Compare commits
271 Commits
v0.3.14
...
v0.4.0-alp
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
53ab0a3fa0 | ||
|
|
aeeff67d2e | ||
|
|
4343703eb3 | ||
|
|
5f09bdbce2 | ||
|
|
3a3e3625f2 | ||
|
|
bdf14c1997 | ||
|
|
d6e064ae00 | ||
|
|
1012094568 | ||
|
|
4117537ff2 | ||
|
|
2a72cb70d6 | ||
|
|
b1cd9d9389 | ||
|
|
568dfc973d | ||
|
|
2e74cec0db | ||
|
|
db378159d6 | ||
|
|
50ff2d8f1b | ||
|
|
061495fb27 | ||
|
|
40cb59ddfd | ||
|
|
38affddc9e | ||
|
|
17dcb90473 | ||
|
|
772402b46f | ||
|
|
29bd8a289c | ||
|
|
79d9e73608 | ||
|
|
b04f8d75f3 | ||
|
|
32b1d123d2 | ||
|
|
b576cafaa4 | ||
|
|
312ef93ffc | ||
|
|
a1dda0c247 | ||
|
|
0c36b96922 | ||
|
|
07e92f052b | ||
|
|
244c834de9 | ||
|
|
61b5c2cffd | ||
|
|
1441bd63cb | ||
|
|
e7d0db0fc0 | ||
|
|
a87d340b25 | ||
|
|
3f0d90cb7c | ||
|
|
b9e9f9b122 | ||
|
|
f2d1cf3baf | ||
|
|
cf1112327a | ||
|
|
c2cb28668d | ||
|
|
75f4fcb91a | ||
|
|
3d92bd0584 | ||
|
|
52ca98a14d | ||
|
|
629a73a5cf | ||
|
|
077ec43855 | ||
|
|
3ecd3618cb | ||
|
|
38bc34913b | ||
|
|
c733e5ceea | ||
|
|
e2536ceb92 | ||
|
|
c17b6f073d | ||
|
|
936b177776 | ||
|
|
7d8036fe69 | ||
|
|
6d08d1a265 | ||
|
|
48aba1c055 | ||
|
|
0b3d3317bf | ||
|
|
d1fbdc581b | ||
|
|
044170eb4b | ||
|
|
a7c16b3ceb | ||
|
|
dd12be2275 | ||
|
|
1049bc543a | ||
|
|
5c5ad3cd32 | ||
|
|
6fce521122 | ||
|
|
2af9941ea6 | ||
|
|
9b24f742d1 | ||
|
|
b36bcf7733 | ||
|
|
9559dbdcd6 | ||
|
|
668dd4b5bf | ||
|
|
b98feab9c4 | ||
|
|
5f4711ac3e | ||
|
|
4a931cbdc0 | ||
|
|
90b2ddbdf2 | ||
|
|
3d6cacc753 | ||
|
|
3aed315dfc | ||
|
|
06233cca8c | ||
|
|
3da0ab260a | ||
|
|
5d47159151 | ||
|
|
7e92a7382e | ||
|
|
e69dcd87df | ||
|
|
fb9589f642 | ||
|
|
b034075437 | ||
|
|
cd10906811 | ||
|
|
a1e0bd9a0e | ||
|
|
2dd70db4c2 | ||
|
|
fc835cd1ab | ||
|
|
5d88058354 | ||
|
|
cda111f623 | ||
|
|
fc5ea6204d | ||
|
|
70ba72bf8b | ||
|
|
c9f84a5a32 | ||
|
|
10f53d1bd9 | ||
|
|
7624aac935 | ||
|
|
06ffb89198 | ||
|
|
d48ce5ad94 | ||
|
|
5c1dd57802 | ||
|
|
1f4133676a | ||
|
|
f83d40d137 | ||
|
|
0999cb7b86 | ||
|
|
c58d6311e1 | ||
|
|
8c9016d7e3 | ||
|
|
072d768ef6 | ||
|
|
7eabe77358 | ||
|
|
e4df74bbae | ||
|
|
80f7d50770 | ||
|
|
31d901ba1c | ||
|
|
4e2a43a6cd | ||
|
|
0408d437e1 | ||
|
|
5a6c36d421 | ||
|
|
5fc07f9ae3 | ||
|
|
91cbe6d8ec | ||
|
|
c2aa87beab | ||
|
|
0094699a88 | ||
|
|
4adaf9a315 | ||
|
|
01eee827df | ||
|
|
fd87241887 | ||
|
|
d63792cb15 | ||
|
|
e2c4992b51 | ||
|
|
481d929f2b | ||
|
|
3d1f1d1e12 | ||
|
|
9f4ef7e1ad | ||
|
|
7d24f0c5ae | ||
|
|
67408130b1 | ||
|
|
cdb9504e5f | ||
|
|
977b32de6e | ||
|
|
4ae4eb00e9 | ||
|
|
063fca6dd1 | ||
|
|
a650bfe94c | ||
|
|
517448da06 | ||
|
|
8ba9abdace | ||
|
|
193d03e0eb | ||
|
|
363cfe1443 | ||
|
|
d9cd36966e | ||
|
|
02bfae55b9 | ||
|
|
6edbf64104 | ||
|
|
1c29319036 | ||
|
|
8c8664cafa | ||
|
|
652c7f4e4b | ||
|
|
753fbc30df | ||
|
|
01de9a4ae1 | ||
|
|
aa52784174 | ||
|
|
dc72e2162e | ||
|
|
8ef37cedfb | ||
|
|
08a77ce0eb | ||
|
|
afc6f21a6a | ||
|
|
bdc2a9a5d3 | ||
|
|
c27365bccd | ||
|
|
83d4fc727d | ||
|
|
5bf4819d83 | ||
|
|
60221743f6 | ||
|
|
9d78661ecb | ||
|
|
addedb6f9b | ||
|
|
e1701b2ba7 | ||
|
|
380a0e4f4c | ||
|
|
7fb24c0471 | ||
|
|
aaae483ad8 | ||
|
|
578652b9ba | ||
|
|
b8133b17fe | ||
|
|
8226a4fcb9 | ||
|
|
ea85a63da9 | ||
|
|
21e784fb09 | ||
|
|
0a1fb5a51e | ||
|
|
2a3c3e07e2 | ||
|
|
f8eb86806e | ||
|
|
25a7c47c3c | ||
|
|
f08d92fef4 | ||
|
|
362a84de51 | ||
|
|
64fefef31a | ||
|
|
b0fced6f98 | ||
|
|
406f79ee36 | ||
|
|
893fc758b1 | ||
|
|
126de62f80 | ||
|
|
0ee634a83d | ||
|
|
d4f634e8af | ||
|
|
f544e1203d | ||
|
|
d0a373f5f4 | ||
|
|
e4dfed3940 | ||
|
|
7f674f89d2 | ||
|
|
0d593a07e6 | ||
|
|
261c8fbec1 | ||
|
|
d5262e3ad2 | ||
|
|
527543331a | ||
|
|
75623f2a95 | ||
|
|
29f6658256 | ||
|
|
dbc6606237 | ||
|
|
1108456a8e | ||
|
|
2debf36cb6 | ||
|
|
896101b840 | ||
|
|
a84854a5b1 | ||
|
|
461966de96 | ||
|
|
6dd3713641 | ||
|
|
d51b301364 | ||
|
|
f8db5d3881 | ||
|
|
781a00e7c2 | ||
|
|
a1bb73ba9d | ||
|
|
d6390108c2 | ||
|
|
fee954c95f | ||
|
|
0347eabc04 | ||
|
|
c6bcd8a89c | ||
|
|
114bcb0d4b | ||
|
|
f4a1a04997 | ||
|
|
70a859e00b | ||
|
|
8d3b2ef474 | ||
|
|
76efc0a0e0 | ||
|
|
166734757f | ||
|
|
97f401371f | ||
|
|
b012e5377b | ||
|
|
3b18dc33d8 | ||
|
|
d798f01576 | ||
|
|
55281bd7d6 | ||
|
|
88e9bde0a9 | ||
|
|
54d5a16761 | ||
|
|
701da50479 | ||
|
|
b43b6aa2d0 | ||
|
|
4279e9d100 | ||
|
|
e5bd979880 | ||
|
|
9a48169bf3 | ||
|
|
99cfd99815 | ||
|
|
e8f082d885 | ||
|
|
b63f475a8c | ||
|
|
e183f10969 | ||
|
|
c1e624b9a0 | ||
|
|
2d87d0e4d3 | ||
|
|
bcf1bffc24 | ||
|
|
f388e8811e | ||
|
|
7ededa6293 | ||
|
|
7d9e1cf2b5 | ||
|
|
299f581609 | ||
|
|
c38d4ed90b | ||
|
|
647bc659d7 | ||
|
|
61eb09e611 | ||
|
|
1a4118d29a | ||
|
|
48655b3771 | ||
|
|
17649c44bf | ||
|
|
7cbb19ddcb | ||
|
|
e13ac7c689 | ||
|
|
941733cdc0 | ||
|
|
a25289a856 | ||
|
|
7bcfeca872 | ||
|
|
240ebc499a | ||
|
|
831882f419 | ||
|
|
e0e5259b4c | ||
|
|
33cd2b5d01 | ||
|
|
d3dda86966 | ||
|
|
59aa5cdb33 | ||
|
|
d26e820492 | ||
|
|
b8b1b04c7e | ||
|
|
26b4acc894 | ||
|
|
12c4220544 | ||
|
|
5fc4f5ba60 | ||
|
|
03ea9bcb76 | ||
|
|
a04c44df98 | ||
|
|
b1431c7e51 | ||
|
|
c09719ffd6 | ||
|
|
16149d95a1 | ||
|
|
658e43da9c | ||
|
|
66ddb451ab | ||
|
|
f135513f3e | ||
|
|
322dfa717b | ||
|
|
bfe7852bdf | ||
|
|
45fe2f311e | ||
|
|
f73daa2b00 | ||
|
|
4e8ff9ec14 | ||
|
|
a96fc84fc1 | ||
|
|
e62ddc37dd | ||
|
|
06cfa34a4b | ||
|
|
ef849dfefd | ||
|
|
091d43520e | ||
|
|
95b6b1bbf9 | ||
|
|
021014e870 | ||
|
|
aaa4fbae7a | ||
|
|
78b645d820 | ||
|
|
61bd6752e3 | ||
|
|
e4e10f5c72 |
1
.github/FUNDING.yml
vendored
1
.github/FUNDING.yml
vendored
@@ -1,2 +1,3 @@
|
||||
github: [patrickgold]
|
||||
liberapay: patrickgold
|
||||
custom: ["https://paypal.me/devpatrickgold"]
|
||||
|
||||
BIN
.github/repo_icon.png
vendored
Normal file
BIN
.github/repo_icon.png
vendored
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 55 KiB |
8
.github/workflows/android.yml
vendored
8
.github/workflows/android.yml
vendored
@@ -29,14 +29,6 @@ jobs:
|
||||
java-version: 11
|
||||
- name: Setup CMake and Ninja
|
||||
uses: lukka/get-cmake@v3.20.1
|
||||
- uses: actions/cache@v2
|
||||
with:
|
||||
path: |
|
||||
~/.gradle/caches
|
||||
~/.gradle/wrapper
|
||||
key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle*') }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-gradle-
|
||||
- name: Build with Gradle
|
||||
# MUST call gradlew separately because of an OSS license plugin issue.
|
||||
# See https://github.com/google/play-services-plugins/issues/199
|
||||
|
||||
3
.gitignore
vendored
3
.gitignore
vendored
@@ -43,6 +43,3 @@ crowdin.properties
|
||||
|
||||
# C++
|
||||
.cxx/
|
||||
|
||||
# AndroidX Room schema JSONs
|
||||
/app/schemas/
|
||||
|
||||
@@ -64,7 +64,7 @@ For the `code` field of each key, make sure to use the UTF-8 code. An useful too
|
||||
is [unicode-table.com](https://unicode-table.com/en/). From there, you search for your letter and then use the HTML
|
||||
code, but without the `&#;`
|
||||
For internal codes of functional or UI keys, see
|
||||
[`app/src/main/java/dev/patrickgold/florisboard/ime/text/key/KeyCode.kt`](app/src/main/java/dev/patrickgold/florisboard/ime/text/key/KeyCode.kt)
|
||||
[`app/src/main/kotlin/dev/patrickgold/florisboard/ime/text/key/KeyCode.kt`](app/src/main/kotlin/dev/patrickgold/florisboard/ime/text/key/KeyCode.kt)
|
||||
.
|
||||
|
||||
The label is equally important and should always match up with the defined code. If `code` and `label` don't match up,
|
||||
|
||||
11
README.md
11
README.md
@@ -1,9 +1,9 @@
|
||||
<img align="left" width="80" height="80"
|
||||
src="fastlane/metadata/android/en-US/images/icon.png" alt="App icon">
|
||||
src=".github/repo_icon.png" alt="App icon">
|
||||
|
||||
# FlorisBoard [](https://crowdin.florisboard.patrickgold.dev) [](https://matrix.to/#/#florisboard:matrix.org) 
|
||||
|
||||
**FlorisBoard** is a free and open-source keyboard for Android 6.0+
|
||||
**FlorisBoard** is a free and open-source keyboard for Android 7.0+
|
||||
devices. It aims at being modern, user-friendly and customizable while
|
||||
fully respecting your privacy. Currently in early-beta state.
|
||||
|
||||
@@ -54,7 +54,8 @@ fully respecting your privacy. Currently in early-beta state.
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
Beginning with v0.4.0 FlorisBoard will follow [SemVer](https://semver.org/#summary) versioning scheme and enter the public beta on Google Play.
|
||||
Beginning with v0.4.0 FlorisBoard will follow [SemVer](https://semver.org/#summary) versioning scheme.
|
||||
Beginning with v0.5.0 FlorisBoard will enter the public beta on Google Play.
|
||||
|
||||
## Highlighted features
|
||||
- Integrated clipboard manager / history
|
||||
@@ -84,6 +85,8 @@ to get more information on this topic.
|
||||
[Android Jetpack](https://github.com/androidx)
|
||||
* [Accompanist Compose UI libraries](https://github.com/google/accompanist/) by
|
||||
[Google](https://github.com/google)
|
||||
* [AboutLibraries](https://github.com/mikepenz/AboutLibraries) by
|
||||
[mikepenz](https://github.com/mikepenz)
|
||||
* [Google Material icons](https://github.com/google/material-design-icons) by
|
||||
[Google](https://github.com/google)
|
||||
* [JetPref preference library](https://github.com/patrickgold/jetpref) by
|
||||
@@ -97,6 +100,8 @@ to get more information on this topic.
|
||||
* [Nuspell](https://github.com/nuspell/nuspell) by
|
||||
[Nuspell](https://github.com/nuspell)
|
||||
|
||||
Many thanks to [Nikolay Anzarov](https://www.behance.net/nikolayanzarov) ([@BloodRaven0](https://github.com/BloodRaven0)) for designing and providing the main app icons to this project!
|
||||
|
||||
## License
|
||||
```
|
||||
Copyright 2020-2022 Patrick Goldinger
|
||||
|
||||
125
ROADMAP.md
125
ROADMAP.md
@@ -8,64 +8,83 @@ out a bit on the stable track. If you are interested in following the developmen
|
||||
along the beta track releases! These are generally more unstable but you get new stuff faster and can provide early
|
||||
feedback, which helps a lot!
|
||||
|
||||
## 0.3.x
|
||||
## 0.4
|
||||
|
||||
Releases in this section still follow the old versioning scheme, meaning the patch number is a feature upgrade. As this
|
||||
naming convention is more confusing than useful, beginning with v0.4.0 development a new release/development cycle will
|
||||
be introduced.
|
||||
Major release which mainly focuses on adding proper word suggestions and inline autocorrect (for Latin-based languages
|
||||
only at first). This is a big effort which will take some time to be fully completed. Additionally general small bug
|
||||
fixes and improvements will be made alongside the development of the main objective.
|
||||
|
||||
### 0.3.14 (almost completed, release candidate phase)
|
||||
With this release the versioning scheme changes to `0.x.y`, where `x` specifies the major changes, and `y` are just
|
||||
small bug fixes and improvements for the former major stable release `x`. This is different to `0.3.x`, where the
|
||||
version scheme just did not make any sense anymore, especially with the latest `0.3.x` releases. As for the beta track,
|
||||
major developments (`0.x`) will have alpha, beta and release candidate releases on the beta track before it goes live on
|
||||
the stable track. Small follow-up bug fixes (`0.x.y`) will be published on both the stable and beta track without
|
||||
release candidates.
|
||||
|
||||
- Re-write of the Preference core
|
||||
- Reduce redundancy in key/default value definitions
|
||||
- Avoid having to manually add redundant code for adding a new pref
|
||||
- Goes hand-in-hand with the Settings UI re-write
|
||||
- Re-write of the Settings UI with Jetpack Compose
|
||||
- Also re-structure UI into a more list-like panel
|
||||
- Adjust theme colors of Settings a bit to make it more modern
|
||||
- Preview the keyboard at any time from within the Settings
|
||||
- Settings language different than device language
|
||||
- Re-write the Setup UI in Jetpack Compose
|
||||
- Simplify screen based on previously discussed ideas and mock-ups
|
||||
- Improve backend setup logic
|
||||
- Implement base-UI for extensions and further continue development of existing Flex (FlorisBoard extension) format
|
||||
- Allows for a continuous experience of customizing FlorisBoard in different areas
|
||||
- Planned what will use Flex:
|
||||
- Themes
|
||||
- Layouts (Characters, symbols, numeric, ...)
|
||||
- Composers for non-Latin script languages
|
||||
- Word suggestion dictionaries (in 0.4.0)
|
||||
- Spell check dictionaries
|
||||
- User dictionaries (not in 0.3.14)
|
||||
- Other features that require only data and no logic (not in 0.3.14)
|
||||
- Maybe full backup of preferences? Not 100% confirmed though and may be pushed back
|
||||
- Theme rework part I:
|
||||
- Custom key corner radius
|
||||
- Custom key border color (not shadow!!)
|
||||
- Re-work theme internals so they use Flex extension format and FlexCSS
|
||||
- Improvement of the Smartbar
|
||||
- Allow to have multiple Smartbars
|
||||
- Better candidate view (in prep for 0.4.0)
|
||||
### Word suggestions / Autocorrect
|
||||
|
||||
### 0.3.15 & 0.3.16
|
||||
The development effort of this feature is quite big, thus it is split into multiple phases:
|
||||
|
||||
- Hotfix releases for possible bugs in the preference rework, may be skipped.
|
||||
**Phase 1: Preparations of suggestions UI & interfacing API (first alpha release(s))**
|
||||
|
||||
## 0.4.0
|
||||
- Rework Smartbar suggestions UI
|
||||
- Allow for primary and optionally secondary label (in a smaller font) to be shown per suggestion
|
||||
- Better integrate clipboard suggestions into word suggestion flow
|
||||
- Add long-press suggestion action for user to prevent from showing again
|
||||
- Generally fix and polish suggestions UI design (3-column mode and scrollable mode)
|
||||
- Add a `SuggestionProvider` interface API to allow for any specialized implementation to be written
|
||||
- A provider's main task is to receive updates on the current state of the editor (except for raw inputs) and
|
||||
provide both current word autocorrect/suggestions or next word suggestions if there is no current word
|
||||
- The provider can utilize the basic APK asset and file APIs for reading dictionary files, however there is no
|
||||
standardization in parsing as different languages may require different dictionary structures and thus have
|
||||
different requirements
|
||||
- Document API and add dummy implementation to test API
|
||||
- Try to add toggle for not underlining the current word (composing region) while not loosing the caching benefits
|
||||
- In parallel: Do local research and preps for phase 2
|
||||
|
||||
- Re-adding word suggestions (at least for Latin-based languages at first)
|
||||
- Importing the dictionaries as well as management relies on the Flex extension core and UI in Kotlin
|
||||
- Actually parsing and generating suggestions happens in C++ to avoid another OOM catastrophe like in 0.3.9/10
|
||||
- The actual format of the dictionary and word list source is not decided yet
|
||||
- Community repository on GitHub for theme sharing across users (may be 0.5.0)
|
||||
_[Anomaly](https://www.anomaly.ltd/), an Australian software company, will sponsor this project with 1000€ so this phase
|
||||
gets implemented first, as they want to use FlorisBoard as a base for
|
||||
their [WCC Language Program project (Gurray)](https://www.anomaly.ltd/portfolio/wcc/gurray/). As this fits in perfectly
|
||||
with the current dev cycle and this had to be done anyways (some parts like documenting and UI polishing just later in
|
||||
the 0.4 milestone), I have accepted this. However in general this does not mean this project accepts sponsoring for any
|
||||
feature to be prioritized, as the project's main goals and planned feature timeline must always come first and human dev
|
||||
resources are limited._
|
||||
|
||||
With this release the versioning scheme changes: the second number now indicates new features, changes in the third "
|
||||
patch" number now indicates bug fixes and minor feature additions for the stable track. The development cycle for each
|
||||
0.x release will have `-alphaXX`, `-betaXX` and `-rcXX` (release candidate) releases on the beta track for interested
|
||||
people to follow along the development. The first release to follow the new scheme will be `0.4.0-alpha01` on the beta
|
||||
track.
|
||||
**Phase 2: Add native (C++) Latin word suggestion core (alpha releases)**
|
||||
|
||||
## 0.5.0
|
||||
- Research and experiment with different approaches/data sources for Latin-based language prediction and autocorrect
|
||||
- Research will mainly be done first locally on Linux to decide what to use
|
||||
- Implementation will be in C++ using STL libraries and if needed other open-source libraries, with compatibility
|
||||
and CPU/memory restrictions on Android devices in mind
|
||||
- Once an experiment runs well locally it will be included in the main project and tested out within the keyboard UI
|
||||
in different alpha releases
|
||||
- Especially at the beginning an idea may be scrapped and replaced by something else if found that another approach
|
||||
is better
|
||||
- (Based on research) Introduce new dictionary/language model format
|
||||
- Importing the dictionaries/models as well as management relies on the Flex extension core and UI in Kotlin
|
||||
- Actually parsing and generating suggestions happens in C++
|
||||
- The actual format of the dictionary/model source is not decided yet
|
||||
- Add system in preprocessing stage to properly mark slightly offensive words and prevent extremely offensive words
|
||||
from being included at all
|
||||
- Add system in preprocessing stage to filter out email addresses and phone numbers that may be included in the
|
||||
large datasets which are used for building the models
|
||||
|
||||
**Phase 3: Add support for more languages & Allow glide typing to utilize new word prediction system (beta releases)**
|
||||
|
||||
- Glide typing: Utilize new prediction system and get rid of current English (US) json dictionary
|
||||
- Add support for more languages (Latin-based), may need to utilize datasets like Opensubtitles or Wikimedia, although
|
||||
those need extensive cleaning and are not as reliable
|
||||
- Focus on improving performance and stabilizing the Latin suggestion core
|
||||
- Possibly address some language-specific issues and ensure suggested word capitalization is correct
|
||||
- Finalize Settings and keyboard UI regarding word suggestions.
|
||||
|
||||
### Other planned features for 0.4
|
||||
|
||||
- General small fixes and improvements
|
||||
- Community repository on GitHub for extension sharing across users (may be 0.5.0 though)
|
||||
- Localized emoji suggestions (may be 0.5.0 though)
|
||||
|
||||
## 0.5
|
||||
|
||||
- Complete rework of the Emoji panel
|
||||
- Recently used / Emoji history (already implemented with 0.3.14)
|
||||
@@ -79,18 +98,16 @@ track.
|
||||
- Rework branding images and texts of FlorisBoard for the app stores
|
||||
- Focus on stability and experience improvements of the app and keyboard
|
||||
|
||||
## 0.6.0
|
||||
## Backlog
|
||||
|
||||
**Features that MAY be added (even in versions mentioned above) or dismissed altogether**
|
||||
|
||||
- Full on-board layout editor which allows users to create their own layouts without writing a JSON file
|
||||
- Import/Export of custom layout files packed in Flex extensions
|
||||
|
||||
## Backlog / Features that MAY be added, even in versions not mentioned above if the feature implementation fits perfectly with another feature
|
||||
|
||||
- Theme rework part II
|
||||
- Adaptive themes v2
|
||||
- Voice-to-text with Mozilla's open-source voice service
|
||||
- Text translation
|
||||
- Glide typing better word detection
|
||||
- Proximity-based key typo detection
|
||||
- Floating keyboard
|
||||
- Tablet mode / Optimizations for landscape input
|
||||
|
||||
@@ -1,14 +1,37 @@
|
||||
/*
|
||||
* Copyright (C) 2022 Patrick Goldinger
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
// Suppress needed until https://youtrack.jetbrains.com/issue/KTIJ-19369 is fixed
|
||||
@file:Suppress("DSL_SCOPE_VIOLATION")
|
||||
|
||||
import java.io.ByteArrayOutputStream
|
||||
import java.io.File
|
||||
|
||||
plugins {
|
||||
id("com.android.application")
|
||||
kotlin("android")
|
||||
kotlin("kapt")
|
||||
kotlin("plugin.serialization")
|
||||
id("com.google.android.gms.oss-licenses-plugin")
|
||||
id("de.mannodermaus.android-junit5")
|
||||
alias(libs.plugins.agp.application)
|
||||
alias(libs.plugins.kotlin.android)
|
||||
alias(libs.plugins.kotlin.serialization)
|
||||
alias(libs.plugins.ksp)
|
||||
alias(libs.plugins.mannodermaus.android.junit5)
|
||||
alias(libs.plugins.mikepenz.aboutlibraries)
|
||||
}
|
||||
|
||||
android {
|
||||
compileSdk = 31
|
||||
namespace = "dev.patrickgold.florisboard"
|
||||
compileSdk = 32
|
||||
buildToolsVersion = "31.0.0"
|
||||
ndkVersion = "22.1.7171670"
|
||||
|
||||
@@ -18,32 +41,29 @@ android {
|
||||
}
|
||||
|
||||
kotlinOptions {
|
||||
jvmTarget = JavaVersion.VERSION_1_8.toString()
|
||||
jvmTarget = "1.8"
|
||||
freeCompilerArgs = listOf(
|
||||
"-Xallow-result-return-type",
|
||||
"-Xopt-in=kotlin.RequiresOptIn",
|
||||
"-Xopt-in=kotlin.contracts.ExperimentalContracts",
|
||||
"-Xjvm-default=compatibility",
|
||||
"-opt-in=kotlin.contracts.ExperimentalContracts",
|
||||
"-Xjvm-default=all-compatibility",
|
||||
)
|
||||
}
|
||||
|
||||
defaultConfig {
|
||||
applicationId = "dev.patrickgold.florisboard"
|
||||
minSdk = 23
|
||||
minSdk = 24
|
||||
targetSdk = 31
|
||||
versionCode = 75
|
||||
versionName = "0.3.14"
|
||||
versionCode = 88
|
||||
versionName = "0.4.0"
|
||||
|
||||
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
|
||||
|
||||
javaCompileOptions {
|
||||
annotationProcessorOptions {
|
||||
arguments += mapOf(
|
||||
Pair("room.schemaLocation", "$projectDir/schemas"),
|
||||
Pair("room.incremental", "true"),
|
||||
Pair("room.expandProjection", "true")
|
||||
)
|
||||
}
|
||||
buildConfigField("String", "BUILD_COMMIT_HASH", "\"${getGitCommitHash()}\"")
|
||||
|
||||
ksp {
|
||||
arg("room.schemaLocation", "$projectDir/schemas")
|
||||
arg("room.incremental", "true")
|
||||
arg("room.expandProjection", "true")
|
||||
}
|
||||
|
||||
externalNativeBuild {
|
||||
@@ -66,6 +86,9 @@ android {
|
||||
jniLibs {
|
||||
srcDirs("src/main/icu4c/prebuilt/jniLibs")
|
||||
}
|
||||
java {
|
||||
srcDirs("src/main/kotlin")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -84,7 +107,7 @@ android {
|
||||
}
|
||||
|
||||
composeOptions {
|
||||
kotlinCompilerExtensionVersion = "1.1.1"
|
||||
kotlinCompilerExtensionVersion = libs.versions.androidx.compose.compiler.get()
|
||||
}
|
||||
|
||||
externalNativeBuild {
|
||||
@@ -94,9 +117,9 @@ android {
|
||||
}
|
||||
|
||||
buildTypes {
|
||||
named("debug").configure {
|
||||
named("debug") {
|
||||
applicationIdSuffix = ".debug"
|
||||
versionNameSuffix = "-debug"
|
||||
versionNameSuffix = "-debug-${getGitCommitHash(short = true)}"
|
||||
|
||||
isDebuggable = true
|
||||
isJniDebuggable = false
|
||||
@@ -112,11 +135,13 @@ android {
|
||||
resValue("string", "floris_app_name", "FlorisBoard Debug")
|
||||
}
|
||||
|
||||
create("beta") // Needed because by default the "beta" BuildType does not exist
|
||||
named("beta").configure {
|
||||
create("beta") {
|
||||
applicationIdSuffix = ".beta"
|
||||
versionNameSuffix = ""
|
||||
proguardFiles.add(getDefaultProguardFile("proguard-android-optimize.txt"))
|
||||
versionNameSuffix = "-alpha02"
|
||||
|
||||
proguardFiles(getDefaultProguardFile("proguard-android-optimize.txt"), "proguard-rules.pro")
|
||||
isMinifyEnabled = true
|
||||
isShrinkResources = true
|
||||
|
||||
resValue("mipmap", "floris_app_icon", "@mipmap/ic_app_icon_beta")
|
||||
resValue("mipmap", "floris_app_icon_round", "@mipmap/ic_app_icon_beta_round")
|
||||
@@ -124,14 +149,31 @@ android {
|
||||
resValue("string", "floris_app_name", "FlorisBoard Beta")
|
||||
}
|
||||
|
||||
named("release").configure {
|
||||
proguardFiles.add(getDefaultProguardFile("proguard-android-optimize.txt"))
|
||||
named("release") {
|
||||
proguardFiles(getDefaultProguardFile("proguard-android-optimize.txt"), "proguard-rules.pro")
|
||||
isMinifyEnabled = true
|
||||
isShrinkResources = true
|
||||
|
||||
resValue("mipmap", "floris_app_icon", "@mipmap/ic_app_icon_release")
|
||||
resValue("mipmap", "floris_app_icon_round", "@mipmap/ic_app_icon_release_round")
|
||||
resValue("drawable", "floris_app_icon_foreground", "@drawable/ic_app_icon_release_foreground")
|
||||
resValue("mipmap", "floris_app_icon", "@mipmap/ic_app_icon_stable")
|
||||
resValue("mipmap", "floris_app_icon_round", "@mipmap/ic_app_icon_stable_round")
|
||||
resValue("drawable", "floris_app_icon_foreground", "@drawable/ic_app_icon_stable_foreground")
|
||||
resValue("string", "floris_app_name", "@string/app_name")
|
||||
}
|
||||
|
||||
create("benchmark") {
|
||||
initWith(getByName("release"))
|
||||
signingConfig = signingConfigs.getByName("debug")
|
||||
matchingFallbacks += listOf("release")
|
||||
|
||||
ndk {
|
||||
// For running FlorisBoard on the emulator
|
||||
abiFilters += listOf("x86", "x86_64")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
aboutLibraries {
|
||||
configPath = "app/src/main/config"
|
||||
}
|
||||
|
||||
testOptions {
|
||||
@@ -149,36 +191,56 @@ tasks.withType<Test> {
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation("androidx.activity:activity-compose:1.4.0")
|
||||
implementation("androidx.activity:activity-ktx:1.4.0")
|
||||
implementation("androidx.autofill:autofill:1.1.0")
|
||||
implementation("androidx.collection:collection-ktx:1.2.0")
|
||||
implementation("androidx.compose.material:material:1.1.1")
|
||||
implementation("androidx.compose.runtime:runtime-livedata:1.1.1")
|
||||
implementation("androidx.compose.ui:ui:1.1.1")
|
||||
implementation("androidx.compose.ui:ui-tooling-preview:1.1.1")
|
||||
implementation("androidx.core:core-ktx:1.7.0")
|
||||
implementation("androidx.core:core-splashscreen:1.0.0-beta01")
|
||||
implementation("androidx.emoji2:emoji2:1.1.0")
|
||||
implementation("androidx.emoji2:emoji2-views:1.1.0")
|
||||
implementation("androidx.navigation:navigation-compose:2.4.1")
|
||||
implementation("com.google.accompanist:accompanist-flowlayout:0.23.0")
|
||||
implementation("com.google.accompanist:accompanist-insets:0.23.0")
|
||||
implementation("com.google.accompanist:accompanist-systemuicontroller:0.23.0")
|
||||
implementation("dev.patrickgold.jetpref:jetpref-datastore-model:0.1.0-beta08")
|
||||
implementation("dev.patrickgold.jetpref:jetpref-datastore-ui:0.1.0-beta08")
|
||||
implementation("dev.patrickgold.jetpref:jetpref-material-ui:0.1.0-beta08")
|
||||
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-android:1.6.0")
|
||||
implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.3.2")
|
||||
implementation("androidx.room:room-runtime:2.4.2")
|
||||
kapt("androidx.room:room-compiler:2.4.2")
|
||||
implementation(libs.accompanist.flowlayout)
|
||||
implementation(libs.accompanist.systemuicontroller)
|
||||
implementation(libs.androidx.activity.compose)
|
||||
implementation(libs.androidx.activity.ktx)
|
||||
implementation(libs.androidx.autofill)
|
||||
implementation(libs.androidx.collection.ktx)
|
||||
implementation(libs.androidx.compose.material)
|
||||
implementation(libs.androidx.compose.runtime.livedata)
|
||||
implementation(libs.androidx.compose.ui)
|
||||
implementation(libs.androidx.compose.ui.tooling.preview)
|
||||
implementation(libs.androidx.core.ktx)
|
||||
implementation(libs.androidx.core.splashscreen)
|
||||
implementation(libs.androidx.emoji2)
|
||||
implementation(libs.androidx.emoji2.views)
|
||||
implementation(libs.androidx.navigation.compose)
|
||||
implementation(libs.androidx.profileinstaller)
|
||||
ksp(libs.androidx.room.compiler)
|
||||
implementation(libs.androidx.room.runtime)
|
||||
implementation(libs.cache4k)
|
||||
implementation(libs.jetpref.datastore.model)
|
||||
implementation(libs.jetpref.datastore.ui)
|
||||
implementation(libs.jetpref.material.ui)
|
||||
implementation(libs.kotlinx.coroutines)
|
||||
implementation(libs.kotlinx.serialization.json)
|
||||
implementation(libs.mikepenz.aboutlibraries.core)
|
||||
implementation(libs.mikepenz.aboutlibraries.compose)
|
||||
|
||||
testImplementation("io.kotest:kotest-runner-junit5:5.1.0")
|
||||
testImplementation("io.kotest:kotest-assertions-core:5.1.0")
|
||||
testImplementation("io.kotest:kotest-property:5.1.0")
|
||||
testImplementation("io.kotest.extensions:kotest-extensions-robolectric:0.5.0")
|
||||
testImplementation("nl.jqno.equalsverifier:equalsverifier:3.8.3")
|
||||
testImplementation(libs.equalsverifier)
|
||||
testImplementation(libs.kotest.assertions.core)
|
||||
testImplementation(libs.kotest.extensions.roboelectric)
|
||||
testImplementation(libs.kotest.property)
|
||||
testImplementation(libs.kotest.runner.junit5)
|
||||
|
||||
androidTestImplementation("androidx.test.ext", "junit", "1.1.2")
|
||||
androidTestImplementation("androidx.test.espresso", "espresso-core", "3.3.0")
|
||||
androidTestImplementation(libs.androidx.test.ext)
|
||||
androidTestImplementation(libs.androidx.test.espresso.core)
|
||||
}
|
||||
|
||||
fun getGitCommitHash(short: Boolean = false): String {
|
||||
if (!File(".git").exists()) {
|
||||
return "null"
|
||||
}
|
||||
|
||||
val stdout = ByteArrayOutputStream()
|
||||
exec {
|
||||
if (short) {
|
||||
commandLine("git", "rev-parse", "--short", "HEAD")
|
||||
} else {
|
||||
commandLine("git", "rev-parse", "HEAD")
|
||||
}
|
||||
standardOutput = stdout
|
||||
}
|
||||
return stdout.toString().trim()
|
||||
}
|
||||
|
||||
29
app/proguard-rules.pro
vendored
Normal file
29
app/proguard-rules.pro
vendored
Normal file
@@ -0,0 +1,29 @@
|
||||
# Disable obfuscation (we use Proguard exclusively for optimization)
|
||||
-dontobfuscate
|
||||
|
||||
# Keep `Companion` object fields of serializable classes.
|
||||
# This avoids serializer lookup through `getDeclaredClasses` as done for named companion objects.
|
||||
-if @kotlinx.serialization.Serializable class **
|
||||
-keepclassmembers class <1> {
|
||||
static <1>$Companion Companion;
|
||||
}
|
||||
|
||||
# Keep `serializer()` on companion objects (both default and named) of serializable classes.
|
||||
-if @kotlinx.serialization.Serializable class ** {
|
||||
static **$* *;
|
||||
}
|
||||
-keepclassmembers class <2>$<3> {
|
||||
kotlinx.serialization.KSerializer serializer(...);
|
||||
}
|
||||
|
||||
# Keep `INSTANCE.serializer()` of serializable objects.
|
||||
-if @kotlinx.serialization.Serializable class ** {
|
||||
public static ** INSTANCE;
|
||||
}
|
||||
-keepclassmembers class <1> {
|
||||
public static <1> INSTANCE;
|
||||
kotlinx.serialization.KSerializer serializer(...);
|
||||
}
|
||||
|
||||
# @Serializable and @Polymorphic are used at runtime for polymorphic serialization.
|
||||
-keepattributes RuntimeVisibleAnnotations,AnnotationDefault
|
||||
@@ -0,0 +1,62 @@
|
||||
{
|
||||
"formatVersion": 1,
|
||||
"database": {
|
||||
"version": 1,
|
||||
"identityHash": "d573e2ae2cbe7026957bc8d8fda291f3",
|
||||
"entities": [
|
||||
{
|
||||
"tableName": "clipboard_files",
|
||||
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`_id` INTEGER NOT NULL, `_display_name` TEXT NOT NULL, `_size` INTEGER NOT NULL, `mimeTypes` TEXT NOT NULL, PRIMARY KEY(`_id`))",
|
||||
"fields": [
|
||||
{
|
||||
"fieldPath": "id",
|
||||
"columnName": "_id",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "displayName",
|
||||
"columnName": "_display_name",
|
||||
"affinity": "TEXT",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "size",
|
||||
"columnName": "_size",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "mimeTypes",
|
||||
"columnName": "mimeTypes",
|
||||
"affinity": "TEXT",
|
||||
"notNull": true
|
||||
}
|
||||
],
|
||||
"primaryKey": {
|
||||
"columnNames": [
|
||||
"_id"
|
||||
],
|
||||
"autoGenerate": false
|
||||
},
|
||||
"indices": [
|
||||
{
|
||||
"name": "index_clipboard_files__id",
|
||||
"unique": false,
|
||||
"columnNames": [
|
||||
"_id"
|
||||
],
|
||||
"orders": [],
|
||||
"createSql": "CREATE INDEX IF NOT EXISTS `index_clipboard_files__id` ON `${TABLE_NAME}` (`_id`)"
|
||||
}
|
||||
],
|
||||
"foreignKeys": []
|
||||
}
|
||||
],
|
||||
"views": [],
|
||||
"setupQueries": [
|
||||
"CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)",
|
||||
"INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, 'd573e2ae2cbe7026957bc8d8fda291f3')"
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,80 @@
|
||||
{
|
||||
"formatVersion": 1,
|
||||
"database": {
|
||||
"version": 2,
|
||||
"identityHash": "6fbec9d7ea017f8aefac4fb84dbd5189",
|
||||
"entities": [
|
||||
{
|
||||
"tableName": "clipboard_history",
|
||||
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`_id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `type` INTEGER NOT NULL, `text` TEXT, `uri` TEXT, `creationTimestampMs` INTEGER NOT NULL, `isPinned` INTEGER NOT NULL, `mimeTypes` TEXT NOT NULL)",
|
||||
"fields": [
|
||||
{
|
||||
"fieldPath": "id",
|
||||
"columnName": "_id",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "type",
|
||||
"columnName": "type",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "text",
|
||||
"columnName": "text",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "uri",
|
||||
"columnName": "uri",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "creationTimestampMs",
|
||||
"columnName": "creationTimestampMs",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "isPinned",
|
||||
"columnName": "isPinned",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "mimeTypes",
|
||||
"columnName": "mimeTypes",
|
||||
"affinity": "TEXT",
|
||||
"notNull": true
|
||||
}
|
||||
],
|
||||
"primaryKey": {
|
||||
"columnNames": [
|
||||
"_id"
|
||||
],
|
||||
"autoGenerate": true
|
||||
},
|
||||
"indices": [
|
||||
{
|
||||
"name": "index_clipboard_history__id",
|
||||
"unique": false,
|
||||
"columnNames": [
|
||||
"_id"
|
||||
],
|
||||
"orders": [],
|
||||
"createSql": "CREATE INDEX IF NOT EXISTS `index_clipboard_history__id` ON `${TABLE_NAME}` (`_id`)"
|
||||
}
|
||||
],
|
||||
"foreignKeys": []
|
||||
}
|
||||
],
|
||||
"views": [],
|
||||
"setupQueries": [
|
||||
"CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)",
|
||||
"INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, '6fbec9d7ea017f8aefac4fb84dbd5189')"
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
{
|
||||
"formatVersion": 1,
|
||||
"database": {
|
||||
"version": 1,
|
||||
"identityHash": "787af4a2df15bf9d2c0597519d3fb273",
|
||||
"entities": [
|
||||
{
|
||||
"tableName": "words",
|
||||
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`_id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `word` TEXT NOT NULL, `frequency` INTEGER NOT NULL, `locale` TEXT, `shortcut` TEXT)",
|
||||
"fields": [
|
||||
{
|
||||
"fieldPath": "id",
|
||||
"columnName": "_id",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "word",
|
||||
"columnName": "word",
|
||||
"affinity": "TEXT",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "freq",
|
||||
"columnName": "frequency",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "locale",
|
||||
"columnName": "locale",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "shortcut",
|
||||
"columnName": "shortcut",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
}
|
||||
],
|
||||
"primaryKey": {
|
||||
"columnNames": [
|
||||
"_id"
|
||||
],
|
||||
"autoGenerate": true
|
||||
},
|
||||
"indices": [
|
||||
{
|
||||
"name": "index_words__id",
|
||||
"unique": false,
|
||||
"columnNames": [
|
||||
"_id"
|
||||
],
|
||||
"orders": [],
|
||||
"createSql": "CREATE INDEX IF NOT EXISTS `index_words__id` ON `${TABLE_NAME}` (`_id`)"
|
||||
}
|
||||
],
|
||||
"foreignKeys": []
|
||||
}
|
||||
],
|
||||
"views": [],
|
||||
"setupQueries": [
|
||||
"CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)",
|
||||
"INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, '787af4a2df15bf9d2c0597519d3fb273')"
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -13,10 +13,8 @@
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
package="dev.patrickgold.florisboard">
|
||||
xmlns:tools="http://schemas.android.com/tools">
|
||||
|
||||
<!-- Permission needed to vibrate if the user has key press vibration enabled -->
|
||||
<uses-permission android:name="android.permission.VIBRATE"/>
|
||||
@@ -46,14 +44,16 @@
|
||||
android:theme="@style/FlorisAppTheme"
|
||||
tools:targetApi="s">
|
||||
|
||||
<!-- Allow app to be profiled for benchmarking and baseline profile generation -->
|
||||
<profileable android:shell="true"/>
|
||||
|
||||
<!-- IME service -->
|
||||
<service
|
||||
android:name="dev.patrickgold.florisboard.FlorisImeService"
|
||||
android:label="@string/floris_app_name"
|
||||
android:permission="android.permission.BIND_INPUT_METHOD"
|
||||
android:directBootAware="true"
|
||||
android:exported="true"
|
||||
tools:targetApi="n">
|
||||
android:exported="true">
|
||||
<intent-filter>
|
||||
<action android:name="android.view.InputMethod"/>
|
||||
</intent-filter>
|
||||
@@ -80,7 +80,7 @@
|
||||
android:launchMode="singleTask"
|
||||
android:roundIcon="@mipmap/floris_app_icon_round"
|
||||
android:windowSoftInputMode="adjustResize"
|
||||
android:theme="@style/FlorisAppTheme"
|
||||
android:theme="@style/FlorisAppTheme.Splash"
|
||||
android:exported="false">
|
||||
<intent-filter>
|
||||
<data android:scheme="florisboard" android:host="app-ui"/>
|
||||
@@ -95,7 +95,7 @@
|
||||
android:launchMode="singleTask"
|
||||
android:roundIcon="@mipmap/floris_app_icon_round"
|
||||
android:targetActivity="dev.patrickgold.florisboard.app.FlorisAppActivity"
|
||||
android:theme="@style/FlorisAppTheme"
|
||||
android:theme="@style/FlorisAppTheme.Splash"
|
||||
android:exported="true">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN"/>
|
||||
@@ -105,7 +105,7 @@
|
||||
|
||||
<!-- Import File Bridging Activity -->
|
||||
<activity
|
||||
android:name="dev.patrickgold.florisboard.app.ui.ext.ImportFileActivity"
|
||||
android:name="dev.patrickgold.florisboard.app.ext.ImportFileActivity"
|
||||
android:icon="@mipmap/floris_app_icon"
|
||||
android:label="@string/settings__title"
|
||||
android:launchMode="singleTask"
|
||||
@@ -123,14 +123,14 @@
|
||||
|
||||
<!-- Crash Dialog Activity -->
|
||||
<activity
|
||||
android:name="dev.patrickgold.florisboard.crashutility.CrashDialogActivity"
|
||||
android:name="dev.patrickgold.florisboard.lib.crashutility.CrashDialogActivity"
|
||||
android:icon="@mipmap/floris_app_icon"
|
||||
android:label="@string/crash_dialog__title"
|
||||
android:theme="@style/CrashDialogTheme"/>
|
||||
|
||||
<!-- Clipboard Image File Provider -->
|
||||
<!-- Clipboard Media File Provider -->
|
||||
<provider
|
||||
android:name="dev.patrickgold.florisboard.ime.clipboard.provider.ClipboardImagesProvider"
|
||||
android:name="dev.patrickgold.florisboard.ime.clipboard.provider.ClipboardMediaProvider"
|
||||
android:authorities="${applicationId}.provider.clipboard"
|
||||
android:grantUriPermissions="true"
|
||||
android:exported="false">
|
||||
@@ -147,6 +147,17 @@
|
||||
android:resource="@xml/file_paths"/>
|
||||
</provider>
|
||||
|
||||
<!-- Disable default EmojiCompat initializer -->
|
||||
<provider
|
||||
android:name="androidx.startup.InitializationProvider"
|
||||
android:authorities="${applicationId}.androidx-startup"
|
||||
android:exported="false"
|
||||
tools:node="merge">
|
||||
<meta-data
|
||||
android:name="androidx.emoji2.text.EmojiCompatInitializer"
|
||||
tools:node="remove"/>
|
||||
</provider>
|
||||
|
||||
</application>
|
||||
|
||||
</manifest>
|
||||
|
||||
Binary file not shown.
@@ -2,10 +2,10 @@
|
||||
"$": "ime.extension.keyboard",
|
||||
"meta": {
|
||||
"id": "org.florisboard.composers",
|
||||
"version": "0.1.0",
|
||||
"version": "0.1.1",
|
||||
"title": "Default composers",
|
||||
"description": "Default composers which are always available.",
|
||||
"maintainers": [ "patrickgold <patrick@patrickgold.dev>" ],
|
||||
"maintainers": [ "patrickgold <patrick@patrickgold.dev>", "thanhhocse96 <thanh.hoquang@pm.me>" ],
|
||||
"license": "apache-2.0"
|
||||
},
|
||||
"composers": [
|
||||
@@ -13,10 +13,10 @@
|
||||
{ "$": "hangul-unicode" },
|
||||
{ "$": "kana-unicode" },
|
||||
{ "$": "with-rules",
|
||||
"id": "basic-telex",
|
||||
"label": "Basic Telex",
|
||||
"id": "telex",
|
||||
"label": "Telex",
|
||||
"rules": {
|
||||
"aw": "ă", "aa": "â", "dd": "đ", "ee": "ê", "oo": "ô", "ow": "ơ", "uw": "ư", "w": "ư",
|
||||
"aw": "ă", "aa": "â", "dd": "đ", "ee": "ê", "oo": "ô", "ow": "ơ", "uw": "ư", "w": "ư",
|
||||
"uow": "ươ",
|
||||
"af": "à", "ar": "ả", "ax": "ã", "as": "á", "aj": "ạ",
|
||||
"ăf": "ằ", "ăr": "ẳ", "ăx": "ẵ", "ăs": "ắ", "ăj": "ặ",
|
||||
@@ -30,7 +30,7 @@
|
||||
"uf": "ù", "ur": "ủ", "ux": "ũ", "us": "ú", "uj": "ụ",
|
||||
"ưf": "ừ", "ưr": "ử", "ưx": "ữ", "ưs": "ứ", "ưj": "ự",
|
||||
"yf": "ỳ", "yr": "ỷ", "yx": "ỹ", "ys": "ý", "yj": "ỵ",
|
||||
"ăw": "aw", "âa": "aa", "đd": "dd", "êe": "ee", "ôo": "oo", "ơw": "ow", "ưw": "w",
|
||||
"ăw": "aw", "âa": "aa", "đd": "dd", "êe": "ee", "ôo": "oo", "ơw": "ow", "ưw": "w", "iêe": "iee",
|
||||
"ươw": "uow",
|
||||
"àf": "af", "ảr": "ar", "ãx": "ax", "ás": "as", "ạj": "aj",
|
||||
"ằf": "ăf", "ẳr": "ăr", "ẵx": "ăx", "ắs": "ăs", "ặj": "ăj",
|
||||
@@ -55,7 +55,623 @@
|
||||
"ờz": "ơ", "ởz": "ơ", "ỡz": "ơ", "ớz": "ơ", "ợz": "ơ",
|
||||
"ùz": "u", "ủz": "u", "ũz": "u", "úz": "u", "ụz": "u",
|
||||
"ừz": "ư", "ửz": "ư", "ữz": "ư", "ứz": "ư", "ựz": "ư",
|
||||
"ỳz": "y", "ỷz": "y", "ỹz": "y", "ýz": "y", "ỵz": "y"
|
||||
"ỳz": "y", "ỷz": "y", "ỹz": "y", "ýz": "y", "ỵz": "y",
|
||||
|
||||
"acw": "ăc", "amw": "ăm", "anw": "ăn", "apw": "ăp", "atw": "ăt", "angw": "ăng",
|
||||
"aca": "âc", "ama": "âm", "ana": "ân", "apa": "âp", "ata": "ât", "aua": "âu", "aya": "ây", "anga": "âng",
|
||||
"eme": "êm", "ene": "ên", "epe": "êp", "ete": "êt", "enhe": "ênh",
|
||||
"oio": "ôi","omo": "ôm", "ono": "ôn", "opo": "ôp", "oto": "ôt", "ongo": "ông",
|
||||
"oiw": "ơi", "omw": "ơm", "onw": "ơn", "opw": "ơp", "otw": "ơt",
|
||||
"uaw": "ưa", "uiw": "ưi", "umw": "ưm", "unw": "ưn", "utw": "ưt", "uuw": "ưu", "ungw": "ưng",
|
||||
"ieme": "iêm", "iene": "iên", "iepe": "iêp", "iete": "iêt", "ieue": "iêu", "ienge": "iêng",
|
||||
"uocw": "ươc", "uoiw": "ươi", "uomw": "ươm", "uonw": "ươn", "uotw": "ươt", "uongw": "ương",
|
||||
"uoco": "uôc", "uoio": "uôi", "uomo": "uôm", "uono": "uôn", "uoto": "uôt", "uongo": "uông",
|
||||
"uyene": "uyên", "uyete": "uyêt",
|
||||
"yeme": "yêm", "yene": "yên", "yete": "yêt", "yeue": "yêu", "yenge": "yêng",
|
||||
|
||||
"ăca": "âc", "ăma": "âm", "ăna": "ân", "ăpa": "âp", "ăta": "ât", "ănga": "âng",
|
||||
"âcw": "ăc", "âmw": "ăm", "ânw": "ăn", "âpw": "ăp", "âtw": "ăt", "ângw": "ăng",
|
||||
"ôiw": "ơi", "ômw": "ơm", "ônw": "ơn", "ôpw": "ơp", "ôtw": "ơt",
|
||||
"ơio": "ôi", "ơmo": "ôm", "ơno": "ôn", "ơpo": "ôp", "ơto": "ôt",
|
||||
|
||||
"ăcw": "acw", "ămw": "amw", "ănw": "anw", "ăpw": "apw", "ătw": "atw", "ăngw": "angw",
|
||||
"âca": "aca", "âma": "ama", "âna": "ana", "âpa": "apa", "âta": "ata", "âua": "aua", "âya": "aya", "ânga": "anga",
|
||||
"ême": "eme", "êne": "ene", "êpe": "epe", "ête": "ete",
|
||||
"ôio": "oio", "ômo": "omo", "ôno": "ono", "ôpo": "opo", "ôto": "oto", "ôngo": "ongo",
|
||||
"ơmw": "omw", "ơnw": "onw", "ơpw": "opw", "ơtw": "otw",
|
||||
"ưaw": "uaw", "ưiw": "uiw", "ưmw": "umw", "ưnw": "unw" , "ưtw": "utw", "ưuw": "uuw", "ưngw": "ungw",
|
||||
"iême": "ieme", "iêne": "iene", "iêpe": "iepe", "iête": "iete", "iêue": "ieue", "iênge": "ienge",
|
||||
"ươcw": "uocw", "ươiw": "uoiw", "ươmw": "uomw", "ươnw": "uonw", "ươtw": "uotw", "ươngw": "uongw",
|
||||
"uyêne": "uyene", "uyêt": "uyete",
|
||||
"yême": "yeme", "yêne": "yene", "yête": "yete", "yêue": "yeue", "yênge": "yenge",
|
||||
|
||||
"acs": "ác", "acj": "ạc",
|
||||
"achs": "ách", "achj": "ạch",
|
||||
"ais": "ái", "aif": "ài", "air": "ải", "aix": "ãi", "aij": "ại",
|
||||
"ams": "ám", "amf": "àm", "amr": "ảm", "amx": "ãm", "amj": "ạm",
|
||||
"ans": "án" , "anf": "àn", "anr": "ản", "anx": "ãn", "anj": "ạn",
|
||||
"aos": "áo", "aof": "ào", "aor": "ảo", "aox": "ão", "aoj": "ạo",
|
||||
"aps":"áp", "apj": "ạp",
|
||||
"ats":"át", "atj": "ạt",
|
||||
"aus":"áu", "auf": "àu", "aur": "ảu", "aux": "ãu", "auj": "ạu",
|
||||
"ays": "áy", "ayf": "ày", "ayr": "ảy", "ayx": "ãy", "ayj": "ạy",
|
||||
"angs": "áng", "angf": "àng", "angr": "ảng", "angx": "ãng", "angj": "ạng",
|
||||
"anhs": "ánh", "anhf": "ành", "anhr": "ảnh", "anhx": "ãnh", "anhj": "ạnh",
|
||||
|
||||
"ács": "acs", "ạcj": "acj",
|
||||
"áchs": "achs", "ạchj": "achj",
|
||||
"áis": "ais", "àif": "aif", "ảir": "air", "ãix": "aix", "ạij": "aij",
|
||||
"áms": "ams", "àmf": "amf", "ảmr": "amr", "ãmx": "amx", "ạmj": "amj",
|
||||
"áns": "ans", "ànf": "anf", "ảnr": "anr", "ãnx": "anx", "ạnj": "anj",
|
||||
"áos": "aos", "àof": "aof", "ảor": "aor", "ãox": "aox", "ạoj":"aoj",
|
||||
"áps": "aps", "ạpj": "apj",
|
||||
"áts": "ats", "ạtj": "atj",
|
||||
"áus": "aus", "àuf": "auf", "ảur": "aur", "ãux": "aux", "ạuj": "auj",
|
||||
"áys": "ays", "àyf": "ayf", "ảyr": "ayr", "ãyx": "ayx", "ạyj": "ayj",
|
||||
"ángs": "angs", "àngf": "angf", "ảngr": "angr", "ãngx": "angx", "ạngj": "angj",
|
||||
"ánhs": "anhs", "ànhf": "anhf", "ảnhr": "anhr", "ãnhx": "anhx", "ạnhj": "anhj",
|
||||
|
||||
"ecs": "éc", "ecj": "ẹc",
|
||||
"ems": "ém", "emf": "èm", "emr": "ẻm", "emx": "ẽm", "emj": "ẹm",
|
||||
"ens": "én", "enf": "èn", "enr": "ẻn", "enx": "ẽn", "enj": "ẹn",
|
||||
"eps": "ép", "epj": "ẹp",
|
||||
"ets": "ét", "etj": "ẹt",
|
||||
"engs": "éng", "engf": "èng", "engr": "ẻng", "engx": "ẽng", "engj": "ẹng",
|
||||
"enhs": "énh", "enhf": "ènh", "enhr": "ẻnh", "enhx": "ẽnh", "enhj": "ẹnh",
|
||||
|
||||
"écs": "ecs", "ẹcj": "ecj",
|
||||
"éms": "ems", "èmf": "emf", "ẻmr": "emr", "ẽmx": "emx", "ẹmj": "emj",
|
||||
"éns": "ens", "ènf": "enf","ẻnr": "enr", "ẽnx": "enx", "ẹnj": "enj",
|
||||
"éps": "eps", "ẹpj": "epj",
|
||||
"éts": "ets", "ẹtj": "etj",
|
||||
"éngs": "engs", "èngf": "engf", "ẻngr": "engr", "ẽngx":"engx", "ẹngj": "engj",
|
||||
"énhs": "enhs", "ènhf": "enhf", "ẻnhr": "enhr", "ẽnh": "enhx", "ẹnh": "enhj",
|
||||
|
||||
"ias": "ía", "iaf": "ìa", "iar": "ỉa", "iax": "ĩa", "iaj": "ịa",
|
||||
"ics": "íc", "icj": "ịc",
|
||||
"ims": "ím", "imf": "ìm", "imr": "ỉm", "imx": "ĩm", "imj": "ịm",
|
||||
"ins": "ín", "inf": "ìn", "inr": "ỉn", "inx": "ĩn", "inj": "ịn",
|
||||
"ips": "íp", "ipj": "ịp",
|
||||
"its": "ít", "itj": "ịt",
|
||||
"ius": "íu", "iuf": "ìu", "iur": "ỉu", "iux": "ĩu", "iuj": "ịu",
|
||||
"ichs": "ích", "ichj": "ịch",
|
||||
"inhs": "ính", "inhf": "ình", "inhr": "ỉnh", "inhx": "ĩnh", "inhj": "ịnh",
|
||||
|
||||
"ías": "ias", "ìaf": "iaf", "ỉar": "iar", "ĩax": "iax", "ịaj": "iaj",
|
||||
"ícs": "ics", "ịcj": "icj",
|
||||
"íms": "ims", "ìmf": "imf", "ỉmr": "imr", "ĩmx": "imx", "ịmj": "imj",
|
||||
"íns": "ins", "ìnf": "inf", "ỉnr": "inr", "ĩnx": "inx", "ịnj": "inj",
|
||||
"íps": "ips", "ịpj": "ipj",
|
||||
"íts": "its", "ịtj": "itj",
|
||||
"íus": "ius", "ìuf": "iuf", "ỉur": "iur", "ĩux": "iux", "ịuj": "iuj",
|
||||
"íchs": "ichs", "ịchj": "ichj",
|
||||
"ínhs": "inhs", "ìnhf": "inhf", "ỉnhr": "inhr", "ĩnhx": "inhx", "ịnhj": "inhj",
|
||||
|
||||
"oas": "óa", "oaf": "òa", "oar": "ỏa", "oax": "õa", "oaj": "ọa",
|
||||
"ocs": "óc", "ocj": "ọc",
|
||||
"ois": "ói", "oif": "òi", "oir": "ỏi", "oix": "õi", "oij": "ọi",
|
||||
"oms": "óm", "omf": "òm", "omr": "ỏm", "omx": "õm", "omj": "ọm",
|
||||
"ons": "ón", "onf": "òn", "onr": "ỏn", "onx": "õn", "onj": "ọn",
|
||||
"ops": "óp", "opj": "ọp",
|
||||
"ots": "ót", "otj": "ọt",
|
||||
"ongs": "óng", "ongf": "òng", "ongr": "ỏng", "ongx": "õng", "ongj": "ọng",
|
||||
|
||||
"óas": "oas", "òaf": "oaf", "ỏar": "oar", "õax": "oax", "ọaj": "oaj",
|
||||
"ócs": "ocs", "ọcj": "ocj",
|
||||
"óis": "ois", "òif": "oif", "ỏir": "oir", "õix": "oix", "ọij": "oij",
|
||||
"óms": "oms", "òmf": "omf", "ỏmr": "omr", "õmx": "omx", "ọmj": "omj",
|
||||
"óns": "ons", "ònf": "onf", "ỏnr": "onr", "õnx": "onx", "ọnj": "onj",
|
||||
"óps": "ops", "ọpj": "opj",
|
||||
"óts": "ots", "ọtj": "otj",
|
||||
"óngs": "ongs", "òngf": "ongf", "ỏngr": "ongr", "õngx": "ongx", "ọngj": "ongj",
|
||||
|
||||
"uas": "úa", "uaf": "ùa", "uar": "ủa", "uax": "ũa", "uaj": "ụa",
|
||||
"ucs": "úc", "ucj": "ục",
|
||||
"uis": "úi", "uif": "ùi", "uir": "ủi", "uix": "ũi", "uij": "ụi",
|
||||
"ums": "úm", "umf": "ùm", "umr": "ủm", "umx": "ũm", "umj": "ụm",
|
||||
"uns": "ún", "unf": "ùn", "unr": "ủn", "unx": "ũn", "unj": "ụn",
|
||||
"ups": "úp", "upj": "ụp",
|
||||
"uts": "út", "utj": "ụt",
|
||||
"uus": "úu", "uuf": "ùu", "uur": "ủu", "uux": "ũu", "uuj": "ụu",
|
||||
"uys": "úy", "uyf": "ùy", "uyr": "ủy", "uyx": "ũy", "uyj": "ụy",
|
||||
"ungs": "úng", "ungf": "ùng", "ungr": "ủng", "ungx": "ũng", "ungj": "ụng",
|
||||
|
||||
"úas": "uas", "ùaf": "uaf", "ủar": "uar", "ũax": "uax", "ụaj": "uaj",
|
||||
"úcs": "ucs", "ụcj": "ucj",
|
||||
"úis": "uis", "ùif": "uif", "ủir": "uir", "ũix": "uix", "ụij": "uij",
|
||||
"úms": "ums", "ùmf": "umf", "ủmr": "umr", "ũmx": "umx", "ụmj": "umj",
|
||||
"úns": "uns", "ùnf": "unf", "ủnr": "unr", "ũnx": "unx", "ụnj": "unj",
|
||||
"úps": "ups", "ụpj": "upj",
|
||||
"úts": "uts", "ụtj": "utj",
|
||||
"úus": "uus", "ùuf": "uuf", "ủur": "uur", "ũux": "uux", "ụuj": "uuj",
|
||||
"úu ": "uus", "ùu ": "uuf", "ủu ": "uur", "ũu ": "uux", "ụu ": "uuj",
|
||||
"úys": "uys", "ùyf": "uyf", "ủyr": "uyr", "ũyx": "uyx", "ụyj": "uyj",
|
||||
"úngs": "ungs", "ùngf": "ungf", "ủngr": "ungr", "ũngx": "ungx", "ụngj": "ungj",
|
||||
|
||||
"ăcs": "ắc", "ăcj": "ặc",
|
||||
"ácw": "ắc", "ạcw": "ặc",
|
||||
"ăms": "ắm", "ămf": "ằm", "ămr": "ẳm", "ămx": "ẵm", "ămj": "ặm",
|
||||
"ámw": "ắm", "àmw": "ằm", "ảmw": "ẳm", "ãmw": "ẵm", "ạmw": "ặm",
|
||||
"ăns": "ắn", "ănf": "ằn", "ănr": "ẳn", "ănx": "ẵn", "ănj": "ặn",
|
||||
"ánw": "ắn", "ànw": "ằn", "ảnw": "ẳn", "ãnw": "ẵn", "ạnw": "ặn",
|
||||
"ăps": "ắp", "ăpj": "ặp",
|
||||
"ápw": "ắp", "ạpw": "ặp",
|
||||
"ăts": "ắt", "ătj": "ặt",
|
||||
"átw": "ắt", "ạtw": "ặt",
|
||||
"ăngs": "ắng", "ăngf": "ằng", "ăngr": "ẳng", "ăngx": "ẵng", "ăngj": "ặng",
|
||||
"ángw": "ắng", "àngw": "ằng", "ảngw": "ẳng", "ãngw":"ẵng", "ạngw": "ặng",
|
||||
|
||||
"ắcw": "ácw", "ắcs": "ăcs", "ăcsw": "acsw", "ácws": "acws",
|
||||
"ặcw": "ạcw", "ặcj": "ăcj", "ăcjw": "acjw", "ạcwj": "acwj",
|
||||
"ắms": "ăms", "ắmw": "ámw", "ămsw": "amsw", "ámws": "amws",
|
||||
"ằmf": "ămf", "ằmw": "àmw", "ămfw": "amfw", "àmwf": "amwf",
|
||||
"ẳmr": "ămr", "ẳmw": "ảmw", "ămrw": "amrw", "ảmwr": "amwr",
|
||||
"ẵmx": "ămx", "ẵmw": "ãmw", "ămxw": "amxw", "ãmwx": "amwx",
|
||||
"ặmj": "ămj", "ặmw": "ạmw", "ămjw": "amjw", "ạmwj": "amwj",
|
||||
"ắns": "ăns", "ắnw": "ánw", "ănsw": "answ", "ánws": "anws",
|
||||
"ằnf": "ănf", "ằnw": "ànw", "ănfw": "anfw", "ànwf": "anwf",
|
||||
"ẳnr": "ănr", "ẳnw": "ảnw", "ănrw": "anrw", "ảnwr": "anwr",
|
||||
"ẵnx": "ănx", "ẵnw": "ãnw", "ănxw": "anxw", "ãnwx": "anwx",
|
||||
"ặnj": "ănj", "ặnw": "ạnw", "ănjw": "anjw", "ạnwj": "anwj",
|
||||
"ắps": "ăps", "ắpw": "ápw", "ăpsw": "apsw", "ápws": "apws",
|
||||
"ặpj": "ăpj", "ặpw": "ạpw", "ăpjw": "apjw", "ạpwj": "apwj",
|
||||
"ắts": "ăts", "ắtw": "átw", "ătsw": "atws", "átws": "atws",
|
||||
"ặtj": "ătj", "ặtw": "ạtw", "ătjw": "atjw", "ạtwj": "atwj",
|
||||
"ắngs": "ăngs", "ắngw": "ángw", "ăngsw": "angsw", "ángws": "angws",
|
||||
"ằngf": "ăngf", "ằngw": "àngw", "ăngfw": "angfw", "àngwf": "angwf",
|
||||
"ẳngr": "ăngr", "ẳngw": "ảngw", "ăngrw": "angrw", "ảngwr": "angwr",
|
||||
"ẵngx": "ăngx", "ẵngw": "ãngw", "ăngxw": "angxw", "ãngwx": "angwx",
|
||||
"ặngj": "ăngj", "ặngw": "ạngw", "ăngjw": "angjw", "ạngwj": "angwj",
|
||||
|
||||
"âcs": "ấc", "âcj": "ậc",
|
||||
"áca": "ấc", "ạca": "ậc",
|
||||
"âms": "ấm", "âmf": "ầm", "âmr": "ẩm", "âmx": "ẫm", "âmj": "ậm",
|
||||
"áma": "ấm", "àma": "ầm", "ảma": "ẩm", "ãma": "ẫm", "ạma": "ậm",
|
||||
"âns": "ấn", "ânf": "ần", "ânr": "ẩn", "ânx": "ẫn", "ânj": "ận",
|
||||
"ána": "ấn", "àna": "ần", "ảna": "ẩn", "ãna": "ẫn", "ạna": "ận",
|
||||
"âps": "ấp", "âpj": "ập",
|
||||
"ápa": "ấp", "ạpa": "ập",
|
||||
"âts": "ất", "âtj": "ật",
|
||||
"áta": "ất", "ạta": "ật",
|
||||
"âus": "ấu", "âuf": "ầu", "âur": "ẩu", "âux": "ẫu", "âuj": "ậu",
|
||||
"áua": "ấu", "àua": "ầu", "ảua": "ẩu", "ãua": "ẫu", "ạua": "ậu",
|
||||
"âys": "ấy", "âyf": "ầy", "âyr": "ẩy", "âyx": "ẫy", "âyj": "ậy",
|
||||
"áya": "ấy", "àya": "ầy", "ảya": "ẩy", "ãya": "ẫy", "ạya": "ậy",
|
||||
"ângs": "ấng", "ângf": "ầng", "ângr": "ẩng", "ângx": "ẫng", "ângj": "ậng",
|
||||
"ánga": "ấng", "ànga": "ầng", "ảnga": "ẩng", "ãnga": "ẫng", "ạnga": "ậng",
|
||||
|
||||
"ấcs": "âcs", "ấca": "áca", "âcsa": "acsa", "ácas": "acas",
|
||||
"ậcj": "âcj", "ậca": "ạca", "âcja": "acja", "ạcaj": "acaj",
|
||||
"ấms": "âms", "ấma": "áma", "âmsa": "amsa", "ámas": "amas",
|
||||
"ầmf": "âmf", "ầma": "àma", "âmfa": "amfa", "àmaf": "amaf",
|
||||
"ẩmr": "âmr", "ẩma": "ảma", "âmra": "amra", "ảmar": "amar",
|
||||
"ẫmx": "âmx", "ẫma": "ãma", "âmxa": "amxa", "ãmax": "amax",
|
||||
"ậmj": "âmj", "ậma": "ạma", "âmja": "amja", "ạmaj": "amaj",
|
||||
"ấns": "âns", "ấna": "ána", "ânsa": "ansa", "ánas": "anas",
|
||||
"ầnf": "ânf", "ầna": "àna", "ânfa": "anfa", "ànaf": "anaf",
|
||||
"ẩnr": "ânr", "ẩna": "ảna", "ânra": "anra", "ảnar": "anar",
|
||||
"ẫnx": "ânx", "ẫna": "ãna", "ânxa": "anxa", "ãnax": "anax",
|
||||
"ậnj": "ânj", "ậna": "ạna", "ânja": "anja", "ạnaj": "anaj",
|
||||
"ấps": "âps", "ấpa": "ápa", "âpsa": "apsa", "ápas": "apas",
|
||||
"ậpj": "âpj", "ậpa": "ạpa", "âpja": "apja", "ạpaj": "apaj",
|
||||
"ấts": "âts", "ấta": "áta", "âtsa": "atas", "átas": "atas",
|
||||
"ậtj": "âtj", "ậta": "ạta", "âtja": "atja", "ạtaj": "ataj",
|
||||
"ấus": "âus", "ấua": "áua", "âusa": "ausa", "áuas": "auas",
|
||||
"ầuf": "âuf", "ầua": "àua", "âufa": "aufa", "àuaf": "auaf",
|
||||
"ẩur": "âur", "ẩua": "ảua", "âura": "aura", "ảuar": "auar",
|
||||
"ẫux": "âux", "ẫua": "ãua", "âuxa": "auxa", "ãuax": "auax",
|
||||
"ậuj": "âuj", "ậua": "ạua", "âuja": "auja", "ạuaj": "auaj",
|
||||
"ấys": "âys", "ấya": "áya", "âysa": "aysa", "áyas": "ayas",
|
||||
"ầyf": "âyf", "ầya": "àya", "âyfa": "ayfa", "àyaf": "ayaf",
|
||||
"ẩyr": "âyr", "ẩya": "ảya", "âyra": "ayra", "ảyar": "ayar",
|
||||
"ẫyx": "âyx", "ẫya": "ãya", "âyxa": "ayxa", "ãyax": "ayax",
|
||||
"ậyj": "âyj", "ậya": "ạya", "âyja": "ayja", "ạyaj": "ayaj",
|
||||
"ấngs": "ângs", "ấnga": "ánga", "ângsa": "angsa", "ángas": "angas",
|
||||
"ầngf": "ângf", "ầnga": "ànga", "ângfa": "angfa", "àngaf": "angaf",
|
||||
"ẩngr": "ângr", "ẩnga": "ảnga", "ângra": "angra", "ảngar": "angar",
|
||||
"ẫngx": "ângx", "ẫnga": "ãnga", "ângxa": "angxa", "ãngax": "angax",
|
||||
"ậngj": "ângj", "ậnga": "ạnga", "ângja": "angja", "ạngaj": "angaj",
|
||||
|
||||
"êcs": "ếc", "êcj": "ệc",
|
||||
"éce": "ếc", "ẹce": "ệc",
|
||||
"êms": "ếm", "êmf": "ềm", "êmr": "ểm", "êmx": "ễm", "êmj": "ệm",
|
||||
"éme": "ếm", "ème": "ềm", "ẻme": "ểm", "ẽme": "ễm", "ẹme": "ệm",
|
||||
"êns": "ến", "ênf": "ền", "ênr": "ển", "ênx": "ễn", "ênj": "ện",
|
||||
"éne": "ến", "ène": "ền", "ẻne": "ển", "ẽne": "ễn", "ẹne": "ện",
|
||||
"êps": "ếp", "êpj": "ệp",
|
||||
"épe": "ếp", "ẹpe": "ệp",
|
||||
"êts": "ết", "êtj": "ệt",
|
||||
"éte": "ết", "ẹte": "ệt",
|
||||
"êchs": "ếch", "êchj": "ệch",
|
||||
"echs": "éch", "echj": "ẹch",
|
||||
"éche": "ếch", "ẹche": "ệch",
|
||||
"ênhs": "ếnh", "ênhf": "ềnh", "ênhr": "ểnh", "ênhx": "ễnh", "ênhj": "ệnh",
|
||||
"énhe": "ếnh", "ènhe": "ềnh", "ẻnhe": "ểnh", "ẽnhe": "ễnh", "ẹnhe": "ệnh",
|
||||
|
||||
"ếms": "êms", "ếme": "éme", "êmse": "emse", "émes": "emes",
|
||||
"ềmf": "êmf", "ềme": "ème", "êmfe": "emfe", "èmef": "emef",
|
||||
"ểmr": "êmr", "ểme": "ẻme", "êmre": "emre", "ẻmer": "emer",
|
||||
"ễmx": "êmx", "ễme": "ẽme", "êmxe": "emxe", "ẽmex": "emex",
|
||||
"ệmj": "êmj", "ệme": "ẹme", "êmje": "emje", "ẹmej": "emej",
|
||||
"ếns": "êns", "ếne": "éne", "ênse": "ense", "énes": "enes",
|
||||
"ềnf": "ênf", "ềne": "ène", "ênfe": "enfe", "ènef": "enef",
|
||||
"ểnr": "ênr", "ểne": "ẻne", "ênre": "enre", "ẻner": "ener",
|
||||
"ễnx": "ênx", "ễne": "ẽne", "ênxe": "enxe", "ẽnex": "enex",
|
||||
"ệnj": "ênj", "ệne": "ẹne", "ênje": "enje", "ẹnej": "enej",
|
||||
"ếps": "êps", "ếpe": "épe", "êpse": "epse", "épes": "epes",
|
||||
"ệpj": "êpj", "ệpe": "ẹpe", "êpje": "epje", "ẹpej": "epej",
|
||||
"ếts": "êts", "ếte": "éte", "êtse": "etes", "étes": "etes",
|
||||
"ệtj": "êtj", "ệte": "ẹte", "êtje": "etje", "ẹtej": "etej",
|
||||
"ếchs": "êchs", "ếche": "éche", "êchse": "eches", "éches": "eches",
|
||||
"ệchj": "êchj", "ệche": "ẹche", "êchje": "echje", "ẹchej": "echej",
|
||||
"ếnhs": "ênhs", "ếnhe": "énhe", "ênhse": "enhse", "énhes": "enhes",
|
||||
"ềnhf": "ênhf", "ềnhe": "ènhe", "ênhfe": "enhfe", "ènhef": "enhef",
|
||||
"ểnhr": "ênhr", "ểnhe": "ẻnhe", "ênhre": "enhre", "ẻnher": "enher",
|
||||
"ễnhx": "ênhx", "ễnhe": "ẽnhe", "ênhxe": "enhxe", "ẽnhex": "enhex",
|
||||
"ệnhj": "ênhj", "ệnhe": "ẹnhe", "ênhje": "enhje", "ẹnhej": "enhej",
|
||||
|
||||
"ôcs": "ốc", "ôcj": "ộc",
|
||||
"óco": "ốc", "ọco": "ộc",
|
||||
"ôis": "ối", "ôif": "ồi", "ôir": "ổi", "ôix": "ỗi", "ôij": "ội",
|
||||
"óio": "ối", "òio": "ồi", "ỏio": "ổi", "õio": "ỗi", "ọio": "ội",
|
||||
"ôms": "ốm", "ômf": "ồm", "ômr": "ổm", "ômx": "ỗm", "ômj": "ộm",
|
||||
"ómo": "ốm", "òmo": "ồm", "ỏmo": "ổm", "õmo": "ỗm", "ọmo": "ộm",
|
||||
"ôns": "ốn", "ônf": "ồn", "ônr": "ổn", "ônx": "ỗn", "ônj": "ộn",
|
||||
"óno": "ốn", "òno": "ồn", "ỏno": "ổn", "õno": "ỗn", "ọno": "ộn",
|
||||
"ôps": "ốp", "ôpj": "ộp",
|
||||
"ópo": "ốp", "ọpo": "ộp",
|
||||
"ôts": "ốt", "ôtj": "ột",
|
||||
"óto": "ốt", "ọto": "ột",
|
||||
"ôngs": "ống", "ôngf": "ồng", "ôngr": "ổng", "ôngx": "ỗng", "ôngj": "ộng",
|
||||
"óngo": "ống", "òngo": "ồng", "ỏngo": "ổng", "õngo": "ỗng", "ọngo": "ộng",
|
||||
|
||||
"ốcs": "ôcs", "ốco": "óco", "ôcso": "ocso", "ócos": "ocos",
|
||||
"ộcj": "ôcj", "ộco": "ọco", "ôcjo": "ocjo", "ọcoj": "ocoj",
|
||||
"ốis": "ôis", "ốio": "óio", "ôiso": "oiso", "óios": "oios",
|
||||
"ồif": "ôif", "ồio": "òio", "ôifo": "oifo", "òiof": "oiof",
|
||||
"ổir": "ôir", "ổio": "ỏio", "ôiro": "oiro", "ỏior": "oior",
|
||||
"ỗix": "ôix", "ỗio": "õio", "ôixo": "oixo", "õiox": "oiox",
|
||||
"ộij": "ôij", "ộio": "ọio", "ôijo": "oijo", "ọioj": "oioj",
|
||||
"ốms": "ôms", "ốmo": "ómo", "ômso": "omso", "ómos": "omos",
|
||||
"ồmf": "ômf", "ồmo": "òmo", "ômfo": "omfo", "òmof": "omof",
|
||||
"ổmr": "ômr", "ổmo": "ỏmo", "ômro": "omro", "ỏmor": "omor",
|
||||
"ỗmx": "ômx", "ỗmo": "õmo", "ômxo": "omxo", "õmox": "omox",
|
||||
"ộmj": "ômj", "ộmo": "ọmo", "ômjo": "omjo", "ọmoj": "omoj",
|
||||
"ốns": "ôns", "ốno": "óno", "ônso": "onso", "ónos": "onos",
|
||||
"ồnf": "ônf", "ồno": "òno", "ônfo": "onfo", "ònof": "onof",
|
||||
"ổnr": "ônr", "ổno": "ỏno", "ônro": "onro", "ỏnor": "onor",
|
||||
"ỗnx": "ônx", "ỗno": "õno", "ônxo": "onxo", "õnox": "onox",
|
||||
"ộnj": "ônj", "ộno": "ọno", "ônjo": "onjo", "ọnoj": "onoj",
|
||||
"ốps": "ôps", "ốpo": "ópo", "ôpso": "opso", "ópos": "opos",
|
||||
"ộpj": "ôpj", "ộpo": "ọpo", "ôpjo": "opjo", "ọpoj": "opoj",
|
||||
"ốts": "ôts", "ốto": "óto", "ôtso": "otso", "ótos": "otos",
|
||||
"ộtj": "ôtj", "ộto": "ọto", "ôtjo": "otjo", "ọtoj": "otoj",
|
||||
"ốngs": "ôngs", "ốngo": "óngo", "ôngso": "ongso", "óngos": "ongos",
|
||||
"ồngf": "ôngf", "ồngo": "òngo", "ôngfo": "ongfo", "òngof": "ongof",
|
||||
"ổngr": "ôngr", "ổngo": "ỏngo", "ôngro": "ongro", "ỏngor": "ongor",
|
||||
"ỗngx": "ôngx", "ỗngo": "õngo", "ôngxo": "ongxo", "õngox": "ongox",
|
||||
"ộngj": "ôngj", "ộngo": "ọngo", "ôngjo": "ongjo", "ọngoj": "ongoj",
|
||||
|
||||
"ơis": "ới", "ơif": "ời", "ơir": "ởi", "ơix": "ỡi", "ơij": "ợi",
|
||||
"óiw": "ới", "òiw": "ời", "ỏiw": "ởi", "õiw": "ỡi", "ọiw": "ợi",
|
||||
"ơms": "ớm", "ơmf": "ờm", "ơmr": "ởm", "ơmx": "ỡm", "ơmj": "ợm",
|
||||
"ómw": "ớm", "òmw": "ờm", "ỏmw": "ởm", "õmw": "ỡm", "ọmw": "ợm",
|
||||
"ơns": "ớn", "ơnf": "ờn", "ơnr": "ởn", "ơnx": "ỡn", "ơnj": "ợn",
|
||||
"ónw": "ớn", "ònw": "ờn", "ỏnw": "ởn", "õnw": "ỡn", "ọnw": "ợn",
|
||||
"ơps": "ớp", "ơpj": "ợp",
|
||||
"ópw": "ớp", "ọpw": "ợp",
|
||||
"ơts": "ớt", "ơtj": "ợt",
|
||||
"ótw": "ớt", "ọtw": "ợt",
|
||||
|
||||
"ớis": "ơis", "ớiw": "óiw", "ơisw": "oisw", "óiws": "oiws",
|
||||
"ờif": "ơif", "ờiw": "òiw", "ơifw": "oifw", "òiwf": "oiwf",
|
||||
"ởir": "ơir", "ởiw": "ỏiw", "ơirw": "oirw", "ỏiwr": "oiwr",
|
||||
"ỡix": "ơix", "ỡiw": "õiw", "ơixw": "oixw", "õiwx": "oiwx",
|
||||
"ợij": "ơij", "ợiw": "ọiw", "ơijw": "oijw", "ọiwj": "oiwj",
|
||||
"ớms": "ơms", "ớmw": "ómw", "ơmsw": "omsw", "ómws": "omws",
|
||||
"ờmf": "ơmf", "ờmw": "òmw", "ơmfw": "omfw", "òmwf": "omwf",
|
||||
"ởmr": "ơmr", "ởmw": "ỏmw", "ơmrw": "omrw", "ỏmwr": "omwr",
|
||||
"ỡmx": "ơmx", "ỡmw": "õmw", "ơmxw": "omxw", "õmwx": "omwx",
|
||||
"ợmj": "ơmj", "ợmw": "ọmw", "ơmjw": "omjw", "ọmwj": "omwj",
|
||||
"ớns": "ơns", "ớnw": "ónw", "ơnsw": "onsw", "ónws": "onws",
|
||||
"ờnf": "ơnf", "ờnw": "ònw", "ơnfw": "onfw", "ònwf": "onwf",
|
||||
"ởnr": "ơnr", "ởnw": "ỏnw", "ơnrw": "onrw", "ỏnwr": "onwr",
|
||||
"ỡnx": "ơnx", "ỡnw": "õnw", "ơnxw": "onxw", "õnwx": "onwx",
|
||||
"ợnj": "ơnj", "ợnw": "ọnw", "ơnjw": "onjw", "ọnwj": "onwj",
|
||||
"ớps": "ơps", "ớpw": "ópw", "ơpsw": "opsw", "ópws": "opws",
|
||||
"ợpj": "ơpj", "ợpw": "ọpw", "ơpjw": "opjw", "ọpwj": "opwj",
|
||||
"ớts": "ơts", "ớtw": "ótw", "ơtsw": "otsw", "ótws": "otws",
|
||||
"ợtj": "ơtj", "ợtw": "ọtw", "ơtjw": "otjw", "ọtwj": "otwj",
|
||||
|
||||
"ưas": "ứa", "ưaf": "ừa", "ưar": "ửa", "ưax": "ữa", "ưaj": "ựa",
|
||||
"úaw": "ứa", "ùaw": "ừa", "ủaw": "ửa", "ũaw": "ữa", "ụaw": "ựa",
|
||||
"ưis": "ứi", "ưif": "ừi", "ưir": "ửi", "ưix": "ữi", "ưij": "ựi",
|
||||
"úiw": "ứi", "ùiw": "ừi", "ủiw": "ửi", "ũiw": "ữi", "ụiw": "ựi",
|
||||
"ưms": "ứm", "ưmf": "ừm", "ưmr": "ửm", "ưmx": "ữm", "ưmj": "ựm",
|
||||
"úmw": "ứm", "ùmw": "ừm", "ủmw": "ửm", "ũmw": "ữm", "ụmw": "ựm",
|
||||
"ưns": "ứn", "ưnf": "ừn", "ưnr": "ửn", "ưnx": "ữn", "ưnj": "ựn",
|
||||
"únw": "ứn", "ùnw": "ừn", "ủnw": "ửn", "ũnw": "ữn", "ụnw": "ựn",
|
||||
"ưts": "ứt", "ưtj": "ựt",
|
||||
"útw": "ứt", "ụtw": "ựt",
|
||||
"ưus": "ứu", "ưuf": "ừu", "ưur": "ửu", "ưux": "ữu", "ưuj": "ựu",
|
||||
"úuw": "ứu", "ùuw": "ừu", "ủuw": "ửu", "ũuw": "ữu", "ụuw": "ựu",
|
||||
"ưngs": "ứng", "ưngf": "ừng", "ưngr": "ửng", "ưngx": "ững", "ưngj": "ựng",
|
||||
"úngw": "ứng", "ùngw": "ừng", "ủngw": "ửng", "ũngw": "ững", "ụngw": "ựng",
|
||||
|
||||
"ứas": "ưas", "ứaw": "úaw", "ưasw": "uasw", "úaws": "uaws",
|
||||
"ừaf": "ưaf", "ừaw": "ùaw", "ưafw": "uafw", "ùawf": "uawf",
|
||||
"ửar": "ưar", "ửaw": "ủaw", "ưarw": "uarw", "ủawr": "uawr",
|
||||
"ữax": "ưax", "ữaw": "ũaw", "ưaxw": "uaxw", "ũawx": "uawx",
|
||||
"ựaj": "ưaj", "ựaw": "ụaw", "ưajw": "uajw", "ụawj": "uawj",
|
||||
"ứis": "ưis", "ứiw": "úiw", "ưisw": "uisw", "úiws": "uiws",
|
||||
"ừif": "ưif", "ừiw": "ùiw", "ưifw": "uifw", "ùiwf": "uiwf",
|
||||
"ửir": "ưir", "ửiw": "ủiw", "ưirw": "uirw", "ủiwr": "uiwr",
|
||||
"ữix": "ưix", "ữiw": "ũiw", "ưixw": "uixw", "ũiwx": "uiwx",
|
||||
"ựij": "ưij", "ựiw": "ụiw", "ưijw": "uijw", "ụiwj": "uiwj",
|
||||
"ứms": "ưms", "ứmw": "úmw", "ưmsw": "umsw", "úmws": "umws",
|
||||
"ừmf": "ưmf", "ừmw": "ùmw", "ưmfw": "umfw", "ùmwf": "umwf",
|
||||
"ửmr": "ưmr", "ửmw": "ủmw", "ưmrw": "umrw", "ủmwr": "umwr",
|
||||
"ữmx": "ưmx", "ữmw": "ũmw", "ưmxw": "umxw", "ũmwx": "umwx",
|
||||
"ựmj": "ưmj", "ựmw": "ụmw", "ưmjw": "umjw", "ụmwj": "umwj",
|
||||
"ứns": "ưns", "ứnw": "únw", "ưnsw": "unsw", "únws": "unws",
|
||||
"ừnf": "ưnf", "ừnw": "ùnw", "ưnfw": "unfw", "ùnwf": "unwf",
|
||||
"ửnr": "ưnr", "ửnw": "ủnw", "ưnrw": "unrw", "ủnwr": "unwr",
|
||||
"ữnx": "ưnx", "ữnw": "ũnw", "ưnxw": "unxw", "ũnwx": "unwx",
|
||||
"ựnj": "ưnj", "ựnw": "ụnw", "ưnjw": "unjw", "ụnwj": "unwj",
|
||||
"ứts": "ưts", "ứtw": "útw", "ưtsw": "utsw", "útws": "utws",
|
||||
"ựtj": "ưtj", "ựtw": "ụtw", "ưtjw": "utjw", "ụtwj": "utwj",
|
||||
"ứus": "ưus", "ứuw": "úuw", "ưusw": "uusw", "úuws": "uuws",
|
||||
"ừuf": "ưuf", "ừuw": "ùuw", "ưufw": "uufw", "ùuwf": "uuwf",
|
||||
"ửur": "ưur", "ửuw": "ủuw", "ưurw": "uurw", "ủuwr": "uuwr",
|
||||
"ữux": "ưux", "ữuw": "ũuw", "ưuxw": "uuxw", "ũuwx": "uuwx",
|
||||
"ựuj": "ưuj", "ựuw": "ụuw", "ưujw": "uujw", "ụuwj": "uuwj",
|
||||
"ứngs": "ưngs", "ứngw": "úngw", "ưngsw": "ungsw", "úngws": "ungws",
|
||||
"ừngf": "ưngf", "ừngw": "ùngw", "ưngfw": "ungfw", "ùngwf": "ungwf",
|
||||
"ửngr": "ưngr", "ửngw": "ủngw", "ưngrw": "ungrw", "ủngwr": "ungwr",
|
||||
"ữngx": "ưngx", "ữngw": "ũngw", "ưngxw": "ungxw", "ũngwx": "ungwx",
|
||||
"ựngj": "ưngj", "ựngw": "ụngw", "ưngjw": "ungjw", "ụngwj": "ungwj",
|
||||
|
||||
"iems": "iém", "iemf": "ièm", "iemr": "iẻm", "iemx": "iẽm", "iemj": "iẹm",
|
||||
"iéme": "iếm", "ième": "iềm", "iẻme": "iểm", "iẽme": "iễm", "iẹme": "iệm",
|
||||
"iêms": "iếm", "iêmf": "iềm", "iêmr": "iểm", "iêmx": "iễm", "iêmj": "iệm",
|
||||
"iens": "ién", "ienf": "ièn", "ienr": "iẻn", "ienx": "iẽn", "ienj": "iẹn",
|
||||
"iéne": "iến", "iène": "iền", "iẻne": "iển", "iẽne": "iễn", "iẹne": "iện",
|
||||
"iêns": "iến", "iênf": "iền", "iênr": "iển", "iênx": "iễn", "iênj": "iện",
|
||||
"ieps": "iép", "iepj": "iẹp",
|
||||
"iépe": "iếp", "iẹpe": "iệp",
|
||||
"iêps": "iếp", "iêpj": "iệp",
|
||||
"iets": "iét", "ietj": "iẹt",
|
||||
"iéte": "iết", "iẹte": "iệt",
|
||||
"iêts": "iết", "iêtj": "iệt",
|
||||
"ieus": "iéu", "ieuf": "ièu", "ieur": "iẻu", "ieux": "iẽu", "ieuj": "iẹu",
|
||||
"iéue": "iếu", "ièue": "iều", "iẻue": "iểu", "iẽue": "iễu", "iẹue": "iệu",
|
||||
"iêus": "iếu", "iêuf": "iều", "iêur": "iểu", "iêux": "iễu", "iêuj": "iệu",
|
||||
"iengs": "iéng", "iengf": "ièng", "iengr": "iẻng", "iengx": "iẽng", "iengj": "iẹng",
|
||||
"iénge": "iếng", "iènge": "iềng", "iẻnge": "iểng", "iẽnge": "iễng", "iẹnge": "iệng",
|
||||
"iêngs": "iếng", "iêngf": "iềng", "iêngr": "iểng", "iêngx": "iễng", "iêngj": "iệng",
|
||||
|
||||
"iếms": "iêms", "iếme": "iéme", "iêmse": "iemse", "iémes": "iemes",
|
||||
"iềmf": "iêmf", "iềme": "ième", "iêmfe": "iemfe", "ièmef": "iemef",
|
||||
"iểmr": "iêmr", "iểme": "iẻme", "iêmre": "iemre", "iẻmer": "iemer",
|
||||
"iễmx": "iêmx", "iễme": "iẽme", "iêmxe": "iemxe", "iẽmex": "iemex",
|
||||
"iệmj": "iêmj", "iệme": "iẹme", "iêmje": "iemje", "iẹmej": "iemej",
|
||||
"iếns": "iêns", "iếne": "iéne", "iênse": "iense", "iénes": "ienes",
|
||||
"iềnf": "iênf", "iềne": "iène", "iênfe": "ienfe", "iènef": "ienef",
|
||||
"iểnr": "iênr", "iểne": "iẻne", "iênre": "ienre", "iẻner": "iener",
|
||||
"iễnx": "iênx", "iễne": "iẽne", "iênxe": "ienxe", "iẽnex": "ienex",
|
||||
"iệnj": "iênj", "iệne": "iẹne", "iênje": "ienje", "iẹnej": "ienej",
|
||||
"iếps": "iêps", "iếpe": "iépe", "iêpse": "iepse", "iépes": "iepes",
|
||||
"iệpj": "iêpj", "iệpe": "iẹpe", "iêpje": "iepje", "iẹpej": "iepej",
|
||||
"iếts": "iêts", "iếte": "iéte", "iêtse": "ietse", "iétes": "ietes",
|
||||
"iệtj": "iêtj", "iệte": "iẹte", "iêtje": "ietje", "iẹtej": "ietej",
|
||||
"iếus": "iêus", "iếue": "iéue", "iêuse": "ieuse", "iéues": "ieues",
|
||||
"iềuf": "iêuf", "iềue": "ièue", "iêufe": "ieufe", "ièuef": "ieuef",
|
||||
"iểur": "iêur", "iểue": "iẻue", "iêure": "ieure", "iẻuer": "ieuer",
|
||||
"iễux": "iêux", "iễue": "iẽue", "iêuxe": "ieuxe", "iẽuex": "ieuex",
|
||||
"iệuj": "iêuj", "iệue": "iẹue", "iêuje": "ieuje", "iẹuej": "ieuej",
|
||||
"iếngs": "iêngs", "iếnge": "iénge", "iêngse": "iengse", "iénges": "ienges",
|
||||
"iềngf": "iêngf", "iềnge": "iènge", "iêngfe": "iengfe", "ièngef": "iengef",
|
||||
"iểngr": "iêngr", "iểnge": "iẻnge", "iêngre": "iengre", "iẻnger": "ienger",
|
||||
"iễngx": "iêngx", "iễnge": "iẽnge", "iêngxe": "iengxe", "iẽngex": "iengex",
|
||||
"iệngj": "iêngj", "iệnge": "iẹnge", "iêngje": "iengje", "iẹngej": "iengej",
|
||||
|
||||
"uyens": "uyén", "uyenf": "uyèn", "uyenr": "uyẻn", "uyenx": "uyẽn", "uyenj": "uyẹn",
|
||||
"uyéne": "uyến", "uyène": "uyền", "uyẻne": "uyển", "uyẽne": "uyễn", "uyẹne": "uyện",
|
||||
"uyêns": "uyến", "uyênf": "uyền", "uyênr": "uyển", "uyênx": "uyễn", "uyênj": "uyện",
|
||||
"uyets": "uyét", "uyetf": "uyèt", "uyetr": "uyẻt", "uyetx": "uyẽt", "uyetj": "uyẹt",
|
||||
"uyéte": "uyết", "uyète": "uyềt", "uyẻte": "uyểt", "uyẽte": "uyễt", "uyẹte": "uyệt",
|
||||
"uyêts": "uyết", "uyêtf": "uyềt", "uyêtr": "uyểt", "uyêtx": "uyễt", "uyêtj": "uyệt",
|
||||
|
||||
"uyếns": "uyêns", "uyếne": "uyéne", "uyênse": "uyense", "uyénes": "uyenes",
|
||||
"uyềnf": "uyênf", "uyềne": "uyène", "uyênfe": "uyenfe", "uyènef": "uyenef",
|
||||
"uyểnr": "uyênr", "uyểne": "uyẻne", "uyênre": "uyenre", "uyẻner": "uyener",
|
||||
"uyễnx": "uyênx", "uyễne": "uyẽne", "uyênxe": "uyenxe", "uyẽnex": "uyenex",
|
||||
"uyệnj": "uyênj", "uyệne": "uyẹne", "uyênje": "uyenje", "uyẹnej": "uyenej",
|
||||
"uyếts": "uyêts", "uyếte": "uyéte", "uyêtse": "uyetse", "uyétes": "uyetes",
|
||||
"uyềtf": "uyêtf", "uyềte": "uyète", "uyêtfe": "uyetfe", "uyètef": "uyetef",
|
||||
"uyểtr": "uyêtr", "uyểte": "uyẻte", "uyêtre": "uyetre", "uyẻter": "uyeter",
|
||||
"uyễtx": "uyêtx", "uyễte": "uyẽte", "uyêtxe": "uyetxe", "uyẽtex": "uyetex",
|
||||
"uyệtj": "uyêtj", "uyệte": "uyẹte", "uyêtje": "uyetje", "uyẹtej": "uyetej",
|
||||
|
||||
"uyts": "uýt", "uytj": "uỵt",
|
||||
"uynhs": "uýnh", "uynhf": "uỳnh", "uynhr": "uỷnh", "uynhx": "uỹnh", "uynhj": "uỵnh",
|
||||
|
||||
"uýts": "uyts", "uỵtj": "uytj",
|
||||
"uýnhs": "uynhs", "uỳnhf": "uynhf", "uỷnhr": "uynhr", "uỹnh": "uynhx", "uỵnhj": "uynhj",
|
||||
|
||||
"uits": "uít", "uitj": "uịt",
|
||||
|
||||
"uíts": "uits", "uịtj": "uitj",
|
||||
|
||||
"uos": "úo", "uof": "ùo", "uor": "ủo", "uox": "ũo", "uoj": "ụo",
|
||||
"úoc": "uóc", "ụoc": "uọc",
|
||||
"uocs": "uóc", "uocj": "uọc",
|
||||
"uócw": "ước", "uọcw": "ược",
|
||||
"ươcs": "ước", "ươcj": "ược",
|
||||
"úoi": "uói", "ùoi" : "uòi", "ủoi": "uỏi", "ũoi": "uõi", "ụoi": "uọi",
|
||||
"uois": "uói", "uoif": "uòi", "uoir": "uỏi", "uoix": "uõi", "uoij": "uọi",
|
||||
"uóiw": "ưới", "uòiw": "ười", "uỏiw": "ưởi", "uõiw": "ưỡi", "uọiw": "ượi",
|
||||
"ươis": "ưới", "ươif": "ười", "ươir": "ưởi", "ươix": "ưỡi", "ươij": "ượi",
|
||||
"úom": "uóm", "ùom" : "uòm", "ủom": "uỏm", "ũom": "uõm", "ụom": "uọm",
|
||||
"uoms": "uóm", "uomf": "uòm", "uomr": "uỏm", "uomx": "uõm", "uomj": "uọm",
|
||||
"uómw": "ướm", "uòmw": "ườm", "uỏmw": "ưởm", "uõmw": "ưỡm", "uọmw": "ượm",
|
||||
"ươms": "ướm", "ươmf": "ườm", "ươmr": "ưởm", "ươmx": "ưỡm", "ươmj": "ượm",
|
||||
"úon": "uón", "ùon" : "uòn", "ủon": "uỏn", "ũon": "uõn", "ụon": "uọn",
|
||||
"uons": "uón", "uonf": "uòn", "uonr": "uỏn", "uonx": "uõn", "uonj": "uọn",
|
||||
"uónw": "ướn", "uònw": "ườn", "uỏnw": "ưởn", "uõnw": "ưỡn", "uọnw": "ượn",
|
||||
"ươns": "ướn", "ươnf": "ườn", "ươnr": "ưởn", "ươnx": "ưỡn", "ươnj": "ượn",
|
||||
"úop": "uóp", "ụop": "uọp",
|
||||
"uops": "uóp", "uopj": "uọp",
|
||||
"uópw": "ướp", "uọpw": "ượp",
|
||||
"ươps": "ướp", "ươpj": "ượp",
|
||||
"úot": "uót", "ụot": "uọt",
|
||||
"uots": "uót", "uotj": "uọt",
|
||||
"uótw": "ướt", "uọtw": "ượt",
|
||||
"ươts": "ướt", "ươtj": "ượt",
|
||||
"úou": "uóu", "ùou" : "uòu", "ủou": "uỏu", "ũou": "uõu", "ụou": "uọu",
|
||||
"uous": "uóu", "uouf": "uòu", "uour": "uỏu", "uoux": "uõu", "uouj": "uọu",
|
||||
"uóuw": "ướu", "uòuw": "ườu", "uỏuw": "ưởu", "uõuw": "ưỡu", "uọuw": "ượu",
|
||||
"ươus": "ướu", "ươuf": "ườu", "ươur": "ưởu", "ươux": "ưỡu", "ươuj": "ượu",
|
||||
"úong": "uóng", "ùong" : "uòng", "ủong": "uỏng", "ũong": "uõng", "ụong": "uọng",
|
||||
"uongs": "uóng", "uongf": "uòng", "uongr": "uỏng", "uongx": "uõng", "uongj": "uọng",
|
||||
"uóngw": "ướng", "uòngw": "ường", "uỏngw": "ưởng", "uõngw": "ưỡng", "uọngw": "ượng",
|
||||
"ươngs": "ướng", "ươngf": "ường", "ươngr": "ưởng", "ươngx": "ưỡng", "ươngj": "ượng",
|
||||
|
||||
"úos": "uos", "ùof": "uof", "ủor": "uor", "ũo": "uox", "ụoj": "uoj",
|
||||
"uócs": "uocs", "uọcj": "uocj",
|
||||
"ướcs": "ươcs", "ướcw": "uócw", "ươcsw": "uocsw", "uócws": "uocws",
|
||||
"ượcj": "ươcj", "ượcw": "uọcw", "ươcjw": "uocjw", "uọcwj": "uocwj",
|
||||
"uóis": "uois", "uòif": "uoif", "uỏir": "uoir", "uõix": "uoix", "uọij": "uoij",
|
||||
"ướis": "ươis", "ướiw": "uóiw", "ươisw": "uoisw", "uóiws": "uoiws",
|
||||
"ườif": "ươif", "ườiw": "uòiw", "ươifw": "uoifw", "uòiwf": "uoiwf",
|
||||
"ưởir": "ươir", "ưởiw": "uỏiw", "ươirw": "uoirw", "uỏiwr": "uoiwr",
|
||||
"ưỡix": "ươix", "ưỡiw": "uõiw", "ươixw": "uoixw", "uõiwx": "uoiwx",
|
||||
"ượij": "ươij", "ượiw": "uóiw", "ươijw": "uoijw", "uọiwj": "uoiwj",
|
||||
"uóms": "uoms", "uòmf": "uomf", "uỏmr": "uomr", "uõmx": "uomx", "uọmj": "uomj",
|
||||
"ướms": "ươms", "ướmw": "uómw", "ươmsw": "uomsw", "uómws": "uomws",
|
||||
"ườmf": "ươmf", "ườmw": "uòmw", "ươmfw": "uomfw", "uòmwf": "uomwf",
|
||||
"ưởmr": "ươmr", "ưởmw": "uỏmw", "ươmrw": "uomrw", "uỏmwr": "uomwr",
|
||||
"ưỡmx": "ươmx", "ưỡmw": "uõmw", "ươmxw": "uomxw", "uõmwx": "uomwx",
|
||||
"ượmj": "ươmj", "ượmw": "uómw", "ươmjw": "uomjw", "uọmwj": "uomwj",
|
||||
"uóns": "uons", "uònf": "uonf", "uỏnr": "uonr", "uõnx": "uonx", "uọnj": "uonj",
|
||||
"ướns": "ươns", "ướnw": "uónw", "ươnsw": "uonsw", "uónws": "uonws",
|
||||
"ườnf": "ươnf", "ườnw": "uònw", "ươnfw": "uonfw", "uònwf": "uonwf",
|
||||
"ưởnr": "ươnr", "ưởnw": "uỏnw", "ươnrw": "uonrw", "uỏnwr": "uonwr",
|
||||
"ưỡnx": "ươnx", "ưỡnw": "uõnw", "ươnxw": "uonxw", "uõnwx": "uonwx",
|
||||
"ượnj": "ươnj", "ượnw": "uónw", "ươnjw": "uonjw", "uọnwj": "uonwj",
|
||||
"uóps": "uops", "uọpj": "uopj",
|
||||
"ướps": "ươps", "ướpw": "uópw", "ươpsw": "uopsw", "uópws": "uopws",
|
||||
"ượpj": "ươpj", "ượpw": "uọpw", "ươpjw": "uopjw", "uọpwj": "uopwj",
|
||||
"uóts": "uots", "uọtj": "uotj",
|
||||
"ướts": "ươts", "ướtw": "uótw", "ươtsw": "uotsw", "uótws": "uotws",
|
||||
"ượtj": "ươtj", "ượtw": "uọtw", "ươtjw": "uotjw", "uọtwj": "uotwj",
|
||||
"uóus": "uous", "uòuf": "uouf", "uỏur": "uour", "uõux": "uoux", "uọuj": "uouj",
|
||||
"ướus": "ươus", "ướuw": "uóuw", "ươusw": "uousw", "uóuws": "uouws",
|
||||
"ườuf": "ươuf", "ườuw": "uòuw", "ươufw": "uoufw", "uòuwf": "uouwf",
|
||||
"ưởur": "ươur", "ưởuw": "uỏuw", "ươurw": "uourw", "uỏuwr": "uouwr",
|
||||
"ưỡux": "ươux", "ưỡuw": "uõuw", "ươuxw": "uouxw", "uõuwx": "uouwx",
|
||||
"ượuj": "ươuj", "ượuw": "uóuw", "ươujw": "uoujw", "uọuwj": "uouwj",
|
||||
"uóngs": "uongs", "uòngf": "uongf", "uỏngr": "uongr", "uõngx": "uongx", "uọngj": "uongj",
|
||||
"ướngs": "ươngs", "ướngw": "uóngw", "ươngsw": "uongsw", "uóngws": "uongws",
|
||||
"ườngf": "ươngf", "ườngw": "uòngw", "ươngfw": "uongfw", "uòngwf": "uongwf",
|
||||
"ưởngr": "ươngr", "ưởngw": "uỏngw", "ươngrw": "uongrw", "uỏngwr": "uongwr",
|
||||
"ưỡngx": "ươngx", "ưỡngw": "uõngw", "ươngxw": "uongxw", "uõngwx": "uongwx",
|
||||
"ượngj": "ươngj", "ượngw": "uóngw", "ươngjw": "uongjw", "uọngwj": "uongwj",
|
||||
|
||||
"uóco": "uốc", "uọco": "uộc",
|
||||
"uôcs": "uốc", "uôcj": "uộc",
|
||||
"uóio": "uối", "uòio": "uồi", "uỏio": "uổi", "uõio": "uỗi", "uọio": "uội",
|
||||
"uôis": "uối", "uôif": "uồi", "uôir": "uổi", "uôix": "uỗi", "uôij": "uội",
|
||||
"uómo": "uốm", "uòmo": "uồm", "uỏmo": "uổm", "uõmo": "uỗm", "uọmo": "uộm",
|
||||
"uôms": "uốm", "uômf": "uồm", "uômr": "uổm", "uômx": "uỗm", "uômj": "uộm",
|
||||
"uóno": "uốn", "uòno": "uồn", "uỏno": "uổn", "uõno": "uỗn", "uọno": "uộn",
|
||||
"uôns": "uốn", "uônf": "uồn", "uônr": "uổn", "uônx": "uỗn", "uônj": "uộn",
|
||||
"uópo": "uốp", "uọpo": "uộp",
|
||||
"uôps": "uốp", "uôpj": "uộp",
|
||||
"uóto": "uốt", "uọto": "uột",
|
||||
"uôts": "uốt", "uôtj": "uột",
|
||||
"uóuo": "uốu", "uòuo": "uồu", "uỏuo": "uổu", "uõuo": "uỗu", "uọuo": "uộu",
|
||||
"uôus": "uốu", "uôuf": "uồu", "uôur": "uổu", "uôux": "uỗu", "uôuj": "uộu",
|
||||
"uóngo": "uống", "uòngo": "uồng", "uỏngo": "uổng", "uõngo": "uỗng", "uọngo": "uộng",
|
||||
"uôngs": "uống", "uôngf": "uồng", "uôngr": "uổng", "uôngx": "uỗng", "uôngj": "uộng",
|
||||
|
||||
"uốcs": "uôcs", "uốco": "uóco", "uôcso": "uocso", "uócos": "uocos",
|
||||
"uộcj": "uôcj", "uộco": "uọco", "uôcjo": "uocjo", "uọcoj": "uocoj",
|
||||
"uốis": "uôis", "uốio": "uóio", "uôiso": "uoiso", "uóios": "uoios",
|
||||
"uồif": "uôif", "uồio": "uòio", "uôifo": "uoifo", "uòiof": "uoiof",
|
||||
"uổir": "uôir", "uổio": "uỏio", "uôiro": "uoiro", "uỏior": "uoior",
|
||||
"uỗix": "uôix", "uỗio": "uõio", "uôixo": "uoixo", "uõiox": "uoiox",
|
||||
"uộij": "uôij", "uộio": "uóio", "uôijo": "uoijo", "uọioj": "uoioj",
|
||||
"uốms": "uôms", "uốmo": "uómo", "uômso": "uomso", "uómos": "uomos",
|
||||
"uồmf": "uômf", "uồmo": "uòmo", "uômfo": "uomfo", "uòmof": "uomof",
|
||||
"uổmr": "uômr", "uổmo": "uỏmo", "uômro": "uomro", "uỏmor": "uomor",
|
||||
"uỗmx": "uômx", "uỗmo": "uõmo", "uômxo": "uomxo", "uõmox": "uomox",
|
||||
"uộmj": "uômj", "uộmo": "uómo", "uômjo": "uomjo", "uọmoj": "uomoj",
|
||||
"uốns": "uôns", "uốno": "uóno", "uônso": "uonso", "uónos": "uonos",
|
||||
"uồnf": "uônf", "uồno": "uòno", "uônfo": "uonfo", "uònof": "uonof",
|
||||
"uổnr": "uônr", "uổno": "uỏno", "uônro": "uonro", "uỏnor": "uonor",
|
||||
"uỗnx": "uônx", "uỗno": "uõno", "uônxo": "uonxo", "uõnox": "uonox",
|
||||
"uộnj": "uônj", "uộno": "uóno", "uônjo": "uonjo", "uọnoj": "uonoj",
|
||||
"uốps": "uôps", "uốpo": "uópo", "uôpso": "uopso", "uópos": "uopos",
|
||||
"uộpj": "uôpj", "uộpo": "uọpo", "uôpjo": "uopjo", "uọpoj": "uopoj",
|
||||
"uốts": "uôts", "uốto": "uóto", "uôtso": "uotso", "uótos": "uotos",
|
||||
"uộtj": "uôtj", "uộto": "uọto", "uôtjo": "uotjo", "uọtoj": "uotoj",
|
||||
"uốus": "uôus", "uốuo": "uóuo", "uôuso": "uouso", "uóuos": "uouos",
|
||||
"uồuf": "uôuf", "uồuo": "uòuo", "uôufo": "uoufo", "uòuof": "uouof",
|
||||
"uổur": "uôur", "uổuo": "uỏuo", "uôuro": "uouro", "uỏuor": "uouor",
|
||||
"uỗux": "uôux", "uỗuo": "uõuo", "uôuxo": "uouxo", "uõuox": "uouox",
|
||||
"uộuj": "uôuj", "uộuo": "uóuo", "uôujo": "uoujo", "uọuoj": "uouoj",
|
||||
"uốngs": "uôngs", "uốngo": "uóngo", "uôngso": "uongso", "uóngos": "uongos",
|
||||
"uồngf": "uôngf", "uồngo": "uòngo", "uôngfo": "uongfo", "uòngof": "uongof",
|
||||
"uổngr": "uôngr", "uổngo": "uỏngo", "uôngro": "uongro", "uỏngor": "uongor",
|
||||
"uỗngx": "uôngx", "uỗngo": "uõngo", "uôngxo": "uongxo", "uõngox": "uongox",
|
||||
"uộngj": "uôngj", "uộngo": "uóngo", "uôngjo": "uongjo", "uọngoj": "uongoj",
|
||||
|
||||
"yes": "ýe", "yef": "ỳe", "yer": "ỷe", "yex": "ỹe", "yej": "ỵe",
|
||||
"ýem": "yém", "ỳem": "yèm", "ỷem": "yẻm", "ỹem": "yẽm", "ỵem": "yẹm",
|
||||
"yems": "yém", "yemf": "yèm", "yemr": "yẻm", "yemx": "yẽm", "yemj": "yẹm",
|
||||
"yêms": "yếm", "yêmf": "yềm", "yêmr": "yểm", "yêmx": "yễm", "yêmj": "yệm",
|
||||
"yéme": "yếm", "yème": "yềm", "yẻme": "yểm", "yẽme": "yễm", "yẹme": "yệm",
|
||||
"ýen": "yén", "ỳen": "yèn", "ỷen": "yẻn", "ỹen": "yẽn", "ỵen": "yẹn",
|
||||
"yens": "yén", "yenf": "yèn", "yenr": "yẻn", "yenx": "yẽn", "yenj": "yẹn",
|
||||
"yêns": "yến", "yênf": "yền", "yênr": "yển", "yênx": "yễn", "yênj": "yện",
|
||||
"yéne": "yến", "yène": "yền", "yẻne": "yển", "yẽne": "yễn", "yẹne": "yện",
|
||||
"ýet": "yét", "ỵet": "yẹt",
|
||||
"yets": "yét", "yetj": "yẹt",
|
||||
"yêts": "yết", "yêtj": "yệt",
|
||||
"yéte": "yết", "yẹte": "yệt",
|
||||
"ýeu": "yéu", "ỳeu": "yèu", "ỷeu": "yẻu", "ỹeu": "yẽu", "ỵeu": "yẹu",
|
||||
"yeus": "yéu", "yeuf": "yèu", "yeur": "yẻu", "yeux": "yẽu", "yeuj": "yẹu",
|
||||
"yêus": "yếu", "yêuf": "yều", "yêur": "yểu", "yêux": "yễu", "yêuj": "yệu",
|
||||
"yéue": "yếu", "yèue": "yều", "yẻue": "yểu", "yẽue": "yễu", "yẹue": "yệu",
|
||||
"ýeng": "yéng", "ỳeng": "yèng", "ỷeng": "yẻng", "ỹeng": "yẽng", "ỵeng": "yẹng",
|
||||
"yengs": "yéng", "yengf": "yèng", "yengr": "yẻng", "yengx": "yẽng", "yengj": "yẹng",
|
||||
"yêngs": "yếng", "yêngf": "yềng", "yêngr": "yểng", "yêngx": "yễng", "yêngj": "yệng",
|
||||
"yénge": "yếng", "yènge": "yềng", "yẻnge": "yểng", "yẽnge": "yễng", "yẹnge": "yệng",
|
||||
|
||||
"ýes": "yes", "ỳef": "yef", "ỷer": "yer", "ỹex": "yex", "ỵej": "yej",
|
||||
"yếms": "yêms", "yếme": "yéme", "yêmse": "yemse", "yémes": "yemes",
|
||||
"yềmf": "yêmf", "yềme": "yème", "yêmfe": "yemfe", "yèmef": "yemef",
|
||||
"yểmr": "yêmr", "yểme": "yẻme", "yêmre": "yemre", "yẻmer": "yemer",
|
||||
"yễmx": "yêmx", "yễme": "yẽme", "yêmxe": "yemxe", "yẽmex": "yemex",
|
||||
"yệmj": "yêmj", "yệme": "yẹme", "yêmje": "yemje", "yẹmej": "yemej",
|
||||
"yếns": "yêns", "yếne": "yéne", "yênse": "yense", "yénes": "yenes",
|
||||
"yềnf": "yênf", "yềne": "yène", "yênfe": "yenfe", "yènef": "yenef",
|
||||
"yểnr": "yênr", "yểne": "yẻne", "yênre": "yenre", "yẻner": "yener",
|
||||
"yễnx": "yênx", "yễne": "yẽne", "yênxe": "yenxe", "yẽnex": "yenex",
|
||||
"yệnj": "yênj", "yệne": "yẹne", "yênje": "yenje", "yẹnej": "yenej",
|
||||
"yếts": "yêts", "yếte": "yéte", "yêtse": "yetse", "yétes": "yetes",
|
||||
"yệtj": "yêtj", "yệte": "yẹte", "yêtje": "yetje", "yẹtej": "yetej",
|
||||
"yếus": "yêus", "yếue": "yéue", "yêuse": "yeuse", "yéues": "yeues",
|
||||
"yềuf": "yêuf", "yềue": "yèue", "yêufe": "yeufe", "yèuef": "yeuef",
|
||||
"yểur": "yêur", "yểue": "yẻue", "yêure": "yeure", "yẻuer": "yeuer",
|
||||
"yễux": "yêux", "yễue": "yẽue", "yêuxe": "yeuxe", "yẽuex": "yeuex",
|
||||
"yệuj": "yêuj", "yệue": "yẹue", "yêuje": "yeuje", "yẹuej": "yeuej",
|
||||
"yếngs": "yêngs", "yếnge": "yénge", "yêngse": "yengse", "yénges": "yenges",
|
||||
"yềngf": "yêngf", "yềnge": "yènge", "yêngfe": "yengfe", "yèngef": "yengef",
|
||||
"yểngr": "yêngr", "yểnge": "yẻnge", "yêngre": "yengre", "yẻnger": "yenger",
|
||||
"yễngx": "yêngx", "yễnge": "yẽnge", "yêngxe": "yengxe", "yẽngex": "yengex",
|
||||
"yệngj": "yêngj", "yệnge": "yẹnge", "yêngje": "yengje", "yẹngej": "yengej"
|
||||
}
|
||||
}
|
||||
]
|
||||
|
||||
@@ -9,6 +9,18 @@
|
||||
"license": "apache-2.0"
|
||||
},
|
||||
"currencySets": [
|
||||
{
|
||||
"id": "armenian_dram",
|
||||
"label": "Armenian dram (֏)",
|
||||
"slots": [
|
||||
{ "code": 1423, "label": "֏" },
|
||||
{ "code": 36, "label": "$" },
|
||||
{ "code": 8364, "label": "€" },
|
||||
{ "code": 162, "label": "¢" },
|
||||
{ "code": 163, "label": "£" },
|
||||
{ "code": 165, "label": "¥" }
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "azerbaijani_manat",
|
||||
"label": "Azerbaijani manat (₼)",
|
||||
@@ -33,6 +45,18 @@
|
||||
{ "code": 165, "label": "¥" }
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "costa_rican_colon",
|
||||
"label": "Costa Rican colón (₡)",
|
||||
"slots": [
|
||||
{ "code": 8353, "label": "₡" },
|
||||
{ "code": 36, "label": "$" },
|
||||
{ "code": 8364, "label": "€" },
|
||||
{ "code": 162, "label": "¢" },
|
||||
{ "code": 163, "label": "£" },
|
||||
{ "code": 165, "label": "¥" }
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "dollar",
|
||||
"label": "Dollar ($)",
|
||||
|
||||
@@ -17,6 +17,26 @@
|
||||
"direction": "rtl",
|
||||
"modifier": "org.florisboard.layouts:arabic"
|
||||
},
|
||||
{
|
||||
"id": "western_armenian",
|
||||
"label": "Armenian (Western)",
|
||||
"authors": [ "PJTSearch" ],
|
||||
"direction": "ltr",
|
||||
"modifier": "org.florisboard.layouts:armenian"
|
||||
},
|
||||
{
|
||||
"id": "eastern_armenian",
|
||||
"label": "Armenian (Eastern)",
|
||||
"authors": [ "PJTSearch" ],
|
||||
"direction": "ltr",
|
||||
"modifier": "org.florisboard.layouts:armenian"
|
||||
},
|
||||
{
|
||||
"id": "azerbaijani",
|
||||
"label": "Azerbaijani",
|
||||
"authors": [ "nijatismayilzada" ],
|
||||
"direction": "ltr"
|
||||
},
|
||||
{
|
||||
"id": "azerty",
|
||||
"label": "AZERTY",
|
||||
@@ -72,6 +92,12 @@
|
||||
"authors": [ "patrickgold" ],
|
||||
"direction": "ltr"
|
||||
},
|
||||
{
|
||||
"id": "colemak_dh",
|
||||
"label": "ColemakDH",
|
||||
"authors": [ "blucin" ],
|
||||
"direction": "ltr"
|
||||
},
|
||||
{
|
||||
"id": "danish",
|
||||
"label": "Danish (QWERTY)",
|
||||
@@ -85,6 +111,13 @@
|
||||
"direction": "ltr",
|
||||
"modifier": "org.florisboard.layouts:dvorak"
|
||||
},
|
||||
{
|
||||
"id": "dvorak_es",
|
||||
"label": "Dvorak (ÑÇ)",
|
||||
"authors": [ "tsiflimagas" ],
|
||||
"direction": "ltr",
|
||||
"modifier": "org.florisboard.layouts:dvorak"
|
||||
},
|
||||
{
|
||||
"id": "esperanto",
|
||||
"label": "Esperanto",
|
||||
@@ -109,6 +142,12 @@
|
||||
"authors": [ "mahmoudk1000" ],
|
||||
"direction": "ltr"
|
||||
},
|
||||
{
|
||||
"id": "german2",
|
||||
"label": "German (GBoard)",
|
||||
"authors": [ "M-Koushan" ],
|
||||
"direction": "rtl"
|
||||
},
|
||||
{
|
||||
"id": "greek",
|
||||
"label": "Ελληνικά",
|
||||
@@ -146,6 +185,12 @@
|
||||
"authors": [ "nd500" ],
|
||||
"direction": "ltr"
|
||||
},
|
||||
{
|
||||
"id": "indonesian",
|
||||
"label": "Indonesian (QWERTY)",
|
||||
"authors": [ "Linerly" ],
|
||||
"direction": "ltr"
|
||||
},
|
||||
{
|
||||
"id": "ipa",
|
||||
"label": "International Phonetic Alphabet",
|
||||
@@ -154,13 +199,13 @@
|
||||
},
|
||||
{
|
||||
"id": "jcuken_russian",
|
||||
"label": "Russian (JCUKEN)",
|
||||
"label": "Russian (ЙЦУКЕН)",
|
||||
"authors": [ "williamtheaker" ],
|
||||
"direction": "ltr"
|
||||
},
|
||||
{
|
||||
"id": "jcuken_ukrainian",
|
||||
"label": "Ukrainian (JCUKEN)",
|
||||
"label": "Ukrainian (ЙЦУКЕН)",
|
||||
"authors": [ "williamtheaker", "33kk" ],
|
||||
"direction": "ltr"
|
||||
},
|
||||
@@ -223,6 +268,20 @@
|
||||
"direction": "rtl",
|
||||
"modifier": "org.florisboard.layouts:persian"
|
||||
},
|
||||
{
|
||||
"id": "persian2",
|
||||
"label": "Persian2",
|
||||
"authors": [ "M-Koushan" ],
|
||||
"direction": "rtl",
|
||||
"modifier": "org.florisboard.layouts:persian2"
|
||||
},
|
||||
{
|
||||
"id": "persian3",
|
||||
"label": "Persian3",
|
||||
"authors": [ "SaeID-Rz" ],
|
||||
"direction": "rtl",
|
||||
"modifier": "org.florisboard.layouts:persian3"
|
||||
},
|
||||
{
|
||||
"id": "qwerty",
|
||||
"label": "QWERTY",
|
||||
@@ -346,6 +405,12 @@
|
||||
"authors": [ "patrickgold" ],
|
||||
"direction": "ltr"
|
||||
},
|
||||
{
|
||||
"id": "armenian",
|
||||
"label": "Armenian",
|
||||
"authors": [ "PJTSearch" ],
|
||||
"direction": "ltr"
|
||||
},
|
||||
{
|
||||
"id": "arabic",
|
||||
"label": "Arabic",
|
||||
@@ -387,6 +452,18 @@
|
||||
"label": "Persian",
|
||||
"authors": [ "PHELAT" ],
|
||||
"direction": "rtl"
|
||||
},
|
||||
{
|
||||
"id": "persian2",
|
||||
"label": "Persian2",
|
||||
"authors": [ "M-Koushan" ],
|
||||
"direction": "rtl"
|
||||
},
|
||||
{
|
||||
"id": "persian3",
|
||||
"label": "Persian3",
|
||||
"authors": [ "SaeID-Rz" ],
|
||||
"direction": "rtl"
|
||||
}
|
||||
],
|
||||
"extension": [
|
||||
@@ -540,6 +617,13 @@
|
||||
}
|
||||
],
|
||||
"symbols": [
|
||||
{
|
||||
"id": "armenian",
|
||||
"label": "Armenian",
|
||||
"authors": [ "PJTSearch" ],
|
||||
"direction": "ltr",
|
||||
"modifier": "org.florisboard.layouts:armenian"
|
||||
},
|
||||
{
|
||||
"id": "cjk",
|
||||
"label": "CJK",
|
||||
@@ -592,6 +676,12 @@
|
||||
"authors": [ "patrickgold" ],
|
||||
"direction": "ltr"
|
||||
},
|
||||
{
|
||||
"id": "armenian",
|
||||
"label": "Armenian",
|
||||
"authors": [ "PJTSearch" ],
|
||||
"direction": "ltr"
|
||||
},
|
||||
{
|
||||
"id": "cjk",
|
||||
"label": "CJK",
|
||||
|
||||
@@ -0,0 +1,46 @@
|
||||
[
|
||||
[
|
||||
{ "$": "auto_text_key", "code": 113, "label": "q" },
|
||||
{ "$": "auto_text_key", "code": 252, "label": "ü" },
|
||||
{ "$": "auto_text_key", "code": 101, "label": "e" },
|
||||
{ "$": "auto_text_key", "code": 114, "label": "r" },
|
||||
{ "$": "auto_text_key", "code": 116, "label": "t" },
|
||||
{ "$": "auto_text_key", "code": 121, "label": "y" },
|
||||
{ "$": "auto_text_key", "code": 117, "label": "u" },
|
||||
{ "$": "case_selector",
|
||||
"lower": { "code": 105, "label": "i" },
|
||||
"upper": { "code": 304, "label": "İ" }
|
||||
},
|
||||
{ "$": "auto_text_key", "code": 111, "label": "o" },
|
||||
{ "$": "auto_text_key", "code": 112, "label": "p" },
|
||||
{ "$": "auto_text_key", "code": 246, "label": "ö" },
|
||||
{ "$": "auto_text_key", "code": 287, "label": "ğ" }
|
||||
],
|
||||
[
|
||||
{ "$": "auto_text_key", "code": 97, "label": "a" },
|
||||
{ "$": "auto_text_key", "code": 115, "label": "s" },
|
||||
{ "$": "auto_text_key", "code": 100, "label": "d" },
|
||||
{ "$": "auto_text_key", "code": 102, "label": "f" },
|
||||
{ "$": "auto_text_key", "code": 103, "label": "g" },
|
||||
{ "$": "auto_text_key", "code": 104, "label": "h" },
|
||||
{ "$": "auto_text_key", "code": 106, "label": "j" },
|
||||
{ "$": "auto_text_key", "code": 107, "label": "k" },
|
||||
{ "$": "auto_text_key", "code": 108, "label": "l" },
|
||||
{ "$": "case_selector",
|
||||
"lower": { "code": 305, "label": "ı" },
|
||||
"upper": { "code": 73, "label": "I" }
|
||||
},
|
||||
{ "$": "auto_text_key", "code": 601, "label": "ə" }
|
||||
],
|
||||
[
|
||||
{ "$": "auto_text_key", "code": 122, "label": "z" },
|
||||
{ "$": "auto_text_key", "code": 120, "label": "x" },
|
||||
{ "$": "auto_text_key", "code": 99, "label": "c" },
|
||||
{ "$": "auto_text_key", "code": 118, "label": "v" },
|
||||
{ "$": "auto_text_key", "code": 98, "label": "b" },
|
||||
{ "$": "auto_text_key", "code": 110, "label": "n" },
|
||||
{ "$": "auto_text_key", "code": 109, "label": "m" },
|
||||
{ "$": "auto_text_key", "code": 231, "label": "ç" },
|
||||
{ "$": "auto_text_key", "code": 351, "label": "ş" }
|
||||
]
|
||||
]
|
||||
@@ -0,0 +1,46 @@
|
||||
[
|
||||
[
|
||||
{ "$": "auto_text_key", "code": 113, "label": "q" },
|
||||
{ "$": "auto_text_key", "code": 119, "label": "w" },
|
||||
{ "$": "auto_text_key", "code": 102, "label": "f" },
|
||||
{ "$": "auto_text_key", "code": 112, "label": "p" },
|
||||
{ "$": "auto_text_key", "code": 98, "label": "b" },
|
||||
{ "$": "auto_text_key", "code": 106, "label": "j" },
|
||||
{ "$": "auto_text_key", "code": 108, "label": "l" },
|
||||
{ "$": "auto_text_key", "code": 117, "label": "u" },
|
||||
{ "$": "auto_text_key", "code": 121, "label": "y" },
|
||||
{ "$": "case_selector",
|
||||
"lower": { "code": 59, "label": ";", "popup": {
|
||||
"relevant": [
|
||||
{ "code": 58, "label": ":" }
|
||||
]
|
||||
} },
|
||||
"upper": { "code": 58, "label": ":", "popup": {
|
||||
"relevant": [
|
||||
{ "code": 59, "label": ";" }
|
||||
]
|
||||
} }
|
||||
}
|
||||
],
|
||||
[
|
||||
{ "$": "auto_text_key", "code": 97, "label": "a" },
|
||||
{ "$": "auto_text_key", "code": 114, "label": "r" },
|
||||
{ "$": "auto_text_key", "code": 115, "label": "s" },
|
||||
{ "$": "auto_text_key", "code": 116, "label": "t" },
|
||||
{ "$": "auto_text_key", "code": 103, "label": "g" },
|
||||
{ "$": "auto_text_key", "code": 109, "label": "m" },
|
||||
{ "$": "auto_text_key", "code": 110, "label": "n" },
|
||||
{ "$": "auto_text_key", "code": 101, "label": "e" },
|
||||
{ "$": "auto_text_key", "code": 105, "label": "i" },
|
||||
{ "$": "auto_text_key", "code": 111, "label": "o" }
|
||||
],
|
||||
[
|
||||
{ "$": "auto_text_key", "code": 120, "label": "x" },
|
||||
{ "$": "auto_text_key", "code": 99, "label": "c" },
|
||||
{ "$": "auto_text_key", "code": 100, "label": "d" },
|
||||
{ "$": "auto_text_key", "code": 118, "label": "v" },
|
||||
{ "$": "auto_text_key", "code": 122, "label": "z" },
|
||||
{ "$": "auto_text_key", "code": 107, "label": "k" },
|
||||
{ "$": "auto_text_key", "code": 104, "label": "h" }
|
||||
]
|
||||
]
|
||||
@@ -1,47 +1,47 @@
|
||||
[
|
||||
[
|
||||
{ "$": "variation_selector",
|
||||
"default": { "$": "case_selector",
|
||||
"lower": { "code": 39, "label": "'", "popup": {
|
||||
{ "$": "shift_state_selector",
|
||||
"shiftedManual": { "code": 34, "label": "\"", "popup": {
|
||||
"relevant": [
|
||||
{ "code": 33, "label": "!" },
|
||||
{ "code": 39, "label": "'"}
|
||||
]
|
||||
} },
|
||||
"default": { "$": "variation_selector",
|
||||
"email": { "code": 64, "label": "@" },
|
||||
"uri": { "code": 47, "label": "/" },
|
||||
"default": { "code": 39, "label": "'", "popup": {
|
||||
"relevant": [
|
||||
{ "code": 33, "label": "!" },
|
||||
{ "code": 34, "label": "\"" }
|
||||
]
|
||||
} },
|
||||
"upper": { "code": 34, "label": "\"", "popup": {
|
||||
"relevant": [
|
||||
{ "code": 33, "label": "!" },
|
||||
{ "code": 39, "label": "'"}
|
||||
]
|
||||
} }
|
||||
},
|
||||
"email": { "code": 64, "label": "@" },
|
||||
"uri": { "code": 47, "label": "/" }
|
||||
}
|
||||
},
|
||||
{ "$": "case_selector",
|
||||
"lower": { "code": 44, "label": ",", "popup": {
|
||||
"relevant": [
|
||||
{ "code": 60, "label": "<" },
|
||||
{ "code": 63, "label": "?" }
|
||||
]
|
||||
} },
|
||||
"upper": { "code": 60, "label": "<", "popup": {
|
||||
{ "$": "shift_state_selector",
|
||||
"shiftedManual": { "code": 60, "label": "<", "popup": {
|
||||
"relevant": [
|
||||
{ "code": 44, "label": "," },
|
||||
{ "code": 63, "label": "?" }
|
||||
]
|
||||
} },
|
||||
"default": { "code": 44, "label": ",", "popup": {
|
||||
"relevant": [
|
||||
{ "code": 60, "label": "<" },
|
||||
{ "code": 63, "label": "?" }
|
||||
]
|
||||
} }
|
||||
},
|
||||
{ "$": "case_selector",
|
||||
"lower": { "code": 46, "label": ".", "popup": {
|
||||
"relevant": [
|
||||
{ "code": 62, "label": ">" }
|
||||
]
|
||||
} },
|
||||
"upper": { "code": 62, "label": ">", "popup": {
|
||||
{ "$": "shift_state_selector",
|
||||
"shiftedManual": { "code": 62, "label": ">", "popup": {
|
||||
"relevant": [
|
||||
{ "code": 46, "label": "." }
|
||||
]
|
||||
} },
|
||||
"default": { "code": 46, "label": ".", "popup": {
|
||||
"relevant": [
|
||||
{ "code": 62, "label": ">" }
|
||||
]
|
||||
} }
|
||||
},
|
||||
{ "$": "auto_text_key", "code": 112, "label": "p" },
|
||||
|
||||
@@ -0,0 +1,78 @@
|
||||
[
|
||||
[
|
||||
{ "$": "shift_state_selector",
|
||||
"shiftedManual": { "code": 60, "label": "<", "popup": {
|
||||
"relevant": [
|
||||
{ "code": 44, "label": "," },
|
||||
{ "code": 63, "label": "?" }
|
||||
]
|
||||
} },
|
||||
"default": { "code": 44, "label": ",", "popup": {
|
||||
"relevant": [
|
||||
{ "code": 60, "label": "<" },
|
||||
{ "code": 63, "label": "?" }
|
||||
]
|
||||
} }
|
||||
},
|
||||
{ "$": "shift_state_selector",
|
||||
"shiftedManual": { "code": 62, "label": ">", "popup": {
|
||||
"relevant": [
|
||||
{ "code": 46, "label": "." }
|
||||
]
|
||||
} },
|
||||
"default": { "code": 46, "label": ".", "popup": {
|
||||
"relevant": [
|
||||
{ "code": 62, "label": ">" }
|
||||
]
|
||||
} }
|
||||
},
|
||||
{ "$": "auto_text_key", "code": 241, "label": "ñ" },
|
||||
{ "$": "auto_text_key", "code": 112, "label": "p" },
|
||||
{ "$": "auto_text_key", "code": 121, "label": "y" },
|
||||
{ "$": "auto_text_key", "code": 102, "label": "f" },
|
||||
{ "$": "auto_text_key", "code": 103, "label": "g" },
|
||||
{ "$": "auto_text_key", "code": 99, "label": "c" },
|
||||
{ "$": "auto_text_key", "code": 104, "label": "h" },
|
||||
{ "$": "auto_text_key", "code": 108, "label": "l" }
|
||||
],
|
||||
[
|
||||
{ "$": "auto_text_key", "code": 97, "label": "a" },
|
||||
{ "$": "auto_text_key", "code": 111, "label": "o" },
|
||||
{ "$": "auto_text_key", "code": 101, "label": "e" },
|
||||
{ "$": "auto_text_key", "code": 117, "label": "u" },
|
||||
{ "$": "auto_text_key", "code": 105, "label": "i" },
|
||||
{ "$": "auto_text_key", "code": 100, "label": "d" },
|
||||
{ "$": "auto_text_key", "code": 114, "label": "r" },
|
||||
{ "$": "auto_text_key", "code": 116, "label": "t" },
|
||||
{ "$": "auto_text_key", "code": 110, "label": "n" },
|
||||
{ "$": "auto_text_key", "code": 115, "label": "s" },
|
||||
{ "$": "shift_state_selector",
|
||||
"shiftedManual": { "code": 34, "label": "\"", "popup": {
|
||||
"relevant": [
|
||||
{ "code": 33, "label": "!" },
|
||||
{ "code": 39, "label": "'"}
|
||||
]
|
||||
} },
|
||||
"default": { "$": "variation_selector",
|
||||
"email": { "code": 64, "label": "@" },
|
||||
"uri": { "code": 47, "label": "/" },
|
||||
"default": { "code": 39, "label": "'", "popup": {
|
||||
"relevant": [
|
||||
{ "code": 33, "label": "!" },
|
||||
{ "code": 34, "label": "\"" }
|
||||
]
|
||||
} }
|
||||
}
|
||||
},
|
||||
{ "$": "auto_text_key", "code": 231, "label": "ç" }
|
||||
],
|
||||
[
|
||||
{ "$": "auto_text_key", "code": 106, "label": "j" },
|
||||
{ "$": "auto_text_key", "code": 107, "label": "k" },
|
||||
{ "$": "auto_text_key", "code": 120, "label": "x" },
|
||||
{ "$": "auto_text_key", "code": 98, "label": "b" },
|
||||
{ "$": "auto_text_key", "code": 109, "label": "m" },
|
||||
{ "$": "auto_text_key", "code": 119, "label": "w" },
|
||||
{ "$": "auto_text_key", "code": 118, "label": "v" }
|
||||
]
|
||||
]
|
||||
@@ -0,0 +1,48 @@
|
||||
[
|
||||
[
|
||||
{ "$": "auto_text_key", "code": 1393, "label": "ձ" },
|
||||
{ "$": "auto_text_key", "code": 1397, "label": "յ" },
|
||||
{ "$": "auto_text_key", "code": 1413, "label": "օ" },
|
||||
{ "$": "auto_text_key", "code": 1404, "label": "ռ" },
|
||||
{ "$": "auto_text_key", "code": 1386, "label": "ժ" },
|
||||
{ "$": "auto_text_key", "code": 1401, "label": "չ" },
|
||||
{ "$": "auto_text_key", "code": 1403, "label": "ջ" },
|
||||
{ "$": "auto_text_key", "code": 1411, "label": "փ" },
|
||||
{ "$": "auto_text_key", "code": 1394, "label": "ղ" },
|
||||
{ "$": "auto_text_key", "code": 1390, "label": "ծ" }
|
||||
],
|
||||
[
|
||||
{ "$": "auto_text_key", "code": 1389, "label": "խ" },
|
||||
{ "$": "auto_text_key", "code": 1410, "label": "ւ" },
|
||||
{ "$": "auto_text_key", "code": 1383, "label": "է" },
|
||||
{ "$": "auto_text_key", "code": 1408, "label": "ր" },
|
||||
{ "$": "auto_text_key", "code": 1407, "label": "տ" },
|
||||
{ "$": "auto_text_key", "code": 1381, "label": "ե" },
|
||||
{ "$": "auto_text_key", "code": 1384, "label": "ը" },
|
||||
{ "$": "auto_text_key", "code": 1387, "label": "ի" },
|
||||
{ "$": "auto_text_key", "code": 1400, "label": "ո" },
|
||||
{ "$": "auto_text_key", "code": 1402, "label": "պ" }
|
||||
],
|
||||
[
|
||||
{ "$": "auto_text_key", "code": 1377, "label": "ա" },
|
||||
{ "$": "auto_text_key", "code": 1405, "label": "ս" },
|
||||
{ "$": "auto_text_key", "code": 1380, "label": "դ" },
|
||||
{ "$": "auto_text_key", "code": 1414, "label": "ֆ" },
|
||||
{ "$": "auto_text_key", "code": 1412, "label": "ք" },
|
||||
{ "$": "auto_text_key", "code": 1392, "label": "հ" },
|
||||
{ "$": "auto_text_key", "code": 1395, "label": "ճ" },
|
||||
{ "$": "auto_text_key", "code": 1391, "label": "կ" },
|
||||
{ "$": "auto_text_key", "code": 1388, "label": "լ" },
|
||||
{ "$": "auto_text_key", "code": 1385, "label": "թ" }
|
||||
],
|
||||
[
|
||||
{ "$": "auto_text_key", "code": 1382, "label": "զ" },
|
||||
{ "$": "auto_text_key", "code": 1409, "label": "ց" },
|
||||
{ "$": "auto_text_key", "code": 1379, "label": "գ" },
|
||||
{ "$": "auto_text_key", "code": 1406, "label": "վ" },
|
||||
{ "$": "auto_text_key", "code": 1378, "label": "բ" },
|
||||
{ "$": "auto_text_key", "code": 1398, "label": "ն" },
|
||||
{ "$": "auto_text_key", "code": 1396, "label": "մ" },
|
||||
{ "$": "auto_text_key", "code": 1399, "label": "շ" }
|
||||
]
|
||||
]
|
||||
@@ -0,0 +1,37 @@
|
||||
[
|
||||
[
|
||||
{ "$": "auto_text_key", "code": 113, "label": "q" },
|
||||
{ "$": "auto_text_key", "code": 119, "label": "w" },
|
||||
{ "$": "auto_text_key", "code": 101, "label": "e" },
|
||||
{ "$": "auto_text_key", "code": 114, "label": "r" },
|
||||
{ "$": "auto_text_key", "code": 116, "label": "t" },
|
||||
{ "$": "auto_text_key", "code": 122, "label": "z" },
|
||||
{ "$": "auto_text_key", "code": 117, "label": "u" },
|
||||
{ "$": "auto_text_key", "code": 105, "label": "i" },
|
||||
{ "$": "auto_text_key", "code": 111, "label": "o" },
|
||||
{ "$": "auto_text_key", "code": 112, "label": "p" },
|
||||
{ "$": "auto_text_key", "code": 252, "label": "ü" }
|
||||
],
|
||||
[
|
||||
{ "$": "auto_text_key", "code": 97, "label": "a" },
|
||||
{ "$": "auto_text_key", "code": 115, "label": "s" },
|
||||
{ "$": "auto_text_key", "code": 100, "label": "d" },
|
||||
{ "$": "auto_text_key", "code": 102, "label": "f" },
|
||||
{ "$": "auto_text_key", "code": 103, "label": "g" },
|
||||
{ "$": "auto_text_key", "code": 104, "label": "h" },
|
||||
{ "$": "auto_text_key", "code": 106, "label": "j" },
|
||||
{ "$": "auto_text_key", "code": 107, "label": "k" },
|
||||
{ "$": "auto_text_key", "code": 108, "label": "l" },
|
||||
{ "$": "auto_text_key", "code": 246, "label": "ö" },
|
||||
{ "$": "auto_text_key", "code": 228, "label": "ä" }
|
||||
],
|
||||
[
|
||||
{ "$": "auto_text_key", "code": 121, "label": "y" },
|
||||
{ "$": "auto_text_key", "code": 120, "label": "x" },
|
||||
{ "$": "auto_text_key", "code": 99, "label": "c" },
|
||||
{ "$": "auto_text_key", "code": 118, "label": "v" },
|
||||
{ "$": "auto_text_key", "code": 98, "label": "b" },
|
||||
{ "$": "auto_text_key", "code": 110, "label": "n" },
|
||||
{ "$": "auto_text_key", "code": 109, "label": "m" }
|
||||
]
|
||||
]
|
||||
@@ -2,44 +2,85 @@
|
||||
[
|
||||
{ "code": 39, "label": "'", "popup": {
|
||||
"relevant": [
|
||||
{ "code": 1474, "label": "ש\u05c2" },
|
||||
{ "code": 1467, "label": "ס\u05bb" },
|
||||
{ "code": 1523, "label": "׳" },
|
||||
{ "code": 1524, "label": "״" },
|
||||
{ "code": 34, "label": "\"" },
|
||||
{ "code": 96, "label": "`" }
|
||||
]
|
||||
} },
|
||||
{ "code": 45, "label": "-", "popup": {
|
||||
"relevant": [
|
||||
{ "code": 1470, "label": "־" },
|
||||
{ "code": 1473, "label": "ש\u05c1" },
|
||||
{ "code": 95, "label": "_" }
|
||||
]
|
||||
} },
|
||||
{ "code": 1511, "label": "ק" },
|
||||
{ "code": 1511, "label": "ק", "popup": {
|
||||
"relevant": [
|
||||
{ "code": 1464, "label": "ס\u05b8" },
|
||||
{ "code": 1459, "label": "ס\u05b3" }
|
||||
]
|
||||
} },
|
||||
{ "code": 1512, "label": "ר" },
|
||||
{ "code": 1488, "label": "א" },
|
||||
{ "code": 1496, "label": "ט" },
|
||||
{ "code": 1493, "label": "ו" },
|
||||
{ "code": 1493, "label": "ו", "popup": {
|
||||
"relevant": [
|
||||
{ "code": 1465, "label": "ס\u05b9" }
|
||||
]
|
||||
} },
|
||||
{ "code": 1503, "label": "ן" },
|
||||
{ "code": 1501, "label": "ם" },
|
||||
{ "code": 1508, "label": "פ" }
|
||||
{ "code": 1508, "label": "פ", "popup": {
|
||||
"relevant": [
|
||||
{ "code": 1463, "label": "ס\u05b7" },
|
||||
{ "code": 1458, "label": "ס\u05b2" }
|
||||
]
|
||||
} }
|
||||
],
|
||||
[
|
||||
{ "code": 1513, "label": "ש" },
|
||||
{ "code": 1491, "label": "ד" },
|
||||
{ "code": 1513, "label": "ש", "popup": {
|
||||
"relevant": [
|
||||
{ "code": 1456, "label": "ס\u05b0" }
|
||||
]
|
||||
} },
|
||||
{ "code": 1491, "label": "ד", "popup": {
|
||||
"relevant": [
|
||||
{ "code": 1468, "label": "ס\u05bc" }
|
||||
]
|
||||
} },
|
||||
{ "code": 1490, "label": "ג" },
|
||||
{ "code": 1499, "label": "כ" },
|
||||
{ "code": 1506, "label": "ע" },
|
||||
{ "code": 1497, "label": "י" },
|
||||
{ "code": 1495, "label": "ח" },
|
||||
{ "code": 1495, "label": "ח", "popup": {
|
||||
"relevant": [
|
||||
{ "code": 1460, "label": "ס\u05b4" }
|
||||
]
|
||||
} },
|
||||
{ "code": 1500, "label": "ל" },
|
||||
{ "code": 1498, "label": "ך" },
|
||||
{ "code": 1507, "label": "ף" }
|
||||
],
|
||||
[
|
||||
{ "code": 1494, "label": "ז" },
|
||||
{ "code": 1505, "label": "ס" },
|
||||
{ "code": 1505, "label": "ס", "popup": {
|
||||
"relevant": [
|
||||
{ "code": 1462, "label": "ס\u05b6" },
|
||||
{ "code": 1457, "label": "ס\u05b1" }
|
||||
]
|
||||
} },
|
||||
{ "code": 1489, "label": "ב" },
|
||||
{ "code": 1492, "label": "ה" },
|
||||
{ "code": 1504, "label": "נ" },
|
||||
{ "code": 1502, "label": "מ" },
|
||||
{ "code": 1510, "label": "צ" },
|
||||
{ "code": 1510, "label": "צ", "popup": {
|
||||
"relevant": [
|
||||
{ "code": 1461, "label": "ס\u05b5" }
|
||||
]
|
||||
} },
|
||||
{ "code": 1514, "label": "ת" },
|
||||
{ "code": 1509, "label": "ץ" }
|
||||
]
|
||||
|
||||
@@ -48,7 +48,9 @@
|
||||
|
||||
],
|
||||
[
|
||||
|
||||
{ "code": 1600, "label": "kashida", "popup":
|
||||
{ "main": { "code": 8204, "label": "half_space" }
|
||||
} },
|
||||
{ "code": 1574, "label": "ﺋ", "popup": {
|
||||
"main": { "code": 1569, "label": "ء" }
|
||||
} },
|
||||
@@ -58,9 +60,14 @@
|
||||
} },
|
||||
{ "code": 1688, "label": "ژ" },
|
||||
{ "code": 1605, "label": "م" },
|
||||
{ "code": 1567, "label": "؟" },
|
||||
{ "code": 1548, "label": "،" },
|
||||
{ "code": 58, "label": ":" }
|
||||
|
||||
{ "code": 1567, "label": "؟", "popup": {
|
||||
"main": { "code": 63, "label": "?" }
|
||||
} },
|
||||
{ "code": 1548, "label": "،", "popup": {
|
||||
"main": { "code": 1643, "label": "٫" }
|
||||
} },
|
||||
{ "code": 58, "label": ":", "popup": {
|
||||
"main": { "code": 1563, "label": "؛" }
|
||||
} }
|
||||
]
|
||||
]
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
[
|
||||
[
|
||||
{ "code": 1589, "label": "ص" },
|
||||
{ "code": 1602, "label": "ق" },
|
||||
{ "code": 1601, "label": "ف" },
|
||||
{ "code": 1594, "label": "غ" },
|
||||
{ "code": 1593, "label": "ع" },
|
||||
{ "code": 1607, "label": "ه" },
|
||||
{ "code": 1582, "label": "خ" },
|
||||
{ "code": 1581, "label": "ح" },
|
||||
{ "code": 1580, "label": "ج" },
|
||||
{ "code": 1670, "label": "چ" }
|
||||
],
|
||||
[
|
||||
{ "code": 1588, "label": "ش" },
|
||||
{ "code": 1587, "label": "س" },
|
||||
{ "code": 1740, "label": "ی" },
|
||||
{ "code": 1576, "label": "ب" },
|
||||
{ "code": 1604, "label": "ل" },
|
||||
{ "code": 1575, "label": "ا" },
|
||||
{ "code": 1578, "label": "ت" },
|
||||
{ "code": 1606, "label": "ن" },
|
||||
{ "code": 1605, "label": "م" },
|
||||
{ "code": 1705, "label": "ک" }
|
||||
],
|
||||
[
|
||||
{ "code": 8204, "label": "half_space" },
|
||||
{ "code": 1591, "label": "ط" },
|
||||
{ "code": 1586, "label": "ز" },
|
||||
{ "code": 1585, "label": "ر" },
|
||||
{ "code": 1584, "label": "ذ" },
|
||||
{ "code": 1583, "label": "د" },
|
||||
{ "code": 1608, "label": "و" },
|
||||
{ "code": 1711, "label": "گ" }
|
||||
]
|
||||
]
|
||||
@@ -0,0 +1,39 @@
|
||||
[
|
||||
[
|
||||
{ "code": 1590, "label": "ض" },
|
||||
{ "code": 1589, "label": "ص" },
|
||||
{ "code": 1579, "label": "ث" },
|
||||
{ "code": 1602, "label": "ق" },
|
||||
{ "code": 1601, "label": "ف" },
|
||||
{ "code": 1594, "label": "غ" },
|
||||
{ "code": 1593, "label": "ع" },
|
||||
{ "code": 1607, "label": "ه" },
|
||||
{ "code": 1582, "label": "خ" },
|
||||
{ "code": 1581, "label": "ح" },
|
||||
{ "code": 1580, "label": "ج" }
|
||||
],
|
||||
[
|
||||
{ "code": 1588, "label": "ش" },
|
||||
{ "code": 1587, "label": "س" },
|
||||
{ "code": 1740, "label": "ی" },
|
||||
{ "code": 1576, "label": "ب" },
|
||||
{ "code": 1604, "label": "ل" },
|
||||
{ "code": 1575, "label": "ا" },
|
||||
{ "code": 1578, "label": "ت" },
|
||||
{ "code": 1606, "label": "ن" },
|
||||
{ "code": 1605, "label": "م" },
|
||||
{ "code": 1705, "label": "ک" },
|
||||
{ "code": 1711, "label": "گ" }
|
||||
],
|
||||
[
|
||||
{ "code": 1592, "label": "ظ" },
|
||||
{ "code": 1591, "label": "ط" },
|
||||
{ "code": 1586, "label": "ز" },
|
||||
{ "code": 1585, "label": "ر" },
|
||||
{ "code": 1584, "label": "ذ" },
|
||||
{ "code": 1583, "label": "د" },
|
||||
{ "code": 1662, "label": "پ" },
|
||||
{ "code": 1608, "label": "و" },
|
||||
{ "code": 1670, "label": "چ" }
|
||||
]
|
||||
]
|
||||
@@ -0,0 +1,49 @@
|
||||
[
|
||||
[
|
||||
|
||||
{ "$": "auto_text_key", "code": 1393, "label": "ձ" },
|
||||
{ "$": "auto_text_key", "code": 1397, "label": "յ" },
|
||||
{ "$": "auto_text_key", "code": 1413, "label": "օ" },
|
||||
{ "$": "auto_text_key", "code": 1404, "label": "ռ" },
|
||||
{ "$": "auto_text_key", "code": 1386, "label": "ժ" },
|
||||
{ "$": "auto_text_key", "code": 1401, "label": "չ" },
|
||||
{ "$": "auto_text_key", "code": 1403, "label": "ջ" },
|
||||
{ "$": "auto_text_key", "code": 1411, "label": "փ" },
|
||||
{ "$": "auto_text_key", "code": 1394, "label": "ղ" },
|
||||
{ "$": "auto_text_key", "code": 1390, "label": "ծ" }
|
||||
],
|
||||
[
|
||||
{ "$": "auto_text_key", "code": 1389, "label": "խ" },
|
||||
{ "$": "auto_text_key", "code": 1406, "label": "վ" },
|
||||
{ "$": "auto_text_key", "code": 1383, "label": "է" },
|
||||
{ "$": "auto_text_key", "code": 1408, "label": "ր" },
|
||||
{ "$": "auto_text_key", "code": 1380, "label": "դ" },
|
||||
{ "$": "auto_text_key", "code": 1381, "label": "ե" },
|
||||
{ "$": "auto_text_key", "code": 1384, "label": "ը" },
|
||||
{ "$": "auto_text_key", "code": 1387, "label": "ի" },
|
||||
{ "$": "auto_text_key", "code": 1400, "label": "ո" },
|
||||
{ "$": "auto_text_key", "code": 1378, "label": "բ" }
|
||||
],
|
||||
[
|
||||
{ "$": "auto_text_key", "code": 1377, "label": "ա" },
|
||||
{ "$": "auto_text_key", "code": 1405, "label": "ս" },
|
||||
{ "$": "auto_text_key", "code": 1407, "label": "տ" },
|
||||
{ "$": "auto_text_key", "code": 1414, "label": "ֆ" },
|
||||
{ "$": "auto_text_key", "code": 1391, "label": "կ" },
|
||||
{ "$": "auto_text_key", "code": 1392, "label": "հ" },
|
||||
{ "$": "auto_text_key", "code": 1395, "label": "ճ" },
|
||||
{ "$": "auto_text_key", "code": 1412, "label": "ք" },
|
||||
{ "$": "auto_text_key", "code": 1388, "label": "լ" },
|
||||
{ "$": "auto_text_key", "code": 1385, "label": "թ" }
|
||||
],
|
||||
[
|
||||
{ "$": "auto_text_key", "code": 1382, "label": "զ" },
|
||||
{ "$": "auto_text_key", "code": 1409, "label": "ց" },
|
||||
{ "$": "auto_text_key", "code": 1379, "label": "գ" },
|
||||
{ "$": "auto_text_key", "code": 1410, "label": "ւ" },
|
||||
{ "$": "auto_text_key", "code": 1402, "label": "պ" },
|
||||
{ "$": "auto_text_key", "code": 1398, "label": "ն" },
|
||||
{ "$": "auto_text_key", "code": 1396, "label": "մ" },
|
||||
{ "$": "auto_text_key", "code": 1399, "label": "շ" }
|
||||
]
|
||||
]
|
||||
@@ -0,0 +1,20 @@
|
||||
[
|
||||
[
|
||||
{ "code": -11, "label": "shift", "type": "modifier" },
|
||||
{ "code": 0, "type": "placeholder" },
|
||||
{ "code": -7, "label": "delete", "type": "enter_editing" }
|
||||
],
|
||||
[
|
||||
{ "code": -202, "label": "view_symbols", "type": "system_gui" },
|
||||
{ "$": "variation_selector",
|
||||
"default": { "code": 44, "label": ",", "groupId": 1 },
|
||||
"email": { "code": 64, "label": "@", "groupId": 1 },
|
||||
"uri": { "code": 47, "label": "/", "groupId": 1 }
|
||||
},
|
||||
{ "code": -227, "label": "language_switch", "type": "system_gui" },
|
||||
{ "code": -212, "label": "ime_ui_mode_media", "type": "system_gui" },
|
||||
{ "code": 32, "label": "space" },
|
||||
{ "code": 1417, "label": "։", "groupId": 2 },
|
||||
{ "code": 10, "label": "enter", "groupId": 3, "type": "enter_editing" }
|
||||
]
|
||||
]
|
||||
@@ -1,8 +1,5 @@
|
||||
[
|
||||
[
|
||||
{ "code": 1600, "label": "kashida", "popup":
|
||||
{ "main": { "code": 8204, "label": "half_space" }
|
||||
} },
|
||||
{ "code": 0, "type": "placeholder" },
|
||||
{ "code": -7, "label": "delete", "type": "enter_editing" }
|
||||
],
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
[
|
||||
[
|
||||
{ "code": 0, "type": "placeholder" },
|
||||
{ "code": -7, "label": "delete", "type": "enter_editing" }
|
||||
],
|
||||
[
|
||||
{ "code": -202, "label": "view_symbols", "type": "system_gui" },
|
||||
{ "code": -227, "label": "language_switch", "type": "system_gui" },
|
||||
{ "code": -212, "label": "ime_ui_mode_media", "type": "system_gui" },
|
||||
{ "$": "variation_selector",
|
||||
"default": { "code": 1548, "label": "،", "groupId": 1 },
|
||||
"email": { "code": 64, "label": "@", "groupId": 1 },
|
||||
"uri": { "code": 47, "label": "/", "groupId": 1 }
|
||||
},
|
||||
{ "code": 32, "label": "space" },
|
||||
{ "code": 46, "label": ".", "groupId": 2 },
|
||||
{ "code": 10, "label": "enter", "groupId": 3, "type": "enter_editing" }
|
||||
]
|
||||
]
|
||||
@@ -0,0 +1,19 @@
|
||||
[
|
||||
[
|
||||
{ "code": 0, "type": "placeholder" },
|
||||
{ "code": -7, "label": "delete", "type": "enter_editing" }
|
||||
],
|
||||
[
|
||||
{ "code": -202, "label": "view_symbols", "type": "system_gui" },
|
||||
{ "$": "variation_selector",
|
||||
"default": { "code": 1548, "label": "،", "groupId": 1 },
|
||||
"email": { "code": 64, "label": "@", "groupId": 1 },
|
||||
"uri": { "code": 47, "label": "/", "groupId": 1 }
|
||||
},
|
||||
{ "code": -227, "label": "language_switch", "type": "system_gui" },
|
||||
{ "code": -212, "label": "ime_ui_mode_media", "type": "system_gui" },
|
||||
{ "code": 32, "label": "space" },
|
||||
{ "code": 46, "label": ".", "groupId": 2 },
|
||||
{ "code": 10, "label": "enter", "groupId": 3, "type": "enter_editing" }
|
||||
]
|
||||
]
|
||||
@@ -1,68 +1,200 @@
|
||||
[
|
||||
[
|
||||
{ "code": 49, "label": "1", "type": "numeric", "popup": {
|
||||
"main": { "code": 185, "label": "¹" },
|
||||
"relevant": [
|
||||
{ "code": 8537, "label": "⅙" },
|
||||
{ "code": 8528, "label": "⅐" },
|
||||
{ "code": 8539, "label": "⅛" },
|
||||
{ "code": 8529, "label": "⅑" },
|
||||
{ "code": 8530, "label": "⅒" },
|
||||
{ "code": 189, "label": "½" },
|
||||
{ "code": 8531, "label": "⅓" },
|
||||
{ "code": 188, "label": "¼" },
|
||||
{ "code": 8533, "label": "⅕" }
|
||||
]
|
||||
} },
|
||||
{ "code": 50, "label": "2", "type": "numeric", "popup": {
|
||||
"main": { "code": 178, "label": "²" },
|
||||
"relevant": [
|
||||
{ "code": 8532, "label": "⅔" },
|
||||
{ "code": 8534, "label": "⅖" }
|
||||
]
|
||||
} },
|
||||
{ "code": 51, "label": "3", "type": "numeric", "popup": {
|
||||
"main": { "code": 179, "label": "³" },
|
||||
"relevant": [
|
||||
{ "code": 8535, "label": "⅗" },
|
||||
{ "code": 190, "label": "¾" },
|
||||
{ "code": 8540, "label": "⅜" }
|
||||
]
|
||||
} },
|
||||
{ "code": 52, "label": "4", "type": "numeric", "popup": {
|
||||
"main": { "code": 8308, "label": "⁴" },
|
||||
"relevant": [
|
||||
{ "code": 8536, "label": "⅘" }
|
||||
]
|
||||
} },
|
||||
{ "code": 53, "label": "5", "type": "numeric", "popup": {
|
||||
"main": { "code": 8309, "label": "⁵" },
|
||||
"relevant": [
|
||||
{ "code": 8538, "label": "⅚" },
|
||||
{ "code": 8541, "label": "⅝" }
|
||||
]
|
||||
} },
|
||||
{ "code": 54, "label": "6", "type": "numeric", "popup": {
|
||||
"main": { "code": 8310, "label": "⁶" }
|
||||
} },
|
||||
{ "code": 55, "label": "7", "type": "numeric", "popup": {
|
||||
"main": { "code": 8311, "label": "⁷" },
|
||||
"relevant": [
|
||||
{ "code": 8542, "label": "⅞" }
|
||||
]
|
||||
} },
|
||||
{ "code": 56, "label": "8", "type": "numeric", "popup": {
|
||||
"main": { "code": 8312, "label": "⁸" }
|
||||
} },
|
||||
{ "code": 57, "label": "9", "type": "numeric", "popup": {
|
||||
"main": { "code": 8313, "label": "⁹" }
|
||||
} },
|
||||
{ "code": 48, "label": "0", "type": "numeric", "popup": {
|
||||
"main": { "code": 8304, "label": "⁰" },
|
||||
"relevant": [
|
||||
{ "code": 8709, "label": "∅" },
|
||||
{ "code": 8319, "label": "ⁿ" }
|
||||
]
|
||||
} }
|
||||
{ "$": "shift_state_selector",
|
||||
"shiftedManual": {
|
||||
"code": 33, "label": "!", "type": "numeric", "popup": {
|
||||
"main": { "code": 161, "label": "¡" }
|
||||
}
|
||||
},
|
||||
"default": {
|
||||
"code": 49, "label": "1", "type": "numeric", "popup": {
|
||||
"main": { "code": 185, "label": "¹" },
|
||||
"relevant": [
|
||||
{ "code": 8537, "label": "⅙" },
|
||||
{ "code": 8528, "label": "⅐" },
|
||||
{ "code": 8539, "label": "⅛" },
|
||||
{ "code": 8529, "label": "⅑" },
|
||||
{ "code": 8530, "label": "⅒" },
|
||||
{ "code": 189, "label": "½" },
|
||||
{ "code": 8531, "label": "⅓" },
|
||||
{ "code": 188, "label": "¼" },
|
||||
{ "code": 8533, "label": "⅕" }
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
{ "$": "shift_state_selector",
|
||||
"shiftedManual": { "code": 64, "label": "@", "type": "numeric" },
|
||||
"default": {
|
||||
"code": 50, "label": "2", "type": "numeric", "popup": {
|
||||
"main": { "code": 178, "label": "²" },
|
||||
"relevant": [
|
||||
{ "code": 8532, "label": "⅔" },
|
||||
{ "code": 8534, "label": "⅖" }
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
{ "$": "shift_state_selector",
|
||||
"shiftedManual": {
|
||||
"code": 35, "label": "#", "type": "numeric", "popup": {
|
||||
"main": { "code": 8470, "label": "№" }
|
||||
}
|
||||
},
|
||||
"default": {
|
||||
"code": 51, "label": "3", "type": "numeric", "popup": {
|
||||
"main": { "code": 179, "label": "³" },
|
||||
"relevant": [
|
||||
{ "code": 8535, "label": "⅗" },
|
||||
{ "code": 190, "label": "¾" },
|
||||
{ "code": 8540, "label": "⅜" }
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
{ "$": "shift_state_selector",
|
||||
"shiftedManual": {
|
||||
"code": -801, "label": "currency_slot_1", "type": "numeric", "popup": {
|
||||
"main": { "code": -802, "label": "currency_slot_2" },
|
||||
"relevant": [
|
||||
{ "code": -806, "label": "currency_slot_6" },
|
||||
{ "code": -803, "label": "currency_slot_3" },
|
||||
{ "code": -804, "label": "currency_slot_4" },
|
||||
{ "code": -805, "label": "currency_slot_5" }
|
||||
]
|
||||
}
|
||||
},
|
||||
"default": {
|
||||
"code": 52, "label": "4", "type": "numeric", "popup": {
|
||||
"main": { "code": 8308, "label": "⁴" },
|
||||
"relevant": [
|
||||
{ "code": 8536, "label": "⅘" }
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
{ "$": "shift_state_selector",
|
||||
"shiftedManual": {
|
||||
"code": 37, "label": "%", "type": "numeric", "popup": {
|
||||
"main": { "code": 8240, "label": "‰" },
|
||||
"relevant": [
|
||||
{ "code": 8453, "label": "℅" }
|
||||
]
|
||||
}
|
||||
},
|
||||
"default": {
|
||||
"code": 53, "label": "5", "type": "numeric", "popup": {
|
||||
"main": { "code": 8309, "label": "⁵" },
|
||||
"relevant": [
|
||||
{ "code": 8538, "label": "⅚" },
|
||||
{ "code": 8541, "label": "⅝" }
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
{ "$": "shift_state_selector",
|
||||
"shiftedManual": {
|
||||
"code": 94, "label": "^", "type": "numeric", "popup": {
|
||||
"main": { "code": 8593, "label": "↑" },
|
||||
"relevant": [
|
||||
{ "code": 8592, "label": "←" },
|
||||
{ "code": 8595, "label": "↓" },
|
||||
{ "code": 8594, "label": "→" }
|
||||
]
|
||||
}
|
||||
},
|
||||
"default": {
|
||||
"code": 54, "label": "6", "type": "numeric", "popup": {
|
||||
"main": { "code": 8310, "label": "⁶" }
|
||||
}
|
||||
}
|
||||
},
|
||||
{ "$": "shift_state_selector",
|
||||
"shiftedManual": { "code": 38, "label": "&", "type": "numeric" },
|
||||
"default": {
|
||||
"code": 55, "label": "7", "type": "numeric", "popup": {
|
||||
"main": { "code": 8311, "label": "⁷" },
|
||||
"relevant": [
|
||||
{ "code": 8542, "label": "⅞" }
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
{ "$": "shift_state_selector",
|
||||
"shiftedManual": {
|
||||
"code": 42, "label": "*", "type": "numeric", "popup": {
|
||||
"main": { "code": 8224, "label": "†" },
|
||||
"relevant": [
|
||||
{ "code": 9733, "label": "★" },
|
||||
{ "code": 8225, "label": "‡" }
|
||||
]
|
||||
}
|
||||
},
|
||||
"default": {
|
||||
"code": 56, "label": "8", "type": "numeric", "popup": {
|
||||
"main": { "code": 8312, "label": "⁸" }
|
||||
}
|
||||
}
|
||||
},
|
||||
{ "$": "shift_state_selector",
|
||||
"shiftedManual": {
|
||||
"$": "layout_direction_selector",
|
||||
"ltr": {
|
||||
"code": 40, "label": "(", "type": "numeric", "popup": {
|
||||
"main": { "code": 60, "label": "<" },
|
||||
"relevant": [
|
||||
{ "code": 91, "label": "[" },
|
||||
{ "code": 123, "label": "{" }
|
||||
]
|
||||
}
|
||||
},
|
||||
"rtl": {
|
||||
"code": 41, "label": "(", "type": "numeric", "popup": {
|
||||
"main": { "code": 62, "label": "<" },
|
||||
"relevant": [
|
||||
{ "code": 93, "label": "[" },
|
||||
{ "code": 125, "label": "{" }
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"default": {
|
||||
"code": 57, "label": "9", "type": "numeric", "popup": {
|
||||
"main": { "code": 8313, "label": "⁹" }
|
||||
}
|
||||
}
|
||||
},
|
||||
{ "$": "shift_state_selector",
|
||||
"shiftedManual": {
|
||||
"$": "layout_direction_selector",
|
||||
"ltr": {
|
||||
"code": 41, "label": ")", "type": "numeric", "popup": {
|
||||
"main": { "code": 62, "label": ">" },
|
||||
"relevant": [
|
||||
{ "code": 93, "label": "]" },
|
||||
{ "code": 125, "label": "}" }
|
||||
]
|
||||
}
|
||||
},
|
||||
"rtl": {
|
||||
"code": 40, "label": ")", "type": "numeric", "popup": {
|
||||
"main": { "code": 60, "label": ">" },
|
||||
"relevant": [
|
||||
{ "code": 91, "label": "]" },
|
||||
{ "code": 123, "label": "}" }
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"default": {
|
||||
"code": 48, "label": "0", "type": "numeric", "popup": {
|
||||
"main": { "code": 8304, "label": "⁰" },
|
||||
"relevant": [
|
||||
{ "code": 8709, "label": "∅" },
|
||||
{ "code": 8319, "label": "ⁿ" }
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
]
|
||||
|
||||
@@ -0,0 +1,92 @@
|
||||
[
|
||||
[
|
||||
{ "code": 64, "label": "@" },
|
||||
{ "code": 35, "label": "#", "popup": {
|
||||
"main": { "code": 8470, "label": "№" }
|
||||
} },
|
||||
{ "code": -801, "label": "currency_slot_1", "popup": {
|
||||
"main": { "code": -802, "label": "currency_slot_2" },
|
||||
"relevant": [
|
||||
{ "code": -806, "label": "currency_slot_6" },
|
||||
{ "code": -803, "label": "currency_slot_3" },
|
||||
{ "code": -804, "label": "currency_slot_4" },
|
||||
{ "code": -805, "label": "currency_slot_5" }
|
||||
]
|
||||
} },
|
||||
{ "code": 37, "label": "%", "popup": {
|
||||
"main": { "code": 8240, "label": "‰" },
|
||||
"relevant": [
|
||||
{ "code": 8453, "label": "℅" }
|
||||
]
|
||||
} },
|
||||
{ "code": 38, "label": "&" },
|
||||
{ "code": 45, "label": "-", "popup": {
|
||||
"main": { "code": 95, "label": "_" },
|
||||
"relevant": [
|
||||
{ "code": 8212, "label": "—" },
|
||||
{ "code": 8211, "label": "–" },
|
||||
{ "code": 183, "label": "·" }
|
||||
]
|
||||
} },
|
||||
{ "code": 43, "label": "+", "popup": {
|
||||
"main": { "code": 177, "label": "±" }
|
||||
} },
|
||||
{ "code": 40, "label": "(", "popup": {
|
||||
"main": { "code": 60, "label": "<" },
|
||||
"relevant": [
|
||||
{ "code": 91, "label": "[" },
|
||||
{ "code": 123, "label": "{" }
|
||||
]
|
||||
} },
|
||||
{ "code": 41, "label": ")", "popup": {
|
||||
"main": { "code": 62, "label": ">" },
|
||||
"relevant": [
|
||||
{ "code": 93, "label": "]" },
|
||||
{ "code": 125, "label": "}" }
|
||||
]
|
||||
} },
|
||||
{ "code": 47, "label": "/" }
|
||||
],
|
||||
[
|
||||
{ "code": 42, "label": "*", "popup": {
|
||||
"main": { "code": 8224, "label": "†" },
|
||||
"relevant": [
|
||||
{ "code": 9733, "label": "★" },
|
||||
{ "code": 8225, "label": "‡" }
|
||||
]
|
||||
} },
|
||||
{ "code": 171, "label": "«", "popup": {
|
||||
"main": { "code": 34, "label": "\"" },
|
||||
"relevant": [
|
||||
{ "code": 8221, "label": "”" },
|
||||
{ "code": 8222, "label": "„" },
|
||||
{ "code": 8220, "label": "“" },
|
||||
{ "code": 8249, "label": "‹" }
|
||||
]
|
||||
} },
|
||||
{ "code": 187, "label": "»", "popup": {
|
||||
"main": { "code": 39, "label": "'" },
|
||||
"relevant": [
|
||||
{ "code": 8217, "label": "’" },
|
||||
{ "code": 8218, "label": "‚" },
|
||||
{ "code": 8216, "label": "‘" },
|
||||
{ "code": 8250, "label": "›" }
|
||||
]
|
||||
} },
|
||||
{ "code": 1373, "label": "՝", "popup": {
|
||||
"main": { "code": 58, "label": ":" }
|
||||
} },
|
||||
{ "code": 46, "label": "." },
|
||||
{ "code": 1372, "label": "՜", "popup": {
|
||||
"main": { "code": 33, "label": "!" }
|
||||
} },
|
||||
{ "code": 1374, "label": "՞", "popup": {
|
||||
"main": { "code": 63, "label": "?" },
|
||||
"relevant": [
|
||||
{ "code": 191, "label": "¿" },
|
||||
{ "code": 8253, "label": "‽" }
|
||||
]
|
||||
} },
|
||||
{ "code": 1371, "label": "՛" }
|
||||
]
|
||||
]
|
||||
@@ -0,0 +1,17 @@
|
||||
[
|
||||
[
|
||||
{ "code": -203, "label": "view_symbols2", "type": "system_gui" },
|
||||
{ "code": 0, "type": "placeholder" },
|
||||
{ "code": -7, "label": "delete", "type": "enter_editing" }
|
||||
],
|
||||
[
|
||||
{ "code": -201, "label": "view_characters", "type": "system_gui" },
|
||||
{ "code": 44, "label": "," },
|
||||
{ "code": -205, "label": "view_numeric_advanced", "type": "system_gui" },
|
||||
{ "code": 32, "label": "space" },
|
||||
{ "code": 1417, "label": "։", "popup": {
|
||||
"main": { "code": 46, "label": "." }
|
||||
} },
|
||||
{ "code": 10, "label": "enter", "groupId": 3, "type": "enter_editing" }
|
||||
]
|
||||
]
|
||||
@@ -2,9 +2,9 @@
|
||||
"$": "ime.extension.keyboard",
|
||||
"meta": {
|
||||
"id": "org.florisboard.localization",
|
||||
"version": "0.1.0",
|
||||
"version": "0.2.0",
|
||||
"title": "Default subtype presets / popup mappings",
|
||||
"description": "Default subptye presets and popup mappings which are always available.",
|
||||
"description": "Default subtype presets and popup mappings which are always available.",
|
||||
"maintainers": [ "patrickgold <patrick@patrickgold.dev>" ],
|
||||
"license": "apache-2.0"
|
||||
},
|
||||
@@ -13,176 +13,66 @@
|
||||
"org.florisboard.currencysets",
|
||||
"org.florisboard.layouts"
|
||||
],
|
||||
"popupMappings": [
|
||||
"punctuationRules": [
|
||||
{
|
||||
"id": "default",
|
||||
"authors": [ "patrickgold" ]
|
||||
},
|
||||
{
|
||||
"id": "ar",
|
||||
"authors": [ "HeiWiper" ]
|
||||
},
|
||||
{
|
||||
"id": "bg",
|
||||
"authors": [ "iorvethe" ]
|
||||
},
|
||||
{
|
||||
"id": "ca",
|
||||
"authors": [ "mikelloc" ]
|
||||
},
|
||||
{
|
||||
"id": "ckb",
|
||||
"authors": [ "GoRaN" ]
|
||||
},
|
||||
{
|
||||
"id": "cs",
|
||||
"authors": [ "stefan-misik" ]
|
||||
},
|
||||
{
|
||||
"id": "da",
|
||||
"authors": [ "patrickgold" ]
|
||||
},
|
||||
{
|
||||
"id": "de",
|
||||
"authors": [ "patrickgold" ]
|
||||
},
|
||||
{
|
||||
"id": "de-DE-neobone",
|
||||
"authors": [ "ostrya" ]
|
||||
},
|
||||
{
|
||||
"id": "el",
|
||||
"authors": [ "tsiflimagas" ]
|
||||
},
|
||||
{
|
||||
"id": "en",
|
||||
"authors": [ "patrickgold" ]
|
||||
},
|
||||
{
|
||||
"id": "eo",
|
||||
"authors": [ "jeremiah-miller" ]
|
||||
},
|
||||
{
|
||||
"id": "es",
|
||||
"authors": [ "patrickgold" ]
|
||||
},
|
||||
{
|
||||
"id": "fa",
|
||||
"authors": [ "PHELAT" ]
|
||||
},
|
||||
{
|
||||
"id": "fi",
|
||||
"authors": [ "patrickgold" ]
|
||||
},
|
||||
{
|
||||
"id": "fo",
|
||||
"authors": [ "BinFlush" ]
|
||||
},
|
||||
{
|
||||
"id": "fr",
|
||||
"authors": [ "patrickgold" ]
|
||||
},
|
||||
{
|
||||
"id": "hr",
|
||||
"authors": [ "hedidnothingwrong" ]
|
||||
},
|
||||
{
|
||||
"id": "hu",
|
||||
"authors": [ "zoli111, gabik65" ]
|
||||
},
|
||||
{
|
||||
"id": "is",
|
||||
"authors": [ "patrickgold" ]
|
||||
},
|
||||
{
|
||||
"id": "it",
|
||||
"authors": [ "patrickgold" ]
|
||||
},
|
||||
{
|
||||
"id": "iw",
|
||||
"authors": [ "Antony" ]
|
||||
},
|
||||
{
|
||||
"id": "ja-JP-jis",
|
||||
"authors": [ "waelwindows" ]
|
||||
},
|
||||
{
|
||||
"id": "ko",
|
||||
"authors": [ "patrickgold", "Hayleia" ]
|
||||
},
|
||||
{
|
||||
"id": "ku",
|
||||
"authors": [ "GoRaN" ]
|
||||
},
|
||||
{
|
||||
"id": "lt",
|
||||
"authors": [ "patrickgold" ]
|
||||
},
|
||||
{
|
||||
"id": "lv",
|
||||
"authors": [ "patrickgold", "eandersons" ]
|
||||
},
|
||||
{
|
||||
"id": "nb",
|
||||
"authors": [ "patrickgold" ]
|
||||
},
|
||||
{
|
||||
"id": "nn",
|
||||
"authors": [ "patrickgold" ]
|
||||
},
|
||||
{
|
||||
"id": "pl",
|
||||
"authors": [ "Mikołaj Biel" ]
|
||||
},
|
||||
{
|
||||
"id": "pt",
|
||||
"authors": [ "patrickgold" ]
|
||||
},
|
||||
{
|
||||
"id": "pt-BR",
|
||||
"authors": [ "rickym7" ]
|
||||
},
|
||||
{
|
||||
"id": "ro",
|
||||
"authors": [ "bertin0" ]
|
||||
},
|
||||
{
|
||||
"id": "ru",
|
||||
"authors": [ "williamtheaker", "33kk" ]
|
||||
},
|
||||
{
|
||||
"id": "rue",
|
||||
"authors": [ "svvvst" ]
|
||||
},
|
||||
{
|
||||
"id": "sk",
|
||||
"authors": [ "stefan-misik", "majso" ]
|
||||
},
|
||||
{
|
||||
"id": "sr",
|
||||
"authors": [ "hedidnothingwrong", "GrbavaCigla" ]
|
||||
},
|
||||
{
|
||||
"id": "sv",
|
||||
"authors": [ "patrickgold" ]
|
||||
},
|
||||
{
|
||||
"id": "tr",
|
||||
"authors": [ "kisekinopureya", "patrickgold", "dvrnynr" ]
|
||||
},
|
||||
{
|
||||
"id": "uk",
|
||||
"authors": [ "williamtheaker", "33kk" ]
|
||||
},
|
||||
{
|
||||
"id": "ur-PK",
|
||||
"authors": [ "mubashir-rehman", "mirfatif" ]
|
||||
},
|
||||
{
|
||||
"id": "vi-VN",
|
||||
"authors": [ "patrickgold", "Hayleia" ]
|
||||
"label": "Default",
|
||||
"symbolsPrecedingAutoSpace": ".,?‽!\"&%)]}»",
|
||||
"symbolsFollowingAutoSpace": "",
|
||||
"symbolsPrecedingPhantomSpace": ".,;:?‽!&%)]}»©®™",
|
||||
"symbolsFollowingPhantomSpace": "¿⸘¡([{",
|
||||
"symbolsTerminatingSentence": ".?‽!"
|
||||
}
|
||||
],
|
||||
"popupMappings": [
|
||||
{ "id": "default", "authors": [ "patrickgold" ] },
|
||||
{ "id": "ar", "authors": [ "HeiWiper" ] },
|
||||
{ "id": "bg", "authors": [ "iorvethe" ] },
|
||||
{ "id": "ca", "authors": [ "mikelloc" ] },
|
||||
{ "id": "ckb", "authors": [ "GoRaN" ] },
|
||||
{ "id": "cs", "authors": [ "stefan-misik" ] },
|
||||
{ "id": "da", "authors": [ "patrickgold" ] },
|
||||
{ "id": "de", "authors": [ "patrickgold" ] },
|
||||
{ "id": "de-DE-neobone", "authors": [ "ostrya" ] },
|
||||
{ "id": "el", "authors": [ "tsiflimagas" ] },
|
||||
{ "id": "en", "authors": [ "patrickgold" ] },
|
||||
{ "id": "eo", "authors": [ "jeremiah-miller" ] },
|
||||
{ "id": "es", "authors": [ "patrickgold" ] },
|
||||
{ "id": "fa", "authors": [ "PHELAT" ] },
|
||||
{ "id": "fa2", "authors": [ "M-Koushan" ] },
|
||||
{ "id": "fa3", "authors": [ "SaeID-Rz" ] },
|
||||
{ "id": "fi", "authors": [ "patrickgold" ] },
|
||||
{ "id": "fo", "authors": [ "BinFlush" ] },
|
||||
{ "id": "fr", "authors": [ "patrickgold" ] },
|
||||
{ "id": "hr", "authors": [ "hedidnothingwrong" ] },
|
||||
{ "id": "hu", "authors": [ "zoli111, gabik65" ] },
|
||||
{ "id": "hy", "authors": [ "PJTSearch" ] },
|
||||
{ "id": "id", "authors": [ "Linerly" ] },
|
||||
{ "id": "is", "authors": [ "patrickgold" ] },
|
||||
{ "id": "it", "authors": [ "patrickgold" ] },
|
||||
{ "id": "iw", "authors": [ "Antony" ] },
|
||||
{ "id": "ja-JP-jis", "authors": [ "waelwindows" ] },
|
||||
{ "id": "ko", "authors": [ "patrickgold", "Hayleia" ] },
|
||||
{ "id": "ku", "authors": [ "GoRaN" ] },
|
||||
{ "id": "lt", "authors": [ "patrickgold" ] },
|
||||
{ "id": "lv", "authors": [ "patrickgold", "eandersons" ] },
|
||||
{ "id": "nb", "authors": [ "patrickgold" ] },
|
||||
{ "id": "nn", "authors": [ "patrickgold" ] },
|
||||
{ "id": "pl", "authors": [ "Mikołaj Biel" ] },
|
||||
{ "id": "pt", "authors": [ "patrickgold" ] },
|
||||
{ "id": "pt-BR", "authors": [ "rickym7" ] },
|
||||
{ "id": "ro", "authors": [ "bertin0" ] },
|
||||
{ "id": "ru", "authors": [ "williamtheaker", "33kk" ] },
|
||||
{ "id": "rue", "authors": [ "svvvst" ] },
|
||||
{ "id": "sk", "authors": [ "stefan-misik", "majso" ] },
|
||||
{ "id": "sr", "authors": [ "hedidnothingwrong", "GrbavaCigla" ] },
|
||||
{ "id": "sv", "authors": [ "patrickgold" ] },
|
||||
{ "id": "tr", "authors": [ "kisekinopureya", "patrickgold", "dvrnynr" ] },
|
||||
{ "id": "uk", "authors": [ "williamtheaker", "33kk", "honsiorovskyi" ] },
|
||||
{ "id": "uk-cyr-ext", "authors": [ "williamtheaker", "33kk", "honsiorovskyi" ] },
|
||||
{ "id": "ur-PK", "authors": [ "mubashir-rehman", "mirfatif" ] },
|
||||
{ "id": "vi-VN", "authors": [ "patrickgold", "Hayleia" ] }
|
||||
],
|
||||
"subtypePresets": [
|
||||
{
|
||||
"languageTag": "en-US",
|
||||
@@ -393,6 +283,15 @@
|
||||
"characters": "org.florisboard.layouts:danish"
|
||||
}
|
||||
},
|
||||
{
|
||||
"languageTag": "id",
|
||||
"composer": "org.florisboard.composers:appender",
|
||||
"currencySet": "org.florisboard.currencysets:dollar",
|
||||
"popupMapping": "org.florisboard.localization:id",
|
||||
"preferred": {
|
||||
"characters": "org.florisboard.layouts:qwerty"
|
||||
}
|
||||
},
|
||||
{
|
||||
"languageTag": "is-IS",
|
||||
"composer": "org.florisboard.composers:appender",
|
||||
@@ -423,6 +322,30 @@
|
||||
"numericRow": "org.florisboard.layouts:persian"
|
||||
}
|
||||
},
|
||||
{
|
||||
"languageTag": "fa-FA",
|
||||
"composer": "org.florisboard.composers:appender",
|
||||
"currencySet": "org.florisboard.currencysets:rial",
|
||||
"popupMapping": "org.florisboard.localization:fa2",
|
||||
"preferred": {
|
||||
"characters": "org.florisboard.layouts:persian2",
|
||||
"symbols": "org.florisboard.layouts:persian",
|
||||
"symbols2": "org.florisboard.layouts:persian",
|
||||
"numericRow": "org.florisboard.layouts:persian"
|
||||
}
|
||||
},
|
||||
{
|
||||
"languageTag": "fa-FA",
|
||||
"composer": "org.florisboard.composers:appender",
|
||||
"currencySet": "org.florisboard.currencysets:rial",
|
||||
"popupMapping": "org.florisboard.localization:fa3",
|
||||
"preferred": {
|
||||
"characters": "org.florisboard.layouts:persian3",
|
||||
"symbols": "org.florisboard.layouts:persian",
|
||||
"symbols2": "org.florisboard.layouts:persian",
|
||||
"numericRow": "org.florisboard.layouts:western_arabic"
|
||||
}
|
||||
},
|
||||
{
|
||||
"languageTag": "ar",
|
||||
"composer": "org.florisboard.composers:appender",
|
||||
@@ -435,6 +358,15 @@
|
||||
"numericRow": "org.florisboard.layouts:eastern_arabic"
|
||||
}
|
||||
},
|
||||
{
|
||||
"languageTag": "az",
|
||||
"composer": "org.florisboard.composers:appender",
|
||||
"currencySet": "org.florisboard.currencysets:azerbaijani_manat",
|
||||
"popupMapping": "org.florisboard.localization:tr",
|
||||
"preferred": {
|
||||
"characters": "org.florisboard.layouts:azerbaijani"
|
||||
}
|
||||
},
|
||||
{
|
||||
"languageTag": "hu",
|
||||
"composer": "org.florisboard.composers:appender",
|
||||
@@ -462,6 +394,26 @@
|
||||
"characters": "org.florisboard.layouts:qwertz"
|
||||
}
|
||||
},
|
||||
{
|
||||
"languageTag": "hy",
|
||||
"composer": "org.florisboard.composers:appender",
|
||||
"currencySet": "org.florisboard.currencysets:armenian_dram",
|
||||
"popupMapping": "org.florisboard.localization:hy",
|
||||
"preferred": {
|
||||
"characters": "org.florisboard.layouts:western_armenian",
|
||||
"symbols": "org.florisboard.layouts:armenian"
|
||||
}
|
||||
},
|
||||
{
|
||||
"languageTag": "hy",
|
||||
"composer": "org.florisboard.composers:appender",
|
||||
"currencySet": "org.florisboard.currencysets:armenian_dram",
|
||||
"popupMapping": "org.florisboard.localization:hy",
|
||||
"preferred": {
|
||||
"characters": "org.florisboard.layouts:eastern_armenian",
|
||||
"symbols": "org.florisboard.layouts:armenian"
|
||||
}
|
||||
},
|
||||
{
|
||||
"languageTag": "ru",
|
||||
"composer": "org.florisboard.composers:appender",
|
||||
@@ -660,7 +612,7 @@
|
||||
},
|
||||
{
|
||||
"languageTag": "vi-VN",
|
||||
"composer": "org.florisboard.composers:basic-telex",
|
||||
"composer": "org.florisboard.composers:telex",
|
||||
"currencySet": "org.florisboard.currencysets:vietnamese_dong",
|
||||
"popupMapping": "org.florisboard.localization:vi-VN",
|
||||
"preferred": {
|
||||
|
||||
@@ -90,7 +90,7 @@
|
||||
},
|
||||
"uri": {
|
||||
"~right": {
|
||||
"main": { "code": -255, "label": ".ir"},
|
||||
"main": { "code": -255, "label": ".sa"},
|
||||
"relevant": [
|
||||
{ "code": -255, "label": ".gov" },
|
||||
{ "code": -255, "label": ".edu" },
|
||||
|
||||
@@ -11,16 +11,18 @@
|
||||
]
|
||||
},
|
||||
"ی": {
|
||||
"main": { "code": 1610, "label": "ي" },
|
||||
"relevant": [
|
||||
{ "code": 1746, "label": "ے" },
|
||||
{ "code": 1741, "label": "ۍ" },
|
||||
{ "code": 1744, "label": "ې" },
|
||||
{ "code": 1610, "label": "ي" },
|
||||
{ "code": 1597, "label": "ؽ" }
|
||||
{ "code": 1744, "label": "ې" }
|
||||
]
|
||||
},
|
||||
|
||||
|
||||
"ێ": {
|
||||
"main": { "code": 1597, "label": "ؽ" }
|
||||
},
|
||||
|
||||
"ﺋ": {
|
||||
"relevant": [
|
||||
{ "code": 65163, "label": "ﺋ" },
|
||||
@@ -118,19 +120,23 @@
|
||||
"~right": {
|
||||
"main": { "code": 1567, "label": "؟" },
|
||||
"relevant": [
|
||||
{ "code": 64, "label": "@" },
|
||||
{ "code": 35, "label": "#" },
|
||||
{ "code": 40, "label": "(" },
|
||||
{ "code": 41, "label": ")" },
|
||||
{ "code": 171, "label": "«" },
|
||||
{ "code": 187, "label": "»" },
|
||||
{ "code": 60, "label": "<" },
|
||||
{ "code": 62, "label": ">" },
|
||||
{ "code": 1642, "label": "٪" },
|
||||
{ "code": 35, "label": "#" },
|
||||
{ "code": 42, "label": "*" },
|
||||
{ "code": 1563, "label": "؛" },
|
||||
{ "code": 59, "label": ";" },
|
||||
{ "code": 58, "label": ":" },
|
||||
{ "code": 44, "label": "," },
|
||||
{ "code": 1549, "label": "؍" },
|
||||
{ "code": 45, "label": "-" },
|
||||
{ "code": 95, "label": "_" },
|
||||
{ "code": 1600, "label": "▬" },
|
||||
{ "code": 33, "label": "!" },
|
||||
{ "code": 1548, "label": "،" }
|
||||
{ "code": 1563, "label": "؛" },
|
||||
{ "code": 58, "label": ":" },
|
||||
{ "code": 1549, "label": "؍" },
|
||||
{ "code": 1643, "label": "٫" },
|
||||
{ "code": 1548, "label": "،" },
|
||||
{ "code": 33, "label": "!" }
|
||||
]
|
||||
}
|
||||
},
|
||||
|
||||
@@ -2,41 +2,74 @@
|
||||
"all": {
|
||||
"α": {
|
||||
"relevant": [
|
||||
{ "$": "auto_text_key", "code": 940, "label": "ά" }
|
||||
{ "$": "case_selector",
|
||||
"lower": { "code": 940, "label": "ά" },
|
||||
"upper": { "code": 902, "label": "Ά" }
|
||||
}
|
||||
]
|
||||
},
|
||||
"ε": {
|
||||
"relevant": [
|
||||
{ "$": "auto_text_key", "code": 941, "label": "έ" }
|
||||
{ "$": "case_selector",
|
||||
"lower": { "code": 941, "label": "έ" },
|
||||
"upper": { "code": 904, "label": "Έ" }
|
||||
}
|
||||
]
|
||||
},
|
||||
"η": {
|
||||
"relevant": [
|
||||
{ "$": "auto_text_key", "code": 942, "label": "ή" }
|
||||
{ "$": "case_selector",
|
||||
"lower": { "code": 942, "label": "ή" },
|
||||
"upper": { "code": 905, "label": "Ή" }
|
||||
}
|
||||
]
|
||||
},
|
||||
"ι": {
|
||||
"main": { "$": "auto_text_key", "code": 943, "label": "ί" },
|
||||
"main": { "$": "case_selector",
|
||||
"lower": { "code": 943, "label": "ί" },
|
||||
"upper": { "code": 906, "label": "Ί" }
|
||||
},
|
||||
"relevant": [
|
||||
{ "$": "auto_text_key", "code": 912, "label": "ΐ" },
|
||||
{ "$": "auto_text_key", "code": 970, "label": "ϊ" }
|
||||
{ "$": "case_selector",
|
||||
"lower": { "code": 912, "label": "ΐ" },
|
||||
"upper": { "$": "multi_text_key", "codePoints": [921, 776, 769], "label": "Ϊ́" }
|
||||
},
|
||||
{ "$": "case_selector",
|
||||
"lower": { "code": 970, "label": "ϊ" },
|
||||
"upper": { "code": 938, "label": "Ϊ" }
|
||||
}
|
||||
]
|
||||
},
|
||||
"ο": {
|
||||
"relevant": [
|
||||
{ "$": "auto_text_key", "code": 972, "label": "ό" }
|
||||
{ "$": "case_selector",
|
||||
"lower": { "code": 972, "label": "ό" },
|
||||
"upper": { "code": 908, "label": "Ό" }
|
||||
}
|
||||
]
|
||||
},
|
||||
"υ": {
|
||||
"main": { "$": "auto_text_key", "code": 973, "label": "ύ" },
|
||||
"main": { "$": "case_selector",
|
||||
"lower": { "code": 973, "label": "ύ" },
|
||||
"upper": { "code": 910, "label": "Ύ" }
|
||||
},
|
||||
"relevant": [
|
||||
{ "$": "auto_text_key", "code": 944, "label": "ΰ" },
|
||||
{ "$": "auto_text_key", "code": 971, "label": "ϋ" }
|
||||
{ "$": "case_selector",
|
||||
"lower": { "code": 944, "label": "ΰ" },
|
||||
"upper": { "$": "multi_text_key", "codePoints": [933, 776, 769], "label": "Ϋ́" }
|
||||
},
|
||||
{ "$": "case_selector",
|
||||
"lower": { "code": 971, "label": "ϋ" },
|
||||
"upper": { "code": 939, "label": "Ϋ" }
|
||||
}
|
||||
]
|
||||
},
|
||||
"ω": {
|
||||
"relevant": [
|
||||
{ "$": "auto_text_key", "code": 974, "label": "ώ" }
|
||||
{ "$": "case_selector",
|
||||
"lower": { "code": 974, "label": "ώ" },
|
||||
"upper": { "code": 911, "label": "Ώ" }
|
||||
}
|
||||
]
|
||||
},
|
||||
"~right": {
|
||||
|
||||
@@ -8,12 +8,12 @@
|
||||
]
|
||||
},
|
||||
"ا": {
|
||||
"main": { "code": 1570, "label": "آ"},
|
||||
"relevant": [
|
||||
{ "code": 1649, "label": "ٱ" },
|
||||
{ "code": 1569, "label": "ء" },
|
||||
{ "code": 1571, "label": "أ" },
|
||||
{ "code": 1573, "label": "إ" },
|
||||
{ "code": 1570, "label": "آ" }
|
||||
{ "code": 1573, "label": "إ" }
|
||||
]
|
||||
},
|
||||
"ه": {
|
||||
|
||||
@@ -0,0 +1,99 @@
|
||||
{
|
||||
"all": {
|
||||
"ص": {
|
||||
"relevant": [
|
||||
{ "code": 1590, "label": "ض" }
|
||||
]
|
||||
},
|
||||
"half_space": {
|
||||
"relevant": [
|
||||
{ "code": 1622, "label": "ٖ" },
|
||||
{ "code": 1648, "label": "ٰ" },
|
||||
{ "code": 1619, "label": "ٓ" },
|
||||
{ "code": 1615, "label": "ُ" },
|
||||
{ "code": 1616, "label": "ِ" },
|
||||
{ "code": 1614, "label": "َ" },
|
||||
{ "code": 1600, "label": "ـ" },
|
||||
{ "code": 1621, "label": "ٕ" },
|
||||
{ "code": 1618, "label": "ْ" },
|
||||
{ "code": 1617, "label": "ّ" },
|
||||
{ "code": 1612, "label": "ٌ" },
|
||||
{ "code": 1613, "label": "ٍ" },
|
||||
{ "code": 1620, "label": "ٔ" }
|
||||
]
|
||||
},
|
||||
"ی": {
|
||||
"relevant": [
|
||||
{ "code": 1574, "label": "ئ" },
|
||||
{ "code": 1610, "label": "ي" },
|
||||
{ "code": 1746, "label": "ے" }
|
||||
]
|
||||
},
|
||||
"ا": {
|
||||
"main": { "code": 1570, "label": "آ"},
|
||||
"relevant": [
|
||||
{ "code": 1649, "label": "ٱ" },
|
||||
{ "code": 1569, "label": "ء" },
|
||||
{ "code": 1571, "label": "أ" },
|
||||
{ "code": 1573, "label": "إ" }
|
||||
]
|
||||
},
|
||||
"ه": {
|
||||
"relevant": [
|
||||
{ "code": 1729, "label": "ہ" },
|
||||
{ "code": 1728, "label": "ۀ" },
|
||||
{ "code": 1726, "label": "ھ" }
|
||||
]
|
||||
},
|
||||
"ت": {
|
||||
"relevant": [
|
||||
{ "code": 1579, "label": "ث" }
|
||||
]
|
||||
},
|
||||
"ک": {
|
||||
"relevant": [
|
||||
{ "code": 1706, "label": "ڪ"}
|
||||
]
|
||||
},
|
||||
"ط": {
|
||||
"relevant": [
|
||||
{ "code": 1592, "label": "ظ" }
|
||||
]
|
||||
},
|
||||
"ز": {
|
||||
"relevant": [
|
||||
{ "code": 1688, "label": "ژ" }
|
||||
]
|
||||
},
|
||||
"و": {
|
||||
"relevant": [
|
||||
{ "code": 1572, "label": "ؤ" }
|
||||
]
|
||||
},
|
||||
"گ": {
|
||||
"relevant": [
|
||||
{ "code": 1662, "label": "پ" }
|
||||
]
|
||||
},
|
||||
"~right": {
|
||||
"main": { "code": 1567, "label": "؟"},
|
||||
"relevant": [
|
||||
{ "code": 1563, "label": "؛" },
|
||||
{ "code": 58, "label": ":"},
|
||||
{ "code": 33, "label": "!" }
|
||||
]
|
||||
}
|
||||
},
|
||||
"uri": {
|
||||
"~right": {
|
||||
"main": { "code": -255, "label": ".ir"},
|
||||
"relevant": [
|
||||
{ "code": -255, "label": ".gov" },
|
||||
{ "code": -255, "label": ".org" },
|
||||
{ "code": -255, "label": ".edu" },
|
||||
{ "code": -255, "label": ".com" },
|
||||
{ "code": -255, "label": ".net" }
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,69 @@
|
||||
{
|
||||
"all": {
|
||||
"ی": {
|
||||
"main": { "code": 1574, "label": "ئ" },
|
||||
"relevant": [
|
||||
{ "code": 1610, "label": "ي" },
|
||||
{ "code": 1746, "label": "ے" }
|
||||
]
|
||||
},
|
||||
"ا": {
|
||||
"main": { "code": 1570, "label": "آ" },
|
||||
"relevant": [
|
||||
{ "code": 1649, "label": "ٱ" },
|
||||
{ "code": 1569, "label": "ء" },
|
||||
{ "code": 1571, "label": "أ" },
|
||||
{ "code": 1573, "label": "إ" }
|
||||
]
|
||||
},
|
||||
"ه": {
|
||||
"relevant": [
|
||||
{ "code": 1729, "label": "ہ" },
|
||||
{ "code": 1728, "label": "ۀ" },
|
||||
{ "code": 1726, "label": "ھ" }
|
||||
]
|
||||
},
|
||||
"ت": {
|
||||
"relevant": [
|
||||
{ "code": 1577, "label": "ة" }
|
||||
]
|
||||
},
|
||||
"ک": {
|
||||
"relevant": [
|
||||
{ "code": 1706, "label": "ڪ"}
|
||||
]
|
||||
},
|
||||
"ز": {
|
||||
"relevant": [
|
||||
{ "code": 1688, "label": "ژ" }
|
||||
]
|
||||
},
|
||||
"و": {
|
||||
"relevant": [
|
||||
{ "code": 1572, "label": "ؤ" }
|
||||
]
|
||||
},
|
||||
"~right": {
|
||||
"main": { "code": 1611, "label": "ً" },
|
||||
"relevant": [
|
||||
{ "code": 1615, "label": "ُ" },
|
||||
{ "code": 1616, "label": "ِ" },
|
||||
{ "code": 1614, "label": "َ" },
|
||||
{ "code": 1617, "label": "ّ" },
|
||||
{ "code": 1620, "label": "ٔ" }
|
||||
]
|
||||
}
|
||||
},
|
||||
"uri": {
|
||||
"~right": {
|
||||
"main": { "code": -255, "label": ".ir"},
|
||||
"relevant": [
|
||||
{ "code": -255, "label": ".gov" },
|
||||
{ "code": -255, "label": ".org" },
|
||||
{ "code": -255, "label": ".edu" },
|
||||
{ "code": -255, "label": ".com" },
|
||||
{ "code": -255, "label": ".net" }
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -22,6 +22,11 @@
|
||||
{ "$": "auto_text_key", "code": 337, "label": "ő" }
|
||||
]
|
||||
},
|
||||
"ö": {
|
||||
"relevant": [
|
||||
{ "$": "auto_text_key", "code": 337, "label": "ő" }
|
||||
]
|
||||
},
|
||||
"u": {
|
||||
"relevant": [
|
||||
{ "$": "auto_text_key", "code": 250, "label": "ú" },
|
||||
@@ -29,6 +34,11 @@
|
||||
{ "$": "auto_text_key", "code": 369, "label": "ű" }
|
||||
]
|
||||
},
|
||||
"ü": {
|
||||
"relevant": [
|
||||
{ "$": "auto_text_key", "code": 369, "label": "ű" }
|
||||
]
|
||||
},
|
||||
"~right": {
|
||||
"main": { "code": 44, "label": "," },
|
||||
"relevant": [
|
||||
@@ -58,13 +68,13 @@
|
||||
},
|
||||
"uri": {
|
||||
"~right": {
|
||||
"main": { "code": -255, "label": ".com" },
|
||||
"main": { "code": -255, "label": ".hu" },
|
||||
"relevant": [
|
||||
{ "code": -255, "label": ".gov" },
|
||||
{ "code": -255, "label": ".edu" },
|
||||
{ "code": -255, "label": ".hu" },
|
||||
{ "code": -255, "label": ".com" },
|
||||
{ "code": -255, "label": ".net" },
|
||||
{ "code": -255, "label": ".org" },
|
||||
{ "code": -255, "label": ".net" }
|
||||
{ "code": -255, "label": ".eu" },
|
||||
{ "code": -255, "label": ".gov.hu" }
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
{
|
||||
"all": {
|
||||
"ե": {
|
||||
"main": { "$": "auto_text_key", "code": 1415, "label": "և" }
|
||||
},
|
||||
"~right": {
|
||||
"main": { "code": 44, "label": "," },
|
||||
"relevant": [
|
||||
{ "code": 38, "label": "&" },
|
||||
{ "code": 37, "label": "%" },
|
||||
{ "code": 43, "label": "+" },
|
||||
{ "code": 171, "label": "«" },
|
||||
{ "code": 187, "label": "»" },
|
||||
{ "code": 45, "label": "-" },
|
||||
{ "code": 1373, "label": "՝" },
|
||||
{ "code": 1371, "label": "՛" },
|
||||
{ "code": 64, "label": "@" },
|
||||
{ "code": 46, "label": "." },
|
||||
{ "code": 47, "label": "/" },
|
||||
{ "code": 40, "label": "(" },
|
||||
{ "code": 41, "label": ")" },
|
||||
{ "code": 35, "label": "#" },
|
||||
{ "code": 1372, "label": "՜" },
|
||||
{ "code": 1374, "label": "՞" },
|
||||
{ "code": 1415, "label": "և" }
|
||||
]
|
||||
}
|
||||
},
|
||||
"uri": {
|
||||
"~right": {
|
||||
"main": { "code": -255, "label": ".com" },
|
||||
"relevant": [
|
||||
{ "code": -255, "label": ".gov" },
|
||||
{ "code": -255, "label": ".edu" },
|
||||
{ "code": -255, "label": ".gr" },
|
||||
{ "code": -255, "label": ".org" },
|
||||
{ "code": -255, "label": ".net" }
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
{
|
||||
"all": {
|
||||
"e": {
|
||||
"relevant": [
|
||||
{ "$": "auto_text_key", "code": 234, "label": "ê" },
|
||||
{ "$": "auto_text_key", "code": 233, "label": "é" },
|
||||
{ "$": "auto_text_key", "code": 232, "label": "è" }
|
||||
]
|
||||
},
|
||||
"~right": {
|
||||
"main": { "code": 44, "label": "," },
|
||||
"relevant": [
|
||||
{ "code": 38, "label": "&" },
|
||||
{ "code": 37, "label": "%" },
|
||||
{ "code": 43, "label": "+" },
|
||||
{ "code": 34, "label": "\"" },
|
||||
{ "code": 45, "label": "-" },
|
||||
{ "code": 58, "label": ":" },
|
||||
{ "code": 39, "label": "'" },
|
||||
{ "code": 64, "label": "@" },
|
||||
{ "code": 59, "label": ";" },
|
||||
{ "code": 47, "label": "/" },
|
||||
{ "$": "layout_direction_selector",
|
||||
"ltr": { "code": 40, "label": "(" },
|
||||
"rtl": { "code": 41, "label": "(" }
|
||||
},
|
||||
{ "$": "layout_direction_selector",
|
||||
"ltr": { "code": 41, "label": ")" },
|
||||
"rtl": { "code": 40, "label": ")" }
|
||||
},
|
||||
{ "code": 35, "label": "#" },
|
||||
{ "code": 33, "label": "!" },
|
||||
{ "code": 63, "label": "?" }
|
||||
]
|
||||
}
|
||||
},
|
||||
"uri": {
|
||||
"~right": {
|
||||
"main": { "code": -255, "label": ".com" },
|
||||
"relevant": [
|
||||
{ "code": -255, "label": ".id" },
|
||||
{ "code": -255, "label": ".org" },
|
||||
{ "code": -255, "label": ".net" },
|
||||
{ "code": -255, "label": ".co.id"},
|
||||
{ "code": -255, "label": ".go.id"}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -43,8 +43,8 @@
|
||||
},
|
||||
"z": {
|
||||
"relevant": [
|
||||
{ "$": "auto_text_key", "code": 378, "label": "ź" },
|
||||
{ "$": "auto_text_key", "code": 380, "label": "ż" }
|
||||
{ "$": "auto_text_key", "code": 380, "label": "ż" },
|
||||
{ "$": "auto_text_key", "code": 378, "label": "ź" }
|
||||
]
|
||||
},
|
||||
"~right": {
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
{
|
||||
"all": {
|
||||
"a": {
|
||||
"main": { "$": "auto_text_key", "code": 226, "label": "â" }
|
||||
},
|
||||
"c": {
|
||||
"main": { "$": "auto_text_key", "code": 231, "label": "ç" }
|
||||
},
|
||||
@@ -10,13 +13,19 @@
|
||||
"main": { "$": "case_selector",
|
||||
"lower": { "code": 305, "label": "ı" },
|
||||
"upper": { "code": 73, "label": "I" }
|
||||
}
|
||||
},
|
||||
"relevant": [
|
||||
{ "$": "auto_text_key", "code": 238, "label": "î" }
|
||||
]
|
||||
},
|
||||
"ı": {
|
||||
"main": { "$": "case_selector",
|
||||
"lower": { "code": 105, "label": "i" },
|
||||
"upper": { "code": 304, "label": "İ" }
|
||||
}
|
||||
},
|
||||
"relevant": [
|
||||
{ "$": "auto_text_key", "code": 238, "label": "î" }
|
||||
]
|
||||
},
|
||||
"o": {
|
||||
"main": { "$": "auto_text_key", "code": 246, "label": "ö" }
|
||||
@@ -25,7 +34,10 @@
|
||||
"main": { "$": "auto_text_key", "code": 351, "label": "ş" }
|
||||
},
|
||||
"u": {
|
||||
"main": { "$": "auto_text_key", "code": 252, "label": "ü" }
|
||||
"main": { "$": "auto_text_key", "code": 252, "label": "ü" },
|
||||
"relevant": [
|
||||
{ "$": "auto_text_key", "code": 251, "label": "û" }
|
||||
]
|
||||
},
|
||||
"~right": {
|
||||
"main": { "code": 44, "label": "," },
|
||||
|
||||
@@ -0,0 +1,74 @@
|
||||
{
|
||||
"all": {
|
||||
"е": {
|
||||
"relevant": [
|
||||
{ "$": "auto_text_key", "code": 1105, "label": "ё" }
|
||||
]
|
||||
},
|
||||
"у": {
|
||||
"relevant": [
|
||||
{ "$": "auto_text_key", "code": 1118, "label": "ў" }
|
||||
]
|
||||
},
|
||||
"г": {
|
||||
"relevant": [
|
||||
{ "$": "auto_text_key", "code": 1169, "label": "ґ" }
|
||||
]
|
||||
},
|
||||
"і": {
|
||||
"relevant": [
|
||||
{ "$": "auto_text_key", "code": 1111, "label": "ї" },
|
||||
{ "$": "auto_text_key", "code": 1099, "label": "ы" }
|
||||
]
|
||||
},
|
||||
"є": {
|
||||
"relevant": [
|
||||
{ "$": "auto_text_key", "code": 8212, "label": "—" },
|
||||
{ "$": "auto_text_key", "code": 1101, "label": "э" }
|
||||
]
|
||||
},
|
||||
"ь": {
|
||||
"relevant": [
|
||||
{ "$": "auto_text_key", "code": 700, "label": "ʼ" },
|
||||
{ "$": "auto_text_key", "code": 39, "label": "'" },
|
||||
{ "$": "auto_text_key", "code": 1098, "label": "ъ" }
|
||||
]
|
||||
},
|
||||
"~right": {
|
||||
"main": { "code": 44, "label": "," },
|
||||
"relevant": [
|
||||
{ "code": 38, "label": "&" },
|
||||
{ "code": 37, "label": "%" },
|
||||
{ "code": 43, "label": "+" },
|
||||
{ "code": 34, "label": "\"" },
|
||||
{ "code": 45, "label": "-" },
|
||||
{ "code": 58, "label": ":" },
|
||||
{ "code": 39, "label": "'" },
|
||||
{ "code": 64, "label": "@" },
|
||||
{ "code": 59, "label": ";" },
|
||||
{ "code": 47, "label": "/" },
|
||||
{ "$": "layout_direction_selector",
|
||||
"ltr": { "code": 40, "label": "(" },
|
||||
"rtl": { "code": 41, "label": "(" }
|
||||
},
|
||||
{ "$": "layout_direction_selector",
|
||||
"ltr": { "code": 41, "label": ")" },
|
||||
"rtl": { "code": 40, "label": ")" }
|
||||
},
|
||||
{ "code": 35, "label": "#" },
|
||||
{ "code": 33, "label": "!" },
|
||||
{ "code": 63, "label": "?" }
|
||||
]
|
||||
}
|
||||
},
|
||||
"uri": {
|
||||
"~right": {
|
||||
"main": { "code": -255, "label": ".com" },
|
||||
"relevant": [
|
||||
{ "code": -255, "label": ".ua" },
|
||||
{ "code": -255, "label": ".org" },
|
||||
{ "code": -255, "label": ".net" }
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,10 +1,26 @@
|
||||
{
|
||||
"all": {
|
||||
"г": {
|
||||
"relevant": [
|
||||
{ "$": "auto_text_key", "code": 1169, "label": "ґ" }
|
||||
]
|
||||
},
|
||||
"і": {
|
||||
"relevant": [
|
||||
{ "$": "auto_text_key", "code": 1111, "label": "ї" }
|
||||
]
|
||||
},
|
||||
"є": {
|
||||
"relevant": [
|
||||
{ "$": "auto_text_key", "code": 8212, "label": "—" }
|
||||
]
|
||||
},
|
||||
"ь": {
|
||||
"relevant": [
|
||||
{ "$": "auto_text_key", "code": 700, "label": "ʼ" },
|
||||
{ "$": "auto_text_key", "code": 39, "label": "'" }
|
||||
]
|
||||
},
|
||||
"~right": {
|
||||
"main": { "code": 44, "label": "," },
|
||||
"relevant": [
|
||||
@@ -37,7 +53,6 @@
|
||||
"main": { "code": -255, "label": ".com" },
|
||||
"relevant": [
|
||||
{ "code": -255, "label": ".ua" },
|
||||
{ "code": -255, "label": ".edu" },
|
||||
{ "code": -255, "label": ".org" },
|
||||
{ "code": -255, "label": ".net" }
|
||||
]
|
||||
|
||||
@@ -183,7 +183,7 @@
|
||||
},
|
||||
"uri": {
|
||||
"~right": {
|
||||
"main": { "code": -255, "label": ".ir"},
|
||||
"main": { "code": -255, "label": ".pk"},
|
||||
"relevant": [
|
||||
{ "code": -255, "label": ".gov" },
|
||||
{ "code": -255, "label": ".edu" },
|
||||
|
||||
@@ -1,15 +0,0 @@
|
||||
[
|
||||
")",
|
||||
"}",
|
||||
"]",
|
||||
">",
|
||||
|
||||
"&",
|
||||
|
||||
".",
|
||||
",",
|
||||
"?",
|
||||
"!",
|
||||
";",
|
||||
":"
|
||||
]
|
||||
@@ -1,74 +0,0 @@
|
||||
{
|
||||
"$type": "dev.patrickgold.florisboard.ime.theme.Theme",
|
||||
"name": "floris_black",
|
||||
"label": "Floris Black",
|
||||
"authors": [ "serebit" ],
|
||||
"isNightTheme": true,
|
||||
"attributes": {
|
||||
"window": {
|
||||
"colorPrimary": "#388E3C",
|
||||
"colorPrimaryDark": "#306D32",
|
||||
"colorAccent": "#FF9800",
|
||||
"navigationBarColor": "@keyboard/background",
|
||||
"navigationBarLight": "false",
|
||||
"semiTransparentColor": "#20FFFFFF",
|
||||
"textColor": "#EEEEEE"
|
||||
},
|
||||
"keyboard": {
|
||||
"background": "#000000"
|
||||
},
|
||||
"key": {
|
||||
"background": "#212121",
|
||||
"backgroundPressed": "#3D3D3D",
|
||||
"foreground": "@window/textColor",
|
||||
"foregroundPressed": "@window/textColor",
|
||||
"showBorder": "true"
|
||||
},
|
||||
"key:enter": {
|
||||
"background": "@window/colorPrimary",
|
||||
"backgroundPressed": "@window/colorPrimaryDark",
|
||||
"foreground": "@window/textColor",
|
||||
"foregroundPressed": "@window/textColor"
|
||||
},
|
||||
"key:shift:capslock": {
|
||||
"foreground": "@window/colorAccent",
|
||||
"foregroundPressed": "@window/colorAccent"
|
||||
},
|
||||
"media": {
|
||||
"foreground": "@window/textColor",
|
||||
"foregroundAlt": "#BDBDBD"
|
||||
},
|
||||
"oneHanded": {
|
||||
"background": "#000000",
|
||||
"foreground": "@window/textColor"
|
||||
},
|
||||
"popup": {
|
||||
"background": "#424242",
|
||||
"backgroundActive": "#707070",
|
||||
"foreground": "@window/textColor"
|
||||
},
|
||||
"privateMode": {
|
||||
"background": "#7800BF",
|
||||
"foreground": "@window/textColor"
|
||||
},
|
||||
"smartbar": {
|
||||
"background": "transparent",
|
||||
"foreground": "@window/textColor",
|
||||
"foregroundAlt": "#73FFFFFF"
|
||||
},
|
||||
"smartbarButton": {
|
||||
"background": "@key/background",
|
||||
"foreground": "@key/foreground"
|
||||
},
|
||||
"extractEditLayout": {
|
||||
"background": "#282828",
|
||||
"foreground": "@window/textColor",
|
||||
"foregroundAlt": "#73FFFFFF"
|
||||
},
|
||||
"extractActionButton": {
|
||||
"background": "@smartbarButton/background",
|
||||
"foreground": "@smartbarButton/foreground"
|
||||
},
|
||||
"glideTrail": {"foreground": "#20388E3C"}
|
||||
}
|
||||
}
|
||||
@@ -1,77 +0,0 @@
|
||||
{
|
||||
"$type": "dev.patrickgold.florisboard.ime.theme.Theme",
|
||||
"name": "floris_black_borderless",
|
||||
"label": "Floris Black Borderless",
|
||||
"authors": [ "serebit" ],
|
||||
"isNightTheme": true,
|
||||
"attributes": {
|
||||
"window": {
|
||||
"colorPrimary": "#388E3C",
|
||||
"colorPrimaryDark": "#306D32",
|
||||
"colorAccent": "#FF9800",
|
||||
"navigationBarColor": "@keyboard/background",
|
||||
"navigationBarLight": "false",
|
||||
"semiTransparentColor": "#20FFFFFF",
|
||||
"textColor": "#EEEEEE"
|
||||
},
|
||||
"keyboard": {
|
||||
"background": "#000000"
|
||||
},
|
||||
"key": {
|
||||
"background": "transparent",
|
||||
"backgroundPressed": "#7F616161",
|
||||
"foreground": "@window/textColor",
|
||||
"foregroundPressed": "@window/textColor",
|
||||
"showBorder": "false"
|
||||
},
|
||||
"key:enter": {
|
||||
"background": "@window/colorPrimary",
|
||||
"backgroundPressed": "@window/colorPrimaryDark",
|
||||
"foreground": "@window/textColor",
|
||||
"foregroundPressed": "@window/textColor"
|
||||
},
|
||||
"key:shift:capslock": {
|
||||
"foreground": "@window/colorAccent",
|
||||
"foregroundPressed": "@window/colorAccent"
|
||||
},
|
||||
"key:space": {
|
||||
"background": "#46616161"
|
||||
},
|
||||
"media": {
|
||||
"foreground": "@window/textColor",
|
||||
"foregroundAlt": "#BDBDBD"
|
||||
},
|
||||
"oneHanded": {
|
||||
"background": "#000000",
|
||||
"foreground": "@window/textColor"
|
||||
},
|
||||
"popup": {
|
||||
"background": "#363636",
|
||||
"backgroundActive": "#5F5F5F",
|
||||
"foreground": "@window/textColor"
|
||||
},
|
||||
"privateMode": {
|
||||
"background": "#7800BF",
|
||||
"foreground": "@window/textColor"
|
||||
},
|
||||
"smartbar": {
|
||||
"background": "transparent",
|
||||
"foreground": "@window/textColor",
|
||||
"foregroundAlt": "#73FFFFFF"
|
||||
},
|
||||
"smartbarButton": {
|
||||
"background": "#212121",
|
||||
"foreground": "@window/textColor"
|
||||
},
|
||||
"extractEditLayout": {
|
||||
"background": "#282828",
|
||||
"foreground": "@window/textColor",
|
||||
"foregroundAlt": "#73FFFFFF"
|
||||
},
|
||||
"extractActionButton": {
|
||||
"background": "@smartbarButton/background",
|
||||
"foreground": "@smartbarButton/foreground"
|
||||
},
|
||||
"glideTrail": {"foreground": "#20388E3C"}
|
||||
}
|
||||
}
|
||||
@@ -1,74 +0,0 @@
|
||||
{
|
||||
"$type": "dev.patrickgold.florisboard.ime.theme.Theme",
|
||||
"name": "floris_day",
|
||||
"label": "Floris Day",
|
||||
"authors": [ "patrickgold" ],
|
||||
"isNightTheme": false,
|
||||
"attributes": {
|
||||
"window": {
|
||||
"colorPrimary": "#4CAF50",
|
||||
"colorPrimaryDark": "#388E3C",
|
||||
"colorAccent": "#FF9800",
|
||||
"navigationBarColor": "@keyboard/background",
|
||||
"navigationBarLight": "true",
|
||||
"semiTransparentColor": "#20000000",
|
||||
"textColor": "#000000"
|
||||
},
|
||||
"keyboard": {
|
||||
"background": "#E0E0E0"
|
||||
},
|
||||
"key": {
|
||||
"background": "#FFFFFF",
|
||||
"backgroundPressed": "#F5F5F5",
|
||||
"foreground": "@window/textColor",
|
||||
"foregroundPressed": "@window/textColor",
|
||||
"showBorder": "true"
|
||||
},
|
||||
"key:enter": {
|
||||
"background": "@window/colorPrimary",
|
||||
"backgroundPressed": "@window/colorPrimaryDark",
|
||||
"foreground": "#FFFFFF",
|
||||
"foregroundPressed": "#FFFFFF"
|
||||
},
|
||||
"key:shift:capslock": {
|
||||
"foreground": "@window/colorAccent",
|
||||
"foregroundPressed": "@window/colorAccent"
|
||||
},
|
||||
"media": {
|
||||
"foreground": "@window/textColor",
|
||||
"foregroundAlt": "#757575"
|
||||
},
|
||||
"oneHanded": {
|
||||
"background": "#E8F5E9",
|
||||
"foreground": "#424242"
|
||||
},
|
||||
"popup": {
|
||||
"background": "#EEEEEE",
|
||||
"backgroundActive": "#BDBDBD",
|
||||
"foreground": "@window/textColor"
|
||||
},
|
||||
"privateMode": {
|
||||
"background": "#A000FF",
|
||||
"foreground": "#FFFFFF"
|
||||
},
|
||||
"smartbar": {
|
||||
"background": "transparent",
|
||||
"foreground": "@window/textColor",
|
||||
"foregroundAlt": "#8A8A8A"
|
||||
},
|
||||
"smartbarButton": {
|
||||
"background": "@key/background",
|
||||
"foreground": "@key/foreground"
|
||||
},
|
||||
"extractEditLayout": {
|
||||
"background": "#E8E8E8",
|
||||
"foreground": "@window/textColor",
|
||||
"foregroundAlt": "#8A8A8A"
|
||||
},
|
||||
"extractActionButton": {
|
||||
"background": "@smartbarButton/background",
|
||||
"foreground": "@smartbarButton/foreground"
|
||||
},
|
||||
"glideTrail": {"foreground": "#204CAF50"}
|
||||
}
|
||||
}
|
||||
@@ -1,78 +0,0 @@
|
||||
{
|
||||
"$type": "dev.patrickgold.florisboard.ime.theme.Theme",
|
||||
"name": "floris_day_borderless",
|
||||
"label": "Floris Day Borderless",
|
||||
"authors": [ "patrickgold" ],
|
||||
"isNightTheme": false,
|
||||
"attributes": {
|
||||
"window": {
|
||||
"colorPrimary": "#4CAF50",
|
||||
"colorPrimaryDark": "#388E3C",
|
||||
"colorAccent": "#FF9800",
|
||||
"navigationBarColor": "@keyboard/background",
|
||||
"navigationBarLight": "true",
|
||||
"semiTransparentColor": "#20000000",
|
||||
"textColor": "#000000"
|
||||
},
|
||||
"keyboard": {
|
||||
"background": "#E0E0E0"
|
||||
},
|
||||
"key": {
|
||||
"background": "transparent",
|
||||
"backgroundPressed": "#7FF5F5F5",
|
||||
"foreground": "@window/textColor",
|
||||
"foregroundPressed": "@window/textColor",
|
||||
"showBorder": "false"
|
||||
},
|
||||
"key:enter": {
|
||||
"background": "@window/colorPrimary",
|
||||
"backgroundPressed": "@window/colorPrimaryDark",
|
||||
"foreground": "#FFFFFF",
|
||||
"foregroundPressed": "#FFFFFF"
|
||||
},
|
||||
"key:shift:capslock": {
|
||||
"foreground": "@window/colorAccent",
|
||||
"foregroundPressed": "@window/colorAccent"
|
||||
},
|
||||
"key:space": {
|
||||
"background": "#7FF5F5F5",
|
||||
"backgroundPressed": "#FFF5F5F5"
|
||||
},
|
||||
"media": {
|
||||
"foreground": "@window/textColor",
|
||||
"foregroundAlt": "#757575"
|
||||
},
|
||||
"oneHanded": {
|
||||
"background": "#E8F5E9",
|
||||
"foreground": "#424242"
|
||||
},
|
||||
"popup": {
|
||||
"background": "#EEEEEE",
|
||||
"backgroundActive": "#BDBDBD",
|
||||
"foreground": "@window/textColor"
|
||||
},
|
||||
"privateMode": {
|
||||
"background": "#A000FF",
|
||||
"foreground": "#FFFFFF"
|
||||
},
|
||||
"smartbar": {
|
||||
"background": "transparent",
|
||||
"foreground": "@window/textColor",
|
||||
"foregroundAlt": "#8A8A8A"
|
||||
},
|
||||
"smartbarButton": {
|
||||
"background": "#FFFFFF",
|
||||
"foreground": "@window/textColor"
|
||||
},
|
||||
"extractEditLayout": {
|
||||
"background": "#E8E8E8",
|
||||
"foreground": "@window/textColor",
|
||||
"foregroundAlt": "#8A8A8A"
|
||||
},
|
||||
"extractActionButton": {
|
||||
"background": "@smartbarButton/background",
|
||||
"foreground": "@smartbarButton/foreground"
|
||||
},
|
||||
"glideTrail": {"foreground": "#204CAF50"}
|
||||
}
|
||||
}
|
||||
@@ -1,74 +0,0 @@
|
||||
{
|
||||
"$type": "dev.patrickgold.florisboard.ime.theme.Theme",
|
||||
"name": "floris_night",
|
||||
"label": "Floris Night",
|
||||
"authors": [ "patrickgold" ],
|
||||
"isNightTheme": true,
|
||||
"attributes": {
|
||||
"window": {
|
||||
"colorPrimary": "#4CAF50",
|
||||
"colorPrimaryDark": "#388E3C",
|
||||
"colorAccent": "#FF9800",
|
||||
"navigationBarColor": "@keyboard/background",
|
||||
"navigationBarLight": "false",
|
||||
"semiTransparentColor": "#20FFFFFF",
|
||||
"textColor": "#FFFFFF"
|
||||
},
|
||||
"keyboard": {
|
||||
"background": "#212121"
|
||||
},
|
||||
"key": {
|
||||
"background": "#424242",
|
||||
"backgroundPressed": "#616161",
|
||||
"foreground": "@window/textColor",
|
||||
"foregroundPressed": "@window/textColor",
|
||||
"showBorder": "true"
|
||||
},
|
||||
"key:enter": {
|
||||
"background": "@window/colorPrimary",
|
||||
"backgroundPressed": "@window/colorPrimaryDark",
|
||||
"foreground": "#FFFFFF",
|
||||
"foregroundPressed": "#FFFFFF"
|
||||
},
|
||||
"key:shift:capslock": {
|
||||
"foreground": "@window/colorAccent",
|
||||
"foregroundPressed": "@window/colorAccent"
|
||||
},
|
||||
"media": {
|
||||
"foreground": "@window/textColor",
|
||||
"foregroundAlt": "#BDBDBD"
|
||||
},
|
||||
"oneHanded": {
|
||||
"background": "#1B5E20",
|
||||
"foreground": "#EEEEEE"
|
||||
},
|
||||
"popup": {
|
||||
"background": "#757575",
|
||||
"backgroundActive": "#BDBDBD",
|
||||
"foreground": "@window/textColor"
|
||||
},
|
||||
"privateMode": {
|
||||
"background": "#A000FF",
|
||||
"foreground": "#FFFFFF"
|
||||
},
|
||||
"smartbar": {
|
||||
"background": "transparent",
|
||||
"foreground": "@window/textColor",
|
||||
"foregroundAlt": "#73FFFFFF"
|
||||
},
|
||||
"smartbarButton": {
|
||||
"background": "@key/background",
|
||||
"foreground": "@key/foreground"
|
||||
},
|
||||
"extractEditLayout": {
|
||||
"background": "#282828",
|
||||
"foreground": "@window/textColor",
|
||||
"foregroundAlt": "#73FFFFFF"
|
||||
},
|
||||
"extractActionButton": {
|
||||
"background": "@smartbarButton/background",
|
||||
"foreground": "@smartbarButton/foreground"
|
||||
},
|
||||
"glideTrail": {"foreground": "#204CAF50"}
|
||||
}
|
||||
}
|
||||
@@ -1,78 +0,0 @@
|
||||
{
|
||||
"$type": "dev.patrickgold.florisboard.ime.theme.Theme",
|
||||
"name": "floris_night_borderless",
|
||||
"label": "Floris Night Borderless",
|
||||
"authors": [ "patrickgold" ],
|
||||
"isNightTheme": true,
|
||||
"attributes": {
|
||||
"window": {
|
||||
"colorPrimary": "#4CAF50",
|
||||
"colorPrimaryDark": "#388E3C",
|
||||
"colorAccent": "#FF9800",
|
||||
"navigationBarColor": "@keyboard/background",
|
||||
"navigationBarLight": "false",
|
||||
"semiTransparentColor": "#20FFFFFF",
|
||||
"textColor": "#FFFFFF"
|
||||
},
|
||||
"keyboard": {
|
||||
"background": "#212121"
|
||||
},
|
||||
"key": {
|
||||
"background": "transparent",
|
||||
"backgroundPressed": "#7F616161",
|
||||
"foreground": "@window/textColor",
|
||||
"foregroundPressed": "@window/textColor",
|
||||
"showBorder": "false"
|
||||
},
|
||||
"key:enter": {
|
||||
"background": "@window/colorPrimary",
|
||||
"backgroundPressed": "@window/colorPrimaryDark",
|
||||
"foreground": "#FFFFFF",
|
||||
"foregroundPressed": "#FFFFFF"
|
||||
},
|
||||
"key:shift:capslock": {
|
||||
"foreground": "@window/colorAccent",
|
||||
"foregroundPressed": "@window/colorAccent"
|
||||
},
|
||||
"key:space": {
|
||||
"background": "#2F616161",
|
||||
"backgroundPressed": "#7F616161"
|
||||
},
|
||||
"media": {
|
||||
"foreground": "@window/textColor",
|
||||
"foregroundAlt": "#BDBDBD"
|
||||
},
|
||||
"oneHanded": {
|
||||
"background": "#1B5E20",
|
||||
"foreground": "#EEEEEE"
|
||||
},
|
||||
"popup": {
|
||||
"background": "#757575",
|
||||
"backgroundActive": "#BDBDBD",
|
||||
"foreground": "@window/textColor"
|
||||
},
|
||||
"privateMode": {
|
||||
"background": "#A000FF",
|
||||
"foreground": "#FFFFFF"
|
||||
},
|
||||
"smartbar": {
|
||||
"background": "transparent",
|
||||
"foreground": "@window/textColor",
|
||||
"foregroundAlt": "#73FFFFFF"
|
||||
},
|
||||
"smartbarButton": {
|
||||
"background": "#424242",
|
||||
"foreground": "@window/textColor"
|
||||
},
|
||||
"extractEditLayout": {
|
||||
"background": "#282828",
|
||||
"foreground": "@window/textColor",
|
||||
"foregroundAlt": "#73FFFFFF"
|
||||
},
|
||||
"extractActionButton": {
|
||||
"background": "@smartbarButton/background",
|
||||
"foreground": "@smartbarButton/foreground"
|
||||
},
|
||||
"glideTrail": {"foreground": "#204CAF50"}
|
||||
}
|
||||
}
|
||||
@@ -17,6 +17,14 @@
|
||||
"isBorderless": false,
|
||||
"isMaterialYouAware": false
|
||||
},
|
||||
{
|
||||
"id": "floris_day_borderless",
|
||||
"label": "Floris Day (Borderless)",
|
||||
"authors": [ "patrickgold" ],
|
||||
"isNight": false,
|
||||
"isBorderless": true,
|
||||
"isMaterialYouAware": false
|
||||
},
|
||||
{
|
||||
"id": "floris_night",
|
||||
"label": "Floris Night",
|
||||
@@ -24,6 +32,30 @@
|
||||
"isNight": true,
|
||||
"isBorderless": false,
|
||||
"isMaterialYouAware": false
|
||||
},
|
||||
{
|
||||
"id": "floris_night_borderless",
|
||||
"label": "Floris Night (Borderless)",
|
||||
"authors": [ "patrickgold" ],
|
||||
"isNight": true,
|
||||
"isBorderless": true,
|
||||
"isMaterialYouAware": false
|
||||
},
|
||||
{
|
||||
"id": "floris_pure_night",
|
||||
"label": "Floris Pure Night",
|
||||
"authors": [ "serebit" ],
|
||||
"isNight": true,
|
||||
"isBorderless": false,
|
||||
"isMaterialYouAware": false
|
||||
},
|
||||
{
|
||||
"id": "floris_pure_night_borderless",
|
||||
"label": "Floris Pure Night (Borderless)",
|
||||
"authors": [ "serebit" ],
|
||||
"isNight": true,
|
||||
"isBorderless": true,
|
||||
"isMaterialYouAware": false
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -24,8 +24,8 @@
|
||||
"background": "var(--surface)",
|
||||
"foreground": "var(--on-surface)",
|
||||
"font-size": "22sp",
|
||||
"shadow-elevation": "2dp",
|
||||
"shape": "var(--shape)"
|
||||
"shape": "var(--shape)",
|
||||
"shadow-elevation": "2dp"
|
||||
},
|
||||
"key:pressed": {
|
||||
"background": "var(--surface-variant)",
|
||||
@@ -39,7 +39,7 @@
|
||||
"background": "var(--primary-variant)",
|
||||
"foreground": "var(--on-surface)"
|
||||
},
|
||||
"key[code={c:shift}][mode={m:capslock}]": {
|
||||
"key[code={c:shift}][shiftstate={sh:caps_lock}]": {
|
||||
"foreground": "var(--secondary)"
|
||||
},
|
||||
"key[code={c:space}]": {
|
||||
@@ -56,8 +56,8 @@
|
||||
"background": "#eeeeee",
|
||||
"foreground": "var(--on-surface)",
|
||||
"font-size": "22sp",
|
||||
"shadow-elevation": "2dp",
|
||||
"shape": "var(--shape)"
|
||||
"shape": "var(--shape)",
|
||||
"shadow-elevation": "2dp"
|
||||
},
|
||||
"key-popup:focus": {
|
||||
"background": "#bdbdbd",
|
||||
@@ -67,8 +67,8 @@
|
||||
"smartbar-primary-actions-toggle": {
|
||||
"background": "var(--surface)",
|
||||
"foreground": "var(--on-surface)",
|
||||
"shadow-elevation": "2dp",
|
||||
"shape": "circle()"
|
||||
"shape": "circle()",
|
||||
"shadow-elevation": "2dp"
|
||||
},
|
||||
"smartbar-secondary-actions-toggle": {
|
||||
"background": "transparent",
|
||||
@@ -127,15 +127,15 @@
|
||||
"background": "var(--surface)",
|
||||
"foreground": "var(--on-surface)",
|
||||
"font-size": "14sp",
|
||||
"shadow-elevation": "2dp",
|
||||
"shape": "var(--shape-variant)"
|
||||
"shape": "var(--shape-variant)",
|
||||
"shadow-elevation": "2dp"
|
||||
},
|
||||
"clipboard-item-popup": {
|
||||
"background": "var(--surface-variant)",
|
||||
"foreground": "var(--on-surface)",
|
||||
"font-size": "14sp",
|
||||
"shadow-elevation": "2dp",
|
||||
"shape": "var(--shape-variant)"
|
||||
"shape": "var(--shape-variant)",
|
||||
"shadow-elevation": "2dp"
|
||||
},
|
||||
|
||||
"emoji-key": {
|
||||
@@ -152,8 +152,8 @@
|
||||
"background": "#eeeeee",
|
||||
"foreground": "var(--on-surface)",
|
||||
"font-size": "22sp",
|
||||
"shadow-elevation": "2dp",
|
||||
"shape": "var(--shape)"
|
||||
"shape": "var(--shape)",
|
||||
"shadow-elevation": "2dp"
|
||||
},
|
||||
"emoji-tab": {
|
||||
"foreground": "var(--on-background)"
|
||||
@@ -162,6 +162,23 @@
|
||||
"foreground": "var(--primary)"
|
||||
},
|
||||
|
||||
"extracted-landscape-input-layout": {
|
||||
"background": "var(--background)"
|
||||
},
|
||||
"extracted-landscape-input-field": {
|
||||
"background": "transparent",
|
||||
"foreground": "var(--on-background)",
|
||||
"font-size": "16sp",
|
||||
"shape": "rounded-corner(12dp, 12dp, 12dp, 12dp)",
|
||||
"border-color": "var(--secondary)",
|
||||
"border-width": "2dp"
|
||||
},
|
||||
"extracted-landscape-input-action": {
|
||||
"background": "var(--primary)",
|
||||
"foreground": "var(--on-surface)",
|
||||
"shape": "rounded-corner(4dp, 4dp, 4dp, 4dp)"
|
||||
},
|
||||
|
||||
"glide-trail": {
|
||||
"foreground": "var(--primary)"
|
||||
},
|
||||
|
||||
@@ -0,0 +1,192 @@
|
||||
{
|
||||
"@defines": {
|
||||
"--primary": "#4caf50",
|
||||
"--primary-variant": "#388e3c",
|
||||
"--secondary": "#ff9800",
|
||||
"--secondary-variant": "#e65100",
|
||||
"--background": "#e0e0e0",
|
||||
"--surface": "#f0f0f0",
|
||||
"--surface-variant": "#ffffff",
|
||||
|
||||
"--on-background": "#121212",
|
||||
"--on-surface": "#000000",
|
||||
"--on-surface-variant": "#5f5f5f",
|
||||
|
||||
"--shape": "rounded-corner(8dp, 8dp, 8dp, 8dp)",
|
||||
"--shape-variant": "rounded-corner(12dp, 12dp, 12dp, 12dp)"
|
||||
},
|
||||
|
||||
"keyboard": {
|
||||
"background": "var(--background)"
|
||||
},
|
||||
|
||||
"key": {
|
||||
"background": "transparent",
|
||||
"foreground": "var(--on-surface)",
|
||||
"font-size": "22sp",
|
||||
"shape": "var(--shape)"
|
||||
},
|
||||
"key:pressed": {
|
||||
"background": "var(--surface)",
|
||||
"foreground": "var(--on-surface)"
|
||||
},
|
||||
"key[code={c:enter}]": {
|
||||
"background": "var(--primary)",
|
||||
"foreground": "var(--on-surface)"
|
||||
},
|
||||
"key[code={c:enter}]:pressed": {
|
||||
"background": "var(--primary-variant)",
|
||||
"foreground": "var(--on-surface)"
|
||||
},
|
||||
"key[code={c:shift}][shiftstate={sh:caps_lock}]": {
|
||||
"foreground": "var(--secondary)"
|
||||
},
|
||||
"key[code={c:space}]": {
|
||||
"background": "var(--surface)",
|
||||
"foreground": "var(--on-surface-variant)",
|
||||
"font-size": "12sp"
|
||||
},
|
||||
"key-hint": {
|
||||
"background": "transparent",
|
||||
"foreground": "var(--on-surface-variant)",
|
||||
"font-size": "12sp"
|
||||
},
|
||||
"key-popup": {
|
||||
"background": "#eeeeee",
|
||||
"foreground": "var(--on-surface)",
|
||||
"font-size": "22sp",
|
||||
"shape": "var(--shape)",
|
||||
"shadow-elevation": "2dp"
|
||||
},
|
||||
"key-popup:focus": {
|
||||
"background": "#bdbdbd",
|
||||
"foreground": "var(--on-surface)"
|
||||
},
|
||||
|
||||
"smartbar-primary-actions-toggle": {
|
||||
"background": "var(--surface)",
|
||||
"foreground": "var(--on-surface)",
|
||||
"shape": "circle()"
|
||||
},
|
||||
"smartbar-secondary-actions-toggle": {
|
||||
"background": "transparent",
|
||||
"foreground": "var(--on-surface-variant)",
|
||||
"shape": "circle()"
|
||||
},
|
||||
"smartbar-quick-action": {
|
||||
"background": "transparent",
|
||||
"foreground": "var(--on-background)",
|
||||
"shape": "circle()"
|
||||
},
|
||||
"smartbar-key": {
|
||||
"background": "transparent",
|
||||
"foreground": "var(--on-background)",
|
||||
"font-size": "18sp",
|
||||
"shape": "var(--shape)"
|
||||
},
|
||||
"smartbar-key:pressed": {
|
||||
"background": "var(--surface)",
|
||||
"foreground": "var(--on-surface)"
|
||||
},
|
||||
"smartbar-key:disabled": {
|
||||
"background": "transparent",
|
||||
"foreground": "#12121248"
|
||||
},
|
||||
"smartbar-candidate-word": {
|
||||
"background": "transparent",
|
||||
"foreground": "var(--on-background)",
|
||||
"font-size": "14sp",
|
||||
"shape": "rectangle()"
|
||||
},
|
||||
"smartbar-candidate-word:pressed": {
|
||||
"background": "var(--surface)",
|
||||
"foreground": "var(--on-background)"
|
||||
},
|
||||
"smartbar-candidate-clip": {
|
||||
"background": "transparent",
|
||||
"foreground": "var(--on-background)",
|
||||
"font-size": "14sp",
|
||||
"shape": "rounded-corner(8%, 8%, 8%, 8%)"
|
||||
},
|
||||
"smartbar-candidate-clip:pressed": {
|
||||
"background": "var(--surface)",
|
||||
"foreground": "var(--on-background)"
|
||||
},
|
||||
"smartbar-candidate-spacer": {
|
||||
"foreground": "var(--surface)"
|
||||
},
|
||||
|
||||
"clipboard-header": {
|
||||
"background": "transparent",
|
||||
"foreground": "var(--on-surface)",
|
||||
"font-size": "16sp"
|
||||
},
|
||||
"clipboard-item": {
|
||||
"background": "var(--surface)",
|
||||
"foreground": "var(--on-surface)",
|
||||
"font-size": "14sp",
|
||||
"shape": "var(--shape-variant)",
|
||||
"shadow-elevation": "2dp"
|
||||
},
|
||||
"clipboard-item-popup": {
|
||||
"background": "var(--surface-variant)",
|
||||
"foreground": "var(--on-surface)",
|
||||
"font-size": "14sp",
|
||||
"shape": "var(--shape-variant)",
|
||||
"shadow-elevation": "2dp"
|
||||
},
|
||||
|
||||
"emoji-key": {
|
||||
"background": "transparent",
|
||||
"foreground": "var(--on-background)",
|
||||
"font-size": "22sp",
|
||||
"shape": "var(--shape)"
|
||||
},
|
||||
"emoji-key:pressed": {
|
||||
"background": "var(--surface)",
|
||||
"foreground": "var(--on-surface)"
|
||||
},
|
||||
"emoji-key-popup": {
|
||||
"background": "#eeeeee",
|
||||
"foreground": "var(--on-surface)",
|
||||
"font-size": "22sp",
|
||||
"shape": "var(--shape)",
|
||||
"shadow-elevation": "2dp"
|
||||
},
|
||||
"emoji-tab": {
|
||||
"foreground": "var(--on-background)"
|
||||
},
|
||||
"emoji-tab:focus": {
|
||||
"foreground": "var(--primary)"
|
||||
},
|
||||
|
||||
"extracted-landscape-input-layout": {
|
||||
"background": "var(--background)"
|
||||
},
|
||||
"extracted-landscape-input-field": {
|
||||
"background": "transparent",
|
||||
"foreground": "var(--on-background)",
|
||||
"font-size": "16sp",
|
||||
"shape": "rounded-corner(12dp, 12dp, 12dp, 12dp)",
|
||||
"border-color": "var(--secondary)",
|
||||
"border-width": "2dp"
|
||||
},
|
||||
"extracted-landscape-input-action": {
|
||||
"background": "var(--primary)",
|
||||
"foreground": "var(--on-surface)",
|
||||
"shape": "rounded-corner(4dp, 4dp, 4dp, 4dp)"
|
||||
},
|
||||
|
||||
"glide-trail": {
|
||||
"foreground": "var(--primary)"
|
||||
},
|
||||
|
||||
"one-handed-panel": {
|
||||
"background": "#e8f5e9",
|
||||
"foreground": "#424242"
|
||||
},
|
||||
|
||||
"system-nav-bar": {
|
||||
"background": "var(--background)"
|
||||
}
|
||||
}
|
||||
@@ -24,8 +24,8 @@
|
||||
"background": "var(--surface)",
|
||||
"foreground": "var(--on-surface)",
|
||||
"font-size": "22sp",
|
||||
"shadow-elevation": "2dp",
|
||||
"shape": "var(--shape)"
|
||||
"shape": "var(--shape)",
|
||||
"shadow-elevation": "2dp"
|
||||
},
|
||||
"key:pressed": {
|
||||
"background": "var(--surface-variant)",
|
||||
@@ -39,7 +39,7 @@
|
||||
"background": "var(--primary-variant)",
|
||||
"foreground": "var(--on-surface)"
|
||||
},
|
||||
"key[code={c:shift}][mode={m:capslock}]": {
|
||||
"key[code={c:shift}][shiftstate={sh:caps_lock}]": {
|
||||
"foreground": "var(--secondary)"
|
||||
},
|
||||
"key[code={c:space}]": {
|
||||
@@ -56,8 +56,8 @@
|
||||
"background": "#757575",
|
||||
"foreground": "var(--on-surface)",
|
||||
"font-size": "22sp",
|
||||
"shadow-elevation": "2dp",
|
||||
"shape": "var(--shape)"
|
||||
"shape": "var(--shape)",
|
||||
"shadow-elevation": "2dp"
|
||||
},
|
||||
"key-popup:focus": {
|
||||
"background": "#bdbdbd",
|
||||
@@ -67,8 +67,8 @@
|
||||
"smartbar-primary-actions-toggle": {
|
||||
"background": "var(--surface)",
|
||||
"foreground": "var(--on-surface)",
|
||||
"shadow-elevation": "2dp",
|
||||
"shape": "circle()"
|
||||
"shape": "circle()",
|
||||
"shadow-elevation": "2dp"
|
||||
},
|
||||
"smartbar-secondary-actions-toggle": {
|
||||
"background": "transparent",
|
||||
@@ -127,15 +127,15 @@
|
||||
"background": "var(--surface)",
|
||||
"foreground": "var(--on-surface)",
|
||||
"font-size": "14sp",
|
||||
"shadow-elevation": "2dp",
|
||||
"shape": "var(--shape-variant)"
|
||||
"shape": "var(--shape-variant)",
|
||||
"shadow-elevation": "2dp"
|
||||
},
|
||||
"clipboard-item-popup": {
|
||||
"background": "var(--surface-variant)",
|
||||
"foreground": "var(--on-surface)",
|
||||
"font-size": "14sp",
|
||||
"shadow-elevation": "2dp",
|
||||
"shape": "var(--shape-variant)"
|
||||
"shape": "var(--shape-variant)",
|
||||
"shadow-elevation": "2dp"
|
||||
},
|
||||
|
||||
"emoji-key": {
|
||||
@@ -152,8 +152,8 @@
|
||||
"background": "#757575",
|
||||
"foreground": "var(--on-surface)",
|
||||
"font-size": "22sp",
|
||||
"shadow-elevation": "2dp",
|
||||
"shape": "var(--shape)"
|
||||
"shape": "var(--shape)",
|
||||
"shadow-elevation": "2dp"
|
||||
},
|
||||
"emoji-tab": {
|
||||
"foreground": "var(--on-background)"
|
||||
@@ -162,6 +162,23 @@
|
||||
"foreground": "var(--primary)"
|
||||
},
|
||||
|
||||
"extracted-landscape-input-layout": {
|
||||
"background": "var(--background)"
|
||||
},
|
||||
"extracted-landscape-input-field": {
|
||||
"background": "transparent",
|
||||
"foreground": "var(--on-background)",
|
||||
"font-size": "16sp",
|
||||
"shape": "rounded-corner(12dp, 12dp, 12dp, 12dp)",
|
||||
"border-color": "var(--secondary)",
|
||||
"border-width": "2dp"
|
||||
},
|
||||
"extracted-landscape-input-action": {
|
||||
"background": "var(--primary)",
|
||||
"foreground": "var(--on-surface)",
|
||||
"shape": "rounded-corner(4dp, 4dp, 4dp, 4dp)"
|
||||
},
|
||||
|
||||
"glide-trail": {
|
||||
"foreground": "var(--primary)"
|
||||
},
|
||||
|
||||
@@ -0,0 +1,192 @@
|
||||
{
|
||||
"@defines": {
|
||||
"--primary": "#4caf50",
|
||||
"--primary-variant": "#388e3c",
|
||||
"--secondary": "#f57c00",
|
||||
"--secondary-variant": "#e65100",
|
||||
"--background": "#212121",
|
||||
"--surface": "#424242",
|
||||
"--surface-variant": "#616161",
|
||||
|
||||
"--on-background": "#dcdcdc",
|
||||
"--on-surface": "#ffffff",
|
||||
"--on-surface-variant": "#a0a0a0",
|
||||
|
||||
"--shape": "rounded-corner(8dp, 8dp, 8dp, 8dp)",
|
||||
"--shape-variant": "rounded-corner(12dp, 12dp, 12dp, 12dp)"
|
||||
},
|
||||
|
||||
"keyboard": {
|
||||
"background": "var(--background)"
|
||||
},
|
||||
|
||||
"key": {
|
||||
"background": "transparent",
|
||||
"foreground": "var(--on-surface)",
|
||||
"font-size": "22sp",
|
||||
"shape": "var(--shape)"
|
||||
},
|
||||
"key:pressed": {
|
||||
"background": "var(--surface)",
|
||||
"foreground": "var(--on-surface)"
|
||||
},
|
||||
"key[code={c:enter}]": {
|
||||
"background": "var(--primary)",
|
||||
"foreground": "var(--on-surface)"
|
||||
},
|
||||
"key[code={c:enter}]:pressed": {
|
||||
"background": "var(--primary-variant)",
|
||||
"foreground": "var(--on-surface)"
|
||||
},
|
||||
"key[code={c:shift}][shiftstate={sh:caps_lock}]": {
|
||||
"foreground": "var(--secondary)"
|
||||
},
|
||||
"key[code={c:space}]": {
|
||||
"background": "var(--surface)",
|
||||
"foreground": "var(--on-surface-variant)",
|
||||
"font-size": "12sp"
|
||||
},
|
||||
"key-hint": {
|
||||
"background": "transparent",
|
||||
"foreground": "var(--on-surface-variant)",
|
||||
"font-size": "12sp"
|
||||
},
|
||||
"key-popup": {
|
||||
"background": "#757575",
|
||||
"foreground": "var(--on-surface)",
|
||||
"font-size": "22sp",
|
||||
"shape": "var(--shape)",
|
||||
"shadow-elevation": "2dp"
|
||||
},
|
||||
"key-popup:focus": {
|
||||
"background": "#bdbdbd",
|
||||
"foreground": "var(--on-surface)"
|
||||
},
|
||||
|
||||
"smartbar-primary-actions-toggle": {
|
||||
"background": "var(--surface)",
|
||||
"foreground": "var(--on-surface)",
|
||||
"shape": "circle()"
|
||||
},
|
||||
"smartbar-secondary-actions-toggle": {
|
||||
"background": "transparent",
|
||||
"foreground": "var(--on-surface-variant)",
|
||||
"shape": "circle()"
|
||||
},
|
||||
"smartbar-quick-action": {
|
||||
"background": "transparent",
|
||||
"foreground": "var(--on-background)",
|
||||
"shape": "circle()"
|
||||
},
|
||||
"smartbar-key": {
|
||||
"background": "transparent",
|
||||
"foreground": "var(--on-background)",
|
||||
"font-size": "18sp",
|
||||
"shape": "var(--shape)"
|
||||
},
|
||||
"smartbar-key:pressed": {
|
||||
"background": "var(--surface)",
|
||||
"foreground": "var(--on-surface)"
|
||||
},
|
||||
"smartbar-key:disabled": {
|
||||
"background": "transparent",
|
||||
"foreground": "#dcdcdc48"
|
||||
},
|
||||
"smartbar-candidate-word": {
|
||||
"background": "transparent",
|
||||
"foreground": "var(--on-background)",
|
||||
"font-size": "14sp",
|
||||
"shape": "rectangle()"
|
||||
},
|
||||
"smartbar-candidate-word:pressed": {
|
||||
"background": "var(--surface)",
|
||||
"foreground": "var(--on-background)"
|
||||
},
|
||||
"smartbar-candidate-clip": {
|
||||
"background": "transparent",
|
||||
"foreground": "var(--on-background)",
|
||||
"font-size": "14sp",
|
||||
"shape": "rounded-corner(8%, 8%, 8%, 8%)"
|
||||
},
|
||||
"smartbar-candidate-clip:pressed": {
|
||||
"background": "var(--surface)",
|
||||
"foreground": "var(--on-background)"
|
||||
},
|
||||
"smartbar-candidate-spacer": {
|
||||
"foreground": "var(--surface)"
|
||||
},
|
||||
|
||||
"clipboard-header": {
|
||||
"background": "transparent",
|
||||
"foreground": "var(--on-surface)",
|
||||
"font-size": "16sp"
|
||||
},
|
||||
"clipboard-item": {
|
||||
"background": "var(--surface)",
|
||||
"foreground": "var(--on-surface)",
|
||||
"font-size": "14sp",
|
||||
"shape": "var(--shape-variant)",
|
||||
"shadow-elevation": "2dp"
|
||||
},
|
||||
"clipboard-item-popup": {
|
||||
"background": "var(--surface-variant)",
|
||||
"foreground": "var(--on-surface)",
|
||||
"font-size": "14sp",
|
||||
"shape": "var(--shape-variant)",
|
||||
"shadow-elevation": "2dp"
|
||||
},
|
||||
|
||||
"emoji-key": {
|
||||
"background": "transparent",
|
||||
"foreground": "var(--on-background)",
|
||||
"font-size": "22sp",
|
||||
"shape": "var(--shape)"
|
||||
},
|
||||
"emoji-key:pressed": {
|
||||
"background": "var(--surface)",
|
||||
"foreground": "var(--on-surface)"
|
||||
},
|
||||
"emoji-key-popup": {
|
||||
"background": "#757575",
|
||||
"foreground": "var(--on-surface)",
|
||||
"font-size": "22sp",
|
||||
"shape": "var(--shape)",
|
||||
"shadow-elevation": "2dp"
|
||||
},
|
||||
"emoji-tab": {
|
||||
"foreground": "var(--on-background)"
|
||||
},
|
||||
"emoji-tab:focus": {
|
||||
"foreground": "var(--primary)"
|
||||
},
|
||||
|
||||
"extracted-landscape-input-layout": {
|
||||
"background": "var(--background)"
|
||||
},
|
||||
"extracted-landscape-input-field": {
|
||||
"background": "transparent",
|
||||
"foreground": "var(--on-background)",
|
||||
"font-size": "16sp",
|
||||
"shape": "rounded-corner(12dp, 12dp, 12dp, 12dp)",
|
||||
"border-color": "var(--secondary)",
|
||||
"border-width": "2dp"
|
||||
},
|
||||
"extracted-landscape-input-action": {
|
||||
"background": "var(--primary)",
|
||||
"foreground": "var(--on-surface)",
|
||||
"shape": "rounded-corner(4dp, 4dp, 4dp, 4dp)"
|
||||
},
|
||||
|
||||
"glide-trail": {
|
||||
"foreground": "var(--primary)"
|
||||
},
|
||||
|
||||
"one-handed-panel": {
|
||||
"background": "#1b5e20",
|
||||
"foreground": "#eeeeee"
|
||||
},
|
||||
|
||||
"system-nav-bar": {
|
||||
"background": "var(--background)"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,194 @@
|
||||
{
|
||||
"@defines": {
|
||||
"--primary": "#388e3c",
|
||||
"--primary-variant": "#306d32",
|
||||
"--secondary": "#ff9800",
|
||||
"--secondary-variant": "#804c00",
|
||||
"--background": "#000000",
|
||||
"--surface": "#212121",
|
||||
"--surface-variant": "#3d3d3d",
|
||||
|
||||
"--on-background": "#eeeeee",
|
||||
"--on-surface": "#eeeeee",
|
||||
"--on-surface-variant": "#ffffff73",
|
||||
|
||||
"--shape": "rounded-corner(8dp, 8dp, 8dp, 8dp)",
|
||||
"--shape-variant": "rounded-corner(12dp, 12dp, 12dp, 12dp)"
|
||||
},
|
||||
|
||||
"keyboard": {
|
||||
"background": "var(--background)"
|
||||
},
|
||||
|
||||
"key": {
|
||||
"background": "var(--surface)",
|
||||
"foreground": "var(--on-surface)",
|
||||
"font-size": "22sp",
|
||||
"shape": "var(--shape)",
|
||||
"shadow-elevation": "2dp"
|
||||
},
|
||||
"key:pressed": {
|
||||
"background": "var(--surface-variant)",
|
||||
"foreground": "var(--on-surface)"
|
||||
},
|
||||
"key[code={c:enter}]": {
|
||||
"background": "var(--primary)",
|
||||
"foreground": "var(--on-surface)"
|
||||
},
|
||||
"key[code={c:enter}]:pressed": {
|
||||
"background": "var(--primary-variant)",
|
||||
"foreground": "var(--on-surface)"
|
||||
},
|
||||
"key[code={c:shift}][shiftstate={sh:caps_lock}]": {
|
||||
"foreground": "var(--secondary)"
|
||||
},
|
||||
"key[code={c:space}]": {
|
||||
"background": "var(--surface)",
|
||||
"foreground": "var(--on-surface-variant)",
|
||||
"font-size": "12sp"
|
||||
},
|
||||
"key-hint": {
|
||||
"background": "transparent",
|
||||
"foreground": "var(--on-surface-variant)",
|
||||
"font-size": "12sp"
|
||||
},
|
||||
"key-popup": {
|
||||
"background": "#424242",
|
||||
"foreground": "var(--on-surface)",
|
||||
"font-size": "22sp",
|
||||
"shape": "var(--shape)",
|
||||
"shadow-elevation": "2dp"
|
||||
},
|
||||
"key-popup:focus": {
|
||||
"background": "#707070",
|
||||
"foreground": "var(--on-surface)"
|
||||
},
|
||||
|
||||
"smartbar-primary-actions-toggle": {
|
||||
"background": "var(--surface)",
|
||||
"foreground": "var(--on-surface)",
|
||||
"shape": "circle()",
|
||||
"shadow-elevation": "2dp"
|
||||
},
|
||||
"smartbar-secondary-actions-toggle": {
|
||||
"background": "transparent",
|
||||
"foreground": "var(--on-surface-variant)",
|
||||
"shape": "circle()"
|
||||
},
|
||||
"smartbar-quick-action": {
|
||||
"background": "transparent",
|
||||
"foreground": "var(--on-background)",
|
||||
"shape": "circle()"
|
||||
},
|
||||
"smartbar-key": {
|
||||
"background": "transparent",
|
||||
"foreground": "var(--on-background)",
|
||||
"font-size": "18sp",
|
||||
"shape": "var(--shape)"
|
||||
},
|
||||
"smartbar-key:pressed": {
|
||||
"background": "var(--surface)",
|
||||
"foreground": "var(--on-surface)"
|
||||
},
|
||||
"smartbar-key:disabled": {
|
||||
"background": "transparent",
|
||||
"foreground": "#dcdcdc48"
|
||||
},
|
||||
"smartbar-candidate-word": {
|
||||
"background": "transparent",
|
||||
"foreground": "var(--on-background)",
|
||||
"font-size": "14sp",
|
||||
"shape": "rectangle()"
|
||||
},
|
||||
"smartbar-candidate-word:pressed": {
|
||||
"background": "var(--surface)",
|
||||
"foreground": "var(--on-background)"
|
||||
},
|
||||
"smartbar-candidate-clip": {
|
||||
"background": "transparent",
|
||||
"foreground": "var(--on-background)",
|
||||
"font-size": "14sp",
|
||||
"shape": "rounded-corner(8%, 8%, 8%, 8%)"
|
||||
},
|
||||
"smartbar-candidate-clip:pressed": {
|
||||
"background": "var(--surface)",
|
||||
"foreground": "var(--on-background)"
|
||||
},
|
||||
"smartbar-candidate-spacer": {
|
||||
"foreground": "var(--surface)"
|
||||
},
|
||||
|
||||
"clipboard-header": {
|
||||
"background": "transparent",
|
||||
"foreground": "var(--on-surface)",
|
||||
"font-size": "16sp"
|
||||
},
|
||||
"clipboard-item": {
|
||||
"background": "var(--surface)",
|
||||
"foreground": "var(--on-surface)",
|
||||
"font-size": "14sp",
|
||||
"shape": "var(--shape-variant)",
|
||||
"shadow-elevation": "2dp"
|
||||
},
|
||||
"clipboard-item-popup": {
|
||||
"background": "var(--surface-variant)",
|
||||
"foreground": "var(--on-surface)",
|
||||
"font-size": "14sp",
|
||||
"shape": "var(--shape-variant)",
|
||||
"shadow-elevation": "2dp"
|
||||
},
|
||||
|
||||
"emoji-key": {
|
||||
"background": "transparent",
|
||||
"foreground": "var(--on-background)",
|
||||
"font-size": "22sp",
|
||||
"shape": "var(--shape)"
|
||||
},
|
||||
"emoji-key:pressed": {
|
||||
"background": "var(--surface)",
|
||||
"foreground": "var(--on-surface)"
|
||||
},
|
||||
"emoji-key-popup": {
|
||||
"background": "#757575",
|
||||
"foreground": "var(--on-surface)",
|
||||
"font-size": "22sp",
|
||||
"shape": "var(--shape)",
|
||||
"shadow-elevation": "2dp"
|
||||
},
|
||||
"emoji-tab": {
|
||||
"foreground": "var(--on-background)"
|
||||
},
|
||||
"emoji-tab:focus": {
|
||||
"foreground": "var(--primary)"
|
||||
},
|
||||
|
||||
"extracted-landscape-input-layout": {
|
||||
"background": "var(--background)"
|
||||
},
|
||||
"extracted-landscape-input-field": {
|
||||
"background": "transparent",
|
||||
"foreground": "var(--on-background)",
|
||||
"font-size": "16sp",
|
||||
"shape": "rounded-corner(12dp, 12dp, 12dp, 12dp)",
|
||||
"border-color": "var(--secondary-variant)",
|
||||
"border-width": "1dp"
|
||||
},
|
||||
"extracted-landscape-input-action": {
|
||||
"background": "var(--surface)",
|
||||
"foreground": "var(--on-surface)",
|
||||
"shape": "rounded-corner(4dp, 4dp, 4dp, 4dp)"
|
||||
},
|
||||
|
||||
"glide-trail": {
|
||||
"foreground": "var(--primary-variant)"
|
||||
},
|
||||
|
||||
"one-handed-panel": {
|
||||
"background": "#000000",
|
||||
"foreground": "#eeeeee"
|
||||
},
|
||||
|
||||
"system-nav-bar": {
|
||||
"background": "var(--background)"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,193 @@
|
||||
{
|
||||
"@defines": {
|
||||
"--primary": "#388e3c",
|
||||
"--primary-variant": "#306d32",
|
||||
"--secondary": "#ff9800",
|
||||
"--secondary-variant": "#804c00",
|
||||
"--background": "#000000",
|
||||
"--surface": "#212121",
|
||||
"--surface-variant": "#3d3d3d",
|
||||
|
||||
"--on-background": "#eeeeee",
|
||||
"--on-surface": "#eeeeee",
|
||||
"--on-surface-variant": "#ffffff73",
|
||||
|
||||
"--shape": "rounded-corner(8dp, 8dp, 8dp, 8dp)",
|
||||
"--shape-variant": "rounded-corner(12dp, 12dp, 12dp, 12dp)"
|
||||
},
|
||||
|
||||
"keyboard": {
|
||||
"background": "var(--background)"
|
||||
},
|
||||
|
||||
"key": {
|
||||
"background": "transparent",
|
||||
"foreground": "var(--on-surface)",
|
||||
"font-size": "22sp",
|
||||
"shape": "var(--shape)"
|
||||
},
|
||||
"key:pressed": {
|
||||
"background": "#6161617f",
|
||||
"foreground": "var(--on-surface)"
|
||||
},
|
||||
"key[code={c:enter}]": {
|
||||
"background": "var(--primary)",
|
||||
"foreground": "var(--on-surface)"
|
||||
},
|
||||
"key[code={c:enter}]:pressed": {
|
||||
"background": "var(--primary-variant)",
|
||||
"foreground": "var(--on-surface)"
|
||||
},
|
||||
"key[code={c:shift}][shiftstate={sh:caps_lock}]": {
|
||||
"foreground": "var(--secondary)"
|
||||
},
|
||||
"key[code={c:space}]": {
|
||||
"background": "#61616146",
|
||||
"foreground": "var(--on-surface-variant)",
|
||||
"font-size": "12sp"
|
||||
},
|
||||
"key-hint": {
|
||||
"background": "transparent",
|
||||
"foreground": "var(--on-surface-variant)",
|
||||
"font-size": "12sp"
|
||||
},
|
||||
"key-popup": {
|
||||
"background": "#363636",
|
||||
"foreground": "var(--on-surface)",
|
||||
"font-size": "22sp",
|
||||
"shape": "var(--shape)",
|
||||
"shadow-elevation": "2dp"
|
||||
},
|
||||
"key-popup:focus": {
|
||||
"background": "#5F5F5F",
|
||||
"foreground": "var(--on-surface)"
|
||||
},
|
||||
|
||||
"smartbar-primary-actions-toggle": {
|
||||
"background": "var(--surface)",
|
||||
"foreground": "var(--on-surface)",
|
||||
"shape": "circle()",
|
||||
"shadow-elevation": "2dp"
|
||||
},
|
||||
"smartbar-secondary-actions-toggle": {
|
||||
"background": "transparent",
|
||||
"foreground": "var(--on-surface-variant)",
|
||||
"shape": "circle()"
|
||||
},
|
||||
"smartbar-quick-action": {
|
||||
"background": "transparent",
|
||||
"foreground": "var(--on-background)",
|
||||
"shape": "circle()"
|
||||
},
|
||||
"smartbar-key": {
|
||||
"background": "transparent",
|
||||
"foreground": "var(--on-background)",
|
||||
"font-size": "18sp",
|
||||
"shape": "var(--shape)"
|
||||
},
|
||||
"smartbar-key:pressed": {
|
||||
"background": "var(--surface)",
|
||||
"foreground": "var(--on-surface)"
|
||||
},
|
||||
"smartbar-key:disabled": {
|
||||
"background": "transparent",
|
||||
"foreground": "#dcdcdc48"
|
||||
},
|
||||
"smartbar-candidate-word": {
|
||||
"background": "transparent",
|
||||
"foreground": "var(--on-background)",
|
||||
"font-size": "14sp",
|
||||
"shape": "rectangle()"
|
||||
},
|
||||
"smartbar-candidate-word:pressed": {
|
||||
"background": "var(--surface)",
|
||||
"foreground": "var(--on-background)"
|
||||
},
|
||||
"smartbar-candidate-clip": {
|
||||
"background": "transparent",
|
||||
"foreground": "var(--on-background)",
|
||||
"font-size": "14sp",
|
||||
"shape": "rounded-corner(8%, 8%, 8%, 8%)"
|
||||
},
|
||||
"smartbar-candidate-clip:pressed": {
|
||||
"background": "var(--surface)",
|
||||
"foreground": "var(--on-background)"
|
||||
},
|
||||
"smartbar-candidate-spacer": {
|
||||
"foreground": "var(--surface)"
|
||||
},
|
||||
|
||||
"clipboard-header": {
|
||||
"background": "transparent",
|
||||
"foreground": "var(--on-surface)",
|
||||
"font-size": "16sp"
|
||||
},
|
||||
"clipboard-item": {
|
||||
"background": "var(--surface)",
|
||||
"foreground": "var(--on-surface)",
|
||||
"font-size": "14sp",
|
||||
"shape": "var(--shape-variant)",
|
||||
"shadow-elevation": "2dp"
|
||||
},
|
||||
"clipboard-item-popup": {
|
||||
"background": "var(--surface-variant)",
|
||||
"foreground": "var(--on-surface)",
|
||||
"font-size": "14sp",
|
||||
"shape": "var(--shape-variant)",
|
||||
"shadow-elevation": "2dp"
|
||||
},
|
||||
|
||||
"emoji-key": {
|
||||
"background": "transparent",
|
||||
"foreground": "var(--on-background)",
|
||||
"font-size": "22sp",
|
||||
"shape": "var(--shape)"
|
||||
},
|
||||
"emoji-key:pressed": {
|
||||
"background": "var(--surface)",
|
||||
"foreground": "var(--on-surface)"
|
||||
},
|
||||
"emoji-key-popup": {
|
||||
"background": "#757575",
|
||||
"foreground": "var(--on-surface)",
|
||||
"font-size": "22sp",
|
||||
"shape": "var(--shape)",
|
||||
"shadow-elevation": "2dp"
|
||||
},
|
||||
"emoji-tab": {
|
||||
"foreground": "var(--on-background)"
|
||||
},
|
||||
"emoji-tab:focus": {
|
||||
"foreground": "var(--primary)"
|
||||
},
|
||||
|
||||
"extracted-landscape-input-layout": {
|
||||
"background": "var(--background)"
|
||||
},
|
||||
"extracted-landscape-input-field": {
|
||||
"background": "transparent",
|
||||
"foreground": "var(--on-background)",
|
||||
"font-size": "16sp",
|
||||
"shape": "rounded-corner(12dp, 12dp, 12dp, 12dp)",
|
||||
"border-color": "var(--secondary-variant)",
|
||||
"border-width": "1dp"
|
||||
},
|
||||
"extracted-landscape-input-action": {
|
||||
"background": "var(--surface)",
|
||||
"foreground": "var(--on-surface)",
|
||||
"shape": "rounded-corner(4dp, 4dp, 4dp, 4dp)"
|
||||
},
|
||||
|
||||
"glide-trail": {
|
||||
"foreground": "var(--primary-variant)"
|
||||
},
|
||||
|
||||
"one-handed-panel": {
|
||||
"background": "#000000",
|
||||
"foreground": "#eeeeee"
|
||||
},
|
||||
|
||||
"system-nav-bar": {
|
||||
"background": "var(--background)"
|
||||
}
|
||||
}
|
||||
8108
app/src/main/baseline-prof.txt
Normal file
8108
app/src/main/baseline-prof.txt
Normal file
File diff suppressed because it is too large
Load Diff
14
app/src/main/config/libraries/google-material-icons.json
Normal file
14
app/src/main/config/libraries/google-material-icons.json
Normal file
@@ -0,0 +1,14 @@
|
||||
{
|
||||
"uniqueId": "google-material-icons",
|
||||
"name": "Google Material Icons",
|
||||
"developers": [
|
||||
{
|
||||
"name": "Google Inc.",
|
||||
"organisationUrl": "https://github.com/google"
|
||||
}
|
||||
],
|
||||
"website": "https://github.com/google/material-design-icons",
|
||||
"licenses": [
|
||||
"Apache-2.0"
|
||||
]
|
||||
}
|
||||
14
app/src/main/config/libraries/icu4c.json
Normal file
14
app/src/main/config/libraries/icu4c.json
Normal file
@@ -0,0 +1,14 @@
|
||||
{
|
||||
"uniqueId": "icu4c",
|
||||
"name": "ICU4C Native C library",
|
||||
"developers": [
|
||||
{
|
||||
"name": "The Unicode Consortium",
|
||||
"organisationUrl": "https://github.com/unicode-org"
|
||||
}
|
||||
],
|
||||
"website": "https://github.com/unicode-org/icu",
|
||||
"licenses": [
|
||||
"icu4c"
|
||||
]
|
||||
}
|
||||
6
app/src/main/config/licenses/icu4c.json
Normal file
6
app/src/main/config/licenses/icu4c.json
Normal file
File diff suppressed because one or more lines are too long
@@ -18,17 +18,12 @@ add_library(ICU::uc STATIC IMPORTED)
|
||||
set_property(TARGET ICU::uc PROPERTY IMPORTED_LOCATION "${JNI_LIBS}/libicuuc.a")
|
||||
|
||||
### FlorisBoard ###
|
||||
add_subdirectory(nuspell)
|
||||
add_subdirectory(utils)
|
||||
add_subdirectory(ime/nlp)
|
||||
add_subdirectory(ime/spelling)
|
||||
|
||||
add_library(
|
||||
florisboard-native
|
||||
SHARED
|
||||
dev_patrickgold_florisboard_FlorisApplication.cpp
|
||||
dev_patrickgold_florisboard_ime_nlp_SuggestionList.cpp
|
||||
dev_patrickgold_florisboard_ime_spelling_SpellingDict.cpp
|
||||
)
|
||||
|
||||
target_compile_options(florisboard-native PRIVATE -ffunction-sections -fdata-sections -fexceptions)
|
||||
@@ -41,8 +36,5 @@ target_link_libraries(
|
||||
log
|
||||
ICU::uc
|
||||
ICU::data
|
||||
Nuspell::nuspell
|
||||
utils
|
||||
ime-nlp
|
||||
ime-spelling
|
||||
)
|
||||
|
||||
@@ -25,9 +25,8 @@
|
||||
extern "C"
|
||||
JNIEXPORT jint JNICALL
|
||||
Java_dev_patrickgold_florisboard_FlorisApplication_00024Companion_nativeInitICUData(
|
||||
JNIEnv *env,
|
||||
jobject thiz,
|
||||
jobject path) {
|
||||
JNIEnv *env, jobject thiz, jobject path)
|
||||
{
|
||||
auto path_str = utils::j2std_string(env, path);
|
||||
std::ifstream in_file(path_str, std::ios::in | std::ios::binary);
|
||||
if (!in_file) {
|
||||
@@ -42,6 +41,7 @@ Java_dev_patrickgold_florisboard_FlorisApplication_00024Companion_nativeInitICUD
|
||||
char *icu_data = new char[size + 1];
|
||||
in_file.read(icu_data, size);
|
||||
if (!in_file) {
|
||||
delete[] icu_data;
|
||||
in_file.close();
|
||||
return U_FILE_ACCESS_ERROR;
|
||||
}
|
||||
|
||||
@@ -1,123 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2021 Patrick Goldinger
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include <jni.h>
|
||||
#include "ime/nlp/suggestion_list.h"
|
||||
|
||||
#pragma ide diagnostic ignored "UnusedLocalVariable"
|
||||
|
||||
using namespace ime::nlp;
|
||||
|
||||
extern "C"
|
||||
JNIEXPORT jlong JNICALL
|
||||
Java_dev_patrickgold_florisboard_ime_nlp_SuggestionList_00024Companion_nativeInitialize(
|
||||
JNIEnv *env,
|
||||
jobject thiz,
|
||||
jint max_size) {
|
||||
auto *suggestionList = new SuggestionList(max_size);
|
||||
return reinterpret_cast<jlong>(suggestionList);
|
||||
}
|
||||
|
||||
extern "C"
|
||||
JNIEXPORT void JNICALL
|
||||
Java_dev_patrickgold_florisboard_ime_nlp_SuggestionList_00024Companion_nativeDispose(
|
||||
JNIEnv *env,
|
||||
jobject thiz,
|
||||
jlong native_ptr) {
|
||||
auto *suggestionList = reinterpret_cast<SuggestionList *>(native_ptr);
|
||||
suggestionList->clear();
|
||||
delete suggestionList;
|
||||
}
|
||||
|
||||
extern "C"
|
||||
JNIEXPORT jboolean JNICALL
|
||||
Java_dev_patrickgold_florisboard_ime_nlp_SuggestionList_00024Companion_nativeAdd(
|
||||
JNIEnv *env,
|
||||
jobject thiz,
|
||||
jlong native_ptr,
|
||||
jstring word,
|
||||
jint freq) {
|
||||
const char *cWord = env->GetStringUTFChars(word, nullptr);
|
||||
word_t stdWord = word_t(cWord);
|
||||
env->ReleaseStringUTFChars(word, cWord);
|
||||
auto *suggestionList = reinterpret_cast<SuggestionList *>(native_ptr);
|
||||
return suggestionList->add(std::move(stdWord), freq);
|
||||
}
|
||||
|
||||
extern "C"
|
||||
JNIEXPORT void JNICALL
|
||||
Java_dev_patrickgold_florisboard_ime_nlp_SuggestionList_00024Companion_nativeClear(
|
||||
JNIEnv *env,
|
||||
jobject thiz,
|
||||
jlong native_ptr) {
|
||||
auto *suggestionList = reinterpret_cast<SuggestionList *>(native_ptr);
|
||||
suggestionList->clear();
|
||||
}
|
||||
|
||||
extern "C"
|
||||
JNIEXPORT jboolean JNICALL
|
||||
Java_dev_patrickgold_florisboard_ime_nlp_SuggestionList_00024Companion_nativeContains(
|
||||
JNIEnv *env,
|
||||
jobject thiz,
|
||||
jlong native_ptr,
|
||||
jstring element) {
|
||||
const char *cWord = env->GetStringUTFChars(element, nullptr);
|
||||
const word_t stdWord = word_t(cWord);
|
||||
env->ReleaseStringUTFChars(element, cWord);
|
||||
auto *suggestionList = reinterpret_cast<SuggestionList *>(native_ptr);
|
||||
return suggestionList->containsWord(stdWord);
|
||||
}
|
||||
|
||||
extern "C"
|
||||
JNIEXPORT jstring JNICALL
|
||||
Java_dev_patrickgold_florisboard_ime_nlp_SuggestionList_00024Companion_nativeGetOrNull(
|
||||
JNIEnv *env,
|
||||
jobject thiz,
|
||||
jlong native_ptr,
|
||||
jint index) {
|
||||
auto *suggestionList = reinterpret_cast<SuggestionList *>(native_ptr);
|
||||
auto weightedToken = suggestionList->get(index);
|
||||
if (weightedToken == nullptr) {
|
||||
return nullptr;
|
||||
}
|
||||
return env->NewStringUTF(weightedToken->data.c_str());
|
||||
}
|
||||
|
||||
extern "C"
|
||||
JNIEXPORT jint JNICALL
|
||||
Java_dev_patrickgold_florisboard_ime_nlp_SuggestionList_00024Companion_nativeSize(
|
||||
JNIEnv *env,
|
||||
jobject thiz,
|
||||
jlong native_ptr) {
|
||||
auto *suggestionList = reinterpret_cast<SuggestionList *>(native_ptr);
|
||||
return suggestionList->size();
|
||||
}
|
||||
|
||||
extern "C"
|
||||
JNIEXPORT jboolean JNICALL
|
||||
Java_dev_patrickgold_florisboard_ime_nlp_SuggestionList_00024Companion_nativeGetIsPrimaryTokenAutoInsert(
|
||||
JNIEnv *env, jobject thiz, jlong native_ptr) {
|
||||
auto *suggestionList = reinterpret_cast<SuggestionList *>(native_ptr);
|
||||
return suggestionList->isPrimaryTokenAutoInsert;
|
||||
}
|
||||
|
||||
extern "C"
|
||||
JNIEXPORT void JNICALL
|
||||
Java_dev_patrickgold_florisboard_ime_nlp_SuggestionList_00024Companion_nativeSetIsPrimaryTokenAutoInsert(
|
||||
JNIEnv *env, jobject thiz, jlong native_ptr, jboolean v) {
|
||||
auto *suggestionList = reinterpret_cast<SuggestionList *>(native_ptr);
|
||||
suggestionList->isPrimaryTokenAutoInsert = v;
|
||||
}
|
||||
@@ -1,90 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2021 Patrick Goldinger
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include <jni.h>
|
||||
#include <algorithm>
|
||||
#include "ime/spelling/spellingdict.h"
|
||||
#include "utils/jni_utils.h"
|
||||
|
||||
#pragma ide diagnostic ignored "UnusedLocalVariable"
|
||||
|
||||
using namespace ime::spellcheck;
|
||||
|
||||
extern "C"
|
||||
JNIEXPORT jlong JNICALL
|
||||
Java_dev_patrickgold_florisboard_ime_spelling_SpellingDict_00024Companion_nativeInitialize(
|
||||
JNIEnv *env,
|
||||
jobject thiz,
|
||||
jobject base_path) {
|
||||
auto strBasePath = utils::j2std_string(env, base_path);
|
||||
|
||||
auto *spellingDict = SpellingDict::load(strBasePath);
|
||||
|
||||
if (spellingDict == nullptr) {
|
||||
return 0L;
|
||||
} else {
|
||||
return reinterpret_cast<jlong>(spellingDict);
|
||||
}
|
||||
}
|
||||
|
||||
extern "C"
|
||||
JNIEXPORT void JNICALL
|
||||
Java_dev_patrickgold_florisboard_ime_spelling_SpellingDict_00024Companion_nativeDispose(
|
||||
JNIEnv *env,
|
||||
jobject thiz,
|
||||
jlong native_ptr) {
|
||||
auto spellingDict = reinterpret_cast<SpellingDict *>(native_ptr);
|
||||
|
||||
delete spellingDict;
|
||||
}
|
||||
|
||||
extern "C"
|
||||
JNIEXPORT jboolean JNICALL
|
||||
Java_dev_patrickgold_florisboard_ime_spelling_SpellingDict_00024Companion_nativeSpell(
|
||||
JNIEnv *env,
|
||||
jobject thiz,
|
||||
jlong native_ptr,
|
||||
jobject word) {
|
||||
auto strWord = utils::j2std_string(env, word);
|
||||
|
||||
auto spellingDict = reinterpret_cast<SpellingDict *>(native_ptr);
|
||||
auto result = spellingDict->spell(strWord);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
extern "C"
|
||||
JNIEXPORT jobjectArray JNICALL
|
||||
Java_dev_patrickgold_florisboard_ime_spelling_SpellingDict_00024Companion_nativeSuggest(
|
||||
JNIEnv *env,
|
||||
jobject thiz,
|
||||
jlong native_ptr,
|
||||
jobject word,
|
||||
jint limit) {
|
||||
auto strWord = utils::j2std_string(env, word);
|
||||
|
||||
auto spellingDict = reinterpret_cast<SpellingDict *>(native_ptr);
|
||||
auto result = spellingDict->suggest(strWord);
|
||||
auto retSize = std::min(result.size(), (size_t)std::max(0, limit));
|
||||
|
||||
jclass jByteArrayClass = env->FindClass("java/nio/ByteBuffer");
|
||||
jobjectArray jSuggestions = env->NewObjectArray(retSize, jByteArrayClass, nullptr);
|
||||
for (int n = 0; n < retSize; n++) {
|
||||
env->SetObjectArrayElement(jSuggestions, n, utils::std2j_string(env, result[n]));
|
||||
}
|
||||
|
||||
return jSuggestions;
|
||||
}
|
||||
@@ -1,13 +0,0 @@
|
||||
add_library(
|
||||
# Name
|
||||
ime-nlp
|
||||
|
||||
# Headers
|
||||
nlp.h
|
||||
token.h
|
||||
suggestion_list.h
|
||||
|
||||
# Sources
|
||||
token.cpp
|
||||
suggestion_list.cpp
|
||||
)
|
||||
@@ -1,98 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2021 Patrick Goldinger
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "suggestion_list.h"
|
||||
|
||||
#include <utility>
|
||||
|
||||
using namespace ime::nlp;
|
||||
|
||||
SuggestionList::SuggestionList(size_t _maxSize) :
|
||||
maxSize(_maxSize), internalSize(0), tokens(_maxSize), isPrimaryTokenAutoInsert(false)
|
||||
{ }
|
||||
|
||||
SuggestionList::~SuggestionList() = default;
|
||||
|
||||
bool SuggestionList::add(word_t &&word, freq_t &&freq) {
|
||||
auto entryIndex = indexOfWord(word);
|
||||
if (entryIndex.has_value()) {
|
||||
// Word exists already
|
||||
auto entry = tokens[entryIndex.value()];
|
||||
if (entry.freq < freq) {
|
||||
// Need to update freq
|
||||
entry.freq = freq;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
if (internalSize < maxSize) {
|
||||
tokens[internalSize++] = WeightedToken(std::move(word), freq);
|
||||
} else {
|
||||
auto last = tokens[internalSize - 1];
|
||||
if (last.freq < freq) {
|
||||
tokens[internalSize - 1] = WeightedToken(std::move(word), freq);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
std::sort(tokens.begin(), tokens.begin() + internalSize, std::greater<>());
|
||||
return true;
|
||||
}
|
||||
|
||||
void SuggestionList::clear() {
|
||||
internalSize = 0;
|
||||
isPrimaryTokenAutoInsert = false;
|
||||
}
|
||||
|
||||
bool SuggestionList::contains(const WeightedToken &element) const {
|
||||
return indexOf(element).has_value();
|
||||
}
|
||||
|
||||
bool SuggestionList::containsWord(const word_t &word) const {
|
||||
return indexOfWord(word).has_value();
|
||||
}
|
||||
|
||||
const WeightedToken *SuggestionList::get(size_t index) const {
|
||||
if (index < 0 || index >= internalSize) return nullptr;
|
||||
return &tokens[index];
|
||||
}
|
||||
|
||||
std::optional<size_t> SuggestionList::indexOf(const WeightedToken &element) const {
|
||||
for (size_t n = 0; n < internalSize; n++) {
|
||||
if (element == tokens[n]) {
|
||||
return n;
|
||||
}
|
||||
}
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
std::optional<size_t> SuggestionList::indexOfWord(const word_t &word) const {
|
||||
for (size_t n = 0; n < internalSize; n++) {
|
||||
if (word == tokens[n].data) {
|
||||
return n;
|
||||
}
|
||||
}
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
bool SuggestionList::isEmpty() const {
|
||||
return internalSize == 0;
|
||||
}
|
||||
|
||||
size_t SuggestionList::size() const {
|
||||
return internalSize;
|
||||
}
|
||||
@@ -1,51 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2021 Patrick Goldinger
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef FLORISBOARD_SUGGESTION_LIST_H
|
||||
#define FLORISBOARD_SUGGESTION_LIST_H
|
||||
|
||||
#include <optional>
|
||||
#include <vector>
|
||||
#include "token.h"
|
||||
|
||||
namespace ime::nlp {
|
||||
|
||||
class SuggestionList {
|
||||
public:
|
||||
SuggestionList(size_t _maxSize);
|
||||
~SuggestionList();
|
||||
|
||||
bool add(word_t &&word, freq_t &&freq);
|
||||
void clear();
|
||||
bool contains(const WeightedToken &element) const;
|
||||
bool containsWord(const word_t &word) const;
|
||||
const WeightedToken *get(size_t index) const;
|
||||
std::optional<size_t> indexOf(const WeightedToken &element) const;
|
||||
std::optional<size_t> indexOfWord(const word_t &word) const;
|
||||
bool isEmpty() const;
|
||||
size_t size() const;
|
||||
|
||||
bool isPrimaryTokenAutoInsert;
|
||||
|
||||
private:
|
||||
std::vector<WeightedToken> tokens;
|
||||
size_t internalSize;
|
||||
size_t maxSize;
|
||||
};
|
||||
|
||||
} // namespace ime::nlp
|
||||
|
||||
#endif // FLORISBOARD_SUGGESTION_LIST_H
|
||||
@@ -1,61 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2021 Patrick Goldinger
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "token.h"
|
||||
|
||||
#include <utility>
|
||||
|
||||
namespace ime::nlp {
|
||||
|
||||
Token::Token() : data() {}
|
||||
Token::Token(word_t &&_data) : data(std::move(_data)) {}
|
||||
|
||||
bool operator==(const Token &t1, const Token &t2) {
|
||||
return t1.data == t2.data;
|
||||
}
|
||||
|
||||
bool operator!=(const Token &t1, const Token &t2) {
|
||||
return !(t1 == t2);
|
||||
}
|
||||
|
||||
WeightedToken::WeightedToken() : Token(), freq(0) {}
|
||||
WeightedToken::WeightedToken(word_t &&_data, freq_t _freq) : Token(std::move(_data)), freq(_freq) {}
|
||||
|
||||
bool operator==(const WeightedToken &t1, const WeightedToken &t2) {
|
||||
return t1.data == t2.data && t1.freq == t2.freq;
|
||||
}
|
||||
|
||||
bool operator!=(const WeightedToken &t1, const WeightedToken &t2) {
|
||||
return !(t1 == t2);
|
||||
}
|
||||
|
||||
bool operator<(const WeightedToken &t1, const WeightedToken &t2) {
|
||||
return t1.freq < t2.freq;
|
||||
}
|
||||
|
||||
bool operator<=(const WeightedToken &t1, const WeightedToken &t2) {
|
||||
return t1.freq <= t2.freq;
|
||||
}
|
||||
|
||||
bool operator>(const WeightedToken &t1, const WeightedToken &t2) {
|
||||
return t1.freq > t2.freq;
|
||||
}
|
||||
|
||||
bool operator>=(const WeightedToken &t1, const WeightedToken &t2) {
|
||||
return t1.freq >= t2.freq;
|
||||
}
|
||||
|
||||
} // namespace ime::nlp
|
||||
@@ -1,51 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2021 Patrick Goldinger
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef FLORISBOARD_TOKEN_H
|
||||
#define FLORISBOARD_TOKEN_H
|
||||
|
||||
#include "nlp.h"
|
||||
#include <string>
|
||||
|
||||
namespace ime::nlp {
|
||||
|
||||
class Token {
|
||||
public:
|
||||
word_t data;
|
||||
Token();
|
||||
Token(word_t &&_data);
|
||||
|
||||
friend bool operator==(const Token &t1, const Token &t2);
|
||||
friend bool operator!=(const Token &t1, const Token &t2);
|
||||
};
|
||||
|
||||
class WeightedToken : public Token {
|
||||
public:
|
||||
freq_t freq;
|
||||
WeightedToken();
|
||||
WeightedToken(word_t &&_data, freq_t _freq);
|
||||
|
||||
friend bool operator==(const WeightedToken &t1, const WeightedToken &t2);
|
||||
friend bool operator!=(const WeightedToken &t1, const WeightedToken &t2);
|
||||
friend bool operator<(const WeightedToken &t1, const WeightedToken &t2);
|
||||
friend bool operator<=(const WeightedToken &t1, const WeightedToken &t2);
|
||||
friend bool operator>(const WeightedToken &t1, const WeightedToken &t2);
|
||||
friend bool operator>=(const WeightedToken &t1, const WeightedToken &t2);
|
||||
};
|
||||
|
||||
} // namespace ime::nlp
|
||||
|
||||
#endif // FLORISBOARD_TOKEN_H
|
||||
@@ -1,10 +0,0 @@
|
||||
add_library(
|
||||
# Name
|
||||
ime-spelling
|
||||
|
||||
# Headers
|
||||
spellingdict.h
|
||||
|
||||
# Sources
|
||||
spellingdict.cpp
|
||||
)
|
||||
@@ -1,51 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2021 Patrick Goldinger
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "spellingdict.h"
|
||||
#include "utils/log.h"
|
||||
|
||||
using namespace ime::spellcheck;
|
||||
|
||||
SpellingDict::SpellingDict(const nuspell::Dictionary& dict) : dictionary(std::make_unique<nuspell::Dictionary>(dict))
|
||||
{ }
|
||||
|
||||
SpellingDict::~SpellingDict() = default;
|
||||
|
||||
SpellingDict* SpellingDict::load(const std::string &basePath) {
|
||||
utils::start_stdout_stderr_logger("spell-floris");
|
||||
try {
|
||||
auto temp = nuspell::Dictionary::load_from_path(basePath);
|
||||
auto spellingDict = new SpellingDict(temp);
|
||||
return spellingDict;
|
||||
} catch (const nuspell::Dictionary_Loading_Error& e) {
|
||||
utils::log_error("SpellingDict.load()", e.what());
|
||||
return nullptr;
|
||||
} catch (...) {
|
||||
utils::log_error("SpellingDict.load()", "An unknown error occurred!");
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
bool SpellingDict::spell(const std::string& word) {
|
||||
bool result = dictionary->spell(word);
|
||||
return result;
|
||||
}
|
||||
|
||||
std::vector<std::string> SpellingDict::suggest(const std::string &word) {
|
||||
auto result = std::vector<std::string>();
|
||||
dictionary->suggest(word, result);
|
||||
return result;
|
||||
}
|
||||
@@ -1,42 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2021 Patrick Goldinger
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef FLORISBOARD_SPELLINGDICT_H
|
||||
#define FLORISBOARD_SPELLINGDICT_H
|
||||
|
||||
#include "nuspell/dictionary.hxx"
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
namespace ime::spellcheck {
|
||||
|
||||
class SpellingDict {
|
||||
public:
|
||||
SpellingDict(const nuspell::Dictionary& dict);
|
||||
~SpellingDict();
|
||||
|
||||
static SpellingDict* load(const std::string& basePath);
|
||||
|
||||
bool spell(const std::string& word);
|
||||
std::vector<std::string> suggest(const std::string& word);
|
||||
|
||||
private:
|
||||
std::unique_ptr<nuspell::Dictionary> dictionary;
|
||||
};
|
||||
|
||||
} // namespace ime::spellcheck
|
||||
|
||||
#endif // FLORISBOARD_SPELLINGDICT_H
|
||||
@@ -1,10 +0,0 @@
|
||||
add_library(nuspell
|
||||
aff_data.cxx aff_data.hxx
|
||||
checker.cxx checker.hxx
|
||||
suggester.cxx suggester.hxx
|
||||
dictionary.cxx dictionary.hxx
|
||||
unicode.hxx
|
||||
utils.cxx utils.hxx
|
||||
structures.hxx)
|
||||
|
||||
add_library(Nuspell::nuspell ALIAS nuspell)
|
||||
@@ -1,165 +0,0 @@
|
||||
GNU LESSER GENERAL PUBLIC LICENSE
|
||||
Version 3, 29 June 2007
|
||||
|
||||
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
|
||||
This version of the GNU Lesser General Public License incorporates
|
||||
the terms and conditions of version 3 of the GNU General Public
|
||||
License, supplemented by the additional permissions listed below.
|
||||
|
||||
0. Additional Definitions.
|
||||
|
||||
As used herein, "this License" refers to version 3 of the GNU Lesser
|
||||
General Public License, and the "GNU GPL" refers to version 3 of the GNU
|
||||
General Public License.
|
||||
|
||||
"The Library" refers to a covered work governed by this License,
|
||||
other than an Application or a Combined Work as defined below.
|
||||
|
||||
An "Application" is any work that makes use of an interface provided
|
||||
by the Library, but which is not otherwise based on the Library.
|
||||
Defining a subclass of a class defined by the Library is deemed a mode
|
||||
of using an interface provided by the Library.
|
||||
|
||||
A "Combined Work" is a work produced by combining or linking an
|
||||
Application with the Library. The particular version of the Library
|
||||
with which the Combined Work was made is also called the "Linked
|
||||
Version".
|
||||
|
||||
The "Minimal Corresponding Source" for a Combined Work means the
|
||||
Corresponding Source for the Combined Work, excluding any source code
|
||||
for portions of the Combined Work that, considered in isolation, are
|
||||
based on the Application, and not on the Linked Version.
|
||||
|
||||
The "Corresponding Application Code" for a Combined Work means the
|
||||
object code and/or source code for the Application, including any data
|
||||
and utility programs needed for reproducing the Combined Work from the
|
||||
Application, but excluding the System Libraries of the Combined Work.
|
||||
|
||||
1. Exception to Section 3 of the GNU GPL.
|
||||
|
||||
You may convey a covered work under sections 3 and 4 of this License
|
||||
without being bound by section 3 of the GNU GPL.
|
||||
|
||||
2. Conveying Modified Versions.
|
||||
|
||||
If you modify a copy of the Library, and, in your modifications, a
|
||||
facility refers to a function or data to be supplied by an Application
|
||||
that uses the facility (other than as an argument passed when the
|
||||
facility is invoked), then you may convey a copy of the modified
|
||||
version:
|
||||
|
||||
a) under this License, provided that you make a good faith effort to
|
||||
ensure that, in the event an Application does not supply the
|
||||
function or data, the facility still operates, and performs
|
||||
whatever part of its purpose remains meaningful, or
|
||||
|
||||
b) under the GNU GPL, with none of the additional permissions of
|
||||
this License applicable to that copy.
|
||||
|
||||
3. Object Code Incorporating Material from Library Header Files.
|
||||
|
||||
The object code form of an Application may incorporate material from
|
||||
a header file that is part of the Library. You may convey such object
|
||||
code under terms of your choice, provided that, if the incorporated
|
||||
material is not limited to numerical parameters, data structure
|
||||
layouts and accessors, or small macros, inline functions and templates
|
||||
(ten or fewer lines in length), you do both of the following:
|
||||
|
||||
a) Give prominent notice with each copy of the object code that the
|
||||
Library is used in it and that the Library and its use are
|
||||
covered by this License.
|
||||
|
||||
b) Accompany the object code with a copy of the GNU GPL and this license
|
||||
document.
|
||||
|
||||
4. Combined Works.
|
||||
|
||||
You may convey a Combined Work under terms of your choice that,
|
||||
taken together, effectively do not restrict modification of the
|
||||
portions of the Library contained in the Combined Work and reverse
|
||||
engineering for debugging such modifications, if you also do each of
|
||||
the following:
|
||||
|
||||
a) Give prominent notice with each copy of the Combined Work that
|
||||
the Library is used in it and that the Library and its use are
|
||||
covered by this License.
|
||||
|
||||
b) Accompany the Combined Work with a copy of the GNU GPL and this license
|
||||
document.
|
||||
|
||||
c) For a Combined Work that displays copyright notices during
|
||||
execution, include the copyright notice for the Library among
|
||||
these notices, as well as a reference directing the user to the
|
||||
copies of the GNU GPL and this license document.
|
||||
|
||||
d) Do one of the following:
|
||||
|
||||
0) Convey the Minimal Corresponding Source under the terms of this
|
||||
License, and the Corresponding Application Code in a form
|
||||
suitable for, and under terms that permit, the user to
|
||||
recombine or relink the Application with a modified version of
|
||||
the Linked Version to produce a modified Combined Work, in the
|
||||
manner specified by section 6 of the GNU GPL for conveying
|
||||
Corresponding Source.
|
||||
|
||||
1) Use a suitable shared library mechanism for linking with the
|
||||
Library. A suitable mechanism is one that (a) uses at run time
|
||||
a copy of the Library already present on the user's computer
|
||||
system, and (b) will operate properly with a modified version
|
||||
of the Library that is interface-compatible with the Linked
|
||||
Version.
|
||||
|
||||
e) Provide Installation Information, but only if you would otherwise
|
||||
be required to provide such information under section 6 of the
|
||||
GNU GPL, and only to the extent that such information is
|
||||
necessary to install and execute a modified version of the
|
||||
Combined Work produced by recombining or relinking the
|
||||
Application with a modified version of the Linked Version. (If
|
||||
you use option 4d0, the Installation Information must accompany
|
||||
the Minimal Corresponding Source and Corresponding Application
|
||||
Code. If you use option 4d1, you must provide the Installation
|
||||
Information in the manner specified by section 6 of the GNU GPL
|
||||
for conveying Corresponding Source.)
|
||||
|
||||
5. Combined Libraries.
|
||||
|
||||
You may place library facilities that are a work based on the
|
||||
Library side by side in a single library together with other library
|
||||
facilities that are not Applications and are not covered by this
|
||||
License, and convey such a combined library under terms of your
|
||||
choice, if you do both of the following:
|
||||
|
||||
a) Accompany the combined library with a copy of the same work based
|
||||
on the Library, uncombined with any other library facilities,
|
||||
conveyed under the terms of this License.
|
||||
|
||||
b) Give prominent notice with the combined library that part of it
|
||||
is a work based on the Library, and explaining where to find the
|
||||
accompanying uncombined form of the same work.
|
||||
|
||||
6. Revised Versions of the GNU Lesser General Public License.
|
||||
|
||||
The Free Software Foundation may publish revised and/or new versions
|
||||
of the GNU Lesser General Public License from time to time. Such new
|
||||
versions will be similar in spirit to the present version, but may
|
||||
differ in detail to address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the
|
||||
Library as you received it specifies that a certain numbered version
|
||||
of the GNU Lesser General Public License "or any later version"
|
||||
applies to it, you have the option of following the terms and
|
||||
conditions either of that published version or of any later version
|
||||
published by the Free Software Foundation. If the Library as you
|
||||
received it does not specify a version number of the GNU Lesser
|
||||
General Public License, you may choose any version of the GNU Lesser
|
||||
General Public License ever published by the Free Software Foundation.
|
||||
|
||||
If the Library as you received it specifies that a proxy can decide
|
||||
whether future versions of the GNU Lesser General Public License shall
|
||||
apply, that proxy's public statement of acceptance of any version is
|
||||
permanent authorization for you to choose that version for the
|
||||
Library.
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,173 +0,0 @@
|
||||
/* Copyright 2016-2021 Dimitrij Mijoski
|
||||
*
|
||||
* This file is part of Nuspell.
|
||||
*
|
||||
* Nuspell is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Nuspell is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with Nuspell. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef NUSPELL_AFF_DATA_HXX
|
||||
#define NUSPELL_AFF_DATA_HXX
|
||||
|
||||
#include "nuspell_export.h"
|
||||
#include "structures.hxx"
|
||||
|
||||
#include <iosfwd>
|
||||
#include <unicode/locid.h>
|
||||
|
||||
namespace nuspell {
|
||||
inline namespace v5 {
|
||||
|
||||
class Encoding {
|
||||
std::string name;
|
||||
|
||||
NUSPELL_EXPORT auto normalize_name() -> void;
|
||||
|
||||
public:
|
||||
enum Enc_Type { SINGLEBYTE = false, UTF8 = true };
|
||||
|
||||
Encoding() = default;
|
||||
explicit Encoding(const std::string& e) : name(e) { normalize_name(); }
|
||||
explicit Encoding(std::string&& e) : name(move(e)) { normalize_name(); }
|
||||
explicit Encoding(const char* e) : name(e) { normalize_name(); }
|
||||
auto& operator=(const std::string& e)
|
||||
{
|
||||
name = e;
|
||||
normalize_name();
|
||||
return *this;
|
||||
}
|
||||
auto& operator=(std::string&& e)
|
||||
{
|
||||
name = move(e);
|
||||
normalize_name();
|
||||
return *this;
|
||||
}
|
||||
auto& operator=(const char* e)
|
||||
{
|
||||
name = e;
|
||||
normalize_name();
|
||||
return *this;
|
||||
}
|
||||
auto empty() const { return name.empty(); }
|
||||
auto& value() const { return name; }
|
||||
auto is_utf8() const { return name == "UTF-8"; }
|
||||
auto value_or_default() const -> std::string
|
||||
{
|
||||
if (name.empty())
|
||||
return "ISO8859-1";
|
||||
else
|
||||
return name;
|
||||
}
|
||||
operator Enc_Type() const { return is_utf8() ? UTF8 : SINGLEBYTE; }
|
||||
};
|
||||
|
||||
enum class Flag_Type { SINGLE_CHAR, DOUBLE_CHAR, NUMBER, UTF8 };
|
||||
|
||||
/**
|
||||
* @internal
|
||||
* @brief Map between words and word_flags.
|
||||
*
|
||||
* Flags are stored as part of the container. Maybe for the future flags should
|
||||
* be stored elsewhere (flag aliases) and this should store pointers.
|
||||
*
|
||||
* Does not store morphological data as is low priority feature and is out of
|
||||
* scope.
|
||||
*/
|
||||
using Word_List = Hash_Multimap<std::string, Flag_Set>;
|
||||
|
||||
struct Aff_Data {
|
||||
static constexpr auto HIDDEN_HOMONYM_FLAG = char16_t(-1);
|
||||
static constexpr auto MAX_SUGGESTIONS = size_t(16);
|
||||
|
||||
// spell checking options
|
||||
Word_List words;
|
||||
Prefix_Table prefixes;
|
||||
Suffix_Table suffixes;
|
||||
|
||||
bool complex_prefixes;
|
||||
bool fullstrip;
|
||||
bool checksharps;
|
||||
bool forbid_warn;
|
||||
char16_t compound_onlyin_flag;
|
||||
char16_t circumfix_flag;
|
||||
char16_t forbiddenword_flag;
|
||||
char16_t keepcase_flag;
|
||||
char16_t need_affix_flag;
|
||||
char16_t warn_flag;
|
||||
|
||||
// compounding options
|
||||
char16_t compound_flag;
|
||||
char16_t compound_begin_flag;
|
||||
char16_t compound_last_flag;
|
||||
char16_t compound_middle_flag;
|
||||
Compound_Rule_Table compound_rules;
|
||||
|
||||
// spell checking options
|
||||
Break_Table break_table;
|
||||
Substr_Replacer input_substr_replacer;
|
||||
std::string ignored_chars;
|
||||
icu::Locale icu_locale;
|
||||
Substr_Replacer output_substr_replacer;
|
||||
|
||||
// suggestion options
|
||||
Replacement_Table replacements;
|
||||
std::vector<Similarity_Group> similarities;
|
||||
std::string keyboard_closeness;
|
||||
std::string try_chars;
|
||||
// Phonetic_Table phonetic_table;
|
||||
|
||||
char16_t nosuggest_flag;
|
||||
char16_t substandard_flag;
|
||||
unsigned short max_compound_suggestions;
|
||||
unsigned short max_ngram_suggestions;
|
||||
unsigned short max_diff_factor;
|
||||
bool only_max_diff;
|
||||
bool no_split_suggestions;
|
||||
bool suggest_with_dots;
|
||||
|
||||
// compounding options
|
||||
unsigned short compound_min_length;
|
||||
unsigned short compound_max_word_count;
|
||||
char16_t compound_permit_flag;
|
||||
char16_t compound_forbid_flag;
|
||||
char16_t compound_root_flag;
|
||||
char16_t compound_force_uppercase;
|
||||
bool compound_more_suffixes;
|
||||
bool compound_check_duplicate;
|
||||
bool compound_check_rep;
|
||||
bool compound_check_case;
|
||||
bool compound_check_triple;
|
||||
bool compound_simplified_triple;
|
||||
bool compound_syllable_num;
|
||||
unsigned short compound_syllable_max;
|
||||
std::string compound_syllable_vowels;
|
||||
std::vector<Compound_Pattern> compound_patterns;
|
||||
|
||||
// data members used only while parsing
|
||||
Flag_Type flag_type;
|
||||
Encoding encoding;
|
||||
std::vector<Flag_Set> flag_aliases;
|
||||
std::string wordchars; // deprecated?
|
||||
|
||||
auto parse_aff(std::istream& in) -> bool;
|
||||
auto parse_dic(std::istream& in) -> bool;
|
||||
auto parse_aff_dic(std::istream& aff, std::istream& dic)
|
||||
{
|
||||
if (parse_aff(aff))
|
||||
return parse_dic(dic);
|
||||
return false;
|
||||
}
|
||||
};
|
||||
} // namespace v5
|
||||
} // namespace nuspell
|
||||
#endif // NUSPELL_AFF_DATA_HXX
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,352 +0,0 @@
|
||||
/* Copyright 2016-2021 Dimitrij Mijoski
|
||||
*
|
||||
* This file is part of Nuspell.
|
||||
*
|
||||
* Nuspell is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Nuspell is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with Nuspell. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef NUSPELL_CHECKER_HXX
|
||||
#define NUSPELL_CHECKER_HXX
|
||||
|
||||
#include "aff_data.hxx"
|
||||
|
||||
namespace nuspell {
|
||||
inline namespace v5 {
|
||||
|
||||
enum Affixing_Mode {
|
||||
FULL_WORD,
|
||||
AT_COMPOUND_BEGIN,
|
||||
AT_COMPOUND_END,
|
||||
AT_COMPOUND_MIDDLE
|
||||
};
|
||||
|
||||
struct Affixing_Result_Base {
|
||||
Word_List::const_pointer root_word = {};
|
||||
|
||||
operator Word_List::const_pointer() const { return root_word; }
|
||||
auto& operator*() const { return *root_word; }
|
||||
auto operator->() const { return root_word; }
|
||||
};
|
||||
|
||||
template <class T1 = void, class T2 = void>
|
||||
struct Affixing_Result : Affixing_Result_Base {
|
||||
const T1* a = {};
|
||||
const T2* b = {};
|
||||
|
||||
Affixing_Result() = default;
|
||||
Affixing_Result(Word_List::const_reference r, const T1& a, const T2& b)
|
||||
: Affixing_Result_Base{&r}, a{&a}, b{&b}
|
||||
{
|
||||
}
|
||||
};
|
||||
template <class T1>
|
||||
struct Affixing_Result<T1, void> : Affixing_Result_Base {
|
||||
const T1* a = {};
|
||||
|
||||
Affixing_Result() = default;
|
||||
Affixing_Result(Word_List::const_reference r, const T1& a)
|
||||
: Affixing_Result_Base{&r}, a{&a}
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct Affixing_Result<void, void> : Affixing_Result_Base {
|
||||
Affixing_Result() = default;
|
||||
Affixing_Result(Word_List::const_reference r) : Affixing_Result_Base{&r}
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
struct Compounding_Result {
|
||||
Word_List::const_pointer word_entry = {};
|
||||
unsigned char num_words_modifier = {};
|
||||
signed char num_syllable_modifier = {};
|
||||
bool affixed_and_modified = {}; /**< non-zero affix */
|
||||
operator Word_List::const_pointer() const { return word_entry; }
|
||||
auto& operator*() const { return *word_entry; }
|
||||
auto operator->() const { return word_entry; }
|
||||
};
|
||||
|
||||
struct Checker : public Aff_Data {
|
||||
enum Forceucase : bool {
|
||||
FORBID_BAD_FORCEUCASE = false,
|
||||
ALLOW_BAD_FORCEUCASE = true
|
||||
};
|
||||
|
||||
enum Hidden_Homonym : bool {
|
||||
ACCEPT_HIDDEN_HOMONYM = false,
|
||||
SKIP_HIDDEN_HOMONYM = true
|
||||
};
|
||||
Checker()
|
||||
: Aff_Data() // we explicity do value init so content is zeroed
|
||||
{
|
||||
}
|
||||
auto spell_priv(std::string& s) const -> bool;
|
||||
auto spell_break(std::string& s, size_t depth = 0) const -> bool;
|
||||
auto spell_casing(std::string& s) const -> const Flag_Set*;
|
||||
auto spell_casing_upper(std::string& s) const -> const Flag_Set*;
|
||||
auto spell_casing_title(std::string& s) const -> const Flag_Set*;
|
||||
auto spell_sharps(std::string& base, size_t n_pos = 0, size_t n = 0,
|
||||
size_t rep = 0) const -> const Flag_Set*;
|
||||
|
||||
auto check_word(std::string& s, Forceucase allow_bad_forceucase = {},
|
||||
Hidden_Homonym skip_hidden_homonym = {}) const
|
||||
-> const Flag_Set*;
|
||||
auto check_simple_word(std::string& word,
|
||||
Hidden_Homonym skip_hidden_homonym = {}) const
|
||||
-> const Flag_Set*;
|
||||
|
||||
template <Affixing_Mode m>
|
||||
auto affix_NOT_valid(const Prefix& a) const;
|
||||
template <Affixing_Mode m>
|
||||
auto affix_NOT_valid(const Suffix& a) const;
|
||||
template <Affixing_Mode m, class AffixT>
|
||||
auto outer_affix_NOT_valid(const AffixT& a) const;
|
||||
template <class AffixT>
|
||||
auto is_circumfix(const AffixT& a) const;
|
||||
template <Affixing_Mode m>
|
||||
auto is_valid_inside_compound(const Flag_Set& flags) const;
|
||||
|
||||
template <Affixing_Mode m = FULL_WORD>
|
||||
auto strip_prefix_only(std::string& s,
|
||||
Hidden_Homonym skip_hidden_homonym = {}) const
|
||||
-> Affixing_Result<Prefix>;
|
||||
|
||||
template <Affixing_Mode m = FULL_WORD>
|
||||
auto strip_suffix_only(std::string& s,
|
||||
Hidden_Homonym skip_hidden_homonym = {}) const
|
||||
-> Affixing_Result<Suffix>;
|
||||
|
||||
template <Affixing_Mode m = FULL_WORD>
|
||||
auto
|
||||
strip_prefix_then_suffix(std::string& s,
|
||||
Hidden_Homonym skip_hidden_homonym = {}) const
|
||||
-> Affixing_Result<Suffix, Prefix>;
|
||||
|
||||
template <Affixing_Mode m>
|
||||
auto strip_pfx_then_sfx_2(const Prefix& pe, std::string& s,
|
||||
Hidden_Homonym skip_hidden_homonym) const
|
||||
-> Affixing_Result<Suffix, Prefix>;
|
||||
|
||||
template <Affixing_Mode m = FULL_WORD>
|
||||
auto
|
||||
strip_suffix_then_prefix(std::string& s,
|
||||
Hidden_Homonym skip_hidden_homonym = {}) const
|
||||
-> Affixing_Result<Prefix, Suffix>;
|
||||
|
||||
template <Affixing_Mode m>
|
||||
auto strip_sfx_then_pfx_2(const Suffix& se, std::string& s,
|
||||
Hidden_Homonym skip_hidden_homonym) const
|
||||
-> Affixing_Result<Prefix, Suffix>;
|
||||
|
||||
template <Affixing_Mode m = FULL_WORD>
|
||||
auto strip_prefix_then_suffix_commutative(
|
||||
std::string& word, Hidden_Homonym skip_hidden_homonym = {}) const
|
||||
-> Affixing_Result<Suffix, Prefix>;
|
||||
|
||||
template <Affixing_Mode m = FULL_WORD>
|
||||
auto strip_pfx_then_sfx_comm_2(const Prefix& pe, std::string& word,
|
||||
Hidden_Homonym skip_hidden_homonym) const
|
||||
-> Affixing_Result<Suffix, Prefix>;
|
||||
|
||||
template <Affixing_Mode m = FULL_WORD>
|
||||
auto
|
||||
strip_suffix_then_suffix(std::string& s,
|
||||
Hidden_Homonym skip_hidden_homonym = {}) const
|
||||
-> Affixing_Result<Suffix, Suffix>;
|
||||
|
||||
template <Affixing_Mode m>
|
||||
auto strip_sfx_then_sfx_2(const Suffix& se1, std::string& s,
|
||||
Hidden_Homonym skip_hidden_homonym) const
|
||||
-> Affixing_Result<Suffix, Suffix>;
|
||||
|
||||
template <Affixing_Mode m = FULL_WORD>
|
||||
auto
|
||||
strip_prefix_then_prefix(std::string& s,
|
||||
Hidden_Homonym skip_hidden_homonym = {}) const
|
||||
-> Affixing_Result<Prefix, Prefix>;
|
||||
|
||||
template <Affixing_Mode m>
|
||||
auto strip_pfx_then_pfx_2(const Prefix& pe1, std::string& s,
|
||||
Hidden_Homonym skip_hidden_homonym) const
|
||||
-> Affixing_Result<Prefix, Prefix>;
|
||||
|
||||
template <Affixing_Mode m = FULL_WORD>
|
||||
auto strip_prefix_then_2_suffixes(
|
||||
std::string& s, Hidden_Homonym skip_hidden_homonym = {}) const
|
||||
-> Affixing_Result<>;
|
||||
|
||||
template <Affixing_Mode m>
|
||||
auto strip_pfx_2_sfx_3(const Prefix& pe1, const Suffix& se1,
|
||||
std::string& s,
|
||||
Hidden_Homonym skip_hidden_homonym) const
|
||||
-> Affixing_Result<>;
|
||||
|
||||
template <Affixing_Mode m = FULL_WORD>
|
||||
auto strip_suffix_prefix_suffix(
|
||||
std::string& s, Hidden_Homonym skip_hidden_homonym = {}) const
|
||||
-> Affixing_Result<>;
|
||||
|
||||
template <Affixing_Mode m>
|
||||
auto strip_s_p_s_3(const Suffix& se1, const Prefix& pe1,
|
||||
std::string& word,
|
||||
Hidden_Homonym skip_hidden_homonym) const
|
||||
-> Affixing_Result<>;
|
||||
|
||||
template <Affixing_Mode m = FULL_WORD>
|
||||
auto strip_2_suffixes_then_prefix(
|
||||
std::string& s, Hidden_Homonym skip_hidden_homonym = {}) const
|
||||
-> Affixing_Result<>;
|
||||
|
||||
template <Affixing_Mode m>
|
||||
auto strip_2_sfx_pfx_3(const Suffix& se1, const Suffix& se2,
|
||||
std::string& word,
|
||||
Hidden_Homonym skip_hidden_homonym) const
|
||||
-> Affixing_Result<>;
|
||||
|
||||
template <Affixing_Mode m = FULL_WORD>
|
||||
auto strip_suffix_then_2_prefixes(
|
||||
std::string& s, Hidden_Homonym skip_hidden_homonym = {}) const
|
||||
-> Affixing_Result<>;
|
||||
|
||||
template <Affixing_Mode m>
|
||||
auto strip_sfx_2_pfx_3(const Suffix& se1, const Prefix& pe1,
|
||||
std::string& s,
|
||||
Hidden_Homonym skip_hidden_homonym) const
|
||||
-> Affixing_Result<>;
|
||||
|
||||
template <Affixing_Mode m = FULL_WORD>
|
||||
auto strip_prefix_suffix_prefix(
|
||||
std::string& word, Hidden_Homonym skip_hidden_homonym = {}) const
|
||||
-> Affixing_Result<>;
|
||||
|
||||
template <Affixing_Mode m>
|
||||
auto strip_p_s_p_3(const Prefix& pe1, const Suffix& se1,
|
||||
std::string& word,
|
||||
Hidden_Homonym skip_hidden_homonym) const
|
||||
-> Affixing_Result<>;
|
||||
|
||||
template <Affixing_Mode m = FULL_WORD>
|
||||
auto strip_2_prefixes_then_suffix(
|
||||
std::string& word, Hidden_Homonym skip_hidden_homonym = {}) const
|
||||
-> Affixing_Result<>;
|
||||
|
||||
template <Affixing_Mode m>
|
||||
auto strip_2_pfx_sfx_3(const Prefix& pe1, const Prefix& pe2,
|
||||
std::string& word,
|
||||
Hidden_Homonym skip_hidden_homonym) const
|
||||
-> Affixing_Result<>;
|
||||
|
||||
auto check_compound(std::string& word,
|
||||
Forceucase allow_bad_forceucase) const
|
||||
-> Compounding_Result;
|
||||
|
||||
template <Affixing_Mode m = AT_COMPOUND_BEGIN>
|
||||
auto check_compound(std::string& word, size_t start_pos,
|
||||
size_t num_part, std::string& part,
|
||||
Forceucase allow_bad_forceucase) const
|
||||
-> Compounding_Result;
|
||||
|
||||
template <Affixing_Mode m = AT_COMPOUND_BEGIN>
|
||||
auto check_compound_classic(std::string& word, size_t start_pos,
|
||||
size_t i, size_t num_part,
|
||||
std::string& part,
|
||||
Forceucase allow_bad_forceucase) const
|
||||
-> Compounding_Result;
|
||||
|
||||
template <Affixing_Mode m = AT_COMPOUND_BEGIN>
|
||||
auto check_compound_with_pattern_replacements(
|
||||
std::string& word, size_t start_pos, size_t i, size_t num_part,
|
||||
std::string& part, Forceucase allow_bad_forceucase) const
|
||||
-> Compounding_Result;
|
||||
|
||||
template <Affixing_Mode m>
|
||||
auto check_word_in_compound(std::string& s) const -> Compounding_Result;
|
||||
|
||||
auto calc_num_words_modifier(const Prefix& pfx) const -> unsigned char;
|
||||
|
||||
template <Affixing_Mode m>
|
||||
auto calc_syllable_modifier(Word_List::const_reference we) const
|
||||
-> signed char;
|
||||
|
||||
template <Affixing_Mode m>
|
||||
auto calc_syllable_modifier(Word_List::const_reference we,
|
||||
const Suffix& sfx) const -> signed char;
|
||||
|
||||
auto count_syllables(std::string_view word) const -> size_t;
|
||||
|
||||
auto check_compound_with_rules(std::string& word,
|
||||
std::vector<const Flag_Set*>& words_data,
|
||||
size_t start_pos, std::string& part,
|
||||
Forceucase allow_bad_forceucase) const
|
||||
|
||||
-> Compounding_Result;
|
||||
auto is_rep_similar(std::string& word) const -> bool;
|
||||
};
|
||||
|
||||
template <Affixing_Mode m>
|
||||
auto Checker::affix_NOT_valid(const Prefix& e) const
|
||||
{
|
||||
if (m == FULL_WORD && e.cont_flags.contains(compound_onlyin_flag))
|
||||
return true;
|
||||
if (m == AT_COMPOUND_END &&
|
||||
!e.cont_flags.contains(compound_permit_flag))
|
||||
return true;
|
||||
if (m != FULL_WORD && e.cont_flags.contains(compound_forbid_flag))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
template <Affixing_Mode m>
|
||||
auto Checker::affix_NOT_valid(const Suffix& e) const
|
||||
{
|
||||
if (m == FULL_WORD && e.cont_flags.contains(compound_onlyin_flag))
|
||||
return true;
|
||||
if (m == AT_COMPOUND_BEGIN &&
|
||||
!e.cont_flags.contains(compound_permit_flag))
|
||||
return true;
|
||||
if (m != FULL_WORD && e.cont_flags.contains(compound_forbid_flag))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
template <Affixing_Mode m, class AffixT>
|
||||
auto Checker::outer_affix_NOT_valid(const AffixT& e) const
|
||||
{
|
||||
if (affix_NOT_valid<m>(e))
|
||||
return true;
|
||||
if (e.cont_flags.contains(need_affix_flag))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
template <class AffixT>
|
||||
auto Checker::is_circumfix(const AffixT& a) const
|
||||
{
|
||||
return a.cont_flags.contains(circumfix_flag);
|
||||
}
|
||||
|
||||
template <class AffixInner, class AffixOuter>
|
||||
auto cross_valid_inner_outer(const AffixInner& inner, const AffixOuter& outer)
|
||||
{
|
||||
return inner.cont_flags.contains(outer.flag);
|
||||
}
|
||||
|
||||
template <class Affix>
|
||||
auto cross_valid_inner_outer(const Flag_Set& word_flags, const Affix& afx)
|
||||
{
|
||||
return word_flags.contains(afx.flag);
|
||||
}
|
||||
|
||||
} // namespace v5
|
||||
} // namespace nuspell
|
||||
#endif // NUSPELL_CHECKER_HXX
|
||||
@@ -1 +0,0 @@
|
||||
clang-format -style=file -i *.[ch]xx
|
||||
@@ -1,115 +0,0 @@
|
||||
/* Copyright 2016-2021 Dimitrij Mijoski
|
||||
*
|
||||
* This file is part of Nuspell.
|
||||
*
|
||||
* Nuspell is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Nuspell is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with Nuspell. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "dictionary.hxx"
|
||||
#include "utils.hxx"
|
||||
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
#include <stdexcept>
|
||||
|
||||
using namespace std;
|
||||
|
||||
namespace nuspell {
|
||||
inline namespace v5 {
|
||||
|
||||
Dictionary::Dictionary(std::istream& aff, std::istream& dic)
|
||||
{
|
||||
if (!parse_aff_dic(aff, dic))
|
||||
throw Dictionary_Loading_Error("error parsing");
|
||||
}
|
||||
|
||||
Dictionary::Dictionary() = default;
|
||||
|
||||
/**
|
||||
* @brief Create a dictionary from opened files as iostreams
|
||||
*
|
||||
* Prefer using load_from_path(). Use this if you have a specific use case,
|
||||
* like when .aff and .dic are in-memory buffers istringstream.
|
||||
*
|
||||
* @param aff The iostream of the .aff file
|
||||
* @param dic The iostream of the .dic file
|
||||
* @return Dictionary object
|
||||
* @throws Dictionary_Loading_Error on error
|
||||
*/
|
||||
auto Dictionary::load_from_aff_dic(std::istream& aff, std::istream& dic)
|
||||
-> Dictionary
|
||||
{
|
||||
return Dictionary(aff, dic);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Create a dictionary from files
|
||||
* @param file_path_without_extension path *without* extensions (without .dic or
|
||||
* .aff)
|
||||
* @return Dictionary object
|
||||
* @throws Dictionary_Loading_Error on error
|
||||
*/
|
||||
auto Dictionary::load_from_path(const std::string& file_path_without_extension)
|
||||
-> Dictionary
|
||||
{
|
||||
auto path = file_path_without_extension;
|
||||
path += ".aff";
|
||||
std::ifstream aff_file(path);
|
||||
if (aff_file.fail()) {
|
||||
auto err = "Aff file " + path + " not found";
|
||||
throw Dictionary_Loading_Error(err);
|
||||
}
|
||||
path.replace(path.size() - 3, 3, "dic");
|
||||
std::ifstream dic_file(path);
|
||||
if (dic_file.fail()) {
|
||||
auto err = "Dic file " + path + " not found";
|
||||
throw Dictionary_Loading_Error(err);
|
||||
}
|
||||
return load_from_aff_dic(aff_file, dic_file);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Checks if a given word is correct
|
||||
* @param word any word
|
||||
* @return true if correct, false otherwise
|
||||
*/
|
||||
auto Dictionary::spell(std::string_view word) const -> bool
|
||||
{
|
||||
auto ok_enc = validate_utf8(word);
|
||||
if (unlikely(word.size() > 360))
|
||||
return false;
|
||||
if (unlikely(!ok_enc))
|
||||
return false;
|
||||
auto word_buf = string(word);
|
||||
return spell_priv(word_buf);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Suggests correct words for a given incorrect word
|
||||
* @param[in] word incorrect word
|
||||
* @param[out] out this object will be populated with the suggestions
|
||||
*/
|
||||
auto Dictionary::suggest(std::string_view word,
|
||||
std::vector<std::string>& out) const -> void
|
||||
{
|
||||
out.clear();
|
||||
auto ok_enc = validate_utf8(word);
|
||||
if (unlikely(word.size() > 360))
|
||||
return;
|
||||
if (unlikely(!ok_enc))
|
||||
return;
|
||||
suggest_priv(word, out);
|
||||
}
|
||||
} // namespace v5
|
||||
} // namespace nuspell
|
||||
@@ -1,59 +0,0 @@
|
||||
/* Copyright 2016-2021 Dimitrij Mijoski
|
||||
*
|
||||
* This file is part of Nuspell.
|
||||
*
|
||||
* Nuspell is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Nuspell is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with Nuspell. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file
|
||||
* @brief Dictionary spelling.
|
||||
*/
|
||||
|
||||
#ifndef NUSPELL_DICTIONARY_HXX
|
||||
#define NUSPELL_DICTIONARY_HXX
|
||||
|
||||
#include "suggester.hxx"
|
||||
|
||||
namespace nuspell {
|
||||
inline namespace v5 {
|
||||
|
||||
/**
|
||||
* @brief The only important public exception
|
||||
*/
|
||||
class Dictionary_Loading_Error : public std::runtime_error {
|
||||
public:
|
||||
using std::runtime_error::runtime_error;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief The only important public class
|
||||
*/
|
||||
class NUSPELL_EXPORT Dictionary : private Suggester {
|
||||
Dictionary(std::istream& aff, std::istream& dic);
|
||||
|
||||
public:
|
||||
Dictionary();
|
||||
auto static load_from_aff_dic(std::istream& aff, std::istream& dic)
|
||||
-> Dictionary;
|
||||
auto static load_from_path(
|
||||
const std::string& file_path_without_extension) -> Dictionary;
|
||||
auto spell(std::string_view word) const -> bool;
|
||||
auto suggest(std::string_view word, std::vector<std::string>& out) const
|
||||
-> void;
|
||||
};
|
||||
|
||||
} // namespace v5
|
||||
} // namespace nuspell
|
||||
#endif // NUSPELL_DICTIONARY_HXX
|
||||
@@ -1,18 +0,0 @@
|
||||
#ifndef NUSPELL_EXPORT_H
|
||||
#define NUSPELL_EXPORT_H
|
||||
|
||||
#ifdef NUSPELL_STATIC_DEFINE
|
||||
# define NUSPELL_EXPORT
|
||||
#elif defined(_WIN32) || defined(__CYGWIN__)
|
||||
# ifdef nuspell_EXPORTS // Define this only when building Nuspell as DLL on Windows, not when using the DLL.
|
||||
# define NUSPELL_EXPORT __declspec(dllexport)
|
||||
# else
|
||||
# define NUSPELL_EXPORT __declspec(dllimport)
|
||||
# endif
|
||||
#elif __GNUC__ >= 4
|
||||
# define NUSPELL_EXPORT __attribute__((visibility("default")))
|
||||
#else
|
||||
# define NUSPELL_EXPORT
|
||||
#endif
|
||||
|
||||
#endif /* NUSPELL_EXPORT_H */
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1,97 +0,0 @@
|
||||
/* Copyright 2016-2021 Dimitrij Mijoski
|
||||
*
|
||||
* This file is part of Nuspell.
|
||||
*
|
||||
* Nuspell is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Nuspell is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with Nuspell. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef NUSPELL_SUGGESTER_HXX
|
||||
#define NUSPELL_SUGGESTER_HXX
|
||||
|
||||
#include "checker.hxx"
|
||||
|
||||
namespace nuspell {
|
||||
inline namespace v5 {
|
||||
|
||||
struct NUSPELL_EXPORT Suggester : public Checker {
|
||||
|
||||
enum High_Quality_Sugs : bool {
|
||||
ALL_LOW_QUALITY_SUGS = false,
|
||||
HAS_HIGH_QUALITY_SUGS = true
|
||||
};
|
||||
|
||||
auto suggest_priv(std::string_view input_word, List_Strings& out) const
|
||||
-> void;
|
||||
|
||||
auto suggest_low(std::string& word, List_Strings& out) const
|
||||
-> High_Quality_Sugs;
|
||||
|
||||
auto add_sug_if_correct(std::string& word, List_Strings& out) const
|
||||
-> bool;
|
||||
|
||||
auto uppercase_suggest(const std::string& word, List_Strings& out) const
|
||||
-> void;
|
||||
|
||||
auto rep_suggest(std::string& word, List_Strings& out) const -> void;
|
||||
|
||||
auto try_rep_suggestion(std::string& word, List_Strings& out) const
|
||||
-> void;
|
||||
|
||||
auto max_attempts_for_long_alogs(std::string_view word) const -> size_t;
|
||||
|
||||
auto map_suggest(std::string& word, List_Strings& out) const -> void;
|
||||
|
||||
auto map_suggest(std::string& word, List_Strings& out, size_t i,
|
||||
size_t& remaining_attempts) const -> void;
|
||||
|
||||
auto adjacent_swap_suggest(std::string& word, List_Strings& out) const
|
||||
-> void;
|
||||
|
||||
auto distant_swap_suggest(std::string& word, List_Strings& out) const
|
||||
-> void;
|
||||
|
||||
auto keyboard_suggest(std::string& word, List_Strings& out) const
|
||||
-> void;
|
||||
|
||||
auto extra_char_suggest(std::string& word, List_Strings& out) const
|
||||
-> void;
|
||||
|
||||
auto forgotten_char_suggest(std::string& word, List_Strings& out) const
|
||||
-> void;
|
||||
|
||||
auto move_char_suggest(std::string& word, List_Strings& out) const
|
||||
-> void;
|
||||
|
||||
auto bad_char_suggest(std::string& word, List_Strings& out) const
|
||||
-> void;
|
||||
|
||||
auto doubled_two_chars_suggest(std::string& word,
|
||||
List_Strings& out) const -> void;
|
||||
|
||||
auto two_words_suggest(const std::string& word, List_Strings& out) const
|
||||
-> void;
|
||||
|
||||
auto ngram_suggest(const std::string& word_u8, List_Strings& out) const
|
||||
-> void;
|
||||
|
||||
auto expand_root_word_for_ngram(Word_List::const_reference root,
|
||||
std::string_view wrong,
|
||||
List_Strings& expanded_list,
|
||||
std::vector<bool>& cross_affix) const
|
||||
-> void;
|
||||
};
|
||||
|
||||
} // namespace v5
|
||||
} // namespace nuspell
|
||||
#endif // NUSPELL_SUGGESTER_HXX
|
||||
@@ -1,383 +0,0 @@
|
||||
/* Copyright 2021 Dimitrij Mijoski
|
||||
*
|
||||
* This file is part of Nuspell.
|
||||
*
|
||||
* Nuspell is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Nuspell is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with Nuspell. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#ifndef NUSPELL_UNICODE_HXX
|
||||
#define NUSPELL_UNICODE_HXX
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
#include <unicode/utf16.h>
|
||||
#include <unicode/utf8.h>
|
||||
|
||||
namespace nuspell {
|
||||
inline namespace v5 {
|
||||
|
||||
// UTF-8, work on malformed
|
||||
|
||||
inline constexpr auto u8_max_cp_length = U8_MAX_LENGTH;
|
||||
|
||||
auto inline u8_is_cp_error(int32_t cp) -> bool { return cp < 0; }
|
||||
|
||||
template <class Range>
|
||||
auto u8_advance_cp(const Range& str, size_t& i, int32_t& cp) -> void
|
||||
{
|
||||
using std::size, std::data;
|
||||
#if U_ICU_VERSION_MAJOR_NUM <= 60
|
||||
auto s_ptr = data(str);
|
||||
int32_t idx = i;
|
||||
int32_t len = size(str);
|
||||
U8_NEXT(s_ptr, idx, len, cp);
|
||||
i = idx;
|
||||
#else
|
||||
auto len = size(str);
|
||||
U8_NEXT(str, i, len, cp);
|
||||
#endif
|
||||
}
|
||||
|
||||
template <class Range>
|
||||
auto u8_advance_index(const Range& str, size_t& i) -> void
|
||||
{
|
||||
using std::size;
|
||||
auto len = size(str);
|
||||
U8_FWD_1(str, i, len);
|
||||
}
|
||||
|
||||
template <class Range>
|
||||
auto u8_reverse_cp(const Range& str, size_t& i, int32_t& cp) -> void
|
||||
{
|
||||
using std::size, std::data;
|
||||
auto ptr = data(str);
|
||||
int32_t idx = i;
|
||||
U8_PREV(ptr, 0, idx, cp);
|
||||
i = idx;
|
||||
}
|
||||
|
||||
template <class Range>
|
||||
auto u8_reverse_index(const Range& str, size_t& i) -> void
|
||||
{
|
||||
using std::size, std::data;
|
||||
auto ptr = data(str);
|
||||
int32_t idx = i;
|
||||
U8_BACK_1(ptr, 0, idx);
|
||||
i = idx;
|
||||
}
|
||||
|
||||
template <class Range>
|
||||
auto u8_write_cp_and_advance(Range& buf, size_t& i, int32_t cp, bool& error)
|
||||
-> void
|
||||
{
|
||||
using std::size, std::data;
|
||||
#if U_ICU_VERSION_MAJOR_NUM <= 60
|
||||
auto ptr = data(buf);
|
||||
int32_t idx = i;
|
||||
int32_t len = size(buf);
|
||||
U8_APPEND(buf, idx, len, cp, error);
|
||||
i = idx;
|
||||
#else
|
||||
auto len = size(buf);
|
||||
U8_APPEND(buf, i, len, cp, error);
|
||||
#endif
|
||||
}
|
||||
|
||||
// UTF-8, valid
|
||||
|
||||
template <class Range>
|
||||
auto valid_u8_advance_cp(const Range& str, size_t& i, char32_t& cp) -> void
|
||||
{
|
||||
U8_NEXT_UNSAFE(str, i, cp);
|
||||
}
|
||||
|
||||
template <class Range>
|
||||
auto valid_u8_advance_index(const Range& str, size_t& i) -> void
|
||||
{
|
||||
U8_FWD_1_UNSAFE(str, i);
|
||||
}
|
||||
|
||||
template <class Range>
|
||||
auto valid_u8_reverse_cp(const Range& str, size_t& i, char32_t& cp) -> void
|
||||
{
|
||||
U8_PREV_UNSAFE(str, i, cp);
|
||||
}
|
||||
|
||||
template <class Range>
|
||||
auto valid_u8_reverse_index(const Range& str, size_t& i) -> void
|
||||
{
|
||||
U8_BACK_1_UNSAFE(str, i);
|
||||
}
|
||||
|
||||
template <class Range>
|
||||
auto valid_u8_write_cp_and_advance(Range& buf, size_t& i, char32_t cp) -> void
|
||||
{
|
||||
U8_APPEND_UNSAFE(buf, i, cp);
|
||||
}
|
||||
|
||||
// UTF-16, work on malformed
|
||||
|
||||
inline constexpr auto u16_max_cp_length = U16_MAX_LENGTH;
|
||||
|
||||
auto inline u16_is_cp_error(int32_t cp) -> bool { return U_IS_SURROGATE(cp); }
|
||||
|
||||
template <class Range>
|
||||
auto u16_advance_cp(const Range& str, size_t& i, int32_t& cp) -> void
|
||||
{
|
||||
using std::size;
|
||||
auto len = size(str);
|
||||
U16_NEXT(str, i, len, cp);
|
||||
}
|
||||
|
||||
template <class Range>
|
||||
auto u16_advance_index(const Range& str, size_t& i) -> void
|
||||
{
|
||||
using std::size;
|
||||
auto len = size(str);
|
||||
U16_FWD_1(str, i, len);
|
||||
}
|
||||
|
||||
template <class Range>
|
||||
auto u16_reverse_cp(const Range& str, size_t& i, int32_t& cp) -> void
|
||||
{
|
||||
U16_PREV(str, 0, i, cp);
|
||||
}
|
||||
|
||||
template <class Range>
|
||||
auto u16_reverse_index(const Range& str, size_t& i) -> void
|
||||
{
|
||||
U16_BACK_1(str, 0, i);
|
||||
}
|
||||
|
||||
template <class Range>
|
||||
auto u16_write_cp_and_advance(Range& buf, size_t& i, int32_t cp, bool& error)
|
||||
-> void
|
||||
{
|
||||
using std::size;
|
||||
auto len = size(buf);
|
||||
U16_APPEND(buf, i, len, cp, error);
|
||||
}
|
||||
|
||||
// UTF-16, valid
|
||||
|
||||
template <class Range>
|
||||
auto valid_u16_advance_cp(const Range& str, size_t& i, char32_t& cp) -> void
|
||||
{
|
||||
U16_NEXT_UNSAFE(str, i, cp);
|
||||
}
|
||||
|
||||
template <class Range>
|
||||
auto valid_u16_advance_index(const Range& str, size_t& i) -> void
|
||||
{
|
||||
U16_FWD_1_UNSAFE(str, i);
|
||||
}
|
||||
|
||||
template <class Range>
|
||||
auto valid_u16_reverse_cp(const Range& str, size_t& i, char32_t& cp) -> void
|
||||
{
|
||||
U16_PREV_UNSAFE(str, i, cp);
|
||||
}
|
||||
|
||||
template <class Range>
|
||||
auto valid_u16_reverse_index(const Range& str, size_t& i) -> void
|
||||
{
|
||||
U16_BACK_1_UNSAFE(str, i);
|
||||
}
|
||||
|
||||
template <class Range>
|
||||
auto valid_u16_write_cp_and_advance(Range& buf, size_t& i, char32_t cp) -> void
|
||||
{
|
||||
U16_APPEND_UNSAFE(buf, i, cp);
|
||||
}
|
||||
|
||||
// higer level funcs
|
||||
|
||||
struct U8_CP_Pos {
|
||||
size_t begin_i = 0;
|
||||
size_t end_i = begin_i;
|
||||
};
|
||||
|
||||
class U8_Encoded_CP {
|
||||
char d[u8_max_cp_length];
|
||||
int sz;
|
||||
|
||||
public:
|
||||
explicit U8_Encoded_CP(std::string_view str, U8_CP_Pos pos)
|
||||
: sz(pos.end_i - pos.begin_i)
|
||||
{
|
||||
auto i = sz;
|
||||
auto j = pos.end_i;
|
||||
auto max_len = 4;
|
||||
do {
|
||||
d[--i] = str[--j];
|
||||
} while (i && --max_len);
|
||||
}
|
||||
U8_Encoded_CP(char32_t cp)
|
||||
{
|
||||
size_t z = 0;
|
||||
valid_u8_write_cp_and_advance(d, z, cp);
|
||||
sz = z;
|
||||
}
|
||||
auto size() const noexcept -> size_t { return sz; }
|
||||
auto data() const noexcept -> const char* { return d; }
|
||||
operator std::string_view() const noexcept
|
||||
{
|
||||
return std::string_view(data(), size());
|
||||
}
|
||||
auto copy_to(std::string& str, size_t j) const
|
||||
{
|
||||
auto i = sz;
|
||||
j += sz;
|
||||
auto max_len = 4;
|
||||
do {
|
||||
str[--j] = d[--i];
|
||||
} while (i && --max_len);
|
||||
}
|
||||
};
|
||||
|
||||
auto inline u8_swap_adjacent_cp(std::string& str, size_t i1, size_t i2,
|
||||
size_t i3) -> size_t
|
||||
{
|
||||
auto cp1 = U8_Encoded_CP(str, {i1, i2});
|
||||
auto cp2 = U8_Encoded_CP(str, {i2, i3});
|
||||
auto new_i2 = i1 + std::size(cp2);
|
||||
cp1.copy_to(str, new_i2);
|
||||
cp2.copy_to(str, i1);
|
||||
return new_i2;
|
||||
}
|
||||
|
||||
auto inline u8_swap_cp(std::string& str, U8_CP_Pos pos1, U8_CP_Pos pos2)
|
||||
-> std::pair<size_t, size_t>
|
||||
{
|
||||
using std::size;
|
||||
auto cp1 = U8_Encoded_CP(str, pos1);
|
||||
auto cp2 = U8_Encoded_CP(str, pos2);
|
||||
auto new_p1_end_i = pos1.begin_i + size(cp2);
|
||||
auto new_p2_begin_i = pos2.end_i - size(cp1);
|
||||
std::char_traits<char>::move(&str[new_p1_end_i], &str[pos1.end_i],
|
||||
pos2.begin_i - pos1.end_i);
|
||||
cp2.copy_to(str, pos1.begin_i);
|
||||
cp1.copy_to(str, new_p2_begin_i);
|
||||
return {new_p1_end_i, new_p2_begin_i};
|
||||
}
|
||||
|
||||
// bellow go func without out-parametars
|
||||
|
||||
// UTF-8, can be malformed, no out-parametars
|
||||
|
||||
struct Idx_And_Next_CP {
|
||||
size_t end_i;
|
||||
int32_t cp;
|
||||
};
|
||||
|
||||
struct Idx_And_Prev_CP {
|
||||
size_t begin_i;
|
||||
int32_t cp;
|
||||
};
|
||||
|
||||
struct Write_CP_Idx_and_Error {
|
||||
size_t end_i;
|
||||
bool error;
|
||||
};
|
||||
|
||||
template <class Range>
|
||||
[[nodiscard]] auto u8_next_cp(const Range& str, size_t i) -> Idx_And_Next_CP
|
||||
{
|
||||
int32_t cp;
|
||||
u8_advance_cp(str, i, cp);
|
||||
return {i, cp};
|
||||
}
|
||||
|
||||
template <class Range>
|
||||
[[nodiscard]] auto u8_next_index(const Range& str, size_t i) -> size_t
|
||||
{
|
||||
u8_advance_index(str, i);
|
||||
return i;
|
||||
}
|
||||
|
||||
template <class Range>
|
||||
[[nodiscard]] auto u8_prev_cp(const Range& str, size_t i) -> Idx_And_Prev_CP
|
||||
{
|
||||
int32_t cp;
|
||||
u8_reverse_cp(str, i, cp);
|
||||
return {i, cp};
|
||||
}
|
||||
|
||||
template <class Range>
|
||||
[[nodiscard]] auto u8_prev_index(const Range& str, size_t i) -> size_t
|
||||
{
|
||||
u8_reverse_index(str, i);
|
||||
return i;
|
||||
}
|
||||
|
||||
template <class Range>
|
||||
[[nodiscard]] auto u8_write_cp(Range& buf, size_t i, int32_t cp)
|
||||
-> Write_CP_Idx_and_Error
|
||||
{
|
||||
bool err;
|
||||
u8_write_cp_and_advance(buf, i, cp, err);
|
||||
return {i, err};
|
||||
}
|
||||
|
||||
// UTF-8, valid, no out-parametars
|
||||
|
||||
struct Idx_And_Next_CP_Valid {
|
||||
size_t end_i;
|
||||
char32_t cp;
|
||||
};
|
||||
|
||||
struct Idx_And_Prev_CP_Valid {
|
||||
size_t begin_i;
|
||||
char32_t cp;
|
||||
};
|
||||
|
||||
template <class Range>
|
||||
[[nodiscard]] auto valid_u8_next_cp(const Range& str, size_t i)
|
||||
-> Idx_And_Next_CP_Valid
|
||||
{
|
||||
char32_t cp;
|
||||
valid_u8_advance_cp(str, i, cp);
|
||||
return {i, cp};
|
||||
}
|
||||
|
||||
template <class Range>
|
||||
[[nodiscard]] auto valid_u8_next_index(const Range& str, size_t i) -> size_t
|
||||
{
|
||||
valid_u8_advance_index(str, i);
|
||||
return i;
|
||||
}
|
||||
|
||||
template <class Range>
|
||||
[[nodiscard]] auto valid_u8_prev_cp(const Range& str, size_t i)
|
||||
-> Idx_And_Prev_CP_Valid
|
||||
{
|
||||
char32_t cp;
|
||||
valid_u8_reverse_cp(str, i, cp);
|
||||
return {i, cp};
|
||||
}
|
||||
|
||||
template <class Range>
|
||||
[[nodiscard]] auto valid_u8_prev_index(const Range& str, size_t i) -> size_t
|
||||
{
|
||||
valid_u8_reverse_index(str, i);
|
||||
return i;
|
||||
}
|
||||
|
||||
template <class Range>
|
||||
[[nodiscard]] auto valid_u8_write_cp(Range& buf, size_t i, int32_t cp) -> size_t
|
||||
{
|
||||
valid_u8_write_cp_and_advance(buf, i, cp);
|
||||
return i;
|
||||
}
|
||||
} // namespace v5
|
||||
} // namespace nuspell
|
||||
#endif // NUSPELL_UNICODE_HXX
|
||||
@@ -1,465 +0,0 @@
|
||||
/* Copyright 2016-2021 Dimitrij Mijoski
|
||||
*
|
||||
* This file is part of Nuspell.
|
||||
*
|
||||
* Nuspell is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Nuspell is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with Nuspell. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "utils.hxx"
|
||||
#include "unicode.hxx"
|
||||
|
||||
#include <algorithm>
|
||||
#include <limits>
|
||||
|
||||
#include <unicode/uchar.h>
|
||||
#include <unicode/ucnv.h>
|
||||
#include <unicode/unistr.h>
|
||||
#include <unicode/ustring.h>
|
||||
|
||||
#if ' ' != 32 || '.' != 46 || 'A' != 65 || 'Z' != 90 || 'a' != 97 || 'z' != 122
|
||||
#error "Basic execution character set is not ASCII"
|
||||
#endif
|
||||
|
||||
using namespace std;
|
||||
|
||||
namespace nuspell {
|
||||
inline namespace v5 {
|
||||
|
||||
template <class SepT>
|
||||
static auto& split_on_any_of_low(std::string_view s, const SepT& sep,
|
||||
std::vector<std::string>& out)
|
||||
{
|
||||
size_t i1 = 0;
|
||||
size_t i2;
|
||||
do {
|
||||
i2 = s.find_first_of(sep, i1);
|
||||
out.emplace_back(s.substr(i1, i2 - i1));
|
||||
i1 = i2 + 1; // we can only add +1 if separator is single char.
|
||||
|
||||
// i2 gets s.npos after the last separator.
|
||||
// Length of i2-i1 will always go past the end. That is defined.
|
||||
} while (i2 != s.npos);
|
||||
return out;
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
* @brief Splits string on single char seperator.
|
||||
*
|
||||
* Consecutive separators are treated as separate and will emit empty strings.
|
||||
*
|
||||
* @param s string to split.
|
||||
* @param sep char that acts as separator to split on.
|
||||
* @param out vector where separated strings are appended.
|
||||
* @return @p out.
|
||||
*/
|
||||
auto split(std::string_view s, char sep, std::vector<std::string>& out)
|
||||
-> std::vector<std::string>&
|
||||
{
|
||||
return split_on_any_of_low(s, sep, out);
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
* @brief Splits string on set of single char seperators.
|
||||
*
|
||||
* Consecutive separators are treated as separate and will emit empty strings.
|
||||
*
|
||||
* @param s string to split.
|
||||
* @param sep seperator(s) to split on.
|
||||
* @param out vector where separated strings are appended.
|
||||
* @return @p out.
|
||||
*/
|
||||
auto split_on_any_of(std::string_view s, const char* sep,
|
||||
std::vector<std::string>& out) -> std::vector<std::string>&
|
||||
{
|
||||
return split_on_any_of_low(s, sep, out);
|
||||
}
|
||||
|
||||
auto utf32_to_utf8(std::u32string_view in, std::string& out) -> void
|
||||
{
|
||||
out.clear();
|
||||
for (size_t i = 0; i != size(in); ++i) {
|
||||
auto cp = in[i];
|
||||
auto enc_cp = U8_Encoded_CP(cp);
|
||||
out += enc_cp;
|
||||
}
|
||||
}
|
||||
auto utf32_to_utf8(std::u32string_view in) -> std::string
|
||||
{
|
||||
auto out = string();
|
||||
utf32_to_utf8(in, out);
|
||||
return out;
|
||||
}
|
||||
|
||||
auto valid_utf8_to_32(std::string_view in, std::u32string& out) -> void
|
||||
{
|
||||
out.clear();
|
||||
for (size_t i = 0; i != size(in);) {
|
||||
char32_t cp;
|
||||
valid_u8_advance_cp(in, i, cp);
|
||||
out.push_back(cp);
|
||||
}
|
||||
}
|
||||
auto valid_utf8_to_32(std::string_view in) -> std::u32string
|
||||
{
|
||||
auto out = u32string();
|
||||
valid_utf8_to_32(in, out);
|
||||
return out;
|
||||
}
|
||||
|
||||
auto utf8_to_16(std::string_view in) -> std::u16string
|
||||
{
|
||||
auto out = u16string();
|
||||
utf8_to_16(in, out);
|
||||
return out;
|
||||
}
|
||||
|
||||
bool utf8_to_16(std::string_view in, std::u16string& out)
|
||||
{
|
||||
int32_t len;
|
||||
auto err = U_ZERO_ERROR;
|
||||
u_strFromUTF8(data(out), size(out), &len, data(in), size(in), &err);
|
||||
out.resize(len);
|
||||
if (err == U_BUFFER_OVERFLOW_ERROR) {
|
||||
err = U_ZERO_ERROR;
|
||||
u_strFromUTF8(data(out), size(out), &len, data(in), size(in),
|
||||
&err);
|
||||
}
|
||||
if (U_SUCCESS(err))
|
||||
return true;
|
||||
out.clear();
|
||||
return false;
|
||||
}
|
||||
|
||||
bool validate_utf8(string_view s)
|
||||
{
|
||||
auto err = U_ZERO_ERROR;
|
||||
u_strFromUTF8(nullptr, 0, nullptr, data(s), size(s), &err);
|
||||
if (err == U_INVALID_CHAR_FOUND)
|
||||
return false;
|
||||
return err == U_BUFFER_OVERFLOW_ERROR || U_SUCCESS(err);
|
||||
}
|
||||
|
||||
auto static is_ascii(char c) -> bool
|
||||
{
|
||||
return static_cast<unsigned char>(c) <= 127;
|
||||
}
|
||||
|
||||
auto is_all_ascii(std::string_view s) -> bool
|
||||
{
|
||||
return all_of(begin(s), end(s), is_ascii);
|
||||
}
|
||||
|
||||
auto static widen_latin1(char c) -> char16_t
|
||||
{
|
||||
return static_cast<unsigned char>(c);
|
||||
}
|
||||
|
||||
auto latin1_to_ucs2(std::string_view s) -> std::u16string
|
||||
{
|
||||
u16string ret;
|
||||
latin1_to_ucs2(s, ret);
|
||||
return ret;
|
||||
}
|
||||
auto latin1_to_ucs2(std::string_view s, std::u16string& out) -> void
|
||||
{
|
||||
out.resize(s.size());
|
||||
transform(begin(s), end(s), begin(out), widen_latin1);
|
||||
}
|
||||
|
||||
auto static is_surrogate_pair(char16_t c) -> bool
|
||||
{
|
||||
return 0xD800 <= c && c <= 0xDFFF;
|
||||
}
|
||||
auto is_all_bmp(std::u16string_view s) -> bool
|
||||
{
|
||||
return none_of(begin(s), end(s), is_surrogate_pair);
|
||||
}
|
||||
|
||||
auto to_upper_ascii(std::string& s) -> void
|
||||
{
|
||||
auto& char_type = use_facet<ctype<char>>(locale::classic());
|
||||
char_type.toupper(begin_ptr(s), end_ptr(s));
|
||||
}
|
||||
|
||||
auto static utf32_to_icu(u32string_view in) -> icu::UnicodeString
|
||||
{
|
||||
static_assert(sizeof(UChar32) == sizeof(char32_t));
|
||||
return icu::UnicodeString::fromUTF32(
|
||||
reinterpret_cast<const UChar32*>(in.data()), in.size());
|
||||
}
|
||||
auto static icu_to_utf32(const icu::UnicodeString& in, std::u32string& out)
|
||||
-> bool
|
||||
{
|
||||
out.resize(in.length());
|
||||
auto err = U_ZERO_ERROR;
|
||||
auto len =
|
||||
in.toUTF32(reinterpret_cast<UChar32*>(out.data()), out.size(), err);
|
||||
if (U_SUCCESS(err)) {
|
||||
out.erase(len);
|
||||
return true;
|
||||
}
|
||||
out.clear();
|
||||
return false;
|
||||
}
|
||||
|
||||
auto to_upper(std::string_view in, const icu::Locale& loc) -> std::string
|
||||
{
|
||||
auto out = std::string();
|
||||
to_upper(in, loc, out);
|
||||
return out;
|
||||
}
|
||||
auto to_title(std::string_view in, const icu::Locale& loc) -> std::string
|
||||
{
|
||||
auto out = std::string();
|
||||
to_title(in, loc, out);
|
||||
return out;
|
||||
}
|
||||
auto to_lower(std::string_view in, const icu::Locale& loc) -> std::string
|
||||
{
|
||||
auto out = std::string();
|
||||
to_lower(in, loc, out);
|
||||
return out;
|
||||
}
|
||||
|
||||
auto to_upper(string_view in, const icu::Locale& loc, string& out) -> void
|
||||
{
|
||||
auto sp = icu::StringPiece(data(in), size(in));
|
||||
auto us = icu::UnicodeString::fromUTF8(sp);
|
||||
us.toUpper(loc);
|
||||
out.clear();
|
||||
us.toUTF8String(out);
|
||||
}
|
||||
auto to_title(string_view in, const icu::Locale& loc, string& out) -> void
|
||||
{
|
||||
auto sp = icu::StringPiece(data(in), size(in));
|
||||
auto us = icu::UnicodeString::fromUTF8(sp);
|
||||
us.toTitle(nullptr, loc);
|
||||
out.clear();
|
||||
us.toUTF8String(out);
|
||||
}
|
||||
auto to_lower(u32string_view in, const icu::Locale& loc, u32string& out) -> void
|
||||
{
|
||||
auto us = utf32_to_icu(in);
|
||||
us.toLower(loc);
|
||||
icu_to_utf32(us, out);
|
||||
}
|
||||
auto to_lower(string_view in, const icu::Locale& loc, string& out) -> void
|
||||
{
|
||||
auto sp = icu::StringPiece(data(in), size(in));
|
||||
auto us = icu::UnicodeString::fromUTF8(sp);
|
||||
us.toLower(loc);
|
||||
out.clear();
|
||||
us.toUTF8String(out);
|
||||
}
|
||||
|
||||
auto to_lower_char_at(std::string& s, size_t i, const icu::Locale& loc) -> void
|
||||
{
|
||||
auto cp = valid_u8_next_cp(s, i);
|
||||
auto us = icu::UnicodeString(UChar32(cp.cp));
|
||||
us.toLower(loc);
|
||||
auto u8_low = string();
|
||||
us.toUTF8String(u8_low);
|
||||
s.replace(i, cp.end_i - i, u8_low);
|
||||
}
|
||||
auto to_title_char_at(std::string& s, size_t i, const icu::Locale& loc) -> void
|
||||
{
|
||||
auto cp = valid_u8_next_cp(s, i);
|
||||
auto us = icu::UnicodeString(UChar32(cp.cp));
|
||||
us.toTitle(nullptr, loc);
|
||||
auto u8_title = string();
|
||||
us.toUTF8String(u8_title);
|
||||
s.replace(i, cp.end_i - i, u8_title);
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
* @brief Determines casing (capitalization) type for a word.
|
||||
*
|
||||
* Casing is sometimes referred to as capitalization.
|
||||
*
|
||||
* @param s word.
|
||||
* @return The casing type.
|
||||
*/
|
||||
auto classify_casing(string_view s) -> Casing
|
||||
{
|
||||
size_t upper = 0;
|
||||
size_t lower = 0;
|
||||
for (size_t i = 0; i != size(s);) {
|
||||
char32_t c;
|
||||
valid_u8_advance_cp(s, i, c);
|
||||
if (u_isupper(c))
|
||||
upper++;
|
||||
else if (u_islower(c))
|
||||
lower++;
|
||||
// else neutral
|
||||
}
|
||||
if (upper == 0) // all lowercase, maybe with some neutral
|
||||
return Casing::SMALL; // most common case
|
||||
|
||||
auto first_cp = valid_u8_next_cp(s, 0);
|
||||
auto first_capital = u_isupper(first_cp.cp);
|
||||
if (first_capital && upper == 1)
|
||||
return Casing::INIT_CAPITAL; // second most common
|
||||
|
||||
if (lower == 0)
|
||||
return Casing::ALL_CAPITAL;
|
||||
|
||||
if (first_capital)
|
||||
return Casing::PASCAL;
|
||||
else
|
||||
return Casing::CAMEL;
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
* @brief Check if word[i] or word[i-1] are uppercase
|
||||
*
|
||||
* Check if the two chars are alphabetic and at least one of them is in
|
||||
* uppercase.
|
||||
*
|
||||
* @return true if at least one is uppercase, false otherwise.
|
||||
*/
|
||||
auto has_uppercase_at_compound_word_boundary(string_view word, size_t i) -> bool
|
||||
{
|
||||
auto cp = valid_u8_next_cp(word, i);
|
||||
auto cp_prev = valid_u8_prev_cp(word, i);
|
||||
if (u_isupper(cp.cp)) {
|
||||
if (u_isalpha(cp_prev.cp))
|
||||
return true;
|
||||
}
|
||||
else if (u_isupper(cp_prev.cp) && u_isalpha(cp.cp))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
Encoding_Converter::Encoding_Converter(const char* enc)
|
||||
{
|
||||
auto err = UErrorCode();
|
||||
cnv = ucnv_open(enc, &err);
|
||||
}
|
||||
|
||||
Encoding_Converter::~Encoding_Converter()
|
||||
{
|
||||
if (cnv)
|
||||
ucnv_close(cnv);
|
||||
}
|
||||
|
||||
Encoding_Converter::Encoding_Converter(const Encoding_Converter& other)
|
||||
{
|
||||
auto err = UErrorCode();
|
||||
cnv = ucnv_safeClone(other.cnv, nullptr, nullptr, &err);
|
||||
}
|
||||
|
||||
auto Encoding_Converter::operator=(const Encoding_Converter& other)
|
||||
-> Encoding_Converter&
|
||||
{
|
||||
this->~Encoding_Converter();
|
||||
auto err = UErrorCode();
|
||||
cnv = ucnv_safeClone(other.cnv, nullptr, nullptr, &err);
|
||||
return *this;
|
||||
}
|
||||
|
||||
auto Encoding_Converter::to_utf8(string_view in, string& out) -> bool
|
||||
{
|
||||
if (ucnv_getType(cnv) == UCNV_UTF8) {
|
||||
if (validate_utf8(in)) {
|
||||
out = in;
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
out.clear();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
auto err = U_ZERO_ERROR;
|
||||
auto len = ucnv_toAlgorithmic(UCNV_UTF8, cnv, out.data(), out.size(),
|
||||
in.data(), in.size(), &err);
|
||||
out.resize(len);
|
||||
if (err == U_BUFFER_OVERFLOW_ERROR) {
|
||||
err = U_ZERO_ERROR;
|
||||
ucnv_toAlgorithmic(UCNV_UTF8, cnv, out.data(), out.size(),
|
||||
in.data(), in.size(), &err);
|
||||
}
|
||||
return U_SUCCESS(err);
|
||||
}
|
||||
|
||||
auto replace_ascii_char(string& s, char from, char to) -> void
|
||||
{
|
||||
for (auto i = s.find(from); i != s.npos; i = s.find(from, i + 1)) {
|
||||
s[i] = to;
|
||||
}
|
||||
}
|
||||
|
||||
auto erase_chars(string& s, string_view erase_chars) -> void
|
||||
{
|
||||
if (erase_chars.empty())
|
||||
return;
|
||||
for (size_t i = 0, next_i = 0; i != size(s); i = next_i) {
|
||||
valid_u8_advance_index(s, next_i);
|
||||
auto enc_cp = string_view(&s[i], next_i - i);
|
||||
if (erase_chars.find(enc_cp) != erase_chars.npos) {
|
||||
s.erase(i, next_i - i);
|
||||
next_i = i;
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
* @brief Tests if word is a number.
|
||||
*
|
||||
* Allow numbers with dot ".", dash "-" or comma "," inbetween the digits, but
|
||||
* forbids double separators such as "..", "--" and ".,".
|
||||
*/
|
||||
auto is_number(string_view s) -> bool
|
||||
{
|
||||
if (s.empty())
|
||||
return false;
|
||||
|
||||
auto it = begin(s);
|
||||
if (s[0] == '-')
|
||||
++it;
|
||||
while (it != end(s)) {
|
||||
auto next = std::find_if(
|
||||
it, end(s), [](auto c) { return c < '0' || c > '9'; });
|
||||
if (next == it)
|
||||
return false;
|
||||
if (next == end(s))
|
||||
return true;
|
||||
it = next;
|
||||
auto c = *it;
|
||||
if (c == '.' || c == ',' || c == '-')
|
||||
++it;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
auto count_appereances_of(string_view haystack, string_view needles) -> size_t
|
||||
{
|
||||
auto ret = size_t(0);
|
||||
for (size_t i = 0, next_i = 0; i != size(haystack); i = next_i) {
|
||||
valid_u8_advance_index(haystack, next_i);
|
||||
auto enc_cp = string_view(&haystack[i], next_i - i);
|
||||
ret += needles.find(enc_cp) != needles.npos;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
} // namespace v5
|
||||
} // namespace nuspell
|
||||
@@ -1,228 +0,0 @@
|
||||
/* Copyright 2016-2021 Dimitrij Mijoski
|
||||
*
|
||||
* This file is part of Nuspell.
|
||||
*
|
||||
* Nuspell is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Nuspell is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with Nuspell. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef NUSPELL_UTILS_HXX
|
||||
#define NUSPELL_UTILS_HXX
|
||||
|
||||
#include "nuspell_export.h"
|
||||
|
||||
#include <clocale>
|
||||
#include <locale>
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
#include <vector>
|
||||
|
||||
#if !defined(_WIN32) && \
|
||||
(defined(__unix__) || defined(__unix) || \
|
||||
(defined(__APPLE__) && defined(__MACH__)) || defined(__HAIKU__))
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#include <unicode/locid.h>
|
||||
|
||||
#ifdef __GNUC__
|
||||
#define likely(expr) __builtin_expect(!!(expr), 1)
|
||||
#define unlikely(expr) __builtin_expect(!!(expr), 0)
|
||||
#else
|
||||
#define likely(expr) (expr)
|
||||
#define unlikely(expr) (expr)
|
||||
#endif
|
||||
|
||||
struct UConverter; // unicode/ucnv.h
|
||||
|
||||
namespace nuspell {
|
||||
inline namespace v5 {
|
||||
|
||||
auto split(std::string_view s, char sep, std::vector<std::string>& out)
|
||||
-> std::vector<std::string>&;
|
||||
NUSPELL_EXPORT auto split_on_any_of(std::string_view s, const char* sep,
|
||||
std::vector<std::string>& out)
|
||||
-> std::vector<std::string>&;
|
||||
|
||||
NUSPELL_EXPORT auto utf32_to_utf8(std::u32string_view in, std::string& out)
|
||||
-> void;
|
||||
NUSPELL_EXPORT auto utf32_to_utf8(std::u32string_view in) -> std::string;
|
||||
|
||||
auto valid_utf8_to_32(std::string_view in, std::u32string& out) -> void;
|
||||
auto valid_utf8_to_32(std::string_view in) -> std::u32string;
|
||||
|
||||
auto utf8_to_16(std::string_view in) -> std::u16string;
|
||||
auto utf8_to_16(std::string_view in, std::u16string& out) -> bool;
|
||||
|
||||
auto validate_utf8(std::string_view s) -> bool;
|
||||
|
||||
NUSPELL_EXPORT auto is_all_ascii(std::string_view s) -> bool;
|
||||
|
||||
NUSPELL_EXPORT auto latin1_to_ucs2(std::string_view s) -> std::u16string;
|
||||
auto latin1_to_ucs2(std::string_view s, std::u16string& out) -> void;
|
||||
|
||||
NUSPELL_EXPORT auto is_all_bmp(std::u16string_view s) -> bool;
|
||||
|
||||
auto to_upper_ascii(std::string& s) -> void;
|
||||
|
||||
[[nodiscard]] NUSPELL_EXPORT auto to_upper(std::string_view in,
|
||||
const icu::Locale& loc)
|
||||
-> std::string;
|
||||
[[nodiscard]] NUSPELL_EXPORT auto to_title(std::string_view in,
|
||||
const icu::Locale& loc)
|
||||
-> std::string;
|
||||
[[nodiscard]] NUSPELL_EXPORT auto to_lower(std::string_view in,
|
||||
const icu::Locale& loc)
|
||||
-> std::string;
|
||||
|
||||
auto to_upper(std::string_view in, const icu::Locale& loc, std::string& out)
|
||||
-> void;
|
||||
auto to_title(std::string_view in, const icu::Locale& loc, std::string& out)
|
||||
-> void;
|
||||
auto to_lower(std::u32string_view in, const icu::Locale& loc,
|
||||
std::u32string& out) -> void;
|
||||
auto to_lower(std::string_view in, const icu::Locale& loc, std::string& out)
|
||||
-> void;
|
||||
auto to_lower_char_at(std::string& s, size_t i, const icu::Locale& loc) -> void;
|
||||
auto to_title_char_at(std::string& s, size_t i, const icu::Locale& loc) -> void;
|
||||
|
||||
/**
|
||||
* @internal
|
||||
* @brief Enum that identifies the casing type of a word.
|
||||
*
|
||||
* Neutral characters like numbers are ignored, so "abc" and "abc123abc" are
|
||||
* both classified as small.
|
||||
*/
|
||||
enum class Casing : char {
|
||||
SMALL,
|
||||
INIT_CAPITAL,
|
||||
ALL_CAPITAL,
|
||||
CAMEL /**< @internal camelCase i.e. mixed case with first small */,
|
||||
PASCAL /**< @internal PascalCase i.e. mixed case with first capital */
|
||||
};
|
||||
|
||||
NUSPELL_EXPORT auto classify_casing(std::string_view s) -> Casing;
|
||||
|
||||
auto has_uppercase_at_compound_word_boundary(std::string_view word, size_t i)
|
||||
-> bool;
|
||||
|
||||
class Encoding_Converter {
|
||||
UConverter* cnv = nullptr;
|
||||
|
||||
public:
|
||||
Encoding_Converter() = default;
|
||||
explicit Encoding_Converter(const char* enc);
|
||||
explicit Encoding_Converter(const std::string& enc)
|
||||
: Encoding_Converter(enc.c_str())
|
||||
{
|
||||
}
|
||||
~Encoding_Converter();
|
||||
Encoding_Converter(const Encoding_Converter& other);
|
||||
Encoding_Converter(Encoding_Converter&& other) noexcept
|
||||
{
|
||||
cnv = other.cnv;
|
||||
cnv = nullptr;
|
||||
}
|
||||
auto operator=(const Encoding_Converter& other) -> Encoding_Converter&;
|
||||
auto operator=(Encoding_Converter&& other) noexcept
|
||||
-> Encoding_Converter&
|
||||
{
|
||||
std::swap(cnv, other.cnv);
|
||||
return *this;
|
||||
}
|
||||
auto to_utf8(std::string_view in, std::string& out) -> bool;
|
||||
auto valid() -> bool { return cnv != nullptr; }
|
||||
};
|
||||
|
||||
//#if _POSIX_VERSION >= 200809L
|
||||
#if defined(_POSIX_VERSION) && !defined(__NetBSD__) && !defined(__HAIKU__)
|
||||
class Setlocale_To_C_In_Scope {
|
||||
locale_t old_loc = nullptr;
|
||||
|
||||
public:
|
||||
Setlocale_To_C_In_Scope()
|
||||
: old_loc{uselocale(newlocale(0, "C", nullptr))}
|
||||
{
|
||||
}
|
||||
~Setlocale_To_C_In_Scope()
|
||||
{
|
||||
auto new_loc = uselocale(old_loc);
|
||||
if (new_loc != old_loc)
|
||||
freelocale(new_loc);
|
||||
}
|
||||
Setlocale_To_C_In_Scope(const Setlocale_To_C_In_Scope&) = delete;
|
||||
};
|
||||
#else
|
||||
class Setlocale_To_C_In_Scope {
|
||||
std::string old_name;
|
||||
#ifdef _WIN32
|
||||
int old_per_thread;
|
||||
#endif
|
||||
public:
|
||||
Setlocale_To_C_In_Scope() : old_name(setlocale(LC_ALL, nullptr))
|
||||
{
|
||||
#ifdef _WIN32
|
||||
old_per_thread = _configthreadlocale(_ENABLE_PER_THREAD_LOCALE);
|
||||
#endif
|
||||
auto x = setlocale(LC_ALL, "C");
|
||||
if (!x)
|
||||
old_name.clear();
|
||||
}
|
||||
~Setlocale_To_C_In_Scope()
|
||||
{
|
||||
#ifdef _WIN32
|
||||
_configthreadlocale(old_per_thread);
|
||||
if (old_per_thread == _ENABLE_PER_THREAD_LOCALE)
|
||||
#endif
|
||||
{
|
||||
if (!old_name.empty())
|
||||
setlocale(LC_ALL, old_name.c_str());
|
||||
}
|
||||
}
|
||||
Setlocale_To_C_In_Scope(const Setlocale_To_C_In_Scope&) = delete;
|
||||
};
|
||||
#endif
|
||||
|
||||
auto replace_ascii_char(std::string& s, char from, char to) -> void;
|
||||
auto erase_chars(std::string& s, std::string_view erase_chars) -> void;
|
||||
NUSPELL_EXPORT auto is_number(std::string_view s) -> bool;
|
||||
auto count_appereances_of(std::string_view haystack, std::string_view needles)
|
||||
-> size_t;
|
||||
|
||||
auto inline begins_with(std::string_view haystack, std::string_view needle)
|
||||
-> bool
|
||||
{
|
||||
return haystack.compare(0, needle.size(), needle) == 0;
|
||||
}
|
||||
|
||||
auto inline ends_with(std::string_view haystack, std::string_view needle)
|
||||
-> bool
|
||||
{
|
||||
return haystack.size() >= needle.size() &&
|
||||
haystack.compare(haystack.size() - needle.size(), needle.size(),
|
||||
needle) == 0;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
auto begin_ptr(T& x)
|
||||
{
|
||||
return x.data();
|
||||
}
|
||||
template <class T>
|
||||
auto end_ptr(T& x)
|
||||
{
|
||||
return x.data() + x.size();
|
||||
}
|
||||
} // namespace v5
|
||||
} // namespace nuspell
|
||||
#endif // NUSPELL_UTILS_HXX
|
||||
@@ -21,12 +21,12 @@ std::string utils::j2std_string(JNIEnv *env, jobject jStr) {
|
||||
auto cStr = reinterpret_cast<const char *>(env->GetDirectBufferAddress(jStr));
|
||||
auto size = env->GetDirectBufferCapacity(jStr);
|
||||
std::string stdStr(cStr, size);
|
||||
log_debug("spell j2s", stdStr);
|
||||
utils::log(ANDROID_LOG_DEBUG, "spell j2s", stdStr);
|
||||
return stdStr;
|
||||
}
|
||||
|
||||
jobject utils::std2j_string(JNIEnv *env, const std::string& stdStr) {
|
||||
log_debug("spell s2j", stdStr);
|
||||
utils::log(ANDROID_LOG_DEBUG, "spell s2j", stdStr);
|
||||
size_t byteCount = stdStr.length();
|
||||
auto cStr = stdStr.c_str();
|
||||
auto buffer = env->NewDirectByteBuffer((void *) cStr, byteCount);
|
||||
|
||||
@@ -15,67 +15,61 @@
|
||||
*/
|
||||
|
||||
#include <android/log.h>
|
||||
#include <cerrno>
|
||||
#include <cstring>
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
#include <thread>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "log.h"
|
||||
|
||||
void utils::log_debug(const std::string &tag, const std::string &msg) {
|
||||
__android_log_print(ANDROID_LOG_DEBUG, tag.c_str(), "%s", msg.c_str());
|
||||
}
|
||||
|
||||
void utils::log_info(const std::string &tag, const std::string &msg) {
|
||||
__android_log_print(ANDROID_LOG_INFO, tag.c_str(), "%s", msg.c_str());
|
||||
}
|
||||
|
||||
void utils::log_warning(const std::string &tag, const std::string &msg) {
|
||||
__android_log_print(ANDROID_LOG_WARN, tag.c_str(), "%s", msg.c_str());
|
||||
}
|
||||
|
||||
void utils::log_error(const std::string &tag, const std::string &msg) {
|
||||
__android_log_print(ANDROID_LOG_ERROR, tag.c_str(), "%s", msg.c_str());
|
||||
}
|
||||
|
||||
void utils::log_wtf(const std::string &tag, const std::string &msg) {
|
||||
__android_log_print(ANDROID_LOG_FATAL, tag.c_str(), "%s", msg.c_str());
|
||||
void utils::log(int log_priority, const std::string &tag, const std::string &msg) {
|
||||
__android_log_print(log_priority, tag.c_str(), "%s", msg.c_str());
|
||||
}
|
||||
|
||||
/**
|
||||
* Code below taken from here:
|
||||
* Code below based on:
|
||||
* https://codelab.wordpress.com/2014/11/03/how-to-use-standard-output-streams-for-logging-in-android-apps/
|
||||
*/
|
||||
static int pfd[2];
|
||||
static pthread_t thr;
|
||||
static const char *tag = "myapp";
|
||||
static bool already_started = false;
|
||||
int utils::start_stdout_stderr_logger(const std::string &app_name) {
|
||||
static bool already_started = false;
|
||||
if (already_started)
|
||||
return 0;
|
||||
|
||||
static void *thread_func(void*) {
|
||||
ssize_t rdsz;
|
||||
char buf[2048];
|
||||
while ((rdsz = read(pfd[0], buf, sizeof buf - 1)) > 0) {
|
||||
if (buf[rdsz - 1] == '\n') --rdsz;
|
||||
buf[rdsz] = 0; /* add null-terminator */
|
||||
__android_log_write(ANDROID_LOG_DEBUG, tag, buf);
|
||||
int piperw[2];
|
||||
if (pipe(piperw) < 0) {
|
||||
std::string msg = "pipe(): ";
|
||||
msg += strerror(errno);
|
||||
utils::log(ANDROID_LOG_ERROR, "stdout/stderr logger", std::ref(msg));
|
||||
return 1;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
int utils::start_stdout_stderr_logger(const char *app_name) {
|
||||
if (already_started) return 0;
|
||||
already_started = true;
|
||||
tag = app_name;
|
||||
|
||||
/* make stdout line-buffered and stderr unbuffered */
|
||||
setvbuf(stdout, nullptr, _IOLBF, 0);
|
||||
setvbuf(stderr, nullptr, _IONBF, 0);
|
||||
|
||||
/* create the pipe and redirect stdout and stderr */
|
||||
pipe(pfd);
|
||||
dup2(pfd[1], 1);
|
||||
dup2(pfd[1], 2);
|
||||
dup2(piperw[0], STDIN_FILENO);
|
||||
dup2(piperw[1], STDOUT_FILENO);
|
||||
dup2(piperw[1], STDERR_FILENO);
|
||||
close(piperw[0]);
|
||||
close(piperw[1]);
|
||||
|
||||
auto f = [](const std::string &tag) {
|
||||
std::string buf;
|
||||
while (std::getline(std::cin, buf)) {
|
||||
char &back = buf.back();
|
||||
if (back == '\n')
|
||||
back = '\0';
|
||||
utils::log(ANDROID_LOG_DEBUG, tag, std::ref(buf));
|
||||
}
|
||||
};
|
||||
|
||||
/* spawn the logging thread */
|
||||
if (pthread_create(&thr, nullptr, thread_func, nullptr) != 0) {
|
||||
return -1;
|
||||
}
|
||||
pthread_detach(thr);
|
||||
std::thread thr(f, app_name);
|
||||
thr.detach();
|
||||
|
||||
already_started = true;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -17,17 +17,14 @@
|
||||
#ifndef FLORISBOARD_LOG_H
|
||||
#define FLORISBOARD_LOG_H
|
||||
|
||||
#include <android/log.h>
|
||||
#include <string>
|
||||
|
||||
namespace utils {
|
||||
|
||||
void log_debug(const std::string& tag, const std::string& msg);
|
||||
void log_info(const std::string& tag, const std::string& msg);
|
||||
void log_warning(const std::string& tag, const std::string& msg);
|
||||
void log_error(const std::string& tag, const std::string& msg);
|
||||
void log_wtf(const std::string& tag, const std::string& msg);
|
||||
void log(int log_priority, const std::string &tag, const std::string &msg);
|
||||
|
||||
int start_stdout_stderr_logger(const char *app_name);
|
||||
int start_stdout_stderr_logger(const std::string &app_name);
|
||||
|
||||
} // namespace utils
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user