diff --git a/.gitignore b/.gitignore index 09c02bf8..dfc4f53c 100644 --- a/.gitignore +++ b/.gitignore @@ -48,3 +48,5 @@ npm-debug.log.* *.css.d.ts *.sass.d.ts *.scss.d.ts + +backend/lib \ No newline at end of file diff --git a/README.md b/README.md index a8799ab9..8893517f 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,8 @@ # Fribbels Epic 7 Gear Optimizer -This is a tool for organizing gear and optimizing gear and unit builds for Epic 7. Gearing units can be time consuming and its not very easy to find optimal combinations of gear within the game, so I made this to help make the gearing process easier. -Please see the **Getting Started** section for instructions. +This is a tool for organizing gear and optimizing gear and unit builds for Epic 7. Gearing units can be time consuming and it's not very easy to find optimal combinations of gear within the game, so I made this to help make the gearing process easier. + +Please see the [**Getting Started**](https://github.com/fribbels/Fribbels-E7-Optimizer#getting-started) section for instructions on how to use it. Features include: @@ -22,7 +23,7 @@ Hers's an example of the optimizer tab. There are a bunch of panels with options #### Settings panel -![](https://i.imgur.com/eSw8bnM.png) +![](https://i.imgur.com/GHzzZCA.png) This panel tracks settings for the other panels to use. @@ -184,11 +185,11 @@ The app also does autosave to an 'autosave.json' on changes being made, but that #### Import gear from Zarroc optimizer -If you're a user of the other gear optimizer from Zarroc2762, this lets you import your gear directly from your existing save file. It won't import heroes though, so you'll have to add those back in. +If you're a user of the other gear optimizer from [Zarroc optimizer](https://github.com/Zarroc2762/E7-Gear-Optimizer), this lets you import your gear directly from your existing save file. It won't import heroes though, so you'll have to add those back in. ## Getting Started -To get started with the app, you'll need to run image recognition on screenshots of your gear, which is built into the Importer tab. If you've previously used the Zarroc2762 optimizer, you can import the gear file directly from that into this app, with the instructions above. +To get started with the app, you'll need to run image recognition on screenshots of your gear, which is built into the Importer tab. If you've previously used the [Zarroc optimizer](https://github.com/Zarroc2762/E7-Gear-Optimizer), you can import the gear file directly from that into this app, with the instructions above. 1. Download the latest release of this app and extract it. The app can be run with FribbelsE7Optimizer.exe 2. Download an emulator to run E7 on @@ -210,7 +211,7 @@ Each screenshot should look like this, and should be exactly 1600x900. I usually ## Closing thoughts -Hopefully this is useful for anyone looking for an easier way to gear their units. I know the Zarroc optimizer does a lot of similar things (https://github.com/Zarroc2762/E7-Gear-Optimizer) but it has been pretty unmaintained and out of date, so I decided to build my own to add some improvements to it. There's still a lot of room to improve and I plan on improving it as feedback comes in. I only work on this in my spare time, so please be patient with new features, or feel free to contribute to the code as well. Feel free to contact me on discord at fribbels#7526 with questions or suggestions. +Hopefully this is useful for anyone looking for an easier way to gear their units. I know the [Zarroc optimizer](https://github.com/Zarroc2762/E7-Gear-Optimizer) does a lot of similar things but it has been pretty unmaintained and out of date, so I decided to build my own app with a different optimization algorithm. There's still a lot of room to improve and I plan on adding new stuff as feedback comes in. I only work on this in my spare time, so please be patient with new features, or you can help contribute to the code as well. Feel free to contact me on discord at fribbels#7526 with questions or suggestions. Planned features: - TBD diff --git a/backend/Gear.iml b/backend/Gear.iml new file mode 100644 index 00000000..c51421c6 --- /dev/null +++ b/backend/Gear.iml @@ -0,0 +1,33 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/backend/app/tessdata/eng.traineddata/eng.traineddata b/backend/app/tessdata/eng.traineddata/eng.traineddata new file mode 100644 index 00000000..84b23ca3 Binary files /dev/null and b/backend/app/tessdata/eng.traineddata/eng.traineddata differ diff --git a/backend/item.json b/backend/item.json new file mode 100644 index 00000000..83d0a7cc --- /dev/null +++ b/backend/item.json @@ -0,0 +1,3 @@ +{ + "level": 3 +} \ No newline at end of file diff --git a/backend/out/artifacts/Gear_jar/Gear.jar b/backend/out/artifacts/Gear_jar/Gear.jar new file mode 100644 index 00000000..3a5d19eb Binary files /dev/null and b/backend/out/artifacts/Gear_jar/Gear.jar differ diff --git a/backend/out/production/Gear/META-INF/MANIFEST.MF b/backend/out/production/Gear/META-INF/MANIFEST.MF new file mode 100644 index 00000000..1e0e5190 --- /dev/null +++ b/backend/out/production/Gear/META-INF/MANIFEST.MF @@ -0,0 +1,3 @@ +Manifest-Version: 1.0 +Main-Class: com.fribbels.Main + diff --git a/backend/out/production/Gear/com/fribbels/Main.class b/backend/out/production/Gear/com/fribbels/Main.class new file mode 100644 index 00000000..9327e051 Binary files /dev/null and b/backend/out/production/Gear/com/fribbels/Main.class differ diff --git a/backend/out/production/Gear/com/fribbels/core/FileIO.class b/backend/out/production/Gear/com/fribbels/core/FileIO.class new file mode 100644 index 00000000..31f27b61 Binary files /dev/null and b/backend/out/production/Gear/com/fribbels/core/FileIO.class differ diff --git a/backend/out/production/Gear/com/fribbels/core/Sorter$1.class b/backend/out/production/Gear/com/fribbels/core/Sorter$1.class new file mode 100644 index 00000000..c2deb585 Binary files /dev/null and b/backend/out/production/Gear/com/fribbels/core/Sorter$1.class differ diff --git a/backend/out/production/Gear/com/fribbels/core/Sorter.class b/backend/out/production/Gear/com/fribbels/core/Sorter.class new file mode 100644 index 00000000..9724d22d Binary files /dev/null and b/backend/out/production/Gear/com/fribbels/core/Sorter.class differ diff --git a/backend/out/production/Gear/com/fribbels/core/StatCalculator.class b/backend/out/production/Gear/com/fribbels/core/StatCalculator.class new file mode 100644 index 00000000..bab6209c Binary files /dev/null and b/backend/out/production/Gear/com/fribbels/core/StatCalculator.class differ diff --git a/backend/out/production/Gear/com/fribbels/db/BaseStatsDb.class b/backend/out/production/Gear/com/fribbels/db/BaseStatsDb.class new file mode 100644 index 00000000..f6089751 Binary files /dev/null and b/backend/out/production/Gear/com/fribbels/db/BaseStatsDb.class differ diff --git a/backend/out/production/Gear/com/fribbels/db/HeroDb.class b/backend/out/production/Gear/com/fribbels/db/HeroDb.class new file mode 100644 index 00000000..64e0626b Binary files /dev/null and b/backend/out/production/Gear/com/fribbels/db/HeroDb.class differ diff --git a/backend/out/production/Gear/com/fribbels/db/ItemDb.class b/backend/out/production/Gear/com/fribbels/db/ItemDb.class new file mode 100644 index 00000000..71d43cce Binary files /dev/null and b/backend/out/production/Gear/com/fribbels/db/ItemDb.class differ diff --git a/backend/out/production/Gear/com/fribbels/db/OptimizationDb.class b/backend/out/production/Gear/com/fribbels/db/OptimizationDb.class new file mode 100644 index 00000000..fc1c7239 Binary files /dev/null and b/backend/out/production/Gear/com/fribbels/db/OptimizationDb.class differ diff --git a/backend/out/production/Gear/com/fribbels/enums/Gear.class b/backend/out/production/Gear/com/fribbels/enums/Gear.class new file mode 100644 index 00000000..9794c0fd Binary files /dev/null and b/backend/out/production/Gear/com/fribbels/enums/Gear.class differ diff --git a/backend/out/production/Gear/com/fribbels/enums/OptimizationColumn.class b/backend/out/production/Gear/com/fribbels/enums/OptimizationColumn.class new file mode 100644 index 00000000..0236e7be Binary files /dev/null and b/backend/out/production/Gear/com/fribbels/enums/OptimizationColumn.class differ diff --git a/backend/out/production/Gear/com/fribbels/enums/Rank.class b/backend/out/production/Gear/com/fribbels/enums/Rank.class new file mode 100644 index 00000000..07a16c5a Binary files /dev/null and b/backend/out/production/Gear/com/fribbels/enums/Rank.class differ diff --git a/backend/out/production/Gear/com/fribbels/enums/Set.class b/backend/out/production/Gear/com/fribbels/enums/Set.class new file mode 100644 index 00000000..26182bef Binary files /dev/null and b/backend/out/production/Gear/com/fribbels/enums/Set.class differ diff --git a/backend/out/production/Gear/com/fribbels/enums/SortOrder.class b/backend/out/production/Gear/com/fribbels/enums/SortOrder.class new file mode 100644 index 00000000..8e18f84e Binary files /dev/null and b/backend/out/production/Gear/com/fribbels/enums/SortOrder.class differ diff --git a/backend/out/production/Gear/com/fribbels/enums/StatType.class b/backend/out/production/Gear/com/fribbels/enums/StatType.class new file mode 100644 index 00000000..3531727c Binary files /dev/null and b/backend/out/production/Gear/com/fribbels/enums/StatType.class differ diff --git a/backend/out/production/Gear/com/fribbels/handler/HeroesRequestHandler.class b/backend/out/production/Gear/com/fribbels/handler/HeroesRequestHandler.class new file mode 100644 index 00000000..275582c3 Binary files /dev/null and b/backend/out/production/Gear/com/fribbels/handler/HeroesRequestHandler.class differ diff --git a/backend/out/production/Gear/com/fribbels/handler/ItemsRequestHandler.class b/backend/out/production/Gear/com/fribbels/handler/ItemsRequestHandler.class new file mode 100644 index 00000000..acb42540 Binary files /dev/null and b/backend/out/production/Gear/com/fribbels/handler/ItemsRequestHandler.class differ diff --git a/backend/out/production/Gear/com/fribbels/handler/OcrRequestHandler.class b/backend/out/production/Gear/com/fribbels/handler/OcrRequestHandler.class new file mode 100644 index 00000000..80171931 Binary files /dev/null and b/backend/out/production/Gear/com/fribbels/handler/OcrRequestHandler.class differ diff --git a/backend/out/production/Gear/com/fribbels/handler/OptimizationRequestHandler.class b/backend/out/production/Gear/com/fribbels/handler/OptimizationRequestHandler.class new file mode 100644 index 00000000..e0d91934 Binary files /dev/null and b/backend/out/production/Gear/com/fribbels/handler/OptimizationRequestHandler.class differ diff --git a/backend/out/production/Gear/com/fribbels/handler/RequestHandler.class b/backend/out/production/Gear/com/fribbels/handler/RequestHandler.class new file mode 100644 index 00000000..a13a06f3 Binary files /dev/null and b/backend/out/production/Gear/com/fribbels/handler/RequestHandler.class differ diff --git a/backend/out/production/Gear/com/fribbels/handler/SystemRequestHandler.class b/backend/out/production/Gear/com/fribbels/handler/SystemRequestHandler.class new file mode 100644 index 00000000..49c3ff8b Binary files /dev/null and b/backend/out/production/Gear/com/fribbels/handler/SystemRequestHandler.class differ diff --git a/backend/out/production/Gear/com/fribbels/model/AugmentedStats.class b/backend/out/production/Gear/com/fribbels/model/AugmentedStats.class new file mode 100644 index 00000000..43ada7e5 Binary files /dev/null and b/backend/out/production/Gear/com/fribbels/model/AugmentedStats.class differ diff --git a/backend/out/production/Gear/com/fribbels/model/Hero$HeroBuilder.class b/backend/out/production/Gear/com/fribbels/model/Hero$HeroBuilder.class new file mode 100644 index 00000000..d22cb03b Binary files /dev/null and b/backend/out/production/Gear/com/fribbels/model/Hero$HeroBuilder.class differ diff --git a/backend/out/production/Gear/com/fribbels/model/Hero.class b/backend/out/production/Gear/com/fribbels/model/Hero.class new file mode 100644 index 00000000..eb473585 Binary files /dev/null and b/backend/out/production/Gear/com/fribbels/model/Hero.class differ diff --git a/backend/out/production/Gear/com/fribbels/model/HeroStats$HeroStatsBuilder.class b/backend/out/production/Gear/com/fribbels/model/HeroStats$HeroStatsBuilder.class new file mode 100644 index 00000000..bb5e93d3 Binary files /dev/null and b/backend/out/production/Gear/com/fribbels/model/HeroStats$HeroStatsBuilder.class differ diff --git a/backend/out/production/Gear/com/fribbels/model/HeroStats.class b/backend/out/production/Gear/com/fribbels/model/HeroStats.class new file mode 100644 index 00000000..9b328d4f Binary files /dev/null and b/backend/out/production/Gear/com/fribbels/model/HeroStats.class differ diff --git a/backend/out/production/Gear/com/fribbels/model/Item.class b/backend/out/production/Gear/com/fribbels/model/Item.class new file mode 100644 index 00000000..d8c753a8 Binary files /dev/null and b/backend/out/production/Gear/com/fribbels/model/Item.class differ diff --git a/backend/out/production/Gear/com/fribbels/model/MiniOptimizationResponse$MiniOptimizationResponseBuilder.class b/backend/out/production/Gear/com/fribbels/model/MiniOptimizationResponse$MiniOptimizationResponseBuilder.class new file mode 100644 index 00000000..9f5b05a8 Binary files /dev/null and b/backend/out/production/Gear/com/fribbels/model/MiniOptimizationResponse$MiniOptimizationResponseBuilder.class differ diff --git a/backend/out/production/Gear/com/fribbels/model/MiniOptimizationResponse.class b/backend/out/production/Gear/com/fribbels/model/MiniOptimizationResponse.class new file mode 100644 index 00000000..a798494e Binary files /dev/null and b/backend/out/production/Gear/com/fribbels/model/MiniOptimizationResponse.class differ diff --git a/backend/out/production/Gear/com/fribbels/model/Request.class b/backend/out/production/Gear/com/fribbels/model/Request.class new file mode 100644 index 00000000..ae2f7b41 Binary files /dev/null and b/backend/out/production/Gear/com/fribbels/model/Request.class differ diff --git a/backend/out/production/Gear/com/fribbels/model/Stat.class b/backend/out/production/Gear/com/fribbels/model/Stat.class new file mode 100644 index 00000000..27515957 Binary files /dev/null and b/backend/out/production/Gear/com/fribbels/model/Stat.class differ diff --git a/backend/out/production/Gear/com/fribbels/ocr/OcrEngine.class b/backend/out/production/Gear/com/fribbels/ocr/OcrEngine.class new file mode 100644 index 00000000..9bad5b2d Binary files /dev/null and b/backend/out/production/Gear/com/fribbels/ocr/OcrEngine.class differ diff --git a/backend/out/production/Gear/com/fribbels/request/BaseStatsRequest$BaseStatsRequestBuilder.class b/backend/out/production/Gear/com/fribbels/request/BaseStatsRequest$BaseStatsRequestBuilder.class new file mode 100644 index 00000000..e0dc774b Binary files /dev/null and b/backend/out/production/Gear/com/fribbels/request/BaseStatsRequest$BaseStatsRequestBuilder.class differ diff --git a/backend/out/production/Gear/com/fribbels/request/BaseStatsRequest.class b/backend/out/production/Gear/com/fribbels/request/BaseStatsRequest.class new file mode 100644 index 00000000..af594834 Binary files /dev/null and b/backend/out/production/Gear/com/fribbels/request/BaseStatsRequest.class differ diff --git a/backend/out/production/Gear/com/fribbels/request/BonusStatsRequest$BonusStatsRequestBuilder.class b/backend/out/production/Gear/com/fribbels/request/BonusStatsRequest$BonusStatsRequestBuilder.class new file mode 100644 index 00000000..7cd93efd Binary files /dev/null and b/backend/out/production/Gear/com/fribbels/request/BonusStatsRequest$BonusStatsRequestBuilder.class differ diff --git a/backend/out/production/Gear/com/fribbels/request/BonusStatsRequest.class b/backend/out/production/Gear/com/fribbels/request/BonusStatsRequest.class new file mode 100644 index 00000000..adc2b190 Binary files /dev/null and b/backend/out/production/Gear/com/fribbels/request/BonusStatsRequest.class differ diff --git a/backend/out/production/Gear/com/fribbels/request/EquipItemsOnHeroRequest$EquipItemsOnHeroRequestBuilder.class b/backend/out/production/Gear/com/fribbels/request/EquipItemsOnHeroRequest$EquipItemsOnHeroRequestBuilder.class new file mode 100644 index 00000000..c5dc2378 Binary files /dev/null and b/backend/out/production/Gear/com/fribbels/request/EquipItemsOnHeroRequest$EquipItemsOnHeroRequestBuilder.class differ diff --git a/backend/out/production/Gear/com/fribbels/request/EquipItemsOnHeroRequest.class b/backend/out/production/Gear/com/fribbels/request/EquipItemsOnHeroRequest.class new file mode 100644 index 00000000..f0771a15 Binary files /dev/null and b/backend/out/production/Gear/com/fribbels/request/EquipItemsOnHeroRequest.class differ diff --git a/backend/out/production/Gear/com/fribbels/request/GetResultRowsRequest$GetResultRowsRequestBuilder.class b/backend/out/production/Gear/com/fribbels/request/GetResultRowsRequest$GetResultRowsRequestBuilder.class new file mode 100644 index 00000000..93cf647b Binary files /dev/null and b/backend/out/production/Gear/com/fribbels/request/GetResultRowsRequest$GetResultRowsRequestBuilder.class differ diff --git a/backend/out/production/Gear/com/fribbels/request/GetResultRowsRequest.class b/backend/out/production/Gear/com/fribbels/request/GetResultRowsRequest.class new file mode 100644 index 00000000..a6596ee2 Binary files /dev/null and b/backend/out/production/Gear/com/fribbels/request/GetResultRowsRequest.class differ diff --git a/backend/out/production/Gear/com/fribbels/request/HeroesRequest$HeroesRequestBuilder.class b/backend/out/production/Gear/com/fribbels/request/HeroesRequest$HeroesRequestBuilder.class new file mode 100644 index 00000000..eb96447d Binary files /dev/null and b/backend/out/production/Gear/com/fribbels/request/HeroesRequest$HeroesRequestBuilder.class differ diff --git a/backend/out/production/Gear/com/fribbels/request/HeroesRequest.class b/backend/out/production/Gear/com/fribbels/request/HeroesRequest.class new file mode 100644 index 00000000..3f6a58b7 Binary files /dev/null and b/backend/out/production/Gear/com/fribbels/request/HeroesRequest.class differ diff --git a/backend/out/production/Gear/com/fribbels/request/IdRequest$IdRequestBuilder.class b/backend/out/production/Gear/com/fribbels/request/IdRequest$IdRequestBuilder.class new file mode 100644 index 00000000..769aef8d Binary files /dev/null and b/backend/out/production/Gear/com/fribbels/request/IdRequest$IdRequestBuilder.class differ diff --git a/backend/out/production/Gear/com/fribbels/request/IdRequest.class b/backend/out/production/Gear/com/fribbels/request/IdRequest.class new file mode 100644 index 00000000..687aece4 Binary files /dev/null and b/backend/out/production/Gear/com/fribbels/request/IdRequest.class differ diff --git a/backend/out/production/Gear/com/fribbels/request/IdsRequest$IdsRequestBuilder.class b/backend/out/production/Gear/com/fribbels/request/IdsRequest$IdsRequestBuilder.class new file mode 100644 index 00000000..3f2f4ab6 Binary files /dev/null and b/backend/out/production/Gear/com/fribbels/request/IdsRequest$IdsRequestBuilder.class differ diff --git a/backend/out/production/Gear/com/fribbels/request/IdsRequest.class b/backend/out/production/Gear/com/fribbels/request/IdsRequest.class new file mode 100644 index 00000000..d8d3590d Binary files /dev/null and b/backend/out/production/Gear/com/fribbels/request/IdsRequest.class differ diff --git a/backend/out/production/Gear/com/fribbels/request/ItemsRequest$ItemsRequestBuilder.class b/backend/out/production/Gear/com/fribbels/request/ItemsRequest$ItemsRequestBuilder.class new file mode 100644 index 00000000..547f4aad Binary files /dev/null and b/backend/out/production/Gear/com/fribbels/request/ItemsRequest$ItemsRequestBuilder.class differ diff --git a/backend/out/production/Gear/com/fribbels/request/ItemsRequest.class b/backend/out/production/Gear/com/fribbels/request/ItemsRequest.class new file mode 100644 index 00000000..ee3f686f Binary files /dev/null and b/backend/out/production/Gear/com/fribbels/request/ItemsRequest.class differ diff --git a/backend/out/production/Gear/com/fribbels/request/Ocr2Request$Ocr2RequestBuilder.class b/backend/out/production/Gear/com/fribbels/request/Ocr2Request$Ocr2RequestBuilder.class new file mode 100644 index 00000000..2843b80b Binary files /dev/null and b/backend/out/production/Gear/com/fribbels/request/Ocr2Request$Ocr2RequestBuilder.class differ diff --git a/backend/out/production/Gear/com/fribbels/request/Ocr2Request.class b/backend/out/production/Gear/com/fribbels/request/Ocr2Request.class new file mode 100644 index 00000000..2ec984a4 Binary files /dev/null and b/backend/out/production/Gear/com/fribbels/request/Ocr2Request.class differ diff --git a/backend/out/production/Gear/com/fribbels/request/OptimizationRequest$OptimizationRequestBuilder.class b/backend/out/production/Gear/com/fribbels/request/OptimizationRequest$OptimizationRequestBuilder.class new file mode 100644 index 00000000..75a6f1c9 Binary files /dev/null and b/backend/out/production/Gear/com/fribbels/request/OptimizationRequest$OptimizationRequestBuilder.class differ diff --git a/backend/out/production/Gear/com/fribbels/request/OptimizationRequest.class b/backend/out/production/Gear/com/fribbels/request/OptimizationRequest.class new file mode 100644 index 00000000..12f89ab9 Binary files /dev/null and b/backend/out/production/Gear/com/fribbels/request/OptimizationRequest.class differ diff --git a/backend/out/production/Gear/com/fribbels/response/GetAllHeroesResponse$GetAllHeroesResponseBuilder.class b/backend/out/production/Gear/com/fribbels/response/GetAllHeroesResponse$GetAllHeroesResponseBuilder.class new file mode 100644 index 00000000..6b9b1817 Binary files /dev/null and b/backend/out/production/Gear/com/fribbels/response/GetAllHeroesResponse$GetAllHeroesResponseBuilder.class differ diff --git a/backend/out/production/Gear/com/fribbels/response/GetAllHeroesResponse.class b/backend/out/production/Gear/com/fribbels/response/GetAllHeroesResponse.class new file mode 100644 index 00000000..c6561dd2 Binary files /dev/null and b/backend/out/production/Gear/com/fribbels/response/GetAllHeroesResponse.class differ diff --git a/backend/out/production/Gear/com/fribbels/response/GetAllItemsResponse$GetAllItemsResponseBuilder.class b/backend/out/production/Gear/com/fribbels/response/GetAllItemsResponse$GetAllItemsResponseBuilder.class new file mode 100644 index 00000000..e3c0671c Binary files /dev/null and b/backend/out/production/Gear/com/fribbels/response/GetAllItemsResponse$GetAllItemsResponseBuilder.class differ diff --git a/backend/out/production/Gear/com/fribbels/response/GetAllItemsResponse.class b/backend/out/production/Gear/com/fribbels/response/GetAllItemsResponse.class new file mode 100644 index 00000000..7c9a1bd0 Binary files /dev/null and b/backend/out/production/Gear/com/fribbels/response/GetAllItemsResponse.class differ diff --git a/backend/out/production/Gear/com/fribbels/response/GetHeroByIdResponse$GetHeroByIdResponseBuilder.class b/backend/out/production/Gear/com/fribbels/response/GetHeroByIdResponse$GetHeroByIdResponseBuilder.class new file mode 100644 index 00000000..892c2c7d Binary files /dev/null and b/backend/out/production/Gear/com/fribbels/response/GetHeroByIdResponse$GetHeroByIdResponseBuilder.class differ diff --git a/backend/out/production/Gear/com/fribbels/response/GetHeroByIdResponse.class b/backend/out/production/Gear/com/fribbels/response/GetHeroByIdResponse.class new file mode 100644 index 00000000..9fa665c0 Binary files /dev/null and b/backend/out/production/Gear/com/fribbels/response/GetHeroByIdResponse.class differ diff --git a/backend/out/production/Gear/com/fribbels/response/GetItemByIdResponse$GetItemByIdResponseBuilder.class b/backend/out/production/Gear/com/fribbels/response/GetItemByIdResponse$GetItemByIdResponseBuilder.class new file mode 100644 index 00000000..e7c33f16 Binary files /dev/null and b/backend/out/production/Gear/com/fribbels/response/GetItemByIdResponse$GetItemByIdResponseBuilder.class differ diff --git a/backend/out/production/Gear/com/fribbels/response/GetItemByIdResponse.class b/backend/out/production/Gear/com/fribbels/response/GetItemByIdResponse.class new file mode 100644 index 00000000..e9b5155b Binary files /dev/null and b/backend/out/production/Gear/com/fribbels/response/GetItemByIdResponse.class differ diff --git a/backend/out/production/Gear/com/fribbels/response/GetResultRowsResponse$GetResultRowsResponseBuilder.class b/backend/out/production/Gear/com/fribbels/response/GetResultRowsResponse$GetResultRowsResponseBuilder.class new file mode 100644 index 00000000..78758d48 Binary files /dev/null and b/backend/out/production/Gear/com/fribbels/response/GetResultRowsResponse$GetResultRowsResponseBuilder.class differ diff --git a/backend/out/production/Gear/com/fribbels/response/GetResultRowsResponse.class b/backend/out/production/Gear/com/fribbels/response/GetResultRowsResponse.class new file mode 100644 index 00000000..3536be0e Binary files /dev/null and b/backend/out/production/Gear/com/fribbels/response/GetResultRowsResponse.class differ diff --git a/backend/out/production/Gear/com/fribbels/response/OcrResponse$OcrResponseBuilder.class b/backend/out/production/Gear/com/fribbels/response/OcrResponse$OcrResponseBuilder.class new file mode 100644 index 00000000..73d51107 Binary files /dev/null and b/backend/out/production/Gear/com/fribbels/response/OcrResponse$OcrResponseBuilder.class differ diff --git a/backend/out/production/Gear/com/fribbels/response/OcrResponse.class b/backend/out/production/Gear/com/fribbels/response/OcrResponse.class new file mode 100644 index 00000000..cf1bc23d Binary files /dev/null and b/backend/out/production/Gear/com/fribbels/response/OcrResponse.class differ diff --git a/backend/out/production/Gear/com/fribbels/response/OptimizationResponse$OptimizationResponseBuilder.class b/backend/out/production/Gear/com/fribbels/response/OptimizationResponse$OptimizationResponseBuilder.class new file mode 100644 index 00000000..77c44ed1 Binary files /dev/null and b/backend/out/production/Gear/com/fribbels/response/OptimizationResponse$OptimizationResponseBuilder.class differ diff --git a/backend/out/production/Gear/com/fribbels/response/OptimizationResponse.class b/backend/out/production/Gear/com/fribbels/response/OptimizationResponse.class new file mode 100644 index 00000000..fcb11e5b Binary files /dev/null and b/backend/out/production/Gear/com/fribbels/response/OptimizationResponse.class differ diff --git a/backend/out/production/Gear/com/fribbels/response/Response.class b/backend/out/production/Gear/com/fribbels/response/Response.class new file mode 100644 index 00000000..ad436457 Binary files /dev/null and b/backend/out/production/Gear/com/fribbels/response/Response.class differ diff --git a/backend/out/test/Gear/com/fribbels/DebugTest.class b/backend/out/test/Gear/com/fribbels/DebugTest.class new file mode 100644 index 00000000..003d0bf3 Binary files /dev/null and b/backend/out/test/Gear/com/fribbels/DebugTest.class differ diff --git a/backend/out/test/Gear/com/fribbels/core/OptimizationRequestHandlerTest.class b/backend/out/test/Gear/com/fribbels/core/OptimizationRequestHandlerTest.class new file mode 100644 index 00000000..9cf88a8a Binary files /dev/null and b/backend/out/test/Gear/com/fribbels/core/OptimizationRequestHandlerTest.class differ diff --git a/backend/resources/resources/tessdata/eng.traineddata/eng.traineddata b/backend/resources/resources/tessdata/eng.traineddata/eng.traineddata new file mode 100644 index 00000000..84b23ca3 Binary files /dev/null and b/backend/resources/resources/tessdata/eng.traineddata/eng.traineddata differ diff --git a/backend/response.txt b/backend/response.txt new file mode 100644 index 00000000..b954681d --- /dev/null +++ b/backend/response.txt @@ -0,0 +1 @@ +[0,1,4500,4501,4502,4503,4504,4505,4506,4507,4508,4509,4510,4511,4512,4513,4514,4515,4516,4517,4518,4519,2,3,4520,4,4521,5,4522,6,4523,7,4524,8,4525,4526,9,4527,10,4528,11,4529,4530,12,4531,13,4532,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,4533,72,73,4534,74,4535,75,4536,76,4537,77,4538,78,4539,79,4540,80,4541,81,4542,82,4543,4544,4545,83,4546,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,4547,129,4548,130,4549,131,4550,132,133,4551,134,4552,135,4553,136,4554,137,4555,138,4556,139,4557,140,4558,141,4559,142,4560,143,4561,144,4562,145,4563,146,4564,147,4565,148,4566,4567,149,4568,4569,150,4570,151,4571,152,4572,4573,153,4574,154,4575,155,4576,156,4577,157,4578,158,4579,159,4580,160,4581,161,4582,162,4583,163,164,4584,165,4585,166,167,4586,168,4587,169,4588,170,4589,171,4590,172,4591,173,4592,174,4593,175,4594,176,4595,177,4596,178,4597,179,4598,180,4599,181,4600,182,4601,183,4602,184,4603,185,4604,186,4605,4606,187,188,189,4607,190,191,4608,192,193,4609,194,4610,195,4611,196,4612,197,4613,198,199,4614,200,4615,201,4616,202,4617,203,4618,204,4619,205,4620,206,4621,207,4622,208,4623,209,4624,210,4625,211,4626,212,4627,213,4628,214,4629,215,4630,216,4631,217,4632,218,4633,219,4634,220,4635,221,4636,222,4637,223,4638,224,4639,225,4640,226,4641,227,4642,228,4643,229,4644,230,4645,231,4646,232,4647,233,4648,234,4649,235,4650,236,4651,237,4652,238,4653,239,4654,240,4655,241,4656,242,4657,243,4658,244,4659,245,246,4660,247,4661,248,4662,249,4663,250,4664,251,4665,252,4666,253,4667,254,4668,255,4669,256,257,4670,258,4671,259,4672,260,4673,261,4674,262,4675,263,4676,264,4677,265,4678,266,4679,267,4680,268,4681,269,4682,270,271,272,273,4683,4684,4685,4686,4687,4688,4689,4690,4691,4692,4693,4694,4695,4696,4697,4698,4699,4700,4701,4702,4703,4704,4705,4706,4707,4708,4709,4710,4711,4712,4713,4714,4715,4716,4717,4718,4719,4720,4721,4722,4723,4724,4725,4726,4727,4728,274,4729,4730,4731,4732,4733,4734,4735,4736,4737,4738,4739,4740,4741,4742,4743,4744,4745,4746,4747,4748,4749,4750,4751,4752,4753,4754,4755,4756,4757,4758,4759,4760,4761,4762,4763,4764,4765,4766,4767,4768,4769,4770,4771,4772,4773,4774,4775,4776,4777,4778,4779,4780,4781,4782,4783,4784,4785,4786,4787,4788,4789,4790,4791,4792,4793,4794,4795,4796,4797,4798,4799,4800,4801,4802,4803,4804,4805,4806,4807,4808,4809,4810,4811,4812,4813,4814,4815,4816,4817,4818,4819,4820,4821,4822,4823,4824,4825,4826,4827,4828,4829,4830,4831,4832,4833,4834,4835,4836,4837,4838,4839,4840,4841,4842,4843,4844,4845,4846,4847,4848,4849,4850,4851,4852,4853,4854,4855,4856,4857,4858,4859,4860,4861,4862,4863,275,276,4864,277,278,4865,279,4866,280,4867,281,4868,282,4869,283,4870,284,4871,285,4872,286,4873,287,4874,288,4875,289,4876,290,4877,291,4878,292,4879,293,4880,294,4881,295,4882,296,4883,297,4884,298,4885,299,4886,300,4887,301,4888,302,4889,303,4890,304,4891,305,4892,306,4893,307,4894,308,309,4895,310,4896,311,4897,312,4898,313,4899,314,4900,4901,4902,315,4903,316,317,318,319,4904,320,4905,321,4906,322,4907,323,4908,4909,4910,4911,4912,324,4913,4914,325,4915,4916,326,4917,327,4918,328,4919,329,4920,330,4921,331,4922,332,4923,333,4924,334,4925,335,4926,4927,336,4928,337,4929,338,339,340,341,342,4930,343,4931,344,345,4932,346,4933,347,4934,348,4935,349,4936,350,4937,351,4938,352,4939,353,4940,354,4941,355,4942,356,4943,357,4944,358,4945,359,4946,360,4947,361,4948,362,4949,363,364,4950,365,4951,366,4952,367,368,4953,369,4954,370,4955,371,4956,4957,4958,372,4959,373,4960,374,4961,375,4962,376,4963,377,4964,378,4965,379,4966,380,4967,381,4968,382,4969,383,4970,384,4971,385,4972,386,4973,387,4974,388,4975,389,4976,390,4977,391,4978,392,4979,393,4980,394,4981,395,4982,396,4983,397,4984,398,4985,399,4986,400,4987,401,4988,402,4989,403,4990,404,4991,405,4992,406,4993,407,4994,408,4995,409,4996,410,4997,411,4998,412,4999,413,5000,414,5001,415,5002,5003,416,5004,417,5005,418,5006,5007,419,5008,420,5009,421,5010,422,5011,423,5012,424,5013,425,5014,426,5015,427,5016,428,5017,429,5018,430,5019,431,5020,432,5021,433,5022,434,5023,435,5024,436,5025,437,5026,438,5027,439,5028,440,5029,441,442,5030,443,5031,444,5032,445,5033,446,5034,447,5035,448,5036,449,5037,450,5038,451,5039,452,5040,453,5041,454,5042,455,5043,456,5044,457,5045,458,5046,5047,5048,5049,5050,5051,5052,5053,5054,5055,5056,5057,5058,5059,5060,5061,5062,5063,5064,5065,5066,5067,5068,5069,5070,5071,5072,5073,5074,5075,5076,5077,5078,5079,5080,5081,5082,5083,5084,5085,5086,5087,5088,5089,5090,5091,5092,5093,5094,5095,5096,459,5097,5098,460,5099,461,462,463,464,5100,465,5101,466,5102,467,5103,468,5104,469,5105,470,5106,471,5107,472,5108,473,5109,474,475,476,477,5110,478,5111,479,5112,480,5113,5114,481,5115,482,5116,483,5117,484,5118,485,5119,486,5120,487,5121,488,5122,489,5123,490,5124,491,5125,492,5126,493,5127,494,5128,495,5129,496,5130,497,5131,498,5132,499,5133,500,5134,501,5135,502,5136,503,5137,504,5138,505,5139,506,5140,507,5141,508,5142,509,5143,510,5144,511,5145,512,5146,513,5147,514,5148,515,5149,516,5150,517,5151,518,5152,519,5153,520,5154,521,5155,522,5156,523,5157,524,5158,525,5159,526,5160,527,5161,528,5162,529,5163,530,5164,531,5165,532,5166,533,5167,534,5168,535,5169,536,5170,537,5171,538,5172,539,5173,540,5174,541,5175,542,5176,543,5177,544,5178,545,5179,546,5180,547,5181,548,5182,549,5183,5184,550,5185,551,5186,552,5187,553,5188,554,5189,555,5190,556,5191,557,5192,558,5193,559,5194,560,5195,561,5196,562,5197,563,5198,564,5199,565,5200,566,5201,567,5202,568,5203,569,5204,570,5205,571,5206,572,5207,573,5208,574,5209,5210,5211,575,5212,5213,576,5214,577,5215,578,5216,579,5217,580,5218,581,5219,582,5220,583,5221,584,5222,585,5223,586,5224,587,5225,588,5226,589,5227,590,5228,591,5229,592,5230,593,5231,594,5232,595,5233,596,5234,597,5235,598,5236,599,5237,600,5238,601,5239,602,5240,603,5241,604,5242,5243,605,5244,606,5245,607,5246,608,5247,609,5248,610,5249,611,612,613,5250,614,5251,615,5252,616,5253,617,5254,618,5255,619,5256,620,5257,621,5258,622,5259,623,5260,624,5261,625,5262,626,5263,627,5264,628,5265,629,5266,630,5267,631,5268,632,5269,633,5270,634,5271,635,5272,5273,636,5274,637,5275,638,5276,639,5277,640,5278,641,5279,642,5280,643,5281,644,5282,645,5283,646,5284,647,5285,648,5286,649,5287,650,5288,651,5289,652,5290,653,5291,654,5292,655,5293,656,5294,657,5295,658,5296,659,5297,660,5298,661,5299,662,5300,663,5301,664,5302,665,5303,666,5304,667,5305,668,5306,669,5307,5308,670,5309,671,672,5310,673,5311,5312,5313,5314,5315,674,5316,5317,675,5318,676,5319,677,5320,678,5321,679,5322,680,5323,681,5324,682,5325,683,5326,684,5327,685,5328,686,5329,5330,687,5331,688,5332,689,5333,690,5334,691,5335,692,5336,693,5337,694,5338,695,5339,696,5340,697,5341,698,5342,699,5343,700,5344,701,5345,702,5346,5347,5348,5349,5350,5351,5352,5353,5354,5355,5356,5357,5358,5359,5360,5361,703,5362,704,5363,5364,705,5365,706,5366,707,5367,708,5368,709,5369,710,5370,711,5371,712,5372,713,5373,714,5374,715,5375,716,5376,717,5377,718,5378,719,5379,720,5380,721,5381,722,5382,723,5383,724,5384,725,5385,726,5386,727,5387,728,5388,729,5389,730,5390,731,5391,732,5392,733,5393,734,5394,735,5395,736,5396,737,5397,738,5398,739,5399,740,741,5400,742,5401,743,5402,744,5403,745,5404,746,5405,747,5406,5407,748,5408,749,5409,750,5410,751,5411,752,5412,753,5413,754,5414,755,5415,756,5416,757,5417,758,5418,759,5419,760,5420,761,5421,762,5422,763,5423,764,5424,765,5425,766,5426,767,5427,768,5428,769,5429,770,5430,771,5431,772,5432,773,5433,774,5434,775,776,5435,777,5436,778,5437,779,5438,780,5439,781,5440,782,5441,783,5442,784,5443,785,5444,786,5445,787,5446,788,5447,789,5448,790,5449,791,5450,792,5451,793,5452,794,5453,795,5454,796,5455,797,5456,798,5457,799,5458,800,5459,801,5460,802,5461,803,5462,804,5463,805,5464,806,5465,807,5466,808,5467,809,5468,810,5469,811,5470,812,5471,813,5472,814,5473,815,5474,816,5475,817,5476,818,5477,819,5478,820,5479,821,5480,822,5481,823,5482,824,5483,825,5484,826,827,5485,828,5486,829,5487,830,5488,831,5489,832,5490,833,5491,834,5492,835,5493,836,5494,837,5495,838,5496,839,5497,840,5498,841,5499,842,5500,843,5501,844,5502,845,5503,846,5504,847,5505,848,5506,849,5507,850,5508,851,5509,852,5510,853,5511,854,5512,855,5513,856,5514,857,5515,858,5516,859,5517,860,5518,861,5519,862,5520,863,5521,864,5522,865,5523,866,5524,867,868,5525,869,5526,870,5527,871,5528,872,5529,873,5530,874,5531,875,5532,876,5533,877,5534,878,5535,879,5536,880,5537,881,5538,882,5539,883,5540,884,5541,885,5542,886,5543,887,5544,888,5545,889,5546,890,5547,891,5548,892,5549,893,894,5550,895,5551,896,5552,5553,897,5554,898,5555,899,5556,900,5557,901,5558,902,5559,903,5560,904,5561,905,5562,906,5563,907,5564,908,5565,909,5566,910,5567,911,5568,912,5569,913,5570,914,5571,915,5572,916,5573,917,5574,918,5575,919,5576,920,5577,921,5578,922,5579,923,5580,924,5581,5582,925,5583,926,5584,927,5585,928,5586,929,5587,930,5588,931,5589,932,933,5590,934,5591,935,5592,936,5593,937,5594,938,5595,939,5596,940,5597,941,5598,942,5599,943,5600,944,5601,945,5602,946,5603,947,5604,948,5605,949,5606,950,5607,951,5608,952,5609,953,5610,954,5611,955,5612,956,5613,957,5614,958,5615,959,5616,960,5617,961,5618,962,5619,963,5620,964,5621,965,5622,966,5623,967,5624,968,969,5625,970,5626,971,5627,972,5628,973,5629,974,5630,975,5631,976,5632,977,5633,978,5634,979,5635,980,5636,981,5637,982,5638,983,5639,984,985,5640,986,5641,987,5642,988,5643,989,5644,990,5645,991,5646,992,5647,993,5648,994,5649,995,5650,996,5651,997,5652,998,5653,999,5654,1000,5655,1001,5656,1002,5657,1003,5658,1004,5659,1005,5660,1006,5661,1007,5662,1008,5663,1009,5664,1010,5665,1011,5666,1012,5667,1013,5668,1014,5669,1015,5670,1016,5671,1017,5672,1018,5673,1019,5674,1020,5675,1021,5676,1022,5677,1023,5678,1024,5679,1025,5680,1026,5681,1027,5682,1028,5683,1029,5684,1030,5685,1031,5686,1032,5687,1033,5688,1034,5689,1035,5690,1036,5691,1037,5692,1038,5693,1039,5694,1040,5695,1041,5696,1042,5697,1043,5698,1044,5699,1045,5700,1046,5701,1047,5702,1048,5703,1049,5704,1050,5705,1051,5706,1052,5707,1053,5708,1054,5709,1055,5710,1056,5711,1057,5712,1058,5713,1059,5714,1060,5715,1061,5716,1062,5717,1063,5718,1064,5719,1065,5720,1066,5721,1067,5722,1068,5723,1069,5724,1070,5725,1071,5726,1072,5727,1073,5728,1074,5729,1075,5730,1076,5731,1077,5732,1078,5733,1079,5734,1080,5735,1081,5736,1082,5737,1083,5738,1084,5739,1085,1086,1087,1088,5740,1089,5741,5742,5743,1090,5744,1091,5745,1092,5746,1093,5747,1094,5748,1095,5749,1096,5750,1097,5751,1098,5752,1099,5753,1100,5754,1101,5755,1102,5756,1103,5757,1104,5758,1105,5759,1106,5760,1107,5761,1108,5762,1109,5763,1110,5764,1111,5765,1112,5766,1113,5767,1114,5768,5769,1115,5770,5771,1116,5772,1117,5773,1118,5774,1119,5775,1120,5776,1121,5777,1122,5778,1123,5779,1124,5780,1125,5781,1126,5782,1127,5783,1128,5784,1129,5785,1130,5786,1131,5787,1132,5788,1133,5789,1134,5790,1135,5791,1136,5792,1137,5793,1138,5794,1139,5795,1140,5796,1141,5797,1142,5798,1143,5799,1144,5800,1145,5801,1146,5802,1147,5803,1148,5804,1149,5805,1150,5806,1151,5807,1152,5808,1153,5809,1154,5810,1155,5811,1156,5812,1157,5813,1158,5814,1159,5815,1160,5816,1161,5817,1162,1163,1164,5818,1165,5819,1166,5820,1167,5821,1168,5822,1169,5823,1170,5824,1171,5825,1172,5826,1173,5827,1174,5828,1175,5829,1176,5830,1177,5831,1178,5832,1179,5833,1180,5834,1181,5835,1182,5836,1183,5837,1184,5838,1185,5839,1186,5840,1187,5841,1188,5842,1189,5843,1190,5844,1191,5845,1192,5846,1193,5847,1194,5848,1195,5849,1196,5850,1197,5851,1198,5852,1199,5853,1200,5854,1201,5855,1202,1203,5856,1204,5857,1205,5858,5859,5860,5861,5862,5863,5864,5865,5866,5867,5868,5869,5870,5871,5872,5873,5874,5875,5876,5877,5878,5879,5880,5881,5882,5883,5884,5885,5886,5887,5888,5889,5890,5891,5892,5893,5894,5895,5896,5897,5898,5899,5900,5901,5902,5903,5904,5905,5906,5907,5908,5909,5910,5911,5912,5913,5914,5915,5916,5917,5918,5919,5920,5921,5922,5923,5924,5925,5926,5927,5928,5929,5930,5931,5932,5933,5934,5935,5936,5937,5938,5939,5940,5941,5942,5943,5944,5945,5946,5947,5948,5949,5950,5951,5952,5953,5954,5955,1206,5956,5957,5958,5959,5960,1207,5961,5962,1208,5963,1209,5964,1210,5965,1211,5966,1212,5967,1213,5968,1214,5969,1215,5970,1216,5971,1217,5972,1218,5973,1219,5974,1220,5975,1221,5976,1222,5977,1223,5978,1224,5979,1225,5980,1226,5981,1227,5982,1228,5983,1229,5984,1230,5985,1231,5986,1232,5987,1233,5988,1234,5989,1235,5990,1236,5991,1237,5992,1238,5993,1239,5994,1240,5995,1241,5996,1242,5997,1243,5998,1244,5999,1245,1246,1247,1248,6000,1249,6001,1250,6002,1251,6003,1252,6004,1253,6005,1254,6006,1255,6007,1256,6008,1257,6009,1258,6010,1259,6011,1260,6012,1261,6013,1262,6014,1263,6015,1264,6016,1265,6017,1266,6018,1267,6019,1268,6020,1269,6021,1270,6022,1271,6023,1272,6024,1273,6025,1274,6026,1275,6027,1276,6028,1277,6029,1278,6030,1279,6031,1280,6032,1281,6033,1282,6034,1283,6035,1284,6036,1285,6037,1286,6038,1287,6039,1288,6040,1289,6041,6042,1290,6043,1291,6044,1292,6045,1293,6046,1294,6047,1295,6048,1296,6049,1297,6050,1298,6051,1299,6052,1300,6053,1301,6054,1302,6055,1303,6056,1304,6057,1305,6058,1306,6059,1307,6060,1308,6061,1309,6062,1310,6063,1311,6064,1312,6065,1313,6066,1314,6067,1315,6068,1316,6069,1317,6070,1318,6071,1319,6072,1320,6073,1321,6074,1322,6075,1323,6076,1324,6077,1325,6078,1326,6079,1327,6080,1328,6081,1329,6082,1330,6083,1331,6084,1332,6085,1333,6086,1334,6087,1335,6088,1336,6089,1337,6090,1338,6091,1339,6092,1340,6093,1341,6094,1342,6095,1343,6096,1344,6097,1345,6098,1346,6099,1347,6100,1348,6101,1349,6102,6103,1350,6104,1351,6105,1352,6106,1353,6107,1354,6108,1355,6109,1356,6110,1357,6111,1358,6112,1359,6113,1360,6114,1361,6115,1362,6116,1363,6117,1364,6118,1365,6119,6120,1366,6121,6122,1367,6123,1368,6124,1369,6125,1370,6126,1371,6127,1372,6128,1373,6129,1374,6130,1375,6131,1376,6132,1377,6133,1378,6134,1379,6135,1380,6136,1381,6137,1382,6138,1383,6139,1384,6140,1385,6141,1386,6142,1387,6143,1388,6144,1389,6145,1390,6146,1391,6147,1392,6148,1393,6149,1394,6150,1395,6151,1396,6152,1397,6153,1398,6154,1399,6155,1400,6156,1401,6157,1402,6158,1403,6159,1404,6160,1405,6161,1406,6162,1407,6163,1408,6164,1409,6165,1410,6166,1411,6167,1412,6168,1413,6169,1414,6170,1415,6171,1416,6172,1417,6173,1418,6174,1419,6175,1420,6176,1421,6177,1422,6178,1423,6179,1424,6180,1425,6181,1426,6182,1427,6183,1428,6184,1429,6185,1430,6186,1431,6187,1432,6188,1433,6189,1434,6190,1435,6191,1436,6192,1437,6193,1438,6194,1439,6195,1440,6196,1441,6197,1442,6198,1443,6199,1444,6200,1445,6201,1446,6202,1447,6203,1448,6204,1449,6205,1450,6206,1451,6207,1452,6208,1453,6209,1454,6210,1455,6211,1456,6212,1457,6213,1458,6214,1459,6215,1460,6216,1461,6217,1462,6218,1463,6219,1464,6220,1465,6221,1466,6222,1467,6223,1468,6224,1469,6225,1470,6226,1471,6227,1472,6228,1473,6229,1474,6230,1475,6231,1476,6232,1477,6233,1478,6234,1479,6235,1480,6236,1481,6237,1482,6238,1483,6239,1484,6240,1485,6241,1486,6242,1487,6243,1488,6244,1489,6245,1490,6246,1491,6247,1492,6248,1493,6249,1494,6250,1495,6251,1496,6252,1497,6253,1498,6254,1499,6255,1500,6256,1501,6257,1502,6258,1503,6259,1504,6260,1505,6261,1506,6262,1507,6263,1508,6264,1509,6265,6266,1510,6267,1511,6268,1512,6269,1513,6270,1514,6271,1515,6272,1516,6273,1517,6274,1518,6275,1519,6276,1520,6277,1521,6278,1522,6279,1523,1524,6280,1525,6281,1526,6282,1527,6283,9000,1528,6284,1529,9001,6285,1530,9002,6286,1531,9003,6287,1532,9004,6288,1533,9005,6289,1534,9006,6290,1535,9007,6291,1536,9008,6292,1537,9009,6293,1538,9010,6294,1539,9011,6295,1540,9012,6296,1541,9013,6297,1542,9014,6298,1543,9015,6299,1544,9016,9017,1545,6300,9018,1546,6301,9019,1547,6302,9020,1548,6303,9021,1549,6304,9022,1550,6305,9023,1551,6306,9024,1552,6307,9025,1553,6308,9026,1554,6309,9027,1555,9028,6310,1556,9029,6311,1557,6312,9030,1558,6313,9031,1559,6314,9032,1560,6315,9033,1561,6316,9034,1562,6317,9035,1563,6318,9036,1564,6319,9037,1565,6320,9038,1566,6321,9039,1567,6322,9040,1568,6323,9041,1569,6324,9042,1570,6325,9043,1571,6326,9044,1572,6327,9045,1573,6328,9046,1574,6329,9047,9048,1575,6330,9049,1576,6331,9050,1577,6332,9051,6333,1578,9052,6334,1579,9053,6335,9054,1580,6336,1581,9055,6337,1582,9056,6338,1583,9057,6339,1584,9058,6340,9059,1585,6341,9060,1586,6342,9061,1587,6343,9062,1588,6344,9063,1589,9064,6345,1590,6346,9065,1591,9066,6347,1592,9067,6348,1593,9068,6349,1594,9069,6350,1595,9070,1596,9071,1597,9072,1598,6351,1599,6352,1600,6353,1601,6354,1602,6355,1603,6356,1604,6357,1605,6358,1606,6359,1607,6360,1608,6361,1609,6362,9073,1610,6363,9074,1611,6364,1612,9075,6365,1613,9076,6366,1614,9077,6367,9078,1615,6368,9079,1616,6369,1617,9080,6370,1618,9081,6371,1619,9082,6372,9083,6373,1620,9084,6374,1621,9085,6375,1622,6376,1623,9086,6377,1624,9087,6378,1625,9088,6379,1626,9089,6380,1627,9090,6381,1628,9091,6382,1629,9092,6383,1630,9093,6384,1631,9094,6385,1632,9095,6386,1633,9096,6387,1634,9097,6388,1635,9098,6389,1636,9099,6390,1637,9100,6391,1638,9101,6392,9102,1639,6393,9103,1640,6394,9104,1641,6395,9105,1642,6396,9106,1643,6397,9107,1644,6398,9108,6399,1645,9109,1646,9110,6400,1647,9111,6401,1648,9112,6402,1649,9113,6403,9114,6404,1650,9115,6405,1651,9116,6406,1652,9117,6407,1653,9118,6408,1654,9119,6409,1655,9120,6410,1656,9121,6411,1657,9122,6412,1658,9123,6413,1659,9124,6414,1660,9125,6415,1661,9126,6416,1662,9127,6417,1663,9128,6418,1664,9129,6419,1665,9130,6420,1666,9131,6421,1667,9132,6422,1668,9133,6423,1669,9134,6424,1670,9135,6425,1671,9136,6426,1672,9137,6427,1673,9138,6428,9139,1674,6429,9140,6430,1675,9141,6431,1676,9142,6432,1677,9143,6433,1678,9144,6434,1679,9145,6435,9146,1680,9147,6436,1681,9148,6437,1682,9149,6438,1683,9150,1684,6439,9151,6440,1685,9152,6441,1686,9153,6442,1687,9154,6443,1688,9155,6444,1689,9156,6445,9157,1690,6446,9158,1691,6447,9159,1692,6448,9160,1693,9161,6449,1694,9162,1695,6450,9163,1696,6451,9164,1697,6452,9165,1698,6453,9166,1699,6454,9167,1700,9168,6455,1701,9169,6456,1702,6457,9170,6458,1703,9171,6459,1704,9172,6460,9173,1705,6461,9174,1706,6462,9175,1707,6463,9176,1708,6464,9177,1709,6465,9178,6466,1710,9179,6467,1711,9180,6468,1712,9181,6469,1713,9182,6470,1714,9183,6471,1715,9184,6472,1716,6473,9185,1717,6474,9186,1718,9187,6475,1719,9188,6476,1720,9189,6477,1721,9190,6478,1722,9191,6479,1723,9192,6480,1724,9193,6481,9194,1725,6482,9195,1726,6483,9196,1727,6484,9197,1728,9198,6485,1729,9199,6486,6487,1730,9200,6488,1731,9201,6489,1732,9202,6490,1733,9203,6491,1734,9204,6492,6493,1735,9205,6494,9206,1736,6495,9207,6496,9208,6497,9209,6498,9210,6499,9211,6500,6501,1737,6502,6503,6504,1738,6505,6506,6507,6508,1739,6509,1740,6510,1741,6511,1742,6512,1743,6513,1744,6514,1745,6515,1746,6516,1747,6517,1748,6518,1749,6519,1750,6520,1751,6521,1752,6522,1753,6523,1754,6524,1755,6525,1756,6526,1757,6527,1758,6528,1759,6529,1760,6530,1761,6531,1762,6532,1763,6533,1764,6534,1765,6535,1766,6536,1767,6537,1768,6538,1769,6539,1770,6540,1771,6541,1772,6542,1773,6543,1774,6544,1775,6545,1776,6546,1777,6547,1778,6548,1779,6549,1780,6550,1781,6551,1782,6552,1783,6553,1784,6554,1785,6555,1786,6556,1787,6557,1788,6558,1789,6559,1790,6560,1791,6561,1792,6562,1793,6563,1794,6564,1795,6565,1796,6566,1797,6567,1798,6568,1799,6569,1800,6570,1801,6571,1802,6572,1803,6573,1804,6574,1805,6575,1806,6576,1807,6577,1808,6578,1809,6579,1810,6580,1811,6581,1812,6582,1813,6583,1814,6584,1815,6585,1816,6586,1817,6587,1818,6588,1819,6589,1820,6590,1821,6591,1822,6592,1823,6593,1824,6594,1825,1826,6595,1827,6596,1828,6597,1829,6598,1830,6599,1831,6600,1832,6601,1833,6602,1834,6603,1835,6604,1836,6605,1837,6606,1838,6607,1839,6608,1840,6609,1841,6610,1842,6611,1843,6612,1844,6613,1845,6614,1846,6615,1847,6616,1848,6617,1849,6618,1850,6619,1851,6620,1852,6621,1853,6622,1854,6623,1855,6624,1856,6625,1857,6626,1858,6627,1859,6628,1860,6629,1861,6630,1862,6631,1863,6632,1864,6633,1865,6634,1866,6635,1867,6636,1868,6637,1869,6638,1870,6639,1871,6640,1872,6641,1873,6642,1874,6643,1875,6644,1876,6645,1877,6646,1878,6647,1879,6648,1880,6649,1881,6650,1882,6651,1883,6652,1884,6653,1885,6654,1886,6655,1887,6656,1888,6657,1889,6658,1890,6659,1891,6660,1892,6661,1893,6662,1894,6663,1895,6664,1896,6665,1897,6666,1898,6667,1899,6668,1900,6669,1901,6670,1902,6671,1903,6672,1904,6673,1905,6674,1906,6675,1907,6676,1908,6677,1909,6678,1910,6679,1911,6680,1912,6681,1913,6682,1914,6683,1915,6684,1916,6685,1917,6686,1918,6687,1919,6688,1920,6689,1921,6690,1922,6691,1923,6692,1924,6693,1925,6694,1926,6695,1927,6696,1928,6697,1929,6698,1930,6699,1931,6700,1932,6701,1933,6702,1934,6703,1935,6704,1936,6705,1937,6706,1938,6707,1939,6708,1940,6709,1941,6710,1942,6711,1943,6712,1944,6713,1945,6714,1946,6715,1947,6716,1948,6717,1949,6718,1950,6719,1951,6720,1952,6721,1953,6722,1954,6723,1955,6724,1956,6725,1957,6726,1958,6727,1959,6728,1960,6729,1961,6730,1962,6731,1963,6732,1964,6733,1965,6734,1966,6735,1967,6736,1968,6737,1969,6738,1970,6739,1971,6740,1972,6741,1973,6742,1974,6743,1975,6744,1976,6745,1977,6746,1978,6747,1979,6748,1980,6749,1981,1982,1983,6750,1984,6751,1985,6752,1986,6753,1987,6754,1988,6755,1989,6756,1990,6757,1991,6758,1992,6759,1993,6760,1994,6761,1995,6762,1996,6763,1997,6764,1998,6765,1999,6766,2000,6767,2001,6768,2002,6769,2003,6770,2004,6771,2005,6772,2006,6773,2007,6774,2008,6775,2009,6776,2010,6777,2011,6778,2012,6779,2013,6780,2014,6781,2015,6782,2016,6783,2017,6784,2018,6785,2019,6786,2020,6787,2021,6788,2022,6789,2023,6790,2024,6791,2025,6792,2026,6793,2027,6794,2028,6795,2029,6796,2030,6797,2031,6798,2032,6799,2033,6800,2034,6801,2035,6802,6803,6804,6805,6806,6807,6808,6809,6810,6811,6812,6813,2036,6814,2037,6815,2038,6816,2039,6817,6818,2040,6819,2041,6820,2042,6821,2043,6822,2044,6823,2045,6824,2046,6825,2047,6826,2048,6827,2049,6828,2050,6829,2051,6830,2052,6831,2053,6832,2054,6833,2055,6834,2056,6835,2057,6836,2058,6837,2059,6838,2060,6839,2061,6840,2062,6841,2063,6842,2064,6843,2065,6844,2066,2067,6845,2068,6846,2069,6847,6848,2070,6849,2071,6850,2072,6851,2073,6852,2074,6853,2075,6854,2076,6855,2077,6856,2078,6857,2079,6858,6859,2080,6860,2081,6861,2082,6862,2083,6863,2084,6864,2085,6865,2086,6866,2087,6867,2088,6868,2089,6869,2090,6870,2091,6871,2092,6872,2093,6873,2094,6874,2095,6875,2096,6876,2097,6877,2098,6878,2099,6879,6880,2100,6881,2101,6882,2102,6883,2103,6884,2104,6885,2105,6886,2106,6887,2107,6888,2108,6889,2109,6890,2110,6891,2111,6892,2112,6893,2113,6894,2114,6895,2115,6896,2116,6897,2117,6898,2118,6899,2119,6900,2120,6901,2121,6902,2122,6903,2123,6904,2124,6905,2125,6906,2126,6907,2127,6908,2128,6909,2129,6910,2130,6911,2131,6912,2132,6913,2133,6914,2134,6915,6916,2135,6917,2136,6918,2137,6919,2138,2139,6920,2140,6921,2141,6922,2142,6923,2143,6924,2144,6925,2145,6926,2146,6927,2147,6928,2148,6929,2149,6930,2150,6931,2151,6932,2152,6933,2153,6934,2154,6935,2155,6936,2156,6937,2157,6938,2158,6939,2159,6940,2160,6941,2161,6942,2162,6943,2163,6944,2164,6945,2165,6946,2166,6947,2167,6948,2168,6949,2169,6950,2170,6951,2171,6952,2172,6953,2173,6954,2174,6955,2175,6956,2176,6957,2177,6958,2178,6959,2179,6960,2180,6961,2181,6962,2182,6963,2183,6964,2184,6965,2185,6966,2186,6967,2187,6968,2188,6969,2189,6970,2190,6971,2191,6972,2192,6973,2193,2194,6974,6975,6976,6977,6978,6979,6980,6981,6982,6983,6984,6985,6986,6987,6988,6989,6990,6991,6992,6993,6994,6995,6996,6997,6998,6999,7000,7001,7002,7003,7004,7005,7006,7007,7008,7009,7010,7011,7012,7013,7014,7015,7016,7017,7018,7019,7020,7021,7022,7023,7024,7025,7026,7027,7028,7029,7030,7031,7032,7033,7034,7035,7036,7037,7038,7039,7040,7041,7042,7043,7044,7045,7046,7047,7048,7049,7050,7051,7052,7053,7054,7055,7056,7057,7058,7059,7060,7061,7062,7063,7064,7065,7066,7067,7068,7069,7070,7071,7072,7073,7074,7075,7076,7077,7078,7079,7080,7081,7082,7083,7084,7085,7086,7087,7088,7089,7090,7091,7092,7093,7094,7095,7096,7097,7098,7099,7100,7101,7102,7103,7104,7105,7106,7107,7108,7109,7110,7111,7112,7113,7114,7115,7116,7117,7118,7119,7120,7121,7122,7123,7124,7125,7126,7127,7128,7129,7130,7131,7132,7133,7134,7135,7136,7137,7138,7139,7140,7141,7142,7143,7144,7145,7146,7147,7148,7149,7150,7151,7152,7153,7154,7155,7156,7157,7158,7159,7160,7161,7162,7163,7164,7165,7166,7167,7168,7169,7170,7171,7172,7173,7174,7175,7176,7177,7178,7179,7180,7181,7182,7183,7184,7185,7186,7187,7188,7189,7190,7191,7192,7193,7194,7195,7196,7197,7198,7199,7200,7201,7202,7203,7204,7205,7206,7207,7208,7209,7210,7211,7212,7213,7214,7215,7216,7217,7218,7219,7220,7221,7222,7223,7224,7225,7226,7227,7228,7229,7230,7231,7232,7233,7234,7235,7236,7237,7238,7239,7240,7241,7242,7243,7244,7245,7246,7247,7248,7249,7250,7251,7252,7253,7254,7255,7256,7257,7258,7259,7260,7261,7262,7263,7264,7265,7266,7267,7268,7269,7270,7271,7272,7273,7274,7275,7276,7277,7278,7279,7280,7281,7282,7283,7284,7285,7286,7287,7288,7289,7290,7291,7292,7293,7294,7295,7296,7297,7298,7299,7300,7301,7302,7303,7304,7305,7306,7307,7308,7309,7310,7311,7312,7313,7314,7315,7316,7317,7318,7319,7320,7321,7322,7323,7324,7325,7326,7327,7328,7329,7330,7331,7332,7333,7334,7335,7336,7337,7338,7339,7340,7341,7342,7343,7344,7345,7346,7347,7348,7349,7350,7351,7352,7353,7354,7355,7356,7357,7358,7359,7360,7361,7362,7363,7364,7365,7366,7367,7368,7369,7370,7371,7372,7373,7374,7375,7376,7377,7378,7379,7380,7381,7382,7383,7384,7385,7386,7387,7388,7389,7390,7391,7392,7393,7394,7395,7396,7397,7398,7399,7400,7401,7402,7403,7404,7405,7406,7407,7408,7409,7410,7411,7412,7413,7414,7415,7416,7417,7418,7419,7420,7421,7422,7423,7424,7425,7426,7427,7428,7429,7430,7431,7432,7433,7434,7435,7436,7437,7438,7439,7440,7441,7442,7443,7444,7445,7446,7447,7448,7449,7450,7451,7452,7453,7454,7455,7456,7457,7458,7459,7460,7461,7462,7463,7464,7465,7466,7467,7468,7469,7470,7471,7472,7473,7474,7475,7476,7477,7478,7479,7480,7481,7482,7483,7484,7485,7486,7487,7488,7489,7490,7491,7492,7493,7494,7495,7496,7497,7498,7499,7500,7501,7502,7503,7504,7505,7506,7507,7508,7509,7510,7511,7512,7513,7514,7515,7516,7517,7518,7519,7520,7521,7522,7523,7524,7525,7526,7527,7528,7529,7530,7531,7532,7533,7534,7535,7536,7537,7538,7539,7540,7541,7542,7543,7544,7545,7546,7547,7548,7549,7550,7551,7552,7553,7554,7555,7556,7557,7558,7559,7560,7561,7562,7563,7564,7565,7566,7567,7568,7569,7570,7571,7572,7573,7574,7575,7576,7577,7578,7579,7580,7581,7582,7583,7584,7585,7586,7587,7588,7589,7590,7591,7592,7593,7594,7595,7596,7597,7598,7599,7600,7601,7602,7603,7604,7605,7606,7607,7608,7609,7610,7611,7612,7613,7614,7615,7616,7617,7618,7619,7620,7621,7622,7623,7624,7625,7626,7627,7628,7629,7630,7631,7632,7633,7634,7635,7636,7637,7638,7639,7640,7641,7642,7643,7644,7645,7646,7647,7648,7649,7650,7651,7652,7653,7654,7655,7656,7657,7658,7659,7660,7661,7662,7663,7664,7665,7666,7667,7668,7669,7670,7671,7672,7673,7674,7675,7676,7677,7678,7679,7680,7681,7682,7683,7684,7685,7686,7687,7688,7689,7690,7691,7692,7693,7694,7695,7696,7697,7698,7699,7700,7701,7702,7703,7704,7705,7706,7707,7708,7709,7710,7711,7712,7713,7714,7715,7716,7717,7718,7719,7720,7721,7722,7723,7724,7725,7726,7727,7728,7729,7730,7731,7732,7733,7734,7735,7736,7737,7738,7739,7740,7741,7742,7743,7744,7745,7746,7747,7748,7749,7750,7751,7752,7753,7754,7755,7756,7757,7758,7759,7760,7761,7762,7763,7764,7765,7766,7767,7768,7769,7770,7771,7772,7773,7774,7775,7776,7777,7778,7779,7780,7781,7782,7783,7784,7785,7786,7787,7788,7789,7790,7791,7792,7793,7794,7795,7796,7797,7798,7799,7800,7801,7802,7803,7804,7805,7806,7807,7808,7809,7810,7811,7812,7813,7814,7815,7816,7817,7818,7819,7820,7821,7822,7823,7824,7825,7826,7827,7828,7829,7830,7831,7832,7833,7834,7835,7836,7837,7838,7839,7840,2195,7841,7842,2196,7843,2197,7844,2198,7845,2199,7846,7847,2200,7848,2201,7849,2202,7850,2203,7851,2204,7852,2205,7853,2206,7854,2207,7855,2208,7856,2209,7857,2210,2211,7858,2212,7859,2213,7860,2214,7861,2215,7862,2216,7863,2217,7864,2218,7865,2219,7866,2220,7867,2221,7868,2222,7869,2223,7870,2224,7871,2225,7872,2226,7873,2227,7874,2228,7875,2229,7876,2230,7877,2231,7878,2232,7879,2233,7880,2234,7881,2235,7882,2236,7883,2237,7884,2238,7885,2239,7886,2240,7887,2241,7888,2242,7889,2243,7890,2244,7891,2245,7892,2246,7893,2247,7894,2248,7895,2249,7896,2250,7897,2251,7898,2252,7899,2253,7900,2254,7901,2255,7902,2256,7903,2257,7904,2258,7905,2259,7906,2260,7907,2261,7908,2262,7909,2263,7910,2264,7911,2265,7912,2266,7913,2267,7914,2268,7915,2269,7916,2270,7917,2271,7918,2272,7919,2273,7920,2274,7921,2275,7922,2276,7923,2277,7924,2278,7925,2279,7926,2280,7927,2281,7928,2282,7929,2283,7930,2284,7931,2285,7932,2286,7933,2287,7934,2288,7935,2289,7936,2290,7937,2291,7938,2292,7939,2293,7940,2294,7941,2295,7942,2296,7943,2297,7944,2298,7945,2299,7946,2300,7947,2301,7948,2302,7949,2303,7950,2304,7951,2305,7952,2306,7953,2307,7954,2308,7955,2309,7956,2310,7957,2311,7958,2312,7959,2313,7960,2314,7961,2315,7962,2316,7963,2317,7964,2318,7965,2319,7966,2320,7967,2321,7968,2322,7969,2323,7970,2324,7971,2325,7972,2326,7973,2327,7974,2328,7975,2329,7976,2330,7977,2331,7978,2332,7979,2333,2334,7980,2335,7981,2336,7982,2337,7983,2338,7984,2339,7985,2340,7986,2341,7987,2342,7988,2343,7989,2344,7990,2345,7991,2346,7992,2347,7993,2348,7994,2349,7995,2350,7996,2351,7997,2352,7998,2353,7999,2354,8000,2355,8001,2356,8002,2357,8003,2358,8004,2359,8005,2360,8006,2361,8007,2362,8008,2363,8009,2364,8010,2365,8011,2366,8012,2367,8013,2368,8014,2369,8015,2370,8016,2371,8017,2372,8018,2373,8019,2374,8020,2375,8021,2376,8022,2377,8023,2378,8024,2379,8025,2380,8026,2381,8027,2382,8028,2383,8029,2384,8030,2385,8031,2386,8032,2387,8033,2388,8034,2389,8035,2390,8036,2391,8037,2392,8038,2393,8039,2394,8040,2395,8041,2396,8042,2397,8043,2398,8044,2399,8045,2400,8046,2401,8047,2402,8048,2403,8049,2404,8050,2405,8051,9212,2406,9213,2407,9214,2408,9215,2409,9216,2410,9217,2411,9218,2412,9219,2413,9220,2414,9221,2415,9222,2416,9223,2417,9224,2418,9225,2419,9226,2420,9227,2421,9228,9229,2422,9230,2423,9231,2424,9232,2425,9233,2426,9234,2427,9235,2428,9236,2429,9237,2430,9238,2431,9239,2432,9240,2433,9241,2434,9242,2435,9243,2436,9244,2437,9245,2438,9246,2439,9247,2440,9248,2441,9249,2442,9250,2443,9251,2444,9252,2445,9253,2446,9254,2447,9255,2448,9256,2449,9257,2450,9258,2451,9259,2452,9260,2453,9261,2454,9262,2455,9263,2456,9264,2457,9265,2458,9266,2459,9267,2460,9268,2461,9269,2462,9270,2463,9271,2464,9272,2465,9273,2466,9274,2467,9275,2468,9276,2469,9277,2470,9278,2471,9279,2472,9280,2473,9281,2474,9282,2475,9283,2476,9284,2477,9285,2478,9286,2479,9287,2480,9288,2481,9289,2482,9290,2483,9291,2484,9292,2485,9293,2486,9294,2487,9295,2488,9296,2489,9297,2490,9298,2491,9299,2492,2493,9300,2494,9301,2495,9302,2496,9303,2497,9304,2498,9305,2499,9306,2500,9307,2501,9308,2502,9309,2503,9310,2504,9311,2505,9312,2506,9313,2507,9314,2508,9315,2509,9316,2510,9317,2511,9318,2512,9319,2513,9320,2514,9321,2515,9322,2516,9323,2517,9324,2518,9325,2519,9326,2520,9327,2521,9328,2522,9329,2523,9330,2524,9331,2525,9332,2526,9333,2527,9334,2528,9335,2529,9336,2530,9337,2531,9338,2532,9339,2533,9340,2534,9341,2535,9342,2536,9343,2537,9344,2538,9345,2539,9346,2540,9347,2541,9348,2542,9349,2543,9350,2544,9351,2545,9352,2546,9353,2547,9354,2548,9355,2549,9356,2550,9357,2551,9358,2552,9359,2553,9360,2554,9361,2555,9362,2556,9363,2557,9364,2558,9365,2559,9366,2560,9367,2561,9368,2562,9369,2563,9370,2564,9371,2565,9372,2566,9373,2567,9374,2568,9375,2569,9376,2570,9377,2571,9378,2572,9379,2573,9380,2574,9381,2575,9382,2576,9383,2577,9384,2578,9385,2579,9386,2580,9387,2581,9388,2582,9389,2583,9390,2584,9391,2585,9392,2586,9393,2587,9394,2588,9395,2589,9396,2590,9397,2591,9398,2592,9399,2593,9400,2594,9401,2595,9402,2596,9403,2597,9404,2598,9405,2599,9406,2600,9407,2601,9408,2602,9409,2603,9410,2604,9411,2605,9412,2606,9413,2607,9414,2608,9415,2609,9416,2610,9417,2611,9418,2612,9419,2613,9420,2614,9421,2615,9422,2616,9423,2617,9424,2618,9425,2619,9426,2620,9427,2621,9428,2622,9429,2623,9430,2624,2625,2626,9431,2627,9432,2628,9433,2629,9434,2630,9435,2631,9436,2632,9437,2633,9438,2634,9439,2635,9440,2636,9441,2637,9442,2638,9443,2639,9444,2640,9445,2641,9446,2642,9447,2643,9448,2644,9449,2645,9450,2646,9451,2647,9452,2648,9453,2649,9454,9455,9456,9457,9458,9459,9460,2650,2651,9461,2652,9462,2653,9463,2654,9464,2655,9465,2656,9466,2657,9467,2658,9468,2659,9469,2660,9470,2661,9471,2662,9472,2663,9473,2664,9474,2665,9475,2666,9476,2667,9477,2668,9478,2669,9479,2670,9480,2671,9481,2672,9482,2673,9483,2674,9484,2675,9485,2676,9486,2677,9487,2678,9488,2679,9489,2680,9490,2681,9491,2682,9492,2683,9493,2684,9494,2685,9495,2686,9496,2687,9497,2688,9498,2689,9499,2690,9500,2691,9501,2692,9502,2693,9503,2694,9504,2695,9505,2696,9506,2697,9507,2698,9508,2699,9509,2700,9510,2701,9511,2702,9512,2703,9513,2704,9514,2705,9515,2706,9516,2707,9517,2708,9518,2709,9519,2710,9520,2711,9521,2712,9522,2713,9523,2714,9524,2715,9525,2716,9526,2717,9527,2718,9528,2719,9529,2720,9530,2721,9531,2722,9532,2723,9533,2724,9534,2725,9535,2726,9536,2727,9537,2728,9538,2729,9539,2730,9540,2731,9541,2732,9542,2733,9543,2734,9544,2735,9545,2736,9546,2737,9547,2738,9548,2739,9549,2740,9550,2741,9551,2742,9552,2743,9553,2744,9554,2745,9555,2746,9556,2747,9557,2748,9558,2749,9559,2750,9560,2751,9561,2752,9562,2753,9563,2754,9564,2755,9565,2756,9566,2757,9567,2758,9568,2759,9569,2760,9570,2761,9571,2762,9572,2763,9573,2764,9574,2765,9575,2766,9576,2767,9577,2768,9578,2769,9579,2770,9580,2771,9581,2772,9582,2773,9583,2774,9584,2775,9585,2776,9586,2777,9587,2778,9588,2779,9589,2780,9590,2781,9591,2782,9592,2783,9593,2784,9594,2785,9595,2786,9596,2787,9597,2788,9598,2789,9599,2790,9600,2791,9601,2792,9602,2793,9603,2794,9604,2795,9605,2796,9606,2797,9607,2798,9608,2799,9609,2800,9610,2801,9611,2802,9612,2803,9613,2804,9614,2805,9615,2806,9616,2807,9617,2808,9618,2809,9619,2810,9620,2811,9621,2812,9622,2813,9623,2814,9624,9625,2815,2816,2817,2818,2819,2820,2821,2822,2823,9626,2824,2825,2826,2827,9627,2828,9628,2829,9629,2830,2831,9630,2832,9631,2833,9632,2834,9633,2835,9634,2836,9635,2837,9636,2838,9637,9638,2839,9639,2840,9640,2841,9641,2842,9642,2843,9643,2844,9644,2845,9645,2846,9646,2847,9647,2848,9648,2849,9649,2850,9650,2851,9651,2852,9652,2853,9653,2854,9654,2855,9655,2856,9656,2857,9657,2858,9658,2859,9659,2860,9660,2861,9661,2862,9662,2863,9663,2864,9664,2865,9665,2866,9666,2867,9667,2868,9668,2869,9669,2870,9670,2871,9671,2872,9672,2873,9673,2874,9674,2875,9675,2876,9676,2877,9677,2878,9678,2879,9679,2880,9680,2881,9681,2882,9682,2883,9683,2884,9684,2885,9685,2886,9686,2887,9687,2888,9688,2889,9689,2890,9690,2891,9691,2892,9692,2893,9693,2894,9694,2895,9695,2896,9696,2897,9697,2898,9698,2899,9699,2900,9700,2901,9701,2902,9702,2903,9703,2904,9704,2905,9705,2906,9706,2907,9707,2908,9708,2909,9709,2910,9710,2911,9711,2912,9712,2913,9713,2914,9714,2915,9715,2916,9716,2917,9717,2918,9718,2919,9719,2920,9720,2921,9721,2922,9722,2923,9723,2924,9724,2925,9725,2926,9726,2927,9727,2928,9728,2929,9729,2930,9730,2931,9731,2932,9732,2933,9733,2934,9734,2935,9735,2936,9736,2937,9737,2938,9738,2939,9739,2940,9740,2941,9741,2942,9742,2943,9743,2944,9744,2945,9745,2946,9746,2947,9747,2948,9748,2949,9749,2950,9750,2951,9751,2952,9752,2953,9753,2954,9754,2955,9755,2956,9756,2957,9757,2958,9758,2959,9759,2960,9760,2961,9761,2962,9762,2963,9763,2964,9764,2965,9765,2966,9766,2967,9767,2968,9768,2969,9769,2970,9770,2971,9771,2972,9772,2973,9773,2974,9774,2975,9775,2976,9776,2977,9777,2978,9778,2979,9779,2980,9780,2981,9781,2982,9782,2983,9783,2984,9784,2985,9785,2986,9786,2987,9787,2988,9788,2989,9789,2990,9790,2991,9791,2992,9792,2993,9793,2994,9794,2995,9795,2996,9796,2997,9797,2998,9798,2999,9799,3000,9800,3001,9801,3002,9802,3003,9803,3004,9804,3005,9805,3006,9806,3007,9807,3008,9808,3009,9809,3010,9810,3011,9811,3012,9812,3013,9813,3014,9814,3015,9815,3016,9816,3017,9817,3018,9818,3019,9819,3020,9820,3021,9821,3022,9822,3023,9823,3024,9824,3025,9825,3026,9826,3027,9827,3028,9828,3029,9829,3030,9830,3031,9831,3032,9832,3033,9833,3034,9834,3035,9835,3036,9836,3037,9837,3038,9838,3039,9839,3040,3041,3042,9840,3043,9841,3044,9842,3045,9843,3046,9844,3047,9845,3048,9846,3049,9847,3050,9848,3051,9849,3052,9850,3053,9851,3054,9852,3055,9853,3056,9854,3057,9855,3058,9856,3059,9857,3060,9858,3061,9859,3062,9860,3063,9861,3064,9862,3065,9863,3066,9864,3067,9865,3068,9866,3069,9867,3070,9868,3071,9869,3072,3073,9870,3074,9871,3075,9872,3076,9873,3077,9874,3078,9875,3079,9876,3080,9877,3081,9878,3082,9879,3083,9880,3084,9881,3085,9882,3086,9883,3087,9884,3088,9885,3089,9886,3090,9887,3091,9888,3092,9889,3093,9890,3094,9891,3095,9892,3096,9893,3097,9894,3098,9895,3099,9896,3100,9897,3101,9898,3102,9899,3103,9900,3104,9901,3105,9902,3106,9903,3107,9904,3108,9905,3109,9906,3110,9907,3111,9908,3112,9909,3113,9910,3114,9911,3115,9912,3116,9913,3117,9914,3118,9915,3119,9916,3120,9917,3121,9918,3122,9919,3123,9920,3124,9921,3125,9922,3126,9923,3127,9924,3128,9925,3129,9926,3130,9927,3131,9928,3132,9929,3133,9930,3134,9931,3135,9932,3136,9933,3137,9934,3138,9935,3139,9936,3140,9937,3141,9938,3142,9939,3143,9940,3144,9941,3145,9942,3146,9943,3147,9944,3148,9945,3149,9946,3150,9947,3151,9948,3152,9949,3153,9950,3154,9951,3155,9952,3156,9953,3157,9954,3158,9955,3159,9956,3160,9957,3161,9958,3162,9959,3163,3164,9960,3165,9961,3166,9962,3167,9963,3168,9964,3169,9965,3170,9966,3171,9967,3172,9968,3173,9969,3174,9970,3175,9971,3176,9972,3177,9973,3178,9974,3179,9975,3180,9976,3181,9977,3182,9978,3183,9979,3184,9980,3185,9981,3186,9982,3187,9983,3188,9984,3189,9985,3190,9986,3191,9987,3192,9988,3193,9989,3194,9990,3195,9991,3196,9992,3197,9993,3198,9994,3199,9995,3200,9996,3201,9997,3202,9998,3203,9999,3204,10000,3205,10001,3206,10002,3207,10003,3208,10004,3209,10005,3210,10006,3211,10007,3212,10008,3213,10009,3214,10010,3215,10011,3216,10012,3217,10013,3218,10014,3219,10015,3220,10016,3221,10017,3222,10018,3223,10019,3224,3225,10020,3226,10021,3227,10022,3228,10023,3229,10024,3230,10025,3231,10026,3232,10027,3233,10028,3234,10029,3235,3236,10030,3237,10031,3238,10032,3239,10033,3240,10034,3241,10035,3242,10036,3243,10037,3244,10038,3245,10039,3246,10040,3247,10041,3248,10042,3249,10043,3250,10044,3251,10045,3252,10046,3253,10047,3254,10048,3255,10049,3256,3257,10050,3258,10051,3259,10052,3260,10053,3261,10054,3262,10055,3263,10056,3264,10057,3265,10058,3266,10059,3267,10060,3268,10061,3269,10062,3270,10063,3271,10064,3272,10065,3273,10066,3274,10067,3275,10068,3276,10069,3277,3278,10070,3279,10071,3280,10072,3281,10073,3282,10074,3283,10075,3284,10076,3285,10077,3286,10078,3287,10079,3288,10080,3289,10081,3290,10082,3291,10083,3292,10084,3293,3294,10085,3295,10086,3296,10087,3297,10088,3298,10089,3299,10090,3300,10091,3301,10092,3302,10093,3303,10094,3304,10095,3305,10096,3306,10097,3307,10098,3308,10099,3309,10100,3310,10101,3311,10102,3312,10103,3313,10104,3314,10105,3315,10106,3316,10107,3317,10108,3318,10109,3319,10110,3320,10111,3321,10112,3322,10113,3323,10114,3324,10115,3325,10116,3326,10117,3327,10118,3328,10119,3329,10120,3330,10121,3331,10122,3332,10123,3333,10124,3334,10125,3335,10126,3336,10127,3337,10128,3338,10129,3339,10130,3340,10131,3341,10132,3342,10133,3343,10134,3344,10135,3345,10136,3346,10137,3347,10138,3348,10139,3349,10140,3350,10141,3351,10142,3352,10143,3353,10144,3354,10145,3355,10146,3356,10147,3357,10148,3358,10149,3359,10150,3360,10151,3361,10152,3362,10153,3363,10154,3364,10155,3365,10156,3366,10157,3367,10158,3368,10159,3369,10160,3370,10161,3371,10162,3372,10163,3373,10164,3374,10165,3375,10166,3376,10167,3377,10168,3378,10169,3379,3380,10170,3381,10171,3382,10172,3383,10173,3384,10174,3385,10175,3386,10176,3387,10177,3388,10178,3389,10179,3390,10180,3391,10181,3392,10182,3393,10183,3394,10184,3395,10185,3396,10186,3397,10187,3398,10188,3399,10189,3400,10190,3401,10191,3402,10192,3403,10193,3404,10194,3405,3406,10195,3407,10196,3408,10197,3409,10198,3410,10199,3411,3412,10200,3413,10201,3414,10202,3415,10203,3416,10204,3417,10205,3418,10206,3419,10207,3420,10208,3421,10209,3422,10210,3423,10211,3424,10212,3425,10213,3426,10214,3427,10215,3428,10216,3429,10217,3430,10218,3431,10219,3432,10220,3433,10221,3434,10222,3435,10223,3436,10224,3437,10225,3438,10226,3439,10227,3440,10228,3441,10229,3442,3443,10230,3444,10231,3445,10232,3446,10233,3447,10234,3448,10235,3449,10236,3450,10237,3451,10238,3452,10239,3453,10240,3454,10241,3455,10242,3456,10243,3457,10244,3458,10245,3459,3460,10246,3461,10247,3462,10248,3463,10249,3464,10250,3465,10251,3466,10252,3467,10253,3468,10254,3469,10255,3470,10256,3471,10257,3472,10258,3473,10259,3474,3475,10260,3476,10261,3477,10262,3478,10263,3479,10264,3480,10265,3481,10266,3482,10267,10268,3483,3484,3485,3486,3487,3488,3489,10269,3490,3491,3492,10270,3493,10271,3494,10272,3495,10273,3496,10274,3497,10275,3498,10276,3499,10277,10278,3500,10279,3501,10280,3502,10281,3503,10282,3504,10283,3505,10284,3506,10285,3507,10286,3508,10287,3509,10288,3510,10289,3511,10290,3512,10291,3513,10292,3514,10293,3515,10294,3516,10295,3517,10296,3518,10297,3519,10298,10299,3520,10300,3521,10301,3522,10302,3523,10303,3524,10304,3525,10305,3526,10306,3527,10307,3528,10308,3529,10309,3530,10310,3531,10311,3532,10312,3533,10313,3534,10314,3535,10315,3536,10316,3537,10317,3538,10318,3539,10319,3540,10320,3541,10321,3542,10322,3543,10323,3544,10324,3545,10325,3546,10326,3547,10327,3548,10328,3549,10329,3550,10330,10331,3551,10332,3552,10333,3553,10334,3554,10335,3555,10336,3556,10337,3557,10338,3558,10339,3559,10340,3560,10341,3561,10342,3562,10343,3563,10344,3564,10345,3565,10346,3566,10347,3567,10348,3568,10349,3569,10350,3570,10351,3571,10352,3572,10353,3573,10354,3574,10355,3575,10356,3576,10357,3577,10358,3578,10359,3579,10360,3580,10361,3581,10362,3582,10363,3583,10364,3584,10365,3585,10366,3586,10367,3587,10368,3588,10369,3589,10370,3590,10371,3591,10372,3592,10373,3593,10374,3594,10375,3595,10376,3596,10377,3597,10378,3598,10379,3599,10380,10381,3600,10382,3601,10383,3602,10384,3603,10385,3604,10386,3605,10387,3606,10388,3607,10389,3608,10390,3609,10391,3610,10392,3611,10393,3612,10394,3613,10395,3614,10396,3615,10397,3616,10398,3617,10399,3618,10400,3619,10401,3620,10402,3621,10403,3622,10404,3623,10405,3624,10406,3625,10407,3626,10408,3627,10409,3628,10410,3629,10411,3630,10412,3631,10413,3632,10414,3633,10415,3634,10416,3635,10417,3636,10418,3637,10419,3638,10420,3639,10421,3640,10422,3641,10423,3642,10424,3643,10425,3644,10426,3645,10427,3646,10428,3647,10429,3648,10430,3649,10431,3650,10432,3651,10433,3652,10434,3653,10435,3654,10436,3655,10437,3656,10438,3657,10439,3658,10440,3659,10441,3660,10442,3661,10443,3662,10444,3663,10445,3664,10446,3665,10447,3666,10448,3667,10449,3668,10450,3669,10451,3670,10452,3671,10453,3672,10454,3673,10455,3674,10456,10457,3675,10458,3676,10459,3677,10460,3678,10461,3679,10462,3680,10463,3681,10464,3682,10465,3683,10466,3684,10467,10468,3685,3686,10469,3687,10470,3688,10471,3689,10472,3690,10473,3691,10474,3692,10475,3693,10476,3694,10477,3695,10478,3696,10479,3697,10480,3698,10481,3699,10482,3700,10483,3701,10484,3702,10485,3703,10486,3704,10487,3705,10488,3706,10489,3707,10490,3708,10491,3709,10492,3710,10493,3711,10494,3712,10495,3713,10496,3714,10497,3715,10498,3716,10499,3717,10500,3718,10501,3719,10502,3720,10503,3721,10504,3722,10505,3723,10506,3724,10507,3725,10508,3726,10509,3727,10510,3728,10511,3729,10512,3730,10513,3731,10514,3732,10515,3733,10516,3734,10517,3735,10518,3736,10519,3737,10520,3738,10521,3739,10522,3740,10523,3741,10524,3742,10525,3743,10526,3744,10527,3745,10528,3746,10529,3747,10530,3748,10531,3749,10532,10533,10534,10535,10536,10537,10538,10539,10540,10541,10542,10543,10544,3750,10545,3751,10546,3752,10547,3753,10548,3754,10549,3755,10550,3756,10551,3757,10552,3758,10553,3759,10554,3760,10555,3761,10556,3762,10557,3763,10558,3764,10559,3765,10560,3766,10561,3767,10562,3768,10563,3769,10564,3770,10565,3771,10566,3772,10567,3773,10568,3774,10569,3775,10570,3776,10571,3777,10572,3778,10573,3779,10574,3780,10575,3781,10576,3782,10577,3783,10578,3784,10579,3785,10580,3786,10581,3787,10582,3788,10583,3789,10584,3790,10585,3791,10586,3792,10587,3793,10588,3794,10589,3795,10590,3796,10591,3797,10592,3798,10593,3799,10594,3800,10595,3801,10596,3802,10597,3803,10598,3804,10599,3805,10600,3806,10601,3807,10602,3808,10603,3809,10604,3810,10605,3811,10606,3812,10607,3813,10608,3814,10609,3815,10610,3816,10611,3817,10612,3818,10613,3819,10614,3820,10615,3821,10616,3822,10617,3823,10618,3824,10619,3825,10620,3826,10621,3827,10622,3828,10623,3829,10624,3830,10625,3831,10626,3832,10627,3833,10628,3834,10629,3835,10630,3836,10631,3837,10632,3838,10633,3839,10634,3840,10635,3841,10636,3842,10637,3843,10638,3844,10639,3845,10640,3846,10641,3847,10642,3848,10643,3849,10644,3850,10645,3851,10646,3852,10647,3853,10648,3854,10649,3855,3856,10650,3857,10651,3858,10652,3859,10653,3860,10654,3861,10655,3862,10656,3863,10657,3864,10658,3865,10659,3866,10660,3867,10661,3868,10662,10663,3869,10664,3870,10665,3871,10666,3872,10667,3873,10668,3874,10669,3875,10670,3876,10671,3877,10672,3878,10673,3879,10674,3880,10675,3881,10676,3882,10677,3883,10678,3884,10679,3885,10680,3886,10681,3887,10682,3888,10683,3889,10684,3890,10685,3891,10686,3892,10687,3893,10688,3894,10689,3895,10690,3896,10691,3897,10692,3898,10693,3899,10694,10695,3900,10696,3901,10697,3902,10698,3903,10699,3904,10700,3905,10701,3906,10702,3907,10703,3908,10704,3909,10705,3910,10706,3911,10707,3912,10708,3913,10709,3914,10710,3915,10711,3916,10712,3917,10713,3918,10714,3919,10715,3920,10716,3921,10717,3922,10718,3923,10719,3924,10720,3925,10721,3926,10722,3927,10723,3928,10724,3929,10725,3930,10726,3931,10727,3932,10728,3933,10729,3934,10730,3935,10731,3936,10732,3937,10733,3938,10734,3939,10735,3940,10736,3941,10737,3942,10738,3943,10739,3944,10740,3945,10741,3946,10742,3947,10743,3948,10744,3949,10745,3950,10746,3951,10747,3952,10748,3953,10749,3954,10750,3955,10751,3956,10752,3957,10753,3958,10754,3959,10755,3960,10756,3961,10757,3962,10758,3963,10759,3964,10760,3965,10761,3966,10762,3967,10763,3968,10764,3969,10765,3970,10766,3971,10767,3972,10768,3973,10769,3974,10770,3975,10771,3976,10772,3977,10773,3978,10774,3979,10775,3980,10776,3981,10777,3982,10778,3983,10779,3984,10780,3985,10781,3986,10782,3987,10783,3988,10784,3989,10785,3990,10786,3991,10787,3992,10788,3993,10789,3994,10790,3995,10791,3996,10792,3997,10793,3998,10794,3999,10795,4000,10796,4001,10797,4002,10798,4003,10799,4004,10800,4005,10801,4006,10802,4007,10803,4008,10804,4009,10805,4010,10806,4011,10807,4012,10808,4013,10809,4014,10810,4015,10811,4016,10812,4017,10813,4018,10814,4019,10815,4020,10816,4021,10817,4022,10818,4023,10819,4024,10820,4025,10821,4026,10822,4027,10823,4028,10824,4029,10825,4030,10826,4031,10827,4032,10828,4033,10829,4034,10830,4035,10831,4036,10832,4037,10833,4038,10834,4039,10835,4040,10836,4041,10837,4042,10838,4043,10839,4044,10840,4045,10841,4046,10842,4047,10843,4048,10844,4049,10845,4050,10846,4051,10847,4052,10848,4053,10849,4054,10850,4055,10851,4056,10852,4057,10853,4058,10854,4059,10855,4060,10856,4061,10857,4062,10858,4063,10859,4064,10860,4065,10861,4066,10862,4067,10863,4068,10864,4069,10865,4070,10866,4071,10867,4072,10868,4073,10869,4074,10870,4075,10871,4076,10872,4077,10873,4078,10874,4079,10875,4080,10876,4081,10877,4082,10878,4083,10879,4084,10880,4085,10881,4086,4087,10882,4088,10883,4089,10884,4090,10885,4091,10886,4092,10887,4093,10888,4094,10889,4095,10890,4096,10891,4097,10892,4098,10893,4099,10894,4100,10895,4101,10896,4102,10897,4103,10898,4104,10899,4105,10900,4106,10901,4107,10902,4108,10903,4109,10904,4110,10905,4111,10906,4112,10907,4113,10908,4114,10909,4115,10910,4116,10911,4117,10912,4118,10913,4119,10914,4120,10915,4121,10916,4122,10917,4123,10918,4124,10919,4125,10920,4126,10921,4127,10922,4128,10923,4129,10924,4130,10925,4131,10926,4132,4133,4134,4135,4136,4137,4138,4139,4140,10927,4141,4142,4143,4144,10928,4145,10929,4146,10930,4147,10931,4148,10932,4149,10933,4150,10934,4151,10935,4152,10936,4153,10937,4154,10938,4155,10939,4156,10940,4157,10941,4158,10942,4159,10943,4160,10944,4161,10945,4162,10946,4163,10947,4164,10948,4165,10949,4166,10950,4167,10951,4168,10952,4169,10953,4170,10954,4171,10955,4172,10956,4173,10957,4174,10958,4175,10959,4176,10960,4177,10961,4178,10962,4179,10963,4180,10964,4181,10965,4182,10966,4183,10967,4184,10968,4185,10969,4186,10970,4187,10971,4188,10972,4189,10973,4190,10974,4191,10975,4192,10976,4193,10977,4194,10978,4195,10979,4196,10980,10981,4197,4198,10982,4199,10983,4200,10984,4201,10985,4202,10986,4203,10987,4204,10988,4205,10989,4206,10990,4207,10991,4208,10992,4209,10993,4210,10994,4211,10995,4212,10996,4213,10997,4214,10998,4215,10999,4216,11000,4217,11001,4218,11002,4219,11003,4220,11004,4221,11005,4222,11006,4223,11007,4224,11008,4225,11009,4226,11010,4227,11011,4228,11012,4229,11013,4230,11014,4231,11015,4232,11016,4233,11017,4234,11018,4235,11019,4236,11020,4237,11021,4238,11022,4239,11023,4240,11024,4241,11025,4242,11026,4243,11027,11028,4244,11029,4245,11030,4246,11031,4247,11032,4248,11033,4249,11034,4250,11035,4251,11036,4252,11037,4253,11038,4254,11039,4255,11040,4256,11041,4257,11042,4258,11043,4259,11044,4260,11045,4261,11046,4262,11047,4263,11048,4264,11049,4265,11050,4266,11051,4267,11052,4268,11053,4269,11054,4270,11055,4271,11056,4272,11057,4273,11058,4274,11059,4275,11060,4276,11061,4277,11062,4278,11063,4279,11064,4280,11065,4281,11066,4282,11067,4283,11068,4284,11069,4285,11070,4286,11071,4287,11072,4288,11073,4289,11074,4290,11075,4291,11076,4292,11077,4293,11078,4294,11079,4295,11080,4296,11081,4297,11082,4298,11083,4299,11084,4300,11085,4301,11086,4302,11087,4303,11088,4304,11089,4305,11090,4306,11091,4307,11092,4308,11093,4309,11094,4310,4311,11095,4312,11096,4313,11097,4314,11098,4315,11099,4316,11100,4317,11101,4318,11102,4319,11103,4320,11104,4321,11105,4322,11106,4323,11107,4324,11108,4325,11109,4326,11110,4327,11111,4328,11112,4329,11113,4330,11114,4331,11115,4332,11116,4333,11117,4334,11118,4335,11119,4336,11120,4337,11121,4338,11122,4339,11123,4340,11124,4341,11125,4342,11126,4343,11127,4344,11128,4345,11129,4346,11130,4347,11131,4348,11132,4349,11133,4350,11134,4351,11135,4352,11136,4353,11137,4354,11138,4355,11139,4356,11140,4357,11141,4358,11142,4359,11143,4360,11144,4361,11145,4362,11146,4363,11147,4364,11148,4365,11149,4366,11150,4367,11151,4368,11152,4369,11153,4370,11154,4371,11155,4372,11156,4373,11157,4374,11158,4375,11159,4376,11160,4377,11161,4378,11162,4379,11163,4380,11164,4381,11165,4382,11166,4383,11167,4384,11168,4385,11169,4386,11170,4387,11171,4388,11172,4389,11173,4390,11174,4391,11175,4392,11176,4393,11177,4394,11178,4395,11179,4396,11180,4397,11181,4398,11182,4399,11183,4400,11184,4401,11185,4402,11186,4403,11187,4404,11188,4405,11189,4406,11190,4407,11191,4408,11192,4409,11193,4410,11194,4411,11195,4412,11196,4413,11197,4414,11198,4415,11199,4416,11200,4417,11201,4418,11202,4419,11203,4420,11204,4421,11205,4422,11206,4423,11207,4424,11208,4425,11209,4426,11210,4427,11211,4428,11212,4429,11213,4430,11214,4431,11215,4432,11216,4433,11217,4434,11218,4435,11219,4436,11220,4437,11221,4438,11222,4439,11223,4440,11224,4441,11225,4442,11226,4443,11227,4444,11228,4445,11229,4446,11230,4447,11231,4448,11232,4449,11233,4450,11234,4451,11235,4452,11236,4453,11237,4454,11238,4455,11239,4456,11240,4457,11241,4458,11242,4459,11243,4460,11244,4461,11245,4462,11246,4463,11247,4464,11248,4465,11249,4466,11250,4467,11251,4468,11252,4469,11253,4470,11254,4471,11255,4472,11256,4473,11257,4474,11258,4475,11259,4476,11260,4477,11261,4478,11262,4479,11263,4480,11264,4481,11265,4482,11266,4483,11267,4484,11268,4485,11269,4486,11270,4487,11271,4488,11272,4489,11273,4490,11274,4491,11275,4492,11276,4493,11277,4494,11278,4495,11279,4496,11280,4497,11281,4498,11282,4499,11283,11284,11285,11286,11287,11288,11289,11290,11291,11292,11293,11294,11295,11296,11297,11298,11299,11300,11301,11302,11303,11304,11305,11306,11307,11308,11309,11310,11311,11312,11313,11314,11315,11316,11317,11318,11319,11320,11321,11322,11323,11324,11325,11326,11327,11328,11329,11330,11331,11332,11333,11334,11335,11336,11337,11338,11339,11340,11341,11342,11343,11344,11345,11346,11347,11348,11349,11350,11351,11352,11353,11354,11355,11356,11357,11358,11359,11360,11361,11362,11363,11364,11365,11366,11367,11368,11369,11370,11371,11372,11373,11374,11375,11376,11377,11378,11379,11380,11381,11382,11383,11384,11385,11386,11387,11388,11389,11390,11391,11392,11393,11394,11395,11396,11397,11398,11399,11400,11401,11402,11403,11404,11405,11406,11407,11408,11409,11410,11411,11412,11413,11414,11415,11416,11417,11418,11419,11420,11421,11422,11423,11424,11425,11426,11427,11428,11429,11430,11431,11432,11433,11434,11435,11436,11437,11438,11439,11440,11441,11442,11443,11444,11445,11446,11447,11448,11449,11450,11451,11452,11453,11454,11455,11456,11457,11458,11459,11460,11461,11462,11463,11464,11465,11466,11467,11468,11469,11470,11471,11472,11473,11474,11475,11476,11477,11478,11479,11480,11481,11482,11483,11484,11485,11486,11487,11488,11489,11490,11491,11492,11493,11494,11495,11496,11497,11498,11499,11500,11501,11502,11503,11504,11505,11506,11507,11508,11509,11510,11511,11512,11513,11514,11515,11516,11517,11518,11519,11520,11521,11522,11523,11524,11525,11526,11527,11528,11529,11530,11531,11532,11533,11534,11535,11536,11537,11538,11539,11540,11541,11542,11543,11544,11545,11546,11547,11548,11549,11550,11551,11552,11553,11554,11555,11556,11557,11558,11559,11560,11561,11562,11563,11564,11565,11566,11567,11568,11569,11570,11571,11572,11573,11574,11575,11576,11577,11578,11579,11580,11581,11582,11583,11584,11585,11586,11587,11588,11589,11590,11591,11592,11593,11594,11595,11596,11597,11598,11599,11600,11601,11602,11603,11604,11605,11606,11607,11608,11609,11610,11611,11612,11613,11614,11615,11616,11617,11618,11619,11620,11621,11622,11623,11624,11625,11626,11627,11628,11629,11630,11631,11632,11633,11634,11635,11636,11637,11638,11639,11640,11641,11642,11643,11644,11645,11646,11647,11648,11649,11650,11651,11652,11653,11654,11655,11656,11657,11658,11659,11660,11661,11662,11663,11664,11665,11666,11667,11668,11669,11670,11671,11672,11673,11674,11675,11676,11677,11678,11679,11680,11681,11682,11683,11684,11685,11686,11687,11688,11689,11690,11691,11692,11693,11694,11695,11696,11697,11698,11699,11700,11701,11702,11703,11704,11705,11706,11707,11708,11709,11710,11711,11712,11713,11714,11715,11716,11717,11718,11719,11720,11721,11722,11723,11724,11725,11726,11727,11728,11729,11730,11731,11732,11733,11734,11735,11736,11737,11738,11739,11740,11741,11742,11743,11744,11745,11746,11747,11748,11749,11750,11751,11752,11753,11754,11755,11756,11757,11758,11759,11760,11761,11762,11763,11764,11765,11766,11767,11768,11769,11770,11771,11772,11773,8052,11774,11775,8053,11776,11777,8054,11778,8055,11779,8056,11780,8057,11781,8058,11782,8059,11783,8060,11784,8061,11785,8062,11786,8063,11787,8064,11788,8065,11789,8066,11790,8067,11791,8068,11792,8069,11793,8070,11794,8071,11795,8072,11796,8073,11797,8074,11798,8075,11799,8076,11800,8077,11801,8078,11802,8079,11803,8080,11804,8081,11805,8082,11806,8083,11807,8084,11808,8085,11809,8086,11810,8087,11811,8088,11812,8089,11813,8090,11814,8091,11815,8092,11816,8093,11817,8094,11818,8095,11819,8096,11820,8097,11821,8098,11822,8099,11823,8100,11824,8101,11825,8102,11826,8103,11827,8104,11828,8105,11829,8106,11830,8107,11831,8108,11832,8109,11833,8110,11834,8111,11835,8112,11836,8113,11837,8114,11838,8115,11839,8116,11840,8117,11841,8118,11842,8119,11843,8120,11844,8121,11845,8122,11846,8123,11847,8124,11848,8125,11849,8126,11850,8127,11851,8128,11852,8129,11853,8130,11854,8131,11855,8132,11856,8133,11857,8134,11858,8135,11859,8136,11860,8137,11861,8138,11862,8139,11863,8140,11864,8141,11865,8142,11866,8143,11867,8144,11868,8145,11869,8146,11870,8147,11871,8148,11872,8149,11873,8150,11874,8151,11875,8152,11876,8153,11877,8154,11878,8155,11879,11880,11881,11882,11883,11884,11885,11886,11887,11888,11889,11890,11891,11892,11893,11894,11895,11896,11897,11898,11899,11900,11901,11902,11903,11904,11905,11906,11907,11908,11909,11910,11911,11912,11913,11914,11915,11916,11917,11918,11919,11920,11921,11922,11923,11924,11925,11926,11927,11928,11929,11930,11931,11932,11933,11934,11935,11936,11937,11938,11939,8156,11940,11941,11942,11943,8157,11944,8158,11945,8159,11946,11947,8160,11948,8161,11949,8162,11950,8163,11951,8164,11952,8165,11953,8166,11954,8167,11955,8168,11956,8169,11957,8170,11958,8171,11959,8172,11960,8173,11961,8174,11962,8175,11963,8176,11964,8177,11965,8178,11966,8179,11967,8180,11968,8181,11969,8182,11970,8183,11971,8184,11972,8185,11973,8186,11974,8187,11975,8188,11976,8189,11977,8190,11978,8191,11979,8192,11980,8193,11981,8194,11982,8195,11983,8196,11984,8197,11985,8198,11986,8199,11987,8200,11988,8201,11989,8202,11990,8203,11991,8204,11992,8205,11993,8206,11994,8207,11995,8208,11996,8209,11997,8210,11998,8211,11999,8212,8213,12000,8214,12001,8215,12002,8216,12003,8217,12004,8218,12005,8219,12006,12007,12008,12009,12010,12011,8220,8221,8222,8223,8224,8225,8226,8227,8228,8229,8230,8231,8232,8233,8234,12012,8235,8236,12013,8237,12014,8238,8239,12015,8240,12016,8241,12017,8242,12018,8243,12019,8244,12020,8245,12021,8246,12022,8247,12023,8248,12024,12025,12026,12027,12028,12029,12030,12031,12032,12033,12034,12035,12036,12037,12038,12039,12040,12041,12042,12043,12044,12045,12046,12047,8249,12048,8250,12049,8251,12050,8252,12051,8253,12052,8254,12053,8255,12054,8256,12055,8257,12056,8258,12057,8259,12058,8260,12059,8261,12060,8262,12061,8263,12062,8264,12063,8265,12064,8266,12065,8267,12066,8268,12067,8269,12068,8270,12069,8271,12070,8272,12071,8273,12072,8274,12073,8275,12074,8276,12075,8277,12076,8278,12077,8279,12078,8280,12079,8281,12080,8282,12081,8283,12082,8284,12083,8285,12084,8286,12085,8287,12086,8288,12087,8289,12088,8290,12089,8291,12090,8292,12091,8293,12092,8294,12093,8295,12094,8296,12095,8297,12096,8298,12097,8299,12098,8300,12099,8301,12100,8302,12101,8303,12102,8304,12103,8305,12104,8306,12105,8307,12106,8308,12107,8309,12108,8310,12109,8311,12110,8312,12111,8313,12112,8314,12113,8315,12114,8316,12115,8317,12116,8318,12117,8319,12118,8320,12119,8321,12120,8322,12121,8323,12122,8324,12123,8325,12124,8326,12125,8327,12126,8328,12127,8329,12128,8330,12129,8331,12130,8332,12131,8333,12132,8334,12133,8335,12134,8336,12135,8337,12136,8338,12137,8339,12138,8340,12139,8341,12140,8342,12141,8343,12142,8344,12143,8345,12144,8346,12145,8347,12146,8348,12147,8349,12148,8350,12149,8351,12150,8352,12151,8353,12152,8354,12153,8355,12154,8356,12155,8357,12156,8358,12157,8359,12158,8360,12159,8361,12160,8362,12161,8363,12162,8364,12163,8365,12164,8366,12165,8367,12166,8368,12167,8369,12168,8370,12169,8371,12170,8372,12171,8373,12172,8374,12173,8375,12174,8376,12175,8377,12176,8378,12177,8379,8380,8381,12178,8382,12179,8383,8384,12180,8385,12181,8386,12182,8387,12183,8388,12184,8389,12185,8390,12186,8391,12187,8392,12188,8393,12189,8394,12190,8395,12191,8396,12192,8397,12193,8398,12194,8399,12195,8400,12196,8401,12197,8402,12198,8403,12199,8404,12200,8405,12201,8406,8407,8408,8409,8410,8411,8412,8413,8414,8415,8416,8417,8418,8419,8420,8421,12202,8422,8423,8424,8425,12203,8426,12204,8427,12205,8428,12206,8429,12207,8430,12208,8431,8432,12209,8433,12210,8434,12211,8435,12212,8436,12213,8437,12214,8438,12215,8439,12216,8440,12217,8441,12218,8442,12219,8443,12220,8444,12221,8445,12222,8446,12223,8447,12224,8448,8449,12225,8450,12226,8451,12227,8452,12228,8453,12229,8454,12230,8455,12231,8456,12232,8457,12233,8458,12234,8459,12235,8460,12236,8461,12237,8462,12238,8463,12239,8464,12240,8465,12241,8466,12242,8467,12243,8468,12244,8469,12245,8470,12246,8471,12247,8472,12248,8473,12249,8474,12250,8475,12251,8476,12252,8477,12253,8478,12254,8479,12255,8480,12256,8481,12257,8482,12258,8483,12259,8484,12260,8485,12261,8486,12262,8487,12263,8488,12264,8489,12265,8490,12266,8491,12267,8492,12268,8493,12269,8494,12270,8495,12271,8496,12272,8497,12273,8498,12274,8499,12275,8500,12276,12277,8501,12278,8502,8503,12279,8504,12280,8505,12281,8506,12282,8507,12283,8508,12284,8509,12285,8510,12286,8511,12287,8512,12288,8513,12289,8514,12290,8515,12291,8516,12292,8517,12293,8518,12294,8519,12295,8520,12296,8521,12297,8522,12298,8523,12299,8524,8525,12300,8526,12301,8527,12302,8528,12303,8529,12304,8530,12305,8531,12306,8532,12307,8533,12308,8534,12309,8535,12310,8536,12311,8537,12312,8538,12313,8539,12314,8540,12315,8541,12316,8542,12317,8543,12318,8544,12319,8545,12320,8546,12321,8547,12322,8548,12323,8549,12324,8550,12325,8551,12326,8552,12327,8553,12328,8554,12329,8555,12330,8556,12331,8557,12332,8558,12333,8559,12334,8560,12335,8561,12336,8562,12337,8563,12338,8564,12339,8565,12340,8566,12341,8567,12342,8568,12343,8569,12344,8570,12345,8571,12346,8572,12347,8573,12348,8574,12349,8575,12350,8576,12351,8577,12352,8578,12353,8579,12354,8580,12355,8581,12356,8582,12357,8583,12358,8584,12359,8585,8586,12360,8587,12361,8588,12362,8589,12363,8590,12364,8591,12365,8592,12366,8593,12367,8594,12368,8595,12369,8596,8597,12370,8598,12371,8599,12372,8600,12373,8601,12374,8602,12375,8603,12376,8604,12377,8605,12378,8606,12379,8607,8608,12380,8609,12381,8610,12382,8611,12383,8612,12384,8613,12385,8614,12386,8615,12387,8616,12388,8617,12389,8618,8619,12390,8620,12391,8621,12392,8622,12393,8623,12394,8624,12395,8625,12396,8626,12397,8627,12398,8628,12399,8629,12400,8630,12401,8631,12402,8632,12403,8633,12404,8634,12405,8635,12406,8636,12407,8637,12408,8638,12409,8639,12410,8640,8641,12411,8642,12412,8643,12413,8644,12414,8645,12415,8646,12416,8647,12417,8648,12418,8649,12419,8650,8651,12420,8652,12421,8653,12422,8654,12423,8655,12424,8656,12425,8657,12426,8658,12427,8659,12428,8660,12429,8661,8662,12430,8663,12431,8664,12432,8665,12433,8666,12434,8667,12435,8668,12436,8669,12437,8670,12438,8671,12439,8672,8673,12440,8674,12441,8675,12442,8676,12443,8677,12444,8678,12445,8679,12446,8680,12447,8681,12448,8682,12449,8683,12450,8684,12451,8685,12452,8686,12453,8687,12454,8688,12455,8689,12456,8690,12457,8691,12458,8692,12459,8693,12460,8694,12461,8695,12462,8696,12463,8697,12464,8698,12465,8699,12466,8700,12467,8701,12468,8702,12469,8703,12470,8704,12471,8705,12472,8706,12473,8707,12474,8708,12475,8709,12476,8710,12477,8711,12478,8712,12479,8713,8714,12480,8715,12481,8716,12482,8717,12483,8718,12484,8719,12485,8720,12486,8721,12487,8722,12488,8723,12489,8724,12490,8725,12491,8726,12492,8727,12493,8728,12494,8729,12495,8730,12496,8731,12497,8732,12498,8733,12499,8734,12500,8735,12501,8736,12502,8737,12503,8738,12504,8739,12505,8740,12506,12507,8741,12508,8742,12509,8743,12510,8744,12511,8745,12512,8746,12513,8747,12514,8748,12515,8749,12516,8750,12517,8751,12518,8752,12519,8753,12520,8754,12521,8755,12522,8756,12523,8757,12524,8758,12525,8759,12526,8760,12527,8761,12528,8762,12529,8763,12530,8764,12531,8765,12532,8766,12533,8767,12534,8768,12535,8769,12536,8770,12537,8771,12538,8772,12539,8773,8774,12540,8775,12541,8776,12542,8777,12543,8778,12544,8779,12545,8780,12546,8781,12547,8782,12548,8783,12549,8784,12550,8785,12551,8786,12552,8787,12553,8788,12554,8789,12555,8790,12556,8791,12557,8792,12558,8793,12559,8794,12560,8795,12561,8796,12562,8797,12563,8798,12564,8799,12565,8800,12566,8801,12567,8802,12568,8803,12569,8804,8805,12570,8806,12571,8807,12572,8808,12573,8809,8810,12574,8811,12575,8812,12576,8813,12577,8814,12578,8815,12579,8816,12580,8817,12581,8818,12582,8819,12583,8820,12584,8821,12585,8822,12586,8823,12587,8824,12588,8825,12589,8826,12590,8827,12591,8828,12592,8829,12593,8830,12594,8831,8832,12595,8833,12596,8834,12597,8835,12598,8836,12599,8837,12600,8838,12601,8839,12602,8840,12603,8841,12604,8842,12605,8843,12606,8844,12607,8845,12608,8846,12609,8847,12610,8848,12611,8849,12612,8850,12613,12614,12615,12616,12617,8851,8852,8853,8854,8855,8856,8857,8858,8859,8860,8861,8862,8863,8864,8865,8866,8867,12618,8868,8869,12619,8870,12620,8871,12621,8872,12622,8873,12623,8874,12624,8875,12625,8876,12626,8877,12627,8878,12628,8879,12629,8880,12630,8881,12631,8882,12632,8883,12633,8884,12634,8885,12635,8886,12636,8887,12637,8888,12638,8889,12639,8890,12640,8891,12641,8892,12642,8893,12643,8894,12644,8895,12645,8896,12646,8897,12647,8898,12648,8899,12649,8900,12650,8901,12651,8902,12652,8903,12653,8904,12654,8905,12655,8906,12656,8907,12657,8908,12658,8909,12659,8910,12660,8911,12661,8912,12662,8913,12663,8914,12664,8915,12665,8916,12666,8917,12667,8918,12668,8919,12669,8920,12670,8921,12671,8922,12672,8923,12673,8924,12674,8925,12675,8926,12676,8927,12677,8928,12678,8929,12679,8930,12680,8931,12681,8932,12682,8933,12683,8934,12684,8935,12685,8936,12686,8937,12687,8938,12688,8939,12689,8940,12690,8941,12691,8942,12692,8943,12693,8944,12694,8945,12695,8946,12696,8947,12697,8948,12698,8949,12699,8950,12700,8951,12701,8952,12702,8953,12703,8954,12704,8955,12705,8956,12706,8957,12707,8958,12708,8959,12709,8960,12710,8961,12711,8962,12712,8963,12713,8964,12714,8965,12715,8966,12716,8967,12717,8968,12718,8969,12719,8970,12720,8971,12721,8972,12722,8973,12723,8974,12724,8975,12725,8976,12726,8977,12727,8978,12728,8979,12729,8980,12730,8981,12731,8982,12732,8983,12733,8984,12734,8985,12735,8986,12736,8987,12737,8988,12738,8989,12739,8990,12740,8991,12741,8992,12742,8993,12743,8994,12744,8995,12745,8996,12746,8997,12747,8998,12748,8999,12749,12750,12751,12752,12753,12754,12755,12756,12757,12758,12759,12760,12761,12762,12763,12764,12765,12766,12767,12768,12769,12770,12771,12772,12773,12774,12775,12776,12777,12778,12779,12780,12781,12782,12783,12784,12785,12786,12787,12788,12789,12790,12791,12792,12793,12794,12795,12796,12797,12798,12799,12800,12801,12802,12803,12804,12805,12806,12807,12808,12809,12810,12811,12812,12813,12814,12815,12816,12817,12818,12819,12820,12821,12822,12823,12824,12825,12826,12827,12828,12829,12830,12831,12832,12833,12834,12835,12836,12837,12838,12839,12840,12841,12842,12843,12844,12845,12846,12847,12848,12849,12850,12851,12852,12853,12854,12855,12856,12857,12858,12859,12860,12861,12862,12863,12864,12865,12866,12867,12868,12869,12870,12871,12872,12873,12874,12875,12876,12877,12878,12879,12880,12881,12882,12883,12884,12885,12886,12887,12888,12889,12890,12891,12892,12893,12894,12895,12896,12897,12898,12899,12900,12901,12902,12903,12904,12905,12906,12907,12908,12909,12910,12911,12912,12913,12914,12915,12916,12917,12918,12919,12920,12921,12922,12923,12924,12925,12926,12927,12928,12929,12930,12931,12932,12933,12934,12935,12936,12937,12938,12939,12940,12941,12942,12943,12944,12945,12946,12947,12948,12949,12950,12951,12952,12953,12954,12955,12956,12957,12958,12959,12960,12961,12962,12963,12964,12965,12966,12967,12968,12969,12970,12971,12972,12973,12974,12975,12976,12977,12978,12979,12980,12981,12982,12983,12984,12985,12986,12987,12988,12989,12990,12991,12992,12993,12994,12995,12996,12997,12998,12999,13000,13001,13002,13003,13004,13005,13006,13007,13008,13009,13010,13011,13012,13013,13014,13015,13016,13017,13018,13019,13020,13021,13022,13023,13024,13025,13026,13027,13028,13029,13030,13031,13032,13033,13034,13035,13036,13037,13038,13039,13040,13041,13042,13043,13044,13045,13046,13047,13048,13049,13050,13051,13052,13053,13054,13055,13056,13057,13058,13059,13060,13061,13062,13063,13064,13065,13066,13067,13068,13069,13070,13071,13072,13073,13074,13075,13076,13077,13078,13079,13080,13081,13082,13083,13084,13085,13086,13087,13088,13089,13090,13091,13092,13093,13094,13095,13096,13097,13098,13099,13100,13101,13102,13103,13104,13105,13106,13107,13108,13109,13110,13111,13112,13113,13114,13115,13116,13117,13118,13119,13120,13121,13122,13123,13124,13125,13126,13127,13128,13129,13130,13131,13132,13133,13134,13135,13136,13137,13138,13139,13140,13141,13142,13143,13144,13145,13146,13147,13148,13149,13150,13151,13152,13153,13154,13155,13156,13157,13158,13159,13160,13161,13162,13163,13164,13165,13166,13167,13168,13169,13170,13171,13172,13173,13174,13175,13176,13177,13178,13179,13180,13181,13182,13183,13184,13185,13186,13187,13188,13189,13190,13191,13192,13193,13194,13195,13196,13197,13198,13199,13200,13201,13202,13203,13204,13205,13206,13207,13208,13209,13210,13211,13212,13213,13214,13215,13216,13217,13218,13219,13220,13221,13222,13223,13224,13225,13226,13227,13228,13229,13230,13231,13232,13233,13234,13235,13236,13237,13238,13239,13240,13241,13242,13243,13244,13245,13246,13247,13248,13249,13250,13251,13252,13253,13254,13255,13256,13257,13258,13259,13260,13261,13262,13263,13264,13265,13266,13267,13268,13269,13270,13271,13272,13273,13274,13275,13276,13277,13278,13279,13280,13281,13282,13283,13284,13285,13286,13287,13288,13289,13290,13291,13292,13293,13294,13295,13296,13297,13298,13299,13300,13301,13302,13303,13304,13305,13306,13307,13308,13309,13310,13311,13312,13313,13314,13315,13316,13317,13318,13319,13320,13321,13322,13323,13324,13325,13326,13327,13328,13329,13330,13331,13332,13333,13334,13335,13336,13337,13338,13339,13340,13341,13342,13343,13344,13345,13346,13347,13348,13349,13350,13351,13352,13353,13354,13355,13356,13357,13358,13359,13360,13361,13362,13363,13364,13365,13366,13367,13368,13369,13370,13371,13372,13373,13374,13375,13376,13377,13378,13379,13380,13381,13382,13383,13384,13385,13386,13387,13388,13389,13390,13391,13392,13393,13394,13395,13396,13397,13398,13399,13400,13401,13402,13403,13404,13405,13406,13407,13408,13409,13410,13411,13412,13413,13414,13415,13416,13417,13418,13419,13420,13421,13422,13423,13424,13425,13426,13427,13428,13429,13430,13431,13432,13433,13434,13435,13436,13437,13438,13439,13440,13441,13500,13501,13502,13503,13504,13505,13506,13507,13508,13509,13510,13511,13512,13513,13514,13515,13516,13517,13518,18000,13519,13520,18001,13521,13522,18002,13523,18003,13524,18004,13525,18005,13526,18006,13527,18007,13528,18008,13529,18009,13530,18010,13531,18011,13532,18012,13533,18013,13534,18014,13535,18015,13536,18016,18017,18018,18019,18020,13537,13538,13539,13540,13541,13542,13543,13544,13545,13546,13547,13548,13549,13550,13551,13552,13553,13554,18021,13555,13556,18022,13557,18023,13558,18024,13559,18025,18026,13560,18027,13561,18028,13562,18029,13563,18030,13564,18031,13565,18032,13566,18033,13567,18034,13568,18035,13569,18036,13570,18037,13571,18038,13572,18039,13573,18040,13574,18041,13575,18042,13576,18043,13577,18044,13578,18045,13579,18046,13580,18047,13581,18048,13582,18049,13583,18050,13584,18051,13585,18052,13586,18053,13587,18054,13588,18055,13589,18056,18057,13590,18058,13591,18059,13592,18060,13593,18061,13594,18062,13595,18063,13596,18064,13597,18065,13598,18066,13599,18067,13600,18068,13601,18069,13602,18070,13603,18071,13604,18072,13605,18073,13606,18074,13607,18075,13608,18076,13609,18077,18078,13610,18079,13611,18080,13612,18081,13613,18082,13614,18083,13615,18084,13616,18085,13617,18086,13618,18087,13619,18088,13620,18089,13621,18090,13622,18091,13623,18092,13624,18093,13625,18094,13626,18095,13627,18096,13628,18097,13629,18098,13630,18099,13631,18100,13632,18101,13633,18102,13634,18103,18104,13635,18105,13636,18106,13637,18107,13638,18108,13639,18109,13640,18110,13641,18111,13642,18112,13643,18113,13644,18114,13645,18115,13646,18116,13647,18117,13648,18118,13649,18119,18120,13650,18121,13651,18122,13652,18123,13653,18124,13654,18125,13655,18126,13656,18127,13657,18128,13658,18129,13659,18130,13660,18131,13661,18132,13662,18133,13663,18134,13664,18135,13665,18136,13666,18137,13667,18138,18139,13668,18140,13669,18141,13670,18142,13671,18143,13672,18144,13673,18145,13674,18146,13675,18147,13676,18148,13677,18149,13678,18150,13679,18151,13680,18152,13681,18153,13682,18154,13683,18155,13684,18156,13685,18157,13686,18158,13687,18159,13688,18160,13689,18161,13690,18162,13691,18163,13692,18164,13693,18165,13694,18166,13695,18167,13696,18168,18169,13697,18170,13698,18171,13699,18172,13700,18173,13701,18174,13702,18175,13703,18176,13704,18177,13705,18178,13706,18179,13707,13708,13709,18180,13710,18181,13711,18182,13712,18183,13713,18184,13714,18185,13715,18186,13716,18187,13717,18188,13718,18189,13719,18190,13720,18191,13721,18192,13722,18193,13723,18194,13724,18195,13725,18196,13726,18197,13727,18198,13728,18199,13729,18200,13730,18201,13731,18202,13732,18203,13733,18204,13734,18205,13735,18206,13736,18207,13737,18208,13738,18209,13739,18210,13740,18211,18212,13741,18213,13742,18214,13743,18215,13744,18216,13745,18217,13746,18218,13747,18219,13748,18220,13749,18221,13750,18222,13751,18223,13752,18224,13753,18225,13754,18226,13755,18227,13756,18228,13757,18229,13758,18230,13759,18231,13760,18232,13761,18233,13762,18234,13763,18235,13764,18236,18237,13765,18238,13766,18239,13767,18240,13768,18241,13769,18242,13770,18243,13771,18244,13772,18245,13773,18246,13774,18247,13775,18248,13776,18249,13777,18250,13778,18251,13779,18252,13780,18253,13781,18254,13782,18255,13783,18256,13784,18257,13785,18258,13786,18259,13787,18260,13788,18261,13789,18262,13790,18263,13791,18264,13792,18265,13793,18266,13794,18267,18268,13795,18269,13796,18270,13797,18271,13798,18272,13799,18273,13800,18274,13801,18275,13802,18276,13803,18277,13804,18278,13805,18279,13806,18280,13807,18281,13808,18282,13809,18283,18284,18285,18286,13810,18287,13811,18288,13812,18289,13813,18290,13814,18291,13815,18292,13816,18293,13817,18294,13818,18295,13819,18296,18297,13820,18298,13821,18299,13822,13823,18300,13824,18301,13825,18302,13826,18303,13827,18304,13828,18305,13829,18306,18307,13830,18308,13831,18309,13832,18310,13833,18311,13834,18312,13835,18313,13836,18314,13837,18315,13838,18316,13839,18317,13840,18318,13841,18319,13842,18320,13843,18321,13844,18322,13845,18323,13846,18324,13847,18325,13848,18326,13849,18327,18328,13850,18329,13851,13852,18330,13853,18331,13854,18332,13855,18333,13856,18334,13857,18335,13858,18336,13859,18337,18338,13860,18339,13861,18340,13862,18341,13863,18342,13864,18343,13865,18344,13866,18345,13867,18346,13868,18347,13869,18348,13870,18349,13871,18350,13872,18351,13873,18352,13874,18353,18354,13875,18355,13876,18356,13877,18357,13878,18358,13879,18359,13880,18360,13881,18361,13882,18362,13883,18363,13884,18364,13885,18365,13886,18366,13887,18367,13888,18368,13889,18369,13890,18370,13891,18371,13892,18372,13893,18373,13894,18374,13895,18375,18376,13896,18377,13897,18378,13898,18379,13899,18380,13900,18381,13901,18382,13902,18383,13903,18384,13904,18385,13905,18386,13906,18387,13907,18388,13908,18389,13909,18390,13910,18391,13911,18392,13912,18393,13913,18394,13914,18395,13915,18396,13916,18397,13917,18398,13918,18399,13919,18400,18401,13920,18402,13921,18403,13922,18404,13923,18405,13924,18406,13925,18407,13926,18408,13927,18409,13928,18410,13929,18411,13930,18412,13931,18413,13932,18414,13933,18415,13934,18416,13935,18417,13936,18418,13937,18419,13938,18420,13939,18421,13940,18422,13941,18423,13942,18424,13943,18425,13944,18426,13945,18427,13946,18428,13947,18429,13948,18430,13949,18431,18432,13950,18433,13951,18434,13952,18435,13953,18436,13954,18437,13955,18438,13956,18439,13957,18440,13958,18441,13959,18442,13960,18443,13961,18444,13962,18445,13963,18446,13964,18447,18448,13965,18449,13966,18450,13967,18451,13968,18452,13969,18453,13970,18454,13971,18455,13972,18456,13973,18457,13974,18458,13975,18459,13976,18460,13977,18461,13978,18462,13979,18463,13980,18464,13981,18465,13982,18466,13983,18467,13984,18468,13985,18469,13986,18470,13987,18471,13988,18472,13989,18473,13990,18474,13991,18475,13992,18476,13993,18477,13994,18478,13995,18479,13996,18480,13997,18481,13998,18482,13999,18483,14000,18484,14001,18485,14002,18486,14003,18487,14004,18488,18489,14005,14006,14007,14008,14009,14010,14011,14012,14013,14014,14015,14016,14017,14018,14019,14020,14021,14022,14023,14024,14025,14026,14027,14028,14029,14030,14031,14032,14033,14034,14035,14036,14037,14038,14039,14040,14041,14042,14043,14044,14045,14046,14047,14048,14049,14050,14051,14052,14053,14054,14055,14056,14057,14058,14059,14060,14061,14062,14063,14064,14065,14066,14067,14068,14069,14070,14071,14072,14073,14074,14075,14076,14077,14078,18490,14079,14080,18491,14081,18492,14082,18493,14083,18494,14084,18495,14085,18496,14086,18497,14087,18498,14088,18499,14089,18500,14090,18501,14091,18502,14092,18503,14093,18504,14094,18505,14095,18506,14096,18507,14097,18508,14098,18509,14099,18510,18511,14100,18512,14101,18513,14102,18514,14103,18515,14104,18516,14105,18517,14106,18518,14107,18519,14108,18520,14109,18521,14110,18522,14111,18523,14112,18524,14113,18525,14114,18526,14115,18527,14116,18528,14117,18529,14118,18530,14119,18531,14120,18532,14121,18533,14122,18534,14123,18535,14124,18536,18537,14125,18538,14126,18539,14127,18540,14128,18541,14129,18542,14130,18543,14131,18544,14132,18545,14133,18546,14134,18547,14135,18548,14136,18549,14137,18550,14138,18551,14139,18552,14140,18553,18554,14141,18555,14142,18556,14143,18557,14144,18558,14145,18559,14146,18560,14147,18561,14148,18562,14149,18563,14150,18564,14151,18565,14152,18566,14153,18567,14154,18568,14155,18569,14156,18570,14157,18571,14158,18572,14159,18573,18574,14160,18575,14161,18576,14162,18577,14163,18578,14164,18579,14165,18580,14166,18581,14167,18582,14168,18583,14169,18584,14170,18585,14171,18586,14172,18587,14173,18588,14174,18589,14175,18590,18591,14176,18592,14177,18593,14178,18594,14179,18595,14180,18596,14181,18597,14182,18598,14183,18599,14184,18600,14185,18601,14186,18602,14187,18603,14188,18604,14189,18605,14190,18606,14191,18607,14192,18608,14193,18609,14194,18610,14195,18611,14196,18612,14197,18613,14198,18614,14199,18615,18616,14200,18617,14201,18618,14202,18619,14203,18620,14204,18621,14205,18622,14206,18623,14207,18624,14208,18625,14209,18626,14210,18627,14211,18628,14212,18629,14213,18630,14214,18631,14215,18632,14216,18633,14217,18634,14218,18635,14219,18636,18637,14220,18638,14221,18639,14222,18640,14223,18641,14224,18642,14225,18643,14226,18644,14227,18645,14228,18646,14229,18647,14230,18648,14231,18649,14232,18650,14233,18651,14234,18652,14235,18653,14236,18654,14237,18655,14238,18656,14239,18657,18658,14240,18659,14241,18660,14242,18661,14243,18662,14244,18663,14245,18664,14246,18665,14247,18666,14248,18667,14249,18668,18669,18670,14250,18671,14251,18672,14252,18673,14253,18674,14254,18675,14255,18676,14256,18677,18678,14257,18679,14258,18680,14259,18681,14260,18682,14261,18683,14262,18684,14263,18685,14264,18686,18687,14265,18688,14266,18689,14267,18690,14268,18691,14269,18692,14270,18693,14271,18694,14272,18695,14273,18696,14274,18697,14275,18698,14276,18699,14277,18700,14278,18701,14279,18702,14280,18703,14281,18704,14282,18705,14283,18706,14284,18707,14285,18708,14286,18709,14287,18710,18711,14288,18712,14289,18713,14290,18714,14291,18715,14292,18716,14293,18717,14294,18718,14295,18719,14296,18720,14297,18721,14298,18722,14299,18723,14300,18724,14301,18725,14302,18726,14303,18727,14304,18728,14305,18729,14306,18730,14307,18731,14308,18732,14309,18733,18734,14310,18735,14311,18736,14312,18737,14313,18738,14314,18739,14315,18740,14316,18741,14317,18742,14318,18743,14319,18744,14320,18745,14321,18746,14322,18747,14323,18748,14324,18749,14325,18750,14326,18751,14327,18752,14328,18753,14329,18754,14330,18755,14331,18756,14332,18757,14333,18758,14334,18759,14335,18760,14336,18761,14337,18762,14338,18763,14339,18764,14340,18765,14341,18766,18767,18768,18769,14342,18770,14343,18771,14344,18772,14345,18773,14346,18774,14347,18775,14348,18776,14349,18777,14350,18778,14351,18779,14352,14353,18780,14354,18781,14355,18782,14356,18783,14357,18784,14358,18785,14359,18786,14360,18787,14361,18788,14362,18789,14363,18790,14364,18791,14365,18792,14366,18793,14367,18794,14368,18795,14369,18796,14370,18797,14371,18798,14372,18799,14373,18800,14374,18801,14375,18802,14376,18803,14377,18804,14378,18805,14379,18806,14380,18807,14381,18808,14382,18809,14383,18810,14384,18811,14385,18812,14386,18813,14387,18814,14388,18815,14389,18816,14390,18817,14391,18818,14392,18819,14393,18820,14394,18821,14395,18822,14396,18823,14397,18824,14398,18825,14399,18826,18827,14400,18828,14401,18829,14402,18830,14403,18831,14404,18832,14405,18833,14406,18834,14407,18835,14408,18836,14409,18837,14410,18838,14411,18839,14412,18840,14413,18841,14414,18842,14415,18843,14416,18844,14417,18845,14418,18846,14419,18847,14420,18848,14421,18849,14422,18850,14423,18851,14424,18852,14425,18853,14426,18854,14427,18855,14428,18856,14429,18857,14430,18858,14431,18859,14432,18860,14433,18861,14434,18862,14435,18863,14436,18864,14437,18865,14438,18866,14439,18867,14440,18868,14441,18869,14442,18870,14443,18871,14444,18872,14445,18873,14446,18874,14447,18875,14448,18876,14449,18877,14450,18878,14451,18879,14452,18880,14453,18881,14454,18882,14455,18883,14456,18884,14457,18885,14458,18886,14459,18887,14460,18888,14461,18889,14462,18890,14463,18891,14464,18892,14465,18893,14466,18894,14467,18895,14468,18896,14469,18897,14470,18898,14471,18899,14472,18900,14473,18901,14474,18902,14475,18903,14476,18904,14477,14478,18905,14479,18906,14480,18907,14481,18908,14482,18909,14483,18910,14484,18911,14485,18912,14486,18913,14487,18914,14488,18915,14489,18916,14490,18917,14491,18918,14492,18919,14493,18920,14494,18921,14495,18922,14496,18923,14497,18924,14498,18925,14499,18926,14500,18927,14501,18928,14502,18929,14503,18930,14504,18931,14505,18932,14506,18933,14507,18934,14508,18935,14509,18936,14510,18937,14511,18938,14512,18939,14513,18940,14514,18941,14515,18942,14516,18943,14517,18944,14518,18945,14519,18946,14520,18947,14521,18948,14522,18949,14523,18950,14524,18951,14525,18952,14526,18953,14527,18954,14528,18955,14529,18956,14530,18957,14531,18958,14532,18959,14533,18960,14534,18961,14535,18962,14536,18963,14537,18964,14538,18965,14539,18966,14540,18967,14541,18968,14542,18969,14543,18970,14544,18971,14545,18972,14546,18973,14547,18974,14548,18975,14549,18976,14550,18977,14551,18978,14552,18979,14553,18980,14554,18981,14555,18982,14556,18983,14557,18984,14558,18985,14559,18986,14560,18987,14561,18988,14562,18989,14563,18990,14564,18991,14565,18992,14566,18993,14567,18994,14568,18995,14569,18996,14570,18997,14571,18998,14572,18999,14573,19000,14574,19001,14575,19002,14576,19003,14577,19004,14578,19005,14579,19006,14580,19007,14581,19008,14582,19009,14583,19010,14584,19011,14585,19012,14586,19013,14587,19014,14588,19015,14589,19016,14590,19017,14591,19018,14592,19019,14593,19020,14594,19021,14595,19022,14596,19023,19024,14597,14598,19025,14599,19026,14600,19027,14601,19028,14602,19029,14603,19030,14604,19031,14605,19032,14606,19033,14607,19034,14608,19035,14609,19036,14610,19037,14611,19038,14612,19039,14613,19040,14614,19041,14615,19042,14616,19043,14617,19044,14618,19045,14619,19046,14620,19047,14621,19048,14622,19049,14623,19050,14624,19051,14625,19052,14626,19053,14627,19054,14628,19055,14629,19056,14630,19057,14631,19058,14632,19059,14633,19060,14634,19061,14635,19062,14636,19063,14637,19064,14638,19065,14639,19066,14640,19067,14641,19068,14642,19069,14643,19070,14644,19071,14645,19072,14646,19073,14647,19074,14648,19075,14649,19076,14650,19077,14651,19078,14652,19079,14653,19080,14654,19081,14655,19082,14656,19083,14657,19084,14658,19085,14659,19086,14660,14661,14662,14663,19087,14664,19088,14665,19089,14666,19090,14667,19091,14668,19092,14669,19093,14670,19094,14671,19095,14672,19096,14673,19097,14674,19098,19099,14675,19100,14676,19101,14677,19102,14678,19103,14679,19104,14680,19105,14681,19106,14682,19107,14683,19108,14684,19109,14685,19110,14686,19111,14687,19112,14688,19113,14689,19114,14690,14691,19115,14692,19116,19117,19118,19119,19120,19121,19122,19123,19124,19125,19126,19127,19128,19129,19130,19131,19132,19133,19134,19135,19136,19137,19138,19139,19140,19141,19142,19143,19144,19145,19146,19147,19148,19149,19150,19151,19152,19153,19154,19155,19156,19157,19158,19159,19160,19161,14693,19162,19163,19164,19165,19166,14694,19167,19168,14695,19169,14696,19170,19171,13442,14697,19172,14698,19173,14699,19174,19175,14700,13443,19176,14701,13444,19177,14702,19178,13445,14703,19179,13446,14704,19180,13447,14705,19181,13448,14706,19182,13449,14707,19183,13450,14708,19184,13451,14709,19185,13452,14710,19186,13453,14711,19187,13454,14712,19188,13455,14713,19189,13456,14714,19190,13457,14715,19191,13458,19192,14716,13459,19193,14717,13460,19194,14718,13461,14719,19195,13462,19196,14720,13463,19197,14721,13464,19198,13465,14722,19199,13466,14723,13467,19200,14724,13468,19201,13469,14725,19202,19203,14726,13470,19204,14727,13471,19205,14728,13472,19206,14729,13473,19207,13474,14730,19208,13475,14731,19209,13476,14732,19210,13477,14733,19211,13478,14734,19212,13479,14735,19213,13480,14736,19214,13481,14737,19215,13482,14738,19216,13483,14739,19217,13484,14740,19218,13485,14741,19219,13486,14742,19220,13487,14743,19221,13488,14744,19222,13489,19223,14745,13490,19224,14746,13491,19225,14747,13492,19226,13493,14748,19227,13494,14749,19228,13495,14750,19229,13496,14751,19230,13497,14752,19231,13498,14753,19232,13499,14754,19233,14755,19234,14756,19235,14757,19236,14758,19237,14759,19238,14760,19239,14761,19240,14762,19241,14763,19242,14764,19243,19244,14765,19245,14766,19246,14767,19247,14768,19248,14769,19249,14770,19250,14771,19251,14772,19252,14773,19253,14774,19254,14775,19255,14776,19256,19257,14777,19258,14778,19259,14779,19260,14780,19261,14781,19262,14782,19263,14783,19264,14784,19265,14785,19266,14786,19267,14787,19268,14788,19269,14789,19270,14790,19271,19272,14791,19273,14792,19274,14793,19275,14794,14795,14796,14797,14798,14799,14800,14801,14802,14803,14804,14805,14806,14807,14808,14809,14810,14811,14812,14813,14814,14815,14816,14817,14818,14819,14820,14821,14822,14823,14824,14825,14826,14827,14828,14829,14830,14831,14832,14833,14834,14835,19276,14836,14837,19277,14838,19278,14839,19279,14840,14841,19280,14842,19281,14843,19282,14844,19283,14845,19284,14846,19285,14847,19286,19287,19288,19289,19290,14848,19291,19292,19293,19294,14849,19295,14850,19296,19297,14851,19298,14852,19299,14853,19300,14854,19301,14855,19302,14856,19303,14857,19304,14858,19305,14859,19306,14860,19307,14861,19308,14862,19309,14863,14864,19310,14865,19311,14866,19312,14867,19313,14868,19314,14869,19315,14870,19316,14871,19317,14872,19318,14873,19319,14874,19320,14875,19321,14876,19322,14877,19323,14878,19324,14879,19325,14880,19326,14881,19327,14882,19328,14883,19329,14884,19330,14885,19331,14886,19332,14887,19333,14888,19334,14889,19335,14890,19336,14891,19337,14892,19338,14893,19339,14894,19340,14895,19341,14896,19342,14897,19343,14898,19344,14899,19345,14900,19346,14901,14902,19347,14903,19348,14904,19349,14905,19350,14906,19351,14907,19352,14908,19353,14909,19354,14910,19355,14911,19356,14912,19357,14913,19358,14914,19359,14915,19360,14916,19361,14917,19362,14918,19363,14919,19364,14920,19365,14921,19366,14922,19367,14923,19368,14924,19369,14925,19370,14926,19371,14927,19372,14928,19373,14929,19374,14930,19375,14931,19376,14932,19377,14933,19378,14934,19379,14935,19380,14936,19381,14937,19382,14938,19383,14939,19384,14940,19385,14941,19386,14942,19387,14943,19388,14944,19389,14945,19390,14946,19391,14947,19392,14948,19393,14949,19394,14950,19395,14951,19396,14952,19397,14953,19398,14954,19399,14955,19400,14956,19401,14957,19402,14958,19403,14959,19404,14960,19405,14961,19406,14962,19407,14963,19408,14964,19409,14965,19410,14966,19411,14967,19412,14968,19413,14969,19414,14970,19415,14971,19416,14972,19417,14973,19418,14974,19419,14975,19420,14976,19421,14977,19422,14978,19423,14979,19424,14980,19425,14981,19426,14982,19427,14983,19428,14984,19429,14985,19430,14986,19431,14987,19432,14988,19433,14989,19434,14990,14991,19435,14992,19436,14993,19437,14994,19438,14995,19439,14996,19440,14997,19441,14998,19442,14999,19443,19444,15000,19445,15001,19446,15002,19447,15003,19448,15004,19449,15005,19450,15006,19451,15007,19452,15008,15009,19453,15010,19454,15011,19455,15012,19456,15013,19457,15014,19458,15015,19459,19460,19461,19462,19463,19464,15016,15017,15018,15019,15020,15021,15022,15023,15024,15025,15026,15027,15028,15029,15030,19465,15031,15032,15033,15034,15035,19466,15036,19467,15037,19468,15038,19469,15039,19470,15040,19471,15041,19472,15042,19473,15043,19474,15044,19475,15045,15046,15047,15048,19476,15049,19477,15050,19478,15051,19479,15052,19480,15053,19481,15054,19482,15055,19483,15056,19484,15057,19485,15058,19486,15059,19487,15060,19488,15061,19489,15062,19490,15063,19491,15064,19492,15065,19493,15066,19494,15067,19495,15068,19496,15069,19497,15070,19498,15071,19499,15072,19500,15073,19501,15074,19502,15075,19503,15076,19504,15077,19505,15078,19506,15079,19507,15080,19508,15081,19509,15082,19510,15083,19511,15084,19512,15085,19513,15086,19514,15087,19515,15088,19516,15089,19517,19518,15090,19519,15091,19520,15092,19521,15093,19522,15094,19523,15095,19524,15096,19525,15097,19526,15098,19527,15099,19528,15100,19529,15101,15102,19530,15103,19531,15104,19532,15105,19533,15106,19534,15107,19535,15108,19536,15109,19537,15110,19538,15111,19539,15112,19540,15113,19541,15114,19542,15115,19543,15116,19544,15117,19545,15118,19546,15119,19547,15120,19548,15121,19549,15122,19550,15123,19551,15124,19552,19553,15125,19554,15126,19555,15127,19556,15128,19557,15129,19558,15130,19559,15131,19560,15132,19561,15133,19562,15134,19563,15135,19564,15136,19565,15137,19566,15138,19567,15139,19568,15140,19569,15141,19570,15142,19571,15143,19572,15144,19573,15145,19574,15146,19575,15147,19576,15148,19577,15149,19578,15150,19579,15151,19580,15152,19581,15153,19582,15154,19583,15155,19584,15156,19585,15157,19586,15158,19587,15159,19588,15160,19589,15161,15162,19590,15163,19591,15164,19592,15165,19593,15166,19594,15167,19595,15168,19596,15169,19597,15170,19598,15171,19599,15172,19600,15173,19601,15174,19602,15175,19603,15176,19604,15177,19605,15178,19606,15179,19607,15180,19608,15181,19609,15182,19610,15183,19611,15184,19612,15185,19613,15186,19614,15187,19615,15188,19616,15189,19617,15190,19618,15191,19619,15192,19620,15193,19621,15194,19622,15195,19623,15196,19624,15197,19625,15198,19626,15199,19627,15200,19628,15201,19629,15202,19630,15203,19631,15204,19632,15205,19633,15206,19634,15207,19635,15208,19636,15209,19637,15210,19638,15211,19639,15212,19640,15213,19641,15214,19642,15215,19643,15216,19644,15217,19645,15218,19646,15219,19647,15220,19648,15221,19649,15222,19650,15223,19651,15224,19652,15225,19653,15226,19654,15227,19655,15228,19656,15229,19657,15230,19658,15231,19659,15232,19660,15233,19661,15234,19662,15235,19663,15236,19664,15237,19665,15238,19666,15239,19667,15240,19668,15241,19669,15242,19670,15243,19671,15244,19672,15245,19673,19674,19675,15246,19676,15247,19677,15248,19678,15249,19679,15250,19680,15251,19681,15252,19682,15253,19683,15254,19684,15255,19685,15256,19686,15257,19687,15258,19688,15259,19689,15260,19690,15261,19691,15262,19692,15263,19693,15264,19694,15265,19695,15266,19696,15267,19697,15268,19698,15269,19699,19700,15270,19701,15271,19702,15272,19703,15273,19704,15274,19705,15275,19706,15276,19707,15277,19708,15278,19709,15279,19710,15280,19711,15281,19712,15282,19713,15283,19714,15284,19715,15285,19716,15286,19717,15287,19718,15288,19719,15289,19720,15290,19721,15291,19722,15292,19723,15293,19724,15294,19725,19726,15295,19727,15296,19728,15297,19729,15298,19730,15299,19731,15300,19732,15301,19733,15302,19734,15303,19735,15304,19736,19737,15305,19738,15306,19739,15307,19740,15308,19741,15309,19742,15310,19743,15311,19744,15312,19745,15313,19746,15314,19747,15315,19748,15316,19749,15317,19750,15318,19751,15319,19752,15320,19753,15321,19754,15322,19755,15323,19756,15324,19757,15325,19758,15326,19759,15327,19760,15328,19761,15329,19762,19763,15330,19764,15331,19765,15332,19766,15333,19767,15334,19768,15335,19769,15336,19770,15337,19771,15338,19772,15339,19773,15340,19774,15341,19775,15342,19776,15343,19777,15344,19778,15345,19779,15346,19780,15347,19781,15348,19782,15349,19783,15350,19784,15351,19785,15352,19786,15353,19787,15354,19788,15355,19789,15356,19790,15357,19791,15358,19792,15359,19793,19794,15360,19795,15361,19796,15362,19797,15363,19798,15364,19799,15365,19800,15366,19801,15367,19802,15368,19803,15369,19804,15370,19805,15371,19806,15372,19807,15373,19808,15374,19809,15375,19810,15376,19811,15377,19812,15378,19813,15379,19814,15380,19815,15381,19816,15382,19817,15383,19818,15384,19819,19820,15385,19821,15386,19822,15387,19823,15388,19824,15389,19825,15390,19826,15391,19827,15392,19828,15393,19829,15394,19830,15395,19831,15396,19832,15397,19833,15398,19834,15399,19835,15400,19836,15401,19837,15402,19838,15403,19839,15404,19840,15405,19841,15406,19842,15407,19843,15408,19844,15409,19845,15410,19846,15411,19847,15412,19848,15413,19849,15414,19850,15415,19851,15416,19852,15417,19853,15418,19854,15419,19855,19856,15420,19857,15421,19858,15422,19859,15423,19860,15424,19861,15425,19862,15426,19863,15427,19864,15428,19865,15429,19866,15430,19867,15431,19868,15432,19869,15433,19870,15434,19871,15435,19872,15436,19873,15437,19874,15438,19875,15439,19876,19877,15440,19878,15441,19879,15442,19880,15443,19881,15444,19882,15445,19883,15446,19884,15447,19885,15448,19886,15449,19887,15450,19888,19889,15451,15452,19890,15453,19891,15454,19892,15455,19893,15456,19894,15457,19895,15458,19896,15459,19897,15460,19898,15461,19899,15462,19900,15463,19901,15464,19902,15465,19903,15466,19904,15467,19905,15468,19906,15469,19907,15470,19908,15471,19909,15472,19910,15473,19911,15474,19912,19913,15475,19914,15476,19915,15477,19916,15478,19917,15479,19918,15480,19919,15481,19920,15482,19921,15483,19922,15484,19923,15485,19924,15486,19925,15487,19926,15488,19927,15489,19928,19929,15490,19930,15491,19931,15492,19932,15493,19933,15494,19934,15495,19935,15496,19936,15497,19937,15498,19938,15499,19939,15500,19940,15501,19941,15502,19942,15503,19943,15504,19944,15505,19945,15506,19946,15507,19947,15508,19948,15509,19949,15510,19950,15511,19951,15512,19952,15513,19953,15514,19954,15515,19955,15516,19956,19957,15517,19958,15518,19959,15519,19960,15520,19961,15521,19962,15522,19963,15523,19964,15524,19965,15525,19966,15526,19967,15527,19968,15528,19969,15529,19970,15530,19971,15531,19972,15532,19973,15533,19974,15534,19975,19976,15535,19977,15536,19978,15537,19979,15538,19980,15539,19981,15540,19982,15541,19983,15542,15543,15544,15545,19984,15546,19985,15547,19986,15548,19987,15549,19988,19989,15550,19990,15551,19991,15552,19992,15553,19993,15554,19994,15555,19995,15556,19996,15557,19997,15558,15559,15560,15561,19998,15562,19999,15563,15564,20000,15565,20001,15566,20002,15567,20003,15568,20004,15569,20005,20006,15570,20007,15571,20008,15572,20009,15573,20010,15574,20011,15575,15576,20012,15577,20013,15578,20014,15579,20015,15580,20016,15581,20017,15582,20018,15583,20019,15584,20020,15585,20021,15586,20022,15587,20023,15588,20024,15589,15590,15591,20025,15592,20026,15593,20027,15594,20028,15595,20029,15596,20030,15597,20031,15598,20032,15599,20033,15600,20034,15601,20035,15602,20036,15603,20037,15604,20038,15605,15606,15607,20039,15608,20040,15609,20041,15610,20042,15611,20043,15612,20044,15613,20045,15614,20046,15615,20047,15616,20048,15617,20049,15618,20050,15619,20051,15620,20052,15621,15622,15623,20053,15624,20054,15625,20055,15626,20056,15627,20057,15628,20058,15629,20059,15630,20060,15631,20061,15632,20062,15633,20063,15634,20064,15635,20065,15636,20066,15637,15638,15639,20067,15640,20068,15641,20069,15642,20070,15643,20071,15644,20072,15645,20073,15646,20074,15647,20075,15648,20076,15649,20077,15650,20078,15651,20079,15652,20080,15653,15654,15655,20081,15656,20082,15657,20083,15658,20084,15659,20085,15660,20086,15661,20087,15662,20088,15663,20089,15664,20090,15665,20091,15666,20092,15667,20093,15668,20094,15669,20095,15670,20096,15671,20097,15672,20098,15673,20099,15674,15675,20100,15676,20101,15677,20102,15678,20103,15679,20104,15680,20105,15681,20106,15682,20107,15683,15684,15685,20108,15686,20109,15687,20110,15688,20111,15689,20112,15690,20113,15691,20114,15692,20115,15693,20116,15694,20117,15695,20118,15696,20119,15697,20120,15698,20121,15699,15700,15701,20122,15702,20123,15703,20124,15704,20125,15705,20126,15706,20127,15707,20128,15708,20129,15709,20130,15710,20131,15711,20132,15712,20133,15713,20134,15714,20135,15715,15716,15717,20136,15718,20137,15719,20138,15720,20139,15721,20140,15722,20141,15723,20142,15724,20143,20144,15725,20145,15726,20146,15727,20147,15728,20148,15729,20149,15730,15731,15732,20150,15733,20151,15734,20152,15735,20153,15736,20154,15737,20155,15738,20156,15739,20157,15740,20158,15741,20159,15742,20160,15743,20161,15744,20162,15745,20163,15746,15747,15748,15749,20164,20165,15750,20166,15751,20167,15752,20168,15753,20169,15754,20170,15755,20171,15756,20172,15757,20173,15758,20174,15759,20175,15760,20176,15761,20177,15762,20178,15763,20179,15764,20180,15765,20181,15766,20182,15767,20183,15768,15769,20184,15770,20185,15771,20186,15772,20187,15773,20188,15774,20189,15775,15776,20190,15777,15778,15779,20191,15780,20192,15781,20193,15782,20194,15783,20195,15784,20196,15785,20197,15786,20198,15787,20199,15788,20200,15789,20201,15790,20202,15791,20203,15792,20204,15793,15794,15795,20205,15796,20206,15797,20207,15798,20208,15799,20209,15800,20210,15801,20211,15802,20212,15803,20213,15804,20214,15805,20215,15806,20216,15807,20217,15808,20218,15809,15810,15811,20219,15812,20220,15813,20221,15814,20222,15815,20223,15816,20224,15817,20225,15818,20226,15819,20227,15820,20228,15821,20229,15822,20230,15823,20231,15824,20232,15825,15826,15827,20233,15828,20234,15829,20235,15830,20236,15831,20237,15832,20238,15833,20239,15834,20240,15835,20241,15836,20242,15837,20243,15838,20244,15839,20245,15840,20246,15841,15842,20247,15843,20248,15844,20249,15845,20250,15846,20251,15847,20252,15848,20253,15849,20254,15850,20255,15851,20256,15852,20257,15853,20258,15854,20259,15855,20260,15856,15857,20261,15858,20262,15859,20263,15860,20264,15861,20265,15862,20266,15863,20267,15864,20268,15865,20269,15866,20270,20271,20272,20273,15867,15868,15869,15870,15871,15872,15873,15874,20274,15875,15876,15877,15878,15879,15880,20275,15881,15882,20276,15883,20277,15884,20278,15885,20279,15886,20280,15887,20281,15888,15889,20282,20283,20284,15890,20285,15891,20286,15892,20287,15893,15894,15895,20288,15896,20289,15897,20290,15898,20291,15899,20292,15900,20293,15901,20294,15902,20295,15903,20296,15904,20297,15905,20298,15906,20299,15907,20300,15908,20301,15909,15910,15911,20302,15912,20303,15913,20304,15914,20305,15915,20306,15916,20307,15917,20308,15918,20309,15919,20310,15920,20311,15921,20312,15922,20313,15923,20314,15924,20315,15925,15926,15927,20316,15928,20317,15929,20318,15930,20319,15931,20320,15932,20321,15933,20322,15934,20323,15935,20324,15936,20325,15937,20326,15938,20327,15939,20328,15940,20329,15941,15942,20330,15943,20331,15944,20332,15945,20333,15946,20334,15947,20335,15948,20336,15949,20337,15950,20338,15951,20339,15952,15953,20340,15954,20341,15955,20342,15956,20343,15957,15958,15959,20344,15960,20345,15961,20346,15962,20347,15963,20348,15964,20349,15965,20350,15966,20351,15967,20352,15968,20353,15969,20354,15970,20355,15971,20356,15972,20357,15973,15974,15975,20358,15976,20359,15977,20360,15978,20361,15979,20362,15980,20363,15981,20364,15982,20365,15983,20366,15984,20367,15985,20368,15986,20369,15987,20370,15988,15989,20371,15990,20372,15991,20373,15992,20374,15993,20375,15994,20376,15995,20377,15996,20378,15997,20379,15998,20380,15999,20381,16000,20382,16001,20383,16002,20384,16003,16004,20385,16005,20386,16006,20387,16007,20388,16008,20389,16009,20390,16010,20391,16011,20392,16012,20393,16013,20394,16014,20395,16015,16016,20396,16017,20397,16018,20398,16019,16020,20399,16021,20400,16022,20401,16023,20402,16024,20403,16025,20404,16026,20405,16027,20406,16028,20407,16029,20408,16030,20409,16031,20410,16032,20411,16033,20412,16034,16035,16036,20413,16037,20414,16038,20415,16039,20416,16040,20417,16041,20418,16042,20419,16043,20420,16044,20421,16045,20422,16046,20423,16047,20424,16048,20425,16049,20426,16050,16051,20427,16052,20428,16053,20429,16054,20430,16055,20431,16056,20432,16057,20433,16058,20434,16059,20435,16060,16061,20436,16062,20437,16063,20438,16064,20439,16065,20440,16066,16067,16068,20441,16069,20442,16070,20443,16071,20444,16072,20445,16073,20446,16074,20447,16075,20448,16076,20449,16077,20450,16078,20451,16079,20452,16080,20453,16081,16082,20454,16083,20455,16084,20456,16085,20457,16086,20458,16087,20459,16088,16089,20460,16090,20461,16091,20462,16092,20463,16093,20464,16094,20465,16095,20466,16096,20467,16097,16098,20468,16099,20469,16100,20470,16101,20471,16102,20472,16103,20473,16104,20474,16105,20475,16106,20476,16107,20477,16108,20478,16109,20479,16110,20480,16111,20481,16112,16113,20482,16114,20483,16115,20484,16116,20485,16117,20486,16118,20487,16119,20488,16120,20489,16121,20490,16122,20491,16123,20492,16124,20493,16125,20494,16126,20495,16127,16128,20496,16129,20497,16130,20498,16131,20499,16132,20500,16133,20501,16134,20502,16135,20503,16136,20504,16137,16138,20505,16139,20506,20507,16140,20508,16141,20509,16142,16143,16144,20510,16145,20511,16146,20512,16147,20513,16148,20514,16149,20515,16150,20516,16151,20517,16152,20518,16153,20519,16154,20520,16155,20521,16156,20522,16157,20523,16158,16159,20524,16160,20525,16161,20526,16162,20527,16163,20528,16164,20529,16165,20530,16166,20531,16167,20532,16168,20533,16169,20534,16170,20535,16171,20536,16172,16173,20537,16174,20538,16175,20539,16176,20540,16177,20541,16178,20542,16179,20543,16180,20544,16181,20545,16182,20546,16183,20547,16184,20548,16185,20549,16186,16187,20550,16188,16189,20551,16190,20552,16191,20553,16192,20554,16193,20555,16194,20556,16195,20557,16196,20558,16197,20559,16198,20560,16199,20561,16200,20562,16201,20563,16202,20564,16203,16204,20565,16205,20566,16206,20567,16207,20568,16208,20569,16209,20570,16210,20571,16211,20572,16212,20573,16213,20574,16214,20575,16215,20576,16216,20577,16217,20578,16218,16219,20579,16220,20580,16221,20581,16222,20582,16223,20583,16224,20584,16225,20585,16226,20586,16227,20587,16228,20588,16229,20589,16230,20590,16231,20591,16232,20592,16233,16234,20593,16235,20594,16236,20595,16237,20596,16238,20597,16239,20598,16240,20599,16241,20600,16242,20601,16243,20602,16244,20603,16245,20604,16246,20605,16247,20606,16248,16249,20607,16250,20608,16251,20609,16252,16253,20610,16254,20611,16255,20612,16256,20613,16257,20614,16258,20615,16259,20616,16260,20617,16261,20618,16262,20619,16263,16264,20620,16265,20621,16266,20622,16267,20623,16268,20624,16269,20625,16270,20626,16271,20627,16272,20628,16273,20629,16274,20630,16275,20631,16276,20632,16277,20633,16278,16279,20634,16280,20635,16281,20636,16282,20637,16283,20638,16284,20639,16285,16286,20640,16287,20641,16288,20642,16289,20643,16290,20644,16291,20645,16292,20646,16293,20647,16294,16295,20648,16296,20649,16297,20650,16298,20651,16299,20652,16300,20653,16301,20654,16302,20655,16303,20656,16304,20657,16305,20658,16306,20659,16307,20660,16308,20661,16309,16310,20662,16311,20663,16312,20664,16313,16314,20665,16315,20666,16316,20667,16317,20668,16318,20669,16319,20670,16320,20671,16321,20672,16322,20673,16323,20674,16324,20675,16325,20676,16326,20677,16327,20678,16328,20679,16329,20680,16330,20681,16331,20682,16332,20683,16333,20684,16334,20685,16335,20686,16336,20687,16337,20688,16338,20689,16339,16340,16341,16342,20690,16343,20691,16344,20692,16345,20693,16346,20694,16347,16348,20695,16349,20696,20697,16350,20698,16351,20699,16352,16353,20700,16354,20701,16355,20702,16356,16357,20703,16358,20704,16359,20705,16360,20706,16361,20707,16362,20708,16363,20709,16364,20710,16365,20711,16366,20712,16367,20713,16368,20714,16369,20715,16370,20716,16371,16372,20717,16373,20718,16374,20719,16375,20720,16376,20721,16377,20722,16378,20723,16379,20724,16380,20725,16381,20726,16382,20727,16383,20728,16384,20729,16385,20730,16386,16387,20731,16388,20732,16389,20733,16390,20734,16391,20735,16392,20736,16393,20737,16394,20738,16395,20739,16396,20740,16397,20741,16398,20742,16399,20743,16400,20744,16401,16402,16403,20745,16404,20746,16405,20747,16406,20748,16407,20749,16408,20750,16409,20751,16410,20752,16411,20753,16412,20754,16413,20755,16414,20756,16415,20757,16416,20758,16417,16418,20759,16419,20760,16420,20761,16421,20762,16422,20763,16423,20764,16424,20765,16425,20766,16426,20767,16427,20768,16428,20769,16429,20770,16430,20771,16431,20772,16432,16433,16434,20773,16435,20774,16436,20775,16437,20776,16438,20777,16439,20778,20779,16440,16441,20780,16442,20781,16443,20782,16444,20783,16445,20784,16446,20785,16447,20786,16448,16449,20787,16450,20788,16451,20789,16452,20790,16453,20791,16454,20792,16455,20793,16456,20794,16457,20795,16458,20796,16459,20797,16460,20798,16461,20799,16462,16463,16464,20800,16465,20801,16466,20802,16467,20803,16468,20804,16469,20805,16470,20806,16471,20807,16472,20808,16473,20809,16474,20810,16475,20811,16476,20812,16477,20813,16478,16479,20814,16480,20815,16481,20816,16482,20817,16483,20818,16484,20819,16485,16486,20820,16487,20821,16488,20822,16489,20823,16490,20824,16491,20825,16492,20826,16493,20827,16494,16495,20828,16496,20829,16497,20830,16498,20831,16499,20832,20833,16500,20834,16501,20835,16502,20836,16503,20837,16504,20838,16505,20839,16506,20840,16507,20841,16508,16509,20842,16510,20843,16511,20844,16512,16513,20845,16514,20846,16515,20847,16516,20848,16517,20849,16518,20850,16519,20851,16520,20852,16521,20853,16522,20854,16523,20855,16524,16525,16526,16527,20856,16528,20857,16529,20858,16530,20859,16531,20860,16532,20861,16533,20862,16534,20863,20864,16535,20865,16536,20866,16537,20867,16538,20868,16539,20869,16540,16541,16542,16543,20870,16544,20871,16545,20872,16546,20873,16547,20874,16548,20875,16549,20876,16550,20877,16551,20878,16552,20879,16553,20880,16554,20881,16555,20882,16556,16557,20883,16558,20884,16559,20885,16560,20886,16561,20887,16562,20888,16563,20889,16564,20890,16565,20891,16566,20892,16567,20893,16568,20894,16569,20895,16570,20896,16571,16572,20897,16573,20898,16574,20899,16575,20900,16576,20901,16577,20902,16578,20903,16579,20904,16580,20905,16581,20906,16582,20907,16583,20908,16584,20909,16585,20910,16586,16587,20911,16588,20912,16589,20913,16590,20914,16591,20915,16592,20916,16593,20917,16594,20918,16595,20919,16596,16597,20920,16598,20921,16599,20922,16600,20923,16601,20924,16602,16603,20925,16604,20926,16605,20927,16606,20928,16607,20929,16608,20930,16609,20931,16610,20932,16611,20933,16612,20934,16613,20935,16614,20936,16615,20937,16616,20938,16617,16618,20939,16619,20940,16620,20941,16621,20942,16622,20943,16623,20944,16624,20945,16625,20946,16626,20947,16627,20948,16628,20949,16629,20950,16630,20951,16631,16632,20952,16633,16634,20953,16635,20954,16636,20955,16637,20956,16638,20957,16639,20958,16640,20959,16641,20960,16642,20961,16643,20962,16644,20963,16645,20964,16646,20965,16647,16648,20966,16649,20967,16650,20968,16651,20969,16652,20970,16653,20971,16654,20972,16655,20973,16656,20974,16657,20975,16658,20976,16659,20977,16660,20978,16661,20979,16662,16663,20980,16664,20981,16665,20982,16666,20983,16667,20984,16668,20985,16669,20986,16670,20987,16671,20988,16672,20989,16673,20990,16674,20991,16675,20992,16676,20993,16677,16678,20994,16679,20995,16680,20996,16681,20997,16682,20998,16683,20999,16684,21000,16685,16686,21001,16687,21002,16688,21003,16689,21004,16690,21005,16691,21006,16692,21007,16693,16694,21008,16695,21009,16696,21010,16697,21011,16698,21012,16699,21013,16700,21014,16701,16702,21015,16703,21016,16704,21017,16705,21018,16706,21019,16707,21020,16708,21021,16709,21022,16710,21023,16711,21024,16712,21025,16713,21026,16714,21027,16715,21028,16716,21029,16717,16718,21030,16719,21031,16720,21032,16721,21033,16722,21034,16723,21035,16724,16725,21036,16726,21037,16727,21038,16728,21039,16729,21040,16730,21041,16731,21042,16732,21043,16733,21044,21045,21046,21047,21048,21049,21050,21051,21052,21053,21054,21055,21056,21057,16734,21058,16735,21059,16736,21060,16737,21061,16738,21062,16739,16740,16741,21063,16742,21064,16743,16744,21065,16745,21066,16746,21067,16747,21068,16748,21069,16749,21070,16750,21071,16751,21072,16752,21073,16753,21074,16754,16755,16756,16757,21075,16758,21076,16759,16760,21077,16761,21078,16762,21079,16763,21080,16764,21081,16765,21082,16766,21083,16767,21084,16768,21085,16769,21086,16770,21087,16771,21088,16772,21089,16773,21090,16774,16775,21091,16776,21092,16777,21093,16778,21094,16779,21095,16780,21096,16781,21097,16782,21098,16783,21099,16784,21100,16785,21101,16786,21102,16787,21103,16788,16789,21104,16790,16791,21105,16792,21106,16793,21107,16794,21108,16795,21109,16796,21110,16797,21111,16798,21112,16799,21113,21114,16800,21115,16801,21116,16802,21117,16803,21118,16804,16805,21119,16806,21120,16807,21121,16808,21122,16809,21123,16810,21124,16811,21125,16812,21126,16813,21127,16814,21128,16815,21129,16816,21130,16817,21131,16818,16819,21132,16820,21133,16821,21134,16822,21135,16823,21136,16824,21137,16825,21138,16826,21139,16827,21140,16828,21141,16829,21142,16830,21143,16831,21144,16832,21145,16833,16834,21146,16835,21147,16836,21148,16837,21149,16838,16839,21150,16840,21151,16841,21152,16842,21153,16843,21154,16844,21155,16845,21156,16846,21157,16847,21158,16848,21159,16849,16850,21160,16851,21161,16852,21162,16853,21163,16854,21164,16855,21165,16856,21166,16857,21167,21168,21169,21170,21171,21172,21173,21174,21175,21176,21177,21178,21179,21180,21181,21182,21183,21184,21185,21186,21187,21188,21189,21190,21191,21192,21193,21194,21195,21196,21197,21198,21199,21200,21201,21202,21203,21204,21205,21206,21207,21208,21209,21210,21211,21212,21213,21214,21215,21216,21217,21218,21219,21220,21221,21222,21223,21224,21225,21226,21227,21228,21229,21230,21231,21232,21233,21234,21235,21236,21237,21238,21239,21240,21241,21242,21243,21244,21245,21246,21247,21248,21249,21250,16858,21251,21252,16859,21253,16860,21254,16861,21255,16862,21256,16863,16864,21257,16865,21258,16866,21259,16867,21260,16868,21261,16869,21262,16870,21263,16871,21264,16872,21265,16873,21266,16874,21267,21268,16875,21269,16876,21270,16877,16878,16879,21271,16880,21272,21273,16881,21274,16882,21275,16883,21276,16884,21277,16885,21278,16886,21279,16887,21280,16888,21281,16889,21282,16890,21283,16891,21284,16892,16893,21285,16894,21286,16895,21287,16896,21288,16897,21289,16898,21290,16899,21291,16900,21292,16901,21293,16902,21294,16903,21295,16904,21296,16905,21297,16906,21298,16907,16908,16909,21299,16910,21300,16911,21301,16912,21302,16913,21303,16914,21304,16915,21305,16916,21306,16917,21307,16918,16919,21308,16920,21309,16921,21310,16922,21311,16923,16924,21312,16925,21313,16926,21314,16927,21315,16928,21316,16929,21317,16930,21318,16931,21319,16932,21320,16933,21321,16934,21322,16935,21323,16936,21324,16937,21325,16938,16939,21326,16940,21327,16941,21328,16942,21329,16943,21330,16944,21331,16945,21332,16946,21333,16947,21334,16948,21335,16949,21336,16950,21337,16951,21338,16952,21339,16953,16954,21340,16955,21341,16956,21342,16957,21343,16958,21344,16959,21345,16960,21346,16961,21347,16962,21348,16963,21349,16964,21350,16965,21351,16966,21352,16967,21353,16968,16969,21354,16970,21355,16971,16972,21356,16973,21357,16974,21358,16975,21359,16976,21360,16977,21361,16978,21362,16979,21363,16980,21364,16981,21365,16982,21366,16983,21367,16984,16985,21368,16986,21369,16987,21370,16988,21371,16989,21372,16990,21373,16991,21374,16992,21375,16993,21376,16994,21377,16995,21378,16996,21379,16997,21380,16998,21381,16999,17000,21382,17001,21383,17002,21384,17003,21385,17004,21386,17005,21387,17006,21388,17007,21389,17008,21390,17009,21391,17010,21392,17011,21393,17012,21394,17013,17014,21395,17015,21396,17016,21397,17017,21398,17018,21399,17019,21400,17020,21401,17021,21402,17022,21403,17023,21404,17024,21405,17025,21406,17026,21407,17027,21408,17028,17029,21409,17030,21410,17031,21411,17032,21412,17033,21413,17034,21414,17035,17036,21415,17037,21416,17038,21417,17039,21418,21419,17040,21420,17041,21421,17042,21422,17043,17044,21423,17045,21424,17046,17047,21425,17048,21426,17049,21427,17050,21428,17051,21429,17052,21430,17053,21431,17054,21432,17055,21433,17056,21434,17057,21435,17058,21436,17059,17060,21437,17061,21438,17062,21439,17063,21440,17064,21441,17065,21442,17066,21443,17067,21444,17068,21445,17069,21446,17070,21447,17071,21448,17072,21449,17073,17074,21450,17075,17076,21451,17077,21452,17078,21453,17079,21454,17080,21455,17081,21456,17082,21457,17083,21458,17084,21459,17085,21460,17086,21461,17087,21462,17088,21463,17089,21464,17090,17091,21465,17092,21466,17093,21467,17094,21468,17095,21469,17096,21470,17097,21471,17098,21472,17099,21473,17100,21474,17101,21475,17102,21476,17103,21477,17104,17105,21478,17106,21479,17107,21480,17108,21481,17109,21482,17110,21483,17111,21484,17112,21485,17113,21486,17114,21487,17115,21488,17116,21489,17117,17118,21490,17119,21491,17120,17121,21492,17122,21493,17123,21494,17124,21495,17125,21496,17126,21497,17127,21498,17128,21499,17129,21500,17130,21501,17131,21502,17132,21503,17133,21504,17134,21505,17135,17136,21506,17137,21507,17138,21508,17139,21509,17140,21510,17141,21511,17142,21512,17143,21513,17144,21514,21515,21516,17145,21517,17146,21518,17147,21519,17148,17149,21520,17150,21521,17151,21522,17152,21523,17153,21524,17154,21525,17155,21526,17156,21527,17157,21528,17158,21529,17159,21530,17160,21531,17161,21532,17162,21533,17163,17164,17165,17166,21534,17167,21535,17168,21536,17169,21537,17170,21538,17171,21539,17172,21540,17173,21541,17174,21542,17175,21543,17176,21544,17177,17178,21545,17179,21546,17180,21547,17181,17182,17183,17184,21548,17185,21549,17186,21550,17187,21551,17188,21552,17189,21553,21554,17190,21555,17191,21556,17192,21557,17193,21558,17194,21559,17195,21560,17196,17197,17198,17199,21561,17200,21562,17201,21563,17202,21564,17203,21565,17204,21566,17205,21567,17206,21568,17207,21569,17208,21570,17209,21571,17210,21572,17211,21573,17212,21574,17213,17214,21575,17215,17216,21576,17217,21577,17218,21578,17219,21579,17220,21580,17221,21581,17222,21582,17223,21583,17224,21584,17225,21585,17226,21586,17227,21587,17228,21588,17229,21589,17230,21590,17231,21591,17232,21592,17233,21593,17234,21594,17235,17236,21595,17237,21596,17238,21597,17239,21598,21599,17240,17241,21600,17242,21601,17243,21602,17244,17245,21603,17246,21604,17247,21605,17248,21606,17249,21607,17250,21608,17251,21609,17252,21610,17253,21611,17254,21612,17255,21613,17256,21614,17257,21615,17258,21616,17259,17260,17261,17262,21617,17263,21618,17264,21619,17265,21620,17266,21621,17267,21622,17268,21623,17269,21624,17270,21625,17271,21626,17272,21627,17273,21628,17274,21629,17275,21630,17276,17277,17278,17279,21631,17280,21632,17281,21633,17282,21634,17283,21635,17284,21636,17285,21637,17286,21638,17287,21639,17288,21640,17289,21641,17290,21642,17291,21643,17292,17293,17294,17295,21644,17296,21645,17297,21646,17298,21647,17299,21648,17300,21649,17301,21650,17302,21651,17303,21652,17304,21653,17305,21654,17306,21655,17307,21656,17308,21657,17309,17310,17311,21658,17312,17313,21659,17314,21660,17315,21661,17316,21662,17317,21663,17318,21664,17319,21665,17320,21666,17321,21667,17322,21668,17323,21669,17324,21670,17325,21671,17326,17327,21672,17328,21673,17329,21674,17330,21675,17331,21676,17332,21677,17333,21678,17334,21679,17335,21680,17336,21681,17337,21682,17338,21683,17339,21684,17340,21685,17341,17342,21686,17343,17344,21687,17345,21688,17346,21689,17347,21690,17348,21691,17349,21692,17350,21693,17351,21694,17352,21695,17353,17354,21696,21697,17355,21698,17356,21699,17357,17358,17359,21700,17360,21701,17361,21702,17362,21703,17363,21704,17364,21705,17365,21706,17366,21707,17367,21708,17368,21709,17369,21710,17370,21711,17371,21712,17372,21713,17373,17374,21714,17375,21715,17376,21716,17377,21717,17378,21718,17379,21719,17380,21720,17381,21721,17382,21722,17383,21723,17384,21724,17385,21725,17386,17387,21726,17388,17389,21727,17390,21728,17391,21729,17392,21730,17393,21731,17394,21732,17395,21733,17396,21734,17397,17398,21735,17399,21736,21737,17400,21738,17401,21739,17402,21740,17403,17404,21741,17405,21742,17406,21743,17407,21744,17408,21745,17409,21746,17410,21747,17411,21748,17412,21749,17413,17414,21750,17415,21751,17416,21752,17417,21753,17418,21754,17419,17420,21755,17421,21756,17422,21757,17423,21758,17424,21759,17425,21760,17426,21761,17427,21762,17428,21763,17429,21764,17430,21765,17431,21766,17432,21767,17433,21768,17434,17435,21769,17436,21770,17437,21771,17438,21772,17439,21773,17440,21774,17441,17442,21775,17443,21776,17444,21777,17445,21778,17446,21779,17447,21780,17448,21781,17449,21782,17450,17451,17452,17453,21783,17454,21784,17455,21785,17456,21786,17457,21787,17458,21788,17459,21789,17460,21790,17461,21791,17462,21792,17463,21793,17464,21794,17465,21795,17466,21796,17467,21797,17468,21798,17469,21799,17470,17471,21800,17472,21801,17473,21802,17474,21803,17475,21804,17476,21805,17477,21806,17478,21807,17479,21808,17480,21809,17481,21810,17482,17483,21811,17484,21812,17485,21813,17486,21814,17487,17488,21815,17489,21816,17490,21817,17491,21818,17492,21819,17493,21820,17494,21821,17495,21822,17496,21823,17497,17498,17499,21824,17500,21825,17501,21826,17502,21827,17503,21828,17504,21829,17505,21830,17506,21831,17507,21832,17508,21833,17509,21834,17510,21835,17511,21836,17512,21837,17513,17514,17515,17516,21838,17517,21839,17518,17519,21840,21841,17520,21842,17521,21843,17522,21844,21845,21846,21847,17523,21848,17524,21849,17525,21850,17526,21851,17527,17528,17529,21852,17530,21853,17531,21854,17532,21855,17533,21856,17534,21857,17535,21858,17536,21859,17537,21860,17538,21861,17539,21862,17540,21863,17541,21864,17542,21865,17543,17544,21866,17545,21867,17546,21868,17547,21869,17548,17549,21870,21871,17550,21872,17551,21873,17552,21874,17553,21875,17554,21876,17555,21877,17556,21878,17557,21879,17558,17559,17560,17561,21880,17562,21881,17563,21882,17564,21883,17565,21884,17566,21885,17567,21886,17568,21887,17569,21888,17570,21889,17571,21890,17572,21891,17573,21892,17574,21893,17575,17576,21894,17577,21895,17578,21896,17579,21897,17580,21898,17581,21899,17582,21900,17583,21901,17584,21902,17585,21903,21904,17586,21905,17587,21906,17588,17589,21907,17590,21908,17591,21909,17592,21910,17593,21911,17594,21912,17595,21913,17596,21914,17597,21915,17598,21916,17599,21917,17600,21918,17601,21919,17602,21920,17603,17604,21921,17605,21922,17606,21923,17607,21924,17608,21925,17609,21926,17610,21927,17611,21928,17612,21929,17613,21930,17614,21931,17615,21932,17616,21933,17617,21934,17618,17619,21935,17620,21936,17621,21937,17622,21938,17623,21939,17624,21940,17625,21941,17626,21942,17627,21943,17628,21944,17629,21945,17630,21946,17631,21947,17632,21948,17633,17634,21949,17635,21950,17636,21951,17637,21952,17638,21953,17639,21954,17640,21955,17641,21956,17642,21957,17643,21958,17644,21959,17645,21960,17646,21961,17647,21962,17648,17649,21963,17650,21964,17651,21965,17652,21966,17653,21967,17654,21968,17655,21969,17656,21970,17657,21971,17658,21972,17659,21973,21974,17660,21975,17661,21976,17662,17663,21977,17664,21978,17665,21979,17666,21980,17667,21981,17668,21982,17669,21983,17670,21984,17671,21985,17672,21986,17673,21987,17674,21988,17675,21989,17676,17677,21990,17678,21991,17679,21992,17680,21993,17681,21994,17682,21995,17683,21996,17684,21997,17685,21998,17686,21999,17687,22000,17688,22001,17689,22002,17690,22003,17691,17692,22004,17693,22005,17694,22006,17695,22007,17696,22008,17697,22009,17698,22010,17699,22011,17700,22012,17701,22013,17702,22014,17703,22015,17704,22016,17705,22017,17706,17707,22018,17708,22019,17709,22020,17710,22021,17711,22022,17712,22023,17713,22024,17714,22025,17715,22026,17716,22027,17717,22028,17718,22029,17719,22030,17720,22031,17721,17722,22032,17723,22033,17724,22034,17725,22035,17726,22036,17727,22037,17728,22038,17729,22039,17730,22040,17731,22041,17732,22042,17733,22043,17734,22044,17735,22045,17736,17737,22046,17738,22047,17739,22048,17740,22049,17741,22050,17742,22051,17743,22052,17744,22053,17745,22054,17746,22055,17747,22056,17748,22057,17749,22058,22059,22060,22061,17750,22062,17751,22063,17752,22064,22065,17753,22066,17754,22067,17755,22068,17756,22069,17757,22070,17758,22071,17759,22072,17760,17761,22073,17762,22074,17763,22075,17764,22076,17765,22077,17766,22078,22079,17767,22080,17768,22081,17769,22082,22083,17770,22084,17771,22085,17772,22086,17773,17774,22087,17775,17776,22088,17777,22089,17778,22090,17779,22091,17780,22092,22093,22094,22095,17781,22096,17782,22097,17783,22098,17784,22099,17785,22100,17786,17787,22101,17788,22102,17789,22103,17790,22104,17791,22105,17792,22106,17793,22107,17794,22108,22109,17795,22110,17796,22111,17797,22112,17798,22113,17799,22114,17800,17801,17802,17803,22115,17804,22116,17805,22117,17806,22118,17807,22119,17808,22120,22121,17809,22122,22123,17810,22124,17811,17812,22125,17813,22126,17814,22127,17815,22128,17816,17817,22129,17818,22130,17819,22131,17820,22132,17821,22133,22134,17822,22135,17823,22136,17824,22137,17825,22138,17826,22139,17827,22140,17828,22141,17829,22142,17830,17831,22143,17832,22144,17833,17834,22145,17835,22146,22147,22148,22149,17836,22150,17837,22151,17838,22152,17839,22153,17840,22154,17841,22155,17842,17843,22156,17844,22157,17845,22158,17846,22159,17847,22160,17848,22161,17849,22162,22163,22164,17850,22165,17851,22166,17852,22167,17853,22168,17854,22169,17855,17856,22170,17857,22171,17858,22172,17859,22173,17860,22174,17861,17862,22175,17863,22176,22177,17864,22178,22179,17865,22180,17866,22181,17867,22182,17868,22183,17869,17870,22184,17871,17872,22185,17873,22186,17874,22187,17875,22188,17876,22189,17877,22190,22191,22192,17878,22193,17879,22194,17880,22195,17881,22196,17882,22197,17883,17884,17885,22198,17886,22199,17887,17888,22200,17889,22201,17890,22202,17891,22203,22204,17892,22205,17893,22206,17894,22207,17895,22208,17896,22209,17897,22210,17898,22211,17899,17900,22212,17901,22213,17902,22214,17903,22215,17904,22216,22217,17905,22218,17906,22219,17907,22220,17908,22221,17909,22222,17910,22223,17911,22224,17912,22225,17913,17914,22226,17915,22227,17916,22228,17917,22229,17918,22230,22231,17919,22232,17920,22233,17921,22234,17922,22235,17923,22236,17924,22237,17925,22238,17926,22239,17927,22240,17928,22241,17929,22242,17930,22243,17931,22244,17932,22245,22246,17933,22247,17934,22248,17935,22249,17936,17937,17938,17939,17940,22250,17941,22251,17942,22252,17943,22253,17944,22254,17945,22255,17946,22256,22257,17947,22258,17948,22259,17949,22260,17950,22261,17951,22262,17952,22263,17953,17954,22264,17955,22265,17956,22266,17957,22267,17958,22268,17959,22269,17960,22270,22271,17961,22272,17962,22273,17963,22274,17964,22275,17965,22276,17966,22277,17967,17968,17969,22278,17970,22279,17971,22280,17972,22281,17973,22282,17974,22283,22284,17975,22285,17976,22286,17977,22287,17978,22288,17979,22289,17980,22290,17981,22291,17982,17983,17984,22292,17985,22293,17986,22294,17987,22295,22296,17988,22297,17989,22298,17990,22299,17991,22300,17992,22301,17993,22302,17994,22303,17995,22304,17996,22305,17997,17998,22306,17999,22307,22308,22309,22310,22311,22312,22313,22314,22315,22316,22317,22318,22319,22320,22321,22322,22323,22324,22325,22326,22327,22328,22329,22330,22331,22332,22333,22334,22335,22336,22337,22338,22339,22340,22341,22342,22343,22344,22345,22346,22347,22348,22349,22350,22351,22352,22353,22354,22355,22356,22357,22358,22359,22360,22361,22362,22363,22364,22365,22366,22367,22368,22369,22370,22371,22372,22373,22374,22375,22376,22377,22378,22379,22380,22381,22382,22383,22384,22385,22386,22387,22388,22389,22390,22391,22392,22393,22394,22395,22396,22397,22398,22399,22400,22401,22402,22403,22404,22405,22406,22407,22408,22409,22410,22411,22412,22413,22414,22415,22416,22417,22418,22419,22420,22421,22422,22423,22424,22425,22426,22427,22428,22429,22430,22431,22432,22433,22434,22435,22436,22437,22438,22439,22440,22441,22442,22443,22444,22445,22446,22447,22448,22449,22450,22451,22452,22453,22454,22455,22456,22457,22458,22459,22460,22461,22462,22463,22464,22465,22466,22467,22468,22469,22470,22471,22472,22473,22474,22475,22476,22477,22478,22479,22480,22481,22482,22483,22484,22485,22486,22487,22488,22489,22490,22491,22492,22493,22494,22495,22496,22497,22498,22499] \ No newline at end of file diff --git a/backend/src/META-INF/MANIFEST.MF b/backend/src/META-INF/MANIFEST.MF new file mode 100644 index 00000000..1e0e5190 --- /dev/null +++ b/backend/src/META-INF/MANIFEST.MF @@ -0,0 +1,3 @@ +Manifest-Version: 1.0 +Main-Class: com.fribbels.Main + diff --git a/backend/src/com/fribbels/Main.java b/backend/src/com/fribbels/Main.java new file mode 100644 index 00000000..27588190 --- /dev/null +++ b/backend/src/com/fribbels/Main.java @@ -0,0 +1,48 @@ +package com.fribbels; + +import com.fribbels.db.BaseStatsDb; +import com.fribbels.handler.OcrRequestHandler; +import com.fribbels.handler.OptimizationRequestHandler; +import com.fribbels.db.HeroDb; +import com.fribbels.db.ItemDb; +import com.fribbels.db.OptimizationDb; +import com.fribbels.handler.SystemRequestHandler; +import com.fribbels.handler.HeroesRequestHandler; +import com.fribbels.handler.ItemsRequestHandler; +import com.sun.net.httpserver.HttpServer; + +import java.io.IOException; +import java.net.InetSocketAddress; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; + +public class Main { + + private static HttpServer server; + private static ExecutorService executorService; + private static final HeroDb heroDb = new HeroDb(); + private static final ItemDb itemDb = new ItemDb(heroDb); + private static final BaseStatsDb baseStatsDb = new BaseStatsDb(); + private static final OptimizationDb optimizationDb = new OptimizationDb(); + + public static boolean interrupt = false; + + public static void main(String[] args) throws IOException { + executorService = Executors.newFixedThreadPool(10); + start(); + } + + public static void start() throws IOException { + server = HttpServer.create(new InetSocketAddress("localhost", 8001), 0); + + server.createContext("/system", new SystemRequestHandler()); + server.createContext("/items", new ItemsRequestHandler(itemDb)); + server.createContext("/optimization", new OptimizationRequestHandler(optimizationDb)); + server.createContext("/heroes", new HeroesRequestHandler(heroDb, baseStatsDb, itemDb)); + server.createContext("/ocr", new OcrRequestHandler()); + + System.out.println("START"); + server.setExecutor(executorService); + server.start(); + } +} diff --git a/backend/src/com/fribbels/core/FileIO.java b/backend/src/com/fribbels/core/FileIO.java new file mode 100644 index 00000000..904c17d8 --- /dev/null +++ b/backend/src/com/fribbels/core/FileIO.java @@ -0,0 +1,80 @@ +package com.fribbels.core; + +import com.fribbels.model.HeroStats; +import com.google.common.base.Charsets; +import com.google.common.io.Files; +import com.google.gson.Gson; +import com.google.gson.stream.JsonWriter; + +import java.io.ByteArrayOutputStream; +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.OutputStreamWriter; +import java.nio.charset.StandardCharsets; +import java.util.List; + +public class FileIO { + + private static final Gson gson = new Gson(); + + public String readFile(final String filename) throws IOException { + final File requestFile = new File(filename); + final String requestString = Files.toString(requestFile, Charsets.UTF_8); + + return requestString; + } + + public void writeFile(final String data) throws IOException { + final File responseFile = new File("response.txt"); + Files.write(data, responseFile, Charsets.UTF_8); + } + + public void writeJsonToFile(final List heroStats) throws IOException { + final FileOutputStream fileOutputStream = new FileOutputStream("response.txt"); + // final JsonWriter jsonWriter = new JsonWriter(new FileWriter("response.txt")); + // jsonWriter. + + JsonWriter writer = new JsonWriter(new OutputStreamWriter(fileOutputStream, "UTF-8")); + writer.beginArray(); + for (int i = 0; i < heroStats.size(); i++) { + if (i > 1000) break; + final HeroStats stat = heroStats.get(i); + gson.toJson(stat, HeroStats.class, writer); + } + writer.endArray(); + writer.close(); + } + + public void writeMiniOptimizationResponsesToFile(final long[] resultInts, final long size) throws IOException { + final FileOutputStream fileOutputStream = new FileOutputStream("response.txt"); + // final JsonWriter jsonWriter = new JsonWriter(new FileWriter("response.txt")); + // jsonWriter. + + JsonWriter writer = new JsonWriter(new OutputStreamWriter(fileOutputStream, StandardCharsets.UTF_8)); + writer.beginArray(); + for (int i = 0; i < size; i++) { +// if (resultInts[i] != 0) { + writer.value(resultInts[i]); +// } + } + writer.endArray(); + writer.close(); + fileOutputStream.close(); + } + + public String writeString(final long[] itemIds, final long size) throws IOException { + final ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); + + JsonWriter writer = new JsonWriter(new OutputStreamWriter(byteArrayOutputStream, StandardCharsets.UTF_8)); + writer.beginArray(); + for (int i = 0; i < size * 6; i++) { + writer.value(itemIds[i]); + } + writer.endArray(); + writer.close(); + byteArrayOutputStream.close(); + + return byteArrayOutputStream.toString(); + } +} diff --git a/backend/src/com/fribbels/core/Sorter.java b/backend/src/com/fribbels/core/Sorter.java new file mode 100644 index 00000000..ec61cb7b --- /dev/null +++ b/backend/src/com/fribbels/core/Sorter.java @@ -0,0 +1,134 @@ +package com.fribbels.core; + +import com.fribbels.enums.OptimizationColumn; +import com.fribbels.enums.SortOrder; +import com.fribbels.model.HeroStats; + +import java.util.Arrays; +import java.util.Comparator; + +public class Sorter { + + public static void sortHeroes(final HeroStats[] data, final OptimizationColumn column, final SortOrder order) { + System.out.println("SORTING HEROES BY " + column + " " + order); + switch (order) { + case ASC: + switch (column) { + case ATK: + Arrays.sort(data, Comparator.comparingInt(HeroStats::getAtk)); + break; + case HP: + Arrays.sort(data, Comparator.comparingInt(HeroStats::getHp)); + break; + case DEF: + Arrays.sort(data, Comparator.comparingInt(HeroStats::getDef)); + break; + case SPD: + Arrays.sort(data, Comparator.comparingInt(HeroStats::getSpd)); + break; + case CR: + Arrays.sort(data, Comparator.comparingInt(HeroStats::getCr)); + break; + case CD: + Arrays.sort(data, Comparator.comparingInt(HeroStats::getCd)); + break; + case EFF: + Arrays.sort(data, Comparator.comparingInt(HeroStats::getEff)); + break; + case RES: + Arrays.sort(data, Comparator.comparingInt(HeroStats::getRes)); + break; + case DAC: + Arrays.sort(data, Comparator.comparingInt(HeroStats::getDac)); + break; + case CP: + Arrays.sort(data, Comparator.comparingInt(HeroStats::getCp)); + break; + case HPPS: + Arrays.sort(data, Comparator.comparingInt(HeroStats::getHpps)); + break; + case EHP: + Arrays.sort(data, Comparator.comparingInt(HeroStats::getEhp)); + break; + case EHPPS: + Arrays.sort(data, Comparator.comparingInt(HeroStats::getEhpps)); + break; + case DMG: + Arrays.sort(data, Comparator.comparingInt(HeroStats::getDmg)); + break; + case DMGPS: + Arrays.sort(data, Comparator.comparingInt(HeroStats::getDmgps)); + break; + case MCDMG: + Arrays.sort(data, Comparator.comparingInt(HeroStats::getMcdmg)); + break; + case MCDMGPS: + Arrays.sort(data, Comparator.comparingInt(HeroStats::getMcdmgps)); + break; + default: + System.err.println("INVALID COLUMN " + column); + } + break; + + case DESC: + switch (column) { + case ATK: + Arrays.sort(data, Comparator.comparingInt(HeroStats::getAtk).reversed()); + break; + case HP: + Arrays.sort(data, Comparator.comparingInt(HeroStats::getHp).reversed()); + break; + case DEF: + Arrays.sort(data, Comparator.comparingInt(HeroStats::getDef).reversed()); + break; + case SPD: + Arrays.sort(data, Comparator.comparingInt(HeroStats::getSpd).reversed()); + break; + case CR: + Arrays.sort(data, Comparator.comparingInt(HeroStats::getCr).reversed()); + break; + case CD: + Arrays.sort(data, Comparator.comparingInt(HeroStats::getCd).reversed()); + break; + case EFF: + Arrays.sort(data, Comparator.comparingInt(HeroStats::getEff).reversed()); + break; + case RES: + Arrays.sort(data, Comparator.comparingInt(HeroStats::getRes).reversed()); + break; + case DAC: + Arrays.sort(data, Comparator.comparingInt(HeroStats::getDac).reversed()); + break; + case CP: + Arrays.sort(data, Comparator.comparingInt(HeroStats::getCp).reversed()); + break; + case HPPS: + Arrays.sort(data, Comparator.comparingInt(HeroStats::getHpps).reversed()); + break; + case EHP: + Arrays.sort(data, Comparator.comparingInt(HeroStats::getEhp).reversed()); + break; + case EHPPS: + Arrays.sort(data, Comparator.comparingInt(HeroStats::getEhpps).reversed()); + break; + case DMG: + Arrays.sort(data, Comparator.comparingInt(HeroStats::getDmg).reversed()); + break; + case DMGPS: + Arrays.sort(data, Comparator.comparingInt(HeroStats::getDmgps).reversed()); + break; + case MCDMG: + Arrays.sort(data, Comparator.comparingInt(HeroStats::getMcdmg).reversed()); + break; + case MCDMGPS: + Arrays.sort(data, Comparator.comparingInt(HeroStats::getMcdmgps).reversed()); + break; + default: + System.err.println("INVALID COLUMN " + column); + } + break; + default: + System.err.println("INVALID ORDER " + order); + } + } +} diff --git a/backend/src/com/fribbels/core/StatCalculator.java b/backend/src/com/fribbels/core/StatCalculator.java new file mode 100644 index 00000000..9f8783f8 --- /dev/null +++ b/backend/src/com/fribbels/core/StatCalculator.java @@ -0,0 +1,99 @@ +package com.fribbels.core; + +import com.fribbels.enums.StatType; +import com.fribbels.model.AugmentedStats; +import com.fribbels.model.Hero; +import com.fribbels.model.HeroStats; +import com.fribbels.model.Item; + +import java.util.Map; + +public class StatCalculator { + + public static HeroStats addAccumulatorArrsToHero(final HeroStats base, final float[][] accs, final int[] sets, final Hero hero) { + int atk = (int) (base.getAtk() + mapAccumulatorArrsToFloat(0, accs) + (sets[2] > 1 ? sets[2] / 4 * 0.35f * base.getAtk() : 0)) + hero.getBonusAtk(); + int hp = (int) (base.getHp() + mapAccumulatorArrsToFloat(1, accs) + (sets[0] > 1 ? sets[0] / 2 * 0.15f * base.getHp() : 0)) + hero.getBonusHp(); + int def = (int) (base.getDef() + mapAccumulatorArrsToFloat(2, accs) + (sets[1] > 1 ? sets[1] / 2 * 0.15f * base.getDef() : 0)) + hero.getBonusDef(); + int spd = (int) (base.getSpd() + mapAccumulatorArrsToFloat(10, accs) + (sets[3] > 1 ? sets[3] / 4 * 0.25f * base.getSpd() : 0) + (sets[14] > 1 ? sets[14] / 4 * 0.1f * base.getSpd() : 0)) + hero.getBonusSpeed(); + int cr = (int) (base.getCr() + mapAccumulatorArrsToFloat(6, accs) + (sets[4] > 1 ? sets[4] / 2 * 12 : 0)) + hero.getBonusCr(); + int cd = (int) (base.getCd() + mapAccumulatorArrsToFloat(7, accs) + (sets[6] > 1 ? sets[6] / 4 * 40 : 0)) + hero.getBonusCd(); + int eff = (int) (base.getEff() + mapAccumulatorArrsToFloat(8, accs) + (sets[5] > 1 ? sets[5] / 2 * 20 : 0)) + hero.getBonusEff(); + int res = (int) (base.getRes() + mapAccumulatorArrsToFloat(9, accs) + (sets[9] > 1 ? sets[9] / 2 * 20 : 0)) + hero.getBonusRes(); + int dac = base.getDac() + sets[10] / 2 * 4; + int cp = (int) (((atk * 1.6f + atk * 1.6f * cr/100f * cd/100f) * (1.0 + (spd - 45f) * 0.02f) + hp + def * 9.3f) * (1f + (res/100f + eff/100f) / 4f)); + + float critRate = (float)Math.min(cr, 100) / 100; + + int ehp = (int) (hp * ((float)def/300 + 1)); + int hpps = (int) ((float)hp*spd/100); + int ehpps = (int) ((float)ehp*spd/100); + int dmg = (int) ((critRate * atk * cd/100) + (1-critRate) * atk); + int dmgps = (int) ((float)dmg*spd/100); + int mcdmg = (int) ((float)atk * cd/100); + int mcdmgps = (int) ((float)mcdmg*spd/100); + + return new HeroStats(atk, hp, def, cr, cd, eff, res, dac, spd, cp, ehp, hpps, ehpps, dmg, dmgps, mcdmg, mcdmgps, sets, null, null, null, null); + } + + public static float mapAccumulatorArrsToFloat(final int index, final float[][] accs) { + return accs[0][index] + + accs[1][index] + + accs[2][index] + + accs[3][index] + + accs[4][index] + + accs[5][index]; + } + + public static float[] getStatAccumulatorArr(final HeroStats base, final Item item, final Map accumulatorsByItem) { + if (accumulatorsByItem.containsKey(item)) { + return accumulatorsByItem.get(item); + } + + final float[] accumulator = buildStatAccumulatorArr(base, item); + accumulatorsByItem.put(item, accumulator); + return accumulator; + } + + public static float[] buildStatAccumulatorArr(final HeroStats base, final Item item) { + final AugmentedStats stats = item.getAugmentedStats(); + final float[] statAccumulatorArr = new float[12]; + + // Add base + statAccumulatorArr[0] += stats.getAttack() + stats.getAttackPercent()/100f * base.getAtk(); + statAccumulatorArr[1] += stats.getHealth() + stats.getHealthPercent()/100f * base.getHp(); + statAccumulatorArr[2] += stats.getDefense() + stats.getDefensePercent()/100f * base.getDef(); + + statAccumulatorArr[10] += stats.getSpeed(); + statAccumulatorArr[6] += stats.getCritRate(); + statAccumulatorArr[7] += stats.getCritDamage(); + statAccumulatorArr[8] += stats.getEffectiveness(); + statAccumulatorArr[9] += stats.getEffectResistance(); + + final StatType mainType = stats.getMainType(); + final int mainTypeIndex = stats.getMainType().getIndex(); + + // Add percents + if (mainTypeIndex == 3) { + statAccumulatorArr[0] += stats.getMainValue()/100f * base.getAtk(); + } else if (mainType == StatType.HEALTHPERCENT) { + statAccumulatorArr[1] += stats.getMainValue()/100f * base.getHp(); + } else if (mainType == StatType.DEFENSEPERCENT) { + statAccumulatorArr[2] += stats.getMainValue()/100f * base.getDef(); + } else { + statAccumulatorArr[mainTypeIndex] += stats.getMainValue(); + } + + return statAccumulatorArr; + } + + public static int[] buildSetsArr(final Item[] items) { + final int[] sets = new int[16]; + sets[items[0].getSet().getIndex()]++; + sets[items[1].getSet().getIndex()]++; + sets[items[2].getSet().getIndex()]++; + sets[items[3].getSet().getIndex()]++; + sets[items[4].getSet().getIndex()]++; + sets[items[5].getSet().getIndex()]++; + return sets; + } +} diff --git a/backend/src/com/fribbels/db/BaseStatsDb.java b/backend/src/com/fribbels/db/BaseStatsDb.java new file mode 100644 index 00000000..898759c2 --- /dev/null +++ b/backend/src/com/fribbels/db/BaseStatsDb.java @@ -0,0 +1,47 @@ +package com.fribbels.db; + +import com.fribbels.model.HeroStats; + +import java.util.HashMap; +import java.util.Map; + +public class BaseStatsDb { + + private Map baseStatsByName; + + public BaseStatsDb() { + baseStatsByName = new HashMap<>(); + } + + public HeroStats getBaseStatsByName(final String name) { + if (!baseStatsByName.containsKey(name)) { + return null; + } + + final HeroStats baseStats = baseStatsByName.get(name); + return HeroStats.builder() + .atk(baseStats.getAtk()) + .hp(baseStats.getHp()) + .def(baseStats.getDef()) + .cr(baseStats.getCr()) + .cd(baseStats.getCd()) + .eff(baseStats.getEff()) + .res(baseStats.getRes()) + .dac(baseStats.getDac()) + .spd(baseStats.getSpd()) + .cp(baseStats.getCp()) + .ehp(baseStats.getEhp()) + .hpps(baseStats.getHpps()) + .ehpps(baseStats.getEhpps()) + .dmg(baseStats.getDmg()) + .dmgps(baseStats.getDmgps()) + .mcdmg(baseStats.getMcdmg()) + .mcdmgps(baseStats.getMcdmgps()) + .build(); + } + + public void setBaseStatsByName(final Map baseStatsByName) { + this.baseStatsByName = baseStatsByName; + } +} + diff --git a/backend/src/com/fribbels/db/HeroDb.java b/backend/src/com/fribbels/db/HeroDb.java new file mode 100644 index 00000000..908226e5 --- /dev/null +++ b/backend/src/com/fribbels/db/HeroDb.java @@ -0,0 +1,45 @@ +package com.fribbels.db; + +import com.fribbels.model.Hero; +import org.apache.commons.collections.CollectionUtils; +import org.apache.commons.lang3.StringUtils; + +import java.util.ArrayList; +import java.util.List; + +public class HeroDb { + + private List heroes; + + public HeroDb() { + heroes = new ArrayList<>(); + } + + public void addHeroes(final List newHero) { + heroes.addAll(newHero); + } + + public List getAllHeroes() { + return heroes; + } + + public void setHeroes(final List newHeroes) { + if (CollectionUtils.isEmpty(newHeroes)) { + heroes = new ArrayList<>(); + return; + } + heroes = newHeroes; + } + + public Hero getHeroById(final String id) { + return heroes.stream() + .filter(x -> StringUtils.equals(x.getId(), id)) + .findFirst() + .orElse(null); + } +} + +// SetHeroes +// GetHeroById +// EquipGearOnHero +// diff --git a/backend/src/com/fribbels/db/ItemDb.java b/backend/src/com/fribbels/db/ItemDb.java new file mode 100644 index 00000000..e54882be --- /dev/null +++ b/backend/src/com/fribbels/db/ItemDb.java @@ -0,0 +1,119 @@ +package com.fribbels.db; + +import com.fribbels.enums.Gear; +import com.fribbels.model.AugmentedStats; +import com.fribbels.model.Hero; +import com.fribbels.model.Item; +import com.fribbels.request.ItemsRequest; +import org.apache.commons.lang3.StringUtils; + +import java.math.BigDecimal; +import java.math.RoundingMode; +import java.text.DecimalFormat; +import java.util.ArrayList; +import java.util.List; +import java.util.stream.Collectors; + +public class ItemDb { + + private List items; + private HeroDb heroDb; + + public ItemDb(final HeroDb heroDb) { + items = new ArrayList<>(); + this.heroDb = heroDb; + } + + public void addItems(final List newItems) { + newItems.forEach(this::calculateWss); + items.addAll(newItems); + } + + public void setItems(final List newItems) { + newItems.forEach(this::calculateWss); + items = newItems; + } + + public List getAllItems() { + return items; + } + + private void calculateWss(final Item item) { + final AugmentedStats stats = item.getAugmentedStats(); + double value = + stats.getAttackPercent() + + stats.getDefensePercent() + + stats.getHealthPercent() + + stats.getEffectResistance() + + stats.getEffectiveness() + + stats.getSpeed() * (8.0/4.0) + + stats.getCritDamage() * (8.0/7.0) + + stats.getCritRate() * (8.0/5.0) + + stats.getAttack() / 39.0 * (1.0/2.0) + + stats.getDefense() / 31.0 * (1.0/2.0) + + stats.getHealth() / 174.0 * (1.0/2.0); + + DecimalFormat df = new DecimalFormat("#.#"); + df.setRoundingMode(RoundingMode.CEILING); + + System.out.println("VALUE" + value); + + item.setWss((int) Math.round(value)); + } + + public Item getItemById(final String id) { + return items.stream() + .filter(x -> StringUtils.equals(x.getId(), id)) + .findFirst() + .orElse(null); + } + + public List getItemsById(final List ids) { + return ids.stream() + .map(this::getItemById) + .collect(Collectors.toList()); + } + + public void editItem(final Item item) { + + } + + public void lockItem(final Item item) { + + } + + public void unequipItem(final String id) { + final Item existingItem = getItemById(id); + + if (existingItem == null) { + return; + } + + existingItem.setEquippedById(null); + existingItem.setEquippedByName(null); + } + + public void equipItemOnHero(final String itemId, final String heroId) { + final Item item = getItemById(itemId); + final Hero hero = heroDb.getHeroById(heroId); + + if (item == null || hero == null) { + return; + } + + final String previousOwner = item.getEquippedById(); + if (previousOwner != null && !StringUtils.equals(previousOwner, heroId)) { + System.out.println("PREV OWNER" + previousOwner); + heroDb.getHeroById(previousOwner).getEquipment().remove(item.getGear()); + } + + final Item previousItem = hero.switchItem(item); + if (previousItem != null && !StringUtils.equals(previousItem.getId(), item.getId())) { + System.out.println("PREV ITEM" + previousItem); + unequipItem(previousItem.getId()); + } + + item.setEquippedById(heroId); + item.setEquippedByName(hero.getName()); + } +} diff --git a/backend/src/com/fribbels/db/OptimizationDb.java b/backend/src/com/fribbels/db/OptimizationDb.java new file mode 100644 index 00000000..c845c28d --- /dev/null +++ b/backend/src/com/fribbels/db/OptimizationDb.java @@ -0,0 +1,116 @@ +package com.fribbels.db; + +import com.fribbels.core.Sorter; +import com.fribbels.enums.OptimizationColumn; +import com.fribbels.enums.SortOrder; +import com.fribbels.model.HeroStats; +import org.apache.commons.lang3.ArrayUtils; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +public class OptimizationDb { + + private HeroStats[] resultHeroStats; + private int[] filteredIndices; + private Set filteredIds; + private long maximum; + private long filteredMaximum; + private boolean filtered = false; + + private OptimizationColumn column; + private SortOrder order; + + public OptimizationDb() { + resultHeroStats = new HeroStats[]{}; + filteredIndices = new int[]{}; + filteredIds = new HashSet<>(); + maximum = 0; + filteredMaximum = 0; + filtered = false; + } + + public void setResultHeroes(final HeroStats[] newResultHeroStats, final long newMaximum) { + resultHeroStats = ArrayUtils.subarray(newResultHeroStats, 0, Integer.parseInt("" + newMaximum)); + maximum = newMaximum; + filteredMaximum = 0; + filteredIds = new HashSet<>(); + filteredIndices = new int[]{}; + filtered = false; + } + + public void setFilteredIds(final Set newFilteredIds, final int newFilteredMaximum) { + filtered = true; + filteredIds = newFilteredIds; + filteredMaximum = newFilteredMaximum; + + int count = 0; + final int[] sortedFilteredIndices = new int[newFilteredMaximum]; + for (int i = 0; i < maximum; i++) { + if (filteredIds.contains(resultHeroStats[i].getId())) { + sortedFilteredIndices[count] = i; + count++; + } + } + + filteredIndices = sortedFilteredIndices; + } + + public HeroStats[] getRows(final int startRow, final int endRow) { + System.out.println("Filtered indices.length " + filteredIndices.length); + System.out.println("FilteredIds size " + filteredIds.size()); + + if (filteredIds.size() == 0) { + return ArrayUtils.subarray(resultHeroStats, startRow, endRow); + } + + final List results = new ArrayList<>(); + for (int i = startRow; i < endRow; i++) { + if (i >= filteredIndices.length) { + break; + } + final int index = filteredIndices[i]; + final HeroStats heroStats = resultHeroStats[index]; + results.add(heroStats); + } + + final HeroStats[] resultsArray = new HeroStats[results.size()]; + return results.toArray(resultsArray); + } + + public HeroStats[] getAllHeroStats() { + return resultHeroStats; + } + + public long getMaximum() { + if (filtered) + return filteredMaximum; + return maximum; + } + + public void sort(final OptimizationColumn newColumn, final SortOrder newOrder) { + if (newColumn == null || newOrder == null || (newColumn == column && newOrder == order)) { + return; + } + + System.out.println("START SORT"); + Sorter.sortHeroes(resultHeroStats, newColumn, newOrder); + System.out.println("END SORT"); + + int count = 0; + final int[] sortedFilteredIndices = new int[Integer.parseInt("" + maximum)]; + for (int i = 0; i < maximum; i++) { + if (filteredIds.contains(resultHeroStats[i].getId())) { + sortedFilteredIndices[count] = i; + count++; + } + } + + filteredIndices = sortedFilteredIndices; + + column = newColumn; + order = newOrder; + } +} diff --git a/backend/src/com/fribbels/enums/Gear.java b/backend/src/com/fribbels/enums/Gear.java new file mode 100644 index 00000000..ce56adba --- /dev/null +++ b/backend/src/com/fribbels/enums/Gear.java @@ -0,0 +1,36 @@ +package com.fribbels.enums; + +import com.google.gson.annotations.SerializedName; + +public enum Gear { + + @SerializedName("Weapon") WEAPON, + @SerializedName("Helmet") HELMET, + @SerializedName("Armor") ARMOR, + @SerializedName("Necklace") NECKLACE, + @SerializedName("Ring") RING, + @SerializedName("Boots") BOOTS; + + @Override + public String toString() { + if (this == Gear.WEAPON) { + return "Weapon"; + } + if (this == Gear.HELMET) { + return "Helmet"; + } + if (this == Gear.ARMOR) { + return "Armor"; + } + if (this == Gear.NECKLACE) { + return "Necklace"; + } + if (this == Gear.RING) { + return "Ring"; + } + if (this == Gear.BOOTS) { + return "Boots"; + } + return ""; + } +} diff --git a/backend/src/com/fribbels/enums/OptimizationColumn.java b/backend/src/com/fribbels/enums/OptimizationColumn.java new file mode 100644 index 00000000..bbe8afb4 --- /dev/null +++ b/backend/src/com/fribbels/enums/OptimizationColumn.java @@ -0,0 +1,28 @@ +package com.fribbels.enums; + +import com.google.gson.annotations.SerializedName; +import lombok.AllArgsConstructor; +import lombok.Getter; + +@Getter +@AllArgsConstructor +public enum OptimizationColumn { + + @SerializedName("atk") ATK, + @SerializedName("hp") HP, + @SerializedName("def") DEF, + @SerializedName("spd") SPD, + @SerializedName("cr") CR, + @SerializedName("cd") CD, + @SerializedName("eff") EFF, + @SerializedName("res") RES, + @SerializedName("dac") DAC, + @SerializedName("cp") CP, + @SerializedName("hpps") HPPS, + @SerializedName("ehp") EHP, + @SerializedName("ehpps") EHPPS, + @SerializedName("dmg") DMG, + @SerializedName("dmgps") DMGPS, + @SerializedName("mcdmg") MCDMG, + @SerializedName("mcdmgps") MCDMGPS, +} diff --git a/backend/src/com/fribbels/enums/Rank.java b/backend/src/com/fribbels/enums/Rank.java new file mode 100644 index 00000000..afb35bfd --- /dev/null +++ b/backend/src/com/fribbels/enums/Rank.java @@ -0,0 +1,12 @@ +package com.fribbels.enums; + +import com.google.gson.annotations.SerializedName; + +public enum Rank { + + @SerializedName("Normal") NORMAL, + @SerializedName("Good") GOOD, + @SerializedName("Rare") RARE, + @SerializedName("Heroic") HEROIC, + @SerializedName("Epic") EPIC +} diff --git a/backend/src/com/fribbels/enums/Set.java b/backend/src/com/fribbels/enums/Set.java new file mode 100644 index 00000000..2e2c8574 --- /dev/null +++ b/backend/src/com/fribbels/enums/Set.java @@ -0,0 +1,33 @@ +package com.fribbels.enums; + +import com.google.gson.annotations.SerializedName; +import lombok.AllArgsConstructor; +import lombok.Getter; + +@Getter +@AllArgsConstructor +public enum Set { + + @SerializedName("HealthSet") HEALTH (0, 2, new int[]{2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, new int[]{0, 0}, "HealthSet"), + @SerializedName("DefenseSet") DEFENSE (1, 2, new int[]{0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, new int[]{1, 1}, "DefenseSet"), + @SerializedName("AttackSet") ATTACK (2, 4, new int[]{0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, new int[]{2, 2, 2, 2}, "AttackSet"), + @SerializedName("SpeedSet") SPEED (3, 4, new int[]{0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, new int[]{3, 3, 3, 3}, "SpeedSet"), + @SerializedName("CriticalSet") CRIT (4, 2, new int[]{0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, new int[]{4, 4}, "CriticalSet"), + @SerializedName("HitSet") HIT (5, 2, new int[]{0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, new int[]{5, 5}, "HitSet"), + @SerializedName("DestructionSet") DESTRUCTION (6, 4, new int[]{0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0}, new int[]{6, 6, 6, 6}, "DestructionSet"), + @SerializedName("LifestealSet") LIFESTEAL (7, 4, new int[]{0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0}, new int[]{7, 7, 7, 7}, "LifestealSet"), + @SerializedName("CounterSet") COUNTER (8, 4, new int[]{0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0}, new int[]{8, 8, 8, 8}, "CounterSet"), + @SerializedName("ResistSet") RESIST (9, 2, new int[]{0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0}, new int[]{9, 9}, "ResistSet"), + @SerializedName("UnitySet") UNITY (10, 2, new int[]{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0}, new int[]{10, 10}, "UnitySet"), + @SerializedName("RageSet") RAGE (11, 4, new int[]{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0}, new int[]{11, 11, 11, 11}, "RageSet"), + @SerializedName("ImmunitySet") IMMUNITY (12, 2, new int[]{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0}, new int[]{12, 12}, "ImmunitySet"), + @SerializedName("PenetrationSet") PENETRATION (13, 2, new int[]{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0}, new int[]{13, 13}, "PenetrationSet"), + @SerializedName("RevengeSet") REVENGE (14, 4, new int[]{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0}, new int[]{14, 14, 14, 14}, "RevengeSet"), + @SerializedName("InjurySet") INJURY (15, 4, new int[]{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4}, new int[]{15, 15, 15, 15}, "InjurySet"); + + private int index; + private int count; + private int[] arr; + private int[] indices; + private String name; +} diff --git a/backend/src/com/fribbels/enums/SortOrder.java b/backend/src/com/fribbels/enums/SortOrder.java new file mode 100644 index 00000000..1a5c4a2f --- /dev/null +++ b/backend/src/com/fribbels/enums/SortOrder.java @@ -0,0 +1,14 @@ +package com.fribbels.enums; + +import com.google.gson.annotations.SerializedName; +import lombok.AllArgsConstructor; +import lombok.Getter; + + +@Getter +@AllArgsConstructor +public enum SortOrder { + + @SerializedName("asc") ASC, + @SerializedName("desc") DESC, +} diff --git a/backend/src/com/fribbels/enums/StatType.java b/backend/src/com/fribbels/enums/StatType.java new file mode 100644 index 00000000..bdcd150a --- /dev/null +++ b/backend/src/com/fribbels/enums/StatType.java @@ -0,0 +1,25 @@ +package com.fribbels.enums; + +import com.google.gson.annotations.SerializedName; +import lombok.AllArgsConstructor; +import lombok.Getter; + +@Getter +@AllArgsConstructor +public enum StatType { + + @SerializedName("Attack") ATTACK (0), + @SerializedName("Health") HEALTH (1), + @SerializedName("Defense") DEFENSE (2), + @SerializedName("AttackPercent") ATTACKPERCENT (3), + @SerializedName("HealthPercent") HEALTHPERCENT (4), + @SerializedName("DefensePercent") DEFENSEPERCENT (5), + @SerializedName("CriticalHitChancePercent") CRITRATE (6), + @SerializedName("CriticalHitDamagePercent") CRITDAMAGE (7), + @SerializedName("EffectivenessPercent") EFFECTIVENESS (8), + @SerializedName("EffectResistancePercent") EFFECTRESISTANCE (9), + @SerializedName("Speed") SPEED (10), + @SerializedName("Dac") DAC (11); + + private int index; +} diff --git a/backend/src/com/fribbels/handler/HeroesRequestHandler.java b/backend/src/com/fribbels/handler/HeroesRequestHandler.java new file mode 100644 index 00000000..0392affd --- /dev/null +++ b/backend/src/com/fribbels/handler/HeroesRequestHandler.java @@ -0,0 +1,286 @@ +package com.fribbels.handler; + +import com.fribbels.core.StatCalculator; +import com.fribbels.db.BaseStatsDb; +import com.fribbels.db.HeroDb; +import com.fribbels.db.ItemDb; +import com.fribbels.enums.Gear; +import com.fribbels.model.Hero; +import com.fribbels.model.HeroStats; +import com.fribbels.model.Item; +import com.fribbels.request.BaseStatsRequest; +import com.fribbels.request.BonusStatsRequest; +import com.fribbels.request.EquipItemsOnHeroRequest; +import com.fribbels.request.HeroesRequest; +import com.fribbels.request.IdRequest; +import com.fribbels.response.GetAllHeroesResponse; +import com.fribbels.response.GetHeroByIdResponse; +import com.google.common.collect.Iterables; +import com.sun.net.httpserver.HttpExchange; +import com.sun.net.httpserver.HttpHandler; +import lombok.AllArgsConstructor; +import org.apache.commons.lang3.StringUtils; + +import java.io.IOException; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +@AllArgsConstructor +public class HeroesRequestHandler extends RequestHandler implements HttpHandler { + + private final HeroDb heroDb; + private final BaseStatsDb baseStatsDb; + private final ItemDb itemDb; + + @Override + public void handle(final HttpExchange exchange) throws IOException { + System.out.println("===================== HeroesRequestHandler ====================="); + final String path = exchange.getRequestURI().getPath(); + + System.out.println("Path: " + path); + try { + switch(path) { + case "/heroes/addHeroes": + final HeroesRequest heroesRequest = parseRequest(exchange, HeroesRequest.class); + sendResponse(exchange, addHeroes(heroesRequest)); + return; + case "/heroes/setHeroes": + final HeroesRequest setHeroesRequest = parseRequest(exchange, HeroesRequest.class); + sendResponse(exchange, setHeroes(setHeroesRequest)); + return; + case "/heroes/getAllHeroes": + sendResponse(exchange, getAllHeroes()); + return; + case "/heroes/removeHeroById": + final IdRequest removeHeroByIdRequest = parseRequest(exchange, IdRequest.class); + sendResponse(exchange, removeHeroById(removeHeroByIdRequest)); + return; + case "/heroes/unequipHeroById": + final IdRequest unequipHeroByIdRequest = parseRequest(exchange, IdRequest.class); + sendResponse(exchange, unequipHeroById(unequipHeroByIdRequest)); + return; + case "/heroes/unlockHeroById": + final IdRequest unlockHeroByIdRequest = parseRequest(exchange, IdRequest.class); + sendResponse(exchange, toggleLockHeroById(unlockHeroByIdRequest, false)); + return; + case "/heroes/lockHeroById": + final IdRequest lockHeroByIdRequest = parseRequest(exchange, IdRequest.class); + sendResponse(exchange, toggleLockHeroById(lockHeroByIdRequest, true)); + return; + case "/heroes/unequipItem": + final IdRequest unequipItemRequest = parseRequest(exchange, IdRequest.class); + sendResponse(exchange, unequipItem(unequipItemRequest)); + return; + case "/heroes/getHeroById": + final IdRequest getHeroByIdRequest = parseRequest(exchange, IdRequest.class); + sendResponse(exchange, getHeroById(getHeroByIdRequest)); + return; + case "/heroes/equipItemsOnHero": + final EquipItemsOnHeroRequest equipItemsOnHeroRequest = parseRequest(exchange, EquipItemsOnHeroRequest.class); + sendResponse(exchange, equipItemsOnHero(equipItemsOnHeroRequest)); + return; + case "/heroes/setBaseStats": + final BaseStatsRequest baseStatsRequest = parseRequest(exchange, BaseStatsRequest.class); + sendResponse(exchange, setBaseStats(baseStatsRequest)); + return; + case "/heroes/setBonusStats": + final BonusStatsRequest bonusStatsRequest = parseRequest(exchange, BonusStatsRequest.class); + sendResponse(exchange, setBonusStats(bonusStatsRequest)); + return; + + default: + System.out.println("No handler found for " + path); + } + + sendResponse(exchange, "ERROR"); + } catch (final Exception e) { + e.printStackTrace(); + throw (e); + } + } + + public String setBaseStats(final BaseStatsRequest request) { + baseStatsDb.setBaseStatsByName(request.getBaseStatsByName()); + + return ""; + } + + public String setBonusStats(final BonusStatsRequest request) { + final Hero hero = heroDb.getHeroById(request.getHeroId()); + if (hero == null) return ""; + + hero.setBonusStats(request); + + return ""; + } + + public String addHeroes(final HeroesRequest request) { + heroDb.addHeroes(request.getHeroes()); + return ""; + } + + public String setHeroes(final HeroesRequest request) { + heroDb.setHeroes(request.getHeroes()); + return ""; + } + + public String getAllHeroes() { + final List heroes = heroDb.getAllHeroes(); + System.out.println("Heroes" + heroes); + + for (final Hero hero : heroes) { + + final HeroStats baseStats = baseStatsDb.getBaseStatsByName(hero.getName()); + + final Map equipment = hero.getEquipment(); + + + if (equipment == null || equipment.values().size() != 6) { + hero.setStats(new HeroStats()); + continue; + } + + final Item[] items = Iterables.toArray(equipment.values(), Item.class); + + final int[] setsArr = StatCalculator.buildSetsArr(items); + final List statAccumulators = equipment.values() + .stream() + .map(item -> StatCalculator.buildStatAccumulatorArr(baseStats, item)) + .collect(Collectors.toList()); + final float[][] statAccumulatorArrs = Iterables.toArray(statAccumulators, float[].class); + + final HeroStats finalStats = StatCalculator.addAccumulatorArrsToHero(baseStats, statAccumulatorArrs, setsArr, hero); + hero.setStats(finalStats); + } + + final GetAllHeroesResponse response = GetAllHeroesResponse.builder() + .heroes(heroes) + .build(); + +// System.out.println(response); + + return toJson(response); + } + + public String getHeroById(final IdRequest request) { + final Hero hero = heroDb.getHeroById(request.getId()); + final GetHeroByIdResponse response = GetHeroByIdResponse.builder() + .hero(hero) + .build(); + + return toJson(response); + } + + public String removeHeroById(final IdRequest request) { + System.out.println(request); + final String id = request.getId(); + final Hero hero = heroDb.getHeroById(id); + + if (hero == null) return ""; + + // Unlink hero from equipments + if (hero.getEquipment() != null) { + final Item[] equipment = hero.getEquipment().values().toArray(new Item[0]); + for (int i = 0; i < equipment.length; i++) { + final Item previousItem = equipment[i]; + + previousItem.setEquippedById(null); + previousItem.setEquippedByName(null); + } + } + + // Remove the hero from db + final List heroes = heroDb.getAllHeroes(); + final List newHeroes = heroes.stream() + .filter(x -> !StringUtils.equals(x.getId(), request.getId())) + .collect(Collectors.toList()); + heroDb.setHeroes(newHeroes); + + final GetAllHeroesResponse response = GetAllHeroesResponse.builder() + .heroes(newHeroes) + .build(); + + return toJson(response); + } + + public String unequipHeroById(final IdRequest request) { + System.out.println(request); + final String id = request.getId(); + final Hero hero = heroDb.getHeroById(id); + + if (hero == null) return ""; + + if (hero.getEquipment() != null) { + // Unlink the gear from the hero + final Item[] equipment = hero.getEquipment().values().toArray(new Item[0]); + for (int i = 0; i < equipment.length; i++) { + final Item previousItem = equipment[i]; + + if (previousItem == null) { + continue; + } + + final Item dbItem = itemDb.getItemById(previousItem.getId()); + + dbItem.setEquippedById(null); + dbItem.setEquippedByName(null); + } + hero.setEquipment(new HashMap<>()); + } + + return ""; + } + + public String toggleLockHeroById(final IdRequest request, final boolean locked) { + System.out.println(request); + final String id = request.getId(); + final Hero hero = heroDb.getHeroById(id); + + if (hero == null) return ""; + + if (hero.getEquipment() != null) { + // Unlink the gear from the hero + final Item[] equipment = hero.getEquipment().values().toArray(new Item[0]); + for (int i = 0; i < equipment.length; i++) { + final Item item = equipment[i]; + + if (item == null) { + continue; + } + + final Item dbItem = itemDb.getItemById(item.getId()); + dbItem.setLocked(locked); + + } + } + + return ""; + } + + public String unequipItem(final IdRequest request) { + final String itemId = request.getId(); + if (itemDb.getItemById(itemId) == null) return ""; + + itemDb.unequipItem(itemId); + + return ""; + } + + public String equipItemsOnHero(final EquipItemsOnHeroRequest request) { + final String heroId = request.getHeroId(); + if (heroDb.getHeroById(heroId) == null) return ""; + + final List itemIds = request.getItemIds(); + final List items = itemIds.stream() + .map(itemDb::getItemById) + .collect(Collectors.toList()); + + for (final Item item : items) { + itemDb.equipItemOnHero(item.getId(), heroId); + } + + return ""; + } +} diff --git a/backend/src/com/fribbels/handler/ItemsRequestHandler.java b/backend/src/com/fribbels/handler/ItemsRequestHandler.java new file mode 100644 index 00000000..209fce63 --- /dev/null +++ b/backend/src/com/fribbels/handler/ItemsRequestHandler.java @@ -0,0 +1,134 @@ +package com.fribbels.handler; + +import com.fribbels.db.ItemDb; +import com.fribbels.model.Item; +import com.fribbels.request.IdRequest; +import com.fribbels.request.IdsRequest; +import com.fribbels.request.ItemsRequest; +import com.fribbels.response.GetAllItemsResponse; +import com.fribbels.response.GetItemByIdResponse; +import com.google.gson.Gson; +import com.sun.net.httpserver.HttpExchange; +import com.sun.net.httpserver.HttpHandler; +import lombok.AllArgsConstructor; + +import java.io.IOException; +import java.util.List; + +@AllArgsConstructor +public class ItemsRequestHandler extends RequestHandler implements HttpHandler { + + private final ItemDb itemDb; + + private static final Gson GSON = new Gson(); + + @Override + public void handle(final HttpExchange exchange) throws IOException { + System.out.println("===================== ItemsRequestHandler ====================="); + final String path = exchange.getRequestURI().getPath(); + + System.out.println("Path: " + path); + + try { + switch (path) { + case "/items/addItems": + final ItemsRequest addItemsRequest = parseRequest(exchange, ItemsRequest.class); + sendResponse(exchange, addItems(addItemsRequest)); + return; + case "/items/setItems": + final ItemsRequest setItemsRequest = parseRequest(exchange, ItemsRequest.class); + sendResponse(exchange, setItems(setItemsRequest)); + return; + case "/items/getAllItems": + sendResponse(exchange, getAllItems()); + return; + case "/items/getItemById": + final IdRequest getItemByIdRequest = parseRequest(exchange, IdRequest.class); + sendResponse(exchange, getItemById(getItemByIdRequest)); + return; + case "/items/lockItems": + final IdsRequest lockItemsRequest = parseRequest(exchange, IdsRequest.class); + sendResponse(exchange, lockItems(lockItemsRequest)); + return; + case "/items/editItems": + final ItemsRequest editItemsRequest = parseRequest(exchange, ItemsRequest.class); + sendResponse(exchange, editItems(editItemsRequest)); + return; + default: + System.out.println("No handler found for " + path); + } + } catch (final RuntimeException e) { + e.printStackTrace(); + } + + sendResponse(exchange, "ERROR"); + } + + public String addItems(final ItemsRequest request) { + itemDb.addItems(request.getItems()); + + return ""; + } + + public String setItems(final ItemsRequest request) { + itemDb.setItems(request.getItems()); + + return ""; + } + + public String editItems(final ItemsRequest request) { + final List items = request.getItems(); + for (final Item item : items) { + final Item dbItem = itemDb.getItemById(item.getId()); + if (dbItem == null) { + System.out.println("No dbitem matching:" + item.getId()); + continue; + } + + dbItem.setEquippedByName(item.getEquippedByName()); + dbItem.setEquippedById(item.getEquippedById()); + dbItem.setLocked(item.isLocked()); + dbItem.setAugmentedStats(item.getAugmentedStats()); + dbItem.setEnhance(item.getEnhance()); + dbItem.setGear(item.getGear()); + dbItem.setLevel(item.getLevel()); + dbItem.setMain(item.getMain()); + dbItem.setRank(item.getRank()); + dbItem.setSet(item.getSet()); + dbItem.setSubstats(item.getSubstats()); + System.out.println("EDITED ITEM"); + } + + return ""; + } + + public String lockItems(final IdsRequest request) { + System.out.println(request); + final List items = itemDb.getItemsById(request.getIds()); + for (final Item item : items) { + item.setLocked(true); + } + + return ""; + } + + public String getAllItems() { + final List items = itemDb.getAllItems(); + final GetAllItemsResponse response = GetAllItemsResponse.builder() + .items(items) + .build(); + + return toJson(response); + } + + public String getItemById(final IdRequest request) { + final Item item = itemDb.getItemById(request.getId()); + System.out.println(request); + System.out.println(item); + final GetItemByIdResponse response = GetItemByIdResponse.builder() + .item(item) + .build(); + + return toJson(response); + } +} diff --git a/backend/src/com/fribbels/handler/OcrRequestHandler.java b/backend/src/com/fribbels/handler/OcrRequestHandler.java new file mode 100644 index 00000000..446b1ca1 --- /dev/null +++ b/backend/src/com/fribbels/handler/OcrRequestHandler.java @@ -0,0 +1,293 @@ +package com.fribbels.handler; + +import com.fribbels.enums.Set; +import com.fribbels.request.IdRequest; +import com.fribbels.request.Ocr2Request; +import com.fribbels.response.OcrResponse; +import com.sun.net.httpserver.HttpExchange; +import com.sun.net.httpserver.HttpHandler; +import org.apache.commons.lang3.StringUtils; +import org.bytedeco.javacpp.BytePointer; +import org.bytedeco.leptonica.PIX; +import org.bytedeco.tesseract.TessBaseAPI; + +import java.io.IOException; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.AbstractMap; +import java.util.Comparator; +import java.util.Map; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +import static org.bytedeco.leptonica.global.lept.pixDestroy; +import static org.bytedeco.leptonica.global.lept.pixRead; + +public class OcrRequestHandler extends RequestHandler implements HttpHandler { + + private TessBaseAPI tessBaseAPI; + + public OcrRequestHandler() { + tessBaseAPI = new TessBaseAPI(); + System.err.println("Working Directory = " + System.getProperty("user.dir")); + Path currentRelativePath = Paths.get(""); + String s = currentRelativePath.toAbsolutePath().toString(); + System.err.println("Current relative path is: " + s); + System.err.println("path is: " + s + "/resources/resources/tessdata/eng.traineddata"); + if (tessBaseAPI.Init(s + "\\resources\\resources\\tessdata\\eng.traineddata", "eng", 0) != 0) { + System.err.println("Could not initialize tesseract."); + System.exit(1); + } + + tessBaseAPI.SetVariable("load_system_dawg", "false"); + tessBaseAPI.SetVariable("load_freq_dawg", "false"); + tessBaseAPI.SetVariable("classify_enable_learning", "0"); + } + + @Override + public void handle(final HttpExchange exchange) throws IOException { + System.out.println("===================== ItemsRequestHandler ====================="); + final String path = exchange.getRequestURI().getPath(); + + System.out.println("Path: " + path); + + try { + switch (path) { + case "/ocr": + final IdRequest ocrRequest = parseRequest(exchange, IdRequest.class); + sendResponse(exchange, handleOcrRequest(ocrRequest)); + return; + case "/ocr2": + final Ocr2Request ocr2Request = parseRequest(exchange, Ocr2Request.class); + sendResponse(exchange, handleOcr2Request(ocr2Request)); + return; + default: + System.out.println("No handler found for " + path); + } + } catch (final RuntimeException e) { + e.printStackTrace(); + } + + sendResponse(exchange, "ERROR"); + } + + private String handleOcr2Request(final Ocr2Request request) { + final String levelFilename = request.getId() + "debugLevel.png"; + final String substatsFilename = request.getId() + "debugSubstats.png"; + final PIX levelImage = pixRead(levelFilename); + final PIX substatsImage = pixRead(substatsFilename); + + tessBaseAPI.SetImage(levelImage); + pixDestroy(levelImage); + + final String enhance; + final String level; + final String substatsText; + final String substatsNumbers; + + if (request.getShifted()) { + enhance = readShiftedEnhance(); + level = readShiftedLevel(); + } else { + enhance = readEnhance(); + level = readLevel(); + } + + tessBaseAPI.SetImage(substatsImage); + pixDestroy(substatsImage); + + if (request.getShifted()) { + substatsText = readShiftedSubstatsText(); + substatsNumbers = readShiftedSubstatsNumbers(); + } else { + substatsText = readSubstatsText(); + substatsNumbers = readSubstatsNumbers(); + } + + final OcrResponse ocrResponse = OcrResponse.builder() + .enhance(enhance) + .level(level) + .substatsText(substatsText) + .substatsNumbers(substatsNumbers) + .build(); + + System.out.println(ocrResponse); + + return toJson(ocrResponse); + } + + private String handleOcrRequest(final IdRequest idRequest) { + final String filename = idRequest.getId(); + final PIX image = pixRead(filename); + + tessBaseAPI.SetImage(image); + pixDestroy(image); + + final Set set = readSet(); + final String title; + final String enhance; + final String level; + final String main; + final String substats; + final String substatsText; + final String substatsNumbers; + + if (isShiftedSet(set)) { + title = readShiftedTitle(); +// enhance = readShiftedEnhance(); +// level = readShiftedLevel(); + main = readShiftedMain(); +// substats = readShiftedSubstats(); +// substatsText = readShiftedSubstatsText(); +// substatsNumbers = readShiftedSubstatsNumbers(); + } else { + title = readTitle(); +// enhance = readEnhance(); +// level = readLevel(); + main = readMain(); +// substats = readSubstats(); +// substatsText = readSubstatsText(); +// substatsNumbers = readSubstatsNumbers(); + } + + // Get OCR result + + final OcrResponse ocrResponse = OcrResponse.builder() + .title(title) +// .enhance(enhance) +// .level(level) + .main(main) +// .substats(substats) +// .substatsText(substatsText) +// .substatsNumbers(substatsNumbers) + .set(set.getName()) + .build(); + + System.out.println(ocrResponse); + + return toJson(ocrResponse); + } + + private int enhanceBufferX = 50; + private int enhanceBufferY = 150; + + private int substatsBufferX = 50; + private int substatsBufferY = 400; + + private String readTitle() { + setText(); + return readRectangle(177, 185, 234, 170); + } + + private String readEnhance() { + setNumbersAndPlus(); + return readRectangle(132-enhanceBufferX, 198-enhanceBufferY, 40, 19); + } + + private String readLevel() { + setNumbers(); + return readRectangle(65-enhanceBufferX, 212-enhanceBufferY, 25, 19); + } + + private String readMain() { + setNumbersAndTextAndPercentAndComma(); + return readRectangle(85, 370, 318, 53); + } + + private String readSubstatsText() { + setText(); + return readRectangle(0, 193, 1000, 580); + } + + private String readSubstatsNumbers() { + setNumbersAndPercentAndComma(); + return readRectangle(1041, 185, 354, 553); + } + + // + + private String readShiftedTitle() { + setText(); + return readRectangle(176, 160, 236, 170); + } + + private String readShiftedEnhance() { + setNumbersAndPlus(); + return readRectangle(132-enhanceBufferX, 173-enhanceBufferY, 39, 20); + } + + private String readShiftedLevel() { + setNumbers(); + return readRectangle(65-enhanceBufferX, 188-enhanceBufferY, 27, 18); + } + + private String readShiftedMain() { + setNumbersAndTextAndPercentAndComma(); + return readRectangle(84, 342, 323, 69); + } + + private String readShiftedSubstatsText() { + setText(); + return readRectangle(0, 100, 1000, 567); + } + + private String readShiftedSubstatsNumbers() { + setNumbersAndPercentAndComma(); + return readRectangle(1034, 108, 339, 524); + } + + private Set readSet() { + setText(); + final String text = readRectangle(100, 572, 250, 69); + + final Map distances = Stream.of(Set.values()).collect(Collectors.toMap( + x -> x, + x -> StringUtils.getLevenshteinDistance(x.getName(), text))); + + final Set likelySet = distances.entrySet().stream() + .min(Comparator.comparingInt(Map.Entry::getValue)) + .orElse(new AbstractMap.SimpleEntry<>(Set.SPEED, 0)) + .getKey(); + + return likelySet; + } + + private String readRectangle(final int x, final int y, final int w, final int h) { + final BytePointer outText; + tessBaseAPI.SetRectangle(x, y, w, h); + outText = tessBaseAPI.GetUTF8Text(); + + final String text = outText.getString(); + outText.deallocate(); + + + return text; + } + + private boolean isShiftedSet(final Set set) { + return set == Set.REVENGE + || set == Set.INJURY + || set == Set.PENETRATION + || set == Set.IMMUNITY; + } + + private void setNumbers() { + tessBaseAPI.SetVariable("tessedit_char_whitelist", "0123456789"); + } + + private void setNumbersAndPercentAndComma() { + tessBaseAPI.SetVariable("tessedit_char_whitelist", "0123456789%,"); + } + + private void setNumbersAndPlus() { + tessBaseAPI.SetVariable("tessedit_char_whitelist", "0123456789+"); + } + + private void setNumbersAndTextAndPercentAndComma() { + tessBaseAPI.SetVariable("tessedit_char_whitelist", "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789%,"); + } + + private void setText() { + tessBaseAPI.SetVariable("tessedit_char_whitelist", "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"); + } +} diff --git a/backend/src/com/fribbels/handler/OptimizationRequestHandler.java b/backend/src/com/fribbels/handler/OptimizationRequestHandler.java new file mode 100644 index 00000000..8aa675b0 --- /dev/null +++ b/backend/src/com/fribbels/handler/OptimizationRequestHandler.java @@ -0,0 +1,554 @@ +package com.fribbels.handler; + +import com.fribbels.Main; +import com.fribbels.core.StatCalculator; +import com.fribbels.db.OptimizationDb; +import com.fribbels.enums.Gear; +import com.fribbels.enums.Set; +import com.fribbels.enums.StatType; +import com.fribbels.model.AugmentedStats; +import com.fribbels.model.HeroStats; +import com.fribbels.model.Item; +import com.fribbels.request.GetResultRowsRequest; +import com.fribbels.request.OptimizationRequest; +import com.fribbels.response.GetResultRowsResponse; +import com.fribbels.response.OptimizationResponse; +import com.google.common.collect.ImmutableList; +import com.google.gson.Gson; +import com.sun.net.httpserver.HttpExchange; +import com.sun.net.httpserver.HttpHandler; +import lombok.AllArgsConstructor; +import lombok.Getter; +import org.apache.commons.lang3.ArrayUtils; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Comparator; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.concurrent.atomic.AtomicLong; +import java.util.function.Function; +import java.util.stream.Collectors; + +public class OptimizationRequestHandler extends RequestHandler implements HttpHandler { + + private OptimizationDb optimizationDb; + + private static final Gson gson = new Gson(); + @Getter + private AtomicLong counter; + + public OptimizationRequestHandler(final OptimizationDb optimizationDb) { + this.optimizationDb = optimizationDb; + } + + @Override + public void handle(final HttpExchange exchange) throws IOException { + System.out.println("===================== OptimizationRequestHandler ====================="); + final String path = exchange.getRequestURI().getPath(); + + System.out.println("Path: " + path); + + try { + switch (path) { + case "/optimization/optimizationRequest": + Main.interrupt = false; + final OptimizationRequest optimizationRequest = parseRequest(exchange, OptimizationRequest.class); + sendResponse(exchange, handleOptimizationRequest(optimizationRequest)); + System.out.println("Sent response"); + return; + case "/optimization/optimizationFilterRequest": + final OptimizationRequest optimizationFilterRequest = parseRequest(exchange, OptimizationRequest.class); + sendResponse(exchange, handleOptimizationFilterRequest(optimizationFilterRequest)); + System.out.println("Sent response"); + return; + case "/optimization/getResultRows": + final GetResultRowsRequest getResultRowsRequest = parseRequest(exchange, GetResultRowsRequest.class); + System.out.println(getResultRowsRequest); + sendResponse(exchange, handleGetResultRowsRequest(getResultRowsRequest)); + System.out.println("Sent response"); + return; + case "/optimization/getProgress": + sendResponse(exchange, handleGetProgressRequest()); + System.out.println("Sent response"); + return; + default: + System.out.println("No handler found for " + path); + } + } catch (final RuntimeException e) { + System.err.println(e); + e.printStackTrace(); + } finally { + Main.interrupt = false; + } + + System.out.println("Sent error"); + sendResponse(exchange, "ERROR"); + } + + public String handleGetProgressRequest() { + final OptimizationResponse response = OptimizationResponse.builder() + .count(counter.get()) + .build(); + + return gson.toJson(response); + } + + public String handleOptimizationFilterRequest(final OptimizationRequest request) { + final HeroStats[] heroStats = optimizationDb.getAllHeroStats(); + final int[] indices = new int[heroStats.length]; + final java.util.Set ids = new HashSet<>(); + int count = 0; + + for (int i = 0; i < heroStats.length; i++) { + final HeroStats heroStatsInstance = heroStats[i]; + if (passesUpdatedFilter(request, heroStatsInstance)) { + indices[count] = i; + ids.add(heroStatsInstance.getId()); + count++; + } + } + + System.out.println("Indices count: " + count); + optimizationDb.setFilteredIds(ids, count); + + return ""; + } + + private boolean passesUpdatedFilter(final OptimizationRequest request, final HeroStats heroStats) { + if (heroStats.getAtk() < request.getInputAtkMinLimit() || heroStats.getAtk() > request.getInputAtkMaxLimit() + || heroStats.getHp() < request.getInputHpMinLimit() || heroStats.getHp() > request.getInputHpMaxLimit() + || heroStats.getDef() < request.getInputDefMinLimit() || heroStats.getDef() > request.getInputDefMaxLimit() + || heroStats.getSpd() < request.getInputSpdMinLimit() || heroStats.getSpd() > request.getInputSpdMaxLimit() + || heroStats.getCr() < request.getInputCrMinLimit() || heroStats.getCr() > request.getInputCrMaxLimit() + || heroStats.getCd() < request.getInputCdMinLimit() || heroStats.getCd() > request.getInputCdMaxLimit() + || heroStats.getEff() < request.getInputEffMinLimit() || heroStats.getEff() > request.getInputEffMaxLimit() + || heroStats.getRes() < request.getInputResMinLimit() || heroStats.getRes() > request.getInputResMaxLimit() + || heroStats.getHpps() < request.getInputMinHppsLimit() || heroStats.getHpps() > request.getInputMaxHppsLimit() + || heroStats.getEhp() < request.getInputMinEhpLimit() || heroStats.getEhp() > request.getInputMaxEhpLimit() + || heroStats.getEhpps() < request.getInputMinEhppsLimit() || heroStats.getEhpps() > request.getInputMaxEhppsLimit() + || heroStats.getDmg() < request.getInputMinDmgLimit() || heroStats.getDmg() > request.getInputMaxDmgLimit() + || heroStats.getDmgps() < request.getInputMinDmgpsLimit() || heroStats.getDmgps() > request.getInputMaxDmgpsLimit() + || heroStats.getMcdmg() < request.getInputMinMcdmgLimit() || heroStats.getMcdmg() > request.getInputMaxMcdmgLimit() + || heroStats.getMcdmgps() < request.getInputMinMcdmgpsLimit() || heroStats.getMcdmgps() > request.getInputMaxMcdmgpsLimit() + ) { + return false; + } + return true; + } + + public String handleOptimizationRequest(final OptimizationRequest request) { + optimizationDb = new OptimizationDb(); + return test(request, HeroStats.builder() + .atk(request.getAtk()) + .hp(request.getHp()) + .spd(request.getSpd()) + .def(request.getDef()) + .cr(request.getCr()) + .cd(request.getCd()) + .eff(request.getEff()) + .res(request.getRes()) + .dac(request.getDac()) + .build()); + } + + private String handleGetResultRowsRequest(final GetResultRowsRequest request) { + optimizationDb.sort(request.getSortColumn(), request.getSortOrder()); + final HeroStats[] heroStats = optimizationDb.getRows(request.getStartRow(), request.getEndRow()); + final long maximum = optimizationDb.getMaximum(); + final GetResultRowsResponse response = GetResultRowsResponse.builder() + .heroStats(heroStats) + .maximum(maximum) + .build(); + return gson.toJson(response); + } + + public String test(final OptimizationRequest request, final HeroStats base) { + System.out.println("REQUEST"); + // final OptimizationRequest request = gson.fromJson(data, OptimizationRequest.class); + addCalculatedFields(request); + final List rawItems = request.getItems(); + + final List firstSets = request.getInputSetsOne(); + rawItems.sort(Comparator.comparing(Item::getSet)); + final List priorityItems = new ArrayList<>(); + final List otherItems = new ArrayList<>(); + for (Item item : rawItems) { + if (firstSets.contains(item.getSet())) { + priorityItems.add(item); + } else { + otherItems.add(item); + } + } + + priorityItems.addAll(otherItems); + final List items = priorityItems; + + final int MAXIMUM_RESULTS = 5_000_000; + final HeroStats[] resultHeroStats = new HeroStats[MAXIMUM_RESULTS]; + final long[] resultInts = new long[MAXIMUM_RESULTS]; + System.out.println("MEMORY"); + + // 5/6/5/5/6/5 + final Map> itemsByGear = buildItemsByGear(items); + // Duplicate items + // itemsByGear.entrySet().forEach(x -> itemsByGear.get(x.getKey()).addAll(itemsByGear.get(x.getKey()))); + // itemsByGear.entrySet().forEach(x -> itemsByGear.get(x.getKey()).addAll(itemsByGear.get(x.getKey()))); + // itemsByGear.entrySet().forEach(x -> itemsByGear.get(x.getKey()).addAll(itemsByGear.get(x.getKey()))); + + final Map accumulatorArrsByItem = new HashMap<>(); + final ExecutorService executorService = Executors.newFixedThreadPool(8); + counter = new AtomicLong(0); + final AtomicLong resultsCounter = new AtomicLong(0); + + final int wSize = itemsByGear.get(Gear.WEAPON).size(); + final int hSize = itemsByGear.get(Gear.HELMET).size(); + final int aSize = itemsByGear.get(Gear.ARMOR).size(); + final int nSize = itemsByGear.get(Gear.NECKLACE).size(); + final int rSize = itemsByGear.get(Gear.RING).size(); + final int bSize = itemsByGear.get(Gear.BOOTS).size(); + + final AtomicInteger maxReached = new AtomicInteger(); + + final boolean isShortCircuitable4PieceSet = request.getSetFormat() == 1 || request.getSetFormat() == 2; + + System.out.println("OUTPUTSTART"); + + for (int w = 0; w < wSize; w++) { + final Item weapon = itemsByGear.get(Gear.WEAPON).get(w); + final long finalW = w; + + executorService.submit(() -> { + boolean exit = false; + try { + + final float[] weaponAccumulatorArr = StatCalculator.getStatAccumulatorArr(base, weapon, accumulatorArrsByItem); + + for (int h = 0; h < hSize; h++) { + final Item helmet = itemsByGear.get(Gear.HELMET).get(h); + final float[] helmetAccumulatorArr = StatCalculator.getStatAccumulatorArr(base, helmet, accumulatorArrsByItem); + + for (int a = 0; a < aSize; a++) { + final Item armor = itemsByGear.get(Gear.ARMOR).get(a); + final float[] armorAccumulatorArr = StatCalculator.getStatAccumulatorArr(base, armor, accumulatorArrsByItem); + + // For 4 piece sets, we can short circuit if the first 3 pieces don't match possible sets, + // but only if the items are sorted & prioritized by set. +// System.out.println(weapon.getSet() + " " + helmet.getSet() + " " + armor.getSet()); + if (isShortCircuitable4PieceSet) { + if (!(firstSets.contains(weapon.getSet()) + || firstSets.contains(helmet.getSet()) + || firstSets.contains(armor.getSet()))) { +// exit = true; + return; + } + } + + for (int n = 0; n < nSize; n++) { + final Item necklace = itemsByGear.get(Gear.NECKLACE).get(n); + final float[] necklaceAccumulatorArr = StatCalculator.getStatAccumulatorArr(base, necklace, accumulatorArrsByItem); + + for (int r = 0; r < rSize; r++) { + final Item ring = itemsByGear.get(Gear.RING).get(r); + final float[] ringAccumulatorArr = StatCalculator.getStatAccumulatorArr(base, ring, accumulatorArrsByItem); + + for (int b = 0; b < bSize; b++) { + if (Main.interrupt) { + System.err.println("Interrupted"); + return; + } + if (exit) return; + + final Item boots = itemsByGear.get(Gear.BOOTS).get(b); + final float[] bootsAccumulatorArr = StatCalculator.getStatAccumulatorArr(base, boots, accumulatorArrsByItem); + + final Item[] collectedItems = new Item[]{weapon, helmet, armor, necklace, ring, boots}; + final int[] collectedSets = StatCalculator.buildSetsArr(collectedItems); + final HeroStats result = StatCalculator.addAccumulatorArrsToHero(base, new float[][]{weaponAccumulatorArr, helmetAccumulatorArr, armorAccumulatorArr, necklaceAccumulatorArr, ringAccumulatorArr, bootsAccumulatorArr}, collectedSets, request.getHero()); + final long index = counter.getAndIncrement(); + // final boolean passesFilter = true; + final boolean passesFilter = passesFilter(result, request, collectedSets); + result.setSets(collectedSets); + if (passesFilter) { + final long resultsIndex = resultsCounter.getAndIncrement(); + if (resultsIndex < MAXIMUM_RESULTS) { + result.setId("" + resultsIndex); + + long index1D = finalW * hSize * aSize * nSize * rSize * bSize + h * aSize * nSize * rSize * bSize + a * nSize * rSize * bSize + n * rSize * bSize + r * bSize + b; + resultHeroStats[(int) resultsIndex] = result; + resultInts[(int) resultsIndex] = index1D; + + result.setItems(ImmutableList.of( + weapon.getId(), + helmet.getId(), + armor.getId(), + necklace.getId(), + ring.getId(), + boots.getId() + )); + + if (resultsIndex == MAXIMUM_RESULTS-1) { + maxReached.set(MAXIMUM_RESULTS-1); + } + } else { + System.out.println("EXIT"); + exit = true; + break; + } + } + + if (index % 100000 == 1) { + System.out.println("PROGRESS: [" + index + "]"); + } + } + } + } + } + } + } catch (Exception e) { + e.printStackTrace(); + } + }); + } + + try { + executorService.shutdown(); + executorService.awaitTermination(500, TimeUnit.SECONDS); + + try { + final long size = maxReached.get() == MAXIMUM_RESULTS-1 ? MAXIMUM_RESULTS : resultsCounter.get(); + System.out.println("MaxReached: " + size); + + optimizationDb.setResultHeroes(resultHeroStats, size); + + System.out.println("OPTIMIZATION_REQUEST_END"); + System.out.println("PROGRESS: [" + size + "]"); + OptimizationResponse response = OptimizationResponse.builder() + .count(size) + .build(); + + return gson.toJson(response); + } catch (Exception e) { + e.printStackTrace(); + } + } catch (Exception e) { + e.printStackTrace(); + } + + return ""; + } + + public int[] convertSetsArrayIntoIndexArray(final int[] sets) { + final int[] output = new int[]{0, 0, 0, 0, 0, 0}; + int count = 0; + + for (int i = 0; i < 13; i++) { + if (sets[i] > 0) { + for (int j = 0; j < sets[i]; j++) { + output[count] = i; + count++; + } + } + } + + return output; + } + + public boolean passesFilter(final HeroStats heroStats, final OptimizationRequest request, final int[] sets) { + if (heroStats.getAtk() < request.getInputAtkMinLimit() || heroStats.getAtk() > request.getInputAtkMaxLimit() + || heroStats.getHp() < request.getInputHpMinLimit() || heroStats.getHp() > request.getInputHpMaxLimit() + || heroStats.getDef() < request.getInputDefMinLimit() || heroStats.getDef() > request.getInputDefMaxLimit() + || heroStats.getSpd() < request.getInputSpdMinLimit() || heroStats.getSpd() > request.getInputSpdMaxLimit() + || heroStats.getCr() < request.getInputCrMinLimit() || heroStats.getCr() > request.getInputCrMaxLimit() + || heroStats.getCd() < request.getInputCdMinLimit() || heroStats.getCd() > request.getInputCdMaxLimit() + || heroStats.getEff() < request.getInputEffMinLimit() || heroStats.getEff() > request.getInputEffMaxLimit() + || heroStats.getRes() < request.getInputResMinLimit() || heroStats.getRes() > request.getInputResMaxLimit() + || heroStats.getHpps() < request.getInputMinHppsLimit() || heroStats.getHpps() > request.getInputMaxHppsLimit() + || heroStats.getEhp() < request.getInputMinEhpLimit() || heroStats.getEhp() > request.getInputMaxEhpLimit() + || heroStats.getEhpps() < request.getInputMinEhppsLimit() || heroStats.getEhpps() > request.getInputMaxEhppsLimit() + || heroStats.getDmg() < request.getInputMinDmgLimit() || heroStats.getDmg() > request.getInputMaxDmgLimit() + || heroStats.getDmgps() < request.getInputMinDmgpsLimit() || heroStats.getDmgps() > request.getInputMaxDmgpsLimit() + || heroStats.getMcdmg() < request.getInputMinMcdmgLimit() || heroStats.getMcdmg() > request.getInputMaxMcdmgLimit() + || heroStats.getMcdmgps() < request.getInputMinMcdmgpsLimit() || heroStats.getMcdmgps() > request.getInputMaxMcdmgpsLimit() + ) { + return false; + } + + final int[] indexArray = convertSetsArrayIntoIndexArray(sets); + final int index = calculateSetIndex(indexArray); +// System.out.println(Arrays.toString(indexArray)); + + if (request.getBoolArr()[index] == false) { + return false; + } + + return true; + } + + public Map> buildItemsByGear(final List items) { + return ImmutableList.copyOf(Gear.values()) + .stream() + .collect(Collectors.toMap( + Function.identity(), + gear -> items.stream() + .filter(x -> x.getGear() == gear) + .collect(Collectors.toList()))); + } + + public List getSetsOrElseAll(final List sets) { + if (sets == null || sets.size() == 0) { + return ImmutableList.of(); + } + return sets; + } + + private static final int POW_13_5 = 371293; + private static final int POW_13_4 = 28561; + private static final int POW_13_3 = 2197; + private static final int POW_13_2 = 169; + private static final int POW_13_1 = 13; + + public int calculateSetIndex(final int[] indices) { // sorted, size 6, elements [0-12] + return indices[0] * POW_13_5 + + indices[1] * POW_13_4 + + indices[2] * POW_13_3 + + indices[3] * POW_13_2 + + indices[4] * POW_13_1 + + indices[5]; + } + + public void addCalculatedFields(OptimizationRequest request) { + boolean[] permutations = new boolean[4826809]; + final List inputSets1 = getSetsOrElseAll(request.getInputSetsOne()); + final List inputSets2 = getSetsOrElseAll(request.getInputSetsTwo()); + final List inputSets3 = getSetsOrElseAll(request.getInputSetsThree()); + + final int setFormat = request.getSetFormat(); + if (setFormat == 0) { + // [0][0][0] All valid + + Arrays.fill(permutations, true); + } else if (setFormat == 1) { + // [4][2][0] + + for (Set set1 : inputSets1) { + for (Set set2 : inputSets2) { + final int[] indices = ArrayUtils.addAll(set1.getIndices(), set2.getIndices()); + Arrays.sort(indices); + final int index1D = calculateSetIndex(indices); + permutations[index1D] = true; + // System.out.println(Arrays.toString(indices)); + // System.out.println(set1); + // System.out.println(set2); + // System.out.println(index1D); + // System.out.println("----"); + } + } + } else if (setFormat == 2) { + // [4][0][0] + + final int[] missing = new int[]{0, 0}; + for (Set set1 : inputSets1) { + final int[] indices = ArrayUtils.addAll(set1.getIndices(), missing); + for (int a = 0; a < 13; a++) { + for (int b = 0; b < 13; b++) { + final int[] indicesInstance = ArrayUtils.clone(indices); + indicesInstance[4] = a; + indicesInstance[5] = b; + + Arrays.sort(indicesInstance); + final int index1D = calculateSetIndex(indicesInstance); + permutations[index1D] = true; + // System.out.println(Arrays.toString(indicesInstance)); + // System.out.println(set1); + // System.out.println(index1D); + // System.out.println("----"); + } + } + } + } else if (setFormat == 3) { + // [2][0][0] + + final int[] missing = new int[]{0, 0, 0, 0}; + for (Set set1 : inputSets1) { + final int[] indices = ArrayUtils.addAll(set1.getIndices(), missing); + for (int a = 0; a < 13; a++) { + for (int b = 0; b < 13; b++) { + for (int c = 0; c < 13; c++) { + for (int d = 0; d < 13; d++) { + final int[] indicesInstance = ArrayUtils.clone(indices); + indicesInstance[2] = a; + indicesInstance[3] = b; + indicesInstance[4] = c; + indicesInstance[5] = d; + + Arrays.sort(indicesInstance); + final int index1D = calculateSetIndex(indicesInstance); + permutations[index1D] = true; + // System.out.println(Arrays.toString(indicesInstance)); + // System.out.println(set1); + // System.out.println(index1D); + // System.out.println("----"); + } + } + } + } + } + } else if (setFormat == 4) { + // [2][2][0] + + final int[] missing = new int[]{0, 0}; + for (Set set1 : inputSets1) { + for (Set set2 : inputSets2) { + final int[] indices = ArrayUtils.addAll(ArrayUtils.addAll(set1.getIndices(), set2.getIndices()), missing); + for (int a = 0; a < 13; a++) { + for (int b = 0; b < 13; b++) { + final int[] indicesInstance = ArrayUtils.clone(indices); + indicesInstance[4] = a; + indicesInstance[5] = b; + + Arrays.sort(indicesInstance); + final int index1D = calculateSetIndex(indicesInstance); + permutations[index1D] = true; + // System.out.println(Arrays.toString(indicesInstance)); + // System.out.println(set1); + // System.out.println(set2); + // System.out.println(index1D); + // System.out.println("----"); + } + } + } + } + } else if (setFormat == 5) { + // [2][2][2] + + for (Set set1 : inputSets1) { + for (Set set2 : inputSets2) { + for (Set set3 : inputSets3) { + final int[] indices = ArrayUtils.addAll(ArrayUtils.addAll(set1.getIndices(), set2.getIndices()), set3.getIndices()); + Arrays.sort(indices); + final int index1D = calculateSetIndex(indices); + permutations[index1D] = true; + // System.out.println(Arrays.toString(indices)); + // System.out.println(set1); + // System.out.println(set2); + // System.out.println(set3); + // System.out.println(index1D); + // System.out.println("----"); + } + } + } + } else { + throw new RuntimeException("Invalid Set Format " + request.getSetFormat()); + } + + request.setBoolArr(permutations); + } +} diff --git a/backend/src/com/fribbels/handler/RequestHandler.java b/backend/src/com/fribbels/handler/RequestHandler.java new file mode 100644 index 00000000..8506800e --- /dev/null +++ b/backend/src/com/fribbels/handler/RequestHandler.java @@ -0,0 +1,82 @@ +package com.fribbels.handler; + +import com.fribbels.model.Request; +import com.fribbels.response.Response; +import com.google.common.base.Charsets; +import com.google.common.io.Files; +import com.google.gson.Gson; +import com.sun.net.httpserver.HttpExchange; +import org.apache.commons.io.IOUtils; + +import java.io.File; +import java.io.IOException; +import java.io.OutputStream; +import java.nio.charset.StandardCharsets; + +public class RequestHandler { + + private static final Gson GSON = new Gson(); + + private static final Gson gson = new Gson(); +// private static final OptimizationRequestHandler optimizationRequestHandler = new OptimizationRequestHandler(); + + public void handleRequest(final String filename) throws IOException { + try { + System.out.println("handleRequest"); + final String data = readFile(filename); + final Request request = gson.fromJson(data, Request.class); + + final String response = handleSpecificRequest(request, data); +// writeFile(response); + } catch (final IOException e) { + writeFile(e.toString()); + } + + System.out.println("DONE"); + } + + private String handleSpecificRequest(final Request request, final String data) { + System.out.println("handleSpecificRequest"); + final String requestType = request.getRequestType(); + + if ("OptimizationRequest".equals(requestType)) { +// return optimizationRequestHandler.handleRequest(data); + } + + throw new UnsupportedOperationException(requestType); + } + + private String readFile(final String filename) throws IOException { + final File requestFile = new File(filename); + final String requestString = Files.toString(requestFile, Charsets.UTF_8); + + return requestString; + } + + private void writeFile(final String data) throws IOException { + final File responseFile = new File("response.txt"); + Files.write(data, responseFile, Charsets.UTF_8); + } + + //////////////////////////////////////////////////// + + protected void sendResponse(final HttpExchange exchange, final String response) throws IOException { + final OutputStream outputStream = exchange.getResponseBody(); + exchange.sendResponseHeaders(200, response.length()); + outputStream.write(response.getBytes()); + outputStream.flush(); + outputStream.close(); + } + + protected T parseRequest(final HttpExchange exchange, final Class type) throws IOException { + final String body = IOUtils.toString(exchange.getRequestBody(), StandardCharsets.UTF_8); + System.out.println(body); + final T request = GSON.fromJson(body, type); + + return request; + } + + protected String toJson(final Response response) { + return GSON.toJson(response); + } +} diff --git a/backend/src/com/fribbels/handler/SystemRequestHandler.java b/backend/src/com/fribbels/handler/SystemRequestHandler.java new file mode 100644 index 00000000..ed90f06e --- /dev/null +++ b/backend/src/com/fribbels/handler/SystemRequestHandler.java @@ -0,0 +1,19 @@ +package com.fribbels.handler; + +import com.fribbels.Main; +import com.sun.net.httpserver.HttpExchange; +import com.sun.net.httpserver.HttpHandler; +import org.apache.commons.io.IOUtils; + +import java.io.IOException; +import java.io.OutputStream; + +public class SystemRequestHandler extends RequestHandler implements HttpHandler { + + @Override + public void handle(final HttpExchange exchange) throws IOException { + Main.interrupt = true; + System.out.println("INTERRUPT MAIN"); + sendResponse(exchange, ""); + } +} diff --git a/backend/src/com/fribbels/model/AugmentedStats.java b/backend/src/com/fribbels/model/AugmentedStats.java new file mode 100644 index 00000000..9ab1039d --- /dev/null +++ b/backend/src/com/fribbels/model/AugmentedStats.java @@ -0,0 +1,27 @@ +package com.fribbels.model; + +import com.fribbels.enums.StatType; +import com.google.gson.annotations.SerializedName; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.ToString; + +@Getter +@ToString +@AllArgsConstructor +public class AugmentedStats { + + @SerializedName("Attack") private int attack; + @SerializedName("AttackPercent") private int attackPercent; + @SerializedName("CriticalHitChancePercent") private int critRate; + @SerializedName("CriticalHitDamagePercent") private int critDamage; + @SerializedName("Defense") private int defense; + @SerializedName("DefensePercent") private int defensePercent; + @SerializedName("EffectResistancePercent") private int effectResistance; + @SerializedName("EffectivenessPercent") private int effectiveness; + @SerializedName("Health") private int health; + @SerializedName("HealthPercent") private int healthPercent; + @SerializedName("Speed") private int speed; + private StatType mainType; + private int mainValue; +} diff --git a/backend/src/com/fribbels/model/Hero.java b/backend/src/com/fribbels/model/Hero.java new file mode 100644 index 00000000..42149ae7 --- /dev/null +++ b/backend/src/com/fribbels/model/Hero.java @@ -0,0 +1,114 @@ +package com.fribbels.model; + +import com.fribbels.enums.Gear; +import com.fribbels.request.BonusStatsRequest; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Getter; +import lombok.Setter; +import lombok.ToString; +import org.apache.commons.lang3.StringUtils; + +import java.util.HashMap; +import java.util.Map; + +@Getter +@Setter +@Builder +@AllArgsConstructor +@ToString +public class Hero { + + private int atk; + private int hp; + private int def; + private int cr; + private int cd; + private int eff; + private int res; + private int dac; + private int spd; + + private int ehp; + private int hpps; + private int ehpps; + private int dmg; + private int dmgps; + private int mcdmg; + private int mcdmgps; + + private String id; + private String name; + private int rarity; + private String attribute; + private String role; + + private int bonusAtk; + private int bonusDef; + private int bonusHp; + private int bonusSpeed; + private int bonusCr; + private int bonusCd; + private int bonusEff; + private int bonusRes; + + private Map equipment; + + public Item switchItem(final Item item) { + final Gear gear = item.getGear(); + final Item previousItem = addToEquipment(gear, item); + + if (previousItem != null) { + return previousItem; + } + + return null; + } + + private Item addToEquipment(final Gear gear, final Item item) { + if (equipment == null) { + equipment = new HashMap<>(); + } + + return equipment.put(gear, item); + } + + public void setBonusStats(final BonusStatsRequest bonusStats) { + this.bonusAtk = bonusStats.getAtk(); + this.bonusDef = bonusStats.getDef(); + this.bonusHp = bonusStats.getHp(); + this.bonusSpeed = bonusStats.getSpeed(); + this.bonusCr = bonusStats.getCr(); + this.bonusCd = bonusStats.getCd(); + this.bonusEff = bonusStats.getEff(); + this.bonusRes = bonusStats.getRes(); + } + + public Map getEquipment() { + if (equipment == null) { + equipment = new HashMap<>(); + } + + return equipment; + } + + public void setStats(final HeroStats heroStats) { + this.atk = heroStats.getAtk(); + this.hp = heroStats.getHp(); + this.def = heroStats.getDef(); + this.cr = heroStats.getCr(); + this.cd = heroStats.getCd(); + this.eff = heroStats.getEff(); + this.res = heroStats.getRes(); + this.dac = heroStats.getDac(); + this.spd = heroStats.getSpd(); + + this.ehp = heroStats.getEhp(); + this.ehpps = heroStats.getEhpps(); + this.hpps = heroStats.getHpps(); + this.dmg = heroStats.getDmg(); + this.dmgps = heroStats.getDmgps(); + this.mcdmg = heroStats.getMcdmg(); + this.mcdmgps = heroStats.getMcdmgps(); + } +} diff --git a/backend/src/com/fribbels/model/HeroStats.java b/backend/src/com/fribbels/model/HeroStats.java new file mode 100644 index 00000000..381fb53a --- /dev/null +++ b/backend/src/com/fribbels/model/HeroStats.java @@ -0,0 +1,50 @@ +package com.fribbels.model; + +import com.fribbels.enums.Gear; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; +import lombok.ToString; + +import java.util.List; +import java.util.Map; + +@Getter +@Setter +@Builder +@NoArgsConstructor +@AllArgsConstructor +@ToString +public class HeroStats { + +// private String name; + + private int atk; + private int hp; + private int def; + private int cr; + private int cd; + private int eff; + private int res; + private int dac; + private int spd; + private int cp; + + private int ehp; + private int hpps; + private int ehpps; + private int dmg; + private int dmgps; + private int mcdmg; + private int mcdmgps; + + private int[] sets; + + private String id; + private String name; + private List items; + + private Map equipment; +} diff --git a/backend/src/com/fribbels/model/Item.java b/backend/src/com/fribbels/model/Item.java new file mode 100644 index 00000000..6035d24f --- /dev/null +++ b/backend/src/com/fribbels/model/Item.java @@ -0,0 +1,43 @@ +package com.fribbels.model; + +import com.fribbels.enums.Gear; +import com.fribbels.enums.Rank; +import com.fribbels.enums.Set; +import com.google.gson.Gson; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.Setter; + +import java.util.List; + +@Getter +@Setter +@AllArgsConstructor +public class Item { + + private Gear gear; + private Rank rank; + private Set set; + + private Integer enhance; + private Integer level; + + private Stat main; + private List substats; + + private String name; + + private AugmentedStats augmentedStats; + + private String id; + + private String equippedById; + private String equippedByName; + + private boolean locked; + private int wss; + + public String toString() { + return new Gson().toJson(this); + } +} diff --git a/backend/src/com/fribbels/model/MiniOptimizationResponse.java b/backend/src/com/fribbels/model/MiniOptimizationResponse.java new file mode 100644 index 00000000..ec127e63 --- /dev/null +++ b/backend/src/com/fribbels/model/MiniOptimizationResponse.java @@ -0,0 +1,18 @@ +package com.fribbels.model; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Getter; +import lombok.ToString; + +import java.util.List; + +@Getter +@Builder +@ToString +@AllArgsConstructor +public class MiniOptimizationResponse { + + private List stats; + private List ids; +} diff --git a/backend/src/com/fribbels/model/Request.java b/backend/src/com/fribbels/model/Request.java new file mode 100644 index 00000000..b7b602f4 --- /dev/null +++ b/backend/src/com/fribbels/model/Request.java @@ -0,0 +1,12 @@ +package com.fribbels.model; + +import lombok.Builder; +import lombok.Getter; +import lombok.ToString; + +@Getter +@ToString +public class Request { + + private String requestType; +} diff --git a/backend/src/com/fribbels/model/Stat.java b/backend/src/com/fribbels/model/Stat.java new file mode 100644 index 00000000..f7635324 --- /dev/null +++ b/backend/src/com/fribbels/model/Stat.java @@ -0,0 +1,16 @@ +package com.fribbels.model; + +import com.fribbels.enums.StatType; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.ToString; + +@Getter +@ToString +@AllArgsConstructor +public class Stat { + + private StatType type; + + private Integer value; +} diff --git a/backend/src/com/fribbels/ocr/OcrEngine.java b/backend/src/com/fribbels/ocr/OcrEngine.java new file mode 100644 index 00000000..59f1f0a8 --- /dev/null +++ b/backend/src/com/fribbels/ocr/OcrEngine.java @@ -0,0 +1,9 @@ +package com.fribbels.ocr; + +public class OcrEngine { + + public String detect() { + + return ""; + } +} diff --git a/backend/src/com/fribbels/request/BaseStatsRequest.java b/backend/src/com/fribbels/request/BaseStatsRequest.java new file mode 100644 index 00000000..8d0d7d91 --- /dev/null +++ b/backend/src/com/fribbels/request/BaseStatsRequest.java @@ -0,0 +1,19 @@ +package com.fribbels.request; + +import com.fribbels.model.HeroStats; +import com.fribbels.model.Request; +import lombok.Builder; +import lombok.Getter; +import lombok.Setter; +import lombok.ToString; + +import java.util.Map; + +@Setter +@Getter +@Builder +@ToString +public class BaseStatsRequest extends Request { + + final Map baseStatsByName; +} diff --git a/backend/src/com/fribbels/request/BonusStatsRequest.java b/backend/src/com/fribbels/request/BonusStatsRequest.java new file mode 100644 index 00000000..fcb104e7 --- /dev/null +++ b/backend/src/com/fribbels/request/BonusStatsRequest.java @@ -0,0 +1,25 @@ +package com.fribbels.request; + +import com.fribbels.model.Request; +import lombok.Builder; +import lombok.Getter; +import lombok.Setter; +import lombok.ToString; + +@Setter +@Getter +@Builder +@ToString +public class BonusStatsRequest extends Request { + + private int atk; + private int def; + private int hp; + private int speed; + private int cr; + private int cd; + private int eff; + private int res; + private String heroId; +} + diff --git a/backend/src/com/fribbels/request/EquipItemsOnHeroRequest.java b/backend/src/com/fribbels/request/EquipItemsOnHeroRequest.java new file mode 100644 index 00000000..0918682f --- /dev/null +++ b/backend/src/com/fribbels/request/EquipItemsOnHeroRequest.java @@ -0,0 +1,19 @@ +package com.fribbels.request; + +import com.fribbels.model.Request; +import lombok.Builder; +import lombok.Getter; +import lombok.Setter; +import lombok.ToString; + +import java.util.List; + +@Setter +@Getter +@Builder +@ToString +public class EquipItemsOnHeroRequest extends Request { + + final String heroId; + final List itemIds; +} diff --git a/backend/src/com/fribbels/request/GetResultRowsRequest.java b/backend/src/com/fribbels/request/GetResultRowsRequest.java new file mode 100644 index 00000000..5c5079fd --- /dev/null +++ b/backend/src/com/fribbels/request/GetResultRowsRequest.java @@ -0,0 +1,22 @@ +package com.fribbels.request; + +import com.fribbels.enums.OptimizationColumn; +import com.fribbels.enums.SortOrder; +import com.fribbels.model.Request; +import lombok.Builder; +import lombok.Getter; +import lombok.Setter; +import lombok.ToString; + +@Setter +@Getter +@Builder +@ToString +public class GetResultRowsRequest extends Request { + + private int startRow; + private int endRow; + private OptimizationColumn sortColumn; + private SortOrder sortOrder; + private OptimizationRequest optimizationRequest; +} diff --git a/backend/src/com/fribbels/request/HeroesRequest.java b/backend/src/com/fribbels/request/HeroesRequest.java new file mode 100644 index 00000000..a9476a20 --- /dev/null +++ b/backend/src/com/fribbels/request/HeroesRequest.java @@ -0,0 +1,19 @@ +package com.fribbels.request; + +import com.fribbels.model.Hero; +import com.fribbels.model.Request; +import lombok.Builder; +import lombok.Getter; +import lombok.Setter; +import lombok.ToString; + +import java.util.List; + +@Setter +@Getter +@Builder +@ToString +public class HeroesRequest extends Request { + + private List heroes; +} diff --git a/backend/src/com/fribbels/request/IdRequest.java b/backend/src/com/fribbels/request/IdRequest.java new file mode 100644 index 00000000..6c11091c --- /dev/null +++ b/backend/src/com/fribbels/request/IdRequest.java @@ -0,0 +1,16 @@ +package com.fribbels.request; + +import com.fribbels.model.Request; +import lombok.Builder; +import lombok.Getter; +import lombok.Setter; +import lombok.ToString; + +@Setter +@Getter +@Builder +@ToString +public class IdRequest extends Request { + + private String id; +} diff --git a/backend/src/com/fribbels/request/IdsRequest.java b/backend/src/com/fribbels/request/IdsRequest.java new file mode 100644 index 00000000..bd6d59da --- /dev/null +++ b/backend/src/com/fribbels/request/IdsRequest.java @@ -0,0 +1,18 @@ +package com.fribbels.request; + +import com.fribbels.model.Request; +import lombok.Builder; +import lombok.Getter; +import lombok.Setter; +import lombok.ToString; + +import java.util.List; + +@Setter +@Getter +@Builder +@ToString +public class IdsRequest extends Request { + + private List ids; +} diff --git a/backend/src/com/fribbels/request/ItemsRequest.java b/backend/src/com/fribbels/request/ItemsRequest.java new file mode 100644 index 00000000..3bb774e2 --- /dev/null +++ b/backend/src/com/fribbels/request/ItemsRequest.java @@ -0,0 +1,19 @@ +package com.fribbels.request; + +import com.fribbels.model.Item; +import com.fribbels.model.Request; +import lombok.Builder; +import lombok.Getter; +import lombok.Setter; +import lombok.ToString; + +import java.util.List; + +@Setter +@Getter +@Builder +@ToString +public class ItemsRequest extends Request { + + private List items; +} diff --git a/backend/src/com/fribbels/request/Ocr2Request.java b/backend/src/com/fribbels/request/Ocr2Request.java new file mode 100644 index 00000000..0e168a16 --- /dev/null +++ b/backend/src/com/fribbels/request/Ocr2Request.java @@ -0,0 +1,18 @@ +package com.fribbels.request; + +import com.fribbels.enums.Set; +import com.fribbels.model.Request; +import lombok.Builder; +import lombok.Getter; +import lombok.Setter; +import lombok.ToString; + +@Setter +@Getter +@Builder +@ToString +public class Ocr2Request extends Request { + + private String id; + private Boolean shifted; +} diff --git a/backend/src/com/fribbels/request/OptimizationRequest.java b/backend/src/com/fribbels/request/OptimizationRequest.java new file mode 100644 index 00000000..f80a60f7 --- /dev/null +++ b/backend/src/com/fribbels/request/OptimizationRequest.java @@ -0,0 +1,111 @@ +package com.fribbels.request; + +import com.fribbels.enums.Set; +import com.fribbels.model.Hero; +import com.fribbels.model.Item; +import com.fribbels.model.Request; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; +import lombok.ToString; + +import java.util.List; + +@Setter +@Getter +@Builder +@ToString +@NoArgsConstructor +@AllArgsConstructor +public class OptimizationRequest extends Request { + + private Hero hero; + private List items; + + private List inputSetsOne; + private List inputSetsTwo; + private List inputSetsThree; + + private Boolean inputAllowLockedItems; + private Boolean inputAllowEquippedItems; + private Boolean inputKeepCurrentItems; + private Boolean inputAllowBrokenSets; + + private int atk; + private int hp; + private int def; + private int cr; + private int cd; + private int eff; + private int res; + private int spd; + private int dac; + + private int inputAtkMinLimit; + private int inputAtkMaxLimit = Integer.MAX_VALUE; + private int inputHpMinLimit; + private int inputHpMaxLimit = Integer.MAX_VALUE; + private int inputDefMinLimit; + private int inputDefMaxLimit = Integer.MAX_VALUE; + private int inputSpdMinLimit; + private int inputSpdMaxLimit = Integer.MAX_VALUE; + private int inputCrMinLimit; + private int inputCrMaxLimit = Integer.MAX_VALUE; + private int inputCdMinLimit; + private int inputCdMaxLimit = Integer.MAX_VALUE; + private int inputEffMinLimit; + private int inputEffMaxLimit = Integer.MAX_VALUE; + private int inputResMinLimit; + private int inputResMaxLimit = Integer.MAX_VALUE; + private int inputMinHppsLimit; + private int inputMaxHppsLimit = Integer.MAX_VALUE; + private int inputMinEhpLimit; + private int inputMaxEhpLimit = Integer.MAX_VALUE; + private int inputMinEhppsLimit; + private int inputMaxEhppsLimit = Integer.MAX_VALUE; + private int inputMinDmgLimit; + private int inputMaxDmgLimit = Integer.MAX_VALUE; + private int inputMinDmgpsLimit; + private int inputMaxDmgpsLimit = Integer.MAX_VALUE; + private int inputMinMcdmgLimit; + private int inputMaxMcdmgLimit = Integer.MAX_VALUE; + private int inputMinMcdmgpsLimit; + private int inputMaxMcdmgpsLimit = Integer.MAX_VALUE; + + private Integer inputAtkMinForce; + private Integer inputAtkMaxForce; + private Integer inputAtkPercentMinForce; + private Integer inputAtkPercentMaxForce; + private Integer inputSpdMinForce; + private Integer inputSpdMaxForce; + private Integer inputCrMinForce; + private Integer inputCrMaxForce; + private Integer inputCdMinForce; + private Integer inputCdMaxForce; + private Integer inputHpMinForce; + private Integer inputHpMaxForce; + private Integer inputHpPercentMinForce; + private Integer inputHpPercentMaxForce; + private Integer inputDefMinForce; + private Integer inputDefMaxForce; + private Integer inputDefPercentMinForce; + private Integer inputDefPercentMaxForce; + private Integer inputEffMinForce; + private Integer inputEffMaxForce; + private Integer inputResMinForce; + private Integer inputResMaxForce; + + private String inputNecklaceStat; + private String inputRingStat; + private String inputBootsStat; + + // calculated fields + private int[][] possibleSetCombinations; + private boolean[] boolArr; + + private int setFormat; + private int bonusAtk; + private int bonusHp; +} diff --git a/backend/src/com/fribbels/response/GetAllHeroesResponse.java b/backend/src/com/fribbels/response/GetAllHeroesResponse.java new file mode 100644 index 00000000..3f44c0a4 --- /dev/null +++ b/backend/src/com/fribbels/response/GetAllHeroesResponse.java @@ -0,0 +1,18 @@ +package com.fribbels.response; + +import com.fribbels.model.Hero; +import lombok.Builder; +import lombok.Getter; +import lombok.Setter; +import lombok.ToString; + +import java.util.List; + +@Setter +@Getter +@Builder +@ToString +public class GetAllHeroesResponse extends Response { + + private final List heroes; +} diff --git a/backend/src/com/fribbels/response/GetAllItemsResponse.java b/backend/src/com/fribbels/response/GetAllItemsResponse.java new file mode 100644 index 00000000..1af14fcf --- /dev/null +++ b/backend/src/com/fribbels/response/GetAllItemsResponse.java @@ -0,0 +1,18 @@ +package com.fribbels.response; + +import com.fribbels.model.Item; +import lombok.Builder; +import lombok.Getter; +import lombok.Setter; +import lombok.ToString; + +import java.util.List; + +@Setter +@Getter +@Builder +@ToString +public class GetAllItemsResponse extends Response { + + private final List items; +} diff --git a/backend/src/com/fribbels/response/GetHeroByIdResponse.java b/backend/src/com/fribbels/response/GetHeroByIdResponse.java new file mode 100644 index 00000000..433a6dc1 --- /dev/null +++ b/backend/src/com/fribbels/response/GetHeroByIdResponse.java @@ -0,0 +1,17 @@ +package com.fribbels.response; + +import com.fribbels.model.Hero; +import com.fribbels.model.HeroStats; +import lombok.Builder; +import lombok.Getter; +import lombok.Setter; +import lombok.ToString; + +@Setter +@Getter +@Builder +@ToString +public class GetHeroByIdResponse extends Response { + + private Hero hero; +} diff --git a/backend/src/com/fribbels/response/GetItemByIdResponse.java b/backend/src/com/fribbels/response/GetItemByIdResponse.java new file mode 100644 index 00000000..118d5bc5 --- /dev/null +++ b/backend/src/com/fribbels/response/GetItemByIdResponse.java @@ -0,0 +1,16 @@ +package com.fribbels.response; + +import com.fribbels.model.Item; +import lombok.Builder; +import lombok.Getter; +import lombok.Setter; +import lombok.ToString; + +@Setter +@Getter +@Builder +@ToString +public class GetItemByIdResponse extends Response { + + private Item item; +} diff --git a/backend/src/com/fribbels/response/GetResultRowsResponse.java b/backend/src/com/fribbels/response/GetResultRowsResponse.java new file mode 100644 index 00000000..0b983d5c --- /dev/null +++ b/backend/src/com/fribbels/response/GetResultRowsResponse.java @@ -0,0 +1,17 @@ +package com.fribbels.response; + +import com.fribbels.model.HeroStats; +import lombok.Builder; +import lombok.Getter; +import lombok.Setter; +import lombok.ToString; + +@Setter +@Getter +@Builder +@ToString +public class GetResultRowsResponse extends Response { + + private HeroStats[] heroStats; + private long maximum; +} diff --git a/backend/src/com/fribbels/response/OcrResponse.java b/backend/src/com/fribbels/response/OcrResponse.java new file mode 100644 index 00000000..2390fbef --- /dev/null +++ b/backend/src/com/fribbels/response/OcrResponse.java @@ -0,0 +1,22 @@ +package com.fribbels.response; + +import lombok.Builder; +import lombok.Getter; +import lombok.Setter; +import lombok.ToString; + +@Setter +@Getter +@Builder +@ToString +public class OcrResponse extends Response { + + private String title; + private String enhance; + private String level; + private String main; + private String substats; + private String substatsText; + private String substatsNumbers; + private String set; +} diff --git a/backend/src/com/fribbels/response/OptimizationResponse.java b/backend/src/com/fribbels/response/OptimizationResponse.java new file mode 100644 index 00000000..6409dab4 --- /dev/null +++ b/backend/src/com/fribbels/response/OptimizationResponse.java @@ -0,0 +1,15 @@ +package com.fribbels.response; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Getter; +import lombok.ToString; + +@Getter +@Builder +@ToString +@AllArgsConstructor +public class OptimizationResponse extends Response { + + private long count; +} diff --git a/backend/src/com/fribbels/response/Response.java b/backend/src/com/fribbels/response/Response.java new file mode 100644 index 00000000..6b8cfbb8 --- /dev/null +++ b/backend/src/com/fribbels/response/Response.java @@ -0,0 +1,5 @@ +package com.fribbels.response; + +public class Response { + +} diff --git a/backend/tst/com/fribbels/DebugTest.java b/backend/tst/com/fribbels/DebugTest.java new file mode 100644 index 00000000..a529241d --- /dev/null +++ b/backend/tst/com/fribbels/DebugTest.java @@ -0,0 +1,31 @@ +package com.fribbels; + +import com.fribbels.model.Item; +import com.google.gson.Gson; +import org.junit.jupiter.api.Test; + +import java.io.FileNotFoundException; +import java.io.FileReader; +import java.io.IOException; +import java.io.Reader; + +public class DebugTest { + + @Test + public void test() { + Gson gson = new Gson(); + + try (Reader reader = new FileReader("C:\\Users\\ivanc\\IdeaProjects\\Gear\\item.json")) { + + // Convert JSON File to Java Object + Item item = gson.fromJson(reader, Item.class); + + // print staff object + System.out.println(item); + + } catch (IOException e) { + e.printStackTrace(); + } + + } +} diff --git a/backend/tst/com/fribbels/core/OptimizationRequestHandlerTest.java b/backend/tst/com/fribbels/core/OptimizationRequestHandlerTest.java new file mode 100644 index 00000000..ee941873 --- /dev/null +++ b/backend/tst/com/fribbels/core/OptimizationRequestHandlerTest.java @@ -0,0 +1,208 @@ +package com.fribbels.core; + +import com.fribbels.enums.Set; +import com.fribbels.handler.OptimizationRequestHandler; +import com.fribbels.model.HeroStats; +import com.fribbels.request.OptimizationRequest; +import com.google.gson.Gson; +import org.apache.commons.lang3.StringUtils; +import org.bytedeco.javacpp.BytePointer; +import org.bytedeco.leptonica.PIX; +import org.bytedeco.tesseract.TessBaseAPI; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Comparator; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +import static org.bytedeco.leptonica.global.lept.pixDestroy; +import static org.bytedeco.leptonica.global.lept.pixRead; + +public class OptimizationRequestHandlerTest { + + private OptimizationRequestHandler handler; + // Basic +// private static final String REQUEST_STRING = "{\"base\":{\"atk\":576,\"hp\":5700,\"def\":743,\"cr\":15,\"cd\":150,\"eff\":0,\"res\":0,\"spd\":88,\"dac\":5},\"requestType\":\"OptimizationRequest\",\"extraField\":\"asdf\",\"items\":[{\"gear\":\"Weapon\",\"rank\":\"Normal\",\"set\":\"CriticalSet\",\"level\":30,\"enhance\":0,\"main\":{\"type\":\"Attack\",\"value\":40},\"substats\":[],\"name\":\"Rapier\",\"augmentedStats\":{\"mainType\":\"Attack\",\"mainValue\":40},\"id\":0},{\"gear\":\"Weapon\",\"rank\":\"Good\",\"set\":\"SpeedSet\",\"level\":44,\"enhance\":0,\"main\":{\"type\":\"Attack\",\"value\":57},\"substats\":[{\"type\":\"Speed\",\"value\":2}],\"name\":\"ImperialLongsword\",\"augmentedStats\":{\"mainType\":\"Attack\",\"mainValue\":57,\"Speed\":2},\"id\":1},{\"gear\":\"Weapon\",\"rank\":\"Rare\",\"set\":\"DestructionSet\",\"level\":85,\"enhance\":0,\"main\":{\"type\":\"Attack\",\"value\":100},\"substats\":[{\"type\":\"EffectResistancePercent\",\"value\":4},{\"type\":\"Health\",\"value\":148}],\"name\":\"HellishEssenceOrb\",\"augmentedStats\":{\"mainType\":\"Attack\",\"mainValue\":100,\"EffectResistancePercent\":4,\"Health\":148},\"id\":2},{\"gear\":\"Weapon\",\"rank\":\"Rare\",\"set\":\"SpeedSet\",\"level\":85,\"enhance\":3,\"main\":{\"type\":\"Attack\",\"value\":160},\"substats\":[{\"type\":\"AttackPercent\",\"value\":4},{\"type\":\"Speed\",\"value\":4}],\"name\":\"AbyssDrakeBonesword\",\"augmentedStats\":{\"mainType\":\"Attack\",\"mainValue\":160,\"AttackPercent\":4,\"Speed\":4},\"id\":3},{\"gear\":\"Weapon\",\"rank\":\"Heroic\",\"set\":\"SpeedSet\",\"level\":85,\"enhance\":3,\"main\":{\"type\":\"Attack\",\"value\":160},\"substats\":[{\"type\":\"Health\",\"value\":159},{\"type\":\"CriticalHitDamagePercent\",\"value\":13},{\"type\":\"Speed\",\"value\":4}],\"name\":\"AbyssDrakeBonesword\",\"augmentedStats\":{\"mainType\":\"Attack\",\"mainValue\":160,\"Health\":159,\"CriticalHitDamagePercent\":13,\"Speed\":4},\"id\":4},{\"gear\":\"Weapon\",\"rank\":\"Rare\",\"set\":\"RageSet\",\"level\":85,\"enhance\":6,\"main\":{\"type\":\"Attack\",\"value\":220},\"substats\":[{\"type\":\"CriticalHitDamagePercent\",\"value\":5},{\"type\":\"Speed\",\"value\":10}],\"name\":\"IndomitableSpiderMace\",\"augmentedStats\":{\"mainType\":\"Attack\",\"mainValue\":220,\"CriticalHitDamagePercent\":5,\"Speed\":10},\"id\":5},{\"gear\":\"Weapon\",\"rank\":\"Heroic\",\"set\":\"HitSet\",\"level\":85,\"enhance\":7,\"main\":{\"type\":\"Attack\",\"value\":240},\"substats\":[{\"type\":\"Speed\",\"value\":8},{\"type\":\"EffectResistancePercent\",\"value\":14},{\"type\":\"CriticalHitChancePercent\",\"value\":4}],\"name\":\"AbyssDrakeBonesword\",\"augmentedStats\":{\"mainType\":\"Attack\",\"mainValue\":240,\"Speed\":8,\"EffectResistancePercent\":14,\"CriticalHitChancePercent\":4},\"id\":6},{\"gear\":\"Weapon\",\"rank\":\"Heroic\",\"set\":\"UnitySet\",\"level\":85,\"enhance\":9,\"main\":{\"type\":\"Attack\",\"value\":280},\"substats\":[{\"type\":\"AttackPercent\",\"value\":11},{\"type\":\"Speed\",\"value\":8},{\"type\":\"EffectivenessPercent\",\"value\":12}],\"name\":\"IndomitableSpiderMace\",\"augmentedStats\":{\"mainType\":\"Attack\",\"mainValue\":280,\"AttackPercent\":11,\"Speed\":8,\"EffectivenessPercent\":12},\"id\":7},{\"gear\":\"Weapon\",\"rank\":\"Heroic\",\"set\":\"HitSet\",\"level\":85,\"enhance\":10,\"main\":{\"type\":\"Attack\",\"value\":300},\"substats\":[{\"type\":\"CriticalHitChancePercent\",\"value\":3},{\"type\":\"Speed\",\"value\":9},{\"type\":\"CriticalHitDamagePercent\",\"value\":14}],\"name\":\"AbyssDrakeBonesword\",\"augmentedStats\":{\"mainType\":\"Attack\",\"mainValue\":300,\"CriticalHitChancePercent\":3,\"Speed\":9,\"CriticalHitDamagePercent\":14},\"id\":8},{\"gear\":\"Weapon\",\"rank\":\"Heroic\",\"set\":\"SpeedSet\",\"level\":85,\"enhance\":12,\"main\":{\"type\":\"Attack\",\"value\":360},\"substats\":[{\"type\":\"Speed\",\"value\":10},{\"type\":\"CriticalHitChancePercent\",\"value\":8},{\"type\":\"Health\",\"value\":187},{\"type\":\"EffectResistancePercent\",\"value\":7}],\"name\":\"AbyssDrakeBonesword\",\"augmentedStats\":{\"mainType\":\"Attack\",\"mainValue\":360,\"Speed\":10,\"CriticalHitChancePercent\":8,\"Health\":187,\"EffectResistancePercent\":7},\"id\":9},{\"gear\":\"Weapon\",\"rank\":\"Heroic\",\"set\":\"SpeedSet\",\"level\":85,\"enhance\":13,\"main\":{\"type\":\"Attack\",\"value\":390},\"substats\":[{\"type\":\"AttackPercent\",\"value\":15},{\"type\":\"HealthPercent\",\"value\":10},{\"type\":\"Speed\",\"value\":2},{\"type\":\"Health\",\"value\":155}],\"name\":\"AbyssDrakeBonesword\",\"augmentedStats\":{\"mainType\":\"Attack\",\"mainValue\":390,\"AttackPercent\":15,\"HealthPercent\":10,\"Speed\":2,\"Health\":155},\"id\":10},{\"gear\":\"Helmet\",\"rank\":\"Epic\",\"set\":\"ImmunitySet\",\"level\":67,\"enhance\":5,\"main\":{\"type\":\"Health\",\"value\":918},\"substats\":[{\"type\":\"HealthPercent\",\"value\":6},{\"type\":\"CriticalHitChancePercent\",\"value\":4},{\"type\":\"Attack\",\"value\":33},{\"type\":\"DefensePercent\",\"value\":5}],\"name\":\"KarkanissDecisionHelm\",\"augmentedStats\":{\"mainType\":\"Health\",\"mainValue\":918,\"HealthPercent\":6,\"CriticalHitChancePercent\":4,\"Attack\":33,\"DefensePercent\":5},\"id\":11},{\"gear\":\"Armor\",\"rank\":\"Epic\",\"set\":\"CounterSet\",\"level\":85,\"enhance\":13,\"main\":{\"type\":\"Defense\",\"value\":234},\"substats\":[{\"type\":\"EffectivenessPercent\",\"value\":12},{\"type\":\"DefensePercent\",\"value\":14},{\"type\":\"HealthPercent\",\"value\":11},{\"type\":\"CriticalHitDamagePercent\",\"value\":11}],\"name\":\"Corimescent\",\"augmentedStats\":{\"mainType\":\"Defense\",\"mainValue\":234,\"EffectivenessPercent\":12,\"DefensePercent\":14,\"HealthPercent\":11,\"CriticalHitDamagePercent\":11},\"id\":12},{\"gear\":\"Armor\",\"rank\":\"Epic\",\"set\":\"CriticalSet\",\"level\":67,\"enhance\":10,\"main\":{\"type\":\"Defense\",\"value\":150},\"substats\":[{\"type\":\"Speed\",\"value\":2},{\"type\":\"HealthPercent\",\"value\":6},{\"type\":\"DefensePercent\",\"value\":21},{\"type\":\"CriticalHitChancePercent\",\"value\":2}],\"name\":\"ArahakansChestplate\",\"augmentedStats\":{\"mainType\":\"Defense\",\"mainValue\":150,\"Speed\":2,\"HealthPercent\":6,\"DefensePercent\":21,\"CriticalHitChancePercent\":2},\"id\":13},{\"gear\":\"Necklace\",\"rank\":\"Epic\",\"set\":\"SpeedSet\",\"level\":85,\"enhance\":7,\"main\":{\"type\":\"CriticalHitDamagePercent\",\"value\":31},\"substats\":[{\"type\":\"Attack\",\"value\":35},{\"type\":\"EffectResistancePercent\",\"value\":17},{\"type\":\"CriticalHitChancePercent\",\"value\":3},{\"type\":\"Speed\",\"value\":3}],\"name\":\"Corselium\",\"augmentedStats\":{\"mainType\":\"CriticalHitDamagePercent\",\"mainValue\":31,\"Attack\":35,\"EffectResistancePercent\":17,\"CriticalHitChancePercent\":3,\"Speed\":3},\"id\":14},{\"gear\":\"Ring\",\"rank\":\"Epic\",\"set\":\"LifestealSet\",\"level\":57,\"enhance\":13,\"main\":{\"type\":\"AttackPercent\",\"value\":31},\"substats\":[{\"type\":\"HealthPercent\",\"value\":10},{\"type\":\"Speed\",\"value\":2},{\"type\":\"CriticalHitChancePercent\",\"value\":7},{\"type\":\"EffectivenessPercent\",\"value\":15}],\"name\":\"BloodBeastsRing\",\"augmentedStats\":{\"mainType\":\"AttackPercent\",\"mainValue\":31,\"HealthPercent\":10,\"Speed\":2,\"CriticalHitChancePercent\":7,\"EffectivenessPercent\":15},\"id\":15}],\"inputAllowLockedItems\":false,\"inputAllowEquippedItems\":false,\"inputKeepCurrentItems\":false,\"inputNecklaceStat\":\"Cd\",\"inputRingStat\":\"Atk\",\"inputBootsStat\":\"Speed\",\"inputSetOne\":\"Speed\",\"inputSetTwo\":\"HP\",\"inputSetThree\":\"HP\",\"inputAllowBrokenSets\":false,\"atk\":576,\"hp\":5700,\"def\":743,\"cr\":15,\"cd\":150,\"eff\":0,\"res\":0,\"spd\":88,\"dac\":5}"; + // 420 set + private static final String REQUEST_STRING = "{\"base\":{\"atk\":576,\"hp\":5700,\"def\":743,\"cr\":15,\"cd\":150,\"eff\":0,\"res\":0,\"spd\":88,\"dac\":5},\"requestType\":\"OptimizationRequest\",\"extraField\":\"asdf\",\"items\":[{\"gear\":\"Weapon\",\"rank\":\"Heroic\",\"set\":\"HealthSet\",\"level\":85,\"enhance\":15,\"main\":{\"type\":\"Attack\",\"value\":500},\"substats\":[{\"type\":\"EffectivenessPercent\",\"value\":4},{\"type\":\"HealthPercent\",\"value\":27},{\"type\":\"AttackPercent\",\"value\":14},{\"type\":\"Health\",\"value\":178}],\"name\":\"DarkSteelSaber\",\"augmentedStats\":{\"mainType\":\"Attack\",\"mainValue\":500,\"EffectivenessPercent\":4,\"HealthPercent\":27,\"AttackPercent\":14,\"Health\":178},\"id\":0},{\"gear\":\"Weapon\",\"rank\":\"Epic\",\"set\":\"HealthSet\",\"level\":88,\"enhance\":15,\"main\":{\"type\":\"Attack\",\"value\":515},\"substats\":[{\"type\":\"Health\",\"value\":214},{\"type\":\"HealthPercent\",\"value\":25},{\"type\":\"CriticalHitDamagePercent\",\"value\":4},{\"type\":\"Speed\",\"value\":9}],\"name\":\"ArahakansFang\",\"augmentedStats\":{\"mainType\":\"Attack\",\"mainValue\":515,\"Health\":214,\"HealthPercent\":25,\"CriticalHitDamagePercent\":4,\"Speed\":9},\"id\":1},{\"gear\":\"Weapon\",\"rank\":\"Epic\",\"set\":\"RageSet\",\"level\":71,\"enhance\":15,\"main\":{\"type\":\"Attack\",\"value\":440},\"substats\":[{\"type\":\"AttackPercent\",\"value\":10},{\"type\":\"Speed\",\"value\":7},{\"type\":\"CriticalHitChancePercent\",\"value\":7},{\"type\":\"CriticalHitDamagePercent\",\"value\":9}],\"name\":\"ThornVineWhip\",\"augmentedStats\":{\"mainType\":\"Attack\",\"mainValue\":440,\"AttackPercent\":10,\"Speed\":7,\"CriticalHitChancePercent\":7,\"CriticalHitDamagePercent\":9},\"id\":2},{\"gear\":\"Weapon\",\"rank\":\"Epic\",\"set\":\"SpeedSet\",\"level\":85,\"enhance\":15,\"main\":{\"type\":\"Attack\",\"value\":500},\"substats\":[{\"type\":\"CriticalHitDamagePercent\",\"value\":15},{\"type\":\"Speed\",\"value\":6},{\"type\":\"CriticalHitChancePercent\",\"value\":10},{\"type\":\"AttackPercent\",\"value\":7}],\"name\":\"AbyssDrakeBonesword\",\"augmentedStats\":{\"mainType\":\"Attack\",\"mainValue\":500,\"CriticalHitDamagePercent\":15,\"Speed\":6,\"CriticalHitChancePercent\":10,\"AttackPercent\":7},\"id\":3},{\"gear\":\"Weapon\",\"rank\":\"Epic\",\"set\":\"CriticalSet\",\"level\":70,\"enhance\":15,\"main\":{\"type\":\"Attack\",\"value\":440},\"substats\":[{\"type\":\"CriticalHitChancePercent\",\"value\":6},{\"type\":\"CriticalHitDamagePercent\",\"value\":11},{\"type\":\"EffectResistancePercent\",\"value\":12},{\"type\":\"AttackPercent\",\"value\":20}],\"name\":\"ManaDrakeBonesword\",\"augmentedStats\":{\"mainType\":\"Attack\",\"mainValue\":440,\"CriticalHitChancePercent\":6,\"CriticalHitDamagePercent\":11,\"EffectResistancePercent\":12,\"AttackPercent\":20},\"id\":4},{\"gear\":\"Helmet\",\"rank\":\"Epic\",\"set\":\"SpeedSet\",\"level\":71,\"enhance\":15,\"main\":{\"type\":\"Health\",\"value\":2360},\"substats\":[{\"type\":\"HealthPercent\",\"value\":12},{\"type\":\"AttackPercent\",\"value\":11},{\"type\":\"DefensePercent\",\"value\":18},{\"type\":\"Speed\",\"value\":3}],\"name\":\"RoseCoronet\",\"augmentedStats\":{\"mainType\":\"Health\",\"mainValue\":2360,\"HealthPercent\":12,\"AttackPercent\":11,\"DefensePercent\":18,\"Speed\":3},\"id\":5},{\"gear\":\"Helmet\",\"rank\":\"Epic\",\"set\":\"SpeedSet\",\"level\":85,\"enhance\":15,\"main\":{\"type\":\"Health\",\"value\":2700},\"substats\":[{\"type\":\"CriticalHitChancePercent\",\"value\":6},{\"type\":\"AttackPercent\",\"value\":4},{\"type\":\"EffectivenessPercent\",\"value\":9},{\"type\":\"HealthPercent\",\"value\":26}],\"name\":\"AbyssDrakeMask\",\"augmentedStats\":{\"mainType\":\"Health\",\"mainValue\":2700,\"CriticalHitChancePercent\":6,\"AttackPercent\":4,\"EffectivenessPercent\":9,\"HealthPercent\":26},\"id\":6},{\"gear\":\"Helmet\",\"rank\":\"Epic\",\"set\":\"SpeedSet\",\"level\":88,\"enhance\":15,\"main\":{\"type\":\"Health\",\"value\":2765},\"substats\":[{\"type\":\"HealthPercent\",\"value\":17},{\"type\":\"DefensePercent\",\"value\":14},{\"type\":\"Speed\",\"value\":6},{\"type\":\"EffectResistancePercent\",\"value\":6}],\"name\":\"GladiatorsHelmofVictory\",\"augmentedStats\":{\"mainType\":\"Health\",\"mainValue\":2765,\"HealthPercent\":17,\"DefensePercent\":14,\"Speed\":6,\"EffectResistancePercent\":6},\"id\":7},{\"gear\":\"Helmet\",\"rank\":\"Epic\",\"set\":\"AttackSet\",\"level\":70,\"enhance\":15,\"main\":{\"type\":\"Health\",\"value\":2360},\"substats\":[{\"type\":\"AttackPercent\",\"value\":13},{\"type\":\"Speed\",\"value\":9},{\"type\":\"CriticalHitChancePercent\",\"value\":7},{\"type\":\"CriticalHitDamagePercent\",\"value\":9}],\"name\":\"TerrariaHelm\",\"augmentedStats\":{\"mainType\":\"Health\",\"mainValue\":2360,\"AttackPercent\":13,\"Speed\":9,\"CriticalHitChancePercent\":7,\"CriticalHitDamagePercent\":9},\"id\":8},{\"gear\":\"Helmet\",\"rank\":\"Epic\",\"set\":\"DefenseSet\",\"level\":88,\"enhance\":15,\"main\":{\"type\":\"Health\",\"value\":2765},\"substats\":[{\"type\":\"DefensePercent\",\"value\":7},{\"type\":\"Defense\",\"value\":34},{\"type\":\"AttackPercent\",\"value\":14},{\"type\":\"HealthPercent\",\"value\":31}],\"name\":\"KarkanissDecisionHelm\",\"augmentedStats\":{\"mainType\":\"Health\",\"mainValue\":2765,\"DefensePercent\":7,\"Defense\":34,\"AttackPercent\":14,\"HealthPercent\":31},\"id\":9},{\"gear\":\"Helmet\",\"rank\":\"Epic\",\"set\":\"ImmunitySet\",\"level\":67,\"enhance\":15,\"main\":{\"type\":\"Health\",\"value\":2295},\"substats\":[{\"type\":\"HealthPercent\",\"value\":6},{\"type\":\"CriticalHitDamagePercent\",\"value\":10},{\"type\":\"AttackPercent\",\"value\":14},{\"type\":\"CriticalHitChancePercent\",\"value\":7}],\"name\":\"KarkanissDecisionHelm\",\"augmentedStats\":{\"mainType\":\"Health\",\"mainValue\":2295,\"HealthPercent\":6,\"CriticalHitDamagePercent\":10,\"AttackPercent\":14,\"CriticalHitChancePercent\":7},\"id\":10},{\"gear\":\"Armor\",\"rank\":\"Epic\",\"set\":\"AttackSet\",\"level\":71,\"enhance\":15,\"main\":{\"type\":\"Defense\",\"value\":260},\"substats\":[{\"type\":\"HealthPercent\",\"value\":13},{\"type\":\"Speed\",\"value\":12},{\"type\":\"CriticalHitChancePercent\",\"value\":8},{\"type\":\"CriticalHitDamagePercent\",\"value\":6}],\"name\":\"AncientShandranWarriorsArmor\",\"augmentedStats\":{\"mainType\":\"Defense\",\"mainValue\":260,\"HealthPercent\":13,\"Speed\":12,\"CriticalHitChancePercent\":8,\"CriticalHitDamagePercent\":6},\"id\":11},{\"gear\":\"Armor\",\"rank\":\"Epic\",\"set\":\"SpeedSet\",\"level\":67,\"enhance\":15,\"main\":{\"type\":\"Defense\",\"value\":250},\"substats\":[{\"type\":\"HealthPercent\",\"value\":12},{\"type\":\"DefensePercent\",\"value\":21},{\"type\":\"Speed\",\"value\":10},{\"type\":\"CriticalHitChancePercent\",\"value\":4}],\"name\":\"AzimanusFightersArmor\",\"augmentedStats\":{\"mainType\":\"Defense\",\"mainValue\":250,\"HealthPercent\":12,\"DefensePercent\":21,\"Speed\":10,\"CriticalHitChancePercent\":4},\"id\":12},{\"gear\":\"Armor\",\"rank\":\"Epic\",\"set\":\"CriticalSet\",\"level\":67,\"enhance\":15,\"main\":{\"type\":\"Defense\",\"value\":250},\"substats\":[{\"type\":\"CriticalHitChancePercent\",\"value\":8},{\"type\":\"DefensePercent\",\"value\":12},{\"type\":\"HealthPercent\",\"value\":11},{\"type\":\"CriticalHitDamagePercent\",\"value\":11}],\"name\":\"ArahakansChestplate\",\"augmentedStats\":{\"mainType\":\"Defense\",\"mainValue\":250,\"CriticalHitChancePercent\":8,\"DefensePercent\":12,\"HealthPercent\":11,\"CriticalHitDamagePercent\":11},\"id\":13},{\"gear\":\"Armor\",\"rank\":\"Epic\",\"set\":\"SpeedSet\",\"level\":85,\"enhance\":15,\"main\":{\"type\":\"Defense\",\"value\":300},\"substats\":[{\"type\":\"CriticalHitDamagePercent\",\"value\":9},{\"type\":\"CriticalHitChancePercent\",\"value\":9},{\"type\":\"DefensePercent\",\"value\":12},{\"type\":\"EffectivenessPercent\",\"value\":18}],\"name\":\"Corimescent\",\"augmentedStats\":{\"mainType\":\"Defense\",\"mainValue\":300,\"CriticalHitDamagePercent\":9,\"CriticalHitChancePercent\":9,\"DefensePercent\":12,\"EffectivenessPercent\":18},\"id\":14},{\"gear\":\"Armor\",\"rank\":\"Epic\",\"set\":\"ImmunitySet\",\"level\":85,\"enhance\":15,\"main\":{\"type\":\"Defense\",\"value\":300},\"substats\":[{\"type\":\"Speed\",\"value\":7},{\"type\":\"CriticalHitChancePercent\",\"value\":7},{\"type\":\"CriticalHitDamagePercent\",\"value\":13},{\"type\":\"EffectivenessPercent\",\"value\":17}],\"name\":\"Corimescent\",\"augmentedStats\":{\"mainType\":\"Defense\",\"mainValue\":300,\"Speed\":7,\"CriticalHitChancePercent\":7,\"CriticalHitDamagePercent\":13,\"EffectivenessPercent\":17},\"id\":15},{\"gear\":\"Necklace\",\"rank\":\"Epic\",\"set\":\"HealthSet\",\"level\":78,\"enhance\":15,\"main\":{\"type\":\"HealthPercent\",\"value\":60},\"substats\":[{\"type\":\"DefensePercent\",\"value\":12},{\"type\":\"CriticalHitChancePercent\",\"value\":10},{\"type\":\"Speed\",\"value\":6},{\"type\":\"EffectResistancePercent\",\"value\":19}],\"name\":\"ConstellasPearlNecklace\",\"augmentedStats\":{\"mainType\":\"HealthPercent\",\"mainValue\":60,\"DefensePercent\":12,\"CriticalHitChancePercent\":10,\"Speed\":6,\"EffectResistancePercent\":19},\"id\":16},{\"gear\":\"Necklace\",\"rank\":\"Epic\",\"set\":\"SpeedSet\",\"level\":71,\"enhance\":15,\"main\":{\"type\":\"HealthPercent\",\"value\":50},\"substats\":[{\"type\":\"DefensePercent\",\"value\":15},{\"type\":\"Speed\",\"value\":5},{\"type\":\"CriticalHitChancePercent\",\"value\":10},{\"type\":\"EffectivenessPercent\",\"value\":6}],\"name\":\"PendantofLuminescence\",\"augmentedStats\":{\"mainType\":\"HealthPercent\",\"mainValue\":50,\"DefensePercent\":15,\"Speed\":5,\"CriticalHitChancePercent\":10,\"EffectivenessPercent\":6},\"id\":17},{\"gear\":\"Necklace\",\"rank\":\"Epic\",\"set\":\"AttackSet\",\"level\":65,\"enhance\":15,\"main\":{\"type\":\"CriticalHitChancePercent\",\"value\":45},\"substats\":[{\"type\":\"Speed\",\"value\":13},{\"type\":\"AttackPercent\",\"value\":5},{\"type\":\"HealthPercent\",\"value\":4},{\"type\":\"EffectivenessPercent\",\"value\":13}],\"name\":\"TreasureCollectorsCharm\",\"augmentedStats\":{\"mainType\":\"CriticalHitChancePercent\",\"mainValue\":45,\"Speed\":13,\"AttackPercent\":5,\"HealthPercent\":4,\"EffectivenessPercent\":13},\"id\":18},{\"gear\":\"Necklace\",\"rank\":\"Epic\",\"set\":\"ResistSet\",\"level\":85,\"enhance\":15,\"main\":{\"type\":\"CriticalHitDamagePercent\",\"value\":65},\"substats\":[{\"type\":\"AttackPercent\",\"value\":14},{\"type\":\"CriticalHitChancePercent\",\"value\":21},{\"type\":\"EffectivenessPercent\",\"value\":4},{\"type\":\"HealthPercent\",\"value\":5}],\"name\":\"ObsidianAmulet\",\"augmentedStats\":{\"mainType\":\"CriticalHitDamagePercent\",\"mainValue\":65,\"AttackPercent\":14,\"CriticalHitChancePercent\":21,\"EffectivenessPercent\":4,\"HealthPercent\":5},\"id\":19},{\"gear\":\"Necklace\",\"rank\":\"Epic\",\"set\":\"CriticalSet\",\"level\":65,\"enhance\":15,\"main\":{\"type\":\"CriticalHitDamagePercent\",\"value\":65},\"substats\":[{\"type\":\"CriticalHitChancePercent\",\"value\":8},{\"type\":\"Speed\",\"value\":14},{\"type\":\"Attack\",\"value\":29},{\"type\":\"AttackPercent\",\"value\":6}],\"name\":\"BoldGeneralsNecklace\",\"augmentedStats\":{\"mainType\":\"CriticalHitDamagePercent\",\"mainValue\":65,\"CriticalHitChancePercent\":8,\"Speed\":14,\"Attack\":29,\"AttackPercent\":6},\"id\":20},{\"gear\":\"Ring\",\"rank\":\"Epic\",\"set\":\"DefenseSet\",\"level\":71,\"enhance\":15,\"main\":{\"type\":\"DefensePercent\",\"value\":50},\"substats\":[{\"type\":\"HealthPercent\",\"value\":11},{\"type\":\"Speed\",\"value\":11},{\"type\":\"CriticalHitChancePercent\",\"value\":4},{\"type\":\"EffectResistancePercent\",\"value\":6}],\"name\":\"OathRing\",\"augmentedStats\":{\"mainType\":\"DefensePercent\",\"mainValue\":50,\"HealthPercent\":11,\"Speed\":11,\"CriticalHitChancePercent\":4,\"EffectResistancePercent\":6},\"id\":21},{\"gear\":\"Ring\",\"rank\":\"Epic\",\"set\":\"LifestealSet\",\"level\":85,\"enhance\":15,\"main\":{\"type\":\"AttackPercent\",\"value\":60},\"substats\":[{\"type\":\"HealthPercent\",\"value\":12},{\"type\":\"Speed\",\"value\":4},{\"type\":\"CriticalHitChancePercent\",\"value\":12},{\"type\":\"EffectivenessPercent\",\"value\":18}],\"name\":\"GaveleetsRing\",\"augmentedStats\":{\"mainType\":\"AttackPercent\",\"mainValue\":60,\"HealthPercent\":12,\"Speed\":4,\"CriticalHitChancePercent\":12,\"EffectivenessPercent\":18},\"id\":22},{\"gear\":\"Ring\",\"rank\":\"Epic\",\"set\":\"SpeedSet\",\"level\":71,\"enhance\":15,\"main\":{\"type\":\"HealthPercent\",\"value\":50},\"substats\":[{\"type\":\"DefensePercent\",\"value\":14},{\"type\":\"Speed\",\"value\":5},{\"type\":\"CriticalHitChancePercent\",\"value\":7},{\"type\":\"EffectResistancePercent\",\"value\":9}],\"name\":\"LightofaMillion\",\"augmentedStats\":{\"mainType\":\"HealthPercent\",\"mainValue\":50,\"DefensePercent\":14,\"Speed\":5,\"CriticalHitChancePercent\":7,\"EffectResistancePercent\":9},\"id\":23},{\"gear\":\"Ring\",\"rank\":\"Epic\",\"set\":\"DefenseSet\",\"level\":88,\"enhance\":15,\"main\":{\"type\":\"EffectivenessPercent\",\"value\":65},\"substats\":[{\"type\":\"CriticalHitChancePercent\",\"value\":9},{\"type\":\"CriticalHitDamagePercent\",\"value\":18},{\"type\":\"DefensePercent\",\"value\":19},{\"type\":\"AttackPercent\",\"value\":9}],\"name\":\"GreaterAzimanusFightersRing\",\"augmentedStats\":{\"mainType\":\"EffectivenessPercent\",\"mainValue\":65,\"CriticalHitChancePercent\":9,\"CriticalHitDamagePercent\":18,\"DefensePercent\":19,\"AttackPercent\":9},\"id\":24},{\"gear\":\"Ring\",\"rank\":\"Epic\",\"set\":\"SpeedSet\",\"level\":65,\"enhance\":15,\"main\":{\"type\":\"EffectResistancePercent\",\"value\":50},\"substats\":[{\"type\":\"CriticalHitDamagePercent\",\"value\":11},{\"type\":\"HealthPercent\",\"value\":5},{\"type\":\"DefensePercent\",\"value\":7},{\"type\":\"Speed\",\"value\":8}],\"name\":\"EmergencyRing\",\"augmentedStats\":{\"mainType\":\"EffectResistancePercent\",\"mainValue\":50,\"CriticalHitDamagePercent\":11,\"HealthPercent\":5,\"DefensePercent\":7,\"Speed\":8},\"id\":25},{\"gear\":\"Ring\",\"rank\":\"Epic\",\"set\":\"DefenseSet\",\"level\":88,\"enhance\":15,\"main\":{\"type\":\"AttackPercent\",\"value\":65},\"substats\":[{\"type\":\"Speed\",\"value\":3},{\"type\":\"DefensePercent\",\"value\":18},{\"type\":\"CriticalHitDamagePercent\",\"value\":21},{\"type\":\"Attack\",\"value\":51}],\"name\":\"GreaterAzimanusFightersRing\",\"augmentedStats\":{\"mainType\":\"AttackPercent\",\"mainValue\":65,\"Speed\":3,\"DefensePercent\":18,\"CriticalHitDamagePercent\":21,\"Attack\":51},\"id\":26},{\"gear\":\"Boots\",\"rank\":\"Epic\",\"set\":\"CriticalSet\",\"level\":77,\"enhance\":15,\"main\":{\"type\":\"AttackPercent\",\"value\":60},\"substats\":[{\"type\":\"HealthPercent\",\"value\":7},{\"type\":\"CriticalHitChancePercent\",\"value\":12},{\"type\":\"CriticalHitDamagePercent\",\"value\":6},{\"type\":\"EffectivenessPercent\",\"value\":17}],\"name\":\"VerdantBoots\",\"augmentedStats\":{\"mainType\":\"AttackPercent\",\"mainValue\":60,\"HealthPercent\":7,\"CriticalHitChancePercent\":12,\"CriticalHitDamagePercent\":6,\"EffectivenessPercent\":17},\"id\":27},{\"gear\":\"Boots\",\"rank\":\"Epic\",\"set\":\"SpeedSet\",\"level\":71,\"enhance\":15,\"main\":{\"type\":\"Speed\",\"value\":35},\"substats\":[{\"type\":\"HealthPercent\",\"value\":6},{\"type\":\"AttackPercent\",\"value\":19},{\"type\":\"DefensePercent\",\"value\":12},{\"type\":\"CriticalHitChancePercent\",\"value\":8}],\"name\":\"SocksofSmallMiracles\",\"augmentedStats\":{\"mainType\":\"Speed\",\"mainValue\":35,\"HealthPercent\":6,\"AttackPercent\":19,\"DefensePercent\":12,\"CriticalHitChancePercent\":8},\"id\":28},{\"gear\":\"Boots\",\"rank\":\"Epic\",\"set\":\"SpeedSet\",\"level\":85,\"enhance\":15,\"main\":{\"type\":\"HealthPercent\",\"value\":60},\"substats\":[{\"type\":\"EffectResistancePercent\",\"value\":7},{\"type\":\"DefensePercent\",\"value\":12},{\"type\":\"Speed\",\"value\":8},{\"type\":\"CriticalHitChancePercent\",\"value\":11}],\"name\":\"AbyssDrakeBoots\",\"augmentedStats\":{\"mainType\":\"HealthPercent\",\"mainValue\":60,\"EffectResistancePercent\":7,\"DefensePercent\":12,\"Speed\":8,\"CriticalHitChancePercent\":11},\"id\":29},{\"gear\":\"Boots\",\"rank\":\"Epic\",\"set\":\"SpeedSet\",\"level\":85,\"enhance\":15,\"main\":{\"type\":\"Speed\",\"value\":40},\"substats\":[{\"type\":\"AttackPercent\",\"value\":6},{\"type\":\"EffectivenessPercent\",\"value\":14},{\"type\":\"EffectResistancePercent\",\"value\":28},{\"type\":\"HealthPercent\",\"value\":13}],\"name\":\"PracticalBoots\",\"augmentedStats\":{\"mainType\":\"Speed\",\"mainValue\":40,\"AttackPercent\":6,\"EffectivenessPercent\":14,\"EffectResistancePercent\":28,\"HealthPercent\":13},\"id\":30},{\"gear\":\"Boots\",\"rank\":\"Epic\",\"set\":\"SpeedSet\",\"level\":85,\"enhance\":15,\"main\":{\"type\":\"Speed\",\"value\":40},\"substats\":[{\"type\":\"EffectResistancePercent\",\"value\":17},{\"type\":\"DefensePercent\",\"value\":17},{\"type\":\"Attack\",\"value\":43},{\"type\":\"CriticalHitChancePercent\",\"value\":8}],\"name\":\"PracticalBoots\",\"augmentedStats\":{\"mainType\":\"Speed\",\"mainValue\":40,\"EffectResistancePercent\":17,\"DefensePercent\":17,\"Attack\":43,\"CriticalHitChancePercent\":8},\"id\":31}],\"inputAllowLockedItems\":false,\"inputAllowEquippedItems\":false,\"inputKeepCurrentItems\":false,\"inputSets\":[[\"SpeedSet\"],[],[]],\"inputSetsOne\":[\"SpeedSet\",\"DestructionSet\"],\"inputSetsTwo\":[\"HealthSet\",\"ImmunitySet\"],\"inputSetsThree\":[],\"inputAllowBrokenSets\":false,\"setFormat\":1,\"atk\":576,\"hp\":5700,\"def\":743,\"cr\":15,\"cd\":150,\"eff\":0,\"res\":0,\"spd\":88,\"dac\":5}"; + // 222 set +// private static final String REQUEST_STRING = "{\"base\":{\"atk\":576,\"hp\":5700,\"def\":743,\"cr\":15,\"cd\":150,\"eff\":0,\"res\":0,\"spd\":88,\"dac\":5},\"requestType\":\"OptimizationRequest\",\"extraField\":\"asdf\",\"items\":[{\"gear\":\"Weapon\",\"rank\":\"Heroic\",\"set\":\"HealthSet\",\"level\":85,\"enhance\":15,\"main\":{\"type\":\"Attack\",\"value\":500},\"substats\":[{\"type\":\"EffectivenessPercent\",\"value\":4},{\"type\":\"HealthPercent\",\"value\":27},{\"type\":\"AttackPercent\",\"value\":14},{\"type\":\"Health\",\"value\":178}],\"name\":\"DarkSteelSaber\",\"augmentedStats\":{\"mainType\":\"Attack\",\"mainValue\":500,\"EffectivenessPercent\":4,\"HealthPercent\":27,\"AttackPercent\":14,\"Health\":178},\"id\":0},{\"gear\":\"Weapon\",\"rank\":\"Epic\",\"set\":\"HealthSet\",\"level\":88,\"enhance\":15,\"main\":{\"type\":\"Attack\",\"value\":515},\"substats\":[{\"type\":\"Health\",\"value\":214},{\"type\":\"HealthPercent\",\"value\":25},{\"type\":\"CriticalHitDamagePercent\",\"value\":4},{\"type\":\"Speed\",\"value\":9}],\"name\":\"ArahakansFang\",\"augmentedStats\":{\"mainType\":\"Attack\",\"mainValue\":515,\"Health\":214,\"HealthPercent\":25,\"CriticalHitDamagePercent\":4,\"Speed\":9},\"id\":1},{\"gear\":\"Weapon\",\"rank\":\"Epic\",\"set\":\"RageSet\",\"level\":71,\"enhance\":15,\"main\":{\"type\":\"Attack\",\"value\":440},\"substats\":[{\"type\":\"AttackPercent\",\"value\":10},{\"type\":\"Speed\",\"value\":7},{\"type\":\"CriticalHitChancePercent\",\"value\":7},{\"type\":\"CriticalHitDamagePercent\",\"value\":9}],\"name\":\"ThornVineWhip\",\"augmentedStats\":{\"mainType\":\"Attack\",\"mainValue\":440,\"AttackPercent\":10,\"Speed\":7,\"CriticalHitChancePercent\":7,\"CriticalHitDamagePercent\":9},\"id\":2},{\"gear\":\"Weapon\",\"rank\":\"Epic\",\"set\":\"SpeedSet\",\"level\":85,\"enhance\":15,\"main\":{\"type\":\"Attack\",\"value\":500},\"substats\":[{\"type\":\"CriticalHitDamagePercent\",\"value\":15},{\"type\":\"Speed\",\"value\":6},{\"type\":\"CriticalHitChancePercent\",\"value\":10},{\"type\":\"AttackPercent\",\"value\":7}],\"name\":\"AbyssDrakeBonesword\",\"augmentedStats\":{\"mainType\":\"Attack\",\"mainValue\":500,\"CriticalHitDamagePercent\":15,\"Speed\":6,\"CriticalHitChancePercent\":10,\"AttackPercent\":7},\"id\":3},{\"gear\":\"Weapon\",\"rank\":\"Epic\",\"set\":\"CriticalSet\",\"level\":70,\"enhance\":15,\"main\":{\"type\":\"Attack\",\"value\":440},\"substats\":[{\"type\":\"CriticalHitChancePercent\",\"value\":6},{\"type\":\"CriticalHitDamagePercent\",\"value\":11},{\"type\":\"EffectResistancePercent\",\"value\":12},{\"type\":\"AttackPercent\",\"value\":20}],\"name\":\"ManaDrakeBonesword\",\"augmentedStats\":{\"mainType\":\"Attack\",\"mainValue\":440,\"CriticalHitChancePercent\":6,\"CriticalHitDamagePercent\":11,\"EffectResistancePercent\":12,\"AttackPercent\":20},\"id\":4},{\"gear\":\"Helmet\",\"rank\":\"Epic\",\"set\":\"SpeedSet\",\"level\":71,\"enhance\":15,\"main\":{\"type\":\"Health\",\"value\":2360},\"substats\":[{\"type\":\"HealthPercent\",\"value\":12},{\"type\":\"AttackPercent\",\"value\":11},{\"type\":\"DefensePercent\",\"value\":18},{\"type\":\"Speed\",\"value\":3}],\"name\":\"RoseCoronet\",\"augmentedStats\":{\"mainType\":\"Health\",\"mainValue\":2360,\"HealthPercent\":12,\"AttackPercent\":11,\"DefensePercent\":18,\"Speed\":3},\"id\":5},{\"gear\":\"Helmet\",\"rank\":\"Epic\",\"set\":\"SpeedSet\",\"level\":85,\"enhance\":15,\"main\":{\"type\":\"Health\",\"value\":2700},\"substats\":[{\"type\":\"CriticalHitChancePercent\",\"value\":6},{\"type\":\"AttackPercent\",\"value\":4},{\"type\":\"EffectivenessPercent\",\"value\":9},{\"type\":\"HealthPercent\",\"value\":26}],\"name\":\"AbyssDrakeMask\",\"augmentedStats\":{\"mainType\":\"Health\",\"mainValue\":2700,\"CriticalHitChancePercent\":6,\"AttackPercent\":4,\"EffectivenessPercent\":9,\"HealthPercent\":26},\"id\":6},{\"gear\":\"Helmet\",\"rank\":\"Epic\",\"set\":\"SpeedSet\",\"level\":88,\"enhance\":15,\"main\":{\"type\":\"Health\",\"value\":2765},\"substats\":[{\"type\":\"HealthPercent\",\"value\":17},{\"type\":\"DefensePercent\",\"value\":14},{\"type\":\"Speed\",\"value\":6},{\"type\":\"EffectResistancePercent\",\"value\":6}],\"name\":\"GladiatorsHelmofVictory\",\"augmentedStats\":{\"mainType\":\"Health\",\"mainValue\":2765,\"HealthPercent\":17,\"DefensePercent\":14,\"Speed\":6,\"EffectResistancePercent\":6},\"id\":7},{\"gear\":\"Helmet\",\"rank\":\"Epic\",\"set\":\"AttackSet\",\"level\":70,\"enhance\":15,\"main\":{\"type\":\"Health\",\"value\":2360},\"substats\":[{\"type\":\"AttackPercent\",\"value\":13},{\"type\":\"Speed\",\"value\":9},{\"type\":\"CriticalHitChancePercent\",\"value\":7},{\"type\":\"CriticalHitDamagePercent\",\"value\":9}],\"name\":\"TerrariaHelm\",\"augmentedStats\":{\"mainType\":\"Health\",\"mainValue\":2360,\"AttackPercent\":13,\"Speed\":9,\"CriticalHitChancePercent\":7,\"CriticalHitDamagePercent\":9},\"id\":8},{\"gear\":\"Helmet\",\"rank\":\"Epic\",\"set\":\"DefenseSet\",\"level\":88,\"enhance\":15,\"main\":{\"type\":\"Health\",\"value\":2765},\"substats\":[{\"type\":\"DefensePercent\",\"value\":7},{\"type\":\"Defense\",\"value\":34},{\"type\":\"AttackPercent\",\"value\":14},{\"type\":\"HealthPercent\",\"value\":31}],\"name\":\"KarkanissDecisionHelm\",\"augmentedStats\":{\"mainType\":\"Health\",\"mainValue\":2765,\"DefensePercent\":7,\"Defense\":34,\"AttackPercent\":14,\"HealthPercent\":31},\"id\":9},{\"gear\":\"Helmet\",\"rank\":\"Epic\",\"set\":\"ImmunitySet\",\"level\":67,\"enhance\":15,\"main\":{\"type\":\"Health\",\"value\":2295},\"substats\":[{\"type\":\"HealthPercent\",\"value\":6},{\"type\":\"CriticalHitDamagePercent\",\"value\":10},{\"type\":\"AttackPercent\",\"value\":14},{\"type\":\"CriticalHitChancePercent\",\"value\":7}],\"name\":\"KarkanissDecisionHelm\",\"augmentedStats\":{\"mainType\":\"Health\",\"mainValue\":2295,\"HealthPercent\":6,\"CriticalHitDamagePercent\":10,\"AttackPercent\":14,\"CriticalHitChancePercent\":7},\"id\":10},{\"gear\":\"Armor\",\"rank\":\"Epic\",\"set\":\"AttackSet\",\"level\":71,\"enhance\":15,\"main\":{\"type\":\"Defense\",\"value\":260},\"substats\":[{\"type\":\"HealthPercent\",\"value\":13},{\"type\":\"Speed\",\"value\":12},{\"type\":\"CriticalHitChancePercent\",\"value\":8},{\"type\":\"CriticalHitDamagePercent\",\"value\":6}],\"name\":\"AncientShandranWarriorsArmor\",\"augmentedStats\":{\"mainType\":\"Defense\",\"mainValue\":260,\"HealthPercent\":13,\"Speed\":12,\"CriticalHitChancePercent\":8,\"CriticalHitDamagePercent\":6},\"id\":11},{\"gear\":\"Armor\",\"rank\":\"Epic\",\"set\":\"SpeedSet\",\"level\":67,\"enhance\":15,\"main\":{\"type\":\"Defense\",\"value\":250},\"substats\":[{\"type\":\"HealthPercent\",\"value\":12},{\"type\":\"DefensePercent\",\"value\":21},{\"type\":\"Speed\",\"value\":10},{\"type\":\"CriticalHitChancePercent\",\"value\":4}],\"name\":\"AzimanusFightersArmor\",\"augmentedStats\":{\"mainType\":\"Defense\",\"mainValue\":250,\"HealthPercent\":12,\"DefensePercent\":21,\"Speed\":10,\"CriticalHitChancePercent\":4},\"id\":12},{\"gear\":\"Armor\",\"rank\":\"Epic\",\"set\":\"CriticalSet\",\"level\":67,\"enhance\":15,\"main\":{\"type\":\"Defense\",\"value\":250},\"substats\":[{\"type\":\"CriticalHitChancePercent\",\"value\":8},{\"type\":\"DefensePercent\",\"value\":12},{\"type\":\"HealthPercent\",\"value\":11},{\"type\":\"CriticalHitDamagePercent\",\"value\":11}],\"name\":\"ArahakansChestplate\",\"augmentedStats\":{\"mainType\":\"Defense\",\"mainValue\":250,\"CriticalHitChancePercent\":8,\"DefensePercent\":12,\"HealthPercent\":11,\"CriticalHitDamagePercent\":11},\"id\":13},{\"gear\":\"Armor\",\"rank\":\"Epic\",\"set\":\"SpeedSet\",\"level\":85,\"enhance\":15,\"main\":{\"type\":\"Defense\",\"value\":300},\"substats\":[{\"type\":\"CriticalHitDamagePercent\",\"value\":9},{\"type\":\"CriticalHitChancePercent\",\"value\":9},{\"type\":\"DefensePercent\",\"value\":12},{\"type\":\"EffectivenessPercent\",\"value\":18}],\"name\":\"Corimescent\",\"augmentedStats\":{\"mainType\":\"Defense\",\"mainValue\":300,\"CriticalHitDamagePercent\":9,\"CriticalHitChancePercent\":9,\"DefensePercent\":12,\"EffectivenessPercent\":18},\"id\":14},{\"gear\":\"Armor\",\"rank\":\"Epic\",\"set\":\"ImmunitySet\",\"level\":85,\"enhance\":15,\"main\":{\"type\":\"Defense\",\"value\":300},\"substats\":[{\"type\":\"Speed\",\"value\":7},{\"type\":\"CriticalHitChancePercent\",\"value\":7},{\"type\":\"CriticalHitDamagePercent\",\"value\":13},{\"type\":\"EffectivenessPercent\",\"value\":17}],\"name\":\"Corimescent\",\"augmentedStats\":{\"mainType\":\"Defense\",\"mainValue\":300,\"Speed\":7,\"CriticalHitChancePercent\":7,\"CriticalHitDamagePercent\":13,\"EffectivenessPercent\":17},\"id\":15},{\"gear\":\"Necklace\",\"rank\":\"Epic\",\"set\":\"HealthSet\",\"level\":78,\"enhance\":15,\"main\":{\"type\":\"HealthPercent\",\"value\":60},\"substats\":[{\"type\":\"DefensePercent\",\"value\":12},{\"type\":\"CriticalHitChancePercent\",\"value\":10},{\"type\":\"Speed\",\"value\":6},{\"type\":\"EffectResistancePercent\",\"value\":19}],\"name\":\"ConstellasPearlNecklace\",\"augmentedStats\":{\"mainType\":\"HealthPercent\",\"mainValue\":60,\"DefensePercent\":12,\"CriticalHitChancePercent\":10,\"Speed\":6,\"EffectResistancePercent\":19},\"id\":16},{\"gear\":\"Necklace\",\"rank\":\"Epic\",\"set\":\"SpeedSet\",\"level\":71,\"enhance\":15,\"main\":{\"type\":\"HealthPercent\",\"value\":50},\"substats\":[{\"type\":\"DefensePercent\",\"value\":15},{\"type\":\"Speed\",\"value\":5},{\"type\":\"CriticalHitChancePercent\",\"value\":10},{\"type\":\"EffectivenessPercent\",\"value\":6}],\"name\":\"PendantofLuminescence\",\"augmentedStats\":{\"mainType\":\"HealthPercent\",\"mainValue\":50,\"DefensePercent\":15,\"Speed\":5,\"CriticalHitChancePercent\":10,\"EffectivenessPercent\":6},\"id\":17},{\"gear\":\"Necklace\",\"rank\":\"Epic\",\"set\":\"AttackSet\",\"level\":65,\"enhance\":15,\"main\":{\"type\":\"CriticalHitChancePercent\",\"value\":45},\"substats\":[{\"type\":\"Speed\",\"value\":13},{\"type\":\"AttackPercent\",\"value\":5},{\"type\":\"HealthPercent\",\"value\":4},{\"type\":\"EffectivenessPercent\",\"value\":13}],\"name\":\"TreasureCollectorsCharm\",\"augmentedStats\":{\"mainType\":\"CriticalHitChancePercent\",\"mainValue\":45,\"Speed\":13,\"AttackPercent\":5,\"HealthPercent\":4,\"EffectivenessPercent\":13},\"id\":18},{\"gear\":\"Necklace\",\"rank\":\"Epic\",\"set\":\"ResistSet\",\"level\":85,\"enhance\":15,\"main\":{\"type\":\"CriticalHitDamagePercent\",\"value\":65},\"substats\":[{\"type\":\"AttackPercent\",\"value\":14},{\"type\":\"CriticalHitChancePercent\",\"value\":21},{\"type\":\"EffectivenessPercent\",\"value\":4},{\"type\":\"HealthPercent\",\"value\":5}],\"name\":\"ObsidianAmulet\",\"augmentedStats\":{\"mainType\":\"CriticalHitDamagePercent\",\"mainValue\":65,\"AttackPercent\":14,\"CriticalHitChancePercent\":21,\"EffectivenessPercent\":4,\"HealthPercent\":5},\"id\":19},{\"gear\":\"Necklace\",\"rank\":\"Epic\",\"set\":\"CriticalSet\",\"level\":65,\"enhance\":15,\"main\":{\"type\":\"CriticalHitDamagePercent\",\"value\":65},\"substats\":[{\"type\":\"CriticalHitChancePercent\",\"value\":8},{\"type\":\"Speed\",\"value\":14},{\"type\":\"Attack\",\"value\":29},{\"type\":\"AttackPercent\",\"value\":6}],\"name\":\"BoldGeneralsNecklace\",\"augmentedStats\":{\"mainType\":\"CriticalHitDamagePercent\",\"mainValue\":65,\"CriticalHitChancePercent\":8,\"Speed\":14,\"Attack\":29,\"AttackPercent\":6},\"id\":20},{\"gear\":\"Ring\",\"rank\":\"Epic\",\"set\":\"DefenseSet\",\"level\":71,\"enhance\":15,\"main\":{\"type\":\"DefensePercent\",\"value\":50},\"substats\":[{\"type\":\"HealthPercent\",\"value\":11},{\"type\":\"Speed\",\"value\":11},{\"type\":\"CriticalHitChancePercent\",\"value\":4},{\"type\":\"EffectResistancePercent\",\"value\":6}],\"name\":\"OathRing\",\"augmentedStats\":{\"mainType\":\"DefensePercent\",\"mainValue\":50,\"HealthPercent\":11,\"Speed\":11,\"CriticalHitChancePercent\":4,\"EffectResistancePercent\":6},\"id\":21},{\"gear\":\"Ring\",\"rank\":\"Epic\",\"set\":\"LifestealSet\",\"level\":85,\"enhance\":15,\"main\":{\"type\":\"AttackPercent\",\"value\":60},\"substats\":[{\"type\":\"HealthPercent\",\"value\":12},{\"type\":\"Speed\",\"value\":4},{\"type\":\"CriticalHitChancePercent\",\"value\":12},{\"type\":\"EffectivenessPercent\",\"value\":18}],\"name\":\"GaveleetsRing\",\"augmentedStats\":{\"mainType\":\"AttackPercent\",\"mainValue\":60,\"HealthPercent\":12,\"Speed\":4,\"CriticalHitChancePercent\":12,\"EffectivenessPercent\":18},\"id\":22},{\"gear\":\"Ring\",\"rank\":\"Epic\",\"set\":\"SpeedSet\",\"level\":71,\"enhance\":15,\"main\":{\"type\":\"HealthPercent\",\"value\":50},\"substats\":[{\"type\":\"DefensePercent\",\"value\":14},{\"type\":\"Speed\",\"value\":5},{\"type\":\"CriticalHitChancePercent\",\"value\":7},{\"type\":\"EffectResistancePercent\",\"value\":9}],\"name\":\"LightofaMillion\",\"augmentedStats\":{\"mainType\":\"HealthPercent\",\"mainValue\":50,\"DefensePercent\":14,\"Speed\":5,\"CriticalHitChancePercent\":7,\"EffectResistancePercent\":9},\"id\":23},{\"gear\":\"Ring\",\"rank\":\"Epic\",\"set\":\"DefenseSet\",\"level\":88,\"enhance\":15,\"main\":{\"type\":\"EffectivenessPercent\",\"value\":65},\"substats\":[{\"type\":\"CriticalHitChancePercent\",\"value\":9},{\"type\":\"CriticalHitDamagePercent\",\"value\":18},{\"type\":\"DefensePercent\",\"value\":19},{\"type\":\"AttackPercent\",\"value\":9}],\"name\":\"GreaterAzimanusFightersRing\",\"augmentedStats\":{\"mainType\":\"EffectivenessPercent\",\"mainValue\":65,\"CriticalHitChancePercent\":9,\"CriticalHitDamagePercent\":18,\"DefensePercent\":19,\"AttackPercent\":9},\"id\":24},{\"gear\":\"Ring\",\"rank\":\"Epic\",\"set\":\"SpeedSet\",\"level\":65,\"enhance\":15,\"main\":{\"type\":\"EffectResistancePercent\",\"value\":50},\"substats\":[{\"type\":\"CriticalHitDamagePercent\",\"value\":11},{\"type\":\"HealthPercent\",\"value\":5},{\"type\":\"DefensePercent\",\"value\":7},{\"type\":\"Speed\",\"value\":8}],\"name\":\"EmergencyRing\",\"augmentedStats\":{\"mainType\":\"EffectResistancePercent\",\"mainValue\":50,\"CriticalHitDamagePercent\":11,\"HealthPercent\":5,\"DefensePercent\":7,\"Speed\":8},\"id\":25},{\"gear\":\"Ring\",\"rank\":\"Epic\",\"set\":\"DefenseSet\",\"level\":88,\"enhance\":15,\"main\":{\"type\":\"AttackPercent\",\"value\":65},\"substats\":[{\"type\":\"Speed\",\"value\":3},{\"type\":\"DefensePercent\",\"value\":18},{\"type\":\"CriticalHitDamagePercent\",\"value\":21},{\"type\":\"Attack\",\"value\":51}],\"name\":\"GreaterAzimanusFightersRing\",\"augmentedStats\":{\"mainType\":\"AttackPercent\",\"mainValue\":65,\"Speed\":3,\"DefensePercent\":18,\"CriticalHitDamagePercent\":21,\"Attack\":51},\"id\":26},{\"gear\":\"Boots\",\"rank\":\"Epic\",\"set\":\"CriticalSet\",\"level\":77,\"enhance\":15,\"main\":{\"type\":\"AttackPercent\",\"value\":60},\"substats\":[{\"type\":\"HealthPercent\",\"value\":7},{\"type\":\"CriticalHitChancePercent\",\"value\":12},{\"type\":\"CriticalHitDamagePercent\",\"value\":6},{\"type\":\"EffectivenessPercent\",\"value\":17}],\"name\":\"VerdantBoots\",\"augmentedStats\":{\"mainType\":\"AttackPercent\",\"mainValue\":60,\"HealthPercent\":7,\"CriticalHitChancePercent\":12,\"CriticalHitDamagePercent\":6,\"EffectivenessPercent\":17},\"id\":27},{\"gear\":\"Boots\",\"rank\":\"Epic\",\"set\":\"SpeedSet\",\"level\":71,\"enhance\":15,\"main\":{\"type\":\"Speed\",\"value\":35},\"substats\":[{\"type\":\"HealthPercent\",\"value\":6},{\"type\":\"AttackPercent\",\"value\":19},{\"type\":\"DefensePercent\",\"value\":12},{\"type\":\"CriticalHitChancePercent\",\"value\":8}],\"name\":\"SocksofSmallMiracles\",\"augmentedStats\":{\"mainType\":\"Speed\",\"mainValue\":35,\"HealthPercent\":6,\"AttackPercent\":19,\"DefensePercent\":12,\"CriticalHitChancePercent\":8},\"id\":28},{\"gear\":\"Boots\",\"rank\":\"Epic\",\"set\":\"SpeedSet\",\"level\":85,\"enhance\":15,\"main\":{\"type\":\"HealthPercent\",\"value\":60},\"substats\":[{\"type\":\"EffectResistancePercent\",\"value\":7},{\"type\":\"DefensePercent\",\"value\":12},{\"type\":\"Speed\",\"value\":8},{\"type\":\"CriticalHitChancePercent\",\"value\":11}],\"name\":\"AbyssDrakeBoots\",\"augmentedStats\":{\"mainType\":\"HealthPercent\",\"mainValue\":60,\"EffectResistancePercent\":7,\"DefensePercent\":12,\"Speed\":8,\"CriticalHitChancePercent\":11},\"id\":29},{\"gear\":\"Boots\",\"rank\":\"Epic\",\"set\":\"SpeedSet\",\"level\":85,\"enhance\":15,\"main\":{\"type\":\"Speed\",\"value\":40},\"substats\":[{\"type\":\"AttackPercent\",\"value\":6},{\"type\":\"EffectivenessPercent\",\"value\":14},{\"type\":\"EffectResistancePercent\",\"value\":28},{\"type\":\"HealthPercent\",\"value\":13}],\"name\":\"PracticalBoots\",\"augmentedStats\":{\"mainType\":\"Speed\",\"mainValue\":40,\"AttackPercent\":6,\"EffectivenessPercent\":14,\"EffectResistancePercent\":28,\"HealthPercent\":13},\"id\":30},{\"gear\":\"Boots\",\"rank\":\"Epic\",\"set\":\"SpeedSet\",\"level\":85,\"enhance\":15,\"main\":{\"type\":\"Speed\",\"value\":40},\"substats\":[{\"type\":\"EffectResistancePercent\",\"value\":17},{\"type\":\"DefensePercent\",\"value\":17},{\"type\":\"Attack\",\"value\":43},{\"type\":\"CriticalHitChancePercent\",\"value\":8}],\"name\":\"PracticalBoots\",\"augmentedStats\":{\"mainType\":\"Speed\",\"mainValue\":40,\"EffectResistancePercent\":17,\"DefensePercent\":17,\"Attack\":43,\"CriticalHitChancePercent\":8},\"id\":31}],\"inputAllowLockedItems\":false,\"inputAllowEquippedItems\":false,\"inputKeepCurrentItems\":false,\"inputSets\":[[\"SpeedSet\"],[],[]],\"inputSetsOne\":[\"HealthSet\",\"HitSet\"],\"inputSetsTwo\":[\"HealthSet\",\"CriticalSet\"],\"inputSetsThree\":[\"DefenseSet\"],\"inputAllowBrokenSets\":false,\"setFormat\":5,\"atk\":576,\"hp\":5700,\"def\":743,\"cr\":15,\"cd\":150,\"eff\":0,\"res\":0,\"spd\":88,\"dac\":5}"; + // 222 All immunity +// private static final String REQUEST_STRING = "{\"base\":{\"atk\":576,\"hp\":5700,\"def\":743,\"cr\":15,\"cd\":150,\"eff\":0,\"res\":0,\"spd\":88,\"dac\":5},\"requestType\":\"OptimizationRequest\",\"extraField\":\"asdf\",\"items\":[{\"gear\":\"Weapon\",\"rank\":\"Heroic\",\"set\":\"HealthSet\",\"level\":85,\"enhance\":15,\"main\":{\"type\":\"Attack\",\"value\":500},\"substats\":[{\"type\":\"EffectivenessPercent\",\"value\":4},{\"type\":\"HealthPercent\",\"value\":27},{\"type\":\"AttackPercent\",\"value\":14},{\"type\":\"Health\",\"value\":178}],\"name\":\"DarkSteelSaber\",\"augmentedStats\":{\"mainType\":\"Attack\",\"mainValue\":500,\"EffectivenessPercent\":4,\"HealthPercent\":27,\"AttackPercent\":14,\"Health\":178},\"id\":0},{\"gear\":\"Weapon\",\"rank\":\"Epic\",\"set\":\"HealthSet\",\"level\":88,\"enhance\":15,\"main\":{\"type\":\"Attack\",\"value\":515},\"substats\":[{\"type\":\"Health\",\"value\":214},{\"type\":\"HealthPercent\",\"value\":25},{\"type\":\"CriticalHitDamagePercent\",\"value\":4},{\"type\":\"Speed\",\"value\":9}],\"name\":\"ArahakansFang\",\"augmentedStats\":{\"mainType\":\"Attack\",\"mainValue\":515,\"Health\":214,\"HealthPercent\":25,\"CriticalHitDamagePercent\":4,\"Speed\":9},\"id\":1},{\"gear\":\"Weapon\",\"rank\":\"Epic\",\"set\":\"RageSet\",\"level\":71,\"enhance\":15,\"main\":{\"type\":\"Attack\",\"value\":440},\"substats\":[{\"type\":\"AttackPercent\",\"value\":10},{\"type\":\"Speed\",\"value\":7},{\"type\":\"CriticalHitChancePercent\",\"value\":7},{\"type\":\"CriticalHitDamagePercent\",\"value\":9}],\"name\":\"ThornVineWhip\",\"augmentedStats\":{\"mainType\":\"Attack\",\"mainValue\":440,\"AttackPercent\":10,\"Speed\":7,\"CriticalHitChancePercent\":7,\"CriticalHitDamagePercent\":9},\"id\":2},{\"gear\":\"Weapon\",\"rank\":\"Epic\",\"set\":\"SpeedSet\",\"level\":85,\"enhance\":15,\"main\":{\"type\":\"Attack\",\"value\":500},\"substats\":[{\"type\":\"CriticalHitDamagePercent\",\"value\":15},{\"type\":\"Speed\",\"value\":6},{\"type\":\"CriticalHitChancePercent\",\"value\":10},{\"type\":\"AttackPercent\",\"value\":7}],\"name\":\"AbyssDrakeBonesword\",\"augmentedStats\":{\"mainType\":\"Attack\",\"mainValue\":500,\"CriticalHitDamagePercent\":15,\"Speed\":6,\"CriticalHitChancePercent\":10,\"AttackPercent\":7},\"id\":3},{\"gear\":\"Weapon\",\"rank\":\"Epic\",\"set\":\"CriticalSet\",\"level\":70,\"enhance\":15,\"main\":{\"type\":\"Attack\",\"value\":440},\"substats\":[{\"type\":\"CriticalHitChancePercent\",\"value\":6},{\"type\":\"CriticalHitDamagePercent\",\"value\":11},{\"type\":\"EffectResistancePercent\",\"value\":12},{\"type\":\"AttackPercent\",\"value\":20}],\"name\":\"ManaDrakeBonesword\",\"augmentedStats\":{\"mainType\":\"Attack\",\"mainValue\":440,\"CriticalHitChancePercent\":6,\"CriticalHitDamagePercent\":11,\"EffectResistancePercent\":12,\"AttackPercent\":20},\"id\":4},{\"gear\":\"Helmet\",\"rank\":\"Epic\",\"set\":\"SpeedSet\",\"level\":71,\"enhance\":15,\"main\":{\"type\":\"Health\",\"value\":2360},\"substats\":[{\"type\":\"HealthPercent\",\"value\":12},{\"type\":\"AttackPercent\",\"value\":11},{\"type\":\"DefensePercent\",\"value\":18},{\"type\":\"Speed\",\"value\":3}],\"name\":\"RoseCoronet\",\"augmentedStats\":{\"mainType\":\"Health\",\"mainValue\":2360,\"HealthPercent\":12,\"AttackPercent\":11,\"DefensePercent\":18,\"Speed\":3},\"id\":5},{\"gear\":\"Helmet\",\"rank\":\"Epic\",\"set\":\"SpeedSet\",\"level\":85,\"enhance\":15,\"main\":{\"type\":\"Health\",\"value\":2700},\"substats\":[{\"type\":\"CriticalHitChancePercent\",\"value\":6},{\"type\":\"AttackPercent\",\"value\":4},{\"type\":\"EffectivenessPercent\",\"value\":9},{\"type\":\"HealthPercent\",\"value\":26}],\"name\":\"AbyssDrakeMask\",\"augmentedStats\":{\"mainType\":\"Health\",\"mainValue\":2700,\"CriticalHitChancePercent\":6,\"AttackPercent\":4,\"EffectivenessPercent\":9,\"HealthPercent\":26},\"id\":6},{\"gear\":\"Helmet\",\"rank\":\"Epic\",\"set\":\"SpeedSet\",\"level\":88,\"enhance\":15,\"main\":{\"type\":\"Health\",\"value\":2765},\"substats\":[{\"type\":\"HealthPercent\",\"value\":17},{\"type\":\"DefensePercent\",\"value\":14},{\"type\":\"Speed\",\"value\":6},{\"type\":\"EffectResistancePercent\",\"value\":6}],\"name\":\"GladiatorsHelmofVictory\",\"augmentedStats\":{\"mainType\":\"Health\",\"mainValue\":2765,\"HealthPercent\":17,\"DefensePercent\":14,\"Speed\":6,\"EffectResistancePercent\":6},\"id\":7},{\"gear\":\"Helmet\",\"rank\":\"Epic\",\"set\":\"AttackSet\",\"level\":70,\"enhance\":15,\"main\":{\"type\":\"Health\",\"value\":2360},\"substats\":[{\"type\":\"AttackPercent\",\"value\":13},{\"type\":\"Speed\",\"value\":9},{\"type\":\"CriticalHitChancePercent\",\"value\":7},{\"type\":\"CriticalHitDamagePercent\",\"value\":9}],\"name\":\"TerrariaHelm\",\"augmentedStats\":{\"mainType\":\"Health\",\"mainValue\":2360,\"AttackPercent\":13,\"Speed\":9,\"CriticalHitChancePercent\":7,\"CriticalHitDamagePercent\":9},\"id\":8},{\"gear\":\"Helmet\",\"rank\":\"Epic\",\"set\":\"DefenseSet\",\"level\":88,\"enhance\":15,\"main\":{\"type\":\"Health\",\"value\":2765},\"substats\":[{\"type\":\"DefensePercent\",\"value\":7},{\"type\":\"Defense\",\"value\":34},{\"type\":\"AttackPercent\",\"value\":14},{\"type\":\"HealthPercent\",\"value\":31}],\"name\":\"KarkanissDecisionHelm\",\"augmentedStats\":{\"mainType\":\"Health\",\"mainValue\":2765,\"DefensePercent\":7,\"Defense\":34,\"AttackPercent\":14,\"HealthPercent\":31},\"id\":9},{\"gear\":\"Helmet\",\"rank\":\"Epic\",\"set\":\"ImmunitySet\",\"level\":67,\"enhance\":15,\"main\":{\"type\":\"Health\",\"value\":2295},\"substats\":[{\"type\":\"HealthPercent\",\"value\":6},{\"type\":\"CriticalHitDamagePercent\",\"value\":10},{\"type\":\"AttackPercent\",\"value\":14},{\"type\":\"CriticalHitChancePercent\",\"value\":7}],\"name\":\"KarkanissDecisionHelm\",\"augmentedStats\":{\"mainType\":\"Health\",\"mainValue\":2295,\"HealthPercent\":6,\"CriticalHitDamagePercent\":10,\"AttackPercent\":14,\"CriticalHitChancePercent\":7},\"id\":10},{\"gear\":\"Armor\",\"rank\":\"Epic\",\"set\":\"AttackSet\",\"level\":71,\"enhance\":15,\"main\":{\"type\":\"Defense\",\"value\":260},\"substats\":[{\"type\":\"HealthPercent\",\"value\":13},{\"type\":\"Speed\",\"value\":12},{\"type\":\"CriticalHitChancePercent\",\"value\":8},{\"type\":\"CriticalHitDamagePercent\",\"value\":6}],\"name\":\"AncientShandranWarriorsArmor\",\"augmentedStats\":{\"mainType\":\"Defense\",\"mainValue\":260,\"HealthPercent\":13,\"Speed\":12,\"CriticalHitChancePercent\":8,\"CriticalHitDamagePercent\":6},\"id\":11},{\"gear\":\"Armor\",\"rank\":\"Epic\",\"set\":\"SpeedSet\",\"level\":67,\"enhance\":15,\"main\":{\"type\":\"Defense\",\"value\":250},\"substats\":[{\"type\":\"HealthPercent\",\"value\":12},{\"type\":\"DefensePercent\",\"value\":21},{\"type\":\"Speed\",\"value\":10},{\"type\":\"CriticalHitChancePercent\",\"value\":4}],\"name\":\"AzimanusFightersArmor\",\"augmentedStats\":{\"mainType\":\"Defense\",\"mainValue\":250,\"HealthPercent\":12,\"DefensePercent\":21,\"Speed\":10,\"CriticalHitChancePercent\":4},\"id\":12},{\"gear\":\"Armor\",\"rank\":\"Epic\",\"set\":\"CriticalSet\",\"level\":67,\"enhance\":15,\"main\":{\"type\":\"Defense\",\"value\":250},\"substats\":[{\"type\":\"CriticalHitChancePercent\",\"value\":8},{\"type\":\"DefensePercent\",\"value\":12},{\"type\":\"HealthPercent\",\"value\":11},{\"type\":\"CriticalHitDamagePercent\",\"value\":11}],\"name\":\"ArahakansChestplate\",\"augmentedStats\":{\"mainType\":\"Defense\",\"mainValue\":250,\"CriticalHitChancePercent\":8,\"DefensePercent\":12,\"HealthPercent\":11,\"CriticalHitDamagePercent\":11},\"id\":13},{\"gear\":\"Armor\",\"rank\":\"Epic\",\"set\":\"SpeedSet\",\"level\":85,\"enhance\":15,\"main\":{\"type\":\"Defense\",\"value\":300},\"substats\":[{\"type\":\"CriticalHitDamagePercent\",\"value\":9},{\"type\":\"CriticalHitChancePercent\",\"value\":9},{\"type\":\"DefensePercent\",\"value\":12},{\"type\":\"EffectivenessPercent\",\"value\":18}],\"name\":\"Corimescent\",\"augmentedStats\":{\"mainType\":\"Defense\",\"mainValue\":300,\"CriticalHitDamagePercent\":9,\"CriticalHitChancePercent\":9,\"DefensePercent\":12,\"EffectivenessPercent\":18},\"id\":14},{\"gear\":\"Armor\",\"rank\":\"Epic\",\"set\":\"ImmunitySet\",\"level\":85,\"enhance\":15,\"main\":{\"type\":\"Defense\",\"value\":300},\"substats\":[{\"type\":\"Speed\",\"value\":7},{\"type\":\"CriticalHitChancePercent\",\"value\":7},{\"type\":\"CriticalHitDamagePercent\",\"value\":13},{\"type\":\"EffectivenessPercent\",\"value\":17}],\"name\":\"Corimescent\",\"augmentedStats\":{\"mainType\":\"Defense\",\"mainValue\":300,\"Speed\":7,\"CriticalHitChancePercent\":7,\"CriticalHitDamagePercent\":13,\"EffectivenessPercent\":17},\"id\":15},{\"gear\":\"Necklace\",\"rank\":\"Epic\",\"set\":\"HealthSet\",\"level\":78,\"enhance\":15,\"main\":{\"type\":\"HealthPercent\",\"value\":60},\"substats\":[{\"type\":\"DefensePercent\",\"value\":12},{\"type\":\"CriticalHitChancePercent\",\"value\":10},{\"type\":\"Speed\",\"value\":6},{\"type\":\"EffectResistancePercent\",\"value\":19}],\"name\":\"ConstellasPearlNecklace\",\"augmentedStats\":{\"mainType\":\"HealthPercent\",\"mainValue\":60,\"DefensePercent\":12,\"CriticalHitChancePercent\":10,\"Speed\":6,\"EffectResistancePercent\":19},\"id\":16},{\"gear\":\"Necklace\",\"rank\":\"Epic\",\"set\":\"SpeedSet\",\"level\":71,\"enhance\":15,\"main\":{\"type\":\"HealthPercent\",\"value\":50},\"substats\":[{\"type\":\"DefensePercent\",\"value\":15},{\"type\":\"Speed\",\"value\":5},{\"type\":\"CriticalHitChancePercent\",\"value\":10},{\"type\":\"EffectivenessPercent\",\"value\":6}],\"name\":\"PendantofLuminescence\",\"augmentedStats\":{\"mainType\":\"HealthPercent\",\"mainValue\":50,\"DefensePercent\":15,\"Speed\":5,\"CriticalHitChancePercent\":10,\"EffectivenessPercent\":6},\"id\":17},{\"gear\":\"Necklace\",\"rank\":\"Epic\",\"set\":\"AttackSet\",\"level\":65,\"enhance\":15,\"main\":{\"type\":\"CriticalHitChancePercent\",\"value\":45},\"substats\":[{\"type\":\"Speed\",\"value\":13},{\"type\":\"AttackPercent\",\"value\":5},{\"type\":\"HealthPercent\",\"value\":4},{\"type\":\"EffectivenessPercent\",\"value\":13}],\"name\":\"TreasureCollectorsCharm\",\"augmentedStats\":{\"mainType\":\"CriticalHitChancePercent\",\"mainValue\":45,\"Speed\":13,\"AttackPercent\":5,\"HealthPercent\":4,\"EffectivenessPercent\":13},\"id\":18},{\"gear\":\"Necklace\",\"rank\":\"Epic\",\"set\":\"ResistSet\",\"level\":85,\"enhance\":15,\"main\":{\"type\":\"CriticalHitDamagePercent\",\"value\":65},\"substats\":[{\"type\":\"AttackPercent\",\"value\":14},{\"type\":\"CriticalHitChancePercent\",\"value\":21},{\"type\":\"EffectivenessPercent\",\"value\":4},{\"type\":\"HealthPercent\",\"value\":5}],\"name\":\"ObsidianAmulet\",\"augmentedStats\":{\"mainType\":\"CriticalHitDamagePercent\",\"mainValue\":65,\"AttackPercent\":14,\"CriticalHitChancePercent\":21,\"EffectivenessPercent\":4,\"HealthPercent\":5},\"id\":19},{\"gear\":\"Necklace\",\"rank\":\"Epic\",\"set\":\"CriticalSet\",\"level\":65,\"enhance\":15,\"main\":{\"type\":\"CriticalHitDamagePercent\",\"value\":65},\"substats\":[{\"type\":\"CriticalHitChancePercent\",\"value\":8},{\"type\":\"Speed\",\"value\":14},{\"type\":\"Attack\",\"value\":29},{\"type\":\"AttackPercent\",\"value\":6}],\"name\":\"BoldGeneralsNecklace\",\"augmentedStats\":{\"mainType\":\"CriticalHitDamagePercent\",\"mainValue\":65,\"CriticalHitChancePercent\":8,\"Speed\":14,\"Attack\":29,\"AttackPercent\":6},\"id\":20},{\"gear\":\"Ring\",\"rank\":\"Epic\",\"set\":\"DefenseSet\",\"level\":71,\"enhance\":15,\"main\":{\"type\":\"DefensePercent\",\"value\":50},\"substats\":[{\"type\":\"HealthPercent\",\"value\":11},{\"type\":\"Speed\",\"value\":11},{\"type\":\"CriticalHitChancePercent\",\"value\":4},{\"type\":\"EffectResistancePercent\",\"value\":6}],\"name\":\"OathRing\",\"augmentedStats\":{\"mainType\":\"DefensePercent\",\"mainValue\":50,\"HealthPercent\":11,\"Speed\":11,\"CriticalHitChancePercent\":4,\"EffectResistancePercent\":6},\"id\":21},{\"gear\":\"Ring\",\"rank\":\"Epic\",\"set\":\"LifestealSet\",\"level\":85,\"enhance\":15,\"main\":{\"type\":\"AttackPercent\",\"value\":60},\"substats\":[{\"type\":\"HealthPercent\",\"value\":12},{\"type\":\"Speed\",\"value\":4},{\"type\":\"CriticalHitChancePercent\",\"value\":12},{\"type\":\"EffectivenessPercent\",\"value\":18}],\"name\":\"GaveleetsRing\",\"augmentedStats\":{\"mainType\":\"AttackPercent\",\"mainValue\":60,\"HealthPercent\":12,\"Speed\":4,\"CriticalHitChancePercent\":12,\"EffectivenessPercent\":18},\"id\":22},{\"gear\":\"Ring\",\"rank\":\"Epic\",\"set\":\"SpeedSet\",\"level\":71,\"enhance\":15,\"main\":{\"type\":\"HealthPercent\",\"value\":50},\"substats\":[{\"type\":\"DefensePercent\",\"value\":14},{\"type\":\"Speed\",\"value\":5},{\"type\":\"CriticalHitChancePercent\",\"value\":7},{\"type\":\"EffectResistancePercent\",\"value\":9}],\"name\":\"LightofaMillion\",\"augmentedStats\":{\"mainType\":\"HealthPercent\",\"mainValue\":50,\"DefensePercent\":14,\"Speed\":5,\"CriticalHitChancePercent\":7,\"EffectResistancePercent\":9},\"id\":23},{\"gear\":\"Ring\",\"rank\":\"Epic\",\"set\":\"DefenseSet\",\"level\":88,\"enhance\":15,\"main\":{\"type\":\"EffectivenessPercent\",\"value\":65},\"substats\":[{\"type\":\"CriticalHitChancePercent\",\"value\":9},{\"type\":\"CriticalHitDamagePercent\",\"value\":18},{\"type\":\"DefensePercent\",\"value\":19},{\"type\":\"AttackPercent\",\"value\":9}],\"name\":\"GreaterAzimanusFightersRing\",\"augmentedStats\":{\"mainType\":\"EffectivenessPercent\",\"mainValue\":65,\"CriticalHitChancePercent\":9,\"CriticalHitDamagePercent\":18,\"DefensePercent\":19,\"AttackPercent\":9},\"id\":24},{\"gear\":\"Ring\",\"rank\":\"Epic\",\"set\":\"SpeedSet\",\"level\":65,\"enhance\":15,\"main\":{\"type\":\"EffectResistancePercent\",\"value\":50},\"substats\":[{\"type\":\"CriticalHitDamagePercent\",\"value\":11},{\"type\":\"HealthPercent\",\"value\":5},{\"type\":\"DefensePercent\",\"value\":7},{\"type\":\"Speed\",\"value\":8}],\"name\":\"EmergencyRing\",\"augmentedStats\":{\"mainType\":\"EffectResistancePercent\",\"mainValue\":50,\"CriticalHitDamagePercent\":11,\"HealthPercent\":5,\"DefensePercent\":7,\"Speed\":8},\"id\":25},{\"gear\":\"Ring\",\"rank\":\"Epic\",\"set\":\"DefenseSet\",\"level\":88,\"enhance\":15,\"main\":{\"type\":\"AttackPercent\",\"value\":65},\"substats\":[{\"type\":\"Speed\",\"value\":3},{\"type\":\"DefensePercent\",\"value\":18},{\"type\":\"CriticalHitDamagePercent\",\"value\":21},{\"type\":\"Attack\",\"value\":51}],\"name\":\"GreaterAzimanusFightersRing\",\"augmentedStats\":{\"mainType\":\"AttackPercent\",\"mainValue\":65,\"Speed\":3,\"DefensePercent\":18,\"CriticalHitDamagePercent\":21,\"Attack\":51},\"id\":26},{\"gear\":\"Boots\",\"rank\":\"Epic\",\"set\":\"CriticalSet\",\"level\":77,\"enhance\":15,\"main\":{\"type\":\"AttackPercent\",\"value\":60},\"substats\":[{\"type\":\"HealthPercent\",\"value\":7},{\"type\":\"CriticalHitChancePercent\",\"value\":12},{\"type\":\"CriticalHitDamagePercent\",\"value\":6},{\"type\":\"EffectivenessPercent\",\"value\":17}],\"name\":\"VerdantBoots\",\"augmentedStats\":{\"mainType\":\"AttackPercent\",\"mainValue\":60,\"HealthPercent\":7,\"CriticalHitChancePercent\":12,\"CriticalHitDamagePercent\":6,\"EffectivenessPercent\":17},\"id\":27},{\"gear\":\"Boots\",\"rank\":\"Epic\",\"set\":\"SpeedSet\",\"level\":71,\"enhance\":15,\"main\":{\"type\":\"Speed\",\"value\":35},\"substats\":[{\"type\":\"HealthPercent\",\"value\":6},{\"type\":\"AttackPercent\",\"value\":19},{\"type\":\"DefensePercent\",\"value\":12},{\"type\":\"CriticalHitChancePercent\",\"value\":8}],\"name\":\"SocksofSmallMiracles\",\"augmentedStats\":{\"mainType\":\"Speed\",\"mainValue\":35,\"HealthPercent\":6,\"AttackPercent\":19,\"DefensePercent\":12,\"CriticalHitChancePercent\":8},\"id\":28},{\"gear\":\"Boots\",\"rank\":\"Epic\",\"set\":\"SpeedSet\",\"level\":85,\"enhance\":15,\"main\":{\"type\":\"HealthPercent\",\"value\":60},\"substats\":[{\"type\":\"EffectResistancePercent\",\"value\":7},{\"type\":\"DefensePercent\",\"value\":12},{\"type\":\"Speed\",\"value\":8},{\"type\":\"CriticalHitChancePercent\",\"value\":11}],\"name\":\"AbyssDrakeBoots\",\"augmentedStats\":{\"mainType\":\"HealthPercent\",\"mainValue\":60,\"EffectResistancePercent\":7,\"DefensePercent\":12,\"Speed\":8,\"CriticalHitChancePercent\":11},\"id\":29},{\"gear\":\"Boots\",\"rank\":\"Epic\",\"set\":\"SpeedSet\",\"level\":85,\"enhance\":15,\"main\":{\"type\":\"Speed\",\"value\":40},\"substats\":[{\"type\":\"AttackPercent\",\"value\":6},{\"type\":\"EffectivenessPercent\",\"value\":14},{\"type\":\"EffectResistancePercent\",\"value\":28},{\"type\":\"HealthPercent\",\"value\":13}],\"name\":\"PracticalBoots\",\"augmentedStats\":{\"mainType\":\"Speed\",\"mainValue\":40,\"AttackPercent\":6,\"EffectivenessPercent\":14,\"EffectResistancePercent\":28,\"HealthPercent\":13},\"id\":30},{\"gear\":\"Boots\",\"rank\":\"Epic\",\"set\":\"SpeedSet\",\"level\":85,\"enhance\":15,\"main\":{\"type\":\"Speed\",\"value\":40},\"substats\":[{\"type\":\"EffectResistancePercent\",\"value\":17},{\"type\":\"DefensePercent\",\"value\":17},{\"type\":\"Attack\",\"value\":43},{\"type\":\"CriticalHitChancePercent\",\"value\":8}],\"name\":\"PracticalBoots\",\"augmentedStats\":{\"mainType\":\"Speed\",\"mainValue\":40,\"EffectResistancePercent\":17,\"DefensePercent\":17,\"Attack\":43,\"CriticalHitChancePercent\":8},\"id\":31}],\"inputAllowLockedItems\":false,\"inputAllowEquippedItems\":false,\"inputKeepCurrentItems\":false,\"inputSets\":[[\"SpeedSet\"],[],[]],\"inputSetsOne\":[\"ImmunitySet\"],\"inputSetsTwo\":[\"ImmunitySet\"],\"inputSetsThree\":[\"ImmunitySet\"],\"inputAllowBrokenSets\":false,\"setFormat\":5,\"atk\":576,\"hp\":5700,\"def\":743,\"cr\":15,\"cd\":150,\"eff\":0,\"res\":0,\"spd\":88,\"dac\":5}"; + // 400 set +// private static final String REQUEST_STRING = "{\"base\":{\"atk\":576,\"hp\":5700,\"def\":743,\"cr\":15,\"cd\":150,\"eff\":0,\"res\":0,\"spd\":88,\"dac\":5},\"requestType\":\"OptimizationRequest\",\"extraField\":\"asdf\",\"items\":[{\"gear\":\"Weapon\",\"rank\":\"Heroic\",\"set\":\"HealthSet\",\"level\":85,\"enhance\":15,\"main\":{\"type\":\"Attack\",\"value\":500},\"substats\":[{\"type\":\"EffectivenessPercent\",\"value\":4},{\"type\":\"HealthPercent\",\"value\":27},{\"type\":\"AttackPercent\",\"value\":14},{\"type\":\"Health\",\"value\":178}],\"name\":\"DarkSteelSaber\",\"augmentedStats\":{\"mainType\":\"Attack\",\"mainValue\":500,\"EffectivenessPercent\":4,\"HealthPercent\":27,\"AttackPercent\":14,\"Health\":178},\"id\":0},{\"gear\":\"Weapon\",\"rank\":\"Epic\",\"set\":\"HealthSet\",\"level\":88,\"enhance\":15,\"main\":{\"type\":\"Attack\",\"value\":515},\"substats\":[{\"type\":\"Health\",\"value\":214},{\"type\":\"HealthPercent\",\"value\":25},{\"type\":\"CriticalHitDamagePercent\",\"value\":4},{\"type\":\"Speed\",\"value\":9}],\"name\":\"ArahakansFang\",\"augmentedStats\":{\"mainType\":\"Attack\",\"mainValue\":515,\"Health\":214,\"HealthPercent\":25,\"CriticalHitDamagePercent\":4,\"Speed\":9},\"id\":1},{\"gear\":\"Weapon\",\"rank\":\"Epic\",\"set\":\"RageSet\",\"level\":71,\"enhance\":15,\"main\":{\"type\":\"Attack\",\"value\":440},\"substats\":[{\"type\":\"AttackPercent\",\"value\":10},{\"type\":\"Speed\",\"value\":7},{\"type\":\"CriticalHitChancePercent\",\"value\":7},{\"type\":\"CriticalHitDamagePercent\",\"value\":9}],\"name\":\"ThornVineWhip\",\"augmentedStats\":{\"mainType\":\"Attack\",\"mainValue\":440,\"AttackPercent\":10,\"Speed\":7,\"CriticalHitChancePercent\":7,\"CriticalHitDamagePercent\":9},\"id\":2},{\"gear\":\"Weapon\",\"rank\":\"Epic\",\"set\":\"SpeedSet\",\"level\":85,\"enhance\":15,\"main\":{\"type\":\"Attack\",\"value\":500},\"substats\":[{\"type\":\"CriticalHitDamagePercent\",\"value\":15},{\"type\":\"Speed\",\"value\":6},{\"type\":\"CriticalHitChancePercent\",\"value\":10},{\"type\":\"AttackPercent\",\"value\":7}],\"name\":\"AbyssDrakeBonesword\",\"augmentedStats\":{\"mainType\":\"Attack\",\"mainValue\":500,\"CriticalHitDamagePercent\":15,\"Speed\":6,\"CriticalHitChancePercent\":10,\"AttackPercent\":7},\"id\":3},{\"gear\":\"Weapon\",\"rank\":\"Epic\",\"set\":\"CriticalSet\",\"level\":70,\"enhance\":15,\"main\":{\"type\":\"Attack\",\"value\":440},\"substats\":[{\"type\":\"CriticalHitChancePercent\",\"value\":6},{\"type\":\"CriticalHitDamagePercent\",\"value\":11},{\"type\":\"EffectResistancePercent\",\"value\":12},{\"type\":\"AttackPercent\",\"value\":20}],\"name\":\"ManaDrakeBonesword\",\"augmentedStats\":{\"mainType\":\"Attack\",\"mainValue\":440,\"CriticalHitChancePercent\":6,\"CriticalHitDamagePercent\":11,\"EffectResistancePercent\":12,\"AttackPercent\":20},\"id\":4},{\"gear\":\"Helmet\",\"rank\":\"Epic\",\"set\":\"SpeedSet\",\"level\":71,\"enhance\":15,\"main\":{\"type\":\"Health\",\"value\":2360},\"substats\":[{\"type\":\"HealthPercent\",\"value\":12},{\"type\":\"AttackPercent\",\"value\":11},{\"type\":\"DefensePercent\",\"value\":18},{\"type\":\"Speed\",\"value\":3}],\"name\":\"RoseCoronet\",\"augmentedStats\":{\"mainType\":\"Health\",\"mainValue\":2360,\"HealthPercent\":12,\"AttackPercent\":11,\"DefensePercent\":18,\"Speed\":3},\"id\":5},{\"gear\":\"Helmet\",\"rank\":\"Epic\",\"set\":\"SpeedSet\",\"level\":85,\"enhance\":15,\"main\":{\"type\":\"Health\",\"value\":2700},\"substats\":[{\"type\":\"CriticalHitChancePercent\",\"value\":6},{\"type\":\"AttackPercent\",\"value\":4},{\"type\":\"EffectivenessPercent\",\"value\":9},{\"type\":\"HealthPercent\",\"value\":26}],\"name\":\"AbyssDrakeMask\",\"augmentedStats\":{\"mainType\":\"Health\",\"mainValue\":2700,\"CriticalHitChancePercent\":6,\"AttackPercent\":4,\"EffectivenessPercent\":9,\"HealthPercent\":26},\"id\":6},{\"gear\":\"Helmet\",\"rank\":\"Epic\",\"set\":\"SpeedSet\",\"level\":88,\"enhance\":15,\"main\":{\"type\":\"Health\",\"value\":2765},\"substats\":[{\"type\":\"HealthPercent\",\"value\":17},{\"type\":\"DefensePercent\",\"value\":14},{\"type\":\"Speed\",\"value\":6},{\"type\":\"EffectResistancePercent\",\"value\":6}],\"name\":\"GladiatorsHelmofVictory\",\"augmentedStats\":{\"mainType\":\"Health\",\"mainValue\":2765,\"HealthPercent\":17,\"DefensePercent\":14,\"Speed\":6,\"EffectResistancePercent\":6},\"id\":7},{\"gear\":\"Helmet\",\"rank\":\"Epic\",\"set\":\"AttackSet\",\"level\":70,\"enhance\":15,\"main\":{\"type\":\"Health\",\"value\":2360},\"substats\":[{\"type\":\"AttackPercent\",\"value\":13},{\"type\":\"Speed\",\"value\":9},{\"type\":\"CriticalHitChancePercent\",\"value\":7},{\"type\":\"CriticalHitDamagePercent\",\"value\":9}],\"name\":\"TerrariaHelm\",\"augmentedStats\":{\"mainType\":\"Health\",\"mainValue\":2360,\"AttackPercent\":13,\"Speed\":9,\"CriticalHitChancePercent\":7,\"CriticalHitDamagePercent\":9},\"id\":8},{\"gear\":\"Helmet\",\"rank\":\"Epic\",\"set\":\"DefenseSet\",\"level\":88,\"enhance\":15,\"main\":{\"type\":\"Health\",\"value\":2765},\"substats\":[{\"type\":\"DefensePercent\",\"value\":7},{\"type\":\"Defense\",\"value\":34},{\"type\":\"AttackPercent\",\"value\":14},{\"type\":\"HealthPercent\",\"value\":31}],\"name\":\"KarkanissDecisionHelm\",\"augmentedStats\":{\"mainType\":\"Health\",\"mainValue\":2765,\"DefensePercent\":7,\"Defense\":34,\"AttackPercent\":14,\"HealthPercent\":31},\"id\":9},{\"gear\":\"Helmet\",\"rank\":\"Epic\",\"set\":\"ImmunitySet\",\"level\":67,\"enhance\":15,\"main\":{\"type\":\"Health\",\"value\":2295},\"substats\":[{\"type\":\"HealthPercent\",\"value\":6},{\"type\":\"CriticalHitDamagePercent\",\"value\":10},{\"type\":\"AttackPercent\",\"value\":14},{\"type\":\"CriticalHitChancePercent\",\"value\":7}],\"name\":\"KarkanissDecisionHelm\",\"augmentedStats\":{\"mainType\":\"Health\",\"mainValue\":2295,\"HealthPercent\":6,\"CriticalHitDamagePercent\":10,\"AttackPercent\":14,\"CriticalHitChancePercent\":7},\"id\":10},{\"gear\":\"Armor\",\"rank\":\"Epic\",\"set\":\"AttackSet\",\"level\":71,\"enhance\":15,\"main\":{\"type\":\"Defense\",\"value\":260},\"substats\":[{\"type\":\"HealthPercent\",\"value\":13},{\"type\":\"Speed\",\"value\":12},{\"type\":\"CriticalHitChancePercent\",\"value\":8},{\"type\":\"CriticalHitDamagePercent\",\"value\":6}],\"name\":\"AncientShandranWarriorsArmor\",\"augmentedStats\":{\"mainType\":\"Defense\",\"mainValue\":260,\"HealthPercent\":13,\"Speed\":12,\"CriticalHitChancePercent\":8,\"CriticalHitDamagePercent\":6},\"id\":11},{\"gear\":\"Armor\",\"rank\":\"Epic\",\"set\":\"SpeedSet\",\"level\":67,\"enhance\":15,\"main\":{\"type\":\"Defense\",\"value\":250},\"substats\":[{\"type\":\"HealthPercent\",\"value\":12},{\"type\":\"DefensePercent\",\"value\":21},{\"type\":\"Speed\",\"value\":10},{\"type\":\"CriticalHitChancePercent\",\"value\":4}],\"name\":\"AzimanusFightersArmor\",\"augmentedStats\":{\"mainType\":\"Defense\",\"mainValue\":250,\"HealthPercent\":12,\"DefensePercent\":21,\"Speed\":10,\"CriticalHitChancePercent\":4},\"id\":12},{\"gear\":\"Armor\",\"rank\":\"Epic\",\"set\":\"CriticalSet\",\"level\":67,\"enhance\":15,\"main\":{\"type\":\"Defense\",\"value\":250},\"substats\":[{\"type\":\"CriticalHitChancePercent\",\"value\":8},{\"type\":\"DefensePercent\",\"value\":12},{\"type\":\"HealthPercent\",\"value\":11},{\"type\":\"CriticalHitDamagePercent\",\"value\":11}],\"name\":\"ArahakansChestplate\",\"augmentedStats\":{\"mainType\":\"Defense\",\"mainValue\":250,\"CriticalHitChancePercent\":8,\"DefensePercent\":12,\"HealthPercent\":11,\"CriticalHitDamagePercent\":11},\"id\":13},{\"gear\":\"Armor\",\"rank\":\"Epic\",\"set\":\"SpeedSet\",\"level\":85,\"enhance\":15,\"main\":{\"type\":\"Defense\",\"value\":300},\"substats\":[{\"type\":\"CriticalHitDamagePercent\",\"value\":9},{\"type\":\"CriticalHitChancePercent\",\"value\":9},{\"type\":\"DefensePercent\",\"value\":12},{\"type\":\"EffectivenessPercent\",\"value\":18}],\"name\":\"Corimescent\",\"augmentedStats\":{\"mainType\":\"Defense\",\"mainValue\":300,\"CriticalHitDamagePercent\":9,\"CriticalHitChancePercent\":9,\"DefensePercent\":12,\"EffectivenessPercent\":18},\"id\":14},{\"gear\":\"Armor\",\"rank\":\"Epic\",\"set\":\"ImmunitySet\",\"level\":85,\"enhance\":15,\"main\":{\"type\":\"Defense\",\"value\":300},\"substats\":[{\"type\":\"Speed\",\"value\":7},{\"type\":\"CriticalHitChancePercent\",\"value\":7},{\"type\":\"CriticalHitDamagePercent\",\"value\":13},{\"type\":\"EffectivenessPercent\",\"value\":17}],\"name\":\"Corimescent\",\"augmentedStats\":{\"mainType\":\"Defense\",\"mainValue\":300,\"Speed\":7,\"CriticalHitChancePercent\":7,\"CriticalHitDamagePercent\":13,\"EffectivenessPercent\":17},\"id\":15},{\"gear\":\"Necklace\",\"rank\":\"Epic\",\"set\":\"HealthSet\",\"level\":78,\"enhance\":15,\"main\":{\"type\":\"HealthPercent\",\"value\":60},\"substats\":[{\"type\":\"DefensePercent\",\"value\":12},{\"type\":\"CriticalHitChancePercent\",\"value\":10},{\"type\":\"Speed\",\"value\":6},{\"type\":\"EffectResistancePercent\",\"value\":19}],\"name\":\"ConstellasPearlNecklace\",\"augmentedStats\":{\"mainType\":\"HealthPercent\",\"mainValue\":60,\"DefensePercent\":12,\"CriticalHitChancePercent\":10,\"Speed\":6,\"EffectResistancePercent\":19},\"id\":16},{\"gear\":\"Necklace\",\"rank\":\"Epic\",\"set\":\"SpeedSet\",\"level\":71,\"enhance\":15,\"main\":{\"type\":\"HealthPercent\",\"value\":50},\"substats\":[{\"type\":\"DefensePercent\",\"value\":15},{\"type\":\"Speed\",\"value\":5},{\"type\":\"CriticalHitChancePercent\",\"value\":10},{\"type\":\"EffectivenessPercent\",\"value\":6}],\"name\":\"PendantofLuminescence\",\"augmentedStats\":{\"mainType\":\"HealthPercent\",\"mainValue\":50,\"DefensePercent\":15,\"Speed\":5,\"CriticalHitChancePercent\":10,\"EffectivenessPercent\":6},\"id\":17},{\"gear\":\"Necklace\",\"rank\":\"Epic\",\"set\":\"AttackSet\",\"level\":65,\"enhance\":15,\"main\":{\"type\":\"CriticalHitChancePercent\",\"value\":45},\"substats\":[{\"type\":\"Speed\",\"value\":13},{\"type\":\"AttackPercent\",\"value\":5},{\"type\":\"HealthPercent\",\"value\":4},{\"type\":\"EffectivenessPercent\",\"value\":13}],\"name\":\"TreasureCollectorsCharm\",\"augmentedStats\":{\"mainType\":\"CriticalHitChancePercent\",\"mainValue\":45,\"Speed\":13,\"AttackPercent\":5,\"HealthPercent\":4,\"EffectivenessPercent\":13},\"id\":18},{\"gear\":\"Necklace\",\"rank\":\"Epic\",\"set\":\"ResistSet\",\"level\":85,\"enhance\":15,\"main\":{\"type\":\"CriticalHitDamagePercent\",\"value\":65},\"substats\":[{\"type\":\"AttackPercent\",\"value\":14},{\"type\":\"CriticalHitChancePercent\",\"value\":21},{\"type\":\"EffectivenessPercent\",\"value\":4},{\"type\":\"HealthPercent\",\"value\":5}],\"name\":\"ObsidianAmulet\",\"augmentedStats\":{\"mainType\":\"CriticalHitDamagePercent\",\"mainValue\":65,\"AttackPercent\":14,\"CriticalHitChancePercent\":21,\"EffectivenessPercent\":4,\"HealthPercent\":5},\"id\":19},{\"gear\":\"Necklace\",\"rank\":\"Epic\",\"set\":\"CriticalSet\",\"level\":65,\"enhance\":15,\"main\":{\"type\":\"CriticalHitDamagePercent\",\"value\":65},\"substats\":[{\"type\":\"CriticalHitChancePercent\",\"value\":8},{\"type\":\"Speed\",\"value\":14},{\"type\":\"Attack\",\"value\":29},{\"type\":\"AttackPercent\",\"value\":6}],\"name\":\"BoldGeneralsNecklace\",\"augmentedStats\":{\"mainType\":\"CriticalHitDamagePercent\",\"mainValue\":65,\"CriticalHitChancePercent\":8,\"Speed\":14,\"Attack\":29,\"AttackPercent\":6},\"id\":20},{\"gear\":\"Ring\",\"rank\":\"Epic\",\"set\":\"DefenseSet\",\"level\":71,\"enhance\":15,\"main\":{\"type\":\"DefensePercent\",\"value\":50},\"substats\":[{\"type\":\"HealthPercent\",\"value\":11},{\"type\":\"Speed\",\"value\":11},{\"type\":\"CriticalHitChancePercent\",\"value\":4},{\"type\":\"EffectResistancePercent\",\"value\":6}],\"name\":\"OathRing\",\"augmentedStats\":{\"mainType\":\"DefensePercent\",\"mainValue\":50,\"HealthPercent\":11,\"Speed\":11,\"CriticalHitChancePercent\":4,\"EffectResistancePercent\":6},\"id\":21},{\"gear\":\"Ring\",\"rank\":\"Epic\",\"set\":\"LifestealSet\",\"level\":85,\"enhance\":15,\"main\":{\"type\":\"AttackPercent\",\"value\":60},\"substats\":[{\"type\":\"HealthPercent\",\"value\":12},{\"type\":\"Speed\",\"value\":4},{\"type\":\"CriticalHitChancePercent\",\"value\":12},{\"type\":\"EffectivenessPercent\",\"value\":18}],\"name\":\"GaveleetsRing\",\"augmentedStats\":{\"mainType\":\"AttackPercent\",\"mainValue\":60,\"HealthPercent\":12,\"Speed\":4,\"CriticalHitChancePercent\":12,\"EffectivenessPercent\":18},\"id\":22},{\"gear\":\"Ring\",\"rank\":\"Epic\",\"set\":\"SpeedSet\",\"level\":71,\"enhance\":15,\"main\":{\"type\":\"HealthPercent\",\"value\":50},\"substats\":[{\"type\":\"DefensePercent\",\"value\":14},{\"type\":\"Speed\",\"value\":5},{\"type\":\"CriticalHitChancePercent\",\"value\":7},{\"type\":\"EffectResistancePercent\",\"value\":9}],\"name\":\"LightofaMillion\",\"augmentedStats\":{\"mainType\":\"HealthPercent\",\"mainValue\":50,\"DefensePercent\":14,\"Speed\":5,\"CriticalHitChancePercent\":7,\"EffectResistancePercent\":9},\"id\":23},{\"gear\":\"Ring\",\"rank\":\"Epic\",\"set\":\"DefenseSet\",\"level\":88,\"enhance\":15,\"main\":{\"type\":\"EffectivenessPercent\",\"value\":65},\"substats\":[{\"type\":\"CriticalHitChancePercent\",\"value\":9},{\"type\":\"CriticalHitDamagePercent\",\"value\":18},{\"type\":\"DefensePercent\",\"value\":19},{\"type\":\"AttackPercent\",\"value\":9}],\"name\":\"GreaterAzimanusFightersRing\",\"augmentedStats\":{\"mainType\":\"EffectivenessPercent\",\"mainValue\":65,\"CriticalHitChancePercent\":9,\"CriticalHitDamagePercent\":18,\"DefensePercent\":19,\"AttackPercent\":9},\"id\":24},{\"gear\":\"Ring\",\"rank\":\"Epic\",\"set\":\"SpeedSet\",\"level\":65,\"enhance\":15,\"main\":{\"type\":\"EffectResistancePercent\",\"value\":50},\"substats\":[{\"type\":\"CriticalHitDamagePercent\",\"value\":11},{\"type\":\"HealthPercent\",\"value\":5},{\"type\":\"DefensePercent\",\"value\":7},{\"type\":\"Speed\",\"value\":8}],\"name\":\"EmergencyRing\",\"augmentedStats\":{\"mainType\":\"EffectResistancePercent\",\"mainValue\":50,\"CriticalHitDamagePercent\":11,\"HealthPercent\":5,\"DefensePercent\":7,\"Speed\":8},\"id\":25},{\"gear\":\"Ring\",\"rank\":\"Epic\",\"set\":\"DefenseSet\",\"level\":88,\"enhance\":15,\"main\":{\"type\":\"AttackPercent\",\"value\":65},\"substats\":[{\"type\":\"Speed\",\"value\":3},{\"type\":\"DefensePercent\",\"value\":18},{\"type\":\"CriticalHitDamagePercent\",\"value\":21},{\"type\":\"Attack\",\"value\":51}],\"name\":\"GreaterAzimanusFightersRing\",\"augmentedStats\":{\"mainType\":\"AttackPercent\",\"mainValue\":65,\"Speed\":3,\"DefensePercent\":18,\"CriticalHitDamagePercent\":21,\"Attack\":51},\"id\":26},{\"gear\":\"Boots\",\"rank\":\"Epic\",\"set\":\"CriticalSet\",\"level\":77,\"enhance\":15,\"main\":{\"type\":\"AttackPercent\",\"value\":60},\"substats\":[{\"type\":\"HealthPercent\",\"value\":7},{\"type\":\"CriticalHitChancePercent\",\"value\":12},{\"type\":\"CriticalHitDamagePercent\",\"value\":6},{\"type\":\"EffectivenessPercent\",\"value\":17}],\"name\":\"VerdantBoots\",\"augmentedStats\":{\"mainType\":\"AttackPercent\",\"mainValue\":60,\"HealthPercent\":7,\"CriticalHitChancePercent\":12,\"CriticalHitDamagePercent\":6,\"EffectivenessPercent\":17},\"id\":27},{\"gear\":\"Boots\",\"rank\":\"Epic\",\"set\":\"SpeedSet\",\"level\":71,\"enhance\":15,\"main\":{\"type\":\"Speed\",\"value\":35},\"substats\":[{\"type\":\"HealthPercent\",\"value\":6},{\"type\":\"AttackPercent\",\"value\":19},{\"type\":\"DefensePercent\",\"value\":12},{\"type\":\"CriticalHitChancePercent\",\"value\":8}],\"name\":\"SocksofSmallMiracles\",\"augmentedStats\":{\"mainType\":\"Speed\",\"mainValue\":35,\"HealthPercent\":6,\"AttackPercent\":19,\"DefensePercent\":12,\"CriticalHitChancePercent\":8},\"id\":28},{\"gear\":\"Boots\",\"rank\":\"Epic\",\"set\":\"SpeedSet\",\"level\":85,\"enhance\":15,\"main\":{\"type\":\"HealthPercent\",\"value\":60},\"substats\":[{\"type\":\"EffectResistancePercent\",\"value\":7},{\"type\":\"DefensePercent\",\"value\":12},{\"type\":\"Speed\",\"value\":8},{\"type\":\"CriticalHitChancePercent\",\"value\":11}],\"name\":\"AbyssDrakeBoots\",\"augmentedStats\":{\"mainType\":\"HealthPercent\",\"mainValue\":60,\"EffectResistancePercent\":7,\"DefensePercent\":12,\"Speed\":8,\"CriticalHitChancePercent\":11},\"id\":29},{\"gear\":\"Boots\",\"rank\":\"Epic\",\"set\":\"SpeedSet\",\"level\":85,\"enhance\":15,\"main\":{\"type\":\"Speed\",\"value\":40},\"substats\":[{\"type\":\"AttackPercent\",\"value\":6},{\"type\":\"EffectivenessPercent\",\"value\":14},{\"type\":\"EffectResistancePercent\",\"value\":28},{\"type\":\"HealthPercent\",\"value\":13}],\"name\":\"PracticalBoots\",\"augmentedStats\":{\"mainType\":\"Speed\",\"mainValue\":40,\"AttackPercent\":6,\"EffectivenessPercent\":14,\"EffectResistancePercent\":28,\"HealthPercent\":13},\"id\":30},{\"gear\":\"Boots\",\"rank\":\"Epic\",\"set\":\"SpeedSet\",\"level\":85,\"enhance\":15,\"main\":{\"type\":\"Speed\",\"value\":40},\"substats\":[{\"type\":\"EffectResistancePercent\",\"value\":17},{\"type\":\"DefensePercent\",\"value\":17},{\"type\":\"Attack\",\"value\":43},{\"type\":\"CriticalHitChancePercent\",\"value\":8}],\"name\":\"PracticalBoots\",\"augmentedStats\":{\"mainType\":\"Speed\",\"mainValue\":40,\"EffectResistancePercent\":17,\"DefensePercent\":17,\"Attack\":43,\"CriticalHitChancePercent\":8},\"id\":31}],\"inputAllowLockedItems\":false,\"inputAllowEquippedItems\":false,\"inputKeepCurrentItems\":false,\"inputSets\":[[\"SpeedSet\"],[],[]],\"inputSetsOne\":[\"SpeedSet\", \"AttackSet\"],\"inputSetsTwo\":[],\"inputSetsThree\":[],\"inputAllowBrokenSets\":false,\"setFormat\":2,\"atk\":576,\"hp\":5700,\"def\":743,\"cr\":15,\"cd\":150,\"eff\":0,\"res\":0,\"spd\":88,\"dac\":5}"; + // 200 set +// private static final String REQUEST_STRING = "{\"base\":{\"atk\":576,\"hp\":5700,\"def\":743,\"cr\":15,\"cd\":150,\"eff\":0,\"res\":0,\"spd\":88,\"dac\":5},\"requestType\":\"OptimizationRequest\",\"extraField\":\"asdf\",\"items\":[{\"gear\":\"Weapon\",\"rank\":\"Heroic\",\"set\":\"HealthSet\",\"level\":85,\"enhance\":15,\"main\":{\"type\":\"Attack\",\"value\":500},\"substats\":[{\"type\":\"EffectivenessPercent\",\"value\":4},{\"type\":\"HealthPercent\",\"value\":27},{\"type\":\"AttackPercent\",\"value\":14},{\"type\":\"Health\",\"value\":178}],\"name\":\"DarkSteelSaber\",\"augmentedStats\":{\"mainType\":\"Attack\",\"mainValue\":500,\"EffectivenessPercent\":4,\"HealthPercent\":27,\"AttackPercent\":14,\"Health\":178},\"id\":0},{\"gear\":\"Weapon\",\"rank\":\"Epic\",\"set\":\"HealthSet\",\"level\":88,\"enhance\":15,\"main\":{\"type\":\"Attack\",\"value\":515},\"substats\":[{\"type\":\"Health\",\"value\":214},{\"type\":\"HealthPercent\",\"value\":25},{\"type\":\"CriticalHitDamagePercent\",\"value\":4},{\"type\":\"Speed\",\"value\":9}],\"name\":\"ArahakansFang\",\"augmentedStats\":{\"mainType\":\"Attack\",\"mainValue\":515,\"Health\":214,\"HealthPercent\":25,\"CriticalHitDamagePercent\":4,\"Speed\":9},\"id\":1},{\"gear\":\"Weapon\",\"rank\":\"Epic\",\"set\":\"RageSet\",\"level\":71,\"enhance\":15,\"main\":{\"type\":\"Attack\",\"value\":440},\"substats\":[{\"type\":\"AttackPercent\",\"value\":10},{\"type\":\"Speed\",\"value\":7},{\"type\":\"CriticalHitChancePercent\",\"value\":7},{\"type\":\"CriticalHitDamagePercent\",\"value\":9}],\"name\":\"ThornVineWhip\",\"augmentedStats\":{\"mainType\":\"Attack\",\"mainValue\":440,\"AttackPercent\":10,\"Speed\":7,\"CriticalHitChancePercent\":7,\"CriticalHitDamagePercent\":9},\"id\":2},{\"gear\":\"Weapon\",\"rank\":\"Epic\",\"set\":\"SpeedSet\",\"level\":85,\"enhance\":15,\"main\":{\"type\":\"Attack\",\"value\":500},\"substats\":[{\"type\":\"CriticalHitDamagePercent\",\"value\":15},{\"type\":\"Speed\",\"value\":6},{\"type\":\"CriticalHitChancePercent\",\"value\":10},{\"type\":\"AttackPercent\",\"value\":7}],\"name\":\"AbyssDrakeBonesword\",\"augmentedStats\":{\"mainType\":\"Attack\",\"mainValue\":500,\"CriticalHitDamagePercent\":15,\"Speed\":6,\"CriticalHitChancePercent\":10,\"AttackPercent\":7},\"id\":3},{\"gear\":\"Weapon\",\"rank\":\"Epic\",\"set\":\"CriticalSet\",\"level\":70,\"enhance\":15,\"main\":{\"type\":\"Attack\",\"value\":440},\"substats\":[{\"type\":\"CriticalHitChancePercent\",\"value\":6},{\"type\":\"CriticalHitDamagePercent\",\"value\":11},{\"type\":\"EffectResistancePercent\",\"value\":12},{\"type\":\"AttackPercent\",\"value\":20}],\"name\":\"ManaDrakeBonesword\",\"augmentedStats\":{\"mainType\":\"Attack\",\"mainValue\":440,\"CriticalHitChancePercent\":6,\"CriticalHitDamagePercent\":11,\"EffectResistancePercent\":12,\"AttackPercent\":20},\"id\":4},{\"gear\":\"Helmet\",\"rank\":\"Epic\",\"set\":\"SpeedSet\",\"level\":71,\"enhance\":15,\"main\":{\"type\":\"Health\",\"value\":2360},\"substats\":[{\"type\":\"HealthPercent\",\"value\":12},{\"type\":\"AttackPercent\",\"value\":11},{\"type\":\"DefensePercent\",\"value\":18},{\"type\":\"Speed\",\"value\":3}],\"name\":\"RoseCoronet\",\"augmentedStats\":{\"mainType\":\"Health\",\"mainValue\":2360,\"HealthPercent\":12,\"AttackPercent\":11,\"DefensePercent\":18,\"Speed\":3},\"id\":5},{\"gear\":\"Helmet\",\"rank\":\"Epic\",\"set\":\"SpeedSet\",\"level\":85,\"enhance\":15,\"main\":{\"type\":\"Health\",\"value\":2700},\"substats\":[{\"type\":\"CriticalHitChancePercent\",\"value\":6},{\"type\":\"AttackPercent\",\"value\":4},{\"type\":\"EffectivenessPercent\",\"value\":9},{\"type\":\"HealthPercent\",\"value\":26}],\"name\":\"AbyssDrakeMask\",\"augmentedStats\":{\"mainType\":\"Health\",\"mainValue\":2700,\"CriticalHitChancePercent\":6,\"AttackPercent\":4,\"EffectivenessPercent\":9,\"HealthPercent\":26},\"id\":6},{\"gear\":\"Helmet\",\"rank\":\"Epic\",\"set\":\"SpeedSet\",\"level\":88,\"enhance\":15,\"main\":{\"type\":\"Health\",\"value\":2765},\"substats\":[{\"type\":\"HealthPercent\",\"value\":17},{\"type\":\"DefensePercent\",\"value\":14},{\"type\":\"Speed\",\"value\":6},{\"type\":\"EffectResistancePercent\",\"value\":6}],\"name\":\"GladiatorsHelmofVictory\",\"augmentedStats\":{\"mainType\":\"Health\",\"mainValue\":2765,\"HealthPercent\":17,\"DefensePercent\":14,\"Speed\":6,\"EffectResistancePercent\":6},\"id\":7},{\"gear\":\"Helmet\",\"rank\":\"Epic\",\"set\":\"AttackSet\",\"level\":70,\"enhance\":15,\"main\":{\"type\":\"Health\",\"value\":2360},\"substats\":[{\"type\":\"AttackPercent\",\"value\":13},{\"type\":\"Speed\",\"value\":9},{\"type\":\"CriticalHitChancePercent\",\"value\":7},{\"type\":\"CriticalHitDamagePercent\",\"value\":9}],\"name\":\"TerrariaHelm\",\"augmentedStats\":{\"mainType\":\"Health\",\"mainValue\":2360,\"AttackPercent\":13,\"Speed\":9,\"CriticalHitChancePercent\":7,\"CriticalHitDamagePercent\":9},\"id\":8},{\"gear\":\"Helmet\",\"rank\":\"Epic\",\"set\":\"DefenseSet\",\"level\":88,\"enhance\":15,\"main\":{\"type\":\"Health\",\"value\":2765},\"substats\":[{\"type\":\"DefensePercent\",\"value\":7},{\"type\":\"Defense\",\"value\":34},{\"type\":\"AttackPercent\",\"value\":14},{\"type\":\"HealthPercent\",\"value\":31}],\"name\":\"KarkanissDecisionHelm\",\"augmentedStats\":{\"mainType\":\"Health\",\"mainValue\":2765,\"DefensePercent\":7,\"Defense\":34,\"AttackPercent\":14,\"HealthPercent\":31},\"id\":9},{\"gear\":\"Helmet\",\"rank\":\"Epic\",\"set\":\"ImmunitySet\",\"level\":67,\"enhance\":15,\"main\":{\"type\":\"Health\",\"value\":2295},\"substats\":[{\"type\":\"HealthPercent\",\"value\":6},{\"type\":\"CriticalHitDamagePercent\",\"value\":10},{\"type\":\"AttackPercent\",\"value\":14},{\"type\":\"CriticalHitChancePercent\",\"value\":7}],\"name\":\"KarkanissDecisionHelm\",\"augmentedStats\":{\"mainType\":\"Health\",\"mainValue\":2295,\"HealthPercent\":6,\"CriticalHitDamagePercent\":10,\"AttackPercent\":14,\"CriticalHitChancePercent\":7},\"id\":10},{\"gear\":\"Armor\",\"rank\":\"Epic\",\"set\":\"AttackSet\",\"level\":71,\"enhance\":15,\"main\":{\"type\":\"Defense\",\"value\":260},\"substats\":[{\"type\":\"HealthPercent\",\"value\":13},{\"type\":\"Speed\",\"value\":12},{\"type\":\"CriticalHitChancePercent\",\"value\":8},{\"type\":\"CriticalHitDamagePercent\",\"value\":6}],\"name\":\"AncientShandranWarriorsArmor\",\"augmentedStats\":{\"mainType\":\"Defense\",\"mainValue\":260,\"HealthPercent\":13,\"Speed\":12,\"CriticalHitChancePercent\":8,\"CriticalHitDamagePercent\":6},\"id\":11},{\"gear\":\"Armor\",\"rank\":\"Epic\",\"set\":\"SpeedSet\",\"level\":67,\"enhance\":15,\"main\":{\"type\":\"Defense\",\"value\":250},\"substats\":[{\"type\":\"HealthPercent\",\"value\":12},{\"type\":\"DefensePercent\",\"value\":21},{\"type\":\"Speed\",\"value\":10},{\"type\":\"CriticalHitChancePercent\",\"value\":4}],\"name\":\"AzimanusFightersArmor\",\"augmentedStats\":{\"mainType\":\"Defense\",\"mainValue\":250,\"HealthPercent\":12,\"DefensePercent\":21,\"Speed\":10,\"CriticalHitChancePercent\":4},\"id\":12},{\"gear\":\"Armor\",\"rank\":\"Epic\",\"set\":\"CriticalSet\",\"level\":67,\"enhance\":15,\"main\":{\"type\":\"Defense\",\"value\":250},\"substats\":[{\"type\":\"CriticalHitChancePercent\",\"value\":8},{\"type\":\"DefensePercent\",\"value\":12},{\"type\":\"HealthPercent\",\"value\":11},{\"type\":\"CriticalHitDamagePercent\",\"value\":11}],\"name\":\"ArahakansChestplate\",\"augmentedStats\":{\"mainType\":\"Defense\",\"mainValue\":250,\"CriticalHitChancePercent\":8,\"DefensePercent\":12,\"HealthPercent\":11,\"CriticalHitDamagePercent\":11},\"id\":13},{\"gear\":\"Armor\",\"rank\":\"Epic\",\"set\":\"SpeedSet\",\"level\":85,\"enhance\":15,\"main\":{\"type\":\"Defense\",\"value\":300},\"substats\":[{\"type\":\"CriticalHitDamagePercent\",\"value\":9},{\"type\":\"CriticalHitChancePercent\",\"value\":9},{\"type\":\"DefensePercent\",\"value\":12},{\"type\":\"EffectivenessPercent\",\"value\":18}],\"name\":\"Corimescent\",\"augmentedStats\":{\"mainType\":\"Defense\",\"mainValue\":300,\"CriticalHitDamagePercent\":9,\"CriticalHitChancePercent\":9,\"DefensePercent\":12,\"EffectivenessPercent\":18},\"id\":14},{\"gear\":\"Armor\",\"rank\":\"Epic\",\"set\":\"ImmunitySet\",\"level\":85,\"enhance\":15,\"main\":{\"type\":\"Defense\",\"value\":300},\"substats\":[{\"type\":\"Speed\",\"value\":7},{\"type\":\"CriticalHitChancePercent\",\"value\":7},{\"type\":\"CriticalHitDamagePercent\",\"value\":13},{\"type\":\"EffectivenessPercent\",\"value\":17}],\"name\":\"Corimescent\",\"augmentedStats\":{\"mainType\":\"Defense\",\"mainValue\":300,\"Speed\":7,\"CriticalHitChancePercent\":7,\"CriticalHitDamagePercent\":13,\"EffectivenessPercent\":17},\"id\":15},{\"gear\":\"Necklace\",\"rank\":\"Epic\",\"set\":\"HealthSet\",\"level\":78,\"enhance\":15,\"main\":{\"type\":\"HealthPercent\",\"value\":60},\"substats\":[{\"type\":\"DefensePercent\",\"value\":12},{\"type\":\"CriticalHitChancePercent\",\"value\":10},{\"type\":\"Speed\",\"value\":6},{\"type\":\"EffectResistancePercent\",\"value\":19}],\"name\":\"ConstellasPearlNecklace\",\"augmentedStats\":{\"mainType\":\"HealthPercent\",\"mainValue\":60,\"DefensePercent\":12,\"CriticalHitChancePercent\":10,\"Speed\":6,\"EffectResistancePercent\":19},\"id\":16},{\"gear\":\"Necklace\",\"rank\":\"Epic\",\"set\":\"SpeedSet\",\"level\":71,\"enhance\":15,\"main\":{\"type\":\"HealthPercent\",\"value\":50},\"substats\":[{\"type\":\"DefensePercent\",\"value\":15},{\"type\":\"Speed\",\"value\":5},{\"type\":\"CriticalHitChancePercent\",\"value\":10},{\"type\":\"EffectivenessPercent\",\"value\":6}],\"name\":\"PendantofLuminescence\",\"augmentedStats\":{\"mainType\":\"HealthPercent\",\"mainValue\":50,\"DefensePercent\":15,\"Speed\":5,\"CriticalHitChancePercent\":10,\"EffectivenessPercent\":6},\"id\":17},{\"gear\":\"Necklace\",\"rank\":\"Epic\",\"set\":\"AttackSet\",\"level\":65,\"enhance\":15,\"main\":{\"type\":\"CriticalHitChancePercent\",\"value\":45},\"substats\":[{\"type\":\"Speed\",\"value\":13},{\"type\":\"AttackPercent\",\"value\":5},{\"type\":\"HealthPercent\",\"value\":4},{\"type\":\"EffectivenessPercent\",\"value\":13}],\"name\":\"TreasureCollectorsCharm\",\"augmentedStats\":{\"mainType\":\"CriticalHitChancePercent\",\"mainValue\":45,\"Speed\":13,\"AttackPercent\":5,\"HealthPercent\":4,\"EffectivenessPercent\":13},\"id\":18},{\"gear\":\"Necklace\",\"rank\":\"Epic\",\"set\":\"ResistSet\",\"level\":85,\"enhance\":15,\"main\":{\"type\":\"CriticalHitDamagePercent\",\"value\":65},\"substats\":[{\"type\":\"AttackPercent\",\"value\":14},{\"type\":\"CriticalHitChancePercent\",\"value\":21},{\"type\":\"EffectivenessPercent\",\"value\":4},{\"type\":\"HealthPercent\",\"value\":5}],\"name\":\"ObsidianAmulet\",\"augmentedStats\":{\"mainType\":\"CriticalHitDamagePercent\",\"mainValue\":65,\"AttackPercent\":14,\"CriticalHitChancePercent\":21,\"EffectivenessPercent\":4,\"HealthPercent\":5},\"id\":19},{\"gear\":\"Necklace\",\"rank\":\"Epic\",\"set\":\"CriticalSet\",\"level\":65,\"enhance\":15,\"main\":{\"type\":\"CriticalHitDamagePercent\",\"value\":65},\"substats\":[{\"type\":\"CriticalHitChancePercent\",\"value\":8},{\"type\":\"Speed\",\"value\":14},{\"type\":\"Attack\",\"value\":29},{\"type\":\"AttackPercent\",\"value\":6}],\"name\":\"BoldGeneralsNecklace\",\"augmentedStats\":{\"mainType\":\"CriticalHitDamagePercent\",\"mainValue\":65,\"CriticalHitChancePercent\":8,\"Speed\":14,\"Attack\":29,\"AttackPercent\":6},\"id\":20},{\"gear\":\"Ring\",\"rank\":\"Epic\",\"set\":\"DefenseSet\",\"level\":71,\"enhance\":15,\"main\":{\"type\":\"DefensePercent\",\"value\":50},\"substats\":[{\"type\":\"HealthPercent\",\"value\":11},{\"type\":\"Speed\",\"value\":11},{\"type\":\"CriticalHitChancePercent\",\"value\":4},{\"type\":\"EffectResistancePercent\",\"value\":6}],\"name\":\"OathRing\",\"augmentedStats\":{\"mainType\":\"DefensePercent\",\"mainValue\":50,\"HealthPercent\":11,\"Speed\":11,\"CriticalHitChancePercent\":4,\"EffectResistancePercent\":6},\"id\":21},{\"gear\":\"Ring\",\"rank\":\"Epic\",\"set\":\"LifestealSet\",\"level\":85,\"enhance\":15,\"main\":{\"type\":\"AttackPercent\",\"value\":60},\"substats\":[{\"type\":\"HealthPercent\",\"value\":12},{\"type\":\"Speed\",\"value\":4},{\"type\":\"CriticalHitChancePercent\",\"value\":12},{\"type\":\"EffectivenessPercent\",\"value\":18}],\"name\":\"GaveleetsRing\",\"augmentedStats\":{\"mainType\":\"AttackPercent\",\"mainValue\":60,\"HealthPercent\":12,\"Speed\":4,\"CriticalHitChancePercent\":12,\"EffectivenessPercent\":18},\"id\":22},{\"gear\":\"Ring\",\"rank\":\"Epic\",\"set\":\"SpeedSet\",\"level\":71,\"enhance\":15,\"main\":{\"type\":\"HealthPercent\",\"value\":50},\"substats\":[{\"type\":\"DefensePercent\",\"value\":14},{\"type\":\"Speed\",\"value\":5},{\"type\":\"CriticalHitChancePercent\",\"value\":7},{\"type\":\"EffectResistancePercent\",\"value\":9}],\"name\":\"LightofaMillion\",\"augmentedStats\":{\"mainType\":\"HealthPercent\",\"mainValue\":50,\"DefensePercent\":14,\"Speed\":5,\"CriticalHitChancePercent\":7,\"EffectResistancePercent\":9},\"id\":23},{\"gear\":\"Ring\",\"rank\":\"Epic\",\"set\":\"DefenseSet\",\"level\":88,\"enhance\":15,\"main\":{\"type\":\"EffectivenessPercent\",\"value\":65},\"substats\":[{\"type\":\"CriticalHitChancePercent\",\"value\":9},{\"type\":\"CriticalHitDamagePercent\",\"value\":18},{\"type\":\"DefensePercent\",\"value\":19},{\"type\":\"AttackPercent\",\"value\":9}],\"name\":\"GreaterAzimanusFightersRing\",\"augmentedStats\":{\"mainType\":\"EffectivenessPercent\",\"mainValue\":65,\"CriticalHitChancePercent\":9,\"CriticalHitDamagePercent\":18,\"DefensePercent\":19,\"AttackPercent\":9},\"id\":24},{\"gear\":\"Ring\",\"rank\":\"Epic\",\"set\":\"SpeedSet\",\"level\":65,\"enhance\":15,\"main\":{\"type\":\"EffectResistancePercent\",\"value\":50},\"substats\":[{\"type\":\"CriticalHitDamagePercent\",\"value\":11},{\"type\":\"HealthPercent\",\"value\":5},{\"type\":\"DefensePercent\",\"value\":7},{\"type\":\"Speed\",\"value\":8}],\"name\":\"EmergencyRing\",\"augmentedStats\":{\"mainType\":\"EffectResistancePercent\",\"mainValue\":50,\"CriticalHitDamagePercent\":11,\"HealthPercent\":5,\"DefensePercent\":7,\"Speed\":8},\"id\":25},{\"gear\":\"Ring\",\"rank\":\"Epic\",\"set\":\"DefenseSet\",\"level\":88,\"enhance\":15,\"main\":{\"type\":\"AttackPercent\",\"value\":65},\"substats\":[{\"type\":\"Speed\",\"value\":3},{\"type\":\"DefensePercent\",\"value\":18},{\"type\":\"CriticalHitDamagePercent\",\"value\":21},{\"type\":\"Attack\",\"value\":51}],\"name\":\"GreaterAzimanusFightersRing\",\"augmentedStats\":{\"mainType\":\"AttackPercent\",\"mainValue\":65,\"Speed\":3,\"DefensePercent\":18,\"CriticalHitDamagePercent\":21,\"Attack\":51},\"id\":26},{\"gear\":\"Boots\",\"rank\":\"Epic\",\"set\":\"CriticalSet\",\"level\":77,\"enhance\":15,\"main\":{\"type\":\"AttackPercent\",\"value\":60},\"substats\":[{\"type\":\"HealthPercent\",\"value\":7},{\"type\":\"CriticalHitChancePercent\",\"value\":12},{\"type\":\"CriticalHitDamagePercent\",\"value\":6},{\"type\":\"EffectivenessPercent\",\"value\":17}],\"name\":\"VerdantBoots\",\"augmentedStats\":{\"mainType\":\"AttackPercent\",\"mainValue\":60,\"HealthPercent\":7,\"CriticalHitChancePercent\":12,\"CriticalHitDamagePercent\":6,\"EffectivenessPercent\":17},\"id\":27},{\"gear\":\"Boots\",\"rank\":\"Epic\",\"set\":\"SpeedSet\",\"level\":71,\"enhance\":15,\"main\":{\"type\":\"Speed\",\"value\":35},\"substats\":[{\"type\":\"HealthPercent\",\"value\":6},{\"type\":\"AttackPercent\",\"value\":19},{\"type\":\"DefensePercent\",\"value\":12},{\"type\":\"CriticalHitChancePercent\",\"value\":8}],\"name\":\"SocksofSmallMiracles\",\"augmentedStats\":{\"mainType\":\"Speed\",\"mainValue\":35,\"HealthPercent\":6,\"AttackPercent\":19,\"DefensePercent\":12,\"CriticalHitChancePercent\":8},\"id\":28},{\"gear\":\"Boots\",\"rank\":\"Epic\",\"set\":\"SpeedSet\",\"level\":85,\"enhance\":15,\"main\":{\"type\":\"HealthPercent\",\"value\":60},\"substats\":[{\"type\":\"EffectResistancePercent\",\"value\":7},{\"type\":\"DefensePercent\",\"value\":12},{\"type\":\"Speed\",\"value\":8},{\"type\":\"CriticalHitChancePercent\",\"value\":11}],\"name\":\"AbyssDrakeBoots\",\"augmentedStats\":{\"mainType\":\"HealthPercent\",\"mainValue\":60,\"EffectResistancePercent\":7,\"DefensePercent\":12,\"Speed\":8,\"CriticalHitChancePercent\":11},\"id\":29},{\"gear\":\"Boots\",\"rank\":\"Epic\",\"set\":\"SpeedSet\",\"level\":85,\"enhance\":15,\"main\":{\"type\":\"Speed\",\"value\":40},\"substats\":[{\"type\":\"AttackPercent\",\"value\":6},{\"type\":\"EffectivenessPercent\",\"value\":14},{\"type\":\"EffectResistancePercent\",\"value\":28},{\"type\":\"HealthPercent\",\"value\":13}],\"name\":\"PracticalBoots\",\"augmentedStats\":{\"mainType\":\"Speed\",\"mainValue\":40,\"AttackPercent\":6,\"EffectivenessPercent\":14,\"EffectResistancePercent\":28,\"HealthPercent\":13},\"id\":30},{\"gear\":\"Boots\",\"rank\":\"Epic\",\"set\":\"SpeedSet\",\"level\":85,\"enhance\":15,\"main\":{\"type\":\"Speed\",\"value\":40},\"substats\":[{\"type\":\"EffectResistancePercent\",\"value\":17},{\"type\":\"DefensePercent\",\"value\":17},{\"type\":\"Attack\",\"value\":43},{\"type\":\"CriticalHitChancePercent\",\"value\":8}],\"name\":\"PracticalBoots\",\"augmentedStats\":{\"mainType\":\"Speed\",\"mainValue\":40,\"EffectResistancePercent\":17,\"DefensePercent\":17,\"Attack\":43,\"CriticalHitChancePercent\":8},\"id\":31}],\"inputAllowLockedItems\":false,\"inputAllowEquippedItems\":false,\"inputKeepCurrentItems\":false,\"inputSets\":[[\"SpeedSet\"],[],[]],\"inputSetsOne\":[\"ImmunitySet\", \"HealthSet\"],\"inputSetsTwo\":[],\"inputSetsThree\":[],\"inputAllowBrokenSets\":false,\"setFormat\":3,\"atk\":576,\"hp\":5700,\"def\":743,\"cr\":15,\"cd\":150,\"eff\":0,\"res\":0,\"spd\":88,\"dac\":5}"; + // 220 set +// private static final String REQUEST_STRING = "{\"base\":{\"atk\":576,\"hp\":5700,\"def\":743,\"cr\":15,\"cd\":150,\"eff\":0,\"res\":0,\"spd\":88,\"dac\":5},\"requestType\":\"OptimizationRequest\",\"extraField\":\"asdf\",\"items\":[{\"gear\":\"Weapon\",\"rank\":\"Heroic\",\"set\":\"HealthSet\",\"level\":85,\"enhance\":15,\"main\":{\"type\":\"Attack\",\"value\":500},\"substats\":[{\"type\":\"EffectivenessPercent\",\"value\":4},{\"type\":\"HealthPercent\",\"value\":27},{\"type\":\"AttackPercent\",\"value\":14},{\"type\":\"Health\",\"value\":178}],\"name\":\"DarkSteelSaber\",\"augmentedStats\":{\"mainType\":\"Attack\",\"mainValue\":500,\"EffectivenessPercent\":4,\"HealthPercent\":27,\"AttackPercent\":14,\"Health\":178},\"id\":0},{\"gear\":\"Weapon\",\"rank\":\"Epic\",\"set\":\"HealthSet\",\"level\":88,\"enhance\":15,\"main\":{\"type\":\"Attack\",\"value\":515},\"substats\":[{\"type\":\"Health\",\"value\":214},{\"type\":\"HealthPercent\",\"value\":25},{\"type\":\"CriticalHitDamagePercent\",\"value\":4},{\"type\":\"Speed\",\"value\":9}],\"name\":\"ArahakansFang\",\"augmentedStats\":{\"mainType\":\"Attack\",\"mainValue\":515,\"Health\":214,\"HealthPercent\":25,\"CriticalHitDamagePercent\":4,\"Speed\":9},\"id\":1},{\"gear\":\"Weapon\",\"rank\":\"Epic\",\"set\":\"RageSet\",\"level\":71,\"enhance\":15,\"main\":{\"type\":\"Attack\",\"value\":440},\"substats\":[{\"type\":\"AttackPercent\",\"value\":10},{\"type\":\"Speed\",\"value\":7},{\"type\":\"CriticalHitChancePercent\",\"value\":7},{\"type\":\"CriticalHitDamagePercent\",\"value\":9}],\"name\":\"ThornVineWhip\",\"augmentedStats\":{\"mainType\":\"Attack\",\"mainValue\":440,\"AttackPercent\":10,\"Speed\":7,\"CriticalHitChancePercent\":7,\"CriticalHitDamagePercent\":9},\"id\":2},{\"gear\":\"Weapon\",\"rank\":\"Epic\",\"set\":\"SpeedSet\",\"level\":85,\"enhance\":15,\"main\":{\"type\":\"Attack\",\"value\":500},\"substats\":[{\"type\":\"CriticalHitDamagePercent\",\"value\":15},{\"type\":\"Speed\",\"value\":6},{\"type\":\"CriticalHitChancePercent\",\"value\":10},{\"type\":\"AttackPercent\",\"value\":7}],\"name\":\"AbyssDrakeBonesword\",\"augmentedStats\":{\"mainType\":\"Attack\",\"mainValue\":500,\"CriticalHitDamagePercent\":15,\"Speed\":6,\"CriticalHitChancePercent\":10,\"AttackPercent\":7},\"id\":3},{\"gear\":\"Weapon\",\"rank\":\"Epic\",\"set\":\"CriticalSet\",\"level\":70,\"enhance\":15,\"main\":{\"type\":\"Attack\",\"value\":440},\"substats\":[{\"type\":\"CriticalHitChancePercent\",\"value\":6},{\"type\":\"CriticalHitDamagePercent\",\"value\":11},{\"type\":\"EffectResistancePercent\",\"value\":12},{\"type\":\"AttackPercent\",\"value\":20}],\"name\":\"ManaDrakeBonesword\",\"augmentedStats\":{\"mainType\":\"Attack\",\"mainValue\":440,\"CriticalHitChancePercent\":6,\"CriticalHitDamagePercent\":11,\"EffectResistancePercent\":12,\"AttackPercent\":20},\"id\":4},{\"gear\":\"Helmet\",\"rank\":\"Epic\",\"set\":\"SpeedSet\",\"level\":71,\"enhance\":15,\"main\":{\"type\":\"Health\",\"value\":2360},\"substats\":[{\"type\":\"HealthPercent\",\"value\":12},{\"type\":\"AttackPercent\",\"value\":11},{\"type\":\"DefensePercent\",\"value\":18},{\"type\":\"Speed\",\"value\":3}],\"name\":\"RoseCoronet\",\"augmentedStats\":{\"mainType\":\"Health\",\"mainValue\":2360,\"HealthPercent\":12,\"AttackPercent\":11,\"DefensePercent\":18,\"Speed\":3},\"id\":5},{\"gear\":\"Helmet\",\"rank\":\"Epic\",\"set\":\"SpeedSet\",\"level\":85,\"enhance\":15,\"main\":{\"type\":\"Health\",\"value\":2700},\"substats\":[{\"type\":\"CriticalHitChancePercent\",\"value\":6},{\"type\":\"AttackPercent\",\"value\":4},{\"type\":\"EffectivenessPercent\",\"value\":9},{\"type\":\"HealthPercent\",\"value\":26}],\"name\":\"AbyssDrakeMask\",\"augmentedStats\":{\"mainType\":\"Health\",\"mainValue\":2700,\"CriticalHitChancePercent\":6,\"AttackPercent\":4,\"EffectivenessPercent\":9,\"HealthPercent\":26},\"id\":6},{\"gear\":\"Helmet\",\"rank\":\"Epic\",\"set\":\"SpeedSet\",\"level\":88,\"enhance\":15,\"main\":{\"type\":\"Health\",\"value\":2765},\"substats\":[{\"type\":\"HealthPercent\",\"value\":17},{\"type\":\"DefensePercent\",\"value\":14},{\"type\":\"Speed\",\"value\":6},{\"type\":\"EffectResistancePercent\",\"value\":6}],\"name\":\"GladiatorsHelmofVictory\",\"augmentedStats\":{\"mainType\":\"Health\",\"mainValue\":2765,\"HealthPercent\":17,\"DefensePercent\":14,\"Speed\":6,\"EffectResistancePercent\":6},\"id\":7},{\"gear\":\"Helmet\",\"rank\":\"Epic\",\"set\":\"AttackSet\",\"level\":70,\"enhance\":15,\"main\":{\"type\":\"Health\",\"value\":2360},\"substats\":[{\"type\":\"AttackPercent\",\"value\":13},{\"type\":\"Speed\",\"value\":9},{\"type\":\"CriticalHitChancePercent\",\"value\":7},{\"type\":\"CriticalHitDamagePercent\",\"value\":9}],\"name\":\"TerrariaHelm\",\"augmentedStats\":{\"mainType\":\"Health\",\"mainValue\":2360,\"AttackPercent\":13,\"Speed\":9,\"CriticalHitChancePercent\":7,\"CriticalHitDamagePercent\":9},\"id\":8},{\"gear\":\"Helmet\",\"rank\":\"Epic\",\"set\":\"DefenseSet\",\"level\":88,\"enhance\":15,\"main\":{\"type\":\"Health\",\"value\":2765},\"substats\":[{\"type\":\"DefensePercent\",\"value\":7},{\"type\":\"Defense\",\"value\":34},{\"type\":\"AttackPercent\",\"value\":14},{\"type\":\"HealthPercent\",\"value\":31}],\"name\":\"KarkanissDecisionHelm\",\"augmentedStats\":{\"mainType\":\"Health\",\"mainValue\":2765,\"DefensePercent\":7,\"Defense\":34,\"AttackPercent\":14,\"HealthPercent\":31},\"id\":9},{\"gear\":\"Helmet\",\"rank\":\"Epic\",\"set\":\"ImmunitySet\",\"level\":67,\"enhance\":15,\"main\":{\"type\":\"Health\",\"value\":2295},\"substats\":[{\"type\":\"HealthPercent\",\"value\":6},{\"type\":\"CriticalHitDamagePercent\",\"value\":10},{\"type\":\"AttackPercent\",\"value\":14},{\"type\":\"CriticalHitChancePercent\",\"value\":7}],\"name\":\"KarkanissDecisionHelm\",\"augmentedStats\":{\"mainType\":\"Health\",\"mainValue\":2295,\"HealthPercent\":6,\"CriticalHitDamagePercent\":10,\"AttackPercent\":14,\"CriticalHitChancePercent\":7},\"id\":10},{\"gear\":\"Armor\",\"rank\":\"Epic\",\"set\":\"AttackSet\",\"level\":71,\"enhance\":15,\"main\":{\"type\":\"Defense\",\"value\":260},\"substats\":[{\"type\":\"HealthPercent\",\"value\":13},{\"type\":\"Speed\",\"value\":12},{\"type\":\"CriticalHitChancePercent\",\"value\":8},{\"type\":\"CriticalHitDamagePercent\",\"value\":6}],\"name\":\"AncientShandranWarriorsArmor\",\"augmentedStats\":{\"mainType\":\"Defense\",\"mainValue\":260,\"HealthPercent\":13,\"Speed\":12,\"CriticalHitChancePercent\":8,\"CriticalHitDamagePercent\":6},\"id\":11},{\"gear\":\"Armor\",\"rank\":\"Epic\",\"set\":\"SpeedSet\",\"level\":67,\"enhance\":15,\"main\":{\"type\":\"Defense\",\"value\":250},\"substats\":[{\"type\":\"HealthPercent\",\"value\":12},{\"type\":\"DefensePercent\",\"value\":21},{\"type\":\"Speed\",\"value\":10},{\"type\":\"CriticalHitChancePercent\",\"value\":4}],\"name\":\"AzimanusFightersArmor\",\"augmentedStats\":{\"mainType\":\"Defense\",\"mainValue\":250,\"HealthPercent\":12,\"DefensePercent\":21,\"Speed\":10,\"CriticalHitChancePercent\":4},\"id\":12},{\"gear\":\"Armor\",\"rank\":\"Epic\",\"set\":\"CriticalSet\",\"level\":67,\"enhance\":15,\"main\":{\"type\":\"Defense\",\"value\":250},\"substats\":[{\"type\":\"CriticalHitChancePercent\",\"value\":8},{\"type\":\"DefensePercent\",\"value\":12},{\"type\":\"HealthPercent\",\"value\":11},{\"type\":\"CriticalHitDamagePercent\",\"value\":11}],\"name\":\"ArahakansChestplate\",\"augmentedStats\":{\"mainType\":\"Defense\",\"mainValue\":250,\"CriticalHitChancePercent\":8,\"DefensePercent\":12,\"HealthPercent\":11,\"CriticalHitDamagePercent\":11},\"id\":13},{\"gear\":\"Armor\",\"rank\":\"Epic\",\"set\":\"SpeedSet\",\"level\":85,\"enhance\":15,\"main\":{\"type\":\"Defense\",\"value\":300},\"substats\":[{\"type\":\"CriticalHitDamagePercent\",\"value\":9},{\"type\":\"CriticalHitChancePercent\",\"value\":9},{\"type\":\"DefensePercent\",\"value\":12},{\"type\":\"EffectivenessPercent\",\"value\":18}],\"name\":\"Corimescent\",\"augmentedStats\":{\"mainType\":\"Defense\",\"mainValue\":300,\"CriticalHitDamagePercent\":9,\"CriticalHitChancePercent\":9,\"DefensePercent\":12,\"EffectivenessPercent\":18},\"id\":14},{\"gear\":\"Armor\",\"rank\":\"Epic\",\"set\":\"ImmunitySet\",\"level\":85,\"enhance\":15,\"main\":{\"type\":\"Defense\",\"value\":300},\"substats\":[{\"type\":\"Speed\",\"value\":7},{\"type\":\"CriticalHitChancePercent\",\"value\":7},{\"type\":\"CriticalHitDamagePercent\",\"value\":13},{\"type\":\"EffectivenessPercent\",\"value\":17}],\"name\":\"Corimescent\",\"augmentedStats\":{\"mainType\":\"Defense\",\"mainValue\":300,\"Speed\":7,\"CriticalHitChancePercent\":7,\"CriticalHitDamagePercent\":13,\"EffectivenessPercent\":17},\"id\":15},{\"gear\":\"Necklace\",\"rank\":\"Epic\",\"set\":\"HealthSet\",\"level\":78,\"enhance\":15,\"main\":{\"type\":\"HealthPercent\",\"value\":60},\"substats\":[{\"type\":\"DefensePercent\",\"value\":12},{\"type\":\"CriticalHitChancePercent\",\"value\":10},{\"type\":\"Speed\",\"value\":6},{\"type\":\"EffectResistancePercent\",\"value\":19}],\"name\":\"ConstellasPearlNecklace\",\"augmentedStats\":{\"mainType\":\"HealthPercent\",\"mainValue\":60,\"DefensePercent\":12,\"CriticalHitChancePercent\":10,\"Speed\":6,\"EffectResistancePercent\":19},\"id\":16},{\"gear\":\"Necklace\",\"rank\":\"Epic\",\"set\":\"SpeedSet\",\"level\":71,\"enhance\":15,\"main\":{\"type\":\"HealthPercent\",\"value\":50},\"substats\":[{\"type\":\"DefensePercent\",\"value\":15},{\"type\":\"Speed\",\"value\":5},{\"type\":\"CriticalHitChancePercent\",\"value\":10},{\"type\":\"EffectivenessPercent\",\"value\":6}],\"name\":\"PendantofLuminescence\",\"augmentedStats\":{\"mainType\":\"HealthPercent\",\"mainValue\":50,\"DefensePercent\":15,\"Speed\":5,\"CriticalHitChancePercent\":10,\"EffectivenessPercent\":6},\"id\":17},{\"gear\":\"Necklace\",\"rank\":\"Epic\",\"set\":\"AttackSet\",\"level\":65,\"enhance\":15,\"main\":{\"type\":\"CriticalHitChancePercent\",\"value\":45},\"substats\":[{\"type\":\"Speed\",\"value\":13},{\"type\":\"AttackPercent\",\"value\":5},{\"type\":\"HealthPercent\",\"value\":4},{\"type\":\"EffectivenessPercent\",\"value\":13}],\"name\":\"TreasureCollectorsCharm\",\"augmentedStats\":{\"mainType\":\"CriticalHitChancePercent\",\"mainValue\":45,\"Speed\":13,\"AttackPercent\":5,\"HealthPercent\":4,\"EffectivenessPercent\":13},\"id\":18},{\"gear\":\"Necklace\",\"rank\":\"Epic\",\"set\":\"ResistSet\",\"level\":85,\"enhance\":15,\"main\":{\"type\":\"CriticalHitDamagePercent\",\"value\":65},\"substats\":[{\"type\":\"AttackPercent\",\"value\":14},{\"type\":\"CriticalHitChancePercent\",\"value\":21},{\"type\":\"EffectivenessPercent\",\"value\":4},{\"type\":\"HealthPercent\",\"value\":5}],\"name\":\"ObsidianAmulet\",\"augmentedStats\":{\"mainType\":\"CriticalHitDamagePercent\",\"mainValue\":65,\"AttackPercent\":14,\"CriticalHitChancePercent\":21,\"EffectivenessPercent\":4,\"HealthPercent\":5},\"id\":19},{\"gear\":\"Necklace\",\"rank\":\"Epic\",\"set\":\"CriticalSet\",\"level\":65,\"enhance\":15,\"main\":{\"type\":\"CriticalHitDamagePercent\",\"value\":65},\"substats\":[{\"type\":\"CriticalHitChancePercent\",\"value\":8},{\"type\":\"Speed\",\"value\":14},{\"type\":\"Attack\",\"value\":29},{\"type\":\"AttackPercent\",\"value\":6}],\"name\":\"BoldGeneralsNecklace\",\"augmentedStats\":{\"mainType\":\"CriticalHitDamagePercent\",\"mainValue\":65,\"CriticalHitChancePercent\":8,\"Speed\":14,\"Attack\":29,\"AttackPercent\":6},\"id\":20},{\"gear\":\"Ring\",\"rank\":\"Epic\",\"set\":\"DefenseSet\",\"level\":71,\"enhance\":15,\"main\":{\"type\":\"DefensePercent\",\"value\":50},\"substats\":[{\"type\":\"HealthPercent\",\"value\":11},{\"type\":\"Speed\",\"value\":11},{\"type\":\"CriticalHitChancePercent\",\"value\":4},{\"type\":\"EffectResistancePercent\",\"value\":6}],\"name\":\"OathRing\",\"augmentedStats\":{\"mainType\":\"DefensePercent\",\"mainValue\":50,\"HealthPercent\":11,\"Speed\":11,\"CriticalHitChancePercent\":4,\"EffectResistancePercent\":6},\"id\":21},{\"gear\":\"Ring\",\"rank\":\"Epic\",\"set\":\"LifestealSet\",\"level\":85,\"enhance\":15,\"main\":{\"type\":\"AttackPercent\",\"value\":60},\"substats\":[{\"type\":\"HealthPercent\",\"value\":12},{\"type\":\"Speed\",\"value\":4},{\"type\":\"CriticalHitChancePercent\",\"value\":12},{\"type\":\"EffectivenessPercent\",\"value\":18}],\"name\":\"GaveleetsRing\",\"augmentedStats\":{\"mainType\":\"AttackPercent\",\"mainValue\":60,\"HealthPercent\":12,\"Speed\":4,\"CriticalHitChancePercent\":12,\"EffectivenessPercent\":18},\"id\":22},{\"gear\":\"Ring\",\"rank\":\"Epic\",\"set\":\"SpeedSet\",\"level\":71,\"enhance\":15,\"main\":{\"type\":\"HealthPercent\",\"value\":50},\"substats\":[{\"type\":\"DefensePercent\",\"value\":14},{\"type\":\"Speed\",\"value\":5},{\"type\":\"CriticalHitChancePercent\",\"value\":7},{\"type\":\"EffectResistancePercent\",\"value\":9}],\"name\":\"LightofaMillion\",\"augmentedStats\":{\"mainType\":\"HealthPercent\",\"mainValue\":50,\"DefensePercent\":14,\"Speed\":5,\"CriticalHitChancePercent\":7,\"EffectResistancePercent\":9},\"id\":23},{\"gear\":\"Ring\",\"rank\":\"Epic\",\"set\":\"DefenseSet\",\"level\":88,\"enhance\":15,\"main\":{\"type\":\"EffectivenessPercent\",\"value\":65},\"substats\":[{\"type\":\"CriticalHitChancePercent\",\"value\":9},{\"type\":\"CriticalHitDamagePercent\",\"value\":18},{\"type\":\"DefensePercent\",\"value\":19},{\"type\":\"AttackPercent\",\"value\":9}],\"name\":\"GreaterAzimanusFightersRing\",\"augmentedStats\":{\"mainType\":\"EffectivenessPercent\",\"mainValue\":65,\"CriticalHitChancePercent\":9,\"CriticalHitDamagePercent\":18,\"DefensePercent\":19,\"AttackPercent\":9},\"id\":24},{\"gear\":\"Ring\",\"rank\":\"Epic\",\"set\":\"SpeedSet\",\"level\":65,\"enhance\":15,\"main\":{\"type\":\"EffectResistancePercent\",\"value\":50},\"substats\":[{\"type\":\"CriticalHitDamagePercent\",\"value\":11},{\"type\":\"HealthPercent\",\"value\":5},{\"type\":\"DefensePercent\",\"value\":7},{\"type\":\"Speed\",\"value\":8}],\"name\":\"EmergencyRing\",\"augmentedStats\":{\"mainType\":\"EffectResistancePercent\",\"mainValue\":50,\"CriticalHitDamagePercent\":11,\"HealthPercent\":5,\"DefensePercent\":7,\"Speed\":8},\"id\":25},{\"gear\":\"Ring\",\"rank\":\"Epic\",\"set\":\"DefenseSet\",\"level\":88,\"enhance\":15,\"main\":{\"type\":\"AttackPercent\",\"value\":65},\"substats\":[{\"type\":\"Speed\",\"value\":3},{\"type\":\"DefensePercent\",\"value\":18},{\"type\":\"CriticalHitDamagePercent\",\"value\":21},{\"type\":\"Attack\",\"value\":51}],\"name\":\"GreaterAzimanusFightersRing\",\"augmentedStats\":{\"mainType\":\"AttackPercent\",\"mainValue\":65,\"Speed\":3,\"DefensePercent\":18,\"CriticalHitDamagePercent\":21,\"Attack\":51},\"id\":26},{\"gear\":\"Boots\",\"rank\":\"Epic\",\"set\":\"CriticalSet\",\"level\":77,\"enhance\":15,\"main\":{\"type\":\"AttackPercent\",\"value\":60},\"substats\":[{\"type\":\"HealthPercent\",\"value\":7},{\"type\":\"CriticalHitChancePercent\",\"value\":12},{\"type\":\"CriticalHitDamagePercent\",\"value\":6},{\"type\":\"EffectivenessPercent\",\"value\":17}],\"name\":\"VerdantBoots\",\"augmentedStats\":{\"mainType\":\"AttackPercent\",\"mainValue\":60,\"HealthPercent\":7,\"CriticalHitChancePercent\":12,\"CriticalHitDamagePercent\":6,\"EffectivenessPercent\":17},\"id\":27},{\"gear\":\"Boots\",\"rank\":\"Epic\",\"set\":\"SpeedSet\",\"level\":71,\"enhance\":15,\"main\":{\"type\":\"Speed\",\"value\":35},\"substats\":[{\"type\":\"HealthPercent\",\"value\":6},{\"type\":\"AttackPercent\",\"value\":19},{\"type\":\"DefensePercent\",\"value\":12},{\"type\":\"CriticalHitChancePercent\",\"value\":8}],\"name\":\"SocksofSmallMiracles\",\"augmentedStats\":{\"mainType\":\"Speed\",\"mainValue\":35,\"HealthPercent\":6,\"AttackPercent\":19,\"DefensePercent\":12,\"CriticalHitChancePercent\":8},\"id\":28},{\"gear\":\"Boots\",\"rank\":\"Epic\",\"set\":\"SpeedSet\",\"level\":85,\"enhance\":15,\"main\":{\"type\":\"HealthPercent\",\"value\":60},\"substats\":[{\"type\":\"EffectResistancePercent\",\"value\":7},{\"type\":\"DefensePercent\",\"value\":12},{\"type\":\"Speed\",\"value\":8},{\"type\":\"CriticalHitChancePercent\",\"value\":11}],\"name\":\"AbyssDrakeBoots\",\"augmentedStats\":{\"mainType\":\"HealthPercent\",\"mainValue\":60,\"EffectResistancePercent\":7,\"DefensePercent\":12,\"Speed\":8,\"CriticalHitChancePercent\":11},\"id\":29},{\"gear\":\"Boots\",\"rank\":\"Epic\",\"set\":\"SpeedSet\",\"level\":85,\"enhance\":15,\"main\":{\"type\":\"Speed\",\"value\":40},\"substats\":[{\"type\":\"AttackPercent\",\"value\":6},{\"type\":\"EffectivenessPercent\",\"value\":14},{\"type\":\"EffectResistancePercent\",\"value\":28},{\"type\":\"HealthPercent\",\"value\":13}],\"name\":\"PracticalBoots\",\"augmentedStats\":{\"mainType\":\"Speed\",\"mainValue\":40,\"AttackPercent\":6,\"EffectivenessPercent\":14,\"EffectResistancePercent\":28,\"HealthPercent\":13},\"id\":30},{\"gear\":\"Boots\",\"rank\":\"Epic\",\"set\":\"SpeedSet\",\"level\":85,\"enhance\":15,\"main\":{\"type\":\"Speed\",\"value\":40},\"substats\":[{\"type\":\"EffectResistancePercent\",\"value\":17},{\"type\":\"DefensePercent\",\"value\":17},{\"type\":\"Attack\",\"value\":43},{\"type\":\"CriticalHitChancePercent\",\"value\":8}],\"name\":\"PracticalBoots\",\"augmentedStats\":{\"mainType\":\"Speed\",\"mainValue\":40,\"EffectResistancePercent\":17,\"DefensePercent\":17,\"Attack\":43,\"CriticalHitChancePercent\":8},\"id\":31}],\"inputAllowLockedItems\":false,\"inputAllowEquippedItems\":false,\"inputKeepCurrentItems\":false,\"inputSets\":[[\"SpeedSet\"],[],[]],\"inputSetsOne\":[\"ImmunitySet\", \"HealthSet\"],\"inputSetsTwo\":[\"HealthSet\",\"DefenseSet\"],\"inputSetsThree\":[],\"inputAllowBrokenSets\":false,\"setFormat\":4,\"atk\":576,\"hp\":5700,\"def\":743,\"cr\":15,\"cd\":150,\"eff\":0,\"res\":0,\"spd\":88,\"dac\":5}"; + // 400 Speed only set +// private static final String REQUEST_STRING = "{\"base\":{\"atk\":576,\"hp\":5700,\"def\":743,\"cr\":15,\"cd\":150,\"eff\":0,\"res\":0,\"spd\":88,\"dac\":5},\"requestType\":\"OptimizationRequest\",\"extraField\":\"asdf\",\"items\":[{\"gear\":\"Weapon\",\"rank\":\"Heroic\",\"set\":\"HealthSet\",\"level\":85,\"enhance\":15,\"main\":{\"type\":\"Attack\",\"value\":500},\"substats\":[{\"type\":\"EffectivenessPercent\",\"value\":4},{\"type\":\"HealthPercent\",\"value\":27},{\"type\":\"AttackPercent\",\"value\":14},{\"type\":\"Health\",\"value\":178}],\"name\":\"DarkSteelSaber\",\"augmentedStats\":{\"mainType\":\"Attack\",\"mainValue\":500,\"EffectivenessPercent\":4,\"HealthPercent\":27,\"AttackPercent\":14,\"Health\":178},\"id\":0},{\"gear\":\"Weapon\",\"rank\":\"Epic\",\"set\":\"HealthSet\",\"level\":88,\"enhance\":15,\"main\":{\"type\":\"Attack\",\"value\":515},\"substats\":[{\"type\":\"Health\",\"value\":214},{\"type\":\"HealthPercent\",\"value\":25},{\"type\":\"CriticalHitDamagePercent\",\"value\":4},{\"type\":\"Speed\",\"value\":9}],\"name\":\"ArahakansFang\",\"augmentedStats\":{\"mainType\":\"Attack\",\"mainValue\":515,\"Health\":214,\"HealthPercent\":25,\"CriticalHitDamagePercent\":4,\"Speed\":9},\"id\":1},{\"gear\":\"Weapon\",\"rank\":\"Epic\",\"set\":\"RageSet\",\"level\":71,\"enhance\":15,\"main\":{\"type\":\"Attack\",\"value\":440},\"substats\":[{\"type\":\"AttackPercent\",\"value\":10},{\"type\":\"Speed\",\"value\":7},{\"type\":\"CriticalHitChancePercent\",\"value\":7},{\"type\":\"CriticalHitDamagePercent\",\"value\":9}],\"name\":\"ThornVineWhip\",\"augmentedStats\":{\"mainType\":\"Attack\",\"mainValue\":440,\"AttackPercent\":10,\"Speed\":7,\"CriticalHitChancePercent\":7,\"CriticalHitDamagePercent\":9},\"id\":2},{\"gear\":\"Weapon\",\"rank\":\"Epic\",\"set\":\"SpeedSet\",\"level\":85,\"enhance\":15,\"main\":{\"type\":\"Attack\",\"value\":500},\"substats\":[{\"type\":\"CriticalHitDamagePercent\",\"value\":15},{\"type\":\"Speed\",\"value\":6},{\"type\":\"CriticalHitChancePercent\",\"value\":10},{\"type\":\"AttackPercent\",\"value\":7}],\"name\":\"AbyssDrakeBonesword\",\"augmentedStats\":{\"mainType\":\"Attack\",\"mainValue\":500,\"CriticalHitDamagePercent\":15,\"Speed\":6,\"CriticalHitChancePercent\":10,\"AttackPercent\":7},\"id\":3},{\"gear\":\"Weapon\",\"rank\":\"Epic\",\"set\":\"CriticalSet\",\"level\":70,\"enhance\":15,\"main\":{\"type\":\"Attack\",\"value\":440},\"substats\":[{\"type\":\"CriticalHitChancePercent\",\"value\":6},{\"type\":\"CriticalHitDamagePercent\",\"value\":11},{\"type\":\"EffectResistancePercent\",\"value\":12},{\"type\":\"AttackPercent\",\"value\":20}],\"name\":\"ManaDrakeBonesword\",\"augmentedStats\":{\"mainType\":\"Attack\",\"mainValue\":440,\"CriticalHitChancePercent\":6,\"CriticalHitDamagePercent\":11,\"EffectResistancePercent\":12,\"AttackPercent\":20},\"id\":4},{\"gear\":\"Helmet\",\"rank\":\"Epic\",\"set\":\"SpeedSet\",\"level\":71,\"enhance\":15,\"main\":{\"type\":\"Health\",\"value\":2360},\"substats\":[{\"type\":\"HealthPercent\",\"value\":12},{\"type\":\"AttackPercent\",\"value\":11},{\"type\":\"DefensePercent\",\"value\":18},{\"type\":\"Speed\",\"value\":3}],\"name\":\"RoseCoronet\",\"augmentedStats\":{\"mainType\":\"Health\",\"mainValue\":2360,\"HealthPercent\":12,\"AttackPercent\":11,\"DefensePercent\":18,\"Speed\":3},\"id\":5},{\"gear\":\"Helmet\",\"rank\":\"Epic\",\"set\":\"SpeedSet\",\"level\":85,\"enhance\":15,\"main\":{\"type\":\"Health\",\"value\":2700},\"substats\":[{\"type\":\"CriticalHitChancePercent\",\"value\":6},{\"type\":\"AttackPercent\",\"value\":4},{\"type\":\"EffectivenessPercent\",\"value\":9},{\"type\":\"HealthPercent\",\"value\":26}],\"name\":\"AbyssDrakeMask\",\"augmentedStats\":{\"mainType\":\"Health\",\"mainValue\":2700,\"CriticalHitChancePercent\":6,\"AttackPercent\":4,\"EffectivenessPercent\":9,\"HealthPercent\":26},\"id\":6},{\"gear\":\"Helmet\",\"rank\":\"Epic\",\"set\":\"SpeedSet\",\"level\":88,\"enhance\":15,\"main\":{\"type\":\"Health\",\"value\":2765},\"substats\":[{\"type\":\"HealthPercent\",\"value\":17},{\"type\":\"DefensePercent\",\"value\":14},{\"type\":\"Speed\",\"value\":6},{\"type\":\"EffectResistancePercent\",\"value\":6}],\"name\":\"GladiatorsHelmofVictory\",\"augmentedStats\":{\"mainType\":\"Health\",\"mainValue\":2765,\"HealthPercent\":17,\"DefensePercent\":14,\"Speed\":6,\"EffectResistancePercent\":6},\"id\":7},{\"gear\":\"Helmet\",\"rank\":\"Epic\",\"set\":\"AttackSet\",\"level\":70,\"enhance\":15,\"main\":{\"type\":\"Health\",\"value\":2360},\"substats\":[{\"type\":\"AttackPercent\",\"value\":13},{\"type\":\"Speed\",\"value\":9},{\"type\":\"CriticalHitChancePercent\",\"value\":7},{\"type\":\"CriticalHitDamagePercent\",\"value\":9}],\"name\":\"TerrariaHelm\",\"augmentedStats\":{\"mainType\":\"Health\",\"mainValue\":2360,\"AttackPercent\":13,\"Speed\":9,\"CriticalHitChancePercent\":7,\"CriticalHitDamagePercent\":9},\"id\":8},{\"gear\":\"Helmet\",\"rank\":\"Epic\",\"set\":\"DefenseSet\",\"level\":88,\"enhance\":15,\"main\":{\"type\":\"Health\",\"value\":2765},\"substats\":[{\"type\":\"DefensePercent\",\"value\":7},{\"type\":\"Defense\",\"value\":34},{\"type\":\"AttackPercent\",\"value\":14},{\"type\":\"HealthPercent\",\"value\":31}],\"name\":\"KarkanissDecisionHelm\",\"augmentedStats\":{\"mainType\":\"Health\",\"mainValue\":2765,\"DefensePercent\":7,\"Defense\":34,\"AttackPercent\":14,\"HealthPercent\":31},\"id\":9},{\"gear\":\"Helmet\",\"rank\":\"Epic\",\"set\":\"ImmunitySet\",\"level\":67,\"enhance\":15,\"main\":{\"type\":\"Health\",\"value\":2295},\"substats\":[{\"type\":\"HealthPercent\",\"value\":6},{\"type\":\"CriticalHitDamagePercent\",\"value\":10},{\"type\":\"AttackPercent\",\"value\":14},{\"type\":\"CriticalHitChancePercent\",\"value\":7}],\"name\":\"KarkanissDecisionHelm\",\"augmentedStats\":{\"mainType\":\"Health\",\"mainValue\":2295,\"HealthPercent\":6,\"CriticalHitDamagePercent\":10,\"AttackPercent\":14,\"CriticalHitChancePercent\":7},\"id\":10},{\"gear\":\"Armor\",\"rank\":\"Epic\",\"set\":\"AttackSet\",\"level\":71,\"enhance\":15,\"main\":{\"type\":\"Defense\",\"value\":260},\"substats\":[{\"type\":\"HealthPercent\",\"value\":13},{\"type\":\"Speed\",\"value\":12},{\"type\":\"CriticalHitChancePercent\",\"value\":8},{\"type\":\"CriticalHitDamagePercent\",\"value\":6}],\"name\":\"AncientShandranWarriorsArmor\",\"augmentedStats\":{\"mainType\":\"Defense\",\"mainValue\":260,\"HealthPercent\":13,\"Speed\":12,\"CriticalHitChancePercent\":8,\"CriticalHitDamagePercent\":6},\"id\":11},{\"gear\":\"Armor\",\"rank\":\"Epic\",\"set\":\"SpeedSet\",\"level\":67,\"enhance\":15,\"main\":{\"type\":\"Defense\",\"value\":250},\"substats\":[{\"type\":\"HealthPercent\",\"value\":12},{\"type\":\"DefensePercent\",\"value\":21},{\"type\":\"Speed\",\"value\":10},{\"type\":\"CriticalHitChancePercent\",\"value\":4}],\"name\":\"AzimanusFightersArmor\",\"augmentedStats\":{\"mainType\":\"Defense\",\"mainValue\":250,\"HealthPercent\":12,\"DefensePercent\":21,\"Speed\":10,\"CriticalHitChancePercent\":4},\"id\":12},{\"gear\":\"Armor\",\"rank\":\"Epic\",\"set\":\"CriticalSet\",\"level\":67,\"enhance\":15,\"main\":{\"type\":\"Defense\",\"value\":250},\"substats\":[{\"type\":\"CriticalHitChancePercent\",\"value\":8},{\"type\":\"DefensePercent\",\"value\":12},{\"type\":\"HealthPercent\",\"value\":11},{\"type\":\"CriticalHitDamagePercent\",\"value\":11}],\"name\":\"ArahakansChestplate\",\"augmentedStats\":{\"mainType\":\"Defense\",\"mainValue\":250,\"CriticalHitChancePercent\":8,\"DefensePercent\":12,\"HealthPercent\":11,\"CriticalHitDamagePercent\":11},\"id\":13},{\"gear\":\"Armor\",\"rank\":\"Epic\",\"set\":\"SpeedSet\",\"level\":85,\"enhance\":15,\"main\":{\"type\":\"Defense\",\"value\":300},\"substats\":[{\"type\":\"CriticalHitDamagePercent\",\"value\":9},{\"type\":\"CriticalHitChancePercent\",\"value\":9},{\"type\":\"DefensePercent\",\"value\":12},{\"type\":\"EffectivenessPercent\",\"value\":18}],\"name\":\"Corimescent\",\"augmentedStats\":{\"mainType\":\"Defense\",\"mainValue\":300,\"CriticalHitDamagePercent\":9,\"CriticalHitChancePercent\":9,\"DefensePercent\":12,\"EffectivenessPercent\":18},\"id\":14},{\"gear\":\"Armor\",\"rank\":\"Epic\",\"set\":\"ImmunitySet\",\"level\":85,\"enhance\":15,\"main\":{\"type\":\"Defense\",\"value\":300},\"substats\":[{\"type\":\"Speed\",\"value\":7},{\"type\":\"CriticalHitChancePercent\",\"value\":7},{\"type\":\"CriticalHitDamagePercent\",\"value\":13},{\"type\":\"EffectivenessPercent\",\"value\":17}],\"name\":\"Corimescent\",\"augmentedStats\":{\"mainType\":\"Defense\",\"mainValue\":300,\"Speed\":7,\"CriticalHitChancePercent\":7,\"CriticalHitDamagePercent\":13,\"EffectivenessPercent\":17},\"id\":15},{\"gear\":\"Necklace\",\"rank\":\"Epic\",\"set\":\"HealthSet\",\"level\":78,\"enhance\":15,\"main\":{\"type\":\"HealthPercent\",\"value\":60},\"substats\":[{\"type\":\"DefensePercent\",\"value\":12},{\"type\":\"CriticalHitChancePercent\",\"value\":10},{\"type\":\"Speed\",\"value\":6},{\"type\":\"EffectResistancePercent\",\"value\":19}],\"name\":\"ConstellasPearlNecklace\",\"augmentedStats\":{\"mainType\":\"HealthPercent\",\"mainValue\":60,\"DefensePercent\":12,\"CriticalHitChancePercent\":10,\"Speed\":6,\"EffectResistancePercent\":19},\"id\":16},{\"gear\":\"Necklace\",\"rank\":\"Epic\",\"set\":\"SpeedSet\",\"level\":71,\"enhance\":15,\"main\":{\"type\":\"HealthPercent\",\"value\":50},\"substats\":[{\"type\":\"DefensePercent\",\"value\":15},{\"type\":\"Speed\",\"value\":5},{\"type\":\"CriticalHitChancePercent\",\"value\":10},{\"type\":\"EffectivenessPercent\",\"value\":6}],\"name\":\"PendantofLuminescence\",\"augmentedStats\":{\"mainType\":\"HealthPercent\",\"mainValue\":50,\"DefensePercent\":15,\"Speed\":5,\"CriticalHitChancePercent\":10,\"EffectivenessPercent\":6},\"id\":17},{\"gear\":\"Necklace\",\"rank\":\"Epic\",\"set\":\"AttackSet\",\"level\":65,\"enhance\":15,\"main\":{\"type\":\"CriticalHitChancePercent\",\"value\":45},\"substats\":[{\"type\":\"Speed\",\"value\":13},{\"type\":\"AttackPercent\",\"value\":5},{\"type\":\"HealthPercent\",\"value\":4},{\"type\":\"EffectivenessPercent\",\"value\":13}],\"name\":\"TreasureCollectorsCharm\",\"augmentedStats\":{\"mainType\":\"CriticalHitChancePercent\",\"mainValue\":45,\"Speed\":13,\"AttackPercent\":5,\"HealthPercent\":4,\"EffectivenessPercent\":13},\"id\":18},{\"gear\":\"Necklace\",\"rank\":\"Epic\",\"set\":\"ResistSet\",\"level\":85,\"enhance\":15,\"main\":{\"type\":\"CriticalHitDamagePercent\",\"value\":65},\"substats\":[{\"type\":\"AttackPercent\",\"value\":14},{\"type\":\"CriticalHitChancePercent\",\"value\":21},{\"type\":\"EffectivenessPercent\",\"value\":4},{\"type\":\"HealthPercent\",\"value\":5}],\"name\":\"ObsidianAmulet\",\"augmentedStats\":{\"mainType\":\"CriticalHitDamagePercent\",\"mainValue\":65,\"AttackPercent\":14,\"CriticalHitChancePercent\":21,\"EffectivenessPercent\":4,\"HealthPercent\":5},\"id\":19},{\"gear\":\"Necklace\",\"rank\":\"Epic\",\"set\":\"CriticalSet\",\"level\":65,\"enhance\":15,\"main\":{\"type\":\"CriticalHitDamagePercent\",\"value\":65},\"substats\":[{\"type\":\"CriticalHitChancePercent\",\"value\":8},{\"type\":\"Speed\",\"value\":14},{\"type\":\"Attack\",\"value\":29},{\"type\":\"AttackPercent\",\"value\":6}],\"name\":\"BoldGeneralsNecklace\",\"augmentedStats\":{\"mainType\":\"CriticalHitDamagePercent\",\"mainValue\":65,\"CriticalHitChancePercent\":8,\"Speed\":14,\"Attack\":29,\"AttackPercent\":6},\"id\":20},{\"gear\":\"Ring\",\"rank\":\"Epic\",\"set\":\"DefenseSet\",\"level\":71,\"enhance\":15,\"main\":{\"type\":\"DefensePercent\",\"value\":50},\"substats\":[{\"type\":\"HealthPercent\",\"value\":11},{\"type\":\"Speed\",\"value\":11},{\"type\":\"CriticalHitChancePercent\",\"value\":4},{\"type\":\"EffectResistancePercent\",\"value\":6}],\"name\":\"OathRing\",\"augmentedStats\":{\"mainType\":\"DefensePercent\",\"mainValue\":50,\"HealthPercent\":11,\"Speed\":11,\"CriticalHitChancePercent\":4,\"EffectResistancePercent\":6},\"id\":21},{\"gear\":\"Ring\",\"rank\":\"Epic\",\"set\":\"LifestealSet\",\"level\":85,\"enhance\":15,\"main\":{\"type\":\"AttackPercent\",\"value\":60},\"substats\":[{\"type\":\"HealthPercent\",\"value\":12},{\"type\":\"Speed\",\"value\":4},{\"type\":\"CriticalHitChancePercent\",\"value\":12},{\"type\":\"EffectivenessPercent\",\"value\":18}],\"name\":\"GaveleetsRing\",\"augmentedStats\":{\"mainType\":\"AttackPercent\",\"mainValue\":60,\"HealthPercent\":12,\"Speed\":4,\"CriticalHitChancePercent\":12,\"EffectivenessPercent\":18},\"id\":22},{\"gear\":\"Ring\",\"rank\":\"Epic\",\"set\":\"SpeedSet\",\"level\":71,\"enhance\":15,\"main\":{\"type\":\"HealthPercent\",\"value\":50},\"substats\":[{\"type\":\"DefensePercent\",\"value\":14},{\"type\":\"Speed\",\"value\":5},{\"type\":\"CriticalHitChancePercent\",\"value\":7},{\"type\":\"EffectResistancePercent\",\"value\":9}],\"name\":\"LightofaMillion\",\"augmentedStats\":{\"mainType\":\"HealthPercent\",\"mainValue\":50,\"DefensePercent\":14,\"Speed\":5,\"CriticalHitChancePercent\":7,\"EffectResistancePercent\":9},\"id\":23},{\"gear\":\"Ring\",\"rank\":\"Epic\",\"set\":\"DefenseSet\",\"level\":88,\"enhance\":15,\"main\":{\"type\":\"EffectivenessPercent\",\"value\":65},\"substats\":[{\"type\":\"CriticalHitChancePercent\",\"value\":9},{\"type\":\"CriticalHitDamagePercent\",\"value\":18},{\"type\":\"DefensePercent\",\"value\":19},{\"type\":\"AttackPercent\",\"value\":9}],\"name\":\"GreaterAzimanusFightersRing\",\"augmentedStats\":{\"mainType\":\"EffectivenessPercent\",\"mainValue\":65,\"CriticalHitChancePercent\":9,\"CriticalHitDamagePercent\":18,\"DefensePercent\":19,\"AttackPercent\":9},\"id\":24},{\"gear\":\"Ring\",\"rank\":\"Epic\",\"set\":\"SpeedSet\",\"level\":65,\"enhance\":15,\"main\":{\"type\":\"EffectResistancePercent\",\"value\":50},\"substats\":[{\"type\":\"CriticalHitDamagePercent\",\"value\":11},{\"type\":\"HealthPercent\",\"value\":5},{\"type\":\"DefensePercent\",\"value\":7},{\"type\":\"Speed\",\"value\":8}],\"name\":\"EmergencyRing\",\"augmentedStats\":{\"mainType\":\"EffectResistancePercent\",\"mainValue\":50,\"CriticalHitDamagePercent\":11,\"HealthPercent\":5,\"DefensePercent\":7,\"Speed\":8},\"id\":25},{\"gear\":\"Ring\",\"rank\":\"Epic\",\"set\":\"DefenseSet\",\"level\":88,\"enhance\":15,\"main\":{\"type\":\"AttackPercent\",\"value\":65},\"substats\":[{\"type\":\"Speed\",\"value\":3},{\"type\":\"DefensePercent\",\"value\":18},{\"type\":\"CriticalHitDamagePercent\",\"value\":21},{\"type\":\"Attack\",\"value\":51}],\"name\":\"GreaterAzimanusFightersRing\",\"augmentedStats\":{\"mainType\":\"AttackPercent\",\"mainValue\":65,\"Speed\":3,\"DefensePercent\":18,\"CriticalHitDamagePercent\":21,\"Attack\":51},\"id\":26},{\"gear\":\"Boots\",\"rank\":\"Epic\",\"set\":\"CriticalSet\",\"level\":77,\"enhance\":15,\"main\":{\"type\":\"AttackPercent\",\"value\":60},\"substats\":[{\"type\":\"HealthPercent\",\"value\":7},{\"type\":\"CriticalHitChancePercent\",\"value\":12},{\"type\":\"CriticalHitDamagePercent\",\"value\":6},{\"type\":\"EffectivenessPercent\",\"value\":17}],\"name\":\"VerdantBoots\",\"augmentedStats\":{\"mainType\":\"AttackPercent\",\"mainValue\":60,\"HealthPercent\":7,\"CriticalHitChancePercent\":12,\"CriticalHitDamagePercent\":6,\"EffectivenessPercent\":17},\"id\":27},{\"gear\":\"Boots\",\"rank\":\"Epic\",\"set\":\"SpeedSet\",\"level\":71,\"enhance\":15,\"main\":{\"type\":\"Speed\",\"value\":35},\"substats\":[{\"type\":\"HealthPercent\",\"value\":6},{\"type\":\"AttackPercent\",\"value\":19},{\"type\":\"DefensePercent\",\"value\":12},{\"type\":\"CriticalHitChancePercent\",\"value\":8}],\"name\":\"SocksofSmallMiracles\",\"augmentedStats\":{\"mainType\":\"Speed\",\"mainValue\":35,\"HealthPercent\":6,\"AttackPercent\":19,\"DefensePercent\":12,\"CriticalHitChancePercent\":8},\"id\":28},{\"gear\":\"Boots\",\"rank\":\"Epic\",\"set\":\"SpeedSet\",\"level\":85,\"enhance\":15,\"main\":{\"type\":\"HealthPercent\",\"value\":60},\"substats\":[{\"type\":\"EffectResistancePercent\",\"value\":7},{\"type\":\"DefensePercent\",\"value\":12},{\"type\":\"Speed\",\"value\":8},{\"type\":\"CriticalHitChancePercent\",\"value\":11}],\"name\":\"AbyssDrakeBoots\",\"augmentedStats\":{\"mainType\":\"HealthPercent\",\"mainValue\":60,\"EffectResistancePercent\":7,\"DefensePercent\":12,\"Speed\":8,\"CriticalHitChancePercent\":11},\"id\":29},{\"gear\":\"Boots\",\"rank\":\"Epic\",\"set\":\"SpeedSet\",\"level\":85,\"enhance\":15,\"main\":{\"type\":\"Speed\",\"value\":40},\"substats\":[{\"type\":\"AttackPercent\",\"value\":6},{\"type\":\"EffectivenessPercent\",\"value\":14},{\"type\":\"EffectResistancePercent\",\"value\":28},{\"type\":\"HealthPercent\",\"value\":13}],\"name\":\"PracticalBoots\",\"augmentedStats\":{\"mainType\":\"Speed\",\"mainValue\":40,\"AttackPercent\":6,\"EffectivenessPercent\":14,\"EffectResistancePercent\":28,\"HealthPercent\":13},\"id\":30},{\"gear\":\"Boots\",\"rank\":\"Epic\",\"set\":\"SpeedSet\",\"level\":85,\"enhance\":15,\"main\":{\"type\":\"Speed\",\"value\":40},\"substats\":[{\"type\":\"EffectResistancePercent\",\"value\":17},{\"type\":\"DefensePercent\",\"value\":17},{\"type\":\"Attack\",\"value\":43},{\"type\":\"CriticalHitChancePercent\",\"value\":8}],\"name\":\"PracticalBoots\",\"augmentedStats\":{\"mainType\":\"Speed\",\"mainValue\":40,\"EffectResistancePercent\":17,\"DefensePercent\":17,\"Attack\":43,\"CriticalHitChancePercent\":8},\"id\":31}],\"inputAllowLockedItems\":false,\"inputAllowEquippedItems\":false,\"inputKeepCurrentItems\":false,\"inputSets\":[[\"SpeedSet\"],[],[]],\"inputSetsOne\":[\"SpeedSet\"],\"inputSetsTwo\":[],\"inputSetsThree\":[],\"inputAllowBrokenSets\":false,\"setFormat\":2,\"atk\":576,\"hp\":5700,\"def\":743,\"cr\":15,\"cd\":150,\"eff\":0,\"res\":0,\"spd\":88,\"dac\":5}"; + + // 7.1, 9.6 + private final HeroStats baseAngelica = HeroStats.builder() + .atk(576) + .hp(5700) + .spd(88) + .def(743) + .cr(15) + .cd(150) + .eff(0) + .res(0) + .dac(5) + .build(); + + @BeforeEach + public void setup() { + handler = new OptimizationRequestHandler(null); + } + + @Test + public void ocr1image() { + BytePointer outText = null; + + TessBaseAPI api = new TessBaseAPI(); + // api.Init("C:/Users/ivanc/optimizer/app/tessdata/eng.traineddata", "eng"); + // Initialize tesseract-ocr with English, without specifying tessdata path + // OEM 0 for Legecy engine, otherwise whitelist doesnt work + if (api.Init("C:/Users/ivanc/optimizer/app/tessdata/eng.traineddata", "eng", 0) != 0) { + System.err.println("Could not initialize tesseract."); + System.exit(1); + } + + api.SetVariable("tessedit_char_whitelist", "0123456789%,"); + api.SetVariable("load_system_dawg", "false"); + api.SetVariable("load_freq_dawg", "false"); + api.SetVariable("classify_enable_learning", "0"); + // Open input image with leptonica library + PIX image = pixRead("C:\\Users\\ivanc\\Documents\\XuanZhi\\Pictures\\Screenshots\\" + + "bugs\\Screenshot_20201206-041200.png"); + // PIX image = pixRead("C:\\Users\\ivanc\\Documents\\ShareX\\Screenshots\\2020-12\\mspaint_BdrQa2bXvO.png"); + api.SetImage(image); + + + api.SetRectangle(311, 444, 85, 144); + outText = api.GetUTF8Text(); + + System.out.println(outText.getString()); + } + + + @Test + public void ocrtest() { + BytePointer outText = null; + + TessBaseAPI api = new TessBaseAPI(); +// api.Init("C:/Users/ivanc/optimizer/app/tessdata/eng.traineddata", "eng"); + // Initialize tesseract-ocr with English, without specifying tessdata path + // OEM 0 for Legecy engine, otherwise whitelist doesnt work + if (api.Init("C:/Users/ivanc/optimizer/app/tessdata/eng.traineddata", "eng", 0) != 0) { + System.err.println("Could not initialize tesseract."); + System.exit(1); + } + + api.SetVariable("tessedit_char_whitelist", "0123456789+"); + api.SetVariable("load_system_dawg", "false"); + api.SetVariable("load_freq_dawg", "false"); + api.SetVariable("classify_enable_learning", "0"); + // Open input image with leptonica library + PIX image = pixRead("C:\\Users\\ivanc\\Documents\\XuanZhi\\Pictures\\Screenshots\\newocr\\y.png"); +// PIX image = pixRead("C:\\Users\\ivanc\\Documents\\ShareX\\Screenshots\\2020-12\\mspaint_BdrQa2bXvO.png"); + api.SetImage(image); + + + int x = 130; + int y = 171; + int w = 40; + int h = 22; + + int d = 2; + + Map> map = new HashMap<>(); + + int[] b = new int[]{1,3,4,5,6,7,8,9,10,11,12,13,14,15}; +// int[] b = new int[]{47, 55, 57, 60, 65, 67, 70, 71, 75, 78, 85, 88, 90}; + + for (int c = 0; c < b.length; c++) { + int a = b[c]; + + System.out.println(a); + + PIX img = pixRead("C:\\Users\\ivanc\\Documents\\XuanZhi\\Pictures\\Screenshots\\newocr\\" + a + ".png"); + api.SetImage(img); + + for (int i = x-d; i < x+d; i++) { + for (int j = y-d; j < y+d; j++) { + for (int k = w-d; k < w+d; k++) { + for (int l = h-d; l < h+d; l++) { + api.SetRectangle(i, j, k, l); + try { + outText = api.GetUTF8Text(); + } catch (final Exception e) { + outText.deallocate(); + continue; + } + if (outText == null || outText.getString() == null || outText.getString().length() == 0) continue; + + String key = i + " " + j + " " + k + " " + l; + String value = outText.getString().replaceAll("\n", "").replaceAll(" ", ""); + + if (StringUtils.equals("+" + a, value) || StringUtils.equals("" + a, value) ) { + if (!map.containsKey(key)) { + map.put(key, new ArrayList<>()); + map.get(key).add(a); + } else { + map.get(key).add(a); + } + } + + // System.out.println(outText.getString().replaceAll("\n", "").replaceAll(" ", "") + " | " + i + " " + j + " " + k + " " + l); + outText.deallocate(); + } + } + } + } + } + + System.out.println(map.entrySet().stream() + .sorted(Comparator.comparingInt(a -> a.getValue().size())) + .collect(Collectors.toList())); + + + + // Destroy used object and release memory + api.End(); + outText.deallocate(); + pixDestroy(image); + } + + @Test + public void test() { + final List s = Stream.of(Set.values()).map(Set::getName).collect(Collectors.toList()); + s.forEach(System.out::println); + + final Map distances = Stream.of(Set.values()).collect(Collectors.toMap( + x -> x, + x -> StringUtils.getLevenshteinDistance(x.getName(), "Unity Set (2/2)"))); + + final Set likelySet = distances.entrySet().stream() + .min(Comparator.comparingInt(Map.Entry::getValue)).get().getKey(); + + + +// System.out.println(s); + } + + @Test + public void testIndex() { + final int[] setsArray = new int[]{0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 2, 1, 1}; + final int[] indexArray = handler.convertSetsArrayIntoIndexArray(setsArray); + + System.out.println(Arrays.toString(indexArray)); + } +} diff --git a/resources/Gear.jar b/resources/Gear.jar index e8c60e7d..2aaa5f3a 100644 Binary files a/resources/Gear.jar and b/resources/Gear.jar differ