@scrabble-solver/scrabble-solver 2.8.6 → 2.8.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (85) hide show
  1. package/.next/BUILD_ID +1 -1
  2. package/.next/build-manifest.json +9 -9
  3. package/.next/cache/.tsbuildinfo +1 -1
  4. package/.next/cache/eslint/.cache_8dgz12 +1 -1
  5. package/.next/cache/next-server.js.nft.json +1 -1
  6. package/.next/cache/webpack/client-production/0.pack +0 -0
  7. package/.next/cache/webpack/client-production/index.pack +0 -0
  8. package/.next/cache/webpack/server-production/0.pack +0 -0
  9. package/.next/cache/webpack/server-production/index.pack +0 -0
  10. package/.next/next-server.js.nft.json +1 -1
  11. package/.next/prerender-manifest.json +1 -1
  12. package/.next/routes-manifest.json +1 -1
  13. package/.next/server/chunks/413.js +183 -94
  14. package/.next/server/chunks/{206.js → 429.js} +2 -4137
  15. package/.next/server/chunks/515.js +92 -70
  16. package/.next/server/chunks/{907.js → 911.js} +134 -367
  17. package/.next/server/chunks/939.js +218 -0
  18. package/.next/server/middleware-build-manifest.js +1 -1
  19. package/.next/server/pages/404.html +2 -2
  20. package/.next/server/pages/404.js.nft.json +1 -1
  21. package/.next/server/pages/500.html +2 -2
  22. package/.next/server/pages/_app.js.nft.json +1 -1
  23. package/.next/server/pages/_document.js.nft.json +1 -1
  24. package/.next/server/pages/_error.js.nft.json +1 -1
  25. package/.next/server/pages/api/dictionary/[locale]/[word].js +33 -17
  26. package/.next/server/pages/api/dictionary/[locale]/[word].js.nft.json +1 -1
  27. package/.next/server/pages/api/solve.js +399 -56
  28. package/.next/server/pages/api/solve.js.nft.json +1 -1
  29. package/.next/server/pages/api/visit.js +3 -2
  30. package/.next/server/pages/api/visit.js.nft.json +1 -1
  31. package/.next/server/pages/index.html +3 -7
  32. package/.next/server/pages/index.js +12 -14
  33. package/.next/server/pages/index.js.nft.json +1 -1
  34. package/.next/server/pages/index.json +1 -1
  35. package/.next/static/chunks/56-cf37c430261bbea5.js +1 -0
  36. package/.next/static/chunks/pages/_app-0b12a65bea70a0df.js +1 -0
  37. package/.next/static/chunks/pages/index-fcb69802550afb81.js +1 -0
  38. package/.next/static/css/1f39b55d50f5b30b.css +1 -0
  39. package/.next/static/css/751e8a14776d05d8.css +1 -0
  40. package/.next/static/z_0_lqfmiI_ISokr6NNRq/_buildManifest.js +1 -0
  41. package/.next/static/{VjSpyGDWyVaO0muz54q_j → z_0_lqfmiI_ISokr6NNRq}/_ssgManifest.js +0 -0
  42. package/.next/trace +40 -42
  43. package/package.json +9 -9
  44. package/src/api/index.ts +3 -9
  45. package/src/api/isBoardValid.ts +43 -0
  46. package/src/api/isCellValid.ts +26 -0
  47. package/src/api/isRowValid.ts +19 -0
  48. package/src/components/Dictionary/Dictionary.module.scss +20 -0
  49. package/src/components/Dictionary/Dictionary.tsx +40 -29
  50. package/src/components/Results/Cell.tsx +3 -2
  51. package/src/components/Results/Result.tsx +16 -6
  52. package/src/components/ResultsInput/ResultsInput.tsx +11 -3
  53. package/src/hooks/useIsTablet.ts +2 -2
  54. package/src/lib/getRemainingTiles.ts +1 -1
  55. package/src/lib/index.ts +2 -1
  56. package/src/lib/isRegExp.ts +11 -0
  57. package/src/lib/isStringArray.ts +5 -0
  58. package/src/lib/sortResults.ts +5 -5
  59. package/src/pages/api/dictionary/[locale]/[word].ts +35 -11
  60. package/src/pages/api/solve.ts +39 -19
  61. package/src/pages/api/visit.ts +1 -0
  62. package/src/pages/index.module.scss +5 -11
  63. package/src/pages/index.tsx +5 -5
  64. package/src/sdk/{findWordDefinition.ts → findWordDefinitions.ts} +3 -3
  65. package/src/sdk/index.ts +1 -1
  66. package/src/state/sagas.ts +11 -11
  67. package/src/state/selectors.ts +6 -2
  68. package/src/state/slices/dictionaryInitialState.ts +3 -3
  69. package/src/state/slices/dictionarySlice.ts +4 -10
  70. package/.next/static/VjSpyGDWyVaO0muz54q_j/_buildManifest.js +0 -1
  71. package/.next/static/chunks/56-e2797384ae4b0fc0.js +0 -1
  72. package/.next/static/chunks/pages/_app-5136d33b9b007fd7.js +0 -1
  73. package/.next/static/chunks/pages/index-13ea7770a65c69ee.js +0 -1
  74. package/.next/static/css/3159cfe62ff742a3.css +0 -1
  75. package/.next/static/css/729bb37fe8f9bee6.css +0 -1
  76. package/src/api/validateBoard.ts +0 -45
  77. package/src/api/validateCell.ts +0 -40
  78. package/src/api/validateCharacter.ts +0 -14
  79. package/src/api/validateCharacters.ts +0 -24
  80. package/src/api/validateConfigId.ts +0 -9
  81. package/src/api/validateLocale.ts +0 -15
  82. package/src/api/validateRow.ts +0 -17
  83. package/src/api/validateTile.ts +0 -21
  84. package/src/api/validateWord.ts +0 -11
  85. package/src/lib/isLocale.ts +0 -7
@@ -110,30 +110,37 @@ __webpack_require__.r(__webpack_exports__);
110
110
  /* harmony export */ __webpack_require__.d(__webpack_exports__, {
111
111
  /* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__)
112
112
  /* harmony export */ });
113
- /* harmony import */ var _scrabble_solver_logger__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(52954);
114
- /* harmony import */ var _scrabble_solver_logger__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_scrabble_solver_logger__WEBPACK_IMPORTED_MODULE_0__);
115
- /* harmony import */ var _scrabble_solver_word_definitions__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(98173);
116
- /* harmony import */ var _scrabble_solver_word_definitions__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(_scrabble_solver_word_definitions__WEBPACK_IMPORTED_MODULE_1__);
117
- /* harmony import */ var api__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(53888);
113
+ /* harmony import */ var _scrabble_solver_configs__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(27911);
114
+ /* harmony import */ var _scrabble_solver_configs__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_scrabble_solver_configs__WEBPACK_IMPORTED_MODULE_0__);
115
+ /* harmony import */ var _scrabble_solver_logger__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(52954);
116
+ /* harmony import */ var _scrabble_solver_logger__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(_scrabble_solver_logger__WEBPACK_IMPORTED_MODULE_1__);
117
+ /* harmony import */ var _scrabble_solver_types__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(46452);
118
+ /* harmony import */ var _scrabble_solver_types__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(_scrabble_solver_types__WEBPACK_IMPORTED_MODULE_2__);
119
+ /* harmony import */ var _scrabble_solver_word_definitions__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(98173);
120
+ /* harmony import */ var _scrabble_solver_word_definitions__WEBPACK_IMPORTED_MODULE_3___default = /*#__PURE__*/__webpack_require__.n(_scrabble_solver_word_definitions__WEBPACK_IMPORTED_MODULE_3__);
121
+ /* harmony import */ var api__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(81025);
118
122
 
119
123
 
120
124
 
125
+
126
+
127
+ const MAXIMUM_WORDS_COUNT = _scrabble_solver_configs__WEBPACK_IMPORTED_MODULE_0__.scrabble["en-US"].maximumCharactersCount;
121
128
  const dictionary = async (request, response)=>{
122
- const meta = (0,api__WEBPACK_IMPORTED_MODULE_2__/* .getServerLoggingData */ .X8)(request);
129
+ const meta = (0,api__WEBPACK_IMPORTED_MODULE_4__/* .getServerLoggingData */ .X8)(request);
123
130
  try {
124
- const { locale , word } = parseRequest(request);
125
- _scrabble_solver_logger__WEBPACK_IMPORTED_MODULE_0___default().info("dictionary - request", {
131
+ const { locale , words } = parseRequest(request);
132
+ _scrabble_solver_logger__WEBPACK_IMPORTED_MODULE_1___default().info("dictionary - request", {
126
133
  meta,
127
134
  payload: {
128
135
  locale,
129
- word
136
+ words
130
137
  }
131
138
  });
132
- const result = await (0,_scrabble_solver_word_definitions__WEBPACK_IMPORTED_MODULE_1__.getWordDefinition)(locale, word);
133
- response.status(200).send(result.toJson());
139
+ const results = await Promise.all(words.map((word)=>(0,_scrabble_solver_word_definitions__WEBPACK_IMPORTED_MODULE_3__.getWordDefinition)(locale, word)));
140
+ response.status(200).send(results.map((result)=>result.toJson()));
134
141
  } catch (error) {
135
142
  const message = error instanceof Error ? error.message : "Unknown error";
136
- _scrabble_solver_logger__WEBPACK_IMPORTED_MODULE_0___default().error("dictionary - error", {
143
+ _scrabble_solver_logger__WEBPACK_IMPORTED_MODULE_1___default().error("dictionary - error", {
137
144
  error,
138
145
  meta
139
146
  });
@@ -141,15 +148,24 @@ const dictionary = async (request, response)=>{
141
148
  error: "Server error",
142
149
  message
143
150
  });
151
+ throw error;
144
152
  }
145
153
  };
146
154
  const parseRequest = (request)=>{
147
155
  const { locale , word } = request.query;
148
- (0,api__WEBPACK_IMPORTED_MODULE_2__/* .validateLocale */ .Qb)(locale);
149
- (0,api__WEBPACK_IMPORTED_MODULE_2__/* .validateWord */ .yd)(word);
156
+ if (!(0,_scrabble_solver_types__WEBPACK_IMPORTED_MODULE_2__.isLocale)(locale)) {
157
+ throw new Error('Invalid "locale" parameter');
158
+ }
159
+ if (typeof word !== "string" || word.length === 0) {
160
+ throw new Error('Invalid "word" parameter');
161
+ }
162
+ const words = Array.from(new Set(word.split(",").map((part)=>part.trim()).filter(Boolean)));
163
+ if (words.length > MAXIMUM_WORDS_COUNT) {
164
+ throw new Error('Invalid "word" parameter');
165
+ }
150
166
  return {
151
- locale: locale,
152
- word: word
167
+ locale,
168
+ words
153
169
  };
154
170
  };
155
171
  /* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (dictionary);
@@ -669,7 +685,7 @@ exports["default"] = parseSpanish;
669
685
  var __webpack_require__ = require("../../../../webpack-api-runtime.js");
670
686
  __webpack_require__.C(exports);
671
687
  var __webpack_exec__ = (moduleId) => (__webpack_require__(__webpack_require__.s = moduleId))
672
- var __webpack_exports__ = __webpack_require__.X(0, [50,865,907], () => (__webpack_exec__(15548)));
688
+ var __webpack_exports__ = __webpack_require__.X(0, [50,865,939,911], () => (__webpack_exec__(15548)));
673
689
  module.exports = __webpack_exports__;
674
690
 
675
691
  })();
@@ -1 +1 @@
1
- {"version":1,"files":["../../../../webpack-api-runtime.js","../../../../chunks/50.js","../../../../chunks/865.js","../../../../chunks/907.js","../../../../../package.json"]}
1
+ {"version":1,"files":["../../../../webpack-api-runtime.js","../../../../chunks/50.js","../../../../chunks/865.js","../../../../chunks/939.js","../../../../chunks/911.js","../../../../../package.json"]}
@@ -500,25 +500,329 @@ Object.defineProperty(exports, "MemoryCache", ({ enumerable: true, get: function
500
500
 
501
501
  /***/ }),
502
502
 
503
- /***/ 38104:
503
+ /***/ 207:
504
504
  /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
505
505
 
506
+ // ESM COMPAT FLAG
506
507
  __webpack_require__.r(__webpack_exports__);
507
- /* harmony export */ __webpack_require__.d(__webpack_exports__, {
508
- /* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__)
509
- /* harmony export */ });
510
- /* harmony import */ var _scrabble_solver_configs__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(27911);
511
- /* harmony import */ var _scrabble_solver_configs__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_scrabble_solver_configs__WEBPACK_IMPORTED_MODULE_0__);
512
- /* harmony import */ var _scrabble_solver_constants__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(38436);
513
- /* harmony import */ var _scrabble_solver_dictionaries__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(89044);
514
- /* harmony import */ var _scrabble_solver_dictionaries__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(_scrabble_solver_dictionaries__WEBPACK_IMPORTED_MODULE_2__);
515
- /* harmony import */ var _scrabble_solver_logger__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(52954);
516
- /* harmony import */ var _scrabble_solver_logger__WEBPACK_IMPORTED_MODULE_3___default = /*#__PURE__*/__webpack_require__.n(_scrabble_solver_logger__WEBPACK_IMPORTED_MODULE_3__);
517
- /* harmony import */ var _scrabble_solver_solver__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(40368);
518
- /* harmony import */ var _scrabble_solver_solver__WEBPACK_IMPORTED_MODULE_4___default = /*#__PURE__*/__webpack_require__.n(_scrabble_solver_solver__WEBPACK_IMPORTED_MODULE_4__);
519
- /* harmony import */ var _scrabble_solver_types__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(46452);
520
- /* harmony import */ var _scrabble_solver_types__WEBPACK_IMPORTED_MODULE_5___default = /*#__PURE__*/__webpack_require__.n(_scrabble_solver_types__WEBPACK_IMPORTED_MODULE_5__);
521
- /* harmony import */ var api__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(53888);
508
+
509
+ // EXPORTS
510
+ __webpack_require__.d(__webpack_exports__, {
511
+ "default": () => (/* binding */ api_solve)
512
+ });
513
+
514
+ // EXTERNAL MODULE: ../configs/build/index.js
515
+ var build = __webpack_require__(27911);
516
+ // EXTERNAL MODULE: ../constants/build/index.js
517
+ var constants_build = __webpack_require__(38436);
518
+ // EXTERNAL MODULE: ../dictionaries/build/index.js
519
+ var dictionaries_build = __webpack_require__(89044);
520
+ // EXTERNAL MODULE: ../logger/build/index.js
521
+ var logger_build = __webpack_require__(52954);
522
+ var logger_build_default = /*#__PURE__*/__webpack_require__.n(logger_build);
523
+ // EXTERNAL MODULE: ../solver/build/index.js
524
+ var solver_build = __webpack_require__(40368);
525
+ var solver_build_default = /*#__PURE__*/__webpack_require__.n(solver_build);
526
+ // EXTERNAL MODULE: ../types/build/index.js
527
+ var types_build = __webpack_require__(46452);
528
+ // EXTERNAL MODULE: ./src/api/index.ts + 4 modules
529
+ var api = __webpack_require__(81025);
530
+ ;// CONCATENATED MODULE: ./src/lib/canUseDom.ts
531
+ const canUseDom = Boolean( false && 0);
532
+ /* harmony default export */ const lib_canUseDom = ((/* unused pure expression or super */ null && (canUseDom)));
533
+
534
+ ;// CONCATENATED MODULE: ./src/lib/detectLocale.ts
535
+
536
+ const detectLocale = ()=>{
537
+ if (window.navigator.languages.includes("pl") || window.navigator.languages.includes("pl-PL")) {
538
+ return Locale.PL_PL;
539
+ }
540
+ if (window.navigator.languages.includes("en-GB")) {
541
+ return Locale.EN_GB;
542
+ }
543
+ if (window.navigator.languages.includes("fr-FR")) {
544
+ return Locale.FR_FR;
545
+ }
546
+ return Locale.EN_US;
547
+ };
548
+ /* harmony default export */ const lib_detectLocale = ((/* unused pure expression or super */ null && (detectLocale)));
549
+
550
+ ;// CONCATENATED MODULE: ./src/parameters/index.ts
551
+ const GITHUB_PROJECT_URL = "https://github.com/kamilmielnik/scrabble-solver";
552
+ const TRANSITION_DURATION = 100;
553
+ const TRANSITION_DURATION_LONG = 250;
554
+ const COLOR_BLUE = "#c7d8f9";
555
+ const COLOR_GREEN = "#bae3ba";
556
+ const COLOR_RED = "#f7c2aa";
557
+ const COLOR_YELLOW = "#efe3ae";
558
+ const COMPONENTS_SPACING = 40;
559
+ const COMPONENTS_SPACING_MOBILE = 20;
560
+ const parameters_BOARD_CELL_BORDER_WIDTH = 1;
561
+ const parameters_BOARD_TILE_FONT_SIZE_MIN = 14;
562
+ const parameters_BOARD_TILE_FONT_SIZE_POINTS_MIN = 10;
563
+ const parameters_BOARD_TILE_SIZE_MAX = 64;
564
+ const parameters_BOARD_TILE_SIZE_MIN = 32;
565
+ const DICTIONARY_HEIGHT = 220;
566
+ const TILE_SIZE = 80;
567
+ const PLAIN_TILES_COLOR_DEFAULT = (/* unused pure expression or super */ null && (COLOR_GREEN));
568
+ const PLAIN_TILES_PADDING_HORIZONTAL = 0;
569
+ const PLAIN_TILES_PADDING_VERTICAL = 0;
570
+ const PLAIN_TILES_POINTS_COLORS = {
571
+ 1: COLOR_YELLOW,
572
+ 2: COLOR_GREEN,
573
+ 3: COLOR_BLUE,
574
+ 4: COLOR_RED,
575
+ 5: COLOR_RED,
576
+ 6: COLOR_RED,
577
+ 7: COLOR_RED,
578
+ 8: COLOR_RED,
579
+ 9: COLOR_RED,
580
+ 10: COLOR_RED
581
+ };
582
+ const PLAIN_TILES_TILE_MARGIN = 6;
583
+ const PLAIN_TILES_TILE_MAX_ROTATE = 0;
584
+ const PLAIN_TILES_TILE_MAX_SCATTER = 0;
585
+ const PLAIN_TILES_TILE_SIZE = 80;
586
+ const PLAIN_TILES_VERSION_TILE_COLOR = (/* unused pure expression or super */ null && (COLOR_GREEN));
587
+ const PLAIN_TILES_VERSION_TILE_SIZE = (/* unused pure expression or super */ null && (TILE_SIZE));
588
+ const REMAINING_TILES_TILE_SIZE = 50;
589
+ const RESULTS_HEADER_HEIGHT = 35;
590
+ const RESULTS_ITEM_HEIGHT = 34;
591
+ const RESULTS_INPUT_HEIGHT = 43;
592
+
593
+ ;// CONCATENATED MODULE: ./src/lib/getCellSize.ts
594
+
595
+ const getCellSize = (config, width, height)=>{
596
+ const maxWidth = (width - BOARD_CELL_BORDER_WIDTH) / config.boardWidth - BOARD_CELL_BORDER_WIDTH;
597
+ const maxHeight = (height - BOARD_CELL_BORDER_WIDTH) / config.boardHeight - BOARD_CELL_BORDER_WIDTH;
598
+ const cellSize = Math.min(maxWidth, maxHeight);
599
+ return Math.floor(Math.min(Math.max(cellSize, BOARD_TILE_SIZE_MIN), BOARD_TILE_SIZE_MAX));
600
+ };
601
+ /* harmony default export */ const lib_getCellSize = ((/* unused pure expression or super */ null && (getCellSize)));
602
+
603
+ ;// CONCATENATED MODULE: ./src/lib/getRemainingTiles.ts
604
+
605
+
606
+ const getRemainingTiles = (config, board, characters)=>{
607
+ const nonEmptyCells = board.rows.flat().filter((cell)=>!cell.isEmpty);
608
+ const letterCells = nonEmptyCells.filter((cell)=>!cell.tile.isBlank);
609
+ const remainingTiles = Object.fromEntries(config.tiles.map((tile)=>[
610
+ tile.character,
611
+ {
612
+ ...tile,
613
+ usedCount: 0
614
+ }
615
+ ]));
616
+ const blank = {
617
+ character: BLANK,
618
+ count: config.blanksCount,
619
+ score: config.blankScore,
620
+ usedCount: nonEmptyCells.filter((cell)=>cell.tile.isBlank).length + characters.filter((character)=>character === BLANK).length
621
+ };
622
+ const letters = [
623
+ ...letterCells.map((cell)=>cell.tile.character),
624
+ ...characters.filter((letter)=>letter !== BLANK),
625
+ ];
626
+ const unknownLetters = letters.filter((letter)=>typeof remainingTiles[letter] === "undefined");
627
+ for (const letter of unknownLetters){
628
+ remainingTiles[letter] = {
629
+ character: letter,
630
+ count: 0,
631
+ score: 0,
632
+ usedCount: 0
633
+ };
634
+ }
635
+ for (const letter1 of letters){
636
+ ++remainingTiles[letter1].usedCount;
637
+ }
638
+ return [
639
+ ...Object.values(remainingTiles).sort(createKeyComparator("character")),
640
+ blank
641
+ ];
642
+ };
643
+ /* harmony default export */ const lib_getRemainingTiles = ((/* unused pure expression or super */ null && (getRemainingTiles)));
644
+
645
+ ;// CONCATENATED MODULE: ./src/lib/getRemainingTilesGroups.ts
646
+
647
+
648
+
649
+ const getRemainingTilesGroups = (remainingTiles)=>{
650
+ const consonants = remainingTiles.filter(({ character })=>CONSONANTS.includes(character));
651
+ const vowels = remainingTiles.filter(({ character })=>VOWELS.includes(character));
652
+ const twoCharacterTiles = remainingTiles.filter(({ character })=>character.length === 2);
653
+ const blanks = remainingTiles.filter(({ character })=>character === BLANK);
654
+ const groups = [
655
+ {
656
+ remainingCount: getRemainingTilesCount(vowels),
657
+ tiles: vowels,
658
+ translationKey: "common.vowels",
659
+ totalCount: getTotalRemainingTilesCount(vowels)
660
+ },
661
+ {
662
+ remainingCount: getRemainingTilesCount(consonants),
663
+ tiles: consonants,
664
+ translationKey: "common.consonants",
665
+ totalCount: getTotalRemainingTilesCount(consonants)
666
+ },
667
+ {
668
+ remainingCount: getRemainingTilesCount(twoCharacterTiles),
669
+ tiles: twoCharacterTiles,
670
+ translationKey: "common.two-letter-tiles",
671
+ totalCount: getTotalRemainingTilesCount(twoCharacterTiles)
672
+ },
673
+ {
674
+ remainingCount: getRemainingTilesCount(blanks),
675
+ tiles: blanks,
676
+ translationKey: "common.blanks",
677
+ totalCount: getTotalRemainingTilesCount(blanks)
678
+ },
679
+ ];
680
+ return groups.filter(({ totalCount })=>totalCount > 0);
681
+ };
682
+ /* harmony default export */ const lib_getRemainingTilesGroups = ((/* unused pure expression or super */ null && (getRemainingTilesGroups)));
683
+
684
+ ;// CONCATENATED MODULE: ./src/lib/getTileSizes.ts
685
+
686
+ const getTileSizes = (tileSize)=>({
687
+ pointsFontSize: Math.max(Math.round(tileSize * 0.25), BOARD_TILE_FONT_SIZE_POINTS_MIN),
688
+ tileFontSize: Math.max(Math.round(tileSize * 0.6), BOARD_TILE_FONT_SIZE_MIN),
689
+ tileSize
690
+ });
691
+ /* harmony default export */ const lib_getTileSizes = ((/* unused pure expression or super */ null && (getTileSizes)));
692
+
693
+ ;// CONCATENATED MODULE: ./src/lib/isStringArray.ts
694
+ const isStringArray = (value)=>{
695
+ return Array.isArray(value) && value.every((item)=>typeof item === "string");
696
+ };
697
+ /* harmony default export */ const lib_isStringArray = (isStringArray);
698
+
699
+ ;// CONCATENATED MODULE: ./src/types/index.ts
700
+ var types_SortDirection;
701
+ (function(SortDirection) {
702
+ SortDirection["Ascending"] = "ascending";
703
+ SortDirection["Descending"] = "descending";
704
+ })(types_SortDirection || (types_SortDirection = {}));
705
+ var ResultColumn;
706
+ (function(ResultColumn) {
707
+ ResultColumn["BlanksCount"] = "blanks-count";
708
+ ResultColumn["ConsonantsCount"] = "consonants-count";
709
+ ResultColumn["Points"] = "points";
710
+ ResultColumn["TilesCount"] = "tiles-count";
711
+ ResultColumn["VowelsCount"] = "vowels-count";
712
+ ResultColumn["Word"] = "word";
713
+ ResultColumn["WordsCount"] = "words-count";
714
+ })(ResultColumn || (ResultColumn = {}));
715
+
716
+ ;// CONCATENATED MODULE: ./src/lib/numberComparator.ts
717
+ const numberComparator = (a, b)=>a - b;
718
+ /* harmony default export */ const lib_numberComparator = (numberComparator);
719
+
720
+ ;// CONCATENATED MODULE: ./src/lib/stringComparator.ts
721
+ const stringComparator = (a, b)=>a.localeCompare(b);
722
+ /* harmony default export */ const lib_stringComparator = (stringComparator);
723
+
724
+ ;// CONCATENATED MODULE: ./src/lib/createKeyComparator.ts
725
+
726
+
727
+ const createKeyComparator_createKeyComparator = (key)=>{
728
+ return (a, b)=>{
729
+ const aValue = a[key];
730
+ const bValue = b[key];
731
+ if (typeof aValue === "string" && typeof bValue === "string") {
732
+ return lib_stringComparator(aValue, bValue);
733
+ }
734
+ if (typeof aValue === "number" && typeof bValue === "number") {
735
+ return lib_numberComparator(aValue, bValue);
736
+ }
737
+ return 0;
738
+ };
739
+ };
740
+ /* harmony default export */ const lib_createKeyComparator = (createKeyComparator_createKeyComparator);
741
+
742
+ ;// CONCATENATED MODULE: ./src/lib/sortResults.ts
743
+
744
+
745
+
746
+ const comparators = {
747
+ [ResultColumn.BlanksCount]: lib_createKeyComparator("blanksCount"),
748
+ [ResultColumn.ConsonantsCount]: lib_createKeyComparator("consonantsCount"),
749
+ [ResultColumn.Points]: lib_createKeyComparator("points"),
750
+ [ResultColumn.TilesCount]: lib_createKeyComparator("tilesCount"),
751
+ [ResultColumn.VowelsCount]: lib_createKeyComparator("vowelsCount"),
752
+ [ResultColumn.Word]: lib_createKeyComparator("word"),
753
+ [ResultColumn.WordsCount]: lib_createKeyComparator("wordsCount")
754
+ };
755
+ const sortResults = (results, column, sortDirection)=>{
756
+ if (typeof results === "undefined") {
757
+ return results;
758
+ }
759
+ const comparator = comparators[column];
760
+ const finalComparator = sortDirection === SortDirection.Descending ? reverseComparator(comparator) : comparator;
761
+ return [
762
+ ...results
763
+ ].sort(finalComparator);
764
+ };
765
+ /* harmony default export */ const lib_sortResults = ((/* unused pure expression or super */ null && (sortResults)));
766
+
767
+ ;// CONCATENATED MODULE: ./src/lib/zipCharactersAndTiles.ts
768
+
769
+ const zipCharactersAndTiles = (characters, tiles)=>{
770
+ let remainingTiles = [
771
+ ...tiles
772
+ ];
773
+ return characters.map((character)=>{
774
+ const index = remainingTiles.findIndex((tile)=>character === BLANK ? tile.isBlank : character === tile.character);
775
+ if (index >= 0) {
776
+ const tile = remainingTiles[index];
777
+ remainingTiles = [
778
+ ...remainingTiles.slice(0, index),
779
+ ...remainingTiles.slice(index + 1)
780
+ ];
781
+ return {
782
+ character,
783
+ tile
784
+ };
785
+ }
786
+ return {
787
+ character,
788
+ tile: null
789
+ };
790
+ });
791
+ };
792
+ /* harmony default export */ const lib_zipCharactersAndTiles = ((/* unused pure expression or super */ null && (zipCharactersAndTiles)));
793
+
794
+ ;// CONCATENATED MODULE: ./src/lib/index.ts
795
+
796
+
797
+
798
+
799
+
800
+
801
+
802
+
803
+
804
+
805
+
806
+
807
+
808
+
809
+
810
+
811
+
812
+
813
+
814
+
815
+
816
+
817
+
818
+
819
+
820
+
821
+
822
+
823
+
824
+ ;// CONCATENATED MODULE: ./src/pages/api/solve.ts
825
+
522
826
 
523
827
 
524
828
 
@@ -527,10 +831,10 @@ __webpack_require__.r(__webpack_exports__);
527
831
 
528
832
 
529
833
  const solve = async (request, response)=>{
530
- const meta = (0,api__WEBPACK_IMPORTED_MODULE_6__/* .getServerLoggingData */ .X8)(request);
834
+ const meta = (0,api/* getServerLoggingData */.X8)(request);
531
835
  try {
532
836
  const { board , characters , config , locale } = parseRequest(request);
533
- _scrabble_solver_logger__WEBPACK_IMPORTED_MODULE_3___default().info("solve - request", {
837
+ logger_build_default().info("solve - request", {
534
838
  meta,
535
839
  payload: {
536
840
  board: board.toString(),
@@ -541,23 +845,17 @@ const solve = async (request, response)=>{
541
845
  locale
542
846
  }
543
847
  });
544
- validateRequest({
545
- board,
546
- characters,
547
- config,
548
- locale
549
- });
550
- const trie = await _scrabble_solver_dictionaries__WEBPACK_IMPORTED_MODULE_2__.dictionaries.get(locale);
551
- const tiles = characters.map((character)=>new _scrabble_solver_types__WEBPACK_IMPORTED_MODULE_5__.Tile({
848
+ const trie = await dictionaries_build.dictionaries.get(locale);
849
+ const tiles = characters.map((character)=>new types_build.Tile({
552
850
  character,
553
- isBlank: character === _scrabble_solver_constants__WEBPACK_IMPORTED_MODULE_1__.BLANK
851
+ isBlank: character === constants_build.BLANK
554
852
  }));
555
- const solver = new (_scrabble_solver_solver__WEBPACK_IMPORTED_MODULE_4___default())(config, trie);
853
+ const solver = new (solver_build_default())(config, trie);
556
854
  const results = solver.solve(board, tiles);
557
855
  response.status(200).send(results.map((result)=>result.toJson()));
558
856
  } catch (error) {
559
857
  const message = error instanceof Error ? error.message : "Unknown error";
560
- _scrabble_solver_logger__WEBPACK_IMPORTED_MODULE_3___default().error("solve - error", {
858
+ logger_build_default().error("solve - error", {
561
859
  error,
562
860
  meta
563
861
  });
@@ -565,30 +863,43 @@ const solve = async (request, response)=>{
565
863
  error: "Server error",
566
864
  message
567
865
  });
866
+ throw error;
568
867
  }
569
868
  };
570
869
  const parseRequest = (request)=>{
571
- const { board , characters , configId , locale } = request.body;
572
- (0,api__WEBPACK_IMPORTED_MODULE_6__/* .validateConfigId */ .Qm)(configId);
573
- (0,api__WEBPACK_IMPORTED_MODULE_6__/* .validateLocale */ .Qb)(locale);
574
- const config = (0,_scrabble_solver_configs__WEBPACK_IMPORTED_MODULE_0__.getLocaleConfig)(configId, locale);
575
- (0,api__WEBPACK_IMPORTED_MODULE_6__/* .validateBoard */ .U4)(board, config);
576
- (0,api__WEBPACK_IMPORTED_MODULE_6__/* .validateCharacters */ .EN)(characters, config);
870
+ const { board: boardJson , characters , configId , locale } = request.body;
871
+ if (!(0,types_build.isLocale)(locale)) {
872
+ throw new Error('Invalid "locale" parameter');
873
+ }
874
+ if (!(0,build.isConfigId)(configId)) {
875
+ throw new Error('Invalid "configId" parameter');
876
+ }
877
+ const config = (0,build.getLocaleConfig)(configId, locale);
878
+ if (!(0,types_build.isBoardJson)(boardJson) || !(0,api/* isBoardValid */.p2)(boardJson, config)) {
879
+ throw new Error('Invalid "board" parameter');
880
+ }
881
+ if (!lib_isStringArray(characters) || characters.length === 0) {
882
+ throw new Error('Invalid "characters" parameter');
883
+ }
884
+ for (const character of characters){
885
+ if (!config.hasCharacter(character) && character !== constants_build.BLANK) {
886
+ throw new Error('Invalid "characters" parameter');
887
+ }
888
+ }
889
+ const board = types_build.Board.fromJson(boardJson);
890
+ const blankTilesCount = characters.filter((character)=>character === constants_build.BLANK).length;
891
+ const blanksCount = board.getBlanksCount() + blankTilesCount;
892
+ if (blanksCount > config.blanksCount) {
893
+ throw new Error("Too many blank tiles passed");
894
+ }
577
895
  return {
578
- board: _scrabble_solver_types__WEBPACK_IMPORTED_MODULE_5__.Board.fromJson(board),
896
+ board,
579
897
  characters,
580
898
  config,
581
899
  locale
582
900
  };
583
901
  };
584
- const validateRequest = ({ board , characters , config })=>{
585
- const blankTilesCount = characters.filter((character)=>character === _scrabble_solver_constants__WEBPACK_IMPORTED_MODULE_1__.BLANK).length;
586
- const blanksCount = board.getBlanksCount() + blankTilesCount;
587
- if (blanksCount > config.numberOfBlanks) {
588
- throw new Error(`Too many blank tiles passed (board: ${board.getBlanksCount()}, tiles: ${blankTilesCount})`);
589
- }
590
- };
591
- /* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (solve);
902
+ /* harmony default export */ const api_solve = (solve);
592
903
 
593
904
 
594
905
  /***/ }),
@@ -607,7 +918,7 @@ class PatternsFiller {
607
918
  }
608
919
  fill(pattern, tiles) {
609
920
  const patterns = [];
610
- if (pattern.getNumberOfEmptyCells() > tiles.length) {
921
+ if (pattern.getEmptyCellsCount() > tiles.length) {
611
922
  return [];
612
923
  }
613
924
  const onPatternFound = (newPattern) => patterns.push(newPattern);
@@ -687,25 +998,25 @@ class PatternsGenerator {
687
998
  return this.generatePatterns({
688
999
  board,
689
1000
  getNthVector: (index) => board.getRow(index),
690
- numberOfVectors: this.config.boardHeight,
691
1001
  PatternModel: types_1.HorizontalPattern,
1002
+ vectorsCount: this.config.boardHeight,
692
1003
  });
693
1004
  }
694
1005
  generateVertical(board) {
695
1006
  return this.generatePatterns({
696
1007
  board,
697
1008
  getNthVector: (index) => board.getColumn(index),
698
- numberOfVectors: this.config.boardWidth,
699
1009
  PatternModel: types_1.VerticalPattern,
1010
+ vectorsCount: this.config.boardWidth,
700
1011
  });
701
1012
  }
702
- generatePatterns({ board, getNthVector, numberOfVectors, PatternModel, }) {
703
- return this.generateVectors({ getNthVector, numberOfVectors }).reduce((patterns, cells) => {
1013
+ generatePatterns({ board, getNthVector, vectorsCount, PatternModel, }) {
1014
+ return this.generateVectors({ getNthVector, vectorsCount }).reduce((patterns, cells) => {
704
1015
  return patterns.concat(this.generateCellsPatterns({ board, PatternModel, cells }));
705
1016
  }, []);
706
1017
  }
707
- generateVectors({ getNthVector, numberOfVectors, }) {
708
- return Array(numberOfVectors)
1018
+ generateVectors({ getNthVector, vectorsCount, }) {
1019
+ return Array(vectorsCount)
709
1020
  .fill(0)
710
1021
  .map((_, index) => getNthVector(index));
711
1022
  }
@@ -766,7 +1077,7 @@ class ScoresCalculator {
766
1077
  return this.calculatePatternScoreWithCollisions(pattern) + this.calculateBonusScore(pattern);
767
1078
  }
768
1079
  calculateBonusScore(pattern) {
769
- const areAllTilesUsed = pattern.getNumberOfEmptyCells() === this.config.maximumNumberOfCharacters;
1080
+ const areAllTilesUsed = pattern.getEmptyCellsCount() === this.config.maximumCharactersCount;
770
1081
  return areAllTilesUsed ? this.config.allTilesBonusScore : 0;
771
1082
  }
772
1083
  calculatePatternScoreWithCollisions(pattern) {
@@ -796,7 +1107,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
796
1107
  };
797
1108
  Object.defineProperty(exports, "__esModule", ({ value: true }));
798
1109
  const types_1 = __webpack_require__(46452);
799
- const uniqBy_1 = __importDefault(__webpack_require__(50285));
1110
+ const getUniquePatterns_1 = __importDefault(__webpack_require__(55555));
800
1111
  const PatternsFiller_1 = __importDefault(__webpack_require__(6700));
801
1112
  const PatternsGenerator_1 = __importDefault(__webpack_require__(34196));
802
1113
  const ScoresCalculator_1 = __importDefault(__webpack_require__(19368));
@@ -809,11 +1120,11 @@ class Solver {
809
1120
  solve(board, tiles) {
810
1121
  const patterns = this.patternsGenerator.generate(board);
811
1122
  const filledPatterns = patterns.flatMap((pattern) => this.patternsFiller.fill(pattern, tiles));
812
- const uniquePatterns = (0, uniqBy_1.default)(filledPatterns, (pattern) => JSON.stringify(pattern.toJson()));
1123
+ const uniquePatterns = (0, getUniquePatterns_1.default)(filledPatterns);
813
1124
  const results = uniquePatterns.map((pattern, index) => new types_1.Result({
814
1125
  cells: pattern.cells,
1126
+ collisions: pattern.getCollisions().map((collision) => collision.cells),
815
1127
  id: index,
816
- numberOfCollisions: pattern.getCollisions().length,
817
1128
  points: this.scoresCalculator.calculate(pattern),
818
1129
  }));
819
1130
  return results;
@@ -822,6 +1133,38 @@ class Solver {
822
1133
  exports["default"] = Solver;
823
1134
 
824
1135
 
1136
+ /***/ }),
1137
+
1138
+ /***/ 55555:
1139
+ /***/ ((__unused_webpack_module, exports) => {
1140
+
1141
+
1142
+ Object.defineProperty(exports, "__esModule", ({ value: true }));
1143
+ const getPatternHash = (pattern) => {
1144
+ return pattern.cells
1145
+ .map((cell) => {
1146
+ const blank = cell.tile.isBlank ? '!' : '';
1147
+ const tile = cell.tile.character + blank;
1148
+ // eslint-disable-next-line prefer-template
1149
+ return cell.x + ',' + cell.y + ',' + tile;
1150
+ })
1151
+ .join('-');
1152
+ };
1153
+ const getUniquePatterns = (patterns) => {
1154
+ const hashes = new Set();
1155
+ const uniquePatterns = [];
1156
+ for (const pattern of patterns) {
1157
+ const hash = getPatternHash(pattern);
1158
+ if (!hashes.has(hash)) {
1159
+ hashes.add(hash);
1160
+ uniquePatterns.push(pattern);
1161
+ }
1162
+ }
1163
+ return uniquePatterns;
1164
+ };
1165
+ exports["default"] = getUniquePatterns;
1166
+
1167
+
825
1168
  /***/ }),
826
1169
 
827
1170
  /***/ 40368:
@@ -1265,7 +1608,7 @@ Object.defineProperty(exports, "getTxtWordList", ({ enumerable: true, get: funct
1265
1608
  var __webpack_require__ = require("../../webpack-api-runtime.js");
1266
1609
  __webpack_require__.C(exports);
1267
1610
  var __webpack_exec__ = (moduleId) => (__webpack_require__(__webpack_require__.s = moduleId))
1268
- var __webpack_exports__ = __webpack_require__.X(0, [50,206,907], () => (__webpack_exec__(38104)));
1611
+ var __webpack_exports__ = __webpack_require__.X(0, [50,429,939,911], () => (__webpack_exec__(207)));
1269
1612
  module.exports = __webpack_exports__;
1270
1613
 
1271
1614
  })();
@@ -1 +1 @@
1
- {"version":1,"files":["../../webpack-api-runtime.js","../../chunks/50.js","../../chunks/206.js","../../chunks/907.js","../../../package.json"]}
1
+ {"version":1,"files":["../../webpack-api-runtime.js","../../chunks/50.js","../../chunks/429.js","../../chunks/939.js","../../chunks/911.js","../../../package.json"]}