scrabble-solver 2.12.2 → 2.12.4
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.
- package/README.md +40 -13
- package/lerna.json +1 -1
- package/package.json +3 -2
- package/packages/configs/build/games/index.d.ts +3 -0
- package/packages/configs/build/games/index.js +12 -0
- package/packages/configs/build/games/literaki.d.ts +25 -0
- package/packages/configs/build/games/literaki.js +110 -0
- package/packages/configs/build/games/scrabble.d.ts +18 -0
- package/packages/configs/build/games/scrabble.js +78 -0
- package/packages/configs/build/games/superScrabble.d.ts +18 -0
- package/packages/configs/build/games/superScrabble.js +141 -0
- package/packages/configs/build/getConfig.d.ts +2 -6
- package/packages/configs/build/getConfig.js +29 -10
- package/packages/configs/build/hasConfig.d.ts +3 -0
- package/packages/configs/build/hasConfig.js +31 -0
- package/packages/configs/build/index.d.ts +7 -4
- package/packages/configs/build/index.js +32 -9
- package/packages/configs/build/locales/deDe.d.ts +3 -0
- package/packages/configs/build/locales/deDe.js +42 -0
- package/packages/configs/build/locales/enGb.d.ts +3 -0
- package/packages/configs/build/locales/enGb.js +104 -0
- package/packages/configs/build/locales/enUs.d.ts +3 -0
- package/packages/configs/build/locales/enUs.js +104 -0
- package/packages/configs/build/locales/esEs.d.ts +3 -0
- package/packages/configs/build/locales/esEs.js +41 -0
- package/packages/configs/build/locales/faIr.d.ts +3 -0
- package/packages/configs/build/locales/faIr.js +45 -0
- package/packages/configs/build/locales/frFr.d.ts +3 -0
- package/packages/configs/build/locales/frFr.js +39 -0
- package/packages/configs/build/locales/index.d.ts +7 -0
- package/packages/configs/build/locales/index.js +20 -0
- package/packages/configs/build/locales/plPl.d.ts +3 -0
- package/packages/configs/build/locales/plPl.js +83 -0
- package/packages/configs/package.json +3 -3
- package/packages/configs/src/games/index.ts +3 -0
- package/packages/configs/src/games/literaki.ts +110 -0
- package/packages/configs/src/games/scrabble.ts +78 -0
- package/packages/configs/src/games/superScrabble.ts +141 -0
- package/packages/configs/src/getConfig.ts +8 -15
- package/packages/configs/src/hasConfig.ts +10 -0
- package/packages/configs/src/index.ts +7 -4
- package/packages/configs/src/locales/deDe.ts +43 -0
- package/packages/configs/src/locales/enGb.ts +105 -0
- package/packages/configs/src/locales/enUs.ts +105 -0
- package/packages/configs/src/locales/esEs.ts +42 -0
- package/packages/configs/src/locales/faIr.ts +46 -0
- package/packages/configs/src/locales/frFr.ts +40 -0
- package/packages/configs/src/locales/index.ts +7 -0
- package/packages/configs/src/locales/plPl.ts +84 -0
- package/packages/constants/package.json +1 -1
- package/packages/dictionaries/package-lock.json +3 -10
- package/packages/dictionaries/package.json +4 -4
- package/packages/logger/package-lock.json +3 -224
- package/packages/logger/package.json +1 -1
- package/packages/scrabble-solver/.next/BUILD_ID +1 -1
- package/packages/scrabble-solver/.next/build-manifest.json +6 -6
- package/packages/scrabble-solver/.next/cache/.tsbuildinfo +1 -1
- package/packages/scrabble-solver/.next/cache/eslint/.cache_8dgz12 +1 -1
- package/packages/scrabble-solver/.next/cache/next-server.js.nft.json +1 -1
- package/packages/scrabble-solver/.next/cache/webpack/client-production/0.pack +0 -0
- package/packages/scrabble-solver/.next/cache/webpack/client-production/index.pack +0 -0
- package/packages/scrabble-solver/.next/cache/webpack/edge-server-production/0.pack +0 -0
- package/packages/scrabble-solver/.next/cache/webpack/edge-server-production/index.pack +0 -0
- package/packages/scrabble-solver/.next/cache/webpack/server-production/0.pack +0 -0
- package/packages/scrabble-solver/.next/cache/webpack/server-production/index.pack +0 -0
- package/packages/scrabble-solver/.next/next-server.js.nft.json +1 -1
- package/packages/scrabble-solver/.next/prerender-manifest.json +1 -1
- package/packages/scrabble-solver/.next/routes-manifest.json +1 -1
- package/packages/scrabble-solver/.next/server/chunks/131.js +478 -106
- package/packages/scrabble-solver/.next/server/chunks/277.js +1132 -976
- package/packages/scrabble-solver/.next/server/chunks/44.js +37 -9
- package/packages/scrabble-solver/.next/server/chunks/865.js +597 -169
- package/packages/scrabble-solver/.next/server/chunks/911.js +894 -773
- package/packages/scrabble-solver/.next/server/middleware-build-manifest.js +1 -1
- package/packages/scrabble-solver/.next/server/pages/404.html +1 -1
- package/packages/scrabble-solver/.next/server/pages/404.js.nft.json +1 -1
- package/packages/scrabble-solver/.next/server/pages/500.html +1 -1
- package/packages/scrabble-solver/.next/server/pages/_app.js +3 -1
- package/packages/scrabble-solver/.next/server/pages/_app.js.nft.json +1 -1
- package/packages/scrabble-solver/.next/server/pages/_document.js.nft.json +1 -1
- package/packages/scrabble-solver/.next/server/pages/api/dictionary/[locale]/[word].js +4 -2
- package/packages/scrabble-solver/.next/server/pages/api/solve.js +23 -19
- package/packages/scrabble-solver/.next/server/pages/api/verify.js +8 -5
- package/packages/scrabble-solver/.next/server/pages/index.html +1 -1
- package/packages/scrabble-solver/.next/server/pages/index.js +42 -55
- package/packages/scrabble-solver/.next/server/pages/index.js.nft.json +1 -1
- package/packages/scrabble-solver/.next/server/pages/index.json +1 -1
- package/packages/scrabble-solver/.next/server/pages-manifest.json +2 -2
- package/packages/scrabble-solver/.next/static/{9dmPfnTc_AQTHBPvL7xQe → 8oRk1nUMQYFWmhu4SExQI}/_buildManifest.js +1 -1
- package/packages/scrabble-solver/.next/static/chunks/pages/_app-e7f3d1c9c09c8f91.js +32 -0
- package/packages/scrabble-solver/.next/static/chunks/pages/index-82b2939158c7729f.js +1 -0
- package/packages/scrabble-solver/.next/static/css/4e8b47fe382a8a8f.css +2 -0
- package/packages/scrabble-solver/.next/static/css/cfae5256f1689f57.css +1 -0
- package/packages/scrabble-solver/.next/trace +51 -52
- package/packages/scrabble-solver/package-lock.json +158 -4898
- package/packages/scrabble-solver/package.json +8 -8
- package/packages/scrabble-solver/src/components/Board/components/Cell/Cell.module.scss +4 -12
- package/packages/scrabble-solver/src/components/Board/components/Cell/Cell.tsx +4 -0
- package/packages/scrabble-solver/src/components/Board/hooks/useBackgroundImage.tsx +23 -0
- package/packages/scrabble-solver/src/components/PlainTiles/lib/createPlainTile.ts +4 -4
- package/packages/scrabble-solver/src/components/Radio/Radio.module.scss +4 -0
- package/packages/scrabble-solver/src/components/Radio/Radio.tsx +1 -0
- package/packages/scrabble-solver/src/components/SeoMessage/SeoMessage.tsx +3 -3
- package/packages/scrabble-solver/src/hooks/useAppLayout.ts +1 -2
- package/packages/scrabble-solver/src/hooks/useLocalStorage.ts +5 -5
- package/packages/scrabble-solver/src/i18n/constants.ts +31 -61
- package/packages/scrabble-solver/src/lib/extractCharacters.test.ts +3 -3
- package/packages/scrabble-solver/src/lib/extractCharactersByCase.test.ts +3 -3
- package/packages/scrabble-solver/src/lib/getCellSize.ts +2 -2
- package/packages/scrabble-solver/src/modals/MenuModal/MenuModal.module.scss +0 -1
- package/packages/scrabble-solver/src/modals/MenuModal/MenuModal.tsx +3 -3
- package/packages/scrabble-solver/src/modals/SettingsModal/components/ConfigSetting/ConfigSetting.tsx +16 -7
- package/packages/scrabble-solver/src/modals/SettingsModal/components/LocaleSetting/LocaleSetting.module.scss +1 -4
- package/packages/scrabble-solver/src/modals/SettingsModal/components/LocaleSetting/LocaleSetting.tsx +8 -8
- package/packages/scrabble-solver/src/pages/_app.tsx +3 -1
- package/packages/scrabble-solver/src/pages/api/dictionary/[locale]/[word].ts +6 -3
- package/packages/scrabble-solver/src/pages/api/solve.ts +11 -7
- package/packages/scrabble-solver/src/pages/api/verify.ts +11 -7
- package/packages/scrabble-solver/src/pages/index.module.scss +0 -1
- package/packages/scrabble-solver/src/parameters/index.ts +4 -6
- package/packages/scrabble-solver/src/sdk/solve.ts +3 -3
- package/packages/scrabble-solver/src/sdk/verify.ts +3 -3
- package/packages/scrabble-solver/src/service-worker/routeSolveRequests.ts +3 -3
- package/packages/scrabble-solver/src/state/localStorage.ts +6 -6
- package/packages/scrabble-solver/src/state/sagas.ts +18 -7
- package/packages/scrabble-solver/src/state/selectors.ts +3 -3
- package/packages/scrabble-solver/src/state/slices/boardInitialState.ts +3 -3
- package/packages/scrabble-solver/src/state/slices/boardSlice.ts +20 -6
- package/packages/scrabble-solver/src/state/slices/settingsInitialState.ts +3 -4
- package/packages/scrabble-solver/src/state/slices/settingsSlice.ts +5 -5
- package/packages/scrabble-solver/src/styles/variables.scss +0 -9
- package/packages/solver/build/getPatternHash.js +2 -2
- package/packages/solver/build/solve.js +3 -1
- package/packages/solver/package-lock.json +3 -10
- package/packages/solver/package.json +5 -5
- package/packages/solver/src/fillPattern.test.ts +3 -3
- package/packages/solver/src/generatePatterns.test.ts +13 -0
- package/packages/solver/src/getPatternHash.ts +2 -2
- package/packages/solver/src/getPatternScore.test.ts +4 -3
- package/packages/solver/src/solve.test.ts +68 -6
- package/packages/solver/src/solve.ts +4 -1
- package/packages/types/build/Config.d.ts +2 -0
- package/packages/types/build/Config.js +3 -0
- package/packages/types/build/ConfigJson.d.ts +2 -1
- package/packages/types/build/Dictionary.d.ts +7 -0
- package/packages/types/build/Dictionary.js +2 -0
- package/packages/types/build/Game.d.ts +7 -0
- package/packages/types/build/Game.js +13 -0
- package/packages/types/build/Locale.d.ts +5 -0
- package/packages/types/build/Locale.js +5 -1
- package/packages/types/build/index.d.ts +4 -2
- package/packages/types/build/index.js +8 -5
- package/packages/types/package.json +2 -2
- package/packages/types/src/Config.ts +5 -0
- package/packages/types/src/ConfigJson.ts +2 -1
- package/packages/types/src/Dictionary.ts +9 -0
- package/packages/types/src/Game.ts +11 -0
- package/packages/types/src/Locale.ts +5 -1
- package/packages/types/src/index.ts +4 -2
- package/packages/word-definitions/build/lib/normalizeDefinition.js +3 -1
- package/packages/word-definitions/package-lock.json +13 -163
- package/packages/word-definitions/package.json +2 -2
- package/packages/word-definitions/src/lib/normalizeDefinition.ts +3 -1
- package/packages/word-lists/build/getFrFrWordList.js +1 -3
- package/packages/word-lists/package-lock.json +9 -401
- package/packages/word-lists/package.json +2 -2
- package/packages/word-lists/src/getFrFrWordList.ts +1 -3
- package/packages/configs/build/getLocaleConfig.d.ts +0 -3
- package/packages/configs/build/getLocaleConfig.js +0 -10
- package/packages/configs/build/isConfigId.d.ts +0 -2
- package/packages/configs/build/isConfigId.js +0 -12
- package/packages/configs/build/literaki/bonuses.d.ts +0 -14
- package/packages/configs/build/literaki/bonuses.js +0 -99
- package/packages/configs/build/literaki/index.d.ts +0 -1
- package/packages/configs/build/literaki/index.js +0 -8
- package/packages/configs/build/literaki/literaki.d.ts +0 -13
- package/packages/configs/build/literaki/literaki.js +0 -31
- package/packages/configs/build/literaki/tiles/index.d.ts +0 -6
- package/packages/configs/build/literaki/tiles/index.js +0 -18
- package/packages/configs/build/literaki/tiles/tilesDe.d.ts +0 -6
- package/packages/configs/build/literaki/tiles/tilesDe.js +0 -34
- package/packages/configs/build/literaki/tiles/tilesEn.d.ts +0 -6
- package/packages/configs/build/literaki/tiles/tilesEn.js +0 -31
- package/packages/configs/build/literaki/tiles/tilesEs.d.ts +0 -6
- package/packages/configs/build/literaki/tiles/tilesEs.js +0 -33
- package/packages/configs/build/literaki/tiles/tilesFa.d.ts +0 -6
- package/packages/configs/build/literaki/tiles/tilesFa.js +0 -37
- package/packages/configs/build/literaki/tiles/tilesFr.d.ts +0 -6
- package/packages/configs/build/literaki/tiles/tilesFr.js +0 -31
- package/packages/configs/build/literaki/tiles/tilesPl.d.ts +0 -6
- package/packages/configs/build/literaki/tiles/tilesPl.js +0 -37
- package/packages/configs/build/scrabble/bonuses.d.ts +0 -7
- package/packages/configs/build/scrabble/bonuses.js +0 -67
- package/packages/configs/build/scrabble/index.d.ts +0 -1
- package/packages/configs/build/scrabble/index.js +0 -8
- package/packages/configs/build/scrabble/scrabble.d.ts +0 -13
- package/packages/configs/build/scrabble/scrabble.js +0 -31
- package/packages/configs/build/scrabble/tiles/index.d.ts +0 -6
- package/packages/configs/build/scrabble/tiles/index.js +0 -18
- package/packages/configs/build/scrabble/tiles/tilesDe.d.ts +0 -6
- package/packages/configs/build/scrabble/tiles/tilesDe.js +0 -34
- package/packages/configs/build/scrabble/tiles/tilesEn.d.ts +0 -6
- package/packages/configs/build/scrabble/tiles/tilesEn.js +0 -31
- package/packages/configs/build/scrabble/tiles/tilesEs.d.ts +0 -6
- package/packages/configs/build/scrabble/tiles/tilesEs.js +0 -33
- package/packages/configs/build/scrabble/tiles/tilesFa.d.ts +0 -6
- package/packages/configs/build/scrabble/tiles/tilesFa.js +0 -37
- package/packages/configs/build/scrabble/tiles/tilesFr.d.ts +0 -6
- package/packages/configs/build/scrabble/tiles/tilesFr.js +0 -31
- package/packages/configs/build/scrabble/tiles/tilesPl.d.ts +0 -6
- package/packages/configs/build/scrabble/tiles/tilesPl.js +0 -37
- package/packages/configs/src/getLocaleConfig.ts +0 -9
- package/packages/configs/src/isConfigId.ts +0 -10
- package/packages/configs/src/literaki/bonuses.ts +0 -99
- package/packages/configs/src/literaki/index.ts +0 -1
- package/packages/configs/src/literaki/literaki.ts +0 -30
- package/packages/configs/src/literaki/tiles/index.ts +0 -6
- package/packages/configs/src/literaki/tiles/tilesDe.ts +0 -33
- package/packages/configs/src/literaki/tiles/tilesEn.ts +0 -30
- package/packages/configs/src/literaki/tiles/tilesEs.ts +0 -32
- package/packages/configs/src/literaki/tiles/tilesFa.ts +0 -36
- package/packages/configs/src/literaki/tiles/tilesFr.ts +0 -30
- package/packages/configs/src/literaki/tiles/tilesPl.ts +0 -36
- package/packages/configs/src/scrabble/bonuses.ts +0 -67
- package/packages/configs/src/scrabble/index.ts +0 -1
- package/packages/configs/src/scrabble/scrabble.ts +0 -30
- package/packages/configs/src/scrabble/tiles/index.ts +0 -6
- package/packages/configs/src/scrabble/tiles/tilesDe.ts +0 -33
- package/packages/configs/src/scrabble/tiles/tilesEn.ts +0 -30
- package/packages/configs/src/scrabble/tiles/tilesEs.ts +0 -32
- package/packages/configs/src/scrabble/tiles/tilesFa.ts +0 -36
- package/packages/configs/src/scrabble/tiles/tilesFr.ts +0 -30
- package/packages/configs/src/scrabble/tiles/tilesPl.ts +0 -36
- package/packages/dictionaries/.scrabble-solver/dictionaries/de-DE.txt +0 -1
- package/packages/dictionaries/.scrabble-solver/dictionaries/en-GB.txt +0 -1
- package/packages/dictionaries/.scrabble-solver/dictionaries/en-US.txt +0 -1
- package/packages/dictionaries/.scrabble-solver/dictionaries/es-ES.txt +0 -1
- package/packages/dictionaries/.scrabble-solver/dictionaries/fa-IR.txt +0 -1
- package/packages/dictionaries/.scrabble-solver/dictionaries/fr-FR.txt +0 -1
- package/packages/dictionaries/.scrabble-solver/dictionaries/pl-PL.txt +0 -1
- package/packages/scrabble-solver/.next/static/chunks/pages/_app-02851b06b95b19cb.js +0 -32
- package/packages/scrabble-solver/.next/static/chunks/pages/index-0ba5607d1aad8a09.js +0 -1
- package/packages/scrabble-solver/.next/static/css/09dfdea53eba31a9.css +0 -2
- package/packages/scrabble-solver/.next/static/css/60e8258da7362a1a.css +0 -1
- package/packages/scrabble-solver/src/i18n/i18n.module.scss +0 -27
- package/packages/scrabble-solver/src/modals/SettingsModal/components/ConfigSetting/options.ts +0 -19
- package/packages/scrabble-solver/src/modals/SettingsModal/components/ConfigSetting/types.ts +0 -9
- package/packages/scrabble-solver/src/modals/SettingsModal/components/InputModeSetting/types.ts +0 -7
- package/packages/scrabble-solver/src/modals/SettingsModal/components/LocaleSetting/types.ts +0 -9
- /package/packages/scrabble-solver/.next/static/{9dmPfnTc_AQTHBPvL7xQe → 8oRk1nUMQYFWmhu4SExQI}/_ssgManifest.js +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@scrabble-solver/scrabble-solver",
|
|
3
|
-
"version": "2.12.
|
|
3
|
+
"version": "2.12.4",
|
|
4
4
|
"description": "Scrabble Solver 2 - App",
|
|
5
5
|
"engines": {
|
|
6
6
|
"node": ">=16"
|
|
@@ -31,13 +31,13 @@
|
|
|
31
31
|
"@floating-ui/react": "^0.22.3",
|
|
32
32
|
"@kamilmielnik/trie": "^2.0.1",
|
|
33
33
|
"@reduxjs/toolkit": "^1.9.3",
|
|
34
|
-
"@scrabble-solver/configs": "^2.12.
|
|
35
|
-
"@scrabble-solver/constants": "^2.12.
|
|
36
|
-
"@scrabble-solver/dictionaries": "^2.12.
|
|
37
|
-
"@scrabble-solver/logger": "^2.12.
|
|
38
|
-
"@scrabble-solver/solver": "^2.12.
|
|
39
|
-
"@scrabble-solver/types": "^2.12.
|
|
40
|
-
"@scrabble-solver/word-definitions": "^2.12.
|
|
34
|
+
"@scrabble-solver/configs": "^2.12.4",
|
|
35
|
+
"@scrabble-solver/constants": "^2.12.4",
|
|
36
|
+
"@scrabble-solver/dictionaries": "^2.12.4",
|
|
37
|
+
"@scrabble-solver/logger": "^2.12.4",
|
|
38
|
+
"@scrabble-solver/solver": "^2.12.4",
|
|
39
|
+
"@scrabble-solver/types": "^2.12.4",
|
|
40
|
+
"@scrabble-solver/word-definitions": "^2.12.4",
|
|
41
41
|
"classnames": "^2.3.2",
|
|
42
42
|
"include-media": "^2.0.0",
|
|
43
43
|
"include-media-query-builder": "^1.1.0",
|
|
@@ -17,18 +17,14 @@
|
|
|
17
17
|
}
|
|
18
18
|
|
|
19
19
|
[dir='ltr'] & {
|
|
20
|
-
|
|
21
|
-
&:nth-child(15n + 2),
|
|
22
|
-
&:nth-child(15n + 3) {
|
|
20
|
+
&.first3 {
|
|
23
21
|
input {
|
|
24
22
|
left: 0;
|
|
25
23
|
clip-path: polygon(0 (100% / 3), (100% / 3) (100% / 3), (100% / 3) (200% / 3), 0 (200% / 3));
|
|
26
24
|
}
|
|
27
25
|
}
|
|
28
26
|
|
|
29
|
-
|
|
30
|
-
&:nth-last-child(15n + 2),
|
|
31
|
-
&:nth-last-child(15n + 3) {
|
|
27
|
+
&.last3 {
|
|
32
28
|
input {
|
|
33
29
|
left: -200%;
|
|
34
30
|
clip-path: polygon((200% / 3) (100% / 3), 100% (100% / 3), 100% (200% / 3), (200% / 3) (200% / 3));
|
|
@@ -37,9 +33,7 @@
|
|
|
37
33
|
}
|
|
38
34
|
|
|
39
35
|
[dir='rtl'] & {
|
|
40
|
-
|
|
41
|
-
&:nth-child(15n + 2),
|
|
42
|
-
&:nth-child(15n + 3) {
|
|
36
|
+
&.first3 {
|
|
43
37
|
input {
|
|
44
38
|
left: -200%;
|
|
45
39
|
right: 0;
|
|
@@ -47,9 +41,7 @@
|
|
|
47
41
|
}
|
|
48
42
|
}
|
|
49
43
|
|
|
50
|
-
|
|
51
|
-
&:nth-last-child(15n + 2),
|
|
52
|
-
&:nth-last-child(15n + 3) {
|
|
44
|
+
&.last3 {
|
|
53
45
|
input {
|
|
54
46
|
left: 0;
|
|
55
47
|
right: -200%;
|
|
@@ -13,6 +13,7 @@ import {
|
|
|
13
13
|
|
|
14
14
|
import {
|
|
15
15
|
selectCellIsValid,
|
|
16
|
+
selectConfig,
|
|
16
17
|
selectInputMode,
|
|
17
18
|
selectLocale,
|
|
18
19
|
selectTilePoints,
|
|
@@ -52,6 +53,7 @@ const Cell: FunctionComponent<Props> = ({
|
|
|
52
53
|
const { tile, x, y } = cell;
|
|
53
54
|
const translate = useTranslate();
|
|
54
55
|
const locale = useTypedSelector(selectLocale);
|
|
56
|
+
const config = useTypedSelector(selectConfig);
|
|
55
57
|
const inputMode = useTypedSelector(selectInputMode);
|
|
56
58
|
const points = useTypedSelector((state) => selectTilePoints(state, cell.tile));
|
|
57
59
|
const isValid = useTypedSelector((state) => selectCellIsValid(state, cell));
|
|
@@ -98,6 +100,8 @@ const Cell: FunctionComponent<Props> = ({
|
|
|
98
100
|
y: (y + 1).toLocaleString(locale),
|
|
99
101
|
})}
|
|
100
102
|
className={classNames(styles.tile, className, {
|
|
103
|
+
[styles.first3]: x < 3,
|
|
104
|
+
[styles.last3]: config.boardWidth - x - 1 < 3,
|
|
101
105
|
[styles.sharpTopLeft]: cellTop?.hasTile() || cellLeft?.hasTile(),
|
|
102
106
|
[styles.sharpTopRight]: cellTop?.hasTile() || cellRight?.hasTile(),
|
|
103
107
|
[styles.sharpBottomLeft]: cellBottom?.hasTile() || cellLeft?.hasTile(),
|
|
@@ -21,6 +21,7 @@ const VERTICAL_LINE = 'v';
|
|
|
21
21
|
const BONUS = 'b';
|
|
22
22
|
const BONUS_WORD_2 = 'b2';
|
|
23
23
|
const BONUS_WORD_3 = 'b3';
|
|
24
|
+
const BONUS_WORD_4 = 'b4';
|
|
24
25
|
const CELL_FILTER = 'c';
|
|
25
26
|
|
|
26
27
|
const useBackgroundImage = () => {
|
|
@@ -41,6 +42,7 @@ const useBackgroundImage = () => {
|
|
|
41
42
|
const characterBonuses = config.bonuses.filter((bonus) => bonus.type === BONUS_CHARACTER);
|
|
42
43
|
const word2Bonuses = config.bonuses.filter((bonus) => bonus.type === BONUS_WORD && bonus.multiplier === 2);
|
|
43
44
|
const word3Bonuses = config.bonuses.filter((bonus) => bonus.type === BONUS_WORD && bonus.multiplier === 3);
|
|
45
|
+
const word4Bonuses = config.bonuses.filter((bonus) => bonus.type === BONUS_WORD && bonus.multiplier === 4);
|
|
44
46
|
|
|
45
47
|
const getX = (point: Point): number => point.x * (cellSize + BORDER_WIDTH);
|
|
46
48
|
|
|
@@ -101,6 +103,23 @@ const useBackgroundImage = () => {
|
|
|
101
103
|
</text>
|
|
102
104
|
</symbol>
|
|
103
105
|
|
|
106
|
+
<symbol id={BONUS_WORD_4}>
|
|
107
|
+
<rect height={bonusSize} rx={borderRadius} width={bonusSize} x={bonusOffset} y={bonusOffset} />
|
|
108
|
+
|
|
109
|
+
<text
|
|
110
|
+
dominantBaseline="central"
|
|
111
|
+
fill="white"
|
|
112
|
+
fontFamily="system-ui, sans-serif"
|
|
113
|
+
fontSize={fontSize}
|
|
114
|
+
fontWeight="bold"
|
|
115
|
+
textAnchor="middle"
|
|
116
|
+
x={fontOffset}
|
|
117
|
+
y={fontOffset}
|
|
118
|
+
>
|
|
119
|
+
x4
|
|
120
|
+
</text>
|
|
121
|
+
</symbol>
|
|
122
|
+
|
|
104
123
|
<symbol id={CELL_FILTER}>
|
|
105
124
|
<rect
|
|
106
125
|
fill={COLOR_FILTERED}
|
|
@@ -137,6 +156,10 @@ const useBackgroundImage = () => {
|
|
|
137
156
|
<use fill={getBonusColor(bonus)} key={index} href={`#${BONUS_WORD_3}`} x={getX(bonus)} y={getY(bonus)} />
|
|
138
157
|
))}
|
|
139
158
|
|
|
159
|
+
{word4Bonuses.map((bonus, index) => (
|
|
160
|
+
<use fill={getBonusColor(bonus)} key={index} href={`#${BONUS_WORD_4}`} x={getX(bonus)} y={getY(bonus)} />
|
|
161
|
+
))}
|
|
162
|
+
|
|
140
163
|
<rect
|
|
141
164
|
fill={COLOR_BONUS_START}
|
|
142
165
|
height={bonusSize}
|
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { Locale } from '@scrabble-solver/types';
|
|
1
|
+
import { getConfig } from '@scrabble-solver/configs';
|
|
2
|
+
import { Game, Locale } from '@scrabble-solver/types';
|
|
3
3
|
|
|
4
4
|
import {
|
|
5
5
|
PLAIN_TILES_COLOR_DEFAULT,
|
|
6
6
|
PLAIN_TILES_POINTS_COLORS,
|
|
7
|
-
PLAIN_TILES_TILE_MAX_SCATTER,
|
|
8
7
|
PLAIN_TILES_TILE_MAX_ROTATE,
|
|
8
|
+
PLAIN_TILES_TILE_MAX_SCATTER,
|
|
9
9
|
PLAIN_TILES_TILE_SIZE,
|
|
10
10
|
} from 'parameters';
|
|
11
11
|
|
|
@@ -16,7 +16,7 @@ import getY from './getY';
|
|
|
16
16
|
import randomize from './randomize';
|
|
17
17
|
|
|
18
18
|
const createPlainTile = ({ cellIndex, character, color, rowIndex, showPoints }: CreatePlainTileOptions): PlainTile => {
|
|
19
|
-
const configPoints =
|
|
19
|
+
const configPoints = getConfig(Game.Literaki, Locale.EN_US).getCharacterPoints(character.toLowerCase());
|
|
20
20
|
const points = showPoints ? configPoints : undefined;
|
|
21
21
|
const defaultColor =
|
|
22
22
|
typeof configPoints === 'number' ? PLAIN_TILES_POINTS_COLORS[configPoints] : PLAIN_TILES_COLOR_DEFAULT;
|
|
@@ -10,9 +10,9 @@ const INVISIBLE_STYLE: CSSProperties = {
|
|
|
10
10
|
|
|
11
11
|
const SeoMessage: FunctionComponent = () => (
|
|
12
12
|
<p style={INVISIBLE_STYLE}>
|
|
13
|
-
Scrabble Solver 2 is a free and open-source analysis tool for Scrabble
|
|
14
|
-
using given letters and board state. Available in English, French, German, Polish & Spanish.
|
|
15
|
-
available on GitHub - contributions are welcome!
|
|
13
|
+
Scrabble Solver 2 is a free and open-source analysis tool for Scrabble, Super Scrabble & Literaki. Quickly find
|
|
14
|
+
top scoring words using given letters and board state. Available in English, French, German, Polish & Spanish.
|
|
15
|
+
Source code is available on GitHub - contributions are welcome!
|
|
16
16
|
</p>
|
|
17
17
|
);
|
|
18
18
|
|
|
@@ -2,7 +2,6 @@
|
|
|
2
2
|
|
|
3
3
|
import {
|
|
4
4
|
BOARD_TILE_SIZE_MAX,
|
|
5
|
-
BOARD_TILE_SIZE_MIN,
|
|
6
5
|
BORDER_WIDTH,
|
|
7
6
|
BUTTON_HEIGHT,
|
|
8
7
|
COMPONENTS_SPACING,
|
|
@@ -47,7 +46,7 @@ const useAppLayout = () => {
|
|
|
47
46
|
: Math.max(solverHeight - bottomContainerHeight, 0);
|
|
48
47
|
const cellWidth = (maxBoardWidth - (config.boardWidth + 1) * BORDER_WIDTH) / config.boardWidth;
|
|
49
48
|
const cellHeight = (maxBoardHeight - (config.boardHeight + 1) * BORDER_WIDTH) / config.boardHeight;
|
|
50
|
-
const cellSize = Math.min(Math.
|
|
49
|
+
const cellSize = Math.min(Math.min(cellWidth, cellHeight), BOARD_TILE_SIZE_MAX);
|
|
51
50
|
const boardSize = (cellSize + BORDER_WIDTH) * config.boardWidth + BORDER_WIDTH;
|
|
52
51
|
const maxControlsWidth = tileSize * config.maximumCharactersCount + 2 * BORDER_WIDTH;
|
|
53
52
|
const showResultsInModal = isLessThanL;
|
|
@@ -4,7 +4,7 @@ import {
|
|
|
4
4
|
localStorage,
|
|
5
5
|
selectAutoGroupTiles,
|
|
6
6
|
selectBoard,
|
|
7
|
-
|
|
7
|
+
selectGame,
|
|
8
8
|
selectInputMode,
|
|
9
9
|
selectLocale,
|
|
10
10
|
selectRack,
|
|
@@ -14,7 +14,7 @@ import {
|
|
|
14
14
|
const useLocalStorage = () => {
|
|
15
15
|
const autoGroupTiles = useTypedSelector(selectAutoGroupTiles);
|
|
16
16
|
const board = useTypedSelector(selectBoard);
|
|
17
|
-
const
|
|
17
|
+
const game = useTypedSelector(selectGame);
|
|
18
18
|
const inputMode = useTypedSelector(selectInputMode);
|
|
19
19
|
const locale = useTypedSelector(selectLocale);
|
|
20
20
|
const rack = useTypedSelector(selectRack);
|
|
@@ -32,10 +32,10 @@ const useLocalStorage = () => {
|
|
|
32
32
|
}, [board]);
|
|
33
33
|
|
|
34
34
|
useEffect(() => {
|
|
35
|
-
if (
|
|
36
|
-
localStorage.
|
|
35
|
+
if (game) {
|
|
36
|
+
localStorage.setGame(game);
|
|
37
37
|
}
|
|
38
|
-
}, [
|
|
38
|
+
}, [game]);
|
|
39
39
|
|
|
40
40
|
useEffect(() => {
|
|
41
41
|
if (inputMode) {
|
|
@@ -4,12 +4,14 @@ import { FunctionComponent, SVGAttributes } from 'react';
|
|
|
4
4
|
|
|
5
5
|
import { FlagDe, FlagEs, FlagFa, FlagFr, FlagGb, FlagPl, FlagUs } from 'icons';
|
|
6
6
|
|
|
7
|
-
import styles from './i18n.module.scss';
|
|
8
|
-
|
|
9
7
|
interface LocaleFeatures {
|
|
10
8
|
comma: string;
|
|
11
9
|
consonants: boolean;
|
|
12
10
|
direction: 'ltr' | 'rtl';
|
|
11
|
+
Icon: FunctionComponent<SVGAttributes<SVGElement>>;
|
|
12
|
+
label: string;
|
|
13
|
+
locale: Locale;
|
|
14
|
+
name: string;
|
|
13
15
|
separator: string;
|
|
14
16
|
vowels: boolean;
|
|
15
17
|
}
|
|
@@ -19,6 +21,10 @@ export const LOCALE_FEATURES: Record<Locale, LocaleFeatures> = {
|
|
|
19
21
|
comma: COMMA_LATIN,
|
|
20
22
|
consonants: true,
|
|
21
23
|
direction: 'ltr',
|
|
24
|
+
Icon: FlagDe,
|
|
25
|
+
label: 'Deutsch',
|
|
26
|
+
locale: Locale.DE_DE,
|
|
27
|
+
name: 'German',
|
|
22
28
|
separator: `${COMMA_LATIN} `,
|
|
23
29
|
vowels: true,
|
|
24
30
|
},
|
|
@@ -26,6 +32,10 @@ export const LOCALE_FEATURES: Record<Locale, LocaleFeatures> = {
|
|
|
26
32
|
comma: COMMA_LATIN,
|
|
27
33
|
consonants: true,
|
|
28
34
|
direction: 'ltr',
|
|
35
|
+
Icon: FlagGb,
|
|
36
|
+
label: 'English (GB)',
|
|
37
|
+
locale: Locale.EN_GB,
|
|
38
|
+
name: 'English (GB)',
|
|
29
39
|
separator: `${COMMA_LATIN} `,
|
|
30
40
|
vowels: true,
|
|
31
41
|
},
|
|
@@ -33,6 +43,10 @@ export const LOCALE_FEATURES: Record<Locale, LocaleFeatures> = {
|
|
|
33
43
|
comma: COMMA_LATIN,
|
|
34
44
|
consonants: true,
|
|
35
45
|
direction: 'ltr',
|
|
46
|
+
Icon: FlagUs,
|
|
47
|
+
label: 'English (US)',
|
|
48
|
+
locale: Locale.EN_US,
|
|
49
|
+
name: 'English (US)',
|
|
36
50
|
separator: `${COMMA_LATIN} `,
|
|
37
51
|
vowels: true,
|
|
38
52
|
},
|
|
@@ -40,6 +54,10 @@ export const LOCALE_FEATURES: Record<Locale, LocaleFeatures> = {
|
|
|
40
54
|
comma: COMMA_LATIN,
|
|
41
55
|
consonants: true,
|
|
42
56
|
direction: 'ltr',
|
|
57
|
+
Icon: FlagEs,
|
|
58
|
+
label: 'Español',
|
|
59
|
+
locale: Locale.ES_ES,
|
|
60
|
+
name: 'Spanish',
|
|
43
61
|
separator: `${COMMA_LATIN} `,
|
|
44
62
|
vowels: true,
|
|
45
63
|
},
|
|
@@ -47,6 +65,10 @@ export const LOCALE_FEATURES: Record<Locale, LocaleFeatures> = {
|
|
|
47
65
|
comma: COMMA_ARABIC,
|
|
48
66
|
consonants: false,
|
|
49
67
|
direction: 'rtl',
|
|
68
|
+
Icon: FlagFa,
|
|
69
|
+
label: 'فارسی',
|
|
70
|
+
locale: Locale.FA_IR,
|
|
71
|
+
name: 'Persian',
|
|
50
72
|
separator: `${COMMA_ARABIC} `,
|
|
51
73
|
vowels: false,
|
|
52
74
|
},
|
|
@@ -54,6 +76,10 @@ export const LOCALE_FEATURES: Record<Locale, LocaleFeatures> = {
|
|
|
54
76
|
comma: COMMA_LATIN,
|
|
55
77
|
consonants: true,
|
|
56
78
|
direction: 'ltr',
|
|
79
|
+
Icon: FlagFr,
|
|
80
|
+
label: 'Français',
|
|
81
|
+
locale: Locale.FR_FR,
|
|
82
|
+
name: 'French',
|
|
57
83
|
separator: `${COMMA_LATIN} `,
|
|
58
84
|
vowels: true,
|
|
59
85
|
},
|
|
@@ -61,67 +87,11 @@ export const LOCALE_FEATURES: Record<Locale, LocaleFeatures> = {
|
|
|
61
87
|
comma: COMMA_LATIN,
|
|
62
88
|
consonants: true,
|
|
63
89
|
direction: 'ltr',
|
|
64
|
-
separator: `${COMMA_LATIN} `,
|
|
65
|
-
vowels: true,
|
|
66
|
-
},
|
|
67
|
-
};
|
|
68
|
-
|
|
69
|
-
interface Flag {
|
|
70
|
-
className: string;
|
|
71
|
-
Icon: FunctionComponent<SVGAttributes<SVGElement>>;
|
|
72
|
-
label: string;
|
|
73
|
-
name: string;
|
|
74
|
-
value: Locale;
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
export const LOCALE_FLAGS: Record<Locale, Flag> = {
|
|
78
|
-
[Locale.DE_DE]: {
|
|
79
|
-
className: styles.de,
|
|
80
|
-
Icon: FlagDe,
|
|
81
|
-
label: 'Deutsch',
|
|
82
|
-
name: 'German',
|
|
83
|
-
value: Locale.DE_DE,
|
|
84
|
-
},
|
|
85
|
-
[Locale.EN_GB]: {
|
|
86
|
-
className: styles.gb,
|
|
87
|
-
Icon: FlagGb,
|
|
88
|
-
label: 'English (GB)',
|
|
89
|
-
name: 'English (GB)',
|
|
90
|
-
value: Locale.EN_GB,
|
|
91
|
-
},
|
|
92
|
-
[Locale.EN_US]: {
|
|
93
|
-
className: styles.us,
|
|
94
|
-
Icon: FlagUs,
|
|
95
|
-
label: 'English (US)',
|
|
96
|
-
name: 'English (US)',
|
|
97
|
-
value: Locale.EN_US,
|
|
98
|
-
},
|
|
99
|
-
[Locale.ES_ES]: {
|
|
100
|
-
className: styles.es,
|
|
101
|
-
Icon: FlagEs,
|
|
102
|
-
label: 'Español',
|
|
103
|
-
name: 'Spanish',
|
|
104
|
-
value: Locale.ES_ES,
|
|
105
|
-
},
|
|
106
|
-
[Locale.FA_IR]: {
|
|
107
|
-
className: styles.fa,
|
|
108
|
-
Icon: FlagFa,
|
|
109
|
-
label: 'فارسی',
|
|
110
|
-
name: 'Persian',
|
|
111
|
-
value: Locale.FA_IR,
|
|
112
|
-
},
|
|
113
|
-
[Locale.FR_FR]: {
|
|
114
|
-
className: styles.fr,
|
|
115
|
-
Icon: FlagFr,
|
|
116
|
-
label: 'Français',
|
|
117
|
-
name: 'French',
|
|
118
|
-
value: Locale.FR_FR,
|
|
119
|
-
},
|
|
120
|
-
[Locale.PL_PL]: {
|
|
121
|
-
className: styles.pl,
|
|
122
90
|
Icon: FlagPl,
|
|
123
91
|
label: 'Polski',
|
|
92
|
+
locale: Locale.PL_PL,
|
|
124
93
|
name: 'Polish',
|
|
125
|
-
|
|
94
|
+
separator: `${COMMA_LATIN} `,
|
|
95
|
+
vowels: true,
|
|
126
96
|
},
|
|
127
97
|
};
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { getConfig } from '@scrabble-solver/configs';
|
|
2
2
|
import { BLANK } from '@scrabble-solver/constants';
|
|
3
|
-
import { Locale } from '@scrabble-solver/types';
|
|
3
|
+
import { Game, Locale } from '@scrabble-solver/types';
|
|
4
4
|
|
|
5
5
|
import extractCharacters from './extractCharacters';
|
|
6
6
|
|
|
@@ -16,7 +16,7 @@ const tests = [
|
|
|
16
16
|
|
|
17
17
|
describe('extractCharacters', () => {
|
|
18
18
|
const locale = Locale.ES_ES;
|
|
19
|
-
const config =
|
|
19
|
+
const config = getConfig(Game.Scrabble, locale);
|
|
20
20
|
|
|
21
21
|
for (const { input, expected } of tests) {
|
|
22
22
|
it(`[${locale}] "${input}"`, () => {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { getConfig } from '@scrabble-solver/configs';
|
|
2
2
|
import { BLANK } from '@scrabble-solver/constants';
|
|
3
|
-
import { Locale } from '@scrabble-solver/types';
|
|
3
|
+
import { Game, Locale } from '@scrabble-solver/types';
|
|
4
4
|
|
|
5
5
|
import extractCharactersByCase from './extractCharactersByCase';
|
|
6
6
|
|
|
@@ -21,7 +21,7 @@ const tests = [
|
|
|
21
21
|
|
|
22
22
|
describe('extractCharactersByCase', () => {
|
|
23
23
|
const locale = Locale.ES_ES;
|
|
24
|
-
const config =
|
|
24
|
+
const config = getConfig(Game.Scrabble, locale);
|
|
25
25
|
|
|
26
26
|
for (const { input, expected } of tests) {
|
|
27
27
|
it(`[${locale}] "${input}"`, () => {
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import { Config } from '@scrabble-solver/types';
|
|
2
2
|
|
|
3
|
-
import { BOARD_CELL_BORDER_WIDTH, BOARD_TILE_SIZE_MAX
|
|
3
|
+
import { BOARD_CELL_BORDER_WIDTH, BOARD_TILE_SIZE_MAX } from 'parameters';
|
|
4
4
|
|
|
5
5
|
const getCellSize = (config: Config, width: number, height: number): number => {
|
|
6
6
|
const maxWidth = (width - BOARD_CELL_BORDER_WIDTH) / config.boardWidth - BOARD_CELL_BORDER_WIDTH;
|
|
7
7
|
const maxHeight = (height - BOARD_CELL_BORDER_WIDTH) / config.boardHeight - BOARD_CELL_BORDER_WIDTH;
|
|
8
8
|
const cellSize = Math.min(maxWidth, maxHeight);
|
|
9
|
-
return Math.floor(Math.min(
|
|
9
|
+
return Math.floor(Math.min(cellSize, BOARD_TILE_SIZE_MAX));
|
|
10
10
|
};
|
|
11
11
|
|
|
12
12
|
export default getCellSize;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { FunctionComponent, memo } from 'react';
|
|
2
2
|
|
|
3
3
|
import { Button, Modal } from 'components';
|
|
4
|
-
import {
|
|
4
|
+
import { LOCALE_FEATURES } from 'i18n';
|
|
5
5
|
import { BookHalf, CardChecklist, Cog, Github, Sack } from 'icons';
|
|
6
6
|
import { GITHUB_PROJECT_URL } from 'parameters';
|
|
7
7
|
import { selectLocale, useTranslate, useTypedSelector } from 'state';
|
|
@@ -29,7 +29,7 @@ const MenuModal: FunctionComponent<Props> = ({
|
|
|
29
29
|
}) => {
|
|
30
30
|
const translate = useTranslate();
|
|
31
31
|
const locale = useTypedSelector(selectLocale);
|
|
32
|
-
const
|
|
32
|
+
const { Icon } = LOCALE_FEATURES[locale];
|
|
33
33
|
|
|
34
34
|
return (
|
|
35
35
|
<Modal className={className} isOpen={isOpen} title={translate('menu')} onClose={onClose}>
|
|
@@ -64,7 +64,7 @@ const MenuModal: FunctionComponent<Props> = ({
|
|
|
64
64
|
<Button aria-label={translate('settings')} className={styles.button} Icon={Cog} onClick={onShowSettings}>
|
|
65
65
|
<div className={styles.settings}>
|
|
66
66
|
<div className={styles.settingsLabel}>{translate('settings')}</div>
|
|
67
|
-
<
|
|
67
|
+
<Icon className={styles.flag} />
|
|
68
68
|
</div>
|
|
69
69
|
</Button>
|
|
70
70
|
</Modal>
|
package/packages/scrabble-solver/src/modals/SettingsModal/components/ConfigSetting/ConfigSetting.tsx
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
|
+
import { games, hasConfig } from '@scrabble-solver/configs';
|
|
2
|
+
import { isGame } from '@scrabble-solver/types';
|
|
1
3
|
import { ChangeEvent, FunctionComponent } from 'react';
|
|
2
4
|
import { useDispatch } from 'react-redux';
|
|
3
5
|
|
|
4
6
|
import { Radio } from 'components';
|
|
5
|
-
import {
|
|
7
|
+
import { selectGame, selectLocale, settingsSlice, useTypedSelector } from 'state';
|
|
6
8
|
|
|
7
9
|
import styles from './ConfigSetting.module.scss';
|
|
8
|
-
import options from './options';
|
|
9
10
|
|
|
10
11
|
interface Props {
|
|
11
12
|
className?: string;
|
|
@@ -14,21 +15,29 @@ interface Props {
|
|
|
14
15
|
|
|
15
16
|
const ConfigSetting: FunctionComponent<Props> = ({ className, disabled }) => {
|
|
16
17
|
const dispatch = useDispatch();
|
|
17
|
-
const
|
|
18
|
+
const game = useTypedSelector(selectGame);
|
|
19
|
+
const locale = useTypedSelector(selectLocale);
|
|
20
|
+
const options = Object.values(games).map((gameConfig) => ({
|
|
21
|
+
disabled: !hasConfig(gameConfig.game, locale),
|
|
22
|
+
label: gameConfig.name,
|
|
23
|
+
value: gameConfig.game,
|
|
24
|
+
}));
|
|
18
25
|
|
|
19
26
|
const handleChange = (event: ChangeEvent<HTMLInputElement>) => {
|
|
20
|
-
|
|
27
|
+
if (isGame(event.target.value)) {
|
|
28
|
+
dispatch(settingsSlice.actions.changeGame(event.target.value));
|
|
29
|
+
}
|
|
21
30
|
};
|
|
22
31
|
|
|
23
32
|
return (
|
|
24
33
|
<div className={className}>
|
|
25
34
|
{options.map((option) => (
|
|
26
35
|
<Radio
|
|
27
|
-
checked={
|
|
36
|
+
checked={game === option.value}
|
|
28
37
|
className={styles.option}
|
|
29
|
-
disabled={disabled}
|
|
38
|
+
disabled={disabled || option.disabled}
|
|
30
39
|
key={option.value}
|
|
31
|
-
name="
|
|
40
|
+
name="game"
|
|
32
41
|
value={option.value}
|
|
33
42
|
onChange={handleChange}
|
|
34
43
|
>
|
package/packages/scrabble-solver/src/modals/SettingsModal/components/LocaleSetting/LocaleSetting.tsx
CHANGED
|
@@ -4,7 +4,7 @@ import { ChangeEvent, FunctionComponent } from 'react';
|
|
|
4
4
|
import { useDispatch } from 'react-redux';
|
|
5
5
|
|
|
6
6
|
import { Radio } from 'components';
|
|
7
|
-
import {
|
|
7
|
+
import { LOCALE_FEATURES } from 'i18n';
|
|
8
8
|
import { selectLocale, settingsSlice, useTypedSelector } from 'state';
|
|
9
9
|
|
|
10
10
|
import styles from './LocaleSetting.module.scss';
|
|
@@ -14,7 +14,7 @@ interface Props {
|
|
|
14
14
|
disabled: boolean;
|
|
15
15
|
}
|
|
16
16
|
|
|
17
|
-
const OPTIONS = Object.values(
|
|
17
|
+
const OPTIONS = Object.values(LOCALE_FEATURES).sort((a, b) => a.name.localeCompare(b.name));
|
|
18
18
|
|
|
19
19
|
const LocaleSetting: FunctionComponent<Props> = ({ className, disabled }) => {
|
|
20
20
|
const dispatch = useDispatch();
|
|
@@ -29,18 +29,18 @@ const LocaleSetting: FunctionComponent<Props> = ({ className, disabled }) => {
|
|
|
29
29
|
<div className={className}>
|
|
30
30
|
{OPTIONS.map(({ Icon, ...option }) => (
|
|
31
31
|
<Radio
|
|
32
|
-
checked={locale === option.
|
|
32
|
+
checked={locale === option.locale}
|
|
33
33
|
className={classNames(styles.option, className, {
|
|
34
|
-
[styles.checked]: locale === option.
|
|
34
|
+
[styles.checked]: locale === option.locale,
|
|
35
35
|
})}
|
|
36
36
|
disabled={disabled}
|
|
37
|
-
key={option.
|
|
37
|
+
key={option.locale}
|
|
38
38
|
name="locale"
|
|
39
|
-
value={option.
|
|
39
|
+
value={option.locale}
|
|
40
40
|
onChange={handleChange}
|
|
41
41
|
>
|
|
42
|
-
<span className={
|
|
43
|
-
<Icon className={
|
|
42
|
+
<span className={styles.label}>
|
|
43
|
+
<Icon className={styles.flag} />
|
|
44
44
|
|
|
45
45
|
<span>{option.label}</span>
|
|
46
46
|
</span>
|
|
@@ -10,12 +10,14 @@ import 'styles/global.scss';
|
|
|
10
10
|
|
|
11
11
|
const DESCRIPTION =
|
|
12
12
|
// eslint-disable-next-line max-len
|
|
13
|
-
'Scrabble Solver 2 - Free and open-source analysis tool for Scrabble
|
|
13
|
+
'Scrabble Solver 2 - Free and open-source analysis tool for Scrabble, Super Scrabble & Literaki. Quickly find top scoring words using given letters and board state. Available in English, French, German, Polish & Spanish.';
|
|
14
14
|
|
|
15
15
|
const KEYWORDS = [
|
|
16
16
|
'Scrabble Solver',
|
|
17
17
|
'Scrabble',
|
|
18
18
|
'Solver',
|
|
19
|
+
'Super Scrabble',
|
|
20
|
+
'Super Scrabble Solver',
|
|
19
21
|
'Board',
|
|
20
22
|
'Open-source',
|
|
21
23
|
'Open',
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { games } from '@scrabble-solver/configs';
|
|
2
2
|
import { COMMA_ARABIC, COMMA_LATIN } from '@scrabble-solver/constants';
|
|
3
3
|
import { dictionaries } from '@scrabble-solver/dictionaries';
|
|
4
4
|
import logger from '@scrabble-solver/logger';
|
|
5
|
-
import {
|
|
5
|
+
import { Locale, isLocale } from '@scrabble-solver/types';
|
|
6
6
|
import { getWordDefinition } from '@scrabble-solver/word-definitions';
|
|
7
7
|
import { NextApiRequest, NextApiResponse } from 'next';
|
|
8
8
|
|
|
@@ -13,7 +13,10 @@ interface RequestData {
|
|
|
13
13
|
words: string[];
|
|
14
14
|
}
|
|
15
15
|
|
|
16
|
-
const MAXIMUM_COLLISIONS_COUNT =
|
|
16
|
+
const MAXIMUM_COLLISIONS_COUNT = Object.values(games).reduce(
|
|
17
|
+
(result, game) => Math.max(result, game.maximumCharactersCount),
|
|
18
|
+
0,
|
|
19
|
+
);
|
|
17
20
|
const MAXIMUM_WORDS_COUNT = MAXIMUM_COLLISIONS_COUNT + 1;
|
|
18
21
|
|
|
19
22
|
const dictionary = async (request: NextApiRequest, response: NextApiResponse): Promise<void> => {
|