scrabble-solver 2.11.0 → 2.11.2

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 (155) hide show
  1. package/lerna.json +1 -1
  2. package/package.json +1 -1
  3. package/packages/configs/package.json +3 -3
  4. package/packages/constants/package.json +1 -1
  5. package/packages/dictionaries/package-lock.json +2 -2
  6. package/packages/dictionaries/package.json +4 -4
  7. package/packages/logger/package-lock.json +2 -2
  8. package/packages/logger/package.json +1 -1
  9. package/packages/scrabble-solver/.next/BUILD_ID +1 -1
  10. package/packages/scrabble-solver/.next/build-manifest.json +7 -7
  11. package/packages/scrabble-solver/.next/cache/.tsbuildinfo +1 -1
  12. package/packages/scrabble-solver/.next/cache/eslint/.cache_8dgz12 +1 -1
  13. package/packages/scrabble-solver/.next/cache/next-server.js.nft.json +1 -1
  14. package/packages/scrabble-solver/.next/cache/webpack/client-production/0.pack +0 -0
  15. package/packages/scrabble-solver/.next/cache/webpack/client-production/index.pack +0 -0
  16. package/packages/scrabble-solver/.next/cache/webpack/edge-server-production/0.pack +0 -0
  17. package/packages/scrabble-solver/.next/cache/webpack/edge-server-production/index.pack +0 -0
  18. package/packages/scrabble-solver/.next/cache/webpack/server-production/0.pack +0 -0
  19. package/packages/scrabble-solver/.next/cache/webpack/server-production/index.pack +0 -0
  20. package/packages/scrabble-solver/.next/next-server.js.nft.json +1 -1
  21. package/packages/scrabble-solver/.next/prerender-manifest.json +1 -1
  22. package/packages/scrabble-solver/.next/routes-manifest.json +1 -1
  23. package/packages/scrabble-solver/.next/server/chunks/277.js +523 -611
  24. package/packages/scrabble-solver/.next/server/middleware-build-manifest.js +1 -1
  25. package/packages/scrabble-solver/.next/server/pages/404.html +2 -2
  26. package/packages/scrabble-solver/.next/server/pages/404.js.nft.json +1 -1
  27. package/packages/scrabble-solver/.next/server/pages/500.html +1 -1
  28. package/packages/scrabble-solver/.next/server/pages/_app.js +0 -24
  29. package/packages/scrabble-solver/.next/server/pages/_app.js.nft.json +1 -1
  30. package/packages/scrabble-solver/.next/server/pages/_document.js.nft.json +1 -1
  31. package/packages/scrabble-solver/.next/server/pages/api/dictionary/[locale]/[word].js +0 -1
  32. package/packages/scrabble-solver/.next/server/pages/api/dictionary/[locale].js +0 -1
  33. package/packages/scrabble-solver/.next/server/pages/api/solve.js +28 -8
  34. package/packages/scrabble-solver/.next/server/pages/api/verify.js +0 -1
  35. package/packages/scrabble-solver/.next/server/pages/api/visit.js +0 -1
  36. package/packages/scrabble-solver/.next/server/pages/index.html +1 -1
  37. package/packages/scrabble-solver/.next/server/pages/index.js +49 -90
  38. package/packages/scrabble-solver/.next/server/pages/index.js.nft.json +1 -1
  39. package/packages/scrabble-solver/.next/server/pages/index.json +1 -1
  40. package/packages/scrabble-solver/.next/static/Mdvi3FY0PqkILKLbPlVBU/_buildManifest.js +1 -0
  41. package/packages/scrabble-solver/.next/static/chunks/pages/{404-e0f30450e9920dc3.js → 404-448ba28510855455.js} +1 -1
  42. package/packages/scrabble-solver/.next/static/chunks/pages/_app-495e6f4ccc278bb2.js +28 -0
  43. package/packages/scrabble-solver/.next/static/chunks/pages/index-5ecc51900ca29685.js +1 -0
  44. package/packages/scrabble-solver/.next/static/css/17b0a2db8742105f.css +1 -0
  45. package/packages/scrabble-solver/.next/static/css/e1ffeb2558330c55.css +2 -0
  46. package/packages/scrabble-solver/.next/trace +54 -55
  47. package/packages/scrabble-solver/package-lock.json +2 -79
  48. package/packages/scrabble-solver/package.json +8 -13
  49. package/packages/scrabble-solver/src/components/{Solver/components/EmptyState/EmptyState.module.scss → Alert/Alert.module.scss} +11 -7
  50. package/packages/scrabble-solver/src/components/{Solver/components/EmptyState/EmptyState.tsx → Alert/Alert.tsx} +8 -6
  51. package/packages/scrabble-solver/src/components/Alert/index.ts +1 -0
  52. package/packages/scrabble-solver/src/components/Board/Board.module.scss +55 -0
  53. package/packages/scrabble-solver/src/components/Board/BoardPure.tsx +4 -0
  54. package/packages/scrabble-solver/src/components/Board/components/Cell/Cell.module.scss +51 -2
  55. package/packages/scrabble-solver/src/components/Board/components/Cell/Cell.tsx +12 -0
  56. package/packages/scrabble-solver/src/components/Board/components/Cell/CellPure.tsx +12 -0
  57. package/packages/scrabble-solver/src/components/Board/hooks/useGrid.ts +9 -26
  58. package/packages/scrabble-solver/src/components/Board/lib/getPositionInGrid.ts +1 -1
  59. package/packages/scrabble-solver/src/components/Dictionary/Dictionary.module.scss +4 -0
  60. package/packages/scrabble-solver/src/components/DictionaryInput/DictionaryInput.module.scss +1 -0
  61. package/packages/scrabble-solver/src/components/EmptyState/EmptyState.module.scss +2 -1
  62. package/packages/scrabble-solver/src/components/EmptyState/EmptyState.tsx +1 -2
  63. package/packages/scrabble-solver/src/components/Loading/Loading.module.scss +1 -1
  64. package/packages/scrabble-solver/src/components/Logo/Logo.tsx +5 -0
  65. package/packages/scrabble-solver/src/components/LogoSplashScreen/LogoSplashScreen.module.scss +4 -1
  66. package/packages/scrabble-solver/src/components/Modal/Modal.module.scss +14 -0
  67. package/packages/scrabble-solver/src/components/Modal/Modal.tsx +4 -1
  68. package/packages/scrabble-solver/src/components/PlainTiles/PlainTiles.module.scss +1 -1
  69. package/packages/scrabble-solver/src/components/PlainTiles/Tile.tsx +3 -3
  70. package/packages/scrabble-solver/src/components/Rack/Rack.module.scss +25 -0
  71. package/packages/scrabble-solver/src/components/Rack/Rack.tsx +5 -4
  72. package/packages/scrabble-solver/src/components/Rack/RackTile.tsx +6 -13
  73. package/packages/scrabble-solver/src/components/Results/HeaderButton.tsx +5 -12
  74. package/packages/scrabble-solver/src/components/Results/Result.tsx +5 -3
  75. package/packages/scrabble-solver/src/components/Results/Results.module.scss +41 -1
  76. package/packages/scrabble-solver/src/components/Results/Results.tsx +29 -43
  77. package/packages/scrabble-solver/src/components/Results/types.ts +1 -1
  78. package/packages/scrabble-solver/src/components/ResultsInput/ResultsInput.module.scss +1 -0
  79. package/packages/scrabble-solver/src/components/Solver/Solver.module.scss +9 -4
  80. package/packages/scrabble-solver/src/components/Solver/Solver.tsx +17 -19
  81. package/packages/scrabble-solver/src/components/Solver/components/ResultCandidatePicker/ResultCandidatePicker.tsx +5 -6
  82. package/packages/scrabble-solver/src/components/Solver/components/index.ts +0 -1
  83. package/packages/scrabble-solver/src/components/Tile/Tile.module.scss +42 -61
  84. package/packages/scrabble-solver/src/components/Tile/Tile.tsx +4 -3
  85. package/packages/scrabble-solver/src/components/Tile/TilePure.tsx +4 -13
  86. package/packages/scrabble-solver/src/components/Tooltip/Tooltip.module.scss +1 -72
  87. package/packages/scrabble-solver/src/components/Tooltip/useTooltip.tsx +25 -35
  88. package/packages/scrabble-solver/src/components/index.ts +1 -0
  89. package/packages/scrabble-solver/src/hooks/index.ts +0 -1
  90. package/packages/scrabble-solver/src/hooks/useAppLayout.ts +3 -1
  91. package/packages/scrabble-solver/src/i18n/de.json +0 -1
  92. package/packages/scrabble-solver/src/i18n/en.json +0 -1
  93. package/packages/scrabble-solver/src/i18n/es.json +0 -1
  94. package/packages/scrabble-solver/src/i18n/fa.json +0 -1
  95. package/packages/scrabble-solver/src/i18n/fr.json +0 -1
  96. package/packages/scrabble-solver/src/i18n/pl.json +0 -1
  97. package/packages/scrabble-solver/src/lib/createRegExp.ts +13 -0
  98. package/packages/scrabble-solver/src/lib/groupResults.ts +38 -0
  99. package/packages/scrabble-solver/src/lib/guessLocale.ts +22 -0
  100. package/packages/scrabble-solver/src/lib/index.ts +4 -2
  101. package/packages/scrabble-solver/src/lib/sortResults.ts +6 -10
  102. package/packages/scrabble-solver/src/modals/DictionaryModal/DictionaryModal.module.scss +6 -2
  103. package/packages/scrabble-solver/src/modals/KeyMapModal/KeyMapModal.tsx +5 -21
  104. package/packages/scrabble-solver/src/modals/KeyMapModal/components/Mapping/Mapping.module.scss +4 -0
  105. package/packages/scrabble-solver/src/modals/MenuModal/MenuModal.module.scss +7 -0
  106. package/packages/scrabble-solver/src/modals/RemainingTilesModal/components/Character/Character.module.scss +1 -0
  107. package/packages/scrabble-solver/src/modals/ResultsModal/ResultsModal.module.scss +3 -3
  108. package/packages/scrabble-solver/src/modals/ResultsModal/ResultsModal.tsx +23 -11
  109. package/packages/scrabble-solver/src/modals/SettingsModal/components/LocaleSetting/LocaleSetting.module.scss +2 -0
  110. package/packages/scrabble-solver/src/modals/WordsModal/WordsModal.module.scss +8 -1
  111. package/packages/scrabble-solver/src/pages/api/dictionary/[locale]/[word].ts +0 -1
  112. package/packages/scrabble-solver/src/pages/api/dictionary/[locale]/index.ts +0 -1
  113. package/packages/scrabble-solver/src/pages/api/solve.ts +0 -1
  114. package/packages/scrabble-solver/src/pages/api/verify.ts +0 -1
  115. package/packages/scrabble-solver/src/pages/api/visit.ts +0 -1
  116. package/packages/scrabble-solver/src/pages/index.tsx +13 -15
  117. package/packages/scrabble-solver/src/parameters/index.ts +2 -2
  118. package/packages/scrabble-solver/src/state/createAppStore.ts +26 -10
  119. package/packages/scrabble-solver/src/state/sagas.ts +1 -0
  120. package/packages/scrabble-solver/src/state/selectors.ts +37 -37
  121. package/packages/scrabble-solver/src/state/slices/boardInitialState.ts +3 -1
  122. package/packages/scrabble-solver/src/state/slices/cellFilterInitialState.ts +3 -3
  123. package/packages/scrabble-solver/src/state/slices/cellFilterSlice.ts +3 -1
  124. package/packages/scrabble-solver/src/state/slices/dictionaryInitialState.ts +2 -2
  125. package/packages/scrabble-solver/src/state/slices/rackInitialState.ts +3 -1
  126. package/packages/scrabble-solver/src/state/slices/resultsInitialState.ts +11 -4
  127. package/packages/scrabble-solver/src/state/slices/settingsInitialState.ts +10 -21
  128. package/packages/scrabble-solver/src/state/slices/solveInitialState.ts +2 -2
  129. package/packages/scrabble-solver/src/state/slices/solveSlice.ts +2 -0
  130. package/packages/scrabble-solver/src/state/slices/verifyInitialState.ts +13 -4
  131. package/packages/scrabble-solver/src/state/types.ts +20 -2
  132. package/packages/scrabble-solver/src/styles/mixins.scss +25 -1
  133. package/packages/scrabble-solver/src/styles/variables.scss +17 -1
  134. package/packages/scrabble-solver/src/types/index.ts +10 -2
  135. package/packages/solver/package-lock.json +2 -2
  136. package/packages/solver/package.json +5 -5
  137. package/packages/types/build/Bonus.d.ts +2 -1
  138. package/packages/types/package.json +2 -2
  139. package/packages/types/src/Bonus.ts +3 -1
  140. package/packages/word-definitions/package-lock.json +8 -8
  141. package/packages/word-definitions/package.json +2 -2
  142. package/packages/word-lists/package-lock.json +2 -2
  143. package/packages/word-lists/package.json +2 -2
  144. package/packages/scrabble-solver/.next/static/45ye7793DY705HOcuK9lJ/_buildManifest.js +0 -1
  145. package/packages/scrabble-solver/.next/static/chunks/pages/_app-d7acee5e526752d9.js +0 -28
  146. package/packages/scrabble-solver/.next/static/chunks/pages/index-35d2c1c79a201ae2.js +0 -1
  147. package/packages/scrabble-solver/.next/static/css/a48caa6f57de6e98.css +0 -1
  148. package/packages/scrabble-solver/.next/static/css/c49bbe944ddd1b39.css +0 -2
  149. package/packages/scrabble-solver/src/components/Board/types/index.ts +0 -4
  150. package/packages/scrabble-solver/src/components/Solver/components/EmptyState/index.ts +0 -1
  151. package/packages/scrabble-solver/src/components/Tooltip/constants.ts +0 -28
  152. package/packages/scrabble-solver/src/hooks/useUniqueId.ts +0 -9
  153. package/packages/scrabble-solver/src/lib/isCtrl.ts +0 -7
  154. package/packages/scrabble-solver/src/state/rootReducer.ts +0 -25
  155. /package/packages/scrabble-solver/.next/static/{45ye7793DY705HOcuK9lJ → Mdvi3FY0PqkILKLbPlVBU}/_ssgManifest.js +0 -0
@@ -1,17 +1,16 @@
1
1
  {
2
2
  "name": "@scrabble-solver/scrabble-solver",
3
- "version": "2.11.0",
3
+ "version": "2.11.2",
4
4
  "lockfileVersion": 2,
5
5
  "requires": true,
6
6
  "packages": {
7
7
  "": {
8
8
  "name": "@scrabble-solver/scrabble-solver",
9
- "version": "2.11.0",
9
+ "version": "2.11.2",
10
10
  "license": "CC BY-NC-ND 4.0",
11
11
  "dependencies": {
12
12
  "@floating-ui/react": "^0.20.1",
13
13
  "@kamilmielnik/trie": "^2.0.1",
14
- "@popperjs/core": "^2.11.6",
15
14
  "@reduxjs/toolkit": "^1.9.3",
16
15
  "classnames": "^2.3.2",
17
16
  "include-media": "^2.0.0",
@@ -21,15 +20,12 @@
21
20
  "react": "^18.2.0",
22
21
  "react-dom": "^18.2.0",
23
22
  "react-modal": "^3.16.1",
24
- "react-popper": "^2.3.0",
25
23
  "react-portal": "^4.2.2",
26
24
  "react-redux": "^8.0.5",
27
25
  "react-use": "^17.4.0",
28
26
  "react-window": "^1.8.8",
29
- "redux": "^4.2.1",
30
27
  "redux-saga": "^1.2.2",
31
28
  "store2": "^2.14.2",
32
- "uuid": "^9.0.0",
33
29
  "workbox-expiration": "^6.5.4",
34
30
  "workbox-precaching": "^6.5.4",
35
31
  "workbox-routing": "^6.5.4",
@@ -46,7 +42,6 @@
46
42
  "@types/react-window": "^1.8.5",
47
43
  "@types/redux": "^3.6.31",
48
44
  "@types/redux-saga": "^0.10.5",
49
- "@types/uuid": "^9.0.1",
50
45
  "env-cmd": "^10.1.0",
51
46
  "sass": "^1.59.2",
52
47
  "workbox-webpack-plugin": "^6.5.4"
@@ -2143,15 +2138,6 @@
2143
2138
  "node": ">= 10"
2144
2139
  }
2145
2140
  },
2146
- "node_modules/@popperjs/core": {
2147
- "version": "2.11.6",
2148
- "resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.11.6.tgz",
2149
- "integrity": "sha512-50/17A98tWUfQ176raKiOGXuYpLyyVMkxxG6oylzL3BPOlA6ADGdK7EYunSa4I064xerltq9TGXs8HmOk5E+vw==",
2150
- "funding": {
2151
- "type": "opencollective",
2152
- "url": "https://opencollective.com/popperjs"
2153
- }
2154
- },
2155
2141
  "node_modules/@redux-saga/core": {
2156
2142
  "version": "1.2.2",
2157
2143
  "resolved": "https://registry.npmjs.org/@redux-saga/core/-/core-1.2.2.tgz",
@@ -2766,12 +2752,6 @@
2766
2752
  "resolved": "https://registry.npmjs.org/@types/use-sync-external-store/-/use-sync-external-store-0.0.3.tgz",
2767
2753
  "integrity": "sha512-EwmlvuaxPNej9+T4v5AuBPJa2x2UOJVdjCtDHgcDqitUeOtjnJKJ+apYjVcAoBEMjKW1VVFGZLUb5+qqa09XFA=="
2768
2754
  },
2769
- "node_modules/@types/uuid": {
2770
- "version": "9.0.1",
2771
- "resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-9.0.1.tgz",
2772
- "integrity": "sha512-rFT3ak0/2trgvp4yYZo5iKFEPsET7vKydKF+VRCxlQ9bpheehyAJH89dAkaLEq/j/RZXJIqcgsmPJKUP1Z28HA==",
2773
- "dev": true
2774
- },
2775
2755
  "node_modules/@webassemblyjs/ast": {
2776
2756
  "version": "1.11.1",
2777
2757
  "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.11.1.tgz",
@@ -5253,11 +5233,6 @@
5253
5233
  "react": "^18.2.0"
5254
5234
  }
5255
5235
  },
5256
- "node_modules/react-fast-compare": {
5257
- "version": "3.2.0",
5258
- "resolved": "https://registry.npmjs.org/react-fast-compare/-/react-fast-compare-3.2.0.tgz",
5259
- "integrity": "sha512-rtGImPZ0YyLrscKI9xTpV8psd6I8VAtjKCzQDlzyDvqJA8XOW78TXYQwNRNd8g8JZnDu8q9Fu/1v4HPAVwVdHA=="
5260
- },
5261
5236
  "node_modules/react-is": {
5262
5237
  "version": "16.13.1",
5263
5238
  "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz",
@@ -5286,20 +5261,6 @@
5286
5261
  "react-dom": "^0.14.0 || ^15.0.0 || ^16 || ^17 || ^18"
5287
5262
  }
5288
5263
  },
5289
- "node_modules/react-popper": {
5290
- "version": "2.3.0",
5291
- "resolved": "https://registry.npmjs.org/react-popper/-/react-popper-2.3.0.tgz",
5292
- "integrity": "sha512-e1hj8lL3uM+sgSR4Lxzn5h1GxBlpa4CQz0XLF8kx4MDrDRWY0Ena4c97PUeSX9i5W3UAfDP0z0FXCTQkoXUl3Q==",
5293
- "dependencies": {
5294
- "react-fast-compare": "^3.0.1",
5295
- "warning": "^4.0.2"
5296
- },
5297
- "peerDependencies": {
5298
- "@popperjs/core": "^2.0.0",
5299
- "react": "^16.8.0 || ^17 || ^18",
5300
- "react-dom": "^16.8.0 || ^17 || ^18"
5301
- }
5302
- },
5303
5264
  "node_modules/react-portal": {
5304
5265
  "version": "4.2.2",
5305
5266
  "resolved": "https://registry.npmjs.org/react-portal/-/react-portal-4.2.2.tgz",
@@ -6384,14 +6345,6 @@
6384
6345
  "react": "^16.8.0 || ^17.0.0 || ^18.0.0"
6385
6346
  }
6386
6347
  },
6387
- "node_modules/uuid": {
6388
- "version": "9.0.0",
6389
- "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.0.tgz",
6390
- "integrity": "sha512-MXcSTerfPa4uqyzStbRoTgt5XIe3x5+42+q1sDuy3R5MDk66URdLMOZe5aPX/SQd+kuYAh0FdP/pO28IkQyTeg==",
6391
- "bin": {
6392
- "uuid": "dist/bin/uuid"
6393
- }
6394
- },
6395
6348
  "node_modules/warning": {
6396
6349
  "version": "4.0.3",
6397
6350
  "resolved": "https://registry.npmjs.org/warning/-/warning-4.0.3.tgz",
@@ -8230,11 +8183,6 @@
8230
8183
  "integrity": "sha512-0MffFmyv7tBLlji01qc0IaPP/LVExzvj7/R5x1Jph1bTAIj4Vu81yFQWHHQAP6r4ff9Ukj1mBK6MDNVXm7Tcvw==",
8231
8184
  "optional": true
8232
8185
  },
8233
- "@popperjs/core": {
8234
- "version": "2.11.6",
8235
- "resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.11.6.tgz",
8236
- "integrity": "sha512-50/17A98tWUfQ176raKiOGXuYpLyyVMkxxG6oylzL3BPOlA6ADGdK7EYunSa4I064xerltq9TGXs8HmOk5E+vw=="
8237
- },
8238
8186
  "@redux-saga/core": {
8239
8187
  "version": "1.2.2",
8240
8188
  "resolved": "https://registry.npmjs.org/@redux-saga/core/-/core-1.2.2.tgz",
@@ -8679,12 +8627,6 @@
8679
8627
  "resolved": "https://registry.npmjs.org/@types/use-sync-external-store/-/use-sync-external-store-0.0.3.tgz",
8680
8628
  "integrity": "sha512-EwmlvuaxPNej9+T4v5AuBPJa2x2UOJVdjCtDHgcDqitUeOtjnJKJ+apYjVcAoBEMjKW1VVFGZLUb5+qqa09XFA=="
8681
8629
  },
8682
- "@types/uuid": {
8683
- "version": "9.0.1",
8684
- "resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-9.0.1.tgz",
8685
- "integrity": "sha512-rFT3ak0/2trgvp4yYZo5iKFEPsET7vKydKF+VRCxlQ9bpheehyAJH89dAkaLEq/j/RZXJIqcgsmPJKUP1Z28HA==",
8686
- "dev": true
8687
- },
8688
8630
  "@webassemblyjs/ast": {
8689
8631
  "version": "1.11.1",
8690
8632
  "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.11.1.tgz",
@@ -10552,11 +10494,6 @@
10552
10494
  "scheduler": "^0.23.0"
10553
10495
  }
10554
10496
  },
10555
- "react-fast-compare": {
10556
- "version": "3.2.0",
10557
- "resolved": "https://registry.npmjs.org/react-fast-compare/-/react-fast-compare-3.2.0.tgz",
10558
- "integrity": "sha512-rtGImPZ0YyLrscKI9xTpV8psd6I8VAtjKCzQDlzyDvqJA8XOW78TXYQwNRNd8g8JZnDu8q9Fu/1v4HPAVwVdHA=="
10559
- },
10560
10497
  "react-is": {
10561
10498
  "version": "16.13.1",
10562
10499
  "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz",
@@ -10578,15 +10515,6 @@
10578
10515
  "warning": "^4.0.3"
10579
10516
  }
10580
10517
  },
10581
- "react-popper": {
10582
- "version": "2.3.0",
10583
- "resolved": "https://registry.npmjs.org/react-popper/-/react-popper-2.3.0.tgz",
10584
- "integrity": "sha512-e1hj8lL3uM+sgSR4Lxzn5h1GxBlpa4CQz0XLF8kx4MDrDRWY0Ena4c97PUeSX9i5W3UAfDP0z0FXCTQkoXUl3Q==",
10585
- "requires": {
10586
- "react-fast-compare": "^3.0.1",
10587
- "warning": "^4.0.2"
10588
- }
10589
- },
10590
10518
  "react-portal": {
10591
10519
  "version": "4.2.2",
10592
10520
  "resolved": "https://registry.npmjs.org/react-portal/-/react-portal-4.2.2.tgz",
@@ -11377,11 +11305,6 @@
11377
11305
  "integrity": "sha512-eEgnFxGQ1Ife9bzYs6VLi8/4X6CObHMw9Qr9tPY43iKwsPw8xE8+EFsf/2cFZ5S3esXgpWgtSCtLNS41F+sKPA==",
11378
11306
  "requires": {}
11379
11307
  },
11380
- "uuid": {
11381
- "version": "9.0.0",
11382
- "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.0.tgz",
11383
- "integrity": "sha512-MXcSTerfPa4uqyzStbRoTgt5XIe3x5+42+q1sDuy3R5MDk66URdLMOZe5aPX/SQd+kuYAh0FdP/pO28IkQyTeg=="
11384
- },
11385
11308
  "warning": {
11386
11309
  "version": "4.0.3",
11387
11310
  "resolved": "https://registry.npmjs.org/warning/-/warning-4.0.3.tgz",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@scrabble-solver/scrabble-solver",
3
- "version": "2.11.0",
3
+ "version": "2.11.2",
4
4
  "description": "Scrabble Solver 2 - App",
5
5
  "engines": {
6
6
  "node": ">=16"
@@ -30,15 +30,14 @@
30
30
  "dependencies": {
31
31
  "@floating-ui/react": "^0.20.1",
32
32
  "@kamilmielnik/trie": "^2.0.1",
33
- "@popperjs/core": "^2.11.6",
34
33
  "@reduxjs/toolkit": "^1.9.3",
35
- "@scrabble-solver/configs": "^2.11.0",
36
- "@scrabble-solver/constants": "^2.11.0",
37
- "@scrabble-solver/dictionaries": "^2.11.0",
38
- "@scrabble-solver/logger": "^2.11.0",
39
- "@scrabble-solver/solver": "^2.11.0",
40
- "@scrabble-solver/types": "^2.11.0",
41
- "@scrabble-solver/word-definitions": "^2.11.0",
34
+ "@scrabble-solver/configs": "^2.11.2",
35
+ "@scrabble-solver/constants": "^2.11.2",
36
+ "@scrabble-solver/dictionaries": "^2.11.2",
37
+ "@scrabble-solver/logger": "^2.11.2",
38
+ "@scrabble-solver/solver": "^2.11.2",
39
+ "@scrabble-solver/types": "^2.11.2",
40
+ "@scrabble-solver/word-definitions": "^2.11.2",
42
41
  "classnames": "^2.3.2",
43
42
  "include-media": "^2.0.0",
44
43
  "include-media-query-builder": "^1.1.0",
@@ -47,15 +46,12 @@
47
46
  "react": "^18.2.0",
48
47
  "react-dom": "^18.2.0",
49
48
  "react-modal": "^3.16.1",
50
- "react-popper": "^2.3.0",
51
49
  "react-portal": "^4.2.2",
52
50
  "react-redux": "^8.0.5",
53
51
  "react-use": "^17.4.0",
54
52
  "react-window": "^1.8.8",
55
- "redux": "^4.2.1",
56
53
  "redux-saga": "^1.2.2",
57
54
  "store2": "^2.14.2",
58
- "uuid": "^9.0.0",
59
55
  "workbox-expiration": "^6.5.4",
60
56
  "workbox-precaching": "^6.5.4",
61
57
  "workbox-routing": "^6.5.4",
@@ -72,7 +68,6 @@
72
68
  "@types/react-window": "^1.8.5",
73
69
  "@types/redux": "^3.6.31",
74
70
  "@types/redux-saga": "^0.10.5",
75
- "@types/uuid": "^9.0.1",
76
71
  "env-cmd": "^10.1.0",
77
72
  "sass": "^1.59.2",
78
73
  "workbox-webpack-plugin": "^6.5.4"
@@ -1,4 +1,4 @@
1
- .emptyState {
1
+ .alert {
2
2
  display: flex;
3
3
  min-width: 0;
4
4
  width: 100%;
@@ -11,7 +11,6 @@
11
11
  .iconContainer {
12
12
  flex: 0 0 auto;
13
13
  display: flex;
14
- align-items: center;
15
14
  justify-content: center;
16
15
  padding: var(--spacing--m);
17
16
  color: var(--color--foreground--secondary);
@@ -33,15 +32,20 @@
33
32
  color: var(--color--error);
34
33
  }
35
34
 
36
- .warning & {
37
- background-color: var(--color--yellow--light);
38
- color: var(--color--warning);
39
- }
40
-
41
35
  .info & {
42
36
  background-color: var(--color--blue--light);
43
37
  color: var(--color--info);
44
38
  }
39
+
40
+ .success & {
41
+ background-color: var(--color--green--light);
42
+ color: var(--color--success);
43
+ }
44
+
45
+ .warning & {
46
+ background-color: var(--color--yellow--light);
47
+ color: var(--color--warning);
48
+ }
45
49
  }
46
50
 
47
51
  .icon {
@@ -1,30 +1,32 @@
1
1
  import classNames from 'classnames';
2
2
  import { FunctionComponent, HTMLProps, ReactNode, SVGAttributes } from 'react';
3
3
 
4
- import { CrossCircleFill, ExclamationTriangleFill, InfoCircleFill } from 'icons';
4
+ import { Check, CrossCircleFill, ExclamationTriangleFill, InfoCircleFill } from 'icons';
5
5
 
6
- import styles from './EmptyState.module.scss';
6
+ import styles from './Alert.module.scss';
7
7
 
8
8
  interface Props extends HTMLProps<HTMLDivElement> {
9
9
  children: ReactNode;
10
10
  className?: string;
11
- variant: 'error' | 'info' | 'warning';
11
+ variant: 'error' | 'info' | 'success' | 'warning';
12
12
  }
13
13
 
14
14
  const ICON_PER_TYPE: Record<Props['variant'], FunctionComponent<SVGAttributes<SVGElement>>> = {
15
15
  error: CrossCircleFill,
16
16
  info: InfoCircleFill,
17
+ success: Check,
17
18
  warning: ExclamationTriangleFill,
18
19
  };
19
20
 
20
- const EmptyState: FunctionComponent<Props> = ({ children, className, variant, ...props }) => {
21
+ const Alert: FunctionComponent<Props> = ({ children, className, variant, ...props }) => {
21
22
  const Icon = ICON_PER_TYPE[variant];
22
23
 
23
24
  return (
24
25
  <div
25
- className={classNames(styles.emptyState, className, {
26
+ className={classNames(styles.alert, className, {
26
27
  [styles.error]: variant === 'error',
27
28
  [styles.info]: variant === 'info',
29
+ [styles.success]: variant === 'success',
28
30
  [styles.warning]: variant === 'warning',
29
31
  })}
30
32
  {...props}
@@ -38,4 +40,4 @@ const EmptyState: FunctionComponent<Props> = ({ children, className, variant, ..
38
40
  );
39
41
  };
40
42
 
41
- export default EmptyState;
43
+ export default Alert;
@@ -0,0 +1 @@
1
+ export { default } from './Alert';
@@ -4,10 +4,65 @@
4
4
  display: table;
5
5
  box-shadow: var(--box-shadow);
6
6
  border: var(--border);
7
+ border-radius: var(--border--radius);
7
8
  }
8
9
 
9
10
  .row {
10
11
  display: table-row;
12
+
13
+ &:first-child {
14
+ border-top-left-radius: var(--border--radius);
15
+ border-top-right-radius: var(--border--radius);
16
+
17
+ .cell {
18
+ &:first-child {
19
+ [dir='ltr'] & {
20
+ border-top-left-radius: var(--border--radius);
21
+ }
22
+
23
+ [dir='rtl'] & {
24
+ border-top-right-radius: var(--border--radius);
25
+ }
26
+ }
27
+
28
+ &:last-child {
29
+ [dir='ltr'] & {
30
+ border-top-right-radius: var(--border--radius);
31
+ }
32
+
33
+ [dir='rtl'] & {
34
+ border-top-left-radius: var(--border--radius);
35
+ }
36
+ }
37
+ }
38
+ }
39
+
40
+ &:last-child {
41
+ border-bottom-left-radius: var(--border--radius);
42
+ border-bottom-right-radius: var(--border--radius);
43
+
44
+ .cell {
45
+ &:first-child {
46
+ [dir='ltr'] & {
47
+ border-bottom-left-radius: var(--border--radius);
48
+ }
49
+
50
+ [dir='rtl'] & {
51
+ border-bottom-right-radius: var(--border--radius);
52
+ }
53
+ }
54
+
55
+ &:last-child {
56
+ [dir='ltr'] & {
57
+ border-bottom-right-radius: var(--border--radius);
58
+ }
59
+
60
+ [dir='rtl'] & {
61
+ border-bottom-left-radius: var(--border--radius);
62
+ }
63
+ }
64
+ }
65
+ }
11
66
  }
12
67
 
13
68
  .actions {
@@ -45,6 +45,10 @@ const BoardPure: FunctionComponent<Props> = ({
45
45
  <Cell
46
46
  className={styles.cell}
47
47
  cell={cell}
48
+ cellBottom={y < rows.length - 1 ? rows[y + 1][x] : undefined}
49
+ cellLeft={x > 0 ? rows[y][x - 1] : undefined}
50
+ cellRight={x < rows.length - 1 ? rows[y][x + 1] : undefined}
51
+ cellTop={y > 0 ? rows[y - 1][x] : undefined}
48
52
  inputRef={inputRefs[y][x]}
49
53
  isBottom={y === rows.length - 1}
50
54
  isCenter={center.x === x && center.y === y}
@@ -6,6 +6,7 @@
6
6
 
7
7
  position: relative;
8
8
  display: table-cell;
9
+ vertical-align: middle;
9
10
  background-color: var(--color--white);
10
11
  border-bottom: var(--border--width) dotted var(--border--color--light);
11
12
  transition: var(--transition);
@@ -35,42 +36,49 @@
35
36
 
36
37
  &.bonusStart {
37
38
  &::before {
39
+ content: '';
38
40
  background-color: var(--color--bonus--start);
39
41
  }
40
42
  }
41
43
 
42
44
  &.bonusCharacter1 {
43
45
  &::before {
46
+ content: '';
44
47
  background-color: var(--color--bonus--character--1);
45
48
  }
46
49
  }
47
50
 
48
51
  &.bonusCharacter2 {
49
52
  &::before {
53
+ content: '';
50
54
  background-color: var(--color--bonus--character--2);
51
55
  }
52
56
  }
53
57
 
54
58
  &.bonusCharacter3 {
55
59
  &::before {
60
+ content: '';
56
61
  background-color: var(--color--bonus--character--3);
57
62
  }
58
63
  }
59
64
 
60
65
  &.bonusCharacter5 {
61
66
  &::before {
67
+ content: '';
62
68
  background-color: var(--color--bonus--character--5);
63
69
  }
64
70
  }
65
71
 
66
72
  &.bonusCharacterMultiplier2 {
67
73
  &::before {
74
+ content: '';
68
75
  background-color: var(--color--bonus--character-multiplier--2);
69
76
  }
70
77
  }
71
78
 
72
79
  &.bonusCharacterMultiplier3 {
73
80
  &::before {
81
+ content: '';
74
82
  background-color: var(--color--bonus--character-multiplier--3);
75
83
  }
76
84
  }
@@ -91,7 +99,7 @@
91
99
 
92
100
  &.filtered {
93
101
  &::before {
94
- content: ' ';
102
+ content: '';
95
103
  background-color: var(--color--foreground--secondary);
96
104
  }
97
105
  }
@@ -113,7 +121,6 @@
113
121
  font-weight: bold;
114
122
  color: var(--color--white);
115
123
  transition: var(--transition);
116
- content: ' ';
117
124
 
118
125
  [lang='fa-IR'] & {
119
126
  font-family: var(--font--family--latin);
@@ -125,6 +132,48 @@
125
132
  }
126
133
  }
127
134
 
135
+ .tile {
136
+ .sharpTopLeft & {
137
+ [dir='ltr'] & {
138
+ border-top-left-radius: 0;
139
+ }
140
+
141
+ [dir='rtl'] & {
142
+ border-top-right-radius: 0;
143
+ }
144
+ }
145
+
146
+ .sharpTopRight & {
147
+ [dir='ltr'] & {
148
+ border-top-right-radius: 0;
149
+ }
150
+
151
+ [dir='rtl'] & {
152
+ border-top-left-radius: 0;
153
+ }
154
+ }
155
+
156
+ .sharpBottomLeft & {
157
+ [dir='ltr'] & {
158
+ border-bottom-left-radius: 0;
159
+ }
160
+
161
+ [dir='rtl'] & {
162
+ border-bottom-right-radius: 0;
163
+ }
164
+ }
165
+
166
+ .sharpBottomRight & {
167
+ [dir='ltr'] & {
168
+ border-bottom-right-radius: 0;
169
+ }
170
+
171
+ [dir='rtl'] & {
172
+ border-bottom-left-radius: 0;
173
+ }
174
+ }
175
+ }
176
+
128
177
  .icon {
129
178
  $size: 40%;
130
179
 
@@ -17,6 +17,10 @@ import CellPure from './CellPure';
17
17
 
18
18
  interface Props {
19
19
  cell: CellModel;
20
+ cellBottom?: CellModel;
21
+ cellLeft?: CellModel;
22
+ cellRight?: CellModel;
23
+ cellTop?: CellModel;
20
24
  className?: string;
21
25
  inputRef: RefObject<HTMLInputElement>;
22
26
  isBottom: boolean;
@@ -29,6 +33,10 @@ interface Props {
29
33
 
30
34
  const Cell: FunctionComponent<Props> = ({
31
35
  cell,
36
+ cellBottom,
37
+ cellLeft,
38
+ cellRight,
39
+ cellTop,
32
40
  className,
33
41
  inputRef,
34
42
  isBottom,
@@ -59,6 +67,10 @@ const Cell: FunctionComponent<Props> = ({
59
67
  })}
60
68
  bonus={bonus}
61
69
  cell={cell}
70
+ cellBottom={cellBottom}
71
+ cellLeft={cellLeft}
72
+ cellRight={cellRight}
73
+ cellTop={cellTop}
62
74
  className={className}
63
75
  inputRef={inputRef}
64
76
  isBottom={isBottom}
@@ -13,6 +13,10 @@ interface Props {
13
13
  'aria-label': string;
14
14
  bonus: Bonus | undefined;
15
15
  cell: Cell;
16
+ cellBottom?: Cell;
17
+ cellLeft?: Cell;
18
+ cellRight?: Cell;
19
+ cellTop?: Cell;
16
20
  className?: string;
17
21
  inputRef: RefObject<HTMLInputElement>;
18
22
  isBottom: boolean;
@@ -33,6 +37,10 @@ const CellPure: FunctionComponent<Props> = ({
33
37
  'aria-label': ariaLabel,
34
38
  bonus,
35
39
  cell,
40
+ cellBottom,
41
+ cellLeft,
42
+ cellRight,
43
+ cellTop,
36
44
  className,
37
45
  inputRef,
38
46
  isBottom,
@@ -53,6 +61,10 @@ const CellPure: FunctionComponent<Props> = ({
53
61
  [styles.bottom]: isBottom,
54
62
  [styles.filtered]: isFiltered,
55
63
  [styles.right]: isRight,
64
+ [styles.sharpTopLeft]: cellTop?.hasTile() || cellLeft?.hasTile(),
65
+ [styles.sharpTopRight]: cellTop?.hasTile() || cellRight?.hasTile(),
66
+ [styles.sharpBottomLeft]: cellBottom?.hasTile() || cellLeft?.hasTile(),
67
+ [styles.sharpBottomRight]: cellBottom?.hasTile() || cellRight?.hasTile(),
56
68
  })}
57
69
  style={style}
58
70
  >
@@ -1,4 +1,5 @@
1
1
  /* eslint-disable max-lines, max-statements */
2
+ import { PayloadAction } from '@reduxjs/toolkit';
2
3
  import { BLANK, EMPTY_CELL } from '@scrabble-solver/constants';
3
4
  import { Board, Cell } from '@scrabble-solver/types';
4
5
  import {
@@ -14,15 +15,13 @@ import {
14
15
  } from 'react';
15
16
  import { useDispatch } from 'react-redux';
16
17
  import { useLatest } from 'react-use';
17
- import { AnyAction } from 'redux';
18
18
 
19
19
  import { LOCALE_FEATURES } from 'i18n';
20
- import { createGridOf, createKeyboardNavigation, extractCharacters, extractInputValue, isCtrl } from 'lib';
20
+ import { createGridOf, createKeyboardNavigation, extractCharacters, extractInputValue } from 'lib';
21
21
  import { boardSlice, selectConfig, selectLocale, useTypedSelector } from 'state';
22
- import { Direction } from 'types';
22
+ import { Direction, Point } from 'types';
23
23
 
24
24
  import { getPositionInGrid } from '../lib';
25
- import { Point } from '../types';
26
25
 
27
26
  const toggleDirection = (direction: Direction) => (direction === 'vertical' ? 'horizontal' : 'vertical');
28
27
 
@@ -85,7 +84,7 @@ const useGrid = (rows: Cell[][]): [State, Actions] => {
85
84
  const insertValue = useCallback(
86
85
  (position: Point, value: string) => {
87
86
  const characters = value ? extractCharacters(config, value).filter((character) => character !== BLANK) : [BLANK];
88
- const actions: AnyAction[] = [];
87
+ const actions: PayloadAction<unknown>[] = [];
89
88
  let board = new Board({ rows: rows.map((row) => row.map((cell) => cell.clone())) });
90
89
  let { x, y } = position;
91
90
 
@@ -225,7 +224,7 @@ const useGrid = (rows: Cell[][]): [State, Actions] => {
225
224
  onArrowDown: (event) => {
226
225
  event.preventDefault();
227
226
 
228
- if (isCtrl(event)) {
227
+ if (direction === 'horizontal') {
229
228
  onDirectionToggle();
230
229
  } else {
231
230
  changeActiveIndex(0, 1);
@@ -234,7 +233,7 @@ const useGrid = (rows: Cell[][]): [State, Actions] => {
234
233
  onArrowLeft: (event) => {
235
234
  event.preventDefault();
236
235
 
237
- if (isCtrl(event)) {
236
+ if (direction === 'vertical') {
238
237
  onDirectionToggle();
239
238
  } else {
240
239
  changeActiveIndex(LOCALE_FEATURES[locale].direction === 'ltr' ? -1 : 1, 0);
@@ -243,7 +242,7 @@ const useGrid = (rows: Cell[][]): [State, Actions] => {
243
242
  onArrowRight: (event) => {
244
243
  event.preventDefault();
245
244
 
246
- if (isCtrl(event)) {
245
+ if (direction === 'vertical') {
247
246
  onDirectionToggle();
248
247
  } else {
249
248
  changeActiveIndex(LOCALE_FEATURES[locale].direction === 'ltr' ? 1 : -1, 0);
@@ -252,7 +251,7 @@ const useGrid = (rows: Cell[][]): [State, Actions] => {
252
251
  onArrowUp: (event) => {
253
252
  event.preventDefault();
254
253
 
255
- if (isCtrl(event)) {
254
+ if (direction === 'horizontal') {
256
255
  onDirectionToggle();
257
256
  } else {
258
257
  changeActiveIndex(0, -1);
@@ -289,22 +288,6 @@ const useGrid = (rows: Cell[][]): [State, Actions] => {
289
288
 
290
289
  const { x, y } = position;
291
290
  const character = event.key.toLowerCase();
292
- const isTogglingBlank = isCtrl(event) && character === 'b';
293
- const twoCharacterTile = config.getTwoCharacterTileByPrefix(character);
294
-
295
- if (isTogglingBlank) {
296
- event.preventDefault();
297
- dispatch(boardSlice.actions.toggleCellIsBlank(position));
298
- return;
299
- }
300
-
301
- if (isCtrl(event) && twoCharacterTile) {
302
- event.preventDefault();
303
- dispatch(boardSlice.actions.changeCellValue({ x, y, value: twoCharacterTile }));
304
- moveFocus(1);
305
- return;
306
- }
307
-
308
291
  const cell = rows[y][x];
309
292
  const twoCharacterCandidate = cell.tile.character + character;
310
293
 
@@ -333,7 +316,7 @@ const useGrid = (rows: Cell[][]): [State, Actions] => {
333
316
  dispatch(boardSlice.actions.toggleCellIsBlank(position));
334
317
  },
335
318
  });
336
- }, [changeActiveIndex, config, dispatch, locale, moveFocus, onDirectionToggle, rows]);
319
+ }, [changeActiveIndex, config, direction, dispatch, locale, moveFocus, onDirectionToggle, rows]);
337
320
 
338
321
  const onPaste = useCallback<ClipboardEventHandler>(
339
322
  (event) => {