@scrabble-solver/scrabble-solver 2.8.7 → 2.8.9

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 (92) hide show
  1. package/.next/BUILD_ID +1 -1
  2. package/.next/build-manifest.json +10 -10
  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 +257 -55
  14. package/.next/server/chunks/44.js +802 -0
  15. package/.next/server/chunks/515.js +452 -104
  16. package/.next/server/chunks/911.js +53 -23
  17. package/.next/server/middleware-build-manifest.js +1 -1
  18. package/.next/server/pages/404.html +2 -2
  19. package/.next/server/pages/404.js.nft.json +1 -1
  20. package/.next/server/pages/500.html +2 -2
  21. package/.next/server/pages/_app.js.nft.json +1 -1
  22. package/.next/server/pages/_document.js.nft.json +1 -1
  23. package/.next/server/pages/_error.js.nft.json +1 -1
  24. package/.next/server/pages/api/solve.js +193 -927
  25. package/.next/server/pages/api/solve.js.nft.json +1 -1
  26. package/.next/server/pages/api/verify.js +217 -0
  27. package/.next/server/pages/api/verify.js.nft.json +1 -0
  28. package/.next/server/pages/index.html +3 -3
  29. package/.next/server/pages/index.js +7 -1
  30. package/.next/server/pages/index.js.nft.json +1 -1
  31. package/.next/server/pages/index.json +1 -1
  32. package/.next/server/pages-manifest.json +1 -0
  33. package/.next/static/chunks/317-a33dd38e9b9a17ed.js +1 -0
  34. package/.next/static/chunks/pages/{404-30c06e61d256c5b2.js → 404-90c624da3c83fd17.js} +1 -1
  35. package/.next/static/chunks/pages/_app-f8f360878e1c2aff.js +1 -0
  36. package/.next/static/chunks/pages/index-ecea697d3e5d8a6f.js +1 -0
  37. package/.next/static/css/64dc2ce1811912f1.css +1 -0
  38. package/.next/static/css/{cdbc9e0afcff5473.css → ad2a08918868cad8.css} +1 -1
  39. package/.next/static/yCxjzzYpw5JjJE53PO_s6/_buildManifest.js +1 -0
  40. package/.next/static/{z_0_lqfmiI_ISokr6NNRq → yCxjzzYpw5JjJE53PO_s6}/_ssgManifest.js +0 -0
  41. package/.next/trace +42 -40
  42. package/package.json +9 -9
  43. package/src/components/Badge/Badge.module.scss +13 -0
  44. package/src/components/Badge/Badge.tsx +15 -0
  45. package/src/components/Badge/index.ts +1 -0
  46. package/src/components/Board/components/Cell/Cell.module.scss +34 -9
  47. package/src/components/Board/components/Cell/Cell.tsx +23 -4
  48. package/src/components/Board/components/Cell/CellPure.tsx +29 -1
  49. package/src/components/Board/hooks/useGrid.ts +1 -0
  50. package/src/components/NavButtons/NavButtons.tsx +33 -14
  51. package/src/components/RemainingTiles/RemainingTiles.module.scss +8 -7
  52. package/src/components/RemainingTiles/RemainingTiles.tsx +13 -4
  53. package/src/components/Sidebar/Sidebar.tsx +2 -2
  54. package/src/components/Sidebar/components/Section/Section.module.scss +0 -1
  55. package/src/components/Sidebar/components/Section/Section.tsx +1 -1
  56. package/src/components/SquareButton/SquareButton.module.scss +5 -0
  57. package/src/components/Words/Words.module.scss +35 -0
  58. package/src/components/Words/Words.tsx +57 -0
  59. package/src/components/Words/index.ts +1 -0
  60. package/src/components/index.ts +2 -0
  61. package/src/i18n/de.json +5 -1
  62. package/src/i18n/en.json +5 -1
  63. package/src/i18n/es.json +5 -1
  64. package/src/i18n/fr.json +5 -1
  65. package/src/i18n/pl.json +5 -1
  66. package/src/icons/BookHalf.svg +4 -0
  67. package/src/icons/Check.svg +4 -0
  68. package/src/icons/Cross.svg +2 -2
  69. package/src/icons/CrossFill.svg +4 -0
  70. package/src/icons/Flag.svg +4 -0
  71. package/src/icons/Star.svg +4 -0
  72. package/src/icons/index.ts +5 -0
  73. package/src/pages/api/solve.ts +2 -3
  74. package/src/pages/api/verify.ts +71 -0
  75. package/src/pages/index.tsx +5 -0
  76. package/src/sdk/index.ts +1 -0
  77. package/src/sdk/verify.ts +24 -0
  78. package/src/state/rootReducer.ts +12 -1
  79. package/src/state/sagas.ts +54 -7
  80. package/src/state/selectors.ts +49 -11
  81. package/src/state/slices/cellFilterInitialState.ts +7 -0
  82. package/src/state/slices/cellFilterSlice.ts +24 -0
  83. package/src/state/slices/index.ts +4 -0
  84. package/src/state/slices/verifyInitialState.ts +12 -0
  85. package/src/state/slices/verifySlice.ts +31 -0
  86. package/src/styles/variables.scss +2 -1
  87. package/src/types/index.ts +5 -1
  88. package/.next/static/chunks/56-cf37c430261bbea5.js +0 -1
  89. package/.next/static/chunks/pages/_app-0b12a65bea70a0df.js +0 -1
  90. package/.next/static/chunks/pages/index-fcb69802550afb81.js +0 -1
  91. package/.next/static/css/1f39b55d50f5b30b.css +0 -1
  92. package/.next/static/z_0_lqfmiI_ISokr6NNRq/_buildManifest.js +0 -1
@@ -122,382 +122,6 @@ module.exports = require("util");
122
122
 
123
123
  module.exports = require("zlib");
124
124
 
125
- /***/ }),
126
-
127
- /***/ 21285:
128
- /***/ (function(__unused_webpack_module, exports, __webpack_require__) {
129
-
130
-
131
- var __importDefault = (this && this.__importDefault) || function (mod) {
132
- return (mod && mod.__esModule) ? mod : { "default": mod };
133
- };
134
- Object.defineProperty(exports, "__esModule", ({ value: true }));
135
- const logger_1 = __importDefault(__webpack_require__(52954));
136
- const types_1 = __webpack_require__(46452);
137
- const fs_1 = __importDefault(__webpack_require__(57147));
138
- const constants_1 = __webpack_require__(75823);
139
- const lib_1 = __webpack_require__(26137);
140
- class Dictionaries {
141
- constructor() {
142
- this.cache = new lib_1.LayeredCache();
143
- this.downloadDictionaryProxies = Object.fromEntries(Object.values(types_1.Locale).map((locale) => [locale, (0, lib_1.createAsyncProxy)(() => (0, lib_1.downloadDictionary)(locale))]));
144
- }
145
- async get(locale) {
146
- if (this.cache.has(locale)) {
147
- const trie = await this.cache.get(locale);
148
- if (trie) {
149
- return trie;
150
- }
151
- }
152
- logger_1.default.info('Dictionaries - cache miss', { locale });
153
- return this.updateDictionary(locale);
154
- }
155
- remove() {
156
- fs_1.default.rmdirSync(constants_1.OUTPUT_DIRECTORY, { recursive: true });
157
- }
158
- async update(force) {
159
- const locales = force ? Object.values(types_1.Locale) : this.getLocalesToUpdate();
160
- logger_1.default.info('Dictionaries - update', { force, locales });
161
- await Promise.all(locales.map((locale) => this.updateDictionary(locale)));
162
- }
163
- getLocalesToUpdate() {
164
- return Object.values(types_1.Locale).filter((locale) => this.cache.isStale(locale) !== false);
165
- }
166
- async updateDictionary(locale) {
167
- logger_1.default.info('Dictionaries - updateDictionary', { locale });
168
- fs_1.default.mkdirSync(constants_1.OUTPUT_DIRECTORY, { recursive: true });
169
- const downloadDictionaryProxy = this.downloadDictionaryProxies[locale];
170
- const trie = await downloadDictionaryProxy();
171
- await this.cache.set(locale, trie);
172
- return trie;
173
- }
174
- }
175
- exports["default"] = Dictionaries;
176
-
177
-
178
- /***/ }),
179
-
180
- /***/ 75823:
181
- /***/ (function(__unused_webpack_module, exports, __webpack_require__) {
182
-
183
-
184
- var __importDefault = (this && this.__importDefault) || function (mod) {
185
- return (mod && mod.__esModule) ? mod : { "default": mod };
186
- };
187
- Object.defineProperty(exports, "__esModule", ({ value: true }));
188
- exports.OUTPUT_DIRECTORY = exports.CACHE_STALE_THRESHOLD = exports.DAY = void 0;
189
- const os_1 = __importDefault(__webpack_require__(22037));
190
- const path_1 = __importDefault(__webpack_require__(71017));
191
- exports.DAY = 24 * 60 * 60 * 1000;
192
- exports.CACHE_STALE_THRESHOLD = 30 * exports.DAY;
193
- exports.OUTPUT_DIRECTORY = path_1.default.resolve(os_1.default.homedir(), '.scrabble-solver', 'dictionaries');
194
-
195
-
196
- /***/ }),
197
-
198
- /***/ 89044:
199
- /***/ (function(__unused_webpack_module, exports, __webpack_require__) {
200
-
201
-
202
- var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
203
- if (k2 === undefined) k2 = k;
204
- var desc = Object.getOwnPropertyDescriptor(m, k);
205
- if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
206
- desc = { enumerable: true, get: function() { return m[k]; } };
207
- }
208
- Object.defineProperty(o, k2, desc);
209
- }) : (function(o, m, k, k2) {
210
- if (k2 === undefined) k2 = k;
211
- o[k2] = m[k];
212
- }));
213
- var __exportStar = (this && this.__exportStar) || function(m, exports) {
214
- for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
215
- };
216
- var __importDefault = (this && this.__importDefault) || function (mod) {
217
- return (mod && mod.__esModule) ? mod : { "default": mod };
218
- };
219
- Object.defineProperty(exports, "__esModule", ({ value: true }));
220
- exports.dictionaries = void 0;
221
- const Dictionaries_1 = __importDefault(__webpack_require__(21285));
222
- __exportStar(__webpack_require__(26137), exports);
223
- exports.dictionaries = new Dictionaries_1.default();
224
-
225
-
226
- /***/ }),
227
-
228
- /***/ 2812:
229
- /***/ (function(__unused_webpack_module, exports, __webpack_require__) {
230
-
231
-
232
- var __importDefault = (this && this.__importDefault) || function (mod) {
233
- return (mod && mod.__esModule) ? mod : { "default": mod };
234
- };
235
- Object.defineProperty(exports, "__esModule", ({ value: true }));
236
- const trie_1 = __webpack_require__(83140);
237
- const fs_1 = __importDefault(__webpack_require__(57147));
238
- const constants_1 = __webpack_require__(75823);
239
- const getDictionaryFilepath_1 = __importDefault(__webpack_require__(68638));
240
- class DiskCache {
241
- async get(locale) {
242
- if (!this.has(locale)) {
243
- return undefined;
244
- }
245
- const filepath = (0, getDictionaryFilepath_1.default)(locale);
246
- const serialized = await fs_1.default.promises.readFile(filepath, 'utf-8');
247
- const trie = trie_1.Trie.deserialize(serialized);
248
- return trie;
249
- }
250
- getLastModifiedTimestamp(locale) {
251
- const filepath = (0, getDictionaryFilepath_1.default)(locale);
252
- if (!fs_1.default.existsSync(filepath)) {
253
- return undefined;
254
- }
255
- const stats = fs_1.default.statSync(filepath);
256
- return stats.mtimeMs;
257
- }
258
- has(locale) {
259
- const filepath = (0, getDictionaryFilepath_1.default)(locale);
260
- return fs_1.default.existsSync(filepath);
261
- }
262
- isStale(locale) {
263
- if (!this.has(locale)) {
264
- return undefined;
265
- }
266
- const lastModifiedTimestamp = this.getLastModifiedTimestamp(locale);
267
- if (typeof lastModifiedTimestamp === 'undefined') {
268
- return undefined;
269
- }
270
- const timeSinceModification = Math.abs(lastModifiedTimestamp - Date.now());
271
- return timeSinceModification > constants_1.CACHE_STALE_THRESHOLD;
272
- }
273
- async set(locale, trie) {
274
- const filepath = (0, getDictionaryFilepath_1.default)(locale);
275
- await fs_1.default.promises.writeFile(filepath, trie.serialize());
276
- }
277
- }
278
- exports["default"] = DiskCache;
279
-
280
-
281
- /***/ }),
282
-
283
- /***/ 70287:
284
- /***/ (function(__unused_webpack_module, exports, __webpack_require__) {
285
-
286
-
287
- var __importDefault = (this && this.__importDefault) || function (mod) {
288
- return (mod && mod.__esModule) ? mod : { "default": mod };
289
- };
290
- Object.defineProperty(exports, "__esModule", ({ value: true }));
291
- const createCacheTimestampComparator_1 = __importDefault(__webpack_require__(20494));
292
- const DiskCache_1 = __importDefault(__webpack_require__(2812));
293
- const MemoryCache_1 = __importDefault(__webpack_require__(50192));
294
- class LayeredCache {
295
- constructor() {
296
- this.layers = [new MemoryCache_1.default(), new DiskCache_1.default()];
297
- }
298
- async get(locale) {
299
- const cache = this.getLastModifiedLayer(locale);
300
- if (!cache) {
301
- return Promise.resolve(undefined);
302
- }
303
- const [memoryCache, diskCache] = this.layers;
304
- const value = await cache.get(locale);
305
- if (cache === diskCache && typeof value !== 'undefined') {
306
- await memoryCache.set(locale, value);
307
- }
308
- return value;
309
- }
310
- getLastModifiedTimestamp(locale) {
311
- const cache = this.getLastModifiedLayer(locale);
312
- if (!cache) {
313
- return undefined;
314
- }
315
- return cache.getLastModifiedTimestamp(locale);
316
- }
317
- has(locale) {
318
- return this.layers.some((cache) => cache.has(locale));
319
- }
320
- isStale(locale) {
321
- if (this.layers.some((cache) => cache.isStale(locale))) {
322
- return true;
323
- }
324
- if (this.layers.every((cache) => typeof cache.isStale(locale) === 'undefined')) {
325
- return undefined;
326
- }
327
- return false;
328
- }
329
- async set(locale, trie) {
330
- const [memoryCache, diskCache] = this.layers;
331
- await diskCache.set(locale, trie);
332
- await memoryCache.set(locale, trie);
333
- }
334
- getLastModifiedLayer(locale) {
335
- const layers = this.layers.filter((cache) => cache.has(locale));
336
- const [cached] = [...layers].sort((0, createCacheTimestampComparator_1.default)(locale));
337
- return cached;
338
- }
339
- }
340
- exports["default"] = LayeredCache;
341
-
342
-
343
- /***/ }),
344
-
345
- /***/ 50192:
346
- /***/ ((__unused_webpack_module, exports, __webpack_require__) => {
347
-
348
-
349
- Object.defineProperty(exports, "__esModule", ({ value: true }));
350
- const constants_1 = __webpack_require__(75823);
351
- class MemoryCache {
352
- constructor() {
353
- this.cache = {};
354
- this.cacheTimestamps = {};
355
- }
356
- get(locale) {
357
- return Promise.resolve(this.cache[locale]);
358
- }
359
- getLastModifiedTimestamp(locale) {
360
- return this.cacheTimestamps[locale];
361
- }
362
- has(locale) {
363
- return typeof this.cache[locale] !== 'undefined';
364
- }
365
- isStale(locale) {
366
- const timestamp = this.getLastModifiedTimestamp(locale);
367
- if (!this.has(locale) || typeof timestamp === 'undefined') {
368
- return undefined;
369
- }
370
- const timeSinceModification = Math.abs(timestamp - Date.now());
371
- return timeSinceModification > constants_1.CACHE_STALE_THRESHOLD;
372
- }
373
- set(locale, trie) {
374
- this.cacheTimestamps[locale] = Date.now();
375
- this.cache[locale] = trie;
376
- return Promise.resolve();
377
- }
378
- }
379
- exports["default"] = MemoryCache;
380
-
381
-
382
- /***/ }),
383
-
384
- /***/ 26554:
385
- /***/ ((__unused_webpack_module, exports) => {
386
-
387
-
388
- Object.defineProperty(exports, "__esModule", ({ value: true }));
389
- const createAsyncProxy = (asyncCallback) => {
390
- let promise = null;
391
- return async () => {
392
- if (promise) {
393
- return promise;
394
- }
395
- try {
396
- promise = asyncCallback();
397
- return await promise;
398
- }
399
- finally {
400
- promise = null;
401
- }
402
- };
403
- };
404
- exports["default"] = createAsyncProxy;
405
-
406
-
407
- /***/ }),
408
-
409
- /***/ 20494:
410
- /***/ ((__unused_webpack_module, exports) => {
411
-
412
-
413
- Object.defineProperty(exports, "__esModule", ({ value: true }));
414
- const createCacheTimestampComparator = (locale) => {
415
- return (a, b) => {
416
- const aTimestamp = a.getLastModifiedTimestamp(locale);
417
- const bTimestamp = b.getLastModifiedTimestamp(locale);
418
- if (aTimestamp === bTimestamp) {
419
- return 0;
420
- }
421
- if (typeof aTimestamp === 'undefined') {
422
- return 1;
423
- }
424
- if (typeof bTimestamp === 'undefined') {
425
- return -1;
426
- }
427
- return bTimestamp - aTimestamp;
428
- };
429
- };
430
- exports["default"] = createCacheTimestampComparator;
431
-
432
-
433
- /***/ }),
434
-
435
- /***/ 41281:
436
- /***/ (function(__unused_webpack_module, exports, __webpack_require__) {
437
-
438
-
439
- var __importDefault = (this && this.__importDefault) || function (mod) {
440
- return (mod && mod.__esModule) ? mod : { "default": mod };
441
- };
442
- Object.defineProperty(exports, "__esModule", ({ value: true }));
443
- const trie_1 = __webpack_require__(83140);
444
- const logger_1 = __importDefault(__webpack_require__(52954));
445
- const word_lists_1 = __webpack_require__(51585);
446
- const downloadDictionary = async (locale) => {
447
- logger_1.default.info('downloadDictionary', { locale });
448
- const words = await (0, word_lists_1.getWordList)(locale);
449
- logger_1.default.info('downloadDictionary - success', { locale });
450
- const trie = trie_1.Trie.fromArray(words);
451
- return trie;
452
- };
453
- exports["default"] = downloadDictionary;
454
-
455
-
456
- /***/ }),
457
-
458
- /***/ 68638:
459
- /***/ (function(__unused_webpack_module, exports, __webpack_require__) {
460
-
461
-
462
- var __importDefault = (this && this.__importDefault) || function (mod) {
463
- return (mod && mod.__esModule) ? mod : { "default": mod };
464
- };
465
- Object.defineProperty(exports, "__esModule", ({ value: true }));
466
- const path_1 = __importDefault(__webpack_require__(71017));
467
- const constants_1 = __webpack_require__(75823);
468
- const getDictionaryFilepath = (locale) => {
469
- return path_1.default.resolve(constants_1.OUTPUT_DIRECTORY, `${locale}.txt`);
470
- };
471
- exports["default"] = getDictionaryFilepath;
472
-
473
-
474
- /***/ }),
475
-
476
- /***/ 26137:
477
- /***/ (function(__unused_webpack_module, exports, __webpack_require__) {
478
-
479
-
480
- var __importDefault = (this && this.__importDefault) || function (mod) {
481
- return (mod && mod.__esModule) ? mod : { "default": mod };
482
- };
483
- Object.defineProperty(exports, "__esModule", ({ value: true }));
484
- exports.MemoryCache = exports.LayeredCache = exports.getDictionaryFilepath = exports.downloadDictionary = exports.DiskCache = exports.createCacheTimestampComparator = exports.createAsyncProxy = void 0;
485
- var createAsyncProxy_1 = __webpack_require__(26554);
486
- Object.defineProperty(exports, "createAsyncProxy", ({ enumerable: true, get: function () { return __importDefault(createAsyncProxy_1).default; } }));
487
- var createCacheTimestampComparator_1 = __webpack_require__(20494);
488
- Object.defineProperty(exports, "createCacheTimestampComparator", ({ enumerable: true, get: function () { return __importDefault(createCacheTimestampComparator_1).default; } }));
489
- var DiskCache_1 = __webpack_require__(2812);
490
- Object.defineProperty(exports, "DiskCache", ({ enumerable: true, get: function () { return __importDefault(DiskCache_1).default; } }));
491
- var downloadDictionary_1 = __webpack_require__(41281);
492
- Object.defineProperty(exports, "downloadDictionary", ({ enumerable: true, get: function () { return __importDefault(downloadDictionary_1).default; } }));
493
- var getDictionaryFilepath_1 = __webpack_require__(68638);
494
- Object.defineProperty(exports, "getDictionaryFilepath", ({ enumerable: true, get: function () { return __importDefault(getDictionaryFilepath_1).default; } }));
495
- var LayeredCache_1 = __webpack_require__(70287);
496
- Object.defineProperty(exports, "LayeredCache", ({ enumerable: true, get: function () { return __importDefault(LayeredCache_1).default; } }));
497
- var MemoryCache_1 = __webpack_require__(50192);
498
- Object.defineProperty(exports, "MemoryCache", ({ enumerable: true, get: function () { return __importDefault(MemoryCache_1).default; } }));
499
-
500
-
501
125
  /***/ }),
502
126
 
503
127
  /***/ 207:
@@ -522,7 +146,6 @@ var logger_build = __webpack_require__(52954);
522
146
  var logger_build_default = /*#__PURE__*/__webpack_require__.n(logger_build);
523
147
  // EXTERNAL MODULE: ../solver/build/index.js
524
148
  var solver_build = __webpack_require__(40368);
525
- var solver_build_default = /*#__PURE__*/__webpack_require__.n(solver_build);
526
149
  // EXTERNAL MODULE: ../types/build/index.js
527
150
  var types_build = __webpack_require__(46452);
528
151
  // EXTERNAL MODULE: ./src/api/index.ts + 4 modules
@@ -850,8 +473,7 @@ const solve = async (request, response)=>{
850
473
  character,
851
474
  isBlank: character === constants_build.BLANK
852
475
  }));
853
- const solver = new (solver_build_default())(config, trie);
854
- const results = solver.solve(board, tiles);
476
+ const results = (0,solver_build.solve)(trie, config, board, tiles);
855
477
  response.status(200).send(results.map((result)=>result.toJson()));
856
478
  } catch (error) {
857
479
  const message = error instanceof Error ? error.message : "Unknown error";
@@ -904,201 +526,82 @@ const parseRequest = (request)=>{
904
526
 
905
527
  /***/ }),
906
528
 
907
- /***/ 6700:
529
+ /***/ 83594:
908
530
  /***/ ((__unused_webpack_module, exports, __webpack_require__) => {
909
531
 
910
532
 
911
533
  Object.defineProperty(exports, "__esModule", ({ value: true }));
534
+ exports.fillPatternRecursive = void 0;
912
535
  const constants_1 = __webpack_require__(38436);
913
536
  const types_1 = __webpack_require__(46452);
914
- class PatternsFiller {
915
- constructor(config, trie) {
916
- this.config = config;
917
- this.trie = trie;
918
- }
919
- fill(pattern, tiles) {
920
- const patterns = [];
921
- if (pattern.getEmptyCellsCount() > tiles.length) {
922
- return [];
923
- }
924
- const onPatternFound = (newPattern) => patterns.push(newPattern);
925
- const tilesPermutations = this.generateBlankTilesPermutations(tiles);
926
- for (let index = 0; index < tilesPermutations.length; ++index) {
927
- const tilesPermutation = tilesPermutations[index];
928
- this.fillPattern(pattern, pattern.toString(), tilesPermutation, onPatternFound);
929
- }
930
- return patterns;
931
- }
932
- fillPattern(pattern, word, tiles, onPatternFound) {
933
- const indexOfFirstCellWithoutTile = pattern.getIndexOfFirstCellWithoutTile();
934
- if (indexOfFirstCellWithoutTile === -1) {
935
- if (this.canAddPattern(pattern, word)) {
936
- onPatternFound(pattern.clone());
937
- }
537
+ const fillPattern = (trie, config, pattern, tiles) => {
538
+ if (pattern.getEmptyCellsCount() > tiles.length) {
539
+ return [];
540
+ }
541
+ const results = [];
542
+ (0, exports.fillPatternRecursive)(results, trie, config, pattern, pattern.toString(), tiles);
543
+ return results;
544
+ };
545
+ const fillPatternRecursive = (
546
+ /** gets mutated when this function is called */
547
+ results, trie, config, pattern, word, tiles) => {
548
+ const indexOfFirstCellWithoutTile = pattern.getIndexOfFirstCellWithoutTile();
549
+ if (indexOfFirstCellWithoutTile === -1) {
550
+ if (trie.has(word) && pattern.getCollisions().every((collision) => trie.has(collision.toString()))) {
551
+ results.push(new types_1.FinalPattern(pattern.clone()));
938
552
  }
939
- else {
940
- for (let index = 0; index < tiles.length; ++index) {
941
- const tile = tiles[index];
942
- const previousTile = pattern.cells[indexOfFirstCellWithoutTile].tile;
943
- pattern.cells[indexOfFirstCellWithoutTile].tile = tile;
944
- const indexOfNextCellWithoutTile = pattern.getIndexOfFirstCellWithoutTile();
945
- const indexOfFirstEmptyLetter = word.indexOf(constants_1.EMPTY_CELL);
946
- const newWordPrefix = word.substring(0, indexOfFirstEmptyLetter) + tile.character;
947
- const newWord = newWordPrefix + word.substring(indexOfFirstEmptyLetter + 1);
948
- if (indexOfNextCellWithoutTile === -1) {
949
- if (this.canAddPattern(pattern, newWord)) {
950
- onPatternFound(pattern.clone());
951
- }
952
- }
953
- else if (this.trie.hasPrefix(newWordPrefix)) {
954
- tiles.splice(index, 1);
955
- this.fillPattern(pattern, newWord, tiles, onPatternFound);
956
- tiles.splice(index, 0, tile);
553
+ return;
554
+ }
555
+ for (let index = 0; index < tiles.length; ++index) {
556
+ const tile = tiles[index];
557
+ const previousTile = pattern.cells[indexOfFirstCellWithoutTile].tile;
558
+ pattern.cells[indexOfFirstCellWithoutTile].tile = tile;
559
+ const indexOfNextCellWithoutTile = pattern.getIndexOfFirstCellWithoutTile();
560
+ const indexOfFirstEmptyLetter = word.indexOf(constants_1.EMPTY_CELL);
561
+ const prefix = word.substring(0, indexOfFirstEmptyLetter);
562
+ const suffix = word.substring(indexOfFirstEmptyLetter + 1);
563
+ const characters = tile.isBlank ? config.alphabet : [tile.character];
564
+ for (const character of characters) {
565
+ const newWordPrefix = prefix + character;
566
+ const newWord = newWordPrefix + suffix;
567
+ tile.character = character;
568
+ if (indexOfNextCellWithoutTile === -1) {
569
+ if (trie.has(newWord) && pattern.getCollisions().every((collision) => trie.has(collision.toString()))) {
570
+ results.push(new types_1.FinalPattern(pattern.clone()));
957
571
  }
958
- pattern.cells[indexOfFirstCellWithoutTile].tile = previousTile;
959
572
  }
960
- }
961
- }
962
- canAddPattern(pattern, word) {
963
- return this.trie.has(word) && pattern.getCollisions().every((collision) => this.trie.has(collision.toString()));
964
- }
965
- generateBlankTilesPermutations(tiles) {
966
- const { alphabet } = this.config;
967
- const firstBlankIndex = tiles.findIndex(({ character, isBlank }) => isBlank && !alphabet.includes(character));
968
- if (firstBlankIndex === -1) {
969
- return [tiles];
970
- }
971
- const remainingTiles = tiles.slice(0, firstBlankIndex).concat(tiles.slice(firstBlankIndex + 1));
972
- return this.config.alphabet.reduce((permutations, character) => {
973
- const newTile = new types_1.Tile({ character, isBlank: true });
974
- const newTiles = [...remainingTiles, newTile];
975
- return permutations.concat(this.generateBlankTilesPermutations(newTiles));
976
- }, []);
977
- }
978
- }
979
- exports["default"] = PatternsFiller;
980
-
981
-
982
- /***/ }),
983
-
984
- /***/ 34196:
985
- /***/ ((__unused_webpack_module, exports, __webpack_require__) => {
986
-
987
-
988
- Object.defineProperty(exports, "__esModule", ({ value: true }));
989
- const types_1 = __webpack_require__(46452);
990
- class PatternsGenerator {
991
- constructor(config) {
992
- this.config = config;
993
- }
994
- generate(board) {
995
- return [...this.generateHorizontal(board), ...this.generateVertical(board)];
996
- }
997
- generateHorizontal(board) {
998
- return this.generatePatterns({
999
- board,
1000
- getNthVector: (index) => board.getRow(index),
1001
- PatternModel: types_1.HorizontalPattern,
1002
- vectorsCount: this.config.boardHeight,
1003
- });
1004
- }
1005
- generateVertical(board) {
1006
- return this.generatePatterns({
1007
- board,
1008
- getNthVector: (index) => board.getColumn(index),
1009
- PatternModel: types_1.VerticalPattern,
1010
- vectorsCount: this.config.boardWidth,
1011
- });
1012
- }
1013
- generatePatterns({ board, getNthVector, vectorsCount, PatternModel, }) {
1014
- return this.generateVectors({ getNthVector, vectorsCount }).reduce((patterns, cells) => {
1015
- return patterns.concat(this.generateCellsPatterns({ board, PatternModel, cells }));
1016
- }, []);
1017
- }
1018
- generateVectors({ getNthVector, vectorsCount, }) {
1019
- return Array(vectorsCount)
1020
- .fill(0)
1021
- .map((_, index) => getNthVector(index));
1022
- }
1023
- generateCellsPatterns({ board, cells, PatternModel, }) {
1024
- return this.generateStartIndices(cells).flatMap((startIndex) => {
1025
- const endIndices = this.generateEndIndices(cells, startIndex);
1026
- const patterns = [];
1027
- for (const endIndex of endIndices) {
1028
- const pattern = new PatternModel({
1029
- board,
1030
- cells: cells.slice(startIndex, endIndex + 1),
1031
- });
1032
- if (pattern.canBePlaced(this.config)) {
1033
- patterns.push(pattern);
1034
- }
573
+ else if (trie.hasPrefix(newWordPrefix)) {
574
+ tiles.splice(index, 1);
575
+ (0, exports.fillPatternRecursive)(results, trie, config, pattern, newWord, tiles);
576
+ tiles.splice(index, 0, tile);
1035
577
  }
1036
- return patterns;
1037
- });
1038
- }
1039
- generateStartIndices(cells) {
1040
- return Array(cells.length - 1)
1041
- .fill(0)
1042
- .map((_, startIndex) => startIndex)
1043
- .filter((startIndex) => startIndex === 0 || !cells[startIndex - 1].hasTile());
1044
- }
1045
- generateEndIndices(cells, startIndex) {
1046
- return Array(cells.length - startIndex - 1)
1047
- .fill(0)
1048
- .map((_, endIndex) => endIndex + startIndex + 1)
1049
- .filter((endIndex) => endIndex >= cells.length - 1 || !cells[endIndex + 1].hasTile());
578
+ }
579
+ pattern.cells[indexOfFirstCellWithoutTile].tile = previousTile;
1050
580
  }
1051
- }
1052
- exports["default"] = PatternsGenerator;
581
+ };
582
+ exports.fillPatternRecursive = fillPatternRecursive;
583
+ exports["default"] = fillPattern;
1053
584
 
1054
585
 
1055
586
  /***/ }),
1056
587
 
1057
- /***/ 19368:
1058
- /***/ ((__unused_webpack_module, exports, __webpack_require__) => {
588
+ /***/ 50856:
589
+ /***/ ((__unused_webpack_module, exports) => {
1059
590
 
1060
591
 
1061
592
  Object.defineProperty(exports, "__esModule", ({ value: true }));
1062
- const constants_1 = __webpack_require__(38436);
1063
- class ScoresCalculator {
1064
- constructor(config) {
1065
- this.reduceCellScore = ({ multiplier, score }, cell) => {
1066
- const bonus = this.config.getCellBonus(cell);
1067
- const { characterMultiplier, wordMultiplier } = bonus && bonus.canApply(this.config, cell) ? bonus.value : constants_1.NO_BONUS;
1068
- const characterScore = cell.tile.isBlank ? this.config.blankScore : this.config.pointsMap[cell.tile.character];
1069
- return {
1070
- multiplier: multiplier * wordMultiplier,
1071
- score: score + characterScore * characterMultiplier,
1072
- };
1073
- };
1074
- this.config = config;
1075
- }
1076
- calculate(pattern) {
1077
- return this.calculatePatternScoreWithCollisions(pattern) + this.calculateBonusScore(pattern);
1078
- }
1079
- calculateBonusScore(pattern) {
1080
- const areAllTilesUsed = pattern.getEmptyCellsCount() === this.config.maximumCharactersCount;
1081
- return areAllTilesUsed ? this.config.allTilesBonusScore : 0;
1082
- }
1083
- calculatePatternScoreWithCollisions(pattern) {
1084
- return pattern
1085
- .getCollisions()
1086
- .reduce((patternsScore, collisionPattern) => patternsScore + this.calculatePatternScore(collisionPattern), this.calculatePatternScore(pattern));
1087
- }
1088
- calculatePatternScore(pattern) {
1089
- const { multiplier, score } = pattern.cells.reduce(this.reduceCellScore, {
1090
- multiplier: 1,
1091
- score: 0,
1092
- });
1093
- return score * multiplier;
1094
- }
1095
- }
1096
- exports["default"] = ScoresCalculator;
593
+ const generateEndIndices = (cells, startIndex) => {
594
+ return Array(cells.length - startIndex - 1)
595
+ .fill(0)
596
+ .map((_, endIndex) => endIndex + startIndex + 1)
597
+ .filter((endIndex) => endIndex >= cells.length - 1 || !cells[endIndex + 1].hasTile());
598
+ };
599
+ exports["default"] = generateEndIndices;
1097
600
 
1098
601
 
1099
602
  /***/ }),
1100
603
 
1101
- /***/ 66650:
604
+ /***/ 41331:
1102
605
  /***/ (function(__unused_webpack_module, exports, __webpack_require__) {
1103
606
 
1104
607
 
@@ -1107,67 +610,23 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
1107
610
  };
1108
611
  Object.defineProperty(exports, "__esModule", ({ value: true }));
1109
612
  const types_1 = __webpack_require__(46452);
1110
- const getUniquePatterns_1 = __importDefault(__webpack_require__(55555));
1111
- const PatternsFiller_1 = __importDefault(__webpack_require__(6700));
1112
- const PatternsGenerator_1 = __importDefault(__webpack_require__(34196));
1113
- const ScoresCalculator_1 = __importDefault(__webpack_require__(19368));
1114
- class Solver {
1115
- constructor(config, trie) {
1116
- this.patternsFiller = new PatternsFiller_1.default(config, trie);
1117
- this.patternsGenerator = new PatternsGenerator_1.default(config);
1118
- this.scoresCalculator = new ScoresCalculator_1.default(config);
1119
- }
1120
- solve(board, tiles) {
1121
- const patterns = this.patternsGenerator.generate(board);
1122
- const filledPatterns = patterns.flatMap((pattern) => this.patternsFiller.fill(pattern, tiles));
1123
- const uniquePatterns = (0, getUniquePatterns_1.default)(filledPatterns);
1124
- const results = uniquePatterns.map((pattern, index) => new types_1.Result({
1125
- cells: pattern.cells,
1126
- collisions: pattern.getCollisions().map((collision) => collision.cells),
1127
- id: index,
1128
- points: this.scoresCalculator.calculate(pattern),
1129
- }));
1130
- return results;
1131
- }
1132
- }
1133
- exports["default"] = Solver;
1134
-
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;
613
+ const generatePattern_1 = __importDefault(__webpack_require__(87984));
614
+ const generateVectors_1 = __importDefault(__webpack_require__(18618));
615
+ const generateHorizontalPatterns = (config, board) => {
616
+ const getNthVector = (index) => board.getRow(index);
617
+ const vectorsCount = config.boardHeight;
618
+ const horizontalVectors = (0, generateVectors_1.default)({ getNthVector, vectorsCount });
619
+ const horizontalPatterns = horizontalVectors.flatMap((cells) => {
620
+ return (0, generatePattern_1.default)({ board, config, PatternModel: types_1.HorizontalPattern, cells });
621
+ });
622
+ return horizontalPatterns;
1164
623
  };
1165
- exports["default"] = getUniquePatterns;
624
+ exports["default"] = generateHorizontalPatterns;
1166
625
 
1167
626
 
1168
627
  /***/ }),
1169
628
 
1170
- /***/ 40368:
629
+ /***/ 87984:
1171
630
  /***/ (function(__unused_webpack_module, exports, __webpack_require__) {
1172
631
 
1173
632
 
@@ -1175,101 +634,28 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
1175
634
  return (mod && mod.__esModule) ? mod : { "default": mod };
1176
635
  };
1177
636
  Object.defineProperty(exports, "__esModule", ({ value: true }));
1178
- exports["default"] = void 0;
1179
- var Solver_1 = __webpack_require__(66650);
1180
- Object.defineProperty(exports, "default", ({ enumerable: true, get: function () { return __importDefault(Solver_1).default; } }));
1181
-
1182
-
1183
- /***/ }),
1184
-
1185
- /***/ 61704:
1186
- /***/ ((__unused_webpack_module, exports, __webpack_require__) => {
1187
-
1188
-
1189
- Object.defineProperty(exports, "__esModule", ({ value: true }));
1190
- const lib_1 = __webpack_require__(60337);
1191
- const FILE_URL = 'https://raw.githubusercontent.com/enz/german-wordlist/master/words';
1192
- const getDeDeWordList = async () => {
1193
- return (0, lib_1.getTxtWordList)(FILE_URL);
1194
- };
1195
- exports["default"] = getDeDeWordList;
1196
-
1197
-
1198
- /***/ }),
1199
-
1200
- /***/ 3284:
1201
- /***/ ((__unused_webpack_module, exports, __webpack_require__) => {
1202
-
1203
-
1204
- Object.defineProperty(exports, "__esModule", ({ value: true }));
1205
- const lib_1 = __webpack_require__(60337);
1206
- const FILE_URL = 'https://www.wordgamedictionary.com/sowpods/download/sowpods.txt';
1207
- const getEnGbWordList = async () => {
1208
- return (0, lib_1.getTxtWordList)(FILE_URL);
1209
- };
1210
- exports["default"] = getEnGbWordList;
1211
-
1212
-
1213
- /***/ }),
1214
-
1215
- /***/ 163:
1216
- /***/ ((__unused_webpack_module, exports, __webpack_require__) => {
1217
-
1218
-
1219
- Object.defineProperty(exports, "__esModule", ({ value: true }));
1220
- const lib_1 = __webpack_require__(60337);
1221
- const FILE_URL = 'https://www.wordgamedictionary.com/twl06/download/twl06.txt';
1222
- const getEnUsWordList = async () => {
1223
- return (0, lib_1.getTxtWordList)(FILE_URL);
1224
- };
1225
- exports["default"] = getEnUsWordList;
1226
-
1227
-
1228
- /***/ }),
1229
-
1230
- /***/ 87537:
1231
- /***/ ((__unused_webpack_module, exports, __webpack_require__) => {
1232
-
1233
-
1234
- Object.defineProperty(exports, "__esModule", ({ value: true }));
1235
- const lib_1 = __webpack_require__(60337);
1236
- const FILE_URL = 'https://raw.githubusercontent.com/kamilmielnik/fise-2/master/fise-2.txt';
1237
- const getEsEsWordList = async () => {
1238
- const words = await (0, lib_1.getTxtWordList)(FILE_URL);
1239
- return words.map(normalizeWord);
1240
- };
1241
- const normalizeWord = (word) => {
1242
- // normalization from https://stackoverflow.com/a/37511463
1243
- return word.normalize('NFD').replace(/[\u0300-\u036f]/g, '');
1244
- };
1245
- exports["default"] = getEsEsWordList;
1246
-
1247
-
1248
- /***/ }),
1249
-
1250
- /***/ 27098:
1251
- /***/ ((__unused_webpack_module, exports, __webpack_require__) => {
1252
-
1253
-
1254
- Object.defineProperty(exports, "__esModule", ({ value: true }));
1255
- const lib_1 = __webpack_require__(60337);
1256
- const FILE_URL =
1257
- // eslint-disable-next-line max-len
1258
- 'https://raw.githubusercontent.com/hbenbel/French-Dictionary/a573eab10cc798d7d5da7daab4d2ac0259bb46a3/dictionary/dictionary.txt';
1259
- const getFrFrWordList = async () => {
1260
- const words = await (0, lib_1.getTxtWordList)(FILE_URL);
1261
- return words.map(normalizeWord);
1262
- };
1263
- const normalizeWord = (word) => {
1264
- // normalization from https://stackoverflow.com/a/37511463
1265
- return word.normalize('NFD').replace(/[\u0300-\u036f]/g, '');
637
+ const generateEndIndices_1 = __importDefault(__webpack_require__(50856));
638
+ const generateStartIndices_1 = __importDefault(__webpack_require__(78182));
639
+ const generatePattern = ({ board, cells, config, PatternModel, }) => {
640
+ const startIndices = (0, generateStartIndices_1.default)(cells);
641
+ return startIndices.flatMap((startIndex) => {
642
+ const endIndices = (0, generateEndIndices_1.default)(cells, startIndex);
643
+ const patterns = [];
644
+ for (const endIndex of endIndices) {
645
+ const pattern = new PatternModel(board, cells.slice(startIndex, endIndex + 1));
646
+ if (pattern.canBePlaced(config)) {
647
+ patterns.push(pattern);
648
+ }
649
+ }
650
+ return patterns;
651
+ });
1266
652
  };
1267
- exports["default"] = getFrFrWordList;
653
+ exports["default"] = generatePattern;
1268
654
 
1269
655
 
1270
656
  /***/ }),
1271
657
 
1272
- /***/ 81848:
658
+ /***/ 29480:
1273
659
  /***/ (function(__unused_webpack_module, exports, __webpack_require__) {
1274
660
 
1275
661
 
@@ -1277,132 +663,50 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
1277
663
  return (mod && mod.__esModule) ? mod : { "default": mod };
1278
664
  };
1279
665
  Object.defineProperty(exports, "__esModule", ({ value: true }));
1280
- const cheerio_1 = __importDefault(__webpack_require__(55473));
1281
- const memfs_1 = __webpack_require__(28098);
1282
- const unzipper_1 = __importDefault(__webpack_require__(23428));
1283
- const url_1 = __webpack_require__(57310);
1284
- const lib_1 = __webpack_require__(60337);
1285
- const PAGE_URL = 'https://sjp.pl/sl/growy/';
1286
- const FILE_TO_EXTRACT_FROM_ZIP = 'slowa.txt';
1287
- const getPlPlWordList = async () => {
1288
- const tempFilename = (0, lib_1.getTempFilename)();
1289
- const zipUrl = await fetchZipUrl(PAGE_URL);
1290
- const zipTempFilename = await (0, lib_1.downloadFile)(zipUrl);
1291
- await unzip(zipTempFilename, tempFilename);
1292
- memfs_1.fs.unlinkSync(zipTempFilename);
1293
- const file = memfs_1.fs.readFileSync(tempFilename, 'utf-8');
1294
- memfs_1.fs.unlinkSync(tempFilename);
1295
- const words = (0, lib_1.extractWords)(file.toLocaleString());
1296
- return words;
1297
- };
1298
- const fetchZipUrl = async (url) => {
1299
- const html = await (0, lib_1.downloadHtml)(url);
1300
- const filename = await parseZipContainingPage(html);
1301
- const { href } = new url_1.URL(filename, url);
1302
- return href;
1303
- };
1304
- const parseZipContainingPage = (html) => {
1305
- const $ = cheerio_1.default.load(html);
1306
- const $links = $('a');
1307
- const links = Array.from($links)
1308
- .map((link) => $(link).attr('href'))
1309
- .filter(Boolean);
1310
- const zipFilename = links.find((link) => link.endsWith('.zip'));
1311
- if (typeof zipFilename === 'undefined') {
1312
- throw new Error('Cannot find link to zip file on the page');
1313
- }
1314
- return zipFilename;
1315
- };
1316
- const unzip = (zipFilename, outputFilename) => {
1317
- return memfs_1.fs
1318
- .createReadStream(zipFilename)
1319
- .pipe(unzipper_1.default.Parse())
1320
- .on('entry', (entry) => {
1321
- const fileName = entry.path;
1322
- if (fileName === FILE_TO_EXTRACT_FROM_ZIP) {
1323
- entry.pipe(memfs_1.fs.createWriteStream(outputFilename));
1324
- }
1325
- else {
1326
- entry.autodrain();
1327
- }
1328
- })
1329
- .promise();
666
+ const generateHorizontalPatterns_1 = __importDefault(__webpack_require__(41331));
667
+ const generateVerticalPatterns_1 = __importDefault(__webpack_require__(75069));
668
+ const generatePatterns = (config, board) => {
669
+ const horizontalPatterns = (0, generateHorizontalPatterns_1.default)(config, board);
670
+ const verticalPatterns = (0, generateVerticalPatterns_1.default)(config, board);
671
+ return horizontalPatterns.concat(verticalPatterns);
1330
672
  };
1331
- exports["default"] = getPlPlWordList;
673
+ exports["default"] = generatePatterns;
1332
674
 
1333
675
 
1334
676
  /***/ }),
1335
677
 
1336
- /***/ 8769:
1337
- /***/ (function(__unused_webpack_module, exports, __webpack_require__) {
678
+ /***/ 78182:
679
+ /***/ ((__unused_webpack_module, exports) => {
1338
680
 
1339
681
 
1340
- var __importDefault = (this && this.__importDefault) || function (mod) {
1341
- return (mod && mod.__esModule) ? mod : { "default": mod };
1342
- };
1343
682
  Object.defineProperty(exports, "__esModule", ({ value: true }));
1344
- const types_1 = __webpack_require__(46452);
1345
- const getDeDeWordList_1 = __importDefault(__webpack_require__(61704));
1346
- const getEnGbWordList_1 = __importDefault(__webpack_require__(3284));
1347
- const getEnUsWordList_1 = __importDefault(__webpack_require__(163));
1348
- const getEsEsWordList_1 = __importDefault(__webpack_require__(87537));
1349
- const getFrFrWordList_1 = __importDefault(__webpack_require__(27098));
1350
- const getPlPlWordList_1 = __importDefault(__webpack_require__(81848));
1351
- const localeMap = {
1352
- [types_1.Locale.DE_DE]: getDeDeWordList_1.default,
1353
- [types_1.Locale.EN_GB]: getEnGbWordList_1.default,
1354
- [types_1.Locale.EN_US]: getEnUsWordList_1.default,
1355
- [types_1.Locale.ES_ES]: getEsEsWordList_1.default,
1356
- [types_1.Locale.FR_FR]: getFrFrWordList_1.default,
1357
- [types_1.Locale.PL_PL]: getPlPlWordList_1.default,
683
+ const generateStartIndices = (cells) => {
684
+ return Array(cells.length - 1)
685
+ .fill(0)
686
+ .map((_, startIndex) => startIndex)
687
+ .filter((startIndex) => startIndex === 0 || !cells[startIndex - 1].hasTile());
1358
688
  };
1359
- const getWordList = (locale) => localeMap[locale]();
1360
- exports["default"] = getWordList;
689
+ exports["default"] = generateStartIndices;
1361
690
 
1362
691
 
1363
692
  /***/ }),
1364
693
 
1365
- /***/ 51585:
1366
- /***/ (function(__unused_webpack_module, exports, __webpack_require__) {
694
+ /***/ 18618:
695
+ /***/ ((__unused_webpack_module, exports) => {
1367
696
 
1368
697
 
1369
- var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
1370
- if (k2 === undefined) k2 = k;
1371
- var desc = Object.getOwnPropertyDescriptor(m, k);
1372
- if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
1373
- desc = { enumerable: true, get: function() { return m[k]; } };
1374
- }
1375
- Object.defineProperty(o, k2, desc);
1376
- }) : (function(o, m, k, k2) {
1377
- if (k2 === undefined) k2 = k;
1378
- o[k2] = m[k];
1379
- }));
1380
- var __exportStar = (this && this.__exportStar) || function(m, exports) {
1381
- for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
1382
- };
1383
- var __importDefault = (this && this.__importDefault) || function (mod) {
1384
- return (mod && mod.__esModule) ? mod : { "default": mod };
1385
- };
1386
698
  Object.defineProperty(exports, "__esModule", ({ value: true }));
1387
- exports.getWordList = exports.getDeDeWordList = exports.getPlPlWordList = exports.getFrFrWordList = exports.getEnGbWordList = exports.getEnUsWordList = void 0;
1388
- var getEnUsWordList_1 = __webpack_require__(163);
1389
- Object.defineProperty(exports, "getEnUsWordList", ({ enumerable: true, get: function () { return __importDefault(getEnUsWordList_1).default; } }));
1390
- var getEnGbWordList_1 = __webpack_require__(3284);
1391
- Object.defineProperty(exports, "getEnGbWordList", ({ enumerable: true, get: function () { return __importDefault(getEnGbWordList_1).default; } }));
1392
- var getFrFrWordList_1 = __webpack_require__(27098);
1393
- Object.defineProperty(exports, "getFrFrWordList", ({ enumerable: true, get: function () { return __importDefault(getFrFrWordList_1).default; } }));
1394
- var getPlPlWordList_1 = __webpack_require__(81848);
1395
- Object.defineProperty(exports, "getPlPlWordList", ({ enumerable: true, get: function () { return __importDefault(getPlPlWordList_1).default; } }));
1396
- var getDeDeWordList_1 = __webpack_require__(61704);
1397
- Object.defineProperty(exports, "getDeDeWordList", ({ enumerable: true, get: function () { return __importDefault(getDeDeWordList_1).default; } }));
1398
- var getWordList_1 = __webpack_require__(8769);
1399
- Object.defineProperty(exports, "getWordList", ({ enumerable: true, get: function () { return __importDefault(getWordList_1).default; } }));
1400
- __exportStar(__webpack_require__(60337), exports);
699
+ const generateVectors = ({ getNthVector, vectorsCount, }) => {
700
+ return Array(vectorsCount)
701
+ .fill(0)
702
+ .map((_, index) => getNthVector(index));
703
+ };
704
+ exports["default"] = generateVectors;
1401
705
 
1402
706
 
1403
707
  /***/ }),
1404
708
 
1405
- /***/ 920:
709
+ /***/ 75069:
1406
710
  /***/ (function(__unused_webpack_module, exports, __webpack_require__) {
1407
711
 
1408
712
 
@@ -1410,116 +714,67 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
1410
714
  return (mod && mod.__esModule) ? mod : { "default": mod };
1411
715
  };
1412
716
  Object.defineProperty(exports, "__esModule", ({ value: true }));
1413
- const follow_redirects_1 = __webpack_require__(24396);
1414
- const memfs_1 = __webpack_require__(28098);
1415
- const getTempFilename_1 = __importDefault(__webpack_require__(52688));
1416
- const downloadFile = (url) => {
1417
- return new Promise((resolve, reject) => {
1418
- const tempFilename = (0, getTempFilename_1.default)();
1419
- const protocol = url.startsWith('https') ? follow_redirects_1.https : follow_redirects_1.http;
1420
- const writeStream = memfs_1.fs.createWriteStream(tempFilename);
1421
- const request = protocol.get(url, (response) => {
1422
- if (typeof response.statusCode === 'undefined' || response.statusCode >= 400) {
1423
- reject(new Error(`Cannot download file: ${url}`));
1424
- return;
1425
- }
1426
- response.on('error', (error) => {
1427
- writeStream.close();
1428
- reject(error);
1429
- });
1430
- response.on('end', () => {
1431
- writeStream.on('finish', () => {
1432
- writeStream.close();
1433
- resolve(tempFilename);
1434
- });
1435
- });
1436
- response.pipe(writeStream);
1437
- });
1438
- request.on('error', (error) => {
1439
- writeStream.close();
1440
- reject(error);
1441
- });
717
+ const types_1 = __webpack_require__(46452);
718
+ const generatePattern_1 = __importDefault(__webpack_require__(87984));
719
+ const generateVectors_1 = __importDefault(__webpack_require__(18618));
720
+ const generateVerticalPatterns = (config, board) => {
721
+ const getNthVector = (index) => board.getColumn(index);
722
+ const vectorsCount = config.boardWidth;
723
+ const verticalVectors = (0, generateVectors_1.default)({ getNthVector, vectorsCount });
724
+ const verticalPatterns = verticalVectors.flatMap((cells) => {
725
+ return (0, generatePattern_1.default)({ board, config, PatternModel: types_1.VerticalPattern, cells });
1442
726
  });
727
+ return verticalPatterns;
1443
728
  };
1444
- exports["default"] = downloadFile;
729
+ exports["default"] = generateVerticalPatterns;
1445
730
 
1446
731
 
1447
732
  /***/ }),
1448
733
 
1449
- /***/ 78015:
734
+ /***/ 56628:
1450
735
  /***/ ((__unused_webpack_module, exports, __webpack_require__) => {
1451
736
 
1452
737
 
1453
738
  Object.defineProperty(exports, "__esModule", ({ value: true }));
1454
- const follow_redirects_1 = __webpack_require__(24396);
1455
- const downloadHtml = (url) => {
1456
- return new Promise((resolve, reject) => {
1457
- const protocol = url.startsWith('https') ? follow_redirects_1.https : follow_redirects_1.http;
1458
- protocol.get(url, (response) => {
1459
- let data = '';
1460
- response.setEncoding('utf8');
1461
- response.on('data', (chunk) => {
1462
- data += chunk;
1463
- });
1464
- response.on('end', () => {
1465
- resolve(data);
1466
- });
1467
- response.on('error', reject);
1468
- });
1469
- });
1470
- };
1471
- exports["default"] = downloadHtml;
1472
-
1473
-
1474
- /***/ }),
1475
-
1476
- /***/ 39759:
1477
- /***/ (function(__unused_webpack_module, exports, __webpack_require__) {
1478
-
1479
-
1480
- var __importDefault = (this && this.__importDefault) || function (mod) {
1481
- return (mod && mod.__esModule) ? mod : { "default": mod };
1482
- };
1483
- Object.defineProperty(exports, "__esModule", ({ value: true }));
1484
- const findFirstWordIndex_1 = __importDefault(__webpack_require__(47669));
1485
- const extractWords = (file) => {
1486
- const lines = file.replace(/\r/g, '').split('\n');
1487
- const firstWordIndex = (0, findFirstWordIndex_1.default)(lines);
1488
- const words = lines
1489
- .slice(firstWordIndex)
1490
- .filter((word) => word.trim().length > 0)
1491
- .map((word) => word.toLocaleLowerCase());
1492
- return words;
739
+ const constants_1 = __webpack_require__(38436);
740
+ const getCellsScore = (config, cells) => {
741
+ const total = cells.reduce(({ multiplier, score }, cell) => {
742
+ const bonus = config.getCellBonus(cell);
743
+ const { characterMultiplier, wordMultiplier } = bonus && bonus.canApply(config, cell) ? bonus.value : constants_1.NO_BONUS;
744
+ const characterScore = cell.tile.isBlank ? config.blankScore : config.pointsMap[cell.tile.character];
745
+ return {
746
+ multiplier: multiplier * wordMultiplier,
747
+ score: score + characterScore * characterMultiplier,
748
+ };
749
+ }, { multiplier: 1, score: 0 });
750
+ return total.score * total.multiplier;
1493
751
  };
1494
- exports["default"] = extractWords;
752
+ exports["default"] = getCellsScore;
1495
753
 
1496
754
 
1497
755
  /***/ }),
1498
756
 
1499
- /***/ 47669:
757
+ /***/ 22352:
1500
758
  /***/ ((__unused_webpack_module, exports) => {
1501
759
 
1502
760
 
1503
761
  Object.defineProperty(exports, "__esModule", ({ value: true }));
1504
- const findFirstWordIndex = (lines) => {
1505
- const firstWordIndex = lines.findIndex((line, index) => {
1506
- const nextLine = line[index + 1] || '';
1507
- const isNextLineInOrder = line.localeCompare(nextLine) === 1;
1508
- const hasWhitespace = Boolean(line.match(/\s/));
1509
- const isEmpty = line.trim().length === 0;
1510
- return !isEmpty && !hasWhitespace && isNextLineInOrder;
1511
- });
1512
- if (typeof firstWordIndex === 'undefined') {
1513
- throw new Error('Cannot find index of the first word in the file');
1514
- }
1515
- return firstWordIndex;
762
+ const getPatternHash = (pattern) => {
763
+ return pattern.cells
764
+ .map((cell) => {
765
+ const blank = cell.tile.isBlank ? '!' : '';
766
+ const tile = cell.tile.character + blank;
767
+ // eslint-disable-next-line prefer-template
768
+ return cell.x + ',' + cell.y + ',' + tile;
769
+ })
770
+ .join('-');
1516
771
  };
1517
- exports["default"] = findFirstWordIndex;
772
+ exports["default"] = getPatternHash;
1518
773
 
1519
774
 
1520
775
  /***/ }),
1521
776
 
1522
- /***/ 93938:
777
+ /***/ 94808:
1523
778
  /***/ (function(__unused_webpack_module, exports, __webpack_require__) {
1524
779
 
1525
780
 
@@ -1527,14 +782,21 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
1527
782
  return (mod && mod.__esModule) ? mod : { "default": mod };
1528
783
  };
1529
784
  Object.defineProperty(exports, "__esModule", ({ value: true }));
1530
- const crypto_1 = __importDefault(__webpack_require__(6113));
1531
- const getHash = (bytes = 8) => crypto_1.default.randomBytes(bytes).toString('hex');
1532
- exports["default"] = getHash;
785
+ const getCellsScore_1 = __importDefault(__webpack_require__(56628));
786
+ const getPatternScore = (config, pattern) => {
787
+ const areAllTilesUsed = pattern.getEmptyCellsCount() === config.maximumCharactersCount;
788
+ const bonusScore = areAllTilesUsed ? config.allTilesBonusScore : 0;
789
+ const score = pattern
790
+ .getCollisions()
791
+ .reduce((sum, collision) => sum + (0, getCellsScore_1.default)(config, collision.cells), (0, getCellsScore_1.default)(config, pattern.cells));
792
+ return score + bonusScore;
793
+ };
794
+ exports["default"] = getPatternScore;
1533
795
 
1534
796
 
1535
797
  /***/ }),
1536
798
 
1537
- /***/ 52688:
799
+ /***/ 55555:
1538
800
  /***/ (function(__unused_webpack_module, exports, __webpack_require__) {
1539
801
 
1540
802
 
@@ -1542,16 +804,25 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
1542
804
  return (mod && mod.__esModule) ? mod : { "default": mod };
1543
805
  };
1544
806
  Object.defineProperty(exports, "__esModule", ({ value: true }));
1545
- const getHash_1 = __importDefault(__webpack_require__(93938));
1546
- const getTempFilename = () => {
1547
- return `/${(0, getHash_1.default)()}.txt`;
807
+ const getPatternHash_1 = __importDefault(__webpack_require__(22352));
808
+ const getUniquePatterns = (patterns) => {
809
+ const hashes = new Set();
810
+ const uniquePatterns = [];
811
+ for (const pattern of patterns) {
812
+ const hash = (0, getPatternHash_1.default)(pattern);
813
+ if (!hashes.has(hash)) {
814
+ hashes.add(hash);
815
+ uniquePatterns.push(pattern);
816
+ }
817
+ }
818
+ return uniquePatterns;
1548
819
  };
1549
- exports["default"] = getTempFilename;
820
+ exports["default"] = getUniquePatterns;
1550
821
 
1551
822
 
1552
823
  /***/ }),
1553
824
 
1554
- /***/ 78029:
825
+ /***/ 40368:
1555
826
  /***/ (function(__unused_webpack_module, exports, __webpack_require__) {
1556
827
 
1557
828
 
@@ -1559,22 +830,14 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
1559
830
  return (mod && mod.__esModule) ? mod : { "default": mod };
1560
831
  };
1561
832
  Object.defineProperty(exports, "__esModule", ({ value: true }));
1562
- const memfs_1 = __webpack_require__(28098);
1563
- const downloadFile_1 = __importDefault(__webpack_require__(920));
1564
- const extractWords_1 = __importDefault(__webpack_require__(39759));
1565
- const getTxtWordList = async (url) => {
1566
- const tempFilename = await (0, downloadFile_1.default)(url);
1567
- const file = memfs_1.fs.readFileSync(tempFilename, 'utf-8');
1568
- const words = (0, extractWords_1.default)(file.toLocaleString());
1569
- memfs_1.fs.unlinkSync(tempFilename);
1570
- return words;
1571
- };
1572
- exports["default"] = getTxtWordList;
833
+ exports.solve = void 0;
834
+ var solve_1 = __webpack_require__(46243);
835
+ Object.defineProperty(exports, "solve", ({ enumerable: true, get: function () { return __importDefault(solve_1).default; } }));
1573
836
 
1574
837
 
1575
838
  /***/ }),
1576
839
 
1577
- /***/ 60337:
840
+ /***/ 46243:
1578
841
  /***/ (function(__unused_webpack_module, exports, __webpack_require__) {
1579
842
 
1580
843
 
@@ -1582,21 +845,24 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
1582
845
  return (mod && mod.__esModule) ? mod : { "default": mod };
1583
846
  };
1584
847
  Object.defineProperty(exports, "__esModule", ({ value: true }));
1585
- exports.getTxtWordList = exports.getTempFilename = exports.getHash = exports.findFirstWordIndex = exports.extractWords = exports.downloadHtml = exports.downloadFile = void 0;
1586
- var downloadFile_1 = __webpack_require__(920);
1587
- Object.defineProperty(exports, "downloadFile", ({ enumerable: true, get: function () { return __importDefault(downloadFile_1).default; } }));
1588
- var downloadHtml_1 = __webpack_require__(78015);
1589
- Object.defineProperty(exports, "downloadHtml", ({ enumerable: true, get: function () { return __importDefault(downloadHtml_1).default; } }));
1590
- var extractWords_1 = __webpack_require__(39759);
1591
- Object.defineProperty(exports, "extractWords", ({ enumerable: true, get: function () { return __importDefault(extractWords_1).default; } }));
1592
- var findFirstWordIndex_1 = __webpack_require__(47669);
1593
- Object.defineProperty(exports, "findFirstWordIndex", ({ enumerable: true, get: function () { return __importDefault(findFirstWordIndex_1).default; } }));
1594
- var getHash_1 = __webpack_require__(93938);
1595
- Object.defineProperty(exports, "getHash", ({ enumerable: true, get: function () { return __importDefault(getHash_1).default; } }));
1596
- var getTempFilename_1 = __webpack_require__(52688);
1597
- Object.defineProperty(exports, "getTempFilename", ({ enumerable: true, get: function () { return __importDefault(getTempFilename_1).default; } }));
1598
- var getTxtWordList_1 = __webpack_require__(78029);
1599
- Object.defineProperty(exports, "getTxtWordList", ({ enumerable: true, get: function () { return __importDefault(getTxtWordList_1).default; } }));
848
+ const types_1 = __webpack_require__(46452);
849
+ const fillPattern_1 = __importDefault(__webpack_require__(83594));
850
+ const generatePatterns_1 = __importDefault(__webpack_require__(29480));
851
+ const getPatternScore_1 = __importDefault(__webpack_require__(94808));
852
+ const getUniquePatterns_1 = __importDefault(__webpack_require__(55555));
853
+ const solve = (trie, config, board, tiles) => {
854
+ const patterns = (0, generatePatterns_1.default)(config, board);
855
+ const filledPatterns = patterns.flatMap((pattern) => (0, fillPattern_1.default)(trie, config, pattern, tiles));
856
+ const uniquePatterns = (0, getUniquePatterns_1.default)(filledPatterns);
857
+ const results = uniquePatterns.map((pattern, index) => new types_1.Result({
858
+ cells: pattern.cells,
859
+ collisions: pattern.getCollisions().map((collision) => collision.cells),
860
+ id: index,
861
+ points: (0, getPatternScore_1.default)(config, pattern),
862
+ }));
863
+ return results;
864
+ };
865
+ exports["default"] = solve;
1600
866
 
1601
867
 
1602
868
  /***/ })
@@ -1608,7 +874,7 @@ Object.defineProperty(exports, "getTxtWordList", ({ enumerable: true, get: funct
1608
874
  var __webpack_require__ = require("../../webpack-api-runtime.js");
1609
875
  __webpack_require__.C(exports);
1610
876
  var __webpack_exec__ = (moduleId) => (__webpack_require__(__webpack_require__.s = moduleId))
1611
- var __webpack_exports__ = __webpack_require__.X(0, [50,429,939,911], () => (__webpack_exec__(207)));
877
+ var __webpack_exports__ = __webpack_require__.X(0, [50,429,939,911,44], () => (__webpack_exec__(207)));
1612
878
  module.exports = __webpack_exports__;
1613
879
 
1614
880
  })();