summaryrefslogtreecommitdiffstats
path: root/extensions
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-07 17:32:43 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-07 17:32:43 +0000
commit6bf0a5cb5034a7e684dcc3500e841785237ce2dd (patch)
treea68f146d7fa01f0134297619fbe7e33db084e0aa /extensions
parentInitial commit. (diff)
downloadthunderbird-6bf0a5cb5034a7e684dcc3500e841785237ce2dd.tar.xz
thunderbird-6bf0a5cb5034a7e684dcc3500e841785237ce2dd.zip
Adding upstream version 1:115.7.0.upstream/1%115.7.0upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'extensions')
-rw-r--r--extensions/auth/gssapi.h792
-rw-r--r--extensions/auth/moz.build39
-rw-r--r--extensions/auth/nsAuth.h23
-rw-r--r--extensions/auth/nsAuthGSSAPI.cpp533
-rw-r--r--extensions/auth/nsAuthGSSAPI.h62
-rw-r--r--extensions/auth/nsAuthSASL.cpp123
-rw-r--r--extensions/auth/nsAuthSASL.h35
-rw-r--r--extensions/auth/nsAuthSSPI.cpp574
-rw-r--r--extensions/auth/nsAuthSSPI.h60
-rw-r--r--extensions/auth/nsAuthSambaNTLM.cpp259
-rw-r--r--extensions/auth/nsAuthSambaNTLM.h51
-rw-r--r--extensions/auth/nsHttpNegotiateAuth.cpp565
-rw-r--r--extensions/auth/nsHttpNegotiateAuth.h35
-rw-r--r--extensions/auth/nsIAuthModule.cpp63
-rw-r--r--extensions/permissions/Permission.cpp122
-rw-r--r--extensions/permissions/Permission.h49
-rw-r--r--extensions/permissions/PermissionDelegateHandler.cpp403
-rw-r--r--extensions/permissions/PermissionDelegateHandler.h203
-rw-r--r--extensions/permissions/PermissionDelegateIPCUtils.h40
-rw-r--r--extensions/permissions/PermissionManager.cpp3928
-rw-r--r--extensions/permissions/PermissionManager.h682
-rw-r--r--extensions/permissions/components.conf25
-rw-r--r--extensions/permissions/moz.build39
-rw-r--r--extensions/permissions/test/PermissionTestUtils.sys.mjs111
-rw-r--r--extensions/permissions/test/browser.ini8
-rw-r--r--extensions/permissions/test/browser_permmgr_sync.js448
-rw-r--r--extensions/permissions/test/browser_permmgr_viewsrc.js28
-rw-r--r--extensions/permissions/test/gtest/PermissionManagerTest.cpp52
-rw-r--r--extensions/permissions/test/gtest/moz.build11
-rw-r--r--extensions/permissions/test/moz.build15
-rw-r--r--extensions/permissions/test/unit/head.js26
-rw-r--r--extensions/permissions/test/unit/test_permmanager_cleardata.js93
-rw-r--r--extensions/permissions/test/unit/test_permmanager_default_pref.js76
-rw-r--r--extensions/permissions/test/unit/test_permmanager_defaults.js485
-rw-r--r--extensions/permissions/test/unit/test_permmanager_expiration.js189
-rw-r--r--extensions/permissions/test/unit/test_permmanager_getAllByTypeSince.js79
-rw-r--r--extensions/permissions/test/unit/test_permmanager_getAllByTypes.js124
-rw-r--r--extensions/permissions/test/unit/test_permmanager_getAllForPrincipal.js72
-rw-r--r--extensions/permissions/test/unit/test_permmanager_getAllWithTypePrefix.js84
-rw-r--r--extensions/permissions/test/unit/test_permmanager_getPermissionObject.js98
-rw-r--r--extensions/permissions/test/unit/test_permmanager_idn.js75
-rw-r--r--extensions/permissions/test/unit/test_permmanager_ipc.js89
-rw-r--r--extensions/permissions/test/unit/test_permmanager_load_invalid_entries.js264
-rw-r--r--extensions/permissions/test/unit/test_permmanager_local_files.js74
-rw-r--r--extensions/permissions/test/unit/test_permmanager_matches.js203
-rw-r--r--extensions/permissions/test/unit/test_permmanager_matchesuri.js252
-rw-r--r--extensions/permissions/test/unit/test_permmanager_migrate_10-11.js196
-rw-r--r--extensions/permissions/test/unit/test_permmanager_migrate_11-12.js230
-rw-r--r--extensions/permissions/test/unit/test_permmanager_migrate_4-7.js264
-rw-r--r--extensions/permissions/test/unit/test_permmanager_migrate_4-7_no_history.js279
-rw-r--r--extensions/permissions/test/unit/test_permmanager_migrate_5-7a.js365
-rw-r--r--extensions/permissions/test/unit/test_permmanager_migrate_5-7b.js203
-rw-r--r--extensions/permissions/test/unit/test_permmanager_migrate_6-7a.js366
-rw-r--r--extensions/permissions/test/unit/test_permmanager_migrate_6-7b.js199
-rw-r--r--extensions/permissions/test/unit/test_permmanager_migrate_7-8.js328
-rw-r--r--extensions/permissions/test/unit/test_permmanager_migrate_9-10.js262
-rw-r--r--extensions/permissions/test/unit/test_permmanager_notifications.js139
-rw-r--r--extensions/permissions/test/unit/test_permmanager_oa_strip.js220
-rw-r--r--extensions/permissions/test/unit/test_permmanager_remove_add_update.js84
-rw-r--r--extensions/permissions/test/unit/test_permmanager_removeall.js47
-rw-r--r--extensions/permissions/test/unit/test_permmanager_removebytype.js76
-rw-r--r--extensions/permissions/test/unit/test_permmanager_removebytypesince.js89
-rw-r--r--extensions/permissions/test/unit/test_permmanager_removepermission.js58
-rw-r--r--extensions/permissions/test/unit/test_permmanager_removesince.js83
-rw-r--r--extensions/permissions/test/unit/test_permmanager_site_scope.js116
-rw-r--r--extensions/permissions/test/unit/test_permmanager_subdomains.js106
-rw-r--r--extensions/permissions/test/unit/xpcshell.ini60
-rw-r--r--extensions/pref/autoconfig/moz.build11
-rw-r--r--extensions/pref/autoconfig/src/components.conf21
-rw-r--r--extensions/pref/autoconfig/src/moz.build21
-rw-r--r--extensions/pref/autoconfig/src/nsAutoConfig.cpp464
-rw-r--r--extensions/pref/autoconfig/src/nsAutoConfig.h54
-rw-r--r--extensions/pref/autoconfig/src/nsJSConfigTriggers.cpp170
-rw-r--r--extensions/pref/autoconfig/src/nsJSConfigTriggers.h23
-rw-r--r--extensions/pref/autoconfig/src/nsReadConfig.cpp312
-rw-r--r--extensions/pref/autoconfig/src/nsReadConfig.h34
-rw-r--r--extensions/pref/autoconfig/src/prefcalls.js225
-rw-r--r--extensions/pref/autoconfig/test/marionette/autoconfig.cfg18
-rw-r--r--extensions/pref/autoconfig/test/marionette/autoconfig.js5
-rw-r--r--extensions/pref/autoconfig/test/marionette/manifest.ini1
-rw-r--r--extensions/pref/autoconfig/test/marionette/test_autoconfig.py101
-rw-r--r--extensions/pref/autoconfig/test/unit/autoconfig-all.cfg31
-rw-r--r--extensions/pref/autoconfig/test/unit/autoconfig-chromecheck.cfg5
-rw-r--r--extensions/pref/autoconfig/test/unit/autoconfig-latin1.cfg6
-rw-r--r--extensions/pref/autoconfig/test/unit/autoconfig-no-sandbox-check.cfg5
-rw-r--r--extensions/pref/autoconfig/test/unit/autoconfig-no-sandbox.js5
-rw-r--r--extensions/pref/autoconfig/test/unit/autoconfig-snap.cfg4
-rw-r--r--extensions/pref/autoconfig/test/unit/autoconfig-utf8.cfg6
-rw-r--r--extensions/pref/autoconfig/test/unit/autoconfig.js5
-rw-r--r--extensions/pref/autoconfig/test/unit/autoconfig_snap.js5
-rw-r--r--extensions/pref/autoconfig/test/unit/test_autoconfig.js83
-rw-r--r--extensions/pref/autoconfig/test/unit/test_autoconfig_custom_path.js22
-rw-r--r--extensions/pref/autoconfig/test/unit/test_autoconfig_default_path.js16
-rw-r--r--extensions/pref/autoconfig/test/unit/test_autoconfig_no_sandbox.js59
-rw-r--r--extensions/pref/autoconfig/test/unit/test_autoconfig_nonascii.js110
-rw-r--r--extensions/pref/autoconfig/test/unit/test_autoconfig_snap.js77
-rw-r--r--extensions/pref/autoconfig/test/unit/xpcshell.ini23
-rw-r--r--extensions/pref/autoconfig/test/unit/xpcshell_snap.ini8
-rw-r--r--extensions/pref/moz.build11
-rw-r--r--extensions/spellcheck/docs/index.rst199
-rw-r--r--extensions/spellcheck/hunspell/glue/PRemoteSpellcheckEngine.ipdl46
-rw-r--r--extensions/spellcheck/hunspell/glue/RLBoxHunspell.cpp256
-rw-r--r--extensions/spellcheck/hunspell/glue/RLBoxHunspell.h66
-rw-r--r--extensions/spellcheck/hunspell/glue/RLBoxHunspellTypes.h27
-rw-r--r--extensions/spellcheck/hunspell/glue/RemoteSpellCheckEngineChild.cpp84
-rw-r--r--extensions/spellcheck/hunspell/glue/RemoteSpellCheckEngineChild.h36
-rw-r--r--extensions/spellcheck/hunspell/glue/RemoteSpellCheckEngineParent.cpp85
-rw-r--r--extensions/spellcheck/hunspell/glue/RemoteSpellCheckEngineParent.h46
-rw-r--r--extensions/spellcheck/hunspell/glue/common.mozbuild9
-rw-r--r--extensions/spellcheck/hunspell/glue/hunspell_alloc_hooks.h59
-rw-r--r--extensions/spellcheck/hunspell/glue/hunspell_csutil.cxx160
-rw-r--r--extensions/spellcheck/hunspell/glue/hunspell_csutil.hxx87
-rw-r--r--extensions/spellcheck/hunspell/glue/hunspell_fopen_hooks.h81
-rw-r--r--extensions/spellcheck/hunspell/glue/moz.build39
-rw-r--r--extensions/spellcheck/hunspell/glue/mozHunspell.cpp594
-rw-r--r--extensions/spellcheck/hunspell/glue/mozHunspell.h145
-rw-r--r--extensions/spellcheck/hunspell/glue/mozHunspellAllocator.h15
-rw-r--r--extensions/spellcheck/hunspell/glue/mozHunspellRLBoxGlue.h45
-rw-r--r--extensions/spellcheck/hunspell/glue/mozHunspellRLBoxHost.cpp235
-rw-r--r--extensions/spellcheck/hunspell/glue/mozHunspellRLBoxHost.h122
-rw-r--r--extensions/spellcheck/hunspell/glue/mozHunspellRLBoxSandbox.cpp54
-rw-r--r--extensions/spellcheck/hunspell/glue/mozHunspellRLBoxSandbox.h36
-rw-r--r--extensions/spellcheck/hunspell/moz.build10
-rw-r--r--extensions/spellcheck/hunspell/patches/bug1410214.patch37
-rw-r--r--extensions/spellcheck/hunspell/patches/bug1653659.patch190
-rw-r--r--extensions/spellcheck/hunspell/patches/bug1739761.patch615
-rw-r--r--extensions/spellcheck/hunspell/patches/bug1838113.patch20
-rw-r--r--extensions/spellcheck/hunspell/src/COPYING.MPL470
-rw-r--r--extensions/spellcheck/hunspell/src/README.md325
-rw-r--r--extensions/spellcheck/hunspell/src/affentry.cxx983
-rw-r--r--extensions/spellcheck/hunspell/src/affentry.hxx223
-rw-r--r--extensions/spellcheck/hunspell/src/affixmgr.cxx4875
-rw-r--r--extensions/spellcheck/hunspell/src/affixmgr.hxx368
-rw-r--r--extensions/spellcheck/hunspell/src/atypes.hxx129
-rw-r--r--extensions/spellcheck/hunspell/src/baseaffix.hxx74
-rw-r--r--extensions/spellcheck/hunspell/src/csutil.cxx2551
-rw-r--r--extensions/spellcheck/hunspell/src/csutil.hxx323
-rw-r--r--extensions/spellcheck/hunspell/src/filemgr.hxx77
-rw-r--r--extensions/spellcheck/hunspell/src/hashmgr.cxx1415
-rw-r--r--extensions/spellcheck/hunspell/src/hashmgr.hxx182
-rw-r--r--extensions/spellcheck/hunspell/src/htypes.hxx75
-rw-r--r--extensions/spellcheck/hunspell/src/hunspell.cxx2249
-rw-r--r--extensions/spellcheck/hunspell/src/hunspell.h162
-rw-r--r--extensions/spellcheck/hunspell/src/hunspell.hxx232
-rw-r--r--extensions/spellcheck/hunspell/src/hunvisapi.h18
-rw-r--r--extensions/spellcheck/hunspell/src/langnum.hxx76
-rw-r--r--extensions/spellcheck/hunspell/src/license.hunspell54
-rw-r--r--extensions/spellcheck/hunspell/src/license.myspell61
-rw-r--r--extensions/spellcheck/hunspell/src/moz.build30
-rw-r--r--extensions/spellcheck/hunspell/src/moz.yaml16
-rw-r--r--extensions/spellcheck/hunspell/src/phonet.cxx270
-rw-r--r--extensions/spellcheck/hunspell/src/phonet.hxx50
-rw-r--r--extensions/spellcheck/hunspell/src/replist.cxx196
-rw-r--r--extensions/spellcheck/hunspell/src/replist.hxx100
-rw-r--r--extensions/spellcheck/hunspell/src/sources.mozbuild17
-rw-r--r--extensions/spellcheck/hunspell/src/suggestmgr.cxx2263
-rw-r--r--extensions/spellcheck/hunspell/src/suggestmgr.hxx183
-rw-r--r--extensions/spellcheck/hunspell/src/w_char.hxx72
-rw-r--r--extensions/spellcheck/hunspell/tests/crashtests/1825445.html12
-rw-r--r--extensions/spellcheck/hunspell/tests/crashtests/crashtests.list1
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/1463589-utf.aff4
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/1463589-utf.dic2
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/1463589-utf.sug5
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/1463589-utf.test4
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/1463589-utf.wrong5
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/1463589.aff3
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/1463589.dic2
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/1463589.sug5
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/1463589.test4
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/1463589.wrong5
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/1592880.aff20
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/1592880.dic4
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/1592880.good3
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/1592880.test4
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/1695964.aff10
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/1695964.dic3
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/1695964.sug3
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/1695964.test4
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/1695964.wrong3
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/1706659.aff13
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/1706659.dic4
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/1706659.test4
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/1706659.wrong3
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/1975530.aff6
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/1975530.dic3
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/1975530.good3
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/1975530.test4
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/1975530.wrong1
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/2970240.aff5
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/2970240.dic4
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/2970240.good1
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/2970240.test4
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/2970240.wrong1
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/2970242.aff4
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/2970242.dic4
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/2970242.good5
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/2970242.test4
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/2970242.wrong1
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/2999225.aff6
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/2999225.dic4
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/2999225.good2
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/2999225.test4
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/IJ.aff8
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/IJ.dic3
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/IJ.good2
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/IJ.sug1
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/IJ.test4
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/IJ.wrong1
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/Makefile.am693
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/Makefile.in1416
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/affixes.aff7
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/affixes.dic4
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/affixes.good7
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/affixes.test4
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/alias.aff12
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/alias.dic2
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/alias.good4
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/alias.test4
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/alias2.aff17
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/alias2.dic2
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/alias2.good4
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/alias2.morph12
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/alias2.test4
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/alias3.aff18
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/alias3.dic2
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/alias3.good4
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/alias3.morph8
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/alias3.test4
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/allcaps-utf.aff6
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/allcaps-utf.dic3
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/allcaps-utf.good4
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/allcaps-utf.sug3
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/allcaps-utf.test4
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/allcaps-utf.wrong3
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/allcaps.aff5
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/allcaps.dic3
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/allcaps.good4
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/allcaps.sug3
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/allcaps.test4
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/allcaps.wrong3
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/allcaps2.aff6
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/allcaps2.dic4
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/allcaps2.good4
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/allcaps2.sug2
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/allcaps2.test4
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/allcaps2.wrong2
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/allcaps3.aff10
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/allcaps3.dic7
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/allcaps3.good13
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/allcaps3.test4
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/allcaps3.wrong4
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/arabic.aff6
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/arabic.dic2
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/arabic.test4
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/arabic.wrong1
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/base-utf.aff198
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/base-utf.dic29
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/base-utf.good27
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/base-utf.sug11
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/base-utf.test4
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/base-utf.wrong11
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/base.aff192
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/base.dic29
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/base.good27
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/base.sug11
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/base.test4
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/base.wrong11
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/break.aff8
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/break.dic4
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/break.good7
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/break.test4
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/break.wrong12
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/breakdefault.aff6
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/breakdefault.dic6
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/breakdefault.good7
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/breakdefault.sug3
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/breakdefault.test4
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/breakdefault.wrong3
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/breakoff.aff7
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/breakoff.dic6
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/breakoff.good3
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/breakoff.test4
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/breakoff.wrong5
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/checkcompoundcase.aff3
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/checkcompoundcase.dic5
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/checkcompoundcase.good5
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/checkcompoundcase.test4
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/checkcompoundcase.wrong3
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/checkcompoundcase2.aff3
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/checkcompoundcase2.dic3
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/checkcompoundcase2.good2
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/checkcompoundcase2.test4
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/checkcompoundcase2.wrong1
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/checkcompoundcaseutf.aff3
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/checkcompoundcaseutf.dic3
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/checkcompoundcaseutf.good2
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/checkcompoundcaseutf.test4
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/checkcompoundcaseutf.wrong1
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/checkcompounddup.aff3
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/checkcompounddup.dic3
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/checkcompounddup.good5
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/checkcompounddup.test4
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/checkcompounddup.wrong3
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/checkcompoundpattern.aff5
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/checkcompoundpattern.dic5
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/checkcompoundpattern.good2
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/checkcompoundpattern.test4
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/checkcompoundpattern.wrong4
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/checkcompoundpattern2.aff7
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/checkcompoundpattern2.dic3
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/checkcompoundpattern2.good3
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/checkcompoundpattern2.test4
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/checkcompoundpattern2.wrong1
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/checkcompoundpattern3.aff6
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/checkcompoundpattern3.dic5
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/checkcompoundpattern3.good9
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/checkcompoundpattern3.test4
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/checkcompoundpattern3.wrong8
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/checkcompoundpattern4.aff8
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/checkcompoundpattern4.dic6
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/checkcompoundpattern4.good2
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/checkcompoundpattern4.test4
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/checkcompoundpattern4.wrong2
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/checkcompoundrep.aff8
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/checkcompoundrep.dic5
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/checkcompoundrep.good2
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/checkcompoundrep.test4
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/checkcompoundrep.wrong3
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/checkcompoundtriple.aff3
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/checkcompoundtriple.dic5
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/checkcompoundtriple.good6
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/checkcompoundtriple.test4
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/checkcompoundtriple.wrong2
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/checksharps.aff4
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/checksharps.dic7
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/checksharps.good13
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/checksharps.sug1
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/checksharps.test4
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/checksharps.wrong1
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/checksharpsutf.aff5
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/checksharpsutf.dic7
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/checksharpsutf.good13
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/checksharpsutf.sug1
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/checksharpsutf.test4
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/checksharpsutf.wrong1
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/circumfix.aff16
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/circumfix.dic2
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/circumfix.good4
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/circumfix.morph12
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/circumfix.test4
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/circumfix.wrong2
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/colons-in-words.aff3
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/colons-in-words.dic4
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/colons-in-words.test4
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/complexprefixes.aff9
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/complexprefixes.dic3
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/complexprefixes.good3
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/complexprefixes.test4
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/complexprefixes.wrong2
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/complexprefixes2.aff12
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/complexprefixes2.dic3
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/complexprefixes2.good4
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/complexprefixes2.test4
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/complexprefixesutf.aff12
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/complexprefixesutf.dic2
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/complexprefixesutf.good3
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/complexprefixesutf.test4
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/complexprefixesutf.wrong2
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/compoundaffix.aff7
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/compoundaffix.dic3
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/compoundaffix.good6
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/compoundaffix.test4
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/compoundaffix.wrong3
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/compoundaffix2.aff8
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/compoundaffix2.dic3
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/compoundaffix2.good8
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/compoundaffix2.test4
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/compoundaffix3.aff8
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/compoundaffix3.dic3
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/compoundaffix3.good5
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/compoundaffix3.test4
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/compoundaffix3.wrong6
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/compoundflag.aff3
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/compoundflag.dic5
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/compoundflag.good3
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/compoundflag.test4
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/compoundflag.wrong4
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/compoundrule.aff3
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/compoundrule.dic5
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/compoundrule.good2
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/compoundrule.test4
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/compoundrule.wrong39
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/compoundrule2.aff3
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/compoundrule2.dic5
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/compoundrule2.good37
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/compoundrule2.test4
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/compoundrule2.wrong8
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/compoundrule3.aff3
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/compoundrule3.dic5
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/compoundrule3.good7
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/compoundrule3.test4
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/compoundrule3.wrong41
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/compoundrule4.aff7
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/compoundrule4.dic24
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/compoundrule4.good29
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/compoundrule4.test6
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/compoundrule4.wrong5
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/compoundrule5.aff7
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/compoundrule5.dic14
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/compoundrule5.good7
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/compoundrule5.morph21
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/compoundrule5.test4
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/compoundrule5.wrong1
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/compoundrule6.aff4
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/compoundrule6.dic5
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/compoundrule6.good4
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/compoundrule6.test4
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/compoundrule6.wrong4
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/compoundrule7.aff8
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/compoundrule7.dic24
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/compoundrule7.good29
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/compoundrule7.test6
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/compoundrule7.wrong5
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/compoundrule8.aff8
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/compoundrule8.dic24
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/compoundrule8.good29
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/compoundrule8.test6
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/compoundrule8.wrong5
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/condition-utf.aff42
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/condition-utf.dic2
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/condition-utf.good19
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/condition-utf.test4
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/condition-utf.wrong18
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/condition.aff62
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/condition.dic6
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/condition.good26
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/condition.test4
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/condition.wrong21
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/conditionalprefix.aff11
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/conditionalprefix.dic3
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/conditionalprefix.good6
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/conditionalprefix.morph20
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/conditionalprefix.test4
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/conditionalprefix.wrong2
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/digits-in-words.aff9
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/digits-in-words.dic12
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/digits-in-words.test4
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/digits-in-words.wrong1
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/encoding.aff1
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/encoding.dic3
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/encoding.good4
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/encoding.test4
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/flag.aff13
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/flag.dic2
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/flag.good8
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/flag.test4
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/flaglong.aff14
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/flaglong.dic2
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/flaglong.good8
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/flaglong.test4
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/flagnum.aff14
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/flagnum.dic2
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/flagnum.good8
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/flagnum.test4
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/flagutf8.aff15
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/flagutf8.dic2
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/flagutf8.good8
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/flagutf8.test4
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/fogemorpheme.aff12
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/fogemorpheme.dic3
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/fogemorpheme.good3
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/fogemorpheme.test4
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/fogemorpheme.wrong3
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/forbiddenword.aff11
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/forbiddenword.dic8
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/forbiddenword.good3
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/forbiddenword.test4
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/forbiddenword.wrong4
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/forceucase.aff4
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/forceucase.dic4
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/forceucase.good7
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/forceucase.sug2
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/forceucase.test4
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/forceucase.wrong2
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/fullstrip.aff15
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/fullstrip.dic4
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/fullstrip.good9
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/fullstrip.test4
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/germancompounding.aff91
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/germancompounding.dic5
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/germancompounding.good20
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/germancompounding.test4
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/germancompounding.wrong50
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/germancompoundingold.aff96
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/germancompoundingold.dic5
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/germancompoundingold.good14
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/germancompoundingold.test4
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/germancompoundingold.wrong50
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/i35725.aff203
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/i35725.dic15
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/i35725.good1
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/i35725.sug10
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/i35725.test4
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/i35725.wrong10
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/i53643.aff2
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/i53643.dic2
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/i53643.good19
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/i53643.test4
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/i53643.wrong4
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/i54633.aff2
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/i54633.dic2
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/i54633.good2
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/i54633.sug2
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/i54633.test4
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/i54633.wrong2
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/i54980.aff2
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/i54980.dic3
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/i54980.good4
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/i54980.test4
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/i58202.aff4
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/i58202.dic5
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/i58202.good10
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/i58202.sug13
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/i58202.test4
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/i58202.wrong13
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/i68568.aff7
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/i68568.dic2
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/i68568.test4
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/i68568.wrong5
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/i68568utf.aff8
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/i68568utf.dic2
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/i68568utf.test4
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/i68568utf.wrong5
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/iconv.aff10
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/iconv.dic5
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/iconv.good6
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/iconv.test4
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/ignore.aff5
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/ignore.dic3
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/ignore.good6
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/ignore.test4
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/ignoreutf.aff6
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/ignoreutf.dic10
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/ignoreutf.good9
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/ignoreutf.test4
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/keepcase.aff3
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/keepcase.dic5
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/keepcase.good4
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/keepcase.sug8
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/keepcase.test4
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/keepcase.wrong8
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/korean.aff1
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/korean.dic3
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/korean.good2
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/korean.test4
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/korean.wrong1
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/map.aff9
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/map.dic4
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/map.sug3
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/map.test4
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/map.wrong3
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/maputf.aff11
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/maputf.dic4
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/maputf.sug3
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/maputf.test4
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/maputf.wrong3
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/morph.aff12
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/morph.dic10
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/morph.good26
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/morph.morph48
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/morph.test4
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/needaffix.aff5
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/needaffix.dic3
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/needaffix.good3
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/needaffix.test4
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/needaffix.wrong1
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/needaffix2.aff2
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/needaffix2.dic5
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/needaffix2.good5
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/needaffix2.morph13
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/needaffix2.test4
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/needaffix3.aff8
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/needaffix3.dic2
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/needaffix3.good2
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/needaffix3.test4
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/needaffix3.wrong1
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/needaffix4.aff2
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/needaffix4.dic5
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/needaffix4.good5
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/needaffix4.test4
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/needaffix5.aff13
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/needaffix5.dic2
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/needaffix5.good11
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/needaffix5.test4
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/needaffix5.wrong3
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/ngram-utf-fix.aff21
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/ngram-utf-fix.dic2
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/ngram-utf-fix.good1
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/ngram-utf-fix.sug2
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/ngram-utf-fix.test4
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/ngram-utf-fix.wrong2
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/nosuggest.aff5
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/nosuggest.dic3
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/nosuggest.good3
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/nosuggest.sug0
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/nosuggest.test4
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/nosuggest.wrong3
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/oconv.aff12
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/oconv.dic4
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/oconv.good2
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/oconv.sug3
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/oconv.test4
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/oconv.wrong3
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/onlyincompound.aff5
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/onlyincompound.dic3
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/onlyincompound.good4
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/onlyincompound.sug0
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/onlyincompound.test4
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/onlyincompound.wrong2
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/onlyincompound2.aff12
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/onlyincompound2.dic3
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/onlyincompound2.good3
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/onlyincompound2.test4
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/onlyincompound2.wrong3
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/opentaal-cpdpat.aff13
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/opentaal-cpdpat.dic4
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/opentaal-cpdpat.good1
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/opentaal-cpdpat.test4
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/opentaal-cpdpat.wrong1
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/opentaal-cpdpat2.aff27
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/opentaal-cpdpat2.dic4
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/opentaal-cpdpat2.good1
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/opentaal-cpdpat2.test4
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/opentaal-cpdpat2.wrong1
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/opentaal-forbiddenword1.aff9
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/opentaal-forbiddenword1.dic5
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/opentaal-forbiddenword1.good3
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/opentaal-forbiddenword1.sug1
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/opentaal-forbiddenword1.test4
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/opentaal-forbiddenword1.wrong5
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/opentaal-forbiddenword2.aff7
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/opentaal-forbiddenword2.dic5
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/opentaal-forbiddenword2.good4
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/opentaal-forbiddenword2.sug1
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/opentaal-forbiddenword2.test4
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/opentaal-forbiddenword2.wrong5
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/opentaal-keepcase.aff8
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/opentaal-keepcase.dic7
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/opentaal-keepcase.good4
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/opentaal-keepcase.sug8
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/opentaal-keepcase.test4
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/opentaal-keepcase.wrong8
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/phone.aff255
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/phone.dic11
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/phone.sug1
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/phone.test4
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/phone.wrong1
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/rep.aff21
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/rep.dic15
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/rep.sug8
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/rep.test4
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/rep.wrong11
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/reputf.aff9
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/reputf.dic2
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/reputf.sug1
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/reputf.test4
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/reputf.wrong1
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/simplifiedtriple.aff8
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/simplifiedtriple.dic3
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/simplifiedtriple.good3
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/simplifiedtriple.test4
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/simplifiedtriple.wrong1
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/slash.aff4
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/slash.dic5
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/slash.good4
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/slash.test4
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/sug.aff15
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/sug.dic11
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/sug.sug12
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/sug.test4
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/sug.wrong12
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/suggestiontest/List_of_common_misspellings.txt4020
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/suggestiontest/Makefile.am6
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/suggestiontest/Makefile.in435
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/suggestiontest/README16
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/suggestiontest/prepare40
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/suggestiontest/test25
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/sugutf.aff15
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/sugutf.dic11
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/sugutf.sug12
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/sugutf.test4
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/sugutf.wrong12
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/test.sh111
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/utf8-bom.aff3
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/utf8-bom.dic2
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/utf8-bom.good2
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/utf8-bom.test4
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/utf8-bom2.aff3
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/utf8-bom2.dic2
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/utf8-bom2.good2
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/utf8-bom2.test4
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/utf8-nonbmp.aff1
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/utf8-nonbmp.dic5
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/utf8-nonbmp.good5
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/utf8-nonbmp.sug2
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/utf8-nonbmp.test4
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/utf8-nonbmp.wrong2
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/utf8.aff10
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/utf8.dic3
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/utf8.good9
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/utf8.test4
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/utfcompound.aff3
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/utfcompound.dic9
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/utfcompound.good5
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/utfcompound.test4
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/utfcompound.wrong7
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/warn.aff13
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/warn.dic3
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/warn.good2
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/warn.test4
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/zeroaffix.aff12
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/zeroaffix.dic3
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/zeroaffix.good3
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/zeroaffix.morph13
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/data/zeroaffix.test4
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/test_hunspell.js250
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/test_hunspell_unicode_paths.js42
-rw-r--r--extensions/spellcheck/hunspell/tests/unit/xpcshell.ini8
-rwxr-xr-xextensions/spellcheck/hunspell/update.sh34
-rw-r--r--extensions/spellcheck/idl/moz.build12
-rw-r--r--extensions/spellcheck/idl/mozIPersonalDictionary.idl55
-rw-r--r--extensions/spellcheck/idl/mozISpellCheckingEngine.idl84
-rw-r--r--extensions/spellcheck/locales/en-US/hunspell/README_en_US.txt347
-rw-r--r--extensions/spellcheck/locales/en-US/hunspell/README_mozilla.txt2
-rw-r--r--extensions/spellcheck/locales/en-US/hunspell/dictionary-sources/5-mozilla-added.txt7041
-rw-r--r--extensions/spellcheck/locales/en-US/hunspell/dictionary-sources/5-mozilla-removed.txt3
-rw-r--r--extensions/spellcheck/locales/en-US/hunspell/dictionary-sources/5-mozilla-specific.txt42
-rw-r--r--extensions/spellcheck/locales/en-US/hunspell/dictionary-sources/README.txt2
-rwxr-xr-xextensions/spellcheck/locales/en-US/hunspell/dictionary-sources/edit-dictionary.sh95
-rwxr-xr-xextensions/spellcheck/locales/en-US/hunspell/dictionary-sources/install-new-dict.sh47
-rwxr-xr-xextensions/spellcheck/locales/en-US/hunspell/dictionary-sources/make-new-dict.sh128
-rw-r--r--extensions/spellcheck/locales/en-US/hunspell/dictionary-sources/mozilla-specific.txt21
-rw-r--r--extensions/spellcheck/locales/en-US/hunspell/dictionary-sources/orig/README_en_US-custom.txt348
-rw-r--r--extensions/spellcheck/locales/en-US/hunspell/dictionary-sources/orig/en_US-custom.aff205
-rw-r--r--extensions/spellcheck/locales/en-US/hunspell/dictionary-sources/orig/en_US-custom.dic50060
-rw-r--r--extensions/spellcheck/locales/en-US/hunspell/dictionary-sources/utf8/en-US-utf8.aff205
-rw-r--r--extensions/spellcheck/locales/en-US/hunspell/dictionary-sources/utf8/en-US-utf8.dic53554
-rw-r--r--extensions/spellcheck/locales/en-US/hunspell/en-US.aff203
-rw-r--r--extensions/spellcheck/locales/en-US/hunspell/en-US.dic53554
-rw-r--r--extensions/spellcheck/locales/moz.build10
-rw-r--r--extensions/spellcheck/moz.build19
-rw-r--r--extensions/spellcheck/src/components.conf20
-rw-r--r--extensions/spellcheck/src/moz.build30
-rw-r--r--extensions/spellcheck/src/mozEnglishWordUtils.cpp102
-rw-r--r--extensions/spellcheck/src/mozEnglishWordUtils.h40
-rw-r--r--extensions/spellcheck/src/mozInlineSpellChecker.cpp2120
-rw-r--r--extensions/spellcheck/src/mozInlineSpellChecker.h338
-rw-r--r--extensions/spellcheck/src/mozInlineSpellWordUtil.cpp1174
-rw-r--r--extensions/spellcheck/src/mozInlineSpellWordUtil.h253
-rw-r--r--extensions/spellcheck/src/mozPersonalDictionary.cpp433
-rw-r--r--extensions/spellcheck/src/mozPersonalDictionary.h80
-rw-r--r--extensions/spellcheck/src/mozSpellChecker.cpp681
-rw-r--r--extensions/spellcheck/src/mozSpellChecker.h197
-rw-r--r--extensions/spellcheck/tests/chrome/base/base_utf.aff198
-rw-r--r--extensions/spellcheck/tests/chrome/base/base_utf.dic29
-rw-r--r--extensions/spellcheck/tests/chrome/chrome.ini10
-rw-r--r--extensions/spellcheck/tests/chrome/map/maputf.aff11
-rw-r--r--extensions/spellcheck/tests/chrome/map/maputf.dic4
-rw-r--r--extensions/spellcheck/tests/chrome/test_add_remove_dictionaries.xhtml129
-rw-r--r--extensions/spellcheck/tests/mochitest/helper_bug1170484.js12
-rw-r--r--extensions/spellcheck/tests/mochitest/mochitest.ini8
-rw-r--r--extensions/spellcheck/tests/mochitest/test_bug1170484.html59
-rw-r--r--extensions/spellcheck/tests/mochitest/test_bug1272623.html83
-rw-r--r--extensions/universalchardet/moz.build10
-rw-r--r--extensions/universalchardet/tests/CharsetDetectionTests.js48
-rw-r--r--extensions/universalchardet/tests/bug1071816-1_text.html9
-rw-r--r--extensions/universalchardet/tests/bug1071816-2_text.html9
-rw-r--r--extensions/universalchardet/tests/bug1071816-3_text.html536
-rw-r--r--extensions/universalchardet/tests/bug1071816-4_text.html536
-rw-r--r--extensions/universalchardet/tests/bug306272_text.html9
-rw-r--r--extensions/universalchardet/tests/bug426271_text-euc-jp.html11
-rw-r--r--extensions/universalchardet/tests/bug426271_text-utf-8.html11
-rw-r--r--extensions/universalchardet/tests/bug431054_text.html5
-rw-r--r--extensions/universalchardet/tests/bug620106_text.html1045
-rw-r--r--extensions/universalchardet/tests/bug631751be_text.htmlbin0 -> 354 bytes
-rw-r--r--extensions/universalchardet/tests/bug631751le_text.htmlbin0 -> 366 bytes
-rw-r--r--extensions/universalchardet/tests/bug638318_text.htmlbin0 -> 1108 bytes
-rw-r--r--extensions/universalchardet/tests/bug811363-1.text1
-rw-r--r--extensions/universalchardet/tests/bug811363-2.text3
-rw-r--r--extensions/universalchardet/tests/bug811363-3.text3
-rw-r--r--extensions/universalchardet/tests/bug811363-4.text3
-rw-r--r--extensions/universalchardet/tests/bug811363-5.text3
-rw-r--r--extensions/universalchardet/tests/bug811363-6.text3
-rw-r--r--extensions/universalchardet/tests/bug811363-7.text3
-rw-r--r--extensions/universalchardet/tests/bug811363-8.text3
-rw-r--r--extensions/universalchardet/tests/bug811363-9.text2
-rw-r--r--extensions/universalchardet/tests/bug811363-invalid-1.text4
-rw-r--r--extensions/universalchardet/tests/bug811363-invalid-5.text3
-rw-r--r--extensions/universalchardet/tests/chrome.ini49
-rw-r--r--extensions/universalchardet/tests/moz.build7
-rw-r--r--extensions/universalchardet/tests/test_bug1071816-1.html31
-rw-r--r--extensions/universalchardet/tests/test_bug1071816-2.html31
-rw-r--r--extensions/universalchardet/tests/test_bug1071816-3.html31
-rw-r--r--extensions/universalchardet/tests/test_bug1071816-4.html31
-rw-r--r--extensions/universalchardet/tests/test_bug306272.html31
-rw-r--r--extensions/universalchardet/tests/test_bug426271-euc-jp.html31
-rw-r--r--extensions/universalchardet/tests/test_bug426271-utf-8.html31
-rw-r--r--extensions/universalchardet/tests/test_bug431054-japanese.html30
-rw-r--r--extensions/universalchardet/tests/test_bug431054.html34
-rw-r--r--extensions/universalchardet/tests/test_bug631751be.html31
-rw-r--r--extensions/universalchardet/tests/test_bug631751le.html31
-rw-r--r--extensions/universalchardet/tests/test_bug638318.html31
-rw-r--r--extensions/universalchardet/tests/test_bug811363-1-1.html29
-rw-r--r--extensions/universalchardet/tests/test_bug811363-1-5.html29
-rw-r--r--extensions/universalchardet/tests/test_bug811363-2-1.html29
-rw-r--r--extensions/universalchardet/tests/test_bug811363-2-2.html29
-rw-r--r--extensions/universalchardet/tests/test_bug811363-2-3.html29
-rw-r--r--extensions/universalchardet/tests/test_bug811363-2-4.html29
-rw-r--r--extensions/universalchardet/tests/test_bug811363-2-5.html29
-rw-r--r--extensions/universalchardet/tests/test_bug811363-2-6.html29
-rw-r--r--extensions/universalchardet/tests/test_bug811363-2-7.html29
-rw-r--r--extensions/universalchardet/tests/test_bug811363-2-8.html29
-rw-r--r--extensions/universalchardet/tests/test_bug811363-2-9.html29
823 files changed, 225592 insertions, 0 deletions
diff --git a/extensions/auth/gssapi.h b/extensions/auth/gssapi.h
new file mode 100644
index 0000000000..826d69df79
--- /dev/null
+++ b/extensions/auth/gssapi.h
@@ -0,0 +1,792 @@
+/* vim:set ts=4 sw=2 sts=2 et cindent: */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Copyright 1993 by OpenVision Technologies, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appears in all copies and
+ * that both that copyright notice and this permission notice appear in
+ * supporting documentation, and that the name of OpenVision not be used
+ * in advertising or publicity pertaining to distribution of the software
+ * without specific, written prior permission. OpenVision makes no
+ * representations about the suitability of this software for any
+ * purpose. It is provided "as is" without express or implied warranty.
+ *
+ * OPENVISION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL OPENVISION BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
+ * USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
+ * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ ****** END LICENSE BLOCK ***** */
+
+#ifndef GSSAPI_H_
+#define GSSAPI_H_
+
+/*
+ * Also define _GSSAPI_H_ as that is what the Kerberos 5 code defines and
+ * what header files on some systems look for.
+ */
+#define _GSSAPI_H_
+
+/*
+ * On Mac OS X, Kerberos/Kerberos.h is used to gain access to certain
+ * system-specific Kerberos functions, but on 10.4, that file also brings
+ * in other headers that conflict with this one.
+ */
+#define _GSSAPI_GENERIC_H_
+#define _GSSAPI_KRB5_H_
+
+/*
+ * Define windows specific needed parameters.
+ */
+
+#ifndef GSS_CALLCONV
+# if defined(_WIN32)
+# define GSS_CALLCONV __stdcall
+# define GSS_CALLCONV_C __cdecl
+# else
+# define GSS_CALLCONV
+# define GSS_CALLCONV_C
+# endif
+#endif /* GSS_CALLCONV */
+
+#ifdef GSS_USE_FUNCTION_POINTERS
+# ifdef _WIN32
+# undef GSS_CALLCONV
+# define GSS_CALLCONV
+# define GSS_FUNC(f) (__stdcall * f##_type)
+# else
+# define GSS_FUNC(f) (*f##_type)
+# endif
+# define GSS_MAKE_TYPEDEF typedef
+#else
+# define GSS_FUNC(f) f
+# define GSS_MAKE_TYPEDEF
+#endif
+
+/*
+ * First, include stddef.h to get size_t defined.
+ */
+#include <stddef.h>
+
+/*
+ * Configure set the following
+ */
+
+#ifndef SIZEOF_LONG
+# undef SIZEOF_LONG
+#endif
+#ifndef SIZEOF_SHORT
+# undef SIZEOF_SHORT
+#endif
+
+#ifndef EXTERN_C_BEGIN
+# ifdef __cplusplus
+# define EXTERN_C_BEGIN extern "C" {
+# define EXTERN_C_END }
+# else
+# define EXTERN_C_BEGIN
+# define EXTERN_C_END
+# endif
+#endif
+
+EXTERN_C_BEGIN
+
+#if defined(XP_MACOSX) && !defined(__aarch64__)
+# pragma pack(push, 2)
+#endif
+
+/*
+ * If the platform supports the xom.h header file, it should be
+ * included here.
+ */
+/* #include <xom.h> */
+
+/*
+ * Now define the three implementation-dependent types.
+ */
+
+typedef void* gss_name_t;
+typedef void* gss_ctx_id_t;
+typedef void* gss_cred_id_t;
+
+/*
+ * The following type must be defined as the smallest natural
+ * unsigned integer supported by the platform that has at least
+ * 32 bits of precision.
+ */
+
+#if SIZEOF_LONG == 4
+typedef unsigned long gss_uint32;
+#elif SIZEOF_SHORT == 4
+typedef unsigned short gss_uint32;
+#else
+typedef unsigned int gss_uint32;
+#endif
+
+#ifdef OM_STRING
+
+/*
+ * We have included the xom.h header file. Verify that OM_uint32
+ * is defined correctly.
+ */
+
+# if sizeof(gss_uint32) != sizeof(OM_uint32)
+# error Incompatible definition of OM_uint32 from xom.h
+# endif
+
+typedef OM_object_identifier gss_OID_desc, *gss_OID;
+
+#else /* !OM_STRING */
+
+/*
+ * We can't use X/Open definitions, so roll our own.
+ */
+typedef gss_uint32 OM_uint32;
+typedef struct gss_OID_desc_struct {
+ OM_uint32 length;
+ void* elements;
+} gss_OID_desc, *gss_OID;
+
+#endif /* !OM_STRING */
+
+typedef struct gss_OID_set_desc_struct {
+ size_t count;
+ gss_OID elements;
+} gss_OID_set_desc, *gss_OID_set;
+
+/*
+ * For now, define a QOP-type as an OM_uint32
+ */
+typedef OM_uint32 gss_qop_t;
+
+typedef int gss_cred_usage_t;
+
+typedef struct gss_buffer_desc_struct {
+ size_t length;
+ void* value;
+} gss_buffer_desc, *gss_buffer_t;
+
+typedef struct gss_channel_bindings_struct {
+ OM_uint32 initiator_addrtype;
+ gss_buffer_desc initiator_address;
+ OM_uint32 acceptor_addrtype;
+ gss_buffer_desc acceptor_address;
+ gss_buffer_desc application_data;
+}* gss_channel_bindings_t;
+
+/*
+ * Flag bits for context-level services.
+ */
+#define GSS_C_DELEG_FLAG 1
+#define GSS_C_MUTUAL_FLAG 2
+#define GSS_C_REPLAY_FLAG 4
+#define GSS_C_SEQUENCE_FLAG 8
+#define GSS_C_CONF_FLAG 16
+#define GSS_C_INTEG_FLAG 32
+#define GSS_C_ANON_FLAG 64
+#define GSS_C_PROT_READY_FLAG 128
+#define GSS_C_TRANS_FLAG 256
+
+/*
+ * Credential usage options
+ */
+#define GSS_C_BOTH 0
+#define GSS_C_INITIATE 1
+#define GSS_C_ACCEPT 2
+
+/*
+ * Status code types for gss_display_status
+ */
+#define GSS_C_GSS_CODE 1
+#define GSS_C_MECH_CODE 2
+
+/*
+ * The constant definitions for channel-bindings address families
+ */
+#define GSS_C_AF_UNSPEC 0
+#define GSS_C_AF_LOCAL 1
+#define GSS_C_AF_INET 2
+#define GSS_C_AF_IMPLINK 3
+#define GSS_C_AF_PUP 4
+#define GSS_C_AF_CHAOS 5
+#define GSS_C_AF_NS 6
+#define GSS_C_AF_NBS 7
+#define GSS_C_AF_ECMA 8
+#define GSS_C_AF_DATAKIT 9
+#define GSS_C_AF_CCITT 10
+#define GSS_C_AF_SNA 11
+#define GSS_C_AF_DECnet 12
+#define GSS_C_AF_DLI 13
+#define GSS_C_AF_LAT 14
+#define GSS_C_AF_HYLINK 15
+#define GSS_C_AF_APPLETALK 16
+#define GSS_C_AF_BSC 17
+#define GSS_C_AF_DSS 18
+#define GSS_C_AF_OSI 19
+#define GSS_C_AF_X25 21
+
+#define GSS_C_AF_NULLADDR 255
+
+/*
+ * Various Null values
+ */
+#define GSS_C_NO_NAME ((gss_name_t)0)
+#define GSS_C_NO_BUFFER ((gss_buffer_t)0)
+#define GSS_C_NO_OID ((gss_OID)0)
+#define GSS_C_NO_OID_SET ((gss_OID_set)0)
+#define GSS_C_NO_CONTEXT ((gss_ctx_id_t)0)
+#define GSS_C_NO_CREDENTIAL ((gss_cred_id_t)0)
+#define GSS_C_NO_CHANNEL_BINDINGS ((gss_channel_bindings_t)0)
+#define GSS_C_EMPTY_BUFFER \
+ { 0, nullptr }
+
+/*
+ * Some alternate names for a couple of the above
+ * values. These are defined for V1 compatibility.
+ */
+#define GSS_C_NULL_OID GSS_C_NO_OID
+#define GSS_C_NULL_OID_SET GSS_C_NO_OID_SET
+
+/*
+ * Define the default Quality of Protection for per-message
+ * services. Note that an implementation that offers multiple
+ * levels of QOP may define GSS_C_QOP_DEFAULT to be either zero
+ * (as done here) to mean "default protection", or to a specific
+ * explicit QOP value. However, a value of 0 should always be
+ * interpreted by a GSSAPI implementation as a request for the
+ * default protection level.
+ */
+#define GSS_C_QOP_DEFAULT 0
+
+/*
+ * Expiration time of 2^32-1 seconds means infinite lifetime for a
+ * credential or security context
+ */
+#define GSS_C_INDEFINITE 0xfffffffful
+
+/*
+ * The implementation must reserve static storage for a
+ * gss_OID_desc object containing the value
+ * {10, (void *)"\x2a\x86\x48\x86\xf7\x12"
+ * "\x01\x02\x01\x01"},
+ * corresponding to an object-identifier value of
+ * {iso(1) member-body(2) United States(840) mit(113554)
+ * infosys(1) gssapi(2) generic(1) user_name(1)}. The constant
+ * GSS_C_NT_USER_NAME should be initialized to point
+ * to that gss_OID_desc.
+ */
+extern gss_OID GSS_C_NT_USER_NAME;
+
+/*
+ * The implementation must reserve static storage for a
+ * gss_OID_desc object containing the value
+ * {10, (void *)"\x2a\x86\x48\x86\xf7\x12"
+ * "\x01\x02\x01\x02"},
+ * corresponding to an object-identifier value of
+ * {iso(1) member-body(2) United States(840) mit(113554)
+ * infosys(1) gssapi(2) generic(1) machine_uid_name(2)}.
+ * The constant GSS_C_NT_MACHINE_UID_NAME should be
+ * initialized to point to that gss_OID_desc.
+ */
+extern gss_OID GSS_C_NT_MACHINE_UID_NAME;
+
+/*
+ * The implementation must reserve static storage for a
+ * gss_OID_desc object containing the value
+ * {10, (void *)"\x2a\x86\x48\x86\xf7\x12"
+ * "\x01\x02\x01\x03"},
+ * corresponding to an object-identifier value of
+ * {iso(1) member-body(2) United States(840) mit(113554)
+ * infosys(1) gssapi(2) generic(1) string_uid_name(3)}.
+ * The constant GSS_C_NT_STRING_UID_NAME should be
+ * initialized to point to that gss_OID_desc.
+ */
+extern gss_OID GSS_C_NT_STRING_UID_NAME;
+
+/*
+ * The implementation must reserve static storage for a
+ * gss_OID_desc object containing the value
+ * {6, (void *)"\x2b\x06\x01\x05\x06\x02"},
+ * corresponding to an object-identifier value of
+ * {iso(1) org(3) dod(6) internet(1) security(5)
+ * nametypes(6) gss-host-based-services(2)). The constant
+ * GSS_C_NT_HOSTBASED_SERVICE_X should be initialized to point
+ * to that gss_OID_desc. This is a deprecated OID value, and
+ * implementations wishing to support hostbased-service names
+ * should instead use the GSS_C_NT_HOSTBASED_SERVICE OID,
+ * defined below, to identify such names;
+ * GSS_C_NT_HOSTBASED_SERVICE_X should be accepted a synonym
+ * for GSS_C_NT_HOSTBASED_SERVICE when presented as an input
+ * parameter, but should not be emitted by GSSAPI
+ * implementations
+ */
+extern gss_OID GSS_C_NT_HOSTBASED_SERVICE_X;
+
+/*
+ * The implementation must reserve static storage for a
+ * gss_OID_desc object containing the value
+ * {10, (void *)"\x2a\x86\x48\x86\xf7\x12"
+ * "\x01\x02\x01\x04"}, corresponding to an
+ * object-identifier value of {iso(1) member-body(2)
+ * Unites States(840) mit(113554) infosys(1) gssapi(2)
+ * generic(1) service_name(4)}. The constant
+ * GSS_C_NT_HOSTBASED_SERVICE should be initialized
+ * to point to that gss_OID_desc.
+ */
+extern gss_OID GSS_C_NT_HOSTBASED_SERVICE;
+
+/*
+ * The implementation must reserve static storage for a
+ * gss_OID_desc object containing the value
+ * {6, (void *)"\x2b\x06\01\x05\x06\x03"},
+ * corresponding to an object identifier value of
+ * {1(iso), 3(org), 6(dod), 1(internet), 5(security),
+ * 6(nametypes), 3(gss-anonymous-name)}. The constant
+ * and GSS_C_NT_ANONYMOUS should be initialized to point
+ * to that gss_OID_desc.
+ */
+extern gss_OID GSS_C_NT_ANONYMOUS;
+
+/*
+ * The implementation must reserve static storage for a
+ * gss_OID_desc object containing the value
+ * {6, (void *)"\x2b\x06\x01\x05\x06\x04"},
+ * corresponding to an object-identifier value of
+ * {1(iso), 3(org), 6(dod), 1(internet), 5(security),
+ * 6(nametypes), 4(gss-api-exported-name)}. The constant
+ * GSS_C_NT_EXPORT_NAME should be initialized to point
+ * to that gss_OID_desc.
+ */
+extern gss_OID GSS_C_NT_EXPORT_NAME;
+
+/* Major status codes */
+
+#define GSS_S_COMPLETE 0
+
+/*
+ * Some "helper" definitions to make the status code macros obvious.
+ */
+#define GSS_C_CALLING_ERROR_OFFSET 24
+#define GSS_C_ROUTINE_ERROR_OFFSET 16
+#define GSS_C_SUPPLEMENTARY_OFFSET 0
+#define GSS_C_CALLING_ERROR_MASK 0377ul
+#define GSS_C_ROUTINE_ERROR_MASK 0377ul
+#define GSS_C_SUPPLEMENTARY_MASK 0177777ul
+
+/*
+ * The macros that test status codes for error conditions.
+ * Note that the GSS_ERROR() macro has changed slightly from
+ * the V1 GSSAPI so that it now evaluates its argument
+ * only once.
+ */
+#define GSS_CALLING_ERROR(x) \
+ (x & (GSS_C_CALLING_ERROR_MASK << GSS_C_CALLING_ERROR_OFFSET))
+#define GSS_ROUTINE_ERROR(x) \
+ (x & (GSS_C_ROUTINE_ERROR_MASK << GSS_C_ROUTINE_ERROR_OFFSET))
+#define GSS_SUPPLEMENTARY_INFO(x) \
+ (x & (GSS_C_SUPPLEMENTARY_MASK << GSS_C_SUPPLEMENTARY_OFFSET))
+#define GSS_ERROR(x) \
+ (x & ((GSS_C_CALLING_ERROR_MASK << GSS_C_CALLING_ERROR_OFFSET) | \
+ (GSS_C_ROUTINE_ERROR_MASK << GSS_C_ROUTINE_ERROR_OFFSET)))
+
+/*
+ * Now the actual status code definitions
+ */
+
+/*
+ * Calling errors:
+ */
+#define GSS_S_CALL_INACCESSIBLE_READ (1ul << GSS_C_CALLING_ERROR_OFFSET)
+#define GSS_S_CALL_INACCESSIBLE_WRITE (2ul << GSS_C_CALLING_ERROR_OFFSET)
+#define GSS_S_CALL_BAD_STRUCTURE (3ul << GSS_C_CALLING_ERROR_OFFSET)
+
+/*
+ * Routine errors:
+ */
+#define GSS_S_BAD_MECH (1ul << GSS_C_ROUTINE_ERROR_OFFSET)
+#define GSS_S_BAD_NAME (2ul << GSS_C_ROUTINE_ERROR_OFFSET)
+#define GSS_S_BAD_NAMETYPE (3ul << GSS_C_ROUTINE_ERROR_OFFSET)
+#define GSS_S_BAD_BINDINGS (4ul << GSS_C_ROUTINE_ERROR_OFFSET)
+#define GSS_S_BAD_STATUS (5ul << GSS_C_ROUTINE_ERROR_OFFSET)
+#define GSS_S_BAD_SIG (6ul << GSS_C_ROUTINE_ERROR_OFFSET)
+#define GSS_S_BAD_MIC GSS_S_BAD_SIG
+#define GSS_S_NO_CRED (7ul << GSS_C_ROUTINE_ERROR_OFFSET)
+#define GSS_S_NO_CONTEXT (8ul << GSS_C_ROUTINE_ERROR_OFFSET)
+#define GSS_S_DEFECTIVE_TOKEN (9ul << GSS_C_ROUTINE_ERROR_OFFSET)
+#define GSS_S_DEFECTIVE_CREDENTIAL (10ul << GSS_C_ROUTINE_ERROR_OFFSET)
+#define GSS_S_CREDENTIALS_EXPIRED (11ul << GSS_C_ROUTINE_ERROR_OFFSET)
+#define GSS_S_CONTEXT_EXPIRED (12ul << GSS_C_ROUTINE_ERROR_OFFSET)
+#define GSS_S_FAILURE (13ul << GSS_C_ROUTINE_ERROR_OFFSET)
+#define GSS_S_BAD_QOP (14ul << GSS_C_ROUTINE_ERROR_OFFSET)
+#define GSS_S_UNAUTHORIZED (15ul << GSS_C_ROUTINE_ERROR_OFFSET)
+#define GSS_S_UNAVAILABLE (16ul << GSS_C_ROUTINE_ERROR_OFFSET)
+#define GSS_S_DUPLICATE_ELEMENT (17ul << GSS_C_ROUTINE_ERROR_OFFSET)
+#define GSS_S_NAME_NOT_MN (18ul << GSS_C_ROUTINE_ERROR_OFFSET)
+
+/*
+ * Supplementary info bits:
+ */
+#define GSS_S_CONTINUE_NEEDED (1ul << (GSS_C_SUPPLEMENTARY_OFFSET + 0))
+#define GSS_S_DUPLICATE_TOKEN (1ul << (GSS_C_SUPPLEMENTARY_OFFSET + 1))
+#define GSS_S_OLD_TOKEN (1ul << (GSS_C_SUPPLEMENTARY_OFFSET + 2))
+#define GSS_S_UNSEQ_TOKEN (1ul << (GSS_C_SUPPLEMENTARY_OFFSET + 3))
+#define GSS_S_GAP_TOKEN (1ul << (GSS_C_SUPPLEMENTARY_OFFSET + 4))
+
+/*
+ * Finally, function prototypes for the GSS-API routines.
+ */
+
+GSS_MAKE_TYPEDEF
+OM_uint32 GSS_CALLCONV GSS_FUNC(gss_acquire_cred)(
+ OM_uint32*, /* minor_status */
+ const gss_name_t, /* desired_name */
+ OM_uint32, /* time_req */
+ const gss_OID_set, /* desired_mechs */
+ gss_cred_usage_t, /* cred_usage */
+ gss_cred_id_t*, /* output_cred_handle */
+ gss_OID_set*, /* actual_mechs */
+ OM_uint32* /* time_rec */
+);
+
+GSS_MAKE_TYPEDEF
+OM_uint32 GSS_CALLCONV GSS_FUNC(gss_release_cred)(
+ OM_uint32*, /* minor_status */
+ gss_cred_id_t* /* cred_handle */
+);
+
+GSS_MAKE_TYPEDEF
+OM_uint32 GSS_CALLCONV GSS_FUNC(gss_init_sec_context)(
+ OM_uint32*, /* minor_status */
+ const gss_cred_id_t, /* initiator_cred_handle */
+ gss_ctx_id_t*, /* context_handle */
+ const gss_name_t, /* target_name */
+ const gss_OID, /* mech_type */
+ OM_uint32, /* req_flags */
+ OM_uint32, /* time_req */
+ const gss_channel_bindings_t, /* input_chan_bindings */
+ const gss_buffer_t, /* input_token */
+ gss_OID*, /* actual_mech_type */
+ gss_buffer_t, /* output_token */
+ OM_uint32*, /* ret_flags */
+ OM_uint32* /* time_rec */
+);
+
+GSS_MAKE_TYPEDEF
+OM_uint32 GSS_CALLCONV GSS_FUNC(gss_accept_sec_context)(
+ OM_uint32*, /* minor_status */
+ gss_ctx_id_t*, /* context_handle */
+ const gss_cred_id_t, /* acceptor_cred_handle */
+ const gss_buffer_t, /* input_token_buffer */
+ const gss_channel_bindings_t, /* input_chan_bindings */
+ gss_name_t*, /* src_name */
+ gss_OID*, /* mech_type */
+ gss_buffer_t, /* output_token */
+ OM_uint32*, /* ret_flags */
+ OM_uint32*, /* time_rec */
+ gss_cred_id_t* /* delegated_cred_handle */
+);
+
+GSS_MAKE_TYPEDEF
+OM_uint32 GSS_CALLCONV GSS_FUNC(gss_process_context_token)(
+ OM_uint32*, /* minor_status */
+ const gss_ctx_id_t, /* context_handle */
+ const gss_buffer_t /* token_buffer */
+);
+
+GSS_MAKE_TYPEDEF
+OM_uint32 GSS_CALLCONV GSS_FUNC(gss_delete_sec_context)(
+ OM_uint32*, /* minor_status */
+ gss_ctx_id_t*, /* context_handle */
+ gss_buffer_t /* output_token */
+);
+
+GSS_MAKE_TYPEDEF
+OM_uint32 GSS_CALLCONV GSS_FUNC(gss_context_time)(
+ OM_uint32*, /* minor_status */
+ const gss_ctx_id_t, /* context_handle */
+ OM_uint32* /* time_rec */
+);
+
+GSS_MAKE_TYPEDEF
+OM_uint32 GSS_CALLCONV GSS_FUNC(gss_get_mic)(
+ OM_uint32*, /* minor_status */
+ const gss_ctx_id_t, /* context_handle */
+ gss_qop_t, /* qop_req */
+ const gss_buffer_t, /* message_buffer */
+ gss_buffer_t /* message_token */
+);
+
+GSS_MAKE_TYPEDEF
+OM_uint32 GSS_CALLCONV GSS_FUNC(gss_verify_mic)(
+ OM_uint32*, /* minor_status */
+ const gss_ctx_id_t, /* context_handle */
+ const gss_buffer_t, /* message_buffer */
+ const gss_buffer_t, /* token_buffer */
+ gss_qop_t* /* qop_state */
+);
+
+GSS_MAKE_TYPEDEF
+OM_uint32 GSS_CALLCONV GSS_FUNC(gss_wrap)(
+ OM_uint32*, /* minor_status */
+ const gss_ctx_id_t, /* context_handle */
+ int, /* conf_req_flag */
+ gss_qop_t, /* qop_req */
+ const gss_buffer_t, /* input_message_buffer */
+ int*, /* conf_state */
+ gss_buffer_t /* output_message_buffer */
+);
+
+GSS_MAKE_TYPEDEF
+OM_uint32 GSS_CALLCONV GSS_FUNC(gss_unwrap)(
+ OM_uint32*, /* minor_status */
+ const gss_ctx_id_t, /* context_handle */
+ const gss_buffer_t, /* input_message_buffer */
+ gss_buffer_t, /* output_message_buffer */
+ int*, /* conf_state */
+ gss_qop_t* /* qop_state */
+);
+
+GSS_MAKE_TYPEDEF
+OM_uint32 GSS_CALLCONV GSS_FUNC(gss_display_status)(
+ OM_uint32*, /* minor_status */
+ OM_uint32, /* status_value */
+ int, /* status_type */
+ const gss_OID, /* mech_type */
+ OM_uint32*, /* message_context */
+ gss_buffer_t /* status_string */
+);
+
+GSS_MAKE_TYPEDEF
+OM_uint32 GSS_CALLCONV GSS_FUNC(gss_indicate_mechs)(
+ OM_uint32*, /* minor_status */
+ gss_OID_set* /* mech_set */
+);
+
+GSS_MAKE_TYPEDEF
+OM_uint32 GSS_CALLCONV GSS_FUNC(gss_compare_name)(OM_uint32*, /* minor_status */
+ const gss_name_t, /* name1 */
+ const gss_name_t, /* name2 */
+ int* /* name_equal */
+);
+
+GSS_MAKE_TYPEDEF
+OM_uint32 GSS_CALLCONV GSS_FUNC(gss_display_name)(
+ OM_uint32*, /* minor_status */
+ const gss_name_t, /* input_name */
+ gss_buffer_t, /* output_name_buffer */
+ gss_OID* /* output_name_type */
+);
+
+GSS_MAKE_TYPEDEF
+OM_uint32 GSS_CALLCONV GSS_FUNC(gss_import_name)(
+ OM_uint32*, /* minor_status */
+ const gss_buffer_t, /* input_name_buffer */
+ const gss_OID, /* input_name_type */
+ gss_name_t* /* output_name */
+);
+
+GSS_MAKE_TYPEDEF
+OM_uint32 GSS_CALLCONV GSS_FUNC(gss_export_name)(
+ OM_uint32*, /* minor_status */
+ const gss_name_t, /* input_name */
+ gss_buffer_t /* exported_name */
+);
+
+GSS_MAKE_TYPEDEF
+OM_uint32 GSS_CALLCONV GSS_FUNC(gss_release_name)(OM_uint32*, /* minor_status */
+ gss_name_t* /* input_name */
+);
+
+GSS_MAKE_TYPEDEF
+OM_uint32 GSS_CALLCONV GSS_FUNC(gss_release_buffer)(
+ OM_uint32*, /* minor_status */
+ gss_buffer_t /* buffer */
+);
+
+GSS_MAKE_TYPEDEF
+OM_uint32 GSS_CALLCONV GSS_FUNC(gss_release_oid_set)(
+ OM_uint32*, /* minor_status */
+ gss_OID_set* /* set */
+);
+
+GSS_MAKE_TYPEDEF
+OM_uint32 GSS_CALLCONV GSS_FUNC(gss_inquire_cred)(
+ OM_uint32*, /* minor_status */
+ const gss_cred_id_t, /* cred_handle */
+ gss_name_t*, /* name */
+ OM_uint32*, /* lifetime */
+ gss_cred_usage_t*, /* cred_usage */
+ gss_OID_set* /* mechanisms */
+);
+
+GSS_MAKE_TYPEDEF
+OM_uint32 GSS_CALLCONV GSS_FUNC(gss_inquire_context)(
+ OM_uint32*, /* minor_status */
+ const gss_ctx_id_t, /* context_handle */
+ gss_name_t*, /* src_name */
+ gss_name_t*, /* targ_name */
+ OM_uint32*, /* lifetime_rec */
+ gss_OID*, /* mech_type */
+ OM_uint32*, /* ctx_flags */
+ int*, /* locally_initiated */
+ int* /* open */
+);
+
+GSS_MAKE_TYPEDEF
+OM_uint32 GSS_CALLCONV GSS_FUNC(gss_wrap_size_limit)(
+ OM_uint32*, /* minor_status */
+ const gss_ctx_id_t, /* context_handle */
+ int, /* conf_req_flag */
+ gss_qop_t, /* qop_req */
+ OM_uint32, /* req_output_size */
+ OM_uint32* /* max_input_size */
+);
+
+GSS_MAKE_TYPEDEF
+OM_uint32 GSS_CALLCONV GSS_FUNC(gss_add_cred)(
+ OM_uint32*, /* minor_status */
+ const gss_cred_id_t, /* input_cred_handle */
+ const gss_name_t, /* desired_name */
+ const gss_OID, /* desired_mech */
+ gss_cred_usage_t, /* cred_usage */
+ OM_uint32, /* initiator_time_req */
+ OM_uint32, /* acceptor_time_req */
+ gss_cred_id_t*, /* output_cred_handle */
+ gss_OID_set*, /* actual_mechs */
+ OM_uint32*, /* initiator_time_rec */
+ OM_uint32* /* acceptor_time_rec */
+);
+
+GSS_MAKE_TYPEDEF
+OM_uint32 GSS_CALLCONV GSS_FUNC(gss_inquire_cred_by_mech)(
+ OM_uint32*, /* minor_status */
+ const gss_cred_id_t, /* cred_handle */
+ const gss_OID, /* mech_type */
+ gss_name_t*, /* name */
+ OM_uint32*, /* initiator_lifetime */
+ OM_uint32*, /* acceptor_lifetime */
+ gss_cred_usage_t* /* cred_usage */
+);
+
+GSS_MAKE_TYPEDEF
+OM_uint32 GSS_CALLCONV GSS_FUNC(gss_export_sec_context)(
+ OM_uint32*, /* minor_status */
+ gss_ctx_id_t*, /* context_handle */
+ gss_buffer_t /* interprocess_token */
+);
+
+GSS_MAKE_TYPEDEF
+OM_uint32 GSS_CALLCONV GSS_FUNC(gss_import_sec_context)(
+ OM_uint32*, /* minor_status */
+ const gss_buffer_t, /* interprocess_token */
+ gss_ctx_id_t* /* context_handle */
+);
+
+GSS_MAKE_TYPEDEF
+OM_uint32 GSS_CALLCONV GSS_FUNC(gss_create_empty_oid_set)(
+ OM_uint32*, /* minor_status */
+ gss_OID_set* /* oid_set */
+);
+
+GSS_MAKE_TYPEDEF
+OM_uint32 GSS_CALLCONV GSS_FUNC(gss_add_oid_set_member)(
+ OM_uint32*, /* minor_status */
+ const gss_OID, /* member_oid */
+ gss_OID_set* /* oid_set */
+);
+
+GSS_MAKE_TYPEDEF
+OM_uint32 GSS_CALLCONV GSS_FUNC(gss_test_oid_set_member)(
+ OM_uint32*, /* minor_status */
+ const gss_OID, /* member */
+ const gss_OID_set, /* set */
+ int* /* present */
+);
+
+GSS_MAKE_TYPEDEF
+OM_uint32 GSS_CALLCONV GSS_FUNC(gss_inquire_names_for_mech)(
+ OM_uint32*, /* minor_status */
+ const gss_OID, /* mechanism */
+ gss_OID_set* /* name_types */
+);
+
+GSS_MAKE_TYPEDEF
+OM_uint32 GSS_CALLCONV GSS_FUNC(gss_inquire_mechs_for_name)(
+ OM_uint32*, /* minor_status */
+ const gss_name_t, /* input_name */
+ gss_OID_set* /* mech_types */
+);
+
+GSS_MAKE_TYPEDEF
+OM_uint32 GSS_CALLCONV GSS_FUNC(gss_canonicalize_name)(
+ OM_uint32*, /* minor_status */
+ const gss_name_t, /* input_name */
+ const gss_OID, /* mech_type */
+ gss_name_t* /* output_name */
+);
+
+GSS_MAKE_TYPEDEF
+OM_uint32 GSS_CALLCONV GSS_FUNC(gss_duplicate_name)(
+ OM_uint32*, /* minor_status */
+ const gss_name_t, /* src_name */
+ gss_name_t* /* dest_name */
+);
+
+/*
+ * The following routines are obsolete variants of gss_get_mic,
+ * gss_verify_mic, gss_wrap and gss_unwrap. They should be
+ * provided by GSSAPI V2 implementations for backwards
+ * compatibility with V1 applications. Distinct entrypoints
+ * (as opposed to #defines) should be provided, both to allow
+ * GSSAPI V1 applications to link against GSSAPI V2 implementations,
+ * and to retain the slight parameter type differences between the
+ * obsolete versions of these routines and their current forms.
+ */
+
+GSS_MAKE_TYPEDEF
+OM_uint32 GSS_CALLCONV GSS_FUNC(gss_sign)(OM_uint32*, /* minor_status */
+ gss_ctx_id_t, /* context_handle */
+ int, /* qop_req */
+ gss_buffer_t, /* message_buffer */
+ gss_buffer_t /* message_token */
+);
+
+GSS_MAKE_TYPEDEF
+OM_uint32 GSS_CALLCONV GSS_FUNC(gss_verify)(OM_uint32*, /* minor_status */
+ gss_ctx_id_t, /* context_handle */
+ gss_buffer_t, /* message_buffer */
+ gss_buffer_t, /* token_buffer */
+ int* /* qop_state */
+);
+
+GSS_MAKE_TYPEDEF
+OM_uint32 GSS_CALLCONV GSS_FUNC(gss_seal)(
+ OM_uint32*, /* minor_status */
+ gss_ctx_id_t, /* context_handle */
+ int, /* conf_req_flag */
+ int, /* qop_req */
+ gss_buffer_t, /* input_message_buffer */
+ int*, /* conf_state */
+ gss_buffer_t /* output_message_buffer */
+);
+
+GSS_MAKE_TYPEDEF
+OM_uint32 GSS_CALLCONV GSS_FUNC(gss_unseal)(
+ OM_uint32*, /* minor_status */
+ gss_ctx_id_t, /* context_handle */
+ gss_buffer_t, /* input_message_buffer */
+ gss_buffer_t, /* output_message_buffer */
+ int*, /* conf_state */
+ int* /* qop_state */
+);
+
+#if defined(XP_MACOSX) && !defined(__aarch64__)
+# pragma pack(pop)
+#endif
+
+EXTERN_C_END
+
+#endif /* GSSAPI_H_ */
diff --git a/extensions/auth/moz.build b/extensions/auth/moz.build
new file mode 100644
index 0000000000..ac2a23fcf0
--- /dev/null
+++ b/extensions/auth/moz.build
@@ -0,0 +1,39 @@
+# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
+# vim: set filetype=python:
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+UNIFIED_SOURCES += [
+ "nsAuthGSSAPI.cpp",
+]
+
+SOURCES += [
+ "nsAuthSASL.cpp",
+ "nsHttpNegotiateAuth.cpp", # contains constants whose names conflict with constants in other files
+ "nsIAuthModule.cpp", # includes windows.h recursively which conflicts with TimeStamp.h
+]
+
+if CONFIG["OS_ARCH"] == "WINNT":
+ SOURCES += [
+ "nsAuthSSPI.cpp",
+ ]
+ DEFINES["USE_SSPI"] = True
+else:
+ UNIFIED_SOURCES += [
+ "nsAuthSambaNTLM.cpp",
+ ]
+
+LOCAL_INCLUDES += [
+ "/netwerk/dns", # For nsDNSService2.h
+ "/security/manager/ssl",
+]
+
+FINAL_LIBRARY = "xul"
+
+with Files("**"):
+ BUG_COMPONENT = ("Core", "Networking")
+
+include("/tools/fuzzing/libfuzzer-config.mozbuild")
+
+include("/ipc/chromium/chromium-config.mozbuild")
diff --git a/extensions/auth/nsAuth.h b/extensions/auth/nsAuth.h
new file mode 100644
index 0000000000..254b33000b
--- /dev/null
+++ b/extensions/auth/nsAuth.h
@@ -0,0 +1,23 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef nsAuth_h__
+#define nsAuth_h__
+
+/* types of packages */
+enum pType { PACKAGE_TYPE_KERBEROS, PACKAGE_TYPE_NEGOTIATE, PACKAGE_TYPE_NTLM };
+
+#include "mozilla/Logging.h"
+
+//
+// in order to do logging, the following environment variables need to be set:
+//
+// set NSPR_LOG_MODULES=negotiateauth:4
+// set NSPR_LOG_FILE=negotiateauth.log
+//
+extern mozilla::LazyLogModule gNegotiateLog;
+
+#define LOG(args) MOZ_LOG(gNegotiateLog, mozilla::LogLevel::Debug, args)
+
+#endif /* !defined( nsAuth_h__ ) */
diff --git a/extensions/auth/nsAuthGSSAPI.cpp b/extensions/auth/nsAuthGSSAPI.cpp
new file mode 100644
index 0000000000..fc3c1592f4
--- /dev/null
+++ b/extensions/auth/nsAuthGSSAPI.cpp
@@ -0,0 +1,533 @@
+/* vim:set ts=4 sw=2 sts=2 et cindent: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+//
+// GSSAPI Authentication Support Module
+//
+// Described by IETF Internet draft: draft-brezak-kerberos-http-00.txt
+// (formerly draft-brezak-spnego-http-04.txt)
+//
+// Also described here:
+// http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnsecure/html/http-sso-1.asp
+//
+//
+
+#include "mozilla/ArrayUtils.h"
+#include "mozilla/IntegerPrintfMacros.h"
+
+#include "nsCOMPtr.h"
+#include "nsNativeCharsetUtils.h"
+#include "mozilla/Preferences.h"
+#include "mozilla/SharedLibrary.h"
+#include "mozilla/Telemetry.h"
+
+#include "nsAuthGSSAPI.h"
+
+#ifdef XP_MACOSX
+# include <Kerberos/Kerberos.h>
+#endif
+
+#ifdef XP_MACOSX
+typedef KLStatus (*KLCacheHasValidTickets_type)(KLPrincipal, KLKerberosVersion,
+ KLBoolean*, KLPrincipal*,
+ char**);
+#endif
+
+#if defined(HAVE_RES_NINIT)
+# include <sys/types.h>
+# include <netinet/in.h>
+# include <arpa/nameser.h>
+# include <resolv.h>
+#endif
+
+using namespace mozilla;
+
+//-----------------------------------------------------------------------------
+
+// We define GSS_C_NT_HOSTBASED_SERVICE explicitly since it may be referenced
+// by by a different name depending on the implementation of gss but always
+// has the same value
+
+static gss_OID_desc gss_c_nt_hostbased_service = {
+ 10, (void*)"\x2a\x86\x48\x86\xf7\x12\x01\x02\x01\x04"};
+
+static const char kNegotiateAuthGssLib[] = "network.negotiate-auth.gsslib";
+static const char kNegotiateAuthNativeImp[] =
+ "network.negotiate-auth.using-native-gsslib";
+
+static struct GSSFunction {
+ const char* str;
+ PRFuncPtr func;
+} gssFuncs[] = {{"gss_display_status", nullptr},
+ {"gss_init_sec_context", nullptr},
+ {"gss_indicate_mechs", nullptr},
+ {"gss_release_oid_set", nullptr},
+ {"gss_delete_sec_context", nullptr},
+ {"gss_import_name", nullptr},
+ {"gss_release_buffer", nullptr},
+ {"gss_release_name", nullptr},
+ {"gss_wrap", nullptr},
+ {"gss_unwrap", nullptr}};
+
+static bool gssNativeImp = true;
+static PRLibrary* gssLibrary = nullptr;
+
+#define gss_display_status_ptr ((gss_display_status_type)*gssFuncs[0].func)
+#define gss_init_sec_context_ptr ((gss_init_sec_context_type)*gssFuncs[1].func)
+#define gss_indicate_mechs_ptr ((gss_indicate_mechs_type)*gssFuncs[2].func)
+#define gss_release_oid_set_ptr ((gss_release_oid_set_type)*gssFuncs[3].func)
+#define gss_delete_sec_context_ptr \
+ ((gss_delete_sec_context_type)*gssFuncs[4].func)
+#define gss_import_name_ptr ((gss_import_name_type)*gssFuncs[5].func)
+#define gss_release_buffer_ptr ((gss_release_buffer_type)*gssFuncs[6].func)
+#define gss_release_name_ptr ((gss_release_name_type)*gssFuncs[7].func)
+#define gss_wrap_ptr ((gss_wrap_type)*gssFuncs[8].func)
+#define gss_unwrap_ptr ((gss_unwrap_type)*gssFuncs[9].func)
+
+#ifdef XP_MACOSX
+static PRFuncPtr KLCacheHasValidTicketsPtr;
+# define KLCacheHasValidTickets_ptr \
+ ((KLCacheHasValidTickets_type)*KLCacheHasValidTicketsPtr)
+#endif
+
+static nsresult gssInit() {
+#ifdef XP_WIN
+ nsAutoString libPathU;
+ Preferences::GetString(kNegotiateAuthGssLib, libPathU);
+ NS_ConvertUTF16toUTF8 libPath(libPathU);
+#else
+ nsAutoCString libPath;
+ Preferences::GetCString(kNegotiateAuthGssLib, libPath);
+#endif
+ gssNativeImp = Preferences::GetBool(kNegotiateAuthNativeImp);
+
+ PRLibrary* lib = nullptr;
+
+ if (!libPath.IsEmpty()) {
+ LOG(("Attempting to load user specified library [%s]\n", libPath.get()));
+ gssNativeImp = false;
+#ifdef XP_WIN
+ lib = LoadLibraryWithFlags(libPathU.get());
+#else
+ lib = LoadLibraryWithFlags(libPath.get());
+#endif
+ } else {
+#ifdef XP_WIN
+# ifdef _WIN64
+ constexpr auto kLibName = u"gssapi64.dll"_ns;
+# else
+ constexpr auto kLibName = u"gssapi32.dll"_ns;
+# endif
+
+ lib = LoadLibraryWithFlags(kLibName.get());
+#elif defined(__OpenBSD__)
+ /* OpenBSD doesn't register inter-library dependencies in basesystem
+ * libs therefor we need to load all the libraries gssapi depends on,
+ * in the correct order and with LD_GLOBAL for GSSAPI auth to work
+ * fine.
+ */
+
+ const char* const verLibNames[] = {
+ "libasn1.so", "libcrypto.so", "libroken.so", "libheimbase.so",
+ "libcom_err.so", "libkrb5.so", "libgssapi.so"};
+
+ PRLibSpec libSpec;
+ for (size_t i = 0; i < ArrayLength(verLibNames); ++i) {
+ libSpec.type = PR_LibSpec_Pathname;
+ libSpec.value.pathname = verLibNames[i];
+ lib = PR_LoadLibraryWithFlags(libSpec, PR_LD_GLOBAL);
+ }
+
+#else
+
+ const char* const libNames[] = {"gss", "gssapi_krb5", "gssapi"};
+
+ const char* const verLibNames[] = {
+ "libgssapi_krb5.so.2", /* MIT - FC, Suse10, Debian */
+ "libgssapi.so.4", /* Heimdal - Suse10, MDK */
+ "libgssapi.so.1" /* Heimdal - Suse9, CITI - FC, MDK, Suse10*/
+ };
+
+ for (size_t i = 0; i < ArrayLength(verLibNames) && !lib; ++i) {
+ lib = PR_LoadLibrary(verLibNames[i]);
+
+ /* The CITI libgssapi library calls exit() during
+ * initialization if it's not correctly configured. Try to
+ * ensure that we never use this library for our GSSAPI
+ * support, as its just a wrapper library, anyway.
+ * See Bugzilla #325433
+ */
+ if (lib && PR_FindFunctionSymbol(lib, "internal_krb5_gss_initialize") &&
+ PR_FindFunctionSymbol(lib, "gssd_pname_to_uid")) {
+ LOG(("CITI libgssapi found, which calls exit(). Skipping\n"));
+ PR_UnloadLibrary(lib);
+ lib = nullptr;
+ }
+ }
+
+ for (size_t i = 0; i < ArrayLength(libNames) && !lib; ++i) {
+ char* libName = PR_GetLibraryName(nullptr, libNames[i]);
+ if (libName) {
+ lib = PR_LoadLibrary(libName);
+ PR_FreeLibraryName(libName);
+
+ if (lib && PR_FindFunctionSymbol(lib, "internal_krb5_gss_initialize") &&
+ PR_FindFunctionSymbol(lib, "gssd_pname_to_uid")) {
+ LOG(("CITI libgssapi found, which calls exit(). Skipping\n"));
+ PR_UnloadLibrary(lib);
+ lib = nullptr;
+ }
+ }
+ }
+#endif
+ }
+
+ if (!lib) {
+ LOG(("Fail to load gssapi library\n"));
+ return NS_ERROR_FAILURE;
+ }
+
+ LOG(("Attempting to load gss functions\n"));
+
+ for (auto& gssFunc : gssFuncs) {
+ gssFunc.func = PR_FindFunctionSymbol(lib, gssFunc.str);
+ if (!gssFunc.func) {
+ LOG(("Fail to load %s function from gssapi library\n", gssFunc.str));
+ PR_UnloadLibrary(lib);
+ return NS_ERROR_FAILURE;
+ }
+ }
+#ifdef XP_MACOSX
+ if (gssNativeImp && !(KLCacheHasValidTicketsPtr = PR_FindFunctionSymbol(
+ lib, "KLCacheHasValidTickets"))) {
+ LOG(("Fail to load KLCacheHasValidTickets function from gssapi library\n"));
+ PR_UnloadLibrary(lib);
+ return NS_ERROR_FAILURE;
+ }
+#endif
+
+ gssLibrary = lib;
+ return NS_OK;
+}
+
+// Generate proper GSSAPI error messages from the major and
+// minor status codes.
+void LogGssError(OM_uint32 maj_stat, OM_uint32 min_stat, const char* prefix) {
+ if (!MOZ_LOG_TEST(gNegotiateLog, LogLevel::Debug)) {
+ return;
+ }
+
+ OM_uint32 new_stat;
+ OM_uint32 msg_ctx = 0;
+ gss_buffer_desc status1_string;
+ gss_buffer_desc status2_string;
+ OM_uint32 ret;
+ nsAutoCString errorStr;
+ errorStr.Assign(prefix);
+
+ if (!gssLibrary) return;
+
+ errorStr += ": ";
+ do {
+ ret = gss_display_status_ptr(&new_stat, maj_stat, GSS_C_GSS_CODE,
+ GSS_C_NULL_OID, &msg_ctx, &status1_string);
+ errorStr.Append((const char*)status1_string.value, status1_string.length);
+ gss_release_buffer_ptr(&new_stat, &status1_string);
+
+ errorStr += '\n';
+ ret = gss_display_status_ptr(&new_stat, min_stat, GSS_C_MECH_CODE,
+ GSS_C_NULL_OID, &msg_ctx, &status2_string);
+ errorStr.Append((const char*)status2_string.value, status2_string.length);
+ errorStr += '\n';
+ } while (!GSS_ERROR(ret) && msg_ctx != 0);
+
+ LOG(("%s\n", errorStr.get()));
+}
+
+//-----------------------------------------------------------------------------
+
+nsAuthGSSAPI::nsAuthGSSAPI(pType package) : mServiceFlags(REQ_DEFAULT) {
+ OM_uint32 minstat;
+ OM_uint32 majstat;
+ gss_OID_set mech_set;
+ gss_OID item;
+
+ unsigned int i;
+ static gss_OID_desc gss_krb5_mech_oid_desc = {
+ 9, (void*)"\x2a\x86\x48\x86\xf7\x12\x01\x02\x02"};
+ static gss_OID_desc gss_spnego_mech_oid_desc = {
+ 6, (void*)"\x2b\x06\x01\x05\x05\x02"};
+
+ LOG(("entering nsAuthGSSAPI::nsAuthGSSAPI()\n"));
+
+ mComplete = false;
+
+ if (!gssLibrary && NS_FAILED(gssInit())) return;
+
+ mCtx = GSS_C_NO_CONTEXT;
+ mMechOID = &gss_krb5_mech_oid_desc;
+
+ // if the type is kerberos we accept it as default
+ // and exit
+
+ if (package == PACKAGE_TYPE_KERBEROS) return;
+
+ // Now, look at the list of supported mechanisms,
+ // if SPNEGO is found, then use it.
+ // Otherwise, set the desired mechanism to
+ // GSS_C_NO_OID and let the system try to use
+ // the default mechanism.
+ //
+ // Using Kerberos directly (instead of negotiating
+ // with SPNEGO) may work in some cases depending
+ // on how smart the server side is.
+
+ majstat = gss_indicate_mechs_ptr(&minstat, &mech_set);
+ if (GSS_ERROR(majstat)) return;
+
+ if (mech_set) {
+ for (i = 0; i < mech_set->count; i++) {
+ item = &mech_set->elements[i];
+ if (item->length == gss_spnego_mech_oid_desc.length &&
+ !memcmp(item->elements, gss_spnego_mech_oid_desc.elements,
+ item->length)) {
+ // ok, we found it
+ mMechOID = &gss_spnego_mech_oid_desc;
+ break;
+ }
+ }
+ gss_release_oid_set_ptr(&minstat, &mech_set);
+ }
+}
+
+void nsAuthGSSAPI::Reset() {
+ if (gssLibrary && mCtx != GSS_C_NO_CONTEXT) {
+ OM_uint32 minor_status;
+ gss_delete_sec_context_ptr(&minor_status, &mCtx, GSS_C_NO_BUFFER);
+ }
+ mCtx = GSS_C_NO_CONTEXT;
+ mComplete = false;
+}
+
+/* static */
+void nsAuthGSSAPI::Shutdown() {
+ if (gssLibrary) {
+ PR_UnloadLibrary(gssLibrary);
+ gssLibrary = nullptr;
+ }
+}
+
+/* Limitations apply to this class's thread safety. See the header file */
+NS_IMPL_ISUPPORTS(nsAuthGSSAPI, nsIAuthModule)
+
+NS_IMETHODIMP
+nsAuthGSSAPI::Init(const nsACString& serviceName, uint32_t serviceFlags,
+ const nsAString& domain, const nsAString& username,
+ const nsAString& password) {
+ // we don't expect to be passed any user credentials
+ NS_ASSERTION(domain.IsEmpty() && username.IsEmpty() && password.IsEmpty(),
+ "unexpected credentials");
+
+ // it's critial that the caller supply a service name to be used
+ NS_ENSURE_TRUE(!serviceName.IsEmpty(), NS_ERROR_INVALID_ARG);
+
+ LOG(("entering nsAuthGSSAPI::Init()\n"));
+
+ if (!gssLibrary) return NS_ERROR_NOT_INITIALIZED;
+
+ mServiceName = serviceName;
+ mServiceFlags = serviceFlags;
+
+ static bool sTelemetrySent = false;
+ if (!sTelemetrySent) {
+ mozilla::Telemetry::Accumulate(mozilla::Telemetry::NTLM_MODULE_USED_2,
+ serviceFlags & nsIAuthModule::REQ_PROXY_AUTH
+ ? NTLM_MODULE_KERBEROS_PROXY
+ : NTLM_MODULE_KERBEROS_DIRECT);
+ sTelemetrySent = true;
+ }
+
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsAuthGSSAPI::GetNextToken(const void* inToken, uint32_t inTokenLen,
+ void** outToken, uint32_t* outTokenLen) {
+ OM_uint32 major_status, minor_status;
+ OM_uint32 req_flags = 0;
+ gss_buffer_desc input_token = GSS_C_EMPTY_BUFFER;
+ gss_buffer_desc output_token = GSS_C_EMPTY_BUFFER;
+ gss_buffer_t in_token_ptr = GSS_C_NO_BUFFER;
+ gss_name_t server;
+ nsAutoCString userbuf;
+ nsresult rv;
+
+ LOG(("entering nsAuthGSSAPI::GetNextToken()\n"));
+
+ if (!gssLibrary) return NS_ERROR_NOT_INITIALIZED;
+
+ // If they've called us again after we're complete, reset to start afresh.
+ if (mComplete) Reset();
+
+ if (mServiceFlags & REQ_DELEGATE) req_flags |= GSS_C_DELEG_FLAG;
+
+ if (mServiceFlags & REQ_MUTUAL_AUTH) req_flags |= GSS_C_MUTUAL_FLAG;
+
+ input_token.value = (void*)mServiceName.get();
+ input_token.length = mServiceName.Length() + 1;
+
+#if defined(HAVE_RES_NINIT)
+ res_ninit(&_res);
+#endif
+ major_status = gss_import_name_ptr(&minor_status, &input_token,
+ &gss_c_nt_hostbased_service, &server);
+ input_token.value = nullptr;
+ input_token.length = 0;
+ if (GSS_ERROR(major_status)) {
+ LogGssError(major_status, minor_status, "gss_import_name() failed");
+ return NS_ERROR_FAILURE;
+ }
+
+ if (inToken) {
+ input_token.length = inTokenLen;
+ input_token.value = (void*)inToken;
+ in_token_ptr = &input_token;
+ } else if (mCtx != GSS_C_NO_CONTEXT) {
+ // If there is no input token, then we are starting a new
+ // authentication sequence. If we have already initialized our
+ // security context, then we're in trouble because it means that the
+ // first sequence failed. We need to bail or else we might end up in
+ // an infinite loop.
+ LOG(("Cannot restart authentication sequence!"));
+ return NS_ERROR_UNEXPECTED;
+ }
+
+#if defined(XP_MACOSX)
+ // Suppress Kerberos prompts to get credentials. See bug 240643.
+ // We can only use Mac OS X specific kerb functions if we are using
+ // the native lib
+ KLBoolean found;
+ bool doingMailTask = mServiceName.Find("imap@") ||
+ mServiceName.Find("pop@") ||
+ mServiceName.Find("smtp@") || mServiceName.Find("ldap@");
+
+ if (!doingMailTask &&
+ (gssNativeImp &&
+ (KLCacheHasValidTickets_ptr(nullptr, kerberosVersion_V5, &found, nullptr,
+ nullptr) != klNoErr ||
+ !found))) {
+ major_status = GSS_S_FAILURE;
+ minor_status = 0;
+ } else
+#endif /* XP_MACOSX */
+ major_status = gss_init_sec_context_ptr(
+ &minor_status, GSS_C_NO_CREDENTIAL, &mCtx, server, mMechOID, req_flags,
+ GSS_C_INDEFINITE, GSS_C_NO_CHANNEL_BINDINGS, in_token_ptr, nullptr,
+ &output_token, nullptr, nullptr);
+
+ if (GSS_ERROR(major_status)) {
+ LogGssError(major_status, minor_status, "gss_init_sec_context() failed");
+ Reset();
+ rv = NS_ERROR_FAILURE;
+ goto end;
+ }
+ if (major_status == GSS_S_COMPLETE) {
+ // Mark ourselves as being complete, so that if we're called again
+ // we know to start afresh.
+ mComplete = true;
+ } else if (major_status == GSS_S_CONTINUE_NEEDED) {
+ //
+ // The important thing is that we do NOT reset the
+ // context here because it will be needed on the
+ // next call.
+ //
+ }
+
+ *outTokenLen = output_token.length;
+ if (output_token.length != 0) {
+ *outToken = moz_xmemdup(output_token.value, output_token.length);
+ } else {
+ *outToken = nullptr;
+ }
+
+ gss_release_buffer_ptr(&minor_status, &output_token);
+
+ if (major_status == GSS_S_COMPLETE) {
+ rv = NS_SUCCESS_AUTH_FINISHED;
+ } else {
+ rv = NS_OK;
+ }
+
+end:
+ gss_release_name_ptr(&minor_status, &server);
+
+ LOG((" leaving nsAuthGSSAPI::GetNextToken [rv=%" PRIx32 "]",
+ static_cast<uint32_t>(rv)));
+ return rv;
+}
+
+NS_IMETHODIMP
+nsAuthGSSAPI::Unwrap(const void* inToken, uint32_t inTokenLen, void** outToken,
+ uint32_t* outTokenLen) {
+ OM_uint32 major_status, minor_status;
+
+ gss_buffer_desc input_token;
+ gss_buffer_desc output_token = GSS_C_EMPTY_BUFFER;
+
+ input_token.value = (void*)inToken;
+ input_token.length = inTokenLen;
+
+ major_status = gss_unwrap_ptr(&minor_status, mCtx, &input_token,
+ &output_token, nullptr, nullptr);
+ if (GSS_ERROR(major_status)) {
+ LogGssError(major_status, minor_status, "gss_unwrap() failed");
+ Reset();
+ gss_release_buffer_ptr(&minor_status, &output_token);
+ return NS_ERROR_FAILURE;
+ }
+
+ *outTokenLen = output_token.length;
+
+ if (output_token.length) {
+ *outToken = moz_xmemdup(output_token.value, output_token.length);
+ } else {
+ *outToken = nullptr;
+ }
+
+ gss_release_buffer_ptr(&minor_status, &output_token);
+
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsAuthGSSAPI::Wrap(const void* inToken, uint32_t inTokenLen, bool confidential,
+ void** outToken, uint32_t* outTokenLen) {
+ OM_uint32 major_status, minor_status;
+
+ gss_buffer_desc input_token;
+ gss_buffer_desc output_token = GSS_C_EMPTY_BUFFER;
+
+ input_token.value = (void*)inToken;
+ input_token.length = inTokenLen;
+
+ major_status =
+ gss_wrap_ptr(&minor_status, mCtx, confidential, GSS_C_QOP_DEFAULT,
+ &input_token, nullptr, &output_token);
+
+ if (GSS_ERROR(major_status)) {
+ LogGssError(major_status, minor_status, "gss_wrap() failed");
+ Reset();
+ gss_release_buffer_ptr(&minor_status, &output_token);
+ return NS_ERROR_FAILURE;
+ }
+
+ *outTokenLen = output_token.length;
+
+ /* it is not possible for output_token.length to be zero */
+ *outToken = moz_xmemdup(output_token.value, output_token.length);
+ gss_release_buffer_ptr(&minor_status, &output_token);
+
+ return NS_OK;
+}
diff --git a/extensions/auth/nsAuthGSSAPI.h b/extensions/auth/nsAuthGSSAPI.h
new file mode 100644
index 0000000000..c25c75b294
--- /dev/null
+++ b/extensions/auth/nsAuthGSSAPI.h
@@ -0,0 +1,62 @@
+/* vim:set ts=4 sw=2 et cindent: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef nsAuthGSSAPI_h__
+#define nsAuthGSSAPI_h__
+
+#include "nsAuth.h"
+#include "nsIAuthModule.h"
+#include "nsString.h"
+#include "mozilla/Attributes.h"
+
+#define GSS_USE_FUNCTION_POINTERS 1
+
+#include "gssapi.h"
+
+// The nsAuthGSSAPI class provides responses for the GSS-API Negotiate method
+// as specified by Microsoft in draft-brezak-spnego-http-04.txt
+
+/* Some remarks on thread safety ...
+ *
+ * The thread safety of this class depends largely upon the thread safety of
+ * the underlying GSSAPI and Kerberos libraries. This code just loads the
+ * system GSSAPI library, and whilst it avoids loading known bad libraries,
+ * it cannot determine the thread safety of the the code it loads.
+ *
+ * When used with a non-threadsafe library, it is not safe to simultaneously
+ * use multiple instantiations of this class.
+ *
+ * When used with a threadsafe Kerberos library, multiple instantiations of
+ * this class may happily co-exist. Methods may be sequentially called from
+ * multiple threads. The nature of the GSSAPI protocol is such that a correct
+ * implementation will never call methods in parallel, as the results of the
+ * last call are required as input to the next.
+ */
+
+class nsAuthGSSAPI final : public nsIAuthModule {
+ public:
+ NS_DECL_THREADSAFE_ISUPPORTS
+ NS_DECL_NSIAUTHMODULE
+
+ explicit nsAuthGSSAPI(pType package);
+
+ static void Shutdown();
+
+ private:
+ ~nsAuthGSSAPI() { Reset(); }
+
+ void Reset();
+ gss_OID GetOID() { return mMechOID; }
+
+ private:
+ gss_ctx_id_t mCtx;
+ gss_OID mMechOID;
+ nsCString mServiceName;
+ uint32_t mServiceFlags;
+ nsString mUsername;
+ bool mComplete;
+};
+
+#endif /* nsAuthGSSAPI_h__ */
diff --git a/extensions/auth/nsAuthSASL.cpp b/extensions/auth/nsAuthSASL.cpp
new file mode 100644
index 0000000000..9fcb2859a7
--- /dev/null
+++ b/extensions/auth/nsAuthSASL.cpp
@@ -0,0 +1,123 @@
+/* vim:set ts=4 sw=2 et cindent: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "nsNativeCharsetUtils.h"
+#include "nsIPrefService.h"
+#include "nsServiceManagerUtils.h"
+
+#include "nsAuthSASL.h"
+
+static const char kNegotiateAuthSSPI[] = "network.auth.use-sspi";
+
+nsAuthSASL::nsAuthSASL() { mSASLReady = false; }
+
+void nsAuthSASL::Reset() { mSASLReady = false; }
+
+/* Limitations apply to this class's thread safety. See the header file */
+NS_IMPL_ISUPPORTS(nsAuthSASL, nsIAuthModule)
+
+NS_IMETHODIMP
+nsAuthSASL::Init(const nsACString& serviceName, uint32_t serviceFlags,
+ const nsAString& domain, const nsAString& username,
+ const nsAString& password) {
+ nsresult rv;
+
+ NS_ASSERTION(!username.IsEmpty(), "SASL requires a username");
+ NS_ASSERTION(domain.IsEmpty() && password.IsEmpty(),
+ "unexpected credentials");
+
+ mUsername = username;
+
+ // If we're doing SASL, we should do mutual auth
+ serviceFlags |= REQ_MUTUAL_AUTH;
+
+ // Find out whether we should be trying SSPI or not
+ const char* authType = "kerb-gss";
+
+ nsCOMPtr<nsIPrefBranch> prefs = do_GetService(NS_PREFSERVICE_CONTRACTID);
+ if (prefs) {
+ bool val;
+ rv = prefs->GetBoolPref(kNegotiateAuthSSPI, &val);
+ if (NS_SUCCEEDED(rv) && val) authType = "kerb-sspi";
+ }
+
+ MOZ_ALWAYS_TRUE(mInnerModule = nsIAuthModule::CreateInstance(authType));
+
+ mInnerModule->Init(serviceName, serviceFlags, u""_ns, u""_ns, u""_ns);
+
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsAuthSASL::GetNextToken(const void* inToken, uint32_t inTokenLen,
+ void** outToken, uint32_t* outTokenLen) {
+ nsresult rv;
+ void* unwrappedToken;
+ char* message;
+ uint32_t unwrappedTokenLen, messageLen;
+ nsAutoCString userbuf;
+
+ if (!mInnerModule) return NS_ERROR_NOT_INITIALIZED;
+
+ if (mSASLReady) {
+ // If the server COMPLETEs with an empty token, Cyrus sends us that token.
+ // I don't think this is correct, but we need to handle that behaviour.
+ // Cyrus ignores the contents of our reply token.
+ if (inTokenLen == 0) {
+ *outToken = nullptr;
+ *outTokenLen = 0;
+ return NS_OK;
+ }
+ // We've completed the GSSAPI portion of the handshake, and are
+ // now ready to do the SASL security layer and authzid negotiation
+
+ // Input packet from the server needs to be unwrapped.
+ rv = mInnerModule->Unwrap(inToken, inTokenLen, &unwrappedToken,
+ &unwrappedTokenLen);
+ if (NS_FAILED(rv)) {
+ Reset();
+ return rv;
+ }
+
+ // If we were doing security layers then we'd care what the
+ // server had sent us. We're not, so all we had to do was make
+ // sure that the signature was correct with the above unwrap()
+ free(unwrappedToken);
+
+ NS_CopyUnicodeToNative(mUsername, userbuf);
+ messageLen = userbuf.Length() + 4 + 1;
+ message = (char*)moz_xmalloc(messageLen);
+ message[0] = 0x01; // No security layer
+ message[1] = 0x00;
+ message[2] = 0x00;
+ message[3] = 0x00; // Maxbuf must be zero if we've got no sec layer
+ strcpy(message + 4, userbuf.get());
+ // Userbuf should not be nullptr terminated, so trim the trailing nullptr
+ // when wrapping the message
+ rv = mInnerModule->Wrap((void*)message, messageLen - 1, false, outToken,
+ outTokenLen);
+ free(message);
+ Reset(); // All done
+ return NS_SUCCEEDED(rv) ? NS_SUCCESS_AUTH_FINISHED : rv;
+ }
+ rv = mInnerModule->GetNextToken(inToken, inTokenLen, outToken, outTokenLen);
+ if (rv == NS_SUCCESS_AUTH_FINISHED) {
+ mSASLReady = true;
+ rv = NS_OK;
+ }
+ return rv;
+}
+
+NS_IMETHODIMP
+nsAuthSASL::Unwrap(const void* inToken, uint32_t inTokenLen, void** outToken,
+ uint32_t* outTokenLen) {
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+NS_IMETHODIMP
+nsAuthSASL::Wrap(const void* inToken, uint32_t inTokenLen, bool confidential,
+ void** outToken, uint32_t* outTokenLen) {
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
diff --git a/extensions/auth/nsAuthSASL.h b/extensions/auth/nsAuthSASL.h
new file mode 100644
index 0000000000..f829fd0d17
--- /dev/null
+++ b/extensions/auth/nsAuthSASL.h
@@ -0,0 +1,35 @@
+/* vim:set ts=4 sw=2 et cindent: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef nsAuthSASL_h__
+#define nsAuthSASL_h__
+
+#include "nsIAuthModule.h"
+#include "nsString.h"
+#include "nsCOMPtr.h"
+
+/* This class is implemented using the nsAuthGSSAPI class, and the same
+ * thread safety constraints which are documented in nsAuthGSSAPI.h
+ * apply to this class
+ */
+
+class nsAuthSASL final : public nsIAuthModule {
+ public:
+ NS_DECL_THREADSAFE_ISUPPORTS
+ NS_DECL_NSIAUTHMODULE
+
+ nsAuthSASL();
+
+ private:
+ ~nsAuthSASL() { Reset(); }
+
+ void Reset();
+
+ nsCOMPtr<nsIAuthModule> mInnerModule;
+ nsString mUsername;
+ bool mSASLReady;
+};
+
+#endif /* nsAuthSASL_h__ */
diff --git a/extensions/auth/nsAuthSSPI.cpp b/extensions/auth/nsAuthSSPI.cpp
new file mode 100644
index 0000000000..ce3ecebdcd
--- /dev/null
+++ b/extensions/auth/nsAuthSSPI.cpp
@@ -0,0 +1,574 @@
+/* vim:set ts=4 sw=2 sts=2 et cindent: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+//
+// Negotiate Authentication Support Module
+//
+// Described by IETF Internet draft: draft-brezak-kerberos-http-00.txt
+// (formerly draft-brezak-spnego-http-04.txt)
+//
+// Also described here:
+// http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnsecure/html/http-sso-1.asp
+//
+
+#include "nsAuthSSPI.h"
+#include "nsComponentManagerUtils.h"
+#include "nsDNSService2.h"
+#include "nsIDNSService.h"
+#include "nsIDNSRecord.h"
+#include "nsNetCID.h"
+#include "nsServiceManagerUtils.h"
+#include "nsCOMPtr.h"
+#include "nsICryptoHash.h"
+#include "mozilla/Telemetry.h"
+
+#include <windows.h>
+
+#define SEC_SUCCESS(Status) ((Status) >= 0)
+
+#ifndef KERB_WRAP_NO_ENCRYPT
+# define KERB_WRAP_NO_ENCRYPT 0x80000001
+#endif
+
+#ifndef SECBUFFER_PADDING
+# define SECBUFFER_PADDING 9
+#endif
+
+#ifndef SECBUFFER_STREAM
+# define SECBUFFER_STREAM 10
+#endif
+
+//-----------------------------------------------------------------------------
+
+static const wchar_t* const pTypeName[] = {L"Kerberos", L"Negotiate", L"NTLM"};
+
+#ifdef DEBUG
+# define CASE_(_x) \
+ case _x: \
+ return #_x;
+static const char* MapErrorCode(int rc) {
+ switch (rc) {
+ CASE_(SEC_E_OK)
+ CASE_(SEC_I_CONTINUE_NEEDED)
+ CASE_(SEC_I_COMPLETE_NEEDED)
+ CASE_(SEC_I_COMPLETE_AND_CONTINUE)
+ CASE_(SEC_E_INCOMPLETE_MESSAGE)
+ CASE_(SEC_I_INCOMPLETE_CREDENTIALS)
+ CASE_(SEC_E_INVALID_HANDLE)
+ CASE_(SEC_E_TARGET_UNKNOWN)
+ CASE_(SEC_E_LOGON_DENIED)
+ CASE_(SEC_E_INTERNAL_ERROR)
+ CASE_(SEC_E_NO_CREDENTIALS)
+ CASE_(SEC_E_NO_AUTHENTICATING_AUTHORITY)
+ CASE_(SEC_E_INSUFFICIENT_MEMORY)
+ CASE_(SEC_E_INVALID_TOKEN)
+ }
+ return "<unknown>";
+}
+#else
+# define MapErrorCode(_rc) ""
+#endif
+
+//-----------------------------------------------------------------------------
+
+static PSecurityFunctionTableW sspi;
+
+static nsresult InitSSPI() {
+ LOG((" InitSSPI\n"));
+
+ sspi = InitSecurityInterfaceW();
+ if (!sspi) {
+ LOG(("InitSecurityInterfaceW failed"));
+ return NS_ERROR_UNEXPECTED;
+ }
+
+ return NS_OK;
+}
+
+//-----------------------------------------------------------------------------
+
+nsresult nsAuthSSPI::MakeSN(const nsACString& principal, nsCString& result) {
+ nsresult rv;
+
+ nsAutoCString buf(principal);
+
+ // The service name looks like "protocol@hostname", we need to map
+ // this to a value that SSPI expects. To be consistent with IE, we
+ // need to map '@' to '/' and canonicalize the hostname.
+ int32_t index = buf.FindChar('@');
+ if (index == kNotFound) return NS_ERROR_UNEXPECTED;
+
+ nsCOMPtr<nsIDNSService> dnsService =
+ do_GetService(NS_DNSSERVICE_CONTRACTID, &rv);
+ if (NS_FAILED(rv)) return rv;
+
+ auto dns = static_cast<nsDNSService*>(dnsService.get());
+
+ // This could be expensive if our DNS cache cannot satisfy the request.
+ // However, we should have at least hit the OS resolver once prior to
+ // reaching this code, so provided the OS resolver has this information
+ // cached, we should not have to worry about blocking on this function call
+ // for very long. NOTE: because we ask for the canonical hostname, we
+ // might end up requiring extra network activity in cases where the OS
+ // resolver might not have enough information to satisfy the request from
+ // its cache. This is not an issue in versions of Windows up to WinXP.
+ nsCOMPtr<nsIDNSRecord> record;
+ mozilla::OriginAttributes attrs;
+ rv = dns->DeprecatedSyncResolve(Substring(buf, index + 1),
+ nsIDNSService::RESOLVE_CANONICAL_NAME, attrs,
+ getter_AddRefs(record));
+ if (NS_FAILED(rv)) return rv;
+ nsCOMPtr<nsIDNSAddrRecord> rec = do_QueryInterface(record);
+ if (!rec) {
+ return NS_ERROR_UNEXPECTED;
+ }
+
+ nsAutoCString cname;
+ rv = rec->GetCanonicalName(cname);
+ if (NS_SUCCEEDED(rv)) {
+ result = StringHead(buf, index) + "/"_ns + cname;
+ LOG(("Using SPN of [%s]\n", result.get()));
+ }
+ return rv;
+}
+
+//-----------------------------------------------------------------------------
+
+nsAuthSSPI::nsAuthSSPI(pType package)
+ : mServiceFlags(REQ_DEFAULT),
+ mMaxTokenLen(0),
+ mPackage(package),
+ mCertDERData(nullptr),
+ mCertDERLength(0) {
+ memset(&mCred, 0, sizeof(mCred));
+ memset(&mCtxt, 0, sizeof(mCtxt));
+}
+
+nsAuthSSPI::~nsAuthSSPI() {
+ Reset();
+
+ if (mCred.dwLower || mCred.dwUpper) {
+ (sspi->FreeCredentialsHandle)(&mCred);
+ memset(&mCred, 0, sizeof(mCred));
+ }
+}
+
+void nsAuthSSPI::Reset() {
+ mIsFirst = true;
+
+ if (mCertDERData) {
+ free(mCertDERData);
+ mCertDERData = nullptr;
+ mCertDERLength = 0;
+ }
+
+ if (mCtxt.dwLower || mCtxt.dwUpper) {
+ (sspi->DeleteSecurityContext)(&mCtxt);
+ memset(&mCtxt, 0, sizeof(mCtxt));
+ }
+}
+
+NS_IMPL_ISUPPORTS(nsAuthSSPI, nsIAuthModule)
+
+NS_IMETHODIMP
+nsAuthSSPI::Init(const nsACString& aServiceName, uint32_t aServiceFlags,
+ const nsAString& aDomain, const nsAString& aUsername,
+ const nsAString& aPassword) {
+ LOG((" nsAuthSSPI::Init\n"));
+
+ mIsFirst = true;
+ mCertDERLength = 0;
+ mCertDERData = nullptr;
+
+ // The caller must supply a service name to be used. (For why we now require
+ // a service name for NTLM, see bug 487872.)
+ NS_ENSURE_TRUE(!aServiceName.IsEmpty(), NS_ERROR_INVALID_ARG);
+
+ nsresult rv;
+
+ // XXX lazy initialization like this assumes that we are single threaded
+ if (!sspi) {
+ rv = InitSSPI();
+ if (NS_FAILED(rv)) return rv;
+ }
+ SEC_WCHAR* package;
+
+ package = (SEC_WCHAR*)pTypeName[(int)mPackage];
+
+ if (mPackage == PACKAGE_TYPE_NTLM) {
+ // (bug 535193) For NTLM, just use the uri host, do not do canonical host
+ // lookups. The incoming serviceName is in the format: "protocol@hostname",
+ // SSPI expects
+ // "<service class>/<hostname>", so swap the '@' for a '/'.
+ mServiceName = aServiceName;
+ int32_t index = mServiceName.FindChar('@');
+ if (index == kNotFound) return NS_ERROR_UNEXPECTED;
+ mServiceName.Replace(index, 1, '/');
+ } else {
+ // Kerberos requires the canonical host, MakeSN takes care of this through a
+ // DNS lookup.
+ rv = MakeSN(aServiceName, mServiceName);
+ if (NS_FAILED(rv)) return rv;
+ }
+
+ mServiceFlags = aServiceFlags;
+
+ SECURITY_STATUS rc;
+
+ PSecPkgInfoW pinfo;
+ rc = (sspi->QuerySecurityPackageInfoW)(package, &pinfo);
+ if (rc != SEC_E_OK) {
+ LOG(("%S package not found\n", package));
+ return NS_ERROR_UNEXPECTED;
+ }
+ mMaxTokenLen = pinfo->cbMaxToken;
+ (sspi->FreeContextBuffer)(pinfo);
+
+ MS_TimeStamp useBefore;
+
+ SEC_WINNT_AUTH_IDENTITY_W ai;
+ SEC_WINNT_AUTH_IDENTITY_W* pai = nullptr;
+
+ // domain, username, and password will be null if nsHttpNTLMAuth's
+ // ChallengeReceived returns false for identityInvalid. Use default
+ // credentials in this case by passing null for pai.
+ if (!aUsername.IsEmpty() && !aPassword.IsEmpty()) {
+ // Keep a copy of these strings for the duration
+ mUsername = aUsername;
+ mPassword = aPassword;
+ mDomain = aDomain;
+ ai.Domain = reinterpret_cast<unsigned short*>(mDomain.BeginWriting());
+ ai.DomainLength = mDomain.Length();
+ ai.User = reinterpret_cast<unsigned short*>(mUsername.BeginWriting());
+ ai.UserLength = mUsername.Length();
+ ai.Password = reinterpret_cast<unsigned short*>(mPassword.BeginWriting());
+ ai.PasswordLength = mPassword.Length();
+ ai.Flags = SEC_WINNT_AUTH_IDENTITY_UNICODE;
+ pai = &ai;
+ }
+
+ rc = (sspi->AcquireCredentialsHandleW)(nullptr, package, SECPKG_CRED_OUTBOUND,
+ nullptr, pai, nullptr, nullptr, &mCred,
+ &useBefore);
+ if (rc != SEC_E_OK) return NS_ERROR_UNEXPECTED;
+
+ static bool sTelemetrySent = false;
+ if (!sTelemetrySent) {
+ mozilla::Telemetry::Accumulate(mozilla::Telemetry::NTLM_MODULE_USED_2,
+ aServiceFlags & nsIAuthModule::REQ_PROXY_AUTH
+ ? NTLM_MODULE_WIN_API_PROXY
+ : NTLM_MODULE_WIN_API_DIRECT);
+ sTelemetrySent = true;
+ }
+
+ LOG(("AcquireCredentialsHandle() succeeded.\n"));
+ return NS_OK;
+}
+
+// The arguments inToken and inTokenLen are used to pass in the server
+// certificate (when available) in the first call of the function. The
+// second time these arguments hold an input token.
+NS_IMETHODIMP
+nsAuthSSPI::GetNextToken(const void* inToken, uint32_t inTokenLen,
+ void** outToken, uint32_t* outTokenLen) {
+ // String for end-point bindings.
+ const char end_point[] = "tls-server-end-point:";
+ const int end_point_length = sizeof(end_point) - 1;
+ const int hash_size = 32; // Size of a SHA256 hash.
+ const int cbt_size = hash_size + end_point_length;
+
+ SECURITY_STATUS rc;
+ MS_TimeStamp ignored;
+
+ DWORD ctxAttr, ctxReq = 0;
+ CtxtHandle* ctxIn;
+ SecBufferDesc ibd, obd;
+ // Optional second input buffer for the CBT (Channel Binding Token)
+ SecBuffer ib[2], ob;
+ // Pointer to the block of memory that stores the CBT
+ char* sspi_cbt = nullptr;
+ SEC_CHANNEL_BINDINGS pendpoint_binding;
+
+ LOG(("entering nsAuthSSPI::GetNextToken()\n"));
+
+ if (!mCred.dwLower && !mCred.dwUpper) {
+ LOG(("nsAuthSSPI::GetNextToken(), not initialized. exiting."));
+ return NS_ERROR_NOT_INITIALIZED;
+ }
+
+ if (mServiceFlags & REQ_DELEGATE) ctxReq |= ISC_REQ_DELEGATE;
+ if (mServiceFlags & REQ_MUTUAL_AUTH) ctxReq |= ISC_REQ_MUTUAL_AUTH;
+
+ if (inToken) {
+ if (mIsFirst) {
+ // First time if it comes with a token,
+ // the token represents the server certificate.
+ mIsFirst = false;
+ mCertDERLength = inTokenLen;
+ mCertDERData = moz_xmalloc(inTokenLen);
+ memcpy(mCertDERData, inToken, inTokenLen);
+
+ // We are starting a new authentication sequence.
+ // If we have already initialized our
+ // security context, then we're in trouble because it means that the
+ // first sequence failed. We need to bail or else we might end up in
+ // an infinite loop.
+ if (mCtxt.dwLower || mCtxt.dwUpper) {
+ LOG(("Cannot restart authentication sequence!"));
+ return NS_ERROR_UNEXPECTED;
+ }
+ ctxIn = nullptr;
+ // The certificate needs to be erased before being passed
+ // to InitializeSecurityContextW().
+ inToken = nullptr;
+ inTokenLen = 0;
+ } else {
+ ibd.ulVersion = SECBUFFER_VERSION;
+ ibd.cBuffers = 0;
+ ibd.pBuffers = ib;
+
+ // If we have stored a certificate, the Channel Binding Token
+ // needs to be generated and sent in the first input buffer.
+ if (mCertDERLength > 0) {
+ // First we create a proper Endpoint Binding structure.
+ pendpoint_binding.dwInitiatorAddrType = 0;
+ pendpoint_binding.cbInitiatorLength = 0;
+ pendpoint_binding.dwInitiatorOffset = 0;
+ pendpoint_binding.dwAcceptorAddrType = 0;
+ pendpoint_binding.cbAcceptorLength = 0;
+ pendpoint_binding.dwAcceptorOffset = 0;
+ pendpoint_binding.cbApplicationDataLength = cbt_size;
+ pendpoint_binding.dwApplicationDataOffset =
+ sizeof(SEC_CHANNEL_BINDINGS);
+
+ // Then add it to the array of sec buffers accordingly.
+ ib[ibd.cBuffers].BufferType = SECBUFFER_CHANNEL_BINDINGS;
+ ib[ibd.cBuffers].cbBuffer = pendpoint_binding.cbApplicationDataLength +
+ pendpoint_binding.dwApplicationDataOffset;
+
+ sspi_cbt = (char*)moz_xmalloc(ib[ibd.cBuffers].cbBuffer);
+
+ // Helper to write in the memory block that stores the CBT
+ char* sspi_cbt_ptr = sspi_cbt;
+
+ ib[ibd.cBuffers].pvBuffer = sspi_cbt;
+ ibd.cBuffers++;
+
+ memcpy(sspi_cbt_ptr, &pendpoint_binding,
+ pendpoint_binding.dwApplicationDataOffset);
+ sspi_cbt_ptr += pendpoint_binding.dwApplicationDataOffset;
+
+ memcpy(sspi_cbt_ptr, end_point, end_point_length);
+ sspi_cbt_ptr += end_point_length;
+
+ // Start hashing. We are always doing SHA256, but depending
+ // on the certificate, a different alogirthm might be needed.
+ nsAutoCString hashString;
+
+ nsresult rv;
+ nsCOMPtr<nsICryptoHash> crypto;
+ crypto = do_CreateInstance(NS_CRYPTO_HASH_CONTRACTID, &rv);
+ if (NS_SUCCEEDED(rv)) rv = crypto->Init(nsICryptoHash::SHA256);
+ if (NS_SUCCEEDED(rv))
+ rv = crypto->Update((unsigned char*)mCertDERData, mCertDERLength);
+ if (NS_SUCCEEDED(rv)) rv = crypto->Finish(false, hashString);
+ if (NS_FAILED(rv)) {
+ free(mCertDERData);
+ mCertDERData = nullptr;
+ mCertDERLength = 0;
+ free(sspi_cbt);
+ return rv;
+ }
+
+ // Once the hash has been computed, we store it in memory right
+ // after the Endpoint structure and the "tls-server-end-point:"
+ // char array.
+ memcpy(sspi_cbt_ptr, hashString.get(), hash_size);
+
+ // Free memory used to store the server certificate
+ free(mCertDERData);
+ mCertDERData = nullptr;
+ mCertDERLength = 0;
+ } // End of CBT computation.
+
+ // We always need this SECBUFFER.
+ ib[ibd.cBuffers].BufferType = SECBUFFER_TOKEN;
+ ib[ibd.cBuffers].cbBuffer = inTokenLen;
+ ib[ibd.cBuffers].pvBuffer = (void*)inToken;
+ ibd.cBuffers++;
+ ctxIn = &mCtxt;
+ }
+ } else { // First time and without a token (no server certificate)
+ // We are starting a new authentication sequence. If we have already
+ // initialized our security context, then we're in trouble because it
+ // means that the first sequence failed. We need to bail or else we
+ // might end up in an infinite loop.
+ if (mCtxt.dwLower || mCtxt.dwUpper || mCertDERData || mCertDERLength) {
+ LOG(("Cannot restart authentication sequence!"));
+ return NS_ERROR_UNEXPECTED;
+ }
+ ctxIn = nullptr;
+ mIsFirst = false;
+ }
+
+ obd.ulVersion = SECBUFFER_VERSION;
+ obd.cBuffers = 1;
+ obd.pBuffers = &ob;
+ ob.BufferType = SECBUFFER_TOKEN;
+ ob.cbBuffer = mMaxTokenLen;
+ ob.pvBuffer = moz_xmalloc(ob.cbBuffer);
+ memset(ob.pvBuffer, 0, ob.cbBuffer);
+
+ NS_ConvertUTF8toUTF16 wSN(mServiceName);
+ SEC_WCHAR* sn = (SEC_WCHAR*)wSN.get();
+
+ rc = (sspi->InitializeSecurityContextW)(
+ &mCred, ctxIn, sn, ctxReq, 0, SECURITY_NATIVE_DREP,
+ inToken ? &ibd : nullptr, 0, &mCtxt, &obd, &ctxAttr, &ignored);
+ if (rc == SEC_I_CONTINUE_NEEDED || rc == SEC_E_OK) {
+ if (rc == SEC_E_OK)
+ LOG(("InitializeSecurityContext: succeeded.\n"));
+ else
+ LOG(("InitializeSecurityContext: continue.\n"));
+
+ if (sspi_cbt) free(sspi_cbt);
+
+ if (!ob.cbBuffer) {
+ free(ob.pvBuffer);
+ ob.pvBuffer = nullptr;
+ }
+ *outToken = ob.pvBuffer;
+ *outTokenLen = ob.cbBuffer;
+
+ if (rc == SEC_E_OK) return NS_SUCCESS_AUTH_FINISHED;
+
+ return NS_OK;
+ }
+
+ LOG(("InitializeSecurityContext failed [rc=%ld:%s]\n", rc, MapErrorCode(rc)));
+ Reset();
+ free(ob.pvBuffer);
+ return NS_ERROR_FAILURE;
+}
+
+NS_IMETHODIMP
+nsAuthSSPI::Unwrap(const void* inToken, uint32_t inTokenLen, void** outToken,
+ uint32_t* outTokenLen) {
+ SECURITY_STATUS rc;
+ SecBufferDesc ibd;
+ SecBuffer ib[2];
+
+ ibd.cBuffers = 2;
+ ibd.pBuffers = ib;
+ ibd.ulVersion = SECBUFFER_VERSION;
+
+ // SSPI Buf
+ ib[0].BufferType = SECBUFFER_STREAM;
+ ib[0].cbBuffer = inTokenLen;
+ ib[0].pvBuffer = moz_xmalloc(ib[0].cbBuffer);
+
+ memcpy(ib[0].pvBuffer, inToken, inTokenLen);
+
+ // app data
+ ib[1].BufferType = SECBUFFER_DATA;
+ ib[1].cbBuffer = 0;
+ ib[1].pvBuffer = nullptr;
+
+ rc = (sspi->DecryptMessage)(&mCtxt, &ibd,
+ 0, // no sequence numbers
+ nullptr);
+
+ if (SEC_SUCCESS(rc)) {
+ // check if ib[1].pvBuffer is really just ib[0].pvBuffer, in which
+ // case we can let the caller free it. Otherwise, we need to
+ // clone it, and free the original
+ if (ib[0].pvBuffer == ib[1].pvBuffer) {
+ *outToken = ib[1].pvBuffer;
+ } else {
+ *outToken = moz_xmemdup(ib[1].pvBuffer, ib[1].cbBuffer);
+ free(ib[0].pvBuffer);
+ }
+ *outTokenLen = ib[1].cbBuffer;
+ } else
+ free(ib[0].pvBuffer);
+
+ if (!SEC_SUCCESS(rc)) return NS_ERROR_FAILURE;
+
+ return NS_OK;
+}
+
+// utility class used to free memory on exit
+class secBuffers {
+ public:
+ SecBuffer ib[3];
+
+ secBuffers() { memset(&ib, 0, sizeof(ib)); }
+
+ ~secBuffers() {
+ if (ib[0].pvBuffer) free(ib[0].pvBuffer);
+
+ if (ib[1].pvBuffer) free(ib[1].pvBuffer);
+
+ if (ib[2].pvBuffer) free(ib[2].pvBuffer);
+ }
+};
+
+NS_IMETHODIMP
+nsAuthSSPI::Wrap(const void* inToken, uint32_t inTokenLen, bool confidential,
+ void** outToken, uint32_t* outTokenLen) {
+ SECURITY_STATUS rc;
+
+ SecBufferDesc ibd;
+ secBuffers bufs;
+ SecPkgContext_Sizes sizes;
+
+ rc = (sspi->QueryContextAttributesW)(&mCtxt, SECPKG_ATTR_SIZES, &sizes);
+
+ if (!SEC_SUCCESS(rc)) return NS_ERROR_FAILURE;
+
+ ibd.cBuffers = 3;
+ ibd.pBuffers = bufs.ib;
+ ibd.ulVersion = SECBUFFER_VERSION;
+
+ // SSPI
+ bufs.ib[0].cbBuffer = sizes.cbSecurityTrailer;
+ bufs.ib[0].BufferType = SECBUFFER_TOKEN;
+ bufs.ib[0].pvBuffer = moz_xmalloc(sizes.cbSecurityTrailer);
+
+ // APP Data
+ bufs.ib[1].BufferType = SECBUFFER_DATA;
+ bufs.ib[1].pvBuffer = moz_xmalloc(inTokenLen);
+ bufs.ib[1].cbBuffer = inTokenLen;
+
+ memcpy(bufs.ib[1].pvBuffer, inToken, inTokenLen);
+
+ // SSPI
+ bufs.ib[2].BufferType = SECBUFFER_PADDING;
+ bufs.ib[2].cbBuffer = sizes.cbBlockSize;
+ bufs.ib[2].pvBuffer = moz_xmalloc(bufs.ib[2].cbBuffer);
+
+ rc = (sspi->EncryptMessage)(&mCtxt, confidential ? 0 : KERB_WRAP_NO_ENCRYPT,
+ &ibd, 0);
+
+ if (SEC_SUCCESS(rc)) {
+ int len = bufs.ib[0].cbBuffer + bufs.ib[1].cbBuffer + bufs.ib[2].cbBuffer;
+ char* p = (char*)moz_xmalloc(len);
+
+ *outToken = (void*)p;
+ *outTokenLen = len;
+
+ memcpy(p, bufs.ib[0].pvBuffer, bufs.ib[0].cbBuffer);
+ p += bufs.ib[0].cbBuffer;
+
+ memcpy(p, bufs.ib[1].pvBuffer, bufs.ib[1].cbBuffer);
+ p += bufs.ib[1].cbBuffer;
+
+ memcpy(p, bufs.ib[2].pvBuffer, bufs.ib[2].cbBuffer);
+
+ return NS_OK;
+ }
+
+ return NS_ERROR_FAILURE;
+}
diff --git a/extensions/auth/nsAuthSSPI.h b/extensions/auth/nsAuthSSPI.h
new file mode 100644
index 0000000000..96ad6b1cb9
--- /dev/null
+++ b/extensions/auth/nsAuthSSPI.h
@@ -0,0 +1,60 @@
+/* vim:set ts=4 sw=2 et cindent: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef nsAuthSSPI_h__
+#define nsAuthSSPI_h__
+
+#include "nsAuth.h"
+#include "nsIAuthModule.h"
+#include "nsString.h"
+
+#include <windows.h>
+
+#define SECURITY_WIN32 1
+#include <ntsecapi.h>
+#include <security.h>
+#include <rpc.h>
+
+// The nsNegotiateAuth class provides responses for the GSS-API Negotiate method
+// as specified by Microsoft in draft-brezak-spnego-http-04.txt
+
+// It can also be configured to talk raw NTLM. This implementation of NTLM has
+// the advantage of being able to access the user's logon credentials. This
+// implementation of NTLM should only be used for single-signon. It should be
+// avoided when authenticating over the internet since it may use a lower-grade
+// version of password hashing depending on the version of Windows being used.
+
+class nsAuthSSPI final : public nsIAuthModule {
+ public:
+ NS_DECL_ISUPPORTS
+ NS_DECL_NSIAUTHMODULE
+
+ explicit nsAuthSSPI(pType package = PACKAGE_TYPE_NEGOTIATE);
+
+ private:
+ ~nsAuthSSPI();
+
+ void Reset();
+
+ typedef ::TimeStamp MS_TimeStamp;
+
+ private:
+ nsresult MakeSN(const nsACString& principal, nsCString& result);
+
+ CredHandle mCred;
+ CtxtHandle mCtxt;
+ nsCString mServiceName;
+ uint32_t mServiceFlags;
+ uint32_t mMaxTokenLen;
+ pType mPackage;
+ nsString mDomain;
+ nsString mUsername;
+ nsString mPassword;
+ bool mIsFirst;
+ void* mCertDERData;
+ uint32_t mCertDERLength;
+};
+
+#endif /* nsAuthSSPI_h__ */
diff --git a/extensions/auth/nsAuthSambaNTLM.cpp b/extensions/auth/nsAuthSambaNTLM.cpp
new file mode 100644
index 0000000000..5b701f2379
--- /dev/null
+++ b/extensions/auth/nsAuthSambaNTLM.cpp
@@ -0,0 +1,259 @@
+/* vim:set ts=4 sw=2 et cindent: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "nsAuth.h"
+#include "nsAuthSambaNTLM.h"
+#include "nspr.h"
+#include "prenv.h"
+#include "plbase64.h"
+#include "prerror.h"
+#include "mozilla/Telemetry.h"
+
+#include <stdlib.h>
+
+nsAuthSambaNTLM::nsAuthSambaNTLM()
+ : mInitialMessage(nullptr),
+ mChildPID(nullptr),
+ mFromChildFD(nullptr),
+ mToChildFD(nullptr) {}
+
+nsAuthSambaNTLM::~nsAuthSambaNTLM() {
+ // ntlm_auth reads from stdin regularly so closing our file handles
+ // should cause it to exit.
+ Shutdown();
+ PR_Free(mInitialMessage);
+}
+
+void nsAuthSambaNTLM::Shutdown() {
+ if (mFromChildFD) {
+ PR_Close(mFromChildFD);
+ mFromChildFD = nullptr;
+ }
+ if (mToChildFD) {
+ PR_Close(mToChildFD);
+ mToChildFD = nullptr;
+ }
+ if (mChildPID) {
+ PR_KillProcess(mChildPID);
+ mChildPID = nullptr;
+ }
+}
+
+NS_IMPL_ISUPPORTS(nsAuthSambaNTLM, nsIAuthModule)
+
+static bool SpawnIOChild(char* const* aArgs, PRProcess** aPID,
+ PRFileDesc** aFromChildFD, PRFileDesc** aToChildFD) {
+ PRFileDesc* toChildPipeRead;
+ PRFileDesc* toChildPipeWrite;
+ if (PR_CreatePipe(&toChildPipeRead, &toChildPipeWrite) != PR_SUCCESS) {
+ return false;
+ }
+ PR_SetFDInheritable(toChildPipeRead, true);
+ PR_SetFDInheritable(toChildPipeWrite, false);
+
+ PRFileDesc* fromChildPipeRead;
+ PRFileDesc* fromChildPipeWrite;
+ if (PR_CreatePipe(&fromChildPipeRead, &fromChildPipeWrite) != PR_SUCCESS) {
+ PR_Close(toChildPipeRead);
+ PR_Close(toChildPipeWrite);
+ return false;
+ }
+ PR_SetFDInheritable(fromChildPipeRead, false);
+ PR_SetFDInheritable(fromChildPipeWrite, true);
+
+ PRProcessAttr* attr = PR_NewProcessAttr();
+ if (!attr) {
+ PR_Close(fromChildPipeRead);
+ PR_Close(fromChildPipeWrite);
+ PR_Close(toChildPipeRead);
+ PR_Close(toChildPipeWrite);
+ return false;
+ }
+
+ PR_ProcessAttrSetStdioRedirect(attr, PR_StandardInput, toChildPipeRead);
+ PR_ProcessAttrSetStdioRedirect(attr, PR_StandardOutput, fromChildPipeWrite);
+
+ PRProcess* process = PR_CreateProcess(aArgs[0], aArgs, nullptr, attr);
+ PR_DestroyProcessAttr(attr);
+ PR_Close(fromChildPipeWrite);
+ PR_Close(toChildPipeRead);
+ if (!process) {
+ LOG(("ntlm_auth exec failure [%d]", PR_GetError()));
+ PR_Close(fromChildPipeRead);
+ PR_Close(toChildPipeWrite);
+ return false;
+ }
+
+ *aPID = process;
+ *aFromChildFD = fromChildPipeRead;
+ *aToChildFD = toChildPipeWrite;
+ return true;
+}
+
+static bool WriteString(PRFileDesc* aFD, const nsACString& aString) {
+ int32_t length = aString.Length();
+ const char* s = aString.BeginReading();
+ LOG(("Writing to ntlm_auth: %s", s));
+
+ while (length > 0) {
+ int result = PR_Write(aFD, s, length);
+ if (result <= 0) return false;
+ s += result;
+ length -= result;
+ }
+ return true;
+}
+
+static bool ReadLine(PRFileDesc* aFD, nsACString& aString) {
+ // ntlm_auth is defined to only send one line in response to each of our
+ // input lines. So this simple unbuffered strategy works as long as we
+ // read the response immediately after sending one request.
+ aString.Truncate();
+ for (;;) {
+ char buf[1024];
+ int result = PR_Read(aFD, buf, sizeof(buf));
+ if (result <= 0) return false;
+ aString.Append(buf, result);
+ if (buf[result - 1] == '\n') {
+ LOG(("Read from ntlm_auth: %s", nsPromiseFlatCString(aString).get()));
+ return true;
+ }
+ }
+}
+
+/**
+ * Returns a heap-allocated array of PRUint8s, and stores the length in aLen.
+ * Returns nullptr if there's an error of any kind.
+ */
+static uint8_t* ExtractMessage(const nsACString& aLine, uint32_t* aLen) {
+ // ntlm_auth sends blobs to us as base64-encoded strings after the "xx "
+ // preamble on the response line.
+ int32_t length = aLine.Length();
+ // The caller should verify there is a valid "xx " prefix and the line
+ // is terminated with a \n
+ NS_ASSERTION(length >= 4, "Line too short...");
+ const char* line = aLine.BeginReading();
+ const char* s = line + 3;
+ length -= 4; // lose first 3 chars plus trailing \n
+ NS_ASSERTION(s[length] == '\n', "aLine not newline-terminated");
+
+ if (length & 3) {
+ // The base64 encoded block must be multiple of 4. If not, something
+ // screwed up.
+ NS_WARNING("Base64 encoded block should be a multiple of 4 chars");
+ return nullptr;
+ }
+
+ // Calculate the exact length. I wonder why there isn't a function for this
+ // in plbase64.
+ int32_t numEquals;
+ for (numEquals = 0; numEquals < length; ++numEquals) {
+ if (s[length - 1 - numEquals] != '=') break;
+ }
+ *aLen = (length / 4) * 3 - numEquals;
+ return reinterpret_cast<uint8_t*>(PL_Base64Decode(s, length, nullptr));
+}
+
+nsresult nsAuthSambaNTLM::SpawnNTLMAuthHelper() {
+ const char* username = PR_GetEnv("USER");
+ if (!username) return NS_ERROR_FAILURE;
+
+ const char* const args[] = {"ntlm_auth",
+ "--helper-protocol",
+ "ntlmssp-client-1",
+ "--use-cached-creds",
+ "--username",
+ username,
+ nullptr};
+
+ bool isOK = SpawnIOChild(const_cast<char* const*>(args), &mChildPID,
+ &mFromChildFD, &mToChildFD);
+ if (!isOK) return NS_ERROR_FAILURE;
+
+ if (!WriteString(mToChildFD, "YR\n"_ns)) return NS_ERROR_FAILURE;
+ nsCString line;
+ if (!ReadLine(mFromChildFD, line)) return NS_ERROR_FAILURE;
+ if (!StringBeginsWith(line, "YR "_ns)) {
+ // Something went wrong. Perhaps no credentials are accessible.
+ return NS_ERROR_FAILURE;
+ }
+
+ // It gave us an initial client-to-server request packet. Save that
+ // because we'll need it later.
+ mInitialMessage = ExtractMessage(line, &mInitialMessageLen);
+ if (!mInitialMessage) return NS_ERROR_FAILURE;
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsAuthSambaNTLM::Init(const nsACString& serviceName, uint32_t serviceFlags,
+ const nsAString& domain, const nsAString& username,
+ const nsAString& password) {
+ NS_ASSERTION(username.IsEmpty() && domain.IsEmpty() && password.IsEmpty(),
+ "unexpected credentials");
+
+ static bool sTelemetrySent = false;
+ if (!sTelemetrySent) {
+ mozilla::Telemetry::Accumulate(mozilla::Telemetry::NTLM_MODULE_USED_2,
+ serviceFlags & nsIAuthModule::REQ_PROXY_AUTH
+ ? NTLM_MODULE_SAMBA_AUTH_PROXY
+ : NTLM_MODULE_SAMBA_AUTH_DIRECT);
+ sTelemetrySent = true;
+ }
+
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsAuthSambaNTLM::GetNextToken(const void* inToken, uint32_t inTokenLen,
+ void** outToken, uint32_t* outTokenLen) {
+ if (!inToken) {
+ /* someone wants our initial message */
+ *outToken = moz_xmemdup(mInitialMessage, mInitialMessageLen);
+ *outTokenLen = mInitialMessageLen;
+ return NS_OK;
+ }
+
+ /* inToken must be a type 2 message. Get ntlm_auth to generate our response */
+ char* encoded =
+ PL_Base64Encode(static_cast<const char*>(inToken), inTokenLen, nullptr);
+ if (!encoded) return NS_ERROR_OUT_OF_MEMORY;
+
+ nsCString request;
+ request.AssignLiteral("TT ");
+ request.Append(encoded);
+ PR_Free(encoded);
+ request.Append('\n');
+
+ if (!WriteString(mToChildFD, request)) return NS_ERROR_FAILURE;
+ nsCString line;
+ if (!ReadLine(mFromChildFD, line)) return NS_ERROR_FAILURE;
+ if (!StringBeginsWith(line, "KK "_ns) && !StringBeginsWith(line, "AF "_ns)) {
+ // Something went wrong. Perhaps no credentials are accessible.
+ return NS_ERROR_FAILURE;
+ }
+ uint8_t* buf = ExtractMessage(line, outTokenLen);
+ if (!buf) return NS_ERROR_FAILURE;
+ *outToken = moz_xmemdup(buf, *outTokenLen);
+ PR_Free(buf);
+
+ // We're done. Close our file descriptors now and reap the helper
+ // process.
+ Shutdown();
+ return NS_SUCCESS_AUTH_FINISHED;
+}
+
+NS_IMETHODIMP
+nsAuthSambaNTLM::Unwrap(const void* inToken, uint32_t inTokenLen,
+ void** outToken, uint32_t* outTokenLen) {
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+NS_IMETHODIMP
+nsAuthSambaNTLM::Wrap(const void* inToken, uint32_t inTokenLen,
+ bool confidential, void** outToken,
+ uint32_t* outTokenLen) {
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
diff --git a/extensions/auth/nsAuthSambaNTLM.h b/extensions/auth/nsAuthSambaNTLM.h
new file mode 100644
index 0000000000..4cfd6a003d
--- /dev/null
+++ b/extensions/auth/nsAuthSambaNTLM.h
@@ -0,0 +1,51 @@
+/* vim:set ts=4 sw=2 et cindent: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef nsAuthSambaNTLM_h__
+#define nsAuthSambaNTLM_h__
+
+#include "nsIAuthModule.h"
+#include "nsString.h"
+#include "nsCOMPtr.h"
+#include "prio.h"
+#include "prproces.h"
+#include "mozilla/Attributes.h"
+
+/**
+ * This is an implementation of NTLM authentication that does single-signon
+ * by obtaining the user's Unix username, parsing it into DOMAIN\name format,
+ * and then asking Samba's ntlm_auth tool to do the authentication for us
+ * using the user's password cached in winbindd, if available. If the
+ * password is not available then this component fails to instantiate so
+ * nsHttpNTLMAuth will fall back to a different NTLM implementation.
+ * NOTE: at time of writing, this requires patches to be added to the stock
+ * Samba winbindd and ntlm_auth!
+ */
+class nsAuthSambaNTLM final : public nsIAuthModule {
+ public:
+ NS_DECL_ISUPPORTS
+ NS_DECL_NSIAUTHMODULE
+
+ nsAuthSambaNTLM();
+
+ // We spawn the ntlm_auth helper from the module constructor, because
+ // that lets us fail to instantiate the module if ntlm_auth isn't
+ // available, triggering fallback to the built-in NTLM support (which
+ // doesn't support single signon, of course)
+ nsresult SpawnNTLMAuthHelper();
+
+ private:
+ ~nsAuthSambaNTLM();
+
+ void Shutdown();
+
+ uint8_t* mInitialMessage; /* free with free() */
+ uint32_t mInitialMessageLen{};
+ PRProcess* mChildPID;
+ PRFileDesc* mFromChildFD;
+ PRFileDesc* mToChildFD;
+};
+
+#endif /* nsAuthSambaNTLM_h__ */
diff --git a/extensions/auth/nsHttpNegotiateAuth.cpp b/extensions/auth/nsHttpNegotiateAuth.cpp
new file mode 100644
index 0000000000..a3ec224b59
--- /dev/null
+++ b/extensions/auth/nsHttpNegotiateAuth.cpp
@@ -0,0 +1,565 @@
+/* vim:set ts=4 sw=2 sts=2 et cindent: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+//
+// HTTP Negotiate Authentication Support Module
+//
+// Described by IETF Internet draft: draft-brezak-kerberos-http-00.txt
+// (formerly draft-brezak-spnego-http-04.txt)
+//
+// Also described here:
+// http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnsecure/html/http-sso-1.asp
+//
+
+#include <stdlib.h>
+
+#include "nsAuth.h"
+#include "nsHttpNegotiateAuth.h"
+
+#include "nsIHttpAuthenticableChannel.h"
+#include "nsIAuthModule.h"
+#include "nsIPrefBranch.h"
+#include "nsIPrefService.h"
+#include "nsIProxyInfo.h"
+#include "nsIURI.h"
+#include "nsCOMPtr.h"
+#include "nsString.h"
+#include "nsNetCID.h"
+#include "nsProxyRelease.h"
+#include "plbase64.h"
+#include "mozilla/Base64.h"
+#include "mozilla/Tokenizer.h"
+#include "mozilla/UniquePtr.h"
+#include "mozilla/Sprintf.h"
+#include "nsIChannel.h"
+#include "nsNetUtil.h"
+#include "nsThreadUtils.h"
+#include "nsIHttpAuthenticatorCallback.h"
+#include "nsICancelable.h"
+#include "mozilla/net/HttpAuthUtils.h"
+#include "mozilla/ClearOnShutdown.h"
+#include "mozilla/net/DNS.h"
+#include "mozilla/StaticPrefs_browser.h"
+
+using mozilla::Base64Decode;
+
+//-----------------------------------------------------------------------------
+
+static const char kNegotiate[] = "Negotiate";
+static const char kNegotiateAuthTrustedURIs[] =
+ "network.negotiate-auth.trusted-uris";
+static const char kNegotiateAuthDelegationURIs[] =
+ "network.negotiate-auth.delegation-uris";
+static const char kNegotiateAuthAllowProxies[] =
+ "network.negotiate-auth.allow-proxies";
+static const char kNegotiateAuthAllowNonFqdn[] =
+ "network.negotiate-auth.allow-non-fqdn";
+static const char kNegotiateAuthSSPI[] = "network.auth.use-sspi";
+static const char kSSOinPBmode[] = "network.auth.private-browsing-sso";
+
+mozilla::StaticRefPtr<nsHttpNegotiateAuth> nsHttpNegotiateAuth::gSingleton;
+
+#define kNegotiateLen (sizeof(kNegotiate) - 1)
+#define DEFAULT_THREAD_TIMEOUT_MS 30000
+
+//-----------------------------------------------------------------------------
+
+// Return false when the channel comes from a Private browsing window.
+static bool TestNotInPBMode(nsIHttpAuthenticableChannel* authChannel,
+ bool proxyAuth) {
+ // Proxy should go all the time, it's not considered a privacy leak
+ // to send default credentials to a proxy.
+ if (proxyAuth) {
+ return true;
+ }
+
+ nsCOMPtr<nsIChannel> bareChannel = do_QueryInterface(authChannel);
+ MOZ_ASSERT(bareChannel);
+
+ if (!NS_UsePrivateBrowsing(bareChannel)) {
+ return true;
+ }
+
+ nsCOMPtr<nsIPrefBranch> prefs = do_GetService(NS_PREFSERVICE_CONTRACTID);
+ if (prefs) {
+ bool ssoInPb;
+ if (NS_SUCCEEDED(prefs->GetBoolPref(kSSOinPBmode, &ssoInPb)) && ssoInPb) {
+ return true;
+ }
+
+ // When the "Never remember history" option is set, all channels are
+ // set PB mode flag, but here we want to make an exception, users
+ // want their credentials go out.
+ if (mozilla::StaticPrefs::browser_privatebrowsing_autostart()) {
+ return true;
+ }
+ }
+
+ return false;
+}
+
+already_AddRefed<nsIHttpAuthenticator> nsHttpNegotiateAuth::GetOrCreate() {
+ nsCOMPtr<nsIHttpAuthenticator> authenticator;
+ if (gSingleton) {
+ authenticator = gSingleton;
+ } else {
+ gSingleton = new nsHttpNegotiateAuth();
+ mozilla::ClearOnShutdown(&gSingleton);
+ authenticator = gSingleton;
+ }
+
+ return authenticator.forget();
+}
+
+NS_IMETHODIMP
+nsHttpNegotiateAuth::GetAuthFlags(uint32_t* flags) {
+ //
+ // Negotiate Auth creds should not be reused across multiple requests.
+ // Only perform the negotiation when it is explicitly requested by the
+ // server. Thus, do *NOT* use the "REUSABLE_CREDENTIALS" flag here.
+ //
+ // CONNECTION_BASED is specified instead of REQUEST_BASED since we need
+ // to complete a sequence of transactions with the server over the same
+ // connection.
+ //
+ *flags = CONNECTION_BASED | IDENTITY_IGNORED;
+ return NS_OK;
+}
+
+//
+// Always set *identityInvalid == FALSE here. This
+// will prevent the browser from popping up the authentication
+// prompt window. Because GSSAPI does not have an API
+// for fetching initial credentials (ex: A Kerberos TGT),
+// there is no correct way to get the users credentials.
+//
+NS_IMETHODIMP
+nsHttpNegotiateAuth::ChallengeReceived(nsIHttpAuthenticableChannel* authChannel,
+ const nsACString& challenge,
+ bool isProxyAuth,
+ nsISupports** sessionState,
+ nsISupports** continuationState,
+ bool* identityInvalid) {
+ nsIAuthModule* rawModule = (nsIAuthModule*)*continuationState;
+
+ *identityInvalid = false;
+ if (rawModule) {
+ return NS_OK;
+ }
+
+ nsresult rv;
+ nsCOMPtr<nsIAuthModule> module;
+
+ nsCOMPtr<nsIURI> uri;
+ rv = authChannel->GetURI(getter_AddRefs(uri));
+ if (NS_FAILED(rv)) return rv;
+
+ uint32_t req_flags = nsIAuthModule::REQ_DEFAULT;
+ nsAutoCString service;
+
+ if (isProxyAuth) {
+ if (!TestBoolPref(kNegotiateAuthAllowProxies)) {
+ LOG(("nsHttpNegotiateAuth::ChallengeReceived proxy auth blocked\n"));
+ return NS_ERROR_ABORT;
+ }
+
+ req_flags |= nsIAuthModule::REQ_PROXY_AUTH;
+ nsCOMPtr<nsIProxyInfo> proxyInfo;
+ authChannel->GetProxyInfo(getter_AddRefs(proxyInfo));
+ NS_ENSURE_STATE(proxyInfo);
+
+ proxyInfo->GetHost(service);
+ } else {
+ bool allowed =
+ TestNotInPBMode(authChannel, isProxyAuth) &&
+ (TestNonFqdn(uri) || mozilla::net::auth::URIMatchesPrefPattern(
+ uri, kNegotiateAuthTrustedURIs));
+ if (!allowed) {
+ LOG(("nsHttpNegotiateAuth::ChallengeReceived URI blocked\n"));
+ return NS_ERROR_ABORT;
+ }
+
+ bool delegation = mozilla::net::auth::URIMatchesPrefPattern(
+ uri, kNegotiateAuthDelegationURIs);
+ if (delegation) {
+ LOG((" using REQ_DELEGATE\n"));
+ req_flags |= nsIAuthModule::REQ_DELEGATE;
+ }
+
+ rv = uri->GetAsciiHost(service);
+ if (NS_FAILED(rv)) return rv;
+ }
+
+ LOG((" service = %s\n", service.get()));
+
+ //
+ // The correct service name for IIS servers is "HTTP/f.q.d.n", so
+ // construct the proper service name for passing to "gss_import_name".
+ //
+ // TODO: Possibly make this a configurable service name for use
+ // with non-standard servers that use stuff like "khttp/f.q.d.n"
+ // instead.
+ //
+ service.InsertLiteral("HTTP@", 0);
+
+ const char* authType;
+ if (TestBoolPref(kNegotiateAuthSSPI)) {
+ LOG((" using negotiate-sspi\n"));
+ authType = "negotiate-sspi";
+ } else {
+ LOG((" using negotiate-gss\n"));
+ authType = "negotiate-gss";
+ }
+
+ MOZ_ALWAYS_TRUE(module = nsIAuthModule::CreateInstance(authType));
+
+ rv = module->Init(service, req_flags, u""_ns, u""_ns, u""_ns);
+
+ if (NS_FAILED(rv)) {
+ return rv;
+ }
+
+ module.forget(continuationState);
+ return NS_OK;
+}
+
+NS_IMPL_ISUPPORTS(nsHttpNegotiateAuth, nsIHttpAuthenticator)
+
+namespace {
+
+//
+// GetNextTokenCompleteEvent
+//
+// This event is fired on main thread when async call of
+// nsHttpNegotiateAuth::GenerateCredentials is finished. During the Run()
+// method the nsIHttpAuthenticatorCallback::OnCredsAvailable is called with
+// obtained credentials, flags and NS_OK when successful, otherwise
+// NS_ERROR_FAILURE is returned as a result of failed operation.
+//
+class GetNextTokenCompleteEvent final : public nsIRunnable,
+ public nsICancelable {
+ public:
+ NS_DECL_THREADSAFE_ISUPPORTS
+
+ explicit GetNextTokenCompleteEvent(nsIHttpAuthenticatorCallback* aCallback)
+ : mCallback(aCallback) {}
+
+ nsresult DispatchSuccess(const nsACString& aCreds, uint32_t aFlags,
+ already_AddRefed<nsISupports> aSessionState,
+ already_AddRefed<nsISupports> aContinuationState) {
+ // Called from worker thread
+ MOZ_ASSERT(!NS_IsMainThread());
+
+ mCreds = aCreds;
+ mFlags = aFlags;
+ mResult = NS_OK;
+ mSessionState = aSessionState;
+ mContinuationState = aContinuationState;
+ return NS_DispatchToMainThread(this, NS_DISPATCH_NORMAL);
+ }
+
+ nsresult DispatchError(already_AddRefed<nsISupports> aSessionState,
+ already_AddRefed<nsISupports> aContinuationState) {
+ // Called from worker thread
+ MOZ_ASSERT(!NS_IsMainThread());
+
+ mResult = NS_ERROR_FAILURE;
+ mSessionState = aSessionState;
+ mContinuationState = aContinuationState;
+ return NS_DispatchToMainThread(this, NS_DISPATCH_NORMAL);
+ }
+
+ NS_IMETHODIMP Run() override {
+ // Runs on main thread
+ MOZ_ASSERT(NS_IsMainThread());
+
+ if (!mCancelled) {
+ nsCOMPtr<nsIHttpAuthenticatorCallback> callback;
+ callback.swap(mCallback);
+ callback->OnCredsGenerated(mCreds, mFlags, mResult, mSessionState,
+ mContinuationState);
+ }
+ return NS_OK;
+ }
+
+ NS_IMETHODIMP Cancel(nsresult aReason) override {
+ // Supposed to be called from main thread
+ MOZ_ASSERT(NS_IsMainThread());
+
+ mCancelled = true;
+ nsCOMPtr<nsIHttpAuthenticatorCallback> callback = std::move(mCallback);
+ if (callback) {
+ callback->OnCredsGenerated(mCreds, mFlags, aReason, nullptr, nullptr);
+ }
+ return NS_OK;
+ }
+
+ private:
+ virtual ~GetNextTokenCompleteEvent() = default;
+
+ nsCOMPtr<nsIHttpAuthenticatorCallback> mCallback;
+ nsCString mCreds;
+ uint32_t mFlags = 0;
+ nsresult mResult = NS_OK;
+ bool mCancelled = false;
+ nsCOMPtr<nsISupports> mSessionState;
+ nsCOMPtr<nsISupports> mContinuationState;
+};
+
+inline nsISupports* ToSupports(GetNextTokenCompleteEvent* aEvent) {
+ return static_cast<nsIRunnable*>(aEvent);
+}
+
+NS_IMPL_ISUPPORTS(GetNextTokenCompleteEvent, nsIRunnable, nsICancelable)
+
+//
+// GetNextTokenRunnable
+//
+// This runnable is created by GenerateCredentialsAsync and it runs
+// on the background thread pool and calls GenerateCredentials.
+//
+class GetNextTokenRunnable final : public mozilla::Runnable {
+ ~GetNextTokenRunnable() override = default;
+
+ public:
+ GetNextTokenRunnable(
+ nsMainThreadPtrHandle<nsIHttpAuthenticableChannel>& authChannel,
+ const nsACString& challenge, bool isProxyAuth, const nsAString& domain,
+ const nsAString& username, const nsAString& password,
+ nsISupports* sessionState, nsISupports* continuationState,
+ nsMainThreadPtrHandle<GetNextTokenCompleteEvent>& aCompleteEvent)
+ : mozilla::Runnable("GetNextTokenRunnable"),
+ mAuthChannel(authChannel),
+ mChallenge(challenge),
+ mIsProxyAuth(isProxyAuth),
+ mDomain(domain),
+ mUsername(username),
+ mPassword(password),
+ mSessionState(sessionState),
+ mContinuationState(continuationState),
+ mCompleteEvent(aCompleteEvent) {}
+
+ NS_IMETHODIMP Run() override {
+ // Runs on worker thread
+ MOZ_ASSERT(!NS_IsMainThread());
+
+ nsCString creds;
+ uint32_t flags;
+ nsresult rv = ObtainCredentialsAndFlags(creds, &flags);
+
+ // Passing session and continuation state this way to not touch
+ // referencing of the object that may not be thread safe.
+ // Not having a thread safe referencing doesn't mean the object
+ // cannot be used on multiple threads (one example is nsAuthSSPI.)
+ // This ensures state objects will be destroyed on the main thread
+ // when not changed by GenerateCredentials.
+ if (NS_FAILED(rv)) {
+ return mCompleteEvent->DispatchError(mSessionState.forget(),
+ mContinuationState.forget());
+ }
+
+ return mCompleteEvent->DispatchSuccess(creds, flags, mSessionState.forget(),
+ mContinuationState.forget());
+ }
+
+ NS_IMETHODIMP ObtainCredentialsAndFlags(nsCString& aCreds, uint32_t* aFlags) {
+ nsresult rv;
+
+ // Use negotiate service to call GenerateCredentials outside of main thread
+ nsCOMPtr<nsIHttpAuthenticator> authenticator = new nsHttpNegotiateAuth();
+
+ nsISupports* sessionState = mSessionState;
+ nsISupports* continuationState = mContinuationState;
+ // The continuationState is for the sake of completeness propagated
+ // to the caller (despite it is not changed in any GenerateCredentials
+ // implementation).
+ //
+ // The only implementation that use sessionState is the
+ // nsHttpDigestAuth::GenerateCredentials. Since there's no reason
+ // to implement nsHttpDigestAuth::GenerateCredentialsAsync
+ // because digest auth does not block the main thread, we won't
+ // propagate changes to sessionState to the caller because of
+ // the change is too complicated on the caller side.
+ //
+ // Should any of the session or continuation states change inside
+ // this method, they must be threadsafe.
+ rv = authenticator->GenerateCredentials(
+ mAuthChannel, mChallenge, mIsProxyAuth, mDomain, mUsername, mPassword,
+ &sessionState, &continuationState, aFlags, aCreds);
+ if (mSessionState != sessionState) {
+ mSessionState = sessionState;
+ }
+ if (mContinuationState != continuationState) {
+ mContinuationState = continuationState;
+ }
+ return rv;
+ }
+
+ private:
+ nsMainThreadPtrHandle<nsIHttpAuthenticableChannel> mAuthChannel;
+ nsCString mChallenge;
+ bool mIsProxyAuth;
+ nsString mDomain;
+ nsString mUsername;
+ nsString mPassword;
+ nsCOMPtr<nsISupports> mSessionState;
+ nsCOMPtr<nsISupports> mContinuationState;
+ nsMainThreadPtrHandle<GetNextTokenCompleteEvent> mCompleteEvent;
+};
+
+} // anonymous namespace
+
+NS_IMETHODIMP
+nsHttpNegotiateAuth::GenerateCredentialsAsync(
+ nsIHttpAuthenticableChannel* authChannel,
+ nsIHttpAuthenticatorCallback* aCallback, const nsACString& challenge,
+ bool isProxyAuth, const nsAString& domain, const nsAString& username,
+ const nsAString& password, nsISupports* sessionState,
+ nsISupports* continuationState, nsICancelable** aCancelable) {
+ NS_ENSURE_ARG(aCallback);
+ NS_ENSURE_ARG_POINTER(aCancelable);
+
+ nsMainThreadPtrHandle<nsIHttpAuthenticableChannel> handle(
+ new nsMainThreadPtrHolder<nsIHttpAuthenticableChannel>(
+ "nsIHttpAuthenticableChannel", authChannel, false));
+ nsMainThreadPtrHandle<GetNextTokenCompleteEvent> cancelEvent(
+ new nsMainThreadPtrHolder<GetNextTokenCompleteEvent>(
+ "GetNextTokenCompleteEvent", new GetNextTokenCompleteEvent(aCallback),
+ false));
+ nsCOMPtr<nsIRunnable> getNextTokenRunnable = new GetNextTokenRunnable(
+ handle, challenge, isProxyAuth, domain, username, password, sessionState,
+ continuationState, cancelEvent);
+
+ nsresult rv = NS_DispatchBackgroundTask(
+ getNextTokenRunnable, nsIEventTarget::DISPATCH_EVENT_MAY_BLOCK);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ RefPtr<GetNextTokenCompleteEvent> cancelable(cancelEvent.get());
+ cancelable.forget(aCancelable);
+ return NS_OK;
+}
+
+//
+// GenerateCredentials
+//
+// This routine is responsible for creating the correct authentication
+// blob to pass to the server that requested "Negotiate" authentication.
+//
+NS_IMETHODIMP
+nsHttpNegotiateAuth::GenerateCredentials(
+ nsIHttpAuthenticableChannel* authChannel, const nsACString& aChallenge,
+ bool isProxyAuth, const nsAString& domain, const nsAString& username,
+ const nsAString& password, nsISupports** sessionState,
+ nsISupports** continuationState, uint32_t* flags, nsACString& creds) {
+ // ChallengeReceived must have been called previously.
+ nsIAuthModule* module = (nsIAuthModule*)*continuationState;
+ NS_ENSURE_TRUE(module, NS_ERROR_NOT_INITIALIZED);
+
+ *flags = USING_INTERNAL_IDENTITY;
+
+ LOG(("nsHttpNegotiateAuth::GenerateCredentials() [challenge=%s]\n",
+ aChallenge.BeginReading()));
+
+#ifdef DEBUG
+ bool isGssapiAuth = StringBeginsWith(aChallenge, "Negotiate"_ns,
+ nsCaseInsensitiveCStringComparator);
+ NS_ASSERTION(isGssapiAuth, "Unexpected challenge");
+#endif
+
+ //
+ // If the "Negotiate:" header had some data associated with it,
+ // that data should be used as the input to this call. This may
+ // be a continuation of an earlier call because GSSAPI authentication
+ // often takes multiple round-trips to complete depending on the
+ // context flags given. We want to use MUTUAL_AUTHENTICATION which
+ // generally *does* require multiple round-trips. Don't assume
+ // auth can be completed in just 1 call.
+ //
+
+ nsAutoCString inToken;
+ if (aChallenge.Length() > kNegotiateLen) {
+ nsDependentCSubstring challenge(aChallenge, kNegotiateLen);
+ uint32_t startPos = 0;
+ while (startPos < challenge.Length() && challenge[startPos] == ' ') {
+ startPos++;
+ }
+ if (startPos == challenge.Length()) {
+ return NS_ERROR_UNEXPECTED;
+ }
+
+ // strip off any padding (see bug 230351)
+ uint32_t len = challenge.Length();
+ while (len > startPos && challenge[len - 1] == '=') {
+ len--;
+ }
+
+ //
+ // Decode the response that followed the "Negotiate" token
+ //
+ (void)Base64Decode(
+ nsDependentCSubstring(challenge, startPos, len - startPos), inToken);
+ }
+
+ void* outToken = nullptr;
+ uint32_t outTokenLen = 0;
+ nsresult rv = module->GetNextToken(inToken.get(), inToken.Length(), &outToken,
+ &outTokenLen);
+ if (NS_FAILED(rv)) {
+ if (outToken) {
+ // Technically if the call fails we shouln't have allocated, but
+ // Coverity doesn't know that.
+ free(outToken);
+ }
+ return rv;
+ }
+
+ if (outTokenLen == 0) {
+ LOG((" No output token to send, exiting"));
+ return NS_ERROR_FAILURE;
+ }
+
+ //
+ // base64 encode the output token.
+ //
+ nsAutoCString encodedToken;
+ rv = mozilla::Base64Encode(
+ nsDependentCSubstring((char*)outToken, outTokenLen), encodedToken);
+ free(outToken);
+ if (NS_FAILED(rv)) {
+ return rv;
+ }
+
+ LOG((" Sending a token of length %d\n", outTokenLen));
+
+ creds = nsPrintfCString("%s %s", kNegotiate, encodedToken.get());
+ return rv;
+}
+
+bool nsHttpNegotiateAuth::TestBoolPref(const char* pref) {
+ nsCOMPtr<nsIPrefBranch> prefs = do_GetService(NS_PREFSERVICE_CONTRACTID);
+ if (!prefs) return false;
+
+ bool val;
+ nsresult rv = prefs->GetBoolPref(pref, &val);
+ if (NS_FAILED(rv)) return false;
+
+ return val;
+}
+
+bool nsHttpNegotiateAuth::TestNonFqdn(nsIURI* uri) {
+ nsAutoCString host;
+
+ if (!TestBoolPref(kNegotiateAuthAllowNonFqdn)) {
+ return false;
+ }
+
+ if (NS_FAILED(uri->GetAsciiHost(host))) {
+ return false;
+ }
+
+ // return true if host does not contain a dot and is not an ip address
+ return !host.IsEmpty() && !host.Contains('.') &&
+ !mozilla::net::HostIsIPLiteral(host);
+}
diff --git a/extensions/auth/nsHttpNegotiateAuth.h b/extensions/auth/nsHttpNegotiateAuth.h
new file mode 100644
index 0000000000..d84f04df5a
--- /dev/null
+++ b/extensions/auth/nsHttpNegotiateAuth.h
@@ -0,0 +1,35 @@
+/* vim:set ts=4 sw=2 et cindent: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef nsHttpNegotiateAuth_h__
+#define nsHttpNegotiateAuth_h__
+
+#include "nsIHttpAuthenticator.h"
+#include "nsIURI.h"
+#include "mozilla/StaticPtr.h"
+
+// The nsHttpNegotiateAuth class provides responses for the GSS-API Negotiate
+// method as specified by Microsoft in draft-brezak-spnego-http-04.txt
+
+class nsHttpNegotiateAuth final : public nsIHttpAuthenticator {
+ public:
+ NS_DECL_THREADSAFE_ISUPPORTS
+ NS_DECL_NSIHTTPAUTHENTICATOR
+
+ static already_AddRefed<nsIHttpAuthenticator> GetOrCreate();
+
+ private:
+ ~nsHttpNegotiateAuth() {}
+
+ // returns the value of the given boolean pref
+ bool TestBoolPref(const char* pref);
+
+ // tests if the host part of an uri is fully qualified
+ bool TestNonFqdn(nsIURI* uri);
+
+ // Singleton pointer
+ static mozilla::StaticRefPtr<nsHttpNegotiateAuth> gSingleton;
+};
+#endif /* nsHttpNegotiateAuth_h__ */
diff --git a/extensions/auth/nsIAuthModule.cpp b/extensions/auth/nsIAuthModule.cpp
new file mode 100644
index 0000000000..8f18a344eb
--- /dev/null
+++ b/extensions/auth/nsIAuthModule.cpp
@@ -0,0 +1,63 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "nsIAuthModule.h"
+#if defined(USE_SSPI)
+# include "nsAuthSSPI.h"
+#else
+# include "nsAuthSambaNTLM.h"
+#endif
+#include "nsCRT.h"
+#include "nsAuthGSSAPI.h"
+#include "nsAuthSASL.h"
+#include "nsNTLMAuthModule.h"
+#include "nsNSSComponent.h"
+
+// static
+already_AddRefed<nsIAuthModule> nsIAuthModule::CreateInstance(
+ const char* aType) {
+ nsCOMPtr<nsIAuthModule> auth;
+ if (!nsCRT::strcmp(aType, "kerb-gss")) {
+ auth = new nsAuthGSSAPI(PACKAGE_TYPE_KERBEROS);
+ } else if (!nsCRT::strcmp(aType, "negotiate-gss")) {
+ auth = new nsAuthGSSAPI(PACKAGE_TYPE_NEGOTIATE);
+#if defined(USE_SSPI)
+ } else if (!nsCRT::strcmp(aType, "negotiate-sspi")) {
+ auth = new nsAuthSSPI();
+ } else if (!nsCRT::strcmp(aType, "kerb-sspi")) {
+ auth = new nsAuthSSPI(PACKAGE_TYPE_KERBEROS);
+ } else if (!nsCRT::strcmp(aType, "sys-ntlm")) {
+ auth = new nsAuthSSPI(PACKAGE_TYPE_NTLM);
+#elif !defined(XP_MACOSX)
+ } else if (!nsCRT::strcmp(aType, "sys-ntlm")) {
+ RefPtr<nsAuthSambaNTLM> sambaAuth = new nsAuthSambaNTLM();
+
+ nsresult rv = sambaAuth->SpawnNTLMAuthHelper();
+ if (NS_FAILED(rv)) {
+ // Failure here probably means that cached credentials were not available
+ return nullptr;
+ }
+
+ auth = std::move(sambaAuth);
+#endif
+ } else if (!nsCRT::strcmp(aType, "sasl-gssapi")) {
+ auth = new nsAuthSASL();
+ } else if (!nsCRT::strcmp(aType, "ntlm") && XRE_IsParentProcess() &&
+ EnsureNSSInitializedChromeOrContent()) {
+ RefPtr<nsNTLMAuthModule> ntlmAuth = new nsNTLMAuthModule();
+
+ nsresult rv = ntlmAuth->InitTest();
+ if (NS_FAILED(rv)) {
+ return nullptr;
+ }
+
+ auth = std::move(ntlmAuth);
+ } else {
+ return nullptr;
+ }
+
+ return auth.forget();
+}
+
+mozilla::LazyLogModule gNegotiateLog("negotiateauth");
diff --git a/extensions/permissions/Permission.cpp b/extensions/permissions/Permission.cpp
new file mode 100644
index 0000000000..adec3689cf
--- /dev/null
+++ b/extensions/permissions/Permission.cpp
@@ -0,0 +1,122 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "mozilla/Permission.h"
+#include "nsIClassInfoImpl.h"
+#include "nsIEffectiveTLDService.h"
+#include "nsNetCID.h"
+#include "nsNetUtil.h"
+#include "mozilla/BasePrincipal.h"
+#include "mozilla/StaticPrefs_permissions.h"
+#include "mozilla/PermissionManager.h"
+
+namespace mozilla {
+
+// Permission Implementation
+
+NS_IMPL_CLASSINFO(Permission, nullptr, 0, {0})
+NS_IMPL_ISUPPORTS_CI(Permission, nsIPermission)
+
+Permission::Permission(nsIPrincipal* aPrincipal, const nsACString& aType,
+ uint32_t aCapability, uint32_t aExpireType,
+ int64_t aExpireTime, int64_t aModificationTime)
+ : mPrincipal(aPrincipal),
+ mType(aType),
+ mCapability(aCapability),
+ mExpireType(aExpireType),
+ mExpireTime(aExpireTime),
+ mModificationTime(aModificationTime) {}
+
+already_AddRefed<nsIPrincipal> Permission::ClonePrincipalForPermission(
+ nsIPrincipal* aPrincipal) {
+ MOZ_ASSERT(aPrincipal);
+
+ mozilla::OriginAttributes attrs = aPrincipal->OriginAttributesRef();
+ PermissionManager::MaybeStripOriginAttributes(false, attrs);
+
+ nsAutoCString originNoSuffix;
+ nsresult rv = aPrincipal->GetOriginNoSuffix(originNoSuffix);
+ NS_ENSURE_SUCCESS(rv, nullptr);
+
+ nsCOMPtr<nsIURI> uri;
+ rv = NS_NewURI(getter_AddRefs(uri), originNoSuffix);
+ NS_ENSURE_SUCCESS(rv, nullptr);
+
+ return mozilla::BasePrincipal::CreateContentPrincipal(uri, attrs);
+}
+
+already_AddRefed<Permission> Permission::Create(
+ nsIPrincipal* aPrincipal, const nsACString& aType, uint32_t aCapability,
+ uint32_t aExpireType, int64_t aExpireTime, int64_t aModificationTime) {
+ NS_ENSURE_TRUE(aPrincipal, nullptr);
+
+ nsCOMPtr<nsIPrincipal> principal =
+ Permission::ClonePrincipalForPermission(aPrincipal);
+ NS_ENSURE_TRUE(principal, nullptr);
+
+ RefPtr<Permission> permission =
+ new Permission(principal, aType, aCapability, aExpireType, aExpireTime,
+ aModificationTime);
+ return permission.forget();
+}
+
+NS_IMETHODIMP
+Permission::GetPrincipal(nsIPrincipal** aPrincipal) {
+ nsCOMPtr<nsIPrincipal> copy = mPrincipal;
+ copy.forget(aPrincipal);
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+Permission::GetType(nsACString& aType) {
+ aType = mType;
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+Permission::GetCapability(uint32_t* aCapability) {
+ *aCapability = mCapability;
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+Permission::GetExpireType(uint32_t* aExpireType) {
+ *aExpireType = mExpireType;
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+Permission::GetExpireTime(int64_t* aExpireTime) {
+ *aExpireTime = mExpireTime;
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+Permission::GetModificationTime(int64_t* aModificationTime) {
+ *aModificationTime = mModificationTime;
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+Permission::Matches(nsIPrincipal* aPrincipal, bool aExactHost, bool* aMatches) {
+ NS_ENSURE_ARG_POINTER(aPrincipal);
+ NS_ENSURE_ARG_POINTER(aMatches);
+
+ return mPrincipal->EqualsForPermission(aPrincipal, aExactHost, aMatches);
+}
+
+NS_IMETHODIMP
+Permission::MatchesURI(nsIURI* aURI, bool aExactHost, bool* aMatches) {
+ NS_ENSURE_ARG_POINTER(aURI);
+
+ mozilla::OriginAttributes attrs;
+ nsCOMPtr<nsIPrincipal> principal =
+ mozilla::BasePrincipal::CreateContentPrincipal(aURI, attrs);
+ NS_ENSURE_TRUE(principal, NS_ERROR_FAILURE);
+
+ return Matches(principal, aExactHost, aMatches);
+}
+
+} // namespace mozilla
diff --git a/extensions/permissions/Permission.h b/extensions/permissions/Permission.h
new file mode 100644
index 0000000000..0d304a48c7
--- /dev/null
+++ b/extensions/permissions/Permission.h
@@ -0,0 +1,49 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef mozilla_Permission_h
+#define mozilla_Permission_h
+
+#include "nsIPermission.h"
+#include "nsCOMPtr.h"
+#include "nsString.h"
+
+namespace mozilla {
+
+////////////////////////////////////////////////////////////////////////////////
+
+class Permission : public nsIPermission {
+ public:
+ // nsISupports
+ NS_DECL_ISUPPORTS
+ NS_DECL_NSIPERMISSION
+
+ static already_AddRefed<Permission> Create(
+ nsIPrincipal* aPrincipal, const nsACString& aType, uint32_t aCapability,
+ uint32_t aExpireType, int64_t aExpireTime, int64_t aModificationTime);
+
+ // This method creates a new nsIPrincipal with a stripped OriginAttributes (no
+ // userContextId) and a content principal equal to the origin of 'aPrincipal'.
+ static already_AddRefed<nsIPrincipal> ClonePrincipalForPermission(
+ nsIPrincipal* aPrincipal);
+
+ protected:
+ Permission(nsIPrincipal* aPrincipal, const nsACString& aType,
+ uint32_t aCapability, uint32_t aExpireType, int64_t aExpireTime,
+ int64_t aModificationTime);
+
+ virtual ~Permission() = default;
+
+ nsCOMPtr<nsIPrincipal> mPrincipal;
+ nsCString mType;
+ uint32_t mCapability;
+ uint32_t mExpireType;
+ int64_t mExpireTime;
+ int64_t mModificationTime;
+};
+
+} // namespace mozilla
+
+#endif // mozilla_Permission_h
diff --git a/extensions/permissions/PermissionDelegateHandler.cpp b/extensions/permissions/PermissionDelegateHandler.cpp
new file mode 100644
index 0000000000..b81943c9b9
--- /dev/null
+++ b/extensions/permissions/PermissionDelegateHandler.cpp
@@ -0,0 +1,403 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "mozilla/PermissionDelegateHandler.h"
+
+#include "nsGlobalWindowInner.h"
+#include "nsPIDOMWindow.h"
+#include "nsIPrincipal.h"
+#include "nsContentPermissionHelper.h"
+
+#include "mozilla/BasePrincipal.h"
+#include "mozilla/StaticPrefs_permissions.h"
+#include "mozilla/dom/Document.h"
+#include "mozilla/dom/FeaturePolicyUtils.h"
+#include "mozilla/dom/WindowContext.h"
+#include "mozilla/PermissionManager.h"
+
+using namespace mozilla::dom;
+
+namespace mozilla {
+
+typedef PermissionDelegateHandler::PermissionDelegatePolicy DelegatePolicy;
+typedef PermissionDelegateHandler::PermissionDelegateInfo DelegateInfo;
+
+// Particular type of permissions to care about. We decide cases by case and
+// give various types of controls over each of these.
+static const DelegateInfo sPermissionsMap[] = {
+ // Permissions API map. All permission names have to be in lowercase.
+ {"geo", u"geolocation", DelegatePolicy::eDelegateUseFeaturePolicy},
+ // The same with geo, but we support both to save some conversions between
+ // "geo" and "geolocation"
+ {"geolocation", u"geolocation", DelegatePolicy::eDelegateUseFeaturePolicy},
+ {"desktop-notification", nullptr,
+ DelegatePolicy::ePersistDeniedCrossOrigin},
+ {"persistent-storage", nullptr, DelegatePolicy::ePersistDeniedCrossOrigin},
+ {"vibration", nullptr, DelegatePolicy::ePersistDeniedCrossOrigin},
+ {"midi", nullptr, DelegatePolicy::eDelegateUseIframeOrigin},
+ // Like "midi" but with sysex support.
+ {"midi-sysex", nullptr, DelegatePolicy::eDelegateUseIframeOrigin},
+ {"storage-access", nullptr, DelegatePolicy::eDelegateUseIframeOrigin},
+ {"camera", u"camera", DelegatePolicy::eDelegateUseFeaturePolicy},
+ {"microphone", u"microphone", DelegatePolicy::eDelegateUseFeaturePolicy},
+ {"screen", u"display-capture", DelegatePolicy::eDelegateUseFeaturePolicy},
+ {"xr", u"xr-spatial-tracking", DelegatePolicy::eDelegateUseFeaturePolicy},
+};
+
+static_assert(PermissionDelegateHandler::DELEGATED_PERMISSION_COUNT ==
+ (sizeof(sPermissionsMap) / sizeof(DelegateInfo)),
+ "The PermissionDelegateHandler::DELEGATED_PERMISSION_COUNT must "
+ "match to the "
+ "length of sPermissionsMap. Please update it.");
+
+NS_IMPL_CYCLE_COLLECTION(PermissionDelegateHandler)
+NS_IMPL_CYCLE_COLLECTING_ADDREF(PermissionDelegateHandler)
+NS_IMPL_CYCLE_COLLECTING_RELEASE(PermissionDelegateHandler)
+
+NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(PermissionDelegateHandler)
+ NS_INTERFACE_MAP_ENTRY(nsIPermissionDelegateHandler)
+ NS_INTERFACE_MAP_ENTRY(nsISupports)
+NS_INTERFACE_MAP_END
+
+PermissionDelegateHandler::PermissionDelegateHandler(dom::Document* aDocument)
+ : mDocument(aDocument) {
+ MOZ_ASSERT(aDocument);
+}
+
+/* static */
+const DelegateInfo* PermissionDelegateHandler::GetPermissionDelegateInfo(
+ const nsAString& aPermissionName) {
+ nsAutoString lowerContent(aPermissionName);
+ ToLowerCase(lowerContent);
+
+ for (const auto& perm : sPermissionsMap) {
+ if (lowerContent.EqualsASCII(perm.mPermissionName)) {
+ return &perm;
+ }
+ }
+
+ return nullptr;
+}
+
+NS_IMETHODIMP
+PermissionDelegateHandler::MaybeUnsafePermissionDelegate(
+ const nsTArray<nsCString>& aTypes, bool* aMaybeUnsafe) {
+ *aMaybeUnsafe = false;
+ if (!StaticPrefs::permissions_delegation_enabled()) {
+ return NS_OK;
+ }
+
+ for (auto& type : aTypes) {
+ const DelegateInfo* info =
+ GetPermissionDelegateInfo(NS_ConvertUTF8toUTF16(type));
+ if (!info) {
+ continue;
+ }
+
+ nsAutoString featureName(info->mFeatureName);
+ if (FeaturePolicyUtils::IsFeatureUnsafeAllowedAll(mDocument, featureName)) {
+ *aMaybeUnsafe = true;
+ return NS_OK;
+ }
+ }
+
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+PermissionDelegateHandler::GetPermissionDelegateFPEnabled(bool* aEnabled) {
+ MOZ_ASSERT(NS_IsMainThread());
+ *aEnabled = StaticPrefs::permissions_delegation_enabled();
+ return NS_OK;
+}
+
+/* static */
+nsresult PermissionDelegateHandler::GetDelegatePrincipal(
+ const nsACString& aType, nsIContentPermissionRequest* aRequest,
+ nsIPrincipal** aResult) {
+ MOZ_ASSERT(aRequest);
+
+ if (!StaticPrefs::permissions_delegation_enabled()) {
+ return aRequest->GetPrincipal(aResult);
+ }
+
+ const DelegateInfo* info =
+ GetPermissionDelegateInfo(NS_ConvertUTF8toUTF16(aType));
+ if (!info) {
+ *aResult = nullptr;
+ return NS_OK;
+ }
+
+ if (info->mPolicy == DelegatePolicy::eDelegateUseTopOrigin ||
+ info->mPolicy == DelegatePolicy::eDelegateUseFeaturePolicy) {
+ return aRequest->GetTopLevelPrincipal(aResult);
+ }
+
+ return aRequest->GetPrincipal(aResult);
+}
+
+bool PermissionDelegateHandler::Initialize() {
+ MOZ_ASSERT(mDocument);
+
+ mPermissionManager = PermissionManager::GetInstance();
+ if (!mPermissionManager) {
+ return false;
+ }
+
+ mPrincipal = mDocument->NodePrincipal();
+ return true;
+}
+
+static bool IsCrossOriginContentToTop(Document* aDocument) {
+ MOZ_ASSERT(aDocument);
+
+ RefPtr<BrowsingContext> bc = aDocument->GetBrowsingContext();
+ if (!bc) {
+ return true;
+ }
+ RefPtr<BrowsingContext> topBC = bc->Top();
+
+ // In Fission, we can know if it is cross-origin by checking whether both
+ // contexts in the same process. So, If they are not in the same process, we
+ // can say that it's cross-origin.
+ if (!topBC->IsInProcess()) {
+ return true;
+ }
+
+ RefPtr<Document> topDoc = topBC->GetDocument();
+ if (!topDoc) {
+ return true;
+ }
+
+ nsCOMPtr<nsIPrincipal> topLevelPrincipal = topDoc->NodePrincipal();
+
+ return !aDocument->NodePrincipal()->Subsumes(topLevelPrincipal);
+}
+
+bool PermissionDelegateHandler::HasFeaturePolicyAllowed(
+ const DelegateInfo* info) const {
+ if (info->mPolicy != DelegatePolicy::eDelegateUseFeaturePolicy ||
+ !info->mFeatureName) {
+ return true;
+ }
+
+ nsAutoString featureName(info->mFeatureName);
+ return FeaturePolicyUtils::IsFeatureAllowed(mDocument, featureName);
+}
+
+bool PermissionDelegateHandler::HasPermissionDelegated(
+ const nsACString& aType) const {
+ MOZ_ASSERT(mDocument);
+
+ // System principal should have right to make permission request
+ if (mPrincipal->IsSystemPrincipal()) {
+ return true;
+ }
+
+ const DelegateInfo* info =
+ GetPermissionDelegateInfo(NS_ConvertUTF8toUTF16(aType));
+ if (!info || !HasFeaturePolicyAllowed(info)) {
+ return false;
+ }
+
+ if (!StaticPrefs::permissions_delegation_enabled()) {
+ return true;
+ }
+
+ if (info->mPolicy == DelegatePolicy::ePersistDeniedCrossOrigin &&
+ !mDocument->IsTopLevelContentDocument() &&
+ IsCrossOriginContentToTop(mDocument)) {
+ return false;
+ }
+
+ return true;
+}
+
+nsresult PermissionDelegateHandler::GetPermission(const nsACString& aType,
+ uint32_t* aPermission,
+ bool aExactHostMatch) {
+ MOZ_ASSERT(mDocument);
+ MOZ_ASSERT(mPrincipal);
+
+ if (mPrincipal->IsSystemPrincipal()) {
+ *aPermission = nsIPermissionManager::ALLOW_ACTION;
+ return NS_OK;
+ }
+
+ const DelegateInfo* info =
+ GetPermissionDelegateInfo(NS_ConvertUTF8toUTF16(aType));
+ if (!info || !HasFeaturePolicyAllowed(info)) {
+ *aPermission = nsIPermissionManager::DENY_ACTION;
+ return NS_OK;
+ }
+
+ nsresult (NS_STDCALL nsIPermissionManager::*testPermission)(
+ nsIPrincipal*, const nsACString&, uint32_t*) =
+ aExactHostMatch ? &nsIPermissionManager::TestExactPermissionFromPrincipal
+ : &nsIPermissionManager::TestPermissionFromPrincipal;
+
+ if (!StaticPrefs::permissions_delegation_enabled()) {
+ return (mPermissionManager->*testPermission)(mPrincipal, aType,
+ aPermission);
+ }
+
+ if (info->mPolicy == DelegatePolicy::ePersistDeniedCrossOrigin &&
+ !mDocument->IsTopLevelContentDocument() &&
+ IsCrossOriginContentToTop(mDocument)) {
+ *aPermission = nsIPermissionManager::DENY_ACTION;
+ return NS_OK;
+ }
+
+ nsIPrincipal* principal = mPrincipal;
+ // If we cannot get the browsing context from the document, we fallback to use
+ // the prinicpal of the document to test the permission.
+ RefPtr<BrowsingContext> bc = mDocument->GetBrowsingContext();
+
+ if ((info->mPolicy == DelegatePolicy::eDelegateUseTopOrigin ||
+ info->mPolicy == DelegatePolicy::eDelegateUseFeaturePolicy) &&
+ bc) {
+ RefPtr<WindowContext> topWC = bc->GetTopWindowContext();
+
+ if (topWC && topWC->IsInProcess()) {
+ // If the top-level window context is in the same process, we directly get
+ // the node principal from the top-level document to test the permission.
+ // We cannot check the lists in the window context in this case since the
+ // 'perm-changed' could be notified in the iframe before the top-level in
+ // certain cases, for example, request permissions in first-party iframes.
+ // In this case, the list in window context hasn't gotten updated, so it
+ // would has an out-dated value until the top-level window get the
+ // observer. So, we have to test permission manager directly if we can.
+ RefPtr<Document> topDoc = topWC->GetBrowsingContext()->GetDocument();
+
+ if (topDoc) {
+ principal = topDoc->NodePrincipal();
+ }
+ } else if (topWC) {
+ // Get the delegated permissions from the top-level window context.
+ DelegatedPermissionList list =
+ aExactHostMatch ? topWC->GetDelegatedExactHostMatchPermissions()
+ : topWC->GetDelegatedPermissions();
+ size_t idx = std::distance(sPermissionsMap, info);
+ *aPermission = list.mPermissions[idx];
+ return NS_OK;
+ }
+ }
+
+ return (mPermissionManager->*testPermission)(principal, aType, aPermission);
+}
+
+nsresult PermissionDelegateHandler::GetPermissionForPermissionsAPI(
+ const nsACString& aType, uint32_t* aPermission) {
+ return GetPermission(aType, aPermission, false);
+}
+
+void PermissionDelegateHandler::PopulateAllDelegatedPermissions() {
+ MOZ_ASSERT(mDocument);
+ MOZ_ASSERT(mPermissionManager);
+
+ // We only populate the delegated permissions for the top-level content.
+ if (!mDocument->IsTopLevelContentDocument()) {
+ return;
+ }
+
+ RefPtr<WindowContext> wc = mDocument->GetWindowContext();
+ NS_ENSURE_TRUE_VOID(wc && !wc->IsDiscarded());
+
+ DelegatedPermissionList list;
+ DelegatedPermissionList exactHostMatchList;
+
+ for (const auto& perm : sPermissionsMap) {
+ size_t idx = std::distance(sPermissionsMap, &perm);
+
+ nsDependentCString type(perm.mPermissionName);
+ // Populate the permission.
+ uint32_t permission = nsIPermissionManager::UNKNOWN_ACTION;
+ Unused << mPermissionManager->TestPermissionFromPrincipal(mPrincipal, type,
+ &permission);
+ list.mPermissions[idx] = permission;
+
+ // Populate the exact-host-match permission.
+ permission = nsIPermissionManager::UNKNOWN_ACTION;
+ Unused << mPermissionManager->TestExactPermissionFromPrincipal(
+ mPrincipal, type, &permission);
+ exactHostMatchList.mPermissions[idx] = permission;
+ }
+
+ WindowContext::Transaction txn;
+ txn.SetDelegatedPermissions(list);
+ txn.SetDelegatedExactHostMatchPermissions(exactHostMatchList);
+ MOZ_ALWAYS_SUCCEEDS(txn.Commit(wc));
+}
+
+void PermissionDelegateHandler::UpdateDelegatedPermission(
+ const nsACString& aType) {
+ MOZ_ASSERT(mDocument);
+ MOZ_ASSERT(mPermissionManager);
+
+ // We only update the delegated permission for the top-level content.
+ if (!mDocument->IsTopLevelContentDocument()) {
+ return;
+ }
+
+ RefPtr<WindowContext> wc = mDocument->GetWindowContext();
+ NS_ENSURE_TRUE_VOID(wc);
+
+ const DelegateInfo* info =
+ GetPermissionDelegateInfo(NS_ConvertUTF8toUTF16(aType));
+ if (!info) {
+ return;
+ }
+ size_t idx = std::distance(sPermissionsMap, info);
+
+ WindowContext::Transaction txn;
+ bool changed = false;
+ DelegatedPermissionList list = wc->GetDelegatedPermissions();
+
+ if (UpdateDelegatePermissionInternal(
+ list, aType, idx,
+ &nsIPermissionManager::TestPermissionFromPrincipal)) {
+ txn.SetDelegatedPermissions(list);
+ changed = true;
+ }
+
+ DelegatedPermissionList exactHostMatchList =
+ wc->GetDelegatedExactHostMatchPermissions();
+
+ if (UpdateDelegatePermissionInternal(
+ exactHostMatchList, aType, idx,
+ &nsIPermissionManager::TestExactPermissionFromPrincipal)) {
+ txn.SetDelegatedExactHostMatchPermissions(exactHostMatchList);
+ changed = true;
+ }
+
+ // We only commit if there is any change of permissions.
+ if (changed) {
+ MOZ_ALWAYS_SUCCEEDS(txn.Commit(wc));
+ }
+}
+
+bool PermissionDelegateHandler::UpdateDelegatePermissionInternal(
+ PermissionDelegateHandler::DelegatedPermissionList& aList,
+ const nsACString& aType, size_t aIdx,
+ nsresult (NS_STDCALL nsIPermissionManager::*aTestFunc)(nsIPrincipal*,
+ const nsACString&,
+ uint32_t*)) {
+ MOZ_ASSERT(aTestFunc);
+ MOZ_ASSERT(mPermissionManager);
+ MOZ_ASSERT(mPrincipal);
+
+ uint32_t permission = nsIPermissionManager::UNKNOWN_ACTION;
+ Unused << (mPermissionManager->*aTestFunc)(mPrincipal, aType, &permission);
+
+ if (aList.mPermissions[aIdx] != permission) {
+ aList.mPermissions[aIdx] = permission;
+ return true;
+ }
+
+ return false;
+}
+
+} // namespace mozilla
diff --git a/extensions/permissions/PermissionDelegateHandler.h b/extensions/permissions/PermissionDelegateHandler.h
new file mode 100644
index 0000000000..a07fbceaeb
--- /dev/null
+++ b/extensions/permissions/PermissionDelegateHandler.h
@@ -0,0 +1,203 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+/*
+ * Permission delegate handler provides a policy of how top-level can
+ * delegate permission to embedded iframes.
+ *
+ * This class includes a mechanism to delegate permission using feature
+ * policy. Feature policy will assure that only cross-origin iframes which
+ * have been explicitly granted access will have the opportunity to request
+ * permission.
+ *
+ * For example if an iframe has not been granted access to geolocation by
+ * Feature Policy, geolocation request from the iframe will be automatically
+ * denied. if the top-level origin already has access to geolocation and the
+ * iframe has been granted access to geolocation by Feature Policy, the iframe
+ * will also have access to geolocation. If the top-level frame did not have
+ * access to geolocation, and the iframe has been granted access to geolocation
+ * by Feature Policy, a request from the cross-origin iframe would trigger a
+ * prompt using of the top-level origin.
+ */
+
+#ifndef mozilla_PermissionDelegateHandler_h
+#define mozilla_PermissionDelegateHandler_h
+
+#include "mozilla/Array.h"
+#include "nsCycleCollectionParticipant.h"
+#include "nsISupports.h"
+#include "nsIPermissionDelegateHandler.h"
+#include "nsIPermissionManager.h"
+#include "nsCOMPtr.h"
+
+class nsIPrincipal;
+class nsIContentPermissionRequest;
+
+namespace mozilla {
+namespace dom {
+class Document;
+class WindowContext;
+} // namespace dom
+
+class PermissionDelegateHandler final : public nsIPermissionDelegateHandler {
+ public:
+ NS_DECL_CYCLE_COLLECTING_ISUPPORTS
+ NS_DECL_CYCLE_COLLECTION_CLASS(PermissionDelegateHandler)
+
+ NS_DECL_NSIPERMISSIONDELEGATEHANDLER
+
+ explicit PermissionDelegateHandler() = default;
+ explicit PermissionDelegateHandler(mozilla::dom::Document* aDocument);
+
+ static constexpr size_t DELEGATED_PERMISSION_COUNT = 12;
+
+ typedef struct DelegatedPermissionList {
+ Array<uint32_t, DELEGATED_PERMISSION_COUNT> mPermissions;
+
+ bool operator==(const DelegatedPermissionList& aOther) const {
+ return mPermissions == aOther.mPermissions;
+ }
+ } DelegatedPermissionList;
+
+ bool Initialize();
+
+ /*
+ * Indicates if we has the right to make permission request with aType
+ */
+ bool HasPermissionDelegated(const nsACString& aType) const;
+
+ /*
+ * Get permission state, which applied permission delegate policy.
+ *
+ * @param aType the permission type to get
+ * @param aPermission out argument which will be a permission type that we
+ * will return from this function.
+ * @param aExactHostMatch whether to look for the exact host name or also for
+ * subdomains that can have the same permission.
+ */
+ nsresult GetPermission(const nsACString& aType, uint32_t* aPermission,
+ bool aExactHostMatch);
+
+ /*
+ * Get permission state for permission api, which applied
+ * permission delegate policy.
+ *
+ * @param aType the permission type to get
+ * @param aExactHostMatch whether to look for the exact host name or also for
+ * subdomains that can have the same permission.
+ * @param aPermission out argument which will be a permission type that we
+ * will return from this function.
+ */
+ nsresult GetPermissionForPermissionsAPI(const nsACString& aType,
+ uint32_t* aPermission);
+
+ enum PermissionDelegatePolicy {
+ /* Always delegate permission from top level to iframe and the iframe
+ * should use top level origin to get/set permission.*/
+ eDelegateUseTopOrigin,
+
+ /* Permission is delegated using Feature Policy. Permission is denied by
+ * default in cross origin iframe and the iframe only could get/set
+ * permission if there's allow attribute set in iframe. e.g allow =
+ * "geolocation" */
+ eDelegateUseFeaturePolicy,
+
+ /* Persistent denied permissions in cross origin iframe */
+ ePersistDeniedCrossOrigin,
+
+ /* This is the old behavior of cross origin iframe permission. The
+ * permission delegation should not have an effect on iframe. The cross
+ * origin iframe get/set permissions by its origin */
+ eDelegateUseIframeOrigin,
+ };
+
+ /*
+ * Indicates matching between Feature Policy and Permissions name defined in
+ * Permissions Manager, not DOM Permissions API. Permissions API exposed in
+ * DOM only supports "geo" at the moment but Permissions Manager also supports
+ * "camera", "microphone".
+ */
+ typedef struct {
+ const char* mPermissionName;
+ const char16_t* mFeatureName;
+ PermissionDelegatePolicy mPolicy;
+ } PermissionDelegateInfo;
+
+ /**
+ * The loader maintains a weak reference to the document with
+ * which it is initialized. This call forces the reference to
+ * be dropped.
+ */
+ void DropDocumentReference() { mDocument = nullptr; }
+
+ /*
+ * Helper function to return the delegate info value for aPermissionName.
+ * @param aPermissionName the permission name to get
+ */
+ static const PermissionDelegateInfo* GetPermissionDelegateInfo(
+ const nsAString& aPermissionName);
+
+ /*
+ * Helper function to return the delegate principal. This will return nullptr,
+ * or request's principal or top level principal based on the delegate policy
+ * will be applied for a given type.
+ * We use this function when prompting, no need to perform permission check
+ * (deny/allow).
+ *
+ * @param aType the permission type to get
+ * @param aRequest The request which the principal is get from.
+ * @param aResult out argument which will be a principal that we
+ * will return from this function.
+ */
+ static nsresult GetDelegatePrincipal(const nsACString& aType,
+ nsIContentPermissionRequest* aRequest,
+ nsIPrincipal** aResult);
+
+ /**
+ * Populate all delegated permissions to the WindowContext of the associated
+ * document. We only populate the permissions for the top-level content.
+ */
+ void PopulateAllDelegatedPermissions();
+
+ /**
+ * Update the given delegated permission to the WindowContext. We only
+ * update it for the top-level content.
+ */
+ void UpdateDelegatedPermission(const nsACString& aType);
+
+ private:
+ ~PermissionDelegateHandler() = default;
+
+ /*
+ * Check whether the permission is blocked by FeaturePolicy directive.
+ * Default allowlist for a featureName of permission used in permissions
+ * delegate should be set to eSelf, to ensure that permission is denied by
+ * default and only have the opportunity to request permission with allow
+ * attribute.
+ */
+ bool HasFeaturePolicyAllowed(const PermissionDelegateInfo* info) const;
+
+ /**
+ * A helper function to test the permission and set the result to the given
+ * list. It will return true if the permission is changed, otherwise false.
+ */
+ bool UpdateDelegatePermissionInternal(
+ PermissionDelegateHandler::DelegatedPermissionList& aList,
+ const nsACString& aType, size_t aIdx,
+ nsresult (NS_STDCALL nsIPermissionManager::*aTestFunc)(nsIPrincipal*,
+ const nsACString&,
+ uint32_t*));
+
+ // A weak pointer to our document. Nulled out by DropDocumentReference.
+ mozilla::dom::Document* mDocument;
+
+ nsCOMPtr<nsIPrincipal> mPrincipal;
+ RefPtr<nsIPermissionManager> mPermissionManager;
+};
+
+} // namespace mozilla
+
+#endif // mozilla_PermissionDelegateHandler_h
diff --git a/extensions/permissions/PermissionDelegateIPCUtils.h b/extensions/permissions/PermissionDelegateIPCUtils.h
new file mode 100644
index 0000000000..c570a587f5
--- /dev/null
+++ b/extensions/permissions/PermissionDelegateIPCUtils.h
@@ -0,0 +1,40 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this file,
+ * You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef mozilla_permissiondelegateipcutils_h
+#define mozilla_permissiondelegateipcutils_h
+
+#include "ipc/IPCMessageUtils.h"
+
+#include "mozilla/PermissionDelegateHandler.h"
+
+namespace IPC {
+
+template <>
+struct ParamTraits<
+ mozilla::PermissionDelegateHandler::DelegatedPermissionList> {
+ typedef mozilla::PermissionDelegateHandler::DelegatedPermissionList paramType;
+
+ static void Write(MessageWriter* aWriter, const paramType& aParam) {
+ for (auto& permission : aParam.mPermissions) {
+ WriteParam(aWriter, permission);
+ }
+ }
+
+ static bool Read(MessageReader* aReader, paramType* aResult) {
+ for (auto& permission : aResult->mPermissions) {
+ if (!ReadParam(aReader, &permission)) {
+ return false;
+ }
+ }
+
+ return true;
+ }
+};
+
+} // namespace IPC
+
+#endif // mozilla_permissiondelegateipcutils_h
diff --git a/extensions/permissions/PermissionManager.cpp b/extensions/permissions/PermissionManager.cpp
new file mode 100644
index 0000000000..f81d823470
--- /dev/null
+++ b/extensions/permissions/PermissionManager.cpp
@@ -0,0 +1,3928 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "mozilla/AbstractThread.h"
+#include "mozilla/AppShutdown.h"
+#include "mozilla/BasePrincipal.h"
+#include "mozilla/ClearOnShutdown.h"
+#include "mozilla/ContentPrincipal.h"
+#include "mozilla/DebugOnly.h"
+#include "mozilla/dom/ContentParent.h"
+#include "mozilla/ExpandedPrincipal.h"
+#include "mozilla/net/NeckoMessageUtils.h"
+#include "mozilla/Permission.h"
+#include "mozilla/PermissionManager.h"
+#include "mozilla/Preferences.h"
+#include "mozilla/ScopeExit.h"
+#include "mozilla/StaticPrefs_permissions.h"
+#include "mozilla/Telemetry.h"
+
+#include "mozIStorageService.h"
+#include "mozIStorageConnection.h"
+#include "mozIStorageStatement.h"
+#include "mozStorageCID.h"
+
+#include "nsAppDirectoryServiceDefs.h"
+#include "nsComponentManagerUtils.h"
+#include "nsContentUtils.h"
+#include "nsCRT.h"
+#include "nsEffectiveTLDService.h"
+#include "nsIConsoleService.h"
+#include "nsIUserIdleService.h"
+#include "nsIInputStream.h"
+#include "nsINavHistoryService.h"
+#include "nsIObserverService.h"
+#include "nsIPrefBranch.h"
+#include "nsIPrincipal.h"
+#include "nsIURIMutator.h"
+#include "nsIWritablePropertyBag2.h"
+#include "nsReadLine.h"
+#include "nsTHashSet.h"
+#include "nsToolkitCompsCID.h"
+
+using namespace mozilla::dom;
+
+namespace mozilla {
+
+#define PERMISSIONS_FILE_NAME "permissions.sqlite"
+#define HOSTS_SCHEMA_VERSION 12
+
+// Default permissions are read from a URL - this is the preference we read
+// to find that URL. If not set, don't use any default permissions.
+constexpr char kDefaultsUrlPrefName[] = "permissions.manager.defaultsUrl";
+
+constexpr char kPermissionChangeNotification[] = PERM_CHANGE_NOTIFICATION;
+
+// A special value for a permission ID that indicates the ID was loaded as
+// a default value. These will never be written to the database, but may
+// be overridden with an explicit permission (including UNKNOWN_ACTION)
+constexpr int64_t cIDPermissionIsDefault = -1;
+
+static StaticRefPtr<PermissionManager> gPermissionManager;
+
+#define ENSURE_NOT_CHILD_PROCESS_(onError) \
+ PR_BEGIN_MACRO \
+ if (IsChildProcess()) { \
+ NS_ERROR("Cannot perform action in content process!"); \
+ onError \
+ } \
+ PR_END_MACRO
+
+#define ENSURE_NOT_CHILD_PROCESS \
+ ENSURE_NOT_CHILD_PROCESS_({ return NS_ERROR_NOT_AVAILABLE; })
+
+#define ENSURE_NOT_CHILD_PROCESS_NORET ENSURE_NOT_CHILD_PROCESS_(;)
+
+#define EXPIRY_NOW PR_Now() / 1000
+
+////////////////////////////////////////////////////////////////////////////////
+
+namespace {
+
+bool IsChildProcess() { return XRE_IsContentProcess(); }
+
+void LogToConsole(const nsAString& aMsg) {
+ nsCOMPtr<nsIConsoleService> console(
+ do_GetService("@mozilla.org/consoleservice;1"));
+ if (!console) {
+ NS_WARNING("Failed to log message to console.");
+ return;
+ }
+
+ nsAutoString msg(aMsg);
+ console->LogStringMessage(msg.get());
+}
+
+// NOTE: an empty string can be passed as aType - if it is this function will
+// return "false" unconditionally.
+bool HasDefaultPref(const nsACString& aType) {
+ // A list of permissions that can have a fallback default permission
+ // set under the permissions.default.* pref.
+ static const nsLiteralCString kPermissionsWithDefaults[] = {
+ "camera"_ns, "microphone"_ns, "geo"_ns, "desktop-notification"_ns,
+ "shortcuts"_ns};
+
+ if (!aType.IsEmpty()) {
+ for (const auto& perm : kPermissionsWithDefaults) {
+ if (perm.Equals(aType)) {
+ return true;
+ }
+ }
+ }
+
+ return false;
+}
+
+// These permissions are special permissions which must be transmitted to the
+// content process before documents with their principals have loaded within
+// that process.
+//
+// Permissions which are in this list are considered to have a "" permission
+// key, even if their principal would not normally have that key.
+static const nsLiteralCString kPreloadPermissions[] = {
+ // This permission is preloaded to support properly blocking service worker
+ // interception when a user has disabled storage for a specific site. Once
+ // service worker interception moves to the parent process this should be
+ // removed. See bug 1428130.
+ "cookie"_ns};
+
+// NOTE: nullptr can be passed as aType - if it is this function will return
+// "false" unconditionally.
+bool IsPreloadPermission(const nsACString& aType) {
+ if (!aType.IsEmpty()) {
+ for (const auto& perm : kPreloadPermissions) {
+ if (perm.Equals(aType)) {
+ return true;
+ }
+ }
+ }
+
+ return false;
+}
+
+// Array of permission types which should not be isolated by origin attributes,
+// for user context and private browsing.
+// Keep this array in sync with 'STRIPPED_PERMS' in
+// 'test_permmanager_oa_strip.js'
+// Currently only preloaded permissions are supported.
+// This is because perms are sent to the content process in bulk by perm key.
+// Non-preloaded, but OA stripped permissions would not be accessible by sites
+// in private browsing / non-default user context.
+static constexpr std::array<nsLiteralCString, 1> kStripOAPermissions = {
+ {"cookie"_ns}};
+
+bool IsOAForceStripPermission(const nsACString& aType) {
+ if (aType.IsEmpty()) {
+ return false;
+ }
+ for (const auto& perm : kStripOAPermissions) {
+ if (perm.Equals(aType)) {
+ return true;
+ }
+ }
+ return false;
+}
+
+// Array of permission prefixes which should be isolated only by site.
+// These site-scoped permissions are stored under their site's principal.
+// GetAllForPrincipal also needs to look for these especially.
+static constexpr std::array<nsLiteralCString, 2> kSiteScopedPermissions = {
+ {"3rdPartyStorage^"_ns, "AllowStorageAccessRequest^"_ns}};
+
+bool IsSiteScopedPermission(const nsACString& aType) {
+ if (aType.IsEmpty()) {
+ return false;
+ }
+ for (const auto& perm : kSiteScopedPermissions) {
+ if (aType.Length() >= perm.Length() &&
+ Substring(aType, 0, perm.Length()) == perm) {
+ return true;
+ }
+ }
+ return false;
+}
+
+void OriginAppendOASuffix(OriginAttributes aOriginAttributes,
+ bool aForceStripOA, nsACString& aOrigin) {
+ PermissionManager::MaybeStripOriginAttributes(aForceStripOA,
+ aOriginAttributes);
+
+ nsAutoCString oaSuffix;
+ aOriginAttributes.CreateSuffix(oaSuffix);
+ aOrigin.Append(oaSuffix);
+}
+
+nsresult GetOriginFromPrincipal(nsIPrincipal* aPrincipal, bool aForceStripOA,
+ nsACString& aOrigin) {
+ nsresult rv = aPrincipal->GetOriginNoSuffix(aOrigin);
+ // The principal may belong to the about:blank content viewer, so this can be
+ // expected to fail.
+ if (NS_FAILED(rv)) {
+ return rv;
+ }
+
+ nsAutoCString suffix;
+ rv = aPrincipal->GetOriginSuffix(suffix);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ OriginAttributes attrs;
+ NS_ENSURE_TRUE(attrs.PopulateFromSuffix(suffix), NS_ERROR_FAILURE);
+
+ OriginAppendOASuffix(attrs, aForceStripOA, aOrigin);
+
+ return NS_OK;
+}
+
+// Returns the site of the principal, including OA, given a principal.
+nsresult GetSiteFromPrincipal(nsIPrincipal* aPrincipal, bool aForceStripOA,
+ nsACString& aSite) {
+ nsCOMPtr<nsIURI> uri = aPrincipal->GetURI();
+ nsEffectiveTLDService* etld = nsEffectiveTLDService::GetInstance();
+ NS_ENSURE_TRUE(etld, NS_ERROR_FAILURE);
+ NS_ENSURE_TRUE(uri, NS_ERROR_FAILURE);
+ nsresult rv = etld->GetSite(uri, aSite);
+
+ // The principal may belong to the about:blank content viewer, so this can be
+ // expected to fail.
+ if (NS_FAILED(rv)) {
+ rv = aPrincipal->GetOrigin(aSite);
+ NS_ENSURE_SUCCESS(rv, rv);
+ return NS_OK;
+ }
+
+ nsAutoCString suffix;
+ rv = aPrincipal->GetOriginSuffix(suffix);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ OriginAttributes attrs;
+ NS_ENSURE_TRUE(attrs.PopulateFromSuffix(suffix), NS_ERROR_FAILURE);
+
+ OriginAppendOASuffix(attrs, aForceStripOA, aSite);
+
+ return NS_OK;
+}
+
+nsresult GetOriginFromURIAndOA(nsIURI* aURI,
+ const OriginAttributes* aOriginAttributes,
+ bool aForceStripOA, nsACString& aOrigin) {
+ nsAutoCString origin(aOrigin);
+ nsresult rv = ContentPrincipal::GenerateOriginNoSuffixFromURI(aURI, origin);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ OriginAppendOASuffix(*aOriginAttributes, aForceStripOA, origin);
+
+ aOrigin = origin;
+
+ return NS_OK;
+}
+
+nsresult GetPrincipalFromOrigin(const nsACString& aOrigin, bool aForceStripOA,
+ nsIPrincipal** aPrincipal) {
+ nsAutoCString originNoSuffix;
+ OriginAttributes attrs;
+ if (!attrs.PopulateFromOrigin(aOrigin, originNoSuffix)) {
+ return NS_ERROR_FAILURE;
+ }
+
+ PermissionManager::MaybeStripOriginAttributes(aForceStripOA, attrs);
+
+ nsCOMPtr<nsIURI> uri;
+ nsresult rv = NS_NewURI(getter_AddRefs(uri), originNoSuffix);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ nsCOMPtr<nsIPrincipal> principal =
+ BasePrincipal::CreateContentPrincipal(uri, attrs);
+ principal.forget(aPrincipal);
+ return NS_OK;
+}
+
+nsresult GetPrincipal(nsIURI* aURI, bool aIsInIsolatedMozBrowserElement,
+ nsIPrincipal** aPrincipal) {
+ OriginAttributes attrs(aIsInIsolatedMozBrowserElement);
+ nsCOMPtr<nsIPrincipal> principal =
+ BasePrincipal::CreateContentPrincipal(aURI, attrs);
+ NS_ENSURE_TRUE(principal, NS_ERROR_FAILURE);
+
+ principal.forget(aPrincipal);
+ return NS_OK;
+}
+
+nsresult GetPrincipal(nsIURI* aURI, nsIPrincipal** aPrincipal) {
+ OriginAttributes attrs;
+ nsCOMPtr<nsIPrincipal> principal =
+ BasePrincipal::CreateContentPrincipal(aURI, attrs);
+ NS_ENSURE_TRUE(principal, NS_ERROR_FAILURE);
+
+ principal.forget(aPrincipal);
+ return NS_OK;
+}
+
+nsCString GetNextSubDomainForHost(const nsACString& aHost) {
+ nsCString subDomain;
+ nsresult rv =
+ nsEffectiveTLDService::GetInstance()->GetNextSubDomain(aHost, subDomain);
+ // We can fail if there is no more subdomain or if the host can't have a
+ // subdomain.
+ if (NS_FAILED(rv)) {
+ return ""_ns;
+ }
+
+ return subDomain;
+}
+
+// This function produces a nsIURI which is identical to the current
+// nsIURI, except that it has one less subdomain segment. It returns
+// `nullptr` if there are no more segments to remove.
+already_AddRefed<nsIURI> GetNextSubDomainURI(nsIURI* aURI) {
+ nsAutoCString host;
+ nsresult rv = aURI->GetHost(host);
+ if (NS_FAILED(rv)) {
+ return nullptr;
+ }
+
+ nsCString domain = GetNextSubDomainForHost(host);
+ if (domain.IsEmpty()) {
+ return nullptr;
+ }
+
+ nsCOMPtr<nsIURI> uri;
+ rv = NS_MutateURI(aURI).SetHost(domain).Finalize(uri);
+ if (NS_FAILED(rv) || !uri) {
+ return nullptr;
+ }
+
+ return uri.forget();
+}
+
+nsresult UpgradeHostToOriginAndInsert(
+ const nsACString& aHost, const nsCString& aType, uint32_t aPermission,
+ uint32_t aExpireType, int64_t aExpireTime, int64_t aModificationTime,
+ bool aIsInIsolatedMozBrowserElement,
+ std::function<nsresult(const nsACString& aOrigin, const nsCString& aType,
+ uint32_t aPermission, uint32_t aExpireType,
+ int64_t aExpireTime, int64_t aModificationTime)>&&
+ aCallback) {
+ if (aHost.EqualsLiteral("<file>")) {
+ // We no longer support the magic host <file>
+ NS_WARNING(
+ "The magic host <file> is no longer supported. "
+ "It is being removed from the permissions database.");
+ return NS_OK;
+ }
+
+ // First, we check to see if the host is a valid URI. If it is, it can be
+ // imported directly
+ nsCOMPtr<nsIURI> uri;
+ nsresult rv = NS_NewURI(getter_AddRefs(uri), aHost);
+ if (NS_SUCCEEDED(rv)) {
+ // It was previously possible to insert useless entries to your permissions
+ // database for URIs which have a null principal. This acts as a cleanup,
+ // getting rid of these useless database entries
+ if (uri->SchemeIs("moz-nullprincipal")) {
+ NS_WARNING("A moz-nullprincipal: permission is being discarded.");
+ return NS_OK;
+ }
+
+ nsCOMPtr<nsIPrincipal> principal;
+ rv = GetPrincipal(uri, aIsInIsolatedMozBrowserElement,
+ getter_AddRefs(principal));
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ nsAutoCString origin;
+ rv = GetOriginFromPrincipal(principal, IsOAForceStripPermission(aType),
+ origin);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ aCallback(origin, aType, aPermission, aExpireType, aExpireTime,
+ aModificationTime);
+ return NS_OK;
+ }
+
+ // The user may use this host at non-standard ports or protocols, we can use
+ // their history to guess what ports and protocols we want to add permissions
+ // for. We find every URI which they have visited with this host (or a
+ // subdomain of this host), and try to add it as a principal.
+ bool foundHistory = false;
+
+ nsCOMPtr<nsINavHistoryService> histSrv =
+ do_GetService(NS_NAVHISTORYSERVICE_CONTRACTID);
+
+ if (histSrv) {
+ nsCOMPtr<nsINavHistoryQuery> histQuery;
+ rv = histSrv->GetNewQuery(getter_AddRefs(histQuery));
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ // Get the eTLD+1 of the domain
+ nsAutoCString eTLD1;
+ rv = nsEffectiveTLDService::GetInstance()->GetBaseDomainFromHost(aHost, 0,
+ eTLD1);
+
+ if (NS_FAILED(rv)) {
+ // If the lookup on the tldService for the base domain for the host
+ // failed, that means that we just want to directly use the host as the
+ // host name for the lookup.
+ eTLD1 = aHost;
+ }
+
+ // We want to only find history items for this particular eTLD+1, and
+ // subdomains
+ rv = histQuery->SetDomain(eTLD1);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ rv = histQuery->SetDomainIsHost(false);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ nsCOMPtr<nsINavHistoryQueryOptions> histQueryOpts;
+ rv = histSrv->GetNewQueryOptions(getter_AddRefs(histQueryOpts));
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ // We want to get the URIs for every item in the user's history with the
+ // given host
+ rv =
+ histQueryOpts->SetResultType(nsINavHistoryQueryOptions::RESULTS_AS_URI);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ // We only search history, because searching both bookmarks and history
+ // is not supported, and history tends to be more comprehensive.
+ rv = histQueryOpts->SetQueryType(
+ nsINavHistoryQueryOptions::QUERY_TYPE_HISTORY);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ // We include hidden URIs (such as those visited via iFrames) as they may
+ // have permissions too
+ rv = histQueryOpts->SetIncludeHidden(true);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ nsCOMPtr<nsINavHistoryResult> histResult;
+ rv = histSrv->ExecuteQuery(histQuery, histQueryOpts,
+ getter_AddRefs(histResult));
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ nsCOMPtr<nsINavHistoryContainerResultNode> histResultContainer;
+ rv = histResult->GetRoot(getter_AddRefs(histResultContainer));
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ rv = histResultContainer->SetContainerOpen(true);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ uint32_t childCount = 0;
+ rv = histResultContainer->GetChildCount(&childCount);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ nsTHashSet<nsCString> insertedOrigins;
+ for (uint32_t i = 0; i < childCount; i++) {
+ nsCOMPtr<nsINavHistoryResultNode> child;
+ histResultContainer->GetChild(i, getter_AddRefs(child));
+ if (NS_WARN_IF(NS_FAILED(rv))) continue;
+
+ uint32_t type;
+ rv = child->GetType(&type);
+ if (NS_WARN_IF(NS_FAILED(rv)) ||
+ type != nsINavHistoryResultNode::RESULT_TYPE_URI) {
+ NS_WARNING(
+ "Unexpected non-RESULT_TYPE_URI node in "
+ "UpgradeHostToOriginAndInsert()");
+ continue;
+ }
+
+ nsAutoCString uriSpec;
+ rv = child->GetUri(uriSpec);
+ if (NS_WARN_IF(NS_FAILED(rv))) continue;
+
+ nsCOMPtr<nsIURI> uri;
+ rv = NS_NewURI(getter_AddRefs(uri), uriSpec);
+ if (NS_WARN_IF(NS_FAILED(rv))) continue;
+
+ // Use the provided host - this URI may be for a subdomain, rather than
+ // the host we care about.
+ rv = NS_MutateURI(uri).SetHost(aHost).Finalize(uri);
+ if (NS_WARN_IF(NS_FAILED(rv))) continue;
+
+ // We now have a URI which we can make a nsIPrincipal out of
+ nsCOMPtr<nsIPrincipal> principal;
+ rv = GetPrincipal(uri, aIsInIsolatedMozBrowserElement,
+ getter_AddRefs(principal));
+ if (NS_WARN_IF(NS_FAILED(rv))) continue;
+
+ nsAutoCString origin;
+ rv = GetOriginFromPrincipal(principal, IsOAForceStripPermission(aType),
+ origin);
+ if (NS_WARN_IF(NS_FAILED(rv))) continue;
+
+ // Ensure that we don't insert the same origin repeatedly
+ if (insertedOrigins.Contains(origin)) {
+ continue;
+ }
+
+ foundHistory = true;
+ rv = aCallback(origin, aType, aPermission, aExpireType, aExpireTime,
+ aModificationTime);
+ NS_WARNING_ASSERTION(NS_SUCCEEDED(rv), "Insert failed");
+ insertedOrigins.Insert(origin);
+ }
+
+ rv = histResultContainer->SetContainerOpen(false);
+ NS_ENSURE_SUCCESS(rv, rv);
+ }
+
+ // If we didn't find any origins for this host in the poermissions database,
+ // we can insert the default http:// and https:// permissions into the
+ // database. This has a relatively high likelihood of applying the permission
+ // to the correct origin.
+ if (!foundHistory) {
+ nsAutoCString hostSegment;
+ nsCOMPtr<nsIPrincipal> principal;
+ nsAutoCString origin;
+
+ // If this is an ipv6 URI, we need to surround it in '[', ']' before trying
+ // to parse it as a URI.
+ if (aHost.FindChar(':') != -1) {
+ hostSegment.AssignLiteral("[");
+ hostSegment.Append(aHost);
+ hostSegment.AppendLiteral("]");
+ } else {
+ hostSegment.Assign(aHost);
+ }
+
+ // http:// URI default
+ rv = NS_NewURI(getter_AddRefs(uri), "http://"_ns + hostSegment);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ rv = GetPrincipal(uri, aIsInIsolatedMozBrowserElement,
+ getter_AddRefs(principal));
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ rv = GetOriginFromPrincipal(principal, IsOAForceStripPermission(aType),
+ origin);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ aCallback(origin, aType, aPermission, aExpireType, aExpireTime,
+ aModificationTime);
+
+ // https:// URI default
+ rv = NS_NewURI(getter_AddRefs(uri), "https://"_ns + hostSegment);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ rv = GetPrincipal(uri, aIsInIsolatedMozBrowserElement,
+ getter_AddRefs(principal));
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ rv = GetOriginFromPrincipal(principal, IsOAForceStripPermission(aType),
+ origin);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ aCallback(origin, aType, aPermission, aExpireType, aExpireTime,
+ aModificationTime);
+ }
+
+ return NS_OK;
+}
+
+bool IsExpandedPrincipal(nsIPrincipal* aPrincipal) {
+ nsCOMPtr<nsIExpandedPrincipal> ep = do_QueryInterface(aPrincipal);
+ return !!ep;
+}
+
+// We only want to persist permissions which don't have session or policy
+// expiration.
+bool IsPersistentExpire(uint32_t aExpire, const nsACString& aType) {
+ bool res = (aExpire != nsIPermissionManager::EXPIRE_SESSION &&
+ aExpire != nsIPermissionManager::EXPIRE_POLICY);
+ return res;
+}
+
+} // namespace
+
+////////////////////////////////////////////////////////////////////////////////
+
+PermissionManager::PermissionKey*
+PermissionManager::PermissionKey::CreateFromPrincipal(nsIPrincipal* aPrincipal,
+ bool aForceStripOA,
+ bool aScopeToSite,
+ nsresult& aResult) {
+ nsAutoCString keyString;
+ if (aScopeToSite) {
+ aResult = GetSiteFromPrincipal(aPrincipal, aForceStripOA, keyString);
+ } else {
+ aResult = GetOriginFromPrincipal(aPrincipal, aForceStripOA, keyString);
+ }
+ if (NS_WARN_IF(NS_FAILED(aResult))) {
+ return nullptr;
+ }
+ return new PermissionKey(keyString);
+}
+
+PermissionManager::PermissionKey*
+PermissionManager::PermissionKey::CreateFromURIAndOriginAttributes(
+ nsIURI* aURI, const OriginAttributes* aOriginAttributes, bool aForceStripOA,
+ nsresult& aResult) {
+ nsAutoCString origin;
+ aResult =
+ GetOriginFromURIAndOA(aURI, aOriginAttributes, aForceStripOA, origin);
+ if (NS_WARN_IF(NS_FAILED(aResult))) {
+ return nullptr;
+ }
+
+ return new PermissionKey(origin);
+}
+
+PermissionManager::PermissionKey*
+PermissionManager::PermissionKey::CreateFromURI(nsIURI* aURI,
+ nsresult& aResult) {
+ nsAutoCString origin;
+ aResult = ContentPrincipal::GenerateOriginNoSuffixFromURI(aURI, origin);
+ if (NS_WARN_IF(NS_FAILED(aResult))) {
+ return nullptr;
+ }
+
+ return new PermissionKey(origin);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// PermissionManager Implementation
+
+NS_IMPL_ISUPPORTS(PermissionManager, nsIPermissionManager, nsIObserver,
+ nsISupportsWeakReference, nsIAsyncShutdownBlocker)
+
+PermissionManager::PermissionManager()
+ : mMonitor("PermissionManager::mMonitor"),
+ mState(eInitializing),
+ mMemoryOnlyDB(false),
+ mLargestID(0) {}
+
+PermissionManager::~PermissionManager() {
+ // NOTE: Make sure to reject each of the promises in mPermissionKeyPromiseMap
+ // before destroying.
+ for (const auto& promise : mPermissionKeyPromiseMap.Values()) {
+ if (promise) {
+ promise->Reject(NS_ERROR_FAILURE, __func__);
+ }
+ }
+ mPermissionKeyPromiseMap.Clear();
+
+ if (mThread) {
+ mThread->Shutdown();
+ mThread = nullptr;
+ }
+}
+
+/* static */
+StaticMutex PermissionManager::sCreationMutex;
+
+// static
+already_AddRefed<nsIPermissionManager> PermissionManager::GetXPCOMSingleton() {
+ // The lazy initialization could race.
+ StaticMutexAutoLock lock(sCreationMutex);
+
+ if (gPermissionManager) {
+ return do_AddRef(gPermissionManager);
+ }
+
+ // Create a new singleton PermissionManager.
+ // We AddRef only once since XPCOM has rules about the ordering of module
+ // teardowns - by the time our module destructor is called, it's too late to
+ // Release our members, since GC cycles have already been completed and
+ // would result in serious leaks.
+ // See bug 209571.
+ auto permManager = MakeRefPtr<PermissionManager>();
+ if (NS_SUCCEEDED(permManager->Init())) {
+ gPermissionManager = permManager.get();
+ return permManager.forget();
+ }
+
+ return nullptr;
+}
+
+// static
+PermissionManager* PermissionManager::GetInstance() {
+ // TODO: There is a minimal chance that we can race here with a
+ // GetXPCOMSingleton call that did not yet set gPermissionManager.
+ // See bug 1745056.
+ if (!gPermissionManager) {
+ // Hand off the creation of the permission manager to GetXPCOMSingleton.
+ nsCOMPtr<nsIPermissionManager> permManager = GetXPCOMSingleton();
+ }
+
+ return gPermissionManager;
+}
+
+nsresult PermissionManager::Init() {
+ // If we are already shutting down, do not permit a creation.
+ // This must match the phase in GetAsyncShutdownBarrier.
+ if (AppShutdown::IsInOrBeyond(ShutdownPhase::XPCOMWillShutdown)) {
+ return NS_ERROR_ILLEGAL_DURING_SHUTDOWN;
+ }
+
+ // If the 'permissions.memory_only' pref is set to true, then don't write any
+ // permission settings to disk, but keep them in a memory-only database.
+ mMemoryOnlyDB = Preferences::GetBool("permissions.memory_only", false);
+
+ nsresult rv;
+ nsCOMPtr<nsIPrefService> prefService =
+ do_GetService(NS_PREFSERVICE_CONTRACTID, &rv);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ rv = prefService->GetBranch("permissions.default.",
+ getter_AddRefs(mDefaultPrefBranch));
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ if (IsChildProcess()) {
+ // Stop here; we don't need the DB in the child process. Instead we will be
+ // sent permissions as we need them by our parent process.
+ mState = eReady;
+
+ // We use ClearOnShutdown on the content process only because on the parent
+ // process we need to block the shutdown for the final closeDB() call.
+ ClearOnShutdown(&gPermissionManager);
+ return NS_OK;
+ }
+
+ nsCOMPtr<nsIObserverService> observerService = services::GetObserverService();
+ if (observerService) {
+ observerService->AddObserver(this, "profile-do-change", true);
+ observerService->AddObserver(this, "testonly-reload-permissions-from-disk",
+ true);
+ }
+
+ if (XRE_IsParentProcess()) {
+ nsCOMPtr<nsIAsyncShutdownClient> asc = GetAsyncShutdownBarrier();
+ if (!asc) {
+ return NS_ERROR_NOT_AVAILABLE;
+ }
+ nsAutoString blockerName;
+ MOZ_ALWAYS_SUCCEEDS(GetName(blockerName));
+
+ nsresult rv = asc->AddBlocker(
+ this, NS_LITERAL_STRING_FROM_CSTRING(__FILE__), __LINE__, blockerName);
+ NS_ENSURE_SUCCESS(rv, rv);
+ }
+
+ AddIdleDailyMaintenanceJob();
+
+ MOZ_ASSERT(!mThread);
+ NS_ENSURE_SUCCESS(NS_NewNamedThread("Permission", getter_AddRefs(mThread)),
+ NS_ERROR_FAILURE);
+
+ PRThread* prThread;
+ MOZ_ALWAYS_SUCCEEDS(mThread->GetPRThread(&prThread));
+ MOZ_ASSERT(prThread);
+
+ mThreadBoundData.Transfer(prThread);
+
+ InitDB(false);
+
+ return NS_OK;
+}
+
+nsresult PermissionManager::OpenDatabase(nsIFile* aPermissionsFile) {
+ MOZ_ASSERT(!NS_IsMainThread());
+ auto data = mThreadBoundData.Access();
+
+ nsresult rv;
+ nsCOMPtr<mozIStorageService> storage =
+ do_GetService(MOZ_STORAGE_SERVICE_CONTRACTID);
+ if (!storage) {
+ return NS_ERROR_UNEXPECTED;
+ }
+ // cache a connection to the hosts database
+ if (mMemoryOnlyDB) {
+ rv = storage->OpenSpecialDatabase(
+ kMozStorageMemoryStorageKey, VoidCString(),
+ mozIStorageService::CONNECTION_DEFAULT, getter_AddRefs(data->mDBConn));
+ } else {
+ rv = storage->OpenDatabase(aPermissionsFile,
+ mozIStorageService::CONNECTION_DEFAULT,
+ getter_AddRefs(data->mDBConn));
+ }
+ return rv;
+}
+
+void PermissionManager::InitDB(bool aRemoveFile) {
+ mState = eInitializing;
+
+ {
+ MonitorAutoLock lock(mMonitor);
+ mReadEntries.Clear();
+ }
+
+ auto readyIfFailed = MakeScopeExit([&]() {
+ // ignore failure here, since it's non-fatal (we can run fine without
+ // persistent storage - e.g. if there's no profile).
+ // XXX should we tell the user about this?
+ mState = eReady;
+ });
+
+ if (!mPermissionsFile) {
+ nsresult rv = NS_GetSpecialDirectory(NS_APP_PERMISSION_PARENT_DIR,
+ getter_AddRefs(mPermissionsFile));
+ if (NS_FAILED(rv)) {
+ rv = NS_GetSpecialDirectory(NS_APP_USER_PROFILE_50_DIR,
+ getter_AddRefs(mPermissionsFile));
+ if (NS_FAILED(rv)) {
+ return;
+ }
+ }
+
+ rv =
+ mPermissionsFile->AppendNative(nsLiteralCString(PERMISSIONS_FILE_NAME));
+ NS_ENSURE_SUCCESS_VOID(rv);
+ }
+
+ nsCOMPtr<nsIInputStream> defaultsInputStream = GetDefaultsInputStream();
+
+ RefPtr<PermissionManager> self = this;
+ mThread->Dispatch(NS_NewRunnableFunction(
+ "PermissionManager::InitDB", [self, aRemoveFile, defaultsInputStream] {
+ nsresult rv = self->TryInitDB(aRemoveFile, defaultsInputStream);
+ Unused << NS_WARN_IF(NS_FAILED(rv));
+
+ // This extra runnable calls EnsureReadCompleted to finialize the
+ // initialization. If there is something blocked by the monitor, it will
+ // be NOP.
+ NS_DispatchToMainThread(
+ NS_NewRunnableFunction("PermissionManager::InitDB-MainThread",
+ [self] { self->EnsureReadCompleted(); }));
+
+ self->mMonitor.Notify();
+ }));
+
+ readyIfFailed.release();
+}
+
+nsresult PermissionManager::TryInitDB(bool aRemoveFile,
+ nsIInputStream* aDefaultsInputStream) {
+ MOZ_ASSERT(!NS_IsMainThread());
+
+ MonitorAutoLock lock(mMonitor);
+
+ auto raii = MakeScopeExit([&]() {
+ if (aDefaultsInputStream) {
+ aDefaultsInputStream->Close();
+ }
+
+ mState = eDBInitialized;
+ });
+
+ auto data = mThreadBoundData.Access();
+
+ auto raiiFailure = MakeScopeExit([&]() {
+ if (data->mDBConn) {
+ DebugOnly<nsresult> rv = data->mDBConn->Close();
+ MOZ_ASSERT(NS_SUCCEEDED(rv));
+ data->mDBConn = nullptr;
+ }
+ });
+
+ nsresult rv;
+
+ if (aRemoveFile) {
+ bool exists = false;
+ rv = mPermissionsFile->Exists(&exists);
+ NS_ENSURE_SUCCESS(rv, rv);
+ if (exists) {
+ rv = mPermissionsFile->Remove(false);
+ NS_ENSURE_SUCCESS(rv, rv);
+ }
+ }
+
+ rv = OpenDatabase(mPermissionsFile);
+ if (rv == NS_ERROR_FILE_CORRUPTED) {
+ LogToConsole(u"permissions.sqlite is corrupted! Try again!"_ns);
+
+ // Add telemetry probe
+ Telemetry::Accumulate(Telemetry::PERMISSIONS_SQL_CORRUPTED, 1);
+
+ // delete corrupted permissions.sqlite and try again
+ rv = mPermissionsFile->Remove(false);
+ NS_ENSURE_SUCCESS(rv, rv);
+ LogToConsole(u"Corrupted permissions.sqlite has been removed."_ns);
+
+ rv = OpenDatabase(mPermissionsFile);
+ NS_ENSURE_SUCCESS(rv, rv);
+ LogToConsole(u"OpenDatabase to permissions.sqlite is successful!"_ns);
+ }
+
+ if (NS_WARN_IF(NS_FAILED(rv))) {
+ return rv;
+ }
+
+ bool ready;
+ data->mDBConn->GetConnectionReady(&ready);
+ if (!ready) {
+ LogToConsole(nsLiteralString(
+ u"Fail to get connection to permissions.sqlite! Try again!"));
+
+ // delete and try again
+ rv = mPermissionsFile->Remove(false);
+ NS_ENSURE_SUCCESS(rv, rv);
+ LogToConsole(u"Defective permissions.sqlite has been removed."_ns);
+
+ // Add telemetry probe
+ Telemetry::Accumulate(Telemetry::DEFECTIVE_PERMISSIONS_SQL_REMOVED, 1);
+
+ rv = OpenDatabase(mPermissionsFile);
+ NS_ENSURE_SUCCESS(rv, rv);
+ LogToConsole(u"OpenDatabase to permissions.sqlite is successful!"_ns);
+
+ data->mDBConn->GetConnectionReady(&ready);
+ if (!ready) return NS_ERROR_UNEXPECTED;
+ }
+
+ bool tableExists = false;
+ data->mDBConn->TableExists("moz_perms"_ns, &tableExists);
+ if (!tableExists) {
+ data->mDBConn->TableExists("moz_hosts"_ns, &tableExists);
+ }
+ if (!tableExists) {
+ rv = CreateTable();
+ NS_ENSURE_SUCCESS(rv, rv);
+ } else {
+ // table already exists; check the schema version before reading
+ int32_t dbSchemaVersion;
+ rv = data->mDBConn->GetSchemaVersion(&dbSchemaVersion);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ switch (dbSchemaVersion) {
+ // upgrading.
+ // every time you increment the database schema, you need to
+ // implement the upgrading code from the previous version to the
+ // new one. fall through to current version
+
+ case 1: {
+ // previous non-expiry version of database. Upgrade it by adding
+ // the expiration columns
+ rv = data->mDBConn->ExecuteSimpleSQL(
+ "ALTER TABLE moz_hosts ADD expireType INTEGER"_ns);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ rv = data->mDBConn->ExecuteSimpleSQL(
+ "ALTER TABLE moz_hosts ADD expireTime INTEGER"_ns);
+ NS_ENSURE_SUCCESS(rv, rv);
+ }
+
+ // fall through to the next upgrade
+ [[fallthrough]];
+
+ // TODO: we want to make default version as version 2 in order to
+ // fix bug 784875.
+ case 0:
+ case 2: {
+ // Add appId/isInBrowserElement fields.
+ rv = data->mDBConn->ExecuteSimpleSQL(
+ "ALTER TABLE moz_hosts ADD appId INTEGER"_ns);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ rv = data->mDBConn->ExecuteSimpleSQL(nsLiteralCString(
+ "ALTER TABLE moz_hosts ADD isInBrowserElement INTEGER"));
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ rv = data->mDBConn->SetSchemaVersion(3);
+ NS_ENSURE_SUCCESS(rv, rv);
+ }
+
+ // fall through to the next upgrade
+ [[fallthrough]];
+
+ // Version 3->4 is the creation of the modificationTime field.
+ case 3: {
+ rv = data->mDBConn->ExecuteSimpleSQL(nsLiteralCString(
+ "ALTER TABLE moz_hosts ADD modificationTime INTEGER"));
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ // We leave the modificationTime at zero for all existing records;
+ // using now() would mean, eg, that doing "remove all from the
+ // last hour" within the first hour after migration would remove
+ // all permissions.
+
+ rv = data->mDBConn->SetSchemaVersion(4);
+ NS_ENSURE_SUCCESS(rv, rv);
+ }
+
+ // fall through to the next upgrade
+ [[fallthrough]];
+
+ // In version 5, host appId, and isInBrowserElement were merged into
+ // a single origin entry
+ //
+ // In version 6, the tables were renamed for backwards compatability
+ // reasons with version 4 and earlier.
+ //
+ // In version 7, a bug in the migration used for version 4->5 was
+ // discovered which could have triggered data-loss. Because of that,
+ // all users with a version 4, 5, or 6 database will be re-migrated
+ // from the backup database. (bug 1186034). This migration bug is
+ // not present after bug 1185340, and the re-migration ensures that
+ // all users have the fix.
+ case 5:
+ // This branch could also be reached via dbSchemaVersion == 3, in
+ // which case we want to fall through to the dbSchemaVersion == 4
+ // case. The easiest way to do that is to perform this extra check
+ // here to make sure that we didn't get here via a fallthrough
+ // from v3
+ if (dbSchemaVersion == 5) {
+ // In version 5, the backup database is named moz_hosts_v4. We
+ // perform the version 5->6 migration to get the tables to have
+ // consistent naming conventions.
+
+ // Version 5->6 is the renaming of moz_hosts to moz_perms, and
+ // moz_hosts_v4 to moz_hosts (bug 1185343)
+ //
+ // In version 5, we performed the modifications to the
+ // permissions database in place, this meant that if you
+ // upgraded to a version which used V5, and then downgraded to a
+ // version which used v4 or earlier, the fallback path would
+ // drop the table, and your permissions data would be lost. This
+ // migration undoes that mistake, by restoring the old moz_hosts
+ // table (if it was present), and instead using the new table
+ // moz_perms for the new permissions schema.
+ //
+ // NOTE: If you downgrade, store new permissions, and then
+ // upgrade again, these new permissions won't be migrated or
+ // reflected in the updated database. This migration only occurs
+ // once, as if moz_perms exists, it will skip creating it. In
+ // addition, permissions added after the migration will not be
+ // visible in previous versions of firefox.
+
+ bool permsTableExists = false;
+ data->mDBConn->TableExists("moz_perms"_ns, &permsTableExists);
+ if (!permsTableExists) {
+ // Move the upgraded database to moz_perms
+ rv = data->mDBConn->ExecuteSimpleSQL(
+ "ALTER TABLE moz_hosts RENAME TO moz_perms"_ns);
+ NS_ENSURE_SUCCESS(rv, rv);
+ } else {
+ NS_WARNING(
+ "moz_hosts was not renamed to moz_perms, "
+ "as a moz_perms table already exists");
+
+ // In the situation where a moz_perms table already exists,
+ // but the schema is lower than 6, a migration has already
+ // previously occured to V6, but a downgrade has caused the
+ // moz_hosts table to be dropped. This should only occur in
+ // the case of a downgrade to a V5 database, which was only
+ // present in a few day's nightlies. As that version was
+ // likely used only on a temporary basis, we assume that the
+ // database from the previous V6 has the permissions which the
+ // user actually wants to use. We have to get rid of moz_hosts
+ // such that moz_hosts_v4 can be moved into its place if it
+ // exists.
+ rv = data->mDBConn->ExecuteSimpleSQL("DROP TABLE moz_hosts"_ns);
+ NS_ENSURE_SUCCESS(rv, rv);
+ }
+
+#ifdef DEBUG
+ // The moz_hosts table shouldn't exist anymore
+ bool hostsTableExists = false;
+ data->mDBConn->TableExists("moz_hosts"_ns, &hostsTableExists);
+ MOZ_ASSERT(!hostsTableExists);
+#endif
+
+ // Rename moz_hosts_v4 back to it's original location, if it
+ // exists
+ bool v4TableExists = false;
+ data->mDBConn->TableExists("moz_hosts_v4"_ns, &v4TableExists);
+ if (v4TableExists) {
+ rv = data->mDBConn->ExecuteSimpleSQL(nsLiteralCString(
+ "ALTER TABLE moz_hosts_v4 RENAME TO moz_hosts"));
+ NS_ENSURE_SUCCESS(rv, rv);
+ }
+
+ rv = data->mDBConn->SetSchemaVersion(6);
+ NS_ENSURE_SUCCESS(rv, rv);
+ }
+
+ // fall through to the next upgrade
+ [[fallthrough]];
+
+ // At this point, the version 5 table has been migrated to a version
+ // 6 table We are guaranteed to have at least one of moz_hosts and
+ // moz_perms. If we have moz_hosts, we will migrate moz_hosts into
+ // moz_perms (even if we already have a moz_perms, as we need a
+ // re-migration due to bug 1186034).
+ //
+ // After this migration, we are guaranteed to have both a moz_hosts
+ // (for backwards compatability), and a moz_perms table. The
+ // moz_hosts table will have a v4 schema, and the moz_perms table
+ // will have a v6 schema.
+ case 4:
+ case 6: {
+ bool hostsTableExists = false;
+ data->mDBConn->TableExists("moz_hosts"_ns, &hostsTableExists);
+ if (hostsTableExists) {
+ // Both versions 4 and 6 have a version 4 formatted hosts table
+ // named moz_hosts. We can migrate this table to our version 7
+ // table moz_perms. If moz_perms is present, then we can use it
+ // as a basis for comparison.
+
+ rv = data->mDBConn->BeginTransaction();
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ bool tableExists = false;
+ data->mDBConn->TableExists("moz_hosts_new"_ns, &tableExists);
+ if (tableExists) {
+ NS_WARNING(
+ "The temporary database moz_hosts_new already exists, "
+ "dropping "
+ "it.");
+ rv = data->mDBConn->ExecuteSimpleSQL("DROP TABLE moz_hosts_new"_ns);
+ NS_ENSURE_SUCCESS(rv, rv);
+ }
+ rv = data->mDBConn->ExecuteSimpleSQL(
+ nsLiteralCString("CREATE TABLE moz_hosts_new ("
+ " id INTEGER PRIMARY KEY"
+ ",origin TEXT"
+ ",type TEXT"
+ ",permission INTEGER"
+ ",expireType INTEGER"
+ ",expireTime INTEGER"
+ ",modificationTime INTEGER"
+ ")"));
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ nsCOMPtr<mozIStorageStatement> stmt;
+ rv = data->mDBConn->CreateStatement(
+ nsLiteralCString(
+ "SELECT host, type, permission, expireType, "
+ "expireTime, "
+ "modificationTime, isInBrowserElement FROM moz_hosts"),
+ getter_AddRefs(stmt));
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ int64_t id = 0;
+ bool hasResult;
+
+ while (NS_SUCCEEDED(stmt->ExecuteStep(&hasResult)) && hasResult) {
+ MigrationEntry entry;
+
+ // Read in the old row
+ rv = stmt->GetUTF8String(0, entry.mHost);
+ if (NS_WARN_IF(NS_FAILED(rv))) {
+ continue;
+ }
+ rv = stmt->GetUTF8String(1, entry.mType);
+ if (NS_WARN_IF(NS_FAILED(rv))) {
+ continue;
+ }
+
+ entry.mId = id++;
+ entry.mPermission = stmt->AsInt32(2);
+ entry.mExpireType = stmt->AsInt32(3);
+ entry.mExpireTime = stmt->AsInt64(4);
+ entry.mModificationTime = stmt->AsInt64(5);
+ entry.mIsInBrowserElement = static_cast<bool>(stmt->AsInt32(6));
+
+ mMigrationEntries.AppendElement(entry);
+ }
+
+ // We don't drop the moz_hosts table such that it is available
+ // for backwards-compatability and for future migrations in case
+ // of migration errors in the current code. Create a marker
+ // empty table which will indicate that the moz_hosts table is
+ // intended to act as a backup. If this table is not present,
+ // then the moz_hosts table was created as a random empty table.
+ rv = data->mDBConn->ExecuteSimpleSQL(
+ nsLiteralCString("CREATE TABLE moz_hosts_is_backup (dummy "
+ "INTEGER PRIMARY KEY)"));
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ bool permsTableExists = false;
+ data->mDBConn->TableExists("moz_perms"_ns, &permsTableExists);
+ if (permsTableExists) {
+ // The user already had a moz_perms table, and we are
+ // performing a re-migration. We count the rows in the old
+ // table for telemetry, and then back up their old database as
+ // moz_perms_v6
+
+ nsCOMPtr<mozIStorageStatement> countStmt;
+ rv = data->mDBConn->CreateStatement(
+ "SELECT COUNT(*) FROM moz_perms"_ns, getter_AddRefs(countStmt));
+ bool hasResult = false;
+ if (NS_FAILED(rv) ||
+ NS_FAILED(countStmt->ExecuteStep(&hasResult)) || !hasResult) {
+ NS_WARNING("Could not count the rows in moz_perms");
+ }
+
+ // Back up the old moz_perms database as moz_perms_v6 before
+ // we move the new table into its position
+ rv = data->mDBConn->ExecuteSimpleSQL(nsLiteralCString(
+ "ALTER TABLE moz_perms RENAME TO moz_perms_v6"));
+ NS_ENSURE_SUCCESS(rv, rv);
+ }
+
+ rv = data->mDBConn->ExecuteSimpleSQL(nsLiteralCString(
+ "ALTER TABLE moz_hosts_new RENAME TO moz_perms"));
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ rv = data->mDBConn->CommitTransaction();
+ NS_ENSURE_SUCCESS(rv, rv);
+ } else {
+ // We don't have a moz_hosts table, so we create one for
+ // downgrading purposes. This table is empty.
+ rv = data->mDBConn->ExecuteSimpleSQL(
+ nsLiteralCString("CREATE TABLE moz_hosts ("
+ " id INTEGER PRIMARY KEY"
+ ",host TEXT"
+ ",type TEXT"
+ ",permission INTEGER"
+ ",expireType INTEGER"
+ ",expireTime INTEGER"
+ ",modificationTime INTEGER"
+ ",appId INTEGER"
+ ",isInBrowserElement INTEGER"
+ ")"));
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ // We are guaranteed to have a moz_perms table at this point.
+ }
+
+#ifdef DEBUG
+ {
+ // At this point, both the moz_hosts and moz_perms tables should
+ // exist
+ bool hostsTableExists = false;
+ bool permsTableExists = false;
+ data->mDBConn->TableExists("moz_hosts"_ns, &hostsTableExists);
+ data->mDBConn->TableExists("moz_perms"_ns, &permsTableExists);
+ MOZ_ASSERT(hostsTableExists && permsTableExists);
+ }
+#endif
+
+ rv = data->mDBConn->SetSchemaVersion(7);
+ NS_ENSURE_SUCCESS(rv, rv);
+ }
+
+ // fall through to the next upgrade
+ [[fallthrough]];
+
+ // The version 7-8 migration is the re-migration of localhost and
+ // ip-address entries due to errors in the previous version 7
+ // migration which caused localhost and ip-address entries to be
+ // incorrectly discarded. The version 7 migration logic has been
+ // corrected, and thus this logic only needs to execute if the user
+ // is currently on version 7.
+ case 7: {
+ // This migration will be relatively expensive as we need to
+ // perform database lookups for each origin which we want to
+ // insert. Fortunately, it shouldn't be too expensive as we only
+ // want to insert a small number of entries created for localhost
+ // or IP addresses.
+
+ // We only want to perform the re-migration if moz_hosts is a
+ // backup
+ bool hostsIsBackupExists = false;
+ data->mDBConn->TableExists("moz_hosts_is_backup"_ns,
+ &hostsIsBackupExists);
+
+ // Only perform this migration if the original schema version was
+ // 7, and the moz_hosts table is a backup.
+ if (dbSchemaVersion == 7 && hostsIsBackupExists) {
+ nsCOMPtr<mozIStorageStatement> stmt;
+ rv = data->mDBConn->CreateStatement(
+ nsLiteralCString(
+ "SELECT host, type, permission, expireType, "
+ "expireTime, "
+ "modificationTime, isInBrowserElement FROM moz_hosts"),
+ getter_AddRefs(stmt));
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ nsCOMPtr<mozIStorageStatement> idStmt;
+ rv = data->mDBConn->CreateStatement(
+ "SELECT MAX(id) FROM moz_hosts"_ns, getter_AddRefs(idStmt));
+
+ int64_t id = 0;
+ bool hasResult = false;
+ if (NS_SUCCEEDED(rv) &&
+ NS_SUCCEEDED(idStmt->ExecuteStep(&hasResult)) && hasResult) {
+ id = idStmt->AsInt32(0) + 1;
+ }
+
+ while (NS_SUCCEEDED(stmt->ExecuteStep(&hasResult)) && hasResult) {
+ MigrationEntry entry;
+
+ // Read in the old row
+ rv = stmt->GetUTF8String(0, entry.mHost);
+ if (NS_WARN_IF(NS_FAILED(rv))) {
+ continue;
+ }
+
+ nsAutoCString eTLD1;
+ rv = nsEffectiveTLDService::GetInstance()->GetBaseDomainFromHost(
+ entry.mHost, 0, eTLD1);
+ if (NS_SUCCEEDED(rv)) {
+ // We only care about entries which the tldService can't
+ // handle
+ continue;
+ }
+
+ rv = stmt->GetUTF8String(1, entry.mType);
+ if (NS_WARN_IF(NS_FAILED(rv))) {
+ continue;
+ }
+
+ entry.mId = id++;
+ entry.mPermission = stmt->AsInt32(2);
+ entry.mExpireType = stmt->AsInt32(3);
+ entry.mExpireTime = stmt->AsInt64(4);
+ entry.mModificationTime = stmt->AsInt64(5);
+ entry.mIsInBrowserElement = static_cast<bool>(stmt->AsInt32(6));
+
+ mMigrationEntries.AppendElement(entry);
+ }
+ }
+
+ // Even if we didn't perform the migration, we want to bump the
+ // schema version to 8.
+ rv = data->mDBConn->SetSchemaVersion(8);
+ NS_ENSURE_SUCCESS(rv, rv);
+ }
+
+ // fall through to the next upgrade
+ [[fallthrough]];
+
+ // The version 8-9 migration removes the unnecessary backup
+ // moz-hosts database contents. as the data no longer needs to be
+ // migrated
+ case 8: {
+ // We only want to clear out the old table if it is a backup. If
+ // it isn't a backup, we don't need to touch it.
+ bool hostsIsBackupExists = false;
+ data->mDBConn->TableExists("moz_hosts_is_backup"_ns,
+ &hostsIsBackupExists);
+ if (hostsIsBackupExists) {
+ // Delete everything from the backup, we want to keep around the
+ // table so that you can still downgrade and not break things,
+ // but we don't need to keep the rows around.
+ rv = data->mDBConn->ExecuteSimpleSQL("DELETE FROM moz_hosts"_ns);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ // The table is no longer a backup, so get rid of it.
+ rv = data->mDBConn->ExecuteSimpleSQL(
+ "DROP TABLE moz_hosts_is_backup"_ns);
+ NS_ENSURE_SUCCESS(rv, rv);
+ }
+
+ rv = data->mDBConn->SetSchemaVersion(9);
+ NS_ENSURE_SUCCESS(rv, rv);
+ }
+
+ // fall through to the next upgrade
+ [[fallthrough]];
+
+ case 9: {
+ rv = data->mDBConn->SetSchemaVersion(10);
+ NS_ENSURE_SUCCESS(rv, rv);
+ }
+
+ // fall through to the next upgrade
+ [[fallthrough]];
+
+ case 10: {
+ // Filter out the rows with storage access API permissions with a
+ // granted origin, and remove the granted origin part from the
+ // permission type.
+ rv = data->mDBConn->ExecuteSimpleSQL(nsLiteralCString(
+ "UPDATE moz_perms "
+ "SET type=SUBSTR(type, 0, INSTR(SUBSTR(type, INSTR(type, "
+ "'^') + "
+ "1), '^') + INSTR(type, '^')) "
+ "WHERE INSTR(SUBSTR(type, INSTR(type, '^') + 1), '^') AND "
+ "SUBSTR(type, 0, 18) == \"storageAccessAPI^\";"));
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ rv = data->mDBConn->SetSchemaVersion(11);
+ NS_ENSURE_SUCCESS(rv, rv);
+ }
+
+ // fall through to the next upgrade
+ [[fallthrough]];
+
+ case 11: {
+ // Migrate 3rdPartyStorage keys to a site scope
+ rv = data->mDBConn->BeginTransaction();
+ NS_ENSURE_SUCCESS(rv, rv);
+ nsCOMPtr<mozIStorageStatement> updateStmt;
+ rv = data->mDBConn->CreateStatement(
+ nsLiteralCString("UPDATE moz_perms SET origin = ?2 WHERE id = ?1"),
+ getter_AddRefs(updateStmt));
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ nsCOMPtr<mozIStorageStatement> deleteStmt;
+ rv = data->mDBConn->CreateStatement(
+ nsLiteralCString("DELETE FROM moz_perms WHERE id = ?1"),
+ getter_AddRefs(deleteStmt));
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ nsCOMPtr<mozIStorageStatement> selectStmt;
+ rv = data->mDBConn->CreateStatement(
+ nsLiteralCString("SELECT id, origin, type FROM moz_perms WHERE "
+ " SUBSTR(type, 0, 17) == \"3rdPartyStorage^\""),
+ getter_AddRefs(selectStmt));
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ nsTHashSet<nsCStringHashKey> deduplicationSet;
+ bool hasResult;
+ while (NS_SUCCEEDED(selectStmt->ExecuteStep(&hasResult)) && hasResult) {
+ int64_t id;
+ rv = selectStmt->GetInt64(0, &id);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ nsCString origin;
+ rv = selectStmt->GetUTF8String(1, origin);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ nsCString type;
+ rv = selectStmt->GetUTF8String(2, type);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ nsCOMPtr<nsIURI> uri;
+ rv = NS_NewURI(getter_AddRefs(uri), origin);
+ if (NS_FAILED(rv)) {
+ continue;
+ }
+ nsCString site;
+ rv = nsEffectiveTLDService::GetInstance()->GetSite(uri, site);
+ if (NS_WARN_IF(NS_FAILED(rv))) {
+ continue;
+ }
+
+ nsCString deduplicationKey =
+ nsPrintfCString("%s,%s", site.get(), type.get());
+ if (deduplicationSet.Contains(deduplicationKey)) {
+ rv = deleteStmt->BindInt64ByIndex(0, id);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ rv = deleteStmt->Execute();
+ NS_ENSURE_SUCCESS(rv, rv);
+ } else {
+ deduplicationSet.Insert(deduplicationKey);
+ rv = updateStmt->BindInt64ByIndex(0, id);
+ NS_ENSURE_SUCCESS(rv, rv);
+ rv = updateStmt->BindUTF8StringByIndex(1, site);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ rv = updateStmt->Execute();
+ NS_ENSURE_SUCCESS(rv, rv);
+ }
+ }
+ rv = data->mDBConn->CommitTransaction();
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ rv = data->mDBConn->SetSchemaVersion(HOSTS_SCHEMA_VERSION);
+ NS_ENSURE_SUCCESS(rv, rv);
+ }
+
+ // fall through to the next upgrade
+ [[fallthrough]];
+
+ // current version.
+ case HOSTS_SCHEMA_VERSION:
+ break;
+
+ // downgrading.
+ // if columns have been added to the table, we can still use the
+ // ones we understand safely. if columns have been deleted or
+ // altered, just blow away the table and start from scratch! if you
+ // change the way a column is interpreted, make sure you also change
+ // its name so this check will catch it.
+ default: {
+ // check if all the expected columns exist
+ nsCOMPtr<mozIStorageStatement> stmt;
+ rv = data->mDBConn->CreateStatement(
+ nsLiteralCString("SELECT origin, type, permission, "
+ "expireType, expireTime, "
+ "modificationTime FROM moz_perms"),
+ getter_AddRefs(stmt));
+ if (NS_SUCCEEDED(rv)) break;
+
+ // our columns aren't there - drop the table!
+ rv = data->mDBConn->ExecuteSimpleSQL("DROP TABLE moz_perms"_ns);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ rv = CreateTable();
+ NS_ENSURE_SUCCESS(rv, rv);
+ } break;
+ }
+ }
+
+ // cache frequently used statements (for insertion, deletion, and
+ // updating)
+ rv = data->mDBConn->CreateStatement(
+ nsLiteralCString("INSERT INTO moz_perms "
+ "(id, origin, type, permission, expireType, "
+ "expireTime, modificationTime) "
+ "VALUES (?1, ?2, ?3, ?4, ?5, ?6, ?7)"),
+ getter_AddRefs(data->mStmtInsert));
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ rv = data->mDBConn->CreateStatement(nsLiteralCString("DELETE FROM moz_perms "
+ "WHERE id = ?1"),
+ getter_AddRefs(data->mStmtDelete));
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ rv = data->mDBConn->CreateStatement(
+ nsLiteralCString("UPDATE moz_perms "
+ "SET permission = ?2, expireType= ?3, expireTime = "
+ "?4, modificationTime = ?5 WHERE id = ?1"),
+ getter_AddRefs(data->mStmtUpdate));
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ // Always import default permissions.
+ ConsumeDefaultsInputStream(aDefaultsInputStream, lock);
+
+ // check whether to import or just read in the db
+ if (tableExists) {
+ rv = Read(lock);
+ NS_ENSURE_SUCCESS(rv, rv);
+ }
+
+ raiiFailure.release();
+
+ return NS_OK;
+}
+
+void PermissionManager::AddIdleDailyMaintenanceJob() {
+ MOZ_ASSERT(NS_IsMainThread());
+
+ nsCOMPtr<nsIObserverService> observerService = services::GetObserverService();
+ NS_ENSURE_TRUE_VOID(observerService);
+
+ nsresult rv =
+ observerService->AddObserver(this, OBSERVER_TOPIC_IDLE_DAILY, false);
+ NS_ENSURE_SUCCESS_VOID(rv);
+}
+
+void PermissionManager::RemoveIdleDailyMaintenanceJob() {
+ MOZ_ASSERT(NS_IsMainThread());
+
+ nsCOMPtr<nsIObserverService> observerService = services::GetObserverService();
+ NS_ENSURE_TRUE_VOID(observerService);
+
+ nsresult rv =
+ observerService->RemoveObserver(this, OBSERVER_TOPIC_IDLE_DAILY);
+ NS_ENSURE_SUCCESS_VOID(rv);
+}
+
+void PermissionManager::PerformIdleDailyMaintenance() {
+ MOZ_ASSERT(NS_IsMainThread());
+
+ RefPtr<PermissionManager> self = this;
+ mThread->Dispatch(NS_NewRunnableFunction(
+ "PermissionManager::PerformIdleDailyMaintenance", [self] {
+ auto data = self->mThreadBoundData.Access();
+
+ if (self->mState == eClosed || !data->mDBConn) {
+ return;
+ }
+
+ nsCOMPtr<mozIStorageStatement> stmtDeleteExpired;
+ nsresult rv = data->mDBConn->CreateStatement(
+ nsLiteralCString("DELETE FROM moz_perms WHERE expireType = "
+ "?1 AND expireTime <= ?2"),
+ getter_AddRefs(stmtDeleteExpired));
+ NS_ENSURE_SUCCESS_VOID(rv);
+
+ rv = stmtDeleteExpired->BindInt32ByIndex(
+ 0, nsIPermissionManager::EXPIRE_TIME);
+ NS_ENSURE_SUCCESS_VOID(rv);
+
+ rv = stmtDeleteExpired->BindInt64ByIndex(1, EXPIRY_NOW);
+ NS_ENSURE_SUCCESS_VOID(rv);
+
+ rv = stmtDeleteExpired->Execute();
+ NS_ENSURE_SUCCESS_VOID(rv);
+ }));
+}
+
+// sets the schema version and creates the moz_perms table.
+nsresult PermissionManager::CreateTable() {
+ MOZ_ASSERT(!NS_IsMainThread());
+ auto data = mThreadBoundData.Access();
+
+ // set the schema version, before creating the table
+ nsresult rv = data->mDBConn->SetSchemaVersion(HOSTS_SCHEMA_VERSION);
+ if (NS_FAILED(rv)) return rv;
+
+ // create the table
+ // SQL also lives in automation.py.in. If you change this SQL change that
+ // one too
+ rv = data->mDBConn->ExecuteSimpleSQL(
+ nsLiteralCString("CREATE TABLE moz_perms ("
+ " id INTEGER PRIMARY KEY"
+ ",origin TEXT"
+ ",type TEXT"
+ ",permission INTEGER"
+ ",expireType INTEGER"
+ ",expireTime INTEGER"
+ ",modificationTime INTEGER"
+ ")"));
+ if (NS_FAILED(rv)) return rv;
+
+ // We also create a legacy V4 table, for backwards compatability,
+ // and to ensure that downgrades don't trigger a schema version change.
+ return data->mDBConn->ExecuteSimpleSQL(
+ nsLiteralCString("CREATE TABLE moz_hosts ("
+ " id INTEGER PRIMARY KEY"
+ ",host TEXT"
+ ",type TEXT"
+ ",permission INTEGER"
+ ",expireType INTEGER"
+ ",expireTime INTEGER"
+ ",modificationTime INTEGER"
+ ",isInBrowserElement INTEGER"
+ ")"));
+}
+
+// Returns whether the given combination of expire type and expire time are
+// expired. Note that EXPIRE_SESSION only honors expireTime if it is nonzero.
+bool PermissionManager::HasExpired(uint32_t aExpireType, int64_t aExpireTime) {
+ return (aExpireType == nsIPermissionManager::EXPIRE_TIME ||
+ (aExpireType == nsIPermissionManager::EXPIRE_SESSION &&
+ aExpireTime != 0)) &&
+ aExpireTime <= EXPIRY_NOW;
+}
+
+NS_IMETHODIMP
+PermissionManager::AddFromPrincipalAndPersistInPrivateBrowsing(
+ nsIPrincipal* aPrincipal, const nsACString& aType, uint32_t aPermission) {
+ ENSURE_NOT_CHILD_PROCESS;
+ NS_ENSURE_ARG_POINTER(aPrincipal);
+ // We don't add the system principal because it actually has no URI and we
+ // always allow action for them.
+ if (aPrincipal->IsSystemPrincipal()) {
+ return NS_OK;
+ }
+
+ // Null principals can't meaningfully have persisted permissions attached to
+ // them, so we don't allow adding permissions for them.
+ if (aPrincipal->GetIsNullPrincipal()) {
+ return NS_OK;
+ }
+
+ // Permissions may not be added to expanded principals.
+ if (IsExpandedPrincipal(aPrincipal)) {
+ return NS_ERROR_INVALID_ARG;
+ }
+
+ // A modificationTime of zero will cause AddInternal to use now().
+ int64_t modificationTime = 0;
+
+ return AddInternal(aPrincipal, aType, aPermission, 0,
+ nsIPermissionManager::EXPIRE_NEVER,
+ /* aExpireTime */ 0, modificationTime, eNotify, eWriteToDB,
+ /* aIgnoreSessionPermissions */ false,
+ /* aOriginString*/ nullptr,
+ /* aAllowPersistInPrivateBrowsing */ true);
+}
+
+NS_IMETHODIMP
+PermissionManager::AddFromPrincipal(nsIPrincipal* aPrincipal,
+ const nsACString& aType,
+ uint32_t aPermission, uint32_t aExpireType,
+ int64_t aExpireTime) {
+ ENSURE_NOT_CHILD_PROCESS;
+ NS_ENSURE_ARG_POINTER(aPrincipal);
+ NS_ENSURE_TRUE(aExpireType == nsIPermissionManager::EXPIRE_NEVER ||
+ aExpireType == nsIPermissionManager::EXPIRE_TIME ||
+ aExpireType == nsIPermissionManager::EXPIRE_SESSION ||
+ aExpireType == nsIPermissionManager::EXPIRE_POLICY,
+ NS_ERROR_INVALID_ARG);
+
+ // Skip addition if the permission is already expired.
+ if (HasExpired(aExpireType, aExpireTime)) {
+ return NS_OK;
+ }
+
+ // We don't add the system principal because it actually has no URI and we
+ // always allow action for them.
+ if (aPrincipal->IsSystemPrincipal()) {
+ return NS_OK;
+ }
+
+ // Null principals can't meaningfully have persisted permissions attached to
+ // them, so we don't allow adding permissions for them.
+ if (aPrincipal->GetIsNullPrincipal()) {
+ return NS_OK;
+ }
+
+ // Permissions may not be added to expanded principals.
+ if (IsExpandedPrincipal(aPrincipal)) {
+ return NS_ERROR_INVALID_ARG;
+ }
+
+ // A modificationTime of zero will cause AddInternal to use now().
+ int64_t modificationTime = 0;
+
+ return AddInternal(aPrincipal, aType, aPermission, 0, aExpireType,
+ aExpireTime, modificationTime, eNotify, eWriteToDB);
+}
+
+nsresult PermissionManager::AddInternal(
+ nsIPrincipal* aPrincipal, const nsACString& aType, uint32_t aPermission,
+ int64_t aID, uint32_t aExpireType, int64_t aExpireTime,
+ int64_t aModificationTime, NotifyOperationType aNotifyOperation,
+ DBOperationType aDBOperation, const bool aIgnoreSessionPermissions,
+ const nsACString* aOriginString,
+ const bool aAllowPersistInPrivateBrowsing) {
+ MOZ_ASSERT(NS_IsMainThread());
+
+ EnsureReadCompleted();
+
+ nsresult rv = NS_OK;
+ nsAutoCString origin;
+ // Only attempt to compute the origin string when it is going to be needed
+ // later on in the function.
+ if (!IsChildProcess() ||
+ (aDBOperation == eWriteToDB && IsPersistentExpire(aExpireType, aType))) {
+ if (aOriginString) {
+ // Use the origin string provided by the caller.
+ origin = *aOriginString;
+ } else {
+ if (IsSiteScopedPermission(aType)) {
+ rv = GetSiteFromPrincipal(aPrincipal, IsOAForceStripPermission(aType),
+ origin);
+ } else {
+ // Compute it from the principal provided.
+ rv = GetOriginFromPrincipal(aPrincipal, IsOAForceStripPermission(aType),
+ origin);
+ }
+ NS_ENSURE_SUCCESS(rv, rv);
+ }
+ }
+
+ // Unless the caller sets aAllowPersistInPrivateBrowsing, only store
+ // permissions for the session in Private Browsing. Except for default
+ // permissions which are stored in-memory only and imported each startup. We
+ // also allow setting persistent UKNOWN_ACTION, to support removing default
+ // private browsing permissions.
+ if (!aAllowPersistInPrivateBrowsing && aID != cIDPermissionIsDefault &&
+ aPermission != UNKNOWN_ACTION && aExpireType != EXPIRE_SESSION) {
+ uint32_t privateBrowsingId =
+ nsScriptSecurityManager::DEFAULT_PRIVATE_BROWSING_ID;
+ nsresult rv = aPrincipal->GetPrivateBrowsingId(&privateBrowsingId);
+ if (NS_SUCCEEDED(rv) &&
+ privateBrowsingId !=
+ nsScriptSecurityManager::DEFAULT_PRIVATE_BROWSING_ID) {
+ aExpireType = EXPIRE_SESSION;
+ }
+ }
+
+ // Let's send the new permission to the content process only if it has to be
+ // notified.
+ if (!IsChildProcess() && aNotifyOperation == eNotify) {
+ IPC::Permission permission(origin, aType, aPermission, aExpireType,
+ aExpireTime);
+
+ nsAutoCString permissionKey;
+ GetKeyForPermission(aPrincipal, aType, permissionKey);
+
+ nsTArray<ContentParent*> cplist;
+ ContentParent::GetAll(cplist);
+ for (uint32_t i = 0; i < cplist.Length(); ++i) {
+ ContentParent* cp = cplist[i];
+ if (cp->NeedsPermissionsUpdate(permissionKey))
+ Unused << cp->SendAddPermission(permission);
+ }
+ }
+
+ MOZ_ASSERT(PermissionAvailable(aPrincipal, aType));
+
+ // look up the type index
+ int32_t typeIndex = GetTypeIndex(aType, true);
+ NS_ENSURE_TRUE(typeIndex != -1, NS_ERROR_OUT_OF_MEMORY);
+
+ // When an entry already exists, PutEntry will return that, instead
+ // of adding a new one
+ RefPtr<PermissionKey> key = PermissionKey::CreateFromPrincipal(
+ aPrincipal, IsOAForceStripPermission(aType),
+ IsSiteScopedPermission(aType), rv);
+ if (!key) {
+ MOZ_ASSERT(NS_FAILED(rv));
+ return rv;
+ }
+
+ PermissionHashKey* entry = mPermissionTable.PutEntry(key);
+ if (!entry) return NS_ERROR_FAILURE;
+ if (!entry->GetKey()) {
+ mPermissionTable.RemoveEntry(entry);
+ return NS_ERROR_OUT_OF_MEMORY;
+ }
+
+ // figure out the transaction type, and get any existing permission value
+ OperationType op;
+ int32_t index = entry->GetPermissionIndex(typeIndex);
+ if (index == -1) {
+ if (aPermission == nsIPermissionManager::UNKNOWN_ACTION)
+ op = eOperationNone;
+ else
+ op = eOperationAdding;
+
+ } else {
+ PermissionEntry oldPermissionEntry = entry->GetPermissions()[index];
+
+ // remove the permission if the permission is UNKNOWN, update the
+ // permission if its value or expire type have changed OR if the time has
+ // changed and the expire type is time, otherwise, don't modify. There's
+ // no need to modify a permission that doesn't expire with time when the
+ // only thing changed is the expire time.
+ if (aPermission == oldPermissionEntry.mPermission &&
+ aExpireType == oldPermissionEntry.mExpireType &&
+ (aExpireType == nsIPermissionManager::EXPIRE_NEVER ||
+ aExpireTime == oldPermissionEntry.mExpireTime))
+ op = eOperationNone;
+ else if (oldPermissionEntry.mID == cIDPermissionIsDefault)
+ // The existing permission is one added as a default and the new
+ // permission doesn't exactly match so we are replacing the default. This
+ // is true even if the new permission is UNKNOWN_ACTION (which means a
+ // "logical remove" of the default)
+ op = eOperationReplacingDefault;
+ else if (aID == cIDPermissionIsDefault)
+ // We are adding a default permission but a "real" permission already
+ // exists. This almost-certainly means we just did a removeAllSince and
+ // are re-importing defaults - so we can ignore this.
+ op = eOperationNone;
+ else if (aPermission == nsIPermissionManager::UNKNOWN_ACTION)
+ op = eOperationRemoving;
+ else
+ op = eOperationChanging;
+ }
+
+ // child processes should *always* be passed a modificationTime of zero.
+ MOZ_ASSERT(!IsChildProcess() || aModificationTime == 0);
+
+ // do the work for adding, deleting, or changing a permission:
+ // update the in-memory list, write to the db, and notify consumers.
+ int64_t id;
+ if (aModificationTime == 0) {
+ aModificationTime = EXPIRY_NOW;
+ }
+
+ switch (op) {
+ case eOperationNone: {
+ // nothing to do
+ return NS_OK;
+ }
+
+ case eOperationAdding: {
+ if (aDBOperation == eWriteToDB) {
+ // we'll be writing to the database - generate a known unique id
+ id = ++mLargestID;
+ } else {
+ // we're reading from the database - use the id already assigned
+ id = aID;
+ }
+
+ entry->GetPermissions().AppendElement(
+ PermissionEntry(id, typeIndex, aPermission, aExpireType, aExpireTime,
+ aModificationTime));
+
+ if (aDBOperation == eWriteToDB &&
+ IsPersistentExpire(aExpireType, aType)) {
+ UpdateDB(op, id, origin, aType, aPermission, aExpireType, aExpireTime,
+ aModificationTime);
+ }
+
+ if (aNotifyOperation == eNotify) {
+ NotifyObserversWithPermission(aPrincipal, mTypeArray[typeIndex],
+ aPermission, aExpireType, aExpireTime,
+ aModificationTime, u"added");
+ }
+
+ break;
+ }
+
+ case eOperationRemoving: {
+ PermissionEntry oldPermissionEntry = entry->GetPermissions()[index];
+ id = oldPermissionEntry.mID;
+
+ // If the type we want to remove is EXPIRE_POLICY, we need to reject
+ // attempts to change the permission.
+ if (entry->GetPermissions()[index].mExpireType == EXPIRE_POLICY) {
+ NS_WARNING("Attempting to remove EXPIRE_POLICY permission");
+ break;
+ }
+
+ entry->GetPermissions().RemoveElementAt(index);
+
+ if (aDBOperation == eWriteToDB)
+ // We care only about the id here so we pass dummy values for all other
+ // parameters.
+ UpdateDB(op, id, ""_ns, ""_ns, 0, nsIPermissionManager::EXPIRE_NEVER, 0,
+ 0);
+
+ if (aNotifyOperation == eNotify) {
+ NotifyObserversWithPermission(
+ aPrincipal, mTypeArray[typeIndex], oldPermissionEntry.mPermission,
+ oldPermissionEntry.mExpireType, oldPermissionEntry.mExpireTime,
+ oldPermissionEntry.mModificationTime, u"deleted");
+ }
+
+ // If there are no more permissions stored for that entry, clear it.
+ if (entry->GetPermissions().IsEmpty()) {
+ mPermissionTable.RemoveEntry(entry);
+ }
+
+ break;
+ }
+
+ case eOperationChanging: {
+ id = entry->GetPermissions()[index].mID;
+
+ // If the existing type is EXPIRE_POLICY, we need to reject attempts to
+ // change the permission.
+ if (entry->GetPermissions()[index].mExpireType == EXPIRE_POLICY) {
+ NS_WARNING("Attempting to modify EXPIRE_POLICY permission");
+ break;
+ }
+
+ PermissionEntry oldPermissionEntry = entry->GetPermissions()[index];
+
+ // If the new expireType is EXPIRE_SESSION, then we have to keep a
+ // copy of the previous permission/expireType values. This cached value
+ // will be used when restoring the permissions of an app.
+ if (entry->GetPermissions()[index].mExpireType !=
+ nsIPermissionManager::EXPIRE_SESSION &&
+ aExpireType == nsIPermissionManager::EXPIRE_SESSION) {
+ entry->GetPermissions()[index].mNonSessionPermission =
+ entry->GetPermissions()[index].mPermission;
+ entry->GetPermissions()[index].mNonSessionExpireType =
+ entry->GetPermissions()[index].mExpireType;
+ entry->GetPermissions()[index].mNonSessionExpireTime =
+ entry->GetPermissions()[index].mExpireTime;
+ } else if (aExpireType != nsIPermissionManager::EXPIRE_SESSION) {
+ entry->GetPermissions()[index].mNonSessionPermission = aPermission;
+ entry->GetPermissions()[index].mNonSessionExpireType = aExpireType;
+ entry->GetPermissions()[index].mNonSessionExpireTime = aExpireTime;
+ }
+
+ entry->GetPermissions()[index].mPermission = aPermission;
+ entry->GetPermissions()[index].mExpireType = aExpireType;
+ entry->GetPermissions()[index].mExpireTime = aExpireTime;
+ entry->GetPermissions()[index].mModificationTime = aModificationTime;
+
+ if (aDBOperation == eWriteToDB) {
+ bool newIsPersistentExpire = IsPersistentExpire(aExpireType, aType);
+ bool oldIsPersistentExpire =
+ IsPersistentExpire(oldPermissionEntry.mExpireType, aType);
+
+ if (!newIsPersistentExpire && oldIsPersistentExpire) {
+ // Maybe we have to remove the previous permission if that was
+ // persistent.
+ UpdateDB(eOperationRemoving, id, ""_ns, ""_ns, 0,
+ nsIPermissionManager::EXPIRE_NEVER, 0, 0);
+ } else if (newIsPersistentExpire && !oldIsPersistentExpire) {
+ // It could also be that the previous permission was session-only but
+ // this needs to be written into the DB. In this case, we have to run
+ // an Adding operation.
+ UpdateDB(eOperationAdding, id, origin, aType, aPermission,
+ aExpireType, aExpireTime, aModificationTime);
+ } else if (newIsPersistentExpire) {
+ // This is the a simple update. We care only about the id, the
+ // permission and expireType/expireTime/modificationTime here. We pass
+ // dummy values for all other parameters.
+ UpdateDB(op, id, ""_ns, ""_ns, aPermission, aExpireType, aExpireTime,
+ aModificationTime);
+ }
+ }
+
+ if (aNotifyOperation == eNotify) {
+ NotifyObserversWithPermission(aPrincipal, mTypeArray[typeIndex],
+ aPermission, aExpireType, aExpireTime,
+ aModificationTime, u"changed");
+ }
+
+ break;
+ }
+ case eOperationReplacingDefault: {
+ // this is handling the case when we have an existing permission
+ // entry that was created as a "default" (and thus isn't in the DB) with
+ // an explicit permission (that may include UNKNOWN_ACTION.)
+ // Note we will *not* get here if we are replacing an already replaced
+ // default value - that is handled as eOperationChanging.
+
+ // So this is a hybrid of eOperationAdding (as we are writing a new entry
+ // to the DB) and eOperationChanging (as we are replacing the in-memory
+ // repr and sending a "changed" notification).
+
+ // We want a new ID even if not writing to the DB, so the modified entry
+ // in memory doesn't have the magic cIDPermissionIsDefault value.
+ id = ++mLargestID;
+
+ // The default permission being replaced can't have session expiry or
+ // policy expiry.
+ NS_ENSURE_TRUE(entry->GetPermissions()[index].mExpireType !=
+ nsIPermissionManager::EXPIRE_SESSION,
+ NS_ERROR_UNEXPECTED);
+ NS_ENSURE_TRUE(entry->GetPermissions()[index].mExpireType !=
+ nsIPermissionManager::EXPIRE_POLICY,
+ NS_ERROR_UNEXPECTED);
+ // We don't support the new entry having any expiry - supporting that
+ // would make things far more complex and none of the permissions we set
+ // as a default support that.
+ NS_ENSURE_TRUE(aExpireType == EXPIRE_NEVER, NS_ERROR_UNEXPECTED);
+
+ // update the existing entry in memory.
+ entry->GetPermissions()[index].mID = id;
+ entry->GetPermissions()[index].mPermission = aPermission;
+ entry->GetPermissions()[index].mExpireType = aExpireType;
+ entry->GetPermissions()[index].mExpireTime = aExpireTime;
+ entry->GetPermissions()[index].mModificationTime = aModificationTime;
+
+ // If requested, create the entry in the DB.
+ if (aDBOperation == eWriteToDB &&
+ IsPersistentExpire(aExpireType, aType)) {
+ UpdateDB(eOperationAdding, id, origin, aType, aPermission, aExpireType,
+ aExpireTime, aModificationTime);
+ }
+
+ if (aNotifyOperation == eNotify) {
+ NotifyObserversWithPermission(aPrincipal, mTypeArray[typeIndex],
+ aPermission, aExpireType, aExpireTime,
+ aModificationTime, u"changed");
+ }
+
+ } break;
+ }
+
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+PermissionManager::RemoveFromPrincipal(nsIPrincipal* aPrincipal,
+ const nsACString& aType) {
+ ENSURE_NOT_CHILD_PROCESS;
+ NS_ENSURE_ARG_POINTER(aPrincipal);
+
+ // System principals are never added to the database, no need to remove them.
+ if (aPrincipal->IsSystemPrincipal()) {
+ return NS_OK;
+ }
+
+ // Permissions may not be added to expanded principals.
+ if (IsExpandedPrincipal(aPrincipal)) {
+ return NS_ERROR_INVALID_ARG;
+ }
+
+ // AddInternal() handles removal, just let it do the work
+ return AddInternal(aPrincipal, aType, nsIPermissionManager::UNKNOWN_ACTION, 0,
+ nsIPermissionManager::EXPIRE_NEVER, 0, 0, eNotify,
+ eWriteToDB);
+}
+
+NS_IMETHODIMP
+PermissionManager::RemovePermission(nsIPermission* aPerm) {
+ if (!aPerm) {
+ return NS_OK;
+ }
+ nsCOMPtr<nsIPrincipal> principal;
+ nsresult rv = aPerm->GetPrincipal(getter_AddRefs(principal));
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ nsAutoCString type;
+ rv = aPerm->GetType(type);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ // Permissions are uniquely identified by their principal and type.
+ // We remove the permission using these two pieces of data.
+ return RemoveFromPrincipal(principal, type);
+}
+
+NS_IMETHODIMP
+PermissionManager::RemoveAll() {
+ ENSURE_NOT_CHILD_PROCESS;
+ return RemoveAllInternal(true);
+}
+
+NS_IMETHODIMP
+PermissionManager::RemoveAllSince(int64_t aSince) {
+ ENSURE_NOT_CHILD_PROCESS;
+ return RemoveAllModifiedSince(aSince);
+}
+
+template <class T>
+nsresult PermissionManager::RemovePermissionEntries(T aCondition) {
+ EnsureReadCompleted();
+
+ Vector<std::tuple<nsCOMPtr<nsIPrincipal>, nsCString, nsCString>, 10> array;
+ for (const PermissionHashKey& entry : mPermissionTable) {
+ for (const auto& permEntry : entry.GetPermissions()) {
+ if (!aCondition(permEntry)) {
+ continue;
+ }
+
+ nsCOMPtr<nsIPrincipal> principal;
+ nsresult rv = GetPrincipalFromOrigin(
+ entry.GetKey()->mOrigin,
+ IsOAForceStripPermission(mTypeArray[permEntry.mType]),
+ getter_AddRefs(principal));
+ if (NS_FAILED(rv)) {
+ continue;
+ }
+
+ if (!array.emplaceBack(principal, mTypeArray[permEntry.mType],
+ entry.GetKey()->mOrigin)) {
+ continue;
+ }
+ }
+ }
+
+ for (auto& i : array) {
+ // AddInternal handles removal, so let it do the work...
+ AddInternal(
+ std::get<0>(i), std::get<1>(i), nsIPermissionManager::UNKNOWN_ACTION, 0,
+ nsIPermissionManager::EXPIRE_NEVER, 0, 0, PermissionManager::eNotify,
+ PermissionManager::eWriteToDB, false, &std::get<2>(i));
+ }
+
+ // now re-import any defaults as they may now be required if we just deleted
+ // an override.
+ ImportLatestDefaults();
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+PermissionManager::RemoveByType(const nsACString& aType) {
+ ENSURE_NOT_CHILD_PROCESS;
+
+ int32_t typeIndex = GetTypeIndex(aType, false);
+ // If type == -1, the type isn't known,
+ // so just return NS_OK
+ if (typeIndex == -1) {
+ return NS_OK;
+ }
+
+ return RemovePermissionEntries(
+ [typeIndex](const PermissionEntry& aPermEntry) {
+ return static_cast<uint32_t>(typeIndex) == aPermEntry.mType;
+ });
+}
+
+NS_IMETHODIMP
+PermissionManager::RemoveByTypeSince(const nsACString& aType,
+ int64_t aModificationTime) {
+ ENSURE_NOT_CHILD_PROCESS;
+
+ int32_t typeIndex = GetTypeIndex(aType, false);
+ // If type == -1, the type isn't known,
+ // so just return NS_OK
+ if (typeIndex == -1) {
+ return NS_OK;
+ }
+
+ return RemovePermissionEntries(
+ [typeIndex, aModificationTime](const PermissionEntry& aPermEntry) {
+ return uint32_t(typeIndex) == aPermEntry.mType &&
+ aModificationTime <= aPermEntry.mModificationTime;
+ });
+}
+
+void PermissionManager::CloseDB(CloseDBNextOp aNextOp) {
+ EnsureReadCompleted();
+
+ mState = eClosed;
+
+ nsCOMPtr<nsIInputStream> defaultsInputStream;
+ if (aNextOp == eRebuldOnSuccess) {
+ defaultsInputStream = GetDefaultsInputStream();
+ }
+
+ RefPtr<PermissionManager> self = this;
+ mThread->Dispatch(NS_NewRunnableFunction(
+ "PermissionManager::CloseDB", [self, aNextOp, defaultsInputStream] {
+ auto data = self->mThreadBoundData.Access();
+ // Null the statements, this will finalize them.
+ data->mStmtInsert = nullptr;
+ data->mStmtDelete = nullptr;
+ data->mStmtUpdate = nullptr;
+ if (data->mDBConn) {
+ DebugOnly<nsresult> rv = data->mDBConn->Close();
+ MOZ_ASSERT(NS_SUCCEEDED(rv));
+ data->mDBConn = nullptr;
+
+ if (aNextOp == eRebuldOnSuccess) {
+ self->TryInitDB(true, defaultsInputStream);
+ }
+ }
+
+ if (aNextOp == eShutdown) {
+ NS_DispatchToMainThread(NS_NewRunnableFunction(
+ "PermissionManager::MaybeCompleteShutdown",
+ [self] { self->MaybeCompleteShutdown(); }));
+ }
+ }));
+}
+
+nsresult PermissionManager::RemoveAllFromIPC() {
+ MOZ_ASSERT(IsChildProcess());
+
+ // Remove from memory and notify immediately. Since the in-memory
+ // database is authoritative, we do not need confirmation from the
+ // on-disk database to notify observers.
+ RemoveAllFromMemory();
+
+ return NS_OK;
+}
+
+nsresult PermissionManager::RemoveAllInternal(bool aNotifyObservers) {
+ ENSURE_NOT_CHILD_PROCESS;
+
+ EnsureReadCompleted();
+
+ // Let's broadcast the removeAll() to any content process.
+ nsTArray<ContentParent*> parents;
+ ContentParent::GetAll(parents);
+ for (ContentParent* parent : parents) {
+ Unused << parent->SendRemoveAllPermissions();
+ }
+
+ // Remove from memory and notify immediately. Since the in-memory
+ // database is authoritative, we do not need confirmation from the
+ // on-disk database to notify observers.
+ RemoveAllFromMemory();
+
+ // Re-import the defaults
+ ImportLatestDefaults();
+
+ if (aNotifyObservers) {
+ NotifyObservers(nullptr, u"cleared");
+ }
+
+ RefPtr<PermissionManager> self = this;
+ mThread->Dispatch(
+ NS_NewRunnableFunction("PermissionManager::RemoveAllInternal", [self] {
+ auto data = self->mThreadBoundData.Access();
+
+ if (self->mState == eClosed || !data->mDBConn) {
+ return;
+ }
+
+ // clear the db
+ nsresult rv =
+ data->mDBConn->ExecuteSimpleSQL("DELETE FROM moz_perms"_ns);
+ if (NS_WARN_IF(NS_FAILED(rv))) {
+ NS_DispatchToMainThread(NS_NewRunnableFunction(
+ "PermissionManager::RemoveAllInternal-Failure",
+ [self] { self->CloseDB(eRebuldOnSuccess); }));
+ }
+ }));
+
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+PermissionManager::TestExactPermissionFromPrincipal(nsIPrincipal* aPrincipal,
+ const nsACString& aType,
+ uint32_t* aPermission) {
+ return CommonTestPermission(aPrincipal, -1, aType, aPermission,
+ nsIPermissionManager::UNKNOWN_ACTION, false, true,
+ true);
+}
+
+NS_IMETHODIMP
+PermissionManager::TestExactPermanentPermission(nsIPrincipal* aPrincipal,
+ const nsACString& aType,
+ uint32_t* aPermission) {
+ return CommonTestPermission(aPrincipal, -1, aType, aPermission,
+ nsIPermissionManager::UNKNOWN_ACTION, false, true,
+ false);
+}
+
+nsresult PermissionManager::LegacyTestPermissionFromURI(
+ nsIURI* aURI, const OriginAttributes* aOriginAttributes,
+ const nsACString& aType, uint32_t* aPermission) {
+ return CommonTestPermission(aURI, aOriginAttributes, -1, aType, aPermission,
+ nsIPermissionManager::UNKNOWN_ACTION, false,
+ false, true);
+}
+
+NS_IMETHODIMP
+PermissionManager::TestPermissionFromPrincipal(nsIPrincipal* aPrincipal,
+ const nsACString& aType,
+ uint32_t* aPermission) {
+ return CommonTestPermission(aPrincipal, -1, aType, aPermission,
+ nsIPermissionManager::UNKNOWN_ACTION, false,
+ false, true);
+}
+
+NS_IMETHODIMP
+PermissionManager::GetPermissionObject(nsIPrincipal* aPrincipal,
+ const nsACString& aType,
+ bool aExactHostMatch,
+ nsIPermission** aResult) {
+ NS_ENSURE_ARG_POINTER(aPrincipal);
+ *aResult = nullptr;
+
+ EnsureReadCompleted();
+
+ if (aPrincipal->IsSystemPrincipal()) {
+ return NS_OK;
+ }
+
+ // Querying the permission object of an nsEP is non-sensical.
+ if (IsExpandedPrincipal(aPrincipal)) {
+ return NS_ERROR_INVALID_ARG;
+ }
+
+ MOZ_ASSERT(PermissionAvailable(aPrincipal, aType));
+
+ int32_t typeIndex = GetTypeIndex(aType, false);
+ // If type == -1, the type isn't known,
+ // so just return NS_OK
+ if (typeIndex == -1) return NS_OK;
+
+ PermissionHashKey* entry =
+ GetPermissionHashKey(aPrincipal, typeIndex, aExactHostMatch);
+ if (!entry) {
+ return NS_OK;
+ }
+
+ // We don't call GetPermission(typeIndex) because that returns a fake
+ // UNKNOWN_ACTION entry if there is no match.
+ int32_t idx = entry->GetPermissionIndex(typeIndex);
+ if (-1 == idx) {
+ return NS_OK;
+ }
+
+ nsCOMPtr<nsIPrincipal> principal;
+ nsresult rv = GetPrincipalFromOrigin(entry->GetKey()->mOrigin,
+ IsOAForceStripPermission(aType),
+ getter_AddRefs(principal));
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ PermissionEntry& perm = entry->GetPermissions()[idx];
+ nsCOMPtr<nsIPermission> r = Permission::Create(
+ principal, mTypeArray[perm.mType], perm.mPermission, perm.mExpireType,
+ perm.mExpireTime, perm.mModificationTime);
+ if (NS_WARN_IF(!r)) {
+ return NS_ERROR_FAILURE;
+ }
+ r.forget(aResult);
+ return NS_OK;
+}
+
+nsresult PermissionManager::CommonTestPermissionInternal(
+ nsIPrincipal* aPrincipal, nsIURI* aURI,
+ const OriginAttributes* aOriginAttributes, int32_t aTypeIndex,
+ const nsACString& aType, uint32_t* aPermission, bool aExactHostMatch,
+ bool aIncludingSession) {
+ MOZ_ASSERT(aPrincipal || aURI);
+ NS_ENSURE_ARG_POINTER(aPrincipal || aURI);
+ MOZ_ASSERT_IF(aPrincipal, !aURI && !aOriginAttributes);
+ MOZ_ASSERT_IF(aURI || aOriginAttributes, !aPrincipal);
+
+ EnsureReadCompleted();
+
+#ifdef DEBUG
+ {
+ nsCOMPtr<nsIPrincipal> prin = aPrincipal;
+ if (!prin) {
+ if (aURI) {
+ prin = BasePrincipal::CreateContentPrincipal(aURI, OriginAttributes());
+ }
+ }
+ MOZ_ASSERT(prin);
+ MOZ_ASSERT(PermissionAvailable(prin, aType));
+ }
+#endif
+
+ PermissionHashKey* entry =
+ aPrincipal ? GetPermissionHashKey(aPrincipal, aTypeIndex, aExactHostMatch)
+ : GetPermissionHashKey(aURI, aOriginAttributes, aTypeIndex,
+ aExactHostMatch);
+ if (!entry || (!aIncludingSession &&
+ entry->GetPermission(aTypeIndex).mNonSessionExpireType ==
+ nsIPermissionManager::EXPIRE_SESSION)) {
+ return NS_OK;
+ }
+
+ *aPermission = aIncludingSession
+ ? entry->GetPermission(aTypeIndex).mPermission
+ : entry->GetPermission(aTypeIndex).mNonSessionPermission;
+
+ return NS_OK;
+}
+
+// Helper function to filter permissions using a condition function.
+template <class T>
+nsresult PermissionManager::GetPermissionEntries(
+ T aCondition, nsTArray<RefPtr<nsIPermission>>& aResult) {
+ aResult.Clear();
+ if (XRE_IsContentProcess()) {
+ NS_WARNING(
+ "Iterating over all permissions is not available in the "
+ "content process, as not all permissions may be available.");
+ return NS_ERROR_NOT_AVAILABLE;
+ }
+
+ EnsureReadCompleted();
+
+ for (const PermissionHashKey& entry : mPermissionTable) {
+ for (const auto& permEntry : entry.GetPermissions()) {
+ // Given how "default" permissions work and the possibility of them being
+ // overridden with UNKNOWN_ACTION, we might see this value here - but we
+ // do *not* want to return them via the enumerator.
+ if (permEntry.mPermission == nsIPermissionManager::UNKNOWN_ACTION) {
+ continue;
+ }
+
+ // If the permission is expired, skip it. We're not deleting it here
+ // because we're iterating over a lot of permissions.
+ // It will be removed as part of the daily maintenance later.
+ if (HasExpired(permEntry.mExpireType, permEntry.mExpireTime)) {
+ continue;
+ }
+
+ if (!aCondition(permEntry)) {
+ continue;
+ }
+
+ nsCOMPtr<nsIPrincipal> principal;
+ nsresult rv = GetPrincipalFromOrigin(
+ entry.GetKey()->mOrigin,
+ IsOAForceStripPermission(mTypeArray[permEntry.mType]),
+ getter_AddRefs(principal));
+ if (NS_FAILED(rv)) {
+ continue;
+ }
+
+ RefPtr<nsIPermission> permission = Permission::Create(
+ principal, mTypeArray[permEntry.mType], permEntry.mPermission,
+ permEntry.mExpireType, permEntry.mExpireTime,
+ permEntry.mModificationTime);
+ if (NS_WARN_IF(!permission)) {
+ continue;
+ }
+ aResult.AppendElement(std::move(permission));
+ }
+ }
+
+ return NS_OK;
+}
+
+NS_IMETHODIMP PermissionManager::GetAll(
+ nsTArray<RefPtr<nsIPermission>>& aResult) {
+ return GetPermissionEntries(
+ [](const PermissionEntry& aPermEntry) { return true; }, aResult);
+}
+
+NS_IMETHODIMP PermissionManager::GetAllByTypeSince(
+ const nsACString& aPrefix, int64_t aSince,
+ nsTArray<RefPtr<nsIPermission>>& aResult) {
+ // Check that aSince is a reasonable point in time, not in the future
+ if (aSince > (PR_Now() / PR_USEC_PER_MSEC)) {
+ return NS_ERROR_INVALID_ARG;
+ }
+ return GetPermissionEntries(
+ [&](const PermissionEntry& aPermEntry) {
+ return mTypeArray[aPermEntry.mType].Equals(aPrefix) &&
+ aSince <= aPermEntry.mModificationTime;
+ },
+ aResult);
+}
+
+NS_IMETHODIMP PermissionManager::GetAllWithTypePrefix(
+ const nsACString& aPrefix, nsTArray<RefPtr<nsIPermission>>& aResult) {
+ return GetPermissionEntries(
+ [&](const PermissionEntry& aPermEntry) {
+ return StringBeginsWith(mTypeArray[aPermEntry.mType], aPrefix);
+ },
+ aResult);
+}
+
+NS_IMETHODIMP PermissionManager::GetAllByTypes(
+ const nsTArray<nsCString>& aTypes,
+ nsTArray<RefPtr<nsIPermission>>& aResult) {
+ if (aTypes.IsEmpty()) {
+ return NS_OK;
+ }
+
+ return GetPermissionEntries(
+ [&](const PermissionEntry& aPermEntry) {
+ return aTypes.Contains(mTypeArray[aPermEntry.mType]);
+ },
+ aResult);
+}
+
+nsresult PermissionManager::GetAllForPrincipalHelper(
+ nsIPrincipal* aPrincipal, bool aSiteScopePermissions,
+ nsTArray<RefPtr<nsIPermission>>& aResult) {
+ nsresult rv;
+ RefPtr<PermissionKey> key = PermissionKey::CreateFromPrincipal(
+ aPrincipal, false, aSiteScopePermissions, rv);
+ if (!key) {
+ MOZ_ASSERT(NS_FAILED(rv));
+ return rv;
+ }
+ PermissionHashKey* entry = mPermissionTable.GetEntry(key);
+
+ nsTArray<PermissionEntry> strippedPerms;
+ rv = GetStripPermsForPrincipal(aPrincipal, aSiteScopePermissions,
+ strippedPerms);
+ if (NS_FAILED(rv)) {
+ return rv;
+ }
+
+ if (entry) {
+ for (const auto& permEntry : entry->GetPermissions()) {
+ // Only return custom permissions
+ if (permEntry.mPermission == nsIPermissionManager::UNKNOWN_ACTION) {
+ continue;
+ }
+
+ // If the permission is expired, skip it. We're not deleting it here
+ // because we're iterating over a lot of permissions.
+ // It will be removed as part of the daily maintenance later.
+ if (HasExpired(permEntry.mExpireType, permEntry.mExpireTime)) {
+ continue;
+ }
+
+ // Make sure that we only get site scoped permissions if this
+ // helper is being invoked for that purpose.
+ if (aSiteScopePermissions !=
+ IsSiteScopedPermission(mTypeArray[permEntry.mType])) {
+ continue;
+ }
+
+ // Stripped principal permissions overwrite regular ones
+ // For each permission check if there is a stripped permission we should
+ // use instead
+ PermissionEntry perm = permEntry;
+ nsTArray<PermissionEntry>::index_type index = 0;
+ for (const auto& strippedPerm : strippedPerms) {
+ if (strippedPerm.mType == permEntry.mType) {
+ perm = strippedPerm;
+ strippedPerms.RemoveElementAt(index);
+ break;
+ }
+ index++;
+ }
+
+ RefPtr<nsIPermission> permission = Permission::Create(
+ aPrincipal, mTypeArray[perm.mType], perm.mPermission,
+ perm.mExpireType, perm.mExpireTime, perm.mModificationTime);
+ if (NS_WARN_IF(!permission)) {
+ continue;
+ }
+ aResult.AppendElement(permission);
+ }
+ }
+
+ for (const auto& perm : strippedPerms) {
+ RefPtr<nsIPermission> permission = Permission::Create(
+ aPrincipal, mTypeArray[perm.mType], perm.mPermission, perm.mExpireType,
+ perm.mExpireTime, perm.mModificationTime);
+ if (NS_WARN_IF(!permission)) {
+ continue;
+ }
+ aResult.AppendElement(permission);
+ }
+
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+PermissionManager::GetAllForPrincipal(
+ nsIPrincipal* aPrincipal, nsTArray<RefPtr<nsIPermission>>& aResult) {
+ nsresult rv;
+ aResult.Clear();
+ EnsureReadCompleted();
+
+ MOZ_ASSERT(PermissionAvailable(aPrincipal, ""_ns));
+
+ // First, append the non-site-scoped permissions.
+ rv = GetAllForPrincipalHelper(aPrincipal, false, aResult);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ // Second, append the site-scoped permissions.
+ return GetAllForPrincipalHelper(aPrincipal, true, aResult);
+}
+
+NS_IMETHODIMP PermissionManager::Observe(nsISupports* aSubject,
+ const char* aTopic,
+ const char16_t* someData) {
+ ENSURE_NOT_CHILD_PROCESS;
+
+ if (!nsCRT::strcmp(aTopic, "profile-do-change") && !mPermissionsFile) {
+ // profile startup is complete, and we didn't have the permissions file
+ // before; init the db from the new location
+ InitDB(false);
+ } else if (!nsCRT::strcmp(aTopic, "testonly-reload-permissions-from-disk")) {
+ // Testing mechanism to reload all permissions from disk. Because the
+ // permission manager automatically initializes itself at startup, tests
+ // that directly manipulate the permissions database need some way to reload
+ // the database for their changes to have any effect. This mechanism was
+ // introduced when moving the permissions manager from on-demand startup to
+ // always being initialized. This is not guarded by a pref because it's not
+ // dangerous to reload permissions from disk, just bad for performance.
+ RemoveAllFromMemory();
+ CloseDB(eNone);
+ InitDB(false);
+ } else if (!nsCRT::strcmp(aTopic, OBSERVER_TOPIC_IDLE_DAILY)) {
+ PerformIdleDailyMaintenance();
+ }
+
+ return NS_OK;
+}
+
+nsresult PermissionManager::RemoveAllModifiedSince(int64_t aModificationTime) {
+ ENSURE_NOT_CHILD_PROCESS;
+
+ return RemovePermissionEntries(
+ [aModificationTime](const PermissionEntry& aPermEntry) {
+ return aModificationTime <= aPermEntry.mModificationTime;
+ });
+}
+
+NS_IMETHODIMP
+PermissionManager::RemovePermissionsWithAttributes(const nsAString& aPattern) {
+ ENSURE_NOT_CHILD_PROCESS;
+ OriginAttributesPattern pattern;
+ if (!pattern.Init(aPattern)) {
+ return NS_ERROR_INVALID_ARG;
+ }
+
+ return RemovePermissionsWithAttributes(pattern);
+}
+
+nsresult PermissionManager::RemovePermissionsWithAttributes(
+ OriginAttributesPattern& aPattern) {
+ EnsureReadCompleted();
+
+ Vector<std::tuple<nsCOMPtr<nsIPrincipal>, nsCString, nsCString>, 10>
+ permissions;
+ for (const PermissionHashKey& entry : mPermissionTable) {
+ nsCOMPtr<nsIPrincipal> principal;
+ nsresult rv = GetPrincipalFromOrigin(entry.GetKey()->mOrigin, false,
+ getter_AddRefs(principal));
+ if (NS_FAILED(rv)) {
+ continue;
+ }
+
+ if (!aPattern.Matches(principal->OriginAttributesRef())) {
+ continue;
+ }
+
+ for (const auto& permEntry : entry.GetPermissions()) {
+ if (!permissions.emplaceBack(principal, mTypeArray[permEntry.mType],
+ entry.GetKey()->mOrigin)) {
+ continue;
+ }
+ }
+ }
+
+ for (auto& i : permissions) {
+ AddInternal(
+ std::get<0>(i), std::get<1>(i), nsIPermissionManager::UNKNOWN_ACTION, 0,
+ nsIPermissionManager::EXPIRE_NEVER, 0, 0, PermissionManager::eNotify,
+ PermissionManager::eWriteToDB, false, &std::get<2>(i));
+ }
+
+ return NS_OK;
+}
+
+nsresult PermissionManager::GetStripPermsForPrincipal(
+ nsIPrincipal* aPrincipal, bool aSiteScopePermissions,
+ nsTArray<PermissionEntry>& aResult) {
+ aResult.Clear();
+ aResult.SetCapacity(kStripOAPermissions.size());
+
+#ifdef __clang__
+# pragma clang diagnostic push
+# pragma clang diagnostic ignored "-Wunreachable-code-return"
+#endif
+ // No special strip permissions
+ if (kStripOAPermissions.empty()) {
+ return NS_OK;
+ }
+#ifdef __clang__
+# pragma clang diagnostic pop
+#endif
+
+ nsresult rv;
+ // Create a key for the principal, but strip any origin attributes.
+ // The key must be created aware of whether or not we are scoping to site.
+ RefPtr<PermissionKey> key = PermissionKey::CreateFromPrincipal(
+ aPrincipal, true, aSiteScopePermissions, rv);
+ if (!key) {
+ MOZ_ASSERT(NS_FAILED(rv));
+ return rv;
+ }
+
+ PermissionHashKey* hashKey = mPermissionTable.GetEntry(key);
+ if (!hashKey) {
+ return NS_OK;
+ }
+
+ for (const auto& permType : kStripOAPermissions) {
+ // if the permission type's site scoping does not match this function call,
+ // we don't care about it, so continue.
+ // As of time of writing, this never happens when aSiteScopePermissions
+ // is true because there is no common permission between kStripOAPermissions
+ // and kSiteScopedPermissions
+ if (aSiteScopePermissions != IsSiteScopedPermission(permType)) {
+ continue;
+ }
+ int32_t index = GetTypeIndex(permType, false);
+ if (index == -1) {
+ continue;
+ }
+ PermissionEntry perm = hashKey->GetPermission(index);
+ if (perm.mPermission == nsIPermissionManager::UNKNOWN_ACTION) {
+ continue;
+ }
+ aResult.AppendElement(perm);
+ }
+
+ return NS_OK;
+}
+
+int32_t PermissionManager::GetTypeIndex(const nsACString& aType, bool aAdd) {
+ for (uint32_t i = 0; i < mTypeArray.length(); ++i) {
+ if (mTypeArray[i].Equals(aType)) {
+ return i;
+ }
+ }
+
+ if (!aAdd) {
+ // Not found, but that is ok - we were just looking.
+ return -1;
+ }
+
+ // This type was not registered before.
+ // append it to the array, without copy-constructing the string
+ if (!mTypeArray.emplaceBack(aType)) {
+ return -1;
+ }
+
+ return mTypeArray.length() - 1;
+}
+
+PermissionManager::PermissionHashKey* PermissionManager::GetPermissionHashKey(
+ nsIPrincipal* aPrincipal, uint32_t aType, bool aExactHostMatch) {
+ EnsureReadCompleted();
+
+ MOZ_ASSERT(PermissionAvailable(aPrincipal, mTypeArray[aType]));
+
+ nsresult rv;
+ RefPtr<PermissionKey> key = PermissionKey::CreateFromPrincipal(
+ aPrincipal, IsOAForceStripPermission(mTypeArray[aType]),
+ IsSiteScopedPermission(mTypeArray[aType]), rv);
+ if (!key) {
+ return nullptr;
+ }
+
+ PermissionHashKey* entry = mPermissionTable.GetEntry(key);
+
+ if (entry) {
+ PermissionEntry permEntry = entry->GetPermission(aType);
+
+ // if the entry is expired, remove and keep looking for others.
+ if (HasExpired(permEntry.mExpireType, permEntry.mExpireTime)) {
+ entry = nullptr;
+ RemoveFromPrincipal(aPrincipal, mTypeArray[aType]);
+ } else if (permEntry.mPermission == nsIPermissionManager::UNKNOWN_ACTION) {
+ entry = nullptr;
+ }
+ }
+
+ if (entry) {
+ return entry;
+ }
+
+ // If aExactHostMatch wasn't true, we can check if the base domain has a
+ // permission entry.
+ if (!aExactHostMatch) {
+ nsCOMPtr<nsIPrincipal> principal = aPrincipal->GetNextSubDomainPrincipal();
+ if (principal) {
+ return GetPermissionHashKey(principal, aType, aExactHostMatch);
+ }
+ }
+
+ // No entry, really...
+ return nullptr;
+}
+
+PermissionManager::PermissionHashKey* PermissionManager::GetPermissionHashKey(
+ nsIURI* aURI, const OriginAttributes* aOriginAttributes, uint32_t aType,
+ bool aExactHostMatch) {
+ MOZ_ASSERT(aURI);
+
+#ifdef DEBUG
+ {
+ nsCOMPtr<nsIPrincipal> principal;
+ nsresult rv = NS_OK;
+ if (aURI) {
+ rv = GetPrincipal(aURI, getter_AddRefs(principal));
+ }
+ MOZ_ASSERT_IF(NS_SUCCEEDED(rv),
+ PermissionAvailable(principal, mTypeArray[aType]));
+ }
+#endif
+
+ nsresult rv;
+ RefPtr<PermissionKey> key;
+
+ if (aOriginAttributes) {
+ key = PermissionKey::CreateFromURIAndOriginAttributes(
+ aURI, aOriginAttributes, IsOAForceStripPermission(mTypeArray[aType]),
+ rv);
+ } else {
+ key = PermissionKey::CreateFromURI(aURI, rv);
+ }
+
+ if (!key) {
+ return nullptr;
+ }
+
+ PermissionHashKey* entry = mPermissionTable.GetEntry(key);
+
+ if (entry) {
+ PermissionEntry permEntry = entry->GetPermission(aType);
+
+ // if the entry is expired, remove and keep looking for others.
+ if (HasExpired(permEntry.mExpireType, permEntry.mExpireTime)) {
+ entry = nullptr;
+ // If we need to remove a permission we mint a principal. This is a bit
+ // inefficient, but hopefully this code path isn't super common.
+ nsCOMPtr<nsIPrincipal> principal;
+ if (aURI) {
+ nsresult rv = GetPrincipal(aURI, getter_AddRefs(principal));
+ if (NS_WARN_IF(NS_FAILED(rv))) {
+ return nullptr;
+ }
+ }
+ RemoveFromPrincipal(principal, mTypeArray[aType]);
+ } else if (permEntry.mPermission == nsIPermissionManager::UNKNOWN_ACTION) {
+ entry = nullptr;
+ }
+ }
+
+ if (entry) {
+ return entry;
+ }
+
+ // If aExactHostMatch wasn't true, we can check if the base domain has a
+ // permission entry.
+ if (!aExactHostMatch) {
+ nsCOMPtr<nsIURI> uri;
+ if (aURI) {
+ uri = GetNextSubDomainURI(aURI);
+ }
+ if (uri) {
+ return GetPermissionHashKey(uri, aOriginAttributes, aType,
+ aExactHostMatch);
+ }
+ }
+
+ // No entry, really...
+ return nullptr;
+}
+
+nsresult PermissionManager::RemoveAllFromMemory() {
+ mLargestID = 0;
+ mTypeArray.clear();
+ mPermissionTable.Clear();
+
+ return NS_OK;
+}
+
+// wrapper function for mangling (host,type,perm,expireType,expireTime)
+// set into an nsIPermission.
+void PermissionManager::NotifyObserversWithPermission(
+ nsIPrincipal* aPrincipal, const nsACString& aType, uint32_t aPermission,
+ uint32_t aExpireType, int64_t aExpireTime, int64_t aModificationTime,
+ const char16_t* aData) {
+ nsCOMPtr<nsIPermission> permission =
+ Permission::Create(aPrincipal, aType, aPermission, aExpireType,
+ aExpireTime, aModificationTime);
+ if (permission) NotifyObservers(permission, aData);
+}
+
+// notify observers that the permission list changed. there are four possible
+// values for aData:
+// "deleted" means a permission was deleted. aPermission is the deleted
+// permission. "added" means a permission was added. aPermission is the added
+// permission. "changed" means a permission was altered. aPermission is the new
+// permission. "cleared" means the entire permission list was cleared.
+// aPermission is null.
+void PermissionManager::NotifyObservers(nsIPermission* aPermission,
+ const char16_t* aData) {
+ nsCOMPtr<nsIObserverService> observerService = services::GetObserverService();
+ if (observerService)
+ observerService->NotifyObservers(aPermission, kPermissionChangeNotification,
+ aData);
+}
+
+nsresult PermissionManager::Read(const MonitorAutoLock& aProofOfLock) {
+ ENSURE_NOT_CHILD_PROCESS;
+
+ MOZ_ASSERT(!NS_IsMainThread());
+ auto data = mThreadBoundData.Access();
+
+ nsresult rv;
+ bool hasResult;
+ nsCOMPtr<mozIStorageStatement> stmt;
+
+ // Let's retrieve the last used ID.
+ rv = data->mDBConn->CreateStatement(
+ nsLiteralCString("SELECT MAX(id) FROM moz_perms"), getter_AddRefs(stmt));
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ while (NS_SUCCEEDED(stmt->ExecuteStep(&hasResult)) && hasResult) {
+ int64_t id = stmt->AsInt64(0);
+ mLargestID = id;
+ }
+
+ rv = data->mDBConn->CreateStatement(
+ nsLiteralCString(
+ "SELECT id, origin, type, permission, expireType, "
+ "expireTime, modificationTime "
+ "FROM moz_perms WHERE expireType != ?1 OR expireTime > ?2"),
+ getter_AddRefs(stmt));
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ rv = stmt->BindInt32ByIndex(0, nsIPermissionManager::EXPIRE_TIME);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ rv = stmt->BindInt64ByIndex(1, EXPIRY_NOW);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ bool readError = false;
+
+ while (NS_SUCCEEDED(stmt->ExecuteStep(&hasResult)) && hasResult) {
+ ReadEntry entry;
+
+ // explicitly set our entry id counter for use in AddInternal(),
+ // and keep track of the largest id so we know where to pick up.
+ entry.mId = stmt->AsInt64(0);
+ MOZ_ASSERT(entry.mId <= mLargestID);
+
+ rv = stmt->GetUTF8String(1, entry.mOrigin);
+ if (NS_FAILED(rv)) {
+ readError = true;
+ continue;
+ }
+
+ rv = stmt->GetUTF8String(2, entry.mType);
+ if (NS_FAILED(rv)) {
+ readError = true;
+ continue;
+ }
+
+ entry.mPermission = stmt->AsInt32(3);
+ entry.mExpireType = stmt->AsInt32(4);
+
+ // convert into int64_t values (milliseconds)
+ entry.mExpireTime = stmt->AsInt64(5);
+ entry.mModificationTime = stmt->AsInt64(6);
+
+ entry.mFromMigration = false;
+
+ mReadEntries.AppendElement(entry);
+ }
+
+ if (readError) {
+ NS_ERROR("Error occured while reading the permissions database!");
+ return NS_ERROR_FAILURE;
+ }
+
+ return NS_OK;
+}
+
+void PermissionManager::CompleteMigrations() {
+ MOZ_ASSERT(NS_IsMainThread());
+ MOZ_ASSERT(mState == eReady);
+
+ nsresult rv;
+
+ nsTArray<MigrationEntry> entries;
+ {
+ MonitorAutoLock lock(mMonitor);
+ entries = std::move(mMigrationEntries);
+ }
+
+ for (const MigrationEntry& entry : entries) {
+ rv = UpgradeHostToOriginAndInsert(
+ entry.mHost, entry.mType, entry.mPermission, entry.mExpireType,
+ entry.mExpireTime, entry.mModificationTime, entry.mIsInBrowserElement,
+ [&](const nsACString& aOrigin, const nsCString& aType,
+ uint32_t aPermission, uint32_t aExpireType, int64_t aExpireTime,
+ int64_t aModificationTime) {
+ MaybeAddReadEntryFromMigration(aOrigin, aType, aPermission,
+ aExpireType, aExpireTime,
+ aModificationTime, entry.mId);
+ return NS_OK;
+ });
+ Unused << NS_WARN_IF(NS_FAILED(rv));
+ }
+}
+
+void PermissionManager::CompleteRead() {
+ MOZ_ASSERT(NS_IsMainThread());
+ MOZ_ASSERT(mState == eReady);
+
+ nsresult rv;
+
+ nsTArray<ReadEntry> entries;
+ {
+ MonitorAutoLock lock(mMonitor);
+ entries = std::move(mReadEntries);
+ }
+
+ for (const ReadEntry& entry : entries) {
+ nsCOMPtr<nsIPrincipal> principal;
+ rv = GetPrincipalFromOrigin(entry.mOrigin,
+ IsOAForceStripPermission(entry.mType),
+ getter_AddRefs(principal));
+ if (NS_WARN_IF(NS_FAILED(rv))) {
+ continue;
+ }
+
+ DBOperationType op = entry.mFromMigration ? eWriteToDB : eNoDBOperation;
+
+ rv = AddInternal(principal, entry.mType, entry.mPermission, entry.mId,
+ entry.mExpireType, entry.mExpireTime,
+ entry.mModificationTime, eDontNotify, op, false,
+ &entry.mOrigin);
+ Unused << NS_WARN_IF(NS_FAILED(rv));
+ }
+}
+
+void PermissionManager::MaybeAddReadEntryFromMigration(
+ const nsACString& aOrigin, const nsCString& aType, uint32_t aPermission,
+ uint32_t aExpireType, int64_t aExpireTime, int64_t aModificationTime,
+ int64_t aId) {
+ MonitorAutoLock lock(mMonitor);
+
+ // We convert a migration to a ReadEntry only if we don't have an existing
+ // ReadEntry for the same origin + type.
+ for (const ReadEntry& entry : mReadEntries) {
+ if (entry.mOrigin == aOrigin && entry.mType == aType) {
+ return;
+ }
+ }
+
+ ReadEntry entry;
+ entry.mId = aId;
+ entry.mOrigin = aOrigin;
+ entry.mType = aType;
+ entry.mPermission = aPermission;
+ entry.mExpireType = aExpireType;
+ entry.mExpireTime = aExpireTime;
+ entry.mModificationTime = aModificationTime;
+ entry.mFromMigration = true;
+
+ mReadEntries.AppendElement(entry);
+}
+
+void PermissionManager::UpdateDB(OperationType aOp, int64_t aID,
+ const nsACString& aOrigin,
+ const nsACString& aType, uint32_t aPermission,
+ uint32_t aExpireType, int64_t aExpireTime,
+ int64_t aModificationTime) {
+ ENSURE_NOT_CHILD_PROCESS_NORET;
+
+ MOZ_ASSERT(NS_IsMainThread());
+ EnsureReadCompleted();
+
+ nsCString origin(aOrigin);
+ nsCString type(aType);
+
+ RefPtr<PermissionManager> self = this;
+ mThread->Dispatch(NS_NewRunnableFunction(
+ "PermissionManager::UpdateDB",
+ [self, aOp, aID, origin, type, aPermission, aExpireType, aExpireTime,
+ aModificationTime] {
+ nsresult rv;
+
+ auto data = self->mThreadBoundData.Access();
+
+ if (self->mState == eClosed || !data->mDBConn) {
+ // no statement is ok - just means we don't have a profile
+ return;
+ }
+
+ mozIStorageStatement* stmt = nullptr;
+ switch (aOp) {
+ case eOperationAdding: {
+ stmt = data->mStmtInsert;
+
+ rv = stmt->BindInt64ByIndex(0, aID);
+ if (NS_FAILED(rv)) break;
+
+ rv = stmt->BindUTF8StringByIndex(1, origin);
+ if (NS_FAILED(rv)) break;
+
+ rv = stmt->BindUTF8StringByIndex(2, type);
+ if (NS_FAILED(rv)) break;
+
+ rv = stmt->BindInt32ByIndex(3, aPermission);
+ if (NS_FAILED(rv)) break;
+
+ rv = stmt->BindInt32ByIndex(4, aExpireType);
+ if (NS_FAILED(rv)) break;
+
+ rv = stmt->BindInt64ByIndex(5, aExpireTime);
+ if (NS_FAILED(rv)) break;
+
+ rv = stmt->BindInt64ByIndex(6, aModificationTime);
+ break;
+ }
+
+ case eOperationRemoving: {
+ stmt = data->mStmtDelete;
+ rv = stmt->BindInt64ByIndex(0, aID);
+ break;
+ }
+
+ case eOperationChanging: {
+ stmt = data->mStmtUpdate;
+
+ rv = stmt->BindInt64ByIndex(0, aID);
+ if (NS_FAILED(rv)) break;
+
+ rv = stmt->BindInt32ByIndex(1, aPermission);
+ if (NS_FAILED(rv)) break;
+
+ rv = stmt->BindInt32ByIndex(2, aExpireType);
+ if (NS_FAILED(rv)) break;
+
+ rv = stmt->BindInt64ByIndex(3, aExpireTime);
+ if (NS_FAILED(rv)) break;
+
+ rv = stmt->BindInt64ByIndex(4, aModificationTime);
+ break;
+ }
+
+ default: {
+ MOZ_ASSERT_UNREACHABLE("need a valid operation in UpdateDB()!");
+ rv = NS_ERROR_UNEXPECTED;
+ break;
+ }
+ }
+
+ if (NS_FAILED(rv)) {
+ NS_WARNING("db change failed!");
+ return;
+ }
+
+ rv = stmt->Execute();
+ MOZ_ASSERT(NS_SUCCEEDED(rv));
+ }));
+}
+
+bool PermissionManager::GetPermissionsFromOriginOrKey(
+ const nsACString& aOrigin, const nsACString& aKey,
+ nsTArray<IPC::Permission>& aPerms) {
+ EnsureReadCompleted();
+
+ aPerms.Clear();
+ if (NS_WARN_IF(XRE_IsContentProcess())) {
+ return false;
+ }
+
+ for (const PermissionHashKey& entry : mPermissionTable) {
+ nsAutoCString permissionKey;
+ if (aOrigin.IsEmpty()) {
+ // We can't check for individual OA strip perms here.
+ // Don't force strip origin attributes.
+ GetKeyForOrigin(entry.GetKey()->mOrigin, false, false, permissionKey);
+
+ // If the keys don't match, and we aren't getting the default "" key, then
+ // we can exit early. We have to keep looking if we're getting the default
+ // key, as we may see a preload permission which should be transmitted.
+ if (aKey != permissionKey && !aKey.IsEmpty()) {
+ continue;
+ }
+ } else if (aOrigin != entry.GetKey()->mOrigin) {
+ // If the origins don't match, then we can exit early. We have to keep
+ // looking if we're getting the default origin, as we may see a preload
+ // permission which should be transmitted.
+ continue;
+ }
+
+ for (const auto& permEntry : entry.GetPermissions()) {
+ // Given how "default" permissions work and the possibility of them
+ // being overridden with UNKNOWN_ACTION, we might see this value here -
+ // but we do not want to send it to the content process.
+ if (permEntry.mPermission == nsIPermissionManager::UNKNOWN_ACTION) {
+ continue;
+ }
+
+ bool isPreload = IsPreloadPermission(mTypeArray[permEntry.mType]);
+ bool shouldAppend;
+ if (aOrigin.IsEmpty()) {
+ shouldAppend = (isPreload && aKey.IsEmpty()) ||
+ (!isPreload && aKey == permissionKey);
+ } else {
+ shouldAppend = (!isPreload && aOrigin == entry.GetKey()->mOrigin);
+ }
+ if (shouldAppend) {
+ aPerms.AppendElement(
+ IPC::Permission(entry.GetKey()->mOrigin,
+ mTypeArray[permEntry.mType], permEntry.mPermission,
+ permEntry.mExpireType, permEntry.mExpireTime));
+ }
+ }
+ }
+
+ return true;
+}
+
+void PermissionManager::SetPermissionsWithKey(
+ const nsACString& aPermissionKey, nsTArray<IPC::Permission>& aPerms) {
+ if (NS_WARN_IF(XRE_IsParentProcess())) {
+ return;
+ }
+
+ RefPtr<GenericNonExclusivePromise::Private> promise;
+ bool foundKey =
+ mPermissionKeyPromiseMap.Get(aPermissionKey, getter_AddRefs(promise));
+ if (promise) {
+ MOZ_ASSERT(foundKey);
+ // NOTE: This will resolve asynchronously, so we can mark it as resolved
+ // now, and be confident that we will have filled in the database before any
+ // callbacks run.
+ promise->Resolve(true, __func__);
+ } else if (foundKey) {
+ // NOTE: We shouldn't be sent two InitializePermissionsWithKey for the same
+ // key, but it's possible.
+ return;
+ }
+ mPermissionKeyPromiseMap.InsertOrUpdate(
+ aPermissionKey, RefPtr<GenericNonExclusivePromise::Private>{});
+
+ // Add the permissions locally to our process
+ for (IPC::Permission& perm : aPerms) {
+ nsCOMPtr<nsIPrincipal> principal;
+ nsresult rv =
+ GetPrincipalFromOrigin(perm.origin, IsOAForceStripPermission(perm.type),
+ getter_AddRefs(principal));
+ if (NS_WARN_IF(NS_FAILED(rv))) {
+ continue;
+ }
+
+#ifdef DEBUG
+ nsAutoCString permissionKey;
+ GetKeyForPermission(principal, perm.type, permissionKey);
+ MOZ_ASSERT(permissionKey == aPermissionKey,
+ "The permission keys which were sent over should match!");
+#endif
+
+ // The child process doesn't care about modification times - it neither
+ // reads nor writes, nor removes them based on the date - so 0 (which
+ // will end up as now()) is fine.
+ uint64_t modificationTime = 0;
+ AddInternal(principal, perm.type, perm.capability, 0, perm.expireType,
+ perm.expireTime, modificationTime, eNotify, eNoDBOperation,
+ true /* ignoreSessionPermissions */);
+ }
+}
+
+/* static */
+nsresult PermissionManager::GetKeyForOrigin(const nsACString& aOrigin,
+ bool aForceStripOA,
+ bool aSiteScopePermissions,
+ nsACString& aKey) {
+ aKey.Truncate();
+
+ // We only key origins for http, https, and ftp URIs. All origins begin with
+ // the URL which they apply to, which means that they should begin with their
+ // scheme in the case where they are one of these interesting URIs. We don't
+ // want to actually parse the URL here however, because this can be called on
+ // hot paths.
+ if (!StringBeginsWith(aOrigin, "http:"_ns) &&
+ !StringBeginsWith(aOrigin, "https:"_ns) &&
+ !StringBeginsWith(aOrigin, "ftp:"_ns)) {
+ return NS_OK;
+ }
+
+ // We need to look at the originAttributes if they are present, to make sure
+ // to remove any which we don't want. We put the rest of the origin, not
+ // including the attributes, into the key.
+ OriginAttributes attrs;
+ if (!attrs.PopulateFromOrigin(aOrigin, aKey)) {
+ aKey.Truncate();
+ return NS_OK;
+ }
+
+ MaybeStripOriginAttributes(aForceStripOA, attrs);
+
+#ifdef DEBUG
+ // Parse the origin string into a principal, and extract some useful
+ // information from it for assertions.
+ nsCOMPtr<nsIPrincipal> dbgPrincipal;
+ MOZ_ALWAYS_SUCCEEDS(GetPrincipalFromOrigin(aOrigin, aForceStripOA,
+ getter_AddRefs(dbgPrincipal)));
+ MOZ_ASSERT(dbgPrincipal->SchemeIs("http") ||
+ dbgPrincipal->SchemeIs("https") || dbgPrincipal->SchemeIs("ftp"));
+ MOZ_ASSERT(dbgPrincipal->OriginAttributesRef() == attrs);
+#endif
+
+ // If it is needed, turn the origin into its site-origin
+ if (aSiteScopePermissions) {
+ nsCOMPtr<nsIURI> uri;
+ nsresult rv = NS_NewURI(getter_AddRefs(uri), aKey);
+ if (!NS_WARN_IF(NS_FAILED(rv))) {
+ nsCString site;
+ rv = nsEffectiveTLDService::GetInstance()->GetSite(uri, site);
+ if (!NS_WARN_IF(NS_FAILED(rv))) {
+ aKey = site;
+ }
+ }
+ }
+
+ // Append the stripped suffix to the output origin key.
+ nsAutoCString suffix;
+ attrs.CreateSuffix(suffix);
+ aKey.Append(suffix);
+
+ return NS_OK;
+}
+
+/* static */
+nsresult PermissionManager::GetKeyForPrincipal(nsIPrincipal* aPrincipal,
+ bool aForceStripOA,
+ bool aSiteScopePermissions,
+ nsACString& aKey) {
+ nsAutoCString origin;
+ nsresult rv = aPrincipal->GetOrigin(origin);
+ if (NS_WARN_IF(NS_FAILED(rv))) {
+ aKey.Truncate();
+ return rv;
+ }
+ return GetKeyForOrigin(origin, aForceStripOA, aSiteScopePermissions, aKey);
+}
+
+/* static */
+nsresult PermissionManager::GetKeyForPermission(nsIPrincipal* aPrincipal,
+ const nsACString& aType,
+ nsACString& aKey) {
+ // Preload permissions have the "" key.
+ if (IsPreloadPermission(aType)) {
+ aKey.Truncate();
+ return NS_OK;
+ }
+
+ return GetKeyForPrincipal(aPrincipal, IsOAForceStripPermission(aType),
+ IsSiteScopedPermission(aType), aKey);
+}
+
+/* static */
+nsTArray<std::pair<nsCString, nsCString>>
+PermissionManager::GetAllKeysForPrincipal(nsIPrincipal* aPrincipal) {
+ MOZ_ASSERT(aPrincipal);
+
+ nsTArray<std::pair<nsCString, nsCString>> pairs;
+ nsCOMPtr<nsIPrincipal> prin = aPrincipal;
+ while (prin) {
+ // Add the pair to the list
+ std::pair<nsCString, nsCString>* pair =
+ pairs.AppendElement(std::make_pair(""_ns, ""_ns));
+ // We can't check for individual OA strip perms here.
+ // Don't force strip origin attributes.
+ GetKeyForPrincipal(prin, false, false, pair->first);
+
+ // On origins with a derived key set to an empty string
+ // (basically any non-web URI scheme), we want to make sure
+ // to return earlier, and leave [("", "")] as the resulting
+ // pairs (but still run the same debug assertions near the
+ // end of this method).
+ if (pair->first.IsEmpty()) {
+ break;
+ }
+
+ Unused << GetOriginFromPrincipal(prin, false, pair->second);
+ prin = prin->GetNextSubDomainPrincipal();
+ // Get the next subdomain principal and loop back around.
+ }
+
+ MOZ_ASSERT(pairs.Length() >= 1,
+ "Every principal should have at least one pair item.");
+ return pairs;
+}
+
+bool PermissionManager::PermissionAvailable(nsIPrincipal* aPrincipal,
+ const nsACString& aType) {
+ EnsureReadCompleted();
+
+ if (XRE_IsContentProcess()) {
+ nsAutoCString permissionKey;
+ // NOTE: GetKeyForPermission accepts a null aType.
+ GetKeyForPermission(aPrincipal, aType, permissionKey);
+
+ // If we have a pending promise for the permission key in question, we don't
+ // have the permission available, so report a warning and return false.
+ RefPtr<GenericNonExclusivePromise::Private> promise;
+ if (!mPermissionKeyPromiseMap.Get(permissionKey, getter_AddRefs(promise)) ||
+ promise) {
+ // Emit a useful diagnostic warning with the permissionKey for the process
+ // which hasn't received permissions yet.
+ NS_WARNING(nsPrintfCString("This content process hasn't received the "
+ "permissions for %s yet",
+ permissionKey.get())
+ .get());
+ return false;
+ }
+ }
+ return true;
+}
+
+void PermissionManager::WhenPermissionsAvailable(nsIPrincipal* aPrincipal,
+ nsIRunnable* aRunnable) {
+ MOZ_ASSERT(aRunnable);
+
+ if (!XRE_IsContentProcess()) {
+ aRunnable->Run();
+ return;
+ }
+
+ nsTArray<RefPtr<GenericNonExclusivePromise>> promises;
+ for (auto& pair : GetAllKeysForPrincipal(aPrincipal)) {
+ RefPtr<GenericNonExclusivePromise::Private> promise;
+ if (!mPermissionKeyPromiseMap.Get(pair.first, getter_AddRefs(promise))) {
+ // In this case we have found a permission which isn't available in the
+ // content process and hasn't been requested yet. We need to create a new
+ // promise, and send the request to the parent (if we have not already
+ // done so).
+ promise = new GenericNonExclusivePromise::Private(__func__);
+ mPermissionKeyPromiseMap.InsertOrUpdate(pair.first, RefPtr{promise});
+ }
+
+ if (promise) {
+ promises.AppendElement(std::move(promise));
+ }
+ }
+
+ // If all of our permissions are available, immediately run the runnable. This
+ // avoids any extra overhead during fetch interception which is performance
+ // sensitive.
+ if (promises.IsEmpty()) {
+ aRunnable->Run();
+ return;
+ }
+
+ auto* thread = AbstractThread::MainThread();
+
+ RefPtr<nsIRunnable> runnable = aRunnable;
+ GenericNonExclusivePromise::All(thread, promises)
+ ->Then(
+ thread, __func__, [runnable]() { runnable->Run(); },
+ []() {
+ NS_WARNING(
+ "PermissionManager permission promise rejected. We're "
+ "probably shutting down.");
+ });
+}
+
+void PermissionManager::EnsureReadCompleted() {
+ MOZ_ASSERT(NS_IsMainThread());
+
+ if (mState == eInitializing) {
+ MonitorAutoLock lock(mMonitor);
+
+ while (mState == eInitializing) {
+ mMonitor.Wait();
+ }
+ }
+
+ switch (mState) {
+ case eInitializing:
+ MOZ_CRASH("This state is impossible!");
+
+ case eDBInitialized:
+ mState = eReady;
+
+ CompleteMigrations();
+ ImportLatestDefaults();
+ CompleteRead();
+
+ [[fallthrough]];
+
+ case eReady:
+ [[fallthrough]];
+
+ case eClosed:
+ return;
+
+ default:
+ MOZ_CRASH("Invalid state");
+ }
+}
+
+already_AddRefed<nsIInputStream> PermissionManager::GetDefaultsInputStream() {
+ MOZ_ASSERT(NS_IsMainThread());
+
+ nsAutoCString defaultsURL;
+ Preferences::GetCString(kDefaultsUrlPrefName, defaultsURL);
+ if (defaultsURL.IsEmpty()) { // == Don't use built-in permissions.
+ return nullptr;
+ }
+
+ nsCOMPtr<nsIURI> defaultsURI;
+ nsresult rv = NS_NewURI(getter_AddRefs(defaultsURI), defaultsURL);
+ NS_ENSURE_SUCCESS(rv, nullptr);
+
+ nsCOMPtr<nsIChannel> channel;
+ rv = NS_NewChannel(getter_AddRefs(channel), defaultsURI,
+ nsContentUtils::GetSystemPrincipal(),
+ nsILoadInfo::SEC_ALLOW_CROSS_ORIGIN_SEC_CONTEXT_IS_NULL,
+ nsIContentPolicy::TYPE_OTHER);
+ NS_ENSURE_SUCCESS(rv, nullptr);
+
+ nsCOMPtr<nsIInputStream> inputStream;
+ rv = channel->Open(getter_AddRefs(inputStream));
+ NS_ENSURE_SUCCESS(rv, nullptr);
+
+ return inputStream.forget();
+}
+
+void PermissionManager::ConsumeDefaultsInputStream(
+ nsIInputStream* aInputStream, const MonitorAutoLock& aProofOfLock) {
+ MOZ_ASSERT(!NS_IsMainThread());
+
+ constexpr char kMatchTypeHost[] = "host";
+ constexpr char kMatchTypeOrigin[] = "origin";
+
+ mDefaultEntries.Clear();
+
+ if (!aInputStream) {
+ return;
+ }
+
+ nsresult rv;
+
+ /* format is:
+ * matchtype \t type \t permission \t host
+ * Only "host" is supported for matchtype
+ * type is a string that identifies the type of permission (e.g. "cookie")
+ * permission is an integer between 1 and 15
+ */
+
+ // Ideally we'd do this with nsILineInputString, but this is called with an
+ // nsIInputStream that comes from a resource:// URI, which doesn't support
+ // that interface. So NS_ReadLine to the rescue...
+ nsLineBuffer<char> lineBuffer;
+ nsCString line;
+ bool isMore = true;
+ do {
+ rv = NS_ReadLine(aInputStream, &lineBuffer, line, &isMore);
+ NS_ENSURE_SUCCESS_VOID(rv);
+
+ if (line.IsEmpty() || line.First() == '#') {
+ continue;
+ }
+
+ nsTArray<nsCString> lineArray;
+
+ // Split the line at tabs
+ ParseString(line, '\t', lineArray);
+
+ if (lineArray.Length() != 4) {
+ continue;
+ }
+
+ nsresult error = NS_OK;
+ uint32_t permission = lineArray[2].ToInteger(&error);
+ if (NS_FAILED(error)) {
+ continue;
+ }
+
+ DefaultEntry::Op op;
+
+ if (lineArray[0].EqualsLiteral(kMatchTypeHost)) {
+ op = DefaultEntry::eImportMatchTypeHost;
+ } else if (lineArray[0].EqualsLiteral(kMatchTypeOrigin)) {
+ op = DefaultEntry::eImportMatchTypeOrigin;
+ } else {
+ continue;
+ }
+
+ DefaultEntry* entry = mDefaultEntries.AppendElement();
+ MOZ_ASSERT(entry);
+
+ entry->mOp = op;
+ entry->mPermission = permission;
+ entry->mHostOrOrigin = lineArray[3];
+ entry->mType = lineArray[1];
+ } while (isMore);
+}
+
+// ImportLatestDefaults will import the latest default cookies read during the
+// last DB initialization.
+nsresult PermissionManager::ImportLatestDefaults() {
+ MOZ_ASSERT(NS_IsMainThread());
+ MOZ_ASSERT(mState == eReady);
+
+ nsresult rv;
+
+ MonitorAutoLock lock(mMonitor);
+
+ for (const DefaultEntry& entry : mDefaultEntries) {
+ if (entry.mOp == DefaultEntry::eImportMatchTypeHost) {
+ // the import file format doesn't handle modification times, so we use
+ // 0, which AddInternal will convert to now()
+ int64_t modificationTime = 0;
+
+ rv = UpgradeHostToOriginAndInsert(
+ entry.mHostOrOrigin, entry.mType, entry.mPermission,
+ nsIPermissionManager::EXPIRE_NEVER, 0, modificationTime, false,
+ [&](const nsACString& aOrigin, const nsCString& aType,
+ uint32_t aPermission, uint32_t aExpireType, int64_t aExpireTime,
+ int64_t aModificationTime) {
+ nsCOMPtr<nsIPrincipal> principal;
+ nsresult rv =
+ GetPrincipalFromOrigin(aOrigin, IsOAForceStripPermission(aType),
+ getter_AddRefs(principal));
+ NS_ENSURE_SUCCESS(rv, rv);
+ rv =
+ AddInternal(principal, aType, aPermission,
+ cIDPermissionIsDefault, aExpireType, aExpireTime,
+ aModificationTime, PermissionManager::eDontNotify,
+ PermissionManager::eNoDBOperation, false, &aOrigin);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ if (StaticPrefs::permissions_isolateBy_privateBrowsing()) {
+ // Also import the permission for private browsing.
+ OriginAttributes attrs =
+ OriginAttributes(principal->OriginAttributesRef());
+ attrs.mPrivateBrowsingId = 1;
+ nsCOMPtr<nsIPrincipal> pbPrincipal =
+ BasePrincipal::Cast(principal)->CloneForcingOriginAttributes(
+ attrs);
+
+ rv = AddInternal(
+ pbPrincipal, aType, aPermission, cIDPermissionIsDefault,
+ aExpireType, aExpireTime, aModificationTime,
+ PermissionManager::eDontNotify,
+ PermissionManager::eNoDBOperation, false, &aOrigin);
+ NS_ENSURE_SUCCESS(rv, rv);
+ }
+
+ return NS_OK;
+ });
+
+ if (NS_FAILED(rv)) {
+ NS_WARNING("There was a problem importing a host permission");
+ }
+ continue;
+ }
+
+ MOZ_ASSERT(entry.mOp == DefaultEntry::eImportMatchTypeOrigin);
+
+ nsCOMPtr<nsIPrincipal> principal;
+ rv = GetPrincipalFromOrigin(entry.mHostOrOrigin,
+ IsOAForceStripPermission(entry.mType),
+ getter_AddRefs(principal));
+ if (NS_FAILED(rv)) {
+ NS_WARNING("Couldn't import an origin permission - malformed origin");
+ continue;
+ }
+
+ // the import file format doesn't handle modification times, so we use
+ // 0, which AddInternal will convert to now()
+ int64_t modificationTime = 0;
+
+ rv = AddInternal(principal, entry.mType, entry.mPermission,
+ cIDPermissionIsDefault, nsIPermissionManager::EXPIRE_NEVER,
+ 0, modificationTime, eDontNotify, eNoDBOperation);
+ if (NS_FAILED(rv)) {
+ NS_WARNING("There was a problem importing an origin permission");
+ }
+
+ if (StaticPrefs::permissions_isolateBy_privateBrowsing()) {
+ // Also import the permission for private browsing.
+ OriginAttributes attrs =
+ OriginAttributes(principal->OriginAttributesRef());
+ attrs.mPrivateBrowsingId = 1;
+ nsCOMPtr<nsIPrincipal> pbPrincipal =
+ BasePrincipal::Cast(principal)->CloneForcingOriginAttributes(attrs);
+ // May return nullptr if clone fails.
+ NS_ENSURE_TRUE(pbPrincipal, NS_ERROR_FAILURE);
+
+ rv = AddInternal(pbPrincipal, entry.mType, entry.mPermission,
+ cIDPermissionIsDefault,
+ nsIPermissionManager::EXPIRE_NEVER, 0, modificationTime,
+ eDontNotify, eNoDBOperation);
+ if (NS_FAILED(rv)) {
+ NS_WARNING(
+ "There was a problem importing an origin permission for private "
+ "browsing");
+ }
+ }
+ }
+
+ return NS_OK;
+}
+
+/**
+ * Perform the early steps of a permission check and determine whether we need
+ * to call CommonTestPermissionInternal() for the actual permission check.
+ *
+ * @param aPrincipal optional principal argument to check the permission for,
+ * can be nullptr if we aren't performing a principal-based
+ * check.
+ * @param aTypeIndex if the caller isn't sure what the index of the permission
+ * type to check for is in the mTypeArray member variable,
+ * it should pass -1, otherwise this would be the index of
+ * the type inside mTypeArray. This would only be something
+ * other than -1 in recursive invocations of this function.
+ * @param aType the permission type to test.
+ * @param aPermission out argument which will be a permission type that we
+ * will return from this function once the function is
+ * done.
+ * @param aDefaultPermission the default permission to be used if we can't
+ * determine the result of the permission check.
+ * @param aDefaultPermissionIsValid whether the previous argument contains a
+ * valid value.
+ * @param aExactHostMatch whether to look for the exact host name or also for
+ * subdomains that can have the same permission.
+ * @param aIncludingSession whether to include session permissions when
+ * testing for the permission.
+ */
+PermissionManager::TestPreparationResult
+PermissionManager::CommonPrepareToTestPermission(
+ nsIPrincipal* aPrincipal, int32_t aTypeIndex, const nsACString& aType,
+ uint32_t* aPermission, uint32_t aDefaultPermission,
+ bool aDefaultPermissionIsValid, bool aExactHostMatch,
+ bool aIncludingSession) {
+ auto* basePrin = BasePrincipal::Cast(aPrincipal);
+ if (basePrin && basePrin->IsSystemPrincipal()) {
+ *aPermission = ALLOW_ACTION;
+ return AsVariant(NS_OK);
+ }
+
+ EnsureReadCompleted();
+
+ // For some permissions, query the default from a pref. We want to avoid
+ // doing this for all permissions so that permissions can opt into having
+ // the pref lookup overhead on each call.
+ int32_t defaultPermission =
+ aDefaultPermissionIsValid ? aDefaultPermission : UNKNOWN_ACTION;
+ if (!aDefaultPermissionIsValid && HasDefaultPref(aType)) {
+ Unused << mDefaultPrefBranch->GetIntPref(PromiseFlatCString(aType).get(),
+ &defaultPermission);
+ }
+
+ // Set the default.
+ *aPermission = defaultPermission;
+
+ int32_t typeIndex =
+ aTypeIndex == -1 ? GetTypeIndex(aType, false) : aTypeIndex;
+
+ // For expanded principals, we want to iterate over the allowlist and see
+ // if the permission is granted for any of them.
+ if (basePrin && basePrin->Is<ExpandedPrincipal>()) {
+ auto ep = basePrin->As<ExpandedPrincipal>();
+ for (auto& prin : ep->AllowList()) {
+ uint32_t perm;
+ nsresult rv =
+ CommonTestPermission(prin, typeIndex, aType, &perm, defaultPermission,
+ true, aExactHostMatch, aIncludingSession);
+ if (NS_WARN_IF(NS_FAILED(rv))) {
+ return AsVariant(rv);
+ }
+
+ if (perm == nsIPermissionManager::ALLOW_ACTION) {
+ *aPermission = perm;
+ return AsVariant(NS_OK);
+ }
+ if (perm == nsIPermissionManager::PROMPT_ACTION) {
+ // Store it, but keep going to see if we can do better.
+ *aPermission = perm;
+ }
+ }
+
+ return AsVariant(NS_OK);
+ }
+
+ // If type == -1, the type isn't known, just signal that we are done.
+ if (typeIndex == -1) {
+ return AsVariant(NS_OK);
+ }
+
+ return AsVariant(typeIndex);
+}
+
+// If aTypeIndex is passed -1, we try to inder the type index from aType.
+nsresult PermissionManager::CommonTestPermission(
+ nsIPrincipal* aPrincipal, int32_t aTypeIndex, const nsACString& aType,
+ uint32_t* aPermission, uint32_t aDefaultPermission,
+ bool aDefaultPermissionIsValid, bool aExactHostMatch,
+ bool aIncludingSession) {
+ auto preparationResult = CommonPrepareToTestPermission(
+ aPrincipal, aTypeIndex, aType, aPermission, aDefaultPermission,
+ aDefaultPermissionIsValid, aExactHostMatch, aIncludingSession);
+ if (preparationResult.is<nsresult>()) {
+ return preparationResult.as<nsresult>();
+ }
+
+ return CommonTestPermissionInternal(
+ aPrincipal, nullptr, nullptr, preparationResult.as<int32_t>(), aType,
+ aPermission, aExactHostMatch, aIncludingSession);
+}
+
+// If aTypeIndex is passed -1, we try to inder the type index from aType.
+nsresult PermissionManager::CommonTestPermission(
+ nsIURI* aURI, int32_t aTypeIndex, const nsACString& aType,
+ uint32_t* aPermission, uint32_t aDefaultPermission,
+ bool aDefaultPermissionIsValid, bool aExactHostMatch,
+ bool aIncludingSession) {
+ auto preparationResult = CommonPrepareToTestPermission(
+ nullptr, aTypeIndex, aType, aPermission, aDefaultPermission,
+ aDefaultPermissionIsValid, aExactHostMatch, aIncludingSession);
+ if (preparationResult.is<nsresult>()) {
+ return preparationResult.as<nsresult>();
+ }
+
+ return CommonTestPermissionInternal(
+ nullptr, aURI, nullptr, preparationResult.as<int32_t>(), aType,
+ aPermission, aExactHostMatch, aIncludingSession);
+}
+
+nsresult PermissionManager::CommonTestPermission(
+ nsIURI* aURI, const OriginAttributes* aOriginAttributes, int32_t aTypeIndex,
+ const nsACString& aType, uint32_t* aPermission, uint32_t aDefaultPermission,
+ bool aDefaultPermissionIsValid, bool aExactHostMatch,
+ bool aIncludingSession) {
+ auto preparationResult = CommonPrepareToTestPermission(
+ nullptr, aTypeIndex, aType, aPermission, aDefaultPermission,
+ aDefaultPermissionIsValid, aExactHostMatch, aIncludingSession);
+ if (preparationResult.is<nsresult>()) {
+ return preparationResult.as<nsresult>();
+ }
+
+ return CommonTestPermissionInternal(
+ nullptr, aURI, aOriginAttributes, preparationResult.as<int32_t>(), aType,
+ aPermission, aExactHostMatch, aIncludingSession);
+}
+
+nsresult PermissionManager::TestPermissionWithoutDefaultsFromPrincipal(
+ nsIPrincipal* aPrincipal, const nsACString& aType, uint32_t* aPermission) {
+ MOZ_ASSERT(!HasDefaultPref(aType));
+
+ return CommonTestPermission(aPrincipal, -1, aType, aPermission,
+ nsIPermissionManager::UNKNOWN_ACTION, true, false,
+ true);
+}
+
+void PermissionManager::MaybeCompleteShutdown() {
+ MOZ_ASSERT(NS_IsMainThread());
+
+ nsCOMPtr<nsIAsyncShutdownClient> asc = GetAsyncShutdownBarrier();
+ MOZ_ASSERT(asc);
+
+ DebugOnly<nsresult> rv = asc->RemoveBlocker(this);
+ MOZ_ASSERT(NS_SUCCEEDED(rv));
+}
+
+// Async shutdown blocker methods
+
+NS_IMETHODIMP PermissionManager::GetName(nsAString& aName) {
+ aName = u"PermissionManager: Flushing data"_ns;
+ return NS_OK;
+}
+
+NS_IMETHODIMP PermissionManager::BlockShutdown(
+ nsIAsyncShutdownClient* aClient) {
+ RemoveIdleDailyMaintenanceJob();
+ RemoveAllFromMemory();
+ CloseDB(eShutdown);
+
+ gPermissionManager = nullptr;
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+PermissionManager::GetState(nsIPropertyBag** aBagOut) {
+ nsCOMPtr<nsIWritablePropertyBag2> propertyBag =
+ do_CreateInstance("@mozilla.org/hash-property-bag;1");
+
+ nsresult rv = propertyBag->SetPropertyAsInt32(u"state"_ns, mState);
+ if (NS_WARN_IF(NS_FAILED(rv))) {
+ return rv;
+ }
+
+ propertyBag.forget(aBagOut);
+
+ return NS_OK;
+}
+
+nsCOMPtr<nsIAsyncShutdownClient> PermissionManager::GetAsyncShutdownBarrier()
+ const {
+ nsresult rv;
+ nsCOMPtr<nsIAsyncShutdownService> svc =
+ do_GetService("@mozilla.org/async-shutdown-service;1", &rv);
+ if (NS_FAILED(rv)) {
+ return nullptr;
+ }
+
+ nsCOMPtr<nsIAsyncShutdownClient> client;
+ // This feels very late but there seem to be other services that rely on
+ // us later than "profile-before-change".
+ rv = svc->GetXpcomWillShutdown(getter_AddRefs(client));
+ MOZ_DIAGNOSTIC_ASSERT(NS_SUCCEEDED(rv));
+
+ return client;
+}
+
+void PermissionManager::MaybeStripOriginAttributes(
+ bool aForceStrip, OriginAttributes& aOriginAttributes) {
+ uint32_t flags = 0;
+
+ if (aForceStrip || !StaticPrefs::permissions_isolateBy_privateBrowsing()) {
+ flags |= OriginAttributes::STRIP_PRIVATE_BROWSING_ID;
+ }
+
+ if (aForceStrip || !StaticPrefs::permissions_isolateBy_userContext()) {
+ flags |= OriginAttributes::STRIP_USER_CONTEXT_ID;
+ }
+
+ if (flags != 0) {
+ aOriginAttributes.StripAttributes(flags);
+ }
+}
+
+} // namespace mozilla
diff --git a/extensions/permissions/PermissionManager.h b/extensions/permissions/PermissionManager.h
new file mode 100644
index 0000000000..a92d583e49
--- /dev/null
+++ b/extensions/permissions/PermissionManager.h
@@ -0,0 +1,682 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef mozilla_PermissionManager_h
+#define mozilla_PermissionManager_h
+
+#include "nsIPermissionManager.h"
+#include "nsIAsyncShutdown.h"
+#include "nsIObserver.h"
+#include "nsWeakReference.h"
+#include "nsCOMPtr.h"
+#include "nsIURI.h"
+#include "nsTHashtable.h"
+#include "nsTArray.h"
+#include "nsString.h"
+#include "nsHashKeys.h"
+#include "nsRefPtrHashtable.h"
+#include "mozilla/Atomics.h"
+#include "mozilla/Monitor.h"
+#include "mozilla/MozPromise.h"
+#include "mozilla/OriginAttributes.h"
+#include "mozilla/StaticMutex.h"
+#include "mozilla/ThreadBound.h"
+#include "mozilla/Variant.h"
+#include "mozilla/Vector.h"
+
+#include <utility>
+
+class mozIStorageConnection;
+class mozIStorageStatement;
+class nsIInputStream;
+class nsIPermission;
+class nsIPrefBranch;
+
+namespace IPC {
+struct Permission;
+}
+
+namespace mozilla {
+class OriginAttributesPattern;
+
+namespace dom {
+class ContentChild;
+} // namespace dom
+
+////////////////////////////////////////////////////////////////////////////////
+
+class PermissionManager final : public nsIPermissionManager,
+ public nsIObserver,
+ public nsSupportsWeakReference,
+ public nsIAsyncShutdownBlocker {
+ friend class dom::ContentChild;
+
+ public:
+ class PermissionEntry {
+ public:
+ PermissionEntry(int64_t aID, uint32_t aType, uint32_t aPermission,
+ uint32_t aExpireType, int64_t aExpireTime,
+ int64_t aModificationTime)
+ : mID(aID),
+ mExpireTime(aExpireTime),
+ mModificationTime(aModificationTime),
+ mType(aType),
+ mPermission(aPermission),
+ mExpireType(aExpireType),
+ mNonSessionPermission(aPermission),
+ mNonSessionExpireType(aExpireType),
+ mNonSessionExpireTime(aExpireTime) {}
+
+ int64_t mID;
+ int64_t mExpireTime;
+ int64_t mModificationTime;
+ uint32_t mType;
+ uint32_t mPermission;
+ uint32_t mExpireType;
+ uint32_t mNonSessionPermission;
+ uint32_t mNonSessionExpireType;
+ uint32_t mNonSessionExpireTime;
+ };
+
+ /**
+ * PermissionKey is the key used by PermissionHashKey hash table.
+ */
+ class PermissionKey {
+ public:
+ static PermissionKey* CreateFromPrincipal(nsIPrincipal* aPrincipal,
+ bool aForceStripOA,
+ bool aScopeToSite,
+ nsresult& aResult);
+ static PermissionKey* CreateFromURI(nsIURI* aURI, nsresult& aResult);
+ static PermissionKey* CreateFromURIAndOriginAttributes(
+ nsIURI* aURI, const OriginAttributes* aOriginAttributes,
+ bool aForceStripOA, nsresult& aResult);
+
+ explicit PermissionKey(const nsACString& aOrigin)
+ : mOrigin(aOrigin), mHashCode(HashString(aOrigin)) {}
+
+ bool operator==(const PermissionKey& aKey) const {
+ return mOrigin.Equals(aKey.mOrigin);
+ }
+
+ PLDHashNumber GetHashCode() const { return mHashCode; }
+
+ NS_INLINE_DECL_THREADSAFE_REFCOUNTING(PermissionKey)
+
+ const nsCString mOrigin;
+ const PLDHashNumber mHashCode;
+
+ private:
+ // Default ctor shouldn't be used.
+ PermissionKey() = delete;
+
+ // Dtor shouldn't be used outside of the class.
+ ~PermissionKey(){};
+ };
+
+ class PermissionHashKey : public nsRefPtrHashKey<PermissionKey> {
+ public:
+ explicit PermissionHashKey(const PermissionKey* aPermissionKey)
+ : nsRefPtrHashKey<PermissionKey>(aPermissionKey) {}
+
+ PermissionHashKey(PermissionHashKey&& toCopy)
+ : nsRefPtrHashKey<PermissionKey>(std::move(toCopy)),
+ mPermissions(std::move(toCopy.mPermissions)) {}
+
+ bool KeyEquals(const PermissionKey* aKey) const {
+ return *aKey == *GetKey();
+ }
+
+ static PLDHashNumber HashKey(const PermissionKey* aKey) {
+ return aKey->GetHashCode();
+ }
+
+ // Force the hashtable to use the copy constructor when shuffling entries
+ // around, otherwise the Auto part of our AutoTArray won't be happy!
+ enum { ALLOW_MEMMOVE = false };
+
+ inline nsTArray<PermissionEntry>& GetPermissions() { return mPermissions; }
+ inline const nsTArray<PermissionEntry>& GetPermissions() const {
+ return mPermissions;
+ }
+
+ inline int32_t GetPermissionIndex(uint32_t aType) const {
+ for (uint32_t i = 0; i < mPermissions.Length(); ++i)
+ if (mPermissions[i].mType == aType) return i;
+
+ return -1;
+ }
+
+ inline PermissionEntry GetPermission(uint32_t aType) const {
+ for (uint32_t i = 0; i < mPermissions.Length(); ++i)
+ if (mPermissions[i].mType == aType) return mPermissions[i];
+
+ // unknown permission... return relevant data
+ return PermissionEntry(-1, aType, nsIPermissionManager::UNKNOWN_ACTION,
+ nsIPermissionManager::EXPIRE_NEVER, 0, 0);
+ }
+
+ private:
+ AutoTArray<PermissionEntry, 1> mPermissions;
+ };
+
+ // nsISupports
+ NS_DECL_THREADSAFE_ISUPPORTS
+ NS_DECL_NSIPERMISSIONMANAGER
+ NS_DECL_NSIOBSERVER
+ NS_DECL_NSIASYNCSHUTDOWNBLOCKER
+
+ PermissionManager();
+ static already_AddRefed<nsIPermissionManager> GetXPCOMSingleton();
+ static PermissionManager* GetInstance();
+ nsresult Init();
+
+ // enums for AddInternal()
+ enum OperationType {
+ eOperationNone,
+ eOperationAdding,
+ eOperationRemoving,
+ eOperationChanging,
+ eOperationReplacingDefault
+ };
+
+ enum DBOperationType { eNoDBOperation, eWriteToDB };
+
+ enum NotifyOperationType { eDontNotify, eNotify };
+
+ // Similar to TestPermissionFromPrincipal, except that it is used only for
+ // permissions which can never have default values.
+ nsresult TestPermissionWithoutDefaultsFromPrincipal(nsIPrincipal* aPrincipal,
+ const nsACString& aType,
+ uint32_t* aPermission);
+
+ nsresult LegacyTestPermissionFromURI(
+ nsIURI* aURI, const OriginAttributes* aOriginAttributes,
+ const nsACString& aType, uint32_t* aPermission);
+
+ nsresult RemovePermissionsWithAttributes(OriginAttributesPattern& aAttrs);
+
+ /**
+ * See `nsIPermissionManager::GetPermissionsWithKey` for more info on
+ * permission keys.
+ *
+ * Get the permission key corresponding to the given Principal. This method is
+ * intentionally infallible, as we want to provide an permission key to every
+ * principal. Principals which don't have meaningful URIs with http://,
+ * https://, or ftp:// schemes are given the default "" Permission Key.
+ *
+ * @param aPrincipal The Principal which the key is to be extracted from.
+ * @param aForceStripOA Whether to force stripping the principals origin
+ * attributes prior to generating the key.
+ * @param aSiteScopePermissions Whether to prepare the key for permissions
+ * scoped to the Principal's site, rather than origin. These are looked
+ * up independently. Scoping of a permission is fully determined by its
+ * type and determined by calls to the function IsSiteScopedPermission.
+ * @param aKey A string which will be filled with the permission
+ * key.
+ */
+ static nsresult GetKeyForPrincipal(nsIPrincipal* aPrincipal,
+ bool aForceStripOA,
+ bool aSiteScopePermissions,
+ nsACString& aKey);
+
+ /**
+ * See `nsIPermissionManager::GetPermissionsWithKey` for more info on
+ * permission keys.
+ *
+ * Get the permission key corresponding to the given Origin. This method is
+ * like GetKeyForPrincipal, except that it avoids creating a nsIPrincipal
+ * object when you already have access to an origin string.
+ *
+ * If this method is passed a nonsensical origin string it may produce a
+ * nonsensical permission key result.
+ *
+ * @param aOrigin The origin which the key is to be extracted from.
+ * @param aForceStripOA Whether to force stripping the origins attributes
+ * prior to generating the key.
+ * @param aSiteScopePermissions Whether to prepare the key for permissions
+ * scoped to the Principal's site, rather than origin. These are looked
+ * up independently. Scoping of a permission is fully determined by its
+ * type and determined by calls to the function IsSiteScopedPermission.
+ * @param aKey A string which will be filled with the permission
+ * key.
+ */
+ static nsresult GetKeyForOrigin(const nsACString& aOrigin, bool aForceStripOA,
+ bool aSiteScopePermissions, nsACString& aKey);
+
+ /**
+ * See `nsIPermissionManager::GetPermissionsWithKey` for more info on
+ * permission keys.
+ *
+ * Get the permission key corresponding to the given Principal and type. This
+ * method is intentionally infallible, as we want to provide an permission key
+ * to every principal. Principals which don't have meaningful URIs with
+ * http://, https://, or ftp:// schemes are given the default "" Permission
+ * Key.
+ *
+ * This method is different from GetKeyForPrincipal in that it also takes
+ * permissions which must be sent down before loading a document into account.
+ *
+ * @param aPrincipal The Principal which the key is to be extracted from.
+ * @param aType The type of the permission to get the key for.
+ * @param aPermissionKey A string which will be filled with the permission
+ * key.
+ */
+ static nsresult GetKeyForPermission(nsIPrincipal* aPrincipal,
+ const nsACString& aType,
+ nsACString& aKey);
+
+ /**
+ * See `nsIPermissionManager::GetPermissionsWithKey` for more info on
+ * permission keys.
+ *
+ * Get all permissions keys which could correspond to the given principal.
+ * This method, like GetKeyForPrincipal, is infallible and should always
+ * produce at least one (key, origin) pair.
+ *
+ * Unlike GetKeyForPrincipal, this method also gets the keys for base domains
+ * of the given principal. All keys returned by this method must be available
+ * in the content process for a given URL to successfully have its permissions
+ * checked in the `aExactHostMatch = false` situation.
+ *
+ * @param aPrincipal The Principal which the key is to be extracted from.
+ * @return returns an array of (key, origin) pairs.
+ */
+ static nsTArray<std::pair<nsCString, nsCString>> GetAllKeysForPrincipal(
+ nsIPrincipal* aPrincipal);
+
+ // From ContentChild.
+ nsresult RemoveAllFromIPC();
+
+ /**
+ * Returns false if this permission manager wouldn't have the permission
+ * requested available.
+ *
+ * If aType is empty, checks that the permission manager would have all
+ * permissions available for the given principal.
+ */
+ bool PermissionAvailable(nsIPrincipal* aPrincipal, const nsACString& aType);
+
+ /**
+ * The content process doesn't have access to every permission. Instead, when
+ * LOAD_DOCUMENT_URI channels for http://, https://, and ftp:// URIs are
+ * opened, the permissions for those channels are sent down to the content
+ * process before the OnStartRequest message. Permissions for principals with
+ * other schemes are sent down at process startup.
+ *
+ * Permissions are keyed and grouped by "Permission Key"s.
+ * `PermissionManager::GetKeyForPrincipal` provides the mechanism for
+ * determining the permission key for a given principal.
+ *
+ * This method may only be called in the parent process. It fills the nsTArray
+ * argument with the IPC::Permission objects which have a matching origin.
+ *
+ * @param origin The origin to use to find the permissions of interest.
+ * @param key The key to use to find the permissions of interest. Only used
+ * when the origin argument is empty.
+ * @param perms An array which will be filled with the permissions which
+ * match the given origin.
+ */
+ bool GetPermissionsFromOriginOrKey(const nsACString& aOrigin,
+ const nsACString& aKey,
+ nsTArray<IPC::Permission>& aPerms);
+
+ /**
+ * See `PermissionManager::GetPermissionsWithKey` for more info on
+ * Permission keys.
+ *
+ * `SetPermissionsWithKey` may only be called in the Child process, and
+ * initializes the permission manager with the permissions for a given
+ * Permission key. marking permissions with that key as available.
+ *
+ * @param permissionKey The key for the permissions which have been sent
+ * over.
+ * @param perms An array with the permissions which match the given key.
+ */
+ void SetPermissionsWithKey(const nsACString& aPermissionKey,
+ nsTArray<IPC::Permission>& aPerms);
+
+ /**
+ * Add a callback which should be run when all permissions are available for
+ * the given nsIPrincipal. This method invokes the callback runnable
+ * synchronously when the permissions are already available. Otherwise the
+ * callback will be run asynchronously in SystemGroup when all permissions
+ * are available in the future.
+ *
+ * NOTE: This method will not request the permissions be sent by the parent
+ * process. This should only be used to wait for permissions which may not
+ * have arrived yet in order to ensure they are present.
+ *
+ * @param aPrincipal The principal to wait for permissions to be available
+ * for.
+ * @param aRunnable The runnable to run when permissions are available for
+ * the given principal.
+ */
+ void WhenPermissionsAvailable(nsIPrincipal* aPrincipal,
+ nsIRunnable* aRunnable);
+
+ /**
+ * Strip origin attributes for permissions, depending on permission isolation
+ * pref state.
+ * @param aForceStrip If true, strips user context and private browsing id,
+ * ignoring permission isolation prefs.
+ * @param aOriginAttributes object to strip.
+ */
+ static void MaybeStripOriginAttributes(bool aForceStrip,
+ OriginAttributes& aOriginAttributes);
+
+ private:
+ ~PermissionManager();
+ static StaticMutex sCreationMutex MOZ_UNANNOTATED;
+
+ /**
+ * Get all permissions for a given principal, which should not be isolated
+ * by user context or private browsing. The principal has its origin
+ * attributes stripped before perm db lookup. This is currently only affects
+ * the "cookie" permission.
+ * @param aPrincipal Used for creating the permission key.
+ * @param aSiteScopePermissions Used to specify whether to get strip perms for
+ * site scoped permissions (defined in IsSiteScopedPermission) or all other
+ * permissions. Also used to create the permission key.
+ */
+ nsresult GetStripPermsForPrincipal(nsIPrincipal* aPrincipal,
+ bool aSiteScopePermissions,
+ nsTArray<PermissionEntry>& aResult);
+
+ // Returns -1 on failure
+ int32_t GetTypeIndex(const nsACString& aType, bool aAdd);
+
+ // Returns whether the given combination of expire type and expire time are
+ // expired. Note that EXPIRE_SESSION only honors expireTime if it is nonzero.
+ bool HasExpired(uint32_t aExpireType, int64_t aExpireTime);
+
+ // Appends the permissions associated with this principal to aResult.
+ // If the onlySiteScopePermissions argument is true, the permissions searched
+ // are those for the site of the principal and only the permissions that are
+ // site-scoped are used.
+ nsresult GetAllForPrincipalHelper(nsIPrincipal* aPrincipal,
+ bool aSiteScopePermissions,
+ nsTArray<RefPtr<nsIPermission>>& aResult);
+
+ // Returns PermissionHashKey for a given { host, isInBrowserElement } tuple.
+ // This is not simply using PermissionKey because we will walk-up domains in
+ // case of |host| contains sub-domains. Returns null if nothing found. Also
+ // accepts host on the format "<foo>". This will perform an exact match lookup
+ // as the string doesn't contain any dots.
+ PermissionHashKey* GetPermissionHashKey(nsIPrincipal* aPrincipal,
+ uint32_t aType, bool aExactHostMatch);
+
+ // Returns PermissionHashKey for a given { host, isInBrowserElement } tuple.
+ // This is not simply using PermissionKey because we will walk-up domains in
+ // case of |host| contains sub-domains. Returns null if nothing found. Also
+ // accepts host on the format "<foo>". This will perform an exact match lookup
+ // as the string doesn't contain any dots.
+ PermissionHashKey* GetPermissionHashKey(
+ nsIURI* aURI, const OriginAttributes* aOriginAttributes, uint32_t aType,
+ bool aExactHostMatch);
+
+ // The int32_t is the type index, the nsresult is an early bail-out return
+ // code.
+ typedef Variant<int32_t, nsresult> TestPreparationResult;
+ TestPreparationResult CommonPrepareToTestPermission(
+ nsIPrincipal* aPrincipal, int32_t aTypeIndex, const nsACString& aType,
+ uint32_t* aPermission, uint32_t aDefaultPermission,
+ bool aDefaultPermissionIsValid, bool aExactHostMatch,
+ bool aIncludingSession);
+
+ // If aTypeIndex is passed -1, we try to inder the type index from aType.
+ nsresult CommonTestPermission(nsIPrincipal* aPrincipal, int32_t aTypeIndex,
+ const nsACString& aType, uint32_t* aPermission,
+ uint32_t aDefaultPermission,
+ bool aDefaultPermissionIsValid,
+ bool aExactHostMatch, bool aIncludingSession);
+
+ // If aTypeIndex is passed -1, we try to inder the type index from aType.
+ nsresult CommonTestPermission(nsIURI* aURI, int32_t aTypeIndex,
+ const nsACString& aType, uint32_t* aPermission,
+ uint32_t aDefaultPermission,
+ bool aDefaultPermissionIsValid,
+ bool aExactHostMatch, bool aIncludingSession);
+
+ nsresult CommonTestPermission(nsIURI* aURI,
+ const OriginAttributes* aOriginAttributes,
+ int32_t aTypeIndex, const nsACString& aType,
+ uint32_t* aPermission,
+ uint32_t aDefaultPermission,
+ bool aDefaultPermissionIsValid,
+ bool aExactHostMatch, bool aIncludingSession);
+
+ // Only one of aPrincipal or aURI is allowed to be passed in.
+ nsresult CommonTestPermissionInternal(
+ nsIPrincipal* aPrincipal, nsIURI* aURI,
+ const OriginAttributes* aOriginAttributes, int32_t aTypeIndex,
+ const nsACString& aType, uint32_t* aPermission, bool aExactHostMatch,
+ bool aIncludingSession);
+
+ nsresult OpenDatabase(nsIFile* permissionsFile);
+
+ void InitDB(bool aRemoveFile);
+ nsresult TryInitDB(bool aRemoveFile, nsIInputStream* aDefaultsInputStream);
+
+ void AddIdleDailyMaintenanceJob();
+ void RemoveIdleDailyMaintenanceJob();
+ void PerformIdleDailyMaintenance();
+
+ nsresult ImportLatestDefaults();
+ already_AddRefed<nsIInputStream> GetDefaultsInputStream();
+ void ConsumeDefaultsInputStream(nsIInputStream* aDefaultsInputStream,
+ const MonitorAutoLock& aProofOfLock);
+
+ nsresult CreateTable();
+ void NotifyObserversWithPermission(nsIPrincipal* aPrincipal,
+ const nsACString& aType,
+ uint32_t aPermission, uint32_t aExpireType,
+ int64_t aExpireTime,
+ int64_t aModificationTime,
+ const char16_t* aData);
+ void NotifyObservers(nsIPermission* aPermission, const char16_t* aData);
+
+ // Finalize all statements, close the DB and null it.
+ enum CloseDBNextOp {
+ eNone,
+ eRebuldOnSuccess,
+ eShutdown,
+ };
+ void CloseDB(CloseDBNextOp aNextOp);
+
+ nsresult RemoveAllInternal(bool aNotifyObservers);
+ nsresult RemoveAllFromMemory();
+
+ void UpdateDB(OperationType aOp, int64_t aID, const nsACString& aOrigin,
+ const nsACString& aType, uint32_t aPermission,
+ uint32_t aExpireType, int64_t aExpireTime,
+ int64_t aModificationTime);
+
+ /**
+ * This method removes all permissions modified after the specified time.
+ */
+ nsresult RemoveAllModifiedSince(int64_t aModificationTime);
+
+ template <class T>
+ nsresult RemovePermissionEntries(T aCondition);
+
+ template <class T>
+ nsresult GetPermissionEntries(T aCondition,
+ nsTArray<RefPtr<nsIPermission>>& aResult);
+
+ // This method must be called before doing any operation to be sure that the
+ // DB reading has been completed. This method is also in charge to complete
+ // the migrations if needed.
+ void EnsureReadCompleted();
+
+ nsresult AddInternal(nsIPrincipal* aPrincipal, const nsACString& aType,
+ uint32_t aPermission, int64_t aID, uint32_t aExpireType,
+ int64_t aExpireTime, int64_t aModificationTime,
+ NotifyOperationType aNotifyOperation,
+ DBOperationType aDBOperation,
+ const bool aIgnoreSessionPermissions = false,
+ const nsACString* aOriginString = nullptr,
+ const bool aAllowPersistInPrivateBrowsing = false);
+
+ void MaybeAddReadEntryFromMigration(const nsACString& aOrigin,
+ const nsCString& aType,
+ uint32_t aPermission,
+ uint32_t aExpireType, int64_t aExpireTime,
+ int64_t aModificationTime, int64_t aId);
+
+ nsCOMPtr<nsIAsyncShutdownClient> GetAsyncShutdownBarrier() const;
+
+ void MaybeCompleteShutdown();
+
+ nsRefPtrHashtable<nsCStringHashKey, GenericNonExclusivePromise::Private>
+ mPermissionKeyPromiseMap;
+
+ nsCOMPtr<nsIFile> mPermissionsFile;
+
+ // This monitor is used to ensure the database reading before any other
+ // operation. The reading of the database happens OMT. See |State| to know the
+ // steps of the database reading.
+ Monitor mMonitor MOZ_UNANNOTATED;
+
+ enum State {
+ // Initial state. The database has not been read yet.
+ // |TryInitDB| is called at startup time to read the database OMT.
+ // During the reading, |mReadEntries| will be populated with all the
+ // existing permissions.
+ eInitializing,
+
+ // At the end of the database reading, we are in this state. A runnable is
+ // executed to call |EnsureReadCompleted| on the main thread.
+ // |EnsureReadCompleted| processes |mReadEntries| and goes to the next
+ // state.
+ eDBInitialized,
+
+ // The permissions are fully read and any pending operation can proceed.
+ eReady,
+
+ // The permission manager has been terminated. No extra database operations
+ // will be allowed.
+ eClosed,
+ };
+ Atomic<State> mState;
+
+ // A single entry, from the database.
+ struct ReadEntry {
+ ReadEntry()
+ : mId(0),
+ mPermission(0),
+ mExpireType(0),
+ mExpireTime(0),
+ mModificationTime(0) {}
+
+ nsCString mOrigin;
+ nsCString mType;
+ int64_t mId;
+ uint32_t mPermission;
+ uint32_t mExpireType;
+ int64_t mExpireTime;
+ int64_t mModificationTime;
+
+ // true if this entry is the result of a migration.
+ bool mFromMigration;
+ };
+
+ // List of entries read from the database. It will be populated OMT and
+ // consumed on the main-thread.
+ // This array is protected by the monitor.
+ nsTArray<ReadEntry> mReadEntries;
+
+ // A single entry, from the database.
+ struct MigrationEntry {
+ MigrationEntry()
+ : mId(0),
+ mPermission(0),
+ mExpireType(0),
+ mExpireTime(0),
+ mModificationTime(0),
+ mIsInBrowserElement(false) {}
+
+ nsCString mHost;
+ nsCString mType;
+ int64_t mId;
+ uint32_t mPermission;
+ uint32_t mExpireType;
+ int64_t mExpireTime;
+ int64_t mModificationTime;
+
+ // Legacy, for migration.
+ bool mIsInBrowserElement;
+ };
+
+ // List of entries read from the database. It will be populated OMT and
+ // consumed on the main-thread. The migration entries will be converted to
+ // ReadEntry in |CompleteMigrations|.
+ // This array is protected by the monitor.
+ nsTArray<MigrationEntry> mMigrationEntries;
+
+ // A single entry from the defaults URL.
+ struct DefaultEntry {
+ DefaultEntry() : mOp(eImportMatchTypeHost), mPermission(0) {}
+
+ enum Op {
+ eImportMatchTypeHost,
+ eImportMatchTypeOrigin,
+ };
+
+ Op mOp;
+
+ nsCString mHostOrOrigin;
+ nsCString mType;
+ uint32_t mPermission;
+ };
+
+ // List of entries read from the default settings.
+ // This array is protected by the monitor.
+ nsTArray<DefaultEntry> mDefaultEntries;
+
+ nsresult Read(const MonitorAutoLock& aProofOfLock);
+ void CompleteRead();
+
+ void CompleteMigrations();
+
+ bool mMemoryOnlyDB;
+
+ nsTHashtable<PermissionHashKey> mPermissionTable;
+ // a unique, monotonically increasing id used to identify each database entry
+ int64_t mLargestID;
+
+ nsCOMPtr<nsIPrefBranch> mDefaultPrefBranch;
+
+ // NOTE: Ensure this is the last member since it has a large inline buffer.
+ // An array to store the strings identifying the different types.
+ Vector<nsCString, 512> mTypeArray;
+
+ nsCOMPtr<nsIThread> mThread;
+
+ struct ThreadBoundData {
+ nsCOMPtr<mozIStorageConnection> mDBConn;
+
+ nsCOMPtr<mozIStorageStatement> mStmtInsert;
+ nsCOMPtr<mozIStorageStatement> mStmtDelete;
+ nsCOMPtr<mozIStorageStatement> mStmtUpdate;
+ };
+ ThreadBound<ThreadBoundData> mThreadBoundData;
+
+ friend class DeleteFromMozHostListener;
+ friend class CloseDatabaseListener;
+};
+
+// {4F6B5E00-0C36-11d5-A535-0010A401EB10}
+#define NS_PERMISSIONMANAGER_CID \
+ { \
+ 0x4f6b5e00, 0xc36, 0x11d5, { \
+ 0xa5, 0x35, 0x0, 0x10, 0xa4, 0x1, 0xeb, 0x10 \
+ } \
+ }
+
+} // namespace mozilla
+
+#endif // mozilla_PermissionManager_h
diff --git a/extensions/permissions/components.conf b/extensions/permissions/components.conf
new file mode 100644
index 0000000000..62f4f7ba1c
--- /dev/null
+++ b/extensions/permissions/components.conf
@@ -0,0 +1,25 @@
+# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
+# vim: set filetype=python:
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+Classes = [
+ {
+ 'name': 'PermissionManager',
+ 'js_name': 'perms',
+ 'cid': '{4f6b5e00-0c36-11d5-a535-0010a401eb10}',
+ 'contract_ids': ['@mozilla.org/permissionmanager;1'],
+ 'interfaces': ['nsIPermissionManager'],
+ 'singleton': True,
+ 'type': 'nsIPermissionManager',
+ 'constructor': 'mozilla::PermissionManager::GetXPCOMSingleton',
+ 'headers': ['/extensions/permissions/PermissionManager.h'],
+ },
+ {
+ 'cid': '{07611dc6-bf4d-4d8a-a64b-f3a5904dddc7}',
+ 'contract_ids': ['@mozilla.org/permissiondelegatehandler;1'],
+ 'type': 'PermissionDelegateHandler',
+ 'headers': ['/extensions/permissions/PermissionDelegateHandler.h'],
+ },
+]
diff --git a/extensions/permissions/moz.build b/extensions/permissions/moz.build
new file mode 100644
index 0000000000..6cdac60926
--- /dev/null
+++ b/extensions/permissions/moz.build
@@ -0,0 +1,39 @@
+# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
+# vim: set filetype=python:
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+TEST_DIRS += ["test"]
+
+TESTING_JS_MODULES += [
+ "test/PermissionTestUtils.sys.mjs",
+]
+
+EXPORTS.mozilla += [
+ "Permission.h",
+ "PermissionDelegateHandler.h",
+ "PermissionDelegateIPCUtils.h",
+ "PermissionManager.h",
+]
+
+UNIFIED_SOURCES += [
+ "Permission.cpp",
+ "PermissionDelegateHandler.cpp",
+ "PermissionManager.cpp",
+]
+
+XPCOM_MANIFESTS += [
+ "components.conf",
+]
+
+LOCAL_INCLUDES += [
+ "/caps",
+]
+
+include("/ipc/chromium/chromium-config.mozbuild")
+
+FINAL_LIBRARY = "xul"
+
+with Files("**"):
+ BUG_COMPONENT = ("Core", "Permission Manager")
diff --git a/extensions/permissions/test/PermissionTestUtils.sys.mjs b/extensions/permissions/test/PermissionTestUtils.sys.mjs
new file mode 100644
index 0000000000..84601376ba
--- /dev/null
+++ b/extensions/permissions/test/PermissionTestUtils.sys.mjs
@@ -0,0 +1,111 @@
+/* Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/publicdomain/zero/1.0/ */
+
+/*
+ * Utility module for tests to access the PermissionManager
+ * with uri or origin string parameters.
+ */
+
+let pm = Services.perms;
+
+let secMan = Services.scriptSecurityManager;
+
+/**
+ * Convert origin string or uri to principal.
+ * If passed an nsIPrincipal it will be returned without conversion.
+ *
+ * @param {Ci.nsIPrincipal|Ci.nsIURI|string} subject - Subject to convert to principal
+ * @returns {Ci.nsIPrincipal} Principal created from subject
+ */
+function convertToPrincipal(subject) {
+ if (subject instanceof Ci.nsIPrincipal) {
+ return subject;
+ }
+ if (typeof subject === "string") {
+ return secMan.createContentPrincipalFromOrigin(subject);
+ }
+ if (subject === null || subject instanceof Ci.nsIURI) {
+ return secMan.createContentPrincipal(subject, {});
+ }
+ throw new Error(
+ "subject parameter must be an nsIURI an origin string or a principal."
+ );
+}
+
+export let PermissionTestUtils = {
+ /**
+ * Add permission information for a given subject.
+ * Subject can be a principal, uri or origin string.
+ *
+ * @see nsIPermissionManager for documentation
+ *
+ * @param {Ci.nsIPrincipal|Ci.nsIURI|string} subject
+ * @param {*} args
+ */
+ add(subject, ...args) {
+ return pm.addFromPrincipal(convertToPrincipal(subject), ...args);
+ },
+ /**
+ * Get all custom permissions for a given subject.
+ * Subject can be a principal, uri or origin string.
+ *
+ * @see nsIPermissionManager for documentation
+ *
+ * @param {Ci.nsIPrincipal|Ci.nsIURI|string} subject
+ * @param {*} args
+ */
+ getAll(subject, ...args) {
+ return pm.getAllForPrincipal(convertToPrincipal(subject), ...args);
+ },
+ /**
+ * Remove permission information for a given subject and permission type
+ * Subject can be a principal, uri or origin string.
+ *
+ * @see nsIPermissionManager for documentation
+ *
+ * @param {Ci.nsIPrincipal|Ci.nsIURI|string} subject
+ * @param {*} args
+ */
+ remove(subject, ...args) {
+ return pm.removeFromPrincipal(convertToPrincipal(subject), ...args);
+ },
+ /**
+ * Test whether a website has permission to perform the given action.
+ * Subject can be a principal, uri or origin string.
+ *
+ * @see nsIPermissionManager for documentation
+ *
+ * @param {Ci.nsIPrincipal|Ci.nsIURI|string} subject
+ * @param {*} args
+ */
+ testPermission(subject, ...args) {
+ return pm.testPermissionFromPrincipal(convertToPrincipal(subject), ...args);
+ },
+ /**
+ * Test whether a website has permission to perform the given action.
+ * Subject can be a principal, uri or origin string.
+ *
+ * @see nsIPermissionManager for documentation
+ *
+ * @param {Ci.nsIPrincipal|Ci.nsIURI|string} subject
+ * @param {*} args
+ */
+ testExactPermission(subject, ...args) {
+ return pm.testExactPermissionFromPrincipal(
+ convertToPrincipal(subject),
+ ...args
+ );
+ },
+ /**
+ * Get the permission object associated with the given subject and action.
+ * Subject can be a principal, uri or origin string.
+ *
+ * @see nsIPermissionManager for documentation
+ *
+ * @param {Ci.nsIPrincipal|Ci.nsIURI|string} subject
+ * @param {*} args
+ */
+ getPermissionObject(subject, type, exactHost = false) {
+ return pm.getPermissionObject(convertToPrincipal(subject), type, exactHost);
+ },
+};
diff --git a/extensions/permissions/test/browser.ini b/extensions/permissions/test/browser.ini
new file mode 100644
index 0000000000..b71b10dfaf
--- /dev/null
+++ b/extensions/permissions/test/browser.ini
@@ -0,0 +1,8 @@
+[DEFAULT]
+
+[browser_permmgr_sync.js]
+# The browser_permmgr_sync test runs code
+# paths which would hit the debug only assertion in
+# PermissionManager::PermissionKey::CreateFromPrincipal.
+skip-if = debug
+[browser_permmgr_viewsrc.js]
diff --git a/extensions/permissions/test/browser_permmgr_sync.js b/extensions/permissions/test/browser_permmgr_sync.js
new file mode 100644
index 0000000000..619c29842c
--- /dev/null
+++ b/extensions/permissions/test/browser_permmgr_sync.js
@@ -0,0 +1,448 @@
+function addPerm(aOrigin, aName) {
+ let principal =
+ Services.scriptSecurityManager.createContentPrincipalFromOrigin(aOrigin);
+ Services.perms.addFromPrincipal(
+ principal,
+ aName,
+ Services.perms.ALLOW_ACTION
+ );
+}
+
+add_task(async function () {
+ // Make sure that we get a new process for the tab which we create. This is
+ // important, because we want to assert information about the initial state
+ // of the local permissions cache.
+
+ addPerm("http://example.com", "perm1");
+ addPerm("http://foo.bar.example.com", "perm2");
+ addPerm("about:home", "perm3");
+ addPerm("https://example.com", "perm4");
+ // NOTE: This permission is a preload permission, so it should be available in
+ // the content process from startup.
+ addPerm("https://somerandomwebsite.com", "cookie");
+
+ await BrowserTestUtils.withNewTab(
+ { gBrowser, url: "about:blank", forceNewProcess: true },
+ async function (aBrowser) {
+ await SpecialPowers.spawn(aBrowser, [], async function () {
+ // Before the load http URIs shouldn't have been sent down yet
+ is(
+ Services.perms.testPermissionFromPrincipal(
+ Services.scriptSecurityManager.createContentPrincipalFromOrigin(
+ "http://example.com"
+ ),
+ "perm1"
+ ),
+ Services.perms.UNKNOWN_ACTION,
+ "perm1-1"
+ );
+ is(
+ Services.perms.testPermissionFromPrincipal(
+ Services.scriptSecurityManager.createContentPrincipalFromOrigin(
+ "http://foo.bar.example.com"
+ ),
+ "perm2"
+ ),
+ Services.perms.UNKNOWN_ACTION,
+ "perm2-1"
+ );
+ is(
+ Services.perms.testPermissionFromPrincipal(
+ Services.scriptSecurityManager.createContentPrincipalFromOrigin(
+ "about:home"
+ ),
+ "perm3"
+ ),
+ Services.perms.ALLOW_ACTION,
+ "perm3-1"
+ );
+ is(
+ Services.perms.testPermissionFromPrincipal(
+ Services.scriptSecurityManager.createContentPrincipalFromOrigin(
+ "https://example.com"
+ ),
+ "perm4"
+ ),
+ Services.perms.UNKNOWN_ACTION,
+ "perm4-1"
+ );
+ is(
+ Services.perms.testPermissionFromPrincipal(
+ Services.scriptSecurityManager.createContentPrincipalFromOrigin(
+ "https://somerandomwebsite.com"
+ ),
+ "cookie"
+ ),
+ Services.perms.ALLOW_ACTION,
+ "cookie-1"
+ );
+
+ let iframe = content.document.createElement("iframe");
+
+ // Perform a load of example.com
+ await new Promise(resolve => {
+ iframe.setAttribute("src", "http://example.com");
+ iframe.onload = resolve;
+ content.document.body.appendChild(iframe);
+ });
+
+ // After the load finishes, the iframe process should know about example.com, but not foo.bar.example.com
+ await content.SpecialPowers.spawn(iframe, [], async function () {
+ is(
+ Services.perms.testPermissionFromPrincipal(
+ Services.scriptSecurityManager.createContentPrincipalFromOrigin(
+ "http://example.com"
+ ),
+ "perm1"
+ ),
+ Services.perms.ALLOW_ACTION,
+ "perm1-2"
+ );
+
+ is(
+ Services.perms.testPermissionFromPrincipal(
+ Services.scriptSecurityManager.createContentPrincipalFromOrigin(
+ "http://foo.bar.example.com"
+ ),
+ "perm2"
+ ),
+ Services.perms.UNKNOWN_ACTION,
+ "perm2-2"
+ );
+
+ is(
+ Services.perms.testPermissionFromPrincipal(
+ Services.scriptSecurityManager.createContentPrincipalFromOrigin(
+ "about:home"
+ ),
+ "perm3"
+ ),
+ Services.perms.ALLOW_ACTION,
+ "perm3-2"
+ );
+
+ is(
+ Services.perms.testPermissionFromPrincipal(
+ Services.scriptSecurityManager.createContentPrincipalFromOrigin(
+ "https://example.com"
+ ),
+ "perm4"
+ ),
+ Services.perms.UNKNOWN_ACTION,
+ "perm4-2"
+ );
+
+ is(
+ Services.perms.testPermissionFromPrincipal(
+ Services.scriptSecurityManager.createContentPrincipalFromOrigin(
+ "https://somerandomwebsite.com"
+ ),
+ "cookie"
+ ),
+ Services.perms.ALLOW_ACTION,
+ "cookie-2"
+ );
+ });
+
+ // In Fission only, the parent process should have no knowledge about the child
+ // process permissions
+ is(
+ Services.perms.testPermissionFromPrincipal(
+ Services.scriptSecurityManager.createContentPrincipalFromOrigin(
+ "http://example.com"
+ ),
+ "perm1"
+ ),
+ SpecialPowers.useRemoteSubframes
+ ? Services.perms.UNKNOWN_ACTION
+ : Services.perms.ALLOW_ACTION,
+ "perm1-3"
+ );
+
+ is(
+ Services.perms.testPermissionFromPrincipal(
+ Services.scriptSecurityManager.createContentPrincipalFromOrigin(
+ "http://foo.bar.example.com"
+ ),
+ "perm2"
+ ),
+ Services.perms.UNKNOWN_ACTION,
+ "perm2-3"
+ );
+
+ is(
+ Services.perms.testPermissionFromPrincipal(
+ Services.scriptSecurityManager.createContentPrincipalFromOrigin(
+ "https://example.com"
+ ),
+ "perm4"
+ ),
+ Services.perms.UNKNOWN_ACTION,
+ "perm4-3"
+ );
+ });
+
+ addPerm("http://example.com", "newperm1");
+ addPerm("http://foo.bar.example.com", "newperm2");
+ addPerm("about:home", "newperm3");
+ addPerm("https://example.com", "newperm4");
+ addPerm("https://someotherrandomwebsite.com", "cookie");
+
+ await SpecialPowers.spawn(aBrowser, [], async function () {
+ // The new permissions should be available, but only for
+ // http://example.com (without Fission), and about:home.
+ is(
+ Services.perms.testPermissionFromPrincipal(
+ Services.scriptSecurityManager.createContentPrincipalFromOrigin(
+ "http://example.com"
+ ),
+ "perm1"
+ ),
+ SpecialPowers.useRemoteSubframes
+ ? Services.perms.UNKNOWN_ACTION
+ : Services.perms.ALLOW_ACTION,
+ "perm1-4"
+ );
+ is(
+ Services.perms.testPermissionFromPrincipal(
+ Services.scriptSecurityManager.createContentPrincipalFromOrigin(
+ "http://example.com"
+ ),
+ "newperm1"
+ ),
+ SpecialPowers.useRemoteSubframes
+ ? Services.perms.UNKNOWN_ACTION
+ : Services.perms.ALLOW_ACTION,
+ "newperm1-1"
+ );
+ is(
+ Services.perms.testPermissionFromPrincipal(
+ Services.scriptSecurityManager.createContentPrincipalFromOrigin(
+ "http://foo.bar.example.com"
+ ),
+ "perm2"
+ ),
+ Services.perms.UNKNOWN_ACTION,
+ "perm2-4"
+ );
+ is(
+ Services.perms.testPermissionFromPrincipal(
+ Services.scriptSecurityManager.createContentPrincipalFromOrigin(
+ "http://foo.bar.example.com"
+ ),
+ "newperm2"
+ ),
+ Services.perms.UNKNOWN_ACTION,
+ "newperm2-1"
+ );
+ is(
+ Services.perms.testPermissionFromPrincipal(
+ Services.scriptSecurityManager.createContentPrincipalFromOrigin(
+ "about:home"
+ ),
+ "perm3"
+ ),
+ Services.perms.ALLOW_ACTION,
+ "perm3-3"
+ );
+ is(
+ Services.perms.testPermissionFromPrincipal(
+ Services.scriptSecurityManager.createContentPrincipalFromOrigin(
+ "about:home"
+ ),
+ "newperm3"
+ ),
+ Services.perms.ALLOW_ACTION,
+ "newperm3-1"
+ );
+ is(
+ Services.perms.testPermissionFromPrincipal(
+ Services.scriptSecurityManager.createContentPrincipalFromOrigin(
+ "https://example.com"
+ ),
+ "perm4"
+ ),
+ Services.perms.UNKNOWN_ACTION,
+ "perm4-4"
+ );
+ is(
+ Services.perms.testPermissionFromPrincipal(
+ Services.scriptSecurityManager.createContentPrincipalFromOrigin(
+ "https://example.com"
+ ),
+ "newperm4"
+ ),
+ Services.perms.UNKNOWN_ACTION,
+ "newperm4-1"
+ );
+ is(
+ Services.perms.testPermissionFromPrincipal(
+ Services.scriptSecurityManager.createContentPrincipalFromOrigin(
+ "https://somerandomwebsite.com"
+ ),
+ "cookie"
+ ),
+ Services.perms.ALLOW_ACTION,
+ "cookie-3"
+ );
+ is(
+ Services.perms.testPermissionFromPrincipal(
+ Services.scriptSecurityManager.createContentPrincipalFromOrigin(
+ "https://someotherrandomwebsite.com"
+ ),
+ "cookie"
+ ),
+ Services.perms.ALLOW_ACTION,
+ "othercookie-3"
+ );
+
+ let iframe = content.document.createElement("iframe");
+ // Loading a subdomain now, on https
+ await new Promise(resolve => {
+ iframe.setAttribute("src", "https://sub1.test1.example.com");
+ iframe.onload = resolve;
+ content.document.body.appendChild(iframe);
+ });
+
+ // After the load finishes, the iframe process should not know about
+ // the permissions of its base domain.
+ await content.SpecialPowers.spawn(iframe, [], async function () {
+ is(
+ Services.perms.testPermissionFromPrincipal(
+ Services.scriptSecurityManager.createContentPrincipalFromOrigin(
+ "https://example.com"
+ ),
+ "perm4"
+ ),
+ Services.perms.ALLOW_ACTION,
+ "perm4-5"
+ );
+
+ // In Fission not across schemes, though.
+ is(
+ Services.perms.testPermissionFromPrincipal(
+ Services.scriptSecurityManager.createContentPrincipalFromOrigin(
+ "http://example.com"
+ ),
+ "perm1"
+ ),
+ SpecialPowers.useRemoteSubframes
+ ? Services.perms.UNKNOWN_ACTION
+ : Services.perms.ALLOW_ACTION,
+ "perm1-5"
+ );
+ is(
+ Services.perms.testPermissionFromPrincipal(
+ Services.scriptSecurityManager.createContentPrincipalFromOrigin(
+ "http://example.com"
+ ),
+ "newperm1"
+ ),
+ SpecialPowers.useRemoteSubframes
+ ? Services.perms.UNKNOWN_ACTION
+ : Services.perms.ALLOW_ACTION,
+ "newperm1-2"
+ );
+ });
+
+ // The parent process should still have no permission under Fission.
+ is(
+ Services.perms.testPermissionFromPrincipal(
+ Services.scriptSecurityManager.createContentPrincipalFromOrigin(
+ "http://example.com"
+ ),
+ "perm1"
+ ),
+ SpecialPowers.useRemoteSubframes
+ ? Services.perms.UNKNOWN_ACTION
+ : Services.perms.ALLOW_ACTION,
+ "perm1-4"
+ );
+ is(
+ Services.perms.testPermissionFromPrincipal(
+ Services.scriptSecurityManager.createContentPrincipalFromOrigin(
+ "http://example.com"
+ ),
+ "newperm1"
+ ),
+ SpecialPowers.useRemoteSubframes
+ ? Services.perms.UNKNOWN_ACTION
+ : Services.perms.ALLOW_ACTION,
+ "newperm1-3"
+ );
+ is(
+ Services.perms.testPermissionFromPrincipal(
+ Services.scriptSecurityManager.createContentPrincipalFromOrigin(
+ "https://example.com"
+ ),
+ "perm4"
+ ),
+ SpecialPowers.useRemoteSubframes
+ ? Services.perms.UNKNOWN_ACTION
+ : Services.perms.ALLOW_ACTION,
+ "perm4-6"
+ );
+ is(
+ Services.perms.testPermissionFromPrincipal(
+ Services.scriptSecurityManager.createContentPrincipalFromOrigin(
+ "http://foo.bar.example.com"
+ ),
+ "perm2"
+ ),
+ Services.perms.UNKNOWN_ACTION,
+ "perm2-5"
+ );
+ is(
+ Services.perms.testPermissionFromPrincipal(
+ Services.scriptSecurityManager.createContentPrincipalFromOrigin(
+ "http://foo.bar.example.com"
+ ),
+ "newperm2"
+ ),
+ Services.perms.UNKNOWN_ACTION,
+ "newperm2-2"
+ );
+ is(
+ Services.perms.testPermissionFromPrincipal(
+ Services.scriptSecurityManager.createContentPrincipalFromOrigin(
+ "about:home"
+ ),
+ "perm3"
+ ),
+ Services.perms.ALLOW_ACTION,
+ "perm3-4"
+ );
+ is(
+ Services.perms.testPermissionFromPrincipal(
+ Services.scriptSecurityManager.createContentPrincipalFromOrigin(
+ "about:home"
+ ),
+ "newperm3"
+ ),
+ Services.perms.ALLOW_ACTION,
+ "newperm3-2"
+ );
+ is(
+ Services.perms.testPermissionFromPrincipal(
+ Services.scriptSecurityManager.createContentPrincipalFromOrigin(
+ "https://somerandomwebsite.com"
+ ),
+ "cookie"
+ ),
+ Services.perms.ALLOW_ACTION,
+ "cookie-4"
+ );
+ is(
+ Services.perms.testPermissionFromPrincipal(
+ Services.scriptSecurityManager.createContentPrincipalFromOrigin(
+ "https://someotherrandomwebsite.com"
+ ),
+ "cookie"
+ ),
+ Services.perms.ALLOW_ACTION,
+ "othercookie-4"
+ );
+ });
+ }
+ );
+});
diff --git a/extensions/permissions/test/browser_permmgr_viewsrc.js b/extensions/permissions/test/browser_permmgr_viewsrc.js
new file mode 100644
index 0000000000..64dcb0413c
--- /dev/null
+++ b/extensions/permissions/test/browser_permmgr_viewsrc.js
@@ -0,0 +1,28 @@
+add_task(async function () {
+ // Add a permission for example.com, start a new content process, and make
+ // sure that the permission has been sent down.
+ let principal =
+ Services.scriptSecurityManager.createContentPrincipalFromOrigin(
+ "https://example.com"
+ );
+ Services.perms.addFromPrincipal(
+ principal,
+ "viewsourceTestingPerm",
+ Services.perms.ALLOW_ACTION
+ );
+
+ let tab = await BrowserTestUtils.openNewForegroundTab(
+ gBrowser,
+ "view-source:https://example.com",
+ /* waitForLoad */ true,
+ /* waitForStateStop */ false,
+ /* forceNewProcess */ true
+ );
+ await SpecialPowers.spawn(tab.linkedBrowser, [principal], async function (p) {
+ is(
+ Services.perms.testPermissionFromPrincipal(p, "viewsourceTestingPerm"),
+ Services.perms.ALLOW_ACTION
+ );
+ });
+ BrowserTestUtils.removeTab(tab);
+});
diff --git a/extensions/permissions/test/gtest/PermissionManagerTest.cpp b/extensions/permissions/test/gtest/PermissionManagerTest.cpp
new file mode 100644
index 0000000000..b69a7d46f2
--- /dev/null
+++ b/extensions/permissions/test/gtest/PermissionManagerTest.cpp
@@ -0,0 +1,52 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "nsNetUtil.h"
+#include "mozilla/BasePrincipal.h"
+#include "mozilla/OriginAttributes.h"
+#include "mozilla/PermissionManager.h"
+#include "mozilla/RefPtr.h"
+#include "mozilla/Unused.h"
+#include "gtest/gtest.h"
+#include "gtest/MozGTestBench.h"
+
+using namespace mozilla;
+
+class PermissionManagerTester : public ::testing::Test {
+ protected:
+ PermissionManagerTester()
+ : mNonExistentType("permissionTypeThatIsGuaranteedToNeverExist"_ns) {}
+ void SetUp() override {
+ mPermissionManager = PermissionManager::GetInstance();
+ nsCOMPtr<nsIURI> uri;
+ nsresult rv =
+ NS_NewURI(getter_AddRefs(uri),
+ "https://test.origin.with.subdomains.example.com"_ns);
+ MOZ_RELEASE_ASSERT(NS_SUCCEEDED(rv));
+ mPrincipal =
+ mozilla::BasePrincipal::CreateContentPrincipal(uri, OriginAttributes());
+ }
+
+ void TearDown() override {
+ mPermissionManager = nullptr;
+ mPrincipal = nullptr;
+ }
+
+ static const unsigned kNumIterations = 100000;
+
+ nsLiteralCString mNonExistentType;
+ RefPtr<PermissionManager> mPermissionManager;
+ nsCOMPtr<nsIPrincipal> mPrincipal;
+};
+
+MOZ_GTEST_BENCH_F(PermissionManagerTester,
+ TestNonExistentPermissionFromPrincipal, [this] {
+ for (unsigned i = 0; i < kNumIterations; ++i) {
+ uint32_t result = 0;
+ Unused << mPermissionManager->TestPermissionFromPrincipal(
+ mPrincipal, mNonExistentType, &result);
+ }
+ });
diff --git a/extensions/permissions/test/gtest/moz.build b/extensions/permissions/test/gtest/moz.build
new file mode 100644
index 0000000000..132c384597
--- /dev/null
+++ b/extensions/permissions/test/gtest/moz.build
@@ -0,0 +1,11 @@
+# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
+# vim: set filetype=python:
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+UNIFIED_SOURCES += [
+ "PermissionManagerTest.cpp",
+]
+
+FINAL_LIBRARY = "xul-gtest"
diff --git a/extensions/permissions/test/moz.build b/extensions/permissions/test/moz.build
new file mode 100644
index 0000000000..5c68459575
--- /dev/null
+++ b/extensions/permissions/test/moz.build
@@ -0,0 +1,15 @@
+# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
+# vim: set filetype=python:
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+TEST_DIRS += [
+ "gtest",
+]
+
+XPCSHELL_TESTS_MANIFESTS += [
+ "unit/xpcshell.ini",
+]
+
+BROWSER_CHROME_MANIFESTS += ["browser.ini"]
diff --git a/extensions/permissions/test/unit/head.js b/extensions/permissions/test/unit/head.js
new file mode 100644
index 0000000000..b5b2518e22
--- /dev/null
+++ b/extensions/permissions/test/unit/head.js
@@ -0,0 +1,26 @@
+/* Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/publicdomain/zero/1.0/
+ */
+
+var { NetUtil } = ChromeUtils.import("resource://gre/modules/NetUtil.jsm");
+
+// Helper to step a generator function and catch a StopIteration exception.
+function do_run_generator(generator) {
+ try {
+ generator.next();
+ } catch (e) {
+ do_throw("caught exception " + e, Components.stack.caller);
+ }
+}
+
+// Helper to finish a generator function test.
+function do_finish_generator_test(generator) {
+ executeSoon(function () {
+ generator.return();
+ do_test_finished();
+ });
+}
+
+function do_count_array(all) {
+ return all.length;
+}
diff --git a/extensions/permissions/test/unit/test_permmanager_cleardata.js b/extensions/permissions/test/unit/test_permmanager_cleardata.js
new file mode 100644
index 0000000000..2bd4d11319
--- /dev/null
+++ b/extensions/permissions/test/unit/test_permmanager_cleardata.js
@@ -0,0 +1,93 @@
+/* Any copyright is dedicated to the Public Domain.
+ http://creativecommons.org/publicdomain/zero/1.0/ */
+
+var pm;
+
+// Create a principal based on the { origin, originAttributes }.
+function createPrincipal(aOrigin, aOriginAttributes) {
+ return Services.scriptSecurityManager.createContentPrincipal(
+ NetUtil.newURI(aOrigin),
+ aOriginAttributes
+ );
+}
+
+function getData(aPattern) {
+ return JSON.stringify(aPattern);
+}
+
+// Use aEntries to create principals, add permissions to them and check that they have them.
+// Then, it is removing origin attributes with the given aData and check if the permissions
+// of principals[i] matches the permission in aResults[i].
+function test(aEntries, aData, aResults) {
+ let principals = [];
+
+ for (const entry of aEntries) {
+ principals.push(createPrincipal(entry.origin, entry.originAttributes));
+ }
+
+ for (const principal of principals) {
+ Assert.equal(
+ pm.testPermissionFromPrincipal(principal, "test/clear-origin"),
+ pm.UNKNOWN_ACTION
+ );
+ pm.addFromPrincipal(
+ principal,
+ "test/clear-origin",
+ pm.ALLOW_ACTION,
+ pm.EXPIRE_NEVER,
+ 0
+ );
+ Assert.equal(
+ pm.testPermissionFromPrincipal(principal, "test/clear-origin"),
+ pm.ALLOW_ACTION
+ );
+ }
+
+ // `clear-origin-attributes-data` notification is removed from permission
+ // manager
+ pm.removePermissionsWithAttributes(aData);
+
+ var length = aEntries.length;
+ for (let i = 0; i < length; ++i) {
+ Assert.equal(
+ pm.testPermissionFromPrincipal(principals[i], "test/clear-origin"),
+ aResults[i]
+ );
+
+ // Remove allowed actions.
+ if (aResults[i] == pm.ALLOW_ACTION) {
+ pm.removeFromPrincipal(principals[i], "test/clear-origin");
+ }
+ }
+}
+
+function run_test() {
+ do_get_profile();
+
+ pm = Services.perms;
+
+ let entries = [
+ { origin: "http://example.com", originAttributes: {} },
+ {
+ origin: "http://example.com",
+ originAttributes: { inIsolatedMozBrowser: true },
+ },
+ ];
+
+ // In that case, all permissions should be removed.
+ test(entries, getData({}), [
+ pm.UNKNOWN_ACTION,
+ pm.UNKNOWN_ACTION,
+ pm.ALLOW_ACTION,
+ pm.ALLOW_ACTION,
+ ]);
+
+ // In that case, only the permissions related to a browserElement should be removed.
+ // All the other permissions should stay.
+ test(entries, getData({ inIsolatedMozBrowser: true }), [
+ pm.ALLOW_ACTION,
+ pm.UNKNOWN_ACTION,
+ pm.ALLOW_ACTION,
+ pm.ALLOW_ACTION,
+ ]);
+}
diff --git a/extensions/permissions/test/unit/test_permmanager_default_pref.js b/extensions/permissions/test/unit/test_permmanager_default_pref.js
new file mode 100644
index 0000000000..3759594bf5
--- /dev/null
+++ b/extensions/permissions/test/unit/test_permmanager_default_pref.js
@@ -0,0 +1,76 @@
+/* Any copyright is dedicated to the Public Domain.
+ http://creativecommons.org/publicdomain/zero/1.0/ */
+
+function run_test() {
+ let principal =
+ Services.scriptSecurityManager.createContentPrincipalFromOrigin(
+ "https://example.org"
+ );
+
+ // Check that without a pref the default return value is UNKNOWN.
+ Assert.equal(
+ Services.perms.testPermissionFromPrincipal(principal, "camera"),
+ Services.perms.UNKNOWN_ACTION
+ );
+
+ // Check that the default return value changed after setting the pref.
+ Services.prefs.setIntPref(
+ "permissions.default.camera",
+ Services.perms.DENY_ACTION
+ );
+ Assert.equal(
+ Services.perms.testPermissionFromPrincipal(principal, "camera"),
+ Services.perms.DENY_ACTION
+ );
+
+ // Check that functions that do not directly return a permission value still
+ // consider the permission as being set to its default.
+ Assert.equal(
+ null,
+ Services.perms.getPermissionObject(principal, "camera", false)
+ );
+
+ // Check that other permissions still return UNKNOWN.
+ Assert.equal(
+ Services.perms.testPermissionFromPrincipal(principal, "geo"),
+ Services.perms.UNKNOWN_ACTION
+ );
+
+ // Check that the default return value changed after changing the pref.
+ Services.prefs.setIntPref(
+ "permissions.default.camera",
+ Services.perms.ALLOW_ACTION
+ );
+ Assert.equal(
+ Services.perms.testPermissionFromPrincipal(principal, "camera"),
+ Services.perms.ALLOW_ACTION
+ );
+
+ // Check that the preference is ignored if there is a value.
+ Services.perms.addFromPrincipal(
+ principal,
+ "camera",
+ Services.perms.DENY_ACTION
+ );
+ Assert.equal(
+ Services.perms.testPermissionFromPrincipal(principal, "camera"),
+ Services.perms.DENY_ACTION
+ );
+ Assert.ok(
+ Services.perms.getPermissionObject(principal, "camera", false) != null
+ );
+
+ // The preference should be honored again, after resetting the permissions.
+ Services.perms.removeAll();
+ Assert.equal(
+ Services.perms.testPermissionFromPrincipal(principal, "camera"),
+ Services.perms.ALLOW_ACTION
+ );
+
+ // Should be UNKNOWN after clearing the pref.
+ Services.prefs.clearUserPref("permissions.default.camera");
+ Assert.equal(
+ Services.perms.testPermissionFromPrincipal(principal, "camera"),
+ Services.perms.UNKNOWN_ACTION
+ );
+}
diff --git a/extensions/permissions/test/unit/test_permmanager_defaults.js b/extensions/permissions/test/unit/test_permmanager_defaults.js
new file mode 100644
index 0000000000..0f608e2151
--- /dev/null
+++ b/extensions/permissions/test/unit/test_permmanager_defaults.js
@@ -0,0 +1,485 @@
+/* Any copyright is dedicated to the Public Domain.
+ http://creativecommons.org/publicdomain/zero/1.0/ */
+
+// The origin we use in most of the tests.
+const TEST_ORIGIN = NetUtil.newURI("http://example.org");
+const TEST_ORIGIN_HTTPS = NetUtil.newURI("https://example.org");
+const TEST_ORIGIN_2 = NetUtil.newURI("http://example.com");
+const TEST_ORIGIN_3 = NetUtil.newURI("https://example2.com:8080");
+const TEST_PERMISSION = "test-permission";
+
+function promiseTimeout(delay) {
+ return new Promise(resolve => {
+ do_timeout(delay, resolve);
+ });
+}
+
+add_task(async function do_test() {
+ // setup a profile.
+ do_get_profile();
+
+ // create a file in the temp directory with the defaults.
+ let file = do_get_tempdir();
+ file.append("test_default_permissions");
+
+ // write our test data to it.
+ let ostream = Cc["@mozilla.org/network/file-output-stream;1"].createInstance(
+ Ci.nsIFileOutputStream
+ );
+ ostream.init(file, -1, 0o666, 0);
+ let conv = Cc["@mozilla.org/intl/converter-output-stream;1"].createInstance(
+ Ci.nsIConverterOutputStream
+ );
+ conv.init(ostream, "UTF-8");
+
+ conv.writeString("# this is a comment\n");
+ conv.writeString("\n"); // a blank line!
+ conv.writeString(
+ "host\t" + TEST_PERMISSION + "\t1\t" + TEST_ORIGIN.host + "\n"
+ );
+ conv.writeString(
+ "host\t" + TEST_PERMISSION + "\t1\t" + TEST_ORIGIN_2.host + "\n"
+ );
+ conv.writeString(
+ "origin\t" + TEST_PERMISSION + "\t1\t" + TEST_ORIGIN_3.spec + "\n"
+ );
+ conv.writeString(
+ "origin\t" + TEST_PERMISSION + "\t1\t" + TEST_ORIGIN.spec + "^inBrowser=1\n"
+ );
+ ostream.close();
+
+ // Set the preference used by the permission manager so the file is read.
+ Services.prefs.setCharPref(
+ "permissions.manager.defaultsUrl",
+ "file://" + file.path
+ );
+
+ // This will force the permission-manager to reload the data.
+ Services.obs.notifyObservers(null, "testonly-reload-permissions-from-disk");
+
+ let permIsolateUserContext = Services.prefs.getBoolPref(
+ "permissions.isolateBy.userContext"
+ );
+ let permIsolatePrivateBrowsing = Services.prefs.getBoolPref(
+ "permissions.isolateBy.privateBrowsing"
+ );
+
+ let pm = Services.perms;
+
+ // test the default permission was applied.
+ let principal = Services.scriptSecurityManager.createContentPrincipal(
+ TEST_ORIGIN,
+ {}
+ );
+ let principalHttps = Services.scriptSecurityManager.createContentPrincipal(
+ TEST_ORIGIN_HTTPS,
+ {}
+ );
+ let principal2 = Services.scriptSecurityManager.createContentPrincipal(
+ TEST_ORIGIN_2,
+ {}
+ );
+ let principal3 = Services.scriptSecurityManager.createContentPrincipal(
+ TEST_ORIGIN_3,
+ {}
+ );
+
+ let attrs = { inIsolatedMozBrowser: true };
+ let principal4 = Services.scriptSecurityManager.createContentPrincipal(
+ TEST_ORIGIN,
+ attrs
+ );
+ let principal5 = Services.scriptSecurityManager.createContentPrincipal(
+ TEST_ORIGIN_3,
+ attrs
+ );
+
+ attrs = { userContextId: 1 };
+ let principal1UserContext =
+ Services.scriptSecurityManager.createContentPrincipal(TEST_ORIGIN, attrs);
+ attrs = { privateBrowsingId: 1 };
+ let principal1PrivateBrowsing =
+ Services.scriptSecurityManager.createContentPrincipal(TEST_ORIGIN, attrs);
+ attrs = { firstPartyDomain: "cnn.com" };
+ let principal7 = Services.scriptSecurityManager.createContentPrincipal(
+ TEST_ORIGIN,
+ attrs
+ );
+ attrs = { userContextId: 1, firstPartyDomain: "cnn.com" };
+ let principal8 = Services.scriptSecurityManager.createContentPrincipal(
+ TEST_ORIGIN,
+ attrs
+ );
+
+ Assert.equal(
+ Ci.nsIPermissionManager.ALLOW_ACTION,
+ pm.testPermissionFromPrincipal(principal, TEST_PERMISSION)
+ );
+ Assert.equal(
+ Ci.nsIPermissionManager.ALLOW_ACTION,
+ pm.testPermissionFromPrincipal(principalHttps, TEST_PERMISSION)
+ );
+ Assert.equal(
+ Ci.nsIPermissionManager.ALLOW_ACTION,
+ pm.testPermissionFromPrincipal(principal3, TEST_PERMISSION)
+ );
+ Assert.equal(
+ Ci.nsIPermissionManager.ALLOW_ACTION,
+ pm.testPermissionFromPrincipal(principal4, TEST_PERMISSION)
+ );
+ // Depending on the prefs there are two scenarios here:
+ // 1. We isolate by private browsing: The permission mgr should
+ // add default permissions for these principals too.
+ // 2. We don't isolate by private browsing: The permission
+ // check will strip the private browsing origin attribute.
+ // In this case the used internally for the lookup is always principal1.
+ Assert.equal(
+ Ci.nsIPermissionManager.ALLOW_ACTION,
+ pm.testPermissionFromPrincipal(principal1PrivateBrowsing, TEST_PERMISSION)
+ );
+
+ // Didn't add
+ Assert.equal(
+ Ci.nsIPermissionManager.UNKNOWN_ACTION,
+ pm.testPermissionFromPrincipal(principal5, TEST_PERMISSION)
+ );
+
+ // the permission should exist in the enumerator.
+ Assert.equal(
+ Ci.nsIPermissionManager.ALLOW_ACTION,
+ findCapabilityViaEnum(TEST_ORIGIN)
+ );
+ Assert.equal(
+ Ci.nsIPermissionManager.ALLOW_ACTION,
+ findCapabilityViaEnum(TEST_ORIGIN_3)
+ );
+
+ // but should not have been written to the DB
+ await checkCapabilityViaDB(null);
+
+ // remove all should not throw and the default should remain
+ pm.removeAll();
+
+ Assert.equal(
+ Ci.nsIPermissionManager.ALLOW_ACTION,
+ pm.testPermissionFromPrincipal(principal, TEST_PERMISSION)
+ );
+ Assert.equal(
+ Ci.nsIPermissionManager.ALLOW_ACTION,
+ pm.testPermissionFromPrincipal(principal3, TEST_PERMISSION)
+ );
+ Assert.equal(
+ Ci.nsIPermissionManager.ALLOW_ACTION,
+ pm.testPermissionFromPrincipal(principal4, TEST_PERMISSION)
+ );
+ // Default permission should have also been added for private browsing.
+ Assert.equal(
+ Ci.nsIPermissionManager.ALLOW_ACTION,
+ pm.testPermissionFromPrincipal(principal1PrivateBrowsing, TEST_PERMISSION)
+ );
+ // make sure principals with userContextId use the same / different permissions
+ // depending on pref state
+ Assert.equal(
+ permIsolateUserContext
+ ? Ci.nsIPermissionManager.UNKNOWN_ACTION
+ : Ci.nsIPermissionManager.ALLOW_ACTION,
+ pm.testPermissionFromPrincipal(principal1UserContext, TEST_PERMISSION)
+ );
+ // make sure principals with a firstPartyDomain use different permissions
+ Assert.equal(
+ Ci.nsIPermissionManager.UNKNOWN_ACTION,
+ pm.testPermissionFromPrincipal(principal7, TEST_PERMISSION)
+ );
+ Assert.equal(
+ Ci.nsIPermissionManager.UNKNOWN_ACTION,
+ pm.testPermissionFromPrincipal(principal8, TEST_PERMISSION)
+ );
+
+ // Asking for this permission to be removed should result in that permission
+ // having UNKNOWN_ACTION
+ pm.removeFromPrincipal(principal, TEST_PERMISSION);
+ Assert.equal(
+ Ci.nsIPermissionManager.UNKNOWN_ACTION,
+ pm.testPermissionFromPrincipal(principal, TEST_PERMISSION)
+ );
+ // make sure principals with userContextId use the correct permissions
+ // (Should be unknown with and without OA stripping )
+ Assert.equal(
+ Ci.nsIPermissionManager.UNKNOWN_ACTION,
+ pm.testPermissionFromPrincipal(principal1UserContext, TEST_PERMISSION)
+ );
+ // If we isolate by private browsing, the permission should still be present
+ // for the private browsing principal.
+ Assert.equal(
+ permIsolatePrivateBrowsing
+ ? Ci.nsIPermissionManager.ALLOW_ACTION
+ : Ci.nsIPermissionManager.UNKNOWN_ACTION,
+ pm.testPermissionFromPrincipal(principal1PrivateBrowsing, TEST_PERMISSION)
+ );
+ // and we should have this UNKNOWN_ACTION reflected in the DB
+ await checkCapabilityViaDB(Ci.nsIPermissionManager.UNKNOWN_ACTION);
+ // but the permission should *not* appear in the enumerator.
+ Assert.equal(null, findCapabilityViaEnum());
+
+ // and a subsequent RemoveAll should restore the default
+ pm.removeAll();
+
+ Assert.equal(
+ Ci.nsIPermissionManager.ALLOW_ACTION,
+ pm.testPermissionFromPrincipal(principal, TEST_PERMISSION)
+ );
+ // Make sure default imports work for private browsing after removeAll.
+ Assert.equal(
+ Ci.nsIPermissionManager.ALLOW_ACTION,
+ pm.testPermissionFromPrincipal(principal1PrivateBrowsing, TEST_PERMISSION)
+ );
+ // make sure principals with userContextId share permissions depending on pref state
+ Assert.equal(
+ permIsolateUserContext
+ ? Ci.nsIPermissionManager.UNKNOWN_ACTION
+ : Ci.nsIPermissionManager.ALLOW_ACTION,
+ pm.testPermissionFromPrincipal(principal1UserContext, TEST_PERMISSION)
+ );
+ // make sure principals with firstPartyDomain use different permissions
+ Assert.equal(
+ Ci.nsIPermissionManager.UNKNOWN_ACTION,
+ pm.testPermissionFromPrincipal(principal7, TEST_PERMISSION)
+ );
+ Assert.equal(
+ Ci.nsIPermissionManager.UNKNOWN_ACTION,
+ pm.testPermissionFromPrincipal(principal8, TEST_PERMISSION)
+ );
+ // and allow it to again be seen in the enumerator.
+ Assert.equal(Ci.nsIPermissionManager.ALLOW_ACTION, findCapabilityViaEnum());
+
+ // now explicitly add a permission - this too should override the default.
+ pm.addFromPrincipal(
+ principal,
+ TEST_PERMISSION,
+ Ci.nsIPermissionManager.DENY_ACTION
+ );
+
+ // it should be reflected in a permission check, in the enumerator and the DB
+ Assert.equal(
+ Ci.nsIPermissionManager.DENY_ACTION,
+ pm.testPermissionFromPrincipal(principal, TEST_PERMISSION)
+ );
+ // make sure principals with userContextId use the same / different permissions
+ // depending on pref state
+ Assert.equal(
+ permIsolateUserContext
+ ? Ci.nsIPermissionManager.UNKNOWN_ACTION
+ : Ci.nsIPermissionManager.DENY_ACTION,
+ pm.testPermissionFromPrincipal(principal1UserContext, TEST_PERMISSION)
+ );
+ // If we isolate by private browsing, we should still have the default perm
+ // for the private browsing principal.
+ Assert.equal(
+ permIsolatePrivateBrowsing
+ ? Ci.nsIPermissionManager.ALLOW_ACTION
+ : Ci.nsIPermissionManager.DENY_ACTION,
+ pm.testPermissionFromPrincipal(principal1PrivateBrowsing, TEST_PERMISSION)
+ );
+ // make sure principals with firstPartyDomain use different permissions
+ Assert.equal(
+ Ci.nsIPermissionManager.UNKNOWN_ACTION,
+ pm.testPermissionFromPrincipal(principal7, TEST_PERMISSION)
+ );
+ Assert.equal(
+ Ci.nsIPermissionManager.UNKNOWN_ACTION,
+ pm.testPermissionFromPrincipal(principal8, TEST_PERMISSION)
+ );
+ Assert.equal(Ci.nsIPermissionManager.DENY_ACTION, findCapabilityViaEnum());
+ await checkCapabilityViaDB(Ci.nsIPermissionManager.DENY_ACTION);
+
+ // explicitly add a different permission - in this case we are no longer
+ // replacing the default, but instead replacing the replacement!
+ pm.addFromPrincipal(
+ principal,
+ TEST_PERMISSION,
+ Ci.nsIPermissionManager.PROMPT_ACTION
+ );
+
+ // it should be reflected in a permission check, in the enumerator and the DB
+ Assert.equal(
+ Ci.nsIPermissionManager.PROMPT_ACTION,
+ pm.testPermissionFromPrincipal(principal, TEST_PERMISSION)
+ );
+ // make sure principals with userContextId use the same / different permissions
+ // depending on pref state
+ Assert.equal(
+ permIsolateUserContext
+ ? Ci.nsIPermissionManager.UNKNOWN_ACTION
+ : Ci.nsIPermissionManager.PROMPT_ACTION,
+ pm.testPermissionFromPrincipal(principal1UserContext, TEST_PERMISSION)
+ );
+ // If we isolate by private browsing, we should still have the default perm
+ // for the private browsing principal.
+ Assert.equal(
+ permIsolatePrivateBrowsing
+ ? Ci.nsIPermissionManager.ALLOW_ACTION
+ : Ci.nsIPermissionManager.PROMPT_ACTION,
+ pm.testPermissionFromPrincipal(principal1PrivateBrowsing, TEST_PERMISSION)
+ );
+ // make sure principals with firstPartyDomain use different permissions
+ Assert.equal(
+ Ci.nsIPermissionManager.UNKNOWN_ACTION,
+ pm.testPermissionFromPrincipal(principal7, TEST_PERMISSION)
+ );
+ Assert.equal(
+ Ci.nsIPermissionManager.UNKNOWN_ACTION,
+ pm.testPermissionFromPrincipal(principal8, TEST_PERMISSION)
+ );
+ Assert.equal(Ci.nsIPermissionManager.PROMPT_ACTION, findCapabilityViaEnum());
+ await checkCapabilityViaDB(Ci.nsIPermissionManager.PROMPT_ACTION);
+
+ // --------------------------------------------------------------
+ // check default permissions and removeAllSince work as expected.
+ pm.removeAll(); // ensure only defaults are there.
+
+ // default for both principals is allow.
+ Assert.equal(
+ Ci.nsIPermissionManager.ALLOW_ACTION,
+ pm.testPermissionFromPrincipal(principal, TEST_PERMISSION)
+ );
+ Assert.equal(
+ Ci.nsIPermissionManager.ALLOW_ACTION,
+ pm.testPermissionFromPrincipal(principal2, TEST_PERMISSION)
+ );
+
+ // Add a default override for TEST_ORIGIN_2 - this one should *not* be
+ // restored in removeAllSince()
+ pm.addFromPrincipal(
+ principal2,
+ TEST_PERMISSION,
+ Ci.nsIPermissionManager.DENY_ACTION
+ );
+ Assert.equal(
+ Ci.nsIPermissionManager.DENY_ACTION,
+ pm.testPermissionFromPrincipal(principal2, TEST_PERMISSION)
+ );
+ await promiseTimeout(20);
+
+ let since = Number(Date.now());
+ await promiseTimeout(20);
+
+ // explicitly add a permission which overrides the default for the first
+ // principal - this one *should* be removed by removeAllSince.
+ pm.addFromPrincipal(
+ principal,
+ TEST_PERMISSION,
+ Ci.nsIPermissionManager.DENY_ACTION
+ );
+ Assert.equal(
+ Ci.nsIPermissionManager.DENY_ACTION,
+ pm.testPermissionFromPrincipal(principal, TEST_PERMISSION)
+ );
+
+ // do a removeAllSince.
+ pm.removeAllSince(since);
+
+ // the default for the first principal should re-appear as we modified it
+ // later then |since|
+ Assert.equal(
+ Ci.nsIPermissionManager.ALLOW_ACTION,
+ pm.testPermissionFromPrincipal(principal, TEST_PERMISSION)
+ );
+
+ // but the permission for principal2 should remain as we added that before |since|.
+ Assert.equal(
+ Ci.nsIPermissionManager.DENY_ACTION,
+ pm.testPermissionFromPrincipal(principal2, TEST_PERMISSION)
+ );
+
+ // remove the temp file we created.
+ file.remove(false);
+});
+
+// use an enumerator to find the requested permission. Returns the permission
+// value (ie, the "capability" in nsIPermission parlance) or null if it can't
+// be found.
+function findCapabilityViaEnum(origin = TEST_ORIGIN, type = TEST_PERMISSION) {
+ let result = undefined;
+ for (let perm of Services.perms.all) {
+ if (perm.matchesURI(origin, true) && perm.type == type) {
+ if (result !== undefined) {
+ // we've already found one previously - that's bad!
+ do_throw("enumerator found multiple entries");
+ }
+ result = perm.capability;
+ }
+ }
+ return result || null;
+}
+
+// A function to check the DB has the specified capability. As the permission
+// manager uses async DB operations without a completion callback, the
+// distinct possibility exists that our checking of the DB will happen before
+// the permission manager update has completed - so we just retry a few times.
+// Returns a promise.
+function checkCapabilityViaDB(
+ expected,
+ origin = TEST_ORIGIN,
+ type = TEST_PERMISSION
+) {
+ return new Promise(resolve => {
+ let count = 0;
+ let max = 20;
+ let do_check = () => {
+ let got = findCapabilityViaDB(origin, type);
+ if (got == expected) {
+ // the do_check_eq() below will succeed - which is what we want.
+ Assert.equal(got, expected, "The database has the expected value");
+ resolve();
+ return;
+ }
+ // value isn't correct - see if we've retried enough
+ if (count++ == max) {
+ // the do_check_eq() below will fail - which is what we want.
+ Assert.equal(
+ got,
+ expected,
+ "The database wasn't updated with the expected value"
+ );
+ resolve();
+ return;
+ }
+ // we can retry...
+ do_timeout(100, do_check);
+ };
+ do_check();
+ });
+}
+
+// use the DB to find the requested permission. Returns the permission
+// value (ie, the "capability" in nsIPermission parlance) or null if it can't
+// be found.
+function findCapabilityViaDB(origin = TEST_ORIGIN, type = TEST_PERMISSION) {
+ let principal = Services.scriptSecurityManager.createContentPrincipal(
+ origin,
+ {}
+ );
+ let originStr = principal.origin;
+
+ let file = Services.dirsvc.get("ProfD", Ci.nsIFile);
+ file.append("permissions.sqlite");
+
+ let connection = Services.storage.openDatabase(file);
+
+ let query = connection.createStatement(
+ "SELECT permission FROM moz_perms WHERE origin = :origin AND type = :type"
+ );
+ query.bindByName("origin", originStr);
+ query.bindByName("type", type);
+
+ if (!query.executeStep()) {
+ // no row
+ return null;
+ }
+ let result = query.getInt32(0);
+ if (query.executeStep()) {
+ // this is bad - we never expect more than 1 row here.
+ do_throw("More than 1 row found!");
+ }
+ return result;
+}
diff --git a/extensions/permissions/test/unit/test_permmanager_expiration.js b/extensions/permissions/test/unit/test_permmanager_expiration.js
new file mode 100644
index 0000000000..24ff366730
--- /dev/null
+++ b/extensions/permissions/test/unit/test_permmanager_expiration.js
@@ -0,0 +1,189 @@
+/* Any copyright is dedicated to the Public Domain.
+ http://creativecommons.org/publicdomain/zero/1.0/ */
+
+// Test that permissions with specific expiry times behave as expected.
+var test_generator = do_run_test();
+
+function run_test() {
+ do_test_pending();
+ test_generator.next();
+}
+
+function continue_test() {
+ do_run_generator(test_generator);
+}
+
+function* do_run_test() {
+ let pm = Services.perms;
+ let permURI = NetUtil.newURI("http://example.com");
+ let principal = Services.scriptSecurityManager.createContentPrincipal(
+ permURI,
+ {}
+ );
+
+ let now = Number(Date.now());
+
+ // add a permission with *now* expiration
+ pm.addFromPrincipal(
+ principal,
+ "test/expiration-perm-exp",
+ 1,
+ pm.EXPIRE_TIME,
+ now
+ );
+ pm.addFromPrincipal(
+ principal,
+ "test/expiration-session-exp",
+ 1,
+ pm.EXPIRE_SESSION,
+ now
+ );
+
+ // add a permission with future expiration (100 milliseconds)
+ pm.addFromPrincipal(
+ principal,
+ "test/expiration-perm-exp2",
+ 1,
+ pm.EXPIRE_TIME,
+ now + 100
+ );
+ pm.addFromPrincipal(
+ principal,
+ "test/expiration-session-exp2",
+ 1,
+ pm.EXPIRE_SESSION,
+ now + 100
+ );
+
+ // add a permission with future expiration (1000 seconds)
+ pm.addFromPrincipal(
+ principal,
+ "test/expiration-perm-exp3",
+ 1,
+ pm.EXPIRE_TIME,
+ now + 1e6
+ );
+ pm.addFromPrincipal(
+ principal,
+ "test/expiration-session-exp3",
+ 1,
+ pm.EXPIRE_SESSION,
+ now + 1e6
+ );
+
+ // add a permission without expiration
+ pm.addFromPrincipal(
+ principal,
+ "test/expiration-perm-nexp",
+ 1,
+ pm.EXPIRE_NEVER,
+ 0
+ );
+
+ // check that the second two haven't expired yet
+ Assert.equal(
+ 1,
+ pm.testPermissionFromPrincipal(principal, "test/expiration-perm-exp3")
+ );
+ Assert.equal(
+ 1,
+ pm.testPermissionFromPrincipal(principal, "test/expiration-session-exp3")
+ );
+ Assert.equal(
+ 1,
+ pm.testPermissionFromPrincipal(principal, "test/expiration-perm-nexp")
+ );
+ Assert.equal(1, pm.getAllWithTypePrefix("test/expiration-perm-exp3").length);
+ Assert.equal(
+ 1,
+ pm.getAllWithTypePrefix("test/expiration-session-exp3").length
+ );
+ Assert.equal(1, pm.getAllWithTypePrefix("test/expiration-perm-nexp").length);
+ Assert.equal(5, pm.getAllForPrincipal(principal).length);
+
+ // ... and the first one has
+ do_timeout(10, continue_test);
+ yield;
+ Assert.equal(
+ 0,
+ pm.testPermissionFromPrincipal(principal, "test/expiration-perm-exp")
+ );
+ Assert.equal(
+ 0,
+ pm.testPermissionFromPrincipal(principal, "test/expiration-session-exp")
+ );
+
+ // ... and that the short-term one will
+ do_timeout(200, continue_test);
+ yield;
+ Assert.equal(
+ 0,
+ pm.testPermissionFromPrincipal(principal, "test/expiration-perm-exp2")
+ );
+ Assert.equal(
+ 0,
+ pm.testPermissionFromPrincipal(principal, "test/expiration-session-exp2")
+ );
+ Assert.equal(0, pm.getAllWithTypePrefix("test/expiration-perm-exp2").length);
+ Assert.equal(
+ 0,
+ pm.getAllWithTypePrefix("test/expiration-session-exp2").length
+ );
+
+ Assert.equal(3, pm.getAllForPrincipal(principal).length);
+
+ // Check that .getPermission returns a matching result
+ Assert.equal(
+ null,
+ pm.getPermissionObject(principal, "test/expiration-perm-exp", false)
+ );
+ Assert.equal(
+ null,
+ pm.getPermissionObject(principal, "test/expiration-session-exp", false)
+ );
+ Assert.equal(
+ null,
+ pm.getPermissionObject(principal, "test/expiration-perm-exp2", false)
+ );
+ Assert.equal(
+ null,
+ pm.getPermissionObject(principal, "test/expiration-session-exp2", false)
+ );
+
+ // Add a persistent permission for private browsing
+ let principalPB = Services.scriptSecurityManager.createContentPrincipal(
+ permURI,
+ { privateBrowsingId: 1 }
+ );
+ pm.addFromPrincipal(
+ principalPB,
+ "test/expiration-session-pb",
+ pm.ALLOW_ACTION
+ );
+
+ // The permission should be set to session expiry
+ let perm = pm.getPermissionObject(
+ principalPB,
+ "test/expiration-session-pb",
+ true
+ );
+ Assert.equal(perm.expireType, pm.EXPIRE_SESSION);
+
+ // Add a persistent permission for private browsing using
+ // addFromPrincipalAndPersistInPrivateBrowsing
+ pm.addFromPrincipalAndPersistInPrivateBrowsing(
+ principalPB,
+ "test/expiration-session-pb",
+ pm.ALLOW_ACTION
+ );
+
+ // The permission should be set to never expire
+ perm = pm.getPermissionObject(
+ principalPB,
+ "test/expiration-session-pb",
+ true
+ );
+ Assert.equal(perm.expireType, pm.EXPIRE_NEVER);
+
+ do_finish_generator_test(test_generator);
+}
diff --git a/extensions/permissions/test/unit/test_permmanager_getAllByTypeSince.js b/extensions/permissions/test/unit/test_permmanager_getAllByTypeSince.js
new file mode 100644
index 0000000000..918f184673
--- /dev/null
+++ b/extensions/permissions/test/unit/test_permmanager_getAllByTypeSince.js
@@ -0,0 +1,79 @@
+/* Any copyright is dedicated to the Public Domain.
+ http://creativecommons.org/publicdomain/zero/1.0/ */
+
+function check_enumerator(prefix, from, permissions) {
+ let pm = Services.perms;
+
+ let array = pm.getAllByTypeSince(prefix, from);
+ Assert.equal(array.length, permissions.length);
+ for (let [principal, type, capability] of permissions) {
+ let perm = array.find(p => p.principal.equals(principal));
+ Assert.ok(perm != null);
+ Assert.equal(perm.type, type);
+ Assert.equal(perm.capability, capability);
+ Assert.equal(perm.expireType, pm.EXPIRE_NEVER);
+ }
+}
+
+add_task(async function test() {
+ let pm = Services.perms;
+
+ let principal =
+ Services.scriptSecurityManager.createContentPrincipalFromOrigin(
+ "http://example.com"
+ );
+ let subPrincipal =
+ Services.scriptSecurityManager.createContentPrincipalFromOrigin(
+ "http://sub.example.com"
+ );
+
+ check_enumerator("test/", 0, []);
+
+ pm.addFromPrincipal(principal, "test/getAllByTypeSince", pm.ALLOW_ACTION);
+
+ // These shouldn't show up anywhere, the name doesn't match.
+ pm.addFromPrincipal(
+ subPrincipal,
+ "other-test/getAllByTypeSince",
+ pm.PROMPT_ACTION
+ );
+ pm.addFromPrincipal(principal, "test/getAllByTypeSince1", pm.PROMPT_ACTION);
+
+ check_enumerator("test/getAllByTypeSince", 0, [
+ [principal, "test/getAllByTypeSince", pm.ALLOW_ACTION],
+ ]);
+
+ // Add some time in between taking the snapshot of the timestamp
+ // to avoid flakyness.
+ await new Promise(c => do_timeout(100, c));
+ let timestamp = Date.now();
+ await new Promise(c => do_timeout(100, c));
+
+ pm.addFromPrincipal(subPrincipal, "test/getAllByTypeSince", pm.DENY_ACTION);
+
+ check_enumerator("test/getAllByTypeSince", 0, [
+ [subPrincipal, "test/getAllByTypeSince", pm.DENY_ACTION],
+ [principal, "test/getAllByTypeSince", pm.ALLOW_ACTION],
+ ]);
+
+ check_enumerator("test/getAllByTypeSince", timestamp, [
+ [subPrincipal, "test/getAllByTypeSince", pm.DENY_ACTION],
+ ]);
+
+ // check that UNKNOWN_ACTION permissions are ignored
+ pm.addFromPrincipal(
+ subPrincipal,
+ "test/getAllByTypeSince",
+ pm.UNKNOWN_ACTION
+ );
+
+ check_enumerator("test/getAllByTypeSince", 0, [
+ [principal, "test/getAllByTypeSince", pm.ALLOW_ACTION],
+ ]);
+
+ // check that permission removals are reflected
+ pm.removeFromPrincipal(principal, "test/getAllByTypeSince");
+ check_enumerator("test/", 0, []);
+
+ pm.removeAll();
+});
diff --git a/extensions/permissions/test/unit/test_permmanager_getAllByTypes.js b/extensions/permissions/test/unit/test_permmanager_getAllByTypes.js
new file mode 100644
index 0000000000..ab40c4b12a
--- /dev/null
+++ b/extensions/permissions/test/unit/test_permmanager_getAllByTypes.js
@@ -0,0 +1,124 @@
+/* Any copyright is dedicated to the Public Domain.
+ http://creativecommons.org/publicdomain/zero/1.0/ */
+
+function check_enumerator(permissionTypes, expectedPermissions) {
+ const permissions = Services.perms.getAllByTypes(permissionTypes);
+
+ Assert.equal(
+ permissions.length,
+ expectedPermissions.length,
+ `getAllByTypes returned the expected number of permissions for ${JSON.stringify(
+ permissionTypes
+ )}`
+ );
+
+ for (const perm of permissions) {
+ Assert.ok(perm != null);
+
+ // For some reason, the order in which we get the permissions doesn't seem to be
+ // stable when running the test with --verify. As a result, we need to retrieve the
+ // expected permission for the origin and type.
+ const expectedPermission = expectedPermissions.find(
+ ([expectedPrincipal, expectedType]) =>
+ perm.principal.equals(expectedPrincipal) && perm.type === expectedType
+ );
+
+ Assert.ok(expectedPermission !== null, "Found the expected permission");
+ Assert.equal(perm.capability, expectedPermission[2]);
+ Assert.equal(perm.expireType, Services.perms.EXPIRE_NEVER);
+ }
+}
+
+function run_test() {
+ let pm = Services.perms;
+
+ let principal =
+ Services.scriptSecurityManager.createContentPrincipalFromOrigin(
+ "http://example.com"
+ );
+ let subPrincipal =
+ Services.scriptSecurityManager.createContentPrincipalFromOrigin(
+ "http://sub.example.com"
+ );
+
+ const PERM_TYPE_1 = "test/getallbytypes_1";
+ const PERM_TYPE_2 = "test/getallbytypes_2";
+
+ info("check default state");
+ check_enumerator([], []);
+ check_enumerator([PERM_TYPE_1], []);
+ check_enumerator([PERM_TYPE_2], []);
+ check_enumerator([PERM_TYPE_1, PERM_TYPE_2], []);
+
+ info("check that expected permissions are retrieved");
+ pm.addFromPrincipal(principal, PERM_TYPE_1, pm.ALLOW_ACTION);
+ pm.addFromPrincipal(
+ subPrincipal,
+ "other-test/getallbytypes_1",
+ pm.PROMPT_ACTION
+ );
+ check_enumerator([PERM_TYPE_1], [[principal, PERM_TYPE_1, pm.ALLOW_ACTION]]);
+ check_enumerator(
+ [PERM_TYPE_1, PERM_TYPE_2],
+ [[principal, PERM_TYPE_1, pm.ALLOW_ACTION]]
+ );
+ check_enumerator([], []);
+ check_enumerator([PERM_TYPE_2], []);
+
+ pm.addFromPrincipal(subPrincipal, PERM_TYPE_1, pm.PROMPT_ACTION);
+ check_enumerator(
+ [PERM_TYPE_1],
+ [
+ [subPrincipal, PERM_TYPE_1, pm.PROMPT_ACTION],
+ [principal, PERM_TYPE_1, pm.ALLOW_ACTION],
+ ]
+ );
+ check_enumerator(
+ [PERM_TYPE_1, PERM_TYPE_2],
+ [
+ [subPrincipal, PERM_TYPE_1, pm.PROMPT_ACTION],
+ [principal, PERM_TYPE_1, pm.ALLOW_ACTION],
+ ]
+ );
+ check_enumerator([], []);
+ check_enumerator([PERM_TYPE_2], []);
+
+ pm.addFromPrincipal(principal, PERM_TYPE_2, pm.PROMPT_ACTION);
+ check_enumerator(
+ [PERM_TYPE_1, PERM_TYPE_2],
+ [
+ [subPrincipal, PERM_TYPE_1, pm.PROMPT_ACTION],
+ [principal, PERM_TYPE_1, pm.ALLOW_ACTION],
+ [principal, PERM_TYPE_2, pm.PROMPT_ACTION],
+ ]
+ );
+ check_enumerator([], []);
+ check_enumerator([PERM_TYPE_2], [[principal, PERM_TYPE_2, pm.PROMPT_ACTION]]);
+
+ info("check that UNKNOWN_ACTION permissions are ignored");
+ pm.addFromPrincipal(subPrincipal, PERM_TYPE_2, pm.UNKNOWN_ACTION);
+ check_enumerator([PERM_TYPE_2], [[principal, PERM_TYPE_2, pm.PROMPT_ACTION]]);
+
+ info("check that permission updates are reflected");
+ pm.addFromPrincipal(subPrincipal, PERM_TYPE_2, pm.PROMPT_ACTION);
+ check_enumerator(
+ [PERM_TYPE_2],
+ [
+ [subPrincipal, PERM_TYPE_2, pm.PROMPT_ACTION],
+ [principal, PERM_TYPE_2, pm.PROMPT_ACTION],
+ ]
+ );
+
+ info("check that permission removals are reflected");
+ pm.removeFromPrincipal(principal, PERM_TYPE_1);
+ check_enumerator(
+ [PERM_TYPE_1],
+ [[subPrincipal, PERM_TYPE_1, pm.PROMPT_ACTION]]
+ );
+
+ pm.removeAll();
+ check_enumerator([], []);
+ check_enumerator([PERM_TYPE_1], []);
+ check_enumerator([PERM_TYPE_2], []);
+ check_enumerator([PERM_TYPE_1, PERM_TYPE_2], []);
+}
diff --git a/extensions/permissions/test/unit/test_permmanager_getAllForPrincipal.js b/extensions/permissions/test/unit/test_permmanager_getAllForPrincipal.js
new file mode 100644
index 0000000000..ad9db37c91
--- /dev/null
+++ b/extensions/permissions/test/unit/test_permmanager_getAllForPrincipal.js
@@ -0,0 +1,72 @@
+/* Any copyright is dedicated to the Public Domain.
+ http://creativecommons.org/publicdomain/zero/1.0/ */
+
+function check_enumerator(principal, permissions) {
+ let perms = Services.perms.getAllForPrincipal(principal);
+ for (let [type, capability] of permissions) {
+ let perm = perms.shift();
+ Assert.ok(perm != null);
+ Assert.equal(perm.type, type);
+ Assert.equal(perm.capability, capability);
+ Assert.equal(perm.expireType, Services.perms.EXPIRE_NEVER);
+ }
+ Assert.ok(!perms.length);
+}
+
+function run_test() {
+ let pm = Services.perms;
+
+ let principal =
+ Services.scriptSecurityManager.createContentPrincipalFromOrigin(
+ "http://example.com"
+ );
+ let subPrincipal =
+ Services.scriptSecurityManager.createContentPrincipalFromOrigin(
+ "http://sub.example.com"
+ );
+
+ check_enumerator(principal, []);
+
+ pm.addFromPrincipal(principal, "test/getallforuri", pm.ALLOW_ACTION);
+ check_enumerator(principal, [["test/getallforuri", pm.ALLOW_ACTION]]);
+
+ // check that uris are matched exactly
+ check_enumerator(subPrincipal, []);
+
+ pm.addFromPrincipal(subPrincipal, "test/getallforuri", pm.PROMPT_ACTION);
+ pm.addFromPrincipal(subPrincipal, "test/getallforuri2", pm.DENY_ACTION);
+
+ check_enumerator(subPrincipal, [
+ ["test/getallforuri", pm.PROMPT_ACTION],
+ ["test/getallforuri2", pm.DENY_ACTION],
+ ]);
+
+ // check that the original uri list has not changed
+ check_enumerator(principal, [["test/getallforuri", pm.ALLOW_ACTION]]);
+
+ // check that UNKNOWN_ACTION permissions are ignored
+ pm.addFromPrincipal(principal, "test/getallforuri2", pm.UNKNOWN_ACTION);
+ pm.addFromPrincipal(principal, "test/getallforuri3", pm.DENY_ACTION);
+
+ check_enumerator(principal, [
+ ["test/getallforuri", pm.ALLOW_ACTION],
+ ["test/getallforuri3", pm.DENY_ACTION],
+ ]);
+
+ // check that permission updates are reflected
+ pm.addFromPrincipal(principal, "test/getallforuri", pm.PROMPT_ACTION);
+
+ check_enumerator(principal, [
+ ["test/getallforuri", pm.PROMPT_ACTION],
+ ["test/getallforuri3", pm.DENY_ACTION],
+ ]);
+
+ // check that permission removals are reflected
+ pm.removeFromPrincipal(principal, "test/getallforuri");
+
+ check_enumerator(principal, [["test/getallforuri3", pm.DENY_ACTION]]);
+
+ pm.removeAll();
+ check_enumerator(principal, []);
+ check_enumerator(subPrincipal, []);
+}
diff --git a/extensions/permissions/test/unit/test_permmanager_getAllWithTypePrefix.js b/extensions/permissions/test/unit/test_permmanager_getAllWithTypePrefix.js
new file mode 100644
index 0000000000..e3708cf445
--- /dev/null
+++ b/extensions/permissions/test/unit/test_permmanager_getAllWithTypePrefix.js
@@ -0,0 +1,84 @@
+/* Any copyright is dedicated to the Public Domain.
+ http://creativecommons.org/publicdomain/zero/1.0/ */
+
+function check_enumerator(prefix, permissions) {
+ let pm = Services.perms;
+
+ let array = pm.getAllWithTypePrefix(prefix);
+ for (let [principal, type, capability] of permissions) {
+ let perm = array.shift();
+ Assert.ok(perm != null);
+ Assert.ok(perm.principal.equals(principal));
+ Assert.equal(perm.type, type);
+ Assert.equal(perm.capability, capability);
+ Assert.equal(perm.expireType, pm.EXPIRE_NEVER);
+ }
+ Assert.equal(array.length, 0);
+}
+
+function run_test() {
+ let pm = Services.perms;
+
+ let principal =
+ Services.scriptSecurityManager.createContentPrincipalFromOrigin(
+ "http://example.com"
+ );
+ let subPrincipal =
+ Services.scriptSecurityManager.createContentPrincipalFromOrigin(
+ "http://sub.example.com"
+ );
+
+ check_enumerator("test/", []);
+
+ pm.addFromPrincipal(principal, "test/getallwithtypeprefix", pm.ALLOW_ACTION);
+ pm.addFromPrincipal(
+ subPrincipal,
+ "other-test/getallwithtypeprefix",
+ pm.PROMPT_ACTION
+ );
+ check_enumerator("test/", [
+ [principal, "test/getallwithtypeprefix", pm.ALLOW_ACTION],
+ ]);
+
+ pm.addFromPrincipal(
+ subPrincipal,
+ "test/getallwithtypeprefix",
+ pm.PROMPT_ACTION
+ );
+ check_enumerator("test/", [
+ [subPrincipal, "test/getallwithtypeprefix", pm.PROMPT_ACTION],
+ [principal, "test/getallwithtypeprefix", pm.ALLOW_ACTION],
+ ]);
+
+ check_enumerator("test/getallwithtypeprefix", [
+ [subPrincipal, "test/getallwithtypeprefix", pm.PROMPT_ACTION],
+ [principal, "test/getallwithtypeprefix", pm.ALLOW_ACTION],
+ ]);
+
+ // check that UNKNOWN_ACTION permissions are ignored
+ pm.addFromPrincipal(
+ principal,
+ "test/getallwithtypeprefix2",
+ pm.UNKNOWN_ACTION
+ );
+ check_enumerator("test/", [
+ [subPrincipal, "test/getallwithtypeprefix", pm.PROMPT_ACTION],
+ [principal, "test/getallwithtypeprefix", pm.ALLOW_ACTION],
+ ]);
+
+ // check that permission updates are reflected
+ pm.addFromPrincipal(principal, "test/getallwithtypeprefix", pm.PROMPT_ACTION);
+ check_enumerator("test/", [
+ [subPrincipal, "test/getallwithtypeprefix", pm.PROMPT_ACTION],
+ [principal, "test/getallwithtypeprefix", pm.PROMPT_ACTION],
+ ]);
+
+ // check that permission removals are reflected
+ pm.removeFromPrincipal(principal, "test/getallwithtypeprefix");
+ check_enumerator("test/", [
+ [subPrincipal, "test/getallwithtypeprefix", pm.PROMPT_ACTION],
+ ]);
+
+ pm.removeAll();
+ check_enumerator("test/", []);
+}
diff --git a/extensions/permissions/test/unit/test_permmanager_getPermissionObject.js b/extensions/permissions/test/unit/test_permmanager_getPermissionObject.js
new file mode 100644
index 0000000000..78ef9ab08a
--- /dev/null
+++ b/extensions/permissions/test/unit/test_permmanager_getPermissionObject.js
@@ -0,0 +1,98 @@
+/* Any copyright is dedicated to the Public Domain.
+ http://creativecommons.org/publicdomain/zero/1.0/ */
+
+function getPrincipalFromURI(aURI) {
+ let ssm = Services.scriptSecurityManager;
+ let uri = NetUtil.newURI(aURI);
+ return ssm.createContentPrincipal(uri, {});
+}
+
+function getSystemPrincipal() {
+ return Services.scriptSecurityManager.getSystemPrincipal();
+}
+
+function run_test() {
+ var pm = Services.perms;
+
+ Assert.equal(
+ null,
+ pm.getPermissionObject(getSystemPrincipal(), "test/pobject", false)
+ );
+
+ let principal = getPrincipalFromURI("http://example.com");
+ let subPrincipal = getPrincipalFromURI("http://sub.example.com");
+ let subSubPrincipal = getPrincipalFromURI("http://sub.sub.example.com");
+
+ Assert.equal(null, pm.getPermissionObject(principal, "test/pobject", false));
+ Assert.equal(null, pm.getPermissionObject(principal, "test/pobject", true));
+
+ pm.addFromPrincipal(principal, "test/pobject", pm.ALLOW_ACTION);
+ var rootPerm = pm.getPermissionObject(principal, "test/pobject", false);
+ Assert.ok(rootPerm != null);
+ Assert.equal(rootPerm.principal.origin, "http://example.com");
+ Assert.equal(rootPerm.type, "test/pobject");
+ Assert.equal(rootPerm.capability, pm.ALLOW_ACTION);
+ Assert.equal(rootPerm.expireType, pm.EXPIRE_NEVER);
+
+ Assert.ok(rootPerm != null);
+ Assert.equal(rootPerm.principal.origin, "http://example.com");
+
+ var subPerm = pm.getPermissionObject(subPrincipal, "test/pobject", true);
+ Assert.equal(null, subPerm);
+ subPerm = pm.getPermissionObject(subPrincipal, "test/pobject", false);
+ Assert.ok(subPerm != null);
+ Assert.equal(subPerm.principal.origin, "http://example.com");
+ Assert.equal(subPerm.type, "test/pobject");
+ Assert.equal(subPerm.capability, pm.ALLOW_ACTION);
+
+ subPerm = pm.getPermissionObject(subSubPrincipal, "test/pobject", true);
+ Assert.equal(null, subPerm);
+ subPerm = pm.getPermissionObject(subSubPrincipal, "test/pobject", false);
+ Assert.ok(subPerm != null);
+ Assert.equal(subPerm.principal.origin, "http://example.com");
+
+ pm.addFromPrincipal(
+ principal,
+ "test/pobject",
+ pm.DENY_ACTION,
+ pm.EXPIRE_SESSION
+ );
+
+ // make sure permission objects are not dynamic
+ Assert.equal(rootPerm.capability, pm.ALLOW_ACTION);
+
+ // but do update on change
+ rootPerm = pm.getPermissionObject(principal, "test/pobject", true);
+ Assert.equal(rootPerm.capability, pm.DENY_ACTION);
+ Assert.equal(rootPerm.expireType, pm.EXPIRE_SESSION);
+
+ subPerm = pm.getPermissionObject(subPrincipal, "test/pobject", false);
+ Assert.equal(subPerm.principal.origin, "http://example.com");
+ Assert.equal(subPerm.capability, pm.DENY_ACTION);
+ Assert.equal(subPerm.expireType, pm.EXPIRE_SESSION);
+
+ pm.addFromPrincipal(subPrincipal, "test/pobject", pm.PROMPT_ACTION);
+ rootPerm = pm.getPermissionObject(principal, "test/pobject", true);
+ Assert.equal(rootPerm.principal.origin, "http://example.com");
+ Assert.equal(rootPerm.capability, pm.DENY_ACTION);
+
+ subPerm = pm.getPermissionObject(subPrincipal, "test/pobject", true);
+ Assert.equal(subPerm.principal.origin, "http://sub.example.com");
+ Assert.equal(subPerm.capability, pm.PROMPT_ACTION);
+
+ subPerm = pm.getPermissionObject(subPrincipal, "test/pobject", false);
+ Assert.equal(subPerm.principal.origin, "http://sub.example.com");
+ Assert.equal(subPerm.capability, pm.PROMPT_ACTION);
+
+ subPerm = pm.getPermissionObject(subSubPrincipal, "test/pobject", true);
+ Assert.equal(null, subPerm);
+
+ subPerm = pm.getPermissionObject(subSubPrincipal, "test/pobject", false);
+ Assert.equal(subPerm.principal.origin, "http://sub.example.com");
+ Assert.equal(subPerm.capability, pm.PROMPT_ACTION);
+
+ pm.removeFromPrincipal(principal, "test/pobject");
+
+ rootPerm = pm.getPermissionObject(principal, "test/pobject", true);
+ Assert.equal(null, rootPerm);
+}
diff --git a/extensions/permissions/test/unit/test_permmanager_idn.js b/extensions/permissions/test/unit/test_permmanager_idn.js
new file mode 100644
index 0000000000..5719131245
--- /dev/null
+++ b/extensions/permissions/test/unit/test_permmanager_idn.js
@@ -0,0 +1,75 @@
+/* Any copyright is dedicated to the Public Domain.
+ http://creativecommons.org/publicdomain/zero/1.0/ */
+
+function getPrincipalFromDomain(aDomain) {
+ let ssm = Services.scriptSecurityManager;
+ let uri = NetUtil.newURI("http://" + aDomain);
+ return ssm.createContentPrincipal(uri, {});
+}
+
+function run_test() {
+ let pm = Services.perms;
+ let perm = "test-idn";
+
+ // We create three principal linked to IDN.
+ // One with just a domain, one with a subdomain and one with the TLD
+ // containing a UTF-8 character.
+ let mainDomainPrincipal = getPrincipalFromDomain("f担短.com");
+ let subDomainPrincipal = getPrincipalFromDomain("f担担.br.com");
+ let tldPrincipal = getPrincipalFromDomain("f担短.br.c担m");
+
+ // We add those to the permission manager.
+ pm.addFromPrincipal(mainDomainPrincipal, perm, pm.ALLOW_ACTION, 0, 0);
+ pm.addFromPrincipal(subDomainPrincipal, perm, pm.ALLOW_ACTION, 0, 0);
+ pm.addFromPrincipal(tldPrincipal, perm, pm.ALLOW_ACTION, 0, 0);
+
+ // They should obviously be there now..
+ Assert.equal(
+ pm.testPermissionFromPrincipal(mainDomainPrincipal, perm),
+ pm.ALLOW_ACTION
+ );
+ Assert.equal(
+ pm.testPermissionFromPrincipal(subDomainPrincipal, perm),
+ pm.ALLOW_ACTION
+ );
+ Assert.equal(
+ pm.testPermissionFromPrincipal(tldPrincipal, perm),
+ pm.ALLOW_ACTION
+ );
+
+ // We do the same thing with the puny-encoded versions of the IDN.
+ let punyMainDomainPrincipal = getPrincipalFromDomain("xn--f-xgav.com");
+ let punySubDomainPrincipal = getPrincipalFromDomain(
+ "xn--f-xgaa.xn--br-jia.com"
+ );
+ let punyTldPrincipal = getPrincipalFromDomain(
+ "xn--f-xgav.xn--br-jia.xn--cm-8ja"
+ );
+
+ // Those principals should have the permission granted too.
+ Assert.equal(
+ pm.testPermissionFromPrincipal(punyMainDomainPrincipal, perm),
+ pm.ALLOW_ACTION
+ );
+ Assert.equal(
+ pm.testPermissionFromPrincipal(punySubDomainPrincipal, perm),
+ pm.ALLOW_ACTION
+ );
+ Assert.equal(
+ pm.testPermissionFromPrincipal(punyTldPrincipal, perm),
+ pm.ALLOW_ACTION
+ );
+
+ // However, those two principals shouldn't be allowed because they are like
+ // the IDN but without the UT8-8 characters.
+ let witnessPrincipal = getPrincipalFromDomain("foo.com");
+ Assert.equal(
+ pm.testPermissionFromPrincipal(witnessPrincipal, perm),
+ pm.UNKNOWN_ACTION
+ );
+ witnessPrincipal = getPrincipalFromDomain("foo.bar.com");
+ Assert.equal(
+ pm.testPermissionFromPrincipal(witnessPrincipal, perm),
+ pm.UNKNOWN_ACTION
+ );
+}
diff --git a/extensions/permissions/test/unit/test_permmanager_ipc.js b/extensions/permissions/test/unit/test_permmanager_ipc.js
new file mode 100644
index 0000000000..239cc5aeaf
--- /dev/null
+++ b/extensions/permissions/test/unit/test_permmanager_ipc.js
@@ -0,0 +1,89 @@
+/* Any copyright is dedicated to the Public Domain.
+ http://creativecommons.org/publicdomain/zero/1.0/ */
+
+const { ExtensionTestUtils } = ChromeUtils.importESModule(
+ "resource://testing-common/ExtensionXPCShellUtils.sys.mjs"
+);
+
+add_task(async function test_permissions_sent_over_ipc_on_bloburl() {
+ const ssm = Services.scriptSecurityManager;
+ const pm = Services.perms;
+
+ // setup a profile.
+ do_get_profile();
+
+ async function assertExpectedContentPage(contentPage) {
+ const [processType, remoteType, principalSpec] = await page.spawn(
+ [],
+ async () => {
+ return [
+ Services.appinfo.processType,
+ Services.appinfo.remoteType,
+ this.content.document.nodePrincipal.spec,
+ ];
+ }
+ );
+
+ equal(
+ processType,
+ Services.appinfo.PROCESS_TYPE_CONTENT,
+ "Got a content process"
+ );
+ equal(remoteType, "file", "Got a file child process");
+ equal(principalSpec, principal.spec, "Got the expected document principal");
+ }
+
+ function getChildProcessID(contentPage) {
+ return contentPage.spawn([], () => Services.appinfo.processID);
+ }
+
+ async function assertHasAllowedPermission(contentPage, perm) {
+ const isPermissionAllowed = await contentPage.spawn(
+ [perm],
+ permName =>
+ Services.perms.getPermissionObject(
+ this.content.document.nodePrincipal,
+ permName,
+ true
+ )?.capability === Services.perms.ALLOW_ACTION
+ );
+ ok(isPermissionAllowed, `Permission "${perm}" allowed as expected`);
+ }
+
+ let file = do_get_file(".", true);
+ let fileURI = Services.io.newFileURI(file);
+ const principal = ssm.createContentPrincipal(fileURI, {});
+ info(`Add a test permission to the document principal: ${principal.spec}`);
+ pm.addFromPrincipal(principal, "test/perm", pm.ALLOW_ACTION);
+
+ info("Test expected permission is propagated into the child process");
+ let page = await ExtensionTestUtils.loadContentPage(fileURI.spec);
+ const childID1 = await getChildProcessID(page);
+ await assertExpectedContentPage(page);
+ await assertHasAllowedPermission(page, "test/perm");
+ await page.close();
+
+ // Ensure this blob url does not prevent permissions to be propagated
+ // to a new child process.
+ info("Create a blob url for a non http/https principal");
+ const blob = new Blob();
+ const blobURL = URL.createObjectURL(blob);
+ ok(blobURL, "Got a blob URL");
+
+ info("Test expected permission is still propagated");
+ page = await ExtensionTestUtils.loadContentPage(fileURI.spec);
+ const childID2 = await getChildProcessID(page);
+ await assertExpectedContentPage(page);
+ Assert.notEqual(childID1, childID2, "Got a new child process as expected");
+ await assertHasAllowedPermission(page, "test/perm");
+ await page.close();
+
+ URL.revokeObjectURL(blobURL);
+
+ page = await ExtensionTestUtils.loadContentPage(fileURI.spec);
+ const childID3 = await getChildProcessID(page);
+ await assertExpectedContentPage(page);
+ Assert.notEqual(childID2, childID3, "Got a new child process as expected");
+ await assertHasAllowedPermission(page, "test/perm");
+ await page.close();
+});
diff --git a/extensions/permissions/test/unit/test_permmanager_load_invalid_entries.js b/extensions/permissions/test/unit/test_permmanager_load_invalid_entries.js
new file mode 100644
index 0000000000..decbce81a0
--- /dev/null
+++ b/extensions/permissions/test/unit/test_permmanager_load_invalid_entries.js
@@ -0,0 +1,264 @@
+/* Any copyright is dedicated to the Public Domain.
+ http://creativecommons.org/publicdomain/zero/1.0/ */
+var DEBUG_TEST = false;
+
+function run_test() {
+ Services.prefs.setCharPref("permissions.manager.defaultsUrl", "");
+ // Setup a profile directory.
+ var dir = do_get_profile();
+
+ // We need to execute a pm method to be sure that the DB is fully
+ // initialized.
+ var pm = Services.perms;
+ Assert.equal(pm.all.length, 0, "No cookies");
+
+ // Get the db file.
+ var file = dir.clone();
+ file.append("permissions.sqlite");
+
+ var storage = Services.storage;
+
+ // Create database.
+ var connection = storage.openDatabase(file);
+ // The file should now exist.
+ Assert.ok(file.exists());
+
+ connection.schemaVersion = 3;
+ connection.executeSimpleSQL("DROP TABLE moz_hosts");
+ connection.executeSimpleSQL(
+ "CREATE TABLE moz_hosts (" +
+ " id INTEGER PRIMARY KEY" +
+ ",host TEXT" +
+ ",type TEXT" +
+ ",permission INTEGER" +
+ ",expireType INTEGER" +
+ ",expireTime INTEGER" +
+ ",appId INTEGER" +
+ ",isInBrowserElement INTEGER" +
+ ")"
+ );
+
+ // Now we can inject garbadge in the database.
+ var garbadge = [
+ // Regular entry.
+ {
+ host: "42",
+ type: "0",
+ permission: 1,
+ expireType: 0,
+ expireTime: 0,
+ isInBrowserElement: 0,
+ },
+
+ // Special values in host (some being invalid).
+ {
+ host: "scheme:file",
+ type: "1",
+ permission: 0,
+ expireType: 0,
+ expireTime: 0,
+ isInBrowserElement: 0,
+ },
+ {
+ host: "192.168.0.1",
+ type: "2",
+ permission: 0,
+ expireType: 0,
+ expireTime: 0,
+ isInBrowserElement: 0,
+ },
+ {
+ host: "2001:0db8:0000:0000:0000:ff00:0042:8329",
+ type: "3",
+ permission: 0,
+ expireType: 0,
+ expireTime: 0,
+ isInBrowserElement: 0,
+ },
+ {
+ host: "::1",
+ type: "4",
+ permission: 0,
+ expireType: 0,
+ expireTime: 0,
+ isInBrowserElement: 0,
+ },
+
+ // Permission is UNKNOWN_ACTION.
+ {
+ host: "42",
+ type: "5",
+ permission: Ci.nsIPermissionManager.UNKNOWN_ACTION,
+ expireType: 0,
+ expireTime: 0,
+ isInBrowserElement: 0,
+ },
+
+ // Permission is out of range.
+ {
+ host: "42",
+ type: "6",
+ permission: 100,
+ expireType: 0,
+ expireTime: 0,
+ isInBrowserElement: 0,
+ },
+ {
+ host: "42",
+ type: "7",
+ permission: -100,
+ expireType: 0,
+ expireTime: 0,
+ isInBrowserElement: 0,
+ },
+
+ // ExpireType is out of range.
+ {
+ host: "42",
+ type: "8",
+ permission: 1,
+ expireType: -100,
+ expireTime: 0,
+ isInBrowserElement: 0,
+ },
+ {
+ host: "42",
+ type: "9",
+ permission: 1,
+ expireType: 100,
+ expireTime: 0,
+ isInBrowserElement: 0,
+ },
+
+ // ExpireTime is at 0 with ExpireType = Time.
+ {
+ host: "42",
+ type: "10",
+ permission: 1,
+ expireType: Ci.nsIPermissionManager.EXPIRE_TIME,
+ expireTime: 0,
+ isInBrowserElement: 0,
+ },
+
+ // ExpireTime has a value with ExpireType != Time
+ {
+ host: "42",
+ type: "11",
+ permission: 1,
+ expireType: Ci.nsIPermissionManager.EXPIRE_SESSION,
+ expireTime: 1000,
+ isInBrowserElement: 0,
+ },
+ {
+ host: "42",
+ type: "12",
+ permission: 1,
+ expireType: Ci.nsIPermissionManager.EXPIRE_NEVER,
+ expireTime: 1000,
+ isInBrowserElement: 0,
+ },
+
+ // ExpireTime is negative.
+ {
+ host: "42",
+ type: "13",
+ permission: 1,
+ expireType: Ci.nsIPermissionManager.EXPIRE_TIME,
+ expireTime: -1,
+ isInBrowserElement: 0,
+ },
+
+ // IsInBrowserElement is negative or higher than 1.
+ {
+ host: "42",
+ type: "15",
+ permission: 1,
+ expireType: 0,
+ expireTime: 0,
+ isInBrowserElement: -1,
+ },
+ {
+ host: "42",
+ type: "16",
+ permission: 1,
+ expireType: 0,
+ expireTime: 0,
+ isInBrowserElement: 10,
+ },
+
+ // This insertion should be the last one. It is used to make sure we always
+ // load it regardless of the previous entries validities.
+ {
+ host: "example.org",
+ type: "test-load-invalid-entries",
+ permission: Ci.nsIPermissionManager.ALLOW_ACTION,
+ expireType: 0,
+ expireTime: 0,
+ isInBrowserElement: 0,
+ },
+ ];
+
+ for (var i = 0; i < garbadge.length; ++i) {
+ if (DEBUG_TEST) {
+ dump("\n value #" + i + "\n\n");
+ }
+ var data = garbadge[i];
+ connection.executeSimpleSQL(
+ "INSERT INTO moz_hosts " +
+ " (id, host, type, permission, expireType, expireTime, isInBrowserElement, appId) " +
+ "VALUES (" +
+ i +
+ ", '" +
+ data.host +
+ "', '" +
+ data.type +
+ "', " +
+ data.permission +
+ ", " +
+ data.expireType +
+ ", " +
+ data.expireTime +
+ ", " +
+ data.isInBrowserElement +
+ ", 0)"
+ );
+ }
+
+ // This will force the permission-manager to reload the data.
+ Services.obs.notifyObservers(null, "testonly-reload-permissions-from-disk");
+
+ // Let's do something in order to be sure the DB is read.
+ Assert.greater(pm.all.length, 0);
+
+ // The schema should be upgraded to 11, and a 'modificationTime' column should
+ // exist with all records having a value of 0.
+ Assert.equal(connection.schemaVersion, 12);
+
+ let select = connection.createStatement(
+ "SELECT modificationTime FROM moz_perms"
+ );
+ let numMigrated = 0;
+ while (select.executeStep()) {
+ let thisModTime = select.getInt64(0);
+ Assert.ok(
+ thisModTime > 0,
+ "new modifiedTime field is correct (but it's not 0!)"
+ );
+ numMigrated += 1;
+ }
+ // check we found at least 1 record that was migrated.
+ Assert.greater(
+ numMigrated,
+ 0,
+ "we found at least 1 record that was migrated"
+ );
+
+ // This permission should always be there.
+ let ssm = Services.scriptSecurityManager;
+ let uri = NetUtil.newURI("http://example.org");
+ let principal = ssm.createContentPrincipal(uri, {});
+ Assert.equal(
+ pm.testPermissionFromPrincipal(principal, "test-load-invalid-entries"),
+ Ci.nsIPermissionManager.ALLOW_ACTION
+ );
+}
diff --git a/extensions/permissions/test/unit/test_permmanager_local_files.js b/extensions/permissions/test/unit/test_permmanager_local_files.js
new file mode 100644
index 0000000000..389eb77916
--- /dev/null
+++ b/extensions/permissions/test/unit/test_permmanager_local_files.js
@@ -0,0 +1,74 @@
+/* Any copyright is dedicated to the Public Domain.
+ http://creativecommons.org/publicdomain/zero/1.0/ */
+
+// Test that permissions work for file:// URIs (aka local files).
+
+function getPrincipalFromURIString(uriStr) {
+ let uri = NetUtil.newURI(uriStr);
+ return Services.scriptSecurityManager.createContentPrincipal(uri, {});
+}
+
+function run_test() {
+ let pm = Services.perms;
+
+ // If we add a permission to a file:// URI, the test should return true.
+ let principal = getPrincipalFromURIString("file:///foo/bar");
+ pm.addFromPrincipal(principal, "test/local-files", pm.ALLOW_ACTION, 0, 0);
+ Assert.equal(
+ pm.testPermissionFromPrincipal(principal, "test/local-files"),
+ pm.ALLOW_ACTION
+ );
+
+ // Another file:// URI should have the same permission.
+ let witnessPrincipal = getPrincipalFromURIString("file:///bar/foo");
+ Assert.equal(
+ pm.testPermissionFromPrincipal(witnessPrincipal, "test/local-files"),
+ pm.UNKNOWN_ACTION
+ );
+
+ // Giving "file:///" a permission shouldn't give it to all file:// URIs.
+ let rootPrincipal = getPrincipalFromURIString("file:///");
+ pm.addFromPrincipal(rootPrincipal, "test/local-files", pm.ALLOW_ACTION, 0, 0);
+ Assert.equal(
+ pm.testPermissionFromPrincipal(witnessPrincipal, "test/local-files"),
+ pm.UNKNOWN_ACTION
+ );
+
+ // Giving "file://" a permission shouldn't give it to all file:// URIs.
+ let schemeRootPrincipal = getPrincipalFromURIString("file://");
+ pm.addFromPrincipal(
+ schemeRootPrincipal,
+ "test/local-files",
+ pm.ALLOW_ACTION,
+ 0,
+ 0
+ );
+ Assert.equal(
+ pm.testPermissionFromPrincipal(witnessPrincipal, "test/local-files"),
+ pm.UNKNOWN_ACTION
+ );
+
+ // Giving 'node' a permission shouldn't give it to its 'children'.
+ let fileInDirPrincipal = getPrincipalFromURIString(
+ "file:///foo/bar/foobar.txt"
+ );
+ Assert.equal(
+ pm.testPermissionFromPrincipal(fileInDirPrincipal, "test/local-files"),
+ pm.UNKNOWN_ACTION
+ );
+
+ // Revert "file:///foo/bar" permission and check that it has been correctly taken into account.
+ pm.removeFromPrincipal(principal, "test/local-files");
+ Assert.equal(
+ pm.testPermissionFromPrincipal(principal, "test/local-files"),
+ pm.UNKNOWN_ACTION
+ );
+ Assert.equal(
+ pm.testPermissionFromPrincipal(witnessPrincipal, "test/local-files"),
+ pm.UNKNOWN_ACTION
+ );
+ Assert.equal(
+ pm.testPermissionFromPrincipal(fileInDirPrincipal, "test/local-files"),
+ pm.UNKNOWN_ACTION
+ );
+}
diff --git a/extensions/permissions/test/unit/test_permmanager_matches.js b/extensions/permissions/test/unit/test_permmanager_matches.js
new file mode 100644
index 0000000000..937a1ce750
--- /dev/null
+++ b/extensions/permissions/test/unit/test_permmanager_matches.js
@@ -0,0 +1,203 @@
+/* Any copyright is dedicated to the Public Domain.
+ http://creativecommons.org/publicdomain/zero/1.0/ */
+
+var attrs;
+
+function matches_always(perm, principals) {
+ principals.forEach(principal => {
+ Assert.ok(
+ perm.matches(principal, true),
+ "perm: " + perm.principal.origin + ", princ: " + principal.origin
+ );
+ Assert.ok(
+ perm.matches(principal, false),
+ "perm: " + perm.principal.origin + ", princ: " + principal.origin
+ );
+ });
+}
+
+function matches_weak(perm, principals) {
+ principals.forEach(principal => {
+ Assert.ok(
+ !perm.matches(principal, true),
+ "perm: " + perm.principal.origin + ", princ: " + principal.origin
+ );
+ Assert.ok(
+ perm.matches(principal, false),
+ "perm: " + perm.principal.origin + ", princ: " + principal.origin
+ );
+ });
+}
+
+function matches_never(perm, principals) {
+ principals.forEach(principal => {
+ Assert.ok(
+ !perm.matches(principal, true),
+ "perm: " + perm.principal.origin + ", princ: " + principal.origin
+ );
+ Assert.ok(
+ !perm.matches(principal, false),
+ "perm: " + perm.principal.origin + ", princ: " + principal.origin
+ );
+ });
+}
+
+function run_test() {
+ // initialize the permission manager service
+ let pm = Services.perms;
+
+ let secMan = Services.scriptSecurityManager;
+
+ // Add some permissions
+ let uri0 = NetUtil.newURI("http://google.com/search?q=foo#hashtag");
+ let uri1 = NetUtil.newURI("http://hangouts.google.com/subdir");
+ let uri2 = NetUtil.newURI("http://google.org/");
+ let uri3 = NetUtil.newURI("https://google.com/some/random/subdirectory");
+ let uri4 = NetUtil.newURI("https://hangouts.google.com/#!/hangout");
+ let uri5 = NetUtil.newURI("http://google.com:8096/");
+
+ let uri0_n = secMan.createContentPrincipal(uri0, {});
+ let uri1_n = secMan.createContentPrincipal(uri1, {});
+ let uri2_n = secMan.createContentPrincipal(uri2, {});
+ let uri3_n = secMan.createContentPrincipal(uri3, {});
+ let uri4_n = secMan.createContentPrincipal(uri4, {});
+ let uri5_n = secMan.createContentPrincipal(uri5, {});
+
+ attrs = { inIsolatedMozBrowser: true };
+ let uri0_y_ = secMan.createContentPrincipal(uri0, attrs);
+ let uri1_y_ = secMan.createContentPrincipal(uri1, attrs);
+ let uri2_y_ = secMan.createContentPrincipal(uri2, attrs);
+ let uri3_y_ = secMan.createContentPrincipal(uri3, attrs);
+ let uri4_y_ = secMan.createContentPrincipal(uri4, attrs);
+ let uri5_y_ = secMan.createContentPrincipal(uri5, attrs);
+
+ attrs = { userContextId: 1 };
+ let uri0_1 = secMan.createContentPrincipal(uri0, attrs);
+ let uri1_1 = secMan.createContentPrincipal(uri1, attrs);
+ let uri2_1 = secMan.createContentPrincipal(uri2, attrs);
+ let uri3_1 = secMan.createContentPrincipal(uri3, attrs);
+ let uri4_1 = secMan.createContentPrincipal(uri4, attrs);
+ let uri5_1 = secMan.createContentPrincipal(uri5, attrs);
+
+ attrs = { firstPartyDomain: "cnn.com" };
+ let uri0_cnn = secMan.createContentPrincipal(uri0, attrs);
+ let uri1_cnn = secMan.createContentPrincipal(uri1, attrs);
+ let uri2_cnn = secMan.createContentPrincipal(uri2, attrs);
+ let uri3_cnn = secMan.createContentPrincipal(uri3, attrs);
+ let uri4_cnn = secMan.createContentPrincipal(uri4, attrs);
+ let uri5_cnn = secMan.createContentPrincipal(uri5, attrs);
+
+ pm.addFromPrincipal(uri0_n, "test/matches", pm.ALLOW_ACTION);
+ let perm_n = pm.getPermissionObject(uri0_n, "test/matches", true);
+ pm.addFromPrincipal(uri0_y_, "test/matches", pm.ALLOW_ACTION);
+ let perm_y_ = pm.getPermissionObject(uri0_y_, "test/matches", true);
+ pm.addFromPrincipal(uri0_1, "test/matches", pm.ALLOW_ACTION);
+ let perm_1 = pm.getPermissionObject(uri0_n, "test/matches", true);
+ pm.addFromPrincipal(uri0_cnn, "test/matches", pm.ALLOW_ACTION);
+ let perm_cnn = pm.getPermissionObject(uri0_n, "test/matches", true);
+
+ matches_always(perm_n, [uri0_n, uri0_1]);
+ matches_weak(perm_n, [uri1_n, uri1_1]);
+ matches_never(perm_n, [
+ uri2_n,
+ uri3_n,
+ uri4_n,
+ uri5_n,
+ uri0_y_,
+ uri1_y_,
+ uri2_y_,
+ uri3_y_,
+ uri4_y_,
+ uri5_y_,
+ uri2_1,
+ uri3_1,
+ uri4_1,
+ uri5_1,
+ uri0_cnn,
+ uri1_cnn,
+ uri2_cnn,
+ uri3_cnn,
+ uri4_cnn,
+ uri5_cnn,
+ ]);
+
+ matches_always(perm_y_, [uri0_y_]);
+ matches_weak(perm_y_, [uri1_y_]);
+ matches_never(perm_y_, [
+ uri2_y_,
+ uri3_y_,
+ uri4_y_,
+ uri5_y_,
+ uri0_n,
+ uri1_n,
+ uri2_n,
+ uri3_n,
+ uri4_n,
+ uri5_n,
+ uri0_1,
+ uri1_1,
+ uri2_1,
+ uri3_1,
+ uri4_1,
+ uri5_1,
+ uri0_cnn,
+ uri1_cnn,
+ uri2_cnn,
+ uri3_cnn,
+ uri4_cnn,
+ uri5_cnn,
+ ]);
+
+ matches_always(perm_1, [uri0_n, uri0_1]);
+ matches_weak(perm_1, [uri1_n, uri1_1]);
+ matches_never(perm_1, [
+ uri2_n,
+ uri3_n,
+ uri4_n,
+ uri5_n,
+ uri0_y_,
+ uri1_y_,
+ uri2_y_,
+ uri3_y_,
+ uri4_y_,
+ uri5_y_,
+ uri2_1,
+ uri3_1,
+ uri4_1,
+ uri5_1,
+ uri0_cnn,
+ uri1_cnn,
+ uri2_cnn,
+ uri3_cnn,
+ uri4_cnn,
+ uri5_cnn,
+ ]);
+
+ matches_always(perm_cnn, [uri0_n, uri0_1]);
+ matches_weak(perm_cnn, [uri1_n, uri1_1]);
+ matches_never(perm_cnn, [
+ uri2_n,
+ uri3_n,
+ uri4_n,
+ uri5_n,
+ uri0_y_,
+ uri1_y_,
+ uri2_y_,
+ uri3_y_,
+ uri4_y_,
+ uri5_y_,
+ uri2_1,
+ uri3_1,
+ uri4_1,
+ uri5_1,
+ uri0_cnn,
+ uri1_cnn,
+ uri2_cnn,
+ uri3_cnn,
+ uri4_cnn,
+ uri5_cnn,
+ ]);
+
+ // Clean up!
+ pm.removeAll();
+}
diff --git a/extensions/permissions/test/unit/test_permmanager_matchesuri.js b/extensions/permissions/test/unit/test_permmanager_matchesuri.js
new file mode 100644
index 0000000000..1218fbf9ca
--- /dev/null
+++ b/extensions/permissions/test/unit/test_permmanager_matchesuri.js
@@ -0,0 +1,252 @@
+/* Any copyright is dedicated to the Public Domain.
+ http://creativecommons.org/publicdomain/zero/1.0/ */
+
+function matches_always(perm, uris) {
+ uris.forEach(uri => {
+ Assert.ok(
+ perm.matchesURI(uri, true),
+ "perm: " + perm.principal.origin + ", URI: " + uri.spec
+ );
+ Assert.ok(
+ perm.matchesURI(uri, false),
+ "perm: " + perm.principal.origin + ", URI: " + uri.spec
+ );
+ });
+}
+
+function matches_weak(perm, uris) {
+ uris.forEach(uri => {
+ Assert.ok(
+ !perm.matchesURI(uri, true),
+ "perm: " + perm.principal.origin + ", URI: " + uri.spec
+ );
+ Assert.ok(
+ perm.matchesURI(uri, false),
+ "perm: " + perm.principal.origin + ", URI: " + uri.spec
+ );
+ });
+}
+
+function matches_never(perm, uris) {
+ uris.forEach(uri => {
+ Assert.ok(
+ !perm.matchesURI(uri, true),
+ "perm: " + perm.principal.origin + ", URI: " + uri.spec
+ );
+ Assert.ok(
+ !perm.matchesURI(uri, false),
+ "perm: " + perm.principal.origin + ", URI: " + uri.spec
+ );
+ });
+}
+
+function mk_permission(uri) {
+ let pm = Services.perms;
+
+ let secMan = Services.scriptSecurityManager;
+
+ // Get the permission from the principal!
+ let principal = secMan.createContentPrincipal(uri, {});
+
+ pm.addFromPrincipal(principal, "test/matchesuri", pm.ALLOW_ACTION);
+ let permission = pm.getPermissionObject(principal, "test/matchesuri", true);
+
+ return permission;
+}
+
+function run_test() {
+ // initialize the permission manager service
+ let pm = Services.perms;
+
+ let fileprefix = "file:///";
+ if (Services.appinfo.OS == "WINNT") {
+ // Windows rejects files if they don't have a drive. See Bug 1180870
+ fileprefix += "c:/";
+ }
+
+ // Add some permissions
+ let uri0 = NetUtil.newURI("http://google.com:9091/just/a/path");
+ let uri1 = NetUtil.newURI("http://hangouts.google.com:9091/some/path");
+ let uri2 = NetUtil.newURI("http://google.com:9091/");
+ let uri3 = NetUtil.newURI("http://google.org:9091/");
+ let uri4 = NetUtil.newURI("http://deeper.hangouts.google.com:9091/");
+ let uri5 = NetUtil.newURI("https://google.com/just/a/path");
+ let uri6 = NetUtil.newURI("https://hangouts.google.com");
+ let uri7 = NetUtil.newURI("https://google.com/");
+
+ let fileuri1 = NetUtil.newURI(fileprefix + "a/file/path");
+ let fileuri2 = NetUtil.newURI(fileprefix + "a/file/path/deeper");
+ let fileuri3 = NetUtil.newURI(fileprefix + "a/file/otherpath");
+
+ {
+ let perm = mk_permission(uri0);
+ matches_always(perm, [uri0, uri2]);
+ matches_weak(perm, [uri1, uri4]);
+ matches_never(perm, [uri3, uri5, uri6, uri7, fileuri1, fileuri2, fileuri3]);
+ }
+
+ {
+ let perm = mk_permission(uri1);
+ matches_always(perm, [uri1]);
+ matches_weak(perm, [uri4]);
+ matches_never(perm, [
+ uri0,
+ uri2,
+ uri3,
+ uri5,
+ uri6,
+ uri7,
+ fileuri1,
+ fileuri2,
+ fileuri3,
+ ]);
+ }
+
+ {
+ let perm = mk_permission(uri2);
+ matches_always(perm, [uri0, uri2]);
+ matches_weak(perm, [uri1, uri4]);
+ matches_never(perm, [uri3, uri5, uri6, uri7, fileuri1, fileuri2, fileuri3]);
+ }
+
+ {
+ let perm = mk_permission(uri3);
+ matches_always(perm, [uri3]);
+ matches_weak(perm, []);
+ matches_never(perm, [
+ uri1,
+ uri2,
+ uri4,
+ uri5,
+ uri6,
+ uri7,
+ fileuri1,
+ fileuri2,
+ fileuri3,
+ ]);
+ }
+
+ {
+ let perm = mk_permission(uri4);
+ matches_always(perm, [uri4]);
+ matches_weak(perm, []);
+ matches_never(perm, [
+ uri1,
+ uri2,
+ uri3,
+ uri5,
+ uri6,
+ uri7,
+ fileuri1,
+ fileuri2,
+ fileuri3,
+ ]);
+ }
+
+ {
+ let perm = mk_permission(uri5);
+ matches_always(perm, [uri5, uri7]);
+ matches_weak(perm, [uri6]);
+ matches_never(perm, [
+ uri0,
+ uri1,
+ uri2,
+ uri3,
+ uri4,
+ fileuri1,
+ fileuri2,
+ fileuri3,
+ ]);
+ }
+
+ {
+ let perm = mk_permission(uri6);
+ matches_always(perm, [uri6]);
+ matches_weak(perm, []);
+ matches_never(perm, [
+ uri0,
+ uri1,
+ uri2,
+ uri3,
+ uri4,
+ uri5,
+ uri7,
+ fileuri1,
+ fileuri2,
+ fileuri3,
+ ]);
+ }
+
+ {
+ let perm = mk_permission(uri7);
+ matches_always(perm, [uri5, uri7]);
+ matches_weak(perm, [uri6]);
+ matches_never(perm, [
+ uri0,
+ uri1,
+ uri2,
+ uri3,
+ uri4,
+ fileuri1,
+ fileuri2,
+ fileuri3,
+ ]);
+ }
+
+ {
+ let perm = mk_permission(fileuri1);
+ matches_always(perm, [fileuri1]);
+ matches_weak(perm, []);
+ matches_never(perm, [
+ uri0,
+ uri1,
+ uri2,
+ uri3,
+ uri4,
+ uri5,
+ uri6,
+ uri7,
+ fileuri2,
+ fileuri3,
+ ]);
+ }
+
+ {
+ let perm = mk_permission(fileuri2);
+ matches_always(perm, [fileuri2]);
+ matches_weak(perm, []);
+ matches_never(perm, [
+ uri0,
+ uri1,
+ uri2,
+ uri3,
+ uri4,
+ uri5,
+ uri6,
+ uri7,
+ fileuri1,
+ fileuri3,
+ ]);
+ }
+
+ {
+ let perm = mk_permission(fileuri3);
+ matches_always(perm, [fileuri3]);
+ matches_weak(perm, []);
+ matches_never(perm, [
+ uri0,
+ uri1,
+ uri2,
+ uri3,
+ uri4,
+ uri5,
+ uri6,
+ uri7,
+ fileuri1,
+ fileuri2,
+ ]);
+ }
+
+ // Clean up!
+ pm.removeAll();
+}
diff --git a/extensions/permissions/test/unit/test_permmanager_migrate_10-11.js b/extensions/permissions/test/unit/test_permmanager_migrate_10-11.js
new file mode 100644
index 0000000000..c0d30865ee
--- /dev/null
+++ b/extensions/permissions/test/unit/test_permmanager_migrate_10-11.js
@@ -0,0 +1,196 @@
+/* Any copyright is dedicated to the Public Domain.
+ http://creativecommons.org/publicdomain/zero/1.0/ */
+
+ChromeUtils.defineESModuleGetters(this, {
+ PlacesTestUtils: "resource://testing-common/PlacesTestUtils.sys.mjs",
+});
+
+var PERMISSIONS_FILE_NAME = "permissions.sqlite";
+
+function GetPermissionsFile(profile) {
+ let file = profile.clone();
+ file.append(PERMISSIONS_FILE_NAME);
+ return file;
+}
+
+add_task(async function test() {
+ // Create and set up the permissions database.
+ Services.prefs.setCharPref("permissions.manager.defaultsUrl", "");
+ let profile = do_get_profile();
+
+ // We need to execute a pm method to be sure that the DB is fully
+ // initialized.
+ var pm = Services.perms;
+ Assert.equal(pm.all.length, 0, "No cookies");
+
+ let db = Services.storage.openDatabase(GetPermissionsFile(profile));
+ db.schemaVersion = 10;
+
+ let stmt6Insert = db.createStatement(
+ "INSERT INTO moz_perms (" +
+ "id, origin, type, permission, expireType, expireTime, modificationTime" +
+ ") VALUES (" +
+ ":id, :origin, :type, :permission, :expireType, :expireTime, :modificationTime" +
+ ")"
+ );
+
+ let id = 0;
+
+ function insertOrigin(
+ origin,
+ type,
+ permission,
+ expireType,
+ expireTime,
+ modificationTime
+ ) {
+ let thisId = id++;
+
+ stmt6Insert.bindByName("id", thisId);
+ stmt6Insert.bindByName("origin", origin);
+ stmt6Insert.bindByName("type", type);
+ stmt6Insert.bindByName("permission", permission);
+ stmt6Insert.bindByName("expireType", expireType);
+ stmt6Insert.bindByName("expireTime", expireTime);
+ stmt6Insert.bindByName("modificationTime", modificationTime);
+
+ try {
+ stmt6Insert.execute();
+ } finally {
+ stmt6Insert.reset();
+ }
+
+ return {
+ id: thisId,
+ origin,
+ type,
+ permission,
+ expireType,
+ expireTime,
+ modificationTime,
+ };
+ }
+
+ insertOrigin(
+ "https://foo.com",
+ "storageAccessAPI^https://foo.com",
+ 2,
+ 0,
+ 0,
+ 0
+ );
+ insertOrigin(
+ "http://foo.com",
+ "storageAccessAPI^https://bar.com^https://foo.com",
+ 2,
+ 0,
+ 0,
+ 0
+ );
+ insertOrigin(
+ "http://foo.com",
+ "storageAccessAPI^https://bar.com^https://baz.com",
+ 2,
+ 0,
+ 0,
+ 0
+ );
+ insertOrigin("http://foo.com^inBrowser=1", "A", 2, 0, 0, 0);
+
+ // CLose the db connection
+ stmt6Insert.finalize();
+ db.close();
+ db = null;
+
+ let expected = [
+ ["https://foo.com", "storageAccessAPI^https://foo.com", 2, 0, 0, 0],
+ ["http://foo.com", "storageAccessAPI^https://bar.com", 2, 0, 0, 0],
+ ["http://foo.com", "storageAccessAPI^https://bar.com", 2, 0, 0, 0],
+ ["http://foo.com^inBrowser=1", "A", 2, 0, 0, 0],
+ ];
+
+ let found = expected.map(it => 0);
+
+ // Add some places to the places database
+ await PlacesTestUtils.addVisits(
+ Services.io.newURI("https://foo.com/some/other/subdirectory")
+ );
+ await PlacesTestUtils.addVisits(
+ Services.io.newURI("ftp://some.subdomain.of.foo.com:8000/some/subdirectory")
+ );
+ await PlacesTestUtils.addVisits(Services.io.newURI("ftp://127.0.0.1:8080"));
+ await PlacesTestUtils.addVisits(Services.io.newURI("https://localhost:8080"));
+
+ // This will force the permission-manager to reload the data.
+ Services.obs.notifyObservers(null, "testonly-reload-permissions-from-disk");
+
+ // Force initialization of the PermissionManager
+ for (let permission of Services.perms.all) {
+ let isExpected = false;
+
+ expected.forEach((it, i) => {
+ if (
+ permission.principal.origin == it[0] &&
+ permission.type == it[1] &&
+ permission.capability == it[2] &&
+ permission.expireType == it[3] &&
+ permission.expireTime == it[4]
+ ) {
+ isExpected = true;
+ found[i]++;
+ }
+ });
+
+ Assert.ok(
+ isExpected,
+ "Permission " +
+ (isExpected ? "should" : "shouldn't") +
+ " be in permission database: " +
+ permission.principal.origin +
+ ", " +
+ permission.type +
+ ", " +
+ permission.capability +
+ ", " +
+ permission.expireType +
+ ", " +
+ permission.expireTime
+ );
+ }
+
+ found.forEach((count, i) => {
+ Assert.ok(
+ count == 1,
+ "Expected count = 1, got count = " +
+ count +
+ " for permission " +
+ expected[i]
+ );
+ });
+
+ // Check to make sure that all of the tables which we care about are present
+ {
+ db = Services.storage.openDatabase(GetPermissionsFile(profile));
+ Assert.ok(db.tableExists("moz_perms"));
+ Assert.ok(db.tableExists("moz_hosts"));
+ Assert.ok(!db.tableExists("moz_perms_v6"));
+
+ let mozHostsCount = db.createStatement("SELECT count(*) FROM moz_hosts");
+ try {
+ mozHostsCount.executeStep();
+ Assert.equal(mozHostsCount.getInt64(0), 0);
+ } finally {
+ mozHostsCount.finalize();
+ }
+
+ let mozPermsCount = db.createStatement("SELECT count(*) FROM moz_perms");
+ try {
+ mozPermsCount.executeStep();
+ Assert.equal(mozPermsCount.getInt64(0), expected.length);
+ } finally {
+ mozPermsCount.finalize();
+ }
+
+ db.close();
+ }
+});
diff --git a/extensions/permissions/test/unit/test_permmanager_migrate_11-12.js b/extensions/permissions/test/unit/test_permmanager_migrate_11-12.js
new file mode 100644
index 0000000000..97170a9240
--- /dev/null
+++ b/extensions/permissions/test/unit/test_permmanager_migrate_11-12.js
@@ -0,0 +1,230 @@
+/* Any copyright is dedicated to the Public Domain.
+ http://creativecommons.org/publicdomain/zero/1.0/ */
+
+ChromeUtils.defineESModuleGetters(this, {
+ PlacesTestUtils: "resource://testing-common/PlacesTestUtils.sys.mjs",
+});
+
+var PERMISSIONS_FILE_NAME = "permissions.sqlite";
+
+function GetPermissionsFile(profile) {
+ let file = profile.clone();
+ file.append(PERMISSIONS_FILE_NAME);
+ return file;
+}
+
+add_task(async function test() {
+ // Create and set up the permissions database.
+ Services.prefs.setCharPref("permissions.manager.defaultsUrl", "");
+ let profile = do_get_profile();
+
+ // We need to execute a pm method to be sure that the DB is fully
+ // initialized.
+ var pm = Services.perms;
+ Assert.equal(pm.all.length, 0, "No cookies");
+
+ let db = Services.storage.openDatabase(GetPermissionsFile(profile));
+ db.schemaVersion = 11;
+
+ let stmt6Insert = db.createStatement(
+ "INSERT INTO moz_perms (" +
+ "id, origin, type, permission, expireType, expireTime, modificationTime" +
+ ") VALUES (" +
+ ":id, :origin, :type, :permission, :expireType, :expireTime, :modificationTime" +
+ ")"
+ );
+
+ let id = 0;
+
+ function insertOrigin(
+ origin,
+ type,
+ permission,
+ expireType,
+ expireTime,
+ modificationTime
+ ) {
+ let thisId = id++;
+
+ stmt6Insert.bindByName("id", thisId);
+ stmt6Insert.bindByName("origin", origin);
+ stmt6Insert.bindByName("type", type);
+ stmt6Insert.bindByName("permission", permission);
+ stmt6Insert.bindByName("expireType", expireType);
+ stmt6Insert.bindByName("expireTime", expireTime);
+ stmt6Insert.bindByName("modificationTime", modificationTime);
+
+ try {
+ stmt6Insert.execute();
+ } finally {
+ stmt6Insert.reset();
+ }
+
+ return {
+ id: thisId,
+ origin,
+ type,
+ permission,
+ expireType,
+ expireTime,
+ modificationTime,
+ };
+ }
+
+ insertOrigin("https://a.com", "3rdPartyStorage^https://b.com", 2, 0, 0, 0);
+ insertOrigin(
+ "https://www.a.com",
+ "3rdPartyStorage^https://www.c.com",
+ 2,
+ 0,
+ 0,
+ 0
+ );
+ insertOrigin(
+ "https://localhost",
+ "3rdPartyStorage^http://www.c.com",
+ 2,
+ 0,
+ 0,
+ 0
+ );
+
+ insertOrigin(
+ "https://www.b.co.uk",
+ "3rdPartyStorage^https://www.a.co.uk",
+ 2,
+ 0,
+ 0,
+ 0
+ );
+
+ insertOrigin(
+ "https://sub.www.b.co.uk",
+ "3rdPartyStorage^https://sub.www.a.co.uk",
+ 2,
+ 0,
+ 0,
+ 0
+ );
+
+ insertOrigin(
+ "https://example.b.co.uk",
+ "3rdPartyStorage^https://www.a.co.uk",
+ 2,
+ 0,
+ 0,
+ 0
+ );
+
+ insertOrigin(
+ "https://[::1]",
+ "3rdPartyStorage^https://www.a.co.uk",
+ 2,
+ 0,
+ 0,
+ 0
+ );
+ // Close the db connection
+ stmt6Insert.finalize();
+ db.close();
+ db = null;
+ info(Services.perms.all);
+
+ let expected = [
+ ["https://a.com", "3rdPartyStorage^https://b.com", 2, 0, 0, 0],
+ ["https://a.com", "3rdPartyStorage^https://www.c.com", 2, 0, 0, 0],
+ ["https://localhost", "3rdPartyStorage^http://www.c.com", 2, 0, 0, 0],
+ ["https://b.co.uk", "3rdPartyStorage^https://www.a.co.uk", 2, 0, 0, 0],
+ ["https://b.co.uk", "3rdPartyStorage^https://sub.www.a.co.uk", 2, 0, 0, 0],
+ ["https://[::1]", "3rdPartyStorage^https://www.a.co.uk", 2, 0, 0, 0],
+ ];
+
+ let found = expected.map(it => 0);
+
+ // Add some places to the places database
+ await PlacesTestUtils.addVisits(
+ Services.io.newURI("https://foo.com/some/other/subdirectory")
+ );
+ await PlacesTestUtils.addVisits(
+ Services.io.newURI("ftp://some.subdomain.of.foo.com:8000/some/subdirectory")
+ );
+ await PlacesTestUtils.addVisits(Services.io.newURI("ftp://127.0.0.1:8080"));
+ await PlacesTestUtils.addVisits(Services.io.newURI("https://localhost:8080"));
+
+ // This will force the permission-manager to reload the data.
+ Services.obs.notifyObservers(null, "testonly-reload-permissions-from-disk");
+
+ info(Services.perms.all);
+
+ // Force initialization of the PermissionManager
+ for (let permission of Services.perms.all) {
+ let isExpected = false;
+
+ expected.forEach((it, i) => {
+ if (
+ permission.principal.origin == it[0] &&
+ permission.type == it[1] &&
+ permission.capability == it[2] &&
+ permission.expireType == it[3] &&
+ permission.expireTime == it[4]
+ ) {
+ isExpected = true;
+ found[i]++;
+ }
+ });
+
+ Assert.ok(
+ isExpected,
+ "Permission " +
+ (isExpected ? "should" : "shouldn't") +
+ " be in permission database: " +
+ permission.principal.origin +
+ ", " +
+ permission.type +
+ ", " +
+ permission.capability +
+ ", " +
+ permission.expireType +
+ ", " +
+ permission.expireTime
+ );
+ }
+ info(expected);
+ info(found);
+
+ found.forEach((count, i) => {
+ Assert.ok(
+ count == 1,
+ "Expected count = 1, got count = " +
+ count +
+ " for permission " +
+ expected[i]
+ );
+ });
+
+ // Check to make sure that all of the tables which we care about are present
+ {
+ db = Services.storage.openDatabase(GetPermissionsFile(profile));
+ Assert.ok(db.tableExists("moz_perms"));
+ Assert.ok(db.tableExists("moz_hosts"));
+ Assert.ok(!db.tableExists("moz_perms_v6"));
+
+ let mozHostsCount = db.createStatement("SELECT count(*) FROM moz_hosts");
+ try {
+ mozHostsCount.executeStep();
+ Assert.equal(mozHostsCount.getInt64(0), 0);
+ } finally {
+ mozHostsCount.finalize();
+ }
+
+ let mozPermsCount = db.createStatement("SELECT count(*) FROM moz_perms");
+ try {
+ mozPermsCount.executeStep();
+ Assert.equal(mozPermsCount.getInt64(0), expected.length);
+ } finally {
+ mozPermsCount.finalize();
+ }
+
+ db.close();
+ }
+});
diff --git a/extensions/permissions/test/unit/test_permmanager_migrate_4-7.js b/extensions/permissions/test/unit/test_permmanager_migrate_4-7.js
new file mode 100644
index 0000000000..857e0a462c
--- /dev/null
+++ b/extensions/permissions/test/unit/test_permmanager_migrate_4-7.js
@@ -0,0 +1,264 @@
+/* Any copyright is dedicated to the Public Domain.
+ http://creativecommons.org/publicdomain/zero/1.0/ */
+
+ChromeUtils.defineESModuleGetters(this, {
+ PlacesTestUtils: "resource://testing-common/PlacesTestUtils.sys.mjs",
+});
+
+var PERMISSIONS_FILE_NAME = "permissions.sqlite";
+
+function GetPermissionsFile(profile) {
+ let file = profile.clone();
+ file.append(PERMISSIONS_FILE_NAME);
+ return file;
+}
+
+add_task(async function test() {
+ // Create and set up the permissions database.
+ Services.prefs.setCharPref("permissions.manager.defaultsUrl", "");
+ let profile = do_get_profile();
+
+ // We need to execute a pm method to be sure that the DB is fully
+ // initialized.
+ var pm = Services.perms;
+ Assert.equal(pm.all.length, 0, "No cookies");
+
+ let db = Services.storage.openDatabase(GetPermissionsFile(profile));
+ db.schemaVersion = 4;
+ db.executeSimpleSQL("DROP TABLE moz_perms");
+ db.executeSimpleSQL("DROP TABLE moz_hosts");
+
+ db.executeSimpleSQL(
+ "CREATE TABLE moz_hosts (" +
+ " id INTEGER PRIMARY KEY" +
+ ",host TEXT" +
+ ",type TEXT" +
+ ",permission INTEGER" +
+ ",expireType INTEGER" +
+ ",expireTime INTEGER" +
+ ",modificationTime INTEGER" +
+ ",appId INTEGER" +
+ ",isInBrowserElement INTEGER" +
+ ")"
+ );
+
+ let stmtInsert = db.createStatement(
+ "INSERT INTO moz_hosts (" +
+ "id, host, type, permission, expireType, expireTime, modificationTime, appId, isInBrowserElement" +
+ ") VALUES (" +
+ ":id, :host, :type, :permission, :expireType, :expireTime, :modificationTime, :appId, :isInBrowserElement" +
+ ")"
+ );
+
+ let id = 0;
+
+ function insertHost(
+ host,
+ type,
+ permission,
+ expireType,
+ expireTime,
+ modificationTime,
+ appId,
+ isInBrowserElement
+ ) {
+ let thisId = id++;
+
+ stmtInsert.bindByName("id", thisId);
+ stmtInsert.bindByName("host", host);
+ stmtInsert.bindByName("type", type);
+ stmtInsert.bindByName("permission", permission);
+ stmtInsert.bindByName("expireType", expireType);
+ stmtInsert.bindByName("expireTime", expireTime);
+ stmtInsert.bindByName("modificationTime", modificationTime);
+ stmtInsert.bindByName("appId", appId);
+ stmtInsert.bindByName("isInBrowserElement", isInBrowserElement);
+
+ try {
+ stmtInsert.execute();
+ } finally {
+ stmtInsert.reset();
+ }
+
+ return {
+ id: thisId,
+ host,
+ type,
+ permission,
+ expireType,
+ expireTime,
+ modificationTime,
+ appId,
+ isInBrowserElement,
+ };
+ }
+
+ // Add some rows to the database
+ // eslint-disable-next-line no-unused-vars
+ let created = [
+ insertHost("foo.com", "A", 1, 0, 0, 0, 0, false),
+ insertHost("foo.com", "C", 1, 0, 0, 0, 0, false),
+ insertHost("foo.com", "A", 1, 0, 0, 0, 1000, false),
+ insertHost("foo.com", "A", 1, 0, 0, 0, 2000, true),
+ insertHost("sub.foo.com", "B", 1, 0, 0, 0, 0, false),
+ insertHost("subber.sub.foo.com", "B", 1, 0, 0, 0, 0, false),
+ insertHost("bar.ca", "B", 1, 0, 0, 0, 0, false),
+ insertHost("bar.ca", "B", 1, 0, 0, 0, 1000, false),
+ insertHost("bar.ca", "A", 1, 0, 0, 0, 1000, true),
+ insertHost("localhost", "A", 1, 0, 0, 0, 0, false),
+ insertHost("127.0.0.1", "A", 1, 0, 0, 0, 0, false),
+ insertHost("192.0.2.235", "A", 1, 0, 0, 0, 0, false),
+ insertHost("file:///some/path/to/file.html", "A", 1, 0, 0, 0, 0, false),
+ insertHost("file:///another/file.html", "A", 1, 0, 0, 0, 0, false),
+ insertHost(
+ "moz-nullprincipal:{8695105a-adbe-4e4e-8083-851faa5ca2d7}",
+ "A",
+ 1,
+ 0,
+ 0,
+ 0,
+ 0,
+ false
+ ),
+ insertHost(
+ "moz-nullprincipal:{12ahjksd-akjs-asd3-8393-asdu2189asdu}",
+ "B",
+ 1,
+ 0,
+ 0,
+ 0,
+ 0,
+ false
+ ),
+ insertHost("<file>", "A", 1, 0, 0, 0, 0, false),
+ insertHost("<file>", "B", 1, 0, 0, 0, 0, false),
+ ];
+
+ // CLose the db connection
+ stmtInsert.finalize();
+ db.close();
+ stmtInsert = null;
+ db = null;
+
+ let expected = [
+ // The http:// entries under foo.com won't be inserted, as there are history entries for foo.com,
+ // and http://foo.com or a subdomain are never visited.
+ // ["http://foo.com", "A", 1, 0, 0],
+ // ["http://foo.com^inBrowser=1", "A", 1, 0, 0],
+ //
+ // Because we search for port/scheme combinations under eTLD+1, we should not have http:// entries
+ // for subdomains of foo.com either
+ // ["http://sub.foo.com", "B", 1, 0, 0],
+ // ["http://subber.sub.foo.com", "B", 1, 0, 0],
+
+ ["https://foo.com", "A", 1, 0, 0],
+ ["https://foo.com", "C", 1, 0, 0],
+ ["https://foo.com^inBrowser=1", "A", 1, 0, 0],
+ ["https://sub.foo.com", "B", 1, 0, 0],
+ ["https://subber.sub.foo.com", "B", 1, 0, 0],
+
+ // bar.ca will have both http:// and https:// for all entries, because there are no associated history entries
+ ["http://bar.ca", "B", 1, 0, 0],
+ ["https://bar.ca", "B", 1, 0, 0],
+ ["http://bar.ca^inBrowser=1", "A", 1, 0, 0],
+ ["https://bar.ca^inBrowser=1", "A", 1, 0, 0],
+ ["file:///some/path/to/file.html", "A", 1, 0, 0],
+ ["file:///another/file.html", "A", 1, 0, 0],
+
+ // Because we put ftp://some.subdomain.of.foo.com:8000/some/subdirectory in the history, we should
+ // also have these entries
+ ["ftp://foo.com:8000", "A", 1, 0, 0],
+ ["ftp://foo.com:8000", "C", 1, 0, 0],
+ ["ftp://foo.com:8000^inBrowser=1", "A", 1, 0, 0],
+
+ // In addition, because we search for port/scheme combinations under eTLD+1, we should have the
+ // following entries
+ ["ftp://sub.foo.com:8000", "B", 1, 0, 0],
+ ["ftp://subber.sub.foo.com:8000", "B", 1, 0, 0],
+
+ // Make sure that we also support localhost, and IP addresses
+ ["http://localhost", "A", 1, 0, 0],
+ ["https://localhost", "A", 1, 0, 0],
+ ["http://127.0.0.1", "A", 1, 0, 0],
+ ["https://127.0.0.1", "A", 1, 0, 0],
+ ["http://192.0.2.235", "A", 1, 0, 0],
+ ["https://192.0.2.235", "A", 1, 0, 0],
+ ];
+
+ let found = expected.map(it => 0);
+
+ // Add some places to the places database
+ await PlacesTestUtils.addVisits(
+ Services.io.newURI("https://foo.com/some/other/subdirectory")
+ );
+ await PlacesTestUtils.addVisits(
+ Services.io.newURI("ftp://some.subdomain.of.foo.com:8000/some/subdirectory")
+ );
+
+ // This will force the permission-manager to reload the data.
+ Services.obs.notifyObservers(null, "testonly-reload-permissions-from-disk");
+
+ // Force initialization of the PermissionManager
+ for (let permission of Services.perms.all) {
+ let isExpected = false;
+
+ expected.forEach((it, i) => {
+ if (
+ permission.principal.origin == it[0] &&
+ permission.type == it[1] &&
+ permission.capability == it[2] &&
+ permission.expireType == it[3] &&
+ permission.expireTime == it[4]
+ ) {
+ isExpected = true;
+ found[i]++;
+ }
+ });
+
+ Assert.ok(
+ isExpected,
+ "Permission " +
+ (isExpected ? "should" : "shouldn't") +
+ " be in permission database: " +
+ permission.principal.origin +
+ ", " +
+ permission.type +
+ ", " +
+ permission.capability +
+ ", " +
+ permission.expireType +
+ ", " +
+ permission.expireTime
+ );
+ }
+
+ found.forEach((count, i) => {
+ Assert.ok(
+ count == 1,
+ "Expected count = 1, got count = " +
+ count +
+ " for permission " +
+ expected[i]
+ );
+ });
+
+ // Check to make sure that all of the tables which we care about are present
+ {
+ db = Services.storage.openDatabase(GetPermissionsFile(profile));
+ Assert.ok(db.tableExists("moz_perms"));
+ Assert.ok(db.tableExists("moz_hosts"));
+ Assert.ok(!db.tableExists("moz_hosts_is_backup"));
+ Assert.ok(!db.tableExists("moz_perms_v6"));
+
+ // The moz_hosts table should still exist but be empty
+ let mozHostsCount = db.createStatement("SELECT count(*) FROM moz_hosts");
+ try {
+ mozHostsCount.executeStep();
+ Assert.equal(mozHostsCount.getInt64(0), 0);
+ } finally {
+ mozHostsCount.finalize();
+ }
+
+ db.close();
+ }
+});
diff --git a/extensions/permissions/test/unit/test_permmanager_migrate_4-7_no_history.js b/extensions/permissions/test/unit/test_permmanager_migrate_4-7_no_history.js
new file mode 100644
index 0000000000..aa735e534a
--- /dev/null
+++ b/extensions/permissions/test/unit/test_permmanager_migrate_4-7_no_history.js
@@ -0,0 +1,279 @@
+/* Any copyright is dedicated to the Public Domain.
+ http://creativecommons.org/publicdomain/zero/1.0/ */
+
+var PERMISSIONS_FILE_NAME = "permissions.sqlite";
+
+/*
+ * Prevent the nsINavHistoryService from being avaliable for the migration
+ */
+
+var CONTRACT_ID = "@mozilla.org/browser/nav-history-service;1";
+var factory = {
+ createInstance() {
+ throw new Error("There is no history service");
+ },
+ QueryInterface: ChromeUtils.generateQI(["nsIFactory"]),
+};
+
+var newClassID = Services.uuid.generateUUID();
+
+var registrar = Components.manager.QueryInterface(Ci.nsIComponentRegistrar);
+var oldClassID = registrar.contractIDToCID(CONTRACT_ID);
+// TODO: There was a var oldFactory = here causing linter errors as it
+// was unused. We should check if this function call is needed at all.
+Components.manager.getClassObject(Cc[CONTRACT_ID], Ci.nsIFactory);
+registrar.registerFactory(newClassID, "", CONTRACT_ID, factory);
+
+function cleanupFactory() {
+ registrar.unregisterFactory(newClassID, factory);
+ registrar.registerFactory(oldClassID, "", CONTRACT_ID, null);
+}
+
+function GetPermissionsFile(profile) {
+ let file = profile.clone();
+ file.append(PERMISSIONS_FILE_NAME);
+ return file;
+}
+
+/*
+ * Done nsINavHistoryService code
+ */
+
+add_task(function test() {
+ // Create and set up the permissions database.
+ Services.prefs.setCharPref("permissions.manager.defaultsUrl", "");
+ let profile = do_get_profile();
+
+ // Make sure that we can't resolve the nsINavHistoryService
+ try {
+ Cc["@mozilla.org/browser/nav-history-service;1"].getService(
+ Ci.nsINavHistoryService
+ );
+ Assert.ok(false, "There shouldn't have been a nsINavHistoryService");
+ } catch (e) {
+ Assert.ok(true, "There wasn't a nsINavHistoryService");
+ }
+
+ // We need to execute a pm method to be sure that the DB is fully
+ // initialized.
+ var pm = Services.perms;
+ Assert.ok(pm.all.length >= 0, "Permission manager not initialized?");
+
+ let db = Services.storage.openDatabase(GetPermissionsFile(profile));
+ db.schemaVersion = 4;
+ db.executeSimpleSQL("DROP TABLE moz_perms");
+ db.executeSimpleSQL("DROP TABLE moz_hosts");
+
+ db.executeSimpleSQL(
+ "CREATE TABLE moz_hosts (" +
+ " id INTEGER PRIMARY KEY" +
+ ",host TEXT" +
+ ",type TEXT" +
+ ",permission INTEGER" +
+ ",expireType INTEGER" +
+ ",expireTime INTEGER" +
+ ",modificationTime INTEGER" +
+ ",appId INTEGER" +
+ ",isInBrowserElement INTEGER" +
+ ")"
+ );
+
+ let stmtInsert = db.createStatement(
+ "INSERT INTO moz_hosts (" +
+ "id, host, type, permission, expireType, expireTime, modificationTime, appId, isInBrowserElement" +
+ ") VALUES (" +
+ ":id, :host, :type, :permission, :expireType, :expireTime, :modificationTime, :appId, :isInBrowserElement" +
+ ")"
+ );
+
+ let id = 0;
+
+ function insertHost(
+ host,
+ type,
+ permission,
+ expireType,
+ expireTime,
+ modificationTime,
+ appId,
+ isInBrowserElement
+ ) {
+ let thisId = id++;
+
+ stmtInsert.bindByName("id", thisId);
+ stmtInsert.bindByName("host", host);
+ stmtInsert.bindByName("type", type);
+ stmtInsert.bindByName("permission", permission);
+ stmtInsert.bindByName("expireType", expireType);
+ stmtInsert.bindByName("expireTime", expireTime);
+ stmtInsert.bindByName("modificationTime", modificationTime);
+ stmtInsert.bindByName("appId", appId);
+ stmtInsert.bindByName("isInBrowserElement", isInBrowserElement);
+
+ try {
+ stmtInsert.execute();
+ } finally {
+ stmtInsert.reset();
+ }
+
+ return {
+ id: thisId,
+ host,
+ type,
+ permission,
+ expireType,
+ expireTime,
+ modificationTime,
+ appId,
+ isInBrowserElement,
+ };
+ }
+
+ // Add some rows to the database
+ // eslint-disable-next-line no-unused-vars
+ let created = [
+ insertHost("foo.com", "A", 1, 0, 0, 0, 0, false),
+ insertHost("foo.com", "C", 1, 0, 0, 0, 0, false),
+ insertHost("foo.com", "A", 1, 0, 0, 0, 1000, false),
+ insertHost("foo.com", "A", 1, 0, 0, 0, 2000, true),
+ insertHost("sub.foo.com", "B", 1, 0, 0, 0, 0, false),
+ insertHost("subber.sub.foo.com", "B", 1, 0, 0, 0, 0, false),
+ insertHost("bar.ca", "B", 1, 0, 0, 0, 0, false),
+ insertHost("bar.ca", "B", 1, 0, 0, 0, 1000, false),
+ insertHost("bar.ca", "A", 1, 0, 0, 0, 1000, true),
+ insertHost("localhost", "A", 1, 0, 0, 0, 0, false),
+ insertHost("127.0.0.1", "A", 1, 0, 0, 0, 0, false),
+ insertHost("263.123.555.676", "A", 1, 0, 0, 0, 0, false),
+ insertHost("file:///some/path/to/file.html", "A", 1, 0, 0, 0, 0, false),
+ insertHost("file:///another/file.html", "A", 1, 0, 0, 0, 0, false),
+ insertHost(
+ "moz-nullprincipal:{8695105a-adbe-4e4e-8083-851faa5ca2d7}",
+ "A",
+ 1,
+ 0,
+ 0,
+ 0,
+ 0,
+ false
+ ),
+ insertHost(
+ "moz-nullprincipal:{12ahjksd-akjs-asd3-8393-asdu2189asdu}",
+ "B",
+ 1,
+ 0,
+ 0,
+ 0,
+ 0,
+ false
+ ),
+ insertHost("<file>", "A", 1, 0, 0, 0, 0, false),
+ insertHost("<file>", "B", 1, 0, 0, 0, 0, false),
+ ];
+
+ // CLose the db connection
+ stmtInsert.finalize();
+ db.close();
+ stmtInsert = null;
+ db = null;
+
+ let expected = [
+ ["http://foo.com", "A", 1, 0, 0],
+ ["http://foo.com", "C", 1, 0, 0],
+ ["http://foo.com^inBrowser=1", "A", 1, 0, 0],
+ ["http://sub.foo.com", "B", 1, 0, 0],
+ ["http://subber.sub.foo.com", "B", 1, 0, 0],
+
+ ["https://foo.com", "A", 1, 0, 0],
+ ["https://foo.com", "C", 1, 0, 0],
+ ["https://foo.com^inBrowser=1", "A", 1, 0, 0],
+ ["https://sub.foo.com", "B", 1, 0, 0],
+ ["https://subber.sub.foo.com", "B", 1, 0, 0],
+
+ // bar.ca will have both http:// and https:// for all entries, because there are no associated history entries
+ ["http://bar.ca", "B", 1, 0, 0],
+ ["https://bar.ca", "B", 1, 0, 0],
+ ["http://bar.ca^inBrowser=1", "A", 1, 0, 0],
+ ["https://bar.ca^inBrowser=1", "A", 1, 0, 0],
+ ["file:///some/path/to/file.html", "A", 1, 0, 0],
+ ["file:///another/file.html", "A", 1, 0, 0],
+
+ // Make sure that we also support localhost, and IP addresses
+ ["http://localhost", "A", 1, 0, 0],
+ ["https://localhost", "A", 1, 0, 0],
+ ["http://127.0.0.1", "A", 1, 0, 0],
+ ["https://127.0.0.1", "A", 1, 0, 0],
+ ["http://263.123.555.676", "A", 1, 0, 0],
+ ["https://263.123.555.676", "A", 1, 0, 0],
+ ];
+
+ let found = expected.map(it => 0);
+
+ // This will force the permission-manager to reload the data.
+ Services.obs.notifyObservers(null, "testonly-reload-permissions-from-disk");
+
+ // Force initialization of the PermissionManager
+ for (let permission of Services.perms.all) {
+ let isExpected = false;
+
+ expected.forEach((it, i) => {
+ if (
+ permission.principal.origin == it[0] &&
+ permission.type == it[1] &&
+ permission.capability == it[2] &&
+ permission.expireType == it[3] &&
+ permission.expireTime == it[4]
+ ) {
+ isExpected = true;
+ found[i]++;
+ }
+ });
+
+ Assert.ok(
+ isExpected,
+ "Permission " +
+ (isExpected ? "should" : "shouldn't") +
+ " be in permission database: " +
+ permission.principal.origin +
+ ", " +
+ permission.type +
+ ", " +
+ permission.capability +
+ ", " +
+ permission.expireType +
+ ", " +
+ permission.expireTime
+ );
+ }
+
+ found.forEach((count, i) => {
+ Assert.ok(
+ count == 1,
+ "Expected count = 1, got count = " +
+ count +
+ " for permission " +
+ expected[i]
+ );
+ });
+
+ // Check to make sure that all of the tables which we care about are present
+ {
+ db = Services.storage.openDatabase(GetPermissionsFile(profile));
+ Assert.ok(db.tableExists("moz_perms"));
+ Assert.ok(db.tableExists("moz_hosts"));
+ Assert.ok(!db.tableExists("moz_hosts_is_backup"));
+ Assert.ok(!db.tableExists("moz_perms_v6"));
+
+ // The moz_hosts table should still exist but be empty
+ let mozHostsCount = db.createStatement("SELECT count(*) FROM moz_hosts");
+ try {
+ mozHostsCount.executeStep();
+ Assert.equal(mozHostsCount.getInt64(0), 0);
+ } finally {
+ mozHostsCount.finalize();
+ }
+
+ db.close();
+ }
+
+ cleanupFactory();
+});
diff --git a/extensions/permissions/test/unit/test_permmanager_migrate_5-7a.js b/extensions/permissions/test/unit/test_permmanager_migrate_5-7a.js
new file mode 100644
index 0000000000..8ea03d5e16
--- /dev/null
+++ b/extensions/permissions/test/unit/test_permmanager_migrate_5-7a.js
@@ -0,0 +1,365 @@
+/* Any copyright is dedicated to the Public Domain.
+ http://creativecommons.org/publicdomain/zero/1.0/ */
+
+ChromeUtils.defineESModuleGetters(this, {
+ PlacesTestUtils: "resource://testing-common/PlacesTestUtils.sys.mjs",
+});
+
+var PERMISSIONS_FILE_NAME = "permissions.sqlite";
+
+function GetPermissionsFile(profile) {
+ let file = profile.clone();
+ file.append(PERMISSIONS_FILE_NAME);
+ return file;
+}
+
+add_task(async function test() {
+ // Create and set up the permissions database.
+ Services.prefs.setCharPref("permissions.manager.defaultsUrl", "");
+ let profile = do_get_profile();
+
+ // We need to execute a pm method to be sure that the DB is fully
+ // initialized.
+ var pm = Services.perms;
+ Assert.equal(pm.all.length, 0, "No cookies");
+
+ let db = Services.storage.openDatabase(GetPermissionsFile(profile));
+ db.schemaVersion = 5;
+ db.executeSimpleSQL("DROP TABLE moz_perms");
+ db.executeSimpleSQL("DROP TABLE moz_hosts");
+
+ /*
+ * V5 table
+ */
+ db.executeSimpleSQL(
+ "CREATE TABLE moz_hosts (" +
+ " id INTEGER PRIMARY KEY" +
+ ",origin TEXT" +
+ ",type TEXT" +
+ ",permission INTEGER" +
+ ",expireType INTEGER" +
+ ",expireTime INTEGER" +
+ ",modificationTime INTEGER" +
+ ")"
+ );
+
+ let stmt5Insert = db.createStatement(
+ "INSERT INTO moz_hosts (" +
+ "id, origin, type, permission, expireType, expireTime, modificationTime" +
+ ") VALUES (" +
+ ":id, :origin, :type, :permission, :expireType, :expireTime, :modificationTime" +
+ ")"
+ );
+
+ /*
+ * V4 table
+ */
+ db.executeSimpleSQL(
+ "CREATE TABLE moz_hosts_v4 (" +
+ " id INTEGER PRIMARY KEY" +
+ ",host TEXT" +
+ ",type TEXT" +
+ ",permission INTEGER" +
+ ",expireType INTEGER" +
+ ",expireTime INTEGER" +
+ ",modificationTime INTEGER" +
+ ",appId INTEGER" +
+ ",isInBrowserElement INTEGER" +
+ ")"
+ );
+
+ let stmtInsert = db.createStatement(
+ "INSERT INTO moz_hosts_v4 (" +
+ "id, host, type, permission, expireType, expireTime, modificationTime, appId, isInBrowserElement" +
+ ") VALUES (" +
+ ":id, :host, :type, :permission, :expireType, :expireTime, :modificationTime, :appId, :isInBrowserElement" +
+ ")"
+ );
+
+ let id = 0;
+
+ function insertOrigin(
+ origin,
+ type,
+ permission,
+ expireType,
+ expireTime,
+ modificationTime
+ ) {
+ let thisId = id++;
+
+ stmt5Insert.bindByName("id", thisId);
+ stmt5Insert.bindByName("origin", origin);
+ stmt5Insert.bindByName("type", type);
+ stmt5Insert.bindByName("permission", permission);
+ stmt5Insert.bindByName("expireType", expireType);
+ stmt5Insert.bindByName("expireTime", expireTime);
+ stmt5Insert.bindByName("modificationTime", modificationTime);
+
+ try {
+ stmt5Insert.execute();
+ } finally {
+ stmt5Insert.reset();
+ }
+
+ return {
+ id: thisId,
+ origin,
+ type,
+ permission,
+ expireType,
+ expireTime,
+ modificationTime,
+ };
+ }
+ function insertHost(
+ host,
+ type,
+ permission,
+ expireType,
+ expireTime,
+ modificationTime,
+ appId,
+ isInBrowserElement
+ ) {
+ let thisId = id++;
+
+ stmtInsert.bindByName("id", thisId);
+ stmtInsert.bindByName("host", host);
+ stmtInsert.bindByName("type", type);
+ stmtInsert.bindByName("permission", permission);
+ stmtInsert.bindByName("expireType", expireType);
+ stmtInsert.bindByName("expireTime", expireTime);
+ stmtInsert.bindByName("modificationTime", modificationTime);
+ stmtInsert.bindByName("appId", appId);
+ stmtInsert.bindByName("isInBrowserElement", isInBrowserElement);
+
+ try {
+ stmtInsert.execute();
+ } finally {
+ stmtInsert.reset();
+ }
+
+ return {
+ id: thisId,
+ host,
+ type,
+ permission,
+ expireType,
+ expireTime,
+ modificationTime,
+ appId,
+ isInBrowserElement,
+ };
+ }
+
+ let created5 = [
+ insertOrigin("https://foo.com", "A", 2, 0, 0, 0),
+ insertOrigin("http://foo.com", "A", 2, 0, 0, 0),
+ insertOrigin("http://foo.com^inBrowser=1", "A", 2, 0, 0, 0),
+ ];
+
+ // Add some rows to the database
+ // eslint-disable-next-line no-unused-vars
+ let created = [
+ insertHost("foo.com", "A", 1, 0, 0, 0, 0, false),
+ insertHost("foo.com", "C", 1, 0, 0, 0, 0, false),
+ insertHost("foo.com", "A", 1, 0, 0, 0, 1000, false),
+ insertHost("foo.com", "A", 1, 0, 0, 0, 2000, true),
+ insertHost("sub.foo.com", "B", 1, 0, 0, 0, 0, false),
+ insertHost("subber.sub.foo.com", "B", 1, 0, 0, 0, 0, false),
+ insertHost("bar.ca", "B", 1, 0, 0, 0, 0, false),
+ insertHost("bar.ca", "B", 1, 0, 0, 0, 1000, false),
+ insertHost("bar.ca", "A", 1, 0, 0, 0, 1000, true),
+ insertHost("localhost", "A", 1, 0, 0, 0, 0, false),
+ insertHost("127.0.0.1", "A", 1, 0, 0, 0, 0, false),
+ insertHost("192.0.2.235", "A", 1, 0, 0, 0, 0, false),
+ insertHost("file:///some/path/to/file.html", "A", 1, 0, 0, 0, 0, false),
+ insertHost("file:///another/file.html", "A", 1, 0, 0, 0, 0, false),
+ insertHost(
+ "moz-nullprincipal:{8695105a-adbe-4e4e-8083-851faa5ca2d7}",
+ "A",
+ 1,
+ 0,
+ 0,
+ 0,
+ 0,
+ false
+ ),
+ insertHost(
+ "moz-nullprincipal:{12ahjksd-akjs-asd3-8393-asdu2189asdu}",
+ "B",
+ 1,
+ 0,
+ 0,
+ 0,
+ 0,
+ false
+ ),
+ insertHost("<file>", "A", 1, 0, 0, 0, 0, false),
+ insertHost("<file>", "B", 1, 0, 0, 0, 0, false),
+ ];
+
+ // CLose the db connection
+ stmt5Insert.finalize();
+ stmtInsert.finalize();
+ db.close();
+ stmtInsert = null;
+ db = null;
+
+ let expected = [
+ // The http:// entries under foo.com won't be inserted, as there are history entries for foo.com,
+ // and http://foo.com or a subdomain are never visited.
+ // ["http://foo.com", "A", 1, 0, 0],
+ // ["http://foo.com^inBrowser=1", "A", 1, 0, 0],
+ //
+ // Because we search for port/scheme combinations under eTLD+1, we should not have http:// entries
+ // for subdomains of foo.com either
+ // ["http://sub.foo.com", "B", 1, 0, 0],
+ // ["http://subber.sub.foo.com", "B", 1, 0, 0],
+
+ ["https://foo.com", "A", 1, 0, 0],
+ ["https://foo.com", "C", 1, 0, 0],
+ ["https://foo.com^inBrowser=1", "A", 1, 0, 0],
+ ["https://sub.foo.com", "B", 1, 0, 0],
+ ["https://subber.sub.foo.com", "B", 1, 0, 0],
+
+ // bar.ca will have both http:// and https:// for all entries, because there are no associated history entries
+ ["http://bar.ca", "B", 1, 0, 0],
+ ["https://bar.ca", "B", 1, 0, 0],
+ ["http://bar.ca^inBrowser=1", "A", 1, 0, 0],
+ ["https://bar.ca^inBrowser=1", "A", 1, 0, 0],
+ ["file:///some/path/to/file.html", "A", 1, 0, 0],
+ ["file:///another/file.html", "A", 1, 0, 0],
+
+ // Because we put ftp://some.subdomain.of.foo.com:8000/some/subdirectory in the history, we should
+ // also have these entries
+ ["ftp://foo.com:8000", "A", 1, 0, 0],
+ ["ftp://foo.com:8000", "C", 1, 0, 0],
+ ["ftp://foo.com:8000^inBrowser=1", "A", 1, 0, 0],
+
+ // In addition, because we search for port/scheme combinations under eTLD+1, we should have the
+ // following entries
+ ["ftp://sub.foo.com:8000", "B", 1, 0, 0],
+ ["ftp://subber.sub.foo.com:8000", "B", 1, 0, 0],
+
+ // Make sure that we also support localhost, and IP addresses
+ ["http://localhost", "A", 1, 0, 0],
+ ["https://localhost", "A", 1, 0, 0],
+ ["http://127.0.0.1", "A", 1, 0, 0],
+ ["https://127.0.0.1", "A", 1, 0, 0],
+ ["http://192.0.2.235", "A", 1, 0, 0],
+ ["https://192.0.2.235", "A", 1, 0, 0],
+ ];
+
+ let found = expected.map(it => 0);
+
+ // Add some places to the places database
+ await PlacesTestUtils.addVisits(
+ Services.io.newURI("https://foo.com/some/other/subdirectory")
+ );
+ await PlacesTestUtils.addVisits(
+ Services.io.newURI("ftp://some.subdomain.of.foo.com:8000/some/subdirectory")
+ );
+
+ // This will force the permission-manager to reload the data.
+ Services.obs.notifyObservers(null, "testonly-reload-permissions-from-disk");
+
+ // Force initialization of the PermissionManager
+ for (let permission of Services.perms.all) {
+ let isExpected = false;
+
+ expected.forEach((it, i) => {
+ if (
+ permission.principal.origin == it[0] &&
+ permission.type == it[1] &&
+ permission.capability == it[2] &&
+ permission.expireType == it[3] &&
+ permission.expireTime == it[4]
+ ) {
+ isExpected = true;
+ found[i]++;
+ }
+ });
+
+ Assert.ok(
+ isExpected,
+ "Permission " +
+ (isExpected ? "should" : "shouldn't") +
+ " be in permission database: " +
+ permission.principal.origin +
+ ", " +
+ permission.type +
+ ", " +
+ permission.capability +
+ ", " +
+ permission.expireType +
+ ", " +
+ permission.expireTime
+ );
+ }
+
+ found.forEach((count, i) => {
+ Assert.ok(
+ count == 1,
+ "Expected count = 1, got count = " +
+ count +
+ " for permission " +
+ expected[i]
+ );
+ });
+
+ // Check to make sure that all of the tables which we care about are present
+ {
+ db = Services.storage.openDatabase(GetPermissionsFile(profile));
+ Assert.ok(db.tableExists("moz_perms"));
+ Assert.ok(db.tableExists("moz_hosts"));
+ Assert.ok(!db.tableExists("moz_hosts_is_backup"));
+ Assert.ok(db.tableExists("moz_perms_v6"));
+
+ // The moz_hosts table should still exist but be empty
+ let mozHostsCount = db.createStatement("SELECT count(*) FROM moz_hosts");
+ try {
+ mozHostsCount.executeStep();
+ Assert.equal(mozHostsCount.getInt64(0), 0);
+ } finally {
+ mozHostsCount.finalize();
+ }
+
+ // Check that the moz_perms_v6 table contains the backup of the entry we created
+ let mozPermsV6Stmt = db.createStatement(
+ "SELECT " +
+ "origin, type, permission, expireType, expireTime, modificationTime " +
+ "FROM moz_perms_v6 WHERE id = :id"
+ );
+ try {
+ // Check that the moz_hosts table still contains the correct values.
+ created5.forEach(it => {
+ mozPermsV6Stmt.reset();
+ mozPermsV6Stmt.bindByName("id", it.id);
+ mozPermsV6Stmt.executeStep();
+ Assert.equal(mozPermsV6Stmt.getUTF8String(0), it.origin);
+ Assert.equal(mozPermsV6Stmt.getUTF8String(1), it.type);
+ Assert.equal(mozPermsV6Stmt.getInt64(2), it.permission);
+ Assert.equal(mozPermsV6Stmt.getInt64(3), it.expireType);
+ Assert.equal(mozPermsV6Stmt.getInt64(4), it.expireTime);
+ Assert.equal(mozPermsV6Stmt.getInt64(5), it.modificationTime);
+ });
+ } finally {
+ mozPermsV6Stmt.finalize();
+ }
+
+ // Check that there are the right number of values
+ let mozPermsV6Count = db.createStatement(
+ "SELECT count(*) FROM moz_perms_v6"
+ );
+ try {
+ mozPermsV6Count.executeStep();
+ Assert.equal(mozPermsV6Count.getInt64(0), created5.length);
+ } finally {
+ mozPermsV6Count.finalize();
+ }
+
+ db.close();
+ }
+});
diff --git a/extensions/permissions/test/unit/test_permmanager_migrate_5-7b.js b/extensions/permissions/test/unit/test_permmanager_migrate_5-7b.js
new file mode 100644
index 0000000000..8c330effa9
--- /dev/null
+++ b/extensions/permissions/test/unit/test_permmanager_migrate_5-7b.js
@@ -0,0 +1,203 @@
+/* Any copyright is dedicated to the Public Domain.
+ http://creativecommons.org/publicdomain/zero/1.0/ */
+
+var PERMISSIONS_FILE_NAME = "permissions.sqlite";
+
+function GetPermissionsFile(profile) {
+ let file = profile.clone();
+ file.append(PERMISSIONS_FILE_NAME);
+ return file;
+}
+
+add_task(function test() {
+ // Create and set up the permissions database.
+ Services.prefs.setCharPref("permissions.manager.defaultsUrl", "");
+ let profile = do_get_profile();
+
+ var pm = Services.perms;
+ Assert.equal(pm.all.length, 0, "No cookies");
+
+ let db = Services.storage.openDatabase(GetPermissionsFile(profile));
+ db.schemaVersion = 5;
+ db.executeSimpleSQL("DROP TABLE moz_perms");
+ db.executeSimpleSQL("DROP TABLE moz_hosts");
+
+ /*
+ * V5 table
+ */
+ db.executeSimpleSQL(
+ "CREATE TABLE moz_hosts (" +
+ " id INTEGER PRIMARY KEY" +
+ ",origin TEXT" +
+ ",type TEXT" +
+ ",permission INTEGER" +
+ ",expireType INTEGER" +
+ ",expireTime INTEGER" +
+ ",modificationTime INTEGER" +
+ ")"
+ );
+
+ let stmt5Insert = db.createStatement(
+ "INSERT INTO moz_hosts (" +
+ "id, origin, type, permission, expireType, expireTime, modificationTime" +
+ ") VALUES (" +
+ ":id, :origin, :type, :permission, :expireType, :expireTime, :modificationTime" +
+ ")"
+ );
+
+ let id = 0;
+ function insertOrigin(
+ origin,
+ type,
+ permission,
+ expireType,
+ expireTime,
+ modificationTime
+ ) {
+ let thisId = id++;
+
+ stmt5Insert.bindByName("id", thisId);
+ stmt5Insert.bindByName("origin", origin);
+ stmt5Insert.bindByName("type", type);
+ stmt5Insert.bindByName("permission", permission);
+ stmt5Insert.bindByName("expireType", expireType);
+ stmt5Insert.bindByName("expireTime", expireTime);
+ stmt5Insert.bindByName("modificationTime", modificationTime);
+
+ try {
+ stmt5Insert.execute();
+ } finally {
+ stmt5Insert.reset();
+ }
+
+ return {
+ id: thisId,
+ host: origin,
+ type,
+ permission,
+ expireType,
+ expireTime,
+ modificationTime,
+ };
+ }
+
+ // eslint-disable-next-line no-unused-vars
+ let created5 = [
+ insertOrigin("https://foo.com", "A", 2, 0, 0, 0),
+ insertOrigin("http://foo.com", "A", 2, 0, 0, 0),
+ insertOrigin("http://foo.com^appId=1000&inBrowser=1", "A", 2, 0, 0, 0),
+
+ insertOrigin("http://127.0.0.1", "B", 2, 0, 0, 0),
+ insertOrigin("http://localhost", "B", 2, 0, 0, 0),
+ ];
+
+ let created4 = []; // Didn't create any v4 entries, so the DB should be empty
+
+ // CLose the db connection
+ stmt5Insert.finalize();
+ db.close();
+ stmt5Insert = null;
+ db = null;
+
+ let expected = [
+ ["https://foo.com", "A", 2, 0, 0, 0],
+ ["http://foo.com", "A", 2, 0, 0, 0],
+ ["http://foo.com^inBrowser=1", "A", 2, 0, 0, 0],
+
+ ["http://127.0.0.1", "B", 2, 0, 0, 0],
+ ["http://localhost", "B", 2, 0, 0, 0],
+ ];
+
+ let found = expected.map(it => 0);
+
+ // This will force the permission-manager to reload the data.
+ Services.obs.notifyObservers(null, "testonly-reload-permissions-from-disk");
+
+ // Force initialization of the PermissionManager
+ for (let permission of Services.perms.all) {
+ let isExpected = false;
+
+ expected.forEach((it, i) => {
+ if (
+ permission.principal.origin == it[0] &&
+ permission.type == it[1] &&
+ permission.capability == it[2] &&
+ permission.expireType == it[3] &&
+ permission.expireTime == it[4]
+ ) {
+ isExpected = true;
+ found[i]++;
+ }
+ });
+
+ Assert.ok(
+ isExpected,
+ "Permission " +
+ (isExpected ? "should" : "shouldn't") +
+ " be in permission database: " +
+ permission.principal.origin +
+ ", " +
+ permission.type +
+ ", " +
+ permission.capability +
+ ", " +
+ permission.expireType +
+ ", " +
+ permission.expireTime
+ );
+ }
+
+ found.forEach((count, i) => {
+ Assert.ok(
+ count == 1,
+ "Expected count = 1, got count = " +
+ count +
+ " for permission " +
+ expected[i]
+ );
+ });
+
+ // Check to make sure that all of the tables which we care about are present
+ {
+ db = Services.storage.openDatabase(GetPermissionsFile(profile));
+ Assert.ok(db.tableExists("moz_perms"));
+ Assert.ok(db.tableExists("moz_hosts"));
+ Assert.ok(!db.tableExists("moz_hosts_is_backup"));
+ Assert.ok(!db.tableExists("moz_perms_v6"));
+
+ let mozHostsStmt = db.createStatement(
+ "SELECT " +
+ "host, type, permission, expireType, expireTime, " +
+ "modificationTime, isInBrowserElement " +
+ "FROM moz_hosts WHERE id = :id"
+ );
+ try {
+ // Check that the moz_hosts table still contains the correct values.
+ created4.forEach(it => {
+ mozHostsStmt.reset();
+ mozHostsStmt.bindByName("id", it.id);
+ mozHostsStmt.executeStep();
+ Assert.equal(mozHostsStmt.getUTF8String(0), it.host);
+ Assert.equal(mozHostsStmt.getUTF8String(1), it.type);
+ Assert.equal(mozHostsStmt.getInt64(2), it.permission);
+ Assert.equal(mozHostsStmt.getInt64(3), it.expireType);
+ Assert.equal(mozHostsStmt.getInt64(4), it.expireTime);
+ Assert.equal(mozHostsStmt.getInt64(5), it.modificationTime);
+ Assert.equal(mozHostsStmt.getInt64(6), it.isInBrowserElement);
+ });
+ } finally {
+ mozHostsStmt.finalize();
+ }
+
+ // Check that there are the right number of values
+ let mozHostsCount = db.createStatement("SELECT count(*) FROM moz_hosts");
+ try {
+ mozHostsCount.executeStep();
+ Assert.equal(mozHostsCount.getInt64(0), created4.length);
+ } finally {
+ mozHostsCount.finalize();
+ }
+
+ db.close();
+ }
+});
diff --git a/extensions/permissions/test/unit/test_permmanager_migrate_6-7a.js b/extensions/permissions/test/unit/test_permmanager_migrate_6-7a.js
new file mode 100644
index 0000000000..93b78e6478
--- /dev/null
+++ b/extensions/permissions/test/unit/test_permmanager_migrate_6-7a.js
@@ -0,0 +1,366 @@
+/* Any copyright is dedicated to the Public Domain.
+ http://creativecommons.org/publicdomain/zero/1.0/ */
+
+ChromeUtils.defineESModuleGetters(this, {
+ PlacesTestUtils: "resource://testing-common/PlacesTestUtils.sys.mjs",
+});
+
+var PERMISSIONS_FILE_NAME = "permissions.sqlite";
+
+function GetPermissionsFile(profile) {
+ let file = profile.clone();
+ file.append(PERMISSIONS_FILE_NAME);
+ return file;
+}
+
+add_task(async function test() {
+ // Create and set up the permissions database.
+ Services.prefs.setCharPref("permissions.manager.defaultsUrl", "");
+ let profile = do_get_profile();
+
+ // We need to execute a pm method to be sure that the DB is fully
+ // initialized.
+ var pm = Services.perms;
+ Assert.equal(pm.all.length, 0, "No cookies");
+
+ let db = Services.storage.openDatabase(GetPermissionsFile(profile));
+ db.schemaVersion = 6;
+ db.executeSimpleSQL("DROP TABLE moz_perms");
+ db.executeSimpleSQL("DROP TABLE moz_hosts");
+
+ /*
+ * V5 table
+ */
+ db.executeSimpleSQL(
+ "CREATE TABLE moz_perms (" +
+ " id INTEGER PRIMARY KEY" +
+ ",origin TEXT" +
+ ",type TEXT" +
+ ",permission INTEGER" +
+ ",expireType INTEGER" +
+ ",expireTime INTEGER" +
+ ",modificationTime INTEGER" +
+ ")"
+ );
+
+ let stmt6Insert = db.createStatement(
+ "INSERT INTO moz_perms (" +
+ "id, origin, type, permission, expireType, expireTime, modificationTime" +
+ ") VALUES (" +
+ ":id, :origin, :type, :permission, :expireType, :expireTime, :modificationTime" +
+ ")"
+ );
+
+ /*
+ * V4 table
+ */
+ db.executeSimpleSQL(
+ "CREATE TABLE moz_hosts (" +
+ " id INTEGER PRIMARY KEY" +
+ ",host TEXT" +
+ ",type TEXT" +
+ ",permission INTEGER" +
+ ",expireType INTEGER" +
+ ",expireTime INTEGER" +
+ ",modificationTime INTEGER" +
+ ",appId INTEGER" +
+ ",isInBrowserElement INTEGER" +
+ ")"
+ );
+
+ let stmtInsert = db.createStatement(
+ "INSERT INTO moz_hosts (" +
+ "id, host, type, permission, expireType, expireTime, modificationTime, appId, isInBrowserElement" +
+ ") VALUES (" +
+ ":id, :host, :type, :permission, :expireType, :expireTime, :modificationTime, :appId, :isInBrowserElement" +
+ ")"
+ );
+
+ let id = 0;
+
+ function insertOrigin(
+ origin,
+ type,
+ permission,
+ expireType,
+ expireTime,
+ modificationTime
+ ) {
+ let thisId = id++;
+
+ stmt6Insert.bindByName("id", thisId);
+ stmt6Insert.bindByName("origin", origin);
+ stmt6Insert.bindByName("type", type);
+ stmt6Insert.bindByName("permission", permission);
+ stmt6Insert.bindByName("expireType", expireType);
+ stmt6Insert.bindByName("expireTime", expireTime);
+ stmt6Insert.bindByName("modificationTime", modificationTime);
+
+ try {
+ stmt6Insert.execute();
+ } finally {
+ stmt6Insert.reset();
+ }
+
+ return {
+ id: thisId,
+ origin,
+ type,
+ permission,
+ expireType,
+ expireTime,
+ modificationTime,
+ };
+ }
+
+ function insertHost(
+ host,
+ type,
+ permission,
+ expireType,
+ expireTime,
+ modificationTime,
+ appId,
+ isInBrowserElement
+ ) {
+ let thisId = id++;
+
+ stmtInsert.bindByName("id", thisId);
+ stmtInsert.bindByName("host", host);
+ stmtInsert.bindByName("type", type);
+ stmtInsert.bindByName("permission", permission);
+ stmtInsert.bindByName("expireType", expireType);
+ stmtInsert.bindByName("expireTime", expireTime);
+ stmtInsert.bindByName("modificationTime", modificationTime);
+ stmtInsert.bindByName("appId", appId);
+ stmtInsert.bindByName("isInBrowserElement", isInBrowserElement);
+
+ try {
+ stmtInsert.execute();
+ } finally {
+ stmtInsert.reset();
+ }
+
+ return {
+ id: thisId,
+ host,
+ type,
+ permission,
+ expireType,
+ expireTime,
+ modificationTime,
+ appId,
+ isInBrowserElement,
+ };
+ }
+
+ let created6 = [
+ insertOrigin("https://foo.com", "A", 2, 0, 0, 0),
+ insertOrigin("http://foo.com", "A", 2, 0, 0, 0),
+ insertOrigin("http://foo.com^inBrowser=1", "A", 2, 0, 0, 0),
+ ];
+
+ // Add some rows to the database
+ // eslint-disable-next-line no-unused-vars
+ let created = [
+ insertHost("foo.com", "A", 1, 0, 0, 0, 0, false),
+ insertHost("foo.com", "C", 1, 0, 0, 0, 0, false),
+ insertHost("foo.com", "A", 1, 0, 0, 0, 1000, false),
+ insertHost("foo.com", "A", 1, 0, 0, 0, 2000, true),
+ insertHost("sub.foo.com", "B", 1, 0, 0, 0, 0, false),
+ insertHost("subber.sub.foo.com", "B", 1, 0, 0, 0, 0, false),
+ insertHost("bar.ca", "B", 1, 0, 0, 0, 0, false),
+ insertHost("bar.ca", "B", 1, 0, 0, 0, 1000, false),
+ insertHost("bar.ca", "A", 1, 0, 0, 0, 1000, true),
+ insertHost("localhost", "A", 1, 0, 0, 0, 0, false),
+ insertHost("127.0.0.1", "A", 1, 0, 0, 0, 0, false),
+ insertHost("192.0.2.235", "A", 1, 0, 0, 0, 0, false),
+ insertHost("file:///some/path/to/file.html", "A", 1, 0, 0, 0, 0, false),
+ insertHost("file:///another/file.html", "A", 1, 0, 0, 0, 0, false),
+ insertHost(
+ "moz-nullprincipal:{8695105a-adbe-4e4e-8083-851faa5ca2d7}",
+ "A",
+ 1,
+ 0,
+ 0,
+ 0,
+ 0,
+ false
+ ),
+ insertHost(
+ "moz-nullprincipal:{12ahjksd-akjs-asd3-8393-asdu2189asdu}",
+ "B",
+ 1,
+ 0,
+ 0,
+ 0,
+ 0,
+ false
+ ),
+ insertHost("<file>", "A", 1, 0, 0, 0, 0, false),
+ insertHost("<file>", "B", 1, 0, 0, 0, 0, false),
+ ];
+
+ // CLose the db connection
+ stmt6Insert.finalize();
+ stmtInsert.finalize();
+ db.close();
+ stmtInsert = null;
+ db = null;
+
+ let expected = [
+ // The http:// entries under foo.com won't be inserted, as there are history entries for foo.com,
+ // and http://foo.com or a subdomain are never visited.
+ // ["http://foo.com", "A", 1, 0, 0],
+ // ["http://foo.com^inBrowser=1", "A", 1, 0, 0],
+ //
+ // Because we search for port/scheme combinations under eTLD+1, we should not have http:// entries
+ // for subdomains of foo.com either
+ // ["http://sub.foo.com", "B", 1, 0, 0],
+ // ["http://subber.sub.foo.com", "B", 1, 0, 0],
+
+ ["https://foo.com", "A", 1, 0, 0],
+ ["https://foo.com", "C", 1, 0, 0],
+ ["https://foo.com^inBrowser=1", "A", 1, 0, 0],
+ ["https://sub.foo.com", "B", 1, 0, 0],
+ ["https://subber.sub.foo.com", "B", 1, 0, 0],
+
+ // bar.ca will have both http:// and https:// for all entries, because there are no associated history entries
+ ["http://bar.ca", "B", 1, 0, 0],
+ ["https://bar.ca", "B", 1, 0, 0],
+ ["http://bar.ca^inBrowser=1", "A", 1, 0, 0],
+ ["https://bar.ca^inBrowser=1", "A", 1, 0, 0],
+ ["file:///some/path/to/file.html", "A", 1, 0, 0],
+ ["file:///another/file.html", "A", 1, 0, 0],
+
+ // Because we put ftp://some.subdomain.of.foo.com:8000/some/subdirectory in the history, we should
+ // also have these entries
+ ["ftp://foo.com:8000", "A", 1, 0, 0],
+ ["ftp://foo.com:8000", "C", 1, 0, 0],
+ ["ftp://foo.com:8000^inBrowser=1", "A", 1, 0, 0],
+
+ // In addition, because we search for port/scheme combinations under eTLD+1, we should have the
+ // following entries
+ ["ftp://sub.foo.com:8000", "B", 1, 0, 0],
+ ["ftp://subber.sub.foo.com:8000", "B", 1, 0, 0],
+
+ // Make sure that we also support localhost, and IP addresses
+ ["http://localhost", "A", 1, 0, 0],
+ ["https://localhost", "A", 1, 0, 0],
+ ["http://127.0.0.1", "A", 1, 0, 0],
+ ["https://127.0.0.1", "A", 1, 0, 0],
+ ["http://192.0.2.235", "A", 1, 0, 0],
+ ["https://192.0.2.235", "A", 1, 0, 0],
+ ];
+
+ let found = expected.map(it => 0);
+
+ // Add some places to the places database
+ await PlacesTestUtils.addVisits(
+ Services.io.newURI("https://foo.com/some/other/subdirectory")
+ );
+ await PlacesTestUtils.addVisits(
+ Services.io.newURI("ftp://some.subdomain.of.foo.com:8000/some/subdirectory")
+ );
+
+ // This will force the permission-manager to reload the data.
+ Services.obs.notifyObservers(null, "testonly-reload-permissions-from-disk");
+
+ // Force initialization of the PermissionManager
+ for (let permission of Services.perms.all) {
+ let isExpected = false;
+
+ expected.forEach((it, i) => {
+ if (
+ permission.principal.origin == it[0] &&
+ permission.type == it[1] &&
+ permission.capability == it[2] &&
+ permission.expireType == it[3] &&
+ permission.expireTime == it[4]
+ ) {
+ isExpected = true;
+ found[i]++;
+ }
+ });
+
+ Assert.ok(
+ isExpected,
+ "Permission " +
+ (isExpected ? "should" : "shouldn't") +
+ " be in permission database: " +
+ permission.principal.origin +
+ ", " +
+ permission.type +
+ ", " +
+ permission.capability +
+ ", " +
+ permission.expireType +
+ ", " +
+ permission.expireTime
+ );
+ }
+
+ found.forEach((count, i) => {
+ Assert.ok(
+ count == 1,
+ "Expected count = 1, got count = " +
+ count +
+ " for permission " +
+ expected[i]
+ );
+ });
+
+ // Check to make sure that all of the tables which we care about are present
+ {
+ db = Services.storage.openDatabase(GetPermissionsFile(profile));
+ Assert.ok(db.tableExists("moz_perms"));
+ Assert.ok(db.tableExists("moz_hosts"));
+ Assert.ok(!db.tableExists("moz_hosts_is_backup"));
+ Assert.ok(db.tableExists("moz_perms_v6"));
+
+ // The moz_hosts table should still exist but be empty
+ let mozHostsCount = db.createStatement("SELECT count(*) FROM moz_hosts");
+ try {
+ mozHostsCount.executeStep();
+ Assert.equal(mozHostsCount.getInt64(0), 0);
+ } finally {
+ mozHostsCount.finalize();
+ }
+
+ // Check that the moz_perms_v6 table contains the backup of the entry we created
+ let mozPermsV6Stmt = db.createStatement(
+ "SELECT " +
+ "origin, type, permission, expireType, expireTime, modificationTime " +
+ "FROM moz_perms_v6 WHERE id = :id"
+ );
+ try {
+ // Check that the moz_hosts table still contains the correct values.
+ created6.forEach(it => {
+ mozPermsV6Stmt.reset();
+ mozPermsV6Stmt.bindByName("id", it.id);
+ mozPermsV6Stmt.executeStep();
+ Assert.equal(mozPermsV6Stmt.getUTF8String(0), it.origin);
+ Assert.equal(mozPermsV6Stmt.getUTF8String(1), it.type);
+ Assert.equal(mozPermsV6Stmt.getInt64(2), it.permission);
+ Assert.equal(mozPermsV6Stmt.getInt64(3), it.expireType);
+ Assert.equal(mozPermsV6Stmt.getInt64(4), it.expireTime);
+ Assert.equal(mozPermsV6Stmt.getInt64(5), it.modificationTime);
+ });
+ } finally {
+ mozPermsV6Stmt.finalize();
+ }
+
+ // Check that there are the right number of values
+ let mozPermsV6Count = db.createStatement(
+ "SELECT count(*) FROM moz_perms_v6"
+ );
+ try {
+ mozPermsV6Count.executeStep();
+ Assert.equal(mozPermsV6Count.getInt64(0), created6.length);
+ } finally {
+ mozPermsV6Count.finalize();
+ }
+
+ db.close();
+ }
+});
diff --git a/extensions/permissions/test/unit/test_permmanager_migrate_6-7b.js b/extensions/permissions/test/unit/test_permmanager_migrate_6-7b.js
new file mode 100644
index 0000000000..feed156d29
--- /dev/null
+++ b/extensions/permissions/test/unit/test_permmanager_migrate_6-7b.js
@@ -0,0 +1,199 @@
+/* Any copyright is dedicated to the Public Domain.
+ http://creativecommons.org/publicdomain/zero/1.0/ */
+
+var PERMISSIONS_FILE_NAME = "permissions.sqlite";
+
+function GetPermissionsFile(profile) {
+ let file = profile.clone();
+ file.append(PERMISSIONS_FILE_NAME);
+ return file;
+}
+
+add_task(function test() {
+ // Create and set up the permissions database.
+ Services.prefs.setCharPref("permissions.manager.defaultsUrl", "");
+ let profile = do_get_profile();
+
+ // We need to execute a pm method to be sure that the DB is fully
+ // initialized.
+ var pm = Services.perms;
+ Assert.equal(pm.all.length, 0, "No cookies");
+
+ let db = Services.storage.openDatabase(GetPermissionsFile(profile));
+ db.schemaVersion = 6;
+ db.executeSimpleSQL("DROP TABLE moz_perms");
+ db.executeSimpleSQL("DROP TABLE moz_hosts");
+
+ /*
+ * V5 table
+ */
+ db.executeSimpleSQL(
+ "CREATE TABLE moz_perms (" +
+ " id INTEGER PRIMARY KEY" +
+ ",origin TEXT" +
+ ",type TEXT" +
+ ",permission INTEGER" +
+ ",expireType INTEGER" +
+ ",expireTime INTEGER" +
+ ",modificationTime INTEGER" +
+ ")"
+ );
+
+ let stmt6Insert = db.createStatement(
+ "INSERT INTO moz_perms (" +
+ "id, origin, type, permission, expireType, expireTime, modificationTime" +
+ ") VALUES (" +
+ ":id, :origin, :type, :permission, :expireType, :expireTime, :modificationTime" +
+ ")"
+ );
+
+ let id = 0;
+ function insertOrigin(
+ origin,
+ type,
+ permission,
+ expireType,
+ expireTime,
+ modificationTime
+ ) {
+ let thisId = id++;
+
+ stmt6Insert.bindByName("id", thisId);
+ stmt6Insert.bindByName("origin", origin);
+ stmt6Insert.bindByName("type", type);
+ stmt6Insert.bindByName("permission", permission);
+ stmt6Insert.bindByName("expireType", expireType);
+ stmt6Insert.bindByName("expireTime", expireTime);
+ stmt6Insert.bindByName("modificationTime", modificationTime);
+
+ try {
+ stmt6Insert.execute();
+ } finally {
+ stmt6Insert.reset();
+ }
+
+ return {
+ id: thisId,
+ host: origin,
+ type,
+ permission,
+ expireType,
+ expireTime,
+ modificationTime,
+ };
+ }
+
+ // eslint-disable-next-line no-unused-vars
+ let created6 = [
+ insertOrigin("https://foo.com", "A", 2, 0, 0, 0),
+ insertOrigin("http://foo.com", "A", 2, 0, 0, 0),
+ insertOrigin("http://foo.com^appId=1000&inBrowser=1", "A", 2, 0, 0, 0),
+ ];
+
+ let created4 = []; // Didn't create any v4 entries, so the DB should be empty
+
+ // CLose the db connection
+ stmt6Insert.finalize();
+ db.close();
+ stmt6Insert = null;
+ db = null;
+
+ let expected = [
+ ["https://foo.com", "A", 2, 0, 0, 0],
+ ["http://foo.com", "A", 2, 0, 0, 0],
+ ["http://foo.com^inBrowser=1", "A", 2, 0, 0, 0],
+ ];
+
+ let found = expected.map(it => 0);
+
+ // This will force the permission-manager to reload the data.
+ Services.obs.notifyObservers(null, "testonly-reload-permissions-from-disk");
+
+ // Force initialization of the PermissionManager
+ for (let permission of Services.perms.all) {
+ let isExpected = false;
+
+ expected.forEach((it, i) => {
+ if (
+ permission.principal.origin == it[0] &&
+ permission.type == it[1] &&
+ permission.capability == it[2] &&
+ permission.expireType == it[3] &&
+ permission.expireTime == it[4]
+ ) {
+ isExpected = true;
+ found[i]++;
+ }
+ });
+
+ Assert.ok(
+ isExpected,
+ "Permission " +
+ (isExpected ? "should" : "shouldn't") +
+ " be in permission database: " +
+ permission.principal.origin +
+ ", " +
+ permission.type +
+ ", " +
+ permission.capability +
+ ", " +
+ permission.expireType +
+ ", " +
+ permission.expireTime
+ );
+ }
+
+ found.forEach((count, i) => {
+ Assert.ok(
+ count == 1,
+ "Expected count = 1, got count = " +
+ count +
+ " for permission " +
+ expected[i]
+ );
+ });
+
+ // Check to make sure that all of the tables which we care about are present
+ {
+ db = Services.storage.openDatabase(GetPermissionsFile(profile));
+ Assert.ok(db.tableExists("moz_perms"));
+ Assert.ok(db.tableExists("moz_hosts"));
+ Assert.ok(!db.tableExists("moz_hosts_is_backup"));
+ Assert.ok(!db.tableExists("moz_perms_v6"));
+
+ let mozHostsStmt = db.createStatement(
+ "SELECT " +
+ "host, type, permission, expireType, expireTime, " +
+ "modificationTime, isInBrowserElement " +
+ "FROM moz_hosts WHERE id = :id"
+ );
+ try {
+ // Check that the moz_hosts table still contains the correct values.
+ created4.forEach(it => {
+ mozHostsStmt.reset();
+ mozHostsStmt.bindByName("id", it.id);
+ mozHostsStmt.executeStep();
+ Assert.equal(mozHostsStmt.getUTF8String(0), it.host);
+ Assert.equal(mozHostsStmt.getUTF8String(1), it.type);
+ Assert.equal(mozHostsStmt.getInt64(2), it.permission);
+ Assert.equal(mozHostsStmt.getInt64(3), it.expireType);
+ Assert.equal(mozHostsStmt.getInt64(4), it.expireTime);
+ Assert.equal(mozHostsStmt.getInt64(5), it.modificationTime);
+ Assert.equal(mozHostsStmt.getInt64(6), it.isInBrowserElement);
+ });
+ } finally {
+ mozHostsStmt.finalize();
+ }
+
+ // Check that there are the right number of values
+ let mozHostsCount = db.createStatement("SELECT count(*) FROM moz_hosts");
+ try {
+ mozHostsCount.executeStep();
+ Assert.equal(mozHostsCount.getInt64(0), created4.length);
+ } finally {
+ mozHostsCount.finalize();
+ }
+
+ db.close();
+ }
+});
diff --git a/extensions/permissions/test/unit/test_permmanager_migrate_7-8.js b/extensions/permissions/test/unit/test_permmanager_migrate_7-8.js
new file mode 100644
index 0000000000..cd8b0f86cc
--- /dev/null
+++ b/extensions/permissions/test/unit/test_permmanager_migrate_7-8.js
@@ -0,0 +1,328 @@
+/* Any copyright is dedicated to the Public Domain.
+ http://creativecommons.org/publicdomain/zero/1.0/ */
+
+ChromeUtils.defineESModuleGetters(this, {
+ PlacesTestUtils: "resource://testing-common/PlacesTestUtils.sys.mjs",
+});
+
+var PERMISSIONS_FILE_NAME = "permissions.sqlite";
+
+function GetPermissionsFile(profile) {
+ let file = profile.clone();
+ file.append(PERMISSIONS_FILE_NAME);
+ return file;
+}
+
+add_task(async function test() {
+ // Create and set up the permissions database.
+ Services.prefs.setCharPref("permissions.manager.defaultsUrl", "");
+ let profile = do_get_profile();
+
+ // We need to execute a pm method to be sure that the DB is fully
+ // initialized.
+ var pm = Services.perms;
+ Assert.equal(pm.all.length, 0, "No cookies");
+
+ let db = Services.storage.openDatabase(GetPermissionsFile(profile));
+ db.schemaVersion = 7;
+ db.executeSimpleSQL("DROP TABLE moz_perms");
+ db.executeSimpleSQL("DROP TABLE moz_hosts");
+
+ /*
+ * V5 table
+ */
+ db.executeSimpleSQL(
+ "CREATE TABLE moz_perms (" +
+ " id INTEGER PRIMARY KEY" +
+ ",origin TEXT" +
+ ",type TEXT" +
+ ",permission INTEGER" +
+ ",expireType INTEGER" +
+ ",expireTime INTEGER" +
+ ",modificationTime INTEGER" +
+ ")"
+ );
+
+ let stmt6Insert = db.createStatement(
+ "INSERT INTO moz_perms (" +
+ "id, origin, type, permission, expireType, expireTime, modificationTime" +
+ ") VALUES (" +
+ ":id, :origin, :type, :permission, :expireType, :expireTime, :modificationTime" +
+ ")"
+ );
+
+ /*
+ * V4 table
+ */
+ db.executeSimpleSQL(
+ "CREATE TABLE moz_hosts (" +
+ " id INTEGER PRIMARY KEY" +
+ ",host TEXT" +
+ ",type TEXT" +
+ ",permission INTEGER" +
+ ",expireType INTEGER" +
+ ",expireTime INTEGER" +
+ ",modificationTime INTEGER" +
+ ",appId INTEGER" +
+ ",isInBrowserElement INTEGER" +
+ ")"
+ );
+
+ let stmtInsert = db.createStatement(
+ "INSERT INTO moz_hosts (" +
+ "id, host, type, permission, expireType, expireTime, modificationTime, appId, isInBrowserElement" +
+ ") VALUES (" +
+ ":id, :host, :type, :permission, :expireType, :expireTime, :modificationTime, :appId, :isInBrowserElement" +
+ ")"
+ );
+
+ /*
+ * The v4 table is a backup
+ */
+ db.executeSimpleSQL(
+ "CREATE TABLE moz_hosts_is_backup (dummy INTEGER PRIMARY KEY)"
+ );
+
+ let id = 0;
+
+ function insertOrigin(
+ origin,
+ type,
+ permission,
+ expireType,
+ expireTime,
+ modificationTime
+ ) {
+ let thisId = id++;
+
+ stmt6Insert.bindByName("id", thisId);
+ stmt6Insert.bindByName("origin", origin);
+ stmt6Insert.bindByName("type", type);
+ stmt6Insert.bindByName("permission", permission);
+ stmt6Insert.bindByName("expireType", expireType);
+ stmt6Insert.bindByName("expireTime", expireTime);
+ stmt6Insert.bindByName("modificationTime", modificationTime);
+
+ try {
+ stmt6Insert.execute();
+ } finally {
+ stmt6Insert.reset();
+ }
+
+ return {
+ id: thisId,
+ origin,
+ type,
+ permission,
+ expireType,
+ expireTime,
+ modificationTime,
+ };
+ }
+
+ function insertHost(
+ host,
+ type,
+ permission,
+ expireType,
+ expireTime,
+ modificationTime,
+ appId,
+ isInBrowserElement
+ ) {
+ let thisId = id++;
+
+ stmtInsert.bindByName("id", thisId);
+ stmtInsert.bindByName("host", host);
+ stmtInsert.bindByName("type", type);
+ stmtInsert.bindByName("permission", permission);
+ stmtInsert.bindByName("expireType", expireType);
+ stmtInsert.bindByName("expireTime", expireTime);
+ stmtInsert.bindByName("modificationTime", modificationTime);
+ stmtInsert.bindByName("appId", appId);
+ stmtInsert.bindByName("isInBrowserElement", isInBrowserElement);
+
+ try {
+ stmtInsert.execute();
+ } finally {
+ stmtInsert.reset();
+ }
+
+ return {
+ id: thisId,
+ host,
+ type,
+ permission,
+ expireType,
+ expireTime,
+ modificationTime,
+ appId,
+ isInBrowserElement,
+ };
+ }
+ // eslint-disable-next-line no-unused-vars
+ let created7 = [
+ insertOrigin("https://foo.com", "A", 2, 0, 0, 0),
+ insertOrigin("http://foo.com", "A", 2, 0, 0, 0),
+ insertOrigin("http://foo.com^inBrowser=1", "A", 2, 0, 0, 0),
+ insertOrigin("https://192.0.2.235", "A", 2, 0, 0),
+ ];
+
+ // Add some rows to the database
+ // eslint-disable-next-line no-unused-vars
+ let created = [
+ insertHost("foo.com", "A", 1, 0, 0, 0, 0, false),
+ insertHost("foo.com", "C", 1, 0, 0, 0, 0, false),
+ insertHost("foo.com", "A", 1, 0, 0, 0, 1000, false),
+ insertHost("foo.com", "A", 1, 0, 0, 0, 2000, true),
+ insertHost("sub.foo.com", "B", 1, 0, 0, 0, 0, false),
+ insertHost("subber.sub.foo.com", "B", 1, 0, 0, 0, 0, false),
+ insertHost("bar.ca", "B", 1, 0, 0, 0, 0, false),
+ insertHost("bar.ca", "B", 1, 0, 0, 0, 1000, false),
+ insertHost("bar.ca", "A", 1, 0, 0, 0, 1000, true),
+ insertHost("localhost", "A", 1, 0, 0, 0, 0, false),
+ insertHost("127.0.0.1", "A", 1, 0, 0, 0, 0, false),
+ insertHost("192.0.2.235", "A", 1, 0, 0, 0, 0, false),
+ // Although ipv6 addresses are written with [] around the IP address,
+ // the .host property doesn't contain these []s, which means that we
+ // write it like this
+ insertHost("2001:db8::ff00:42:8329", "C", 1, 0, 0, 0, 0, false),
+ insertHost("file:///some/path/to/file.html", "A", 1, 0, 0, 0, 0, false),
+ insertHost("file:///another/file.html", "A", 1, 0, 0, 0, 0, false),
+ insertHost(
+ "moz-nullprincipal:{8695105a-adbe-4e4e-8083-851faa5ca2d7}",
+ "A",
+ 1,
+ 0,
+ 0,
+ 0,
+ 0,
+ false
+ ),
+ insertHost(
+ "moz-nullprincipal:{12ahjksd-akjs-asd3-8393-asdu2189asdu}",
+ "B",
+ 1,
+ 0,
+ 0,
+ 0,
+ 0,
+ false
+ ),
+ insertHost("<file>", "A", 1, 0, 0, 0, 0, false),
+ insertHost("<file>", "B", 1, 0, 0, 0, 0, false),
+ ];
+
+ // CLose the db connection
+ stmt6Insert.finalize();
+ stmtInsert.finalize();
+ db.close();
+ stmtInsert = null;
+ db = null;
+
+ let expected = [
+ // We should have kept the previously migrated entries
+ ["https://foo.com", "A", 2, 0, 0, 0],
+ ["http://foo.com", "A", 2, 0, 0, 0],
+ ["http://foo.com^inBrowser=1", "A", 2, 0, 0, 0],
+
+ // Make sure that we also support localhost, and IP addresses
+ ["https://localhost:8080", "A", 1, 0, 0],
+ ["ftp://127.0.0.1:8080", "A", 1, 0, 0],
+
+ ["http://[2001:db8::ff00:42:8329]", "C", 1, 0, 0],
+ ["https://[2001:db8::ff00:42:8329]", "C", 1, 0, 0],
+ ["http://192.0.2.235", "A", 1, 0, 0],
+
+ // There should only be one entry of this type in the database
+ ["https://192.0.2.235", "A", 2, 0, 0],
+ ];
+
+ let found = expected.map(it => 0);
+
+ // Add some places to the places database
+ await PlacesTestUtils.addVisits(
+ Services.io.newURI("https://foo.com/some/other/subdirectory")
+ );
+ await PlacesTestUtils.addVisits(
+ Services.io.newURI("ftp://some.subdomain.of.foo.com:8000/some/subdirectory")
+ );
+ await PlacesTestUtils.addVisits(Services.io.newURI("ftp://127.0.0.1:8080"));
+ await PlacesTestUtils.addVisits(Services.io.newURI("https://localhost:8080"));
+
+ // This will force the permission-manager to reload the data.
+ Services.obs.notifyObservers(null, "testonly-reload-permissions-from-disk");
+
+ // Force initialization of the PermissionManager
+ for (let permission of Services.perms.all) {
+ let isExpected = false;
+
+ expected.forEach((it, i) => {
+ if (
+ permission.principal.origin == it[0] &&
+ permission.type == it[1] &&
+ permission.capability == it[2] &&
+ permission.expireType == it[3] &&
+ permission.expireTime == it[4]
+ ) {
+ isExpected = true;
+ found[i]++;
+ }
+ });
+
+ Assert.ok(
+ isExpected,
+ "Permission " +
+ (isExpected ? "should" : "shouldn't") +
+ " be in permission database: " +
+ permission.principal.origin +
+ ", " +
+ permission.type +
+ ", " +
+ permission.capability +
+ ", " +
+ permission.expireType +
+ ", " +
+ permission.expireTime
+ );
+ }
+
+ found.forEach((count, i) => {
+ Assert.ok(
+ count == 1,
+ "Expected count = 1, got count = " +
+ count +
+ " for permission " +
+ expected[i]
+ );
+ });
+
+ // Check to make sure that all of the tables which we care about are present
+ {
+ db = Services.storage.openDatabase(GetPermissionsFile(profile));
+ Assert.ok(db.tableExists("moz_perms"));
+ Assert.ok(db.tableExists("moz_hosts"));
+ Assert.ok(!db.tableExists("moz_hosts_is_backup"));
+ Assert.ok(!db.tableExists("moz_perms_v6"));
+
+ // The moz_hosts table should still exist but be empty
+ let mozHostsCount = db.createStatement("SELECT count(*) FROM moz_hosts");
+ try {
+ mozHostsCount.executeStep();
+ Assert.equal(mozHostsCount.getInt64(0), 0);
+ } finally {
+ mozHostsCount.finalize();
+ }
+
+ // Check that there are the right number of values in the permissions database
+ let mozPermsCount = db.createStatement("SELECT count(*) FROM moz_perms");
+ try {
+ mozPermsCount.executeStep();
+ Assert.equal(mozPermsCount.getInt64(0), expected.length);
+ } finally {
+ mozPermsCount.finalize();
+ }
+
+ db.close();
+ }
+});
diff --git a/extensions/permissions/test/unit/test_permmanager_migrate_9-10.js b/extensions/permissions/test/unit/test_permmanager_migrate_9-10.js
new file mode 100644
index 0000000000..02aa3bb467
--- /dev/null
+++ b/extensions/permissions/test/unit/test_permmanager_migrate_9-10.js
@@ -0,0 +1,262 @@
+/* Any copyright is dedicated to the Public Domain.
+ http://creativecommons.org/publicdomain/zero/1.0/ */
+
+ChromeUtils.defineESModuleGetters(this, {
+ PlacesTestUtils: "resource://testing-common/PlacesTestUtils.sys.mjs",
+});
+
+var PERMISSIONS_FILE_NAME = "permissions.sqlite";
+
+function GetPermissionsFile(profile) {
+ let file = profile.clone();
+ file.append(PERMISSIONS_FILE_NAME);
+ return file;
+}
+
+add_task(async function test() {
+ // Create and set up the permissions database.
+ Services.prefs.setCharPref("permissions.manager.defaultsUrl", "");
+ let profile = do_get_profile();
+
+ // We need to execute a pm method to be sure that the DB is fully
+ // initialized.
+ var pm = Services.perms;
+ Assert.equal(pm.all.length, 0, "No cookies");
+
+ let db = Services.storage.openDatabase(GetPermissionsFile(profile));
+ db.schemaVersion = 9;
+ db.executeSimpleSQL("DROP TABLE moz_perms");
+ db.executeSimpleSQL("DROP TABLE IF EXISTS moz_hosts");
+
+ db.executeSimpleSQL(
+ "CREATE TABLE moz_perms (" +
+ " id INTEGER PRIMARY KEY" +
+ ",origin TEXT" +
+ ",type TEXT" +
+ ",permission INTEGER" +
+ ",expireType INTEGER" +
+ ",expireTime INTEGER" +
+ ",modificationTime INTEGER" +
+ ")"
+ );
+
+ let stmt6Insert = db.createStatement(
+ "INSERT INTO moz_perms (" +
+ "id, origin, type, permission, expireType, expireTime, modificationTime" +
+ ") VALUES (" +
+ ":id, :origin, :type, :permission, :expireType, :expireTime, :modificationTime" +
+ ")"
+ );
+
+ db.executeSimpleSQL(
+ "CREATE TABLE moz_hosts (" +
+ " id INTEGER PRIMARY KEY" +
+ ",host TEXT" +
+ ",type TEXT" +
+ ",permission INTEGER" +
+ ",expireType INTEGER" +
+ ",expireTime INTEGER" +
+ ",modificationTime INTEGER" +
+ ",appId INTEGER" +
+ ",isInBrowserElement INTEGER" +
+ ")"
+ );
+
+ let stmtInsert = db.createStatement(
+ "INSERT INTO moz_hosts (" +
+ "id, host, type, permission, expireType, expireTime, modificationTime, appId, isInBrowserElement" +
+ ") VALUES (" +
+ ":id, :host, :type, :permission, :expireType, :expireTime, :modificationTime, :appId, :isInBrowserElement" +
+ ")"
+ );
+
+ let id = 0;
+
+ function insertOrigin(
+ origin,
+ type,
+ permission,
+ expireType,
+ expireTime,
+ modificationTime
+ ) {
+ let thisId = id++;
+
+ stmt6Insert.bindByName("id", thisId);
+ stmt6Insert.bindByName("origin", origin);
+ stmt6Insert.bindByName("type", type);
+ stmt6Insert.bindByName("permission", permission);
+ stmt6Insert.bindByName("expireType", expireType);
+ stmt6Insert.bindByName("expireTime", expireTime);
+ stmt6Insert.bindByName("modificationTime", modificationTime);
+
+ try {
+ stmt6Insert.execute();
+ } finally {
+ stmt6Insert.reset();
+ }
+
+ return {
+ id: thisId,
+ origin,
+ type,
+ permission,
+ expireType,
+ expireTime,
+ modificationTime,
+ };
+ }
+
+ function insertHost(
+ host,
+ type,
+ permission,
+ expireType,
+ expireTime,
+ modificationTime,
+ appId,
+ isInBrowserElement
+ ) {
+ let thisId = id++;
+
+ stmtInsert.bindByName("id", thisId);
+ stmtInsert.bindByName("host", host);
+ stmtInsert.bindByName("type", type);
+ stmtInsert.bindByName("permission", permission);
+ stmtInsert.bindByName("expireType", expireType);
+ stmtInsert.bindByName("expireTime", expireTime);
+ stmtInsert.bindByName("modificationTime", modificationTime);
+ stmtInsert.bindByName("appId", appId);
+ stmtInsert.bindByName("isInBrowserElement", isInBrowserElement);
+
+ try {
+ stmtInsert.execute();
+ } finally {
+ stmtInsert.reset();
+ }
+
+ return {
+ id: thisId,
+ host,
+ type,
+ permission,
+ expireType,
+ expireTime,
+ modificationTime,
+ appId,
+ isInBrowserElement,
+ };
+ }
+ // eslint-disable-next-line no-unused-vars
+ let created7 = [
+ insertOrigin("https://foo.com", "A", 2, 0, 0, 0),
+ insertOrigin("http://foo.com", "A", 2, 0, 0, 0),
+ insertOrigin("http://foo.com^inBrowser=1", "A", 2, 0, 0, 0),
+ ];
+
+ // Add some rows to the database
+ // eslint-disable-next-line no-unused-vars
+ let created = [
+ insertHost("foo.com", "A", 1, 0, 0, 0, 0, false),
+ insertHost("foo.com", "B", 1, 0, 0, 0, 1000, false),
+ insertHost("foo.com", "C", 1, 0, 0, 0, 2000, true),
+ ];
+
+ // CLose the db connection
+ stmt6Insert.finalize();
+ stmtInsert.finalize();
+ db.close();
+ stmtInsert = null;
+ db = null;
+
+ let expected = [
+ ["https://foo.com", "A", 2, 0, 0, 0],
+ ["http://foo.com", "A", 2, 0, 0, 0],
+ ["http://foo.com^inBrowser=1", "A", 2, 0, 0, 0],
+ ];
+
+ let found = expected.map(it => 0);
+
+ // Add some places to the places database
+ await PlacesTestUtils.addVisits(
+ Services.io.newURI("https://foo.com/some/other/subdirectory")
+ );
+ await PlacesTestUtils.addVisits(
+ Services.io.newURI("ftp://some.subdomain.of.foo.com:8000/some/subdirectory")
+ );
+ await PlacesTestUtils.addVisits(Services.io.newURI("ftp://127.0.0.1:8080"));
+ await PlacesTestUtils.addVisits(Services.io.newURI("https://localhost:8080"));
+
+ // This will force the permission-manager to reload the data.
+ Services.obs.notifyObservers(null, "testonly-reload-permissions-from-disk");
+
+ // Force initialization of the PermissionManager
+ for (let permission of Services.perms.all) {
+ let isExpected = false;
+
+ expected.forEach((it, i) => {
+ if (
+ permission.principal.origin == it[0] &&
+ permission.type == it[1] &&
+ permission.capability == it[2] &&
+ permission.expireType == it[3] &&
+ permission.expireTime == it[4]
+ ) {
+ isExpected = true;
+ found[i]++;
+ }
+ });
+
+ Assert.ok(
+ isExpected,
+ "Permission " +
+ (isExpected ? "should" : "shouldn't") +
+ " be in permission database: " +
+ permission.principal.origin +
+ ", " +
+ permission.type +
+ ", " +
+ permission.capability +
+ ", " +
+ permission.expireType +
+ ", " +
+ permission.expireTime
+ );
+ }
+
+ found.forEach((count, i) => {
+ Assert.ok(
+ count == 1,
+ "Expected count = 1, got count = " +
+ count +
+ " for permission " +
+ expected[i]
+ );
+ });
+
+ // Check to make sure that all of the tables which we care about are present
+ {
+ db = Services.storage.openDatabase(GetPermissionsFile(profile));
+ Assert.ok(db.tableExists("moz_perms"));
+ Assert.ok(db.tableExists("moz_hosts"));
+ Assert.ok(!db.tableExists("moz_perms_v6"));
+
+ let mozHostsCount = db.createStatement("SELECT count(*) FROM moz_hosts");
+ try {
+ mozHostsCount.executeStep();
+ Assert.equal(mozHostsCount.getInt64(0), 3);
+ } finally {
+ mozHostsCount.finalize();
+ }
+
+ let mozPermsCount = db.createStatement("SELECT count(*) FROM moz_perms");
+ try {
+ mozPermsCount.executeStep();
+ Assert.equal(mozPermsCount.getInt64(0), expected.length);
+ } finally {
+ mozPermsCount.finalize();
+ }
+
+ db.close();
+ }
+});
diff --git a/extensions/permissions/test/unit/test_permmanager_notifications.js b/extensions/permissions/test/unit/test_permmanager_notifications.js
new file mode 100644
index 0000000000..fb851aa04b
--- /dev/null
+++ b/extensions/permissions/test/unit/test_permmanager_notifications.js
@@ -0,0 +1,139 @@
+/* Any copyright is dedicated to the Public Domain.
+ http://creativecommons.org/publicdomain/zero/1.0/ */
+
+// Test that the permissionmanager 'added', 'changed', 'deleted', and 'cleared'
+// notifications behave as expected.
+
+var test_generator = do_run_test();
+
+function run_test() {
+ Services.prefs.setCharPref("permissions.manager.defaultsUrl", "");
+ do_test_pending();
+ test_generator.next();
+}
+
+function* do_run_test() {
+ let pm = Services.perms;
+ let now = Number(Date.now());
+ let permType = "test/expiration-perm";
+ let ssm = Services.scriptSecurityManager;
+ let uri = NetUtil.newURI("http://example.com");
+ let principal = ssm.createContentPrincipal(uri, {});
+
+ let observer = new permission_observer(test_generator, now, permType);
+ Services.obs.addObserver(observer, "perm-changed");
+
+ // Add a permission, to test the 'add' notification. Note that we use
+ // do_execute_soon() so that we can use our generator to continue the test
+ // where we left off.
+ executeSoon(function () {
+ pm.addFromPrincipal(
+ principal,
+ permType,
+ pm.ALLOW_ACTION,
+ pm.EXPIRE_TIME,
+ now + 100000
+ );
+ });
+ yield;
+
+ // Alter a permission, to test the 'changed' notification.
+ executeSoon(function () {
+ pm.addFromPrincipal(
+ principal,
+ permType,
+ pm.ALLOW_ACTION,
+ pm.EXPIRE_TIME,
+ now + 200000
+ );
+ });
+ yield;
+
+ // Remove a permission, to test the 'deleted' notification.
+ executeSoon(function () {
+ pm.removeFromPrincipal(principal, permType);
+ });
+ yield;
+
+ // Clear permissions, to test the 'cleared' notification.
+ executeSoon(function () {
+ pm.removeAll();
+ });
+ yield;
+
+ Services.obs.removeObserver(observer, "perm-changed");
+ Assert.equal(observer.adds, 1);
+ Assert.equal(observer.changes, 1);
+ Assert.equal(observer.deletes, 1);
+ Assert.ok(observer.cleared);
+
+ do_finish_generator_test(test_generator);
+}
+
+function permission_observer(generator, now, type) {
+ // Set up our observer object.
+ this.generator = generator;
+ this.pm = Services.perms;
+ this.now = now;
+ this.type = type;
+ this.adds = 0;
+ this.changes = 0;
+ this.deletes = 0;
+ this.cleared = false;
+}
+
+permission_observer.prototype = {
+ observe(subject, topic, data) {
+ Assert.equal(topic, "perm-changed");
+
+ // "deleted" means a permission was deleted. aPermission is the deleted permission.
+ // "added" means a permission was added. aPermission is the added permission.
+ // "changed" means a permission was altered. aPermission is the new permission.
+ // "cleared" means the entire permission list was cleared. aPermission is null.
+ if (data == "added") {
+ let perm = subject.QueryInterface(Ci.nsIPermission);
+ this.adds++;
+ switch (this.adds) {
+ case 1:
+ Assert.equal(this.type, perm.type);
+ Assert.equal(this.pm.EXPIRE_TIME, perm.expireType);
+ Assert.equal(this.now + 100000, perm.expireTime);
+ break;
+ default:
+ do_throw("too many add notifications posted.");
+ }
+ } else if (data == "changed") {
+ let perm = subject.QueryInterface(Ci.nsIPermission);
+ this.changes++;
+ switch (this.changes) {
+ case 1:
+ Assert.equal(this.type, perm.type);
+ Assert.equal(this.pm.EXPIRE_TIME, perm.expireType);
+ Assert.equal(this.now + 200000, perm.expireTime);
+ break;
+ default:
+ do_throw("too many change notifications posted.");
+ }
+ } else if (data == "deleted") {
+ let perm = subject.QueryInterface(Ci.nsIPermission);
+ this.deletes++;
+ switch (this.deletes) {
+ case 1:
+ Assert.equal(this.type, perm.type);
+ break;
+ default:
+ do_throw("too many delete notifications posted.");
+ }
+ } else if (data == "cleared") {
+ // only clear once: at the end
+ Assert.ok(!this.cleared);
+ Assert.equal(do_count_array(Services.perms.all), 0);
+ this.cleared = true;
+ } else {
+ do_throw("unexpected data '" + data + "'!");
+ }
+
+ // Continue the test.
+ do_run_generator(this.generator);
+ },
+};
diff --git a/extensions/permissions/test/unit/test_permmanager_oa_strip.js b/extensions/permissions/test/unit/test_permmanager_oa_strip.js
new file mode 100644
index 0000000000..d6c15bd807
--- /dev/null
+++ b/extensions/permissions/test/unit/test_permmanager_oa_strip.js
@@ -0,0 +1,220 @@
+/* Any copyright is dedicated to the Public Domain.
+ http://creativecommons.org/publicdomain/zero/1.0/ */
+
+const TEST_URI = Services.io.newURI("http://example.com");
+const TEST_PERMISSION = "test/oastrip";
+const TEST_PERMISSION2 = "test/oastrip2";
+const TEST_PERMISSION3 = "test/oastrip3";
+
+// List of permissions which are not isolated by private browsing or user context
+// as per array kStripOAPermissions in PermissionManager.cpp
+const STRIPPED_PERMS = ["cookie"];
+
+let principal = Services.scriptSecurityManager.createContentPrincipal(
+ TEST_URI,
+ {}
+);
+let principalPrivateBrowsing =
+ Services.scriptSecurityManager.createContentPrincipal(TEST_URI, {
+ privateBrowsingId: 1,
+ });
+let principalUserContext1 =
+ Services.scriptSecurityManager.createContentPrincipal(TEST_URI, {
+ userContextId: 1,
+ });
+let principalUserContext2 =
+ Services.scriptSecurityManager.createContentPrincipal(TEST_URI, {
+ userContextId: 2,
+ });
+
+function testOAIsolation(permIsolateUserContext, permIsolatePrivateBrowsing) {
+ info(
+ `testOAIsolation: permIsolateUserContext: ${permIsolateUserContext}; permIsolatePrivateBrowsing: ${permIsolatePrivateBrowsing}`
+ );
+
+ let pm = Services.perms;
+
+ Services.prefs.setBoolPref(
+ "permissions.isolateBy.userContext",
+ permIsolateUserContext
+ );
+ Services.prefs.setBoolPref(
+ "permissions.isolateBy.privateBrowsing",
+ permIsolatePrivateBrowsing
+ );
+
+ // Set test permission for normal browsing
+ pm.addFromPrincipal(principal, TEST_PERMISSION, pm.ALLOW_ACTION);
+
+ // Check normal browsing permission
+ Assert.equal(
+ Ci.nsIPermissionManager.ALLOW_ACTION,
+ pm.testPermissionFromPrincipal(principal, TEST_PERMISSION)
+ );
+ // normal browsing => user context 1
+ Assert.equal(
+ permIsolateUserContext
+ ? Ci.nsIPermissionManager.UNKNOWN_ACTION
+ : Ci.nsIPermissionManager.ALLOW_ACTION,
+ pm.testPermissionFromPrincipal(principalUserContext1, TEST_PERMISSION)
+ );
+ // normal browsing => user context 2
+ Assert.equal(
+ permIsolateUserContext
+ ? Ci.nsIPermissionManager.UNKNOWN_ACTION
+ : Ci.nsIPermissionManager.ALLOW_ACTION,
+ pm.testPermissionFromPrincipal(principalUserContext2, TEST_PERMISSION)
+ );
+ // normal browsing => private browsing
+ Assert.equal(
+ permIsolatePrivateBrowsing
+ ? Ci.nsIPermissionManager.UNKNOWN_ACTION
+ : Ci.nsIPermissionManager.ALLOW_ACTION,
+ pm.testPermissionFromPrincipal(principalPrivateBrowsing, TEST_PERMISSION)
+ );
+
+ // Set permission for private browsing
+ pm.addFromPrincipal(
+ principalPrivateBrowsing,
+ TEST_PERMISSION2,
+ pm.DENY_ACTION
+ );
+
+ // Check private browsing permission
+ Assert.equal(
+ Ci.nsIPermissionManager.DENY_ACTION,
+ pm.testPermissionFromPrincipal(principalPrivateBrowsing, TEST_PERMISSION2)
+ );
+ // private browsing => normal browsing
+ Assert.equal(
+ permIsolatePrivateBrowsing
+ ? Ci.nsIPermissionManager.UNKNOWN_ACTION
+ : Ci.nsIPermissionManager.DENY_ACTION,
+ pm.testPermissionFromPrincipal(principal, TEST_PERMISSION2)
+ );
+ // private browsing => user context 1
+ Assert.equal(
+ permIsolatePrivateBrowsing || permIsolateUserContext
+ ? Ci.nsIPermissionManager.UNKNOWN_ACTION
+ : Ci.nsIPermissionManager.DENY_ACTION,
+ pm.testPermissionFromPrincipal(principalUserContext1, TEST_PERMISSION2)
+ );
+ // private browsing => user context 2
+ Assert.equal(
+ permIsolatePrivateBrowsing || permIsolateUserContext
+ ? Ci.nsIPermissionManager.UNKNOWN_ACTION
+ : Ci.nsIPermissionManager.DENY_ACTION,
+ pm.testPermissionFromPrincipal(principalUserContext2, TEST_PERMISSION2)
+ );
+
+ // Set permission for user context 1
+ pm.addFromPrincipal(
+ principalUserContext1,
+ TEST_PERMISSION3,
+ pm.PROMPT_ACTION
+ );
+
+ // Check user context 1 permission
+ Assert.equal(
+ Ci.nsIPermissionManager.PROMPT_ACTION,
+ pm.testPermissionFromPrincipal(principalUserContext1, TEST_PERMISSION3)
+ );
+
+ // user context 1 => normal browsing
+ Assert.equal(
+ permIsolateUserContext
+ ? Ci.nsIPermissionManager.UNKNOWN_ACTION
+ : Ci.nsIPermissionManager.PROMPT_ACTION,
+ pm.testPermissionFromPrincipal(principal, TEST_PERMISSION3)
+ );
+ // user context 1 => user context 2
+ Assert.equal(
+ permIsolateUserContext
+ ? Ci.nsIPermissionManager.UNKNOWN_ACTION
+ : Ci.nsIPermissionManager.PROMPT_ACTION,
+ pm.testPermissionFromPrincipal(principalUserContext2, TEST_PERMISSION3)
+ );
+ // user context 1 => private browsing
+ Assert.equal(
+ permIsolatePrivateBrowsing || permIsolateUserContext
+ ? Ci.nsIPermissionManager.UNKNOWN_ACTION
+ : Ci.nsIPermissionManager.PROMPT_ACTION,
+ pm.testPermissionFromPrincipal(principalPrivateBrowsing, TEST_PERMISSION3)
+ );
+
+ pm.removeAll();
+
+ // Modifying an non-isolated/stripped permission should affect all browsing contexts,
+ // independently of permission isolation pref state
+ STRIPPED_PERMS.forEach(perm => {
+ info("Testing stripped permission " + perm);
+
+ // Add a permission for the normal window
+ pm.addFromPrincipal(principal, perm, pm.ALLOW_ACTION);
+ Assert.equal(
+ pm.testPermissionFromPrincipal(principalPrivateBrowsing, perm),
+ Ci.nsIPermissionManager.ALLOW_ACTION
+ );
+ Assert.equal(
+ pm.testPermissionFromPrincipal(principalUserContext1, perm),
+ Ci.nsIPermissionManager.ALLOW_ACTION
+ );
+ Assert.equal(
+ pm.testPermissionFromPrincipal(principalUserContext2, perm),
+ Ci.nsIPermissionManager.ALLOW_ACTION
+ );
+
+ // Remove the permission from private window
+ pm.removeFromPrincipal(principalPrivateBrowsing, perm);
+ Assert.equal(
+ pm.testPermissionFromPrincipal(principal, perm),
+ Ci.nsIPermissionManager.UNKNOWN_ACTION
+ );
+ Assert.equal(
+ pm.testPermissionFromPrincipal(principalUserContext1, perm),
+ Ci.nsIPermissionManager.UNKNOWN_ACTION
+ );
+ Assert.equal(
+ pm.testPermissionFromPrincipal(principalUserContext2, perm),
+ Ci.nsIPermissionManager.UNKNOWN_ACTION
+ );
+
+ // Set a permission for a normal window and then override it by adding it to container 2 again
+ pm.addFromPrincipal(principal, perm, pm.PROMPT_ACTION);
+ pm.addFromPrincipal(principal, TEST_PERMISSION, pm.ALLOW_ACTION);
+ pm.addFromPrincipal(principalUserContext2, perm, pm.DENY_ACTION);
+
+ let principalPerms = pm.getAllForPrincipal(principalPrivateBrowsing, perm);
+
+ Assert.ok(
+ principalPerms.some(p => p.type == perm && p.capability == pm.DENY_ACTION)
+ );
+ if (permIsolatePrivateBrowsing) {
+ Assert.equal(principalPerms.length, 1);
+ Assert.ok(
+ principalPerms.some(
+ p => p.type == perm && p.capability == pm.DENY_ACTION
+ )
+ );
+ } else {
+ Assert.equal(principalPerms.length, 2);
+ Assert.ok(
+ principalPerms.some(
+ p => p.type == TEST_PERMISSION && p.capability == pm.ALLOW_ACTION
+ )
+ );
+ }
+ });
+
+ // Cleanup
+ pm.removeAll();
+}
+
+add_task(async function do_test() {
+ // Test all pref combinations and check if principals with different origin attributes
+ // are isolated.
+ testOAIsolation(true, true);
+ testOAIsolation(true, false);
+ testOAIsolation(false, true);
+ testOAIsolation(false, false);
+});
diff --git a/extensions/permissions/test/unit/test_permmanager_remove_add_update.js b/extensions/permissions/test/unit/test_permmanager_remove_add_update.js
new file mode 100644
index 0000000000..6ec7b1f6e5
--- /dev/null
+++ b/extensions/permissions/test/unit/test_permmanager_remove_add_update.js
@@ -0,0 +1,84 @@
+/* Any copyright is dedicated to the Public Domain.
+ http://creativecommons.org/publicdomain/zero/1.0/ */
+
+function check_enumerator(principal, permissions) {
+ let perms = Services.perms.getAllForPrincipal(principal);
+ for (let [type, capability, expireType] of permissions) {
+ let perm = perms.shift();
+ Assert.ok(perm != null);
+ Assert.equal(perm.type, type);
+ Assert.equal(perm.capability, capability);
+ Assert.equal(perm.expireType, expireType);
+ }
+ Assert.ok(!perms.length);
+}
+
+add_task(async function test() {
+ Services.prefs.setCharPref("permissions.manager.defaultsUrl", "");
+
+ // setup a profile directory
+ do_get_profile();
+
+ // We need to execute a pm method to be sure that the DB is fully
+ // initialized.
+ var pm = Services.perms;
+ Assert.ok(pm.all.length === 0);
+
+ let principal =
+ Services.scriptSecurityManager.createContentPrincipalFromOrigin(
+ "http://example.com"
+ );
+
+ info("From session to persistent");
+ pm.addFromPrincipal(
+ principal,
+ "test/foo",
+ pm.ALLOW_ACTION,
+ pm.EXPIRE_SESSION
+ );
+
+ check_enumerator(principal, [
+ ["test/foo", pm.ALLOW_ACTION, pm.EXPIRE_SESSION],
+ ]);
+
+ pm.addFromPrincipal(principal, "test/foo", pm.ALLOW_ACTION, pm.EXPIRE_NEVER);
+
+ check_enumerator(principal, [["test/foo", pm.ALLOW_ACTION, pm.EXPIRE_NEVER]]);
+
+ // Let's reload the DB.
+ Services.obs.notifyObservers(null, "testonly-reload-permissions-from-disk");
+
+ Assert.ok(pm.all.length === 1);
+ check_enumerator(principal, [["test/foo", pm.ALLOW_ACTION, pm.EXPIRE_NEVER]]);
+
+ info("From persistent to session");
+ pm.addFromPrincipal(
+ principal,
+ "test/foo",
+ pm.ALLOW_ACTION,
+ pm.EXPIRE_SESSION
+ );
+
+ check_enumerator(principal, [
+ ["test/foo", pm.ALLOW_ACTION, pm.EXPIRE_SESSION],
+ ]);
+
+ // Let's reload the DB.
+ Services.obs.notifyObservers(null, "testonly-reload-permissions-from-disk");
+ Assert.ok(pm.all.length === 0);
+
+ info("From persistent to persistent");
+ pm.addFromPrincipal(principal, "test/foo", pm.ALLOW_ACTION, pm.EXPIRE_NEVER);
+ pm.addFromPrincipal(principal, "test/foo", pm.DENY_ACTION, pm.EXPIRE_NEVER);
+
+ check_enumerator(principal, [["test/foo", pm.DENY_ACTION, pm.EXPIRE_NEVER]]);
+
+ // Let's reload the DB.
+ Services.obs.notifyObservers(null, "testonly-reload-permissions-from-disk");
+ Assert.ok(pm.all.length === 1);
+ check_enumerator(principal, [["test/foo", pm.DENY_ACTION, pm.EXPIRE_NEVER]]);
+
+ info("Cleanup");
+ pm.removeAll();
+ check_enumerator(principal, []);
+});
diff --git a/extensions/permissions/test/unit/test_permmanager_removeall.js b/extensions/permissions/test/unit/test_permmanager_removeall.js
new file mode 100644
index 0000000000..e6faea1369
--- /dev/null
+++ b/extensions/permissions/test/unit/test_permmanager_removeall.js
@@ -0,0 +1,47 @@
+/* Any copyright is dedicated to the Public Domain.
+ http://creativecommons.org/publicdomain/zero/1.0/ */
+
+add_task(async function test() {
+ Services.prefs.setCharPref("permissions.manager.defaultsUrl", "");
+ // setup a profile directory
+ var dir = do_get_profile();
+
+ // We need to execute a pm method to be sure that the DB is fully
+ // initialized.
+ var pm = Services.perms;
+ Assert.ok(pm.all.length === 0);
+
+ Services.obs.notifyObservers(null, "testonly-reload-permissions-from-disk");
+
+ // Let's force the completion of the DB reading.
+ Assert.ok(pm.all.length === 0);
+
+ // get the db file
+ var file = dir.clone();
+ file.append("permissions.sqlite");
+
+ Assert.ok(file.exists());
+
+ // corrupt the file
+ var ostream = Cc["@mozilla.org/network/file-output-stream;1"].createInstance(
+ Ci.nsIFileOutputStream
+ );
+ ostream.init(file, 0x02, 0o666, 0);
+ var conv = Cc["@mozilla.org/intl/converter-output-stream;1"].createInstance(
+ Ci.nsIConverterOutputStream
+ );
+ conv.init(ostream, "UTF-8");
+ for (var i = 0; i < file.fileSize; ++i) {
+ conv.writeString("a");
+ }
+ conv.close();
+
+ // prepare an empty hostperm.1 file so that it can be used for importing
+ var hostperm = dir.clone();
+ hostperm.append("hostperm.1");
+ ostream.init(hostperm, 0x02 | 0x08, 0o666, 0);
+ ostream.close();
+
+ // remove all should not throw
+ pm.removeAll();
+});
diff --git a/extensions/permissions/test/unit/test_permmanager_removebytype.js b/extensions/permissions/test/unit/test_permmanager_removebytype.js
new file mode 100644
index 0000000000..127e0de6ec
--- /dev/null
+++ b/extensions/permissions/test/unit/test_permmanager_removebytype.js
@@ -0,0 +1,76 @@
+/* Any copyright is dedicated to the Public Domain.
+ http://creativecommons.org/publicdomain/zero/1.0/ */
+
+function run_test() {
+ Services.prefs.setCharPref("permissions.manager.defaultsUrl", "");
+
+ // initialize the permission manager service
+ let pm = Services.perms;
+
+ Assert.equal(pm.all.length, 0);
+
+ // add some permissions
+ let principal =
+ Services.scriptSecurityManager.createContentPrincipalFromOrigin(
+ "http://amazon.com:8080"
+ );
+ let principal2 =
+ Services.scriptSecurityManager.createContentPrincipalFromOrigin(
+ "http://google.com:2048"
+ );
+ let principal3 =
+ Services.scriptSecurityManager.createContentPrincipalFromOrigin(
+ "https://google.com"
+ );
+
+ pm.addFromPrincipal(principal, "apple", 3);
+ pm.addFromPrincipal(principal, "pear", 1);
+ pm.addFromPrincipal(principal, "cucumber", 1);
+
+ pm.addFromPrincipal(principal2, "apple", 2);
+ pm.addFromPrincipal(principal2, "pear", 2);
+
+ pm.addFromPrincipal(principal3, "cucumber", 3);
+ pm.addFromPrincipal(principal3, "apple", 1);
+
+ Assert.equal(pm.all.length, 7);
+
+ pm.removeByType("apple");
+ Assert.equal(pm.all.length, 4);
+
+ Assert.equal(pm.testPermissionFromPrincipal(principal, "pear"), 1);
+ Assert.equal(pm.testPermissionFromPrincipal(principal2, "pear"), 2);
+
+ Assert.equal(pm.testPermissionFromPrincipal(principal, "apple"), 0);
+ Assert.equal(pm.testPermissionFromPrincipal(principal2, "apple"), 0);
+ Assert.equal(pm.testPermissionFromPrincipal(principal3, "apple"), 0);
+
+ Assert.equal(pm.testPermissionFromPrincipal(principal, "cucumber"), 1);
+ Assert.equal(pm.testPermissionFromPrincipal(principal3, "cucumber"), 3);
+
+ pm.removeByType("cucumber");
+ Assert.equal(pm.all.length, 2);
+
+ Assert.equal(pm.testPermissionFromPrincipal(principal, "pear"), 1);
+ Assert.equal(pm.testPermissionFromPrincipal(principal2, "pear"), 2);
+
+ Assert.equal(pm.testPermissionFromPrincipal(principal, "apple"), 0);
+ Assert.equal(pm.testPermissionFromPrincipal(principal2, "apple"), 0);
+ Assert.equal(pm.testPermissionFromPrincipal(principal3, "apple"), 0);
+
+ Assert.equal(pm.testPermissionFromPrincipal(principal, "cucumber"), 0);
+ Assert.equal(pm.testPermissionFromPrincipal(principal3, "cucumber"), 0);
+
+ pm.removeByType("pear");
+ Assert.equal(pm.all.length, 0);
+
+ Assert.equal(pm.testPermissionFromPrincipal(principal, "pear"), 0);
+ Assert.equal(pm.testPermissionFromPrincipal(principal2, "pear"), 0);
+
+ Assert.equal(pm.testPermissionFromPrincipal(principal, "apple"), 0);
+ Assert.equal(pm.testPermissionFromPrincipal(principal2, "apple"), 0);
+ Assert.equal(pm.testPermissionFromPrincipal(principal3, "apple"), 0);
+
+ Assert.equal(pm.testPermissionFromPrincipal(principal, "cucumber"), 0);
+ Assert.equal(pm.testPermissionFromPrincipal(principal3, "cucumber"), 0);
+}
diff --git a/extensions/permissions/test/unit/test_permmanager_removebytypesince.js b/extensions/permissions/test/unit/test_permmanager_removebytypesince.js
new file mode 100644
index 0000000000..4c392501d7
--- /dev/null
+++ b/extensions/permissions/test/unit/test_permmanager_removebytypesince.js
@@ -0,0 +1,89 @@
+/* Any copyright is dedicated to the Public Domain.
+ http://creativecommons.org/publicdomain/zero/1.0/ */
+
+add_task(async function test() {
+ Services.prefs.setCharPref("permissions.manager.defaultsUrl", "");
+
+ // initialize the permission manager service
+ let pm = Services.perms;
+
+ Assert.equal(pm.all.length, 0);
+
+ // add some permissions
+ let principal =
+ Services.scriptSecurityManager.createContentPrincipalFromOrigin(
+ "http://amazon.com:8080"
+ );
+ let principal2 =
+ Services.scriptSecurityManager.createContentPrincipalFromOrigin(
+ "http://google.com:2048"
+ );
+ let principal3 =
+ Services.scriptSecurityManager.createContentPrincipalFromOrigin(
+ "https://google.com"
+ );
+
+ pm.addFromPrincipal(principal, "apple", 3);
+ pm.addFromPrincipal(principal, "pear", 1);
+ pm.addFromPrincipal(principal, "cucumber", 1);
+
+ // sleep briefly, then record the time - we'll remove some permissions since then.
+ await new Promise(resolve => do_timeout(20, resolve));
+
+ let since = Date.now();
+
+ // *sob* - on Windows at least, the now recorded by PermissionManager.cpp
+ // might be a couple of ms *earlier* than what JS sees. So another sleep
+ // to ensure our |since| is greater than the time of the permissions we
+ // are now adding. Sadly this means we'll never be able to test when since
+ // exactly equals the modTime, but there you go...
+ await new Promise(resolve => do_timeout(20, resolve));
+
+ pm.addFromPrincipal(principal2, "apple", 2);
+ pm.addFromPrincipal(principal2, "pear", 2);
+
+ pm.addFromPrincipal(principal3, "cucumber", 3);
+ pm.addFromPrincipal(principal3, "apple", 1);
+
+ Assert.equal(pm.all.length, 7);
+
+ pm.removeByTypeSince("apple", since);
+
+ Assert.equal(pm.all.length, 5);
+
+ Assert.equal(pm.testPermissionFromPrincipal(principal, "pear"), 1);
+ Assert.equal(pm.testPermissionFromPrincipal(principal2, "pear"), 2);
+
+ Assert.equal(pm.testPermissionFromPrincipal(principal, "apple"), 3);
+ Assert.equal(pm.testPermissionFromPrincipal(principal2, "apple"), 0);
+ Assert.equal(pm.testPermissionFromPrincipal(principal3, "apple"), 0);
+
+ Assert.equal(pm.testPermissionFromPrincipal(principal, "cucumber"), 1);
+ Assert.equal(pm.testPermissionFromPrincipal(principal3, "cucumber"), 3);
+
+ pm.removeByTypeSince("cucumber", since);
+ Assert.equal(pm.all.length, 4);
+
+ Assert.equal(pm.testPermissionFromPrincipal(principal, "pear"), 1);
+ Assert.equal(pm.testPermissionFromPrincipal(principal2, "pear"), 2);
+
+ Assert.equal(pm.testPermissionFromPrincipal(principal, "apple"), 3);
+ Assert.equal(pm.testPermissionFromPrincipal(principal2, "apple"), 0);
+ Assert.equal(pm.testPermissionFromPrincipal(principal3, "apple"), 0);
+
+ Assert.equal(pm.testPermissionFromPrincipal(principal, "cucumber"), 1);
+ Assert.equal(pm.testPermissionFromPrincipal(principal3, "cucumber"), 0);
+
+ pm.removeByTypeSince("pear", since);
+ Assert.equal(pm.all.length, 3);
+
+ Assert.equal(pm.testPermissionFromPrincipal(principal, "pear"), 1);
+ Assert.equal(pm.testPermissionFromPrincipal(principal2, "pear"), 0);
+
+ Assert.equal(pm.testPermissionFromPrincipal(principal, "apple"), 3);
+ Assert.equal(pm.testPermissionFromPrincipal(principal2, "apple"), 0);
+ Assert.equal(pm.testPermissionFromPrincipal(principal3, "apple"), 0);
+
+ Assert.equal(pm.testPermissionFromPrincipal(principal, "cucumber"), 1);
+ Assert.equal(pm.testPermissionFromPrincipal(principal3, "cucumber"), 0);
+});
diff --git a/extensions/permissions/test/unit/test_permmanager_removepermission.js b/extensions/permissions/test/unit/test_permmanager_removepermission.js
new file mode 100644
index 0000000000..50b2c3105b
--- /dev/null
+++ b/extensions/permissions/test/unit/test_permmanager_removepermission.js
@@ -0,0 +1,58 @@
+/* Any copyright is dedicated to the Public Domain.
+ http://creativecommons.org/publicdomain/zero/1.0/ */
+
+function run_test() {
+ // initialize the permission manager service
+ let pm = Services.perms;
+
+ Assert.equal(pm.all.length, 0);
+
+ // add some permissions
+ let principal =
+ Services.scriptSecurityManager.createContentPrincipalFromOrigin(
+ "http://amazon.com:8080"
+ );
+ let principal2 =
+ Services.scriptSecurityManager.createContentPrincipalFromOrigin(
+ "http://google.com:2048"
+ );
+
+ pm.addFromPrincipal(principal, "apple", 0);
+ pm.addFromPrincipal(principal, "apple", 3);
+ pm.addFromPrincipal(principal, "pear", 3);
+ pm.addFromPrincipal(principal, "pear", 1);
+ pm.addFromPrincipal(principal, "cucumber", 1);
+ pm.addFromPrincipal(principal, "cucumber", 1);
+ pm.addFromPrincipal(principal, "cucumber", 1);
+
+ pm.addFromPrincipal(principal2, "apple", 2);
+ pm.addFromPrincipal(principal2, "pear", 0);
+ pm.addFromPrincipal(principal2, "pear", 2);
+
+ // Make sure that removePermission doesn't remove more than one permission each time
+ Assert.equal(pm.all.length, 5);
+
+ remove_one_by_type("apple");
+ Assert.equal(pm.all.length, 4);
+
+ remove_one_by_type("apple");
+ Assert.equal(pm.all.length, 3);
+
+ remove_one_by_type("pear");
+ Assert.equal(pm.all.length, 2);
+
+ remove_one_by_type("cucumber");
+ Assert.equal(pm.all.length, 1);
+
+ remove_one_by_type("pear");
+ Assert.equal(pm.all.length, 0);
+
+ function remove_one_by_type(type) {
+ for (let perm of pm.all) {
+ if (perm.type == type) {
+ pm.removePermission(perm);
+ break;
+ }
+ }
+ }
+}
diff --git a/extensions/permissions/test/unit/test_permmanager_removesince.js b/extensions/permissions/test/unit/test_permmanager_removesince.js
new file mode 100644
index 0000000000..c33d02b08b
--- /dev/null
+++ b/extensions/permissions/test/unit/test_permmanager_removesince.js
@@ -0,0 +1,83 @@
+/* Any copyright is dedicated to the Public Domain.
+ http://creativecommons.org/publicdomain/zero/1.0/ */
+
+// Test that removing permissions since a specified time behaves as expected.
+
+var test_generator = do_run_test();
+
+function run_test() {
+ do_test_pending();
+ test_generator.next();
+}
+
+function continue_test() {
+ do_run_generator(test_generator);
+}
+
+function* do_run_test() {
+ let pm = Services.perms;
+
+ // to help with testing edge-cases, we will arrange for .removeAllSince to
+ // remove *all* permissions from one principal and one permission from another.
+ let permURI1 = NetUtil.newURI("http://example.com");
+ let principal1 = Services.scriptSecurityManager.createContentPrincipal(
+ permURI1,
+ {}
+ );
+
+ let permURI2 = NetUtil.newURI("http://example.org");
+ let principal2 = Services.scriptSecurityManager.createContentPrincipal(
+ permURI2,
+ {}
+ );
+
+ // add a permission now - this isn't going to be removed.
+ pm.addFromPrincipal(principal1, "test/remove-since", 1);
+
+ // sleep briefly, then record the time - we'll remove all since then.
+ do_timeout(20, continue_test);
+ yield;
+
+ let since = Number(Date.now());
+
+ // *sob* - on Windows at least, the now recorded by PermissionManager.cpp
+ // might be a couple of ms *earlier* than what JS sees. So another sleep
+ // to ensure our |since| is greater than the time of the permissions we
+ // are now adding. Sadly this means we'll never be able to test when since
+ // exactly equals the modTime, but there you go...
+ do_timeout(20, continue_test);
+ yield;
+
+ // add another item - this second one should get nuked.
+ pm.addFromPrincipal(principal1, "test/remove-since-2", 1);
+
+ // add 2 items for the second principal - both will be removed.
+ pm.addFromPrincipal(principal2, "test/remove-since", 1);
+ pm.addFromPrincipal(principal2, "test/remove-since-2", 1);
+
+ // do the removal.
+ pm.removeAllSince(since);
+
+ // principal1 - the first one should remain.
+ Assert.equal(
+ 1,
+ pm.testPermissionFromPrincipal(principal1, "test/remove-since")
+ );
+ // but the second should have been removed.
+ Assert.equal(
+ 0,
+ pm.testPermissionFromPrincipal(principal1, "test/remove-since-2")
+ );
+
+ // principal2 - both should have been removed.
+ Assert.equal(
+ 0,
+ pm.testPermissionFromPrincipal(principal2, "test/remove-since")
+ );
+ Assert.equal(
+ 0,
+ pm.testPermissionFromPrincipal(principal2, "test/remove-since-2")
+ );
+
+ do_finish_generator_test(test_generator);
+}
diff --git a/extensions/permissions/test/unit/test_permmanager_site_scope.js b/extensions/permissions/test/unit/test_permmanager_site_scope.js
new file mode 100644
index 0000000000..2944fa2623
--- /dev/null
+++ b/extensions/permissions/test/unit/test_permmanager_site_scope.js
@@ -0,0 +1,116 @@
+const TEST_SITE_URI = Services.io.newURI("http://example.com");
+const TEST_FQDN_1_URI = Services.io.newURI("http://test1.example.com");
+const TEST_FQDN_2_URI = Services.io.newURI("http://test2.example.com");
+const TEST_OTHER_URI = Services.io.newURI("http://example.net");
+const TEST_PERMISSION = "3rdPartyStorage^https://example.org";
+
+add_task(async function do_test() {
+ let pm = Services.perms;
+
+ let principal = Services.scriptSecurityManager.createContentPrincipal(
+ TEST_SITE_URI,
+ {}
+ );
+
+ let subdomain1Principal =
+ Services.scriptSecurityManager.createContentPrincipal(TEST_FQDN_1_URI, {});
+
+ let subdomain2Principal =
+ Services.scriptSecurityManager.createContentPrincipal(TEST_FQDN_2_URI, {});
+
+ let otherPrincipal = Services.scriptSecurityManager.createContentPrincipal(
+ TEST_OTHER_URI,
+ {}
+ );
+
+ // Set test permission for site
+ pm.addFromPrincipal(principal, TEST_PERMISSION, pm.ALLOW_ACTION);
+
+ // Check normal site permission
+ Assert.equal(
+ Ci.nsIPermissionManager.ALLOW_ACTION,
+ pm.testPermissionFromPrincipal(principal, TEST_PERMISSION)
+ );
+
+ // Check subdomain permission
+ Assert.equal(
+ Ci.nsIPermissionManager.ALLOW_ACTION,
+ pm.testPermissionFromPrincipal(subdomain1Principal, TEST_PERMISSION)
+ );
+
+ // Check other site permission
+ Assert.equal(
+ Ci.nsIPermissionManager.UNKNOWN_ACTION,
+ pm.testPermissionFromPrincipal(otherPrincipal, TEST_PERMISSION)
+ );
+
+ // Remove the permission from the site
+ pm.removeFromPrincipal(principal, TEST_PERMISSION);
+ Assert.equal(
+ pm.testPermissionFromPrincipal(principal, TEST_PERMISSION),
+ Ci.nsIPermissionManager.UNKNOWN_ACTION
+ );
+ Assert.equal(
+ pm.testPermissionFromPrincipal(subdomain1Principal, TEST_PERMISSION),
+ Ci.nsIPermissionManager.UNKNOWN_ACTION
+ );
+
+ // Set test permission for subdomain
+ pm.addFromPrincipal(subdomain1Principal, TEST_PERMISSION, pm.ALLOW_ACTION);
+
+ // Check normal site permission
+ Assert.equal(
+ Ci.nsIPermissionManager.ALLOW_ACTION,
+ pm.testPermissionFromPrincipal(principal, TEST_PERMISSION)
+ );
+
+ // Check subdomain permission
+ Assert.equal(
+ Ci.nsIPermissionManager.ALLOW_ACTION,
+ pm.testPermissionFromPrincipal(subdomain1Principal, TEST_PERMISSION)
+ );
+
+ // Check other subdomain permission
+ Assert.equal(
+ Ci.nsIPermissionManager.ALLOW_ACTION,
+ pm.testPermissionFromPrincipal(subdomain2Principal, TEST_PERMISSION)
+ );
+
+ // Check other site permission
+ Assert.equal(
+ Ci.nsIPermissionManager.UNKNOWN_ACTION,
+ pm.testPermissionFromPrincipal(otherPrincipal, TEST_PERMISSION)
+ );
+
+ // Check that subdomains include the site-scoped in the getAllForPrincipal
+ let sitePerms = pm.getAllForPrincipal(principal, TEST_PERMISSION);
+ let subdomain1Perms = pm.getAllForPrincipal(
+ subdomain1Principal,
+ TEST_PERMISSION
+ );
+ let subdomain2Perms = pm.getAllForPrincipal(
+ subdomain2Principal,
+ TEST_PERMISSION
+ );
+ let otherSitePerms = pm.getAllForPrincipal(otherPrincipal, TEST_PERMISSION);
+
+ Assert.equal(sitePerms.length, 1);
+ Assert.equal(subdomain1Perms.length, 1);
+ Assert.equal(subdomain2Perms.length, 1);
+ Assert.equal(otherSitePerms.length, 0);
+
+ // Remove the permission from the subdomain
+ pm.removeFromPrincipal(subdomain1Principal, TEST_PERMISSION);
+ Assert.equal(
+ pm.testPermissionFromPrincipal(principal, TEST_PERMISSION),
+ Ci.nsIPermissionManager.UNKNOWN_ACTION
+ );
+ Assert.equal(
+ pm.testPermissionFromPrincipal(subdomain1Principal, TEST_PERMISSION),
+ Ci.nsIPermissionManager.UNKNOWN_ACTION
+ );
+ Assert.equal(
+ pm.testPermissionFromPrincipal(subdomain2Principal, TEST_PERMISSION),
+ Ci.nsIPermissionManager.UNKNOWN_ACTION
+ );
+});
diff --git a/extensions/permissions/test/unit/test_permmanager_subdomains.js b/extensions/permissions/test/unit/test_permmanager_subdomains.js
new file mode 100644
index 0000000000..4d30372332
--- /dev/null
+++ b/extensions/permissions/test/unit/test_permmanager_subdomains.js
@@ -0,0 +1,106 @@
+/* Any copyright is dedicated to the Public Domain.
+ http://creativecommons.org/publicdomain/zero/1.0/ */
+
+function getPrincipalFromURI(aURI) {
+ let ssm = Services.scriptSecurityManager;
+ let uri = NetUtil.newURI(aURI);
+ return ssm.createContentPrincipal(uri, {});
+}
+
+function run_test() {
+ var pm = Services.perms;
+
+ // Adds a permission to a sub-domain. Checks if it is working.
+ let sub1Principal = getPrincipalFromURI("http://sub1.example.com");
+ pm.addFromPrincipal(sub1Principal, "test/subdomains", pm.ALLOW_ACTION, 0, 0);
+ Assert.equal(
+ pm.testPermissionFromPrincipal(sub1Principal, "test/subdomains"),
+ pm.ALLOW_ACTION
+ );
+
+ // A sub-sub-domain should get the permission.
+ let subsubPrincipal = getPrincipalFromURI("http://sub.sub1.example.com");
+ Assert.equal(
+ pm.testPermissionFromPrincipal(subsubPrincipal, "test/subdomains"),
+ pm.ALLOW_ACTION
+ );
+
+ // Another sub-domain shouldn't get the permission.
+ let sub2Principal = getPrincipalFromURI("http://sub2.example.com");
+ Assert.equal(
+ pm.testPermissionFromPrincipal(sub2Principal, "test/subdomains"),
+ pm.UNKNOWN_ACTION
+ );
+
+ // Remove current permissions.
+ pm.removeFromPrincipal(sub1Principal, "test/subdomains");
+ Assert.equal(
+ pm.testPermissionFromPrincipal(sub1Principal, "test/subdomains"),
+ pm.UNKNOWN_ACTION
+ );
+
+ // Adding the permission to the main domain. Checks if it is working.
+ let mainPrincipal = getPrincipalFromURI("http://example.com");
+ pm.addFromPrincipal(mainPrincipal, "test/subdomains", pm.ALLOW_ACTION, 0, 0);
+ Assert.equal(
+ pm.testPermissionFromPrincipal(mainPrincipal, "test/subdomains"),
+ pm.ALLOW_ACTION
+ );
+
+ // All sub-domains should have the permission now.
+ Assert.equal(
+ pm.testPermissionFromPrincipal(sub1Principal, "test/subdomains"),
+ pm.ALLOW_ACTION
+ );
+ Assert.equal(
+ pm.testPermissionFromPrincipal(sub2Principal, "test/subdomains"),
+ pm.ALLOW_ACTION
+ );
+ Assert.equal(
+ pm.testPermissionFromPrincipal(subsubPrincipal, "test/subdomains"),
+ pm.ALLOW_ACTION
+ );
+
+ // Remove current permissions.
+ pm.removeFromPrincipal(mainPrincipal, "test/subdomains");
+ Assert.equal(
+ pm.testPermissionFromPrincipal(mainPrincipal, "test/subdomains"),
+ pm.UNKNOWN_ACTION
+ );
+ Assert.equal(
+ pm.testPermissionFromPrincipal(sub1Principal, "test/subdomains"),
+ pm.UNKNOWN_ACTION
+ );
+ Assert.equal(
+ pm.testPermissionFromPrincipal(sub2Principal, "test/subdomains"),
+ pm.UNKNOWN_ACTION
+ );
+ Assert.equal(
+ pm.testPermissionFromPrincipal(subsubPrincipal, "test/subdomains"),
+ pm.UNKNOWN_ACTION
+ );
+
+ // A sanity check that the previous implementation wasn't passing...
+ let crazyPrincipal = getPrincipalFromURI("http://com");
+ pm.addFromPrincipal(crazyPrincipal, "test/subdomains", pm.ALLOW_ACTION, 0, 0);
+ Assert.equal(
+ pm.testPermissionFromPrincipal(crazyPrincipal, "test/subdomains"),
+ pm.ALLOW_ACTION
+ );
+ Assert.equal(
+ pm.testPermissionFromPrincipal(mainPrincipal, "test/subdomains"),
+ pm.UNKNOWN_ACTION
+ );
+ Assert.equal(
+ pm.testPermissionFromPrincipal(sub1Principal, "test/subdomains"),
+ pm.UNKNOWN_ACTION
+ );
+ Assert.equal(
+ pm.testPermissionFromPrincipal(sub2Principal, "test/subdomains"),
+ pm.UNKNOWN_ACTION
+ );
+ Assert.equal(
+ pm.testPermissionFromPrincipal(subsubPrincipal, "test/subdomains"),
+ pm.UNKNOWN_ACTION
+ );
+}
diff --git a/extensions/permissions/test/unit/xpcshell.ini b/extensions/permissions/test/unit/xpcshell.ini
new file mode 100644
index 0000000000..294d7c47a3
--- /dev/null
+++ b/extensions/permissions/test/unit/xpcshell.ini
@@ -0,0 +1,60 @@
+[DEFAULT]
+head = head.js
+
+[test_permmanager_default_pref.js]
+[test_permmanager_defaults.js]
+[test_permmanager_expiration.js]
+skip-if =
+ win10_2004 # Bug 1718292
+ win10_2009 # Bug 1718292
+ win11_2009 # Bug 1797751
+ os == "win" && os_version == "6.1" # Skip on Azure - frequent failure
+[test_permmanager_getAllByTypes.js]
+[test_permmanager_getAllByTypeSince.js]
+[test_permmanager_getAllForPrincipal.js]
+[test_permmanager_getAllWithTypePrefix.js]
+[test_permmanager_getPermissionObject.js]
+[test_permmanager_notifications.js]
+[test_permmanager_removeall.js]
+[test_permmanager_removebytype.js]
+[test_permmanager_removebytypesince.js]
+[test_permmanager_removesince.js]
+[test_permmanager_load_invalid_entries.js]
+skip-if = debug == true
+[test_permmanager_idn.js]
+[test_permmanager_subdomains.js]
+[test_permmanager_local_files.js]
+[test_permmanager_cleardata.js]
+[test_permmanager_removepermission.js]
+[test_permmanager_matchesuri.js]
+[test_permmanager_matches.js]
+[test_permmanager_migrate_4-7.js]
+skip-if = toolkit == 'android' # Android doesn't use places
+[test_permmanager_migrate_5-7a.js]
+skip-if = toolkit == 'android' # Android doesn't use places
+[test_permmanager_migrate_5-7b.js]
+skip-if = toolkit == 'android' # Android doesn't use places
+[test_permmanager_migrate_6-7a.js]
+skip-if = toolkit == 'android' # Android doesn't use places
+[test_permmanager_migrate_6-7b.js]
+skip-if = toolkit == 'android' # Android doesn't use places
+[test_permmanager_migrate_4-7_no_history.js]
+skip-if =
+ apple_silicon || toolkit == 'android' # Disabled due to bleedover with other tests when run in regular suites; passes in "failures" jobs
+[test_permmanager_migrate_7-8.js]
+skip-if = toolkit == 'android' # Android doesn't use places
+[test_permmanager_migrate_9-10.js]
+skip-if = toolkit == 'android' # Android doesn't use places
+[test_permmanager_migrate_10-11.js]
+skip-if = toolkit == 'android' # Android doesn't use places
+[test_permmanager_migrate_11-12.js]
+skip-if = toolkit == 'android' # Android doesn't use places
+[test_permmanager_oa_strip.js]
+[test_permmanager_site_scope.js]
+[test_permmanager_remove_add_update.js]
+skip-if = win10_2004 && bits == 64 # Bug 1718292
+[test_permmanager_ipc.js]
+# This test is meant to run on a multi process mode
+# and with file urls loaded in their own child process.
+skip-if = !e10s
+firefox-appdir = browser
diff --git a/extensions/pref/autoconfig/moz.build b/extensions/pref/autoconfig/moz.build
new file mode 100644
index 0000000000..a8292ea733
--- /dev/null
+++ b/extensions/pref/autoconfig/moz.build
@@ -0,0 +1,11 @@
+# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
+# vim: set filetype=python:
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+DIRS += ["src"]
+
+XPCSHELL_TESTS_MANIFESTS += ["test/unit/xpcshell.ini", "test/unit/xpcshell_snap.ini"]
+
+MARIONETTE_UNIT_MANIFESTS += ["test/marionette/manifest.ini"]
diff --git a/extensions/pref/autoconfig/src/components.conf b/extensions/pref/autoconfig/src/components.conf
new file mode 100644
index 0000000000..41de352694
--- /dev/null
+++ b/extensions/pref/autoconfig/src/components.conf
@@ -0,0 +1,21 @@
+# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
+# vim: set filetype=python:
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+Classes = [
+ {
+ 'cid': '{ba5bc4c6-1dd1-11b2-bb89-b844c6ec0339}',
+ 'contract_ids': ['@mozilla.org/readconfig;1'],
+ 'type': 'nsReadConfig',
+ 'headers': ['/extensions/pref/autoconfig/src/nsReadConfig.h'],
+ 'init_method': 'Init',
+ 'categories': {
+ 'pref-config-startup': {
+ 'name': 'ReadConfig Module',
+ 'backgroundtasks': BackgroundTasksSelector.ALL_TASKS,
+ },
+ },
+ },
+]
diff --git a/extensions/pref/autoconfig/src/moz.build b/extensions/pref/autoconfig/src/moz.build
new file mode 100644
index 0000000000..12722cf6d7
--- /dev/null
+++ b/extensions/pref/autoconfig/src/moz.build
@@ -0,0 +1,21 @@
+# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
+# vim: set filetype=python:
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+UNIFIED_SOURCES += [
+ "nsAutoConfig.cpp",
+ "nsJSConfigTriggers.cpp",
+ "nsReadConfig.cpp",
+]
+
+XPCOM_MANIFESTS += [
+ "components.conf",
+]
+
+FINAL_LIBRARY = "xul"
+
+FINAL_TARGET_FILES.defaults.autoconfig += [
+ "prefcalls.js",
+]
diff --git a/extensions/pref/autoconfig/src/nsAutoConfig.cpp b/extensions/pref/autoconfig/src/nsAutoConfig.cpp
new file mode 100644
index 0000000000..907d4b7646
--- /dev/null
+++ b/extensions/pref/autoconfig/src/nsAutoConfig.cpp
@@ -0,0 +1,464 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "mozilla/ResultExtensions.h"
+#include "nsAutoConfig.h"
+#include "nsJSConfigTriggers.h"
+
+#include "nsIURI.h"
+#include "nsIHttpChannel.h"
+#include "nsThreadUtils.h"
+#include "nsAppDirectoryServiceDefs.h"
+#include "nsIObserverService.h"
+#include "nsLiteralString.h"
+#include "nsIPromptService.h"
+#include "nsIInputStream.h"
+#include "nsIOutputStream.h"
+#include "nsIPrefBranch.h"
+#include "nsIPrefService.h"
+#include "nsIStringBundle.h"
+#include "nsContentUtils.h"
+#include "nsCRT.h"
+#include "nsNetCID.h"
+#include "nsNetUtil.h"
+#include "nspr.h"
+#include <algorithm>
+
+#include "mozilla/IntegerPrintfMacros.h"
+#include "mozilla/Logging.h"
+#include "mozilla/SpinEventLoopUntil.h"
+
+using mozilla::LogLevel;
+
+mozilla::LazyLogModule MCD("MCD");
+
+// nsISupports Implementation
+
+NS_IMPL_ISUPPORTS(nsAutoConfig, nsITimerCallback, nsIStreamListener,
+ nsIObserver, nsIRequestObserver, nsISupportsWeakReference,
+ nsINamed)
+
+nsAutoConfig::nsAutoConfig() {}
+
+nsresult nsAutoConfig::Init() {
+ // member initializers and constructor code
+
+ nsresult rv;
+ mLoaded = false;
+
+ // Registering the object as an observer to the profile-after-change topic
+ nsCOMPtr<nsIObserverService> observerService =
+ do_GetService("@mozilla.org/observer-service;1", &rv);
+ if (NS_FAILED(rv)) return rv;
+
+ rv = observerService->AddObserver(this, "profile-after-change", true);
+
+ return rv;
+}
+
+nsAutoConfig::~nsAutoConfig() {}
+
+void nsAutoConfig::SetConfigURL(const char* aConfigURL) {
+ mConfigURL.Assign(aConfigURL);
+}
+
+NS_IMETHODIMP
+nsAutoConfig::OnStartRequest(nsIRequest* request) { return NS_OK; }
+
+NS_IMETHODIMP
+nsAutoConfig::OnDataAvailable(nsIRequest* request, nsIInputStream* aIStream,
+ uint64_t aSourceOffset, uint32_t aLength) {
+ uint32_t amt, size;
+ nsresult rv;
+ char buf[1024];
+
+ while (aLength) {
+ size = std::min<size_t>(aLength, sizeof(buf));
+ rv = aIStream->Read(buf, size, &amt);
+ if (NS_FAILED(rv)) return rv;
+ mBuf.Append(buf, amt);
+ aLength -= amt;
+ }
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsAutoConfig::OnStopRequest(nsIRequest* request, nsresult aStatus) {
+ nsresult rv;
+
+ // If the request is failed, go read the failover.jsc file
+ if (NS_FAILED(aStatus)) {
+ MOZ_LOG(MCD, LogLevel::Debug,
+ ("mcd request failed with status %" PRIx32 "\n",
+ static_cast<uint32_t>(aStatus)));
+ return readOfflineFile();
+ }
+
+ // Checking for the http response, if failure go read the failover file.
+ nsCOMPtr<nsIHttpChannel> pHTTPCon(do_QueryInterface(request));
+ if (pHTTPCon) {
+ uint32_t httpStatus;
+ rv = pHTTPCon->GetResponseStatus(&httpStatus);
+ if (NS_FAILED(rv) || httpStatus != 200) {
+ MOZ_LOG(MCD, LogLevel::Debug,
+ ("mcd http request failed with status %x\n", httpStatus));
+ return readOfflineFile();
+ }
+ }
+
+ // Send the autoconfig.jsc to javascript engine.
+
+ rv = EvaluateAdminConfigScript(mBuf.get(), mBuf.Length(), nullptr, false,
+ true, false);
+ if (NS_SUCCEEDED(rv)) {
+ // Write the autoconfig.jsc to failover.jsc (cached copy)
+ rv = writeFailoverFile();
+
+ if (NS_FAILED(rv)) NS_WARNING("Error writing failover.jsc file");
+
+ // Releasing the lock to allow the main thread to start execution
+ mLoaded = true;
+
+ return NS_OK;
+ }
+ // there is an error in parsing of the autoconfig file.
+ NS_WARNING(
+ "Error reading autoconfig.jsc from the network, reading the offline "
+ "version");
+ return readOfflineFile();
+}
+
+// Notify method as a TimerCallBack function
+NS_IMETHODIMP nsAutoConfig::Notify(nsITimer* timer) {
+ downloadAutoConfig();
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsAutoConfig::GetName(nsACString& aName) {
+ aName.AssignLiteral("nsAutoConfig");
+ return NS_OK;
+}
+
+/* Observe() is called twice: once at the instantiation time and other
+ after the profile is set. It doesn't do anything but return NS_OK during the
+ creation time. Second time it calls downloadAutoConfig().
+*/
+
+NS_IMETHODIMP nsAutoConfig::Observe(nsISupports* aSubject, const char* aTopic,
+ const char16_t* someData) {
+ nsresult rv = NS_OK;
+ if (!nsCRT::strcmp(aTopic, "profile-after-change")) {
+ // We will be calling downloadAutoConfig even if there is no profile
+ // name. Nothing will be passed as a parameter to the URL and the
+ // default case will be picked up by the script.
+
+ rv = downloadAutoConfig();
+ }
+
+ return rv;
+}
+
+nsresult nsAutoConfig::downloadAutoConfig() {
+ nsresult rv;
+ nsAutoCString emailAddr;
+ static bool firstTime = true;
+
+ if (mConfigURL.IsEmpty()) {
+ MOZ_LOG(MCD, LogLevel::Debug,
+ ("global config url is empty - did you set "
+ "autoadmin.global_config_url?\n"));
+ NS_WARNING("AutoConfig called without global_config_url");
+ return NS_OK;
+ }
+
+ // If there is an email address appended as an argument to the ConfigURL
+ // in the previous read, we need to remove it when timer kicks in and
+ // downloads the autoconfig file again.
+ // If necessary, the email address will be added again as an argument.
+ int32_t index = mConfigURL.RFindChar((char16_t)'?');
+ if (index != -1) mConfigURL.Truncate(index);
+
+ // Clean up the previous read, the new read is going to use the same buffer
+ if (!mBuf.IsEmpty()) mBuf.Truncate(0);
+
+ // Get the preferences branch and save it to the member variable
+ if (!mPrefBranch) {
+ nsCOMPtr<nsIPrefService> prefs =
+ do_GetService(NS_PREFSERVICE_CONTRACTID, &rv);
+ if (NS_FAILED(rv)) return rv;
+
+ rv = prefs->GetBranch(nullptr, getter_AddRefs(mPrefBranch));
+ if (NS_FAILED(rv)) return rv;
+ }
+
+ // Check to see if the network is online/offline
+ nsCOMPtr<nsIIOService> ios = do_GetService(NS_IOSERVICE_CONTRACTID, &rv);
+ if (NS_FAILED(rv)) return rv;
+
+ bool offline;
+ rv = ios->GetOffline(&offline);
+ if (NS_FAILED(rv)) return rv;
+
+ if (offline) {
+ bool offlineFailover;
+ rv = mPrefBranch->GetBoolPref("autoadmin.offline_failover",
+ &offlineFailover);
+ // Read the failover.jsc if the network is offline and the pref says so
+ if (NS_SUCCEEDED(rv) && offlineFailover) return readOfflineFile();
+ }
+
+ /* Append user's identity at the end of the URL if the pref says so.
+ First we are checking for the user's email address but if it is not
+ available in the case where the client is used without messenger, user's
+ profile name will be used as an unique identifier
+ */
+ bool appendMail;
+ rv = mPrefBranch->GetBoolPref("autoadmin.append_emailaddr", &appendMail);
+ if (NS_SUCCEEDED(rv) && appendMail) {
+ rv = getEmailAddr(emailAddr);
+ if (NS_SUCCEEDED(rv) && emailAddr.get()) {
+ /* Adding the unique identifier at the end of autoconfig URL.
+ In this case the autoconfig URL is a script and
+ emailAddr as passed as an argument
+ */
+ mConfigURL.Append('?');
+ mConfigURL.Append(emailAddr);
+ }
+ }
+
+ // create a new url
+ nsCOMPtr<nsIURI> url;
+ nsCOMPtr<nsIChannel> channel;
+
+ rv = NS_NewURI(getter_AddRefs(url), mConfigURL);
+ if (NS_FAILED(rv)) {
+ MOZ_LOG(
+ MCD, LogLevel::Debug,
+ ("failed to create URL - is autoadmin.global_config_url valid? - %s\n",
+ mConfigURL.get()));
+ return rv;
+ }
+
+ MOZ_LOG(MCD, LogLevel::Debug, ("running MCD url %s\n", mConfigURL.get()));
+ // open a channel for the url
+ rv = NS_NewChannel(
+ getter_AddRefs(channel), url, nsContentUtils::GetSystemPrincipal(),
+ nsILoadInfo::SEC_ALLOW_CROSS_ORIGIN_SEC_CONTEXT_IS_NULL,
+ nsIContentPolicy::TYPE_OTHER,
+ nullptr, // nsICookieJarSettings
+ nullptr, // PerformanceStorage
+ nullptr, // loadGroup
+ nullptr, // aCallbacks
+ nsIRequest::INHIBIT_PERSISTENT_CACHING | nsIRequest::LOAD_BYPASS_CACHE);
+
+ if (NS_FAILED(rv)) return rv;
+
+ rv = channel->AsyncOpen(this);
+ if (NS_FAILED(rv)) {
+ readOfflineFile();
+ return rv;
+ }
+
+ // Set a repeating timer if the pref is set.
+ // This is to be done only once.
+ // Also We are having the event queue processing only for the startup
+ // It is not needed with the repeating timer.
+ if (firstTime) {
+ firstTime = false;
+
+ /* process events until we're finished. AutoConfig.jsc reading needs
+ to be finished before the browser starts loading up
+ We are waiting for the mLoaded which will be set through
+ onStopRequest or readOfflineFile methods
+ There is a possibility of deadlock so we need to make sure
+ that mLoaded will be set to true in any case (success/failure)
+ */
+
+ if (!mozilla::SpinEventLoopUntil("nsAutoConfig::downloadAutoConfig"_ns,
+ [&]() { return mLoaded; })) {
+ return NS_ERROR_FAILURE;
+ }
+
+ int32_t minutes;
+ rv = mPrefBranch->GetIntPref("autoadmin.refresh_interval", &minutes);
+ if (NS_SUCCEEDED(rv) && minutes > 0) {
+ // Create a new timer and pass this nsAutoConfig
+ // object as a timer callback.
+ MOZ_TRY_VAR(mTimer,
+ NS_NewTimerWithCallback(this, minutes * 60 * 1000,
+ nsITimer::TYPE_REPEATING_SLACK));
+ }
+ } // first_time
+
+ return NS_OK;
+} // nsPref::downloadAutoConfig()
+
+nsresult nsAutoConfig::readOfflineFile() {
+ nsresult rv;
+
+ /* Releasing the lock to allow main thread to start
+ execution. At this point we do not need to stall
+ the thread since all network activities are done.
+ */
+ mLoaded = true;
+
+ bool failCache;
+ rv = mPrefBranch->GetBoolPref("autoadmin.failover_to_cached", &failCache);
+ if (NS_SUCCEEDED(rv) && !failCache) {
+ // disable network connections and return.
+
+ nsCOMPtr<nsIIOService> ios = do_GetService(NS_IOSERVICE_CONTRACTID, &rv);
+ if (NS_FAILED(rv)) return rv;
+
+ bool offline;
+ rv = ios->GetOffline(&offline);
+ if (NS_FAILED(rv)) return rv;
+
+ if (!offline) {
+ rv = ios->SetOffline(true);
+ if (NS_FAILED(rv)) return rv;
+ }
+
+ // lock the "network.online" prference so user cannot toggle back to
+ // online mode.
+ rv = mPrefBranch->SetBoolPref("network.online", false);
+ if (NS_FAILED(rv)) return rv;
+
+ mPrefBranch->LockPref("network.online");
+ return NS_OK;
+ }
+
+ /* faiover_to_cached is set to true so
+ Open the file and read the content.
+ execute the javascript file
+ */
+
+ nsCOMPtr<nsIFile> failoverFile;
+ rv = NS_GetSpecialDirectory(NS_APP_USER_PROFILE_50_DIR,
+ getter_AddRefs(failoverFile));
+ if (NS_FAILED(rv)) return rv;
+
+ failoverFile->AppendNative("failover.jsc"_ns);
+ rv = evaluateLocalFile(failoverFile);
+ if (NS_FAILED(rv))
+ NS_WARNING("Couldn't open failover.jsc, going back to default prefs");
+ return NS_OK;
+}
+
+nsresult nsAutoConfig::evaluateLocalFile(nsIFile* file) {
+ nsresult rv;
+ nsCOMPtr<nsIInputStream> inStr;
+
+ rv = NS_NewLocalFileInputStream(getter_AddRefs(inStr), file);
+ if (NS_FAILED(rv)) return rv;
+
+ int64_t fileSize;
+ file->GetFileSize(&fileSize);
+ uint32_t fs = fileSize; // Converting 64 bit structure to unsigned int
+ char* buf = (char*)malloc(fs * sizeof(char));
+ if (!buf) return NS_ERROR_OUT_OF_MEMORY;
+
+ uint32_t amt = 0;
+ rv = inStr->Read(buf, fs, &amt);
+ if (NS_SUCCEEDED(rv)) {
+ EvaluateAdminConfigScript(buf, fs, nullptr, false, true, false);
+ }
+ inStr->Close();
+ free(buf);
+ return rv;
+}
+
+nsresult nsAutoConfig::writeFailoverFile() {
+ nsresult rv;
+ nsCOMPtr<nsIFile> failoverFile;
+ nsCOMPtr<nsIOutputStream> outStr;
+ uint32_t amt;
+
+ rv = NS_GetSpecialDirectory(NS_APP_USER_PROFILE_50_DIR,
+ getter_AddRefs(failoverFile));
+ if (NS_FAILED(rv)) return rv;
+
+ failoverFile->AppendNative("failover.jsc"_ns);
+
+ rv = NS_NewLocalFileOutputStream(getter_AddRefs(outStr), failoverFile);
+ if (NS_FAILED(rv)) return rv;
+ rv = outStr->Write(mBuf.get(), mBuf.Length(), &amt);
+ outStr->Close();
+ return rv;
+}
+
+nsresult nsAutoConfig::getEmailAddr(nsACString& emailAddr) {
+ nsresult rv;
+ nsAutoCString prefValue;
+
+ /* Getting an email address through set of three preferences:
+ First getting a default account with
+ "mail.accountmanager.defaultaccount"
+ second getting an associated id with the default account
+ Third getting an email address with id
+ */
+
+ rv =
+ mPrefBranch->GetCharPref("mail.accountmanager.defaultaccount", prefValue);
+ if (NS_SUCCEEDED(rv) && !prefValue.IsEmpty()) {
+ emailAddr = "mail.account."_ns + prefValue + ".identities"_ns;
+ rv = mPrefBranch->GetCharPref(PromiseFlatCString(emailAddr).get(),
+ prefValue);
+ if (NS_FAILED(rv) || prefValue.IsEmpty())
+ return PromptForEMailAddress(emailAddr);
+ int32_t commandIndex = prefValue.FindChar(',');
+ if (commandIndex != kNotFound) prefValue.Truncate(commandIndex);
+ emailAddr = "mail.identity."_ns + prefValue + ".useremail"_ns;
+ rv = mPrefBranch->GetCharPref(PromiseFlatCString(emailAddr).get(),
+ prefValue);
+ if (NS_FAILED(rv) || prefValue.IsEmpty())
+ return PromptForEMailAddress(emailAddr);
+ emailAddr = prefValue;
+ } else {
+ // look for 4.x pref in case we just migrated.
+ rv = mPrefBranch->GetCharPref("mail.identity.useremail", prefValue);
+ if (NS_SUCCEEDED(rv) && !prefValue.IsEmpty())
+ emailAddr = prefValue;
+ else
+ PromptForEMailAddress(emailAddr);
+ }
+
+ return NS_OK;
+}
+
+nsresult nsAutoConfig::PromptForEMailAddress(nsACString& emailAddress) {
+ nsresult rv;
+ nsCOMPtr<nsIPromptService> promptService =
+ do_GetService("@mozilla.org/prompter;1", &rv);
+ NS_ENSURE_SUCCESS(rv, rv);
+ nsCOMPtr<nsIStringBundleService> bundleService =
+ do_GetService(NS_STRINGBUNDLE_CONTRACTID, &rv);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ nsCOMPtr<nsIStringBundle> bundle;
+ rv = bundleService->CreateBundle(
+ "chrome://autoconfig/locale/autoconfig.properties",
+ getter_AddRefs(bundle));
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ nsAutoString title;
+ rv = bundle->GetStringFromName("emailPromptTitle", title);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ nsAutoString err;
+ rv = bundle->GetStringFromName("emailPromptMsg", err);
+ NS_ENSURE_SUCCESS(rv, rv);
+ bool check = false;
+ nsString emailResult;
+ bool success;
+ rv = promptService->Prompt(nullptr, title.get(), err.get(),
+ getter_Copies(emailResult), nullptr, &check,
+ &success);
+ if (!success) return NS_ERROR_FAILURE;
+ NS_ENSURE_SUCCESS(rv, rv);
+ LossyCopyUTF16toASCII(emailResult, emailAddress);
+ return NS_OK;
+}
diff --git a/extensions/pref/autoconfig/src/nsAutoConfig.h b/extensions/pref/autoconfig/src/nsAutoConfig.h
new file mode 100644
index 0000000000..3a78239286
--- /dev/null
+++ b/extensions/pref/autoconfig/src/nsAutoConfig.h
@@ -0,0 +1,54 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef nsAutoConfig_h
+#define nsAutoConfig_h
+
+#include "nsITimer.h"
+#include "nsIFile.h"
+#include "nsINamed.h"
+#include "nsIObserver.h"
+#include "nsIStreamListener.h"
+#include "nsWeakReference.h"
+#include "nsString.h"
+
+class nsIPrefBranch;
+
+class nsAutoConfig final : public nsITimerCallback,
+ public nsIStreamListener,
+ public nsIObserver,
+ public nsSupportsWeakReference,
+ public nsINamed
+
+{
+ public:
+ NS_DECL_THREADSAFE_ISUPPORTS
+ NS_DECL_NSIREQUESTOBSERVER
+ NS_DECL_NSISTREAMLISTENER
+ NS_DECL_NSIOBSERVER
+ NS_DECL_NSITIMERCALLBACK
+ NS_DECL_NSINAMED
+
+ nsAutoConfig();
+ nsresult Init();
+
+ void SetConfigURL(const char* aConfigURL);
+
+ protected:
+ virtual ~nsAutoConfig();
+ nsresult downloadAutoConfig();
+ nsresult readOfflineFile();
+ nsresult evaluateLocalFile(nsIFile* file);
+ nsresult writeFailoverFile();
+ nsresult getEmailAddr(nsACString& emailAddr);
+ nsresult PromptForEMailAddress(nsACString& emailAddress);
+ nsCString mBuf;
+ nsCOMPtr<nsIPrefBranch> mPrefBranch;
+ bool mLoaded;
+ nsCOMPtr<nsITimer> mTimer;
+ nsCString mConfigURL;
+};
+
+#endif
diff --git a/extensions/pref/autoconfig/src/nsJSConfigTriggers.cpp b/extensions/pref/autoconfig/src/nsJSConfigTriggers.cpp
new file mode 100644
index 0000000000..e0b4324f40
--- /dev/null
+++ b/extensions/pref/autoconfig/src/nsJSConfigTriggers.cpp
@@ -0,0 +1,170 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "nsJSConfigTriggers.h"
+
+#include "jsapi.h"
+#include "nsIXPConnect.h"
+#include "nsCOMPtr.h"
+#include "nsString.h"
+#include "nspr.h"
+#include "mozilla/Attributes.h"
+#include "mozilla/Maybe.h"
+#include "mozilla/NullPrincipal.h"
+#include "mozilla/dom/ScriptSettings.h"
+#include "mozilla/dom/ChromeUtilsBinding.h"
+#include "nsContentUtils.h"
+#include "nsJSPrincipals.h"
+#include "nsIScriptError.h"
+#include "js/PropertyAndElement.h" // JS_DefineProperty
+#include "js/Wrapper.h"
+#include "mozilla/Utf8.h"
+
+extern mozilla::LazyLogModule MCD;
+using mozilla::AutoSafeJSContext;
+using mozilla::IsUtf8;
+using mozilla::NullPrincipal;
+using mozilla::dom::AutoJSAPI;
+
+//*****************************************************************************
+
+static JS::PersistentRooted<JSObject*> autoconfigSystemSb;
+static JS::PersistentRooted<JSObject*> autoconfigSb;
+bool sandboxEnabled;
+
+nsresult CentralizedAdminPrefManagerInit(bool aSandboxEnabled) {
+ // If the sandbox is already created, no need to create it again.
+ if (autoconfigSb.initialized()) return NS_OK;
+
+ sandboxEnabled = aSandboxEnabled;
+
+ // Grab XPConnect.
+ nsCOMPtr<nsIXPConnect> xpc = nsIXPConnect::XPConnect();
+
+ // Grab the system principal.
+ nsCOMPtr<nsIPrincipal> principal;
+ nsContentUtils::GetSecurityManager()->GetSystemPrincipal(
+ getter_AddRefs(principal));
+
+ // Create a sandbox.
+ AutoSafeJSContext cx;
+ JS::Rooted<JSObject*> sandbox(cx);
+ nsresult rv = xpc->CreateSandbox(cx, principal, sandbox.address());
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ // Unwrap, store and root the sandbox.
+ NS_ENSURE_STATE(sandbox);
+ autoconfigSystemSb.init(cx, js::UncheckedUnwrap(sandbox));
+
+ // Create an unprivileged sandbox.
+ principal = NullPrincipal::CreateWithoutOriginAttributes();
+ rv = xpc->CreateSandbox(cx, principal, sandbox.address());
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ autoconfigSb.init(cx, js::UncheckedUnwrap(sandbox));
+
+ // Define gSandbox on system sandbox.
+ JSAutoRealm ar(cx, autoconfigSystemSb);
+
+ JS::Rooted<JS::Value> value(cx, JS::ObjectValue(*sandbox));
+
+ if (!JS_WrapValue(cx, &value) ||
+ !JS_DefineProperty(cx, autoconfigSystemSb, "gSandbox", value,
+ JSPROP_ENUMERATE)) {
+ return NS_ERROR_FAILURE;
+ }
+
+ // Define ChromeUtils for ChromeUtils.import.
+ if (!mozilla::dom::ChromeUtils_Binding::GetConstructorObject(cx)) {
+ return NS_ERROR_FAILURE;
+ }
+
+ return NS_OK;
+}
+
+nsresult CentralizedAdminPrefManagerFinish() {
+ if (autoconfigSb.initialized()) {
+ AutoSafeJSContext cx;
+ autoconfigSb.reset();
+ autoconfigSystemSb.reset();
+ JS_MaybeGC(cx);
+ }
+ return NS_OK;
+}
+
+nsresult EvaluateAdminConfigScript(const char* js_buffer, size_t length,
+ const char* filename, bool globalContext,
+ bool callbacks, bool skipFirstLine,
+ bool isPrivileged) {
+ if (!sandboxEnabled) {
+ isPrivileged = true;
+ }
+ return EvaluateAdminConfigScript(
+ isPrivileged ? autoconfigSystemSb : autoconfigSb, js_buffer, length,
+ filename, globalContext, callbacks, skipFirstLine);
+}
+
+nsresult EvaluateAdminConfigScript(JS::Handle<JSObject*> sandbox,
+ const char* js_buffer, size_t length,
+ const char* filename, bool globalContext,
+ bool callbacks, bool skipFirstLine) {
+ if (skipFirstLine) {
+ /* In order to protect the privacy of the JavaScript preferences file
+ * from loading by the browser, we make the first line unparseable
+ * by JavaScript. We must skip that line here before executing
+ * the JavaScript code.
+ */
+ unsigned int i = 0;
+ while (i < length) {
+ char c = js_buffer[i++];
+ if (c == '\r') {
+ if (js_buffer[i] == '\n') i++;
+ break;
+ }
+ if (c == '\n') break;
+ }
+
+ length -= i;
+ js_buffer += i;
+ }
+
+ // Grab XPConnect.
+ nsCOMPtr<nsIXPConnect> xpc = nsIXPConnect::XPConnect();
+
+ AutoJSAPI jsapi;
+ if (!jsapi.Init(sandbox)) {
+ return NS_ERROR_UNEXPECTED;
+ }
+ JSContext* cx = jsapi.cx();
+
+ nsAutoCString script(js_buffer, length);
+ JS::Rooted<JS::Value> v(cx);
+
+ nsString convertedScript;
+ bool isUTF8 = IsUtf8(script);
+ if (isUTF8) {
+ CopyUTF8toUTF16(script, convertedScript);
+ } else {
+ nsContentUtils::ReportToConsoleNonLocalized(
+ nsLiteralString(
+ u"Your AutoConfig file is ASCII. Please convert it to UTF-8."),
+ nsIScriptError::warningFlag, "autoconfig"_ns, nullptr);
+ /* If the length is 0, the conversion failed. Fallback to ASCII */
+ convertedScript = NS_ConvertASCIItoUTF16(script);
+ }
+ {
+ JSAutoRealm ar(cx, autoconfigSystemSb);
+ JS::Rooted<JS::Value> value(cx, JS::BooleanValue(isUTF8));
+ if (!JS_DefineProperty(cx, autoconfigSystemSb, "gIsUTF8", value,
+ JSPROP_ENUMERATE)) {
+ return NS_ERROR_UNEXPECTED;
+ }
+ }
+ nsresult rv =
+ xpc->EvalInSandboxObject(convertedScript, filename, cx, sandbox, &v);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ return NS_OK;
+}
diff --git a/extensions/pref/autoconfig/src/nsJSConfigTriggers.h b/extensions/pref/autoconfig/src/nsJSConfigTriggers.h
new file mode 100644
index 0000000000..1f7c3804b9
--- /dev/null
+++ b/extensions/pref/autoconfig/src/nsJSConfigTriggers.h
@@ -0,0 +1,23 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef nsConfigTriggers_h
+#define nsConfigTriggers_h
+
+#include "nscore.h"
+#include "js/TypeDecls.h"
+
+nsresult EvaluateAdminConfigScript(const char* js_buffer, size_t length,
+ const char* filename, bool bGlobalContext,
+ bool bCallbacks, bool skipFirstLine,
+ bool isPrivileged = false);
+
+nsresult EvaluateAdminConfigScript(JS::Handle<JSObject*> sandbox,
+ const char* js_buffer, size_t length,
+ const char* filename, bool bGlobalContext,
+ bool bCallbacks, bool skipFirstLine);
+
+#endif // nsConfigTriggers_h
diff --git a/extensions/pref/autoconfig/src/nsReadConfig.cpp b/extensions/pref/autoconfig/src/nsReadConfig.cpp
new file mode 100644
index 0000000000..3da68faac6
--- /dev/null
+++ b/extensions/pref/autoconfig/src/nsReadConfig.cpp
@@ -0,0 +1,312 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "nsReadConfig.h"
+#include "nsJSConfigTriggers.h"
+
+#include "mozilla/Logging.h"
+#include "mozilla/Components.h"
+#include "nsAppDirectoryServiceDefs.h"
+#include "nsIAppStartup.h"
+#include "nsIChannel.h"
+#include "nsContentUtils.h"
+#include "nsDirectoryServiceDefs.h"
+#include "nsIFile.h"
+#include "nsIInputStream.h"
+#include "nsIObserverService.h"
+#include "nsIPrefBranch.h"
+#include "nsIPrefService.h"
+#include "nsIPromptService.h"
+#include "nsIStringBundle.h"
+#include "nsNetUtil.h"
+#include "nsString.h"
+#include "nsCRT.h"
+#include "nspr.h"
+#include "nsXULAppAPI.h"
+
+#if defined(MOZ_WIDGET_GTK)
+# include "mozilla/WidgetUtilsGtk.h"
+#endif // defined(MOZ_WIDGET_GTK)
+
+using namespace mozilla;
+
+extern bool sandboxEnabled;
+
+extern mozilla::LazyLogModule MCD;
+
+extern nsresult CentralizedAdminPrefManagerInit(bool aSandboxEnabled);
+extern nsresult CentralizedAdminPrefManagerFinish();
+
+static nsresult DisplayError(void) {
+ nsresult rv;
+
+ nsCOMPtr<nsIPromptService> promptService =
+ do_GetService("@mozilla.org/prompter;1");
+ if (!promptService) return NS_ERROR_FAILURE;
+
+ nsCOMPtr<nsIStringBundleService> bundleService =
+ do_GetService(NS_STRINGBUNDLE_CONTRACTID);
+ if (!bundleService) return NS_ERROR_FAILURE;
+
+ nsCOMPtr<nsIStringBundle> bundle;
+ bundleService->CreateBundle(
+ "chrome://autoconfig/locale/autoconfig.properties",
+ getter_AddRefs(bundle));
+ if (!bundle) return NS_ERROR_FAILURE;
+
+ nsAutoString title;
+ rv = bundle->GetStringFromName("readConfigTitle", title);
+ if (NS_FAILED(rv)) return rv;
+
+ nsAutoString err;
+ rv = bundle->GetStringFromName("readConfigMsg", err);
+ if (NS_FAILED(rv)) return rv;
+
+ return promptService->Alert(nullptr, title.get(), err.get());
+}
+
+// nsISupports Implementation
+
+NS_IMPL_ISUPPORTS(nsReadConfig, nsIObserver)
+
+nsReadConfig::nsReadConfig() : mRead(false) {}
+
+nsresult nsReadConfig::Init() {
+ nsresult rv;
+
+ nsCOMPtr<nsIObserverService> observerService =
+ do_GetService("@mozilla.org/observer-service;1", &rv);
+
+ if (observerService) {
+ rv =
+ observerService->AddObserver(this, NS_PREFSERVICE_READ_TOPIC_ID, false);
+ }
+ return (rv);
+}
+
+nsReadConfig::~nsReadConfig() { CentralizedAdminPrefManagerFinish(); }
+
+NS_IMETHODIMP nsReadConfig::Observe(nsISupports* aSubject, const char* aTopic,
+ const char16_t* someData) {
+ nsresult rv = NS_OK;
+
+ if (!nsCRT::strcmp(aTopic, NS_PREFSERVICE_READ_TOPIC_ID)) {
+ rv = readConfigFile();
+ // Don't show error alerts if the sandbox is enabled, just show
+ // sandbox warning.
+ if (NS_FAILED(rv)) {
+ if (sandboxEnabled) {
+ nsContentUtils::ReportToConsoleNonLocalized(
+ u"Autoconfig is sandboxed by default. See "
+ "https://support.mozilla.org/products/"
+ "firefox-enterprise for more information."_ns,
+ nsIScriptError::warningFlag, "autoconfig"_ns, nullptr);
+ } else {
+ rv = DisplayError();
+ if (NS_FAILED(rv)) {
+ nsCOMPtr<nsIAppStartup> appStartup =
+ components::AppStartup::Service();
+ if (appStartup) {
+ bool userAllowedQuit = true;
+ appStartup->Quit(nsIAppStartup::eAttemptQuit, 0, &userAllowedQuit);
+ }
+ }
+ }
+ }
+ }
+ return rv;
+}
+
+/**
+ * This is the blocklist for known bad autoconfig files.
+ */
+static const char* gBlockedConfigs[] = {"dsengine.cfg"};
+
+nsresult nsReadConfig::readConfigFile() {
+ nsresult rv = NS_OK;
+ nsAutoCString lockFileName;
+ nsAutoCString lockVendor;
+ uint32_t fileNameLen = 0;
+
+ nsCOMPtr<nsIPrefBranch> defaultPrefBranch;
+ nsCOMPtr<nsIPrefService> prefService =
+ do_GetService(NS_PREFSERVICE_CONTRACTID, &rv);
+ if (NS_FAILED(rv)) return rv;
+
+ rv =
+ prefService->GetDefaultBranch(nullptr, getter_AddRefs(defaultPrefBranch));
+ if (NS_FAILED(rv)) return rv;
+
+ constexpr auto channel = nsLiteralCString{MOZ_STRINGIFY(MOZ_UPDATE_CHANNEL)};
+
+ bool sandboxEnabled =
+ channel.EqualsLiteral("beta") || channel.EqualsLiteral("release");
+
+ mozilla::Unused << defaultPrefBranch->GetBoolPref(
+ "general.config.sandbox_enabled", &sandboxEnabled);
+
+ rv = defaultPrefBranch->GetCharPref("general.config.filename", lockFileName);
+
+ if (NS_FAILED(rv)) return rv;
+
+ MOZ_LOG(MCD, LogLevel::Debug,
+ ("general.config.filename = %s\n", lockFileName.get()));
+
+ for (size_t index = 0, len = mozilla::ArrayLength(gBlockedConfigs);
+ index < len; ++index) {
+ if (lockFileName == gBlockedConfigs[index]) {
+ // This is NS_OK because we don't want to show an error to the user
+ return rv;
+ }
+ }
+
+ // This needs to be read only once.
+ //
+ if (!mRead) {
+ // Initiate the new JS Context for Preference management
+
+ rv = CentralizedAdminPrefManagerInit(sandboxEnabled);
+ if (NS_FAILED(rv)) return rv;
+
+ // Open and evaluate function calls to set/lock/unlock prefs
+ rv = openAndEvaluateJSFile("prefcalls.js", 0, false, false);
+ if (NS_FAILED(rv)) return rv;
+
+ mRead = true;
+ }
+ // If the lockFileName is nullptr return ok, because no lockFile will be used
+
+ // Once the config file is read, we should check that the vendor name
+ // is consistent By checking for the vendor name after reading the config
+ // file we allow for the preference to be set (and locked) by the creator
+ // of the cfg file meaning the file can not be renamed (successfully).
+
+ nsCOMPtr<nsIPrefBranch> prefBranch;
+ rv = prefService->GetBranch(nullptr, getter_AddRefs(prefBranch));
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ int32_t obscureValue = 0;
+ (void)defaultPrefBranch->GetIntPref("general.config.obscure_value",
+ &obscureValue);
+ MOZ_LOG(MCD, LogLevel::Debug,
+ ("evaluating .cfg file %s with obscureValue %d\n", lockFileName.get(),
+ obscureValue));
+ rv = openAndEvaluateJSFile(lockFileName.get(), obscureValue, true, true);
+ if (NS_FAILED(rv)) {
+ MOZ_LOG(MCD, LogLevel::Debug,
+ ("error evaluating .cfg file %s %" PRIx32 "\n", lockFileName.get(),
+ static_cast<uint32_t>(rv)));
+ return rv;
+ }
+
+ rv = prefBranch->GetCharPref("general.config.filename", lockFileName);
+ if (NS_FAILED(rv))
+ // There is NO REASON we should ever get here. This is POST reading
+ // of the config file.
+ return NS_ERROR_FAILURE;
+
+ rv = prefBranch->GetCharPref("general.config.vendor", lockVendor);
+ // If vendor is not nullptr, do this check
+ if (NS_SUCCEEDED(rv)) {
+ fileNameLen = strlen(lockFileName.get());
+
+ // lockVendor and lockFileName should be the same with the addtion of
+ // .cfg to the filename by checking this post reading of the cfg file
+ // this value can be set within the cfg file adding a level of security.
+
+ if (strncmp(lockFileName.get(), lockVendor.get(), fileNameLen - 4) != 0) {
+ return NS_ERROR_FAILURE;
+ }
+ }
+
+ // get the value of the autoconfig url
+ nsAutoCString urlName;
+ rv = prefBranch->GetCharPref("autoadmin.global_config_url", urlName);
+ if (NS_SUCCEEDED(rv) && !urlName.IsEmpty()) {
+ // Instantiating nsAutoConfig object if the pref is present
+ mAutoConfig = new nsAutoConfig();
+
+ rv = mAutoConfig->Init();
+ if (NS_WARN_IF(NS_FAILED(rv))) {
+ return rv;
+ }
+
+ mAutoConfig->SetConfigURL(urlName.get());
+ }
+
+ return NS_OK;
+} // ReadConfigFile
+
+nsresult nsReadConfig::openAndEvaluateJSFile(const char* aFileName,
+ int32_t obscureValue,
+ bool isEncoded, bool isBinDir) {
+ nsresult rv;
+
+ nsCOMPtr<nsIInputStream> inStr;
+ if (isBinDir) {
+ nsCOMPtr<nsIFile> jsFile;
+#if defined(MOZ_WIDGET_GTK)
+ if (!mozilla::widget::IsRunningUnderFlatpakOrSnap()) {
+#endif // defined(MOZ_WIDGET_GTK)
+ rv = NS_GetSpecialDirectory(NS_GRE_DIR, getter_AddRefs(jsFile));
+#if defined(MOZ_WIDGET_GTK)
+ } else {
+ rv = NS_GetSpecialDirectory(NS_OS_SYSTEM_CONFIG_DIR,
+ getter_AddRefs(jsFile));
+ }
+#endif // defined(MOZ_WIDGET_GTK)
+ if (NS_FAILED(rv)) return rv;
+
+ rv = jsFile->AppendNative(nsDependentCString(aFileName));
+ if (NS_FAILED(rv)) return rv;
+
+ rv = NS_NewLocalFileInputStream(getter_AddRefs(inStr), jsFile);
+ if (NS_FAILED(rv)) return rv;
+
+ } else {
+ nsAutoCString location("resource://gre/defaults/autoconfig/");
+ location += aFileName;
+
+ nsCOMPtr<nsIURI> uri;
+ rv = NS_NewURI(getter_AddRefs(uri), location);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ nsCOMPtr<nsIChannel> channel;
+ rv = NS_NewChannel(getter_AddRefs(channel), uri,
+ nsContentUtils::GetSystemPrincipal(),
+ nsILoadInfo::SEC_ALLOW_CROSS_ORIGIN_SEC_CONTEXT_IS_NULL,
+ nsIContentPolicy::TYPE_OTHER);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ rv = channel->Open(getter_AddRefs(inStr));
+ NS_ENSURE_SUCCESS(rv, rv);
+ }
+
+ uint64_t fs64;
+ uint32_t amt = 0;
+ rv = inStr->Available(&fs64);
+ if (NS_FAILED(rv)) return rv;
+ // This used to use PR_Malloc(), which doesn't support over 4GB.
+ if (fs64 > UINT32_MAX) return NS_ERROR_FILE_TOO_BIG;
+ uint32_t fs = (uint32_t)fs64;
+
+ char* buf = (char*)malloc(fs * sizeof(char));
+ if (!buf) return NS_ERROR_OUT_OF_MEMORY;
+
+ rv = inStr->Read(buf, (uint32_t)fs, &amt);
+ NS_ASSERTION((amt == fs), "failed to read the entire configuration file!!");
+ if (NS_SUCCEEDED(rv)) {
+ if (obscureValue > 0) {
+ // Unobscure file by subtracting some value from every char.
+ for (uint32_t i = 0; i < amt; i++) buf[i] -= obscureValue;
+ }
+ rv = EvaluateAdminConfigScript(buf, amt, aFileName, false, true, isEncoded,
+ !isBinDir);
+ }
+ inStr->Close();
+ free(buf);
+
+ return rv;
+}
diff --git a/extensions/pref/autoconfig/src/nsReadConfig.h b/extensions/pref/autoconfig/src/nsReadConfig.h
new file mode 100644
index 0000000000..465a517186
--- /dev/null
+++ b/extensions/pref/autoconfig/src/nsReadConfig.h
@@ -0,0 +1,34 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef nsReadConfig_h
+#define nsReadConfig_h
+
+#include "mozilla/RefPtr.h"
+#include "nsAutoConfig.h"
+#include "nsIObserver.h"
+
+class nsReadConfig final : public nsIObserver {
+ public:
+ NS_DECL_THREADSAFE_ISUPPORTS
+ NS_DECL_NSIOBSERVER
+
+ nsReadConfig();
+
+ nsresult Init();
+
+ protected:
+ virtual ~nsReadConfig();
+
+ nsresult readConfigFile();
+ nsresult openAndEvaluateJSFile(const char* aFileName, int32_t obscureValue,
+ bool isEncoded, bool isBinDir);
+ bool mRead;
+
+ private:
+ RefPtr<nsAutoConfig> mAutoConfig;
+};
+
+#endif
diff --git a/extensions/pref/autoconfig/src/prefcalls.js b/extensions/pref/autoconfig/src/prefcalls.js
new file mode 100644
index 0000000000..b66e5df898
--- /dev/null
+++ b/extensions/pref/autoconfig/src/prefcalls.js
@@ -0,0 +1,225 @@
+/* global processLDAPValues */
+/* -*- tab-width: 4; indent-tabs-mode: nil; js-indent-level: 4 -*-
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+/* globals gSandbox */
+
+const LDAPSyncQueryContractID = "@mozilla.org/ldapsyncquery;1";
+
+var gVersion;
+var gIsUTF8;
+
+function getPrefBranch() {
+ return Services.prefs.getBranch(null);
+}
+
+function pref(prefName, value) {
+ try {
+ var prefBranch = getPrefBranch();
+
+ if (typeof value == "string") {
+ if (gIsUTF8) {
+ prefBranch.setStringPref(prefName, value);
+ return;
+ }
+ prefBranch.setCharPref(prefName, value);
+ } else if (typeof value == "number") {
+ prefBranch.setIntPref(prefName, value);
+ } else if (typeof value == "boolean") {
+ prefBranch.setBoolPref(prefName, value);
+ }
+ } catch (e) {
+ displayError("pref", e);
+ }
+}
+
+function defaultPref(prefName, value) {
+ try {
+ var prefBranch = Services.prefs.getDefaultBranch(null);
+ if (typeof value == "string") {
+ if (gIsUTF8) {
+ prefBranch.setStringPref(prefName, value);
+ return;
+ }
+ prefBranch.setCharPref(prefName, value);
+ } else if (typeof value == "number") {
+ prefBranch.setIntPref(prefName, value);
+ } else if (typeof value == "boolean") {
+ prefBranch.setBoolPref(prefName, value);
+ }
+ } catch (e) {
+ displayError("defaultPref", e);
+ }
+}
+
+function lockPref(prefName, value) {
+ try {
+ var prefBranch = getPrefBranch();
+
+ if (prefBranch.prefIsLocked(prefName)) {
+ prefBranch.unlockPref(prefName);
+ }
+
+ defaultPref(prefName, value);
+
+ prefBranch.lockPref(prefName);
+ } catch (e) {
+ displayError("lockPref", e);
+ }
+}
+
+function unlockPref(prefName) {
+ try {
+ var prefBranch = getPrefBranch();
+ prefBranch.unlockPref(prefName);
+ } catch (e) {
+ displayError("unlockPref", e);
+ }
+}
+
+function getPref(prefName) {
+ try {
+ var prefBranch = getPrefBranch();
+
+ switch (prefBranch.getPrefType(prefName)) {
+ case prefBranch.PREF_STRING:
+ if (gIsUTF8) {
+ return prefBranch.getStringPref(prefName);
+ }
+ return prefBranch.getCharPref(prefName);
+
+ case prefBranch.PREF_INT:
+ return prefBranch.getIntPref(prefName);
+
+ case prefBranch.PREF_BOOL:
+ return prefBranch.getBoolPref(prefName);
+ default:
+ return null;
+ }
+ } catch (e) {
+ displayError("getPref", e);
+ }
+ return undefined;
+}
+
+function clearPref(prefName) {
+ try {
+ var prefBranch = getPrefBranch();
+ prefBranch.clearUserPref(prefName);
+ } catch (e) {}
+}
+
+function setLDAPVersion(version) {
+ gVersion = version;
+}
+
+function getLDAPAttributes(host, base, filter, attribs, isSecure) {
+ try {
+ var urlSpec =
+ "ldap" +
+ (isSecure ? "s" : "") +
+ "://" +
+ host +
+ (isSecure ? ":636" : "") +
+ "/" +
+ base +
+ "?" +
+ attribs +
+ "?sub?" +
+ filter;
+
+ // nsILDAP* are only defined in comm-central.
+ // eslint-disable-next-line mozilla/valid-ci-uses
+ var url = Services.io.newURI(urlSpec).QueryInterface(Ci.nsILDAPURL);
+
+ var ldapquery = Cc[LDAPSyncQueryContractID].createInstance(
+ // eslint-disable-next-line mozilla/valid-ci-uses
+ Ci.nsILDAPSyncQuery
+ );
+ // default to LDAP v3
+ if (!gVersion) {
+ // eslint-disable-next-line mozilla/valid-ci-uses
+ gVersion = Ci.nsILDAPConnection.VERSION3;
+ }
+ // user supplied method
+ if ("processLDAPValues" in gSandbox) {
+ gSandbox.processLDAPValues(ldapquery.getQueryResults(url, gVersion));
+ } else {
+ processLDAPValues(ldapquery.getQueryResults(url, gVersion));
+ }
+ } catch (e) {
+ displayError("getLDAPAttributes", e);
+ }
+}
+
+function getLDAPValue(str, key) {
+ try {
+ if (str == null || key == null) {
+ return null;
+ }
+
+ var search_key = "\n" + key + "=";
+
+ var start_pos = str.indexOf(search_key);
+ if (start_pos == -1) {
+ return null;
+ }
+
+ start_pos += search_key.length;
+
+ var end_pos = str.indexOf("\n", start_pos);
+ if (end_pos == -1) {
+ end_pos = str.length;
+ }
+
+ return str.substring(start_pos, end_pos);
+ } catch (e) {
+ displayError("getLDAPValue", e);
+ }
+ return undefined;
+}
+
+function displayError(funcname, message) {
+ try {
+ var bundle = Services.strings.createBundle(
+ "chrome://autoconfig/locale/autoconfig.properties"
+ );
+
+ var title = bundle.GetStringFromName("autoConfigTitle");
+ var msg = bundle.formatStringFromName("autoConfigMsg", [funcname]);
+ Services.prompt.alert(null, title, msg + " " + message);
+ } catch (e) {}
+}
+
+function getenv(name) {
+ try {
+ return Services.env.get(name);
+ } catch (e) {
+ displayError("getEnvironment", e);
+ }
+ return undefined;
+}
+
+var APIs = {
+ pref,
+ defaultPref,
+ lockPref,
+ unlockPref,
+ getPref,
+ clearPref,
+ setLDAPVersion,
+ getLDAPAttributes,
+ getLDAPValue,
+ displayError,
+ getenv,
+};
+
+for (let [defineAs, func] of Object.entries(APIs)) {
+ Cu.exportFunction(func, gSandbox, { defineAs });
+}
+
+Object.defineProperty(Cu.waiveXrays(gSandbox), "gIsUTF8", {
+ get: Cu.exportFunction(() => gIsUTF8, gSandbox),
+});
diff --git a/extensions/pref/autoconfig/test/marionette/autoconfig.cfg b/extensions/pref/autoconfig/test/marionette/autoconfig.cfg
new file mode 100644
index 0000000000..1e6fde18bf
--- /dev/null
+++ b/extensions/pref/autoconfig/test/marionette/autoconfig.cfg
@@ -0,0 +1,18 @@
+// # don't remove this comment! (the first line is ignored by Mozilla)
+
+// Verify this one has a user value
+pref("_autoconfig_.test.userpref", "userpref");
+
+// Verify this one has a default pref
+defaultPref("_autoconfig_.test.defaultpref", "defaultpref");
+
+// Verify this one is locked
+lockPref("_autoconfig_.test.lockpref", "lockpref");
+
+lockPref("_autoconfig_.test.unlockpref", "unlockpref");
+// Verify this one is unlocked
+unlockPref("_autoconfig_.test.unlockpref");
+
+pref("_autoconfig_.test.clearpref", "clearpref");
+// Verify this one has no value
+clearPref("_autoconfig_.test.clearpref");
diff --git a/extensions/pref/autoconfig/test/marionette/autoconfig.js b/extensions/pref/autoconfig/test/marionette/autoconfig.js
new file mode 100644
index 0000000000..c891c5d108
--- /dev/null
+++ b/extensions/pref/autoconfig/test/marionette/autoconfig.js
@@ -0,0 +1,5 @@
+/* global pref */
+pref("general.config.sandbox_enabled", true);
+pref("general.config.filename", "autoconfig.cfg");
+pref("general.config.vendor", "autoconfig");
+pref("general.config.obscure_value", 0);
diff --git a/extensions/pref/autoconfig/test/marionette/manifest.ini b/extensions/pref/autoconfig/test/marionette/manifest.ini
new file mode 100644
index 0000000000..c10c20c2ae
--- /dev/null
+++ b/extensions/pref/autoconfig/test/marionette/manifest.ini
@@ -0,0 +1 @@
+[test_autoconfig.py]
diff --git a/extensions/pref/autoconfig/test/marionette/test_autoconfig.py b/extensions/pref/autoconfig/test/marionette/test_autoconfig.py
new file mode 100644
index 0000000000..0cdc0feede
--- /dev/null
+++ b/extensions/pref/autoconfig/test/marionette/test_autoconfig.py
@@ -0,0 +1,101 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+import os
+import shutil
+
+from marionette_harness import MarionetteTestCase
+
+
+class TestAutoConfig(MarionetteTestCase):
+ def tearDown(self):
+ self.marionette.quit(in_app=False, clean=True)
+
+ if hasattr(self, "pref_file"):
+ os.remove(self.pref_file)
+ if hasattr(self, "autoconfig_file"):
+ os.remove(self.autoconfig_file)
+
+ super(TestAutoConfig, self).tearDown()
+
+ def pref_has_user_value(self, pref):
+ with self.marionette.using_context("chrome"):
+ return self.marionette.execute_script(
+ """
+ return Services.prefs.prefHasUserValue(arguments[0]);
+ """,
+ script_args=(pref,),
+ )
+
+ def pref_is_locked(self, pref):
+ with self.marionette.using_context("chrome"):
+ return self.marionette.execute_script(
+ """
+ return Services.prefs.prefIsLocked(arguments[0]);
+ """,
+ script_args=(pref,),
+ )
+
+ def test_autoconfig(self):
+ with self.marionette.using_context("chrome"):
+ self.exe_dir = self.marionette.execute_script(
+ """
+ return Services.dirsvc.get("GreD", Ci.nsIFile).path;
+ """
+ )
+
+ self.marionette.quit()
+
+ test_dir = os.path.dirname(__file__)
+ self.pref_file = os.path.join(self.exe_dir, "defaults", "pref", "autoconfig.js")
+ shutil.copyfile(os.path.join(test_dir, "autoconfig.js"), self.pref_file)
+ self.autoconfig_file = os.path.join(self.exe_dir, "autoconfig.cfg")
+ shutil.copyfile(os.path.join(test_dir, "autoconfig.cfg"), self.autoconfig_file)
+
+ self.marionette.start_session()
+
+ with self.marionette.using_context("chrome"):
+ self.assertTrue(
+ self.pref_has_user_value("_autoconfig_.test.userpref"),
+ "Pref should have user value",
+ )
+
+ self.assertEqual(
+ self.marionette.get_pref("_autoconfig_.test.userpref"),
+ "userpref",
+ "User pref should be set",
+ )
+
+ self.assertEqual(
+ self.marionette.get_pref("_autoconfig_.test.defaultpref", True),
+ "defaultpref",
+ "Default pref should be set",
+ )
+
+ self.assertTrue(
+ self.pref_is_locked("_autoconfig_.test.lockpref"),
+ "Pref should be locked",
+ )
+
+ self.assertEqual(
+ self.marionette.get_pref("_autoconfig_.test.lockpref"),
+ "lockpref",
+ "Locked pref should be set",
+ )
+
+ self.assertFalse(
+ self.pref_is_locked("_autoconfig_.test.unlockpref"),
+ "Pref should be unlocked",
+ )
+
+ self.assertEqual(
+ self.marionette.get_pref("_autoconfig_.test.unlockpref"),
+ "unlockpref",
+ "Unlocked pref should be set",
+ )
+
+ self.assertFalse(
+ self.pref_has_user_value("_autoconfig_.test.clearpref"),
+ "Pref should be cleared",
+ )
diff --git a/extensions/pref/autoconfig/test/unit/autoconfig-all.cfg b/extensions/pref/autoconfig/test/unit/autoconfig-all.cfg
new file mode 100644
index 0000000000..f636c3ec22
--- /dev/null
+++ b/extensions/pref/autoconfig/test/unit/autoconfig-all.cfg
@@ -0,0 +1,31 @@
+// # don't remove this comment! (the first line is ignored by Mozilla)
+
+// Verify this one has a user value
+pref("_autoconfig_.test.userpref", "userpref");
+
+// Verify this one has a default pref
+defaultPref("_autoconfig_.test.defaultpref", "defaultpref");
+
+// Verify this one is locked
+lockPref("_autoconfig_.test.lockpref", "lockpref");
+
+lockPref("_autoconfig_.test.unlockpref", "unlockpref");
+// Verify this one is unlocked
+unlockPref("_autoconfig_.test.unlockpref");
+
+pref("_autoconfig_.test.clearpref", "clearpref");
+// Verify this one has no value
+clearPref("_autoconfig_.test.clearpref");
+
+// Verify this one is set to the correct value
+pref("_autoconfig_.test.getpref.query", "getpref");
+pref("_autoconfig_.test.getpref", getPref("_autoconfig_.test.getpref.query"));
+
+// Verify this one is set to the correct value
+pref("_autoconfig_.test.getenv", getenv("AUTOCONFIG_TEST_GETENV"));
+
+// Since we can't test displayError directly, verify that it
+// exists and is a function
+pref("_autoconfig_.test.displayerror", typeof(displayError));
+
+// We are not getPrefBranch because it is being removed
diff --git a/extensions/pref/autoconfig/test/unit/autoconfig-chromecheck.cfg b/extensions/pref/autoconfig/test/unit/autoconfig-chromecheck.cfg
new file mode 100644
index 0000000000..2af6cfc109
--- /dev/null
+++ b/extensions/pref/autoconfig/test/unit/autoconfig-chromecheck.cfg
@@ -0,0 +1,5 @@
+// # don't remove this comment! (the first line is ignored by Mozilla)
+
+lockPref("_test.string.typeofComponents", typeof Components);
+lockPref("_test.string.typeofChromeUtils", typeof ChromeUtils);
+lockPref("_test.string.typeofServices", typeof Services);
diff --git a/extensions/pref/autoconfig/test/unit/autoconfig-latin1.cfg b/extensions/pref/autoconfig/test/unit/autoconfig-latin1.cfg
new file mode 100644
index 0000000000..6b96c65fd0
--- /dev/null
+++ b/extensions/pref/autoconfig/test/unit/autoconfig-latin1.cfg
@@ -0,0 +1,6 @@
+// # don't remove this comment! (the first line is ignored by Mozilla)
+//
+lockPref("_test.string.ASCII", "ASCII");
+lockPref("_test.string.non-ASCII", "ユ茯");
+lockPref("_test.string.getPref", getPref("_test.string.non-ASCII"));
+lockPref("_test.string.gIsUTF8", String(this.gIsUTF8));
diff --git a/extensions/pref/autoconfig/test/unit/autoconfig-no-sandbox-check.cfg b/extensions/pref/autoconfig/test/unit/autoconfig-no-sandbox-check.cfg
new file mode 100644
index 0000000000..a39080562f
--- /dev/null
+++ b/extensions/pref/autoconfig/test/unit/autoconfig-no-sandbox-check.cfg
@@ -0,0 +1,5 @@
+// # don't remove this comment! (the first line is ignored by Mozilla)
+
+lockPref("_test.typeof_Components", typeof Components);
+lockPref("_test.typeof_ChromeUtils", typeof ChromeUtils);
+lockPref("_test.typeof_Services", typeof Services);
diff --git a/extensions/pref/autoconfig/test/unit/autoconfig-no-sandbox.js b/extensions/pref/autoconfig/test/unit/autoconfig-no-sandbox.js
new file mode 100644
index 0000000000..a53b53dfb6
--- /dev/null
+++ b/extensions/pref/autoconfig/test/unit/autoconfig-no-sandbox.js
@@ -0,0 +1,5 @@
+/* global pref */
+pref("general.config.sandbox_enabled", false);
+pref("general.config.filename", "autoconfig.cfg");
+pref("general.config.vendor", "autoconfig");
+pref("general.config.obscure_value", 0);
diff --git a/extensions/pref/autoconfig/test/unit/autoconfig-snap.cfg b/extensions/pref/autoconfig/test/unit/autoconfig-snap.cfg
new file mode 100644
index 0000000000..c5c67bfbb7
--- /dev/null
+++ b/extensions/pref/autoconfig/test/unit/autoconfig-snap.cfg
@@ -0,0 +1,4 @@
+// # don't remove this comment! (the first line is ignored by Mozilla)
+
+// Verify this one has a user value
+pref("_autoconfig_.test.userpref-snap", "userpref-snap");
diff --git a/extensions/pref/autoconfig/test/unit/autoconfig-utf8.cfg b/extensions/pref/autoconfig/test/unit/autoconfig-utf8.cfg
new file mode 100644
index 0000000000..eec7899420
--- /dev/null
+++ b/extensions/pref/autoconfig/test/unit/autoconfig-utf8.cfg
@@ -0,0 +1,6 @@
+// # don't remove this comment! (the first line is ignored by Mozilla)
+
+lockPref("_test.string.ASCII", "UTF-8");
+lockPref("_test.string.non-ASCII", "ユ茯");
+lockPref("_test.string.getPref", getPref("_test.string.non-ASCII"));
+lockPref("_test.string.gIsUTF8", String(this.gIsUTF8));
diff --git a/extensions/pref/autoconfig/test/unit/autoconfig.js b/extensions/pref/autoconfig/test/unit/autoconfig.js
new file mode 100644
index 0000000000..c891c5d108
--- /dev/null
+++ b/extensions/pref/autoconfig/test/unit/autoconfig.js
@@ -0,0 +1,5 @@
+/* global pref */
+pref("general.config.sandbox_enabled", true);
+pref("general.config.filename", "autoconfig.cfg");
+pref("general.config.vendor", "autoconfig");
+pref("general.config.obscure_value", 0);
diff --git a/extensions/pref/autoconfig/test/unit/autoconfig_snap.js b/extensions/pref/autoconfig/test/unit/autoconfig_snap.js
new file mode 100644
index 0000000000..bfa1df4859
--- /dev/null
+++ b/extensions/pref/autoconfig/test/unit/autoconfig_snap.js
@@ -0,0 +1,5 @@
+/* global pref */
+pref("general.config.sandbox_enabled", true);
+pref("general.config.filename", "autoconfig-snap.cfg");
+pref("general.config.vendor", "autoconfig-snap");
+pref("general.config.obscure_value", 0);
diff --git a/extensions/pref/autoconfig/test/unit/test_autoconfig.js b/extensions/pref/autoconfig/test/unit/test_autoconfig.js
new file mode 100644
index 0000000000..60284c4544
--- /dev/null
+++ b/extensions/pref/autoconfig/test/unit/test_autoconfig.js
@@ -0,0 +1,83 @@
+/* Any copyright is dedicated to the Public Domain.
+ http://creativecommons.org/publicdomain/zero/1.0/ */
+
+/* eslint no-unsafe-finally: "off"*/
+/* Turning off this rule to allow control flow operations in finally block
+ * http://eslint.org/docs/rules/no-unsafe-finally */
+
+function run_test() {
+ let prefs = Services.prefs.getBranch(null);
+ let defPrefs = Services.prefs.getDefaultBranch(null);
+
+ let greD = Services.dirsvc.get("GreD", Ci.nsIFile);
+ let defaultPrefD = Services.dirsvc.get("PrfDef", Ci.nsIFile);
+ let testDir = do_get_cwd();
+
+ try {
+ let autoConfigJS = testDir.clone();
+ autoConfigJS.append("autoconfig.js");
+ autoConfigJS.copyTo(defaultPrefD, "autoconfig.js");
+
+ // Make sure nsReadConfig is initialized.
+ Cc["@mozilla.org/readconfig;1"].getService(Ci.nsISupports);
+ Services.prefs.resetPrefs();
+
+ let autoConfigCfg = testDir.clone();
+ autoConfigCfg.append("autoconfig-all.cfg");
+ autoConfigCfg.copyTo(greD, "autoconfig.cfg");
+
+ Services.env.set("AUTOCONFIG_TEST_GETENV", "getenv");
+
+ Services.obs.notifyObservers(
+ Services.prefs,
+ "prefservice:before-read-userprefs"
+ );
+
+ ok(prefs.prefHasUserValue("_autoconfig_.test.userpref"));
+ equal("userpref", prefs.getStringPref("_autoconfig_.test.userpref"));
+
+ equal(
+ "defaultpref",
+ defPrefs.getStringPref("_autoconfig_.test.defaultpref")
+ );
+ equal("defaultpref", prefs.getStringPref("_autoconfig_.test.defaultpref"));
+
+ ok(prefs.prefIsLocked("_autoconfig_.test.lockpref"));
+ equal("lockpref", prefs.getStringPref("_autoconfig_.test.lockpref"));
+
+ ok(!prefs.prefIsLocked("_autoconfig_.test.unlockpref"));
+ equal("unlockpref", prefs.getStringPref("_autoconfig_.test.unlockpref"));
+
+ ok(!prefs.prefHasUserValue("_autoconfig_.test.clearpref"));
+
+ equal("getpref", prefs.getStringPref("_autoconfig_.test.getpref"));
+
+ equal("getenv", prefs.getStringPref("_autoconfig_.test.getenv"));
+
+ equal("function", prefs.getStringPref("_autoconfig_.test.displayerror"));
+
+ Services.prefs.resetPrefs();
+ } finally {
+ try {
+ let autoConfigJS = defaultPrefD.clone();
+ autoConfigJS.append("autoconfig.js");
+ autoConfigJS.remove(false);
+ } catch (e) {
+ if (e.result != Cr.NS_ERROR_FILE_NOT_FOUND) {
+ throw e;
+ }
+ }
+
+ try {
+ let autoConfigCfg = greD.clone();
+ autoConfigCfg.append("autoconfig.cfg");
+ autoConfigCfg.remove(false);
+ } catch (e) {
+ if (e.result != Cr.NS_ERROR_FILE_NOT_FOUND) {
+ throw e;
+ }
+ }
+
+ Services.prefs.resetPrefs();
+ }
+}
diff --git a/extensions/pref/autoconfig/test/unit/test_autoconfig_custom_path.js b/extensions/pref/autoconfig/test/unit/test_autoconfig_custom_path.js
new file mode 100644
index 0000000000..abfa8881b9
--- /dev/null
+++ b/extensions/pref/autoconfig/test/unit/test_autoconfig_custom_path.js
@@ -0,0 +1,22 @@
+/* Any copyright is dedicated to the Public Domain.
+ http://creativecommons.org/publicdomain/zero/1.0/ */
+
+const { updateAppInfo } = ChromeUtils.importESModule(
+ "resource://testing-common/AppInfo.sys.mjs"
+);
+
+function run_test() {
+ let testDirName = do_get_cwd().clone();
+ Services.env.set("MOZ_SYSTEM_CONFIG_DIR", testDirName.path);
+
+ updateAppInfo();
+
+ try {
+ Services.dirsvc.undefine("SysConfD");
+ } catch (e) {}
+ let customSysConfD = Services.dirsvc.get("SysConfD", Ci.nsIFile);
+ let parent = customSysConfD.parent;
+ let child = customSysConfD.leafName;
+ notEqual("/etc", parent.path, "SysConfD is not in /etc");
+ equal("xpcshell", child, "SysConfD is xpcshell");
+}
diff --git a/extensions/pref/autoconfig/test/unit/test_autoconfig_default_path.js b/extensions/pref/autoconfig/test/unit/test_autoconfig_default_path.js
new file mode 100644
index 0000000000..20d3801ab1
--- /dev/null
+++ b/extensions/pref/autoconfig/test/unit/test_autoconfig_default_path.js
@@ -0,0 +1,16 @@
+/* Any copyright is dedicated to the Public Domain.
+ http://creativecommons.org/publicdomain/zero/1.0/ */
+
+const { updateAppInfo } = ChromeUtils.importESModule(
+ "resource://testing-common/AppInfo.sys.mjs"
+);
+
+function run_test() {
+ updateAppInfo();
+
+ try {
+ Services.dirsvc.undefine("SysConfD");
+ } catch (e) {}
+ let defaultSysConfD = Services.dirsvc.get("SysConfD", Ci.nsIFile);
+ equal("/etc/xpcshell", defaultSysConfD.path, "SysConfD is in /etc");
+}
diff --git a/extensions/pref/autoconfig/test/unit/test_autoconfig_no_sandbox.js b/extensions/pref/autoconfig/test/unit/test_autoconfig_no_sandbox.js
new file mode 100644
index 0000000000..7553432bc0
--- /dev/null
+++ b/extensions/pref/autoconfig/test/unit/test_autoconfig_no_sandbox.js
@@ -0,0 +1,59 @@
+/* Any copyright is dedicated to the Public Domain.
+ http://creativecommons.org/publicdomain/zero/1.0/ */
+
+/* eslint no-unsafe-finally: "off"*/
+
+function run_test() {
+ let prefs = Services.prefs.getBranch(null);
+
+ let greD = Services.dirsvc.get("GreD", Ci.nsIFile);
+ let defaultPrefD = Services.dirsvc.get("PrfDef", Ci.nsIFile);
+ let testDir = do_get_cwd();
+
+ try {
+ let autoConfigJS = testDir.clone();
+ autoConfigJS.append("autoconfig-no-sandbox.js");
+ autoConfigJS.copyTo(defaultPrefD, "autoconfig.js");
+
+ // Make sure nsReadConfig is initialized.
+ Cc["@mozilla.org/readconfig;1"].getService(Ci.nsISupports);
+ Services.prefs.resetPrefs();
+
+ let autoConfigCfg = testDir.clone();
+ autoConfigCfg.append("autoconfig-no-sandbox-check.cfg");
+ autoConfigCfg.copyTo(greD, "autoconfig.cfg");
+
+ Services.obs.notifyObservers(
+ Services.prefs,
+ "prefservice:before-read-userprefs"
+ );
+
+ equal("object", prefs.getStringPref("_test.typeof_Components"));
+ equal("object", prefs.getStringPref("_test.typeof_ChromeUtils"));
+ equal("object", prefs.getStringPref("_test.typeof_Services"));
+
+ Services.prefs.resetPrefs();
+ } finally {
+ try {
+ let autoConfigJS = defaultPrefD.clone();
+ autoConfigJS.append("autoconfig.js");
+ autoConfigJS.remove(false);
+ } catch (e) {
+ if (e.result != Cr.NS_ERROR_FILE_NOT_FOUND) {
+ throw e;
+ }
+ }
+
+ try {
+ let autoConfigCfg = greD.clone();
+ autoConfigCfg.append("autoconfig.cfg");
+ autoConfigCfg.remove(false);
+ } catch (e) {
+ if (e.result != Cr.NS_ERROR_FILE_NOT_FOUND) {
+ throw e;
+ }
+ }
+
+ Services.prefs.resetPrefs();
+ }
+}
diff --git a/extensions/pref/autoconfig/test/unit/test_autoconfig_nonascii.js b/extensions/pref/autoconfig/test/unit/test_autoconfig_nonascii.js
new file mode 100644
index 0000000000..e535469360
--- /dev/null
+++ b/extensions/pref/autoconfig/test/unit/test_autoconfig_nonascii.js
@@ -0,0 +1,110 @@
+/* Any copyright is dedicated to the Public Domain.
+ http://creativecommons.org/publicdomain/zero/1.0/ */
+
+/* eslint no-unsafe-finally: "off"*/
+/* Turning off this rule to allow control flow operations in finally block
+ * http://eslint.org/docs/rules/no-unsafe-finally */
+
+function run_test() {
+ let greD = Services.dirsvc.get("GreD", Ci.nsIFile);
+ let defaultPrefD = Services.dirsvc.get("PrfDef", Ci.nsIFile);
+ let testDir = do_get_cwd();
+
+ try {
+ let autoConfigJS = testDir.clone();
+ autoConfigJS.append("autoconfig.js");
+ autoConfigJS.copyTo(defaultPrefD, "autoconfig.js");
+
+ // Make sure nsReadConfig is initialized.
+ Cc["@mozilla.org/readconfig;1"].getService(Ci.nsISupports);
+ Services.prefs.resetPrefs();
+
+ var tests = [
+ {
+ filename: "autoconfig-utf8.cfg",
+ prefs: {
+ "_test.string.ASCII": "UTF-8",
+ "_test.string.non-ASCII": "ユ茯",
+ "_test.string.getPref": "ユ茯",
+ "_test.string.gIsUTF8": "true",
+ },
+ },
+ {
+ filename: "autoconfig-latin1.cfg",
+ prefs: {
+ "_test.string.ASCII": "ASCII",
+ "_test.string.non-ASCII": "ユ茯",
+ "_test.string.getPref": "ユ茯",
+ "_test.string.gIsUTF8": "false",
+ },
+ },
+ {
+ filename: "autoconfig-chromecheck.cfg",
+ prefs: {
+ "_test.string.typeofComponents": "undefined",
+ "_test.string.typeofChromeUtils": "undefined",
+ "_test.string.typeofServices": "undefined",
+ },
+ },
+ ];
+
+ function testAutoConfig(test) {
+ // Make sure pref values are unset.
+ for (let prefName in test.prefs) {
+ Assert.equal(
+ Ci.nsIPrefBranch.PREF_INVALID,
+ Services.prefs.getPrefType(prefName)
+ );
+ }
+
+ let autoConfigCfg = testDir.clone();
+ autoConfigCfg.append(test.filename);
+ autoConfigCfg.copyTo(greD, "autoconfig.cfg");
+
+ Services.obs.notifyObservers(
+ Services.prefs,
+ "prefservice:before-read-userprefs"
+ );
+
+ for (let prefName in test.prefs) {
+ Assert.equal(
+ test.prefs[prefName],
+ Services.prefs.getStringPref(prefName)
+ );
+ }
+
+ Services.prefs.resetPrefs();
+ // Make sure pref values are reset.
+ for (let prefName in test.prefs) {
+ Assert.equal(
+ Ci.nsIPrefBranch.PREF_INVALID,
+ Services.prefs.getPrefType(prefName)
+ );
+ }
+ }
+
+ tests.forEach(testAutoConfig);
+ } finally {
+ try {
+ let autoConfigJS = defaultPrefD.clone();
+ autoConfigJS.append("autoconfig.js");
+ autoConfigJS.remove(false);
+ } catch (e) {
+ if (e.result != Cr.NS_ERROR_FILE_NOT_FOUND) {
+ throw e;
+ }
+ }
+
+ try {
+ let autoConfigCfg = greD.clone();
+ autoConfigCfg.append("autoconfig.cfg");
+ autoConfigCfg.remove(false);
+ } catch (e) {
+ if (e.result != Cr.NS_ERROR_FILE_NOT_FOUND) {
+ throw e;
+ }
+ }
+
+ Services.prefs.resetPrefs();
+ }
+}
diff --git a/extensions/pref/autoconfig/test/unit/test_autoconfig_snap.js b/extensions/pref/autoconfig/test/unit/test_autoconfig_snap.js
new file mode 100644
index 0000000000..1a58e11cf5
--- /dev/null
+++ b/extensions/pref/autoconfig/test/unit/test_autoconfig_snap.js
@@ -0,0 +1,77 @@
+/* Any copyright is dedicated to the Public Domain.
+ http://creativecommons.org/publicdomain/zero/1.0/ */
+
+/* eslint no-unsafe-finally: "off"*/
+/* Turning off this rule to allow control flow operations in finally block
+ * http://eslint.org/docs/rules/no-unsafe-finally */
+
+const { updateAppInfo } = ChromeUtils.importESModule(
+ "resource://testing-common/AppInfo.sys.mjs"
+);
+
+function ensureRemove(file) {
+ try {
+ file.remove(false);
+ } catch (e) {
+ if (e.result != Cr.NS_ERROR_FILE_NOT_FOUND) {
+ throw e;
+ }
+ }
+}
+
+async function run_test() {
+ let prefs = Services.prefs.getBranch(null);
+
+ let testDir = do_get_cwd();
+ let confDir = testDir.clone();
+ confDir.append("MozSystemConfigDir");
+ Services.env.set("MOZ_SYSTEM_CONFIG_DIR", confDir.path);
+ Services.env.set("SNAP_INSTANCE_NAME", "xpcshell");
+
+ updateAppInfo();
+
+ let sysConfD = Services.dirsvc.get("SysConfD", Ci.nsIFile);
+
+ let defaultPrefDExtra = sysConfD.clone();
+ defaultPrefDExtra.append("defaults");
+ defaultPrefDExtra.append("pref");
+
+ await IOUtils.makeDirectory(defaultPrefDExtra.path);
+
+ const kAutoConfigFile = defaultPrefDExtra.clone();
+ kAutoConfigFile.append("autoconfig_snap.js");
+ const kAutoConfigCfg = sysConfD.clone();
+ kAutoConfigCfg.append("autoconfig-snap.cfg");
+
+ let autoConfigJS = testDir.clone();
+ autoConfigJS.append(kAutoConfigFile.leafName);
+
+ let autoConfigCfg = testDir.clone();
+ autoConfigCfg.append(kAutoConfigCfg.leafName);
+
+ try {
+ autoConfigJS.copyTo(kAutoConfigFile.parent, kAutoConfigFile.leafName);
+ autoConfigCfg.copyTo(kAutoConfigCfg.parent, kAutoConfigCfg.leafName);
+
+ // Make sure nsReadConfig is initialized.
+ Cc["@mozilla.org/readconfig;1"].getService(Ci.nsISupports);
+ Services.prefs.resetPrefs();
+
+ Services.obs.notifyObservers(
+ Services.prefs,
+ "prefservice:before-read-userprefs"
+ );
+
+ ok(prefs.prefHasUserValue("_autoconfig_.test.userpref-snap"));
+ equal(
+ "userpref-snap",
+ prefs.getStringPref("_autoconfig_.test.userpref-snap")
+ );
+
+ Services.prefs.resetPrefs();
+ } finally {
+ ensureRemove(kAutoConfigFile);
+ ensureRemove(kAutoConfigCfg);
+ Services.prefs.resetPrefs();
+ }
+}
diff --git a/extensions/pref/autoconfig/test/unit/xpcshell.ini b/extensions/pref/autoconfig/test/unit/xpcshell.ini
new file mode 100644
index 0000000000..fd09da01af
--- /dev/null
+++ b/extensions/pref/autoconfig/test/unit/xpcshell.ini
@@ -0,0 +1,23 @@
+[DEFAULT]
+head =
+skip-if =
+ toolkit == 'android'
+ os == 'win' && msix # Does not work in MSIX builds.
+support-files =
+ autoconfig-all.cfg
+ autoconfig-latin1.cfg
+ autoconfig-utf8.cfg
+ autoconfig-chromecheck.cfg
+ autoconfig-no-sandbox-check.cfg
+ autoconfig.js
+ autoconfig-no-sandbox.js
+
+[test_autoconfig.js]
+[test_autoconfig_nonascii.js]
+run-sequentially = very high failure rate in parallel
+[test_autoconfig_no_sandbox.js]
+run-sequentially = very high failure rate in parallel
+[test_autoconfig_default_path.js]
+run-if = os == 'linux'
+[test_autoconfig_custom_path.js]
+run-if = os == 'linux'
diff --git a/extensions/pref/autoconfig/test/unit/xpcshell_snap.ini b/extensions/pref/autoconfig/test/unit/xpcshell_snap.ini
new file mode 100644
index 0000000000..ff24d46646
--- /dev/null
+++ b/extensions/pref/autoconfig/test/unit/xpcshell_snap.ini
@@ -0,0 +1,8 @@
+[DEFAULT]
+head =
+skip-if = os != 'linux'
+
+[test_autoconfig_snap.js]
+support-files =
+ autoconfig_snap.js
+ autoconfig-snap.cfg
diff --git a/extensions/pref/moz.build b/extensions/pref/moz.build
new file mode 100644
index 0000000000..b0b3670440
--- /dev/null
+++ b/extensions/pref/moz.build
@@ -0,0 +1,11 @@
+# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
+# vim: set filetype=python:
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+DIRS += ["autoconfig"]
+
+with Files("**"):
+ BUG_COMPONENT = ("Core", "AutoConfig (Mission Control Desktop)")
diff --git a/extensions/spellcheck/docs/index.rst b/extensions/spellcheck/docs/index.rst
new file mode 100644
index 0000000000..5ec2a224d9
--- /dev/null
+++ b/extensions/spellcheck/docs/index.rst
@@ -0,0 +1,199 @@
+======================================
+Managing the built-in en-US dictionary
+======================================
+
+The en-US build of Firefox includes a built-in Hunspell dictionary based on the
+`SCOWL`_ dataset. This document describes the process to add new words to the
+dictionary, or update it to the current upstream version.
+
+For more information about Hunspell or the affix file format, you can check
+`the Ubuntu man page for hunspell
+<https://manpages.ubuntu.com/manpages/bionic/man5/hunspell.5.html>`_.
+
+Requesting to add new words to the en-US dictionary
+===================================================
+
+If youd like to add new words to the dictionary, you can add your request to
+`this bug <https://bugzilla.mozilla.org/show_bug.cgi?id=enus-dictionary>`_:
+
+* Include all possible forms, e.g. plural and genitive forms for nouns,
+ different tenses for verbs.
+* Try to provide information on the terms you want to add, in particular
+ references to external sources that confirm the usage of the term (e.g.
+ Merriam-Webster or Oxford online dictionaries).
+
+.. note::
+
+ If youre fixing the existing bug with pending requests, make sure to `file a
+ new bug`_ and move the alias ``enus-dictionary`` (in the *Details* section)
+ from the old bug to the new one.
+
+Adding new words to the en-US dictionary
+========================================
+
+This section describes the process for adding new words to the dictionary:
+
+#. Get a clone of mozilla-central (see :ref:`Firefox Contributors' Quick
+ Reference`), if you dont already have one, and make sure you can build it
+ successfully.
+#. Move in the dictionary sources directory using this command:
+ ``cd extensions/spellcheck/locales/en-US/hunspell/dictionary-sources``.
+#. Identify the current version of SCOWL by checking the file
+ ``README_en_US.txt`` (at the beginning of the file there is a line similar to
+ ``Generated from SCOWL Version 2020.12.07``, where ``2020.12.07`` is the
+ SCOWL version).
+#. Download the same version of the dictionary from the `SCOWL`_ homepage or
+ `SourceForce`_ as a tarball (tag.gz) and unpack it in the working directory.
+ Rename the resulting folder from ``scowl-YYYY.MM.DD`` to ``scowl``.
+#. Theres a special script used for editing dictionaries. The script
+ only works if you have the environment variable ``EDITOR`` set to the
+ executable of an editor program; if you dont have it set, you can use
+ ``EDITOR=vim sh edit-dictionary.sh`` to edit using ``vim`` (or you can
+ substitute it with another editor), or you can just type
+ ``sh edit-dictionary.sh`` if you have an ``EDITOR`` already specified.
+
+ Copy and paste the full list of words, then save and quit the editor. Its
+ not necessary to put the words in alphabetical order, as it will be corrected
+ by the script.
+#. Run the script ``sh make-new-dict.sh`` to generate a new dictionary and make
+ sure it runs without errors. For more details on this script, see the
+ `make-new-dict.sh`_ section.
+#. Do a sanity check on the resulting dictionary file ``en_US-mozilla.dic``. For
+ example, make sure that the size is about the same as the original dictionary
+ (or slightly larger).
+#. If everything looks correct, use ``sh install-new-dict.sh`` to copy the
+ generated file in the right position.
+#. Build Firefox and test your updated dictionary. Once youre
+ satisfied, use the process described in :ref:`write_a_patch` to create a
+ patch.
+
+Note that the update script will modify 2 versions of the dictionary, and both
+need to be committed:
+
+* ``en-US.dic``: the dictionary actually shipping in the build, it uses
+ ISO-8859-1 encoding.
+* ``utf8/en-US.dic``: a version of the same dictionary with UTF-8 encoding. This
+ is used to work around issues with Phabricator, and it allows to display
+ actual changes in the diff.
+
+Exclude words from suggestions
+==============================
+
+Its possible to completely exclude words from suggested alternatives by adding
+an affix rule ``!`` at the end of the definition in the ``.dic`` file. For
+example:
+
+* ``bum`` would be changed to ``bum/!`` (note the additional forward slash).
+* ``bum/MS`` would be changed to ``bum/MS!``.
+
+In order to exclude a word from suggestions, follow the instructions available
+in `Adding new words to the en-US dictionary`_. Instead of running the
+``edit-dictionary.sh`` script (point 5), use a text editor to edit the file
+``en-US.dic`` directly, then proceed with the remaining instructions.
+
+.. warning::
+
+ Make sure to open ``en-US.dic`` with the correct encoding. For example, Visual
+ Studio Code will try to open it as ``UTF-8``, and it needs to be reopened with
+ encoding ``Western (ISO 8859-1)``.
+
+Upgrading dictionary to a new upstream version of SCOWL
+=======================================================
+
+The English dictionary available in mozilla-central is based on the
+`SCOWL`_ dictionary. Some scripts distributed with the SCOWL package are
+used to generate the files for the en-US dictionary.
+
+The working directory for this process is
+``extensions/spellcheck/locales/en-US/hunspell/dictionary-sources``.
+
+#. Download the latest version of the dictionary from the `SCOWL`_ homepage or
+ `SourceForce`_ as a tarball (tag.gz) and unpack it in the working directory.
+ Rename the resulting folder from ``scowl-YYYY.MM.DD`` to ``scowl``.
+#. Run the script ``sh make-new-dict.sh`` to generate a new dictionary and make
+ sure it runs without errors. For more details on this script, see the
+ `make-new-dict.sh`_ section.
+#. Do a sanity check on the resulting dictionary file ``en_US-mozilla.dic``. For
+ example, make sure that the size is about the same as the original dictionary
+ (or slightly larger).
+#. If everything looks correct, use ``sh install-new-dict.sh`` to copy the
+ generated file in the right position and use the process described in
+ :ref:`write_a_patch` to create a patch.
+
+Info about the file structure
+=============================
+
+mozilla-specific.txt
+--------------------
+
+This file contains Mozilla-specific words that should not be submitted
+upstream. For example, ``Firefox`` should go in this file (see `bug 237921`_).
+
+Note that the file ``5-mozilla-specific.txt`` is generated by expanding
+``mozilla-specific.txt`` and should not be edited directly.
+
+utf8 folder
+-----------
+
+``dictionary-sources/utf8`` is used to store a copy with UTF-8 encoding of the
+dictionary files. This is used to work around limitations in Phabricator, which
+treats ISO-8859-1 files as binary and wont display a diff when updating them.
+
+Info about the included scripts
+===============================
+
+make-new-dict.sh
+----------------
+
+The dictionary upgrade scripts ``make-new-dict.sh`` works by expanding (i.e.
+unmunching) the affix compression dictionaries to create wordlists and
+use those to generate a new dictionary.
+
+The upgrade script expects the current upstream version to be kept in the
+directory ``orig``.
+
+The script will create a few files in ``dictionary-sources/support_file`` in the
+following order:
+
+* ``0-special.txt`` contains numbers and ordinals expanded from SCOWL
+ ``en.dic.supp``.
+* ``1-base.txt`` contains words expanded from ``en_US-custom.dic`` in the
+ **previous** version of SCOWL (from the ``orig`` folder).
+* ``2-mozilla.txt`` contains words expanded from the current Mozilla dictionary.
+* ``3-upstream.txt`` contains words expanded from ``en_US-custom.dic`` in the
+ **new** version of SCOWL (from the ``scowl/speller`` folder).
+* ``2-mozilla-removed.txt`` contains words that are only available in the SCOWL
+ dictionary, i.e. removed by Mozilla.
+* ``2-mozilla-added.txt`` contains words that are only available in the current
+ Mozilla dictionary, i.e. added by Mozilla.
+* ``4-patched.txt`` contains words from the new SCOWL dictionary
+ (``3-upstream.txt``), with words from (``2-mozilla-removed.txt``) removed and
+ words (``2-mozilla-added.txt``) added.
+* ``5-mozilla-specific.txt`` is expanded from ``mozilla-specific.txt`` using the
+ current affix rules from the Mozilla dictionary.
+* ``5-mozilla-removed.txt`` and ``5-mozilla-added.txt`` contain words that are
+ respectively removed and added by Mozilla compared to the **new** SCOWL
+ version. These files could be used to submit upstream changes, but words
+ included in ``5-mozilla-specific.txt`` should be removed from this list.
+
+The new dictionary is available as ``en_US-mozilla.dic`` and should be copied
+over using the ``install-new-dict.sh`` script.
+
+install-new-dict.sh
+-------------------
+
+The script:
+
+* Creates a copy of ``orig`` as ``support_files/orig-bk`` and copies the new
+ upstream version to ``orig``.
+* Copies the existing Mozilla dictionary in ``support_files/mozilla-bk``.
+* Converts the dictionary (.dic) generated by ``make-new-dict.sh`` from UTF-8 to
+ ISO-8859-1 and moves it to the parent folder.
+* Sets the affix file (.aff) to use ``ISO8859-1`` as ``SET`` instead of the
+ original ``UTF-8``, removes ``ICONV`` patterns (input conversion tables).
+
+
+.. _SCOWL: http://wordlist.aspell.net
+.. _file a new bug: https://bugzilla.mozilla.org/show_bug.cgi?id=enus-dictionary
+.. _SourceForce: https://sourceforge.net/projects/wordlist/files/SCOWL/
+.. _bug 237921: https://bugzilla.mozilla.org/show_bug.cgi?id=237921
diff --git a/extensions/spellcheck/hunspell/glue/PRemoteSpellcheckEngine.ipdl b/extensions/spellcheck/hunspell/glue/PRemoteSpellcheckEngine.ipdl
new file mode 100644
index 0000000000..c327d97e65
--- /dev/null
+++ b/extensions/spellcheck/hunspell/glue/PRemoteSpellcheckEngine.ipdl
@@ -0,0 +1,46 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+include protocol PContent;
+
+include "mozilla/RemoteSpellCheckEngineParent.h";
+include "mozilla/RemoteSpellCheckEngineChild.h";
+
+namespace mozilla {
+
+[ManualDealloc, ChildImpl="RemoteSpellcheckEngineChild", ParentImpl="RemoteSpellcheckEngineParent"]
+sync protocol PRemoteSpellcheckEngine {
+ manager PContent;
+
+parent:
+ async __delete__();
+
+ async CheckAsync(nsString[] aWord) returns (bool[] aIsMisspelled);
+
+ sync SetDictionary(nsCString aDictionary) returns (bool success);
+
+ /*
+ * Set multiple current dictionaries from a list of dictionary names.
+ *
+ * @aDictionaries An array of dictionary names to use. If the array is empty,
+ * no dictionary will be used.
+ * @aSuccess true if setting the dictionaries succeeded, false otherwise.
+ */
+ async SetDictionaries(nsCString[] aDictionaries) returns (bool success);
+
+ async Suggest(nsString aWord, uint32_t aCount) returns (nsString[] aSuggestions);
+
+ /*
+ * Set current dictionary from list of dictionary name.
+ *
+ * @aList A list of dictionary name. If a string into this list is
+ * empty string, dictionary selection is reset
+ * @aSuccess true if setting dictionary is successful
+ * @aDictionary Return current dictionary name that set by this method.
+ */
+ async SetDictionaryFromList(nsCString[] aList)
+ returns (bool aSuccess, nsCString aDictionary);
+};
+
+} // namespace mozilla
diff --git a/extensions/spellcheck/hunspell/glue/RLBoxHunspell.cpp b/extensions/spellcheck/hunspell/glue/RLBoxHunspell.cpp
new file mode 100644
index 0000000000..b3a1990ceb
--- /dev/null
+++ b/extensions/spellcheck/hunspell/glue/RLBoxHunspell.cpp
@@ -0,0 +1,256 @@
+/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "mozilla/Assertions.h"
+#ifdef MOZ_WASM_SANDBOXING_HUNSPELL
+# include "mozilla/ipc/LibrarySandboxPreload.h"
+#endif
+#include "RLBoxHunspell.h"
+#include "mozHunspellRLBoxGlue.h"
+#include "mozHunspellRLBoxHost.h"
+#include "nsThread.h"
+
+using namespace rlbox;
+using namespace mozilla;
+
+// Helper function for allocating and copying std::string into sandbox
+static tainted_hunspell<char*> allocStrInSandbox(
+ rlbox_sandbox_hunspell& aSandbox, const std::string& str) {
+ size_t size = str.size() + 1;
+ tainted_hunspell<char*> t_str = aSandbox.malloc_in_sandbox<char>(size);
+ if (t_str) {
+ rlbox::memcpy(aSandbox, t_str, str.c_str(), size);
+ }
+ return t_str;
+}
+
+/* static */
+RLBoxHunspell* RLBoxHunspell::Create(const nsCString& affpath,
+ const nsCString& dpath) {
+ MOZ_DIAGNOSTIC_ASSERT(NS_IsMainThread());
+
+ mozilla::UniquePtr<rlbox_sandbox_hunspell> sandbox(
+ new rlbox_sandbox_hunspell());
+
+#if defined(MOZ_WASM_SANDBOXING_HUNSPELL) && !defined(HAVE_64BIT_BUILD)
+ // By default, the rlbox sandbox size is smaller on 32-bit builds than the max
+ // 4GB. We may need to ask for a larger sandbox size for hunspell to
+ // spellcheck in some locales See Bug 1739669 for more details
+
+ // We first get the size of the dictionary. This is actually the first read we
+ // try on dpath and it might fail for whatever filesystem reasons (invalid
+ // path, unaccessible, ...).
+ Result<int64_t, nsresult> dictSizeResult =
+ mozHunspellFileMgrHost::GetSize(dpath);
+ NS_ENSURE_TRUE(dictSizeResult.isOk(), nullptr);
+
+ int64_t dictSize = dictSizeResult.unwrap();
+ NS_ENSURE_TRUE(dictSize >= 0, nullptr);
+
+ // Next, we compute the expected memory needed for hunspell spell checking.
+ // This will vary based on the size of the dictionary file, which varies by
+ // locale so we size the sandbox by multiplying the file size by 4.8. This
+ // allows the 1.5MB en_US dictionary to fit in an 8MB sandbox. See bug 1739669
+ // and bug 1739761 for the analysis behind this.
+ const uint64_t expectedMaxMemory = static_cast<uint64_t>(4.8 * dictSize);
+
+ // Get a capacity of at least the expected size
+ const w2c_mem_capacity capacity = get_valid_wasm2c_memory_capacity(
+ expectedMaxMemory, true /* wasm's 32-bit memory */);
+
+ bool success =
+ sandbox->create_sandbox(/* shouldAbortOnFailure = */ false, &capacity);
+#elif defined(MOZ_WASM_SANDBOXING_HUNSPELL)
+ bool success = sandbox->create_sandbox(/* shouldAbortOnFailure = */ false);
+#else
+ sandbox->create_sandbox();
+ const bool success = true;
+#endif
+
+ NS_ENSURE_TRUE(success, nullptr);
+
+ mozilla::UniquePtr<rlbox_sandbox_hunspell, RLBoxDeleter> sandbox_initialized(
+ sandbox.release());
+
+ // Add the aff and dict files to allow list
+ if (!affpath.IsEmpty()) {
+ mozHunspellCallbacks::AllowFile(affpath);
+ }
+ if (!dpath.IsEmpty()) {
+ mozHunspellCallbacks::AllowFile(dpath);
+ }
+
+ // TODO Bug 1788857: Verify error handling in case of inaccessible file
+ return new RLBoxHunspell(std::move(sandbox_initialized), affpath, dpath);
+}
+
+RLBoxHunspell::RLBoxHunspell(
+ mozilla::UniquePtr<rlbox_sandbox_hunspell, RLBoxDeleter> aSandbox,
+ const nsCString& affpath, const nsCString& dpath)
+ : mSandbox(std::move(aSandbox)), mHandle(nullptr) {
+ // Register callbacks
+ mCreateFilemgr =
+ mSandbox->register_callback(mozHunspellCallbacks::CreateFilemgr);
+ mGetLine = mSandbox->register_callback(mozHunspellCallbacks::GetLine);
+ mGetLineNum = mSandbox->register_callback(mozHunspellCallbacks::GetLineNum);
+ mDestructFilemgr =
+ mSandbox->register_callback(mozHunspellCallbacks::DestructFilemgr);
+ mHunspellToUpperCase =
+ mSandbox->register_callback(mozHunspellCallbacks::ToUpperCase);
+ mHunspellToLowerCase =
+ mSandbox->register_callback(mozHunspellCallbacks::ToLowerCase);
+ mHunspellGetCurrentCS =
+ mSandbox->register_callback(mozHunspellCallbacks::GetCurrentCS);
+
+ mSandbox->invoke_sandbox_function(RegisterHunspellCallbacks, mCreateFilemgr,
+ mGetLine, mGetLineNum, mDestructFilemgr,
+ mHunspellToUpperCase, mHunspellToLowerCase,
+ mHunspellGetCurrentCS);
+
+ // Copy the affpath and dpath into the sandbox
+ // These allocations should definitely succeed as these are first allocations
+ // inside the sandbox.
+ tainted_hunspell<char*> t_affpath =
+ allocStrInSandbox(*mSandbox, affpath.get());
+ MOZ_RELEASE_ASSERT(t_affpath);
+
+ tainted_hunspell<char*> t_dpath = allocStrInSandbox(*mSandbox, dpath.get());
+ MOZ_RELEASE_ASSERT(t_dpath);
+
+ // Create handle
+ mHandle = mSandbox->invoke_sandbox_function(
+ Hunspell_create, rlbox::sandbox_const_cast<const char*>(t_affpath),
+ rlbox::sandbox_const_cast<const char*>(t_dpath));
+ MOZ_RELEASE_ASSERT(mHandle);
+
+ mSandbox->free_in_sandbox(t_dpath);
+ mSandbox->free_in_sandbox(t_affpath);
+
+ // Get dictionary encoding
+ tainted_hunspell<char*> t_enc =
+ mSandbox->invoke_sandbox_function(Hunspell_get_dic_encoding, mHandle);
+ t_enc.copy_and_verify_string([&](std::unique_ptr<char[]> enc) {
+ size_t len = std::strlen(enc.get());
+ mDicEncoding = std::string(enc.get(), len);
+ });
+}
+
+RLBoxHunspell::~RLBoxHunspell() {
+ MOZ_DIAGNOSTIC_ASSERT(NS_IsMainThread());
+ // Call hunspell's destroy which frees mHandle
+ mSandbox->invoke_sandbox_function(Hunspell_destroy, mHandle);
+ mHandle = nullptr;
+
+ // Unregister callbacks
+ mDestructFilemgr.unregister();
+ mGetLineNum.unregister();
+ mGetLine.unregister();
+ mCreateFilemgr.unregister();
+ mHunspellToUpperCase.unregister();
+ mHunspellToLowerCase.unregister();
+ mHunspellGetCurrentCS.unregister();
+
+ // Clear any callback data and allow list
+ mozHunspellCallbacks::Clear();
+}
+
+// Invoking hunspell with words larger than a certain size will cause the
+// Hunspell sandbox to run out of memory. So we pick an arbitrary limit of
+// 200000 here to ensure this doesn't happen.
+static const size_t gWordSizeLimit = 200000;
+
+int RLBoxHunspell::spell(const std::string& stdWord) {
+ MOZ_DIAGNOSTIC_ASSERT(NS_IsMainThread());
+
+ const int ok = 1;
+
+ if (stdWord.length() >= gWordSizeLimit) {
+ // Fail gracefully assuming the word is spelt correctly
+ return ok;
+ }
+
+ // Copy word into the sandbox
+ tainted_hunspell<char*> t_word = allocStrInSandbox(*mSandbox, stdWord);
+ if (!t_word) {
+ // Ran out of memory in the hunspell sandbox
+ // Fail gracefully assuming the word is spelt correctly
+ return ok;
+ }
+
+ // Check word
+ int good = mSandbox
+ ->invoke_sandbox_function(
+ Hunspell_spell, mHandle,
+ rlbox::sandbox_const_cast<const char*>(t_word))
+ .copy_and_verify([](int good) { return good; });
+ mSandbox->free_in_sandbox(t_word);
+ return good;
+}
+
+const std::string& RLBoxHunspell::get_dict_encoding() const {
+ return mDicEncoding;
+}
+
+// This function fails gracefully - if we run out of memory in the hunspell
+// sandbox, we return empty suggestion list
+std::vector<std::string> RLBoxHunspell::suggest(const std::string& stdWord) {
+ MOZ_DIAGNOSTIC_ASSERT(NS_IsMainThread());
+
+ if (stdWord.length() >= gWordSizeLimit) {
+ return {};
+ }
+
+ // Copy word into the sandbox
+ tainted_hunspell<char*> t_word = allocStrInSandbox(*mSandbox, stdWord);
+ if (!t_word) {
+ return {};
+ }
+
+ // Allocate suggestion list in the sandbox
+ tainted_hunspell<char***> t_slst = mSandbox->malloc_in_sandbox<char**>();
+ if (!t_slst) {
+ // Free the earlier allocation
+ mSandbox->free_in_sandbox(t_word);
+ return {};
+ }
+
+ *t_slst = nullptr;
+
+ // Get suggestions
+ int nr = mSandbox
+ ->invoke_sandbox_function(
+ Hunspell_suggest, mHandle, t_slst,
+ rlbox::sandbox_const_cast<const char*>(t_word))
+ .copy_and_verify([](int nr) {
+ MOZ_RELEASE_ASSERT(nr >= 0);
+ return nr;
+ });
+
+ tainted_hunspell<char**> t_slst_ref = *t_slst;
+
+ std::vector<std::string> suggestions;
+ if (nr > 0 && t_slst_ref != nullptr) {
+ // Copy suggestions from sandbox
+ suggestions.reserve(nr);
+
+ for (int i = 0; i < nr; i++) {
+ tainted_hunspell<char*> t_sug = t_slst_ref[i];
+
+ if (t_sug) {
+ t_sug.copy_and_verify_string(
+ [&](std::string sug) { suggestions.push_back(std::move(sug)); });
+ // free the suggestion string allocated by the sandboxed hunspell
+ mSandbox->free_in_sandbox(t_sug);
+ }
+ }
+
+ // free the suggestion list allocated by the sandboxed hunspell
+ mSandbox->free_in_sandbox(t_slst_ref);
+ }
+
+ mSandbox->free_in_sandbox(t_word);
+ mSandbox->free_in_sandbox(t_slst);
+ return suggestions;
+}
diff --git a/extensions/spellcheck/hunspell/glue/RLBoxHunspell.h b/extensions/spellcheck/hunspell/glue/RLBoxHunspell.h
new file mode 100644
index 0000000000..2e5a11d936
--- /dev/null
+++ b/extensions/spellcheck/hunspell/glue/RLBoxHunspell.h
@@ -0,0 +1,66 @@
+/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef EXTENSIONS_SPELLCHECK_HUNSPELL_GLUE_RLBOXHUNSPELL_H_
+#define EXTENSIONS_SPELLCHECK_HUNSPELL_GLUE_RLBOXHUNSPELL_H_
+
+#include "RLBoxHunspellTypes.h"
+
+// Load general firefox configuration of RLBox
+#include "mozilla/rlbox/rlbox_config.h"
+
+#ifdef MOZ_WASM_SANDBOXING_HUNSPELL
+// Include the generated header file so that we are able to resolve the symbols
+// in the wasm binary
+# include "rlbox.wasm.h"
+# define RLBOX_USE_STATIC_CALLS() rlbox_wasm2c_sandbox_lookup_symbol
+# include "mozilla/rlbox/rlbox_wasm2c_sandbox.hpp"
+#else
+# define RLBOX_USE_STATIC_CALLS() rlbox_noop_sandbox_lookup_symbol
+# include "mozilla/rlbox/rlbox_noop_sandbox.hpp"
+#endif
+
+#include "mozilla/rlbox/rlbox.hpp"
+
+#include <hunspell.h>
+#include "mozHunspellRLBoxGlue.h"
+
+class RLBoxHunspell {
+ public:
+ static RLBoxHunspell* Create(const nsCString& affpath,
+ const nsCString& dpath);
+
+ ~RLBoxHunspell();
+
+ int spell(const std::string& stdWord);
+ const std::string& get_dict_encoding() const;
+
+ std::vector<std::string> suggest(const std::string& word);
+
+ private:
+ struct RLBoxDeleter {
+ void operator()(rlbox_sandbox_hunspell* sandbox) {
+ sandbox->destroy_sandbox();
+ delete sandbox;
+ }
+ };
+
+ RLBoxHunspell(
+ mozilla::UniquePtr<rlbox_sandbox_hunspell, RLBoxDeleter> aSandbox,
+ const nsCString& affpath, const nsCString& dpath);
+
+ mozilla::UniquePtr<rlbox_sandbox_hunspell, RLBoxDeleter> mSandbox;
+ sandbox_callback_hunspell<hunspell_create_filemgr_t*> mCreateFilemgr;
+ sandbox_callback_hunspell<hunspell_get_line_t*> mGetLine;
+ sandbox_callback_hunspell<hunspell_get_line_num_t*> mGetLineNum;
+ sandbox_callback_hunspell<hunspell_destruct_filemgr_t*> mDestructFilemgr;
+ sandbox_callback_hunspell<hunspell_ToUpperCase_t*> mHunspellToUpperCase;
+ sandbox_callback_hunspell<hunspell_ToLowerCase_t*> mHunspellToLowerCase;
+ sandbox_callback_hunspell<hunspell_get_current_cs_t*> mHunspellGetCurrentCS;
+ tainted_hunspell<Hunhandle*> mHandle;
+ std::string mDicEncoding;
+};
+
+#endif
diff --git a/extensions/spellcheck/hunspell/glue/RLBoxHunspellTypes.h b/extensions/spellcheck/hunspell/glue/RLBoxHunspellTypes.h
new file mode 100644
index 0000000000..d05703ad0f
--- /dev/null
+++ b/extensions/spellcheck/hunspell/glue/RLBoxHunspellTypes.h
@@ -0,0 +1,27 @@
+/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef EXTENSIONS_SPELLCHECK_HUNSPELL_GLUE_RLBOXHUNSPELLTYPES_H_
+#define EXTENSIONS_SPELLCHECK_HUNSPELL_GLUE_RLBOXHUNSPELLTYPES_H_
+
+#include <stddef.h>
+#include "mozilla/rlbox/rlbox_types.hpp"
+#include "hunspell_csutil.hxx"
+
+#ifdef MOZ_WASM_SANDBOXING_HUNSPELL
+RLBOX_DEFINE_BASE_TYPES_FOR(hunspell, wasm2c)
+#else
+RLBOX_DEFINE_BASE_TYPES_FOR(hunspell, noop)
+#endif
+
+#define sandbox_fields_reflection_hunspell_class_cs_info(f, g, ...) \
+ f(unsigned char, ccase, FIELD_NORMAL, ##__VA_ARGS__) g() \
+ f(unsigned char, clower, FIELD_NORMAL, ##__VA_ARGS__) g() \
+ f(unsigned char, cupper, FIELD_NORMAL, ##__VA_ARGS__) g()
+
+#define sandbox_fields_reflection_hunspell_allClasses(f, ...) \
+ f(cs_info, hunspell, ##__VA_ARGS__)
+
+#endif
diff --git a/extensions/spellcheck/hunspell/glue/RemoteSpellCheckEngineChild.cpp b/extensions/spellcheck/hunspell/glue/RemoteSpellCheckEngineChild.cpp
new file mode 100644
index 0000000000..8971694db3
--- /dev/null
+++ b/extensions/spellcheck/hunspell/glue/RemoteSpellCheckEngineChild.cpp
@@ -0,0 +1,84 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "mozilla/UniquePtr.h"
+#include "RemoteSpellCheckEngineChild.h"
+
+namespace mozilla {
+
+RemoteSpellcheckEngineChild::RemoteSpellcheckEngineChild(
+ mozSpellChecker* aOwner)
+ : mOwner(aOwner) {}
+
+RemoteSpellcheckEngineChild::~RemoteSpellcheckEngineChild() {
+ // null out the owner's SpellcheckEngineChild to prevent state corruption
+ // during shutdown
+ mOwner->DeleteRemoteEngine();
+}
+
+RefPtr<GenericPromise> RemoteSpellcheckEngineChild::SetCurrentDictionaries(
+ const nsTArray<nsCString>& aDictionaries) {
+ RefPtr<mozSpellChecker> spellChecker = mOwner;
+
+ return SendSetDictionaries(aDictionaries)
+ ->Then(
+ GetMainThreadSerialEventTarget(), __func__,
+ [spellChecker, dictionaries = aDictionaries.Clone()](bool&& aParam) {
+ if (aParam) {
+ spellChecker->mCurrentDictionaries = dictionaries.Clone();
+ return GenericPromise::CreateAndResolve(true, __func__);
+ }
+ spellChecker->mCurrentDictionaries.Clear();
+ return GenericPromise::CreateAndReject(NS_ERROR_NOT_AVAILABLE,
+ __func__);
+ },
+ [spellChecker](ResponseRejectReason&& aReason) {
+ spellChecker->mCurrentDictionaries.Clear();
+ return GenericPromise::CreateAndReject(NS_ERROR_NOT_AVAILABLE,
+ __func__);
+ });
+}
+
+RefPtr<GenericPromise>
+RemoteSpellcheckEngineChild::SetCurrentDictionaryFromList(
+ const nsTArray<nsCString>& aList) {
+ RefPtr<mozSpellChecker> spellChecker = mOwner;
+
+ return SendSetDictionaryFromList(aList)->Then(
+ GetMainThreadSerialEventTarget(), __func__,
+ [spellChecker](std::tuple<bool, nsCString>&& aParam) {
+ if (!std::get<0>(aParam)) {
+ spellChecker->mCurrentDictionaries.Clear();
+ return GenericPromise::CreateAndReject(NS_ERROR_NOT_AVAILABLE,
+ __func__);
+ }
+ spellChecker->mCurrentDictionaries.Clear();
+ spellChecker->mCurrentDictionaries.AppendElement(
+ std::move(std::get<1>(aParam)));
+ return GenericPromise::CreateAndResolve(true, __func__);
+ },
+ [spellChecker](ResponseRejectReason&& aReason) {
+ spellChecker->mCurrentDictionaries.Clear();
+ return GenericPromise::CreateAndReject(NS_ERROR_NOT_AVAILABLE,
+ __func__);
+ });
+}
+
+RefPtr<CheckWordPromise> RemoteSpellcheckEngineChild::CheckWords(
+ const nsTArray<nsString>& aWords) {
+ RefPtr<mozSpellChecker> kungFuDeathGrip = mOwner;
+
+ return SendCheckAsync(aWords)->Then(
+ GetMainThreadSerialEventTarget(), __func__,
+ [kungFuDeathGrip](nsTArray<bool>&& aIsMisspelled) {
+ return CheckWordPromise::CreateAndResolve(std::move(aIsMisspelled),
+ __func__);
+ },
+ [kungFuDeathGrip](mozilla::ipc::ResponseRejectReason&& aReason) {
+ return CheckWordPromise::CreateAndReject(NS_ERROR_NOT_AVAILABLE,
+ __func__);
+ });
+}
+
+} // namespace mozilla
diff --git a/extensions/spellcheck/hunspell/glue/RemoteSpellCheckEngineChild.h b/extensions/spellcheck/hunspell/glue/RemoteSpellCheckEngineChild.h
new file mode 100644
index 0000000000..06721d91ea
--- /dev/null
+++ b/extensions/spellcheck/hunspell/glue/RemoteSpellCheckEngineChild.h
@@ -0,0 +1,36 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef RemoteSpellcheckEngineChild_h_
+#define RemoteSpellcheckEngineChild_h_
+
+#include "mozilla/MozPromise.h"
+#include "mozilla/PRemoteSpellcheckEngineChild.h"
+#include "mozSpellChecker.h"
+
+class mozSpellChecker;
+
+namespace mozilla {
+
+class RemoteSpellcheckEngineChild
+ : public mozilla::PRemoteSpellcheckEngineChild {
+ public:
+ explicit RemoteSpellcheckEngineChild(mozSpellChecker* aOwner);
+ virtual ~RemoteSpellcheckEngineChild();
+
+ RefPtr<GenericPromise> SetCurrentDictionaries(
+ const nsTArray<nsCString>& aDictionaries);
+
+ RefPtr<GenericPromise> SetCurrentDictionaryFromList(
+ const nsTArray<nsCString>& aList);
+
+ RefPtr<CheckWordPromise> CheckWords(const nsTArray<nsString>& aWords);
+
+ private:
+ mozSpellChecker* mOwner;
+};
+
+} // namespace mozilla
+
+#endif // RemoteSpellcheckEngineChild_h_
diff --git a/extensions/spellcheck/hunspell/glue/RemoteSpellCheckEngineParent.cpp b/extensions/spellcheck/hunspell/glue/RemoteSpellCheckEngineParent.cpp
new file mode 100644
index 0000000000..e9f341d524
--- /dev/null
+++ b/extensions/spellcheck/hunspell/glue/RemoteSpellCheckEngineParent.cpp
@@ -0,0 +1,85 @@
+/* vim: set ts=2 sw=2 sts=2 tw=80: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "RemoteSpellCheckEngineParent.h"
+#include "mozilla/Unused.h"
+#include "mozilla/mozSpellChecker.h"
+#include "nsServiceManagerUtils.h"
+
+namespace mozilla {
+
+RemoteSpellcheckEngineParent::RemoteSpellcheckEngineParent() {
+ mSpellChecker = mozSpellChecker::Create();
+}
+
+RemoteSpellcheckEngineParent::~RemoteSpellcheckEngineParent() {}
+
+mozilla::ipc::IPCResult RemoteSpellcheckEngineParent::RecvSetDictionary(
+ const nsACString& aDictionary, bool* success) {
+ nsresult rv = mSpellChecker->SetCurrentDictionary(aDictionary);
+ *success = NS_SUCCEEDED(rv);
+ return IPC_OK();
+}
+
+mozilla::ipc::IPCResult RemoteSpellcheckEngineParent::RecvSetDictionaries(
+ const nsTArray<nsCString>& aDictionaries,
+ SetDictionariesResolver&& aResolve) {
+ mSpellChecker->SetCurrentDictionaries(aDictionaries)
+ ->Then(
+ GetMainThreadSerialEventTarget(), __func__,
+ [aResolve]() { aResolve(true); }, [aResolve]() { aResolve(false); });
+ return IPC_OK();
+}
+
+mozilla::ipc::IPCResult RemoteSpellcheckEngineParent::RecvSetDictionaryFromList(
+ nsTArray<nsCString>&& aList, SetDictionaryFromListResolver&& aResolve) {
+ for (auto& dictionary : aList) {
+ nsresult rv = mSpellChecker->SetCurrentDictionary(dictionary);
+ if (NS_SUCCEEDED(rv)) {
+ aResolve(std::tuple<const bool&, const nsACString&>(true, dictionary));
+ return IPC_OK();
+ }
+ }
+ aResolve(std::tuple<const bool&, const nsACString&>(false, ""_ns));
+ return IPC_OK();
+}
+
+mozilla::ipc::IPCResult RemoteSpellcheckEngineParent::RecvCheckAsync(
+ nsTArray<nsString>&& aWords, CheckAsyncResolver&& aResolve) {
+ nsTArray<bool> misspells;
+ misspells.SetCapacity(aWords.Length());
+ for (auto& word : aWords) {
+ bool misspelled;
+ nsresult rv = mSpellChecker->CheckWord(word, &misspelled, nullptr);
+ // If CheckWord failed, we can't tell whether the word is correctly spelled
+ if (NS_FAILED(rv)) {
+ misspelled = false;
+ }
+ misspells.AppendElement(misspelled);
+ }
+ aResolve(std::move(misspells));
+ return IPC_OK();
+}
+
+mozilla::ipc::IPCResult RemoteSpellcheckEngineParent::RecvSuggest(
+ const nsAString& aWord, uint32_t aCount, SuggestResolver&& aResolve) {
+ nsTArray<nsString> suggestions;
+ mSpellChecker->Suggest(aWord, aCount)
+ ->Then(
+ GetMainThreadSerialEventTarget(), __func__,
+ [aResolve](CopyableTArray<nsString> aSuggestions) {
+ aResolve(std::move(aSuggestions));
+ },
+ [aResolve](nsresult aError) {
+ // No suggestions due to error
+ nsTArray<nsString> suggestions;
+ aResolve(std::move(suggestions));
+ });
+ return IPC_OK();
+}
+
+void RemoteSpellcheckEngineParent::ActorDestroy(ActorDestroyReason aWhy) {}
+
+} // namespace mozilla
diff --git a/extensions/spellcheck/hunspell/glue/RemoteSpellCheckEngineParent.h b/extensions/spellcheck/hunspell/glue/RemoteSpellCheckEngineParent.h
new file mode 100644
index 0000000000..06f4a7e8f5
--- /dev/null
+++ b/extensions/spellcheck/hunspell/glue/RemoteSpellCheckEngineParent.h
@@ -0,0 +1,46 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+#ifndef RemoteSpellcheckEngineParent_h_
+#define RemoteSpellcheckEngineParent_h_
+
+#include "mozilla/PRemoteSpellcheckEngineParent.h"
+#include "nsCOMPtr.h"
+#include "nsTArray.h"
+
+class mozSpellChecker;
+
+namespace mozilla {
+
+class RemoteSpellcheckEngineParent : public PRemoteSpellcheckEngineParent {
+ public:
+ RemoteSpellcheckEngineParent();
+
+ virtual ~RemoteSpellcheckEngineParent();
+
+ virtual void ActorDestroy(ActorDestroyReason aWhy) override;
+
+ virtual mozilla::ipc::IPCResult RecvSetDictionary(
+ const nsACString& aDictionary, bool* success);
+
+ virtual mozilla::ipc::IPCResult RecvSetDictionaries(
+ const nsTArray<nsCString>& aDictionaries,
+ SetDictionariesResolver&& aResolve);
+
+ virtual mozilla::ipc::IPCResult RecvSetDictionaryFromList(
+ nsTArray<nsCString>&& aList, SetDictionaryFromListResolver&& aResolve);
+
+ virtual mozilla::ipc::IPCResult RecvCheckAsync(nsTArray<nsString>&& aWord,
+ CheckAsyncResolver&& aResolve);
+
+ virtual mozilla::ipc::IPCResult RecvSuggest(const nsAString& aWord,
+ uint32_t aCount,
+ SuggestResolver&& aResolve);
+
+ private:
+ RefPtr<mozSpellChecker> mSpellChecker;
+};
+
+} // namespace mozilla
+
+#endif
diff --git a/extensions/spellcheck/hunspell/glue/common.mozbuild b/extensions/spellcheck/hunspell/glue/common.mozbuild
new file mode 100644
index 0000000000..ded414075e
--- /dev/null
+++ b/extensions/spellcheck/hunspell/glue/common.mozbuild
@@ -0,0 +1,9 @@
+# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
+# vim: set filetype=python:
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+@template
+def HunspellIncludes():
+ ForceInclude('hunspell_alloc_hooks.h', 'hunspell_fopen_hooks.h')
diff --git a/extensions/spellcheck/hunspell/glue/hunspell_alloc_hooks.h b/extensions/spellcheck/hunspell/glue/hunspell_alloc_hooks.h
new file mode 100644
index 0000000000..27a719d788
--- /dev/null
+++ b/extensions/spellcheck/hunspell/glue/hunspell_alloc_hooks.h
@@ -0,0 +1,59 @@
+/******* BEGIN LICENSE BLOCK *******
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (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.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Initial Developers of the Original Code is Mozilla Foundation.
+ * Portions created by the Initial Developers
+ * are Copyright (C) 2011 the Initial Developers. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ ******* END LICENSE BLOCK *******/
+
+#ifndef alloc_hooks_h__
+#define alloc_hooks_h__
+
+/**
+ * This file is force-included in hunspell code. Its purpose is to add memory
+ * reporting to hunspell without modifying its code, in order to ease future
+ * upgrades.
+ *
+ * Currently, the memory allocated using operator new/new[] is not being
+ * tracked, but that's OK, since almost all of the memory used by Hunspell is
+ * allocated using C memory allocation functions.
+ */
+
+#include "mozHunspellAllocator.h"
+
+// Ensure that malloc is imported before we set our malloc-counting hooks below.
+// Otherwise, if malloc is imported afterwards, its source will be trampled
+// over by the "#define"s.
+#include "mozmemory.h"
+
+#define malloc(size) HunspellAllocator::CountingMalloc(size)
+#define calloc(count, size) HunspellAllocator::CountingCalloc(count, size)
+#define free(ptr) HunspellAllocator::CountingFree(ptr)
+#define realloc(ptr, size) HunspellAllocator::CountingRealloc(ptr, size)
+
+#endif
diff --git a/extensions/spellcheck/hunspell/glue/hunspell_csutil.cxx b/extensions/spellcheck/hunspell/glue/hunspell_csutil.cxx
new file mode 100644
index 0000000000..0f5565a12c
--- /dev/null
+++ b/extensions/spellcheck/hunspell/glue/hunspell_csutil.cxx
@@ -0,0 +1,160 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * Copyright (C) 2002-2017 N辿meth L叩szl坦
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (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.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * Hunspell is based on MySpell which is Copyright (C) 2002 Kevin Hendricks.
+ *
+ * Contributor(s): David Einstein, Davide Prina, Giuseppe Modugno,
+ * Gianluca Turconi, Simon Brouwer, Noll J叩nos, B鱈r坦 rp叩d,
+ * Goldman Eleon坦ra, Sarl坦s Tam叩s, Bencs叩th Boldizs叩r, Hal叩csy P辿ter,
+ * Dvornik L叩szl坦, Gefferth Andr叩s, Nagy Viktor, Varga D叩niel, Chris Halls,
+ * Rene Engelhard, Bram Moolenaar, Dafydd Jones, Harri Pitk辰nen
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+/*
+ * Copyright 2002 Kevin B. Hendricks, Stratford, Ontario, Canada
+ * And Contributors. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. All modifications to the source code must be clearly marked as
+ * such. Binary redistributions based on modified source code
+ * must be clearly marked as modified versions in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY KEVIN B. HENDRICKS AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
+ * KEVIN B. HENDRICKS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+#include "hunspell_csutil.hxx"
+#include "mozilla/Encoding.h"
+#include "mozilla/Span.h"
+#include "nsUnicharUtils.h"
+
+/* This is a copy of get_current_cs from the hunspell csutil.cxx file.
+ */
+struct cs_info* hunspell_get_current_cs(const std::string& es) {
+ struct cs_info* ccs = new cs_info[256];
+ // Initialze the array with dummy data so that we wouldn't need
+ // to return null in case of failures.
+ for (int i = 0; i <= 0xff; ++i) {
+ ccs[i].ccase = false;
+ ccs[i].clower = i;
+ ccs[i].cupper = i;
+ }
+
+ auto encoding = mozilla::Encoding::ForLabelNoReplacement(es);
+ if (!encoding) {
+ return ccs;
+ }
+ auto encoder = encoding->NewEncoder();
+ auto decoder = encoding->NewDecoderWithoutBOMHandling();
+
+ for (unsigned int i = 0; i <= 0xff; ++i) {
+ bool success = false;
+ // We want to find the upper/lowercase equivalents of each byte
+ // in this 1-byte character encoding. Call our encoding/decoding
+ // APIs separately for each byte since they may reject some of the
+ // bytes, and we want to handle errors separately for each byte.
+ uint8_t lower, upper;
+ do {
+ if (i == 0) break;
+ uint8_t source = uint8_t(i);
+ char16_t uni[2];
+ char16_t uniCased;
+ uint8_t destination[4];
+ auto src1 = mozilla::Span(&source, 1);
+ auto dst1 = mozilla::Span(uni);
+ auto src2 = mozilla::Span(&uniCased, 1);
+ auto dst2 = mozilla::Span(destination);
+
+ uint32_t result;
+ size_t read;
+ size_t written;
+ std::tie(result, read, written) =
+ decoder->DecodeToUTF16WithoutReplacement(src1, dst1, true);
+ if (result != mozilla::kInputEmpty || read != 1 || written != 1) {
+ break;
+ }
+
+ uniCased = ToLowerCase(uni[0]);
+ std::tie(result, read, written) =
+ encoder->EncodeFromUTF16WithoutReplacement(src2, dst2, true);
+ if (result != mozilla::kInputEmpty || read != 1 || written != 1) {
+ break;
+ }
+ lower = destination[0];
+
+ uniCased = ToUpperCase(uni[0]);
+ std::tie(result, read, written) =
+ encoder->EncodeFromUTF16WithoutReplacement(src2, dst2, true);
+ if (result != mozilla::kInputEmpty || read != 1 || written != 1) {
+ break;
+ }
+ upper = destination[0];
+
+ success = true;
+ } while (0);
+
+ encoding->NewEncoderInto(*encoder);
+ encoding->NewDecoderWithoutBOMHandlingInto(*decoder);
+
+ if (success) {
+ ccs[i].cupper = upper;
+ ccs[i].clower = lower;
+ } else {
+ ccs[i].cupper = i;
+ ccs[i].clower = i;
+ }
+
+ if (ccs[i].clower != (unsigned char)i)
+ ccs[i].ccase = true;
+ else
+ ccs[i].ccase = false;
+ }
+
+ return ccs;
+}
diff --git a/extensions/spellcheck/hunspell/glue/hunspell_csutil.hxx b/extensions/spellcheck/hunspell/glue/hunspell_csutil.hxx
new file mode 100644
index 0000000000..00dd89a964
--- /dev/null
+++ b/extensions/spellcheck/hunspell/glue/hunspell_csutil.hxx
@@ -0,0 +1,87 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * Copyright (C) 2002-2017 N辿meth L叩szl坦
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (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.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * Hunspell is based on MySpell which is Copyright (C) 2002 Kevin Hendricks.
+ *
+ * Contributor(s): David Einstein, Davide Prina, Giuseppe Modugno,
+ * Gianluca Turconi, Simon Brouwer, Noll J叩nos, B鱈r坦 rp叩d,
+ * Goldman Eleon坦ra, Sarl坦s Tam叩s, Bencs叩th Boldizs叩r, Hal叩csy P辿ter,
+ * Dvornik L叩szl坦, Gefferth Andr叩s, Nagy Viktor, Varga D叩niel, Chris Halls,
+ * Rene Engelhard, Bram Moolenaar, Dafydd Jones, Harri Pitk辰nen
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+/*
+ * Copyright 2002 Kevin B. Hendricks, Stratford, Ontario, Canada
+ * And Contributors. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. All modifications to the source code must be clearly marked as
+ * such. Binary redistributions based on modified source code
+ * must be clearly marked as modified versions in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY KEVIN B. HENDRICKS AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
+ * KEVIN B. HENDRICKS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+#ifndef EXTENSIONS_SPELLCHECK_HUNSPELL_GLUE_HUNSPELL_CSUTIL_H_
+#define EXTENSIONS_SPELLCHECK_HUNSPELL_GLUE_HUNSPELL_CSUTIL_H_
+
+/* We need get_current_cs from hunspell's csutil to live outside the RLBox
+ * sandbox (since it relies on a Gecko encoding bits) and then expose it to the
+ * sandboxed hunspell.
+ */
+
+struct cs_info {
+ unsigned char ccase;
+ unsigned char clower;
+ unsigned char cupper;
+};
+
+struct cs_info* hunspell_get_current_cs(const std::string& es);
+
+#endif
diff --git a/extensions/spellcheck/hunspell/glue/hunspell_fopen_hooks.h b/extensions/spellcheck/hunspell/glue/hunspell_fopen_hooks.h
new file mode 100644
index 0000000000..7388b1daa7
--- /dev/null
+++ b/extensions/spellcheck/hunspell/glue/hunspell_fopen_hooks.h
@@ -0,0 +1,81 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef fopen_hooks_h__
+#define fopen_hooks_h__
+
+/**
+ * This file is force-included in hunspell code. Its purpose is to add
+ * readahead to fopen() calls in hunspell without modifying its code, in order
+ * to ease future upgrades.
+ */
+
+#include "mozilla/FileUtils.h"
+#include <stdio.h>
+#include <string.h>
+
+#if defined(XP_WIN)
+# include "nsNativeCharsetUtils.h"
+# include "nsString.h"
+
+# include <fcntl.h>
+# include <windows.h>
+// Hunspell defines a function named near. Windef.h #defines near.
+# undef near
+// mozHunspell defines a function named RemoveDirectory.
+# undef RemoveDirectory
+#endif /* defined(XP_WIN) */
+
+inline FILE* hunspell_fopen_readahead(const char* filename, const char* mode) {
+ if (!filename || !mode) {
+ return nullptr;
+ }
+ // Fall back to libc's fopen for modes not supported by ReadAheadFile
+ if (!strchr(mode, 'r') || strchr(mode, '+')) {
+ return fopen(filename, mode);
+ }
+ int fd = -1;
+#if defined(XP_WIN)
+ // filename is obtained via the nsIFile::nativePath attribute, so
+ // it is using the Windows ANSI code page, NOT UTF-8!
+ nsAutoString utf16Filename;
+ nsresult rv =
+ NS_CopyNativeToUnicode(nsDependentCString(filename), utf16Filename);
+ if (NS_FAILED(rv)) {
+ return nullptr;
+ }
+ HANDLE handle = INVALID_HANDLE_VALUE;
+ mozilla::ReadAheadFile(utf16Filename.get(), 0, SIZE_MAX, &handle);
+ if (handle == INVALID_HANDLE_VALUE) {
+ return nullptr;
+ }
+ int flags = _O_RDONLY;
+ // MSVC CRT's _open_osfhandle only supports adding _O_TEXT, not _O_BINARY
+ if (strchr(mode, 't')) {
+ // Force translated mode
+ flags |= _O_TEXT;
+ }
+ // Import the Win32 fd into the CRT
+ fd = _open_osfhandle((intptr_t)handle, flags);
+ if (fd < 0) {
+ CloseHandle(handle);
+ return nullptr;
+ }
+#else
+ mozilla::ReadAheadFile(filename, 0, SIZE_MAX, &fd);
+ if (fd < 0) {
+ return nullptr;
+ }
+#endif /* defined(XP_WIN) */
+
+ FILE* file = fdopen(fd, mode);
+ if (!file) {
+ close(fd);
+ }
+ return file;
+}
+
+#define fopen(filename, mode) hunspell_fopen_readahead(filename, mode)
+
+#endif /* fopen_hooks_h__ */
diff --git a/extensions/spellcheck/hunspell/glue/moz.build b/extensions/spellcheck/hunspell/glue/moz.build
new file mode 100644
index 0000000000..7cde4156c7
--- /dev/null
+++ b/extensions/spellcheck/hunspell/glue/moz.build
@@ -0,0 +1,39 @@
+# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
+# vim: set filetype=python:
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+UNIFIED_SOURCES += [
+ "hunspell_csutil.cxx",
+ "mozHunspell.cpp",
+ "mozHunspellRLBoxHost.cpp",
+ "RemoteSpellCheckEngineChild.cpp",
+ "RemoteSpellCheckEngineParent.cpp",
+ "RLBoxHunspell.cpp",
+]
+
+DEFINES["HUNSPELL_STATIC"] = True
+
+FINAL_LIBRARY = "xul"
+
+LOCAL_INCLUDES += [
+ "!/security/rlbox",
+ "../src",
+ "/dom/base",
+ "/extensions/spellcheck/src",
+]
+
+include("/ipc/chromium/chromium-config.mozbuild")
+include("common.mozbuild")
+
+HunspellIncludes()
+
+IPDL_SOURCES = [
+ "PRemoteSpellcheckEngine.ipdl",
+]
+
+EXPORTS.mozilla += [
+ "RemoteSpellCheckEngineChild.h",
+ "RemoteSpellCheckEngineParent.h",
+]
diff --git a/extensions/spellcheck/hunspell/glue/mozHunspell.cpp b/extensions/spellcheck/hunspell/glue/mozHunspell.cpp
new file mode 100644
index 0000000000..a69dcd6b05
--- /dev/null
+++ b/extensions/spellcheck/hunspell/glue/mozHunspell.cpp
@@ -0,0 +1,594 @@
+/******* BEGIN LICENSE BLOCK *******
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (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.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Initial Developers of the Original Code are Kevin Hendricks (MySpell)
+ * and L叩szl坦 N辿meth (Hunspell). Portions created by the Initial Developers
+ * are Copyright (C) 2002-2005 the Initial Developers. All Rights Reserved.
+ *
+ * Contributor(s): Kevin Hendricks (kevin.hendricks@sympatico.ca)
+ * David Einstein (deinst@world.std.com)
+ * Michiel van Leeuwen (mvl@exedo.nl)
+ * Caolan McNamara (cmc@openoffice.org)
+ * L叩szl坦 N辿meth (nemethl@gyorsposta.hu)
+ * Davide Prina
+ * Giuseppe Modugno
+ * Gianluca Turconi
+ * Simon Brouwer
+ * Noll Janos
+ * Biro Arpad
+ * Goldman Eleonora
+ * Sarlos Tamas
+ * Bencsath Boldizsar
+ * Halacsy Peter
+ * Dvornik Laszlo
+ * Gefferth Andras
+ * Nagy Viktor
+ * Varga Daniel
+ * Chris Halls
+ * Rene Engelhard
+ * Bram Moolenaar
+ * Dafydd Jones
+ * Harri Pitkanen
+ * Andras Timar
+ * Tor Lillqvist
+ * Jesper Kristensen (mail@jesperkristensen.dk)
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ ******* END LICENSE BLOCK *******/
+
+#include "mozHunspell.h"
+#include "nsReadableUtils.h"
+#include "nsString.h"
+#include "nsIObserverService.h"
+#include "nsIDirectoryEnumerator.h"
+#include "nsIFile.h"
+#include "nsUnicharUtils.h"
+#include "nsCRT.h"
+#include "mozInlineSpellChecker.h"
+#include "nsIPrefBranch.h"
+#include "nsIPrefService.h"
+#include "nsNetUtil.h"
+#include "mozilla/dom/ContentParent.h"
+#include "mozilla/Components.h"
+#include "mozilla/Services.h"
+
+#include <stdlib.h>
+#include <tuple>
+
+using mozilla::dom::ContentParent;
+using namespace mozilla;
+
+NS_IMPL_CYCLE_COLLECTING_ADDREF(mozHunspell)
+NS_IMPL_CYCLE_COLLECTING_RELEASE(mozHunspell)
+
+NS_INTERFACE_MAP_BEGIN(mozHunspell)
+ NS_INTERFACE_MAP_ENTRY(mozISpellCheckingEngine)
+ NS_INTERFACE_MAP_ENTRY(nsIObserver)
+ NS_INTERFACE_MAP_ENTRY(nsISupportsWeakReference)
+ NS_INTERFACE_MAP_ENTRY(nsIMemoryReporter)
+ NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, mozISpellCheckingEngine)
+ NS_INTERFACE_MAP_ENTRIES_CYCLE_COLLECTION(mozHunspell)
+NS_INTERFACE_MAP_END
+
+NS_IMPL_CYCLE_COLLECTION_WEAK(mozHunspell, mPersonalDictionary)
+
+NS_IMPL_COMPONENT_FACTORY(mozHunspell) {
+ auto hunspell = MakeRefPtr<mozHunspell>();
+ if (NS_SUCCEEDED(hunspell->Init())) {
+ return hunspell.forget().downcast<mozISpellCheckingEngine>();
+ }
+ return nullptr;
+}
+
+mozHunspell::mozHunspell() {
+#ifdef DEBUG
+ // There must be only one instance of this class: it reports memory based on
+ // a single static count in HunspellAllocator.
+ static bool hasRun = false;
+ MOZ_ASSERT(!hasRun);
+ hasRun = true;
+#endif
+}
+
+nsresult mozHunspell::Init() {
+ LoadDictionaryList(false);
+
+ nsCOMPtr<nsIObserverService> obs = mozilla::services::GetObserverService();
+ if (obs) {
+ obs->AddObserver(this, "profile-do-change", true);
+ obs->AddObserver(this, "profile-after-change", true);
+ }
+
+ mozilla::RegisterWeakMemoryReporter(this);
+
+ return NS_OK;
+}
+
+mozHunspell::~mozHunspell() {
+ mozilla::UnregisterWeakMemoryReporter(this);
+
+ mPersonalDictionary = nullptr;
+ mHunspells.Clear();
+}
+
+NS_IMETHODIMP
+mozHunspell::GetDictionaries(nsTArray<nsCString>& aDictionaries) {
+ MOZ_ASSERT(aDictionaries.IsEmpty());
+ for (auto iter = mHunspells.ConstIter(); !iter.Done(); iter.Next()) {
+ if (iter.Data().mEnabled) {
+ aDictionaries.AppendElement(iter.Key());
+ }
+ }
+ return NS_OK;
+}
+
+/* Set the Dictionaries.
+ * This also Loads the dictionaries and initializes the converter using the
+ * dictionaries converter
+ */
+NS_IMETHODIMP
+mozHunspell::SetDictionaries(const nsTArray<nsCString>& aDictionaries) {
+ if (aDictionaries.IsEmpty()) {
+ mHunspells.Clear();
+ return NS_OK;
+ }
+
+ // Disable any dictionaries we've already loaded that we're not
+ // going to use.
+ for (auto iter = mHunspells.Iter(); !iter.Done(); iter.Next()) {
+ if (!aDictionaries.Contains(iter.Key())) {
+ iter.Data().mEnabled = false;
+ }
+ }
+
+ bool firstDictionary = true;
+ for (const auto& dictionary : aDictionaries) {
+ NS_ConvertUTF8toUTF16 dict(dictionary);
+ nsIURI* affFile = mDictionaries.GetWeak(dict);
+ if (!affFile) {
+ return NS_ERROR_FILE_NOT_FOUND;
+ }
+
+ nsAutoCString affFileName;
+ nsresult rv = affFile->GetSpec(affFileName);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ if (auto entry = mHunspells.Lookup(dictionary)) {
+ if (entry.Data().mAffixFileName == affFileName) {
+ entry.Data().mEnabled = true;
+ continue;
+ }
+ }
+
+ DictionaryData dictionaryData;
+ dictionaryData.mAffixFileName = affFileName;
+
+ // Load the first dictionary now, we'll load the others lazily during
+ // checking.
+ if (firstDictionary) {
+ rv = dictionaryData.LoadIfNecessary();
+ NS_ENSURE_SUCCESS(rv, rv);
+ firstDictionary = false;
+ }
+
+ mHunspells.InsertOrUpdate(dictionary, std::move(dictionaryData));
+ }
+
+ // If we have a large number of dictionaries loaded, try freeing any disabled
+ // dictionaries to limit memory use.
+ if (mHunspells.Count() > 10) {
+ mHunspells.RemoveIf([](const auto& iter) { return !iter.Data().mEnabled; });
+ }
+
+ return NS_OK;
+}
+
+NS_IMETHODIMP mozHunspell::GetPersonalDictionary(
+ mozIPersonalDictionary** aPersonalDictionary) {
+ *aPersonalDictionary = mPersonalDictionary;
+ NS_IF_ADDREF(*aPersonalDictionary);
+ return NS_OK;
+}
+
+NS_IMETHODIMP mozHunspell::SetPersonalDictionary(
+ mozIPersonalDictionary* aPersonalDictionary) {
+ mPersonalDictionary = aPersonalDictionary;
+ return NS_OK;
+}
+
+NS_IMETHODIMP mozHunspell::GetDictionaryList(
+ nsTArray<nsCString>& aDictionaries) {
+ MOZ_ASSERT(aDictionaries.IsEmpty());
+ for (const auto& key : mDictionaries.Keys()) {
+ aDictionaries.AppendElement(NS_ConvertUTF16toUTF8(key));
+ }
+
+ return NS_OK;
+}
+
+void mozHunspell::LoadDictionaryList(bool aNotifyChildProcesses) {
+ mDictionaries.Clear();
+
+ nsresult rv;
+
+ // find built in dictionaries, or dictionaries specified in
+ // spellchecker.dictionary_path in prefs
+ nsCOMPtr<nsIFile> dictDir;
+
+ // check preferences first
+ nsCOMPtr<nsIPrefBranch> prefs(do_GetService(NS_PREFSERVICE_CONTRACTID));
+ if (prefs) {
+ nsAutoCString extDictPath;
+ rv = prefs->GetCharPref("spellchecker.dictionary_path", extDictPath);
+ if (NS_SUCCEEDED(rv)) {
+ // set the spellchecker.dictionary_path
+ rv = NS_NewNativeLocalFile(extDictPath, true, getter_AddRefs(dictDir));
+ }
+ if (dictDir) {
+ LoadDictionariesFromDir(dictDir);
+ }
+ }
+
+ // find dictionaries in DICPATH
+ char* dicEnv = PR_GetEnv("DICPATH");
+ if (dicEnv) {
+ // do a two-pass dance so dictionaries are loaded right-to-left as
+ // preference
+ nsTArray<nsCOMPtr<nsIFile>> dirs;
+ nsAutoCString env(dicEnv); // assume dicEnv is UTF-8
+
+ char* currPath = nullptr;
+ char* nextPaths = env.BeginWriting();
+ while ((currPath = NS_strtok(":", &nextPaths))) {
+ nsCOMPtr<nsIFile> dir;
+ rv =
+ NS_NewNativeLocalFile(nsCString(currPath), true, getter_AddRefs(dir));
+ if (NS_SUCCEEDED(rv)) {
+ dirs.AppendElement(dir);
+ }
+ }
+
+ // load them in reverse order so they override each other properly
+ for (int32_t i = dirs.Length() - 1; i >= 0; i--) {
+ LoadDictionariesFromDir(dirs[i]);
+ }
+ }
+
+ // find dictionaries from restartless extensions
+ for (int32_t i = 0; i < mDynamicDirectories.Count(); i++) {
+ LoadDictionariesFromDir(mDynamicDirectories[i]);
+ }
+
+ for (const auto& dictionaryEntry : mDynamicDictionaries) {
+ mDictionaries.InsertOrUpdate(dictionaryEntry.GetKey(),
+ dictionaryEntry.GetData());
+ }
+
+ DictionariesChanged(aNotifyChildProcesses);
+}
+
+void mozHunspell::DictionariesChanged(bool aNotifyChildProcesses) {
+ // Now we have finished updating the list of dictionaries, update the current
+ // dictionary and any editors which may use it.
+ mozInlineSpellChecker::UpdateCanEnableInlineSpellChecking();
+
+ if (aNotifyChildProcesses) {
+ ContentParent::NotifyUpdatedDictionaries();
+ }
+
+ // Check if the current dictionaries are still available.
+ // If not, try to replace it with other dictionaries of the same language.
+ if (!mHunspells.IsEmpty()) {
+ nsTArray<nsCString> dictionaries;
+ for (auto iter = mHunspells.ConstIter(); !iter.Done(); iter.Next()) {
+ if (iter.Data().mEnabled) {
+ dictionaries.AppendElement(iter.Key());
+ }
+ }
+ nsresult rv = SetDictionaries(dictionaries);
+ if (NS_SUCCEEDED(rv)) return;
+ }
+
+ // If the current dictionaries are gone, and we don't have a good replacement,
+ // set no current dictionary.
+ if (!mHunspells.IsEmpty()) {
+ nsTArray<nsCString> empty;
+ SetDictionaries(empty);
+ }
+}
+
+NS_IMETHODIMP
+mozHunspell::LoadDictionariesFromDir(nsIFile* aDir) {
+ nsresult rv;
+
+ bool check = false;
+ rv = aDir->Exists(&check);
+ if (NS_FAILED(rv) || !check) return NS_ERROR_UNEXPECTED;
+
+ rv = aDir->IsDirectory(&check);
+ if (NS_FAILED(rv) || !check) return NS_ERROR_UNEXPECTED;
+
+ nsCOMPtr<nsIDirectoryEnumerator> files;
+ rv = aDir->GetDirectoryEntries(getter_AddRefs(files));
+ if (NS_FAILED(rv)) return NS_ERROR_UNEXPECTED;
+
+ nsCOMPtr<nsIFile> file;
+ while (NS_SUCCEEDED(files->GetNextFile(getter_AddRefs(file))) && file) {
+ nsAutoString leafName;
+ file->GetLeafName(leafName);
+ if (!StringEndsWith(leafName, u".dic"_ns)) continue;
+
+ nsAutoString dict(leafName);
+ dict.SetLength(dict.Length() - 4); // magic length of ".dic"
+
+ // check for the presence of the .aff file
+ leafName = dict;
+ leafName.AppendLiteral(".aff");
+ file->SetLeafName(leafName);
+ rv = file->Exists(&check);
+ if (NS_FAILED(rv) || !check) continue;
+
+ // Replace '_' separator with '-'
+ dict.ReplaceChar('_', '-');
+
+ nsCOMPtr<nsIURI> uri;
+ rv = NS_NewFileURI(getter_AddRefs(uri), file);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ mDictionaries.InsertOrUpdate(dict, uri);
+ }
+
+ return NS_OK;
+}
+
+nsresult mozHunspell::DictionaryData::ConvertCharset(const nsAString& aStr,
+ std::string& aDst) {
+ if (NS_WARN_IF(!mEncoder)) {
+ return NS_ERROR_NOT_INITIALIZED;
+ }
+
+ auto src = Span(aStr.BeginReading(), aStr.Length());
+ CheckedInt<size_t> needed =
+ mEncoder->MaxBufferLengthFromUTF16WithoutReplacement(src.Length());
+ if (!needed.isValid()) {
+ return NS_ERROR_OUT_OF_MEMORY;
+ }
+
+ aDst.resize(needed.value());
+
+ char* dstPtr = &aDst[0];
+ auto dst = Span(reinterpret_cast<uint8_t*>(dstPtr), needed.value());
+
+ uint32_t result;
+ size_t written;
+ std::tie(result, std::ignore, written) =
+ mEncoder->EncodeFromUTF16WithoutReplacement(src, dst, true);
+ MOZ_ASSERT(result != kOutputFull);
+ if (result != kInputEmpty) {
+ return NS_ERROR_UENC_NOMAPPING;
+ }
+ aDst.resize(written);
+ mEncoder->Encoding()->NewEncoderInto(*mEncoder);
+ return NS_OK;
+}
+
+nsresult mozHunspell::DictionaryData::LoadIfNecessary() {
+ if (mHunspell && mEncoder && mDecoder) {
+ return NS_OK;
+ }
+
+ if (mLoadFailed) {
+ return NS_ERROR_FAILURE;
+ }
+
+ nsCString dictFileName = mAffixFileName;
+ int32_t dotPos = dictFileName.RFindChar('.');
+ if (dotPos == -1) {
+ mLoadFailed = true;
+ return NS_ERROR_FAILURE;
+ }
+ dictFileName.SetLength(dotPos);
+ dictFileName.AppendLiteral(".dic");
+
+ UniquePtr<RLBoxHunspell> hunspell(
+ RLBoxHunspell::Create(mAffixFileName, dictFileName));
+ if (!hunspell) {
+ mLoadFailed = true;
+ // TODO Bug 1788857: Verify error propagation in case of inaccessible file
+ return NS_ERROR_OUT_OF_MEMORY;
+ }
+ mHunspell = std::move(hunspell);
+ auto encoding =
+ Encoding::ForLabelNoReplacement(mHunspell->get_dict_encoding());
+ if (!encoding) {
+ mLoadFailed = true;
+ return NS_ERROR_UCONV_NOCONV;
+ }
+ mEncoder = encoding->NewEncoder();
+ mDecoder = encoding->NewDecoderWithoutBOMHandling();
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+mozHunspell::CollectReports(nsIHandleReportCallback* aHandleReport,
+ nsISupports* aData, bool aAnonymize) {
+ MOZ_COLLECT_REPORT("explicit/spell-check", KIND_HEAP, UNITS_BYTES,
+ HunspellAllocator::MemoryAllocated(),
+ "Memory used by the spell-checking engine.");
+
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+mozHunspell::Check(const nsAString& aWord, bool* aResult) {
+ if (NS_WARN_IF(!aResult)) {
+ return NS_ERROR_INVALID_ARG;
+ }
+
+ if (NS_WARN_IF(mHunspells.IsEmpty())) {
+ return NS_ERROR_FAILURE;
+ }
+
+ *aResult = true;
+ for (auto iter = mHunspells.Iter(); !iter.Done(); iter.Next()) {
+ if (!iter.Data().mEnabled) {
+ continue;
+ }
+
+ nsresult rv = iter.Data().LoadIfNecessary();
+ if (NS_FAILED(rv)) {
+ continue;
+ }
+
+ std::string charsetWord;
+ rv = iter.Data().ConvertCharset(aWord, charsetWord);
+ if (NS_FAILED(rv)) {
+ continue;
+ }
+
+ // Depending upon the encoding, we might end up with a string that begins
+ // with the null byte. Since the hunspell interface uses C-style strings,
+ // this appears like an empty string, and hunspell marks empty strings as
+ // spelled correctly. Skip these cases to allow another dictionary to have
+ // the chance to spellcheck them.
+ if (charsetWord.empty() || charsetWord[0] == 0) {
+ continue;
+ }
+
+ *aResult = iter.Data().mHunspell->spell(charsetWord);
+ if (*aResult) {
+ break;
+ }
+ }
+
+ if (!*aResult && mPersonalDictionary) {
+ return mPersonalDictionary->Check(aWord, aResult);
+ }
+
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+mozHunspell::Suggest(const nsAString& aWord, nsTArray<nsString>& aSuggestions) {
+ if (NS_WARN_IF(mHunspells.IsEmpty())) {
+ return NS_ERROR_FAILURE;
+ }
+
+ MOZ_ASSERT(aSuggestions.IsEmpty());
+
+ for (auto iter = mHunspells.Iter(); !iter.Done(); iter.Next()) {
+ if (!iter.Data().mEnabled) {
+ continue;
+ }
+
+ nsresult rv = iter.Data().LoadIfNecessary();
+ if (NS_FAILED(rv)) {
+ continue;
+ }
+
+ std::string charsetWord;
+ rv = iter.Data().ConvertCharset(aWord, charsetWord);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ std::vector<std::string> suggestions =
+ iter.Data().mHunspell->suggest(charsetWord);
+ if (!suggestions.empty()) {
+ aSuggestions.SetCapacity(aSuggestions.Length() + suggestions.size());
+ for (Span<const char> charSrc : suggestions) {
+ // Convert the suggestion to utf16
+ auto src = AsBytes(charSrc);
+ nsresult rv =
+ iter.Data().mDecoder->Encoding()->DecodeWithoutBOMHandling(
+ src, *aSuggestions.AppendElement());
+ NS_ENSURE_SUCCESS(rv, rv);
+ iter.Data().mDecoder->Encoding()->NewDecoderWithoutBOMHandlingInto(
+ *iter.Data().mDecoder);
+ }
+ }
+ }
+
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+mozHunspell::Observe(nsISupports* aSubj, const char* aTopic,
+ const char16_t* aData) {
+ NS_ASSERTION(!strcmp(aTopic, "profile-do-change") ||
+ !strcmp(aTopic, "profile-after-change"),
+ "Unexpected observer topic");
+
+ LoadDictionaryList(false);
+
+ return NS_OK;
+}
+
+NS_IMETHODIMP mozHunspell::AddDirectory(nsIFile* aDir) {
+ mDynamicDirectories.AppendObject(aDir);
+ LoadDictionaryList(true);
+ return NS_OK;
+}
+
+NS_IMETHODIMP mozHunspell::RemoveDirectory(nsIFile* aDir) {
+ mDynamicDirectories.RemoveObject(aDir);
+ LoadDictionaryList(true);
+
+#ifdef MOZ_THUNDERBIRD
+ /*
+ * This notification is needed for Thunderbird. Thunderbird derives the
+ * dictionary from the document's "lang" attribute. If a dictionary is
+ * removed, we need to change the "lang" attribute.
+ */
+ nsCOMPtr<nsIObserverService> obs = mozilla::services::GetObserverService();
+ if (obs) {
+ obs->NotifyObservers(nullptr, SPELLCHECK_DICTIONARY_REMOVE_NOTIFICATION,
+ nullptr);
+ }
+#endif
+ return NS_OK;
+}
+
+NS_IMETHODIMP mozHunspell::AddDictionary(const nsAString& aLang,
+ nsIURI* aFile) {
+ NS_ENSURE_TRUE(aFile, NS_ERROR_INVALID_ARG);
+
+ mDynamicDictionaries.InsertOrUpdate(aLang, aFile);
+ mDictionaries.InsertOrUpdate(aLang, aFile);
+ DictionariesChanged(true);
+ return NS_OK;
+}
+
+NS_IMETHODIMP mozHunspell::RemoveDictionary(const nsAString& aLang,
+ nsIURI* aFile, bool* aRetVal) {
+ NS_ENSURE_TRUE(aFile, NS_ERROR_INVALID_ARG);
+ *aRetVal = false;
+
+ nsCOMPtr<nsIURI> file = mDynamicDictionaries.Get(aLang);
+ bool equal;
+ if (file && NS_SUCCEEDED(file->Equals(aFile, &equal)) && equal) {
+ mDynamicDictionaries.Remove(aLang);
+ LoadDictionaryList(true);
+ *aRetVal = true;
+ }
+ return NS_OK;
+}
diff --git a/extensions/spellcheck/hunspell/glue/mozHunspell.h b/extensions/spellcheck/hunspell/glue/mozHunspell.h
new file mode 100644
index 0000000000..89a38d9e49
--- /dev/null
+++ b/extensions/spellcheck/hunspell/glue/mozHunspell.h
@@ -0,0 +1,145 @@
+/******* BEGIN LICENSE BLOCK *******
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (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.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Initial Developers of the Original Code are Kevin Hendricks (MySpell)
+ * and L叩szl坦 N辿meth (Hunspell). Portions created by the Initial Developers
+ * are Copyright (C) 2002-2005 the Initial Developers. All Rights Reserved.
+ *
+ * Contributor(s): Kevin Hendricks (kevin.hendricks@sympatico.ca)
+ * David Einstein (deinst@world.std.com)
+ * Michiel van Leeuwen (mvl@exedo.nl)
+ * Caolan McNamara (cmc@openoffice.org)
+ * L叩szl坦 N辿meth (nemethl@gyorsposta.hu)
+ * Davide Prina
+ * Giuseppe Modugno
+ * Gianluca Turconi
+ * Simon Brouwer
+ * Noll Janos
+ * Biro Arpad
+ * Goldman Eleonora
+ * Sarlos Tamas
+ * Bencsath Boldizsar
+ * Halacsy Peter
+ * Dvornik Laszlo
+ * Gefferth Andras
+ * Nagy Viktor
+ * Varga Daniel
+ * Chris Halls
+ * Rene Engelhard
+ * Bram Moolenaar
+ * Dafydd Jones
+ * Harri Pitkanen
+ * Andras Timar
+ * Tor Lillqvist
+ * Jesper Kristensen (mail@jesperkristensen.dk)
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ ******* END LICENSE BLOCK *******/
+
+#ifndef mozHunspell_h__
+#define mozHunspell_h__
+
+#include "RLBoxHunspell.h"
+#include "mozISpellCheckingEngine.h"
+#include "mozIPersonalDictionary.h"
+#include "nsString.h"
+#include "nsCOMPtr.h"
+#include "nsCOMArray.h"
+#include "nsHashKeys.h"
+#include "nsIMemoryReporter.h"
+#include "nsIObserver.h"
+#include "nsIURI.h"
+#include "mozilla/Encoding.h"
+#include "mozilla/UniquePtr.h"
+#include "nsInterfaceHashtable.h"
+#include "nsWeakReference.h"
+#include "nsTHashMap.h"
+#include "nsCycleCollectionParticipant.h"
+#include "mozHunspellAllocator.h"
+
+#define MOZ_HUNSPELL_CONTRACTID "@mozilla.org/spellchecker/engine;1"
+#define MOZ_HUNSPELL_CID \
+ /* 56c778e4-1bee-45f3-a689-886692a97fe7 */ \
+ { \
+ 0x56c778e4, 0x1bee, 0x45f3, { \
+ 0xa6, 0x89, 0x88, 0x66, 0x92, 0xa9, 0x7f, 0xe7 \
+ } \
+ }
+
+class mozHunspell final : public mozISpellCheckingEngine,
+ public nsIObserver,
+ public nsSupportsWeakReference,
+ public nsIMemoryReporter {
+ public:
+ NS_DECL_CYCLE_COLLECTING_ISUPPORTS
+ NS_DECL_MOZISPELLCHECKINGENGINE
+ NS_DECL_NSIOBSERVER
+ NS_DECL_CYCLE_COLLECTION_CLASS_AMBIGUOUS(mozHunspell, mozISpellCheckingEngine)
+
+ mozHunspell();
+
+ nsresult Init();
+
+ void LoadDictionaryList(bool aNotifyChildProcesses);
+
+ NS_DECL_NSIMEMORYREPORTER
+
+ protected:
+ virtual ~mozHunspell();
+
+ void DictionariesChanged(bool aNotifyChildProcesses);
+
+ nsCOMPtr<mozIPersonalDictionary> mPersonalDictionary;
+
+ // Hashtable matches dictionary name to .aff file
+ nsInterfaceHashtable<nsStringHashKey, nsIURI> mDictionaries;
+
+ // dynamic dirs used to search for dictionaries
+ nsCOMArray<nsIFile> mDynamicDirectories;
+ nsInterfaceHashtable<nsStringHashKey, nsIURI> mDynamicDictionaries;
+
+ struct DictionaryData {
+ // keep track of whether the dictionary is currently in use or not
+ bool mEnabled = true;
+
+ // keep track of whether we've failed loading this dictionary before.
+ // if set, we don't try loading it again.
+ bool mLoadFailed = false;
+
+ mozilla::UniquePtr<mozilla::Encoder> mEncoder;
+ mozilla::UniquePtr<mozilla::Decoder> mDecoder;
+ mozilla::UniquePtr<RLBoxHunspell> mHunspell;
+ nsCString mAffixFileName;
+
+ // helper method for converting a word to the charset of the dictionary
+ nsresult ConvertCharset(const nsAString& aStr, std::string& aDst);
+
+ // helper method to the load the dictionary if it is not already loaded
+ nsresult LoadIfNecessary();
+ };
+
+ nsTHashMap<nsCStringHashKey, DictionaryData> mHunspells;
+};
+
+#endif
diff --git a/extensions/spellcheck/hunspell/glue/mozHunspellAllocator.h b/extensions/spellcheck/hunspell/glue/mozHunspellAllocator.h
new file mode 100644
index 0000000000..ddcec3e28c
--- /dev/null
+++ b/extensions/spellcheck/hunspell/glue/mozHunspellAllocator.h
@@ -0,0 +1,15 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef mozHunspellAllocator_h__
+#define mozHunspellAllocator_h__
+
+#include "mozilla/CountingAllocatorBase.h"
+
+class HunspellAllocator
+ : public mozilla::CountingAllocatorBase<HunspellAllocator> {};
+
+#endif
diff --git a/extensions/spellcheck/hunspell/glue/mozHunspellRLBoxGlue.h b/extensions/spellcheck/hunspell/glue/mozHunspellRLBoxGlue.h
new file mode 100644
index 0000000000..d84a5ba739
--- /dev/null
+++ b/extensions/spellcheck/hunspell/glue/mozHunspellRLBoxGlue.h
@@ -0,0 +1,45 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef mozHunspellRLBoxGlue_h
+#define mozHunspellRLBoxGlue_h
+
+#include <stdint.h>
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+typedef uint32_t(hunspell_create_filemgr_t)(const char* aFilename);
+typedef bool(hunspell_get_line_t)(uint32_t aFd, char** aLinePtr);
+typedef int(hunspell_get_line_num_t)(uint32_t aFd);
+typedef void(hunspell_destruct_filemgr_t)(uint32_t aFd);
+typedef uint32_t(hunspell_ToUpperCase_t)(uint32_t aChar);
+typedef uint32_t(hunspell_ToLowerCase_t)(uint32_t aChar);
+typedef struct cs_info*(hunspell_get_current_cs_t)(const char* es);
+
+void RegisterHunspellCallbacks(
+ hunspell_create_filemgr_t* aHunspellCreateFilemgr,
+ hunspell_get_line_t* aHunspellGetLine,
+ hunspell_get_line_num_t* aHunspellGetLine_num,
+ hunspell_destruct_filemgr_t* aHunspellDestructFilemgr,
+ hunspell_ToUpperCase_t* aHunspellToUpperCase,
+ hunspell_ToLowerCase_t* aHunspellToLowerCase,
+ hunspell_get_current_cs_t* aHunspellGetCurrentCS);
+
+extern hunspell_create_filemgr_t* moz_glue_hunspell_create_filemgr;
+extern hunspell_get_line_t* moz_glue_hunspell_get_line;
+extern hunspell_get_line_num_t* moz_glue_hunspell_get_line_num;
+extern hunspell_destruct_filemgr_t* moz_glue_hunspell_destruct_filemgr;
+extern hunspell_ToUpperCase_t* moz_hunspell_ToUpperCase;
+extern hunspell_ToLowerCase_t* moz_hunspell_ToLowerCase;
+extern hunspell_get_current_cs_t* moz_hunspell_GetCurrentCS;
+
+#if defined(__cplusplus)
+}
+#endif
+
+#endif
diff --git a/extensions/spellcheck/hunspell/glue/mozHunspellRLBoxHost.cpp b/extensions/spellcheck/hunspell/glue/mozHunspellRLBoxHost.cpp
new file mode 100644
index 0000000000..cd80fb989b
--- /dev/null
+++ b/extensions/spellcheck/hunspell/glue/mozHunspellRLBoxHost.cpp
@@ -0,0 +1,235 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include <limits>
+
+#include "mozHunspellRLBoxHost.h"
+#include "mozilla/DebugOnly.h"
+#include "nsContentUtils.h"
+#include "nsILoadInfo.h"
+#include "nsNetUtil.h"
+#include "nsUnicharUtils.h"
+
+#include "hunspell_csutil.hxx"
+
+using namespace mozilla;
+
+mozHunspellFileMgrHost::mozHunspellFileMgrHost(const nsCString& aFilename) {
+ nsCOMPtr<nsIChannel> channel;
+ DebugOnly<Result<Ok, nsresult>> result = Open(aFilename, channel, mStream);
+ NS_WARNING_ASSERTION(result.value.isOk(), "Failed to open Hunspell file");
+}
+
+/* static */
+Result<Ok, nsresult> mozHunspellFileMgrHost::Open(
+ const nsCString& aPath, nsCOMPtr<nsIChannel>& aChannel,
+ nsCOMPtr<nsIInputStream>& aStream) {
+ nsCOMPtr<nsIURI> uri;
+ MOZ_TRY(NS_NewURI(getter_AddRefs(uri), aPath));
+
+ MOZ_TRY(NS_NewChannel(
+ getter_AddRefs(aChannel), uri, nsContentUtils::GetSystemPrincipal(),
+ nsILoadInfo::SEC_REQUIRE_SAME_ORIGIN_INHERITS_SEC_CONTEXT,
+ nsIContentPolicy::TYPE_OTHER));
+
+ MOZ_TRY(aChannel->Open(getter_AddRefs(aStream)));
+ return Ok();
+}
+
+Result<Ok, nsresult> mozHunspellFileMgrHost::ReadLine(nsCString& aLine) {
+ if (!mStream) {
+ return Err(NS_ERROR_NOT_INITIALIZED);
+ }
+
+ bool ok;
+ MOZ_TRY(NS_ReadLine(mStream.get(), &mLineBuffer, aLine, &ok));
+ if (!ok) {
+ mStream = nullptr;
+ }
+
+ mLineNum++;
+ return Ok();
+}
+
+/* static */
+Result<int64_t, nsresult> mozHunspellFileMgrHost::GetSize(
+ const nsCString& aFilename) {
+ int64_t ret = -1;
+
+ nsCOMPtr<nsIChannel> channel;
+ nsCOMPtr<nsIInputStream> stream;
+ MOZ_TRY(Open(aFilename, channel, stream));
+
+ channel->GetContentLength(&ret);
+ return ret;
+}
+
+bool mozHunspellFileMgrHost::GetLine(std::string& aResult) {
+ nsAutoCString line;
+ auto res = ReadLine(line);
+ if (res.isErr()) {
+ return false;
+ }
+
+ aResult.assign(line.BeginReading(), line.Length());
+ return true;
+}
+
+/* static */
+uint32_t mozHunspellCallbacks::sCurrentFreshId = 0;
+/* static */
+mozilla::StaticRWLock mozHunspellCallbacks::sFileMgrMapLock;
+/* static */
+std::map<uint32_t, std::unique_ptr<mozHunspellFileMgrHost>>
+ mozHunspellCallbacks::sFileMgrMap;
+/* static */
+std::set<nsCString> mozHunspellCallbacks::sFileMgrAllowList;
+
+/* static */
+void mozHunspellCallbacks::AllowFile(const nsCString& aFilename) {
+ mozilla::StaticAutoWriteLock lock(sFileMgrMapLock);
+ sFileMgrAllowList.insert(aFilename);
+}
+
+/* static */
+void mozHunspellCallbacks::Clear() {
+ mozilla::StaticAutoWriteLock lock(sFileMgrMapLock);
+ sCurrentFreshId = 0;
+ sFileMgrMap.clear();
+ sFileMgrAllowList.clear();
+}
+
+/* static */
+tainted_hunspell<uint32_t> mozHunspellCallbacks::CreateFilemgr(
+ rlbox_sandbox_hunspell& aSandbox,
+ tainted_hunspell<const char*> t_aFilename) {
+ mozilla::StaticAutoWriteLock lock(sFileMgrMapLock);
+
+ return t_aFilename.copy_and_verify_string(
+ [&](std::unique_ptr<char[]> aFilename) {
+ nsCString cFilename = nsDependentCString(aFilename.get());
+
+ // Ensure that the filename is in the allowlist
+ auto it = sFileMgrAllowList.find(cFilename);
+ MOZ_RELEASE_ASSERT(it != sFileMgrAllowList.end());
+
+ // Get new id
+ uint32_t freshId = GetFreshId();
+ // Save mapping of id to file manager
+ sFileMgrMap[freshId] = std::unique_ptr<mozHunspellFileMgrHost>(
+ new mozHunspellFileMgrHost(cFilename));
+
+ return freshId;
+ });
+}
+
+/* static */
+uint32_t mozHunspellCallbacks::GetFreshId() {
+ // i is uint64_t to prevent overflow during loop increment which would cause
+ // an infinite loop
+ for (uint64_t i = sCurrentFreshId; i < std::numeric_limits<uint32_t>::max();
+ i++) {
+ auto it = sFileMgrMap.find(i);
+ if (it == sFileMgrMap.end()) {
+ // set sCurrentFreshId to the next (possibly) available id
+ sCurrentFreshId = i + 1;
+ return static_cast<uint32_t>(i);
+ }
+ }
+
+ MOZ_CRASH("Ran out of unique file ids for hunspell dictionaries");
+}
+
+/* static */
+mozHunspellFileMgrHost& mozHunspellCallbacks::GetMozHunspellFileMgrHost(
+ tainted_hunspell<uint32_t> t_aFd) {
+ mozilla::StaticAutoReadLock lock(sFileMgrMapLock);
+ uint32_t aFd = t_aFd.copy_and_verify([](uint32_t aFd) { return aFd; });
+ auto iter = sFileMgrMap.find(aFd);
+ MOZ_RELEASE_ASSERT(iter != sFileMgrMap.end());
+ return *(iter->second.get());
+}
+
+/* static */
+tainted_hunspell<bool> mozHunspellCallbacks::GetLine(
+ rlbox_sandbox_hunspell& aSandbox, tainted_hunspell<uint32_t> t_aFd,
+ tainted_hunspell<char**> t_aLinePtr) {
+ mozHunspellFileMgrHost& inst =
+ mozHunspellCallbacks::GetMozHunspellFileMgrHost(t_aFd);
+ std::string line;
+ bool ok = inst.GetLine(line);
+ // If the getline fails, return a null which is "graceful" failure
+ if (ok) {
+ // Copy the line into the sandbox. This memory is eventually freed by
+ // hunspell.
+ size_t size = line.size() + 1;
+ tainted_hunspell<char*> t_line = aSandbox.malloc_in_sandbox<char>(size);
+
+ if (t_line == nullptr) {
+ // If malloc fails, we should go to "graceful" failure path
+ ok = false;
+ } else {
+ rlbox::memcpy(aSandbox, t_line, line.c_str(), size);
+ }
+ *t_aLinePtr = t_line;
+ } else {
+ *t_aLinePtr = nullptr;
+ }
+ return ok;
+}
+
+/* static */
+tainted_hunspell<int> mozHunspellCallbacks::GetLineNum(
+ rlbox_sandbox_hunspell& aSandbox, tainted_hunspell<uint32_t> t_aFd) {
+ mozHunspellFileMgrHost& inst =
+ mozHunspellCallbacks::GetMozHunspellFileMgrHost(t_aFd);
+ int num = inst.GetLineNum();
+ return num;
+}
+
+/* static */
+void mozHunspellCallbacks::DestructFilemgr(rlbox_sandbox_hunspell& aSandbox,
+ tainted_hunspell<uint32_t> t_aFd) {
+ mozilla::StaticAutoWriteLock lock(sFileMgrMapLock);
+ uint32_t aFd = t_aFd.copy_and_verify([](uint32_t aFd) { return aFd; });
+
+ auto iter = sFileMgrMap.find(aFd);
+ if (iter != sFileMgrMap.end()) {
+ sFileMgrMap.erase(iter);
+ }
+}
+
+// Callbacks for using Firefox's encoding instead of hunspell's
+
+/* static */
+tainted_hunspell<uint32_t> mozHunspellCallbacks::ToUpperCase(
+ rlbox_sandbox_hunspell& aSandbox, tainted_hunspell<uint32_t> t_aChar) {
+ uint32_t aChar =
+ t_aChar.copy_and_verify([](uint32_t aChar) { return aChar; });
+ return ::ToUpperCase(aChar);
+}
+
+/* static */
+tainted_hunspell<uint32_t> mozHunspellCallbacks::ToLowerCase(
+ rlbox_sandbox_hunspell& aSandbox, tainted_hunspell<uint32_t> t_aChar) {
+ uint32_t aChar =
+ t_aChar.copy_and_verify([](uint32_t aChar) { return aChar; });
+ return ::ToLowerCase(aChar);
+}
+
+/* static */ tainted_hunspell<struct cs_info*>
+mozHunspellCallbacks::GetCurrentCS(rlbox_sandbox_hunspell& aSandbox,
+ tainted_hunspell<const char*> t_es) {
+ tainted_hunspell<struct cs_info*> t_ccs =
+ aSandbox.malloc_in_sandbox<struct cs_info>(256);
+ MOZ_RELEASE_ASSERT(t_ccs);
+ return t_es.copy_and_verify_string([&](std::unique_ptr<char[]> es) {
+ struct cs_info* ccs = hunspell_get_current_cs(es.get());
+ rlbox::memcpy(aSandbox, t_ccs, ccs, sizeof(struct cs_info) * 256);
+ delete[] ccs;
+ return t_ccs;
+ });
+}
diff --git a/extensions/spellcheck/hunspell/glue/mozHunspellRLBoxHost.h b/extensions/spellcheck/hunspell/glue/mozHunspellRLBoxHost.h
new file mode 100644
index 0000000000..f92070eabf
--- /dev/null
+++ b/extensions/spellcheck/hunspell/glue/mozHunspellRLBoxHost.h
@@ -0,0 +1,122 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef mozHunspellRLBoxHost_h
+#define mozHunspellRLBoxHost_h
+
+#include <map>
+#include <memory>
+#include <mutex>
+#include <set>
+#include <stdint.h>
+#include <string>
+
+#include "RLBoxHunspell.h"
+#include "mozilla/Result.h"
+#include "mozilla/ResultExtensions.h"
+#include "mozilla/RWLock.h"
+#include "nsIChannel.h"
+#include "nsIInputStream.h"
+#include "nsReadLine.h"
+
+namespace mozilla {
+
+class mozHunspellFileMgrHost final {
+ public:
+ /**
+ * aFilename must be a local file/jar URI for the file to load.
+ */
+ explicit mozHunspellFileMgrHost(const nsCString& aFilename);
+ ~mozHunspellFileMgrHost() = default;
+
+ bool GetLine(std::string& aResult);
+ int GetLineNum() const { return mLineNum; }
+
+ static Result<int64_t, nsresult> GetSize(const nsCString& aFilename);
+
+ private:
+ static mozilla::Result<mozilla::Ok, nsresult> Open(
+ const nsCString& aPath, nsCOMPtr<nsIChannel>& aChannel,
+ nsCOMPtr<nsIInputStream>& aStream);
+
+ mozilla::Result<mozilla::Ok, nsresult> ReadLine(nsCString& aLine);
+
+ int mLineNum = 0;
+ nsCOMPtr<nsIInputStream> mStream;
+ nsLineBuffer<char> mLineBuffer;
+};
+
+class mozHunspellCallbacks {
+ public:
+ // APIs invoked by the sandboxed hunspell file manager
+ static tainted_hunspell<uint32_t> CreateFilemgr(
+ rlbox_sandbox_hunspell& aSandbox,
+ tainted_hunspell<const char*> t_aFilename);
+ static tainted_hunspell<bool> GetLine(rlbox_sandbox_hunspell& aSandbox,
+ tainted_hunspell<uint32_t> t_aFd,
+ tainted_hunspell<char**> t_aLinePtr);
+ static tainted_hunspell<int> GetLineNum(rlbox_sandbox_hunspell& aSandbox,
+ tainted_hunspell<uint32_t> t_aFd);
+ static void DestructFilemgr(rlbox_sandbox_hunspell& aSandbox,
+ tainted_hunspell<uint32_t> t_aFd);
+
+ // APIs necessary for hunspell UTF encoding
+ static tainted_hunspell<uint32_t> ToUpperCase(
+ rlbox_sandbox_hunspell& aSandbox, tainted_hunspell<uint32_t> t_aChar);
+ static tainted_hunspell<uint32_t> ToLowerCase(
+ rlbox_sandbox_hunspell& aSandbox, tainted_hunspell<uint32_t> t_aChar);
+ static tainted_hunspell<struct cs_info*> GetCurrentCS(
+ rlbox_sandbox_hunspell& aSandbox, tainted_hunspell<const char*> t_es);
+
+ protected:
+ // API called by RLBox
+
+ /**
+ * Add filename to allow list.
+ */
+ static void AllowFile(const nsCString& aFilename);
+ friend RLBoxHunspell* RLBoxHunspell::Create(const nsCString& affpath,
+ const nsCString& dpath);
+ /**
+ * Clear allow list and map of hunspell file managers.
+ */
+ static void Clear();
+ friend RLBoxHunspell::~RLBoxHunspell();
+
+ private:
+ /**
+ * sFileMgrMap holds a map between unique uint32_t
+ * integers and mozHunspellFileMgrHost instances
+ */
+ static std::map<uint32_t, std::unique_ptr<mozHunspellFileMgrHost>>
+ sFileMgrMap;
+
+ /**
+ * sFileMgrAllowList contains the filenames of the dictionary files hunspell
+ * is allowed to open
+ */
+ static std::set<nsCString> sFileMgrAllowList;
+ /**
+ * Reader-writer lock for the sFileMgrMap
+ */
+ static mozilla::StaticRWLock sFileMgrMapLock;
+ /**
+ * Tracks the next possibly unused id for sFileMgrMap
+ */
+ static uint32_t sCurrentFreshId;
+ /**
+ * Returns an unused id for sFileMgrMap
+ */
+ static uint32_t GetFreshId();
+ /**
+ * Returns the mozHunspellFileMgrHost for the given uint32_t id
+ */
+ static mozHunspellFileMgrHost& GetMozHunspellFileMgrHost(
+ tainted_hunspell<uint32_t> t_aFd);
+};
+} // namespace mozilla
+
+#endif
diff --git a/extensions/spellcheck/hunspell/glue/mozHunspellRLBoxSandbox.cpp b/extensions/spellcheck/hunspell/glue/mozHunspellRLBoxSandbox.cpp
new file mode 100644
index 0000000000..f913b4bc83
--- /dev/null
+++ b/extensions/spellcheck/hunspell/glue/mozHunspellRLBoxSandbox.cpp
@@ -0,0 +1,54 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "mozHunspellRLBoxSandbox.h"
+#include "mozHunspellRLBoxGlue.h"
+
+FileMgr::FileMgr(const char* aFilename, const char* aKey) : mFd(0) {
+ // The key is not used in firefox
+ mFd = moz_glue_hunspell_create_filemgr(aFilename);
+}
+
+bool FileMgr::getline(std::string& aResult) {
+ char* line = nullptr;
+ bool ok = moz_glue_hunspell_get_line(mFd, &line);
+ if (ok && line) {
+ aResult = line;
+ free(line);
+ }
+ return ok;
+}
+
+int FileMgr::getlinenum() const { return moz_glue_hunspell_get_line_num(mFd); }
+
+FileMgr::~FileMgr() { moz_glue_hunspell_destruct_filemgr(mFd); }
+
+// Glue code to set global callbacks
+
+hunspell_create_filemgr_t* moz_glue_hunspell_create_filemgr = nullptr;
+hunspell_get_line_t* moz_glue_hunspell_get_line = nullptr;
+hunspell_get_line_num_t* moz_glue_hunspell_get_line_num = nullptr;
+hunspell_destruct_filemgr_t* moz_glue_hunspell_destruct_filemgr = nullptr;
+hunspell_ToUpperCase_t* moz_hunspell_ToUpperCase = nullptr;
+hunspell_ToLowerCase_t* moz_hunspell_ToLowerCase = nullptr;
+hunspell_get_current_cs_t* moz_hunspell_GetCurrentCS = nullptr;
+
+void RegisterHunspellCallbacks(
+ hunspell_create_filemgr_t* aHunspellCreateFilemgr,
+ hunspell_get_line_t* aHunspellGetLine,
+ hunspell_get_line_num_t* aHunspellGetLine_num,
+ hunspell_destruct_filemgr_t* aHunspellDestructFilemgr,
+ hunspell_ToUpperCase_t* aHunspellToUpperCase,
+ hunspell_ToLowerCase_t* aHunspellToLowerCase,
+ hunspell_get_current_cs_t* aHunspellGetCurrentCS) {
+ moz_glue_hunspell_create_filemgr = aHunspellCreateFilemgr;
+ moz_glue_hunspell_get_line = aHunspellGetLine;
+ moz_glue_hunspell_get_line_num = aHunspellGetLine_num;
+ moz_glue_hunspell_destruct_filemgr = aHunspellDestructFilemgr;
+ moz_hunspell_ToUpperCase = aHunspellToUpperCase;
+ moz_hunspell_ToLowerCase = aHunspellToLowerCase;
+ moz_hunspell_GetCurrentCS = aHunspellGetCurrentCS;
+}
diff --git a/extensions/spellcheck/hunspell/glue/mozHunspellRLBoxSandbox.h b/extensions/spellcheck/hunspell/glue/mozHunspellRLBoxSandbox.h
new file mode 100644
index 0000000000..9850408807
--- /dev/null
+++ b/extensions/spellcheck/hunspell/glue/mozHunspellRLBoxSandbox.h
@@ -0,0 +1,36 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef mozHunspellRLBoxSandbox_h
+#define mozHunspellRLBoxSandbox_h
+
+#include <string>
+#include <stdint.h>
+
+// Note: This class name and lack of namespacing terrible, but are necessary
+// for Hunspell compatibility.
+class FileMgr final {
+ public:
+ /**
+ * aFilename must be a local file/jar URI for the file to load.
+ *
+ * aKey is the decription key for encrypted Hunzip files, and is
+ * unsupported. The argument is there solely for compatibility.
+ */
+ explicit FileMgr(const char* aFilename, const char* aKey = nullptr);
+ ~FileMgr();
+
+ // Note: The nonstandard naming conventions of these methods are necessary for
+ // Hunspell compatibility.
+ bool getline(std::string& aLine);
+ int getlinenum() const;
+
+ private:
+ // opaque file descriptor got from the host application
+ uint32_t mFd;
+};
+
+#endif // mozHunspellRLBoxSandbox_h
diff --git a/extensions/spellcheck/hunspell/moz.build b/extensions/spellcheck/hunspell/moz.build
new file mode 100644
index 0000000000..1c31aea6ff
--- /dev/null
+++ b/extensions/spellcheck/hunspell/moz.build
@@ -0,0 +1,10 @@
+# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
+# vim: set filetype=python:
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+DIRS += ["glue", "src"]
+
+if CONFIG["ENABLE_TESTS"]:
+ XPCSHELL_TESTS_MANIFESTS += ["tests/unit/xpcshell.ini"]
diff --git a/extensions/spellcheck/hunspell/patches/bug1410214.patch b/extensions/spellcheck/hunspell/patches/bug1410214.patch
new file mode 100644
index 0000000000..4db781b5e7
--- /dev/null
+++ b/extensions/spellcheck/hunspell/patches/bug1410214.patch
@@ -0,0 +1,37 @@
+diff --git a/extensions/spellcheck/hunspell/src/filemgr.hxx b/extensions/spellcheck/hunspell/src/filemgr.hxx
+--- a/extensions/spellcheck/hunspell/src/filemgr.hxx
++++ b/extensions/spellcheck/hunspell/src/filemgr.hxx
+@@ -67,32 +67,11 @@
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+ /* file manager class - read lines of files [filename] OR [filename.hz] */
+ #ifndef FILEMGR_HXX_
+ #define FILEMGR_HXX_
+
+-#include "hunzip.hxx"
+-#include <stdio.h>
+-#include <string>
+-#include <fstream>
+-
+-class FileMgr {
+- private:
+- FileMgr(const FileMgr&);
+- FileMgr& operator=(const FileMgr&);
++#include "mozHunspellRLBoxSandbox.h"
+
+- protected:
+- std::ifstream fin;
+- Hunzip* hin;
+- char in[BUFSIZE + 50]; // input buffer
+- int fail(const char* err, const char* par);
+- int linenum;
+-
+- public:
+- FileMgr(const char* filename, const char* key = NULL);
+- ~FileMgr();
+- bool getline(std::string&);
+- int getlinenum();
+-};
+ #endif
diff --git a/extensions/spellcheck/hunspell/patches/bug1653659.patch b/extensions/spellcheck/hunspell/patches/bug1653659.patch
new file mode 100644
index 0000000000..ab3e752015
--- /dev/null
+++ b/extensions/spellcheck/hunspell/patches/bug1653659.patch
@@ -0,0 +1,190 @@
+diff --git a/extensions/spellcheck/hunspell/src/csutil.cxx b/extensions/spellcheck/hunspell/src/csutil.cxx
+--- a/extensions/spellcheck/hunspell/src/csutil.cxx
++++ b/extensions/spellcheck/hunspell/src/csutil.cxx
+@@ -90,21 +90,17 @@
+ #else
+ #ifndef MOZILLA_CLIENT
+ #include "utf_info.hxx"
+ #define UTF_LST_LEN (sizeof(utf_lst) / (sizeof(unicode_info)))
+ #endif
+ #endif
+
+ #ifdef MOZILLA_CLIENT
+-#include "nsCOMPtr.h"
+-#include "nsUnicharUtils.h"
+-#include "mozilla/Encoding.h"
+-
+-using namespace mozilla;
++#include "mozHunspellRLBoxGlue.h"
+ #endif
+
+ struct unicode_info2 {
+ char cletter;
+ unsigned short cupper;
+ unsigned short clower;
+ };
+
+@@ -2277,101 +2273,18 @@ struct cs_info* get_current_cs(const std
+ "error: unknown encoding %s: using %s as fallback\n", es.c_str(),
+ encds[0].enc_name);
+ ccs = encds[0].cs_table;
+ }
+
+ return ccs;
+ }
+ #else
+-// XXX This function was rewritten for mozilla. Instead of storing the
+-// conversion tables static in this file, create them when needed
+-// with help the mozilla backend.
+ struct cs_info* get_current_cs(const std::string& es) {
+- struct cs_info* ccs = new cs_info[256];
+- // Initialze the array with dummy data so that we wouldn't need
+- // to return null in case of failures.
+- for (int i = 0; i <= 0xff; ++i) {
+- ccs[i].ccase = false;
+- ccs[i].clower = i;
+- ccs[i].cupper = i;
+- }
+-
+- auto encoding = Encoding::ForLabelNoReplacement(es);
+- if (!encoding) {
+- return ccs;
+- }
+- auto encoder = encoding->NewEncoder();
+- auto decoder = encoding->NewDecoderWithoutBOMHandling();
+-
+- for (unsigned int i = 0; i <= 0xff; ++i) {
+- bool success = false;
+- // We want to find the upper/lowercase equivalents of each byte
+- // in this 1-byte character encoding. Call our encoding/decoding
+- // APIs separately for each byte since they may reject some of the
+- // bytes, and we want to handle errors separately for each byte.
+- uint8_t lower, upper;
+- do {
+- if (i == 0)
+- break;
+- uint8_t source = uint8_t(i);
+- char16_t uni[2];
+- char16_t uniCased;
+- uint8_t destination[4];
+- auto src1 = MakeSpan(&source, 1);
+- auto dst1 = MakeSpan(uni);
+- auto src2 = MakeSpan(&uniCased, 1);
+- auto dst2 = MakeSpan(destination);
+-
+- uint32_t result;
+- size_t read;
+- size_t written;
+- Tie(result, read, written) =
+- decoder->DecodeToUTF16WithoutReplacement(src1, dst1, true);
+- if (result != kInputEmpty || read != 1 || written != 1) {
+- break;
+- }
+-
+- uniCased = ToLowerCase(uni[0]);
+- Tie(result, read, written) =
+- encoder->EncodeFromUTF16WithoutReplacement(src2, dst2, true);
+- if (result != kInputEmpty || read != 1 || written != 1) {
+- break;
+- }
+- lower = destination[0];
+-
+- uniCased = ToUpperCase(uni[0]);
+- Tie(result, read, written) =
+- encoder->EncodeFromUTF16WithoutReplacement(src2, dst2, true);
+- if (result != kInputEmpty || read != 1 || written != 1) {
+- break;
+- }
+- upper = destination[0];
+-
+- success = true;
+- } while (0);
+-
+- encoding->NewEncoderInto(*encoder);
+- encoding->NewDecoderWithoutBOMHandlingInto(*decoder);
+-
+- if (success) {
+- ccs[i].cupper = upper;
+- ccs[i].clower = lower;
+- } else {
+- ccs[i].cupper = i;
+- ccs[i].clower = i;
+- }
+-
+- if (ccs[i].clower != (unsigned char)i)
+- ccs[i].ccase = true;
+- else
+- ccs[i].ccase = false;
+- }
+-
+- return ccs;
++ return moz_hunspell_GetCurrentCS(es.c_str());
+ }
+ #endif
+
+ // primitive isalpha() replacement for tokenization
+ std::string get_casechars(const char* enc) {
+ struct cs_info* csconv = get_current_cs(enc);
+ std::string expw;
+ for (int i = 0; i <= 255; ++i) {
+@@ -2455,34 +2368,34 @@ unsigned short unicodetoupper(unsigned s
+ // There are a dotless lower case i pair of upper `I',
+ // and an upper I with dot pair of lower `i'.
+ if (c == 0x0069 && ((langnum == LANG_az) || (langnum == LANG_tr) || (langnum == LANG_crh)))
+ return 0x0130;
+ #ifdef OPENOFFICEORG
+ return static_cast<unsigned short>(u_toupper(c));
+ #else
+ #ifdef MOZILLA_CLIENT
+- return ToUpperCase((char16_t)c);
++ return moz_hunspell_ToUpperCase((char16_t)c);
+ #else
+ return (utf_tbl) ? utf_tbl[c].cupper : c;
+ #endif
+ #endif
+ }
+
+ unsigned short unicodetolower(unsigned short c, int langnum) {
+ // In Azeri and Turkish, I and i dictinct letters:
+ // There are a dotless lower case i pair of upper `I',
+ // and an upper I with dot pair of lower `i'.
+ if (c == 0x0049 && ((langnum == LANG_az) || (langnum == LANG_tr) || (langnum == LANG_crh)))
+ return 0x0131;
+ #ifdef OPENOFFICEORG
+ return static_cast<unsigned short>(u_tolower(c));
+ #else
+ #ifdef MOZILLA_CLIENT
+- return ToLowerCase((char16_t)c);
++ return moz_hunspell_ToLowerCase((char16_t)c);
+ #else
+ return (utf_tbl) ? utf_tbl[c].clower : c;
+ #endif
+ #endif
+ }
+
+ int unicodeisalpha(unsigned short c) {
+ #ifdef OPENOFFICEORG
+diff --git a/extensions/spellcheck/hunspell/src/csutil.hxx b/extensions/spellcheck/hunspell/src/csutil.hxx
+--- a/extensions/spellcheck/hunspell/src/csutil.hxx
++++ b/extensions/spellcheck/hunspell/src/csutil.hxx
+@@ -77,20 +77,16 @@
+
+ #include <fstream>
+ #include <string>
+ #include <vector>
+ #include <string.h>
+ #include "w_char.hxx"
+ #include "htypes.hxx"
+
+-#ifdef MOZILLA_CLIENT
+-#include "nscore.h" // for mozalloc headers
+-#endif
+-
+ // casing
+ #define NOCAP 0
+ #define INITCAP 1
+ #define ALLCAP 2
+ #define HUHCAP 3
+ #define HUHINITCAP 4
+
+ // default encoding and keystring
diff --git a/extensions/spellcheck/hunspell/patches/bug1739761.patch b/extensions/spellcheck/hunspell/patches/bug1739761.patch
new file mode 100644
index 0000000000..66ffefadb5
--- /dev/null
+++ b/extensions/spellcheck/hunspell/patches/bug1739761.patch
@@ -0,0 +1,615 @@
+diff --git a/extensions/spellcheck/hunspell/src/hashmgr.cxx b/extensions/spellcheck/hunspell/src/hashmgr.cxx
+--- a/extensions/spellcheck/hunspell/src/hashmgr.cxx
++++ b/extensions/spellcheck/hunspell/src/hashmgr.cxx
+@@ -63,16 +63,17 @@
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
++#include <assert.h>
+ #include <stdlib.h>
+ #include <string.h>
+ #include <stdio.h>
+ #include <ctype.h>
+ #include <limits>
+ #include <sstream>
+
+ #include "hashmgr.hxx"
+@@ -118,52 +119,54 @@ HashMgr::~HashMgr() {
+ // go through column by column of the table
+ for (int i = 0; i < tablesize; i++) {
+ struct hentry* pt = tableptr[i];
+ struct hentry* nt = NULL;
+ while (pt) {
+ nt = pt->next;
+ if (pt->astr &&
+ (!aliasf || TESTAFF(pt->astr, ONLYUPCASEFLAG, pt->alen)))
+- free(pt->astr);
+- free(pt);
++ arena_free(pt->astr);
++ arena_free(pt);
+ pt = nt;
+ }
+ }
+ free(tableptr);
+ }
+ tablesize = 0;
+
+ if (aliasf) {
+ for (int j = 0; j < (numaliasf); j++)
+- free(aliasf[j]);
+- free(aliasf);
++ arena_free(aliasf[j]);
++ arena_free(aliasf);
+ aliasf = NULL;
+ if (aliasflen) {
+- free(aliasflen);
++ arena_free(aliasflen);
+ aliasflen = NULL;
+ }
+ }
+ if (aliasm) {
+ for (int j = 0; j < (numaliasm); j++)
+- free(aliasm[j]);
+- free(aliasm);
++ arena_free(aliasm[j]);
++ arena_free(aliasm);
+ aliasm = NULL;
+ }
+
+ #ifndef OPENOFFICEORG
+ #ifndef MOZILLA_CLIENT
+ if (utf8)
+ free_utf_tbl();
+ #endif
+ #endif
+
+ #ifdef MOZILLA_CLIENT
+ delete[] csconv;
+ #endif
++
++ assert(outstanding_arena_allocations == 0);
+ }
+
+ // lookup a root word in the hashtable
+
+ struct hentry* HashMgr::lookup(const char* word) const {
+ struct hentry* dp;
+ if (tableptr) {
+ dp = tableptr[hash(word)];
+@@ -222,17 +225,17 @@ int HashMgr::add_word(const std::string&
+
+ word = word_copy;
+ }
+
+ bool upcasehomonym = false;
+ int descl = desc ? (aliasm ? sizeof(char*) : desc->size() + 1) : 0;
+ // variable-length hash record with word and optional fields
+ struct hentry* hp =
+- (struct hentry*)malloc(sizeof(struct hentry) + word->size() + descl);
++ (struct hentry*)arena_alloc(sizeof(struct hentry) + word->size() + descl);
+ if (!hp) {
+ delete desc_copy;
+ delete word_copy;
+ return 1;
+ }
+
+ char* hpw = hp->word;
+ strcpy(hpw, word->c_str());
+@@ -366,57 +369,57 @@ int HashMgr::add_word(const std::string&
+ delete word_copy;
+ return 0;
+ }
+ while (dp->next != NULL) {
+ if ((!dp->next_homonym) && (strcmp(hp->word, dp->word) == 0)) {
+ // remove hidden onlyupcase homonym
+ if (!onlyupcase) {
+ if ((dp->astr) && TESTAFF(dp->astr, ONLYUPCASEFLAG, dp->alen)) {
+- free(dp->astr);
++ arena_free(dp->astr);
+ dp->astr = hp->astr;
+ dp->alen = hp->alen;
+- free(hp);
++ arena_free(hp);
+ delete desc_copy;
+ delete word_copy;
+ return 0;
+ } else {
+ dp->next_homonym = hp;
+ }
+ } else {
+ upcasehomonym = true;
+ }
+ }
+ dp = dp->next;
+ }
+ if (strcmp(hp->word, dp->word) == 0) {
+ // remove hidden onlyupcase homonym
+ if (!onlyupcase) {
+ if ((dp->astr) && TESTAFF(dp->astr, ONLYUPCASEFLAG, dp->alen)) {
+- free(dp->astr);
++ arena_free(dp->astr);
+ dp->astr = hp->astr;
+ dp->alen = hp->alen;
+- free(hp);
++ arena_free(hp);
+ delete desc_copy;
+ delete word_copy;
+ return 0;
+ } else {
+ dp->next_homonym = hp;
+ }
+ } else {
+ upcasehomonym = true;
+ }
+ }
+ if (!upcasehomonym) {
+ dp->next = hp;
+ } else {
+ // remove hidden onlyupcase homonym
+ if (hp->astr)
+- free(hp->astr);
+- free(hp);
++ arena_free(hp->astr);
++ arena_free(hp);
+ }
+
+ delete desc_copy;
+ delete word_copy;
+ return 0;
+ }
+
+ int HashMgr::add_hidden_capitalized_word(const std::string& word,
+@@ -430,17 +433,17 @@ int HashMgr::add_hidden_capitalized_word
+
+ // add inner capitalized forms to handle the following allcap forms:
+ // Mixed caps: OpenOffice.org -> OPENOFFICE.ORG
+ // Allcaps with suffixes: CIA's -> CIA'S
+ if (((captype == HUHCAP) || (captype == HUHINITCAP) ||
+ ((captype == ALLCAP) && (flagslen != 0))) &&
+ !((flagslen != 0) && TESTAFF(flags, forbiddenword, flagslen))) {
+ unsigned short* flags2 =
+- (unsigned short*)malloc(sizeof(unsigned short) * (flagslen + 1));
++ (unsigned short*)arena_alloc(sizeof(unsigned short) * (flagslen + 1));
+ if (!flags2)
+ return 1;
+ if (flagslen)
+ memcpy(flags2, flags, flagslen * sizeof(unsigned short));
+ flags2[flagslen] = ONLYUPCASEFLAG;
+ if (utf8) {
+ std::string st;
+ std::vector<w_char> w;
+@@ -479,23 +482,23 @@ int HashMgr::get_clen_and_captype(const
+ }
+
+ // remove word (personal dictionary function for standalone applications)
+ int HashMgr::remove(const std::string& word) {
+ struct hentry* dp = lookup(word.c_str());
+ while (dp) {
+ if (dp->alen == 0 || !TESTAFF(dp->astr, forbiddenword, dp->alen)) {
+ unsigned short* flags =
+- (unsigned short*)malloc(sizeof(unsigned short) * (dp->alen + 1));
++ (unsigned short*)arena_alloc(sizeof(unsigned short) * (dp->alen + 1));
+ if (!flags)
+ return 1;
+ for (int i = 0; i < dp->alen; i++)
+ flags[i] = dp->astr[i];
+ flags[dp->alen] = forbiddenword;
+- free(dp->astr);
++ arena_free(dp->astr);
+ dp->astr = flags;
+ dp->alen++;
+ std::sort(flags, flags + dp->alen);
+ }
+ dp = dp->next_homonym;
+ }
+ return 0;
+ }
+@@ -533,17 +536,17 @@ int HashMgr::add_with_affix(const std::s
+ remove_forbidden_flag(word);
+ if (dp && dp->astr) {
+ int captype;
+ int wcl = get_clen_and_captype(word, &captype);
+ if (aliasf) {
+ add_word(word, wcl, dp->astr, dp->alen, NULL, false, captype);
+ } else {
+ unsigned short* flags =
+- (unsigned short*)malloc(dp->alen * sizeof(unsigned short));
++ (unsigned short*) arena_alloc(dp->alen * sizeof(unsigned short));
+ if (flags) {
+ memcpy((void*)flags, (void*)dp->astr,
+ dp->alen * sizeof(unsigned short));
+ add_word(word, wcl, flags, dp->alen, NULL, false, captype);
+ } else
+ return 1;
+ }
+ return add_hidden_capitalized_word(word, wcl, dp->astr,
+@@ -668,17 +671,17 @@ int HashMgr::load_tables(const char* tpa
+ if (aliasf) {
+ int index = atoi(ap.c_str());
+ al = get_aliasf(index, &flags, dict);
+ if (!al) {
+ HUNSPELL_WARNING(stderr, "error: line %d: bad flag vector alias\n",
+ dict->getlinenum());
+ }
+ } else {
+- al = decode_flags(&flags, ap.c_str(), dict);
++ al = decode_flags(&flags, ap.c_str(), dict, /* arena = */ true);
+ if (al == -1) {
+ HUNSPELL_WARNING(stderr, "Can't allocate memory.\n");
+ delete dict;
+ return 6;
+ }
+ std::sort(flags, flags + al);
+ }
+ } else {
+@@ -709,47 +712,48 @@ int HashMgr::hash(const char* word) cons
+ hv = (hv << 8) | (*word++);
+ while (*word != 0) {
+ ROTATE(hv, ROTATE_LEN);
+ hv ^= (*word++);
+ }
+ return (unsigned long)hv % tablesize;
+ }
+
+-int HashMgr::decode_flags(unsigned short** result, const std::string& flags, FileMgr* af) const {
++int HashMgr::decode_flags(unsigned short** result, const std::string& flags, FileMgr* af, bool arena) const {
++ auto alloc = [arena, this](int n) { return arena ? this->arena_alloc(n) : malloc(n); };
+ int len;
+ if (flags.empty()) {
+ *result = NULL;
+ return 0;
+ }
+ switch (flag_mode) {
+ case FLAG_LONG: { // two-character flags (1x2yZz -> 1x 2y Zz)
+ len = flags.size();
+ if (len % 2 == 1)
+ HUNSPELL_WARNING(stderr, "error: line %d: bad flagvector\n",
+ af->getlinenum());
+ len /= 2;
+- *result = (unsigned short*)malloc(len * sizeof(unsigned short));
++ *result = (unsigned short*)alloc(len * sizeof(unsigned short));
+ if (!*result)
+ return -1;
+ for (int i = 0; i < len; i++) {
+ (*result)[i] = ((unsigned short)((unsigned char)flags[i * 2]) << 8) +
+ (unsigned char)flags[i * 2 + 1];
+ }
+ break;
+ }
+ case FLAG_NUM: { // decimal numbers separated by comma (4521,23,233 -> 4521
+ // 23 233)
+ len = 1;
+ unsigned short* dest;
+ for (size_t i = 0; i < flags.size(); ++i) {
+ if (flags[i] == ',')
+ len++;
+ }
+- *result = (unsigned short*)malloc(len * sizeof(unsigned short));
++ *result = (unsigned short*)alloc(len * sizeof(unsigned short));
+ if (!*result)
+ return -1;
+ dest = *result;
+ const char* src = flags.c_str();
+ for (const char* p = src; *p; p++) {
+ if (*p == ',') {
+ int i = atoi(src);
+ if (i >= DEFAULTFLAGS)
+@@ -774,26 +778,26 @@ int HashMgr::decode_flags(unsigned short
+ HUNSPELL_WARNING(stderr, "error: line %d: 0 is wrong flag id\n",
+ af->getlinenum());
+ break;
+ }
+ case FLAG_UNI: { // UTF-8 characters
+ std::vector<w_char> w;
+ u8_u16(w, flags);
+ len = w.size();
+- *result = (unsigned short*)malloc(len * sizeof(unsigned short));
++ *result = (unsigned short*)alloc(len * sizeof(unsigned short));
+ if (!*result)
+ return -1;
+ memcpy(*result, w.data(), len * sizeof(short));
+ break;
+ }
+ default: { // Ispell's one-character flags (erfg -> e r f g)
+ unsigned short* dest;
+ len = flags.size();
+- *result = (unsigned short*)malloc(len * sizeof(unsigned short));
++ *result = (unsigned short*)alloc(len * sizeof(unsigned short));
+ if (!*result)
+ return -1;
+ dest = *result;
+ for (size_t i = 0; i < flags.size(); ++i) {
+ *dest = (unsigned char)flags[i];
+ dest++;
+ }
+ }
+@@ -890,16 +894,18 @@ unsigned short HashMgr::decode_flag(cons
+ default:
+ s = *(unsigned char*)f;
+ }
+ if (s == 0)
+ HUNSPELL_WARNING(stderr, "error: 0 is wrong flag id\n");
+ return s;
+ }
+
++// This function is only called by external consumers, and so using the default
++// allocator with mystrdup is correct.
+ char* HashMgr::encode_flag(unsigned short f) const {
+ if (f == 0)
+ return mystrdup("(NULL)");
+ std::string ch;
+ if (flag_mode == FLAG_LONG) {
+ ch.push_back((unsigned char)(f >> 8));
+ ch.push_back((unsigned char)(f - ((f >> 8) << 8)));
+ } else if (flag_mode == FLAG_NUM) {
+@@ -1070,42 +1076,42 @@ bool HashMgr::parse_aliasf(const std::st
+ numaliasf = 0;
+ aliasf = NULL;
+ aliasflen = NULL;
+ HUNSPELL_WARNING(stderr, "error: line %d: bad entry number\n",
+ af->getlinenum());
+ return false;
+ }
+ aliasf =
+- (unsigned short**)malloc(numaliasf * sizeof(unsigned short*));
++ (unsigned short**)arena_alloc(numaliasf * sizeof(unsigned short*));
+ aliasflen =
+- (unsigned short*)malloc(numaliasf * sizeof(unsigned short));
++ (unsigned short*)arena_alloc(numaliasf * sizeof(unsigned short));
+ if (!aliasf || !aliasflen) {
+ numaliasf = 0;
+ if (aliasf)
+- free(aliasf);
++ arena_free(aliasf);
+ if (aliasflen)
+- free(aliasflen);
++ arena_free(aliasflen);
+ aliasf = NULL;
+ aliasflen = NULL;
+ return false;
+ }
+ np++;
+ break;
+ }
+ default:
+ break;
+ }
+ ++i;
+ start_piece = mystrsep(line, iter);
+ }
+ if (np != 2) {
+ numaliasf = 0;
+- free(aliasf);
+- free(aliasflen);
++ arena_free(aliasf);
++ arena_free(aliasflen);
+ aliasf = NULL;
+ aliasflen = NULL;
+ HUNSPELL_WARNING(stderr, "error: line %d: missing data\n",
+ af->getlinenum());
+ return false;
+ }
+
+ /* now parse the numaliasf lines to read in the remainder of the table */
+@@ -1126,33 +1132,33 @@ bool HashMgr::parse_aliasf(const std::st
+ errored = true;
+ break;
+ }
+ break;
+ }
+ case 1: {
+ std::string piece(start_piece, iter);
+ aliasflen[j] =
+- (unsigned short)decode_flags(&(aliasf[j]), piece, af);
++ (unsigned short)decode_flags(&(aliasf[j]), piece, af, /* arena = */ true);
+ std::sort(aliasf[j], aliasf[j] + aliasflen[j]);
+ break;
+ }
+ default:
+ break;
+ }
+ ++i;
+ start_piece = mystrsep(nl, iter);
+ }
+ }
+ if (!aliasf[j]) {
+ for (int k = 0; k < j; ++k) {
+- free(aliasf[k]);
++ arena_free(aliasf[k]);
+ }
+- free(aliasf);
+- free(aliasflen);
++ arena_free(aliasf);
++ arena_free(aliasflen);
+ aliasf = NULL;
+ aliasflen = NULL;
+ numaliasf = 0;
+ HUNSPELL_WARNING(stderr, "error: line %d: table is corrupt\n",
+ af->getlinenum());
+ return false;
+ }
+ }
+@@ -1193,33 +1199,33 @@ bool HashMgr::parse_aliasm(const std::st
+ }
+ case 1: {
+ numaliasm = atoi(std::string(start_piece, iter).c_str());
+ if (numaliasm < 1) {
+ HUNSPELL_WARNING(stderr, "error: line %d: bad entry number\n",
+ af->getlinenum());
+ return false;
+ }
+- aliasm = (char**)malloc(numaliasm * sizeof(char*));
++ aliasm = (char**)arena_alloc(numaliasm * sizeof(char*));
+ if (!aliasm) {
+ numaliasm = 0;
+ return false;
+ }
+ np++;
+ break;
+ }
+ default:
+ break;
+ }
+ ++i;
+ start_piece = mystrsep(line, iter);
+ }
+ if (np != 2) {
+ numaliasm = 0;
+- free(aliasm);
++ arena_free(aliasm);
+ aliasm = NULL;
+ HUNSPELL_WARNING(stderr, "error: line %d: missing data\n",
+ af->getlinenum());
+ return false;
+ }
+
+ /* now parse the numaliasm lines to read in the remainder of the table */
+ for (int j = 0; j < numaliasm; j++) {
+@@ -1245,32 +1251,36 @@ bool HashMgr::parse_aliasm(const std::st
+ std::string::const_iterator end = nl.end();
+ std::string chunk(start_piece, end);
+ if (complexprefixes) {
+ if (utf8)
+ reverseword_utf(chunk);
+ else
+ reverseword(chunk);
+ }
+- aliasm[j] = mystrdup(chunk.c_str());
++ size_t sl = chunk.length() + 1;
++ aliasm[j] = (char*)arena_alloc(sl);
++ if (aliasm[j]) {
++ memcpy(aliasm[j], chunk.c_str(), sl);
++ }
+ break;
+ }
+ default:
+ break;
+ }
+ ++i;
+ start_piece = mystrsep(nl, iter);
+ }
+ }
+ if (!aliasm[j]) {
+ numaliasm = 0;
+ for (int k = 0; k < j; ++k) {
+- free(aliasm[k]);
++ arena_free(aliasm[k]);
+ }
+- free(aliasm);
++ arena_free(aliasm);
+ aliasm = NULL;
+ HUNSPELL_WARNING(stderr, "error: line %d: table is corrupt\n",
+ af->getlinenum());
+ return false;
+ }
+ }
+ return true;
+ }
+@@ -1379,8 +1389,27 @@ bool HashMgr::parse_reptable(const std::
+ }
+ return true;
+ }
+
+ // return replacing table
+ const std::vector<replentry>& HashMgr::get_reptable() const {
+ return reptable;
+ }
++
++void* HashMgr::arena_alloc(int num_bytes) {
++ static const int MIN_CHUNK_SIZE = 4096;
++ if (arena.empty() || (current_chunk_size - current_chunk_offset < num_bytes)) {
++ current_chunk_size = std::max(MIN_CHUNK_SIZE, num_bytes);
++ arena.push_back(std::make_unique<uint8_t[]>(current_chunk_size));
++ current_chunk_offset = 0;
++ }
++
++ uint8_t* ptr = &arena.back()[current_chunk_offset];
++ current_chunk_offset += num_bytes;
++ outstanding_arena_allocations++;
++ return ptr;
++}
++
++void HashMgr::arena_free(void* ptr) {
++ --outstanding_arena_allocations;
++ assert(outstanding_arena_allocations >= 0);
++}
+diff --git a/extensions/spellcheck/hunspell/src/hashmgr.hxx b/extensions/spellcheck/hunspell/src/hashmgr.hxx
+--- a/extensions/spellcheck/hunspell/src/hashmgr.hxx
++++ b/extensions/spellcheck/hunspell/src/hashmgr.hxx
+@@ -67,16 +67,18 @@
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+ #ifndef HASHMGR_HXX_
+ #define HASHMGR_HXX_
+
+ #include <stdio.h>
++#include <stdint.h>
++#include <memory>
+ #include <string>
+ #include <vector>
+
+ #include "htypes.hxx"
+ #include "filemgr.hxx"
+ #include "w_char.hxx"
+
+ enum flag { FLAG_CHAR, FLAG_LONG, FLAG_NUM, FLAG_UNI };
+@@ -116,17 +118,23 @@ class HashMgr {
+
+ struct hentry* lookup(const char*) const;
+ int hash(const char*) const;
+ struct hentry* walk_hashtable(int& col, struct hentry* hp) const;
+
+ int add(const std::string& word);
+ int add_with_affix(const std::string& word, const std::string& pattern);
+ int remove(const std::string& word);
+- int decode_flags(unsigned short** result, const std::string& flags, FileMgr* af) const;
++private:
++ // Only internal consumers are allowed to arena-allocate.
++ int decode_flags(unsigned short** result, const std::string& flags, FileMgr* af, bool arena) const;
++public:
++ int decode_flags(unsigned short** result, const std::string& flags, FileMgr* af) const {
++ return decode_flags(result, flags, af, /* arena = */ false);
++ }
+ bool decode_flags(std::vector<unsigned short>& result, const std::string& flags, FileMgr* af) const;
+ unsigned short decode_flag(const char* flag) const;
+ char* encode_flag(unsigned short flag) const;
+ int is_aliasf() const;
+ int get_aliasf(int index, unsigned short** fvec, FileMgr* af) const;
+ int is_aliasm() const;
+ char* get_aliasm(int index) const;
+ const std::vector<replentry>& get_reptable() const;
+@@ -148,11 +156,27 @@ class HashMgr {
+ int wcl,
+ unsigned short* flags,
+ int al,
+ const std::string* dp,
+ int captype);
+ bool parse_aliasm(const std::string& line, FileMgr* af);
+ bool parse_reptable(const std::string& line, FileMgr* af);
+ int remove_forbidden_flag(const std::string& word);
++
++ // Our Mozilla fork uses a simple arena allocator for certain strings which
++ // persist for the lifetime of the HashMgr in order to avoid heap fragmentation.
++ // It's a simple bump-allocator, so we can't actually free() memory midway
++ // through the lifecycle, but we have a dummy free() implementation to ensure
++ // that our calls to arena_alloc() and arena_free() are balanced.
++ void* arena_alloc(int num_bytes);
++ void* arena_alloc(int num_bytes) const {
++ return const_cast<HashMgr*>(this)->arena_alloc(num_bytes);
++ }
++ void arena_free(void* ptr);
++
++ std::vector<std::unique_ptr<uint8_t[]>> arena;
++ int current_chunk_size = 0;
++ int current_chunk_offset = 0;
++ int outstanding_arena_allocations = 0;
+ };
+
+ #endif
diff --git a/extensions/spellcheck/hunspell/patches/bug1838113.patch b/extensions/spellcheck/hunspell/patches/bug1838113.patch
new file mode 100644
index 0000000000..61ec2af701
--- /dev/null
+++ b/extensions/spellcheck/hunspell/patches/bug1838113.patch
@@ -0,0 +1,20 @@
+diff --git a/extensions/spellcheck/hunspell/src/csutil.cxx b/extensions/spellcheck/hunspell/src/csutil.cxx
+index 48e58ff4b2677..39a54d38023c8 100644
+--- a/extensions/spellcheck/hunspell/src/csutil.cxx
++++ b/extensions/spellcheck/hunspell/src/csutil.cxx
+@@ -108,6 +108,7 @@ static struct unicode_info2* utf_tbl = NULL;
+ static int utf_tbl_count =
+ 0; // utf_tbl can be used by multiple Hunspell instances
+
++#ifndef MOZILLA_CLIENT
+ void myopen(std::ifstream& stream, const char* path, std::ios_base::openmode mode)
+ {
+ #if defined(_WIN32) && defined(_MSC_VER)
+@@ -127,6 +128,7 @@ void myopen(std::ifstream& stream, const char* path, std::ios_base::openmode mod
+ #endif
+ stream.open(path, mode);
+ }
++#endif
+
+ std::string& u16_u8(std::string& dest, const std::vector<w_char>& src) {
+ dest.clear();
diff --git a/extensions/spellcheck/hunspell/src/COPYING.MPL b/extensions/spellcheck/hunspell/src/COPYING.MPL
new file mode 100644
index 0000000000..7714141d15
--- /dev/null
+++ b/extensions/spellcheck/hunspell/src/COPYING.MPL
@@ -0,0 +1,470 @@
+ MOZILLA PUBLIC LICENSE
+ Version 1.1
+
+ ---------------
+
+1. Definitions.
+
+ 1.0.1. "Commercial Use" means distribution or otherwise making the
+ Covered Code available to a third party.
+
+ 1.1. "Contributor" means each entity that creates or contributes to
+ the creation of Modifications.
+
+ 1.2. "Contributor Version" means the combination of the Original
+ Code, prior Modifications used by a Contributor, and the Modifications
+ made by that particular Contributor.
+
+ 1.3. "Covered Code" means the Original Code or Modifications or the
+ combination of the Original Code and Modifications, in each case
+ including portions thereof.
+
+ 1.4. "Electronic Distribution Mechanism" means a mechanism generally
+ accepted in the software development community for the electronic
+ transfer of data.
+
+ 1.5. "Executable" means Covered Code in any form other than Source
+ Code.
+
+ 1.6. "Initial Developer" means the individual or entity identified
+ as the Initial Developer in the Source Code notice required by Exhibit
+ A.
+
+ 1.7. "Larger Work" means a work which combines Covered Code or
+ portions thereof with code not governed by the terms of this License.
+
+ 1.8. "License" means this document.
+
+ 1.8.1. "Licensable" means having the right to grant, to the maximum
+ extent possible, whether at the time of the initial grant or
+ subsequently acquired, any and all of the rights conveyed herein.
+
+ 1.9. "Modifications" means any addition to or deletion from the
+ substance or structure of either the Original Code or any previous
+ Modifications. When Covered Code is released as a series of files, a
+ Modification is:
+ A. Any addition to or deletion from the contents of a file
+ containing Original Code or previous Modifications.
+
+ B. Any new file that contains any part of the Original Code or
+ previous Modifications.
+
+ 1.10. "Original Code" means Source Code of computer software code
+ which is described in the Source Code notice required by Exhibit A as
+ Original Code, and which, at the time of its release under this
+ License is not already Covered Code governed by this License.
+
+ 1.10.1. "Patent Claims" means any patent claim(s), now owned or
+ hereafter acquired, including without limitation, method, process,
+ and apparatus claims, in any patent Licensable by grantor.
+
+ 1.11. "Source Code" means the preferred form of the Covered Code for
+ making modifications to it, including all modules it contains, plus
+ any associated interface definition files, scripts used to control
+ compilation and installation of an Executable, or source code
+ differential comparisons against either the Original Code or another
+ well known, available Covered Code of the Contributor's choice. The
+ Source Code can be in a compressed or archival form, provided the
+ appropriate decompression or de-archiving software is widely available
+ for no charge.
+
+ 1.12. "You" (or "Your") means an individual or a legal entity
+ exercising rights under, and complying with all of the terms of, this
+ License or a future version of this License issued under Section 6.1.
+ For legal entities, "You" includes any entity which controls, is
+ controlled by, or is under common control with You. For purposes of
+ this definition, "control" means (a) the power, direct or indirect,
+ to cause the direction or management of such entity, whether by
+ contract or otherwise, or (b) ownership of more than fifty percent
+ (50%) of the outstanding shares or beneficial ownership of such
+ entity.
+
+2. Source Code License.
+
+ 2.1. The Initial Developer Grant.
+ The Initial Developer hereby grants You a world-wide, royalty-free,
+ non-exclusive license, subject to third party intellectual property
+ claims:
+ (a) under intellectual property rights (other than patent or
+ trademark) Licensable by Initial Developer to use, reproduce,
+ modify, display, perform, sublicense and distribute the Original
+ Code (or portions thereof) with or without Modifications, and/or
+ as part of a Larger Work; and
+
+ (b) under Patents Claims infringed by the making, using or
+ selling of Original Code, to make, have made, use, practice,
+ sell, and offer for sale, and/or otherwise dispose of the
+ Original Code (or portions thereof).
+
+ (c) the licenses granted in this Section 2.1(a) and (b) are
+ effective on the date Initial Developer first distributes
+ Original Code under the terms of this License.
+
+ (d) Notwithstanding Section 2.1(b) above, no patent license is
+ granted: 1) for code that You delete from the Original Code; 2)
+ separate from the Original Code; or 3) for infringements caused
+ by: i) the modification of the Original Code or ii) the
+ combination of the Original Code with other software or devices.
+
+ 2.2. Contributor Grant.
+ Subject to third party intellectual property claims, each Contributor
+ hereby grants You a world-wide, royalty-free, non-exclusive license
+
+ (a) under intellectual property rights (other than patent or
+ trademark) Licensable by Contributor, to use, reproduce, modify,
+ display, perform, sublicense and distribute the Modifications
+ created by such Contributor (or portions thereof) either on an
+ unmodified basis, with other Modifications, as Covered Code
+ and/or as part of a Larger Work; and
+
+ (b) under Patent Claims infringed by the making, using, or
+ selling of Modifications made by that Contributor either alone
+ and/or in combination with its Contributor Version (or portions
+ of such combination), to make, use, sell, offer for sale, have
+ made, and/or otherwise dispose of: 1) Modifications made by that
+ Contributor (or portions thereof); and 2) the combination of
+ Modifications made by that Contributor with its Contributor
+ Version (or portions of such combination).
+
+ (c) the licenses granted in Sections 2.2(a) and 2.2(b) are
+ effective on the date Contributor first makes Commercial Use of
+ the Covered Code.
+
+ (d) Notwithstanding Section 2.2(b) above, no patent license is
+ granted: 1) for any code that Contributor has deleted from the
+ Contributor Version; 2) separate from the Contributor Version;
+ 3) for infringements caused by: i) third party modifications of
+ Contributor Version or ii) the combination of Modifications made
+ by that Contributor with other software (except as part of the
+ Contributor Version) or other devices; or 4) under Patent Claims
+ infringed by Covered Code in the absence of Modifications made by
+ that Contributor.
+
+3. Distribution Obligations.
+
+ 3.1. Application of License.
+ The Modifications which You create or to which You contribute are
+ governed by the terms of this License, including without limitation
+ Section 2.2. The Source Code version of Covered Code may be
+ distributed only under the terms of this License or a future version
+ of this License released under Section 6.1, and You must include a
+ copy of this License with every copy of the Source Code You
+ distribute. You may not offer or impose any terms on any Source Code
+ version that alters or restricts the applicable version of this
+ License or the recipients' rights hereunder. However, You may include
+ an additional document offering the additional rights described in
+ Section 3.5.
+
+ 3.2. Availability of Source Code.
+ Any Modification which You create or to which You contribute must be
+ made available in Source Code form under the terms of this License
+ either on the same media as an Executable version or via an accepted
+ Electronic Distribution Mechanism to anyone to whom you made an
+ Executable version available; and if made available via Electronic
+ Distribution Mechanism, must remain available for at least twelve (12)
+ months after the date it initially became available, or at least six
+ (6) months after a subsequent version of that particular Modification
+ has been made available to such recipients. You are responsible for
+ ensuring that the Source Code version remains available even if the
+ Electronic Distribution Mechanism is maintained by a third party.
+
+ 3.3. Description of Modifications.
+ You must cause all Covered Code to which You contribute to contain a
+ file documenting the changes You made to create that Covered Code and
+ the date of any change. You must include a prominent statement that
+ the Modification is derived, directly or indirectly, from Original
+ Code provided by the Initial Developer and including the name of the
+ Initial Developer in (a) the Source Code, and (b) in any notice in an
+ Executable version or related documentation in which You describe the
+ origin or ownership of the Covered Code.
+
+ 3.4. Intellectual Property Matters
+ (a) Third Party Claims.
+ If Contributor has knowledge that a license under a third party's
+ intellectual property rights is required to exercise the rights
+ granted by such Contributor under Sections 2.1 or 2.2,
+ Contributor must include a text file with the Source Code
+ distribution titled "LEGAL" which describes the claim and the
+ party making the claim in sufficient detail that a recipient will
+ know whom to contact. If Contributor obtains such knowledge after
+ the Modification is made available as described in Section 3.2,
+ Contributor shall promptly modify the LEGAL file in all copies
+ Contributor makes available thereafter and shall take other steps
+ (such as notifying appropriate mailing lists or newsgroups)
+ reasonably calculated to inform those who received the Covered
+ Code that new knowledge has been obtained.
+
+ (b) Contributor APIs.
+ If Contributor's Modifications include an application programming
+ interface and Contributor has knowledge of patent licenses which
+ are reasonably necessary to implement that API, Contributor must
+ also include this information in the LEGAL file.
+
+ (c) Representations.
+ Contributor represents that, except as disclosed pursuant to
+ Section 3.4(a) above, Contributor believes that Contributor's
+ Modifications are Contributor's original creation(s) and/or
+ Contributor has sufficient rights to grant the rights conveyed by
+ this License.
+
+ 3.5. Required Notices.
+ You must duplicate the notice in Exhibit A in each file of the Source
+ Code. If it is not possible to put such notice in a particular Source
+ Code file due to its structure, then You must include such notice in a
+ location (such as a relevant directory) where a user would be likely
+ to look for such a notice. If You created one or more Modification(s)
+ You may add your name as a Contributor to the notice described in
+ Exhibit A. You must also duplicate this License in any documentation
+ for the Source Code where You describe recipients' rights or ownership
+ rights relating to Covered Code. You may choose to offer, and to
+ charge a fee for, warranty, support, indemnity or liability
+ obligations to one or more recipients of Covered Code. However, You
+ may do so only on Your own behalf, and not on behalf of the Initial
+ Developer or any Contributor. You must make it absolutely clear than
+ any such warranty, support, indemnity or liability obligation is
+ offered by You alone, and You hereby agree to indemnify the Initial
+ Developer and every Contributor for any liability incurred by the
+ Initial Developer or such Contributor as a result of warranty,
+ support, indemnity or liability terms You offer.
+
+ 3.6. Distribution of Executable Versions.
+ You may distribute Covered Code in Executable form only if the
+ requirements of Section 3.1-3.5 have been met for that Covered Code,
+ and if You include a notice stating that the Source Code version of
+ the Covered Code is available under the terms of this License,
+ including a description of how and where You have fulfilled the
+ obligations of Section 3.2. The notice must be conspicuously included
+ in any notice in an Executable version, related documentation or
+ collateral in which You describe recipients' rights relating to the
+ Covered Code. You may distribute the Executable version of Covered
+ Code or ownership rights under a license of Your choice, which may
+ contain terms different from this License, provided that You are in
+ compliance with the terms of this License and that the license for the
+ Executable version does not attempt to limit or alter the recipient's
+ rights in the Source Code version from the rights set forth in this
+ License. If You distribute the Executable version under a different
+ license You must make it absolutely clear that any terms which differ
+ from this License are offered by You alone, not by the Initial
+ Developer or any Contributor. You hereby agree to indemnify the
+ Initial Developer and every Contributor for any liability incurred by
+ the Initial Developer or such Contributor as a result of any such
+ terms You offer.
+
+ 3.7. Larger Works.
+ You may create a Larger Work by combining Covered Code with other code
+ not governed by the terms of this License and distribute the Larger
+ Work as a single product. In such a case, You must make sure the
+ requirements of this License are fulfilled for the Covered Code.
+
+4. Inability to Comply Due to Statute or Regulation.
+
+ If it is impossible for You to comply with any of the terms of this
+ License with respect to some or all of the Covered Code due to
+ statute, judicial order, or regulation then You must: (a) comply with
+ the terms of this License to the maximum extent possible; and (b)
+ describe the limitations and the code they affect. Such description
+ must be included in the LEGAL file described in Section 3.4 and must
+ be included with all distributions of the Source Code. Except to the
+ extent prohibited by statute or regulation, such description must be
+ sufficiently detailed for a recipient of ordinary skill to be able to
+ understand it.
+
+5. Application of this License.
+
+ This License applies to code to which the Initial Developer has
+ attached the notice in Exhibit A and to related Covered Code.
+
+6. Versions of the License.
+
+ 6.1. New Versions.
+ Netscape Communications Corporation ("Netscape") may publish revised
+ and/or new versions of the License from time to time. Each version
+ will be given a distinguishing version number.
+
+ 6.2. Effect of New Versions.
+ Once Covered Code has been published under a particular version of the
+ License, You may always continue to use it under the terms of that
+ version. You may also choose to use such Covered Code under the terms
+ of any subsequent version of the License published by Netscape. No one
+ other than Netscape has the right to modify the terms applicable to
+ Covered Code created under this License.
+
+ 6.3. Derivative Works.
+ If You create or use a modified version of this License (which you may
+ only do in order to apply it to code which is not already Covered Code
+ governed by this License), You must (a) rename Your license so that
+ the phrases "Mozilla", "MOZILLAPL", "MOZPL", "Netscape",
+ "MPL", "NPL" or any confusingly similar phrase do not appear in your
+ license (except to note that your license differs from this License)
+ and (b) otherwise make it clear that Your version of the license
+ contains terms which differ from the Mozilla Public License and
+ Netscape Public License. (Filling in the name of the Initial
+ Developer, Original Code or Contributor in the notice described in
+ Exhibit A shall not of themselves be deemed to be modifications of
+ this License.)
+
+7. DISCLAIMER OF WARRANTY.
+
+ COVERED CODE IS PROVIDED UNDER THIS LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ WITHOUT LIMITATION, WARRANTIES THAT THE COVERED CODE IS FREE OF
+ DEFECTS, MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE OR NON-INFRINGING.
+ THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE COVERED CODE
+ IS WITH YOU. SHOULD ANY COVERED CODE PROVE DEFECTIVE IN ANY RESPECT,
+ YOU (NOT THE INITIAL DEVELOPER OR ANY OTHER CONTRIBUTOR) ASSUME THE
+ COST OF ANY NECESSARY SERVICING, REPAIR OR CORRECTION. THIS DISCLAIMER
+ OF WARRANTY CONSTITUTES AN ESSENTIAL PART OF THIS LICENSE. NO USE OF
+ ANY COVERED CODE IS AUTHORIZED HEREUNDER EXCEPT UNDER THIS DISCLAIMER.
+
+8. TERMINATION.
+
+ 8.1. This License and the rights granted hereunder will terminate
+ automatically if You fail to comply with terms herein and fail to cure
+ such breach within 30 days of becoming aware of the breach. All
+ sublicenses to the Covered Code which are properly granted shall
+ survive any termination of this License. Provisions which, by their
+ nature, must remain in effect beyond the termination of this License
+ shall survive.
+
+ 8.2. If You initiate litigation by asserting a patent infringement
+ claim (excluding declatory judgment actions) against Initial Developer
+ or a Contributor (the Initial Developer or Contributor against whom
+ You file such action is referred to as "Participant") alleging that:
+
+ (a) such Participant's Contributor Version directly or indirectly
+ infringes any patent, then any and all rights granted by such
+ Participant to You under Sections 2.1 and/or 2.2 of this License
+ shall, upon 60 days notice from Participant terminate prospectively,
+ unless if within 60 days after receipt of notice You either: (i)
+ agree in writing to pay Participant a mutually agreeable reasonable
+ royalty for Your past and future use of Modifications made by such
+ Participant, or (ii) withdraw Your litigation claim with respect to
+ the Contributor Version against such Participant. If within 60 days
+ of notice, a reasonable royalty and payment arrangement are not
+ mutually agreed upon in writing by the parties or the litigation claim
+ is not withdrawn, the rights granted by Participant to You under
+ Sections 2.1 and/or 2.2 automatically terminate at the expiration of
+ the 60 day notice period specified above.
+
+ (b) any software, hardware, or device, other than such Participant's
+ Contributor Version, directly or indirectly infringes any patent, then
+ any rights granted to You by such Participant under Sections 2.1(b)
+ and 2.2(b) are revoked effective as of the date You first made, used,
+ sold, distributed, or had made, Modifications made by that
+ Participant.
+
+ 8.3. If You assert a patent infringement claim against Participant
+ alleging that such Participant's Contributor Version directly or
+ indirectly infringes any patent where such claim is resolved (such as
+ by license or settlement) prior to the initiation of patent
+ infringement litigation, then the reasonable value of the licenses
+ granted by such Participant under Sections 2.1 or 2.2 shall be taken
+ into account in determining the amount or value of any payment or
+ license.
+
+ 8.4. In the event of termination under Sections 8.1 or 8.2 above,
+ all end user license agreements (excluding distributors and resellers)
+ which have been validly granted by You or any distributor hereunder
+ prior to termination shall survive termination.
+
+9. LIMITATION OF LIABILITY.
+
+ UNDER NO CIRCUMSTANCES AND UNDER NO LEGAL THEORY, WHETHER TORT
+ (INCLUDING NEGLIGENCE), CONTRACT, OR OTHERWISE, SHALL YOU, THE INITIAL
+ DEVELOPER, ANY OTHER CONTRIBUTOR, OR ANY DISTRIBUTOR OF COVERED CODE,
+ OR ANY SUPPLIER OF ANY OF SUCH PARTIES, BE LIABLE TO ANY PERSON FOR
+ ANY INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES OF ANY
+ CHARACTER INCLUDING, WITHOUT LIMITATION, DAMAGES FOR LOSS OF GOODWILL,
+ WORK STOPPAGE, COMPUTER FAILURE OR MALFUNCTION, OR ANY AND ALL OTHER
+ COMMERCIAL DAMAGES OR LOSSES, EVEN IF SUCH PARTY SHALL HAVE BEEN
+ INFORMED OF THE POSSIBILITY OF SUCH DAMAGES. THIS LIMITATION OF
+ LIABILITY SHALL NOT APPLY TO LIABILITY FOR DEATH OR PERSONAL INJURY
+ RESULTING FROM SUCH PARTY'S NEGLIGENCE TO THE EXTENT APPLICABLE LAW
+ PROHIBITS SUCH LIMITATION. SOME JURISDICTIONS DO NOT ALLOW THE
+ EXCLUSION OR LIMITATION OF INCIDENTAL OR CONSEQUENTIAL DAMAGES, SO
+ THIS EXCLUSION AND LIMITATION MAY NOT APPLY TO YOU.
+
+10. U.S. GOVERNMENT END USERS.
+
+ The Covered Code is a "commercial item," as that term is defined in
+ 48 C.F.R. 2.101 (Oct. 1995), consisting of "commercial computer
+ software" and "commercial computer software documentation," as such
+ terms are used in 48 C.F.R. 12.212 (Sept. 1995). Consistent with 48
+ C.F.R. 12.212 and 48 C.F.R. 227.7202-1 through 227.7202-4 (June 1995),
+ all U.S. Government End Users acquire Covered Code with only those
+ rights set forth herein.
+
+11. MISCELLANEOUS.
+
+ This License represents the complete agreement concerning subject
+ matter hereof. If any provision of this License is held to be
+ unenforceable, such provision shall be reformed only to the extent
+ necessary to make it enforceable. This License shall be governed by
+ California law provisions (except to the extent applicable law, if
+ any, provides otherwise), excluding its conflict-of-law provisions.
+ With respect to disputes in which at least one party is a citizen of,
+ or an entity chartered or registered to do business in the United
+ States of America, any litigation relating to this License shall be
+ subject to the jurisdiction of the Federal Courts of the Northern
+ District of California, with venue lying in Santa Clara County,
+ California, with the losing party responsible for costs, including
+ without limitation, court costs and reasonable attorneys' fees and
+ expenses. The application of the United Nations Convention on
+ Contracts for the International Sale of Goods is expressly excluded.
+ Any law or regulation which provides that the language of a contract
+ shall be construed against the drafter shall not apply to this
+ License.
+
+12. RESPONSIBILITY FOR CLAIMS.
+
+ As between Initial Developer and the Contributors, each party is
+ responsible for claims and damages arising, directly or indirectly,
+ out of its utilization of rights under this License and You agree to
+ work with Initial Developer and Contributors to distribute such
+ responsibility on an equitable basis. Nothing herein is intended or
+ shall be deemed to constitute any admission of liability.
+
+13. MULTIPLE-LICENSED CODE.
+
+ Initial Developer may designate portions of the Covered Code as
+ "Multiple-Licensed". "Multiple-Licensed" means that the Initial
+ Developer permits you to utilize portions of the Covered Code under
+ Your choice of the NPL or the alternative licenses, if any, specified
+ by the Initial Developer in the file described in Exhibit A.
+
+EXHIBIT A -Mozilla Public License.
+
+ ``The contents of this file are subject to the Mozilla Public License
+ Version 1.1 (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.mozilla.org/MPL/
+
+ Software distributed under the License is distributed on an "AS IS"
+ basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
+ License for the specific language governing rights and limitations
+ under the License.
+
+ The Original Code is ______________________________________.
+
+ The Initial Developer of the Original Code is ________________________.
+ Portions created by ______________________ are Copyright (C) ______
+ _______________________. All Rights Reserved.
+
+ Contributor(s): ______________________________________.
+
+ Alternatively, the contents of this file may be used under the terms
+ of the _____ license (the "[___] License"), in which case the
+ provisions of [______] License are applicable instead of those
+ above. If you wish to allow use of your version of this file only
+ under the terms of the [____] License and not to allow others to use
+ your version of this file under the MPL, indicate your decision by
+ deleting the provisions above and replace them with the notice and
+ other provisions required by the [___] License. If you do not delete
+ the provisions above, a recipient may use your version of this file
+ under either the MPL or the [___] License."
+
+ [NOTE: The text of this Exhibit A may differ slightly from the text of
+ the notices in the Source Code files of the Original Code. You should
+ use the text of this Exhibit A rather than the text found in the
+ Original Code Source Code for Your Modifications.]
+
diff --git a/extensions/spellcheck/hunspell/src/README.md b/extensions/spellcheck/hunspell/src/README.md
new file mode 100644
index 0000000000..90ef880e86
--- /dev/null
+++ b/extensions/spellcheck/hunspell/src/README.md
@@ -0,0 +1,325 @@
+# About Hunspell
+
+Hunspell is a free spell checker and morphological analyzer library
+and command-line tool, licensed under LGPL/GPL/MPL tri-license.
+
+Hunspell is used by LibreOffice office suite, free browsers, like
+Mozilla Firefox and Google Chrome, and other tools and OSes, like
+Linux distributions and macOS. It is also a command-line tool for
+Linux, Unix-like and other OSes.
+
+It is designed for quick and high quality spell checking and
+correcting for languages with word-level writing system,
+including languages with rich morphology, complex word compounding
+and character encoding.
+
+Hunspell interfaces: Ispell-like terminal interface using Curses
+library, Ispell pipe interface, C++/C APIs and shared library, also
+with existing language bindings for other programming languages.
+
+Hunspell's code base comes from OpenOffice.org's MySpell library,
+developed by Kevin Hendricks (originally a C++ reimplementation of
+spell checking and affixation of Geoff Kuenning's International
+Ispell from scratch, later extended with eg. n-gram suggestions),
+see http://lingucomponent.openoffice.org/MySpell-3.zip, and
+its README, CONTRIBUTORS and license.readme (here: license.myspell) files.
+
+Main features of Hunspell library, developed by L叩szl坦 N辿meth:
+
+ - Unicode support
+ - Highly customizable suggestions: word-part replacement tables and
+ stem-level phonetic and other alternative transcriptions to recognize
+ and fix all typical misspellings, don't suggest offensive words etc.
+ - Complex morphology: dictionary and affix homonyms; twofold affix
+ stripping to handle inflectional and derivational morpheme groups for
+ agglutinative languages, like Azeri, Basque, Estonian, Finnish, Hungarian,
+ Turkish; 64 thousand affix classes with arbitrary number of affixes;
+ conditional affixes, circumfixes, fogemorphemes, zero morphemes,
+ virtual dictionary stems, forbidden words to avoid overgeneration etc.
+ - Handling complex compounds (for example, for Finno-Ugric, German and
+ Indo-Aryan languages): recognizing compounds made of arbitrary
+ number of words, handle affixation within compounds etc.
+ - Custom dictionaries with affixation
+ - Stemming
+ - Morphological analysis (in custom item and arrangement style)
+ - Morphological generation
+ - SPELLML XML API over plain spell() API function for easier integration
+ of stemming, morpological generation and custom dictionaries with affixation
+ - Language specific algorithms, like special casing of Azeri or Turkish
+ dotted i and German sharp s, and special compound rules of Hungarian.
+
+Main features of Hunspell command line tool, developed by L叩szl坦 N辿meth:
+
+ - Reimplementation of quick interactive interface of Geoff Kuenning's Ispell
+ - Parsing formats: text, OpenDocument, TeX/LaTeX, HTML/SGML/XML, nroff/troff
+ - Custom dictionaries with optional affixation, specified by a model word
+ - Multiple dictionary usage (for example hunspell -d en_US,de_DE,de_medical)
+ - Various filtering options (bad or good words/lines)
+ - Morphological analysis (option -m)
+ - Stemming (option -s)
+
+See man hunspell, man 3 hunspell, man 5 hunspell for complete manual.
+
+Translations: Hunspell has been translated into several languages already. If your language is missing or incomplete, please use [Weblate](https://hosted.weblate.org/engage/hunspell/) to help translate Hunspell.
+
+<a href="https://hosted.weblate.org/engage/hunspell/">
+<img src="https://hosted.weblate.org/widgets/hunspell/-/translations/horizontal-auto.svg" alt="Stanje prijevoda" />
+</a>
+
+# Dependencies
+
+Build only dependencies:
+
+ g++ make autoconf automake autopoint libtool
+
+Runtime dependencies:
+
+| | Mandatory | Optional |
+|---------------|------------------|------------------|
+|libhunspell | | |
+|hunspell tool | libiconv gettext | ncurses readline |
+
+# Compiling on GNU/Linux and Unixes
+
+We first need to download the dependencies. On Linux, `gettext` and
+`libiconv` are part of the standard library. On other Unixes we
+need to manually install them.
+
+For Ubuntu:
+
+ sudo apt install autoconf automake autopoint libtool
+
+Then run the following commands:
+
+ autoreconf -vfi
+ ./configure
+ make
+ sudo make install
+ sudo ldconfig
+
+For dictionary development, use the `--with-warnings` option of
+configure.
+
+For interactive user interface of Hunspell executable, use the
+`--with-ui` option.
+
+Optional developer packages:
+
+ - ncurses (need for --with-ui), eg. libncursesw5 for UTF-8
+ - readline (for fancy input line editing, configure parameter:
+ --with-readline)
+
+In Ubuntu, the packages are:
+
+ libncurses5-dev libreadline-dev
+
+# Compiling on OSX and macOS
+
+On macOS for compiler always use `clang` and not `g++` because Homebrew
+dependencies are build with that.
+
+ brew install autoconf automake libtool gettext
+ brew link gettext --force
+
+Then run:
+
+ autoreconf -vfi
+ ./configure
+ make
+
+# Compiling on Windows
+
+## Compiling with Mingw64 and MSYS2
+
+Download Msys2, update everything and install the following
+ packages:
+
+ pacman -S base-devel mingw-w64-x86_64-toolchain mingw-w64-x86_64-libtool
+
+Open Mingw-w64 Win64 prompt and compile the same way as on Linux, see
+above.
+
+## Compiling in Cygwin environment
+
+Download and install Cygwin environment for Windows with the following
+extra packages:
+
+ - make
+ - automake
+ - autoconf
+ - libtool
+ - gcc-g++ development package
+ - ncurses, readline (for user interface)
+ - iconv (character conversion)
+
+Then compile the same way as on Linux. Cygwin builds depend on
+Cygwin1.dll.
+
+# Debugging
+
+It is recommended to install a debug build of the standard library:
+
+ libstdc++6-6-dbg
+
+For debugging we need to create a debug build and then we need to start
+`gdb`.
+
+ ./configure CXXFLAGS='-g -O0 -Wall -Wextra'
+ make
+ ./libtool --mode=execute gdb src/tools/hunspell
+
+You can also pass the `CXXFLAGS` directly to `make` without calling
+`./configure`, but we don't recommend this way during long development
+sessions.
+
+If you like to develop and debug with an IDE, see documentation at
+https://github.com/hunspell/hunspell/wiki/IDE-Setup
+
+# Testing
+
+Testing Hunspell (see tests in tests/ subdirectory):
+
+ make check
+
+or with Valgrind debugger:
+
+ make check
+ VALGRIND=[Valgrind_tool] make check
+
+For example:
+
+ make check
+ VALGRIND=memcheck make check
+
+# Documentation
+
+features and dictionary format:
+
+ man 5 hunspell
+ man hunspell
+ hunspell -h
+
+http://hunspell.github.io/
+
+# Usage
+
+After compiling and installing (see INSTALL) you can run the Hunspell
+spell checker (compiled with user interface) with a Hunspell or Myspell
+dictionary:
+
+ hunspell -d en_US text.txt
+
+or without interface:
+
+ hunspell
+ hunspell -d en_GB -l <text.txt
+
+Dictionaries consist of an affix (.aff) and dictionary (.dic) file, for
+example, download American English dictionary files of LibreOffice
+(older version, but with stemming and morphological generation) with
+
+ wget -O en_US.aff https://cgit.freedesktop.org/libreoffice/dictionaries/plain/en/en_US.aff?id=a4473e06b56bfe35187e302754f6baaa8d75e54f
+ wget -O en_US.dic https://cgit.freedesktop.org/libreoffice/dictionaries/plain/en/en_US.dic?id=a4473e06b56bfe35187e302754f6baaa8d75e54f
+
+and with command line input and output, it's possible to check its work quickly,
+for example with the input words "example", "examples", "teached" and
+"verybaaaaaaaaaaaaaaaaaaaaaad":
+
+ $ hunspell -d en_US
+ Hunspell 1.7.0
+ example
+ *
+
+ examples
+ + example
+
+ teached
+ & teached 9 0: taught, teased, reached, teaches, teacher, leached, beached
+
+ verybaaaaaaaaaaaaaaaaaaaaaad
+ # verybaaaaaaaaaaaaaaaaaaaaaad 0
+
+Where in the output, `*` and `+` mean correct (accepted) words (`*` = dictionary stem,
+`+` = affixed forms of the following dictionary stem), and
+`&` and `#` mean bad (rejected) words (`&` = with suggestions, `#` = without suggestions)
+(see man hunspell).
+
+Example for stemming:
+
+ $ hunspell -d en_US -s
+ mice
+ mice mouse
+
+Example for morphological analysis (very limited with this English dictionary):
+
+ $ hunspell -d en_US -m
+ mice
+ mice st:mouse ts:Ns
+
+ cats
+ cats st:cat ts:0 is:Ns
+ cats st:cat ts:0 is:Vs
+
+# Other executables
+
+The src/tools directory contains the following executables after compiling.
+
+ - The main executable:
+ - hunspell: main program for spell checking and others (see
+ manual)
+ - Example tools:
+ - analyze: example of spell checking, stemming and morphological
+ analysis
+ - chmorph: example of automatic morphological generation and
+ conversion
+ - example: example of spell checking and suggestion
+ - Tools for dictionary development:
+ - affixcompress: dictionary generation from large (millions of
+ words) vocabularies
+ - makealias: alias compression (Hunspell only, not back compatible
+ with MySpell)
+ - wordforms: word generation (Hunspell version of unmunch)
+ - hunzip: decompressor of hzip format
+ - hzip: compressor of hzip format
+ - munch (DEPRECATED, use affixcompress): dictionary generation
+ from vocabularies (it needs an affix file, too).
+ - unmunch (DEPRECATED, use wordforms): list all recognized words
+ of a MySpell dictionary
+
+Example for morphological generation:
+
+ $ ~/hunspell/src/tools/analyze en_US.aff en_US.dic /dev/stdin
+ cat mice
+ generate(cat, mice) = cats
+ mouse cats
+ generate(mouse, cats) = mice
+ generate(mouse, cats) = mouses
+
+# Using Hunspell library with GCC
+
+Including in your program:
+
+ #include <hunspell.hxx>
+
+Linking with Hunspell static library:
+
+ g++ -lhunspell-1.7 example.cxx
+ # or better, use pkg-config
+ g++ $(pkg-config --cflags --libs hunspell) example.cxx
+
+## Dictionaries
+
+Hunspell (MySpell) dictionaries:
+
+ - https://wiki.documentfoundation.org/Language_support_of_LibreOffice
+ - http://cgit.freedesktop.org/libreoffice/dictionaries
+ - http://extensions.libreoffice.org
+ - https://extensions.openoffice.org
+ - https://wiki.openoffice.org/wiki/Dictionaries
+
+Aspell dictionaries (conversion: man 5 hunspell):
+
+ - ftp://ftp.gnu.org/gnu/aspell/dict
+
+L叩szl坦 N辿meth, nemeth at numbertext org
+
diff --git a/extensions/spellcheck/hunspell/src/affentry.cxx b/extensions/spellcheck/hunspell/src/affentry.cxx
new file mode 100644
index 0000000000..2cf4f4671f
--- /dev/null
+++ b/extensions/spellcheck/hunspell/src/affentry.cxx
@@ -0,0 +1,983 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * Copyright (C) 2002-2022 N辿meth L叩szl坦
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (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.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * Hunspell is based on MySpell which is Copyright (C) 2002 Kevin Hendricks.
+ *
+ * Contributor(s): David Einstein, Davide Prina, Giuseppe Modugno,
+ * Gianluca Turconi, Simon Brouwer, Noll J叩nos, B鱈r坦 rp叩d,
+ * Goldman Eleon坦ra, Sarl坦s Tam叩s, Bencs叩th Boldizs叩r, Hal叩csy P辿ter,
+ * Dvornik L叩szl坦, Gefferth Andr叩s, Nagy Viktor, Varga D叩niel, Chris Halls,
+ * Rene Engelhard, Bram Moolenaar, Dafydd Jones, Harri Pitk辰nen
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+/*
+ * Copyright 2002 Kevin B. Hendricks, Stratford, Ontario, Canada
+ * And Contributors. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. All modifications to the source code must be clearly marked as
+ * such. Binary redistributions based on modified source code
+ * must be clearly marked as modified versions in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY KEVIN B. HENDRICKS AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
+ * KEVIN B. HENDRICKS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+#include <ctype.h>
+
+#include "affentry.hxx"
+#include "csutil.hxx"
+
+AffEntry::~AffEntry() {
+ if (opts & aeLONGCOND)
+ free(c.l.conds2);
+ if (morphcode && !(opts & aeALIASM))
+ free(morphcode);
+ if (contclass && !(opts & aeALIASF))
+ free(contclass);
+}
+
+PfxEntry::PfxEntry(AffixMgr* pmgr)
+ // register affix manager
+ : pmyMgr(pmgr),
+ next(NULL),
+ nexteq(NULL),
+ nextne(NULL),
+ flgnxt(NULL) {
+}
+
+// add prefix to this word assuming conditions hold
+std::string PfxEntry::add(const char* word, size_t len) {
+ std::string result;
+ if ((len > strip.size() || (len == 0 && pmyMgr->get_fullstrip())) &&
+ (len >= numconds) && test_condition(word) &&
+ (!strip.size() || (strncmp(word, strip.c_str(), strip.size()) == 0))) {
+ /* we have a match so add prefix */
+ result.assign(appnd);
+ result.append(word + strip.size());
+ }
+ return result;
+}
+
+inline char* PfxEntry::nextchar(char* p) {
+ if (p) {
+ p++;
+ if (opts & aeLONGCOND) {
+ // jump to the 2nd part of the condition
+ if (p == c.conds + MAXCONDLEN_1)
+ return c.l.conds2;
+ // end of the MAXCONDLEN length condition
+ } else if (p == c.conds + MAXCONDLEN)
+ return NULL;
+ return *p ? p : NULL;
+ }
+ return NULL;
+}
+
+inline int PfxEntry::test_condition(const char* st) {
+ const char* pos = NULL; // group with pos input position
+ bool neg = false; // complementer
+ bool ingroup = false; // character in the group
+ if (numconds == 0)
+ return 1;
+ char* p = c.conds;
+ while (1) {
+ switch (*p) {
+ case '\0':
+ return 1;
+ case '[': {
+ neg = false;
+ ingroup = false;
+ p = nextchar(p);
+ pos = st;
+ break;
+ }
+ case '^': {
+ p = nextchar(p);
+ neg = true;
+ break;
+ }
+ case ']': {
+ if (bool(neg) == bool(ingroup))
+ return 0;
+ pos = NULL;
+ p = nextchar(p);
+ // skip the next character
+ if (!ingroup && *st)
+ for (st++; (opts & aeUTF8) && (*st & 0xc0) == 0x80; st++)
+ ;
+ if (*st == '\0' && p)
+ return 0; // word <= condition
+ break;
+ }
+ case '.':
+ if (!pos) { // dots are not metacharacters in groups: [.]
+ p = nextchar(p);
+ // skip the next character
+ for (st++; (opts & aeUTF8) && (*st & 0xc0) == 0x80; st++)
+ ;
+ if (*st == '\0' && p)
+ return 0; // word <= condition
+ break;
+ }
+ /* FALLTHROUGH */
+ default: {
+ if (*st == *p) {
+ st++;
+ p = nextchar(p);
+ if ((opts & aeUTF8) && (*(st - 1) & 0x80)) { // multibyte
+ while (p && (*p & 0xc0) == 0x80) { // character
+ if (*p != *st) {
+ if (!pos)
+ return 0;
+ st = pos;
+ break;
+ }
+ p = nextchar(p);
+ st++;
+ }
+ if (pos && st != pos) {
+ ingroup = true;
+ while (p && *p != ']' && ((p = nextchar(p)) != NULL)) {
+ }
+ }
+ } else if (pos) {
+ ingroup = true;
+ while (p && *p != ']' && ((p = nextchar(p)) != NULL)) {
+ }
+ }
+ } else if (pos) { // group
+ p = nextchar(p);
+ } else
+ return 0;
+ }
+ }
+ if (!p)
+ return 1;
+ }
+}
+
+// check if this prefix entry matches
+struct hentry* PfxEntry::checkword(const char* word,
+ int len,
+ char in_compound,
+ const FLAG needflag) {
+ struct hentry* he; // hash entry of root word or NULL
+
+ // on entry prefix is 0 length or already matches the beginning of the word.
+ // So if the remaining root word has positive length
+ // and if there are enough chars in root word and added back strip chars
+ // to meet the number of characters conditions, then test it
+
+ int tmpl = len - appnd.size(); // length of tmpword
+
+ if (tmpl > 0 || (tmpl == 0 && pmyMgr->get_fullstrip())) {
+ // generate new root word by removing prefix and adding
+ // back any characters that would have been stripped
+
+ std::string tmpword(strip);
+ tmpword.append(word + appnd.size(), tmpl);
+
+ // now make sure all of the conditions on characters
+ // are met. Please see the appendix at the end of
+ // this file for more info on exactly what is being
+ // tested
+
+ // if all conditions are met then check if resulting
+ // root word in the dictionary
+
+ if (test_condition(tmpword.c_str())) {
+ tmpl += strip.size();
+ if ((he = pmyMgr->lookup(tmpword.c_str())) != NULL) {
+ do {
+ if (TESTAFF(he->astr, aflag, he->alen) &&
+ // forbid single prefixes with needaffix flag
+ !TESTAFF(contclass, pmyMgr->get_needaffix(), contclasslen) &&
+ // needflag
+ ((!needflag) || TESTAFF(he->astr, needflag, he->alen) ||
+ (contclass && TESTAFF(contclass, needflag, contclasslen))))
+ return he;
+ he = he->next_homonym; // check homonyms
+ } while (he);
+ }
+
+ // prefix matched but no root word was found
+ // if aeXPRODUCT is allowed, try again but now
+ // ross checked combined with a suffix
+
+ // if ((opts & aeXPRODUCT) && in_compound) {
+ if ((opts & aeXPRODUCT)) {
+ he = pmyMgr->suffix_check(tmpword.c_str(), tmpl, aeXPRODUCT, this,
+ FLAG_NULL, needflag, in_compound);
+ if (he)
+ return he;
+ }
+ }
+ }
+ return NULL;
+}
+
+// check if this prefix entry matches
+struct hentry* PfxEntry::check_twosfx(const char* word,
+ int len,
+ char in_compound,
+ const FLAG needflag) {
+ // on entry prefix is 0 length or already matches the beginning of the word.
+ // So if the remaining root word has positive length
+ // and if there are enough chars in root word and added back strip chars
+ // to meet the number of characters conditions, then test it
+
+ int tmpl = len - appnd.size(); // length of tmpword
+
+ if ((tmpl > 0 || (tmpl == 0 && pmyMgr->get_fullstrip())) &&
+ (tmpl + strip.size() >= numconds)) {
+ // generate new root word by removing prefix and adding
+ // back any characters that would have been stripped
+
+ std::string tmpword(strip);
+ tmpword.append(word + appnd.size());
+
+ // now make sure all of the conditions on characters
+ // are met. Please see the appendix at the end of
+ // this file for more info on exactly what is being
+ // tested
+
+ // if all conditions are met then check if resulting
+ // root word in the dictionary
+
+ if (test_condition(tmpword.c_str())) {
+ tmpl += strip.size();
+
+ // prefix matched but no root word was found
+ // if aeXPRODUCT is allowed, try again but now
+ // cross checked combined with a suffix
+
+ if ((opts & aeXPRODUCT) && (in_compound != IN_CPD_BEGIN)) {
+ // hash entry of root word or NULL
+ struct hentry* he = pmyMgr->suffix_check_twosfx(tmpword.c_str(), tmpl, aeXPRODUCT, this,
+ needflag);
+ if (he)
+ return he;
+ }
+ }
+ }
+ return NULL;
+}
+
+// check if this prefix entry matches
+std::string PfxEntry::check_twosfx_morph(const char* word,
+ int len,
+ char in_compound,
+ const FLAG needflag) {
+ std::string result;
+ // on entry prefix is 0 length or already matches the beginning of the word.
+ // So if the remaining root word has positive length
+ // and if there are enough chars in root word and added back strip chars
+ // to meet the number of characters conditions, then test it
+ int tmpl = len - appnd.size(); // length of tmpword
+
+ if ((tmpl > 0 || (tmpl == 0 && pmyMgr->get_fullstrip())) &&
+ (tmpl + strip.size() >= numconds)) {
+ // generate new root word by removing prefix and adding
+ // back any characters that would have been stripped
+
+ std::string tmpword(strip);
+ tmpword.append(word + appnd.size());
+
+ // now make sure all of the conditions on characters
+ // are met. Please see the appendix at the end of
+ // this file for more info on exactly what is being
+ // tested
+
+ // if all conditions are met then check if resulting
+ // root word in the dictionary
+
+ if (test_condition(tmpword.c_str())) {
+ tmpl += strip.size();
+
+ // prefix matched but no root word was found
+ // if aeXPRODUCT is allowed, try again but now
+ // ross checked combined with a suffix
+
+ if ((opts & aeXPRODUCT) && (in_compound != IN_CPD_BEGIN)) {
+ result = pmyMgr->suffix_check_twosfx_morph(tmpword.c_str(), tmpl,
+ aeXPRODUCT,
+ this, needflag);
+ }
+ }
+ }
+ return result;
+}
+
+// check if this prefix entry matches
+std::string PfxEntry::check_morph(const char* word,
+ int len,
+ char in_compound,
+ const FLAG needflag) {
+ std::string result;
+
+ // on entry prefix is 0 length or already matches the beginning of the word.
+ // So if the remaining root word has positive length
+ // and if there are enough chars in root word and added back strip chars
+ // to meet the number of characters conditions, then test it
+
+ int tmpl = len - appnd.size(); // length of tmpword
+
+ if ((tmpl > 0 || (tmpl == 0 && pmyMgr->get_fullstrip())) &&
+ (tmpl + strip.size() >= numconds)) {
+ // generate new root word by removing prefix and adding
+ // back any characters that would have been stripped
+
+ std::string tmpword(strip);
+ tmpword.append(word + appnd.size());
+
+ // now make sure all of the conditions on characters
+ // are met. Please see the appendix at the end of
+ // this file for more info on exactly what is being
+ // tested
+
+ // if all conditions are met then check if resulting
+ // root word in the dictionary
+
+ if (test_condition(tmpword.c_str())) {
+ tmpl += strip.size();
+ struct hentry* he; // hash entry of root word or NULL
+ if ((he = pmyMgr->lookup(tmpword.c_str())) != NULL) {
+ do {
+ if (TESTAFF(he->astr, aflag, he->alen) &&
+ // forbid single prefixes with needaffix flag
+ !TESTAFF(contclass, pmyMgr->get_needaffix(), contclasslen) &&
+ // needflag
+ ((!needflag) || TESTAFF(he->astr, needflag, he->alen) ||
+ (contclass && TESTAFF(contclass, needflag, contclasslen)))) {
+ if (morphcode) {
+ result.push_back(MSEP_FLD);
+ result.append(morphcode);
+ } else
+ result.append(getKey());
+ if (!HENTRY_FIND(he, MORPH_STEM)) {
+ result.push_back(MSEP_FLD);
+ result.append(MORPH_STEM);
+ result.append(HENTRY_WORD(he));
+ }
+ // store the pointer of the hash entry
+ if (HENTRY_DATA(he)) {
+ result.push_back(MSEP_FLD);
+ result.append(HENTRY_DATA2(he));
+ } else {
+ // return with debug information
+ char* flag = pmyMgr->encode_flag(getFlag());
+ result.push_back(MSEP_FLD);
+ result.append(MORPH_FLAG);
+ result.append(flag);
+ free(flag);
+ }
+ result.push_back(MSEP_REC);
+ }
+ he = he->next_homonym;
+ } while (he);
+ }
+
+ // prefix matched but no root word was found
+ // if aeXPRODUCT is allowed, try again but now
+ // ross checked combined with a suffix
+
+ if ((opts & aeXPRODUCT) && (in_compound != IN_CPD_BEGIN)) {
+ std::string st = pmyMgr->suffix_check_morph(tmpword.c_str(), tmpl, aeXPRODUCT, this,
+ FLAG_NULL, needflag);
+ if (!st.empty()) {
+ result.append(st);
+ }
+ }
+ }
+ }
+
+ return result;
+}
+
+SfxEntry::SfxEntry(AffixMgr* pmgr)
+ : pmyMgr(pmgr) // register affix manager
+ ,
+ next(NULL),
+ nexteq(NULL),
+ nextne(NULL),
+ flgnxt(NULL),
+ l_morph(NULL),
+ r_morph(NULL),
+ eq_morph(NULL) {
+}
+
+// add suffix to this word assuming conditions hold
+std::string SfxEntry::add(const char* word, size_t len) {
+ std::string result;
+ /* make sure all conditions match */
+ if ((len > strip.size() || (len == 0 && pmyMgr->get_fullstrip())) &&
+ (len >= numconds) && test_condition(word + len, word) &&
+ (!strip.size() ||
+ (strcmp(word + len - strip.size(), strip.c_str()) == 0))) {
+ result.assign(word);
+ /* we have a match so add suffix */
+ result.replace(len - strip.size(), std::string::npos, appnd);
+ }
+ return result;
+}
+
+inline char* SfxEntry::nextchar(char* p) {
+ if (p) {
+ p++;
+ if (opts & aeLONGCOND) {
+ // jump to the 2nd part of the condition
+ if (p == c.l.conds1 + MAXCONDLEN_1)
+ return c.l.conds2;
+ // end of the MAXCONDLEN length condition
+ } else if (p == c.conds + MAXCONDLEN)
+ return NULL;
+ return *p ? p : NULL;
+ }
+ return NULL;
+}
+
+inline int SfxEntry::test_condition(const char* st, const char* beg) {
+ const char* pos = NULL; // group with pos input position
+ bool neg = false; // complementer
+ bool ingroup = false; // character in the group
+ if (numconds == 0)
+ return 1;
+ char* p = c.conds;
+ st--;
+ int i = 1;
+ while (1) {
+ switch (*p) {
+ case '\0':
+ return 1;
+ case '[':
+ p = nextchar(p);
+ pos = st;
+ break;
+ case '^':
+ p = nextchar(p);
+ neg = true;
+ break;
+ case ']':
+ if (!neg && !ingroup)
+ return 0;
+ i++;
+ // skip the next character
+ if (!ingroup) {
+ for (; (opts & aeUTF8) && (st >= beg) && (*st & 0xc0) == 0x80; st--)
+ ;
+ st--;
+ }
+ pos = NULL;
+ neg = false;
+ ingroup = false;
+ p = nextchar(p);
+ if (st < beg && p)
+ return 0; // word <= condition
+ break;
+ case '.':
+ if (!pos) {
+ // dots are not metacharacters in groups: [.]
+ p = nextchar(p);
+ // skip the next character
+ for (st--; (opts & aeUTF8) && (st >= beg) && (*st & 0xc0) == 0x80;
+ st--)
+ ;
+ if (st < beg) { // word <= condition
+ if (p)
+ return 0;
+ else
+ return 1;
+ }
+ if ((opts & aeUTF8) && (*st & 0x80)) { // head of the UTF-8 character
+ st--;
+ if (st < beg) { // word <= condition
+ if (p)
+ return 0;
+ else
+ return 1;
+ }
+ }
+ break;
+ }
+ /* FALLTHROUGH */
+ default: {
+ if (*st == *p) {
+ p = nextchar(p);
+ if ((opts & aeUTF8) && (*st & 0x80)) {
+ st--;
+ while (p && (st >= beg)) {
+ if (*p != *st) {
+ if (!pos)
+ return 0;
+ st = pos;
+ break;
+ }
+ // first byte of the UTF-8 multibyte character
+ if ((*p & 0xc0) != 0x80)
+ break;
+ p = nextchar(p);
+ st--;
+ }
+ if (pos && st != pos) {
+ if (neg)
+ return 0;
+ else if (i == numconds)
+ return 1;
+ ingroup = true;
+ while (p && *p != ']' && ((p = nextchar(p)) != NULL)) {
+ }
+ st--;
+ }
+ if (p && *p != ']')
+ p = nextchar(p);
+ } else if (pos) {
+ if (neg)
+ return 0;
+ else if (i == numconds)
+ return 1;
+ ingroup = true;
+ while (p && *p != ']' && ((p = nextchar(p)) != NULL)) {
+ }
+ // if (p && *p != ']') p = nextchar(p);
+ st--;
+ }
+ if (!pos) {
+ i++;
+ st--;
+ }
+ if (st < beg && p && *p != ']')
+ return 0; // word <= condition
+ } else if (pos) { // group
+ p = nextchar(p);
+ } else
+ return 0;
+ }
+ }
+ if (!p)
+ return 1;
+ }
+}
+
+// see if this suffix is present in the word
+struct hentry* SfxEntry::checkword(const char* word,
+ int len,
+ int optflags,
+ PfxEntry* ppfx,
+ const FLAG cclass,
+ const FLAG needflag,
+ const FLAG badflag) {
+ struct hentry* he; // hash entry pointer
+ PfxEntry* ep = ppfx;
+
+ // if this suffix is being cross checked with a prefix
+ // but it does not support cross products skip it
+
+ if (((optflags & aeXPRODUCT) != 0) && ((opts & aeXPRODUCT) == 0))
+ return NULL;
+
+ // upon entry suffix is 0 length or already matches the end of the word.
+ // So if the remaining root word has positive length
+ // and if there are enough chars in root word and added back strip chars
+ // to meet the number of characters conditions, then test it
+
+ int tmpl = len - appnd.size(); // length of tmpword
+ // the second condition is not enough for UTF-8 strings
+ // it checked in test_condition()
+
+ if ((tmpl > 0 || (tmpl == 0 && pmyMgr->get_fullstrip())) &&
+ (tmpl + strip.size() >= numconds)) {
+ // generate new root word by removing suffix and adding
+ // back any characters that would have been stripped or
+ // or null terminating the shorter string
+
+ std::string tmpstring(word, tmpl);
+ if (strip.size()) {
+ tmpstring.append(strip);
+ }
+
+ const char* tmpword = tmpstring.c_str();
+ const char* endword = tmpword + tmpstring.size();
+
+ // now make sure all of the conditions on characters
+ // are met. Please see the appendix at the end of
+ // this file for more info on exactly what is being
+ // tested
+
+ // if all conditions are met then check if resulting
+ // root word in the dictionary
+
+ if (test_condition(endword, tmpword)) {
+#ifdef SZOSZABLYA_POSSIBLE_ROOTS
+ fprintf(stdout, "%s %s %c\n", word, tmpword, aflag);
+#endif
+ if ((he = pmyMgr->lookup(tmpword)) != NULL) {
+ do {
+ // check conditional suffix (enabled by prefix)
+ if ((TESTAFF(he->astr, aflag, he->alen) ||
+ (ep && ep->getCont() &&
+ TESTAFF(ep->getCont(), aflag, ep->getContLen()))) &&
+ (((optflags & aeXPRODUCT) == 0) ||
+ (ep && TESTAFF(he->astr, ep->getFlag(), he->alen)) ||
+ // enabled by prefix
+ ((contclass) &&
+ (ep && TESTAFF(contclass, ep->getFlag(), contclasslen)))) &&
+ // handle cont. class
+ ((!cclass) ||
+ ((contclass) && TESTAFF(contclass, cclass, contclasslen))) &&
+ // check only in compound homonyms (bad flags)
+ (!badflag || !TESTAFF(he->astr, badflag, he->alen)) &&
+ // handle required flag
+ ((!needflag) ||
+ (TESTAFF(he->astr, needflag, he->alen) ||
+ ((contclass) && TESTAFF(contclass, needflag, contclasslen)))))
+ return he;
+ he = he->next_homonym; // check homonyms
+ } while (he);
+ }
+ }
+ }
+ return NULL;
+}
+
+// see if two-level suffix is present in the word
+struct hentry* SfxEntry::check_twosfx(const char* word,
+ int len,
+ int optflags,
+ PfxEntry* ppfx,
+ const FLAG needflag) {
+ PfxEntry* ep = ppfx;
+
+ // if this suffix is being cross checked with a prefix
+ // but it does not support cross products skip it
+
+ if ((optflags & aeXPRODUCT) != 0 && (opts & aeXPRODUCT) == 0)
+ return NULL;
+
+ // upon entry suffix is 0 length or already matches the end of the word.
+ // So if the remaining root word has positive length
+ // and if there are enough chars in root word and added back strip chars
+ // to meet the number of characters conditions, then test it
+
+ int tmpl = len - appnd.size(); // length of tmpword
+
+ if ((tmpl > 0 || (tmpl == 0 && pmyMgr->get_fullstrip())) &&
+ (tmpl + strip.size() >= numconds)) {
+ // generate new root word by removing suffix and adding
+ // back any characters that would have been stripped or
+ // or null terminating the shorter string
+
+ std::string tmpword(word);
+ tmpword.resize(tmpl);
+ tmpword.append(strip);
+ tmpl += strip.size();
+
+ const char* beg = tmpword.c_str();
+ const char* end = beg + tmpl;
+
+ // now make sure all of the conditions on characters
+ // are met. Please see the appendix at the end of
+ // this file for more info on exactly what is being
+ // tested
+
+ // if all conditions are met then recall suffix_check
+
+ if (test_condition(end, beg)) {
+ struct hentry* he; // hash entry pointer
+ if (ppfx) {
+ // handle conditional suffix
+ if ((contclass) && TESTAFF(contclass, ep->getFlag(), contclasslen))
+ he = pmyMgr->suffix_check(tmpword.c_str(), tmpl, 0, NULL,
+ (FLAG)aflag, needflag, IN_CPD_NOT);
+ else
+ he = pmyMgr->suffix_check(tmpword.c_str(), tmpl, optflags, ppfx,
+ (FLAG)aflag, needflag, IN_CPD_NOT);
+ } else {
+ he = pmyMgr->suffix_check(tmpword.c_str(), tmpl, 0, NULL,
+ (FLAG)aflag, needflag, IN_CPD_NOT);
+ }
+ if (he)
+ return he;
+ }
+ }
+ return NULL;
+}
+
+// see if two-level suffix is present in the word
+std::string SfxEntry::check_twosfx_morph(const char* word,
+ int len,
+ int optflags,
+ PfxEntry* ppfx,
+ const FLAG needflag) {
+ PfxEntry* ep = ppfx;
+
+ std::string result;
+
+ // if this suffix is being cross checked with a prefix
+ // but it does not support cross products skip it
+
+ if ((optflags & aeXPRODUCT) != 0 && (opts & aeXPRODUCT) == 0)
+ return result;
+
+ // upon entry suffix is 0 length or already matches the end of the word.
+ // So if the remaining root word has positive length
+ // and if there are enough chars in root word and added back strip chars
+ // to meet the number of characters conditions, then test it
+
+ int tmpl = len - appnd.size(); // length of tmpword
+
+ if ((tmpl > 0 || (tmpl == 0 && pmyMgr->get_fullstrip())) &&
+ (tmpl + strip.size() >= numconds)) {
+ // generate new root word by removing suffix and adding
+ // back any characters that would have been stripped or
+ // or null terminating the shorter string
+
+ std::string tmpword(word);
+ tmpword.resize(tmpl);
+ tmpword.append(strip);
+ tmpl += strip.size();
+
+ const char* beg = tmpword.c_str();
+ const char* end = beg + tmpl;
+
+ // now make sure all of the conditions on characters
+ // are met. Please see the appendix at the end of
+ // this file for more info on exactly what is being
+ // tested
+
+ // if all conditions are met then recall suffix_check
+
+ if (test_condition(end, beg)) {
+ if (ppfx) {
+ // handle conditional suffix
+ if ((contclass) && TESTAFF(contclass, ep->getFlag(), contclasslen)) {
+ std::string st = pmyMgr->suffix_check_morph(tmpword.c_str(), tmpl, 0, NULL, aflag,
+ needflag);
+ if (!st.empty()) {
+ if (ppfx->getMorph()) {
+ result.append(ppfx->getMorph());
+ result.push_back(MSEP_FLD);
+ }
+ result.append(st);
+ mychomp(result);
+ }
+ } else {
+ std::string st = pmyMgr->suffix_check_morph(tmpword.c_str(), tmpl, optflags, ppfx, aflag,
+ needflag);
+ if (!st.empty()) {
+ result.append(st);
+ mychomp(result);
+ }
+ }
+ } else {
+ std::string st = pmyMgr->suffix_check_morph(tmpword.c_str(), tmpl, 0, NULL, aflag, needflag);
+ if (!st.empty()) {
+ result.append(st);
+ mychomp(result);
+ }
+ }
+ }
+ }
+ return result;
+}
+
+// get next homonym with same affix
+struct hentry* SfxEntry::get_next_homonym(struct hentry* he,
+ int optflags,
+ PfxEntry* ppfx,
+ const FLAG cclass,
+ const FLAG needflag) {
+ PfxEntry* ep = ppfx;
+ FLAG eFlag = ep ? ep->getFlag() : FLAG_NULL;
+
+ while (he->next_homonym) {
+ he = he->next_homonym;
+ if ((TESTAFF(he->astr, aflag, he->alen) ||
+ (ep && ep->getCont() &&
+ TESTAFF(ep->getCont(), aflag, ep->getContLen()))) &&
+ ((optflags & aeXPRODUCT) == 0 || TESTAFF(he->astr, eFlag, he->alen) ||
+ // handle conditional suffix
+ ((contclass) && TESTAFF(contclass, eFlag, contclasslen))) &&
+ // handle cont. class
+ ((!cclass) ||
+ ((contclass) && TESTAFF(contclass, cclass, contclasslen))) &&
+ // handle required flag
+ ((!needflag) ||
+ (TESTAFF(he->astr, needflag, he->alen) ||
+ ((contclass) && TESTAFF(contclass, needflag, contclasslen)))))
+ return he;
+ }
+ return NULL;
+}
+
+void SfxEntry::initReverseWord() {
+ rappnd = appnd;
+ reverseword(rappnd);
+}
+
+#if 0
+
+Appendix: Understanding Affix Code
+
+
+An affix is either a prefix or a suffix attached to root words to make
+other words.
+
+Basically a Prefix or a Suffix is set of AffEntry objects
+which store information about the prefix or suffix along
+with supporting routines to check if a word has a particular
+prefix or suffix or a combination.
+
+The structure affentry is defined as follows:
+
+struct affentry
+{
+ unsigned short aflag; // ID used to represent the affix
+ std::string strip; // string to strip before adding affix
+ std::string appnd; // the affix string to add
+ char numconds; // the number of conditions that must be met
+ char opts; // flag: aeXPRODUCT- combine both prefix and suffix
+ char conds[SETSIZE]; // array which encodes the conditions to be met
+};
+
+
+Here is a suffix borrowed from the en_US.aff file. This file
+is whitespace delimited.
+
+SFX D Y 4
+SFX D 0 e d
+SFX D y ied [^aeiou]y
+SFX D 0 ed [^ey]
+SFX D 0 ed [aeiou]y
+
+This information can be interpreted as follows:
+
+In the first line has 4 fields
+
+Field
+-----
+1 SFX - indicates this is a suffix
+2 D - is the name of the character flag which represents this suffix
+3 Y - indicates it can be combined with prefixes (cross product)
+4 4 - indicates that sequence of 4 affentry structures are needed to
+ properly store the affix information
+
+The remaining lines describe the unique information for the 4 SfxEntry
+objects that make up this affix. Each line can be interpreted
+as follows: (note fields 1 and 2 are as a check against line 1 info)
+
+Field
+-----
+1 SFX - indicates this is a suffix
+2 D - is the name of the character flag for this affix
+3 y - the string of chars to strip off before adding affix
+ (a 0 here indicates the NULL string)
+4 ied - the string of affix characters to add
+5 [^aeiou]y - the conditions which must be met before the affix
+ can be applied
+
+Field 5 is interesting. Since this is a suffix, field 5 tells us that
+there are 2 conditions that must be met. The first condition is that
+the next to the last character in the word must *NOT* be any of the
+following "a", "e", "i", "o" or "u". The second condition is that
+the last character of the word must end in "y".
+
+So how can we encode this information concisely and be able to
+test for both conditions in a fast manner? The answer is found
+but studying the wonderful ispell code of Geoff Kuenning, et.al.
+(now available under a normal BSD license).
+
+If we set up a conds array of 256 bytes indexed (0 to 255) and access it
+using a character (cast to an unsigned char) of a string, we have 8 bits
+of information we can store about that character. Specifically we
+could use each bit to say if that character is allowed in any of the
+last (or first for prefixes) 8 characters of the word.
+
+Basically, each character at one end of the word (up to the number
+of conditions) is used to index into the conds array and the resulting
+value found there says whether the that character is valid for a
+specific character position in the word.
+
+For prefixes, it does this by setting bit 0 if that char is valid
+in the first position, bit 1 if valid in the second position, and so on.
+
+If a bit is not set, then that char is not valid for that postion in the
+word.
+
+If working with suffixes bit 0 is used for the character closest
+to the front, bit 1 for the next character towards the end, ...,
+with bit numconds-1 representing the last char at the end of the string.
+
+Note: since entries in the conds[] are 8 bits, only 8 conditions
+(read that only 8 character positions) can be examined at one
+end of a word (the beginning for prefixes and the end for suffixes.
+
+So to make this clearer, lets encode the conds array values for the
+first two affentries for the suffix D described earlier.
+
+
+ For the first affentry:
+ numconds = 1 (only examine the last character)
+
+ conds['e'] = (1 << 0) (the word must end in an E)
+ all others are all 0
+
+ For the second affentry:
+ numconds = 2 (only examine the last two characters)
+
+ conds[X] = conds[X] | (1 << 0) (aeiou are not allowed)
+ where X is all characters *but* a, e, i, o, or u
+
+
+ conds['y'] = (1 << 1) (the last char must be a y)
+ all other bits for all other entries in the conds array are zero
+
+#endif
diff --git a/extensions/spellcheck/hunspell/src/affentry.hxx b/extensions/spellcheck/hunspell/src/affentry.hxx
new file mode 100644
index 0000000000..b736bf0350
--- /dev/null
+++ b/extensions/spellcheck/hunspell/src/affentry.hxx
@@ -0,0 +1,223 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * Copyright (C) 2002-2022 N辿meth L叩szl坦
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (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.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * Hunspell is based on MySpell which is Copyright (C) 2002 Kevin Hendricks.
+ *
+ * Contributor(s): David Einstein, Davide Prina, Giuseppe Modugno,
+ * Gianluca Turconi, Simon Brouwer, Noll J叩nos, B鱈r坦 rp叩d,
+ * Goldman Eleon坦ra, Sarl坦s Tam叩s, Bencs叩th Boldizs叩r, Hal叩csy P辿ter,
+ * Dvornik L叩szl坦, Gefferth Andr叩s, Nagy Viktor, Varga D叩niel, Chris Halls,
+ * Rene Engelhard, Bram Moolenaar, Dafydd Jones, Harri Pitk辰nen
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+/*
+ * Copyright 2002 Kevin B. Hendricks, Stratford, Ontario, Canada
+ * And Contributors. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. All modifications to the source code must be clearly marked as
+ * such. Binary redistributions based on modified source code
+ * must be clearly marked as modified versions in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY KEVIN B. HENDRICKS AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
+ * KEVIN B. HENDRICKS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef AFFIX_HXX_
+#define AFFIX_HXX_
+
+#include "atypes.hxx"
+#include "baseaffix.hxx"
+#include "affixmgr.hxx"
+
+/* A Prefix Entry */
+
+class PfxEntry : public AffEntry {
+ private:
+ PfxEntry(const PfxEntry&);
+ PfxEntry& operator=(const PfxEntry&);
+
+ private:
+ AffixMgr* pmyMgr;
+
+ PfxEntry* next;
+ PfxEntry* nexteq;
+ PfxEntry* nextne;
+ PfxEntry* flgnxt;
+
+ public:
+ explicit PfxEntry(AffixMgr* pmgr);
+
+ bool allowCross() const { return ((opts & aeXPRODUCT) != 0); }
+ struct hentry* checkword(const char* word,
+ int len,
+ char in_compound,
+ const FLAG needflag = FLAG_NULL);
+
+ struct hentry* check_twosfx(const char* word,
+ int len,
+ char in_compound,
+ const FLAG needflag = FLAG_NULL);
+
+ std::string check_morph(const char* word,
+ int len,
+ char in_compound,
+ const FLAG needflag = FLAG_NULL);
+
+ std::string check_twosfx_morph(const char* word,
+ int len,
+ char in_compound,
+ const FLAG needflag = FLAG_NULL);
+
+ FLAG getFlag() { return aflag; }
+ const char* getKey() { return appnd.c_str(); }
+ std::string add(const char* word, size_t len);
+
+ inline short getKeyLen() { return appnd.size(); }
+
+ inline const char* getMorph() { return morphcode; }
+
+ inline const unsigned short* getCont() { return contclass; }
+ inline short getContLen() { return contclasslen; }
+
+ inline PfxEntry* getNext() { return next; }
+ inline PfxEntry* getNextNE() { return nextne; }
+ inline PfxEntry* getNextEQ() { return nexteq; }
+ inline PfxEntry* getFlgNxt() { return flgnxt; }
+
+ inline void setNext(PfxEntry* ptr) { next = ptr; }
+ inline void setNextNE(PfxEntry* ptr) { nextne = ptr; }
+ inline void setNextEQ(PfxEntry* ptr) { nexteq = ptr; }
+ inline void setFlgNxt(PfxEntry* ptr) { flgnxt = ptr; }
+
+ inline char* nextchar(char* p);
+ inline int test_condition(const char* st);
+};
+
+/* A Suffix Entry */
+
+class SfxEntry : public AffEntry {
+ private:
+ SfxEntry(const SfxEntry&);
+ SfxEntry& operator=(const SfxEntry&);
+
+ private:
+ AffixMgr* pmyMgr;
+ std::string rappnd;
+
+ SfxEntry* next;
+ SfxEntry* nexteq;
+ SfxEntry* nextne;
+ SfxEntry* flgnxt;
+
+ SfxEntry* l_morph;
+ SfxEntry* r_morph;
+ SfxEntry* eq_morph;
+
+ public:
+ explicit SfxEntry(AffixMgr* pmgr);
+
+ bool allowCross() const { return ((opts & aeXPRODUCT) != 0); }
+ struct hentry* checkword(const char* word,
+ int len,
+ int optflags,
+ PfxEntry* ppfx,
+ const FLAG cclass,
+ const FLAG needflag,
+ const FLAG badflag);
+
+ struct hentry* check_twosfx(const char* word,
+ int len,
+ int optflags,
+ PfxEntry* ppfx,
+ const FLAG needflag = FLAG_NULL);
+
+ std::string check_twosfx_morph(const char* word,
+ int len,
+ int optflags,
+ PfxEntry* ppfx,
+ const FLAG needflag = FLAG_NULL);
+ struct hentry* get_next_homonym(struct hentry* he);
+ struct hentry* get_next_homonym(struct hentry* word,
+ int optflags,
+ PfxEntry* ppfx,
+ const FLAG cclass,
+ const FLAG needflag);
+
+ FLAG getFlag() { return aflag; }
+ const char* getKey() { return rappnd.c_str(); }
+ std::string add(const char* word, size_t len);
+
+ inline const char* getMorph() { return morphcode; }
+
+ inline const unsigned short* getCont() { return contclass; }
+ inline short getContLen() { return contclasslen; }
+ inline const char* getAffix() { return appnd.c_str(); }
+
+ inline short getKeyLen() { return appnd.size(); }
+
+ inline SfxEntry* getNext() { return next; }
+ inline SfxEntry* getNextNE() { return nextne; }
+ inline SfxEntry* getNextEQ() { return nexteq; }
+
+ inline SfxEntry* getLM() { return l_morph; }
+ inline SfxEntry* getRM() { return r_morph; }
+ inline SfxEntry* getEQM() { return eq_morph; }
+ inline SfxEntry* getFlgNxt() { return flgnxt; }
+
+ inline void setNext(SfxEntry* ptr) { next = ptr; }
+ inline void setNextNE(SfxEntry* ptr) { nextne = ptr; }
+ inline void setNextEQ(SfxEntry* ptr) { nexteq = ptr; }
+ inline void setFlgNxt(SfxEntry* ptr) { flgnxt = ptr; }
+ void initReverseWord();
+
+ inline char* nextchar(char* p);
+ inline int test_condition(const char* st, const char* begin);
+};
+
+#endif
diff --git a/extensions/spellcheck/hunspell/src/affixmgr.cxx b/extensions/spellcheck/hunspell/src/affixmgr.cxx
new file mode 100644
index 0000000000..adb750dba1
--- /dev/null
+++ b/extensions/spellcheck/hunspell/src/affixmgr.cxx
@@ -0,0 +1,4875 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * Copyright (C) 2002-2022 N辿meth L叩szl坦
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (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.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * Hunspell is based on MySpell which is Copyright (C) 2002 Kevin Hendricks.
+ *
+ * Contributor(s): David Einstein, Davide Prina, Giuseppe Modugno,
+ * Gianluca Turconi, Simon Brouwer, Noll J叩nos, B鱈r坦 rp叩d,
+ * Goldman Eleon坦ra, Sarl坦s Tam叩s, Bencs叩th Boldizs叩r, Hal叩csy P辿ter,
+ * Dvornik L叩szl坦, Gefferth Andr叩s, Nagy Viktor, Varga D叩niel, Chris Halls,
+ * Rene Engelhard, Bram Moolenaar, Dafydd Jones, Harri Pitk辰nen
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+/*
+ * Copyright 2002 Kevin B. Hendricks, Stratford, Ontario, Canada
+ * And Contributors. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. All modifications to the source code must be clearly marked as
+ * such. Binary redistributions based on modified source code
+ * must be clearly marked as modified versions in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY KEVIN B. HENDRICKS AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
+ * KEVIN B. HENDRICKS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+#include <ctype.h>
+#include <time.h>
+
+#include <algorithm>
+#include <limits>
+#include <string>
+#include <vector>
+
+#include "affixmgr.hxx"
+#include "affentry.hxx"
+#include "langnum.hxx"
+
+#include "csutil.hxx"
+
+AffixMgr::AffixMgr(const char* affpath,
+ const std::vector<HashMgr*>& ptr,
+ const char* key)
+ : alldic(ptr)
+ , pHMgr(ptr[0]) {
+
+ // register hash manager and load affix data from aff file
+ csconv = NULL;
+ utf8 = 0;
+ complexprefixes = 0;
+ parsedmaptable = false;
+ parsedbreaktable = false;
+ iconvtable = NULL;
+ oconvtable = NULL;
+ // allow simplified compound forms (see 3rd field of CHECKCOMPOUNDPATTERN)
+ simplifiedcpd = 0;
+ parsedcheckcpd = false;
+ parseddefcpd = false;
+ phone = NULL;
+ compoundflag = FLAG_NULL; // permits word in compound forms
+ compoundbegin = FLAG_NULL; // may be first word in compound forms
+ compoundmiddle = FLAG_NULL; // may be middle word in compound forms
+ compoundend = FLAG_NULL; // may be last word in compound forms
+ compoundroot = FLAG_NULL; // compound word signing flag
+ compoundpermitflag = FLAG_NULL; // compound permitting flag for suffixed word
+ compoundforbidflag = FLAG_NULL; // compound fordidden flag for suffixed word
+ compoundmoresuffixes = 0; // allow more suffixes within compound words
+ checkcompounddup = 0; // forbid double words in compounds
+ checkcompoundrep = 0; // forbid bad compounds (may be non-compound word with
+ // a REP substitution)
+ checkcompoundcase =
+ 0; // forbid upper and lowercase combinations at word bounds
+ checkcompoundtriple = 0; // forbid compounds with triple letters
+ simplifiedtriple = 0; // allow simplified triple letters in compounds
+ // (Schiff+fahrt -> Schiffahrt)
+ forbiddenword = FORBIDDENWORD; // forbidden word signing flag
+ nosuggest = FLAG_NULL; // don't suggest words signed with NOSUGGEST flag
+ nongramsuggest = FLAG_NULL;
+ langnum = 0; // language code (see http://l10n.openoffice.org/languages.html)
+ needaffix = FLAG_NULL; // forbidden root, allowed only with suffixes
+ cpdwordmax = -1; // default: unlimited wordcount in compound words
+ cpdmin = -1; // undefined
+ cpdmaxsyllable = 0; // default: unlimited syllablecount in compound words
+ pfxappnd = NULL; // previous prefix for counting syllables of the prefix BUG
+ sfxappnd = NULL; // previous suffix for counting syllables of the suffix BUG
+ sfxextra = 0; // modifier for syllable count of sfxappnd BUG
+ checknum = 0; // checking numbers, and word with numbers
+ havecontclass = 0; // flags of possible continuing classes (double affix)
+ // LEMMA_PRESENT: not put root into the morphological output. Lemma presents
+ // in morhological description in dictionary file. It's often combined with
+ // PSEUDOROOT.
+ lemma_present = FLAG_NULL;
+ circumfix = FLAG_NULL;
+ onlyincompound = FLAG_NULL;
+ maxngramsugs = -1; // undefined
+ maxdiff = -1; // undefined
+ onlymaxdiff = 0;
+ maxcpdsugs = -1; // undefined
+ nosplitsugs = 0;
+ sugswithdots = 0;
+ keepcase = 0;
+ forceucase = 0;
+ warn = 0;
+ forbidwarn = 0;
+ checksharps = 0;
+ substandard = FLAG_NULL;
+ fullstrip = 0;
+
+ sfx = NULL;
+ pfx = NULL;
+
+ for (int i = 0; i < SETSIZE; i++) {
+ pStart[i] = NULL;
+ sStart[i] = NULL;
+ pFlag[i] = NULL;
+ sFlag[i] = NULL;
+ }
+
+ for (int j = 0; j < CONTSIZE; j++) {
+ contclasses[j] = 0;
+ }
+
+ if (parse_file(affpath, key)) {
+ HUNSPELL_WARNING(stderr, "Failure loading aff file %s\n", affpath);
+ }
+
+ if (cpdmin == -1)
+ cpdmin = MINCPDLEN;
+}
+
+AffixMgr::~AffixMgr() {
+ // pass through linked prefix entries and clean up
+ for (int i = 0; i < SETSIZE; i++) {
+ pFlag[i] = NULL;
+ PfxEntry* ptr = pStart[i];
+ PfxEntry* nptr = NULL;
+ while (ptr) {
+ nptr = ptr->getNext();
+ delete (ptr);
+ ptr = nptr;
+ nptr = NULL;
+ }
+ }
+
+ // pass through linked suffix entries and clean up
+ for (int j = 0; j < SETSIZE; j++) {
+ sFlag[j] = NULL;
+ SfxEntry* ptr = sStart[j];
+ SfxEntry* nptr = NULL;
+ while (ptr) {
+ nptr = ptr->getNext();
+ delete (ptr);
+ ptr = nptr;
+ nptr = NULL;
+ }
+ sStart[j] = NULL;
+ }
+
+ delete iconvtable;
+ delete oconvtable;
+ delete phone;
+
+ FREE_FLAG(compoundflag);
+ FREE_FLAG(compoundbegin);
+ FREE_FLAG(compoundmiddle);
+ FREE_FLAG(compoundend);
+ FREE_FLAG(compoundpermitflag);
+ FREE_FLAG(compoundforbidflag);
+ FREE_FLAG(compoundroot);
+ FREE_FLAG(forbiddenword);
+ FREE_FLAG(nosuggest);
+ FREE_FLAG(nongramsuggest);
+ FREE_FLAG(needaffix);
+ FREE_FLAG(lemma_present);
+ FREE_FLAG(circumfix);
+ FREE_FLAG(onlyincompound);
+
+ cpdwordmax = 0;
+ pHMgr = NULL;
+ cpdmin = 0;
+ cpdmaxsyllable = 0;
+ free_utf_tbl();
+ checknum = 0;
+#ifdef MOZILLA_CLIENT
+ delete[] csconv;
+#endif
+}
+
+void AffixMgr::finishFileMgr(FileMgr* afflst) {
+ delete afflst;
+
+ // convert affix trees to sorted list
+ process_pfx_tree_to_list();
+ process_sfx_tree_to_list();
+}
+
+// read in aff file and build up prefix and suffix entry objects
+int AffixMgr::parse_file(const char* affpath, const char* key) {
+
+ // checking flag duplication
+ char dupflags[CONTSIZE];
+ char dupflags_ini = 1;
+
+ // first line indicator for removing byte order mark
+ int firstline = 1;
+
+ // open the affix file
+ FileMgr* afflst = new FileMgr(affpath, key);
+ if (!afflst) {
+ HUNSPELL_WARNING(
+ stderr, "error: could not open affix description file %s\n", affpath);
+ return 1;
+ }
+
+ // step one is to parse the affix file building up the internal
+ // affix data structures
+
+ // read in each line ignoring any that do not
+ // start with a known line type indicator
+ std::string line;
+ while (afflst->getline(line)) {
+ mychomp(line);
+
+ /* remove byte order mark */
+ if (firstline) {
+ firstline = 0;
+ // Affix file begins with byte order mark: possible incompatibility with
+ // old Hunspell versions
+ if (line.compare(0, 3, "\xEF\xBB\xBF", 3) == 0) {
+ line.erase(0, 3);
+ }
+ }
+
+ /* parse in the keyboard string */
+ if (line.compare(0, 3, "KEY", 3) == 0) {
+ if (!parse_string(line, keystring, afflst->getlinenum())) {
+ finishFileMgr(afflst);
+ return 1;
+ }
+ }
+
+ /* parse in the try string */
+ if (line.compare(0, 3, "TRY", 3) == 0) {
+ if (!parse_string(line, trystring, afflst->getlinenum())) {
+ finishFileMgr(afflst);
+ return 1;
+ }
+ }
+
+ /* parse in the name of the character set used by the .dict and .aff */
+ if (line.compare(0, 3, "SET", 3) == 0) {
+ if (!parse_string(line, encoding, afflst->getlinenum())) {
+ finishFileMgr(afflst);
+ return 1;
+ }
+ if (encoding == "UTF-8") {
+ utf8 = 1;
+#ifndef OPENOFFICEORG
+#ifndef MOZILLA_CLIENT
+ initialize_utf_tbl();
+#endif
+#endif
+ }
+ }
+
+ /* parse COMPLEXPREFIXES for agglutinative languages with right-to-left
+ * writing system */
+ if (line.compare(0, 15, "COMPLEXPREFIXES", 15) == 0)
+ complexprefixes = 1;
+
+ /* parse in the flag used by the controlled compound words */
+ if (line.compare(0, 12, "COMPOUNDFLAG", 12) == 0) {
+ if (!parse_flag(line, &compoundflag, afflst)) {
+ finishFileMgr(afflst);
+ return 1;
+ }
+ }
+
+ /* parse in the flag used by compound words */
+ if (line.compare(0, 13, "COMPOUNDBEGIN", 13) == 0) {
+ if (complexprefixes) {
+ if (!parse_flag(line, &compoundend, afflst)) {
+ finishFileMgr(afflst);
+ return 1;
+ }
+ } else {
+ if (!parse_flag(line, &compoundbegin, afflst)) {
+ finishFileMgr(afflst);
+ return 1;
+ }
+ }
+ }
+
+ /* parse in the flag used by compound words */
+ if (line.compare(0, 14, "COMPOUNDMIDDLE", 14) == 0) {
+ if (!parse_flag(line, &compoundmiddle, afflst)) {
+ finishFileMgr(afflst);
+ return 1;
+ }
+ }
+
+ /* parse in the flag used by compound words */
+ if (line.compare(0, 11, "COMPOUNDEND", 11) == 0) {
+ if (complexprefixes) {
+ if (!parse_flag(line, &compoundbegin, afflst)) {
+ finishFileMgr(afflst);
+ return 1;
+ }
+ } else {
+ if (!parse_flag(line, &compoundend, afflst)) {
+ finishFileMgr(afflst);
+ return 1;
+ }
+ }
+ }
+
+ /* parse in the data used by compound_check() method */
+ if (line.compare(0, 15, "COMPOUNDWORDMAX", 15) == 0) {
+ if (!parse_num(line, &cpdwordmax, afflst)) {
+ finishFileMgr(afflst);
+ return 1;
+ }
+ }
+
+ /* parse in the flag sign compounds in dictionary */
+ if (line.compare(0, 12, "COMPOUNDROOT", 12) == 0) {
+ if (!parse_flag(line, &compoundroot, afflst)) {
+ finishFileMgr(afflst);
+ return 1;
+ }
+ }
+
+ /* parse in the flag used by compound_check() method */
+ if (line.compare(0, 18, "COMPOUNDPERMITFLAG", 18) == 0) {
+ if (!parse_flag(line, &compoundpermitflag, afflst)) {
+ finishFileMgr(afflst);
+ return 1;
+ }
+ }
+
+ /* parse in the flag used by compound_check() method */
+ if (line.compare(0, 18, "COMPOUNDFORBIDFLAG", 18) == 0) {
+ if (!parse_flag(line, &compoundforbidflag, afflst)) {
+ finishFileMgr(afflst);
+ return 1;
+ }
+ }
+
+ if (line.compare(0, 20, "COMPOUNDMORESUFFIXES", 20) == 0) {
+ compoundmoresuffixes = 1;
+ }
+
+ if (line.compare(0, 16, "CHECKCOMPOUNDDUP", 16) == 0) {
+ checkcompounddup = 1;
+ }
+
+ if (line.compare(0, 16, "CHECKCOMPOUNDREP", 16) == 0) {
+ checkcompoundrep = 1;
+ }
+
+ if (line.compare(0, 19, "CHECKCOMPOUNDTRIPLE", 19) == 0) {
+ checkcompoundtriple = 1;
+ }
+
+ if (line.compare(0, 16, "SIMPLIFIEDTRIPLE", 16) == 0) {
+ simplifiedtriple = 1;
+ }
+
+ if (line.compare(0, 17, "CHECKCOMPOUNDCASE", 17) == 0) {
+ checkcompoundcase = 1;
+ }
+
+ if (line.compare(0, 9, "NOSUGGEST", 9) == 0) {
+ if (!parse_flag(line, &nosuggest, afflst)) {
+ finishFileMgr(afflst);
+ return 1;
+ }
+ }
+
+ if (line.compare(0, 14, "NONGRAMSUGGEST", 14) == 0) {
+ if (!parse_flag(line, &nongramsuggest, afflst)) {
+ finishFileMgr(afflst);
+ return 1;
+ }
+ }
+
+ /* parse in the flag used by forbidden words */
+ if (line.compare(0, 13, "FORBIDDENWORD", 13) == 0) {
+ if (!parse_flag(line, &forbiddenword, afflst)) {
+ finishFileMgr(afflst);
+ return 1;
+ }
+ }
+
+ /* parse in the flag used by forbidden words (is deprecated) */
+ if (line.compare(0, 13, "LEMMA_PRESENT", 13) == 0) {
+ if (!parse_flag(line, &lemma_present, afflst)) {
+ finishFileMgr(afflst);
+ return 1;
+ }
+ }
+
+ /* parse in the flag used by circumfixes */
+ if (line.compare(0, 9, "CIRCUMFIX", 9) == 0) {
+ if (!parse_flag(line, &circumfix, afflst)) {
+ finishFileMgr(afflst);
+ return 1;
+ }
+ }
+
+ /* parse in the flag used by fogemorphemes */
+ if (line.compare(0, 14, "ONLYINCOMPOUND", 14) == 0) {
+ if (!parse_flag(line, &onlyincompound, afflst)) {
+ finishFileMgr(afflst);
+ return 1;
+ }
+ }
+
+ /* parse in the flag used by `needaffixs' (is deprecated) */
+ if (line.compare(0, 10, "PSEUDOROOT", 10) == 0) {
+ if (!parse_flag(line, &needaffix, afflst)) {
+ finishFileMgr(afflst);
+ return 1;
+ }
+ }
+
+ /* parse in the flag used by `needaffixs' */
+ if (line.compare(0, 9, "NEEDAFFIX", 9) == 0) {
+ if (!parse_flag(line, &needaffix, afflst)) {
+ finishFileMgr(afflst);
+ return 1;
+ }
+ }
+
+ /* parse in the minimal length for words in compounds */
+ if (line.compare(0, 11, "COMPOUNDMIN", 11) == 0) {
+ if (!parse_num(line, &cpdmin, afflst)) {
+ finishFileMgr(afflst);
+ return 1;
+ }
+ if (cpdmin < 1)
+ cpdmin = 1;
+ }
+
+ /* parse in the max. words and syllables in compounds */
+ if (line.compare(0, 16, "COMPOUNDSYLLABLE", 16) == 0) {
+ if (!parse_cpdsyllable(line, afflst)) {
+ finishFileMgr(afflst);
+ return 1;
+ }
+ }
+
+ /* parse in the flag used by compound_check() method */
+ if (line.compare(0, 11, "SYLLABLENUM", 11) == 0) {
+ if (!parse_string(line, cpdsyllablenum, afflst->getlinenum())) {
+ finishFileMgr(afflst);
+ return 1;
+ }
+ }
+
+ /* parse in the flag used by the controlled compound words */
+ if (line.compare(0, 8, "CHECKNUM", 8) == 0) {
+ checknum = 1;
+ }
+
+ /* parse in the extra word characters */
+ if (line.compare(0, 9, "WORDCHARS", 9) == 0) {
+ if (!parse_array(line, wordchars, wordchars_utf16,
+ utf8, afflst->getlinenum())) {
+ finishFileMgr(afflst);
+ return 1;
+ }
+ }
+
+ /* parse in the ignored characters (for example, Arabic optional diacretics
+ * charachters */
+ if (line.compare(0, 6, "IGNORE", 6) == 0) {
+ if (!parse_array(line, ignorechars, ignorechars_utf16,
+ utf8, afflst->getlinenum())) {
+ finishFileMgr(afflst);
+ return 1;
+ }
+ }
+
+ /* parse in the input conversion table */
+ if (line.compare(0, 5, "ICONV", 5) == 0) {
+ if (!parse_convtable(line, afflst, &iconvtable, "ICONV")) {
+ finishFileMgr(afflst);
+ return 1;
+ }
+ }
+
+ /* parse in the output conversion table */
+ if (line.compare(0, 5, "OCONV", 5) == 0) {
+ if (!parse_convtable(line, afflst, &oconvtable, "OCONV")) {
+ finishFileMgr(afflst);
+ return 1;
+ }
+ }
+
+ /* parse in the phonetic translation table */
+ if (line.compare(0, 5, "PHONE", 5) == 0) {
+ if (!parse_phonetable(line, afflst)) {
+ finishFileMgr(afflst);
+ return 1;
+ }
+ }
+
+ /* parse in the checkcompoundpattern table */
+ if (line.compare(0, 20, "CHECKCOMPOUNDPATTERN", 20) == 0) {
+ if (!parse_checkcpdtable(line, afflst)) {
+ finishFileMgr(afflst);
+ return 1;
+ }
+ }
+
+ /* parse in the defcompound table */
+ if (line.compare(0, 12, "COMPOUNDRULE", 12) == 0) {
+ if (!parse_defcpdtable(line, afflst)) {
+ finishFileMgr(afflst);
+ return 1;
+ }
+ }
+
+ /* parse in the related character map table */
+ if (line.compare(0, 3, "MAP", 3) == 0) {
+ if (!parse_maptable(line, afflst)) {
+ finishFileMgr(afflst);
+ return 1;
+ }
+ }
+
+ /* parse in the word breakpoints table */
+ if (line.compare(0, 5, "BREAK", 5) == 0) {
+ if (!parse_breaktable(line, afflst)) {
+ finishFileMgr(afflst);
+ return 1;
+ }
+ }
+
+ /* parse in the language for language specific codes */
+ if (line.compare(0, 4, "LANG", 4) == 0) {
+ if (!parse_string(line, lang, afflst->getlinenum())) {
+ finishFileMgr(afflst);
+ return 1;
+ }
+ langnum = get_lang_num(lang);
+ }
+
+ if (line.compare(0, 7, "VERSION", 7) == 0) {
+ size_t startpos = line.find_first_not_of(" \t", 7);
+ if (startpos != std::string::npos) {
+ version = line.substr(startpos);
+ }
+ }
+
+ if (line.compare(0, 12, "MAXNGRAMSUGS", 12) == 0) {
+ if (!parse_num(line, &maxngramsugs, afflst)) {
+ finishFileMgr(afflst);
+ return 1;
+ }
+ }
+
+ if (line.compare(0, 11, "ONLYMAXDIFF", 11) == 0)
+ onlymaxdiff = 1;
+
+ if (line.compare(0, 7, "MAXDIFF", 7) == 0) {
+ if (!parse_num(line, &maxdiff, afflst)) {
+ finishFileMgr(afflst);
+ return 1;
+ }
+ }
+
+ if (line.compare(0, 10, "MAXCPDSUGS", 10) == 0) {
+ if (!parse_num(line, &maxcpdsugs, afflst)) {
+ finishFileMgr(afflst);
+ return 1;
+ }
+ }
+
+ if (line.compare(0, 11, "NOSPLITSUGS", 11) == 0) {
+ nosplitsugs = 1;
+ }
+
+ if (line.compare(0, 9, "FULLSTRIP", 9) == 0) {
+ fullstrip = 1;
+ }
+
+ if (line.compare(0, 12, "SUGSWITHDOTS", 12) == 0) {
+ sugswithdots = 1;
+ }
+
+ /* parse in the flag used by forbidden words */
+ if (line.compare(0, 8, "KEEPCASE", 8) == 0) {
+ if (!parse_flag(line, &keepcase, afflst)) {
+ finishFileMgr(afflst);
+ return 1;
+ }
+ }
+
+ /* parse in the flag used by `forceucase' */
+ if (line.compare(0, 10, "FORCEUCASE", 10) == 0) {
+ if (!parse_flag(line, &forceucase, afflst)) {
+ finishFileMgr(afflst);
+ return 1;
+ }
+ }
+
+ /* parse in the flag used by `warn' */
+ if (line.compare(0, 4, "WARN", 4) == 0) {
+ if (!parse_flag(line, &warn, afflst)) {
+ finishFileMgr(afflst);
+ return 1;
+ }
+ }
+
+ if (line.compare(0, 10, "FORBIDWARN", 10) == 0) {
+ forbidwarn = 1;
+ }
+
+ /* parse in the flag used by the affix generator */
+ if (line.compare(0, 11, "SUBSTANDARD", 11) == 0) {
+ if (!parse_flag(line, &substandard, afflst)) {
+ finishFileMgr(afflst);
+ return 1;
+ }
+ }
+
+ if (line.compare(0, 11, "CHECKSHARPS", 11) == 0) {
+ checksharps = 1;
+ }
+
+ /* parse this affix: P - prefix, S - suffix */
+ // affix type
+ char ft = ' ';
+ if (line.compare(0, 3, "PFX", 3) == 0)
+ ft = complexprefixes ? 'S' : 'P';
+ if (line.compare(0, 3, "SFX", 3) == 0)
+ ft = complexprefixes ? 'P' : 'S';
+ if (ft != ' ') {
+ if (dupflags_ini) {
+ memset(dupflags, 0, sizeof(dupflags));
+ dupflags_ini = 0;
+ }
+ if (!parse_affix(line, ft, afflst, dupflags)) {
+ finishFileMgr(afflst);
+ return 1;
+ }
+ }
+ }
+
+ finishFileMgr(afflst);
+ // affix trees are sorted now
+
+ // now we can speed up performance greatly taking advantage of the
+ // relationship between the affixes and the idea of "subsets".
+
+ // View each prefix as a potential leading subset of another and view
+ // each suffix (reversed) as a potential trailing subset of another.
+
+ // To illustrate this relationship if we know the prefix "ab" is found in the
+ // word to examine, only prefixes that "ab" is a leading subset of need be
+ // examined.
+ // Furthermore is "ab" is not present then none of the prefixes that "ab" is
+ // is a subset need be examined.
+ // The same argument goes for suffix string that are reversed.
+
+ // Then to top this off why not examine the first char of the word to quickly
+ // limit the set of prefixes to examine (i.e. the prefixes to examine must
+ // be leading supersets of the first character of the word (if they exist)
+
+ // To take advantage of this "subset" relationship, we need to add two links
+ // from entry. One to take next if the current prefix is found (call it
+ // nexteq)
+ // and one to take next if the current prefix is not found (call it nextne).
+
+ // Since we have built ordered lists, all that remains is to properly
+ // initialize
+ // the nextne and nexteq pointers that relate them
+
+ process_pfx_order();
+ process_sfx_order();
+
+ /* get encoding for CHECKCOMPOUNDCASE */
+ if (!utf8) {
+ csconv = get_current_cs(get_encoding());
+ for (int i = 0; i <= 255; i++) {
+ if ((csconv[i].cupper != csconv[i].clower) &&
+ (wordchars.find((char)i) == std::string::npos)) {
+ wordchars.push_back((char)i);
+ }
+ }
+
+ }
+
+ // default BREAK definition
+ if (!parsedbreaktable) {
+ breaktable.push_back("-");
+ breaktable.push_back("^-");
+ breaktable.push_back("-$");
+ parsedbreaktable = true;
+ }
+ return 0;
+}
+
+// we want to be able to quickly access prefix information
+// both by prefix flag, and sorted by prefix string itself
+// so we need to set up two indexes
+
+int AffixMgr::build_pfxtree(PfxEntry* pfxptr) {
+ PfxEntry* ptr;
+ PfxEntry* pptr;
+ PfxEntry* ep = pfxptr;
+
+ // get the right starting points
+ const char* key = ep->getKey();
+ const unsigned char flg = (unsigned char)(ep->getFlag() & 0x00FF);
+
+ // first index by flag which must exist
+ ptr = pFlag[flg];
+ ep->setFlgNxt(ptr);
+ pFlag[flg] = ep;
+
+ // handle the special case of null affix string
+ if (strlen(key) == 0) {
+ // always inset them at head of list at element 0
+ ptr = pStart[0];
+ ep->setNext(ptr);
+ pStart[0] = ep;
+ return 0;
+ }
+
+ // now handle the normal case
+ ep->setNextEQ(NULL);
+ ep->setNextNE(NULL);
+
+ unsigned char sp = *((const unsigned char*)key);
+ ptr = pStart[sp];
+
+ // handle the first insert
+ if (!ptr) {
+ pStart[sp] = ep;
+ return 0;
+ }
+
+ // otherwise use binary tree insertion so that a sorted
+ // list can easily be generated later
+ pptr = NULL;
+ for (;;) {
+ pptr = ptr;
+ if (strcmp(ep->getKey(), ptr->getKey()) <= 0) {
+ ptr = ptr->getNextEQ();
+ if (!ptr) {
+ pptr->setNextEQ(ep);
+ break;
+ }
+ } else {
+ ptr = ptr->getNextNE();
+ if (!ptr) {
+ pptr->setNextNE(ep);
+ break;
+ }
+ }
+ }
+ return 0;
+}
+
+// we want to be able to quickly access suffix information
+// both by suffix flag, and sorted by the reverse of the
+// suffix string itself; so we need to set up two indexes
+int AffixMgr::build_sfxtree(SfxEntry* sfxptr) {
+
+ sfxptr->initReverseWord();
+
+ SfxEntry* ptr;
+ SfxEntry* pptr;
+ SfxEntry* ep = sfxptr;
+
+ /* get the right starting point */
+ const char* key = ep->getKey();
+ const unsigned char flg = (unsigned char)(ep->getFlag() & 0x00FF);
+
+ // first index by flag which must exist
+ ptr = sFlag[flg];
+ ep->setFlgNxt(ptr);
+ sFlag[flg] = ep;
+
+ // next index by affix string
+
+ // handle the special case of null affix string
+ if (strlen(key) == 0) {
+ // always inset them at head of list at element 0
+ ptr = sStart[0];
+ ep->setNext(ptr);
+ sStart[0] = ep;
+ return 0;
+ }
+
+ // now handle the normal case
+ ep->setNextEQ(NULL);
+ ep->setNextNE(NULL);
+
+ unsigned char sp = *((const unsigned char*)key);
+ ptr = sStart[sp];
+
+ // handle the first insert
+ if (!ptr) {
+ sStart[sp] = ep;
+ return 0;
+ }
+
+ // otherwise use binary tree insertion so that a sorted
+ // list can easily be generated later
+ pptr = NULL;
+ for (;;) {
+ pptr = ptr;
+ if (strcmp(ep->getKey(), ptr->getKey()) <= 0) {
+ ptr = ptr->getNextEQ();
+ if (!ptr) {
+ pptr->setNextEQ(ep);
+ break;
+ }
+ } else {
+ ptr = ptr->getNextNE();
+ if (!ptr) {
+ pptr->setNextNE(ep);
+ break;
+ }
+ }
+ }
+ return 0;
+}
+
+// convert from binary tree to sorted list
+int AffixMgr::process_pfx_tree_to_list() {
+ for (int i = 1; i < SETSIZE; i++) {
+ pStart[i] = process_pfx_in_order(pStart[i], NULL);
+ }
+ return 0;
+}
+
+PfxEntry* AffixMgr::process_pfx_in_order(PfxEntry* ptr, PfxEntry* nptr) {
+ if (ptr) {
+ nptr = process_pfx_in_order(ptr->getNextNE(), nptr);
+ ptr->setNext(nptr);
+ nptr = process_pfx_in_order(ptr->getNextEQ(), ptr);
+ }
+ return nptr;
+}
+
+// convert from binary tree to sorted list
+int AffixMgr::process_sfx_tree_to_list() {
+ for (int i = 1; i < SETSIZE; i++) {
+ sStart[i] = process_sfx_in_order(sStart[i], NULL);
+ }
+ return 0;
+}
+
+SfxEntry* AffixMgr::process_sfx_in_order(SfxEntry* ptr, SfxEntry* nptr) {
+ if (ptr) {
+ nptr = process_sfx_in_order(ptr->getNextNE(), nptr);
+ ptr->setNext(nptr);
+ nptr = process_sfx_in_order(ptr->getNextEQ(), ptr);
+ }
+ return nptr;
+}
+
+// reinitialize the PfxEntry links NextEQ and NextNE to speed searching
+// using the idea of leading subsets this time
+int AffixMgr::process_pfx_order() {
+ PfxEntry* ptr;
+
+ // loop through each prefix list starting point
+ for (int i = 1; i < SETSIZE; i++) {
+ ptr = pStart[i];
+
+ // look through the remainder of the list
+ // and find next entry with affix that
+ // the current one is not a subset of
+ // mark that as destination for NextNE
+ // use next in list that you are a subset
+ // of as NextEQ
+
+ for (; ptr != NULL; ptr = ptr->getNext()) {
+ PfxEntry* nptr = ptr->getNext();
+ for (; nptr != NULL; nptr = nptr->getNext()) {
+ if (!isSubset(ptr->getKey(), nptr->getKey()))
+ break;
+ }
+ ptr->setNextNE(nptr);
+ ptr->setNextEQ(NULL);
+ if ((ptr->getNext()) &&
+ isSubset(ptr->getKey(), (ptr->getNext())->getKey()))
+ ptr->setNextEQ(ptr->getNext());
+ }
+
+ // now clean up by adding smart search termination strings:
+ // if you are already a superset of the previous prefix
+ // but not a subset of the next, search can end here
+ // so set NextNE properly
+
+ ptr = pStart[i];
+ for (; ptr != NULL; ptr = ptr->getNext()) {
+ PfxEntry* nptr = ptr->getNext();
+ PfxEntry* mptr = NULL;
+ for (; nptr != NULL; nptr = nptr->getNext()) {
+ if (!isSubset(ptr->getKey(), nptr->getKey()))
+ break;
+ mptr = nptr;
+ }
+ if (mptr)
+ mptr->setNextNE(NULL);
+ }
+ }
+ return 0;
+}
+
+// initialize the SfxEntry links NextEQ and NextNE to speed searching
+// using the idea of leading subsets this time
+int AffixMgr::process_sfx_order() {
+ SfxEntry* ptr;
+
+ // loop through each prefix list starting point
+ for (int i = 1; i < SETSIZE; i++) {
+ ptr = sStart[i];
+
+ // look through the remainder of the list
+ // and find next entry with affix that
+ // the current one is not a subset of
+ // mark that as destination for NextNE
+ // use next in list that you are a subset
+ // of as NextEQ
+
+ for (; ptr != NULL; ptr = ptr->getNext()) {
+ SfxEntry* nptr = ptr->getNext();
+ for (; nptr != NULL; nptr = nptr->getNext()) {
+ if (!isSubset(ptr->getKey(), nptr->getKey()))
+ break;
+ }
+ ptr->setNextNE(nptr);
+ ptr->setNextEQ(NULL);
+ if ((ptr->getNext()) &&
+ isSubset(ptr->getKey(), (ptr->getNext())->getKey()))
+ ptr->setNextEQ(ptr->getNext());
+ }
+
+ // now clean up by adding smart search termination strings:
+ // if you are already a superset of the previous suffix
+ // but not a subset of the next, search can end here
+ // so set NextNE properly
+
+ ptr = sStart[i];
+ for (; ptr != NULL; ptr = ptr->getNext()) {
+ SfxEntry* nptr = ptr->getNext();
+ SfxEntry* mptr = NULL;
+ for (; nptr != NULL; nptr = nptr->getNext()) {
+ if (!isSubset(ptr->getKey(), nptr->getKey()))
+ break;
+ mptr = nptr;
+ }
+ if (mptr)
+ mptr->setNextNE(NULL);
+ }
+ }
+ return 0;
+}
+
+// add flags to the result for dictionary debugging
+std::string& AffixMgr::debugflag(std::string& result, unsigned short flag) {
+ char* st = encode_flag(flag);
+ result.push_back(MSEP_FLD);
+ result.append(MORPH_FLAG);
+ if (st) {
+ result.append(st);
+ free(st);
+ }
+ return result;
+}
+
+// calculate the character length of the condition
+int AffixMgr::condlen(const char* st) {
+ int l = 0;
+ bool group = false;
+ for (; *st; st++) {
+ if (*st == '[') {
+ group = true;
+ l++;
+ } else if (*st == ']')
+ group = false;
+ else if (!group && (!utf8 || (!(*st & 0x80) || ((*st & 0xc0) == 0x80))))
+ l++;
+ }
+ return l;
+}
+
+int AffixMgr::encodeit(AffEntry& entry, const char* cs) {
+ if (strcmp(cs, ".") != 0) {
+ entry.numconds = (char)condlen(cs);
+ const size_t cslen = strlen(cs);
+ const size_t short_part = std::min<size_t>(MAXCONDLEN, cslen);
+ memcpy(entry.c.conds, cs, short_part);
+ if (short_part < MAXCONDLEN) {
+ //blank out the remaining space
+ memset(entry.c.conds + short_part, 0, MAXCONDLEN - short_part);
+ } else if (cs[MAXCONDLEN]) {
+ //there is more conditions than fit in fixed space, so its
+ //a long condition
+ entry.opts |= aeLONGCOND;
+ entry.c.l.conds2 = mystrdup(cs + MAXCONDLEN_1);
+ if (!entry.c.l.conds2)
+ return 1;
+ }
+ } else {
+ entry.numconds = 0;
+ entry.c.conds[0] = '\0';
+ }
+ return 0;
+}
+
+// return 1 if s1 is a leading subset of s2 (dots are for infixes)
+inline int AffixMgr::isSubset(const char* s1, const char* s2) {
+ while (((*s1 == *s2) || (*s1 == '.')) && (*s1 != '\0')) {
+ s1++;
+ s2++;
+ }
+ return (*s1 == '\0');
+}
+
+// check word for prefixes
+struct hentry* AffixMgr::prefix_check(const char* word,
+ int len,
+ char in_compound,
+ const FLAG needflag) {
+ struct hentry* rv = NULL;
+
+ pfx = NULL;
+ pfxappnd = NULL;
+ sfxappnd = NULL;
+ sfxextra = 0;
+
+ // first handle the special case of 0 length prefixes
+ PfxEntry* pe = pStart[0];
+ while (pe) {
+ if (
+ // fogemorpheme
+ ((in_compound != IN_CPD_NOT) ||
+ !(pe->getCont() &&
+ (TESTAFF(pe->getCont(), onlyincompound, pe->getContLen())))) &&
+ // permit prefixes in compounds
+ ((in_compound != IN_CPD_END) ||
+ (pe->getCont() &&
+ (TESTAFF(pe->getCont(), compoundpermitflag, pe->getContLen()))))) {
+ // check prefix
+ rv = pe->checkword(word, len, in_compound, needflag);
+ if (rv) {
+ pfx = pe; // BUG: pfx not stateless
+ return rv;
+ }
+ }
+ pe = pe->getNext();
+ }
+
+ // now handle the general case
+ unsigned char sp = *((const unsigned char*)word);
+ PfxEntry* pptr = pStart[sp];
+
+ while (pptr) {
+ if (isSubset(pptr->getKey(), word)) {
+ if (
+ // fogemorpheme
+ ((in_compound != IN_CPD_NOT) ||
+ !(pptr->getCont() &&
+ (TESTAFF(pptr->getCont(), onlyincompound, pptr->getContLen())))) &&
+ // permit prefixes in compounds
+ ((in_compound != IN_CPD_END) ||
+ (pptr->getCont() && (TESTAFF(pptr->getCont(), compoundpermitflag,
+ pptr->getContLen()))))) {
+ // check prefix
+ rv = pptr->checkword(word, len, in_compound, needflag);
+ if (rv) {
+ pfx = pptr; // BUG: pfx not stateless
+ return rv;
+ }
+ }
+ pptr = pptr->getNextEQ();
+ } else {
+ pptr = pptr->getNextNE();
+ }
+ }
+
+ return NULL;
+}
+
+// check word for prefixes and two-level suffixes
+struct hentry* AffixMgr::prefix_check_twosfx(const char* word,
+ int len,
+ char in_compound,
+ const FLAG needflag) {
+ struct hentry* rv = NULL;
+
+ pfx = NULL;
+ sfxappnd = NULL;
+ sfxextra = 0;
+
+ // first handle the special case of 0 length prefixes
+ PfxEntry* pe = pStart[0];
+
+ while (pe) {
+ rv = pe->check_twosfx(word, len, in_compound, needflag);
+ if (rv)
+ return rv;
+ pe = pe->getNext();
+ }
+
+ // now handle the general case
+ unsigned char sp = *((const unsigned char*)word);
+ PfxEntry* pptr = pStart[sp];
+
+ while (pptr) {
+ if (isSubset(pptr->getKey(), word)) {
+ rv = pptr->check_twosfx(word, len, in_compound, needflag);
+ if (rv) {
+ pfx = pptr;
+ return rv;
+ }
+ pptr = pptr->getNextEQ();
+ } else {
+ pptr = pptr->getNextNE();
+ }
+ }
+
+ return NULL;
+}
+
+// check word for prefixes and morph
+std::string AffixMgr::prefix_check_morph(const char* word,
+ int len,
+ char in_compound,
+ const FLAG needflag) {
+
+ std::string result;
+
+ pfx = NULL;
+ sfxappnd = NULL;
+ sfxextra = 0;
+
+ // first handle the special case of 0 length prefixes
+ PfxEntry* pe = pStart[0];
+ while (pe) {
+ std::string st = pe->check_morph(word, len, in_compound, needflag);
+ if (!st.empty()) {
+ result.append(st);
+ }
+ pe = pe->getNext();
+ }
+
+ // now handle the general case
+ unsigned char sp = *((const unsigned char*)word);
+ PfxEntry* pptr = pStart[sp];
+
+ while (pptr) {
+ if (isSubset(pptr->getKey(), word)) {
+ std::string st = pptr->check_morph(word, len, in_compound, needflag);
+ if (!st.empty()) {
+ // fogemorpheme
+ if ((in_compound != IN_CPD_NOT) ||
+ !((pptr->getCont() && (TESTAFF(pptr->getCont(), onlyincompound,
+ pptr->getContLen()))))) {
+ result.append(st);
+ pfx = pptr;
+ }
+ }
+ pptr = pptr->getNextEQ();
+ } else {
+ pptr = pptr->getNextNE();
+ }
+ }
+
+ return result;
+}
+
+// check word for prefixes and morph and two-level suffixes
+std::string AffixMgr::prefix_check_twosfx_morph(const char* word,
+ int len,
+ char in_compound,
+ const FLAG needflag) {
+ std::string result;
+
+ pfx = NULL;
+ sfxappnd = NULL;
+ sfxextra = 0;
+
+ // first handle the special case of 0 length prefixes
+ PfxEntry* pe = pStart[0];
+ while (pe) {
+ std::string st = pe->check_twosfx_morph(word, len, in_compound, needflag);
+ if (!st.empty()) {
+ result.append(st);
+ }
+ pe = pe->getNext();
+ }
+
+ // now handle the general case
+ unsigned char sp = *((const unsigned char*)word);
+ PfxEntry* pptr = pStart[sp];
+
+ while (pptr) {
+ if (isSubset(pptr->getKey(), word)) {
+ std::string st = pptr->check_twosfx_morph(word, len, in_compound, needflag);
+ if (!st.empty()) {
+ result.append(st);
+ pfx = pptr;
+ }
+ pptr = pptr->getNextEQ();
+ } else {
+ pptr = pptr->getNextNE();
+ }
+ }
+
+ return result;
+}
+
+// Is word a non-compound with a REP substitution (see checkcompoundrep)?
+int AffixMgr::cpdrep_check(const char* word, int wl) {
+
+ if ((wl < 2) || get_reptable().empty())
+ return 0;
+
+ for (size_t i = 0; i < get_reptable().size(); ++i) {
+ // use only available mid patterns
+ if (!get_reptable()[i].outstrings[0].empty()) {
+ const char* r = word;
+ const size_t lenp = get_reptable()[i].pattern.size();
+ // search every occurence of the pattern in the word
+ while ((r = strstr(r, get_reptable()[i].pattern.c_str())) != NULL) {
+ std::string candidate(word);
+ candidate.replace(r - word, lenp, get_reptable()[i].outstrings[0]);
+ if (candidate_check(candidate.c_str(), candidate.size()))
+ return 1;
+ ++r; // search for the next letter
+ }
+ }
+ }
+
+ return 0;
+}
+
+// forbid compound words, if they are in the dictionary as a
+// word pair separated by space
+int AffixMgr::cpdwordpair_check(const char * word, int wl) {
+ if (wl > 2) {
+ std::string candidate(word);
+ for (size_t i = 1; i < candidate.size(); i++) {
+ // go to end of the UTF-8 character
+ if (utf8 && ((word[i] & 0xc0) == 0x80))
+ continue;
+ candidate.insert(i, 1, ' ');
+ if (candidate_check(candidate.c_str(), candidate.size()))
+ return 1;
+ candidate.erase(i, 1);
+ }
+ }
+
+ return 0;
+}
+
+// forbid compoundings when there are special patterns at word bound
+int AffixMgr::cpdpat_check(const char* word,
+ int pos,
+ hentry* r1,
+ hentry* r2,
+ const char /*affixed*/) {
+ for (size_t i = 0; i < checkcpdtable.size(); ++i) {
+ size_t len;
+ if (isSubset(checkcpdtable[i].pattern2.c_str(), word + pos) &&
+ (!r1 || !checkcpdtable[i].cond ||
+ (r1->astr && TESTAFF(r1->astr, checkcpdtable[i].cond, r1->alen))) &&
+ (!r2 || !checkcpdtable[i].cond2 ||
+ (r2->astr && TESTAFF(r2->astr, checkcpdtable[i].cond2, r2->alen))) &&
+ // zero length pattern => only TESTAFF
+ // zero pattern (0/flag) => unmodified stem (zero affixes allowed)
+ (checkcpdtable[i].pattern.empty() ||
+ ((checkcpdtable[i].pattern[0] == '0' && r1->blen <= pos &&
+ strncmp(word + pos - r1->blen, r1->word, r1->blen) == 0) ||
+ (checkcpdtable[i].pattern[0] != '0' &&
+ ((len = checkcpdtable[i].pattern.size()) != 0) &&
+ strncmp(word + pos - len, checkcpdtable[i].pattern.c_str(), len) == 0)))) {
+ return 1;
+ }
+ }
+ return 0;
+}
+
+// forbid compounding with neighbouring upper and lower case characters at word
+// bounds
+int AffixMgr::cpdcase_check(const char* word, int pos) {
+ if (utf8) {
+ const char* p;
+ for (p = word + pos - 1; (*p & 0xc0) == 0x80; p--)
+ ;
+ std::string pair(p);
+ std::vector<w_char> pair_u;
+ u8_u16(pair_u, pair);
+ unsigned short a = pair_u.size() > 1 ? ((pair_u[1].h << 8) + pair_u[1].l) : 0;
+ unsigned short b = !pair_u.empty() ? ((pair_u[0].h << 8) + pair_u[0].l) : 0;
+ if (((unicodetoupper(a, langnum) == a) ||
+ (unicodetoupper(b, langnum) == b)) &&
+ (a != '-') && (b != '-'))
+ return 1;
+ } else {
+ unsigned char a = *(word + pos - 1);
+ unsigned char b = *(word + pos);
+ if ((csconv[a].ccase || csconv[b].ccase) && (a != '-') && (b != '-'))
+ return 1;
+ }
+ return 0;
+}
+
+struct metachar_data {
+ signed short btpp; // metacharacter (*, ?) position for backtracking
+ signed short btwp; // word position for metacharacters
+ int btnum; // number of matched characters in metacharacter
+};
+
+// check compound patterns
+int AffixMgr::defcpd_check(hentry*** words,
+ short wnum,
+ hentry* rv,
+ hentry** def,
+ char all) {
+ int w = 0;
+
+ if (!*words) {
+ w = 1;
+ *words = def;
+ }
+
+ if (!*words) {
+ return 0;
+ }
+
+ std::vector<metachar_data> btinfo(1);
+
+ short bt = 0;
+
+ (*words)[wnum] = rv;
+
+ // has the last word COMPOUNDRULE flag?
+ if (rv->alen == 0) {
+ (*words)[wnum] = NULL;
+ if (w)
+ *words = NULL;
+ return 0;
+ }
+ int ok = 0;
+ for (size_t i = 0; i < defcpdtable.size(); ++i) {
+ for (size_t j = 0; j < defcpdtable[i].size(); ++j) {
+ if (defcpdtable[i][j] != '*' && defcpdtable[i][j] != '?' &&
+ TESTAFF(rv->astr, defcpdtable[i][j], rv->alen)) {
+ ok = 1;
+ break;
+ }
+ }
+ }
+ if (ok == 0) {
+ (*words)[wnum] = NULL;
+ if (w)
+ *words = NULL;
+ return 0;
+ }
+
+ for (size_t i = 0; i < defcpdtable.size(); ++i) {
+ size_t pp = 0; // pattern position
+ signed short wp = 0; // "words" position
+ int ok2;
+ ok = 1;
+ ok2 = 1;
+ do {
+ while ((pp < defcpdtable[i].size()) && (wp <= wnum)) {
+ if (((pp + 1) < defcpdtable[i].size()) &&
+ ((defcpdtable[i][pp + 1] == '*') ||
+ (defcpdtable[i][pp + 1] == '?'))) {
+ int wend = (defcpdtable[i][pp + 1] == '?') ? wp : wnum;
+ ok2 = 1;
+ pp += 2;
+ btinfo[bt].btpp = pp;
+ btinfo[bt].btwp = wp;
+ while (wp <= wend) {
+ if (!(*words)[wp]->alen ||
+ !TESTAFF((*words)[wp]->astr, defcpdtable[i][pp - 2],
+ (*words)[wp]->alen)) {
+ ok2 = 0;
+ break;
+ }
+ wp++;
+ }
+ if (wp <= wnum)
+ ok2 = 0;
+ btinfo[bt].btnum = wp - btinfo[bt].btwp;
+ if (btinfo[bt].btnum > 0) {
+ ++bt;
+ btinfo.resize(bt+1);
+ }
+ if (ok2)
+ break;
+ } else {
+ ok2 = 1;
+ if (!(*words)[wp] || !(*words)[wp]->alen ||
+ !TESTAFF((*words)[wp]->astr, defcpdtable[i][pp],
+ (*words)[wp]->alen)) {
+ ok = 0;
+ break;
+ }
+ pp++;
+ wp++;
+ if ((defcpdtable[i].size() == pp) && !(wp > wnum))
+ ok = 0;
+ }
+ }
+ if (ok && ok2) {
+ size_t r = pp;
+ while ((defcpdtable[i].size() > r) && ((r + 1) < defcpdtable[i].size()) &&
+ ((defcpdtable[i][r + 1] == '*') ||
+ (defcpdtable[i][r + 1] == '?')))
+ r += 2;
+ if (defcpdtable[i].size() <= r)
+ return 1;
+ }
+ // backtrack
+ if (bt)
+ do {
+ ok = 1;
+ btinfo[bt - 1].btnum--;
+ pp = btinfo[bt - 1].btpp;
+ wp = btinfo[bt - 1].btwp + (signed short)btinfo[bt - 1].btnum;
+ } while ((btinfo[bt - 1].btnum < 0) && --bt);
+ } while (bt);
+
+ if (ok && ok2 && (!all || (defcpdtable[i].size() <= pp)))
+ return 1;
+
+ // check zero ending
+ while (ok && ok2 && (defcpdtable[i].size() > pp) &&
+ ((pp + 1) < defcpdtable[i].size()) &&
+ ((defcpdtable[i][pp + 1] == '*') ||
+ (defcpdtable[i][pp + 1] == '?')))
+ pp += 2;
+ if (ok && ok2 && (defcpdtable[i].size() <= pp))
+ return 1;
+ }
+ (*words)[wnum] = NULL;
+ if (w)
+ *words = NULL;
+ return 0;
+}
+
+inline int AffixMgr::candidate_check(const char* word, int len) {
+
+ struct hentry* rv = lookup(word);
+ if (rv)
+ return 1;
+
+ // rv = prefix_check(word,len,1);
+ // if (rv) return 1;
+
+ rv = affix_check(word, len);
+ if (rv)
+ return 1;
+ return 0;
+}
+
+// calculate number of syllable for compound-checking
+short AffixMgr::get_syllable(const std::string& word) {
+ if (cpdmaxsyllable == 0)
+ return 0;
+
+ short num = 0;
+
+ if (!utf8) {
+ for (size_t i = 0; i < word.size(); ++i) {
+ if (std::binary_search(cpdvowels.begin(), cpdvowels.end(),
+ word[i])) {
+ ++num;
+ }
+ }
+ } else if (!cpdvowels_utf16.empty()) {
+ std::vector<w_char> w;
+ u8_u16(w, word);
+ for (size_t i = 0; i < w.size(); ++i) {
+ if (std::binary_search(cpdvowels_utf16.begin(),
+ cpdvowels_utf16.end(),
+ w[i])) {
+ ++num;
+ }
+ }
+ }
+
+ return num;
+}
+
+void AffixMgr::setcminmax(int* cmin, int* cmax, const char* word, int len) {
+ if (utf8) {
+ int i;
+ for (*cmin = 0, i = 0; (i < cpdmin) && *cmin < len; i++) {
+ for ((*cmin)++; *cmin < len && (word[*cmin] & 0xc0) == 0x80; (*cmin)++)
+ ;
+ }
+ for (*cmax = len, i = 0; (i < (cpdmin - 1)) && *cmax >= 0; i++) {
+ for ((*cmax)--; *cmax >= 0 && (word[*cmax] & 0xc0) == 0x80; (*cmax)--)
+ ;
+ }
+ } else {
+ *cmin = cpdmin;
+ *cmax = len - cpdmin + 1;
+ }
+}
+
+// check if compound word is correctly spelled
+// hu_mov_rule = spec. Hungarian rule (XXX)
+struct hentry* AffixMgr::compound_check(const std::string& word,
+ short wordnum,
+ short numsyllable,
+ short maxwordnum,
+ short wnum,
+ hentry** words = NULL,
+ hentry** rwords = NULL,
+ char hu_mov_rule = 0,
+ char is_sug = 0,
+ int* info = NULL) {
+ int i;
+ short oldnumsyllable, oldnumsyllable2, oldwordnum, oldwordnum2;
+ struct hentry* rv = NULL;
+ struct hentry* rv_first;
+ std::string st;
+ char ch = '\0';
+ int cmin;
+ int cmax;
+ int striple = 0;
+ size_t scpd = 0;
+ int soldi = 0;
+ int oldcmin = 0;
+ int oldcmax = 0;
+ int oldlen = 0;
+ int checkedstriple = 0;
+ char affixed = 0;
+ hentry** oldwords = words;
+ size_t len = word.size();
+
+ int checked_prefix;
+
+ // add a time limit to handle possible
+ // combinatorical explosion of the overlapping words
+
+ HUNSPELL_THREAD_LOCAL clock_t timelimit;
+
+ if (wordnum == 0) {
+ // get the start time, seeing as we're reusing this set to 0
+ // to flag timeout, use clock() + 1 to avoid start clock()
+ // of 0 as being a timeout
+ timelimit = clock() + 1;
+ }
+ else if (timelimit != 0 && (clock() > timelimit + TIMELIMIT)) {
+ timelimit = 0;
+ }
+
+ setcminmax(&cmin, &cmax, word.c_str(), len);
+
+ st.assign(word);
+
+ for (i = cmin; i < cmax; i++) {
+ // go to end of the UTF-8 character
+ if (utf8) {
+ for (; (st[i] & 0xc0) == 0x80; i++)
+ ;
+ if (i >= cmax)
+ return NULL;
+ }
+
+ words = oldwords;
+ int onlycpdrule = (words) ? 1 : 0;
+
+ do { // onlycpdrule loop
+
+ oldnumsyllable = numsyllable;
+ oldwordnum = wordnum;
+ checked_prefix = 0;
+
+ do { // simplified checkcompoundpattern loop
+
+ if (timelimit == 0)
+ return 0;
+
+ if (scpd > 0) {
+ for (; scpd <= checkcpdtable.size() &&
+ (checkcpdtable[scpd - 1].pattern3.empty() ||
+ strncmp(word.c_str() + i, checkcpdtable[scpd - 1].pattern3.c_str(),
+ checkcpdtable[scpd - 1].pattern3.size()) != 0);
+ scpd++)
+ ;
+
+ if (scpd > checkcpdtable.size())
+ break; // break simplified checkcompoundpattern loop
+ st.replace(i, std::string::npos, checkcpdtable[scpd - 1].pattern);
+ soldi = i;
+ i += checkcpdtable[scpd - 1].pattern.size();
+ st.replace(i, std::string::npos, checkcpdtable[scpd - 1].pattern2);
+ st.replace(i + checkcpdtable[scpd - 1].pattern2.size(), std::string::npos,
+ word.substr(soldi + checkcpdtable[scpd - 1].pattern3.size()));
+
+ oldlen = len;
+ len += checkcpdtable[scpd - 1].pattern.size() +
+ checkcpdtable[scpd - 1].pattern2.size() -
+ checkcpdtable[scpd - 1].pattern3.size();
+ oldcmin = cmin;
+ oldcmax = cmax;
+ setcminmax(&cmin, &cmax, st.c_str(), len);
+
+ cmax = len - cpdmin + 1;
+ }
+
+ ch = st[i];
+ st[i] = '\0';
+
+ sfx = NULL;
+ pfx = NULL;
+
+ // FIRST WORD
+
+ affixed = 1;
+ rv = lookup(st.c_str()); // perhaps without prefix
+
+ // forbid dictionary stems with COMPOUNDFORBIDFLAG in
+ // compound words, overriding the effect of COMPOUNDPERMITFLAG
+ if ((rv) && compoundforbidflag &&
+ TESTAFF(rv->astr, compoundforbidflag, rv->alen) && !hu_mov_rule)
+ continue;
+
+ // search homonym with compound flag
+ while ((rv) && !hu_mov_rule &&
+ ((needaffix && TESTAFF(rv->astr, needaffix, rv->alen)) ||
+ !((compoundflag && !words && !onlycpdrule &&
+ TESTAFF(rv->astr, compoundflag, rv->alen)) ||
+ (compoundbegin && !wordnum && !onlycpdrule &&
+ TESTAFF(rv->astr, compoundbegin, rv->alen)) ||
+ (compoundmiddle && wordnum && !words && !onlycpdrule &&
+ TESTAFF(rv->astr, compoundmiddle, rv->alen)) ||
+ (!defcpdtable.empty() && onlycpdrule &&
+ ((!words && !wordnum &&
+ defcpd_check(&words, wnum, rv, rwords, 0)) ||
+ (words &&
+ defcpd_check(&words, wnum, rv, rwords, 0))))) ||
+ (scpd != 0 && checkcpdtable[scpd - 1].cond != FLAG_NULL &&
+ !TESTAFF(rv->astr, checkcpdtable[scpd - 1].cond, rv->alen)))) {
+ rv = rv->next_homonym;
+ }
+
+ if (rv)
+ affixed = 0;
+
+ if (!rv) {
+ if (onlycpdrule)
+ break;
+ if (compoundflag &&
+ !(rv = prefix_check(st.c_str(), i,
+ hu_mov_rule ? IN_CPD_OTHER : IN_CPD_BEGIN,
+ compoundflag))) {
+ if (((rv = suffix_check(
+ st.c_str(), i, 0, NULL, FLAG_NULL, compoundflag,
+ hu_mov_rule ? IN_CPD_OTHER : IN_CPD_BEGIN)) ||
+ (compoundmoresuffixes &&
+ (rv = suffix_check_twosfx(st.c_str(), i, 0, NULL, compoundflag)))) &&
+ !hu_mov_rule && sfx->getCont() &&
+ ((compoundforbidflag &&
+ TESTAFF(sfx->getCont(), compoundforbidflag,
+ sfx->getContLen())) ||
+ (compoundend &&
+ TESTAFF(sfx->getCont(), compoundend, sfx->getContLen())))) {
+ rv = NULL;
+ }
+ }
+
+ if (rv ||
+ (((wordnum == 0) && compoundbegin &&
+ ((rv = suffix_check(
+ st.c_str(), i, 0, NULL, FLAG_NULL, compoundbegin,
+ hu_mov_rule ? IN_CPD_OTHER : IN_CPD_BEGIN)) ||
+ (compoundmoresuffixes &&
+ (rv = suffix_check_twosfx(
+ st.c_str(), i, 0, NULL,
+ compoundbegin))) || // twofold suffixes + compound
+ (rv = prefix_check(st.c_str(), i,
+ hu_mov_rule ? IN_CPD_OTHER : IN_CPD_BEGIN,
+ compoundbegin)))) ||
+ ((wordnum > 0) && compoundmiddle &&
+ ((rv = suffix_check(
+ st.c_str(), i, 0, NULL, FLAG_NULL, compoundmiddle,
+ hu_mov_rule ? IN_CPD_OTHER : IN_CPD_BEGIN)) ||
+ (compoundmoresuffixes &&
+ (rv = suffix_check_twosfx(
+ st.c_str(), i, 0, NULL,
+ compoundmiddle))) || // twofold suffixes + compound
+ (rv = prefix_check(st.c_str(), i,
+ hu_mov_rule ? IN_CPD_OTHER : IN_CPD_BEGIN,
+ compoundmiddle))))))
+ checked_prefix = 1;
+ // else check forbiddenwords and needaffix
+ } else if (rv->astr && (TESTAFF(rv->astr, forbiddenword, rv->alen) ||
+ TESTAFF(rv->astr, needaffix, rv->alen) ||
+ TESTAFF(rv->astr, ONLYUPCASEFLAG, rv->alen) ||
+ (is_sug && nosuggest &&
+ TESTAFF(rv->astr, nosuggest, rv->alen)))) {
+ st[i] = ch;
+ // continue;
+ break;
+ }
+
+ // check non_compound flag in suffix and prefix
+ if ((rv) && !hu_mov_rule &&
+ ((pfx && pfx->getCont() &&
+ TESTAFF(pfx->getCont(), compoundforbidflag, pfx->getContLen())) ||
+ (sfx && sfx->getCont() &&
+ TESTAFF(sfx->getCont(), compoundforbidflag,
+ sfx->getContLen())))) {
+ rv = NULL;
+ }
+
+ // check compoundend flag in suffix and prefix
+ if ((rv) && !checked_prefix && compoundend && !hu_mov_rule &&
+ ((pfx && pfx->getCont() &&
+ TESTAFF(pfx->getCont(), compoundend, pfx->getContLen())) ||
+ (sfx && sfx->getCont() &&
+ TESTAFF(sfx->getCont(), compoundend, sfx->getContLen())))) {
+ rv = NULL;
+ }
+
+ // check compoundmiddle flag in suffix and prefix
+ if ((rv) && !checked_prefix && (wordnum == 0) && compoundmiddle &&
+ !hu_mov_rule &&
+ ((pfx && pfx->getCont() &&
+ TESTAFF(pfx->getCont(), compoundmiddle, pfx->getContLen())) ||
+ (sfx && sfx->getCont() &&
+ TESTAFF(sfx->getCont(), compoundmiddle, sfx->getContLen())))) {
+ rv = NULL;
+ }
+
+ // check forbiddenwords
+ if ((rv) && (rv->astr) &&
+ (TESTAFF(rv->astr, forbiddenword, rv->alen) ||
+ TESTAFF(rv->astr, ONLYUPCASEFLAG, rv->alen) ||
+ (is_sug && nosuggest && TESTAFF(rv->astr, nosuggest, rv->alen)))) {
+ return NULL;
+ }
+
+ // increment word number, if the second root has a compoundroot flag
+ if ((rv) && compoundroot &&
+ (TESTAFF(rv->astr, compoundroot, rv->alen))) {
+ wordnum++;
+ }
+
+ // first word is acceptable in compound words?
+ if (((rv) &&
+ (checked_prefix || (words && words[wnum]) ||
+ (compoundflag && TESTAFF(rv->astr, compoundflag, rv->alen)) ||
+ ((oldwordnum == 0) && compoundbegin &&
+ TESTAFF(rv->astr, compoundbegin, rv->alen)) ||
+ ((oldwordnum > 0) && compoundmiddle &&
+ TESTAFF(rv->astr, compoundmiddle, rv->alen))
+
+ // LANG_hu section: spec. Hungarian rule
+ || ((langnum == LANG_hu) && hu_mov_rule &&
+ (TESTAFF(
+ rv->astr, 'F',
+ rv->alen) || // XXX hardwired Hungarian dictionary codes
+ TESTAFF(rv->astr, 'G', rv->alen) ||
+ TESTAFF(rv->astr, 'H', rv->alen)))
+ // END of LANG_hu section
+ ) &&
+ (
+ // test CHECKCOMPOUNDPATTERN conditions
+ scpd == 0 || checkcpdtable[scpd - 1].cond == FLAG_NULL ||
+ TESTAFF(rv->astr, checkcpdtable[scpd - 1].cond, rv->alen)) &&
+ !((checkcompoundtriple && scpd == 0 &&
+ !words && // test triple letters
+ (word[i - 1] == word[i]) &&
+ (((i > 1) && (word[i - 1] == word[i - 2])) ||
+ ((word[i - 1] == word[i + 1])) // may be word[i+1] == '\0'
+ )) ||
+ (checkcompoundcase && scpd == 0 && !words &&
+ cpdcase_check(word.c_str(), i))))
+ // LANG_hu section: spec. Hungarian rule
+ || ((!rv) && (langnum == LANG_hu) && hu_mov_rule &&
+ (rv = affix_check(st.c_str(), i)) &&
+ (sfx && sfx->getCont() &&
+ ( // XXX hardwired Hungarian dic. codes
+ TESTAFF(sfx->getCont(), (unsigned short)'x',
+ sfx->getContLen()) ||
+ TESTAFF(
+ sfx->getCont(), (unsigned short)'%',
+ sfx->getContLen()))))) { // first word is ok condition
+
+ // LANG_hu section: spec. Hungarian rule
+ if (langnum == LANG_hu) {
+ // calculate syllable number of the word
+ numsyllable += get_syllable(st.substr(0, i));
+ // + 1 word, if syllable number of the prefix > 1 (hungarian
+ // convention)
+ if (pfx && (get_syllable(pfx->getKey()) > 1))
+ wordnum++;
+ }
+ // END of LANG_hu section
+
+ // NEXT WORD(S)
+ rv_first = rv;
+ st[i] = ch;
+
+ do { // striple loop
+
+ // check simplifiedtriple
+ if (simplifiedtriple) {
+ if (striple) {
+ checkedstriple = 1;
+ i--; // check "fahrt" instead of "ahrt" in "Schiffahrt"
+ } else if (i > 2 && word[i - 1] == word[i - 2])
+ striple = 1;
+ }
+
+ rv = lookup(st.c_str() + i); // perhaps without prefix
+
+ // search homonym with compound flag
+ while ((rv) &&
+ ((needaffix && TESTAFF(rv->astr, needaffix, rv->alen)) ||
+ !((compoundflag && !words &&
+ TESTAFF(rv->astr, compoundflag, rv->alen)) ||
+ (compoundend && !words &&
+ TESTAFF(rv->astr, compoundend, rv->alen)) ||
+ (!defcpdtable.empty() && words &&
+ defcpd_check(&words, wnum + 1, rv, NULL, 1))) ||
+ (scpd != 0 && checkcpdtable[scpd - 1].cond2 != FLAG_NULL &&
+ !TESTAFF(rv->astr, checkcpdtable[scpd - 1].cond2,
+ rv->alen)))) {
+ rv = rv->next_homonym;
+ }
+
+ // check FORCEUCASE
+ if (rv && forceucase && (rv) &&
+ (TESTAFF(rv->astr, forceucase, rv->alen)) &&
+ !(info && *info & SPELL_ORIGCAP))
+ rv = NULL;
+
+ if (rv && words && words[wnum + 1])
+ return rv_first;
+
+ oldnumsyllable2 = numsyllable;
+ oldwordnum2 = wordnum;
+
+ // LANG_hu section: spec. Hungarian rule, XXX hardwired dictionary
+ // code
+ if ((rv) && (langnum == LANG_hu) &&
+ (TESTAFF(rv->astr, 'I', rv->alen)) &&
+ !(TESTAFF(rv->astr, 'J', rv->alen))) {
+ numsyllable--;
+ }
+ // END of LANG_hu section
+
+ // increment word number, if the second root has a compoundroot flag
+ if ((rv) && (compoundroot) &&
+ (TESTAFF(rv->astr, compoundroot, rv->alen))) {
+ wordnum++;
+ }
+
+ // check forbiddenwords
+ if ((rv) && (rv->astr) &&
+ (TESTAFF(rv->astr, forbiddenword, rv->alen) ||
+ TESTAFF(rv->astr, ONLYUPCASEFLAG, rv->alen) ||
+ (is_sug && nosuggest &&
+ TESTAFF(rv->astr, nosuggest, rv->alen))))
+ return NULL;
+
+ // second word is acceptable, as a root?
+ // hungarian conventions: compounding is acceptable,
+ // when compound forms consist of 2 words, or if more,
+ // then the syllable number of root words must be 6, or lesser.
+
+ if ((rv) &&
+ ((compoundflag && TESTAFF(rv->astr, compoundflag, rv->alen)) ||
+ (compoundend && TESTAFF(rv->astr, compoundend, rv->alen))) &&
+ (((cpdwordmax == -1) || (wordnum + 1 < cpdwordmax)) ||
+ ((cpdmaxsyllable != 0) &&
+ (numsyllable + get_syllable(std::string(HENTRY_WORD(rv), rv->blen)) <=
+ cpdmaxsyllable))) &&
+ (
+ // test CHECKCOMPOUNDPATTERN
+ checkcpdtable.empty() || scpd != 0 ||
+ !cpdpat_check(word.c_str(), i, rv_first, rv, 0)) &&
+ ((!checkcompounddup || (rv != rv_first)))
+ // test CHECKCOMPOUNDPATTERN conditions
+ &&
+ (scpd == 0 || checkcpdtable[scpd - 1].cond2 == FLAG_NULL ||
+ TESTAFF(rv->astr, checkcpdtable[scpd - 1].cond2, rv->alen))) {
+ // forbid compound word, if it is a non-compound word with typical
+ // fault
+ if ((checkcompoundrep && cpdrep_check(word.c_str(), len)) ||
+ cpdwordpair_check(word.c_str(), len))
+ return NULL;
+ return rv_first;
+ }
+
+ numsyllable = oldnumsyllable2;
+ wordnum = oldwordnum2;
+
+ // perhaps second word has prefix or/and suffix
+ sfx = NULL;
+ sfxflag = FLAG_NULL;
+ rv = (compoundflag && !onlycpdrule)
+ ? affix_check((word.c_str() + i), strlen(word.c_str() + i), compoundflag,
+ IN_CPD_END)
+ : NULL;
+ if (!rv && compoundend && !onlycpdrule) {
+ sfx = NULL;
+ pfx = NULL;
+ rv = affix_check((word.c_str() + i), strlen(word.c_str() + i), compoundend,
+ IN_CPD_END);
+ }
+
+ if (!rv && !defcpdtable.empty() && words) {
+ rv = affix_check((word.c_str() + i), strlen(word.c_str() + i), 0, IN_CPD_END);
+ if (rv && defcpd_check(&words, wnum + 1, rv, NULL, 1))
+ return rv_first;
+ rv = NULL;
+ }
+
+ // test CHECKCOMPOUNDPATTERN conditions (allowed forms)
+ if (rv &&
+ !(scpd == 0 || checkcpdtable[scpd - 1].cond2 == FLAG_NULL ||
+ TESTAFF(rv->astr, checkcpdtable[scpd - 1].cond2, rv->alen)))
+ rv = NULL;
+
+ // test CHECKCOMPOUNDPATTERN conditions (forbidden compounds)
+ if (rv && !checkcpdtable.empty() && scpd == 0 &&
+ cpdpat_check(word.c_str(), i, rv_first, rv, affixed))
+ rv = NULL;
+
+ // check non_compound flag in suffix and prefix
+ if ((rv) && ((pfx && pfx->getCont() &&
+ TESTAFF(pfx->getCont(), compoundforbidflag,
+ pfx->getContLen())) ||
+ (sfx && sfx->getCont() &&
+ TESTAFF(sfx->getCont(), compoundforbidflag,
+ sfx->getContLen())))) {
+ rv = NULL;
+ }
+
+ // check FORCEUCASE
+ if (rv && forceucase && (rv) &&
+ (TESTAFF(rv->astr, forceucase, rv->alen)) &&
+ !(info && *info & SPELL_ORIGCAP))
+ rv = NULL;
+
+ // check forbiddenwords
+ if ((rv) && (rv->astr) &&
+ (TESTAFF(rv->astr, forbiddenword, rv->alen) ||
+ TESTAFF(rv->astr, ONLYUPCASEFLAG, rv->alen) ||
+ (is_sug && nosuggest &&
+ TESTAFF(rv->astr, nosuggest, rv->alen))))
+ return NULL;
+
+ // pfxappnd = prefix of word+i, or NULL
+ // calculate syllable number of prefix.
+ // hungarian convention: when syllable number of prefix is more,
+ // than 1, the prefix+word counts as two words.
+
+ if (langnum == LANG_hu) {
+ // calculate syllable number of the word
+ numsyllable += get_syllable(word.c_str() + i);
+
+ // - affix syllable num.
+ // XXX only second suffix (inflections, not derivations)
+ if (sfxappnd) {
+ std::string tmp(sfxappnd);
+ reverseword(tmp);
+ numsyllable -= short(get_syllable(tmp) + sfxextra);
+ } else {
+ numsyllable -= short(sfxextra);
+ }
+
+ // + 1 word, if syllable number of the prefix > 1 (hungarian
+ // convention)
+ if (pfx && (get_syllable(pfx->getKey()) > 1))
+ wordnum++;
+
+ // increment syllable num, if last word has a SYLLABLENUM flag
+ // and the suffix is beginning `s'
+
+ if (!cpdsyllablenum.empty()) {
+ switch (sfxflag) {
+ case 'c': {
+ numsyllable += 2;
+ break;
+ }
+ case 'J': {
+ numsyllable += 1;
+ break;
+ }
+ case 'I': {
+ if (rv && TESTAFF(rv->astr, 'J', rv->alen))
+ numsyllable += 1;
+ break;
+ }
+ }
+ }
+ }
+
+ // increment word number, if the second word has a compoundroot flag
+ if ((rv) && (compoundroot) &&
+ (TESTAFF(rv->astr, compoundroot, rv->alen))) {
+ wordnum++;
+ }
+ // second word is acceptable, as a word with prefix or/and suffix?
+ // hungarian conventions: compounding is acceptable,
+ // when compound forms consist 2 word, otherwise
+ // the syllable number of root words is 6, or lesser.
+ if ((rv) &&
+ (((cpdwordmax == -1) || (wordnum + 1 < cpdwordmax)) ||
+ ((cpdmaxsyllable != 0) && (numsyllable <= cpdmaxsyllable))) &&
+ ((!checkcompounddup || (rv != rv_first)))) {
+ // forbid compound word, if it is a non-compound word with typical
+ // fault
+ if ((checkcompoundrep && cpdrep_check(word.c_str(), len)) ||
+ cpdwordpair_check(word.c_str(), len))
+ return NULL;
+ return rv_first;
+ }
+
+ numsyllable = oldnumsyllable2;
+ wordnum = oldwordnum2;
+
+ // perhaps second word is a compound word (recursive call)
+ if (wordnum + 2 < maxwordnum) {
+ rv = compound_check(st.substr(i), wordnum + 1,
+ numsyllable, maxwordnum, wnum + 1, words, rwords, 0,
+ is_sug, info);
+
+ if (rv && !checkcpdtable.empty() &&
+ ((scpd == 0 &&
+ cpdpat_check(word.c_str(), i, rv_first, rv, affixed)) ||
+ (scpd != 0 &&
+ !cpdpat_check(word.c_str(), i, rv_first, rv, affixed))))
+ rv = NULL;
+ } else {
+ rv = NULL;
+ }
+ if (rv) {
+ // forbid compound word, if it is a non-compound word with typical
+ // fault, or a dictionary word pair
+
+ if (cpdwordpair_check(word.c_str(), len))
+ return NULL;
+
+ if (checkcompoundrep || forbiddenword) {
+
+ if (checkcompoundrep && cpdrep_check(word.c_str(), len))
+ return NULL;
+
+ // check first part
+ if (strncmp(rv->word, word.c_str() + i, rv->blen) == 0) {
+ char r = st[i + rv->blen];
+ st[i + rv->blen] = '\0';
+
+ if ((checkcompoundrep && cpdrep_check(st.c_str(), i + rv->blen)) ||
+ cpdwordpair_check(st.c_str(), i + rv->blen)) {
+ st[ + i + rv->blen] = r;
+ continue;
+ }
+
+ if (forbiddenword) {
+ struct hentry* rv2 = lookup(word.c_str());
+ if (!rv2)
+ rv2 = affix_check(word.c_str(), len);
+ if (rv2 && rv2->astr &&
+ TESTAFF(rv2->astr, forbiddenword, rv2->alen) &&
+ (strncmp(rv2->word, st.c_str(), i + rv->blen) == 0)) {
+ return NULL;
+ }
+ }
+ st[i + rv->blen] = r;
+ }
+ }
+ return rv_first;
+ }
+ } while (striple && !checkedstriple); // end of striple loop
+
+ if (checkedstriple) {
+ i++;
+ checkedstriple = 0;
+ striple = 0;
+ }
+
+ } // first word is ok condition
+
+ if (soldi != 0) {
+ i = soldi;
+ soldi = 0;
+ len = oldlen;
+ cmin = oldcmin;
+ cmax = oldcmax;
+ }
+ scpd++;
+
+ } while (!onlycpdrule && simplifiedcpd &&
+ scpd <= checkcpdtable.size()); // end of simplifiedcpd loop
+
+ scpd = 0;
+ wordnum = oldwordnum;
+ numsyllable = oldnumsyllable;
+
+ if (soldi != 0) {
+ i = soldi;
+ st.assign(word); // XXX add more optim.
+ soldi = 0;
+ } else
+ st[i] = ch;
+
+ } while (!defcpdtable.empty() && oldwordnum == 0 &&
+ onlycpdrule++ < 1); // end of onlycpd loop
+ }
+
+ return NULL;
+}
+
+// check if compound word is correctly spelled
+// hu_mov_rule = spec. Hungarian rule (XXX)
+int AffixMgr::compound_check_morph(const char* word,
+ int len,
+ short wordnum,
+ short numsyllable,
+ short maxwordnum,
+ short wnum,
+ hentry** words,
+ hentry** rwords,
+ char hu_mov_rule,
+ std::string& result,
+ const std::string* partresult) {
+ int i;
+ short oldnumsyllable, oldnumsyllable2, oldwordnum, oldwordnum2;
+ int ok = 0;
+
+ struct hentry* rv = NULL;
+ struct hentry* rv_first;
+ std::string st;
+ char ch;
+
+ int checked_prefix;
+ std::string presult;
+
+ int cmin;
+ int cmax;
+
+ char affixed = 0;
+ hentry** oldwords = words;
+
+ // add a time limit to handle possible
+ // combinatorical explosion of the overlapping words
+
+ HUNSPELL_THREAD_LOCAL clock_t timelimit;
+
+ if (wordnum == 0) {
+ // get the start time, seeing as we're reusing this set to 0
+ // to flag timeout, use clock() + 1 to avoid start clock()
+ // of 0 as being a timeout
+ timelimit = clock() + 1;
+ }
+ else if (timelimit != 0 && (clock() > timelimit + TIMELIMIT)) {
+ timelimit = 0;
+ }
+
+ setcminmax(&cmin, &cmax, word, len);
+
+ st.assign(word);
+
+ for (i = cmin; i < cmax; i++) {
+ // go to end of the UTF-8 character
+ if (utf8) {
+ for (; (st[i] & 0xc0) == 0x80; i++)
+ ;
+ if (i >= cmax)
+ return 0;
+ }
+
+ words = oldwords;
+ int onlycpdrule = (words) ? 1 : 0;
+
+ do { // onlycpdrule loop
+
+ if (timelimit == 0)
+ return 0;
+
+ oldnumsyllable = numsyllable;
+ oldwordnum = wordnum;
+ checked_prefix = 0;
+
+ ch = st[i];
+ st[i] = '\0';
+ sfx = NULL;
+
+ // FIRST WORD
+
+ affixed = 1;
+
+ presult.clear();
+ if (partresult)
+ presult.append(*partresult);
+
+ rv = lookup(st.c_str()); // perhaps without prefix
+
+ // forbid dictionary stems with COMPOUNDFORBIDFLAG in
+ // compound words, overriding the effect of COMPOUNDPERMITFLAG
+ if ((rv) && compoundforbidflag &&
+ TESTAFF(rv->astr, compoundforbidflag, rv->alen) && !hu_mov_rule)
+ continue;
+
+ // search homonym with compound flag
+ while ((rv) && !hu_mov_rule &&
+ ((needaffix && TESTAFF(rv->astr, needaffix, rv->alen)) ||
+ !((compoundflag && !words && !onlycpdrule &&
+ TESTAFF(rv->astr, compoundflag, rv->alen)) ||
+ (compoundbegin && !wordnum && !onlycpdrule &&
+ TESTAFF(rv->astr, compoundbegin, rv->alen)) ||
+ (compoundmiddle && wordnum && !words && !onlycpdrule &&
+ TESTAFF(rv->astr, compoundmiddle, rv->alen)) ||
+ (!defcpdtable.empty() && onlycpdrule &&
+ ((!words && !wordnum &&
+ defcpd_check(&words, wnum, rv, rwords, 0)) ||
+ (words &&
+ defcpd_check(&words, wnum, rv, rwords, 0))))))) {
+ rv = rv->next_homonym;
+ }
+
+ if (timelimit == 0)
+ return 0;
+
+ if (rv)
+ affixed = 0;
+
+ if (rv) {
+ presult.push_back(MSEP_FLD);
+ presult.append(MORPH_PART);
+ presult.append(st.c_str());
+ if (!HENTRY_FIND(rv, MORPH_STEM)) {
+ presult.push_back(MSEP_FLD);
+ presult.append(MORPH_STEM);
+ presult.append(st.c_str());
+ }
+ if (HENTRY_DATA(rv)) {
+ presult.push_back(MSEP_FLD);
+ presult.append(HENTRY_DATA2(rv));
+ }
+ }
+
+ if (!rv) {
+ if (compoundflag &&
+ !(rv =
+ prefix_check(st.c_str(), i, hu_mov_rule ? IN_CPD_OTHER : IN_CPD_BEGIN,
+ compoundflag))) {
+ if (((rv = suffix_check(st.c_str(), i, 0, NULL, FLAG_NULL,
+ compoundflag,
+ hu_mov_rule ? IN_CPD_OTHER : IN_CPD_BEGIN)) ||
+ (compoundmoresuffixes &&
+ (rv = suffix_check_twosfx(st.c_str(), i, 0, NULL, compoundflag)))) &&
+ !hu_mov_rule && sfx->getCont() &&
+ ((compoundforbidflag &&
+ TESTAFF(sfx->getCont(), compoundforbidflag,
+ sfx->getContLen())) ||
+ (compoundend &&
+ TESTAFF(sfx->getCont(), compoundend, sfx->getContLen())))) {
+ rv = NULL;
+ }
+ }
+
+ if (rv ||
+ (((wordnum == 0) && compoundbegin &&
+ ((rv = suffix_check(st.c_str(), i, 0, NULL, FLAG_NULL,
+ compoundbegin,
+ hu_mov_rule ? IN_CPD_OTHER : IN_CPD_BEGIN)) ||
+ (compoundmoresuffixes &&
+ (rv = suffix_check_twosfx(
+ st.c_str(), i, 0, NULL,
+ compoundbegin))) || // twofold suffix+compound
+ (rv = prefix_check(st.c_str(), i,
+ hu_mov_rule ? IN_CPD_OTHER : IN_CPD_BEGIN,
+ compoundbegin)))) ||
+ ((wordnum > 0) && compoundmiddle &&
+ ((rv = suffix_check(st.c_str(), i, 0, NULL, FLAG_NULL,
+ compoundmiddle,
+ hu_mov_rule ? IN_CPD_OTHER : IN_CPD_BEGIN)) ||
+ (compoundmoresuffixes &&
+ (rv = suffix_check_twosfx(
+ st.c_str(), i, 0, NULL,
+ compoundmiddle))) || // twofold suffix+compound
+ (rv = prefix_check(st.c_str(), i,
+ hu_mov_rule ? IN_CPD_OTHER : IN_CPD_BEGIN,
+ compoundmiddle)))))) {
+ std::string p;
+ if (compoundflag)
+ p = affix_check_morph(st.c_str(), i, compoundflag);
+ if (p.empty()) {
+ if ((wordnum == 0) && compoundbegin) {
+ p = affix_check_morph(st.c_str(), i, compoundbegin);
+ } else if ((wordnum > 0) && compoundmiddle) {
+ p = affix_check_morph(st.c_str(), i, compoundmiddle);
+ }
+ }
+ if (!p.empty()) {
+ presult.push_back(MSEP_FLD);
+ presult.append(MORPH_PART);
+ presult.append(st.c_str());
+ line_uniq_app(p, MSEP_REC);
+ presult.append(p);
+ }
+ checked_prefix = 1;
+ }
+ // else check forbiddenwords
+ } else if (rv->astr && (TESTAFF(rv->astr, forbiddenword, rv->alen) ||
+ TESTAFF(rv->astr, ONLYUPCASEFLAG, rv->alen) ||
+ TESTAFF(rv->astr, needaffix, rv->alen))) {
+ st[i] = ch;
+ continue;
+ }
+
+ // check non_compound flag in suffix and prefix
+ if ((rv) && !hu_mov_rule &&
+ ((pfx && pfx->getCont() &&
+ TESTAFF(pfx->getCont(), compoundforbidflag, pfx->getContLen())) ||
+ (sfx && sfx->getCont() &&
+ TESTAFF(sfx->getCont(), compoundforbidflag, sfx->getContLen())))) {
+ continue;
+ }
+
+ // check compoundend flag in suffix and prefix
+ if ((rv) && !checked_prefix && compoundend && !hu_mov_rule &&
+ ((pfx && pfx->getCont() &&
+ TESTAFF(pfx->getCont(), compoundend, pfx->getContLen())) ||
+ (sfx && sfx->getCont() &&
+ TESTAFF(sfx->getCont(), compoundend, sfx->getContLen())))) {
+ continue;
+ }
+
+ // check compoundmiddle flag in suffix and prefix
+ if ((rv) && !checked_prefix && (wordnum == 0) && compoundmiddle &&
+ !hu_mov_rule &&
+ ((pfx && pfx->getCont() &&
+ TESTAFF(pfx->getCont(), compoundmiddle, pfx->getContLen())) ||
+ (sfx && sfx->getCont() &&
+ TESTAFF(sfx->getCont(), compoundmiddle, sfx->getContLen())))) {
+ rv = NULL;
+ }
+
+ // check forbiddenwords
+ if ((rv) && (rv->astr) && (TESTAFF(rv->astr, forbiddenword, rv->alen) ||
+ TESTAFF(rv->astr, ONLYUPCASEFLAG, rv->alen)))
+ continue;
+
+ // increment word number, if the second root has a compoundroot flag
+ if ((rv) && (compoundroot) &&
+ (TESTAFF(rv->astr, compoundroot, rv->alen))) {
+ wordnum++;
+ }
+
+ // first word is acceptable in compound words?
+ if (((rv) &&
+ (checked_prefix || (words && words[wnum]) ||
+ (compoundflag && TESTAFF(rv->astr, compoundflag, rv->alen)) ||
+ ((oldwordnum == 0) && compoundbegin &&
+ TESTAFF(rv->astr, compoundbegin, rv->alen)) ||
+ ((oldwordnum > 0) && compoundmiddle &&
+ TESTAFF(rv->astr, compoundmiddle, rv->alen))
+ // LANG_hu section: spec. Hungarian rule
+ || ((langnum == LANG_hu) && // hu_mov_rule
+ hu_mov_rule && (TESTAFF(rv->astr, 'F', rv->alen) ||
+ TESTAFF(rv->astr, 'G', rv->alen) ||
+ TESTAFF(rv->astr, 'H', rv->alen)))
+ // END of LANG_hu section
+ ) &&
+ !((checkcompoundtriple && !words && // test triple letters
+ (word[i - 1] == word[i]) &&
+ (((i > 1) && (word[i - 1] == word[i - 2])) ||
+ ((word[i - 1] == word[i + 1])) // may be word[i+1] == '\0'
+ )) ||
+ (
+ // test CHECKCOMPOUNDPATTERN
+ !checkcpdtable.empty() && !words &&
+ cpdpat_check(word, i, rv, NULL, affixed)) ||
+ (checkcompoundcase && !words && cpdcase_check(word, i))))
+ // LANG_hu section: spec. Hungarian rule
+ ||
+ ((!rv) && (langnum == LANG_hu) && hu_mov_rule &&
+ (rv = affix_check(st.c_str(), i)) &&
+ (sfx && sfx->getCont() &&
+ (TESTAFF(sfx->getCont(), (unsigned short)'x', sfx->getContLen()) ||
+ TESTAFF(sfx->getCont(), (unsigned short)'%', sfx->getContLen()))))
+ // END of LANG_hu section
+ ) {
+ // LANG_hu section: spec. Hungarian rule
+ if (langnum == LANG_hu) {
+ // calculate syllable number of the word
+ numsyllable += get_syllable(st.substr(0, i));
+
+ // + 1 word, if syllable number of the prefix > 1 (hungarian
+ // convention)
+ if (pfx && (get_syllable(pfx->getKey()) > 1))
+ wordnum++;
+ }
+ // END of LANG_hu section
+
+ // NEXT WORD(S)
+ rv_first = rv;
+ rv = lookup((word + i)); // perhaps without prefix
+
+ // search homonym with compound flag
+ while ((rv) && ((needaffix && TESTAFF(rv->astr, needaffix, rv->alen)) ||
+ !((compoundflag && !words &&
+ TESTAFF(rv->astr, compoundflag, rv->alen)) ||
+ (compoundend && !words &&
+ TESTAFF(rv->astr, compoundend, rv->alen)) ||
+ (!defcpdtable.empty() && words &&
+ defcpd_check(&words, wnum + 1, rv, NULL, 1))))) {
+ rv = rv->next_homonym;
+ }
+
+ if (rv && words && words[wnum + 1]) {
+ result.append(presult);
+ result.push_back(MSEP_FLD);
+ result.append(MORPH_PART);
+ result.append(word + i);
+ if (complexprefixes && HENTRY_DATA(rv))
+ result.append(HENTRY_DATA2(rv));
+ if (!HENTRY_FIND(rv, MORPH_STEM)) {
+ result.push_back(MSEP_FLD);
+ result.append(MORPH_STEM);
+ result.append(HENTRY_WORD(rv));
+ }
+ // store the pointer of the hash entry
+ if (!complexprefixes && HENTRY_DATA(rv)) {
+ result.push_back(MSEP_FLD);
+ result.append(HENTRY_DATA2(rv));
+ }
+ result.push_back(MSEP_REC);
+ return 0;
+ }
+
+ oldnumsyllable2 = numsyllable;
+ oldwordnum2 = wordnum;
+
+ // LANG_hu section: spec. Hungarian rule
+ if ((rv) && (langnum == LANG_hu) &&
+ (TESTAFF(rv->astr, 'I', rv->alen)) &&
+ !(TESTAFF(rv->astr, 'J', rv->alen))) {
+ numsyllable--;
+ }
+ // END of LANG_hu section
+ // increment word number, if the second root has a compoundroot flag
+ if ((rv) && (compoundroot) &&
+ (TESTAFF(rv->astr, compoundroot, rv->alen))) {
+ wordnum++;
+ }
+
+ // check forbiddenwords
+ if ((rv) && (rv->astr) &&
+ (TESTAFF(rv->astr, forbiddenword, rv->alen) ||
+ TESTAFF(rv->astr, ONLYUPCASEFLAG, rv->alen))) {
+ st[i] = ch;
+ continue;
+ }
+
+ // second word is acceptable, as a root?
+ // hungarian conventions: compounding is acceptable,
+ // when compound forms consist of 2 words, or if more,
+ // then the syllable number of root words must be 6, or lesser.
+ if ((rv) &&
+ ((compoundflag && TESTAFF(rv->astr, compoundflag, rv->alen)) ||
+ (compoundend && TESTAFF(rv->astr, compoundend, rv->alen))) &&
+ (((cpdwordmax == -1) || (wordnum + 1 < cpdwordmax)) ||
+ ((cpdmaxsyllable != 0) &&
+ (numsyllable + get_syllable(std::string(HENTRY_WORD(rv), rv->blen)) <=
+ cpdmaxsyllable))) &&
+ ((!checkcompounddup || (rv != rv_first)))) {
+ // bad compound word
+ result.append(presult);
+ result.push_back(MSEP_FLD);
+ result.append(MORPH_PART);
+ result.append(word + i);
+
+ if (HENTRY_DATA(rv)) {
+ if (complexprefixes)
+ result.append(HENTRY_DATA2(rv));
+ if (!HENTRY_FIND(rv, MORPH_STEM)) {
+ result.push_back(MSEP_FLD);
+ result.append(MORPH_STEM);
+ result.append(HENTRY_WORD(rv));
+ }
+ // store the pointer of the hash entry
+ if (!complexprefixes) {
+ result.push_back(MSEP_FLD);
+ result.append(HENTRY_DATA2(rv));
+ }
+ }
+ result.push_back(MSEP_REC);
+ ok = 1;
+ }
+
+ numsyllable = oldnumsyllable2;
+ wordnum = oldwordnum2;
+
+ // perhaps second word has prefix or/and suffix
+ sfx = NULL;
+ sfxflag = FLAG_NULL;
+
+ if (compoundflag && !onlycpdrule)
+ rv = affix_check((word + i), strlen(word + i), compoundflag);
+ else
+ rv = NULL;
+
+ if (!rv && compoundend && !onlycpdrule) {
+ sfx = NULL;
+ pfx = NULL;
+ rv = affix_check((word + i), strlen(word + i), compoundend);
+ }
+
+ if (!rv && !defcpdtable.empty() && words) {
+ rv = affix_check((word + i), strlen(word + i), 0, IN_CPD_END);
+ if (rv && words && defcpd_check(&words, wnum + 1, rv, NULL, 1)) {
+ std::string m;
+ if (compoundflag)
+ m = affix_check_morph((word + i), strlen(word + i), compoundflag);
+ if (m.empty() && compoundend) {
+ m = affix_check_morph((word + i), strlen(word + i), compoundend);
+ }
+ result.append(presult);
+ if (!m.empty()) {
+ result.push_back(MSEP_FLD);
+ result.append(MORPH_PART);
+ result.append(word + i);
+ line_uniq_app(m, MSEP_REC);
+ result.append(m);
+ }
+ result.push_back(MSEP_REC);
+ ok = 1;
+ }
+ }
+
+ // check non_compound flag in suffix and prefix
+ if ((rv) &&
+ ((pfx && pfx->getCont() &&
+ TESTAFF(pfx->getCont(), compoundforbidflag, pfx->getContLen())) ||
+ (sfx && sfx->getCont() &&
+ TESTAFF(sfx->getCont(), compoundforbidflag,
+ sfx->getContLen())))) {
+ rv = NULL;
+ }
+
+ // check forbiddenwords
+ if ((rv) && (rv->astr) &&
+ (TESTAFF(rv->astr, forbiddenword, rv->alen) ||
+ TESTAFF(rv->astr, ONLYUPCASEFLAG, rv->alen)) &&
+ (!TESTAFF(rv->astr, needaffix, rv->alen))) {
+ st[i] = ch;
+ continue;
+ }
+
+ if (langnum == LANG_hu) {
+ // calculate syllable number of the word
+ numsyllable += get_syllable(word + i);
+
+ // - affix syllable num.
+ // XXX only second suffix (inflections, not derivations)
+ if (sfxappnd) {
+ std::string tmp(sfxappnd);
+ reverseword(tmp);
+ numsyllable -= short(get_syllable(tmp) + sfxextra);
+ } else {
+ numsyllable -= short(sfxextra);
+ }
+
+ // + 1 word, if syllable number of the prefix > 1 (hungarian
+ // convention)
+ if (pfx && (get_syllable(pfx->getKey()) > 1))
+ wordnum++;
+
+ // increment syllable num, if last word has a SYLLABLENUM flag
+ // and the suffix is beginning `s'
+
+ if (!cpdsyllablenum.empty()) {
+ switch (sfxflag) {
+ case 'c': {
+ numsyllable += 2;
+ break;
+ }
+ case 'J': {
+ numsyllable += 1;
+ break;
+ }
+ case 'I': {
+ if (rv && TESTAFF(rv->astr, 'J', rv->alen))
+ numsyllable += 1;
+ break;
+ }
+ }
+ }
+ }
+
+ // increment word number, if the second word has a compoundroot flag
+ if ((rv) && (compoundroot) &&
+ (TESTAFF(rv->astr, compoundroot, rv->alen))) {
+ wordnum++;
+ }
+ // second word is acceptable, as a word with prefix or/and suffix?
+ // hungarian conventions: compounding is acceptable,
+ // when compound forms consist 2 word, otherwise
+ // the syllable number of root words is 6, or lesser.
+ if ((rv) &&
+ (((cpdwordmax == -1) || (wordnum + 1 < cpdwordmax)) ||
+ ((cpdmaxsyllable != 0) && (numsyllable <= cpdmaxsyllable))) &&
+ ((!checkcompounddup || (rv != rv_first)))) {
+ std::string m;
+ if (compoundflag)
+ m = affix_check_morph((word + i), strlen(word + i), compoundflag);
+ if (m.empty() && compoundend) {
+ m = affix_check_morph((word + i), strlen(word + i), compoundend);
+ }
+ result.append(presult);
+ if (!m.empty()) {
+ result.push_back(MSEP_FLD);
+ result.append(MORPH_PART);
+ result.append(word + i);
+ line_uniq_app(m, MSEP_REC);
+ result.push_back(MSEP_FLD);
+ result.append(m);
+ }
+ result.push_back(MSEP_REC);
+ ok = 1;
+ }
+
+ numsyllable = oldnumsyllable2;
+ wordnum = oldwordnum2;
+
+ // perhaps second word is a compound word (recursive call)
+ if ((wordnum + 2 < maxwordnum) && (ok == 0)) {
+ compound_check_morph((word + i), strlen(word + i), wordnum + 1,
+ numsyllable, maxwordnum, wnum + 1, words, rwords, 0,
+ result, &presult);
+ } else {
+ rv = NULL;
+ }
+ }
+ st[i] = ch;
+ wordnum = oldwordnum;
+ numsyllable = oldnumsyllable;
+
+ } while (!defcpdtable.empty() && oldwordnum == 0 &&
+ onlycpdrule++ < 1); // end of onlycpd loop
+ }
+ return 0;
+}
+
+
+inline int AffixMgr::isRevSubset(const char* s1,
+ const char* end_of_s2,
+ int len) {
+ while ((len > 0) && (*s1 != '\0') && ((*s1 == *end_of_s2) || (*s1 == '.'))) {
+ s1++;
+ end_of_s2--;
+ len--;
+ }
+ return (*s1 == '\0');
+}
+
+// check word for suffixes
+struct hentry* AffixMgr::suffix_check(const char* word,
+ int len,
+ int sfxopts,
+ PfxEntry* ppfx,
+ const FLAG cclass,
+ const FLAG needflag,
+ char in_compound) {
+ struct hentry* rv = NULL;
+ PfxEntry* ep = ppfx;
+
+ // first handle the special case of 0 length suffixes
+ SfxEntry* se = sStart[0];
+
+ while (se) {
+ if (!cclass || se->getCont()) {
+ // suffixes are not allowed in beginning of compounds
+ if ((((in_compound != IN_CPD_BEGIN)) || // && !cclass
+ // except when signed with compoundpermitflag flag
+ (se->getCont() && compoundpermitflag &&
+ TESTAFF(se->getCont(), compoundpermitflag, se->getContLen()))) &&
+ (!circumfix ||
+ // no circumfix flag in prefix and suffix
+ ((!ppfx || !(ep->getCont()) ||
+ !TESTAFF(ep->getCont(), circumfix, ep->getContLen())) &&
+ (!se->getCont() ||
+ !(TESTAFF(se->getCont(), circumfix, se->getContLen())))) ||
+ // circumfix flag in prefix AND suffix
+ ((ppfx && (ep->getCont()) &&
+ TESTAFF(ep->getCont(), circumfix, ep->getContLen())) &&
+ (se->getCont() &&
+ (TESTAFF(se->getCont(), circumfix, se->getContLen()))))) &&
+ // fogemorpheme
+ (in_compound ||
+ !(se->getCont() &&
+ (TESTAFF(se->getCont(), onlyincompound, se->getContLen())))) &&
+ // needaffix on prefix or first suffix
+ (cclass ||
+ !(se->getCont() &&
+ TESTAFF(se->getCont(), needaffix, se->getContLen())) ||
+ (ppfx &&
+ !((ep->getCont()) &&
+ TESTAFF(ep->getCont(), needaffix, ep->getContLen()))))) {
+ rv = se->checkword(word, len, sfxopts, ppfx,
+ (FLAG)cclass, needflag,
+ (in_compound ? 0 : onlyincompound));
+ if (rv) {
+ sfx = se; // BUG: sfx not stateless
+ return rv;
+ }
+ }
+ }
+ se = se->getNext();
+ }
+
+ // now handle the general case
+ if (len == 0)
+ return NULL; // FULLSTRIP
+ unsigned char sp = *((const unsigned char*)(word + len - 1));
+ SfxEntry* sptr = sStart[sp];
+
+ while (sptr) {
+ if (isRevSubset(sptr->getKey(), word + len - 1, len)) {
+ // suffixes are not allowed in beginning of compounds
+ if ((((in_compound != IN_CPD_BEGIN)) || // && !cclass
+ // except when signed with compoundpermitflag flag
+ (sptr->getCont() && compoundpermitflag &&
+ TESTAFF(sptr->getCont(), compoundpermitflag,
+ sptr->getContLen()))) &&
+ (!circumfix ||
+ // no circumfix flag in prefix and suffix
+ ((!ppfx || !(ep->getCont()) ||
+ !TESTAFF(ep->getCont(), circumfix, ep->getContLen())) &&
+ (!sptr->getCont() ||
+ !(TESTAFF(sptr->getCont(), circumfix, sptr->getContLen())))) ||
+ // circumfix flag in prefix AND suffix
+ ((ppfx && (ep->getCont()) &&
+ TESTAFF(ep->getCont(), circumfix, ep->getContLen())) &&
+ (sptr->getCont() &&
+ (TESTAFF(sptr->getCont(), circumfix, sptr->getContLen()))))) &&
+ // fogemorpheme
+ (in_compound ||
+ !((sptr->getCont() && (TESTAFF(sptr->getCont(), onlyincompound,
+ sptr->getContLen()))))) &&
+ // needaffix on prefix or first suffix
+ (cclass ||
+ !(sptr->getCont() &&
+ TESTAFF(sptr->getCont(), needaffix, sptr->getContLen())) ||
+ (ppfx &&
+ !((ep->getCont()) &&
+ TESTAFF(ep->getCont(), needaffix, ep->getContLen())))))
+ if (in_compound != IN_CPD_END || ppfx ||
+ !(sptr->getCont() &&
+ TESTAFF(sptr->getCont(), onlyincompound, sptr->getContLen()))) {
+ rv = sptr->checkword(word, len, sfxopts, ppfx,
+ cclass, needflag,
+ (in_compound ? 0 : onlyincompound));
+ if (rv) {
+ sfx = sptr; // BUG: sfx not stateless
+ sfxflag = sptr->getFlag(); // BUG: sfxflag not stateless
+ if (!sptr->getCont())
+ sfxappnd = sptr->getKey(); // BUG: sfxappnd not stateless
+ // LANG_hu section: spec. Hungarian rule
+ else if (langnum == LANG_hu && sptr->getKeyLen() &&
+ sptr->getKey()[0] == 'i' && sptr->getKey()[1] != 'y' &&
+ sptr->getKey()[1] != 't') {
+ sfxextra = 1;
+ }
+ // END of LANG_hu section
+ return rv;
+ }
+ }
+ sptr = sptr->getNextEQ();
+ } else {
+ sptr = sptr->getNextNE();
+ }
+ }
+
+ return NULL;
+}
+
+// check word for two-level suffixes
+struct hentry* AffixMgr::suffix_check_twosfx(const char* word,
+ int len,
+ int sfxopts,
+ PfxEntry* ppfx,
+ const FLAG needflag) {
+ struct hentry* rv = NULL;
+
+ // first handle the special case of 0 length suffixes
+ SfxEntry* se = sStart[0];
+ while (se) {
+ if (contclasses[se->getFlag()]) {
+ rv = se->check_twosfx(word, len, sfxopts, ppfx, needflag);
+ if (rv)
+ return rv;
+ }
+ se = se->getNext();
+ }
+
+ // now handle the general case
+ if (len == 0)
+ return NULL; // FULLSTRIP
+ unsigned char sp = *((const unsigned char*)(word + len - 1));
+ SfxEntry* sptr = sStart[sp];
+
+ while (sptr) {
+ if (isRevSubset(sptr->getKey(), word + len - 1, len)) {
+ if (contclasses[sptr->getFlag()]) {
+ rv = sptr->check_twosfx(word, len, sfxopts, ppfx, needflag);
+ if (rv) {
+ sfxflag = sptr->getFlag(); // BUG: sfxflag not stateless
+ if (!sptr->getCont())
+ sfxappnd = sptr->getKey(); // BUG: sfxappnd not stateless
+ return rv;
+ }
+ }
+ sptr = sptr->getNextEQ();
+ } else {
+ sptr = sptr->getNextNE();
+ }
+ }
+
+ return NULL;
+}
+
+// check word for two-level suffixes and morph
+std::string AffixMgr::suffix_check_twosfx_morph(const char* word,
+ int len,
+ int sfxopts,
+ PfxEntry* ppfx,
+ const FLAG needflag) {
+ std::string result;
+ std::string result2;
+ std::string result3;
+
+ // first handle the special case of 0 length suffixes
+ SfxEntry* se = sStart[0];
+ while (se) {
+ if (contclasses[se->getFlag()]) {
+ std::string st = se->check_twosfx_morph(word, len, sfxopts, ppfx, needflag);
+ if (!st.empty()) {
+ if (ppfx) {
+ if (ppfx->getMorph()) {
+ result.append(ppfx->getMorph());
+ result.push_back(MSEP_FLD);
+ } else
+ debugflag(result, ppfx->getFlag());
+ }
+ result.append(st);
+ if (se->getMorph()) {
+ result.push_back(MSEP_FLD);
+ result.append(se->getMorph());
+ } else
+ debugflag(result, se->getFlag());
+ result.push_back(MSEP_REC);
+ }
+ }
+ se = se->getNext();
+ }
+
+ // now handle the general case
+ if (len == 0)
+ return std::string(); // FULLSTRIP
+ unsigned char sp = *((const unsigned char*)(word + len - 1));
+ SfxEntry* sptr = sStart[sp];
+
+ while (sptr) {
+ if (isRevSubset(sptr->getKey(), word + len - 1, len)) {
+ if (contclasses[sptr->getFlag()]) {
+ std::string st = sptr->check_twosfx_morph(word, len, sfxopts, ppfx, needflag);
+ if (!st.empty()) {
+ sfxflag = sptr->getFlag(); // BUG: sfxflag not stateless
+ if (!sptr->getCont())
+ sfxappnd = sptr->getKey(); // BUG: sfxappnd not stateless
+ result2.assign(st);
+
+ result3.clear();
+
+ if (sptr->getMorph()) {
+ result3.push_back(MSEP_FLD);
+ result3.append(sptr->getMorph());
+ } else
+ debugflag(result3, sptr->getFlag());
+ strlinecat(result2, result3);
+ result2.push_back(MSEP_REC);
+ result.append(result2);
+ }
+ }
+ sptr = sptr->getNextEQ();
+ } else {
+ sptr = sptr->getNextNE();
+ }
+ }
+
+ return result;
+}
+
+std::string AffixMgr::suffix_check_morph(const char* word,
+ int len,
+ int sfxopts,
+ PfxEntry* ppfx,
+ const FLAG cclass,
+ const FLAG needflag,
+ char in_compound) {
+ std::string result;
+
+ struct hentry* rv = NULL;
+
+ PfxEntry* ep = ppfx;
+
+ // first handle the special case of 0 length suffixes
+ SfxEntry* se = sStart[0];
+ while (se) {
+ if (!cclass || se->getCont()) {
+ // suffixes are not allowed in beginning of compounds
+ if (((((in_compound != IN_CPD_BEGIN)) || // && !cclass
+ // except when signed with compoundpermitflag flag
+ (se->getCont() && compoundpermitflag &&
+ TESTAFF(se->getCont(), compoundpermitflag, se->getContLen()))) &&
+ (!circumfix ||
+ // no circumfix flag in prefix and suffix
+ ((!ppfx || !(ep->getCont()) ||
+ !TESTAFF(ep->getCont(), circumfix, ep->getContLen())) &&
+ (!se->getCont() ||
+ !(TESTAFF(se->getCont(), circumfix, se->getContLen())))) ||
+ // circumfix flag in prefix AND suffix
+ ((ppfx && (ep->getCont()) &&
+ TESTAFF(ep->getCont(), circumfix, ep->getContLen())) &&
+ (se->getCont() &&
+ (TESTAFF(se->getCont(), circumfix, se->getContLen()))))) &&
+ // fogemorpheme
+ (in_compound ||
+ !((se->getCont() &&
+ (TESTAFF(se->getCont(), onlyincompound, se->getContLen()))))) &&
+ // needaffix on prefix or first suffix
+ (cclass ||
+ !(se->getCont() &&
+ TESTAFF(se->getCont(), needaffix, se->getContLen())) ||
+ (ppfx &&
+ !((ep->getCont()) &&
+ TESTAFF(ep->getCont(), needaffix, ep->getContLen()))))))
+ rv = se->checkword(word, len, sfxopts, ppfx, cclass,
+ needflag, FLAG_NULL);
+ while (rv) {
+ if (ppfx) {
+ if (ppfx->getMorph()) {
+ result.append(ppfx->getMorph());
+ result.push_back(MSEP_FLD);
+ } else
+ debugflag(result, ppfx->getFlag());
+ }
+ if (complexprefixes && HENTRY_DATA(rv))
+ result.append(HENTRY_DATA2(rv));
+ if (!HENTRY_FIND(rv, MORPH_STEM)) {
+ result.push_back(MSEP_FLD);
+ result.append(MORPH_STEM);
+ result.append(HENTRY_WORD(rv));
+ }
+
+ if (!complexprefixes && HENTRY_DATA(rv)) {
+ result.push_back(MSEP_FLD);
+ result.append(HENTRY_DATA2(rv));
+ }
+ if (se->getMorph()) {
+ result.push_back(MSEP_FLD);
+ result.append(se->getMorph());
+ } else
+ debugflag(result, se->getFlag());
+ result.push_back(MSEP_REC);
+ rv = se->get_next_homonym(rv, sfxopts, ppfx, cclass, needflag);
+ }
+ }
+ se = se->getNext();
+ }
+
+ // now handle the general case
+ if (len == 0)
+ return std::string(); // FULLSTRIP
+ unsigned char sp = *((const unsigned char*)(word + len - 1));
+ SfxEntry* sptr = sStart[sp];
+
+ while (sptr) {
+ if (isRevSubset(sptr->getKey(), word + len - 1, len)) {
+ // suffixes are not allowed in beginning of compounds
+ if (((((in_compound != IN_CPD_BEGIN)) || // && !cclass
+ // except when signed with compoundpermitflag flag
+ (sptr->getCont() && compoundpermitflag &&
+ TESTAFF(sptr->getCont(), compoundpermitflag,
+ sptr->getContLen()))) &&
+ (!circumfix ||
+ // no circumfix flag in prefix and suffix
+ ((!ppfx || !(ep->getCont()) ||
+ !TESTAFF(ep->getCont(), circumfix, ep->getContLen())) &&
+ (!sptr->getCont() ||
+ !(TESTAFF(sptr->getCont(), circumfix, sptr->getContLen())))) ||
+ // circumfix flag in prefix AND suffix
+ ((ppfx && (ep->getCont()) &&
+ TESTAFF(ep->getCont(), circumfix, ep->getContLen())) &&
+ (sptr->getCont() &&
+ (TESTAFF(sptr->getCont(), circumfix, sptr->getContLen()))))) &&
+ // fogemorpheme
+ (in_compound ||
+ !((sptr->getCont() && (TESTAFF(sptr->getCont(), onlyincompound,
+ sptr->getContLen()))))) &&
+ // needaffix on first suffix
+ (cclass ||
+ !(sptr->getCont() &&
+ TESTAFF(sptr->getCont(), needaffix, sptr->getContLen())))))
+ rv = sptr->checkword(word, len, sfxopts, ppfx, cclass,
+ needflag, FLAG_NULL);
+ while (rv) {
+ if (ppfx) {
+ if (ppfx->getMorph()) {
+ result.append(ppfx->getMorph());
+ result.push_back(MSEP_FLD);
+ } else
+ debugflag(result, ppfx->getFlag());
+ }
+ if (complexprefixes && HENTRY_DATA(rv))
+ result.append(HENTRY_DATA2(rv));
+ if (!HENTRY_FIND(rv, MORPH_STEM)) {
+ result.push_back(MSEP_FLD);
+ result.append(MORPH_STEM);
+ result.append(HENTRY_WORD(rv));
+ }
+
+ if (!complexprefixes && HENTRY_DATA(rv)) {
+ result.push_back(MSEP_FLD);
+ result.append(HENTRY_DATA2(rv));
+ }
+
+ if (sptr->getMorph()) {
+ result.push_back(MSEP_FLD);
+ result.append(sptr->getMorph());
+ } else
+ debugflag(result, sptr->getFlag());
+ result.push_back(MSEP_REC);
+ rv = sptr->get_next_homonym(rv, sfxopts, ppfx, cclass, needflag);
+ }
+ sptr = sptr->getNextEQ();
+ } else {
+ sptr = sptr->getNextNE();
+ }
+ }
+
+ return result;
+}
+
+// check if word with affixes is correctly spelled
+struct hentry* AffixMgr::affix_check(const char* word,
+ int len,
+ const FLAG needflag,
+ char in_compound) {
+
+ // check all prefixes (also crossed with suffixes if allowed)
+ struct hentry* rv = prefix_check(word, len, in_compound, needflag);
+ if (rv)
+ return rv;
+
+ // if still not found check all suffixes
+ rv = suffix_check(word, len, 0, NULL, FLAG_NULL, needflag, in_compound);
+
+ if (havecontclass) {
+ sfx = NULL;
+ pfx = NULL;
+
+ if (rv)
+ return rv;
+ // if still not found check all two-level suffixes
+ rv = suffix_check_twosfx(word, len, 0, NULL, needflag);
+
+ if (rv)
+ return rv;
+ // if still not found check all two-level suffixes
+ rv = prefix_check_twosfx(word, len, IN_CPD_NOT, needflag);
+ }
+
+ return rv;
+}
+
+// check if word with affixes is correctly spelled
+std::string AffixMgr::affix_check_morph(const char* word,
+ int len,
+ const FLAG needflag,
+ char in_compound) {
+ std::string result;
+
+ // check all prefixes (also crossed with suffixes if allowed)
+ std::string st = prefix_check_morph(word, len, in_compound);
+ if (!st.empty()) {
+ result.append(st);
+ }
+
+ // if still not found check all suffixes
+ st = suffix_check_morph(word, len, 0, NULL, '\0', needflag, in_compound);
+ if (!st.empty()) {
+ result.append(st);
+ }
+
+ if (havecontclass) {
+ sfx = NULL;
+ pfx = NULL;
+ // if still not found check all two-level suffixes
+ st = suffix_check_twosfx_morph(word, len, 0, NULL, needflag);
+ if (!st.empty()) {
+ result.append(st);
+ }
+
+ // if still not found check all two-level suffixes
+ st = prefix_check_twosfx_morph(word, len, IN_CPD_NOT, needflag);
+ if (!st.empty()) {
+ result.append(st);
+ }
+ }
+
+ return result;
+}
+
+// morphcmp(): compare MORPH_DERI_SFX, MORPH_INFL_SFX and MORPH_TERM_SFX fields
+// in the first line of the inputs
+// return 0, if inputs equal
+// return 1, if inputs may equal with a secondary suffix
+// otherwise return -1
+static int morphcmp(const char* s, const char* t) {
+ int se = 0;
+ int te = 0;
+ const char* sl;
+ const char* tl;
+ const char* olds;
+ const char* oldt;
+ if (!s || !t)
+ return 1;
+ olds = s;
+ sl = strchr(s, '\n');
+ s = strstr(s, MORPH_DERI_SFX);
+ if (!s || (sl && sl < s))
+ s = strstr(olds, MORPH_INFL_SFX);
+ if (!s || (sl && sl < s)) {
+ s = strstr(olds, MORPH_TERM_SFX);
+ olds = NULL;
+ }
+ oldt = t;
+ tl = strchr(t, '\n');
+ t = strstr(t, MORPH_DERI_SFX);
+ if (!t || (tl && tl < t))
+ t = strstr(oldt, MORPH_INFL_SFX);
+ if (!t || (tl && tl < t)) {
+ t = strstr(oldt, MORPH_TERM_SFX);
+ oldt = NULL;
+ }
+ while (s && t && (!sl || sl > s) && (!tl || tl > t)) {
+ s += MORPH_TAG_LEN;
+ t += MORPH_TAG_LEN;
+ se = 0;
+ te = 0;
+ while ((*s == *t) && !se && !te) {
+ s++;
+ t++;
+ switch (*s) {
+ case ' ':
+ case '\n':
+ case '\t':
+ case '\0':
+ se = 1;
+ }
+ switch (*t) {
+ case ' ':
+ case '\n':
+ case '\t':
+ case '\0':
+ te = 1;
+ }
+ }
+ if (!se || !te) {
+ // not terminal suffix difference
+ if (olds)
+ return -1;
+ return 1;
+ }
+ olds = s;
+ s = strstr(s, MORPH_DERI_SFX);
+ if (!s || (sl && sl < s))
+ s = strstr(olds, MORPH_INFL_SFX);
+ if (!s || (sl && sl < s)) {
+ s = strstr(olds, MORPH_TERM_SFX);
+ olds = NULL;
+ }
+ oldt = t;
+ t = strstr(t, MORPH_DERI_SFX);
+ if (!t || (tl && tl < t))
+ t = strstr(oldt, MORPH_INFL_SFX);
+ if (!t || (tl && tl < t)) {
+ t = strstr(oldt, MORPH_TERM_SFX);
+ oldt = NULL;
+ }
+ }
+ if (!s && !t && se && te)
+ return 0;
+ return 1;
+}
+
+std::string AffixMgr::morphgen(const char* ts,
+ int wl,
+ const unsigned short* ap,
+ unsigned short al,
+ const char* morph,
+ const char* targetmorph,
+ int level) {
+ // handle suffixes
+ if (!morph)
+ return std::string();
+
+ // check substandard flag
+ if (TESTAFF(ap, substandard, al))
+ return std::string();
+
+ if (morphcmp(morph, targetmorph) == 0)
+ return ts;
+
+ size_t stemmorphcatpos;
+ std::string mymorph;
+
+ // use input suffix fields, if exist
+ if (strstr(morph, MORPH_INFL_SFX) || strstr(morph, MORPH_DERI_SFX)) {
+ mymorph.assign(morph);
+ mymorph.push_back(MSEP_FLD);
+ stemmorphcatpos = mymorph.size();
+ } else {
+ stemmorphcatpos = std::string::npos;
+ }
+
+ for (int i = 0; i < al; i++) {
+ const unsigned char c = (unsigned char)(ap[i] & 0x00FF);
+ SfxEntry* sptr = sFlag[c];
+ while (sptr) {
+ if (sptr->getFlag() == ap[i] && sptr->getMorph() &&
+ ((sptr->getContLen() == 0) ||
+ // don't generate forms with substandard affixes
+ !TESTAFF(sptr->getCont(), substandard, sptr->getContLen()))) {
+ const char* stemmorph;
+ if (stemmorphcatpos != std::string::npos) {
+ mymorph.replace(stemmorphcatpos, std::string::npos, sptr->getMorph());
+ stemmorph = mymorph.c_str();
+ } else {
+ stemmorph = sptr->getMorph();
+ }
+
+ int cmp = morphcmp(stemmorph, targetmorph);
+
+ if (cmp == 0) {
+ std::string newword = sptr->add(ts, wl);
+ if (!newword.empty()) {
+ hentry* check = pHMgr->lookup(newword.c_str()); // XXX extra dic
+ if (!check || !check->astr ||
+ !(TESTAFF(check->astr, forbiddenword, check->alen) ||
+ TESTAFF(check->astr, ONLYUPCASEFLAG, check->alen))) {
+ return newword;
+ }
+ }
+ }
+
+ // recursive call for secondary suffixes
+ if ((level == 0) && (cmp == 1) && (sptr->getContLen() > 0) &&
+ !TESTAFF(sptr->getCont(), substandard, sptr->getContLen())) {
+ std::string newword = sptr->add(ts, wl);
+ if (!newword.empty()) {
+ std::string newword2 =
+ morphgen(newword.c_str(), newword.size(), sptr->getCont(),
+ sptr->getContLen(), stemmorph, targetmorph, 1);
+
+ if (!newword2.empty()) {
+ return newword2;
+ }
+ }
+ }
+ }
+ sptr = sptr->getFlgNxt();
+ }
+ }
+ return std::string();
+}
+
+int AffixMgr::expand_rootword(struct guessword* wlst,
+ int maxn,
+ const char* ts,
+ int wl,
+ const unsigned short* ap,
+ unsigned short al,
+ const char* bad,
+ int badl,
+ const char* phon) {
+ int nh = 0;
+ // first add root word to list
+ if ((nh < maxn) &&
+ !(al && ((needaffix && TESTAFF(ap, needaffix, al)) ||
+ (onlyincompound && TESTAFF(ap, onlyincompound, al))))) {
+ wlst[nh].word = mystrdup(ts);
+ if (!wlst[nh].word)
+ return 0;
+ wlst[nh].allow = false;
+ wlst[nh].orig = NULL;
+ nh++;
+ // add special phonetic version
+ if (phon && (nh < maxn)) {
+ wlst[nh].word = mystrdup(phon);
+ if (!wlst[nh].word)
+ return nh - 1;
+ wlst[nh].allow = false;
+ wlst[nh].orig = mystrdup(ts);
+ if (!wlst[nh].orig)
+ return nh - 1;
+ nh++;
+ }
+ }
+
+ // handle suffixes
+ for (int i = 0; i < al; i++) {
+ const unsigned char c = (unsigned char)(ap[i] & 0x00FF);
+ SfxEntry* sptr = sFlag[c];
+ while (sptr) {
+ if ((sptr->getFlag() == ap[i]) &&
+ (!sptr->getKeyLen() ||
+ ((badl > sptr->getKeyLen()) &&
+ (strcmp(sptr->getAffix(), bad + badl - sptr->getKeyLen()) == 0))) &&
+ // check needaffix flag
+ !(sptr->getCont() &&
+ ((needaffix &&
+ TESTAFF(sptr->getCont(), needaffix, sptr->getContLen())) ||
+ (circumfix &&
+ TESTAFF(sptr->getCont(), circumfix, sptr->getContLen())) ||
+ (onlyincompound &&
+ TESTAFF(sptr->getCont(), onlyincompound, sptr->getContLen()))))) {
+ std::string newword = sptr->add(ts, wl);
+ if (!newword.empty()) {
+ if (nh < maxn) {
+ wlst[nh].word = mystrdup(newword.c_str());
+ wlst[nh].allow = sptr->allowCross();
+ wlst[nh].orig = NULL;
+ nh++;
+ // add special phonetic version
+ if (phon && (nh < maxn)) {
+ std::string prefix(phon);
+ std::string key(sptr->getKey());
+ reverseword(key);
+ prefix.append(key);
+ wlst[nh].word = mystrdup(prefix.c_str());
+ if (!wlst[nh].word)
+ return nh - 1;
+ wlst[nh].allow = false;
+ wlst[nh].orig = mystrdup(newword.c_str());
+ if (!wlst[nh].orig)
+ return nh - 1;
+ nh++;
+ }
+ }
+ }
+ }
+ sptr = sptr->getFlgNxt();
+ }
+ }
+
+ int n = nh;
+
+ // handle cross products of prefixes and suffixes
+ for (int j = 1; j < n; j++)
+ if (wlst[j].allow) {
+ for (int k = 0; k < al; k++) {
+ const unsigned char c = (unsigned char)(ap[k] & 0x00FF);
+ PfxEntry* cptr = pFlag[c];
+ while (cptr) {
+ if ((cptr->getFlag() == ap[k]) && cptr->allowCross() &&
+ (!cptr->getKeyLen() ||
+ ((badl > cptr->getKeyLen()) &&
+ (strncmp(cptr->getKey(), bad, cptr->getKeyLen()) == 0)))) {
+ int l1 = strlen(wlst[j].word);
+ std::string newword = cptr->add(wlst[j].word, l1);
+ if (!newword.empty()) {
+ if (nh < maxn) {
+ wlst[nh].word = mystrdup(newword.c_str());
+ wlst[nh].allow = cptr->allowCross();
+ wlst[nh].orig = NULL;
+ nh++;
+ }
+ }
+ }
+ cptr = cptr->getFlgNxt();
+ }
+ }
+ }
+
+ // now handle pure prefixes
+ for (int m = 0; m < al; m++) {
+ const unsigned char c = (unsigned char)(ap[m] & 0x00FF);
+ PfxEntry* ptr = pFlag[c];
+ while (ptr) {
+ if ((ptr->getFlag() == ap[m]) &&
+ (!ptr->getKeyLen() ||
+ ((badl > ptr->getKeyLen()) &&
+ (strncmp(ptr->getKey(), bad, ptr->getKeyLen()) == 0))) &&
+ // check needaffix flag
+ !(ptr->getCont() &&
+ ((needaffix &&
+ TESTAFF(ptr->getCont(), needaffix, ptr->getContLen())) ||
+ (circumfix &&
+ TESTAFF(ptr->getCont(), circumfix, ptr->getContLen())) ||
+ (onlyincompound &&
+ TESTAFF(ptr->getCont(), onlyincompound, ptr->getContLen()))))) {
+ std::string newword = ptr->add(ts, wl);
+ if (!newword.empty()) {
+ if (nh < maxn) {
+ wlst[nh].word = mystrdup(newword.c_str());
+ wlst[nh].allow = ptr->allowCross();
+ wlst[nh].orig = NULL;
+ nh++;
+ }
+ }
+ }
+ ptr = ptr->getFlgNxt();
+ }
+ }
+
+ return nh;
+}
+
+// return replacing table
+const std::vector<replentry>& AffixMgr::get_reptable() const {
+ return pHMgr->get_reptable();
+}
+
+// return iconv table
+RepList* AffixMgr::get_iconvtable() const {
+ if (!iconvtable)
+ return NULL;
+ return iconvtable;
+}
+
+// return oconv table
+RepList* AffixMgr::get_oconvtable() const {
+ if (!oconvtable)
+ return NULL;
+ return oconvtable;
+}
+
+// return replacing table
+struct phonetable* AffixMgr::get_phonetable() const {
+ if (!phone)
+ return NULL;
+ return phone;
+}
+
+// return character map table
+const std::vector<mapentry>& AffixMgr::get_maptable() const {
+ return maptable;
+}
+
+// return character map table
+const std::vector<std::string>& AffixMgr::get_breaktable() const {
+ return breaktable;
+}
+
+// return text encoding of dictionary
+const std::string& AffixMgr::get_encoding() {
+ if (encoding.empty())
+ encoding = SPELL_ENCODING;
+ return encoding;
+}
+
+// return text encoding of dictionary
+int AffixMgr::get_langnum() const {
+ return langnum;
+}
+
+// return double prefix option
+int AffixMgr::get_complexprefixes() const {
+ return complexprefixes;
+}
+
+// return FULLSTRIP option
+int AffixMgr::get_fullstrip() const {
+ return fullstrip;
+}
+
+FLAG AffixMgr::get_keepcase() const {
+ return keepcase;
+}
+
+FLAG AffixMgr::get_forceucase() const {
+ return forceucase;
+}
+
+FLAG AffixMgr::get_warn() const {
+ return warn;
+}
+
+int AffixMgr::get_forbidwarn() const {
+ return forbidwarn;
+}
+
+int AffixMgr::get_checksharps() const {
+ return checksharps;
+}
+
+char* AffixMgr::encode_flag(unsigned short aflag) const {
+ return pHMgr->encode_flag(aflag);
+}
+
+// return the preferred ignore string for suggestions
+const char* AffixMgr::get_ignore() const {
+ if (ignorechars.empty())
+ return NULL;
+ return ignorechars.c_str();
+}
+
+// return the preferred ignore string for suggestions
+const std::vector<w_char>& AffixMgr::get_ignore_utf16() const {
+ return ignorechars_utf16;
+}
+
+// return the keyboard string for suggestions
+char* AffixMgr::get_key_string() {
+ if (keystring.empty())
+ keystring = SPELL_KEYSTRING;
+ return mystrdup(keystring.c_str());
+}
+
+// return the preferred try string for suggestions
+char* AffixMgr::get_try_string() const {
+ if (trystring.empty())
+ return NULL;
+ return mystrdup(trystring.c_str());
+}
+
+// return the preferred try string for suggestions
+const std::string& AffixMgr::get_wordchars() const {
+ return wordchars;
+}
+
+const std::vector<w_char>& AffixMgr::get_wordchars_utf16() const {
+ return wordchars_utf16;
+}
+
+// is there compounding?
+int AffixMgr::get_compound() const {
+ return compoundflag || compoundbegin || !defcpdtable.empty();
+}
+
+// return the compound words control flag
+FLAG AffixMgr::get_compoundflag() const {
+ return compoundflag;
+}
+
+// return the forbidden words control flag
+FLAG AffixMgr::get_forbiddenword() const {
+ return forbiddenword;
+}
+
+// return the forbidden words control flag
+FLAG AffixMgr::get_nosuggest() const {
+ return nosuggest;
+}
+
+// return the forbidden words control flag
+FLAG AffixMgr::get_nongramsuggest() const {
+ return nongramsuggest;
+}
+
+// return the substandard root/affix control flag
+FLAG AffixMgr::get_substandard() const {
+ return substandard;
+}
+
+// return the forbidden words flag modify flag
+FLAG AffixMgr::get_needaffix() const {
+ return needaffix;
+}
+
+// return the onlyincompound flag
+FLAG AffixMgr::get_onlyincompound() const {
+ return onlyincompound;
+}
+
+// return the value of suffix
+const std::string& AffixMgr::get_version() const {
+ return version;
+}
+
+// utility method to look up root words in hash table
+struct hentry* AffixMgr::lookup(const char* word) {
+ struct hentry* he = NULL;
+ for (size_t i = 0; i < alldic.size() && !he; ++i) {
+ he = alldic[i]->lookup(word);
+ }
+ return he;
+}
+
+// return the value of suffix
+int AffixMgr::have_contclass() const {
+ return havecontclass;
+}
+
+// return utf8
+int AffixMgr::get_utf8() const {
+ return utf8;
+}
+
+int AffixMgr::get_maxngramsugs(void) const {
+ return maxngramsugs;
+}
+
+int AffixMgr::get_maxcpdsugs(void) const {
+ return maxcpdsugs;
+}
+
+int AffixMgr::get_maxdiff(void) const {
+ return maxdiff;
+}
+
+int AffixMgr::get_onlymaxdiff(void) const {
+ return onlymaxdiff;
+}
+
+// return nosplitsugs
+int AffixMgr::get_nosplitsugs(void) const {
+ return nosplitsugs;
+}
+
+// return sugswithdots
+int AffixMgr::get_sugswithdots(void) const {
+ return sugswithdots;
+}
+
+/* parse flag */
+bool AffixMgr::parse_flag(const std::string& line, unsigned short* out, FileMgr* af) {
+ if (*out != FLAG_NULL && !(*out >= DEFAULTFLAGS)) {
+ HUNSPELL_WARNING(
+ stderr,
+ "error: line %d: multiple definitions of an affix file parameter\n",
+ af->getlinenum());
+ return false;
+ }
+ std::string s;
+ if (!parse_string(line, s, af->getlinenum()))
+ return false;
+ *out = pHMgr->decode_flag(s.c_str());
+ return true;
+}
+
+/* parse num */
+bool AffixMgr::parse_num(const std::string& line, int* out, FileMgr* af) {
+ if (*out != -1) {
+ HUNSPELL_WARNING(
+ stderr,
+ "error: line %d: multiple definitions of an affix file parameter\n",
+ af->getlinenum());
+ return false;
+ }
+ std::string s;
+ if (!parse_string(line, s, af->getlinenum()))
+ return false;
+ *out = atoi(s.c_str());
+ return true;
+}
+
+/* parse in the max syllablecount of compound words and */
+bool AffixMgr::parse_cpdsyllable(const std::string& line, FileMgr* af) {
+ int i = 0;
+ int np = 0;
+ std::string::const_iterator iter = line.begin();
+ std::string::const_iterator start_piece = mystrsep(line, iter);
+ while (start_piece != line.end()) {
+ switch (i) {
+ case 0: {
+ np++;
+ break;
+ }
+ case 1: {
+ cpdmaxsyllable = atoi(std::string(start_piece, iter).c_str());
+ np++;
+ break;
+ }
+ case 2: {
+ if (!utf8) {
+ cpdvowels.assign(start_piece, iter);
+ std::sort(cpdvowels.begin(), cpdvowels.end());
+ } else {
+ std::string piece(start_piece, iter);
+ u8_u16(cpdvowels_utf16, piece);
+ std::sort(cpdvowels_utf16.begin(), cpdvowels_utf16.end());
+ }
+ np++;
+ break;
+ }
+ default:
+ break;
+ }
+ ++i;
+ start_piece = mystrsep(line, iter);
+ }
+ if (np < 2) {
+ HUNSPELL_WARNING(stderr,
+ "error: line %d: missing compoundsyllable information\n",
+ af->getlinenum());
+ return false;
+ }
+ if (np == 2)
+ cpdvowels = "AEIOUaeiou";
+ return true;
+}
+
+bool AffixMgr::parse_convtable(const std::string& line,
+ FileMgr* af,
+ RepList** rl,
+ const std::string& keyword) {
+ if (*rl) {
+ HUNSPELL_WARNING(stderr, "error: line %d: multiple table definitions\n",
+ af->getlinenum());
+ return false;
+ }
+ int i = 0;
+ int np = 0;
+ int numrl = 0;
+ std::string::const_iterator iter = line.begin();
+ std::string::const_iterator start_piece = mystrsep(line, iter);
+ while (start_piece != line.end()) {
+ switch (i) {
+ case 0: {
+ np++;
+ break;
+ }
+ case 1: {
+ numrl = atoi(std::string(start_piece, iter).c_str());
+ if (numrl < 1) {
+ HUNSPELL_WARNING(stderr, "error: line %d: incorrect entry number\n",
+ af->getlinenum());
+ return false;
+ }
+ *rl = new RepList(numrl);
+ if (!*rl)
+ return false;
+ np++;
+ break;
+ }
+ default:
+ break;
+ }
+ ++i;
+ start_piece = mystrsep(line, iter);
+ }
+ if (np != 2) {
+ HUNSPELL_WARNING(stderr, "error: line %d: missing data\n",
+ af->getlinenum());
+ return false;
+ }
+
+ /* now parse the num lines to read in the remainder of the table */
+ for (int j = 0; j < numrl; j++) {
+ std::string nl;
+ if (!af->getline(nl))
+ return false;
+ mychomp(nl);
+ i = 0;
+ std::string pattern;
+ std::string pattern2;
+ iter = nl.begin();
+ start_piece = mystrsep(nl, iter);
+ while (start_piece != nl.end()) {
+ {
+ switch (i) {
+ case 0: {
+ if (nl.compare(start_piece - nl.begin(), keyword.size(), keyword, 0, keyword.size()) != 0) {
+ HUNSPELL_WARNING(stderr, "error: line %d: table is corrupt\n",
+ af->getlinenum());
+ delete *rl;
+ *rl = NULL;
+ return false;
+ }
+ break;
+ }
+ case 1: {
+ pattern.assign(start_piece, iter);
+ break;
+ }
+ case 2: {
+ pattern2.assign(start_piece, iter);
+ break;
+ }
+ default:
+ break;
+ }
+ ++i;
+ }
+ start_piece = mystrsep(nl, iter);
+ }
+ if (pattern.empty() || pattern2.empty()) {
+ HUNSPELL_WARNING(stderr, "error: line %d: table is corrupt\n",
+ af->getlinenum());
+ return false;
+ }
+ (*rl)->add(pattern, pattern2);
+ }
+ return true;
+}
+
+/* parse in the typical fault correcting table */
+bool AffixMgr::parse_phonetable(const std::string& line, FileMgr* af) {
+ if (phone) {
+ HUNSPELL_WARNING(stderr, "error: line %d: multiple table definitions\n",
+ af->getlinenum());
+ return false;
+ }
+ int num = -1;
+ int i = 0;
+ int np = 0;
+ std::string::const_iterator iter = line.begin();
+ std::string::const_iterator start_piece = mystrsep(line, iter);
+ while (start_piece != line.end()) {
+ switch (i) {
+ case 0: {
+ np++;
+ break;
+ }
+ case 1: {
+ num = atoi(std::string(start_piece, iter).c_str());
+ if (num < 1) {
+ HUNSPELL_WARNING(stderr, "error: line %d: bad entry number\n",
+ af->getlinenum());
+ return false;
+ }
+ phone = new phonetable;
+ phone->utf8 = (char)utf8;
+ np++;
+ break;
+ }
+ default:
+ break;
+ }
+ ++i;
+ start_piece = mystrsep(line, iter);
+ }
+ if (np != 2) {
+ HUNSPELL_WARNING(stderr, "error: line %d: missing data\n",
+ af->getlinenum());
+ return false;
+ }
+
+ /* now parse the phone->num lines to read in the remainder of the table */
+ for (int j = 0; j < num; ++j) {
+ std::string nl;
+ if (!af->getline(nl))
+ return false;
+ mychomp(nl);
+ i = 0;
+ const size_t old_size = phone->rules.size();
+ iter = nl.begin();
+ start_piece = mystrsep(nl, iter);
+ while (start_piece != nl.end()) {
+ {
+ switch (i) {
+ case 0: {
+ if (nl.compare(start_piece - nl.begin(), 5, "PHONE", 5) != 0) {
+ HUNSPELL_WARNING(stderr, "error: line %d: table is corrupt\n",
+ af->getlinenum());
+ return false;
+ }
+ break;
+ }
+ case 1: {
+ phone->rules.push_back(std::string(start_piece, iter));
+ break;
+ }
+ case 2: {
+ phone->rules.push_back(std::string(start_piece, iter));
+ mystrrep(phone->rules.back(), "_", "");
+ break;
+ }
+ default:
+ break;
+ }
+ ++i;
+ }
+ start_piece = mystrsep(nl, iter);
+ }
+ if (phone->rules.size() != old_size + 2) {
+ HUNSPELL_WARNING(stderr, "error: line %d: table is corrupt\n",
+ af->getlinenum());
+ phone->rules.clear();
+ return false;
+ }
+ }
+ phone->rules.push_back("");
+ phone->rules.push_back("");
+ init_phonet_hash(*phone);
+ return true;
+}
+
+/* parse in the checkcompoundpattern table */
+bool AffixMgr::parse_checkcpdtable(const std::string& line, FileMgr* af) {
+ if (parsedcheckcpd) {
+ HUNSPELL_WARNING(stderr, "error: line %d: multiple table definitions\n",
+ af->getlinenum());
+ return false;
+ }
+ parsedcheckcpd = true;
+ int numcheckcpd = -1;
+ int i = 0;
+ int np = 0;
+ std::string::const_iterator iter = line.begin();
+ std::string::const_iterator start_piece = mystrsep(line, iter);
+ while (start_piece != line.end()) {
+ switch (i) {
+ case 0: {
+ np++;
+ break;
+ }
+ case 1: {
+ numcheckcpd = atoi(std::string(start_piece, iter).c_str());
+ if (numcheckcpd < 1) {
+ HUNSPELL_WARNING(stderr, "error: line %d: bad entry number\n",
+ af->getlinenum());
+ return false;
+ }
+ checkcpdtable.reserve(numcheckcpd);
+ np++;
+ break;
+ }
+ default:
+ break;
+ }
+ ++i;
+ start_piece = mystrsep(line, iter);
+ }
+ if (np != 2) {
+ HUNSPELL_WARNING(stderr, "error: line %d: missing data\n",
+ af->getlinenum());
+ return false;
+ }
+
+ /* now parse the numcheckcpd lines to read in the remainder of the table */
+ for (int j = 0; j < numcheckcpd; ++j) {
+ std::string nl;
+ if (!af->getline(nl))
+ return false;
+ mychomp(nl);
+ i = 0;
+ checkcpdtable.push_back(patentry());
+ iter = nl.begin();
+ start_piece = mystrsep(nl, iter);
+ while (start_piece != nl.end()) {
+ switch (i) {
+ case 0: {
+ if (nl.compare(start_piece - nl.begin(), 20, "CHECKCOMPOUNDPATTERN", 20) != 0) {
+ HUNSPELL_WARNING(stderr, "error: line %d: table is corrupt\n",
+ af->getlinenum());
+ return false;
+ }
+ break;
+ }
+ case 1: {
+ checkcpdtable.back().pattern.assign(start_piece, iter);
+ size_t slash_pos = checkcpdtable.back().pattern.find('/');
+ if (slash_pos != std::string::npos) {
+ std::string chunk(checkcpdtable.back().pattern, slash_pos + 1);
+ checkcpdtable.back().pattern.resize(slash_pos);
+ checkcpdtable.back().cond = pHMgr->decode_flag(chunk.c_str());
+ }
+ break;
+ }
+ case 2: {
+ checkcpdtable.back().pattern2.assign(start_piece, iter);
+ size_t slash_pos = checkcpdtable.back().pattern2.find('/');
+ if (slash_pos != std::string::npos) {
+ std::string chunk(checkcpdtable.back().pattern2, slash_pos + 1);
+ checkcpdtable.back().pattern2.resize(slash_pos);
+ checkcpdtable.back().cond2 = pHMgr->decode_flag(chunk.c_str());
+ }
+ break;
+ }
+ case 3: {
+ checkcpdtable.back().pattern3.assign(start_piece, iter);
+ simplifiedcpd = 1;
+ break;
+ }
+ default:
+ break;
+ }
+ i++;
+ start_piece = mystrsep(nl, iter);
+ }
+ }
+ return true;
+}
+
+/* parse in the compound rule table */
+bool AffixMgr::parse_defcpdtable(const std::string& line, FileMgr* af) {
+ if (parseddefcpd) {
+ HUNSPELL_WARNING(stderr, "error: line %d: multiple table definitions\n",
+ af->getlinenum());
+ return false;
+ }
+ parseddefcpd = true;
+ int numdefcpd = -1;
+ int i = 0;
+ int np = 0;
+ std::string::const_iterator iter = line.begin();
+ std::string::const_iterator start_piece = mystrsep(line, iter);
+ while (start_piece != line.end()) {
+ switch (i) {
+ case 0: {
+ np++;
+ break;
+ }
+ case 1: {
+ numdefcpd = atoi(std::string(start_piece, iter).c_str());
+ if (numdefcpd < 1) {
+ HUNSPELL_WARNING(stderr, "error: line %d: bad entry number\n",
+ af->getlinenum());
+ return false;
+ }
+ defcpdtable.reserve(numdefcpd);
+ np++;
+ break;
+ }
+ default:
+ break;
+ }
+ ++i;
+ start_piece = mystrsep(line, iter);
+ }
+ if (np != 2) {
+ HUNSPELL_WARNING(stderr, "error: line %d: missing data\n",
+ af->getlinenum());
+ return false;
+ }
+
+ /* now parse the numdefcpd lines to read in the remainder of the table */
+ for (int j = 0; j < numdefcpd; ++j) {
+ std::string nl;
+ if (!af->getline(nl))
+ return false;
+ mychomp(nl);
+ i = 0;
+ defcpdtable.push_back(flagentry());
+ iter = nl.begin();
+ start_piece = mystrsep(nl, iter);
+ while (start_piece != nl.end()) {
+ switch (i) {
+ case 0: {
+ if (nl.compare(start_piece - nl.begin(), 12, "COMPOUNDRULE", 12) != 0) {
+ HUNSPELL_WARNING(stderr, "error: line %d: table is corrupt\n",
+ af->getlinenum());
+ numdefcpd = 0;
+ return false;
+ }
+ break;
+ }
+ case 1: { // handle parenthesized flags
+ if (std::find(start_piece, iter, '(') != iter) {
+ for (std::string::const_iterator k = start_piece; k != iter; ++k) {
+ std::string::const_iterator chb = k;
+ std::string::const_iterator che = k + 1;
+ if (*k == '(') {
+ std::string::const_iterator parpos = std::find(k, iter, ')');
+ if (parpos != iter) {
+ chb = k + 1;
+ che = parpos;
+ k = parpos;
+ }
+ }
+
+ if (*chb == '*' || *chb == '?') {
+ defcpdtable.back().push_back((FLAG)*chb);
+ } else {
+ pHMgr->decode_flags(defcpdtable.back(), std::string(chb, che), af);
+ }
+ }
+ } else {
+ pHMgr->decode_flags(defcpdtable.back(), std::string(start_piece, iter), af);
+ }
+ break;
+ }
+ default:
+ break;
+ }
+ ++i;
+ start_piece = mystrsep(nl, iter);
+ }
+ if (defcpdtable.back().empty()) {
+ HUNSPELL_WARNING(stderr, "error: line %d: table is corrupt\n",
+ af->getlinenum());
+ return false;
+ }
+ }
+ return true;
+}
+
+/* parse in the character map table */
+bool AffixMgr::parse_maptable(const std::string& line, FileMgr* af) {
+ if (parsedmaptable) {
+ HUNSPELL_WARNING(stderr, "error: line %d: multiple table definitions\n",
+ af->getlinenum());
+ return false;
+ }
+ parsedmaptable = true;
+ int nummap = -1;
+ int i = 0;
+ int np = 0;
+ std::string::const_iterator iter = line.begin();
+ std::string::const_iterator start_piece = mystrsep(line, iter);
+ while (start_piece != line.end()) {
+ switch (i) {
+ case 0: {
+ np++;
+ break;
+ }
+ case 1: {
+ nummap = atoi(std::string(start_piece, iter).c_str());
+ if (nummap < 1) {
+ HUNSPELL_WARNING(stderr, "error: line %d: bad entry number\n",
+ af->getlinenum());
+ return false;
+ }
+ maptable.reserve(nummap);
+ np++;
+ break;
+ }
+ default:
+ break;
+ }
+ ++i;
+ start_piece = mystrsep(line, iter);
+ }
+ if (np != 2) {
+ HUNSPELL_WARNING(stderr, "error: line %d: missing data\n",
+ af->getlinenum());
+ return false;
+ }
+
+ /* now parse the nummap lines to read in the remainder of the table */
+ for (int j = 0; j < nummap; ++j) {
+ std::string nl;
+ if (!af->getline(nl))
+ return false;
+ mychomp(nl);
+ i = 0;
+ maptable.push_back(mapentry());
+ iter = nl.begin();
+ start_piece = mystrsep(nl, iter);
+ while (start_piece != nl.end()) {
+ switch (i) {
+ case 0: {
+ if (nl.compare(start_piece - nl.begin(), 3, "MAP", 3) != 0) {
+ HUNSPELL_WARNING(stderr, "error: line %d: table is corrupt\n",
+ af->getlinenum());
+ nummap = 0;
+ return false;
+ }
+ break;
+ }
+ case 1: {
+ for (std::string::const_iterator k = start_piece; k != iter; ++k) {
+ std::string::const_iterator chb = k;
+ std::string::const_iterator che = k + 1;
+ if (*k == '(') {
+ std::string::const_iterator parpos = std::find(k, iter, ')');
+ if (parpos != iter) {
+ chb = k + 1;
+ che = parpos;
+ k = parpos;
+ }
+ } else {
+ if (utf8 && (*k & 0xc0) == 0xc0) {
+ ++k;
+ while (k != iter && (*k & 0xc0) == 0x80)
+ ++k;
+ che = k;
+ --k;
+ }
+ }
+ maptable.back().push_back(std::string(chb, che));
+ }
+ break;
+ }
+ default:
+ break;
+ }
+ ++i;
+ start_piece = mystrsep(nl, iter);
+ }
+ if (maptable.back().empty()) {
+ HUNSPELL_WARNING(stderr, "error: line %d: table is corrupt\n",
+ af->getlinenum());
+ return false;
+ }
+ }
+ return true;
+}
+
+/* parse in the word breakpoint table */
+bool AffixMgr::parse_breaktable(const std::string& line, FileMgr* af) {
+ if (parsedbreaktable) {
+ HUNSPELL_WARNING(stderr, "error: line %d: multiple table definitions\n",
+ af->getlinenum());
+ return false;
+ }
+ parsedbreaktable = true;
+ int numbreak = -1;
+ int i = 0;
+ int np = 0;
+ std::string::const_iterator iter = line.begin();
+ std::string::const_iterator start_piece = mystrsep(line, iter);
+ while (start_piece != line.end()) {
+ switch (i) {
+ case 0: {
+ np++;
+ break;
+ }
+ case 1: {
+ numbreak = atoi(std::string(start_piece, iter).c_str());
+ if (numbreak < 0) {
+ HUNSPELL_WARNING(stderr, "error: line %d: bad entry number\n",
+ af->getlinenum());
+ return false;
+ }
+ if (numbreak == 0)
+ return true;
+ breaktable.reserve(numbreak);
+ np++;
+ break;
+ }
+ default:
+ break;
+ }
+ ++i;
+ start_piece = mystrsep(line, iter);
+ }
+ if (np != 2) {
+ HUNSPELL_WARNING(stderr, "error: line %d: missing data\n",
+ af->getlinenum());
+ return false;
+ }
+
+ /* now parse the numbreak lines to read in the remainder of the table */
+ for (int j = 0; j < numbreak; ++j) {
+ std::string nl;
+ if (!af->getline(nl))
+ return false;
+ mychomp(nl);
+ i = 0;
+ iter = nl.begin();
+ start_piece = mystrsep(nl, iter);
+ while (start_piece != nl.end()) {
+ switch (i) {
+ case 0: {
+ if (nl.compare(start_piece - nl.begin(), 5, "BREAK", 5) != 0) {
+ HUNSPELL_WARNING(stderr, "error: line %d: table is corrupt\n",
+ af->getlinenum());
+ numbreak = 0;
+ return false;
+ }
+ break;
+ }
+ case 1: {
+ breaktable.push_back(std::string(start_piece, iter));
+ break;
+ }
+ default:
+ break;
+ }
+ ++i;
+ start_piece = mystrsep(nl, iter);
+ }
+ }
+
+ if (breaktable.size() != static_cast<size_t>(numbreak)) {
+ HUNSPELL_WARNING(stderr, "error: line %d: table is corrupt\n",
+ af->getlinenum());
+ return false;
+ }
+
+ return true;
+}
+
+void AffixMgr::reverse_condition(std::string& piece) {
+ if (piece.empty())
+ return;
+
+ int neg = 0;
+ for (std::string::reverse_iterator k = piece.rbegin(); k != piece.rend(); ++k) {
+ switch (*k) {
+ case '[': {
+ if (neg)
+ *(k - 1) = '[';
+ else
+ *k = ']';
+ break;
+ }
+ case ']': {
+ *k = '[';
+ if (neg)
+ *(k - 1) = '^';
+ neg = 0;
+ break;
+ }
+ case '^': {
+ if (*(k - 1) == ']')
+ neg = 1;
+ else if (neg)
+ *(k - 1) = *k;
+ break;
+ }
+ default: {
+ if (neg)
+ *(k - 1) = *k;
+ }
+ }
+ }
+}
+
+class entries_container {
+ std::vector<AffEntry*> entries;
+ AffixMgr* m_mgr;
+ char m_at;
+public:
+ entries_container(char at, AffixMgr* mgr)
+ : m_mgr(mgr)
+ , m_at(at) {
+ }
+ void release() {
+ entries.clear();
+ }
+ void initialize(int numents,
+ char opts, unsigned short aflag) {
+ entries.reserve(numents);
+
+ if (m_at == 'P') {
+ entries.push_back(new PfxEntry(m_mgr));
+ } else {
+ entries.push_back(new SfxEntry(m_mgr));
+ }
+
+ entries.back()->opts = opts;
+ entries.back()->aflag = aflag;
+ }
+
+ AffEntry* add_entry(char opts) {
+ if (m_at == 'P') {
+ entries.push_back(new PfxEntry(m_mgr));
+ } else {
+ entries.push_back(new SfxEntry(m_mgr));
+ }
+ AffEntry* ret = entries.back();
+ ret->opts = entries[0]->opts & opts;
+ return ret;
+ }
+
+ AffEntry* first_entry() {
+ return entries.empty() ? NULL : entries[0];
+ }
+
+ ~entries_container() {
+ for (size_t i = 0; i < entries.size(); ++i) {
+ delete entries[i];
+ }
+ }
+
+ std::vector<AffEntry*>::iterator begin() { return entries.begin(); }
+ std::vector<AffEntry*>::iterator end() { return entries.end(); }
+};
+
+bool AffixMgr::parse_affix(const std::string& line,
+ const char at,
+ FileMgr* af,
+ char* dupflags) {
+ int numents = 0; // number of AffEntry structures to parse
+
+ unsigned short aflag = 0; // affix char identifier
+
+ char ff = 0;
+ entries_container affentries(at, this);
+
+ int i = 0;
+
+// checking lines with bad syntax
+#ifdef DEBUG
+ int basefieldnum = 0;
+#endif
+
+ // split affix header line into pieces
+
+ int np = 0;
+ std::string::const_iterator iter = line.begin();
+ std::string::const_iterator start_piece = mystrsep(line, iter);
+ while (start_piece != line.end()) {
+ switch (i) {
+ // piece 1 - is type of affix
+ case 0: {
+ np++;
+ break;
+ }
+
+ // piece 2 - is affix char
+ case 1: {
+ np++;
+ aflag = pHMgr->decode_flag(std::string(start_piece, iter).c_str());
+ if (((at == 'S') && (dupflags[aflag] & dupSFX)) ||
+ ((at == 'P') && (dupflags[aflag] & dupPFX))) {
+ HUNSPELL_WARNING(
+ stderr,
+ "error: line %d: multiple definitions of an affix flag\n",
+ af->getlinenum());
+ }
+ dupflags[aflag] += (char)((at == 'S') ? dupSFX : dupPFX);
+ break;
+ }
+ // piece 3 - is cross product indicator
+ case 2: {
+ np++;
+ if (*start_piece == 'Y')
+ ff = aeXPRODUCT;
+ break;
+ }
+
+ // piece 4 - is number of affentries
+ case 3: {
+ np++;
+ numents = atoi(std::string(start_piece, iter).c_str());
+ if ((numents <= 0) || ((std::numeric_limits<size_t>::max() /
+ sizeof(AffEntry)) < static_cast<size_t>(numents))) {
+ char* err = pHMgr->encode_flag(aflag);
+ if (err) {
+ HUNSPELL_WARNING(stderr, "error: line %d: bad entry number\n",
+ af->getlinenum());
+ free(err);
+ }
+ return false;
+ }
+
+ char opts = ff;
+ if (utf8)
+ opts |= aeUTF8;
+ if (pHMgr->is_aliasf())
+ opts |= aeALIASF;
+ if (pHMgr->is_aliasm())
+ opts |= aeALIASM;
+ affentries.initialize(numents, opts, aflag);
+ }
+
+ default:
+ break;
+ }
+ ++i;
+ start_piece = mystrsep(line, iter);
+ }
+ // check to make sure we parsed enough pieces
+ if (np != 4) {
+ char* err = pHMgr->encode_flag(aflag);
+ if (err) {
+ HUNSPELL_WARNING(stderr, "error: line %d: missing data\n",
+ af->getlinenum());
+ free(err);
+ }
+ return false;
+ }
+
+ // now parse numents affentries for this affix
+ AffEntry* entry = affentries.first_entry();
+ for (int ent = 0; ent < numents; ++ent) {
+ std::string nl;
+ if (!af->getline(nl))
+ return false;
+ mychomp(nl);
+
+ iter = nl.begin();
+ i = 0;
+ np = 0;
+
+ // split line into pieces
+ start_piece = mystrsep(nl, iter);
+ while (start_piece != nl.end()) {
+ switch (i) {
+ // piece 1 - is type
+ case 0: {
+ np++;
+ if (ent != 0)
+ entry = affentries.add_entry((char)(aeXPRODUCT + aeUTF8 + aeALIASF + aeALIASM));
+ break;
+ }
+
+ // piece 2 - is affix char
+ case 1: {
+ np++;
+ std::string chunk(start_piece, iter);
+ if (pHMgr->decode_flag(chunk.c_str()) != aflag) {
+ char* err = pHMgr->encode_flag(aflag);
+ if (err) {
+ HUNSPELL_WARNING(stderr,
+ "error: line %d: affix %s is corrupt\n",
+ af->getlinenum(), err);
+ free(err);
+ }
+ return false;
+ }
+
+ if (ent != 0) {
+ AffEntry* start_entry = affentries.first_entry();
+ entry->aflag = start_entry->aflag;
+ }
+ break;
+ }
+
+ // piece 3 - is string to strip or 0 for null
+ case 2: {
+ np++;
+ entry->strip = std::string(start_piece, iter);
+ if (complexprefixes) {
+ if (utf8)
+ reverseword_utf(entry->strip);
+ else
+ reverseword(entry->strip);
+ }
+ if (entry->strip.compare("0") == 0) {
+ entry->strip.clear();
+ }
+ break;
+ }
+
+ // piece 4 - is affix string or 0 for null
+ case 3: {
+ entry->morphcode = NULL;
+ entry->contclass = NULL;
+ entry->contclasslen = 0;
+ np++;
+ std::string::const_iterator dash = std::find(start_piece, iter, '/');
+ if (dash != iter) {
+ entry->appnd = std::string(start_piece, dash);
+ std::string dash_str(dash + 1, iter);
+
+ if (!ignorechars.empty() && !has_no_ignored_chars(entry->appnd, ignorechars)) {
+ if (utf8) {
+ remove_ignored_chars_utf(entry->appnd, ignorechars_utf16);
+ } else {
+ remove_ignored_chars(entry->appnd, ignorechars);
+ }
+ }
+
+ if (complexprefixes) {
+ if (utf8)
+ reverseword_utf(entry->appnd);
+ else
+ reverseword(entry->appnd);
+ }
+
+ if (pHMgr->is_aliasf()) {
+ int index = atoi(dash_str.c_str());
+ entry->contclasslen = (unsigned short)pHMgr->get_aliasf(
+ index, &(entry->contclass), af);
+ if (!entry->contclasslen)
+ HUNSPELL_WARNING(stderr,
+ "error: bad affix flag alias: \"%s\"\n",
+ dash_str.c_str());
+ } else {
+ entry->contclasslen = (unsigned short)pHMgr->decode_flags(
+ &(entry->contclass), dash_str.c_str(), af);
+ std::sort(entry->contclass, entry->contclass + entry->contclasslen);
+ }
+
+ havecontclass = 1;
+ for (unsigned short _i = 0; _i < entry->contclasslen; _i++) {
+ contclasses[(entry->contclass)[_i]] = 1;
+ }
+ } else {
+ entry->appnd = std::string(start_piece, iter);
+
+ if (!ignorechars.empty() && !has_no_ignored_chars(entry->appnd, ignorechars)) {
+ if (utf8) {
+ remove_ignored_chars_utf(entry->appnd, ignorechars_utf16);
+ } else {
+ remove_ignored_chars(entry->appnd, ignorechars);
+ }
+ }
+
+ if (complexprefixes) {
+ if (utf8)
+ reverseword_utf(entry->appnd);
+ else
+ reverseword(entry->appnd);
+ }
+ }
+
+ if (entry->appnd.compare("0") == 0) {
+ entry->appnd.clear();
+ }
+ break;
+ }
+
+ // piece 5 - is the conditions descriptions
+ case 4: {
+ std::string chunk(start_piece, iter);
+ np++;
+ if (complexprefixes) {
+ if (utf8)
+ reverseword_utf(chunk);
+ else
+ reverseword(chunk);
+ reverse_condition(chunk);
+ }
+ if (!entry->strip.empty() && chunk != "." &&
+ redundant_condition(at, entry->strip.c_str(), entry->strip.size(), chunk.c_str(),
+ af->getlinenum()))
+ chunk = ".";
+ if (at == 'S') {
+ reverseword(chunk);
+ reverse_condition(chunk);
+ }
+ if (encodeit(*entry, chunk.c_str()))
+ return false;
+ break;
+ }
+
+ case 5: {
+ std::string chunk(start_piece, iter);
+ np++;
+ if (pHMgr->is_aliasm()) {
+ int index = atoi(chunk.c_str());
+ entry->morphcode = pHMgr->get_aliasm(index);
+ } else {
+ if (complexprefixes) { // XXX - fix me for morph. gen.
+ if (utf8)
+ reverseword_utf(chunk);
+ else
+ reverseword(chunk);
+ }
+ // add the remaining of the line
+ std::string::const_iterator end = nl.end();
+ if (iter != end) {
+ chunk.append(iter, end);
+ }
+ entry->morphcode = mystrdup(chunk.c_str());
+ if (!entry->morphcode)
+ return false;
+ }
+ break;
+ }
+ default:
+ break;
+ }
+ i++;
+ start_piece = mystrsep(nl, iter);
+ }
+ // check to make sure we parsed enough pieces
+ if (np < 4) {
+ char* err = pHMgr->encode_flag(aflag);
+ if (err) {
+ HUNSPELL_WARNING(stderr, "error: line %d: affix %s is corrupt\n",
+ af->getlinenum(), err);
+ free(err);
+ }
+ return false;
+ }
+
+#ifdef DEBUG
+ // detect unnecessary fields, excepting comments
+ if (basefieldnum) {
+ int fieldnum =
+ !(entry->morphcode) ? 5 : ((*(entry->morphcode) == '#') ? 5 : 6);
+ if (fieldnum != basefieldnum)
+ HUNSPELL_WARNING(stderr, "warning: line %d: bad field number\n",
+ af->getlinenum());
+ } else {
+ basefieldnum =
+ !(entry->morphcode) ? 5 : ((*(entry->morphcode) == '#') ? 5 : 6);
+ }
+#endif
+ }
+
+ // now create SfxEntry or PfxEntry objects and use links to
+ // build an ordered (sorted by affix string) list
+ std::vector<AffEntry*>::iterator start = affentries.begin();
+ std::vector<AffEntry*>::iterator end = affentries.end();
+ for (std::vector<AffEntry*>::iterator affentry = start; affentry != end; ++affentry) {
+ if (at == 'P') {
+ build_pfxtree(static_cast<PfxEntry*>(*affentry));
+ } else {
+ build_sfxtree(static_cast<SfxEntry*>(*affentry));
+ }
+ }
+
+ //contents belong to AffixMgr now
+ affentries.release();
+
+ return true;
+}
+
+int AffixMgr::redundant_condition(char ft,
+ const char* strip,
+ int stripl,
+ const char* cond,
+ int linenum) {
+ int condl = strlen(cond);
+ int i;
+ int j;
+ int neg;
+ int in;
+ if (ft == 'P') { // prefix
+ if (strncmp(strip, cond, condl) == 0)
+ return 1;
+ if (utf8) {
+ } else {
+ for (i = 0, j = 0; (i < stripl) && (j < condl); i++, j++) {
+ if (cond[j] != '[') {
+ if (cond[j] != strip[i]) {
+ HUNSPELL_WARNING(stderr,
+ "warning: line %d: incompatible stripping "
+ "characters and condition\n",
+ linenum);
+ return 0;
+ }
+ } else {
+ neg = (cond[j + 1] == '^') ? 1 : 0;
+ in = 0;
+ do {
+ j++;
+ if (strip[i] == cond[j])
+ in = 1;
+ } while ((j < (condl - 1)) && (cond[j] != ']'));
+ if (j == (condl - 1) && (cond[j] != ']')) {
+ HUNSPELL_WARNING(stderr,
+ "error: line %d: missing ] in condition:\n%s\n",
+ linenum, cond);
+ return 0;
+ }
+ if ((!neg && !in) || (neg && in)) {
+ HUNSPELL_WARNING(stderr,
+ "warning: line %d: incompatible stripping "
+ "characters and condition\n",
+ linenum);
+ return 0;
+ }
+ }
+ }
+ if (j >= condl)
+ return 1;
+ }
+ } else { // suffix
+ if ((stripl >= condl) && strcmp(strip + stripl - condl, cond) == 0)
+ return 1;
+ if (utf8) {
+ } else {
+ for (i = stripl - 1, j = condl - 1; (i >= 0) && (j >= 0); i--, j--) {
+ if (cond[j] != ']') {
+ if (cond[j] != strip[i]) {
+ HUNSPELL_WARNING(stderr,
+ "warning: line %d: incompatible stripping "
+ "characters and condition\n",
+ linenum);
+ return 0;
+ }
+ } else {
+ in = 0;
+ do {
+ j--;
+ if (strip[i] == cond[j])
+ in = 1;
+ } while ((j > 0) && (cond[j] != '['));
+ if ((j == 0) && (cond[j] != '[')) {
+ HUNSPELL_WARNING(stderr,
+ "error: line: %d: missing ] in condition:\n%s\n",
+ linenum, cond);
+ return 0;
+ }
+ neg = (cond[j + 1] == '^') ? 1 : 0;
+ if ((!neg && !in) || (neg && in)) {
+ HUNSPELL_WARNING(stderr,
+ "warning: line %d: incompatible stripping "
+ "characters and condition\n",
+ linenum);
+ return 0;
+ }
+ }
+ }
+ if (j < 0)
+ return 1;
+ }
+ }
+ return 0;
+}
+
+std::vector<std::string> AffixMgr::get_suffix_words(short unsigned* suff,
+ int len,
+ const char* root_word) {
+ std::vector<std::string> slst;
+ short unsigned* start_ptr = suff;
+ for (int j = 0; j < SETSIZE; j++) {
+ SfxEntry* ptr = sStart[j];
+ while (ptr) {
+ suff = start_ptr;
+ for (int i = 0; i < len; i++) {
+ if ((*suff) == ptr->getFlag()) {
+ std::string nw(root_word);
+ nw.append(ptr->getAffix());
+ hentry* ht = ptr->checkword(nw.c_str(), nw.size(), 0, NULL, 0, 0, 0);
+ if (ht) {
+ slst.push_back(nw);
+ }
+ }
+ suff++;
+ }
+ ptr = ptr->getNext();
+ }
+ }
+ return slst;
+}
diff --git a/extensions/spellcheck/hunspell/src/affixmgr.hxx b/extensions/spellcheck/hunspell/src/affixmgr.hxx
new file mode 100644
index 0000000000..450f50a65c
--- /dev/null
+++ b/extensions/spellcheck/hunspell/src/affixmgr.hxx
@@ -0,0 +1,368 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * Copyright (C) 2002-2022 N辿meth L叩szl坦
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (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.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * Hunspell is based on MySpell which is Copyright (C) 2002 Kevin Hendricks.
+ *
+ * Contributor(s): David Einstein, Davide Prina, Giuseppe Modugno,
+ * Gianluca Turconi, Simon Brouwer, Noll J叩nos, B鱈r坦 rp叩d,
+ * Goldman Eleon坦ra, Sarl坦s Tam叩s, Bencs叩th Boldizs叩r, Hal叩csy P辿ter,
+ * Dvornik L叩szl坦, Gefferth Andr叩s, Nagy Viktor, Varga D叩niel, Chris Halls,
+ * Rene Engelhard, Bram Moolenaar, Dafydd Jones, Harri Pitk辰nen
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+/*
+ * Copyright 2002 Kevin B. Hendricks, Stratford, Ontario, Canada
+ * And Contributors. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. All modifications to the source code must be clearly marked as
+ * such. Binary redistributions based on modified source code
+ * must be clearly marked as modified versions in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY KEVIN B. HENDRICKS AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
+ * KEVIN B. HENDRICKS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef AFFIXMGR_HXX_
+#define AFFIXMGR_HXX_
+
+#include <stdio.h>
+
+#include <string>
+#include <vector>
+
+#include "atypes.hxx"
+#include "baseaffix.hxx"
+#include "hashmgr.hxx"
+#include "phonet.hxx"
+#include "replist.hxx"
+
+// check flag duplication
+#define dupSFX (1 << 0)
+#define dupPFX (1 << 1)
+
+class PfxEntry;
+class SfxEntry;
+
+class AffixMgr {
+ PfxEntry* pStart[SETSIZE];
+ SfxEntry* sStart[SETSIZE];
+ PfxEntry* pFlag[SETSIZE];
+ SfxEntry* sFlag[SETSIZE];
+ const std::vector<HashMgr*>& alldic;
+ const HashMgr* pHMgr;
+ std::string keystring;
+ std::string trystring;
+ std::string encoding;
+ struct cs_info* csconv;
+ int utf8;
+ int complexprefixes;
+ FLAG compoundflag;
+ FLAG compoundbegin;
+ FLAG compoundmiddle;
+ FLAG compoundend;
+ FLAG compoundroot;
+ FLAG compoundforbidflag;
+ FLAG compoundpermitflag;
+ int compoundmoresuffixes;
+ int checkcompounddup;
+ int checkcompoundrep;
+ int checkcompoundcase;
+ int checkcompoundtriple;
+ int simplifiedtriple;
+ FLAG forbiddenword;
+ FLAG nosuggest;
+ FLAG nongramsuggest;
+ FLAG needaffix;
+ int cpdmin;
+ RepList* iconvtable;
+ RepList* oconvtable;
+ bool parsedmaptable;
+ std::vector<mapentry> maptable;
+ bool parsedbreaktable;
+ std::vector<std::string> breaktable;
+ bool parsedcheckcpd;
+ std::vector<patentry> checkcpdtable;
+ int simplifiedcpd;
+ bool parseddefcpd;
+ std::vector<flagentry> defcpdtable;
+ phonetable* phone;
+ int maxngramsugs;
+ int maxcpdsugs;
+ int maxdiff;
+ int onlymaxdiff;
+ int nosplitsugs;
+ int sugswithdots;
+ int cpdwordmax;
+ int cpdmaxsyllable;
+ std::string cpdvowels; // vowels (for calculating of Hungarian compounding limit,
+ std::vector<w_char> cpdvowels_utf16; //vowels for UTF-8 encoding
+ std::string cpdsyllablenum; // syllable count incrementing flag
+ const char* pfxappnd; // BUG: not stateless
+ const char* sfxappnd; // BUG: not stateless
+ int sfxextra; // BUG: not stateless
+ FLAG sfxflag; // BUG: not stateless
+ char* derived; // BUG: not stateless
+ SfxEntry* sfx; // BUG: not stateless
+ PfxEntry* pfx; // BUG: not stateless
+ int checknum;
+ std::string wordchars; // letters + spec. word characters
+ std::vector<w_char> wordchars_utf16;
+ std::string ignorechars; // letters + spec. word characters
+ std::vector<w_char> ignorechars_utf16;
+ std::string version; // affix and dictionary file version string
+ std::string lang; // language
+ int langnum;
+ FLAG lemma_present;
+ FLAG circumfix;
+ FLAG onlyincompound;
+ FLAG keepcase;
+ FLAG forceucase;
+ FLAG warn;
+ int forbidwarn;
+ FLAG substandard;
+ int checksharps;
+ int fullstrip;
+
+ int havecontclass; // boolean variable
+ char contclasses[CONTSIZE]; // flags of possible continuing classes (twofold
+ // affix)
+
+ public:
+ AffixMgr(const char* affpath, const std::vector<HashMgr*>& ptr, const char* key = NULL);
+ ~AffixMgr();
+ struct hentry* affix_check(const char* word,
+ int len,
+ const unsigned short needflag = (unsigned short)0,
+ char in_compound = IN_CPD_NOT);
+ struct hentry* prefix_check(const char* word,
+ int len,
+ char in_compound,
+ const FLAG needflag = FLAG_NULL);
+ inline int isSubset(const char* s1, const char* s2);
+ struct hentry* prefix_check_twosfx(const char* word,
+ int len,
+ char in_compound,
+ const FLAG needflag = FLAG_NULL);
+ inline int isRevSubset(const char* s1, const char* end_of_s2, int len);
+ struct hentry* suffix_check(const char* word,
+ int len,
+ int sfxopts,
+ PfxEntry* ppfx,
+ const FLAG cclass = FLAG_NULL,
+ const FLAG needflag = FLAG_NULL,
+ char in_compound = IN_CPD_NOT);
+ struct hentry* suffix_check_twosfx(const char* word,
+ int len,
+ int sfxopts,
+ PfxEntry* ppfx,
+ const FLAG needflag = FLAG_NULL);
+
+ std::string affix_check_morph(const char* word,
+ int len,
+ const FLAG needflag = FLAG_NULL,
+ char in_compound = IN_CPD_NOT);
+ std::string prefix_check_morph(const char* word,
+ int len,
+ char in_compound,
+ const FLAG needflag = FLAG_NULL);
+ std::string suffix_check_morph(const char* word,
+ int len,
+ int sfxopts,
+ PfxEntry* ppfx,
+ const FLAG cclass = FLAG_NULL,
+ const FLAG needflag = FLAG_NULL,
+ char in_compound = IN_CPD_NOT);
+
+ std::string prefix_check_twosfx_morph(const char* word,
+ int len,
+ char in_compound,
+ const FLAG needflag = FLAG_NULL);
+ std::string suffix_check_twosfx_morph(const char* word,
+ int len,
+ int sfxopts,
+ PfxEntry* ppfx,
+ const FLAG needflag = FLAG_NULL);
+
+ std::string morphgen(const char* ts,
+ int wl,
+ const unsigned short* ap,
+ unsigned short al,
+ const char* morph,
+ const char* targetmorph,
+ int level);
+
+ int expand_rootword(struct guessword* wlst,
+ int maxn,
+ const char* ts,
+ int wl,
+ const unsigned short* ap,
+ unsigned short al,
+ const char* bad,
+ int,
+ const char*);
+
+ short get_syllable(const std::string& word);
+ int cpdrep_check(const char* word, int len);
+ int cpdwordpair_check(const char * word, int len);
+ int cpdpat_check(const char* word,
+ int len,
+ hentry* r1,
+ hentry* r2,
+ const char affixed);
+ int defcpd_check(hentry*** words,
+ short wnum,
+ hentry* rv,
+ hentry** rwords,
+ char all);
+ int cpdcase_check(const char* word, int len);
+ inline int candidate_check(const char* word, int len);
+ void setcminmax(int* cmin, int* cmax, const char* word, int len);
+ struct hentry* compound_check(const std::string& word,
+ short wordnum,
+ short numsyllable,
+ short maxwordnum,
+ short wnum,
+ hentry** words,
+ hentry** rwords,
+ char hu_mov_rule,
+ char is_sug,
+ int* info);
+
+ int compound_check_morph(const char* word,
+ int len,
+ short wordnum,
+ short numsyllable,
+ short maxwordnum,
+ short wnum,
+ hentry** words,
+ hentry** rwords,
+ char hu_mov_rule,
+ std::string& result,
+ const std::string* partresult);
+
+ std::vector<std::string> get_suffix_words(short unsigned* suff,
+ int len,
+ const char* root_word);
+
+ struct hentry* lookup(const char* word);
+ const std::vector<replentry>& get_reptable() const;
+ RepList* get_iconvtable() const;
+ RepList* get_oconvtable() const;
+ struct phonetable* get_phonetable() const;
+ const std::vector<mapentry>& get_maptable() const;
+ const std::vector<std::string>& get_breaktable() const;
+ const std::string& get_encoding();
+ int get_langnum() const;
+ char* get_key_string();
+ char* get_try_string() const;
+ const std::string& get_wordchars() const;
+ const std::vector<w_char>& get_wordchars_utf16() const;
+ const char* get_ignore() const;
+ const std::vector<w_char>& get_ignore_utf16() const;
+ int get_compound() const;
+ FLAG get_compoundflag() const;
+ FLAG get_forbiddenword() const;
+ FLAG get_nosuggest() const;
+ FLAG get_nongramsuggest() const;
+ FLAG get_substandard() const;
+ FLAG get_needaffix() const;
+ FLAG get_onlyincompound() const;
+ const char* get_derived() const;
+ const std::string& get_version() const;
+ int have_contclass() const;
+ int get_utf8() const;
+ int get_complexprefixes() const;
+ char* get_suffixed(char) const;
+ int get_maxngramsugs() const;
+ int get_maxcpdsugs() const;
+ int get_maxdiff() const;
+ int get_onlymaxdiff() const;
+ int get_nosplitsugs() const;
+ int get_sugswithdots(void) const;
+ FLAG get_keepcase(void) const;
+ FLAG get_forceucase(void) const;
+ FLAG get_warn(void) const;
+ int get_forbidwarn(void) const;
+ int get_checksharps(void) const;
+ char* encode_flag(unsigned short aflag) const;
+ int get_fullstrip() const;
+
+ private:
+ int parse_file(const char* affpath, const char* key);
+ bool parse_flag(const std::string& line, unsigned short* out, FileMgr* af);
+ bool parse_num(const std::string& line, int* out, FileMgr* af);
+ bool parse_cpdsyllable(const std::string& line, FileMgr* af);
+ bool parse_convtable(const std::string& line,
+ FileMgr* af,
+ RepList** rl,
+ const std::string& keyword);
+ bool parse_phonetable(const std::string& line, FileMgr* af);
+ bool parse_maptable(const std::string& line, FileMgr* af);
+ bool parse_breaktable(const std::string& line, FileMgr* af);
+ bool parse_checkcpdtable(const std::string& line, FileMgr* af);
+ bool parse_defcpdtable(const std::string& line, FileMgr* af);
+ bool parse_affix(const std::string& line, const char at, FileMgr* af, char* dupflags);
+
+ void reverse_condition(std::string&);
+ std::string& debugflag(std::string& result, unsigned short flag);
+ int condlen(const char*);
+ int encodeit(AffEntry& entry, const char* cs);
+ int build_pfxtree(PfxEntry* pfxptr);
+ int build_sfxtree(SfxEntry* sfxptr);
+ int process_pfx_order();
+ int process_sfx_order();
+ PfxEntry* process_pfx_in_order(PfxEntry* ptr, PfxEntry* nptr);
+ SfxEntry* process_sfx_in_order(SfxEntry* ptr, SfxEntry* nptr);
+ int process_pfx_tree_to_list();
+ int process_sfx_tree_to_list();
+ int redundant_condition(char, const char* strip, int stripl, const char* cond, int);
+ void finishFileMgr(FileMgr* afflst);
+};
+
+#endif
diff --git a/extensions/spellcheck/hunspell/src/atypes.hxx b/extensions/spellcheck/hunspell/src/atypes.hxx
new file mode 100644
index 0000000000..1b78d4724b
--- /dev/null
+++ b/extensions/spellcheck/hunspell/src/atypes.hxx
@@ -0,0 +1,129 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * Copyright (C) 2002-2022 N辿meth L叩szl坦
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (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.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * Hunspell is based on MySpell which is Copyright (C) 2002 Kevin Hendricks.
+ *
+ * Contributor(s): David Einstein, Davide Prina, Giuseppe Modugno,
+ * Gianluca Turconi, Simon Brouwer, Noll J叩nos, B鱈r坦 rp叩d,
+ * Goldman Eleon坦ra, Sarl坦s Tam叩s, Bencs叩th Boldizs叩r, Hal叩csy P辿ter,
+ * Dvornik L叩szl坦, Gefferth Andr叩s, Nagy Viktor, Varga D叩niel, Chris Halls,
+ * Rene Engelhard, Bram Moolenaar, Dafydd Jones, Harri Pitk辰nen
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#ifndef ATYPES_HXX_
+#define ATYPES_HXX_
+
+#ifndef HUNSPELL_WARNING
+#include <stdio.h>
+#ifdef HUNSPELL_WARNING_ON
+#define HUNSPELL_WARNING fprintf
+#else
+// empty inline function to switch off warnings (instead of the C99 standard
+// variadic macros)
+static inline void HUNSPELL_WARNING(FILE*, const char*, ...) {}
+#endif
+#endif
+
+// HUNSTEM def.
+#define HUNSTEM
+
+#include "w_char.hxx"
+#include <algorithm>
+#include <string>
+#include <vector>
+
+#define SETSIZE 256
+#define CONTSIZE 65536
+
+// AffEntry options
+#define aeXPRODUCT (1 << 0)
+#define aeUTF8 (1 << 1)
+#define aeALIASF (1 << 2)
+#define aeALIASM (1 << 3)
+#define aeLONGCOND (1 << 4)
+
+// compound options
+#define IN_CPD_NOT 0
+#define IN_CPD_BEGIN 1
+#define IN_CPD_END 2
+#define IN_CPD_OTHER 3
+
+// info options
+#define SPELL_COMPOUND (1 << 0)
+#define SPELL_FORBIDDEN (1 << 1)
+#define SPELL_ALLCAP (1 << 2)
+#define SPELL_NOCAP (1 << 3)
+#define SPELL_INITCAP (1 << 4)
+#define SPELL_ORIGCAP (1 << 5)
+#define SPELL_WARN (1 << 6)
+
+#define MINCPDLEN 3
+#define MAXCOMPOUND 10
+#define MAXCONDLEN 20
+#define MAXCONDLEN_1 (MAXCONDLEN - sizeof(char*))
+
+#define MAXACC 1000
+
+#define FLAG unsigned short
+#define FLAG_NULL 0x00
+#define FREE_FLAG(a) a = 0
+
+#define TESTAFF(a, b, c) (std::binary_search(a, a + c, b))
+
+// timelimit: max. ~1/4 sec (process time on Linux) for
+// for a suggestion, including max. ~/10 sec for a case
+// sensitive plain or compound word suggestion, within
+// ~1/20 sec long time consuming suggestion functions
+#define TIMELIMIT_GLOBAL (CLOCKS_PER_SEC / 4)
+#define TIMELIMIT_SUGGESTION (CLOCKS_PER_SEC / 10)
+#define TIMELIMIT (CLOCKS_PER_SEC / 20)
+#define MINTIMER 100
+#define MAXPLUSTIMER 100
+
+struct guessword {
+ char* word;
+ bool allow;
+ char* orig;
+};
+
+typedef std::vector<std::string> mapentry;
+typedef std::vector<FLAG> flagentry;
+
+struct patentry {
+ std::string pattern;
+ std::string pattern2;
+ std::string pattern3;
+ FLAG cond;
+ FLAG cond2;
+ patentry()
+ : cond(FLAG_NULL)
+ , cond2(FLAG_NULL) {
+ }
+};
+
+#endif
diff --git a/extensions/spellcheck/hunspell/src/baseaffix.hxx b/extensions/spellcheck/hunspell/src/baseaffix.hxx
new file mode 100644
index 0000000000..52cd60e028
--- /dev/null
+++ b/extensions/spellcheck/hunspell/src/baseaffix.hxx
@@ -0,0 +1,74 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * Copyright (C) 2002-2022 N辿meth L叩szl坦
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (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.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * Hunspell is based on MySpell which is Copyright (C) 2002 Kevin Hendricks.
+ *
+ * Contributor(s): David Einstein, Davide Prina, Giuseppe Modugno,
+ * Gianluca Turconi, Simon Brouwer, Noll J叩nos, B鱈r坦 rp叩d,
+ * Goldman Eleon坦ra, Sarl坦s Tam叩s, Bencs叩th Boldizs叩r, Hal叩csy P辿ter,
+ * Dvornik L叩szl坦, Gefferth Andr叩s, Nagy Viktor, Varga D叩niel, Chris Halls,
+ * Rene Engelhard, Bram Moolenaar, Dafydd Jones, Harri Pitk辰nen
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#ifndef BASEAFF_HXX_
+#define BASEAFF_HXX_
+
+#include <string>
+
+class AffEntry {
+ private:
+ AffEntry(const AffEntry&);
+ AffEntry& operator=(const AffEntry&);
+
+ public:
+ AffEntry()
+ : numconds(0),
+ opts(0),
+ aflag(0),
+ morphcode(0),
+ contclass(NULL),
+ contclasslen(0) {}
+ virtual ~AffEntry();
+ std::string appnd;
+ std::string strip;
+ unsigned char numconds;
+ char opts;
+ unsigned short aflag;
+ union {
+ char conds[MAXCONDLEN];
+ struct {
+ char conds1[MAXCONDLEN_1];
+ char* conds2;
+ } l;
+ } c;
+ char* morphcode;
+ unsigned short* contclass;
+ short contclasslen;
+};
+
+#endif
diff --git a/extensions/spellcheck/hunspell/src/csutil.cxx b/extensions/spellcheck/hunspell/src/csutil.cxx
new file mode 100644
index 0000000000..39a54d3802
--- /dev/null
+++ b/extensions/spellcheck/hunspell/src/csutil.cxx
@@ -0,0 +1,2551 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * Copyright (C) 2002-2022 N辿meth L叩szl坦
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (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.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * Hunspell is based on MySpell which is Copyright (C) 2002 Kevin Hendricks.
+ *
+ * Contributor(s): David Einstein, Davide Prina, Giuseppe Modugno,
+ * Gianluca Turconi, Simon Brouwer, Noll J叩nos, B鱈r坦 rp叩d,
+ * Goldman Eleon坦ra, Sarl坦s Tam叩s, Bencs叩th Boldizs叩r, Hal叩csy P辿ter,
+ * Dvornik L叩szl坦, Gefferth Andr叩s, Nagy Viktor, Varga D叩niel, Chris Halls,
+ * Rene Engelhard, Bram Moolenaar, Dafydd Jones, Harri Pitk辰nen
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+/*
+ * Copyright 2002 Kevin B. Hendricks, Stratford, Ontario, Canada
+ * And Contributors. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. All modifications to the source code must be clearly marked as
+ * such. Binary redistributions based on modified source code
+ * must be clearly marked as modified versions in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY KEVIN B. HENDRICKS AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
+ * KEVIN B. HENDRICKS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <algorithm>
+#include <assert.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+#include <ctype.h>
+#include <sstream>
+
+#include "csutil.hxx"
+#include "atypes.hxx"
+#include "langnum.hxx"
+
+#ifdef _WIN32
+#include <windows.h>
+#include <wchar.h>
+#endif
+
+#ifdef OPENOFFICEORG
+#include <unicode/uchar.h>
+#else
+#ifndef MOZILLA_CLIENT
+#include "utf_info.hxx"
+#define UTF_LST_LEN (sizeof(utf_lst) / (sizeof(unicode_info)))
+#endif
+#endif
+
+#ifdef MOZILLA_CLIENT
+#include "mozHunspellRLBoxGlue.h"
+#endif
+
+struct unicode_info2 {
+ char cletter;
+ unsigned short cupper;
+ unsigned short clower;
+};
+
+static struct unicode_info2* utf_tbl = NULL;
+static int utf_tbl_count =
+ 0; // utf_tbl can be used by multiple Hunspell instances
+
+#ifndef MOZILLA_CLIENT
+void myopen(std::ifstream& stream, const char* path, std::ios_base::openmode mode)
+{
+#if defined(_WIN32) && defined(_MSC_VER)
+#define WIN32_LONG_PATH_PREFIX "\\\\?\\"
+ if (strncmp(path, WIN32_LONG_PATH_PREFIX, 4) == 0) {
+ int len = MultiByteToWideChar(CP_UTF8, 0, path, -1, NULL, 0);
+ wchar_t* buff = new wchar_t[len];
+ wchar_t* buff2 = new wchar_t[len];
+ MultiByteToWideChar(CP_UTF8, 0, path, -1, buff, len);
+ if (_wfullpath(buff2, buff, len) != NULL) {
+ stream.open(buff2, mode);
+ }
+ delete [] buff;
+ delete [] buff2;
+ }
+ else
+#endif
+ stream.open(path, mode);
+}
+#endif
+
+std::string& u16_u8(std::string& dest, const std::vector<w_char>& src) {
+ dest.clear();
+ std::vector<w_char>::const_iterator u2 = src.begin();
+ std::vector<w_char>::const_iterator u2_max = src.end();
+ while (u2 < u2_max) {
+ signed char u8;
+ if (u2->h) { // > 0xFF
+ // XXX 4-byte haven't implemented yet.
+ if (u2->h >= 0x08) { // >= 0x800 (3-byte UTF-8 character)
+ u8 = 0xe0 + (u2->h >> 4);
+ dest.push_back(u8);
+ u8 = 0x80 + ((u2->h & 0xf) << 2) + (u2->l >> 6);
+ dest.push_back(u8);
+ u8 = 0x80 + (u2->l & 0x3f);
+ dest.push_back(u8);
+ } else { // < 0x800 (2-byte UTF-8 character)
+ u8 = 0xc0 + (u2->h << 2) + (u2->l >> 6);
+ dest.push_back(u8);
+ u8 = 0x80 + (u2->l & 0x3f);
+ dest.push_back(u8);
+ }
+ } else { // <= 0xFF
+ if (u2->l & 0x80) { // >0x80 (2-byte UTF-8 character)
+ u8 = 0xc0 + (u2->l >> 6);
+ dest.push_back(u8);
+ u8 = 0x80 + (u2->l & 0x3f);
+ dest.push_back(u8);
+ } else { // < 0x80 (1-byte UTF-8 character)
+ u8 = u2->l;
+ dest.push_back(u8);
+ }
+ }
+ ++u2;
+ }
+ return dest;
+}
+
+int u8_u16(std::vector<w_char>& dest, const std::string& src) {
+ dest.clear();
+ std::string::const_iterator u8 = src.begin();
+ std::string::const_iterator u8_max = src.end();
+
+ while (u8 < u8_max) {
+ w_char u2;
+ switch ((*u8) & 0xf0) {
+ case 0x00:
+ case 0x10:
+ case 0x20:
+ case 0x30:
+ case 0x40:
+ case 0x50:
+ case 0x60:
+ case 0x70: {
+ u2.h = 0;
+ u2.l = *u8;
+ break;
+ }
+ case 0x80:
+ case 0x90:
+ case 0xa0:
+ case 0xb0: {
+ HUNSPELL_WARNING(stderr,
+ "UTF-8 encoding error. Unexpected continuation bytes "
+ "in %ld. character position\n%s\n",
+ static_cast<long>(std::distance(src.begin(), u8)),
+ src.c_str());
+ u2.h = 0xff;
+ u2.l = 0xfd;
+ break;
+ }
+ case 0xc0:
+ case 0xd0: { // 2-byte UTF-8 codes
+ if ((*(u8 + 1) & 0xc0) == 0x80) {
+ u2.h = (*u8 & 0x1f) >> 2;
+ u2.l = (static_cast<unsigned char>(*u8) << 6) + (*(u8 + 1) & 0x3f);
+ ++u8;
+ } else {
+ HUNSPELL_WARNING(stderr,
+ "UTF-8 encoding error. Missing continuation byte in "
+ "%ld. character position:\n%s\n",
+ static_cast<long>(std::distance(src.begin(), u8)),
+ src.c_str());
+ u2.h = 0xff;
+ u2.l = 0xfd;
+ }
+ break;
+ }
+ case 0xe0: { // 3-byte UTF-8 codes
+ if ((*(u8 + 1) & 0xc0) == 0x80) {
+ u2.h = ((*u8 & 0x0f) << 4) + ((*(u8 + 1) & 0x3f) >> 2);
+ ++u8;
+ if ((*(u8 + 1) & 0xc0) == 0x80) {
+ u2.l = (static_cast<unsigned char>(*u8) << 6) + (*(u8 + 1) & 0x3f);
+ ++u8;
+ } else {
+ HUNSPELL_WARNING(stderr,
+ "UTF-8 encoding error. Missing continuation byte "
+ "in %ld. character position:\n%s\n",
+ static_cast<long>(std::distance(src.begin(), u8)),
+ src.c_str());
+ u2.h = 0xff;
+ u2.l = 0xfd;
+ }
+ } else {
+ HUNSPELL_WARNING(stderr,
+ "UTF-8 encoding error. Missing continuation byte in "
+ "%ld. character position:\n%s\n",
+ static_cast<long>(std::distance(src.begin(), u8)),
+ src.c_str());
+ u2.h = 0xff;
+ u2.l = 0xfd;
+ }
+ break;
+ }
+ case 0xf0: { // 4 or more byte UTF-8 codes
+ HUNSPELL_WARNING(stderr,
+ "This UTF-8 encoding can't convert to UTF-16:\n%s\n",
+ src.c_str());
+ u2.h = 0xff;
+ u2.l = 0xfd;
+ dest.push_back(u2);
+ return -1;
+ }
+ }
+ dest.push_back(u2);
+ ++u8;
+ }
+
+ return dest.size();
+}
+
+namespace {
+class is_any_of {
+ public:
+ explicit is_any_of(const std::string& in) : chars(in) {}
+
+ bool operator()(char c) { return chars.find(c) != std::string::npos; }
+
+ private:
+ std::string chars;
+};
+}
+
+std::string::const_iterator mystrsep(const std::string &str,
+ std::string::const_iterator& start) {
+ std::string::const_iterator end = str.end();
+
+ is_any_of op(" \t");
+ // don't use isspace() here, the string can be in some random charset
+ // that's way different than the locale's
+ std::string::const_iterator sp = start;
+ while (sp != end && op(*sp))
+ ++sp;
+
+ std::string::const_iterator dp = sp;
+ while (dp != end && !op(*dp))
+ ++dp;
+
+ start = dp;
+ return sp;
+}
+
+// replaces strdup with ansi version
+char* mystrdup(const char* s) {
+ char* d = NULL;
+ if (s) {
+ size_t sl = strlen(s) + 1;
+ d = (char*)malloc(sl);
+ if (d) {
+ memcpy(d, s, sl);
+ } else {
+ HUNSPELL_WARNING(stderr, "Can't allocate memory.\n");
+ }
+ }
+ return d;
+}
+
+// remove cross-platform text line end characters
+void mychomp(std::string& s) {
+ size_t k = s.size();
+ size_t newsize = k;
+ if ((k > 0) && ((s[k - 1] == '\r') || (s[k - 1] == '\n')))
+ --newsize;
+ if ((k > 1) && (s[k - 2] == '\r'))
+ --newsize;
+ s.resize(newsize);
+}
+
+// break text to lines
+std::vector<std::string> line_tok(const std::string& text, char breakchar) {
+ std::vector<std::string> ret;
+ if (text.empty()) {
+ return ret;
+ }
+
+ std::stringstream ss(text);
+ std::string tok;
+ while(std::getline(ss, tok, breakchar)) {
+ if (!tok.empty()) {
+ ret.push_back(tok);
+ }
+ }
+
+ return ret;
+}
+
+// uniq line in place
+void line_uniq(std::string& text, char breakchar)
+{
+ std::vector<std::string> lines = line_tok(text, breakchar);
+ text.clear();
+ if (lines.empty()) {
+ return;
+ }
+ text = lines[0];
+ for (size_t i = 1; i < lines.size(); ++i) {
+ bool dup = false;
+ for (size_t j = 0; j < i; ++j) {
+ if (lines[i] == lines[j]) {
+ dup = true;
+ break;
+ }
+ }
+ if (!dup) {
+ if (!text.empty())
+ text.push_back(breakchar);
+ text.append(lines[i]);
+ }
+ }
+}
+
+// uniq and boundary for compound analysis: "1\n\2\n\1" -> " ( \1 | \2 ) "
+void line_uniq_app(std::string& text, char breakchar) {
+ if (text.find(breakchar) == std::string::npos) {
+ return;
+ }
+
+ std::vector<std::string> lines = line_tok(text, breakchar);
+ text.clear();
+ if (lines.empty()) {
+ return;
+ }
+ text = lines[0];
+ for (size_t i = 1; i < lines.size(); ++i) {
+ bool dup = false;
+ for (size_t j = 0; j < i; ++j) {
+ if (lines[i] == lines[j]) {
+ dup = true;
+ break;
+ }
+ }
+ if (!dup) {
+ if (!text.empty())
+ text.push_back(breakchar);
+ text.append(lines[i]);
+ }
+ }
+
+ if (lines.size() == 1) {
+ text = lines[0];
+ return;
+ }
+
+ text.assign(" ( ");
+ for (size_t i = 0; i < lines.size(); ++i) {
+ text.append(lines[i]);
+ text.append(" | ");
+ }
+ text[text.size() - 2] = ')'; // " ) "
+}
+
+// append s to ends of every lines in text
+std::string& strlinecat(std::string& str, const std::string& apd) {
+ size_t pos = 0;
+ while ((pos = str.find('\n', pos)) != std::string::npos) {
+ str.insert(pos, apd);
+ pos += apd.length() + 1;
+ }
+ str.append(apd);
+ return str;
+}
+
+int fieldlen(const char* r) {
+ int n = 0;
+ while (r && *r != ' ' && *r != '\t' && *r != '\0' && *r != '\n') {
+ r++;
+ n++;
+ }
+ return n;
+}
+
+bool copy_field(std::string& dest,
+ const std::string& morph,
+ const std::string& var) {
+ if (morph.empty())
+ return false;
+ size_t pos = morph.find(var);
+ if (pos == std::string::npos)
+ return false;
+ dest.clear();
+ std::string beg(morph.substr(pos + MORPH_TAG_LEN, std::string::npos));
+
+ for (size_t i = 0; i < beg.size(); ++i) {
+ const char c(beg[i]);
+ if (c == ' ' || c == '\t' || c == '\n')
+ break;
+ dest.push_back(c);
+ }
+
+ return true;
+}
+
+std::string& mystrrep(std::string& str,
+ const std::string& search,
+ const std::string& replace) {
+ size_t pos = 0;
+ while ((pos = str.find(search, pos)) != std::string::npos) {
+ str.replace(pos, search.length(), replace);
+ pos += replace.length();
+ }
+ return str;
+}
+
+// reverse word
+size_t reverseword(std::string& word) {
+ std::reverse(word.begin(), word.end());
+ return word.size();
+}
+
+// reverse word
+size_t reverseword_utf(std::string& word) {
+ std::vector<w_char> w;
+ u8_u16(w, word);
+ std::reverse(w.begin(), w.end());
+ u16_u8(word, w);
+ return w.size();
+}
+
+void uniqlist(std::vector<std::string>& list) {
+ if (list.size() < 2)
+ return;
+
+ std::vector<std::string> ret;
+ ret.push_back(list[0]);
+
+ for (size_t i = 1; i < list.size(); ++i) {
+ if (std::find(ret.begin(), ret.end(), list[i]) == ret.end())
+ ret.push_back(list[i]);
+ }
+
+ list.swap(ret);
+}
+
+namespace {
+unsigned char cupper(const struct cs_info* csconv, int nIndex) {
+ assert(nIndex >= 0 && nIndex <= 255);
+ return csconv[nIndex].cupper;
+}
+
+unsigned char clower(const struct cs_info* csconv, int nIndex) {
+ assert(nIndex >= 0 && nIndex <= 255);
+ return csconv[nIndex].clower;
+}
+
+unsigned char ccase(const struct cs_info* csconv, int nIndex) {
+ assert(nIndex >= 0 && nIndex <= 255);
+ return csconv[nIndex].ccase;
+}
+}
+
+w_char upper_utf(w_char u, int langnum) {
+ unsigned short idx = (u.h << 8) + u.l;
+ unsigned short upridx = unicodetoupper(idx, langnum);
+ if (idx != upridx) {
+ u.h = (unsigned char)(upridx >> 8);
+ u.l = (unsigned char)(upridx & 0x00FF);
+ }
+ return u;
+}
+
+w_char lower_utf(w_char u, int langnum) {
+ unsigned short idx = (u.h << 8) + u.l;
+ unsigned short lwridx = unicodetolower(idx, langnum);
+ if (idx != lwridx) {
+ u.h = (unsigned char)(lwridx >> 8);
+ u.l = (unsigned char)(lwridx & 0x00FF);
+ }
+ return u;
+}
+
+// convert std::string to all caps
+std::string& mkallcap(std::string& s, const struct cs_info* csconv) {
+ for (std::string::iterator aI = s.begin(), aEnd = s.end(); aI != aEnd; ++aI) {
+ *aI = cupper(csconv, static_cast<unsigned char>(*aI));
+ }
+ return s;
+}
+
+// convert std::string to all little
+std::string& mkallsmall(std::string& s, const struct cs_info* csconv) {
+ for (std::string::iterator aI = s.begin(), aEnd = s.end(); aI != aEnd; ++aI) {
+ *aI = clower(csconv, static_cast<unsigned char>(*aI));
+ }
+ return s;
+}
+
+std::vector<w_char>& mkallsmall_utf(std::vector<w_char>& u,
+ int langnum) {
+ for (size_t i = 0; i < u.size(); ++i) {
+ unsigned short idx = (u[i].h << 8) + u[i].l;
+ unsigned short lwridx = unicodetolower(idx, langnum);
+ if (idx != lwridx) {
+ u[i].h = (unsigned char)(lwridx >> 8);
+ u[i].l = (unsigned char)(lwridx & 0x00FF);
+ }
+ }
+ return u;
+}
+
+std::vector<w_char>& mkallcap_utf(std::vector<w_char>& u, int langnum) {
+ for (size_t i = 0; i < u.size(); i++) {
+ unsigned short idx = (u[i].h << 8) + u[i].l;
+ unsigned short upridx = unicodetoupper(idx, langnum);
+ if (idx != upridx) {
+ u[i].h = (unsigned char)(upridx >> 8);
+ u[i].l = (unsigned char)(upridx & 0x00FF);
+ }
+ }
+ return u;
+}
+
+std::string& mkinitcap(std::string& s, const struct cs_info* csconv) {
+ if (!s.empty()) {
+ s[0] = cupper(csconv, static_cast<unsigned char>(s[0]));
+ }
+ return s;
+}
+
+std::vector<w_char>& mkinitcap_utf(std::vector<w_char>& u, int langnum) {
+ if (!u.empty()) {
+ unsigned short idx = (u[0].h << 8) + u[0].l;
+ unsigned short upridx = unicodetoupper(idx, langnum);
+ if (idx != upridx) {
+ u[0].h = (unsigned char)(upridx >> 8);
+ u[0].l = (unsigned char)(upridx & 0x00FF);
+ }
+ }
+ return u;
+}
+
+std::string& mkinitsmall(std::string& s, const struct cs_info* csconv) {
+ if (!s.empty()) {
+ s[0] = clower(csconv, static_cast<unsigned char>(s[0]));
+ }
+ return s;
+}
+
+std::vector<w_char>& mkinitsmall_utf(std::vector<w_char>& u, int langnum) {
+ if (!u.empty()) {
+ unsigned short idx = (u[0].h << 8) + u[0].l;
+ unsigned short lwridx = unicodetolower(idx, langnum);
+ if (idx != lwridx) {
+ u[0].h = (unsigned char)(lwridx >> 8);
+ u[0].l = (unsigned char)(lwridx & 0x00FF);
+ }
+ }
+ return u;
+}
+
+// conversion function for protected memory
+void store_pointer(char* dest, char* source) {
+ memcpy(dest, &source, sizeof(char*));
+}
+
+// conversion function for protected memory
+char* get_stored_pointer(const char* s) {
+ char* p;
+ memcpy(&p, s, sizeof(char*));
+ return p;
+}
+
+#ifndef MOZILLA_CLIENT
+
+// these are simple character mappings for the
+// encodings supported
+// supplying isupper, tolower, and toupper
+
+static struct cs_info iso1_tbl[] = {
+ {0x00, 0x00, 0x00}, {0x00, 0x01, 0x01}, {0x00, 0x02, 0x02},
+ {0x00, 0x03, 0x03}, {0x00, 0x04, 0x04}, {0x00, 0x05, 0x05},
+ {0x00, 0x06, 0x06}, {0x00, 0x07, 0x07}, {0x00, 0x08, 0x08},
+ {0x00, 0x09, 0x09}, {0x00, 0x0a, 0x0a}, {0x00, 0x0b, 0x0b},
+ {0x00, 0x0c, 0x0c}, {0x00, 0x0d, 0x0d}, {0x00, 0x0e, 0x0e},
+ {0x00, 0x0f, 0x0f}, {0x00, 0x10, 0x10}, {0x00, 0x11, 0x11},
+ {0x00, 0x12, 0x12}, {0x00, 0x13, 0x13}, {0x00, 0x14, 0x14},
+ {0x00, 0x15, 0x15}, {0x00, 0x16, 0x16}, {0x00, 0x17, 0x17},
+ {0x00, 0x18, 0x18}, {0x00, 0x19, 0x19}, {0x00, 0x1a, 0x1a},
+ {0x00, 0x1b, 0x1b}, {0x00, 0x1c, 0x1c}, {0x00, 0x1d, 0x1d},
+ {0x00, 0x1e, 0x1e}, {0x00, 0x1f, 0x1f}, {0x00, 0x20, 0x20},
+ {0x00, 0x21, 0x21}, {0x00, 0x22, 0x22}, {0x00, 0x23, 0x23},
+ {0x00, 0x24, 0x24}, {0x00, 0x25, 0x25}, {0x00, 0x26, 0x26},
+ {0x00, 0x27, 0x27}, {0x00, 0x28, 0x28}, {0x00, 0x29, 0x29},
+ {0x00, 0x2a, 0x2a}, {0x00, 0x2b, 0x2b}, {0x00, 0x2c, 0x2c},
+ {0x00, 0x2d, 0x2d}, {0x00, 0x2e, 0x2e}, {0x00, 0x2f, 0x2f},
+ {0x00, 0x30, 0x30}, {0x00, 0x31, 0x31}, {0x00, 0x32, 0x32},
+ {0x00, 0x33, 0x33}, {0x00, 0x34, 0x34}, {0x00, 0x35, 0x35},
+ {0x00, 0x36, 0x36}, {0x00, 0x37, 0x37}, {0x00, 0x38, 0x38},
+ {0x00, 0x39, 0x39}, {0x00, 0x3a, 0x3a}, {0x00, 0x3b, 0x3b},
+ {0x00, 0x3c, 0x3c}, {0x00, 0x3d, 0x3d}, {0x00, 0x3e, 0x3e},
+ {0x00, 0x3f, 0x3f}, {0x00, 0x40, 0x40}, {0x01, 0x61, 0x41},
+ {0x01, 0x62, 0x42}, {0x01, 0x63, 0x43}, {0x01, 0x64, 0x44},
+ {0x01, 0x65, 0x45}, {0x01, 0x66, 0x46}, {0x01, 0x67, 0x47},
+ {0x01, 0x68, 0x48}, {0x01, 0x69, 0x49}, {0x01, 0x6a, 0x4a},
+ {0x01, 0x6b, 0x4b}, {0x01, 0x6c, 0x4c}, {0x01, 0x6d, 0x4d},
+ {0x01, 0x6e, 0x4e}, {0x01, 0x6f, 0x4f}, {0x01, 0x70, 0x50},
+ {0x01, 0x71, 0x51}, {0x01, 0x72, 0x52}, {0x01, 0x73, 0x53},
+ {0x01, 0x74, 0x54}, {0x01, 0x75, 0x55}, {0x01, 0x76, 0x56},
+ {0x01, 0x77, 0x57}, {0x01, 0x78, 0x58}, {0x01, 0x79, 0x59},
+ {0x01, 0x7a, 0x5a}, {0x00, 0x5b, 0x5b}, {0x00, 0x5c, 0x5c},
+ {0x00, 0x5d, 0x5d}, {0x00, 0x5e, 0x5e}, {0x00, 0x5f, 0x5f},
+ {0x00, 0x60, 0x60}, {0x00, 0x61, 0x41}, {0x00, 0x62, 0x42},
+ {0x00, 0x63, 0x43}, {0x00, 0x64, 0x44}, {0x00, 0x65, 0x45},
+ {0x00, 0x66, 0x46}, {0x00, 0x67, 0x47}, {0x00, 0x68, 0x48},
+ {0x00, 0x69, 0x49}, {0x00, 0x6a, 0x4a}, {0x00, 0x6b, 0x4b},
+ {0x00, 0x6c, 0x4c}, {0x00, 0x6d, 0x4d}, {0x00, 0x6e, 0x4e},
+ {0x00, 0x6f, 0x4f}, {0x00, 0x70, 0x50}, {0x00, 0x71, 0x51},
+ {0x00, 0x72, 0x52}, {0x00, 0x73, 0x53}, {0x00, 0x74, 0x54},
+ {0x00, 0x75, 0x55}, {0x00, 0x76, 0x56}, {0x00, 0x77, 0x57},
+ {0x00, 0x78, 0x58}, {0x00, 0x79, 0x59}, {0x00, 0x7a, 0x5a},
+ {0x00, 0x7b, 0x7b}, {0x00, 0x7c, 0x7c}, {0x00, 0x7d, 0x7d},
+ {0x00, 0x7e, 0x7e}, {0x00, 0x7f, 0x7f}, {0x00, 0x80, 0x80},
+ {0x00, 0x81, 0x81}, {0x00, 0x82, 0x82}, {0x00, 0x83, 0x83},
+ {0x00, 0x84, 0x84}, {0x00, 0x85, 0x85}, {0x00, 0x86, 0x86},
+ {0x00, 0x87, 0x87}, {0x00, 0x88, 0x88}, {0x00, 0x89, 0x89},
+ {0x00, 0x8a, 0x8a}, {0x00, 0x8b, 0x8b}, {0x00, 0x8c, 0x8c},
+ {0x00, 0x8d, 0x8d}, {0x00, 0x8e, 0x8e}, {0x00, 0x8f, 0x8f},
+ {0x00, 0x90, 0x90}, {0x00, 0x91, 0x91}, {0x00, 0x92, 0x92},
+ {0x00, 0x93, 0x93}, {0x00, 0x94, 0x94}, {0x00, 0x95, 0x95},
+ {0x00, 0x96, 0x96}, {0x00, 0x97, 0x97}, {0x00, 0x98, 0x98},
+ {0x00, 0x99, 0x99}, {0x00, 0x9a, 0x9a}, {0x00, 0x9b, 0x9b},
+ {0x00, 0x9c, 0x9c}, {0x00, 0x9d, 0x9d}, {0x00, 0x9e, 0x9e},
+ {0x00, 0x9f, 0x9f}, {0x00, 0xa0, 0xa0}, {0x00, 0xa1, 0xa1},
+ {0x00, 0xa2, 0xa2}, {0x00, 0xa3, 0xa3}, {0x00, 0xa4, 0xa4},
+ {0x00, 0xa5, 0xa5}, {0x00, 0xa6, 0xa6}, {0x00, 0xa7, 0xa7},
+ {0x00, 0xa8, 0xa8}, {0x00, 0xa9, 0xa9}, {0x00, 0xaa, 0xaa},
+ {0x00, 0xab, 0xab}, {0x00, 0xac, 0xac}, {0x00, 0xad, 0xad},
+ {0x00, 0xae, 0xae}, {0x00, 0xaf, 0xaf}, {0x00, 0xb0, 0xb0},
+ {0x00, 0xb1, 0xb1}, {0x00, 0xb2, 0xb2}, {0x00, 0xb3, 0xb3},
+ {0x00, 0xb4, 0xb4}, {0x00, 0xb5, 0xb5}, {0x00, 0xb6, 0xb6},
+ {0x00, 0xb7, 0xb7}, {0x00, 0xb8, 0xb8}, {0x00, 0xb9, 0xb9},
+ {0x00, 0xba, 0xba}, {0x00, 0xbb, 0xbb}, {0x00, 0xbc, 0xbc},
+ {0x00, 0xbd, 0xbd}, {0x00, 0xbe, 0xbe}, {0x00, 0xbf, 0xbf},
+ {0x01, 0xe0, 0xc0}, {0x01, 0xe1, 0xc1}, {0x01, 0xe2, 0xc2},
+ {0x01, 0xe3, 0xc3}, {0x01, 0xe4, 0xc4}, {0x01, 0xe5, 0xc5},
+ {0x01, 0xe6, 0xc6}, {0x01, 0xe7, 0xc7}, {0x01, 0xe8, 0xc8},
+ {0x01, 0xe9, 0xc9}, {0x01, 0xea, 0xca}, {0x01, 0xeb, 0xcb},
+ {0x01, 0xec, 0xcc}, {0x01, 0xed, 0xcd}, {0x01, 0xee, 0xce},
+ {0x01, 0xef, 0xcf}, {0x01, 0xf0, 0xd0}, {0x01, 0xf1, 0xd1},
+ {0x01, 0xf2, 0xd2}, {0x01, 0xf3, 0xd3}, {0x01, 0xf4, 0xd4},
+ {0x01, 0xf5, 0xd5}, {0x01, 0xf6, 0xd6}, {0x00, 0xd7, 0xd7},
+ {0x01, 0xf8, 0xd8}, {0x01, 0xf9, 0xd9}, {0x01, 0xfa, 0xda},
+ {0x01, 0xfb, 0xdb}, {0x01, 0xfc, 0xdc}, {0x01, 0xfd, 0xdd},
+ {0x01, 0xfe, 0xde}, {0x00, 0xdf, 0xdf}, {0x00, 0xe0, 0xc0},
+ {0x00, 0xe1, 0xc1}, {0x00, 0xe2, 0xc2}, {0x00, 0xe3, 0xc3},
+ {0x00, 0xe4, 0xc4}, {0x00, 0xe5, 0xc5}, {0x00, 0xe6, 0xc6},
+ {0x00, 0xe7, 0xc7}, {0x00, 0xe8, 0xc8}, {0x00, 0xe9, 0xc9},
+ {0x00, 0xea, 0xca}, {0x00, 0xeb, 0xcb}, {0x00, 0xec, 0xcc},
+ {0x00, 0xed, 0xcd}, {0x00, 0xee, 0xce}, {0x00, 0xef, 0xcf},
+ {0x00, 0xf0, 0xd0}, {0x00, 0xf1, 0xd1}, {0x00, 0xf2, 0xd2},
+ {0x00, 0xf3, 0xd3}, {0x00, 0xf4, 0xd4}, {0x00, 0xf5, 0xd5},
+ {0x00, 0xf6, 0xd6}, {0x00, 0xf7, 0xf7}, {0x00, 0xf8, 0xd8},
+ {0x00, 0xf9, 0xd9}, {0x00, 0xfa, 0xda}, {0x00, 0xfb, 0xdb},
+ {0x00, 0xfc, 0xdc}, {0x00, 0xfd, 0xdd}, {0x00, 0xfe, 0xde},
+ {0x00, 0xff, 0xff}};
+
+static struct cs_info iso2_tbl[] = {
+ {0x00, 0x00, 0x00}, {0x00, 0x01, 0x01}, {0x00, 0x02, 0x02},
+ {0x00, 0x03, 0x03}, {0x00, 0x04, 0x04}, {0x00, 0x05, 0x05},
+ {0x00, 0x06, 0x06}, {0x00, 0x07, 0x07}, {0x00, 0x08, 0x08},
+ {0x00, 0x09, 0x09}, {0x00, 0x0a, 0x0a}, {0x00, 0x0b, 0x0b},
+ {0x00, 0x0c, 0x0c}, {0x00, 0x0d, 0x0d}, {0x00, 0x0e, 0x0e},
+ {0x00, 0x0f, 0x0f}, {0x00, 0x10, 0x10}, {0x00, 0x11, 0x11},
+ {0x00, 0x12, 0x12}, {0x00, 0x13, 0x13}, {0x00, 0x14, 0x14},
+ {0x00, 0x15, 0x15}, {0x00, 0x16, 0x16}, {0x00, 0x17, 0x17},
+ {0x00, 0x18, 0x18}, {0x00, 0x19, 0x19}, {0x00, 0x1a, 0x1a},
+ {0x00, 0x1b, 0x1b}, {0x00, 0x1c, 0x1c}, {0x00, 0x1d, 0x1d},
+ {0x00, 0x1e, 0x1e}, {0x00, 0x1f, 0x1f}, {0x00, 0x20, 0x20},
+ {0x00, 0x21, 0x21}, {0x00, 0x22, 0x22}, {0x00, 0x23, 0x23},
+ {0x00, 0x24, 0x24}, {0x00, 0x25, 0x25}, {0x00, 0x26, 0x26},
+ {0x00, 0x27, 0x27}, {0x00, 0x28, 0x28}, {0x00, 0x29, 0x29},
+ {0x00, 0x2a, 0x2a}, {0x00, 0x2b, 0x2b}, {0x00, 0x2c, 0x2c},
+ {0x00, 0x2d, 0x2d}, {0x00, 0x2e, 0x2e}, {0x00, 0x2f, 0x2f},
+ {0x00, 0x30, 0x30}, {0x00, 0x31, 0x31}, {0x00, 0x32, 0x32},
+ {0x00, 0x33, 0x33}, {0x00, 0x34, 0x34}, {0x00, 0x35, 0x35},
+ {0x00, 0x36, 0x36}, {0x00, 0x37, 0x37}, {0x00, 0x38, 0x38},
+ {0x00, 0x39, 0x39}, {0x00, 0x3a, 0x3a}, {0x00, 0x3b, 0x3b},
+ {0x00, 0x3c, 0x3c}, {0x00, 0x3d, 0x3d}, {0x00, 0x3e, 0x3e},
+ {0x00, 0x3f, 0x3f}, {0x00, 0x40, 0x40}, {0x01, 0x61, 0x41},
+ {0x01, 0x62, 0x42}, {0x01, 0x63, 0x43}, {0x01, 0x64, 0x44},
+ {0x01, 0x65, 0x45}, {0x01, 0x66, 0x46}, {0x01, 0x67, 0x47},
+ {0x01, 0x68, 0x48}, {0x01, 0x69, 0x49}, {0x01, 0x6a, 0x4a},
+ {0x01, 0x6b, 0x4b}, {0x01, 0x6c, 0x4c}, {0x01, 0x6d, 0x4d},
+ {0x01, 0x6e, 0x4e}, {0x01, 0x6f, 0x4f}, {0x01, 0x70, 0x50},
+ {0x01, 0x71, 0x51}, {0x01, 0x72, 0x52}, {0x01, 0x73, 0x53},
+ {0x01, 0x74, 0x54}, {0x01, 0x75, 0x55}, {0x01, 0x76, 0x56},
+ {0x01, 0x77, 0x57}, {0x01, 0x78, 0x58}, {0x01, 0x79, 0x59},
+ {0x01, 0x7a, 0x5a}, {0x00, 0x5b, 0x5b}, {0x00, 0x5c, 0x5c},
+ {0x00, 0x5d, 0x5d}, {0x00, 0x5e, 0x5e}, {0x00, 0x5f, 0x5f},
+ {0x00, 0x60, 0x60}, {0x00, 0x61, 0x41}, {0x00, 0x62, 0x42},
+ {0x00, 0x63, 0x43}, {0x00, 0x64, 0x44}, {0x00, 0x65, 0x45},
+ {0x00, 0x66, 0x46}, {0x00, 0x67, 0x47}, {0x00, 0x68, 0x48},
+ {0x00, 0x69, 0x49}, {0x00, 0x6a, 0x4a}, {0x00, 0x6b, 0x4b},
+ {0x00, 0x6c, 0x4c}, {0x00, 0x6d, 0x4d}, {0x00, 0x6e, 0x4e},
+ {0x00, 0x6f, 0x4f}, {0x00, 0x70, 0x50}, {0x00, 0x71, 0x51},
+ {0x00, 0x72, 0x52}, {0x00, 0x73, 0x53}, {0x00, 0x74, 0x54},
+ {0x00, 0x75, 0x55}, {0x00, 0x76, 0x56}, {0x00, 0x77, 0x57},
+ {0x00, 0x78, 0x58}, {0x00, 0x79, 0x59}, {0x00, 0x7a, 0x5a},
+ {0x00, 0x7b, 0x7b}, {0x00, 0x7c, 0x7c}, {0x00, 0x7d, 0x7d},
+ {0x00, 0x7e, 0x7e}, {0x00, 0x7f, 0x7f}, {0x00, 0x80, 0x80},
+ {0x00, 0x81, 0x81}, {0x00, 0x82, 0x82}, {0x00, 0x83, 0x83},
+ {0x00, 0x84, 0x84}, {0x00, 0x85, 0x85}, {0x00, 0x86, 0x86},
+ {0x00, 0x87, 0x87}, {0x00, 0x88, 0x88}, {0x00, 0x89, 0x89},
+ {0x00, 0x8a, 0x8a}, {0x00, 0x8b, 0x8b}, {0x00, 0x8c, 0x8c},
+ {0x00, 0x8d, 0x8d}, {0x00, 0x8e, 0x8e}, {0x00, 0x8f, 0x8f},
+ {0x00, 0x90, 0x90}, {0x00, 0x91, 0x91}, {0x00, 0x92, 0x92},
+ {0x00, 0x93, 0x93}, {0x00, 0x94, 0x94}, {0x00, 0x95, 0x95},
+ {0x00, 0x96, 0x96}, {0x00, 0x97, 0x97}, {0x00, 0x98, 0x98},
+ {0x00, 0x99, 0x99}, {0x00, 0x9a, 0x9a}, {0x00, 0x9b, 0x9b},
+ {0x00, 0x9c, 0x9c}, {0x00, 0x9d, 0x9d}, {0x00, 0x9e, 0x9e},
+ {0x00, 0x9f, 0x9f}, {0x00, 0xa0, 0xa0}, {0x01, 0xb1, 0xa1},
+ {0x00, 0xa2, 0xa2}, {0x01, 0xb3, 0xa3}, {0x00, 0xa4, 0xa4},
+ {0x01, 0xb5, 0xa5}, {0x01, 0xb6, 0xa6}, {0x00, 0xa7, 0xa7},
+ {0x00, 0xa8, 0xa8}, {0x01, 0xb9, 0xa9}, {0x01, 0xba, 0xaa},
+ {0x01, 0xbb, 0xab}, {0x01, 0xbc, 0xac}, {0x00, 0xad, 0xad},
+ {0x01, 0xbe, 0xae}, {0x01, 0xbf, 0xaf}, {0x00, 0xb0, 0xb0},
+ {0x00, 0xb1, 0xa1}, {0x00, 0xb2, 0xb2}, {0x00, 0xb3, 0xa3},
+ {0x00, 0xb4, 0xb4}, {0x00, 0xb5, 0xa5}, {0x00, 0xb6, 0xa6},
+ {0x00, 0xb7, 0xb7}, {0x00, 0xb8, 0xb8}, {0x00, 0xb9, 0xa9},
+ {0x00, 0xba, 0xaa}, {0x00, 0xbb, 0xab}, {0x00, 0xbc, 0xac},
+ {0x00, 0xbd, 0xbd}, {0x00, 0xbe, 0xae}, {0x00, 0xbf, 0xaf},
+ {0x01, 0xe0, 0xc0}, {0x01, 0xe1, 0xc1}, {0x01, 0xe2, 0xc2},
+ {0x01, 0xe3, 0xc3}, {0x01, 0xe4, 0xc4}, {0x01, 0xe5, 0xc5},
+ {0x01, 0xe6, 0xc6}, {0x01, 0xe7, 0xc7}, {0x01, 0xe8, 0xc8},
+ {0x01, 0xe9, 0xc9}, {0x01, 0xea, 0xca}, {0x01, 0xeb, 0xcb},
+ {0x01, 0xec, 0xcc}, {0x01, 0xed, 0xcd}, {0x01, 0xee, 0xce},
+ {0x01, 0xef, 0xcf}, {0x01, 0xf0, 0xd0}, {0x01, 0xf1, 0xd1},
+ {0x01, 0xf2, 0xd2}, {0x01, 0xf3, 0xd3}, {0x01, 0xf4, 0xd4},
+ {0x01, 0xf5, 0xd5}, {0x01, 0xf6, 0xd6}, {0x00, 0xd7, 0xd7},
+ {0x01, 0xf8, 0xd8}, {0x01, 0xf9, 0xd9}, {0x01, 0xfa, 0xda},
+ {0x01, 0xfb, 0xdb}, {0x01, 0xfc, 0xdc}, {0x01, 0xfd, 0xdd},
+ {0x01, 0xfe, 0xde}, {0x00, 0xdf, 0xdf}, {0x00, 0xe0, 0xc0},
+ {0x00, 0xe1, 0xc1}, {0x00, 0xe2, 0xc2}, {0x00, 0xe3, 0xc3},
+ {0x00, 0xe4, 0xc4}, {0x00, 0xe5, 0xc5}, {0x00, 0xe6, 0xc6},
+ {0x00, 0xe7, 0xc7}, {0x00, 0xe8, 0xc8}, {0x00, 0xe9, 0xc9},
+ {0x00, 0xea, 0xca}, {0x00, 0xeb, 0xcb}, {0x00, 0xec, 0xcc},
+ {0x00, 0xed, 0xcd}, {0x00, 0xee, 0xce}, {0x00, 0xef, 0xcf},
+ {0x00, 0xf0, 0xd0}, {0x00, 0xf1, 0xd1}, {0x00, 0xf2, 0xd2},
+ {0x00, 0xf3, 0xd3}, {0x00, 0xf4, 0xd4}, {0x00, 0xf5, 0xd5},
+ {0x00, 0xf6, 0xd6}, {0x00, 0xf7, 0xf7}, {0x00, 0xf8, 0xd8},
+ {0x00, 0xf9, 0xd9}, {0x00, 0xfa, 0xda}, {0x00, 0xfb, 0xdb},
+ {0x00, 0xfc, 0xdc}, {0x00, 0xfd, 0xdd}, {0x00, 0xfe, 0xde},
+ {0x00, 0xff, 0xff}};
+
+static struct cs_info iso3_tbl[] = {
+ {0x00, 0x00, 0x00}, {0x00, 0x01, 0x01}, {0x00, 0x02, 0x02},
+ {0x00, 0x03, 0x03}, {0x00, 0x04, 0x04}, {0x00, 0x05, 0x05},
+ {0x00, 0x06, 0x06}, {0x00, 0x07, 0x07}, {0x00, 0x08, 0x08},
+ {0x00, 0x09, 0x09}, {0x00, 0x0a, 0x0a}, {0x00, 0x0b, 0x0b},
+ {0x00, 0x0c, 0x0c}, {0x00, 0x0d, 0x0d}, {0x00, 0x0e, 0x0e},
+ {0x00, 0x0f, 0x0f}, {0x00, 0x10, 0x10}, {0x00, 0x11, 0x11},
+ {0x00, 0x12, 0x12}, {0x00, 0x13, 0x13}, {0x00, 0x14, 0x14},
+ {0x00, 0x15, 0x15}, {0x00, 0x16, 0x16}, {0x00, 0x17, 0x17},
+ {0x00, 0x18, 0x18}, {0x00, 0x19, 0x19}, {0x00, 0x1a, 0x1a},
+ {0x00, 0x1b, 0x1b}, {0x00, 0x1c, 0x1c}, {0x00, 0x1d, 0x1d},
+ {0x00, 0x1e, 0x1e}, {0x00, 0x1f, 0x1f}, {0x00, 0x20, 0x20},
+ {0x00, 0x21, 0x21}, {0x00, 0x22, 0x22}, {0x00, 0x23, 0x23},
+ {0x00, 0x24, 0x24}, {0x00, 0x25, 0x25}, {0x00, 0x26, 0x26},
+ {0x00, 0x27, 0x27}, {0x00, 0x28, 0x28}, {0x00, 0x29, 0x29},
+ {0x00, 0x2a, 0x2a}, {0x00, 0x2b, 0x2b}, {0x00, 0x2c, 0x2c},
+ {0x00, 0x2d, 0x2d}, {0x00, 0x2e, 0x2e}, {0x00, 0x2f, 0x2f},
+ {0x00, 0x30, 0x30}, {0x00, 0x31, 0x31}, {0x00, 0x32, 0x32},
+ {0x00, 0x33, 0x33}, {0x00, 0x34, 0x34}, {0x00, 0x35, 0x35},
+ {0x00, 0x36, 0x36}, {0x00, 0x37, 0x37}, {0x00, 0x38, 0x38},
+ {0x00, 0x39, 0x39}, {0x00, 0x3a, 0x3a}, {0x00, 0x3b, 0x3b},
+ {0x00, 0x3c, 0x3c}, {0x00, 0x3d, 0x3d}, {0x00, 0x3e, 0x3e},
+ {0x00, 0x3f, 0x3f}, {0x00, 0x40, 0x40}, {0x01, 0x61, 0x41},
+ {0x01, 0x62, 0x42}, {0x01, 0x63, 0x43}, {0x01, 0x64, 0x44},
+ {0x01, 0x65, 0x45}, {0x01, 0x66, 0x46}, {0x01, 0x67, 0x47},
+ {0x01, 0x68, 0x48}, {0x01, 0x69, 0x49}, {0x01, 0x6a, 0x4a},
+ {0x01, 0x6b, 0x4b}, {0x01, 0x6c, 0x4c}, {0x01, 0x6d, 0x4d},
+ {0x01, 0x6e, 0x4e}, {0x01, 0x6f, 0x4f}, {0x01, 0x70, 0x50},
+ {0x01, 0x71, 0x51}, {0x01, 0x72, 0x52}, {0x01, 0x73, 0x53},
+ {0x01, 0x74, 0x54}, {0x01, 0x75, 0x55}, {0x01, 0x76, 0x56},
+ {0x01, 0x77, 0x57}, {0x01, 0x78, 0x58}, {0x01, 0x79, 0x59},
+ {0x01, 0x7a, 0x5a}, {0x00, 0x5b, 0x5b}, {0x00, 0x5c, 0x5c},
+ {0x00, 0x5d, 0x5d}, {0x00, 0x5e, 0x5e}, {0x00, 0x5f, 0x5f},
+ {0x00, 0x60, 0x60}, {0x00, 0x61, 0x41}, {0x00, 0x62, 0x42},
+ {0x00, 0x63, 0x43}, {0x00, 0x64, 0x44}, {0x00, 0x65, 0x45},
+ {0x00, 0x66, 0x46}, {0x00, 0x67, 0x47}, {0x00, 0x68, 0x48},
+ {0x00, 0x69, 0x49}, {0x00, 0x6a, 0x4a}, {0x00, 0x6b, 0x4b},
+ {0x00, 0x6c, 0x4c}, {0x00, 0x6d, 0x4d}, {0x00, 0x6e, 0x4e},
+ {0x00, 0x6f, 0x4f}, {0x00, 0x70, 0x50}, {0x00, 0x71, 0x51},
+ {0x00, 0x72, 0x52}, {0x00, 0x73, 0x53}, {0x00, 0x74, 0x54},
+ {0x00, 0x75, 0x55}, {0x00, 0x76, 0x56}, {0x00, 0x77, 0x57},
+ {0x00, 0x78, 0x58}, {0x00, 0x79, 0x59}, {0x00, 0x7a, 0x5a},
+ {0x00, 0x7b, 0x7b}, {0x00, 0x7c, 0x7c}, {0x00, 0x7d, 0x7d},
+ {0x00, 0x7e, 0x7e}, {0x00, 0x7f, 0x7f}, {0x00, 0x80, 0x80},
+ {0x00, 0x81, 0x81}, {0x00, 0x82, 0x82}, {0x00, 0x83, 0x83},
+ {0x00, 0x84, 0x84}, {0x00, 0x85, 0x85}, {0x00, 0x86, 0x86},
+ {0x00, 0x87, 0x87}, {0x00, 0x88, 0x88}, {0x00, 0x89, 0x89},
+ {0x00, 0x8a, 0x8a}, {0x00, 0x8b, 0x8b}, {0x00, 0x8c, 0x8c},
+ {0x00, 0x8d, 0x8d}, {0x00, 0x8e, 0x8e}, {0x00, 0x8f, 0x8f},
+ {0x00, 0x90, 0x90}, {0x00, 0x91, 0x91}, {0x00, 0x92, 0x92},
+ {0x00, 0x93, 0x93}, {0x00, 0x94, 0x94}, {0x00, 0x95, 0x95},
+ {0x00, 0x96, 0x96}, {0x00, 0x97, 0x97}, {0x00, 0x98, 0x98},
+ {0x00, 0x99, 0x99}, {0x00, 0x9a, 0x9a}, {0x00, 0x9b, 0x9b},
+ {0x00, 0x9c, 0x9c}, {0x00, 0x9d, 0x9d}, {0x00, 0x9e, 0x9e},
+ {0x00, 0x9f, 0x9f}, {0x00, 0xa0, 0xa0}, {0x01, 0xb1, 0xa1},
+ {0x00, 0xa2, 0xa2}, {0x00, 0xa3, 0xa3}, {0x00, 0xa4, 0xa4},
+ {0x00, 0xa5, 0xa5}, {0x01, 0xb6, 0xa6}, {0x00, 0xa7, 0xa7},
+ {0x00, 0xa8, 0xa8}, {0x01, 0x69, 0xa9}, {0x01, 0xba, 0xaa},
+ {0x01, 0xbb, 0xab}, {0x01, 0xbc, 0xac}, {0x00, 0xad, 0xad},
+ {0x00, 0xae, 0xae}, {0x01, 0xbf, 0xaf}, {0x00, 0xb0, 0xb0},
+ {0x00, 0xb1, 0xa1}, {0x00, 0xb2, 0xb2}, {0x00, 0xb3, 0xb3},
+ {0x00, 0xb4, 0xb4}, {0x00, 0xb5, 0xb5}, {0x00, 0xb6, 0xa6},
+ {0x00, 0xb7, 0xb7}, {0x00, 0xb8, 0xb8}, {0x00, 0xb9, 0x49},
+ {0x00, 0xba, 0xaa}, {0x00, 0xbb, 0xab}, {0x00, 0xbc, 0xac},
+ {0x00, 0xbd, 0xbd}, {0x00, 0xbe, 0xbe}, {0x00, 0xbf, 0xaf},
+ {0x01, 0xe0, 0xc0}, {0x01, 0xe1, 0xc1}, {0x01, 0xe2, 0xc2},
+ {0x00, 0xc3, 0xc3}, {0x01, 0xe4, 0xc4}, {0x01, 0xe5, 0xc5},
+ {0x01, 0xe6, 0xc6}, {0x01, 0xe7, 0xc7}, {0x01, 0xe8, 0xc8},
+ {0x01, 0xe9, 0xc9}, {0x01, 0xea, 0xca}, {0x01, 0xeb, 0xcb},
+ {0x01, 0xec, 0xcc}, {0x01, 0xed, 0xcd}, {0x01, 0xee, 0xce},
+ {0x01, 0xef, 0xcf}, {0x00, 0xd0, 0xd0}, {0x01, 0xf1, 0xd1},
+ {0x01, 0xf2, 0xd2}, {0x01, 0xf3, 0xd3}, {0x01, 0xf4, 0xd4},
+ {0x01, 0xf5, 0xd5}, {0x01, 0xf6, 0xd6}, {0x00, 0xd7, 0xd7},
+ {0x01, 0xf8, 0xd8}, {0x01, 0xf9, 0xd9}, {0x01, 0xfa, 0xda},
+ {0x01, 0xfb, 0xdb}, {0x01, 0xfc, 0xdc}, {0x01, 0xfd, 0xdd},
+ {0x01, 0xfe, 0xde}, {0x00, 0xdf, 0xdf}, {0x00, 0xe0, 0xc0},
+ {0x00, 0xe1, 0xc1}, {0x00, 0xe2, 0xc2}, {0x00, 0xe3, 0xe3},
+ {0x00, 0xe4, 0xc4}, {0x00, 0xe5, 0xc5}, {0x00, 0xe6, 0xc6},
+ {0x00, 0xe7, 0xc7}, {0x00, 0xe8, 0xc8}, {0x00, 0xe9, 0xc9},
+ {0x00, 0xea, 0xca}, {0x00, 0xeb, 0xcb}, {0x00, 0xec, 0xcc},
+ {0x00, 0xed, 0xcd}, {0x00, 0xee, 0xce}, {0x00, 0xef, 0xcf},
+ {0x00, 0xf0, 0xf0}, {0x00, 0xf1, 0xd1}, {0x00, 0xf2, 0xd2},
+ {0x00, 0xf3, 0xd3}, {0x00, 0xf4, 0xd4}, {0x00, 0xf5, 0xd5},
+ {0x00, 0xf6, 0xd6}, {0x00, 0xf7, 0xf7}, {0x00, 0xf8, 0xd8},
+ {0x00, 0xf9, 0xd9}, {0x00, 0xfa, 0xda}, {0x00, 0xfb, 0xdb},
+ {0x00, 0xfc, 0xdc}, {0x00, 0xfd, 0xdd}, {0x00, 0xfe, 0xde},
+ {0x00, 0xff, 0xff}};
+
+static struct cs_info iso4_tbl[] = {
+ {0x00, 0x00, 0x00}, {0x00, 0x01, 0x01}, {0x00, 0x02, 0x02},
+ {0x00, 0x03, 0x03}, {0x00, 0x04, 0x04}, {0x00, 0x05, 0x05},
+ {0x00, 0x06, 0x06}, {0x00, 0x07, 0x07}, {0x00, 0x08, 0x08},
+ {0x00, 0x09, 0x09}, {0x00, 0x0a, 0x0a}, {0x00, 0x0b, 0x0b},
+ {0x00, 0x0c, 0x0c}, {0x00, 0x0d, 0x0d}, {0x00, 0x0e, 0x0e},
+ {0x00, 0x0f, 0x0f}, {0x00, 0x10, 0x10}, {0x00, 0x11, 0x11},
+ {0x00, 0x12, 0x12}, {0x00, 0x13, 0x13}, {0x00, 0x14, 0x14},
+ {0x00, 0x15, 0x15}, {0x00, 0x16, 0x16}, {0x00, 0x17, 0x17},
+ {0x00, 0x18, 0x18}, {0x00, 0x19, 0x19}, {0x00, 0x1a, 0x1a},
+ {0x00, 0x1b, 0x1b}, {0x00, 0x1c, 0x1c}, {0x00, 0x1d, 0x1d},
+ {0x00, 0x1e, 0x1e}, {0x00, 0x1f, 0x1f}, {0x00, 0x20, 0x20},
+ {0x00, 0x21, 0x21}, {0x00, 0x22, 0x22}, {0x00, 0x23, 0x23},
+ {0x00, 0x24, 0x24}, {0x00, 0x25, 0x25}, {0x00, 0x26, 0x26},
+ {0x00, 0x27, 0x27}, {0x00, 0x28, 0x28}, {0x00, 0x29, 0x29},
+ {0x00, 0x2a, 0x2a}, {0x00, 0x2b, 0x2b}, {0x00, 0x2c, 0x2c},
+ {0x00, 0x2d, 0x2d}, {0x00, 0x2e, 0x2e}, {0x00, 0x2f, 0x2f},
+ {0x00, 0x30, 0x30}, {0x00, 0x31, 0x31}, {0x00, 0x32, 0x32},
+ {0x00, 0x33, 0x33}, {0x00, 0x34, 0x34}, {0x00, 0x35, 0x35},
+ {0x00, 0x36, 0x36}, {0x00, 0x37, 0x37}, {0x00, 0x38, 0x38},
+ {0x00, 0x39, 0x39}, {0x00, 0x3a, 0x3a}, {0x00, 0x3b, 0x3b},
+ {0x00, 0x3c, 0x3c}, {0x00, 0x3d, 0x3d}, {0x00, 0x3e, 0x3e},
+ {0x00, 0x3f, 0x3f}, {0x00, 0x40, 0x40}, {0x01, 0x61, 0x41},
+ {0x01, 0x62, 0x42}, {0x01, 0x63, 0x43}, {0x01, 0x64, 0x44},
+ {0x01, 0x65, 0x45}, {0x01, 0x66, 0x46}, {0x01, 0x67, 0x47},
+ {0x01, 0x68, 0x48}, {0x01, 0x69, 0x49}, {0x01, 0x6a, 0x4a},
+ {0x01, 0x6b, 0x4b}, {0x01, 0x6c, 0x4c}, {0x01, 0x6d, 0x4d},
+ {0x01, 0x6e, 0x4e}, {0x01, 0x6f, 0x4f}, {0x01, 0x70, 0x50},
+ {0x01, 0x71, 0x51}, {0x01, 0x72, 0x52}, {0x01, 0x73, 0x53},
+ {0x01, 0x74, 0x54}, {0x01, 0x75, 0x55}, {0x01, 0x76, 0x56},
+ {0x01, 0x77, 0x57}, {0x01, 0x78, 0x58}, {0x01, 0x79, 0x59},
+ {0x01, 0x7a, 0x5a}, {0x00, 0x5b, 0x5b}, {0x00, 0x5c, 0x5c},
+ {0x00, 0x5d, 0x5d}, {0x00, 0x5e, 0x5e}, {0x00, 0x5f, 0x5f},
+ {0x00, 0x60, 0x60}, {0x00, 0x61, 0x41}, {0x00, 0x62, 0x42},
+ {0x00, 0x63, 0x43}, {0x00, 0x64, 0x44}, {0x00, 0x65, 0x45},
+ {0x00, 0x66, 0x46}, {0x00, 0x67, 0x47}, {0x00, 0x68, 0x48},
+ {0x00, 0x69, 0x49}, {0x00, 0x6a, 0x4a}, {0x00, 0x6b, 0x4b},
+ {0x00, 0x6c, 0x4c}, {0x00, 0x6d, 0x4d}, {0x00, 0x6e, 0x4e},
+ {0x00, 0x6f, 0x4f}, {0x00, 0x70, 0x50}, {0x00, 0x71, 0x51},
+ {0x00, 0x72, 0x52}, {0x00, 0x73, 0x53}, {0x00, 0x74, 0x54},
+ {0x00, 0x75, 0x55}, {0x00, 0x76, 0x56}, {0x00, 0x77, 0x57},
+ {0x00, 0x78, 0x58}, {0x00, 0x79, 0x59}, {0x00, 0x7a, 0x5a},
+ {0x00, 0x7b, 0x7b}, {0x00, 0x7c, 0x7c}, {0x00, 0x7d, 0x7d},
+ {0x00, 0x7e, 0x7e}, {0x00, 0x7f, 0x7f}, {0x00, 0x80, 0x80},
+ {0x00, 0x81, 0x81}, {0x00, 0x82, 0x82}, {0x00, 0x83, 0x83},
+ {0x00, 0x84, 0x84}, {0x00, 0x85, 0x85}, {0x00, 0x86, 0x86},
+ {0x00, 0x87, 0x87}, {0x00, 0x88, 0x88}, {0x00, 0x89, 0x89},
+ {0x00, 0x8a, 0x8a}, {0x00, 0x8b, 0x8b}, {0x00, 0x8c, 0x8c},
+ {0x00, 0x8d, 0x8d}, {0x00, 0x8e, 0x8e}, {0x00, 0x8f, 0x8f},
+ {0x00, 0x90, 0x90}, {0x00, 0x91, 0x91}, {0x00, 0x92, 0x92},
+ {0x00, 0x93, 0x93}, {0x00, 0x94, 0x94}, {0x00, 0x95, 0x95},
+ {0x00, 0x96, 0x96}, {0x00, 0x97, 0x97}, {0x00, 0x98, 0x98},
+ {0x00, 0x99, 0x99}, {0x00, 0x9a, 0x9a}, {0x00, 0x9b, 0x9b},
+ {0x00, 0x9c, 0x9c}, {0x00, 0x9d, 0x9d}, {0x00, 0x9e, 0x9e},
+ {0x00, 0x9f, 0x9f}, {0x00, 0xa0, 0xa0}, {0x01, 0xb1, 0xa1},
+ {0x00, 0xa2, 0xa2}, {0x01, 0xb3, 0xa3}, {0x00, 0xa4, 0xa4},
+ {0x01, 0xb5, 0xa5}, {0x01, 0xb6, 0xa6}, {0x00, 0xa7, 0xa7},
+ {0x00, 0xa8, 0xa8}, {0x01, 0xb9, 0xa9}, {0x01, 0xba, 0xaa},
+ {0x01, 0xbb, 0xab}, {0x01, 0xbc, 0xac}, {0x00, 0xad, 0xad},
+ {0x01, 0xbe, 0xae}, {0x00, 0xaf, 0xaf}, {0x00, 0xb0, 0xb0},
+ {0x00, 0xb1, 0xa1}, {0x00, 0xb2, 0xb2}, {0x00, 0xb3, 0xa3},
+ {0x00, 0xb4, 0xb4}, {0x00, 0xb5, 0xa5}, {0x00, 0xb6, 0xa6},
+ {0x00, 0xb7, 0xb7}, {0x00, 0xb8, 0xb8}, {0x00, 0xb9, 0xa9},
+ {0x00, 0xba, 0xaa}, {0x00, 0xbb, 0xab}, {0x00, 0xbc, 0xac},
+ {0x00, 0xbd, 0xbd}, {0x00, 0xbe, 0xae}, {0x00, 0xbf, 0xbf},
+ {0x01, 0xe0, 0xc0}, {0x01, 0xe1, 0xc1}, {0x01, 0xe2, 0xc2},
+ {0x01, 0xe3, 0xc3}, {0x01, 0xe4, 0xc4}, {0x01, 0xe5, 0xc5},
+ {0x01, 0xe6, 0xc6}, {0x01, 0xe7, 0xc7}, {0x01, 0xe8, 0xc8},
+ {0x01, 0xe9, 0xc9}, {0x01, 0xea, 0xca}, {0x01, 0xeb, 0xcb},
+ {0x01, 0xec, 0xcc}, {0x01, 0xed, 0xcd}, {0x01, 0xee, 0xce},
+ {0x01, 0xef, 0xcf}, {0x01, 0xf0, 0xd0}, {0x01, 0xf1, 0xd1},
+ {0x01, 0xf2, 0xd2}, {0x01, 0xf3, 0xd3}, {0x01, 0xf4, 0xd4},
+ {0x01, 0xf5, 0xd5}, {0x01, 0xf6, 0xd6}, {0x00, 0xd7, 0xd7},
+ {0x01, 0xf8, 0xd8}, {0x01, 0xf9, 0xd9}, {0x01, 0xfa, 0xda},
+ {0x01, 0xfb, 0xdb}, {0x01, 0xfc, 0xdc}, {0x01, 0xfd, 0xdd},
+ {0x01, 0xfe, 0xde}, {0x00, 0xdf, 0xdf}, {0x00, 0xe0, 0xc0},
+ {0x00, 0xe1, 0xc1}, {0x00, 0xe2, 0xc2}, {0x00, 0xe3, 0xc3},
+ {0x00, 0xe4, 0xc4}, {0x00, 0xe5, 0xc5}, {0x00, 0xe6, 0xc6},
+ {0x00, 0xe7, 0xc7}, {0x00, 0xe8, 0xc8}, {0x00, 0xe9, 0xc9},
+ {0x00, 0xea, 0xca}, {0x00, 0xeb, 0xcb}, {0x00, 0xec, 0xcc},
+ {0x00, 0xed, 0xcd}, {0x00, 0xee, 0xce}, {0x00, 0xef, 0xcf},
+ {0x00, 0xf0, 0xd0}, {0x00, 0xf1, 0xd1}, {0x00, 0xf2, 0xd2},
+ {0x00, 0xf3, 0xd3}, {0x00, 0xf4, 0xd4}, {0x00, 0xf5, 0xd5},
+ {0x00, 0xf6, 0xd6}, {0x00, 0xf7, 0xf7}, {0x00, 0xf8, 0xd8},
+ {0x00, 0xf9, 0xd9}, {0x00, 0xfa, 0xda}, {0x00, 0xfb, 0xdb},
+ {0x00, 0xfc, 0xdc}, {0x00, 0xfd, 0xdd}, {0x00, 0xfe, 0xde},
+ {0x00, 0xff, 0xff}};
+
+static struct cs_info iso5_tbl[] = {
+ {0x00, 0x00, 0x00}, {0x00, 0x01, 0x01}, {0x00, 0x02, 0x02},
+ {0x00, 0x03, 0x03}, {0x00, 0x04, 0x04}, {0x00, 0x05, 0x05},
+ {0x00, 0x06, 0x06}, {0x00, 0x07, 0x07}, {0x00, 0x08, 0x08},
+ {0x00, 0x09, 0x09}, {0x00, 0x0a, 0x0a}, {0x00, 0x0b, 0x0b},
+ {0x00, 0x0c, 0x0c}, {0x00, 0x0d, 0x0d}, {0x00, 0x0e, 0x0e},
+ {0x00, 0x0f, 0x0f}, {0x00, 0x10, 0x10}, {0x00, 0x11, 0x11},
+ {0x00, 0x12, 0x12}, {0x00, 0x13, 0x13}, {0x00, 0x14, 0x14},
+ {0x00, 0x15, 0x15}, {0x00, 0x16, 0x16}, {0x00, 0x17, 0x17},
+ {0x00, 0x18, 0x18}, {0x00, 0x19, 0x19}, {0x00, 0x1a, 0x1a},
+ {0x00, 0x1b, 0x1b}, {0x00, 0x1c, 0x1c}, {0x00, 0x1d, 0x1d},
+ {0x00, 0x1e, 0x1e}, {0x00, 0x1f, 0x1f}, {0x00, 0x20, 0x20},
+ {0x00, 0x21, 0x21}, {0x00, 0x22, 0x22}, {0x00, 0x23, 0x23},
+ {0x00, 0x24, 0x24}, {0x00, 0x25, 0x25}, {0x00, 0x26, 0x26},
+ {0x00, 0x27, 0x27}, {0x00, 0x28, 0x28}, {0x00, 0x29, 0x29},
+ {0x00, 0x2a, 0x2a}, {0x00, 0x2b, 0x2b}, {0x00, 0x2c, 0x2c},
+ {0x00, 0x2d, 0x2d}, {0x00, 0x2e, 0x2e}, {0x00, 0x2f, 0x2f},
+ {0x00, 0x30, 0x30}, {0x00, 0x31, 0x31}, {0x00, 0x32, 0x32},
+ {0x00, 0x33, 0x33}, {0x00, 0x34, 0x34}, {0x00, 0x35, 0x35},
+ {0x00, 0x36, 0x36}, {0x00, 0x37, 0x37}, {0x00, 0x38, 0x38},
+ {0x00, 0x39, 0x39}, {0x00, 0x3a, 0x3a}, {0x00, 0x3b, 0x3b},
+ {0x00, 0x3c, 0x3c}, {0x00, 0x3d, 0x3d}, {0x00, 0x3e, 0x3e},
+ {0x00, 0x3f, 0x3f}, {0x00, 0x40, 0x40}, {0x01, 0x61, 0x41},
+ {0x01, 0x62, 0x42}, {0x01, 0x63, 0x43}, {0x01, 0x64, 0x44},
+ {0x01, 0x65, 0x45}, {0x01, 0x66, 0x46}, {0x01, 0x67, 0x47},
+ {0x01, 0x68, 0x48}, {0x01, 0x69, 0x49}, {0x01, 0x6a, 0x4a},
+ {0x01, 0x6b, 0x4b}, {0x01, 0x6c, 0x4c}, {0x01, 0x6d, 0x4d},
+ {0x01, 0x6e, 0x4e}, {0x01, 0x6f, 0x4f}, {0x01, 0x70, 0x50},
+ {0x01, 0x71, 0x51}, {0x01, 0x72, 0x52}, {0x01, 0x73, 0x53},
+ {0x01, 0x74, 0x54}, {0x01, 0x75, 0x55}, {0x01, 0x76, 0x56},
+ {0x01, 0x77, 0x57}, {0x01, 0x78, 0x58}, {0x01, 0x79, 0x59},
+ {0x01, 0x7a, 0x5a}, {0x00, 0x5b, 0x5b}, {0x00, 0x5c, 0x5c},
+ {0x00, 0x5d, 0x5d}, {0x00, 0x5e, 0x5e}, {0x00, 0x5f, 0x5f},
+ {0x00, 0x60, 0x60}, {0x00, 0x61, 0x41}, {0x00, 0x62, 0x42},
+ {0x00, 0x63, 0x43}, {0x00, 0x64, 0x44}, {0x00, 0x65, 0x45},
+ {0x00, 0x66, 0x46}, {0x00, 0x67, 0x47}, {0x00, 0x68, 0x48},
+ {0x00, 0x69, 0x49}, {0x00, 0x6a, 0x4a}, {0x00, 0x6b, 0x4b},
+ {0x00, 0x6c, 0x4c}, {0x00, 0x6d, 0x4d}, {0x00, 0x6e, 0x4e},
+ {0x00, 0x6f, 0x4f}, {0x00, 0x70, 0x50}, {0x00, 0x71, 0x51},
+ {0x00, 0x72, 0x52}, {0x00, 0x73, 0x53}, {0x00, 0x74, 0x54},
+ {0x00, 0x75, 0x55}, {0x00, 0x76, 0x56}, {0x00, 0x77, 0x57},
+ {0x00, 0x78, 0x58}, {0x00, 0x79, 0x59}, {0x00, 0x7a, 0x5a},
+ {0x00, 0x7b, 0x7b}, {0x00, 0x7c, 0x7c}, {0x00, 0x7d, 0x7d},
+ {0x00, 0x7e, 0x7e}, {0x00, 0x7f, 0x7f}, {0x00, 0x80, 0x80},
+ {0x00, 0x81, 0x81}, {0x00, 0x82, 0x82}, {0x00, 0x83, 0x83},
+ {0x00, 0x84, 0x84}, {0x00, 0x85, 0x85}, {0x00, 0x86, 0x86},
+ {0x00, 0x87, 0x87}, {0x00, 0x88, 0x88}, {0x00, 0x89, 0x89},
+ {0x00, 0x8a, 0x8a}, {0x00, 0x8b, 0x8b}, {0x00, 0x8c, 0x8c},
+ {0x00, 0x8d, 0x8d}, {0x00, 0x8e, 0x8e}, {0x00, 0x8f, 0x8f},
+ {0x00, 0x90, 0x90}, {0x00, 0x91, 0x91}, {0x00, 0x92, 0x92},
+ {0x00, 0x93, 0x93}, {0x00, 0x94, 0x94}, {0x00, 0x95, 0x95},
+ {0x00, 0x96, 0x96}, {0x00, 0x97, 0x97}, {0x00, 0x98, 0x98},
+ {0x00, 0x99, 0x99}, {0x00, 0x9a, 0x9a}, {0x00, 0x9b, 0x9b},
+ {0x00, 0x9c, 0x9c}, {0x00, 0x9d, 0x9d}, {0x00, 0x9e, 0x9e},
+ {0x00, 0x9f, 0x9f}, {0x00, 0xa0, 0xa0}, {0x01, 0xf1, 0xa1},
+ {0x01, 0xf2, 0xa2}, {0x01, 0xf3, 0xa3}, {0x01, 0xf4, 0xa4},
+ {0x01, 0xf5, 0xa5}, {0x01, 0xf6, 0xa6}, {0x01, 0xf7, 0xa7},
+ {0x01, 0xf8, 0xa8}, {0x01, 0xf9, 0xa9}, {0x01, 0xfa, 0xaa},
+ {0x01, 0xfb, 0xab}, {0x01, 0xfc, 0xac}, {0x00, 0xad, 0xad},
+ {0x01, 0xfe, 0xae}, {0x01, 0xff, 0xaf}, {0x01, 0xd0, 0xb0},
+ {0x01, 0xd1, 0xb1}, {0x01, 0xd2, 0xb2}, {0x01, 0xd3, 0xb3},
+ {0x01, 0xd4, 0xb4}, {0x01, 0xd5, 0xb5}, {0x01, 0xd6, 0xb6},
+ {0x01, 0xd7, 0xb7}, {0x01, 0xd8, 0xb8}, {0x01, 0xd9, 0xb9},
+ {0x01, 0xda, 0xba}, {0x01, 0xdb, 0xbb}, {0x01, 0xdc, 0xbc},
+ {0x01, 0xdd, 0xbd}, {0x01, 0xde, 0xbe}, {0x01, 0xdf, 0xbf},
+ {0x01, 0xe0, 0xc0}, {0x01, 0xe1, 0xc1}, {0x01, 0xe2, 0xc2},
+ {0x01, 0xe3, 0xc3}, {0x01, 0xe4, 0xc4}, {0x01, 0xe5, 0xc5},
+ {0x01, 0xe6, 0xc6}, {0x01, 0xe7, 0xc7}, {0x01, 0xe8, 0xc8},
+ {0x01, 0xe9, 0xc9}, {0x01, 0xea, 0xca}, {0x01, 0xeb, 0xcb},
+ {0x01, 0xec, 0xcc}, {0x01, 0xed, 0xcd}, {0x01, 0xee, 0xce},
+ {0x01, 0xef, 0xcf}, {0x00, 0xd0, 0xb0}, {0x00, 0xd1, 0xb1},
+ {0x00, 0xd2, 0xb2}, {0x00, 0xd3, 0xb3}, {0x00, 0xd4, 0xb4},
+ {0x00, 0xd5, 0xb5}, {0x00, 0xd6, 0xb6}, {0x00, 0xd7, 0xb7},
+ {0x00, 0xd8, 0xb8}, {0x00, 0xd9, 0xb9}, {0x00, 0xda, 0xba},
+ {0x00, 0xdb, 0xbb}, {0x00, 0xdc, 0xbc}, {0x00, 0xdd, 0xbd},
+ {0x00, 0xde, 0xbe}, {0x00, 0xdf, 0xbf}, {0x00, 0xe0, 0xc0},
+ {0x00, 0xe1, 0xc1}, {0x00, 0xe2, 0xc2}, {0x00, 0xe3, 0xc3},
+ {0x00, 0xe4, 0xc4}, {0x00, 0xe5, 0xc5}, {0x00, 0xe6, 0xc6},
+ {0x00, 0xe7, 0xc7}, {0x00, 0xe8, 0xc8}, {0x00, 0xe9, 0xc9},
+ {0x00, 0xea, 0xca}, {0x00, 0xeb, 0xcb}, {0x00, 0xec, 0xcc},
+ {0x00, 0xed, 0xcd}, {0x00, 0xee, 0xce}, {0x00, 0xef, 0xcf},
+ {0x00, 0xf0, 0xf0}, {0x00, 0xf1, 0xa1}, {0x00, 0xf2, 0xa2},
+ {0x00, 0xf3, 0xa3}, {0x00, 0xf4, 0xa4}, {0x00, 0xf5, 0xa5},
+ {0x00, 0xf6, 0xa6}, {0x00, 0xf7, 0xa7}, {0x00, 0xf8, 0xa8},
+ {0x00, 0xf9, 0xa9}, {0x00, 0xfa, 0xaa}, {0x00, 0xfb, 0xab},
+ {0x00, 0xfc, 0xac}, {0x00, 0xfd, 0xfd}, {0x00, 0xfe, 0xae},
+ {0x00, 0xff, 0xaf}};
+
+static struct cs_info iso6_tbl[] = {
+ {0x00, 0x00, 0x00}, {0x00, 0x01, 0x01}, {0x00, 0x02, 0x02},
+ {0x00, 0x03, 0x03}, {0x00, 0x04, 0x04}, {0x00, 0x05, 0x05},
+ {0x00, 0x06, 0x06}, {0x00, 0x07, 0x07}, {0x00, 0x08, 0x08},
+ {0x00, 0x09, 0x09}, {0x00, 0x0a, 0x0a}, {0x00, 0x0b, 0x0b},
+ {0x00, 0x0c, 0x0c}, {0x00, 0x0d, 0x0d}, {0x00, 0x0e, 0x0e},
+ {0x00, 0x0f, 0x0f}, {0x00, 0x10, 0x10}, {0x00, 0x11, 0x11},
+ {0x00, 0x12, 0x12}, {0x00, 0x13, 0x13}, {0x00, 0x14, 0x14},
+ {0x00, 0x15, 0x15}, {0x00, 0x16, 0x16}, {0x00, 0x17, 0x17},
+ {0x00, 0x18, 0x18}, {0x00, 0x19, 0x19}, {0x00, 0x1a, 0x1a},
+ {0x00, 0x1b, 0x1b}, {0x00, 0x1c, 0x1c}, {0x00, 0x1d, 0x1d},
+ {0x00, 0x1e, 0x1e}, {0x00, 0x1f, 0x1f}, {0x00, 0x20, 0x20},
+ {0x00, 0x21, 0x21}, {0x00, 0x22, 0x22}, {0x00, 0x23, 0x23},
+ {0x00, 0x24, 0x24}, {0x00, 0x25, 0x25}, {0x00, 0x26, 0x26},
+ {0x00, 0x27, 0x27}, {0x00, 0x28, 0x28}, {0x00, 0x29, 0x29},
+ {0x00, 0x2a, 0x2a}, {0x00, 0x2b, 0x2b}, {0x00, 0x2c, 0x2c},
+ {0x00, 0x2d, 0x2d}, {0x00, 0x2e, 0x2e}, {0x00, 0x2f, 0x2f},
+ {0x00, 0x30, 0x30}, {0x00, 0x31, 0x31}, {0x00, 0x32, 0x32},
+ {0x00, 0x33, 0x33}, {0x00, 0x34, 0x34}, {0x00, 0x35, 0x35},
+ {0x00, 0x36, 0x36}, {0x00, 0x37, 0x37}, {0x00, 0x38, 0x38},
+ {0x00, 0x39, 0x39}, {0x00, 0x3a, 0x3a}, {0x00, 0x3b, 0x3b},
+ {0x00, 0x3c, 0x3c}, {0x00, 0x3d, 0x3d}, {0x00, 0x3e, 0x3e},
+ {0x00, 0x3f, 0x3f}, {0x00, 0x40, 0x40}, {0x01, 0x61, 0x41},
+ {0x01, 0x62, 0x42}, {0x01, 0x63, 0x43}, {0x01, 0x64, 0x44},
+ {0x01, 0x65, 0x45}, {0x01, 0x66, 0x46}, {0x01, 0x67, 0x47},
+ {0x01, 0x68, 0x48}, {0x01, 0x69, 0x49}, {0x01, 0x6a, 0x4a},
+ {0x01, 0x6b, 0x4b}, {0x01, 0x6c, 0x4c}, {0x01, 0x6d, 0x4d},
+ {0x01, 0x6e, 0x4e}, {0x01, 0x6f, 0x4f}, {0x01, 0x70, 0x50},
+ {0x01, 0x71, 0x51}, {0x01, 0x72, 0x52}, {0x01, 0x73, 0x53},
+ {0x01, 0x74, 0x54}, {0x01, 0x75, 0x55}, {0x01, 0x76, 0x56},
+ {0x01, 0x77, 0x57}, {0x01, 0x78, 0x58}, {0x01, 0x79, 0x59},
+ {0x01, 0x7a, 0x5a}, {0x00, 0x5b, 0x5b}, {0x00, 0x5c, 0x5c},
+ {0x00, 0x5d, 0x5d}, {0x00, 0x5e, 0x5e}, {0x00, 0x5f, 0x5f},
+ {0x00, 0x60, 0x60}, {0x00, 0x61, 0x41}, {0x00, 0x62, 0x42},
+ {0x00, 0x63, 0x43}, {0x00, 0x64, 0x44}, {0x00, 0x65, 0x45},
+ {0x00, 0x66, 0x46}, {0x00, 0x67, 0x47}, {0x00, 0x68, 0x48},
+ {0x00, 0x69, 0x49}, {0x00, 0x6a, 0x4a}, {0x00, 0x6b, 0x4b},
+ {0x00, 0x6c, 0x4c}, {0x00, 0x6d, 0x4d}, {0x00, 0x6e, 0x4e},
+ {0x00, 0x6f, 0x4f}, {0x00, 0x70, 0x50}, {0x00, 0x71, 0x51},
+ {0x00, 0x72, 0x52}, {0x00, 0x73, 0x53}, {0x00, 0x74, 0x54},
+ {0x00, 0x75, 0x55}, {0x00, 0x76, 0x56}, {0x00, 0x77, 0x57},
+ {0x00, 0x78, 0x58}, {0x00, 0x79, 0x59}, {0x00, 0x7a, 0x5a},
+ {0x00, 0x7b, 0x7b}, {0x00, 0x7c, 0x7c}, {0x00, 0x7d, 0x7d},
+ {0x00, 0x7e, 0x7e}, {0x00, 0x7f, 0x7f}, {0x00, 0x80, 0x80},
+ {0x00, 0x81, 0x81}, {0x00, 0x82, 0x82}, {0x00, 0x83, 0x83},
+ {0x00, 0x84, 0x84}, {0x00, 0x85, 0x85}, {0x00, 0x86, 0x86},
+ {0x00, 0x87, 0x87}, {0x00, 0x88, 0x88}, {0x00, 0x89, 0x89},
+ {0x00, 0x8a, 0x8a}, {0x00, 0x8b, 0x8b}, {0x00, 0x8c, 0x8c},
+ {0x00, 0x8d, 0x8d}, {0x00, 0x8e, 0x8e}, {0x00, 0x8f, 0x8f},
+ {0x00, 0x90, 0x90}, {0x00, 0x91, 0x91}, {0x00, 0x92, 0x92},
+ {0x00, 0x93, 0x93}, {0x00, 0x94, 0x94}, {0x00, 0x95, 0x95},
+ {0x00, 0x96, 0x96}, {0x00, 0x97, 0x97}, {0x00, 0x98, 0x98},
+ {0x00, 0x99, 0x99}, {0x00, 0x9a, 0x9a}, {0x00, 0x9b, 0x9b},
+ {0x00, 0x9c, 0x9c}, {0x00, 0x9d, 0x9d}, {0x00, 0x9e, 0x9e},
+ {0x00, 0x9f, 0x9f}, {0x00, 0xa0, 0xa0}, {0x00, 0xa1, 0xa1},
+ {0x00, 0xa2, 0xa2}, {0x00, 0xa3, 0xa3}, {0x00, 0xa4, 0xa4},
+ {0x00, 0xa5, 0xa5}, {0x00, 0xa6, 0xa6}, {0x00, 0xa7, 0xa7},
+ {0x00, 0xa8, 0xa8}, {0x00, 0xa9, 0xa9}, {0x00, 0xaa, 0xaa},
+ {0x00, 0xab, 0xab}, {0x00, 0xac, 0xac}, {0x00, 0xad, 0xad},
+ {0x00, 0xae, 0xae}, {0x00, 0xaf, 0xaf}, {0x00, 0xb0, 0xb0},
+ {0x00, 0xb1, 0xb1}, {0x00, 0xb2, 0xb2}, {0x00, 0xb3, 0xb3},
+ {0x00, 0xb4, 0xb4}, {0x00, 0xb5, 0xb5}, {0x00, 0xb6, 0xb6},
+ {0x00, 0xb7, 0xb7}, {0x00, 0xb8, 0xb8}, {0x00, 0xb9, 0xb9},
+ {0x00, 0xba, 0xba}, {0x00, 0xbb, 0xbb}, {0x00, 0xbc, 0xbc},
+ {0x00, 0xbd, 0xbd}, {0x00, 0xbe, 0xbe}, {0x00, 0xbf, 0xbf},
+ {0x00, 0xc0, 0xc0}, {0x00, 0xc1, 0xc1}, {0x00, 0xc2, 0xc2},
+ {0x00, 0xc3, 0xc3}, {0x00, 0xc4, 0xc4}, {0x00, 0xc5, 0xc5},
+ {0x00, 0xc6, 0xc6}, {0x00, 0xc7, 0xc7}, {0x00, 0xc8, 0xc8},
+ {0x00, 0xc9, 0xc9}, {0x00, 0xca, 0xca}, {0x00, 0xcb, 0xcb},
+ {0x00, 0xcc, 0xcc}, {0x00, 0xcd, 0xcd}, {0x00, 0xce, 0xce},
+ {0x00, 0xcf, 0xcf}, {0x00, 0xd0, 0xd0}, {0x00, 0xd1, 0xd1},
+ {0x00, 0xd2, 0xd2}, {0x00, 0xd3, 0xd3}, {0x00, 0xd4, 0xd4},
+ {0x00, 0xd5, 0xd5}, {0x00, 0xd6, 0xd6}, {0x00, 0xd7, 0xd7},
+ {0x00, 0xd8, 0xd8}, {0x00, 0xd9, 0xd9}, {0x00, 0xda, 0xda},
+ {0x00, 0xdb, 0xdb}, {0x00, 0xdc, 0xdc}, {0x00, 0xdd, 0xdd},
+ {0x00, 0xde, 0xde}, {0x00, 0xdf, 0xdf}, {0x00, 0xe0, 0xe0},
+ {0x00, 0xe1, 0xe1}, {0x00, 0xe2, 0xe2}, {0x00, 0xe3, 0xe3},
+ {0x00, 0xe4, 0xe4}, {0x00, 0xe5, 0xe5}, {0x00, 0xe6, 0xe6},
+ {0x00, 0xe7, 0xe7}, {0x00, 0xe8, 0xe8}, {0x00, 0xe9, 0xe9},
+ {0x00, 0xea, 0xea}, {0x00, 0xeb, 0xeb}, {0x00, 0xec, 0xec},
+ {0x00, 0xed, 0xed}, {0x00, 0xee, 0xee}, {0x00, 0xef, 0xef},
+ {0x00, 0xf0, 0xf0}, {0x00, 0xf1, 0xf1}, {0x00, 0xf2, 0xf2},
+ {0x00, 0xf3, 0xf3}, {0x00, 0xf4, 0xf4}, {0x00, 0xf5, 0xf5},
+ {0x00, 0xf6, 0xf6}, {0x00, 0xf7, 0xf7}, {0x00, 0xf8, 0xf8},
+ {0x00, 0xf9, 0xf9}, {0x00, 0xfa, 0xfa}, {0x00, 0xfb, 0xfb},
+ {0x00, 0xfc, 0xfc}, {0x00, 0xfd, 0xfd}, {0x00, 0xfe, 0xfe},
+ {0x00, 0xff, 0xff}};
+
+static struct cs_info iso7_tbl[] = {
+ {0x00, 0x00, 0x00}, {0x00, 0x01, 0x01}, {0x00, 0x02, 0x02},
+ {0x00, 0x03, 0x03}, {0x00, 0x04, 0x04}, {0x00, 0x05, 0x05},
+ {0x00, 0x06, 0x06}, {0x00, 0x07, 0x07}, {0x00, 0x08, 0x08},
+ {0x00, 0x09, 0x09}, {0x00, 0x0a, 0x0a}, {0x00, 0x0b, 0x0b},
+ {0x00, 0x0c, 0x0c}, {0x00, 0x0d, 0x0d}, {0x00, 0x0e, 0x0e},
+ {0x00, 0x0f, 0x0f}, {0x00, 0x10, 0x10}, {0x00, 0x11, 0x11},
+ {0x00, 0x12, 0x12}, {0x00, 0x13, 0x13}, {0x00, 0x14, 0x14},
+ {0x00, 0x15, 0x15}, {0x00, 0x16, 0x16}, {0x00, 0x17, 0x17},
+ {0x00, 0x18, 0x18}, {0x00, 0x19, 0x19}, {0x00, 0x1a, 0x1a},
+ {0x00, 0x1b, 0x1b}, {0x00, 0x1c, 0x1c}, {0x00, 0x1d, 0x1d},
+ {0x00, 0x1e, 0x1e}, {0x00, 0x1f, 0x1f}, {0x00, 0x20, 0x20},
+ {0x00, 0x21, 0x21}, {0x00, 0x22, 0x22}, {0x00, 0x23, 0x23},
+ {0x00, 0x24, 0x24}, {0x00, 0x25, 0x25}, {0x00, 0x26, 0x26},
+ {0x00, 0x27, 0x27}, {0x00, 0x28, 0x28}, {0x00, 0x29, 0x29},
+ {0x00, 0x2a, 0x2a}, {0x00, 0x2b, 0x2b}, {0x00, 0x2c, 0x2c},
+ {0x00, 0x2d, 0x2d}, {0x00, 0x2e, 0x2e}, {0x00, 0x2f, 0x2f},
+ {0x00, 0x30, 0x30}, {0x00, 0x31, 0x31}, {0x00, 0x32, 0x32},
+ {0x00, 0x33, 0x33}, {0x00, 0x34, 0x34}, {0x00, 0x35, 0x35},
+ {0x00, 0x36, 0x36}, {0x00, 0x37, 0x37}, {0x00, 0x38, 0x38},
+ {0x00, 0x39, 0x39}, {0x00, 0x3a, 0x3a}, {0x00, 0x3b, 0x3b},
+ {0x00, 0x3c, 0x3c}, {0x00, 0x3d, 0x3d}, {0x00, 0x3e, 0x3e},
+ {0x00, 0x3f, 0x3f}, {0x00, 0x40, 0x40}, {0x01, 0x61, 0x41},
+ {0x01, 0x62, 0x42}, {0x01, 0x63, 0x43}, {0x01, 0x64, 0x44},
+ {0x01, 0x65, 0x45}, {0x01, 0x66, 0x46}, {0x01, 0x67, 0x47},
+ {0x01, 0x68, 0x48}, {0x01, 0x69, 0x49}, {0x01, 0x6a, 0x4a},
+ {0x01, 0x6b, 0x4b}, {0x01, 0x6c, 0x4c}, {0x01, 0x6d, 0x4d},
+ {0x01, 0x6e, 0x4e}, {0x01, 0x6f, 0x4f}, {0x01, 0x70, 0x50},
+ {0x01, 0x71, 0x51}, {0x01, 0x72, 0x52}, {0x01, 0x73, 0x53},
+ {0x01, 0x74, 0x54}, {0x01, 0x75, 0x55}, {0x01, 0x76, 0x56},
+ {0x01, 0x77, 0x57}, {0x01, 0x78, 0x58}, {0x01, 0x79, 0x59},
+ {0x01, 0x7a, 0x5a}, {0x00, 0x5b, 0x5b}, {0x00, 0x5c, 0x5c},
+ {0x00, 0x5d, 0x5d}, {0x00, 0x5e, 0x5e}, {0x00, 0x5f, 0x5f},
+ {0x00, 0x60, 0x60}, {0x00, 0x61, 0x41}, {0x00, 0x62, 0x42},
+ {0x00, 0x63, 0x43}, {0x00, 0x64, 0x44}, {0x00, 0x65, 0x45},
+ {0x00, 0x66, 0x46}, {0x00, 0x67, 0x47}, {0x00, 0x68, 0x48},
+ {0x00, 0x69, 0x49}, {0x00, 0x6a, 0x4a}, {0x00, 0x6b, 0x4b},
+ {0x00, 0x6c, 0x4c}, {0x00, 0x6d, 0x4d}, {0x00, 0x6e, 0x4e},
+ {0x00, 0x6f, 0x4f}, {0x00, 0x70, 0x50}, {0x00, 0x71, 0x51},
+ {0x00, 0x72, 0x52}, {0x00, 0x73, 0x53}, {0x00, 0x74, 0x54},
+ {0x00, 0x75, 0x55}, {0x00, 0x76, 0x56}, {0x00, 0x77, 0x57},
+ {0x00, 0x78, 0x58}, {0x00, 0x79, 0x59}, {0x00, 0x7a, 0x5a},
+ {0x00, 0x7b, 0x7b}, {0x00, 0x7c, 0x7c}, {0x00, 0x7d, 0x7d},
+ {0x00, 0x7e, 0x7e}, {0x00, 0x7f, 0x7f}, {0x00, 0x80, 0x80},
+ {0x00, 0x81, 0x81}, {0x00, 0x82, 0x82}, {0x00, 0x83, 0x83},
+ {0x00, 0x84, 0x84}, {0x00, 0x85, 0x85}, {0x00, 0x86, 0x86},
+ {0x00, 0x87, 0x87}, {0x00, 0x88, 0x88}, {0x00, 0x89, 0x89},
+ {0x00, 0x8a, 0x8a}, {0x00, 0x8b, 0x8b}, {0x00, 0x8c, 0x8c},
+ {0x00, 0x8d, 0x8d}, {0x00, 0x8e, 0x8e}, {0x00, 0x8f, 0x8f},
+ {0x00, 0x90, 0x90}, {0x00, 0x91, 0x91}, {0x00, 0x92, 0x92},
+ {0x00, 0x93, 0x93}, {0x00, 0x94, 0x94}, {0x00, 0x95, 0x95},
+ {0x00, 0x96, 0x96}, {0x00, 0x97, 0x97}, {0x00, 0x98, 0x98},
+ {0x00, 0x99, 0x99}, {0x00, 0x9a, 0x9a}, {0x00, 0x9b, 0x9b},
+ {0x00, 0x9c, 0x9c}, {0x00, 0x9d, 0x9d}, {0x00, 0x9e, 0x9e},
+ {0x00, 0x9f, 0x9f}, {0x00, 0xa0, 0xa0}, {0x00, 0xa1, 0xa1},
+ {0x00, 0xa2, 0xa2}, {0x00, 0xa3, 0xa3}, {0x00, 0xa4, 0xa4},
+ {0x00, 0xa5, 0xa5}, {0x00, 0xa6, 0xa6}, {0x00, 0xa7, 0xa7},
+ {0x00, 0xa8, 0xa8}, {0x00, 0xa9, 0xa9}, {0x00, 0xaa, 0xaa},
+ {0x00, 0xab, 0xab}, {0x00, 0xac, 0xac}, {0x00, 0xad, 0xad},
+ {0x00, 0xae, 0xae}, {0x00, 0xaf, 0xaf}, {0x00, 0xb0, 0xb0},
+ {0x00, 0xb1, 0xb1}, {0x00, 0xb2, 0xb2}, {0x00, 0xb3, 0xb3},
+ {0x00, 0xb4, 0xb4}, {0x00, 0xb5, 0xb5}, {0x01, 0xdc, 0xb6},
+ {0x00, 0xb7, 0xb7}, {0x01, 0xdd, 0xb8}, {0x01, 0xde, 0xb9},
+ {0x01, 0xdf, 0xba}, {0x00, 0xbb, 0xbb}, {0x01, 0xfc, 0xbc},
+ {0x00, 0xbd, 0xbd}, {0x01, 0xfd, 0xbe}, {0x01, 0xfe, 0xbf},
+ {0x00, 0xc0, 0xc0}, {0x01, 0xe1, 0xc1}, {0x01, 0xe2, 0xc2},
+ {0x01, 0xe3, 0xc3}, {0x01, 0xe4, 0xc4}, {0x01, 0xe5, 0xc5},
+ {0x01, 0xe6, 0xc6}, {0x01, 0xe7, 0xc7}, {0x01, 0xe8, 0xc8},
+ {0x01, 0xe9, 0xc9}, {0x01, 0xea, 0xca}, {0x01, 0xeb, 0xcb},
+ {0x01, 0xec, 0xcc}, {0x01, 0xed, 0xcd}, {0x01, 0xee, 0xce},
+ {0x01, 0xef, 0xcf}, {0x01, 0xf0, 0xd0}, {0x01, 0xf1, 0xd1},
+ {0x00, 0xd2, 0xd2}, {0x01, 0xf3, 0xd3}, {0x01, 0xf4, 0xd4},
+ {0x01, 0xf5, 0xd5}, {0x01, 0xf6, 0xd6}, {0x01, 0xf7, 0xd7},
+ {0x01, 0xf8, 0xd8}, {0x01, 0xf9, 0xd9}, {0x01, 0xfa, 0xda},
+ {0x01, 0xfb, 0xdb}, {0x00, 0xdc, 0xb6}, {0x00, 0xdd, 0xb8},
+ {0x00, 0xde, 0xb9}, {0x00, 0xdf, 0xba}, {0x00, 0xe0, 0xe0},
+ {0x00, 0xe1, 0xc1}, {0x00, 0xe2, 0xc2}, {0x00, 0xe3, 0xc3},
+ {0x00, 0xe4, 0xc4}, {0x00, 0xe5, 0xc5}, {0x00, 0xe6, 0xc6},
+ {0x00, 0xe7, 0xc7}, {0x00, 0xe8, 0xc8}, {0x00, 0xe9, 0xc9},
+ {0x00, 0xea, 0xca}, {0x00, 0xeb, 0xcb}, {0x00, 0xec, 0xcc},
+ {0x00, 0xed, 0xcd}, {0x00, 0xee, 0xce}, {0x00, 0xef, 0xcf},
+ {0x00, 0xf0, 0xd0}, {0x00, 0xf1, 0xd1}, {0x00, 0xf2, 0xd3},
+ {0x00, 0xf3, 0xd3}, {0x00, 0xf4, 0xd4}, {0x00, 0xf5, 0xd5},
+ {0x00, 0xf6, 0xd6}, {0x00, 0xf7, 0xd7}, {0x00, 0xf8, 0xd8},
+ {0x00, 0xf9, 0xd9}, {0x00, 0xfa, 0xda}, {0x00, 0xfb, 0xdb},
+ {0x00, 0xfc, 0xbc}, {0x00, 0xfd, 0xbe}, {0x00, 0xfe, 0xbf},
+ {0x00, 0xff, 0xff}};
+
+static struct cs_info iso8_tbl[] = {
+ {0x00, 0x00, 0x00}, {0x00, 0x01, 0x01}, {0x00, 0x02, 0x02},
+ {0x00, 0x03, 0x03}, {0x00, 0x04, 0x04}, {0x00, 0x05, 0x05},
+ {0x00, 0x06, 0x06}, {0x00, 0x07, 0x07}, {0x00, 0x08, 0x08},
+ {0x00, 0x09, 0x09}, {0x00, 0x0a, 0x0a}, {0x00, 0x0b, 0x0b},
+ {0x00, 0x0c, 0x0c}, {0x00, 0x0d, 0x0d}, {0x00, 0x0e, 0x0e},
+ {0x00, 0x0f, 0x0f}, {0x00, 0x10, 0x10}, {0x00, 0x11, 0x11},
+ {0x00, 0x12, 0x12}, {0x00, 0x13, 0x13}, {0x00, 0x14, 0x14},
+ {0x00, 0x15, 0x15}, {0x00, 0x16, 0x16}, {0x00, 0x17, 0x17},
+ {0x00, 0x18, 0x18}, {0x00, 0x19, 0x19}, {0x00, 0x1a, 0x1a},
+ {0x00, 0x1b, 0x1b}, {0x00, 0x1c, 0x1c}, {0x00, 0x1d, 0x1d},
+ {0x00, 0x1e, 0x1e}, {0x00, 0x1f, 0x1f}, {0x00, 0x20, 0x20},
+ {0x00, 0x21, 0x21}, {0x00, 0x22, 0x22}, {0x00, 0x23, 0x23},
+ {0x00, 0x24, 0x24}, {0x00, 0x25, 0x25}, {0x00, 0x26, 0x26},
+ {0x00, 0x27, 0x27}, {0x00, 0x28, 0x28}, {0x00, 0x29, 0x29},
+ {0x00, 0x2a, 0x2a}, {0x00, 0x2b, 0x2b}, {0x00, 0x2c, 0x2c},
+ {0x00, 0x2d, 0x2d}, {0x00, 0x2e, 0x2e}, {0x00, 0x2f, 0x2f},
+ {0x00, 0x30, 0x30}, {0x00, 0x31, 0x31}, {0x00, 0x32, 0x32},
+ {0x00, 0x33, 0x33}, {0x00, 0x34, 0x34}, {0x00, 0x35, 0x35},
+ {0x00, 0x36, 0x36}, {0x00, 0x37, 0x37}, {0x00, 0x38, 0x38},
+ {0x00, 0x39, 0x39}, {0x00, 0x3a, 0x3a}, {0x00, 0x3b, 0x3b},
+ {0x00, 0x3c, 0x3c}, {0x00, 0x3d, 0x3d}, {0x00, 0x3e, 0x3e},
+ {0x00, 0x3f, 0x3f}, {0x00, 0x40, 0x40}, {0x01, 0x61, 0x41},
+ {0x01, 0x62, 0x42}, {0x01, 0x63, 0x43}, {0x01, 0x64, 0x44},
+ {0x01, 0x65, 0x45}, {0x01, 0x66, 0x46}, {0x01, 0x67, 0x47},
+ {0x01, 0x68, 0x48}, {0x01, 0x69, 0x49}, {0x01, 0x6a, 0x4a},
+ {0x01, 0x6b, 0x4b}, {0x01, 0x6c, 0x4c}, {0x01, 0x6d, 0x4d},
+ {0x01, 0x6e, 0x4e}, {0x01, 0x6f, 0x4f}, {0x01, 0x70, 0x50},
+ {0x01, 0x71, 0x51}, {0x01, 0x72, 0x52}, {0x01, 0x73, 0x53},
+ {0x01, 0x74, 0x54}, {0x01, 0x75, 0x55}, {0x01, 0x76, 0x56},
+ {0x01, 0x77, 0x57}, {0x01, 0x78, 0x58}, {0x01, 0x79, 0x59},
+ {0x01, 0x7a, 0x5a}, {0x00, 0x5b, 0x5b}, {0x00, 0x5c, 0x5c},
+ {0x00, 0x5d, 0x5d}, {0x00, 0x5e, 0x5e}, {0x00, 0x5f, 0x5f},
+ {0x00, 0x60, 0x60}, {0x00, 0x61, 0x41}, {0x00, 0x62, 0x42},
+ {0x00, 0x63, 0x43}, {0x00, 0x64, 0x44}, {0x00, 0x65, 0x45},
+ {0x00, 0x66, 0x46}, {0x00, 0x67, 0x47}, {0x00, 0x68, 0x48},
+ {0x00, 0x69, 0x49}, {0x00, 0x6a, 0x4a}, {0x00, 0x6b, 0x4b},
+ {0x00, 0x6c, 0x4c}, {0x00, 0x6d, 0x4d}, {0x00, 0x6e, 0x4e},
+ {0x00, 0x6f, 0x4f}, {0x00, 0x70, 0x50}, {0x00, 0x71, 0x51},
+ {0x00, 0x72, 0x52}, {0x00, 0x73, 0x53}, {0x00, 0x74, 0x54},
+ {0x00, 0x75, 0x55}, {0x00, 0x76, 0x56}, {0x00, 0x77, 0x57},
+ {0x00, 0x78, 0x58}, {0x00, 0x79, 0x59}, {0x00, 0x7a, 0x5a},
+ {0x00, 0x7b, 0x7b}, {0x00, 0x7c, 0x7c}, {0x00, 0x7d, 0x7d},
+ {0x00, 0x7e, 0x7e}, {0x00, 0x7f, 0x7f}, {0x00, 0x80, 0x80},
+ {0x00, 0x81, 0x81}, {0x00, 0x82, 0x82}, {0x00, 0x83, 0x83},
+ {0x00, 0x84, 0x84}, {0x00, 0x85, 0x85}, {0x00, 0x86, 0x86},
+ {0x00, 0x87, 0x87}, {0x00, 0x88, 0x88}, {0x00, 0x89, 0x89},
+ {0x00, 0x8a, 0x8a}, {0x00, 0x8b, 0x8b}, {0x00, 0x8c, 0x8c},
+ {0x00, 0x8d, 0x8d}, {0x00, 0x8e, 0x8e}, {0x00, 0x8f, 0x8f},
+ {0x00, 0x90, 0x90}, {0x00, 0x91, 0x91}, {0x00, 0x92, 0x92},
+ {0x00, 0x93, 0x93}, {0x00, 0x94, 0x94}, {0x00, 0x95, 0x95},
+ {0x00, 0x96, 0x96}, {0x00, 0x97, 0x97}, {0x00, 0x98, 0x98},
+ {0x00, 0x99, 0x99}, {0x00, 0x9a, 0x9a}, {0x00, 0x9b, 0x9b},
+ {0x00, 0x9c, 0x9c}, {0x00, 0x9d, 0x9d}, {0x00, 0x9e, 0x9e},
+ {0x00, 0x9f, 0x9f}, {0x00, 0xa0, 0xa0}, {0x00, 0xa1, 0xa1},
+ {0x00, 0xa2, 0xa2}, {0x00, 0xa3, 0xa3}, {0x00, 0xa4, 0xa4},
+ {0x00, 0xa5, 0xa5}, {0x00, 0xa6, 0xa6}, {0x00, 0xa7, 0xa7},
+ {0x00, 0xa8, 0xa8}, {0x00, 0xa9, 0xa9}, {0x00, 0xaa, 0xaa},
+ {0x00, 0xab, 0xab}, {0x00, 0xac, 0xac}, {0x00, 0xad, 0xad},
+ {0x00, 0xae, 0xae}, {0x00, 0xaf, 0xaf}, {0x00, 0xb0, 0xb0},
+ {0x00, 0xb1, 0xb1}, {0x00, 0xb2, 0xb2}, {0x00, 0xb3, 0xb3},
+ {0x00, 0xb4, 0xb4}, {0x00, 0xb5, 0xb5}, {0x00, 0xb6, 0xb6},
+ {0x00, 0xb7, 0xb7}, {0x00, 0xb8, 0xb8}, {0x00, 0xb9, 0xb9},
+ {0x00, 0xba, 0xba}, {0x00, 0xbb, 0xbb}, {0x00, 0xbc, 0xbc},
+ {0x00, 0xbd, 0xbd}, {0x00, 0xbe, 0xbe}, {0x00, 0xbf, 0xbf},
+ {0x00, 0xc0, 0xc0}, {0x00, 0xc1, 0xc1}, {0x00, 0xc2, 0xc2},
+ {0x00, 0xc3, 0xc3}, {0x00, 0xc4, 0xc4}, {0x00, 0xc5, 0xc5},
+ {0x00, 0xc6, 0xc6}, {0x00, 0xc7, 0xc7}, {0x00, 0xc8, 0xc8},
+ {0x00, 0xc9, 0xc9}, {0x00, 0xca, 0xca}, {0x00, 0xcb, 0xcb},
+ {0x00, 0xcc, 0xcc}, {0x00, 0xcd, 0xcd}, {0x00, 0xce, 0xce},
+ {0x00, 0xcf, 0xcf}, {0x00, 0xd0, 0xd0}, {0x00, 0xd1, 0xd1},
+ {0x00, 0xd2, 0xd2}, {0x00, 0xd3, 0xd3}, {0x00, 0xd4, 0xd4},
+ {0x00, 0xd5, 0xd5}, {0x00, 0xd6, 0xd6}, {0x00, 0xd7, 0xd7},
+ {0x00, 0xd8, 0xd8}, {0x00, 0xd9, 0xd9}, {0x00, 0xda, 0xda},
+ {0x00, 0xdb, 0xdb}, {0x00, 0xdc, 0xdc}, {0x00, 0xdd, 0xdd},
+ {0x00, 0xde, 0xde}, {0x00, 0xdf, 0xdf}, {0x00, 0xe0, 0xe0},
+ {0x00, 0xe1, 0xe1}, {0x00, 0xe2, 0xe2}, {0x00, 0xe3, 0xe3},
+ {0x00, 0xe4, 0xe4}, {0x00, 0xe5, 0xe5}, {0x00, 0xe6, 0xe6},
+ {0x00, 0xe7, 0xe7}, {0x00, 0xe8, 0xe8}, {0x00, 0xe9, 0xe9},
+ {0x00, 0xea, 0xea}, {0x00, 0xeb, 0xeb}, {0x00, 0xec, 0xec},
+ {0x00, 0xed, 0xed}, {0x00, 0xee, 0xee}, {0x00, 0xef, 0xef},
+ {0x00, 0xf0, 0xf0}, {0x00, 0xf1, 0xf1}, {0x00, 0xf2, 0xf2},
+ {0x00, 0xf3, 0xf3}, {0x00, 0xf4, 0xf4}, {0x00, 0xf5, 0xf5},
+ {0x00, 0xf6, 0xf6}, {0x00, 0xf7, 0xf7}, {0x00, 0xf8, 0xf8},
+ {0x00, 0xf9, 0xf9}, {0x00, 0xfa, 0xfa}, {0x00, 0xfb, 0xfb},
+ {0x00, 0xfc, 0xfc}, {0x00, 0xfd, 0xfd}, {0x00, 0xfe, 0xfe},
+ {0x00, 0xff, 0xff}};
+
+static struct cs_info iso9_tbl[] = {
+ {0x00, 0x00, 0x00}, {0x00, 0x01, 0x01}, {0x00, 0x02, 0x02},
+ {0x00, 0x03, 0x03}, {0x00, 0x04, 0x04}, {0x00, 0x05, 0x05},
+ {0x00, 0x06, 0x06}, {0x00, 0x07, 0x07}, {0x00, 0x08, 0x08},
+ {0x00, 0x09, 0x09}, {0x00, 0x0a, 0x0a}, {0x00, 0x0b, 0x0b},
+ {0x00, 0x0c, 0x0c}, {0x00, 0x0d, 0x0d}, {0x00, 0x0e, 0x0e},
+ {0x00, 0x0f, 0x0f}, {0x00, 0x10, 0x10}, {0x00, 0x11, 0x11},
+ {0x00, 0x12, 0x12}, {0x00, 0x13, 0x13}, {0x00, 0x14, 0x14},
+ {0x00, 0x15, 0x15}, {0x00, 0x16, 0x16}, {0x00, 0x17, 0x17},
+ {0x00, 0x18, 0x18}, {0x00, 0x19, 0x19}, {0x00, 0x1a, 0x1a},
+ {0x00, 0x1b, 0x1b}, {0x00, 0x1c, 0x1c}, {0x00, 0x1d, 0x1d},
+ {0x00, 0x1e, 0x1e}, {0x00, 0x1f, 0x1f}, {0x00, 0x20, 0x20},
+ {0x00, 0x21, 0x21}, {0x00, 0x22, 0x22}, {0x00, 0x23, 0x23},
+ {0x00, 0x24, 0x24}, {0x00, 0x25, 0x25}, {0x00, 0x26, 0x26},
+ {0x00, 0x27, 0x27}, {0x00, 0x28, 0x28}, {0x00, 0x29, 0x29},
+ {0x00, 0x2a, 0x2a}, {0x00, 0x2b, 0x2b}, {0x00, 0x2c, 0x2c},
+ {0x00, 0x2d, 0x2d}, {0x00, 0x2e, 0x2e}, {0x00, 0x2f, 0x2f},
+ {0x00, 0x30, 0x30}, {0x00, 0x31, 0x31}, {0x00, 0x32, 0x32},
+ {0x00, 0x33, 0x33}, {0x00, 0x34, 0x34}, {0x00, 0x35, 0x35},
+ {0x00, 0x36, 0x36}, {0x00, 0x37, 0x37}, {0x00, 0x38, 0x38},
+ {0x00, 0x39, 0x39}, {0x00, 0x3a, 0x3a}, {0x00, 0x3b, 0x3b},
+ {0x00, 0x3c, 0x3c}, {0x00, 0x3d, 0x3d}, {0x00, 0x3e, 0x3e},
+ {0x00, 0x3f, 0x3f}, {0x00, 0x40, 0x40}, {0x01, 0x61, 0x41},
+ {0x01, 0x62, 0x42}, {0x01, 0x63, 0x43}, {0x01, 0x64, 0x44},
+ {0x01, 0x65, 0x45}, {0x01, 0x66, 0x46}, {0x01, 0x67, 0x47},
+ {0x01, 0x68, 0x48}, {0x01, 0xfd, 0x49}, {0x01, 0x6a, 0x4a},
+ {0x01, 0x6b, 0x4b}, {0x01, 0x6c, 0x4c}, {0x01, 0x6d, 0x4d},
+ {0x01, 0x6e, 0x4e}, {0x01, 0x6f, 0x4f}, {0x01, 0x70, 0x50},
+ {0x01, 0x71, 0x51}, {0x01, 0x72, 0x52}, {0x01, 0x73, 0x53},
+ {0x01, 0x74, 0x54}, {0x01, 0x75, 0x55}, {0x01, 0x76, 0x56},
+ {0x01, 0x77, 0x57}, {0x01, 0x78, 0x58}, {0x01, 0x79, 0x59},
+ {0x01, 0x7a, 0x5a}, {0x00, 0x5b, 0x5b}, {0x00, 0x5c, 0x5c},
+ {0x00, 0x5d, 0x5d}, {0x00, 0x5e, 0x5e}, {0x00, 0x5f, 0x5f},
+ {0x00, 0x60, 0x60}, {0x00, 0x61, 0x41}, {0x00, 0x62, 0x42},
+ {0x00, 0x63, 0x43}, {0x00, 0x64, 0x44}, {0x00, 0x65, 0x45},
+ {0x00, 0x66, 0x46}, {0x00, 0x67, 0x47}, {0x00, 0x68, 0x48},
+ {0x00, 0x69, 0xdd}, {0x00, 0x6a, 0x4a}, {0x00, 0x6b, 0x4b},
+ {0x00, 0x6c, 0x4c}, {0x00, 0x6d, 0x4d}, {0x00, 0x6e, 0x4e},
+ {0x00, 0x6f, 0x4f}, {0x00, 0x70, 0x50}, {0x00, 0x71, 0x51},
+ {0x00, 0x72, 0x52}, {0x00, 0x73, 0x53}, {0x00, 0x74, 0x54},
+ {0x00, 0x75, 0x55}, {0x00, 0x76, 0x56}, {0x00, 0x77, 0x57},
+ {0x00, 0x78, 0x58}, {0x00, 0x79, 0x59}, {0x00, 0x7a, 0x5a},
+ {0x00, 0x7b, 0x7b}, {0x00, 0x7c, 0x7c}, {0x00, 0x7d, 0x7d},
+ {0x00, 0x7e, 0x7e}, {0x00, 0x7f, 0x7f}, {0x00, 0x80, 0x80},
+ {0x00, 0x81, 0x81}, {0x00, 0x82, 0x82}, {0x00, 0x83, 0x83},
+ {0x00, 0x84, 0x84}, {0x00, 0x85, 0x85}, {0x00, 0x86, 0x86},
+ {0x00, 0x87, 0x87}, {0x00, 0x88, 0x88}, {0x00, 0x89, 0x89},
+ {0x00, 0x8a, 0x8a}, {0x00, 0x8b, 0x8b}, {0x00, 0x8c, 0x8c},
+ {0x00, 0x8d, 0x8d}, {0x00, 0x8e, 0x8e}, {0x00, 0x8f, 0x8f},
+ {0x00, 0x90, 0x90}, {0x00, 0x91, 0x91}, {0x00, 0x92, 0x92},
+ {0x00, 0x93, 0x93}, {0x00, 0x94, 0x94}, {0x00, 0x95, 0x95},
+ {0x00, 0x96, 0x96}, {0x00, 0x97, 0x97}, {0x00, 0x98, 0x98},
+ {0x00, 0x99, 0x99}, {0x00, 0x9a, 0x9a}, {0x00, 0x9b, 0x9b},
+ {0x00, 0x9c, 0x9c}, {0x00, 0x9d, 0x9d}, {0x00, 0x9e, 0x9e},
+ {0x00, 0x9f, 0x9f}, {0x00, 0xa0, 0xa0}, {0x00, 0xa1, 0xa1},
+ {0x00, 0xa2, 0xa2}, {0x00, 0xa3, 0xa3}, {0x00, 0xa4, 0xa4},
+ {0x00, 0xa5, 0xa5}, {0x00, 0xa6, 0xa6}, {0x00, 0xa7, 0xa7},
+ {0x00, 0xa8, 0xa8}, {0x00, 0xa9, 0xa9}, {0x00, 0xaa, 0xaa},
+ {0x00, 0xab, 0xab}, {0x00, 0xac, 0xac}, {0x00, 0xad, 0xad},
+ {0x00, 0xae, 0xae}, {0x00, 0xaf, 0xaf}, {0x00, 0xb0, 0xb0},
+ {0x00, 0xb1, 0xb1}, {0x00, 0xb2, 0xb2}, {0x00, 0xb3, 0xb3},
+ {0x00, 0xb4, 0xb4}, {0x00, 0xb5, 0xb5}, {0x00, 0xb6, 0xb6},
+ {0x00, 0xb7, 0xb7}, {0x00, 0xb8, 0xb8}, {0x00, 0xb9, 0xb9},
+ {0x00, 0xba, 0xba}, {0x00, 0xbb, 0xbb}, {0x00, 0xbc, 0xbc},
+ {0x00, 0xbd, 0xbd}, {0x00, 0xbe, 0xbe}, {0x00, 0xbf, 0xbf},
+ {0x01, 0xe0, 0xc0}, {0x01, 0xe1, 0xc1}, {0x01, 0xe2, 0xc2},
+ {0x01, 0xe3, 0xc3}, {0x01, 0xe4, 0xc4}, {0x01, 0xe5, 0xc5},
+ {0x01, 0xe6, 0xc6}, {0x01, 0xe7, 0xc7}, {0x01, 0xe8, 0xc8},
+ {0x01, 0xe9, 0xc9}, {0x01, 0xea, 0xca}, {0x01, 0xeb, 0xcb},
+ {0x01, 0xec, 0xcc}, {0x01, 0xed, 0xcd}, {0x01, 0xee, 0xce},
+ {0x01, 0xef, 0xcf}, {0x01, 0xf0, 0xd0}, {0x01, 0xf1, 0xd1},
+ {0x01, 0xf2, 0xd2}, {0x01, 0xf3, 0xd3}, {0x01, 0xf4, 0xd4},
+ {0x01, 0xf5, 0xd5}, {0x01, 0xf6, 0xd6}, {0x00, 0xd7, 0xd7},
+ {0x01, 0xf8, 0xd8}, {0x01, 0xf9, 0xd9}, {0x01, 0xfa, 0xda},
+ {0x01, 0xfb, 0xdb}, {0x01, 0xfc, 0xdc}, {0x01, 0x69, 0xdd},
+ {0x01, 0xfe, 0xde}, {0x00, 0xdf, 0xdf}, {0x00, 0xe0, 0xc0},
+ {0x00, 0xe1, 0xc1}, {0x00, 0xe2, 0xc2}, {0x00, 0xe3, 0xc3},
+ {0x00, 0xe4, 0xc4}, {0x00, 0xe5, 0xc5}, {0x00, 0xe6, 0xc6},
+ {0x00, 0xe7, 0xc7}, {0x00, 0xe8, 0xc8}, {0x00, 0xe9, 0xc9},
+ {0x00, 0xea, 0xca}, {0x00, 0xeb, 0xcb}, {0x00, 0xec, 0xcc},
+ {0x00, 0xed, 0xcd}, {0x00, 0xee, 0xce}, {0x00, 0xef, 0xcf},
+ {0x00, 0xf0, 0xd0}, {0x00, 0xf1, 0xd1}, {0x00, 0xf2, 0xd2},
+ {0x00, 0xf3, 0xd3}, {0x00, 0xf4, 0xd4}, {0x00, 0xf5, 0xd5},
+ {0x00, 0xf6, 0xd6}, {0x00, 0xf7, 0xf7}, {0x00, 0xf8, 0xd8},
+ {0x00, 0xf9, 0xd9}, {0x00, 0xfa, 0xda}, {0x00, 0xfb, 0xdb},
+ {0x00, 0xfc, 0xdc}, {0x00, 0xfd, 0x49}, {0x00, 0xfe, 0xde},
+ {0x00, 0xff, 0xff}};
+
+static struct cs_info iso10_tbl[] = {
+ {0x00, 0x00, 0x00}, {0x00, 0x01, 0x01}, {0x00, 0x02, 0x02},
+ {0x00, 0x03, 0x03}, {0x00, 0x04, 0x04}, {0x00, 0x05, 0x05},
+ {0x00, 0x06, 0x06}, {0x00, 0x07, 0x07}, {0x00, 0x08, 0x08},
+ {0x00, 0x09, 0x09}, {0x00, 0x0a, 0x0a}, {0x00, 0x0b, 0x0b},
+ {0x00, 0x0c, 0x0c}, {0x00, 0x0d, 0x0d}, {0x00, 0x0e, 0x0e},
+ {0x00, 0x0f, 0x0f}, {0x00, 0x10, 0x10}, {0x00, 0x11, 0x11},
+ {0x00, 0x12, 0x12}, {0x00, 0x13, 0x13}, {0x00, 0x14, 0x14},
+ {0x00, 0x15, 0x15}, {0x00, 0x16, 0x16}, {0x00, 0x17, 0x17},
+ {0x00, 0x18, 0x18}, {0x00, 0x19, 0x19}, {0x00, 0x1a, 0x1a},
+ {0x00, 0x1b, 0x1b}, {0x00, 0x1c, 0x1c}, {0x00, 0x1d, 0x1d},
+ {0x00, 0x1e, 0x1e}, {0x00, 0x1f, 0x1f}, {0x00, 0x20, 0x20},
+ {0x00, 0x21, 0x21}, {0x00, 0x22, 0x22}, {0x00, 0x23, 0x23},
+ {0x00, 0x24, 0x24}, {0x00, 0x25, 0x25}, {0x00, 0x26, 0x26},
+ {0x00, 0x27, 0x27}, {0x00, 0x28, 0x28}, {0x00, 0x29, 0x29},
+ {0x00, 0x2a, 0x2a}, {0x00, 0x2b, 0x2b}, {0x00, 0x2c, 0x2c},
+ {0x00, 0x2d, 0x2d}, {0x00, 0x2e, 0x2e}, {0x00, 0x2f, 0x2f},
+ {0x00, 0x30, 0x30}, {0x00, 0x31, 0x31}, {0x00, 0x32, 0x32},
+ {0x00, 0x33, 0x33}, {0x00, 0x34, 0x34}, {0x00, 0x35, 0x35},
+ {0x00, 0x36, 0x36}, {0x00, 0x37, 0x37}, {0x00, 0x38, 0x38},
+ {0x00, 0x39, 0x39}, {0x00, 0x3a, 0x3a}, {0x00, 0x3b, 0x3b},
+ {0x00, 0x3c, 0x3c}, {0x00, 0x3d, 0x3d}, {0x00, 0x3e, 0x3e},
+ {0x00, 0x3f, 0x3f}, {0x00, 0x40, 0x40}, {0x01, 0x61, 0x41},
+ {0x01, 0x62, 0x42}, {0x01, 0x63, 0x43}, {0x01, 0x64, 0x44},
+ {0x01, 0x65, 0x45}, {0x01, 0x66, 0x46}, {0x01, 0x67, 0x47},
+ {0x01, 0x68, 0x48}, {0x01, 0x69, 0x49}, {0x01, 0x6a, 0x4a},
+ {0x01, 0x6b, 0x4b}, {0x01, 0x6c, 0x4c}, {0x01, 0x6d, 0x4d},
+ {0x01, 0x6e, 0x4e}, {0x01, 0x6f, 0x4f}, {0x01, 0x70, 0x50},
+ {0x01, 0x71, 0x51}, {0x01, 0x72, 0x52}, {0x01, 0x73, 0x53},
+ {0x01, 0x74, 0x54}, {0x01, 0x75, 0x55}, {0x01, 0x76, 0x56},
+ {0x01, 0x77, 0x57}, {0x01, 0x78, 0x58}, {0x01, 0x79, 0x59},
+ {0x01, 0x7a, 0x5a}, {0x00, 0x5b, 0x5b}, {0x00, 0x5c, 0x5c},
+ {0x00, 0x5d, 0x5d}, {0x00, 0x5e, 0x5e}, {0x00, 0x5f, 0x5f},
+ {0x00, 0x60, 0x60}, {0x00, 0x61, 0x41}, {0x00, 0x62, 0x42},
+ {0x00, 0x63, 0x43}, {0x00, 0x64, 0x44}, {0x00, 0x65, 0x45},
+ {0x00, 0x66, 0x46}, {0x00, 0x67, 0x47}, {0x00, 0x68, 0x48},
+ {0x00, 0x69, 0x49}, {0x00, 0x6a, 0x4a}, {0x00, 0x6b, 0x4b},
+ {0x00, 0x6c, 0x4c}, {0x00, 0x6d, 0x4d}, {0x00, 0x6e, 0x4e},
+ {0x00, 0x6f, 0x4f}, {0x00, 0x70, 0x50}, {0x00, 0x71, 0x51},
+ {0x00, 0x72, 0x52}, {0x00, 0x73, 0x53}, {0x00, 0x74, 0x54},
+ {0x00, 0x75, 0x55}, {0x00, 0x76, 0x56}, {0x00, 0x77, 0x57},
+ {0x00, 0x78, 0x58}, {0x00, 0x79, 0x59}, {0x00, 0x7a, 0x5a},
+ {0x00, 0x7b, 0x7b}, {0x00, 0x7c, 0x7c}, {0x00, 0x7d, 0x7d},
+ {0x00, 0x7e, 0x7e}, {0x00, 0x7f, 0x7f}, {0x00, 0x80, 0x80},
+ {0x00, 0x81, 0x81}, {0x00, 0x82, 0x82}, {0x00, 0x83, 0x83},
+ {0x00, 0x84, 0x84}, {0x00, 0x85, 0x85}, {0x00, 0x86, 0x86},
+ {0x00, 0x87, 0x87}, {0x00, 0x88, 0x88}, {0x00, 0x89, 0x89},
+ {0x00, 0x8a, 0x8a}, {0x00, 0x8b, 0x8b}, {0x00, 0x8c, 0x8c},
+ {0x00, 0x8d, 0x8d}, {0x00, 0x8e, 0x8e}, {0x00, 0x8f, 0x8f},
+ {0x00, 0x90, 0x90}, {0x00, 0x91, 0x91}, {0x00, 0x92, 0x92},
+ {0x00, 0x93, 0x93}, {0x00, 0x94, 0x94}, {0x00, 0x95, 0x95},
+ {0x00, 0x96, 0x96}, {0x00, 0x97, 0x97}, {0x00, 0x98, 0x98},
+ {0x00, 0x99, 0x99}, {0x00, 0x9a, 0x9a}, {0x00, 0x9b, 0x9b},
+ {0x00, 0x9c, 0x9c}, {0x00, 0x9d, 0x9d}, {0x00, 0x9e, 0x9e},
+ {0x00, 0x9f, 0x9f}, {0x00, 0xa0, 0xa0}, {0x00, 0xa1, 0xa1},
+ {0x00, 0xa2, 0xa2}, {0x00, 0xa3, 0xa3}, {0x00, 0xa4, 0xa4},
+ {0x00, 0xa5, 0xa5}, {0x00, 0xa6, 0xa6}, {0x00, 0xa7, 0xa7},
+ {0x00, 0xa8, 0xa8}, {0x00, 0xa9, 0xa9}, {0x00, 0xaa, 0xaa},
+ {0x00, 0xab, 0xab}, {0x00, 0xac, 0xac}, {0x00, 0xad, 0xad},
+ {0x00, 0xae, 0xae}, {0x00, 0xaf, 0xaf}, {0x00, 0xb0, 0xb0},
+ {0x00, 0xb1, 0xb1}, {0x00, 0xb2, 0xb2}, {0x00, 0xb3, 0xb3},
+ {0x00, 0xb4, 0xb4}, {0x00, 0xb5, 0xb5}, {0x00, 0xb6, 0xb6},
+ {0x00, 0xb7, 0xb7}, {0x00, 0xb8, 0xb8}, {0x00, 0xb9, 0xb9},
+ {0x00, 0xba, 0xba}, {0x00, 0xbb, 0xbb}, {0x00, 0xbc, 0xbc},
+ {0x00, 0xbd, 0xbd}, {0x00, 0xbe, 0xbe}, {0x00, 0xbf, 0xbf},
+ {0x00, 0xc0, 0xc0}, {0x00, 0xc1, 0xc1}, {0x00, 0xc2, 0xc2},
+ {0x00, 0xc3, 0xc3}, {0x00, 0xc4, 0xc4}, {0x00, 0xc5, 0xc5},
+ {0x00, 0xc6, 0xc6}, {0x00, 0xc7, 0xc7}, {0x00, 0xc8, 0xc8},
+ {0x00, 0xc9, 0xc9}, {0x00, 0xca, 0xca}, {0x00, 0xcb, 0xcb},
+ {0x00, 0xcc, 0xcc}, {0x00, 0xcd, 0xcd}, {0x00, 0xce, 0xce},
+ {0x00, 0xcf, 0xcf}, {0x00, 0xd0, 0xd0}, {0x00, 0xd1, 0xd1},
+ {0x00, 0xd2, 0xd2}, {0x00, 0xd3, 0xd3}, {0x00, 0xd4, 0xd4},
+ {0x00, 0xd5, 0xd5}, {0x00, 0xd6, 0xd6}, {0x00, 0xd7, 0xd7},
+ {0x00, 0xd8, 0xd8}, {0x00, 0xd9, 0xd9}, {0x00, 0xda, 0xda},
+ {0x00, 0xdb, 0xdb}, {0x00, 0xdc, 0xdc}, {0x00, 0xdd, 0xdd},
+ {0x00, 0xde, 0xde}, {0x00, 0xdf, 0xdf}, {0x00, 0xe0, 0xe0},
+ {0x00, 0xe1, 0xe1}, {0x00, 0xe2, 0xe2}, {0x00, 0xe3, 0xe3},
+ {0x00, 0xe4, 0xe4}, {0x00, 0xe5, 0xe5}, {0x00, 0xe6, 0xe6},
+ {0x00, 0xe7, 0xe7}, {0x00, 0xe8, 0xe8}, {0x00, 0xe9, 0xe9},
+ {0x00, 0xea, 0xea}, {0x00, 0xeb, 0xeb}, {0x00, 0xec, 0xec},
+ {0x00, 0xed, 0xed}, {0x00, 0xee, 0xee}, {0x00, 0xef, 0xef},
+ {0x00, 0xf0, 0xf0}, {0x00, 0xf1, 0xf1}, {0x00, 0xf2, 0xf2},
+ {0x00, 0xf3, 0xf3}, {0x00, 0xf4, 0xf4}, {0x00, 0xf5, 0xf5},
+ {0x00, 0xf6, 0xf6}, {0x00, 0xf7, 0xf7}, {0x00, 0xf8, 0xf8},
+ {0x00, 0xf9, 0xf9}, {0x00, 0xfa, 0xfa}, {0x00, 0xfb, 0xfb},
+ {0x00, 0xfc, 0xfc}, {0x00, 0xfd, 0xfd}, {0x00, 0xfe, 0xfe},
+ {0x00, 0xff, 0xff}};
+
+static struct cs_info koi8r_tbl[] = {
+ {0x00, 0x00, 0x00}, {0x00, 0x01, 0x01}, {0x00, 0x02, 0x02},
+ {0x00, 0x03, 0x03}, {0x00, 0x04, 0x04}, {0x00, 0x05, 0x05},
+ {0x00, 0x06, 0x06}, {0x00, 0x07, 0x07}, {0x00, 0x08, 0x08},
+ {0x00, 0x09, 0x09}, {0x00, 0x0a, 0x0a}, {0x00, 0x0b, 0x0b},
+ {0x00, 0x0c, 0x0c}, {0x00, 0x0d, 0x0d}, {0x00, 0x0e, 0x0e},
+ {0x00, 0x0f, 0x0f}, {0x00, 0x10, 0x10}, {0x00, 0x11, 0x11},
+ {0x00, 0x12, 0x12}, {0x00, 0x13, 0x13}, {0x00, 0x14, 0x14},
+ {0x00, 0x15, 0x15}, {0x00, 0x16, 0x16}, {0x00, 0x17, 0x17},
+ {0x00, 0x18, 0x18}, {0x00, 0x19, 0x19}, {0x00, 0x1a, 0x1a},
+ {0x00, 0x1b, 0x1b}, {0x00, 0x1c, 0x1c}, {0x00, 0x1d, 0x1d},
+ {0x00, 0x1e, 0x1e}, {0x00, 0x1f, 0x1f}, {0x00, 0x20, 0x20},
+ {0x00, 0x21, 0x21}, {0x00, 0x22, 0x22}, {0x00, 0x23, 0x23},
+ {0x00, 0x24, 0x24}, {0x00, 0x25, 0x25}, {0x00, 0x26, 0x26},
+ {0x00, 0x27, 0x27}, {0x00, 0x28, 0x28}, {0x00, 0x29, 0x29},
+ {0x00, 0x2a, 0x2a}, {0x00, 0x2b, 0x2b}, {0x00, 0x2c, 0x2c},
+ {0x00, 0x2d, 0x2d}, {0x00, 0x2e, 0x2e}, {0x00, 0x2f, 0x2f},
+ {0x00, 0x30, 0x30}, {0x00, 0x31, 0x31}, {0x00, 0x32, 0x32},
+ {0x00, 0x33, 0x33}, {0x00, 0x34, 0x34}, {0x00, 0x35, 0x35},
+ {0x00, 0x36, 0x36}, {0x00, 0x37, 0x37}, {0x00, 0x38, 0x38},
+ {0x00, 0x39, 0x39}, {0x00, 0x3a, 0x3a}, {0x00, 0x3b, 0x3b},
+ {0x00, 0x3c, 0x3c}, {0x00, 0x3d, 0x3d}, {0x00, 0x3e, 0x3e},
+ {0x00, 0x3f, 0x3f}, {0x00, 0x40, 0x40}, {0x01, 0x61, 0x41},
+ {0x01, 0x62, 0x42}, {0x01, 0x63, 0x43}, {0x01, 0x64, 0x44},
+ {0x01, 0x65, 0x45}, {0x01, 0x66, 0x46}, {0x01, 0x67, 0x47},
+ {0x01, 0x68, 0x48}, {0x01, 0x69, 0x49}, {0x01, 0x6a, 0x4a},
+ {0x01, 0x6b, 0x4b}, {0x01, 0x6c, 0x4c}, {0x01, 0x6d, 0x4d},
+ {0x01, 0x6e, 0x4e}, {0x01, 0x6f, 0x4f}, {0x01, 0x70, 0x50},
+ {0x01, 0x71, 0x51}, {0x01, 0x72, 0x52}, {0x01, 0x73, 0x53},
+ {0x01, 0x74, 0x54}, {0x01, 0x75, 0x55}, {0x01, 0x76, 0x56},
+ {0x01, 0x77, 0x57}, {0x01, 0x78, 0x58}, {0x01, 0x79, 0x59},
+ {0x01, 0x7a, 0x5a}, {0x00, 0x5b, 0x5b}, {0x00, 0x5c, 0x5c},
+ {0x00, 0x5d, 0x5d}, {0x00, 0x5e, 0x5e}, {0x00, 0x5f, 0x5f},
+ {0x00, 0x60, 0x60}, {0x00, 0x61, 0x41}, {0x00, 0x62, 0x42},
+ {0x00, 0x63, 0x43}, {0x00, 0x64, 0x44}, {0x00, 0x65, 0x45},
+ {0x00, 0x66, 0x46}, {0x00, 0x67, 0x47}, {0x00, 0x68, 0x48},
+ {0x00, 0x69, 0x49}, {0x00, 0x6a, 0x4a}, {0x00, 0x6b, 0x4b},
+ {0x00, 0x6c, 0x4c}, {0x00, 0x6d, 0x4d}, {0x00, 0x6e, 0x4e},
+ {0x00, 0x6f, 0x4f}, {0x00, 0x70, 0x50}, {0x00, 0x71, 0x51},
+ {0x00, 0x72, 0x52}, {0x00, 0x73, 0x53}, {0x00, 0x74, 0x54},
+ {0x00, 0x75, 0x55}, {0x00, 0x76, 0x56}, {0x00, 0x77, 0x57},
+ {0x00, 0x78, 0x58}, {0x00, 0x79, 0x59}, {0x00, 0x7a, 0x5a},
+ {0x00, 0x7b, 0x7b}, {0x00, 0x7c, 0x7c}, {0x00, 0x7d, 0x7d},
+ {0x00, 0x7e, 0x7e}, {0x00, 0x7f, 0x7f}, {0x00, 0x80, 0x80},
+ {0x00, 0x81, 0x81}, {0x00, 0x82, 0x82}, {0x00, 0x83, 0x83},
+ {0x00, 0x84, 0x84}, {0x00, 0x85, 0x85}, {0x00, 0x86, 0x86},
+ {0x00, 0x87, 0x87}, {0x00, 0x88, 0x88}, {0x00, 0x89, 0x89},
+ {0x00, 0x8a, 0x8a}, {0x00, 0x8b, 0x8b}, {0x00, 0x8c, 0x8c},
+ {0x00, 0x8d, 0x8d}, {0x00, 0x8e, 0x8e}, {0x00, 0x8f, 0x8f},
+ {0x00, 0x90, 0x90}, {0x00, 0x91, 0x91}, {0x00, 0x92, 0x92},
+ {0x00, 0x93, 0x93}, {0x00, 0x94, 0x94}, {0x00, 0x95, 0x95},
+ {0x00, 0x96, 0x96}, {0x00, 0x97, 0x97}, {0x00, 0x98, 0x98},
+ {0x00, 0x99, 0x99}, {0x00, 0x9a, 0x9a}, {0x00, 0x9b, 0x9b},
+ {0x00, 0x9c, 0x9c}, {0x00, 0x9d, 0x9d}, {0x00, 0x9e, 0x9e},
+ {0x00, 0x9f, 0x9f}, {0x00, 0xa0, 0xa0}, {0x00, 0xa1, 0xa1},
+ {0x00, 0xa2, 0xa2}, {0x00, 0xa3, 0xb3}, {0x00, 0xa4, 0xa4},
+ {0x00, 0xa5, 0xa5}, {0x00, 0xa6, 0xa6}, {0x00, 0xa7, 0xa7},
+ {0x00, 0xa8, 0xa8}, {0x00, 0xa9, 0xa9}, {0x00, 0xaa, 0xaa},
+ {0x00, 0xab, 0xab}, {0x00, 0xac, 0xac}, {0x00, 0xad, 0xad},
+ {0x00, 0xae, 0xae}, {0x00, 0xaf, 0xaf}, {0x00, 0xb0, 0xb0},
+ {0x00, 0xb1, 0xb1}, {0x00, 0xb2, 0xb2}, {0x01, 0xa3, 0xb3},
+ {0x00, 0xb4, 0xb4}, {0x00, 0xb5, 0xb5}, {0x00, 0xb6, 0xb6},
+ {0x00, 0xb7, 0xb7}, {0x00, 0xb8, 0xb8}, {0x00, 0xb9, 0xb9},
+ {0x00, 0xba, 0xba}, {0x00, 0xbb, 0xbb}, {0x00, 0xbc, 0xbc},
+ {0x00, 0xbd, 0xbd}, {0x00, 0xbe, 0xbe}, {0x00, 0xbf, 0xbf},
+ {0x00, 0xc0, 0xe0}, {0x00, 0xc1, 0xe1}, {0x00, 0xc2, 0xe2},
+ {0x00, 0xc3, 0xe3}, {0x00, 0xc4, 0xe4}, {0x00, 0xc5, 0xe5},
+ {0x00, 0xc6, 0xe6}, {0x00, 0xc7, 0xe7}, {0x00, 0xc8, 0xe8},
+ {0x00, 0xc9, 0xe9}, {0x00, 0xca, 0xea}, {0x00, 0xcb, 0xeb},
+ {0x00, 0xcc, 0xec}, {0x00, 0xcd, 0xed}, {0x00, 0xce, 0xee},
+ {0x00, 0xcf, 0xef}, {0x00, 0xd0, 0xf0}, {0x00, 0xd1, 0xf1},
+ {0x00, 0xd2, 0xf2}, {0x00, 0xd3, 0xf3}, {0x00, 0xd4, 0xf4},
+ {0x00, 0xd5, 0xf5}, {0x00, 0xd6, 0xf6}, {0x00, 0xd7, 0xf7},
+ {0x00, 0xd8, 0xf8}, {0x00, 0xd9, 0xf9}, {0x00, 0xda, 0xfa},
+ {0x00, 0xdb, 0xfb}, {0x00, 0xdc, 0xfc}, {0x00, 0xdd, 0xfd},
+ {0x00, 0xde, 0xfe}, {0x00, 0xdf, 0xff}, {0x01, 0xc0, 0xe0},
+ {0x01, 0xc1, 0xe1}, {0x01, 0xc2, 0xe2}, {0x01, 0xc3, 0xe3},
+ {0x01, 0xc4, 0xe4}, {0x01, 0xc5, 0xe5}, {0x01, 0xc6, 0xe6},
+ {0x01, 0xc7, 0xe7}, {0x01, 0xc8, 0xe8}, {0x01, 0xc9, 0xe9},
+ {0x01, 0xca, 0xea}, {0x01, 0xcb, 0xeb}, {0x01, 0xcc, 0xec},
+ {0x01, 0xcd, 0xed}, {0x01, 0xce, 0xee}, {0x01, 0xcf, 0xef},
+ {0x01, 0xd0, 0xf0}, {0x01, 0xd1, 0xf1}, {0x01, 0xd2, 0xf2},
+ {0x01, 0xd3, 0xf3}, {0x01, 0xd4, 0xf4}, {0x01, 0xd5, 0xf5},
+ {0x01, 0xd6, 0xf6}, {0x01, 0xd7, 0xf7}, {0x01, 0xd8, 0xf8},
+ {0x01, 0xd9, 0xf9}, {0x01, 0xda, 0xfa}, {0x01, 0xdb, 0xfb},
+ {0x01, 0xdc, 0xfc}, {0x01, 0xdd, 0xfd}, {0x01, 0xde, 0xfe},
+ {0x01, 0xdf, 0xff}};
+
+static struct cs_info koi8u_tbl[] = {
+ {0x00, 0x00, 0x00}, {0x00, 0x01, 0x01}, {0x00, 0x02, 0x02},
+ {0x00, 0x03, 0x03}, {0x00, 0x04, 0x04}, {0x00, 0x05, 0x05},
+ {0x00, 0x06, 0x06}, {0x00, 0x07, 0x07}, {0x00, 0x08, 0x08},
+ {0x00, 0x09, 0x09}, {0x00, 0x0a, 0x0a}, {0x00, 0x0b, 0x0b},
+ {0x00, 0x0c, 0x0c}, {0x00, 0x0d, 0x0d}, {0x00, 0x0e, 0x0e},
+ {0x00, 0x0f, 0x0f}, {0x00, 0x10, 0x10}, {0x00, 0x11, 0x11},
+ {0x00, 0x12, 0x12}, {0x00, 0x13, 0x13}, {0x00, 0x14, 0x14},
+ {0x00, 0x15, 0x15}, {0x00, 0x16, 0x16}, {0x00, 0x17, 0x17},
+ {0x00, 0x18, 0x18}, {0x00, 0x19, 0x19}, {0x00, 0x1a, 0x1a},
+ {0x00, 0x1b, 0x1b}, {0x00, 0x1c, 0x1c}, {0x00, 0x1d, 0x1d},
+ {0x00, 0x1e, 0x1e}, {0x00, 0x1f, 0x1f}, {0x00, 0x20, 0x20},
+ {0x00, 0x21, 0x21}, {0x00, 0x22, 0x22}, {0x00, 0x23, 0x23},
+ {0x00, 0x24, 0x24}, {0x00, 0x25, 0x25}, {0x00, 0x26, 0x26},
+ {0x00, 0x27, 0x27}, {0x00, 0x28, 0x28}, {0x00, 0x29, 0x29},
+ {0x00, 0x2a, 0x2a}, {0x00, 0x2b, 0x2b}, {0x00, 0x2c, 0x2c},
+ {0x00, 0x2d, 0x2d}, {0x00, 0x2e, 0x2e}, {0x00, 0x2f, 0x2f},
+ {0x00, 0x30, 0x30}, {0x00, 0x31, 0x31}, {0x00, 0x32, 0x32},
+ {0x00, 0x33, 0x33}, {0x00, 0x34, 0x34}, {0x00, 0x35, 0x35},
+ {0x00, 0x36, 0x36}, {0x00, 0x37, 0x37}, {0x00, 0x38, 0x38},
+ {0x00, 0x39, 0x39}, {0x00, 0x3a, 0x3a}, {0x00, 0x3b, 0x3b},
+ {0x00, 0x3c, 0x3c}, {0x00, 0x3d, 0x3d}, {0x00, 0x3e, 0x3e},
+ {0x00, 0x3f, 0x3f}, {0x00, 0x40, 0x40}, {0x01, 0x61, 0x41},
+ {0x01, 0x62, 0x42}, {0x01, 0x63, 0x43}, {0x01, 0x64, 0x44},
+ {0x01, 0x65, 0x45}, {0x01, 0x66, 0x46}, {0x01, 0x67, 0x47},
+ {0x01, 0x68, 0x48}, {0x01, 0x69, 0x49}, {0x01, 0x6a, 0x4a},
+ {0x01, 0x6b, 0x4b}, {0x01, 0x6c, 0x4c}, {0x01, 0x6d, 0x4d},
+ {0x01, 0x6e, 0x4e}, {0x01, 0x6f, 0x4f}, {0x01, 0x70, 0x50},
+ {0x01, 0x71, 0x51}, {0x01, 0x72, 0x52}, {0x01, 0x73, 0x53},
+ {0x01, 0x74, 0x54}, {0x01, 0x75, 0x55}, {0x01, 0x76, 0x56},
+ {0x01, 0x77, 0x57}, {0x01, 0x78, 0x58}, {0x01, 0x79, 0x59},
+ {0x01, 0x7a, 0x5a}, {0x00, 0x5b, 0x5b}, {0x00, 0x5c, 0x5c},
+ {0x00, 0x5d, 0x5d}, {0x00, 0x5e, 0x5e}, {0x00, 0x5f, 0x5f},
+ {0x00, 0x60, 0x60}, {0x00, 0x61, 0x41}, {0x00, 0x62, 0x42},
+ {0x00, 0x63, 0x43}, {0x00, 0x64, 0x44}, {0x00, 0x65, 0x45},
+ {0x00, 0x66, 0x46}, {0x00, 0x67, 0x47}, {0x00, 0x68, 0x48},
+ {0x00, 0x69, 0x49}, {0x00, 0x6a, 0x4a}, {0x00, 0x6b, 0x4b},
+ {0x00, 0x6c, 0x4c}, {0x00, 0x6d, 0x4d}, {0x00, 0x6e, 0x4e},
+ {0x00, 0x6f, 0x4f}, {0x00, 0x70, 0x50}, {0x00, 0x71, 0x51},
+ {0x00, 0x72, 0x52}, {0x00, 0x73, 0x53}, {0x00, 0x74, 0x54},
+ {0x00, 0x75, 0x55}, {0x00, 0x76, 0x56}, {0x00, 0x77, 0x57},
+ {0x00, 0x78, 0x58}, {0x00, 0x79, 0x59}, {0x00, 0x7a, 0x5a},
+ {0x00, 0x7b, 0x7b}, {0x00, 0x7c, 0x7c}, {0x00, 0x7d, 0x7d},
+ {0x00, 0x7e, 0x7e}, {0x00, 0x7f, 0x7f}, {0x00, 0x80, 0x80},
+ {0x00, 0x81, 0x81}, {0x00, 0x82, 0x82}, {0x00, 0x83, 0x83},
+ {0x00, 0x84, 0x84}, {0x00, 0x85, 0x85}, {0x00, 0x86, 0x86},
+ {0x00, 0x87, 0x87}, {0x00, 0x88, 0x88}, {0x00, 0x89, 0x89},
+ {0x00, 0x8a, 0x8a}, {0x00, 0x8b, 0x8b}, {0x00, 0x8c, 0x8c},
+ {0x00, 0x8d, 0x8d}, {0x00, 0x8e, 0x8e}, {0x00, 0x8f, 0x8f},
+ {0x00, 0x90, 0x90}, {0x00, 0x91, 0x91}, {0x00, 0x92, 0x92},
+ {0x00, 0x93, 0x93}, {0x00, 0x94, 0x94}, {0x00, 0x95, 0x95},
+ {0x00, 0x96, 0x96}, {0x00, 0x97, 0x97}, {0x00, 0x98, 0x98},
+ {0x00, 0x99, 0x99}, {0x00, 0x9a, 0x9a}, {0x00, 0x9b, 0x9b},
+ {0x00, 0x9c, 0x9c}, {0x00, 0x9d, 0x9d}, {0x00, 0x9e, 0x9e},
+ {0x00, 0x9f, 0x9f}, {0x00, 0xa0, 0xa0}, {0x00, 0xa1, 0xa1},
+ {0x00, 0xa2, 0xa2}, {0x00, 0xa3, 0xb3}, {0x00, 0xa4, 0xb4}, /* ie */
+ {0x00, 0xa5, 0xa5}, {0x00, 0xa6, 0xb6}, /* i */
+ {0x00, 0xa7, 0xb7}, /* ii */
+ {0x00, 0xa8, 0xa8}, {0x00, 0xa9, 0xa9}, {0x00, 0xaa, 0xaa},
+ {0x00, 0xab, 0xab}, {0x00, 0xac, 0xac}, {0x00, 0xad, 0xbd}, /* g'' */
+ {0x00, 0xae, 0xae}, {0x00, 0xaf, 0xaf}, {0x00, 0xb0, 0xb0},
+ {0x00, 0xb1, 0xb1}, {0x00, 0xb2, 0xb2}, {0x01, 0xa3, 0xb3},
+ {0x00, 0xb4, 0xb4}, /* IE */
+ {0x00, 0xb5, 0xb5}, {0x00, 0xb6, 0xb6}, /* I */
+ {0x00, 0xb7, 0xb7}, /* II */
+ {0x00, 0xb8, 0xb8}, {0x00, 0xb9, 0xb9}, {0x00, 0xba, 0xba},
+ {0x00, 0xbb, 0xbb}, {0x00, 0xbc, 0xbc}, {0x00, 0xbd, 0xbd},
+ {0x00, 0xbe, 0xbe}, {0x00, 0xbf, 0xbf}, {0x00, 0xc0, 0xe0},
+ {0x00, 0xc1, 0xe1}, {0x00, 0xc2, 0xe2}, {0x00, 0xc3, 0xe3},
+ {0x00, 0xc4, 0xe4}, {0x00, 0xc5, 0xe5}, {0x00, 0xc6, 0xe6},
+ {0x00, 0xc7, 0xe7}, {0x00, 0xc8, 0xe8}, {0x00, 0xc9, 0xe9},
+ {0x00, 0xca, 0xea}, {0x00, 0xcb, 0xeb}, {0x00, 0xcc, 0xec},
+ {0x00, 0xcd, 0xed}, {0x00, 0xce, 0xee}, {0x00, 0xcf, 0xef},
+ {0x00, 0xd0, 0xf0}, {0x00, 0xd1, 0xf1}, {0x00, 0xd2, 0xf2},
+ {0x00, 0xd3, 0xf3}, {0x00, 0xd4, 0xf4}, {0x00, 0xd5, 0xf5},
+ {0x00, 0xd6, 0xf6}, {0x00, 0xd7, 0xf7}, {0x00, 0xd8, 0xf8},
+ {0x00, 0xd9, 0xf9}, {0x00, 0xda, 0xfa}, {0x00, 0xdb, 0xfb},
+ {0x00, 0xdc, 0xfc}, {0x00, 0xdd, 0xfd}, {0x00, 0xde, 0xfe},
+ {0x00, 0xdf, 0xff}, {0x01, 0xc0, 0xe0}, {0x01, 0xc1, 0xe1},
+ {0x01, 0xc2, 0xe2}, {0x01, 0xc3, 0xe3}, {0x01, 0xc4, 0xe4},
+ {0x01, 0xc5, 0xe5}, {0x01, 0xc6, 0xe6}, {0x01, 0xc7, 0xe7},
+ {0x01, 0xc8, 0xe8}, {0x01, 0xc9, 0xe9}, {0x01, 0xca, 0xea},
+ {0x01, 0xcb, 0xeb}, {0x01, 0xcc, 0xec}, {0x01, 0xcd, 0xed},
+ {0x01, 0xce, 0xee}, {0x01, 0xcf, 0xef}, {0x01, 0xd0, 0xf0},
+ {0x01, 0xd1, 0xf1}, {0x01, 0xd2, 0xf2}, {0x01, 0xd3, 0xf3},
+ {0x01, 0xd4, 0xf4}, {0x01, 0xd5, 0xf5}, {0x01, 0xd6, 0xf6},
+ {0x01, 0xd7, 0xf7}, {0x01, 0xd8, 0xf8}, {0x01, 0xd9, 0xf9},
+ {0x01, 0xda, 0xfa}, {0x01, 0xdb, 0xfb}, {0x01, 0xdc, 0xfc},
+ {0x01, 0xdd, 0xfd}, {0x01, 0xde, 0xfe}, {0x01, 0xdf, 0xff}};
+
+static struct cs_info cp1251_tbl[] = {
+ {0x00, 0x00, 0x00}, {0x00, 0x01, 0x01}, {0x00, 0x02, 0x02},
+ {0x00, 0x03, 0x03}, {0x00, 0x04, 0x04}, {0x00, 0x05, 0x05},
+ {0x00, 0x06, 0x06}, {0x00, 0x07, 0x07}, {0x00, 0x08, 0x08},
+ {0x00, 0x09, 0x09}, {0x00, 0x0a, 0x0a}, {0x00, 0x0b, 0x0b},
+ {0x00, 0x0c, 0x0c}, {0x00, 0x0d, 0x0d}, {0x00, 0x0e, 0x0e},
+ {0x00, 0x0f, 0x0f}, {0x00, 0x10, 0x10}, {0x00, 0x11, 0x11},
+ {0x00, 0x12, 0x12}, {0x00, 0x13, 0x13}, {0x00, 0x14, 0x14},
+ {0x00, 0x15, 0x15}, {0x00, 0x16, 0x16}, {0x00, 0x17, 0x17},
+ {0x00, 0x18, 0x18}, {0x00, 0x19, 0x19}, {0x00, 0x1a, 0x1a},
+ {0x00, 0x1b, 0x1b}, {0x00, 0x1c, 0x1c}, {0x00, 0x1d, 0x1d},
+ {0x00, 0x1e, 0x1e}, {0x00, 0x1f, 0x1f}, {0x00, 0x20, 0x20},
+ {0x00, 0x21, 0x21}, {0x00, 0x22, 0x22}, {0x00, 0x23, 0x23},
+ {0x00, 0x24, 0x24}, {0x00, 0x25, 0x25}, {0x00, 0x26, 0x26},
+ {0x00, 0x27, 0x27}, {0x00, 0x28, 0x28}, {0x00, 0x29, 0x29},
+ {0x00, 0x2a, 0x2a}, {0x00, 0x2b, 0x2b}, {0x00, 0x2c, 0x2c},
+ {0x00, 0x2d, 0x2d}, {0x00, 0x2e, 0x2e}, {0x00, 0x2f, 0x2f},
+ {0x00, 0x30, 0x30}, {0x00, 0x31, 0x31}, {0x00, 0x32, 0x32},
+ {0x00, 0x33, 0x33}, {0x00, 0x34, 0x34}, {0x00, 0x35, 0x35},
+ {0x00, 0x36, 0x36}, {0x00, 0x37, 0x37}, {0x00, 0x38, 0x38},
+ {0x00, 0x39, 0x39}, {0x00, 0x3a, 0x3a}, {0x00, 0x3b, 0x3b},
+ {0x00, 0x3c, 0x3c}, {0x00, 0x3d, 0x3d}, {0x00, 0x3e, 0x3e},
+ {0x00, 0x3f, 0x3f}, {0x00, 0x40, 0x40}, {0x01, 0x61, 0x41},
+ {0x01, 0x62, 0x42}, {0x01, 0x63, 0x43}, {0x01, 0x64, 0x44},
+ {0x01, 0x65, 0x45}, {0x01, 0x66, 0x46}, {0x01, 0x67, 0x47},
+ {0x01, 0x68, 0x48}, {0x01, 0x69, 0x49}, {0x01, 0x6a, 0x4a},
+ {0x01, 0x6b, 0x4b}, {0x01, 0x6c, 0x4c}, {0x01, 0x6d, 0x4d},
+ {0x01, 0x6e, 0x4e}, {0x01, 0x6f, 0x4f}, {0x01, 0x70, 0x50},
+ {0x01, 0x71, 0x51}, {0x01, 0x72, 0x52}, {0x01, 0x73, 0x53},
+ {0x01, 0x74, 0x54}, {0x01, 0x75, 0x55}, {0x01, 0x76, 0x56},
+ {0x01, 0x77, 0x57}, {0x01, 0x78, 0x58}, {0x01, 0x79, 0x59},
+ {0x01, 0x7a, 0x5a}, {0x00, 0x5b, 0x5b}, {0x00, 0x5c, 0x5c},
+ {0x00, 0x5d, 0x5d}, {0x00, 0x5e, 0x5e}, {0x00, 0x5f, 0x5f},
+ {0x00, 0x60, 0x60}, {0x00, 0x61, 0x41}, {0x00, 0x62, 0x42},
+ {0x00, 0x63, 0x43}, {0x00, 0x64, 0x44}, {0x00, 0x65, 0x45},
+ {0x00, 0x66, 0x46}, {0x00, 0x67, 0x47}, {0x00, 0x68, 0x48},
+ {0x00, 0x69, 0x49}, {0x00, 0x6a, 0x4a}, {0x00, 0x6b, 0x4b},
+ {0x00, 0x6c, 0x4c}, {0x00, 0x6d, 0x4d}, {0x00, 0x6e, 0x4e},
+ {0x00, 0x6f, 0x4f}, {0x00, 0x70, 0x50}, {0x00, 0x71, 0x51},
+ {0x00, 0x72, 0x52}, {0x00, 0x73, 0x53}, {0x00, 0x74, 0x54},
+ {0x00, 0x75, 0x55}, {0x00, 0x76, 0x56}, {0x00, 0x77, 0x57},
+ {0x00, 0x78, 0x58}, {0x00, 0x79, 0x59}, {0x00, 0x7a, 0x5a},
+ {0x00, 0x7b, 0x7b}, {0x00, 0x7c, 0x7c}, {0x00, 0x7d, 0x7d},
+ {0x00, 0x7e, 0x7e}, {0x00, 0x7f, 0x7f}, {0x01, 0x90, 0x80},
+ {0x01, 0x83, 0x81}, {0x00, 0x82, 0x82}, {0x00, 0x83, 0x81},
+ {0x00, 0x84, 0x84}, {0x00, 0x85, 0x85}, {0x00, 0x86, 0x86},
+ {0x00, 0x87, 0x87}, {0x00, 0x88, 0x88}, {0x00, 0x89, 0x89},
+ {0x01, 0x9a, 0x8a}, {0x00, 0x8b, 0x8b}, {0x01, 0x9c, 0x8c},
+ {0x01, 0x9d, 0x8d}, {0x01, 0x9e, 0x8e}, {0x01, 0x9f, 0x8f},
+ {0x00, 0x90, 0x80}, {0x00, 0x91, 0x91}, {0x00, 0x92, 0x92},
+ {0x00, 0x93, 0x93}, {0x00, 0x94, 0x94}, {0x00, 0x95, 0x95},
+ {0x00, 0x96, 0x96}, {0x00, 0x97, 0x97}, {0x00, 0x98, 0x98},
+ {0x00, 0x99, 0x99}, {0x00, 0x9a, 0x8a}, {0x00, 0x9b, 0x9b},
+ {0x00, 0x9c, 0x8c}, {0x00, 0x9d, 0x8d}, {0x00, 0x9e, 0x8e},
+ {0x00, 0x9f, 0x8f}, {0x00, 0xa0, 0xa0}, {0x01, 0xa2, 0xa1},
+ {0x00, 0xa2, 0xa1}, {0x01, 0xbc, 0xa3}, {0x00, 0xa4, 0xa4},
+ {0x01, 0xb4, 0xa5}, {0x00, 0xa6, 0xa6}, {0x00, 0xa7, 0xa7},
+ {0x01, 0xb8, 0xa8}, {0x00, 0xa9, 0xa9}, {0x01, 0xba, 0xaa},
+ {0x00, 0xab, 0xab}, {0x00, 0xac, 0xac}, {0x00, 0xad, 0xad},
+ {0x00, 0xae, 0xae}, {0x01, 0xbf, 0xaf}, {0x00, 0xb0, 0xb0},
+ {0x00, 0xb1, 0xb1}, {0x01, 0xb3, 0xb2}, {0x00, 0xb3, 0xb2},
+ {0x00, 0xb4, 0xa5}, {0x00, 0xb5, 0xb5}, {0x00, 0xb6, 0xb6},
+ {0x00, 0xb7, 0xb7}, {0x00, 0xb8, 0xa8}, {0x00, 0xb9, 0xb9},
+ {0x00, 0xba, 0xaa}, {0x00, 0xbb, 0xbb}, {0x00, 0xbc, 0xa3},
+ {0x01, 0xbe, 0xbd}, {0x00, 0xbe, 0xbd}, {0x00, 0xbf, 0xaf},
+ {0x01, 0xe0, 0xc0}, {0x01, 0xe1, 0xc1}, {0x01, 0xe2, 0xc2},
+ {0x01, 0xe3, 0xc3}, {0x01, 0xe4, 0xc4}, {0x01, 0xe5, 0xc5},
+ {0x01, 0xe6, 0xc6}, {0x01, 0xe7, 0xc7}, {0x01, 0xe8, 0xc8},
+ {0x01, 0xe9, 0xc9}, {0x01, 0xea, 0xca}, {0x01, 0xeb, 0xcb},
+ {0x01, 0xec, 0xcc}, {0x01, 0xed, 0xcd}, {0x01, 0xee, 0xce},
+ {0x01, 0xef, 0xcf}, {0x01, 0xf0, 0xd0}, {0x01, 0xf1, 0xd1},
+ {0x01, 0xf2, 0xd2}, {0x01, 0xf3, 0xd3}, {0x01, 0xf4, 0xd4},
+ {0x01, 0xf5, 0xd5}, {0x01, 0xf6, 0xd6}, {0x01, 0xf7, 0xd7},
+ {0x01, 0xf8, 0xd8}, {0x01, 0xf9, 0xd9}, {0x01, 0xfa, 0xda},
+ {0x01, 0xfb, 0xdb}, {0x01, 0xfc, 0xdc}, {0x01, 0xfd, 0xdd},
+ {0x01, 0xfe, 0xde}, {0x01, 0xff, 0xdf}, {0x00, 0xe0, 0xc0},
+ {0x00, 0xe1, 0xc1}, {0x00, 0xe2, 0xc2}, {0x00, 0xe3, 0xc3},
+ {0x00, 0xe4, 0xc4}, {0x00, 0xe5, 0xc5}, {0x00, 0xe6, 0xc6},
+ {0x00, 0xe7, 0xc7}, {0x00, 0xe8, 0xc8}, {0x00, 0xe9, 0xc9},
+ {0x00, 0xea, 0xca}, {0x00, 0xeb, 0xcb}, {0x00, 0xec, 0xcc},
+ {0x00, 0xed, 0xcd}, {0x00, 0xee, 0xce}, {0x00, 0xef, 0xcf},
+ {0x00, 0xf0, 0xd0}, {0x00, 0xf1, 0xd1}, {0x00, 0xf2, 0xd2},
+ {0x00, 0xf3, 0xd3}, {0x00, 0xf4, 0xd4}, {0x00, 0xf5, 0xd5},
+ {0x00, 0xf6, 0xd6}, {0x00, 0xf7, 0xd7}, {0x00, 0xf8, 0xd8},
+ {0x00, 0xf9, 0xd9}, {0x00, 0xfa, 0xda}, {0x00, 0xfb, 0xdb},
+ {0x00, 0xfc, 0xdc}, {0x00, 0xfd, 0xdd}, {0x00, 0xfe, 0xde},
+ {0x00, 0xff, 0xdf}};
+
+static struct cs_info iso13_tbl[] = {
+ {0x00, 0x00, 0x00}, {0x00, 0x01, 0x01}, {0x00, 0x02, 0x02},
+ {0x00, 0x03, 0x03}, {0x00, 0x04, 0x04}, {0x00, 0x05, 0x05},
+ {0x00, 0x06, 0x06}, {0x00, 0x07, 0x07}, {0x00, 0x08, 0x08},
+ {0x00, 0x09, 0x09}, {0x00, 0x0A, 0x0A}, {0x00, 0x0B, 0x0B},
+ {0x00, 0x0C, 0x0C}, {0x00, 0x0D, 0x0D}, {0x00, 0x0E, 0x0E},
+ {0x00, 0x0F, 0x0F}, {0x00, 0x10, 0x10}, {0x00, 0x11, 0x11},
+ {0x00, 0x12, 0x12}, {0x00, 0x13, 0x13}, {0x00, 0x14, 0x14},
+ {0x00, 0x15, 0x15}, {0x00, 0x16, 0x16}, {0x00, 0x17, 0x17},
+ {0x00, 0x18, 0x18}, {0x00, 0x19, 0x19}, {0x00, 0x1A, 0x1A},
+ {0x00, 0x1B, 0x1B}, {0x00, 0x1C, 0x1C}, {0x00, 0x1D, 0x1D},
+ {0x00, 0x1E, 0x1E}, {0x00, 0x1F, 0x1F}, {0x00, 0x20, 0x20},
+ {0x00, 0x21, 0x21}, {0x00, 0x22, 0x22}, {0x00, 0x23, 0x23},
+ {0x00, 0x24, 0x24}, {0x00, 0x25, 0x25}, {0x00, 0x26, 0x26},
+ {0x00, 0x27, 0x27}, {0x00, 0x28, 0x28}, {0x00, 0x29, 0x29},
+ {0x00, 0x2A, 0x2A}, {0x00, 0x2B, 0x2B}, {0x00, 0x2C, 0x2C},
+ {0x00, 0x2D, 0x2D}, {0x00, 0x2E, 0x2E}, {0x00, 0x2F, 0x2F},
+ {0x00, 0x30, 0x30}, {0x00, 0x31, 0x31}, {0x00, 0x32, 0x32},
+ {0x00, 0x33, 0x33}, {0x00, 0x34, 0x34}, {0x00, 0x35, 0x35},
+ {0x00, 0x36, 0x36}, {0x00, 0x37, 0x37}, {0x00, 0x38, 0x38},
+ {0x00, 0x39, 0x39}, {0x00, 0x3A, 0x3A}, {0x00, 0x3B, 0x3B},
+ {0x00, 0x3C, 0x3C}, {0x00, 0x3D, 0x3D}, {0x00, 0x3E, 0x3E},
+ {0x00, 0x3F, 0x3F}, {0x00, 0x40, 0x40}, {0x01, 0x61, 0x41},
+ {0x01, 0x62, 0x42}, {0x01, 0x63, 0x43}, {0x01, 0x64, 0x44},
+ {0x01, 0x65, 0x45}, {0x01, 0x66, 0x46}, {0x01, 0x67, 0x47},
+ {0x01, 0x68, 0x48}, {0x01, 0x69, 0x49}, {0x01, 0x6A, 0x4A},
+ {0x01, 0x6B, 0x4B}, {0x01, 0x6C, 0x4C}, {0x01, 0x6D, 0x4D},
+ {0x01, 0x6E, 0x4E}, {0x01, 0x6F, 0x4F}, {0x01, 0x70, 0x50},
+ {0x01, 0x71, 0x51}, {0x01, 0x72, 0x52}, {0x01, 0x73, 0x53},
+ {0x01, 0x74, 0x54}, {0x01, 0x75, 0x55}, {0x01, 0x76, 0x56},
+ {0x01, 0x77, 0x57}, {0x01, 0x78, 0x58}, {0x01, 0x79, 0x59},
+ {0x01, 0x7A, 0x5A}, {0x00, 0x5B, 0x5B}, {0x00, 0x5C, 0x5C},
+ {0x00, 0x5D, 0x5D}, {0x00, 0x5E, 0x5E}, {0x00, 0x5F, 0x5F},
+ {0x00, 0x60, 0x60}, {0x00, 0x61, 0x41}, {0x00, 0x62, 0x42},
+ {0x00, 0x63, 0x43}, {0x00, 0x64, 0x44}, {0x00, 0x65, 0x45},
+ {0x00, 0x66, 0x46}, {0x00, 0x67, 0x47}, {0x00, 0x68, 0x48},
+ {0x00, 0x69, 0x49}, {0x00, 0x6A, 0x4A}, {0x00, 0x6B, 0x4B},
+ {0x00, 0x6C, 0x4C}, {0x00, 0x6D, 0x4D}, {0x00, 0x6E, 0x4E},
+ {0x00, 0x6F, 0x4F}, {0x00, 0x70, 0x50}, {0x00, 0x71, 0x51},
+ {0x00, 0x72, 0x52}, {0x00, 0x73, 0x53}, {0x00, 0x74, 0x54},
+ {0x00, 0x75, 0x55}, {0x00, 0x76, 0x56}, {0x00, 0x77, 0x57},
+ {0x00, 0x78, 0x58}, {0x00, 0x79, 0x59}, {0x00, 0x7A, 0x5A},
+ {0x00, 0x7B, 0x7B}, {0x00, 0x7C, 0x7C}, {0x00, 0x7D, 0x7D},
+ {0x00, 0x7E, 0x7E}, {0x00, 0x7F, 0x7F}, {0x00, 0x80, 0x80},
+ {0x00, 0x81, 0x81}, {0x00, 0x82, 0x82}, {0x00, 0x83, 0x83},
+ {0x00, 0x84, 0x84}, {0x00, 0x85, 0x85}, {0x00, 0x86, 0x86},
+ {0x00, 0x87, 0x87}, {0x00, 0x88, 0x88}, {0x00, 0x89, 0x89},
+ {0x00, 0x8A, 0x8A}, {0x00, 0x8B, 0x8B}, {0x00, 0x8C, 0x8C},
+ {0x00, 0x8D, 0x8D}, {0x00, 0x8E, 0x8E}, {0x00, 0x8F, 0x8F},
+ {0x00, 0x90, 0x90}, {0x00, 0x91, 0x91}, {0x00, 0x92, 0x92},
+ {0x00, 0x93, 0x93}, {0x00, 0x94, 0x94}, {0x00, 0x95, 0x95},
+ {0x00, 0x96, 0x96}, {0x00, 0x97, 0x97}, {0x00, 0x98, 0x98},
+ {0x00, 0x99, 0x99}, {0x00, 0x9A, 0x9A}, {0x00, 0x9B, 0x9B},
+ {0x00, 0x9C, 0x9C}, {0x00, 0x9D, 0x9D}, {0x00, 0x9E, 0x9E},
+ {0x00, 0x9F, 0x9F}, {0x00, 0xA0, 0xA0}, {0x00, 0xA1, 0xA1},
+ {0x00, 0xA2, 0xA2}, {0x00, 0xA3, 0xA3}, {0x00, 0xA4, 0xA4},
+ {0x00, 0xA5, 0xA5}, {0x00, 0xA6, 0xA6}, {0x00, 0xA7, 0xA7},
+ {0x01, 0xB8, 0xA8}, {0x00, 0xA9, 0xA9}, {0x01, 0xBA, 0xAA},
+ {0x00, 0xAB, 0xAB}, {0x00, 0xAC, 0xAC}, {0x00, 0xAD, 0xAD},
+ {0x00, 0xAE, 0xAE}, {0x01, 0xBF, 0xAF}, {0x00, 0xB0, 0xB0},
+ {0x00, 0xB1, 0xB1}, {0x00, 0xB2, 0xB2}, {0x00, 0xB3, 0xB3},
+ {0x00, 0xB4, 0xB4}, {0x00, 0xB5, 0xB5}, {0x00, 0xB6, 0xB6},
+ {0x00, 0xB7, 0xB7}, {0x00, 0xB8, 0xA8}, {0x00, 0xB9, 0xB9},
+ {0x00, 0xBA, 0xAA}, {0x00, 0xBB, 0xBB}, {0x00, 0xBC, 0xBC},
+ {0x00, 0xBD, 0xBD}, {0x00, 0xBE, 0xBE}, {0x00, 0xBF, 0xAF},
+ {0x01, 0xE0, 0xC0}, {0x01, 0xE1, 0xC1}, {0x01, 0xE2, 0xC2},
+ {0x01, 0xE3, 0xC3}, {0x01, 0xE4, 0xC4}, {0x01, 0xE5, 0xC5},
+ {0x01, 0xE6, 0xC6}, {0x01, 0xE7, 0xC7}, {0x01, 0xE8, 0xC8},
+ {0x01, 0xE9, 0xC9}, {0x01, 0xEA, 0xCA}, {0x01, 0xEB, 0xCB},
+ {0x01, 0xEC, 0xCC}, {0x01, 0xED, 0xCD}, {0x01, 0xEE, 0xCE},
+ {0x01, 0xEF, 0xCF}, {0x01, 0xF0, 0xD0}, {0x01, 0xF1, 0xD1},
+ {0x01, 0xF2, 0xD2}, {0x01, 0xF3, 0xD3}, {0x01, 0xF4, 0xD4},
+ {0x01, 0xF5, 0xD5}, {0x01, 0xF6, 0xD6}, {0x00, 0xD7, 0xD7},
+ {0x01, 0xF8, 0xD8}, {0x01, 0xF9, 0xD9}, {0x01, 0xFA, 0xDA},
+ {0x01, 0xFB, 0xDB}, {0x01, 0xFC, 0xDC}, {0x01, 0xFD, 0xDD},
+ {0x01, 0xFE, 0xDE}, {0x00, 0xDF, 0xDF}, {0x00, 0xE0, 0xC0},
+ {0x00, 0xE1, 0xC1}, {0x00, 0xE2, 0xC2}, {0x00, 0xE3, 0xC3},
+ {0x00, 0xE4, 0xC4}, {0x00, 0xE5, 0xC5}, {0x00, 0xE6, 0xC6},
+ {0x00, 0xE7, 0xC7}, {0x00, 0xE8, 0xC8}, {0x00, 0xE9, 0xC9},
+ {0x00, 0xEA, 0xCA}, {0x00, 0xEB, 0xCB}, {0x00, 0xEC, 0xCC},
+ {0x00, 0xED, 0xCD}, {0x00, 0xEE, 0xCE}, {0x00, 0xEF, 0xCF},
+ {0x00, 0xF0, 0xD0}, {0x00, 0xF1, 0xD1}, {0x00, 0xF2, 0xD2},
+ {0x00, 0xF3, 0xD3}, {0x00, 0xF4, 0xD4}, {0x00, 0xF5, 0xD5},
+ {0x00, 0xF6, 0xD6}, {0x00, 0xF7, 0xF7}, {0x00, 0xF8, 0xD8},
+ {0x00, 0xF9, 0xD9}, {0x00, 0xFA, 0xDA}, {0x00, 0xFB, 0xDB},
+ {0x00, 0xFC, 0xDC}, {0x00, 0xFD, 0xDD}, {0x00, 0xFE, 0xDE},
+ {0x00, 0xFF, 0xFF}};
+
+static struct cs_info iso14_tbl[] = {
+ {0x00, 0x00, 0x00}, {0x00, 0x01, 0x01}, {0x00, 0x02, 0x02},
+ {0x00, 0x03, 0x03}, {0x00, 0x04, 0x04}, {0x00, 0x05, 0x05},
+ {0x00, 0x06, 0x06}, {0x00, 0x07, 0x07}, {0x00, 0x08, 0x08},
+ {0x00, 0x09, 0x09}, {0x00, 0x0a, 0x0a}, {0x00, 0x0b, 0x0b},
+ {0x00, 0x0c, 0x0c}, {0x00, 0x0d, 0x0d}, {0x00, 0x0e, 0x0e},
+ {0x00, 0x0f, 0x0f}, {0x00, 0x10, 0x10}, {0x00, 0x11, 0x11},
+ {0x00, 0x12, 0x12}, {0x00, 0x13, 0x13}, {0x00, 0x14, 0x14},
+ {0x00, 0x15, 0x15}, {0x00, 0x16, 0x16}, {0x00, 0x17, 0x17},
+ {0x00, 0x18, 0x18}, {0x00, 0x19, 0x19}, {0x00, 0x1a, 0x1a},
+ {0x00, 0x1b, 0x1b}, {0x00, 0x1c, 0x1c}, {0x00, 0x1d, 0x1d},
+ {0x00, 0x1e, 0x1e}, {0x00, 0x1f, 0x1f}, {0x00, 0x20, 0x20},
+ {0x00, 0x21, 0x21}, {0x00, 0x22, 0x22}, {0x00, 0x23, 0x23},
+ {0x00, 0x24, 0x24}, {0x00, 0x25, 0x25}, {0x00, 0x26, 0x26},
+ {0x00, 0x27, 0x27}, {0x00, 0x28, 0x28}, {0x00, 0x29, 0x29},
+ {0x00, 0x2a, 0x2a}, {0x00, 0x2b, 0x2b}, {0x00, 0x2c, 0x2c},
+ {0x00, 0x2d, 0x2d}, {0x00, 0x2e, 0x2e}, {0x00, 0x2f, 0x2f},
+ {0x00, 0x30, 0x30}, {0x00, 0x31, 0x31}, {0x00, 0x32, 0x32},
+ {0x00, 0x33, 0x33}, {0x00, 0x34, 0x34}, {0x00, 0x35, 0x35},
+ {0x00, 0x36, 0x36}, {0x00, 0x37, 0x37}, {0x00, 0x38, 0x38},
+ {0x00, 0x39, 0x39}, {0x00, 0x3a, 0x3a}, {0x00, 0x3b, 0x3b},
+ {0x00, 0x3c, 0x3c}, {0x00, 0x3d, 0x3d}, {0x00, 0x3e, 0x3e},
+ {0x00, 0x3f, 0x3f}, {0x00, 0x40, 0x40}, {0x01, 0x61, 0x41},
+ {0x01, 0x62, 0x42}, {0x01, 0x63, 0x43}, {0x01, 0x64, 0x44},
+ {0x01, 0x65, 0x45}, {0x01, 0x66, 0x46}, {0x01, 0x67, 0x47},
+ {0x01, 0x68, 0x48}, {0x01, 0x69, 0x49}, {0x01, 0x6a, 0x4a},
+ {0x01, 0x6b, 0x4b}, {0x01, 0x6c, 0x4c}, {0x01, 0x6d, 0x4d},
+ {0x01, 0x6e, 0x4e}, {0x01, 0x6f, 0x4f}, {0x01, 0x70, 0x50},
+ {0x01, 0x71, 0x51}, {0x01, 0x72, 0x52}, {0x01, 0x73, 0x53},
+ {0x01, 0x74, 0x54}, {0x01, 0x75, 0x55}, {0x01, 0x76, 0x56},
+ {0x01, 0x77, 0x57}, {0x01, 0x78, 0x58}, {0x01, 0x79, 0x59},
+ {0x01, 0x7a, 0x5a}, {0x00, 0x5b, 0x5b}, {0x00, 0x5c, 0x5c},
+ {0x00, 0x5d, 0x5d}, {0x00, 0x5e, 0x5e}, {0x00, 0x5f, 0x5f},
+ {0x00, 0x60, 0x60}, {0x00, 0x61, 0x41}, {0x00, 0x62, 0x42},
+ {0x00, 0x63, 0x43}, {0x00, 0x64, 0x44}, {0x00, 0x65, 0x45},
+ {0x00, 0x66, 0x46}, {0x00, 0x67, 0x47}, {0x00, 0x68, 0x48},
+ {0x00, 0x69, 0x49}, {0x00, 0x6a, 0x4a}, {0x00, 0x6b, 0x4b},
+ {0x00, 0x6c, 0x4c}, {0x00, 0x6d, 0x4d}, {0x00, 0x6e, 0x4e},
+ {0x00, 0x6f, 0x4f}, {0x00, 0x70, 0x50}, {0x00, 0x71, 0x51},
+ {0x00, 0x72, 0x52}, {0x00, 0x73, 0x53}, {0x00, 0x74, 0x54},
+ {0x00, 0x75, 0x55}, {0x00, 0x76, 0x56}, {0x00, 0x77, 0x57},
+ {0x00, 0x78, 0x58}, {0x00, 0x79, 0x59}, {0x00, 0x7a, 0x5a},
+ {0x00, 0x7b, 0x7b}, {0x00, 0x7c, 0x7c}, {0x00, 0x7d, 0x7d},
+ {0x00, 0x7e, 0x7e}, {0x00, 0x7f, 0x7f}, {0x00, 0x80, 0x80},
+ {0x00, 0x81, 0x81}, {0x00, 0x82, 0x82}, {0x00, 0x83, 0x83},
+ {0x00, 0x84, 0x84}, {0x00, 0x85, 0x85}, {0x00, 0x86, 0x86},
+ {0x00, 0x87, 0x87}, {0x00, 0x88, 0x88}, {0x00, 0x89, 0x89},
+ {0x00, 0x8a, 0x8a}, {0x00, 0x8b, 0x8b}, {0x00, 0x8c, 0x8c},
+ {0x00, 0x8d, 0x8d}, {0x00, 0x8e, 0x8e}, {0x00, 0x8f, 0x8f},
+ {0x00, 0x90, 0x90}, {0x00, 0x91, 0x91}, {0x00, 0x92, 0x92},
+ {0x00, 0x93, 0x93}, {0x00, 0x94, 0x94}, {0x00, 0x95, 0x95},
+ {0x00, 0x96, 0x96}, {0x00, 0x97, 0x97}, {0x00, 0x98, 0x98},
+ {0x00, 0x99, 0x99}, {0x00, 0x9a, 0x9a}, {0x00, 0x9b, 0x9b},
+ {0x00, 0x9c, 0x9c}, {0x00, 0x9d, 0x9d}, {0x00, 0x9e, 0x9e},
+ {0x00, 0x9f, 0x9f}, {0x00, 0xa0, 0xa0}, {0x01, 0xa2, 0xa1},
+ {0x00, 0xa2, 0xa1}, {0x00, 0xa3, 0xa3}, {0x01, 0xa5, 0xa4},
+ {0x00, 0xa5, 0xa4}, {0x01, 0xa6, 0xab}, {0x00, 0xa7, 0xa7},
+ {0x01, 0xb8, 0xa8}, {0x00, 0xa9, 0xa9}, {0x01, 0xba, 0xaa},
+ {0x00, 0xab, 0xa6}, {0x01, 0xbc, 0xac}, {0x00, 0xad, 0xad},
+ {0x00, 0xae, 0xae}, {0x01, 0xff, 0xaf}, {0x01, 0xb1, 0xb0},
+ {0x00, 0xb1, 0xb0}, {0x01, 0xb3, 0xb2}, {0x00, 0xb3, 0xb2},
+ {0x01, 0xb5, 0xb4}, {0x00, 0xb5, 0xb4}, {0x00, 0xb6, 0xb6},
+ {0x01, 0xb9, 0xb7}, {0x00, 0xb8, 0xa8}, {0x00, 0xb9, 0xb6},
+ {0x00, 0xba, 0xaa}, {0x01, 0xbf, 0xbb}, {0x00, 0xbc, 0xac},
+ {0x01, 0xbe, 0xbd}, {0x00, 0xbe, 0xbd}, {0x00, 0xbf, 0xbb},
+ {0x01, 0xe0, 0xc0}, {0x01, 0xe1, 0xc1}, {0x01, 0xe2, 0xc2},
+ {0x01, 0xe3, 0xc3}, {0x01, 0xe4, 0xc4}, {0x01, 0xe5, 0xc5},
+ {0x01, 0xe6, 0xc6}, {0x01, 0xe7, 0xc7}, {0x01, 0xe8, 0xc8},
+ {0x01, 0xe9, 0xc9}, {0x01, 0xea, 0xca}, {0x01, 0xeb, 0xcb},
+ {0x01, 0xec, 0xcc}, {0x01, 0xed, 0xcd}, {0x01, 0xee, 0xce},
+ {0x01, 0xef, 0xcf}, {0x01, 0xf0, 0xd0}, {0x01, 0xf1, 0xd1},
+ {0x01, 0xf2, 0xd2}, {0x01, 0xf3, 0xd3}, {0x01, 0xf4, 0xd4},
+ {0x01, 0xf5, 0xd5}, {0x01, 0xf6, 0xd6}, {0x01, 0xf7, 0xd7},
+ {0x01, 0xf8, 0xd8}, {0x01, 0xf9, 0xd9}, {0x01, 0xfa, 0xda},
+ {0x01, 0xfb, 0xdb}, {0x01, 0xfc, 0xdc}, {0x01, 0xfd, 0xdd},
+ {0x01, 0xfe, 0xde}, {0x00, 0xdf, 0xdf}, {0x00, 0xe0, 0xc0},
+ {0x00, 0xe1, 0xc1}, {0x00, 0xe2, 0xc2}, {0x00, 0xe3, 0xc3},
+ {0x00, 0xe4, 0xc4}, {0x00, 0xe5, 0xc5}, {0x00, 0xe6, 0xc6},
+ {0x00, 0xe7, 0xc7}, {0x00, 0xe8, 0xc8}, {0x00, 0xe9, 0xc9},
+ {0x00, 0xea, 0xca}, {0x00, 0xeb, 0xcb}, {0x00, 0xec, 0xcc},
+ {0x00, 0xed, 0xcd}, {0x00, 0xee, 0xce}, {0x00, 0xef, 0xcf},
+ {0x00, 0xf0, 0xd0}, {0x00, 0xf1, 0xd1}, {0x00, 0xf2, 0xd2},
+ {0x00, 0xf3, 0xd3}, {0x00, 0xf4, 0xd4}, {0x00, 0xf5, 0xd5},
+ {0x00, 0xf6, 0xd6}, {0x00, 0xf7, 0xd7}, {0x00, 0xf8, 0xd8},
+ {0x00, 0xf9, 0xd9}, {0x00, 0xfa, 0xda}, {0x00, 0xfb, 0xdb},
+ {0x00, 0xfc, 0xdc}, {0x00, 0xfd, 0xdd}, {0x00, 0xfe, 0xde},
+ {0x00, 0xff, 0xff}};
+
+static struct cs_info iso15_tbl[] = {
+ {0x00, 0x00, 0x00}, {0x00, 0x01, 0x01}, {0x00, 0x02, 0x02},
+ {0x00, 0x03, 0x03}, {0x00, 0x04, 0x04}, {0x00, 0x05, 0x05},
+ {0x00, 0x06, 0x06}, {0x00, 0x07, 0x07}, {0x00, 0x08, 0x08},
+ {0x00, 0x09, 0x09}, {0x00, 0x0a, 0x0a}, {0x00, 0x0b, 0x0b},
+ {0x00, 0x0c, 0x0c}, {0x00, 0x0d, 0x0d}, {0x00, 0x0e, 0x0e},
+ {0x00, 0x0f, 0x0f}, {0x00, 0x10, 0x10}, {0x00, 0x11, 0x11},
+ {0x00, 0x12, 0x12}, {0x00, 0x13, 0x13}, {0x00, 0x14, 0x14},
+ {0x00, 0x15, 0x15}, {0x00, 0x16, 0x16}, {0x00, 0x17, 0x17},
+ {0x00, 0x18, 0x18}, {0x00, 0x19, 0x19}, {0x00, 0x1a, 0x1a},
+ {0x00, 0x1b, 0x1b}, {0x00, 0x1c, 0x1c}, {0x00, 0x1d, 0x1d},
+ {0x00, 0x1e, 0x1e}, {0x00, 0x1f, 0x1f}, {0x00, 0x20, 0x20},
+ {0x00, 0x21, 0x21}, {0x00, 0x22, 0x22}, {0x00, 0x23, 0x23},
+ {0x00, 0x24, 0x24}, {0x00, 0x25, 0x25}, {0x00, 0x26, 0x26},
+ {0x00, 0x27, 0x27}, {0x00, 0x28, 0x28}, {0x00, 0x29, 0x29},
+ {0x00, 0x2a, 0x2a}, {0x00, 0x2b, 0x2b}, {0x00, 0x2c, 0x2c},
+ {0x00, 0x2d, 0x2d}, {0x00, 0x2e, 0x2e}, {0x00, 0x2f, 0x2f},
+ {0x00, 0x30, 0x30}, {0x00, 0x31, 0x31}, {0x00, 0x32, 0x32},
+ {0x00, 0x33, 0x33}, {0x00, 0x34, 0x34}, {0x00, 0x35, 0x35},
+ {0x00, 0x36, 0x36}, {0x00, 0x37, 0x37}, {0x00, 0x38, 0x38},
+ {0x00, 0x39, 0x39}, {0x00, 0x3a, 0x3a}, {0x00, 0x3b, 0x3b},
+ {0x00, 0x3c, 0x3c}, {0x00, 0x3d, 0x3d}, {0x00, 0x3e, 0x3e},
+ {0x00, 0x3f, 0x3f}, {0x00, 0x40, 0x40}, {0x01, 0x61, 0x41},
+ {0x01, 0x62, 0x42}, {0x01, 0x63, 0x43}, {0x01, 0x64, 0x44},
+ {0x01, 0x65, 0x45}, {0x01, 0x66, 0x46}, {0x01, 0x67, 0x47},
+ {0x01, 0x68, 0x48}, {0x01, 0x69, 0x49}, {0x01, 0x6a, 0x4a},
+ {0x01, 0x6b, 0x4b}, {0x01, 0x6c, 0x4c}, {0x01, 0x6d, 0x4d},
+ {0x01, 0x6e, 0x4e}, {0x01, 0x6f, 0x4f}, {0x01, 0x70, 0x50},
+ {0x01, 0x71, 0x51}, {0x01, 0x72, 0x52}, {0x01, 0x73, 0x53},
+ {0x01, 0x74, 0x54}, {0x01, 0x75, 0x55}, {0x01, 0x76, 0x56},
+ {0x01, 0x77, 0x57}, {0x01, 0x78, 0x58}, {0x01, 0x79, 0x59},
+ {0x01, 0x7a, 0x5a}, {0x00, 0x5b, 0x5b}, {0x00, 0x5c, 0x5c},
+ {0x00, 0x5d, 0x5d}, {0x00, 0x5e, 0x5e}, {0x00, 0x5f, 0x5f},
+ {0x00, 0x60, 0x60}, {0x00, 0x61, 0x41}, {0x00, 0x62, 0x42},
+ {0x00, 0x63, 0x43}, {0x00, 0x64, 0x44}, {0x00, 0x65, 0x45},
+ {0x00, 0x66, 0x46}, {0x00, 0x67, 0x47}, {0x00, 0x68, 0x48},
+ {0x00, 0x69, 0x49}, {0x00, 0x6a, 0x4a}, {0x00, 0x6b, 0x4b},
+ {0x00, 0x6c, 0x4c}, {0x00, 0x6d, 0x4d}, {0x00, 0x6e, 0x4e},
+ {0x00, 0x6f, 0x4f}, {0x00, 0x70, 0x50}, {0x00, 0x71, 0x51},
+ {0x00, 0x72, 0x52}, {0x00, 0x73, 0x53}, {0x00, 0x74, 0x54},
+ {0x00, 0x75, 0x55}, {0x00, 0x76, 0x56}, {0x00, 0x77, 0x57},
+ {0x00, 0x78, 0x58}, {0x00, 0x79, 0x59}, {0x00, 0x7a, 0x5a},
+ {0x00, 0x7b, 0x7b}, {0x00, 0x7c, 0x7c}, {0x00, 0x7d, 0x7d},
+ {0x00, 0x7e, 0x7e}, {0x00, 0x7f, 0x7f}, {0x00, 0x80, 0x80},
+ {0x00, 0x81, 0x81}, {0x00, 0x82, 0x82}, {0x00, 0x83, 0x83},
+ {0x00, 0x84, 0x84}, {0x00, 0x85, 0x85}, {0x00, 0x86, 0x86},
+ {0x00, 0x87, 0x87}, {0x00, 0x88, 0x88}, {0x00, 0x89, 0x89},
+ {0x00, 0x8a, 0x8a}, {0x00, 0x8b, 0x8b}, {0x00, 0x8c, 0x8c},
+ {0x00, 0x8d, 0x8d}, {0x00, 0x8e, 0x8e}, {0x00, 0x8f, 0x8f},
+ {0x00, 0x90, 0x90}, {0x00, 0x91, 0x91}, {0x00, 0x92, 0x92},
+ {0x00, 0x93, 0x93}, {0x00, 0x94, 0x94}, {0x00, 0x95, 0x95},
+ {0x00, 0x96, 0x96}, {0x00, 0x97, 0x97}, {0x00, 0x98, 0x98},
+ {0x00, 0x99, 0x99}, {0x00, 0x9a, 0x9a}, {0x00, 0x9b, 0x9b},
+ {0x00, 0x9c, 0x9c}, {0x00, 0x9d, 0x9d}, {0x00, 0x9e, 0x9e},
+ {0x00, 0x9f, 0x9f}, {0x00, 0xa0, 0xa0}, {0x00, 0xa1, 0xa1},
+ {0x00, 0xa2, 0xa2}, {0x00, 0xa3, 0xa3}, {0x00, 0xa4, 0xa4},
+ {0x00, 0xa5, 0xa5}, {0x01, 0xa8, 0xa6}, {0x00, 0xa7, 0xa7},
+ {0x00, 0xa8, 0xa6}, {0x00, 0xa9, 0xa9}, {0x00, 0xaa, 0xaa},
+ {0x00, 0xab, 0xab}, {0x00, 0xac, 0xac}, {0x00, 0xad, 0xad},
+ {0x00, 0xae, 0xae}, {0x00, 0xaf, 0xaf}, {0x00, 0xb0, 0xb0},
+ {0x00, 0xb1, 0xb1}, {0x00, 0xb2, 0xb2}, {0x00, 0xb3, 0xb3},
+ {0x01, 0xb8, 0xb4}, {0x00, 0xb5, 0xb5}, {0x00, 0xb6, 0xb6},
+ {0x00, 0xb7, 0xb7}, {0x00, 0xb8, 0xb4}, {0x00, 0xb9, 0xb9},
+ {0x00, 0xba, 0xba}, {0x00, 0xbb, 0xbb}, {0x01, 0xbd, 0xbc},
+ {0x00, 0xbd, 0xbc}, {0x01, 0xff, 0xbe}, {0x00, 0xbf, 0xbf},
+ {0x01, 0xe0, 0xc0}, {0x01, 0xe1, 0xc1}, {0x01, 0xe2, 0xc2},
+ {0x01, 0xe3, 0xc3}, {0x01, 0xe4, 0xc4}, {0x01, 0xe5, 0xc5},
+ {0x01, 0xe6, 0xc6}, {0x01, 0xe7, 0xc7}, {0x01, 0xe8, 0xc8},
+ {0x01, 0xe9, 0xc9}, {0x01, 0xea, 0xca}, {0x01, 0xeb, 0xcb},
+ {0x01, 0xec, 0xcc}, {0x01, 0xed, 0xcd}, {0x01, 0xee, 0xce},
+ {0x01, 0xef, 0xcf}, {0x01, 0xf0, 0xd0}, {0x01, 0xf1, 0xd1},
+ {0x01, 0xf2, 0xd2}, {0x01, 0xf3, 0xd3}, {0x01, 0xf4, 0xd4},
+ {0x01, 0xf5, 0xd5}, {0x01, 0xf6, 0xd6}, {0x00, 0xd7, 0xd7},
+ {0x01, 0xf8, 0xd8}, {0x01, 0xf9, 0xd9}, {0x01, 0xfa, 0xda},
+ {0x01, 0xfb, 0xdb}, {0x01, 0xfc, 0xdc}, {0x01, 0xfd, 0xdd},
+ {0x01, 0xfe, 0xde}, {0x00, 0xdf, 0xdf}, {0x00, 0xe0, 0xc0},
+ {0x00, 0xe1, 0xc1}, {0x00, 0xe2, 0xc2}, {0x00, 0xe3, 0xc3},
+ {0x00, 0xe4, 0xc4}, {0x00, 0xe5, 0xc5}, {0x00, 0xe6, 0xc6},
+ {0x00, 0xe7, 0xc7}, {0x00, 0xe8, 0xc8}, {0x00, 0xe9, 0xc9},
+ {0x00, 0xea, 0xca}, {0x00, 0xeb, 0xcb}, {0x00, 0xec, 0xcc},
+ {0x00, 0xed, 0xcd}, {0x00, 0xee, 0xce}, {0x00, 0xef, 0xcf},
+ {0x00, 0xf0, 0xd0}, {0x00, 0xf1, 0xd1}, {0x00, 0xf2, 0xd2},
+ {0x00, 0xf3, 0xd3}, {0x00, 0xf4, 0xd4}, {0x00, 0xf5, 0xd5},
+ {0x00, 0xf6, 0xd6}, {0x00, 0xf7, 0xf7}, {0x00, 0xf8, 0xd8},
+ {0x00, 0xf9, 0xd9}, {0x00, 0xfa, 0xda}, {0x00, 0xfb, 0xdb},
+ {0x00, 0xfc, 0xdc}, {0x00, 0xfd, 0xdd}, {0x00, 0xfe, 0xde},
+ {0x00, 0xff, 0xbe}};
+
+static struct cs_info iscii_devanagari_tbl[] = {
+ {0x00, 0x00, 0x00}, {0x00, 0x01, 0x01}, {0x00, 0x02, 0x02},
+ {0x00, 0x03, 0x03}, {0x00, 0x04, 0x04}, {0x00, 0x05, 0x05},
+ {0x00, 0x06, 0x06}, {0x00, 0x07, 0x07}, {0x00, 0x08, 0x08},
+ {0x00, 0x09, 0x09}, {0x00, 0x0a, 0x0a}, {0x00, 0x0b, 0x0b},
+ {0x00, 0x0c, 0x0c}, {0x00, 0x0d, 0x0d}, {0x00, 0x0e, 0x0e},
+ {0x00, 0x0f, 0x0f}, {0x00, 0x10, 0x10}, {0x00, 0x11, 0x11},
+ {0x00, 0x12, 0x12}, {0x00, 0x13, 0x13}, {0x00, 0x14, 0x14},
+ {0x00, 0x15, 0x15}, {0x00, 0x16, 0x16}, {0x00, 0x17, 0x17},
+ {0x00, 0x18, 0x18}, {0x00, 0x19, 0x19}, {0x00, 0x1a, 0x1a},
+ {0x00, 0x1b, 0x1b}, {0x00, 0x1c, 0x1c}, {0x00, 0x1d, 0x1d},
+ {0x00, 0x1e, 0x1e}, {0x00, 0x1f, 0x1f}, {0x00, 0x20, 0x20},
+ {0x00, 0x21, 0x21}, {0x00, 0x22, 0x22}, {0x00, 0x23, 0x23},
+ {0x00, 0x24, 0x24}, {0x00, 0x25, 0x25}, {0x00, 0x26, 0x26},
+ {0x00, 0x27, 0x27}, {0x00, 0x28, 0x28}, {0x00, 0x29, 0x29},
+ {0x00, 0x2a, 0x2a}, {0x00, 0x2b, 0x2b}, {0x00, 0x2c, 0x2c},
+ {0x00, 0x2d, 0x2d}, {0x00, 0x2e, 0x2e}, {0x00, 0x2f, 0x2f},
+ {0x00, 0x30, 0x30}, {0x00, 0x31, 0x31}, {0x00, 0x32, 0x32},
+ {0x00, 0x33, 0x33}, {0x00, 0x34, 0x34}, {0x00, 0x35, 0x35},
+ {0x00, 0x36, 0x36}, {0x00, 0x37, 0x37}, {0x00, 0x38, 0x38},
+ {0x00, 0x39, 0x39}, {0x00, 0x3a, 0x3a}, {0x00, 0x3b, 0x3b},
+ {0x00, 0x3c, 0x3c}, {0x00, 0x3d, 0x3d}, {0x00, 0x3e, 0x3e},
+ {0x00, 0x3f, 0x3f}, {0x00, 0x40, 0x40}, {0x01, 0x61, 0x41},
+ {0x01, 0x62, 0x42}, {0x01, 0x63, 0x43}, {0x01, 0x64, 0x44},
+ {0x01, 0x65, 0x45}, {0x01, 0x66, 0x46}, {0x01, 0x67, 0x47},
+ {0x01, 0x68, 0x48}, {0x01, 0x69, 0x49}, {0x01, 0x6a, 0x4a},
+ {0x01, 0x6b, 0x4b}, {0x01, 0x6c, 0x4c}, {0x01, 0x6d, 0x4d},
+ {0x01, 0x6e, 0x4e}, {0x01, 0x6f, 0x4f}, {0x01, 0x70, 0x50},
+ {0x01, 0x71, 0x51}, {0x01, 0x72, 0x52}, {0x01, 0x73, 0x53},
+ {0x01, 0x74, 0x54}, {0x01, 0x75, 0x55}, {0x01, 0x76, 0x56},
+ {0x01, 0x77, 0x57}, {0x01, 0x78, 0x58}, {0x01, 0x79, 0x59},
+ {0x01, 0x7a, 0x5a}, {0x00, 0x5b, 0x5b}, {0x00, 0x5c, 0x5c},
+ {0x00, 0x5d, 0x5d}, {0x00, 0x5e, 0x5e}, {0x00, 0x5f, 0x5f},
+ {0x00, 0x60, 0x60}, {0x00, 0x61, 0x41}, {0x00, 0x62, 0x42},
+ {0x00, 0x63, 0x43}, {0x00, 0x64, 0x44}, {0x00, 0x65, 0x45},
+ {0x00, 0x66, 0x46}, {0x00, 0x67, 0x47}, {0x00, 0x68, 0x48},
+ {0x00, 0x69, 0x49}, {0x00, 0x6a, 0x4a}, {0x00, 0x6b, 0x4b},
+ {0x00, 0x6c, 0x4c}, {0x00, 0x6d, 0x4d}, {0x00, 0x6e, 0x4e},
+ {0x00, 0x6f, 0x4f}, {0x00, 0x70, 0x50}, {0x00, 0x71, 0x51},
+ {0x00, 0x72, 0x52}, {0x00, 0x73, 0x53}, {0x00, 0x74, 0x54},
+ {0x00, 0x75, 0x55}, {0x00, 0x76, 0x56}, {0x00, 0x77, 0x57},
+ {0x00, 0x78, 0x58}, {0x00, 0x79, 0x59}, {0x00, 0x7a, 0x5a},
+ {0x00, 0x7b, 0x7b}, {0x00, 0x7c, 0x7c}, {0x00, 0x7d, 0x7d},
+ {0x00, 0x7e, 0x7e}, {0x00, 0x7f, 0x7f}, {0x00, 0x80, 0x80},
+ {0x00, 0x81, 0x81}, {0x00, 0x82, 0x82}, {0x00, 0x83, 0x83},
+ {0x00, 0x84, 0x84}, {0x00, 0x85, 0x85}, {0x00, 0x86, 0x86},
+ {0x00, 0x87, 0x87}, {0x00, 0x88, 0x88}, {0x00, 0x89, 0x89},
+ {0x00, 0x8a, 0x8a}, {0x00, 0x8b, 0x8b}, {0x00, 0x8c, 0x8c},
+ {0x00, 0x8d, 0x8d}, {0x00, 0x8e, 0x8e}, {0x00, 0x8f, 0x8f},
+ {0x00, 0x90, 0x90}, {0x00, 0x91, 0x91}, {0x00, 0x92, 0x92},
+ {0x00, 0x93, 0x93}, {0x00, 0x94, 0x94}, {0x00, 0x95, 0x95},
+ {0x00, 0x96, 0x96}, {0x00, 0x97, 0x97}, {0x00, 0x98, 0x98},
+ {0x00, 0x99, 0x99}, {0x00, 0x9a, 0x9a}, {0x00, 0x9b, 0x9b},
+ {0x00, 0x9c, 0x9c}, {0x00, 0x9d, 0x9d}, {0x00, 0x9e, 0x9e},
+ {0x00, 0x9f, 0x9f}, {0x00, 0xa0, 0xa0}, {0x00, 0xa1, 0xa1},
+ {0x00, 0xa2, 0xa2}, {0x00, 0xa3, 0xa3}, {0x00, 0xa4, 0xa4},
+ {0x00, 0xa5, 0xa5}, {0x00, 0xa6, 0xa6}, {0x00, 0xa7, 0xa7},
+ {0x00, 0xa8, 0xa8}, {0x00, 0xa9, 0xa9}, {0x00, 0xaa, 0xaa},
+ {0x00, 0xab, 0xab}, {0x00, 0xac, 0xac}, {0x00, 0xad, 0xad},
+ {0x00, 0xae, 0xae}, {0x00, 0xaf, 0xaf}, {0x00, 0xb0, 0xb0},
+ {0x00, 0xb1, 0xb1}, {0x00, 0xb2, 0xb2}, {0x00, 0xb3, 0xb3},
+ {0x00, 0xb4, 0xb4}, {0x00, 0xb5, 0xb5}, {0x00, 0xb6, 0xb6},
+ {0x00, 0xb7, 0xb7}, {0x00, 0xb8, 0xb8}, {0x00, 0xb9, 0xb9},
+ {0x00, 0xba, 0xba}, {0x00, 0xbb, 0xbb}, {0x00, 0xbc, 0xbc},
+ {0x00, 0xbd, 0xbd}, {0x00, 0xbe, 0xbe}, {0x00, 0xbf, 0xbf},
+ {0x00, 0xc0, 0xc0}, {0x00, 0xc1, 0xc1}, {0x00, 0xc2, 0xc2},
+ {0x00, 0xc3, 0xc3}, {0x00, 0xc4, 0xc4}, {0x00, 0xc5, 0xc5},
+ {0x00, 0xc6, 0xc6}, {0x00, 0xc7, 0xc7}, {0x00, 0xc8, 0xc8},
+ {0x00, 0xc9, 0xc9}, {0x00, 0xca, 0xca}, {0x00, 0xcb, 0xcb},
+ {0x00, 0xcc, 0xcc}, {0x00, 0xcd, 0xcd}, {0x00, 0xce, 0xce},
+ {0x00, 0xcf, 0xcf}, {0x00, 0xd0, 0xd0}, {0x00, 0xd1, 0xd1},
+ {0x00, 0xd2, 0xd2}, {0x00, 0xd3, 0xd3}, {0x00, 0xd4, 0xd4},
+ {0x00, 0xd5, 0xd5}, {0x00, 0xd6, 0xd6}, {0x00, 0xd7, 0xd7},
+ {0x00, 0xd8, 0xd8}, {0x00, 0xd9, 0xd9}, {0x00, 0xda, 0xda},
+ {0x00, 0xdb, 0xdb}, {0x00, 0xdc, 0xdc}, {0x00, 0xdd, 0xdd},
+ {0x00, 0xde, 0xde}, {0x00, 0xdf, 0xdf}, {0x00, 0xe0, 0xe0},
+ {0x00, 0xe1, 0xe1}, {0x00, 0xe2, 0xe2}, {0x00, 0xe3, 0xe3},
+ {0x00, 0xe4, 0xe4}, {0x00, 0xe5, 0xe5}, {0x00, 0xe6, 0xe6},
+ {0x00, 0xe7, 0xe7}, {0x00, 0xe8, 0xe8}, {0x00, 0xe9, 0xe9},
+ {0x00, 0xea, 0xea}, {0x00, 0xeb, 0xeb}, {0x00, 0xec, 0xec},
+ {0x00, 0xed, 0xed}, {0x00, 0xee, 0xee}, {0x00, 0xef, 0xef},
+ {0x00, 0xf0, 0xf0}, {0x00, 0xf1, 0xf1}, {0x00, 0xf2, 0xf2},
+ {0x00, 0xf3, 0xf3}, {0x00, 0xf4, 0xf4}, {0x00, 0xf5, 0xf5},
+ {0x00, 0xf6, 0xf6}, {0x00, 0xf7, 0xf7}, {0x00, 0xf8, 0xf8},
+ {0x00, 0xf9, 0xf9}, {0x00, 0xfa, 0xfa}, {0x00, 0xfb, 0xfb},
+ {0x00, 0xfc, 0xfc}, {0x00, 0xfd, 0xfd}, {0x00, 0xfe, 0xfe},
+ {0x00, 0xff, 0xff}};
+
+static struct cs_info tis620_tbl[] = {
+ {0x00, 0x00, 0x00}, {0x00, 0x01, 0x01}, {0x00, 0x02, 0x02},
+ {0x00, 0x03, 0x03}, {0x00, 0x04, 0x04}, {0x00, 0x05, 0x05},
+ {0x00, 0x06, 0x06}, {0x00, 0x07, 0x07}, {0x00, 0x08, 0x08},
+ {0x00, 0x09, 0x09}, {0x00, 0x0a, 0x0a}, {0x00, 0x0b, 0x0b},
+ {0x00, 0x0c, 0x0c}, {0x00, 0x0d, 0x0d}, {0x00, 0x0e, 0x0e},
+ {0x00, 0x0f, 0x0f}, {0x00, 0x10, 0x10}, {0x00, 0x11, 0x11},
+ {0x00, 0x12, 0x12}, {0x00, 0x13, 0x13}, {0x00, 0x14, 0x14},
+ {0x00, 0x15, 0x15}, {0x00, 0x16, 0x16}, {0x00, 0x17, 0x17},
+ {0x00, 0x18, 0x18}, {0x00, 0x19, 0x19}, {0x00, 0x1a, 0x1a},
+ {0x00, 0x1b, 0x1b}, {0x00, 0x1c, 0x1c}, {0x00, 0x1d, 0x1d},
+ {0x00, 0x1e, 0x1e}, {0x00, 0x1f, 0x1f}, {0x00, 0x20, 0x20},
+ {0x00, 0x21, 0x21}, {0x00, 0x22, 0x22}, {0x00, 0x23, 0x23},
+ {0x00, 0x24, 0x24}, {0x00, 0x25, 0x25}, {0x00, 0x26, 0x26},
+ {0x00, 0x27, 0x27}, {0x00, 0x28, 0x28}, {0x00, 0x29, 0x29},
+ {0x00, 0x2a, 0x2a}, {0x00, 0x2b, 0x2b}, {0x00, 0x2c, 0x2c},
+ {0x00, 0x2d, 0x2d}, {0x00, 0x2e, 0x2e}, {0x00, 0x2f, 0x2f},
+ {0x00, 0x30, 0x30}, {0x00, 0x31, 0x31}, {0x00, 0x32, 0x32},
+ {0x00, 0x33, 0x33}, {0x00, 0x34, 0x34}, {0x00, 0x35, 0x35},
+ {0x00, 0x36, 0x36}, {0x00, 0x37, 0x37}, {0x00, 0x38, 0x38},
+ {0x00, 0x39, 0x39}, {0x00, 0x3a, 0x3a}, {0x00, 0x3b, 0x3b},
+ {0x00, 0x3c, 0x3c}, {0x00, 0x3d, 0x3d}, {0x00, 0x3e, 0x3e},
+ {0x00, 0x3f, 0x3f}, {0x00, 0x40, 0x40}, {0x01, 0x61, 0x41},
+ {0x01, 0x62, 0x42}, {0x01, 0x63, 0x43}, {0x01, 0x64, 0x44},
+ {0x01, 0x65, 0x45}, {0x01, 0x66, 0x46}, {0x01, 0x67, 0x47},
+ {0x01, 0x68, 0x48}, {0x01, 0x69, 0x49}, {0x01, 0x6a, 0x4a},
+ {0x01, 0x6b, 0x4b}, {0x01, 0x6c, 0x4c}, {0x01, 0x6d, 0x4d},
+ {0x01, 0x6e, 0x4e}, {0x01, 0x6f, 0x4f}, {0x01, 0x70, 0x50},
+ {0x01, 0x71, 0x51}, {0x01, 0x72, 0x52}, {0x01, 0x73, 0x53},
+ {0x01, 0x74, 0x54}, {0x01, 0x75, 0x55}, {0x01, 0x76, 0x56},
+ {0x01, 0x77, 0x57}, {0x01, 0x78, 0x58}, {0x01, 0x79, 0x59},
+ {0x01, 0x7a, 0x5a}, {0x00, 0x5b, 0x5b}, {0x00, 0x5c, 0x5c},
+ {0x00, 0x5d, 0x5d}, {0x00, 0x5e, 0x5e}, {0x00, 0x5f, 0x5f},
+ {0x00, 0x60, 0x60}, {0x00, 0x61, 0x41}, {0x00, 0x62, 0x42},
+ {0x00, 0x63, 0x43}, {0x00, 0x64, 0x44}, {0x00, 0x65, 0x45},
+ {0x00, 0x66, 0x46}, {0x00, 0x67, 0x47}, {0x00, 0x68, 0x48},
+ {0x00, 0x69, 0x49}, {0x00, 0x6a, 0x4a}, {0x00, 0x6b, 0x4b},
+ {0x00, 0x6c, 0x4c}, {0x00, 0x6d, 0x4d}, {0x00, 0x6e, 0x4e},
+ {0x00, 0x6f, 0x4f}, {0x00, 0x70, 0x50}, {0x00, 0x71, 0x51},
+ {0x00, 0x72, 0x52}, {0x00, 0x73, 0x53}, {0x00, 0x74, 0x54},
+ {0x00, 0x75, 0x55}, {0x00, 0x76, 0x56}, {0x00, 0x77, 0x57},
+ {0x00, 0x78, 0x58}, {0x00, 0x79, 0x59}, {0x00, 0x7a, 0x5a},
+ {0x00, 0x7b, 0x7b}, {0x00, 0x7c, 0x7c}, {0x00, 0x7d, 0x7d},
+ {0x00, 0x7e, 0x7e}, {0x00, 0x7f, 0x7f}, {0x00, 0x80, 0x80},
+ {0x00, 0x81, 0x81}, {0x00, 0x82, 0x82}, {0x00, 0x83, 0x83},
+ {0x00, 0x84, 0x84}, {0x00, 0x85, 0x85}, {0x00, 0x86, 0x86},
+ {0x00, 0x87, 0x87}, {0x00, 0x88, 0x88}, {0x00, 0x89, 0x89},
+ {0x00, 0x8a, 0x8a}, {0x00, 0x8b, 0x8b}, {0x00, 0x8c, 0x8c},
+ {0x00, 0x8d, 0x8d}, {0x00, 0x8e, 0x8e}, {0x00, 0x8f, 0x8f},
+ {0x00, 0x90, 0x90}, {0x00, 0x91, 0x91}, {0x00, 0x92, 0x92},
+ {0x00, 0x93, 0x93}, {0x00, 0x94, 0x94}, {0x00, 0x95, 0x95},
+ {0x00, 0x96, 0x96}, {0x00, 0x97, 0x97}, {0x00, 0x98, 0x98},
+ {0x00, 0x99, 0x99}, {0x00, 0x9a, 0x9a}, {0x00, 0x9b, 0x9b},
+ {0x00, 0x9c, 0x9c}, {0x00, 0x9d, 0x9d}, {0x00, 0x9e, 0x9e},
+ {0x00, 0x9f, 0x9f}, {0x00, 0xa0, 0xa0}, {0x00, 0xa1, 0xa1},
+ {0x00, 0xa2, 0xa2}, {0x00, 0xa3, 0xa3}, {0x00, 0xa4, 0xa4},
+ {0x00, 0xa5, 0xa5}, {0x00, 0xa6, 0xa6}, {0x00, 0xa7, 0xa7},
+ {0x00, 0xa8, 0xa8}, {0x00, 0xa9, 0xa9}, {0x00, 0xaa, 0xaa},
+ {0x00, 0xab, 0xab}, {0x00, 0xac, 0xac}, {0x00, 0xad, 0xad},
+ {0x00, 0xae, 0xae}, {0x00, 0xaf, 0xaf}, {0x00, 0xb0, 0xb0},
+ {0x00, 0xb1, 0xb1}, {0x00, 0xb2, 0xb2}, {0x00, 0xb3, 0xb3},
+ {0x00, 0xb4, 0xb4}, {0x00, 0xb5, 0xb5}, {0x00, 0xb6, 0xb6},
+ {0x00, 0xb7, 0xb7}, {0x00, 0xb8, 0xb8}, {0x00, 0xb9, 0xb9},
+ {0x00, 0xba, 0xba}, {0x00, 0xbb, 0xbb}, {0x00, 0xbc, 0xbc},
+ {0x00, 0xbd, 0xbd}, {0x00, 0xbe, 0xbe}, {0x00, 0xbf, 0xbf},
+ {0x00, 0xc0, 0xc0}, {0x00, 0xc1, 0xc1}, {0x00, 0xc2, 0xc2},
+ {0x00, 0xc3, 0xc3}, {0x00, 0xc4, 0xc4}, {0x00, 0xc5, 0xc5},
+ {0x00, 0xc6, 0xc6}, {0x00, 0xc7, 0xc7}, {0x00, 0xc8, 0xc8},
+ {0x00, 0xc9, 0xc9}, {0x00, 0xca, 0xca}, {0x00, 0xcb, 0xcb},
+ {0x00, 0xcc, 0xcc}, {0x00, 0xcd, 0xcd}, {0x00, 0xce, 0xce},
+ {0x00, 0xcf, 0xcf}, {0x00, 0xd0, 0xd0}, {0x00, 0xd1, 0xd1},
+ {0x00, 0xd2, 0xd2}, {0x00, 0xd3, 0xd3}, {0x00, 0xd4, 0xd4},
+ {0x00, 0xd5, 0xd5}, {0x00, 0xd6, 0xd6}, {0x00, 0xd7, 0xd7},
+ {0x00, 0xd8, 0xd8}, {0x00, 0xd9, 0xd9}, {0x00, 0xda, 0xda},
+ {0x00, 0xdb, 0xdb}, {0x00, 0xdc, 0xdc}, {0x00, 0xdd, 0xdd},
+ {0x00, 0xde, 0xde}, {0x00, 0xdf, 0xdf}, {0x00, 0xe0, 0xe0},
+ {0x00, 0xe1, 0xe1}, {0x00, 0xe2, 0xe2}, {0x00, 0xe3, 0xe3},
+ {0x00, 0xe4, 0xe4}, {0x00, 0xe5, 0xe5}, {0x00, 0xe6, 0xe6},
+ {0x00, 0xe7, 0xe7}, {0x00, 0xe8, 0xe8}, {0x00, 0xe9, 0xe9},
+ {0x00, 0xea, 0xea}, {0x00, 0xeb, 0xeb}, {0x00, 0xec, 0xec},
+ {0x00, 0xed, 0xed}, {0x00, 0xee, 0xee}, {0x00, 0xef, 0xef},
+ {0x00, 0xf0, 0xf0}, {0x00, 0xf1, 0xf1}, {0x00, 0xf2, 0xf2},
+ {0x00, 0xf3, 0xf3}, {0x00, 0xf4, 0xf4}, {0x00, 0xf5, 0xf5},
+ {0x00, 0xf6, 0xf6}, {0x00, 0xf7, 0xf7}, {0x00, 0xf8, 0xf8},
+ {0x00, 0xf9, 0xf9}, {0x00, 0xfa, 0xfa}, {0x00, 0xfb, 0xfb},
+ {0x00, 0xfc, 0xfc}, {0x00, 0xfd, 0xfd}, {0x00, 0xfe, 0xfe},
+ {0x00, 0xff, 0xff}};
+
+struct enc_entry {
+ const char* enc_name;
+ struct cs_info* cs_table;
+};
+
+static struct enc_entry encds[] = {
+ {"iso88591", iso1_tbl}, // ISO-8859-1
+ {"iso88592", iso2_tbl}, // ISO-8859-2
+ {"iso88593", iso3_tbl}, // ISO-8859-3
+ {"iso88594", iso4_tbl}, // ISO-8859-4
+ {"iso88595", iso5_tbl}, // ISO-8859-5
+ {"iso88596", iso6_tbl}, // ISO-8859-6
+ {"iso88597", iso7_tbl}, // ISO-8859-7
+ {"iso88598", iso8_tbl}, // ISO-8859-8
+ {"iso88599", iso9_tbl}, // ISO-8859-9
+ {"iso885910", iso10_tbl}, // ISO-8859-10
+ {"tis620", tis620_tbl}, // TIS-620/ISO-8859-11
+ {"tis6202533", tis620_tbl}, // TIS-620/ISO-8859-11
+ {"iso885911", tis620_tbl}, // TIS-620/ISO-8859-11
+ {"iso885913", iso13_tbl}, // ISO-8859-13
+ {"iso885914", iso14_tbl}, // ISO-8859-14
+ {"iso885915", iso15_tbl}, // ISO-8859-15
+ {"koi8r", koi8r_tbl}, // KOI8-R
+ {"koi8u", koi8u_tbl}, // KOI8-U
+ {"cp1251", cp1251_tbl}, // CP-1251
+ {"microsoftcp1251", cp1251_tbl}, // microsoft-cp1251
+ {"xisciias", iscii_devanagari_tbl}, // x-iscii-as
+ {"isciidevanagari", iscii_devanagari_tbl} // ISCII-DEVANAGARI
+};
+
+/* map to lower case and remove non alphanumeric chars */
+static void toAsciiLowerAndRemoveNonAlphanumeric(const char* pName,
+ char* pBuf) {
+ while (*pName) {
+ /* A-Z */
+ if ((*pName >= 0x41) && (*pName <= 0x5A)) {
+ *pBuf = (*pName) + 0x20; /* toAsciiLower */
+ pBuf++;
+ }
+ /* a-z, 0-9 */
+ else if (((*pName >= 0x61) && (*pName <= 0x7A)) ||
+ ((*pName >= 0x30) && (*pName <= 0x39))) {
+ *pBuf = *pName;
+ pBuf++;
+ }
+
+ pName++;
+ }
+
+ *pBuf = '\0';
+}
+
+struct cs_info* get_current_cs(const std::string& es) {
+ char* normalized_encoding = new char[es.size() + 1];
+ toAsciiLowerAndRemoveNonAlphanumeric(es.c_str(), normalized_encoding);
+
+ struct cs_info* ccs = NULL;
+ int n = sizeof(encds) / sizeof(encds[0]);
+ for (int i = 0; i < n; i++) {
+ if (strcmp(normalized_encoding, encds[i].enc_name) == 0) {
+ ccs = encds[i].cs_table;
+ break;
+ }
+ }
+
+ delete[] normalized_encoding;
+
+ if (!ccs) {
+ HUNSPELL_WARNING(stderr,
+ "error: unknown encoding %s: using %s as fallback\n", es.c_str(),
+ encds[0].enc_name);
+ ccs = encds[0].cs_table;
+ }
+
+ return ccs;
+}
+#else
+struct cs_info* get_current_cs(const std::string& es) {
+ return moz_hunspell_GetCurrentCS(es.c_str());
+}
+#endif
+
+// primitive isalpha() replacement for tokenization
+std::string get_casechars(const char* enc) {
+ struct cs_info* csconv = get_current_cs(enc);
+ std::string expw;
+ for (int i = 0; i <= 255; ++i) {
+ if (cupper(csconv, i) != clower(csconv, i)) {
+ expw.push_back(static_cast<char>(i));
+ }
+ }
+#ifdef MOZILLA_CLIENT
+ delete[] csconv;
+#endif
+ return expw;
+}
+
+// language to encoding default map
+
+struct lang_map {
+ const char* lang;
+ int num;
+};
+
+static struct lang_map lang2enc[] =
+ {{"ar", LANG_ar}, {"az", LANG_az},
+ {"az_AZ", LANG_az}, // for back-compatibility
+ {"bg", LANG_bg}, {"ca", LANG_ca},
+ {"crh", LANG_crh},
+ {"cs", LANG_cs}, {"da", LANG_da},
+ {"de", LANG_de}, {"el", LANG_el},
+ {"en", LANG_en}, {"es", LANG_es},
+ {"eu", LANG_eu}, {"gl", LANG_gl},
+ {"fr", LANG_fr}, {"hr", LANG_hr},
+ {"hu", LANG_hu}, {"hu_HU", LANG_hu}, // for back-compatibility
+ {"it", LANG_it}, {"la", LANG_la},
+ {"lv", LANG_lv}, {"nl", LANG_nl},
+ {"pl", LANG_pl}, {"pt", LANG_pt},
+ {"sv", LANG_sv}, {"tr", LANG_tr},
+ {"tr_TR", LANG_tr}, // for back-compatibility
+ {"ru", LANG_ru}, {"uk", LANG_uk}};
+
+int get_lang_num(const std::string& lang) {
+ int n = sizeof(lang2enc) / sizeof(lang2enc[0]);
+ for (int i = 0; i < n; i++) {
+ if (strcmp(lang.c_str(), lang2enc[i].lang) == 0) {
+ return lang2enc[i].num;
+ }
+ }
+ return LANG_xx;
+}
+
+#ifndef OPENOFFICEORG
+#ifndef MOZILLA_CLIENT
+void initialize_utf_tbl() {
+ utf_tbl_count++;
+ if (utf_tbl)
+ return;
+ utf_tbl = new unicode_info2[CONTSIZE];
+ for (size_t j = 0; j < CONTSIZE; ++j) {
+ utf_tbl[j].cletter = 0;
+ utf_tbl[j].clower = (unsigned short)j;
+ utf_tbl[j].cupper = (unsigned short)j;
+ }
+ for (size_t j = 0; j < UTF_LST_LEN; ++j) {
+ utf_tbl[utf_lst[j].c].cletter = 1;
+ utf_tbl[utf_lst[j].c].clower = utf_lst[j].clower;
+ utf_tbl[utf_lst[j].c].cupper = utf_lst[j].cupper;
+ }
+}
+#endif
+#endif
+
+void free_utf_tbl() {
+ if (utf_tbl_count > 0)
+ utf_tbl_count--;
+ if (utf_tbl && (utf_tbl_count == 0)) {
+ delete[] utf_tbl;
+ utf_tbl = NULL;
+ }
+}
+
+unsigned short unicodetoupper(unsigned short c, int langnum) {
+ // In Azeri and Turkish, I and i dictinct letters:
+ // There are a dotless lower case i pair of upper `I',
+ // and an upper I with dot pair of lower `i'.
+ if (c == 0x0069 && ((langnum == LANG_az) || (langnum == LANG_tr) || (langnum == LANG_crh)))
+ return 0x0130;
+#ifdef OPENOFFICEORG
+ return static_cast<unsigned short>(u_toupper(c));
+#else
+#ifdef MOZILLA_CLIENT
+ return moz_hunspell_ToUpperCase((char16_t)c);
+#else
+ return (utf_tbl) ? utf_tbl[c].cupper : c;
+#endif
+#endif
+}
+
+unsigned short unicodetolower(unsigned short c, int langnum) {
+ // In Azeri and Turkish, I and i dictinct letters:
+ // There are a dotless lower case i pair of upper `I',
+ // and an upper I with dot pair of lower `i'.
+ if (c == 0x0049 && ((langnum == LANG_az) || (langnum == LANG_tr) || (langnum == LANG_crh)))
+ return 0x0131;
+#ifdef OPENOFFICEORG
+ return static_cast<unsigned short>(u_tolower(c));
+#else
+#ifdef MOZILLA_CLIENT
+ return moz_hunspell_ToLowerCase((char16_t)c);
+#else
+ return (utf_tbl) ? utf_tbl[c].clower : c;
+#endif
+#endif
+}
+
+int unicodeisalpha(unsigned short c) {
+#ifdef OPENOFFICEORG
+ return u_isalpha(c);
+#else
+ return (utf_tbl) ? utf_tbl[c].cletter : 0;
+#endif
+}
+
+/* get type of capitalization */
+int get_captype(const std::string& word, cs_info* csconv) {
+ // now determine the capitalization type of the first nl letters
+ size_t ncap = 0;
+ size_t nneutral = 0;
+ size_t firstcap = 0;
+ if (csconv == NULL)
+ return NOCAP;
+ for (std::string::const_iterator q = word.begin(); q != word.end(); ++q) {
+ unsigned char nIndex = static_cast<unsigned char>(*q);
+ if (ccase(csconv, nIndex))
+ ncap++;
+ if (cupper(csconv, nIndex) == clower(csconv, nIndex))
+ nneutral++;
+ }
+ if (ncap) {
+ unsigned char nIndex = static_cast<unsigned char>(word[0]);
+ firstcap = csconv[nIndex].ccase;
+ }
+
+ // now finally set the captype
+ if (ncap == 0) {
+ return NOCAP;
+ } else if ((ncap == 1) && firstcap) {
+ return INITCAP;
+ } else if ((ncap == word.size()) || ((ncap + nneutral) == word.size())) {
+ return ALLCAP;
+ } else if ((ncap > 1) && firstcap) {
+ return HUHINITCAP;
+ }
+ return HUHCAP;
+}
+
+int get_captype_utf8(const std::vector<w_char>& word, int langnum) {
+ // now determine the capitalization type of the first nl letters
+ size_t ncap = 0;
+ size_t nneutral = 0;
+ size_t firstcap = 0;
+
+ std::vector<w_char>::const_iterator it = word.begin();
+ std::vector<w_char>::const_iterator it_end = word.end();
+ while (it != it_end) {
+ unsigned short idx = (it->h << 8) + it->l;
+ unsigned short lwridx = unicodetolower(idx, langnum);
+ if (idx != lwridx)
+ ncap++;
+ if (unicodetoupper(idx, langnum) == lwridx)
+ nneutral++;
+ ++it;
+ }
+ if (ncap) {
+ unsigned short idx = (word[0].h << 8) + word[0].l;
+ firstcap = (idx != unicodetolower(idx, langnum));
+ }
+
+ // now finally set the captype
+ if (ncap == 0) {
+ return NOCAP;
+ } else if ((ncap == 1) && firstcap) {
+ return INITCAP;
+ } else if ((ncap == word.size()) || ((ncap + nneutral) == word.size())) {
+ return ALLCAP;
+ } else if ((ncap > 1) && firstcap) {
+ return HUHINITCAP;
+ }
+ return HUHCAP;
+}
+
+// strip all ignored characters in the string
+size_t remove_ignored_chars_utf(std::string& word,
+ const std::vector<w_char>& ignored_chars) {
+ std::vector<w_char> w;
+ std::vector<w_char> w2;
+ u8_u16(w, word);
+
+ for (size_t i = 0; i < w.size(); ++i) {
+ if (!std::binary_search(ignored_chars.begin(),
+ ignored_chars.end(),
+ w[i])) {
+ w2.push_back(w[i]);
+ }
+ }
+
+ u16_u8(word, w2);
+ return w2.size();
+}
+
+// strip all ignored characters in the string
+size_t remove_ignored_chars(std::string& word,
+ const std::string& ignored_chars) {
+ word.erase(
+ std::remove_if(word.begin(), word.end(), is_any_of(ignored_chars)),
+ word.end());
+ return word.size();
+}
+
+bool parse_string(const std::string& line, std::string& out, int ln) {
+ if (!out.empty()) {
+ HUNSPELL_WARNING(stderr, "error: line %d: multiple definitions\n", ln);
+ return false;
+ }
+ int i = 0;
+ int np = 0;
+ std::string::const_iterator iter = line.begin();
+ std::string::const_iterator start_piece = mystrsep(line, iter);
+ while (start_piece != line.end()) {
+ switch (i) {
+ case 0: {
+ np++;
+ break;
+ }
+ case 1: {
+ out.assign(start_piece, iter);
+ np++;
+ break;
+ }
+ default:
+ break;
+ }
+ ++i;
+ start_piece = mystrsep(line, iter);
+ }
+ if (np != 2) {
+ HUNSPELL_WARNING(stderr, "error: line %d: missing data\n", ln);
+ return false;
+ }
+ return true;
+}
+
+bool parse_array(const std::string& line,
+ std::string& out,
+ std::vector<w_char>& out_utf16,
+ int utf8,
+ int ln) {
+ if (!parse_string(line, out, ln))
+ return false;
+ if (utf8) {
+ u8_u16(out_utf16, out);
+ std::sort(out_utf16.begin(), out_utf16.end());
+ }
+ return true;
+}
diff --git a/extensions/spellcheck/hunspell/src/csutil.hxx b/extensions/spellcheck/hunspell/src/csutil.hxx
new file mode 100644
index 0000000000..96f15c1469
--- /dev/null
+++ b/extensions/spellcheck/hunspell/src/csutil.hxx
@@ -0,0 +1,323 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * Copyright (C) 2002-2022 N辿meth L叩szl坦
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (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.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * Hunspell is based on MySpell which is Copyright (C) 2002 Kevin Hendricks.
+ *
+ * Contributor(s): David Einstein, Davide Prina, Giuseppe Modugno,
+ * Gianluca Turconi, Simon Brouwer, Noll J叩nos, B鱈r坦 rp叩d,
+ * Goldman Eleon坦ra, Sarl坦s Tam叩s, Bencs叩th Boldizs叩r, Hal叩csy P辿ter,
+ * Dvornik L叩szl坦, Gefferth Andr叩s, Nagy Viktor, Varga D叩niel, Chris Halls,
+ * Rene Engelhard, Bram Moolenaar, Dafydd Jones, Harri Pitk辰nen
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+/*
+ * Copyright 2002 Kevin B. Hendricks, Stratford, Ontario, Canada
+ * And Contributors. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. All modifications to the source code must be clearly marked as
+ * such. Binary redistributions based on modified source code
+ * must be clearly marked as modified versions in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY KEVIN B. HENDRICKS AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
+ * KEVIN B. HENDRICKS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef CSUTIL_HXX_
+#define CSUTIL_HXX_
+
+#include "hunvisapi.h"
+
+// First some base level utility routines
+
+#include <fstream>
+#include <string>
+#include <vector>
+#include <string.h>
+#include "w_char.hxx"
+#include "htypes.hxx"
+
+// casing
+#define NOCAP 0
+#define INITCAP 1
+#define ALLCAP 2
+#define HUHCAP 3
+#define HUHINITCAP 4
+
+// default encoding and keystring
+#define SPELL_ENCODING "ISO8859-1"
+#define SPELL_KEYSTRING "qwertyuiop|asdfghjkl|zxcvbnm"
+
+// default morphological fields
+#define MORPH_STEM "st:"
+#define MORPH_ALLOMORPH "al:"
+#define MORPH_POS "po:"
+#define MORPH_DERI_PFX "dp:"
+#define MORPH_INFL_PFX "ip:"
+#define MORPH_TERM_PFX "tp:"
+#define MORPH_DERI_SFX "ds:"
+#define MORPH_INFL_SFX "is:"
+#define MORPH_TERM_SFX "ts:"
+#define MORPH_SURF_PFX "sp:"
+#define MORPH_FREQ "fr:"
+#define MORPH_PHON "ph:"
+#define MORPH_HYPH "hy:"
+#define MORPH_PART "pa:"
+#define MORPH_FLAG "fl:"
+#define MORPH_HENTRY "_H:"
+#define MORPH_TAG_LEN strlen(MORPH_STEM)
+
+#define MSEP_FLD ' '
+#define MSEP_REC '\n'
+#define MSEP_ALT '\v'
+
+// default flags
+#define DEFAULTFLAGS 65510
+#define FORBIDDENWORD 65510
+#define ONLYUPCASEFLAG 65511
+
+// fix long pathname problem of WIN32 by using w_char std::fstream::open override
+LIBHUNSPELL_DLL_EXPORTED void myopen(std::ifstream& stream, const char* path,
+ std::ios_base::openmode mode);
+
+// convert UTF-16 characters to UTF-8
+LIBHUNSPELL_DLL_EXPORTED std::string& u16_u8(std::string& dest,
+ const std::vector<w_char>& src);
+
+// convert UTF-8 characters to UTF-16
+LIBHUNSPELL_DLL_EXPORTED int u8_u16(std::vector<w_char>& dest,
+ const std::string& src);
+
+// remove end of line char(s)
+LIBHUNSPELL_DLL_EXPORTED void mychomp(std::string& s);
+
+// duplicate string
+LIBHUNSPELL_DLL_EXPORTED char* mystrdup(const char* s);
+
+// parse into tokens with char delimiter
+LIBHUNSPELL_DLL_EXPORTED std::string::const_iterator mystrsep(const std::string &str,
+ std::string::const_iterator& start);
+
+// replace pat by rep in word and return word
+LIBHUNSPELL_DLL_EXPORTED std::string& mystrrep(std::string& str,
+ const std::string& search,
+ const std::string& replace);
+
+// append s to ends of every lines in text
+LIBHUNSPELL_DLL_EXPORTED std::string& strlinecat(std::string& str,
+ const std::string& apd);
+
+// tokenize into lines with new line
+LIBHUNSPELL_DLL_EXPORTED std::vector<std::string> line_tok(const std::string& text,
+ char breakchar);
+
+// tokenize into lines with new line and uniq in place
+LIBHUNSPELL_DLL_EXPORTED void line_uniq(std::string& text, char breakchar);
+
+LIBHUNSPELL_DLL_EXPORTED void line_uniq_app(std::string& text, char breakchar);
+
+// reverse word
+LIBHUNSPELL_DLL_EXPORTED size_t reverseword(std::string& word);
+
+// reverse word
+LIBHUNSPELL_DLL_EXPORTED size_t reverseword_utf(std::string&);
+
+// remove duplicates
+LIBHUNSPELL_DLL_EXPORTED void uniqlist(std::vector<std::string>& list);
+
+// character encoding information
+struct cs_info {
+ unsigned char ccase;
+ unsigned char clower;
+ unsigned char cupper;
+};
+
+LIBHUNSPELL_DLL_EXPORTED void initialize_utf_tbl();
+LIBHUNSPELL_DLL_EXPORTED void free_utf_tbl();
+LIBHUNSPELL_DLL_EXPORTED unsigned short unicodetoupper(unsigned short c,
+ int langnum);
+LIBHUNSPELL_DLL_EXPORTED w_char upper_utf(w_char u, int langnum);
+LIBHUNSPELL_DLL_EXPORTED w_char lower_utf(w_char u, int langnum);
+LIBHUNSPELL_DLL_EXPORTED unsigned short unicodetolower(unsigned short c,
+ int langnum);
+LIBHUNSPELL_DLL_EXPORTED int unicodeisalpha(unsigned short c);
+
+LIBHUNSPELL_DLL_EXPORTED struct cs_info* get_current_cs(const std::string& es);
+
+// get language identifiers of language codes
+LIBHUNSPELL_DLL_EXPORTED int get_lang_num(const std::string& lang);
+
+// get characters of the given 8bit encoding with lower- and uppercase forms
+LIBHUNSPELL_DLL_EXPORTED std::string get_casechars(const char* enc);
+
+// convert std::string to all caps
+LIBHUNSPELL_DLL_EXPORTED std::string& mkallcap(std::string& s,
+ const struct cs_info* csconv);
+
+// convert null terminated string to all little
+LIBHUNSPELL_DLL_EXPORTED std::string& mkallsmall(std::string& s,
+ const struct cs_info* csconv);
+
+// convert first letter of string to little
+LIBHUNSPELL_DLL_EXPORTED std::string& mkinitsmall(std::string& s,
+ const struct cs_info* csconv);
+
+// convert first letter of string to capital
+LIBHUNSPELL_DLL_EXPORTED std::string& mkinitcap(std::string& s,
+ const struct cs_info* csconv);
+
+// convert first letter of UTF-8 string to capital
+LIBHUNSPELL_DLL_EXPORTED std::vector<w_char>&
+mkinitcap_utf(std::vector<w_char>& u, int langnum);
+
+// convert UTF-8 string to little
+LIBHUNSPELL_DLL_EXPORTED std::vector<w_char>&
+mkallsmall_utf(std::vector<w_char>& u, int langnum);
+
+// convert first letter of UTF-8 string to little
+LIBHUNSPELL_DLL_EXPORTED std::vector<w_char>&
+mkinitsmall_utf(std::vector<w_char>& u, int langnum);
+
+// convert UTF-8 string to capital
+LIBHUNSPELL_DLL_EXPORTED std::vector<w_char>&
+mkallcap_utf(std::vector<w_char>& u, int langnum);
+
+// get type of capitalization
+LIBHUNSPELL_DLL_EXPORTED int get_captype(const std::string& q, cs_info*);
+
+// get type of capitalization (UTF-8)
+LIBHUNSPELL_DLL_EXPORTED int get_captype_utf8(const std::vector<w_char>& q, int langnum);
+
+// strip all ignored characters in the string
+LIBHUNSPELL_DLL_EXPORTED size_t remove_ignored_chars_utf(
+ std::string& word,
+ const std::vector<w_char>& ignored_chars);
+
+// strip all ignored characters in the string
+LIBHUNSPELL_DLL_EXPORTED size_t remove_ignored_chars(
+ std::string& word,
+ const std::string& ignored_chars);
+
+LIBHUNSPELL_DLL_EXPORTED bool parse_string(const std::string& line,
+ std::string& out,
+ int ln);
+
+LIBHUNSPELL_DLL_EXPORTED bool parse_array(const std::string& line,
+ std::string& out,
+ std::vector<w_char>& out_utf16,
+ int utf8,
+ int ln);
+
+LIBHUNSPELL_DLL_EXPORTED int fieldlen(const char* r);
+
+LIBHUNSPELL_DLL_EXPORTED bool copy_field(std::string& dest,
+ const std::string& morph,
+ const std::string& var);
+
+// conversion function for protected memory
+LIBHUNSPELL_DLL_EXPORTED void store_pointer(char* dest, char* source);
+
+// conversion function for protected memory
+LIBHUNSPELL_DLL_EXPORTED char* get_stored_pointer(const char* s);
+
+
+// to avoid unnecessary string copies and Unicode conversions
+// we simply check the ignored_chars characters in the word
+// (in the case of UTF-8 encoded strings, "false" means
+// "likely false", if ignored_chars characters are not ASCII)
+inline bool has_no_ignored_chars(const std::string& word,
+ const std::string& ignored_chars) {
+ for (std::string::const_iterator it = ignored_chars.begin(), end = ignored_chars.end(); it != end; ++it)
+ if (word.find(*it) != std::string::npos)
+ return false;
+ return true;
+}
+
+// hash entry macros
+inline char* HENTRY_DATA(struct hentry* h) {
+ char* ret;
+ if (!(h->var & H_OPT))
+ ret = NULL;
+ else if (h->var & H_OPT_ALIASM)
+ ret = get_stored_pointer(HENTRY_WORD(h) + h->blen + 1);
+ else
+ ret = HENTRY_WORD(h) + h->blen + 1;
+ return ret;
+}
+
+inline const char* HENTRY_DATA(
+ const struct hentry* h) {
+ const char* ret;
+ if (!(h->var & H_OPT))
+ ret = NULL;
+ else if (h->var & H_OPT_ALIASM)
+ ret = get_stored_pointer(HENTRY_WORD(h) + h->blen + 1);
+ else
+ ret = HENTRY_WORD(h) + h->blen + 1;
+ return ret;
+}
+
+// NULL-free version for warning-free OOo build
+inline const char* HENTRY_DATA2(
+ const struct hentry* h) {
+ const char* ret;
+ if (!(h->var & H_OPT))
+ ret = "";
+ else if (h->var & H_OPT_ALIASM)
+ ret = get_stored_pointer(HENTRY_WORD(h) + h->blen + 1);
+ else
+ ret = HENTRY_WORD(h) + h->blen + 1;
+ return ret;
+}
+
+inline char* HENTRY_FIND(struct hentry* h,
+ const char* p) {
+ return (HENTRY_DATA(h) ? strstr(HENTRY_DATA(h), p) : NULL);
+}
+
+#endif
diff --git a/extensions/spellcheck/hunspell/src/filemgr.hxx b/extensions/spellcheck/hunspell/src/filemgr.hxx
new file mode 100644
index 0000000000..7773a321a6
--- /dev/null
+++ b/extensions/spellcheck/hunspell/src/filemgr.hxx
@@ -0,0 +1,77 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * Copyright (C) 2002-2022 N辿meth L叩szl坦
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (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.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * Hunspell is based on MySpell which is Copyright (C) 2002 Kevin Hendricks.
+ *
+ * Contributor(s): David Einstein, Davide Prina, Giuseppe Modugno,
+ * Gianluca Turconi, Simon Brouwer, Noll J叩nos, B鱈r坦 rp叩d,
+ * Goldman Eleon坦ra, Sarl坦s Tam叩s, Bencs叩th Boldizs叩r, Hal叩csy P辿ter,
+ * Dvornik L叩szl坦, Gefferth Andr叩s, Nagy Viktor, Varga D叩niel, Chris Halls,
+ * Rene Engelhard, Bram Moolenaar, Dafydd Jones, Harri Pitk辰nen
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+/*
+ * Copyright 2002 Kevin B. Hendricks, Stratford, Ontario, Canada
+ * And Contributors. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. All modifications to the source code must be clearly marked as
+ * such. Binary redistributions based on modified source code
+ * must be clearly marked as modified versions in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY KEVIN B. HENDRICKS AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
+ * KEVIN B. HENDRICKS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/* file manager class - read lines of files [filename] OR [filename.hz] */
+#ifndef FILEMGR_HXX_
+#define FILEMGR_HXX_
+
+#include "mozHunspellRLBoxSandbox.h"
+
+#endif
diff --git a/extensions/spellcheck/hunspell/src/hashmgr.cxx b/extensions/spellcheck/hunspell/src/hashmgr.cxx
new file mode 100644
index 0000000000..d22f2e7b7d
--- /dev/null
+++ b/extensions/spellcheck/hunspell/src/hashmgr.cxx
@@ -0,0 +1,1415 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * Copyright (C) 2002-2022 N辿meth L叩szl坦
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (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.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * Hunspell is based on MySpell which is Copyright (C) 2002 Kevin Hendricks.
+ *
+ * Contributor(s): David Einstein, Davide Prina, Giuseppe Modugno,
+ * Gianluca Turconi, Simon Brouwer, Noll J叩nos, B鱈r坦 rp叩d,
+ * Goldman Eleon坦ra, Sarl坦s Tam叩s, Bencs叩th Boldizs叩r, Hal叩csy P辿ter,
+ * Dvornik L叩szl坦, Gefferth Andr叩s, Nagy Viktor, Varga D叩niel, Chris Halls,
+ * Rene Engelhard, Bram Moolenaar, Dafydd Jones, Harri Pitk辰nen
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+/*
+ * Copyright 2002 Kevin B. Hendricks, Stratford, Ontario, Canada
+ * And Contributors. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. All modifications to the source code must be clearly marked as
+ * such. Binary redistributions based on modified source code
+ * must be clearly marked as modified versions in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY KEVIN B. HENDRICKS AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
+ * KEVIN B. HENDRICKS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <assert.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+#include <ctype.h>
+#include <limits>
+#include <sstream>
+
+#include "hashmgr.hxx"
+#include "csutil.hxx"
+#include "atypes.hxx"
+#include "langnum.hxx"
+
+// build a hash table from a munched word list
+
+HashMgr::HashMgr(const char* tpath, const char* apath, const char* key)
+ : tablesize(0),
+ tableptr(NULL),
+ flag_mode(FLAG_CHAR),
+ complexprefixes(0),
+ utf8(0),
+ forbiddenword(FORBIDDENWORD) // forbidden word signing flag
+ ,
+ numaliasf(0),
+ aliasf(NULL),
+ aliasflen(0),
+ numaliasm(0),
+ aliasm(NULL) {
+ langnum = 0;
+ csconv = 0;
+ load_config(apath, key);
+ int ec = load_tables(tpath, key);
+ if (ec) {
+ /* error condition - what should we do here */
+ HUNSPELL_WARNING(stderr, "Hash Manager Error : %d\n", ec);
+ free(tableptr);
+ //keep tablesize to 1 to fix possible division with zero
+ tablesize = 1;
+ tableptr = (struct hentry**)calloc(tablesize, sizeof(struct hentry*));
+ if (!tableptr) {
+ tablesize = 0;
+ }
+ }
+}
+
+HashMgr::~HashMgr() {
+ if (tableptr) {
+ // now pass through hash table freeing up everything
+ // go through column by column of the table
+ for (int i = 0; i < tablesize; i++) {
+ struct hentry* pt = tableptr[i];
+ struct hentry* nt = NULL;
+ while (pt) {
+ nt = pt->next;
+ if (pt->astr &&
+ (!aliasf || TESTAFF(pt->astr, ONLYUPCASEFLAG, pt->alen)))
+ arena_free(pt->astr);
+ arena_free(pt);
+ pt = nt;
+ }
+ }
+ free(tableptr);
+ }
+ tablesize = 0;
+
+ if (aliasf) {
+ for (int j = 0; j < (numaliasf); j++)
+ arena_free(aliasf[j]);
+ arena_free(aliasf);
+ aliasf = NULL;
+ if (aliasflen) {
+ arena_free(aliasflen);
+ aliasflen = NULL;
+ }
+ }
+ if (aliasm) {
+ for (int j = 0; j < (numaliasm); j++)
+ arena_free(aliasm[j]);
+ arena_free(aliasm);
+ aliasm = NULL;
+ }
+
+#ifndef OPENOFFICEORG
+#ifndef MOZILLA_CLIENT
+ if (utf8)
+ free_utf_tbl();
+#endif
+#endif
+
+#ifdef MOZILLA_CLIENT
+ delete[] csconv;
+#endif
+
+ assert(outstanding_arena_allocations == 0);
+}
+
+// lookup a root word in the hashtable
+
+struct hentry* HashMgr::lookup(const char* word) const {
+ struct hentry* dp;
+ if (tableptr) {
+ dp = tableptr[hash(word)];
+ if (!dp)
+ return NULL;
+ for (; dp != NULL; dp = dp->next) {
+ if (strcmp(word, dp->word) == 0)
+ return dp;
+ }
+ }
+ return NULL;
+}
+
+// add a word to the hash table (private)
+int HashMgr::add_word(const std::string& in_word,
+ int wcl,
+ unsigned short* aff,
+ int al,
+ const std::string* in_desc,
+ bool onlyupcase,
+ int captype) {
+ const std::string* word = &in_word;
+ const std::string* desc = in_desc;
+
+ std::string *word_copy = NULL;
+ std::string *desc_copy = NULL;
+ if ((!ignorechars.empty() && !has_no_ignored_chars(in_word, ignorechars)) || complexprefixes) {
+ word_copy = new std::string(in_word);
+
+ if (!ignorechars.empty()) {
+ if (utf8) {
+ wcl = remove_ignored_chars_utf(*word_copy, ignorechars_utf16);
+ } else {
+ remove_ignored_chars(*word_copy, ignorechars);
+ }
+ }
+
+ if (complexprefixes) {
+ if (utf8)
+ wcl = reverseword_utf(*word_copy);
+ else
+ reverseword(*word_copy);
+
+ if (in_desc && !aliasm) {
+ desc_copy = new std::string(*in_desc);
+
+ if (complexprefixes) {
+ if (utf8)
+ reverseword_utf(*desc_copy);
+ else
+ reverseword(*desc_copy);
+ }
+ desc = desc_copy;
+ }
+ }
+
+ word = word_copy;
+ }
+
+ bool upcasehomonym = false;
+ int descl = desc ? (aliasm ? sizeof(char*) : desc->size() + 1) : 0;
+ // variable-length hash record with word and optional fields
+ struct hentry* hp =
+ (struct hentry*)arena_alloc(sizeof(struct hentry) + word->size() + descl);
+ if (!hp) {
+ delete desc_copy;
+ delete word_copy;
+ return 1;
+ }
+
+ char* hpw = hp->word;
+ strcpy(hpw, word->c_str());
+
+ int i = hash(hpw);
+
+ hp->blen = (unsigned char)word->size();
+ hp->clen = (unsigned char)wcl;
+ hp->alen = (short)al;
+ hp->astr = aff;
+ hp->next = NULL;
+ hp->next_homonym = NULL;
+ hp->var = (captype == INITCAP) ? H_OPT_INITCAP : 0;
+
+ // store the description string or its pointer
+ if (desc) {
+ hp->var |= H_OPT;
+ if (aliasm) {
+ hp->var |= H_OPT_ALIASM;
+ store_pointer(hpw + word->size() + 1, get_aliasm(atoi(desc->c_str())));
+ } else {
+ strcpy(hpw + word->size() + 1, desc->c_str());
+ }
+ if (strstr(HENTRY_DATA(hp), MORPH_PHON)) {
+ hp->var |= H_OPT_PHON;
+ // store ph: fields (pronounciation, misspellings, old orthography etc.)
+ // of a morphological description in reptable to use in REP replacements.
+ if (reptable.capacity() < (unsigned int)(tablesize/MORPH_PHON_RATIO))
+ reptable.reserve(tablesize/MORPH_PHON_RATIO);
+ std::string fields = HENTRY_DATA(hp);
+ std::string::const_iterator iter = fields.begin();
+ std::string::const_iterator start_piece = mystrsep(fields, iter);
+ while (start_piece != fields.end()) {
+ if (std::string(start_piece, iter).find(MORPH_PHON) == 0) {
+ std::string ph = std::string(start_piece, iter).substr(sizeof MORPH_PHON - 1);
+ if (ph.size() > 0) {
+ std::vector<w_char> w;
+ size_t strippatt;
+ std::string wordpart;
+ // dictionary based REP replacement, separated by "->"
+ // for example "pretty ph:prity ph:priti->pretti" to handle
+ // both prity -> pretty and pritier -> prettiest suggestions.
+ if (((strippatt = ph.find("->")) != std::string::npos) &&
+ (strippatt > 0) && (strippatt < ph.size() - 2)) {
+ wordpart = ph.substr(strippatt + 2);
+ ph.erase(ph.begin() + strippatt, ph.end());
+ } else
+ wordpart = in_word;
+ // when the ph: field ends with the character *,
+ // strip last character of the pattern and the replacement
+ // to match in REP suggestions also at character changes,
+ // for example, "pretty ph:prity*" results "prit->prett"
+ // REP replacement instead of "prity->pretty", to get
+ // prity->pretty and pritiest->prettiest suggestions.
+ if (ph.at(ph.size()-1) == '*') {
+ strippatt = 1;
+ size_t stripword = 0;
+ if (utf8) {
+ while ((strippatt < ph.size()) &&
+ ((ph.at(ph.size()-strippatt-1) & 0xc0) == 0x80))
+ ++strippatt;
+ while ((stripword < wordpart.size()) &&
+ ((wordpart.at(wordpart.size()-stripword-1) & 0xc0) == 0x80))
+ ++stripword;
+ }
+ ++strippatt;
+ ++stripword;
+ if ((ph.size() > strippatt) && (wordpart.size() > stripword)) {
+ ph.erase(ph.size()-strippatt, strippatt);
+ wordpart.erase(in_word.size()-stripword, stripword);
+ }
+ }
+ // capitalize lowercase pattern for capitalized words to support
+ // good suggestions also for capitalized misspellings, eg.
+ // Wednesday ph:wendsay
+ // results wendsay -> Wednesday and Wendsay -> Wednesday, too.
+ if (captype==INITCAP) {
+ std::string ph_capitalized;
+ if (utf8) {
+ u8_u16(w, ph);
+ if (get_captype_utf8(w, langnum) == NOCAP) {
+ mkinitcap_utf(w, langnum);
+ u16_u8(ph_capitalized, w);
+ }
+ } else if (get_captype(ph, csconv) == NOCAP)
+ mkinitcap(ph_capitalized, csconv);
+
+ if (ph_capitalized.size() > 0) {
+ // add also lowercase word in the case of German or
+ // Hungarian to support lowercase suggestions lowercased by
+ // compound word generation or derivational suffixes
+ // (for example by adjectival suffix "-i" of geographical
+ // names in Hungarian:
+ // Massachusetts ph:messzecsuzec
+ // messzecsuzeci -> massachusettsi (adjective)
+ // For lowercasing by conditional PFX rules, see
+ // tests/germancompounding test example or the
+ // Hungarian dictionary.)
+ if (langnum == LANG_de || langnum == LANG_hu) {
+ std::string wordpart_lower(wordpart);
+ if (utf8) {
+ u8_u16(w, wordpart_lower);
+ mkallsmall_utf(w, langnum);
+ u16_u8(wordpart_lower, w);
+ } else {
+ mkallsmall(wordpart_lower, csconv);
+ }
+ reptable.push_back(replentry());
+ reptable.back().pattern.assign(ph);
+ reptable.back().outstrings[0].assign(wordpart_lower);
+ }
+ reptable.push_back(replentry());
+ reptable.back().pattern.assign(ph_capitalized);
+ reptable.back().outstrings[0].assign(wordpart);
+ }
+ }
+ reptable.push_back(replentry());
+ reptable.back().pattern.assign(ph);
+ reptable.back().outstrings[0].assign(wordpart);
+ }
+ }
+ start_piece = mystrsep(fields, iter);
+ }
+ }
+ }
+
+ struct hentry* dp = tableptr[i];
+ if (!dp) {
+ tableptr[i] = hp;
+ delete desc_copy;
+ delete word_copy;
+ return 0;
+ }
+ while (dp->next != NULL) {
+ if ((!dp->next_homonym) && (strcmp(hp->word, dp->word) == 0)) {
+ // remove hidden onlyupcase homonym
+ if (!onlyupcase) {
+ if ((dp->astr) && TESTAFF(dp->astr, ONLYUPCASEFLAG, dp->alen)) {
+ arena_free(dp->astr);
+ dp->astr = hp->astr;
+ dp->alen = hp->alen;
+ arena_free(hp);
+ delete desc_copy;
+ delete word_copy;
+ return 0;
+ } else {
+ dp->next_homonym = hp;
+ }
+ } else {
+ upcasehomonym = true;
+ }
+ }
+ dp = dp->next;
+ }
+ if (strcmp(hp->word, dp->word) == 0) {
+ // remove hidden onlyupcase homonym
+ if (!onlyupcase) {
+ if ((dp->astr) && TESTAFF(dp->astr, ONLYUPCASEFLAG, dp->alen)) {
+ arena_free(dp->astr);
+ dp->astr = hp->astr;
+ dp->alen = hp->alen;
+ arena_free(hp);
+ delete desc_copy;
+ delete word_copy;
+ return 0;
+ } else {
+ dp->next_homonym = hp;
+ }
+ } else {
+ upcasehomonym = true;
+ }
+ }
+ if (!upcasehomonym) {
+ dp->next = hp;
+ } else {
+ // remove hidden onlyupcase homonym
+ if (hp->astr)
+ arena_free(hp->astr);
+ arena_free(hp);
+ }
+
+ delete desc_copy;
+ delete word_copy;
+ return 0;
+}
+
+int HashMgr::add_hidden_capitalized_word(const std::string& word,
+ int wcl,
+ unsigned short* flags,
+ int flagslen,
+ const std::string* dp,
+ int captype) {
+ if (flags == NULL)
+ flagslen = 0;
+
+ // add inner capitalized forms to handle the following allcap forms:
+ // Mixed caps: OpenOffice.org -> OPENOFFICE.ORG
+ // Allcaps with suffixes: CIA's -> CIA'S
+ if (((captype == HUHCAP) || (captype == HUHINITCAP) ||
+ ((captype == ALLCAP) && (flagslen != 0))) &&
+ !((flagslen != 0) && TESTAFF(flags, forbiddenword, flagslen))) {
+ unsigned short* flags2 =
+ (unsigned short*)arena_alloc(sizeof(unsigned short) * (flagslen + 1));
+ if (!flags2)
+ return 1;
+ if (flagslen)
+ memcpy(flags2, flags, flagslen * sizeof(unsigned short));
+ flags2[flagslen] = ONLYUPCASEFLAG;
+ if (utf8) {
+ std::string st;
+ std::vector<w_char> w;
+ u8_u16(w, word);
+ mkallsmall_utf(w, langnum);
+ mkinitcap_utf(w, langnum);
+ u16_u8(st, w);
+ return add_word(st, wcl, flags2, flagslen + 1, dp, true, INITCAP);
+ } else {
+ std::string new_word(word);
+ mkallsmall(new_word, csconv);
+ mkinitcap(new_word, csconv);
+ int ret = add_word(new_word, wcl, flags2, flagslen + 1, dp, true, INITCAP);
+ return ret;
+ }
+ }
+ return 0;
+}
+
+// detect captype and modify word length for UTF-8 encoding
+int HashMgr::get_clen_and_captype(const std::string& word, int* captype, std::vector<w_char> &workbuf) {
+ int len;
+ if (utf8) {
+ len = u8_u16(workbuf, word);
+ *captype = get_captype_utf8(workbuf, langnum);
+ } else {
+ len = word.size();
+ *captype = get_captype(word, csconv);
+ }
+ return len;
+}
+
+int HashMgr::get_clen_and_captype(const std::string& word, int* captype) {
+ std::vector<w_char> workbuf;
+ return get_clen_and_captype(word, captype, workbuf);
+}
+
+// remove word (personal dictionary function for standalone applications)
+int HashMgr::remove(const std::string& word) {
+ struct hentry* dp = lookup(word.c_str());
+ while (dp) {
+ if (dp->alen == 0 || !TESTAFF(dp->astr, forbiddenword, dp->alen)) {
+ unsigned short* flags =
+ (unsigned short*)arena_alloc(sizeof(unsigned short) * (dp->alen + 1));
+ if (!flags)
+ return 1;
+ for (int i = 0; i < dp->alen; i++)
+ flags[i] = dp->astr[i];
+ flags[dp->alen] = forbiddenword;
+ arena_free(dp->astr);
+ dp->astr = flags;
+ dp->alen++;
+ std::sort(flags, flags + dp->alen);
+ }
+ dp = dp->next_homonym;
+ }
+ return 0;
+}
+
+/* remove forbidden flag to add a personal word to the hash */
+int HashMgr::remove_forbidden_flag(const std::string& word) {
+ struct hentry* dp = lookup(word.c_str());
+ if (!dp)
+ return 1;
+ while (dp) {
+ if (dp->astr && TESTAFF(dp->astr, forbiddenword, dp->alen))
+ dp->alen = 0; // XXX forbidden words of personal dic.
+ dp = dp->next_homonym;
+ }
+ return 0;
+}
+
+// add a custom dic. word to the hash table (public)
+int HashMgr::add(const std::string& word) {
+ if (remove_forbidden_flag(word)) {
+ int captype;
+ int al = 0;
+ unsigned short* flags = NULL;
+ int wcl = get_clen_and_captype(word, &captype);
+ add_word(word, wcl, flags, al, NULL, false, captype);
+ return add_hidden_capitalized_word(word, wcl, flags, al, NULL,
+ captype);
+ }
+ return 0;
+}
+
+int HashMgr::add_with_affix(const std::string& word, const std::string& example) {
+ // detect captype and modify word length for UTF-8 encoding
+ struct hentry* dp = lookup(example.c_str());
+ remove_forbidden_flag(word);
+ if (dp && dp->astr) {
+ int captype;
+ int wcl = get_clen_and_captype(word, &captype);
+ if (aliasf) {
+ add_word(word, wcl, dp->astr, dp->alen, NULL, false, captype);
+ } else {
+ unsigned short* flags =
+ (unsigned short*) arena_alloc(dp->alen * sizeof(unsigned short));
+ if (flags) {
+ memcpy((void*)flags, (void*)dp->astr,
+ dp->alen * sizeof(unsigned short));
+ add_word(word, wcl, flags, dp->alen, NULL, false, captype);
+ } else
+ return 1;
+ }
+ return add_hidden_capitalized_word(word, wcl, dp->astr,
+ dp->alen, NULL, captype);
+ }
+ return 1;
+}
+
+// walk the hash table entry by entry - null at end
+// initialize: col=-1; hp = NULL; hp = walk_hashtable(&col, hp);
+struct hentry* HashMgr::walk_hashtable(int& col, struct hentry* hp) const {
+ if (hp && hp->next != NULL)
+ return hp->next;
+ for (col++; col < tablesize; col++) {
+ if (tableptr[col])
+ return tableptr[col];
+ }
+ // null at end and reset to start
+ col = -1;
+ return NULL;
+}
+
+// load a munched word list and build a hash table on the fly
+int HashMgr::load_tables(const char* tpath, const char* key) {
+ // open dictionary file
+ FileMgr* dict = new FileMgr(tpath, key);
+ if (dict == NULL)
+ return 1;
+
+ // first read the first line of file to get hash table size */
+ std::string ts;
+ if (!dict->getline(ts)) {
+ HUNSPELL_WARNING(stderr, "error: empty dic file %s\n", tpath);
+ delete dict;
+ return 2;
+ }
+ mychomp(ts);
+
+ /* remove byte order mark */
+ if (ts.compare(0, 3, "\xEF\xBB\xBF", 3) == 0) {
+ ts.erase(0, 3);
+ }
+
+ tablesize = atoi(ts.c_str());
+
+ int nExtra = 5 + USERWORD;
+
+ if (tablesize <= 0 ||
+ (tablesize >= (std::numeric_limits<int>::max() - 1 - nExtra) /
+ int(sizeof(struct hentry*)))) {
+ HUNSPELL_WARNING(
+ stderr, "error: line 1: missing or bad word count in the dic file\n");
+ delete dict;
+ return 4;
+ }
+ tablesize += nExtra;
+ if ((tablesize % 2) == 0)
+ tablesize++;
+
+ // allocate the hash table
+ tableptr = (struct hentry**)calloc(tablesize, sizeof(struct hentry*));
+ if (!tableptr) {
+ delete dict;
+ return 3;
+ }
+
+ // loop through all words on much list and add to hash
+ // table and create word and affix strings
+
+ std::vector<w_char> workbuf;
+
+ while (dict->getline(ts)) {
+ mychomp(ts);
+ // split each line into word and morphological description
+ size_t dp_pos = 0;
+ while ((dp_pos = ts.find(':', dp_pos)) != std::string::npos) {
+ if ((dp_pos > 3) && (ts[dp_pos - 3] == ' ' || ts[dp_pos - 3] == '\t')) {
+ for (dp_pos -= 3; dp_pos > 0 && (ts[dp_pos-1] == ' ' || ts[dp_pos-1] == '\t'); --dp_pos)
+ ;
+ if (dp_pos == 0) { // missing word
+ dp_pos = std::string::npos;
+ } else {
+ ++dp_pos;
+ }
+ break;
+ }
+ ++dp_pos;
+ }
+
+ // tabulator is the old morphological field separator
+ size_t dp2_pos = ts.find('\t');
+ if (dp2_pos != std::string::npos && (dp_pos == std::string::npos || dp2_pos < dp_pos)) {
+ dp_pos = dp2_pos + 1;
+ }
+
+ std::string dp;
+ if (dp_pos != std::string::npos) {
+ dp.assign(ts.substr(dp_pos));
+ ts.resize(dp_pos - 1);
+ }
+
+ // split each line into word and affix char strings
+ // "\/" signs slash in words (not affix separator)
+ // "/" at beginning of the line is word character (not affix separator)
+ size_t ap_pos = ts.find('/');
+ while (ap_pos != std::string::npos) {
+ if (ap_pos == 0) {
+ ++ap_pos;
+ continue;
+ } else if (ts[ap_pos - 1] != '\\')
+ break;
+ // replace "\/" with "/"
+ ts.erase(ap_pos - 1, 1);
+ ap_pos = ts.find('/', ap_pos);
+ }
+
+ unsigned short* flags;
+ int al;
+ if (ap_pos != std::string::npos && ap_pos != ts.size()) {
+ std::string ap(ts.substr(ap_pos + 1));
+ ts.resize(ap_pos);
+ if (aliasf) {
+ int index = atoi(ap.c_str());
+ al = get_aliasf(index, &flags, dict);
+ if (!al) {
+ HUNSPELL_WARNING(stderr, "error: line %d: bad flag vector alias\n",
+ dict->getlinenum());
+ }
+ } else {
+ al = decode_flags(&flags, ap.c_str(), dict, /* arena = */ true);
+ if (al == -1) {
+ HUNSPELL_WARNING(stderr, "Can't allocate memory.\n");
+ delete dict;
+ return 6;
+ }
+ std::sort(flags, flags + al);
+ }
+ } else {
+ al = 0;
+ flags = NULL;
+ }
+
+ int captype;
+ int wcl = get_clen_and_captype(ts, &captype, workbuf);
+ const std::string *dp_str = dp.empty() ? NULL : &dp;
+ // add the word and its index plus its capitalized form optionally
+ if (add_word(ts, wcl, flags, al, dp_str, false, captype) ||
+ add_hidden_capitalized_word(ts, wcl, flags, al, dp_str, captype)) {
+ delete dict;
+ return 5;
+ }
+ }
+
+ delete dict;
+ return 0;
+}
+
+// the hash function is a simple load and rotate
+// algorithm borrowed
+int HashMgr::hash(const char* word) const {
+ unsigned long hv = 0;
+ for (int i = 0; i < 4 && *word != 0; i++)
+ hv = (hv << 8) | (*word++);
+ while (*word != 0) {
+ ROTATE(hv, ROTATE_LEN);
+ hv ^= (*word++);
+ }
+ return (unsigned long)hv % tablesize;
+}
+
+int HashMgr::decode_flags(unsigned short** result, const std::string& flags, FileMgr* af, bool arena) const {
+ auto alloc = [arena, this](int n) { return arena ? this->arena_alloc(n) : malloc(n); };
+ int len;
+ if (flags.empty()) {
+ *result = NULL;
+ return 0;
+ }
+ switch (flag_mode) {
+ case FLAG_LONG: { // two-character flags (1x2yZz -> 1x 2y Zz)
+ len = flags.size();
+ if (len % 2 == 1)
+ HUNSPELL_WARNING(stderr, "error: line %d: bad flagvector\n",
+ af->getlinenum());
+ len /= 2;
+ *result = (unsigned short*)alloc(len * sizeof(unsigned short));
+ if (!*result)
+ return -1;
+ for (int i = 0; i < len; i++) {
+ (*result)[i] = ((unsigned short)((unsigned char)flags[i * 2]) << 8) +
+ (unsigned char)flags[i * 2 + 1];
+ }
+ break;
+ }
+ case FLAG_NUM: { // decimal numbers separated by comma (4521,23,233 -> 4521
+ // 23 233)
+ len = 1;
+ unsigned short* dest;
+ for (size_t i = 0; i < flags.size(); ++i) {
+ if (flags[i] == ',')
+ len++;
+ }
+ *result = (unsigned short*)alloc(len * sizeof(unsigned short));
+ if (!*result)
+ return -1;
+ dest = *result;
+ const char* src = flags.c_str();
+ for (const char* p = src; *p; p++) {
+ if (*p == ',') {
+ int i = atoi(src);
+ if (i >= DEFAULTFLAGS)
+ HUNSPELL_WARNING(
+ stderr, "error: line %d: flag id %d is too large (max: %d)\n",
+ af->getlinenum(), i, DEFAULTFLAGS - 1);
+ *dest = (unsigned short)i;
+ if (*dest == 0)
+ HUNSPELL_WARNING(stderr, "error: line %d: 0 is wrong flag id\n",
+ af->getlinenum());
+ src = p + 1;
+ dest++;
+ }
+ }
+ int i = atoi(src);
+ if (i >= DEFAULTFLAGS)
+ HUNSPELL_WARNING(stderr,
+ "error: line %d: flag id %d is too large (max: %d)\n",
+ af->getlinenum(), i, DEFAULTFLAGS - 1);
+ *dest = (unsigned short)i;
+ if (*dest == 0)
+ HUNSPELL_WARNING(stderr, "error: line %d: 0 is wrong flag id\n",
+ af->getlinenum());
+ break;
+ }
+ case FLAG_UNI: { // UTF-8 characters
+ std::vector<w_char> w;
+ u8_u16(w, flags);
+ len = w.size();
+ *result = (unsigned short*)alloc(len * sizeof(unsigned short));
+ if (!*result)
+ return -1;
+ memcpy(*result, w.data(), len * sizeof(short));
+ break;
+ }
+ default: { // Ispell's one-character flags (erfg -> e r f g)
+ unsigned short* dest;
+ len = flags.size();
+ *result = (unsigned short*)alloc(len * sizeof(unsigned short));
+ if (!*result)
+ return -1;
+ dest = *result;
+ for (size_t i = 0; i < flags.size(); ++i) {
+ *dest = (unsigned char)flags[i];
+ dest++;
+ }
+ }
+ }
+ return len;
+}
+
+bool HashMgr::decode_flags(std::vector<unsigned short>& result, const std::string& flags, FileMgr* af) const {
+ if (flags.empty()) {
+ return false;
+ }
+ switch (flag_mode) {
+ case FLAG_LONG: { // two-character flags (1x2yZz -> 1x 2y Zz)
+ size_t len = flags.size();
+ if (len % 2 == 1)
+ HUNSPELL_WARNING(stderr, "error: line %d: bad flagvector\n",
+ af->getlinenum());
+ len /= 2;
+ result.reserve(result.size() + len);
+ for (size_t i = 0; i < len; ++i) {
+ result.push_back(((unsigned short)((unsigned char)flags[i * 2]) << 8) +
+ (unsigned char)flags[i * 2 + 1]);
+ }
+ break;
+ }
+ case FLAG_NUM: { // decimal numbers separated by comma (4521,23,233 -> 4521
+ // 23 233)
+ const char* src = flags.c_str();
+ for (const char* p = src; *p; p++) {
+ if (*p == ',') {
+ int i = atoi(src);
+ if (i >= DEFAULTFLAGS)
+ HUNSPELL_WARNING(
+ stderr, "error: line %d: flag id %d is too large (max: %d)\n",
+ af->getlinenum(), i, DEFAULTFLAGS - 1);
+ result.push_back((unsigned short)i);
+ if (result.back() == 0)
+ HUNSPELL_WARNING(stderr, "error: line %d: 0 is wrong flag id\n",
+ af->getlinenum());
+ src = p + 1;
+ }
+ }
+ int i = atoi(src);
+ if (i >= DEFAULTFLAGS)
+ HUNSPELL_WARNING(stderr,
+ "error: line %d: flag id %d is too large (max: %d)\n",
+ af->getlinenum(), i, DEFAULTFLAGS - 1);
+ result.push_back((unsigned short)i);
+ if (result.back() == 0)
+ HUNSPELL_WARNING(stderr, "error: line %d: 0 is wrong flag id\n",
+ af->getlinenum());
+ break;
+ }
+ case FLAG_UNI: { // UTF-8 characters
+ std::vector<w_char> w;
+ u8_u16(w, flags);
+ size_t len = w.size();
+ size_t origsize = result.size();
+ result.resize(origsize + len);
+ memcpy(result.data() + origsize, w.data(), len * sizeof(short));
+ break;
+ }
+ default: { // Ispell's one-character flags (erfg -> e r f g)
+ result.reserve(flags.size());
+ for (size_t i = 0; i < flags.size(); ++i) {
+ result.push_back((unsigned char)flags[i]);
+ }
+ }
+ }
+ return true;
+}
+
+unsigned short HashMgr::decode_flag(const char* f) const {
+ unsigned short s = 0;
+ int i;
+ switch (flag_mode) {
+ case FLAG_LONG:
+ s = ((unsigned short)((unsigned char)f[0]) << 8) + (unsigned char)f[1];
+ break;
+ case FLAG_NUM:
+ i = atoi(f);
+ if (i >= DEFAULTFLAGS)
+ HUNSPELL_WARNING(stderr, "error: flag id %d is too large (max: %d)\n",
+ i, DEFAULTFLAGS - 1);
+ s = (unsigned short)i;
+ break;
+ case FLAG_UNI: {
+ std::vector<w_char> w;
+ u8_u16(w, f);
+ if (!w.empty())
+ memcpy(&s, w.data(), 1 * sizeof(short));
+ break;
+ }
+ default:
+ s = *(unsigned char*)f;
+ }
+ if (s == 0)
+ HUNSPELL_WARNING(stderr, "error: 0 is wrong flag id\n");
+ return s;
+}
+
+// This function is only called by external consumers, and so using the default
+// allocator with mystrdup is correct.
+char* HashMgr::encode_flag(unsigned short f) const {
+ if (f == 0)
+ return mystrdup("(NULL)");
+ std::string ch;
+ if (flag_mode == FLAG_LONG) {
+ ch.push_back((unsigned char)(f >> 8));
+ ch.push_back((unsigned char)(f - ((f >> 8) << 8)));
+ } else if (flag_mode == FLAG_NUM) {
+ std::ostringstream stream;
+ stream << f;
+ ch = stream.str();
+ } else if (flag_mode == FLAG_UNI) {
+ const w_char* w_c = (const w_char*)&f;
+ std::vector<w_char> w(w_c, w_c + 1);
+ u16_u8(ch, w);
+ } else {
+ ch.push_back((unsigned char)(f));
+ }
+ return mystrdup(ch.c_str());
+}
+
+// read in aff file and set flag mode
+int HashMgr::load_config(const char* affpath, const char* key) {
+ int firstline = 1;
+
+ // open the affix file
+ FileMgr* afflst = new FileMgr(affpath, key);
+ if (!afflst) {
+ HUNSPELL_WARNING(
+ stderr, "Error - could not open affix description file %s\n", affpath);
+ return 1;
+ }
+
+ // read in each line ignoring any that do not
+ // start with a known line type indicator
+
+ std::string line;
+ while (afflst->getline(line)) {
+ mychomp(line);
+
+ /* remove byte order mark */
+ if (firstline) {
+ firstline = 0;
+ if (line.compare(0, 3, "\xEF\xBB\xBF", 3) == 0) {
+ line.erase(0, 3);
+ }
+ }
+
+ /* parse in the try string */
+ if ((line.compare(0, 4, "FLAG", 4) == 0) && line.size() > 4 && isspace(line[4])) {
+ if (flag_mode != FLAG_CHAR) {
+ HUNSPELL_WARNING(stderr,
+ "error: line %d: multiple definitions of the FLAG "
+ "affix file parameter\n",
+ afflst->getlinenum());
+ }
+ if (line.find("long") != std::string::npos)
+ flag_mode = FLAG_LONG;
+ if (line.find("num") != std::string::npos)
+ flag_mode = FLAG_NUM;
+ if (line.find("UTF-8") != std::string::npos)
+ flag_mode = FLAG_UNI;
+ if (flag_mode == FLAG_CHAR) {
+ HUNSPELL_WARNING(
+ stderr,
+ "error: line %d: FLAG needs `num', `long' or `UTF-8' parameter\n",
+ afflst->getlinenum());
+ }
+ }
+
+ if (line.compare(0, 13, "FORBIDDENWORD", 13) == 0) {
+ std::string st;
+ if (!parse_string(line, st, afflst->getlinenum())) {
+ delete afflst;
+ return 1;
+ }
+ forbiddenword = decode_flag(st.c_str());
+ }
+
+ if (line.compare(0, 3, "SET", 3) == 0) {
+ if (!parse_string(line, enc, afflst->getlinenum())) {
+ delete afflst;
+ return 1;
+ }
+ if (enc == "UTF-8") {
+ utf8 = 1;
+#ifndef OPENOFFICEORG
+#ifndef MOZILLA_CLIENT
+ initialize_utf_tbl();
+#endif
+#endif
+ } else
+ csconv = get_current_cs(enc);
+ }
+
+ if (line.compare(0, 4, "LANG", 4) == 0) {
+ if (!parse_string(line, lang, afflst->getlinenum())) {
+ delete afflst;
+ return 1;
+ }
+ langnum = get_lang_num(lang);
+ }
+
+ /* parse in the ignored characters (for example, Arabic optional diacritics
+ * characters */
+ if (line.compare(0, 6, "IGNORE", 6) == 0) {
+ if (!parse_array(line, ignorechars, ignorechars_utf16,
+ utf8, afflst->getlinenum())) {
+ delete afflst;
+ return 1;
+ }
+ }
+
+ if ((line.compare(0, 2, "AF", 2) == 0) && line.size() > 2 && isspace(line[2])) {
+ if (!parse_aliasf(line, afflst)) {
+ delete afflst;
+ return 1;
+ }
+ }
+
+ if ((line.compare(0, 2, "AM", 2) == 0) && line.size() > 2 && isspace(line[2])) {
+ if (!parse_aliasm(line, afflst)) {
+ delete afflst;
+ return 1;
+ }
+ }
+
+ if (line.compare(0, 15, "COMPLEXPREFIXES", 15) == 0)
+ complexprefixes = 1;
+
+ /* parse in the typical fault correcting table */
+ if (line.compare(0, 3, "REP", 3) == 0) {
+ if (!parse_reptable(line, afflst)) {
+ delete afflst;
+ return 1;
+ }
+ }
+
+ // don't check the full affix file, yet
+ if (((line.compare(0, 3, "SFX", 3) == 0) ||
+ (line.compare(0, 3, "PFX", 3) == 0)) &&
+ line.size() > 3 && isspace(line[3]) &&
+ !reptable.empty()) // (REP table is in the end of Afrikaans aff file)
+ break;
+ }
+
+ if (csconv == NULL)
+ csconv = get_current_cs(SPELL_ENCODING);
+ delete afflst;
+ return 0;
+}
+
+/* parse in the ALIAS table */
+bool HashMgr::parse_aliasf(const std::string& line, FileMgr* af) {
+ if (numaliasf != 0) {
+ HUNSPELL_WARNING(stderr, "error: line %d: multiple table definitions\n",
+ af->getlinenum());
+ return false;
+ }
+ int i = 0;
+ int np = 0;
+ std::string::const_iterator iter = line.begin();
+ std::string::const_iterator start_piece = mystrsep(line, iter);
+ while (start_piece != line.end()) {
+ switch (i) {
+ case 0: {
+ np++;
+ break;
+ }
+ case 1: {
+ numaliasf = atoi(std::string(start_piece, iter).c_str());
+ if (numaliasf < 1) {
+ numaliasf = 0;
+ aliasf = NULL;
+ aliasflen = NULL;
+ HUNSPELL_WARNING(stderr, "error: line %d: bad entry number\n",
+ af->getlinenum());
+ return false;
+ }
+ aliasf =
+ (unsigned short**)arena_alloc(numaliasf * sizeof(unsigned short*));
+ aliasflen =
+ (unsigned short*)arena_alloc(numaliasf * sizeof(unsigned short));
+ if (!aliasf || !aliasflen) {
+ numaliasf = 0;
+ if (aliasf)
+ arena_free(aliasf);
+ if (aliasflen)
+ arena_free(aliasflen);
+ aliasf = NULL;
+ aliasflen = NULL;
+ return false;
+ }
+ np++;
+ break;
+ }
+ default:
+ break;
+ }
+ ++i;
+ start_piece = mystrsep(line, iter);
+ }
+ if (np != 2) {
+ numaliasf = 0;
+ arena_free(aliasf);
+ arena_free(aliasflen);
+ aliasf = NULL;
+ aliasflen = NULL;
+ HUNSPELL_WARNING(stderr, "error: line %d: missing data\n",
+ af->getlinenum());
+ return false;
+ }
+
+ /* now parse the numaliasf lines to read in the remainder of the table */
+ for (int j = 0; j < numaliasf; j++) {
+ std::string nl;
+ aliasf[j] = NULL;
+ aliasflen[j] = 0;
+ i = 0;
+ if (af->getline(nl)) {
+ mychomp(nl);
+ iter = nl.begin();
+ start_piece = mystrsep(nl, iter);
+ bool errored = false;
+ while (!errored && start_piece != nl.end()) {
+ switch (i) {
+ case 0: {
+ if (nl.compare(start_piece - nl.begin(), 2, "AF", 2) != 0) {
+ errored = true;
+ break;
+ }
+ break;
+ }
+ case 1: {
+ std::string piece(start_piece, iter);
+ aliasflen[j] =
+ (unsigned short)decode_flags(&(aliasf[j]), piece, af, /* arena = */ true);
+ std::sort(aliasf[j], aliasf[j] + aliasflen[j]);
+ break;
+ }
+ default:
+ break;
+ }
+ ++i;
+ start_piece = mystrsep(nl, iter);
+ }
+ }
+ if (!aliasf[j]) {
+ for (int k = 0; k < j; ++k) {
+ arena_free(aliasf[k]);
+ }
+ arena_free(aliasf);
+ arena_free(aliasflen);
+ aliasf = NULL;
+ aliasflen = NULL;
+ numaliasf = 0;
+ HUNSPELL_WARNING(stderr, "error: line %d: table is corrupt\n",
+ af->getlinenum());
+ return false;
+ }
+ }
+ return true;
+}
+
+int HashMgr::is_aliasf() const {
+ return (aliasf != NULL);
+}
+
+int HashMgr::get_aliasf(int index, unsigned short** fvec, FileMgr* af) const {
+ if ((index > 0) && (index <= numaliasf)) {
+ *fvec = aliasf[index - 1];
+ return aliasflen[index - 1];
+ }
+ HUNSPELL_WARNING(stderr, "error: line %d: bad flag alias index: %d\n",
+ af->getlinenum(), index);
+ *fvec = NULL;
+ return 0;
+}
+
+/* parse morph alias definitions */
+bool HashMgr::parse_aliasm(const std::string& line, FileMgr* af) {
+ if (numaliasm != 0) {
+ HUNSPELL_WARNING(stderr, "error: line %d: multiple table definitions\n",
+ af->getlinenum());
+ return false;
+ }
+ int i = 0;
+ int np = 0;
+ std::string::const_iterator iter = line.begin();
+ std::string::const_iterator start_piece = mystrsep(line, iter);
+ while (start_piece != line.end()) {
+ switch (i) {
+ case 0: {
+ np++;
+ break;
+ }
+ case 1: {
+ numaliasm = atoi(std::string(start_piece, iter).c_str());
+ if (numaliasm < 1) {
+ HUNSPELL_WARNING(stderr, "error: line %d: bad entry number\n",
+ af->getlinenum());
+ return false;
+ }
+ aliasm = (char**)arena_alloc(numaliasm * sizeof(char*));
+ if (!aliasm) {
+ numaliasm = 0;
+ return false;
+ }
+ np++;
+ break;
+ }
+ default:
+ break;
+ }
+ ++i;
+ start_piece = mystrsep(line, iter);
+ }
+ if (np != 2) {
+ numaliasm = 0;
+ arena_free(aliasm);
+ aliasm = NULL;
+ HUNSPELL_WARNING(stderr, "error: line %d: missing data\n",
+ af->getlinenum());
+ return false;
+ }
+
+ /* now parse the numaliasm lines to read in the remainder of the table */
+ for (int j = 0; j < numaliasm; j++) {
+ std::string nl;
+ aliasm[j] = NULL;
+ if (af->getline(nl)) {
+ mychomp(nl);
+ iter = nl.begin();
+ i = 0;
+ start_piece = mystrsep(nl, iter);
+ bool errored = false;
+ while (!errored && start_piece != nl.end()) {
+ switch (i) {
+ case 0: {
+ if (nl.compare(start_piece - nl.begin(), 2, "AM", 2) != 0) {
+ errored = true;
+ break;
+ }
+ break;
+ }
+ case 1: {
+ // add the remaining of the line
+ std::string::const_iterator end = nl.end();
+ std::string chunk(start_piece, end);
+ if (complexprefixes) {
+ if (utf8)
+ reverseword_utf(chunk);
+ else
+ reverseword(chunk);
+ }
+ size_t sl = chunk.length() + 1;
+ aliasm[j] = (char*)arena_alloc(sl);
+ if (aliasm[j]) {
+ memcpy(aliasm[j], chunk.c_str(), sl);
+ }
+ break;
+ }
+ default:
+ break;
+ }
+ ++i;
+ start_piece = mystrsep(nl, iter);
+ }
+ }
+ if (!aliasm[j]) {
+ numaliasm = 0;
+ for (int k = 0; k < j; ++k) {
+ arena_free(aliasm[k]);
+ }
+ arena_free(aliasm);
+ aliasm = NULL;
+ HUNSPELL_WARNING(stderr, "error: line %d: table is corrupt\n",
+ af->getlinenum());
+ return false;
+ }
+ }
+ return true;
+}
+
+int HashMgr::is_aliasm() const {
+ return (aliasm != NULL);
+}
+
+char* HashMgr::get_aliasm(int index) const {
+ if ((index > 0) && (index <= numaliasm))
+ return aliasm[index - 1];
+ HUNSPELL_WARNING(stderr, "error: bad morph. alias index: %d\n", index);
+ return NULL;
+}
+
+/* parse in the typical fault correcting table */
+bool HashMgr::parse_reptable(const std::string& line, FileMgr* af) {
+ if (!reptable.empty()) {
+ HUNSPELL_WARNING(stderr, "error: line %d: multiple table definitions\n",
+ af->getlinenum());
+ return false;
+ }
+ int numrep = -1;
+ int i = 0;
+ int np = 0;
+ std::string::const_iterator iter = line.begin();
+ std::string::const_iterator start_piece = mystrsep(line, iter);
+ while (start_piece != line.end()) {
+ switch (i) {
+ case 0: {
+ np++;
+ break;
+ }
+ case 1: {
+ numrep = atoi(std::string(start_piece, iter).c_str());
+ if (numrep < 1) {
+ HUNSPELL_WARNING(stderr, "error: line %d: incorrect entry number\n",
+ af->getlinenum());
+ return false;
+ }
+ reptable.reserve(numrep);
+ np++;
+ break;
+ }
+ default:
+ break;
+ }
+ ++i;
+ start_piece = mystrsep(line, iter);
+ }
+ if (np != 2) {
+ HUNSPELL_WARNING(stderr, "error: line %d: missing data\n",
+ af->getlinenum());
+ return false;
+ }
+
+ /* now parse the numrep lines to read in the remainder of the table */
+ for (int j = 0; j < numrep; ++j) {
+ std::string nl;
+ reptable.push_back(replentry());
+ int type = 0;
+ if (af->getline(nl)) {
+ mychomp(nl);
+ iter = nl.begin();
+ i = 0;
+ start_piece = mystrsep(nl, iter);
+ bool errored = false;
+ while (!errored && start_piece != nl.end()) {
+ switch (i) {
+ case 0: {
+ if (nl.compare(start_piece - nl.begin(), 3, "REP", 3) != 0) {
+ errored = true;
+ break;
+ }
+ break;
+ }
+ case 1: {
+ if (*start_piece == '^')
+ type = 1;
+ reptable.back().pattern.assign(start_piece + type, iter);
+ mystrrep(reptable.back().pattern, "_", " ");
+ if (!reptable.back().pattern.empty() && reptable.back().pattern[reptable.back().pattern.size() - 1] == '$') {
+ type += 2;
+ reptable.back().pattern.resize(reptable.back().pattern.size() - 1);
+ }
+ break;
+ }
+ case 2: {
+ reptable.back().outstrings[type].assign(start_piece, iter);
+ mystrrep(reptable.back().outstrings[type], "_", " ");
+ break;
+ }
+ default:
+ break;
+ }
+ ++i;
+ start_piece = mystrsep(nl, iter);
+ }
+ }
+ if (reptable.back().pattern.empty() || reptable.back().outstrings[type].empty()) {
+ HUNSPELL_WARNING(stderr, "error: line %d: table is corrupt\n",
+ af->getlinenum());
+ reptable.clear();
+ return false;
+ }
+ }
+ return true;
+}
+
+// return replacing table
+const std::vector<replentry>& HashMgr::get_reptable() const {
+ return reptable;
+}
+
+void* HashMgr::arena_alloc(int num_bytes) {
+ static const int MIN_CHUNK_SIZE = 4096;
+ if (arena.empty() || (current_chunk_size - current_chunk_offset < num_bytes)) {
+ current_chunk_size = std::max(MIN_CHUNK_SIZE, num_bytes);
+ arena.push_back(std::make_unique<uint8_t[]>(current_chunk_size));
+ current_chunk_offset = 0;
+ }
+
+ uint8_t* ptr = &arena.back()[current_chunk_offset];
+ current_chunk_offset += num_bytes;
+ outstanding_arena_allocations++;
+ return ptr;
+}
+
+void HashMgr::arena_free(void* ptr) {
+ --outstanding_arena_allocations;
+ assert(outstanding_arena_allocations >= 0);
+}
diff --git a/extensions/spellcheck/hunspell/src/hashmgr.hxx b/extensions/spellcheck/hunspell/src/hashmgr.hxx
new file mode 100644
index 0000000000..f367a1c4a6
--- /dev/null
+++ b/extensions/spellcheck/hunspell/src/hashmgr.hxx
@@ -0,0 +1,182 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * Copyright (C) 2002-2022 N辿meth L叩szl坦
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (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.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * Hunspell is based on MySpell which is Copyright (C) 2002 Kevin Hendricks.
+ *
+ * Contributor(s): David Einstein, Davide Prina, Giuseppe Modugno,
+ * Gianluca Turconi, Simon Brouwer, Noll J叩nos, B鱈r坦 rp叩d,
+ * Goldman Eleon坦ra, Sarl坦s Tam叩s, Bencs叩th Boldizs叩r, Hal叩csy P辿ter,
+ * Dvornik L叩szl坦, Gefferth Andr叩s, Nagy Viktor, Varga D叩niel, Chris Halls,
+ * Rene Engelhard, Bram Moolenaar, Dafydd Jones, Harri Pitk辰nen
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+/*
+ * Copyright 2002 Kevin B. Hendricks, Stratford, Ontario, Canada
+ * And Contributors. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. All modifications to the source code must be clearly marked as
+ * such. Binary redistributions based on modified source code
+ * must be clearly marked as modified versions in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY KEVIN B. HENDRICKS AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
+ * KEVIN B. HENDRICKS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef HASHMGR_HXX_
+#define HASHMGR_HXX_
+
+#include <stdio.h>
+#include <stdint.h>
+#include <memory>
+#include <string>
+#include <vector>
+
+#include "htypes.hxx"
+#include "filemgr.hxx"
+#include "w_char.hxx"
+
+enum flag { FLAG_CHAR, FLAG_LONG, FLAG_NUM, FLAG_UNI };
+
+// morphological description of a dictionary item can contain
+// arbitrary number "ph:" (MORPH_PHON) fields to store typical
+// phonetic or other misspellings of that word.
+// ratio of lines/lines with "ph:" in the dic file: 1/MORPH_PHON_RATIO
+#define MORPH_PHON_RATIO 500
+
+class HashMgr {
+ int tablesize;
+ struct hentry** tableptr;
+ flag flag_mode;
+ int complexprefixes;
+ int utf8;
+ unsigned short forbiddenword;
+ int langnum;
+ std::string enc;
+ std::string lang;
+ struct cs_info* csconv;
+ std::string ignorechars;
+ std::vector<w_char> ignorechars_utf16;
+ int numaliasf; // flag vector `compression' with aliases
+ unsigned short** aliasf;
+ unsigned short* aliasflen;
+ int numaliasm; // morphological desciption `compression' with aliases
+ char** aliasm;
+ // reptable created from REP table of aff file and from "ph:" fields
+ // of the dic file. It contains phonetic and other common misspellings
+ // (letters, letter groups and words) for better suggestions
+ std::vector<replentry> reptable;
+
+ public:
+ HashMgr(const char* tpath, const char* apath, const char* key = NULL);
+ ~HashMgr();
+
+ struct hentry* lookup(const char*) const;
+ int hash(const char*) const;
+ struct hentry* walk_hashtable(int& col, struct hentry* hp) const;
+
+ int add(const std::string& word);
+ int add_with_affix(const std::string& word, const std::string& pattern);
+ int remove(const std::string& word);
+private:
+ // Only internal consumers are allowed to arena-allocate.
+ int decode_flags(unsigned short** result, const std::string& flags, FileMgr* af, bool arena) const;
+public:
+ int decode_flags(unsigned short** result, const std::string& flags, FileMgr* af) const {
+ return decode_flags(result, flags, af, /* arena = */ false);
+ }
+ bool decode_flags(std::vector<unsigned short>& result, const std::string& flags, FileMgr* af) const;
+ unsigned short decode_flag(const char* flag) const;
+ char* encode_flag(unsigned short flag) const;
+ int is_aliasf() const;
+ int get_aliasf(int index, unsigned short** fvec, FileMgr* af) const;
+ int is_aliasm() const;
+ char* get_aliasm(int index) const;
+ const std::vector<replentry>& get_reptable() const;
+
+ private:
+ int get_clen_and_captype(const std::string& word, int* captype);
+ int get_clen_and_captype(const std::string& word, int* captype, std::vector<w_char> &workbuf);
+ int load_tables(const char* tpath, const char* key);
+ int add_word(const std::string& word,
+ int wcl,
+ unsigned short* ap,
+ int al,
+ const std::string* desc,
+ bool onlyupcase,
+ int captype);
+ int load_config(const char* affpath, const char* key);
+ bool parse_aliasf(const std::string& line, FileMgr* af);
+ int add_hidden_capitalized_word(const std::string& word,
+ int wcl,
+ unsigned short* flags,
+ int al,
+ const std::string* dp,
+ int captype);
+ bool parse_aliasm(const std::string& line, FileMgr* af);
+ bool parse_reptable(const std::string& line, FileMgr* af);
+ int remove_forbidden_flag(const std::string& word);
+
+ // Our Mozilla fork uses a simple arena allocator for certain strings which
+ // persist for the lifetime of the HashMgr in order to avoid heap fragmentation.
+ // It's a simple bump-allocator, so we can't actually free() memory midway
+ // through the lifecycle, but we have a dummy free() implementation to ensure
+ // that our calls to arena_alloc() and arena_free() are balanced.
+ void* arena_alloc(int num_bytes);
+ void* arena_alloc(int num_bytes) const {
+ return const_cast<HashMgr*>(this)->arena_alloc(num_bytes);
+ }
+ void arena_free(void* ptr);
+
+ std::vector<std::unique_ptr<uint8_t[]>> arena;
+ int current_chunk_size = 0;
+ int current_chunk_offset = 0;
+ int outstanding_arena_allocations = 0;
+};
+
+#endif
diff --git a/extensions/spellcheck/hunspell/src/htypes.hxx b/extensions/spellcheck/hunspell/src/htypes.hxx
new file mode 100644
index 0000000000..44366b1d68
--- /dev/null
+++ b/extensions/spellcheck/hunspell/src/htypes.hxx
@@ -0,0 +1,75 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * Copyright (C) 2002-2022 N辿meth L叩szl坦
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (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.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * Hunspell is based on MySpell which is Copyright (C) 2002 Kevin Hendricks.
+ *
+ * Contributor(s): David Einstein, Davide Prina, Giuseppe Modugno,
+ * Gianluca Turconi, Simon Brouwer, Noll J叩nos, B鱈r坦 rp叩d,
+ * Goldman Eleon坦ra, Sarl坦s Tam叩s, Bencs叩th Boldizs叩r, Hal叩csy P辿ter,
+ * Dvornik L叩szl坦, Gefferth Andr叩s, Nagy Viktor, Varga D叩niel, Chris Halls,
+ * Rene Engelhard, Bram Moolenaar, Dafydd Jones, Harri Pitk辰nen
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#ifndef HTYPES_HXX_
+#define HTYPES_HXX_
+
+#define ROTATE_LEN 5
+
+#define ROTATE(v, q) \
+ (v) = ((v) << (q)) | (((v) >> (32 - q)) & ((1 << (q)) - 1));
+
+// hentry options
+#define H_OPT (1 << 0) // is there optional morphological data?
+#define H_OPT_ALIASM (1 << 1) // using alias compression?
+#define H_OPT_PHON (1 << 2) // is there ph: field in the morphological data?
+#define H_OPT_INITCAP (1 << 3) // is dictionary word capitalized?
+
+// see also csutil.hxx
+#define HENTRY_WORD(h) &(h->word[0])
+
+// approx. number of user defined words
+#define USERWORD 1000
+
+#if __cplusplus >= 201103L || (defined(_MSC_VER) && _MSC_VER >= 1900)
+# define HUNSPELL_THREAD_LOCAL thread_local
+#else
+# define HUNSPELL_THREAD_LOCAL static
+#endif
+
+struct hentry {
+ unsigned char blen; // word length in bytes
+ unsigned char clen; // word length in characters (different for UTF-8 enc.)
+ short alen; // length of affix flag vector
+ unsigned short* astr; // affix flag vector
+ struct hentry* next; // next word with same hash code
+ struct hentry* next_homonym; // next homonym word (with same hash code)
+ char var; // bit vector of H_OPT hentry options
+ char word[1]; // variable-length word (8-bit or UTF-8 encoding)
+};
+
+#endif
diff --git a/extensions/spellcheck/hunspell/src/hunspell.cxx b/extensions/spellcheck/hunspell/src/hunspell.cxx
new file mode 100644
index 0000000000..4afafdadc1
--- /dev/null
+++ b/extensions/spellcheck/hunspell/src/hunspell.cxx
@@ -0,0 +1,2249 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * Copyright (C) 2002-2022 N辿meth L叩szl坦
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (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.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * Hunspell is based on MySpell which is Copyright (C) 2002 Kevin Hendricks.
+ *
+ * Contributor(s): David Einstein, Davide Prina, Giuseppe Modugno,
+ * Gianluca Turconi, Simon Brouwer, Noll J叩nos, B鱈r坦 rp叩d,
+ * Goldman Eleon坦ra, Sarl坦s Tam叩s, Bencs叩th Boldizs叩r, Hal叩csy P辿ter,
+ * Dvornik L叩szl坦, Gefferth Andr叩s, Nagy Viktor, Varga D叩niel, Chris Halls,
+ * Rene Engelhard, Bram Moolenaar, Dafydd Jones, Harri Pitk辰nen
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+/*
+ * Copyright 2002 Kevin B. Hendricks, Stratford, Ontario, Canada
+ * And Contributors. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. All modifications to the source code must be clearly marked as
+ * such. Binary redistributions based on modified source code
+ * must be clearly marked as modified versions in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY KEVIN B. HENDRICKS AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
+ * KEVIN B. HENDRICKS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+#include <time.h>
+
+#include "affixmgr.hxx"
+#include "hunspell.hxx"
+#include "suggestmgr.hxx"
+#include "hunspell.h"
+#include "csutil.hxx"
+
+#include <limits>
+#include <string>
+
+#define MAXWORDUTF8LEN (MAXWORDLEN * 3)
+
+class HunspellImpl
+{
+public:
+ HunspellImpl(const char* affpath, const char* dpath, const char* key = NULL);
+ ~HunspellImpl();
+ int add_dic(const char* dpath, const char* key = NULL);
+ std::vector<std::string> suffix_suggest(const std::string& root_word);
+ std::vector<std::string> generate(const std::string& word, const std::vector<std::string>& pl);
+ std::vector<std::string> generate(const std::string& word, const std::string& pattern);
+ std::vector<std::string> stem(const std::string& word);
+ std::vector<std::string> stem(const std::vector<std::string>& morph);
+ std::vector<std::string> analyze(const std::string& word);
+ int get_langnum() const;
+ bool input_conv(const std::string& word, std::string& dest);
+ bool spell(const std::string& word, int* info = NULL, std::string* root = NULL);
+ std::vector<std::string> suggest(const std::string& word);
+ const std::string& get_wordchars_cpp() const;
+ const std::vector<w_char>& get_wordchars_utf16() const;
+ const std::string& get_dict_encoding() const;
+ int add(const std::string& word);
+ int add_with_affix(const std::string& word, const std::string& example);
+ int remove(const std::string& word);
+ const std::string& get_version_cpp() const;
+ struct cs_info* get_csconv();
+
+ int spell(const char* word, int* info = NULL, char** root = NULL);
+ int suggest(char*** slst, const char* word);
+ int suffix_suggest(char*** slst, const char* root_word);
+ void free_list(char*** slst, int n);
+ char* get_dic_encoding();
+ int analyze(char*** slst, const char* word);
+ int stem(char*** slst, const char* word);
+ int stem(char*** slst, char** morph, int n);
+ int generate(char*** slst, const char* word, const char* word2);
+ int generate(char*** slst, const char* word, char** desc, int n);
+ const char* get_wordchars() const;
+ const char* get_version() const;
+ int input_conv(const char* word, char* dest, size_t destsize);
+
+private:
+ AffixMgr* pAMgr;
+ std::vector<HashMgr*> m_HMgrs;
+ SuggestMgr* pSMgr;
+ char* affixpath;
+ std::string encoding;
+ struct cs_info* csconv;
+ int langnum;
+ int utf8;
+ int complexprefixes;
+ std::vector<std::string> wordbreak;
+
+private:
+ std::vector<std::string> analyze_internal(const std::string& word);
+ bool spell_internal(const std::string& word, int* info = NULL, std::string* root = NULL);
+ std::vector<std::string> suggest_internal(const std::string& word,
+ bool& capitalized, size_t& abbreviated, int& captype);
+ void cleanword(std::string& dest, const std::string&, int* pcaptype, int* pabbrev);
+ size_t cleanword2(std::string& dest,
+ std::vector<w_char>& dest_u,
+ const std::string& src,
+ int* pcaptype,
+ size_t* pabbrev);
+ void clean_ignore(std::string& dest, const std::string& src);
+ void mkinitcap(std::string& u8);
+ int mkinitcap2(std::string& u8, std::vector<w_char>& u16);
+ int mkinitsmall2(std::string& u8, std::vector<w_char>& u16);
+ void mkallcap(std::string& u8);
+ int mkallsmall2(std::string& u8, std::vector<w_char>& u16);
+ struct hentry* checkword(const std::string& source, int* info, std::string* root);
+ std::string sharps_u8_l1(const std::string& source);
+ hentry*
+ spellsharps(std::string& base, size_t start_pos, int, int, int* info, std::string* root);
+ int is_keepcase(const hentry* rv);
+ void insert_sug(std::vector<std::string>& slst, const std::string& word);
+ void cat_result(std::string& result, const std::string& st);
+ std::vector<std::string> spellml(const std::string& word);
+ std::string get_xml_par(const std::string& par, std::string::size_type pos);
+ std::string::size_type get_xml_pos(const std::string& s, std::string::size_type pos, const char* attr);
+ std::vector<std::string> get_xml_list(const std::string& list, std::string::size_type pos, const char* tag);
+ int check_xml_par(const std::string& q, std::string::size_type pos, const char* attr, const char* value);
+private:
+ HunspellImpl(const HunspellImpl&);
+ HunspellImpl& operator=(const HunspellImpl&);
+};
+
+HunspellImpl::HunspellImpl(const char* affpath, const char* dpath, const char* key) {
+ csconv = NULL;
+ utf8 = 0;
+ complexprefixes = 0;
+ affixpath = mystrdup(affpath);
+
+ /* first set up the hash manager */
+ m_HMgrs.push_back(new HashMgr(dpath, affpath, key));
+
+ /* next set up the affix manager */
+ /* it needs access to the hash manager lookup methods */
+ pAMgr = new AffixMgr(affpath, m_HMgrs, key);
+
+ /* get the preferred try string and the dictionary */
+ /* encoding from the Affix Manager for that dictionary */
+ char* try_string = pAMgr->get_try_string();
+ encoding = pAMgr->get_encoding();
+ langnum = pAMgr->get_langnum();
+ utf8 = pAMgr->get_utf8();
+ if (!utf8)
+ csconv = get_current_cs(encoding);
+ complexprefixes = pAMgr->get_complexprefixes();
+ wordbreak = pAMgr->get_breaktable();
+
+ /* and finally set up the suggestion manager */
+ pSMgr = new SuggestMgr(try_string, MAXSUGGESTION, pAMgr);
+ if (try_string)
+ free(try_string);
+}
+
+HunspellImpl::~HunspellImpl() {
+ delete pSMgr;
+ delete pAMgr;
+ for (size_t i = 0; i < m_HMgrs.size(); ++i)
+ delete m_HMgrs[i];
+ pSMgr = NULL;
+ pAMgr = NULL;
+#ifdef MOZILLA_CLIENT
+ delete[] csconv;
+#endif
+ csconv = NULL;
+ if (affixpath)
+ free(affixpath);
+ affixpath = NULL;
+}
+
+// load extra dictionaries
+int HunspellImpl::add_dic(const char* dpath, const char* key) {
+ if (!affixpath)
+ return 1;
+ m_HMgrs.push_back(new HashMgr(dpath, affixpath, key));
+ return 0;
+}
+
+
+// make a copy of src at dest while removing all characters
+// specified in IGNORE rule
+void HunspellImpl::clean_ignore(std::string& dest,
+ const std::string& src) {
+ dest.clear();
+ dest.assign(src);
+ const char* ignoredchars = pAMgr ? pAMgr->get_ignore() : NULL;
+ if (ignoredchars != NULL) {
+ if (utf8) {
+ const std::vector<w_char>& ignoredchars_utf16 =
+ pAMgr->get_ignore_utf16();
+ remove_ignored_chars_utf(dest, ignoredchars_utf16);
+ } else {
+ remove_ignored_chars(dest, ignoredchars);
+ }
+ }
+}
+
+
+// make a copy of src at destination while removing all leading
+// blanks and removing any trailing periods after recording
+// their presence with the abbreviation flag
+// also since already going through character by character,
+// set the capitalization type
+// return the length of the "cleaned" (and UTF-8 encoded) word
+
+size_t HunspellImpl::cleanword2(std::string& dest,
+ std::vector<w_char>& dest_utf,
+ const std::string& src,
+ int* pcaptype,
+ size_t* pabbrev) {
+ dest.clear();
+ dest_utf.clear();
+
+ // remove IGNORE characters from the string
+ std::string w2;
+ clean_ignore(w2, src);
+
+ const char* q = w2.c_str();
+
+ // first skip over any leading blanks
+ while (*q == ' ')
+ ++q;
+
+ // now strip off any trailing periods (recording their presence)
+ *pabbrev = 0;
+ int nl = strlen(q);
+ while ((nl > 0) && (*(q + nl - 1) == '.')) {
+ nl--;
+ (*pabbrev)++;
+ }
+
+ // if no characters are left it can't be capitalized
+ if (nl <= 0) {
+ *pcaptype = NOCAP;
+ return 0;
+ }
+
+ dest.append(q, nl);
+ nl = dest.size();
+ if (utf8) {
+ u8_u16(dest_utf, dest);
+ *pcaptype = get_captype_utf8(dest_utf, langnum);
+ } else {
+ *pcaptype = get_captype(dest, csconv);
+ }
+ return nl;
+}
+
+void HunspellImpl::cleanword(std::string& dest,
+ const std::string& src,
+ int* pcaptype,
+ int* pabbrev) {
+ dest.clear();
+ const unsigned char* q = (const unsigned char*)src.c_str();
+ int firstcap = 0;
+
+ // first skip over any leading blanks
+ while (*q == ' ')
+ ++q;
+
+ // now strip off any trailing periods (recording their presence)
+ *pabbrev = 0;
+ int nl = strlen((const char*)q);
+ while ((nl > 0) && (*(q + nl - 1) == '.')) {
+ nl--;
+ (*pabbrev)++;
+ }
+
+ // if no characters are left it can't be capitalized
+ if (nl <= 0) {
+ *pcaptype = NOCAP;
+ return;
+ }
+
+ // now determine the capitalization type of the first nl letters
+ int ncap = 0;
+ int nneutral = 0;
+ int nc = 0;
+
+ if (!utf8) {
+ while (nl > 0) {
+ nc++;
+ if (csconv[(*q)].ccase)
+ ncap++;
+ if (csconv[(*q)].cupper == csconv[(*q)].clower)
+ nneutral++;
+ dest.push_back(*q++);
+ nl--;
+ }
+ // remember to terminate the destination string
+ firstcap = csconv[static_cast<unsigned char>(dest[0])].ccase;
+ } else {
+ std::vector<w_char> t;
+ u8_u16(t, src);
+ for (size_t i = 0; i < t.size(); ++i) {
+ unsigned short idx = (t[i].h << 8) + t[i].l;
+ unsigned short low = unicodetolower(idx, langnum);
+ if (idx != low)
+ ncap++;
+ if (unicodetoupper(idx, langnum) == low)
+ nneutral++;
+ }
+ u16_u8(dest, t);
+ if (ncap) {
+ unsigned short idx = (t[0].h << 8) + t[0].l;
+ firstcap = (idx != unicodetolower(idx, langnum));
+ }
+ }
+
+ // now finally set the captype
+ if (ncap == 0) {
+ *pcaptype = NOCAP;
+ } else if ((ncap == 1) && firstcap) {
+ *pcaptype = INITCAP;
+ } else if ((ncap == nc) || ((ncap + nneutral) == nc)) {
+ *pcaptype = ALLCAP;
+ } else if ((ncap > 1) && firstcap) {
+ *pcaptype = HUHINITCAP;
+ } else {
+ *pcaptype = HUHCAP;
+ }
+}
+
+void HunspellImpl::mkallcap(std::string& u8) {
+ if (utf8) {
+ std::vector<w_char> u16;
+ u8_u16(u16, u8);
+ ::mkallcap_utf(u16, langnum);
+ u16_u8(u8, u16);
+ } else {
+ ::mkallcap(u8, csconv);
+ }
+}
+
+int HunspellImpl::mkallsmall2(std::string& u8, std::vector<w_char>& u16) {
+ if (utf8) {
+ ::mkallsmall_utf(u16, langnum);
+ u16_u8(u8, u16);
+ } else {
+ ::mkallsmall(u8, csconv);
+ }
+ return u8.size();
+}
+
+// convert UTF-8 sharp S codes to latin 1
+std::string HunspellImpl::sharps_u8_l1(const std::string& source) {
+ std::string dest(source);
+ mystrrep(dest, "\xC3\x9F", "\xDF");
+ return dest;
+}
+
+// recursive search for right ss - sharp s permutations
+hentry* HunspellImpl::spellsharps(std::string& base,
+ size_t n_pos,
+ int n,
+ int repnum,
+ int* info,
+ std::string* root) {
+ size_t pos = base.find("ss", n_pos);
+ if (pos != std::string::npos && (n < MAXSHARPS)) {
+ base[pos] = '\xC3';
+ base[pos + 1] = '\x9F';
+ hentry* h = spellsharps(base, pos + 2, n + 1, repnum + 1, info, root);
+ if (h)
+ return h;
+ base[pos] = 's';
+ base[pos + 1] = 's';
+ h = spellsharps(base, pos + 2, n + 1, repnum, info, root);
+ if (h)
+ return h;
+ } else if (repnum > 0) {
+ if (utf8)
+ return checkword(base, info, root);
+ std::string tmp(sharps_u8_l1(base));
+ return checkword(tmp, info, root);
+ }
+ return NULL;
+}
+
+int HunspellImpl::is_keepcase(const hentry* rv) {
+ return pAMgr && rv->astr && pAMgr->get_keepcase() &&
+ TESTAFF(rv->astr, pAMgr->get_keepcase(), rv->alen);
+}
+
+/* insert a word to the beginning of the suggestion array */
+void HunspellImpl::insert_sug(std::vector<std::string>& slst, const std::string& word) {
+ slst.insert(slst.begin(), word);
+}
+
+bool HunspellImpl::spell(const std::string& word, int* info, std::string* root) {
+ bool r = spell_internal(word, info, root);
+ if (r && root) {
+ // output conversion
+ RepList* rl = (pAMgr) ? pAMgr->get_oconvtable() : NULL;
+ if (rl) {
+ std::string wspace;
+ if (rl->conv(*root, wspace)) {
+ *root = wspace;
+ }
+ }
+ }
+ return r;
+}
+
+bool HunspellImpl::spell_internal(const std::string& word, int* info, std::string* root) {
+ struct hentry* rv = NULL;
+
+ int info2 = 0;
+ if (!info)
+ info = &info2;
+ else
+ *info = 0;
+
+ // Hunspell supports XML input of the simplified API (see manual)
+ if (word == SPELL_XML)
+ return true;
+ if (utf8) {
+ if (word.size() >= MAXWORDUTF8LEN)
+ return false;
+ } else {
+ if (word.size() >= MAXWORDLEN)
+ return false;
+ }
+ int captype = NOCAP;
+ size_t abbv = 0;
+ size_t wl = 0;
+
+ std::string scw;
+ std::vector<w_char> sunicw;
+
+ // input conversion
+ RepList* rl = pAMgr ? pAMgr->get_iconvtable() : NULL;
+ {
+ std::string wspace;
+
+ bool convstatus = rl ? rl->conv(word, wspace) : false;
+ if (convstatus)
+ wl = cleanword2(scw, sunicw, wspace, &captype, &abbv);
+ else
+ wl = cleanword2(scw, sunicw, word, &captype, &abbv);
+ }
+
+#ifdef MOZILLA_CLIENT
+ // accept the abbreviated words without dots
+ // workaround for the incomplete tokenization of Mozilla
+ abbv = 1;
+#endif
+
+ if (wl == 0 || m_HMgrs.empty())
+ return true;
+ if (root)
+ root->clear();
+
+ // allow numbers with dots, dashes and commas (but forbid double separators:
+ // "..", "--" etc.)
+ enum { NBEGIN, NNUM, NSEP };
+ int nstate = NBEGIN;
+ size_t i;
+
+ for (i = 0; (i < wl); i++) {
+ if ((scw[i] <= '9') && (scw[i] >= '0')) {
+ nstate = NNUM;
+ } else if ((scw[i] == ',') || (scw[i] == '.') || (scw[i] == '-')) {
+ if ((nstate == NSEP) || (i == 0))
+ break;
+ nstate = NSEP;
+ } else
+ break;
+ }
+ if ((i == wl) && (nstate == NNUM))
+ return true;
+
+ switch (captype) {
+ case HUHCAP:
+ /* FALLTHROUGH */
+ case HUHINITCAP:
+ *info |= SPELL_ORIGCAP;
+ /* FALLTHROUGH */
+ case NOCAP:
+ rv = checkword(scw, info, root);
+ if ((abbv) && !(rv)) {
+ std::string u8buffer(scw);
+ u8buffer.push_back('.');
+ rv = checkword(u8buffer, info, root);
+ }
+ break;
+ case ALLCAP: {
+ *info |= SPELL_ORIGCAP;
+ rv = checkword(scw, info, root);
+ if (rv)
+ break;
+ if (abbv) {
+ std::string u8buffer(scw);
+ u8buffer.push_back('.');
+ rv = checkword(u8buffer, info, root);
+ if (rv)
+ break;
+ }
+ // Spec. prefix handling for Catalan, French, Italian:
+ // prefixes separated by apostrophe (SANT'ELIA -> Sant'+Elia).
+ size_t apos = pAMgr ? scw.find('\'') : std::string::npos;
+ if (apos != std::string::npos) {
+ mkallsmall2(scw, sunicw);
+ //conversion may result in string with different len to pre-mkallsmall2
+ //so re-scan
+ if (apos != std::string::npos && apos < scw.size() - 1) {
+ std::string part1 = scw.substr(0, apos+1);
+ std::string part2 = scw.substr(apos+1);
+ if (utf8) {
+ std::vector<w_char> part1u, part2u;
+ u8_u16(part1u, part1);
+ u8_u16(part2u, part2);
+ mkinitcap2(part2, part2u);
+ scw = part1 + part2;
+ sunicw = part1u;
+ sunicw.insert(sunicw.end(), part2u.begin(), part2u.end());
+ rv = checkword(scw, info, root);
+ if (rv)
+ break;
+ } else {
+ mkinitcap2(part2, sunicw);
+ scw = part1 + part2;
+ rv = checkword(scw, info, root);
+ if (rv)
+ break;
+ }
+ mkinitcap2(scw, sunicw);
+ rv = checkword(scw, info, root);
+ if (rv)
+ break;
+ }
+ }
+ if (pAMgr && pAMgr->get_checksharps() && scw.find("SS") != std::string::npos) {
+
+ mkallsmall2(scw, sunicw);
+ std::string u8buffer(scw);
+ rv = spellsharps(u8buffer, 0, 0, 0, info, root);
+ if (!rv) {
+ mkinitcap2(scw, sunicw);
+ rv = spellsharps(scw, 0, 0, 0, info, root);
+ }
+ if ((abbv) && !(rv)) {
+ u8buffer.push_back('.');
+ rv = spellsharps(u8buffer, 0, 0, 0, info, root);
+ if (!rv) {
+ u8buffer = std::string(scw);
+ u8buffer.push_back('.');
+ rv = spellsharps(u8buffer, 0, 0, 0, info, root);
+ }
+ }
+ if (rv)
+ break;
+ }
+ }
+ /* FALLTHROUGH */
+ case INITCAP: {
+ // handle special capitalization of dotted I
+ bool Idot = (utf8 && (unsigned char) scw[0] == 0xc4 && (unsigned char) scw[1] == 0xb0);
+ *info |= SPELL_ORIGCAP;
+ if (captype == ALLCAP) {
+ mkallsmall2(scw, sunicw);
+ mkinitcap2(scw, sunicw);
+ if (Idot)
+ scw.replace(0, 1, "\xc4\xb0");
+ }
+ if (captype == INITCAP)
+ *info |= SPELL_INITCAP;
+ rv = checkword(scw, info, root);
+ if (captype == INITCAP)
+ *info &= ~SPELL_INITCAP;
+ // forbid bad capitalization
+ // (for example, ijs -> Ijs instead of IJs in Dutch)
+ // use explicit forms in dic: Ijs/F (F = FORBIDDENWORD flag)
+ if (*info & SPELL_FORBIDDEN) {
+ rv = NULL;
+ break;
+ }
+ if (rv && is_keepcase(rv) && (captype == ALLCAP))
+ rv = NULL;
+ if (rv || (Idot && langnum != LANG_az && langnum != LANG_tr && langnum != LANG_crh))
+ break;
+
+ mkallsmall2(scw, sunicw);
+ std::string u8buffer(scw);
+ mkinitcap2(scw, sunicw);
+
+ rv = checkword(u8buffer, info, root);
+ if (abbv && !rv) {
+ u8buffer.push_back('.');
+ rv = checkword(u8buffer, info, root);
+ if (!rv) {
+ u8buffer = scw;
+ u8buffer.push_back('.');
+ if (captype == INITCAP)
+ *info |= SPELL_INITCAP;
+ rv = checkword(u8buffer, info, root);
+ if (captype == INITCAP)
+ *info &= ~SPELL_INITCAP;
+ if (rv && is_keepcase(rv) && (captype == ALLCAP))
+ rv = NULL;
+ break;
+ }
+ }
+ if (rv && is_keepcase(rv) &&
+ ((captype == ALLCAP) ||
+ // if CHECKSHARPS: KEEPCASE words with \xDF are allowed
+ // in INITCAP form, too.
+ !(pAMgr->get_checksharps() &&
+ ((utf8 && u8buffer.find("\xC3\x9F") != std::string::npos) ||
+ (!utf8 && u8buffer.find('\xDF') != std::string::npos)))))
+ rv = NULL;
+ break;
+ }
+ }
+
+ if (rv) {
+ if (pAMgr && pAMgr->get_warn() && rv->astr &&
+ TESTAFF(rv->astr, pAMgr->get_warn(), rv->alen)) {
+ *info |= SPELL_WARN;
+ if (pAMgr->get_forbidwarn())
+ return false;
+ return true;
+ }
+ return true;
+ }
+
+ // recursive breaking at break points
+ if (!wordbreak.empty() && !(*info & SPELL_FORBIDDEN)) {
+
+ int nbr = 0;
+ wl = scw.size();
+
+ // calculate break points for recursion limit
+ for (size_t j = 0; j < wordbreak.size(); ++j) {
+ size_t pos = 0;
+ while ((pos = scw.find(wordbreak[j], pos)) != std::string::npos) {
+ ++nbr;
+ pos += wordbreak[j].size();
+ }
+ }
+ if (nbr >= 10)
+ return false;
+
+ // check boundary patterns (^begin and end$)
+ for (size_t j = 0; j < wordbreak.size(); ++j) {
+ size_t plen = wordbreak[j].size();
+ if (plen == 1 || plen > wl)
+ continue;
+
+ if (wordbreak[j][0] == '^' &&
+ scw.compare(0, plen - 1, wordbreak[j], 1, plen -1) == 0 && spell(scw.substr(plen - 1)))
+ return true;
+
+ if (wordbreak[j][plen - 1] == '$' &&
+ scw.compare(wl - plen + 1, plen - 1, wordbreak[j], 0, plen - 1) == 0) {
+ std::string suffix(scw.substr(wl - plen + 1));
+ scw.resize(wl - plen + 1);
+ if (spell(scw))
+ return true;
+ scw.append(suffix);
+ }
+ }
+
+ // other patterns
+ for (size_t j = 0; j < wordbreak.size(); ++j) {
+ size_t plen = wordbreak[j].size();
+ size_t found = scw.find(wordbreak[j]);
+ if ((found > 0) && (found < wl - plen)) {
+ size_t found2 = scw.find(wordbreak[j], found + 1);
+ // try to break at the second occurance
+ // to recognize dictionary words with wordbreak
+ if (found2 > 0 && (found2 < wl - plen))
+ found = found2;
+ if (!spell(scw.substr(found + plen)))
+ continue;
+ std::string suffix(scw.substr(found));
+ scw.resize(found);
+ // examine 2 sides of the break point
+ if (spell(scw))
+ return true;
+ scw.append(suffix);
+
+ // LANG_hu: spec. dash rule
+ if (langnum == LANG_hu && wordbreak[j] == "-") {
+ suffix = scw.substr(found + 1);
+ scw.resize(found + 1);
+ if (spell(scw))
+ return true; // check the first part with dash
+ scw.append(suffix);
+ }
+ // end of LANG specific region
+ }
+ }
+
+ // other patterns (break at first break point)
+ for (size_t j = 0; j < wordbreak.size(); ++j) {
+ size_t plen = wordbreak[j].size();
+ size_t found = scw.find(wordbreak[j]);
+ if ((found > 0) && (found < wl - plen)) {
+ if (!spell(scw.substr(found + plen)))
+ continue;
+ std::string suffix(scw.substr(found));
+ scw.resize(found);
+ // examine 2 sides of the break point
+ if (spell(scw))
+ return true;
+ scw.append(suffix);
+
+ // LANG_hu: spec. dash rule
+ if (langnum == LANG_hu && wordbreak[j] == "-") {
+ suffix = scw.substr(found + 1);
+ scw.resize(found + 1);
+ if (spell(scw))
+ return true; // check the first part with dash
+ scw.append(suffix);
+ }
+ // end of LANG specific region
+ }
+ }
+ }
+
+ return false;
+}
+
+struct hentry* HunspellImpl::checkword(const std::string& w, int* info, std::string* root) {
+ std::string w2;
+ const char* word;
+ int len;
+
+ // remove IGNORE characters from the string
+ clean_ignore(w2, w);
+
+ word = w2.c_str();
+ len = w2.size();
+
+ if (!len)
+ return NULL;
+
+ // word reversing wrapper for complex prefixes
+ if (complexprefixes) {
+ if (utf8)
+ reverseword_utf(w2);
+ else
+ reverseword(w2);
+ }
+
+ word = w2.c_str();
+
+ // look word in hash table
+ struct hentry* he = NULL;
+ for (size_t i = 0; (i < m_HMgrs.size()) && !he; ++i) {
+ he = m_HMgrs[i]->lookup(word);
+
+ // check forbidden and onlyincompound words
+ if ((he) && (he->astr) && (pAMgr) &&
+ TESTAFF(he->astr, pAMgr->get_forbiddenword(), he->alen)) {
+ if (info)
+ *info |= SPELL_FORBIDDEN;
+ // LANG_hu section: set dash information for suggestions
+ if (langnum == LANG_hu) {
+ if (pAMgr->get_compoundflag() &&
+ TESTAFF(he->astr, pAMgr->get_compoundflag(), he->alen)) {
+ if (info)
+ *info |= SPELL_COMPOUND;
+ }
+ }
+ return NULL;
+ }
+
+ // he = next not needaffix, onlyincompound homonym or onlyupcase word
+ while (he && (he->astr) && pAMgr &&
+ ((pAMgr->get_needaffix() &&
+ TESTAFF(he->astr, pAMgr->get_needaffix(), he->alen)) ||
+ (pAMgr->get_onlyincompound() &&
+ TESTAFF(he->astr, pAMgr->get_onlyincompound(), he->alen)) ||
+ (info && (*info & SPELL_INITCAP) &&
+ TESTAFF(he->astr, ONLYUPCASEFLAG, he->alen))))
+ he = he->next_homonym;
+ }
+
+ // check with affixes
+ if (!he && pAMgr) {
+ // try stripping off affixes */
+ he = pAMgr->affix_check(word, len, 0);
+
+ // check compound restriction and onlyupcase
+ if (he && he->astr &&
+ ((pAMgr->get_onlyincompound() &&
+ TESTAFF(he->astr, pAMgr->get_onlyincompound(), he->alen)) ||
+ (info && (*info & SPELL_INITCAP) &&
+ TESTAFF(he->astr, ONLYUPCASEFLAG, he->alen)))) {
+ he = NULL;
+ }
+
+ if (he) {
+ if ((he->astr) && (pAMgr) &&
+ TESTAFF(he->astr, pAMgr->get_forbiddenword(), he->alen)) {
+ if (info)
+ *info |= SPELL_FORBIDDEN;
+ return NULL;
+ }
+ if (root) {
+ root->assign(he->word);
+ if (complexprefixes) {
+ if (utf8)
+ reverseword_utf(*root);
+ else
+ reverseword(*root);
+ }
+ }
+ // try check compound word
+ } else if (pAMgr->get_compound()) {
+ struct hentry* rwords[100]; // buffer for COMPOUND pattern checking
+ he = pAMgr->compound_check(word, 0, 0, 100, 0, NULL, (hentry**)&rwords, 0, 0, info);
+ // LANG_hu section: `moving rule' with last dash
+ if ((!he) && (langnum == LANG_hu) && (word[len - 1] == '-')) {
+ std::string dup(word, len - 1);
+ he = pAMgr->compound_check(dup, -5, 0, 100, 0, NULL, (hentry**)&rwords, 1, 0, info);
+ }
+ // end of LANG specific region
+ if (he) {
+ if (root) {
+ root->assign(he->word);
+ if (complexprefixes) {
+ if (utf8)
+ reverseword_utf(*root);
+ else
+ reverseword(*root);
+ }
+ }
+ if (info)
+ *info |= SPELL_COMPOUND;
+ }
+ }
+ }
+
+ return he;
+}
+
+std::vector<std::string> HunspellImpl::suggest(const std::string& word) {
+ bool capwords;
+ size_t abbv;
+ int captype;
+ std::vector<std::string> slst = suggest_internal(word, capwords, abbv, captype);
+ // word reversing wrapper for complex prefixes
+ if (complexprefixes) {
+ for (size_t j = 0; j < slst.size(); ++j) {
+ if (utf8)
+ reverseword_utf(slst[j]);
+ else
+ reverseword(slst[j]);
+ }
+ }
+
+ // capitalize
+ if (capwords)
+ for (size_t j = 0; j < slst.size(); ++j) {
+ mkinitcap(slst[j]);
+ }
+
+ // expand suggestions with dot(s)
+ if (abbv && pAMgr && pAMgr->get_sugswithdots()) {
+ for (size_t j = 0; j < slst.size(); ++j) {
+ slst[j].append(word.substr(word.size() - abbv));
+ }
+ }
+
+ // remove bad capitalized and forbidden forms
+ if (pAMgr && (pAMgr->get_keepcase() || pAMgr->get_forbiddenword())) {
+ switch (captype) {
+ case INITCAP:
+ case ALLCAP: {
+ size_t l = 0;
+ for (size_t j = 0; j < slst.size(); ++j) {
+ if (slst[j].find(' ') == std::string::npos && !spell(slst[j])) {
+ std::string s;
+ std::vector<w_char> w;
+ if (utf8) {
+ u8_u16(w, slst[j]);
+ } else {
+ s = slst[j];
+ }
+ mkallsmall2(s, w);
+ if (spell(s)) {
+ slst[l] = s;
+ ++l;
+ } else {
+ mkinitcap2(s, w);
+ if (spell(s)) {
+ slst[l] = s;
+ ++l;
+ }
+ }
+ } else {
+ slst[l] = slst[j];
+ ++l;
+ }
+ }
+ slst.resize(l);
+ }
+ }
+ }
+
+ // remove duplications
+ size_t l = 0;
+ for (size_t j = 0; j < slst.size(); ++j) {
+ slst[l] = slst[j];
+ for (size_t k = 0; k < l; ++k) {
+ if (slst[k] == slst[j]) {
+ --l;
+ break;
+ }
+ }
+ ++l;
+ }
+ slst.resize(l);
+
+ // output conversion
+ RepList* rl = (pAMgr) ? pAMgr->get_oconvtable() : NULL;
+ if (rl) {
+ for (size_t i = 0; rl && i < slst.size(); ++i) {
+ std::string wspace;
+ if (rl->conv(slst[i], wspace)) {
+ slst[i] = wspace;
+ }
+ }
+ }
+ return slst;
+}
+
+std::vector<std::string> HunspellImpl::suggest_internal(const std::string& word,
+ bool& capwords, size_t& abbv, int& captype) {
+ captype = NOCAP;
+ abbv = 0;
+ capwords = false;
+
+ std::vector<std::string> slst;
+
+ int onlycmpdsug = 0;
+ if (!pSMgr || m_HMgrs.empty())
+ return slst;
+
+ // process XML input of the simplified API (see manual)
+ if (word.compare(0, sizeof(SPELL_XML) - 3, SPELL_XML, sizeof(SPELL_XML) - 3) == 0) {
+ return spellml(word);
+ }
+ if (utf8) {
+ if (word.size() >= MAXWORDUTF8LEN)
+ return slst;
+ } else {
+ if (word.size() >= MAXWORDLEN)
+ return slst;
+ }
+ size_t wl = 0;
+
+ std::string scw;
+ std::vector<w_char> sunicw;
+
+ // input conversion
+ RepList* rl = (pAMgr) ? pAMgr->get_iconvtable() : NULL;
+ {
+ std::string wspace;
+
+ bool convstatus = rl ? rl->conv(word, wspace) : false;
+ if (convstatus)
+ wl = cleanword2(scw, sunicw, wspace, &captype, &abbv);
+ else
+ wl = cleanword2(scw, sunicw, word, &captype, &abbv);
+
+ if (wl == 0)
+ return slst;
+ }
+
+ bool good = false;
+
+ clock_t timelimit;
+ // initialize in every suggestion call
+ timelimit = clock();
+
+ // check capitalized form for FORCEUCASE
+ if (pAMgr && captype == NOCAP && pAMgr->get_forceucase()) {
+ int info = SPELL_ORIGCAP;
+ if (checkword(scw, &info, NULL)) {
+ std::string form(scw);
+ mkinitcap(form);
+ slst.push_back(form);
+ return slst;
+ }
+ }
+
+ switch (captype) {
+ case NOCAP: {
+ good |= pSMgr->suggest(slst, scw.c_str(), &onlycmpdsug);
+ if (clock() > timelimit + TIMELIMIT_GLOBAL)
+ return slst;
+ if (abbv) {
+ std::string wspace(scw);
+ wspace.push_back('.');
+ good |= pSMgr->suggest(slst, wspace.c_str(), &onlycmpdsug);
+ if (clock() > timelimit + TIMELIMIT_GLOBAL)
+ return slst;
+ }
+ break;
+ }
+
+ case INITCAP: {
+ capwords = true;
+ good |= pSMgr->suggest(slst, scw.c_str(), &onlycmpdsug);
+ if (clock() > timelimit + TIMELIMIT_GLOBAL)
+ return slst;
+ std::string wspace(scw);
+ mkallsmall2(wspace, sunicw);
+ good |= pSMgr->suggest(slst, wspace.c_str(), &onlycmpdsug);
+ if (clock() > timelimit + TIMELIMIT_GLOBAL)
+ return slst;
+ break;
+ }
+ case HUHINITCAP:
+ capwords = true;
+ /* FALLTHROUGH */
+ case HUHCAP: {
+ good |= pSMgr->suggest(slst, scw.c_str(), &onlycmpdsug);
+ if (clock() > timelimit + TIMELIMIT_GLOBAL)
+ return slst;
+ // something.The -> something. The
+ size_t dot_pos = scw.find('.');
+ if (dot_pos != std::string::npos) {
+ std::string postdot = scw.substr(dot_pos + 1);
+ int captype_;
+ if (utf8) {
+ std::vector<w_char> postdotu;
+ u8_u16(postdotu, postdot);
+ captype_ = get_captype_utf8(postdotu, langnum);
+ } else {
+ captype_ = get_captype(postdot, csconv);
+ }
+ if (captype_ == INITCAP) {
+ std::string str(scw);
+ str.insert(dot_pos + 1, 1, ' ');
+ insert_sug(slst, str);
+ }
+ }
+
+ std::string wspace;
+
+ if (captype == HUHINITCAP) {
+ // TheOpenOffice.org -> The OpenOffice.org
+ wspace = scw;
+ mkinitsmall2(wspace, sunicw);
+ good |= pSMgr->suggest(slst, wspace.c_str(), &onlycmpdsug);
+ if (clock() > timelimit + TIMELIMIT_GLOBAL)
+ return slst;
+ }
+ wspace = scw;
+ mkallsmall2(wspace, sunicw);
+ if (spell(wspace.c_str()))
+ insert_sug(slst, wspace);
+ size_t prevns = slst.size();
+ good |= pSMgr->suggest(slst, wspace.c_str(), &onlycmpdsug);
+ if (clock() > timelimit + TIMELIMIT_GLOBAL)
+ return slst;
+ if (captype == HUHINITCAP) {
+ mkinitcap2(wspace, sunicw);
+ if (spell(wspace.c_str()))
+ insert_sug(slst, wspace);
+ good |= pSMgr->suggest(slst, wspace.c_str(), &onlycmpdsug);
+ if (clock() > timelimit + TIMELIMIT_GLOBAL)
+ return slst;
+ }
+ // aNew -> "a New" (instead of "a new")
+ for (size_t j = prevns; j < slst.size(); ++j) {
+ const char* space = strchr(slst[j].c_str(), ' ');
+ if (space) {
+ size_t slen = strlen(space + 1);
+ // different case after space (need capitalisation)
+ if ((slen < wl) && strcmp(scw.c_str() + wl - slen, space + 1)) {
+ std::string first(slst[j].c_str(), space + 1);
+ std::string second(space + 1);
+ std::vector<w_char> w;
+ if (utf8)
+ u8_u16(w, second);
+ mkinitcap2(second, w);
+ // set as first suggestion
+ slst.erase(slst.begin() + j);
+ slst.insert(slst.begin(), first + second);
+ }
+ }
+ }
+ break;
+ }
+
+ case ALLCAP: {
+ std::string wspace(scw);
+ mkallsmall2(wspace, sunicw);
+ good |= pSMgr->suggest(slst, wspace.c_str(), &onlycmpdsug);
+ if (clock() > timelimit + TIMELIMIT_GLOBAL)
+ return slst;
+ if (pAMgr && pAMgr->get_keepcase() && spell(wspace.c_str()))
+ insert_sug(slst, wspace);
+ mkinitcap2(wspace, sunicw);
+ good |= pSMgr->suggest(slst, wspace.c_str(), &onlycmpdsug);
+ if (clock() > timelimit + TIMELIMIT_GLOBAL)
+ return slst;
+ for (size_t j = 0; j < slst.size(); ++j) {
+ mkallcap(slst[j]);
+ if (pAMgr && pAMgr->get_checksharps()) {
+ if (utf8) {
+ mystrrep(slst[j], "\xC3\x9F", "SS");
+ } else {
+ mystrrep(slst[j], "\xDF", "SS");
+ }
+ }
+ }
+ break;
+ }
+ }
+
+ // LANG_hu section: replace '-' with ' ' in Hungarian
+ if (langnum == LANG_hu) {
+ for (size_t j = 0; j < slst.size(); ++j) {
+ size_t pos = slst[j].find('-');
+ if (pos != std::string::npos) {
+ int info;
+ std::string w(slst[j].substr(0, pos));
+ w.append(slst[j].substr(pos + 1));
+ (void)spell(w, &info, NULL);
+ if ((info & SPELL_COMPOUND) && (info & SPELL_FORBIDDEN)) {
+ slst[j][pos] = ' ';
+ } else
+ slst[j][pos] = '-';
+ }
+ }
+ }
+ // END OF LANG_hu section
+ // try ngram approach since found nothing good suggestion
+ if (!good && pAMgr && (slst.empty() || onlycmpdsug) && (pAMgr->get_maxngramsugs() != 0)) {
+ switch (captype) {
+ case NOCAP: {
+ pSMgr->ngsuggest(slst, scw.c_str(), m_HMgrs, NOCAP);
+ if (clock() > timelimit + TIMELIMIT_GLOBAL)
+ return slst;
+ break;
+ }
+ /* FALLTHROUGH */
+ case HUHINITCAP:
+ capwords = true;
+ /* FALLTHROUGH */
+ case HUHCAP: {
+ std::string wspace(scw);
+ mkallsmall2(wspace, sunicw);
+ pSMgr->ngsuggest(slst, wspace.c_str(), m_HMgrs, HUHCAP);
+ if (clock() > timelimit + TIMELIMIT_GLOBAL)
+ return slst;
+ break;
+ }
+ case INITCAP: {
+ capwords = true;
+ std::string wspace(scw);
+ mkallsmall2(wspace, sunicw);
+ pSMgr->ngsuggest(slst, wspace.c_str(), m_HMgrs, INITCAP);
+ if (clock() > timelimit + TIMELIMIT_GLOBAL)
+ return slst;
+ break;
+ }
+ case ALLCAP: {
+ std::string wspace(scw);
+ mkallsmall2(wspace, sunicw);
+ size_t oldns = slst.size();
+ pSMgr->ngsuggest(slst, wspace.c_str(), m_HMgrs, ALLCAP);
+ if (clock() > timelimit + TIMELIMIT_GLOBAL)
+ return slst;
+ for (size_t j = oldns; j < slst.size(); ++j) {
+ mkallcap(slst[j]);
+ }
+ break;
+ }
+ }
+ }
+
+ // try dash suggestion (Afo-American -> Afro-American)
+ // Note: LibreOffice was modified to treat dashes as word
+ // characters to check "scot-free" etc. word forms, but
+ // we need to handle suggestions for "Afo-American", etc.,
+ // while "Afro-American" is missing from the dictionary.
+ // TODO avoid possible overgeneration
+ size_t dash_pos = scw.find('-');
+ if (dash_pos != std::string::npos) {
+ int nodashsug = 1;
+ for (size_t j = 0; j < slst.size() && nodashsug == 1; ++j) {
+ if (slst[j].find('-') != std::string::npos)
+ nodashsug = 0;
+ }
+
+ size_t prev_pos = 0;
+ bool last = false;
+
+ while (!good && nodashsug && !last) {
+ if (dash_pos == scw.size())
+ last = 1;
+ std::string chunk = scw.substr(prev_pos, dash_pos - prev_pos);
+ if (!spell(chunk.c_str())) {
+ std::vector<std::string> nlst = suggest(chunk.c_str());
+ if (clock() > timelimit + TIMELIMIT_GLOBAL)
+ return slst;
+ for (std::vector<std::string>::reverse_iterator j = nlst.rbegin(); j != nlst.rend(); ++j) {
+ std::string wspace = scw.substr(0, prev_pos);
+ wspace.append(*j);
+ if (!last) {
+ wspace.append("-");
+ wspace.append(scw.substr(dash_pos + 1));
+ }
+ int info = 0;
+ if (pAMgr && pAMgr->get_forbiddenword())
+ checkword(wspace, &info, NULL);
+ if (!(info & SPELL_FORBIDDEN))
+ insert_sug(slst, wspace);
+ }
+ nodashsug = 0;
+ }
+ if (!last) {
+ prev_pos = dash_pos + 1;
+ dash_pos = scw.find('-', prev_pos);
+ }
+ if (dash_pos == std::string::npos)
+ dash_pos = scw.size();
+ }
+ }
+ return slst;
+}
+
+const std::string& HunspellImpl::get_dict_encoding() const {
+ return encoding;
+}
+
+std::vector<std::string> HunspellImpl::stem(const std::vector<std::string>& desc) {
+ std::vector<std::string> slst;
+
+ std::string result2;
+ if (desc.empty())
+ return slst;
+ for (size_t i = 0; i < desc.size(); ++i) {
+
+ std::string result;
+
+ // add compound word parts (except the last one)
+ const char* s = desc[i].c_str();
+ const char* part = strstr(s, MORPH_PART);
+ if (part) {
+ const char* nextpart = strstr(part + 1, MORPH_PART);
+ while (nextpart) {
+ std::string field;
+ copy_field(field, part, MORPH_PART);
+ result.append(field);
+ part = nextpart;
+ nextpart = strstr(part + 1, MORPH_PART);
+ }
+ s = part;
+ }
+
+ std::string tok(s);
+ size_t alt = 0;
+ while ((alt = tok.find(" | ", alt)) != std::string::npos) {
+ tok[alt + 1] = MSEP_ALT;
+ }
+ std::vector<std::string> pl = line_tok(tok, MSEP_ALT);
+ for (size_t k = 0; k < pl.size(); ++k) {
+ // add derivational suffixes
+ if (pl[k].find(MORPH_DERI_SFX) != std::string::npos) {
+ // remove inflectional suffixes
+ const size_t is = pl[k].find(MORPH_INFL_SFX);
+ if (is != std::string::npos)
+ pl[k].resize(is);
+ std::vector<std::string> singlepl;
+ singlepl.push_back(pl[k]);
+ std::string sg = pSMgr->suggest_gen(singlepl, pl[k]);
+ if (!sg.empty()) {
+ std::vector<std::string> gen = line_tok(sg, MSEP_REC);
+ for (size_t j = 0; j < gen.size(); ++j) {
+ result2.push_back(MSEP_REC);
+ result2.append(result);
+ result2.append(gen[j]);
+ }
+ }
+ } else {
+ result2.push_back(MSEP_REC);
+ result2.append(result);
+ if (pl[k].find(MORPH_SURF_PFX) != std::string::npos) {
+ std::string field;
+ copy_field(field, pl[k], MORPH_SURF_PFX);
+ result2.append(field);
+ }
+ std::string field;
+ copy_field(field, pl[k], MORPH_STEM);
+ result2.append(field);
+ }
+ }
+ }
+ slst = line_tok(result2, MSEP_REC);
+ uniqlist(slst);
+ return slst;
+}
+
+std::vector<std::string> HunspellImpl::stem(const std::string& word) {
+ return stem(analyze(word));
+}
+
+const std::string& HunspellImpl::get_wordchars_cpp() const {
+ return pAMgr->get_wordchars();
+}
+
+const std::vector<w_char>& HunspellImpl::get_wordchars_utf16() const {
+ return pAMgr->get_wordchars_utf16();
+}
+
+void HunspellImpl::mkinitcap(std::string& u8) {
+ if (utf8) {
+ std::vector<w_char> u16;
+ u8_u16(u16, u8);
+ ::mkinitcap_utf(u16, langnum);
+ u16_u8(u8, u16);
+ } else {
+ ::mkinitcap(u8, csconv);
+ }
+}
+
+int HunspellImpl::mkinitcap2(std::string& u8, std::vector<w_char>& u16) {
+ if (utf8) {
+ ::mkinitcap_utf(u16, langnum);
+ u16_u8(u8, u16);
+ } else {
+ ::mkinitcap(u8, csconv);
+ }
+ return u8.size();
+}
+
+int HunspellImpl::mkinitsmall2(std::string& u8, std::vector<w_char>& u16) {
+ if (utf8) {
+ ::mkinitsmall_utf(u16, langnum);
+ u16_u8(u8, u16);
+ } else {
+ ::mkinitsmall(u8, csconv);
+ }
+ return u8.size();
+}
+
+int HunspellImpl::add(const std::string& word) {
+ if (!m_HMgrs.empty())
+ return m_HMgrs[0]->add(word);
+ return 0;
+}
+
+int HunspellImpl::add_with_affix(const std::string& word, const std::string& example) {
+ if (!m_HMgrs.empty())
+ return m_HMgrs[0]->add_with_affix(word, example);
+ return 0;
+}
+
+int HunspellImpl::remove(const std::string& word) {
+ if (!m_HMgrs.empty())
+ return m_HMgrs[0]->remove(word);
+ return 0;
+}
+
+const std::string& HunspellImpl::get_version_cpp() const {
+ return pAMgr->get_version();
+}
+
+struct cs_info* HunspellImpl::get_csconv() {
+ return csconv;
+}
+
+void HunspellImpl::cat_result(std::string& result, const std::string& st) {
+ if (!st.empty()) {
+ if (!result.empty())
+ result.append("\n");
+ result.append(st);
+ }
+}
+
+std::vector<std::string> HunspellImpl::analyze(const std::string& word) {
+ std::vector<std::string> slst = analyze_internal(word);
+ // output conversion
+ RepList* rl = (pAMgr) ? pAMgr->get_oconvtable() : NULL;
+ if (rl) {
+ for (size_t i = 0; rl && i < slst.size(); ++i) {
+ std::string wspace;
+ if (rl->conv(slst[i], wspace)) {
+ slst[i] = wspace;
+ }
+ }
+ }
+ return slst;
+}
+
+std::vector<std::string> HunspellImpl::analyze_internal(const std::string& word) {
+ std::vector<std::string> slst;
+ if (!pSMgr || m_HMgrs.empty())
+ return slst;
+ if (utf8) {
+ if (word.size() >= MAXWORDUTF8LEN)
+ return slst;
+ } else {
+ if (word.size() >= MAXWORDLEN)
+ return slst;
+ }
+ int captype = NOCAP;
+ size_t abbv = 0;
+ size_t wl = 0;
+
+ std::string scw;
+ std::vector<w_char> sunicw;
+
+ // input conversion
+ RepList* rl = (pAMgr) ? pAMgr->get_iconvtable() : NULL;
+ {
+ std::string wspace;
+
+ bool convstatus = rl ? rl->conv(word, wspace) : false;
+ if (convstatus)
+ wl = cleanword2(scw, sunicw, wspace, &captype, &abbv);
+ else
+ wl = cleanword2(scw, sunicw, word, &captype, &abbv);
+ }
+
+ if (wl == 0) {
+ if (abbv) {
+ scw.clear();
+ for (wl = 0; wl < abbv; wl++)
+ scw.push_back('.');
+ abbv = 0;
+ } else
+ return slst;
+ }
+
+ std::string result;
+
+ size_t n = 0;
+ // test numbers
+ // LANG_hu section: set dash information for suggestions
+ if (langnum == LANG_hu) {
+ size_t n2 = 0;
+ size_t n3 = 0;
+
+ while ((n < wl) && (((scw[n] <= '9') && (scw[n] >= '0')) ||
+ (((scw[n] == '.') || (scw[n] == ',')) && (n > 0)))) {
+ n++;
+ if ((scw[n] == '.') || (scw[n] == ',')) {
+ if (((n2 == 0) && (n > 3)) ||
+ ((n2 > 0) && ((scw[n - 1] == '.') || (scw[n - 1] == ','))))
+ break;
+ n2++;
+ n3 = n;
+ }
+ }
+
+ if ((n == wl) && (n3 > 0) && (n - n3 > 3))
+ return slst;
+ if ((n == wl) || ((n > 0) && ((scw[n] == '%') || (scw[n] == '\xB0')) &&
+ checkword(scw.substr(n), NULL, NULL))) {
+ result.append(scw);
+ result.resize(n - 1);
+ if (n == wl)
+ cat_result(result, pSMgr->suggest_morph(scw.substr(n - 1)));
+ else {
+ std::string chunk = scw.substr(n - 1, 1);
+ cat_result(result, pSMgr->suggest_morph(chunk));
+ result.push_back('+'); // XXX SPEC. MORPHCODE
+ cat_result(result, pSMgr->suggest_morph(scw.substr(n)));
+ }
+ return line_tok(result, MSEP_REC);
+ }
+ }
+ // END OF LANG_hu section
+
+ switch (captype) {
+ case HUHCAP:
+ case HUHINITCAP:
+ case NOCAP: {
+ cat_result(result, pSMgr->suggest_morph(scw));
+ if (abbv) {
+ std::string u8buffer(scw);
+ u8buffer.push_back('.');
+ cat_result(result, pSMgr->suggest_morph(u8buffer));
+ }
+ break;
+ }
+ case INITCAP: {
+ mkallsmall2(scw, sunicw);
+ std::string u8buffer(scw);
+ mkinitcap2(scw, sunicw);
+ cat_result(result, pSMgr->suggest_morph(u8buffer));
+ cat_result(result, pSMgr->suggest_morph(scw));
+ if (abbv) {
+ u8buffer.push_back('.');
+ cat_result(result, pSMgr->suggest_morph(u8buffer));
+
+ u8buffer = scw;
+ u8buffer.push_back('.');
+
+ cat_result(result, pSMgr->suggest_morph(u8buffer));
+ }
+ break;
+ }
+ case ALLCAP: {
+ cat_result(result, pSMgr->suggest_morph(scw));
+ if (abbv) {
+ std::string u8buffer(scw);
+ u8buffer.push_back('.');
+ cat_result(result, pSMgr->suggest_morph(u8buffer));
+ }
+ mkallsmall2(scw, sunicw);
+ std::string u8buffer(scw);
+ mkinitcap2(scw, sunicw);
+
+ cat_result(result, pSMgr->suggest_morph(u8buffer));
+ cat_result(result, pSMgr->suggest_morph(scw));
+ if (abbv) {
+ u8buffer.push_back('.');
+ cat_result(result, pSMgr->suggest_morph(u8buffer));
+
+ u8buffer = scw;
+ u8buffer.push_back('.');
+
+ cat_result(result, pSMgr->suggest_morph(u8buffer));
+ }
+ break;
+ }
+ }
+
+ if (!result.empty()) {
+ // word reversing wrapper for complex prefixes
+ if (complexprefixes) {
+ if (utf8)
+ reverseword_utf(result);
+ else
+ reverseword(result);
+ }
+ return line_tok(result, MSEP_REC);
+ }
+
+ // compound word with dash (HU) I18n
+ // LANG_hu section: set dash information for suggestions
+
+ size_t dash_pos = langnum == LANG_hu ? scw.find('-') : std::string::npos;
+ if (dash_pos != std::string::npos) {
+ int nresult = 0;
+
+ std::string part1 = scw.substr(0, dash_pos);
+ std::string part2 = scw.substr(dash_pos+1);
+
+ // examine 2 sides of the dash
+ if (part2.empty()) { // base word ending with dash
+ if (spell(part1)) {
+ std::string p = pSMgr->suggest_morph(part1);
+ if (!p.empty()) {
+ slst = line_tok(p, MSEP_REC);
+ return slst;
+ }
+ }
+ } else if (part2.size() == 1 && part2[0] == 'e') { // XXX (HU) -e hat.
+ if (spell(part1) && (spell("-e"))) {
+ std::string st = pSMgr->suggest_morph(part1);
+ if (!st.empty()) {
+ result.append(st);
+ }
+ result.push_back('+'); // XXX spec. separator in MORPHCODE
+ st = pSMgr->suggest_morph("-e");
+ if (!st.empty()) {
+ result.append(st);
+ }
+ return line_tok(result, MSEP_REC);
+ }
+ } else {
+ // first word ending with dash: word- XXX ???
+ part1.push_back(' ');
+ nresult = spell(part1);
+ part1.erase(part1.size() - 1);
+ if (nresult && spell(part2) &&
+ ((part2.size() > 1) || ((part2[0] > '0') && (part2[0] < '9')))) {
+ std::string st = pSMgr->suggest_morph(part1);
+ if (!st.empty()) {
+ result.append(st);
+ result.push_back('+'); // XXX spec. separator in MORPHCODE
+ }
+ st = pSMgr->suggest_morph(part2);
+ if (!st.empty()) {
+ result.append(st);
+ }
+ return line_tok(result, MSEP_REC);
+ }
+ }
+ // affixed number in correct word
+ if (nresult && (dash_pos > 0) &&
+ (((scw[dash_pos - 1] <= '9') && (scw[dash_pos - 1] >= '0')) ||
+ (scw[dash_pos - 1] == '.'))) {
+ n = 1;
+ if (scw[dash_pos - n] == '.')
+ n++;
+ // search first not a number character to left from dash
+ while ((dash_pos >= n) && ((scw[dash_pos - n] == '0') || (n < 3)) &&
+ (n < 6)) {
+ n++;
+ }
+ if (dash_pos < n)
+ n--;
+ // numbers: valami1000000-hoz
+ // examine 100000-hoz, 10000-hoz 1000-hoz, 10-hoz,
+ // 56-hoz, 6-hoz
+ for (; n >= 1; n--) {
+ if (scw[dash_pos - n] < '0' || scw[dash_pos - n] > '9') {
+ continue;
+ }
+ std::string chunk = scw.substr(dash_pos - n);
+ if (checkword(chunk, NULL, NULL)) {
+ result.append(chunk);
+ std::string st = pSMgr->suggest_morph(chunk);
+ if (!st.empty()) {
+ result.append(st);
+ }
+ return line_tok(result, MSEP_REC);
+ }
+ }
+ }
+ }
+ return slst;
+}
+
+std::vector<std::string> HunspellImpl::generate(const std::string& word, const std::vector<std::string>& pl) {
+ std::vector<std::string> slst;
+ if (!pSMgr || pl.empty())
+ return slst;
+ std::vector<std::string> pl2 = analyze(word);
+ int captype = NOCAP;
+ int abbv = 0;
+ std::string cw;
+ cleanword(cw, word, &captype, &abbv);
+ std::string result;
+
+ for (size_t i = 0; i < pl.size(); ++i) {
+ cat_result(result, pSMgr->suggest_gen(pl2, pl[i]));
+ }
+
+ if (!result.empty()) {
+ // allcap
+ if (captype == ALLCAP)
+ mkallcap(result);
+
+ // line split
+ slst = line_tok(result, MSEP_REC);
+
+ // capitalize
+ if (captype == INITCAP || captype == HUHINITCAP) {
+ for (size_t j = 0; j < slst.size(); ++j) {
+ mkinitcap(slst[j]);
+ }
+ }
+
+ // temporary filtering of prefix related errors (eg.
+ // generate("undrinkable", "eats") --> "undrinkables" and "*undrinks")
+ std::vector<std::string>::iterator it = slst.begin();
+ while (it != slst.end()) {
+ if (!spell(*it)) {
+ it = slst.erase(it);
+ } else {
+ ++it;
+ }
+ }
+ }
+ return slst;
+}
+
+std::vector<std::string> HunspellImpl::generate(const std::string& word, const std::string& pattern) {
+ std::vector<std::string> pl = analyze(pattern);
+ std::vector<std::string> slst = generate(word, pl);
+ uniqlist(slst);
+ return slst;
+}
+
+// minimal XML parser functions
+std::string HunspellImpl::get_xml_par(const std::string& in_par, std::string::size_type pos) {
+ std::string dest;
+ if (pos == std::string::npos)
+ return dest;
+ const char* par = in_par.c_str() + pos;
+ char end = *par;
+ if (end == '>')
+ end = '<';
+ else if (end != '\'' && end != '"')
+ return dest; // bad XML
+ for (par++; *par != '\0' && *par != end; ++par) {
+ dest.push_back(*par);
+ }
+ mystrrep(dest, "&lt;", "<");
+ mystrrep(dest, "&amp;", "&");
+ return dest;
+}
+
+int HunspellImpl::get_langnum() const {
+ return langnum;
+}
+
+bool HunspellImpl::input_conv(const std::string& word, std::string& dest) {
+ RepList* rl = pAMgr ? pAMgr->get_iconvtable() : NULL;
+ if (rl) {
+ return rl->conv(word, dest);
+ }
+ dest.assign(word);
+ return false;
+}
+
+// return the beginning of the element (attr == NULL) or the attribute
+std::string::size_type HunspellImpl::get_xml_pos(const std::string& s, std::string::size_type pos, const char* attr) {
+ if (pos == std::string::npos)
+ return std::string::npos;
+
+ std::string::size_type endpos = s.find('>', pos);
+ if (attr == NULL)
+ return endpos;
+ while (true) {
+ pos = s.find(attr, pos);
+ if (pos == std::string::npos || pos >= endpos)
+ return std::string::npos;
+ if (s[pos - 1] == ' ' || s[pos - 1] == '\n')
+ break;
+ pos += strlen(attr);
+ }
+ return pos + strlen(attr);
+}
+
+int HunspellImpl::check_xml_par(const std::string& q, std::string::size_type pos,
+ const char* attr,
+ const char* value) {
+ std::string cw = get_xml_par(q, get_xml_pos(q, pos, attr));
+ if (cw == value)
+ return 1;
+ return 0;
+}
+
+std::vector<std::string> HunspellImpl::get_xml_list(const std::string& list, std::string::size_type pos, const char* tag) {
+ std::vector<std::string> slst;
+ if (pos == std::string::npos)
+ return slst;
+ while (true) {
+ pos = list.find(tag, pos);
+ if (pos == std::string::npos)
+ break;
+ std::string cw = get_xml_par(list, pos + strlen(tag) - 1);
+ if (cw.empty()) {
+ break;
+ }
+ slst.push_back(cw);
+ ++pos;
+ }
+ return slst;
+}
+
+std::vector<std::string> HunspellImpl::spellml(const std::string& in_word) {
+ std::vector<std::string> slst;
+
+ std::string::size_type qpos = in_word.find("<query");
+ if (qpos == std::string::npos)
+ return slst; // bad XML input
+
+ std::string::size_type q2pos = in_word.find('>', qpos);
+ if (q2pos == std::string::npos)
+ return slst; // bad XML input
+
+ q2pos = in_word.find("<word", q2pos);
+ if (q2pos == std::string::npos)
+ return slst; // bad XML input
+
+ if (check_xml_par(in_word, qpos, "type=", "analyze")) {
+ std::string cw = get_xml_par(in_word, in_word.find('>', q2pos));
+ if (!cw.empty())
+ slst = analyze(cw);
+ if (slst.empty())
+ return slst;
+ // convert the result to <code><a>ana1</a><a>ana2</a></code> format
+ std::string r;
+ r.append("<code>");
+ for (size_t i = 0; i < slst.size(); ++i) {
+ r.append("<a>");
+
+ std::string entry(slst[i]);
+ mystrrep(entry, "\t", " ");
+ mystrrep(entry, "&", "&amp;");
+ mystrrep(entry, "<", "&lt;");
+ r.append(entry);
+
+ r.append("</a>");
+ }
+ r.append("</code>");
+ slst.clear();
+ slst.push_back(r);
+ return slst;
+ } else if (check_xml_par(in_word, qpos, "type=", "stem")) {
+ std::string cw = get_xml_par(in_word, in_word.find('>', q2pos));
+ if (!cw.empty())
+ return stem(cw);
+ } else if (check_xml_par(in_word, qpos, "type=", "generate")) {
+ std::string cw = get_xml_par(in_word, in_word.find('>', q2pos));
+ if (cw.empty())
+ return slst;
+ std::string::size_type q3pos = in_word.find("<word", q2pos + 1);
+ if (q3pos != std::string::npos) {
+ std::string cw2 = get_xml_par(in_word, in_word.find('>', q3pos));
+ if (!cw2.empty()) {
+ return generate(cw, cw2);
+ }
+ } else {
+ q2pos = in_word.find("<code", q2pos + 1);
+ if (q2pos != std::string::npos) {
+ std::vector<std::string> slst2 = get_xml_list(in_word, in_word.find('>', q2pos), "<a>");
+ if (!slst2.empty()) {
+ slst = generate(cw, slst2);
+ uniqlist(slst);
+ return slst;
+ }
+ }
+ }
+ } else if (check_xml_par(in_word, qpos, "type=", "add")) {
+ std::string cw = get_xml_par(in_word, in_word.find('>', q2pos));
+ if (cw.empty())
+ return slst;
+ std::string::size_type q3pos = in_word.find("<word", q2pos + 1);
+ if (q3pos != std::string::npos) {
+ std::string cw2 = get_xml_par(in_word, in_word.find('>', q3pos));
+ if (!cw2.empty()) {
+ add_with_affix(cw, cw2);
+ } else {
+ add(cw);
+ }
+ } else {
+ add(cw);
+ }
+ }
+ return slst;
+}
+
+std::vector<std::string> HunspellImpl::suffix_suggest(const std::string& root_word) {
+ std::vector<std::string> slst;
+ struct hentry* he = NULL;
+ int len;
+ std::string w2;
+ const char* word;
+ const char* ignoredchars = pAMgr->get_ignore();
+ if (ignoredchars != NULL) {
+ w2.assign(root_word);
+ if (utf8) {
+ const std::vector<w_char>& ignoredchars_utf16 =
+ pAMgr->get_ignore_utf16();
+ remove_ignored_chars_utf(w2, ignoredchars_utf16);
+ } else {
+ remove_ignored_chars(w2, ignoredchars);
+ }
+ word = w2.c_str();
+ } else
+ word = root_word.c_str();
+
+ len = strlen(word);
+
+ if (!len)
+ return slst;
+
+ for (size_t i = 0; (i < m_HMgrs.size()) && !he; ++i) {
+ he = m_HMgrs[i]->lookup(word);
+ }
+ if (he) {
+ slst = pAMgr->get_suffix_words(he->astr, he->alen, root_word.c_str());
+ }
+ return slst;
+}
+
+namespace {
+ int munge_vector(char*** slst, const std::vector<std::string>& items) {
+ if (items.empty()) {
+ *slst = NULL;
+ return 0;
+ } else {
+ *slst = (char**)malloc(sizeof(char*) * items.size());
+ if (!*slst)
+ return 0;
+ for (size_t i = 0; i < items.size(); ++i)
+ (*slst)[i] = mystrdup(items[i].c_str());
+ }
+ return items.size();
+ }
+}
+
+int HunspellImpl::spell(const char* word, int* info, char** root) {
+ std::string sroot;
+ bool ret = spell(word, info, root ? &sroot : NULL);
+ if (root) {
+ if (sroot.empty()) {
+ *root = NULL;
+ } else {
+ *root = mystrdup(sroot.c_str());
+ }
+ }
+ return ret;
+}
+
+int HunspellImpl::suggest(char*** slst, const char* word) {
+ std::vector<std::string> suggests = suggest(word);
+ return munge_vector(slst, suggests);
+}
+
+int HunspellImpl::suffix_suggest(char*** slst, const char* root_word) {
+ std::vector<std::string> stems = suffix_suggest(root_word);
+ return munge_vector(slst, stems);
+}
+
+void HunspellImpl::free_list(char*** slst, int n) {
+ if (slst && *slst) {
+ for (int i = 0; i < n; i++)
+ free((*slst)[i]);
+ free(*slst);
+ *slst = NULL;
+ }
+}
+
+char* HunspellImpl::get_dic_encoding() {
+ return &encoding[0];
+}
+
+int HunspellImpl::analyze(char*** slst, const char* word) {
+ std::vector<std::string> stems = analyze(word);
+ return munge_vector(slst, stems);
+}
+
+int HunspellImpl::stem(char*** slst, const char* word) {
+ std::vector<std::string> stems = stem(word);
+ return munge_vector(slst, stems);
+}
+
+int HunspellImpl::stem(char*** slst, char** desc, int n) {
+ std::vector<std::string> morph;
+ morph.reserve(n);
+ for (int i = 0; i < n; ++i)
+ morph.push_back(desc[i]);
+
+ std::vector<std::string> stems = stem(morph);
+ return munge_vector(slst, stems);
+}
+
+int HunspellImpl::generate(char*** slst, const char* word, const char* pattern) {
+ std::vector<std::string> stems = generate(word, pattern);
+ return munge_vector(slst, stems);
+}
+
+int HunspellImpl::generate(char*** slst, const char* word, char** pl, int pln) {
+ std::vector<std::string> morph;
+ morph.reserve(pln);
+ for (int i = 0; i < pln; ++i)
+ morph.push_back(pl[i]);
+
+ std::vector<std::string> stems = generate(word, morph);
+ return munge_vector(slst, stems);
+}
+
+const char* HunspellImpl::get_wordchars() const {
+ return get_wordchars_cpp().c_str();
+}
+
+const char* HunspellImpl::get_version() const {
+ return get_version_cpp().c_str();
+}
+
+int HunspellImpl::input_conv(const char* word, char* dest, size_t destsize) {
+ std::string d;
+ bool ret = input_conv(word, d);
+ if (ret && d.size() < destsize) {
+ strncpy(dest, d.c_str(), destsize);
+ return 1;
+ }
+ return 0;
+}
+
+Hunspell::Hunspell(const char* affpath, const char* dpath, const char* key)
+ : m_Impl(new HunspellImpl(affpath, dpath, key)) {
+}
+
+Hunspell::~Hunspell() {
+ delete m_Impl;
+}
+
+// load extra dictionaries
+int Hunspell::add_dic(const char* dpath, const char* key) {
+ return m_Impl->add_dic(dpath, key);
+}
+
+bool Hunspell::spell(const std::string& word, int* info, std::string* root) {
+ return m_Impl->spell(word, info, root);
+}
+
+std::vector<std::string> Hunspell::suggest(const std::string& word) {
+ return m_Impl->suggest(word);
+}
+
+std::vector<std::string> Hunspell::suffix_suggest(const std::string& root_word) {
+ return m_Impl->suffix_suggest(root_word);
+}
+
+const std::string& Hunspell::get_dict_encoding() const {
+ return m_Impl->get_dict_encoding();
+}
+
+std::vector<std::string> Hunspell::stem(const std::vector<std::string>& desc) {
+ return m_Impl->stem(desc);
+}
+
+std::vector<std::string> Hunspell::stem(const std::string& word) {
+ return m_Impl->stem(word);
+}
+
+const std::string& Hunspell::get_wordchars_cpp() const {
+ return m_Impl->get_wordchars_cpp();
+}
+
+const std::vector<w_char>& Hunspell::get_wordchars_utf16() const {
+ return m_Impl->get_wordchars_utf16();
+}
+
+int Hunspell::add(const std::string& word) {
+ return m_Impl->add(word);
+}
+
+int Hunspell::add_with_affix(const std::string& word, const std::string& example) {
+ return m_Impl->add_with_affix(word, example);
+}
+
+int Hunspell::remove(const std::string& word) {
+ return m_Impl->remove(word);
+}
+
+const std::string& Hunspell::get_version_cpp() const {
+ return m_Impl->get_version_cpp();
+}
+
+struct cs_info* Hunspell::get_csconv() {
+ return m_Impl->get_csconv();
+}
+
+std::vector<std::string> Hunspell::analyze(const std::string& word) {
+ return m_Impl->analyze(word);
+}
+
+std::vector<std::string> Hunspell::generate(const std::string& word, const std::vector<std::string>& pl) {
+ return m_Impl->generate(word, pl);
+}
+
+std::vector<std::string> Hunspell::generate(const std::string& word, const std::string& pattern) {
+ return m_Impl->generate(word, pattern);
+}
+
+int Hunspell::get_langnum() const {
+ return m_Impl->get_langnum();
+}
+
+bool Hunspell::input_conv(const std::string& word, std::string& dest) {
+ return m_Impl->input_conv(word, dest);
+}
+
+int Hunspell::spell(const char* word, int* info, char** root) {
+ return m_Impl->spell(word, info, root);
+}
+
+int Hunspell::suggest(char*** slst, const char* word) {
+ return m_Impl->suggest(slst, word);
+}
+
+int Hunspell::suffix_suggest(char*** slst, const char* root_word) {
+ return m_Impl->suffix_suggest(slst, root_word);
+}
+
+void Hunspell::free_list(char*** slst, int n) {
+ m_Impl->free_list(slst, n);
+}
+
+char* Hunspell::get_dic_encoding() {
+ return m_Impl->get_dic_encoding();
+}
+
+int Hunspell::analyze(char*** slst, const char* word) {
+ return m_Impl->analyze(slst, word);
+}
+
+int Hunspell::stem(char*** slst, const char* word) {
+ return m_Impl->stem(slst, word);
+}
+
+int Hunspell::stem(char*** slst, char** desc, int n) {
+ return m_Impl->stem(slst, desc, n);
+}
+
+int Hunspell::generate(char*** slst, const char* word, const char* pattern) {
+ return m_Impl->generate(slst, word, pattern);
+}
+
+int Hunspell::generate(char*** slst, const char* word, char** pl, int pln) {
+ return m_Impl->generate(slst, word, pl, pln);
+}
+
+const char* Hunspell::get_wordchars() const {
+ return m_Impl->get_wordchars();
+}
+
+const char* Hunspell::get_version() const {
+ return m_Impl->get_version();
+}
+
+int Hunspell::input_conv(const char* word, char* dest, size_t destsize) {
+ return m_Impl->input_conv(word, dest, destsize);
+}
+
+Hunhandle* Hunspell_create(const char* affpath, const char* dpath) {
+ return reinterpret_cast<Hunhandle*>(new HunspellImpl(affpath, dpath));
+}
+
+Hunhandle* Hunspell_create_key(const char* affpath,
+ const char* dpath,
+ const char* key) {
+ return reinterpret_cast<Hunhandle*>(new HunspellImpl(affpath, dpath, key));
+}
+
+void Hunspell_destroy(Hunhandle* pHunspell) {
+ delete reinterpret_cast<HunspellImpl*>(pHunspell);
+}
+
+int Hunspell_add_dic(Hunhandle* pHunspell, const char* dpath) {
+ return reinterpret_cast<HunspellImpl*>(pHunspell)->add_dic(dpath);
+}
+
+int Hunspell_spell(Hunhandle* pHunspell, const char* word) {
+ return reinterpret_cast<HunspellImpl*>(pHunspell)->spell(word);
+}
+
+char* Hunspell_get_dic_encoding(Hunhandle* pHunspell) {
+ return reinterpret_cast<HunspellImpl*>(pHunspell)->get_dic_encoding();
+}
+
+int Hunspell_suggest(Hunhandle* pHunspell, char*** slst, const char* word) {
+ return reinterpret_cast<HunspellImpl*>(pHunspell)->suggest(slst, word);
+}
+
+int Hunspell_analyze(Hunhandle* pHunspell, char*** slst, const char* word) {
+ return reinterpret_cast<HunspellImpl*>(pHunspell)->analyze(slst, word);
+}
+
+int Hunspell_stem(Hunhandle* pHunspell, char*** slst, const char* word) {
+ return reinterpret_cast<HunspellImpl*>(pHunspell)->stem(slst, word);
+}
+
+int Hunspell_stem2(Hunhandle* pHunspell, char*** slst, char** desc, int n) {
+ return reinterpret_cast<HunspellImpl*>(pHunspell)->stem(slst, desc, n);
+}
+
+int Hunspell_generate(Hunhandle* pHunspell,
+ char*** slst,
+ const char* word,
+ const char* pattern)
+{
+ return reinterpret_cast<HunspellImpl*>(pHunspell)->generate(slst, word, pattern);
+}
+
+int Hunspell_generate2(Hunhandle* pHunspell,
+ char*** slst,
+ const char* word,
+ char** desc,
+ int n)
+{
+ return reinterpret_cast<HunspellImpl*>(pHunspell)->generate(slst, word, desc, n);
+}
+
+/* functions for run-time modification of the dictionary */
+
+/* add word to the run-time dictionary */
+
+int Hunspell_add(Hunhandle* pHunspell, const char* word) {
+ return reinterpret_cast<HunspellImpl*>(pHunspell)->add(word);
+}
+
+/* add word to the run-time dictionary with affix flags of
+ * the example (a dictionary word): Hunspell will recognize
+ * affixed forms of the new word, too.
+ */
+
+int Hunspell_add_with_affix(Hunhandle* pHunspell,
+ const char* word,
+ const char* example) {
+ return reinterpret_cast<HunspellImpl*>(pHunspell)->add_with_affix(word, example);
+}
+
+/* remove word from the run-time dictionary */
+
+int Hunspell_remove(Hunhandle* pHunspell, const char* word) {
+ return reinterpret_cast<HunspellImpl*>(pHunspell)->remove(word);
+}
+
+void Hunspell_free_list(Hunhandle* pHunspell, char*** list, int n) {
+ reinterpret_cast<HunspellImpl*>(pHunspell)->free_list(list, n);
+}
diff --git a/extensions/spellcheck/hunspell/src/hunspell.h b/extensions/spellcheck/hunspell/src/hunspell.h
new file mode 100644
index 0000000000..3aca30ab2f
--- /dev/null
+++ b/extensions/spellcheck/hunspell/src/hunspell.h
@@ -0,0 +1,162 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (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.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Hunspell, based on MySpell.
+ *
+ * The Initial Developers of the Original Code are
+ * Kevin Hendricks (MySpell) and N辿meth L叩szl坦 (Hunspell).
+ * Portions created by the Initial Developers are Copyright (C) 2002-2005
+ * the Initial Developers. All Rights Reserved.
+ *
+ * Contributor(s): David Einstein, Davide Prina, Giuseppe Modugno,
+ * Gianluca Turconi, Simon Brouwer, Noll J叩nos, B鱈r坦 rp叩d,
+ * Goldman Eleon坦ra, Sarl坦s Tam叩s, Bencs叩th Boldizs叩r, Hal叩csy P辿ter,
+ * Dvornik L叩szl坦, Gefferth Andr叩s, Nagy Viktor, Varga D叩niel, Chris Halls,
+ * Rene Engelhard, Bram Moolenaar, Dafydd Jones, Harri Pitk辰nen
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#ifndef MYSPELLMGR_H_
+#define MYSPELLMGR_H_
+
+#include "hunvisapi.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct Hunhandle Hunhandle;
+
+LIBHUNSPELL_DLL_EXPORTED Hunhandle* Hunspell_create(const char* affpath,
+ const char* dpath);
+
+LIBHUNSPELL_DLL_EXPORTED Hunhandle* Hunspell_create_key(const char* affpath,
+ const char* dpath,
+ const char* key);
+
+LIBHUNSPELL_DLL_EXPORTED void Hunspell_destroy(Hunhandle* pHunspell);
+
+/* load extra dictionaries (only dic files)
+ * output: 0 = additional dictionary slots available, 1 = slots are now full*/
+LIBHUNSPELL_DLL_EXPORTED int Hunspell_add_dic(Hunhandle* pHunspell,
+ const char* dpath);
+
+/* spell(word) - spellcheck word
+ * output: 0 = bad word, not 0 = good word
+ */
+LIBHUNSPELL_DLL_EXPORTED int Hunspell_spell(Hunhandle* pHunspell, const char*);
+
+LIBHUNSPELL_DLL_EXPORTED char* Hunspell_get_dic_encoding(Hunhandle* pHunspell);
+
+/* suggest(suggestions, word) - search suggestions
+ * input: pointer to an array of strings pointer and the (bad) word
+ * array of strings pointer (here *slst) may not be initialized
+ * output: number of suggestions in string array, and suggestions in
+ * a newly allocated array of strings (*slts will be NULL when number
+ * of suggestion equals 0.)
+ */
+LIBHUNSPELL_DLL_EXPORTED int Hunspell_suggest(Hunhandle* pHunspell,
+ char*** slst,
+ const char* word);
+
+/* morphological functions */
+
+/* analyze(result, word) - morphological analysis of the word */
+
+LIBHUNSPELL_DLL_EXPORTED int Hunspell_analyze(Hunhandle* pHunspell,
+ char*** slst,
+ const char* word);
+
+/* stem(result, word) - stemmer function */
+
+LIBHUNSPELL_DLL_EXPORTED int Hunspell_stem(Hunhandle* pHunspell,
+ char*** slst,
+ const char* word);
+
+/* stem(result, analysis, n) - get stems from a morph. analysis
+ * example:
+ * char ** result, result2;
+ * int n1 = Hunspell_analyze(result, "words");
+ * int n2 = Hunspell_stem2(result2, result, n1);
+ */
+
+LIBHUNSPELL_DLL_EXPORTED int Hunspell_stem2(Hunhandle* pHunspell,
+ char*** slst,
+ char** desc,
+ int n);
+
+/* generate(result, word, word2) - morphological generation by example(s) */
+
+LIBHUNSPELL_DLL_EXPORTED int Hunspell_generate(Hunhandle* pHunspell,
+ char*** slst,
+ const char* word,
+ const char* word2);
+
+/* generate(result, word, desc, n) - generation by morph. description(s)
+ * example:
+ * char ** result;
+ * char * affix = "is:plural"; // description depends from dictionaries, too
+ * int n = Hunspell_generate2(result, "word", &affix, 1);
+ * for (int i = 0; i < n; i++) printf("%s\n", result[i]);
+ */
+
+LIBHUNSPELL_DLL_EXPORTED int Hunspell_generate2(Hunhandle* pHunspell,
+ char*** slst,
+ const char* word,
+ char** desc,
+ int n);
+
+/* functions for run-time modification of the dictionary */
+
+/* add word to the run-time dictionary */
+
+LIBHUNSPELL_DLL_EXPORTED int Hunspell_add(Hunhandle* pHunspell,
+ const char* word);
+
+/* add word to the run-time dictionary with affix flags of
+ * the example (a dictionary word): Hunspell will recognize
+ * affixed forms of the new word, too.
+ */
+
+LIBHUNSPELL_DLL_EXPORTED int Hunspell_add_with_affix(Hunhandle* pHunspell,
+ const char* word,
+ const char* example);
+
+/* remove word from the run-time dictionary */
+
+LIBHUNSPELL_DLL_EXPORTED int Hunspell_remove(Hunhandle* pHunspell,
+ const char* word);
+
+/* free suggestion lists */
+
+LIBHUNSPELL_DLL_EXPORTED void Hunspell_free_list(Hunhandle* pHunspell,
+ char*** slst,
+ int n);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/extensions/spellcheck/hunspell/src/hunspell.hxx b/extensions/spellcheck/hunspell/src/hunspell.hxx
new file mode 100644
index 0000000000..8640a35ca1
--- /dev/null
+++ b/extensions/spellcheck/hunspell/src/hunspell.hxx
@@ -0,0 +1,232 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * Copyright (C) 2002-2022 N辿meth L叩szl坦
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (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.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * Hunspell is based on MySpell which is Copyright (C) 2002 Kevin Hendricks.
+ *
+ * Contributor(s): David Einstein, Davide Prina, Giuseppe Modugno,
+ * Gianluca Turconi, Simon Brouwer, Noll J叩nos, B鱈r坦 rp叩d,
+ * Goldman Eleon坦ra, Sarl坦s Tam叩s, Bencs叩th Boldizs叩r, Hal叩csy P辿ter,
+ * Dvornik L叩szl坦, Gefferth Andr叩s, Nagy Viktor, Varga D叩niel, Chris Halls,
+ * Rene Engelhard, Bram Moolenaar, Dafydd Jones, Harri Pitk辰nen
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+/*
+ * Copyright 2002 Kevin B. Hendricks, Stratford, Ontario, Canada
+ * And Contributors. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. All modifications to the source code must be clearly marked as
+ * such. Binary redistributions based on modified source code
+ * must be clearly marked as modified versions in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY KEVIN B. HENDRICKS AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
+ * KEVIN B. HENDRICKS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+#ifndef MYSPELLMGR_HXX_
+#define MYSPELLMGR_HXX_
+
+#include "hunvisapi.h"
+#include "w_char.hxx"
+#include "atypes.hxx"
+#include <string>
+#include <vector>
+
+#define SPELL_XML "<?xml?>"
+
+#ifndef MAXSUGGESTION
+#define MAXSUGGESTION 15
+#endif
+
+#define MAXSHARPS 5
+
+#ifndef MAXWORDLEN
+#define MAXWORDLEN 100
+#endif
+
+#if defined __GNUC__ && (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1))
+# define H_DEPRECATED __attribute__((__deprecated__))
+#elif defined(_MSC_VER) && (_MSC_VER >= 1300)
+# define H_DEPRECATED __declspec(deprecated)
+#else
+# define H_DEPRECATED
+#endif
+
+class HunspellImpl;
+
+class LIBHUNSPELL_DLL_EXPORTED Hunspell {
+ private:
+ Hunspell(const Hunspell&);
+ Hunspell& operator=(const Hunspell&);
+
+ private:
+ HunspellImpl* m_Impl;
+
+ public:
+ /* Hunspell(aff, dic) - constructor of Hunspell class
+ * input: path of affix file and dictionary file
+ *
+ * In WIN32 environment, use UTF-8 encoded paths started with the long path
+ * prefix \\\\?\\ to handle system-independent character encoding and very
+ * long path names (without the long path prefix Hunspell will use fopen()
+ * with system-dependent character encoding instead of _wfopen()).
+ */
+ Hunspell(const char* affpath, const char* dpath, const char* key = NULL);
+ ~Hunspell();
+
+ /* load extra dictionaries (only dic files) */
+ int add_dic(const char* dpath, const char* key = NULL);
+
+ /* spell(word) - spellcheck word
+ * output: false = bad word, true = good word
+ *
+ * plus output:
+ * info: information bit array, fields:
+ * SPELL_COMPOUND = a compound word
+ * SPELL_FORBIDDEN = an explicit forbidden word
+ * root: root (stem), when input is a word with affix(es)
+ */
+ bool spell(const std::string& word, int* info = NULL, std::string* root = NULL);
+ H_DEPRECATED int spell(const char* word, int* info = NULL, char** root = NULL);
+
+ /* suggest(suggestions, word) - search suggestions
+ * input: pointer to an array of strings pointer and the (bad) word
+ * array of strings pointer (here *slst) may not be initialized
+ * output: number of suggestions in string array, and suggestions in
+ * a newly allocated array of strings (*slts will be NULL when number
+ * of suggestion equals 0.)
+ */
+ std::vector<std::string> suggest(const std::string& word);
+ H_DEPRECATED int suggest(char*** slst, const char* word);
+
+ /* Suggest words from suffix rules
+ * suffix_suggest(suggestions, root_word)
+ * input: pointer to an array of strings pointer and the word
+ * array of strings pointer (here *slst) may not be initialized
+ * output: number of suggestions in string array, and suggestions in
+ * a newly allocated array of strings (*slts will be NULL when number
+ * of suggestion equals 0.)
+ */
+ std::vector<std::string> suffix_suggest(const std::string& root_word);
+ H_DEPRECATED int suffix_suggest(char*** slst, const char* root_word);
+
+ /* deallocate suggestion lists */
+ H_DEPRECATED void free_list(char*** slst, int n);
+
+ const std::string& get_dict_encoding() const;
+ char* get_dic_encoding();
+
+ /* morphological functions */
+
+ /* analyze(result, word) - morphological analysis of the word */
+ std::vector<std::string> analyze(const std::string& word);
+ H_DEPRECATED int analyze(char*** slst, const char* word);
+
+ /* stem(word) - stemmer function */
+ std::vector<std::string> stem(const std::string& word);
+ H_DEPRECATED int stem(char*** slst, const char* word);
+
+ /* stem(analysis, n) - get stems from a morph. analysis
+ * example:
+ * char ** result, result2;
+ * int n1 = analyze(&result, "words");
+ * int n2 = stem(&result2, result, n1);
+ */
+ std::vector<std::string> stem(const std::vector<std::string>& morph);
+ H_DEPRECATED int stem(char*** slst, char** morph, int n);
+
+ /* generate(result, word, word2) - morphological generation by example(s) */
+ std::vector<std::string> generate(const std::string& word, const std::string& word2);
+ H_DEPRECATED int generate(char*** slst, const char* word, const char* word2);
+
+ /* generate(result, word, desc, n) - generation by morph. description(s)
+ * example:
+ * char ** result;
+ * char * affix = "is:plural"; // description depends from dictionaries, too
+ * int n = generate(&result, "word", &affix, 1);
+ * for (int i = 0; i < n; i++) printf("%s\n", result[i]);
+ */
+ std::vector<std::string> generate(const std::string& word, const std::vector<std::string>& pl);
+ H_DEPRECATED int generate(char*** slst, const char* word, char** desc, int n);
+
+ /* functions for run-time modification of the dictionary */
+
+ /* add word to the run-time dictionary */
+
+ int add(const std::string& word);
+
+ /* add word to the run-time dictionary with affix flags of
+ * the example (a dictionary word): Hunspell will recognize
+ * affixed forms of the new word, too.
+ */
+
+ int add_with_affix(const std::string& word, const std::string& example);
+
+ /* remove word from the run-time dictionary */
+
+ int remove(const std::string& word);
+
+ /* other */
+
+ /* get extra word characters definied in affix file for tokenization */
+ const char* get_wordchars() const;
+ const std::string& get_wordchars_cpp() const;
+ const std::vector<w_char>& get_wordchars_utf16() const;
+
+ struct cs_info* get_csconv();
+
+ const char* get_version() const;
+ const std::string& get_version_cpp() const;
+
+ int get_langnum() const;
+
+ /* need for putdic */
+ bool input_conv(const std::string& word, std::string& dest);
+ H_DEPRECATED int input_conv(const char* word, char* dest, size_t destsize);
+};
+
+#endif
diff --git a/extensions/spellcheck/hunspell/src/hunvisapi.h b/extensions/spellcheck/hunspell/src/hunvisapi.h
new file mode 100644
index 0000000000..ed0a502ba2
--- /dev/null
+++ b/extensions/spellcheck/hunspell/src/hunvisapi.h
@@ -0,0 +1,18 @@
+#ifndef HUNSPELL_VISIBILITY_H_
+#define HUNSPELL_VISIBILITY_H_
+
+#if defined(HUNSPELL_STATIC)
+# define LIBHUNSPELL_DLL_EXPORTED
+#elif defined(_WIN32)
+# if defined(BUILDING_LIBHUNSPELL)
+# define LIBHUNSPELL_DLL_EXPORTED __declspec(dllexport)
+# else
+# define LIBHUNSPELL_DLL_EXPORTED __declspec(dllimport)
+# endif
+#elif defined(BUILDING_LIBHUNSPELL) && 1
+# define LIBHUNSPELL_DLL_EXPORTED __attribute__((__visibility__("default")))
+#else
+# define LIBHUNSPELL_DLL_EXPORTED
+#endif
+
+#endif
diff --git a/extensions/spellcheck/hunspell/src/langnum.hxx b/extensions/spellcheck/hunspell/src/langnum.hxx
new file mode 100644
index 0000000000..39e63efdaa
--- /dev/null
+++ b/extensions/spellcheck/hunspell/src/langnum.hxx
@@ -0,0 +1,76 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * Copyright (C) 2002-2022 N辿meth L叩szl坦
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (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.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * Hunspell is based on MySpell which is Copyright (C) 2002 Kevin Hendricks.
+ *
+ * Contributor(s): David Einstein, Davide Prina, Giuseppe Modugno,
+ * Gianluca Turconi, Simon Brouwer, Noll J叩nos, B鱈r坦 rp叩d,
+ * Goldman Eleon坦ra, Sarl坦s Tam叩s, Bencs叩th Boldizs叩r, Hal叩csy P辿ter,
+ * Dvornik L叩szl坦, Gefferth Andr叩s, Nagy Viktor, Varga D叩niel, Chris Halls,
+ * Rene Engelhard, Bram Moolenaar, Dafydd Jones, Harri Pitk辰nen
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#ifndef LANGNUM_HXX_
+#define LANGNUM_HXX_
+
+/*
+ language numbers for language specific codes
+ see https://wiki.openoffice.org/w/index.php?title=Languages&oldid=230199
+*/
+
+enum {
+ LANG_ar = 96,
+ LANG_az = 100, // custom number
+ LANG_bg = 41,
+ LANG_ca = 37,
+ LANG_crh = 102, // custom number
+ LANG_cs = 42,
+ LANG_da = 45,
+ LANG_de = 49,
+ LANG_el = 30,
+ LANG_en = 01,
+ LANG_es = 34,
+ LANG_eu = 10,
+ LANG_fr = 02,
+ LANG_gl = 38,
+ LANG_hr = 78,
+ LANG_hu = 36,
+ LANG_it = 39,
+ LANG_la = 99, // custom number
+ LANG_lv = 101, // custom number
+ LANG_nl = 31,
+ LANG_pl = 48,
+ LANG_pt = 03,
+ LANG_ru = 07,
+ LANG_sv = 50,
+ LANG_tr = 90,
+ LANG_uk = 80,
+ LANG_xx = 999
+};
+
+#endif
diff --git a/extensions/spellcheck/hunspell/src/license.hunspell b/extensions/spellcheck/hunspell/src/license.hunspell
new file mode 100644
index 0000000000..fad5a16230
--- /dev/null
+++ b/extensions/spellcheck/hunspell/src/license.hunspell
@@ -0,0 +1,54 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * Copyright (C) 2002-2022 N辿meth L叩szl坦
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (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.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * Hunspell is based on MySpell which is Copyright (C) 2002 Kevin Hendricks.
+ *
+ * Contributor(s):
+ * David Einstein
+ * Davide Prina
+ * Giuseppe Modugno
+ * Gianluca Turconi
+ * Simon Brouwer
+ * Noll J叩nos
+ * B鱈r坦 rp叩d
+ * Goldman Eleon坦ra
+ * Sarl坦s Tam叩s
+ * Bencs叩th Boldizs叩r
+ * Hal叩csy P辿ter
+ * Dvornik L叩szl坦
+ * Gefferth Andr叩s
+ * Nagy Viktor
+ * Varga D叩niel
+ * Chris Halls
+ * Rene Engelhard
+ * Bram Moolenaar
+ * Dafydd Jones
+ * Harri Pitk辰nen
+ * Andras Timar
+ * Tor Lillqvist
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
diff --git a/extensions/spellcheck/hunspell/src/license.myspell b/extensions/spellcheck/hunspell/src/license.myspell
new file mode 100644
index 0000000000..2da5330750
--- /dev/null
+++ b/extensions/spellcheck/hunspell/src/license.myspell
@@ -0,0 +1,61 @@
+/*
+ * Copyright 2002 Kevin B. Hendricks, Stratford, Ontario, Canada
+ * And Contributors. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. All modifications to the source code must be clearly marked as
+ * such. Binary redistributions based on modified source code
+ * must be clearly marked as modified versions in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY KEVIN B. HENDRICKS AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
+ * KEVIN B. HENDRICKS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ *
+ * NOTE: A special thanks and credit goes to Geoff Kuenning
+ * the creator of ispell. MySpell's affix algorithms were
+ * based on those of ispell which should be noted is
+ * copyright Geoff Kuenning et.al. and now available
+ * under a BSD style license. For more information on ispell
+ * and affix compression in general, please see:
+ * http://www.cs.ucla.edu/ficus-members/geoff/ispell.html
+ * (the home page for ispell)
+ *
+ * An almost complete rewrite of MySpell for use by
+ * the Mozilla project has been developed by David Einstein
+ * (Deinst@world.std.com). David and I are now
+ * working on parallel development tracks to help
+ * our respective projects (Mozilla and OpenOffice.org
+ * and we will maintain full affix file and dictionary
+ * file compatibility and work on merging our versions
+ * of MySpell back into a single tree. David has been
+ * a significant help in improving MySpell.
+ *
+ * Special thanks also go to La'szlo' Ne'meth
+ * <nemethl@gyorsposta.hu> who is the author of the
+ * Hungarian dictionary and who developed and contributed
+ * the code to support compound words in MySpell
+ * and fixed numerous problems with the encoding
+ * case conversion tables.
+ *
+ */
diff --git a/extensions/spellcheck/hunspell/src/moz.build b/extensions/spellcheck/hunspell/src/moz.build
new file mode 100644
index 0000000000..c6f7930262
--- /dev/null
+++ b/extensions/spellcheck/hunspell/src/moz.build
@@ -0,0 +1,30 @@
+# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
+# vim: set filetype=python:
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+include("sources.mozbuild")
+
+UNIFIED_SOURCES += hunspell_sources
+
+DEFINES['HUNSPELL_STATIC'] = True
+
+FINAL_LIBRARY = 'xul'
+
+LOCAL_INCLUDES += [
+ '../glue',
+]
+
+# We allow warnings for third-party code that can be updated from upstream.
+AllowCompilerWarnings()
+
+include('/ipc/chromium/chromium-config.mozbuild')
+include('../glue/common.mozbuild')
+
+HunspellIncludes()
+
+if CONFIG['CC_TYPE'] in ('clang', 'clang-cl'):
+ CXXFLAGS += [
+ '-Wno-implicit-fallthrough',
+ ]
diff --git a/extensions/spellcheck/hunspell/src/moz.yaml b/extensions/spellcheck/hunspell/src/moz.yaml
new file mode 100644
index 0000000000..64987b4100
--- /dev/null
+++ b/extensions/spellcheck/hunspell/src/moz.yaml
@@ -0,0 +1,16 @@
+# Version of this schema
+schema: 1
+
+bugzilla:
+ product: "Core"
+ component: "Spelling checker"
+
+origin:
+ name: "Hunspell"
+ description: "Spell Checker"
+
+ url: "http://hunspell.github.io/"
+ license: "MPL-1.1"
+ license-file: "COPYING.MPL"
+
+ release: "1.7.0"
diff --git a/extensions/spellcheck/hunspell/src/phonet.cxx b/extensions/spellcheck/hunspell/src/phonet.cxx
new file mode 100644
index 0000000000..69601a2872
--- /dev/null
+++ b/extensions/spellcheck/hunspell/src/phonet.cxx
@@ -0,0 +1,270 @@
+/* phonetic.c - generic replacement aglogithms for phonetic transformation
+ Copyright (C) 2000 Bjoern Jacke
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License version 2.1 as published by the Free Software Foundation;
+
+ This library 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 this library; If not, see
+ <http://www.gnu.org/licenses/>.
+
+ Changelog:
+
+ 2000-01-05 Bjoern Jacke <bjoern at j3e.de>
+ Initial Release insprired by the article about phonetic
+ transformations out of c't 25/1999
+
+ 2007-07-26 Bjoern Jacke <bjoern at j3e.de>
+ Released under MPL/GPL/LGPL tri-license for Hunspell
+
+ 2007-08-23 Laszlo Nemeth <nemeth at OOo>
+ Porting from Aspell to Hunspell using C-like structs
+*/
+
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+#include <ctype.h>
+
+#include "csutil.hxx"
+#include "phonet.hxx"
+
+void init_phonet_hash(phonetable& parms) {
+ for (int i = 0; i < HASHSIZE; i++) {
+ parms.hash[i] = -1;
+ }
+
+ for (int i = 0; parms.rules[i][0] != '\0'; i += 2) {
+ /** set hash value **/
+ int k = (unsigned char)parms.rules[i][0];
+
+ if (parms.hash[k] < 0) {
+ parms.hash[k] = i;
+ }
+ }
+}
+
+// like strcpy but safe if the strings overlap
+// but only if dest < src
+static inline void strmove(char* dest, char* src) {
+ while (*src)
+ *dest++ = *src++;
+ *dest = '\0';
+}
+
+static int myisalpha(char ch) {
+ if ((unsigned char)ch < 128)
+ return isalpha(ch);
+ return 1;
+}
+
+/* Do phonetic transformation. */
+/* phonetic transcription algorithm */
+/* see: http://aspell.net/man-html/Phonetic-Code.html */
+/* convert string to uppercase before this call */
+std::string phonet(const std::string& inword, phonetable& parms) {
+
+ int i, k = 0, p, z;
+ int k0, n0, p0 = -333;
+ char c;
+ typedef unsigned char uchar;
+
+ size_t len = inword.size();
+ if (len > MAXPHONETUTF8LEN)
+ return std::string();
+ char word[MAXPHONETUTF8LEN + 1];
+ strncpy(word, inword.c_str(), MAXPHONETUTF8LEN);
+ word[MAXPHONETUTF8LEN] = '\0';
+
+ std::string target;
+ /** check word **/
+ i = z = 0;
+ while ((c = word[i]) != '\0') {
+ int n = parms.hash[(uchar)c];
+ int z0 = 0;
+
+ if (n >= 0 && !parms.rules[n].empty()) {
+ /** check all rules for the same letter **/
+ while (parms.rules[n][0] == c) {
+ /** check whole string **/
+ k = 1; /** number of found letters **/
+ p = 5; /** default priority **/
+ const char*s = parms.rules[n].c_str();
+ s++; /** important for (see below) "*(s-1)" **/
+
+ while (*s != '\0' && word[i + k] == *s && !isdigit((unsigned char)*s) &&
+ strchr("(-<^$", *s) == NULL) {
+ k++;
+ s++;
+ }
+ if (*s == '(') {
+ /** check letters in "(..)" **/
+ if (myisalpha(word[i + k]) // ...could be implied?
+ && strchr(s + 1, word[i + k]) != NULL) {
+ k++;
+ while (*s != ')')
+ s++;
+ s++;
+ }
+ }
+ p0 = (int)*s;
+ k0 = k;
+ while (*s == '-' && k > 1) {
+ k--;
+ s++;
+ }
+ if (*s == '<')
+ s++;
+ if (isdigit((unsigned char)*s)) {
+ /** determine priority **/
+ p = *s - '0';
+ s++;
+ }
+ if (*s == '^' && *(s + 1) == '^')
+ s++;
+
+ if (*s == '\0' || (*s == '^' && (i == 0 || !myisalpha(word[i - 1])) &&
+ (*(s + 1) != '$' || (!myisalpha(word[i + k0])))) ||
+ (*s == '$' && i > 0 && myisalpha(word[i - 1]) &&
+ (!myisalpha(word[i + k0])))) {
+ /** search for followup rules, if: **/
+ /** parms.followup and k > 1 and NO '-' in searchstring **/
+ char c0 = word[i + k - 1];
+ n0 = parms.hash[(uchar)c0];
+
+ // if (parms.followup && k > 1 && n0 >= 0
+ if (k > 1 && n0 >= 0 && p0 != (int)'-' && word[i + k] != '\0' && !parms.rules[n0].empty()) {
+ /** test follow-up rule for "word[i+k]" **/
+ while (parms.rules[n0][0] == c0) {
+ /** check whole string **/
+ k0 = k;
+ p0 = 5;
+ s = parms.rules[n0].c_str();
+ s++;
+ while (*s != '\0' && word[i + k0] == *s &&
+ !isdigit((unsigned char)*s) &&
+ strchr("(-<^$", *s) == NULL) {
+ k0++;
+ s++;
+ }
+ if (*s == '(') {
+ /** check letters **/
+ if (myisalpha(word[i + k0]) &&
+ strchr(s + 1, word[i + k0]) != NULL) {
+ k0++;
+ while (*s != ')' && *s != '\0')
+ s++;
+ if (*s == ')')
+ s++;
+ }
+ }
+ while (*s == '-') {
+ /** "k0" gets NOT reduced **/
+ /** because "if (k0 == k)" **/
+ s++;
+ }
+ if (*s == '<')
+ s++;
+ if (isdigit((unsigned char)*s)) {
+ p0 = *s - '0';
+ s++;
+ }
+
+ if (*s == '\0'
+ /** *s == '^' cuts **/
+ || (*s == '$' && !myisalpha(word[i + k0]))) {
+ if (k0 == k) {
+ /** this is just a piece of the string **/
+ n0 += 2;
+ continue;
+ }
+
+ if (p0 < p) {
+ /** priority too low **/
+ n0 += 2;
+ continue;
+ }
+ /** rule fits; stop search **/
+ break;
+ }
+ n0 += 2;
+ } /** End of "while (parms.rules[n0][0] == c0)" **/
+
+ if (p0 >= p && parms.rules[n0][0] == c0) {
+ n += 2;
+ continue;
+ }
+ } /** end of follow-up stuff **/
+
+ /** replace string **/
+ s = parms.rules[n + 1].c_str();
+ p0 = (!parms.rules[n].empty() &&
+ strchr(parms.rules[n].c_str() + 1, '<') != NULL)
+ ? 1
+ : 0;
+ if (p0 == 1 && z == 0) {
+ /** rule with '<' is used **/
+ if (!target.empty() && *s != '\0' &&
+ (target[target.size()-1] == c || target[target.size()-1] == *s)) {
+ target.erase(target.size() - 1);
+ }
+ z0 = 1;
+ z = 1;
+ k0 = 0;
+ while (*s != '\0' && word[i + k0] != '\0') {
+ word[i + k0] = *s;
+ k0++;
+ s++;
+ }
+ if (k > k0)
+ strmove(&word[0] + i + k0, &word[0] + i + k);
+
+ /** new "actual letter" **/
+ c = word[i];
+ } else { /** no '<' rule used **/
+ i += k - 1;
+ z = 0;
+ while (*s != '\0' && *(s + 1) != '\0' && target.size() < len) {
+ if (target.empty() || target[target.size()-1] != *s) {
+ target.push_back(*s);
+ }
+ s++;
+ }
+ /** new "actual letter" **/
+ c = *s;
+ if (!parms.rules[n].empty() &&
+ strstr(parms.rules[n].c_str() + 1, "^^") != NULL) {
+ if (c != '\0') {
+ target.push_back(c);
+ }
+ strmove(&word[0], &word[0] + i + 1);
+ i = 0;
+ z0 = 1;
+ }
+ }
+ break;
+ } /** end of follow-up stuff **/
+ n += 2;
+ } /** end of while (parms.rules[n][0] == c) **/
+ } /** end of if (n >= 0) **/
+ if (z0 == 0) {
+ if (k && !p0 && target.size() < len && c != '\0') {
+ /** condense only double letters **/
+ target.push_back(c);
+ /// printf("\n setting \n");
+ }
+
+ i++;
+ z = 0;
+ k = 0;
+ }
+ } /** end of while ((c = word[i]) != '\0') **/
+
+ return target;
+} /** end of function "phonet" **/
diff --git a/extensions/spellcheck/hunspell/src/phonet.hxx b/extensions/spellcheck/hunspell/src/phonet.hxx
new file mode 100644
index 0000000000..2d58b3ba1b
--- /dev/null
+++ b/extensions/spellcheck/hunspell/src/phonet.hxx
@@ -0,0 +1,50 @@
+/* phonetic.c - generic replacement aglogithms for phonetic transformation
+ Copyright (C) 2000 Bjoern Jacke
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License version 2.1 as published by the Free Software Foundation;
+
+ This library 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 this library; If not, see
+ <http://www.gnu.org/licenses/>.
+
+ Changelog:
+
+ 2000-01-05 Bjoern Jacke <bjoern at j3e.de>
+ Initial Release insprired by the article about phonetic
+ transformations out of c't 25/1999
+
+ 2007-07-26 Bjoern Jacke <bjoern at j3e.de>
+ Released under MPL/GPL/LGPL tri-license for Hunspell
+
+ 2007-08-23 Laszlo Nemeth <nemeth at OOo>
+ Porting from Aspell to Hunspell using C-like structs
+*/
+
+#ifndef PHONET_HXX_
+#define PHONET_HXX_
+
+#define HASHSIZE 256
+#define MAXPHONETLEN 256
+#define MAXPHONETUTF8LEN (MAXPHONETLEN * 4)
+
+#include "hunvisapi.h"
+
+struct phonetable {
+ char utf8;
+ std::vector<std::string> rules;
+ int hash[HASHSIZE];
+};
+
+LIBHUNSPELL_DLL_EXPORTED void init_phonet_hash(phonetable& parms);
+
+LIBHUNSPELL_DLL_EXPORTED std::string phonet(const std::string& inword,
+ phonetable& phone);
+
+#endif
diff --git a/extensions/spellcheck/hunspell/src/replist.cxx b/extensions/spellcheck/hunspell/src/replist.cxx
new file mode 100644
index 0000000000..1395ade607
--- /dev/null
+++ b/extensions/spellcheck/hunspell/src/replist.cxx
@@ -0,0 +1,196 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * Copyright (C) 2002-2022 N辿meth L叩szl坦
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (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.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * Hunspell is based on MySpell which is Copyright (C) 2002 Kevin Hendricks.
+ *
+ * Contributor(s): David Einstein, Davide Prina, Giuseppe Modugno,
+ * Gianluca Turconi, Simon Brouwer, Noll J叩nos, B鱈r坦 rp叩d,
+ * Goldman Eleon坦ra, Sarl坦s Tam叩s, Bencs叩th Boldizs叩r, Hal叩csy P辿ter,
+ * Dvornik L叩szl坦, Gefferth Andr叩s, Nagy Viktor, Varga D叩niel, Chris Halls,
+ * Rene Engelhard, Bram Moolenaar, Dafydd Jones, Harri Pitk辰nen
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+/*
+ * Copyright 2002 Kevin B. Hendricks, Stratford, Ontario, Canada
+ * And Contributors. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. All modifications to the source code must be clearly marked as
+ * such. Binary redistributions based on modified source code
+ * must be clearly marked as modified versions in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY KEVIN B. HENDRICKS AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
+ * KEVIN B. HENDRICKS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+#include <limits>
+
+#include "replist.hxx"
+#include "csutil.hxx"
+
+RepList::RepList(int n) {
+ dat = (replentry**)malloc(sizeof(replentry*) * n);
+ if (dat == 0)
+ size = 0;
+ else
+ size = n;
+ pos = 0;
+}
+
+RepList::~RepList() {
+ for (int i = 0; i < pos; i++) {
+ delete dat[i];
+ }
+ free(dat);
+}
+
+replentry* RepList::item(int n) {
+ return dat[n];
+}
+
+int RepList::find(const char* word) {
+ int p1 = 0;
+ int p2 = pos - 1;
+ int ret = -1;
+ while (p1 <= p2) {
+ int m = ((unsigned)p1 + (unsigned)p2) >> 1;
+ int c = strncmp(word, dat[m]->pattern.c_str(), dat[m]->pattern.size());
+ if (c < 0)
+ p2 = m - 1;
+ else if (c > 0)
+ p1 = m + 1;
+ else { // scan in the right half for a longer match
+ ret = m;
+ p1 = m + 1;
+ }
+ }
+ return ret;
+}
+
+std::string RepList::replace(const char* word, int ind, bool atstart) {
+ int type = atstart ? 1 : 0;
+ if (ind < 0)
+ return std::string();
+ if (strlen(word) == dat[ind]->pattern.size())
+ type = atstart ? 3 : 2;
+ while (type && dat[ind]->outstrings[type].empty())
+ type = (type == 2 && !atstart) ? 0 : type - 1;
+ return dat[ind]->outstrings[type];
+}
+
+int RepList::add(const std::string& in_pat1, const std::string& pat2) {
+ if (pos >= size || in_pat1.empty() || pat2.empty()) {
+ return 1;
+ }
+ // analyse word context
+ int type = 0;
+ std::string pat1(in_pat1);
+ if (pat1[0] == '_') {
+ pat1.erase(0, 1);
+ type = 1;
+ }
+ if (!pat1.empty() && pat1[pat1.size() - 1] == '_') {
+ type = type + 2;
+ pat1.erase(pat1.size() - 1);
+ }
+ mystrrep(pat1, "_", " ");
+
+ // find existing entry
+ int m = find(pat1.c_str());
+ if (m >= 0 && dat[m]->pattern == pat1) {
+ // since already used
+ dat[m]->outstrings[type] = pat2;
+ mystrrep(dat[m]->outstrings[type], "_", " ");
+ return 0;
+ }
+
+ // make a new entry if none exists
+ replentry* r = new replentry;
+ if (r == NULL)
+ return 1;
+ r->pattern = pat1;
+ r->outstrings[type] = pat2;
+ mystrrep(r->outstrings[type], "_", " ");
+ dat[pos++] = r;
+ // sort to the right place in the list
+ int i;
+ for (i = pos - 1; i > 0; i--) {
+ if (strcmp(r->pattern.c_str(), dat[i - 1]->pattern.c_str()) < 0) {
+ dat[i] = dat[i - 1];
+ } else
+ break;
+ }
+ dat[i] = r;
+ return 0;
+}
+
+bool RepList::conv(const std::string& in_word, std::string& dest) {
+ dest.clear();
+
+ size_t wordlen = in_word.size();
+ const char* word = in_word.c_str();
+
+ bool change = false;
+ for (size_t i = 0; i < wordlen; ++i) {
+ int n = find(word + i);
+ std::string l = replace(word + i, n, i == 0);
+ if (!l.empty()) {
+ dest.append(l);
+ i += dat[n]->pattern.size() - 1;
+ change = true;
+ } else {
+ dest.push_back(word[i]);
+ }
+ }
+
+ return change;
+}
+
diff --git a/extensions/spellcheck/hunspell/src/replist.hxx b/extensions/spellcheck/hunspell/src/replist.hxx
new file mode 100644
index 0000000000..08daeb4488
--- /dev/null
+++ b/extensions/spellcheck/hunspell/src/replist.hxx
@@ -0,0 +1,100 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * Copyright (C) 2002-2022 N辿meth L叩szl坦
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (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.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * Hunspell is based on MySpell which is Copyright (C) 2002 Kevin Hendricks.
+ *
+ * Contributor(s): David Einstein, Davide Prina, Giuseppe Modugno,
+ * Gianluca Turconi, Simon Brouwer, Noll J叩nos, B鱈r坦 rp叩d,
+ * Goldman Eleon坦ra, Sarl坦s Tam叩s, Bencs叩th Boldizs叩r, Hal叩csy P辿ter,
+ * Dvornik L叩szl坦, Gefferth Andr叩s, Nagy Viktor, Varga D叩niel, Chris Halls,
+ * Rene Engelhard, Bram Moolenaar, Dafydd Jones, Harri Pitk辰nen
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+/*
+ * Copyright 2002 Kevin B. Hendricks, Stratford, Ontario, Canada
+ * And Contributors. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. All modifications to the source code must be clearly marked as
+ * such. Binary redistributions based on modified source code
+ * must be clearly marked as modified versions in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY KEVIN B. HENDRICKS AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
+ * KEVIN B. HENDRICKS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/* string replacement list class */
+#ifndef REPLIST_HXX_
+#define REPLIST_HXX_
+
+#include "w_char.hxx"
+
+#include <string>
+#include <vector>
+
+class RepList {
+ private:
+ RepList(const RepList&);
+ RepList& operator=(const RepList&);
+
+ protected:
+ replentry** dat;
+ int size;
+ int pos;
+
+ public:
+ explicit RepList(int n);
+ ~RepList();
+
+ int add(const std::string& pat1, const std::string& pat2);
+ replentry* item(int n);
+ int find(const char* word);
+ std::string replace(const char* word, int n, bool atstart);
+ bool conv(const std::string& word, std::string& dest);
+};
+#endif
diff --git a/extensions/spellcheck/hunspell/src/sources.mozbuild b/extensions/spellcheck/hunspell/src/sources.mozbuild
new file mode 100644
index 0000000000..6649bedb1f
--- /dev/null
+++ b/extensions/spellcheck/hunspell/src/sources.mozbuild
@@ -0,0 +1,17 @@
+# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
+# vim: set filetype=python:
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+hunspell_sources = [
+ '../glue/mozHunspellRLBoxSandbox.cpp',
+ 'affentry.cxx',
+ 'affixmgr.cxx',
+ 'csutil.cxx',
+ 'hashmgr.cxx',
+ 'hunspell.cxx',
+ 'phonet.cxx',
+ 'replist.cxx',
+ 'suggestmgr.cxx',
+]
diff --git a/extensions/spellcheck/hunspell/src/suggestmgr.cxx b/extensions/spellcheck/hunspell/src/suggestmgr.cxx
new file mode 100644
index 0000000000..6b363debd5
--- /dev/null
+++ b/extensions/spellcheck/hunspell/src/suggestmgr.cxx
@@ -0,0 +1,2263 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * Copyright (C) 2002-2022 N辿meth L叩szl坦
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (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.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * Hunspell is based on MySpell which is Copyright (C) 2002 Kevin Hendricks.
+ *
+ * Contributor(s): David Einstein, Davide Prina, Giuseppe Modugno,
+ * Gianluca Turconi, Simon Brouwer, Noll J叩nos, B鱈r坦 rp叩d,
+ * Goldman Eleon坦ra, Sarl坦s Tam叩s, Bencs叩th Boldizs叩r, Hal叩csy P辿ter,
+ * Dvornik L叩szl坦, Gefferth Andr叩s, Nagy Viktor, Varga D叩niel, Chris Halls,
+ * Rene Engelhard, Bram Moolenaar, Dafydd Jones, Harri Pitk辰nen
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+/*
+ * Copyright 2002 Kevin B. Hendricks, Stratford, Ontario, Canada
+ * And Contributors. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. All modifications to the source code must be clearly marked as
+ * such. Binary redistributions based on modified source code
+ * must be clearly marked as modified versions in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY KEVIN B. HENDRICKS AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
+ * KEVIN B. HENDRICKS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+#include <ctype.h>
+#include <time.h>
+
+#include "suggestmgr.hxx"
+#include "htypes.hxx"
+#include "csutil.hxx"
+
+const w_char W_VLINE = {'\0', '|'};
+
+#define MAX_CHAR_DISTANCE 4
+
+SuggestMgr::SuggestMgr(const char* tryme, unsigned int maxn, AffixMgr* aptr) {
+ // register affix manager and check in string of chars to
+ // try when building candidate suggestions
+ pAMgr = aptr;
+
+ csconv = NULL;
+
+ ckeyl = 0;
+ ckey = NULL;
+
+ ctryl = 0;
+ ctry = NULL;
+
+ utf8 = 0;
+ langnum = 0;
+ complexprefixes = 0;
+
+ maxSug = maxn;
+ nosplitsugs = 0;
+ maxngramsugs = MAXNGRAMSUGS;
+ maxcpdsugs = MAXCOMPOUNDSUGS;
+
+ if (pAMgr) {
+ langnum = pAMgr->get_langnum();
+ ckey = pAMgr->get_key_string();
+ nosplitsugs = pAMgr->get_nosplitsugs();
+ if (pAMgr->get_maxngramsugs() >= 0)
+ maxngramsugs = pAMgr->get_maxngramsugs();
+ utf8 = pAMgr->get_utf8();
+ if (pAMgr->get_maxcpdsugs() >= 0)
+ maxcpdsugs = pAMgr->get_maxcpdsugs();
+ if (!utf8) {
+ csconv = get_current_cs(pAMgr->get_encoding());
+ }
+ complexprefixes = pAMgr->get_complexprefixes();
+ }
+
+ if (ckey) {
+ if (utf8) {
+ ckeyl = u8_u16(ckey_utf, ckey);
+ } else {
+ ckeyl = strlen(ckey);
+ }
+ }
+
+ if (tryme) {
+ ctry = mystrdup(tryme);
+ if (ctry)
+ ctryl = strlen(ctry);
+ if (ctry && utf8) {
+ ctryl = u8_u16(ctry_utf, tryme);
+ }
+ }
+
+ // language with possible dash usage
+ // (latin letters or dash in TRY characters)
+ lang_with_dash_usage = (ctry &&
+ ((strchr(ctry, '-') != NULL) || (strchr(ctry, 'a') != NULL)));
+}
+
+SuggestMgr::~SuggestMgr() {
+ pAMgr = NULL;
+ if (ckey)
+ free(ckey);
+ ckey = NULL;
+ ckeyl = 0;
+ if (ctry)
+ free(ctry);
+ ctry = NULL;
+ ctryl = 0;
+ maxSug = 0;
+#ifdef MOZILLA_CLIENT
+ delete[] csconv;
+#endif
+}
+
+void SuggestMgr::testsug(std::vector<std::string>& wlst,
+ const std::string& candidate,
+ int cpdsuggest,
+ int* timer,
+ clock_t* timelimit) {
+ int cwrd = 1;
+ if (wlst.size() == maxSug)
+ return;
+ for (size_t k = 0; k < wlst.size(); ++k) {
+ if (wlst[k] == candidate) {
+ cwrd = 0;
+ break;
+ }
+ }
+ if ((cwrd) && checkword(candidate, cpdsuggest, timer, timelimit)) {
+ wlst.push_back(candidate);
+ }
+}
+
+/* generate suggestions for a misspelled word
+ * pass in address of array of char * pointers
+ * onlycompoundsug: probably bad suggestions (need for ngram sugs, too)
+ * return value: true, if there is a good suggestion
+ * (REP, ph: or a dictionary word pair)
+ */
+bool SuggestMgr::suggest(std::vector<std::string>& slst,
+ const char* w,
+ int* onlycompoundsug) {
+ int nocompoundtwowords = 0;
+ std::vector<w_char> word_utf;
+ int wl = 0;
+ size_t nsugorig = slst.size();
+ std::string w2;
+ const char* word = w;
+ size_t oldSug = 0;
+ bool good_suggestion = false;
+
+ // word reversing wrapper for complex prefixes
+ if (complexprefixes) {
+ w2.assign(w);
+ if (utf8)
+ reverseword_utf(w2);
+ else
+ reverseword(w2);
+ word = w2.c_str();
+ }
+
+ if (utf8) {
+ wl = u8_u16(word_utf, word);
+ if (wl == -1) {
+ return false;
+ }
+ }
+
+ for (int cpdsuggest = 0; (cpdsuggest < 2) && (nocompoundtwowords == 0) && !good_suggestion;
+ cpdsuggest++) {
+
+ clock_t timelimit;
+ // initialize both in non-compound and compound cycles
+ timelimit = clock();
+
+ // limit compound suggestion
+ if (cpdsuggest > 0)
+ oldSug = slst.size();
+
+ // suggestions for an uppercase word (html -> HTML)
+ if (slst.size() < maxSug) {
+ size_t i = slst.size();
+ if (utf8)
+ capchars_utf(slst, word_utf.data(), wl, cpdsuggest);
+ else
+ capchars(slst, word, cpdsuggest);
+ if (slst.size() > i)
+ good_suggestion = true;
+ }
+
+ // perhaps we made a typical fault of spelling
+ if ((slst.size() < maxSug) && (!cpdsuggest || (slst.size() < oldSug + maxcpdsugs))) {
+ size_t i = slst.size();
+ replchars(slst, word, cpdsuggest);
+ if (slst.size() > i)
+ good_suggestion = true;
+ }
+ if (clock() > timelimit + TIMELIMIT_SUGGESTION)
+ return good_suggestion;
+
+ // perhaps we made chose the wrong char from a related set
+ if ((slst.size() < maxSug) &&
+ (!cpdsuggest || (slst.size() < oldSug + maxcpdsugs))) {
+ mapchars(slst, word, cpdsuggest);
+ }
+ if (clock() > timelimit + TIMELIMIT_SUGGESTION)
+ return good_suggestion;
+
+ // only suggest compound words when no other suggestion
+ if ((cpdsuggest == 0) && (slst.size() > nsugorig))
+ nocompoundtwowords = 1;
+
+ // did we swap the order of chars by mistake
+ if ((slst.size() < maxSug) && (!cpdsuggest || (slst.size() < oldSug + maxcpdsugs))) {
+ if (utf8)
+ swapchar_utf(slst, word_utf.data(), wl, cpdsuggest);
+ else
+ swapchar(slst, word, cpdsuggest);
+ }
+ if (clock() > timelimit + TIMELIMIT_SUGGESTION)
+ return good_suggestion;
+
+ // did we swap the order of non adjacent chars by mistake
+ if ((slst.size() < maxSug) && (!cpdsuggest || (slst.size() < oldSug + maxcpdsugs))) {
+ if (utf8)
+ longswapchar_utf(slst, word_utf.data(), wl, cpdsuggest);
+ else
+ longswapchar(slst, word, cpdsuggest);
+ }
+ if (clock() > timelimit + TIMELIMIT_SUGGESTION)
+ return good_suggestion;
+
+ // did we just hit the wrong key in place of a good char (case and keyboard)
+ if ((slst.size() < maxSug) && (!cpdsuggest || (slst.size() < oldSug + maxcpdsugs))) {
+ if (utf8)
+ badcharkey_utf(slst, word_utf.data(), wl, cpdsuggest);
+ else
+ badcharkey(slst, word, cpdsuggest);
+ }
+ if (clock() > timelimit + TIMELIMIT_SUGGESTION)
+ return good_suggestion;
+
+ // did we add a char that should not be there
+ if ((slst.size() < maxSug) && (!cpdsuggest || (slst.size() < oldSug + maxcpdsugs))) {
+ if (utf8)
+ extrachar_utf(slst, word_utf.data(), wl, cpdsuggest);
+ else
+ extrachar(slst, word, cpdsuggest);
+ }
+ if (clock() > timelimit + TIMELIMIT_SUGGESTION)
+ return good_suggestion;
+
+ // did we forgot a char
+ if ((slst.size() < maxSug) && (!cpdsuggest || (slst.size() < oldSug + maxcpdsugs))) {
+ if (utf8)
+ forgotchar_utf(slst, word_utf.data(), wl, cpdsuggest);
+ else
+ forgotchar(slst, word, cpdsuggest);
+ }
+ if (clock() > timelimit + TIMELIMIT_SUGGESTION)
+ return good_suggestion;
+
+ // did we move a char
+ if ((slst.size() < maxSug) && (!cpdsuggest || (slst.size() < oldSug + maxcpdsugs))) {
+ if (utf8)
+ movechar_utf(slst, word_utf.data(), wl, cpdsuggest);
+ else
+ movechar(slst, word, cpdsuggest);
+ }
+ if (clock() > timelimit + TIMELIMIT_SUGGESTION)
+ return good_suggestion;
+
+ // did we just hit the wrong key in place of a good char
+ if ((slst.size() < maxSug) && (!cpdsuggest || (slst.size() < oldSug + maxcpdsugs))) {
+ if (utf8)
+ badchar_utf(slst, word_utf.data(), wl, cpdsuggest);
+ else
+ badchar(slst, word, cpdsuggest);
+ }
+ if (clock() > timelimit + TIMELIMIT_SUGGESTION)
+ return good_suggestion;
+
+ // did we double two characters
+ if ((slst.size() < maxSug) && (!cpdsuggest || (slst.size() < oldSug + maxcpdsugs))) {
+ if (utf8)
+ doubletwochars_utf(slst, word_utf.data(), wl, cpdsuggest);
+ else
+ doubletwochars(slst, word, cpdsuggest);
+ }
+ if (clock() > timelimit + TIMELIMIT_SUGGESTION)
+ return good_suggestion;
+
+ // perhaps we forgot to hit space and two words ran together
+ // (dictionary word pairs have top priority here, so
+ // we always suggest them, in despite of nosplitsugs, and
+ // drop compound word and other suggestions)
+ if (!cpdsuggest || (!nosplitsugs && slst.size() < oldSug + maxcpdsugs)) {
+ good_suggestion = twowords(slst, word, cpdsuggest, good_suggestion);
+ }
+ if (clock() > timelimit + TIMELIMIT_SUGGESTION)
+ return good_suggestion;
+
+ } // repeating ``for'' statement compounding support
+
+ if (!nocompoundtwowords && (!slst.empty()) && onlycompoundsug)
+ *onlycompoundsug = 1;
+
+ return good_suggestion;
+}
+
+// suggestions for an uppercase word (html -> HTML)
+void SuggestMgr::capchars_utf(std::vector<std::string>& wlst,
+ const w_char* word,
+ int wl,
+ int cpdsuggest) {
+ std::vector<w_char> candidate_utf(word, word + wl);
+ mkallcap_utf(candidate_utf, langnum);
+ std::string candidate;
+ u16_u8(candidate, candidate_utf);
+ testsug(wlst, candidate, cpdsuggest, NULL, NULL);
+}
+
+// suggestions for an uppercase word (html -> HTML)
+void SuggestMgr::capchars(std::vector<std::string>& wlst,
+ const char* word,
+ int cpdsuggest) {
+ std::string candidate(word);
+ mkallcap(candidate, csconv);
+ testsug(wlst, candidate, cpdsuggest, NULL, NULL);
+}
+
+// suggestions for when chose the wrong char out of a related set
+int SuggestMgr::mapchars(std::vector<std::string>& wlst,
+ const char* word,
+ int cpdsuggest) {
+ std::string candidate;
+ clock_t timelimit;
+ int timer;
+
+ int wl = strlen(word);
+ if (wl < 2 || !pAMgr)
+ return wlst.size();
+
+ const std::vector<mapentry>& maptable = pAMgr->get_maptable();
+ if (maptable.empty())
+ return wlst.size();
+
+ timelimit = clock();
+ timer = MINTIMER;
+ return map_related(word, candidate, 0, wlst, cpdsuggest,
+ maptable, &timer, &timelimit);
+}
+
+int SuggestMgr::map_related(const char* word,
+ std::string& candidate,
+ int wn,
+ std::vector<std::string>& wlst,
+ int cpdsuggest,
+ const std::vector<mapentry>& maptable,
+ int* timer,
+ clock_t* timelimit) {
+ if (*(word + wn) == '\0') {
+ int cwrd = 1;
+ for (size_t m = 0; m < wlst.size(); ++m) {
+ if (wlst[m] == candidate) {
+ cwrd = 0;
+ break;
+ }
+ }
+ if ((cwrd) && checkword(candidate, cpdsuggest, timer, timelimit)) {
+ if (wlst.size() < maxSug) {
+ wlst.push_back(candidate);
+ }
+ }
+ return wlst.size();
+ }
+ int in_map = 0;
+ for (size_t j = 0; j < maptable.size(); ++j) {
+ for (size_t k = 0; k < maptable[j].size(); ++k) {
+ size_t len = maptable[j][k].size();
+ if (strncmp(maptable[j][k].c_str(), word + wn, len) == 0) {
+ in_map = 1;
+ size_t cn = candidate.size();
+ for (size_t l = 0; l < maptable[j].size(); ++l) {
+ candidate.resize(cn);
+ candidate.append(maptable[j][l]);
+ map_related(word, candidate, wn + len, wlst,
+ cpdsuggest, maptable, timer, timelimit);
+ if (!(*timer))
+ return wlst.size();
+ }
+ }
+ }
+ }
+ if (!in_map) {
+ candidate.push_back(*(word + wn));
+ map_related(word, candidate, wn + 1, wlst, cpdsuggest,
+ maptable, timer, timelimit);
+ }
+ return wlst.size();
+}
+
+// suggestions for a typical fault of spelling, that
+// differs with more, than 1 letter from the right form.
+int SuggestMgr::replchars(std::vector<std::string>& wlst,
+ const char* word,
+ int cpdsuggest) {
+ std::string candidate;
+ int wl = strlen(word);
+ if (wl < 2 || !pAMgr)
+ return wlst.size();
+ const std::vector<replentry>& reptable = pAMgr->get_reptable();
+ for (size_t i = 0; i < reptable.size(); ++i) {
+ const char* r = word;
+ // search every occurence of the pattern in the word
+ while ((r = strstr(r, reptable[i].pattern.c_str())) != NULL) {
+ int type = (r == word) ? 1 : 0;
+ if (r - word + reptable[i].pattern.size() == strlen(word))
+ type += 2;
+ while (type && reptable[i].outstrings[type].empty())
+ type = (type == 2 && r != word) ? 0 : type - 1;
+ const std::string&out = reptable[i].outstrings[type];
+ if (out.empty()) {
+ ++r;
+ continue;
+ }
+ candidate.assign(word);
+ candidate.resize(r - word);
+ candidate.append(reptable[i].outstrings[type]);
+ candidate.append(r + reptable[i].pattern.size());
+ testsug(wlst, candidate, cpdsuggest, NULL, NULL);
+ // check REP suggestions with space
+ size_t sp = candidate.find(' ');
+ if (sp != std::string::npos) {
+ size_t prev = 0;
+ while (sp != std::string::npos) {
+ std::string prev_chunk = candidate.substr(prev, sp - prev);
+ if (checkword(prev_chunk, 0, NULL, NULL)) {
+ size_t oldns = wlst.size();
+ std::string post_chunk = candidate.substr(sp + 1);
+ testsug(wlst, post_chunk, cpdsuggest, NULL, NULL);
+ if (oldns < wlst.size()) {
+ wlst[wlst.size() - 1] = candidate;
+ }
+ }
+ prev = sp + 1;
+ sp = candidate.find(' ', prev);
+ }
+ }
+ r++; // search for the next letter
+ }
+ }
+ return wlst.size();
+}
+
+// perhaps we doubled two characters
+// (for example vacation -> vacacation)
+// The recognized pattern with regex back-references:
+// "(.)(.)\1\2\1" or "..(.)(.)\1\2"
+
+int SuggestMgr::doubletwochars(std::vector<std::string>& wlst,
+ const char* word,
+ int cpdsuggest) {
+ int state = 0;
+ int wl = strlen(word);
+ if (wl < 5 || !pAMgr)
+ return wlst.size();
+ for (int i = 2; i < wl; i++) {
+ if (word[i] == word[i - 2]) {
+ state++;
+ if (state == 3 || (state == 2 && i >= 4)) {
+ std::string candidate(word, word + i - 1);
+ candidate.insert(candidate.end(), word + i + 1, word + wl);
+ testsug(wlst, candidate, cpdsuggest, NULL, NULL);
+ state = 0;
+ }
+ } else {
+ state = 0;
+ }
+ }
+ return wlst.size();
+}
+
+// perhaps we doubled two characters
+// (for example vacation -> vacacation)
+// The recognized pattern with regex back-references:
+// "(.)(.)\1\2\1" or "..(.)(.)\1\2"
+
+int SuggestMgr::doubletwochars_utf(std::vector<std::string>& wlst,
+ const w_char* word,
+ int wl,
+ int cpdsuggest) {
+ int state = 0;
+ if (wl < 5 || !pAMgr)
+ return wlst.size();
+ for (int i = 2; i < wl; i++) {
+ if (word[i] == word[i - 2]) {
+ state++;
+ if (state == 3 || (state == 2 && i >= 4)) {
+ std::vector<w_char> candidate_utf(word, word + i - 1);
+ candidate_utf.insert(candidate_utf.end(), word + i + 1, word + wl);
+ std::string candidate;
+ u16_u8(candidate, candidate_utf);
+ testsug(wlst, candidate, cpdsuggest, NULL, NULL);
+ state = 0;
+ }
+ } else {
+ state = 0;
+ }
+ }
+ return wlst.size();
+}
+
+// error is wrong char in place of correct one (case and keyboard related
+// version)
+int SuggestMgr::badcharkey(std::vector<std::string>& wlst,
+ const char* word,
+ int cpdsuggest) {
+ std::string candidate(word);
+
+ // swap out each char one by one and try uppercase and neighbor
+ // keyboard chars in its place to see if that makes a good word
+ for (size_t i = 0; i < candidate.size(); ++i) {
+ char tmpc = candidate[i];
+ // check with uppercase letters
+ candidate[i] = csconv[((unsigned char)tmpc)].cupper;
+ if (tmpc != candidate[i]) {
+ testsug(wlst, candidate, cpdsuggest, NULL, NULL);
+ candidate[i] = tmpc;
+ }
+ // check neighbor characters in keyboard string
+ if (!ckey)
+ continue;
+ char* loc = strchr(ckey, tmpc);
+ while (loc) {
+ if ((loc > ckey) && (*(loc - 1) != '|')) {
+ candidate[i] = *(loc - 1);
+ testsug(wlst, candidate, cpdsuggest, NULL, NULL);
+ }
+ if ((*(loc + 1) != '|') && (*(loc + 1) != '\0')) {
+ candidate[i] = *(loc + 1);
+ testsug(wlst, candidate, cpdsuggest, NULL, NULL);
+ }
+ loc = strchr(loc + 1, tmpc);
+ }
+ candidate[i] = tmpc;
+ }
+ return wlst.size();
+}
+
+// error is wrong char in place of correct one (case and keyboard related
+// version)
+int SuggestMgr::badcharkey_utf(std::vector<std::string>& wlst,
+ const w_char* word,
+ int wl,
+ int cpdsuggest) {
+ std::string candidate;
+ std::vector<w_char> candidate_utf(word, word + wl);
+ // swap out each char one by one and try all the tryme
+ // chars in its place to see if that makes a good word
+ for (int i = 0; i < wl; i++) {
+ w_char tmpc = candidate_utf[i];
+ // check with uppercase letters
+ candidate_utf[i] = upper_utf(candidate_utf[i], 1);
+ if (tmpc != candidate_utf[i]) {
+ u16_u8(candidate, candidate_utf);
+ testsug(wlst, candidate, cpdsuggest, NULL, NULL);
+ candidate_utf[i] = tmpc;
+ }
+ // check neighbor characters in keyboard string
+ if (!ckey)
+ continue;
+ size_t loc = 0;
+ while ((loc < ckeyl) && ckey_utf[loc] != tmpc)
+ ++loc;
+ while (loc < ckeyl) {
+ if ((loc > 0) && ckey_utf[loc - 1] != W_VLINE) {
+ candidate_utf[i] = ckey_utf[loc - 1];
+ u16_u8(candidate, candidate_utf);
+ testsug(wlst, candidate, cpdsuggest, NULL, NULL);
+ }
+ if (((loc + 1) < ckeyl) && (ckey_utf[loc + 1] != W_VLINE)) {
+ candidate_utf[i] = ckey_utf[loc + 1];
+ u16_u8(candidate, candidate_utf);
+ testsug(wlst, candidate, cpdsuggest, NULL, NULL);
+ }
+ do {
+ loc++;
+ } while ((loc < ckeyl) && ckey_utf[loc] != tmpc);
+ }
+ candidate_utf[i] = tmpc;
+ }
+ return wlst.size();
+}
+
+// error is wrong char in place of correct one
+int SuggestMgr::badchar(std::vector<std::string>& wlst, const char* word, int cpdsuggest) {
+ std::string candidate(word);
+ clock_t timelimit = clock();
+ int timer = MINTIMER;
+ // swap out each char one by one and try all the tryme
+ // chars in its place to see if that makes a good word
+ for (size_t j = 0; j < ctryl; ++j) {
+ for (std::string::reverse_iterator aI = candidate.rbegin(), aEnd = candidate.rend(); aI != aEnd; ++aI) {
+ char tmpc = *aI;
+ if (ctry[j] == tmpc)
+ continue;
+ *aI = ctry[j];
+ testsug(wlst, candidate, cpdsuggest, &timer, &timelimit);
+ if (!timer)
+ return wlst.size();
+ *aI = tmpc;
+ }
+ }
+ return wlst.size();
+}
+
+// error is wrong char in place of correct one
+int SuggestMgr::badchar_utf(std::vector<std::string>& wlst,
+ const w_char* word,
+ int wl,
+ int cpdsuggest) {
+ std::vector<w_char> candidate_utf(word, word + wl);
+ std::string candidate;
+ clock_t timelimit = clock();
+ int timer = MINTIMER;
+ // swap out each char one by one and try all the tryme
+ // chars in its place to see if that makes a good word
+ for (size_t j = 0; j < ctryl; ++j) {
+ for (int i = wl - 1; i >= 0; i--) {
+ w_char tmpc = candidate_utf[i];
+ if (tmpc == ctry_utf[j])
+ continue;
+ candidate_utf[i] = ctry_utf[j];
+ u16_u8(candidate, candidate_utf);
+ testsug(wlst, candidate, cpdsuggest, &timer, &timelimit);
+ if (!timer)
+ return wlst.size();
+ candidate_utf[i] = tmpc;
+ }
+ }
+ return wlst.size();
+}
+
+// error is word has an extra letter it does not need
+int SuggestMgr::extrachar_utf(std::vector<std::string>& wlst,
+ const w_char* word,
+ int wl,
+ int cpdsuggest) {
+ std::vector<w_char> candidate_utf(word, word + wl);
+ if (candidate_utf.size() < 2)
+ return wlst.size();
+ // try omitting one char of word at a time
+ for (size_t i = 0; i < candidate_utf.size(); ++i) {
+ size_t index = candidate_utf.size() - 1 - i;
+ w_char tmpc = candidate_utf[index];
+ candidate_utf.erase(candidate_utf.begin() + index);
+ std::string candidate;
+ u16_u8(candidate, candidate_utf);
+ testsug(wlst, candidate, cpdsuggest, NULL, NULL);
+ candidate_utf.insert(candidate_utf.begin() + index, tmpc);
+ }
+ return wlst.size();
+}
+
+// error is word has an extra letter it does not need
+int SuggestMgr::extrachar(std::vector<std::string>& wlst,
+ const char* word,
+ int cpdsuggest) {
+ std::string candidate(word);
+ if (candidate.size() < 2)
+ return wlst.size();
+ // try omitting one char of word at a time
+ for (size_t i = 0; i < candidate.size(); ++i) {
+ size_t index = candidate.size() - 1 - i;
+ char tmpc = candidate[index];
+ candidate.erase(candidate.begin() + index);
+ testsug(wlst, candidate, cpdsuggest, NULL, NULL);
+ candidate.insert(candidate.begin() + index, tmpc);
+ }
+ return wlst.size();
+}
+
+// error is missing a letter it needs
+int SuggestMgr::forgotchar(std::vector<std::string>& wlst,
+ const char* word,
+ int cpdsuggest) {
+ std::string candidate(word);
+ clock_t timelimit = clock();
+ int timer = MINTIMER;
+
+ // try inserting a tryme character before every letter (and the null
+ // terminator)
+ for (size_t k = 0; k < ctryl; ++k) {
+ for (size_t i = 0; i <= candidate.size(); ++i) {
+ size_t index = candidate.size() - i;
+ candidate.insert(candidate.begin() + index, ctry[k]);
+ testsug(wlst, candidate, cpdsuggest, &timer, &timelimit);
+ if (!timer)
+ return wlst.size();
+ candidate.erase(candidate.begin() + index);
+ }
+ }
+ return wlst.size();
+}
+
+// error is missing a letter it needs
+int SuggestMgr::forgotchar_utf(std::vector<std::string>& wlst,
+ const w_char* word,
+ int wl,
+ int cpdsuggest) {
+ std::vector<w_char> candidate_utf(word, word + wl);
+ clock_t timelimit = clock();
+ int timer = MINTIMER;
+
+ // try inserting a tryme character at the end of the word and before every
+ // letter
+ for (size_t k = 0; k < ctryl; ++k) {
+ for (size_t i = 0; i <= candidate_utf.size(); ++i) {
+ size_t index = candidate_utf.size() - i;
+ candidate_utf.insert(candidate_utf.begin() + index, ctry_utf[k]);
+ std::string candidate;
+ u16_u8(candidate, candidate_utf);
+ testsug(wlst, candidate, cpdsuggest, &timer, &timelimit);
+ if (!timer)
+ return wlst.size();
+ candidate_utf.erase(candidate_utf.begin() + index);
+ }
+ }
+ return wlst.size();
+}
+
+/* error is should have been two words
+ * return value is true, if there is a dictionary word pair,
+ * or there was already a good suggestion before calling
+ * this function.
+ */
+bool SuggestMgr::twowords(std::vector<std::string>& wlst,
+ const char* word,
+ int cpdsuggest,
+ bool good) {
+ int c2;
+ int forbidden = 0;
+ int cwrd;
+
+ int wl = strlen(word);
+ if (wl < 3)
+ return false;
+
+ if (langnum == LANG_hu)
+ forbidden = check_forbidden(word, wl);
+
+ char* candidate = (char*)malloc(wl + 2);
+ strcpy(candidate + 1, word);
+
+ // split the string into two pieces after every char
+ // if both pieces are good words make them a suggestion
+ for (char* p = candidate + 1; p[1] != '\0'; p++) {
+ p[-1] = *p;
+ // go to end of the UTF-8 character
+ while (utf8 && ((p[1] & 0xc0) == 0x80)) {
+ *p = p[1];
+ p++;
+ }
+ if (utf8 && p[1] == '\0')
+ break; // last UTF-8 character
+
+ // Suggest only word pairs, if they are listed in the dictionary.
+ // For example, adding "a lot" to the English dic file will
+ // result only "alot" -> "a lot" suggestion instead of
+ // "alto, slot, alt, lot, allot, aloft, aloe, clot, plot, blot, a lot".
+ // Note: using "ph:alot" keeps the other suggestions:
+ // a lot ph:alot
+ // alot -> a lot, alto, slot...
+ *p = ' ';
+ if (!cpdsuggest && checkword(candidate, cpdsuggest, NULL, NULL)) {
+ // remove not word pair suggestions
+ if (!good) {
+ good = true;
+ wlst.clear();
+ }
+ wlst.insert(wlst.begin(), candidate);
+ }
+
+ // word pairs with dash?
+ if (lang_with_dash_usage) {
+ *p = '-';
+
+ if (!cpdsuggest && checkword(candidate, cpdsuggest, NULL, NULL)) {
+ // remove not word pair suggestions
+ if (!good) {
+ good = true;
+ wlst.clear();
+ }
+ wlst.insert(wlst.begin(), candidate);
+ }
+ }
+
+ if (wlst.size() < maxSug && !nosplitsugs && !good) {
+ *p = '\0';
+ int c1 = checkword(candidate, cpdsuggest, NULL, NULL);
+ if (c1) {
+ c2 = checkword((p + 1), cpdsuggest, NULL, NULL);
+ if (c2) {
+ // spec. Hungarian code (TODO need a better compound word support)
+ if ((langnum == LANG_hu) && !forbidden &&
+ // if 3 repeating letter, use - instead of space
+ (((p[-1] == p[1]) &&
+ (((p > candidate + 1) && (p[-1] == p[-2])) || (p[-1] == p[2]))) ||
+ // or multiple compounding, with more, than 6 syllables
+ ((c1 == 3) && (c2 >= 2))))
+ *p = '-';
+ else
+ *p = ' ';
+
+ cwrd = 1;
+ for (size_t k = 0; k < wlst.size(); ++k) {
+ if (wlst[k] == candidate) {
+ cwrd = 0;
+ break;
+ }
+ }
+
+ if (cwrd && (wlst.size() < maxSug))
+ wlst.push_back(candidate);
+
+ // add two word suggestion with dash, depending on the language
+ // Note that cwrd doesn't modified for REP twoword sugg.
+ if ( !nosplitsugs && lang_with_dash_usage &&
+ mystrlen(p + 1) > 1 && mystrlen(candidate) - mystrlen(p) > 1) {
+ *p = '-';
+ for (size_t k = 0; k < wlst.size(); ++k) {
+ if (wlst[k] == candidate) {
+ cwrd = 0;
+ break;
+ }
+ }
+
+ if ((wlst.size() < maxSug) && cwrd)
+ wlst.push_back(candidate);
+ }
+ }
+ }
+ }
+ }
+ free(candidate);
+ return good;
+}
+
+// error is adjacent letter were swapped
+int SuggestMgr::swapchar(std::vector<std::string>& wlst,
+ const char* word,
+ int cpdsuggest) {
+ std::string candidate(word);
+ if (candidate.size() < 2)
+ return wlst.size();
+
+ // try swapping adjacent chars one by one
+ for (size_t i = 0; i < candidate.size() - 1; ++i) {
+ std::swap(candidate[i], candidate[i+1]);
+ testsug(wlst, candidate, cpdsuggest, NULL, NULL);
+ std::swap(candidate[i], candidate[i+1]);
+ }
+
+ // try double swaps for short words
+ // ahev -> have, owudl -> would
+ if (candidate.size() == 4 || candidate.size() == 5) {
+ candidate[0] = word[1];
+ candidate[1] = word[0];
+ candidate[2] = word[2];
+ candidate[candidate.size() - 2] = word[candidate.size() - 1];
+ candidate[candidate.size() - 1] = word[candidate.size() - 2];
+ testsug(wlst, candidate, cpdsuggest, NULL, NULL);
+ if (candidate.size() == 5) {
+ candidate[0] = word[0];
+ candidate[1] = word[2];
+ candidate[2] = word[1];
+ testsug(wlst, candidate, cpdsuggest, NULL, NULL);
+ }
+ }
+
+ return wlst.size();
+}
+
+// error is adjacent letter were swapped
+int SuggestMgr::swapchar_utf(std::vector<std::string>& wlst,
+ const w_char* word,
+ int wl,
+ int cpdsuggest) {
+ std::vector<w_char> candidate_utf(word, word + wl);
+ if (candidate_utf.size() < 2)
+ return wlst.size();
+
+ std::string candidate;
+ // try swapping adjacent chars one by one
+ for (size_t i = 0; i < candidate_utf.size() - 1; ++i) {
+ std::swap(candidate_utf[i], candidate_utf[i+1]);
+ u16_u8(candidate, candidate_utf);
+ testsug(wlst, candidate, cpdsuggest, NULL, NULL);
+ std::swap(candidate_utf[i], candidate_utf[i+1]);
+ }
+
+ // try double swaps for short words
+ // ahev -> have, owudl -> would, suodn -> sound
+ if (candidate_utf.size() == 4 || candidate_utf.size() == 5) {
+ candidate_utf[0] = word[1];
+ candidate_utf[1] = word[0];
+ candidate_utf[2] = word[2];
+ candidate_utf[candidate_utf.size() - 2] = word[candidate_utf.size() - 1];
+ candidate_utf[candidate_utf.size() - 1] = word[candidate_utf.size() - 2];
+ u16_u8(candidate, candidate_utf);
+ testsug(wlst, candidate, cpdsuggest, NULL, NULL);
+ if (candidate_utf.size() == 5) {
+ candidate_utf[0] = word[0];
+ candidate_utf[1] = word[2];
+ candidate_utf[2] = word[1];
+ u16_u8(candidate, candidate_utf);
+ testsug(wlst, candidate, cpdsuggest, NULL, NULL);
+ }
+ }
+ return wlst.size();
+}
+
+// error is not adjacent letter were swapped
+int SuggestMgr::longswapchar(std::vector<std::string>& wlst,
+ const char* word,
+ int cpdsuggest) {
+ std::string candidate(word);
+ // try swapping not adjacent chars one by one
+ for (std::string::iterator p = candidate.begin(); p < candidate.end(); ++p) {
+ for (std::string::iterator q = candidate.begin(); q < candidate.end(); ++q) {
+ size_t distance = std::abs(std::distance(q, p));
+ if (distance > 1 && distance <= MAX_CHAR_DISTANCE) {
+ std::swap(*p, *q);
+ testsug(wlst, candidate, cpdsuggest, NULL, NULL);
+ std::swap(*p, *q);
+ }
+ }
+ }
+ return wlst.size();
+}
+
+// error is adjacent letter were swapped
+int SuggestMgr::longswapchar_utf(std::vector<std::string>& wlst,
+ const w_char* word,
+ int wl,
+ int cpdsuggest) {
+ std::vector<w_char> candidate_utf(word, word + wl);
+ // try swapping not adjacent chars
+ for (std::vector<w_char>::iterator p = candidate_utf.begin(); p < candidate_utf.end(); ++p) {
+ for (std::vector<w_char>::iterator q = candidate_utf.begin(); q < candidate_utf.end(); ++q) {
+ size_t distance = std::abs(std::distance(q, p));
+ if (distance > 1 && distance <= MAX_CHAR_DISTANCE) {
+ std::swap(*p, *q);
+ std::string candidate;
+ u16_u8(candidate, candidate_utf);
+ testsug(wlst, candidate, cpdsuggest, NULL, NULL);
+ std::swap(*p, *q);
+ }
+ }
+ }
+ return wlst.size();
+}
+
+// error is a letter was moved
+int SuggestMgr::movechar(std::vector<std::string>& wlst,
+ const char* word,
+ int cpdsuggest) {
+ std::string candidate(word);
+ if (candidate.size() < 2)
+ return wlst.size();
+
+ // try moving a char
+ for (std::string::iterator p = candidate.begin(); p < candidate.end(); ++p) {
+ for (std::string::iterator q = p + 1; q < candidate.end() && std::distance(p, q) <= MAX_CHAR_DISTANCE; ++q) {
+ std::swap(*q, *(q - 1));
+ if (std::distance(p, q) < 2)
+ continue; // omit swap char
+ testsug(wlst, candidate, cpdsuggest, NULL, NULL);
+ }
+ std::copy(word, word + candidate.size(), candidate.begin());
+ }
+
+ for (std::string::reverse_iterator p = candidate.rbegin(), pEnd = candidate.rend() - 1; p != pEnd; ++p) {
+ for (std::string::reverse_iterator q = p + 1, qEnd = candidate.rend(); q != qEnd && std::distance(p, q) <= MAX_CHAR_DISTANCE; ++q) {
+ std::swap(*q, *(q - 1));
+ if (std::distance(p, q) < 2)
+ continue; // omit swap char
+ testsug(wlst, candidate, cpdsuggest, NULL, NULL);
+ }
+ std::copy(word, word + candidate.size(), candidate.begin());
+ }
+
+ return wlst.size();
+}
+
+// error is a letter was moved
+int SuggestMgr::movechar_utf(std::vector<std::string>& wlst,
+ const w_char* word,
+ int wl,
+ int cpdsuggest) {
+ std::vector<w_char> candidate_utf(word, word + wl);
+ if (candidate_utf.size() < 2)
+ return wlst.size();
+
+ // try moving a char
+ for (std::vector<w_char>::iterator p = candidate_utf.begin(); p < candidate_utf.end(); ++p) {
+ for (std::vector<w_char>::iterator q = p + 1; q < candidate_utf.end() && std::distance(p, q) <= MAX_CHAR_DISTANCE; ++q) {
+ std::swap(*q, *(q - 1));
+ if (std::distance(p, q) < 2)
+ continue; // omit swap char
+ std::string candidate;
+ u16_u8(candidate, candidate_utf);
+ testsug(wlst, candidate, cpdsuggest, NULL, NULL);
+ }
+ std::copy(word, word + candidate_utf.size(), candidate_utf.begin());
+ }
+
+ for (std::vector<w_char>::reverse_iterator p = candidate_utf.rbegin(); p < candidate_utf.rend(); ++p) {
+ for (std::vector<w_char>::reverse_iterator q = p + 1; q < candidate_utf.rend() && std::distance(p, q) <= MAX_CHAR_DISTANCE; ++q) {
+ std::swap(*q, *(q - 1));
+ if (std::distance(p, q) < 2)
+ continue; // omit swap char
+ std::string candidate;
+ u16_u8(candidate, candidate_utf);
+ testsug(wlst, candidate, cpdsuggest, NULL, NULL);
+ }
+ std::copy(word, word + candidate_utf.size(), candidate_utf.begin());
+ }
+
+ return wlst.size();
+}
+
+// generate a set of suggestions for very poorly spelled words
+void SuggestMgr::ngsuggest(std::vector<std::string>& wlst,
+ const char* w,
+ const std::vector<HashMgr*>& rHMgr,
+ int captype) {
+ int lval;
+ int sc;
+ int lp, lpphon;
+ int nonbmp = 0;
+
+ // exhaustively search through all root words
+ // keeping track of the MAX_ROOTS most similar root words
+ struct hentry* roots[MAX_ROOTS];
+ char* rootsphon[MAX_ROOTS];
+ int scores[MAX_ROOTS];
+ int scoresphon[MAX_ROOTS];
+ for (int i = 0; i < MAX_ROOTS; i++) {
+ roots[i] = NULL;
+ scores[i] = -100 * i;
+ rootsphon[i] = NULL;
+ scoresphon[i] = -100 * i;
+ }
+ lp = MAX_ROOTS - 1;
+ lpphon = MAX_ROOTS - 1;
+ int low = NGRAM_LOWERING;
+
+ std::string w2;
+ const char* word = w;
+
+ // word reversing wrapper for complex prefixes
+ if (complexprefixes) {
+ w2.assign(w);
+ if (utf8)
+ reverseword_utf(w2);
+ else
+ reverseword(w2);
+ word = w2.c_str();
+ }
+
+ std::vector<w_char> u8;
+ int nc = strlen(word);
+ int n = (utf8) ? u8_u16(u8, word) : nc;
+
+ // set character based ngram suggestion for words with non-BMP Unicode
+ // characters
+ if (n == -1) {
+ utf8 = 0; // XXX not state-free
+ n = nc;
+ nonbmp = 1;
+ low = 0;
+ }
+
+ struct hentry* hp = NULL;
+ int col = -1;
+ phonetable* ph = (pAMgr) ? pAMgr->get_phonetable() : NULL;
+ std::string target;
+ std::string candidate;
+ std::vector<w_char> w_candidate;
+ if (ph) {
+ if (utf8) {
+ u8_u16(w_candidate, word);
+ mkallcap_utf(w_candidate, langnum);
+ u16_u8(candidate, w_candidate);
+ } else {
+ candidate.assign(word);
+ if (!nonbmp)
+ mkallcap(candidate, csconv);
+ }
+ target = phonet(candidate, *ph); // XXX phonet() is 8-bit (nc, not n)
+ }
+
+ FLAG forbiddenword = pAMgr ? pAMgr->get_forbiddenword() : FLAG_NULL;
+ FLAG nosuggest = pAMgr ? pAMgr->get_nosuggest() : FLAG_NULL;
+ FLAG nongramsuggest = pAMgr ? pAMgr->get_nongramsuggest() : FLAG_NULL;
+ FLAG onlyincompound = pAMgr ? pAMgr->get_onlyincompound() : FLAG_NULL;
+
+ std::vector<w_char> w_word, w_target;
+ if (utf8) {
+ u8_u16(w_word, word);
+ u8_u16(w_target, target);
+ }
+
+ std::string f;
+ std::vector<w_char> w_f;
+
+ for (size_t i = 0; i < rHMgr.size(); ++i) {
+ while (0 != (hp = rHMgr[i]->walk_hashtable(col, hp))) {
+ // skip exceptions
+ if (
+ // skip it, if the word length different by 5 or
+ // more characters (to avoid strange suggestions)
+ // (except Unicode characters over BMP)
+ (((abs(n - hp->clen) > 4) && !nonbmp)) ||
+ // don't suggest capitalized dictionary words for
+ // lower case misspellings in ngram suggestions, except
+ // - PHONE usage, or
+ // - in the case of German, where not only proper
+ // nouns are capitalized, or
+ // - the capitalized word has special pronunciation
+ ((captype == NOCAP) && (hp->var & H_OPT_INITCAP) &&
+ !ph && (langnum != LANG_de) && !(hp->var & H_OPT_PHON)) ||
+ // or it has one of the following special flags
+ ((hp->astr) && (pAMgr) &&
+ (TESTAFF(hp->astr, forbiddenword, hp->alen) ||
+ TESTAFF(hp->astr, ONLYUPCASEFLAG, hp->alen) ||
+ TESTAFF(hp->astr, nosuggest, hp->alen) ||
+ TESTAFF(hp->astr, nongramsuggest, hp->alen) ||
+ TESTAFF(hp->astr, onlyincompound, hp->alen)))
+ )
+ continue;
+
+ if (utf8) {
+ u8_u16(w_f, HENTRY_WORD(hp));
+
+ int leftcommon = leftcommonsubstring(w_word, w_f);
+ if (low) {
+ // lowering dictionary word
+ mkallsmall_utf(w_f, langnum);
+ }
+ sc = ngram(3, w_word, w_f, NGRAM_LONGER_WORSE) + leftcommon;
+ } else {
+ f.assign(HENTRY_WORD(hp));
+
+ int leftcommon = leftcommonsubstring(word, f.c_str());
+ if (low) {
+ // lowering dictionary word
+ mkallsmall(f, csconv);
+ }
+ sc = ngram(3, word, f, NGRAM_LONGER_WORSE) + leftcommon;
+ }
+
+ // check special pronunciation
+ f.clear();
+ if ((hp->var & H_OPT_PHON) &&
+ copy_field(f, HENTRY_DATA(hp), MORPH_PHON)) {
+ int sc2;
+ if (utf8) {
+ u8_u16(w_f, f);
+
+ int leftcommon = leftcommonsubstring(w_word, w_f);
+ if (low) {
+ // lowering dictionary word
+ mkallsmall_utf(w_f, langnum);
+ }
+ sc2 = ngram(3, w_word, w_f, NGRAM_LONGER_WORSE) + leftcommon;
+ } else {
+ int leftcommon = leftcommonsubstring(word, f.c_str());
+ if (low) {
+ // lowering dictionary word
+ mkallsmall(f, csconv);
+ }
+ sc2 = ngram(3, word, f, NGRAM_LONGER_WORSE) + leftcommon;
+ }
+ if (sc2 > sc)
+ sc = sc2;
+ }
+
+ int scphon = -20000;
+ if (ph && (sc > 2) && (abs(n - (int)hp->clen) <= 3)) {
+ if (utf8) {
+ u8_u16(w_candidate, HENTRY_WORD(hp));
+ mkallcap_utf(w_candidate, langnum);
+ u16_u8(candidate, w_candidate);
+ } else {
+ candidate = HENTRY_WORD(hp);
+ mkallcap(candidate, csconv);
+ }
+ f = phonet(candidate, *ph);
+ if (utf8) {
+ u8_u16(w_f, f);
+ scphon = 2 * ngram(3, w_target, w_f,
+ NGRAM_LONGER_WORSE);
+ } else {
+ scphon = 2 * ngram(3, target, f,
+ NGRAM_LONGER_WORSE);
+ }
+ }
+
+ if (sc > scores[lp]) {
+ scores[lp] = sc;
+ roots[lp] = hp;
+ lval = sc;
+ for (int j = 0; j < MAX_ROOTS; j++)
+ if (scores[j] < lval) {
+ lp = j;
+ lval = scores[j];
+ }
+ }
+
+ if (scphon > scoresphon[lpphon]) {
+ scoresphon[lpphon] = scphon;
+ rootsphon[lpphon] = HENTRY_WORD(hp);
+ lval = scphon;
+ for (int j = 0; j < MAX_ROOTS; j++)
+ if (scoresphon[j] < lval) {
+ lpphon = j;
+ lval = scoresphon[j];
+ }
+ }
+ }
+ }
+
+ // find minimum threshold for a passable suggestion
+ // mangle original word three differnt ways
+ // and score them to generate a minimum acceptable score
+ std::vector<w_char> w_mw;
+ int thresh = 0;
+ for (int sp = 1; sp < 4; sp++) {
+ if (utf8) {
+ w_mw = w_word;
+ for (int k = sp; k < n; k += 4) {
+ w_mw[k].l = '*';
+ w_mw[k].h = 0;
+ }
+
+ if (low) {
+ // lowering dictionary word
+ mkallsmall_utf(w_mw, langnum);
+ }
+
+ thresh += ngram(n, w_word, w_mw, NGRAM_ANY_MISMATCH);
+ } else {
+ std::string mw = word;
+ for (int k = sp; k < n; k += 4)
+ mw[k] = '*';
+
+ if (low) {
+ // lowering dictionary word
+ mkallsmall(mw, csconv);
+ }
+
+ thresh += ngram(n, word, mw, NGRAM_ANY_MISMATCH);
+ }
+ }
+ thresh = thresh / 3;
+ thresh--;
+
+ // now expand affixes on each of these root words and
+ // and use length adjusted ngram scores to select
+ // possible suggestions
+ char* guess[MAX_GUESS];
+ char* guessorig[MAX_GUESS];
+ int gscore[MAX_GUESS];
+ for (int i = 0; i < MAX_GUESS; i++) {
+ guess[i] = NULL;
+ guessorig[i] = NULL;
+ gscore[i] = -100 * i;
+ }
+
+ lp = MAX_GUESS - 1;
+
+ struct guessword* glst;
+ glst = (struct guessword*)calloc(MAX_WORDS, sizeof(struct guessword));
+ if (!glst) {
+ if (nonbmp)
+ utf8 = 1;
+ return;
+ }
+
+ for (int i = 0; i < MAX_ROOTS; i++) {
+ if (roots[i]) {
+ struct hentry* rp = roots[i];
+
+ f.clear();
+ const char *field = NULL;
+ if ((rp->var & H_OPT_PHON) && copy_field(f, HENTRY_DATA(rp), MORPH_PHON))
+ field = f.c_str();
+ int nw = pAMgr->expand_rootword(
+ glst, MAX_WORDS, HENTRY_WORD(rp), rp->blen, rp->astr, rp->alen, word,
+ nc, field);
+
+ for (int k = 0; k < nw; k++) {
+ if (utf8) {
+ u8_u16(w_f, glst[k].word);
+
+ int leftcommon = leftcommonsubstring(w_word, w_f);
+ if (low) {
+ // lowering dictionary word
+ mkallsmall_utf(w_f, langnum);
+ }
+
+ sc = ngram(n, w_word, w_f, NGRAM_ANY_MISMATCH) + leftcommon;
+ } else {
+ f = glst[k].word;
+
+ int leftcommon = leftcommonsubstring(word, f.c_str());
+ if (low) {
+ // lowering dictionary word
+ mkallsmall(f, csconv);
+ }
+
+ sc = ngram(n, word, f, NGRAM_ANY_MISMATCH) + leftcommon;
+ }
+
+ if (sc > thresh) {
+ if (sc > gscore[lp]) {
+ if (guess[lp]) {
+ free(guess[lp]);
+ if (guessorig[lp]) {
+ free(guessorig[lp]);
+ guessorig[lp] = NULL;
+ }
+ }
+ gscore[lp] = sc;
+ guess[lp] = glst[k].word;
+ guessorig[lp] = glst[k].orig;
+ lval = sc;
+ for (int j = 0; j < MAX_GUESS; j++)
+ if (gscore[j] < lval) {
+ lp = j;
+ lval = gscore[j];
+ }
+ } else {
+ free(glst[k].word);
+ if (glst[k].orig)
+ free(glst[k].orig);
+ }
+ } else {
+ free(glst[k].word);
+ if (glst[k].orig)
+ free(glst[k].orig);
+ }
+ }
+ }
+ }
+ free(glst);
+
+ // now we are done generating guesses
+ // sort in order of decreasing score
+
+ bubblesort(&guess[0], &guessorig[0], &gscore[0], MAX_GUESS);
+ if (ph)
+ bubblesort(&rootsphon[0], NULL, &scoresphon[0], MAX_ROOTS);
+
+ // weight suggestions with a similarity index, based on
+ // the longest common subsequent algorithm and resort
+
+ int is_swap = 0;
+ int re = 0;
+ double fact = 1.0;
+ if (pAMgr) {
+ int maxd = pAMgr->get_maxdiff();
+ if (maxd >= 0)
+ fact = (10.0 - maxd) / 5.0;
+ }
+
+ std::vector<w_char> w_gl;
+ for (int i = 0; i < MAX_GUESS; i++) {
+ if (guess[i]) {
+ // lowering guess[i]
+ std::string gl;
+ int len;
+ if (utf8) {
+ len = u8_u16(w_gl, guess[i]);
+ mkallsmall_utf(w_gl, langnum);
+ u16_u8(gl, w_gl);
+ } else {
+ gl.assign(guess[i]);
+ if (!nonbmp)
+ mkallsmall(gl, csconv);
+ len = strlen(guess[i]);
+ }
+
+ int _lcs = lcslen(word, gl.c_str());
+
+ // same characters with different casing
+ if ((n == len) && (n == _lcs)) {
+ gscore[i] += 2000;
+ break;
+ }
+ // using 2-gram instead of 3, and other weightening
+
+ if (utf8) {
+ u8_u16(w_gl, gl);
+ //w_gl is lowercase already at this point
+ re = ngram(2, w_word, w_gl, NGRAM_ANY_MISMATCH + NGRAM_WEIGHTED);
+ if (low) {
+ w_f = w_word;
+ // lowering dictionary word
+ mkallsmall_utf(w_f, langnum);
+ re += ngram(2, w_gl, w_f, NGRAM_ANY_MISMATCH + NGRAM_WEIGHTED);
+ } else {
+ re += ngram(2, w_gl, w_word, NGRAM_ANY_MISMATCH + NGRAM_WEIGHTED);
+ }
+ } else {
+ //gl is lowercase already at this point
+ re = ngram(2, word, gl, NGRAM_ANY_MISMATCH + NGRAM_WEIGHTED);
+ if (low) {
+ f = word;
+ // lowering dictionary word
+ mkallsmall(f, csconv);
+ re += ngram(2, gl, f, NGRAM_ANY_MISMATCH + NGRAM_WEIGHTED);
+ } else {
+ re += ngram(2, gl, word, NGRAM_ANY_MISMATCH + NGRAM_WEIGHTED);
+ }
+ }
+
+ int ngram_score, leftcommon_score;
+ if (utf8) {
+ //w_gl is lowercase already at this point
+ ngram_score = ngram(4, w_word, w_gl, NGRAM_ANY_MISMATCH);
+ leftcommon_score = leftcommonsubstring(w_word, w_gl);
+ } else {
+ //gl is lowercase already at this point
+ ngram_score = ngram(4, word, gl, NGRAM_ANY_MISMATCH);
+ leftcommon_score = leftcommonsubstring(word, gl.c_str());
+ }
+ gscore[i] =
+ // length of longest common subsequent minus length difference
+ 2 * _lcs - abs((int)(n - len)) +
+ // weight length of the left common substring
+ leftcommon_score +
+ // weight equal character positions
+ (!nonbmp && commoncharacterpositions(word, gl.c_str(), &is_swap)
+ ? 1
+ : 0) +
+ // swap character (not neighboring)
+ ((is_swap) ? 10 : 0) +
+ // ngram
+ ngram_score +
+ // weighted ngrams
+ re +
+ // different limit for dictionaries with PHONE rules
+ (ph ? (re < len * fact ? -1000 : 0)
+ : (re < (n + len) * fact ? -1000 : 0));
+ }
+ }
+
+ bubblesort(&guess[0], &guessorig[0], &gscore[0], MAX_GUESS);
+
+ // phonetic version
+ if (ph)
+ for (int i = 0; i < MAX_ROOTS; i++) {
+ if (rootsphon[i]) {
+ // lowering rootphon[i]
+ std::string gl;
+ int len;
+ if (utf8) {
+ len = u8_u16(w_gl, rootsphon[i]);
+ mkallsmall_utf(w_gl, langnum);
+ u16_u8(gl, w_gl);
+ } else {
+ gl.assign(rootsphon[i]);
+ if (!nonbmp)
+ mkallsmall(gl, csconv);
+ len = strlen(rootsphon[i]);
+ }
+
+ // weight length of the left common substring
+ int leftcommon_score;
+ if (utf8)
+ leftcommon_score = leftcommonsubstring(w_word, w_gl);
+ else
+ leftcommon_score = leftcommonsubstring(word, gl.c_str());
+ // heuristic weigthing of ngram scores
+ scoresphon[i] += 2 * lcslen(word, gl) - abs((int)(n - len)) +
+ leftcommon_score;
+ }
+ }
+
+ if (ph)
+ bubblesort(&rootsphon[0], NULL, &scoresphon[0], MAX_ROOTS);
+
+ // copy over
+ size_t oldns = wlst.size();
+
+ int same = 0;
+ for (int i = 0; i < MAX_GUESS; i++) {
+ if (guess[i]) {
+ if ((wlst.size() < oldns + maxngramsugs) && (wlst.size() < maxSug) &&
+ (!same || (gscore[i] > 1000))) {
+ int unique = 1;
+ // leave only excellent suggestions, if exists
+ if (gscore[i] > 1000)
+ same = 1;
+ else if (gscore[i] < -100) {
+ same = 1;
+ // keep the best ngram suggestions, unless in ONLYMAXDIFF mode
+ if (wlst.size() > oldns || (pAMgr && pAMgr->get_onlymaxdiff())) {
+ free(guess[i]);
+ if (guessorig[i])
+ free(guessorig[i]);
+ continue;
+ }
+ }
+ for (size_t j = 0; j < wlst.size(); ++j) {
+ // don't suggest previous suggestions or a previous suggestion with
+ // prefixes or affixes
+ if ((!guessorig[i] && strstr(guess[i], wlst[j].c_str())) ||
+ (guessorig[i] && strstr(guessorig[i], wlst[j].c_str())) ||
+ // check forbidden words
+ !checkword(guess[i], 0, NULL, NULL)) {
+ unique = 0;
+ break;
+ }
+ }
+ if (unique) {
+ if (guessorig[i]) {
+ wlst.push_back(guessorig[i]);
+ } else {
+ wlst.push_back(guess[i]);
+ }
+ }
+ free(guess[i]);
+ if (guessorig[i])
+ free(guessorig[i]);
+ } else {
+ free(guess[i]);
+ if (guessorig[i])
+ free(guessorig[i]);
+ }
+ }
+ }
+
+ oldns = wlst.size();
+ if (ph)
+ for (int i = 0; i < MAX_ROOTS; i++) {
+ if (rootsphon[i]) {
+ if ((wlst.size() < oldns + MAXPHONSUGS) && (wlst.size() < maxSug)) {
+ int unique = 1;
+ for (size_t j = 0; j < wlst.size(); ++j) {
+ // don't suggest previous suggestions or a previous suggestion with
+ // prefixes or affixes
+ if (strstr(rootsphon[i], wlst[j].c_str()) ||
+ // check forbidden words
+ !checkword(rootsphon[i], 0, NULL, NULL)) {
+ unique = 0;
+ break;
+ }
+ }
+ if (unique) {
+ wlst.push_back(rootsphon[i]);
+ }
+ }
+ }
+ }
+
+ if (nonbmp)
+ utf8 = 1;
+}
+
+// see if a candidate suggestion is spelled correctly
+// needs to check both root words and words with affixes
+
+// obsolote MySpell-HU modifications:
+// return value 2 and 3 marks compounding with hyphen (-)
+// `3' marks roots without suffix
+int SuggestMgr::checkword(const std::string& word,
+ int cpdsuggest,
+ int* timer,
+ clock_t* timelimit) {
+ // check time limit
+ if (timer) {
+ (*timer)--;
+ if (!(*timer) && timelimit) {
+ if ((clock() - *timelimit) > TIMELIMIT)
+ return 0;
+ *timer = MAXPLUSTIMER;
+ }
+ }
+
+ if (pAMgr) {
+ struct hentry* rv = NULL;
+ int nosuffix = 0;
+
+ if (cpdsuggest == 1) {
+ if (pAMgr->get_compound()) {
+ struct hentry* rv2 = NULL;
+ struct hentry* rwords[100]; // buffer for COMPOUND pattern checking
+ rv = pAMgr->compound_check(word, 0, 0, 100, 0, NULL, (hentry**)&rwords, 0, 1, 0); // EXT
+ if (rv &&
+ (!(rv2 = pAMgr->lookup(word.c_str())) || !rv2->astr ||
+ !(TESTAFF(rv2->astr, pAMgr->get_forbiddenword(), rv2->alen) ||
+ TESTAFF(rv2->astr, pAMgr->get_nosuggest(), rv2->alen))))
+ return 3; // XXX obsolote categorisation + only ICONV needs affix
+ // flag check?
+ }
+ return 0;
+ }
+
+ rv = pAMgr->lookup(word.c_str());
+
+ if (rv) {
+ if ((rv->astr) &&
+ (TESTAFF(rv->astr, pAMgr->get_forbiddenword(), rv->alen) ||
+ TESTAFF(rv->astr, pAMgr->get_nosuggest(), rv->alen) ||
+ TESTAFF(rv->astr, pAMgr->get_substandard(), rv->alen)))
+ return 0;
+ while (rv) {
+ if (rv->astr &&
+ (TESTAFF(rv->astr, pAMgr->get_needaffix(), rv->alen) ||
+ TESTAFF(rv->astr, ONLYUPCASEFLAG, rv->alen) ||
+ TESTAFF(rv->astr, pAMgr->get_onlyincompound(), rv->alen))) {
+ rv = rv->next_homonym;
+ } else
+ break;
+ }
+ } else
+ rv = pAMgr->prefix_check(word.c_str(), word.size(),
+ 0); // only prefix, and prefix + suffix XXX
+
+ if (rv) {
+ nosuffix = 1;
+ } else {
+ rv = pAMgr->suffix_check(word.c_str(), word.size(), 0, NULL,
+ FLAG_NULL, FLAG_NULL, IN_CPD_NOT); // only suffix
+ }
+
+ if (!rv && pAMgr->have_contclass()) {
+ rv = pAMgr->suffix_check_twosfx(word.c_str(), word.size(), 0, NULL, FLAG_NULL);
+ if (!rv)
+ rv = pAMgr->prefix_check_twosfx(word.c_str(), word.size(), 0, FLAG_NULL);
+ }
+
+ // check forbidden words
+ if ((rv) && (rv->astr) &&
+ (TESTAFF(rv->astr, pAMgr->get_forbiddenword(), rv->alen) ||
+ TESTAFF(rv->astr, ONLYUPCASEFLAG, rv->alen) ||
+ TESTAFF(rv->astr, pAMgr->get_nosuggest(), rv->alen) ||
+ TESTAFF(rv->astr, pAMgr->get_onlyincompound(), rv->alen)))
+ return 0;
+
+ if (rv) { // XXX obsolote
+ if ((pAMgr->get_compoundflag()) &&
+ TESTAFF(rv->astr, pAMgr->get_compoundflag(), rv->alen))
+ return 2 + nosuffix;
+ return 1;
+ }
+ }
+ return 0;
+}
+
+int SuggestMgr::check_forbidden(const char* word, int len) {
+ if (pAMgr) {
+ struct hentry* rv = pAMgr->lookup(word);
+ if (rv && rv->astr &&
+ (TESTAFF(rv->astr, pAMgr->get_needaffix(), rv->alen) ||
+ TESTAFF(rv->astr, pAMgr->get_onlyincompound(), rv->alen)))
+ rv = NULL;
+ if (!(pAMgr->prefix_check(word, len, 1)))
+ rv = pAMgr->suffix_check(word, len, 0, NULL,
+ FLAG_NULL, FLAG_NULL, IN_CPD_NOT); // prefix+suffix, suffix
+ // check forbidden words
+ if ((rv) && (rv->astr) &&
+ TESTAFF(rv->astr, pAMgr->get_forbiddenword(), rv->alen))
+ return 1;
+ }
+ return 0;
+}
+
+std::string SuggestMgr::suggest_morph(const std::string& in_w) {
+ std::string result;
+
+ struct hentry* rv = NULL;
+
+ if (!pAMgr)
+ return std::string();
+
+ std::string w(in_w);
+
+ // word reversing wrapper for complex prefixes
+ if (complexprefixes) {
+ if (utf8)
+ reverseword_utf(w);
+ else
+ reverseword(w);
+ }
+
+ rv = pAMgr->lookup(w.c_str());
+
+ while (rv) {
+ if ((!rv->astr) ||
+ !(TESTAFF(rv->astr, pAMgr->get_forbiddenword(), rv->alen) ||
+ TESTAFF(rv->astr, pAMgr->get_needaffix(), rv->alen) ||
+ TESTAFF(rv->astr, pAMgr->get_onlyincompound(), rv->alen))) {
+ if (!HENTRY_FIND(rv, MORPH_STEM)) {
+ result.push_back(MSEP_FLD);
+ result.append(MORPH_STEM);
+ result.append(w);
+ }
+ if (HENTRY_DATA(rv)) {
+ result.push_back(MSEP_FLD);
+ result.append(HENTRY_DATA2(rv));
+ }
+ result.push_back(MSEP_REC);
+ }
+ rv = rv->next_homonym;
+ }
+
+ std::string st = pAMgr->affix_check_morph(w.c_str(), w.size());
+ if (!st.empty()) {
+ result.append(st);
+ }
+
+ if (pAMgr->get_compound() && result.empty()) {
+ struct hentry* rwords[100]; // buffer for COMPOUND pattern checking
+ pAMgr->compound_check_morph(w.c_str(), w.size(), 0, 0, 100, 0, NULL, (hentry**)&rwords, 0, result,
+ NULL);
+ }
+
+ line_uniq(result, MSEP_REC);
+
+ return result;
+}
+
+static int get_sfxcount(const char* morph) {
+ if (!morph || !*morph)
+ return 0;
+ int n = 0;
+ const char* old = morph;
+ morph = strstr(morph, MORPH_DERI_SFX);
+ if (!morph)
+ morph = strstr(old, MORPH_INFL_SFX);
+ if (!morph)
+ morph = strstr(old, MORPH_TERM_SFX);
+ while (morph) {
+ n++;
+ old = morph;
+ morph = strstr(morph + 1, MORPH_DERI_SFX);
+ if (!morph)
+ morph = strstr(old + 1, MORPH_INFL_SFX);
+ if (!morph)
+ morph = strstr(old + 1, MORPH_TERM_SFX);
+ }
+ return n;
+}
+
+/* affixation */
+std::string SuggestMgr::suggest_hentry_gen(hentry* rv, const char* pattern) {
+ std::string result;
+ int sfxcount = get_sfxcount(pattern);
+
+ if (get_sfxcount(HENTRY_DATA(rv)) > sfxcount)
+ return result;
+
+ if (HENTRY_DATA(rv)) {
+ std::string aff = pAMgr->morphgen(HENTRY_WORD(rv), rv->blen, rv->astr, rv->alen,
+ HENTRY_DATA(rv), pattern, 0);
+ if (!aff.empty()) {
+ result.append(aff);
+ result.push_back(MSEP_REC);
+ }
+ }
+
+ // check all allomorphs
+ char* p = NULL;
+ if (HENTRY_DATA(rv))
+ p = (char*)strstr(HENTRY_DATA2(rv), MORPH_ALLOMORPH);
+ while (p) {
+ p += MORPH_TAG_LEN;
+ int plen = fieldlen(p);
+ std::string allomorph(p, plen);
+ struct hentry* rv2 = pAMgr->lookup(allomorph.c_str());
+ while (rv2) {
+ // if (HENTRY_DATA(rv2) && get_sfxcount(HENTRY_DATA(rv2)) <=
+ // sfxcount) {
+ if (HENTRY_DATA(rv2)) {
+ char* st = (char*)strstr(HENTRY_DATA2(rv2), MORPH_STEM);
+ if (st && (strncmp(st + MORPH_TAG_LEN, HENTRY_WORD(rv),
+ fieldlen(st + MORPH_TAG_LEN)) == 0)) {
+ std::string aff = pAMgr->morphgen(HENTRY_WORD(rv2), rv2->blen, rv2->astr,
+ rv2->alen, HENTRY_DATA(rv2), pattern, 0);
+ if (!aff.empty()) {
+ result.append(aff);
+ result.push_back(MSEP_REC);
+ }
+ }
+ }
+ rv2 = rv2->next_homonym;
+ }
+ p = strstr(p + plen, MORPH_ALLOMORPH);
+ }
+
+ return result;
+}
+
+std::string SuggestMgr::suggest_gen(const std::vector<std::string>& desc, const std::string& in_pattern) {
+ if (desc.empty() || !pAMgr)
+ return std::string();
+
+ const char* pattern = in_pattern.c_str();
+ std::string result2;
+ std::string newpattern;
+ struct hentry* rv = NULL;
+
+ // search affixed forms with and without derivational suffixes
+ while (1) {
+ for (size_t k = 0; k < desc.size(); ++k) {
+ std::string result;
+
+ // add compound word parts (except the last one)
+ const char* s = desc[k].c_str();
+ const char* part = strstr(s, MORPH_PART);
+ if (part) {
+ const char* nextpart = strstr(part + 1, MORPH_PART);
+ while (nextpart) {
+ std::string field;
+ copy_field(field, part, MORPH_PART);
+ result.append(field);
+ part = nextpart;
+ nextpart = strstr(part + 1, MORPH_PART);
+ }
+ s = part;
+ }
+
+ std::string tok(s);
+ size_t pos = tok.find(" | ");
+ while (pos != std::string::npos) {
+ tok[pos + 1] = MSEP_ALT;
+ pos = tok.find(" | ", pos);
+ }
+ std::vector<std::string> pl = line_tok(tok, MSEP_ALT);
+ for (size_t i = 0; i < pl.size(); ++i) {
+ // remove inflectional and terminal suffixes
+ size_t is = pl[i].find(MORPH_INFL_SFX);
+ if (is != std::string::npos)
+ pl[i].resize(is);
+ size_t ts = pl[i].find(MORPH_TERM_SFX);
+ while (ts != std::string::npos) {
+ pl[i][ts] = '_';
+ ts = pl[i].find(MORPH_TERM_SFX);
+ }
+ const char* st = strstr(s, MORPH_STEM);
+ if (st) {
+ copy_field(tok, st, MORPH_STEM);
+ rv = pAMgr->lookup(tok.c_str());
+ while (rv) {
+ std::string newpat(pl[i]);
+ newpat.append(pattern);
+ std::string sg = suggest_hentry_gen(rv, newpat.c_str());
+ if (sg.empty())
+ sg = suggest_hentry_gen(rv, pattern);
+ if (!sg.empty()) {
+ std::vector<std::string> gen = line_tok(sg, MSEP_REC);
+ for (size_t j = 0; j < gen.size(); ++j) {
+ result2.push_back(MSEP_REC);
+ result2.append(result);
+ if (pl[i].find(MORPH_SURF_PFX) != std::string::npos) {
+ std::string field;
+ copy_field(field, pl[i], MORPH_SURF_PFX);
+ result2.append(field);
+ }
+ result2.append(gen[j]);
+ }
+ }
+ rv = rv->next_homonym;
+ }
+ }
+ }
+ }
+
+ if (!result2.empty() || !strstr(pattern, MORPH_DERI_SFX))
+ break;
+
+ newpattern.assign(pattern);
+ mystrrep(newpattern, MORPH_DERI_SFX, MORPH_TERM_SFX);
+ pattern = newpattern.c_str();
+ }
+ return result2;
+}
+
+// generate an n-gram score comparing s1 and s2, UTF16 version
+int SuggestMgr::ngram(int n,
+ const std::vector<w_char>& su1,
+ const std::vector<w_char>& su2,
+ int opt) {
+ int nscore = 0;
+ int ns;
+ int l1;
+ int l2;
+ int test = 0;
+
+ l1 = su1.size();
+ l2 = su2.size();
+ if (l2 == 0)
+ return 0;
+ for (int j = 1; j <= n; j++) {
+ ns = 0;
+ for (int i = 0; i <= (l1 - j); i++) {
+ int k = 0;
+ for (int l = 0; l <= (l2 - j); l++) {
+ for (k = 0; k < j; k++) {
+ const w_char& c1 = su1[i + k];
+ const w_char& c2 = su2[l + k];
+ if ((c1.l != c2.l) || (c1.h != c2.h))
+ break;
+ }
+ if (k == j) {
+ ns++;
+ break;
+ }
+ }
+ if (k != j && opt & NGRAM_WEIGHTED) {
+ ns--;
+ test++;
+ if (i == 0 || i == l1 - j)
+ ns--; // side weight
+ }
+ }
+ nscore = nscore + ns;
+ if (ns < 2 && !(opt & NGRAM_WEIGHTED))
+ break;
+ }
+
+ ns = 0;
+ if (opt & NGRAM_LONGER_WORSE)
+ ns = (l2 - l1) - 2;
+ if (opt & NGRAM_ANY_MISMATCH)
+ ns = abs(l2 - l1) - 2;
+ ns = (nscore - ((ns > 0) ? ns : 0));
+ return ns;
+}
+
+// generate an n-gram score comparing s1 and s2, non-UTF16 version
+int SuggestMgr::ngram(int n,
+ const std::string& s1,
+ const std::string& s2,
+ int opt) {
+ int nscore = 0;
+ int ns;
+ int l1;
+ int l2;
+ int test = 0;
+
+ l2 = s2.size();
+ if (l2 == 0)
+ return 0;
+ l1 = s1.size();
+ for (int j = 1; j <= n; j++) {
+ ns = 0;
+ for (int i = 0; i <= (l1 - j); i++) {
+ //s2 is haystack, s1[i..i+j) is needle
+ if (s2.find(s1.c_str()+i, 0, j) != std::string::npos) {
+ ns++;
+ } else if (opt & NGRAM_WEIGHTED) {
+ ns--;
+ test++;
+ if (i == 0 || i == l1 - j)
+ ns--; // side weight
+ }
+ }
+ nscore = nscore + ns;
+ if (ns < 2 && !(opt & NGRAM_WEIGHTED))
+ break;
+ }
+
+ ns = 0;
+ if (opt & NGRAM_LONGER_WORSE)
+ ns = (l2 - l1) - 2;
+ if (opt & NGRAM_ANY_MISMATCH)
+ ns = abs(l2 - l1) - 2;
+ ns = (nscore - ((ns > 0) ? ns : 0));
+ return ns;
+}
+
+// length of the left common substring of s1 and (decapitalised) s2, UTF version
+int SuggestMgr::leftcommonsubstring(
+ const std::vector<w_char>& su1,
+ const std::vector<w_char>& su2) {
+ int l1 = su1.size();
+ int l2 = su2.size();
+ // decapitalize dictionary word
+ if (complexprefixes) {
+ if (l1 && l2 && su1[l1 - 1] == su2[l2 - 1])
+ return 1;
+ } else {
+ unsigned short idx = su2.empty() ? 0 : (su2[0].h << 8) + su2[0].l;
+ unsigned short otheridx = su1.empty() ? 0 : (su1[0].h << 8) + su1[0].l;
+ if (otheridx != idx && (otheridx != unicodetolower(idx, langnum)))
+ return 0;
+ int i;
+ for (i = 1; (i < l1) && (i < l2) && (su1[i].l == su2[i].l) &&
+ (su1[i].h == su2[i].h);
+ i++)
+ ;
+ return i;
+ }
+ return 0;
+}
+
+// length of the left common substring of s1 and (decapitalised) s2, non-UTF
+int SuggestMgr::leftcommonsubstring(
+ const char* s1,
+ const char* s2) {
+ if (complexprefixes) {
+ int l1 = strlen(s1);
+ int l2 = strlen(s2);
+ if (l1 <= l2 && s2[l1 - 1] == s2[l2 - 1])
+ return 1;
+ } else if (csconv) {
+ const char* olds = s1;
+ // decapitalise dictionary word
+ if ((*s1 != *s2) && (*s1 != csconv[((unsigned char)*s2)].clower))
+ return 0;
+ do {
+ s1++;
+ s2++;
+ } while ((*s1 == *s2) && (*s1 != '\0'));
+ return (int)(s1 - olds);
+ }
+ return 0;
+}
+
+int SuggestMgr::commoncharacterpositions(const char* s1,
+ const char* s2,
+ int* is_swap) {
+ int num = 0;
+ int diff = 0;
+ int diffpos[2];
+ *is_swap = 0;
+ if (utf8) {
+ std::vector<w_char> su1;
+ std::vector<w_char> su2;
+ int l1 = u8_u16(su1, s1);
+ int l2 = u8_u16(su2, s2);
+
+ if (l1 <= 0 || l2 <= 0)
+ return 0;
+
+ // decapitalize dictionary word
+ if (complexprefixes) {
+ su2[l2 - 1] = lower_utf(su2[l2 - 1], langnum);
+ } else {
+ su2[0] = lower_utf(su2[0], langnum);
+ }
+ for (int i = 0; (i < l1) && (i < l2); i++) {
+ if (su1[i] == su2[i]) {
+ num++;
+ } else {
+ if (diff < 2)
+ diffpos[diff] = i;
+ diff++;
+ }
+ }
+ if ((diff == 2) && (l1 == l2) &&
+ (su1[diffpos[0]] == su2[diffpos[1]]) &&
+ (su1[diffpos[1]] == su2[diffpos[0]]))
+ *is_swap = 1;
+ } else {
+ size_t i;
+ std::string t(s2);
+ // decapitalize dictionary word
+ if (complexprefixes) {
+ size_t l2 = t.size();
+ t[l2 - 1] = csconv[(unsigned char)t[l2 - 1]].clower;
+ } else {
+ mkallsmall(t, csconv);
+ }
+ for (i = 0; i < t.size() && (*(s1 + i) != 0); ++i) {
+ if (*(s1 + i) == t[i]) {
+ num++;
+ } else {
+ if (diff < 2)
+ diffpos[diff] = i;
+ diff++;
+ }
+ }
+ if ((diff == 2) && (*(s1 + i) == 0) && i == t.size() &&
+ (*(s1 + diffpos[0]) == t[diffpos[1]]) &&
+ (*(s1 + diffpos[1]) == t[diffpos[0]]))
+ *is_swap = 1;
+ }
+ return num;
+}
+
+int SuggestMgr::mystrlen(const char* word) {
+ if (utf8) {
+ std::vector<w_char> w;
+ return u8_u16(w, word);
+ } else
+ return strlen(word);
+}
+
+// sort in decreasing order of score
+void SuggestMgr::bubblesort(char** rword, char** rword2, int* rsc, int n) {
+ int m = 1;
+ while (m < n) {
+ int j = m;
+ while (j > 0) {
+ if (rsc[j - 1] < rsc[j]) {
+ int sctmp = rsc[j - 1];
+ char* wdtmp = rword[j - 1];
+ rsc[j - 1] = rsc[j];
+ rword[j - 1] = rword[j];
+ rsc[j] = sctmp;
+ rword[j] = wdtmp;
+ if (rword2) {
+ wdtmp = rword2[j - 1];
+ rword2[j - 1] = rword2[j];
+ rword2[j] = wdtmp;
+ }
+ j--;
+ } else
+ break;
+ }
+ m++;
+ }
+ return;
+}
+
+// longest common subsequence
+void SuggestMgr::lcs(const char* s,
+ const char* s2,
+ int* l1,
+ int* l2,
+ char** result) {
+ int n, m;
+ std::vector<w_char> su;
+ std::vector<w_char> su2;
+ char* b;
+ char* c;
+ int i;
+ int j;
+ if (utf8) {
+ m = u8_u16(su, s);
+ n = u8_u16(su2, s2);
+ } else {
+ m = strlen(s);
+ n = strlen(s2);
+ }
+ c = (char*)malloc((m + 1) * (n + 1));
+ b = (char*)malloc((m + 1) * (n + 1));
+ if (!c || !b) {
+ if (c)
+ free(c);
+ if (b)
+ free(b);
+ *result = NULL;
+ return;
+ }
+ for (i = 1; i <= m; i++)
+ c[i * (n + 1)] = 0;
+ for (j = 0; j <= n; j++)
+ c[j] = 0;
+ for (i = 1; i <= m; i++) {
+ for (j = 1; j <= n; j++) {
+ if (((utf8) && (su[i - 1] == su2[j - 1])) ||
+ ((!utf8) && (s[i - 1] == s2[j - 1]))) {
+ c[i * (n + 1) + j] = c[(i - 1) * (n + 1) + j - 1] + 1;
+ b[i * (n + 1) + j] = LCS_UPLEFT;
+ } else if (c[(i - 1) * (n + 1) + j] >= c[i * (n + 1) + j - 1]) {
+ c[i * (n + 1) + j] = c[(i - 1) * (n + 1) + j];
+ b[i * (n + 1) + j] = LCS_UP;
+ } else {
+ c[i * (n + 1) + j] = c[i * (n + 1) + j - 1];
+ b[i * (n + 1) + j] = LCS_LEFT;
+ }
+ }
+ }
+ *result = b;
+ free(c);
+ *l1 = m;
+ *l2 = n;
+}
+
+int SuggestMgr::lcslen(const char* s, const char* s2) {
+ int m;
+ int n;
+ int i;
+ int j;
+ char* result;
+ int len = 0;
+ lcs(s, s2, &m, &n, &result);
+ if (!result)
+ return 0;
+ i = m;
+ j = n;
+ while ((i != 0) && (j != 0)) {
+ if (result[i * (n + 1) + j] == LCS_UPLEFT) {
+ len++;
+ i--;
+ j--;
+ } else if (result[i * (n + 1) + j] == LCS_UP) {
+ i--;
+ } else
+ j--;
+ }
+ free(result);
+ return len;
+}
+
+int SuggestMgr::lcslen(const std::string& s, const std::string& s2) {
+ return lcslen(s.c_str(), s2.c_str());
+}
diff --git a/extensions/spellcheck/hunspell/src/suggestmgr.hxx b/extensions/spellcheck/hunspell/src/suggestmgr.hxx
new file mode 100644
index 0000000000..4c2fb69032
--- /dev/null
+++ b/extensions/spellcheck/hunspell/src/suggestmgr.hxx
@@ -0,0 +1,183 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * Copyright (C) 2002-2022 N辿meth L叩szl坦
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (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.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * Hunspell is based on MySpell which is Copyright (C) 2002 Kevin Hendricks.
+ *
+ * Contributor(s): David Einstein, Davide Prina, Giuseppe Modugno,
+ * Gianluca Turconi, Simon Brouwer, Noll J叩nos, B鱈r坦 rp叩d,
+ * Goldman Eleon坦ra, Sarl坦s Tam叩s, Bencs叩th Boldizs叩r, Hal叩csy P辿ter,
+ * Dvornik L叩szl坦, Gefferth Andr叩s, Nagy Viktor, Varga D叩niel, Chris Halls,
+ * Rene Engelhard, Bram Moolenaar, Dafydd Jones, Harri Pitk辰nen
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+/*
+ * Copyright 2002 Kevin B. Hendricks, Stratford, Ontario, Canada
+ * And Contributors. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. All modifications to the source code must be clearly marked as
+ * such. Binary redistributions based on modified source code
+ * must be clearly marked as modified versions in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY KEVIN B. HENDRICKS AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
+ * KEVIN B. HENDRICKS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef SUGGESTMGR_HXX_
+#define SUGGESTMGR_HXX_
+
+#define MAX_ROOTS 100
+#define MAX_WORDS 100
+#define MAX_GUESS 200
+#define MAXNGRAMSUGS 4
+#define MAXPHONSUGS 2
+#define MAXCOMPOUNDSUGS 3
+
+#define NGRAM_LONGER_WORSE (1 << 0)
+#define NGRAM_ANY_MISMATCH (1 << 1)
+#define NGRAM_LOWERING (1 << 2)
+#define NGRAM_WEIGHTED (1 << 3)
+
+#include "atypes.hxx"
+#include "affixmgr.hxx"
+#include "hashmgr.hxx"
+#include "langnum.hxx"
+
+enum { LCS_UP, LCS_LEFT, LCS_UPLEFT };
+
+class SuggestMgr {
+ private:
+ SuggestMgr(const SuggestMgr&);
+ SuggestMgr& operator=(const SuggestMgr&);
+
+ private:
+ char* ckey;
+ size_t ckeyl;
+ std::vector<w_char> ckey_utf;
+
+ char* ctry;
+ size_t ctryl;
+ std::vector<w_char> ctry_utf;
+ bool lang_with_dash_usage;
+
+ AffixMgr* pAMgr;
+ unsigned int maxSug;
+ struct cs_info* csconv;
+ int utf8;
+ int langnum;
+ int nosplitsugs;
+ int maxngramsugs;
+ int maxcpdsugs;
+ int complexprefixes;
+
+ public:
+ SuggestMgr(const char* tryme, unsigned int maxn, AffixMgr* aptr);
+ ~SuggestMgr();
+
+ bool suggest(std::vector<std::string>& slst, const char* word, int* onlycmpdsug);
+ void ngsuggest(std::vector<std::string>& slst, const char* word, const std::vector<HashMgr*>& rHMgr, int captype);
+
+ std::string suggest_morph(const std::string& word);
+ std::string suggest_gen(const std::vector<std::string>& pl, const std::string& pattern);
+
+ private:
+ void testsug(std::vector<std::string>& wlst,
+ const std::string& candidate,
+ int cpdsuggest,
+ int* timer,
+ clock_t* timelimit);
+ int checkword(const std::string& word, int, int*, clock_t*);
+ int check_forbidden(const char*, int);
+
+ void capchars(std::vector<std::string>&, const char*, int);
+ int replchars(std::vector<std::string>&, const char*, int);
+ int doubletwochars(std::vector<std::string>&, const char*, int);
+ int forgotchar(std::vector<std::string>&, const char*, int);
+ int swapchar(std::vector<std::string>&, const char*, int);
+ int longswapchar(std::vector<std::string>&, const char*, int);
+ int movechar(std::vector<std::string>&, const char*, int);
+ int extrachar(std::vector<std::string>&, const char*, int);
+ int badcharkey(std::vector<std::string>&, const char*, int);
+ int badchar(std::vector<std::string>&, const char*, int);
+ bool twowords(std::vector<std::string>&, const char*, int, bool);
+
+ void capchars_utf(std::vector<std::string>&, const w_char*, int wl, int);
+ int doubletwochars_utf(std::vector<std::string>&, const w_char*, int wl, int);
+ int forgotchar_utf(std::vector<std::string>&, const w_char*, int wl, int);
+ int extrachar_utf(std::vector<std::string>&, const w_char*, int wl, int);
+ int badcharkey_utf(std::vector<std::string>&, const w_char*, int wl, int);
+ int badchar_utf(std::vector<std::string>&, const w_char*, int wl, int);
+ int swapchar_utf(std::vector<std::string>&, const w_char*, int wl, int);
+ int longswapchar_utf(std::vector<std::string>&, const w_char*, int, int);
+ int movechar_utf(std::vector<std::string>&, const w_char*, int, int);
+
+ int mapchars(std::vector<std::string>&, const char*, int);
+ int map_related(const char*,
+ std::string&,
+ int,
+ std::vector<std::string>& wlst,
+ int,
+ const std::vector<mapentry>&,
+ int*,
+ clock_t*);
+ int ngram(int n, const std::vector<w_char>& su1,
+ const std::vector<w_char>& su2, int opt);
+ int ngram(int n, const std::string& s1, const std::string& s2, int opt);
+ int mystrlen(const char* word);
+ int leftcommonsubstring(const std::vector<w_char>& su1,
+ const std::vector<w_char>& su2);
+ int leftcommonsubstring(const char* s1, const char* s2);
+ int commoncharacterpositions(const char* s1, const char* s2, int* is_swap);
+ void bubblesort(char** rwd, char** rwd2, int* rsc, int n);
+ void lcs(const char* s, const char* s2, int* l1, int* l2, char** result);
+ int lcslen(const char* s, const char* s2);
+ int lcslen(const std::string& s, const std::string& s2);
+ std::string suggest_hentry_gen(hentry* rv, const char* pattern);
+};
+
+#endif
diff --git a/extensions/spellcheck/hunspell/src/w_char.hxx b/extensions/spellcheck/hunspell/src/w_char.hxx
new file mode 100644
index 0000000000..7e71d04680
--- /dev/null
+++ b/extensions/spellcheck/hunspell/src/w_char.hxx
@@ -0,0 +1,72 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * Copyright (C) 2002-2022 N辿meth L叩szl坦
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (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.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * Hunspell is based on MySpell which is Copyright (C) 2002 Kevin Hendricks.
+ *
+ * Contributor(s): David Einstein, Davide Prina, Giuseppe Modugno,
+ * Gianluca Turconi, Simon Brouwer, Noll J叩nos, B鱈r坦 rp叩d,
+ * Goldman Eleon坦ra, Sarl坦s Tam叩s, Bencs叩th Boldizs叩r, Hal叩csy P辿ter,
+ * Dvornik L叩szl坦, Gefferth Andr叩s, Nagy Viktor, Varga D叩niel, Chris Halls,
+ * Rene Engelhard, Bram Moolenaar, Dafydd Jones, Harri Pitk辰nen
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#ifndef W_CHAR_HXX_
+#define W_CHAR_HXX_
+
+#include <string>
+
+#ifndef GCC
+struct w_char {
+#else
+struct __attribute__((packed)) w_char {
+#endif
+ unsigned char l;
+ unsigned char h;
+
+ friend bool operator<(const w_char a, const w_char b) {
+ unsigned short a_idx = (a.h << 8) + a.l;
+ unsigned short b_idx = (b.h << 8) + b.l;
+ return a_idx < b_idx;
+ }
+
+ friend bool operator==(const w_char a, const w_char b) {
+ return (((a).l == (b).l) && ((a).h == (b).h));
+ }
+
+ friend bool operator!=(const w_char a, const w_char b) {
+ return !(a == b);;
+ }
+};
+
+// two character arrays
+struct replentry {
+ std::string pattern;
+ std::string outstrings[4]; // med, ini, fin, isol
+};
+
+#endif
diff --git a/extensions/spellcheck/hunspell/tests/crashtests/1825445.html b/extensions/spellcheck/hunspell/tests/crashtests/1825445.html
new file mode 100644
index 0000000000..203bd2d1c3
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/crashtests/1825445.html
@@ -0,0 +1,12 @@
+<html>
+<p id="targetParagraph">
+
+<script>
+ document.designMode = 'on';
+
+ function crash() {
+ for(var i=0; i<850; i++) { targetParagraph.insertAdjacentText("afterEnd", "S".repeat(8567)); }
+ }
+ crash();
+</script>
+</html>
diff --git a/extensions/spellcheck/hunspell/tests/crashtests/crashtests.list b/extensions/spellcheck/hunspell/tests/crashtests/crashtests.list
new file mode 100644
index 0000000000..396dae83f9
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/crashtests/crashtests.list
@@ -0,0 +1 @@
+skip-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) load 1825445.html
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/1463589-utf.aff b/extensions/spellcheck/hunspell/tests/unit/data/1463589-utf.aff
new file mode 100644
index 0000000000..0a11404fd6
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/1463589-utf.aff
@@ -0,0 +1,4 @@
+# capitalized ngram suggestion test data (Unicode version) for
+# Sf.net Bug ID 1463589, reported by Frederik Fouvry.
+SET UTF-8
+MAXNGRAMSUGS 1
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/1463589-utf.dic b/extensions/spellcheck/hunspell/tests/unit/data/1463589-utf.dic
new file mode 100644
index 0000000000..8cec606034
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/1463589-utf.dic
@@ -0,0 +1,2 @@
+1
+K端hlschrank
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/1463589-utf.sug b/extensions/spellcheck/hunspell/tests/unit/data/1463589-utf.sug
new file mode 100644
index 0000000000..8a72f1e21f
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/1463589-utf.sug
@@ -0,0 +1,5 @@
+K端hlschrank
+K端hlschrank
+K端hlschrank
+K端hlschrank
+K端hlschrank
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/1463589-utf.test b/extensions/spellcheck/hunspell/tests/unit/data/1463589-utf.test
new file mode 100644
index 0000000000..cde7c54109
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/1463589-utf.test
@@ -0,0 +1,4 @@
+#!/bin/sh
+DIR="`dirname $0`"
+NAME="`basename $0 .test`"
+$DIR/test.sh $NAME -i utf-8
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/1463589-utf.wrong b/extensions/spellcheck/hunspell/tests/unit/data/1463589-utf.wrong
new file mode 100644
index 0000000000..9de6c63cdf
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/1463589-utf.wrong
@@ -0,0 +1,5 @@
+kuhlschrank
+kuehlschrank
+k端hlschrank
+Kuhlschrank
+Kuehlschrank
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/1463589.aff b/extensions/spellcheck/hunspell/tests/unit/data/1463589.aff
new file mode 100644
index 0000000000..8ecf4594e0
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/1463589.aff
@@ -0,0 +1,3 @@
+# capitalized ngram suggestion test data for
+# Sf.net Bug ID 1463589, reported by Frederik Fouvry.
+MAXNGRAMSUGS 1
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/1463589.dic b/extensions/spellcheck/hunspell/tests/unit/data/1463589.dic
new file mode 100644
index 0000000000..a3caab802f
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/1463589.dic
@@ -0,0 +1,2 @@
+1
+Khlschrank
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/1463589.sug b/extensions/spellcheck/hunspell/tests/unit/data/1463589.sug
new file mode 100644
index 0000000000..2961eddd2b
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/1463589.sug
@@ -0,0 +1,5 @@
+Khlschrank
+Khlschrank
+Khlschrank
+Khlschrank
+Khlschrank
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/1463589.test b/extensions/spellcheck/hunspell/tests/unit/data/1463589.test
new file mode 100644
index 0000000000..dc295077fb
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/1463589.test
@@ -0,0 +1,4 @@
+#!/bin/sh
+DIR="`dirname $0`"
+NAME="`basename $0 .test`"
+$DIR/test.sh $NAME -i ISO8859-1
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/1463589.wrong b/extensions/spellcheck/hunspell/tests/unit/data/1463589.wrong
new file mode 100644
index 0000000000..0f3f489698
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/1463589.wrong
@@ -0,0 +1,5 @@
+kuhlschrank
+kuehlschrank
+khlschrank
+Kuhlschrank
+Kuehlschrank
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/1592880.aff b/extensions/spellcheck/hunspell/tests/unit/data/1592880.aff
new file mode 100644
index 0000000000..0aa064e37e
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/1592880.aff
@@ -0,0 +1,20 @@
+# fix homonym handling for German dictionary project,
+# reported by Bj旦rn Jacke (sf.net Bug ID 1592880).
+SET ISO8859-1
+
+SFX N Y 1
+SFX N 0 n .
+
+SFX S Y 1
+SFX S 0 s .
+
+SFX P Y 1
+SFX P 0 en .
+
+SFX Q Y 2
+SFX Q 0 e .
+SFX Q 0 en .
+
+COMPOUNDEND z
+COMPOUNDPERMITFLAG c
+ONLYINCOMPOUND o
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/1592880.dic b/extensions/spellcheck/hunspell/tests/unit/data/1592880.dic
new file mode 100644
index 0000000000..8b0fef8141
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/1592880.dic
@@ -0,0 +1,4 @@
+3
+weg/Qoz
+weg/P
+wege
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/1592880.good b/extensions/spellcheck/hunspell/tests/unit/data/1592880.good
new file mode 100644
index 0000000000..aa00a58b12
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/1592880.good
@@ -0,0 +1,3 @@
+weg
+wege
+wegen
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/1592880.test b/extensions/spellcheck/hunspell/tests/unit/data/1592880.test
new file mode 100644
index 0000000000..7f44369060
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/1592880.test
@@ -0,0 +1,4 @@
+#!/bin/sh
+DIR="`dirname $0`"
+NAME="`basename $0 .test`"
+$DIR/test.sh $NAME
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/1695964.aff b/extensions/spellcheck/hunspell/tests/unit/data/1695964.aff
new file mode 100644
index 0000000000..359a25f3a3
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/1695964.aff
@@ -0,0 +1,10 @@
+# fix NEEDAFFIX homonym suggestion.
+# Sf.net Bug ID 1695964, reported by Bj旦rn Jacke.
+TRY esianrtolcdugmphbyfvkwESIANRTOLCDUGMPHBYFVKW
+MAXNGRAMSUGS 0
+NEEDAFFIX h
+SFX S Y 1
+SFX S 0 s .
+
+SFX e Y 1
+SFX e 0 e .
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/1695964.dic b/extensions/spellcheck/hunspell/tests/unit/data/1695964.dic
new file mode 100644
index 0000000000..ff6d110cc7
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/1695964.dic
@@ -0,0 +1,3 @@
+2
+Mull/he
+Mull/S
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/1695964.sug b/extensions/spellcheck/hunspell/tests/unit/data/1695964.sug
new file mode 100644
index 0000000000..35aedff7cc
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/1695964.sug
@@ -0,0 +1,3 @@
+Mull
+Mulle
+Mulls
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/1695964.test b/extensions/spellcheck/hunspell/tests/unit/data/1695964.test
new file mode 100644
index 0000000000..7f44369060
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/1695964.test
@@ -0,0 +1,4 @@
+#!/bin/sh
+DIR="`dirname $0`"
+NAME="`basename $0 .test`"
+$DIR/test.sh $NAME
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/1695964.wrong b/extensions/spellcheck/hunspell/tests/unit/data/1695964.wrong
new file mode 100644
index 0000000000..fd13dc8cac
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/1695964.wrong
@@ -0,0 +1,3 @@
+Mall
+Malle
+Malls
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/1706659.aff b/extensions/spellcheck/hunspell/tests/unit/data/1706659.aff
new file mode 100644
index 0000000000..66a676efa5
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/1706659.aff
@@ -0,0 +1,13 @@
+# test COMPOUNDRULE bug reported by Bj旦rn Jacke
+SET ISO8859-1
+TRY esijanrtolcdugmphbyfvkwqxz
+
+SFX A Y 5
+SFX A 0 e .
+SFX A 0 er .
+SFX A 0 en .
+SFX A 0 em .
+SFX A 0 es .
+
+COMPOUNDRULE 1
+COMPOUNDRULE vw
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/1706659.dic b/extensions/spellcheck/hunspell/tests/unit/data/1706659.dic
new file mode 100644
index 0000000000..32d461f7a9
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/1706659.dic
@@ -0,0 +1,4 @@
+3
+arbeits/v
+scheu/Aw
+farbig/A
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/1706659.test b/extensions/spellcheck/hunspell/tests/unit/data/1706659.test
new file mode 100644
index 0000000000..7f44369060
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/1706659.test
@@ -0,0 +1,4 @@
+#!/bin/sh
+DIR="`dirname $0`"
+NAME="`basename $0 .test`"
+$DIR/test.sh $NAME
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/1706659.wrong b/extensions/spellcheck/hunspell/tests/unit/data/1706659.wrong
new file mode 100644
index 0000000000..799dd31117
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/1706659.wrong
@@ -0,0 +1,3 @@
+arbeitsfarbig
+arbeitsfarbige
+arbeitsfarbiger
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/1975530.aff b/extensions/spellcheck/hunspell/tests/unit/data/1975530.aff
new file mode 100644
index 0000000000..0912050d1f
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/1975530.aff
@@ -0,0 +1,6 @@
+SET UTF-8
+IGNORE ル
+
+PFX x N 1
+PFX x 悖 惠 悖[^]
+
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/1975530.dic b/extensions/spellcheck/hunspell/tests/unit/data/1975530.dic
new file mode 100644
index 0000000000..b1b455df5a
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/1975530.dic
@@ -0,0 +1,3 @@
+2
+悖惘/x
+悖悋惘/x
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/1975530.good b/extensions/spellcheck/hunspell/tests/unit/data/1975530.good
new file mode 100644
index 0000000000..89212a57ec
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/1975530.good
@@ -0,0 +1,3 @@
+悖惘
+悖悋惘
+惠惘
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/1975530.test b/extensions/spellcheck/hunspell/tests/unit/data/1975530.test
new file mode 100644
index 0000000000..4d59c42126
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/1975530.test
@@ -0,0 +1,4 @@
+#!/bin/sh
+DIR="`dirname $0`"
+NAME="`basename $0 .test`"
+$DIR/test.sh $NAME -i UTF-8
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/1975530.wrong b/extensions/spellcheck/hunspell/tests/unit/data/1975530.wrong
new file mode 100644
index 0000000000..24cb57627a
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/1975530.wrong
@@ -0,0 +1 @@
+惠悋惘
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/2970240.aff b/extensions/spellcheck/hunspell/tests/unit/data/2970240.aff
new file mode 100644
index 0000000000..6ef95161d7
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/2970240.aff
@@ -0,0 +1,5 @@
+# test words with three parts
+CHECKCOMPOUNDPATTERN 1
+CHECKCOMPOUNDPATTERN le fi
+COMPOUNDFLAG c
+
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/2970240.dic b/extensions/spellcheck/hunspell/tests/unit/data/2970240.dic
new file mode 100644
index 0000000000..f0b6305693
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/2970240.dic
@@ -0,0 +1,4 @@
+3
+first/c
+middle/c
+last/c
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/2970240.good b/extensions/spellcheck/hunspell/tests/unit/data/2970240.good
new file mode 100644
index 0000000000..a8d3a593b6
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/2970240.good
@@ -0,0 +1 @@
+firstmiddlelast
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/2970240.test b/extensions/spellcheck/hunspell/tests/unit/data/2970240.test
new file mode 100644
index 0000000000..7f44369060
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/2970240.test
@@ -0,0 +1,4 @@
+#!/bin/sh
+DIR="`dirname $0`"
+NAME="`basename $0 .test`"
+$DIR/test.sh $NAME
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/2970240.wrong b/extensions/spellcheck/hunspell/tests/unit/data/2970240.wrong
new file mode 100644
index 0000000000..32cead611d
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/2970240.wrong
@@ -0,0 +1 @@
+lastmiddlefirst
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/2970242.aff b/extensions/spellcheck/hunspell/tests/unit/data/2970242.aff
new file mode 100644
index 0000000000..909f0fbc3d
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/2970242.aff
@@ -0,0 +1,4 @@
+CHECKCOMPOUNDPATTERN 1
+CHECKCOMPOUNDPATTERN /a /b
+COMPOUNDFLAG c
+
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/2970242.dic b/extensions/spellcheck/hunspell/tests/unit/data/2970242.dic
new file mode 100644
index 0000000000..da0d05f92a
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/2970242.dic
@@ -0,0 +1,4 @@
+3
+foo/ac
+bar/c
+baz/bc
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/2970242.good b/extensions/spellcheck/hunspell/tests/unit/data/2970242.good
new file mode 100644
index 0000000000..90ecb182fa
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/2970242.good
@@ -0,0 +1,5 @@
+foobar
+barfoo
+bazfoo
+barbaz
+bazbar
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/2970242.test b/extensions/spellcheck/hunspell/tests/unit/data/2970242.test
new file mode 100644
index 0000000000..7f44369060
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/2970242.test
@@ -0,0 +1,4 @@
+#!/bin/sh
+DIR="`dirname $0`"
+NAME="`basename $0 .test`"
+$DIR/test.sh $NAME
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/2970242.wrong b/extensions/spellcheck/hunspell/tests/unit/data/2970242.wrong
new file mode 100644
index 0000000000..9dabfec919
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/2970242.wrong
@@ -0,0 +1 @@
+foobaz
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/2999225.aff b/extensions/spellcheck/hunspell/tests/unit/data/2999225.aff
new file mode 100644
index 0000000000..ea9d0b07ba
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/2999225.aff
@@ -0,0 +1,6 @@
+COMPOUNDRULE 1
+COMPOUNDRULE ab
+
+COMPOUNDBEGIN A
+COMPOUNDEND B
+
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/2999225.dic b/extensions/spellcheck/hunspell/tests/unit/data/2999225.dic
new file mode 100644
index 0000000000..249860362e
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/2999225.dic
@@ -0,0 +1,4 @@
+3
+foo/aA
+bar/b
+baz/B
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/2999225.good b/extensions/spellcheck/hunspell/tests/unit/data/2999225.good
new file mode 100644
index 0000000000..865e15452d
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/2999225.good
@@ -0,0 +1,2 @@
+foobar
+foobaz
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/2999225.test b/extensions/spellcheck/hunspell/tests/unit/data/2999225.test
new file mode 100644
index 0000000000..7f44369060
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/2999225.test
@@ -0,0 +1,4 @@
+#!/bin/sh
+DIR="`dirname $0`"
+NAME="`basename $0 .test`"
+$DIR/test.sh $NAME
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/IJ.aff b/extensions/spellcheck/hunspell/tests/unit/data/IJ.aff
new file mode 100644
index 0000000000..c817c2e913
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/IJ.aff
@@ -0,0 +1,8 @@
+# check bad capitalisation of Dutch letter IJ.
+TRY i
+FORBIDDENWORD *
+PFX i N 1
+PFX i ij IJ ij
+
+REP 1
+REP ij IJ
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/IJ.dic b/extensions/spellcheck/hunspell/tests/unit/data/IJ.dic
new file mode 100644
index 0000000000..ecaf91d212
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/IJ.dic
@@ -0,0 +1,3 @@
+1
+ijs/i
+Ijs/*
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/IJ.good b/extensions/spellcheck/hunspell/tests/unit/data/IJ.good
new file mode 100644
index 0000000000..5f888f057d
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/IJ.good
@@ -0,0 +1,2 @@
+ijs
+IJs
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/IJ.sug b/extensions/spellcheck/hunspell/tests/unit/data/IJ.sug
new file mode 100644
index 0000000000..582b7956b5
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/IJ.sug
@@ -0,0 +1 @@
+IJs, ijs
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/IJ.test b/extensions/spellcheck/hunspell/tests/unit/data/IJ.test
new file mode 100644
index 0000000000..7f44369060
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/IJ.test
@@ -0,0 +1,4 @@
+#!/bin/sh
+DIR="`dirname $0`"
+NAME="`basename $0 .test`"
+$DIR/test.sh $NAME
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/IJ.wrong b/extensions/spellcheck/hunspell/tests/unit/data/IJ.wrong
new file mode 100644
index 0000000000..54bbb475a0
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/IJ.wrong
@@ -0,0 +1 @@
+Ijs
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/Makefile.am b/extensions/spellcheck/hunspell/tests/unit/data/Makefile.am
new file mode 100644
index 0000000000..8018ccf7ba
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/Makefile.am
@@ -0,0 +1,693 @@
+## Process this file with automake to create Makefile.in
+
+SUBDIRS = suggestiontest
+
+XFAIL_TESTS = @XFAILED@
+
+TESTS = \
+affixes.test \
+condition.test \
+condition_utf.test \
+base.test \
+base_utf.test \
+allcaps.test \
+allcaps_utf.test \
+allcaps2.test \
+allcaps3.test \
+keepcase.test \
+i58202.test \
+map.test \
+rep.test \
+sug.test \
+sugutf.test \
+phone.test \
+flag.test \
+flaglong.test \
+flagnum.test \
+flagutf8.test \
+slash.test \
+forbiddenword.test \
+nosuggest.test \
+alias.test \
+alias2.test \
+alias3.test \
+breakdefault.test \
+break.test \
+needaffix.test \
+needaffix2.test \
+needaffix3.test \
+needaffix4.test \
+needaffix5.test \
+circumfix.test \
+fogemorpheme.test \
+onlyincompound.test \
+complexprefixes.test \
+complexprefixes2.test \
+complexprefixesutf.test \
+conditionalprefix.test \
+zeroaffix.test \
+utf8.test \
+utf8_bom.test \
+utf8_bom2.test \
+utf8_nonbmp.test \
+compoundflag.test \
+compoundrule.test \
+compoundrule2.test \
+compoundrule3.test \
+compoundrule4.test \
+compoundrule5.test \
+compoundrule6.test \
+compoundrule7.test \
+compoundrule8.test \
+compoundaffix.test \
+compoundaffix2.test \
+compoundaffix3.test \
+checkcompounddup.test \
+checkcompoundtriple.test \
+simplifiedtriple.test \
+checkcompoundrep.test \
+checkcompoundcase2.test \
+checkcompoundcaseutf.test \
+checkcompoundpattern.test \
+checkcompoundpattern2.test \
+checkcompoundpattern3.test \
+checkcompoundpattern4.test \
+utfcompound.test \
+checksharps.test \
+checksharpsutf.test \
+germancompounding.test \
+germancompoundingold.test \
+i35725.test \
+i53643.test \
+i54633.test \
+i54980.test \
+maputf.test \
+reputf.test \
+ignore.test \
+ignoreutf.test \
+1592880.test \
+1695964.test \
+1463589.test \
+1463589_utf.test \
+IJ.test \
+i68568.test \
+i68568utf.test \
+1706659.test \
+digits_in_words.test \
+colons_in_words.test \
+ngram_utf_fix.test \
+morph.test \
+1975530.test \
+fullstrip.test \
+iconv.test \
+oconv.test \
+encoding.test \
+korean.test \
+opentaal_forbiddenword1.test \
+opentaal_forbiddenword2.test \
+opentaal_keepcase.test \
+arabic.test \
+2970240.test \
+2970242.test \
+breakoff.test \
+opentaal_cpdpat.test \
+opentaal_cpdpat2.test \
+2999225.test \
+onlyincompound2.test \
+forceucase.test \
+warn.test
+
+# infixes.test
+
+distclean-local:
+ -rm -rf testSubDir
+
+EXTRA_DIST = \
+test.sh \
+affixes.aff \
+affixes.dic \
+affixes.good \
+affixes.test \
+condition.aff \
+condition.dic \
+condition.good \
+condition.test \
+condition.wrong \
+condition_utf.aff \
+condition_utf.dic \
+condition_utf.good \
+condition_utf.test \
+condition_utf.wrong \
+base.aff \
+base.dic \
+base.good \
+base.sug \
+base.test \
+base.wrong \
+base_utf.aff \
+base_utf.dic \
+base_utf.good \
+base_utf.sug \
+base_utf.test \
+base_utf.wrong \
+allcaps.aff \
+allcaps.dic \
+allcaps.good \
+allcaps.sug \
+allcaps.test \
+allcaps.wrong \
+allcaps2.aff \
+allcaps2.dic \
+allcaps2.good \
+allcaps2.sug \
+allcaps2.test \
+allcaps2.wrong \
+allcaps3.aff \
+allcaps3.dic \
+allcaps3.good \
+allcaps3.test \
+allcaps3.wrong \
+allcaps_utf.aff \
+allcaps_utf.dic \
+allcaps_utf.good \
+allcaps_utf.sug \
+allcaps_utf.test \
+allcaps_utf.wrong \
+keepcase.aff \
+keepcase.dic \
+keepcase.good \
+keepcase.sug \
+keepcase.test \
+keepcase.wrong \
+map.aff \
+map.dic \
+map.sug \
+map.test \
+map.wrong \
+rep.aff \
+rep.dic \
+rep.sug \
+rep.test \
+rep.wrong \
+sug.aff \
+sug.dic \
+sug.sug \
+sug.test \
+sug.wrong \
+sugutf.aff \
+sugutf.dic \
+sugutf.sug \
+sugutf.test \
+sugutf.wrong \
+phone.aff \
+phone.dic \
+phone.sug \
+phone.test \
+phone.wrong \
+alias.aff \
+alias.dic \
+alias.good \
+alias.test \
+alias2.aff \
+alias2.dic \
+alias2.good \
+alias2.morph \
+alias2.test \
+alias3.aff \
+alias3.dic \
+alias3.good \
+alias3.morph \
+alias3.test \
+break.aff \
+break.dic \
+break.good \
+break.test \
+break.wrong \
+breakdefault.aff \
+breakdefault.dic \
+breakdefault.good \
+breakdefault.sug \
+breakdefault.test \
+breakdefault.wrong \
+circumfix.aff \
+circumfix.dic \
+circumfix.good \
+circumfix.morph \
+circumfix.test \
+circumfix.wrong \
+fogemorpheme.aff \
+fogemorpheme.dic \
+fogemorpheme.good \
+fogemorpheme.test \
+fogemorpheme.wrong \
+onlyincompound.aff \
+onlyincompound.dic \
+onlyincompound.good \
+onlyincompound.sug \
+onlyincompound.test \
+onlyincompound.wrong \
+forbiddenword.aff \
+forbiddenword.dic \
+forbiddenword.good \
+forbiddenword.test \
+forbiddenword.wrong \
+nosuggest.aff \
+nosuggest.dic \
+nosuggest.good \
+nosuggest.sug \
+nosuggest.test \
+nosuggest.wrong \
+germancompounding.aff \
+germancompounding.dic \
+germancompounding.good \
+germancompounding.test \
+germancompounding.wrong \
+germancompoundingold.aff \
+germancompoundingold.dic \
+germancompoundingold.good \
+germancompoundingold.test \
+germancompoundingold.wrong \
+needaffix2.aff \
+needaffix2.dic \
+needaffix2.good \
+needaffix2.morph \
+needaffix2.test \
+needaffix3.aff \
+needaffix3.dic \
+needaffix3.good \
+needaffix3.test \
+needaffix3.wrong \
+needaffix4.aff \
+needaffix4.dic \
+needaffix4.good \
+needaffix4.test \
+needaffix5.aff \
+needaffix5.dic \
+needaffix5.good \
+needaffix5.test \
+needaffix5.wrong \
+needaffix.aff \
+needaffix.dic \
+needaffix.good \
+needaffix.test \
+needaffix.wrong \
+zeroaffix.aff \
+zeroaffix.dic \
+zeroaffix.good \
+zeroaffix.morph \
+zeroaffix.test \
+utf8.aff \
+utf8.dic \
+utf8.good \
+utf8.test \
+utf8_bom.aff \
+utf8_bom.dic \
+utf8_bom.good \
+utf8_bom.test \
+utf8_bom2.aff \
+utf8_bom2.dic \
+utf8_bom2.good \
+utf8_bom2.test \
+utf8_nonbmp.aff \
+utf8_nonbmp.dic \
+utf8_nonbmp.good \
+utf8_nonbmp.sug \
+utf8_nonbmp.test \
+utf8_nonbmp.wrong \
+utfcompound.aff \
+utfcompound.dic \
+utfcompound.good \
+utfcompound.test \
+utfcompound.wrong \
+compoundflag.aff \
+compoundflag.dic \
+compoundflag.good \
+compoundflag.test \
+compoundflag.wrong \
+compoundrule.aff \
+compoundrule.dic \
+compoundrule.good \
+compoundrule.test \
+compoundrule.wrong \
+compoundrule2.aff \
+compoundrule2.dic \
+compoundrule2.good \
+compoundrule2.test \
+compoundrule2.wrong \
+compoundrule3.aff \
+compoundrule3.dic \
+compoundrule3.good \
+compoundrule3.test \
+compoundrule3.wrong \
+compoundrule4.aff \
+compoundrule4.dic \
+compoundrule4.good \
+compoundrule4.test \
+compoundrule4.wrong \
+compoundrule5.aff \
+compoundrule5.dic \
+compoundrule5.good \
+compoundrule5.morph \
+compoundrule5.test \
+compoundrule5.wrong \
+compoundrule6.aff \
+compoundrule6.dic \
+compoundrule6.good \
+compoundrule6.test \
+compoundrule6.wrong \
+compoundrule7.aff \
+compoundrule7.dic \
+compoundrule7.good \
+compoundrule7.test \
+compoundrule7.wrong \
+compoundrule8.aff \
+compoundrule8.dic \
+compoundrule8.good \
+compoundrule8.test \
+compoundrule8.wrong \
+compoundaffix.aff \
+compoundaffix.dic \
+compoundaffix.good \
+compoundaffix.test \
+compoundaffix.wrong \
+compoundaffix2.aff \
+compoundaffix2.dic \
+compoundaffix2.good \
+compoundaffix2.test \
+compoundaffix3.aff \
+compoundaffix3.dic \
+compoundaffix3.good \
+compoundaffix3.test \
+compoundaffix3.wrong \
+checkcompounddup.aff \
+checkcompounddup.dic \
+checkcompounddup.good \
+checkcompounddup.test \
+checkcompounddup.wrong \
+checkcompoundcase.aff \
+checkcompoundcase.dic \
+checkcompoundcase.good \
+checkcompoundcase.test \
+checkcompoundcase.wrong \
+checkcompoundcase2.aff \
+checkcompoundcase2.dic \
+checkcompoundcase2.good \
+checkcompoundcase2.test \
+checkcompoundcase2.wrong \
+checkcompoundcaseutf.aff \
+checkcompoundcaseutf.dic \
+checkcompoundcaseutf.good \
+checkcompoundcaseutf.test \
+checkcompoundcaseutf.wrong \
+checkcompoundrep.aff \
+checkcompoundrep.dic \
+checkcompoundrep.good \
+checkcompoundrep.test \
+checkcompoundrep.wrong \
+checkcompoundtriple.aff \
+checkcompoundtriple.dic \
+checkcompoundtriple.good \
+checkcompoundtriple.test \
+checkcompoundtriple.wrong \
+simplifiedtriple.aff \
+simplifiedtriple.dic \
+simplifiedtriple.good \
+simplifiedtriple.test \
+simplifiedtriple.wrong \
+checkcompoundpattern.aff \
+checkcompoundpattern.dic \
+checkcompoundpattern.good \
+checkcompoundpattern.test \
+checkcompoundpattern.wrong \
+checkcompoundpattern2.aff \
+checkcompoundpattern2.dic \
+checkcompoundpattern2.good \
+checkcompoundpattern2.test \
+checkcompoundpattern2.wrong \
+checkcompoundpattern3.aff \
+checkcompoundpattern3.dic \
+checkcompoundpattern3.good \
+checkcompoundpattern3.test \
+checkcompoundpattern3.wrong \
+checkcompoundpattern4.aff \
+checkcompoundpattern4.dic \
+checkcompoundpattern4.good \
+checkcompoundpattern4.test \
+checkcompoundpattern4.wrong \
+checksharps.aff \
+checksharps.dic \
+checksharps.good \
+checksharps.sug \
+checksharps.test \
+checksharps.wrong \
+checksharpsutf.aff \
+checksharpsutf.dic \
+checksharpsutf.good \
+checksharpsutf.sug \
+checksharpsutf.test \
+checksharpsutf.wrong \
+conditionalprefix.aff \
+conditionalprefix.dic \
+conditionalprefix.good \
+conditionalprefix.morph \
+conditionalprefix.test \
+conditionalprefix.wrong \
+flaglong.aff \
+flaglong.dic \
+flaglong.good \
+flaglong.test \
+flagnum.aff \
+flagnum.dic \
+flagnum.good \
+flagnum.test \
+flag.aff \
+flag.dic \
+flag.good \
+flag.test \
+flagutf8.aff \
+flagutf8.dic \
+flagutf8.good \
+flagutf8.test \
+complexprefixes.aff \
+complexprefixes.dic \
+complexprefixes.good \
+complexprefixes.wrong \
+complexprefixes.test \
+complexprefixes2.aff \
+complexprefixes2.dic \
+complexprefixes2.good \
+complexprefixes2.test \
+complexprefixesutf.aff \
+complexprefixesutf.dic \
+complexprefixesutf.good \
+complexprefixesutf.wrong \
+complexprefixesutf.test \
+i35725.aff \
+i35725.dic \
+i35725.good \
+i35725.sug \
+i35725.test \
+i35725.wrong \
+i53643.aff \
+i53643.dic \
+i53643.good \
+i53643.test \
+i53643.wrong \
+i54633.aff \
+i54633.dic \
+i54633.good \
+i54633.sug \
+i54633.test \
+i54633.wrong \
+i54980.aff \
+i54980.dic \
+i54980.good \
+i54980.test \
+i58202.aff \
+i58202.dic \
+i58202.good \
+i58202.sug \
+i58202.test \
+i58202.wrong \
+maputf.aff \
+maputf.dic \
+maputf.sug \
+maputf.wrong \
+maputf.test \
+reputf.aff \
+reputf.dic \
+reputf.sug \
+reputf.wrong \
+reputf.test \
+slash.aff \
+slash.dic \
+slash.good \
+slash.test \
+ignore.aff \
+ignore.dic \
+ignore.good \
+ignore.test \
+ignoreutf.aff \
+ignoreutf.dic \
+ignoreutf.good \
+ignoreutf.test \
+1592880.aff \
+1592880.dic \
+1592880.good \
+1592880.test \
+1695964.aff \
+1695964.dic \
+1695964.sug \
+1695964.test \
+1695964.wrong \
+1463589.aff \
+1463589.dic \
+1463589.sug \
+1463589.test \
+1463589.wrong \
+1463589_utf.aff \
+1463589_utf.dic \
+1463589_utf.sug \
+1463589_utf.test \
+1463589_utf.wrong \
+IJ.aff \
+IJ.dic \
+IJ.good \
+IJ.sug \
+IJ.test \
+IJ.wrong \
+i68568.aff \
+i68568.dic \
+i68568.test \
+i68568.wrong \
+i68568utf.aff \
+i68568utf.dic \
+i68568utf.test \
+i68568utf.wrong \
+1706659.aff \
+1706659.dic \
+1706659.test \
+1706659.wrong \
+digits_in_words.aff \
+digits_in_words.dic \
+digits_in_words.test \
+digits_in_words.wrong \
+colons_in_words.aff \
+colons_in_words.dic \
+colons_in_words.test \
+ngram_utf_fix.aff \
+ngram_utf_fix.dic \
+ngram_utf_fix.good \
+ngram_utf_fix.sug \
+ngram_utf_fix.test \
+ngram_utf_fix.wrong \
+morph.aff \
+morph.dic \
+morph.good \
+morph.morph \
+morph.test \
+1975530.aff \
+1975530.dic \
+1975530.good \
+1975530.test \
+1975530.wrong \
+fullstrip.aff \
+fullstrip.dic \
+fullstrip.good \
+fullstrip.test \
+iconv.aff \
+iconv.dic \
+iconv.good \
+iconv.test \
+oconv.aff \
+oconv.dic \
+oconv.good \
+oconv.sug \
+oconv.test \
+oconv.wrong \
+encoding.aff \
+encoding.dic \
+encoding.good \
+encoding.test \
+opentaal_forbiddenword1.aff \
+opentaal_forbiddenword1.dic \
+opentaal_forbiddenword1.good \
+opentaal_forbiddenword1.sug \
+opentaal_forbiddenword1.test \
+opentaal_forbiddenword1.wrong \
+opentaal_forbiddenword2.aff \
+opentaal_forbiddenword2.dic \
+opentaal_forbiddenword2.good \
+opentaal_forbiddenword2.sug \
+opentaal_forbiddenword2.test \
+opentaal_forbiddenword2.wrong \
+opentaal_forbiddenword2.aff \
+opentaal_forbiddenword2.dic \
+opentaal_forbiddenword2.good \
+opentaal_forbiddenword2.sug \
+opentaal_forbiddenword2.test \
+opentaal_forbiddenword2.wrong \
+opentaal_keepcase.aff \
+opentaal_keepcase.dic \
+opentaal_keepcase.good \
+opentaal_keepcase.sug \
+opentaal_keepcase.test \
+opentaal_keepcase.wrong \
+arabic.aff \
+arabic.dic \
+arabic.wrong \
+arabic.test \
+2970240.aff \
+2970240.dic \
+2970240.good \
+2970240.wrong \
+2970240.test \
+2970242.aff \
+2970242.dic \
+2970242.good \
+2970242.wrong \
+2970242.test \
+breakoff.aff \
+breakoff.dic \
+breakoff.good \
+breakoff.wrong \
+breakoff.test \
+opentaal_cpdpat.aff \
+opentaal_cpdpat.dic \
+opentaal_cpdpat.good \
+opentaal_cpdpat.wrong \
+opentaal_cpdpat.test \
+opentaal_cpdpat2.aff \
+opentaal_cpdpat2.dic \
+opentaal_cpdpat2.good \
+opentaal_cpdpat2.wrong \
+opentaal_cpdpat2.test \
+2999225.aff \
+2999225.dic \
+2999225.good \
+2999225.test \
+korean.aff \
+korean.dic \
+korean.good \
+korean.wrong \
+korean.test \
+onlyincompound2.aff \
+onlyincompound2.dic \
+onlyincompound2.good \
+onlyincompound2.test \
+onlyincompound2.wrong \
+forceucase.aff \
+forceucase.dic \
+forceucase.good \
+forceucase.sug \
+forceucase.wrong \
+forceucase.test \
+warn.aff \
+warn.dic \
+warn.good \
+warn.test
+
+# infixes.aff
+# infixes.dic
+# infixes.good
+# infixes.test
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/Makefile.in b/extensions/spellcheck/hunspell/tests/unit/data/Makefile.in
new file mode 100644
index 0000000000..a27e048758
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/Makefile.in
@@ -0,0 +1,1416 @@
+# Makefile.in generated by automake 1.11.1 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+# 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation,
+# Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+VPATH = @srcdir@
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+target_triplet = @target@
+subdir = tests
+DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/m4/codeset.m4 \
+ $(top_srcdir)/m4/gettext.m4 $(top_srcdir)/m4/glibc2.m4 \
+ $(top_srcdir)/m4/glibc21.m4 $(top_srcdir)/m4/iconv.m4 \
+ $(top_srcdir)/m4/intdiv0.m4 $(top_srcdir)/m4/intl.m4 \
+ $(top_srcdir)/m4/intlmacosx.m4 $(top_srcdir)/m4/intmax.m4 \
+ $(top_srcdir)/m4/inttypes-pri.m4 \
+ $(top_srcdir)/m4/inttypes_h.m4 $(top_srcdir)/m4/lcmessage.m4 \
+ $(top_srcdir)/m4/lib-ld.m4 $(top_srcdir)/m4/lib-link.m4 \
+ $(top_srcdir)/m4/lib-prefix.m4 $(top_srcdir)/m4/libtool.m4 \
+ $(top_srcdir)/m4/lock.m4 $(top_srcdir)/m4/longlong.m4 \
+ $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \
+ $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \
+ $(top_srcdir)/m4/nls.m4 $(top_srcdir)/m4/po.m4 \
+ $(top_srcdir)/m4/printf-posix.m4 $(top_srcdir)/m4/progtest.m4 \
+ $(top_srcdir)/m4/size_max.m4 $(top_srcdir)/m4/stdint_h.m4 \
+ $(top_srcdir)/m4/uintmax_t.m4 $(top_srcdir)/m4/visibility.m4 \
+ $(top_srcdir)/m4/wchar_t.m4 $(top_srcdir)/m4/wint_t.m4 \
+ $(top_srcdir)/m4/xsize.m4 $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
+CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+SOURCES =
+DIST_SOURCES =
+RECURSIVE_TARGETS = all-recursive check-recursive dvi-recursive \
+ html-recursive info-recursive install-data-recursive \
+ install-dvi-recursive install-exec-recursive \
+ install-html-recursive install-info-recursive \
+ install-pdf-recursive install-ps-recursive install-recursive \
+ installcheck-recursive installdirs-recursive pdf-recursive \
+ ps-recursive uninstall-recursive
+RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \
+ distclean-recursive maintainer-clean-recursive
+AM_RECURSIVE_TARGETS = $(RECURSIVE_TARGETS:-recursive=) \
+ $(RECURSIVE_CLEAN_TARGETS:-recursive=) tags TAGS ctags CTAGS \
+ distdir
+ETAGS = etags
+CTAGS = ctags
+am__tty_colors = \
+red=; grn=; lgn=; blu=; std=
+DIST_SUBDIRS = $(SUBDIRS)
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+am__relativize = \
+ dir0=`pwd`; \
+ sed_first='s,^\([^/]*\)/.*$$,\1,'; \
+ sed_rest='s,^[^/]*/*,,'; \
+ sed_last='s,^.*/\([^/]*\)$$,\1,'; \
+ sed_butlast='s,/*[^/]*$$,,'; \
+ while test -n "$$dir1"; do \
+ first=`echo "$$dir1" | sed -e "$$sed_first"`; \
+ if test "$$first" != "."; then \
+ if test "$$first" = ".."; then \
+ dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \
+ dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \
+ else \
+ first2=`echo "$$dir2" | sed -e "$$sed_first"`; \
+ if test "$$first2" = "$$first"; then \
+ dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \
+ else \
+ dir2="../$$dir2"; \
+ fi; \
+ dir0="$$dir0"/"$$first"; \
+ fi; \
+ fi; \
+ dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \
+ done; \
+ reldir="$$dir2"
+ACLOCAL = @ACLOCAL@
+ALLOCA = @ALLOCA@
+AMTAR = @AMTAR@
+AR = @AR@
+AS = @AS@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+BUILD_INCLUDED_LIBINTL = @BUILD_INCLUDED_LIBINTL@
+CATOBJEXT = @CATOBJEXT@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CFLAG_VISIBILITY = @CFLAG_VISIBILITY@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CURSESLIB = @CURSESLIB@
+CXX = @CXX@
+CXXCPP = @CXXCPP@
+CXXDEPMODE = @CXXDEPMODE@
+CXXFLAGS = @CXXFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DATADIRNAME = @DATADIRNAME@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DLLTOOL = @DLLTOOL@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+FGREP = @FGREP@
+GENCAT = @GENCAT@
+GETTEXT_MACRO_VERSION = @GETTEXT_MACRO_VERSION@
+GLIBC2 = @GLIBC2@
+GLIBC21 = @GLIBC21@
+GMSGFMT = @GMSGFMT@
+GMSGFMT_015 = @GMSGFMT_015@
+GREP = @GREP@
+HAVE_ASPRINTF = @HAVE_ASPRINTF@
+HAVE_POSIX_PRINTF = @HAVE_POSIX_PRINTF@
+HAVE_SNPRINTF = @HAVE_SNPRINTF@
+HAVE_VISIBILITY = @HAVE_VISIBILITY@
+HAVE_WPRINTF = @HAVE_WPRINTF@
+HUNSPELL_VERSION_MAJOR = @HUNSPELL_VERSION_MAJOR@
+HUNSPELL_VERSION_MINOR = @HUNSPELL_VERSION_MINOR@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+INSTOBJEXT = @INSTOBJEXT@
+INTLBISON = @INTLBISON@
+INTLLIBS = @INTLLIBS@
+INTLOBJS = @INTLOBJS@
+INTL_LIBTOOL_SUFFIX_PREFIX = @INTL_LIBTOOL_SUFFIX_PREFIX@
+INTL_MACOSX_LIBS = @INTL_MACOSX_LIBS@
+LD = @LD@
+LDFLAGS = @LDFLAGS@
+LIBICONV = @LIBICONV@
+LIBINTL = @LIBINTL@
+LIBMULTITHREAD = @LIBMULTITHREAD@
+LIBOBJS = @LIBOBJS@
+LIBPTH = @LIBPTH@
+LIBPTH_PREFIX = @LIBPTH_PREFIX@
+LIBS = @LIBS@
+LIBTHREAD = @LIBTHREAD@
+LIBTOOL = @LIBTOOL@
+LIPO = @LIPO@
+LN_S = @LN_S@
+LTLIBC = @LTLIBC@
+LTLIBICONV = @LTLIBICONV@
+LTLIBINTL = @LTLIBINTL@
+LTLIBMULTITHREAD = @LTLIBMULTITHREAD@
+LTLIBOBJS = @LTLIBOBJS@
+LTLIBPTH = @LTLIBPTH@
+LTLIBTHREAD = @LTLIBTHREAD@
+MAKEINFO = @MAKEINFO@
+MKDIR_P = @MKDIR_P@
+MSGFMT = @MSGFMT@
+MSGFMT_015 = @MSGFMT_015@
+MSGMERGE = @MSGMERGE@
+NM = @NM@
+NMEDIT = @NMEDIT@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+POSUB = @POSUB@
+PRI_MACROS_BROKEN = @PRI_MACROS_BROKEN@
+RANLIB = @RANLIB@
+READLINELIB = @READLINELIB@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STRIP = @STRIP@
+USE_INCLUDED_LIBINTL = @USE_INCLUDED_LIBINTL@
+USE_NLS = @USE_NLS@
+VERSION = @VERSION@
+WINDRES = @WINDRES@
+WOE32 = @WOE32@
+WOE32DLL = @WOE32DLL@
+XFAILED = @XFAILED@
+XGETTEXT = @XGETTEXT@
+XGETTEXT_015 = @XGETTEXT_015@
+XGETTEXT_EXTRA_OPTIONS = @XGETTEXT_EXTRA_OPTIONS@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_CXX = @ac_ct_CXX@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+lt_ECHO = @lt_ECHO@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+sysconfdir = @sysconfdir@
+target = @target@
+target_alias = @target_alias@
+target_cpu = @target_cpu@
+target_os = @target_os@
+target_vendor = @target_vendor@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+SUBDIRS = suggestiontest
+XFAIL_TESTS = @XFAILED@
+TESTS = \
+affixes.test \
+condition.test \
+condition_utf.test \
+base.test \
+base_utf.test \
+allcaps.test \
+allcaps_utf.test \
+allcaps2.test \
+allcaps3.test \
+keepcase.test \
+i58202.test \
+map.test \
+rep.test \
+sug.test \
+sugutf.test \
+phone.test \
+flag.test \
+flaglong.test \
+flagnum.test \
+flagutf8.test \
+slash.test \
+forbiddenword.test \
+nosuggest.test \
+alias.test \
+alias2.test \
+alias3.test \
+breakdefault.test \
+break.test \
+needaffix.test \
+needaffix2.test \
+needaffix3.test \
+needaffix4.test \
+needaffix5.test \
+circumfix.test \
+fogemorpheme.test \
+onlyincompound.test \
+complexprefixes.test \
+complexprefixes2.test \
+complexprefixesutf.test \
+conditionalprefix.test \
+zeroaffix.test \
+utf8.test \
+utf8_bom.test \
+utf8_bom2.test \
+utf8_nonbmp.test \
+compoundflag.test \
+compoundrule.test \
+compoundrule2.test \
+compoundrule3.test \
+compoundrule4.test \
+compoundrule5.test \
+compoundrule6.test \
+compoundrule7.test \
+compoundrule8.test \
+compoundaffix.test \
+compoundaffix2.test \
+compoundaffix3.test \
+checkcompounddup.test \
+checkcompoundtriple.test \
+simplifiedtriple.test \
+checkcompoundrep.test \
+checkcompoundcase2.test \
+checkcompoundcaseutf.test \
+checkcompoundpattern.test \
+checkcompoundpattern2.test \
+checkcompoundpattern3.test \
+checkcompoundpattern4.test \
+utfcompound.test \
+checksharps.test \
+checksharpsutf.test \
+germancompounding.test \
+germancompoundingold.test \
+i35725.test \
+i53643.test \
+i54633.test \
+i54980.test \
+maputf.test \
+reputf.test \
+ignore.test \
+ignoreutf.test \
+1592880.test \
+1695964.test \
+1463589.test \
+1463589_utf.test \
+IJ.test \
+i68568.test \
+i68568utf.test \
+1706659.test \
+digits_in_words.test \
+colons_in_words.test \
+ngram_utf_fix.test \
+morph.test \
+1975530.test \
+fullstrip.test \
+iconv.test \
+oconv.test \
+encoding.test \
+korean.test \
+opentaal_forbiddenword1.test \
+opentaal_forbiddenword2.test \
+opentaal_keepcase.test \
+arabic.test \
+2970240.test \
+2970242.test \
+breakoff.test \
+opentaal_cpdpat.test \
+opentaal_cpdpat2.test \
+2999225.test \
+onlyincompound2.test \
+forceucase.test \
+warn.test
+
+EXTRA_DIST = \
+test.sh \
+affixes.aff \
+affixes.dic \
+affixes.good \
+affixes.test \
+condition.aff \
+condition.dic \
+condition.good \
+condition.test \
+condition.wrong \
+condition_utf.aff \
+condition_utf.dic \
+condition_utf.good \
+condition_utf.test \
+condition_utf.wrong \
+base.aff \
+base.dic \
+base.good \
+base.sug \
+base.test \
+base.wrong \
+base_utf.aff \
+base_utf.dic \
+base_utf.good \
+base_utf.sug \
+base_utf.test \
+base_utf.wrong \
+allcaps.aff \
+allcaps.dic \
+allcaps.good \
+allcaps.sug \
+allcaps.test \
+allcaps.wrong \
+allcaps2.aff \
+allcaps2.dic \
+allcaps2.good \
+allcaps2.sug \
+allcaps2.test \
+allcaps2.wrong \
+allcaps3.aff \
+allcaps3.dic \
+allcaps3.good \
+allcaps3.test \
+allcaps3.wrong \
+allcaps_utf.aff \
+allcaps_utf.dic \
+allcaps_utf.good \
+allcaps_utf.sug \
+allcaps_utf.test \
+allcaps_utf.wrong \
+keepcase.aff \
+keepcase.dic \
+keepcase.good \
+keepcase.sug \
+keepcase.test \
+keepcase.wrong \
+map.aff \
+map.dic \
+map.sug \
+map.test \
+map.wrong \
+rep.aff \
+rep.dic \
+rep.sug \
+rep.test \
+rep.wrong \
+sug.aff \
+sug.dic \
+sug.sug \
+sug.test \
+sug.wrong \
+sugutf.aff \
+sugutf.dic \
+sugutf.sug \
+sugutf.test \
+sugutf.wrong \
+phone.aff \
+phone.dic \
+phone.sug \
+phone.test \
+phone.wrong \
+alias.aff \
+alias.dic \
+alias.good \
+alias.test \
+alias2.aff \
+alias2.dic \
+alias2.good \
+alias2.morph \
+alias2.test \
+alias3.aff \
+alias3.dic \
+alias3.good \
+alias3.morph \
+alias3.test \
+break.aff \
+break.dic \
+break.good \
+break.test \
+break.wrong \
+breakdefault.aff \
+breakdefault.dic \
+breakdefault.good \
+breakdefault.sug \
+breakdefault.test \
+breakdefault.wrong \
+circumfix.aff \
+circumfix.dic \
+circumfix.good \
+circumfix.morph \
+circumfix.test \
+circumfix.wrong \
+fogemorpheme.aff \
+fogemorpheme.dic \
+fogemorpheme.good \
+fogemorpheme.test \
+fogemorpheme.wrong \
+onlyincompound.aff \
+onlyincompound.dic \
+onlyincompound.good \
+onlyincompound.sug \
+onlyincompound.test \
+onlyincompound.wrong \
+forbiddenword.aff \
+forbiddenword.dic \
+forbiddenword.good \
+forbiddenword.test \
+forbiddenword.wrong \
+nosuggest.aff \
+nosuggest.dic \
+nosuggest.good \
+nosuggest.sug \
+nosuggest.test \
+nosuggest.wrong \
+germancompounding.aff \
+germancompounding.dic \
+germancompounding.good \
+germancompounding.test \
+germancompounding.wrong \
+germancompoundingold.aff \
+germancompoundingold.dic \
+germancompoundingold.good \
+germancompoundingold.test \
+germancompoundingold.wrong \
+needaffix2.aff \
+needaffix2.dic \
+needaffix2.good \
+needaffix2.morph \
+needaffix2.test \
+needaffix3.aff \
+needaffix3.dic \
+needaffix3.good \
+needaffix3.test \
+needaffix3.wrong \
+needaffix4.aff \
+needaffix4.dic \
+needaffix4.good \
+needaffix4.test \
+needaffix5.aff \
+needaffix5.dic \
+needaffix5.good \
+needaffix5.test \
+needaffix5.wrong \
+needaffix.aff \
+needaffix.dic \
+needaffix.good \
+needaffix.test \
+needaffix.wrong \
+zeroaffix.aff \
+zeroaffix.dic \
+zeroaffix.good \
+zeroaffix.morph \
+zeroaffix.test \
+utf8.aff \
+utf8.dic \
+utf8.good \
+utf8.test \
+utf8_bom.aff \
+utf8_bom.dic \
+utf8_bom.good \
+utf8_bom.test \
+utf8_bom2.aff \
+utf8_bom2.dic \
+utf8_bom2.good \
+utf8_bom2.test \
+utf8_nonbmp.aff \
+utf8_nonbmp.dic \
+utf8_nonbmp.good \
+utf8_nonbmp.sug \
+utf8_nonbmp.test \
+utf8_nonbmp.wrong \
+utfcompound.aff \
+utfcompound.dic \
+utfcompound.good \
+utfcompound.test \
+utfcompound.wrong \
+compoundflag.aff \
+compoundflag.dic \
+compoundflag.good \
+compoundflag.test \
+compoundflag.wrong \
+compoundrule.aff \
+compoundrule.dic \
+compoundrule.good \
+compoundrule.test \
+compoundrule.wrong \
+compoundrule2.aff \
+compoundrule2.dic \
+compoundrule2.good \
+compoundrule2.test \
+compoundrule2.wrong \
+compoundrule3.aff \
+compoundrule3.dic \
+compoundrule3.good \
+compoundrule3.test \
+compoundrule3.wrong \
+compoundrule4.aff \
+compoundrule4.dic \
+compoundrule4.good \
+compoundrule4.test \
+compoundrule4.wrong \
+compoundrule5.aff \
+compoundrule5.dic \
+compoundrule5.good \
+compoundrule5.morph \
+compoundrule5.test \
+compoundrule5.wrong \
+compoundrule6.aff \
+compoundrule6.dic \
+compoundrule6.good \
+compoundrule6.test \
+compoundrule6.wrong \
+compoundrule7.aff \
+compoundrule7.dic \
+compoundrule7.good \
+compoundrule7.test \
+compoundrule7.wrong \
+compoundrule8.aff \
+compoundrule8.dic \
+compoundrule8.good \
+compoundrule8.test \
+compoundrule8.wrong \
+compoundaffix.aff \
+compoundaffix.dic \
+compoundaffix.good \
+compoundaffix.test \
+compoundaffix.wrong \
+compoundaffix2.aff \
+compoundaffix2.dic \
+compoundaffix2.good \
+compoundaffix2.test \
+compoundaffix3.aff \
+compoundaffix3.dic \
+compoundaffix3.good \
+compoundaffix3.test \
+compoundaffix3.wrong \
+checkcompounddup.aff \
+checkcompounddup.dic \
+checkcompounddup.good \
+checkcompounddup.test \
+checkcompounddup.wrong \
+checkcompoundcase.aff \
+checkcompoundcase.dic \
+checkcompoundcase.good \
+checkcompoundcase.test \
+checkcompoundcase.wrong \
+checkcompoundcase2.aff \
+checkcompoundcase2.dic \
+checkcompoundcase2.good \
+checkcompoundcase2.test \
+checkcompoundcase2.wrong \
+checkcompoundcaseutf.aff \
+checkcompoundcaseutf.dic \
+checkcompoundcaseutf.good \
+checkcompoundcaseutf.test \
+checkcompoundcaseutf.wrong \
+checkcompoundrep.aff \
+checkcompoundrep.dic \
+checkcompoundrep.good \
+checkcompoundrep.test \
+checkcompoundrep.wrong \
+checkcompoundtriple.aff \
+checkcompoundtriple.dic \
+checkcompoundtriple.good \
+checkcompoundtriple.test \
+checkcompoundtriple.wrong \
+simplifiedtriple.aff \
+simplifiedtriple.dic \
+simplifiedtriple.good \
+simplifiedtriple.test \
+simplifiedtriple.wrong \
+checkcompoundpattern.aff \
+checkcompoundpattern.dic \
+checkcompoundpattern.good \
+checkcompoundpattern.test \
+checkcompoundpattern.wrong \
+checkcompoundpattern2.aff \
+checkcompoundpattern2.dic \
+checkcompoundpattern2.good \
+checkcompoundpattern2.test \
+checkcompoundpattern2.wrong \
+checkcompoundpattern3.aff \
+checkcompoundpattern3.dic \
+checkcompoundpattern3.good \
+checkcompoundpattern3.test \
+checkcompoundpattern3.wrong \
+checkcompoundpattern4.aff \
+checkcompoundpattern4.dic \
+checkcompoundpattern4.good \
+checkcompoundpattern4.test \
+checkcompoundpattern4.wrong \
+checksharps.aff \
+checksharps.dic \
+checksharps.good \
+checksharps.sug \
+checksharps.test \
+checksharps.wrong \
+checksharpsutf.aff \
+checksharpsutf.dic \
+checksharpsutf.good \
+checksharpsutf.sug \
+checksharpsutf.test \
+checksharpsutf.wrong \
+conditionalprefix.aff \
+conditionalprefix.dic \
+conditionalprefix.good \
+conditionalprefix.morph \
+conditionalprefix.test \
+conditionalprefix.wrong \
+flaglong.aff \
+flaglong.dic \
+flaglong.good \
+flaglong.test \
+flagnum.aff \
+flagnum.dic \
+flagnum.good \
+flagnum.test \
+flag.aff \
+flag.dic \
+flag.good \
+flag.test \
+flagutf8.aff \
+flagutf8.dic \
+flagutf8.good \
+flagutf8.test \
+complexprefixes.aff \
+complexprefixes.dic \
+complexprefixes.good \
+complexprefixes.wrong \
+complexprefixes.test \
+complexprefixes2.aff \
+complexprefixes2.dic \
+complexprefixes2.good \
+complexprefixes2.test \
+complexprefixesutf.aff \
+complexprefixesutf.dic \
+complexprefixesutf.good \
+complexprefixesutf.wrong \
+complexprefixesutf.test \
+i35725.aff \
+i35725.dic \
+i35725.good \
+i35725.sug \
+i35725.test \
+i35725.wrong \
+i53643.aff \
+i53643.dic \
+i53643.good \
+i53643.test \
+i53643.wrong \
+i54633.aff \
+i54633.dic \
+i54633.good \
+i54633.sug \
+i54633.test \
+i54633.wrong \
+i54980.aff \
+i54980.dic \
+i54980.good \
+i54980.test \
+i58202.aff \
+i58202.dic \
+i58202.good \
+i58202.sug \
+i58202.test \
+i58202.wrong \
+maputf.aff \
+maputf.dic \
+maputf.sug \
+maputf.wrong \
+maputf.test \
+reputf.aff \
+reputf.dic \
+reputf.sug \
+reputf.wrong \
+reputf.test \
+slash.aff \
+slash.dic \
+slash.good \
+slash.test \
+ignore.aff \
+ignore.dic \
+ignore.good \
+ignore.test \
+ignoreutf.aff \
+ignoreutf.dic \
+ignoreutf.good \
+ignoreutf.test \
+1592880.aff \
+1592880.dic \
+1592880.good \
+1592880.test \
+1695964.aff \
+1695964.dic \
+1695964.sug \
+1695964.test \
+1695964.wrong \
+1463589.aff \
+1463589.dic \
+1463589.sug \
+1463589.test \
+1463589.wrong \
+1463589_utf.aff \
+1463589_utf.dic \
+1463589_utf.sug \
+1463589_utf.test \
+1463589_utf.wrong \
+IJ.aff \
+IJ.dic \
+IJ.good \
+IJ.sug \
+IJ.test \
+IJ.wrong \
+i68568.aff \
+i68568.dic \
+i68568.test \
+i68568.wrong \
+i68568utf.aff \
+i68568utf.dic \
+i68568utf.test \
+i68568utf.wrong \
+1706659.aff \
+1706659.dic \
+1706659.test \
+1706659.wrong \
+digits_in_words.aff \
+digits_in_words.dic \
+digits_in_words.test \
+digits_in_words.wrong \
+colons_in_words.aff \
+colons_in_words.dic \
+colons_in_words.test \
+ngram_utf_fix.aff \
+ngram_utf_fix.dic \
+ngram_utf_fix.good \
+ngram_utf_fix.sug \
+ngram_utf_fix.test \
+ngram_utf_fix.wrong \
+morph.aff \
+morph.dic \
+morph.good \
+morph.morph \
+morph.test \
+1975530.aff \
+1975530.dic \
+1975530.good \
+1975530.test \
+1975530.wrong \
+fullstrip.aff \
+fullstrip.dic \
+fullstrip.good \
+fullstrip.test \
+iconv.aff \
+iconv.dic \
+iconv.good \
+iconv.test \
+oconv.aff \
+oconv.dic \
+oconv.good \
+oconv.sug \
+oconv.test \
+oconv.wrong \
+encoding.aff \
+encoding.dic \
+encoding.good \
+encoding.test \
+opentaal_forbiddenword1.aff \
+opentaal_forbiddenword1.dic \
+opentaal_forbiddenword1.good \
+opentaal_forbiddenword1.sug \
+opentaal_forbiddenword1.test \
+opentaal_forbiddenword1.wrong \
+opentaal_forbiddenword2.aff \
+opentaal_forbiddenword2.dic \
+opentaal_forbiddenword2.good \
+opentaal_forbiddenword2.sug \
+opentaal_forbiddenword2.test \
+opentaal_forbiddenword2.wrong \
+opentaal_forbiddenword2.aff \
+opentaal_forbiddenword2.dic \
+opentaal_forbiddenword2.good \
+opentaal_forbiddenword2.sug \
+opentaal_forbiddenword2.test \
+opentaal_forbiddenword2.wrong \
+opentaal_keepcase.aff \
+opentaal_keepcase.dic \
+opentaal_keepcase.good \
+opentaal_keepcase.sug \
+opentaal_keepcase.test \
+opentaal_keepcase.wrong \
+arabic.aff \
+arabic.dic \
+arabic.wrong \
+arabic.test \
+2970240.aff \
+2970240.dic \
+2970240.good \
+2970240.wrong \
+2970240.test \
+2970242.aff \
+2970242.dic \
+2970242.good \
+2970242.wrong \
+2970242.test \
+breakoff.aff \
+breakoff.dic \
+breakoff.good \
+breakoff.wrong \
+breakoff.test \
+opentaal_cpdpat.aff \
+opentaal_cpdpat.dic \
+opentaal_cpdpat.good \
+opentaal_cpdpat.wrong \
+opentaal_cpdpat.test \
+opentaal_cpdpat2.aff \
+opentaal_cpdpat2.dic \
+opentaal_cpdpat2.good \
+opentaal_cpdpat2.wrong \
+opentaal_cpdpat2.test \
+2999225.aff \
+2999225.dic \
+2999225.good \
+2999225.test \
+korean.aff \
+korean.dic \
+korean.good \
+korean.wrong \
+korean.test \
+onlyincompound2.aff \
+onlyincompound2.dic \
+onlyincompound2.good \
+onlyincompound2.test \
+onlyincompound2.wrong \
+forceucase.aff \
+forceucase.dic \
+forceucase.good \
+forceucase.sug \
+forceucase.wrong \
+forceucase.test \
+warn.aff \
+warn.dic \
+warn.good \
+warn.test
+
+all: all-recursive
+
+.SUFFIXES:
+$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+ && { if test -f $@; then exit 0; else break; fi; }; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu tests/Makefile'; \
+ $(am__cd) $(top_srcdir) && \
+ $(AUTOMAKE) --gnu tests/Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(am__aclocal_m4_deps):
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+
+# This directory's subdirectories are mostly independent; you can cd
+# into them and run `make' without going through this Makefile.
+# To change the values of `make' variables: instead of editing Makefiles,
+# (1) if the variable is set in `config.status', edit `config.status'
+# (which will cause the Makefiles to be regenerated when you run `make');
+# (2) otherwise, pass the desired values on the `make' command line.
+$(RECURSIVE_TARGETS):
+ @fail= failcom='exit 1'; \
+ for f in x $$MAKEFLAGS; do \
+ case $$f in \
+ *=* | --[!k]*);; \
+ *k*) failcom='fail=yes';; \
+ esac; \
+ done; \
+ dot_seen=no; \
+ target=`echo $@ | sed s/-recursive//`; \
+ list='$(SUBDIRS)'; for subdir in $$list; do \
+ echo "Making $$target in $$subdir"; \
+ if test "$$subdir" = "."; then \
+ dot_seen=yes; \
+ local_target="$$target-am"; \
+ else \
+ local_target="$$target"; \
+ fi; \
+ ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
+ || eval $$failcom; \
+ done; \
+ if test "$$dot_seen" = "no"; then \
+ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \
+ fi; test -z "$$fail"
+
+$(RECURSIVE_CLEAN_TARGETS):
+ @fail= failcom='exit 1'; \
+ for f in x $$MAKEFLAGS; do \
+ case $$f in \
+ *=* | --[!k]*);; \
+ *k*) failcom='fail=yes';; \
+ esac; \
+ done; \
+ dot_seen=no; \
+ case "$@" in \
+ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \
+ *) list='$(SUBDIRS)' ;; \
+ esac; \
+ rev=''; for subdir in $$list; do \
+ if test "$$subdir" = "."; then :; else \
+ rev="$$subdir $$rev"; \
+ fi; \
+ done; \
+ rev="$$rev ."; \
+ target=`echo $@ | sed s/-recursive//`; \
+ for subdir in $$rev; do \
+ echo "Making $$target in $$subdir"; \
+ if test "$$subdir" = "."; then \
+ local_target="$$target-am"; \
+ else \
+ local_target="$$target"; \
+ fi; \
+ ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
+ || eval $$failcom; \
+ done && test -z "$$fail"
+tags-recursive:
+ list='$(SUBDIRS)'; for subdir in $$list; do \
+ test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \
+ done
+ctags-recursive:
+ list='$(SUBDIRS)'; for subdir in $$list; do \
+ test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) ctags); \
+ done
+
+ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ mkid -fID $$unique
+tags: TAGS
+
+TAGS: tags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ set x; \
+ here=`pwd`; \
+ if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \
+ include_option=--etags-include; \
+ empty_fix=.; \
+ else \
+ include_option=--include; \
+ empty_fix=; \
+ fi; \
+ list='$(SUBDIRS)'; for subdir in $$list; do \
+ if test "$$subdir" = .; then :; else \
+ test ! -f $$subdir/TAGS || \
+ set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \
+ fi; \
+ done; \
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ shift; \
+ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
+ test -n "$$unique" || unique=$$empty_fix; \
+ if test $$# -gt 0; then \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ "$$@" $$unique; \
+ else \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ $$unique; \
+ fi; \
+ fi
+ctags: CTAGS
+CTAGS: ctags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ test -z "$(CTAGS_ARGS)$$unique" \
+ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+ $$unique
+
+GTAGS:
+ here=`$(am__cd) $(top_builddir) && pwd` \
+ && $(am__cd) $(top_srcdir) \
+ && gtags -i $(GTAGS_ARGS) "$$here"
+
+distclean-tags:
+ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+check-TESTS: $(TESTS)
+ @failed=0; all=0; xfail=0; xpass=0; skip=0; \
+ srcdir=$(srcdir); export srcdir; \
+ list=' $(TESTS) '; \
+ $(am__tty_colors); \
+ if test -n "$$list"; then \
+ for tst in $$list; do \
+ if test -f ./$$tst; then dir=./; \
+ elif test -f $$tst; then dir=; \
+ else dir="$(srcdir)/"; fi; \
+ if $(TESTS_ENVIRONMENT) $${dir}$$tst; then \
+ all=`expr $$all + 1`; \
+ case " $(XFAIL_TESTS) " in \
+ *[\ \ ]$$tst[\ \ ]*) \
+ xpass=`expr $$xpass + 1`; \
+ failed=`expr $$failed + 1`; \
+ col=$$red; res=XPASS; \
+ ;; \
+ *) \
+ col=$$grn; res=PASS; \
+ ;; \
+ esac; \
+ elif test $$? -ne 77; then \
+ all=`expr $$all + 1`; \
+ case " $(XFAIL_TESTS) " in \
+ *[\ \ ]$$tst[\ \ ]*) \
+ xfail=`expr $$xfail + 1`; \
+ col=$$lgn; res=XFAIL; \
+ ;; \
+ *) \
+ failed=`expr $$failed + 1`; \
+ col=$$red; res=FAIL; \
+ ;; \
+ esac; \
+ else \
+ skip=`expr $$skip + 1`; \
+ col=$$blu; res=SKIP; \
+ fi; \
+ echo "$${col}$$res$${std}: $$tst"; \
+ done; \
+ if test "$$all" -eq 1; then \
+ tests="test"; \
+ All=""; \
+ else \
+ tests="tests"; \
+ All="All "; \
+ fi; \
+ if test "$$failed" -eq 0; then \
+ if test "$$xfail" -eq 0; then \
+ banner="$$All$$all $$tests passed"; \
+ else \
+ if test "$$xfail" -eq 1; then failures=failure; else failures=failures; fi; \
+ banner="$$All$$all $$tests behaved as expected ($$xfail expected $$failures)"; \
+ fi; \
+ else \
+ if test "$$xpass" -eq 0; then \
+ banner="$$failed of $$all $$tests failed"; \
+ else \
+ if test "$$xpass" -eq 1; then passes=pass; else passes=passes; fi; \
+ banner="$$failed of $$all $$tests did not behave as expected ($$xpass unexpected $$passes)"; \
+ fi; \
+ fi; \
+ dashes="$$banner"; \
+ skipped=""; \
+ if test "$$skip" -ne 0; then \
+ if test "$$skip" -eq 1; then \
+ skipped="($$skip test was not run)"; \
+ else \
+ skipped="($$skip tests were not run)"; \
+ fi; \
+ test `echo "$$skipped" | wc -c` -le `echo "$$banner" | wc -c` || \
+ dashes="$$skipped"; \
+ fi; \
+ report=""; \
+ if test "$$failed" -ne 0 && test -n "$(PACKAGE_BUGREPORT)"; then \
+ report="Please report to $(PACKAGE_BUGREPORT)"; \
+ test `echo "$$report" | wc -c` -le `echo "$$banner" | wc -c` || \
+ dashes="$$report"; \
+ fi; \
+ dashes=`echo "$$dashes" | sed s/./=/g`; \
+ if test "$$failed" -eq 0; then \
+ echo "$$grn$$dashes"; \
+ else \
+ echo "$$red$$dashes"; \
+ fi; \
+ echo "$$banner"; \
+ test -z "$$skipped" || echo "$$skipped"; \
+ test -z "$$report" || echo "$$report"; \
+ echo "$$dashes$$std"; \
+ test "$$failed" -eq 0; \
+ else :; fi
+
+distdir: $(DISTFILES)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ list='$(DISTFILES)'; \
+ dist_files=`for file in $$list; do echo $$file; done | \
+ sed -e "s|^$$srcdirstrip/||;t" \
+ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+ case $$dist_files in \
+ */*) $(MKDIR_P) `echo "$$dist_files" | \
+ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+ sort -u` ;; \
+ esac; \
+ for file in $$dist_files; do \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ if test -d $$d/$$file; then \
+ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test -d "$(distdir)/$$file"; then \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+ else \
+ test -f "$(distdir)/$$file" \
+ || cp -p $$d/$$file "$(distdir)/$$file" \
+ || exit 1; \
+ fi; \
+ done
+ @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \
+ if test "$$subdir" = .; then :; else \
+ test -d "$(distdir)/$$subdir" \
+ || $(MKDIR_P) "$(distdir)/$$subdir" \
+ || exit 1; \
+ fi; \
+ done
+ @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \
+ if test "$$subdir" = .; then :; else \
+ dir1=$$subdir; dir2="$(distdir)/$$subdir"; \
+ $(am__relativize); \
+ new_distdir=$$reldir; \
+ dir1=$$subdir; dir2="$(top_distdir)"; \
+ $(am__relativize); \
+ new_top_distdir=$$reldir; \
+ echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \
+ echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \
+ ($(am__cd) $$subdir && \
+ $(MAKE) $(AM_MAKEFLAGS) \
+ top_distdir="$$new_top_distdir" \
+ distdir="$$new_distdir" \
+ am__remove_distdir=: \
+ am__skip_length_check=: \
+ am__skip_mode_fix=: \
+ distdir) \
+ || exit 1; \
+ fi; \
+ done
+check-am: all-am
+ $(MAKE) $(AM_MAKEFLAGS) check-TESTS
+check: check-recursive
+all-am: Makefile
+installdirs: installdirs-recursive
+installdirs-am:
+install: install-recursive
+install-exec: install-exec-recursive
+install-data: install-data-recursive
+uninstall: uninstall-recursive
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-recursive
+install-strip:
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ `test -z '$(STRIP)' || \
+ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+ -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+clean: clean-recursive
+
+clean-am: clean-generic clean-libtool mostlyclean-am
+
+distclean: distclean-recursive
+ -rm -f Makefile
+distclean-am: clean-am distclean-generic distclean-local \
+ distclean-tags
+
+dvi: dvi-recursive
+
+dvi-am:
+
+html: html-recursive
+
+html-am:
+
+info: info-recursive
+
+info-am:
+
+install-data-am:
+
+install-dvi: install-dvi-recursive
+
+install-dvi-am:
+
+install-exec-am:
+
+install-html: install-html-recursive
+
+install-html-am:
+
+install-info: install-info-recursive
+
+install-info-am:
+
+install-man:
+
+install-pdf: install-pdf-recursive
+
+install-pdf-am:
+
+install-ps: install-ps-recursive
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-recursive
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-recursive
+
+mostlyclean-am: mostlyclean-generic mostlyclean-libtool
+
+pdf: pdf-recursive
+
+pdf-am:
+
+ps: ps-recursive
+
+ps-am:
+
+uninstall-am:
+
+.MAKE: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) check-am \
+ ctags-recursive install-am install-strip tags-recursive
+
+.PHONY: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) CTAGS GTAGS \
+ all all-am check check-TESTS check-am clean clean-generic \
+ clean-libtool ctags ctags-recursive distclean \
+ distclean-generic distclean-libtool distclean-local \
+ distclean-tags distdir dvi dvi-am html html-am info info-am \
+ install install-am install-data install-data-am install-dvi \
+ install-dvi-am install-exec install-exec-am install-html \
+ install-html-am install-info install-info-am install-man \
+ install-pdf install-pdf-am install-ps install-ps-am \
+ install-strip installcheck installcheck-am installdirs \
+ installdirs-am maintainer-clean maintainer-clean-generic \
+ mostlyclean mostlyclean-generic mostlyclean-libtool pdf pdf-am \
+ ps ps-am tags tags-recursive uninstall uninstall-am
+
+
+# infixes.test
+
+distclean-local:
+ -rm -rf testSubDir
+
+# infixes.aff
+# infixes.dic
+# infixes.good
+# infixes.test
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/affixes.aff b/extensions/spellcheck/hunspell/tests/unit/data/affixes.aff
new file mode 100644
index 0000000000..cf3c500218
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/affixes.aff
@@ -0,0 +1,7 @@
+# simple example for affix compression (see Hunspell(4))
+PFX A Y 1
+PFX A 0 re .
+
+SFX B Y 2
+SFX B 0 ed [^y]
+SFX B y ied y
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/affixes.dic b/extensions/spellcheck/hunspell/tests/unit/data/affixes.dic
new file mode 100644
index 0000000000..e228043ef1
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/affixes.dic
@@ -0,0 +1,4 @@
+3
+hello
+try/B
+work/AB
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/affixes.good b/extensions/spellcheck/hunspell/tests/unit/data/affixes.good
new file mode 100644
index 0000000000..20097e8e6c
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/affixes.good
@@ -0,0 +1,7 @@
+hello
+try
+tried
+work
+worked
+rework
+reworked
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/affixes.test b/extensions/spellcheck/hunspell/tests/unit/data/affixes.test
new file mode 100644
index 0000000000..7f44369060
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/affixes.test
@@ -0,0 +1,4 @@
+#!/bin/sh
+DIR="`dirname $0`"
+NAME="`basename $0 .test`"
+$DIR/test.sh $NAME
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/alias.aff b/extensions/spellcheck/hunspell/tests/unit/data/alias.aff
new file mode 100644
index 0000000000..3fbce0ac40
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/alias.aff
@@ -0,0 +1,12 @@
+# aliases for flag vectors (AF)
+# AB -> 1
+# A -> 2
+AF 2
+AF AB
+AF A
+
+SFX A Y 1
+SFX A 0 x .
+
+SFX B Y 1
+SFX B 0 y/2 .
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/alias.dic b/extensions/spellcheck/hunspell/tests/unit/data/alias.dic
new file mode 100644
index 0000000000..e0af3c918a
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/alias.dic
@@ -0,0 +1,2 @@
+1
+foo/1
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/alias.good b/extensions/spellcheck/hunspell/tests/unit/data/alias.good
new file mode 100644
index 0000000000..71702f2317
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/alias.good
@@ -0,0 +1,4 @@
+foo
+foox
+fooy
+fooyx
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/alias.test b/extensions/spellcheck/hunspell/tests/unit/data/alias.test
new file mode 100644
index 0000000000..7f44369060
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/alias.test
@@ -0,0 +1,4 @@
+#!/bin/sh
+DIR="`dirname $0`"
+NAME="`basename $0 .test`"
+$DIR/test.sh $NAME
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/alias2.aff b/extensions/spellcheck/hunspell/tests/unit/data/alias2.aff
new file mode 100644
index 0000000000..66a183833d
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/alias2.aff
@@ -0,0 +1,17 @@
+# aliases for flag vectors (AF) and morphological descriptions (AM)
+# AB -> 1
+# A -> 2
+AF 2
+AF AB
+AF A
+
+AM 3
+AM is:affix_x
+AM ds:affix_y
+AM po:noun xx:other_data
+
+SFX A Y 1
+SFX A 0 x . 1
+
+SFX B Y 1
+SFX B 0 y/2 . 2
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/alias2.dic b/extensions/spellcheck/hunspell/tests/unit/data/alias2.dic
new file mode 100644
index 0000000000..60300aceef
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/alias2.dic
@@ -0,0 +1,2 @@
+1
+foo/1 3
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/alias2.good b/extensions/spellcheck/hunspell/tests/unit/data/alias2.good
new file mode 100644
index 0000000000..71702f2317
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/alias2.good
@@ -0,0 +1,4 @@
+foo
+foox
+fooy
+fooyx
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/alias2.morph b/extensions/spellcheck/hunspell/tests/unit/data/alias2.morph
new file mode 100644
index 0000000000..01f983d57b
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/alias2.morph
@@ -0,0 +1,12 @@
+> foo
+analyze(foo) = st:foo po:noun xx:other_data
+stem(foo) = foo
+> foox
+analyze(foox) = st:foo po:noun xx:other_data is:affix_x
+stem(foox) = foo
+> fooy
+analyze(fooy) = st:foo po:noun xx:other_data ds:affix_y
+stem(fooy) = fooy
+> fooyx
+analyze(fooyx) = st:foo po:noun xx:other_data ds:affix_y is:affix_x
+stem(fooyx) = fooy
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/alias2.test b/extensions/spellcheck/hunspell/tests/unit/data/alias2.test
new file mode 100644
index 0000000000..7f44369060
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/alias2.test
@@ -0,0 +1,4 @@
+#!/bin/sh
+DIR="`dirname $0`"
+NAME="`basename $0 .test`"
+$DIR/test.sh $NAME
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/alias3.aff b/extensions/spellcheck/hunspell/tests/unit/data/alias3.aff
new file mode 100644
index 0000000000..a328185008
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/alias3.aff
@@ -0,0 +1,18 @@
+# morph. aliases with complex prefixes
+COMPLEXPREFIXES
+WORDCHARS _
+
+AM 4
+AM affix_1/
+AM affix_2/
+AM /suffix_1
+AM [stem_1]
+
+PFX A Y 1
+PFX A 0 tek . 1
+
+PFX B Y 1
+PFX B 0 met/A . 2
+
+SFX C Y 1
+SFX C 0 _test_ . 3
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/alias3.dic b/extensions/spellcheck/hunspell/tests/unit/data/alias3.dic
new file mode 100644
index 0000000000..f22567cbe1
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/alias3.dic
@@ -0,0 +1,2 @@
+1
+ouro/BC 4
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/alias3.good b/extensions/spellcheck/hunspell/tests/unit/data/alias3.good
new file mode 100644
index 0000000000..6bf822826b
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/alias3.good
@@ -0,0 +1,4 @@
+ouro
+metouro
+tekmetouro
+ouro_test_
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/alias3.morph b/extensions/spellcheck/hunspell/tests/unit/data/alias3.morph
new file mode 100644
index 0000000000..33edf5cee7
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/alias3.morph
@@ -0,0 +1,8 @@
+> ouro
+analyze(ouro) = [stem_1] ouro:ts
+> metouro
+analyze(metouro) = affix_2/ ouro:ts [stem_1]
+> tekmetouro
+analyze(tekmetouro) = affix_1/ affix_2/ ouro:ts [stem_1]
+> ouro_test_
+analyze(ouro_test_) = [stem_1] ouro:ts /suffix_1
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/alias3.test b/extensions/spellcheck/hunspell/tests/unit/data/alias3.test
new file mode 100644
index 0000000000..7f44369060
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/alias3.test
@@ -0,0 +1,4 @@
+#!/bin/sh
+DIR="`dirname $0`"
+NAME="`basename $0 .test`"
+$DIR/test.sh $NAME
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/allcaps-utf.aff b/extensions/spellcheck/hunspell/tests/unit/data/allcaps-utf.aff
new file mode 100644
index 0000000000..a117625685
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/allcaps-utf.aff
@@ -0,0 +1,6 @@
+SET UTF-8
+WORDCHARS '.
+
+SFX S N 1
+SFX S 0 's .
+
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/allcaps-utf.dic b/extensions/spellcheck/hunspell/tests/unit/data/allcaps-utf.dic
new file mode 100644
index 0000000000..7d3cdcc046
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/allcaps-utf.dic
@@ -0,0 +1,3 @@
+2
+OpenOffice.org
+UNICEF/S
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/allcaps-utf.good b/extensions/spellcheck/hunspell/tests/unit/data/allcaps-utf.good
new file mode 100644
index 0000000000..3afd877d9d
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/allcaps-utf.good
@@ -0,0 +1,4 @@
+OpenOffice.org
+OPENOFFICE.ORG
+UNICEF's
+UNICEF'S
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/allcaps-utf.sug b/extensions/spellcheck/hunspell/tests/unit/data/allcaps-utf.sug
new file mode 100644
index 0000000000..d372ff23d6
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/allcaps-utf.sug
@@ -0,0 +1,3 @@
+OpenOffice.org
+UNICEF
+UNICEF's
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/allcaps-utf.test b/extensions/spellcheck/hunspell/tests/unit/data/allcaps-utf.test
new file mode 100644
index 0000000000..cde7c54109
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/allcaps-utf.test
@@ -0,0 +1,4 @@
+#!/bin/sh
+DIR="`dirname $0`"
+NAME="`basename $0 .test`"
+$DIR/test.sh $NAME -i utf-8
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/allcaps-utf.wrong b/extensions/spellcheck/hunspell/tests/unit/data/allcaps-utf.wrong
new file mode 100644
index 0000000000..668194906e
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/allcaps-utf.wrong
@@ -0,0 +1,3 @@
+Openoffice.org
+Unicef
+Unicef's
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/allcaps.aff b/extensions/spellcheck/hunspell/tests/unit/data/allcaps.aff
new file mode 100644
index 0000000000..57e916bf53
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/allcaps.aff
@@ -0,0 +1,5 @@
+# check uppercase forms of allcaps word + affix and words with mixed casing
+WORDCHARS '.
+
+SFX S N 1
+SFX S 0 's .
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/allcaps.dic b/extensions/spellcheck/hunspell/tests/unit/data/allcaps.dic
new file mode 100644
index 0000000000..7d3cdcc046
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/allcaps.dic
@@ -0,0 +1,3 @@
+2
+OpenOffice.org
+UNICEF/S
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/allcaps.good b/extensions/spellcheck/hunspell/tests/unit/data/allcaps.good
new file mode 100644
index 0000000000..3afd877d9d
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/allcaps.good
@@ -0,0 +1,4 @@
+OpenOffice.org
+OPENOFFICE.ORG
+UNICEF's
+UNICEF'S
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/allcaps.sug b/extensions/spellcheck/hunspell/tests/unit/data/allcaps.sug
new file mode 100644
index 0000000000..d372ff23d6
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/allcaps.sug
@@ -0,0 +1,3 @@
+OpenOffice.org
+UNICEF
+UNICEF's
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/allcaps.test b/extensions/spellcheck/hunspell/tests/unit/data/allcaps.test
new file mode 100644
index 0000000000..7f44369060
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/allcaps.test
@@ -0,0 +1,4 @@
+#!/bin/sh
+DIR="`dirname $0`"
+NAME="`basename $0 .test`"
+$DIR/test.sh $NAME
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/allcaps.wrong b/extensions/spellcheck/hunspell/tests/unit/data/allcaps.wrong
new file mode 100644
index 0000000000..668194906e
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/allcaps.wrong
@@ -0,0 +1,3 @@
+Openoffice.org
+Unicef
+Unicef's
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/allcaps2.aff b/extensions/spellcheck/hunspell/tests/unit/data/allcaps2.aff
new file mode 100644
index 0000000000..67022d6eb0
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/allcaps2.aff
@@ -0,0 +1,6 @@
+# forbidden all caps words are case sensitive
+# iPod -> ipodos ("iPodic" in Hungarian)
+FORBIDDENWORD *
+SFX s N 1
+SFX s 0 os .
+
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/allcaps2.dic b/extensions/spellcheck/hunspell/tests/unit/data/allcaps2.dic
new file mode 100644
index 0000000000..be21bfb40b
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/allcaps2.dic
@@ -0,0 +1,4 @@
+3
+iPod/s
+iPodos/*
+ipodos
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/allcaps2.good b/extensions/spellcheck/hunspell/tests/unit/data/allcaps2.good
new file mode 100644
index 0000000000..5fd2f82ce4
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/allcaps2.good
@@ -0,0 +1,4 @@
+iPod
+IPOD
+ipodos
+IPODOS
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/allcaps2.sug b/extensions/spellcheck/hunspell/tests/unit/data/allcaps2.sug
new file mode 100644
index 0000000000..5c312d7b56
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/allcaps2.sug
@@ -0,0 +1,2 @@
+iPod
+ipodos
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/allcaps2.test b/extensions/spellcheck/hunspell/tests/unit/data/allcaps2.test
new file mode 100644
index 0000000000..7f44369060
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/allcaps2.test
@@ -0,0 +1,4 @@
+#!/bin/sh
+DIR="`dirname $0`"
+NAME="`basename $0 .test`"
+$DIR/test.sh $NAME
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/allcaps2.wrong b/extensions/spellcheck/hunspell/tests/unit/data/allcaps2.wrong
new file mode 100644
index 0000000000..010967be67
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/allcaps2.wrong
@@ -0,0 +1,2 @@
+ipod
+iPodos
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/allcaps3.aff b/extensions/spellcheck/hunspell/tests/unit/data/allcaps3.aff
new file mode 100644
index 0000000000..789818e1a5
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/allcaps3.aff
@@ -0,0 +1,10 @@
+# homonym support
+WORDCHARS '
+
+SFX s N 1
+SFX s 0 s .
+
+SFX S N 1
+SFX S 0 's .
+
+
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/allcaps3.dic b/extensions/spellcheck/hunspell/tests/unit/data/allcaps3.dic
new file mode 100644
index 0000000000..e903a0fa96
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/allcaps3.dic
@@ -0,0 +1,7 @@
+4
+UNESCO/S
+Unesco/S
+Nasa/S
+NASA/S
+ACTS
+act/s
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/allcaps3.good b/extensions/spellcheck/hunspell/tests/unit/data/allcaps3.good
new file mode 100644
index 0000000000..b9930a24dd
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/allcaps3.good
@@ -0,0 +1,13 @@
+UNESCO
+Unesco
+UNESCO's
+Unesco's
+UNESCO'S
+NASA
+Nasa
+NASA's
+Nasa's
+NASA'S
+ACTS
+acts
+Acts
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/allcaps3.test b/extensions/spellcheck/hunspell/tests/unit/data/allcaps3.test
new file mode 100644
index 0000000000..7f44369060
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/allcaps3.test
@@ -0,0 +1,4 @@
+#!/bin/sh
+DIR="`dirname $0`"
+NAME="`basename $0 .test`"
+$DIR/test.sh $NAME
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/allcaps3.wrong b/extensions/spellcheck/hunspell/tests/unit/data/allcaps3.wrong
new file mode 100644
index 0000000000..89172b8245
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/allcaps3.wrong
@@ -0,0 +1,4 @@
+unesco
+unesco's
+nasa
+nasa's
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/arabic.aff b/extensions/spellcheck/hunspell/tests/unit/data/arabic.aff
new file mode 100644
index 0000000000..f8dd5cf244
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/arabic.aff
@@ -0,0 +1,6 @@
+SET UTF-8
+TRY 悖
+IGNORE ル
+
+PFX Aa Y 1
+PFX Aa 0 0/X0 悖[^]
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/arabic.dic b/extensions/spellcheck/hunspell/tests/unit/data/arabic.dic
new file mode 100644
index 0000000000..9a2035def2
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/arabic.dic
@@ -0,0 +1,2 @@
+1
+惡
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/arabic.test b/extensions/spellcheck/hunspell/tests/unit/data/arabic.test
new file mode 100644
index 0000000000..4d59c42126
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/arabic.test
@@ -0,0 +1,4 @@
+#!/bin/sh
+DIR="`dirname $0`"
+NAME="`basename $0 .test`"
+$DIR/test.sh $NAME -i UTF-8
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/arabic.wrong b/extensions/spellcheck/hunspell/tests/unit/data/arabic.wrong
new file mode 100644
index 0000000000..9b566c3646
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/arabic.wrong
@@ -0,0 +1 @@
+
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/base-utf.aff b/extensions/spellcheck/hunspell/tests/unit/data/base-utf.aff
new file mode 100644
index 0000000000..493157b301
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/base-utf.aff
@@ -0,0 +1,198 @@
+# OpenOffice.orgs en_US.aff file
+# with Unicode apostrophe:
+
+SET UTF-8
+TRY esianrtolcdugmphbyfvkwzESIANRTOLCDUGMPHBYFVKWZ'
+
+MAXNGRAMSUGS 1
+WORDCHARS .'
+
+PFX A Y 1
+PFX A 0 re .
+
+PFX I Y 1
+PFX I 0 in .
+
+PFX U Y 1
+PFX U 0 un .
+
+PFX C Y 1
+PFX C 0 de .
+
+PFX E Y 1
+PFX E 0 dis .
+
+PFX F Y 1
+PFX F 0 con .
+
+PFX K Y 1
+PFX K 0 pro .
+
+SFX V N 2
+SFX V e ive e
+SFX V 0 ive [^e]
+
+SFX N Y 3
+SFX N e ion e
+SFX N y ication y
+SFX N 0 en [^ey]
+
+SFX X Y 3
+SFX X e ions e
+SFX X y ications y
+SFX X 0 ens [^ey]
+
+SFX H N 2
+SFX H y ieth y
+SFX H 0 th [^y]
+
+SFX Y Y 1
+SFX Y 0 ly .
+
+SFX G Y 2
+SFX G e ing e
+SFX G 0 ing [^e]
+
+SFX J Y 2
+SFX J e ings e
+SFX J 0 ings [^e]
+
+SFX D Y 4
+SFX D 0 d e
+SFX D y ied [^aeiou]y
+SFX D 0 ed [^ey]
+SFX D 0 ed [aeiou]y
+
+SFX T N 4
+SFX T 0 st e
+SFX T y iest [^aeiou]y
+SFX T 0 est [aeiou]y
+SFX T 0 est [^ey]
+
+SFX R Y 4
+SFX R 0 r e
+SFX R y ier [^aeiou]y
+SFX R 0 er [aeiou]y
+SFX R 0 er [^ey]
+
+SFX Z Y 4
+SFX Z 0 rs e
+SFX Z y iers [^aeiou]y
+SFX Z 0 ers [aeiou]y
+SFX Z 0 ers [^ey]
+
+SFX S Y 4
+SFX S y ies [^aeiou]y
+SFX S 0 s [aeiou]y
+SFX S 0 es [sxzh]
+SFX S 0 s [^sxzhy]
+
+SFX P Y 3
+SFX P y iness [^aeiou]y
+SFX P 0 ness [aeiou]y
+SFX P 0 ness [^y]
+
+SFX M Y 1
+SFX M 0 's .
+
+SFX B Y 3
+SFX B 0 able [^aeiou]
+SFX B 0 able ee
+SFX B e able [^aeiou]e
+
+SFX L Y 1
+SFX L 0 ment .
+
+REP 88
+REP a ei
+REP ei a
+REP a ey
+REP ey a
+REP ai ie
+REP ie ai
+REP are air
+REP are ear
+REP are eir
+REP air are
+REP air ere
+REP ere air
+REP ere ear
+REP ere eir
+REP ear are
+REP ear air
+REP ear ere
+REP eir are
+REP eir ere
+REP ch te
+REP te ch
+REP ch ti
+REP ti ch
+REP ch tu
+REP tu ch
+REP ch s
+REP s ch
+REP ch k
+REP k ch
+REP f ph
+REP ph f
+REP gh f
+REP f gh
+REP i igh
+REP igh i
+REP i uy
+REP uy i
+REP i ee
+REP ee i
+REP j di
+REP di j
+REP j gg
+REP gg j
+REP j ge
+REP ge j
+REP s ti
+REP ti s
+REP s ci
+REP ci s
+REP k cc
+REP cc k
+REP k qu
+REP qu k
+REP kw qu
+REP o eau
+REP eau o
+REP o ew
+REP ew o
+REP oo ew
+REP ew oo
+REP ew ui
+REP ui ew
+REP oo ui
+REP ui oo
+REP ew u
+REP u ew
+REP oo u
+REP u oo
+REP u oe
+REP oe u
+REP u ieu
+REP ieu u
+REP ue ew
+REP ew ue
+REP uff ough
+REP oo ieu
+REP ieu oo
+REP ier ear
+REP ear ier
+REP ear air
+REP air ear
+REP w qu
+REP qu w
+REP z ss
+REP ss z
+REP shun tion
+REP shun sion
+REP shun cion
+McDonaldss叩/w
+McDonaldssz叩/g3) st:McDonald但s po:noun_prs is:TRANS
+McDonaldsszal/g4) st:McDonald但s po:noun_prs is:INSTR
+McDonaldssal/w
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/base-utf.dic b/extensions/spellcheck/hunspell/tests/unit/data/base-utf.dic
new file mode 100644
index 0000000000..b2b536d285
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/base-utf.dic
@@ -0,0 +1,29 @@
+28
+created/U
+create/XKVNGADS
+imply/GNSDX
+natural/PUY
+like/USPBY
+convey/BDGS
+look/GZRDS
+text
+hello
+said
+sawyer
+NASA
+rotten
+day
+tomorrow
+seven
+FAQ/SM
+cant
+doesnt
+etc
+wont
+lip
+text
+horrifying
+speech
+suggest
+uncreate/V
+Hunspell
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/base-utf.good b/extensions/spellcheck/hunspell/tests/unit/data/base-utf.good
new file mode 100644
index 0000000000..4c73e42b8e
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/base-utf.good
@@ -0,0 +1,27 @@
+created
+uncreate
+uncreated
+imply
+implied
+unnatural
+conveyed
+sawyer
+NASA
+FAQs
+cant
+doesnt
+wont
+Created
+Hello
+HELLO
+NASA
+etc.
+etc
+HELLO
+lip.
+text.
+NASA.
+Text.
+TEXT.
+Hunspell.
+HUNSPELL.
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/base-utf.sug b/extensions/spellcheck/hunspell/tests/unit/data/base-utf.sug
new file mode 100644
index 0000000000..990b640cf3
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/base-utf.sug
@@ -0,0 +1,11 @@
+looked, look
+text, create
+hello
+said
+rotten day, rotten-day, rotten
+tomorrow, rotten
+seven
+NASA
+horrifying
+speech, Hunspell
+suggest
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/base-utf.test b/extensions/spellcheck/hunspell/tests/unit/data/base-utf.test
new file mode 100644
index 0000000000..4d59c42126
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/base-utf.test
@@ -0,0 +1,4 @@
+#!/bin/sh
+DIR="`dirname $0`"
+NAME="`basename $0 .test`"
+$DIR/test.sh $NAME -i UTF-8
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/base-utf.wrong b/extensions/spellcheck/hunspell/tests/unit/data/base-utf.wrong
new file mode 100644
index 0000000000..88a6e25204
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/base-utf.wrong
@@ -0,0 +1,11 @@
+loooked
+texxt
+hlelo
+seid
+rottenday
+tomorow
+seeeven
+Nasa
+horrorfying
+peech
+sugesst
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/base.aff b/extensions/spellcheck/hunspell/tests/unit/data/base.aff
new file mode 100644
index 0000000000..632f04b96c
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/base.aff
@@ -0,0 +1,192 @@
+# OpenOffice.org's en_US.aff file
+
+SET ISO8859-1
+TRY esianrtolcdugmphbyfvkwz'
+
+WORDCHARS .'
+
+PFX A Y 1
+PFX A 0 re .
+
+PFX I Y 1
+PFX I 0 in .
+
+PFX U Y 1
+PFX U 0 un .
+
+PFX C Y 1
+PFX C 0 de .
+
+PFX E Y 1
+PFX E 0 dis .
+
+PFX F Y 1
+PFX F 0 con .
+
+PFX K Y 1
+PFX K 0 pro .
+
+SFX V N 2
+SFX V e ive e
+SFX V 0 ive [^e]
+
+SFX N Y 3
+SFX N e ion e
+SFX N y ication y
+SFX N 0 en [^ey]
+
+SFX X Y 3
+SFX X e ions e
+SFX X y ications y
+SFX X 0 ens [^ey]
+
+SFX H N 2
+SFX H y ieth y
+SFX H 0 th [^y]
+
+SFX Y Y 1
+SFX Y 0 ly .
+
+SFX G Y 2
+SFX G e ing e
+SFX G 0 ing [^e]
+
+SFX J Y 2
+SFX J e ings e
+SFX J 0 ings [^e]
+
+SFX D Y 4
+SFX D 0 d e
+SFX D y ied [^aeiou]y
+SFX D 0 ed [^ey]
+SFX D 0 ed [aeiou]y
+
+SFX T N 4
+SFX T 0 st e
+SFX T y iest [^aeiou]y
+SFX T 0 est [aeiou]y
+SFX T 0 est [^ey]
+
+SFX R Y 4
+SFX R 0 r e
+SFX R y ier [^aeiou]y
+SFX R 0 er [aeiou]y
+SFX R 0 er [^ey]
+
+SFX Z Y 4
+SFX Z 0 rs e
+SFX Z y iers [^aeiou]y
+SFX Z 0 ers [aeiou]y
+SFX Z 0 ers [^ey]
+
+SFX S Y 4
+SFX S y ies [^aeiou]y
+SFX S 0 s [aeiou]y
+SFX S 0 es [sxzh]
+SFX S 0 s [^sxzhy]
+
+SFX P Y 3
+SFX P y iness [^aeiou]y
+SFX P 0 ness [aeiou]y
+SFX P 0 ness [^y]
+
+SFX M Y 1
+SFX M 0 's .
+
+SFX B Y 3
+SFX B 0 able [^aeiou]
+SFX B 0 able ee
+SFX B e able [^aeiou]e
+
+SFX L Y 1
+SFX L 0 ment .
+
+REP 88
+REP a ei
+REP ei a
+REP a ey
+REP ey a
+REP ai ie
+REP ie ai
+REP are air
+REP are ear
+REP are eir
+REP air are
+REP air ere
+REP ere air
+REP ere ear
+REP ere eir
+REP ear are
+REP ear air
+REP ear ere
+REP eir are
+REP eir ere
+REP ch te
+REP te ch
+REP ch ti
+REP ti ch
+REP ch tu
+REP tu ch
+REP ch s
+REP s ch
+REP ch k
+REP k ch
+REP f ph
+REP ph f
+REP gh f
+REP f gh
+REP i igh
+REP igh i
+REP i uy
+REP uy i
+REP i ee
+REP ee i
+REP j di
+REP di j
+REP j gg
+REP gg j
+REP j ge
+REP ge j
+REP s ti
+REP ti s
+REP s ci
+REP ci s
+REP k cc
+REP cc k
+REP k qu
+REP qu k
+REP kw qu
+REP o eau
+REP eau o
+REP o ew
+REP ew o
+REP oo ew
+REP ew oo
+REP ew ui
+REP ui ew
+REP oo ui
+REP ui oo
+REP ew u
+REP u ew
+REP oo u
+REP u oo
+REP u oe
+REP oe u
+REP u ieu
+REP ieu u
+REP ue ew
+REP ew ue
+REP uff ough
+REP oo ieu
+REP ieu oo
+REP ier ear
+REP ear ier
+REP ear air
+REP air ear
+REP w qu
+REP qu w
+REP z ss
+REP ss z
+REP shun tion
+REP shun sion
+REP shun cion
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/base.dic b/extensions/spellcheck/hunspell/tests/unit/data/base.dic
new file mode 100644
index 0000000000..5d9b8a28b5
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/base.dic
@@ -0,0 +1,29 @@
+28
+created/U
+create/XKVNGADS
+imply/GNSDX
+natural/PUY
+like/USPBY
+convey/BDGS
+look/GZRDS
+text
+hello
+said
+sawyer
+NASA
+rotten
+day
+tomorrow
+seven
+FAQ/SM
+can't
+doesn't
+etc
+won't
+lip
+text
+horrifying
+speech
+suggest
+uncreate/V
+Hunspell
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/base.good b/extensions/spellcheck/hunspell/tests/unit/data/base.good
new file mode 100644
index 0000000000..8e7f88e2b4
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/base.good
@@ -0,0 +1,27 @@
+created
+uncreate
+uncreated
+imply
+implied
+unnatural
+conveyed
+sawyer
+NASA
+FAQs
+can't
+doesn't
+won't
+Created
+Hello
+HELLO
+NASA
+etc.
+etc
+HELLO
+lip.
+text.
+NASA.
+Text.
+TEXT.
+Hunspell.
+HUNSPELL.
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/base.sug b/extensions/spellcheck/hunspell/tests/unit/data/base.sug
new file mode 100644
index 0000000000..553280a6aa
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/base.sug
@@ -0,0 +1,11 @@
+looked, look
+text
+hello
+said
+rotten day, rotten-day, rotten
+tomorrow
+seven
+NASA
+horrifying
+speech
+suggest
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/base.test b/extensions/spellcheck/hunspell/tests/unit/data/base.test
new file mode 100644
index 0000000000..7f44369060
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/base.test
@@ -0,0 +1,4 @@
+#!/bin/sh
+DIR="`dirname $0`"
+NAME="`basename $0 .test`"
+$DIR/test.sh $NAME
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/base.wrong b/extensions/spellcheck/hunspell/tests/unit/data/base.wrong
new file mode 100644
index 0000000000..88a6e25204
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/base.wrong
@@ -0,0 +1,11 @@
+loooked
+texxt
+hlelo
+seid
+rottenday
+tomorow
+seeeven
+Nasa
+horrorfying
+peech
+sugesst
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/break.aff b/extensions/spellcheck/hunspell/tests/unit/data/break.aff
new file mode 100644
index 0000000000..47b8f6b7be
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/break.aff
@@ -0,0 +1,8 @@
+# word break points test, recursive break at dash and n-dash
+SET UTF-8
+
+BREAK 2
+BREAK -
+BREAK
+
+WORDCHARS -
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/break.dic b/extensions/spellcheck/hunspell/tests/unit/data/break.dic
new file mode 100644
index 0000000000..f3d2aa02fd
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/break.dic
@@ -0,0 +1,4 @@
+3
+foo
+bar
+fox-bax
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/break.good b/extensions/spellcheck/hunspell/tests/unit/data/break.good
new file mode 100644
index 0000000000..5f08bfd2f1
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/break.good
@@ -0,0 +1,7 @@
+foo
+bar
+fox-bax
+foo-bar
+foobar
+foo-bar-foo-bar
+foo-barfoo-bar
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/break.test b/extensions/spellcheck/hunspell/tests/unit/data/break.test
new file mode 100644
index 0000000000..cde7c54109
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/break.test
@@ -0,0 +1,4 @@
+#!/bin/sh
+DIR="`dirname $0`"
+NAME="`basename $0 .test`"
+$DIR/test.sh $NAME -i utf-8
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/break.wrong b/extensions/spellcheck/hunspell/tests/unit/data/break.wrong
new file mode 100644
index 0000000000..599ed9f7ff
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/break.wrong
@@ -0,0 +1,12 @@
+fox
+bax
+-foo
+bar-
+fox-bar
+foo-bax
+foobax
+foxbar
+foo-bar-fox-bar
+foo-bax-foo-bar
+foo-barfox-bar
+foo-baxfoo-bar
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/breakdefault.aff b/extensions/spellcheck/hunspell/tests/unit/data/breakdefault.aff
new file mode 100644
index 0000000000..a13f464a60
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/breakdefault.aff
@@ -0,0 +1,6 @@
+# default word break at hyphens and n-dashes
+
+SET UTF-8
+MAXNGRAMSUGS 0
+WORDCHARS -
+TRY ot
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/breakdefault.dic b/extensions/spellcheck/hunspell/tests/unit/data/breakdefault.dic
new file mode 100644
index 0000000000..bf29960357
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/breakdefault.dic
@@ -0,0 +1,6 @@
+3
+foo
+bar
+free
+scott
+scot-free
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/breakdefault.good b/extensions/spellcheck/hunspell/tests/unit/data/breakdefault.good
new file mode 100644
index 0000000000..8d81254571
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/breakdefault.good
@@ -0,0 +1,7 @@
+foo
+bar
+foo-
+-foo
+scot-free
+foo-bar
+foo-bar-foo-bar
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/breakdefault.sug b/extensions/spellcheck/hunspell/tests/unit/data/breakdefault.sug
new file mode 100644
index 0000000000..8bfc69d936
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/breakdefault.sug
@@ -0,0 +1,3 @@
+scott
+scot-free
+foo-bar
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/breakdefault.test b/extensions/spellcheck/hunspell/tests/unit/data/breakdefault.test
new file mode 100644
index 0000000000..cde7c54109
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/breakdefault.test
@@ -0,0 +1,4 @@
+#!/bin/sh
+DIR="`dirname $0`"
+NAME="`basename $0 .test`"
+$DIR/test.sh $NAME -i utf-8
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/breakdefault.wrong b/extensions/spellcheck/hunspell/tests/unit/data/breakdefault.wrong
new file mode 100644
index 0000000000..c3b203a7f2
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/breakdefault.wrong
@@ -0,0 +1,3 @@
+scot
+sco-free
+fo-bar
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/breakoff.aff b/extensions/spellcheck/hunspell/tests/unit/data/breakoff.aff
new file mode 100644
index 0000000000..2e83d38023
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/breakoff.aff
@@ -0,0 +1,7 @@
+# switch off default word break at hyphens and n-dashes by BREAK 0
+SET UTF-8
+MAXNGRAMSUGS 0
+WORDCHARS -
+TRY ot
+
+BREAK 0
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/breakoff.dic b/extensions/spellcheck/hunspell/tests/unit/data/breakoff.dic
new file mode 100644
index 0000000000..bf29960357
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/breakoff.dic
@@ -0,0 +1,6 @@
+3
+foo
+bar
+free
+scott
+scot-free
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/breakoff.good b/extensions/spellcheck/hunspell/tests/unit/data/breakoff.good
new file mode 100644
index 0000000000..854b39efad
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/breakoff.good
@@ -0,0 +1,3 @@
+foo
+bar
+scot-free
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/breakoff.test b/extensions/spellcheck/hunspell/tests/unit/data/breakoff.test
new file mode 100644
index 0000000000..cde7c54109
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/breakoff.test
@@ -0,0 +1,4 @@
+#!/bin/sh
+DIR="`dirname $0`"
+NAME="`basename $0 .test`"
+$DIR/test.sh $NAME -i utf-8
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/breakoff.wrong b/extensions/spellcheck/hunspell/tests/unit/data/breakoff.wrong
new file mode 100644
index 0000000000..a6fcf7f1e2
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/breakoff.wrong
@@ -0,0 +1,5 @@
+foo-
+-foo
+foo-bar
+foo-bar-foo-bar
+scot
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/checkcompoundcase.aff b/extensions/spellcheck/hunspell/tests/unit/data/checkcompoundcase.aff
new file mode 100644
index 0000000000..7ac46eeab7
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/checkcompoundcase.aff
@@ -0,0 +1,3 @@
+# forbid upper case letters at word bounds in compounding
+CHECKCOMPOUNDCASE
+COMPOUNDFLAG A
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/checkcompoundcase.dic b/extensions/spellcheck/hunspell/tests/unit/data/checkcompoundcase.dic
new file mode 100644
index 0000000000..80f65d38f6
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/checkcompoundcase.dic
@@ -0,0 +1,5 @@
+4
+foo/A
+Bar/A
+BAZ/A
+-/A
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/checkcompoundcase.good b/extensions/spellcheck/hunspell/tests/unit/data/checkcompoundcase.good
new file mode 100644
index 0000000000..9cbd79064d
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/checkcompoundcase.good
@@ -0,0 +1,5 @@
+Barfoo
+foo-Bar
+foo-BAZ
+BAZ-foo
+BAZ-Bar
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/checkcompoundcase.test b/extensions/spellcheck/hunspell/tests/unit/data/checkcompoundcase.test
new file mode 100644
index 0000000000..dc295077fb
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/checkcompoundcase.test
@@ -0,0 +1,4 @@
+#!/bin/sh
+DIR="`dirname $0`"
+NAME="`basename $0 .test`"
+$DIR/test.sh $NAME -i ISO8859-1
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/checkcompoundcase.wrong b/extensions/spellcheck/hunspell/tests/unit/data/checkcompoundcase.wrong
new file mode 100644
index 0000000000..0714c22e5d
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/checkcompoundcase.wrong
@@ -0,0 +1,3 @@
+fooBar
+BAZBar
+BAZfoo
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/checkcompoundcase2.aff b/extensions/spellcheck/hunspell/tests/unit/data/checkcompoundcase2.aff
new file mode 100644
index 0000000000..fea046b195
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/checkcompoundcase2.aff
@@ -0,0 +1,3 @@
+# check extended ascii
+CHECKCOMPOUNDCASE
+COMPOUNDFLAG A
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/checkcompoundcase2.dic b/extensions/spellcheck/hunspell/tests/unit/data/checkcompoundcase2.dic
new file mode 100644
index 0000000000..086de0aed7
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/checkcompoundcase2.dic
@@ -0,0 +1,3 @@
+2
+o/A
+o/A
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/checkcompoundcase2.good b/extensions/spellcheck/hunspell/tests/unit/data/checkcompoundcase2.good
new file mode 100644
index 0000000000..b38fd0c6c0
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/checkcompoundcase2.good
@@ -0,0 +1,2 @@
+o黶o
+o瘁o
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/checkcompoundcase2.test b/extensions/spellcheck/hunspell/tests/unit/data/checkcompoundcase2.test
new file mode 100644
index 0000000000..dc295077fb
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/checkcompoundcase2.test
@@ -0,0 +1,4 @@
+#!/bin/sh
+DIR="`dirname $0`"
+NAME="`basename $0 .test`"
+$DIR/test.sh $NAME -i ISO8859-1
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/checkcompoundcase2.wrong b/extensions/spellcheck/hunspell/tests/unit/data/checkcompoundcase2.wrong
new file mode 100644
index 0000000000..94786e95b3
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/checkcompoundcase2.wrong
@@ -0,0 +1 @@
+o靡o
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/checkcompoundcaseutf.aff b/extensions/spellcheck/hunspell/tests/unit/data/checkcompoundcaseutf.aff
new file mode 100644
index 0000000000..546f478a52
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/checkcompoundcaseutf.aff
@@ -0,0 +1,3 @@
+SET UTF-8
+CHECKCOMPOUNDCASE
+COMPOUNDFLAG A
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/checkcompoundcaseutf.dic b/extensions/spellcheck/hunspell/tests/unit/data/checkcompoundcaseutf.dic
new file mode 100644
index 0000000000..0b7fbc9acf
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/checkcompoundcaseutf.dic
@@ -0,0 +1,3 @@
+2
+叩o坦/A
+o叩/A
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/checkcompoundcaseutf.good b/extensions/spellcheck/hunspell/tests/unit/data/checkcompoundcaseutf.good
new file mode 100644
index 0000000000..32ae1353c9
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/checkcompoundcaseutf.good
@@ -0,0 +1,2 @@
+叩o坦叩o坦
+o叩叩o坦
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/checkcompoundcaseutf.test b/extensions/spellcheck/hunspell/tests/unit/data/checkcompoundcaseutf.test
new file mode 100644
index 0000000000..cde7c54109
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/checkcompoundcaseutf.test
@@ -0,0 +1,4 @@
+#!/bin/sh
+DIR="`dirname $0`"
+NAME="`basename $0 .test`"
+$DIR/test.sh $NAME -i utf-8
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/checkcompoundcaseutf.wrong b/extensions/spellcheck/hunspell/tests/unit/data/checkcompoundcaseutf.wrong
new file mode 100644
index 0000000000..07434ccae5
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/checkcompoundcaseutf.wrong
@@ -0,0 +1 @@
+叩o坦o叩
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/checkcompounddup.aff b/extensions/spellcheck/hunspell/tests/unit/data/checkcompounddup.aff
new file mode 100644
index 0000000000..5cd357a5a5
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/checkcompounddup.aff
@@ -0,0 +1,3 @@
+# Forbid compound word with triple letters
+CHECKCOMPOUNDDUP
+COMPOUNDFLAG A
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/checkcompounddup.dic b/extensions/spellcheck/hunspell/tests/unit/data/checkcompounddup.dic
new file mode 100644
index 0000000000..8ac75f4fc5
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/checkcompounddup.dic
@@ -0,0 +1,3 @@
+2
+foo/A
+bar/A
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/checkcompounddup.good b/extensions/spellcheck/hunspell/tests/unit/data/checkcompounddup.good
new file mode 100644
index 0000000000..3866f24cae
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/checkcompounddup.good
@@ -0,0 +1,5 @@
+barfoo
+foobar
+foofoobar
+foobarfoo
+barfoobarfoo
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/checkcompounddup.test b/extensions/spellcheck/hunspell/tests/unit/data/checkcompounddup.test
new file mode 100644
index 0000000000..7f44369060
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/checkcompounddup.test
@@ -0,0 +1,4 @@
+#!/bin/sh
+DIR="`dirname $0`"
+NAME="`basename $0 .test`"
+$DIR/test.sh $NAME
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/checkcompounddup.wrong b/extensions/spellcheck/hunspell/tests/unit/data/checkcompounddup.wrong
new file mode 100644
index 0000000000..5e809b3d8c
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/checkcompounddup.wrong
@@ -0,0 +1,3 @@
+foofoo
+foofoofoo
+foobarbar
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/checkcompoundpattern.aff b/extensions/spellcheck/hunspell/tests/unit/data/checkcompoundpattern.aff
new file mode 100644
index 0000000000..dfda51af27
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/checkcompoundpattern.aff
@@ -0,0 +1,5 @@
+# forbid compounds with spec. pattern at word bounds
+COMPOUNDFLAG A
+CHECKCOMPOUNDPATTERN 2
+CHECKCOMPOUNDPATTERN nny ny
+CHECKCOMPOUNDPATTERN ssz sz
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/checkcompoundpattern.dic b/extensions/spellcheck/hunspell/tests/unit/data/checkcompoundpattern.dic
new file mode 100644
index 0000000000..09300f0bcd
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/checkcompoundpattern.dic
@@ -0,0 +1,5 @@
+4
+knny/A
+nyels/A
+hossz/A
+szmts/A
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/checkcompoundpattern.good b/extensions/spellcheck/hunspell/tests/unit/data/checkcompoundpattern.good
new file mode 100644
index 0000000000..0f99c52d24
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/checkcompoundpattern.good
@@ -0,0 +1,2 @@
+knnyszmts
+hossznyels
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/checkcompoundpattern.test b/extensions/spellcheck/hunspell/tests/unit/data/checkcompoundpattern.test
new file mode 100644
index 0000000000..dc295077fb
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/checkcompoundpattern.test
@@ -0,0 +1,4 @@
+#!/bin/sh
+DIR="`dirname $0`"
+NAME="`basename $0 .test`"
+$DIR/test.sh $NAME -i ISO8859-1
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/checkcompoundpattern.wrong b/extensions/spellcheck/hunspell/tests/unit/data/checkcompoundpattern.wrong
new file mode 100644
index 0000000000..5edd115342
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/checkcompoundpattern.wrong
@@ -0,0 +1,4 @@
+knnynyels
+hosszszmts
+hosszknnynyels
+knnynyelshossz
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/checkcompoundpattern2.aff b/extensions/spellcheck/hunspell/tests/unit/data/checkcompoundpattern2.aff
new file mode 100644
index 0000000000..fdf6560b4f
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/checkcompoundpattern2.aff
@@ -0,0 +1,7 @@
+# forbid compounds with spec. pattern at word bound and allow modificated form
+# (for German and Indian languages)
+COMPOUNDFLAG A
+CHECKCOMPOUNDPATTERN 2
+CHECKCOMPOUNDPATTERN o b z
+CHECKCOMPOUNDPATTERN oo ba u
+COMPOUNDMIN 1
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/checkcompoundpattern2.dic b/extensions/spellcheck/hunspell/tests/unit/data/checkcompoundpattern2.dic
new file mode 100644
index 0000000000..8ac75f4fc5
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/checkcompoundpattern2.dic
@@ -0,0 +1,3 @@
+2
+foo/A
+bar/A
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/checkcompoundpattern2.good b/extensions/spellcheck/hunspell/tests/unit/data/checkcompoundpattern2.good
new file mode 100644
index 0000000000..eaad4f902b
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/checkcompoundpattern2.good
@@ -0,0 +1,3 @@
+barfoo
+fozar
+fur
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/checkcompoundpattern2.test b/extensions/spellcheck/hunspell/tests/unit/data/checkcompoundpattern2.test
new file mode 100644
index 0000000000..dc295077fb
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/checkcompoundpattern2.test
@@ -0,0 +1,4 @@
+#!/bin/sh
+DIR="`dirname $0`"
+NAME="`basename $0 .test`"
+$DIR/test.sh $NAME -i ISO8859-1
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/checkcompoundpattern2.wrong b/extensions/spellcheck/hunspell/tests/unit/data/checkcompoundpattern2.wrong
new file mode 100644
index 0000000000..323fae03f4
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/checkcompoundpattern2.wrong
@@ -0,0 +1 @@
+foobar
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/checkcompoundpattern3.aff b/extensions/spellcheck/hunspell/tests/unit/data/checkcompoundpattern3.aff
new file mode 100644
index 0000000000..6c2cfa4aa9
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/checkcompoundpattern3.aff
@@ -0,0 +1,6 @@
+# forbid compounds with spec. pattern at word bound and allow modificated form
+# (for Indian languages)
+COMPOUNDFLAG A
+CHECKCOMPOUNDPATTERN 1
+CHECKCOMPOUNDPATTERN o/X b/Y z
+COMPOUNDMIN 1
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/checkcompoundpattern3.dic b/extensions/spellcheck/hunspell/tests/unit/data/checkcompoundpattern3.dic
new file mode 100644
index 0000000000..6bd1b7fc9e
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/checkcompoundpattern3.dic
@@ -0,0 +1,5 @@
+4
+foo/A
+boo/AX
+bar/A
+ban/AY
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/checkcompoundpattern3.good b/extensions/spellcheck/hunspell/tests/unit/data/checkcompoundpattern3.good
new file mode 100644
index 0000000000..6070eff5c5
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/checkcompoundpattern3.good
@@ -0,0 +1,9 @@
+bozan
+barfoo
+banfoo
+banbar
+foobar
+fooban
+foobanbar
+boobar
+boobarfoo
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/checkcompoundpattern3.test b/extensions/spellcheck/hunspell/tests/unit/data/checkcompoundpattern3.test
new file mode 100644
index 0000000000..dc295077fb
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/checkcompoundpattern3.test
@@ -0,0 +1,4 @@
+#!/bin/sh
+DIR="`dirname $0`"
+NAME="`basename $0 .test`"
+$DIR/test.sh $NAME -i ISO8859-1
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/checkcompoundpattern3.wrong b/extensions/spellcheck/hunspell/tests/unit/data/checkcompoundpattern3.wrong
new file mode 100644
index 0000000000..41d8d37471
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/checkcompoundpattern3.wrong
@@ -0,0 +1,8 @@
+booban
+boobanfoo
+fozar
+fozarfoo
+fozan
+fozanfoo
+bozar
+bozarfoo
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/checkcompoundpattern4.aff b/extensions/spellcheck/hunspell/tests/unit/data/checkcompoundpattern4.aff
new file mode 100644
index 0000000000..ef25663080
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/checkcompoundpattern4.aff
@@ -0,0 +1,8 @@
+# sandhi in Telugu writing system, based on the Kiran Chittella's example
+
+COMPOUNDFLAG x
+COMPOUNDMIN 1
+CHECKCOMPOUNDPATTERN 2
+CHECKCOMPOUNDPATTERN a/A u/A O
+CHECKCOMPOUNDPATTERN u/B u/B u
+
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/checkcompoundpattern4.dic b/extensions/spellcheck/hunspell/tests/unit/data/checkcompoundpattern4.dic
new file mode 100644
index 0000000000..d245ef0196
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/checkcompoundpattern4.dic
@@ -0,0 +1,6 @@
+4
+sUrya/Ax
+udayaM/Ax
+pEru/Bx
+unna/Bx
+
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/checkcompoundpattern4.good b/extensions/spellcheck/hunspell/tests/unit/data/checkcompoundpattern4.good
new file mode 100644
index 0000000000..48761b6ee0
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/checkcompoundpattern4.good
@@ -0,0 +1,2 @@
+sUryOdayaM
+pErunna
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/checkcompoundpattern4.test b/extensions/spellcheck/hunspell/tests/unit/data/checkcompoundpattern4.test
new file mode 100644
index 0000000000..dc295077fb
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/checkcompoundpattern4.test
@@ -0,0 +1,4 @@
+#!/bin/sh
+DIR="`dirname $0`"
+NAME="`basename $0 .test`"
+$DIR/test.sh $NAME -i ISO8859-1
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/checkcompoundpattern4.wrong b/extensions/spellcheck/hunspell/tests/unit/data/checkcompoundpattern4.wrong
new file mode 100644
index 0000000000..a357fec522
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/checkcompoundpattern4.wrong
@@ -0,0 +1,2 @@
+sUryaudayaM
+pEruunna
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/checkcompoundrep.aff b/extensions/spellcheck/hunspell/tests/unit/data/checkcompoundrep.aff
new file mode 100644
index 0000000000..4fb7ff55e5
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/checkcompoundrep.aff
@@ -0,0 +1,8 @@
+// forbid compound word, if it is also a non compound word with a REP fault
+// In example: Hungarian `szervz' (szer+vz) compound word is forbidden, because
+// this word is also a dictionary word (szerviz) with typical fault (i->)
+CHECKCOMPOUNDREP
+COMPOUNDFLAG A
+
+REP 1
+REP i
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/checkcompoundrep.dic b/extensions/spellcheck/hunspell/tests/unit/data/checkcompoundrep.dic
new file mode 100644
index 0000000000..030bda916c
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/checkcompoundrep.dic
@@ -0,0 +1,5 @@
+3
+szer/A
+vz/A
+szerviz
+kocsi/A
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/checkcompoundrep.good b/extensions/spellcheck/hunspell/tests/unit/data/checkcompoundrep.good
new file mode 100644
index 0000000000..c95c03c875
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/checkcompoundrep.good
@@ -0,0 +1,2 @@
+vzszer
+szerkocsi \ No newline at end of file
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/checkcompoundrep.test b/extensions/spellcheck/hunspell/tests/unit/data/checkcompoundrep.test
new file mode 100644
index 0000000000..dc295077fb
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/checkcompoundrep.test
@@ -0,0 +1,4 @@
+#!/bin/sh
+DIR="`dirname $0`"
+NAME="`basename $0 .test`"
+$DIR/test.sh $NAME -i ISO8859-1
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/checkcompoundrep.wrong b/extensions/spellcheck/hunspell/tests/unit/data/checkcompoundrep.wrong
new file mode 100644
index 0000000000..8c8701d472
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/checkcompoundrep.wrong
@@ -0,0 +1,3 @@
+szervz
+szervzkocsi
+kocsiszervz
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/checkcompoundtriple.aff b/extensions/spellcheck/hunspell/tests/unit/data/checkcompoundtriple.aff
new file mode 100644
index 0000000000..7159cf55dd
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/checkcompoundtriple.aff
@@ -0,0 +1,3 @@
+# Forbid compound word with triple letters
+CHECKCOMPOUNDTRIPLE
+COMPOUNDFLAG A
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/checkcompoundtriple.dic b/extensions/spellcheck/hunspell/tests/unit/data/checkcompoundtriple.dic
new file mode 100644
index 0000000000..607c489e8b
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/checkcompoundtriple.dic
@@ -0,0 +1,5 @@
+4
+foo/A
+opera/A
+eel/A
+bare/A
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/checkcompoundtriple.good b/extensions/spellcheck/hunspell/tests/unit/data/checkcompoundtriple.good
new file mode 100644
index 0000000000..1293f749ad
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/checkcompoundtriple.good
@@ -0,0 +1,6 @@
+operafoo
+operaeel
+operabare
+eelbare
+eelfoo
+eelopera
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/checkcompoundtriple.test b/extensions/spellcheck/hunspell/tests/unit/data/checkcompoundtriple.test
new file mode 100644
index 0000000000..7f44369060
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/checkcompoundtriple.test
@@ -0,0 +1,4 @@
+#!/bin/sh
+DIR="`dirname $0`"
+NAME="`basename $0 .test`"
+$DIR/test.sh $NAME
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/checkcompoundtriple.wrong b/extensions/spellcheck/hunspell/tests/unit/data/checkcompoundtriple.wrong
new file mode 100644
index 0000000000..ae2d02b20d
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/checkcompoundtriple.wrong
@@ -0,0 +1,2 @@
+fooopera
+bareeel
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/checksharps.aff b/extensions/spellcheck/hunspell/tests/unit/data/checksharps.aff
new file mode 100644
index 0000000000..6b22c73906
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/checksharps.aff
@@ -0,0 +1,4 @@
+# test - SS special capitalizing
+CHECKSHARPS
+WORDCHARS .
+KEEPCASE k
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/checksharps.dic b/extensions/spellcheck/hunspell/tests/unit/data/checksharps.dic
new file mode 100644
index 0000000000..91d14ab9ef
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/checksharps.dic
@@ -0,0 +1,7 @@
+6
+mig/k
+Aussto
+Absto.
+Auenabmessung
+Prozessionsstrae
+Auenmae
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/checksharps.good b/extensions/spellcheck/hunspell/tests/unit/data/checksharps.good
new file mode 100644
index 0000000000..e9be8c5c79
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/checksharps.good
@@ -0,0 +1,13 @@
+mig
+Mig
+MSSIG
+Aussto
+Absto.
+Auenabmessung
+Prozessionsstrae
+Auenmae
+AUSSTOSS
+ABSTOSS.
+AUSSENABMESSUNG
+PROZESSIONSSTRASSE
+AUSSENMASSE
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/checksharps.sug b/extensions/spellcheck/hunspell/tests/unit/data/checksharps.sug
new file mode 100644
index 0000000000..52c6a943be
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/checksharps.sug
@@ -0,0 +1 @@
+MSSIG, mig
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/checksharps.test b/extensions/spellcheck/hunspell/tests/unit/data/checksharps.test
new file mode 100644
index 0000000000..dc295077fb
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/checksharps.test
@@ -0,0 +1,4 @@
+#!/bin/sh
+DIR="`dirname $0`"
+NAME="`basename $0 .test`"
+$DIR/test.sh $NAME -i ISO8859-1
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/checksharps.wrong b/extensions/spellcheck/hunspell/tests/unit/data/checksharps.wrong
new file mode 100644
index 0000000000..96eb8aea7c
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/checksharps.wrong
@@ -0,0 +1 @@
+M槹IG
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/checksharpsutf.aff b/extensions/spellcheck/hunspell/tests/unit/data/checksharpsutf.aff
new file mode 100644
index 0000000000..86c0fc426f
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/checksharpsutf.aff
@@ -0,0 +1,5 @@
+# test - SS special capitalizing in UTF-8
+SET UTF-8
+CHECKSHARPS
+WORDCHARS .
+KEEPCASE k
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/checksharpsutf.dic b/extensions/spellcheck/hunspell/tests/unit/data/checksharpsutf.dic
new file mode 100644
index 0000000000..9cc364eec1
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/checksharpsutf.dic
@@ -0,0 +1,7 @@
+6
+m端ig/k
+Aussto
+Absto.
+Auenabmessung
+Prozessionsstrae
+Auenmae
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/checksharpsutf.good b/extensions/spellcheck/hunspell/tests/unit/data/checksharpsutf.good
new file mode 100644
index 0000000000..a61c243193
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/checksharpsutf.good
@@ -0,0 +1,13 @@
+m端ig
+M端ig
+MSSIG
+Aussto
+Absto.
+Auenabmessung
+Prozessionsstrae
+Auenmae
+AUSSTOSS
+ABSTOSS.
+AUSSENABMESSUNG
+PROZESSIONSSTRASSE
+AUSSENMASSE
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/checksharpsutf.sug b/extensions/spellcheck/hunspell/tests/unit/data/checksharpsutf.sug
new file mode 100644
index 0000000000..ab68568e52
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/checksharpsutf.sug
@@ -0,0 +1 @@
+MSSIG, m端ig
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/checksharpsutf.test b/extensions/spellcheck/hunspell/tests/unit/data/checksharpsutf.test
new file mode 100644
index 0000000000..cde7c54109
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/checksharpsutf.test
@@ -0,0 +1,4 @@
+#!/bin/sh
+DIR="`dirname $0`"
+NAME="`basename $0 .test`"
+$DIR/test.sh $NAME -i utf-8
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/checksharpsutf.wrong b/extensions/spellcheck/hunspell/tests/unit/data/checksharpsutf.wrong
new file mode 100644
index 0000000000..25eb03dcec
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/checksharpsutf.wrong
@@ -0,0 +1 @@
+MIG
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/circumfix.aff b/extensions/spellcheck/hunspell/tests/unit/data/circumfix.aff
new file mode 100644
index 0000000000..1eecc644b0
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/circumfix.aff
@@ -0,0 +1,16 @@
+# circumfixes: ~ obligate prefix/suffix combinations
+# superlative in Hungarian: leg- (prefix) AND -bb (suffix)
+
+CIRCUMFIX X
+
+PFX A Y 1
+PFX A 0 leg/X .
+
+PFX B Y 1
+PFX B 0 legesleg/X .
+
+SFX C Y 3
+SFX C 0 obb . is:COMPARATIVE
+SFX C 0 obb/AX . is:SUPERLATIVE
+SFX C 0 obb/BX . is:SUPERSUPERLATIVE
+
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/circumfix.dic b/extensions/spellcheck/hunspell/tests/unit/data/circumfix.dic
new file mode 100644
index 0000000000..ba96f046dd
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/circumfix.dic
@@ -0,0 +1,2 @@
+1
+nagy/C po:adj
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/circumfix.good b/extensions/spellcheck/hunspell/tests/unit/data/circumfix.good
new file mode 100644
index 0000000000..65049d9f01
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/circumfix.good
@@ -0,0 +1,4 @@
+nagy
+nagyobb
+legnagyobb
+legeslegnagyobb
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/circumfix.morph b/extensions/spellcheck/hunspell/tests/unit/data/circumfix.morph
new file mode 100644
index 0000000000..62e6c5371b
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/circumfix.morph
@@ -0,0 +1,12 @@
+> nagy
+analyze(nagy) = st:nagy po:adj
+stem(nagy) = nagy
+> nagyobb
+analyze(nagyobb) = st:nagy po:adj is:COMPARATIVE
+stem(nagyobb) = nagy
+> legnagyobb
+analyze(legnagyobb) = fl:A st:nagy po:adj is:SUPERLATIVE
+stem(legnagyobb) = nagy
+> legeslegnagyobb
+analyze(legeslegnagyobb) = fl:B st:nagy po:adj is:SUPERSUPERLATIVE
+stem(legeslegnagyobb) = nagy
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/circumfix.test b/extensions/spellcheck/hunspell/tests/unit/data/circumfix.test
new file mode 100644
index 0000000000..7f44369060
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/circumfix.test
@@ -0,0 +1,4 @@
+#!/bin/sh
+DIR="`dirname $0`"
+NAME="`basename $0 .test`"
+$DIR/test.sh $NAME
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/circumfix.wrong b/extensions/spellcheck/hunspell/tests/unit/data/circumfix.wrong
new file mode 100644
index 0000000000..bab8084ee1
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/circumfix.wrong
@@ -0,0 +1,2 @@
+legnagy
+legeslegnagy
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/colons-in-words.aff b/extensions/spellcheck/hunspell/tests/unit/data/colons-in-words.aff
new file mode 100644
index 0000000000..d08022694e
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/colons-in-words.aff
@@ -0,0 +1,3 @@
+# Colons in Finnish and Swedish words. Problem reported by Lars Aronsson.
+# Parsing test (src/parsers)
+WORDCHARS :
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/colons-in-words.dic b/extensions/spellcheck/hunspell/tests/unit/data/colons-in-words.dic
new file mode 100644
index 0000000000..bfea1ccc7e
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/colons-in-words.dic
@@ -0,0 +1,4 @@
+2
+c:a
+S:t
+foo
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/colons-in-words.test b/extensions/spellcheck/hunspell/tests/unit/data/colons-in-words.test
new file mode 100644
index 0000000000..7f44369060
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/colons-in-words.test
@@ -0,0 +1,4 @@
+#!/bin/sh
+DIR="`dirname $0`"
+NAME="`basename $0 .test`"
+$DIR/test.sh $NAME
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/complexprefixes.aff b/extensions/spellcheck/hunspell/tests/unit/data/complexprefixes.aff
new file mode 100644
index 0000000000..7ddb497a62
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/complexprefixes.aff
@@ -0,0 +1,9 @@
+# set twofold prefix stripping
+# Coptic example by Moheb Mekhaiel
+COMPLEXPREFIXES
+
+PFX A Y 1
+PFX A 0 tek .
+
+PFX B Y 1
+PFX B 0 met/A .
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/complexprefixes.dic b/extensions/spellcheck/hunspell/tests/unit/data/complexprefixes.dic
new file mode 100644
index 0000000000..2618c7cf43
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/complexprefixes.dic
@@ -0,0 +1,3 @@
+1
+ouro/B
+
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/complexprefixes.good b/extensions/spellcheck/hunspell/tests/unit/data/complexprefixes.good
new file mode 100644
index 0000000000..eed87a7746
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/complexprefixes.good
@@ -0,0 +1,3 @@
+ouro
+metouro
+tekmetouro
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/complexprefixes.test b/extensions/spellcheck/hunspell/tests/unit/data/complexprefixes.test
new file mode 100644
index 0000000000..7f44369060
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/complexprefixes.test
@@ -0,0 +1,4 @@
+#!/bin/sh
+DIR="`dirname $0`"
+NAME="`basename $0 .test`"
+$DIR/test.sh $NAME
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/complexprefixes.wrong b/extensions/spellcheck/hunspell/tests/unit/data/complexprefixes.wrong
new file mode 100644
index 0000000000..fb1c8b4835
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/complexprefixes.wrong
@@ -0,0 +1,2 @@
+tekouro
+mettekouro
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/complexprefixes2.aff b/extensions/spellcheck/hunspell/tests/unit/data/complexprefixes2.aff
new file mode 100644
index 0000000000..b4fe1dca61
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/complexprefixes2.aff
@@ -0,0 +1,12 @@
+# complex prefixes with morphological analysis
+COMPLEXPREFIXES
+WORDCHARS _
+
+PFX A Y 1
+PFX A 0 tek . affix_1/
+
+PFX B Y 1
+PFX B 0 met/A . affix_2/
+
+SFX C Y 1
+SFX C 0 _test_ . /suffix_1
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/complexprefixes2.dic b/extensions/spellcheck/hunspell/tests/unit/data/complexprefixes2.dic
new file mode 100644
index 0000000000..7e4baf06c1
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/complexprefixes2.dic
@@ -0,0 +1,3 @@
+1
+ouro/BC [stem_1]
+
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/complexprefixes2.good b/extensions/spellcheck/hunspell/tests/unit/data/complexprefixes2.good
new file mode 100644
index 0000000000..6bf822826b
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/complexprefixes2.good
@@ -0,0 +1,4 @@
+ouro
+metouro
+tekmetouro
+ouro_test_
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/complexprefixes2.test b/extensions/spellcheck/hunspell/tests/unit/data/complexprefixes2.test
new file mode 100644
index 0000000000..7f44369060
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/complexprefixes2.test
@@ -0,0 +1,4 @@
+#!/bin/sh
+DIR="`dirname $0`"
+NAME="`basename $0 .test`"
+$DIR/test.sh $NAME
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/complexprefixesutf.aff b/extensions/spellcheck/hunspell/tests/unit/data/complexprefixesutf.aff
new file mode 100644
index 0000000000..3991e9f5ca
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/complexprefixesutf.aff
@@ -0,0 +1,12 @@
+# Coptic example by Moheb Mekhaiel
+# Encoded with the new Coptic character encoding of Unicode 4.1
+SET UTF-8
+
+# set twofold prefix stripping
+COMPLEXPREFIXES
+
+PFX A Y 1
+PFX A 0 皺р皺 .
+
+PFX B Y 1
+PFX B 0 皺皺皺/A .
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/complexprefixesutf.dic b/extensions/spellcheck/hunspell/tests/unit/data/complexprefixesutf.dic
new file mode 100644
index 0000000000..bd0eb6df0d
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/complexprefixesutf.dic
@@ -0,0 +1,2 @@
+1
+皺皺皺b/B
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/complexprefixesutf.good b/extensions/spellcheck/hunspell/tests/unit/data/complexprefixesutf.good
new file mode 100644
index 0000000000..7eb9566199
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/complexprefixesutf.good
@@ -0,0 +1,3 @@
+皺皺皺b
+皺皺皺р皺皺b
+皺р皺皺皺皺р皺皺b
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/complexprefixesutf.test b/extensions/spellcheck/hunspell/tests/unit/data/complexprefixesutf.test
new file mode 100644
index 0000000000..cde7c54109
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/complexprefixesutf.test
@@ -0,0 +1,4 @@
+#!/bin/sh
+DIR="`dirname $0`"
+NAME="`basename $0 .test`"
+$DIR/test.sh $NAME -i utf-8
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/complexprefixesutf.wrong b/extensions/spellcheck/hunspell/tests/unit/data/complexprefixesutf.wrong
new file mode 100644
index 0000000000..d8021fc444
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/complexprefixesutf.wrong
@@ -0,0 +1,2 @@
+皺р皺皺皺皺b
+皺皺皺р翁皺皺皺皺皺b
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/compoundaffix.aff b/extensions/spellcheck/hunspell/tests/unit/data/compoundaffix.aff
new file mode 100644
index 0000000000..cae5669c21
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/compoundaffix.aff
@@ -0,0 +1,7 @@
+COMPOUNDFLAG X
+
+PFX P Y 1
+PFX P 0 pre .
+
+SFX S Y 1
+SFX S 0 suf .
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/compoundaffix.dic b/extensions/spellcheck/hunspell/tests/unit/data/compoundaffix.dic
new file mode 100644
index 0000000000..eba6b83fb4
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/compoundaffix.dic
@@ -0,0 +1,3 @@
+2
+foo/XPS
+bar/XPS
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/compoundaffix.good b/extensions/spellcheck/hunspell/tests/unit/data/compoundaffix.good
new file mode 100644
index 0000000000..af1f0019ad
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/compoundaffix.good
@@ -0,0 +1,6 @@
+foo
+foofoo
+prefoo
+foosuf
+prefoosuf
+prefoobarsuf
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/compoundaffix.test b/extensions/spellcheck/hunspell/tests/unit/data/compoundaffix.test
new file mode 100644
index 0000000000..7f44369060
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/compoundaffix.test
@@ -0,0 +1,4 @@
+#!/bin/sh
+DIR="`dirname $0`"
+NAME="`basename $0 .test`"
+$DIR/test.sh $NAME
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/compoundaffix.wrong b/extensions/spellcheck/hunspell/tests/unit/data/compoundaffix.wrong
new file mode 100644
index 0000000000..b7e4067bca
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/compoundaffix.wrong
@@ -0,0 +1,3 @@
+foosufbar
+fooprebarsuf
+prefooprebarsuf
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/compoundaffix2.aff b/extensions/spellcheck/hunspell/tests/unit/data/compoundaffix2.aff
new file mode 100644
index 0000000000..1cac16e117
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/compoundaffix2.aff
@@ -0,0 +1,8 @@
+COMPOUNDFLAG X
+COMPOUNDPERMITFLAG Y
+
+PFX P Y 1
+PFX P 0 pre/Y .
+
+SFX S Y 1
+SFX S 0 suf/Y .
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/compoundaffix2.dic b/extensions/spellcheck/hunspell/tests/unit/data/compoundaffix2.dic
new file mode 100644
index 0000000000..eba6b83fb4
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/compoundaffix2.dic
@@ -0,0 +1,3 @@
+2
+foo/XPS
+bar/XPS
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/compoundaffix2.good b/extensions/spellcheck/hunspell/tests/unit/data/compoundaffix2.good
new file mode 100644
index 0000000000..9f3020da07
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/compoundaffix2.good
@@ -0,0 +1,8 @@
+foo
+prefoo
+foosuf
+prefoosuf
+prefoobarsuf
+foosufbar
+fooprebarsuf
+prefooprebarsuf
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/compoundaffix2.test b/extensions/spellcheck/hunspell/tests/unit/data/compoundaffix2.test
new file mode 100644
index 0000000000..7f44369060
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/compoundaffix2.test
@@ -0,0 +1,4 @@
+#!/bin/sh
+DIR="`dirname $0`"
+NAME="`basename $0 .test`"
+$DIR/test.sh $NAME
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/compoundaffix3.aff b/extensions/spellcheck/hunspell/tests/unit/data/compoundaffix3.aff
new file mode 100644
index 0000000000..98a12b56c7
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/compoundaffix3.aff
@@ -0,0 +1,8 @@
+COMPOUNDFLAG X
+COMPOUNDFORBIDFLAG Z
+
+PFX P Y 1
+PFX P 0 pre/Z .
+
+SFX S Y 1
+SFX S 0 suf/Z .
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/compoundaffix3.dic b/extensions/spellcheck/hunspell/tests/unit/data/compoundaffix3.dic
new file mode 100644
index 0000000000..eba6b83fb4
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/compoundaffix3.dic
@@ -0,0 +1,3 @@
+2
+foo/XPS
+bar/XPS
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/compoundaffix3.good b/extensions/spellcheck/hunspell/tests/unit/data/compoundaffix3.good
new file mode 100644
index 0000000000..76cc08eae2
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/compoundaffix3.good
@@ -0,0 +1,5 @@
+foo
+foofoo
+prefoo
+foosuf
+prefoosuf
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/compoundaffix3.test b/extensions/spellcheck/hunspell/tests/unit/data/compoundaffix3.test
new file mode 100644
index 0000000000..7f44369060
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/compoundaffix3.test
@@ -0,0 +1,4 @@
+#!/bin/sh
+DIR="`dirname $0`"
+NAME="`basename $0 .test`"
+$DIR/test.sh $NAME
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/compoundaffix3.wrong b/extensions/spellcheck/hunspell/tests/unit/data/compoundaffix3.wrong
new file mode 100644
index 0000000000..d92b90b282
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/compoundaffix3.wrong
@@ -0,0 +1,6 @@
+prefoobarsuf
+foosufbar
+fooprebar
+foosufprebar
+fooprebarsuf
+prefooprebarsuf
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/compoundflag.aff b/extensions/spellcheck/hunspell/tests/unit/data/compoundflag.aff
new file mode 100644
index 0000000000..bc8369ceba
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/compoundflag.aff
@@ -0,0 +1,3 @@
+COMPOUNDMIN 3
+COMPOUNDFLAG A
+
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/compoundflag.dic b/extensions/spellcheck/hunspell/tests/unit/data/compoundflag.dic
new file mode 100644
index 0000000000..d1ea8e96e7
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/compoundflag.dic
@@ -0,0 +1,5 @@
+4
+foo/A
+bar/A
+xy/A
+yz/A
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/compoundflag.good b/extensions/spellcheck/hunspell/tests/unit/data/compoundflag.good
new file mode 100644
index 0000000000..21cc29f2f0
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/compoundflag.good
@@ -0,0 +1,3 @@
+foobar
+barfoo
+foobarfoo
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/compoundflag.test b/extensions/spellcheck/hunspell/tests/unit/data/compoundflag.test
new file mode 100644
index 0000000000..7f44369060
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/compoundflag.test
@@ -0,0 +1,4 @@
+#!/bin/sh
+DIR="`dirname $0`"
+NAME="`basename $0 .test`"
+$DIR/test.sh $NAME
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/compoundflag.wrong b/extensions/spellcheck/hunspell/tests/unit/data/compoundflag.wrong
new file mode 100644
index 0000000000..c185bf150e
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/compoundflag.wrong
@@ -0,0 +1,4 @@
+xyyz
+fooxy
+xyfoo
+fooxybar
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/compoundrule.aff b/extensions/spellcheck/hunspell/tests/unit/data/compoundrule.aff
new file mode 100644
index 0000000000..09309e0aab
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/compoundrule.aff
@@ -0,0 +1,3 @@
+COMPOUNDMIN 1
+COMPOUNDRULE 1
+COMPOUNDRULE ABC
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/compoundrule.dic b/extensions/spellcheck/hunspell/tests/unit/data/compoundrule.dic
new file mode 100644
index 0000000000..b11e8291e6
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/compoundrule.dic
@@ -0,0 +1,5 @@
+3
+a/A
+b/B
+c/BC
+
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/compoundrule.good b/extensions/spellcheck/hunspell/tests/unit/data/compoundrule.good
new file mode 100644
index 0000000000..c7a0763bb1
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/compoundrule.good
@@ -0,0 +1,2 @@
+abc
+acc
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/compoundrule.test b/extensions/spellcheck/hunspell/tests/unit/data/compoundrule.test
new file mode 100644
index 0000000000..7f44369060
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/compoundrule.test
@@ -0,0 +1,4 @@
+#!/bin/sh
+DIR="`dirname $0`"
+NAME="`basename $0 .test`"
+$DIR/test.sh $NAME
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/compoundrule.wrong b/extensions/spellcheck/hunspell/tests/unit/data/compoundrule.wrong
new file mode 100644
index 0000000000..bc151ea029
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/compoundrule.wrong
@@ -0,0 +1,39 @@
+ba
+aaabaaa
+bbaaa
+aaaaba
+bbbbbaa
+aa
+aaa
+aaaa
+ab
+aab
+aaab
+aaaab
+abb
+aabb
+aaabbb
+bb
+bbb
+bbbb
+aaab
+abcc
+abbc
+abbcc
+aabc
+aabcc
+aabbc
+aabbcc
+aaabbbccc
+ac
+aac
+aacc
+aaaccc
+bc
+bcc
+bbc
+bbcc
+bbbccc
+cc
+ccc
+cccccc
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/compoundrule2.aff b/extensions/spellcheck/hunspell/tests/unit/data/compoundrule2.aff
new file mode 100644
index 0000000000..e4b86a53b4
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/compoundrule2.aff
@@ -0,0 +1,3 @@
+COMPOUNDMIN 1
+COMPOUNDRULE 1
+COMPOUNDRULE A*B*C*
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/compoundrule2.dic b/extensions/spellcheck/hunspell/tests/unit/data/compoundrule2.dic
new file mode 100644
index 0000000000..7d07bbc89a
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/compoundrule2.dic
@@ -0,0 +1,5 @@
+3
+a/A
+b/B
+c/C
+
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/compoundrule2.good b/extensions/spellcheck/hunspell/tests/unit/data/compoundrule2.good
new file mode 100644
index 0000000000..de743bb067
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/compoundrule2.good
@@ -0,0 +1,37 @@
+aa
+aaa
+aaaa
+ab
+aab
+aaab
+aaaab
+abb
+aabb
+aaabbb
+bb
+bbb
+bbbb
+aaab
+abc
+abcc
+abbc
+abbcc
+aabc
+aabcc
+aabbc
+aabbcc
+aaabbbccc
+ac
+acc
+aac
+aacc
+aaaccc
+bc
+bcc
+bbc
+bbcc
+bbbccc
+cc
+ccc
+cccccc
+abcc
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/compoundrule2.test b/extensions/spellcheck/hunspell/tests/unit/data/compoundrule2.test
new file mode 100644
index 0000000000..7f44369060
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/compoundrule2.test
@@ -0,0 +1,4 @@
+#!/bin/sh
+DIR="`dirname $0`"
+NAME="`basename $0 .test`"
+$DIR/test.sh $NAME
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/compoundrule2.wrong b/extensions/spellcheck/hunspell/tests/unit/data/compoundrule2.wrong
new file mode 100644
index 0000000000..9e5d38d350
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/compoundrule2.wrong
@@ -0,0 +1,8 @@
+ba
+aaabaaa
+bbaaa
+aaaaba
+bbbbbaa
+cba
+cab
+acb
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/compoundrule3.aff b/extensions/spellcheck/hunspell/tests/unit/data/compoundrule3.aff
new file mode 100644
index 0000000000..005314586c
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/compoundrule3.aff
@@ -0,0 +1,3 @@
+COMPOUNDMIN 1
+COMPOUNDRULE 1
+COMPOUNDRULE A?B?C?
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/compoundrule3.dic b/extensions/spellcheck/hunspell/tests/unit/data/compoundrule3.dic
new file mode 100644
index 0000000000..7d07bbc89a
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/compoundrule3.dic
@@ -0,0 +1,5 @@
+3
+a/A
+b/B
+c/C
+
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/compoundrule3.good b/extensions/spellcheck/hunspell/tests/unit/data/compoundrule3.good
new file mode 100644
index 0000000000..7f518893e9
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/compoundrule3.good
@@ -0,0 +1,7 @@
+a
+b
+c
+ab
+abc
+ac
+bc
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/compoundrule3.test b/extensions/spellcheck/hunspell/tests/unit/data/compoundrule3.test
new file mode 100644
index 0000000000..7f44369060
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/compoundrule3.test
@@ -0,0 +1,4 @@
+#!/bin/sh
+DIR="`dirname $0`"
+NAME="`basename $0 .test`"
+$DIR/test.sh $NAME
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/compoundrule3.wrong b/extensions/spellcheck/hunspell/tests/unit/data/compoundrule3.wrong
new file mode 100644
index 0000000000..6bd1d8004a
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/compoundrule3.wrong
@@ -0,0 +1,41 @@
+aa
+aaa
+aaaa
+aab
+aaab
+aaaab
+abb
+aabb
+aaabbb
+bb
+bbb
+bbbb
+aaab
+abcc
+abbc
+abbcc
+aabc
+aabcc
+aabbc
+aabbcc
+aaabbbccc
+acc
+aac
+aacc
+aaaccc
+bcc
+bbc
+bbcc
+bbbccc
+cc
+ccc
+cccccc
+abcc
+ba
+aaabaaa
+bbaaa
+aaaaba
+bbbbbaa
+cba
+cab
+acb
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/compoundrule4.aff b/extensions/spellcheck/hunspell/tests/unit/data/compoundrule4.aff
new file mode 100644
index 0000000000..8a9996cb3e
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/compoundrule4.aff
@@ -0,0 +1,7 @@
+# English ordinal numbers
+WORDCHARS 0123456789
+COMPOUNDMIN 1
+ONLYINCOMPOUND c
+COMPOUNDRULE 2
+COMPOUNDRULE n*1t
+COMPOUNDRULE n*mp
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/compoundrule4.dic b/extensions/spellcheck/hunspell/tests/unit/data/compoundrule4.dic
new file mode 100644
index 0000000000..ced0735ec1
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/compoundrule4.dic
@@ -0,0 +1,24 @@
+22
+0/nm
+1/n1
+2/nm
+3/nm
+4/nm
+5/nm
+6/nm
+7/nm
+8/nm
+9/nm
+0th/pt
+1st/p
+1th/tc
+2nd/p
+2th/tc
+3rd/p
+3th/tc
+4th/pt
+5th/pt
+6th/pt
+7th/pt
+8th/pt
+9th/pt
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/compoundrule4.good b/extensions/spellcheck/hunspell/tests/unit/data/compoundrule4.good
new file mode 100644
index 0000000000..fafe64a5ca
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/compoundrule4.good
@@ -0,0 +1,29 @@
+1st
+2nd
+3rd
+4th
+5th
+6th
+7th
+8th
+9th
+10th
+11th
+12th
+13th
+14th
+15th
+16th
+17th
+18th
+19th
+20th
+21st
+22nd
+23rd
+24th
+25th
+100th
+1000th
+10001st
+10011th
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/compoundrule4.test b/extensions/spellcheck/hunspell/tests/unit/data/compoundrule4.test
new file mode 100644
index 0000000000..52e144cb80
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/compoundrule4.test
@@ -0,0 +1,6 @@
+#!/bin/sh
+DIR="`dirname $0`"
+NAME="`basename $0 .test`"
+$DIR/test.sh $NAME
+
+
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/compoundrule4.wrong b/extensions/spellcheck/hunspell/tests/unit/data/compoundrule4.wrong
new file mode 100644
index 0000000000..99f28e7cc3
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/compoundrule4.wrong
@@ -0,0 +1,5 @@
+1th
+2th
+3th
+10001th
+10011st
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/compoundrule5.aff b/extensions/spellcheck/hunspell/tests/unit/data/compoundrule5.aff
new file mode 100644
index 0000000000..46502460bc
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/compoundrule5.aff
@@ -0,0 +1,7 @@
+# number + percent
+SET UTF-8
+COMPOUNDMIN 1
+COMPOUNDRULE 2
+COMPOUNDRULE N*%?
+COMPOUNDRULE NN*.NN*%?
+WORDCHARS 0123456789.
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/compoundrule5.dic b/extensions/spellcheck/hunspell/tests/unit/data/compoundrule5.dic
new file mode 100644
index 0000000000..eeeffdac50
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/compoundrule5.dic
@@ -0,0 +1,14 @@
+13
+0/N po:num
+1/N po:num
+2/N po:num
+3/N po:num
+4/N po:num
+5/N po:num
+6/N po:num
+7/N po:num
+8/N po:num
+9/N po:num
+./. po:sign_dot
+%/% po:sign_percent
+/% po:sign_per_mille
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/compoundrule5.good b/extensions/spellcheck/hunspell/tests/unit/data/compoundrule5.good
new file mode 100644
index 0000000000..691fca1fb9
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/compoundrule5.good
@@ -0,0 +1,7 @@
+10%
+0.2%
+0.20%
+123.4561
+10
+0000
+10.25
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/compoundrule5.morph b/extensions/spellcheck/hunspell/tests/unit/data/compoundrule5.morph
new file mode 100644
index 0000000000..107a80859f
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/compoundrule5.morph
@@ -0,0 +1,21 @@
+> 10%
+analyze(10%) = pa:1 st:1 po:num pa:0 st:0 po:num pa:% st:% po:sign_percent
+stem(10%) = 10%
+> 0.2%
+analyze(0.2%) = pa:0 st:0 po:num pa:. st:. po:sign_dot pa:2 st:2 po:num pa:% st:% po:sign_percent
+stem(0.2%) = 0.2%
+> 0.20%
+analyze(0.20%) = pa:0 st:0 po:num pa:. st:. po:sign_dot pa:2 st:2 po:num pa:0 st:0 po:num pa:% st:% po:sign_percent
+stem(0.20%) = 0.20%
+> 123.4561
+analyze(123.4561) = pa:1 st:1 po:num pa:2 st:2 po:num pa:3 st:3 po:num pa:. st:. po:sign_dot pa:4 st:4 po:num pa:5 st:5 po:num pa:6 st:6 po:num pa:1 st:1 po:num pa: st: po:sign_per_mille
+stem(123.4561) = 123.4561
+> 10
+analyze(10) = pa:1 st:1 po:num pa:0 st:0 po:num
+stem(10) = 10
+> 0000
+analyze(0000) = pa:0 st:0 po:num pa:0 st:0 po:num pa:0 st:0 po:num pa:0 st:0 po:num
+stem(0000) = 0000
+> 10.25
+analyze(10.25) = pa:1 st:1 po:num pa:0 st:0 po:num pa:. st:. po:sign_dot pa:2 st:2 po:num pa:5 st:5 po:num
+stem(10.25) = 10.25
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/compoundrule5.test b/extensions/spellcheck/hunspell/tests/unit/data/compoundrule5.test
new file mode 100644
index 0000000000..cde7c54109
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/compoundrule5.test
@@ -0,0 +1,4 @@
+#!/bin/sh
+DIR="`dirname $0`"
+NAME="`basename $0 .test`"
+$DIR/test.sh $NAME -i utf-8
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/compoundrule5.wrong b/extensions/spellcheck/hunspell/tests/unit/data/compoundrule5.wrong
new file mode 100644
index 0000000000..ba1fe3290f
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/compoundrule5.wrong
@@ -0,0 +1 @@
+.25
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/compoundrule6.aff b/extensions/spellcheck/hunspell/tests/unit/data/compoundrule6.aff
new file mode 100644
index 0000000000..e8a088d5a7
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/compoundrule6.aff
@@ -0,0 +1,4 @@
+COMPOUNDMIN 1
+COMPOUNDRULE 2
+COMPOUNDRULE A*A
+COMPOUNDRULE A*AAB*BBBC*C
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/compoundrule6.dic b/extensions/spellcheck/hunspell/tests/unit/data/compoundrule6.dic
new file mode 100644
index 0000000000..7d07bbc89a
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/compoundrule6.dic
@@ -0,0 +1,5 @@
+3
+a/A
+b/B
+c/C
+
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/compoundrule6.good b/extensions/spellcheck/hunspell/tests/unit/data/compoundrule6.good
new file mode 100644
index 0000000000..55a8f8bc5f
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/compoundrule6.good
@@ -0,0 +1,4 @@
+aa
+aaaaaa
+aabbbc
+aaaaabbbbbbcccccc
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/compoundrule6.test b/extensions/spellcheck/hunspell/tests/unit/data/compoundrule6.test
new file mode 100644
index 0000000000..7f44369060
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/compoundrule6.test
@@ -0,0 +1,4 @@
+#!/bin/sh
+DIR="`dirname $0`"
+NAME="`basename $0 .test`"
+$DIR/test.sh $NAME
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/compoundrule6.wrong b/extensions/spellcheck/hunspell/tests/unit/data/compoundrule6.wrong
new file mode 100644
index 0000000000..48b376dac5
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/compoundrule6.wrong
@@ -0,0 +1,4 @@
+abc
+abbbbbccccccc
+aabbccccccc
+aabbbbbbb
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/compoundrule7.aff b/extensions/spellcheck/hunspell/tests/unit/data/compoundrule7.aff
new file mode 100644
index 0000000000..3ae1fc7847
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/compoundrule7.aff
@@ -0,0 +1,8 @@
+# English ordinal numbers (parenthesized long flags)
+FLAG long
+WORDCHARS 0123456789
+COMPOUNDMIN 1
+ONLYINCOMPOUND cc
+COMPOUNDRULE 2
+COMPOUNDRULE (nn)*(11)(tt)
+COMPOUNDRULE (nn)*(mm)(pp)
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/compoundrule7.dic b/extensions/spellcheck/hunspell/tests/unit/data/compoundrule7.dic
new file mode 100644
index 0000000000..ad4bb4d284
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/compoundrule7.dic
@@ -0,0 +1,24 @@
+22
+0/nnmm
+1/nn11
+2/nnmm
+3/nnmm
+4/nnmm
+5/nnmm
+6/nnmm
+7/nnmm
+8/nnmm
+9/nnmm
+0th/pptt
+1st/pp
+1th/ttcc
+2nd/pp
+2th/ttcc
+3rd/pp
+3th/ttcc
+4th/pptt
+5th/pptt
+6th/pptt
+7th/pptt
+8th/pptt
+9th/pptt
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/compoundrule7.good b/extensions/spellcheck/hunspell/tests/unit/data/compoundrule7.good
new file mode 100644
index 0000000000..fafe64a5ca
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/compoundrule7.good
@@ -0,0 +1,29 @@
+1st
+2nd
+3rd
+4th
+5th
+6th
+7th
+8th
+9th
+10th
+11th
+12th
+13th
+14th
+15th
+16th
+17th
+18th
+19th
+20th
+21st
+22nd
+23rd
+24th
+25th
+100th
+1000th
+10001st
+10011th
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/compoundrule7.test b/extensions/spellcheck/hunspell/tests/unit/data/compoundrule7.test
new file mode 100644
index 0000000000..52e144cb80
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/compoundrule7.test
@@ -0,0 +1,6 @@
+#!/bin/sh
+DIR="`dirname $0`"
+NAME="`basename $0 .test`"
+$DIR/test.sh $NAME
+
+
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/compoundrule7.wrong b/extensions/spellcheck/hunspell/tests/unit/data/compoundrule7.wrong
new file mode 100644
index 0000000000..99f28e7cc3
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/compoundrule7.wrong
@@ -0,0 +1,5 @@
+1th
+2th
+3th
+10001th
+10011st
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/compoundrule8.aff b/extensions/spellcheck/hunspell/tests/unit/data/compoundrule8.aff
new file mode 100644
index 0000000000..03a423d486
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/compoundrule8.aff
@@ -0,0 +1,8 @@
+# English ordinal numbers (parenthesized numerical flags)
+FLAG num
+WORDCHARS 0123456789
+COMPOUNDMIN 1
+ONLYINCOMPOUND 1000
+COMPOUNDRULE 2
+COMPOUNDRULE (1001)*(1002)(2001)
+COMPOUNDRULE (1001)*(2002)(2000)
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/compoundrule8.dic b/extensions/spellcheck/hunspell/tests/unit/data/compoundrule8.dic
new file mode 100644
index 0000000000..e156e95fe0
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/compoundrule8.dic
@@ -0,0 +1,24 @@
+22
+0/1001,2002
+1/1001,1002
+2/1001,2002
+3/1001,2002
+4/1001,2002
+5/1001,2002
+6/1001,2002
+7/1001,2002
+8/1001,2002
+9/1001,2002
+0th/2000,2001
+1st/2000
+1th/2001,1000
+2nd/2000
+2th/2001,1000
+3rd/2000
+3th/2001,1000
+4th/2000,2001
+5th/2000,2001
+6th/2000,2001
+7th/2000,2001
+8th/2000,2001
+9th/2000,2001
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/compoundrule8.good b/extensions/spellcheck/hunspell/tests/unit/data/compoundrule8.good
new file mode 100644
index 0000000000..fafe64a5ca
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/compoundrule8.good
@@ -0,0 +1,29 @@
+1st
+2nd
+3rd
+4th
+5th
+6th
+7th
+8th
+9th
+10th
+11th
+12th
+13th
+14th
+15th
+16th
+17th
+18th
+19th
+20th
+21st
+22nd
+23rd
+24th
+25th
+100th
+1000th
+10001st
+10011th
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/compoundrule8.test b/extensions/spellcheck/hunspell/tests/unit/data/compoundrule8.test
new file mode 100644
index 0000000000..52e144cb80
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/compoundrule8.test
@@ -0,0 +1,6 @@
+#!/bin/sh
+DIR="`dirname $0`"
+NAME="`basename $0 .test`"
+$DIR/test.sh $NAME
+
+
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/compoundrule8.wrong b/extensions/spellcheck/hunspell/tests/unit/data/compoundrule8.wrong
new file mode 100644
index 0000000000..99f28e7cc3
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/compoundrule8.wrong
@@ -0,0 +1,5 @@
+1th
+2th
+3th
+10001th
+10011st
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/condition-utf.aff b/extensions/spellcheck/hunspell/tests/unit/data/condition-utf.aff
new file mode 100644
index 0000000000..62a1ce5e52
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/condition-utf.aff
@@ -0,0 +1,42 @@
+SET UTF-8
+WORDCHARS 0123456789
+
+SFX S N 18
+SFX S 0 suf1 .
+SFX S 0 suf2 坦
+SFX S 0 suf3 [叩辿坦炭]
+SFX S 0 suf4 [^坦]
+SFX S 0 suf5 [^叩辿坦炭]
+SFX S 0 suf6 坦
+SFX S 0 suf7 [叩辿坦炭]
+SFX S 0 suf8 [^坦]
+SFX S 0 suf9 [^叩辿坦炭]
+SFX S 0 suf10 [叩辿坦炭]坦
+SFX S 0 suf11 [^]坦
+SFX S 0 suf12 [^叩辿坦炭]坦
+SFX S 0 suf13 [叩辿炭][^炭]
+SFX S 0 suf14 [^炭][叩辿坦炭]
+SFX S 0 suf15 [叩辿坦炭][^叩辿炭]
+SFX S 0 suf16 [^叩辿坦炭][^叩辿炭]
+SFX S 0 suf17 [叩辿坦炭][bcdfgkmn坦prstvz]
+SFX S 0 suf18 [叩辿坦炭]坦
+
+PFX P N 18
+PFX P 0 pre1 .
+PFX P 0 pre2 坦
+PFX P 0 pre3 [叩辿坦炭]
+PFX P 0 pre4 [^坦]
+PFX P 0 pre5 [^叩辿坦炭]
+PFX P 0 pre6 坦
+PFX P 0 pre7 坦[叩辿炭]
+PFX P 0 pre8 坦[^]
+PFX P 0 pre9 坦[^叩辿坦炭]
+PFX P 0 pre10 [叩辿坦炭]
+PFX P 0 pre11 [^坦]
+PFX P 0 pre12 [^叩辿坦炭]
+PFX P 0 pre13 [叩辿坦炭][叩辿炭]
+PFX P 0 pre14 [叩辿坦炭][^叩辿坦炭]
+PFX P 0 pre15 [叩辿坦炭][^叩辿炭]
+PFX P 0 pre16 [^叩辿炭][^叩辿坦炭]
+PFX P 0 pre17 [bcdfgkmn坦prstvz][叩辿坦炭]
+PFX P 0 pre18 坦[叩辿坦炭]
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/condition-utf.dic b/extensions/spellcheck/hunspell/tests/unit/data/condition-utf.dic
new file mode 100644
index 0000000000..f03ce4ea2c
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/condition-utf.dic
@@ -0,0 +1,2 @@
+1
+坦坦/SP
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/condition-utf.good b/extensions/spellcheck/hunspell/tests/unit/data/condition-utf.good
new file mode 100644
index 0000000000..6c6203737a
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/condition-utf.good
@@ -0,0 +1,19 @@
+坦坦
+坦坦suf1
+pre1坦坦
+坦坦suf2
+pre2坦坦
+坦坦suf3
+pre3坦坦
+坦坦suf6
+pre6坦坦
+坦坦suf7
+pre7坦坦
+坦坦suf10
+pre10坦坦
+坦坦suf13
+pre13坦坦
+坦坦suf14
+pre14坦坦
+坦坦suf16
+pre16坦坦
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/condition-utf.test b/extensions/spellcheck/hunspell/tests/unit/data/condition-utf.test
new file mode 100644
index 0000000000..cde7c54109
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/condition-utf.test
@@ -0,0 +1,4 @@
+#!/bin/sh
+DIR="`dirname $0`"
+NAME="`basename $0 .test`"
+$DIR/test.sh $NAME -i utf-8
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/condition-utf.wrong b/extensions/spellcheck/hunspell/tests/unit/data/condition-utf.wrong
new file mode 100644
index 0000000000..f1022132ce
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/condition-utf.wrong
@@ -0,0 +1,18 @@
+坦坦suf4
+pre4坦坦
+坦坦suf5
+pre5坦坦
+坦坦suf8
+pre8坦坦
+坦坦suf9
+pre9坦坦
+坦坦suf11
+pre11坦坦
+坦坦suf12
+pre12坦坦
+坦坦suf15
+pre15坦坦
+坦坦suf17
+坦坦suf18
+pre17坦坦
+pre18坦坦
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/condition.aff b/extensions/spellcheck/hunspell/tests/unit/data/condition.aff
new file mode 100644
index 0000000000..62157421ab
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/condition.aff
@@ -0,0 +1,62 @@
+SET ISO8859-2
+WORDCHARS 0123456789
+
+SFX S N 18
+SFX S 0 suf1 .
+SFX S 0 suf2 o
+SFX S 0 suf3 [aeou]
+SFX S 0 suf4 [^o]
+SFX S 0 suf5 [^aeou]
+SFX S 0 suf6 fo
+SFX S 0 suf7 f[aeou]
+SFX S 0 suf8 f[^o]
+SFX S 0 suf9 f[^aeou]
+SFX S 0 suf10 [aefu]o
+SFX S 0 suf11 [^f]o
+SFX S 0 suf12 [^aefu]o
+SFX S 0 suf13 [aefu][^aefu]
+SFX S 0 suf14 [^aeou][aeou]
+SFX S 0 suf15 [aeou][^aefu]
+SFX S 0 suf16 [^aeou][^aefu]
+SFX S 0 suf17 [aeou][bcdfgkmnoprstvz]
+SFX S 0 suf18 [aeou]o
+
+SFX Q N 2
+SFX Q 0 ning [^aeio][aeiou]n
+SFX Q 0 ing [aeio][aeiou][bcdfgkmnprstvz]
+
+SFX T N 1
+SFX T y ies .[^aeiou]y
+
+PFX U N 1
+PFX U 0 un wr.
+
+SFX Z Y 3
+SFX Z 0 ch [瘟逑璧].a
+SFX Z 0 m [瘟逑璧].a
+SFX Z a 0 [瘟逑瓔].a
+
+PFX P N 18
+PFX P 0 pre1 .
+PFX P 0 pre2 o
+PFX P 0 pre3 [aeou]
+PFX P 0 pre4 [^o]
+PFX P 0 pre5 [^aeou]
+PFX P 0 pre6 of
+PFX P 0 pre7 o[aefou]
+PFX P 0 pre8 o[^f]
+PFX P 0 pre9 o[^aefu]
+PFX P 0 pre10 [aefu]o
+PFX P 0 pre11 [^f]o
+PFX P 0 pre12 [^aefou]o
+PFX P 0 pre13 [aeou][aefu]
+PFX P 0 pre14 [aeou][^aeou]
+PFX P 0 pre15 [aeou][^aefu]
+PFX P 0 pre16 [^aefu][^aeou]
+PFX P 0 pre17 [bcdfgkmnoprstvz][aeou]
+PFX P 0 pre18 o[aeou]
+
+
+PFX R N 2
+PFX R 0 gnin n[aeiou][^aeio]
+PFX R 0 gni [bcdfgkmnprstvz][aeiou][aeio]
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/condition.dic b/extensions/spellcheck/hunspell/tests/unit/data/condition.dic
new file mode 100644
index 0000000000..40ebd55880
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/condition.dic
@@ -0,0 +1,6 @@
+5
+ofo/SP
+entertain/Q
+nianretne/R
+ra/Z
+wry/TU
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/condition.good b/extensions/spellcheck/hunspell/tests/unit/data/condition.good
new file mode 100644
index 0000000000..8fef4a7477
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/condition.good
@@ -0,0 +1,26 @@
+ofo
+ofosuf1
+pre1ofo
+ofosuf2
+pre2ofo
+ofosuf3
+pre3ofo
+ofosuf6
+pre6ofo
+ofosuf7
+pre7ofo
+ofosuf10
+ofosuf13
+pre13ofo
+ofosuf14
+pre14ofo
+ofosuf16
+pre16ofo
+entertain
+entertaining
+gninianretne
+r
+ram
+rach
+wries
+unwry
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/condition.test b/extensions/spellcheck/hunspell/tests/unit/data/condition.test
new file mode 100644
index 0000000000..c95329532a
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/condition.test
@@ -0,0 +1,4 @@
+#!/bin/sh
+DIR="`dirname $0`"
+NAME="`basename $0 .test`"
+$DIR/test.sh $NAME -i ISO8859-2
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/condition.wrong b/extensions/spellcheck/hunspell/tests/unit/data/condition.wrong
new file mode 100644
index 0000000000..7b83d828d0
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/condition.wrong
@@ -0,0 +1,21 @@
+ofosuf4
+pre4ofo
+ofosuf5
+pre5ofo
+ofosuf8
+pre8ofo
+ofosuf9
+pre9ofo
+ofosuf11
+pre10ofo
+pre11ofo
+ofosuf12
+pre12ofo
+ofosuf15
+pre15ofo
+ofosuf17
+pre17ofo
+ofosuf18
+pre18ofo
+entertainning
+gninnianretne
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/conditionalprefix.aff b/extensions/spellcheck/hunspell/tests/unit/data/conditionalprefix.aff
new file mode 100644
index 0000000000..e7a9bf749e
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/conditionalprefix.aff
@@ -0,0 +1,11 @@
+PFX P Y 1
+PFX P 0 un . ip:un
+
+SFX S Y 1
+SFX S 0 s . is:PL
+
+SFX Q Y 1
+SFX Q 0 s . is:3SGV
+
+SFX R Y 1
+SFX R 0 able/PS . ds:DER_V_ADJ_ABLE
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/conditionalprefix.dic b/extensions/spellcheck/hunspell/tests/unit/data/conditionalprefix.dic
new file mode 100644
index 0000000000..2f6d456152
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/conditionalprefix.dic
@@ -0,0 +1,3 @@
+2
+drink/RQ po:verb
+drink/S po:noun
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/conditionalprefix.good b/extensions/spellcheck/hunspell/tests/unit/data/conditionalprefix.good
new file mode 100644
index 0000000000..01438d0ebf
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/conditionalprefix.good
@@ -0,0 +1,6 @@
+drink
+drinks
+drinkable
+drinkables
+undrinkable
+undrinkables
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/conditionalprefix.morph b/extensions/spellcheck/hunspell/tests/unit/data/conditionalprefix.morph
new file mode 100644
index 0000000000..95d5443894
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/conditionalprefix.morph
@@ -0,0 +1,20 @@
+> drink
+analyze(drink) = st:drink po:verb
+analyze(drink) = st:drink po:noun
+stem(drink) = drink
+> drinks
+analyze(drinks) = st:drink po:verb is:3SGV
+analyze(drinks) = st:drink po:noun is:PL
+stem(drinks) = drink
+> drinkable
+analyze(drinkable) = st:drink po:verb ds:DER_V_ADJ_ABLE
+stem(drinkable) = drinkable
+> drinkables
+analyze(drinkables) = st:drink po:verb ds:DER_V_ADJ_ABLE is:PL
+stem(drinkables) = drinkable
+> undrinkable
+analyze(undrinkable) = ip:un st:drink po:verb ds:DER_V_ADJ_ABLE
+stem(undrinkable) = drinkable
+> undrinkables
+analyze(undrinkables) = ip:un st:drink po:verb ds:DER_V_ADJ_ABLE is:PL
+stem(undrinkables) = drinkable
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/conditionalprefix.test b/extensions/spellcheck/hunspell/tests/unit/data/conditionalprefix.test
new file mode 100644
index 0000000000..7f44369060
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/conditionalprefix.test
@@ -0,0 +1,4 @@
+#!/bin/sh
+DIR="`dirname $0`"
+NAME="`basename $0 .test`"
+$DIR/test.sh $NAME
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/conditionalprefix.wrong b/extensions/spellcheck/hunspell/tests/unit/data/conditionalprefix.wrong
new file mode 100644
index 0000000000..70262d9400
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/conditionalprefix.wrong
@@ -0,0 +1,2 @@
+undrink
+undrinks
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/digits-in-words.aff b/extensions/spellcheck/hunspell/tests/unit/data/digits-in-words.aff
new file mode 100644
index 0000000000..18a42f6fd9
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/digits-in-words.aff
@@ -0,0 +1,9 @@
+# Digits in words, handled by COMPOUNDRULE.
+# 1-j辰hrig, 2-j辰hrig, 100-j辰hrig etc.
+SET UTF-8
+COMPOUNDMIN 1
+# recognize ab, aab, aaab etc. compounds (a=digits, b=-j辰hrig, see dic file)
+COMPOUNDRULE 1
+COMPOUNDRULE a*b
+ONLYINCOMPOUND c
+WORDCHARS 0123456789-
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/digits-in-words.dic b/extensions/spellcheck/hunspell/tests/unit/data/digits-in-words.dic
new file mode 100644
index 0000000000..deeaece05d
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/digits-in-words.dic
@@ -0,0 +1,12 @@
+11
+0/a
+1/a
+2/a
+3/a
+4/a
+5/a
+6/a
+7/a
+8/a
+9/a
+-j辰hrig/bc
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/digits-in-words.test b/extensions/spellcheck/hunspell/tests/unit/data/digits-in-words.test
new file mode 100644
index 0000000000..cde7c54109
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/digits-in-words.test
@@ -0,0 +1,4 @@
+#!/bin/sh
+DIR="`dirname $0`"
+NAME="`basename $0 .test`"
+$DIR/test.sh $NAME -i utf-8
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/digits-in-words.wrong b/extensions/spellcheck/hunspell/tests/unit/data/digits-in-words.wrong
new file mode 100644
index 0000000000..aeaf6ce344
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/digits-in-words.wrong
@@ -0,0 +1 @@
+-j辰hrig
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/encoding.aff b/extensions/spellcheck/hunspell/tests/unit/data/encoding.aff
new file mode 100644
index 0000000000..1f560d262e
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/encoding.aff
@@ -0,0 +1 @@
+SET ISO-8859-15
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/encoding.dic b/extensions/spellcheck/hunspell/tests/unit/data/encoding.dic
new file mode 100644
index 0000000000..414f9b8d3e
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/encoding.dic
@@ -0,0 +1,3 @@
+2
+cur
+uvre
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/encoding.good b/extensions/spellcheck/hunspell/tests/unit/data/encoding.good
new file mode 100644
index 0000000000..fc41c90aac
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/encoding.good
@@ -0,0 +1,4 @@
+cur
+uvre
+CUR
+UVRE
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/encoding.test b/extensions/spellcheck/hunspell/tests/unit/data/encoding.test
new file mode 100644
index 0000000000..09619572e9
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/encoding.test
@@ -0,0 +1,4 @@
+#!/bin/sh
+DIR="`dirname $0`"
+NAME="`basename $0 .test`"
+$DIR/test.sh $NAME -i ISO8859-15
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/flag.aff b/extensions/spellcheck/hunspell/tests/unit/data/flag.aff
new file mode 100644
index 0000000000..ac105c11fb
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/flag.aff
@@ -0,0 +1,13 @@
+# base 1-character flags
+
+SFX A Y 1
+SFX A 0 s/123 .
+
+SFX 1 Y 1
+SFX 1 0 bar .
+
+SFX 2 Y 1
+SFX 2 0 baz .
+
+PFX 3 Y 1
+PFX 3 0 un .
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/flag.dic b/extensions/spellcheck/hunspell/tests/unit/data/flag.dic
new file mode 100644
index 0000000000..b1b237106f
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/flag.dic
@@ -0,0 +1,2 @@
+1
+foo/A3
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/flag.good b/extensions/spellcheck/hunspell/tests/unit/data/flag.good
new file mode 100644
index 0000000000..d5c27b1a67
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/flag.good
@@ -0,0 +1,8 @@
+foo
+foos
+foosbar
+foosbaz
+unfoo
+unfoos
+unfoosbar
+unfoosbaz
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/flag.test b/extensions/spellcheck/hunspell/tests/unit/data/flag.test
new file mode 100644
index 0000000000..7f44369060
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/flag.test
@@ -0,0 +1,4 @@
+#!/bin/sh
+DIR="`dirname $0`"
+NAME="`basename $0 .test`"
+$DIR/test.sh $NAME
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/flaglong.aff b/extensions/spellcheck/hunspell/tests/unit/data/flaglong.aff
new file mode 100644
index 0000000000..437f13b3ac
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/flaglong.aff
@@ -0,0 +1,14 @@
+# 2-character flags
+FLAG long
+
+SFX zx Y 1
+SFX zx 0 s/g?1G09 .
+
+SFX g? Y 1
+SFX g? 0 bar .
+
+SFX 1G Y 1
+SFX 1G 0 baz .
+
+PFX 09 Y 1
+PFX 09 0 un .
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/flaglong.dic b/extensions/spellcheck/hunspell/tests/unit/data/flaglong.dic
new file mode 100644
index 0000000000..46c6012860
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/flaglong.dic
@@ -0,0 +1,2 @@
+1
+foo/zx09
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/flaglong.good b/extensions/spellcheck/hunspell/tests/unit/data/flaglong.good
new file mode 100644
index 0000000000..d5c27b1a67
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/flaglong.good
@@ -0,0 +1,8 @@
+foo
+foos
+foosbar
+foosbaz
+unfoo
+unfoos
+unfoosbar
+unfoosbaz
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/flaglong.test b/extensions/spellcheck/hunspell/tests/unit/data/flaglong.test
new file mode 100644
index 0000000000..7f44369060
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/flaglong.test
@@ -0,0 +1,4 @@
+#!/bin/sh
+DIR="`dirname $0`"
+NAME="`basename $0 .test`"
+$DIR/test.sh $NAME
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/flagnum.aff b/extensions/spellcheck/hunspell/tests/unit/data/flagnum.aff
new file mode 100644
index 0000000000..823cee4cda
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/flagnum.aff
@@ -0,0 +1,14 @@
+# numerical flags
+FLAG num
+
+SFX 999 Y 1
+SFX 999 0 s/214,216,54321 .
+
+SFX 214 Y 1
+SFX 214 0 bar .
+
+SFX 216 Y 1
+SFX 216 0 baz .
+
+PFX 54321 Y 1
+PFX 54321 0 un .
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/flagnum.dic b/extensions/spellcheck/hunspell/tests/unit/data/flagnum.dic
new file mode 100644
index 0000000000..927c45f2fd
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/flagnum.dic
@@ -0,0 +1,2 @@
+1
+foo/999,54321
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/flagnum.good b/extensions/spellcheck/hunspell/tests/unit/data/flagnum.good
new file mode 100644
index 0000000000..d5c27b1a67
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/flagnum.good
@@ -0,0 +1,8 @@
+foo
+foos
+foosbar
+foosbaz
+unfoo
+unfoos
+unfoosbar
+unfoosbaz
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/flagnum.test b/extensions/spellcheck/hunspell/tests/unit/data/flagnum.test
new file mode 100644
index 0000000000..7f44369060
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/flagnum.test
@@ -0,0 +1,4 @@
+#!/bin/sh
+DIR="`dirname $0`"
+NAME="`basename $0 .test`"
+$DIR/test.sh $NAME
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/flagutf8.aff b/extensions/spellcheck/hunspell/tests/unit/data/flagutf8.aff
new file mode 100644
index 0000000000..d0f75c1858
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/flagutf8.aff
@@ -0,0 +1,15 @@
+# UTF-8 flags
+FLAG UTF-8
+
+SFX A Y 1
+SFX A 0 s/端 .
+#SFX A 0 s/端 .
+
+SFX Y 1
+SFX 0 bar .
+
+SFX 端 Y 1
+SFX 端 0 baz .
+
+PFX Y 1
+PFX 0 un .
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/flagutf8.dic b/extensions/spellcheck/hunspell/tests/unit/data/flagutf8.dic
new file mode 100644
index 0000000000..2944490c90
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/flagutf8.dic
@@ -0,0 +1,2 @@
+1
+foo/A
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/flagutf8.good b/extensions/spellcheck/hunspell/tests/unit/data/flagutf8.good
new file mode 100644
index 0000000000..d5c27b1a67
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/flagutf8.good
@@ -0,0 +1,8 @@
+foo
+foos
+foosbar
+foosbaz
+unfoo
+unfoos
+unfoosbar
+unfoosbaz
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/flagutf8.test b/extensions/spellcheck/hunspell/tests/unit/data/flagutf8.test
new file mode 100644
index 0000000000..cde7c54109
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/flagutf8.test
@@ -0,0 +1,4 @@
+#!/bin/sh
+DIR="`dirname $0`"
+NAME="`basename $0 .test`"
+$DIR/test.sh $NAME -i utf-8
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/fogemorpheme.aff b/extensions/spellcheck/hunspell/tests/unit/data/fogemorpheme.aff
new file mode 100644
index 0000000000..56cdabe5a3
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/fogemorpheme.aff
@@ -0,0 +1,12 @@
+# fogemorphemes: special morphemes in compounds
+#
+# Swedish example:
+# gata + kontoret = gatukontoret
+
+COMPOUNDFLAG X
+COMPOUNDBEGIN Y
+ONLYINCOMPOUND Z
+COMPOUNDPERMITFLAG P
+
+SFX A Y 1
+SFX A a u/YPZ .
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/fogemorpheme.dic b/extensions/spellcheck/hunspell/tests/unit/data/fogemorpheme.dic
new file mode 100644
index 0000000000..1b76380d1b
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/fogemorpheme.dic
@@ -0,0 +1,3 @@
+2
+gata/A
+kontoret/X
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/fogemorpheme.good b/extensions/spellcheck/hunspell/tests/unit/data/fogemorpheme.good
new file mode 100644
index 0000000000..01e77d561d
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/fogemorpheme.good
@@ -0,0 +1,3 @@
+gata
+kontoret
+gatukontoret
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/fogemorpheme.test b/extensions/spellcheck/hunspell/tests/unit/data/fogemorpheme.test
new file mode 100644
index 0000000000..7f44369060
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/fogemorpheme.test
@@ -0,0 +1,4 @@
+#!/bin/sh
+DIR="`dirname $0`"
+NAME="`basename $0 .test`"
+$DIR/test.sh $NAME
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/fogemorpheme.wrong b/extensions/spellcheck/hunspell/tests/unit/data/fogemorpheme.wrong
new file mode 100644
index 0000000000..f920745c79
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/fogemorpheme.wrong
@@ -0,0 +1,3 @@
+gatu
+gatakontoret
+kontoretgatu
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/forbiddenword.aff b/extensions/spellcheck/hunspell/tests/unit/data/forbiddenword.aff
new file mode 100644
index 0000000000..de7f8ad9a4
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/forbiddenword.aff
@@ -0,0 +1,11 @@
+# FORBIDDENWORD flag
+# The signed word, and its suffixed forms are all forbidden,
+# excepts with root homonyms.
+# Useful for forbidding bad suffixed forms or compounds.
+
+
+FORBIDDENWORD X
+COMPOUNDFLAG Y
+
+SFX A Y 1
+SFX A 0 s .
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/forbiddenword.dic b/extensions/spellcheck/hunspell/tests/unit/data/forbiddenword.dic
new file mode 100644
index 0000000000..78f2ee3d15
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/forbiddenword.dic
@@ -0,0 +1,8 @@
+5
+foo/S [1]
+foo/YX [2]
+foo/Y [3]
+foo/S [4]
+bar/YS [5]
+bars/X
+foos/X
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/forbiddenword.good b/extensions/spellcheck/hunspell/tests/unit/data/forbiddenword.good
new file mode 100644
index 0000000000..7bd112e9ea
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/forbiddenword.good
@@ -0,0 +1,3 @@
+foo
+bar
+
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/forbiddenword.test b/extensions/spellcheck/hunspell/tests/unit/data/forbiddenword.test
new file mode 100644
index 0000000000..7f44369060
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/forbiddenword.test
@@ -0,0 +1,4 @@
+#!/bin/sh
+DIR="`dirname $0`"
+NAME="`basename $0 .test`"
+$DIR/test.sh $NAME
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/forbiddenword.wrong b/extensions/spellcheck/hunspell/tests/unit/data/forbiddenword.wrong
new file mode 100644
index 0000000000..5752c1e446
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/forbiddenword.wrong
@@ -0,0 +1,4 @@
+bars
+foos
+foobar
+barfoo
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/forceucase.aff b/extensions/spellcheck/hunspell/tests/unit/data/forceucase.aff
new file mode 100644
index 0000000000..5eebcbdab7
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/forceucase.aff
@@ -0,0 +1,4 @@
+# force capitalized compound
+TRY F
+FORCEUCASE A
+COMPOUNDFLAG C
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/forceucase.dic b/extensions/spellcheck/hunspell/tests/unit/data/forceucase.dic
new file mode 100644
index 0000000000..82fd93b309
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/forceucase.dic
@@ -0,0 +1,4 @@
+3
+foo/C
+bar/C
+baz/CA
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/forceucase.good b/extensions/spellcheck/hunspell/tests/unit/data/forceucase.good
new file mode 100644
index 0000000000..37ecf49573
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/forceucase.good
@@ -0,0 +1,7 @@
+foo
+bar
+baz
+foobar
+Foobaz
+foobazbar
+Foobarbaz
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/forceucase.sug b/extensions/spellcheck/hunspell/tests/unit/data/forceucase.sug
new file mode 100644
index 0000000000..6a77cbd06d
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/forceucase.sug
@@ -0,0 +1,2 @@
+Foobaz
+Foobarbaz
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/forceucase.test b/extensions/spellcheck/hunspell/tests/unit/data/forceucase.test
new file mode 100644
index 0000000000..7f44369060
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/forceucase.test
@@ -0,0 +1,4 @@
+#!/bin/sh
+DIR="`dirname $0`"
+NAME="`basename $0 .test`"
+$DIR/test.sh $NAME
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/forceucase.wrong b/extensions/spellcheck/hunspell/tests/unit/data/forceucase.wrong
new file mode 100644
index 0000000000..1503e42ddc
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/forceucase.wrong
@@ -0,0 +1,2 @@
+foobaz
+foobarbaz
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/fullstrip.aff b/extensions/spellcheck/hunspell/tests/unit/data/fullstrip.aff
new file mode 100644
index 0000000000..d60cb74d7c
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/fullstrip.aff
@@ -0,0 +1,15 @@
+# FULLSTRIP option: Hunspell can strip full words by affix rules
+# see OpenOffice.org Issue #80145
+# test data from Davide Prina
+
+FULLSTRIP
+
+SET ISO8859-15
+TRY aioertnsclmdpgubzfvhq'ACMSkBGPLxEyRTV嘆IODNwF辿湛竪狸jUZKHWJYQX
+
+SFX A Y 3 # verbo andare (verb to go)
+SFX A andare vado andare # io vado (I go)
+SFX A andare va andare # tu vai (you go)
+SFX A are iamo andare # noi andiamo (we go)
+
+
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/fullstrip.dic b/extensions/spellcheck/hunspell/tests/unit/data/fullstrip.dic
new file mode 100644
index 0000000000..553113d442
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/fullstrip.dic
@@ -0,0 +1,4 @@
+2
+andare/A
+riandare/A
+
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/fullstrip.good b/extensions/spellcheck/hunspell/tests/unit/data/fullstrip.good
new file mode 100644
index 0000000000..1240e71f53
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/fullstrip.good
@@ -0,0 +1,9 @@
+andare
+vado
+va
+andiamo
+riandare
+rivado
+riva
+riandiamo
+
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/fullstrip.test b/extensions/spellcheck/hunspell/tests/unit/data/fullstrip.test
new file mode 100644
index 0000000000..4d59c42126
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/fullstrip.test
@@ -0,0 +1,4 @@
+#!/bin/sh
+DIR="`dirname $0`"
+NAME="`basename $0 .test`"
+$DIR/test.sh $NAME -i UTF-8
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/germancompounding.aff b/extensions/spellcheck/hunspell/tests/unit/data/germancompounding.aff
new file mode 100644
index 0000000000..5ff25872ce
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/germancompounding.aff
@@ -0,0 +1,91 @@
+# German compounding
+
+# handle special casing of German sharp s
+
+CHECKSHARPS
+
+# compound flags
+
+COMPOUNDBEGIN U
+COMPOUNDMIDDLE V
+COMPOUNDEND W
+
+# Prefixes are allowed at the beginning of compounds,
+# suffixes are allowed at the end of compounds by default:
+# (prefix)?(root)+(affix)?
+# Affixes with COMPOUNDPERMITFLAG may be inside of compounds.
+COMPOUNDPERMITFLAG P
+
+# for German fogemorphemes (Fuge-element)
+# Hint: ONLYINCOMPOUND is not required everywhere, but the
+# checking will be a little faster with it.
+
+ONLYINCOMPOUND X
+
+# forbid uppercase characters at compound word bounds
+CHECKCOMPOUNDCASE
+
+# for handling Fuge-elements with dashes (Arbeits-)
+# dash will be a special word
+
+COMPOUNDMIN 1
+WORDCHARS -
+
+# compound settings and fogemorpheme for `Arbeit'
+
+SFX A Y 3
+SFX A 0 s/UPX .
+SFX A 0 s/VPDX .
+SFX A 0 0/WXD .
+
+SFX B Y 2
+SFX B 0 0/UPX .
+SFX B 0 0/VWXDP .
+
+# a suffix for `Computer'
+
+SFX C Y 1
+SFX C 0 n/WD .
+
+# for forbid exceptions (*Arbeitsnehmer)
+
+FORBIDDENWORD Z
+
+# dash prefix for compounds with dash (Arbeits-Computer)
+
+PFX - Y 1
+PFX - 0 -/P .
+
+# decapitalizing prefix
+# circumfix for positioning in compounds
+
+PFX D Y 29
+PFX D A a/PX A
+PFX D /PX
+PFX D B b/PX B
+PFX D C c/PX C
+PFX D D d/PX D
+PFX D E e/PX E
+PFX D F f/PX F
+PFX D G g/PX G
+PFX D H h/PX H
+PFX D I i/PX I
+PFX D J j/PX J
+PFX D K k/PX K
+PFX D L l/PX L
+PFX D M m/PX M
+PFX D N n/PX N
+PFX D O o/PX O
+PFX D /PX
+PFX D P p/PX P
+PFX D Q q/PX Q
+PFX D R r/PX R
+PFX D S s/PX S
+PFX D T t/PX T
+PFX D U u/PX U
+PFX D /PX
+PFX D V v/PX V
+PFX D W w/PX W
+PFX D X x/PX X
+PFX D Y y/PX Y
+PFX D Z z/PX Z
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/germancompounding.dic b/extensions/spellcheck/hunspell/tests/unit/data/germancompounding.dic
new file mode 100644
index 0000000000..5db6783a4d
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/germancompounding.dic
@@ -0,0 +1,5 @@
+4
+Arbeit/A-
+Computer/BC-
+-/W
+Arbeitsnehmer/Z
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/germancompounding.good b/extensions/spellcheck/hunspell/tests/unit/data/germancompounding.good
new file mode 100644
index 0000000000..e4945553c5
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/germancompounding.good
@@ -0,0 +1,20 @@
+Computer
+Computern
+Arbeit
+Arbeits-
+Computerarbeit
+Computerarbeits-
+Arbeitscomputer
+Computercomputer
+Computercomputern
+Arbeitscomputern
+Computerarbeitscomputer
+Computerarbeitscomputern
+Arbeitscomputercomputer
+Computercomputerarbeit
+Arbeitscomputerarbeit
+Arbeitsarbeitsarbeit
+Computerarbeitsarbeit
+Computerarbeits-Computer
+Computerarbeits-Computern
+Computer-Arbeit
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/germancompounding.test b/extensions/spellcheck/hunspell/tests/unit/data/germancompounding.test
new file mode 100644
index 0000000000..dc295077fb
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/germancompounding.test
@@ -0,0 +1,4 @@
+#!/bin/sh
+DIR="`dirname $0`"
+NAME="`basename $0 .test`"
+$DIR/test.sh $NAME -i ISO8859-1
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/germancompounding.wrong b/extensions/spellcheck/hunspell/tests/unit/data/germancompounding.wrong
new file mode 100644
index 0000000000..c5f2ba1151
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/germancompounding.wrong
@@ -0,0 +1,50 @@
+computer
+computern
+arbeit
+Arbeits
+arbeits
+ComputerArbeit
+ComputernArbeit
+Computernarbeit
+ComputerArbeits
+Arbeitcomputer
+Arbeitcomputern
+ArbeitsComputer
+ArbeitsComputern
+Computerarbeitcomputer
+ComputerArbeitcomputer
+ComputerArbeitscomputer
+Computerarbeitcomputern
+ComputerArbeitcomputern
+ComputerArbeitscomputern
+Arbeitscomputerarbeits
+Arbeitscomputernarbeits
+Computerarbeits-computer
+Arbeitsnehmer
+computers
+computern
+computernarbeit
+computernArbeit
+computerArbeit
+computerArbeits
+arbeitcomputer
+arbeitsComputer
+computerarbeitcomputer
+computerArbeitcomputer
+computerArbeitscomputer
+arbeitscomputerarbeits
+computerarbeits-computer
+arbeitsnehmer
+computernarbeit
+computernArbeit
+arbeits-
+computerarbeit
+computerarbeits-
+arbeitscomputer
+arbeitscomputern
+computerarbeitscomputer
+computerarbeitscomputern
+computerarbeitscomputers
+arbeitscomputerarbeit
+computerarbeits-Computer
+computerarbeits-Computern
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/germancompoundingold.aff b/extensions/spellcheck/hunspell/tests/unit/data/germancompoundingold.aff
new file mode 100644
index 0000000000..3e06f0647e
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/germancompoundingold.aff
@@ -0,0 +1,96 @@
+# German compounding
+
+# handle special casing of German sharp s
+
+CHECKSHARPS
+
+# compound flags
+
+COMPOUNDBEGIN U
+COMPOUNDMIDDLE V
+COMPOUNDEND W
+
+# Prefixes are allowed at the beginning of compounds,
+# suffixes are allowed at the end of compounds by default:
+# (prefix)?(root)+(affix)?
+# Affixes with COMPOUNDPERMITFLAG may be inside of compounds.
+COMPOUNDPERMITFLAG P
+
+# for German fogemorphemes (Fuge-element)
+# Hint: ONLYINCOMPOUND is not required everywhere, but the
+# checking will be a little faster with it.
+
+ONLYINCOMPOUND X
+
+# for decapitalizing nouns with fogemorphemes
+
+CIRCUMFIX Y
+
+# for handling Fuge-elements with dashes (Arbeits-)
+# dash will be a special word
+
+COMPOUNDMIN 1
+WORDCHARS -
+
+# compound settings and fogemorpheme for `Arbeit'
+
+SFX A Y 3
+SFX A 0 s/UPX .
+SFX A 0 s/VPXDY .
+SFX A 0 0/WXDY .
+
+# compound settings for `Computer'
+
+SFX B Y 2
+SFX B 0 0/UPX .
+SFX B 0 0/VWPXDY .
+
+# a suffix for `Computer'
+
+SFX C Y 2
+SFX C 0 n .
+SFX C 0 n/WXDY .
+
+# for forbid exceptions (*Arbeitsnehmer)
+
+FORBIDDENWORD Z
+
+# dash prefix for compounds with dash (Arbeits-Computer)
+
+PFX - Y 2
+PFX - 0 -/PUVW .
+PFX - 0 -/PY .
+
+# decapitalizing prefix
+# circumfix for positioning in compounds
+
+PFX D Y 29
+PFX D A a/PXY A
+PFX D /PXY
+PFX D B b/PXY B
+PFX D C c/PXY C
+PFX D D d/PXY D
+PFX D E e/PXY E
+PFX D F f/PXY F
+PFX D G g/PXY G
+PFX D H h/PXY H
+PFX D I i/PXY I
+PFX D J j/PXY J
+PFX D K k/PXY K
+PFX D L l/PXY L
+PFX D M m/PXY M
+PFX D N n/PXY N
+PFX D O o/PXY O
+PFX D /PXY
+PFX D P p/PXY P
+PFX D Q q/PXY Q
+PFX D R r/PXY R
+PFX D S s/PXY S
+PFX D T t/PXY T
+PFX D U u/PXY U
+PFX D /PXY
+PFX D V v/PXY V
+PFX D W w/PXY W
+PFX D X x/PXY X
+PFX D Y y/PXY Y
+PFX D Z z/PXY Z
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/germancompoundingold.dic b/extensions/spellcheck/hunspell/tests/unit/data/germancompoundingold.dic
new file mode 100644
index 0000000000..5db6783a4d
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/germancompoundingold.dic
@@ -0,0 +1,5 @@
+4
+Arbeit/A-
+Computer/BC-
+-/W
+Arbeitsnehmer/Z
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/germancompoundingold.good b/extensions/spellcheck/hunspell/tests/unit/data/germancompoundingold.good
new file mode 100644
index 0000000000..5357bff165
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/germancompoundingold.good
@@ -0,0 +1,14 @@
+Computer
+Computern
+Arbeit
+Arbeits-
+Computerarbeit
+Computerarbeits-
+Arbeitscomputer
+Arbeitscomputern
+Computerarbeitscomputer
+Computerarbeitscomputern
+Arbeitscomputerarbeit
+Computerarbeits-Computer
+Computerarbeits-Computern
+Computer-Arbeit
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/germancompoundingold.test b/extensions/spellcheck/hunspell/tests/unit/data/germancompoundingold.test
new file mode 100644
index 0000000000..7f44369060
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/germancompoundingold.test
@@ -0,0 +1,4 @@
+#!/bin/sh
+DIR="`dirname $0`"
+NAME="`basename $0 .test`"
+$DIR/test.sh $NAME
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/germancompoundingold.wrong b/extensions/spellcheck/hunspell/tests/unit/data/germancompoundingold.wrong
new file mode 100644
index 0000000000..c5f2ba1151
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/germancompoundingold.wrong
@@ -0,0 +1,50 @@
+computer
+computern
+arbeit
+Arbeits
+arbeits
+ComputerArbeit
+ComputernArbeit
+Computernarbeit
+ComputerArbeits
+Arbeitcomputer
+Arbeitcomputern
+ArbeitsComputer
+ArbeitsComputern
+Computerarbeitcomputer
+ComputerArbeitcomputer
+ComputerArbeitscomputer
+Computerarbeitcomputern
+ComputerArbeitcomputern
+ComputerArbeitscomputern
+Arbeitscomputerarbeits
+Arbeitscomputernarbeits
+Computerarbeits-computer
+Arbeitsnehmer
+computers
+computern
+computernarbeit
+computernArbeit
+computerArbeit
+computerArbeits
+arbeitcomputer
+arbeitsComputer
+computerarbeitcomputer
+computerArbeitcomputer
+computerArbeitscomputer
+arbeitscomputerarbeits
+computerarbeits-computer
+arbeitsnehmer
+computernarbeit
+computernArbeit
+arbeits-
+computerarbeit
+computerarbeits-
+arbeitscomputer
+arbeitscomputern
+computerarbeitscomputer
+computerarbeitscomputern
+computerarbeitscomputers
+arbeitscomputerarbeit
+computerarbeits-Computer
+computerarbeits-Computern
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/i35725.aff b/extensions/spellcheck/hunspell/tests/unit/data/i35725.aff
new file mode 100644
index 0000000000..96755c7ecd
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/i35725.aff
@@ -0,0 +1,203 @@
+# Ngram suggestions
+# - fix case problem
+# - detect character swapping (keep only these suggestions)
+# - lesser suggestions
+# - weight with common subsequence algorithm
+# - suggest uppercased words
+
+# 2007-02-05:
+# now not neighbour character replacements and character movings are
+# detected by not ngram suggestions, too.
+
+# OpenOffice.org's en_US.aff file
+
+SET ISO8859-1
+TRY esianrtolcdugmphbyfvkwzESIANRTOLCDUGMPHBYFVKWZ'
+
+WORDCHARS '
+
+PFX A Y 1
+PFX A 0 re .
+
+PFX I Y 1
+PFX I 0 in .
+
+PFX U Y 1
+PFX U 0 un .
+
+PFX C Y 1
+PFX C 0 de .
+
+PFX E Y 1
+PFX E 0 dis .
+
+PFX F Y 1
+PFX F 0 con .
+
+PFX K Y 1
+PFX K 0 pro .
+
+SFX V N 2
+SFX V e ive e
+SFX V 0 ive [^e]
+
+SFX N Y 3
+SFX N e ion e
+SFX N y ication y
+SFX N 0 en [^ey]
+
+SFX X Y 3
+SFX X e ions e
+SFX X y ications y
+SFX X 0 ens [^ey]
+
+SFX H N 2
+SFX H y ieth y
+SFX H 0 th [^y]
+
+SFX Y Y 1
+SFX Y 0 ly .
+
+SFX G Y 2
+SFX G e ing e
+SFX G 0 ing [^e]
+
+SFX J Y 2
+SFX J e ings e
+SFX J 0 ings [^e]
+
+SFX D Y 4
+SFX D 0 d e
+SFX D y ied [^aeiou]y
+SFX D 0 ed [^ey]
+SFX D 0 ed [aeiou]y
+
+SFX T N 4
+SFX T 0 st e
+SFX T y iest [^aeiou]y
+SFX T 0 est [aeiou]y
+SFX T 0 est [^ey]
+
+SFX R Y 4
+SFX R 0 r e
+SFX R y ier [^aeiou]y
+SFX R 0 er [aeiou]y
+SFX R 0 er [^ey]
+
+SFX Z Y 4
+SFX Z 0 rs e
+SFX Z y iers [^aeiou]y
+SFX Z 0 ers [aeiou]y
+SFX Z 0 ers [^ey]
+
+SFX S Y 4
+SFX S y ies [^aeiou]y
+SFX S 0 s [aeiou]y
+SFX S 0 es [sxzh]
+SFX S 0 s [^sxzhy]
+
+SFX P Y 3
+SFX P y iness [^aeiou]y
+SFX P 0 ness [aeiou]y
+SFX P 0 ness [^y]
+
+SFX M Y 1
+SFX M 0 's .
+
+SFX B Y 3
+SFX B 0 able [^aeiou]
+SFX B 0 able ee
+SFX B e able [^aeiou]e
+
+SFX L Y 1
+SFX L 0 ment .
+
+REP 88
+REP a ei
+REP ei a
+REP a ey
+REP ey a
+REP ai ie
+REP ie ai
+REP are air
+REP are ear
+REP are eir
+REP air are
+REP air ere
+REP ere air
+REP ere ear
+REP ere eir
+REP ear are
+REP ear air
+REP ear ere
+REP eir are
+REP eir ere
+REP ch te
+REP te ch
+REP ch ti
+REP ti ch
+REP ch tu
+REP tu ch
+REP ch s
+REP s ch
+REP ch k
+REP k ch
+REP f ph
+REP ph f
+REP gh f
+REP f gh
+REP i igh
+REP igh i
+REP i uy
+REP uy i
+REP i ee
+REP ee i
+REP j di
+REP di j
+REP j gg
+REP gg j
+REP j ge
+REP ge j
+REP s ti
+REP ti s
+REP s ci
+REP ci s
+REP k cc
+REP cc k
+REP k qu
+REP qu k
+REP kw qu
+REP o eau
+REP eau o
+REP o ew
+REP ew o
+REP oo ew
+REP ew oo
+REP ew ui
+REP ui ew
+REP oo ui
+REP ui oo
+REP ew u
+REP u ew
+REP oo u
+REP u oo
+REP u oe
+REP oe u
+REP u ieu
+REP ieu u
+REP ue ew
+REP ew ue
+REP uff ough
+REP oo ieu
+REP ieu oo
+REP ier ear
+REP ear ier
+REP ear air
+REP air ear
+REP w qu
+REP qu w
+REP z ss
+REP ss z
+REP shun tion
+REP shun sion
+REP shun cion
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/i35725.dic b/extensions/spellcheck/hunspell/tests/unit/data/i35725.dic
new file mode 100644
index 0000000000..0c61f0031e
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/i35725.dic
@@ -0,0 +1,15 @@
+15
+endangerment/SM
+ferment/FSCM
+preferment/SM
+impermanent/Y
+permanent/YSP
+semipermanent/Y
+empowerment/MS
+supermen
+tournament/MS
+ornamental/SY
+ornament/GSDM
+supernatant
+pimpernel
+UNESCO/M
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/i35725.good b/extensions/spellcheck/hunspell/tests/unit/data/i35725.good
new file mode 100644
index 0000000000..052ba8418a
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/i35725.good
@@ -0,0 +1 @@
+permanent
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/i35725.sug b/extensions/spellcheck/hunspell/tests/unit/data/i35725.sug
new file mode 100644
index 0000000000..a8bf1d9808
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/i35725.sug
@@ -0,0 +1,10 @@
+permanent, preferment
+permanent, ornament
+permanent
+Permanent, Preferment
+Permanent, Ornament
+Permanent
+UNESCO
+UNESCO
+UNESCO's
+UNESCO's
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/i35725.test b/extensions/spellcheck/hunspell/tests/unit/data/i35725.test
new file mode 100644
index 0000000000..7f44369060
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/i35725.test
@@ -0,0 +1,4 @@
+#!/bin/sh
+DIR="`dirname $0`"
+NAME="`basename $0 .test`"
+$DIR/test.sh $NAME
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/i35725.wrong b/extensions/spellcheck/hunspell/tests/unit/data/i35725.wrong
new file mode 100644
index 0000000000..573e195d8f
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/i35725.wrong
@@ -0,0 +1,10 @@
+permenant
+pernament
+pernemant
+Permenant
+Pernament
+Pernemant
+unesco
+Unesco
+unesco's
+Unesco's
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/i53643.aff b/extensions/spellcheck/hunspell/tests/unit/data/i53643.aff
new file mode 100644
index 0000000000..9fac6d84ca
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/i53643.aff
@@ -0,0 +1,2 @@
+# check numbers with separators
+WORDCHARS 0123456789.-,
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/i53643.dic b/extensions/spellcheck/hunspell/tests/unit/data/i53643.dic
new file mode 100644
index 0000000000..aec5d506bd
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/i53643.dic
@@ -0,0 +1,2 @@
+1
+foo
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/i53643.good b/extensions/spellcheck/hunspell/tests/unit/data/i53643.good
new file mode 100644
index 0000000000..116333452f
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/i53643.good
@@ -0,0 +1,19 @@
+1
+12
+123
+1234
+12345
+123456
+1234567
+1.1
+1.12
+1.123
+1.1234
+1.12345
+1.123456
+12.1
+123.12
+1234.123
+12345.1234
+123456.12345
+1234567.123456
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/i53643.test b/extensions/spellcheck/hunspell/tests/unit/data/i53643.test
new file mode 100644
index 0000000000..7f44369060
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/i53643.test
@@ -0,0 +1,4 @@
+#!/bin/sh
+DIR="`dirname $0`"
+NAME="`basename $0 .test`"
+$DIR/test.sh $NAME
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/i53643.wrong b/extensions/spellcheck/hunspell/tests/unit/data/i53643.wrong
new file mode 100644
index 0000000000..45c61d2985
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/i53643.wrong
@@ -0,0 +1,4 @@
+1..2
+1,,2
+1.,2
+1,.2
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/i54633.aff b/extensions/spellcheck/hunspell/tests/unit/data/i54633.aff
new file mode 100644
index 0000000000..46281e1c5b
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/i54633.aff
@@ -0,0 +1,2 @@
+# Missing capitalized suggestion for capitalized bad words
+SET ISO8859-1
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/i54633.dic b/extensions/spellcheck/hunspell/tests/unit/data/i54633.dic
new file mode 100644
index 0000000000..e26d6f9c89
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/i54633.dic
@@ -0,0 +1,2 @@
+1
+diter
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/i54633.good b/extensions/spellcheck/hunspell/tests/unit/data/i54633.good
new file mode 100644
index 0000000000..a115f67ed4
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/i54633.good
@@ -0,0 +1,2 @@
+diter
+diter
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/i54633.sug b/extensions/spellcheck/hunspell/tests/unit/data/i54633.sug
new file mode 100644
index 0000000000..a115f67ed4
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/i54633.sug
@@ -0,0 +1,2 @@
+diter
+diter
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/i54633.test b/extensions/spellcheck/hunspell/tests/unit/data/i54633.test
new file mode 100644
index 0000000000..dc295077fb
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/i54633.test
@@ -0,0 +1,4 @@
+#!/bin/sh
+DIR="`dirname $0`"
+NAME="`basename $0 .test`"
+$DIR/test.sh $NAME -i ISO8859-1
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/i54633.wrong b/extensions/spellcheck/hunspell/tests/unit/data/i54633.wrong
new file mode 100644
index 0000000000..579a45dab1
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/i54633.wrong
@@ -0,0 +1,2 @@
+editer
+Editer
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/i54980.aff b/extensions/spellcheck/hunspell/tests/unit/data/i54980.aff
new file mode 100644
index 0000000000..37cc5c53d9
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/i54980.aff
@@ -0,0 +1,2 @@
+# ISO-8859-15 (extended latin-1) support for French, Finnish and EURO symbol
+SET ISO8859-15
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/i54980.dic b/extensions/spellcheck/hunspell/tests/unit/data/i54980.dic
new file mode 100644
index 0000000000..414f9b8d3e
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/i54980.dic
@@ -0,0 +1,3 @@
+2
+cur
+uvre
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/i54980.good b/extensions/spellcheck/hunspell/tests/unit/data/i54980.good
new file mode 100644
index 0000000000..fc41c90aac
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/i54980.good
@@ -0,0 +1,4 @@
+cur
+uvre
+CUR
+UVRE
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/i54980.test b/extensions/spellcheck/hunspell/tests/unit/data/i54980.test
new file mode 100644
index 0000000000..09619572e9
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/i54980.test
@@ -0,0 +1,4 @@
+#!/bin/sh
+DIR="`dirname $0`"
+NAME="`basename $0 .test`"
+$DIR/test.sh $NAME -i ISO8859-15
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/i58202.aff b/extensions/spellcheck/hunspell/tests/unit/data/i58202.aff
new file mode 100644
index 0000000000..11249d4f28
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/i58202.aff
@@ -0,0 +1,4 @@
+# case suggestions
+MAXNGRAMSUGS 0
+# capitalise baz->Baz
+TRY B
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/i58202.dic b/extensions/spellcheck/hunspell/tests/unit/data/i58202.dic
new file mode 100644
index 0000000000..19e1980ba2
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/i58202.dic
@@ -0,0 +1,5 @@
+4
+foo
+bar
+Baz
+Boo
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/i58202.good b/extensions/spellcheck/hunspell/tests/unit/data/i58202.good
new file mode 100644
index 0000000000..88a079a55d
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/i58202.good
@@ -0,0 +1,10 @@
+foo
+bar
+Foo
+Bar
+Baz
+Boo
+FOO
+BAR
+BAZ
+BOO
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/i58202.sug b/extensions/spellcheck/hunspell/tests/unit/data/i58202.sug
new file mode 100644
index 0000000000..bc784acef9
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/i58202.sug
@@ -0,0 +1,13 @@
+foo, Boo
+Bar
+Baz
+Boo
+foo bar
+foo Bar
+Foo bar
+Foo Bar
+foo Baz
+Foo Baz
+Baz foo
+Baz Foo
+Baz Boo
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/i58202.test b/extensions/spellcheck/hunspell/tests/unit/data/i58202.test
new file mode 100644
index 0000000000..7f44369060
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/i58202.test
@@ -0,0 +1,4 @@
+#!/bin/sh
+DIR="`dirname $0`"
+NAME="`basename $0 .test`"
+$DIR/test.sh $NAME
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/i58202.wrong b/extensions/spellcheck/hunspell/tests/unit/data/i58202.wrong
new file mode 100644
index 0000000000..886584d809
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/i58202.wrong
@@ -0,0 +1,13 @@
+fOO
+BAr
+baz
+BOo
+foobar
+fooBar
+Foobar
+FooBar
+fooBaz
+FooBaz
+Bazfoo
+BazFoo
+BazBoo
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/i68568.aff b/extensions/spellcheck/hunspell/tests/unit/data/i68568.aff
new file mode 100644
index 0000000000..f0c639e8dd
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/i68568.aff
@@ -0,0 +1,7 @@
+# Sant'Elia -> SANT'ELIA (Italian)
+# OpenOffice.org Issue 68658
+
+PFX a Y 1
+PFX a 0 Sant' E
+
+WORDCHARS '
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/i68568.dic b/extensions/spellcheck/hunspell/tests/unit/data/i68568.dic
new file mode 100644
index 0000000000..966010835b
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/i68568.dic
@@ -0,0 +1,2 @@
+1
+Elia/a
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/i68568.test b/extensions/spellcheck/hunspell/tests/unit/data/i68568.test
new file mode 100644
index 0000000000..7f44369060
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/i68568.test
@@ -0,0 +1,4 @@
+#!/bin/sh
+DIR="`dirname $0`"
+NAME="`basename $0 .test`"
+$DIR/test.sh $NAME
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/i68568.wrong b/extensions/spellcheck/hunspell/tests/unit/data/i68568.wrong
new file mode 100644
index 0000000000..998e9f4e46
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/i68568.wrong
@@ -0,0 +1,5 @@
+sant'elia
+sant'Elia
+Sant'elia
+Sant'
+SANT'
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/i68568utf.aff b/extensions/spellcheck/hunspell/tests/unit/data/i68568utf.aff
new file mode 100644
index 0000000000..7076ee938a
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/i68568utf.aff
@@ -0,0 +1,8 @@
+# Sant'Elia -> SANT'ELIA (Italian)
+# OpenOffice.org Issue 68658
+SET UTF-8
+
+PFX a Y 1
+PFX a 0 Fo坦' B
+
+WORDCHARS '
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/i68568utf.dic b/extensions/spellcheck/hunspell/tests/unit/data/i68568utf.dic
new file mode 100644
index 0000000000..bc38229faa
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/i68568utf.dic
@@ -0,0 +1,2 @@
+1
+B叩r/a
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/i68568utf.test b/extensions/spellcheck/hunspell/tests/unit/data/i68568utf.test
new file mode 100644
index 0000000000..4d59c42126
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/i68568utf.test
@@ -0,0 +1,4 @@
+#!/bin/sh
+DIR="`dirname $0`"
+NAME="`basename $0 .test`"
+$DIR/test.sh $NAME -i UTF-8
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/i68568utf.wrong b/extensions/spellcheck/hunspell/tests/unit/data/i68568utf.wrong
new file mode 100644
index 0000000000..0713c13690
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/i68568utf.wrong
@@ -0,0 +1,5 @@
+fo坦'b叩r
+fo坦'B叩r
+Fo坦'b叩r
+fo坦'
+FO'
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/iconv.aff b/extensions/spellcheck/hunspell/tests/unit/data/iconv.aff
new file mode 100644
index 0000000000..36cf7a2234
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/iconv.aff
@@ -0,0 +1,10 @@
+# input conversion (accept comma acuted letters also with cedilla,
+# as de facto replacement of the Romanian standard)
+SET UTF-8
+
+ICONV 4
+ICONV
+ICONV 釘
+ICONV
+ICONV 鄭
+
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/iconv.dic b/extensions/spellcheck/hunspell/tests/unit/data/iconv.dic
new file mode 100644
index 0000000000..8326eee2d6
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/iconv.dic
@@ -0,0 +1,5 @@
+4
+Chiinu
+epes
+
+
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/iconv.good b/extensions/spellcheck/hunspell/tests/unit/data/iconv.good
new file mode 100644
index 0000000000..746cf1e539
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/iconv.good
@@ -0,0 +1,6 @@
+Chiinu
+Chiinu
+epes
+鄭epes
+
+釘
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/iconv.test b/extensions/spellcheck/hunspell/tests/unit/data/iconv.test
new file mode 100644
index 0000000000..cde7c54109
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/iconv.test
@@ -0,0 +1,4 @@
+#!/bin/sh
+DIR="`dirname $0`"
+NAME="`basename $0 .test`"
+$DIR/test.sh $NAME -i utf-8
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/ignore.aff b/extensions/spellcheck/hunspell/tests/unit/data/ignore.aff
new file mode 100644
index 0000000000..238dc15e55
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/ignore.aff
@@ -0,0 +1,5 @@
+# ignore characters in words (for Arabic Harakat or Hebrew niqqud)
+IGNORE aeiou
+
+PFX A Y 1
+PFX A 0 re .
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/ignore.dic b/extensions/spellcheck/hunspell/tests/unit/data/ignore.dic
new file mode 100644
index 0000000000..846983b7d8
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/ignore.dic
@@ -0,0 +1,3 @@
+2
+xmpl
+expression/A
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/ignore.good b/extensions/spellcheck/hunspell/tests/unit/data/ignore.good
new file mode 100644
index 0000000000..d7dd645c29
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/ignore.good
@@ -0,0 +1,6 @@
+example
+expression
+xmpl
+xprssn
+reexpression
+rxprssn
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/ignore.test b/extensions/spellcheck/hunspell/tests/unit/data/ignore.test
new file mode 100644
index 0000000000..7f44369060
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/ignore.test
@@ -0,0 +1,4 @@
+#!/bin/sh
+DIR="`dirname $0`"
+NAME="`basename $0 .test`"
+$DIR/test.sh $NAME
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/ignoreutf.aff b/extensions/spellcheck/hunspell/tests/unit/data/ignoreutf.aff
new file mode 100644
index 0000000000..8646676d09
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/ignoreutf.aff
@@ -0,0 +1,6 @@
+# Arabic test for feature ignoring diacritics
+SET UTF-8
+# Arabic diacritics (harakat):
+# sukun, shadda, kasra, damma, fatha, kasratan, dammantan, fathatan (left to right)
+IGNORE ル
+WORDCHARS ル
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/ignoreutf.dic b/extensions/spellcheck/hunspell/tests/unit/data/ignoreutf.dic
new file mode 100644
index 0000000000..d4a2a81e7d
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/ignoreutf.dic
@@ -0,0 +1,10 @@
+9
+愀惘
+リ忰悸
+惷悸
+愕惘悸
+惠忰惠悋
+惷惠悋
+愕惘惠悋
+愆惆悸
+愕
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/ignoreutf.good b/extensions/spellcheck/hunspell/tests/unit/data/ignoreutf.good
new file mode 100644
index 0000000000..d463cd59fc
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/ignoreutf.good
@@ -0,0 +1,9 @@
+愀惘
+惠忰悸
+惷悸
+愕惘悸
+惠忰惠悋
+惷惠悋
+愕惘惠悋
+愆惆悸
+愕
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/ignoreutf.test b/extensions/spellcheck/hunspell/tests/unit/data/ignoreutf.test
new file mode 100644
index 0000000000..cde7c54109
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/ignoreutf.test
@@ -0,0 +1,4 @@
+#!/bin/sh
+DIR="`dirname $0`"
+NAME="`basename $0 .test`"
+$DIR/test.sh $NAME -i utf-8
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/keepcase.aff b/extensions/spellcheck/hunspell/tests/unit/data/keepcase.aff
new file mode 100644
index 0000000000..b08006bf78
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/keepcase.aff
@@ -0,0 +1,3 @@
+# keep case in signed words
+KEEPCASE A
+WORDCHARS .
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/keepcase.dic b/extensions/spellcheck/hunspell/tests/unit/data/keepcase.dic
new file mode 100644
index 0000000000..bf9992acf2
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/keepcase.dic
@@ -0,0 +1,5 @@
+4
+foo/A
+Bar/A
+baz./A
+Quux./A
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/keepcase.good b/extensions/spellcheck/hunspell/tests/unit/data/keepcase.good
new file mode 100644
index 0000000000..e6ff1817d3
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/keepcase.good
@@ -0,0 +1,4 @@
+foo
+Bar
+baz.
+Quux.
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/keepcase.sug b/extensions/spellcheck/hunspell/tests/unit/data/keepcase.sug
new file mode 100644
index 0000000000..551dd8bb36
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/keepcase.sug
@@ -0,0 +1,8 @@
+foo
+foo
+Bar
+Bar
+baz.
+baz.
+Quux.
+Quux.
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/keepcase.test b/extensions/spellcheck/hunspell/tests/unit/data/keepcase.test
new file mode 100644
index 0000000000..7f44369060
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/keepcase.test
@@ -0,0 +1,4 @@
+#!/bin/sh
+DIR="`dirname $0`"
+NAME="`basename $0 .test`"
+$DIR/test.sh $NAME
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/keepcase.wrong b/extensions/spellcheck/hunspell/tests/unit/data/keepcase.wrong
new file mode 100644
index 0000000000..3b79142915
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/keepcase.wrong
@@ -0,0 +1,8 @@
+Foo
+FOO
+BAR
+bar
+Baz.
+BAZ.
+quux.
+QUUX.
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/korean.aff b/extensions/spellcheck/hunspell/tests/unit/data/korean.aff
new file mode 100644
index 0000000000..979e3c2284
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/korean.aff
@@ -0,0 +1 @@
+SET UTF-8
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/korean.dic b/extensions/spellcheck/hunspell/tests/unit/data/korean.dic
new file mode 100644
index 0000000000..95cb4508e3
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/korean.dic
@@ -0,0 +1,3 @@
+2
+れ伎れ語
+語
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/korean.good b/extensions/spellcheck/hunspell/tests/unit/data/korean.good
new file mode 100644
index 0000000000..660d506bb6
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/korean.good
@@ -0,0 +1,2 @@
+れ伎れ語
+語
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/korean.test b/extensions/spellcheck/hunspell/tests/unit/data/korean.test
new file mode 100644
index 0000000000..4d59c42126
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/korean.test
@@ -0,0 +1,4 @@
+#!/bin/sh
+DIR="`dirname $0`"
+NAME="`basename $0 .test`"
+$DIR/test.sh $NAME -i UTF-8
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/korean.wrong b/extensions/spellcheck/hunspell/tests/unit/data/korean.wrong
new file mode 100644
index 0000000000..5ea85cead3
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/korean.wrong
@@ -0,0 +1 @@
+れ伎れ
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/map.aff b/extensions/spellcheck/hunspell/tests/unit/data/map.aff
new file mode 100644
index 0000000000..3e78baba6b
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/map.aff
@@ -0,0 +1,9 @@
+# With MAP suggestion, Hunspell can add missing accents to a word.
+
+# switch off ngram suggestion for testing
+MAXNGRAMSUGS 0
+
+MAP 3
+MAP u
+MAP o齧
+MAP (ss)
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/map.dic b/extensions/spellcheck/hunspell/tests/unit/data/map.dic
new file mode 100644
index 0000000000..744394f0c8
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/map.dic
@@ -0,0 +1,4 @@
+3
+Frhstck
+tkrfr
+gro
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/map.sug b/extensions/spellcheck/hunspell/tests/unit/data/map.sug
new file mode 100644
index 0000000000..cadb754228
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/map.sug
@@ -0,0 +1,3 @@
+Frhstck
+tkrfr
+gro
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/map.test b/extensions/spellcheck/hunspell/tests/unit/data/map.test
new file mode 100644
index 0000000000..dc295077fb
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/map.test
@@ -0,0 +1,4 @@
+#!/bin/sh
+DIR="`dirname $0`"
+NAME="`basename $0 .test`"
+$DIR/test.sh $NAME -i ISO8859-1
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/map.wrong b/extensions/spellcheck/hunspell/tests/unit/data/map.wrong
new file mode 100644
index 0000000000..251c8a1e94
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/map.wrong
@@ -0,0 +1,3 @@
+Fruhstuck
+tukorfuro
+gross
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/maputf.aff b/extensions/spellcheck/hunspell/tests/unit/data/maputf.aff
new file mode 100644
index 0000000000..30edb2a785
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/maputf.aff
@@ -0,0 +1,11 @@
+# With MAP suggestion, Hunspell can add missing accents to a word.
+
+SET UTF-8
+
+# switch off ngram suggestion for testing
+MAXNGRAMSUGS 0
+
+MAP 3
+MAP u炭端
+MAP 旦坦o
+MAP (ss)
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/maputf.dic b/extensions/spellcheck/hunspell/tests/unit/data/maputf.dic
new file mode 100644
index 0000000000..1c6fa8d058
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/maputf.dic
@@ -0,0 +1,4 @@
+3
+Fr端hst端ck
+t端k旦rf炭r坦
+gro
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/maputf.sug b/extensions/spellcheck/hunspell/tests/unit/data/maputf.sug
new file mode 100644
index 0000000000..81d09e0214
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/maputf.sug
@@ -0,0 +1,3 @@
+Fr端hst端ck
+t端k旦rf炭r坦
+gro
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/maputf.test b/extensions/spellcheck/hunspell/tests/unit/data/maputf.test
new file mode 100644
index 0000000000..cde7c54109
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/maputf.test
@@ -0,0 +1,4 @@
+#!/bin/sh
+DIR="`dirname $0`"
+NAME="`basename $0 .test`"
+$DIR/test.sh $NAME -i utf-8
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/maputf.wrong b/extensions/spellcheck/hunspell/tests/unit/data/maputf.wrong
new file mode 100644
index 0000000000..251c8a1e94
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/maputf.wrong
@@ -0,0 +1,3 @@
+Fruhstuck
+tukorfuro
+gross
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/morph.aff b/extensions/spellcheck/hunspell/tests/unit/data/morph.aff
new file mode 100644
index 0000000000..6080858608
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/morph.aff
@@ -0,0 +1,12 @@
+# example for morphological analysis, stemming and generation
+PFX P Y 1
+PFX P 0 un . dp:pfx_un sp:un
+
+SFX S Y 1
+SFX S 0 s . is:plur
+
+SFX Q Y 1
+SFX Q 0 s . is:sg_3
+
+SFX R Y 1
+SFX R 0 able/PS . ds:der_able
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/morph.dic b/extensions/spellcheck/hunspell/tests/unit/data/morph.dic
new file mode 100644
index 0000000000..f8d58a6d4d
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/morph.dic
@@ -0,0 +1,10 @@
+9
+drink/S po:noun
+drink/RQ po:verb al:drank al:drunk ts:present
+drank po:verb st:drink is:past_1
+drunk po:verb st:drink is:past_2
+eat/RQ po:verb al:ate al:eaten ts:present
+ate po:verb st:eat is:past_1
+eaten po:verb st:eat is:past_2
+phenomenon po:noun al:phenomena
+phenomena po:noun st:phenomenon is:plur
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/morph.good b/extensions/spellcheck/hunspell/tests/unit/data/morph.good
new file mode 100644
index 0000000000..9f0d24768f
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/morph.good
@@ -0,0 +1,26 @@
+drink
+drinks
+drinkable
+drinkables
+undrinkable
+undrinkables
+drank
+drunk
+phenomenon
+phenomena
+drink eat
+drink eats
+drink ate
+drink eaten
+drink eatable
+drink eatables
+drink phenomena
+drinks eat
+drinks eats
+drinks ate
+drinks eaten
+drinks eatable
+drinks eatables
+drinks phenomena
+undrinkable phenomena
+phenomenon drinks
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/morph.morph b/extensions/spellcheck/hunspell/tests/unit/data/morph.morph
new file mode 100644
index 0000000000..9965d7ea83
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/morph.morph
@@ -0,0 +1,48 @@
+> drink
+analyze(drink) = st:drink po:noun
+analyze(drink) = st:drink po:verb al:drank al:drunk ts:present
+stem(drink) = drink
+> drinks
+analyze(drinks) = st:drink po:verb al:drank al:drunk ts:present is:sg_3
+analyze(drinks) = st:drink po:noun is:plur
+stem(drinks) = drink
+> drinkable
+analyze(drinkable) = st:drink po:verb al:drank al:drunk ts:present ds:der_able
+stem(drinkable) = drinkable
+> drinkables
+analyze(drinkables) = st:drink po:verb al:drank al:drunk ts:present ds:der_able is:plur
+stem(drinkables) = drinkable
+> undrinkable
+analyze(undrinkable) = dp:pfx_un sp:un st:drink po:verb al:drank al:drunk ts:present ds:der_able
+stem(undrinkable) = undrinkable
+> undrinkables
+analyze(undrinkables) = dp:pfx_un sp:un st:drink po:verb al:drank al:drunk ts:present ds:der_able is:plur
+stem(undrinkables) = undrinkable
+> drank
+analyze(drank) = po:verb st:drink is:past_1
+stem(drank) = drink
+> drunk
+analyze(drunk) = po:verb st:drink is:past_2
+stem(drunk) = drink
+> phenomenon
+analyze(phenomenon) = st:phenomenon po:noun al:phenomena
+stem(phenomenon) = phenomenon
+> phenomena
+analyze(phenomena) = po:noun st:phenomenon is:plur
+stem(phenomena) = phenomenon
+generate(drink, eat) = drink
+generate(drink, eats) = drinks
+generate(drink, ate) = drank
+generate(drink, eaten) = drunk
+generate(drink, eatable) = drinkable
+generate(drink, eatables) = drinkables
+generate(drink, phenomena) = drinks
+generate(drinks, eat) = drink
+generate(drinks, eats) = drinks
+generate(drinks, ate) = drank
+generate(drinks, eaten) = drunk
+generate(drinks, eatable) = drinkable
+generate(drinks, eatables) = drinkables
+generate(drinks, phenomena) = drinks
+generate(undrinkable, phenomena) = undrinkables
+generate(phenomenon, drinks) = phenomena
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/morph.test b/extensions/spellcheck/hunspell/tests/unit/data/morph.test
new file mode 100644
index 0000000000..7f44369060
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/morph.test
@@ -0,0 +1,4 @@
+#!/bin/sh
+DIR="`dirname $0`"
+NAME="`basename $0 .test`"
+$DIR/test.sh $NAME
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/needaffix.aff b/extensions/spellcheck/hunspell/tests/unit/data/needaffix.aff
new file mode 100644
index 0000000000..a5981ef69f
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/needaffix.aff
@@ -0,0 +1,5 @@
+NEEDAFFIX X
+COMPOUNDFLAG Y
+
+SFX A Y 1
+SFX A 0 s/Y .
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/needaffix.dic b/extensions/spellcheck/hunspell/tests/unit/data/needaffix.dic
new file mode 100644
index 0000000000..b5792765e3
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/needaffix.dic
@@ -0,0 +1,3 @@
+2
+foo/YXA
+bar/Y
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/needaffix.good b/extensions/spellcheck/hunspell/tests/unit/data/needaffix.good
new file mode 100644
index 0000000000..f9e0663f3d
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/needaffix.good
@@ -0,0 +1,3 @@
+bar
+foos
+barfoos
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/needaffix.test b/extensions/spellcheck/hunspell/tests/unit/data/needaffix.test
new file mode 100644
index 0000000000..7f44369060
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/needaffix.test
@@ -0,0 +1,4 @@
+#!/bin/sh
+DIR="`dirname $0`"
+NAME="`basename $0 .test`"
+$DIR/test.sh $NAME
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/needaffix.wrong b/extensions/spellcheck/hunspell/tests/unit/data/needaffix.wrong
new file mode 100644
index 0000000000..257cc5642c
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/needaffix.wrong
@@ -0,0 +1 @@
+foo
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/needaffix2.aff b/extensions/spellcheck/hunspell/tests/unit/data/needaffix2.aff
new file mode 100644
index 0000000000..c434dac664
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/needaffix2.aff
@@ -0,0 +1,2 @@
+NEEDAFFIX X
+COMPOUNDFLAG Y
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/needaffix2.dic b/extensions/spellcheck/hunspell/tests/unit/data/needaffix2.dic
new file mode 100644
index 0000000000..ff32e878bd
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/needaffix2.dic
@@ -0,0 +1,5 @@
+4
+foo st:foo id:1
+foo/YX st:foo id:2
+foo/Y st:foo id:3
+bar/Y
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/needaffix2.good b/extensions/spellcheck/hunspell/tests/unit/data/needaffix2.good
new file mode 100644
index 0000000000..7e4b098ef9
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/needaffix2.good
@@ -0,0 +1,5 @@
+foo
+bar
+foobar
+barfoo
+
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/needaffix2.morph b/extensions/spellcheck/hunspell/tests/unit/data/needaffix2.morph
new file mode 100644
index 0000000000..0f3e474312
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/needaffix2.morph
@@ -0,0 +1,13 @@
+> foo
+analyze(foo) = st:foo id:1
+analyze(foo) = st:foo id:3
+stem(foo) = foo
+> bar
+analyze(bar) = st:bar
+stem(bar) = bar
+> foobar
+analyze(foobar) = pa:foo st:foo id:3 pa:bar
+stem(foobar) = foo
+> barfoo
+analyze(barfoo) = pa:bar st:bar pa:foo st:foo id:3
+stem(barfoo) = barfoo
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/needaffix2.test b/extensions/spellcheck/hunspell/tests/unit/data/needaffix2.test
new file mode 100644
index 0000000000..7f44369060
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/needaffix2.test
@@ -0,0 +1,4 @@
+#!/bin/sh
+DIR="`dirname $0`"
+NAME="`basename $0 .test`"
+$DIR/test.sh $NAME
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/needaffix3.aff b/extensions/spellcheck/hunspell/tests/unit/data/needaffix3.aff
new file mode 100644
index 0000000000..5d55d38e9e
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/needaffix3.aff
@@ -0,0 +1,8 @@
+# neeadaffix on affixes
+NEEDAFFIX X
+
+SFX A Y 1
+SFX A 0 s/XB .
+
+SFX B Y 1
+SFX B 0 baz .
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/needaffix3.dic b/extensions/spellcheck/hunspell/tests/unit/data/needaffix3.dic
new file mode 100644
index 0000000000..001d95e776
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/needaffix3.dic
@@ -0,0 +1,2 @@
+2
+foo/A
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/needaffix3.good b/extensions/spellcheck/hunspell/tests/unit/data/needaffix3.good
new file mode 100644
index 0000000000..dc9a6a97d8
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/needaffix3.good
@@ -0,0 +1,2 @@
+foo
+foosbaz
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/needaffix3.test b/extensions/spellcheck/hunspell/tests/unit/data/needaffix3.test
new file mode 100644
index 0000000000..7f44369060
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/needaffix3.test
@@ -0,0 +1,4 @@
+#!/bin/sh
+DIR="`dirname $0`"
+NAME="`basename $0 .test`"
+$DIR/test.sh $NAME
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/needaffix3.wrong b/extensions/spellcheck/hunspell/tests/unit/data/needaffix3.wrong
new file mode 100644
index 0000000000..c09c408f24
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/needaffix3.wrong
@@ -0,0 +1 @@
+foos
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/needaffix4.aff b/extensions/spellcheck/hunspell/tests/unit/data/needaffix4.aff
new file mode 100644
index 0000000000..c434dac664
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/needaffix4.aff
@@ -0,0 +1,2 @@
+NEEDAFFIX X
+COMPOUNDFLAG Y
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/needaffix4.dic b/extensions/spellcheck/hunspell/tests/unit/data/needaffix4.dic
new file mode 100644
index 0000000000..96f80c12b0
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/needaffix4.dic
@@ -0,0 +1,5 @@
+4
+foo/X [1]
+foo/Y [2]
+foo/YX [3]
+bar/Y [4]
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/needaffix4.good b/extensions/spellcheck/hunspell/tests/unit/data/needaffix4.good
new file mode 100644
index 0000000000..7e4b098ef9
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/needaffix4.good
@@ -0,0 +1,5 @@
+foo
+bar
+foobar
+barfoo
+
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/needaffix4.test b/extensions/spellcheck/hunspell/tests/unit/data/needaffix4.test
new file mode 100644
index 0000000000..7f44369060
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/needaffix4.test
@@ -0,0 +1,4 @@
+#!/bin/sh
+DIR="`dirname $0`"
+NAME="`basename $0 .test`"
+$DIR/test.sh $NAME
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/needaffix5.aff b/extensions/spellcheck/hunspell/tests/unit/data/needaffix5.aff
new file mode 100644
index 0000000000..6399a3e98f
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/needaffix5.aff
@@ -0,0 +1,13 @@
+# on affixes
+NEEDAFFIX X
+
+SFX A Y 2
+SFX A 0 suf/B .
+SFX A 0 pseudosuf/XB .
+
+SFX B Y 1
+SFX B 0 bar .
+
+PFX C Y 2
+PFX C 0 pre .
+PFX C 0 pseudopre/X .
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/needaffix5.dic b/extensions/spellcheck/hunspell/tests/unit/data/needaffix5.dic
new file mode 100644
index 0000000000..83131e27a5
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/needaffix5.dic
@@ -0,0 +1,2 @@
+1
+foo/AC
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/needaffix5.good b/extensions/spellcheck/hunspell/tests/unit/data/needaffix5.good
new file mode 100644
index 0000000000..d1b86bf831
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/needaffix5.good
@@ -0,0 +1,11 @@
+foo
+prefoo
+foosuf
+prefoosuf
+foosufbar
+prefoosufbar
+pseudoprefoosuf
+pseudoprefoosufbar
+pseudoprefoopseudosufbar
+prefoopseudosuf
+prefoopseudosufbar
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/needaffix5.test b/extensions/spellcheck/hunspell/tests/unit/data/needaffix5.test
new file mode 100644
index 0000000000..7f44369060
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/needaffix5.test
@@ -0,0 +1,4 @@
+#!/bin/sh
+DIR="`dirname $0`"
+NAME="`basename $0 .test`"
+$DIR/test.sh $NAME
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/needaffix5.wrong b/extensions/spellcheck/hunspell/tests/unit/data/needaffix5.wrong
new file mode 100644
index 0000000000..fdd1797fdf
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/needaffix5.wrong
@@ -0,0 +1,3 @@
+pseudoprefoo
+foopseudosuf
+pseudoprefoopseudosuf
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/ngram-utf-fix.aff b/extensions/spellcheck/hunspell/tests/unit/data/ngram-utf-fix.aff
new file mode 100644
index 0000000000..19e6981215
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/ngram-utf-fix.aff
@@ -0,0 +1,21 @@
+# Test fix of suffixed ngram suggestions with UTF-8 encoding and long flags.
+# Based on Vitaly Piryatinsky's bug report and example.
+SET UTF-8
+FLAG num
+
+PFX 101 Y 1
+PFX 101 0 仗亠亟 .
+
+SFX 1381 Y 1
+SFX 1381 0 仂 .
+
+SFX 2000 Y 3
+SFX 2000 0 舒仄 .
+SFX 2000 0 舒仄亳 .
+SFX 2000 0 舒 .
+
+SFX 2022 Y 4
+SFX 2022 0 舒 .
+SFX 2022 0 .
+SFX 2022 0 仂仄 .
+SFX 2022 0 亠 .
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/ngram-utf-fix.dic b/extensions/spellcheck/hunspell/tests/unit/data/ngram-utf-fix.dic
new file mode 100644
index 0000000000..27ce413aeb
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/ngram-utf-fix.dic
@@ -0,0 +1,2 @@
+1
+亠仍仂于亠从/2022,2000,101
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/ngram-utf-fix.good b/extensions/spellcheck/hunspell/tests/unit/data/ngram-utf-fix.good
new file mode 100644
index 0000000000..366d92a9bc
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/ngram-utf-fix.good
@@ -0,0 +1 @@
+亠仍仂于亠从
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/ngram-utf-fix.sug b/extensions/spellcheck/hunspell/tests/unit/data/ngram-utf-fix.sug
new file mode 100644
index 0000000000..58ab09b534
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/ngram-utf-fix.sug
@@ -0,0 +1,2 @@
+亠仍仂于亠从
+亠仍仂于亠从
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/ngram-utf-fix.test b/extensions/spellcheck/hunspell/tests/unit/data/ngram-utf-fix.test
new file mode 100644
index 0000000000..cde7c54109
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/ngram-utf-fix.test
@@ -0,0 +1,4 @@
+#!/bin/sh
+DIR="`dirname $0`"
+NAME="`basename $0 .test`"
+$DIR/test.sh $NAME -i utf-8
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/ngram-utf-fix.wrong b/extensions/spellcheck/hunspell/tests/unit/data/ngram-utf-fix.wrong
new file mode 100644
index 0000000000..97de996e08
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/ngram-utf-fix.wrong
@@ -0,0 +1,2 @@
+于亠仄从仂
+亠仍仂于亠从仂
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/nosuggest.aff b/extensions/spellcheck/hunspell/tests/unit/data/nosuggest.aff
new file mode 100644
index 0000000000..c9361da4c6
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/nosuggest.aff
@@ -0,0 +1,5 @@
+# don't suggest word with NOSUGGEST flag (for example vulgar or obscene words)
+# See OpenOffice.org Issue #55498
+# (nosuggest.sug is an empty file)
+NOSUGGEST A
+COMPOUNDFLAG B
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/nosuggest.dic b/extensions/spellcheck/hunspell/tests/unit/data/nosuggest.dic
new file mode 100644
index 0000000000..dc80c916d4
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/nosuggest.dic
@@ -0,0 +1,3 @@
+1
+foo/AB
+bar/B
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/nosuggest.good b/extensions/spellcheck/hunspell/tests/unit/data/nosuggest.good
new file mode 100644
index 0000000000..ad91a5e313
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/nosuggest.good
@@ -0,0 +1,3 @@
+foo
+foobar
+barfoo
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/nosuggest.sug b/extensions/spellcheck/hunspell/tests/unit/data/nosuggest.sug
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/nosuggest.sug
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/nosuggest.test b/extensions/spellcheck/hunspell/tests/unit/data/nosuggest.test
new file mode 100644
index 0000000000..7f44369060
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/nosuggest.test
@@ -0,0 +1,4 @@
+#!/bin/sh
+DIR="`dirname $0`"
+NAME="`basename $0 .test`"
+$DIR/test.sh $NAME
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/nosuggest.wrong b/extensions/spellcheck/hunspell/tests/unit/data/nosuggest.wrong
new file mode 100644
index 0000000000..89c7a1a9c0
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/nosuggest.wrong
@@ -0,0 +1,3 @@
+foox
+foobarx
+barfoox
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/oconv.aff b/extensions/spellcheck/hunspell/tests/unit/data/oconv.aff
new file mode 100644
index 0000000000..13a3d9b207
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/oconv.aff
@@ -0,0 +1,12 @@
+# output conversion
+SET UTF-8
+
+OCONV 7
+OCONV a A
+OCONV 叩
+OCONV b B
+OCONV c C
+OCONV d D
+OCONV e E
+OCONV 辿
+
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/oconv.dic b/extensions/spellcheck/hunspell/tests/unit/data/oconv.dic
new file mode 100644
index 0000000000..359186cac1
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/oconv.dic
@@ -0,0 +1,4 @@
+3
+b辿b辿
+d叩d叩
+a叩bcde辿
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/oconv.good b/extensions/spellcheck/hunspell/tests/unit/data/oconv.good
new file mode 100644
index 0000000000..6cdaab16e3
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/oconv.good
@@ -0,0 +1,2 @@
+b辿b辿
+d叩d叩
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/oconv.sug b/extensions/spellcheck/hunspell/tests/unit/data/oconv.sug
new file mode 100644
index 0000000000..a191c629dd
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/oconv.sug
@@ -0,0 +1,3 @@
+BB
+DD
+ABCDE
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/oconv.test b/extensions/spellcheck/hunspell/tests/unit/data/oconv.test
new file mode 100644
index 0000000000..cde7c54109
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/oconv.test
@@ -0,0 +1,4 @@
+#!/bin/sh
+DIR="`dirname $0`"
+NAME="`basename $0 .test`"
+$DIR/test.sh $NAME -i utf-8
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/oconv.wrong b/extensions/spellcheck/hunspell/tests/unit/data/oconv.wrong
new file mode 100644
index 0000000000..73dcc895a9
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/oconv.wrong
@@ -0,0 +1,3 @@
+b辿b
+d叩d
+a叩bcde
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/onlyincompound.aff b/extensions/spellcheck/hunspell/tests/unit/data/onlyincompound.aff
new file mode 100644
index 0000000000..e700b0e54a
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/onlyincompound.aff
@@ -0,0 +1,5 @@
+# words only in compounds (see also fogemorpheme example)
+ONLYINCOMPOUND O
+COMPOUNDFLAG A
+SFX B Y 1
+SFX B 0 s .
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/onlyincompound.dic b/extensions/spellcheck/hunspell/tests/unit/data/onlyincompound.dic
new file mode 100644
index 0000000000..dc742f7abe
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/onlyincompound.dic
@@ -0,0 +1,3 @@
+2
+foo/A
+pseudo/OAB
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/onlyincompound.good b/extensions/spellcheck/hunspell/tests/unit/data/onlyincompound.good
new file mode 100644
index 0000000000..151d597342
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/onlyincompound.good
@@ -0,0 +1,4 @@
+foo
+pseudofoo
+foopseudo
+foopseudos
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/onlyincompound.sug b/extensions/spellcheck/hunspell/tests/unit/data/onlyincompound.sug
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/onlyincompound.sug
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/onlyincompound.test b/extensions/spellcheck/hunspell/tests/unit/data/onlyincompound.test
new file mode 100644
index 0000000000..7f44369060
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/onlyincompound.test
@@ -0,0 +1,4 @@
+#!/bin/sh
+DIR="`dirname $0`"
+NAME="`basename $0 .test`"
+$DIR/test.sh $NAME
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/onlyincompound.wrong b/extensions/spellcheck/hunspell/tests/unit/data/onlyincompound.wrong
new file mode 100644
index 0000000000..115d0c6174
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/onlyincompound.wrong
@@ -0,0 +1,2 @@
+pseudo
+pseudos
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/onlyincompound2.aff b/extensions/spellcheck/hunspell/tests/unit/data/onlyincompound2.aff
new file mode 100644
index 0000000000..5d0ac5e69b
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/onlyincompound2.aff
@@ -0,0 +1,12 @@
+# affixes only in compounds (see also fogemorpheme example)
+ONLYINCOMPOUND O
+COMPOUNDFLAG A
+COMPOUNDPERMITFLAG P
+
+SFX B Y 1
+SFX B 0 s/OP .
+
+# obligate fogemorpheme by forbidding the stem (0) in compounds
+
+CHECKCOMPOUNDPATTERN 1
+CHECKCOMPOUNDPATTERN 0/B /A
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/onlyincompound2.dic b/extensions/spellcheck/hunspell/tests/unit/data/onlyincompound2.dic
new file mode 100644
index 0000000000..1adab653bf
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/onlyincompound2.dic
@@ -0,0 +1,3 @@
+2
+foo/A
+pseudo/AB
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/onlyincompound2.good b/extensions/spellcheck/hunspell/tests/unit/data/onlyincompound2.good
new file mode 100644
index 0000000000..a31ce34aca
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/onlyincompound2.good
@@ -0,0 +1,3 @@
+foo
+foopseudo
+pseudosfoo
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/onlyincompound2.test b/extensions/spellcheck/hunspell/tests/unit/data/onlyincompound2.test
new file mode 100644
index 0000000000..7f44369060
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/onlyincompound2.test
@@ -0,0 +1,4 @@
+#!/bin/sh
+DIR="`dirname $0`"
+NAME="`basename $0 .test`"
+$DIR/test.sh $NAME
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/onlyincompound2.wrong b/extensions/spellcheck/hunspell/tests/unit/data/onlyincompound2.wrong
new file mode 100644
index 0000000000..29a71a3c3b
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/onlyincompound2.wrong
@@ -0,0 +1,3 @@
+pseudos
+foopseudos
+pseudofoo
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/opentaal-cpdpat.aff b/extensions/spellcheck/hunspell/tests/unit/data/opentaal-cpdpat.aff
new file mode 100644
index 0000000000..413aca4049
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/opentaal-cpdpat.aff
@@ -0,0 +1,13 @@
+FLAG long
+COMPOUNDBEGIN Ca
+COMPOUNDMIDDLE Cb
+COMPOUNDEND Cc
+COMPOUNDPERMITFLAG Cp
+ONLYINCOMPOUND Cx
+
+CHECKCOMPOUNDPATTERN 1
+CHECKCOMPOUNDPATTERN /Ch /Xs
+
+SFX Ch Y 2
+SFX Ch 0 s/CaCbCxCp .
+SFX Ch 0 s-/CaCbCcCp .
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/opentaal-cpdpat.dic b/extensions/spellcheck/hunspell/tests/unit/data/opentaal-cpdpat.dic
new file mode 100644
index 0000000000..e7831b7045
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/opentaal-cpdpat.dic
@@ -0,0 +1,4 @@
+3
+schoonheid/Ch
+port/CcXs
+sport/Cc
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/opentaal-cpdpat.good b/extensions/spellcheck/hunspell/tests/unit/data/opentaal-cpdpat.good
new file mode 100644
index 0000000000..fbaf830beb
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/opentaal-cpdpat.good
@@ -0,0 +1 @@
+schoonheidssport
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/opentaal-cpdpat.test b/extensions/spellcheck/hunspell/tests/unit/data/opentaal-cpdpat.test
new file mode 100644
index 0000000000..7f44369060
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/opentaal-cpdpat.test
@@ -0,0 +1,4 @@
+#!/bin/sh
+DIR="`dirname $0`"
+NAME="`basename $0 .test`"
+$DIR/test.sh $NAME
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/opentaal-cpdpat.wrong b/extensions/spellcheck/hunspell/tests/unit/data/opentaal-cpdpat.wrong
new file mode 100644
index 0000000000..3f9e8949b1
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/opentaal-cpdpat.wrong
@@ -0,0 +1 @@
+schoonheidsport
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/opentaal-cpdpat2.aff b/extensions/spellcheck/hunspell/tests/unit/data/opentaal-cpdpat2.aff
new file mode 100644
index 0000000000..22dfe69d86
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/opentaal-cpdpat2.aff
@@ -0,0 +1,27 @@
+# Test file based on OpenTaal's Dutch dictionary, coded by Ruud Baars
+
+WORDCHARS -
+NOSPLITSUGS
+FLAG long
+
+COMPOUNDBEGIN Ca
+COMPOUNDMIDDLE Cb
+COMPOUNDEND Cc
+COMPOUNDPERMITFLAG Cp
+ONLYINCOMPOUND Cx
+
+CHECKCOMPOUNDPATTERN 2
+CHECKCOMPOUNDPATTERN 0/Ch /Xs
+CHECKCOMPOUNDPATTERN 0/Xm /Xm
+
+SFX CA Y 2
+SFX CA 0 /CaCp .
+SFX CA 0 -/CaCp .
+
+SFX CB Y 2
+SFX CB 0 /CbCp .
+SFX CB 0 -/CbCp .
+
+SFX Ch Y 2
+SFX Ch 0 s/CaCbCxCp .
+SFX Ch 0 s-/CaCbCcCp .
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/opentaal-cpdpat2.dic b/extensions/spellcheck/hunspell/tests/unit/data/opentaal-cpdpat2.dic
new file mode 100644
index 0000000000..52581e942e
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/opentaal-cpdpat2.dic
@@ -0,0 +1,4 @@
+100
+test/CACBCc
+zout/CACBXm
+suiker/CACBXm \ No newline at end of file
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/opentaal-cpdpat2.good b/extensions/spellcheck/hunspell/tests/unit/data/opentaal-cpdpat2.good
new file mode 100644
index 0000000000..e604d6e2f7
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/opentaal-cpdpat2.good
@@ -0,0 +1 @@
+zout-suikertest
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/opentaal-cpdpat2.test b/extensions/spellcheck/hunspell/tests/unit/data/opentaal-cpdpat2.test
new file mode 100644
index 0000000000..7f44369060
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/opentaal-cpdpat2.test
@@ -0,0 +1,4 @@
+#!/bin/sh
+DIR="`dirname $0`"
+NAME="`basename $0 .test`"
+$DIR/test.sh $NAME
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/opentaal-cpdpat2.wrong b/extensions/spellcheck/hunspell/tests/unit/data/opentaal-cpdpat2.wrong
new file mode 100644
index 0000000000..d8ddb16a57
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/opentaal-cpdpat2.wrong
@@ -0,0 +1 @@
+zoutsuikertest
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/opentaal-forbiddenword1.aff b/extensions/spellcheck/hunspell/tests/unit/data/opentaal-forbiddenword1.aff
new file mode 100644
index 0000000000..fa073432f5
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/opentaal-forbiddenword1.aff
@@ -0,0 +1,9 @@
+TRY r
+
+FORBIDDENWORD F
+COMPOUNDRULE 2
+COMPOUNDRULE WW
+COMPOUNDRULE WWW
+
+SFX S Y 1
+SFX S 0 s .
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/opentaal-forbiddenword1.dic b/extensions/spellcheck/hunspell/tests/unit/data/opentaal-forbiddenword1.dic
new file mode 100644
index 0000000000..44375948ff
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/opentaal-forbiddenword1.dic
@@ -0,0 +1,5 @@
+4
+foo/W
+word/W
+bar/WS
+foowordbar/FS
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/opentaal-forbiddenword1.good b/extensions/spellcheck/hunspell/tests/unit/data/opentaal-forbiddenword1.good
new file mode 100644
index 0000000000..73a96a7845
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/opentaal-forbiddenword1.good
@@ -0,0 +1,3 @@
+fooword
+wordbar
+barwordfoo
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/opentaal-forbiddenword1.sug b/extensions/spellcheck/hunspell/tests/unit/data/opentaal-forbiddenword1.sug
new file mode 100644
index 0000000000..60111a417f
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/opentaal-forbiddenword1.sug
@@ -0,0 +1 @@
+barwordfoo
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/opentaal-forbiddenword1.test b/extensions/spellcheck/hunspell/tests/unit/data/opentaal-forbiddenword1.test
new file mode 100644
index 0000000000..7f44369060
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/opentaal-forbiddenword1.test
@@ -0,0 +1,4 @@
+#!/bin/sh
+DIR="`dirname $0`"
+NAME="`basename $0 .test`"
+$DIR/test.sh $NAME
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/opentaal-forbiddenword1.wrong b/extensions/spellcheck/hunspell/tests/unit/data/opentaal-forbiddenword1.wrong
new file mode 100644
index 0000000000..59dfddfb24
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/opentaal-forbiddenword1.wrong
@@ -0,0 +1,5 @@
+foowordbar
+foowordbars
+foowordba
+foowordbas
+barwodfoo
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/opentaal-forbiddenword2.aff b/extensions/spellcheck/hunspell/tests/unit/data/opentaal-forbiddenword2.aff
new file mode 100644
index 0000000000..441354d6b0
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/opentaal-forbiddenword2.aff
@@ -0,0 +1,7 @@
+TRY r
+
+FORBIDDENWORD F
+COMPOUNDFLAG W
+
+SFX S Y 1
+SFX S 0 s .
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/opentaal-forbiddenword2.dic b/extensions/spellcheck/hunspell/tests/unit/data/opentaal-forbiddenword2.dic
new file mode 100644
index 0000000000..895dd62305
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/opentaal-forbiddenword2.dic
@@ -0,0 +1,5 @@
+3
+foo/WS
+word/W
+bar/WS
+foowordbar/FS \ No newline at end of file
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/opentaal-forbiddenword2.good b/extensions/spellcheck/hunspell/tests/unit/data/opentaal-forbiddenword2.good
new file mode 100644
index 0000000000..17cf47de3d
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/opentaal-forbiddenword2.good
@@ -0,0 +1,4 @@
+fooword
+wordbar
+barwordfoo
+barwordfoos
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/opentaal-forbiddenword2.sug b/extensions/spellcheck/hunspell/tests/unit/data/opentaal-forbiddenword2.sug
new file mode 100644
index 0000000000..60111a417f
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/opentaal-forbiddenword2.sug
@@ -0,0 +1 @@
+barwordfoo
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/opentaal-forbiddenword2.test b/extensions/spellcheck/hunspell/tests/unit/data/opentaal-forbiddenword2.test
new file mode 100644
index 0000000000..7f44369060
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/opentaal-forbiddenword2.test
@@ -0,0 +1,4 @@
+#!/bin/sh
+DIR="`dirname $0`"
+NAME="`basename $0 .test`"
+$DIR/test.sh $NAME
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/opentaal-forbiddenword2.wrong b/extensions/spellcheck/hunspell/tests/unit/data/opentaal-forbiddenword2.wrong
new file mode 100644
index 0000000000..59dfddfb24
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/opentaal-forbiddenword2.wrong
@@ -0,0 +1,5 @@
+foowordbar
+foowordbars
+foowordba
+foowordbas
+barwodfoo
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/opentaal-keepcase.aff b/extensions/spellcheck/hunspell/tests/unit/data/opentaal-keepcase.aff
new file mode 100644
index 0000000000..15c914bec3
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/opentaal-keepcase.aff
@@ -0,0 +1,8 @@
+KEEPCASE K
+COMPOUNDBEGIN B
+COMPOUNDEND E
+COMPOUNDFLAG C
+COMPOUNDMIN 1
+WORDCHARS -
+BREAK 1
+BREAK #
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/opentaal-keepcase.dic b/extensions/spellcheck/hunspell/tests/unit/data/opentaal-keepcase.dic
new file mode 100644
index 0000000000..b05ec131a2
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/opentaal-keepcase.dic
@@ -0,0 +1,7 @@
+5
+tv-/KB
+-tv/KE
+word/C
+NATO-/B
+-NATO/E
+
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/opentaal-keepcase.good b/extensions/spellcheck/hunspell/tests/unit/data/opentaal-keepcase.good
new file mode 100644
index 0000000000..e1c1129102
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/opentaal-keepcase.good
@@ -0,0 +1,4 @@
+tv-word
+word-tv
+NATO-word
+word-NATO
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/opentaal-keepcase.sug b/extensions/spellcheck/hunspell/tests/unit/data/opentaal-keepcase.sug
new file mode 100644
index 0000000000..07dde3fe68
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/opentaal-keepcase.sug
@@ -0,0 +1,8 @@
+Tv-word, Tv- word, Word
+Tv- word, Word
+word -tv, word-tv, word
+word -tv, word-tv, word
+wordword-tv, word
+Tv-word-tv
+NATO-
+-NATO
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/opentaal-keepcase.test b/extensions/spellcheck/hunspell/tests/unit/data/opentaal-keepcase.test
new file mode 100644
index 0000000000..7f44369060
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/opentaal-keepcase.test
@@ -0,0 +1,4 @@
+#!/bin/sh
+DIR="`dirname $0`"
+NAME="`basename $0 .test`"
+$DIR/test.sh $NAME
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/opentaal-keepcase.wrong b/extensions/spellcheck/hunspell/tests/unit/data/opentaal-keepcase.wrong
new file mode 100644
index 0000000000..b15752ed20
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/opentaal-keepcase.wrong
@@ -0,0 +1,8 @@
+TV-word
+Tv-word
+word-TV
+word-Tv
+wordword-TV
+TV-word-TV
+Nato-word
+word-nato
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/phone.aff b/extensions/spellcheck/hunspell/tests/unit/data/phone.aff
new file mode 100644
index 0000000000..5a27c14d7e
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/phone.aff
@@ -0,0 +1,255 @@
+# phonetic suggestions by PHONE and optional ph field of dictionary words
+# Documentationo of PHONE: http://aspell.net/man-html/Phonetic-Code.html
+
+# phonetic_english.h - phonetic transformation rules for use with phonetic.c
+# Copyright (C) 2000 Bj旦rn Jacke
+#
+# This rule set is based on Lawrence Phillips original metaphone
+# algorithm with modifications made by Michael Kuhn in his
+# C implantation, more modifications by Bj旦rn Jacke when
+# converting the algorithm to a rule set and minor
+# touch ups by Kevin Atkinson
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License version 2.1 as published by the Free Software Foundation;
+#
+# This library 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 this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#
+# Bj旦rn Jacke may be reached by email at bjoern.jacke@gmx.de
+#
+# Changelog:
+#
+# 2000-01-05 Bj旦rn Jacke <bjoern.jacke@gmx.de>
+# - first version with translation rules derived from
+# metaphone.cc distributed with aspell 0.28.3
+# - "TH" is now representated as "@" because "0" is a
+# meta character
+# - removed TH(!vowel) --> T; always use TH --> # instead
+# - dropped "^AE" -> "E" (redundant)
+# - "ing" is transformed to "N", not "NK"
+# - "SCH(EO)" transforms to "SK" now
+# - added R --> SILENT if (after a vowel) and no (vowel or
+# "y" follows) like in "Marcy" or "abort"
+# - H is SILENT in RH at beginning of words
+# - H is SILENT if vowel leads and "Y" follows
+# - some ".OUGH.." --> ...F exceptions added
+# - "^V" transforms to "W"
+# 2000-01-07 Kevin Atkinson <kevinatk@home.com>
+# Converted from header to data file.
+#
+# 2007-08-23 L叩szl坦 N辿meth <nemeth AT OOo>
+# Add PHONE header and PHONE keywords
+#
+# version 1.1
+
+PHONE 105
+PHONE AH(AEIOUY)-^ *H
+PHONE AR(AEIOUY)-^ *R
+PHONE A(HR)^ *
+PHONE A^ *
+PHONE AH(AEIOUY)- H
+PHONE AR(AEIOUY)- R
+PHONE A(HR) _
+PHONE BB- _
+PHONE B B
+PHONE CQ- _
+PHONE CIA X
+PHONE CH X
+PHONE C(EIY)- S
+PHONE CK K
+PHONE COUGH^ KF
+PHONE CC< C
+PHONE C K
+PHONE DG(EIY) K
+PHONE DD- _
+PHONE D T
+PHONE < E
+PHONE EH(AEIOUY)-^ *H
+PHONE ER(AEIOUY)-^ *R
+PHONE E(HR)^ *
+PHONE ENOUGH^$ *NF
+PHONE E^ *
+PHONE EH(AEIOUY)- H
+PHONE ER(AEIOUY)- R
+PHONE E(HR) _
+PHONE FF- _
+PHONE F F
+PHONE GN^ N
+PHONE GN$ N
+PHONE GNS$ NS
+PHONE GNED$ N
+PHONE GH(AEIOUY)- K
+PHONE GH _
+PHONE GG9 K
+PHONE G K
+PHONE H H
+PHONE IH(AEIOUY)-^ *H
+PHONE IR(AEIOUY)-^ *R
+PHONE I(HR)^ *
+PHONE I^ *
+PHONE ING6 N
+PHONE IH(AEIOUY)- H
+PHONE IR(AEIOUY)- R
+PHONE I(HR) _
+PHONE J K
+PHONE KN^ N
+PHONE KK- _
+PHONE K K
+PHONE LAUGH^ LF
+PHONE LL- _
+PHONE L L
+PHONE MB$ M
+PHONE MM M
+PHONE M M
+PHONE NN- _
+PHONE N N
+PHONE OH(AEIOUY)-^ *H
+PHONE OR(AEIOUY)-^ *R
+PHONE O(HR)^ *
+PHONE O^ *
+PHONE OH(AEIOUY)- H
+PHONE OR(AEIOUY)- R
+PHONE O(HR) _
+PHONE PH F
+PHONE PN^ N
+PHONE PP- _
+PHONE P P
+PHONE Q K
+PHONE RH^ R
+PHONE ROUGH^ RF
+PHONE RR- _
+PHONE R R
+PHONE SCH(EOU)- SK
+PHONE SC(IEY)- S
+PHONE SH X
+PHONE SI(AO)- X
+PHONE SS- _
+PHONE S S
+PHONE TI(AO)- X
+PHONE TH @
+PHONE TCH-- _
+PHONE TOUGH^ TF
+PHONE TT- _
+PHONE T T
+PHONE UH(AEIOUY)-^ *H
+PHONE UR(AEIOUY)-^ *R
+PHONE U(HR)^ *
+PHONE U^ *
+PHONE UH(AEIOUY)- H
+PHONE UR(AEIOUY)- R
+PHONE U(HR) _
+PHONE V^ W
+PHONE V F
+PHONE WR^ R
+PHONE WH^ W
+PHONE W(AEIOU)- W
+PHONE X^ S
+PHONE X KS
+PHONE Y(AEIOU)- Y
+PHONE ZZ- _
+PHONE Z S
+
+#The rules in a different view:
+#
+# Exceptions:
+#
+# Beginning of word: "gn", "kn-", "pn-", "wr-" ----> drop first letter
+# "Aebersold", "Gnagy", "Knuth", "Pniewski", "Wright"
+#
+# Beginning of word: "x" ----> change to "s"
+# as in "Deng Xiaopeng"
+#
+# Beginning of word: "wh-" ----> change to "w"
+# as in "Whalen"
+# Beginning of word: leading vowels are transformed to "*"
+#
+# "[crt]ough" and "enough" are handled separately because of "F" sound
+#
+#
+# A --> A at beginning
+# _ otherwise
+#
+# B --> B unless at the end of word after "m", as in "dumb", "McComb"
+#
+# C --> X (sh) if "-cia-" or "-ch-"
+# S if "-ci-", "-ce-", or "-cy-"
+# SILENT if "-sci-", "-sce-", or "-scy-", or "-cq-"
+# K otherwise, including in "-sch-"
+#
+# D --> K if in "-dge-", "-dgy-", or "-dgi-"
+# T otherwise
+#
+# E --> A at beginnig
+# _ SILENT otherwise
+#
+# F --> F
+#
+# G --> SILENT if in "-gh-" and not at end or before a vowel
+# in "-gn" or "-gned" or "-gns"
+# in "-dge-" etc., as in above rule
+# K if before "i", or "e", or "y" if not double "gg"
+#
+# K otherwise (incl. "GG"!)
+#
+# H --> SILENT if after vowel and no vowel or "Y" follows
+# or after "-ch-", "-sh-", "-ph-", "-th-", "-gh-"
+# or after "rh-" at beginning
+# H otherwise
+#
+# I --> A at beginning
+# _ SILENT otherwise
+#
+# J --> K
+#
+# K --> SILENT if after "c"
+# K otherwise
+#
+# L --> L
+#
+# M --> M
+#
+# N --> N
+#
+# O --> A at beginning
+# _ SILENT otherwise
+#
+# P --> F if before "h"
+# P otherwise
+#
+# Q --> K
+#
+# R --> SILENT if after vowel and no vowel or "Y" follows
+# R otherwise
+#
+# S --> X (sh) if before "h" or in "-sio-" or "-sia-"
+# SK if followed by "ch(eo)" (SCH(EO))
+# S otherwise
+#
+# T --> X (sh) if "-tia-" or "-tio-"
+# 0 (th) if before "h"
+# silent if in "-tch-"
+# T otherwise
+#
+# U --> A at beginning
+# _ SILENT otherwise
+#
+# V --> V if first letter of word
+# F otherwise
+#
+# W --> SILENT if not followed by a vowel
+# W if followed by a vowel
+#
+# X --> KS
+#
+# Y --> SILENT if not followed by a vowel
+# Y if followed by a vowel
+#
+# Z --> S
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/phone.dic b/extensions/spellcheck/hunspell/tests/unit/data/phone.dic
new file mode 100644
index 0000000000..51b0743d0e
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/phone.dic
@@ -0,0 +1,11 @@
+10
+Brasilia
+brassily
+Brazilian
+brilliance
+brilliancy
+brilliant
+brain
+brass
+Churchillian
+xxxxxxxxxx ph:Brasilia
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/phone.sug b/extensions/spellcheck/hunspell/tests/unit/data/phone.sug
new file mode 100644
index 0000000000..cc22e37984
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/phone.sug
@@ -0,0 +1 @@
+Brasilia, Xxxxxxxxxx, Brilliant, Brazilian, Brassily, Brilliance
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/phone.test b/extensions/spellcheck/hunspell/tests/unit/data/phone.test
new file mode 100644
index 0000000000..7f44369060
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/phone.test
@@ -0,0 +1,4 @@
+#!/bin/sh
+DIR="`dirname $0`"
+NAME="`basename $0 .test`"
+$DIR/test.sh $NAME
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/phone.wrong b/extensions/spellcheck/hunspell/tests/unit/data/phone.wrong
new file mode 100644
index 0000000000..ca9db395e3
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/phone.wrong
@@ -0,0 +1 @@
+Brasillian
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/rep.aff b/extensions/spellcheck/hunspell/tests/unit/data/rep.aff
new file mode 100644
index 0000000000..485755c898
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/rep.aff
@@ -0,0 +1,21 @@
+# With REP suggestions, we can fix typical language specific misspellings.
+
+# switch off ngram suggestion for testing
+MAXNGRAMSUGS 0
+
+REP 8
+REP f ph
+REP ph f
+REP shun$ tion
+REP ^alot$ a_lot # add the highest priority for "a lot" suggestion to "alot"
+REP ^foo$ bar
+REP ' _ # "un'alunno" -> "un alunno"
+REP ^vinten$ vinte_e_un
+REP s 's
+
+
+SFX A Y 1
+SFX A 0 's .
+
+
+WORDCHARS '
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/rep.dic b/extensions/spellcheck/hunspell/tests/unit/data/rep.dic
new file mode 100644
index 0000000000..f9a4c008b0
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/rep.dic
@@ -0,0 +1,15 @@
+10
+form
+phantom
+vacation
+vacations
+a
+lot
+un
+alunno
+bar
+barbars
+vinte
+e
+un
+auto/A
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/rep.sug b/extensions/spellcheck/hunspell/tests/unit/data/rep.sug
new file mode 100644
index 0000000000..b48a5b80eb
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/rep.sug
@@ -0,0 +1,8 @@
+form
+phantom
+vacation
+a lot, lot
+un alunno
+bar
+vinte e un
+auto's, auto
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/rep.test b/extensions/spellcheck/hunspell/tests/unit/data/rep.test
new file mode 100644
index 0000000000..dc295077fb
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/rep.test
@@ -0,0 +1,4 @@
+#!/bin/sh
+DIR="`dirname $0`"
+NAME="`basename $0 .test`"
+$DIR/test.sh $NAME -i ISO8859-1
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/rep.wrong b/extensions/spellcheck/hunspell/tests/unit/data/rep.wrong
new file mode 100644
index 0000000000..cd9699c4c7
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/rep.wrong
@@ -0,0 +1,11 @@
+phorm
+fantom
+vacashun
+vacashuns
+alot
+un'alunno
+foo
+foobars
+barfoos
+vinten
+autos
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/reputf.aff b/extensions/spellcheck/hunspell/tests/unit/data/reputf.aff
new file mode 100644
index 0000000000..ac434a4267
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/reputf.aff
@@ -0,0 +1,9 @@
+# With REP suggestions, we can fix typical language specific misspellings.
+
+SET UTF-8
+
+# switch off ngram suggestion for testing
+MAXNGRAMSUGS 0
+
+REP 1
+REP oo
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/reputf.dic b/extensions/spellcheck/hunspell/tests/unit/data/reputf.dic
new file mode 100644
index 0000000000..1890fcb8eb
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/reputf.dic
@@ -0,0 +1,2 @@
+1
+f
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/reputf.sug b/extensions/spellcheck/hunspell/tests/unit/data/reputf.sug
new file mode 100644
index 0000000000..8a00bc3717
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/reputf.sug
@@ -0,0 +1 @@
+f
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/reputf.test b/extensions/spellcheck/hunspell/tests/unit/data/reputf.test
new file mode 100644
index 0000000000..cde7c54109
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/reputf.test
@@ -0,0 +1,4 @@
+#!/bin/sh
+DIR="`dirname $0`"
+NAME="`basename $0 .test`"
+$DIR/test.sh $NAME -i utf-8
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/reputf.wrong b/extensions/spellcheck/hunspell/tests/unit/data/reputf.wrong
new file mode 100644
index 0000000000..257cc5642c
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/reputf.wrong
@@ -0,0 +1 @@
+foo
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/simplifiedtriple.aff b/extensions/spellcheck/hunspell/tests/unit/data/simplifiedtriple.aff
new file mode 100644
index 0000000000..3ab347319a
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/simplifiedtriple.aff
@@ -0,0 +1,8 @@
+# Forbid compound word with triple letters
+CHECKCOMPOUNDTRIPLE
+# Allow simplified forms
+SIMPLIFIEDTRIPLE
+
+COMPOUNDMIN 2
+
+COMPOUNDFLAG A
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/simplifiedtriple.dic b/extensions/spellcheck/hunspell/tests/unit/data/simplifiedtriple.dic
new file mode 100644
index 0000000000..cfe7a35dce
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/simplifiedtriple.dic
@@ -0,0 +1,3 @@
+2
+glass/A
+sko/A
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/simplifiedtriple.good b/extensions/spellcheck/hunspell/tests/unit/data/simplifiedtriple.good
new file mode 100644
index 0000000000..23a4815e8b
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/simplifiedtriple.good
@@ -0,0 +1,3 @@
+glass
+sko
+glassko
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/simplifiedtriple.test b/extensions/spellcheck/hunspell/tests/unit/data/simplifiedtriple.test
new file mode 100644
index 0000000000..7f44369060
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/simplifiedtriple.test
@@ -0,0 +1,4 @@
+#!/bin/sh
+DIR="`dirname $0`"
+NAME="`basename $0 .test`"
+$DIR/test.sh $NAME
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/simplifiedtriple.wrong b/extensions/spellcheck/hunspell/tests/unit/data/simplifiedtriple.wrong
new file mode 100644
index 0000000000..2811287685
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/simplifiedtriple.wrong
@@ -0,0 +1 @@
+glasssko
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/slash.aff b/extensions/spellcheck/hunspell/tests/unit/data/slash.aff
new file mode 100644
index 0000000000..6ab104b9ee
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/slash.aff
@@ -0,0 +1,4 @@
+# slashes in words (\/)
+
+# (only for tokenization)
+WORDCHARS /:
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/slash.dic b/extensions/spellcheck/hunspell/tests/unit/data/slash.dic
new file mode 100644
index 0000000000..478276df68
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/slash.dic
@@ -0,0 +1,5 @@
+4
+/
+1\/2
+http:\/\/
+\/usr\/share\/myspell\/
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/slash.good b/extensions/spellcheck/hunspell/tests/unit/data/slash.good
new file mode 100644
index 0000000000..4a25e205f6
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/slash.good
@@ -0,0 +1,4 @@
+/
+1/2
+http://
+/usr/share/myspell/
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/slash.test b/extensions/spellcheck/hunspell/tests/unit/data/slash.test
new file mode 100644
index 0000000000..7f44369060
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/slash.test
@@ -0,0 +1,4 @@
+#!/bin/sh
+DIR="`dirname $0`"
+NAME="`basename $0 .test`"
+$DIR/test.sh $NAME
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/sug.aff b/extensions/spellcheck/hunspell/tests/unit/data/sug.aff
new file mode 100644
index 0000000000..b1f2adba60
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/sug.aff
@@ -0,0 +1,15 @@
+# new suggestion methods of Hunspell 1.5:
+# capitalization: nasa -> NASA
+# long swap: permenant -> permanent
+# long mov: Ghandi -> Gandhi
+# double two characters: vacacation -> vacation
+# space with REP: "alot" -> "a lot" ("a lot" need to be in the dic file.)
+
+# switch off ngram suggestion for testing
+MAXNGRAMSUGS 0
+REP 1
+REP alot a_lot
+KEY qwertzuiop|asdfghjkl|yxcvbnm|aq
+WORDCHARS .
+FORBIDDENWORD ?
+
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/sug.dic b/extensions/spellcheck/hunspell/tests/unit/data/sug.dic
new file mode 100644
index 0000000000..0c22cedf42
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/sug.dic
@@ -0,0 +1,11 @@
+1
+NASA
+Gandhi
+grateful
+permanent
+vacation
+a
+lot
+have
+which
+McDonald
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/sug.sug b/extensions/spellcheck/hunspell/tests/unit/data/sug.sug
new file mode 100644
index 0000000000..e277bdb778
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/sug.sug
@@ -0,0 +1,12 @@
+NASA
+Gandhi
+grateful
+permanent
+vacation
+a lot, lot
+permanent. Vacation
+have
+which
+Gandhi
+McDonald
+permanent
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/sug.test b/extensions/spellcheck/hunspell/tests/unit/data/sug.test
new file mode 100644
index 0000000000..7f44369060
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/sug.test
@@ -0,0 +1,4 @@
+#!/bin/sh
+DIR="`dirname $0`"
+NAME="`basename $0 .test`"
+$DIR/test.sh $NAME
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/sug.wrong b/extensions/spellcheck/hunspell/tests/unit/data/sug.wrong
new file mode 100644
index 0000000000..4d184d5a61
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/sug.wrong
@@ -0,0 +1,12 @@
+nasa
+Ghandi
+greatful
+permenant
+vacacation
+alot
+permanent.Vacation
+ahev
+hwihc
+GAndhi
+Mcdonald
+permqnent
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/suggestiontest/List_of_common_misspellings.txt b/extensions/spellcheck/hunspell/tests/unit/data/suggestiontest/List_of_common_misspellings.txt
new file mode 100644
index 0000000000..571f3796a6
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/suggestiontest/List_of_common_misspellings.txt
@@ -0,0 +1,4020 @@
+# source: http://en.wikipedia.org/wiki/Wikipedia:Lists_of_common_misspellings/For_machines
+abandonned abandoned
+aberation aberration
+abilties abilities
+abilty ability
+abondon abandon
+abondoned abandoned
+abondoning abandoning
+abondons abandons
+aborigene aborigine
+abortificant abortifacient
+abreviated abbreviated
+abreviation abbreviation
+abritrary arbitrary
+absense absence
+absolutly absolutely
+absorbsion absorption
+absorbtion absorption
+abundacies abundances
+abundancies abundances
+abundunt abundant
+abutts abuts
+acadamy academy
+acadmic academic
+accademic academic
+accademy academy
+acccused accused
+accelleration acceleration
+accension accession, ascension
+acceptence acceptance
+acceptible acceptable
+accessable accessible
+accidentaly accidentally
+accidently accidentally
+acclimitization acclimatization
+acommodate accommodate
+accomadate accommodate
+accomadated accommodated
+accomadates accommodates
+accomadating accommodating
+accomadation accommodation
+accomadations accommodations
+accomdate accommodate
+accomodate accommodate
+accomodated accommodated
+accomodates accommodates
+accomodating accommodating
+accomodation accommodation
+accomodations accommodations
+accompanyed accompanied
+accordeon accordion
+accordian accordion
+accoring according
+accoustic acoustic
+accquainted acquainted
+accross across
+accussed accused
+acedemic academic
+acheive achieve
+acheived achieved
+acheivement achievement
+acheivements achievements
+acheives achieves
+acheiving achieving
+acheivment achievement
+acheivments achievements
+achievment achievement
+achievments achievements
+achive achieve, archive
+achived achieved, archived
+achivement achievement
+achivements achievements
+acknowldeged acknowledged
+acknowledgeing acknowledging
+ackward awkward, backward
+acomplish accomplish
+acomplished accomplished
+acomplishment accomplishment
+acomplishments accomplishments
+acording according
+acordingly accordingly
+acquaintence acquaintance
+acquaintences acquaintances
+acquiantence acquaintance
+acquiantences acquaintances
+acquited acquitted
+activites activities
+activly actively
+actualy actually
+acuracy accuracy
+acused accused
+acustom accustom
+acustommed accustomed
+adavanced advanced
+adbandon abandon
+additinally additionally
+additionaly additionally
+addmission admission
+addopt adopt
+addopted adopted
+addoptive adoptive
+addres address, adders
+addresable addressable
+addresed addressed
+addresing addressing
+addressess addresses
+addtion addition
+addtional additional
+adecuate adequate
+adhearing adhering
+adherance adherence
+admendment amendment
+admininistrative administrative
+adminstered administered
+adminstrate administrate
+adminstration administration
+adminstrative administrative
+adminstrator administrator
+admissability admissibility
+admissable admissible
+admited admitted
+admitedly admittedly
+adn and
+adolecent adolescent
+adquire acquire
+adquired acquired
+adquires acquires
+adquiring acquiring
+adres address
+adresable addressable
+adresing addressing
+adress address
+adressable addressable
+adressed addressed
+adressing addressing, dressing
+adventrous adventurous
+advertisment advertisement
+advertisments advertisements
+advesary adversary
+adviced advised
+aeriel aerial
+aeriels aerials
+afair affair
+afficianados aficionados
+afficionado aficionado
+afficionados aficionados
+affilate affiliate
+affilliate affiliate
+affort afford, effort
+aforememtioned aforementioned
+againnst against
+agains against
+agaisnt against
+aganist against
+aggaravates aggravates
+aggreed agreed
+aggreement agreement
+aggregious egregious
+aggresive aggressive
+agian again
+agianst against
+agin again
+agina again, angina
+aginst against
+agravate aggravate
+agre agree
+agred agreed
+agreeement agreement
+agreemnt agreement
+agregate aggregate
+agregates aggregates
+agreing agreeing
+agression aggression
+agressive aggressive
+agressively aggressively
+agressor aggressor
+agricuture agriculture
+agrieved aggrieved
+ahev have
+ahppen happen
+ahve have
+aicraft aircraft
+aiport airport
+airbourne airborne
+aircaft aircraft
+aircrafts aircraft
+airporta airports
+airrcraft aircraft
+aisian asian
+albiet albeit
+alchohol alcohol
+alchoholic alcoholic
+alchol alcohol
+alcholic alcoholic
+alcohal alcohol
+alcoholical alcoholic
+aledge allege
+aledged alleged
+aledges alleges
+alege allege
+aleged alleged
+alegience allegiance
+algebraical algebraic
+algorhitms algorithms
+algoritm algorithm
+algoritms algorithms
+alientating alienating
+alledge allege
+alledged alleged
+alledgedly allegedly
+alledges alleges
+allegedely allegedly
+allegedy allegedly
+allegely allegedly
+allegence allegiance
+allegience allegiance
+allign align
+alligned aligned
+alliviate alleviate
+allopone allophone
+allopones allophones
+allready already
+allthough although
+alltime all-time
+alltogether altogether
+almsot almost
+alochol alcohol
+alomst almost
+alot a lot, allot
+alotted allotted
+alowed allowed
+alowing allowing
+alreayd already
+alse else
+alsot also
+alternitives alternatives
+altho although
+althought although
+altough although
+alusion allusion, illusion
+alwasy always
+alwyas always
+amalgomated amalgamated
+amatuer amateur
+amature armature, amateur
+amendmant amendment
+amerliorate ameliorate
+amke make
+amking making
+ammend amend
+ammended amended
+ammendment amendment
+ammendments amendments
+ammount amount
+ammused amused
+amoung among
+amoungst amongst
+amung among
+analagous analogous
+analitic analytic
+analogeous analogous
+anarchim anarchism
+anarchistm anarchism
+anbd and
+ancestory ancestry
+ancilliary ancillary
+androgenous androgynous
+androgeny androgyny
+anihilation annihilation
+aniversary anniversary
+annoint anoint
+annointed anointed
+annointing anointing
+annoints anoints
+annouced announced
+annualy annually
+annuled annulled
+anohter another
+anomolies anomalies
+anomolous anomalous
+anomoly anomaly
+anonimity anonymity
+anounced announced
+ansalisation nasalisation
+ansalization nasalization
+ansestors ancestors
+antartic antarctic
+anthromorphization anthropomorphization
+anual annual, anal
+anulled annulled
+anwsered answered
+anyhwere anywhere
+anyother any other
+anytying anything
+aparent apparent
+aparment apartment
+apenines apennines, Apennines
+aplication application
+aplied applied
+apolegetics apologetics
+apon upon, apron
+apparant apparent
+apparantly apparently
+appart apart
+appartment apartment
+appartments apartments
+appealling appealing, appalling
+appeareance appearance
+appearence appearance
+appearences appearances
+appenines apennines, Apennines
+apperance appearance
+apperances appearances
+applicaiton application
+applicaitons applications
+appologies apologies
+appology apology
+apprearance appearance
+apprieciate appreciate
+approachs approaches
+appropiate appropriate
+appropraite appropriate
+appropropiate appropriate
+approproximate approximate
+approxamately approximately
+approxiately approximately
+approximitely approximately
+aprehensive apprehensive
+apropriate appropriate
+aproximate approximate
+aproximately approximately
+aquaintance acquaintance
+aquainted acquainted
+aquiantance acquaintance
+aquire acquire
+aquired acquired
+aquiring acquiring
+aquisition acquisition
+aquitted acquitted
+aranged arranged
+arangement arrangement
+arbitarily arbitrarily
+arbitary arbitrary
+archaelogists archaeologists
+archaelogy archaeology
+archaoelogy archeology, archaeology
+archaology archeology, archaeology
+archeaologist archeologist, archaeologist
+archeaologists archeologists, archaeologists
+archetect architect
+archetects architects
+archetectural architectural
+archetecturally architecturally
+archetecture architecture
+archiac archaic
+archictect architect
+archimedian archimedean
+architechturally architecturally
+architechture architecture
+architechtures architectures
+architectual architectural
+archtype archetype
+archtypes archetypes
+aready already
+areodynamics aerodynamics
+argubly arguably
+arguement argument
+arguements arguments
+arised arose
+arival arrival
+armamant armament
+armistace armistice
+aroud around
+arrangment arrangement
+arrangments arrangements
+arround around
+artical article
+artice article
+articel article
+artifical artificial
+artifically artificially
+artillary artillery
+arund around
+asetic ascetic
+asign assign
+aslo also
+asociated associated
+asorbed absorbed
+asphyxation asphyxiation
+assasin assassin
+assasinate assassinate
+assasinated assassinated
+assasinates assassinates
+assasination assassination
+assasinations assassinations
+assasined assassinated
+assasins assassins
+assassintation assassination
+assemple assemble
+assertation assertion
+asside aside
+assisnate assassinate
+assit assist
+assitant assistant
+assocation association
+assoicate associate
+assoicated associated
+assoicates associates
+assosication assassination
+asssassans assassins
+assualt assault
+assualted assaulted
+assymetric asymmetric
+assymetrical asymmetrical
+asteriod asteroid
+asthetic aesthetic
+asthetical aesthetical
+asthetically aesthetically
+asume assume
+aswell as well
+atain attain
+atempting attempting
+atheistical atheistic
+athenean athenian
+atheneans athenians
+athiesm atheism
+athiest atheist
+atorney attorney
+atribute attribute
+atributed attributed
+atributes attributes
+attaindre attainder, attained
+attemp attempt
+attemped attempted
+attemt attempt
+attemted attempted
+attemting attempting
+attemts attempts
+attendence attendance
+attendent attendant
+attendents attendants
+attened attended
+attension attention
+attitide attitude
+attributred attributed
+attrocities atrocities
+audeince audience
+auromated automated
+austrailia Australia
+austrailian Australian
+auther author
+authobiographic autobiographic
+authobiography autobiography
+authorative authoritative
+authorites authorities
+authorithy authority
+authoritiers authorities
+authoritive authoritative
+authrorities authorities
+autochtonous autochthonous
+autoctonous autochthonous
+automaticly automatically
+automibile automobile
+automonomous autonomous
+autor author
+autority authority
+auxilary auxiliary
+auxillaries auxiliaries
+auxillary auxiliary
+auxilliaries auxiliaries
+auxilliary auxiliary
+availablity availability
+availaible available
+availble available
+availiable available
+availible available
+avalable available
+avalance avalanche
+avaliable available
+avation aviation
+avengence a vengeance
+averageed averaged
+avilable available
+awared awarded
+awya away
+baceause because
+backgorund background
+backrounds backgrounds
+bakc back
+banannas bananas
+bandwith bandwidth
+bankrupcy bankruptcy
+banruptcy bankruptcy
+baout about, bout
+basicaly basically
+basicly basically
+bcak back
+beachead beachhead
+beacuse because
+beastiality bestiality
+beatiful beautiful
+beaurocracy bureaucracy
+beaurocratic bureaucratic
+beautyfull beautiful
+becamae became
+becasue because
+beccause because
+becomeing becoming
+becomming becoming
+becouse because
+becuase because
+bedore before
+befoer before
+beggin begin, begging
+begginer beginner
+begginers beginners
+beggining beginning
+begginings beginnings
+beggins begins
+begining beginning
+beginnig beginning
+behavour behavior, behaviour
+beleagured beleaguered
+beleif belief
+beleive believe
+beleived believed
+beleives believes
+beleiving believing
+beligum belgium
+belive believe
+belived believed
+belives believes, beliefs
+belligerant belligerent
+bellweather bellwether
+bemusemnt bemusement
+beneficary beneficiary
+beng being
+benificial beneficial
+benifit benefit
+benifits benefits
+bergamont bergamot
+Bernouilli Bernoulli
+beseige besiege
+beseiged besieged
+beseiging besieging
+betwen between
+beween between
+bewteen between
+bilateraly bilaterally
+billingualism bilingualism
+binominal binomial
+bizzare bizarre
+blaim blame
+blaimed blamed
+blessure blessing
+Blitzkreig Blitzkrieg
+boaut bout, boat, about
+bodydbuilder bodybuilder
+bombardement bombardment
+bombarment bombardment
+bondary boundary
+Bonnano Bonanno
+borke broke
+boundry boundary
+bouyancy buoyancy
+bouyant buoyant
+boyant buoyant
+Brasillian Brazilian
+breakthough breakthrough
+breakthroughts breakthroughs
+breif brief
+breifly briefly
+brethen brethren
+bretheren brethren
+briliant brilliant
+brillant brilliant
+brimestone brimstone
+Britian Britain
+Brittish British
+broacasted broadcast
+broadacasting broadcasting
+broady broadly
+Buddah Buddha
+buisness business
+buisnessman businessman
+buoancy buoyancy
+buring burying, burning, burin, during
+burried buried
+busineses business, businesses
+busness business
+bussiness business
+cacuses caucuses
+cahracters characters
+calaber caliber
+calander calendar, calender, colander
+calculs calculus
+calenders calendars
+caligraphy calligraphy
+caluclate calculate
+caluclated calculated
+caluculate calculate
+caluculated calculated
+calulate calculate
+calulated calculated
+Cambrige Cambridge
+camoflage camouflage
+campain campaign
+campains campaigns
+candadate candidate
+candiate candidate
+candidiate candidate
+cannister canister
+cannisters canisters
+cannnot cannot
+cannonical canonical
+cannotation connotation
+cannotations connotations
+cant cannot, can not, can't
+caost coast
+caperbility capability
+Capetown Cape Town
+capible capable
+captial capital
+captued captured
+capturd captured
+carachter character
+caracterized characterized
+carcas carcass, Caracas
+carefull careful
+careing caring
+carismatic charismatic
+Carmalite Carmelite
+carmel caramel, carmel-by-the-sea
+carniverous carnivorous
+carreer career
+carrers careers
+Carribbean Caribbean
+Carribean Caribbean
+cartdridge cartridge
+Carthagian Carthaginian
+carthographer cartographer
+cartilege cartilage
+cartilidge cartilage
+cartrige cartridge
+casette cassette
+casion caisson
+cassawory cassowary
+cassowarry cassowary
+casulaties casualties
+casulaty casualty
+catagories categories
+catagorized categorized
+catagory category
+catergorize categorize
+catergorized categorized
+Cataline Catiline, Catalina
+cathlic catholic
+catholocism catholicism
+catterpilar caterpillar
+catterpilars caterpillars
+cattleship battleship
+causalities casualties
+Ceasar Caesar
+Celcius Celsius
+cellpading cellpadding
+cementary cemetery
+cemetarey cemetery
+cemetaries cemeteries
+cemetary cemetery
+cencus census
+censur censor, censure
+cententenial centennial
+centruies centuries
+centruy century
+ceratin certain, keratin
+cerimonial ceremonial
+cerimonies ceremonies
+cerimonious ceremonious
+cerimony ceremony
+ceromony ceremony
+certainity certainty
+certian certain
+cervial cervical, servile, serval
+chalenging challenging
+challange challenge
+challanged challenged
+challege challenge
+Champange Champagne
+changable changeable
+charachter character
+charactor character
+charachters characters
+charactersistic characteristic
+charactors characters
+charasmatic charismatic
+charaterized characterized
+chariman chairman
+charistics characteristics
+chasr chaser, chase
+cheif chief
+chemcial chemical
+chemcially chemically
+chemestry chemistry
+chemicaly chemically
+childbird childbirth
+childen children
+choosen chosen
+chracter character
+chuch church
+churchs churches
+Cincinatti Cincinnati
+Cincinnatti Cincinnati
+circulaton circulation
+circumsicion circumcision
+circut circuit
+ciricuit circuit
+ciriculum curriculum
+civillian civilian
+claer clear
+claerer clearer
+claerly clearly
+claimes claims
+clas class
+clasic classic
+clasical classical
+clasically classically
+cleareance clearance
+clera clear, sclera
+clincial clinical
+clinicaly clinically
+cmo com
+cmoputer computer
+co-incided coincided
+coctail cocktail
+coform conform
+cognizent cognizant
+coincedentally coincidentally
+colaborations collaborations
+colateral collateral
+colelctive collective
+collaberative collaborative
+collecton collection
+collegue colleague
+collegues colleagues
+collonade colonnade
+collonies colonies
+collony colony
+collosal colossal
+colonizators colonizers
+comander commander, commandeer
+comando commando
+comandos commandos
+comany company
+comapany company
+comback comeback
+combanations combinations
+combinatins combinations
+combusion combustion
+comdemnation condemnation
+comemmorates commemorates
+comemoretion commemoration
+comision commission
+comisioned commissioned
+comisioner commissioner
+comisioning commissioning
+comisions commissions
+comission commission
+comissioned commissioned
+comissioner commissioner
+comissioning commissioning
+comissions commissions
+comited committed
+comiting committing
+comitted committed
+comittee committee
+comitting committing
+commandoes commandos
+commedic comedic
+commemerative commemorative
+commemmorate commemorate
+commemmorating commemorating
+commerical commercial
+commerically commercially
+commericial commercial
+commericially commercially
+commerorative commemorative
+comming coming
+comminication communication
+commision commission
+commisioned commissioned
+commisioner commissioner
+commisioning commissioning
+commisions commissions
+commited committed
+commitee committee
+commiting committing
+committe committee
+committment commitment
+committments commitments
+commmemorated commemorated
+commongly commonly
+commonweath commonwealth
+commuications communications
+commuinications communications
+communciation communication
+communiation communication
+communites communities
+compability compatibility
+comparision comparison
+comparisions comparisons
+comparitive comparative
+comparitively comparatively
+compatabilities compatibilities
+compatability compatibility
+compatable compatible
+compatablities compatibilities
+compatablity compatibility
+compatiable compatible
+compatiblities compatibilities
+compatiblity compatibility
+compeitions competitions
+compensantion compensation
+competance competence
+competant competent
+competative competitive
+competion competition, completion
+competitiion competition
+competive competitive
+competiveness competitiveness
+comphrehensive comprehensive
+compitent competent
+completedthe completed the
+completelyl completely
+completetion completion
+complier compiler
+componant component
+comprable comparable
+comprimise compromise
+compulsary compulsory
+compulsery compulsory
+computarized computerized
+concensus consensus
+concider consider
+concidered considered
+concidering considering
+conciders considers
+concieted conceited
+concieved conceived
+concious conscious
+conciously consciously
+conciousness consciousness
+condamned condemned
+condemmed condemned
+condidtion condition
+condidtions conditions
+conditionsof conditions of
+conected connected
+conection connection
+conesencus consensus
+confidental confidential
+confidentally confidentially
+confids confides
+configureable configurable
+confortable comfortable
+congradulations congratulations
+congresional congressional
+conived connived
+conjecutre conjecture
+conjuction conjunction
+Conneticut Connecticut
+conotations connotations
+conquerd conquered
+conquerer conqueror
+conquerers conquerors
+conqured conquered
+conscent consent
+consciouness consciousness
+consdider consider
+consdidered considered
+consdiered considered
+consectutive consecutive
+consenquently consequently
+consentrate concentrate
+consentrated concentrated
+consentrates concentrates
+consept concept
+consequentually consequently
+consequeseces consequences
+consern concern
+conserned concerned
+conserning concerning
+conservitive conservative
+consiciousness consciousness
+consicousness consciousness
+considerd considered
+consideres considered
+consious conscious
+consistant consistent
+consistantly consistently
+consituencies constituencies
+consituency constituency
+consituted constituted
+consitution constitution
+consitutional constitutional
+consolodate consolidate
+consolodated consolidated
+consonent consonant
+consonents consonants
+consorcium consortium
+conspiracys conspiracies
+conspiriator conspirator
+constaints constraints
+constanly constantly
+constarnation consternation
+constatn constant
+constinually continually
+constituant constituent
+constituants constituents
+constituion constitution
+constituional constitutional
+consttruction construction
+constuction construction
+consulant consultant
+consumate consummate
+consumated consummated
+contaiminate contaminate
+containes contains
+contamporaries contemporaries
+contamporary contemporary
+contempoary contemporary
+contemporaneus contemporaneous
+contempory contemporary
+contendor contender
+contined continued
+continous continuous
+continously continuously
+continueing continuing
+contravercial controversial
+contraversy controversy
+contributer contributor
+contributers contributors
+contritutions contributions
+controled controlled
+controling controlling
+controll control
+controlls controls
+controvercial controversial
+controvercy controversy
+controveries controversies
+controversal controversial
+controversey controversy
+controvertial controversial
+controvery controversy
+contruction construction
+conveinent convenient
+convenant covenant
+convential conventional
+convertables convertibles
+convertion conversion
+conveyer conveyor
+conviced convinced
+convienient convenient
+coordiantion coordination
+coorperation cooperation, corporation
+coorperations corporations
+copmetitors competitors
+coputer computer
+copywrite copyright
+coridal cordial
+cornmitted committed
+corosion corrosion
+corparate corporate
+corperations corporations
+correcters correctors
+correponding corresponding
+correposding corresponding
+correspondant correspondent
+correspondants correspondents
+corridoors corridors
+corrispond correspond
+corrispondant correspondent
+corrispondants correspondents
+corrisponded corresponded
+corrisponding corresponding
+corrisponds corresponds
+costitution constitution
+coucil council
+coudl could, cloud
+councellor councillor, counselor, councilor
+councellors councillors, counselors, councilors
+counries countries
+countains contains
+countires countries
+coururier courier, couturier
+coverted converted, covered, coveted
+cpoy coy, copy
+creaeted created
+creedence credence
+critereon criterion
+criterias criteria
+criticists critics
+critising criticising, criticizing
+critisising criticising
+critisism criticism
+critisisms criticisms
+critisize criticise, criticize
+critisized criticised, criticized
+critisizes criticises, criticizes
+critisizing criticising, criticizing
+critized criticized
+critizing criticizing
+crockodiles crocodiles
+crowm crown
+crtical critical
+crticised criticised
+crucifiction crucifixion
+crusies cruises
+crystalisation crystallisation
+culiminating culminating
+cumulatative cumulative
+curch church
+curcuit circuit
+currenly currently
+curriculem curriculum
+cxan cyan
+cyclinder cylinder
+dael deal, dial, dahl
+dalmation dalmatian
+damenor demeanor
+Dardenelles Dardanelles
+dacquiri daiquiri
+debateable debatable
+decendant descendant
+decendants descendants
+decendent descendant
+decendents descendants
+decideable decidable
+decidely decidedly
+decieved deceived
+decison decision
+decomissioned decommissioned
+decomposit decompose
+decomposited decomposed
+decompositing decomposing
+decomposits decomposes
+decress decrees
+decribe describe
+decribed described
+decribes describes
+decribing describing
+dectect detect
+defendent defendant
+defendents defendants
+deffensively defensively
+deffine define
+deffined defined
+definance defiance
+definate definite
+definately definitely
+definatly definitely
+definetly definitely
+definining defining
+definit definite
+definitly definitely
+definiton definition
+defintion definition
+degrate degrade
+delagates delegates
+delapidated dilapidated
+delerious delirious
+delevopment development
+deliberatly deliberately
+delusionally delusively
+demenor demeanor
+demographical demographic
+demolision demolition
+demorcracy democracy
+demostration demonstration
+denegrating denigrating
+densly densely
+deparment department
+deparments departments
+deparmental departmental
+dependance dependence
+dependancy dependency
+dependant dependent
+deram dram, dream
+deriviated derived
+derivitive derivative
+derogitory derogatory
+descendands descendants
+descibed described
+descision decision
+descisions decisions
+descriibes describes
+descripters descriptors
+descripton description
+desctruction destruction
+descuss discuss
+desgined designed
+deside decide
+desigining designing
+desinations destinations
+desintegrated disintegrated
+desintegration disintegration
+desireable desirable
+desitned destined
+desktiop desktop
+desorder disorder
+desoriented disoriented
+desparate desperate, disparate
+despatched dispatched
+despict depict
+despiration desperation
+dessicated desiccated
+dessigned designed
+destablized destabilized
+destory destroy
+detailled detailed
+detatched detached
+deteoriated deteriorated
+deteriate deteriorate
+deterioriating deteriorating
+determinining determining
+detremental detrimental
+devasted devastated
+develope develop
+developement development
+developped developed
+develpment development
+devels delves
+devestated devastated
+devestating devastating
+devide divide
+devided divided
+devistating devastating
+devolopement development
+diablical diabolical
+diamons diamonds
+diaster disaster
+dichtomy dichotomy
+diconnects disconnects
+dicover discover
+dicovered discovered
+dicovering discovering
+dicovers discovers
+dicovery discovery
+dicussed discussed
+didnt didn't
+diea idea, die
+dieing dying, dyeing
+dieties deities
+diety deity
+diferent different
+diferrent different
+differentiatiations differentiations
+differnt different
+difficulity difficulty
+diffrent different
+dificulties difficulties
+dificulty difficulty
+dimenions dimensions
+dimention dimension
+dimentional dimensional
+dimentions dimensions
+dimesnional dimensional
+diminuitive diminutive
+diosese diocese
+diphtong diphthong
+diphtongs diphthongs
+diplomancy diplomacy
+dipthong diphthong
+dipthongs diphthongs
+dirived derived
+disagreeed disagreed
+disapeared disappeared
+disapointing disappointing
+disappearred disappeared
+disaproval disapproval
+disasterous disastrous
+disatisfaction dissatisfaction
+disatisfied dissatisfied
+disatrous disastrous
+discontentment discontent
+discribe describe
+discribed described
+discribes describes
+discribing describing
+disctinction distinction
+disctinctive distinctive
+disemination dissemination
+disenchanged disenchanted
+disiplined disciplined
+disobediance disobedience
+disobediant disobedient
+disolved dissolved
+disover discover
+dispair despair
+disparingly disparagingly
+dispence dispense
+dispenced dispensed
+dispencing dispensing
+dispicable despicable
+dispite despite
+dispostion disposition
+disproportiate disproportionate
+disputandem disputandum
+disricts districts
+dissagreement disagreement
+dissapear disappear
+dissapearance disappearance
+dissapeared disappeared
+dissapearing disappearing
+dissapears disappears
+dissappear disappear
+dissappears disappears
+dissappointed disappointed
+dissarray disarray
+dissobediance disobedience
+dissobediant disobedient
+dissobedience disobedience
+dissobedient disobedient
+distiction distinction
+distingish distinguish
+distingished distinguished
+distingishes distinguishes
+distingishing distinguishing
+distingquished distinguished
+distrubution distribution
+distruction destruction
+distructive destructive
+ditributed distributed
+diversed diverse, diverged
+divice device
+divison division
+divisons divisions
+doccument document
+doccumented documented
+doccuments documents
+docrines doctrines
+doctines doctrines
+documenatry documentary
+doens does
+doesnt doesn't
+doign doing
+dominaton domination
+dominent dominant
+dominiant dominant
+donig doing
+dosen't doesn't
+doub doubt, daub
+doulbe double
+dowloads downloads
+dramtic dramatic
+draughtman draughtsman
+Dravadian Dravidian
+dreasm dreams
+driectly directly
+drnik drink
+druming drumming
+drummless drumless
+dupicate duplicate
+durig during
+durring during
+duting during
+dyas dryas
+eahc each
+ealier earlier
+earlies earliest
+earnt earned
+ecclectic eclectic
+eceonomy economy
+ecidious deciduous
+eclispe eclipse
+ecomonic economic
+ect etc
+eearly early
+efel evil
+effeciency efficiency
+effecient efficient
+effeciently efficiently
+efficency efficiency
+efficent efficient
+efficently efficiently
+efford effort, afford
+effords efforts, affords
+effulence effluence
+eigth eighth, eight
+eiter either
+elction election
+electic eclectic, electric
+electon election, electron
+electrial electrical
+electricly electrically
+electricty electricity
+elementay elementary
+eleminated eliminated
+eleminating eliminating
+eles eels
+eletricity electricity
+elicided elicited
+eligable eligible
+elimentary elementary
+ellected elected
+elphant elephant
+embarass embarrass
+embarassed embarrassed
+embarassing embarrassing
+embarassment embarrassment
+embargos embargoes
+embarras embarrass
+embarrased embarrassed
+embarrasing embarrassing
+embarrasment embarrassment
+embezelled embezzled
+emblamatic emblematic
+eminate emanate
+eminated emanated
+emision emission
+emited emitted
+emiting emitting
+emition emission, emotion
+emmediately immediately
+emmigrated emigrated
+emminent eminent, imminent
+emminently eminently
+emmisaries emissaries
+emmisarries emissaries
+emmisarry emissary
+emmisary emissary
+emmision emission
+emmisions emissions
+emmited emitted
+emmiting emitting
+emmitted emitted
+emmitting emitting
+emnity enmity
+emperical empirical
+emphaised emphasised
+emphsis emphasis
+emphysyma emphysema
+empirial empirical, imperial
+emprisoned imprisoned
+enameld enameled
+enchancement enhancement
+encouraing encouraging
+encryptiion encryption
+encylopedia encyclopedia
+endevors endeavors
+endevour endeavour
+endig ending
+endolithes endoliths
+enduce induce
+ened need
+enflamed inflamed
+enforceing enforcing
+engagment engagement
+engeneer engineer
+engeneering engineering
+engieneer engineer
+engieneers engineers
+enlargment enlargement
+enlargments enlargements
+Enlish English, enlist
+enourmous enormous
+enourmously enormously
+ensconsed ensconced
+entaglements entanglements
+enteratinment entertainment
+entitity entity
+entitlied entitled
+entrepeneur entrepreneur
+entrepeneurs entrepreneurs
+enviorment environment
+enviormental environmental
+enviormentally environmentally
+enviorments environments
+enviornment environment
+enviornmental environmental
+enviornmentalist environmentalist
+enviornmentally environmentally
+enviornments environments
+enviroment environment
+enviromental environmental
+enviromentalist environmentalist
+enviromentally environmentally
+enviroments environments
+envolutionary evolutionary
+envrionments environments
+enxt next
+epidsodes episodes
+epsiode episode
+equialent equivalent
+equilibium equilibrium
+equilibrum equilibrium
+equiped equipped
+equippment equipment
+equitorial equatorial
+equivelant equivalent
+equivelent equivalent
+equivilant equivalent
+equivilent equivalent
+equivlalent equivalent
+erally orally, really
+eratic erratic
+eratically erratically
+eraticly erratically
+erested arrested, erected
+errupted erupted
+esential essential
+esitmated estimated
+esle else
+especialy especially
+essencial essential
+essense essence
+essentail essential
+essentialy essentially
+essentual essential
+essesital essential
+estabishes establishes
+establising establishing
+ethnocentricm ethnocentrism
+ethose those, ethos
+Europian European
+Europians Europeans
+Eurpean European
+Eurpoean European
+evenhtually eventually
+eventally eventually
+eventially eventually
+eventualy eventually
+everthing everything
+everytime every time
+everyting everything
+eveyr every
+evidentally evidently
+exagerate exaggerate
+exagerated exaggerated
+exagerates exaggerates
+exagerating exaggerating
+exagerrate exaggerate
+exagerrated exaggerated
+exagerrates exaggerates
+exagerrating exaggerating
+examinated examined
+exampt exempt
+exapansion expansion
+excact exact
+excange exchange
+excecute execute
+excecuted executed
+excecutes executes
+excecuting executing
+excecution execution
+excedded exceeded
+excelent excellent
+excell excel
+excellance excellence
+excellant excellent
+excells excels
+excercise exercise
+exchanching exchanging
+excisted existed
+exculsivly exclusively
+execising exercising
+exection execution
+exectued executed
+exeedingly exceedingly
+exelent excellent
+exellent excellent
+exemple example
+exept except
+exeptional exceptional
+exerbate exacerbate
+exerbated exacerbated
+exerciese exercises
+exerpt excerpt
+exerpts excerpts
+exersize exercise
+exerternal external
+exhalted exalted
+exhibtion exhibition
+exibition exhibition
+exibitions exhibitions
+exicting exciting
+exinct extinct
+existance existence
+existant existent
+existince existence
+exliled exiled
+exludes excludes
+exmaple example
+exonorate exonerate
+exoskelaton exoskeleton
+expalin explain
+expeced expected
+expecially especially
+expeditonary expeditionary
+expeiments experiments
+expell expel
+expells expels
+experiance experience
+experianced experienced
+expiditions expeditions
+expierence experience
+explaination explanation
+explaning explaining
+explictly explicitly
+exploititive exploitative
+explotation exploitation
+expropiated expropriated
+expropiation expropriation
+exressed expressed
+extemely extremely
+extention extension
+extentions extensions
+extered exerted
+extermist extremist
+extint extinct, extant
+extradiction extradition
+extraterrestial extraterrestrial
+extraterrestials extraterrestrials
+extravagent extravagant
+extrememly extremely
+extremeophile extremophile
+extremly extremely
+extrordinarily extraordinarily
+extrordinary extraordinary
+eyar year, eyas
+eyars years, eyas
+eyasr years, eyas
+faciliate facilitate
+faciliated facilitated
+faciliates facilitates
+facilites facilities
+facillitate facilitate
+facinated fascinated
+facist fascist
+familes families
+familliar familiar
+famoust famous
+fanatism fanaticism
+Farenheit Fahrenheit
+fatc fact
+faught fought
+favoutrable favourable
+feasable feasible
+Febuary February
+fedreally federally
+feromone pheromone
+fertily fertility
+fianite finite
+fianlly finally
+ficticious fictitious
+fictious fictitious
+fidn find
+fiel feel, field, file, phial
+fiels feels, fields, files, phials
+fiercly fiercely
+fightings fighting
+filiament filament
+fimilies families
+finacial financial
+finaly finally
+financialy financially
+firends friends
+firts flirts, first
+fisionable fissionable
+flamable flammable
+flawess flawless
+fleed fled, freed
+Flemmish Flemish
+florescent fluorescent
+flourescent fluorescent
+fluorish flourish
+follwoing following
+folowing following
+fomed formed
+fomr from, form
+fonetic phonetic
+fontrier fontier
+foootball football
+forbad forbade
+forbiden forbidden
+foreward foreword
+forfiet forfeit
+forhead forehead
+foriegn foreign
+Formalhaut Fomalhaut
+formallize formalize
+formallized formalized
+formaly formally
+formelly formerly
+formidible formidable
+formost foremost
+forsaw foresaw
+forseeable foreseeable
+fortelling foretelling
+forunner forerunner
+foucs focus
+foudn found
+fougth fought
+foundaries foundries
+foundary foundry
+Foundland Newfoundland
+fourties forties
+fourty forty
+fouth fourth
+foward forward
+fucntion function
+fucntioning functioning
+Fransiscan Franciscan
+Fransiscans Franciscans
+freind friend
+freindly friendly
+frequentily frequently
+frome from
+fromed formed
+froniter frontier
+fufill fulfill
+fufilled fulfilled
+fulfiled fulfilled
+fundametal fundamental
+fundametals fundamentals
+funguses fungi
+funtion function
+furuther further
+futher further
+futhermore furthermore
+futhroc futhark, futhorc
+gae game, Gael, gale
+galatic galactic
+Galations Galatians
+gallaxies galaxies
+galvinized galvanized
+Gameboy Game Boy
+ganerate generate
+ganes games
+ganster gangster
+garantee guarantee
+garanteed guaranteed
+garantees guarantees
+garnison garrison
+gauarana guaran叩
+gaurantee guarantee
+gauranteed guaranteed
+gaurantees guarantees
+gaurd guard, gourd
+gaurentee guarantee
+gaurenteed guaranteed
+gaurentees guarantees
+geneological genealogical
+geneologies genealogies
+geneology genealogy
+generaly generally
+generatting generating
+genialia genitalia
+geographicial geographical
+geometrician geometer
+geometricians geometers
+gerat great
+Ghandi Gandhi
+glight flight
+gnawwed gnawed
+godess goddess
+godesses goddesses
+Godounov Godunov
+gogin going, Gauguin
+goign going
+gonig going
+Gothenberg Gothenburg
+Gottleib Gottlieb
+gouvener governor
+govement government
+govenment government
+govenrment government
+goverance governance
+goverment government
+govermental governmental
+governer governor
+governmnet government
+govorment government
+govormental governmental
+govornment government
+gracefull graceful
+graet great
+grafitti graffiti
+gramatically grammatically
+grammaticaly grammatically
+grammer grammar
+grat great
+gratuitious gratuitous
+greatful grateful
+greatfully gratefully
+greif grief
+gridles griddles
+gropu group
+grwo grow
+Guaduloupe Guadalupe, Guadeloupe
+Guadulupe Guadalupe, Guadeloupe
+guage gauge
+guarentee guarantee
+guarenteed guaranteed
+guarentees guarantees
+Guatamala Guatemala
+Guatamalan Guatemalan
+guerilla guerrilla
+guerillas guerrillas
+guerrila guerrilla
+guerrilas guerrillas
+guidence guidance
+Guilia Giulia
+Guilio Giulio
+Guiness Guinness
+Guiseppe Giuseppe
+gunanine guanine
+gurantee guarantee
+guranteed guaranteed
+gurantees guarantees
+guttaral guttural
+gutteral guttural
+habaeus habeas
+habeus habeas
+Habsbourg Habsburg
+haemorrage haemorrhage
+haev have, heave
+Hallowean Hallowe'en, Halloween
+halp help
+hapen happen
+hapened happened
+hapening happening
+happend happened
+happended happened
+happenned happened
+harased harassed
+harases harasses
+harasment harassment
+harasments harassments
+harassement harassment
+harras harass
+harrased harassed
+harrases harasses
+harrasing harassing
+harrasment harassment
+harrasments harassments
+harrassed harassed
+harrasses harassed
+harrassing harassing
+harrassment harassment
+harrassments harassments
+hasnt hasn't
+haviest heaviest
+headquater headquarter
+headquarer headquarter
+headquatered headquartered
+headquaters headquarters
+healthercare healthcare
+heared heard
+heathy healthy
+Heidelburg Heidelberg
+heigher higher
+heirarchy hierarchy
+heiroglyphics hieroglyphics
+helment helmet
+helpfull helpful
+helpped helped
+hemmorhage hemorrhage
+herad heard, Hera
+heridity heredity
+heroe hero
+heros heroes
+hertzs hertz
+hesistant hesitant
+heterogenous heterogeneous
+hieght height
+hierachical hierarchical
+hierachies hierarchies
+hierachy hierarchy
+hierarcical hierarchical
+hierarcy hierarchy
+hieroglph hieroglyph
+hieroglphs hieroglyphs
+higer higher
+higest highest
+higway highway
+hillarious hilarious
+himselv himself
+hinderance hindrance
+hinderence hindrance
+hindrence hindrance
+hipopotamus hippopotamus
+hismelf himself
+histocompatability histocompatibility
+historicians historians
+hitsingles hit singles
+holliday holiday
+homestate home state
+homogeneize homogenize
+homogeneized homogenized
+honory honorary
+horrifing horrifying
+hosited hoisted
+hospitible hospitable
+hounour honour
+housr hours, house
+howver however
+hsitorians historians
+hstory history
+hten then, hen, the
+htere there, here
+htey they
+htikn think
+hting thing
+htink think
+htis this
+humer humor, humour
+humerous humorous, humerus
+huminoid humanoid
+humoural humoral
+humurous humorous
+husban husband
+hvae have
+hvaing having
+hvea have, heave
+hwihc which
+hwile while
+hwole whole
+hydogen hydrogen
+hydropile hydrophile
+hydropilic hydrophilic
+hydropobe hydrophobe
+hydropobic hydrophobic
+hygeine hygiene
+hypocracy hypocrisy
+hypocrasy hypocrisy
+hypocricy hypocrisy
+hypocrit hypocrite
+hypocrits hypocrites
+iconclastic iconoclastic
+idaeidae idea
+idaes ideas
+idealogies ideologies
+idealogy ideology
+identicial identical
+identifers identifiers
+ideosyncratic idiosyncratic
+idesa ideas, ides
+idiosyncracy idiosyncrasy
+Ihaca Ithaca
+illegimacy illegitimacy
+illegitmate illegitimate
+illess illness
+illiegal illegal
+illution illusion
+ilness illness
+ilogical illogical
+imagenary imaginary
+imagin imagine
+imaginery imaginary, imagery
+imanent eminent, imminent
+imcomplete incomplete
+imediately immediately
+imense immense
+imigrant emigrant, immigrant
+imigrated emigrated, immigrated
+imigration emigration, immigration
+iminent eminent, imminent, immanent
+immediatley immediately
+immediatly immediately
+immidately immediately
+immidiately immediately
+immitate imitate
+immitated imitated
+immitating imitating
+immitator imitator
+immunosupressant immunosuppressant
+impecabbly impeccably
+impedence impedance
+implamenting implementing
+impliment implement
+implimented implemented
+imploys employs
+importamt important
+imprioned imprisoned
+imprisonned imprisoned
+improvision improvisation
+improvments improvements
+inablility inability
+inaccessable inaccessible
+inadiquate inadequate
+inadquate inadequate
+inadvertant inadvertent
+inadvertantly inadvertently
+inagurated inaugurated
+inaguration inauguration
+inappropiate inappropriate
+inaugures inaugurates
+inbalance imbalance
+inbalanced imbalanced
+inbetween between
+incarcirated incarcerated
+incidentially incidentally
+incidently incidentally
+inclreased increased
+includ include
+includng including
+incompatabilities incompatibilities
+incompatability incompatibility
+incompatable incompatible
+incompatablities incompatibilities
+incompatablity incompatibility
+incompatiblities incompatibilities
+incompatiblity incompatibility
+incompetance incompetence
+incompetant incompetent
+incomptable incompatible
+incomptetent incompetent
+inconsistant inconsistent
+incorperation incorporation
+incorportaed incorporated
+incorprates incorporates
+incorruptable incorruptible
+incramentally incrementally
+increadible incredible
+incredable incredible
+inctroduce introduce
+inctroduced introduced
+incuding including
+incunabla incunabula
+indefinately indefinitely
+indefineable undefinable
+indefinitly indefinitely
+indentical identical
+indepedantly independently
+indepedence independence
+independance independence
+independant independent
+independantly independently
+independece independence
+independendet independent
+indictement indictment
+indigineous indigenous
+indipendence independence
+indipendent independent
+indipendently independently
+indespensible indispensable
+indespensable indispensable
+indispensible indispensable
+indisputible indisputable
+indisputibly indisputably
+indite indict
+individualy individually
+indpendent independent
+indpendently independently
+indulgue indulge
+indutrial industrial
+indviduals individuals
+inefficienty inefficiently
+inevatible inevitable
+inevitible inevitable
+inevititably inevitably
+infalability infallibility
+infallable infallible
+infectuous infectious
+infered inferred
+infilitrate infiltrate
+infilitrated infiltrated
+infilitration infiltration
+infinit infinite
+inflamation inflammation
+influencial influential
+influented influenced
+infomation information
+informtion information
+infrantryman infantryman
+infrigement infringement
+ingenius ingenious
+ingreediants ingredients
+inhabitans inhabitants
+inherantly inherently
+inheritage heritage, inheritance
+inheritence inheritance
+inital initial
+initally initially
+initation initiation
+initiaitive initiative
+inlcuding including
+inmigrant immigrant
+inmigrants immigrants
+innoculated inoculated
+inocence innocence
+inofficial unofficial
+inot into
+inpeach impeach
+inpolite impolite
+inprisonment imprisonment
+inproving improving
+insectiverous insectivorous
+insensative insensitive
+inseperable inseparable
+insistance insistence
+insitution institution
+insitutions institutions
+inspite in spite, inspire
+instade instead
+instatance instance
+institue institute
+instuction instruction
+instuments instruments
+instutionalized institutionalized
+instutions intuitions
+insurence insurance
+intelectual intellectual
+inteligence intelligence
+inteligent intelligent
+intenational international
+intepretation interpretation
+intepretator interpretor
+interational international
+interbread interbreed, interbred
+interchangable interchangeable
+interchangably interchangeably
+intercontinetal intercontinental
+intered interred, interned
+interelated interrelated
+interferance interference
+interfereing interfering
+intergrated integrated
+intergration integration
+interm interim
+internation international
+interpet interpret
+interrim interim
+interrugum interregnum
+intertaining entertaining
+interupt interrupt
+intervines intervenes
+intevene intervene
+intial initial
+intially initially
+intrduced introduced
+intrest interest
+introdued introduced
+intruduced introduced
+intrusted entrusted
+intutive intuitive
+intutively intuitively
+inudstry industry
+inumerable enumerable, innumerable
+inventer inventor
+invertibrates invertebrates
+investingate investigate
+involvment involvement
+irelevent irrelevant
+iresistable irresistible
+iresistably irresistibly
+iresistible irresistible
+iresistibly irresistibly
+iritable irritable
+iritated irritated
+ironicly ironically
+irregardless regardless
+irrelevent irrelevant
+irreplacable irreplaceable
+irresistable irresistible
+irresistably irresistibly
+isnt isn't
+Israelies Israelis
+issueing issuing
+itnroduced introduced
+iunior junior
+iwll will
+iwth with
+Japanes Japanese
+jaques jacques
+jeapardy jeopardy
+jewllery jewellery
+Johanine Johannine
+Jospeh Joseph
+jouney journey
+journied journeyed
+journies journeys
+jstu just
+jsut just
+Juadaism Judaism
+Juadism Judaism
+judical judicial
+judisuary judiciary
+juducial judicial
+juristiction jurisdiction
+juristictions jurisdictions
+kindergarden kindergarten
+klenex kleenex
+knifes knives
+knive knife
+knowlege knowledge
+knowlegeable knowledgeable
+knwo know
+knwos knows
+konw know
+konws knows
+kwno know
+labatory lavatory, laboratory
+labled labelled, labeled
+labratory laboratory
+laguage language
+laguages languages
+larg large
+largst largest
+larrry larry
+lastr last
+lattitude latitude
+launchs launch
+launhed launched
+lavae larvae
+layed laid
+lazyness laziness
+leaded led
+leage league
+leanr lean, learn, leaner
+leathal lethal
+lefted left
+legitamate legitimate
+legitmate legitimate
+leibnitz leibniz
+lenght length
+leran learn
+lerans learns
+lieuenant lieutenant
+leutenant lieutenant
+levetate levitate
+levetated levitated
+levetates levitates
+levetating levitating
+levle level
+liasion liaison
+liason liaison
+liasons liaisons
+libary library
+libell libel
+libguistic linguistic
+libguistics linguistics
+libitarianisn libertarianism
+lible libel, liable
+lieing lying
+liek like
+liekd liked
+liesure leisure
+lieved lived
+liftime lifetime
+lightyear light year
+lightyears light years
+likelyhood likelihood
+linnaena linnaean
+lippizaner lipizzaner
+liquify liquefy
+liscense license, licence
+lisence license, licence
+lisense license, licence
+listners listeners
+litature literature
+literture literature
+littel little
+litterally literally
+liuke like
+livley lively
+lmits limits
+loev love
+lonelyness loneliness
+longitudonal longitudinal
+lonley lonely
+lonly lonely, only
+loosing losing
+lotharingen lothringen
+lsat last
+lukid likud
+lveo love
+lvoe love
+Lybia Libya
+mackeral mackerel
+magasine magazine
+magincian magician
+magnificient magnificent
+magolia magnolia
+mailny mainly
+maintainance maintenance
+maintainence maintenance
+maintance maintenance
+maintenence maintenance
+maintinaing maintaining
+maintioned mentioned
+majoroty majority
+maked marked, made
+makse makes
+Malcom Malcolm
+maltesian Maltese
+mamal mammal
+mamalian mammalian
+managable manageable, manageably
+managment management
+manisfestations manifestations
+manoeuverability maneuverability
+manouver maneuver, manoeuvre
+manouverability maneuverability, manoeuvrability, manoeuverability
+manouverable maneuverable, manoeuvrable
+manouvers maneuvers, manoeuvres
+mantained maintained
+manuever maneuver, manoeuvre
+manuevers maneuvers, manoeuvres
+manufacturedd manufactured
+manufature manufacture
+manufatured manufactured
+manufaturing manufacturing
+manuver maneuver
+mariage marriage
+marjority majority
+markes marks
+marketting marketing
+marmelade marmalade
+marrage marriage
+marraige marriage
+marrtyred martyred
+marryied married
+Massachussets Massachusetts
+Massachussetts Massachusetts
+massmedia mass media
+masterbation masturbation
+mataphysical metaphysical
+materalists materialist
+mathamatics mathematics
+mathematican mathematician
+mathematicas mathematics
+matheticians mathematicians
+mathmatically mathematically
+mathmatician mathematician
+mathmaticians mathematicians
+mccarthyst mccarthyist
+mchanics mechanics
+meaninng meaning
+mear wear, mere, mare
+mechandise merchandise
+medacine medicine
+medeival medieval
+medevial medieval
+mediciney mediciny
+medievel medieval
+mediterainnean mediterranean
+Mediteranean Mediterranean
+meerkrat meerkat
+melieux milieux
+membranaphone membranophone
+memeber member
+menally mentally
+meranda veranda, Miranda
+mercentile mercantile
+messanger messenger
+messenging messaging
+metalic metallic
+metalurgic metallurgic
+metalurgical metallurgical
+metalurgy metallurgy
+metamorphysis metamorphosis
+metaphoricial metaphorical
+meterologist meteorologist
+meterology meteorology
+methaphor metaphor
+methaphors metaphors
+Michagan Michigan
+micoscopy microscopy
+midwifes midwives
+mileau milieu
+milennia millennia
+milennium millennium
+mileu milieu
+miliary military
+milion million
+miliraty military
+millenia millennia
+millenial millennial
+millenialism millennialism
+millenium millennium
+millepede millipede
+millioniare millionaire
+millitary military
+millon million
+miltary military
+minature miniature
+minerial mineral
+miniscule minuscule
+ministery ministry
+minstries ministries
+minstry ministry
+minumum minimum
+mirrorred mirrored
+miscelaneous miscellaneous
+miscellanious miscellaneous
+miscellanous miscellaneous
+mischeivous mischievous
+mischevious mischievous
+mischievious mischievous
+misdameanor misdemeanor
+misdameanors misdemeanors
+misdemenor misdemeanor
+misdemenors misdemeanors
+misfourtunes misfortunes
+misile missile
+Misouri Missouri
+mispell misspell
+mispelled misspelled
+mispelling misspelling
+missen mizzen
+Missisipi Mississippi
+Missisippi Mississippi
+missle missile
+missonary missionary
+misterious mysterious
+mistery mystery
+misteryous mysterious
+mkae make
+mkaes makes
+mkaing making
+mkea make
+moderm modem
+modle model
+moent moment
+moeny money
+mohammedans muslims
+moil mohel
+moleclues molecules
+momento memento
+monestaries monasteries
+monestary monastery, monetary
+monickers monikers
+monolite monolithic
+Monserrat Montserrat
+montains mountains
+montanous mountainous
+monts months
+montypic monotypic
+moreso more, more so
+morgage mortgage
+Morisette Morissette
+Morrisette Morissette
+morroccan moroccan
+morrocco morocco
+morroco morocco
+mosture moisture
+motiviated motivated
+mounth month
+movei movie
+movment movement
+mroe more
+mucuous mucous
+muder murder
+mudering murdering
+muhammadan muslim
+multicultralism multiculturalism
+multipled multiplied
+multiplers multipliers
+munbers numbers
+muncipalities municipalities
+muncipality municipality
+munnicipality municipality
+muscels mussels, muscles
+muscial musical
+muscician musician
+muscicians musicians
+mutiliated mutilated
+myraid myriad
+mysef myself
+mysogynist misogynist
+mysogyny misogyny
+mysterous mysterious
+Mythraic Mithraic
+naieve naive
+Napoleonian Napoleonic
+naturaly naturally
+naturely naturally
+naturual natural
+naturually naturally
+Nazereth Nazareth
+neccesarily necessarily
+neccesary necessary
+neccessarily necessarily
+neccessary necessary
+neccessities necessities
+necesarily necessarily
+necesary necessary
+necessiate necessitate
+neglible negligible
+negligable negligible
+negociate negotiate
+negociation negotiation
+negociations negotiations
+negotation negotiation
+neice niece, nice
+neigborhood neighborhood
+neigbour neighbour, neighbor
+neigbourhood neighbourhood
+neigbouring neighbouring, neighboring
+neigbours neighbours, neighbors
+neolitic neolithic
+nessasarily necessarily
+nessecary necessary
+nestin nesting
+neverthless nevertheless
+newletters newsletters
+Newyorker New Yorker
+nickle nickel
+nightfa;; nightfall
+nightime nighttime
+nineth ninth
+ninteenth nineteenth
+ninties 1990s
+ninty ninety
+nkow know
+nkwo know
+nmae name
+noncombatents noncombatants
+nonsence nonsense
+nontheless nonetheless
+noone no one
+norhern northern
+northen northern
+northereastern northeastern
+notabley notably
+noteable notable
+noteably notably
+noteriety notoriety
+noth north
+nothern northern
+noticable noticeable
+noticably noticeably
+noticeing noticing
+noticible noticeable
+notwhithstanding notwithstanding
+noveau nouveau
+nowdays nowadays
+nowe now
+nto not
+nucular nuclear
+nuculear nuclear
+nuisanse nuisance
+Nullabour Nullarbor
+numberous numerous
+Nuremburg Nuremberg
+nusance nuisance
+nutritent nutrient
+nutritents nutrients
+nuturing nurturing
+obediance obedience
+obediant obedient
+obession obsession
+obssessed obsessed
+obstacal obstacle
+obstancles obstacles
+obstruced obstructed
+ocasion occasion
+ocasional occasional
+ocasionally occasionally
+ocasionaly occasionally
+ocasioned occasioned
+ocasions occasions
+ocassion occasion
+ocassional occasional
+ocassionally occasionally
+ocassionaly occasionally
+ocassioned occasioned
+ocassions occasions
+occaison occasion
+occassion occasion
+occassional occasional
+occassionally occasionally
+occassionaly occasionally
+occassioned occasioned
+occassions occasions
+occationally occasionally
+occour occur
+occurance occurrence
+occurances occurrences
+occured occurred
+occurence occurrence
+occurences occurrences
+occuring occurring
+occurr occur
+occurrance occurrence
+occurrances occurrences
+octohedra octahedra
+octohedral octahedral
+octohedron octahedron
+ocuntries countries
+ocuntry country
+ocurr occur
+ocurrance occurrence
+ocurred occurred
+ocurrence occurrence
+offcers officers
+offcially officially
+offereings offerings
+offical official
+officals officials
+offically officially
+officaly officially
+officialy officially
+offred offered
+oftenly often
+oging going, ogling
+omision omission
+omited omitted
+omiting omitting
+omlette omelette
+ommision omission
+ommited omitted
+ommiting omitting
+ommitted omitted
+ommitting omitting
+omniverous omnivorous
+omniverously omnivorously
+omre more
+onot note, not
+onyl only
+openess openness
+oponent opponent
+oportunity opportunity
+opose oppose
+oposite opposite
+oposition opposition
+oppenly openly
+oppinion opinion
+opponant opponent
+oppononent opponent
+oppositition opposition
+oppossed opposed
+opprotunity opportunity
+opression oppression
+opressive oppressive
+opthalmic ophthalmic
+opthalmologist ophthalmologist
+opthalmology ophthalmology
+opthamologist ophthalmologist
+optmizations optimizations
+optomism optimism
+orded ordered
+organim organism
+organiztion organization
+orgin origin, organ
+orginal original
+orginally originally
+orginize organise
+oridinarily ordinarily
+origanaly originally
+originall original, originally
+originaly originally
+originially originally
+originnally originally
+origional original
+orignally originally
+orignially originally
+otehr other
+ouevre oeuvre
+overshaddowed overshadowed
+overthere over there
+overwelming overwhelming
+overwheliming overwhelming
+owrk work
+owudl would
+oxigen oxygen
+oximoron oxymoron
+paide paid
+paitience patience
+palce place, palace
+paleolitic paleolithic
+paliamentarian parliamentarian
+Palistian Palestinian
+Palistinian Palestinian
+Palistinians Palestinians
+pallete palette
+pamflet pamphlet
+pamplet pamphlet
+pantomine pantomime
+Papanicalou Papanicolaou
+paralel parallel
+paralell parallel
+paralelly parallelly
+paralely parallelly
+parallely parallelly
+paranthesis parenthesis
+paraphenalia paraphernalia
+parellels parallels
+parituclar particular
+parliment parliament
+parrakeets parakeets
+parralel parallel
+parrallel parallel
+parrallell parallel
+parrallelly parallelly
+parrallely parallelly
+partialy partially
+particually particularly
+particualr particular
+particuarly particularly
+particularily particularly
+particulary particularly
+pary party
+pased passed
+pasengers passengers
+passerbys passersby
+pasttime pastime
+pastural pastoral
+paticular particular
+pattented patented
+pavillion pavilion
+payed paid
+peacefuland peaceful and
+peageant pageant
+peculure peculiar
+pedestrain pedestrian
+peice piece
+Peloponnes Peloponnesus
+penatly penalty
+penerator penetrator
+penisula peninsula
+penisular peninsular
+penninsula peninsula
+penninsular peninsular
+pennisula peninsula
+pensinula peninsula
+peom poem
+peoms poems
+peopel people
+peotry poetry
+perade parade
+percepted perceived
+percieve perceive
+percieved perceived
+perenially perennially
+perfomers performers
+performence performance
+performes performed, performs
+perhasp perhaps
+perheaps perhaps
+perhpas perhaps
+peripathetic peripatetic
+peristent persistent
+perjery perjury
+perjorative pejorative
+permanant permanent
+permenant permanent
+permenantly permanently
+permissable permissible
+perogative prerogative
+peronal personal
+perosnality personality
+perphas perhaps
+perpindicular perpendicular
+perseverence perseverance
+persistance persistence
+persistant persistent
+personel personnel, personal
+personell personnel
+personnell personnel
+persuded persuaded
+persue pursue
+persued pursued
+persuing pursuing
+persuit pursuit
+persuits pursuits
+pertubation perturbation
+pertubations perturbations
+pessiary pessary
+petetion petition
+Pharoah Pharaoh
+phenomenom phenomenon
+phenomenonal phenomenal
+phenomenonly phenomenally
+phenomonenon phenomenon
+phenomonon phenomenon
+phenonmena phenomena
+Philipines Philippines
+philisopher philosopher
+philisophical philosophical
+philisophy philosophy
+Phillipine Philippine
+Phillipines Philippines
+Phillippines Philippines
+phillosophically philosophically
+philospher philosopher
+philosphies philosophies
+philosphy philosophy
+Phonecian Phoenecian
+phongraph phonograph
+phylosophical philosophical
+physicaly physically
+pich pitch
+pilgrimmage pilgrimage
+pilgrimmages pilgrimages
+pinapple pineapple
+pinnaple pineapple
+pinoneered pioneered
+plagarism plagiarism
+planation plantation
+planed planned
+plantiff plaintiff
+plateu plateau
+plausable plausible
+playright playwright
+playwrite playwright
+playwrites playwrights
+pleasent pleasant
+plebicite plebiscite
+plesant pleasant
+poeoples peoples
+poety poetry
+poisin poison
+polical political
+polinator pollinator
+polinators pollinators
+politican politician
+politicans politicians
+poltical political
+polute pollute
+poluted polluted
+polutes pollutes
+poluting polluting
+polution pollution
+polyphonyic polyphonic
+polysaccaride polysaccharide
+polysaccharid polysaccharide
+pomegranite pomegranate
+pomotion promotion
+poportional proportional
+popoulation population
+popularaty popularity
+populare popular
+populer popular
+portayed portrayed
+portraing portraying
+Portugese Portuguese
+portuguease portuguese
+posess possess
+posessed possessed
+posesses possesses
+posessing possessing
+posession possession
+posessions possessions
+posion poison
+positon position, positron
+possable possible
+possably possibly
+posseses possesses
+possesing possessing
+possesion possession
+possessess possesses
+possibile possible
+possibilty possibility
+possiblility possibility
+possiblilty possibility
+possiblities possibilities
+possiblity possibility
+possition position
+Postdam Potsdam
+posthomous posthumous
+postion position
+postive positive
+potatos potatoes
+portait portrait
+potrait portrait
+potrayed portrayed
+poulations populations
+poverful powerful
+poweful powerful
+powerfull powerful
+practial practical
+practially practically
+practicaly practically
+practicioner practitioner
+practicioners practitioners
+practicly practically
+practioner practitioner
+practioners practitioners
+prairy prairie
+prarie prairie
+praries prairies
+pratice practice
+preample preamble
+precedessor predecessor
+preceed precede
+preceeded preceded
+preceeding preceding
+preceeds precedes
+precentage percentage
+precice precise
+precisly precisely
+precurser precursor
+predecesors predecessors
+predicatble predictable
+predicitons predictions
+predomiantly predominately
+prefered preferred
+prefering preferring
+preferrably preferably
+pregancies pregnancies
+preiod period
+preliferation proliferation
+premeire premiere
+premeired premiered
+premillenial premillennial
+preminence preeminence
+premission permission
+Premonasterians Premonstratensians
+preocupation preoccupation
+prepair prepare
+prepartion preparation
+prepatory preparatory
+preperation preparation
+preperations preparations
+preriod period
+presedential presidential
+presense presence
+presidenital presidential
+presidental presidential
+presitgious prestigious
+prespective perspective
+prestigeous prestigious
+prestigous prestigious
+presumabely presumably
+presumibly presumably
+pretection protection
+prevelant prevalent
+preverse perverse
+previvous previous
+pricipal principal
+priciple principle
+priestood priesthood
+primarly primarily
+primative primitive
+primatively primitively
+primatives primitives
+primordal primordial
+priveledges privileges
+privelege privilege
+priveleged privileged
+priveleges privileges
+privelige privilege
+priveliged privileged
+priveliges privileges
+privelleges privileges
+privilage privilege
+priviledge privilege
+priviledges privileges
+privledge privilege
+privte private
+probabilaty probability
+probablistic probabilistic
+probablly probably
+probalibity probability
+probaly probably
+probelm problem
+proccess process
+proccessing processing
+procede proceed, precede
+proceded proceeded, preceded
+procedes proceeds, precedes
+procedger procedure
+proceding proceeding, preceding
+procedings proceedings
+proceedure procedure
+proces process
+processer processor
+proclaimation proclamation
+proclamed proclaimed
+proclaming proclaiming
+proclomation proclamation
+profesion profusion, profession
+profesor professor
+professer professor
+proffesed professed
+proffesion profession
+proffesional professional
+proffesor professor
+profilic prolific
+progessed progressed
+programable programmable
+progrom pogrom, program
+progroms pogroms, programs
+prohabition prohibition
+prologomena prolegomena
+prominance prominence
+prominant prominent
+prominantly prominently
+prominately prominently, predominately
+promiscous promiscuous
+promotted promoted
+pronomial pronominal
+pronouced pronounced
+pronounched pronounced
+pronounciation pronunciation
+proove prove
+prooved proved
+prophacy prophecy
+propietary proprietary
+propmted prompted
+propoganda propaganda
+propogate propagate
+propogates propagates
+propogation propagation
+propostion proposition
+propotions proportions
+propper proper
+propperly properly
+proprietory proprietary
+proseletyzing proselytizing
+protaganist protagonist
+protaganists protagonists
+protocal protocol
+protoganist protagonist
+protrayed portrayed
+protruberance protuberance
+protruberances protuberances
+prouncements pronouncements
+provacative provocative
+provded provided
+provicial provincial
+provinicial provincial
+provisonal provisional
+provisiosn provision
+proximty proximity
+pseudononymous pseudonymous
+pseudonyn pseudonym
+psuedo pseudo
+psycology psychology
+psyhic psychic
+publicaly publicly
+puchasing purchasing
+Pucini Puccini
+Puertorrican Puerto Rican
+Puertorricans Puerto Ricans
+pumkin pumpkin
+puritannical puritanical
+purposedly purposely
+purpotedly purportedly
+pursuade persuade
+pursuaded persuaded
+pursuades persuades
+pususading persuading
+puting putting
+pwoer power
+pyscic psychic
+qtuie quite, quiet
+quantaty quantity
+quantitiy quantity
+quarantaine quarantine
+Queenland Queensland
+questonable questionable
+quicklyu quickly
+quinessential quintessential
+quitted quit
+quizes quizzes
+qutie quite, quiet
+rabinnical rabbinical
+racaus raucous
+radiactive radioactive
+radify ratify
+raelly really
+rarified rarefied
+reaccurring recurring
+reacing reaching
+reacll recall
+readmition readmission
+realitvely relatively
+realsitic realistic
+realtions relations
+realy really
+realyl really
+reasearch research
+rebiulding rebuilding
+rebllions rebellions
+rebounce rebound
+reccomend recommend
+reccomendations recommendations
+reccomended recommended
+reccomending recommending
+reccommend recommend
+reccommended recommended
+reccommending recommending
+reccuring recurring
+receeded receded
+receeding receding
+receivedfrom received from
+recepient recipient
+recepients recipients
+receving receiving
+rechargable rechargeable
+reched reached
+recide reside
+recided resided
+recident resident
+recidents residents
+reciding residing
+reciepents recipients
+reciept receipt
+recieve receive
+recieved received
+reciever receiver
+recievers receivers
+recieves receives
+recieving receiving
+recipiant recipient
+recipiants recipients
+recived received
+recivership receivership
+recogise recognise
+recogize recognize
+recomend recommend
+recomended recommended
+recomending recommending
+recomends recommends
+recommedations recommendations
+reconaissance reconnaissance
+reconcilation reconciliation
+reconized recognized
+reconnaissence reconnaissance
+recontructed reconstructed
+recordproducer record producer
+recquired required
+recrational recreational
+recrod record
+recuiting recruiting
+recuring recurring
+recurrance recurrence
+rediculous ridiculous
+reedeming redeeming
+reenforced reinforced
+refect reflect
+refedendum referendum
+referal referral
+refered referred
+referiang referring
+refering referring
+refernces references
+referrence reference
+referrs refers
+reffered referred
+refference reference
+refrence reference
+refrences references
+refrers refers
+refridgeration refrigeration
+refridgerator refrigerator
+refromist reformist
+refusla refusal
+regardes regards
+regluar regular
+reguarly regularly
+regulaion regulation
+regulaotrs regulators
+regularily regularly
+rehersal rehearsal
+reicarnation reincarnation
+reigining reigning
+reknown renown
+reknowned renowned
+rela real
+relaly really
+relatiopnship relationship
+relativly relatively
+relected reelected
+releive relieve
+releived relieved
+releiver reliever
+releses releases
+relevence relevance
+relevent relevant
+reliablity reliability
+relient reliant
+religeous religious
+religous religious
+religously religiously
+relinqushment relinquishment
+relitavely relatively
+relized realised, realized
+relpacement replacement
+remaing remaining
+remeber remember
+rememberable memorable
+rememberance remembrance
+remembrence remembrance
+remenant remnant
+remenicent reminiscent
+reminent remnant
+reminescent reminiscent
+reminscent reminiscent
+reminsicent reminiscent
+rendevous rendezvous
+rendezous rendezvous
+renedered rende
+renewl renewal
+rentors renters
+reoccurrence recurrence
+reorganision reorganisation
+repatition repetition, repartition
+repentence repentance
+repentent repentant
+repeteadly repeatedly
+repetion repetition
+repid rapid
+reponse response
+reponsible responsible
+reportadly reportedly
+represantative representative
+representive representative
+representives representatives
+reproducable reproducible
+reprtoire repertoire
+repsectively respectively
+reptition repetition
+requirment requirement
+requred required
+resaurant restaurant
+resembelance resemblance
+resembes resembles
+resemblence resemblance
+resevoir reservoir
+resignement resignment
+resistable resistible
+resistence resistance
+resistent resistant
+respectivly respectively
+responce response
+responibilities responsibilities
+responisble responsible
+responnsibilty responsibility
+responsability responsibility
+responsibile responsible
+responsibilites responsibilities
+responsiblity responsibility
+ressemblance resemblance
+ressemble resemble
+ressembled resembled
+ressemblence resemblance
+ressembling resembling
+resssurecting resurrecting
+ressurect resurrect
+ressurected resurrected
+ressurection resurrection
+ressurrection resurrection
+restaraunt restaurant
+restaraunteur restaurateur
+restaraunteurs restaurateurs
+restaraunts restaurants
+restauranteurs restaurateurs
+restauration restoration
+restauraunt restaurant
+resteraunt restaurant
+resteraunts restaurants
+resticted restricted
+restraunt restraint, restaurant
+resturant restaurant
+resturaunt restaurant
+resurecting resurrecting
+retalitated retaliated
+retalitation retaliation
+retreive retrieve
+returnd returned
+revaluated reevaluated
+reveral reversal
+reversable reversible
+revolutionar revolutionary
+rewitten rewritten
+rewriet rewrite
+rhymme rhyme
+rhythem rhythm
+rhythim rhythm
+rhytmic rhythmic
+rigeur rigueur, rigour, rigor
+rigourous rigorous
+rininging ringing
+rised rose
+Rockerfeller Rockefeller
+rococco rococo
+rocord record
+roomate roommate
+rougly roughly
+rucuperate recuperate
+rudimentatry rudimentary
+rulle rule
+runing running
+runnung running
+russina Russian
+Russion Russian
+rwite write
+rythem rhythm
+rythim rhythm
+rythm rhythm
+rythmic rhythmic
+rythyms rhythms
+sacrafice sacrifice
+sacreligious sacrilegious
+sacrifical sacrificial
+saftey safety
+safty safety
+salery salary
+sanctionning sanctioning
+sandwhich sandwich
+Sanhedrim Sanhedrin
+santioned sanctioned
+sargant sergeant
+sargeant sergeant
+sasy says, sassy
+satelite satellite
+satelites satellites
+Saterday Saturday
+Saterdays Saturdays
+satisfactority satisfactorily
+satric satiric
+satrical satirical
+satrically satirically
+sattelite satellite
+sattelites satellites
+saught sought
+saveing saving
+saxaphone saxophone
+scaleable scalable
+scandanavia Scandinavia
+scaricity scarcity
+scavanged scavenged
+schedual schedule
+scholarhip scholarship
+scholarstic scholastic, scholarly
+scientfic scientific
+scientifc scientific
+scientis scientist
+scince science
+scinece science
+scirpt script
+scoll scroll
+screenwrighter screenwriter
+scrutinity scrutiny
+scuptures sculptures
+seach search
+seached searched
+seaches searches
+secceeded seceded, succeeded
+seceed succeed, secede
+seceeded succeeded, seceded
+secratary secretary
+secretery secretary
+sedereal sidereal
+seeked sought
+segementation segmentation
+seguoys segues
+seige siege
+seing seeing
+seinor senior
+seldomly seldom
+senarios scenarios
+sence sense
+senstive sensitive
+sensure censure
+seperate separate
+seperated separated
+seperately separately
+seperates separates
+seperating separating
+seperation separation
+seperatism separatism
+seperatist separatist
+sepina subpoena
+sepulchure sepulchre, sepulcher
+sepulcre sepulchre, sepulcher
+sergent sergeant
+settelement settlement
+settlment settlement
+severeal several
+severley severely
+severly severely
+sevice service
+shaddow shadow
+shamen shaman, shamans
+sheat sheath, sheet, cheat
+sheild shield
+sherif sheriff
+shineing shining
+shiped shipped
+shiping shipping
+shopkeeepers shopkeepers
+shorly shortly
+shortwhile short while
+shoudl should
+shoudln should, shouldn't
+shouldnt shouldn't
+shreak shriek
+shrinked shrunk
+sicne since
+sideral sidereal
+sieze seize, size
+siezed seized, sized
+siezing seizing, sizing
+siezure seizure
+siezures seizures
+siginificant significant
+signficant significant
+signficiant significant
+signfies signifies
+signifantly significantly
+significently significantly
+signifigant significant
+signifigantly significantly
+signitories signatories
+signitory signatory
+similarily similarly
+similiar similar
+similiarity similarity
+similiarly similarly
+simmilar similar
+simpley simply
+simplier simpler
+simultanous simultaneous
+simultanously simultaneously
+sincerley sincerely
+singsog singsong
+sinse sines, since
+Sionist Zionist
+Sionists Zionists
+Sixtin Sistine
+Skagerak Skagerrak
+skateing skating
+slaugterhouses slaughterhouses
+slowy slowly
+smae same
+smealting smelting
+smoe some
+sneeks sneaks
+snese sneeze
+socalism socialism
+socities societies
+soem some
+sofware software
+sohw show
+soilders soldiers
+solatary solitary
+soley solely
+soliders soldiers
+soliliquy soliloquy
+soluable soluble
+somene someone
+somtimes sometimes
+somwhere somewhere
+sophicated sophisticated
+sorceror sorcerer
+sorrounding surrounding
+sotry story
+sotyr satyr, story
+soudn sound
+soudns sounds
+sould could, should, sold
+sountrack soundtrack
+sourth south
+sourthern southern
+souvenier souvenir
+souveniers souvenirs
+soveits soviets
+sovereignity sovereignty
+soverign sovereign
+soverignity sovereignty
+soverignty sovereignty
+spainish Spanish
+speach speech
+specfic specific
+speciallized specialised, specialized
+specif specific, specify
+specifiying specifying
+speciman specimen
+spectauclar spectacular
+spectaulars spectaculars
+spects aspects, expects
+spectum spectrum
+speices species
+spendour splendour
+spermatozoan spermatozoon
+spoace space
+sponser sponsor
+sponsered sponsored
+spontanous spontaneous
+sponzored sponsored
+spoonfulls spoonfuls
+sppeches speeches
+spreaded spread
+sprech speech
+spred spread
+spriritual spiritual
+spritual spiritual
+sqaure square
+stablility stability
+stainlees stainless
+staion station
+standars standards
+stange strange
+startegic strategic
+startegies strategies
+startegy strategy
+stateman statesman
+statememts statements
+statment statement
+steriods steroids
+sterotypes stereotypes
+stilus stylus
+stingent stringent
+stiring stirring
+stirrs stirs
+stlye style
+stong strong
+stopry story
+storeis stories
+storise stories
+stornegst strongest
+stoyr story
+stpo stop
+stradegies strategies
+stradegy strategy
+strat start, strata
+stratagically strategically
+streemlining streamlining
+stregth strength
+strenghen strengthen
+strenghened strengthened
+strenghening strengthening
+strenght strength
+strenghten strengthen
+strenghtened strengthened
+strenghtening strengthening
+strengtened strengthened
+strenous strenuous
+strictist strictest
+strikely strikingly
+strnad strand
+stroy story, destroy
+structual structural
+stubborness stubbornness
+stucture structure
+stuctured structured
+studdy study
+studing studying
+stuggling struggling
+sturcture structure
+subcatagories subcategories
+subcatagory subcategory
+subconsiously subconsciously
+subjudgation subjugation
+submachne submachine
+subpecies subspecies
+subsidary subsidiary
+subsiduary subsidiary
+subsquent subsequent
+subsquently subsequently
+substace substance
+substancial substantial
+substatial substantial
+substituded substituted
+substract subtract
+substracted subtracted
+substracting subtracting
+substraction subtraction
+substracts subtracts
+subtances substances
+subterranian subterranean
+suburburban suburban
+succceeded succeeded
+succcesses successes
+succedded succeeded
+succeded succeeded
+succeds succeeds
+succesful successful
+succesfully successfully
+succesfuly successfully
+succesion succession
+succesive successive
+successfull successful
+successully successfully
+succsess success
+succsessfull successful
+suceed succeed
+suceeded succeeded
+suceeding succeeding
+suceeds succeeds
+sucesful successful
+sucesfully successfully
+sucesfuly successfully
+sucesion succession
+sucess success
+sucesses successes
+sucessful successful
+sucessfull successful
+sucessfully successfully
+sucessfuly successfully
+sucession succession
+sucessive successive
+sucessor successor
+sucessot successor
+sucide suicide
+sucidial suicidal
+sufferage suffrage
+sufferred suffered
+sufferring suffering
+sufficent sufficient
+sufficently sufficiently
+sumary summary
+sunglases sunglasses
+suop soup
+superceeded superseded
+superintendant superintendent
+suphisticated sophisticated
+suplimented supplemented
+supose suppose
+suposed supposed
+suposedly supposedly
+suposes supposes
+suposing supposing
+supplamented supplemented
+suppliementing supplementing
+suppoed supposed
+supposingly supposedly
+suppy supply
+supress suppress
+supressed suppressed
+supresses suppresses
+supressing suppressing
+suprise surprise
+suprised surprised
+suprising surprising
+suprisingly surprisingly
+suprize surprise
+suprized surprised
+suprizing surprising
+suprizingly surprisingly
+surfce surface
+surley surly, surely
+suround surround
+surounded surrounded
+surounding surrounding
+suroundings surroundings
+surounds surrounds
+surplanted supplanted
+surpress suppress
+surpressed suppressed
+surprize surprise
+surprized surprised
+surprizing surprising
+surprizingly surprisingly
+surrended surrounded, surrendered
+surrepetitious surreptitious
+surrepetitiously surreptitiously
+surreptious surreptitious
+surreptiously surreptitiously
+surronded surrounded
+surrouded surrounded
+surrouding surrounding
+surrundering surrendering
+surveilence surveillance
+surveill surveil
+surveyer surveyor
+surviver survivor
+survivers survivors
+survivied survived
+suseptable susceptible
+suseptible susceptible
+suspention suspension
+swaer swear
+swaers swears
+swepth swept
+swiming swimming
+syas says
+symetrical symmetrical
+symetrically symmetrically
+symetry symmetry
+symettric symmetric
+symmetral symmetric
+symmetricaly symmetrically
+synagouge synagogue
+syncronization synchronization
+synonomous synonymous
+synonymns synonyms
+synphony symphony
+syphyllis syphilis
+sypmtoms symptoms
+syrap syrup
+sysmatically systematically
+sytem system
+sytle style
+tabacco tobacco
+tahn than
+taht that
+talekd talked
+targetted targeted
+targetting targeting
+tast taste
+tath that
+tattooes tattoos
+taxanomic taxonomic
+taxanomy taxonomy
+teached taught
+techician technician
+techicians technicians
+techiniques techniques
+technitian technician
+technnology technology
+technolgy technology
+teh the
+tehy they
+telelevision television
+televsion television
+telphony telephony
+temerature temperature
+temparate temperate
+temperarily temporarily
+temperment temperament
+tempertaure temperature
+temperture temperature
+temprary temporary
+tenacle tentacle
+tenacles tentacles
+tendacy tendency
+tendancies tendencies
+tendancy tendency
+tennisplayer tennis player
+tepmorarily temporarily
+terrestial terrestrial
+terriories territories
+terriory territory
+territorist terrorist
+territoy territory
+terroist terrorist
+testiclular testicular
+tghe the
+thast that, that's
+theather theater, theatre
+theese these
+theif thief
+theives thieves
+themselfs themselves
+themslves themselves
+ther there, their, the
+therafter thereafter
+therby thereby
+theri their
+thgat that
+thge the
+thier their
+thign thing
+thigns things
+thigsn things
+thikn think
+thikning thinking, thickening
+thikns thinks
+thiunk think
+thn then
+thna than
+thne then
+thnig thing
+thnigs things
+thoughout throughout
+threatend threatened
+threatning threatening
+threee three
+threshhold threshold
+thrid third
+throrough thorough
+throughly thoroughly
+throught thought, through, throughout
+througout throughout
+thru through
+thsi this
+thsoe those
+thta that
+thyat that
+tiem time, Tim
+tihkn think
+tihs this
+timne time
+tiome time, tome
+tje the
+tjhe the
+tjpanishad upanishad
+tkae take
+tkaes takes
+tkaing taking
+tlaking talking
+tobbaco tobacco
+todays today's
+todya today
+toghether together
+tolerence tolerance
+Tolkein Tolkien
+tomatos tomatoes
+tommorow tomorrow
+tommorrow tomorrow
+tongiht tonight
+toriodal toroidal
+tormenters tormentors
+torpeados torpedoes
+torpedos torpedoes
+tothe to the
+toubles troubles
+tounge tongue
+tourch torch, touch
+towords towards
+towrad toward
+tradionally traditionally
+traditionaly traditionally
+traditionnal traditional
+traditition tradition
+tradtionally traditionally
+trafficed trafficked
+trafficing trafficking
+trafic traffic
+trancendent transcendent
+trancending transcending
+tranform transform
+tranformed transformed
+transcendance transcendence
+transcendant transcendent
+transcendentational transcendental
+transcripting transcribing, transcription
+transending transcending
+transesxuals transsexuals
+transfered transferred
+transfering transferring
+transformaton transformation
+transistion transition
+translater translator
+translaters translators
+transmissable transmissible
+transporation transportation
+tremelo tremolo
+tremelos tremolos
+triguered triggered
+triology trilogy
+troling trolling
+troup troupe
+troups troupes, troops
+truely truly
+trustworthyness trustworthiness
+turnk turnkey, trunk
+Tuscon Tucson
+tust trust
+twelth twelfth
+twon town
+twpo two
+tyhat that
+tyhe they
+typcial typical
+typicaly typically
+tyranies tyrannies
+tyrany tyranny
+tyrranies tyrannies
+tyrrany tyranny
+ubiquitious ubiquitous
+uise use
+Ukranian Ukrainian
+ultimely ultimately
+unacompanied unaccompanied
+unahppy unhappy
+unanymous unanimous
+unathorised unauthorised
+unavailible unavailable
+unballance unbalance
+unbeleivable unbelievable
+uncertainity uncertainty
+unchallengable unchallengeable
+unchangable unchangeable
+uncompetive uncompetitive
+unconcious unconscious
+unconciousness unconsciousness
+unconfortability discomfort
+uncontitutional unconstitutional
+unconvential unconventional
+undecideable undecidable
+understoon understood
+undesireable undesirable
+undetecable undetectable
+undoubtely undoubtedly
+undreground underground
+uneccesary unnecessary
+unecessary unnecessary
+unequalities inequalities
+unforetunately unfortunately
+unforgetable unforgettable
+unforgiveable unforgivable
+unfortunatley unfortunately
+unfortunatly unfortunately
+unfourtunately unfortunately
+unihabited uninhabited
+unilateraly unilaterally
+unilatreal unilateral
+unilatreally unilaterally
+uninterruped uninterrupted
+uninterupted uninterrupted
+UnitesStates UnitedStates
+univeral universal
+univeristies universities
+univeristy university
+universtiy university
+univesities universities
+univesity university
+unkown unknown
+unlikey unlikely
+unmanouverable unmaneuverable, unmanoeuvrable
+unmistakeably unmistakably
+unneccesarily unnecessarily
+unneccesary unnecessary
+unneccessarily unnecessarily
+unneccessary unnecessary
+unnecesarily unnecessarily
+unnecesary unnecessary
+unoffical unofficial
+unoperational nonoperational
+unoticeable unnoticeable
+unplease displease
+unplesant unpleasant
+unprecendented unprecedented
+unprecidented unprecedented
+unrepentent unrepentant
+unrepetant unrepentant
+unrepetent unrepentant
+unsed used, unused, unsaid
+unsubstanciated unsubstantiated
+unsuccesful unsuccessful
+unsuccesfully unsuccessfully
+unsuccessfull unsuccessful
+unsucesful unsuccessful
+unsucesfuly unsuccessfully
+unsucessful unsuccessful
+unsucessfull unsuccessful
+unsucessfully unsuccessfully
+unsuprised unsurprised
+unsuprising unsurprising
+unsuprisingly unsurprisingly
+unsuprized unsurprised
+unsuprizing unsurprising
+unsuprizingly unsurprisingly
+unsurprized unsurprised
+unsurprizing unsurprising
+unsurprizingly unsurprisingly
+untill until
+untranslateable untranslatable
+unuseable unusable
+unusuable unusable
+unviersity university
+unwarrented unwarranted
+unweildly unwieldy
+unwieldly unwieldy
+upcomming upcoming
+upgradded upgraded
+usally usually
+useage usage
+usefull useful
+usefuly usefully
+useing using
+usualy usually
+ususally usually
+vaccum vacuum
+vaccume vacuum
+vacinity vicinity
+vaguaries vagaries
+vaieties varieties
+vailidty validity
+valetta valletta
+valuble valuable
+valueable valuable
+varations variations
+varient variant
+variey variety
+varing varying
+varities varieties
+varity variety
+vasall vassal
+vasalls vassals
+vegatarian vegetarian
+vegitable vegetable
+vegitables vegetables
+vegtable vegetable
+vehicule vehicle
+vell well
+venemous venomous
+vengance vengeance
+vengence vengeance
+verfication verification
+verison version
+verisons versions
+vermillion vermilion
+versitilaty versatility
+versitlity versatility
+vetween between
+veyr very
+vigeur vigueur, vigour, vigor
+vigilence vigilance
+vigourous vigorous
+villian villain
+villification vilification
+villify vilify
+villin villi, villain, villein
+vincinity vicinity
+violentce violence
+virutal virtual
+virtualy virtually
+virutally virtually
+visable visible
+visably visibly
+visting visiting
+vistors visitors
+vitories victories
+volcanoe volcano
+voleyball volleyball
+volontary voluntary
+volonteer volunteer
+volonteered volunteered
+volonteering volunteering
+volonteers volunteers
+volounteer volunteer
+volounteered volunteered
+volounteering volunteering
+volounteers volunteers
+vreity variety
+vrey very
+vriety variety
+vulnerablility vulnerability
+vyer very
+vyre very
+waht what
+wanna want to
+warantee warranty
+wardobe wardrobe
+warrent warrant
+warrriors warriors
+wasnt wasn't
+wass was
+watn want
+wayword wayward
+weaponary weaponry
+weas was
+wehn when
+weild wield, wild
+weilded wielded
+wendsay Wednesday
+wensday Wednesday
+wereabouts whereabouts
+whant want
+whants wants
+whcih which
+wheras whereas
+wherease whereas
+whereever wherever
+whic which
+whihc which
+whith with
+whlch which
+whn when
+wholey wholly
+wholy wholly, holy
+whta what
+whther whether
+wich which, witch
+widesread widespread
+wief wife
+wierd weird
+wiew view
+wih with
+wiht with
+wille will
+willingless willingness
+wirting writing
+withdrawl withdrawal, withdraw
+witheld withheld
+withing within
+withold withhold
+witht with
+witn with
+wiull will
+wnat want
+wnated wanted
+wnats wants
+wohle whole
+wokr work
+wokring working
+wonderfull wonderful
+workststion workstation
+worls world
+wordlwide worldwide
+worshipper worshiper
+worshipping worshiping
+worstened worsened
+woudl would
+wresters wrestlers
+wriet write
+writen written
+wroet wrote
+wrok work
+wroking working
+ws was
+wtih with
+wupport support
+xenophoby xenophobia
+yaching yachting
+yatch yacht
+yeasr years
+yeild yield
+yeilding yielding
+Yementite Yemenite, Yemeni
+yearm year
+yera year
+yeras years
+yersa years
+youseff yousef
+youself yourself
+ytou you
+yuo you
+joo you
+zeebra zebra
+
+[[Category:Wikipedia tools]]
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/suggestiontest/Makefile.am b/extensions/spellcheck/hunspell/tests/unit/data/suggestiontest/Makefile.am
new file mode 100644
index 0000000000..b8be6c5b6d
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/suggestiontest/Makefile.am
@@ -0,0 +1,6 @@
+EXTRA_DIST= \
+List_of_common_misspellings.txt \
+Makefile.orig \
+prepare \
+README \
+test
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/suggestiontest/Makefile.in b/extensions/spellcheck/hunspell/tests/unit/data/suggestiontest/Makefile.in
new file mode 100644
index 0000000000..11d332705d
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/suggestiontest/Makefile.in
@@ -0,0 +1,435 @@
+# Makefile.in generated by automake 1.11.1 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+# 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation,
+# Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+VPATH = @srcdir@
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+target_triplet = @target@
+subdir = tests/suggestiontest
+DIST_COMMON = README $(srcdir)/Makefile.am $(srcdir)/Makefile.in
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/m4/codeset.m4 \
+ $(top_srcdir)/m4/gettext.m4 $(top_srcdir)/m4/glibc2.m4 \
+ $(top_srcdir)/m4/glibc21.m4 $(top_srcdir)/m4/iconv.m4 \
+ $(top_srcdir)/m4/intdiv0.m4 $(top_srcdir)/m4/intl.m4 \
+ $(top_srcdir)/m4/intlmacosx.m4 $(top_srcdir)/m4/intmax.m4 \
+ $(top_srcdir)/m4/inttypes-pri.m4 \
+ $(top_srcdir)/m4/inttypes_h.m4 $(top_srcdir)/m4/lcmessage.m4 \
+ $(top_srcdir)/m4/lib-ld.m4 $(top_srcdir)/m4/lib-link.m4 \
+ $(top_srcdir)/m4/lib-prefix.m4 $(top_srcdir)/m4/libtool.m4 \
+ $(top_srcdir)/m4/lock.m4 $(top_srcdir)/m4/longlong.m4 \
+ $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \
+ $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \
+ $(top_srcdir)/m4/nls.m4 $(top_srcdir)/m4/po.m4 \
+ $(top_srcdir)/m4/printf-posix.m4 $(top_srcdir)/m4/progtest.m4 \
+ $(top_srcdir)/m4/size_max.m4 $(top_srcdir)/m4/stdint_h.m4 \
+ $(top_srcdir)/m4/uintmax_t.m4 $(top_srcdir)/m4/visibility.m4 \
+ $(top_srcdir)/m4/wchar_t.m4 $(top_srcdir)/m4/wint_t.m4 \
+ $(top_srcdir)/m4/xsize.m4 $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
+CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+SOURCES =
+DIST_SOURCES =
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+ALLOCA = @ALLOCA@
+AMTAR = @AMTAR@
+AR = @AR@
+AS = @AS@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+BUILD_INCLUDED_LIBINTL = @BUILD_INCLUDED_LIBINTL@
+CATOBJEXT = @CATOBJEXT@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CFLAG_VISIBILITY = @CFLAG_VISIBILITY@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CURSESLIB = @CURSESLIB@
+CXX = @CXX@
+CXXCPP = @CXXCPP@
+CXXDEPMODE = @CXXDEPMODE@
+CXXFLAGS = @CXXFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DATADIRNAME = @DATADIRNAME@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DLLTOOL = @DLLTOOL@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+FGREP = @FGREP@
+GENCAT = @GENCAT@
+GETTEXT_MACRO_VERSION = @GETTEXT_MACRO_VERSION@
+GLIBC2 = @GLIBC2@
+GLIBC21 = @GLIBC21@
+GMSGFMT = @GMSGFMT@
+GMSGFMT_015 = @GMSGFMT_015@
+GREP = @GREP@
+HAVE_ASPRINTF = @HAVE_ASPRINTF@
+HAVE_POSIX_PRINTF = @HAVE_POSIX_PRINTF@
+HAVE_SNPRINTF = @HAVE_SNPRINTF@
+HAVE_VISIBILITY = @HAVE_VISIBILITY@
+HAVE_WPRINTF = @HAVE_WPRINTF@
+HUNSPELL_VERSION_MAJOR = @HUNSPELL_VERSION_MAJOR@
+HUNSPELL_VERSION_MINOR = @HUNSPELL_VERSION_MINOR@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+INSTOBJEXT = @INSTOBJEXT@
+INTLBISON = @INTLBISON@
+INTLLIBS = @INTLLIBS@
+INTLOBJS = @INTLOBJS@
+INTL_LIBTOOL_SUFFIX_PREFIX = @INTL_LIBTOOL_SUFFIX_PREFIX@
+INTL_MACOSX_LIBS = @INTL_MACOSX_LIBS@
+LD = @LD@
+LDFLAGS = @LDFLAGS@
+LIBICONV = @LIBICONV@
+LIBINTL = @LIBINTL@
+LIBMULTITHREAD = @LIBMULTITHREAD@
+LIBOBJS = @LIBOBJS@
+LIBPTH = @LIBPTH@
+LIBPTH_PREFIX = @LIBPTH_PREFIX@
+LIBS = @LIBS@
+LIBTHREAD = @LIBTHREAD@
+LIBTOOL = @LIBTOOL@
+LIPO = @LIPO@
+LN_S = @LN_S@
+LTLIBC = @LTLIBC@
+LTLIBICONV = @LTLIBICONV@
+LTLIBINTL = @LTLIBINTL@
+LTLIBMULTITHREAD = @LTLIBMULTITHREAD@
+LTLIBOBJS = @LTLIBOBJS@
+LTLIBPTH = @LTLIBPTH@
+LTLIBTHREAD = @LTLIBTHREAD@
+MAKEINFO = @MAKEINFO@
+MKDIR_P = @MKDIR_P@
+MSGFMT = @MSGFMT@
+MSGFMT_015 = @MSGFMT_015@
+MSGMERGE = @MSGMERGE@
+NM = @NM@
+NMEDIT = @NMEDIT@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+POSUB = @POSUB@
+PRI_MACROS_BROKEN = @PRI_MACROS_BROKEN@
+RANLIB = @RANLIB@
+READLINELIB = @READLINELIB@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STRIP = @STRIP@
+USE_INCLUDED_LIBINTL = @USE_INCLUDED_LIBINTL@
+USE_NLS = @USE_NLS@
+VERSION = @VERSION@
+WINDRES = @WINDRES@
+WOE32 = @WOE32@
+WOE32DLL = @WOE32DLL@
+XFAILED = @XFAILED@
+XGETTEXT = @XGETTEXT@
+XGETTEXT_015 = @XGETTEXT_015@
+XGETTEXT_EXTRA_OPTIONS = @XGETTEXT_EXTRA_OPTIONS@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_CXX = @ac_ct_CXX@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+lt_ECHO = @lt_ECHO@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+sysconfdir = @sysconfdir@
+target = @target@
+target_alias = @target_alias@
+target_cpu = @target_cpu@
+target_os = @target_os@
+target_vendor = @target_vendor@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+EXTRA_DIST = \
+List_of_common_misspellings.txt \
+Makefile.orig \
+prepare \
+README \
+test
+
+all: all-am
+
+.SUFFIXES:
+$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+ && { if test -f $@; then exit 0; else break; fi; }; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu tests/suggestiontest/Makefile'; \
+ $(am__cd) $(top_srcdir) && \
+ $(AUTOMAKE) --gnu tests/suggestiontest/Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(am__aclocal_m4_deps):
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+tags: TAGS
+TAGS:
+
+ctags: CTAGS
+CTAGS:
+
+
+distdir: $(DISTFILES)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ list='$(DISTFILES)'; \
+ dist_files=`for file in $$list; do echo $$file; done | \
+ sed -e "s|^$$srcdirstrip/||;t" \
+ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+ case $$dist_files in \
+ */*) $(MKDIR_P) `echo "$$dist_files" | \
+ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+ sort -u` ;; \
+ esac; \
+ for file in $$dist_files; do \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ if test -d $$d/$$file; then \
+ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test -d "$(distdir)/$$file"; then \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+ else \
+ test -f "$(distdir)/$$file" \
+ || cp -p $$d/$$file "$(distdir)/$$file" \
+ || exit 1; \
+ fi; \
+ done
+check-am: all-am
+check: check-am
+all-am: Makefile
+installdirs:
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ `test -z '$(STRIP)' || \
+ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+ -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+clean: clean-am
+
+clean-am: clean-generic clean-libtool mostlyclean-am
+
+distclean: distclean-am
+ -rm -f Makefile
+distclean-am: clean-am distclean-generic
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+html-am:
+
+info: info-am
+
+info-am:
+
+install-data-am:
+
+install-dvi: install-dvi-am
+
+install-dvi-am:
+
+install-exec-am:
+
+install-html: install-html-am
+
+install-html-am:
+
+install-info: install-info-am
+
+install-info-am:
+
+install-man:
+
+install-pdf: install-pdf-am
+
+install-pdf-am:
+
+install-ps: install-ps-am
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-generic mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am:
+
+.MAKE: install-am install-strip
+
+.PHONY: all all-am check check-am clean clean-generic clean-libtool \
+ distclean distclean-generic distclean-libtool distdir dvi \
+ dvi-am html html-am info info-am install install-am \
+ install-data install-data-am install-dvi install-dvi-am \
+ install-exec install-exec-am install-html install-html-am \
+ install-info install-info-am install-man install-pdf \
+ install-pdf-am install-ps install-ps-am install-strip \
+ installcheck installcheck-am installdirs maintainer-clean \
+ maintainer-clean-generic mostlyclean mostlyclean-generic \
+ mostlyclean-libtool pdf pdf-am ps ps-am uninstall uninstall-am
+
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/suggestiontest/README b/extensions/spellcheck/hunspell/tests/unit/data/suggestiontest/README
new file mode 100644
index 0000000000..c50e05cea9
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/suggestiontest/README
@@ -0,0 +1,16 @@
+source of text data: Wikipedia
+http://en.wikipedia.org/wiki/Wikipedia:Lists_of_common_misspellings/For_machines
+
+For testing Hunspell you need the extended en_US dictionary with phonetic table:
+http://hunspell.sourceforge.net/en_US.zip
+
+test:
+make -f Makefile.orig
+
+test only with Hunspell:
+
+make -f Makefile.orig single
+
+test with different input file and dictionaries:
+
+INPUT=dutchlist.txt HUNSPELL=nl_NL ASPELL=nl make -f Makefile.orig
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/suggestiontest/prepare b/extensions/spellcheck/hunspell/tests/unit/data/suggestiontest/prepare
new file mode 100644
index 0000000000..a72d931b8b
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/suggestiontest/prepare
@@ -0,0 +1,40 @@
+#!/bin/bash
+# Check common misspellings
+# input file format:
+# word->word1, ...
+# Source: http://en.wikipedia.org/wiki/Wikipedia:Lists_of_common_misspellings/For_machines
+
+hunspell=../../src/tools/hunspell
+hlang=${HUNSPELL:-en_US}
+alang=${ASPELL:-en_US}
+input=${INPUT:-List_of_common_misspellings.txt}
+
+# remove bad words recognised by Hunspell as good
+cat $input | sed 's/[-]>/ /' | $hunspell -d $hlang -1 -L |
+
+# remove items with dash for Aspell
+grep '^[^-]* ' |
+
+# remove spaces from end of lines
+sed 's/ *$//' >$input.1
+
+# remove bad words recognised by Aspell as good
+cut -f 1 -d ' ' $input.1 | aspell -l $alang --list |
+awk 'FILENAME=="-"{a[$1]=1;next}a[$1]{print$0}' - $input.1 |
+
+# change commas with tabs
+sed 's/, */ /g' >$input.2
+
+# remove lines with unrecognised suggestions (except suggestion with spaces)
+cut -d ' ' -f 2- $input.2 | tr "\t" "\n" | grep -v ' ' >x.1
+cat x.1 | $hunspell -l -d $hlang >x.2
+cat x.1 | aspell -l $alang --list >>x.2
+cat x.2 | awk 'BEGIN{FS="\t"}
+FILENAME=="-"{a[$1]=1;next}a[$2]!=1 && a[$3]!=1{print $0}' - $input.2 >$input.3
+
+cut -f 1 -d ' ' $input.3 | aspell -l $alang -a | grep -v ^$ | sed -n '2,$p' |
+sed 's/^.*: //;s/, / /g' >$input.4
+
+cat $input.3 | $hunspell -d $hlang -a -1 | grep -v ^$ | sed -n '2,$p' |
+sed 's/^.*: //;s/, / /g' >$input.5
+
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/suggestiontest/test b/extensions/spellcheck/hunspell/tests/unit/data/suggestiontest/test
new file mode 100644
index 0000000000..8e6c1cc1ff
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/suggestiontest/test
@@ -0,0 +1,25 @@
+#!/bin/bash
+# Check common misspellings
+# input file format:
+# word->word1, ...
+# Source: http://en.wikipedia.org/wiki/Wikipedia:Lists_of_common_misspellings/For_machines
+
+input=${INPUT:-List_of_common_misspellings.txt}
+
+function check() {
+cat $1 | awk 'BEGIN{maxord=0;FS="\t"}FILENAME=="-"{for (i=1; i<=NF; i++){a[NR,$(i)]=i};max=NR;next}{x1=a[NR-max,$2];x2=a[NR-max,$3];sug++;if($3)sug++;if (!x1&&!x2){mis2++;misrow=misrow"\n"$0};if(!x1||($3 && !x2))mis++;ord+=x1+x2;}END{
+print "Missed rows", misrow;
+print "======================================="
+print maxord, "max. suggestion for a word";
+print max, "input rows";
+print mis2, "missing rows";
+print sug, "expected suggestions";
+print mis, "missing suggestions";
+print ord/(sug-mis), "average ranking";
+}' - $2
+}
+
+test -f $input.4 && check $input.4 $input.3 >result.aspell
+check $input.5 $input.3 >result.hunspell
+test -f result.aspell && tail -6 result.aspell
+tail -6 result.hunspell
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/sugutf.aff b/extensions/spellcheck/hunspell/tests/unit/data/sugutf.aff
new file mode 100644
index 0000000000..60294d24ca
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/sugutf.aff
@@ -0,0 +1,15 @@
+# new suggestion methods of Hunspell 1.5:
+# capitalization: nasa -> NASA
+# long swap: permenant -> permanent
+# long mov: Ghandi -> Gandhi
+# double two characters: vacacation -> vacation
+# space with REP: "alot" -> "a lot" ("a lot" need to be in the dic file.)
+
+SET UTF-8
+# switch off ngram suggestion for testing
+MAXNGRAMSUGS 0
+REP 1
+REP alot a_lot
+KEY qwertzuiop|asdfghjkl|yxcvbnm|aq
+WORDCHARS .
+FORBIDDENWORD ?
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/sugutf.dic b/extensions/spellcheck/hunspell/tests/unit/data/sugutf.dic
new file mode 100644
index 0000000000..cf7c9aadbe
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/sugutf.dic
@@ -0,0 +1,11 @@
+10
+NASA
+Gandhi
+grateful
+permanent
+vacation
+a
+lot
+have
+which
+McDonald
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/sugutf.sug b/extensions/spellcheck/hunspell/tests/unit/data/sugutf.sug
new file mode 100644
index 0000000000..e277bdb778
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/sugutf.sug
@@ -0,0 +1,12 @@
+NASA
+Gandhi
+grateful
+permanent
+vacation
+a lot, lot
+permanent. Vacation
+have
+which
+Gandhi
+McDonald
+permanent
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/sugutf.test b/extensions/spellcheck/hunspell/tests/unit/data/sugutf.test
new file mode 100644
index 0000000000..7f44369060
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/sugutf.test
@@ -0,0 +1,4 @@
+#!/bin/sh
+DIR="`dirname $0`"
+NAME="`basename $0 .test`"
+$DIR/test.sh $NAME
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/sugutf.wrong b/extensions/spellcheck/hunspell/tests/unit/data/sugutf.wrong
new file mode 100644
index 0000000000..4d184d5a61
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/sugutf.wrong
@@ -0,0 +1,12 @@
+nasa
+Ghandi
+greatful
+permenant
+vacacation
+alot
+permanent.Vacation
+ahev
+hwihc
+GAndhi
+Mcdonald
+permqnent
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/test.sh b/extensions/spellcheck/hunspell/tests/unit/data/test.sh
new file mode 100644
index 0000000000..c89ca9bf75
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/test.sh
@@ -0,0 +1,111 @@
+#!/bin/bash
+export LC_ALL="C"
+
+function check_valgrind_log () {
+if [ "$VALGRIND" != "" ]; then
+ if [ -f $TEMPDIR/test.pid* ]; then
+ log=`ls $TEMPDIR/test.pid*`
+ if ! grep -q 'ERROR SUMMARY: 0 error' $log; then
+ echo "Fail in $NAME $1 checking detected by Valgrind"
+ echo "$log Valgrind log file moved to $TEMPDIR/badlogs"
+ mv $log $TEMPDIR/badlogs
+ exit 1
+ fi
+ if grep -q 'LEAK SUMMARY' $log; then
+ echo "Memory leak in $NAME $1 checking detected by Valgrind"
+ echo "$log Valgrind log file moved to $TEMPDIR/badlogs"
+ mv $log $TEMPDIR/badlogs
+ exit 1
+ fi
+ rm -f $log
+ fi
+fi
+}
+
+TESTDIR=.
+TEMPDIR=$TESTDIR/testSubDir
+NAME="$1"
+shift
+
+if [ ! -d $TEMPDIR ]; then
+ mkdir $TEMPDIR
+fi
+
+shopt -s expand_aliases
+
+alias hunspell='../libtool --mode=execute -dlopen ../src/hunspell/.libs/libhunspell*.la ../src/tools/hunspell'
+alias analyze='../libtool --mode=execute -dlopen ../src/hunspell/.libs/libhunspell*.la ../src/tools/analyze'
+
+if [ "$VALGRIND" != "" ]; then
+ rm -f $TEMPDIR/test.pid*
+ if [ ! -d $TEMPDIR/badlogs ]; then
+ mkdir $TEMPDIR/badlogs
+ fi
+
+ alias hunspell='../libtool --mode=execute -dlopen ../src/hunspell/.libs/libhunspell*.la valgrind --tool=$VALGRIND --leak-check=yes --show-reachable=yes --log-file=$TEMPDIR/test.pid ../src/tools/hunspell'
+ alias analyze='../libtool --mode=execute -dlopen ../src/hunspell/.libs/libhunspell*.la valgrind --tool=$VALGRIND --leak-check=yes --show-reachable=yes --log-file=$TEMPDIR/test.pid ../src/tools/analyze'
+fi
+
+# Tests good words
+if test -f $TESTDIR/$NAME.good; then
+ hunspell -l $* -d $TESTDIR/$NAME <$TESTDIR/$NAME.good >$TEMPDIR/$NAME.good
+ if test -s $TEMPDIR/$NAME.good; then
+ echo "============================================="
+ echo "Fail in $NAME.good. Good words recognised as wrong:"
+ cat $TEMPDIR/$NAME.good
+ rm -f $TEMPDIR/$NAME.good
+ exit 1
+ fi
+ rm -f $TEMPDIR/$NAME.good
+fi
+
+check_valgrind_log "good words"
+
+# Tests bad words
+if test -f $TESTDIR/$NAME.wrong; then
+ hunspell -l $* -d $TESTDIR/$NAME <$TESTDIR/$NAME.wrong >$TEMPDIR/$NAME.wrong
+ tr -d ' ' <$TESTDIR/$NAME.wrong >$TEMPDIR/$NAME.wrong.detab
+ if ! cmp $TEMPDIR/$NAME.wrong $TEMPDIR/$NAME.wrong.detab >/dev/null; then
+ echo "============================================="
+ echo "Fail in $NAME.wrong. Bad words recognised as good:"
+ tr -d ' ' <$TESTDIR/$NAME.wrong >$TEMPDIR/$NAME.wrong.detab
+ diff $TEMPDIR/$NAME.wrong.detab $TEMPDIR/$NAME.wrong | grep '^<' | sed 's/^..//'
+ rm -f $TEMPDIR/$NAME.wrong $TEMPDIR/$NAME.wrong.detab
+ exit 1
+ fi
+ rm -f $TEMPDIR/$NAME.wrong $TEMPDIR/$NAME.wrong.detab
+fi
+
+check_valgrind_log "bad words"
+
+# Tests morphological analysis
+if test -f $TESTDIR/$NAME.morph; then
+ sed 's/ $//' $TESTDIR/$NAME.good >$TEMPDIR/$NAME.good
+ analyze $TESTDIR/$NAME.aff $TESTDIR/$NAME.dic $TEMPDIR/$NAME.good >$TEMPDIR/$NAME.morph
+ if ! cmp $TEMPDIR/$NAME.morph $TESTDIR/$NAME.morph >/dev/null; then
+ echo "============================================="
+ echo "Fail in $NAME.morph. Bad analysis?"
+ diff $TESTDIR/$NAME.morph $TEMPDIR/$NAME.morph | grep '^<' | sed 's/^..//'
+ rm -f $TEMPDIR/$NAME.morph
+ exit 1
+ fi
+ rm -f $TEMPDIR/$NAME.{morph,good}
+fi
+
+check_valgrind_log "morphological analysis"
+
+# Tests suggestions
+if test -f $TESTDIR/$NAME.sug; then
+ hunspell $* -a -d $TESTDIR/$NAME <$TESTDIR/$NAME.wrong | grep '^&' | \
+ sed 's/^[^:]*: //' >$TEMPDIR/$NAME.sug
+ if ! cmp $TEMPDIR/$NAME.sug $TESTDIR/$NAME.sug >/dev/null; then
+ echo "============================================="
+ echo "Fail in $NAME.sug. Bad suggestion?"
+ diff $TESTDIR/$NAME.sug $TEMPDIR/$NAME.sug
+ rm -f $TEMPDIR/$NAME.sug
+ exit 1
+ fi
+ rm -f $TEMPDIR/$NAME.sug
+fi
+
+check_valgrind_log "suggestion"
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/utf8-bom.aff b/extensions/spellcheck/hunspell/tests/unit/data/utf8-bom.aff
new file mode 100644
index 0000000000..f56998b9f3
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/utf8-bom.aff
@@ -0,0 +1,3 @@
+鏤SET UTF-8
+
+# removing byte order mark from affix file
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/utf8-bom.dic b/extensions/spellcheck/hunspell/tests/unit/data/utf8-bom.dic
new file mode 100644
index 0000000000..8b10768e55
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/utf8-bom.dic
@@ -0,0 +1,2 @@
+1
+ap辿ritif
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/utf8-bom.good b/extensions/spellcheck/hunspell/tests/unit/data/utf8-bom.good
new file mode 100644
index 0000000000..c344eaf5ac
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/utf8-bom.good
@@ -0,0 +1,2 @@
+ap辿ritif
+APRITIF
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/utf8-bom.test b/extensions/spellcheck/hunspell/tests/unit/data/utf8-bom.test
new file mode 100644
index 0000000000..1d25699aa2
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/utf8-bom.test
@@ -0,0 +1,4 @@
+#!/bin/sh
+DIR="`dirname $0`"
+NAME="`basename $0 .test`"
+$DIR/test.sh $NAME -i utf-8 -1
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/utf8-bom2.aff b/extensions/spellcheck/hunspell/tests/unit/data/utf8-bom2.aff
new file mode 100644
index 0000000000..784935c841
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/utf8-bom2.aff
@@ -0,0 +1,3 @@
+SET UTF-8
+
+# removing byte order mark from dic file
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/utf8-bom2.dic b/extensions/spellcheck/hunspell/tests/unit/data/utf8-bom2.dic
new file mode 100644
index 0000000000..b763179a0d
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/utf8-bom2.dic
@@ -0,0 +1,2 @@
+鏤1
+ap辿ritif
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/utf8-bom2.good b/extensions/spellcheck/hunspell/tests/unit/data/utf8-bom2.good
new file mode 100644
index 0000000000..c344eaf5ac
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/utf8-bom2.good
@@ -0,0 +1,2 @@
+ap辿ritif
+APRITIF
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/utf8-bom2.test b/extensions/spellcheck/hunspell/tests/unit/data/utf8-bom2.test
new file mode 100644
index 0000000000..1d25699aa2
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/utf8-bom2.test
@@ -0,0 +1,4 @@
+#!/bin/sh
+DIR="`dirname $0`"
+NAME="`basename $0 .test`"
+$DIR/test.sh $NAME -i utf-8 -1
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/utf8-nonbmp.aff b/extensions/spellcheck/hunspell/tests/unit/data/utf8-nonbmp.aff
new file mode 100644
index 0000000000..979e3c2284
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/utf8-nonbmp.aff
@@ -0,0 +1 @@
+SET UTF-8
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/utf8-nonbmp.dic b/extensions/spellcheck/hunspell/tests/unit/data/utf8-nonbmp.dic
new file mode 100644
index 0000000000..4a040eeb0b
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/utf8-nonbmp.dic
@@ -0,0 +1,5 @@
+4 # Old Persian numbers (1-4), source: Wikipedia
+
+
+
+
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/utf8-nonbmp.good b/extensions/spellcheck/hunspell/tests/unit/data/utf8-nonbmp.good
new file mode 100644
index 0000000000..9f989d3397
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/utf8-nonbmp.good
@@ -0,0 +1,5 @@
+
+
+
+
+
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/utf8-nonbmp.sug b/extensions/spellcheck/hunspell/tests/unit/data/utf8-nonbmp.sug
new file mode 100644
index 0000000000..bfe2a539fe
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/utf8-nonbmp.sug
@@ -0,0 +1,2 @@
+,
+,
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/utf8-nonbmp.test b/extensions/spellcheck/hunspell/tests/unit/data/utf8-nonbmp.test
new file mode 100644
index 0000000000..1d25699aa2
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/utf8-nonbmp.test
@@ -0,0 +1,4 @@
+#!/bin/sh
+DIR="`dirname $0`"
+NAME="`basename $0 .test`"
+$DIR/test.sh $NAME -i utf-8 -1
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/utf8-nonbmp.wrong b/extensions/spellcheck/hunspell/tests/unit/data/utf8-nonbmp.wrong
new file mode 100644
index 0000000000..d18dfa4c20
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/utf8-nonbmp.wrong
@@ -0,0 +1,2 @@
+
+
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/utf8.aff b/extensions/spellcheck/hunspell/tests/unit/data/utf8.aff
new file mode 100644
index 0000000000..e8934d71b5
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/utf8.aff
@@ -0,0 +1,10 @@
+SET UTF-8
+
+SFX A Y 7
+SFX A 0 .
+SFX A 0 o
+SFX A 0 坦
+SFX A 坦 坦
+SFX A 坦 oo 坦
+SFX A o o o
+SFX A 0 坦 [abcd坦]
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/utf8.dic b/extensions/spellcheck/hunspell/tests/unit/data/utf8.dic
new file mode 100644
index 0000000000..e7cb34daf6
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/utf8.dic
@@ -0,0 +1,3 @@
+2
+foo/A
+fo坦/A
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/utf8.good b/extensions/spellcheck/hunspell/tests/unit/data/utf8.good
new file mode 100644
index 0000000000..08aa4dadf9
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/utf8.good
@@ -0,0 +1,9 @@
+foo
+fo坦
+foo
+foo
+fo坦
+fo
+foo
+fooo
+fo坦坦
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/utf8.test b/extensions/spellcheck/hunspell/tests/unit/data/utf8.test
new file mode 100644
index 0000000000..cde7c54109
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/utf8.test
@@ -0,0 +1,4 @@
+#!/bin/sh
+DIR="`dirname $0`"
+NAME="`basename $0 .test`"
+$DIR/test.sh $NAME -i utf-8
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/utfcompound.aff b/extensions/spellcheck/hunspell/tests/unit/data/utfcompound.aff
new file mode 100644
index 0000000000..43506afa31
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/utfcompound.aff
@@ -0,0 +1,3 @@
+SET UTF-8
+COMPOUNDMIN 3
+COMPOUNDFLAG A
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/utfcompound.dic b/extensions/spellcheck/hunspell/tests/unit/data/utfcompound.dic
new file mode 100644
index 0000000000..ab90a1b703
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/utfcompound.dic
@@ -0,0 +1,9 @@
+8
+foo/A
+bar/A
+f坦坦/A
+叩叩r/A
+xy/A
+yz/A
+辿辿/A
+/A
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/utfcompound.good b/extensions/spellcheck/hunspell/tests/unit/data/utfcompound.good
new file mode 100644
index 0000000000..1a1a1b19c0
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/utfcompound.good
@@ -0,0 +1,5 @@
+foobar
+barfoo
+foobarfoo
+f坦坦叩叩r
+叩叩rf坦坦
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/utfcompound.test b/extensions/spellcheck/hunspell/tests/unit/data/utfcompound.test
new file mode 100644
index 0000000000..cde7c54109
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/utfcompound.test
@@ -0,0 +1,4 @@
+#!/bin/sh
+DIR="`dirname $0`"
+NAME="`basename $0 .test`"
+$DIR/test.sh $NAME -i utf-8
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/utfcompound.wrong b/extensions/spellcheck/hunspell/tests/unit/data/utfcompound.wrong
new file mode 100644
index 0000000000..fa385c1b03
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/utfcompound.wrong
@@ -0,0 +1,7 @@
+xyyz
+fooxy
+xyfoo
+fooxybar
+辿辿
+f坦坦辿辿
+叩叩r
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/warn.aff b/extensions/spellcheck/hunspell/tests/unit/data/warn.aff
new file mode 100644
index 0000000000..d586fa33ef
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/warn.aff
@@ -0,0 +1,13 @@
+# WARN flag
+# The signed word, and its suffixed forms result warning message in command-line
+
+#Use to forbid the words with flag WARN
+#FORBIDWARN
+
+WARN W
+
+SFX A Y 1
+SFX A 0 s .
+
+REP 1
+REP foo bar
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/warn.dic b/extensions/spellcheck/hunspell/tests/unit/data/warn.dic
new file mode 100644
index 0000000000..d63f6047ea
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/warn.dic
@@ -0,0 +1,3 @@
+1
+foo/WA
+bar
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/warn.good b/extensions/spellcheck/hunspell/tests/unit/data/warn.good
new file mode 100644
index 0000000000..542f439a4f
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/warn.good
@@ -0,0 +1,2 @@
+foo
+foos
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/warn.test b/extensions/spellcheck/hunspell/tests/unit/data/warn.test
new file mode 100644
index 0000000000..7f44369060
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/warn.test
@@ -0,0 +1,4 @@
+#!/bin/sh
+DIR="`dirname $0`"
+NAME="`basename $0 .test`"
+$DIR/test.sh $NAME
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/zeroaffix.aff b/extensions/spellcheck/hunspell/tests/unit/data/zeroaffix.aff
new file mode 100644
index 0000000000..fdb047b0c1
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/zeroaffix.aff
@@ -0,0 +1,12 @@
+PSEUDOROOT X
+COMPOUNDFLAG Y
+
+SFX A Y 1
+SFX A 0 0 . >
+
+SFX B Y 1
+SFX B 0 0 . <ZERO>>
+
+SFX C Y 2
+SFX C 0 0/XAB . <ZERODERIV>
+SFX C 0 baz/XAB . <DERIV>
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/zeroaffix.dic b/extensions/spellcheck/hunspell/tests/unit/data/zeroaffix.dic
new file mode 100644
index 0000000000..72cba8d346
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/zeroaffix.dic
@@ -0,0 +1,3 @@
+2
+foo/XA <FOO
+bar/XABC <BAR
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/zeroaffix.good b/extensions/spellcheck/hunspell/tests/unit/data/zeroaffix.good
new file mode 100644
index 0000000000..b1fb3ba5c3
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/zeroaffix.good
@@ -0,0 +1,3 @@
+bar
+foo
+barbaz
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/zeroaffix.morph b/extensions/spellcheck/hunspell/tests/unit/data/zeroaffix.morph
new file mode 100644
index 0000000000..bcb788ad75
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/zeroaffix.morph
@@ -0,0 +1,13 @@
+> bar
+analyze(bar) = st:bar <BAR <ZERO>>
+analyze(bar) = st:bar <BAR >
+analyze(bar) = st:bar <BAR <ZERODERIV> <ZERO>>
+analyze(bar) = st:bar <BAR <ZERODERIV> >
+stem(bar) = bar
+> foo
+analyze(foo) = st:foo <FOO >
+stem(foo) = foo
+> barbaz
+analyze(barbaz) = st:bar <BAR <DERIV> <ZERO>>
+analyze(barbaz) = st:bar <BAR <DERIV> >
+stem(barbaz) = bar
diff --git a/extensions/spellcheck/hunspell/tests/unit/data/zeroaffix.test b/extensions/spellcheck/hunspell/tests/unit/data/zeroaffix.test
new file mode 100644
index 0000000000..7f44369060
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/data/zeroaffix.test
@@ -0,0 +1,4 @@
+#!/bin/sh
+DIR="`dirname $0`"
+NAME="`basename $0 .test`"
+$DIR/test.sh $NAME
diff --git a/extensions/spellcheck/hunspell/tests/unit/test_hunspell.js b/extensions/spellcheck/hunspell/tests/unit/test_hunspell.js
new file mode 100644
index 0000000000..28736fc023
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/test_hunspell.js
@@ -0,0 +1,250 @@
+/* Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/publicdomain/zero/1.0/
+ */
+
+const tests = [
+ ["affixes", "iso-8859-1"],
+ ["condition", "iso-8859-1"],
+ ["condition-utf", "UTF-8"],
+ ["base", "iso-8859-1"],
+ ["base-utf", "UTF-8"],
+ ["allcaps", "iso-8859-1"],
+ ["allcaps-utf", "UTF-8"],
+ ["allcaps2", "iso-8859-1"],
+ ["allcaps3", "iso-8859-1"],
+ ["keepcase", "iso-8859-1"],
+ ["i58202", "iso-8859-1"],
+ ["map", "iso-8859-1"],
+ ["rep", "iso-8859-1"],
+ ["sug", "iso-8859-1"],
+ ["sugutf", "UTF-8"],
+ ["phone", "iso-8859-1"],
+ ["flag", "iso-8859-1"],
+ ["flaglong", "iso-8859-1"],
+ ["flagnum", "iso-8859-1"],
+ ["flagutf8", "UTF-8"],
+ ["slash", "iso-8859-1"],
+ ["forbiddenword", "iso-8859-1"],
+ ["nosuggest", "iso-8859-1"],
+ ["alias", "iso-8859-1"],
+ ["alias2", "iso-8859-1"],
+ ["alias3", "iso-8859-1"],
+ ["breakdefault", "iso-8859-1"],
+ ["break", "UTF-8"],
+ ["needaffix", "iso-8859-1"],
+ ["needaffix2", "iso-8859-1"],
+ ["needaffix3", "iso-8859-1"],
+ ["needaffix4", "iso-8859-1"],
+ ["needaffix5", "iso-8859-1"],
+ ["circumfix", "iso-8859-1"],
+ ["fogemorpheme", "iso-8859-1"],
+ ["onlyincompound", "iso-8859-1"],
+ ["complexprefixes", "iso-8859-1"],
+ ["complexprefixes2", "iso-8859-1"],
+ ["complexprefixesutf", "UTF-8"],
+ ["conditionalprefix", "iso-8859-1"],
+ ["zeroaffix", "iso-8859-1"],
+ ["utf8", "UTF-8"],
+ ["utf8-bom", "UTF-8", { 1: "todo" }],
+ ["utf8-bom2", "UTF-8", { 1: "todo" }],
+ ["utf8-nonbmp", "UTF-8", { 1: "todo", 2: "todo", 3: "todo", 4: "todo" }],
+ ["compoundflag", "iso-8859-1"],
+ ["compoundrule", "iso-8859-1"],
+ ["compoundrule2", "iso-8859-1"],
+ ["compoundrule3", "iso-8859-1"],
+ ["compoundrule4", "iso-8859-1"],
+ ["compoundrule5", "UTF-8"],
+ ["compoundrule6", "iso-8859-1"],
+ ["compoundrule7", "iso-8859-1"],
+ ["compoundrule8", "iso-8859-1"],
+ ["compoundaffix", "iso-8859-1"],
+ ["compoundaffix2", "iso-8859-1"],
+ ["compoundaffix3", "iso-8859-1"],
+ ["checkcompounddup", "iso-8859-1"],
+ ["checkcompoundtriple", "iso-8859-1"],
+ ["simplifiedtriple", "iso-8859-1"],
+ ["checkcompoundrep", "iso-8859-1"],
+ ["checkcompoundcase2", "iso-8859-1"],
+ ["checkcompoundcaseutf", "UTF-8"],
+ ["checkcompoundpattern", "iso-8859-1"],
+ ["checkcompoundpattern2", "iso-8859-1"],
+ ["checkcompoundpattern3", "iso-8859-1"],
+ ["checkcompoundpattern4", "iso-8859-1"],
+ ["utfcompound", "UTF-8"],
+ ["checksharps", "iso-8859-1"],
+ ["checksharpsutf", "UTF-8"],
+ ["germancompounding", "iso-8859-1"],
+ ["germancompoundingold", "iso-8859-1"],
+ ["i35725", "iso-8859-1"],
+ ["i53643", "iso-8859-1"],
+ ["i54633", "iso-8859-1"],
+ ["i54980", "iso-8859-1", { 1: "todo", 3: "todo" }],
+ ["maputf", "UTF-8"],
+ ["reputf", "UTF-8"],
+ ["ignore", "iso-8859-1"],
+ [
+ "ignoreutf",
+ "UTF-8",
+ {
+ 1: "todo",
+ 2: "todo",
+ 3: "todo",
+ 4: "todo",
+ 5: "todo",
+ 6: "todo",
+ 7: "todo",
+ 8: "todo",
+ },
+ ],
+ ["1592880", "iso-8859-1"],
+ ["1695964", "iso-8859-1"],
+ ["1463589", "iso-8859-1"],
+ ["1463589-utf", "UTF-8"],
+ ["IJ", "iso-8859-1"],
+ ["i68568", "iso-8859-1"],
+ ["i68568utf", "UTF-8"],
+ ["1706659", "iso-8859-1"],
+ ["digits-in-words", "iso-8859-1"],
+ // ["colons-in-words", "iso-8859-1"], Suggestion test only
+ ["ngram-utf-fix", "UTF-8"],
+ [
+ "morph",
+ "us-ascii",
+ {
+ 11: "todo",
+ 12: "todo",
+ 13: "todo",
+ 14: "todo",
+ 15: "todo",
+ 16: "todo",
+ 17: "todo",
+ 18: "todo",
+ 19: "todo",
+ 20: "todo",
+ 21: "todo",
+ 22: "todo",
+ 23: "todo",
+ 24: "todo",
+ 25: "todo",
+ 26: "todo",
+ 27: "todo",
+ },
+ ],
+ ["1975530", "UTF-8"],
+ ["fullstrip", "iso-8859-1"],
+ ["iconv", "UTF-8"],
+ ["oconv", "UTF-8"],
+ ["encoding", "iso-8859-1", { 1: "todo", 3: "todo" }],
+ ["korean", "UTF-8"],
+ ["opentaal-forbiddenword1", "UTF-8"],
+ ["opentaal-forbiddenword2", "UTF-8"],
+ ["opentaal-keepcase", "UTF-8"],
+ ["arabic", "UTF-8"],
+ ["2970240", "iso-8859-1"],
+ ["2970242", "iso-8859-1"],
+ ["breakoff", "iso-8859-1"],
+ ["opentaal-cpdpat", "iso-8859-1"],
+ ["opentaal-cpdpat2", "iso-8859-1"],
+ ["2999225", "iso-8859-1"],
+ ["onlyincompound2", "iso-8859-1"],
+ ["forceucase", "iso-8859-1"],
+ ["warn", "iso-8859-1"],
+];
+
+// eslint-disable-next-line no-shadow
+function* do_get_file_by_line(file, charset) {
+ dump("getting file by line for file " + file.path + "\n");
+ dump("using charset1" + charset + "\n");
+ let fis = Cc["@mozilla.org/network/file-input-stream;1"].createInstance(
+ Ci.nsIFileInputStream
+ );
+ fis.init(file, 0x1 /* READONLY */, 0o444, Ci.nsIFileInputStream.CLOSE_ON_EOF);
+
+ let lis = Cc["@mozilla.org/intl/converter-input-stream;1"].createInstance(
+ Ci.nsIConverterInputStream
+ );
+ lis.init(fis, charset, 1024, 0);
+ lis.QueryInterface(Ci.nsIUnicharLineInputStream);
+
+ let val = {};
+ while (lis.readLine(val)) {
+ yield val.value;
+ val = {};
+ }
+}
+
+function do_run_test(checker, name, charset, todo_good, todo_bad) {
+ dump("\n\n\n\n");
+ dump("running test for " + name + "\n");
+ if (!checker) {
+ do_throw("Need spell checker here!");
+ }
+
+ let good = do_get_file("data/" + name + ".good", true);
+ let bad = do_get_file("data/" + name + ".wrong", true);
+ let sug = do_get_file("data/" + name + ".sug", true);
+
+ dump("Need some expected output\n");
+ Assert.ok(good.exists() || bad.exists() || sug.exists());
+
+ dump("Setting dictionary to " + name + "\n");
+ checker.dictionaries = [name];
+
+ if (good.exists()) {
+ var good_counter = 0;
+ for (const val of do_get_file_by_line(good, charset)) {
+ let todo = false;
+ good_counter++;
+ if (todo_good && todo_good[good_counter]) {
+ todo = true;
+ dump("TODO\n");
+ }
+
+ dump("Expect word " + val + " is spelled correctly\n");
+ if (todo) {
+ todo_check_true(checker.check(val));
+ } else {
+ Assert.ok(checker.check(val));
+ }
+ }
+ }
+
+ if (bad.exists()) {
+ var bad_counter = 0;
+ for (const val of do_get_file_by_line(bad, charset)) {
+ let todo = false;
+ bad_counter++;
+ if (todo_bad && todo_bad[bad_counter]) {
+ todo = true;
+ dump("TODO\n");
+ }
+
+ dump("Expect word " + val + " is spelled wrong\n");
+ if (todo) {
+ todo_check_false(checker.check(val));
+ } else {
+ Assert.ok(!checker.check(val));
+ }
+ }
+ }
+
+ // XXXkhuey test suggestions
+}
+
+function run_test() {
+ let spellChecker = Cc["@mozilla.org/spellchecker/engine;1"].getService(
+ Ci.mozISpellCheckingEngine
+ );
+
+ Assert.ok(!!spellChecker, "Should have a spell checker");
+ spellChecker.QueryInterface(Ci.mozISpellCheckingEngine);
+ let testdir = do_get_file("data/", false);
+ spellChecker.loadDictionariesFromDir(testdir);
+
+ function do_run_test_closure(test) {
+ let [name, charset, todo_good, todo_bad] = test;
+ do_run_test(spellChecker, name, charset, todo_good, todo_bad);
+ }
+
+ tests.forEach(do_run_test_closure);
+}
diff --git a/extensions/spellcheck/hunspell/tests/unit/test_hunspell_unicode_paths.js b/extensions/spellcheck/hunspell/tests/unit/test_hunspell_unicode_paths.js
new file mode 100644
index 0000000000..3fb4c78b59
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/test_hunspell_unicode_paths.js
@@ -0,0 +1,42 @@
+"use strict";
+
+const { XPCOMUtils } = ChromeUtils.importESModule(
+ "resource://gre/modules/XPCOMUtils.sys.mjs"
+);
+
+XPCOMUtils.defineLazyServiceGetter(
+ this,
+ "spellCheck",
+ "@mozilla.org/spellchecker/engine;1",
+ "mozISpellCheckingEngine"
+);
+
+const nsFile = Components.Constructor(
+ "@mozilla.org/file/local;1",
+ "nsIFile",
+ "initWithPath"
+);
+
+add_task(async function () {
+ let prof = do_get_profile();
+
+ let basePath = PathUtils.join(prof.path, "\u263a", "dictionaries");
+ let baseDir = nsFile(basePath);
+ await IOUtils.makeDirectory(basePath, { createAncestors: true });
+
+ let dicPath = PathUtils.join(basePath, "dict.dic");
+ let affPath = PathUtils.join(basePath, "dict.aff");
+
+ const WORD = "Flehgragh";
+
+ await IOUtils.writeUTF8(dicPath, `1\n${WORD}\n`);
+ await IOUtils.writeUTF8(affPath, "");
+
+ spellCheck.loadDictionariesFromDir(baseDir);
+ spellCheck.dictionaries = ["dict"];
+
+ ok(
+ spellCheck.check(WORD),
+ "Dictionary should have been loaded from a unicode path"
+ );
+});
diff --git a/extensions/spellcheck/hunspell/tests/unit/xpcshell.ini b/extensions/spellcheck/hunspell/tests/unit/xpcshell.ini
new file mode 100644
index 0000000000..badbe8debf
--- /dev/null
+++ b/extensions/spellcheck/hunspell/tests/unit/xpcshell.ini
@@ -0,0 +1,8 @@
+[DEFAULT]
+head =
+skip-if = toolkit == 'android'
+support-files = data/**
+firefox-appdir = browser
+
+[test_hunspell.js]
+[test_hunspell_unicode_paths.js]
diff --git a/extensions/spellcheck/hunspell/update.sh b/extensions/spellcheck/hunspell/update.sh
new file mode 100755
index 0000000000..5bed8cfb12
--- /dev/null
+++ b/extensions/spellcheck/hunspell/update.sh
@@ -0,0 +1,34 @@
+#!/bin/sh
+
+if [ $# -lt 1 ]; then
+ echo update.sh "<release tag name>"
+ exit 1
+fi
+
+hunspell_dir=`dirname $0`
+
+tmpclonedir=$(mktemp -d)
+git clone https://github.com/hunspell/hunspell --depth 1 --branch $1 ${tmpclonedir}
+# Back up mozilla files
+cp ${hunspell_dir}/src/moz.build ${tmpclonedir}/src/hunspell
+cp ${hunspell_dir}/src/moz.yaml ${tmpclonedir}/src/hunspell
+cp ${hunspell_dir}/src/sources.mozbuild ${tmpclonedir}/src/hunspell
+
+rm -rf ${hunspell_dir}/src
+cp -r ${tmpclonedir}/src/hunspell/ ${hunspell_dir}/src
+cp ${tmpclonedir}/license.hunspell ${hunspell_dir}/src
+cp ${tmpclonedir}/license.myspell ${hunspell_dir}/src
+cp ${tmpclonedir}/README.md ${hunspell_dir}/src
+rm ${hunspell_dir}/src/Makefile.am
+rm ${hunspell_dir}/src/filemgr.cxx
+rm ${hunspell_dir}/src/hunvisapi.h.in
+rm ${hunspell_dir}/src/hunzip.cxx
+rm ${hunspell_dir}/src/hunzip.hxx
+rm ${hunspell_dir}/src/utf_info.hxx
+rm -rf ${tmpclonedir}
+
+cd ${hunspell_dir}/src
+patch -p5 < ../patches/bug1410214.patch
+patch -p5 < ../patches/bug1653659.patch
+patch -p5 < ../patches/bug1739761.patch
+patch -p5 < ../patches/bug1838113.patch
diff --git a/extensions/spellcheck/idl/moz.build b/extensions/spellcheck/idl/moz.build
new file mode 100644
index 0000000000..caed8a2d58
--- /dev/null
+++ b/extensions/spellcheck/idl/moz.build
@@ -0,0 +1,12 @@
+# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
+# vim: set filetype=python:
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+XPIDL_SOURCES += [
+ "mozIPersonalDictionary.idl",
+ "mozISpellCheckingEngine.idl",
+]
+
+XPIDL_MODULE = "spellchecker"
diff --git a/extensions/spellcheck/idl/mozIPersonalDictionary.idl b/extensions/spellcheck/idl/mozIPersonalDictionary.idl
new file mode 100644
index 0000000000..61cdf4c48d
--- /dev/null
+++ b/extensions/spellcheck/idl/mozIPersonalDictionary.idl
@@ -0,0 +1,55 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "nsISupports.idl"
+
+interface nsIStringEnumerator;
+
+/**
+ * This interface represents a Personal Dictionary.
+ */
+[scriptable, uuid(7EF52EAF-B7E1-462B-87E2-5D1DBACA9048)]
+interface mozIPersonalDictionary : nsISupports {
+
+ /**
+ * Load the dictionary
+ */
+ void load();
+
+ /**
+ * Save the dictionary
+ */
+ void save();
+
+ /**
+ * Get the (lexicographically sorted) list of words
+ */
+ readonly attribute nsIStringEnumerator wordList;
+
+ /**
+ * Check a unicode string
+ */
+ boolean check(in AString word);
+
+ /**
+ * Add a word to the personal dictionary
+ */
+ void addWord(in AString word);
+
+ /**
+ * Remove a word from the personal dictionary
+ */
+ void removeWord(in AString word);
+
+ /**
+ * Add a word to the ignore all list
+ */
+ void ignoreWord(in AString word);
+
+ /**
+ * Clear the ignore list
+ */
+ void endSession();
+};
diff --git a/extensions/spellcheck/idl/mozISpellCheckingEngine.idl b/extensions/spellcheck/idl/mozISpellCheckingEngine.idl
new file mode 100644
index 0000000000..f3e67280f6
--- /dev/null
+++ b/extensions/spellcheck/idl/mozISpellCheckingEngine.idl
@@ -0,0 +1,84 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "nsISupports.idl"
+
+interface nsIFile;
+interface nsIURI;
+interface mozIPersonalDictionary;
+
+/**
+ * This interface represents a SpellChecker.
+ */
+[scriptable, uuid(8ba643a4-7ddc-4662-b976-7ec123843f10)]
+interface mozISpellCheckingEngine : nsISupports {
+ /**
+ * The names of the dictionaries currently used. These are either values
+ * from getDictionaryList or the empty array if no dictionary is selected.
+ * Setting this attribute to contain a value not in getDictionaryList will
+ * throw NS_ERROR_FILE_NOT_FOUND.
+ *
+ * If the dictionaries are changed to no dictionary (the empty array), an
+ * observer is allowed to set another dictionary before it returns.
+ */
+ attribute Array<ACString> dictionaries;
+
+ /**
+ * the personal dictionary
+ */
+ attribute mozIPersonalDictionary personalDictionary;
+
+ /**
+ * Get the list of dictionaries
+ */
+ Array<ACString> getDictionaryList();
+
+ /**
+ * check a word
+ */
+ boolean check(in AString word);
+
+ /**
+ * get a list of suggestions for a misspelled word
+ */
+ Array<AString> suggest(in AString word);
+
+ /**
+ * Load dictionaries from the specified dir
+ */
+ void loadDictionariesFromDir(in nsIFile dir);
+
+ /**
+ * Add dictionaries from a directory to the spell checker
+ */
+ void addDirectory(in nsIFile dir);
+
+ /**
+ * Remove dictionaries from a directory from the spell checker
+ */
+ void removeDirectory(in nsIFile dir);
+
+ /**
+ * Add a dictionary with the given language code and source URI. The URI
+ * must point to an affix file, with the ".aff" extension. The word list
+ * file must be in the same directory, with the same base name, and the
+ * ".dic" extension.
+ */
+ void addDictionary(in AString lang, in nsIURI file);
+
+ /**
+ * Remove a dictionary with the given language code and path. If the path does
+ * not match that of the current entry with the given language code, it is not
+ * removed.
+ *
+ * @returns True if the dictionary was found and removed.
+ */
+ bool removeDictionary(in AString lang, in nsIURI file);
+};
+
+%{C++
+#define SPELLCHECK_DICTIONARY_REMOVE_NOTIFICATION \
+ "spellcheck-dictionary-remove"
+%}
diff --git a/extensions/spellcheck/locales/en-US/hunspell/README_en_US.txt b/extensions/spellcheck/locales/en-US/hunspell/README_en_US.txt
new file mode 100644
index 0000000000..47503f12a6
--- /dev/null
+++ b/extensions/spellcheck/locales/en-US/hunspell/README_en_US.txt
@@ -0,0 +1,347 @@
+en_US-mozilla Hunspell Dictionary
+Generated from SCOWL Version 2020.12.07
+Wed Jan 25 07:25:51 CET 2023
+
+http://wordlist.sourceforge.net
+
+README file for English Hunspell dictionaries derived from SCOWL.
+
+These dictionaries are created using the speller/make-hunspell-dict
+script in SCOWL.
+
+The following dictionaries are available:
+
+ en_US (American)
+ en_CA (Canadian)
+ en_GB-ise (British with "ise" spelling)
+ en_GB-ize (British with "ize" spelling)
+ en_AU (Australian)
+
+ en_US-large
+ en_CA-large
+ en_GB-large (with both "ise" and "ize" spelling)
+ en_AU-large
+
+The normal (non-large) dictionaries correspond to SCOWL size 60 and,
+to encourage consistent spelling, generally only include one spelling
+variant for a word. The large dictionaries correspond to SCOWL size
+70 and may include multiple spelling for a word when both variants are
+considered almost equal. The larger dictionaries however (1) have not
+been as carefully checked for errors as the normal dictionaries and
+thus may contain misspelled or invalid words; and (2) contain
+uncommon, yet valid, words that might cause problems as they are
+likely to be misspellings of more common words (for example, "ort" and
+"calender").
+
+To get an idea of the difference in size, here are 25 random words
+only found in the large dictionary for American English:
+
+ Bermejo Freyr's Guenevere Hatshepsut Nottinghamshire arrestment
+ crassitudes crural dogwatches errorless fetial flaxseeds godroon
+ incretion jalape単o's kelpie kishkes neuroglias pietisms pullulation
+ stemwinder stenoses syce thalassic zees
+
+The en_US, en_CA and en_AU are the official dictionaries for Hunspell.
+The en_GB and large dictionaries are made available on an experimental
+basis. If you find them useful please send me a quick email at
+kevina@gnu.org.
+
+If none of these dictionaries suite you (for example, maybe you want
+the normal dictionary that also includes common variants) additional
+dictionaries can be generated at http://app.aspell.net/create or by
+modifying speller/make-hunspell-dict in SCOWL. Please do let me know
+if you end up publishing a customized dictionary.
+
+If a word is not found in the dictionary or a word is there you think
+shouldn't be, you can lookup the word up at http://app.aspell.net/lookup
+to help determine why that is.
+
+General comments on these list can be sent directly to me at
+kevina@gnu.org or to the wordlist-devel mailing lists
+(https://lists.sourceforge.net/lists/listinfo/wordlist-devel). If you
+have specific issues with any of these dictionaries please file a bug
+report at https://github.com/kevina/wordlist/issues.
+
+IMPORTANT CHANGES INTRODUCED In 2016.11.20:
+
+New Australian dictionaries thanks to the work of Benjamin Titze
+(btitze@protonmail.ch).
+
+IMPORTANT CHANGES INTRODUCED IN 2016.04.24:
+
+The dictionaries are now in UTF-8 format instead of ISO-8859-1. This
+was required to handle smart quotes correctly.
+
+IMPORTANT CHANGES INTRODUCED IN 2016.01.19:
+
+"SET UTF8" was changes to "SET UTF-8" in the affix file as some
+versions of Hunspell do not recognize "UTF8".
+
+ADDITIONAL NOTES:
+
+The NOSUGGEST flag was added to certain taboo words. While I made an
+honest attempt to flag the strongest taboo words with the NOSUGGEST
+flag, I MAKE NO GUARANTEE THAT I FLAGGED EVERY POSSIBLE TABOO WORD.
+The list was originally derived from N辿meth L叩szl坦, however I removed
+some words which, while being considered taboo by some dictionaries,
+are not really considered swear words in today's society.
+
+COPYRIGHT, SOURCES, and CREDITS:
+
+The English dictionaries come directly from SCOWL
+and is thus under the same copyright of SCOWL. The affix file is
+a heavily modified version of the original english.aff file which was
+released as part of Geoff Kuenning's Ispell and as such is covered by
+his BSD license. Part of SCOWL is also based on Ispell thus the
+Ispell copyright is included with the SCOWL copyright.
+
+The collective work is Copyright 2000-2018 by Kevin Atkinson as well
+as any of the copyrights mentioned below:
+
+ Copyright 2000-2018 by Kevin Atkinson
+
+ Permission to use, copy, modify, distribute and sell these word
+ lists, the associated scripts, the output created from the scripts,
+ and its documentation for any purpose is hereby granted without fee,
+ provided that the above copyright notice appears in all copies and
+ that both that copyright notice and this permission notice appear in
+ supporting documentation. Kevin Atkinson makes no representations
+ about the suitability of this array for any purpose. It is provided
+ "as is" without express or implied warranty.
+
+Alan Beale <biljir@pobox.com> also deserves special credit as he has,
+in addition to providing the 12Dicts package and being a major
+contributor to the ENABLE word list, given me an incredible amount of
+feedback and created a number of special lists (those found in the
+Supplement) in order to help improve the overall quality of SCOWL.
+
+The 10 level includes the 1000 most common English words (according to
+the Moby (TM) Words II [MWords] package), a subset of the 1000 most
+common words on the Internet (again, according to Moby Words II), and
+frequently class 16 from Brian Kelk's "UK English Wordlist
+with Frequency Classification".
+
+The MWords package was explicitly placed in the public domain:
+
+ The Moby lexicon project is complete and has
+ been place into the public domain. Use, sell,
+ rework, excerpt and use in any way on any platform.
+
+ Placing this material on internal or public servers is
+ also encouraged. The compiler is not aware of any
+ export restrictions so freely distribute world-wide.
+
+ You can verify the public domain status by contacting
+
+ Grady Ward
+ 3449 Martha Ct.
+ Arcata, CA 95521-4884
+
+ grady@netcom.com
+ grady@northcoast.com
+
+The "UK English Wordlist With Frequency Classification" is also in the
+Public Domain:
+
+ Date: Sat, 08 Jul 2000 20:27:21 +0100
+ From: Brian Kelk <Brian.Kelk@cl.cam.ac.uk>
+
+ > I was wondering what the copyright status of your "UK English
+ > Wordlist With Frequency Classification" word list as it seems to
+ > be lacking any copyright notice.
+
+ There were many many sources in total, but any text marked
+ "copyright" was avoided. Locally-written documentation was one
+ source. An earlier version of the list resided in a filespace called
+ PUBLIC on the University mainframe, because it was considered public
+ domain.
+
+ Date: Tue, 11 Jul 2000 19:31:34 +0100
+
+ > So are you saying your word list is also in the public domain?
+
+ That is the intention.
+
+The 20 level includes frequency classes 7-15 from Brian's word list.
+
+The 35 level includes frequency classes 2-6 and words appearing in at
+least 11 of 12 dictionaries as indicated in the 12Dicts package. All
+words from the 12Dicts package have had likely inflections added via
+my inflection database.
+
+The 12Dicts package and Supplement is in the Public Domain.
+
+The WordNet database, which was used in the creation of the
+Inflections database, is under the following copyright:
+
+ This software and database is being provided to you, the LICENSEE,
+ by Princeton University under the following license. By obtaining,
+ using and/or copying this software and database, you agree that you
+ have read, understood, and will comply with these terms and
+ conditions.:
+
+ Permission to use, copy, modify and distribute this software and
+ database and its documentation for any purpose and without fee or
+ royalty is hereby granted, provided that you agree to comply with
+ the following copyright notice and statements, including the
+ disclaimer, and that the same appear on ALL copies of the software,
+ database and documentation, including modifications that you make
+ for internal use or for distribution.
+
+ WordNet 1.6 Copyright 1997 by Princeton University. All rights
+ reserved.
+
+ THIS SOFTWARE AND DATABASE IS PROVIDED "AS IS" AND PRINCETON
+ UNIVERSITY MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR
+ IMPLIED. BY WAY OF EXAMPLE, BUT NOT LIMITATION, PRINCETON
+ UNIVERSITY MAKES NO REPRESENTATIONS OR WARRANTIES OF MERCHANT-
+ ABILITY OR FITNESS FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF THE
+ LICENSED SOFTWARE, DATABASE OR DOCUMENTATION WILL NOT INFRINGE ANY
+ THIRD PARTY PATENTS, COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS.
+
+ The name of Princeton University or Princeton may not be used in
+ advertising or publicity pertaining to distribution of the software
+ and/or database. Title to copyright in this software, database and
+ any associated documentation shall at all times remain with
+ Princeton University and LICENSEE agrees to preserve same.
+
+The 40 level includes words from Alan's 3esl list found in version 4.0
+of his 12dicts package. Like his other stuff the 3esl list is also in the
+public domain.
+
+The 50 level includes Brian's frequency class 1, words appearing
+in at least 5 of 12 of the dictionaries as indicated in the 12Dicts
+package, and uppercase words in at least 4 of the previous 12
+dictionaries. A decent number of proper names is also included: The
+top 1000 male, female, and Last names from the 1990 Census report; a
+list of names sent to me by Alan Beale; and a few names that I added
+myself. Finally a small list of abbreviations not commonly found in
+other word lists is included.
+
+The name files form the Census report is a government document which I
+don't think can be copyrighted.
+
+The file special-jargon.50 uses common.lst and word.lst from the
+"Unofficial Jargon File Word Lists" which is derived from "The Jargon
+File". All of which is in the Public Domain. This file also contain
+a few extra UNIX terms which are found in the file "unix-terms" in the
+special/ directory.
+
+The 55 level includes words from Alan's 2of4brif list found in version
+4.0 of his 12dicts package. Like his other stuff the 2of4brif is also
+in the public domain.
+
+The 60 level includes all words appearing in at least 2 of the 12
+dictionaries as indicated by the 12Dicts package.
+
+The 70 level includes Brian's frequency class 0 and the 74,550 common
+dictionary words from the MWords package. The common dictionary words,
+like those from the 12Dicts package, have had all likely inflections
+added. The 70 level also included the 5desk list from version 4.0 of
+the 12Dics package which is in the public domain.
+
+The 80 level includes the ENABLE word list, all the lists in the
+ENABLE supplement package (except for ABLE), the "UK Advanced Cryptics
+Dictionary" (UKACD), the list of signature words from the YAWL package,
+and the 10,196 places list from the MWords package.
+
+The ENABLE package, mainted by M\Cooper <thegrendel@theriver.com>,
+is in the Public Domain:
+
+ The ENABLE master word list, WORD.LST, is herewith formally released
+ into the Public Domain. Anyone is free to use it or distribute it in
+ any manner they see fit. No fee or registration is required for its
+ use nor are "contributions" solicited (if you feel you absolutely
+ must contribute something for your own peace of mind, the authors of
+ the ENABLE list ask that you make a donation on their behalf to your
+ favorite charity). This word list is our gift to the Scrabble
+ community, as an alternate to "official" word lists. Game designers
+ may feel free to incorporate the WORD.LST into their games. Please
+ mention the source and credit us as originators of the list. Note
+ that if you, as a game designer, use the WORD.LST in your product,
+ you may still copyright and protect your product, but you may *not*
+ legally copyright or in any way restrict redistribution of the
+ WORD.LST portion of your product. This *may* under law restrict your
+ rights to restrict your users' rights, but that is only fair.
+
+UKACD, by J Ross Beresford <ross@bryson.demon.co.uk>, is under the
+following copyright:
+
+ Copyright (c) J Ross Beresford 1993-1999. All Rights Reserved.
+
+ The following restriction is placed on the use of this publication:
+ if The UK Advanced Cryptics Dictionary is used in a software package
+ or redistributed in any form, the copyright notice must be
+ prominently displayed and the text of this document must be included
+ verbatim.
+
+ There are no other restrictions: I would like to see the list
+ distributed as widely as possible.
+
+The 95 level includes the 354,984 single words, 256,772 compound
+words, 4,946 female names and the 3,897 male names, and 21,986 names
+from the MWords package, ABLE.LST from the ENABLE Supplement, and some
+additional words found in my part-of-speech database that were not
+found anywhere else.
+
+Accent information was taken from UKACD.
+
+The VarCon package was used to create the American, British, Canadian,
+and Australian word list. It is under the following copyright:
+
+ Copyright 2000-2016 by Kevin Atkinson
+
+ Permission to use, copy, modify, distribute and sell this array, the
+ associated software, and its documentation for any purpose is hereby
+ granted without fee, provided that the above copyright notice appears
+ in all copies and that both that copyright notice and this permission
+ notice appear in supporting documentation. Kevin Atkinson makes no
+ representations about the suitability of this array for any
+ purpose. It is provided "as is" without express or implied warranty.
+
+ Copyright 2016 by Benjamin Titze
+
+ Permission to use, copy, modify, distribute and sell this array, the
+ associated software, and its documentation for any purpose is hereby
+ granted without fee, provided that the above copyright notice appears
+ in all copies and that both that copyright notice and this permission
+ notice appear in supporting documentation. Benjamin Titze makes no
+ representations about the suitability of this array for any
+ purpose. It is provided "as is" without express or implied warranty.
+
+ Since the original words lists come from the Ispell distribution:
+
+ Copyright 1993, Geoff Kuenning, Granada Hills, CA
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+
+ 1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+ 3. All modifications to the source code must be clearly marked as
+ such. Binary redistributions based on modified source code
+ must be clearly marked as modified versions in the documentation
+ and/or other materials provided with the distribution.
+ (clause 4 removed with permission from Geoff Kuenning)
+ 5. The name of Geoff Kuenning may not be used to endorse or promote
+ products derived from this software without specific prior
+ written permission.
+
+ THIS SOFTWARE IS PROVIDED BY GEOFF KUENNING AND CONTRIBUTORS ``AS IS'' AND
+ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL GEOFF KUENNING OR CONTRIBUTORS BE LIABLE
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ SUCH DAMAGE.
+
+Build Date: Wed Jan 25 07:25:51 CET 2023
diff --git a/extensions/spellcheck/locales/en-US/hunspell/README_mozilla.txt b/extensions/spellcheck/locales/en-US/hunspell/README_mozilla.txt
new file mode 100644
index 0000000000..e1918f0a32
--- /dev/null
+++ b/extensions/spellcheck/locales/en-US/hunspell/README_mozilla.txt
@@ -0,0 +1,2 @@
+See Firefox Source Docs for information about these scripts, and how to add new words.
+https://firefox-source-docs.mozilla.org/extensions/spellcheck/index.html
diff --git a/extensions/spellcheck/locales/en-US/hunspell/dictionary-sources/5-mozilla-added.txt b/extensions/spellcheck/locales/en-US/hunspell/dictionary-sources/5-mozilla-added.txt
new file mode 100644
index 0000000000..b1b9356809
--- /dev/null
+++ b/extensions/spellcheck/locales/en-US/hunspell/dictionary-sources/5-mozilla-added.txt
@@ -0,0 +1,7041 @@
+API's
+APIs
+ATPase
+ATPase's
+Ab's
+Abba
+Abbie
+Abbie's
+Abdel
+Abdel's
+AbeBooks
+Abie
+Abie's
+Abra
+Abra's
+Abramo
+Abramo's
+ActiveX
+ActiveX's
+Acura
+Acura's
+Adah
+Adah's
+Adair
+Adair's
+Adaline
+Adaline's
+Adamo
+Adamo's
+AddThis
+AddThis's
+Adda
+Adda's
+Addi
+Addi's
+Addy
+Addy's
+Ade
+Ade's
+Adel
+Adel's
+Adelaida
+Adelaida's
+Adelbert
+Adelbert's
+Adelheid
+Adelheid's
+Adelina
+Adelina's
+Adelle
+Adelle's
+Adena
+Adena's
+Adey
+Adey's
+Adham
+Adham's
+Adi
+Adi's
+Adina
+Adina's
+Adlai
+Adlai's
+Adolphe
+Adolphe's
+Adolphus
+Adolphus's
+Adore's
+Adria
+Adria's
+Adriane
+Adriane's
+Adrianna
+Adrianna's
+Adrianne
+Adrianne's
+Adriano
+Adriano's
+Adrien
+Adrien's
+Afton
+Afton's
+Agata
+Agata's
+Agathe
+Agathe's
+Agilent
+Agnese
+Agnese's
+Agosto
+Agosto's
+Aharon
+Aharon's
+Aidan
+Aidan's
+Aila
+Aila's
+Ailey
+Ailey's
+Aime
+Aime's
+Ainsley
+Ainsley's
+Ainslie
+Ainslie's
+Ajay
+Ajay's
+Akim
+Akim's
+Alain
+Alain's
+Alameda
+Alameda's
+Aland
+Aland's
+Alanna
+Alanna's
+Alanson
+Alanson's
+Alasdair
+Alasdair's
+Alastair
+Alastair's
+Albertina
+Albertina's
+Albertine
+Albertine's
+Albie
+Albie's
+Albina
+Albina's
+Albrecht
+Albrecht's
+Aldin
+Aldin's
+Aldis
+Aldis's
+Aldon
+Aldon's
+Aldous
+Aldous's
+Aldrich
+Aldrich's
+Aldridge
+Aldridge's
+Aldus
+Aldus's
+Aleksandr
+Aleksandr's
+Alena
+Alena's
+Alene
+Alene's
+Alessandra
+Alessandra's
+Alessandro
+Alessandro's
+Alethea
+Alethea's
+Alexa
+Alexa's
+Alexandr
+Alexandr's
+Alexandre
+Alexandre's
+Alexandrina
+Alexandrina's
+Alexandros
+Alexi
+Alexi's
+Alexia
+Alexia's
+Alexina
+Alexina's
+Alf
+Alf's
+Alfie
+Alfie's
+Alfons
+Alfons's
+Alfonse
+Alfonse's
+Algernon
+Algernon's
+Alia
+Alia's
+Alick
+Alick's
+Alida
+Alida's
+Alina
+Alina's
+Alis
+Alister
+Alister's
+Alix
+Alix's
+Alla
+Alla's
+Allard
+Allard's
+Allene
+Allene's
+Alleyn
+Alleyn's
+Allister
+Allister's
+Allyn
+Allyn's
+Almeria
+Almeria's
+Almira
+Almira's
+Alon
+Alon's
+Alonso
+Alonso's
+Aloysius
+Aloysius's
+Alric
+Alric's
+Alvan
+Alvan's
+Alvina
+Alvina's
+Alvis
+Alvis's
+Alvy
+Alvy's
+Alwin
+Alwin's
+Alwyn
+Alwyn's
+Alyosha
+Alyosha's
+Alys
+Alys's
+Alyss
+Amabel
+Amabel's
+Amalie
+Amalie's
+Amara
+Amara's
+Amata
+Amata's
+Ambros
+Ambros's
+Ambrose
+Ambrosio
+Ambrosio's
+Ambrosius
+Ambrosius's
+Ame
+Ame's
+Amelie
+Amelie's
+Amerigo
+Amerigo's
+Amery
+Amery's
+Ami
+Ami's
+Amil
+Amil's
+Amory
+Amory's
+Analise
+Analise's
+Anatol
+Anatol's
+Anders
+Andi
+Andi's
+Andie
+Andie's
+Andra
+Andra's
+Andras
+Andreas
+Andree
+Andree's
+Andrej
+Andrej's
+Andrey
+Andrey's
+Andria
+Andria's
+Andros
+Andrus
+Andrus's
+Anet
+Anet's
+Ange
+Ange's
+Angele
+Angele's
+Angeli
+Angeli's
+Angelika
+Angelika's
+Ania
+Ania's
+Annabella
+Annabella's
+Annalise
+Annalise's
+Anneliese
+Anneliese's
+Annelise
+Annelise's
+Annemarie
+Annemarie's
+Anni
+Anni's
+Annis
+Anny
+Anny's
+Ansel
+Ansel's
+Ansell
+Ansell's
+Ansley
+Ansley's
+Anson
+Anson's
+Anstice
+Anstice's
+Anthea
+Anthea's
+Antin
+Antin's
+Antonella
+Antonella's
+Antoni
+Antoni's
+Antonie
+Antonie's
+Antonietta
+Antonietta's
+Antonin
+Antonin's
+Antonina
+Antonina's
+Antonino
+Antonino's
+Any's
+Anya
+Anya's
+Arabella
+Arabella's
+Arabidopsis
+Archambault
+Archambault's
+Archy
+Archy's
+Arda
+Arda's
+Ardis
+Ardis's
+Aretha
+Aretha's
+Ari
+Ari's
+Arial
+Arial's
+Ariana
+Ariana's
+Arie
+Arie's
+Arielle
+Arielle's
+Arin
+Arin's
+Arlen
+Arlen's
+Arlette
+Arlette's
+Arley
+Arley's
+Arlie
+Arlie's
+Arlin
+Arlin's
+Arly
+Arly's
+Arman
+Arman's
+Armin
+Armin's
+Arnaldo
+Arnaldo's
+Arne
+Arni
+Arni's
+Arnie
+Arnie's
+Arnoldo
+Arnoldo's
+Arte
+Arte's
+Artemas
+Artemus
+Artemus's
+Artur
+Artur's
+Artus
+Artus's
+Arty's
+Arv
+Arv's
+Arvin
+Arvin's
+Asa
+Asa's
+Ase
+Ase's
+Ashby
+Ashby's
+Asher
+Ashleigh
+Ashleigh's
+Ashton
+Assyriaca
+Assyriaca's
+Astra
+Astra's
+Astrid
+Astrid's
+Athlon
+Athlon's
+Aube
+Aubert
+Aubert's
+Aubry
+Aubry's
+Audie
+Audie's
+Audre
+Audre's
+Augie
+Augie's
+Auguste
+Auguste's
+Augustin
+Augustin's
+Augusto
+Augusto's
+Aurea
+Aurea's
+Aurel
+Aurel's
+Aurelie
+Aurelie's
+Aurore
+Aurore's
+Aveline
+Aveline's
+Averell
+Averell's
+Averil
+Averil's
+Averill
+Averill's
+Avigdor
+Avigdor's
+Aviva
+Aviva's
+Avram
+Avram's
+Avril
+Avril's
+Axe
+Axe's
+Axel
+Aylmer
+Aylmer's
+Aymer
+Aymer's
+Ayn
+Ayn's
+Bab
+Bab's
+Babb
+Babb's
+Babbie
+Babbie's
+Babette
+Babette's
+Babs
+Bahasa
+Bahasa's
+Bailie
+Bailie's
+Baillie
+Baillie's
+Baily
+Baily's
+Bald's
+Bancorp
+Barbe
+Barbe's
+Barbee
+Barbee's
+Barbette
+Barbette's
+Barbey
+Barbey's
+Barde
+Barde's
+Bari
+Bari's
+Barret
+Barret's
+Barri
+Barri's
+Barris
+Bartel
+Bartel's
+Barthel
+Barthel's
+Bartlet
+Bartlet's
+Bartolomeo
+Bartolomeo's
+Bartram
+Bartram's
+Barty
+Barty's
+Bary
+Bary's
+Basia
+Basia's
+Basile
+Basile's
+Basilio
+Basilio's
+Basilius
+Basilius's
+Bastian
+Bastian's
+Bastien
+Bastien's
+Baudoin
+Baudoin's
+Bax
+Bayard
+Bea
+Bea's
+Beale
+Beale's
+Bebe
+Bebe's
+Becca
+Becca's
+Becka
+Becka's
+Beckham
+Beckham's
+Beckie
+Beckie's
+Bel
+Bel's
+Belkin
+Belkin's
+Bellevue
+Bellevue's
+Beltran
+Beltran's
+Belva
+Belva's
+Benedetta
+Benedetta's
+Benedetto
+Benedetto's
+Benedick
+Benedick's
+Benedicta
+Benedicta's
+Benedicto
+Benedicto's
+Benedikt
+Benedikt's
+Bengt
+Bengt's
+Benji
+Benji's
+Benjie
+Benjie's
+Benjy
+Benjy's
+Benn
+Benn's
+Benoit
+Benoit's
+Ber
+Ber's
+Berk
+Berk's
+Berke
+Berke's
+Berkley
+Berkley's
+Bernardine
+Bernhard
+Bernhard's
+Berni
+Berni's
+Berri
+Berri's
+Berthe
+Berthe's
+Berti
+Berti's
+Berton
+Berton's
+Bessy
+Bessy's
+Betsey
+Betsey's
+Betta
+Betta's
+Betti
+Bettina
+Bettina's
+Bevan
+Bevin
+Bevvy's
+BibSonomy
+BibSonomy's
+BibTeX
+BibTeX's
+Bibby
+Bibby's
+Bibi
+Bibi's
+Bil
+Bil's
+Bili
+Bili's
+Bing
+Bing's
+Bink
+Bink's
+Binky
+Binky's
+Binnie
+Binnie's
+Birgit
+Birgit's
+Birgitta
+Birgitta's
+Birk
+Birk's
+Biron
+Biron's
+BizRate
+BizRate's
+Bjorn
+Bjorn's
+Blakeley
+Blakeley's
+Blanch's
+Blane
+Blane's
+BlinkList
+BlinkList's
+Blithe's
+Bloomberg
+Bloomberg's
+Bo
+Bo's
+Bondy
+Bondy's
+Boothe
+Boothe's
+Bord
+Bord's
+Bourke
+Bourke's
+Boyce
+Boyce's
+Braden
+Braden's
+Bram
+Bram's
+Brande
+Brande's
+Brander
+Brander's
+Brannon
+Brannon's
+Brantley
+Brantley's
+Bree
+Bree's
+Bren
+Bren's
+Brenden
+Brenden's
+Brendon
+Brendon's
+Brenna
+Brenna's
+Brianne
+Brianne's
+Briant
+Briant's
+Bridie
+Bridie's
+Brien
+Brien's
+Brigg
+Brigg's
+Brigida
+Brigida's
+Brigit
+Brigit's
+Brigitta
+Brigitta's
+Briny's
+Brion
+Brion's
+Brita
+Brita's
+Britta
+Britta's
+Brittan
+Brittan's
+Brod
+Brod's
+Broderick
+Broderick's
+Brodie
+Brodie's
+Brody
+Brody's
+Bron
+Bron's
+Brose
+Brose's
+Bryn
+Bryn's
+Brynn
+Brynn's
+Bucky
+Bucky's
+Budd
+Budd's
+Buenos
+Burk
+Burk's
+Burkina
+Burkina's
+Burnaby
+Burnaby's
+Burnard
+Burnard's
+Byram
+Byram's
+Byrom
+Byrom's
+CAPTCHA
+CEOs
+CFCs
+Cad
+Cad's
+Caicos
+Caicos's
+Cale
+Cale's
+Calley
+Calley's
+Calli
+Calli's
+Cally
+Cally's
+Cambridgeshire
+Cambridgeshire's
+Cami
+Cami's
+Camila
+Camila's
+Cammie
+Cammie's
+Cammy
+Cammy's
+Candi
+Candi's
+Candida
+Candida's
+Candra
+Candra's
+CareerBuilder
+CareerBuilder's
+Caren
+Caren's
+Cari
+Cari's
+Caria
+Carin
+Carin's
+Carine
+Carine's
+Carita
+Carita's
+Carlen
+Carlen's
+Carleton
+Carleton's
+Carley
+Carley's
+Carlie
+Carlie's
+Carling
+Carling's
+Carlisle
+Carlisle's
+Carlota
+Carlotta
+Carlotta's
+Carmel
+Carmelita
+Carmelita's
+Carmina
+Carmina's
+Caro
+Caro's
+Carola
+Carola's
+Carolan
+Carolan's
+Carolus
+Carolus's
+Carolyne
+Carolyne's
+Caron
+Caron's
+Carrol
+Carrol's
+Caryl
+Caryl's
+Caryn
+Caryn's
+Casar
+Casar's
+Casi
+Casi's
+Cass
+Cass's
+Cassi
+Cassi's
+Cassini
+Cassini's
+Cassy
+Cassy's
+Catarina
+Catarina's
+Cate
+Cate's
+Caterina
+Caterina's
+Catharina
+Catharina's
+Catharine
+Catharine's
+Cathie
+Cathie's
+Cati
+Cati's
+Catie
+Catie's
+Catlin
+Catlin's
+Catrina
+Catrina's
+Catriona
+Catriona's
+Caye
+Caye's
+Caz
+Caz's
+Cece
+Cece's
+Cecilio
+Cecilio's
+Ced
+Ced's
+Ceil
+Ceil's
+Cele
+Cele's
+Celestia
+Celestia's
+Celestina
+Celestina's
+Celestine
+Celestine's
+Celie
+Celie's
+Celine
+Celine's
+Celle
+Celle's
+Centro
+Centro's
+Cesare
+Cesare's
+Chaim
+Chaim's
+Chancey
+Chancey's
+Chanda
+Chanda's
+Chane
+Chane's
+Channa
+Channa's
+Chantal
+Chantal's
+Chara
+Charis
+Charisse
+Charisse's
+Charlot
+Charlot's
+Charlotta
+Charlotta's
+Charlton
+Charmian
+Charmian's
+Chas
+ChatZilla
+ChatZilla's
+Chatham
+Chatham's
+Cher
+Chere
+Chere's
+Cherise
+Cherise's
+Cherish's
+Ches
+Chet
+Chet's
+Chev
+Chev's
+Chilton
+Chilton's
+Chloris
+Chloris's
+Choi
+Choi's
+Chrissie
+Chrissie's
+Chrissy
+Chrissy's
+Christabel
+Christabel's
+Christel
+Christel's
+Christen's
+Christiana
+Christiana's
+Christiane
+Christiane's
+Christianized
+Christianizing
+Christoph
+Christoph's
+Christophe
+Christos
+Christos's
+Cicely
+Cicely's
+Ciel
+Ciel's
+Cindi
+Cindi's
+Cingular
+Cingular's
+Cirillo
+Cirillo's
+Ciro
+Ciro's
+Cissy
+Cissy's
+Clari
+Clari's
+Claribel
+Claribel's
+Clarinda
+Clarinda's
+Clarisse
+Clarisse's
+Clarita
+Clarita's
+Clarkson
+Clarkson's
+Clary
+Clary's
+Claudian
+Claudian's
+Clayborne
+Clayborne's
+Clea
+Clea's
+Clemence
+Clemence's
+Clemente
+Clemente's
+Clementina
+Clementina's
+Clemmie
+Clemmie's
+Cleon
+Clerc
+Clerc's
+Cletus
+Cletus's
+Cleve
+Cleve's
+Clo
+Clo's
+Clotilda
+Clotilda's
+ColdFusion
+ColdFusion's
+Colet
+Coletta
+Coletta's
+Collen
+Collen's
+Collette
+Collette's
+Colline
+Colline's
+Colman
+Colman's
+Comcast
+Comcast's
+Computerworld
+Computerworld's
+Conant
+Conant's
+Conchita
+Conchita's
+Concordia
+Concordia's
+Congressionally
+Connor
+Connor's
+Conny
+Conny's
+Conrado
+Conrado's
+Conroy
+Conroy's
+Constancia
+Constancia's
+Constanta
+Constanta's
+Constantia
+Constantin
+Constantin's
+Constantino
+Constantino's
+Consuela
+Consuela's
+Coralie
+Coralie's
+Corbet
+Corbet's
+Corbett
+Corbett's
+Corbie
+Corbie's
+Corbin
+Corbin's
+Corby
+Cordell
+Cordell's
+Cordy
+Cordy's
+Coretta
+Coretta's
+Cori
+Cori's
+Corinna
+Corinna's
+Corliss
+Corliss's
+Corney
+Corney's
+Corny's
+Corrie
+Corrie's
+Corry
+Corry's
+Cort
+Cort's
+Cosette
+Cosette's
+Cosimo
+Cosimo's
+Cosme
+Cosme's
+Cosmo
+Cosmo's
+Costa
+Costa's
+Costanza
+Costanza's
+Councillor
+Councillor's
+Councillors
+Courtenay
+Courtenay's
+Craggy's
+Craigslist
+Craigslist's
+Cris
+Cris's
+Crissy
+Crissy's
+Crista
+Crista's
+Cristal
+Cristal's
+Cristian
+Cristian's
+Cristiano
+Cristiano's
+Cristobal
+Cristobal's
+Culley
+Culley's
+Cully
+Cully's
+Culver
+Culver's
+Cumbria
+Cumbria's
+Curcio
+Curcio's
+Curr
+Curr's
+Curran
+Curran's
+Currey
+Currey's
+Currie
+Currie's
+Curtice
+Curtice's
+Cy
+Cybil
+Cybil's
+Cyndi
+Cyndi's
+Cynthy
+Cynthy's
+Cyrille
+Cyrille's
+D'Arcy
+DRM
+Dacey
+Dacey's
+Dacia
+Daffy's
+Dag's
+Dagmar
+Dagmar's
+Dagny
+Dagny's
+Dal
+Dal's
+Dalia
+Dalia's
+Dalila
+Dalila's
+Dall
+Dall's
+Damara
+Damara's
+Damaris
+Damaris's
+Damiano
+Damiano's
+Danette
+Danette's
+Dani
+Dani's
+Dania
+Dania's
+Danica
+Danica's
+Daniela
+Daniela's
+Daniele
+Daniele's
+Daniella
+Daniella's
+Danna
+Danna's
+Danni
+Danni's
+Dar
+Dar's
+Dara
+Dara's
+Darcey
+Darcey's
+Darci
+Darci's
+Darcie
+Darcie's
+Dari
+Dari's
+Daria
+Daria's
+Daron
+Daron's
+Darsie
+Darsie's
+Darya
+Darya's
+Dasha
+Dasha's
+Dav
+Dav's
+Davey
+Davey's
+Davida
+Davida's
+Davide
+Davide's
+Davie
+Davie's
+Davin
+Davin's
+Davina
+Davina's
+Dayna
+Dayna's
+Daytona
+Daytona's
+De
+De's
+DealTime
+DealTime's
+Deane
+Deane's
+Deb
+Deb's
+Debbi
+Debbi's
+Debi
+Debi's
+Dede
+Dede's
+Deedee
+Deedee's
+Dela
+Dela's
+Delmore
+Delmore's
+Deloitte
+Deloitte's
+Deloria
+Deloria's
+Delphine
+Delphine's
+Demetri
+Demetri's
+Demetria
+Demetria's
+Demott
+Demott's
+Dene
+Deni
+Deni's
+Denney
+Denney's
+Dennie
+Dennie's
+Dennison
+Dennison's
+Deny's
+Denys
+Der
+Der's
+Derk
+Derk's
+Derry
+Des
+Deseret
+Deseret's
+Desi
+Desi's
+Dev
+Dev's
+Deva
+Deva's
+Devan
+Devan's
+Devlin
+Devlin's
+Dex
+Dex's
+Dhabi
+Dian
+Dian's
+Dickie
+Dickie's
+Dicky
+Dicky's
+Didi
+Didi's
+Dierdre
+Dierdre's
+Dieter
+Dieter's
+Digg
+Digg's
+Diggs
+Dimitri
+Dimitri's
+Dinny
+Dinny's
+Dione
+Dionisio
+Dionisio's
+Dita
+Dita's
+DivX
+DivX's
+Dodi
+Dodi's
+Dodie
+Dodie's
+Dolf
+Dolf's
+Dolley
+Dolley's
+Dolph
+Dolph's
+Dom
+Domenic
+Domenic's
+Domenico
+Domenico's
+Domini
+Domini's
+Dominik
+Dominik's
+Donal
+Donal's
+Dore
+Dore's
+Dorey
+Dorey's
+Dori
+Dori's
+Doria
+Doria's
+Dorie
+Dorie's
+Dorise
+Dorise's
+Doro
+Doro's
+Dorotea
+Dorotea's
+Dorothee
+Dorothee's
+Dorrie
+Dorrie's
+Dorris
+Dosi
+Dosi's
+Dottie
+Dottie's
+Dotty's
+Dougie
+Dougie's
+Dov
+Dov's
+Doy
+Doy's
+Dre
+Dre's
+Dreamweaver
+Dreamweaver's
+Drona
+Drona's
+Dru
+Dru's
+Drusilla
+Drusilla's
+Duff
+Duff's
+Duffie
+Duffie's
+Dugald
+Dugald's
+Dulce
+Dulce's
+Dulcie
+Dulcie's
+Dulcinea
+Dulcinea's
+Dunstan
+Dur
+Durand
+Durand's
+Durward
+Durward's
+Dyan
+Dyan's
+Dyna
+Dyna's
+Eadie
+Eadie's
+Eal
+Eal's
+Eamon
+Eamon's
+Early's
+Easton
+Easton's
+Eb
+Eb's
+Eba
+Eba's
+Ebba
+Ebba's
+Ebenezer
+Ebenezer's
+Eberhard
+Eberhard's
+Ecma
+Ecma's
+Eda
+Eda's
+Edd
+Edd's
+Ede
+Edgard
+Edgard's
+Edi
+Edi's
+Edie
+Edie's
+Edin
+Edin's
+Editha
+Editha's
+Edlin
+Edlin's
+Edouard
+Edouard's
+Eduard
+Eduard's
+Edvard
+Edvard's
+Edy
+Edy's
+Edythe
+Edythe's
+Efrem
+Efrem's
+Egan
+Egan's
+Egbert
+Egon
+Egon's
+Egor
+Egor's
+Einsteinian
+Einsteinian's
+Ekaterina
+Ekaterina's
+El
+Elaina
+Elaina's
+Elana
+Elana's
+Elayne
+Elayne's
+Elden
+Elden's
+Eldin
+Eldin's
+Eldredge
+Eldredge's
+Eldridge
+Eldridge's
+Eleanora
+Eleanora's
+Eleanore
+Eleanore's
+Elene
+Elene's
+Eleni
+Eleni's
+Eleonora
+Eleonora's
+Eleonore
+Eleonore's
+Elfreda
+Elfreda's
+Elfrida
+Elfrida's
+Elia
+Elie
+Elie's
+Elihu
+Elihu's
+Elisabet
+Elisabet's
+Elisabetta
+Elisabetta's
+Elissa
+Elissa's
+Elke
+Elke's
+Elle
+Elle's
+Ellery
+Ellery's
+Elli
+Elli's
+Ellsworth
+Ellsworth's
+Ellwood
+Ellwood's
+Elly
+Elly's
+Ellyn
+Ellyn's
+Elmore
+Elmore's
+Eloisa
+Eloisa's
+Elsbeth
+Elsbeth's
+Else's
+Elsevier
+Elsevier's
+Elsey
+Elsey's
+Elspeth
+Elspeth's
+Elston
+Elston's
+Elwin
+Elwin's
+Elwyn
+Elwyn's
+Ely
+Elyse
+Elyse's
+Elyssa
+Elyssa's
+Ema
+Ema's
+Emanuele
+Emanuele's
+Emeline
+Emeline's
+Emeryville
+Emeryville's
+Emilie
+Emilie's
+Emlen
+Emlen's
+Emlyn
+Emlyn's
+Emmaline
+Emmaline's
+Emmeline
+Emmeline's
+Emmerich
+Emmerich's
+Emmet
+Emmet's
+Emmie
+Emmie's
+EndNote
+EndNote's
+Engelbert
+Engelbert's
+Ennis
+Enrica
+Enrica's
+Ephrem
+Ephrem's
+Eran
+Eran's
+Erastus
+Erastus's
+Erda
+Erda's
+Erl
+Erl's
+Erroll
+Erroll's
+Erskine
+Erv
+Erv's
+Esdras
+Esme
+Esme's
+Essa
+Essa's
+Esta
+Esta's
+Estevan
+Estevan's
+Estrella
+Estrella's
+Ethelbert
+Ethelyn
+Ethelyn's
+Etienne
+Etienne's
+Ettie
+Ettie's
+Ettore
+Ettore's
+Etty
+Etty's
+Eudora
+Eudora's
+Eugen
+Eugen's
+Eugenius
+Eugenius's
+Eulalie
+Eulalie's
+Euphemia
+Euphemia's
+Europaea
+Europaea's
+Eustace
+Eustace's
+Eustacia
+Eustacia's
+Ev
+Ev's
+Evelina
+Evelina's
+Eveline
+Eveline's
+Everard
+Everard's
+Evey
+Evey's
+Evie
+Evie's
+Evin
+Evin's
+Evy
+Evy's
+Ewan
+Ewan's
+Ewart
+Ewart's
+Ewell
+Ewell's
+Ewen
+Ewen's
+Expedia
+Expedia's
+Ezequiel
+Ezequiel's
+FTM
+FTM's
+FTMs
+Faber
+Faber's
+Fabien
+Fabien's
+Fabio
+Fabio's
+Fae
+Fae's
+Fairfax
+Fairleigh
+Fairleigh's
+Fairlie
+Fairlie's
+Falkner
+Fallon
+Fallon's
+Fania
+Fania's
+Far's
+Fara
+Fara's
+Farah
+Farah's
+Farr
+Farr's
+Farrah
+Farrah's
+Farrand
+Farrand's
+Farrel
+Farrel's
+Farris
+Farris's
+Faso
+Faso's
+Faustina
+Faustina's
+Fayette
+Fayette's
+Fayre
+Fayre's
+Feliks
+Feliks's
+Feng
+Feng's
+Fenix
+Fenix's
+Fennec
+Fennec's
+Feodor
+Feodor's
+Ferd
+Ferd's
+Ferdie
+Ferdie's
+Ferdy
+Ferdy's
+Fernanda
+Fernanda's
+Fernande
+Fernande's
+Fernandina
+Fernandina's
+Ferne
+Ferne's
+Ferrel
+Ferrel's
+Fey's
+Fianna
+Fidelia
+Fidelia's
+Fidelio
+Fidelio's
+Fifi
+Fifi's
+Filip
+Filip's
+Filippo
+Filippo's
+FilmSpot
+FilmSpot's
+Filmer
+Filmer's
+Fina
+Fina's
+FindArticles
+FindArticles's
+FindLaw
+FindLaw's
+Findlay
+Findlay's
+Findley
+Findley's
+Fitz
+Fitz's
+Flem
+Flemming
+Flemming's
+Fletch
+Fletch's
+Fleur
+Fleur's
+Flickr
+Flickr's
+Flin
+Flin's
+Flinn
+Flinn's
+Flor
+Flor's
+Flore
+Flore's
+Florencia
+Florencia's
+Florette
+Florette's
+Florian
+Florian's
+Florinda
+Florinda's
+Floris
+Florrie
+Florrie's
+Flossy's
+Fons
+Forex
+Forex's
+Forrester
+Forrester's
+Fortran
+Foss
+Foss's
+Francesco
+Francesco's
+Franklyn
+Franklyn's
+Franky
+Franky's
+Frannie
+Frannie's
+Frans
+Fransisco
+Fransisco's
+Franzen
+Franzen's
+Frasier
+Frasier's
+Frazer
+Frederica
+Frederica's
+Frederich
+Frederich's
+Frederico
+Frederico's
+Frederik
+Frederik's
+Frederique
+Frederique's
+Fredrika
+Fredrika's
+Free's
+FreeBSD
+FreeBSD's
+Freeland
+Freeland's
+Friederike
+Friederike's
+Friedrich
+Friulian
+Friulian's
+FrontPage
+FrontPage's
+Fukushima
+Fukushima's
+Fulvia
+Fulvia's
+GDPR
+GHz's
+GaAs
+Gabby
+Gabby's
+Gabe
+Gabe's
+Gabi
+Gabi's
+Gabriele
+Gabriele's
+Gabriella
+Gabriella's
+Gaby
+Gaby's
+Gae
+Gae's
+Galina
+Galina's
+Galvan
+Galvan's
+Galvin
+Galvin's
+Gamaliel
+Gamaliel's
+GameCube
+GameCube's
+GameFAQs
+GameFAQs's
+GameSpot
+GameSpot's
+Gan
+Gan's
+Gannon
+Gannon's
+Garamond
+Gard
+Gardiner
+Gare
+Gare's
+Garey
+Garey's
+Garrard
+Garrard's
+Garvin
+Garvin's
+Garwood
+Garwood's
+Gaspar
+Gaspard
+Gaspard's
+Gasparo
+Gasparo's
+Gasper
+Gasper's
+Gaston
+Gaston's
+Gauthier
+Gauthier's
+Gav
+Gav's
+Gavan
+Gavan's
+Gaven
+Gaven's
+Gaye
+Gaye's
+Gaylord
+Gaylord's
+Gaynor
+Gaynor's
+Gbps
+Gecko
+Gecko's
+GenBank
+GenBank's
+Genevra
+Genevra's
+Genia
+Genia's
+Genna
+Genna's
+Genny
+Genny's
+Geno
+Geno's
+Geoff
+Geoff's
+Geordie
+Georg
+Georg's
+Georgi
+Georgi's
+Georgiana
+Georgiana's
+Georgianna
+Georgianna's
+Georgie
+Georgie's
+Georgy
+Georgy's
+Gerda
+Gerda's
+Gerhard
+Gerhard's
+Gerhardt
+Gerhardt's
+Geri
+Geri's
+Germain
+Germain's
+Germaine
+Germaine's
+Gerome
+Gerome's
+Gerrard
+Gerrard's
+Gerri
+Gerri's
+Gert
+Gert's
+Gertie
+Gertie's
+Gertrud
+Gertrud's
+Gertrudis
+Gertrudis's
+Gerty
+Gerty's
+Gery
+Gery's
+Giacomo
+Giacomo's
+Gian
+Gian's
+Gianna
+Gianna's
+Gianni
+Gianni's
+Gib
+Gib's
+Gibb
+Gibb's
+Giff
+Giff's
+Giffard
+Giffard's
+Gifford
+Gifford's
+Gigi
+Gigi's
+Gilberte
+Gilberte's
+Gillan
+Gillan's
+Gilles
+Gillie's
+Gilly
+Gilly's
+Ginevra
+Ginevra's
+Ginnie
+Ginnie's
+Giordano
+Giordano's
+Giorgi
+Giorgi's
+Giorgio
+Giorgio's
+Giovanna
+Giovanna's
+Giraud
+Gisela
+Gisela's
+Gisele
+Gisele's
+Giulia
+Giulia's
+Giulietta
+Giulietta's
+Giulio
+Giulio's
+Giusto
+Giusto's
+Glendon
+Glendon's
+Glennie
+Glennie's
+Gloriana
+Gloriana's
+Gloucestershire
+Gloucestershire's
+Glyn
+Glyn's
+Glynis
+Glynis's
+Glynn
+Glynn's
+GmbH
+Godfrey
+Godfrey's
+Godwin
+Goldy
+Goldy's
+Goran
+Goran's
+Gordan
+Gordan's
+Gorden
+Gorden's
+Gordie
+Gordie's
+Gordy
+Gordy's
+Gottfried
+Gottfried's
+Gracia
+Gracia's
+Graeme
+Graeme's
+Gran's
+Grange
+Granger
+Grannie
+Grannie's
+Grantham
+Grantham's
+Grantley
+Grantley's
+Granville
+Granville's
+Grata
+Grata's
+Gratia
+Gratia's
+Grazia
+Grazia's
+Gregoire
+Gregoire's
+Gregor
+Gregor's
+Gregorius
+Gregorius's
+Grenville
+Grete
+Grete's
+Gretna
+Gretna's
+Gretta
+Gretta's
+Grier
+Grier's
+Griff
+Griff's
+Griffiths
+Griselda
+Griswold
+Griswold's
+Guenevere
+Guenevere's
+Guglielmo
+Guglielmo's
+Gui
+Gui's
+Guido's
+Guilbert
+Guilbert's
+Guildford
+Guildford's
+Guillaume
+Guillaume's
+Gunilla
+Gunilla's
+Gunter
+Gussie
+Gussie's
+Gussy's
+Gusta
+Gusta's
+Gustaf
+Gustaf's
+Gustave
+Gustave's
+Gusti
+Gusti's
+Gusty's
+Gwendolen
+Gwendolen's
+Gwyneth
+Gwyneth's
+Gwynne
+Gwynne's
+HTTPS
+HVAC
+Had's
+Hadleigh
+Hadleigh's
+Hadley
+Hadley's
+Hadria
+Hadria's
+Hagan
+Hagan's
+Hagen
+Hailey
+Hailey's
+Hakeem
+Hakeem's
+Hakim
+Hakim's
+Hali
+Hali's
+Hally
+Hally's
+Hamas
+Hamas's
+Hamel
+Hamel's
+Hamid
+Hamid's
+Hamil
+Hamil's
+Hamish
+Hamish's
+Hammad
+Hammad's
+Hana
+Hana's
+Hanan
+Hanan's
+Hanni
+Hanni's
+Happy's
+Harald
+Harald's
+Harbert
+Harbert's
+Harcourt
+Harcourt's
+Harland
+Harland's
+Harlin
+Harlin's
+Harman
+Harman's
+Harmonia
+Harmonia's
+Harmonie
+Harmonie's
+Haroun
+Haroun's
+Harri
+Harri's
+Harriette
+Harriette's
+Harriot
+Harriot's
+Harriott
+Harriott's
+Hartley
+Hartwell
+Hartwell's
+Harv
+Harv's
+Harwell
+Harwell's
+Hashim
+Hashim's
+Haslett
+Haslett's
+Hassan
+Hassan's
+Hastie
+Hastie's
+Hasty's
+Hatti
+Hatti's
+Hatty
+Hatty's
+Haydon
+Haydon's
+Hayley
+Hayley's
+Hayyim
+Hayyim's
+Hazlett
+Hazlett's
+Hedda
+Hedda's
+Hedi
+Hedi's
+Hedwig
+Hedwig's
+Hedy
+Hedy's
+Hejira's
+Helaina
+Helaina's
+Helge
+Helge's
+Hellenized
+Helvetica
+Hendrik
+Hendrik's
+Henriette
+Henriette's
+Hephzibah
+Hephzibah's
+Herbie
+Herbie's
+Herby
+Herby's
+Herc
+Herc's
+Hercule
+Hercule's
+Hermann
+Hermann's
+Hermia
+Hermia's
+Hermine
+Hermine's
+Hermione
+Hermione's
+Hermon
+Hernando
+Hernando's
+Herold
+Herold's
+Hersch
+Hersch's
+Hersh
+Hersh's
+Herta
+Herta's
+Hertfordshire
+Hertfordshire's
+Hertha
+Hertha's
+Herve
+Herve's
+Hervey
+Hervey's
+Hestia
+Hestia's
+Hetty
+Hetty's
+Hew's
+Hewett
+Hewett's
+Hi's
+Hilde
+Hilde's
+Hildegarde
+Hildegarde's
+Hildy
+Hildy's
+Hillard
+Hillard's
+Hillery
+Hillery's
+Hilliard
+Hillier
+Hillier's
+Hillsborough
+Hillsborough's
+Hilly's
+Hillyer
+Hillyer's
+Hinze
+Hinze's
+Hirsch
+Hirsch's
+Hispanica
+Hispanica's
+Hobie
+Hobie's
+Hollandica
+Hollandica's
+Honoria
+Honoria's
+Horatia
+Horatia's
+Horatius
+Horatius's
+Horst
+Horst's
+Hort
+Hort's
+Hortense
+Hortensia
+Hortensia's
+Hotmail
+Hotmail's
+Houghton
+Houghton's
+Howey
+Howey's
+Howie
+Howie's
+Hoyt
+Hoyt's
+Hughie
+Hugues
+Hugues's
+Hulda
+Hulda's
+Humbert
+Humbert's
+Humfrey
+Humfrey's
+Husein
+Husein's
+Hy
+Hy's
+Hyacinthe
+Hyacinthe's
+Hyatt
+Hyatt's
+Hyman
+Hyman's
+Hymie
+IANAL
+IIRC
+IMDb
+IMDb's
+IMDbPro
+IMDbPro's
+IPO's
+IPOs
+ISP's
+ISPs
+Iain
+Iain's
+Ianthe
+Ianthe's
+Ibrahim
+Ibrahim's
+Ichabod
+Ichabod's
+Iggy
+Iggy's
+Ignace
+Ignace's
+Ignaz
+Ignaz's
+Ignazio
+Ignazio's
+Ikey
+Ikey's
+Ileana
+Ileana's
+Ilka
+Ilka's
+Illa
+Illa's
+Ilsa
+Ilsa's
+Ilse
+Ilse's
+Immanuel
+Imogen
+Imogen's
+Inga
+Inga's
+Ingeborg
+Ingeborg's
+Ingemar
+Ingemar's
+Inger
+Inger's
+Inglis
+Inglis's
+Ingmar
+Ingmar's
+Inigo
+Inigo's
+Inna
+Inna's
+Inness
+Inness's
+Innis
+Innis's
+Iona
+Irena
+Irena's
+Irina
+Irina's
+Irv
+Irv's
+Isa
+Isaak
+Isaak's
+Isadora
+Isadora's
+Isadore
+Isadore's
+Isak
+Isak's
+Isidor
+Isidor's
+Isidora
+Isidora's
+Isidore
+Isidore's
+Isidoro
+Isidoro's
+Islamica
+Islamica's
+Isobel
+Isobel's
+Issy
+Issy's
+Italia
+Italia's
+Ivar
+Ivar's
+Ive
+Ive's
+Iver
+Iver's
+Ivie
+Ivie's
+Ivoire
+Ivor
+Ivor's
+Izzy
+Izzy's
+JPEG's
+JPEGs
+JSON
+Jabez
+Jabez's
+Jacinta
+Jacinta's
+Jacki
+Jacki's
+Jacklin
+Jacklin's
+Jacobo
+Jacobo's
+Jacqui
+Jacqui's
+Jacquie
+Jacquie's
+Jada
+Jada's
+Jae
+Jae's
+Jakob
+Jakob's
+Jameson
+Jamey
+Jamey's
+Jamil
+Jamil's
+Jamison
+Jamison's
+Janek
+Janek's
+Janey
+Janey's
+Janina
+Janos
+Janos's
+Jany
+Jany's
+Jarret
+Jarret's
+Jase
+Jase's
+Jasmin
+Jasmin's
+Jaye
+Jaye's
+Jayme
+Jayme's
+Jeana
+Jeana's
+Jeane
+Jeane's
+Jedediah
+Jedediah's
+Jedidiah
+Jedidiah's
+Jehu
+Jemima
+Jemima's
+Jemmy
+Jemmy's
+Jen
+Jen's
+Jena
+Jena's
+Jenn
+Jenn's
+Jenni
+Jenni's
+Jeno
+Jeno's
+Jens
+Jere
+Jere's
+Jeremias
+Jeremias's
+Jeremie
+Jeremie's
+Jerrie
+Jerrie's
+Jervis
+Jervis's
+Jessamine
+Jessamine's
+Jessamyn
+Jessamyn's
+Jessey
+Jessey's
+Jessi
+Jessi's
+Jessy
+Jessy's
+Jethro
+Jilly
+Jilly's
+Joachim
+Joana
+Joana's
+Joane
+Joane's
+Joanie
+Joanie's
+Joannes
+Joby
+Joby's
+Jocelin
+Jocelin's
+Jocelyne
+Jocelyne's
+Jocko
+Jocko's
+Joelle
+Joelle's
+Johan
+Johan's
+Jojo
+Jojo's
+Joli
+Joli's
+Jolie
+Jolie's
+Joly
+Joly's
+Jone
+Jone's
+Jordana
+Jordana's
+Jordon
+Jordon's
+Jori
+Jori's
+Jory
+Jory's
+Joscelin
+Joscelin's
+Josepha
+Josepha's
+Josey
+Josey's
+Josias
+Josias's
+Josselyn
+Josselyn's
+Jourdain
+Jourdain's
+Jourdan
+Jourdan's
+Joya
+Joya's
+Joye
+Joye's
+Jozef
+Jozef's
+Jud
+Judi
+Judi's
+Jule
+Jule's
+Juli
+Juli's
+Juliane
+Juliane's
+Julianna
+Julianna's
+Julienne's
+Juneteenth
+Juneteenth's
+Junia
+Junia's
+Junie
+Junie's
+Justina
+Justina's
+Justus
+Justus's
+Jyoti
+Jyoti's
+Kahlil
+Kahlil's
+Kai
+Kai's
+Kaia
+Kaia's
+Kaila
+Kaila's
+Kain
+Kain's
+Kaine
+Kaine's
+Kaitlyn
+Kaitlyn's
+Kaja
+Kaja's
+Kala
+Kala's
+Kalil
+Kalil's
+Kalina
+Kalina's
+Kalle
+Kalle's
+Kandy
+Kania
+Kania's
+Kanya
+Kanya's
+Kare
+Kare's
+Karel
+Karel's
+Karim
+Karim's
+Karine
+Karine's
+Karlen
+Karlen's
+Karly
+Karly's
+Karna
+Karna's
+Karnataka
+Karnataka's
+Karolina
+Karolina's
+Karoline
+Karoline's
+Karoly
+Karoly's
+Karon
+Karon's
+Kaspar
+Kaspar's
+Kasper
+Kasper's
+Kass
+Kassandra
+Kassandra's
+Kat
+Kat's
+Kata
+Kata's
+Katalin
+Katalin's
+Katerina
+Katerina's
+Kath
+Kath's
+Katha
+Katha's
+Katharina
+Katharina's
+Kathe
+Kathe's
+Katherina
+Katherina's
+Kathi
+Kathi's
+Kati
+Kati's
+Katinka
+Katinka's
+Katrine
+Katrinka
+Katrinka's
+Katya
+Katya's
+Kavanaugh
+Kavanaugh's
+Kaycee
+Kaycee's
+Kaylee
+Kaylee's
+Kayne
+Kayne's
+Kean
+Keane
+Keane's
+Kearney
+Kearney's
+Keefe
+Keefe's
+Keefer
+Keefer's
+Keeley
+Keeley's
+Keely
+Keely's
+Keene
+Keene's
+Keir
+Keir's
+Kellen
+Kellen's
+Kendal
+Kendal's
+Kendell
+Kendell's
+Kendricks
+Kenn
+Kenn's
+Kenna
+Kenna's
+Kennett
+Kennett's
+Ker
+Ker's
+Kerala
+Kerala's
+Kerby
+Kerby's
+Kerk
+Kerk's
+Kerrie
+Kerrie's
+Kerstin
+Kerstin's
+Kerwin
+Kerwin's
+Kev
+Kev's
+Kevan
+Kevan's
+Khalil
+Khalil's
+Khazarica
+Khazarica's
+Ki
+Ki's
+Kile
+Kile's
+Kiley
+Kiley's
+Kilian
+Kilian's
+Killian
+Killian's
+Kimball
+Kimball's
+Kimbell
+Kimbell's
+Kimble
+Kimble's
+Kimmy
+Kimmy's
+Kincaid
+Kincaid's
+Kingsley
+Kinko
+Kinsley
+Kinsley's
+Kipp
+Kipp's
+Kira
+Kira's
+Kiri
+Kiri's
+Kitts
+Kitts's
+Klara
+Klara's
+Klemens
+Klemens's
+Klement
+Klement's
+Konstantin
+Konstantin's
+Koo
+Koo's
+Kora
+Kora's
+Kore
+Kore's
+Koren
+Koren's
+Kori
+Kori's
+Kort
+Kort's
+Kosovo
+Kosovo's
+Kristian
+Kristian's
+Krystyna
+Krystyna's
+Kuala
+Kuala's
+Kubernetes
+Kubernetes's
+Kyiv
+Kyiv's
+Kyla
+Kyla's
+Kylie
+Kylie's
+Kym
+Kym's
+LISTSERV
+LISTSERV's
+Laetitia
+Laetitia's
+Lainey
+Lainey's
+Lakers
+Lakers's
+Lalo
+Lalo's
+Lamond
+Lamond's
+Laney
+Laney's
+Langston
+Langston's
+Lani
+Lani's
+Lanie
+Lanie's
+Lanna
+Lanna's
+Lari
+Lari's
+Larisa
+Larisa's
+Larissa
+Larissa's
+Laughton
+Launce
+Launce's
+Laure
+Laure's
+Laurens
+Lauretta
+Lauretta's
+Laurette
+Laurette's
+Lauryn
+Lauryn's
+Lavina
+Lavina's
+Lavinia
+Lavinia's
+Lawry
+Lawry's
+Layne
+Layne's
+Lazar
+Lazar's
+Lazare
+Lazare's
+Leandra
+Leandra's
+Leela
+Leela's
+Leena
+Leena's
+Leese
+Leese's
+Leia
+Leia's
+Leica
+Leica's
+Leighton
+Leighton's
+Lek
+Lek's
+Lem
+Lem's
+Lennard
+Lennard's
+Lennie
+Lennie's
+Leone
+Leone's
+Leonhard
+Leonhard's
+Leonie
+Leonie's
+Leonora
+Leonora's
+Leonore
+Leonore's
+Leontine
+Leontine's
+Leora
+Leora's
+Leroi
+Leroi's
+Letizia
+Letizia's
+Lettie
+Lettie's
+Letty
+Letty's
+Lev
+Levey
+Levey's
+Levin
+Levin's
+Levon
+Levon's
+Lewes
+Lexi
+Lexi's
+Lexie
+Lexie's
+LexisNexis
+LexisNexis's
+Lexy
+Lexy's
+Leyla
+Leyla's
+Lia
+Lia's
+Liam
+Liam's
+Lian
+Lian's
+Liana
+Liana's
+Liane
+Liane's
+Lianne
+Lianne's
+Libbey
+Libbey's
+Libbie
+Libbie's
+Lida
+Lida's
+Lief's
+Lil
+Lil's
+Lilah
+Lilah's
+Liliane
+Liliane's
+Lilias
+Lilla
+Lilla's
+Lilli
+Lilli's
+Linc
+Linc's
+Lincolnshire
+Lincolnshire's
+Lindi
+Lindi's
+Lindon
+Lindon's
+Linea
+Linea's
+LinkedIn
+LinkedIn's
+Linn
+Linn's
+Linnea
+Linnea's
+Linnell
+Linnell's
+Lisbeth
+Lisbeth's
+Lise
+Lise's
+Lisette
+Lisette's
+Lisle
+Lisle's
+Lissa
+Lissa's
+Lissy
+Lissy's
+Lita
+Lita's
+Liv
+Liv's
+LiveJournal
+LiveJournal's
+Livvy
+Livvy's
+Lizabeth
+Lizabeth's
+Lizbeth
+Lizbeth's
+Lizette
+Lizette's
+Lodovico
+Lodovico's
+Logitech
+Logitech's
+Lolly's
+Lona
+Lona's
+Loni
+Loni's
+Lonny
+Lonny's
+LookSmart
+LookSmart's
+Lorant
+Lorant's
+Lorenza
+Lorenza's
+Lorette
+Lorette's
+Loria
+Loria's
+Lorin
+Lorin's
+Lorinda
+Lorinda's
+Lorne
+Lorne's
+Lory
+Lory's
+Lotta
+Lotta's
+Lotte
+Lotte's
+Lotti
+Lotti's
+Lotty
+Lotty's
+Lovell
+Loy
+Loy's
+Luca
+Luca's
+Luci
+Luci's
+Luciana
+Luciana's
+Lucie
+Lucie's
+Lucienne
+Lucienne's
+Lucina
+Lucky's
+Ludovico
+Ludovico's
+Ludvig
+Ludvig's
+Luise
+Luise's
+Lukas
+Lukas's
+Lura
+Lura's
+Ly
+Ly's
+Lycos
+Lycos's
+Lyda
+Lyda's
+Lydie
+Lydie's
+Lydon
+Lydon's
+Lyn
+Lyn's
+Lynde
+Lynde's
+Lyndsay
+Lyndsay's
+Lyndsey
+Lyndsey's
+Lyssa
+Lyssa's
+MDF
+MHz's
+MPEG's
+MPEGs
+MTF
+MTF's
+MTFs
+Mab
+Macau
+Macau's
+Macromedia
+Macromedia's
+Mada
+Mada's
+Madalyn
+Madalyn's
+Maddalena
+Maddalena's
+Maddi
+Maddi's
+Maddie
+Maddie's
+Maddy
+Maddy's
+Madelaine
+Madelaine's
+Madelon
+Madelon's
+Magda
+Magda's
+Magdalen
+Maggi
+Maggi's
+Maggy
+Maggy's
+Mahala
+Mahala's
+Mahalia
+Mahalia's
+Mahmoud
+Mahmoud's
+Mahmud
+Mahmud's
+Maia
+Maia's
+Mair
+Mair's
+Maire
+Maire's
+Maison
+Maison's
+Mal
+Mala
+Mala's
+Malia
+Malia's
+Malina
+Malina's
+Malissa
+Malissa's
+Malva
+Malva's
+Malvin
+Malvin's
+Malvina
+Malvina's
+Mame
+Mame's
+Manda
+Manda's
+Mandel
+Mandel's
+Mandi
+Mandi's
+Mandie
+Mandie's
+Mannie
+Mannie's
+Manny
+Manny's
+Mano
+Mano's
+Manolo
+Manolo's
+Manon
+Manon's
+Manya
+Manya's
+MapQuest
+MapQuest's
+Marcela
+Marcela's
+Marcelle
+Marcelle's
+Marcello
+Marcello's
+Marcellus
+Maren
+Maren's
+Marga
+Marga's
+Margalit
+Margalit's
+Margareta
+Margareta's
+Margarete
+Margarete's
+Margaretha
+Margaretha's
+Margarethe
+Margarethe's
+Margaretta
+Margaretta's
+Margaux
+Marget
+Marget's
+Margit
+Margit's
+Margot's
+Margy
+Margy's
+Mariam
+Mariam's
+Marianna
+Marianna's
+Maribeth
+Maribeth's
+Mariel
+Mariel's
+Marielle
+Marielle's
+Mariette
+Mariette's
+Marika
+Marika's
+Marilee
+Marilee's
+Mariska
+Mariska's
+Marita
+Marita's
+Marj
+Marj's
+Marja
+Marja's
+Markos
+Markus
+Markus's
+Marlee
+Marlee's
+Marleen
+Marleen's
+Marlena
+Marlena's
+Marline
+Marline's
+Marlo
+Marlo's
+Marlow
+Marlow's
+Marmaduke
+Marmaduke's
+Marney
+Marney's
+Marni
+Marni's
+Marnie
+Marnie's
+Marris
+Marris's
+Marthe
+Marthe's
+Marti
+Marti's
+Martie
+Martie's
+Martino
+Martino's
+Martyn
+Martyn's
+Marv
+Marv's
+Marya
+Marya's
+Marybeth
+Marybeth's
+Marylin
+Marylin's
+Marys
+Masha
+Masha's
+Massimiliano
+Massimiliano's
+Massimo
+Massimo's
+Mata
+Mata's
+Mateo
+Mateo's
+MathML
+MathML's
+Mathe
+Mathe's
+Mathilda
+Mathilda's
+Mathilde
+Mathilde's
+Matias
+Matias's
+Matilde
+Matilde's
+Matteo
+Matteo's
+Matthieu
+Matthieu's
+Matti
+Matti's
+Mattias
+Mattias's
+Matty
+Matty's
+Maudie
+Maudie's
+Maurie
+Maurie's
+Maurits
+Maurits's
+Maurizio
+Maurizio's
+Maury
+Maxie
+Maxie's
+Maximilien
+Maximilien's
+Maximo
+Maximo's
+Maybelle
+Maybelle's
+Maye
+Maye's
+Mayne
+Mayne's
+Mbps
+McAfee
+McAfee's
+McCann
+McCann's
+Meaghan
+Meaghan's
+Meara
+Meara's
+Medline
+Medline's
+Meggie
+Meggie's
+Mei
+Mei's
+Mela
+Mela's
+Melania
+Melania's
+Melicent
+Melicent's
+Melina
+Melina's
+Melita
+Melita's
+Mella
+Mella's
+Melli
+Melli's
+Mellie
+Mellie's
+Melly
+Melly's
+Melodie
+Melodie's
+Melony
+Melony's
+Melvyn
+Melvyn's
+Menard
+Menard's
+Merci
+Merci's
+Meriel
+Meriel's
+Merl
+Merl's
+Merrie
+Merrie's
+Merrily's
+Merry's
+Mersey
+Merv
+Merv's
+Merwin
+Merwin's
+Merwyn
+Merwyn's
+Meryl
+Meryl's
+Metacafe
+Metacafe's
+Micaela
+Micaela's
+Michaela
+Michaela's
+Michail
+Michail's
+Michal
+Michal's
+Micheline
+Micheline's
+Michell
+Michell's
+Micki
+Micki's
+Mignon
+Mignon's
+Mikael
+Mikael's
+Mikel
+Mikel's
+Mikey
+Mikey's
+Mikkel
+Mikkel's
+Milena
+Milena's
+Milli
+Milli's
+Milly
+Milly's
+Mina
+Mina's
+Minda
+Minda's
+Minette
+Minette's
+Minna
+Minne
+Minne's
+Minny
+Minny's
+Minta
+Minta's
+Mirabel
+Mirabel's
+Mirabella
+Mirabella's
+Mirabelle
+Mirabelle's
+Miran
+Miran's
+Mireille
+Mireille's
+Mirella
+Mirella's
+Mirna
+Mirna's
+Mischa
+Mischa's
+Misha
+Misha's
+Missie
+Missie's
+Mohandas
+Mohandas's
+Moise
+Moise's
+Moishe
+Moishe's
+Mongolica
+Mongolica's
+Monika
+Monika's
+Monro
+Monro's
+Monti
+Monti's
+Mora
+Mora's
+Mord
+Mord's
+Mordecai
+Morena
+Morena's
+Morey
+Morey's
+Morgana
+Morgana's
+Morgen
+Morgen's
+Moria
+Moria's
+Moritz
+Moritz's
+Morna
+Morna's
+Morrie
+Morrie's
+Morten
+Morten's
+Morty
+Morty's
+Mose
+Mose's
+Moshe
+Moshe's
+Moyra
+Moyra's
+Mozillian
+Mozillian's
+Mozillians
+Munchausen
+Munchausen's
+Munroe
+Munroe's
+Murdock
+Murdock's
+Murry
+Murry's
+My's
+MySpell
+MySpell's
+Myer
+Myer's
+Myriam
+Myriam's
+NGO
+NGO's
+NGOs
+NSPR
+NSPR's
+NSS
+NSS's
+Nada
+Nada's
+Nadu
+Nadu's
+Nadya
+Nadya's
+Nana
+Nana's
+Nance
+Nance's
+Nanci
+Nanci's
+Nani
+Nani's
+Nanni
+Nanni's
+Nanon
+Nanon's
+Nara
+Nari
+Nari's
+Naruto
+Naruto's
+Nata
+Nata's
+Natal's
+Natale
+Natale's
+Natalya
+Natalya's
+Nathalie
+Nathalie's
+Nathanael
+Nathanial
+Nathanial's
+Natividad
+Natividad's
+Natty's
+Neale
+Neale's
+Nealy
+Nealy's
+Necko
+Necko's
+Neda
+Neda's
+Nedda
+Nedda's
+Neddy
+Neddy's
+Nederland
+Nederland's
+Nederlands
+Neel
+Neel's
+Neely
+Neely's
+Neill
+Neill's
+Neils
+Nelle
+Nelle's
+Nelli
+Nelli's
+Nels
+Nerissa
+Nerissa's
+Nessa
+Nessa's
+Nessie
+Nessie's
+Nesta
+Nesta's
+Nester
+Nester's
+NetBSD
+NetBSD's
+Netta
+Netta's
+Nevil
+Nevil's
+Nevile
+Nevile's
+Neville
+Neville's
+Nevin
+Nevin's
+Nevins
+NexTag
+NexTag's
+Nextel
+Nextel's
+Nial
+Nial's
+Niall
+Niall's
+Nicephori
+Nicephori's
+Nichol
+Nichol's
+Nicki
+Nicki's
+Nickie
+Nickie's
+Nicko
+Nicko's
+Nicky
+Nicky's
+Nico
+Nico's
+Nicol
+Nicol's
+Nicolai
+Nicolette
+Nicolette's
+Nicolis
+Nicolle
+Nicolle's
+Niel
+Niel's
+Niels
+Nigeriana
+Nigeriana's
+Niki
+Niki's
+Niko
+Niko's
+Nikola
+Nikola's
+Nikolaos
+Nikolaos's
+Nikolas
+Nikolaus
+Nikolaus's
+Nikos
+Niles
+Nils
+Nilson
+Nilson's
+Ninette
+Ninette's
+Ninon
+Ninon's
+Niue
+Niue's
+Niven
+Niven's
+Noam
+Noam's
+Noland
+Noland's
+Noll
+Noll's
+Nomi
+Nomi's
+Noni
+Noni's
+Nonie
+Nonie's
+Nonna
+Nonna's
+Norah
+Norah's
+Norrie
+Norrie's
+Nortel
+Nortel's
+Notre
+Nowell
+Nowell's
+Nye
+Nye's
+Nyssa
+Nyssa's
+OMG
+Obed
+Obed's
+Obie
+Octavius
+Octavius's
+Odette
+Odette's
+Odie
+Odie's
+Odo
+Odo's
+Ody
+Ody's
+Olimpia
+Olimpia's
+Olly
+Olly's
+Olwen
+Olwen's
+Olympe
+Olympe's
+Oona
+Oona's
+Opaline
+Opaline's
+OpenBSD
+OpenBSD's
+Orazio
+Orazio's
+Orel
+Oren
+Oren's
+Oriana
+Oriana's
+Orlan
+Orlan's
+Orland
+Orland's
+Orren
+Orren's
+Orrin
+Orrin's
+Orson
+Orson's
+Orton
+Orton's
+Orv
+Orv's
+Oryza
+Oryza's
+Osbourne
+Osbourne's
+Osmond
+Osmond's
+Osmund
+Osmund's
+Ossie
+Ossie's
+Otho
+Otho's
+Ottilie
+Ottilie's
+Ottomana
+Ottomana's
+Oxley
+Oxley's
+Ozzy
+Ozzy's
+PDA
+PDA's
+PDAs
+PDF's
+PDFs
+PNG
+PNG's
+PNGs
+POTUS
+POTUS's
+PRNewswire
+PRNewswire's
+Paco
+Paco's
+Padgett
+Padgett's
+Padraic
+Padraic's
+Padraig
+Padraig's
+Palin
+Palin's
+Paloma
+Paloma's
+Pancho
+Pancho's
+Paola
+Paola's
+Paolina
+Paolina's
+Paolo
+Paolo's
+Papageno
+Papageno's
+Papua
+Papua's
+Parke
+Parke's
+Pascale
+Pascale's
+Paten
+Paten's
+Paton
+Patric
+Patric's
+Patricio
+Patricio's
+Patrizia
+Patrizia's
+Patten
+Patten's
+Pattie
+Pattie's
+Paule
+Paule's
+Paulie
+Paulie's
+Paulina
+Paulina's
+Paulo
+Paulo's
+Pauly
+Pauly's
+Pavel
+Pavel's
+Pavia
+Pavia's
+Paxton
+Payton
+Payton's
+Peadar
+Peadar's
+Pearce
+Pearce's
+Pearle
+Pearle's
+Peder
+Peder's
+Pegeen
+Pegeen's
+Peirce
+Peirce's
+Penrod
+Penrod's
+Pepe
+Pepe's
+Pepi
+Pepi's
+Pepita
+Pepita's
+Perceval
+Peri
+Peri's
+Perkin
+Perkin's
+Perla
+Perla's
+Perle
+Perle's
+Perri
+Perri's
+Perrine
+Perrine's
+Persis
+Peta
+Peta's
+Peterborough
+Peterborough's
+Petey
+Petey's
+Petr
+Petr's
+Petronella
+Petronella's
+Petronilla
+Petronilla's
+Peyronie's
+Peyton
+Peyton's
+Phebe
+Philippa
+Philippa's
+Phillida
+Phillida's
+Phillipe
+Phillipe's
+Phillis
+Phillis's
+Philomena
+Philomena's
+Phineas
+Phineas's
+Photoshop
+Photoshop's
+Phyllida
+Phyllida's
+Pia
+Pia's
+Pictor
+Pierrette
+Pierrette's
+Pierson
+Pierson's
+Pieter
+Pieter's
+Pietra
+Pietra's
+Pietro
+Pietro's
+Pinchas
+Pinchas's
+Piotr
+Piotr's
+Pippa
+Pippa's
+Pixar
+Pixar's
+Polska
+PostScript
+PostScript's
+Poul
+Poul's
+Poynter
+Poynter's
+Praetoriana
+Praetoriana's
+Prentiss
+Prentiss's
+Prinz
+Pris
+Prisca
+Prisca's
+Prix
+ProQuest
+ProQuest's
+Pru
+Pru's
+Prudy
+Prudy's
+Prue
+Prue's
+Pryce
+Pryce's
+Pseudomonas
+Pseudomonas's
+PubMed
+PubMed's
+Qaeda
+Qaeda's
+Queenie
+Queenie's
+Quent
+Quent's
+QuickList
+QuickList's
+QuickTime
+QuickTime's
+Quillan
+Quillan's
+Quincey
+Quincey's
+Quinlan
+Quinlan's
+Quint
+Quint's
+Quinta
+Quinta's
+Quintana
+Quintana's
+Quintin
+Quintin's
+Quintus
+Quintus's
+Qwest
+Qwest's
+Rab
+Rab's
+Rabi
+Raf
+Raf's
+Rafa
+Rafa's
+Rafe
+Rafe's
+Raff
+Raff's
+Raffaello
+Raffaello's
+Rafferty
+Rafferty's
+Rafi
+Rafi's
+Ragnar
+Ragnar's
+Rahel
+Rahel's
+Raimondo
+Raimondo's
+Raimund
+Raimund's
+Raimundo
+Raimundo's
+Raina
+Raina's
+Raine
+Raine's
+Rainer
+Rainer's
+Ralf
+Ralf's
+Rana
+Rana's
+Rance
+Rance's
+Randa
+Randa's
+Rani
+Rani's
+Ravi
+Ravi's
+Ravid
+Ravid's
+Raviv
+Raviv's
+Rawley
+Rawley's
+Raye
+Raye's
+Raymund
+Raymund's
+Rayna
+Rayna's
+Rayner
+Rayner's
+Raynor
+Raynor's
+Rea
+Rea's
+Reade
+Rebeca
+Rebeca's
+Rebecca
+Rebecca's
+Rebecka
+Rebecka's
+Redd
+Redd's
+Ree
+Ree's
+Reece
+Reece's
+Reena
+Reena's
+Rees
+Regan
+Regan's
+Regen
+Regen's
+Regine
+Regine's
+Reiko
+Reiko's
+Reina
+Reina's
+Reine
+Reine's
+Reinhard
+Reinhard's
+Remanence
+Remanent
+Remy
+Remy's
+Renae
+Renae's
+Renaldo
+Renaldo's
+Renard
+Renard's
+Renata
+Renata's
+Renate
+Renate's
+Renato
+Renato's
+Renaud
+Renaud's
+Renie
+Renie's
+Rennie
+Rennie's
+Reta
+Reta's
+Reuven
+Reuven's
+Rey
+Rey's
+Reynard
+Reynard's
+Reynold
+Reynold's
+Rhett
+Rhett's
+Rhianna
+Rhianna's
+Rhona
+Rhona's
+Rhys
+Rhys's
+Ric
+Ric's
+Rica
+Rica's
+Ricard
+Ricard's
+Riccardo
+Riccardo's
+Richart
+Richart's
+Rickard
+Rickard's
+Rickert
+Rickert's
+Ricki
+Ricki's
+Rik
+Rik's
+Riki
+Riki's
+Rikki
+Rikki's
+Rina
+Rina's
+Rinaldo
+Rinaldo's
+Riordan
+Riordan's
+Risa
+Risa's
+Ritchie
+Ritchie's
+Riva
+Riva's
+Roarke
+Roarke's
+Robb
+Robb's
+Robina
+Robina's
+Robinet
+Robinet's
+Robinette
+Robinette's
+Robinia
+Robinia's
+Roby
+Roby's
+Roch
+Roch's
+Roda
+Roda's
+Rodd
+Rodd's
+Roddy
+Roddy's
+Roderic
+Roderic's
+Roderigo
+Roderigo's
+Rodham
+Rodham's
+Rodi
+Rodi's
+Rodolph
+Rodolph's
+Rodolphe
+Rodolphe's
+Rog
+Rog's
+Roi
+Roi's
+Rois
+Roldan
+Roldan's
+Rolf
+Rolfe
+Rolfe's
+Rollie
+Rollie's
+Rollin
+Rollin's
+Rollo
+Rolph
+Rolph's
+Roma
+Roma's
+Romain
+Romain's
+Romana
+Romana's
+Romola
+Romola's
+Romy
+Romy's
+Rona
+Rona's
+Ronni
+Ronni's
+Rorke
+Rorke's
+Ros
+Rosaleen
+Rosaleen's
+Rosalia
+Rosalia's
+Rosaline
+Rosaline's
+Rosamond
+Rosamond's
+Rosamund
+Rosamund's
+Rosco
+Rosco's
+Roseanne
+Roseanne's
+Roselle
+Roselle's
+Rosina
+Rosina's
+Rosita
+Rosita's
+Rossie
+Rossie's
+Rosy's
+Routledge
+Routledge's
+Rowan
+Rowan's
+Rowen
+Rowen's
+Roxana
+Roxana's
+Roxane
+Roxane's
+Roxanna
+Roxanna's
+Royall
+Royall's
+Roz
+Roz's
+Rubi
+Rubi's
+Rubia
+Rubia's
+Rudd
+Rudd's
+Ruddy's
+Rudiger
+Rudiger's
+Rudolfo
+Rudolfo's
+Rufe
+Rufe's
+Ruggiero
+Ruggiero's
+Ruprecht
+Ruprecht's
+Rurik
+Rustin
+Rustin's
+Rutger
+Rutger's
+Rutter
+Rutter's
+Ruy
+Ruy's
+SCOTUS
+SCOTUS's
+SME
+SME's
+SMEs
+SMEs's
+SNP
+SNP's
+SNPs
+SSN
+Saba
+Saba's
+Saccharomyces
+Saccharomyces's
+Sacha
+Sacha's
+Sada
+Sada's
+Saleem
+Saleem's
+Salim
+Salim's
+Sallee
+Sallee's
+Salomon
+Salomon's
+Samaria
+Sande
+Sande's
+Sanderson
+Sanderson's
+Sandi
+Sandi's
+Sandie
+Sandie's
+Sandor
+Sandor's
+Sandro
+Sandro's
+Sanson
+Sanson's
+Sansone
+Sansone's
+Sapphira
+Sarbanes
+Sarbanes's
+Sardinian
+Sardinian's
+Saree
+Saree's
+Sarge
+Sarge's
+Sarina
+Sarina's
+Sarita
+Sarita's
+Sascha
+Sascha's
+Saunderson
+Saunderson's
+Sauveur
+Sauveur's
+Savina
+Savina's
+Saxe
+Saxe's
+Sayer
+Sayer's
+Sayre
+Sayre's
+Scarface
+Scarface's
+Scarlett
+Scarlett's
+Schwarz
+Schwarz's
+Scotti
+Scotti's
+Scunthorpe
+Scunthorpe's
+SeaMonkey
+SeaMonkey's
+Seamus
+Seamus's
+Sebastiano
+Sebastiano's
+Sebastien
+Sebastien's
+Sela
+Sela's
+Selby
+Selby's
+Selene
+Selene's
+Selig
+Selig's
+Selina
+Selina's
+Sella
+Sella's
+Selle
+Selle's
+Sena
+Sena's
+Sergent
+Sergent's
+Shalom's
+Shamus
+Shamus's
+Shandy
+Shandy's
+Shani
+Shani's
+Shanta
+Shanta's
+Shara
+Shara's
+Sharma
+Sharma's
+Shayla
+Shayla's
+Shayna
+Shayna's
+Shayne
+Shayne's
+Sheela
+Sheela's
+Sheilah
+Sheilah's
+Shel
+Shel's
+Shelagh
+Shelagh's
+Shem
+Shem's
+Shen
+Shen's
+Shenzhen
+Shenzhen's
+Shep
+Shep's
+Sher
+Sher's
+Sherm
+Sherm's
+Sherwin
+Sherwin's
+Shina
+Shina's
+Shir
+Shir's
+Shirl
+Shirl's
+Sholom
+Sholom's
+Shoshana
+Shoshana's
+Sib
+Sib's
+Sibley
+Sibley's
+Sibylla
+Sibylla's
+Sibylle
+Sibylle's
+Sidonia
+Sidonia's
+Sig
+Sigismondo
+Sigismondo's
+Sigrid
+Sigrid's
+Silvan
+Silvan's
+Silvana
+Silvana's
+Silvano
+Silvano's
+Silvanus
+Silvanus's
+Silvester
+Silvester's
+Silvie
+Silvie's
+Silvio
+Silvio's
+Sim's
+Simeon
+Simeon's
+Simmonds
+Simmonds's
+Simona
+Simona's
+Sinica
+Sinica's
+Siobhan
+Siobhan's
+Sion
+Sissie
+Sissie's
+Siward
+Siward's
+Skelly
+Skelly's
+Skipton
+Skipton's
+Skylar
+Skylar's
+Skyler
+Skyler's
+Slade
+Slade's
+Sly's
+Smitty
+Smitty's
+Sofie
+Sofie's
+Solaris
+Solaris's
+Solly
+Solly's
+Somerset
+Sophi
+Sophi's
+Sophronia
+Sophronia's
+Sorcha
+Sorcha's
+Sovietica
+Sovietica's
+Sparc
+SpiderMonkey
+SpiderMonkey's
+Stace
+Stace's
+Standford
+Standford's
+Stanfield
+Stanfield's
+Stanislas
+Stanislas's
+Stanislaus
+Stanislaus's
+Stanislaw
+Stanislaw's
+Stanly
+Stanly's
+Stanwood
+Stanwood's
+Stavros
+Stearn
+Stearn's
+Stefania
+Stefania's
+Stefano
+Stefano's
+Steffen
+Steffen's
+Steffi
+Steffi's
+Stephani
+Stephani's
+Stephanus
+Stephanus's
+Stillman
+Stillman's
+Stinky's
+Stoddard
+Stoddard's
+Stormy's
+StumbleUpon
+StumbleUpon's
+Sukey
+Sukey's
+Suki
+Suki's
+Sula
+Sula's
+Sumerica
+Sumerica's
+Sunderland
+Sunderland's
+Sunny's
+Suomi
+Suomi's
+Susann
+Susann's
+Susannah
+Susannah's
+Susi
+Susi's
+Susy
+Susy's
+Suzanna
+Suzanna's
+Suzi
+Suzi's
+Suzie
+Suzie's
+Svend
+Svend's
+Swindon
+Swindon's
+Sybilla
+Sybilla's
+Sybille
+Sybille's
+Syd
+Syd's
+Sylvan's
+Symantec
+Symantec's
+Symbian
+Symbian's
+Symon
+Symon's
+Syriana
+Syriana's
+TEirtza
+TEirtza's
+THz
+THz's
+TIF
+TIF's
+TIFF
+TIFF's
+TIFFs
+TIFs
+Tabb
+Tabb's
+Taber
+Taber's
+Tabor
+Taddeo
+Taddeo's
+Tait
+Tait's
+Talbert
+Talbert's
+Talia
+Talia's
+Tallulah
+Tallulah's
+Talya
+Talya's
+Tamar
+Tamar's
+Tamas
+Tana
+Tandy
+Tandy's
+Tani
+Tani's
+Tann
+Tann's
+Taryn
+Taryn's
+Tatiana
+Tatiana's
+TechRepublic
+TechRepublic's
+Technorati
+Technorati's
+Teddie
+Teddie's
+Tedi
+Tedi's
+Teena
+Teena's
+Templeton
+Templeton's
+Teodor
+Teodor's
+Teodora
+Teodora's
+Teodoro
+Teodoro's
+Tera
+Tera's
+Terese
+Terese's
+Teresita
+Teresita's
+Terrill
+Terrill's
+Terza
+Terza's
+Tesco
+Tesco's
+TextEdit
+TextEdit's
+Thacher
+Thacher's
+Thatcherism
+Thaxter
+Thaxter's
+Theda
+Theda's
+Theia
+Thekla
+Thekla's
+Theo
+Theo's
+Theobald
+Theobald's
+Theodor
+Theodor's
+Theodosia
+Theodosia's
+Thia
+Thia's
+Thibaut
+Thibaut's
+Thom
+Thom's
+Thoma
+Thoma's
+Thomasin
+Thomasin's
+Thomasina
+Thomasina's
+Thorin
+Thorin's
+Thorndike
+Thorny's
+Thorstein
+Thorstein's
+Thorsten
+Thorsten's
+Thorvald
+Thorvald's
+Thurstan
+Thurstan's
+Thurston
+Thurston's
+Tiebout
+Tiebout's
+Tierney
+Tierney's
+Tilda
+Tilda's
+Tildi
+Tildi's
+Tildy
+Tildy's
+Tillie
+Tillie's
+Tilly
+Tilly's
+Timi
+Timi's
+Timotheus
+Timotheus's
+Tish
+Tish's
+Tobe
+Tobe's
+Tobey
+Tobi
+Tobi's
+Tobias
+Tobias's
+Tobie
+Tobie's
+Tobin
+Tobin's
+Toma
+Toma's
+Tomaso
+Tomaso's
+Tomi
+Tomi's
+Tootsie
+Tootsie's
+Tore's
+Torey
+Torey's
+Tori
+Tori's
+Torin
+Torin's
+Torr
+Torr's
+Torre
+Torre's
+Torrence
+Torrence's
+Torrey
+Torrey's
+Torrie
+Torrie's
+Torry
+Torry's
+Tova
+Tova's
+Tove
+Tove's
+Traver
+Traver's
+Travers
+Tremain
+Tremain's
+Tremaine
+Tremaine's
+Tremayne
+Tremayne's
+Treo
+Treo's
+Trev
+Trev's
+TripAdvisor
+TripAdvisor's
+Tripp
+Tripp's
+Tris
+Trish
+Trish's
+Trista
+Trista's
+Trix
+Trix's
+Trixie
+Trixie's
+Trude
+Trude's
+Trudi
+Trudi's
+Trueman
+Trueman's
+Tully
+Tully's
+Twyla
+Twyla's
+Tybalt
+Tybalt's
+Tye
+Tye's
+Tynan
+Tynan's
+Tyne
+Tyne's
+Tyrus
+Tyrus's
+UI
+UI's
+UIs
+Udell
+Udell's
+Ugo
+Ugo's
+Ula
+Ula's
+Ulick
+Ulick's
+Ulises
+Ulises's
+Ulla
+Ulla's
+Ulric
+Ulric's
+Ulrica
+Ulrica's
+Ulrich
+Ulrich's
+Ulrike
+Ulrike's
+Umberto
+Umberto's
+Una
+Una's
+Urbain
+Urbain's
+Urbano
+Urbano's
+Uri
+Uri's
+Uta
+Uta's
+VPN
+VPN's
+VPNs
+Vachel
+Vachel's
+Vaclav
+Vaclav's
+Vail
+Vail's
+Valdemar
+Valdemar's
+Valentia
+Valentia's
+Valentina
+Valentina's
+Valera
+Valle
+Valle's
+Valli
+Valli's
+Vanda
+Vanda's
+Vania
+Vania's
+Vanna
+Vanna's
+Vanni
+Vanni's
+Vanya
+Vanya's
+Vasili
+Vasili's
+Vasily
+Vasily's
+Vassili
+Vassili's
+Vassily
+Vassily's
+Vere
+Vere's
+Verena
+Verena's
+Verney
+Verney's
+Vernor
+Vernor's
+Veronika
+Veronika's
+Veronique
+Vi
+Vi's
+Vick
+Vick's
+Vicodin
+Vicodin's
+Vida
+Vida's
+Vikki
+Vikki's
+Vin
+Vin's
+Vina
+Vina's
+Vinnie
+Vinnie's
+Vinny
+Vinny's
+Violante
+Violante's
+Violetta
+Violetta's
+Violette
+Violette's
+Virgilio
+Virgilio's
+Virginie
+Virginie's
+Vite
+Vite's
+Vitoria
+Vittoria
+Vittoria's
+Vittorio
+Vittorio's
+Viv
+Viv's
+Vivi
+Vivi's
+Viviana
+Viviana's
+Vivie
+Vivie's
+Vivien
+Vivien's
+Vodafone
+Vodafone's
+Von
+Von's
+WASPs
+WTF
+Wadsworth
+Wadsworth's
+Wainwright
+Wainwright's
+Wakefield
+Wallas
+Wallas's
+Wallie
+Wallie's
+Wally
+Wally's
+Walther
+Walther's
+Warcraft
+Warcraft's
+Warde
+Warde's
+Warwickshire
+Warwickshire's
+Wat
+Wat's
+Waverley
+Waverley's
+Waverly
+Waverly's
+Wayland
+Wayland's
+Waylon
+Waylon's
+WebSphere
+WebSphere's
+Weider
+Weider's
+Welby
+Welby's
+Wendel
+Wendel's
+Werner
+Werner's
+Wernher
+Wernher's
+Wes
+Westbrook
+Westbrook's
+Westley
+Westley's
+Whitby
+Whitby's
+Whittaker
+Whittaker's
+Wi-Fi
+Wi-Fi's
+WiFi's
+WikiPatents
+WikiPatents's
+Wikibooks
+Wikibooks's
+Wikimedia
+Wikimedia's
+Wikinews
+Wikinews's
+Wikiquote
+Wikiquote's
+Wikisource
+Wikisource's
+Wiktionary
+Wiktionary's
+Wilden
+Wilden's
+Wilfrid
+Wilfrid's
+Wilhelmine
+Willem
+Willem's
+Willey
+Willey's
+Willi
+Willi's
+Wilmette
+Wilmette's
+Wiltshire
+Wiltshire's
+Windham
+Windham's
+Windy's
+Winfield
+Winfield's
+Winn
+Winn's
+Winna
+Winna's
+Winne
+Winne's
+Winnifred
+Winnifred's
+Winny
+Winny's
+Winona
+Winona's
+Winslow
+Winslow's
+Witty's
+Woodie
+Woodie's
+Worden
+Worden's
+WorldCat
+WorldCat's
+Worthington
+Worthington's
+Wye
+Wyn
+Wyn's
+Wyndham
+Wyndham's
+Wynne
+Wynne's
+XBL
+XBL's
+XLS
+XLS's
+XLSX
+XLSX's
+XLSXs
+XLSs
+XPCOM
+XPCOM's
+XPConnect
+XPConnect's
+XPInstall
+XPInstall's
+XUL
+XUL's
+XULRunner
+XULRunner's
+Xanax
+Xanax's
+Xbox
+Xbox's
+Xena
+Xena's
+Ximenez
+Ximenez's
+Yancey
+Yancey's
+Yancy
+Yancy's
+Yardley
+Yardley's
+Yasmin
+Yasmin's
+Yehudi
+Yehudi's
+Yelena
+Yelena's
+Yetta
+Yetta's
+Ynez
+Ynez's
+Yolande
+Yolande's
+Yorke
+Yorke's
+Yorker
+Yorker's
+Yoshi
+Yoshi's
+Yoshiko
+Yoshiko's
+Ysabel
+Ysabel's
+Yul
+Yul's
+Yvon
+Yvon's
+Yvor
+Yvor's
+ZDNet
+ZDNet's
+Zaccaria
+Zaccaria's
+Zach
+Zacharias
+Zack
+Zack's
+Zahara
+Zahara's
+Zak
+Zak's
+Zarah
+Zarah's
+Zaria
+Zaria's
+Zea
+Zea's
+Zeb
+Zeb's
+Zebulon
+Zebulon's
+Zelda
+Zelda's
+Zena
+Zena's
+Zenia
+Zenia's
+Zhang
+Zhang's
+Zhao
+Zhao's
+Zhou
+Zhou's
+Zia
+Zia's
+Ziff
+Ziff's
+Zita
+Zita's
+Zora
+Zora's
+Zune
+Zune's
+abridgement
+abridgement's
+abridgements
+absorbances
+absorbancy
+absorbancy's
+absorber
+absorbers
+accelerometer
+accelerometer's
+accelerometers
+accountabilities
+accrete
+accreted
+accretes
+acetabular
+acetabulum
+actin
+add-on
+add-ons
+addendums
+addictiveness
+adduction
+adduction's
+adductions
+admin's
+adoptee
+adoptee's
+adoptees
+adorbs
+advocator
+advocator's
+advocators
+adware's
+adwares
+affective
+affordance
+affordances
+aider
+aider's
+al
+algorithmically
+alkoxy
+all-nighter
+all-nighters
+aluminize
+aluminized
+amici
+amicus
+amongst
+amped
+anaphylactic
+anaphylaxes
+anaphylaxis
+annualize
+annualizing
+anonymization
+anonymization's
+anonymizations
+anonymize
+anonymized
+anonymizes
+anonymizing
+another's
+anthropomorphized
+anthropomorphizes
+antiderivative
+antiderivatives
+antifa
+antisense
+antivirus's
+apatosaurus
+apatosaurus's
+appealable
+appointer
+appointers
+arXiv
+arXiv's
+archaeoastronomy
+archaeoastronomy's
+archaeologic
+archaeomagnetic
+archaeomagnetism
+areola
+areolae
+areolar
+areolas
+areolate
+arrestee
+arrestees
+arthroplasty
+artisanal
+artisanally
+artisanship
+artisanships
+aryl
+aryl's
+aryls
+asexuals
+aspirational
+aspirationally
+astroarchaeologies
+astroarchaeology
+astroarchaeology's
+astrobiology
+astrobiology's
+astrobleme
+astroblemes
+asymptote
+asymptotes
+asynchronicity
+auditability
+auditable
+auditee
+aurei
+auteur
+auteur's
+auteurs
+autocomplete
+autocompletes
+autocorrect
+autocorrect's
+autocorrected
+autocorrecting
+autocorrects
+automata
+avant-garde
+avo
+avos
+axe
+axe's
+backlight
+backlight's
+backlighting
+backlighting's
+backlights
+backlit
+backsplash
+backsplashes
+backstab
+backstabby
+backstabs
+badass
+badasses
+badging
+balancer
+balancers
+balanitis
+balanoposthitis
+balkanization
+balkanize
+balkanized
+balkanizes
+balkanizing
+ballistically
+banc
+bancs
+bandicoot
+bandicoot's
+bandicoots
+barcode
+barcoded
+barcodes
+barcoding
+baryonic
+basilar
+beaucoup
+belcher
+belcher's
+belchers
+biblically
+bifida
+bijection
+bijections
+bingeable
+biochem
+biocomputing
+biocomputing's
+biodiesel
+biodiesel's
+biograph
+biograph's
+biographed
+biographing
+biographs
+biohacker
+biohacker's
+biohackers
+biohacking
+bioinformatic
+bioinformatic's
+bioinformatics
+biologies
+biomasses
+biomechanics
+biomedicine
+biorobotics
+biosecurity
+biosecurity's
+biostatistics
+biosyntheses
+biotech's
+biotechnologies
+biotherapies
+biotherapy
+biotherapy's
+biotope
+biotope's
+biotopes
+biozone
+biozone's
+biozones
+biscotti
+biscotto
+blacksmithing
+blanche
+blogroll
+blogroll's
+blogrolls
+bloviate
+bloviated
+bloviates
+bloviating
+bloviation
+bloviator
+bloviator's
+bloviators
+bon
+bona
+bono
+bons
+bookselling
+boson
+bougie
+bougies
+boulderer
+boulderer's
+bouldering
+bridesman
+bridesman's
+bridesmen
+broadcasted
+bubonic
+bullseyes
+bupkis
+cDNA
+canceller
+canceller's
+canonicalization
+canonicalization's
+canonicalizations
+canonicalize
+canonicalized
+canonicalizes
+canonicalizing
+cantina
+cantinas
+capita
+captcha
+carabiner
+carboxylic
+cardinalities
+cardinality
+cardiomegaly
+carnitas
+carte
+cartes
+cerevisiae
+cerevisiae's
+cerevisiaes
+champertous
+champerty
+charcuterie
+chemistries
+chewable
+chiral
+chirality
+ciphertext
+ciphertexts
+cisgendered
+closable
+coaxially
+codebook
+codebook's
+codec
+codec's
+codecs
+codon's
+cofunction
+cofunction's
+cofunctions
+coli
+collegial
+collimate
+collimated
+collimating
+collimation
+collinear
+collinearity
+colocate
+colocated
+colocates
+colocating
+colocation
+colocations
+colonoscope
+colonoscope's
+colonoscopes
+colorimeter
+colorimeter's
+colorimeters
+combinatorics
+commensurability
+commenter
+commenter's
+commenters
+commoditization
+comorbidities
+compatibilities
+complementarities
+complementarity
+complementarity's
+composable
+compositeness
+compressions
+comradery
+concurrents
+conferable
+conferenced
+config
+config's
+configs
+conformant
+congressionally
+conmanly
+continentalism
+continentalism's
+contrabass
+contrabass's
+contrabasses
+convolutional
+coproduct
+coproduct's
+coproducts
+copyrightable
+corrigibility
+corrigibility's
+corrigible
+corruptibly
+cosplayed
+cosplayer
+cosplayers
+cosplaying
+cosplays
+counterintuitive
+counterintuitively
+counterproposal
+counterstrike
+counterstrike's
+counterstrikes
+countertop
+countertops
+coupler
+couplers
+court-martial
+court-martialed
+court-martialing
+court-martials
+covariate
+covariates
+crapola
+crappiness
+creatine
+crimeware
+crimeware's
+criminalization
+crore
+crore's
+crores
+crosshair
+crosshair's
+crosshairs
+crowdsource
+crowdsourced
+crowdsources
+crowdsourcing
+cryonic
+crypto
+crypto's
+cryptographic
+cryptologist
+cryptologist's
+cryptologists
+cryptosystem
+cryptosystems
+crystalize
+crystalized
+crystalizes
+crystalizing
+cul-de-sac
+culpa
+culpas
+curation
+customizable
+cyber
+cyberattack
+cyberattack's
+cyberattacks
+cybersecurity
+cypher
+cypher's
+cysteine
+cysteine's
+cysteines
+cysticerci
+cysticercoid
+cysticercoids
+cysticercoses
+cysticercosis
+cysticercus
+cystoscope
+cystoscopic
+cystoscopy
+cytokine
+cytokine's
+datasheet
+datasheet's
+datasheets
+de
+decertification
+decertifications
+decertified
+decertifies
+decertify
+decertifying
+decile
+deciles
+decisis
+decompressions
+deconstructionist's
+decontextualize
+decontextualized
+decontextualizes
+decontextualizing
+decoupler
+decouplers
+decrypt
+decryptable
+decrypted
+decrypting
+decrypts
+dedendum
+dedendum's
+dedendums
+definitional
+definitionally
+degenerations
+dehydrogenase's
+demonym
+demonyms
+dequeuing
+descalable
+designee
+designings
+deuteride
+deuterides
+dialoged
+dialoging
+dialogs
+dialogued
+dialoguer
+dialoguing
+diatomaceous
+differentiator
+differentiators
+digitalize
+digitalized
+digitalizes
+digitalizing
+dihydro
+directionalities
+directionality
+directionality's
+disambiguated
+disambiguates
+disambiguating
+disappointer
+disappointers
+disarrangements
+disassembler
+disassembler's
+disassemblers
+disassembly's
+disbarments
+disclaimable
+disclosable
+discountenance's
+discoverability
+discoverable
+disincentivize
+disincentivized
+disincentivizes
+disincentivizing
+disintegrations
+disintermediation
+disintermediations
+dispositive
+dispositive's
+dispositively
+dispositiveness
+dispositives
+dissentious
+distractability
+distractable
+distractible
+diverter
+diverters
+dizygotic
+dizygous
+djinn
+dominative
+dominator
+donator
+donator's
+donators
+doozie
+doozy
+dox
+doxastic
+doxed
+doxes
+doxing
+doxx
+doxxed
+doxxes
+doxxing
+dreck
+dreckish
+drecky
+drek
+duffel
+duffels
+dumbed
+duplicative
+durian
+durian's
+durians
+dyad
+dyadically
+dystopians
+dystopias
+eBook
+eBook's
+eBooks
+eCommerce
+eCommerce's
+ectopic
+ectopically
+egads
+elicitor
+elicitor's
+elicitors
+else's
+embattlement
+embattlement's
+embattlements
+embiggen
+empathic
+emplace
+emplaced
+emplaces
+emplacing
+encodings
+encyclopaedia
+encyclopedist
+encyclopedist's
+encyclopedists
+enqueuing
+epical
+epically
+epicycle
+ergodic
+ergodicity
+eschatologist
+eschatologist's
+eschatologists
+et
+ethicist
+ethicist's
+ethicists
+eutrophic
+evidential
+evidentiality
+evidentially
+evidentiary
+exacta
+exactable
+exactas
+exactingness
+exactions
+exactor
+exactor's
+exactors
+exbibyte
+exbibyte's
+exbibytes
+exfiltrate
+exfiltrated
+exfiltrates
+exfiltrating
+exfiltration
+exfiltrations
+exonerations
+experimentalism
+experimentalist
+explainer
+explainers
+exploitive
+explorative
+expos辿
+expunction
+expungement
+expungements
+extensor
+extensor's
+extensors
+extortionary
+extrema
+extremum
+extremums
+facto
+fav
+favs
+fearmonger
+fearmonger's
+fearmongering
+fearmongers
+fermion
+ferrite
+ferritin
+fibromyalgia
+fibromyalgia's
+fibromyalgic
+fibromyalgics
+fides
+filesystem
+filesystem's
+filesystems
+filmography
+financials
+findable
+fineable
+fintech
+fintechs
+fissionables
+flaneur
+flaneur's
+flaneurs
+flexor
+flexor's
+flexors
+fluidize
+fluidizes
+fluidizing
+flyer
+flyer's
+flyers
+foci
+fomite
+fomites
+forma
+fracker
+frackers
+franca
+freegan
+freegans
+fugacious
+fugaciously
+fugaciousness
+funder
+funders
+gamification
+gamified
+gamifies
+gamify
+gamifying
+gaslighted
+gaslighting
+gastroenterologist
+gastroenterologist's
+gastroenterology
+gatekeeping
+gatekeeping's
+gazillionth
+gendering
+genomic
+genomic's
+geocentricism
+geocentrism
+geopolitically
+gerontocracy
+gibibyte
+gibibyte's
+gibibytes
+gigajoule's
+glamping
+glom
+glomed
+gloming
+gloms
+gochujang
+golem
+gothic
+gothically
+gothicness
+grande
+grantor
+grantor's
+grantors
+grayscale
+grey
+grey's
+greybeard's
+greybeards
+greyed
+greyer
+greyest
+greying
+greyness's
+greys
+guac
+gunsmoke
+habeas
+hadithes
+hadron
+hadronic
+handwashing
+handwrite
+handwrites
+handwrote
+haptical
+haptically
+haptics
+harissa
+hatchling
+headspace
+helicities
+helicity
+heliocentrically
+heliocentricism
+heliocentrism
+hentai
+heritability
+hexane
+hexane's
+hexanes
+hippopotami
+holdem
+hophead
+hopheads
+hormesis
+hornbeams
+howto
+howto's
+howtos
+hydride
+iPods
+iatrogenesis
+iatrogenic
+idolator
+idolator's
+idolators
+iftar
+iftars
+igniter
+igniter's
+igniters
+impactful
+impaction
+implementers
+inactives
+inactivities
+incentivize
+incentivized
+incentivizes
+incentivizing
+inclosable
+incongruent
+incongruently
+incorporator
+incorporators
+incorrigibleness
+inductor
+inductor's
+inductors
+infinitum
+infringer
+infringers
+initialisms
+initializer
+initializers
+inkjet
+inkjet's
+inkjets
+instantiation
+instantiations
+integrand
+integrationist
+integrationist's
+integrationists
+integrations
+intercellular
+intermediacies
+intermediacy
+intermediated
+intermediateness
+intermediating
+intermediation
+intermediations
+intermediator
+intermediator's
+intermediators
+intermittences
+intermittencies
+intermolecular
+intermolecularly
+interquartile
+interruptible
+intersexual
+intersexual's
+intersexualism
+intersexuality
+intersexuals
+intifadas
+intl
+invertible
+irrevocability
+irrevocableness
+isometry
+isospin
+isospins
+iteratively
+japonica
+jewellery
+jitter
+jittered
+jittering
+jokester
+jokesters
+judgement
+judgement's
+judgements
+judgeships
+judgey
+judgy
+kabocha
+kakistocracy
+kbps
+keester
+keesters
+keister
+keisters
+kern
+kerne
+kerning
+keylogger
+keylogger's
+keyloggers
+keylogging
+keylogging's
+keyloggings
+kibibyte
+kibibyte's
+kibibytes
+kludgy
+kombucha
+kryptonite
+labelled
+laissez-faire
+langue
+langue's
+langues
+lawyerly
+leachate
+leachates
+learnt
+lector
+lector's
+lectors
+lede
+lepidopterist
+lepidopterist's
+lepidopterists
+lethality
+lexicological
+lexicologies
+lexicologist
+lexicologist's
+lexicology
+lexicology's
+licensor
+lifecycle
+limnological
+limnologist
+limnologist's
+limnologists
+limnology
+limnology's
+lingua
+linguistical
+listserv
+listserv's
+localizer
+localizers
+lumens
+lumina
+mRNA
+macOS
+macOS's
+macroscopically
+malform
+malforms
+malwares
+mammalia
+manticore
+masse
+massless
+maximalist
+maximalist's
+maximalists
+mea
+measurer
+mebibyte
+mebibyte's
+mebibytes
+meerkats
+megajoule's
+merchantability
+merchanting
+mesothelioma
+mesothelioma's
+metadata's
+methoxy
+microcredit
+microgram
+micropayment
+micropayments
+migrator
+migrator's
+migrators
+millennials
+millisievert
+millisieverts
+mins
+misandrist
+misandrist's
+misandrists
+misandry
+miscellanea
+mischaracterization
+mischaracterizations
+mischaracterize
+mischaracterized
+mischaracterizing
+misclassification
+misclassifications
+misclassify
+misclassifying
+misconfiguration
+mise
+mises
+misgender
+misgendered
+misgendering
+misgenders
+misjudgement
+misjudgement's
+misjudgements
+missileer
+mistyped
+mitigable
+mitigations
+mocktail
+mocktails
+mockumentaries
+mockumentary
+modeller
+modeller's
+modellers
+modelling
+modelling's
+modellings
+mojo
+mojos
+monied
+monofilament
+monomial
+monozygotic
+monozygous
+mosquitos
+motorsport
+motorsport's
+motorsports
+movant
+movent
+multicast
+multivariable
+murine
+musculus
+namespace
+namespace's
+namespaces
+nano
+natively
+na誰ve
+na誰vely
+na誰ver
+na誰vest
+na誰vety
+na誰vety's
+na誰vet辿
+na誰vet辿's
+neato
+neoadjuvant
+neurocysticercoses
+neurocysticercosis
+neurophysiology's
+neuroscience's
+neurosciences
+neuroscientist
+neuroscientist's
+neuroscientists
+neurotoxin
+neurotoxins
+newish
+newswires
+nitrile
+nitriles
+nitty
+nitty-gritty
+nonbinary
+nonnegative
+nonreal
+nosings
+nuclide
+nuclides
+numbingly
+nutjob
+nutjobs
+nystagmus
+octant
+octantal
+octants
+octopi
+octothorp
+octothorpe
+olds
+oligo
+omnidirectional
+opensource
+operationalize
+operationalized
+operationalizes
+operationalizing
+opposable
+opposer
+oppositional
+outlier's
+outsized
+overbroad
+overinclusion
+overinclusive
+overrich
+overrichness
+oxymoronic
+oxymoronically
+oy
+oyes
+oyez
+paracord
+parallelization's
+parallelizations
+parallelize
+parallelizes
+parallelizing
+parametrize
+parametrized
+paronychia
+parsers
+partygoers
+paver
+pavers
+pax
+pebibyte
+pebibyte's
+pebibytes
+pendency
+performant
+permalink
+permalink's
+permalinks
+permissibility
+permittee
+personalization
+pharma
+pharma's
+pharmas
+phimosis
+phimosises
+phlebotomist
+phlebotomist's
+phlebotomists
+phlebotomize
+phlebotomized
+phlebotomizes
+phlebotomizing
+phlebotomy
+phlogiston
+phlogistons
+pho
+phosphine
+phosphine's
+phosphines
+phosphorylate
+phosphorylated
+phosphorylates
+phosphorylating
+photodetector
+photodetectors
+photosensor
+photosensors
+photosensory
+phyllo
+piecewise
+pilgrimaged
+pilgrimaging
+pixelate
+pixelated
+pixelates
+plaintext
+plusses
+polarizer
+polarizers
+polymorphically
+polymorphism
+polynucleotide
+polynucleotide's
+polynucleotides
+polypeptide
+polypeptide's
+polypeptides
+portlet
+portlet's
+portlets
+positivities
+positivity
+positivity's
+post-partum
+posthitides
+posthitis
+postnatally
+pounder
+pounders
+poutine
+poutines
+praecipe
+pranked
+pranking
+pre-fill
+pre-filled
+pre-filling
+pre-fills
+pre-programmed
+pre-programming
+precedential
+precession
+precessional
+preclusions
+prefill
+prefilled
+prefilling
+prefills
+preinstall
+prejudgement
+prejudgement's
+prejudgements
+preliminarily
+preload
+preloaded
+preloading
+preloads
+preparer
+preparers
+prepended
+prepending
+prepends
+preprocess
+preprocessed
+preprocesses
+preprocessing
+preprogrammed
+preprogramming
+prev
+proclaimable
+procreations
+profiler
+profiler's
+profilers
+programmability
+programmatically
+pronate
+pronated
+pronates
+pronating
+pronation
+pronator
+pronator's
+pronators
+propounder
+propounders
+proprietorships
+propyl
+proration
+prosecutable
+prosecutorial
+prosthetics
+prothonotarial
+prothonotaries
+prothonotary
+proverbed
+proverbing
+pruno
+pseudorandom
+pseudorandomly
+psychomotor
+quantized
+quartile
+quartiles
+racoon
+rambutan
+rambutans
+ramen
+ramped
+rando
+randos
+rasterization
+rasterization's
+rasterize
+rasterized
+rasterizer
+rasterizes
+rasterizing
+reabsorber
+reabsorbers
+reactivity's
+reappointer
+reappointers
+reappointments
+rebar
+rebars
+rebrand
+rebranded
+rebranding
+rebroadcasted
+rebuttable
+recency
+recertification
+recertification's
+recertifications
+recoilless
+recommender
+recommenders
+recompilation's
+reconfigurable
+recurse
+recursed
+recurses
+recursing
+recusal
+recusals
+redactions
+redirections
+rediscoverable
+reflux
+reflux's
+refluxed
+refluxes
+refluxing
+refunder
+refunders
+reglet
+reintegrations
+relatedly
+relict
+relict's
+relicts
+relocations
+renderer
+renderer's
+renderers
+renewables
+renominations
+repartitions
+repaver
+repavers
+replead
+repleaded
+repleader
+repleaders
+repleading
+repleadings
+repleads
+reproducibility
+repurpose
+repurposes
+repurposing
+reputational
+requestor
+resistive
+resistively
+resistiveness
+resizable
+resizer
+reskin
+reskin's
+reskinned
+reskinning
+reskins
+respellings
+responder
+responder's
+responders
+responsivity
+responsivity's
+resubmission's
+retainage
+retainages
+reticle
+reticle's
+reticles
+retransmission
+retransmission's
+retransmissions
+retroreflector
+retroreflectors
+reviewability
+reviewable
+rheumatological
+rheumatologist
+rheumatologist's
+rheumatologists
+rheumatology
+rheumatology's
+ribbie
+ribbies
+roadmap
+roadmaps
+rollout
+rotatable
+rotatably
+rotator
+salability
+sativa
+savoir
+sayonara
+sayonaras
+scalable
+schemas
+schnaps
+schrod
+schrods
+scooch
+scooched
+scooches
+scooching
+scorebook
+scorebook's
+scorebooks
+scoresheet
+scoresheet's
+scoresheets
+scot-free
+screener
+screeners
+screenshot's
+scrollbar
+scrollbars
+se
+segregable
+seldomly
+selfing
+selfism
+selfist
+selfists
+sensationalistic
+sentiently
+sera
+seraphim
+severability
+shapeshift
+shapeshifted
+shapeshifter
+shapeshifters
+shapeshifting
+shemale
+shemale's
+shemales
+shifter
+shifters
+showtime's
+showtimes
+shroom
+shrooms
+signalling
+signup
+signup's
+signups
+siloed
+single-handedly
+skeuomorph
+skeuomorphic
+skeuomorphism
+skeuomorphs
+slushed
+slushes
+slushing
+smidge
+smidge's
+smidges
+snarkily
+snazziness
+snifflier
+sniffliest
+sniffly
+snowcap
+snowcap's
+snowcaps
+snowcat
+snowcat's
+snowcats
+soffit
+soffits
+solvability
+sommelier
+sommelier's
+sommeliers
+spectrogram
+spectrogram's
+spectrograms
+specula
+specular
+specularity
+specularly
+speculum
+speculums
+spelt
+spick
+spicks
+spina
+spitballer
+spitballers
+spitballing
+splitter
+splitter's
+splitters
+sponsorships
+spywares
+stealer
+stealers
+steradian
+stereogram
+stereogram's
+stereograms
+stevia
+stevia's
+stoolie
+stoolie's
+stoolies
+stopword
+stopwords
+strategize
+strategized
+strategizing
+streetwalking
+struct
+struct's
+structs
+stupefyingly
+stylometric
+stylometries
+stylometry
+sublate
+sublate's
+sublated
+sublates
+sublating
+subparagraphs
+subpoenable
+subrogate
+subrogated
+subrogates
+subrogation
+substituent's
+substituents
+subsumptions
+subtractive
+subtweet
+subtweets
+subwoofer
+subwoofers
+sucky
+summited
+superset
+supervillain
+supervillain's
+supervillains
+surjection
+surjections
+surveil
+surveillances
+surveillant
+surveillant's
+surveillants
+surveilled
+surveilling
+surveils
+survivorship
+switcheroo
+switcheroos
+syllabi
+symbiote
+symbiotes
+synches
+synchronism
+synchronism's
+synchronizer
+synchronizer's
+synchronizers
+synesthesia
+synesthete
+synesthetes
+synesthetic
+synthase
+synthase's
+synthases
+sysadmin's
+sysop's
+tRNA
+tRNA's
+tebibyte
+tebibyte's
+tebibytes
+telecom
+telecom's
+teleported
+teleporting
+teleports
+terraforming
+terraforming's
+testcase
+testcase's
+testcases
+testsuite
+testsuite's
+testsuites
+textbox
+textbox's
+textboxes
+thaliana
+theming
+themself
+therebetween
+thermobaric
+thoracotomy
+throbber
+thruster
+thrusters
+thusly
+toodles
+traceur
+traceur's
+traceurs
+trackback
+trackback's
+trackbacks
+tradable
+tradeoff
+tradeoffs
+trailhead
+trailheads
+trainings
+transcreation
+transcreation's
+transcriptional
+transfect
+transfected
+transfecting
+transfects
+transfeminine
+transformative
+transgenderism
+transgene
+transgenes
+transgressive
+transmasculine
+trebuchet
+trebuchets
+triages
+triaging
+trichotomies
+trichotomy
+tricorn
+tricorn's
+tricorns
+triplane
+triplane's
+triplanes
+tunable
+tung
+turtleback
+turtlebacks
+tweedle
+tweedled
+tweedles
+tweedling
+tweep
+tweeps
+udon
+ulcerative
+unaffordable
+unaffordably
+unattenuated
+unboxings
+uncancelled
+uncheck
+unchecking
+unchecks
+uncompassionate
+uncompassionately
+uncontained
+uncontradicted
+uncopyrightable
+uncoupler
+uncouplers
+undeliverables
+underinclusive
+underlayer
+underlayer's
+underlayers
+underwing
+underwing's
+underwings
+undesignated
+unencrypted
+unexamined
+unexplainable
+unexplainably
+unexploded
+unfalsifiable
+unironic
+unironically
+unlabelled
+unlasting
+unlastingly
+unlink
+unlinked
+unlinking
+unlinks
+unobservable
+unpressured
+unpressurized
+unredacted
+unrequest
+unrequested
+unrideable
+unsaw
+unsee
+unsees
+unsharp
+unvaccinated
+uplink
+uplink's
+uplinks
+uptime
+upvote
+upvoted
+upvotes
+usufruct
+usufruct's
+usufructs
+utero
+vaccinator
+vaccinators
+vacinal
+validator
+validators
+validities
+vanishingly
+vasopressor
+vasopressor's
+vasopressors
+verbed
+verbing
+verifiability
+verifiably
+verifier
+verifier's
+verifiers
+vertebrata
+vertebrobasilar
+vibrational
+vibrationless
+videographer
+videographer's
+videographers
+videographies
+videography
+videography's
+videophile
+videophile's
+videophiles
+vivant
+vivants
+vlogged
+vlogger
+vlogger's
+vlogging
+vocoder
+vocoders
+volatiles
+volcanological
+volcanologist
+volcanologist's
+volcanologists
+volcanology
+volcanology's
+webdesign
+webdesign's
+webdesigns
+webmail
+webmail's
+webmails
+webpage
+webpage's
+webpages
+weirded
+weirding
+welp
+whistleblower
+whistleblower's
+whistleblowering
+whistleblowers
+whitepaper
+whitepaper's
+whitepapers
+wicking
+wickings
+willy-nilly
+windings
+wineshop
+wineshop's
+wineshops
+winsorization
+winsorize
+winsorized
+winsorizes
+winsorizing
+wishy-washy
+woah
+wordie
+wordies
+xenophile
+xenophiles
+yay
+yeet
+yeeted
+yeeting
+yeets
+yobibyte
+yobibyte's
+yobibytes
+yowsa
+yowsah
+yowza
+yowzah
+zebibyte
+zebibyte's
+zebibytes
+zoomorphism
+zoomorphism's
+zoonosis
+zoonotic
+zoophilia
+zoophilia's
+zuke
+zukes
diff --git a/extensions/spellcheck/locales/en-US/hunspell/dictionary-sources/5-mozilla-removed.txt b/extensions/spellcheck/locales/en-US/hunspell/dictionary-sources/5-mozilla-removed.txt
new file mode 100644
index 0000000000..927e51c650
--- /dev/null
+++ b/extensions/spellcheck/locales/en-US/hunspell/dictionary-sources/5-mozilla-removed.txt
@@ -0,0 +1,3 @@
+ABCs
+Munchhausen
+Munchhausen's
diff --git a/extensions/spellcheck/locales/en-US/hunspell/dictionary-sources/5-mozilla-specific.txt b/extensions/spellcheck/locales/en-US/hunspell/dictionary-sources/5-mozilla-specific.txt
new file mode 100644
index 0000000000..b0c004bc5b
--- /dev/null
+++ b/extensions/spellcheck/locales/en-US/hunspell/dictionary-sources/5-mozilla-specific.txt
@@ -0,0 +1,42 @@
+Bugzilla
+Bugzilla's
+ChatZilla
+ChatZilla's
+Fenix
+Fenix's
+Fennec
+Fennec's
+Firefox
+Firefox's
+Gecko
+Gecko's
+JavaScript
+JavaScript's
+Mozilla
+Mozilla's
+NSPR
+NSPR's
+NSS
+NSS's
+Necko
+Necko's
+Netscape
+Netscape's
+SeaMonkey
+SeaMonkey's
+SpiderMonkey
+SpiderMonkey's
+Thunderbird
+Thunderbird's
+XBL
+XBL's
+XPCOM
+XPCOM's
+XPConnect
+XPConnect's
+XPInstall
+XPInstall's
+XUL
+XUL's
+XULRunner
+XULRunner's
diff --git a/extensions/spellcheck/locales/en-US/hunspell/dictionary-sources/README.txt b/extensions/spellcheck/locales/en-US/hunspell/dictionary-sources/README.txt
new file mode 100644
index 0000000000..e1918f0a32
--- /dev/null
+++ b/extensions/spellcheck/locales/en-US/hunspell/dictionary-sources/README.txt
@@ -0,0 +1,2 @@
+See Firefox Source Docs for information about these scripts, and how to add new words.
+https://firefox-source-docs.mozilla.org/extensions/spellcheck/index.html
diff --git a/extensions/spellcheck/locales/en-US/hunspell/dictionary-sources/edit-dictionary.sh b/extensions/spellcheck/locales/en-US/hunspell/dictionary-sources/edit-dictionary.sh
new file mode 100755
index 0000000000..e72654e84d
--- /dev/null
+++ b/extensions/spellcheck/locales/en-US/hunspell/dictionary-sources/edit-dictionary.sh
@@ -0,0 +1,95 @@
+#! /usr/bin/env sh
+
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+set -e
+
+WKDIR="`pwd`"
+SPELLER="$WKDIR/scowl/speller"
+
+munch() {
+ $SPELLER/munch-list munch $1 | sort -u
+}
+
+expand() {
+ grep -v '^[0-9]\+$' | $SPELLER/munch-list expand $1 | sort -u
+}
+
+if [ ! -d "$SPELLER" ]; then
+ echo "The 'scowl' folder is missing. Check the documentation at"
+ echo "https://firefox-source-docs.mozilla.org/extensions/spellcheck/index.html"
+ exit 1
+fi
+
+if [ -z "$EDITOR" ]; then
+ echo 'Need to set the $EDITOR environment variable to your favorite editor.'
+ exit 1
+fi
+
+# Open the editor and allow the user to type or paste words
+echo "Editor is going to open, you can add the list of words. Quit the editor to finish editing."
+echo "Press Enter to begin."
+read foo
+$EDITOR temp-list.txt
+
+if [ ! -f temp-list.txt ]; then
+ echo "The content of the editor hasn't been saved."
+ exit 1
+fi
+# Remove empty lines
+sed -i "" "/^$/d" temp-list.txt
+
+# Copy the current en-US dictionary and strip the first line that contains
+# the count.
+tail -n +2 ../en-US.dic > en-US.stripped
+
+# Convert the file to UTF-8
+iconv -f iso-8859-1 -t utf-8 en-US.stripped > en-US.utf8
+rm en-US.stripped
+
+# Save to a temporary file words excluded from suggestions, and numerals,
+# since the munched result is different for both.
+grep '!$' < utf8/en-US-utf8.dic > en-US-nosug.txt
+grep '^[0-9][a-z/]' < utf8/en-US-utf8.dic > en-US-numerals.txt
+
+# Expand the dictionary to a word list
+expand ../en-US.aff < en-US.utf8 > en-US-wordlist.txt
+rm en-US.utf8
+
+# Add the new words
+cat temp-list.txt >> en-US-wordlist.txt
+rm temp-list.txt
+
+# Remove numerals from the expanded wordlist
+grep -v '^[0-9]' < en-US-wordlist.txt > en-US-wordlist-nonum.txt
+rm en-US-wordlist.txt
+
+# Run the wordlist through the munch script, to compress the dictionary where
+# possible (using affix rules).
+munch ../en-US.aff < en-US-wordlist-nonum.txt > en-US-munched.dic
+rm en-US-wordlist-nonum.txt
+
+# Remove words that should not be suggested
+while IFS='/' read -ra line
+do
+ sed -E -i "" "\:^$line($|/.*):d" en-US-munched.dic
+done < "en-US-nosug.txt"
+
+# Add back suggestion exclusions and numerals from the original .dic file
+cat en-US-nosug.txt >> en-US-munched.dic
+cat en-US-numerals.txt >> en-US-munched.dic
+rm en-US-nosug.txt
+rm en-US-numerals.txt
+
+# Add back the line count and sort the lines
+wc -l < en-US-munched.dic | tr -d '[:blank:]' > en-US.dic
+LC_ALL=C sort en-US-munched.dic >> en-US.dic
+rm -f en-US-munched.dic
+
+# Convert back to ISO-8859-1
+iconv -f utf-8 -t iso-8859-1 en-US.dic > ../en-US.dic
+
+# Keep a copy of the UTF-8 file in /utf8
+mv en-US.dic utf8/en-US-utf8.dic
diff --git a/extensions/spellcheck/locales/en-US/hunspell/dictionary-sources/install-new-dict.sh b/extensions/spellcheck/locales/en-US/hunspell/dictionary-sources/install-new-dict.sh
new file mode 100755
index 0000000000..9e2f37a16f
--- /dev/null
+++ b/extensions/spellcheck/locales/en-US/hunspell/dictionary-sources/install-new-dict.sh
@@ -0,0 +1,47 @@
+#! /usr/bin/env sh
+
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+# This script copies the new dictionary created by make-new-dict in
+# place.
+
+set -e
+
+WKDIR="`pwd`"
+SUPPORT_DIR="$WKDIR/support_files"
+SPELLER="$WKDIR/scowl/speller"
+
+# Stop if backup folders already exist, because it means that this script
+# has already been run once.
+FOLDERS=( "orig-bk" "mozilla-bk")
+for f in ${FOLDERS[@]}; do
+ if [ -d "$SUPPORT_DIR/$f" ]; then
+ echo "Backup folder already present: $f"
+ echo "Run make-new-dict.sh before running this script."
+ exit 1
+ fi
+done
+
+mv orig "$SUPPORT_DIR/orig-bk"
+mkdir orig
+cp $SPELLER/en_US-custom.dic $SPELLER/en_US-custom.aff $SPELLER/README_en_US-custom.txt orig
+
+mkdir "$SUPPORT_DIR/mozilla-bk"
+mv ../en-US.dic ../en-US.aff ../README_en_US.txt "$SUPPORT_DIR/mozilla-bk"
+
+# The affix file is ISO-8859-1, but still need to change the character set to
+# ISO-8859-1 and remove conversion rules.
+cp en_US-mozilla.aff utf8/en-US-utf8.aff
+sed -i "" -e '/^ICONV/d' -e 's/^SET UTF-8$/SET ISO8859-1/' en_US-mozilla.aff
+
+# Convert the dictionary to ISO-8859-1
+cp en_US-mozilla.dic utf8/en-US-utf8.dic
+iconv -f utf-8 -t iso-8859-1 < utf8/en-US-utf8.dic > en_US-mozilla.dic
+
+cp en_US-mozilla.aff ../en-US.aff
+cp en_US-mozilla.dic ../en-US.dic
+mv README_en_US-mozilla.txt ../README_en_US.txt
+
+echo "New dictionary copied into place. Please commit the changes."
diff --git a/extensions/spellcheck/locales/en-US/hunspell/dictionary-sources/make-new-dict.sh b/extensions/spellcheck/locales/en-US/hunspell/dictionary-sources/make-new-dict.sh
new file mode 100755
index 0000000000..de06dfe3d6
--- /dev/null
+++ b/extensions/spellcheck/locales/en-US/hunspell/dictionary-sources/make-new-dict.sh
@@ -0,0 +1,128 @@
+#! /usr/bin/env sh
+
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+# This script creates a new dictionary by expanding the original,
+# Mozilla's, and the upstream dictionary to remove affix flags and
+# then doing the wordlist equivalent of diff3 to create a new
+# dictionary.
+#
+# The files 2-mozilla-add and 2-mozilla-rem contain words added and
+# removed, respectively in the Mozilla dictionary. The final
+# dictionary will be in hunspell-en_US-mozilla.zip.
+
+set -e
+
+export LANG=C
+export LC_ALL=C
+export LC_CTYPE=C
+export LC_COLLATE=C
+
+WKDIR="`pwd`"
+ORIG="$WKDIR/orig"
+SUPPORT_DIR="$WKDIR/support_files"
+SPELLER="$WKDIR/scowl/speller"
+
+# This is required by scowl scripts
+export SCOWL="$WKDIR/scowl/"
+
+expand() {
+ grep -v '^[0-9]\+$' | $SPELLER/munch-list expand $1 | sort -u
+}
+
+if [ ! -d "$SPELLER" ]; then
+ echo "The 'scowl' folder is missing. Check the documentation at"
+ echo "https://firefox-source-docs.mozilla.org/extensions/spellcheck/index.html"
+ exit 1
+fi
+
+mkdir -p $SUPPORT_DIR
+cd $SPELLER
+MK_LIST="../mk-list -v1 --accents=both en_US 60"
+cat <<EOF > params.txt
+With Input Command: $MK_LIST
+EOF
+# Note: the output of make-hunspell-dict is UTF-8
+$MK_LIST | ./make-hunspell-dict -one en_US-custom params.txt > ./make-hunspell-dict.log
+cd $WKDIR
+
+# Note: Input and output of "expand" is always ISO-8859-1.
+# All expanded word list files are thus in ISO-8859-1.
+expand $SPELLER/en.aff < $SPELLER/en.dic.supp > $SUPPORT_DIR/0-special.txt
+
+# Input is UTF-8, expand expects ISO-8859-1 so use iconv
+iconv -f utf-8 -t iso-8859-1 $ORIG/en_US-custom.dic | expand $ORIG/en_US-custom.aff > $SUPPORT_DIR/1-base.txt
+
+# Store suggestion exclusions (ending with !) defined in current Mozilla dictionary.
+# Save both the compressed (munched) and expanded version.
+grep '!$' ../en-US.dic > $SUPPORT_DIR/2-mozilla-nosug-munched.txt
+expand ../en-US.aff < $SUPPORT_DIR/2-mozilla-nosug-munched.txt > $SUPPORT_DIR/2-mozilla-nosug.txt
+
+# Remove suggestion exclusions and expand the existing Mozilla dictionary.
+# The existing Mozilla dictionary is already in ISO-8859-1.
+grep -v '!$' < ../en-US.dic > $SUPPORT_DIR/en-US-nosug.dic
+expand ../en-US.aff < $SUPPORT_DIR/en-US-nosug.dic > $SUPPORT_DIR/2-mozilla.txt
+rm $SUPPORT_DIR/en-US-nosug.dic
+
+# Input is UTF-8, expand expects ISO-8859-1 so use iconv
+iconv -f utf-8 -t iso-8859-1 $SPELLER/en_US-custom.dic | expand $SPELLER/en_US-custom.aff > $SUPPORT_DIR/3-upstream.txt
+
+# Suppress common lines and lines only in the 2nd file, leaving words that are
+# only available in the 1st file (SCOWL), i.e. were removed by Mozilla.
+comm -23 $SUPPORT_DIR/1-base.txt $SUPPORT_DIR/2-mozilla.txt > $SUPPORT_DIR/2-mozilla-removed.txt
+
+# Suppress common lines and lines only in the 1st file, leaving words that are
+# only available in the 2nd file (current Mozilla dictionary), i.e. were added
+# by Mozilla.
+comm -13 $SUPPORT_DIR/1-base.txt $SUPPORT_DIR/2-mozilla.txt > $SUPPORT_DIR/2-mozilla-added.txt
+
+# Suppress common lines and lines only in the 2nd file, leaving words that are
+# only available in the 1st file (words from the new upstream SCOWL dictionary).
+# The result is upstream, minus the words removed, plus the words added.
+comm -23 $SUPPORT_DIR/3-upstream.txt $SUPPORT_DIR/2-mozilla-removed.txt | cat - $SUPPORT_DIR/2-mozilla-added.txt | sort -u > $SUPPORT_DIR/4-patched.txt
+
+# Note: the output of make-hunspell-dict is UTF-8
+cat $SUPPORT_DIR/4-patched.txt | comm -23 - $SUPPORT_DIR/0-special.txt | $SPELLER/make-hunspell-dict -one en_US-mozilla /dev/null
+
+# Add back Mozilla suggestion exclusions. Need to convert the file from
+# ISO-8859-1 to UTF-8 first, then add back the line count and reorder.
+tail -n +2 en_US-mozilla.dic > en_US-mozilla-complete.dic
+iconv -f iso-8859-1 -t utf-8 $SUPPORT_DIR/2-mozilla-nosug-munched.txt >> en_US-mozilla-complete.dic
+wc -l < en_US-mozilla-complete.dic | tr -d '[:blank:]' > en_US-mozilla.dic
+LC_ALL=C sort en_US-mozilla-complete.dic >> en_US-mozilla.dic
+rm -f en_US-mozilla-complete.dic
+
+# Sanity check should yield identical results
+#comm -23 $SUPPORT_DIR/1-base.txt $SUPPORT_DIR/3-upstream.txt > $SUPPORT_DIR/3-upstream-remover.txt
+#comm -13 $SUPPORT_DIR/1-base.txt $SUPPORT_DIR/3-upstream.txt > $SUPPORT_DIR/3-upstream-added.txt
+#comm -23 $SUPPORT_DIR/2-mozilla.txt $SUPPORT_DIR/3-upstream-removed.txt | cat - $SUPPORT_DIR/3-upstream-added.txt | sort -u > $SUPPORT_DIR/4-patched-v2.txt
+
+expand ../en-US.aff < mozilla-specific.txt > 5-mozilla-specific.txt
+
+# Update Mozilla removed and added wordlists based on the new upstream
+# dictionary, save them as UTF-8 and not ISO-8951-1.
+# Ignore words excluded from suggestions for both files.
+comm -12 $SUPPORT_DIR/3-upstream.txt $SUPPORT_DIR/2-mozilla-removed.txt > $SUPPORT_DIR/5-mozilla-removed-tmp.txt
+comm -23 $SUPPORT_DIR/5-mozilla-removed-tmp.txt $SUPPORT_DIR/2-mozilla-nosug.txt > $SUPPORT_DIR/5-mozilla-removed.txt
+rm $SUPPORT_DIR/5-mozilla-removed-tmp.txt
+iconv -f iso-8859-1 -t utf-8 $SUPPORT_DIR/5-mozilla-removed.txt > 5-mozilla-removed.txt
+
+comm -13 $SUPPORT_DIR/3-upstream.txt $SUPPORT_DIR/2-mozilla-added.txt > $SUPPORT_DIR/5-mozilla-added-tmp.txt
+comm -23 $SUPPORT_DIR/5-mozilla-added-tmp.txt $SUPPORT_DIR/2-mozilla-nosug.txt > $SUPPORT_DIR/5-mozilla-added.txt
+rm $SUPPORT_DIR/5-mozilla-added-tmp.txt
+iconv -f iso-8859-1 -t utf-8 $SUPPORT_DIR/5-mozilla-added.txt > 5-mozilla-added.txt
+
+# Clean up some files
+rm hunspell-en_US-mozilla.zip
+rm nosug
+
+# Remove backup folders in preparation for the install-new-dict script
+FOLDERS=( "orig-bk" "mozilla-bk")
+for f in ${FOLDERS[@]}; do
+ if [ -d "$SUPPORT_DIR/$f" ]; then
+ echo "Removing backup folder $f"
+ rm -rf "$SUPPORT_DIR/$f"
+ fi
+done
diff --git a/extensions/spellcheck/locales/en-US/hunspell/dictionary-sources/mozilla-specific.txt b/extensions/spellcheck/locales/en-US/hunspell/dictionary-sources/mozilla-specific.txt
new file mode 100644
index 0000000000..d28a4c756b
--- /dev/null
+++ b/extensions/spellcheck/locales/en-US/hunspell/dictionary-sources/mozilla-specific.txt
@@ -0,0 +1,21 @@
+Bugzilla/M
+ChatZilla/M
+Fenix/M
+Fennec/M
+Firefox/M
+Gecko/M
+JavaScript/M
+Mozilla/M
+Necko/M
+Netscape/M
+NSPR/M
+NSS/M
+SeaMonkey/M
+SpiderMonkey/M
+Thunderbird/M
+XBL/M
+XPCOM/M
+XPConnect/M
+XPInstall/M
+XUL/M
+XULRunner/M
diff --git a/extensions/spellcheck/locales/en-US/hunspell/dictionary-sources/orig/README_en_US-custom.txt b/extensions/spellcheck/locales/en-US/hunspell/dictionary-sources/orig/README_en_US-custom.txt
new file mode 100644
index 0000000000..94474576b6
--- /dev/null
+++ b/extensions/spellcheck/locales/en-US/hunspell/dictionary-sources/orig/README_en_US-custom.txt
@@ -0,0 +1,348 @@
+en_US-custom Hunspell Dictionary
+Generated from SCOWL Version 2020.12.07
+Wed Jan 25 07:25:50 CET 2023
+
+http://wordlist.sourceforge.net
+
+README file for English Hunspell dictionaries derived from SCOWL.
+
+These dictionaries are created using the speller/make-hunspell-dict
+script in SCOWL.
+
+The following dictionaries are available:
+
+ en_US (American)
+ en_CA (Canadian)
+ en_GB-ise (British with "ise" spelling)
+ en_GB-ize (British with "ize" spelling)
+ en_AU (Australian)
+
+ en_US-large
+ en_CA-large
+ en_GB-large (with both "ise" and "ize" spelling)
+ en_AU-large
+
+The normal (non-large) dictionaries correspond to SCOWL size 60 and,
+to encourage consistent spelling, generally only include one spelling
+variant for a word. The large dictionaries correspond to SCOWL size
+70 and may include multiple spelling for a word when both variants are
+considered almost equal. The larger dictionaries however (1) have not
+been as carefully checked for errors as the normal dictionaries and
+thus may contain misspelled or invalid words; and (2) contain
+uncommon, yet valid, words that might cause problems as they are
+likely to be misspellings of more common words (for example, "ort" and
+"calender").
+
+To get an idea of the difference in size, here are 25 random words
+only found in the large dictionary for American English:
+
+ Bermejo Freyr's Guenevere Hatshepsut Nottinghamshire arrestment
+ crassitudes crural dogwatches errorless fetial flaxseeds godroon
+ incretion jalape単o's kelpie kishkes neuroglias pietisms pullulation
+ stemwinder stenoses syce thalassic zees
+
+The en_US, en_CA and en_AU are the official dictionaries for Hunspell.
+The en_GB and large dictionaries are made available on an experimental
+basis. If you find them useful please send me a quick email at
+kevina@gnu.org.
+
+If none of these dictionaries suite you (for example, maybe you want
+the normal dictionary that also includes common variants) additional
+dictionaries can be generated at http://app.aspell.net/create or by
+modifying speller/make-hunspell-dict in SCOWL. Please do let me know
+if you end up publishing a customized dictionary.
+
+If a word is not found in the dictionary or a word is there you think
+shouldn't be, you can lookup the word up at http://app.aspell.net/lookup
+to help determine why that is.
+
+General comments on these list can be sent directly to me at
+kevina@gnu.org or to the wordlist-devel mailing lists
+(https://lists.sourceforge.net/lists/listinfo/wordlist-devel). If you
+have specific issues with any of these dictionaries please file a bug
+report at https://github.com/kevina/wordlist/issues.
+
+IMPORTANT CHANGES INTRODUCED In 2016.11.20:
+
+New Australian dictionaries thanks to the work of Benjamin Titze
+(btitze@protonmail.ch).
+
+IMPORTANT CHANGES INTRODUCED IN 2016.04.24:
+
+The dictionaries are now in UTF-8 format instead of ISO-8859-1. This
+was required to handle smart quotes correctly.
+
+IMPORTANT CHANGES INTRODUCED IN 2016.01.19:
+
+"SET UTF8" was changes to "SET UTF-8" in the affix file as some
+versions of Hunspell do not recognize "UTF8".
+
+ADDITIONAL NOTES:
+
+The NOSUGGEST flag was added to certain taboo words. While I made an
+honest attempt to flag the strongest taboo words with the NOSUGGEST
+flag, I MAKE NO GUARANTEE THAT I FLAGGED EVERY POSSIBLE TABOO WORD.
+The list was originally derived from N辿meth L叩szl坦, however I removed
+some words which, while being considered taboo by some dictionaries,
+are not really considered swear words in today's society.
+
+COPYRIGHT, SOURCES, and CREDITS:
+
+The English dictionaries come directly from SCOWL
+and is thus under the same copyright of SCOWL. The affix file is
+a heavily modified version of the original english.aff file which was
+released as part of Geoff Kuenning's Ispell and as such is covered by
+his BSD license. Part of SCOWL is also based on Ispell thus the
+Ispell copyright is included with the SCOWL copyright.
+
+The collective work is Copyright 2000-2018 by Kevin Atkinson as well
+as any of the copyrights mentioned below:
+
+ Copyright 2000-2018 by Kevin Atkinson
+
+ Permission to use, copy, modify, distribute and sell these word
+ lists, the associated scripts, the output created from the scripts,
+ and its documentation for any purpose is hereby granted without fee,
+ provided that the above copyright notice appears in all copies and
+ that both that copyright notice and this permission notice appear in
+ supporting documentation. Kevin Atkinson makes no representations
+ about the suitability of this array for any purpose. It is provided
+ "as is" without express or implied warranty.
+
+Alan Beale <biljir@pobox.com> also deserves special credit as he has,
+in addition to providing the 12Dicts package and being a major
+contributor to the ENABLE word list, given me an incredible amount of
+feedback and created a number of special lists (those found in the
+Supplement) in order to help improve the overall quality of SCOWL.
+
+The 10 level includes the 1000 most common English words (according to
+the Moby (TM) Words II [MWords] package), a subset of the 1000 most
+common words on the Internet (again, according to Moby Words II), and
+frequently class 16 from Brian Kelk's "UK English Wordlist
+with Frequency Classification".
+
+The MWords package was explicitly placed in the public domain:
+
+ The Moby lexicon project is complete and has
+ been place into the public domain. Use, sell,
+ rework, excerpt and use in any way on any platform.
+
+ Placing this material on internal or public servers is
+ also encouraged. The compiler is not aware of any
+ export restrictions so freely distribute world-wide.
+
+ You can verify the public domain status by contacting
+
+ Grady Ward
+ 3449 Martha Ct.
+ Arcata, CA 95521-4884
+
+ grady@netcom.com
+ grady@northcoast.com
+
+The "UK English Wordlist With Frequency Classification" is also in the
+Public Domain:
+
+ Date: Sat, 08 Jul 2000 20:27:21 +0100
+ From: Brian Kelk <Brian.Kelk@cl.cam.ac.uk>
+
+ > I was wondering what the copyright status of your "UK English
+ > Wordlist With Frequency Classification" word list as it seems to
+ > be lacking any copyright notice.
+
+ There were many many sources in total, but any text marked
+ "copyright" was avoided. Locally-written documentation was one
+ source. An earlier version of the list resided in a filespace called
+ PUBLIC on the University mainframe, because it was considered public
+ domain.
+
+ Date: Tue, 11 Jul 2000 19:31:34 +0100
+
+ > So are you saying your word list is also in the public domain?
+
+ That is the intention.
+
+The 20 level includes frequency classes 7-15 from Brian's word list.
+
+The 35 level includes frequency classes 2-6 and words appearing in at
+least 11 of 12 dictionaries as indicated in the 12Dicts package. All
+words from the 12Dicts package have had likely inflections added via
+my inflection database.
+
+The 12Dicts package and Supplement is in the Public Domain.
+
+The WordNet database, which was used in the creation of the
+Inflections database, is under the following copyright:
+
+ This software and database is being provided to you, the LICENSEE,
+ by Princeton University under the following license. By obtaining,
+ using and/or copying this software and database, you agree that you
+ have read, understood, and will comply with these terms and
+ conditions.:
+
+ Permission to use, copy, modify and distribute this software and
+ database and its documentation for any purpose and without fee or
+ royalty is hereby granted, provided that you agree to comply with
+ the following copyright notice and statements, including the
+ disclaimer, and that the same appear on ALL copies of the software,
+ database and documentation, including modifications that you make
+ for internal use or for distribution.
+
+ WordNet 1.6 Copyright 1997 by Princeton University. All rights
+ reserved.
+
+ THIS SOFTWARE AND DATABASE IS PROVIDED "AS IS" AND PRINCETON
+ UNIVERSITY MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR
+ IMPLIED. BY WAY OF EXAMPLE, BUT NOT LIMITATION, PRINCETON
+ UNIVERSITY MAKES NO REPRESENTATIONS OR WARRANTIES OF MERCHANT-
+ ABILITY OR FITNESS FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF THE
+ LICENSED SOFTWARE, DATABASE OR DOCUMENTATION WILL NOT INFRINGE ANY
+ THIRD PARTY PATENTS, COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS.
+
+ The name of Princeton University or Princeton may not be used in
+ advertising or publicity pertaining to distribution of the software
+ and/or database. Title to copyright in this software, database and
+ any associated documentation shall at all times remain with
+ Princeton University and LICENSEE agrees to preserve same.
+
+The 40 level includes words from Alan's 3esl list found in version 4.0
+of his 12dicts package. Like his other stuff the 3esl list is also in the
+public domain.
+
+The 50 level includes Brian's frequency class 1, words appearing
+in at least 5 of 12 of the dictionaries as indicated in the 12Dicts
+package, and uppercase words in at least 4 of the previous 12
+dictionaries. A decent number of proper names is also included: The
+top 1000 male, female, and Last names from the 1990 Census report; a
+list of names sent to me by Alan Beale; and a few names that I added
+myself. Finally a small list of abbreviations not commonly found in
+other word lists is included.
+
+The name files form the Census report is a government document which I
+don't think can be copyrighted.
+
+The file special-jargon.50 uses common.lst and word.lst from the
+"Unofficial Jargon File Word Lists" which is derived from "The Jargon
+File". All of which is in the Public Domain. This file also contain
+a few extra UNIX terms which are found in the file "unix-terms" in the
+special/ directory.
+
+The 55 level includes words from Alan's 2of4brif list found in version
+4.0 of his 12dicts package. Like his other stuff the 2of4brif is also
+in the public domain.
+
+The 60 level includes all words appearing in at least 2 of the 12
+dictionaries as indicated by the 12Dicts package.
+
+The 70 level includes Brian's frequency class 0 and the 74,550 common
+dictionary words from the MWords package. The common dictionary words,
+like those from the 12Dicts package, have had all likely inflections
+added. The 70 level also included the 5desk list from version 4.0 of
+the 12Dics package which is in the public domain.
+
+The 80 level includes the ENABLE word list, all the lists in the
+ENABLE supplement package (except for ABLE), the "UK Advanced Cryptics
+Dictionary" (UKACD), the list of signature words from the YAWL package,
+and the 10,196 places list from the MWords package.
+
+The ENABLE package, mainted by M\Cooper <thegrendel@theriver.com>,
+is in the Public Domain:
+
+ The ENABLE master word list, WORD.LST, is herewith formally released
+ into the Public Domain. Anyone is free to use it or distribute it in
+ any manner they see fit. No fee or registration is required for its
+ use nor are "contributions" solicited (if you feel you absolutely
+ must contribute something for your own peace of mind, the authors of
+ the ENABLE list ask that you make a donation on their behalf to your
+ favorite charity). This word list is our gift to the Scrabble
+ community, as an alternate to "official" word lists. Game designers
+ may feel free to incorporate the WORD.LST into their games. Please
+ mention the source and credit us as originators of the list. Note
+ that if you, as a game designer, use the WORD.LST in your product,
+ you may still copyright and protect your product, but you may *not*
+ legally copyright or in any way restrict redistribution of the
+ WORD.LST portion of your product. This *may* under law restrict your
+ rights to restrict your users' rights, but that is only fair.
+
+UKACD, by J Ross Beresford <ross@bryson.demon.co.uk>, is under the
+following copyright:
+
+ Copyright (c) J Ross Beresford 1993-1999. All Rights Reserved.
+
+ The following restriction is placed on the use of this publication:
+ if The UK Advanced Cryptics Dictionary is used in a software package
+ or redistributed in any form, the copyright notice must be
+ prominently displayed and the text of this document must be included
+ verbatim.
+
+ There are no other restrictions: I would like to see the list
+ distributed as widely as possible.
+
+The 95 level includes the 354,984 single words, 256,772 compound
+words, 4,946 female names and the 3,897 male names, and 21,986 names
+from the MWords package, ABLE.LST from the ENABLE Supplement, and some
+additional words found in my part-of-speech database that were not
+found anywhere else.
+
+Accent information was taken from UKACD.
+
+The VarCon package was used to create the American, British, Canadian,
+and Australian word list. It is under the following copyright:
+
+ Copyright 2000-2016 by Kevin Atkinson
+
+ Permission to use, copy, modify, distribute and sell this array, the
+ associated software, and its documentation for any purpose is hereby
+ granted without fee, provided that the above copyright notice appears
+ in all copies and that both that copyright notice and this permission
+ notice appear in supporting documentation. Kevin Atkinson makes no
+ representations about the suitability of this array for any
+ purpose. It is provided "as is" without express or implied warranty.
+
+ Copyright 2016 by Benjamin Titze
+
+ Permission to use, copy, modify, distribute and sell this array, the
+ associated software, and its documentation for any purpose is hereby
+ granted without fee, provided that the above copyright notice appears
+ in all copies and that both that copyright notice and this permission
+ notice appear in supporting documentation. Benjamin Titze makes no
+ representations about the suitability of this array for any
+ purpose. It is provided "as is" without express or implied warranty.
+
+ Since the original words lists come from the Ispell distribution:
+
+ Copyright 1993, Geoff Kuenning, Granada Hills, CA
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+
+ 1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+ 3. All modifications to the source code must be clearly marked as
+ such. Binary redistributions based on modified source code
+ must be clearly marked as modified versions in the documentation
+ and/or other materials provided with the distribution.
+ (clause 4 removed with permission from Geoff Kuenning)
+ 5. The name of Geoff Kuenning may not be used to endorse or promote
+ products derived from this software without specific prior
+ written permission.
+
+ THIS SOFTWARE IS PROVIDED BY GEOFF KUENNING AND CONTRIBUTORS ``AS IS'' AND
+ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL GEOFF KUENNING OR CONTRIBUTORS BE LIABLE
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ SUCH DAMAGE.
+
+Build Date: Wed Jan 25 07:25:50 CET 2023
+With Input Command: ../mk-list -v1 --accents=both en_US 60
diff --git a/extensions/spellcheck/locales/en-US/hunspell/dictionary-sources/orig/en_US-custom.aff b/extensions/spellcheck/locales/en-US/hunspell/dictionary-sources/orig/en_US-custom.aff
new file mode 100644
index 0000000000..d0cccb3dc7
--- /dev/null
+++ b/extensions/spellcheck/locales/en-US/hunspell/dictionary-sources/orig/en_US-custom.aff
@@ -0,0 +1,205 @@
+SET UTF-8
+TRY esianrtolcdugmphbyfvkwzESIANRTOLCDUGMPHBYFVKWZ'
+ICONV 1
+ICONV '
+NOSUGGEST !
+
+# ordinal numbers
+COMPOUNDMIN 1
+# only in compounds: 1th, 2th, 3th
+ONLYINCOMPOUND c
+# compound rules:
+# 1. [0-9]*1[0-9]th (10th, 11th, 12th, 56714th, etc.)
+# 2. [0-9]*[02-9](1st|2nd|3rd|[4-9]th) (21st, 22nd, 123rd, 1234th, etc.)
+COMPOUNDRULE 2
+COMPOUNDRULE n*1t
+COMPOUNDRULE n*mp
+WORDCHARS 0123456789
+
+PFX A Y 1
+PFX A 0 re .
+
+PFX I Y 1
+PFX I 0 in .
+
+PFX U Y 1
+PFX U 0 un .
+
+PFX C Y 1
+PFX C 0 de .
+
+PFX E Y 1
+PFX E 0 dis .
+
+PFX F Y 1
+PFX F 0 con .
+
+PFX K Y 1
+PFX K 0 pro .
+
+SFX V N 2
+SFX V e ive e
+SFX V 0 ive [^e]
+
+SFX N Y 3
+SFX N e ion e
+SFX N y ication y
+SFX N 0 en [^ey]
+
+SFX X Y 3
+SFX X e ions e
+SFX X y ications y
+SFX X 0 ens [^ey]
+
+SFX H N 2
+SFX H y ieth y
+SFX H 0 th [^y]
+
+SFX Y Y 1
+SFX Y 0 ly .
+
+SFX G Y 2
+SFX G e ing e
+SFX G 0 ing [^e]
+
+SFX J Y 2
+SFX J e ings e
+SFX J 0 ings [^e]
+
+SFX D Y 4
+SFX D 0 d e
+SFX D y ied [^aeiou]y
+SFX D 0 ed [^ey]
+SFX D 0 ed [aeiou]y
+
+SFX T N 4
+SFX T 0 st e
+SFX T y iest [^aeiou]y
+SFX T 0 est [aeiou]y
+SFX T 0 est [^ey]
+
+SFX R Y 4
+SFX R 0 r e
+SFX R y ier [^aeiou]y
+SFX R 0 er [aeiou]y
+SFX R 0 er [^ey]
+
+SFX Z Y 4
+SFX Z 0 rs e
+SFX Z y iers [^aeiou]y
+SFX Z 0 ers [aeiou]y
+SFX Z 0 ers [^ey]
+
+SFX S Y 4
+SFX S y ies [^aeiou]y
+SFX S 0 s [aeiou]y
+SFX S 0 es [sxzh]
+SFX S 0 s [^sxzhy]
+
+SFX P Y 3
+SFX P y iness [^aeiou]y
+SFX P 0 ness [aeiou]y
+SFX P 0 ness [^y]
+
+SFX M Y 1
+SFX M 0 's .
+
+SFX B Y 3
+SFX B 0 able [^aeiou]
+SFX B 0 able ee
+SFX B e able [^aeiou]e
+
+SFX L Y 1
+SFX L 0 ment .
+
+REP 90
+REP a ei
+REP ei a
+REP a ey
+REP ey a
+REP ai ie
+REP ie ai
+REP alot a_lot
+REP are air
+REP are ear
+REP are eir
+REP air are
+REP air ere
+REP ere air
+REP ere ear
+REP ere eir
+REP ear are
+REP ear air
+REP ear ere
+REP eir are
+REP eir ere
+REP ch te
+REP te ch
+REP ch ti
+REP ti ch
+REP ch tu
+REP tu ch
+REP ch s
+REP s ch
+REP ch k
+REP k ch
+REP f ph
+REP ph f
+REP gh f
+REP f gh
+REP i igh
+REP igh i
+REP i uy
+REP uy i
+REP i ee
+REP ee i
+REP j di
+REP di j
+REP j gg
+REP gg j
+REP j ge
+REP ge j
+REP s ti
+REP ti s
+REP s ci
+REP ci s
+REP k cc
+REP cc k
+REP k qu
+REP qu k
+REP kw qu
+REP o eau
+REP eau o
+REP o ew
+REP ew o
+REP oo ew
+REP ew oo
+REP ew ui
+REP ui ew
+REP oo ui
+REP ui oo
+REP ew u
+REP u ew
+REP oo u
+REP u oo
+REP u oe
+REP oe u
+REP u ieu
+REP ieu u
+REP ue ew
+REP ew ue
+REP uff ough
+REP oo ieu
+REP ieu oo
+REP ier ear
+REP ear ier
+REP ear air
+REP air ear
+REP w qu
+REP qu w
+REP z ss
+REP ss z
+REP shun tion
+REP shun sion
+REP shun cion
+REP size cise
diff --git a/extensions/spellcheck/locales/en-US/hunspell/dictionary-sources/orig/en_US-custom.dic b/extensions/spellcheck/locales/en-US/hunspell/dictionary-sources/orig/en_US-custom.dic
new file mode 100644
index 0000000000..6d3d66a46f
--- /dev/null
+++ b/extensions/spellcheck/locales/en-US/hunspell/dictionary-sources/orig/en_US-custom.dic
@@ -0,0 +1,50060 @@
+50059
+0/nm
+0th/pt
+1/n1
+1st/p
+1th/tc
+2/nm
+2nd/p
+2th/tc
+3/nm
+3rd/p
+3th/tc
+4/nm
+4th/pt
+5/nm
+5th/pt
+6/nm
+6th/pt
+7/nm
+7th/pt
+8/nm
+8th/pt
+9/nm
+9th/pt
+A/SM
+AA/M
+AAA
+AB/M
+ABA
+ABC/SM
+ABM/SM
+ABS
+AC/M
+ACLU/M
+ACT
+ACTH/M
+AD/M
+ADC
+ADD
+ADM
+ADP/M
+AF
+AFAIK
+AFB
+AFC/M
+AFDC
+AFN
+AFT
+AI/SM
+AIDS/M
+AK
+AL
+AM/M
+AMA
+AMD/M
+ANSI/S
+ANZUS/M
+AOL/M
+AP/M
+APB
+APC
+API
+APO
+APR
+AR
+ARC
+ASAP
+ASCII/SM
+ASL/M
+ASPCA
+ATM/M
+ATP/M
+ATV
+AV
+AVI
+AWACS/M
+AWOL/M
+AWS/M
+AZ/M
+AZT/M
+Aachen/M
+Aaliyah/M
+Aaron/M
+Abbas/M
+Abbasid/M
+Abbott/M
+Abby/M
+Abdul/M
+Abe/M
+Abel/M
+Abelard/M
+Abelson/M
+Aberdeen/M
+Abernathy/M
+Abidjan/M
+Abigail/M
+Abilene/M
+Abner/M
+Aborigine/MS
+Abraham/M
+Abram/MS
+Abrams/M
+Absalom/M
+Abuja/M
+Abyssinia/M
+Abyssinian/M
+Ac/M
+Acadia/M
+Acapulco/M
+Accenture/M
+Accra/M
+Acevedo/M
+Achaean/M
+Achebe/M
+Achernar/M
+Acheson/M
+Achilles/M
+Aconcagua/M
+Acosta/M
+Acropolis
+Acrux/M
+Actaeon/M
+Acton/M
+Acts/M
+Acuff/M
+Ada/SM
+Adam/SM
+Adams/M
+Adan/M
+Adana/M
+Adar/M
+Addams/M
+Adderley/M
+Addie/M
+Addison/M
+Adela/M
+Adelaide/M
+Adele/M
+Adeline/M
+Aden/M
+Adenauer/M
+Adhara/M
+Adidas/M
+Adirondack/SM
+Adirondacks/M
+Adkins/M
+Adler/M
+Adm
+Admiralty
+Adolf/M
+Adolfo/M
+Adolph/M
+Adonis/MS
+Adrenalin/MS
+Adrian/M
+Adriana/M
+Adriatic/M
+Adrienne/M
+Advent/MS
+Adventist/MS
+Advil/M
+Aegean/M
+Aelfric/M
+Aeneas/M
+Aeneid/M
+Aeolus/M
+Aeroflot/M
+Aeschylus/M
+Aesculapius/M
+Aesop/M
+Afghan/SM
+Afghani/M
+Afghanistan/M
+Afr
+Africa/M
+African/SM
+Afrikaans/M
+Afrikaner/SM
+Afro/SM
+Afrocentric
+Afrocentrism/M
+Ag/M
+Agamemnon/M
+Agana
+Agassi/M
+Agassiz/M
+Agatha/M
+Aggie/M
+Aglaia/M
+Agnes/M
+Agnew/M
+Agni/M
+Agra/M
+Agricola/M
+Agrippa/M
+Agrippina/M
+Aguadilla/M
+Aguascalientes
+Aguilar/M
+Aguinaldo/M
+Aguirre/M
+Agustin/M
+Ahab/M
+Ahmad/M
+Ahmadabad/M
+Ahmadinejad/M
+Ahmed/M
+Ahriman/M
+Aida/M
+Aiken/M
+Aileen/M
+Aimee/M
+Ainu/M
+Airedale/MS
+Aires/M
+Aisha/M
+Ajax/M
+Akbar/M
+Akhmatova/M
+Akihito/M
+Akita/M
+Akiva/M
+Akkad/M
+Akron/M
+Al/M
+Ala/S
+Alabama/M
+Alabaman/MS
+Alabamian/SM
+Aladdin/M
+Alamo/M
+Alamogordo/M
+Alan/M
+Alana/M
+Alar/M
+Alaric/M
+Alaska/M
+Alaskan/MS
+Alba/M
+Albania/M
+Albanian/MS
+Albany/M
+Albee/M
+Alberio/M
+Albert/M
+Alberta/M
+Albertan
+Alberto/M
+Albigensian/M
+Albion/M
+Albireo/M
+Albuquerque/M
+Alcatraz/M
+Alcestis/M
+Alcibiades/M
+Alcindor/M
+Alcmena/M
+Alcoa/M
+Alcott/M
+Alcuin/M
+Alcyone/M
+Aldan/M
+Aldebaran/M
+Alden/M
+Alderamin/M
+Aldo/M
+Aldrin/M
+Alec/M
+Aleichem/M
+Alejandra/M
+Alejandro/M
+Alembert/M
+Aleppo/M
+Aleut/MS
+Aleutian/SM
+Alex/M
+Alexander/MS
+Alexandra/M
+Alexandria/M
+Alexandrian
+Alexei/M
+Alexis/M
+Alfonso/M
+Alfonzo/M
+Alford/M
+Alfred/M
+Alfreda/M
+Alfredo/M
+Algenib/M
+Alger/M
+Algeria/M
+Algerian/SM
+Algieba/M
+Algiers/M
+Algol/M
+Algonquian/SM
+Algonquin/MS
+Alhambra/M
+Alhena/M
+Ali/M
+Alice/M
+Alicia/M
+Alighieri/M
+Aline/M
+Alioth/M
+Alisa/M
+Alisha/M
+Alison/M
+Alissa/M
+Alistair/M
+Alkaid/M
+Allah/M
+Allahabad/M
+Allan/M
+Alleghenies/M
+Allegheny/SM
+Allegra/M
+Allen/M
+Allende/M
+Allentown/M
+Allhallows/M
+Allie/MS
+Allison/M
+Allstate/M
+Allyson/M
+Alma/M
+Almach/M
+Almaty/M
+Almighty/M
+Almohad/M
+Almoravid/M
+Alnilam/M
+Alnitak/M
+Alonzo/M
+Alpert/M
+Alphard/M
+Alphecca/M
+Alpheratz/M
+Alphonse/M
+Alphonso/M
+Alpine/M
+Alpo/M
+Alps/M
+Alsace/M
+Alsatian/SM
+Alsop/M
+Alston/M
+Alta/M
+Altaba/M
+Altai/M
+Altaic/M
+Altair/M
+Altamira/M
+Althea/M
+Altiplano/M
+Altman/M
+Altoids/M
+Alton/M
+Altoona/M
+Aludra/M
+Alva/M
+Alvarado/M
+Alvarez/M
+Alvaro/M
+Alvin/M
+Alyce/M
+Alyson/M
+Alyssa/M
+Alzheimer/M
+Am/MNR
+Amadeus/M
+Amado/M
+Amalia/M
+Amanda/M
+Amarillo/M
+Amaru/M
+Amaterasu/M
+Amati/M
+Amazon/SM
+Amazonian
+Amber/M
+Amelia/M
+Amen/M
+Amenhotep/M
+Amerasian/M
+America/SM
+American/MS
+Americana/M
+Americanism/MS
+Americanization/MS
+Americanize/GDS
+Amerind/SM
+Amerindian/MS
+Ames/M
+Ameslan/M
+Amgen/M
+Amharic/M
+Amherst/M
+Amie/M
+Amiga/M
+Amish/M
+Amman/M
+Amoco/M
+Amos/M
+Amparo/M
+Ampere/M
+Amritsar/M
+Amsterdam/M
+Amtrak/M
+Amundsen/M
+Amur/M
+Amway/M
+Amy/M
+Ana/M
+Anabaptist/M
+Anabel/M
+Anacin/M
+Anacreon/M
+Anaheim/M
+Analects/M
+Ananias/M
+Anasazi/M
+Anastasia/M
+Anatole/M
+Anatolia/M
+Anatolian/M
+Anaxagoras/M
+Anchorage/M
+Andalusia/M
+Andalusian/M
+Andaman/M
+Andean/M
+Andersen/M
+Anderson/M
+Andes/M
+Andorra/M
+Andorran/SM
+Andre/MS
+Andrea/M
+Andrei/M
+Andres/M
+Andretti/M
+Andrew/SM
+Andrews/M
+Andrianampoinimerina/M
+Android/M
+Andromache/M
+Andromeda/M
+Andropov/M
+Andy/M
+Angara/M
+Angel/M
+Angela/M
+Angeles/M
+Angelia/M
+Angelica/M
+Angelico/M
+Angelina/M
+Angeline/M
+Angelique/M
+Angelita/M
+Angelo/M
+Angelou/M
+Angevin/M
+Angie/M
+Angkor/M
+Angle/MS
+Angleton/M
+Anglia/M
+Anglican/SM
+Anglicanism/MS
+Anglicism/MS
+Anglicization
+Anglicize
+Anglo/M
+Anglophile/M
+Anglophobe
+Angola/M
+Angolan/MS
+Angora/SM
+Angstrom/M
+Anguilla/M
+Angus/M
+Anhui/M
+Aniakchak/M
+Anibal/M
+Anita/M
+Ankara/M
+Ann/M
+Anna/M
+Annabel/M
+Annabelle/M
+Annam/M
+Annapolis/M
+Annapurna/M
+Anne/M
+Annette/M
+Annie/M
+Anniston/M
+Annmarie/M
+Annunciation/SM
+Anouilh/M
+Anselm/M
+Anselmo/M
+Anshan/M
+Antaeus/M
+Antananarivo/M
+Antarctic/M
+Antarctica/M
+Antares/M
+Anthony/M
+Anthropocene
+Antichrist/SM
+Antietam/M
+Antifa/M
+Antigone/M
+Antigua/M
+Antillean
+Antilles/M
+Antioch/M
+Antipas/M
+Antipodes
+Antofagasta/M
+Antoine/M
+Antoinette/M
+Anton/M
+Antone/M
+Antonia/M
+Antoninus/M
+Antonio/M
+Antonius/M
+Antony/M
+Antwan/M
+Antwerp/M
+Anubis/M
+Anzac/M
+Apache/SM
+Apalachicola/M
+Apatosaurus
+Apennines/M
+Aphrodite/M
+Apia/M
+Apocalypse/M
+Apocrypha/M
+Apollinaire/M
+Apollo/SM
+Apollonian/M
+Apostle/M
+Appalachia/M
+Appalachian/SM
+Appalachians/M
+Appaloosa/SM
+Apple/M
+Appleseed/M
+Appleton/M
+Appomattox/M
+Apr/M
+April/MS
+Apuleius/M
+Aquafresh/M
+Aquarian
+Aquarius/MS
+Aquila/M
+Aquinas/M
+Aquino/M
+Aquitaine/M
+Ar/M
+Ara/M
+Arab/SM
+Arabia/M
+Arabian/MS
+Arabic/M
+Arabist/MS
+Araby/M
+Araceli/M
+Arafat/M
+Aragon
+Araguaya/M
+Aral/M
+Aramaic/M
+Aramco/M
+Arapaho/MS
+Arapahoes
+Ararat/M
+Araucanian/M
+Arawak/M
+Arawakan/M
+Arbitron/M
+Arcadia/M
+Arcadian/M
+Archean/M
+Archibald/M
+Archie/M
+Archimedes/M
+Arctic/M
+Arcturus/M
+Ardabil
+Arden/M
+Arduino/M
+Arecibo/M
+Arequipa/M
+Ares/M
+Argentina/M
+Argentine/M
+Argentinean
+Argentinian/MS
+Argo/SM
+Argonaut/MS
+Argonne/M
+Argos/M
+Argus/M
+Ariadne/M
+Arianism/M
+Ariel/M
+Aries/MS
+Ariosto/M
+Aristarchus/M
+Aristides/M
+Aristophanes/M
+Aristotelian/M
+Aristotle/M
+Arius/M
+Ariz
+Arizona/M
+Arizonan/SM
+Arizonian/MS
+Arjuna/M
+Ark/M
+Arkansan/MS
+Arkansas/M
+Arkhangelsk/M
+Arkwright/M
+Arlene/M
+Arline/M
+Arlington/M
+Armageddon/SM
+Armagnac/M
+Armand/M
+Armando/M
+Armani/M
+Armenia/M
+Armenian/SM
+Arminius/M
+Armonk/M
+Armour/M
+Armstrong/M
+Arneb/M
+Arnhem/M
+Arno/M
+Arnold/M
+Arnulfo/M
+Aron/M
+Arrhenius/M
+Arron/M
+Art/M
+Artaxerxes/M
+Artemis/M
+Arthur/M
+Arthurian/M
+Artie/M
+Arturo/M
+Aruba/M
+Aryan/MS
+As/M
+Asama/M
+Ascella/M
+Ascension/M
+Asgard/M
+Ashanti/M
+Ashcroft/M
+Ashe/M
+Asheville/M
+Ashgabat
+Ashikaga/M
+Ashkenazim/M
+Ashkhabad/M
+Ashlee/M
+Ashley/M
+Ashmolean/M
+Ashurbanipal/M
+Asia/M
+Asiago
+Asian/MS
+Asiatic/SM
+Asimov/M
+Asmara/M
+Asoka/M
+Aspell/M
+Aspen/M
+Asperger/M
+Aspidiske/M
+Asquith/M
+Assad/M
+Assam/M
+Assamese/M
+Assembly
+Assisi/M
+Assyria/M
+Assyrian/SM
+Astaire/M
+Astana/M
+Astarte/M
+Aston/M
+Astor/M
+Astoria/M
+Astrakhan/M
+AstroTurf/M
+Asturias/M
+Asuncion/M
+Asunci坦n/M
+Aswan/M
+At/SM
+Atacama/M
+Atahualpa/M
+Atalanta/M
+Atari/M
+Atascadero/M
+Ataturk/M
+Atat端rk/M
+Athabasca/M
+Athabaska
+Athabaskan/SM
+Athanasius
+Athena/M
+Athene/M
+Athenian/SM
+Athens/M
+Atkins/M
+Atkinson/M
+Atlanta/M
+Atlantes
+Atlantic/M
+Atlantis/M
+Atlas/MS
+Atman/M
+Atonement
+Atreus/M
+Atria/M
+Atropos/M
+Attic/M
+Attica/M
+Attila/M
+Attlee/M
+Attn
+Attucks/M
+Atwood/M
+Au/M
+Aubrey/M
+Auburn/M
+Auckland/M
+Auden/M
+Audi/M
+Audion/M
+Audra/M
+Audrey/M
+Audubon/M
+Aug/M
+Augean/M
+Augsburg/M
+August/MS
+Augusta/M
+Augustan/M
+Augustine/M
+Augustinian/MS
+Augustus/M
+Aurangzeb/M
+Aurelia/M
+Aurelio/M
+Aurelius/M
+Aureomycin/M
+Auriga/M
+Aurora/M
+Auschwitz/M
+Aussie/MS
+Austen/M
+Austerlitz/M
+Austin/MS
+Australasia/M
+Australasian
+Australia/M
+Australian/SM
+Australoid/M
+Australopithecus/M
+Austria/M
+Austrian/SM
+Austronesian/M
+Autumn/M
+Av/M
+Ava/M
+Avalon/M
+Ave/M
+Aventine/M
+Avernus/M
+Averroes/M
+Avery/M
+Avesta/M
+Avicenna/M
+Avignon/M
+Avila/M
+Avior/M
+Avis/M
+Avogadro/M
+Avon/M
+Avondale/M
+Axis
+Axum/M
+Ayala/M
+Ayers/M
+Aymara/M
+Ayrshire/M
+Ayurveda/M
+Ayyubid/M
+Azana/M
+Azania/M
+Azazel/M
+Azerbaijan/M
+Azerbaijani/MS
+Azores/M
+Azov/M
+Aztec/SM
+Aztecan/M
+Aztlan/M
+B/MNT
+BA/M
+BASIC/SM
+BB/M
+BBB/M
+BBC/M
+BBQ
+BBS
+BBSes
+BC/M
+BFF
+BIA
+BIOS
+BITNET
+BLT/SM
+BM/M
+BMW/M
+BO
+BP/M
+BPOE
+BR
+BS/M
+BSA
+BSD/SM
+BTU
+BTW
+BYOB
+Ba/M
+Baal/SM
+Baath/M
+Baathist/M
+Babbage/M
+Babbitt/M
+Babel/MS
+Babylon/MS
+Babylonia/M
+Babylonian/SM
+Bacall/M
+Bacardi/M
+Bacchanalia/M
+Bacchic
+Bacchus/M
+Bach/M
+Backus/M
+Bacon/M
+Bactria/M
+Baden/M
+Badlands/M
+Baedeker/MS
+Baez/M
+Baffin/M
+Baggies/M
+Baghdad/M
+Baguio/M
+Baha'i/M
+Baha'ullah/M
+Bahama/SM
+Bahamanian
+Bahamas/M
+Bahamian/MS
+Bahia/M
+Bahrain/M
+Baidu/M
+Baikal/M
+Bailey/M
+Baird/M
+Bakelite/M
+Baker/M
+Bakersfield/M
+Baku/M
+Bakunin/M
+Balanchine/M
+Balaton/M
+Balboa/M
+Balder/M
+Baldwin/SM
+Balearic/M
+Balfour/M
+Bali/M
+Balinese/M
+Balkan/MS
+Balkans/M
+Balkhash/M
+Ball/M
+Ballard/M
+Balthazar/M
+Baltic/M
+Baltimore/M
+Baluchistan/M
+Balzac/M
+Bamako/M
+Bambi/M
+Banach/M
+Bancroft/M
+Bandung/M
+Bangalore/M
+Bangkok/M
+Bangladesh/M
+Bangladeshi/SM
+Bangor/M
+Bangui/M
+Banjarmasin/M
+Banjul/M
+Banks/M
+Banneker/M
+Bannister/M
+Banting/M
+Bantu/MS
+Baotou/M
+Baptist/SM
+Baptiste/M
+Barabbas/M
+Barack/M
+Barbadian/SM
+Barbados/M
+Barbara/M
+Barbarella/M
+Barbarossa/M
+Barbary/M
+Barber/M
+Barbie/M
+Barbour/M
+Barbra/M
+Barbuda/M
+Barcelona/M
+Barceloneta/M
+Barclay/SM
+Barclays/M
+Bardeen/M
+Barents/M
+Barker/M
+Barkley/M
+Barlow/M
+Barnabas/M
+Barnaby/M
+Barnard/M
+Barnaul/M
+Barnes/M
+Barnett/M
+Barney/M
+Barnum/M
+Baroda/M
+Barquisimeto/M
+Barr/M
+Barranquilla/M
+Barrera/M
+Barrett/M
+Barrie/M
+Barron/M
+Barry/M
+Barrymore/M
+Bart/M
+Barth/MS
+Bartholdi/M
+Bartholomew/M
+Bartlett/M
+Bartok/M
+Barton/M
+Bart坦k/M
+Baruch/M
+Baryshnikov/M
+Basel/M
+Basho/M
+Basic
+Basie/M
+Basil/M
+Basque/MS
+Basra/M
+Bass/M
+Basseterre/M
+Bastille/M
+Basutoland/M
+Bataan/M
+Bates/M
+Bathsheba/M
+Batista/M
+Batman/M
+Battle/M
+Batu/M
+Baudelaire/M
+Baudouin/M
+Baudrillard/M
+Bauer/M
+Bauhaus/M
+Baum/M
+Bavaria/M
+Bavarian/M
+Baxter/M
+Bayamon
+Bayer/M
+Bayes/M
+Bayesian/M
+Bayeux/M
+Baylor/M
+Bayonne/M
+Bayreuth/M
+Baywatch/M
+Be/MH
+Beach/M
+Beadle/M
+Bean/M
+Beard/M
+Beardmore/M
+Beardsley/M
+Bearnaise/M
+Beasley/M
+Beatlemania/M
+Beatles/M
+Beatrice/M
+Beatrix/M
+Beatriz/M
+Beatty/M
+Beau/M
+Beaufort/M
+Beaujolais/M
+Beaumarchais/M
+Beaumont/M
+Beauregard/M
+Beauvoir/M
+Bechtel/M
+Beck/MR
+Becker/M
+Becket/M
+Beckett/M
+Beckley/M
+Beckman
+Becky/M
+Becquerel/M
+Bede/M
+Bedouin/SM
+Beebe/M
+Beecher/M
+Beefaroni/M
+Beelzebub/M
+Beerbohm/M
+Beethoven/M
+Beeton/M
+Begin/M
+Behan/M
+Behring/M
+Beiderbecke/M
+Beijing/M
+Beirut/M
+Bekesy/M
+Bela/M
+Belarus/M
+Belarusian
+Belau/M
+Belem/M
+Belfast/M
+Belg
+Belgian/SM
+Belgium/M
+Belgrade/M
+Belinda/M
+Belize/M
+Bell/M
+Bella/M
+Bellamy/M
+Bellatrix/M
+Belleek/M
+Bellingham/M
+Bellini/M
+Bellow/M
+Belmont/M
+Belmopan/M
+Beloit/M
+Belorussian/MS
+Belshazzar/M
+Beltane/M
+Belushi/M
+Ben/M
+Benacerraf/M
+Benares/M
+Benchley/M
+Bend/MR
+Bender/M
+Bendictus
+Bendix/M
+Benedict/M
+Benedictine/MS
+Benelux/M
+Benet/M
+Benetton/M
+Bengal/SM
+Bengali/M
+Benghazi/M
+Benin/M
+Beninese/M
+Benita/M
+Benito/M
+Benjamin/M
+Bennett/M
+Bennie/M
+Benny/M
+Benson/M
+Bentham/M
+Bentley/M
+Benton/M
+Benz/M
+Benzedrine/M
+Beowulf/M
+Berber/SM
+Berenice/M
+Beretta/M
+Berg/MNR
+Bergen/M
+Berger/M
+Bergerac/M
+Bergman/M
+Bergson/M
+Beria/M
+Bering/M
+Berkeley/M
+Berkshire/SM
+Berkshires/M
+Berle/M
+Berlin/SZMR
+Berliner/M
+Berlioz/M
+Berlitz/M
+Bermuda/SM
+Bermudan/SM
+Bermudian/SM
+Bern/M
+Bernadette/M
+Bernadine/M
+Bernanke/M
+Bernard/M
+Bernardo/M
+Bernays/M
+Bernbach/M
+Bernese
+Bernhardt/M
+Bernice/M
+Bernie/M
+Bernini/M
+Bernoulli/M
+Bernstein/M
+Berra/M
+Berry/M
+Bert/M
+Berta/M
+Bertelsmann/M
+Bertha/M
+Bertie/M
+Bertillon/M
+Bertram/M
+Bertrand/M
+Berwick/M
+Beryl/M
+Berzelius/M
+Bess/M
+Bessel/M
+Bessemer/M
+Bessie/M
+Best/M
+Betelgeuse/M
+Beth/M
+Bethany/M
+Bethe/M
+Bethesda/M
+Bethlehem/M
+Bethune/M
+Betsy/M
+Bette/M
+Bettie/M
+Betty/M
+Bettye/M
+Beulah/M
+Beveridge
+Beverley/M
+Beverly/M
+Beyer/M
+Bharat/M
+Bhopal/M
+Bhutan/M
+Bhutanese/M
+Bhutto/M
+Bi/M
+Bialystok/M
+Bianca/M
+Bib
+Bible/MS
+Biblical/M
+Bic/M
+Biddle/M
+Biden/M
+Bierce/M
+BigQuery/M
+Bigfoot/M
+Biggles/M
+Biko/M
+Bilbao/M
+Bilbo/M
+Bill/MJ
+Billie/M
+Billings/M
+Billy/M
+Bimini/M
+Binghamton/M
+Biogen/M
+Bioko/M
+Bird/M
+Birdseye/M
+Birkenstock/M
+Birmingham/M
+Biro/M
+Biscay/M
+Biscayne/M
+Bishkek/M
+Bishop/M
+Bismarck/M
+Bismark/M
+Bisquick/M
+Bissau/M
+BitTorrent/M
+Bizet/M
+Bjerknes/M
+Bjork/M
+Bk/M
+Black/MS
+BlackBerry/M
+Blackbeard/M
+Blackburn/M
+Blackfeet/M
+Blackfoot/M
+Blackpool/M
+Blacksburg/M
+Blackshirt/M
+Blackstone/M
+Blackwell/M
+Blaine/M
+Blair/M
+Blake/M
+Blanca/M
+Blanchard/M
+Blanche/M
+Blankenship/M
+Blantyre/M
+Blatz/M
+Blavatsky/M
+Blenheim/M
+Blevins/M
+Bligh/M
+Bloch/M
+Blockbuster/M
+Bloemfontein/M
+Blondel/M
+Blondie/M
+Bloom/MR
+Bloomer/M
+Bloomfield/M
+Bloomingdale/M
+Bloomington/M
+Bloomsburg/M
+Bloomsbury/M
+Blu
+Blucher/M
+Bluebeard/M
+Bluetooth/M
+Blvd
+Blythe/M
+Boadicea
+Boas/M
+Bob/M
+Bobbi/M
+Bobbie/M
+Bobbitt/M
+Bobby/M
+Boccaccio/M
+Bodhidharma/M
+Bodhisattva/M
+Bodleian
+Boeing/M
+Boeotia/M
+Boeotian/M
+Boer/SM
+Boethius/M
+Bogart/M
+Bogota/M
+Bogot叩/M
+Bohemia/M
+Bohemian/SM
+Bohr/M
+Boise/M
+Bojangles/M
+Boleyn/M
+Bolivar/M
+Bolivia/M
+Bolivian/MS
+Bollywood/M
+Bologna/M
+Bolshevik/SM
+Bolsheviki
+Bolshevism/M
+Bolshevist/M
+Bolshoi/M
+Bolton/M
+Boltzmann/M
+Bombay/M
+Bonaparte/M
+Bonaventure/M
+Bond/M
+Bonhoeffer/M
+Boniface/M
+Bonita/M
+Bonn/MR
+Bonner/M
+Bonneville/M
+Bonnie/M
+Bono/M
+Booker/M
+Boole/M
+Boolean/M
+Boone/M
+Bootes/M
+Booth/M
+Bordeaux/M
+Borden/M
+Bordon/M
+Boreas/M
+Borg/SM
+Borges/M
+Borgia/M
+Borglum/M
+Boris/M
+Bork/M
+Borlaug/M
+Born/M
+Borneo/M
+Borobudur/M
+Borodin/M
+Boru/M
+Bosch/M
+Bose/M
+Bosnia/M
+Bosnian
+Bosporus/M
+Boston/MS
+Bostonian/M
+Boswell/M
+Botha
+Botox
+Botswana/M
+Botticelli/M
+Boulder/M
+Boulez/M
+Bourbaki/M
+Bourbon/SM
+Bournemouth/M
+Bovary/M
+Bowditch/M
+Bowell/M
+Bowen/M
+Bowers/M
+Bowery/M
+Bowie/M
+Bowman/M
+Boyd/M
+Boyer/M
+Boyle/M
+Bo旦tes/M
+Br/MT
+Brad/MY
+Bradbury/M
+Braddock/M
+Bradenton/M
+Bradford/M
+Bradley/M
+Bradly/M
+Bradshaw/M
+Bradstreet/M
+Brady/M
+Bragg/M
+Brahe/M
+Brahma/MS
+Brahmagupta/M
+Brahman/MS
+Brahmani
+Brahmanism/SM
+Brahmaputra/M
+Brahms/M
+Braille/MS
+Brain/M
+Brampton/M
+Bran/M
+Branch/M
+Brandeis/M
+Branden/M
+Brandenburg/M
+Brandi/M
+Brandie/M
+Brando/M
+Brandon/M
+Brandt/M
+Brandy/M
+Brant/M
+Braque/M
+Brasilia/M
+Bratislava/M
+Brattain/M
+Bray/M
+Brazil/M
+Brazilian/MS
+Brazos/M
+Brazzaville/M
+Breakspear/M
+Breathalyzer
+Brecht/M
+Breckenridge/M
+Bremen/M
+Bremerton/M
+Brenda/M
+Brendan/M
+Brennan/M
+Brenner/M
+Brent/M
+Brenton/M
+Brest/M
+Bret/M
+Breton/M
+Brett/M
+Brewer/M
+Brewster/M
+Brexit
+Brezhnev/M
+Brian/M
+Briana/M
+Brianna/M
+Brice/M
+Bridalveil/M
+Bridgeport/M
+Bridger/M
+Bridges/M
+Bridget/M
+Bridgetown/M
+Bridgett/M
+Bridgette/M
+Bridgman/M
+Brie/SM
+Brigadoon/M
+Briggs/M
+Brigham/M
+Bright/M
+Brighton/M
+Brigid/M
+Brigitte/M
+Brillo/M
+Brillouin
+Brinkley/M
+Brisbane/M
+Bristol/M
+Brit/SM
+Britain/M
+Britannia/M
+Britannic/M
+Britannica/M
+Briticism/SM
+British/MRZ
+Britisher/M
+Britney/M
+Briton/MS
+Britt/MN
+Brittany/SM
+Britten/M
+Brittney/M
+Brno/M
+Broadway/SM
+Brobdingnag/M
+Brobdingnagian/M
+Brock/M
+Brokaw/M
+Bronson/M
+Bronte/M
+Brontosaurus
+Bronx/M
+Brooke/MS
+Brooklyn/M
+Brooks/M
+Bros
+Brown/MG
+Browne/M
+Brownian/M
+Brownie/S
+Browning/M
+Brownshirt/M
+Brownsville/M
+Brubeck/M
+Bruce/M
+Bruckner/M
+Bruegel
+Brummel/M
+Brunei/M
+Bruneian/MS
+Brunelleschi/M
+Brunhilde/M
+Bruno/M
+Brunswick/M
+Brussels/M
+Brut/M
+Brutus/M
+Bryan/M
+Bryant/M
+Bryce/M
+Brynner/M
+Bryon/M
+Brzezinski/M
+Btu/M
+Buber/M
+Buchanan/M
+Bucharest/M
+Buchenwald/M
+Buchwald/M
+Buck/M
+Buckingham/M
+Buckley/M
+Buckner/M
+Bud/M
+Budapest/M
+Buddha/SM
+Buddhism/SM
+Buddhist/SM
+Buddy/M
+Budweiser/M
+Buffalo/M
+Buffy/M
+Buford/M
+Bugatti/M
+Bugzilla/M
+Buick/M
+Bujumbura/M
+Bukhara/M
+Bukharin/M
+Bulawayo/M
+Bulfinch/M
+Bulganin/M
+Bulgar/M
+Bulgari/M
+Bulgaria/M
+Bulgarian/SM
+Bullock/M
+Bullwinkle/M
+Bultmann/M
+Bumppo/M
+Bunche/M
+Bundesbank/M
+Bundestag/M
+Bunin/M
+Bunker/M
+Bunsen/M
+Bunuel/M
+Bunyan/M
+Burbank/M
+Burberry/M
+Burch/M
+Burger/M
+Burgess/M
+Burgoyne/M
+Burgundian/M
+Burgundy/SM
+Burke/M
+Burks/M
+Burl/M
+Burlington/M
+Burma/M
+Burmese/M
+Burnett/M
+Burns/M
+Burnside/M
+Burr/M
+Burris/M
+Burroughs/M
+Bursa/M
+Burt/M
+Burton/M
+Burundi/M
+Burundian/MS
+Busch/M
+Bush/M
+Bushido/M
+Bushnell/M
+Butler/M
+Butterfingers/M
+Buxtehude/M
+Bu単uel/M
+Byblos/M
+Byers/M
+Byrd/M
+Byron/M
+Byronic/M
+Byzantine/MS
+Byzantium/M
+C/SM
+CA
+CAD/M
+CAI
+CAM
+CAP
+CARE
+CATV
+CB
+CBC/M
+CBS/M
+CCTV
+CCU
+CD/SM
+CDC
+CDT
+CEO/M
+CF
+CFC/M
+CFO
+CGI
+CIA/M
+CID
+CNN/M
+CNS/M
+CO/M
+COBOL/SM
+COD
+COL
+COLA
+COVID
+CPA/M
+CPI/M
+CPO
+CPR/M
+CPU/M
+CRT/SM
+CSS/M
+CST/M
+CT/M
+CV
+CVS/M
+CZ
+Ca/M
+Cabernet/M
+Cabot/M
+Cabral/M
+Cabrera/M
+Cabrini/M
+Cadette
+Cadillac/M
+Cadiz/M
+Caedmon/M
+Caerphilly/M
+Caesar/SM
+Cage/M
+Cagney/M
+Cahokia/M
+Caiaphas/M
+Cain/SM
+Cairo/M
+Caitlin/M
+Cajun/MS
+Cal/M
+Calais/M
+Calcutta/M
+Calder/M
+Calderon/M
+Caldwell/M
+Caleb/M
+Caledonia/M
+Calexico/M
+Calgary/M
+Calhoun/M
+Cali/M
+Caliban/M
+Calif
+California/M
+Californian/SM
+Caligula/M
+Callaghan/M
+Callahan/M
+Callao/M
+Callas/M
+Callie/M
+Calliope/M
+Callisto/M
+Caloocan/M
+Calvary/M
+Calvert/M
+Calvin/M
+Calvinism/MS
+Calvinist/MS
+Calvinistic
+Camacho/M
+Camarillo/M
+Cambodia/M
+Cambodian/SM
+Cambrian/SM
+Cambridge/M
+Camden/M
+Camel/M
+Camelopardalis/M
+Camelot/MS
+Camembert/MS
+Cameron/M
+Cameroon/SM
+Cameroonian/MS
+Camilla/M
+Camille/M
+Camoens/M
+Campanella/M
+Campbell/M
+Campinas/M
+Campos/M
+Camry/M
+Camus/M
+Can/M
+Canaan/M
+Canaanite/MS
+Canad
+Canada/M
+Canadian/SM
+Canadianism
+Canaletto/M
+Canaries/M
+Canaveral/M
+Canberra/M
+Cancer/SM
+Cancun/M
+Candace/M
+Candice/M
+Candide/M
+Candy/M
+Cannes/M
+Cannon/M
+Canon/M
+Canopus/M
+Cantabrigian/M
+Canterbury/M
+Canton/M
+Cantonese/M
+Cantor/M
+Cantrell/M
+Cantu/M
+Canute/M
+Capablanca/M
+Capek/M
+Capella/M
+Capet/M
+Capetian/M
+Capetown/M
+Caph/M
+Capistrano/M
+Capitol/SM
+Capitoline/M
+Capone/M
+Capote/M
+Capra/M
+Capri/M
+Capricorn/MS
+Capt
+Capuchin/M
+Capulet/M
+Cara/M
+Caracalla/M
+Caracas/M
+Caravaggio/M
+Carboloy/M
+Carbondale/M
+Carboniferous/M
+Carborundum/M
+Cardenas/M
+Cardiff/M
+Cardin/M
+Cardozo/M
+Carey/M
+Carib/MS
+Caribbean/MS
+Carina/M
+Carissa/M
+Carl/M
+Carla/M
+Carlene/M
+Carlin/M
+Carlo/MS
+Carlos/M
+Carlsbad/M
+Carlson/M
+Carlton/M
+Carly/M
+Carlyle/M
+Carmela/M
+Carmella/M
+Carmelo/M
+Carmen/M
+Carmichael/M
+Carmine/M
+Carnap/M
+Carnation/M
+Carnegie/M
+Carney/M
+Carnot/M
+Carol/M
+Carole/M
+Carolina/M
+Caroline/M
+Carolingian/M
+Carolinian/M
+Carolyn/M
+Carpathian/SM
+Carpathians/M
+Carpenter/M
+Carr/M
+Carranza/M
+Carrie/RM
+Carrier/M
+Carrillo/M
+Carroll/M
+Carson/M
+Carter/M
+Cartersville/M
+Cartesian/M
+Carthage/M
+Carthaginian/MS
+Cartier/M
+Cartwright/M
+Caruso/M
+Carver/M
+Cary/M
+Casablanca/M
+Casals/M
+Casandra/M
+Casanova/SM
+Cascades/M
+Case/M
+Casey/M
+Cash/M
+Casio/M
+Caspar/M
+Casper/M
+Caspian/M
+Cassandra/SM
+Cassatt/M
+Cassidy/M
+Cassie/M
+Cassiopeia/M
+Cassius/M
+Castaneda/M
+Castile/M
+Castilian
+Castillo/M
+Castlereagh/M
+Castor/M
+Castries/M
+Castro/M
+Catalan/SM
+Catalina/M
+Catalonia/M
+Catawba/M
+Caterpillar/M
+Cathay/M
+Cather/M
+Catherine/M
+Cathleen/M
+Catholic/MS
+Catholicism/MS
+Cathryn/M
+Cathy/M
+Catiline/M
+Cato/M
+Catskill/SM
+Catskills/M
+Catt/M
+Catullus/M
+Caucasian/MS
+Caucasoid
+Caucasus/M
+Cauchy/M
+Cavendish/M
+Cavour/M
+Caxton/M
+Cayenne/M
+Cayman/M
+Cayuga/SM
+Cayuse
+Cb
+Cd/M
+Ce/M
+Ceausescu/M
+Cebu/M
+Cebuano/M
+Cecelia/M
+Cecil/M
+Cecile/M
+Cecilia/M
+Cecily/M
+Cedric/M
+Celebes/M
+Celeste/M
+Celgene/M
+Celia/M
+Celina/M
+Cellini/M
+Celsius/M
+Celt/SM
+Celtic/SM
+Cenozoic/M
+Centaurus/M
+Centigrade
+Central
+Cepheid/M
+Cepheus/M
+Cerberus/M
+Cerenkov/M
+Ceres/M
+Cerf/M
+Cervantes/M
+Cesar/M
+Cesarean/M
+Cessna/M
+Cetus/M
+Ceylon/M
+Ceylonese
+Cezanne/M
+Cf/M
+Ch'in/M
+Ch/N
+Chablis/M
+Chad/M
+Chadian/MS
+Chadwick/M
+Chagall/M
+Chaitanya/M
+Chaitin/M
+Chaldea
+Chaldean/M
+Challenger/M
+Chalmers
+Chamberlain/M
+Chambers/M
+Chambersburg/M
+Champaign/M
+Champlain/M
+Champollion/M
+Chan/M
+Chance/M
+Chancellorsville/M
+Chandigarh/M
+Chandler/M
+Chandon/M
+Chandra/M
+Chandragupta/M
+Chandrasekhar/M
+Chanel/M
+Chaney/M
+Chang/M
+Changchun/M
+Changsha/M
+Chantilly/M
+Chaplin/M
+Chaplinesque
+Chapman/M
+Chappaquiddick/M
+Chapultepec/M
+Charbray/M
+Chardonnay/M
+Charity/M
+Charlemagne/M
+Charlene/M
+Charles/M
+Charleston/MS
+Charley/M
+Charlie/M
+Charlotte/M
+Charlottesville/M
+Charlottetown/M
+Charmaine/M
+Charmin/M
+Charolais/M
+Charon/M
+Chartism/M
+Chartres/M
+Charybdis/M
+Chase/M
+Chasity/M
+Chateaubriand/M
+Chattahoochee/M
+Chattanooga/M
+Chatterley/M
+Chatterton/M
+Chaucer/M
+Chauncey/M
+Chautauqua/M
+Chavez/M
+Chayefsky/M
+Che/M
+Chechen/M
+Chechnya/M
+Cheddar/M
+Cheer/M
+Cheerios/M
+Cheetos/M
+Cheever/M
+Chekhov/M
+Chekhovian
+Chelsea/M
+Chelyabinsk/M
+Chen/M
+Cheney/M
+Chengdu/M
+Chennai/M
+Cheops/M
+Cheri/M
+Cherie/M
+Chernenko/M
+Chernobyl/M
+Chernomyrdin/M
+Cherokee/MS
+Cherry/M
+Cheryl/M
+Chesapeake/M
+Cheshire/M
+Chester/M
+Chesterfield/M
+Chesterton/M
+Chevalier/M
+Cheviot/M
+Chevrolet/M
+Chevron/M
+Chevy/M
+Cheyenne/SM
+Chi/M
+Chianti/MS
+Chiba/M
+Chibcha/M
+Chicago/M
+Chicagoan/M
+Chicana/M
+Chicano/M
+Chickasaw/MS
+Chiclets/M
+Chico/M
+Chihuahua/MS
+Chile/M
+Chilean/MS
+Chimborazo/M
+Chimera/MS
+Chimu/M
+Chin/M
+China/M
+Chinatown/M
+Chinese/M
+Chinook/MS
+Chipewyan/M
+Chippendale/M
+Chippewa/SM
+Chiquita/M
+Chirico/M
+Chisholm/M
+Chisinau/M
+Chittagong/M
+Chivas/M
+Chloe/M
+Choctaw/SM
+Chomsky/M
+Chongqing/M
+Chopin/M
+Chopra/M
+Chou/M
+Chretien/M
+Chris/M
+Christ/MS
+Christa/M
+Christchurch/M
+Christendom/MS
+Christensen/M
+Christi/M
+Christian/SM
+Christianity/SM
+Christianize
+Christie/M
+Christina/M
+Christine/M
+Christlike
+Christmas/MS
+Christmastide/MS
+Christmastime/MS
+Christoper/M
+Christopher/M
+Chromebook/MS
+Chronicles
+Chrysler/M
+Chrysostom/M
+Chrystal/M
+Chuck/M
+Chukchi/M
+Chumash/M
+Chung/M
+Church/M
+Churchill/M
+Churriguera/M
+Chuvash/M
+Ci/M
+Cicero/M
+Cid/M
+Cimabue/M
+Cincinnati/M
+Cinderella/MS
+Cindy/M
+CinemaScope/M
+Cinerama/M
+Cipro/M
+Circe/M
+Cisco/M
+Citibank/M
+Citigroup/M
+Citroen/M
+Cl/MV
+Claiborne/M
+Clair/M
+Claire/M
+Clairol/M
+Clancy/M
+Clapeyron/M
+Clapton/M
+Clara/M
+Clare/M
+Clarence/M
+Clarendon/M
+Clarice/M
+Clarissa/M
+Clark/M
+Clarke/M
+Clarksville/M
+Claude/M
+Claudette/M
+Claudia/M
+Claudine/M
+Claudio/M
+Claudius/M
+Claus/M
+Clausewitz/M
+Clausius/M
+Clay/M
+Clayton/M
+Clearasil/M
+Clem/XM
+Clemenceau/M
+Clemens/M
+Clement/MS
+Clementine/M
+Clements/M
+Clemons/M
+Clemson/M
+Cleo/M
+Cleopatra/M
+Cleveland/M
+Cliburn/M
+Cliff/M
+Clifford/M
+Clifton/M
+Cline/M
+Clint/M
+Clinton/M
+Clio/M
+Clive/M
+Clojure/M
+Clorets/M
+Clorox/M
+Closure/M
+Clotho/M
+Clouseau/M
+Clovis/M
+Clyde/M
+Clydesdale/M
+Clytemnestra/M
+Cm/M
+Cmdr
+Co/M
+Cobain/M
+Cobb/M
+Cochabamba/M
+Cochin/M
+Cochise/M
+Cochran/M
+Cockney/M
+Cocteau/M
+Cod
+Cody/M
+Coffey/M
+Cognac/M
+Cohan/M
+Cohen/M
+Coimbatore/M
+Cointreau/M
+Coke/SM
+Col/M
+Colbert/M
+Colby/M
+Cole/M
+Coleen/M
+Coleman/M
+Coleridge/M
+Colette/M
+Colfax/M
+Colgate/M
+Colin/M
+Colleen/M
+Collier/M
+Collin/SM
+Collins/M
+Colo
+Cologne/M
+Colombia/M
+Colombian/MS
+Colombo/M
+Colon/M
+Coloradan/SM
+Colorado/M
+Coloradoan
+Colosseum/M
+Colt/M
+Coltrane/M
+Columbia/M
+Columbine/M
+Columbus/M
+Com
+Comanche/MS
+Combs/M
+Comdr
+Comintern/M
+Commandment
+Commons/M
+Commonwealth
+Communion/SM
+Communism
+Communist/SM
+Como/M
+Comoran
+Comoros/M
+Compaq/M
+Compton/M
+CompuServe/M
+Comte/M
+Conakry/M
+Conan/M
+Concepcion/M
+Concepci坦n/M
+Concetta/M
+Concord/SM
+Concorde/M
+Condillac/M
+Condorcet/M
+Conestoga/M
+Confederacy/M
+Confederate/MS
+Confucian/SM
+Confucianism/MS
+Confucius/M
+Cong/M
+Congo/M
+Congolese/M
+Congregational
+Congregationalist/MS
+Congress/MS
+Congressional
+Congreve/M
+Conley/M
+Conn/MR
+Connecticut/M
+Connellsville/M
+Connemara/M
+Conner/M
+Connery/M
+Connie/M
+Connolly/M
+Connors/M
+Conrad/M
+Conrail/M
+Conroe/M
+Conservative
+Constable/M
+Constance/M
+Constantine/M
+Constantinople/M
+Constitution
+Consuelo/M
+Continent/M
+Continental/M
+Contreras/M
+Conway/M
+Cook/M
+Cooke/M
+Cooley/M
+Coolidge/M
+Cooper/M
+Cooperstown/M
+Coors/M
+Copacabana/M
+Copeland/M
+Copenhagen/M
+Copernican/M
+Copernicus/M
+Copland/M
+Copley/M
+Copperfield/M
+Coppertone/M
+Coppola/M
+Coptic/M
+Cora/M
+Cordelia/M
+Cordilleras/M
+Cordoba/M
+Corey/M
+Corfu/M
+Corina/M
+Corine/M
+Corinne/M
+Corinth/M
+Corinthian/MS
+Corinthians/M
+Coriolanus/M
+Coriolis/M
+Cork
+Corleone/M
+Cormack/M
+Corneille/M
+Cornelia/M
+Cornelius/M
+Cornell/M
+Corning/M
+Cornish/MS
+Cornwall/M
+Cornwallis/M
+Coronado/M
+Corot/M
+Corp
+Correggio/M
+Corrine/M
+Corsica/M
+Corsican/M
+Cortes/MS
+Cortland/M
+Corvallis/M
+Corvette/M
+Corvus/M
+Cory/M
+Cosby/M
+CosmosDB/M
+Cossack/M
+Costco/M
+Costello/M
+Costner/M
+Cote/M
+Cotonou/M
+Cotopaxi/M
+Cotswold/M
+Cotton/M
+Coulomb/M
+Coulter/M
+Couperin/M
+Courbet/M
+Courtney/M
+Cousteau/M
+Coventry/SM
+Covington/M
+Coward/M
+Cowell/M
+Cowley/M
+Cowper/M
+Cox/M
+Coy/M
+Coyle/M
+Cozumel/M
+Cpl
+Cr/MT
+Crabbe/M
+Craft/M
+Craig/M
+Cranach/M
+Crane/M
+Cranmer/M
+Crater/M
+Crawford/M
+Cray/M
+Crayola/M
+Creation/M
+Creator/M
+Crecy/M
+Cree/DSM
+Creek/SM
+Creighton/M
+Creole/SM
+Creon/M
+Cressida/M
+Crest/M
+Cretaceous/M
+Cretan/SM
+Crete/M
+Crichton/M
+Crick/M
+Crimea/M
+Crimean/M
+Criollo/M
+Crisco/M
+Cristina/M
+Croat/SM
+Croatia/M
+Croatian/MS
+Croce/M
+Crockett/M
+Croesus/M
+Cromwell/M
+Cromwellian/M
+Cronin/M
+Cronkite/M
+Cronus/M
+Crookes/M
+Crosby/M
+Cross/M
+Crow/SM
+Crowley/M
+Crucifixion/MS
+Cruikshank/M
+Cruise/M
+Crusades's
+Crusoe/M
+Crux/M
+Cruz/M
+Cryptozoic/M
+Crystal/M
+Csonka/M
+Ct
+Ctesiphon/M
+Cthulhu/M
+Cu/M
+Cuba/M
+Cuban/SM
+Cuchulain/M
+Cuisinart/M
+Culbertson/M
+Cullen/M
+Cumberland/M
+Cummings/M
+Cunard/M
+Cunningham/M
+Cupid/M
+Curacao/M
+Curie/M
+Curitiba/M
+Currier/M
+Curry/RM
+Curt/M
+Curtis/M
+Custer/M
+Cuvier/M
+Cuzco/M
+Cybele/M
+Cyclades/M
+Cyclopes/M
+Cyclops/M
+Cygnus/M
+Cymbeline/M
+Cynthia/M
+Cyprian/M
+Cypriot/MS
+Cyprus/M
+Cyrano/M
+Cyril/M
+Cyrillic/M
+Cyrus/M
+Czech/M
+Czechia/M
+Czechoslovak
+Czechoslovakia/M
+Czechoslovakian/SM
+Czechs
+Czerny/M
+D/M
+DA/M
+DAR
+DAT/M
+DBMS/M
+DC/M
+DD/M
+DDS/M
+DDT/S
+DE
+DEA
+DEC/SD
+DH
+DHS
+DI
+DJ
+DMCA
+DMD/M
+DMZ
+DNA/M
+DOA
+DOB
+DOD
+DOE
+DOS/M
+DOT
+DP/SM
+DPT
+DST
+DTP
+DUI
+DVD/S
+DVR/SM
+DWI
+Dachau/M
+Dacron/SM
+Dada/M
+Dadaism/M
+Daedalus/M
+Daguerre/M
+Dagwood/M
+Dahomey/M
+Daimler/M
+Daisy/M
+Dakar/M
+Dakota/SM
+Dakotan/M
+Dalai
+Dale/M
+Daley/M
+Dali/M
+Dalian/M
+Dallas/M
+Dalmatia/M
+Dalmatian/SM
+Dalton/M
+Damascus/M
+Dame/MN
+Damian/M
+Damien/M
+Damion/M
+Damocles/M
+Damon/M
+Dan/M
+Dana/M
+Danae/M
+Dana谷/M
+Danbury/M
+Dane/SM
+Danelaw/M
+Dangerfield/M
+Danial/M
+Daniel/SM
+Danielle/M
+Daniels/M
+Danish/M
+Dannie/M
+Danny/M
+Danone/M
+Dante/M
+Danton/M
+Danube/M
+Danubian/M
+Danville/M
+Daphne/M
+Darby/M
+Darcy/M
+Dardanelles/M
+Dare/M
+Daren/M
+Darfur/M
+Darin/M
+Dario/M
+Darius/M
+Darjeeling/M
+Darla/M
+Darlene/M
+Darling/M
+Darnell/M
+Darrel/M
+Darrell/M
+Darren/M
+Darrin/M
+Darrow/M
+Darryl/M
+Darth/M
+Dartmoor/M
+Dartmouth/M
+Darvon/M
+Darwin/M
+Darwinian/M
+Darwinism/SM
+Darwinist
+Daryl/M
+Datamation
+Daugherty/M
+Daumier/M
+Davao/M
+Dave/M
+Davenport/M
+David/MS
+Davidson/M
+Davies/M
+Davis/M
+Davy/SM
+Dawes/M
+Dawkins
+Dawn/M
+Dawson/M
+Day/M
+Dayan
+Dayton/M
+DeGeneres/M
+DeKalb/M
+Deadhead/M
+Dean/M
+Deana/M
+Deandre/M
+Deann/M
+Deanna/M
+Deanne/M
+Death/M
+Debbie/M
+Debby/M
+Debian/M
+Debora/M
+Deborah/M
+Debouillet/M
+Debra/M
+Debs/M
+Debussy/M
+Dec/M
+Decalogue/M
+Decatur/M
+Decca/M
+Deccan/M
+December/SM
+Decker/M
+Dedekind/M
+Dee/M
+Deena/M
+Deere/M
+Defoe/M
+Degas/M
+Deidre/M
+Deimos/M
+Deirdre/M
+Deity
+Dejesus/M
+Del/M
+Delacroix/M
+Delacruz/M
+Delaney/M
+Delano/M
+Delaware/MS
+Delawarean/SM
+Delbert/M
+Deleon/M
+Delgado/M
+Delhi/M
+Delia/M
+Delibes/M
+Delicious/M
+Delilah/M
+Delilahs
+Delius/M
+Dell/M
+Della/M
+Delmar/M
+Delmarva/M
+Delmer/M
+Delmonico/M
+Delores/M
+Deloris/M
+Delphi/M
+Delphic/M
+Delphinus/M
+Delta/M
+Deltona/M
+Dem/G
+Demavend/M
+Demerol/M
+Demeter/M
+Demetrius/M
+Deming/M
+Democrat/SM
+Democratic
+Democritus/M
+Demosthenes/M
+Dempsey/M
+Dena/M
+Denali
+Deneb/M
+Denebola/M
+Deng/M
+Denis/M
+Denise/M
+Denmark/M
+Dennis/M
+Denny/M
+Denton/M
+Denver/M
+Deon/M
+Depp/M
+Derby/M
+Derek/M
+Derick/M
+Dermot/M
+Derrick/M
+Derrida/M
+Descartes/M
+Desdemona/M
+Desiree/M
+Desmond/M
+Detroit/M
+Deuteronomy/M
+Deutschmark/SM
+Devanagari/M
+Devi/M
+Devil/M
+Devin/M
+Devon/M
+Devonian/M
+Dewar/M
+Dewayne/M
+Dewey/M
+Dewitt/M
+Dexedrine/M
+Dexter/M
+Dhaka/M
+Dhaulagiri/M
+Di/SM
+DiCaprio/M
+DiMaggio/M
+Diaghilev/M
+Dial/M
+Diana/M
+Diane/M
+Diann/M
+Dianna/M
+Dianne/M
+Dias
+Diaspora/MS
+Dick/XM
+Dickens/M
+Dickensian
+Dickerson/M
+Dickinson/M
+Dickson/M
+Dictaphone/SM
+Diderot/M
+Dido/M
+Didrikson/M
+Diefenbaker/M
+Diego/M
+Diem/M
+Dietrich/M
+Dijkstra/M
+Dijon/M
+Dilbert/MS
+Dillard/M
+Dillinger/M
+Dillon/M
+Dina/M
+Dinah/M
+Dino/M
+Diocletian/M
+Diogenes/M
+Dion/M
+Dionne/M
+Dionysian/M
+Dionysus/M
+Diophantine/M
+Dior/M
+Dipper/M
+Dir
+Dirac/M
+Dirichlet/M
+Dirk/M
+Dis/M
+Disney/M
+Disneyland/M
+Disraeli/M
+Divine/M
+Diwali/M
+Dix/M
+Dixie/M
+Dixiecrat/M
+Dixieland/SM
+Dixon/M
+Django/M
+Djibouti/M
+Dmitri/M
+Dnepr
+Dnepropetrovsk/M
+Dnieper/M
+Dniester/M
+Dobbin/M
+Doberman/M
+Dobro/M
+Doctor
+Doctorow/M
+Dodge/M
+Dodgson/M
+Dodoma/M
+Dodson/M
+Doe/M
+Doha/M
+Dolby/M
+Dole/M
+Dollie/M
+Dolly/M
+Dolores/M
+Domesday/M
+Domingo/M
+Dominguez/M
+Dominic/M
+Dominica/M
+Dominican/MS
+Dominick/M
+Dominion
+Dominique/M
+Domitian/M
+Don/SM
+Dona/M
+Donahue/M
+Donald/M
+Donaldson/M
+Donatello/M
+Donetsk/M
+Donizetti/M
+Donn/MR
+Donna/M
+Donne/M
+Donnell/M
+Donner/M
+Donnie/M
+Donny/M
+Donovan/M
+Dooley/M
+Doolittle/M
+Doonesbury/M
+Doppler/M
+Dora/M
+Dorcas/M
+Doreen/M
+Dorian/M
+Doric/M
+Doris/M
+Doritos/M
+Dorothea/M
+Dorothy/M
+Dorset/M
+Dorsey/M
+Dorthy/M
+Dortmund/M
+Dostoevsky/M
+Dot/M
+Dothan/M
+Dotson/M
+Douala/M
+Douay/M
+Doubleday/M
+Doug/M
+Douglas/M
+Douglass/M
+Douro/M
+Dover/M
+Dow/M
+Downs/M
+Downy/M
+Doyle/M
+Dr
+Draco/M
+Draconian/M
+Dracula/M
+Drake/M
+Dramamine/SM
+Drambuie/M
+Drano/M
+Dravidian/M
+Dreiser/M
+Dresden/M
+Drew/M
+Dreyfus/M
+Dristan/M
+Dropbox/M
+Drudge/M
+Druid/M
+Drupal/M
+Dryden/M
+Dschubba/M
+Du
+DuPont/M
+Duane/M
+Dubai/M
+Dubcek/M
+Dubhe/M
+Dublin/M
+Dubrovnik/M
+Dubuque/M
+Duchamp/M
+Dudley/M
+Duffy/M
+Duisburg/M
+Duke/M
+Dulles/M
+Duluth/M
+Dumas/M
+Dumbledore/M
+Dumbo/M
+Dunant/M
+Dunbar/M
+Duncan/M
+Dundee
+Dunedin/M
+Dunkirk/M
+Dunlap/M
+Dunn/M
+Dunne/M
+Duracell/M
+Duran/M
+Durant/M
+Durante/M
+Durban/M
+Durer/M
+Durex/M
+Durham/MS
+Durkheim/M
+Duroc/M
+Durocher/M
+Duse/M
+Dushanbe/M
+Dusseldorf/M
+Dustbuster/M
+Dustin/M
+Dusty/M
+Dutch/M
+Dutchman/M
+Dutchmen/M
+Dutchwoman
+Duvalier/M
+Dvina/M
+Dvorak/M
+Dvor叩k/M
+Dwayne/M
+Dwight/M
+Dy/M
+Dyer/M
+Dylan/M
+DynamoDB/M
+Dyson/M
+Dzerzhinsky/M
+Dzungaria/M
+D端rer/M
+D端sseldorf/M
+E/SM
+EC
+ECG/M
+ECMAScript/M
+EDP/M
+EDT
+EEC/M
+EEG/M
+EEO
+EEOC
+EFL
+EFT
+EKG/M
+ELF/M
+EM
+EMT
+ENE/M
+EOE
+EPA/M
+ER
+ERA
+ESE/M
+ESL
+ESP/M
+ESPN/M
+ESR
+EST/M
+ET
+ETA
+ETD
+EU
+EULA/S
+Eakins/M
+Earhart/M
+Earl/M
+Earle/M
+Earlene/M
+Earline/M
+Earnest/M
+Earnestine/M
+Earnhardt/M
+Earp/M
+East/SZMR
+Easter/M
+Eastern/R
+Eastman/M
+Eastwood/M
+Eaton/M
+Eben/M
+Ebeneezer/M
+Ebert/M
+Ebola/M
+Ebonics/M
+Ebony/M
+Ebro/M
+Ecclesiastes/M
+Eco/M
+Ecstasy
+Ecuador/M
+Ecuadoran/SM
+Ecuadorean
+Ecuadorian/SM
+Ed/MNX
+Edam/SM
+Edda/M
+Eddie/M
+Eddington/M
+Eddy/M
+Eden/M
+Edgar/M
+Edgardo/M
+Edinburgh/M
+Edison/M
+Edith/M
+Edmond/M
+Edmonton/M
+Edmund/M
+Edna/M
+Edsel/M
+Eduardo/M
+Edward/SM
+Edwardian/M
+Edwardo/M
+Edwards/M
+Edwin/M
+Edwina/M
+Eeyore/M
+Effie/M
+Efrain/M
+Efren/M
+Eggo/M
+Egypt/M
+Egyptian/MS
+Egyptology/M
+Ehrenberg/M
+Ehrlich/M
+Eichmann/M
+Eiffel/M
+Eileen/M
+Einstein/MS
+Eire/M
+Eisenhower/M
+Eisenstein/M
+Eisner/M
+Elaine/M
+Elam/M
+Elanor/M
+Elasticsearch/M
+Elastoplast/M
+Elba/M
+Elbe/M
+Elbert/M
+Elbrus/M
+Eldersburg/M
+Eldon/M
+Eleanor/M
+Eleazar/M
+Electra/M
+Elena/M
+Elgar/M
+Eli/M
+Elias/M
+Elijah/M
+Elinor/M
+Eliot/M
+Elisa/M
+Elisabeth/M
+Elise/M
+Eliseo/M
+Elisha/M
+Eliza/M
+Elizabeth/M
+Elizabethan/SM
+Elizabethtown/M
+Elkhart/M
+Ella/M
+Ellen/M
+Ellesmere/M
+Ellie/M
+Ellington/M
+Elliot/M
+Elliott/M
+Ellis/M
+Ellison/M
+Elma/M
+Elmer/M
+Elmira/M
+Elmo/M
+Elnath/M
+Elnora/M
+Elohim/M
+Eloise/M
+Eloy/M
+Elroy/M
+Elsa/M
+Elsie/M
+Elsinore/M
+Eltanin/M
+Elton/M
+Elul/M
+Elva/M
+Elvia/M
+Elvin/M
+Elvira/M
+Elvis/M
+Elway/M
+Elwood/M
+Elyria/M
+Elysee/M
+Elysian/M
+Elysium/SM
+Elys辿e/M
+Emacs/M
+Emanuel/M
+Emerson/M
+Emery/M
+Emil/M
+Emile/M
+Emilia/M
+Emilio/M
+Emily/M
+Eminem/M
+Eminence
+Emma/M
+Emmanuel/M
+Emmett/M
+Emmy/M
+Emory/M
+Encarta/M
+Endymion/M
+Eng/M
+Engels/M
+England/M
+English/MRS
+Englishman/M
+Englishmen/M
+Englishwoman/M
+Englishwomen/M
+Enid/M
+Enif/M
+Eniwetok/M
+Enkidu/M
+Enoch/M
+Enos/M
+Enrico/M
+Enrique/M
+Enron/M
+Enterprise/M
+Eocene/M
+Epcot/M
+Ephesian/MS
+Ephesus/M
+Ephraim/M
+Epictetus/M
+Epicurean/M
+Epicurus/M
+Epimethius/M
+Epiphany/SM
+Episcopal
+Episcopalian/MS
+Epistle
+Epsom/M
+Epson/M
+Epstein/M
+Equuleus/M
+Er/M
+Erasmus/M
+Erato/M
+Eratosthenes/M
+Erebus/M
+Erector/M
+Erewhon/M
+Erhard/M
+Eric/M
+Erica/M
+Erich/M
+Erick/M
+Ericka/M
+Erickson/M
+Ericson/M
+Ericsson/M
+Eridanus/M
+Erie/M
+Erik/M
+Erika/M
+Erin/M
+Eris/MS
+Eritrea/M
+Eritrean/SM
+Erlang/M
+Erlenmeyer/M
+Erma/M
+Erna/M
+Ernest/M
+Ernestine/M
+Ernesto/M
+Ernie/M
+Ernst/M
+Eros/MS
+Errol/M
+Erse/M
+ErvIn/M
+Erwin/M
+Esau/M
+Escher/M
+Escherichia/M
+Escondido
+Eskimo/MS
+Esmeralda/M
+Esperanto/M
+Esperanza/M
+Espinoza/M
+Esq/M
+Esquire/MS
+Essen/M
+Essene/M
+Essequibo/M
+Essex/M
+Essie/M
+Establishment
+Esteban/M
+Estela/M
+Estella/M
+Estelle/M
+Ester/M
+Esterhazy/M
+Esterh叩zy/M
+Estes/M
+Esther/M
+Estonia/M
+Estonian/SM
+Estrada/M
+Ethan/M
+Ethel/M
+Ethelred/M
+Ethernet/M
+Ethiopia/M
+Ethiopian/SM
+Etna/M
+Eton/M
+Etruria/M
+Etruscan/M
+Etta/M
+Eu/M
+Eucharist/MS
+Eucharistic
+Euclid/M
+Euclidean/M
+Eugene/M
+Eugenia/M
+Eugenie/M
+Eugenio/M
+Eula/M
+Euler/M
+Eumenides/M
+Eunice/M
+Euphrates/M
+Eur
+Eurasia/M
+Eurasian/MS
+Euripides/M
+Eurodollar/SM
+Europa/M
+Europe/M
+European/MS
+Eurydice/M
+Eustachian/M
+Eustis/M
+Euterpe/M
+Eva/M
+Evan/SM
+Evangelical
+Evangelina/M
+Evangeline/M
+Evangelist/M
+Evans/M
+Evansville/M
+Eve/M
+Evelyn/M
+Evenki/M
+EverReady/M
+Everest/M
+Everett/M
+Everette/M
+Everglades/M
+Evert/M
+Evian/M
+Evita/M
+Ewing/M
+Excalibur/M
+Excedrin/M
+Excellency/SM
+Exchequer
+Exercycle/M
+Exocet/M
+Exodus/M
+Exxon/M
+Eyck/M
+Eyre/M
+Eysenck/M
+Ezekiel/M
+Ezra/M
+F/MD
+FAA
+FAQ/SM
+FBI/M
+FCC
+FD
+FDA
+FDIC/M
+FDR/M
+FHA/M
+FICA/M
+FIFO
+FL
+FM/SM
+FNMA/M
+FOFL
+FORTRAN/M
+FPO
+FSF/M
+FSLIC
+FTC
+FUD/S
+FWD
+FWIW
+FY
+FYI
+Faberge/M
+Faberg辿/M
+Fabian/MS
+Facebook/M
+Faeroe/M
+Fafnir/M
+Fagin/M
+Fahd/M
+Fahrenheit/M
+Fairbanks/M
+Fairfield/M
+Fairhope/M
+Faisal/M
+Faisalabad/M
+Faith/M
+Fajardo/M
+Falasha/M
+Falkland/SM
+Falklands/M
+Fallopian/M
+Falstaff/M
+Falwell/M
+Fannie/M
+Fanny/M
+Faraday/M
+Fargo/M
+Farley/M
+Farmer/M
+Farmington/M
+Farragut/M
+Farrakhan/M
+Farrell/M
+Farrow/M
+Farsi/M
+Fascist
+Fassbinder/M
+Fatah/M
+Fates/M
+Father/SM
+Fatima/M
+Fatimid/M
+Faulkner/M
+Faulknerian/M
+Fauntleroy/M
+Faust/M
+Faustian/M
+Faustino/M
+Faustus/M
+Fawkes/M
+Fay/M
+Faye/M
+Fayetteville/M
+Fe/M
+Feb/M
+February/SM
+Fed/SM
+FedEx/M
+Federal/MS
+Federalist/M
+Federico/M
+Feds/M
+Felecia/M
+Felice/M
+Felicia/M
+Felicity/M
+Felipe/M
+Felix/M
+Fellini/M
+Fenian/M
+Ferber/M
+Ferdinand/M
+Fergus/M
+Ferguson/M
+Ferlinghetti/M
+Fermat/M
+Fermi/M
+Fern/M
+Fernandez/M
+Fernando/M
+Ferrari/M
+Ferraro/M
+Ferrell/M
+Ferris/M
+Feynman/M
+Fez/M
+Fiat/M
+Fiberglas/M
+Fibonacci/M
+Fichte/M
+Fidel/M
+Fido/M
+Fielding/M
+Fields/M
+Figaro/M
+Figueroa/M
+Fiji/M
+Fijian/MS
+Filipino/MS
+Fillmore/M
+Filofax/M
+Finch/M
+Finland/M
+Finlay/M
+Finley/M
+Finn/SM
+Finnbogadottir/M
+Finnegan/M
+Finnish/M
+Fiona/M
+Firebase/M
+Firefox/M
+Firestone/M
+Fischer/M
+Fisher/M
+Fisk/M
+Fitch/M
+Fitchburg/M
+Fitzgerald/M
+Fitzpatrick/M
+Fitzroy/M
+Fizeau/M
+Fla
+Flagstaff/M
+Flanagan/M
+Flanders/M
+Flathead
+Flatt/M
+Flaubert/M
+Fleischer/M
+Fleming/M
+Flemish/M
+Fletcher/M
+Flint/M
+Flintstones/M
+Flo/M
+Flora/M
+Florence/M
+Florentine/M
+Flores/M
+Florida/M
+Floridan/M
+Floridian/SM
+Florine/M
+Florsheim/M
+Flory/M
+Flossie/M
+Flowers/M
+Floyd/M
+Flynn/M
+Fm/M
+Foch/M
+Fokker/M
+Foley/M
+Folgers/M
+Folsom/M
+Fomalhaut/M
+Fonda/M
+Foosball/M
+Forbes/M
+Ford/M
+Foreman/M
+Forest/MR
+Forester/M
+Formica/MS
+Formosa/M
+Formosan/M
+Forrest/M
+Forster/M
+Fortaleza/M
+Fosse/M
+Foster/M
+Fotomat/M
+Foucault/M
+Fourier/M
+Fourneyron/M
+Fourth
+Fowler/M
+Fox/MS
+Fr/MD
+Fragonard/M
+Fran/M
+France/SM
+Frances/M
+Francesca/M
+Francine/M
+Francis/M
+Francisca/M
+Franciscan/MS
+Francisco/M
+Franck/M
+Franco/M
+Francois/M
+Francoise/M
+Francophile
+Franglais/M
+Frank/SM
+Frankel/M
+Frankenstein/M
+Frankfort/M
+Frankfurt/MR
+Frankfurter/M
+Frankie/M
+Frankish
+Franklin/M
+Franks/M
+Franny/M
+Franz/M
+Fraser/M
+Frau/MN
+Fraulein
+Frazier/M
+Fred/M
+Freda/M
+Freddie/M
+Freddy/M
+Frederic/M
+Frederick/M
+Fredericksburg/M
+Fredericton/M
+Fredric/M
+Fredrick/M
+Freeman/M
+Freemason/SM
+Freemasonry/SM
+Freetown/M
+Freida/M
+Fremont/M
+French/MS
+Frenchman/M
+Frenchmen/M
+Frenchwoman/M
+Frenchwomen/M
+Freon/M
+Fresnel/M
+Fresno/M
+Freud/M
+Freudian/M
+Frey/M
+Freya/M
+Fri/M
+Friday/SM
+Frieda/M
+Friedan/M
+Friedman/M
+Friedmann/M
+Friend/SM
+Frigga/M
+Frigidaire/M
+Frisbee/M
+Frisco/M
+Frisian/MS
+Frito/M
+Fritz/M
+Frobisher/M
+Frodo/M
+Froissart/M
+Fromm/M
+Fronde/M
+Frontenac/M
+Frost/M
+Frostbelt/M
+Frunze/M
+Fry/M
+Frye/M
+Fuchs/M
+Fuentes/M
+Fugger/M
+Fuji/M
+Fujian/M
+Fujitsu/M
+Fujiwara/M
+Fujiyama/M
+Fukuoka/M
+Fukuyama/M
+Fulani/M
+Fulbright/M
+Fuller/M
+Fullerton/M
+Fulton/M
+Funafuti/M
+Fundy/M
+Furies/M
+Furman/M
+Furtwangler/M
+Furtw辰ngler/M
+Fushun/M
+Fuzhou/M
+Fuzzbuster/M
+G/MNRB
+GA
+GAO
+GATT/M
+GB/M
+GCC/M
+GDP/M
+GE/M
+GED
+GHQ/M
+GHz
+GI
+GIF
+GIGO
+GM/M
+GMAT
+GMO
+GMT/M
+GNP/M
+GNU/M
+GOP/M
+GP/M
+GPA
+GPO
+GPS
+GPU
+GSA
+GTE/M
+GU
+GUI/M
+Ga/M
+Gable/M
+Gabon/M
+Gabonese/M
+Gaborone/M
+Gabriel/M
+Gabriela/M
+Gabrielle/M
+Gacrux/M
+Gadsden/M
+Gaea/M
+Gael/SM
+Gaelic/M
+Gagarin/M
+Gage/M
+Gaia/M
+Gail/M
+Gaiman/M
+Gaines/M
+Gainesville/M
+Gainsborough/M
+Galahad/SM
+Galapagos/M
+Galatea/M
+Galatia/M
+Galatians/M
+Galaxy
+Galbraith/M
+Gale/M
+Galen/M
+Galibi/M
+Galilean/SM
+Galilee/M
+Galileo/M
+Gall/M
+Gallagher/M
+Gallegos/M
+Gallic/M
+Gallicism/SM
+Gallo/M
+Galloway/M
+Gallup/M
+Galois/M
+Galsworthy/M
+Galvani/M
+Galveston/M
+Gama
+Gamay/M
+Gambia/M
+Gambian/SM
+Gamble/M
+Gamow/M
+Gandalf/M
+Gandhi/M
+Gandhian/M
+Ganesha/M
+Ganges/M
+Gangtok/M
+Gansu/M
+Gantry/M
+Ganymede/M
+Gap/M
+Garbo/M
+Garcia/M
+Gardner/M
+Gareth/M
+Garfield/M
+Garfunkel/M
+Gargantua/M
+Garibaldi/M
+Garland/M
+Garner/M
+Garrett/M
+Garrick/M
+Garrison/M
+Garry/M
+Garth/M
+Garvey/M
+Gary/M
+Garza/M
+Gascony/M
+Gasser/M
+Gastonia/M
+Gastroenterology
+Gates/M
+Gatling/M
+Gatorade/M
+Gatsby/M
+Gatun/M
+Gauguin/M
+Gaul/SM
+Gaulish
+Gauss/M
+Gaussian/M
+Gautama/M
+Gautier/M
+Gavin/M
+Gawain/M
+Gay/M
+Gayle/M
+Gaza/M
+Gaziantep/M
+Gd/M
+Gdansk/M
+Ge/M
+Geffen/M
+Gehenna/M
+Gehrig/M
+Geiger/M
+Gelbvieh/M
+Geller/M
+Gemini/MS
+Gen/M
+Gena/M
+Genaro/M
+Gene/M
+Genesis/M
+Genet/M
+Geneva/M
+Genevieve/M
+Genghis/M
+Genoa/SM
+Gentoo/M
+Gentry/M
+Geo/M
+Geoffrey/M
+George/MS
+Georgetown/M
+Georgette/M
+Georgia/M
+Georgian/MS
+Georgina/M
+Ger/M
+Gerald/M
+Geraldine/M
+Gerard/M
+Gerardo/M
+Gerber/M
+Gere/M
+Geritol/M
+German/MS
+Germanic/M
+Germany/M
+Geronimo/M
+Gerry/M
+Gershwin/M
+Gertrude/M
+Gestapo/SM
+Gethsemane/M
+Getty/M
+Gettysburg/M
+Gewurztraminer/M
+Gew端rztraminer/M
+Ghana/M
+Ghanaian
+Ghats/M
+Ghazvanid/M
+Ghent/M
+Ghibelline/M
+Giacometti/M
+Giannini/M
+Giauque/M
+Gibbon/M
+Gibbs/M
+Gibraltar/MS
+Gibson/M
+Gide/M
+Gideon/M
+Gielgud/M
+Gienah/M
+Gil/M
+Gila/M
+Gilbert/M
+Gilberto/M
+Gilchrist/M
+Gilda/M
+Gilead/M
+Giles/M
+Gilgamesh/M
+Gill/M
+Gillespie/M
+Gillette/M
+Gilliam/M
+Gillian/M
+Gilligan/M
+Gilman
+Gilmore/M
+Gilroy/M
+Gina/M
+Ginger/M
+Gingrich/M
+Ginny/M
+Gino/M
+Ginsberg/M
+Ginsburg/M
+Ginsu/M
+Giorgione/M
+Giotto/M
+Giovanni/M
+Giraudoux/M
+Giselle/M
+Gish/M
+GitHub/M
+Giuliani/M
+Giuseppe/M
+Giza/M
+Gk
+Gladstone/MS
+Gladys/M
+Glaser/M
+Glasgow/M
+Glass/M
+Glastonbury/M
+Glaswegian/SM
+Glaxo/M
+Gleason/M
+Glen/M
+Glenda/M
+Glendale
+Glenlivet/M
+Glenn/M
+Glenna/M
+Gloria/M
+Gloucester/M
+Glover/M
+Gnostic/M
+Gnosticism/M
+GnuPG
+Goa/M
+Gobi/M
+God/M
+Godard/M
+Goddard/M
+Godel/M
+Godhead/M
+Godiva/M
+Godot/M
+Godspeed/SM
+Godthaab/M
+Godunov/M
+Godzilla/M
+Goebbels/M
+Goering/M
+Goethals/M
+Goethe/M
+Goff/M
+Gog/M
+Gogol/M
+Goiania/M
+Golan/M
+Golconda/M
+Golda/M
+Goldberg/M
+Golden/M
+Goldie/M
+Goldilocks/M
+Golding/M
+Goldman/M
+Goldsboro/M
+Goldsmith/M
+Goldwater/M
+Goldwyn/M
+Golgi/M
+Golgotha/M
+Goliath/M
+Gomez/M
+Gomorrah/M
+Gompers/M
+Gomulka/M
+Gondwanaland/M
+Gonzales/M
+Gonzalez/M
+Gonzalo/M
+Good/M
+Goodall/M
+Goode/M
+Goodman/M
+Goodrich/M
+Goodwill/M
+Goodwin/M
+Goodyear/M
+Google/M
+Goolagong/M
+Gopher
+Gorbachev/M
+Gordian/M
+Gordimer/M
+Gordon/M
+Gore/M
+Goren/M
+Gorey/M
+Gorgas/M
+Gorgon/M
+Gorgonzola/M
+Gorky/M
+Gospel/MS
+Goteborg/M
+Goth/M
+Gotham/M
+Gothic/MS
+Goths
+Gouda/SM
+Gould/M
+Gounod/M
+Governor
+Goya/M
+Gr/B
+Grable/M
+Gracchus/M
+Grace/M
+Graceland/M
+Gracie/M
+Graciela/M
+Grady/M
+Graffias/M
+Grafton/M
+Graham/M
+Grahame/M
+Grail/M
+Grammy/M
+Grampians/M
+Granada/M
+Grant/M
+Grass/M
+Graves/M
+Gray/M
+Grayslake/M
+Grecian/M
+Greece/M
+Greek/SM
+Greeley/M
+Green/SM
+Greene/M
+Greenland/M
+Greenlandic
+Greenpeace/M
+Greensboro/M
+Greensleeves/M
+Greenspan/M
+Greenville/M
+Greenwich/M
+Greer/M
+Greg/M
+Gregg/M
+Gregorian/M
+Gregorio/M
+Gregory/M
+Grenada/M
+Grenadian/MS
+Grenadines/M
+Grendel/M
+Grenoble/M
+Gresham/M
+Greta/M
+Gretchen/M
+Gretel/M
+Gretzky/M
+Grey/M
+Grieg/M
+Griffin/M
+Griffith/M
+Grimes/M
+Grimm/M
+Grinch/M
+Gris/M
+Gromyko/M
+Gropius/M
+Gross/M
+Grosz/M
+Grotius/M
+Grover/M
+Grozny
+Grumman/M
+Grundy/M
+Grunewald/M
+Grus/M
+Gruyere/SM
+Gruy竪re/M
+Gr端newald/M
+Guadalajara/M
+Guadalcanal/M
+Guadalquivir/M
+Guadalupe/M
+Guadeloupe/M
+Guallatiri/M
+Guam/M
+Guamanian
+Guangdong/M
+Guangzhou/M
+Guantanamo/M
+Guarani/M
+Guarnieri/M
+Guatemala/M
+Guatemalan/MS
+Guayama/M
+Guayaquil/M
+Gucci/M
+Guelph/M
+Guernsey/MS
+Guerra/M
+Guerrero/M
+Guevara/M
+Guggenheim/M
+Guiana/M
+Guido
+Guillermo/M
+Guinea/M
+Guinean/MS
+Guinevere/M
+Guinness/M
+Guiyang/M
+Guizhou/M
+Guizot/M
+Gujarat/M
+Gujarati/M
+Gujranwala/M
+Gulfport/M
+Gullah/M
+Gulliver/M
+Gumbel/M
+Gunther/M
+Guofeng/M
+Gupta/M
+Gurkha/M
+Gus/M
+Gustav/M
+Gustavo/M
+Gustavus/M
+Gutenberg/M
+Guthrie/M
+Gutierrez/M
+Guy/M
+Guyana/M
+Guyanese/M
+Guzman/M
+Gwalior/M
+Gwen/M
+Gwendoline/M
+Gwendolyn/M
+Gwyn/M
+Gypsy/SM
+G旦del/M
+G旦teborg/M
+H/M
+HBO/M
+HBase/M
+HDD
+HDMI
+HDTV
+HF/M
+HHS
+HI
+HIV/M
+HM
+HMO/M
+HMS
+HOV
+HP/M
+HPV
+HQ/M
+HR
+HRH
+HS
+HSBC/M
+HST
+HT
+HTML/M
+HTTP
+HUD/M
+Ha/M
+Haas/M
+Habakkuk/M
+Haber/M
+Hadar/M
+Hades/M
+Hadoop/M
+Hadrian/M
+Hafiz/M
+Hagar/M
+Hagerstown/M
+Haggai/M
+Hagiographa/M
+Hague/M
+Hahn/M
+Haida/SM
+Haifa/M
+Hainan/M
+Haiphong/M
+Haiti/M
+Haitian/MS
+Hakka/M
+Hakluyt/M
+Hal/SM
+Haldane/M
+Hale/M
+Haleakala/M
+Haley/M
+Halifax/M
+Hall/M
+Halley/M
+Halliburton/M
+Hallie/M
+Hallmark/M
+Halloween/MS
+Hallstatt/M
+Halon/M
+Hals/M
+Halsey/M
+Ham/M
+Haman/M
+Hamburg/MS
+Hamhung/M
+Hamilcar/M
+Hamill/M
+Hamilton/M
+Hamiltonian/M
+Hamitic/M
+Hamlet/M
+Hamlin/M
+Hammarskjold/M
+Hammerstein/M
+Hammett/M
+Hammond/M
+Hammurabi/M
+Hampshire/M
+Hampton/M
+Hamsun/M
+Han/SM
+Hancock/M
+Handel/M
+Handy/M
+Haney/M
+Hanford/M
+Hangul/M
+Hangzhou/M
+Hank/M
+Hanna/M
+Hannah/M
+Hannibal/M
+Hanoi/M
+Hanover/M
+Hanoverian/M
+Hans/MN
+Hansel/M
+Hansen/M
+Hanson/M
+Hanuka
+Hanukah/M
+Hanukkah/M
+Hanukkahs
+Hapsburg/M
+Harare/M
+Harbin/M
+Hardin/M
+Harding/M
+Hardy/M
+Hargreaves/M
+Harlan/M
+Harlem/M
+Harlequin/M
+Harley/M
+Harlingen/M
+Harlow/M
+Harmon/M
+Harold/M
+Harper/M
+Harpy/SM
+Harrell/M
+Harriet/M
+Harriett/M
+Harrington/M
+Harris/M
+Harrisburg/M
+Harrison/M
+Harrisonburg/M
+Harrods/M
+Harry/M
+Hart/M
+Harte/M
+Hartford/M
+Hartline/M
+Hartman/M
+Harvard/M
+Harvey/M
+Hasbro/M
+Hasidim/M
+Haskell/M
+Hastings/M
+Hatfield/M
+Hathaway/M
+Hatsheput/M
+Hatteras/M
+Hattie/M
+Hattiesburg/M
+Hauptmann/M
+Hausa/M
+Hausdorff/M
+Havana/MS
+Havarti/M
+Havel/M
+Havoline/M
+Haw
+Hawaii/M
+Hawaiian/SM
+Hawking/M
+Hawkins/M
+Hawks
+Hawthorne/M
+Hay/SM
+Hayden/M
+Haydn/M
+Hayek/M
+Hayes/M
+Haynes/M
+Hays/M
+Hayward/M
+Haywood/M
+Hayworth/M
+Hazel/M
+Hazleton/M
+Hazlitt/M
+He/M
+Head/M
+Hearst/M
+Heath/MR
+Heather/M
+Heaviside/M
+Heb
+Hebe/M
+Hebei/M
+Hebert/M
+Hebraic/M
+Hebraism/SM
+Hebrew/MS
+Hebrews/M
+Hebrides/M
+Hecate/M
+Hector/M
+Hecuba/M
+Heep/M
+Hefner/M
+Hegel/M
+Hegelian/M
+Hegira/M
+Heidegger/M
+Heidelberg/M
+Heidi/M
+Heifetz/M
+Heilongjiang/M
+Heimlich/M
+Heine/M
+Heineken/M
+Heinlein/M
+Heinrich/M
+Heinz/M
+Heisenberg/M
+Heisman/M
+Helen/M
+Helena/M
+Helene/M
+Helga/M
+Helicobacter
+Helicon/M
+Heliopolis/M
+Helios/M
+Hellene/SM
+Hellenic/M
+Hellenism/MS
+Hellenist
+Hellenistic/M
+Hellenization/M
+Hellenize/M
+Heller/M
+Hellespont/M
+Hellman/M
+Helmholtz/M
+Heloise/M
+Helsinki/M
+Helvetian
+Helvetius/M
+Hemet/M
+Hemingway/M
+Henan/M
+Hench/M
+Henderson/M
+Hendrick/MS
+Hendricks/M
+Hendrix/M
+Henley/M
+Hennessy/M
+Henri/M
+Henrietta/M
+Henrik/M
+Henry/M
+Hensley/M
+Henson/M
+Hepburn/M
+Hephaestus/M
+Hepplewhite/M
+Hera/M
+Heracles/M
+Heraclitus/M
+Herakles/M
+Herbart/M
+Herbert/M
+Herculaneum/M
+Herculean
+Hercules/M
+Herder/M
+Hereford/SM
+Herero/M
+Heriberto/M
+Herman/M
+Hermaphroditus/M
+Hermes/M
+Herminia/M
+Hermitage/M
+Hermite/M
+Hermosillo/M
+Hernandez/M
+Herod/M
+Herodotus/M
+Heroku/M
+Herr/MG
+Herrera/M
+Herrick/M
+Herring/M
+Herschel/M
+Hersey/M
+Hershel/M
+Hershey/M
+Hertz/M
+Hertzsprung/M
+Herzegovina/M
+Herzl/M
+Heshvan/M
+Hesiod/M
+Hesperia/M
+Hesperus/M
+Hess/M
+Hesse/M
+Hessian/M
+Hester/M
+Heston/M
+Hettie/M
+Hewitt/M
+Hewlett/M
+Heyerdahl/M
+Heywood/M
+Hezbollah/M
+Hezekiah/M
+Hf/M
+Hg/M
+Hialeah/M
+Hiawatha/M
+Hibernia/M
+Hibernian
+Hickman/M
+Hickok/M
+Hickory/M
+Hicks/M
+Hieronymus/M
+Higashiosaka
+Higgins/M
+Highlander/SM
+Highlands
+Highness/M
+Hightstown/M
+Hilario/M
+Hilary/M
+Hilbert/M
+Hilda/M
+Hildebrand/M
+Hilfiger/M
+Hill/M
+Hillary/M
+Hillel/M
+Hilton/M
+Himalaya/SM
+Himalayan
+Himalayas/M
+Himmler/M
+Hinayana/M
+Hindemith/M
+Hindenburg/M
+Hindi/M
+Hindu/SM
+Hinduism/SM
+Hindustan/M
+Hindustani/SM
+Hines/M
+Hinesville/M
+Hinton/M
+Hipparchus/M
+Hippocrates/M
+Hippocratic/M
+Hiram/M
+Hirobumi/M
+Hirohito/M
+Hiroshima/M
+Hispanic/SM
+Hispaniola/M
+Hiss/M
+Hitachi/M
+Hitchcock/M
+Hitler/MS
+Hittite/SM
+Hmong/M
+Ho/M
+Hobart/M
+Hobbes/M
+Hobbs/M
+Hockney/M
+Hodge/SM
+Hodges/M
+Hodgkin/M
+Hoff/M
+Hoffa/M
+Hoffman/M
+Hofstadter/M
+Hogan/M
+Hogarth/M
+Hogwarts/M
+Hohenlohe/M
+Hohenstaufen/M
+Hohenzollern/M
+Hohhot/M
+Hohokam/M
+Hokkaido/M
+Hokusai/M
+Holbein/M
+Holcomb/M
+Holden/M
+Holder/M
+Holiday/M
+Holiness
+Holland/ZSMR
+Hollander/M
+Hollerith/M
+Holley/M
+Hollie/M
+Hollis/M
+Holloway/M
+Holly/M
+Hollywood/M
+Holman/M
+Holmes/M
+Holocaust/M
+Holocene/M
+Holst/M
+Holstein/SM
+Holt/M
+Homer/M
+Homeric/M
+Hon
+Honda/M
+Honduran/MS
+Honduras/M
+Honecker/M
+Honeywell/M
+Hong
+Honiara/M
+Honolulu/M
+Honorable
+Honshu/M
+Hood/M
+Hooke/RM
+Hooker/M
+Hooper/M
+Hoosier/MS
+Hooters/M
+Hoover/MS
+Hope/M
+Hopewell/M
+Hopi/SM
+Hopkins/M
+Hopper/M
+Horace/M
+Horacio/M
+Horatio/M
+Hormel/M
+Hormuz/M
+Horn/M
+Hornblower/M
+Horne/M
+Horowitz/M
+Horthy/M
+Horton/M
+Horus/M
+Hosea/M
+Host/SM
+Hotpoint/M
+Hottentot/SM
+Houdini/M
+Houma/M
+House/M
+Housman/M
+Houston/M
+Houyhnhnm/M
+Hovhaness/M
+Howard/M
+Howe/M
+Howell/MS
+Howells/M
+Howrah
+Hoyle/M
+Hrothgar/M
+Hts
+Huang/M
+Hubbard/M
+Hubble/M
+Hubei/M
+Huber/M
+Hubert/M
+Huck/M
+Huddersfield
+Hudson/M
+Huerta/M
+Huey/M
+Huff/M
+Huffman/M
+Huggins/M
+Hugh/MS
+Hughes/M
+Hugo/M
+Huguenot/MS
+Hui/M
+Huitzilopotchli/M
+Hull/M
+Humberto/M
+Humboldt/M
+Hume/M
+Hummel/M
+Hummer/M
+Humphrey/SM
+Humvee/M
+Hun/SM
+Hunan/M
+Hung/M
+Hungarian/SM
+Hungary/M
+Hunspell/M
+Hunt/MR
+Hunter/M
+Huntington/M
+Huntley/M
+Huntsville/M
+Hurd/M
+Hurley/M
+Huron/M
+Hurst/M
+Hus/M
+Hussein/M
+Husserl/M
+Hussite/M
+Huston/M
+Hutchinson/M
+Hutton/M
+Hutu/M
+Huxley/M
+Huygens/M
+Hyades/M
+Hyde/M
+Hyderabad/M
+Hydra/M
+Hymen/M
+Hyperion/M
+Hyundai/M
+Hz/M
+H辿loise/M
+I'd
+I'll
+I'm
+I've
+I/M
+IA
+IBM/M
+ICBM/SM
+ICC
+ICU
+ID/SM
+IDE
+IE
+IED
+IEEE
+IKEA/M
+IL
+IMF/M
+IMHO
+IMNSHO
+IMO
+IN
+ING/M
+INRI
+INS
+IOU/M
+IP
+IPA
+IPO
+IQ/M
+IRA/SM
+IRC
+IRS/M
+ISBN
+ISIS
+ISO/M
+ISP
+ISS
+IT
+IUD
+IV/SM
+IVF
+Ia
+Iaccoca/M
+Iago/M
+Ian/M
+Iapetus/M
+Ibadan/M
+Iberia/M
+Iberian/M
+Ibiza/M
+Iblis/M
+Ibo/M
+Ibsen/M
+Icahn/M
+Icarus/M
+Ice
+Iceland/MRZ
+Icelander/M
+Icelandic/M
+Ida/M
+Idaho/SM
+Idahoan/MS
+Idahoes
+Ieyasu/M
+Ignacio/M
+Ignatius/M
+Igor/M
+Iguassu/M
+Ijsselmeer/M
+Ike/M
+Ikhnaton/M
+Ila/M
+Ilene/M
+Iliad/SM
+Ill
+Illinois/M
+Illinoisan/MS
+Illuminati/M
+Ilyushin/M
+Imam
+Imelda/M
+Imhotep/M
+Imodium/M
+Imogene/M
+Imus/M
+In/M
+Ina/M
+Inc
+Inca/SM
+Inchon/M
+Incorporated
+Ind
+Independence/M
+India/M
+Indian/MS
+Indiana/M
+Indianan/SM
+Indianapolis/M
+Indianian
+Indies/M
+Indio/M
+Indira/M
+Indochina/M
+Indochinese/M
+Indonesia/M
+Indonesian/SM
+Indore/M
+Indra/M
+Indus/M
+Indy/SM
+Ines/M
+Inez/M
+Inge/M
+Inglewood
+Ingram/M
+Ingres/M
+Ingrid/M
+Innocent/M
+Innsbruck
+Inonu/M
+Inquisition/M
+Inst
+Instagram/M
+Instamatic/M
+Intel/M
+Intelsat/M
+Internationale/M
+Internet/SM
+Interpol/M
+Inuit/MS
+Inuktitut/M
+Invar/M
+Io/M
+Ionesco/M
+Ionian/MS
+Ionic/SM
+Iowa/SM
+Iowan/MS
+Iphigenia/M
+Ipswich
+Iqaluit/M
+Iqbal/M
+Iquitos/M
+Ir/M
+Ira/M
+Iran/M
+Iranian/SM
+Iraq/M
+Iraqi/MS
+Ireland/M
+Irene/M
+Iris/M
+Irish/MR
+Irishman/M
+Irishmen/M
+Irishwoman/M
+Irishwomen/M
+Irkutsk/M
+Irma/M
+Iroquoian/SM
+Iroquois/M
+Irrawaddy/M
+Irtish/M
+Irvin/M
+Irvine/M
+Irving/M
+Irwin/M
+Isaac/M
+Isabel/M
+Isabela/M
+Isabella/M
+Isabelle/M
+Isaiah/M
+Iscariot/M
+Isfahan/M
+Isherwood/M
+Ishim/M
+Ishmael/M
+Ishtar/M
+Isiah/M
+Isidro/M
+Isis/M
+Islam/MS
+Islamabad/M
+Islamic/M
+Islamism/M
+Islamist/M
+Islamophobia
+Islamophobic
+Ismael/M
+Ismail/M
+Isolde/M
+Ispell/M
+Israel/SM
+Israeli/SM
+Israelite/M
+Issac/M
+Issachar/M
+Istanbul/M
+Isuzu/M
+It
+Itaipu/M
+Ital
+Italian/SM
+Italianate
+Italy/M
+Itasca/M
+Ithaca/M
+Ithacan/M
+Ito/M
+Iva/M
+Ivan/M
+Ivanhoe/M
+Ives/M
+Ivorian
+Ivory/M
+Ivy/M
+Iyar/M
+Izaak/M
+Izanagi/M
+Izanami/M
+Izhevsk/M
+Izmir/M
+Izod/M
+Izvestia/M
+J/MD
+JCS
+JD
+JFK/M
+JP
+JPEG
+JV
+Jack/M
+Jackie/M
+Jacklyn/M
+Jackson/M
+Jacksonian/M
+Jacksonville/M
+Jacky/M
+Jaclyn/M
+Jacob/SM
+Jacobean/M
+Jacobi/M
+Jacobin/M
+Jacobite/M
+Jacobs/M
+Jacobson/M
+Jacquard/M
+Jacqueline/M
+Jacquelyn/M
+Jacques/M
+Jacuzzi/M
+Jagger/M
+Jagiellon/M
+Jaguar/M
+Jahangir/M
+Jaime/M
+Jain/M
+Jainism/M
+Jaipur/M
+Jakarta/M
+Jake/M
+Jamaal/M
+Jamaica/M
+Jamaican/SM
+Jamal/M
+Jamar/M
+Jame/SM
+Jamel/M
+James/M
+Jamestown/M
+Jami/M
+Jamie/M
+Jan/M
+Jana/M
+Janacek/M
+Jane/M
+Janell/M
+Janelle/M
+Janesville/M
+Janet/M
+Janette/M
+Janice/M
+Janie/M
+Janine/M
+Janis/M
+Janissary/M
+Janjaweed/M
+Janna/M
+Jannie/M
+Jansen/M
+Jansenist/M
+January/SM
+Janus/M
+Jap/SM
+Japan/M
+Japanese/MS
+Japura/M
+Jared/M
+Jarlsberg/M
+Jarred/M
+Jarrett/M
+Jarrod/M
+Jarvis/M
+Jasmine/M
+Jason/M
+Jasper/M
+Jataka/M
+Java/SM
+JavaScript/M
+Javanese/M
+Javier/M
+Jaxartes/M
+Jay/M
+Jayapura/M
+Jayawardene/M
+Jaycee/MS
+Jaycees/M
+Jayne/M
+Jayson/M
+Jean/M
+Jeanette/M
+Jeanie/M
+Jeanine/M
+Jeanne/M
+Jeannette/M
+Jeannie/M
+Jeannine/M
+Jed/M
+Jedi/M
+Jeep/M
+Jeeves/M
+Jeff/M
+Jefferey/M
+Jefferson/M
+Jeffersonian/M
+Jeffery/M
+Jeffrey/M
+Jeffry/M
+Jehoshaphat/M
+Jehovah/M
+Jekyll/M
+Jenifer/M
+Jenkins/M
+Jenna/M
+Jenner/M
+Jennie/M
+Jennifer/M
+Jennings/M
+Jenny/M
+Jensen/M
+Jephthah/M
+Jerald/M
+Jeremiah/M
+Jeremiahs
+Jeremy/M
+Jeri/M
+Jericho/M
+Jermaine/M
+Jeroboam/M
+Jerold/M
+Jerome/M
+Jerri/M
+Jerrod/M
+Jerrold/M
+Jerry/M
+Jersey/MS
+Jerusalem/M
+Jess/M
+Jesse/M
+Jessica/M
+Jessie/M
+Jesuit/MS
+Jesus/M
+Jetway/M
+Jew/SM
+Jewel/M
+Jewell/M
+Jewess/MS
+Jewish/PM
+Jewry/M
+Jezebel/SM
+Jiangsu/M
+Jiangxi/M
+Jidda/M
+Jilin/M
+Jill/M
+Jillian/M
+Jim/M
+Jimenez/M
+Jimmie/M
+Jimmy/M
+Jinan/M
+Jinnah/M
+Jinny/M
+Jivaro/M
+Jo/M
+Joan/M
+Joann/M
+Joanna/M
+Joanne/M
+Joaquin/M
+Job/SM
+Jobs/M
+Jocasta/M
+Jocelyn/M
+Jock/M
+Jockey/M
+Jodi/M
+Jodie/M
+Jody/M
+Joe/M
+Joel/M
+Joey/M
+Jogjakarta/M
+Johann/M
+Johanna/M
+Johannes/M
+Johannesburg/M
+John/SM
+Johnathan/M
+Johnathon/M
+Johnie/M
+Johnnie/M
+Johnny/M
+Johns/M
+Johnson/M
+Johnston/M
+Johnstown/M
+Jolene/M
+Joliet/M
+Jolson/M
+Jon/M
+Jonah/M
+Jonahs
+Jonas/M
+Jonathan/M
+Jonathon/M
+Jones/M
+Jonesboro/M
+Joni/M
+Jonson/M
+Joplin/M
+Jordan/M
+Jordanian/MS
+Jorge/M
+Jose/M
+Josef/M
+Josefa/M
+Josefina/M
+Joseph/M
+Josephine/M
+Josephs
+Josephson/M
+Josephus/M
+Josh/M
+Joshua/M
+Josiah/M
+Josie/M
+Josue/M
+Joule/M
+Jove/M
+Jovian/M
+Joy/M
+Joyce/M
+Joycean/M
+Joyner/M
+Jpn
+Jr/M
+Juan/M
+Juana/M
+Juanita/M
+Juarez/M
+Jubal/M
+Judaeo
+Judah/M
+Judaic
+Judaical
+Judaism/MS
+Judas/MS
+Judd/M
+Jude/M
+Judea/M
+Judges
+Judith/M
+Judson/M
+Judy/M
+Juggernaut/M
+Jul
+Jules/M
+Julia/M
+Julian/M
+Juliana/M
+Julianne/M
+Julie/M
+Juliet/M
+Juliette/M
+Julio/M
+Julius/M
+Julliard/M
+July/SM
+Jun/M
+June/SM
+Juneau/M
+Jung/M
+Jungfrau/M
+Jungian/M
+Junior/SM
+Junker/SM
+Juno/M
+Jupiter/M
+Jurassic/M
+Jurua/M
+Justice/M
+Justin/M
+Justine/M
+Justinian/M
+Jutland/M
+Juvenal/M
+K/SMNGJ
+KB/M
+KC
+KFC/M
+KGB/M
+KIA
+KKK/M
+KO/M
+KP
+KS
+KY
+Kaaba/M
+Kabul/M
+Kafka/M
+Kafkaesque/M
+Kagoshima/M
+Kahlua/M
+Kahului/M
+Kaifeng/M
+Kailua/M
+Kaiser/MS
+Kaitlin/M
+Kalahari/M
+Kalamazoo/M
+Kalashnikov/M
+Kalb/M
+Kalevala/M
+Kalgoorlie/M
+Kali/M
+Kalmyk/M
+Kama/M
+Kamchatka/M
+Kamehameha/M
+Kampala/M
+Kampuchea/M
+Kan/SM
+Kanchenjunga/M
+Kandahar/M
+Kandinsky/M
+Kane/M
+Kaneohe/M
+Kankakee/M
+Kannada/M
+Kano/M
+Kanpur/M
+Kansan/MS
+Kansas/M
+Kant/M
+Kantian/M
+Kaohsiung/M
+Kaposi/M
+Kara/M
+Karachi/M
+Karaganda/M
+Karakorum/M
+Karamazov/M
+Kareem/M
+Karen/M
+Karenina/M
+Kari/M
+Karin/M
+Karina/M
+Karl/M
+Karla/M
+Karloff/M
+Karo/M
+Karol/M
+Karroo/M
+Karyn/M
+Kasai/M
+Kasey/M
+Kashmir/SM
+Kasparov/M
+Kate/M
+Katelyn/M
+Katharine/M
+Katherine/M
+Katheryn/M
+Kathiawar/M
+Kathie/M
+Kathleen/M
+Kathmandu/M
+Kathrine/M
+Kathryn/M
+Kathy/M
+Katie/M
+Katina/M
+Katmai/M
+Katmandu/M
+Katowice/M
+Katrina/M
+Katy/M
+Kauai/M
+Kaufman/M
+Kaunas/M
+Kaunda/M
+Kawabata/M
+Kawasaki/M
+Kay/M
+Kaye/M
+Kayla/M
+Kazakh/M
+Kazakhs
+Kazakhstan/M
+Kazan/M
+Kazantzakis/M
+Kb/M
+Keaton/M
+Keats/M
+Keck/M
+Keenan/M
+Keewatin/M
+Keillor/M
+Keisha/M
+Keith/M
+Keller/M
+Kelley/M
+Kelli/M
+Kellie/M
+Kellogg/M
+Kelly/M
+Kelsey/M
+Kelvin/M
+Kemerovo/M
+Kemp/M
+Kempis/M
+Ken/M
+Kendall/M
+Kendra/M
+Kendrick/M
+Kenmore/M
+Kennan/M
+Kennedy/M
+Kenneth/M
+Kennewick/M
+Kennith/M
+Kenny/M
+Kenosha/M
+Kent/M
+Kenton/M
+Kentuckian/MS
+Kentucky/M
+Kenya/M
+Kenyan/SM
+Kenyatta/M
+Kenyon/M
+Keogh/M
+Keokuk/M
+Kepler/M
+Kerensky/M
+Keri/M
+Kermit/M
+Kern/M
+Kerouac/M
+Kerr/M
+Kerri/M
+Kerry/M
+Kettering/M
+Keven/M
+Kevin/M
+Kevlar/M
+Kevorkian/M
+Kewpie/M
+Key/M
+Keynes/M
+Keynesian/M
+Khabarovsk/M
+Khachaturian/M
+Khalid/M
+Khan/M
+Kharkov/M
+Khartoum/M
+Khayyam/M
+Khazar/M
+Khmer/M
+Khoikhoi/M
+Khoisan/M
+Khomeini/M
+Khorana/M
+Khrushchev/M
+Khufu/M
+Khulna/M
+Khwarizmi/M
+Khyber/M
+Kickapoo/M
+Kidd/M
+Kiel/M
+Kierkegaard/M
+Kieth/M
+Kiev/M
+Kigali/M
+Kikuyu/M
+Kilauea/M
+Kilimanjaro/M
+Killeen/M
+Kilroy/M
+Kim/M
+Kimberley/M
+Kimberly/M
+King/M
+Kingsport/M
+Kingston/M
+Kingstown/M
+Kinko's
+Kinney/M
+Kinsey/M
+Kinshasa/M
+Kiowa/MS
+Kip/M
+Kipling/M
+Kirby/M
+Kirchhoff/M
+Kirchner/M
+Kirghistan/M
+Kirghiz/M
+Kirghizia/M
+Kiribati/M
+Kirinyaga/M
+Kirk/M
+Kirkland/M
+Kirkpatrick/M
+Kirov/M
+Kirsten/M
+Kisangani/M
+Kishinev/M
+Kislev/M
+Kissimmee/M
+Kissinger/M
+Kit/M
+Kitakyushu/M
+Kitchener/M
+Kitty/M
+Kiwanis/M
+Klan/M
+Klansman/M
+Klaus/M
+Klee/M
+Kleenex/MS
+Klein/M
+Klimt/M
+Kline/M
+Klingon/M
+Klondike/MS
+Kmart/M
+Knapp/M
+Knesset/M
+Kngwarreye/M
+Knickerbocker/M
+Knievel/M
+Knight/M
+Knopf/M
+Knossos/M
+Knowles/M
+Knox/M
+Knoxville/M
+Knudsen/M
+Knuth/M
+Knuths
+Kobe/M
+Koch/M
+Kochab/M
+Kodachrome/M
+Kodak/M
+Kodaly/M
+Kodiak/M
+Koestler/M
+Kohinoor/M
+Kohl/M
+Koizumi/M
+Kojak/M
+Kokomo/M
+Kolyma/M
+Kommunizma/M
+Kong/M
+Kongo/M
+Konrad/M
+Koontz/M
+Koppel/M
+Koran/MS
+Koranic
+Korea/M
+Korean/SM
+Kornberg/M
+Kory/M
+Korzybski/M
+Kosciusko/M
+Kossuth/M
+Kosygin/M
+Kotlin/M
+Koufax/M
+Kowloon/M
+Kr/M
+Kraft/M
+Krakatau/M
+Krakatoa/M
+Krakow/M
+Kramer/M
+Krasnodar/M
+Krasnoyarsk/M
+Krebs/M
+Kremlin/M
+Kremlinologist
+Kremlinology
+Kresge/M
+Kringle/M
+Kris/M
+Krishna/M
+Krishnamurti/M
+Krista/M
+Kristen/M
+Kristi/M
+Kristie/M
+Kristin/M
+Kristina/M
+Kristine/M
+Kristopher/M
+Kristy/M
+Kroc/M
+Kroger/M
+Kronecker/M
+Kropotkin/M
+Kruger/M
+Krugerrand/M
+Krupp/M
+Krystal/M
+Kshatriya/M
+Kublai/M
+Kubrick/M
+Kuhn/M
+Kuibyshev/M
+Kulthumm/M
+Kunming/M
+Kuomintang/M
+Kurd/M
+Kurdish/M
+Kurdistan/M
+Kurosawa/M
+Kurt/M
+Kurtis/M
+Kusch/M
+Kutuzov/M
+Kuwait/M
+Kuwaiti/SM
+Kuznets/M
+Kuznetsk/M
+Kwakiutl/M
+Kwan/M
+Kwangchow/M
+Kwangju/M
+Kwanzaa/MS
+Ky/MH
+Kyle/M
+Kyoto/M
+Kyrgyzstan/M
+Kyushu/M
+L'Amour/M
+L'Enfant
+L'Oreal/M
+L'Ouverture/M
+L/MN
+LA
+LAN/M
+LBJ/M
+LC
+LCD/M
+LCM
+LDC
+LED/M
+LG/M
+LGBT
+LIFO
+LL
+LLB/M
+LLD/M
+LNG
+LOGO
+LP/M
+LPG
+LPN/SM
+LSAT
+LSD/M
+LVN
+La/SM
+Lab
+Laban/M
+Labrador/SM
+Labradorean
+Labradorian
+Lacey/M
+Lachesis/M
+Lactobacillus
+Lacy/M
+Ladoga/M
+Ladonna/M
+Lady/M
+Ladyship/MS
+Lafayette/M
+Lafitte/M
+Lagos/M
+Lagrange/M
+Lagrangian/M
+Lahore/M
+Laius/M
+Lajos/M
+Lakeisha/M
+Lakeland/M
+Lakewood
+Lakisha/M
+Lakota/M
+Lakshmi/M
+Lamaism/SM
+Lamar/M
+Lamarck/M
+Lamaze/M
+Lamb/M
+Lambert/M
+Lamborghini/M
+Lambrusco/M
+Lamentations
+Lamont/M
+Lana/M
+Lanai/M
+Lancashire/M
+Lancaster/M
+Lance/M
+Lancelot/M
+Land/M
+Landon/M
+Landry/M
+Landsat/M
+Landsteiner/M
+Lane/M
+Lang/M
+Langerhans/M
+Langland/M
+Langley/M
+Langmuir/M
+Lanka/M
+Lankan/M
+Lanny/M
+Lansing/M
+Lanzhou/M
+Lao/SM
+Laocoon/M
+Laos/M
+Laotian/SM
+Laplace/M
+Laplacian
+Lapland/MR
+Lapp/SM
+Lara/M
+Laramie/M
+Lardner/M
+Laredo/M
+Larousse/M
+Larry/M
+Lars/MN
+Larsen/M
+Larson/M
+Lascaux/M
+Lassa/M
+Lassen/M
+Lassie/M
+Lat/M
+Latasha/M
+Lateran/M
+Latham/M
+Latin/MRS
+Latina
+Latino/SM
+Latinx
+Latisha/M
+Latonya/M
+Latoya/M
+Latrobe/M
+Latvia/M
+Latvian/MS
+Laud/MR
+Lauder/M
+Laue/M
+Laundromat/M
+Laura/M
+Laurasia/M
+Laurel/M
+Lauren/M
+Laurence/M
+Laurent/M
+Lauri/M
+Laurie/M
+Laval/M
+Lavern/M
+Laverne/M
+Lavoisier/M
+Lavonne/M
+Lawanda/M
+Lawrence/M
+Lawson/M
+Lawton/M
+Layamon/M
+Layla/M
+Layton/M
+Lazaro/M
+Lazarus/M
+Le/SM
+Lea/M
+Leach/M
+Leadbelly/M
+Leah/M
+Leakey/M
+Lean/M
+Leander/M
+Leann/M
+Leanna/M
+Leanne/M
+Lear/M
+Learjet/M
+Leary/M
+Leavenworth/M
+Lebanese/M
+Lebanon/M
+Lebesgue/M
+Leblanc/M
+Leda/M
+Lederberg/M
+Lee/M
+Leeds/M
+Leesburg/M
+Leeuwenhoek/M
+Leeward/M
+Left
+Legendre/M
+Leger/M
+Leghorn/M
+Lego/M
+Legree/M
+Lehman/M
+Leibniz/M
+Leicester/SM
+Leiden/M
+Leif/M
+Leigh/M
+Leila/M
+Leipzig/M
+Lela/M
+Leland/M
+Lelia/M
+Lemaitre/M
+Lemuel/M
+Lemuria/M
+Len/M
+Lena/M
+Lenard/M
+Lenin/M
+Leningrad/M
+Leninism/M
+Leninist/M
+Lennon/M
+Lenny/M
+Leno/M
+Lenoir/M
+Lenora/M
+Lenore/M
+Lent/SMN
+Lenten/M
+Leo/SM
+Leola/M
+Leominster/M
+Leon/M
+Leona/M
+Leonard/M
+Leonardo/M
+Leoncavallo/M
+Leonel/M
+Leonid/M
+Leonidas/M
+Leonor/M
+Leopold/M
+Leopoldo/M
+Lepidus/M
+Lepke/M
+Lepus/M
+Lerner/M
+Leroy/M
+Les/M
+Lesa/M
+Lesley/M
+Leslie/M
+Lesotho/M
+Lesseps/M
+Lessie/M
+Lester/M
+Lestrade/M
+Leta/M
+Letha/M
+Lethe/M
+Leticia/M
+Letitia/M
+Letterman/M
+Levant/M
+Levesque/M
+Levi/SM
+Leviathan/M
+Levine/M
+Leviticus/M
+Levitt/M
+Levy/M
+Lew/M
+Lewinsky/M
+Lewis/M
+Lewiston/M
+Lewisville/M
+Lexington/M
+Lexus/M
+Lhasa/MS
+Lhotse/M
+Li/MY
+Liaoning/M
+Libby/M
+Liberace/M
+Liberal
+Liberia/M
+Liberian/SM
+Libra/MS
+LibreOffice/M
+Libreville/M
+Librium/M
+Libya/M
+Libyan/SM
+Lichtenstein/M
+Lidia/M
+Lie/M
+Lieberman/M
+Liebfraumilch/M
+Liechtenstein/ZMR
+Liechtensteiner/M
+Liege/M
+Lieut
+Lila/M
+Lilia/M
+Lilian/M
+Liliana/M
+Lilith/M
+Liliuokalani/M
+Lille/M
+Lillian/M
+Lillie/M
+Lilliput/M
+Lilliputian/MS
+Lilly/M
+Lilongwe/M
+Lily/M
+Lima/M
+Limbaugh/M
+Limbo
+Limburger/M
+Limoges/M
+Limousin/M
+Limpopo/M
+Lin/M
+Lina/M
+Lincoln/MS
+Lind/M
+Linda/M
+Lindbergh/M
+Lindsay/M
+Lindsey/M
+Lindy/M
+Linnaeus/M
+Linotype/M
+Linton/M
+Linus/M
+Linux/MS
+Linwood/M
+Lionel/M
+Lipizzaner/M
+Lippi/M
+Lippmann/M
+Lipscomb/M
+Lipton/M
+Lisa/M
+Lisbon/M
+Lissajous/M
+Lister/M
+Listerine/M
+Liston/M
+Liszt/M
+Lithuania/M
+Lithuanian/MS
+Little/M
+Litton/M
+Livermore/M
+Liverpool/M
+Liverpudlian/SM
+Livia/M
+Livingston/M
+Livingstone/M
+Livonia/M
+Livy/M
+Liz/M
+Liza/M
+Lizzie/M
+Lizzy/M
+Ljubljana/M
+Llewellyn/M
+Lloyd/M
+Ln
+Loafer/SM
+Lobachevsky/M
+Lochinvar/M
+Locke/M
+Lockean/M
+Lockheed/M
+Lockwood/M
+Lodge/M
+Lodi/M
+Lodz/M
+Loewe/M
+Loewi/M
+Loews/M
+Logan/M
+Lohengrin/M
+Loire/M
+Lois/M
+Loki/M
+Lola/M
+Lolita/M
+Lollard/M
+Lollobrigida/M
+Lombard/M
+Lombardi/M
+Lombardy/M
+Lome/M
+Lompoc/M
+Lon/M
+London/MRZ
+Londoner/M
+Long/M
+Longfellow/M
+Longmont/M
+Longstreet/M
+Longueuil
+Longview/M
+Lonnie/M
+Lopez/M
+Lora/M
+Lorain/M
+Loraine/M
+Lord/SM
+Lordship/SM
+Lorelei/M
+Loren/M
+Lorena/M
+Lorene/M
+Lorentz/M
+Lorentzian
+Lorenz/M
+Lorenzo/M
+Loretta/M
+Lori/M
+Lorie/M
+Lorna/M
+Lorraine/M
+Lorre/M
+Lorrie/M
+Los
+Lot/M
+Lothario/SM
+Lott/M
+Lottie/M
+Lou/M
+Louella/M
+Louie/M
+Louis/M
+Louisa/M
+Louise/M
+Louisiana/M
+Louisianan/MS
+Louisianian/MS
+Louisville/M
+Lourdes/M
+Louvre/M
+Love/M
+Lovecraft/M
+Lovelace/M
+Lowe/M
+Lowell/M
+Lowenbrau/M
+Lowery/M
+Lowlands
+Loyang/M
+Loyd/M
+Loyola/M
+Lr
+Lt
+Ltd
+Lu/M
+Luanda/M
+Luann/M
+Lubavitcher/M
+Lubbock/M
+Lubumbashi/M
+Lucas/M
+Luce/M
+Lucia/M
+Lucian/M
+Luciano/M
+Lucien/M
+Lucifer/M
+Lucile/M
+Lucille/M
+Lucinda/M
+Lucio/M
+Lucite/SM
+Lucius/M
+Lucknow/M
+Lucretia/M
+Lucretius/M
+Lucy/M
+Luddite/MS
+Ludhiana/M
+Ludwig/M
+Luella/M
+Lufthansa/M
+Luftwaffe/M
+Luger/M
+Lugosi/M
+Luigi/M
+Luis/M
+Luisa/M
+Luke/M
+Lula/M
+Lully/M
+Lulu/M
+Lumiere/M
+Lumi竪re/M
+Luna/M
+Lupe/M
+Lupercalia/M
+Lupus/M
+Luria/M
+Lusaka/M
+Lusitania/M
+Luther/M
+Lutheran/SM
+Lutheranism/MS
+Luvs/M
+Luxembourg/ZMR
+Luxembourger/M
+Luxembourgian
+Luz/M
+Luzon/M
+Lvov/M
+LyX/M
+Lyallpur
+Lycra/M
+Lycurgus/M
+Lydia/M
+Lydian/SM
+Lyell/M
+Lyle/M
+Lyly/M
+Lyman/M
+Lyme/M
+Lynch/M
+Lynchburg/M
+Lynda/M
+Lyndon/M
+Lynette/M
+Lynn/M
+Lynne/M
+Lynnette/M
+Lyon/SM
+Lyons/M
+Lyra/M
+Lysenko/M
+Lysistrata/M
+Lysol/M
+M/SMGB
+MA/M
+MASH
+MB/M
+MBA/M
+MC
+MCI/M
+MD/M
+MDT
+ME
+MEGO/S
+MFA/M
+MGM/M
+MHz
+MI/M
+MIA
+MIDI/M
+MIPS
+MIRV
+MIT/M
+MM
+MN
+MO
+MOOC
+MP/M
+MPEG
+MRI/M
+MS/M
+MSG/M
+MST/M
+MSW
+MT/M
+MTV/M
+MVP/M
+MW
+Maalox/M
+Mabel/M
+Mable/M
+Mac/M
+MacArthur/M
+MacBride/M
+MacDonald/M
+MacLeish/M
+Macao/M
+Macaulay/M
+Macbeth/M
+Maccabees
+Maccabeus/M
+Mace/M
+Macedon/M
+Macedonia/M
+Macedonian/SM
+Mach/M
+Machiavelli/M
+Machiavellian/M
+Macias/M
+Macintosh/M
+Mack/M
+Mackenzie/M
+Mackinac/M
+Mackinaw/M
+Macmillan/M
+Macon/M
+Macumba/M
+Macy/M
+Madagascan/SM
+Madagascar/M
+Madam
+Madden/M
+Maddox/M
+Madeira/SM
+Madeleine/M
+Madeline/M
+Madelyn/M
+Madera/M
+Madge/M
+Madison/M
+Madonna/SM
+Madras/M
+Madrid/M
+Madurai/M
+Mae/M
+Maeterlinck/M
+Mafia/MS
+Mafioso/M
+Magdalena/M
+Magdalene/M
+Magellan/M
+Magellanic/M
+Maggie/M
+Maghreb/M
+Magi
+Maginot/M
+Magnificat
+Magnitogorsk/M
+Magog/M
+Magoo/M
+Magritte/M
+Magsaysay/M
+Magus
+Magyar/SM
+Mahabharata/M
+Maharashtra/M
+Mahavira/M
+Mahayana/M
+Mahayanist/M
+Mahdi/M
+Mahfouz/M
+Mahican/SM
+Mahler/M
+Mai/M
+Maidenform/M
+Maigret/M
+Mailer/M
+Maillol/M
+Maiman/M
+Maimonides/M
+Maine/MZR
+Mainer/M
+Maisie/M
+Maitreya/M
+Maj
+Majesty
+Major/M
+Majorca/M
+Majuro/M
+Makarios/M
+Maker/M
+Malabar/M
+Malabo/M
+Malacca/M
+Malachi/M
+Malagasy/M
+Malamud/M
+Malaprop/M
+Malawi/M
+Malawian/SM
+Malay/MS
+Malaya/M
+Malayalam/M
+Malayan/MS
+Malaysia/M
+Malaysian/MS
+Malcolm/M
+Maldive/MS
+Maldives/M
+Maldivian/MS
+Maldonado/M
+Male/M
+Mali/M
+Malian/SM
+Malibu/M
+Malinda/M
+Malinowski/M
+Mallarme/M
+Mallarm辿/M
+Mallomars/M
+Mallory/M
+Malone/M
+Malory/M
+Malplaquet/M
+Malraux/M
+Malta/M
+Maltese/M
+Malthus/M
+Malthusian/SM
+Mameluke/M
+Mamet/M
+Mamie/M
+Mammon/SM
+Mamore/M
+Man/M
+Managua/M
+Manama/M
+Manasseh/M
+Manchester/M
+Manchu/SM
+Manchuria/M
+Manchurian/M
+Mancini/M
+Mancunian/MS
+Mandalay/M
+Mandarin/M
+Mandela/M
+Mandelbrot/M
+Mandeville/M
+Mandingo/M
+Mandrell/M
+Mandy/M
+Manet/M
+Manfred/M
+Manhattan/SM
+Mani/M
+Manichean/M
+Manila/SM
+Manitoba/M
+Manitoulin/M
+Mankato/M
+Manley/M
+Mann/GM
+Mannheim/M
+Manning/M
+Mansfield/M
+Manson/M
+Manteca/M
+Mantegna/M
+Mantle/M
+Manuel/M
+Manuela/M
+Manx/M
+Mao/M
+Maoism/SM
+Maoist/SM
+Maori/MS
+Mapplethorpe/M
+Maputo/M
+Mar/SM
+Mara/M
+Maracaibo/M
+Marat/M
+Maratha/M
+Marathi/M
+Marathon/M
+Marc/M
+Marceau/M
+Marcel/M
+Marcelino/M
+Marcella/M
+Marcelo/M
+March/MS
+Marci/M
+Marcia/M
+Marciano/M
+Marcie/M
+Marco/MS
+Marconi/M
+Marcos/M
+Marcus/M
+Marcuse
+Marcy/M
+Marduk/M
+Margaret/M
+Margarita/M
+Margarito/M
+Marge/M
+Margery/M
+Margie/M
+Margo/M
+Margot
+Margret/M
+Margrethe/M
+Marguerite/M
+Mari/SM
+Maria/M
+MariaDB/M
+Marian/M
+Mariana/SM
+Marianas/M
+Marianne/M
+Mariano/M
+Maribel/M
+Maricela/M
+Marie/M
+Marietta/M
+Marilyn/M
+Marin/M
+Marina/M
+Marine/SM
+Mario/M
+Marion/M
+Maris/M
+Marisa/M
+Marisol/M
+Marissa/M
+Maritain/M
+Maritza/M
+Mariupol
+Marius/M
+Marjorie/M
+Marjory/M
+Mark/SM
+Markab/M
+Markham/M
+Markov/M
+Marks/M
+Marla/M
+Marlboro/M
+Marlborough/M
+Marlene/M
+Marley/M
+Marlin/M
+Marlon/M
+Marlowe/M
+Marmara/M
+Marne/M
+Maronite/M
+Marple/M
+Marquesas/M
+Marquette/M
+Marquez/M
+Marquis/M
+Marquita/M
+Marrakesh/M
+Marriott/M
+Mars/MS
+Marsala/M
+Marseillaise/MS
+Marseilles/M
+Marsh/M
+Marsha/M
+Marshall/M
+Marta/M
+Martel/M
+Martha/M
+Martial/M
+Martian/SM
+Martin/M
+Martina/M
+Martinez/M
+Martinique/M
+Marty/M
+Marva/M
+Marvell/M
+Marvin/M
+Marx/M
+Marxian
+Marxism/SM
+Marxist/SM
+Mary/M
+Maryann/M
+Maryanne/M
+Maryellen/M
+Maryland/MR
+Marylander/M
+Marylou/M
+Marysville/M
+Masada/M
+Masai/M
+Masaryk/M
+Mascagni/M
+Masefield/M
+Maserati/M
+Maseru/M
+Mashhad/M
+Mason/MS
+Masonic/M
+Masonite/M
+Mass/MS
+Massachusetts/M
+Massasoit/M
+Massenet/M
+Massey/M
+Master/S
+MasterCard/M
+Masters/M
+Mather/M
+Matheson/M
+Mathew/SM
+Mathews/M
+Mathewson/M
+Mathias/M
+Mathis/M
+Matilda/M
+Matisse/M
+Matlab/M
+Matt/M
+Mattel/M
+Matterhorn/M
+Matthew/SM
+Matthews/M
+Matthias/M
+Mattie/M
+Maud/M
+Maude/M
+Maugham/M
+Maui/M
+Mauldin/M
+Maupassant/M
+Maura/M
+Maureen/M
+Mauriac/M
+Maurice/M
+Mauricio/M
+Maurine/M
+Mauritania/M
+Mauritanian/SM
+Mauritian/SM
+Mauritius/M
+Mauro/M
+Maurois/M
+Mauryan/M
+Mauser/M
+Mavis/M
+Max/M
+Maximilian/M
+Maxine/M
+Maxwell/M
+May/SMR
+Maya/SM
+Mayan/MS
+Mayer/M
+Mayfair/M
+Mayflower/M
+Maynard/M
+Mayo/M
+Maypole
+Mayra/M
+Mays/M
+Maytag/M
+Mazama/M
+Mazarin/M
+Mazatlan/M
+Mazda/M
+Mazola/M
+Mazzini/M
+Mb/M
+Mbabane/M
+Mbini/M
+McAdam/M
+McAllen/M
+McBride/M
+McCain/M
+McCall/M
+McCarthy/M
+McCarthyism/M
+McCartney/M
+McCarty/M
+McClain/M
+McClellan/M
+McClure/M
+McConnell/M
+McCormick/M
+McCoy/M
+McCray/M
+McCullough/M
+McDaniel/M
+McDonald/M
+McDonnell/M
+McDowell/M
+McEnroe/M
+McFadden/M
+McFarland/M
+McGee/M
+McGovern/M
+McGowan/M
+McGuffey/M
+McGuire/M
+McHenry/M
+McIntosh/M
+McIntyre/M
+McJob
+McKay/M
+McKee/M
+McKenzie/M
+McKinley/M
+McKinney/M
+McKnight/M
+McLaughlin/M
+McLean/M
+McLeod/M
+McLuhan/M
+McMahon/M
+McMillan/M
+McNamara/M
+McNaughton/M
+McNeil/M
+McPherson/M
+McQueen/M
+McVeigh/M
+Md/M
+Me
+Mead/M
+Meade/M
+Meadows/M
+Meagan/M
+Meany/M
+Mecca/MS
+Medan/M
+Medea/M
+Medellin/M
+Medford/M
+Media/M
+Medicaid/SM
+Medicare/SM
+Medici/M
+Medina/M
+Mediterranean/MS
+Medusa/M
+Meg/M
+Megan/M
+Meghan/M
+Meier/M
+Meighen/M
+Meiji/M
+Meir/M
+Mejia/M
+Mekong/M
+Mel/M
+Melanesia/M
+Melanesian/M
+Melanie/M
+Melba/M
+Melbourne/M
+Melchior/M
+Melchizedek/M
+Melendez/M
+Melinda/M
+Melisa/M
+Melisande/M
+Melissa/M
+Mellon/M
+Melody/M
+Melpomene/M
+Melton/M
+Melva/M
+Melville/M
+Melvin/M
+Memcached/M
+Memling/M
+Memphis/M
+Menander/M
+Mencius/M
+Mencken/M
+Mendel/M
+Mendeleev/M
+Mendelian/M
+Mendelssohn/M
+Mendez/M
+Mendocino/M
+Mendoza/M
+Menelaus/M
+Menelik/M
+Menes/M
+Mengzi
+Menifee/M
+Menkalinan/M
+Menkar/M
+Menkent/M
+Mennen/M
+Mennonite/MS
+Menominee/M
+Menotti/M
+Mensa/M
+Mentholatum/M
+Menuhin/M
+Menzies/M
+Mephisto
+Mephistopheles/M
+Merak/M
+Mercado/M
+Mercator/M
+Merced/M
+Mercedes/M
+Mercer/M
+Mercia/M
+Merck/M
+Mercurochrome/M
+Mercury/SM
+Meredith/M
+Merino/M
+Merle/M
+Merlin/M
+Merlot/M
+Merovingian/M
+Merriam/M
+Merrick/M
+Merrill/M
+Merrimack/M
+Merritt/M
+Merthiolate/M
+Merton/M
+Mervin/M
+Mesa/M
+Mesabi/M
+Meshed/M
+Mesmer/M
+Mesolithic/M
+Mesopotamia/M
+Mesopotamian
+Mesozoic/M
+Messerschmidt/M
+Messiaen/M
+Messiah/M
+Messiahs
+Messianic
+Messieurs
+Metallica/M
+Metamucil/M
+Methodism/SM
+Methodist/SM
+Methuselah/M
+Metternich/M
+Meuse/M
+Mex
+Mexicali/M
+Mexican/MS
+Mexico/M
+Meyer/MS
+Meyerbeer/M
+Meyers/M
+Mfume/M
+Mg/M
+Mgr
+MiG/M
+Mia/M
+Miami/MS
+Miaplacidus/M
+Micah/M
+Micawber/M
+Mich/M
+Michael/M
+Michaelmas/MS
+Micheal/M
+Michel/M
+Michelangelo/M
+Michele/M
+Michelin/M
+Michelle/M
+Michelob/M
+Michelson/M
+Michigan/M
+Michigander/MS
+Michiganite
+Mick/M
+Mickey/M
+Mickie/M
+Micky/M
+Micmac/SM
+Micronesia/M
+Micronesian/M
+Microsoft/M
+Midas/M
+Middleton/M
+Middletown/M
+Mideast
+Mideastern
+Midland/MS
+Midway/M
+Midwest/M
+Midwestern/MR
+Miguel/M
+Mike/M
+Mikhail/M
+Mikoyan/M
+Milagros/M
+Milan/M
+Milanese
+Mildred/M
+Miles/M
+Milford/M
+Milken/M
+Mill/SMR
+Millard/M
+Millay/M
+Miller/M
+Millet/M
+Millicent/M
+Millie/M
+Millikan/M
+Mills/M
+Milne/M
+Milo/M
+Milosevic/M
+Milquetoast/M
+Miltiades/M
+Milton/M
+Miltonian
+Miltonic/M
+Miltown/M
+Milwaukee/M
+Mimi/M
+Mimosa/M
+Min/M
+Minamoto/M
+Mindanao/M
+Mindoro/M
+Mindy/M
+Minerva/M
+Ming/M
+Mingus/M
+Minn
+Minneapolis/M
+Minnelli/M
+Minnesota/M
+Minnesotan/SM
+Minnie/M
+Minoan/MS
+Minolta/M
+Minos/M
+Minot/M
+Minotaur/M
+Minsk/M
+Minsky/M
+Mintaka/M
+Minuit/M
+Minuteman/M
+Miocene/M
+Mir/M
+Mira/M
+Mirabeau/M
+Mirach/M
+Miranda/M
+Mirfak/M
+Miriam/M
+Miro/M
+Mirzam/M
+Miskito/M
+Miss
+Mississauga/M
+Mississippi/M
+Mississippian/SM
+Missoula/M
+Missouri/M
+Missourian/MS
+Missy/M
+Mistassini/M
+Mister
+Mistress
+Misty/M
+Mitch/M
+Mitchel/M
+Mitchell/M
+Mitford/M
+Mithra/M
+Mithridates/M
+Mitsubishi/M
+Mitterrand/M
+Mitty/M
+Mitzi/M
+Mixtec/M
+Mizar/M
+Mk
+Mlle
+Mme/S
+Mn/M
+Mnemosyne/M
+Mo/M
+Mobil/M
+Mobile/M
+Mobutu/M
+Modesto/M
+Modigliani/M
+Moe/M
+Moet/M
+Mogadishu/M
+Mogul/MS
+Mohacs/M
+Mohamed/M
+Mohammad/M
+Mohammedan/SM
+Mohammedanism/SM
+Mohave/SM
+Mohawk/SM
+Mohegan
+Moho/M
+Mohorovicic/M
+Moira/M
+Moises/M
+Moiseyev/M
+Mojave/SM
+Moldavia/M
+Moldavian
+Moldova/M
+Moldovan
+Moliere/M
+Molina/M
+Moll/M
+Mollie/M
+Molly/M
+Molnar/M
+Moloch/M
+Molokai/M
+Molotov/M
+Moluccas/M
+Mombasa/M
+Mon/SM
+Mona/M
+Monacan
+Monaco/M
+Mondale/M
+Monday/SM
+Mondrian/M
+Monegasque/SM
+Monera/M
+Monessen/M
+Monet/M
+MongoDB/M
+Mongol/SM
+Mongolia/M
+Mongolian/SM
+Mongolic/M
+Mongoloid
+Monica/M
+Monique/M
+Monk/M
+Monmouth/M
+Monongahela/M
+Monroe/M
+Monrovia/M
+Monsanto/M
+Monsieur/M
+Monsignor/SM
+Mont/M
+Montague/M
+Montaigne/M
+Montana/M
+Montanan/SM
+Montcalm/M
+Monte/M
+Montenegrin/M
+Montenegro/M
+Monterey/M
+Monterrey/M
+Montesquieu/M
+Montessori/M
+Monteverdi/M
+Montevideo/M
+Montezuma/M
+Montgolfier/M
+Montgomery/M
+Monticello/M
+Montoya/M
+Montpelier/M
+Montrachet/M
+Montreal/M
+Montserrat/M
+Monty/M
+Moody/M
+Moog/M
+Moon/M
+Mooney/M
+Moor/SM
+Moore/M
+Moorish/M
+Morales/M
+Moran/M
+Moravia/M
+Moravian/M
+Mordred/M
+More/M
+Moreno/M
+Morgan/SM
+Morgantown/M
+Moriarty/M
+Morin/M
+Morison/M
+Morita/M
+Morley/M
+Mormon/SM
+Mormonism/SM
+Moro/M
+Moroccan/SM
+Morocco/M
+Moroni/M
+Morpheus/M
+Morphy/M
+Morris/M
+Morrison/M
+Morristown/M
+Morrow/M
+Morse/M
+Mort/M
+Mortimer/M
+Morton/M
+Mosaic/M
+Moscow/M
+Moseley/M
+Moselle/M
+Moses/M
+Moslem/M
+Mosley/M
+Moss/M
+Mosul/M
+Motorola/M
+Motown/M
+Motrin/M
+Mott/M
+Moulton/M
+Mount/M
+Mountbatten/M
+Mountie/MS
+Moussorgsky/M
+Mouthe/M
+Mouton/M
+Mowgli/M
+Mozambican/SM
+Mozambique/M
+Mozart/M
+Mozilla/M
+Mr/SM
+Ms/S
+Msgr
+Mt
+Muawiya/M
+Mubarak/M
+Mueller/M
+Muenster/MS
+Mugabe/M
+Muhammad/M
+Muhammadan/MS
+Muhammadanism/SM
+Muir/M
+Mujib/M
+Mulder/M
+Mullen/M
+Muller/M
+Mulligan/M
+Mullikan/M
+Mullins/M
+Mulroney/M
+Multan/M
+Multics
+Mumbai/M
+Mumford/M
+Munch/M
+Munchhausen/M
+Muncie/M
+Munich/M
+Munoz/M
+Munro/M
+Munster/M
+Muppet/M
+Murasaki/M
+Murat/M
+Murchison/M
+Murcia
+Murdoch/M
+Murfreesboro/M
+Muriel/M
+Murillo/M
+Murine/M
+Murmansk/M
+Murphy/M
+Murray/M
+Murrieta/M
+Murrow/M
+Murrumbidgee/M
+Muscat/M
+Muscovite/M
+Muscovy/M
+Muse/M
+Musharraf/M
+Musial/M
+Muskegon/M
+Muskogee/M
+Muslim/MS
+Mussolini/M
+Mussorgsky/M
+Mutsuhito/M
+Muzak/M
+MySQL/M
+MySpace/M
+Myanmar/M
+Mycenae/M
+Mycenaean/M
+Myers/M
+Mylar/MS
+Myles/M
+Myra/M
+Myrdal/M
+Myrna/M
+Myron/M
+Myrtle/M
+Mysore/M
+Myst/M
+M端nchhausen/M
+N'Djamena
+N/MD
+NAACP/M
+NAFTA/M
+NASA/M
+NASCAR/M
+NASDAQ/M
+NATO/M
+NB
+NBA/M
+NBC/M
+NBS
+NC
+NCAA/M
+NCO
+ND
+NE/M
+NEH
+NF
+NFC
+NFL/M
+NH
+NHL/M
+NIH
+NIMBY
+NJ
+NLRB
+NM
+NORAD/M
+NOW
+NP
+NPR/M
+NR
+NRA
+NRC
+NS
+NSA/M
+NSC
+NSF
+NSFW
+NT
+NV
+NVIDIA/M
+NW/M
+NWT
+NY
+NYC
+NYSE
+NZ
+Na/M
+Nabisco/M
+Nabokov/M
+Nader/M
+Nadia/M
+Nadine/M
+Nagasaki/M
+Nagoya/M
+Nagpur/M
+Nagy/M
+Nahuatl/MS
+Nahum/M
+Naipaul/M
+Nair/M
+Nairobi/M
+Naismith/M
+Nam/M
+Namath/M
+Namibia/M
+Namibian/MS
+Nampa/M
+Nan/M
+Nanak/M
+Nanchang/M
+Nancy/M
+Nanette/M
+Nanjing/M
+Nannie/M
+Nanook/M
+Nansen/M
+Nantes/M
+Nantucket/M
+Naomi/M
+Napa/M
+Naphtali/M
+Napier/M
+Naples/M
+Napoleon/MS
+Napoleonic/M
+Napster/M
+Narcissus/M
+Narmada/M
+Narnia/M
+Narraganset
+Narragansett/M
+Nash/M
+Nashua/M
+Nashville/M
+Nassau/M
+Nasser/M
+Nat/M
+Natalia/M
+Natalie/M
+Natasha/M
+Natchez/M
+Nate/MN
+Nathan/SM
+Nathaniel/M
+Nathans/M
+Nation/M
+Nationwide/M
+Nativity/M
+Nature
+Naugahyde/M
+Nauru/M
+Nautilus/M
+Navajo/SM
+Navajoes
+Navarre/M
+Navarro/M
+Navratilova/M
+Navy
+Nazarene/M
+Nazareth/M
+Nazca/M
+Nazi/SM
+Nazism/MS
+Nb/M
+Nd/M
+Ndjamena/M
+Ne/M
+NeWS
+NeWSes
+Neal/M
+Neanderthal/SM
+Neapolitan/M
+Neb
+Nebr
+Nebraska/M
+Nebraskan/MS
+Nebuchadnezzar/M
+Ned/M
+Nefertiti/M
+Negev/M
+Negress/MS
+Negritude
+Negro/MS
+Negroes
+Negroid/SM
+Negros/M
+Nehemiah/M
+Nehru/M
+Neil/M
+Nelda/M
+Nell/M
+Nellie/M
+Nelly/M
+Nelsen/M
+Nelson/M
+Nembutal/M
+Nemesis/M
+Neo/M
+Neogene/M
+Neolithic
+Nepal/M
+Nepalese/M
+Nepali/MS
+Neptune/M
+Nereid/M
+Nerf/M
+Nero/M
+Neruda/M
+Nescafe/M
+Nesselrode/M
+Nestle/M
+Nestor/M
+Nestorius/M
+Netflix/M
+Netherlander/SM
+Netherlands/M
+Netscape/M
+Nettie/M
+Netzahualcoyotl/M
+Nev/M
+Neva/M
+Nevada/M
+Nevadan/SM
+Nevadian
+Nevis/M
+Nevsky/M
+Newark/M
+Newburgh/M
+Newcastle/M
+Newfoundland/MRS
+Newman/M
+Newport/M
+Newsweek/M
+Newton/M
+Newtonian/M
+Nexis/M
+Ngaliema/M
+Nguyen/M
+Ni/M
+Niagara/M
+Niamey/M
+Nibelung/M
+Nicaea/M
+Nicaragua/M
+Nicaraguan/SM
+Niccolo/M
+Nice/M
+Nicene/M
+Nichiren/M
+Nicholas/M
+Nichole/M
+Nichols/M
+Nicholson/M
+Nick/M
+Nickelodeon/M
+Nicklaus/M
+Nickolas/M
+Nicobar/M
+Nicodemus/M
+Nicola/SM
+Nicolas/M
+Nicole/M
+Nicosia/M
+Niebuhr/M
+Nielsen/M
+Nietzsche/M
+Nieves/M
+Nigel/M
+Niger/M
+Nigeria/M
+Nigerian/MS
+Nigerien/M
+Nightingale/M
+Nijinsky/M
+Nike/M
+Nikita/M
+Nikkei/M
+Nikki/M
+Nikolai/M
+Nikolayev/M
+Nikon/M
+Nile/M
+Nimitz/M
+Nimrod/M
+Nina/M
+Nineveh/M
+Nintendo/M
+Niobe/M
+Nippon/M
+Nipponese/M
+Nirenberg/M
+Nirvana/M
+Nisan/M
+Nisei/M
+Nissan/M
+Nita/M
+Nivea/M
+Nixon/M
+Nkrumah/M
+No/SM
+NoDoz/M
+Noah/M
+Nobel/M
+Nobelist/MS
+Noble/M
+Noe/M
+Noel/SM
+Noelle/M
+Noemi/M
+Nokia/M
+Nola/M
+Nolan/M
+Nome/M
+Nona/M
+Nootka/M
+Nora/M
+Norbert/M
+Norberto/M
+Nordic/MS
+Noreen/M
+Norfolk/M
+Noriega/M
+Norma/M
+Normal/M
+Norman/MS
+Normand/M
+Normandy/M
+Norplant/M
+Norris/M
+Norse/M
+Norseman/M
+Norsemen/M
+North/M
+Northampton/M
+Northeast/MS
+Northern/MR
+Northerner/M
+Northrop/M
+Northrup/M
+Norths
+Northwest/SM
+Norton/M
+Norw
+Norway/M
+Norwegian/SM
+Norwich/M
+Nosferatu/M
+Nostradamus/M
+Nottingham/M
+Nouakchott/M
+Noumea/M
+Nov/M
+Nova/M
+Novartis/M
+November/MS
+Novgorod/M
+Novocain/MS
+Novocaine
+Novokuznetsk/M
+Novosibirsk/M
+Noxzema/M
+Noyce/M
+Noyes/M
+Np/M
+Nubia/M
+Nubian/M
+Nukualofa/M
+Numbers/M
+Nunavut/M
+Nunez/M
+Nunki/M
+Nuremberg/M
+Nureyev/M
+NutraSweet/M
+NyQuil/M
+Nyasa/M
+Nyerere/M
+O'Brien/M
+O'Casey/M
+O'Connell/M
+O'Connor/M
+O'Donnell/M
+O'Hara/M
+O'Higgins/M
+O'Keeffe/M
+O'Neil/M
+O'Neill/M
+O'Rourke/M
+O'Toole/M
+O/SM
+OAS/M
+OB
+OCR
+OD/SM
+OE
+OED
+OH
+OHSA/M
+OJ
+OK/SMDG
+OMB/M
+ON
+OPEC/M
+OR
+OS/M
+OSHA/M
+OSes
+OT
+OTB
+OTC
+OTOH
+Oahu/M
+Oakland/M
+Oakley/M
+Oates/M
+Oaxaca/M
+Ob/M
+Obadiah/M
+Obama/M
+Obamacare
+Oberlin/M
+Oberon/M
+Ocala/M
+Ocaml/M
+Occam/M
+Occident
+Occidental/MS
+Oceania/M
+Oceanside
+Oceanus/M
+Ochoa/M
+Oct/M
+Octavia/M
+Octavian/M
+Octavio/M
+October/SM
+Odell/M
+Oder/M
+Odessa/M
+Odets/M
+Odin/M
+Odis/M
+Odom/M
+Odysseus/M
+Odyssey/M
+Oedipal/M
+Oedipus/M
+Oersted/M
+Ofelia/M
+Offenbach/M
+OfficeMax/M
+Ogbomosho/M
+Ogden/M
+Ogilvy/M
+Oglethorpe/M
+Ohio/M
+Ohioan/SM
+Oise/M
+Ojibwa/SM
+Okayama
+Okeechobee/M
+Okefenokee/M
+Okhotsk/M
+Okinawa/M
+Okinawan
+Okla
+Oklahoma/M
+Oklahoman/M
+Oktoberfest/M
+Ola/M
+Olaf/M
+Olajuwon/M
+Olav/M
+Oldenburg/M
+Oldfield/M
+Oldsmobile/M
+Olduvai/M
+Olen/M
+Olenek/M
+Olga/M
+Oligocene/M
+Olin/M
+Olive/MR
+Oliver/M
+Olivetti/M
+Olivia/M
+Olivier/M
+Ollie/M
+Olmec/M
+Olmsted/M
+Olsen/M
+Olson/M
+Olympia/SM
+Olympiad/MS
+Olympian/MS
+Olympic/SM
+Olympics/M
+Olympus/M
+Omaha/MS
+Oman/M
+Omani/MS
+Omar/M
+Omayyad/M
+Omdurman/M
+Omnipotent
+Omsk/M
+Onassis/M
+Oneal/M
+Onega/M
+Onegin/M
+Oneida/MS
+Onion/M
+Ono/M
+Onondaga/MS
+Onsager/M
+Ont
+Ontarian
+Ontario/M
+Oort/M
+Opal/M
+Opel/M
+OpenOffice/M
+Ophelia/M
+Ophiuchus/M
+Oppenheimer/M
+Opposition
+Oprah/M
+Ora/M
+Oracle/M
+Oran/M
+Orange/M
+Oranjestad/M
+Orbison/M
+Ordovician/M
+Ore/N
+Oreg
+Oregon/M
+Oregonian/SM
+Orem/M
+Oreo/M
+Orestes/M
+Orient/M
+Oriental/MS
+Orientalism
+Orin/M
+Orinoco/M
+Orion/M
+Oriya/M
+Orizaba/M
+Orkney/M
+Orlando/M
+Orleans/M
+Orlon/MS
+Orly/M
+Orpheus/M
+Orphic/M
+Orr/M
+Ortega/M
+Orthodox
+Ortiz/M
+Orval/M
+Orville/M
+Orwell/M
+Orwellian/M
+Os/M
+Osage/MS
+Osaka/M
+Osbert/M
+Osborn/M
+Osborne/M
+Oscar/MS
+Osceola/M
+Osgood/M
+Oshawa/M
+Oshkosh/M
+Osiris/M
+Oslo/M
+Osman/M
+Ostrogoth/M
+Ostwald/M
+Osvaldo/M
+Oswald/M
+Othello/M
+Otis/M
+Ottawa/SM
+Otto/M
+Ottoman/M
+Ouagadougou/M
+Ouija/MS
+Ovid/M
+Owen/SM
+Owens/M
+Owensboro/M
+Oxford/SM
+Oxnard/M
+Oxonian/M
+Oxus/M
+Oxycontin/M
+Oz/M
+Ozark/MS
+Ozarks/M
+Ozymandias/M
+Ozzie/M
+P/MN
+PA/M
+PAC/M
+PARC/S
+PASCAL
+PBS/M
+PBX
+PC/SM
+PCB
+PCMCIA
+PCP/M
+PD
+PDF
+PDQ
+PDT
+PE
+PET/M
+PFC
+PG
+PGP
+PHP/M
+PIN
+PJ's
+PLO/M
+PM/SMDG
+PMS/M
+PO
+POW/M
+PP
+PPS
+PR
+PRC/M
+PRO
+PS/M
+PST/M
+PT
+PTA/M
+PTO
+PVC/M
+PW
+PX
+Pa/M
+Paar/M
+Pablo/M
+Pablum/M
+Pabst/M
+Pace/M
+Pacheco/M
+Pacific/M
+Pacino/M
+Packard/M
+Padang
+Paderewski/M
+Padilla/M
+Paganini/M
+Page/M
+Paglia/M
+Pahlavi/M
+Paige/M
+Paine/M
+Paiute/SM
+Pakistan/M
+Pakistani/SM
+Palau/M
+Palembang/M
+Paleocene/M
+Paleogene/M
+Paleolithic/M
+Paleozoic/M
+Palermo/M
+Palestine/M
+Palestinian/SM
+Palestrina/M
+Paley/M
+Palikir/M
+Palisades/M
+Palladio/M
+Palmdale/M
+Palmer/M
+Palmerston/M
+Palmolive/M
+Palmyra/M
+Palomar/M
+Pam/M
+Pamela/M
+Pamirs/M
+Pampers/M
+Pan/M
+Panama/SM
+Panamanian/MS
+Panasonic/M
+Pandora/M
+Pangaea/M
+Pankhurst/M
+Panmunjom/M
+Pansy/M
+Pantagruel/M
+Pantaloon/M
+Pantheon/M
+Panza/M
+Paracelsus/M
+Paraclete/M
+Paradise
+Paraguay/M
+Paraguayan/MS
+Paralympic/S
+Paramaribo/M
+Paramount/M
+Parana/M
+Paran叩/M
+Parcheesi/M
+Pareto/M
+Paris/M
+Parisian/MS
+Park/SMR
+Parker/M
+Parkersburg/M
+Parkinson/M
+Parkinsonism
+Parkman/M
+Parks/M
+Parliament/M
+Parmenides
+Parmesan/MS
+Parnassus/MS
+Parnell/M
+Parr/M
+Parrish/M
+Parsee/SM
+Parsi/MS
+Parsifal/M
+Parsons/M
+Parthenon/M
+Parthia/M
+Pasadena/M
+Pascagoula/M
+Pascal/SM
+Pasco/M
+Pasquale/M
+Passion/SM
+Passover/MS
+Pasternak/M
+Pasteur/M
+Pat/M
+Patagonia/M
+Patagonian/M
+Pate/M
+Patel/M
+Paterson/M
+Patna/M
+Patrica/M
+Patrice/M
+Patricia/M
+Patrick/M
+Patsy/M
+Patterson/M
+Patti/M
+Patton/M
+Patty/M
+Paul/GM
+Paula/M
+Paulette/M
+Pauli/M
+Pauline/M
+Pauling/M
+Pavarotti/M
+Pavlov/M
+Pavlova/M
+Pavlovian/M
+Pawnee/SM
+PayPal/M
+Payne/M
+Pb/M
+Pd/M
+Peabody/M
+Peace/M
+Peale/M
+Pearl/M
+Pearlie/M
+Pearson/M
+Peary/M
+Pechora/M
+Peck/M
+Peckinpah/M
+Pecos/M
+Pedro/M
+Peel/M
+Peg/M
+Pegasus/MS
+Peggy/M
+Pei/M
+Peiping/M
+Pekinese/M
+Peking/SM
+Pekingese/SM
+Pele/M
+Pelee/M
+Peloponnese/M
+Pembroke/M
+Pen/M
+Pena/M
+Penderecki/M
+Penelope/M
+Penn/M
+Penna
+Penney/M
+Pennington/M
+Pennsylvania/M
+Pennsylvanian/MS
+Penny/M
+Pennzoil/M
+Pensacola/M
+Pentagon/M
+Pentateuch/M
+Pentax/M
+Pentecost/SM
+Pentecostal/MS
+Pentecostalism
+Pentium/SM
+Peoria/M
+Pepin/M
+Pepsi/M
+Pepys/M
+Pequot/M
+Percheron/M
+Percival/M
+Percy/M
+Perelman/M
+Perez/M
+Periclean/M
+Pericles/M
+Perkins/M
+Perl/SM
+Perm/M
+Permalloy/M
+Permian/M
+Pernod/M
+Peron/M
+Perot/M
+Perrier/M
+Perry/RM
+Perseid/M
+Persephone/M
+Persepolis/M
+Perseus/M
+Pershing/M
+Persia/M
+Persian/SM
+Perth/M
+Peru/M
+Peruvian/MS
+Peshawar/M
+Petain/M
+Petaluma/M
+Pete/RMZ
+Peter/M
+Peters/MN
+Petersen/M
+Peterson/M
+Petra/M
+Petrarch/M
+Petty/M
+Peugeot/M
+Pfc
+Pfizer/M
+PhD/M
+Phaedra/M
+Phaethon/M
+Phanerozoic/M
+Pharaoh/M
+Pharaohs
+Pharisaic
+Pharisaical
+Pharisee/MS
+Phekda/M
+Phelps/M
+Phidias/M
+Phil/MY
+Philadelphia/M
+Philby/M
+Philemon/M
+Philip/MS
+Philippe/M
+Philippians/M
+Philippine/SM
+Philippines/M
+Philips/M
+Philistine/M
+Phillip/SM
+Phillipa/M
+Phillips/M
+Philly/M
+Phipps/M
+Phobos/M
+Phoebe/M
+Phoenicia/M
+Phoenician/SM
+Phoenix/M
+Photostat/MS
+Photostatted
+Photostatting
+Phrygia/M
+Phyllis/M
+Piaf/M
+Piaget/M
+Pianola/M
+Picasso/M
+Piccadilly/M
+Pickering/M
+Pickett/M
+Pickford/M
+Pickwick/M
+Pict/M
+Piedmont/M
+Pierce/M
+Pierre/M
+Pierrot/M
+Pike/M
+Pilate/MS
+Pilates/M
+Pilcomayo/M
+Pilgrim/SM
+Pillsbury/M
+Pinatubo/M
+Pincus/M
+Pindar/M
+Pinkerton/M
+Pinocchio/M
+Pinochet/M
+Pinter/M
+Pinyin
+Pippin/M
+Piraeus/M
+Pirandello/M
+Pisa/M
+Pisces/M
+Pisistratus/M
+Pissaro/M
+Pitcairn/M
+Pitt/SM
+Pittman/M
+Pitts/M
+Pittsburgh/M
+Pittsfield/M
+Pius/M
+Pizarro/M
+Pkwy
+Pl
+Place
+Planck/M
+Plano
+Plantagenet/M
+Plasticine/M
+Plataea/M
+Plath/M
+Plato/M
+Platonic
+Platonism/M
+Platonist/M
+Platte/M
+Plautus/M
+PlayStation/M
+Playboy/M
+Playtex/M
+Pleiades/M
+Pleistocene/M
+Plexiglas/MS
+Pliny/M
+Pliocene/SM
+Plutarch/M
+Pluto/M
+Plymouth/M
+Pm/M
+Po/M
+Pocahontas/M
+Pocatello/M
+Pocono/SM
+Poconos/M
+Podgorica/M
+Podhoretz/M
+Podunk/M
+Poe/M
+Pogo/M
+Poincare/M
+Poincar辿/M
+Poiret/M
+Poirot/M
+Poisson/M
+Poitier/M
+Pokemon/M
+Pok辿mon/M
+Pol/MY
+Poland/M
+Polanski/M
+Polaris/M
+Polaroid/MS
+Pole/SM
+Polish/M
+Politburo/M
+Polk/M
+Pollard/M
+Pollock/M
+Pollux/M
+Polly/M
+Pollyanna/M
+Polo/M
+Poltava/M
+Polyhymnia/M
+Polynesia/M
+Polynesian/MS
+Polyphemus/M
+Pomerania/M
+Pomeranian/M
+Pomona/M
+Pompadour/M
+Pompeian
+Pompeii/M
+Pompey/M
+Ponce/M
+Pontchartrain/M
+Pontiac/M
+Pontianak/M
+Pooh/M
+Poole/M
+Poona/M
+Pope/M
+Popeye/M
+Popocatepetl/M
+Popper/M
+Poppins/M
+Popsicle/M
+Porfirio/M
+Porrima/M
+Porsche/M
+Port/MR
+Porter/M
+Porterville/M
+Portia/M
+Portland/M
+Porto/M
+Portsmouth/M
+Portugal/M
+Portuguese/M
+Poseidon/M
+Post/M
+PostgreSQL/M
+Potemkin/M
+Potomac/M
+Potsdam/M
+Pottawatomie/M
+Potter/M
+Potts/M
+Pottstown/M
+Poughkeepsie/M
+Pound/M
+Poussin/M
+Powell/M
+PowerPC/M
+PowerPoint/M
+Powers/M
+Powhatan/M
+Poznan/M
+Pr/M
+Prada/M
+Prado/M
+Praetorian/M
+Prague/M
+Praia/M
+Prakrit/M
+Pratchett/M
+Pratt/M
+Pravda/M
+Praxiteles/M
+Preakness/M
+Precambrian/M
+Preminger/M
+Premyslid/M
+Prensa/M
+Prentice/M
+Pres
+Presbyterian/SM
+Presbyterianism/MS
+Prescott/M
+Presley/M
+Preston/M
+Pretoria/M
+Priam/M
+Pribilof/M
+Price/M
+Priceline/M
+Priestley/M
+Prince/M
+Princeton/M
+Principe/M
+Priscilla/M
+Prius/M
+Private
+Procrustean/M
+Procrustes/M
+Procter/M
+Procyon/M
+Prof
+Prohibition
+Prokofiev/M
+Promethean/M
+Prometheus/M
+Prophets
+Proserpina/M
+Proserpine/M
+Protagoras/M
+Proterozoic/M
+Protestant/MS
+Protestantism/SM
+Proteus/M
+Proudhon/M
+Proust/M
+Provencal/MS
+Provence/M
+Proven巽al/M
+Proverbs
+Providence/SM
+Provo/M
+Prozac/MS
+Prudence/M
+Prudential/M
+Pruitt/M
+Prussia/M
+Prussian/MS
+Prut/M
+Pryor/M
+Psalms/M
+Psalter/MS
+Psyche/M
+Pt/M
+Ptah/M
+Ptolemaic/M
+Ptolemy/SM
+Pu/M
+Puccini/M
+Puck/M
+Puckett/M
+Puebla/M
+Pueblo/M
+Puerto
+Puget/M
+Pugh/M
+Pulaski/M
+Pulitzer/M
+Pullman/MS
+Punch/M
+Punic/M
+Punjab/M
+Punjabi/M
+Purana/M
+Purcell/M
+Purdue/M
+Purgatory
+Purim/MS
+Purina/M
+Puritan/M
+Puritanism/MS
+Purus/M
+Pusan/M
+Pusey/M
+Pushkin/M
+Pushtu/M
+Putin/M
+Putnam/M
+Puzo/M
+Pvt
+PyTorch/M
+Pygmalion/M
+Pygmy/SM
+Pyle/M
+Pym/M
+Pynchon/M
+Pyongyang/M
+Pyotr/M
+Pyrenees/M
+Pyrex/MS
+Pyrrhic/M
+Pythagoras/M
+Pythagorean/M
+Pythias/M
+Python/M
+P辿tain/M
+P担rto/M
+Q
+QA
+QB
+QC
+QED
+QM
+QWERTY
+Qaddafi/M
+Qantas/M
+Qatar/M
+Qatari/MS
+Qingdao/M
+Qinghai/M
+Qiqihar/M
+Qom/M
+Quaalude/M
+Quaker/MS
+Quakerism/SM
+Qualcomm/M
+Quaoar/M
+Quasimodo/M
+Quaternary/M
+Quayle/M
+Que
+Quebec/M
+Quebecker
+Quebecois/M
+Quechua/M
+Queen/MS
+Queens/M
+Queensland/M
+Quentin/M
+Quetzalcoatl/M
+Quezon/M
+Quincy/M
+Quinn/M
+Quintilian/M
+Quinton/M
+Quirinal/M
+Quisling/M
+Quito/M
+Quixote/M
+Quixotism/M
+Qumran/M
+Quonset/M
+Qur'an/MS
+Qur'anic
+Quran
+Quranic
+Qu辿becois/M
+R/MD
+RAF/M
+RAM/SM
+RBI
+RC
+RCA/M
+RCMP
+RD
+RDA
+RDS/M
+REIT
+REM/SM
+RF
+RFC/S
+RFD
+RI
+RIF
+RIP
+RISC
+RN/M
+RNA/M
+ROFL
+ROM/M
+ROTC/M
+RP
+RR
+RSFSR
+RSI
+RSV
+RSVP
+RTFM
+RV/SM
+Ra/M
+Rabat/M
+Rabelais/M
+Rabelaisian/M
+Rabin/M
+Rachael/M
+Rachel/M
+Rachelle/M
+Rachmaninoff/M
+Racine/M
+Radcliff/M
+Radcliffe/M
+Rae/M
+Rafael/M
+Raffles/M
+Ragnarok/M
+Ragnar旦k/M
+Rainier/M
+Raleigh/M
+Ralph/M
+Rama/M
+Ramada/M
+Ramadan/MS
+Ramakrishna/M
+Ramanujan/M
+Ramayana/M
+Rambo/M
+Ramirez/M
+Ramiro/M
+Ramon/M
+Ramona/M
+Ramos/M
+Ramsay/M
+Ramses/M
+Ramsey/M
+Rand/M
+Randal/M
+Randall/M
+Randell/M
+Randi/M
+Randolph/M
+Randy/M
+Rangoon/M
+Rankin/M
+Rankine/M
+Raoul/M
+Raphael/M
+Rappaport/M
+Rapunzel/M
+Raquel/M
+Rasalgethi/M
+Rasalhague/M
+Rasmussen/M
+Rasputin/M
+Rasta
+Rastaban/M
+Rastafarian/MS
+Rastafarianism
+Rather/M
+Ratliff/M
+Raul/M
+Ravel/M
+Rawalpindi/M
+Ray/M
+RayBan/M
+Rayburn/M
+Rayleigh/M
+Raymond/M
+Raymundo/M
+Rb/M
+Rd
+Re/M
+Reading/M
+Reagan/M
+Reaganomics/M
+Realtor/M
+Reasoner/M
+Reba/M
+Rebekah/M
+Recife/M
+Reconstruction/M
+Red/SM
+Redding/M
+Redeemer/M
+Redford/M
+Redgrave/M
+Redis/M
+Redmond/M
+Redshift/M
+Reebok/M
+Reed/M
+Reese/M
+Reeves/M
+Reformation/MS
+Refugio/M
+Reggie/M
+Regina/M
+Reginae/M
+Reginald/M
+Regor/M
+Regulus/M
+Rehnquist/M
+Reich/M
+Reichstag's
+Reid/M
+Reilly/M
+Reinaldo/M
+Reinhardt/M
+Reinhold/M
+Remarque/M
+Rembrandt/M
+Remington/M
+Remus/M
+Rena/M
+Renaissance/SM
+Renascence
+Renault/M
+Rene/M
+Renee/M
+Reno/M
+Renoir/M
+Rep
+Representative
+Republican/SM
+Republicanism
+Requiem/MS
+Resistance
+Restoration/M
+Resurrection
+Reuben/M
+Reunion/M
+Reuters/M
+Reuther/M
+Rev
+Reva/M
+Revelation/SM
+Revelations/M
+Revere/M
+Reverend/M
+Revlon/M
+Rex/M
+Reyes/M
+Reykjavik/M
+Reyna/M
+Reynaldo/M
+Reynolds/M
+Rf/M
+Rh/M
+Rhea/M
+Rhee/M
+Rheingau/M
+Rhenish/M
+Rhiannon/M
+Rhine/M
+Rhineland/M
+Rhoda/M
+Rhode/S
+Rhodes/M
+Rhodesia/M
+Rhodesian
+Rhonda/M
+Rhone/M
+Ribbentrop/M
+Ricardo/M
+Rice/M
+Rich/M
+Richard/MS
+Richards/M
+Richardson/M
+Richelieu/M
+Richie/M
+Richmond/M
+Richter/M
+Richthofen/M
+Rick/M
+Rickenbacker/M
+Rickey/M
+Rickie/M
+Rickover/M
+Ricky/M
+Rico/M
+Riddle/M
+Ride/M
+Riefenstahl/M
+Riel/M
+Riemann/M
+Riesling/MS
+Riga/M
+Rigel/M
+Riggs/M
+Right
+Rigoberto/M
+Rigoletto/M
+Riley/M
+Rilke/M
+Rimbaud/M
+Ringling/M
+Ringo/M
+Rio/SM
+Rios/M
+Ripley/M
+Risorgimento/M
+Rita/M
+Ritalin/M
+Ritz/M
+Rivas/M
+Rivera/M
+Rivers/M
+Riverside/M
+Riviera/MS
+Riyadh/M
+Rizal/M
+Rn/M
+Roach/M
+Roanoke/M
+Rob/M
+Robbie/M
+Robbin/MS
+Robbins/M
+Robby/M
+Roberson/M
+Robert/MS
+Roberta/M
+Roberto/M
+Roberts/M
+Robertson/M
+Robeson/M
+Robespierre/M
+Robin/M
+Robinson/M
+Robitussin/M
+Robles/M
+Robson/M
+Robt/M
+Robyn/M
+Rocco/M
+Rocha/M
+Rochambeau/M
+Roche/M
+Rochelle/M
+Rochester/M
+Rock/M
+Rockefeller/M
+Rockford/M
+Rockies/M
+Rockne/M
+Rockwell/M
+Rocky/SM
+Rod/M
+Roddenberry/M
+Roderick/M
+Rodger/MS
+Rodgers/M
+Rodin/M
+Rodney/M
+Rodolfo/M
+Rodrick/M
+Rodrigo/M
+Rodriguez/M
+Rodriquez/M
+Roeg/M
+Roentgen
+Rogelio/M
+Roger/MS
+Rogers/M
+Roget/M
+Rojas/M
+Roku/M
+Rolaids/M
+Roland/M
+Rolando/M
+Rolex/M
+Rolland/M
+Rollerblade/M
+Rollins/M
+Rolodex/M
+Rolvaag/M
+Rom
+Roman/MS
+Romanesque/MS
+Romania/M
+Romanian/MS
+Romano/M
+Romanov/M
+Romans/M
+Romansh/M
+Romantic
+Romanticism
+Romany/SM
+Rome/SM
+Romeo/M
+Romero/M
+Rommel/M
+Romney/M
+Romulus/M
+Ron/M
+Ronald/M
+Ronda/M
+Ronnie/M
+Ronny/M
+Ronstadt/M
+Rontgen
+Rooney/M
+Roosevelt/M
+Root/M
+Roquefort/SM
+Rorschach/M
+Rory/M
+Rosa/M
+Rosales/M
+Rosalie/M
+Rosalind/M
+Rosalinda/M
+Rosalyn/M
+Rosanna/M
+Rosanne/M
+Rosario/M
+Roscoe/M
+Rose/M
+Roseann/M
+Roseau/M
+Rosecrans/M
+Rosella/M
+Rosemarie/M
+Rosemary/M
+Rosenberg/M
+Rosendo/M
+Rosenzweig/M
+Rosetta/M
+Rosicrucian/M
+Rosie/M
+Roslyn/M
+Ross/M
+Rossetti/M
+Rossini/M
+Rostand/M
+Rostov/M
+Rostropovich/M
+Roswell/M
+Rotarian/M
+Roth/M
+Rothko/M
+Rothschild/M
+Rotterdam/M
+Rottweiler/M
+Rouault/M
+Rourke/M
+Rousseau/M
+Rove/RM
+Rover/M
+Rowe/M
+Rowena/M
+Rowland/M
+Rowling/M
+Roxanne/M
+Roxie/M
+Roxy/M
+Roy/M
+Royal/M
+Royce/M
+Rozelle/M
+Rte
+Ru/MH
+Rubaiyat/M
+Rubbermaid/M
+Ruben/SM
+Rubens/M
+Rubicon/MS
+Rubik/M
+Rubin/M
+Rubinstein/M
+Ruby/M
+Ruchbah/M
+Rudolf/M
+Rudolph/M
+Rudy/M
+Rudyard/M
+Rufus/M
+Rugby
+Ruhr/M
+Ruiz/M
+Rukeyser/M
+Rumanian/SM
+Rumpelstiltskin/M
+Rumsfeld/M
+Runnymede/M
+Runyon/M
+Rupert/M
+Rush/M
+Rushdie/M
+Rushmore/M
+Ruskin/M
+Russ/M
+Russel/M
+Russell/M
+Russia/M
+Russian/SM
+Russo/M
+Rustbelt/M
+Rusty/M
+Rutan/M
+Rutgers/M
+Ruth/M
+Rutherford/M
+Ruthie/M
+Rutledge/M
+Rwanda/MS
+Rwandan/SM
+Rwy
+Rx
+Ry
+Ryan/M
+Rydberg/M
+Ryder/M
+Ryukyu/M
+S/MN
+SA
+SAC
+SALT/M
+SAM/M
+SAP/M
+SARS/M
+SASE
+SAT
+SBA
+SC/M
+SCSI/M
+SD
+SDI
+SE/M
+SEATO
+SEC/M
+SF
+SGML/M
+SIDS/M
+SJ
+SJW
+SK
+SLR
+SO/S
+SOB/M
+SOP/M
+SOS/M
+SOSes
+SPCA
+SPF
+SQL
+SQLite/M
+SRO
+SS
+SSA
+SSE/M
+SSS
+SST
+SSW/M
+ST
+STD
+STOL
+SUSE/M
+SUV
+SVN/M
+SW/M
+SWAK
+SWAT
+Saab/M
+Saar/M
+Saarinen/M
+Saatchi/M
+Sabbath/M
+Sabbaths
+Sabik/M
+Sabin/M
+Sabina/M
+Sabine/M
+Sabre/M
+Sabrina/M
+Sacajawea/M
+Sacco/M
+Sachs/M
+Sacramento/M
+Sadat/M
+Saddam/M
+Sadducee/M
+Sade/M
+Sadie/M
+Sadr/M
+Safavid/M
+Safeway/M
+Sagan/M
+Saginaw/M
+Sagittarius/MS
+Sahara/M
+Saharan/M
+Sahel/M
+Saigon/M
+Saiph/M
+Sakai/M
+Sakha/M
+Sakhalin/M
+Sakharov/M
+Saki/M
+Saks/M
+Sal/MY
+Saladin/M
+Salado/M
+Salamis/M
+Salas/M
+Salazar/M
+Salem/M
+Salerno/M
+Salesforce/M
+Salinas/M
+Salinger/M
+Salisbury/M
+Salish/M
+Salk/M
+Sallie/M
+Sallust/M
+Sally/M
+Salome/M
+Salonika/M
+Salton/M
+Salvador/M
+Salvadoran/SM
+Salvadorean/MS
+Salvadorian/MS
+Salvatore/M
+Salween/M
+Salyut/M
+Sam/M
+Samantha/M
+Samar/M
+Samara/M
+Samaritan/MS
+Samarkand/M
+Sammie/M
+Sammy/M
+Samoa/M
+Samoan/SM
+Samoset/M
+Samoyed/M
+Sampson/M
+Samson/M
+Samsonite/M
+Samsung/M
+Samuel/M
+Samuelson/M
+San'a
+San/M
+Sana/M
+Sanaa/M
+Sanchez/M
+Sancho/M
+Sand/ZM
+Sandburg/M
+Sanders/M
+Sandinista/M
+Sandoval/M
+Sandra/M
+Sandy/M
+Sanford/M
+Sanforized/M
+Sang/MR
+Sanger/M
+Sanhedrin/M
+Sanka/M
+Sankara/M
+Sanskrit/M
+Santa/M
+Santana/M
+Santayana/M
+Santeria/M
+Santiago/M
+Santos/M
+Sappho/M
+Sapporo/M
+Sara/M
+Saracen/MS
+Saragossa/M
+Sarah/M
+Sarajevo/M
+Saran/M
+Sarasota/M
+Saratov/M
+Sarawak/M
+Sardinia/M
+Sargasso/M
+Sargent/M
+Sargon/M
+Sarnoff/M
+Saroyan/M
+Sarto/M
+Sartre/M
+Sasha/M
+Sask
+Saskatchewan/M
+Saskatoon/M
+Sasquatch/MS
+Sassanian/M
+Sassoon/M
+Sat/M
+Satan/M
+Satanism/M
+Satanist/M
+Saturday/MS
+Saturn/M
+Saturnalia/M
+Saudi/MS
+Saul/M
+Saunders/M
+Saundra/M
+Saussure/M
+Sauternes
+Savage/M
+Savannah/M
+Savior/M
+Savonarola/M
+Savoy/M
+Savoyard/M
+Sawyer/M
+Saxon/MS
+Saxony/M
+Sayers/M
+Sb/M
+Sc/M
+Scala/M
+Scan
+Scandinavia/M
+Scandinavian/MS
+Scaramouch/M
+Scarborough/M
+Scarlatti/M
+Scheat/M
+Schedar/M
+Scheherazade/M
+Schelling/M
+Schenectady/M
+Schiaparelli/M
+Schick/M
+Schiller/M
+Schindler/M
+Schlesinger/M
+Schliemann/M
+Schlitz/M
+Schloss/M
+Schmidt/M
+Schnabel/M
+Schnauzer/M
+Schneider/M
+Schoenberg/M
+Schopenhauer/M
+Schrieffer/M
+Schrodinger/M
+Schroeder/M
+Schr旦dinger/M
+Schubert/M
+Schultz/M
+Schulz/M
+Schumann/M
+Schumpeter/M
+Schuyler/M
+Schuylkill/M
+Schwartz/M
+Schwarzenegger/M
+Schwarzkopf/M
+Schweitzer/M
+Schweppes/M
+Schwinger/M
+Schwinn/M
+Scientologist/SM
+Scientology/M
+Scipio/M
+Scopes/M
+Scorpio/SM
+Scorpius/M
+Scorsese/M
+Scot/SM
+Scotch/MS
+Scotchman/M
+Scotchmen/M
+Scotchwoman/M
+Scotchwomen/M
+Scotia/M
+Scotland/M
+Scotsman/M
+Scotsmen/M
+Scotswoman/M
+Scotswomen/M
+Scott/M
+Scottie/SM
+Scottish/M
+Scottsdale/M
+Scrabble/MS
+Scranton/M
+Scriabin/M
+Scribner/M
+Scripture/SM
+Scrooge/M
+Scruggs/M
+Scud/M
+Sculley/M
+Scylla/M
+Scythia/M
+Scythian/M
+Se/MH
+Seaborg/M
+Seagram/M
+Sean/M
+Sears/M
+Seaside/M
+Seattle/M
+Sebastian/M
+Sebring/M
+Sec
+Seconal/M
+Secretariat/M
+Secretary
+Seder/MS
+Sedna/M
+Seebeck/M
+Seeger/M
+Sega/M
+Segovia/M
+Segre/M
+Segundo/M
+Segway/S
+Seiko/M
+Seine/M
+Seinfeld/M
+Sejong/M
+Selassie/M
+Selectric/M
+Selena/M
+Seleucid/M
+Seleucus/M
+Selim/M
+Seljuk/M
+Selkirk/M
+Sellers/M
+Selma/M
+Selznick/M
+Semarang/M
+Seminole/MS
+Semiramis/M
+Semite/MS
+Semitic/SM
+Semtex/M
+Senate/MS
+Sendai/M
+Seneca/MS
+Senegal/M
+Senegalese/M
+Senghor/M
+Senior/M
+Sennacherib/M
+Sennett/M
+Sensurround/M
+Seoul/M
+Sep
+Sephardi/M
+Sepoy/M
+Sept/M
+September/MS
+Septuagint/MS
+Sequoya/M
+Serb/SM
+Serbia/M
+Serbian/MS
+Serena/M
+Serengeti/M
+Sergei/M
+Sergio/M
+Serpens/M
+Serra/M
+Serrano/M
+Set/M
+Seth/M
+Seton/M
+Seurat/M
+Seuss/M
+Sevastopol/M
+Severn/M
+Severus/M
+Seville/M
+Sevres/M
+Seward/M
+Sextans/M
+Sexton/M
+Seychelles/M
+Seyfert/M
+Seymour/M
+Sgt
+Shaanxi/M
+Shackleton/M
+Shaffer/M
+Shah/M
+Shaka/M
+Shaker
+Shakespeare/M
+Shakespearean/M
+Shana/M
+Shandong/M
+Shane/M
+Shanghai/M
+Shankara/M
+Shanna/M
+Shannon/M
+Shantung/M
+Shanxi/M
+Shapiro/M
+SharePoint/M
+Shari'a/M
+Shari/M
+Sharif/M
+Sharlene/M
+Sharon/M
+Sharp/M
+Sharpe/M
+Sharron/M
+Shasta/M
+Shaula/M
+Shaun/M
+Shauna/M
+Shavian/M
+Shavuot/M
+Shaw/M
+Shawn/M
+Shawna/M
+Shawnee/SM
+Shcharansky/M
+Shea/M
+Sheba/M
+Shebeli/M
+Sheboygan/M
+Sheena/M
+Sheetrock/M
+Sheffield/M
+Sheila/M
+Shelby/M
+Sheldon/M
+Shelia/M
+Shell/M
+Shelley/M
+Shelly/M
+Shelton/M
+Shenandoah/M
+Shenyang/M
+Sheol/M
+Shepard/M
+Shepherd/M
+Sheppard/M
+Sheratan/M
+Sheraton/M
+Sheree/M
+Sheri/M
+Sheridan/M
+Sherlock/M
+Sherman/M
+Sherpa/M
+Sherri/M
+Sherrie/M
+Sherry/M
+Sherwood/M
+Sheryl/M
+Shetland/SM
+Shetlands/M
+Shevardnadze/M
+Shevat/M
+Shi'ite/M
+Shields/M
+Shiite/MS
+Shijiazhuang/M
+Shikoku/M
+Shillong/M
+Shiloh/M
+Shinto/MS
+Shintoism/MS
+Shintoist/MS
+Shiraz/M
+Shirley/M
+Shiva/M
+Shockley/M
+Short/M
+Shorthorn/M
+Shoshone/SM
+Shostakovitch/M
+Shrek/M
+Shreveport/M
+Shriner/M
+Shropshire/M
+Shula/M
+Shylock/M
+Shylockian/M
+Si/M
+Siam/M
+Siamese/M
+Sian/M
+Sibelius/M
+Siberia/M
+Siberian/MS
+Sibyl/M
+Sichuan/M
+Sicilian/SM
+Sicily/M
+Sid/M
+Siddhartha/M
+Sidney/M
+Siegfried/M
+Siemens/M
+Sierpinski/M
+Sierras
+Sigismund/M
+Sigmund/M
+Sigurd/M
+Sihanouk/M
+Sikh/M
+Sikhism
+Sikhs
+Sikkim/M
+Sikkimese/M
+Sikorsky/M
+Silas/M
+Silesia/M
+Silurian/SM
+Silva/M
+Silvia/M
+Simenon/M
+Simmental/M
+Simmons/M
+Simon/M
+Simone/M
+Simpson/SM
+Simpsons/M
+Simpsonville/M
+Sims/M
+Sinai/M
+Sinatra/M
+Sinbad/M
+Sinclair/M
+Sindbad/M
+Sindhi/M
+Singapore/M
+Singaporean/SM
+Singer/M
+Singh/M
+Singleton/M
+Sinhalese/M
+Sinkiang/M
+Sioux/M
+Sir/SM
+Sirius/M
+Sister/MS
+Sistine/M
+Sisyphean/M
+Sisyphus/M
+Siva/M
+Sivan/M
+Sjaelland/M
+Skinner/M
+Skippy/M
+Skopje/M
+Skye/M
+Skylab/M
+Skype/M
+Slackware/M
+Slashdot/M
+Slater/M
+Slav/SM
+Slavic/M
+Slavonic/M
+Slidell/M
+Slinky/M
+Sloan/M
+Sloane/M
+Slocum/M
+Slovak/SM
+Slovakia/M
+Slovakian
+Slovene/SM
+Slovenia/M
+Slovenian/MS
+Slurpee/M
+Sm/M
+Small/M
+Smetana/M
+Smirnoff/M
+Smith/M
+Smithson/M
+Smithsonian/M
+Smokey/M
+Smolensk/M
+Smollett/M
+Smuts/M
+Smyrna
+Sn/M
+Snake/M
+Snapple/M
+Snead/M
+Snell/M
+Snickers/M
+Snider/M
+Snoopy/M
+Snow/M
+Snowbelt/M
+Snyder/M
+Soave/M
+Soc
+Socastee/M
+Socorro/M
+Socrates/M
+Socratic/M
+Soddy/M
+Sodom/M
+Sofia/M
+Soho/M
+Sol/M
+Solis/M
+Solomon/M
+Solon/M
+Solzhenitsyn/M
+Somali/SM
+Somalia/M
+Somalian/MS
+Somme/M
+Somoza/M
+Son/M
+Sondheim/M
+Sondra/M
+Songhai/M
+Songhua/M
+Sonia/M
+Sonja/M
+Sonny/M
+Sonora/M
+Sontag/M
+Sony/M
+Sonya/M
+Sophia/M
+Sophie/M
+Sophoclean/M
+Sophocles/M
+Sopwith/M
+Sorbonne/M
+Sosa/M
+Soto/M
+Souphanouvong/M
+Sourceforge/M
+Sousa/M
+South/M
+Southampton/M
+Southeast/MS
+Southern/ZR
+Southerner/M
+Southey/M
+Souths
+Southwest/MS
+Soviet/M
+Soweto/M
+Soyinka/M
+Soyuz/M
+Sp
+Spaatz/M
+Spackle/M
+Spahn/M
+Spain/M
+Spam/M
+Span
+Spanglish
+Spaniard/SM
+Spanish/M
+Sparks/M
+Sparta/M
+Spartacus/M
+Spartan/MS
+Spartanburg/M
+Spears/M
+Speer/M
+Spence/RM
+Spencer/M
+Spencerian/M
+Spengler/M
+Spenglerian/M
+Spenser/M
+Spenserian/M
+Sperry/M
+Sphinx/M
+Spica/M
+Spielberg/M
+Spillane/M
+Spinoza/M
+Spinx/M
+Spiro/M
+Spirograph/M
+Spitsbergen/M
+Spitz/M
+Spock/M
+Spokane/M
+Springdale/M
+Springfield/M
+Springsteen/M
+Sprint/M
+Sprite/M
+Sputnik/M
+Sq
+Squanto/M
+Squibb/M
+Sr/M
+Srinagar/M
+Srivijaya/M
+St
+Sta
+Stacey/M
+Staci/M
+Stacie/M
+Stacy/M
+Stael/M
+Stafford/M
+StairMaster/M
+Stalin/M
+Stalingrad/M
+Stalinist/M
+Stallone/M
+Stamford/M
+Stan/M
+Standish/M
+Stanford/M
+Stanislavsky/M
+Stanley/M
+Stanton/M
+Staples/M
+Starbucks/M
+Stark/M
+Starkey/M
+Starr/M
+Statehouse/MS
+Staten/M
+States
+Stateside
+Staubach/M
+Staunton/M
+Ste
+Steadicam/M
+Steele/M
+Stefan/M
+Stefanie/M
+Stein/MR
+Steinbeck/M
+Steinem/M
+Steiner/M
+Steinmetz/M
+Steinway/M
+Stella/M
+Stendhal/M
+Stengel/M
+Stephan/M
+Stephanie/M
+Stephen/MS
+Stephens/M
+Stephenson/M
+Sterling/M
+Stern/M
+Sterne/M
+Sterno/M
+Stetson/M
+Steuben/M
+Steubenville/M
+Steve/M
+Steven/MS
+Stevens/M
+Stevenson/M
+Stevie/M
+Stewart/M
+Stieglitz/M
+Stilton/SM
+Stimson/M
+Stine/M
+Stirling/M
+Stockhausen/M
+Stockholm/M
+Stockton/M
+Stoic/SM
+Stoicism/MS
+Stokes/M
+Stolichnaya/M
+Stolypin/M
+Stone/M
+Stonehenge/M
+Stoppard/M
+Stout/M
+Stowe/M
+Strabo/M
+Stradivari
+Stradivarius/M
+Strasbourg/M
+Strauss/M
+Stravinsky/M
+Streisand/M
+Strickland/M
+Strindberg/M
+Stromboli/M
+Strong/M
+Stu/M
+Stuart/MS
+Studebaker/M
+Stuttgart/M
+Stuyvesant/M
+Stygian/M
+Styrofoam/SM
+Styron/M
+Styx/M
+Suarez/M
+Subaru/M
+Sucre/M
+Sucrets/M
+Sudan/M
+Sudanese/M
+Sudetenland/M
+Sudoku/M
+Sudra/M
+Sue/M
+Suetonius/M
+Suez/M
+Suffolk/M
+Sufi/M
+Sufism/M
+Suharto/M
+Sui/M
+Sukarno/M
+Sukkot
+Sukkoth/M
+Sukkoths
+Sulawesi/M
+Suleiman/M
+Sulla/M
+Sullivan/M
+Sumatra/M
+Sumatran/SM
+Sumeria/M
+Sumerian/SM
+Summer/MS
+Summers/M
+Sumner/M
+Sumter/M
+Sun/SM
+Sunbeam/M
+Sunbelt/M
+Sundanese/M
+Sundas/M
+Sunday/MS
+Sung/M
+Sunkist/M
+Sunni/SM
+Sunnite/MS
+Sunnyvale/M
+Superbowl/M
+Superfund/M
+Superglue/M
+Superior/M
+Superman/M
+Supt
+Surabaja
+Surabaya/M
+Surat/M
+Suriname/M
+Surinamese
+Surya/M
+Susan/M
+Susana/M
+Susanna/M
+Susanne/M
+Susie/M
+Susquehanna/M
+Sussex/M
+Sutherland/M
+Sutton/M
+Suva/M
+Suwanee/M
+Suzanne/M
+Suzette/M
+Suzhou/M
+Suzuki/M
+Suzy/M
+Svalbard/M
+Sven/M
+Svengali/M
+Sverdlovsk
+Swahili/SM
+Swammerdam/M
+Swanee/M
+Swansea/M
+Swanson/M
+Swazi/SM
+Swaziland/M
+Swed/N
+Swede/SM
+Sweden/M
+Swedenborg/M
+Swedish/M
+Sweeney/M
+Sweet/M
+Swift/M
+Swinburne/M
+Swiss/MS
+Swissair/M
+Switz
+Switzerland/M
+Sybil/M
+Sydney/M
+Sykes/M
+Sylvester/M
+Sylvia/M
+Sylvie/M
+Synge/M
+Syracuse/M
+Syria/M
+Syriac/M
+Syrian/MS
+Szilard/M
+Szymborska/M
+S竪vres/M
+T'ang/M
+T/MDG
+TA
+TARP
+TB/M
+TBA
+TD
+TDD
+TEFL
+TELNET/S
+TELNETTed
+TELNETTing
+TESL
+TESOL
+TGIF
+THC
+TKO/M
+TLC/M
+TM
+TN
+TNT/M
+TOEFL
+TQM
+TV/SM
+TVA
+TWA/M
+TWX
+TX
+Ta/M
+Tabasco/SM
+Tabatha/M
+Tabernacle/MS
+Tabitha/M
+Tabriz/MS
+Tacitus/M
+Tacoma/M
+Tad/M
+Tadzhik/M
+Taegu/M
+Taejon/M
+Taft/M
+Tagalog/SM
+Tagore/M
+Tagus/M
+Tahiti/M
+Tahitian/MS
+Tahoe/M
+Taichung/M
+Tainan
+Taine/M
+Taipei/M
+Taiping/M
+Taiwan/M
+Taiwanese/M
+Taiyuan/M
+Tajikistan/M
+Taklamakan/M
+Talbot/M
+Taliban/M
+Taliesin/M
+Tallahassee/M
+Tallchief/M
+Talley/M
+Talleyrand/M
+Tallinn/M
+Talmud/MS
+Talmudic
+Talmudist
+Tamara/M
+Tameka/M
+Tamera/M
+Tamerlane/M
+Tami/M
+Tamika/M
+Tamil/MS
+Tammany/M
+Tammi/M
+Tammie/M
+Tammuz/M
+Tammy/M
+Tampa/M
+Tampax/M
+Tamra/M
+Tamworth/M
+Tancred/M
+Taney/M
+Tanganyika/M
+Tangier/MS
+Tangshan/M
+Tania/M
+Tanisha/M
+Tanner/M
+Tannhauser/M
+Tannh辰user/M
+Tantalus/M
+Tanya/M
+Tanzania/M
+Tanzanian/SM
+Tao/M
+Taoism/MS
+Taoist/MS
+Tara/M
+Tarantino/M
+Tarawa/M
+Tarazed/M
+Tarbell/M
+Target/M
+Tarim/M
+Tarkenton/M
+Tarkington/M
+Tartar/MS
+Tartary/M
+Tartuffe/M
+Tarzan/M
+Tasha/M
+Tashkent/M
+Tasman/M
+Tasmania/M
+Tasmanian/M
+Tass/M
+Tatar/MS
+Tate/M
+Tatum/M
+Taurus/MS
+Tavares/M
+Tawney/M
+Taylor/M
+Tb/M
+Tbilisi/M
+Tc/M
+Tchaikovsky/M
+Te/M
+TeX
+TeXes
+Teasdale/M
+Technicolor/M
+Tecumseh/M
+Ted/M
+Teddy/M
+Teflon/MS
+Tegucigalpa/M
+Tehran
+TelePrompTer
+TelePrompter/M
+Telemachus/M
+Telemann/M
+Teletype
+Tell/MR
+Teller/M
+Telugu/M
+Temecula/M
+Tempe
+Templar/M
+Temple/M
+Tenn/M
+Tennessean/SM
+Tennessee/M
+Tennyson/M
+Tennysonian
+Tenochtitlan/M
+TensorFlow/M
+Teotihuacan/M
+Terence/M
+Teresa/M
+Tereshkova/M
+Teri/M
+Terkel/M
+Terpsichore/M
+Terr/M
+Terra/M
+Terran/M
+Terrance/M
+Terrell/M
+Terrence/M
+Terri/M
+Terrie/M
+Territory
+Terry/M
+Tertiary/M
+Tesla/M
+Tess/M
+Tessa/M
+Tessie/M
+Tet/M
+Tethys/M
+Tetons/M
+Teuton/MS
+Teutonic/M
+Tevet/M
+Tex/M
+Texaco/M
+Texan/MS
+Texarkana/M
+Texas/M
+Th/M
+Thackeray/M
+Thad/M
+Thaddeus/M
+Thai/SM
+Thailand/M
+Thales/M
+Thalia/M
+Thames/M
+Thanh/M
+Thanksgiving/MS
+Thant/M
+Thar/M
+Tharp/M
+Thatcher/M
+Thea/M
+Thebes/M
+Theiler/M
+Thelma/M
+Themistocles/M
+Theocritus/M
+Theodora/M
+Theodore/M
+Theodoric/M
+Theodosius/M
+Theosophy/M
+Theravada/M
+Theresa/M
+Therese/M
+Thermopylae/M
+Thermos
+Theron/M
+Theseus/M
+Thespian/M
+Thespis/M
+Thessalonian/SM
+Thessaloniki/M
+Thessalon鱈ki/M
+Thessaly/M
+Thieu/M
+Thimbu/M
+Thimphu
+Thomas/M
+Thomism/M
+Thomistic/M
+Thompson/M
+Thomson/M
+Thor/M
+Thorazine/M
+Thoreau/M
+Thornton/M
+Thoroughbred/M
+Thorpe/M
+Thoth/M
+Thrace/M
+Thracian/M
+Thu
+Thucydides/M
+Thule/M
+Thunderbird/M
+Thur/S
+Thurber/M
+Thurman/M
+Thurmond/M
+Thursday/SM
+Thutmose/M
+Ti/M
+Tia/M
+Tianjin/M
+Tiber/M
+Tiberius/M
+Tibet/M
+Tibetan/MS
+Ticketmaster/M
+Ticonderoga/M
+Tide/M
+Tienanmen/M
+Tientsin/M
+Tiffany/M
+Tigris/M
+Tijuana/M
+Tillich/M
+Tillman/M
+Tilsit/M
+Tim/M
+Timbuktu/M
+Timex/M
+Timmy/M
+Timon/M
+Timor/M
+Timothy/M
+Timur/M
+Timurid/M
+Tina/M
+Ting/M
+Tinkerbell/M
+Tinkertoy/M
+Tinseltown/M
+Tintoretto/M
+Tippecanoe/M
+Tipperary/M
+Tirane
+Tiresias/M
+Tirol/M
+Tirolean
+Tisha/M
+Tishri/M
+Titan/SM
+Titania/M
+Titanic/M
+Titian/M
+Titicaca/M
+Tito/M
+Titus/M
+Titusville/M
+Tl/M
+Tlaloc/M
+Tlingit/M
+Tm/M
+Tobago/M
+Tobit/M
+Toby/M
+Tocantins/M
+Tocqueville/M
+Tod/M
+Todd/M
+Togo/M
+Togolese/M
+Tojo/M
+Tokay/M
+Tokugawa/M
+Tokyo/M
+Tokyoite
+Toledo/MS
+Tolkien/M
+Tolstoy/M
+Toltec/M
+Tolyatti/M
+Tom/M
+Tomas/M
+Tombaugh/M
+Tomlin/M
+Tommie/M
+Tommy/M
+Tompkins/M
+Tomsk/M
+Tonga/M
+Tongan/MS
+Toni/M
+Tonia/M
+Tonto/M
+Tony/M
+Tonya/M
+Topeka/M
+Topsy/M
+Torah/M
+Torahs
+Toronto/M
+Torquemada/M
+Torrance/M
+Torrens/M
+Torres/M
+Torricelli/M
+Tortola/M
+Tortuga/M
+Torvalds/M
+Tory/SM
+Tosca/M
+Toscanini/M
+Toshiba/M
+Toto/M
+Toulouse/M
+Townes/M
+Townsend/M
+Toynbee/M
+Toyoda/M
+Toyota/M
+Tracey/M
+Traci/M
+Tracie/M
+Tracy/M
+Trafalgar/M
+Trailways/M
+Trajan/M
+Tran/M
+Transcaucasia/M
+Transvaal/M
+Transylvania/M
+Transylvanian/M
+Trappist/SM
+Travis/M
+Travolta/M
+Treasury/SM
+Treblinka/M
+Trekkie/M
+Trent/M
+Trenton/M
+Trevelyan/M
+Trevino/M
+Trevor/M
+Trey/M
+Triangulum/M
+Triassic/M
+Tricia/M
+Trident/M
+Trieste/M
+Trimurti/M
+Trina/M
+Trinidad/M
+Trinidadian/MS
+Trinity/SM
+Tripitaka/M
+Tripoli/M
+Trippe/M
+Trisha/M
+Tristan/M
+Triton/M
+Trobriand/M
+Troilus/M
+Trojan/MS
+Trollope/M
+Trondheim/M
+Tropicana/M
+Trotsky/M
+Troy/M
+Troyes
+Truckee/M
+Trudeau/M
+Trudy/M
+Truffaut/M
+Trujillo/M
+Truman/M
+Trumbull/M
+Trump/M
+Truth/M
+Tsimshian/M
+Tsiolkovsky/M
+Tsitsihar/M
+Tsongkhapa/M
+Tswana/M
+Tu/M
+Tuamotu/M
+Tuareg/M
+Tubman/M
+Tucker/M
+Tucson/M
+Tucuman/M
+Tudor/SM
+Tue/S
+Tues/M
+Tuesday/MS
+Tulane/M
+Tull/M
+Tulsa/M
+Tulsidas/M
+Tums/M
+Tungus/M
+Tunguska/M
+Tunis/M
+Tunisia/M
+Tunisian/MS
+Tunney/M
+Tupi/M
+Tupperware/M
+Tupungato/M
+Turgenev/M
+Turin/M
+Turing/M
+Turk/SM
+Turkestan/M
+Turkey/M
+Turkic/MS
+Turkish/M
+Turkmenistan/M
+Turlock/M
+Turner/M
+Turpin/M
+Tuscaloosa/M
+Tuscan/M
+Tuscany/M
+Tuscarora/MS
+Tuscon/M
+Tuskegee/M
+Tussaud/M
+Tut/M
+Tutankhamen/M
+Tutsi/M
+Tutu/M
+Tuvalu/M
+Tuvaluan
+Twain/M
+Tweed/M
+Tweedledee/M
+Tweedledum/M
+Twila/M
+Twinkies/M
+Twitter/M
+Twizzlers/M
+Twp
+Ty/M
+Tycho/M
+Tylenol/M
+Tyler/M
+Tyndale/M
+Tyndall/M
+Tyre/M
+Tyree/M
+Tyrolean
+Tyrone/M
+Tyson/M
+U/M
+UAR
+UAW
+UBS/M
+UCLA/M
+UFO/SM
+UHF/M
+UK/M
+UL
+UN/M
+UNESCO/M
+UNICEF/M
+UNIX/M
+UPC
+UPI/M
+UPS/M
+URL/S
+US/M
+USA/M
+USAF
+USB
+USCG
+USDA/M
+USIA
+USMC
+USN
+USO
+USP
+USPS
+USS
+USSR/M
+UT/M
+UTC
+UV/M
+Ubangi/M
+Ubuntu/M
+Ucayali/M
+Uccello/M
+Udall/M
+Ufa/M
+Uganda/M
+Ugandan/MS
+Uighur/M
+Ujungpandang/M
+Ukraine/M
+Ukrainian/SM
+Ulster/M
+Ultrasuede/M
+Ulyanovsk/M
+Ulysses/M
+Umbriel/M
+Underwood/M
+Ungava/M
+Unicode/M
+Unilever/M
+Union/SM
+Unionist
+Uniontown/M
+Uniroyal/M
+Unitarian/MS
+Unitarianism/MS
+Unitas/M
+Unix/S
+Unukalhai/M
+Upanishads/M
+Updike/M
+Upjohn/M
+Upton/M
+Ur/M
+Ural/SM
+Urals/M
+Urania/M
+Uranus/M
+Urban/M
+Urdu/M
+Urey/M
+Uriah/M
+Uriel/M
+Uris/M
+Urquhart/M
+Ursa/M
+Ursula/M
+Ursuline/M
+Uruguay/M
+Uruguayan/MS
+Urumqi/M
+Usenet/MS
+Ustinov/M
+Ut
+Utah/M
+Utahan/MS
+Ute/SM
+Utica/M
+Utopia/SM
+Utopian/SM
+Utrecht/M
+Utrillo/M
+Uzbek/M
+Uzbekistan/M
+Uzi/SM
+V/M
+VA
+VAT/M
+VAX
+VAXes
+VBA/M
+VCR/M
+VD/M
+VDT
+VDU
+VF
+VFW/M
+VG
+VGA
+VHF/M
+VHS
+VI/M
+VIP/SM
+VISTA
+VJ
+VLF/M
+VOA
+VP
+VT
+VTOL
+Va/M
+Vacaville/M
+Vader/M
+Vaduz/M
+Val/M
+Valarie/M
+Valdez/M
+Valdosta/M
+Valencia/SM
+Valenti/M
+Valentin/M
+Valentine/M
+Valentino/M
+Valenzuela/M
+Valeria/M
+Valerian/M
+Valerie/M
+Valery/M
+Valhalla/M
+Valium/MS
+Valkyrie/SM
+Vallejo/M
+Valletta/M
+Valois/M
+Valparaiso/M
+Valvoline/M
+Val辿ry/M
+Van/M
+Vance/M
+Vancouver/M
+Vandal/MS
+Vanderbilt/M
+Vandyke/M
+Vanessa/M
+Vang/M
+Vanuatu/M
+Vanzetti/M
+Varanasi/M
+Varese/M
+Vargas/M
+Vaseline/SM
+Vasquez/M
+Vassar/M
+Vatican/M
+Vauban/M
+Vaughan/M
+Vaughn/M
+Vazquez/M
+Veblen/M
+Veda/SM
+Vedanta/M
+Veep
+Vega/SM
+Vegas/M
+Vegemite/M
+Vela/M
+Velasquez/M
+Velazquez/M
+Velcro/MS
+Velez/M
+Velma/M
+Velveeta/M
+Vel叩squez/M
+Vel叩zquez/M
+Venetian/SM
+Venezuela/M
+Venezuelan/SM
+Venice/M
+Venn/M
+Ventolin/M
+Venus/MS
+Venusian/M
+Vera/M
+Veracruz/M
+Verde/M
+Verdi/M
+Verdun/M
+Verizon/M
+Verlaine/M
+Vermeer/M
+Vermont/ZMR
+Vermonter/M
+Vern/M
+Verna/M
+Verne/M
+Vernon/M
+Verona/M
+Veronese/M
+Veronica/M
+Versailles/M
+Vesalius/M
+Vespasian/M
+Vespucci/M
+Vesta/M
+Vesuvius/M
+Viacom/M
+Viagra/M
+Vic/M
+Vicente/M
+Vichy/M
+Vicki/M
+Vickie/M
+Vicksburg/M
+Vicky/M
+Victor/M
+Victoria/M
+Victorian/MS
+Victorianism
+Victorville/M
+Victrola/M
+Vidal/M
+Vienna/M
+Viennese/M
+Vientiane/M
+Vietcong/M
+Vietminh/M
+Vietnam/M
+Vietnamese/M
+Vijayanagar/M
+Vijayawada/M
+Viking/MS
+Vila/M
+Villa/SM
+Villarreal/M
+Villas/M
+Villon/M
+Vilma/M
+Vilnius/M
+Vilyui/M
+Vince/M
+Vincent/M
+Vindemiatrix/M
+Vineland/M
+Vinson/M
+Viola/M
+Violet/M
+Virgie/M
+Virgil/M
+Virginia/M
+Virginian/SM
+Virgo/SM
+Visa/M
+Visakhapatnam/M
+Visalia/M
+Visayans/M
+Vishnu/M
+Visigoth/M
+Visigoths
+Vistula/M
+Vitim/M
+Vito/M
+Vitus/M
+Vivaldi/M
+Vivekananda/M
+Vivian/M
+Vivienne/M
+Vlad/M
+Vladimir/M
+Vladivostok/M
+Vlaminck/M
+Vlasic/M
+VoIP
+Vogue/M
+Volcker/M
+Voldemort/M
+Volga/M
+Volgograd/M
+Volkswagen/M
+Volstead/M
+Volta/M
+Voltaire/M
+Volvo/M
+Vonda/M
+Vonnegut/M
+Voronezh/M
+Vorster/M
+Voyager/M
+Vt
+Vuitton/M
+Vulcan/M
+Vulg
+Vulgate/SM
+W/MDT
+WA
+WAC
+WASP/M
+WATS/M
+WC
+WHO/M
+WI
+WMD
+WNW/M
+WP
+WSW/M
+WTO
+WV
+WW
+WWI
+WWII
+WWW/M
+WY
+WYSIWYG
+Wabash/M
+Wac
+Waco/M
+Wade/M
+Wagner/M
+Wagnerian/M
+Wahhabi/M
+Waikiki/M
+Waite/M
+Wake/M
+Waksman/M
+Wald/MN
+Waldemar/M
+Walden/M
+Waldensian/M
+Waldheim/M
+Waldo/M
+Waldorf/M
+Wales/M
+Walesa/M
+Walgreen/SM
+Walgreens/M
+Walker/M
+Walkman/M
+Wall/SMR
+Wallace/M
+Wallenstein/M
+Waller/M
+Wallis/M
+Walloon/M
+Walls/M
+Walmart/M
+Walpole/M
+Walpurgisnacht/M
+Walsh/M
+Walt/MRZ
+Walter/M
+Walters/M
+Walton/M
+Wanamaker/M
+Wanda/M
+Wang/M
+Wankel/M
+Ward/M
+Ware/MG
+Warhol/M
+Waring/M
+Warner/M
+Warren/M
+Warsaw/M
+Warwick/M
+Wasatch/M
+Wash/M
+Washington/M
+Washingtonian/MS
+Wassermann/M
+Waterbury/M
+Waterford/M
+Watergate/M
+Waterloo/MS
+Waters/M
+Watertown/M
+Watkins/M
+Watson/M
+Watsonville/M
+Watt/SM
+Watteau/M
+Watts/M
+Watusi/M
+Waugh/M
+Wausau/M
+Wave
+Wayne/M
+Waynesboro/M
+Weaver/M
+Web/MR
+Webb/M
+Weber/M
+Webern/M
+Webster/MS
+Wed/M
+Weddell/M
+Wedgwood/M
+Wednesday/MS
+Weeks/M
+Wehrmacht/M
+Wei/M
+Weierstrass/M
+Weill/M
+Weinberg/M
+Weirton/M
+Weiss/M
+Weissmuller/M
+Weizmann/M
+Weldon/M
+Welland/M
+Weller/M
+Welles/M
+Wellington/SM
+Wells/M
+Welsh/M
+Welshman/M
+Welshmen/M
+Welshwoman
+Wenatchee/M
+Wendell/M
+Wendi/M
+Wendy/M
+Wesak/M
+Wesley/M
+Wesleyan/M
+Wessex/M
+Wesson/M
+West/SM
+Western/MRS
+Westinghouse/M
+Westminster/M
+Weston/M
+Westphalia/M
+Weyden/M
+Wezen/M
+Wharton/M
+Wheaties/M
+Wheatstone/M
+Wheeler/M
+Wheeling/M
+Whig/SM
+Whipple/M
+Whirlpool/M
+Whistler/M
+Whitaker/M
+White/SM
+Whitefield/M
+Whitehall/M
+Whitehead/M
+Whitehorse/M
+Whiteley/M
+Whitfield/M
+Whitley/M
+Whitman/M
+Whitney/M
+Whitsunday/MS
+Whittier/M
+WiFi
+Wicca/M
+Wichita/M
+Wiemar/M
+Wiesel/M
+Wiesenthal/M
+Wiggins/M
+Wigner/M
+Wii/M
+Wikileaks
+Wikipedia/M
+Wilberforce/M
+Wilbert/M
+Wilbur/M
+Wilburn/M
+Wilcox/M
+Wilda/M
+Wilde/MR
+Wilder/M
+Wiles/M
+Wiley/M
+Wilford/M
+Wilfred/M
+Wilfredo/M
+Wilhelm/M
+Wilhelmina/M
+Wilkerson/M
+Wilkes/M
+Wilkins/M
+Wilkinson/M
+Will/M
+Willa/M
+Willamette/M
+Willard/M
+Willemstad/M
+William/SM
+Williams/M
+Williamsburg/M
+Williamson/M
+Williamsport/M
+Willie/M
+Willis/M
+Willy/M
+Wilma/M
+Wilmer/M
+Wilmington/M
+Wilson/M
+Wilsonian/M
+Wilton/M
+Wimbledon/M
+Wimsey/M
+Winchell/M
+Winchester/MS
+Windbreaker/M
+Windex/M
+Windhoek/M
+Windows/M
+Windsor/SM
+Windward/M
+Winesap/M
+Winfred/M
+Winfrey/M
+Winifred/M
+Winkle/M
+Winnebago/M
+Winnie/M
+Winnipeg/M
+Winston/M
+Winters/M
+Winthrop/M
+Wis
+Wisc
+Wisconsin/M
+Wisconsinite/MS
+Wise/M
+Witt/M
+Wittgenstein/M
+Witwatersrand/M
+Wm/M
+Wobegon/M
+Wodehouse/M
+Wolf/M
+Wolfe/M
+Wolff/M
+Wolfgang/M
+Wollongong/M
+Wollstonecraft/M
+Wolsey/M
+Wolverhampton
+Wonder/M
+Wonderbra/M
+Wong/M
+Wood/SM
+Woodard/M
+Woodhull/M
+Woodland/M
+Woodrow/M
+Woods/M
+Woodstock/M
+Woodward/M
+Woolf/M
+Woolite/M
+Woolongong/M
+Woolworth/M
+Wooster/M
+Wooten/M
+Worcester/SM
+Worcestershire/M
+WordPress/M
+Wordsworth/M
+Workman/M
+Worms/M
+Wotan/M
+Wovoka/M
+Wozniak/M
+Wozzeck/M
+Wrangell/M
+Wren/M
+Wright/M
+Wrigley/M
+Wroclaw/M
+Wu/M
+Wuhan/M
+Wurlitzer/M
+Wyatt/M
+Wycherley/M
+Wycliffe/M
+Wyeth/M
+Wylie/M
+Wynn/M
+Wyo
+Wyoming/M
+Wyomingite/SM
+X/M
+XEmacs/M
+XL/M
+XML
+XS
+XXL
+Xamarin/M
+Xanadu/M
+Xanthippe/M
+Xavier/M
+Xe/SM
+Xenakis/M
+Xenia/M
+Xenophon/M
+Xerox/MS
+Xerxes/M
+Xhosa/M
+Xi'an/M
+Xian/SM
+Xiaoping/M
+Ximenes/M
+Xingu/M
+Xinjiang/M
+Xiongnu/M
+Xizang/M
+Xmas/MS
+Xochipilli/M
+Xuzhou/M
+Y/M
+YMCA/M
+YMHA
+YMMV
+YT
+YWCA/M
+YWHA
+Yacc/M
+Yahoo/M
+Yahtzee/M
+Yahweh/M
+Yakima/M
+Yakut/M
+Yakutsk/M
+Yale/M
+Yalow/M
+Yalta/M
+Yalu/M
+Yamagata/M
+Yamaha/M
+Yamoussoukro/M
+Yang/M
+Yangon/M
+Yangtze/M
+Yank/SM
+Yankee/SM
+Yaobang/M
+Yaounde/M
+Yaqui/M
+Yaren
+Yaroslavl/M
+Yataro/M
+Yates/M
+Yauco/M
+Yb/M
+Yeager/M
+Yeats/M
+Yekaterinburg/M
+Yellowknife/M
+Yellowstone/M
+Yeltsin/M
+Yemen/M
+Yemeni/SM
+Yemenite
+Yenisei/M
+Yerevan/M
+Yerkes/M
+Yesenia/M
+Yevtushenko/M
+Yggdrasil/M
+Yiddish/M
+Ymir/M
+Yoda/M
+Yoknapatawpha/M
+Yoko/M
+Yokohama/M
+Yolanda/M
+Yong/M
+Yonkers/M
+York/M
+Yorkie/M
+Yorkshire/MS
+Yorktown/M
+Yoruba/M
+Yosemite/M
+Yossarian/M
+YouTube/M
+Young/M
+Youngstown/M
+Ypres/M
+Ypsilanti/M
+Yuan/M
+Yucatan/M
+Yugo/M
+Yugoslav/MS
+Yugoslavia/M
+Yugoslavian/SM
+Yukon/M
+Yule/SM
+Yuletide/MS
+Yuma/SM
+Yunnan/M
+Yuri/M
+Yves/M
+Yvette/M
+Yvonne/M
+Z/SMNXT
+Zachariah/M
+Zachary/M
+Zachery/M
+Zagreb/M
+Zaire/M
+Zairian
+Zambezi/M
+Zambia/M
+Zambian/SM
+Zamboni/M
+Zamenhof/M
+Zamora/M
+Zane/M
+Zanuck/M
+Zanzibar/M
+Zapata/M
+Zaporozhye/M
+Zapotec/M
+Zappa/M
+Zara/M
+Zarathustra/M
+Zealand/M
+Zebedee/M
+Zechariah/M
+Zedekiah/M
+Zedong/M
+Zeffirelli/M
+Zeke/M
+Zelig/M
+Zelma/M
+Zen/M
+Zenger/M
+Zeno/M
+Zephaniah/M
+Zephyrhills/M
+Zephyrus/M
+Zeppelin/M
+Zest/M
+Zeus/M
+Zhdanov
+Zhejiang/M
+Zhengzhou/M
+Zhivago/M
+Zhukov/M
+Zibo/M
+Ziegfeld/M
+Ziegler/M
+Ziggy/M
+Zika
+Zimbabwe/M
+Zimbabwean/SM
+Zimmerman/M
+Zinfandel/M
+Zion/SM
+Zionism/SM
+Zionist/SM
+Ziploc/M
+Zn/M
+Zoe/M
+Zola/M
+Zollverein/M
+Zoloft/M
+Zomba/M
+Zorn/M
+Zoroaster/M
+Zoroastrian/MS
+Zoroastrianism/SM
+Zorro/M
+Zosma/M
+Zr/M
+Zsigmondy/M
+Zubenelgenubi/M
+Zubeneschamali/M
+Zukor/M
+Zulu/SM
+Zululand
+Zuni/M
+Zurich/M
+Zwingli/M
+Zworykin/M
+Zyrtec/M
+Zyuganov/M
+Zzz
+Z端rich/M
+a/S
+aah
+aardvark/SM
+ab/SDY
+aback
+abacus/MS
+abaft
+abalone/SM
+abandon/LSDG
+abandonment/M
+abase/LGDS
+abasement/M
+abash/GLDS
+abashed/UY
+abashment/M
+abate/LGDS
+abated/U
+abatement/M
+abattoir/MS
+abbe/SM
+abbess/MS
+abbey/MS
+abbot/MS
+abbr
+abbrev/S
+abbreviate/DSGNX
+abbreviation/M
+abb辿/SM
+abdicate/GNDSX
+abdication/M
+abdomen/SM
+abdominal
+abduct/DSG
+abductee/MS
+abduction/SM
+abductor/MS
+abeam
+aberrant
+aberration/MS
+aberrational
+abet/S
+abetted
+abetter/SM
+abetting
+abettor/SM
+abeyance/M
+abhor/S
+abhorred
+abhorrence/M
+abhorrent/Y
+abhorring
+abidance/M
+abide/GS
+abiding/Y
+ability/IEMS
+abject/YP
+abjection/M
+abjectness/M
+abjuration/SM
+abjuratory
+abjure/ZGDRS
+abjurer/M
+ablate/XGNVDS
+ablation/M
+ablative/MS
+ablaze
+able/UT
+abler
+abloom
+ablution/SM
+abnegate/GNDS
+abnegation/M
+abnormal/Y
+abnormality/SM
+aboard
+abode/MS
+abolish/GDS
+abolition/M
+abolitionism/M
+abolitionist/SM
+abominable
+abominably
+abominate/DSGNX
+abomination/M
+aboriginal/MS
+aborigine/SM
+aborning
+abort/GVDS
+abortion/MS
+abortionist/MS
+abortive/Y
+abound/DSG
+about
+above/M
+aboveboard
+abracadabra/M
+abrade/GDS
+abrasion/MS
+abrasive/MYPS
+abrasiveness/M
+abreast
+abridge/DSG
+abridgment/MS
+abroad
+abrogate/XGNDS
+abrogation/M
+abrogator/MS
+abrupt/TPRY
+abruptness/M
+abs/M
+abscess/MDSG
+abscissa/SM
+abscission/M
+abscond/ZGSDR
+absconder/M
+abseil/MDSG
+absence/SM
+absent/DYSG
+absentee/MS
+absenteeism/M
+absentminded/YP
+absentmindedness/M
+absinthe/M
+absolute/PMYTNS
+absoluteness/M
+absolution/M
+absolutism/M
+absolutist/MS
+absolve/DSG
+absorb/AGDS
+absorbance
+absorbency/M
+absorbent/SM
+absorbing/Y
+absorption/M
+absorptive
+abstain/DRZGS
+abstainer/M
+abstemious/PY
+abstemiousness/M
+abstention/MS
+abstinence/M
+abstinent
+abstract/GSPMDY
+abstracted/YP
+abstractedness/M
+abstraction/SM
+abstractness/MS
+abstruse/YP
+abstruseness/M
+absurd/TPRY
+absurdist/MS
+absurdity/SM
+absurdness/M
+abundance/SM
+abundant/Y
+abuse's
+abuse/EGVDS
+abuser/MS
+abusive/YP
+abusiveness/M
+abut/SL
+abutment/MS
+abutted
+abutting
+abuzz
+abysmal/Y
+abyss/MS
+abyssal
+ac
+acacia/MS
+academe/M
+academia/M
+academic/SM
+academical/Y
+academician/MS
+academy/SM
+acanthus/MS
+accede/GDS
+accelerate/GNXDS
+acceleration/M
+accelerator/SM
+accent/MDSG
+accented/U
+accentual
+accentuate/GNDS
+accentuation/M
+accept/DSBG
+acceptability/M
+acceptableness/M
+acceptably/U
+acceptance/SM
+acceptation/MS
+accepted/U
+access/MDSG
+accessibility/IM
+accessible/I
+accessibly/I
+accession/MDGS
+accessorize/DSG
+accessory/SM
+accident/MS
+accidental/SMY
+acclaim/MDGS
+acclamation/M
+acclimate/DSGN
+acclimation/M
+acclimatization/M
+acclimatize/DSG
+acclivity/SM
+accolade/SM
+accommodate/XGNDS
+accommodating/Y
+accommodation/M
+accompanied/U
+accompaniment/MS
+accompanist/SM
+accompany/DSG
+accomplice/SM
+accomplish/DSLG
+accomplished/U
+accomplishment/MS
+accord/GMDS
+accordance/M
+accordant
+according/Y
+accordion/MS
+accordionist/MS
+accost/GMDS
+account/MDSBG
+accountability/M
+accountable/U
+accountancy/M
+accountant/MS
+accounted/U
+accounting/M
+accouter/SGD
+accouterments/M
+accoutre/DSG
+accoutrements
+accredit/SGD
+accreditation/M
+accredited/U
+accretion/MS
+accrual/MS
+accrue/GDS
+acct
+acculturate/DSGN
+acculturation/M
+accumulate/XGNVDS
+accumulation/M
+accumulator/MS
+accuracy/IM
+accurate/IY
+accurateness/M
+accursed/P
+accursedness/M
+accusation/MS
+accusative/MS
+accusatory
+accuse/ZGDRS
+accuser/M
+accusing/Y
+accustom/DSG
+accustomed/U
+ace/DSMG
+acerbate/DSG
+acerbic
+acerbically
+acerbity/M
+acetaminophen/M
+acetate/MS
+acetic
+acetone/M
+acetonic
+acetyl
+acetylene/M
+ache/DSMG
+achene/MS
+achievable/U
+achieve/BLZGDRS
+achievement/SM
+achiever/M
+aching/Y
+achoo/M
+achromatic
+achy/TR
+acid/SMY
+acidic
+acidify/GDS
+acidity/M
+acidosis/M
+acidulous
+acknowledge/DSGL
+acknowledged/U
+acknowledgement/MS
+acknowledgment/SM
+acme/SM
+acne/M
+acolyte/MS
+aconite/MS
+acorn/MS
+acoustic/S
+acoustical/Y
+acoustics/M
+acquaint/AGSD
+acquaintance/SM
+acquaintanceship/M
+acquainted/U
+acquiesce/DSG
+acquiescence/M
+acquiescent/Y
+acquire/ZGBDRSL
+acquirement/M
+acquisition/MS
+acquisitive/YP
+acquisitiveness/M
+acquit/S
+acquittal/MS
+acquitted
+acquitting
+acre/SM
+acreage/MS
+acrid/PTRY
+acridity/M
+acridness/M
+acrimonious/YP
+acrimoniousness/M
+acrimony/M
+acrobat/MS
+acrobatic/S
+acrobatically
+acrobatics/M
+acronym/MS
+acrophobia/M
+acropolis/MS
+across
+acrostic/SM
+acrylamide
+acrylic/MS
+act's
+act/ASDGV
+acting/M
+actinium/M
+action/ASM
+actionable
+activate/ICANGSD
+activation/ICAM
+activator/MS
+active's
+active/IKY
+activeness/M
+actives
+activism/M
+activist/MS
+activities
+activity/IM
+actor/AMS
+actress/MS
+actual/Y
+actuality/SM
+actualization/M
+actualize/GDS
+actuarial
+actuary/SM
+actuate/GNDS
+actuation/M
+actuator/SM
+acuity/M
+acumen/M
+acupressure/M
+acupuncture/M
+acupuncturist/SM
+acute/PMYTRS
+acuteness/M
+acyclovir/M
+acyl
+ad/SM
+adage/MS
+adagio/MS
+adamant/MY
+adapt/BZGVDRS
+adaptability/M
+adaptation/MS
+adapter/M
+adaption/S
+add/SDRBZG
+addend/MS
+addenda
+addendum/M
+adder/M
+addible
+addict/GVMDS
+addiction/SM
+addition/SM
+additional/Y
+additive/SM
+addle/GDS
+address's
+address/AGDS
+addressable
+addressed/U
+addressee/SM
+adduce/GDS
+adenine/M
+adenocarcinoma
+adenoid/SM
+adenoidal
+adept/MYPS
+adeptness/M
+adequacy/IM
+adequate/IY
+adequateness/M
+adhere/GDS
+adherence/M
+adherent/SM
+adhesion/M
+adhesive/PSM
+adhesiveness/M
+adiabatic
+adieu/MS
+adios
+adipose
+adi坦s
+adj
+adjacency/M
+adjacent/Y
+adjectival/Y
+adjective/MS
+adjoin/GDS
+adjourn/DGLS
+adjournment/SM
+adjudge/GDS
+adjudicate/GNVXDS
+adjudication/M
+adjudicator/SM
+adjudicatory
+adjunct/MS
+adjuration/MS
+adjure/GDS
+adjust/AGDSL
+adjustable
+adjuster/SM
+adjustment/AMS
+adjutant/SM
+adman/M
+admen
+admin/S
+administer/DGS
+administrate/XDSGNV
+administration/M
+administrative/Y
+administrator/MS
+admirably
+admiral/MS
+admiralty/M
+admiration/M
+admire/BZGDRS
+admirer/M
+admiring/Y
+admissibility/IM
+admissible/I
+admissibly
+admission/AM
+admissions
+admit/AS
+admittance/M
+admitted/Y
+admitting/A
+admix/GDS
+admixture/SM
+admonish/LDSG
+admonishment/MS
+admonition/MS
+admonitory
+ado/M
+adobe/MS
+adolescence/SM
+adolescent/SM
+adopt/AGVDS
+adoptable
+adopter/MS
+adoption/SM
+adorableness/M
+adorably
+adoration/M
+adore/BZGDRS
+adorer/M
+adoring/Y
+adorn/LGDS
+adorned/U
+adornment/MS
+adrenal/MS
+adrenalin's
+adrenaline/M
+adrenergic
+adrift
+adroit/PY
+adroitness/M
+adsorb/SDG
+adsorbent/MS
+adsorption/SM
+adulate/DSGN
+adulation/M
+adulator/MS
+adulatory
+adult/MS
+adulterant/MS
+adulterate/GNDS
+adulterated/U
+adulteration/M
+adulterer/SM
+adulteress/MS
+adulterous
+adultery/SM
+adulthood/M
+adumbrate/GNDS
+adumbration/M
+adv
+advance/LDSMG
+advancement/SM
+advantage/EDSMG
+advantageous/EY
+advent/SM
+adventitious/Y
+adventure/DRSMZG
+adventurer/M
+adventuresome
+adventuress/MS
+adventurism
+adventurist/S
+adventurous/YP
+adventurousness/M
+adverb/SM
+adverbial/SMY
+adversarial
+adversary/SM
+adverse/PRYT
+adverseness/M
+adversity/SM
+advert/SMDG
+advertise/LZGDRS
+advertised/U
+advertisement/MS
+advertiser/M
+advertising/M
+advertorial/SM
+advice/M
+advisability/IM
+advisable/I
+advisably
+advise/LDRSZGB
+advised/UY
+advisement/M
+adviser/M
+advisor/SM
+advisory/SM
+advocacy/M
+advocate/MGDS
+advt
+adware
+adz/MS
+adze/M
+aegis/M
+aeon/SM
+aerate/DSGN
+aeration/M
+aerator/SM
+aerial/SMY
+aerialist/MS
+aerie/MS
+aerobatic/S
+aerobatics/M
+aerobic/S
+aerobically
+aerobics/M
+aerodrome/MS
+aerodynamic/S
+aerodynamically
+aerodynamics/M
+aerogram/S
+aerogramme/S
+aeronautic/S
+aeronautical
+aeronautics/M
+aerosol/MS
+aerospace/M
+aery
+aesthete/MS
+aesthetic/S
+aesthetically
+aestheticism/M
+aesthetics/M
+afar
+affability/M
+affable
+affably
+affair/MS
+affect's
+affect/EGDS
+affectation/SM
+affected/UY
+affecting/Y
+affection/EM
+affectionate/Y
+affections
+afferent
+affiance/GDS
+affidavit/SM
+affiliate's
+affiliate/EGNDS
+affiliated/U
+affiliation/EM
+affiliations
+affine
+affinity/SM
+affirm/AGDS
+affirmation/AMS
+affirmative/MYS
+affix/GMDS
+afflatus/M
+afflict/GDS
+affliction/SM
+affluence/M
+affluent/Y
+afford/GDSB
+affordability
+affordably
+afforest/EGSD
+afforestation/M
+affray/MS
+affront/GMDS
+afghan/MS
+aficionado/MS
+afield
+afire
+aflame
+afloat
+aflutter
+afoot
+aforementioned
+aforesaid
+aforethought
+afoul
+afraid/U
+afresh
+aft/RZ
+afterbirth/M
+afterbirths
+afterburner/MS
+aftercare/M
+aftereffect/MS
+afterglow/SM
+afterimage/MS
+afterlife/M
+afterlives
+aftermarket/MS
+aftermath/M
+aftermaths
+afternoon/MS
+aftershave/SM
+aftershock/SM
+aftertaste/SM
+afterthought/SM
+afterward/S
+afterword/MS
+again
+against
+agape/M
+agar/M
+agate/MS
+agave/M
+age/DSMGJ
+ageing/SM
+ageism/M
+ageist/SM
+ageless/YP
+agelessness/M
+agency/SM
+agenda/SM
+agenesis
+agent/AMS
+ageratum/M
+agglomerate/DSMGNX
+agglomeration/M
+agglutinate/DSXGN
+agglutination/M
+aggrandize/GLDS
+aggrandizement/M
+aggravate/GNXDS
+aggravating/Y
+aggravation/M
+aggregate/MGNDSX
+aggregation/M
+aggregator/SM
+aggression/M
+aggressive/PY
+aggressiveness/M
+aggressor/SM
+aggrieve/DSG
+aggro
+aghast
+agile/Y
+agility/M
+aging/M
+agitate/XGNDS
+agitation/M
+agitator/MS
+agitprop/M
+agleam
+aglitter
+aglow
+agnostic/MS
+agnosticism/M
+ago
+agog
+agonist/S
+agonize/GDS
+agonizing/Y
+agony/SM
+agoraphobia/M
+agoraphobic/MS
+agrarian/MS
+agrarianism/M
+agree/EBLDS
+agreeableness/EM
+agreeably/E
+agreeing/E
+agreement/ESM
+agribusiness/MS
+agricultural/Y
+agriculturalist/MS
+agriculture/M
+agriculturist/MS
+agronomic
+agronomist/MS
+agronomy/M
+aground
+ague/M
+ah
+aha
+ahchoo
+ahead
+ahem
+ahoy
+aid/SMDG
+aide/SM
+aided/U
+aigrette/MS
+ail/SDLG
+aileron/SM
+ailment/SM
+aim/SMDG
+aimless/YP
+aimlessness/M
+ain't
+air/SMDJG
+airbag/MS
+airbase/SM
+airbed/S
+airborne
+airbrush/MDSG
+airbus/MS
+aircraft/M
+aircraftman
+aircraftmen
+aircrew/S
+airdrome/S
+airdrop/SM
+airdropped
+airdropping
+airfare/SM
+airfield/SM
+airflow/M
+airfoil/SM
+airfreight/M
+airgun/S
+airhead/SM
+airily
+airiness/M
+airing/M
+airless/P
+airlessness/M
+airletter/S
+airlift/SGMD
+airline/RSMZ
+airliner/M
+airlock/SM
+airmail/GSMD
+airman/M
+airmen
+airplane/MS
+airplay/M
+airport/SM
+airship/SM
+airshow/S
+airsick/P
+airsickness/M
+airspace/M
+airspeed
+airstrike/MS
+airstrip/SM
+airtight
+airtime/M
+airwaves/M
+airway/MS
+airwoman
+airwomen
+airworthiness/M
+airworthy/P
+airy/PTR
+aisle/MS
+aitch/MS
+ajar
+aka
+akimbo
+akin
+alabaster/M
+alack
+alacrity/M
+alarm/GMDS
+alarming/Y
+alarmist/SM
+alas
+alb/SM
+albacore/SM
+albatross/MS
+albeit
+albinism/M
+albino/MS
+album/MNS
+albumen/M
+albumin/M
+albuminous
+alchemist/SM
+alchemy/M
+alcohol/SM
+alcoholic/MS
+alcoholically
+alcoholism/M
+alcove/MS
+alder/MS
+alderman/M
+aldermen
+alderwoman/M
+alderwomen
+ale/SMV
+aleatory
+alehouse/SM
+alembic/SM
+alert/GMDYPS
+alertness/M
+alewife/M
+alewives
+alfalfa/M
+alfresco
+alga/M
+algae
+algal
+algebra/SM
+algebraic
+algebraically
+algorithm/SM
+algorithmic
+alias/GMDS
+alibi/GMDS
+alien/BGMDS
+alienable/IU
+alienate/DSGN
+alienation/M
+alienist/SM
+alight/GDS
+align/ALGDS
+aligned/U
+aligner/MS
+alignment/AMS
+alike/U
+aliment/MDSG
+alimentary
+alimony/M
+aliveness/M
+aliyah/M
+aliyahs
+alkali/MS
+alkalies
+alkaline
+alkalinity/M
+alkalize/DSG
+alkaloid/SM
+alkyd/MS
+all/M
+allay/GDS
+allegation/MS
+allege/GDS
+alleged/Y
+allegiance/MS
+allegoric
+allegorical/Y
+allegorist/MS
+allegory/SM
+allegretto/MS
+allegro/MS
+allele/MS
+alleluia/SM
+allergen/SM
+allergenic
+allergic
+allergically
+allergist/SM
+allergy/SM
+alleviate/DSGN
+alleviation/M
+alley/MS
+alleyway/SM
+alliance/SM
+alligator/MS
+alliterate/DSXGNV
+alliteration/M
+alliterative/Y
+allocate/ADSGN
+allocation/AM
+allocations
+allot/LS
+allotment/SM
+allotted
+allotting
+allover
+allow/EGDS
+allowable/U
+allowably
+allowance/SM
+alloy/GMDS
+alloyed/U
+allspice/M
+allude/GDS
+allure/MGLDS
+allurement/MS
+alluring/Y
+allusion/SM
+allusive/PY
+allusiveness/M
+alluvial/M
+alluvium/SM
+ally/GDSM
+almanac/SM
+almighty
+almond/MS
+almoner/SM
+almost
+alms/M
+almshouse/MS
+aloe/SM
+aloft
+aloha/MS
+alone
+along
+alongshore
+alongside
+aloof/PY
+aloofness/M
+aloud
+alp/SM
+alpaca/MS
+alpha/MS
+alphabet/SM
+alphabetic
+alphabetical/Y
+alphabetization/SM
+alphabetize/ZGDRS
+alphabetizer/M
+alphanumeric
+alphanumerical/Y
+alpine/S
+already
+alright
+also
+alt/S
+altar/MS
+altarpiece/SM
+alter/GDBS
+alterable/U
+alteration/MS
+altercation/SM
+altered/U
+alternate/DSMYGNVX
+alternation/M
+alternative/MYS
+alternator/SM
+although
+altimeter/MS
+altitude/MS
+alto/SM
+altogether
+altruism/M
+altruist/SM
+altruistic
+altruistically
+alum/SM
+alumina/M
+aluminum/M
+alumna/M
+alumnae
+alumni
+alumnus/M
+alveolar/S
+always
+am/N
+amalgam/SM
+amalgamate/XGNDS
+amalgamation/M
+amanuenses
+amanuensis/M
+amaranth/M
+amaranths
+amaretto/M
+amaryllis/MS
+amass/GDS
+amateur/SM
+amateurish/YP
+amateurishness/M
+amateurism/M
+amatory
+amaze/LMGDS
+amazement/M
+amazing/Y
+amazon/MS
+amazonian
+ambassador/SM
+ambassadorial
+ambassadorship/MS
+ambassadress/MS
+amber/M
+ambergris/M
+ambiance/MS
+ambidexterity/M
+ambidextrous/Y
+ambience/MS
+ambient
+ambiguity/SM
+ambiguous/UY
+ambit
+ambition/MS
+ambitious/YP
+ambitiousness/M
+ambivalence/M
+ambivalent/Y
+amble/MZGDRS
+ambler/M
+ambrosia/M
+ambrosial
+ambulance/MS
+ambulanceman
+ambulancemen
+ambulancewoman
+ambulancewomen
+ambulant
+ambulate/DSXGN
+ambulation/M
+ambulatory/SM
+ambuscade/MGDS
+ambush/GMDS
+ameba/MS
+amebae
+amebic
+ameboid
+ameliorate/GNVDS
+amelioration/M
+amen/B
+amenability/M
+amenably
+amend/BLGDS
+amendment/SM
+amenity/SM
+amerce/GLDS
+amercement/SM
+americium/M
+amethyst/SM
+amiability/M
+amiable
+amiably
+amicability/M
+amicable
+amicably
+amid
+amide/MS
+amidship/S
+amidst
+amigo/MS
+amine/S
+amino
+amir/SM
+amiss
+amitriptyline
+amity/M
+ammeter/SM
+ammo/M
+ammonia/M
+ammonium
+ammunition/M
+amnesia/M
+amnesiac/MS
+amnesic/SM
+amnesty/GDSM
+amniocenteses
+amniocentesis/M
+amnion/MS
+amniotic
+amoeba/MS
+amoebae
+amoebic
+amok
+among
+amontillado/SM
+amoral/Y
+amorality/M
+amorous/YP
+amorousness/M
+amorphous/PY
+amorphousness/M
+amortization/SM
+amortize/DSGB
+amount/GMDS
+amour/MS
+amoxicillin
+amp/SMY
+amperage/M
+ampere/MS
+ampersand/MS
+amphetamine/SM
+amphibian/MS
+amphibious/Y
+amphitheater/SM
+amphora/M
+amphorae
+ampicillin
+ample/TR
+amplification/M
+amplifier/M
+amplify/NDRSXZG
+amplitude/SM
+ampoule/MS
+ampule/MS
+amputate/GNDSX
+amputation/M
+amputee/MS
+amt
+amuck
+amulet/MS
+amuse/LGDS
+amusement/MS
+amusing/Y
+amygdala
+amylase/M
+amyloid
+an/CS
+anabolism/M
+anachronism/SM
+anachronistic
+anachronistically
+anaconda/SM
+anaerobe/SM
+anaerobic
+anaerobically
+anagram/MS
+anal/Y
+analgesia/M
+analgesic/SM
+analog/MS
+analogical/Y
+analogize/GDS
+analogous/YP
+analogousness/M
+analogue/SM
+analogy/SM
+analysand/MS
+analyses/A
+analysis/AM
+analyst/SM
+analytic/S
+analytical/Y
+analyticalally
+analyzable
+analyze/ADSG
+analyzer/SM
+anapest/SM
+anapestic/MS
+anarchic
+anarchically
+anarchism/M
+anarchist/MS
+anarchistic
+anarchy/M
+anathema/SM
+anathematize/DSG
+anatomic
+anatomical/Y
+anatomist/SM
+anatomize/DSG
+anatomy/SM
+ancestor/SM
+ancestral/Y
+ancestress/MS
+ancestry/SM
+anchor/MDGS
+anchorage/MS
+anchorite/MS
+anchorman/M
+anchormen
+anchorpeople
+anchorperson/SM
+anchorwoman/M
+anchorwomen
+anchovy/SM
+ancient/SPMRYT
+ancientness/M
+ancillary/SM
+and
+andante/SM
+andiron/SM
+androgen/M
+androgenic
+androgynous
+androgyny/M
+android/SM
+anecdotal/Y
+anecdote/MS
+anemia/M
+anemic
+anemically
+anemometer/SM
+anemone/SM
+anent
+anesthesia/M
+anesthesiologist/SM
+anesthesiology/M
+anesthetic/SM
+anesthetist/MS
+anesthetization/M
+anesthetize/GDS
+aneurysm/SM
+anew
+angel/MS
+angelfish/MS
+angelic
+angelica/M
+angelical/Y
+anger/GMDS
+angina/M
+angioplasty/SM
+angiosperm/SM
+angle/MZGDRS
+angler/M
+angleworm/MS
+anglicism/S
+anglicize/GDS
+angling/M
+anglophile/S
+anglophone/S
+angora/MS
+angostura
+angrily
+angry/TR
+angst/M
+angstrom/MS
+anguish/GMDS
+angular
+angularity/SM
+angulation
+anhydrous
+aniline/M
+anilingus
+animadversion/MS
+animadvert/GSD
+animal/MS
+animalcule/SM
+animate/ADSGN
+animated/Y
+animation/AM
+animations
+animator/MS
+anime/M
+animism/M
+animist/SM
+animistic
+animosity/SM
+animus/M
+anion/MS
+anionic
+anise/M
+aniseed/M
+anisette/M
+ankh/M
+ankhs
+ankle/MS
+anklebone/MS
+anklet/MS
+annalist/SM
+annals/M
+anneal/GDS
+annelid/MS
+annex/GMDS
+annexation/MS
+annihilate/DSGN
+annihilation/M
+annihilator/SM
+anniversary/SM
+annotate/DSXGNV
+annotation/M
+annotator/MS
+announce/DRSLZG
+announced/U
+announcement/MS
+announcer/M
+annoy/GDS
+annoyance/MS
+annoying/Y
+annual/MYS
+annualized
+annuitant/SM
+annuity/SM
+annul/LS
+annular
+annulled
+annulling
+annulment/SM
+annulus
+annunciation/SM
+anode/MS
+anodize/GDS
+anodyne/MS
+anoint/GDLS
+anointment/M
+anomalous/Y
+anomaly/SM
+anon/S
+anonymity/M
+anonymous/Y
+anopheles/M
+anorak/MS
+anorectic/SM
+anorexia/M
+anorexic/MS
+another
+answer/BMDGS
+answerable/U
+answered/U
+answerphone/S
+ant/SMD
+antacid/SM
+antagonism/SM
+antagonist/SM
+antagonistic
+antagonistically
+antagonize/DSG
+antarctic
+ante/SM
+anteater/MS
+antebellum
+antecedence/M
+antecedent/SM
+antechamber/SM
+antedate/GDS
+antediluvian
+anteing
+antelope/MS
+antenatal
+antenna/SM
+antennae
+anterior
+anteroom/MS
+anthem/MS
+anther/MS
+anthill/SM
+anthologist/SM
+anthologize/DSG
+anthology/SM
+anthracite/M
+anthrax/M
+anthropocentric
+anthropoid/MS
+anthropological/Y
+anthropologist/SM
+anthropology/M
+anthropomorphic
+anthropomorphically
+anthropomorphism/M
+anthropomorphize
+anthropomorphous
+anti/SM
+antiabortion
+antiabortionist/MS
+antiaircraft
+antibacterial/MS
+antibiotic/MS
+antibody/SM
+antic/MS
+anticancer
+antichrist/SM
+anticipate/GNXDS
+anticipated/U
+anticipation/M
+anticipatory
+anticked
+anticking
+anticlerical
+anticlimactic
+anticlimactically
+anticlimax/MS
+anticline/SM
+anticlockwise
+anticoagulant/MS
+anticommunism/M
+anticommunist/SM
+anticyclone/SM
+anticyclonic
+antidemocratic
+antidepressant/MS
+antidote/MS
+antifascist/MS
+antiferromagnetic
+antifreeze/M
+antigen/SM
+antigenic
+antigenicity/M
+antihero/M
+antiheroes
+antihistamine/SM
+antiknock/M
+antilabor
+antilogarithm/SM
+antimacassar/MS
+antimalarial
+antimatter/M
+antimicrobial
+antimissile
+antimony/M
+antineutrino/SM
+antineutron/MS
+antinuclear
+antioxidant/MS
+antiparticle/SM
+antipasti
+antipasto/MS
+antipathetic
+antipathy/SM
+antipersonnel
+antiperspirant/SM
+antiphon/SM
+antiphonal/MYS
+antipodal/S
+antipodean/MS
+antipodes/M
+antipollution
+antipoverty
+antiproton/MS
+antiquarian/SM
+antiquarianism/M
+antiquary/SM
+antiquate/GDS
+antique/DSMG
+antiquity/SM
+antirrhinum/S
+antiscience
+antisemitic
+antisemitism/M
+antisepsis/M
+antiseptic/SM
+antiseptically
+antiserum/MS
+antislavery
+antisocial/Y
+antispasmodic/MS
+antisubmarine
+antitank
+antitheses
+antithesis/M
+antithetic
+antithetical/Y
+antitoxin/MS
+antitrust
+antivenin/MS
+antivenom
+antiviral/MS
+antivirus
+antivivisectionist/MS
+antiwar
+antler/MDS
+antonym/SM
+antonymous
+antrum
+antsy/TR
+anus/MS
+anvil/MS
+anxiety/SM
+anxious/YP
+anxiousness/M
+any
+anybody/SM
+anyhow
+anymore
+anyone/M
+anyplace
+anything/SM
+anytime
+anyway/S
+anywhere
+anywise
+aorta/MS
+aortic
+apace
+apart
+apartheid/M
+apartment/MS
+apathetic
+apathetically
+apathy/M
+apatite/M
+ape/DSMG
+apelike
+aperitif/MS
+aperture/SM
+apex/MS
+aphasia/M
+aphasic/MS
+aphelia
+aphelion/SM
+aphid/MS
+aphorism/MS
+aphoristic
+aphoristically
+aphrodisiac/SM
+apiarist/SM
+apiary/SM
+apical/Y
+apiece
+apish/Y
+aplenty
+aplomb/M
+apocalypse/SM
+apocalyptic
+apocrypha/M
+apocryphal/Y
+apogee/MS
+apolitical/Y
+apologetic/U
+apologetically
+apologia/SM
+apologist/MS
+apologize/GDS
+apology/SM
+apoplectic
+apoplexy/SM
+apoptosis
+apoptotic
+apostasy/SM
+apostate/SM
+apostatize/GDS
+apostle/MS
+apostleship/M
+apostolic
+apostrophe/MS
+apothecary/SM
+apothegm/SM
+apotheoses
+apotheosis/M
+app/SM
+appall/GDS
+appalling/Y
+appaloosa/MS
+apparatchik/S
+apparatus/MS
+apparel/MDGS
+apparent/Y
+apparition/SM
+appeal/GMDS
+appealing/UY
+appear/AESDG
+appearance/EAMS
+appease/LZGDRS
+appeasement/SM
+appeaser/M
+appellant/SM
+appellate/XN
+appellation/M
+append/GDS
+appendage/SM
+appendectomy/SM
+appendices
+appendicitis/M
+appendix/MS
+appertain/GDS
+appetite/SM
+appetizer/MS
+appetizing/Y
+applaud/ZGDRS
+applauder/M
+applause/M
+apple/MS
+applejack/M
+applesauce/M
+applet/MS
+appliance/SM
+applicability/M
+applicable/I
+applicably
+applicant/SM
+application/AM
+applicator/SM
+applier/MS
+applique/DSM
+appliqueing
+appliqu辿/SMG
+appliqu辿d
+apply/ANXGDS
+appoint/AELSVGD
+appointee/SM
+appointment's/A
+appointment/ESM
+apportion/AGDLS
+apportionment/AM
+appose/GDS
+apposite/YNVP
+appositeness/M
+apposition/M
+appositive/SM
+appraisal/AMS
+appraise/ADSG
+appraiser/MS
+appreciable/I
+appreciably/I
+appreciate/DSXGNV
+appreciated/U
+appreciation/M
+appreciative/Y
+appreciator/MS
+appreciatory
+apprehend/GDS
+apprehension/MS
+apprehensive/YP
+apprehensiveness/M
+apprentice/DSMG
+apprenticeship/MS
+apprise/GDS
+apprize/GDS
+approach/GBMDS
+approachable/UI
+approbation/EM
+approbations
+appropriate/PYGNXDS
+appropriated/U
+appropriateness/IM
+appropriation/M
+appropriator/SM
+approval/EM
+approvals
+approve/EGDS
+approved/U
+approving/EY
+approx
+approximate/DSXYGN
+approximation/M
+appurtenance/SM
+appurtenant
+apricot/MS
+apron/MS
+apropos
+apse/SM
+apt/IYPT
+apter
+aptitude/SM
+aptness/IM
+aqua/SM
+aquaculture/M
+aqualung/MS
+aquamarine/SM
+aquanaut/MS
+aquaplane/MGDS
+aquarium/MS
+aquatic/SM
+aquatically
+aquatics/M
+aquatint/S
+aquavit/M
+aqueduct/MS
+aqueous
+aquifer/SM
+aquiline
+arabesque/MS
+arability/M
+arachnid/MS
+arachnophobia
+arbiter/SM
+arbitrage/MZGDRS
+arbitrager/M
+arbitrageur/SM
+arbitrament/SM
+arbitrarily
+arbitrariness/M
+arbitrary/P
+arbitrate/GNDS
+arbitration/M
+arbitrator/MS
+arbor/MS
+arboreal
+arboretum/SM
+arborvitae/SM
+arbutus/MS
+arc/SMDG
+arcade/MS
+arcane
+arch/PZTGVMDRSY
+archaeological/Y
+archaeologist/SM
+archaeology/M
+archaic
+archaically
+archaism/MS
+archaist/MS
+archangel/MS
+archbishop/SM
+archbishopric/SM
+archdeacon/SM
+archdiocesan
+archdiocese/MS
+archduchess/MS
+archduke/MS
+archenemy/SM
+archeological/Y
+archeologist/SM
+archeology/M
+archer/M
+archery/M
+archetypal
+archetype/MS
+archfiend/MS
+archiepiscopal
+archipelago/MS
+archipelagoes
+architect/SM
+architectonic/S
+architectonics/M
+architectural/Y
+architecture/MS
+architrave/SM
+archival
+archive/DSMG
+archivist/MS
+archness/M
+archway/SM
+arctic/MS
+ardent/Y
+ardor/MS
+arduous/YP
+arduousness/M
+are/SMB
+area/SM
+areal
+aren't
+arena/MS
+argent/M
+arginine
+argon/M
+argosy/SM
+argot/MS
+arguable/IU
+arguably/U
+argue/ZGDRS
+arguer/M
+argument/MS
+argumentation/M
+argumentative/PY
+argumentativeness/M
+argyle/MS
+aria/SM
+arid/Y
+aridity/M
+aright
+arise/GS
+arisen
+aristocracy/SM
+aristocrat/SM
+aristocratic
+aristocratically
+arithmetic/M
+arithmetical/Y
+arithmetician/MS
+ark/SM
+arm's
+arm/EAGDS
+armada/MS
+armadillo/SM
+armament/AEM
+armaments
+armature/MS
+armband/MS
+armchair/MS
+armed/U
+armful/MS
+armhole/SM
+armistice/SM
+armlet/MS
+armload/S
+armor/ZGMDRS
+armored/U
+armorer/M
+armorial
+armory/SM
+armpit/MS
+armrest/SM
+army/SM
+aroma/MS
+aromatherapist/MS
+aromatherapy/M
+aromatic/MS
+aromatically
+arose
+around
+arousal/M
+arouse/GDS
+arpeggio/MS
+arr
+arraign/DGSL
+arraignment/SM
+arrange/AESDLG
+arrangement's/E
+arrangement/ASM
+arranger/SM
+arrant
+arras/MS
+array/EGMDS
+arrears/M
+arrest/AGMDS
+arrhythmia/M
+arrhythmic
+arrhythmical
+arrival/MS
+arrive/GDS
+arrogance/M
+arrogant/Y
+arrogate/GNDS
+arrogation/M
+arrow/MS
+arrowhead/MS
+arrowroot/M
+arroyo/MS
+arsed
+arsenal/MS
+arsenic/M
+arsing
+arson/M
+arsonist/SM
+art/SM
+arterial
+arteriole/MS
+arteriosclerosis/M
+artery/SM
+artful/PY
+artfulness/M
+arthritic/MS
+arthritis/M
+arthropod/MS
+arthroscope/SM
+arthroscopic
+arthroscopy
+artichoke/SM
+article/MDS
+articulacy/I
+articular
+articulate/YGNPDSX
+articulateness/IM
+articulation/M
+artifact/SM
+artifice/RSMZ
+artificer/M
+artificial/Y
+artificiality/M
+artillery/M
+artilleryman/M
+artillerymen
+artiness/M
+artisan/MS
+artist/MS
+artiste/MS
+artistic/I
+artistically
+artistry/M
+artless/PY
+artlessness/M
+artsy/TR
+artwork/MS
+arty/PTR
+arugula
+arum/SM
+asap
+asbestos/M
+ascend/AGDS
+ascendance/M
+ascendancy/M
+ascendant/SM
+ascension/MS
+ascent/MS
+ascertain/GDSBL
+ascertainment/M
+ascetic/MS
+ascetically
+asceticism/M
+ascot/MS
+ascribe/GBDS
+ascription/M
+aseptic
+aseptically
+asexual/Y
+asexuality/M
+ash/MDNSG
+ashamed/UY
+ashcan/MS
+ashlar/MS
+ashore
+ashram/MS
+ashtray/SM
+ashy/TR
+aside/MS
+asinine/Y
+asininity/SM
+ask/SDG
+askance
+asked/U
+askew
+aslant
+asleep
+asocial
+asp/SMNX
+asparagus/M
+aspartame/M
+aspect/MS
+aspen/M
+asperity/SM
+aspersion/MS
+asphalt/MDGS
+asphodel/SM
+asphyxia/M
+asphyxiate/DSXGN
+asphyxiation/M
+aspic/MS
+aspidistra/MS
+aspirant/MS
+aspirate/MGNDSX
+aspiration/M
+aspirator/SM
+aspire/GDS
+aspirin/MS
+ass/MS
+assail/GBDS
+assailable/U
+assailant/SM
+assassin/SM
+assassinate/GNXDS
+assassination/M
+assault/MDRGS
+assay/ZGMDRS
+assayer/M
+assemblage/SM
+assemble/AEGSD
+assembler/MS
+assemblies
+assembly/AM
+assemblyman/M
+assemblymen
+assemblywoman/M
+assemblywomen
+assent/GMDS
+assert/AGVDS
+assertion/AM
+assertions
+assertive/YP
+assertiveness/M
+assess/ALGDS
+assessment/ASM
+assessor/MS
+asset/MS
+asseverate/DSGN
+asseveration/M
+asshole/MS!
+assiduity/M
+assiduous/PY
+assiduousness/M
+assign's
+assign/ALGDS
+assignable
+assignation/MS
+assigned/U
+assignee/M
+assigner/MS
+assignment/AMS
+assignor/MS
+assimilate/DSGN
+assimilated/U
+assimilation/M
+assist/GVMDS
+assistance/M
+assistant/SM
+assisted/U
+assize/MS
+assn
+assoc
+associate's
+associate/EDSGNV
+association/EM
+associations
+associativity
+assonance/M
+assonant/MS
+assort/GLDS
+assortative
+assortment/MS
+asst
+assuage/GDS
+assume/BGDS
+assumption/SM
+assumptive
+assurance/ASM
+assure/AGDS
+assured/MYS
+astatine/M
+aster/EMS
+asterisk/GMDS
+astern
+asteroid/MS
+asthma/M
+asthmatic/SM
+asthmatically
+astigmatic
+astigmatism/SM
+astir
+astonish/DSLG
+astonishing/Y
+astonishment/M
+astound/GDS
+astounding/Y
+astraddle
+astrakhan/M
+astral
+astray
+astride
+astringency/M
+astringent/SMY
+astrolabe/SM
+astrologer/SM
+astrological/Y
+astrologist/MS
+astrology/M
+astronaut/MS
+astronautic/S
+astronautical
+astronautics/M
+astronomer/SM
+astronomic
+astronomical/Y
+astronomy/M
+astrophysical
+astrophysicist/MS
+astrophysics/M
+astute/PYTR
+astuteness/M
+asunder
+asylum/SM
+asymmetric
+asymmetrical/Y
+asymmetry/SM
+asymptomatic
+asymptotic
+asymptotically
+asynchronous/Y
+at
+atavism/M
+atavist/SM
+atavistic
+ataxia/M
+ataxic/MS
+ate
+atelier/SM
+atheism/M
+atheist/MS
+atheistic
+atherosclerosis/M
+atherosclerotic
+athirst
+athlete/MS
+athletic/S
+athletically
+athleticism
+athletics/M
+athwart
+atilt
+atishoo
+atlas/MS
+atmosphere/MS
+atmospheric/S
+atmospherically
+atmospherics/M
+atoll/MS
+atom/SM
+atomic
+atomically
+atomize/ZGDRS
+atomizer/M
+atonal/Y
+atonality/M
+atone/LGDS
+atonement/M
+atop
+atria
+atrial
+atrioventricular
+atrium/M
+atrocious/PY
+atrociousness/M
+atrocity/SM
+atrophy/DSMG
+atropine/M
+attach/ALGDS
+attache/BM
+attached/U
+attachment/AM
+attachments
+attach辿/MS
+attack/ZGMDRS
+attacker/M
+attain/AGDS
+attainability/M
+attainable/U
+attainder/M
+attainment/SM
+attar/M
+attempt's
+attempt/ASDG
+attend/SDRZG
+attendance/SM
+attendant/SM
+attended/U
+attendee/SM
+attention/IM
+attentions
+attentive/IPY
+attentiveness/IM
+attenuate/DSGN
+attenuation/M
+attest/SDG
+attestation/SM
+attested/U
+attic/SM
+attire/DSMG
+attitude/SM
+attitudinal
+attitudinize/GDS
+attn
+attorney/MS
+attract/SGVDB
+attractant/MS
+attraction/MS
+attractive/UY
+attractiveness/M
+attribute/DSMGNVBX
+attributed/U
+attribution/M
+attributive/MYS
+attrition/M
+attune/DSG
+atty
+atwitter
+atypical/Y
+aubergine/S
+auburn/M
+auction/MDGS
+auctioneer/SM
+audacious/YP
+audaciousness/M
+audacity/M
+audibility/IM
+audible/MS
+audibly/I
+audience/MS
+audio/MS
+audiological
+audiologist/SM
+audiology/M
+audiometer/SM
+audiophile/SM
+audiotape/SM
+audiovisual/S
+audiovisuals/M
+audit/GMDS
+audition/SMDG
+auditor/MS
+auditorium/SM
+auditory
+auger/MS
+aught/MS
+augment/DRZGS
+augmentation/MS
+augmentative
+augmenter/M
+augur/GMDS
+augury/SM
+august/PTRY
+augustness/M
+auk/SM
+aunt/SM
+auntie/SM
+aura/MS
+aural/Y
+aureola/M
+aureole/SM
+aureus
+auricle/SM
+auricular
+aurora/SM
+auscultate/GNDSX
+auscultation/M
+auspice/SM
+auspicious/IY
+auspiciousness/M
+austere/RYT
+austerity/SM
+austral
+authentic/IU
+authentically
+authenticate/XGNDS
+authenticated/U
+authentication/M
+authenticity/M
+author/SMDG
+authoress/MS
+authorial
+authoritarian/MS
+authoritarianism/M
+authoritative/YP
+authoritativeness/M
+authority/SM
+authorization/MS
+authorize/AGDS
+authorized/U
+authorship/M
+autism/M
+autistic
+auto/MS
+autobahn/SM
+autobiographer/SM
+autobiographic
+autobiographical/Y
+autobiography/SM
+autoclave/MS
+autocracy/SM
+autocrat/SM
+autocratic
+autocratically
+autocross
+autodidact/SM
+autograph/MDG
+autographs
+autoimmune
+autoimmunity/M
+automaker/SM
+automate/GNDS
+automatic/SM
+automatically
+automation/M
+automatism/M
+automatize/GDS
+automaton/SM
+automobile/DSMG
+automotive
+autonomic
+autonomous/Y
+autonomy/M
+autopilot/SM
+autopsy/GDSM
+autosuggestion
+autoworker/MS
+autumn/SM
+autumnal
+aux
+auxiliary/SM
+auxin/M
+av/RZ
+avail/BGMDS
+availability/UM
+available/U
+avalanche/SM
+avarice/M
+avaricious/Y
+avast
+avatar/MS
+avaunt
+avdp
+ave
+avenge/ZGDRS
+avenger/M
+avenue/MS
+average/MYGDS
+averred
+averring
+averse/XN
+aversion/M
+avert/GDS
+avg
+avian
+aviary/SM
+aviation/M
+aviator/MS
+aviatrices
+aviatrix/MS
+avid/Y
+avidity/M
+avionic/S
+avionics/M
+avitaminosis/M
+avocado/SM
+avocation/MS
+avocational
+avoid/SDGB
+avoidable/U
+avoidably/U
+avoidance/M
+avoidant
+avoirdupois/M
+avouch/DSG
+avow/EDGS
+avowal/ESM
+avowed/Y
+avuncular/Y
+aw
+await/GDS
+awake/GS
+awaken/AGDS
+awakening/SM
+award/GMDS
+awardee/S
+aware/UP
+awareness/UM
+awash
+away
+awe/DSMG
+aweigh
+awesome/YP
+awesomeness/M
+awestruck
+awful/YP
+awfuller
+awfullest
+awfulness/M
+awhile
+awkward/RYPT
+awkwardness/M
+awl/SM
+awn/GJSM
+awning/M
+awoke
+awoken
+awol
+awry
+ax/MDSG
+axial/Y
+axiom/SM
+axiomatic
+axiomatically
+axis/M
+axle/MS
+axletree/SM
+axolotl/SM
+axon/MS
+ayah/M
+ayahs
+ayatollah/M
+ayatollahs
+aye/SM
+azalea/SM
+azimuth/M
+azimuths
+azure/SM
+b/KDT
+baa/SMDG
+babble/MZGDRS
+babbler/M
+babe/SM
+babel/MS
+baboon/MS
+babushka/SM
+baby/TGDRSM
+babyhood/M
+babyish
+babysat
+babysit/S
+babysitter/MS
+babysitting/M
+baccalaureate/SM
+baccarat/M
+bacchanal/MS
+bacchanalia/M
+bacchanalian/MS
+baccy
+bachelor/SM
+bachelorhood/M
+bacillary
+bacilli
+bacillus/M
+back/SJZGMDR
+backache/MS
+backbench/S
+backbit
+backbite/ZGRS
+backbiter/M
+backbitten
+backboard/SM
+backbone/MS
+backbreaking
+backchat
+backcloth
+backcloths
+backcomb/DSG
+backdate/GDS
+backdoor
+backdrop/MS
+backer/M
+backfield/SM
+backfire/MGDS
+backgammon/M
+background/MRZS
+backgrounder/M
+backhand/MDRSZG
+backhanded/Y
+backhander/M
+backhoe/MS
+backing/M
+backlash/MS
+backless
+backlog/MS
+backlogged
+backlogging
+backpack/ZGMDRS
+backpacker/M
+backpacking/M
+backpedal/SDG
+backrest/SM
+backroom/S
+backscratching/M
+backseat/SM
+backside/SM
+backslapper/SM
+backslapping/M
+backslash/MS
+backslid
+backslide/RSZG
+backslider/M
+backspace/DSMG
+backspin/M
+backstabber/MS
+backstabbing
+backstage/M
+backstair/S
+backstop/SM
+backstopped
+backstopping
+backstory/S
+backstreet/S
+backstretch/MS
+backstroke/MGDS
+backtalk/M
+backtrack/SDG
+backup/MS
+backward/PSY
+backwardness/M
+backwash/M
+backwater/SM
+backwoods/M
+backwoodsman/M
+backwoodsmen
+backyard/SM
+bacon/M
+bacteria/M
+bacterial
+bactericidal
+bactericide/SM
+bacteriologic
+bacteriological
+bacteriologist/SM
+bacteriology/M
+bacterium/M
+bad/MYP
+badder
+baddest
+baddie/M
+baddy/SM
+bade
+badge/MZRS
+badger/GMD
+badinage/M
+badlands/M
+badman/M
+badmen
+badminton/M
+badmouth/GD
+badmouths
+badness/M
+baffle/MZGDRSL
+bafflement/M
+baffler/M
+bag/SM
+bagatelle/SM
+bagel/MS
+bagful/MS
+baggage/M
+bagged
+baggie/M
+baggily
+bagginess/M
+bagging
+baggy/PTRS
+bagpipe/MZRS
+bagpiper/M
+baguette/MS
+bah
+baht/SM
+bail/SBGMD
+bailey/S
+bailiff/S
+bailiwick/MS
+bailout/SM
+bailsman/M
+bailsmen
+bairn/MS
+bait/SGMD
+baize/M
+bake/DRSMZG
+baked/U
+baker/M
+bakery/SM
+bakeshop/MS
+baklava/M
+baksheesh/M
+balaclava/MS
+balalaika/MS
+balance's
+balance/UDSG
+balboa/SM
+balcony/SM
+bald/STGPDRY
+balderdash/M
+baldfaced
+baldness/M
+baldric/SM
+baldy/S
+bale/DRSMZG
+baleen/M
+baleful/PY
+balefulness/M
+baler/M
+balk/SGMD
+balky/RT
+ball/SGMD
+ballad/SM
+balladeer/MS
+balladry/M
+ballast/GSMD
+ballcock/MS
+ballerina/SM
+ballet/SM
+balletic
+ballgame/MS
+ballgirl/S
+ballgown/S
+ballistic/S
+ballistics/M
+balloon/SGMD
+balloonist/MS
+ballot/SMDG
+ballpark/MS
+ballplayer/MS
+ballpoint/MS
+ballroom/MS
+balls/DSG
+ballsy/RT
+bally
+ballyhoo/SMDG
+balm/SM
+balminess/M
+balmy/RTP
+baloney/M
+balsa/MS
+balsam/SM
+balsamic
+baluster/SM
+balustrade/MS
+bamboo/SM
+bamboozle/DSG
+ban/SM
+banal/Y
+banality/SM
+banana/SM
+band's
+band/ESGD
+bandage/DSMG
+bandana/SM
+bandanna/MS
+bandbox/MS
+bandeau/M
+bandeaux
+bandit/SM
+banditry/M
+bandleader/S
+bandmaster/SM
+bandoleer/SM
+bandolier/SM
+bandsman/M
+bandsmen
+bandstand/SM
+bandwagon/SM
+bandwidth
+bandwidths
+bandy/DRSTG
+bane/SM
+baneful
+bang/SGMDR
+bangle/SM
+bani
+banish/GLDS
+banishment/M
+banister/SM
+banjo/MS
+banjoist/SM
+bank/SZGBMDR
+bankbook/SM
+bankcard/SM
+banker/M
+banking/M
+banknote/SM
+bankroll/SGMD
+bankrupt/SGMD
+bankruptcy/SM
+banned
+banner/SM
+banning
+bannock/MS
+banns/M
+banquet/ZGMDRS
+banqueter/M
+banquette/SM
+banshee/MS
+bantam/SM
+bantamweight/SM
+banter/GSMD
+bantering/Y
+banyan/SM
+banzai/SM
+baobab/SM
+bap/S
+baptism/MS
+baptismal
+baptist/S
+baptistery/SM
+baptistry/SM
+baptize/ZGDRS
+baptized/U
+baptizer/M
+bar's
+bar/ECUTS
+barb/SZGMDR
+barbacoa
+barbarian/SM
+barbarianism/MS
+barbaric
+barbarically
+barbarism/SM
+barbarity/SM
+barbarize/DSG
+barbarous/Y
+barbecue/DSMG
+barbel/SM
+barbell/MS
+barber/GMD
+barberry/SM
+barbershop/MS
+barbie/S
+barbiturate/SM
+barbwire/M
+barcarole/SM
+bard/SM
+bardic
+bare/DRSPYG
+bareback/D
+barefaced/Y
+barefoot/D
+barehanded
+bareheaded
+barelegged
+bareness/M
+barf/SGMDY
+barfly/SM
+bargain/MDRZGS
+bargainer/M
+barge/MGDS
+bargeman/M
+bargemen
+barhop/S
+barhopped
+barhopping
+barista/MS
+baritone/MS
+barium/M
+bark's
+bark/CSGD
+barkeep/ZMRS
+barkeeper/M
+barker/SM
+barley/M
+barmaid/MS
+barman/M
+barmen
+barmy/RT
+barn/SM
+barnacle/MDS
+barney/S
+barnstorm/SDRZG
+barnstormer/M
+barnyard/SM
+barometer/MS
+barometric
+barometrically
+baron/MS
+baronage/MS
+baroness/MS
+baronet/MS
+baronetcy/SM
+baronial
+barony/SM
+baroque/M
+barque/SM
+barrack/MDGS
+barracuda/SM
+barrage/MGDS
+barre/MGJDS
+barred/UEC
+barrel/GSMD
+barrelled
+barrelling
+barren/TPSMR
+barrenness/M
+barrette/SM
+barricade/MGDS
+barrier/MS
+barring/ECU
+barrio/SM
+barrister/MS
+barroom/MS
+barrow/SM
+bartender/SM
+barter/ZGSMDR
+barterer/M
+baryon/SM
+basal/Y
+basalt/M
+basaltic
+base's
+base/CDSLTG
+baseball/SM
+baseboard/MS
+baseless
+baseline/MS
+basely
+baseman/M
+basemen
+basement/CMS
+baseness/M
+baser
+bash/GMDS
+bashful/PY
+bashfulness/M
+bashing/M
+basic/MS
+basically
+basil/M
+basilica/MS
+basilisk/MS
+basin/MS
+basinful/MS
+basis/M
+bask/SGD
+basket/SM
+basketball/MS
+basketry/M
+basketwork/M
+basque/S
+bass/MS
+basset/SM
+bassinet/MS
+bassist/MS
+basso/MS
+bassoon/MS
+bassoonist/SM
+basswood/MS
+bast/M
+bastard/MS
+bastardization/MS
+bastardize/GDS
+bastardy/M
+baste/ZGNXDRS
+baster/M
+bastion/M
+bat/SM
+batch/MDSG
+bate/KACGSD
+bath/ZGMDRS
+bathe/M
+bather/M
+bathetic
+bathhouse/MS
+bathing/M
+bathmat/MS
+bathos/M
+bathrobe/SM
+bathroom/SM
+baths
+bathtub/MS
+bathwater
+bathyscaph/MS
+bathyscaphe/M
+bathyscaphs
+bathysphere/MS
+batik/MS
+batiste/M
+batman/M
+batmen
+baton/MS
+batsman/M
+batsmen
+battalion/SM
+batted
+batten/GSMD
+batter/JZGSMDR
+batterer/M
+battery/SM
+batting/M
+battle/LDRSMZG
+battleax/MS
+battleaxe/M
+battledore/SM
+battledress
+battlefield/MS
+battlefront/MS
+battleground/MS
+battlement/SM
+battler/M
+battleship/SM
+batty/RT
+bauble/SM
+baud/SM
+bauxite/M
+bawd/SM
+bawdily
+bawdiness/M
+bawdy/PRT
+bawl/SGMD
+bay/SMDG
+bayberry/SM
+bayonet/SMDG
+bayou/MS
+bazaar/SM
+bazillion/S
+bazooka/SM
+bbl
+bdrm
+be
+beach/MDSG
+beachcomber/SM
+beachfront
+beachhead/MS
+beachwear/M
+beacon/SM
+bead/SGMD
+beading/M
+beadle/SM
+beady/RT
+beagle/SM
+beak/SZMDR
+beaker/M
+beam/SGMD
+bean/SGMD
+beanbag/MS
+beanfeast/S
+beanie/SM
+beanpole/MS
+beansprout/S
+beanstalk/MS
+bear/SZGBJMR
+bearable/U
+bearably/U
+beard/MDGS
+beardless
+bearer/M
+bearing/M
+bearish/PY
+bearishness/M
+bearlike
+bearskin/MS
+beast/MS
+beastliness/M
+beastly/TPRM
+beat/SZGBMNRJ
+beatable/U
+beaten/U
+beater/M
+beatific
+beatifically
+beatification/M
+beatify/GXNDS
+beating/M
+beatitude/SM
+beatnik/MS
+beau/SM
+beaut/MS
+beauteous/Y
+beautician/SM
+beautification/M
+beautifier/M
+beautiful/Y
+beautify/NDRSZG
+beauty/SM
+beaux
+beaver/SGMD
+bebop/MS
+becalm/GSD
+became
+because
+beck/SM
+beckon/SGD
+becloud/GDS
+become/S
+becoming/UY
+becquerel/S
+bed/SM
+bedaub/GSD
+bedazzle/GDSL
+bedazzlement/M
+bedbug/SM
+bedchamber/S
+bedclothes/M
+bedded
+bedder
+bedding/M
+bedeck/GSD
+bedevil/LGDS
+bedevilment/M
+bedfellow/SM
+bedhead/S
+bedim/S
+bedimmed
+bedimming
+bedizen/GDS
+bedlam/SM
+bedpan/SM
+bedpost/SM
+bedraggle/GDS
+bedridden
+bedrock/SM
+bedroll/SM
+bedroom/SM
+bedside/SM
+bedsit/S
+bedsitter/S
+bedsore/SM
+bedspread/SM
+bedstead/SM
+bedtime/SM
+bee/RSMZGJ
+beebread/M
+beech/MS
+beechnut/MS
+beef/SGMD
+beefburger/SM
+beefcake/MS
+beefiness/M
+beefsteak/MS
+beefy/RPT
+beehive/MS
+beekeeper/MS
+beekeeping/M
+beeline/MS
+been
+beep/SZGMDR
+beeper/M
+beer/M
+beery/TR
+beeswax/M
+beet/SM
+beetle/MGDS
+beetroot/S
+beeves
+befall/SGN
+befell
+befit/S
+befitted
+befitting/Y
+befog/S
+befogged
+befogging
+before
+beforehand
+befoul/DGS
+befriend/SGD
+befuddle/GLDS
+befuddlement/M
+beg/S
+began
+begat
+beget/S
+begetter/S
+begetting
+beggar/MDYGS
+beggary/M
+begged
+begging
+begin/S
+beginner/SM
+beginning/MS
+begone
+begonia/SM
+begot
+begotten
+begrime/DSG
+begrudge/DSG
+begrudging/Y
+beguile/DRSZGL
+beguilement/M
+beguiler/M
+beguiling/Y
+beguine/SM
+begum/MS
+begun
+behalf/M
+behalves
+behave/GDS
+behavior/SM
+behavioral/Y
+behaviorism/M
+behaviorist/MS
+behead/DGS
+beheld
+behemoth/M
+behemoths
+behest/MS
+behind/MS
+behindhand
+behold/NRZGS
+beholder/M
+behoove/DSG
+beige/M
+being/M
+bejewel/SDG
+belabor/SDG
+belated/Y
+belay/GDS
+belch/GMDS
+beleaguer/GSD
+belfry/SM
+belie/DS
+belief/EUM
+beliefs
+believable/U
+believably/U
+believe/EDRSZG
+believer/EUMS
+believing/U
+belittle/LDSG
+belittlement/M
+bell/SGMD
+belladonna/M
+bellboy/SM
+belle/MS
+belled/A
+belletrist/MS
+belletristic
+bellhop/SM
+bellicose
+bellicosity/M
+belligerence/M
+belligerency/M
+belligerent/MYS
+belling/A
+bellman/M
+bellmen
+bellow/MDGS
+bellwether/MS
+belly/GDSM
+bellyache/MGDS
+bellybutton/SM
+bellyful/MS
+belong/JDGS
+belonging/M
+beloved/SM
+below
+belt/SGMD
+beltway/SM
+beluga/MS
+belying
+bemire/GDS
+bemoan/DGS
+bemuse/LGDS
+bemused/Y
+bemusement/M
+bench/GMDS
+benchmark/MS
+bend/BSZGMR
+bender/M
+bendy/TR
+beneath
+benedictine
+benediction/SM
+benedictory
+benefaction/SM
+benefactor/MS
+benefactress/MS
+benefice/SM
+beneficence/M
+beneficent/Y
+beneficial/Y
+beneficiary/SM
+benefit/SMDG
+benevolence/SM
+benevolent/Y
+benighted/Y
+benign/Y
+benignant
+benignity/M
+bent/SM
+bentonite
+bentwood/M
+benumb/DSG
+benzene/M
+benzine/M
+benzyl
+bequeath/DG
+bequeaths
+bequest/MS
+berate/GDS
+bereave/DSLG
+bereavement/MS
+bereft
+beret/MS
+berg/SM
+beriberi/M
+berk/S
+berkelium/M
+berm/SM
+berry/GDSM
+berrylike
+berserk
+berth/GMD
+berths
+beryl/MS
+beryllium/M
+beseech/ZGRS
+beseecher/M
+beseeching/Y
+beseem/DSG
+beset/S
+besetting
+beside/S
+besiege/ZGDRS
+besieger/M
+besmear/DSG
+besmirch/GDS
+besom/MS
+besot/S
+besotted
+besotting
+besought
+bespangle/DSG
+bespatter/GSD
+bespeak/SG
+bespectacled
+bespoke
+bespoken
+best/SGMD
+bestial/Y
+bestiality/M
+bestiary/SM
+bestir/S
+bestirred
+bestirring
+bestow/DGS
+bestowal/SM
+bestrew/SDG
+bestrewn
+bestridden
+bestride/SG
+bestrode
+bestseller/MS
+bestselling
+bet/SM
+beta/SM
+betake/GS
+betaken
+betcha
+betel/M
+bethink/SG
+bethought
+betide/GDS
+betimes
+betoken/GDS
+betook
+betray/DRZGS
+betrayal/SM
+betrayer/M
+betroth/DG
+betrothal/SM
+betrothed/M
+betroths
+better/MDGLS
+betterment/M
+betting
+bettor/MS
+between
+betwixt
+bevel/GMDS
+beverage/SM
+bevvy/S
+bevy/SM
+bewail/DGS
+beware/GDS
+bewhiskered
+bewigged
+bewilder/LSGD
+bewildering/Y
+bewilderment/M
+bewitch/GLDS
+bewitching/Y
+bewitchment/M
+bey/SM
+beyond
+bezel/MS
+bf
+bhaji
+bi/SMRZ
+biannual/Y
+bias/GMDS
+biased/U
+biassed
+biassing
+biathlon/SM
+bib/SM
+bible/MS
+biblical
+bibliographer/MS
+bibliographic
+bibliographical/Y
+bibliography/SM
+bibliophile/SM
+bibulous
+bicameral
+bicameralism/M
+bicarb/MS
+bicarbonate/MS
+bicentenary/SM
+bicentennial/SM
+bicep/MS
+biceps/M
+bicker/MDRZGS
+bickerer/M
+biconcave
+biconvex
+bicuspid/MS
+bicycle/DRSMZG
+bicycler/M
+bicyclist/SM
+bid/SMG
+biddable
+bidden/U
+bidder/MS
+bidding/M
+biddy/SM
+bide/S
+bidet/MS
+bidirectional/Y
+biennial/MYS
+biennium/MS
+bier/M
+biff/SGD
+bifocal/S
+bifocals/M
+bifurcate/XDSGN
+bifurcation/M
+big/P
+bigamist/SM
+bigamous
+bigamy/M
+bigger
+biggest
+biggie/MS
+biggish
+bighead/SM
+bighearted/P
+bigheartedness/M
+bighorn/SM
+bight/MS
+bigmouth/M
+bigmouths
+bigness/M
+bigot/MDS
+bigotry/SM
+bigwig/MS
+bijou/M
+bijoux
+bike/DRSMZG
+biker/M
+bikini/MS
+bilabial/MS
+bilateral/Y
+bilberry/S
+bile/M
+bilge/MS
+bilingual/SMY
+bilingualism/M
+bilious/P
+biliousness/M
+bilirubin
+bilk/SZGDR
+bilker/M
+bill/SBJGMD
+billboard/MS
+billet/GMDS
+billfold/SM
+billhook/S
+billiard/S
+billiards/M
+billing/M
+billingsgate/M
+billion/MHS
+billionaire/SM
+billionth/M
+billionths
+billow/GMDS
+billowy
+billy/SM
+billycan/S
+bimbo/MS
+bimetallic/SM
+bimetallism/M
+bimodal
+bimonthly/SM
+bin/SM
+binary/SM
+binaural
+bind's
+bind/AUGS
+binder/MS
+bindery/SM
+binding/MS
+bindweed/M
+binge/MGDS
+bingeing
+bingo/M
+binman
+binmen
+binnacle/SM
+binned
+binning
+binocular/MS
+binomial/SM
+bio/SM
+biochemical/SMY
+biochemist/MS
+biochemistry/M
+biodegradability/M
+biodegrade/DSGB
+biodiversity/M
+bioethics/M
+biofeedback/M
+biofilm/MS
+biog
+biographer/SM
+biographic
+biographical/Y
+biography/SM
+biol
+biologic
+biological/Y
+biologist/MS
+biology/M
+biomarker/MS
+biomass/M
+biomedical
+bionic/S
+bionically
+bionics/M
+biophysical
+biophysicist/MS
+biophysics/M
+biopic/MS
+biopsy/GDSM
+bioreactor/S
+biorhythm/MS
+biosensor/S
+biosphere/SM
+biosynthesis
+biotech
+biotechnological
+biotechnology/M
+biotin/M
+bipartisan
+bipartisanship/M
+bipartite
+biped/MS
+bipedal
+biplane/MS
+bipolar
+bipolarity/M
+biracial
+birch/GMDS
+bird/SZGMDR
+birdbath/M
+birdbaths
+birdbrain/SMD
+birdcage/S
+birder/M
+birdhouse/MS
+birdie/MDS
+birdieing
+birdlike
+birdlime/M
+birdseed/M
+birdsong
+birdwatcher/SM
+birdying
+biretta/SM
+birth/ZGMDR
+birthday/MS
+birther/M
+birthmark/MS
+birthplace/MS
+birthrate/MS
+birthright/MS
+births/A
+birthstone/SM
+biscuit/SM
+bisect/DGS
+bisection/MS
+bisector/SM
+bisexual/MYS
+bisexuality/M
+bishop/MS
+bishopric/SM
+bismuth/M
+bison/M
+bisque/M
+bistro/MS
+bit/CSMG
+bitch/GMDS
+bitchily
+bitchiness/M
+bitchy/PRT
+bitcoin/SM
+bite/RSMZ
+biter/M
+biting/Y
+bitmap/S
+bitten
+bitter/PMRYTS
+bittern/SM
+bitterness/M
+bitters/M
+bittersweet/MS
+bitty/TR
+bitumen/M
+bituminous
+bivalent
+bivalve/SM
+bivouac/MS
+bivouacked
+bivouacking
+biweekly/SM
+biyearly
+biz/M
+bizarre/Y
+bk
+bl/DG
+blab/SM
+blabbed
+blabber/DGS
+blabbermouth/M
+blabbermouths
+blabbing
+black/PXTGMDNRYS
+blackamoor/MS
+blackball/SGMD
+blackberry/GSM
+blackbird/SM
+blackboard/MS
+blackcurrant/S
+blacken/DG
+blackface
+blackguard/SM
+blackhead/MS
+blacking/M
+blackish
+blackjack/MDGS
+blackleg/S
+blacklist/MDSG
+blackmail/MDRSZG
+blackmailer/M
+blackness/M
+blackout/SM
+blacksmith/M
+blacksmiths
+blacksnake/SM
+blackthorn/SM
+blacktop/SM
+blacktopped
+blacktopping
+bladder/MS
+blade/MDS
+blag/S
+blagged
+blagging
+blah/M
+blahs/M
+blame/BMGDRS
+blameable
+blameless/YP
+blamelessness/M
+blameworthiness/M
+blameworthy/P
+blammo
+blanch/GDS
+blancmange/MS
+bland/PTRY
+blandish/DSLG
+blandishment/SM
+blandness/M
+blank/TGPMDRYS
+blanket/GMDS
+blankness/M
+blare/MGDS
+blarney/SMDG
+blase
+blaspheme/ZGDRS
+blasphemer/M
+blasphemous/Y
+blasphemy/SM
+blast/ZGMDRS
+blaster/M
+blastoff/MS
+blas辿
+blat/S
+blatancy/SM
+blatant/Y
+blather/SMDG
+blaze/MZGDRS
+blazer/M
+blazon/MDGS
+bldg
+bleach/MDRSZG
+bleached/U
+bleacher/M
+bleak/TPRY
+bleakness/M
+blear
+blearily
+bleariness/M
+bleary/PRT
+bleat/GMDS
+bleed/ZGRS
+bleeder/M
+bleeding/M
+bleep/ZGMDRS
+bleeper/M
+blemish/GMDS
+blemished/U
+blench/DSG
+blend/ZGMDRS
+blender/M
+bless/GDSJ
+blessed/YP
+blessedness/M
+blessing/M
+bletch
+blew
+blight/ZGMDRS
+blimey
+blimp/MS
+blimpish
+blind/PZTGMDRYS
+blinder/M
+blindfold/SMDG
+blinding/Y
+blindness/M
+blindside/DSG
+blini/MS
+blink/ZGMDRS
+blinker/MDG
+blintz/MS
+blintze/M
+blip/SM
+bliss/M
+blissful/YP
+blissfulness/M
+blister/GMDS
+blistering/Y
+blistery
+blithe/PYTR
+blitheness/M
+blither/G
+blithesome
+blitz/GMDS
+blitzkrieg/MS
+blivet/S
+blizzard/SM
+bloat/ZGDRS
+bloatware
+blob/SM
+blobbed
+blobbing
+bloc/SM
+block's
+block/UGDS
+blockade/MZGDRS
+blockader/M
+blockage/MS
+blockbuster/SM
+blockbusting/M
+blockchain/MS
+blocker/MS
+blockhead/SM
+blockhouse/MS
+blog/SM
+blogged
+blogger/MS
+blogging
+bloke/MS
+blokish
+blond/PTMRS
+blonde/MS
+blondish
+blondness/M
+blood/GMDS
+bloodbath/M
+bloodbaths
+bloodcurdling
+bloodhound/SM
+bloodily
+bloodiness/M
+bloodless/YP
+bloodlessness/M
+bloodletting/M
+bloodline/SM
+bloodmobile/MS
+bloodshed/M
+bloodshot
+bloodstain/SMD
+bloodstock/M
+bloodstream/SM
+bloodsucker/SM
+bloodsucking
+bloodthirstily
+bloodthirstiness/M
+bloodthirsty/RPT
+bloody/PTGDRS
+bloom/ZGMDRS
+bloomer/M
+bloop/ZGMDRS
+blooper/M
+blossom/GMDS
+blossomy
+blot/SM
+blotch/GMDS
+blotchy/TR
+blotted
+blotter/MS
+blotting
+blotto
+blouse/MGDS
+blow/SZGMR
+blower/M
+blowfly/SM
+blowgun/MS
+blowhard/MS
+blowhole/S
+blowjob/SM
+blowlamp/S
+blown
+blowout/SM
+blowpipe/SM
+blowsy/RT
+blowtorch/MS
+blowup/MS
+blowy/TR
+blowzy/RT
+blubber/GSMD
+blubbery
+bludgeon/MDGS
+blue/DRSPMTG
+bluebell/MS
+blueberry/SM
+bluebird/MS
+bluebonnet/SM
+bluebottle/SM
+bluefish/MS
+bluegill/MS
+bluegrass/M
+blueing/M
+blueish
+bluejacket/SM
+bluejay/SM
+bluejeans/M
+blueness/M
+bluenose/MS
+bluepoint/MS
+blueprint/MDGS
+bluestocking/SM
+bluesy/RT
+bluet/MS
+bluff/ZTGPMDRYS
+bluffer/M
+bluffness/M
+bluing/M
+bluish
+blunder/MDRZGS
+blunderbuss/MS
+blunderer/M
+blunt/PTGDRYS
+bluntness/M
+blur/SM
+blurb/MS
+blurred
+blurriness/M
+blurring
+blurry/TRP
+blurt/GDS
+blush/ZGMDRS
+blusher/M
+bluster/MDRSZG
+blusterer/M
+blusterous
+blustery
+blvd
+boa/SM
+boar/SM
+board/ZGMDRS
+boarder/M
+boarding/M
+boardinghouse/MS
+boardroom/MS
+boardwalk/MS
+boast/ZGMDRS
+boaster/M
+boastful/PY
+boastfulness/M
+boat/SZGMDR
+boater/M
+boathouse/MS
+boating/M
+boatload/S
+boatman/M
+boatmen
+boatswain/SM
+boatyard/S
+bob/SM
+bobbed
+bobbin/MS
+bobbing
+bobble/MGDS
+bobby/SM
+bobbysoxer/SM
+bobcat/MS
+bobolink/SM
+bobsled/SM
+bobsledded
+bobsledder/MS
+bobsledding
+bobsleigh/M
+bobsleighs
+bobtail/SM
+bobwhite/MS
+bocce/M
+bocci/M
+boccie/M
+bock/M
+bod/SMDG
+bodacious
+bode/S
+bodega/MS
+bodge/GDS
+bodice/MS
+bodily
+bodkin/MS
+body/DSM
+bodybuilder/SM
+bodybuilding/M
+bodyguard/MS
+bodysuit/SM
+bodywork/M
+boffin/S
+boffo
+bog/SM
+boga
+bogey/GMDS
+bogeyman/M
+bogeymen
+bogged
+bogging
+boggle/GDS
+boggy/TR
+bogie/MS
+bogon
+bogosity
+bogus
+bogyman/M
+bogymen
+bohemian/SM
+bohemianism/M
+boil/SJZGMDR
+boiler/M
+boilermaker/SM
+boilerplate/M
+boink/GDS
+boisterous/YP
+boisterousness/M
+bola/SM
+bold/PTRY
+boldface/DM
+boldness/M
+bole/SM
+bolero/MS
+bolivar/MS
+bolivares
+boll/SM
+bollard/S
+bollix/GMDS
+bollocking/S
+bollocks
+bologna/M
+bolshevik/SM
+bolshie
+bolshy
+bolster/GMDS
+bolt's
+bolt/USGD
+bolthole/S
+bolus/MS
+bomb/SJZGMDR
+bombard/GDLS
+bombardier/MS
+bombardment/SM
+bombast/M
+bombastic
+bombastically
+bomber/M
+bombproof
+bombshell/SM
+bombsite/S
+bonanza/MS
+bonbon/MS
+bonce/S
+bond/SGMD
+bondage/M
+bondholder/MS
+bonding/M
+bondman/M
+bondmen
+bondsman/M
+bondsmen
+bondwoman/M
+bondwomen
+bone/DRSMZG
+bonehead/SMD
+boneless
+boner/M
+boneshaker/S
+boneyard
+bonfire/MS
+bong/SGMD
+bongo/MS
+bonhomie/M
+boniness/M
+bonito/MS
+bonk/SZGD
+bonnet/MS
+bonny/TR
+bonobo/MS
+bonsai/M
+bonus/MS
+bony/PTR
+boo/SMDHG
+boob/SGMD
+booboo/MS
+booby/SM
+boodle/MS
+booger/S
+boogeyman/M
+boogeymen
+boogie/MDS
+boogieing
+boogieman/M
+boohoo/GMDS
+book/SBJGMD
+bookbinder/SM
+bookbindery/SM
+bookbinding/M
+bookcase/MS
+bookend/MS
+bookie/MS
+booking/M
+bookish
+bookkeeper/MS
+bookkeeping/M
+booklet/MS
+bookmaker/SM
+bookmaking/M
+bookmark/SMDG
+bookmobile/SM
+bookplate/MS
+bookseller/MS
+bookshelf/M
+bookshelves
+bookshop/SM
+bookstall/S
+bookstore/MS
+bookworm/SM
+boolean
+boom/SZGMDR
+boombox/MS
+boomerang/MDGS
+boon/SM
+boondocks/M
+boondoggle/MZGDRS
+boondoggler/M
+boonies/M
+boor/SM
+boorish/PY
+boorishness/MS
+boost/ZGMDRS
+booster/M
+boot's
+boot/ASGD
+bootblack/SM
+bootee/MS
+booth/M
+booths
+bootie/M
+bootlace/S
+bootleg/MS
+bootlegged
+bootlegger/MS
+bootlegging/M
+bootless
+bootstrap/MS
+bootstrapped
+bootstrapping
+booty/SM
+booze/MZGDRS
+boozer/M
+boozy/TR
+bop/SM
+bopped
+bopping
+borax/M
+bordello/MS
+border/GMDS
+borderland/MS
+borderline/MS
+bore/DRSMZG
+boredom/M
+borehole/S
+borer/M
+boring/Y
+born/IAU
+borne
+boron/M
+borough/M
+boroughs
+borrow/SDRZGJ
+borrower/M
+borrowing/M
+borsch/M
+borscht/M
+borstal/S
+borzoi/SM
+bosh/M
+bosom's
+bosom/US
+bosomy
+boss/DSGM
+bossily
+bossiness/M
+bossism/M
+bossy/RTP
+bosun/SM
+bot/S
+botanic
+botanical/Y
+botanist/SM
+botany/M
+botch/DRSZGM
+botcher/M
+both
+bother/SMDG
+botheration
+bothered/U
+bothersome
+botnet/SM
+bottle/DRSMZG
+bottleneck/MS
+bottler/M
+bottom/SMDG
+bottomless
+botulinum
+botulism/M
+boudoir/SM
+bouffant/SM
+bougainvillea/MS
+bough/M
+boughs
+bought
+bouillabaisse/SM
+bouillon/MS
+boulder/SM
+boules
+boulevard/SM
+bounce/DRSMZG
+bouncer/M
+bouncily
+bounciness/M
+bouncy/RTP
+bound/ASMGD
+boundary/SM
+bounden
+bounder/SM
+boundless/PY
+boundlessness/M
+bounteous/YP
+bounteousness/M
+bountiful/YP
+bountifulness/M
+bounty/SM
+bouquet/SM
+bourbon/SM
+bourgeois/M
+bourgeoisie/M
+boustrophedon
+bout/MS
+boutique/SM
+boutonniere/MS
+boutonni竪re/MS
+bouzouki/MS
+bovine/SM
+bovver
+bow/ZGSMDR
+bowdlerization/MS
+bowdlerize/DSG
+bowed/U
+bowel/SM
+bower/M
+bowl/MDRZGS
+bowleg/SM
+bowlegged
+bowler/M
+bowlful/SM
+bowline/SM
+bowling/M
+bowman/M
+bowmen
+bowsprit/SM
+bowstring/SM
+bowwow/SM
+box/ZGMDNRS
+boxcar/SM
+boxer/M
+boxing/M
+boxlike
+boxroom/S
+boxwood/M
+boxy/RT
+boy/SM
+boycott/SGMD
+boyfriend/MS
+boyhood/SM
+boyish/YP
+boyishness/M
+boysenberry/SM
+bozo/MS
+bpm
+bps
+bra/SM
+brace/MZGDRS
+bracelet/MS
+bracer/M
+bracero/MS
+bracken/M
+bracket/GMDS
+brackish/P
+brackishness/M
+bract/MS
+brad/SM
+bradawl/S
+bradycardia
+brae/SM
+brag/SM
+braggadocio/SM
+braggart/SM
+bragged
+bragger/MS
+bragging
+braid/GMDS
+braiding/M
+braille/M
+brain/GMDS
+brainchild/M
+brainchildren/M
+braininess/M
+brainless/Y
+brainpower
+brainstorm/SMDG
+brainstorming/M
+brainteaser/SM
+brainwash/DSG
+brainwashing/M
+brainwave/S
+brainy/PTR
+braise/GDS
+brake/MGDS
+brakeman/M
+brakemen
+bramble/MS
+brambly
+bran/M
+branch/GMDS
+branchlike
+brand/ZGMDRS
+branded/U
+brander/M
+brandish/DSG
+brandy/GDSM
+brash/PTRY
+brashness/M
+brass/MS
+brasserie/MS
+brassiere/MS
+brassily
+brassiness/M
+brassy/PTR
+brat/SM
+bratty/RT
+bratwurst/SM
+bravado/M
+brave/GPMYDTRS
+braveness/M
+bravery/M
+bravo/SM
+bravura/SM
+brawl/SDRZGM
+brawler/M
+brawn/M
+brawniness/M
+brawny/RTP
+bray/DGSM
+braze/DRSZG
+brazen/SDYGP
+brazenness/M
+brazer/M
+brazier/SM
+breach/GMDS
+bread/GMDHS
+breadbasket/SM
+breadboard/SM
+breadbox/MS
+breadcrumb/MS
+breadfruit/SM
+breadline/MS
+breadth/M
+breadths
+breadwinner/SM
+break/BMZGRS
+breakable/MS
+breakage/MS
+breakaway/MS
+breakdown/MS
+breaker/M
+breakeven/M
+breakfast/MDGS
+breakfront/MS
+breakneck
+breakout/MS
+breakpoints
+breakthrough/M
+breakthroughs
+breakup/SM
+breakwater/SM
+bream/MS
+breast/SMDG
+breastbone/MS
+breastfed
+breastfeed/GS
+breastplate/SM
+breaststroke/SM
+breastwork/MS
+breath/MDRSZGB
+breathalyze/ZGDRS
+breathe
+breather/M
+breathing/M
+breathless/PY
+breathlessness/M
+breaths
+breathtaking/Y
+breathy/RT
+bred/I
+breech/MS
+breed/SRZGM
+breeder/M
+breeding/IM
+breeze/DSMG
+breezeway/SM
+breezily
+breeziness/M
+breezy/RTP
+brethren
+breve/SM
+brevet/SM
+brevetted
+brevetting
+breviary/SM
+brevity/M
+brew/MDRZGS
+brewer/M
+brewery/SM
+brewpub/SM
+briar/SM
+bribe/DRSMZG
+briber/M
+bribery/M
+brick/SMDG
+brickbat/SM
+brickie/S
+bricklayer/MS
+bricklaying/M
+brickwork/M
+brickyard/S
+bridal/SM
+bride/SM
+bridegroom/SM
+bridesmaid/MS
+bridge/DSMG
+bridgeable/U
+bridgehead/SM
+bridgework/M
+bridle/DSMG
+bridled/U
+bridleway/S
+brie/MZR
+brief's
+brief/CSDTGJ
+briefcase/SM
+briefer
+briefing/CM
+briefly
+briefness/M
+brier/M
+brig/MS
+brigade/SM
+brigadier/MS
+brigand/SM
+brigandage/M
+brigantine/MS
+bright/SPNRYXT
+brighten/DRZG
+brightener/M
+brightness/M
+brights/M
+brill
+brilliance/M
+brilliancy/M
+brilliant/MYS
+brilliantine/M
+brim/MS
+brimful
+brimless
+brimmed
+brimming
+brimstone/M
+brindle/DM
+brine/M
+bring/SRZG
+bringer/M
+brininess/M
+brink/SM
+brinkmanship/M
+briny/RTP
+brioche/SM
+briquet/SM
+briquette/MS
+brisk/SDRYTGP
+brisket/SM
+briskness/M
+bristle/DSMG
+bristly/TR
+britches/M
+brittle/PRMT
+brittleness/M
+bro/SMH
+broach/MDSG
+broad/SMNRYXTP
+broadband/M
+broadcast/AMGS
+broadcaster/MS
+broadcasting/M
+broadcloth/M
+broaden/DG
+broadloom/M
+broadminded
+broadness/M
+broadsheet/SM
+broadside/MGDS
+broadsword/SM
+brocade/DSMG
+broccoli/M
+brochette/SM
+brochure/MS
+brogan/SM
+brogue/SM
+broil/SMDRZG
+broiler/M
+broke
+broken/YP
+brokenhearted/Y
+brokenness/M
+broker/SMDG
+brokerage/MS
+brolly/S
+bromide/SM
+bromidic
+bromine/M
+bronc/SM
+bronchi
+bronchial
+bronchitic
+bronchitis/M
+bronchus/M
+bronco/SM
+broncobuster/SM
+brontosaur/MS
+brontosaurus/MS
+bronze/DSMG
+brooch/MS
+brood/SMDRZG
+brooder/M
+broodily
+brooding/MY
+broodmare/MS
+broody/RMPT
+brook/SMDG
+brooklet/SM
+broom/SM
+broomstick/MS
+broth/MRZ
+brothel/MS
+brother/MY
+brotherhood/MS
+brotherliness/M
+broths
+brougham/SM
+brought
+brouhaha/SM
+brow/MS
+browbeat/SNG
+brown/SMDRPTG
+brownfield
+brownie/MS
+brownish
+brownness/M
+brownout/SM
+brownstone/MS
+browse/DRSMZG
+browser/M
+brr
+bruin/SM
+bruise/DRSMZG
+bruiser/M
+bruising/M
+bruit/SDG
+brunch/MDSG
+brunet/SM
+brunette/MS
+brunt/M
+brush/MDSG
+brushoff/SM
+brushstroke/S
+brushwood/M
+brushwork/M
+brusque/RPYT
+brusqueness/M
+brutal/Y
+brutality/SM
+brutalization/M
+brutalize/GDS
+brute/SM
+brutish/PY
+brutishness/M
+bu
+bub/SM
+bubble/DSMG
+bubblegum/M
+bubbly/RMT
+bubo/M
+buboes
+buccaneer/SGMD
+buck/MDGS
+buckaroo/SM
+buckboard/MS
+bucket/SGMD
+bucketful/MS
+buckeye/MS
+buckle's
+buckle/UDSG
+buckler/MS
+buckram/M
+bucksaw/MS
+buckshot/M
+buckskin/MS
+buckteeth
+bucktooth/MD
+buckwheat/M
+buckyball/SM
+bucolic/MS
+bucolically
+bud/SM
+budded
+budding/S
+buddy/SM
+budge/DSG
+budgerigar/MS
+budget/SGMD
+budgetary
+budgie/SM
+buff/AMDGS
+buffalo/MDG
+buffaloes
+buffer/SMDG
+buffet/SMDGJ
+buffoon/SM
+buffoonery/M
+buffoonish
+bug's
+bug/CS
+bugaboo/SM
+bugbear/SM
+bugged/C
+bugger/SMDG
+buggery
+bugging/C
+buggy/RSMT
+bugle/DRSMZG
+bugler/M
+build/SMRZGJ
+builder/M
+building/M
+buildup/SM
+built/AI
+builtin
+bulb/MS
+bulbous
+bulge/DSMG
+bulgy/RT
+bulimarexia/M
+bulimia/M
+bulimic/SM
+bulk/MDGS
+bulkhead/MS
+bulkiness/M
+bulky/RTP
+bull/MDGS
+bulldog/SM
+bulldogged
+bulldogging
+bulldoze/ZGDRS
+bulldozer/M
+bullet/SMD
+bulletin/MDGS
+bulletproof/SDG
+bullfight/SMRZG
+bullfighter/M
+bullfighting/M
+bullfinch/MS
+bullfrog/MS
+bullhead/MDS
+bullheaded/PY
+bullheadedness/M
+bullhorn/MS
+bullion/M
+bullish/YP
+bullishness/M
+bullock/SM
+bullpen/SM
+bullring/MS
+bullseye
+bullshit/MS!
+bullshitted/!
+bullshitter/SM!
+bullshitting/!
+bullwhip/S
+bully/DSMG
+bulrush/MS
+bulwark/MS
+bum/SM
+bumbag/S
+bumble/DRSZG
+bumblebee/SM
+bumbler/M
+bumf
+bummed
+bummer/SM
+bummest
+bumming
+bump/MDRZGS
+bumper/M
+bumph
+bumpiness/M
+bumpkin/MS
+bumptious/PY
+bumptiousness/M
+bumpy/PRT
+bun/SM
+bunch/MDSG
+bunchy/RT
+bunco/SMDG
+buncombe/M
+bundle/DSMG
+bung/MDGS
+bungalow/MS
+bungee/SM
+bunghole/MS
+bungle/DRSMZG
+bungler/M
+bunion/SM
+bunk's
+bunk/CDGS
+bunker/SM
+bunkhouse/SM
+bunko/SMDG
+bunkum/M
+bunny/SM
+bunt/MDGSJ
+bunting/M
+buoy/MDGS
+buoyancy/M
+buoyant/Y
+bur/SMY
+burble/DSMG
+burbs/M
+burden's
+burden/USGD
+burdensome
+burdock/M
+bureau/SM
+bureaucracy/SM
+bureaucrat/MS
+bureaucratic
+bureaucratically
+bureaucratization/M
+bureaucratize/GDS
+burg/MRZS
+burgeon/DSG
+burger/M
+burgh/MRZ
+burgher/M
+burghs
+burglar/MS
+burglarize/GDS
+burglarproof
+burglary/SM
+burgle/DSG
+burgomaster/SM
+burgundy/SM
+burial/ASM
+burka/SM
+burl/MDS
+burlap/M
+burlesque/MGDS
+burliness/M
+burly/RPT
+burn/MDRZGSB
+burnable/SM
+burner/M
+burnish/ZGMDRS
+burnisher/M
+burnoose/MS
+burnous/MS
+burnout/MS
+burnt
+burp/MDGS
+burr/MDGS
+burrito/MS
+burro/SM
+burrow/SMDRZG
+burrower/M
+bursa/M
+bursae
+bursar/SM
+bursary/SM
+bursitis/M
+burst/SMG
+bury/ADSG
+bus/AMS
+busboy/SM
+busby/SM
+bused
+busgirl/MS
+bush/MDSGJ
+bushel/SGMD
+bushiness/M
+bushing/M
+bushman/M
+bushmaster/SM
+bushmen
+bushwhack/DRSZG
+bushwhacker/M
+bushy/RPT
+busily
+business/MS
+businesslike
+businessman/M
+businessmen
+businessperson/SM
+businesswoman/M
+businesswomen
+busing/M
+busk/DRZGS
+buskin/SM
+busload/S
+buss/MDSG
+bust/MDRZGS
+buster/M
+bustle/DSMG
+busty/RZT
+busy/DRSTGP
+busybody/SM
+busyness/M
+busywork/M
+but/ACS
+butane/M
+butch/MRSZ
+butcher/MDG
+butchery/SM
+butler/SM
+butt/MDRZGS
+butte/SM
+butted/A
+butter/MDG
+butterball/MS
+buttercream
+buttercup/SM
+butterfat/M
+butterfingered
+butterfingers/M
+butterfly/GDSM
+buttermilk/M
+butternut/SM
+butterscotch/M
+buttery/TRSM
+butting/A
+buttock/SM
+button's
+button/USDG
+buttonhole/DSMG
+buttonwood/MS
+buttress/MDSG
+butty/S
+buxom
+buy/ZGSMR
+buyback/SM
+buyer/M
+buyout/SM
+buzz/MDRSZG
+buzzard/MS
+buzzer/M
+buzzkill/SM
+buzzword/SM
+bx
+bxs
+by/M
+bye/SM
+bygone/SM
+bylaw/SM
+byline/SM
+bypass/GMDS
+bypath/M
+bypaths
+byplay/M
+byproduct/MS
+byre/S
+byroad/SM
+bystander/MS
+byte/MS
+byway/SM
+byword/SM
+byzantine
+c/IES
+ca
+cab/SMRZ
+cabal/MS
+cabala/M
+caballero/MS
+cabana/SM
+cabaret/SM
+cabbage/MS
+cabbed
+cabbie/M
+cabbing
+cabby/SM
+cabdriver/SM
+cabin/MS
+cabinet/SM
+cabinetmaker/MS
+cabinetmaking/M
+cabinetry/M
+cabinetwork/M
+cable/MGDS
+cablecast/GMS
+cablegram/MS
+cabochon/SM
+caboodle/M
+caboose/SM
+cabriolet/SM
+cabstand/SM
+cacao/MS
+cache/MGDS
+cachepot/SM
+cachet/MS
+cackle/MZGDRS
+cackler/M
+cacophonous
+cacophony/SM
+cacti
+cactus/M
+cad/SM
+cadaver/SM
+cadaverous
+caddie/MDS
+caddish/YP
+caddishness/M
+caddying
+cadence/DSM
+cadenza/SM
+cadet/MS
+cadge/ZGDRS
+cadger/M
+cadmium/M
+cadre/MS
+caducei
+caduceus/M
+caesarean/MS
+caesura/SM
+cafe/SM
+cafeteria/MS
+cafetiere/S
+caff/CS
+caffeinated
+caffeine/M
+caftan/MS
+caf辿/SM
+cage/DSMG
+cagey
+cagier
+cagiest
+cagily
+caginess/M
+cagoule/S
+cahoot/MS
+caiman/MS
+cairn/MS
+caisson/SM
+caitiff/SM
+cajole/ZGLDRS
+cajolement/M
+cajoler/M
+cajolery/M
+cake/DSMG
+cakewalk/SM
+cal
+calabash/MS
+calaboose/SM
+calamari/SM
+calamine/M
+calamitous/Y
+calamity/SM
+calcareous
+calciferous
+calcification/M
+calcify/GNDS
+calcimine/DSMG
+calcine/DSG
+calcite/M
+calcium/M
+calculable/I
+calculate/AGNVDSX
+calculated/Y
+calculating/Y
+calculation/AM
+calculator/SM
+calculi
+calculus/M
+caldera/SM
+caldron/SM
+calendar/MDGS
+calf/M
+calfskin/M
+caliber/SM
+calibrate/GNDSX
+calibration/M
+calibrator/SM
+calico/MS
+calicoes
+californium/M
+caliper/SGMD
+caliph/M
+caliphate/MS
+caliphs
+calisthenic/S
+calisthenics/M
+calk/SGMD
+call/ASGMD
+calla/MS
+callable
+callback/MS
+called/U
+caller/MS
+calligrapher/SM
+calligraphic
+calligraphist/MS
+calligraphy/M
+calling/SM
+calliope/MS
+callosity/SM
+callous/PGDSY
+callousness/M
+callow/RPT
+callowness/M
+callus/MDSG
+calm/PSTGMDRY
+calmness/M
+caloric
+calorie/MS
+calorific
+calumet/MS
+calumniate/GNDS
+calumniation/M
+calumniator/MS
+calumnious
+calumny/SM
+calve/GDS
+calypso/MS
+calyx/MS
+cam/SM
+camaraderie/M
+camber/MDSG
+cambial
+cambium/SM
+cambric/M
+camcorder/SM
+came
+camel/MS
+camelhair/M
+camellia/MS
+cameo/MS
+camera/MS
+cameraman/M
+cameramen
+camerapeople
+cameraperson
+camerawoman/M
+camerawomen
+camerawork
+camiknickers
+camisole/SM
+camomile/SM
+camouflage/MZGDRS
+camouflager/M
+camp's
+camp/CSGD
+campaign/SMDRZG
+campaigner/M
+campanile/SM
+campanologist/MS
+campanology/M
+camper/MS
+campfire/SM
+campground/SM
+camphor/M
+camping/M
+campsite/SM
+campus/MS
+campy/TR
+camshaft/SM
+can't
+can/SMDRZG
+canal/MS
+canalization/M
+canalize/GDS
+canape/MS
+canap辿/MS
+canard/MS
+canary/SM
+canasta/M
+cancan/MS
+cancel/DRSZG
+canceler/M
+cancellation/SM
+cancelled
+cancelling
+cancelous
+cancer/MS
+cancerous
+candelabra/SM
+candelabrum/M
+candid/YP
+candida
+candidacy/SM
+candidate/MS
+candidature/SM
+candidness/M
+candle/MZGDRS
+candlelight/M
+candlelit
+candlepower/M
+candler/M
+candlestick/MS
+candlewick/SM
+candor/M
+candy/GDSM
+candyfloss
+cane/SM
+canebrake/MS
+caner/M
+canine/MS
+canister/SM
+canker/GMDS
+cankerous
+cannabis/MS
+canned
+cannelloni/M
+cannery/SM
+cannibal/SM
+cannibalism/M
+cannibalistic
+cannibalization/M
+cannibalize/GDS
+cannily/U
+canniness/M
+canning
+cannon/GMDS
+cannonade/MGDS
+cannonball/SM
+cannot
+canny/UTR
+canoe/MDS
+canoeing
+canoeist/SM
+canola/M
+canon/MS
+canonical/Y
+canonization/SM
+canonize/DSG
+canoodle/DSG
+canopy/GDSM
+canst
+cant's
+cant/CZRDGS
+cantabile
+cantaloupe/SM
+cantankerous/PY
+cantankerousness/M
+cantata/MS
+canteen/MS
+canter/CM
+cantered
+cantering
+canticle/MS
+cantilever/MDGS
+canto/MS
+canton/MLS
+cantonal
+cantonment/MS
+cantor/MS
+canvas/MGDS
+canvasback/SM
+canvass/MDRSZG
+canvasser/M
+canyon/MGS
+cap/SMDRBZ
+capabilities
+capability/IM
+capable/I
+capably/I
+capacious/PY
+capaciousness/M
+capacitance/M
+capacities
+capacitor/SM
+capacity/IM
+caparison/MDGS
+cape/SM
+caper/GMD
+capeskin/M
+capillarity/M
+capillary/SM
+capital/MSY
+capitalism/M
+capitalist/SM
+capitalistic
+capitalistically
+capitalization/M
+capitalize/ADSG
+capitation/CSM
+capitol/SM
+capitulate/ADSXGN
+capitulation/AM
+caplet/MS
+capo/SM
+capon/MS
+capped/UA
+capping/UA
+cappuccino/SM
+caprice/SM
+capricious/PY
+capriciousness/M
+capsicum/SM
+capsize/DSG
+capstan/SM
+capstone/MS
+capsular
+capsule/DSMG
+capsulize/DSG
+capt
+captain/SMDG
+captaincy/SM
+caption/SMDG
+captious/YP
+captiousness/M
+captivate/DSGN
+captivation/M
+captivator/SM
+captive/SM
+captivity/SM
+captor/MS
+capture/ADSMG
+car/SMDRZG
+carafe/MS
+caramel/SM
+caramelize/DSG
+carapace/SM
+carat/MS
+caravan/SM
+caravansarai/S
+caravansary/SM
+caravanserai/M
+caravel/SM
+caraway/SM
+carbide/SM
+carbine/SM
+carbohydrate/SM
+carbolic
+carbon/MS
+carbonaceous
+carbonate/MGNDS
+carbonation/M
+carboniferous
+carbonize/GDS
+carborundum/M
+carboy/MS
+carbs
+carbuncle/SM
+carbuncular
+carburetor/SM
+carcass/MS
+carcinogen/SM
+carcinogenic/MS
+carcinogenicity/M
+carcinoma/MS
+card/ESGMD
+cardamom/SM
+cardamon/S
+cardboard/M
+carder/MS
+cardholder/S
+cardiac
+cardie/S
+cardigan/SM
+cardinal/SMY
+cardio
+cardiogram/SM
+cardiograph/M
+cardiographs
+cardiologist/MS
+cardiology/M
+cardiomyopathy
+cardiopulmonary
+cardiovascular
+cardsharp/MRZS
+cardsharper/M
+care/SM
+careen/DGS
+career/MDGS
+careerism
+careerist/SM
+carefree
+careful/YP
+carefuller
+carefullest
+carefulness/M
+caregiver/SM
+careless/PY
+carelessness/M
+carer/M
+caress/MDSG
+caret/MS
+caretaker/MS
+careworn
+carfare/M
+cargo/M
+cargoes
+carhop/MS
+caribou/SM
+caricature/MGDS
+caricaturist/SM
+caries/M
+carillon/SM
+caring/M
+carious
+carjack/JSDRZG
+carjacker/M
+carjacking/M
+carload/SM
+carmaker/S
+carmine/SM
+carnage/M
+carnal/Y
+carnality/M
+carnation/IMS
+carnelian/MS
+carney/MS
+carnie/M
+carnival/MS
+carnivora
+carnivore/SM
+carnivorous/PY
+carnivorousness/M
+carny/SM
+carob/MS
+carol/ZGMDRS
+caroler/M
+carom/GMDS
+carotene/M
+carotid/SM
+carousal/SM
+carouse/DRSMZG
+carousel/SM
+carouser/M
+carp/SZGMDR
+carpal/MS
+carpel/MS
+carpenter/MDGS
+carpentry/M
+carper/M
+carpet/MDGS
+carpetbag/MS
+carpetbagged
+carpetbagger/MS
+carpetbagging
+carpeting/M
+carpi
+carpool/SMDG
+carport/SM
+carpus/M
+carrel/MS
+carriage/SM
+carriageway/S
+carrier/M
+carrion/M
+carrot/MS
+carroty
+carry/ZGDRSM
+carryall/SM
+carrycot/S
+carryout
+carryover/MS
+carsick/P
+carsickness/M
+cart/SZGMDR
+cartage/M
+cartel/MS
+carter/M
+carthorse/SM
+cartilage/SM
+cartilaginous
+cartload/SM
+cartographer/SM
+cartographic
+cartography/M
+carton/MS
+cartoon/SMDG
+cartoonist/MS
+cartridge/MS
+cartwheel/GMDS
+carve/JZGDRS
+carver/M
+carvery/S
+carving/M
+caryatid/MS
+casaba/MS
+cascade/DSMG
+cascara/SM
+case/LDSJMG
+casebook/S
+cased/U
+caseharden/DGS
+casein/M
+caseload/MS
+casement/MS
+casework/ZMR
+caseworker/M
+cash/GMDS
+cashback/M
+cashbook/MS
+cashew/MS
+cashier/GSMD
+cashless
+cashmere/M
+casing/M
+casino/MS
+cask/SM
+casket/MS
+cassava/SM
+casserole/DSMG
+cassette/MS
+cassia/MS
+cassock/SM
+cassowary/SM
+cast/ASGM
+castanet/MS
+castaway/MS
+caste/JMZRS
+castellated
+caster/M
+castigate/DSGN
+castigation/M
+castigator/SM
+casting/AM
+castle/MGDS
+castoff/SM
+castor/MS
+castrate/GNXDS
+castration/M
+casual/PMYS
+casualness/M
+casualty/SM
+casuist/SM
+casuistic
+casuistry/M
+cat/SM
+cataclysm/MS
+cataclysmal
+cataclysmic
+catacomb/SM
+catafalque/MS
+catalepsy/M
+cataleptic/MS
+catalog/ZGSMDR
+cataloger/M
+catalogue/DSMG
+catalogued/U
+catalpa/SM
+catalyses
+catalysis/M
+catalyst/MS
+catalytic/M
+catalyze/GDS
+catamaran/SM
+catapult/GMDS
+cataract/MS
+catarrh/M
+catastrophe/MS
+catastrophic
+catastrophically
+catatonia/M
+catatonic/SM
+catbird/SM
+catboat/SM
+catcall/GSMD
+catch/ZGJLMRS
+catchall/MS
+catcher/M
+catchment/MS
+catchpenny
+catchphrase/SM
+catchword/MS
+catchy/RT
+catechism/SM
+catechist/SM
+catechize/DSG
+categorical/Y
+categorization/MS
+categorize/GDS
+category/SM
+cater/ZGJDRS
+catercorner
+caterer/M
+caterpillar/MS
+caterwaul/SMDG
+catfish/MS
+catgut/M
+catharses
+catharsis/M
+cathartic/SM
+cathedral/SM
+catheter/SM
+catheterize/DSG
+cathode/SM
+cathodic
+catholic
+catholicity/M
+cation/MS
+catkin/MS
+catlike
+catnap/MS
+catnapped
+catnapping
+catnip/M
+catsuit/S
+catsup/MS
+cattail/SM
+catted
+cattery/S
+cattily
+cattiness/M
+catting
+cattle/M
+cattleman/M
+cattlemen
+catty/TPR
+catwalk/SM
+caucus/MDSG
+caudal/Y
+caught/U
+cauldron/MS
+cauliflower/SM
+caulk/ZGMDRS
+caulker/M
+causal/Y
+causality/SM
+causation/M
+causative
+cause/MZGDRS
+causeless
+causer/M
+causerie/SM
+causeway/SM
+caustic/SM
+caustically
+causticity/M
+cauterization/M
+cauterize/GDS
+caution/SMDG
+cautionary
+cautious/IY
+cautiousness/M
+cavalcade/MS
+cavalier/SMY
+cavalry/SM
+cavalryman/M
+cavalrymen
+cave/DRSMZG
+caveat/MS
+caveman/M
+cavemen
+cavern/MS
+cavernous/Y
+caviar/M
+cavil/ZGJMDRS
+caviler/M
+caving/M
+cavitation
+cavity/FSM
+cavort/DGS
+caw/SMDG
+cay/CSM
+cayenne/M
+cayuse/MS
+cc
+cease/CMGDS
+ceasefire/MS
+ceaseless/YP
+ceaselessness/M
+ceca
+cecal
+cecum/M
+cedar/MS
+cede/FAGSD
+ceder/MS
+cedilla/SM
+ceilidh
+ceilidhs
+ceiling/MS
+celandine/M
+celeb/S
+celebrant/SM
+celebrate/DSGNX
+celebration/M
+celebrator/SM
+celebratory
+celebrity/SM
+celeriac
+celerity/M
+celery/M
+celesta/MS
+celestial/Y
+celibacy/M
+celibate/MS
+cell/SMD
+cellar/MS
+cellist/SM
+cellmate/SM
+cello/MS
+cellophane/M
+cellphone/MS
+cellular/SM
+cellulite/M
+cellulitis
+celluloid/M
+cellulose/M
+cement/MDRZGS
+cementer/M
+cementum/M
+cemetery/SM
+cenobite/MS
+cenobitic
+cenotaph/M
+cenotaphs
+censer/MS
+censor/MDGS
+censored/U
+censorial
+censorious/PY
+censoriousness/M
+censorship/M
+censure/BDRSMZG
+censurer/M
+census/MDSG
+cent/SZMR
+centaur/SM
+centavo/SM
+centenarian/MS
+centenary/SM
+centennial/MYS
+center/MDG
+centerboard/SM
+centerfold/MS
+centerpiece/MS
+centigrade
+centigram/SM
+centiliter/MS
+centime/SM
+centimeter/MS
+centipede/SM
+central/SMY
+centralism
+centralist
+centrality/M
+centralization/CM
+centralize/CGDS
+centralizer/MS
+centrifugal/Y
+centrifuge/DSMG
+centripetal/Y
+centrism/M
+centrist/MS
+centurion/SM
+century/SM
+cephalic
+ceramic/SM
+ceramicist/SM
+ceramics/M
+ceramist/MS
+cereal/MS
+cerebellar
+cerebellum/SM
+cerebra
+cerebral
+cerebrate/GNDS
+cerebration/M
+cerebrovascular
+cerebrum/MS
+cerement/MS
+ceremonial/SMY
+ceremonious/UY
+ceremoniousness/M
+ceremony/SM
+cerise/M
+cerium/M
+cermet/M
+cert/S
+certain/UY
+certainty/USM
+certifiable
+certifiably
+certificate/MGNXDS
+certification/M
+certify/DSG
+certitude/IM
+certitudes
+cerulean/M
+cervical
+cervices
+cervix/M
+cesarean/MS
+cesium/M
+cessation/MS
+cession/KAFSM
+cesspit/S
+cesspool/MS
+cetacean/MS
+ceteris
+cf
+cg
+ch/IFVT
+chad/S
+chafe/GDS
+chaff/GMDS
+chaffinch/MS
+chagrin/GSMD
+chain's
+chain/UGDS
+chainsaw/MDGS
+chair/GMDS
+chairlift/MS
+chairman/M
+chairmanship/SM
+chairmen
+chairperson/SM
+chairwoman/M
+chairwomen
+chaise/MS
+chalcedony/M
+chalet/MS
+chalice/SM
+chalk/GMDS
+chalkboard/SM
+chalkiness/M
+chalky/PRT
+challenge/DRSMZG
+challenged/U
+challenger/M
+challis/M
+chamber/SMD
+chamberlain/MS
+chambermaid/MS
+chambray/M
+chameleon/SM
+chamois/M
+chamomile/MS
+champ/ZGMDS
+champagne/MS
+champion/GMDS
+championship/MS
+chance/MGDS
+chancel/SM
+chancellery/SM
+chancellor/MS
+chancellorship/M
+chancery/SM
+chanciness/M
+chancre/SM
+chancy/PRT
+chandelier/SM
+chandler/MS
+change/MZGDRS
+changeability/M
+changeable/P
+changeableness/M
+changeably
+changed/U
+changeless/Y
+changeling/SM
+changeover/SM
+changer/M
+changing/U
+channel/GSMD
+channelization/M
+channelize/DSG
+chanson/SM
+chant/ZGMDRS
+chanter/M
+chanteuse/MS
+chantey/SM
+chanticleer/MS
+chaos/M
+chaotic
+chaotically
+chap/SM
+chaparral/SM
+chapati/S
+chapatti/S
+chapbook/MS
+chapeau/SM
+chapel/MS
+chaperon/MDGS
+chaperonage/M
+chaperone/SM
+chaperoned/U
+chaplain/MS
+chaplaincy/SM
+chaplet/SM
+chapped
+chapping
+chappy/S
+chapter/SM
+char/SM
+charabanc/MS
+character/MS
+characterful
+characteristic/SM
+characteristically/U
+characterization/MS
+characterize/DSG
+characterless
+charade/SM
+charbroil/GDS
+charcoal/MS
+chard/M
+chardonnay/SM
+charge/AESDGM
+chargeable/A
+charged/U
+charger/SM
+charily
+chariness/M
+chariot/SM
+charioteer/MS
+charisma/M
+charismatic/MS
+charitable/P
+charitableness/M
+charitably/U
+charity/SM
+charlady/S
+charlatan/SM
+charlatanism/M
+charlatanry/M
+charlie/S
+charm/ZGMDRS
+charmer/M
+charming/Y
+charmless
+charred
+charring
+chart/GMDS
+charted/U
+charter's
+charter/ASGD
+charterer/MS
+chartreuse/M
+charwoman/M
+charwomen
+chary/TRP
+chase/MZGDRS
+chaser/M
+chasm/MS
+chassis/M
+chaste/PYTR
+chasten/DGS
+chasteness/M
+chastise/DRSZGL
+chastisement/SM
+chastiser/M
+chastity/M
+chasuble/SM
+chat/SM
+chateau/SM
+chateaux
+chatelaine/SM
+chatline/S
+chatroom/M
+chatted
+chattel/MS
+chatter/MDRZGS
+chatterbox/MS
+chatterer/M
+chattily
+chattiness/M
+chatting
+chatty/TPR
+chauffeur/GMDS
+chauvinism/M
+chauvinist/SM
+chauvinistic
+chauvinistically
+cheap/PXTNRY
+cheapen/DG
+cheapness/M
+cheapo
+cheapskate/MS
+cheat/ZGMDRS
+cheater/M
+check/AGMDS
+checkbook/SM
+checkbox
+checked/U
+checker/MDGS
+checkerboard/SM
+checkers/M
+checklist/MS
+checkmate/MGDS
+checkoff/SM
+checkout/SM
+checkpoint/SM
+checkroom/MS
+checksum
+checkup/MS
+cheddar/M
+cheek/GMDS
+cheekbone/SM
+cheekily
+cheekiness/M
+cheeky/TPR
+cheep/GMDS
+cheer/ZGMDRS
+cheerer/M
+cheerful/YP
+cheerfuller
+cheerfullest
+cheerfulness/M
+cheerily
+cheeriness/M
+cheerio/MS
+cheerleader/SM
+cheerless/PY
+cheerlessness/M
+cheery/TPR
+cheese/MGDS
+cheeseboard/S
+cheeseburger/SM
+cheesecake/SM
+cheesecloth/M
+cheeseparing/M
+cheesiness/M
+cheesy/TPR
+cheetah/M
+cheetahs
+chef/SM
+chem
+chemical/SMY
+chemise/MS
+chemist/MS
+chemistry/M
+chemo/M
+chemotherapeutic
+chemotherapy/M
+chemurgy/M
+chenille/M
+cherish/DSG
+cheroot/MS
+cherry/SM
+chert/M
+cherub/MS
+cherubic
+cherubim
+chervil/M
+chess/M
+chessboard/MS
+chessman/M
+chessmen
+chest/MDS
+chesterfield/SM
+chestful/SM
+chestnut/SM
+chesty/TR
+chevalier/SM
+cheviot/M
+chevron/MS
+chew/SZGMDR
+chewer/M
+chewiness/M
+chewy/PTR
+chg
+chge
+chi/SM
+chiaroscuro/M
+chic/PTMR
+chicane/MS
+chicanery/SM
+chichi/MS
+chick/XMNS
+chickadee/SM
+chicken/MDG
+chickenfeed/M
+chickenhearted
+chickenpox/M
+chickenshit/S!
+chickpea/SM
+chickweed/M
+chicle/M
+chicness/M
+chicory/SM
+chide/GDS
+chiding/Y
+chief/TMRYS
+chiefdom/M
+chieftain/MS
+chieftainship/SM
+chiffon/M
+chiffonier/MS
+chigger/MS
+chignon/MS
+chihuahua/SM
+chilblain/SM
+child/M
+childbearing/M
+childbirth/M
+childbirths
+childcare/M
+childhood/SM
+childish/YP
+childishness/M
+childless/P
+childlessness/M
+childlike
+childminder/S
+childminding
+childproof/GSD
+children/M
+chili/M
+chilies
+chill/JPZTGMDRS
+chiller/M
+chilliness/M
+chilling/Y
+chillness/M
+chilly/TPR
+chimaera/MS
+chime/MZGDRS
+chimer/M
+chimera/MS
+chimeric
+chimerical
+chimney/MS
+chimp/MS
+chimpanzee/SM
+chin/SM
+china/M
+chinaware/M
+chinchilla/MS
+chine/MS
+chink/GMDS
+chinless
+chinned
+chinning
+chino/MS
+chinstrap/MS
+chintz/M
+chintzy/RT
+chinwag/S
+chip/SM
+chipboard
+chipmunk/SM
+chipolata/S
+chipped
+chipper/MS
+chippie
+chipping/S
+chippy/S
+chirography/M
+chiropodist/MS
+chiropody/M
+chiropractic/SM
+chiropractor/SM
+chirp/GMDS
+chirpily
+chirpy/PTR
+chirrup/GMDS
+chisel/ZGMDRS
+chiseler/M
+chiselled
+chiseller/MS
+chiselling
+chit/SM
+chitchat/SM
+chitchatted
+chitchatting
+chitin/M
+chitinous
+chitlins/M
+chitosan
+chitterlings/M
+chivalrous/PY
+chivalrousness/M
+chivalry/M
+chive/MS
+chivvy/GDS
+chivy/GDS
+chlamydia/MS
+chlamydiae
+chloral/M
+chlordane/M
+chloride/MS
+chlorinate/GNDS
+chlorination/M
+chlorine/M
+chlorofluorocarbon/SM
+chloroform/SGMD
+chlorophyll/M
+chloroplast/MS
+chm
+choc/S
+chock/GMDS
+chockablock
+chocoholic/SM
+chocolate/MS
+chocolatey
+chocolaty
+choice/MTRS
+choir/MS
+choirboy/MS
+choirmaster/SM
+choke/MZGDRS
+chokecherry/SM
+choker/M
+cholecystectomy
+cholecystitis
+choler/M
+cholera/M
+choleric
+cholesterol/M
+chomp/ZGMDRS
+choose/ZGRS
+chooser/M
+choosiness/M
+choosy/TPR
+chop/SM
+chophouse/SM
+chopped
+chopper/MDGS
+choppily
+choppiness/M
+chopping
+choppy/TPR
+chopstick/SM
+choral/MYS
+chorale/MS
+chord/MS
+chordal
+chordate/SM
+chore/MS
+chorea/M
+choreograph/DRZG
+choreographer/M
+choreographic
+choreographically
+choreographs
+choreography/M
+chorister/SM
+choroid/MS
+chortle/MZGDRS
+chortler/M
+chorus/GMDS
+chose
+chosen
+chow/SGMD
+chowder/MS
+chrism/M
+christen/ASGD
+christening/MS
+christian/U
+christology
+chromatic
+chromatically
+chromatin/M
+chromatography
+chrome/MGDS
+chromium/M
+chromosomal
+chromosome/MS
+chronic
+chronically
+chronicle/DRSMZG
+chronicler/M
+chronograph/M
+chronographs
+chronological/Y
+chronologist/MS
+chronology/SM
+chronometer/SM
+chrysalis/MS
+chrysanthemum/MS
+chub/SM
+chubbiness/M
+chubby/TPR
+chuck/GMDS
+chuckhole/SM
+chuckle/MGDS
+chuffed
+chug/SM
+chugged
+chugging
+chukka/MS
+chum/SM
+chummed
+chummily
+chumminess/M
+chumming
+chummy/PTR
+chump/MS
+chunder/GDS
+chunk/GMDS
+chunkiness/M
+chunky/PTR
+chunter/DGS
+church/MS
+churchgoer/SM
+churchgoing/M
+churchman/M
+churchmen
+churchwarden/MS
+churchwoman
+churchwomen
+churchyard/SM
+churl/MS
+churlish/PY
+churlishness/M
+churn/ZGMDRS
+churner/M
+chute/MS
+chutney/MS
+chutzpah/M
+chyme/M
+chyron/MS
+ch但teau/M
+ch但teaux
+ch但telaine/SM
+ciabatta/SM
+ciao/S
+cicada/MS
+cicatrices
+cicatrix/M
+cicerone/SM
+ciceroni
+cider's
+cider/S
+cigar/MS
+cigarette/MS
+cigarillo/MS
+cilantro/M
+cilia
+cilium/M
+cinch/GMDS
+cinchona/SM
+cincture/SM
+cinder/GMDS
+cine
+cinema/MS
+cinematic
+cinematographer/MS
+cinematographic
+cinematography/M
+cinnabar/M
+cinnamon/M
+cipher's
+cipher/CGDS
+cir
+circa
+circadian
+circle/MGDS
+circlet/MS
+circuit/MDGS
+circuital
+circuitous/YP
+circuitousness/M
+circuitry/M
+circuity/M
+circular/SMY
+circularity/M
+circularize/DSG
+circulate/ADSG
+circulation/SM
+circulatory
+circumcise/XDSGN
+circumcised/U
+circumcision/M
+circumference/MS
+circumferential
+circumflex/MS
+circumlocution/MS
+circumlocutory
+circumnavigate/XGNDS
+circumnavigation/M
+circumpolar
+circumscribe/GDS
+circumscription/MS
+circumspect/Y
+circumspection/M
+circumstance/MGDS
+circumstantial/Y
+circumvent/DSG
+circumvention/M
+circus/MS
+cirque/MS
+cirrhosis/M
+cirrhotic/SM
+cirri
+cirrus/M
+cis
+cisgender
+cistern/MS
+cit
+citadel/MS
+citation/AMS
+cite's
+cite/IAGSD
+citified
+citizen/MS
+citizenry/M
+citizenship/M
+citric
+citron/MS
+citronella/M
+citrous
+citrus/MS
+city/SM
+citywide
+civet/MS
+civic/S
+civically
+civics/M
+civil/UY
+civilian/MS
+civility/ISM
+civilization/MS
+civilize/GDS
+civilized/U
+civvies/M
+ck
+cl
+clack/GMDS
+clad/U
+cladding/M
+clade
+claim's
+claim/CKEAGDS
+claimable/A
+claimant/MS
+claimed/U
+claimer/ECSM
+clairvoyance/M
+clairvoyant/MS
+clam/SM
+clambake/MS
+clamber/ZGMDRS
+clamberer/M
+clammed
+clammily
+clamminess/M
+clamming
+clammy/PTR
+clamor/GMDS
+clamorous
+clamp/GMDS
+clampdown/MS
+clan/SM
+clandestine/Y
+clang/ZGMDRS
+clangor/M
+clangorous/Y
+clank/GMDS
+clannish/P
+clannishness/M
+clansman/M
+clansmen
+clanswoman
+clanswomen
+clap/SM
+clapboard/MDGS
+clapped
+clapper/MS
+clapperboard/S
+clapping/M
+claptrap/M
+claque/MS
+claret/MS
+clarification/M
+clarify/XDSNG
+clarinet/SM
+clarinetist/SM
+clarinettist/MS
+clarion/MDGS
+clarity/M
+clash/GMDS
+clasp's
+clasp/UGDS
+class/GMDS
+classic/MS
+classical/MY
+classicism/M
+classicist/MS
+classifiable
+classification/CAM
+classifications
+classified's
+classified/U
+classifieds
+classifier/MS
+classify/ACSDGN
+classiness/M
+classism
+classless/P
+classmate/MS
+classroom/MS
+classwork/M
+classy/TRP
+clatter/GMDS
+clausal
+clause/MS
+claustrophobia/M
+claustrophobic
+clavichord/SM
+clavicle/MS
+clavier/MS
+claw's
+claw/CSGD
+clay/M
+clayey
+clayier
+clayiest
+clean/BJPZTGDRYS
+cleaner/M
+cleaning/M
+cleanliness/UM
+cleanly/UTPR
+cleanness/UM
+cleanse/ZGDRS
+cleanser/M
+cleanup/MS
+clear/JPTGMDRYS
+clearance/SM
+clearheaded
+clearing/M
+clearinghouse/SM
+clearness/M
+clearway/S
+cleat/MS
+cleavage/MS
+cleave/ZGDRS
+cleaver/M
+clef/SM
+cleft/MS
+clematis/MS
+clemency/IM
+clement/Y
+clementine/S
+clench/GMDS
+clerestory/SM
+clergy/SM
+clergyman/M
+clergymen
+clergywoman/M
+clergywomen
+cleric/MS
+clerical/Y
+clericalism/M
+clerk/GMDS
+clerkship/M
+clever/PTRY
+cleverness/M
+clevis/MS
+clew/SGMD
+cliche/MDS
+clich辿/MS
+clich辿d
+click/BZGMDRS
+clickbait
+clicker/M
+client/MS
+clientele/MS
+client竪le/MS
+cliff/MS
+cliffhanger/SM
+cliffhanging
+clifftop/S
+clii
+climacteric/M
+climactic
+climate/SM
+climatic
+climatically
+climatologist/SM
+climatology/M
+climax/MDSG
+climb/SMDRZGB
+climber/M
+climbing/M
+clime/SM
+clinch/MDRSZG
+clincher/M
+cling/SMRZG
+clinger/M
+clingfilm
+clingy/RT
+clinic/SM
+clinical/Y
+clinician/SM
+clink/SMDRZG
+clinker/M
+cliometric/S
+cliometrician/MS
+cliometrics/M
+clip/SM
+clipboard/MS
+clipped
+clipper/SM
+clipping/SM
+clique/SM
+cliquey
+cliquish/YP
+cliquishness/M
+clit/SM
+clitoral
+clitorides
+clitoris/MS
+clix
+cloaca/M
+cloacae
+cloak's
+cloak/USDG
+cloakroom/MS
+clobber/SMDG
+cloche/SM
+clock/SMDG
+clockwise
+clockwork/SM
+clod/MS
+cloddish
+clodhopper/MS
+clog's
+clog/US
+clogged/U
+clogging/U
+cloisonne/M
+cloisonn辿/M
+cloister/SMDG
+cloistral
+clomp/SDG
+clonal
+clone/DSMG
+clonidine
+clonk/SMDG
+clop/MS
+clopped
+clopping
+close/DRSMYTGJP
+closefisted
+closemouthed
+closeness/M
+closeout/MS
+closet/SMDG
+closeup/SM
+closing/M
+closure/ESM
+clot/MS
+cloth/M
+clothe/UDSG
+clotheshorse/MS
+clothesline/SM
+clothespin/SM
+clothier/MS
+clothing/M
+cloths
+clotted
+clotting
+cloture/SM
+cloud/SMDG
+cloudburst/SM
+clouded/U
+cloudiness/M
+cloudless
+cloudy/RPT
+clout/SMDG
+clove/RSMZ
+cloven
+clover/M
+cloverleaf/SM
+cloverleaves
+clown/SMDG
+clownish/YP
+clownishness/M
+cloy/DGS
+cloying/Y
+club/MS
+clubbable
+clubbed
+clubber/S
+clubbing
+clubfeet
+clubfoot/MD
+clubhouse/SM
+clubland
+cluck/SMDG
+clue/MGDS
+clueless
+clump/SMDG
+clumpy/TR
+clumsily
+clumsiness/M
+clumsy/TRP
+clung
+clunk/SMDRZG
+clunker/M
+clunky/TR
+cluster/MDSG
+clutch/GMDS
+clutter's
+clutter/UDSG
+clvi
+clvii
+clxi
+clxii
+clxiv
+clxix
+clxvi
+clxvii
+cm
+cnidarian/MS
+co/ESD
+coach/MDSG
+coachload/S
+coachman/M
+coachmen
+coachwork
+coadjutor/MS
+coagulant/MS
+coagulate/GNDS
+coagulation/M
+coagulator/MS
+coal/MDGS
+coalesce/GDS
+coalescence/M
+coalescent
+coalface/MS
+coalfield/S
+coalition/MS
+coalitionist/MS
+coalmine/S
+coarse/RYTP
+coarsen/SDG
+coarseness/M
+coast/SMDRZG
+coastal
+coaster/M
+coastguard/S
+coastline/MS
+coat/MDGJS
+coating/M
+coatroom/S
+coattail/SM
+coauthor/MDGS
+coax/DRSZG
+coaxer/M
+coaxial
+coaxing/Y
+cob/SM
+cobalt/M
+cobber/S
+cobble/DRSMZG
+cobbler/M
+cobblestone/SM
+cobnut/S
+cobra/SM
+cobweb/SM
+cobwebbed
+cobwebby/RT
+coca/M
+cocaine/M
+cocci/S
+coccus/M
+coccyges
+coccyx/M
+cochineal/M
+cochlea/SM
+cochleae
+cochlear
+cock/MDGS
+cockade/SM
+cockamamie
+cockatiel/MS
+cockatoo/SM
+cockatrice/SM
+cockchafer/S
+cockcrow/SM
+cockerel/SM
+cockeyed
+cockfight/MGS
+cockfighting/M
+cockily
+cockiness/M
+cockle/SM
+cockleshell/SM
+cockney/SM
+cockpit/SM
+cockroach/MS
+cockscomb/SM
+cocksucker/MS!
+cocksure
+cocktail/MS
+cocky/RTP
+coco/MS
+cocoa/SM
+coconut/SM
+cocoon/SMDG
+cod/SM
+coda/MS
+codded
+codding
+coddle/DSG
+code's
+code/CZGDRS
+codeine/M
+codependency/M
+codependent/SM
+coder/CM
+codex/M
+codfish/MS
+codger/SM
+codices
+codicil/SM
+codification/M
+codifier/M
+codify/XDRSNZG
+codon/S
+codpiece/MS
+codswallop
+coed/MS
+coeducation/M
+coeducational
+coefficient/MS
+coelenterate/MS
+coenzyme
+coequal/MYS
+coerce/DRSZGNV
+coercer/M
+coercion/M
+coeval/SMY
+coexist/DSG
+coexistence/M
+coexistent
+coextensive
+coffee/SM
+coffeecake/SM
+coffeehouse/MS
+coffeemaker/SM
+coffeepot/MS
+coffer/SM
+cofferdam/MS
+coffin/SMDG
+cog/SM
+cogency/M
+cogent/Y
+cogitate/DSXGNV
+cogitation/M
+cogitator/MS
+cognac/SM
+cognate/MS
+cognition/AM
+cognitional
+cognitive/Y
+cognizable
+cognizance/AM
+cognizant
+cognomen/SM
+cognoscente/M
+cognoscenti
+cogwheel/SM
+cohabit/SGD
+cohabitant/MS
+cohabitation/M
+coheir/SM
+cohere/DSG
+coherence/IM
+coherency/M
+coherent/IY
+cohesion/M
+cohesive/YP
+cohesiveness/M
+coho/MS
+cohort/SM
+coif/MDGS
+coiffed
+coiffing
+coiffure/DSMG
+coil's/A
+coil/UADGS
+coin/MDRZGS
+coinage/SM
+coincide/DSG
+coincidence/MS
+coincident
+coincidental/Y
+coiner/M
+coinsurance/M
+coir
+coital
+coitus/M
+coke/MGDS
+col/S
+cola/MS
+colander/SM
+cold/MRYTPS
+coldblooded
+coldness/M
+coleslaw/M
+coleus/MS
+coley/S
+colic/M
+colicky
+coliseum/MS
+colitis/M
+coll
+collaborate/DSXGNV
+collaboration/M
+collaborationist
+collaborative/Y
+collaborator/MS
+collage/SM
+collagen
+collapse/MGDS
+collapsible
+collar/SMDG
+collarbone/SM
+collard/SM
+collarless
+collate/DSXGN
+collateral/MY
+collateralize
+collation/M
+collator/MS
+colleague/MS
+collect's
+collect/ASGVD
+collectable/MS
+collected/U
+collectedly
+collectible/SM
+collection/AMS
+collective/MYS
+collectivism/M
+collectivist/SM
+collectivization/M
+collectivize/DSG
+collector/MS
+colleen/SM
+college/SM
+collegiality/M
+collegian/MS
+collegiate
+collide/DRSZG
+collie/RSMZ
+collier/M
+colliery/SM
+collision/SM
+collocate/MGNDSX
+collocation/M
+colloid/SM
+colloidal
+colloq
+colloquial/Y
+colloquialism/SM
+colloquies
+colloquium/MS
+colloquy/M
+collude/DSG
+collusion/M
+collusive
+cologne/SM
+colon/SM
+colonel/SM
+colonelcy/M
+colones
+colonial/SMY
+colonialism/M
+colonialist/MS
+colonist/SM
+colonization/ACM
+colonize/CAGSD
+colonizer/MS
+colonnade/MDS
+colonoscopy/SM
+colony/SM
+colophon/SM
+color's
+color/AEGDS
+colorant/SM
+coloration/EM
+coloratura/MS
+colorblind/P
+colorblindness/M
+colored's
+colored/U
+coloreds
+colorfast/P
+colorfastness/M
+colorful/PY
+colorfulness/M
+coloring's
+colorist/S
+colorization/M
+colorize/DSG
+colorless/PY
+colorlessness/M
+colorway/S
+colossal/Y
+colossi
+colossus/M
+colostomy/SM
+colostrum/M
+colt/MS
+coltish
+columbine/SM
+column/SMD
+columnar
+columnist/SM
+com/JL
+coma/MS
+comaker/SM
+comatose
+comb/MDRZGJS
+combat/SMDGV
+combatant/SM
+combativeness/M
+combed/U
+comber/M
+combination/SM
+combine's
+combine/ADSG
+combined/U
+combiner/MS
+combings/M
+combo/SM
+combust/SGVD
+combustibility/M
+combustible/MS
+combustion/M
+come/IMZGRS
+comeback/MS
+comedian/MS
+comedic
+comedienne/MS
+comedown/MS
+comedy/SM
+comeliness/M
+comely/RPT
+comer's
+comestible/SM
+comet/SM
+comeuppance/SM
+comfit's
+comfit/ES
+comfort/ESMDG
+comfortable/P
+comfortableness/M
+comfortably/U
+comforter/MS
+comforting/Y
+comfortless
+comfy/RT
+comic/SM
+comical/Y
+comicality/M
+coming/M
+comity/M
+comm
+comma/SM
+command/SMDRLZG
+commandant/MS
+commandeer/GDS
+commander/M
+commandment/MS
+commando/SM
+commemorate/XGNVDS
+commemoration/M
+commemorator/MS
+commence/ADSLG
+commencement/AM
+commencements
+commend/ASDBG
+commendably
+commendation/AMS
+commendatory
+commensurable
+commensurate/IY
+comment/GSMD
+commentary/SM
+commentate/DSG
+commentator/SM
+commerce/M
+commercial/SMY
+commercialism/M
+commercialization/M
+commercialize/GDS
+commie/SM
+commingle/DSG
+commiserate/GNVDSX
+commiseration/M
+commissar/SM
+commissariat/SM
+commissary/SM
+commission's
+commission/ACSGD
+commissionaire/S
+commissioner/SM
+commit/AS
+commitment/MS
+committal/SM
+committed/AU
+committee/SM
+committeeman/M
+committeemen
+committeewoman/M
+committeewomen
+committer/S
+committing/A
+commode's
+commode/EIS
+commodification
+commodious/Y
+commodity/SM
+commodore/SM
+common's
+common/UPRYT
+commonality/S
+commonalty/M
+commoner/MS
+commonness/UM
+commonplace/MS
+commons
+commonsense
+commonweal/MH
+commonwealth/M
+commonwealths
+commotion/SM
+communal/Y
+commune/XDSMGN
+communicability/M
+communicable/I
+communicably
+communicant/MS
+communicate/GNVDSX
+communication/M
+communicative/U
+communicator/SM
+communion/M
+communique/SM
+communism/M
+communist/SM
+communistic
+community/SM
+commutation/MS
+commutative
+commutativity
+commutator/SM
+commute/BDRSMZG
+commuter/M
+comorbidity
+comp/MDYGS
+compact/TGSMDRYP
+compaction
+compactness/M
+compactor/SM
+companion/SBM
+companionably
+companionship/M
+companionway/MS
+company/SM
+comparability/M
+comparable/I
+comparably/I
+comparative/MYS
+compare/BDSG
+comparison/MS
+compartment/SM
+compartmental
+compartmentalization/M
+compartmentalize/DSG
+compass/GMDS
+compassion/M
+compassionate/Y
+compatibility/IM
+compatible/IMS
+compatibly/I
+compatriot/MS
+compeer/SM
+compel/S
+compelled
+compelling/Y
+compendious
+compendium/SM
+compensate/DSXGN
+compensated/U
+compensation/M
+compensatory
+compere/DSG
+compete/DSG
+competence/IM
+competences
+competencies
+competency/IM
+competent/IY
+competition/SM
+competitive/PY
+competitiveness/M
+competitor/SM
+compilation/SM
+compile/DRSZG
+compiler/M
+complacence/M
+complacency/M
+complacent/Y
+complain/DRZGS
+complainant/MS
+complainer/M
+complaint/SM
+complaisance/M
+complaisant/Y
+complected
+complement/SGMD
+complementary
+complete/PYTGNXDRS
+completed/U
+completeness/IM
+completion/M
+complex/MSY
+complexion/MDS
+complexional
+complexity/SM
+compliance/M
+compliant/Y
+complicate/GDS
+complicated/Y
+complication/M
+complicit
+complicity/M
+compliment/MDGS
+complimentary/U
+comply/NDSXG
+compo/S
+component/SM
+comport/LSGD
+comportment/M
+compose/AECGSD
+composedly
+composer/MS
+composite/MYGNXDS
+composition/CM
+compositional
+compositor/SM
+compost/SGMD
+composure/EM
+compote/SM
+compound/GMDBS
+compounded/U
+comprehend/SDG
+comprehensibility/IM
+comprehensible/I
+comprehensibly/I
+comprehension/IM
+comprehensions
+comprehensive/PMYS
+comprehensiveness/M
+compress's
+compress/CGVDS
+compressed/U
+compressible
+compression/CM
+compressor/SM
+comprise/GDS
+compromise/MGDS
+comptroller/MS
+compulsion/MS
+compulsive/YP
+compulsiveness/M
+compulsorily
+compulsory/SM
+compunction/SM
+computation/SM
+computational/Y
+compute/ADSG
+computer/MS
+computerate
+computerization/M
+computerize/GDS
+computing/M
+comp竪re/DSG
+comrade/SMY
+comradeship/M
+con/GSM
+concatenate/XDSGN
+concatenation/M
+concave/YP
+concaveness/M
+conceal/SDRZGBL
+concealed/U
+concealer/M
+concealment/M
+conceit/SMD
+conceited/PY
+conceitedness/M
+conceivable/I
+conceivably/I
+conceive/DSGB
+concentrate/DSMGNX
+concentration/M
+concentric
+concentrically
+concept/SM
+conception/SM
+conceptional
+conceptual/Y
+conceptualization/MS
+conceptualize/DSG
+concern/UMD
+concerned/UY
+concerning
+concerns
+concert's
+concert/ESDG
+concerted/Y
+concertgoer/S
+concertina/SGMD
+concertize/DSG
+concertmaster/MS
+concerto/SM
+concessionaire/MS
+concessional
+concessionary
+conch/M
+conchie/S
+conchs
+concierge/MS
+conciliate/DSGN
+conciliation/AM
+conciliator/SM
+conciliatory
+concise/RPYTN
+conciseness/M
+concision/M
+conclave/SM
+conclude/DSG
+conclusion/MS
+conclusive/IYP
+conclusiveness/IM
+concoct/SDG
+concoction/MS
+concomitant/MYS
+concord/M
+concordance/SM
+concordant
+concordat/SM
+concourse/SM
+concrete/DSPMYGNX
+concreteness/M
+concretion/M
+concubinage/M
+concubine/MS
+concupiscence/M
+concupiscent
+concur/S
+concurred
+concurrence/SM
+concurrency
+concurring
+concuss/V
+concussion/SM
+condemn/SDRZG
+condemnation/MS
+condemnatory
+condemner/M
+condensate/MNXS
+condensation/M
+condense/DRSZG
+condenser/M
+condescending/Y
+condescension/M
+condign
+condiment/MS
+condition's
+condition/AGSD
+conditional/SMY
+conditionality
+conditioned/U
+conditioner/SM
+conditioning/M
+condo/SM
+condolence/SM
+condom/SM
+condominium/MS
+condone/DSG
+condor/SM
+conduce/DSGV
+conduct/MDGV
+conductance/M
+conductibility/M
+conductible
+conduction/M
+conductivity/M
+conductor/MS
+conductress/MS
+conduit/SM
+cone/M
+coney/SM
+confab/SM
+confabbed
+confabbing
+confabulate/XDSGN
+confabulation/M
+confection/SZMR
+confectioner/M
+confectionery/SM
+confederacy/SM
+confederate/M
+confer/S
+conferee/SM
+conference/MGS
+conferrable
+conferral/M
+conferred
+conferrer/MS
+conferring
+confessed/Y
+confession/SM
+confessional/SM
+confessor/MS
+confetti/M
+confidant/MS
+confidante/SM
+confide/DRSZG
+confidence/SM
+confident/Y
+confidential/Y
+confidentiality/M
+confider/M
+confiding/Y
+configuration/S
+configure/B
+confined/U
+confinement/MS
+confirm/ASDG
+confirmation/ASM
+confirmatory
+confirmed/U
+confiscate/DSGNX
+confiscation/M
+confiscator/SM
+confiscatory
+conflagration/MS
+conflate/XDSGN
+conflation/M
+conflict/SGMD
+confluence/MS
+confluent
+conform/ZB
+conformable/U
+conformal
+conformance/M
+conformism/M
+conformist/SM
+conformity/M
+confrere/MS
+confrontation/SM
+confrontational
+confr竪re/SM
+confuse/RZ
+confused/Y
+confusing/Y
+confutation/M
+confute/DSG
+conga/SMDG
+congeal/SLDG
+congealment/M
+conger/SM
+congeries/M
+congest/SDGV
+congestion/M
+conglomerate/DSXMGN
+conglomeration/M
+congrats/M
+congratulate/XGNDS
+congratulation/M
+congratulatory
+congregant/MS
+congregate/GNDSX
+congregation/M
+congregational
+congregationalism/M
+congregationalist/MS
+congress/MS
+congressional
+congressman/M
+congressmen
+congresspeople
+congressperson/MS
+congresswoman/M
+congresswomen
+congruence/M
+congruent/Y
+congruity/ISM
+congruous
+conic/SM
+conical/Y
+conifer/SM
+coniferous
+conjectural
+conjecture/MGDS
+conjoint
+conjugal/Y
+conjugate/DSXGN
+conjugation/M
+conjunct/VMS
+conjunctiva/SM
+conjunctive/SM
+conjunctivitis/M
+conjuration/MS
+conjure/DRSZG
+conjurer/M
+conk/MDRZ
+conman
+connect/AEDVGS
+connectable
+connected/U
+connection/EMS
+connective/MS
+connectivity/M
+connector/MS
+conned
+conning
+conniption/MS
+connivance/M
+connive/DRSZG
+conniver/M
+connoisseur/SM
+connotative
+connubial
+conquer/ASDG
+conquerable/U
+conquered/U
+conqueror/MS
+conquest/AM
+conquistador/SM
+cons/DSG
+consanguineous
+consanguinity/M
+conscienceless
+conscientious/PY
+conscientiousness/M
+conscious/UYP
+consciousness/UM
+consciousnesses
+conscription/M
+consecrate/ADSGN
+consecrated/U
+consecration/AM
+consecrations
+consecutive/Y
+consensual
+consensus/MS
+consent/SMDG
+consequence/SM
+consequent/Y
+consequential/IY
+conservancy/SM
+conservation/M
+conservationism/M
+conservationist/SM
+conservatism/M
+conservative/MYS
+conservatoire/S
+conservator/SM
+conservatory/SM
+consider/AGSD
+considerable/I
+considerably
+considerate/IPYN
+considerateness/IM
+consideration/AIM
+considerations
+considered/U
+consign/ASDG
+consignee/MS
+consignment/MS
+consist/SDG
+consistence/MS
+consistency/ISM
+consistent/IY
+consistory/SM
+consolable/I
+consolation/MS
+consolatory
+consolidate/XDSGN
+consolidated/U
+consolidation/M
+consolidator/MS
+consoling/Y
+consomme/M
+consomm辿/M
+consonance/SM
+consonant/SMY
+consortia
+consortium/M
+conspectus/MS
+conspicuous/IPY
+conspicuousness/IM
+conspiracy/SM
+conspirator/MS
+conspiratorial/Y
+conspire/GD
+constable/SM
+constabulary/SM
+constancy/IM
+constant/MYS
+constellation/SM
+consternation/M
+constipate/GNDS
+constipation/M
+constituency/SM
+constituent/SM
+constitute/ADSGNV
+constitution/AM
+constitutional/MYS
+constitutionalism
+constitutionality/UM
+constitutions
+constrained/U
+constraint/SM
+constrict/GVSD
+constriction/SM
+constrictor/SM
+construable
+construct's
+construct/CADVGS
+construction/CAMS
+constructional
+constructionist's
+constructionist/CS
+constructive/YP
+constructiveness/M
+constructor/MS
+construe/GDS
+consul/KSM
+consular/K
+consulate/SM
+consulship/M
+consult/GSD
+consultancy/SM
+consultant/MS
+consultation/MS
+consultative
+consumable/SM
+consume/BDRSZG
+consumed/U
+consumer/M
+consumerism/M
+consumerist/MS
+consummate/YGNXDS
+consummated/U
+consumption/M
+consumptive/SM
+cont
+contact/ASDG
+contactable
+contactless
+contagion/MS
+contagious/PY
+contagiousness/M
+contain/SBLDRZG
+container/M
+containerization/M
+containerize/DSG
+containment/M
+contaminant/SM
+contaminate/ACDSG
+contaminated/U
+contamination/CM
+contaminator/SM
+contd
+contemn/SDG
+contemplate/DSGNV
+contemplation/M
+contemplative/SMY
+contemporaneity/M
+contemporaneous/Y
+contempt/M
+contemptible
+contemptibly
+contemptuous/YP
+contemptuousness/M
+contender/MS
+content/ESLMDG
+contented/EY
+contentedness/M
+contention/SM
+contentious/YP
+contentiousness/M
+contently
+contentment/EM
+conterminous/Y
+contestable/I
+contestant/MS
+contested/U
+contextualization
+contextualize/DSG
+contiguity/M
+contiguous/Y
+continence/IM
+continent/SM
+continental/SM
+contingency/SM
+contingent/SMY
+continua
+continual/Y
+continuance/EMS
+continuation/EMS
+continue/EGDS
+continuity/ESM
+continuous/EY
+continuum/M
+contort/GD
+contortion/MS
+contortionist/SM
+contra
+contraband/M
+contrabassoon/S
+contraception/M
+contraceptive/SM
+contract/MDG
+contractible
+contractile
+contractility
+contraction/S
+contractual/Y
+contradict/SDG
+contradiction/SM
+contradictory
+contradistinction/MS
+contraflow/S
+contrail/MS
+contraindicate/GNXDS
+contraindication/M
+contralto/SM
+contraption/SM
+contrapuntal/Y
+contrarian/SM
+contrarianism
+contrariety/M
+contrarily
+contrariness/M
+contrariwise
+contrary/PSM
+contrast/MDGS
+contravene/GDS
+contravention/SM
+contretemps/M
+contribute/XGND
+contribution/M
+contributor/MS
+contributory
+contrition/M
+contrivance/MS
+contrive/ZGDRS
+contriver/M
+control's
+control/CS
+controllable/U
+controlled/UC
+controller/MS
+controlling/C
+controversial/Y
+controversy/SM
+controvert/DSG
+controvertible/I
+contumacious/Y
+contumacy/M
+contumelious
+contumely/SM
+contuse/XDSGN
+contusion/M
+conundrum/SM
+conurbation/MS
+convalesce/DSG
+convalescence/MS
+convalescent/SM
+convection/M
+convectional
+convective
+convector/S
+convene/ADSG
+convener/MS
+convenience/IMS
+convenient/IY
+convenor/MS
+convent/SM
+conventicle/MS
+convention/SM
+conventional/UY
+conventionality/UM
+conventionalize/GDS
+conventioneer/S
+convergence/MS
+convergent
+conversant
+conversation/MS
+conversational/Y
+conversationalist/SM
+converse/Y
+convert's
+convert/AGSD
+converted/U
+converter/SM
+convertibility/M
+convertible/SM
+convertor/SM
+convex/Y
+convexity/M
+convey/SBDG
+conveyance/MGS
+conveyor/MS
+convict/GSMD
+conviction/MS
+convince/GDS
+convinced/U
+convincing/UY
+convivial/Y
+conviviality/M
+convoke/DSG
+convoluted
+convolution/MS
+convoy/SMDG
+convulse/GNVXDS
+convulsion/M
+convulsive/Y
+cony/SM
+coo/GSMD
+cook's
+cook/ADGS
+cookbook/MS
+cooked/U
+cooker/SM
+cookery/SM
+cookhouse/S
+cookie/M
+cooking/M
+cookout/SM
+cookware/SM
+cooky/SM
+cool/MDRYZTGPS
+coolant/SM
+cooler/M
+coolie/SM
+coolness/M
+coon/MS!
+coonskin/MS
+coop/MDRZGS
+cooper/MDG
+cooperage/M
+cooperate/DSGNV
+cooperation/M
+cooperative/PMYS
+cooperativeness/M
+cooperator/SM
+coordinate/DSMYGN
+coordinated/U
+coordination/M
+coordinator/MS
+coot/MS
+cootie/SM
+cop/GJSMD
+copacetic
+copay/M
+cope/MS
+copier/SM
+copilot/SM
+coping/M
+copious/PY
+copiousness/M
+copped
+copper/SM
+copperhead/SM
+copperplate/M
+coppery
+copping
+copra/M
+copse/SM
+copter/SM
+copula/SM
+copulate/GNVDS
+copulation/M
+copulative/SM
+copy's
+copy/ADSG
+copybook/SM
+copycat/MS
+copycatted
+copycatting
+copyist/MS
+copyleft
+copyright/GSMD
+copywriter/MS
+coquetry/SM
+coquette/DSMG
+coquettish/Y
+cor
+coracle/SM
+coral/SM
+corbel/SM
+cord/EASGDM
+cordage/M
+cordial/SMY
+cordiality/M
+cordillera/MS
+cordite/M
+cordless
+cordon/SMDG
+cordovan/M
+corduroy/MS
+corduroys/M
+core/MZGDRS
+coreligionist/S
+corer/M
+corespondent/MS
+corgi/SM
+coriander/M
+cork's
+cork/UDGS
+corkage
+corker/SM
+corkscrew/SMDG
+corm/MS
+cormorant/SM
+corn/MDRZGS
+cornball/MS
+cornbread/M
+corncob/MS
+corncrake/S
+cornea/SM
+corneal
+corner/GMD
+cornerstone/SM
+cornet/SM
+cornfield/S
+cornflakes/M
+cornflour
+cornflower/SM
+cornice/MS
+cornily
+corniness/M
+cornmeal/M
+cornrow/MDGS
+cornstalk/SM
+cornstarch/M
+cornucopia/MS
+corny/PRT
+corolla/MS
+corollary/SM
+corona/SM
+coronal/MS
+coronary/SM
+coronation/SM
+coronavirus/MS
+coroner/MS
+coronet/MS
+corp
+corpora
+corporal/SM
+corporate/XYN
+corporation/IM
+corporatism
+corporeal/Y
+corporeality/M
+corps/MS
+corpse/M
+corpsman/M
+corpsmen
+corpulence/M
+corpulent
+corpus/M
+corpuscle/MS
+corpuscular
+corr
+corral/SM
+corralled
+corralling
+correct/DRYTGVSBP
+corrected/U
+correction/SM
+correctional
+corrective/SM
+correctness/IM
+corrector
+correlate/XDSMGNV
+correlated/U
+correlation/M
+correlational
+correlative/MS
+correspond/SDG
+correspondence/SM
+correspondent/SM
+corresponding/Y
+corridor/SM
+corrie/S
+corroborate/GNVDSX
+corroborated/U
+corroboration/M
+corroborator/SM
+corroboratory
+corrode/GDS
+corrosion/M
+corrosive/SMY
+corrugate/GNXDS
+corrugation/M
+corrupt/DRYPSTG
+corruptibility/IM
+corruptible/I
+corruption/MS
+corruptness/M
+corsage/MS
+corsair/MS
+corset/SGMD
+cortege/MS
+cortex/M
+cortical
+cortices
+cortisol
+cortisone/M
+cort竪ge/SM
+corundum/M
+coruscate/GNDS
+coruscation/M
+corvette/SM
+cos/M
+cosh/DSG
+cosign/ZGSDR
+cosignatory/SM
+cosigner/M
+cosine/SM
+cosmetic/SM
+cosmetically
+cosmetician/MS
+cosmetologist/MS
+cosmetology/M
+cosmic
+cosmically
+cosmogonist/SM
+cosmogony/SM
+cosmological
+cosmologist/SM
+cosmology/SM
+cosmonaut/SM
+cosmopolitan/MS
+cosmopolitanism/M
+cosmos/MS
+cosplay
+cosponsor/GSMD
+cosset/SGD
+cossetted
+cossetting
+cost/MDYGSJ
+costar/SM
+costarred
+costarring
+costliness/M
+costly/PTR
+costume/MZGDRS
+costumer/M
+costumier/S
+cot/SM
+cotangent/MS
+cote/MS
+coterie/MS
+coterminous
+cotillion/SM
+cottage/MZGRS
+cottager/M
+cottar/SM
+cotter/SM
+cotton/SGMD
+cottonmouth/M
+cottonmouths
+cottonseed/MS
+cottontail/MS
+cottonwood/SM
+cottony
+cotyledon/MS
+couch/MDSG
+couchette/S
+cougar/SM
+cough/MDG
+coughs
+could
+could've
+couldn't
+coulee/SM
+coulis
+coulomb/MS
+coul辿e/SM
+council/MS
+councilman/M
+councilmen
+councilor/MS
+councilperson/SM
+councilwoman/M
+councilwomen
+counsel/JMDGS
+counselor/MS
+count/EASMDG
+countable/U
+countably
+countdown/MS
+counted/U
+countenance's
+countenance/EGDS
+counter/EMS
+counteract/SGVD
+counteraction/MS
+counterargument/S
+counterattack/GMDS
+counterbalance/MGDS
+counterblast/S
+counterclaim/GSMD
+counterclockwise
+counterculture/SM
+countered
+counterespionage/M
+counterexample/S
+counterfactual
+counterfeit/ZGMDRS
+counterfeiter/M
+counterfoil/MS
+countering
+counterinsurgency/SM
+counterintelligence/M
+counterman/M
+countermand/GMDS
+countermeasure/SM
+countermelody/S
+countermen
+countermove/S
+counteroffensive/SM
+counteroffer/SM
+counterpane/SM
+counterpart/SM
+counterpetition
+counterpoint/MDGS
+counterpoise/MGDS
+counterproductive
+counterrevolution/SM
+counterrevolutionary/SM
+countersign/GSMD
+countersignature/MS
+countersink/GSM
+counterspy/SM
+counterstroke/SM
+countersunk
+countertenor/MS
+countervail/GSD
+counterweight/MS
+countess/MS
+countless
+countrified
+country/SM
+countryman/M
+countrymen
+countryside/MS
+countrywide
+countrywoman/M
+countrywomen
+county/SM
+countywide
+coup's
+coup/AS
+coupe/SM
+couple's
+couple/UCGSD
+couplet/MS
+coupling/SM
+coupon/SM
+courage/M
+courageous/YP
+courageousness/M
+courgette/S
+courier/MDSG
+course/EDGMS
+coursebook/S
+courser/MS
+coursework
+court/SMDYG
+courteous/EY
+courteousness/M
+courtesan/SM
+courtesy/ESM
+courthouse/MS
+courtier/SM
+courtliness/M
+courtly/PRT
+courtroom/MS
+courtship/MS
+courtyard/MS
+couscous/M
+cousin/SM
+couture/M
+couturier/MS
+covalent
+covariance
+covariant
+cove/MS
+coven/SM
+covenant/MDSG
+cover's
+cover/AEUGDS
+coverage/M
+coverall/MS
+covering's
+coverings
+coverlet/MS
+covert/SPMY
+covertness/M
+coverup/MS
+covet/SDG
+covetous/YP
+covetousness/M
+covey/SM
+cow/ZGSMDR
+coward/SMY
+cowardice/M
+cowardliness/M
+cowbell/MS
+cowbird/MS
+cowboy/SM
+cowcatcher/MS
+cower/DG
+cowgirl/MS
+cowhand/MS
+cowherd/MS
+cowhide/MS
+cowl/MGSJ
+cowlick/MS
+cowling/M
+cowman/M
+cowmen
+coworker/MS
+cowpat/S
+cowpoke/MS
+cowpox/M
+cowpuncher/SM
+cowrie/SM
+cowshed/S
+cowslip/SM
+cox/GDS
+coxcomb/MS
+coxswain/MS
+coy/TPRY
+coyness/M
+coyote/SM
+coypu/SM
+cozen/SDG
+cozenage/M
+cozily
+coziness/M
+cozy/RSMTP
+cpd
+cpl
+cps
+crab/MS
+crabbed
+crabber/SM
+crabbily
+crabbiness/M
+crabbing
+crabby/PRT
+crabgrass/M
+crablike
+crabwise
+crack/SMDRYZGJ
+crackdown/MS
+cracker/M
+crackerjack/MS
+crackhead/MS
+crackle/DSJMG
+crackling/M
+crackpot/MS
+crackup/SM
+cradle/DSMG
+craft/SMDG
+craftily
+craftiness/M
+craftsman/M
+craftsmanship/M
+craftsmen
+craftspeople
+craftswoman/M
+craftswomen
+crafty/RTP
+crag/MS
+cragginess/M
+craggy/RPT
+cram/S
+crammed
+crammer/S
+cramming
+cramp/SMDG
+cramping/M
+crampon/SM
+cranberry/SM
+crane/DSMG
+cranial
+cranium/SM
+crank/SMDG
+crankcase/SM
+crankily
+crankiness/M
+crankshaft/MS
+cranky/PRT
+cranny/DSM
+crap/MS
+crape/SM
+crapped
+crapper/S
+crappie/RSMT
+crapping
+crappy
+craps/M
+crapshooter/MS
+crash/MDSG
+crass/RYTP
+crassness/M
+crate/DRSMZG
+crater/MDG
+cravat/SM
+crave/DSGJ
+craven/SMYP
+cravenness/M
+craving/M
+craw/MS
+crawdad/SM
+crawl/SMDRZG
+crawler/M
+crawlspace/SM
+crawly/TRSM
+cray/S
+crayfish/MS
+crayola/S
+crayon/GSMD
+craze/DSMG
+crazily
+craziness/M
+crazy/PRSMT
+creak/SMDG
+creakily
+creakiness/M
+creaky/RPT
+cream/SMDRZG
+creamer/M
+creamery/SM
+creamily
+creaminess/M
+creamy/RPT
+crease/ICGMSD
+create/KADSGNV
+creation's/K
+creation/ASM
+creationism/SM
+creationist/SM
+creative/SMYP
+creativeness/M
+creativity/M
+creator/MS
+creature/SM
+creche/SM
+cred
+credence/M
+credential/SGMD
+credenza/SM
+credibility/IM
+credible/I
+credibly/I
+credit/EGSBMD
+creditably/E
+creditor/SM
+creditworthy/P
+credo/SM
+credulity/IM
+credulous/IY
+credulousness/M
+creed/SM
+creek/SM
+creel/SM
+creep/SMRZG
+creeper/M
+creepily
+creepiness/M
+creepy/TPR
+cremains/M
+cremate/GNDSX
+cremation/M
+crematoria
+crematorium/MS
+crematory/SM
+creme/SM
+crenelate/XGNDS
+crenelation/M
+creole/SM
+creosote/MGDS
+crepe/SM
+crept
+crepuscular
+crescendo/CSM
+crescent/MS
+cress/M
+crest/SMDG
+crestfallen
+crestless
+cretaceous
+cretin/SM
+cretinism/M
+cretinous
+cretonne/M
+crevasse/SM
+crevice/MS
+crew/MDGS
+crewel/M
+crewelwork/M
+crewman/M
+crewmen
+crib/MS
+cribbage/M
+cribbed
+cribber/MS
+cribbing
+crick/SMDG
+cricket/MRSZG
+cricketer/M
+crier/M
+crikey
+crime/SM
+criminal/MYS
+criminality/M
+criminalize/CGDS
+criminologist/MS
+criminology/M
+crimp/SMDG
+crimson/SMDG
+cringe/DSMG
+crinkle/DSMG
+crinkly/RT
+crinoline/SM
+cripes
+cripple/DRSMZG
+crippler/M
+crippleware
+crippling/Y
+crises
+crisis/M
+crisp/SMDRYTGP
+crispbread/S
+crispiness/M
+crispness/M
+crispy/PRT
+crisscross/GMDS
+criteria
+criterion/M
+critic/SM
+critical/UY
+criticality
+criticism/MS
+criticize/ZGDRS
+criticizer/M
+critique/MGDS
+critter/SM
+croak/SMDG
+croaky/RT
+crochet/SMDRZG
+crocheter/M
+crocheting/M
+crock/SMD
+crockery/M
+crocodile/SM
+crocus/MS
+croft/SRZG
+croissant/MS
+crone/SM
+crony/SM
+cronyism/M
+crook/SMDG
+crooked/PTRY
+crookedness/M
+crookneck/SM
+croon/SMDRZG
+crooner/M
+crop/MS
+cropland/SM
+cropped
+cropper/MS
+cropping
+croquet/M
+croquette/SM
+crosier/MS
+cross's
+cross/AUGTSD
+crossbar/SM
+crossbeam/MS
+crossbones/M
+crossbow/SM
+crossbowman/M
+crossbowmen
+crossbred
+crossbreed/SGM
+crosscheck/SMDG
+crosscurrent/MS
+crosscut/SM
+crosscutting
+crosser
+crossfire/MS
+crosshatch/GDS
+crossing/SM
+crossly
+crossness/M
+crossover/MS
+crosspatch/MS
+crosspiece/SM
+crossroad/MS
+crossroads/M
+crosstown
+crosswalk/MS
+crosswind/MS
+crosswise
+crossword/MS
+crotch/MS
+crotchet/SM
+crotchety
+crouch/GMDS
+croup/M
+croupier/M
+croupy/ZTR
+crouton/MS
+crow/MDGS
+crowbar/MS
+crowd/SMDG
+crowded/U
+crowdfund/SDG
+crowfeet
+crowfoot/SM
+crown/SMDG
+crowned/U
+crozier/MS
+cro短ton/MS
+crucial/Y
+crucible/SM
+crucifix/MS
+crucifixion/SM
+cruciform/SM
+crucify/DSG
+crud/M
+cruddy/TR
+crude/RMYTP
+crudeness/M
+crudites/M
+crudity/SM
+crudit辿s/M
+cruel/RYPT
+cruelness/M
+cruelty/SM
+cruet/SM
+cruft/SD
+crufty
+cruise/DRSMZG
+cruiser/M
+cruller/MS
+crumb/SMDYG
+crumble/MGDS
+crumbliness/M
+crumbly/TPR
+crumby/TR
+crumminess/M
+crummy/PTR
+crumpet/MS
+crumple/MGDS
+crunch/GMDRS
+crunchiness/M
+crunchy/TRP
+crupper/MS
+crusade/MZGDRS
+crusader/M
+cruse/SM
+crush/MDRSZG
+crusher/M
+crushing/Y
+crust/SMDG
+crustacean/SM
+crustal
+crustily
+crustiness/M
+crusty/TRP
+crutch/MS
+crux/MS
+cry/ZGJDRSM
+crybaby/SM
+cryogenic/S
+cryogenics/M
+cryonics
+cryosurgery/M
+crypt/SM
+cryptanalysis
+cryptic
+cryptically
+cryptocurrency/SM
+cryptogram/SM
+cryptographer/SM
+cryptography/M
+crystal/SM
+crystalline
+crystallization/M
+crystallize/ADSG
+crystallographic
+crystallography
+cr竪che/MS
+ct
+ctn
+ctr
+cu
+cub/ZGSMDR
+cubbyhole/MS
+cube/MS
+cuber/M
+cubic
+cubical
+cubicle/MS
+cubism/M
+cubist/SM
+cubit/SM
+cuboid/S
+cuckold/MDSG
+cuckoldry/M
+cuckoo/SM
+cucumber/SM
+cud/SM
+cuddle/DSMG
+cuddly/TR
+cudgel/SGMDJ
+cue/DSMG
+cuff/MDGS
+cuisine/SM
+culinary
+cull/MDGS
+cullender/MS
+culminate/XDSGN
+culmination/M
+culotte/SM
+culpability/M
+culpable/I
+culpably
+culprit/SM
+cult/MS
+cultism/M
+cultist/MS
+cultivable
+cultivar/SM
+cultivate/BDSGN
+cultivated/U
+cultivation/M
+cultivator/MS
+cultural/Y
+culture/MGDS
+cultured/U
+culvert/MS
+cum/SM
+cumber/SDG
+cumbersome/P
+cumbersomeness/M
+cumbrous
+cumin/M
+cummerbund/MS
+cumming
+cumulative/Y
+cumuli
+cumulonimbi
+cumulonimbus/M
+cumulus/M
+cuneiform/M
+cunnilingus/M
+cunning/MRYT
+cunt/MS!
+cup/SM
+cupboard/SM
+cupcake/MS
+cupful/SM
+cupid/SM
+cupidity/M
+cupola/SMD
+cuppa/S
+cupped
+cupping
+cupric
+cur/SMY
+curability/M
+curacao
+curacy/SM
+curare/M
+curate/DSMGV
+curative/MS
+curator/KMS
+curatorial
+cura巽ao
+curb/MDGS
+curbing/M
+curbside
+curbstone/SM
+curd/MS
+curdle/DSG
+cure's
+cure/KZGBDRS
+cured/U
+curer/KM
+curettage/M
+curfew/SM
+curia/M
+curiae
+curie/SM
+curio/SM
+curiosity/SM
+curious/YP
+curiousness/M
+curium/M
+curl's
+curl/UDGS
+curler/SM
+curlew/SM
+curlicue/DSMG
+curliness/M
+curling/M
+curly/RPT
+curmudgeon/MYS
+currant/MS
+currency/SM
+current's
+current/FAY
+currents
+curricula
+curricular
+curriculum/M
+curry/DSMG
+currycomb/SGMD
+curse/DSMGV
+cursed/Y
+cursive's
+cursive/EAY
+cursor/SM
+cursorily
+cursoriness/M
+cursory/P
+curt/RYTP
+curtail/GDSL
+curtailment/SM
+curtain/GMDS
+curtness/M
+curtsy/GDSM
+curvaceous/P
+curvaceousness/M
+curvature/SM
+curve/DSMG
+curvy/RT
+cushion/MDSG
+cushy/RT
+cusp/MS
+cuspid/SM
+cuspidor/SM
+cuss's
+cuss/FEGSD
+cussed/PY
+custard/MS
+custodial
+custodian/MS
+custodianship/M
+custody/M
+custom/SZMR
+customarily
+customary/U
+customer/M
+customhouse/SM
+customization/M
+customize/DSG
+cut/TSMR
+cutaneous
+cutaway/MS
+cutback/MS
+cute/YP
+cuteness/M
+cutesy/TR
+cutey/S
+cuticle/MS
+cutie/SM
+cutlass/MS
+cutler/SM
+cutlery/M
+cutlet/SM
+cutoff/SM
+cutout/SM
+cutter/SM
+cutthroat/SM
+cutting/MYS
+cuttlefish/MS
+cutup/SM
+cutworm/MS
+cw
+cwt
+cyan/M
+cyanide/M
+cyanobacteria
+cyberbully/SM
+cybercafe/S
+cybercaf辿/S
+cybernetic/S
+cybernetics/M
+cyberpunk/SM
+cybersex
+cyberspace/MS
+cyborg/SM
+cyclamen/MS
+cycle/ADSMG
+cyclic
+cyclical/Y
+cyclist/MS
+cyclometer/MS
+cyclone/MS
+cyclonic
+cyclopaedia/MS
+cyclopedia/MS
+cyclopes
+cyclops/M
+cyclotron/MS
+cygnet/MS
+cylinder/MS
+cylindrical
+cymbal/MS
+cymbalist/MS
+cynic/SM
+cynical/Y
+cynicism/M
+cynosure/MS
+cypress/MS
+cyst/MS
+cystic
+cystitis
+cytokines
+cytologist/SM
+cytology/M
+cytoplasm/M
+cytoplasmic
+cytosine/M
+czar/MS
+czarina/SM
+czarism
+czarist/SM
+d'Arezzo/M
+d'Estaing/M
+d/NXGJ
+dB
+dab/SM
+dabbed
+dabber/MS
+dabbing
+dabble/ZGDRS
+dabbler/M
+dace/SM
+dacha/MS
+dachshund/MS
+dactyl/MS
+dactylic/MS
+dad/SM
+dadaism/M
+dadaist/MS
+daddy/SM
+dado/SM
+dadoes
+daemon/MS
+daemonic
+daffiness/M
+daffodil/SM
+daffy/PTR
+daft/PTRY
+daftness/M
+dag/S
+dagger/MS
+dago/S
+dagoes
+daguerreotype/DSMG
+dahlia/MS
+dailiness/M
+daily/PSM
+daintily
+daintiness/M
+dainty/RSMTP
+daiquiri/MS
+dairy/GSM
+dairying/M
+dairymaid/MS
+dairyman/M
+dairymen
+dairywoman/M
+dairywomen
+dais/MS
+daisy/SM
+dale/SM
+dalliance/MS
+dallier/M
+dally/ZGDRS
+dalmatian/MS
+dam/SM
+damage/MGDS
+damageable
+damaged/U
+damages/M
+damask/MDGS
+dame/SM
+dammed
+damming
+dammit
+damn/SBGMD
+damnably
+damnation/M
+damned/T
+damp/SPXZTGMDNRY
+dampen/ZGDR
+dampener/M
+damper/M
+dampness/M
+damsel/MS
+damselfly/SM
+damson/MS
+dance/MZGDRS
+dancer/M
+dancing/M
+dandelion/SM
+dander/M
+dandify/GDS
+dandle/GDS
+dandruff/M
+dandy/TRSM
+dang/SZGDR
+danger/M
+dangerous/Y
+dangle/ZGDRS
+dangler/M
+danish/MS
+dank/PTRY
+dankness/M
+danseuse/MS
+dapper/TR
+dapple/MGDS
+dare/DRSMZG
+daredevil/MS
+daredevilry/M
+darer/M
+daresay
+daring/MY
+dark/PXTMNRY
+darken/ZGDR
+darkener/M
+darkie/S
+darkness/M
+darkroom/MS
+darling/MS
+darn/SZGMDR
+darned/TR
+darner/M
+dart/SZGMDR
+dartboard/MS
+darter/M
+dash/ZGMDRS
+dashboard/SM
+dasher/M
+dashiki/MS
+dashing/Y
+dastard/MYS
+dastardliness/M
+data
+database/SM
+dataset/MS
+datatype
+date/DRSMZGV
+datebook/S
+dated/U
+dateless
+dateline/MGDS
+dater/M
+dateset
+dative/MS
+datum/M
+daub/SZGMDR
+dauber/M
+daughter/SMY
+daunt/GDS
+daunting/Y
+dauntless/YP
+dauntlessness/M
+dauphin/MS
+davenport/MS
+davit/MS
+dawdle/ZGDRS
+dawdler/M
+dawn/SGMD
+day/SM
+daybed/MS
+daybreak/M
+daycare/M
+daydream/MDRZGS
+daydreamer/M
+daylight/MS
+daylights/M
+daylong
+daytime/M
+daze/DSMG
+dazed/Y
+dazzle/MZGDRS
+dazzler/M
+dazzling/Y
+db
+dbl
+dc
+dd/SDG
+dded/K
+dding/K
+deacon/MS
+deaconess/MS
+dead/XTMNRY
+deadbeat/MS
+deadbolt/SM
+deaden/GD
+deadhead/SDG
+deadline/SM
+deadliness/M
+deadlock/GSMD
+deadly/TPR
+deadpan/MS
+deadpanned
+deadpanning
+deadwood/M
+deaf/PXTNR
+deafen/GD
+deafening/Y
+deafness/M
+deal/SJZGMR
+dealer/M
+dealership/SM
+dealing/M
+dealt
+dean/M
+deanery/SM
+deanship/M
+dear/SPTMRYH
+dearest/S
+dearie/M
+dearness/M
+dearth/M
+dearths
+deary/SM
+death/MY
+deathbed/SM
+deathblow/MS
+deathless/Y
+deathlike
+deaths
+deathtrap/MS
+deathwatch/MS
+deaves
+deb/SM
+debacle/MS
+debarkation/M
+debarment/M
+debate/BMZR
+debater/M
+debating/M
+debauch/MDSG
+debauchee/MS
+debauchery/SM
+debenture/MS
+debilitate/DSGN
+debilitation/M
+debility/SM
+debit/D
+debonair/PY
+debonairness/M
+debouch/GDS
+debridement
+debris/M
+debt/SM
+debtor/MS
+debugger/S
+debut/GMD
+debutante/SM
+decade/MS
+decadence/M
+decadency/M
+decadent/MYS
+decaf/MS
+decaffeinate/DSG
+decagon/MS
+decal/MS
+decampment/M
+decapitate/XGNDS
+decapitator/MS
+decathlete/S
+decathlon/SM
+decay/GD
+deceased/M
+decedent/MS
+deceit/MS
+deceitful/YP
+deceitfulness/M
+deceive/UGDS
+deceiver/MS
+deceiving/Y
+decelerate/GNDS
+deceleration/M
+decelerator/SM
+decency/ISM
+decennial/SM
+decent/IY
+deception/MS
+deceptive/YP
+deceptiveness/M
+decibel/MS
+decidable/U
+decide/BZGDRS
+decided/Y
+deciduous
+deciliter/MS
+decimal/SM
+decimalization
+decimate/DSGN
+decimation/M
+decimeter/MS
+decipherable/UI
+decision/IM
+decisions
+decisive/IPY
+decisiveness/IM
+deck/SGMD
+deckchair/S
+deckhand/SM
+deckle/S
+declamation/MS
+declamatory
+declaration/MS
+declarative
+declaratory
+declare/DRSZGB
+declared/U
+declarer/M
+declension/SM
+declination/M
+decline/DRSMZG
+decliner/M
+declivity/SM
+decoherence
+decolletage/SM
+decollete
+decongestant/MS
+deconstructionism
+decor/MS
+decorate/AGNVDS
+decorating/M
+decoration/AM
+decorations
+decorative/Y
+decorator/MS
+decorous/IY
+decorousness/M
+decorum/M
+decoupage/DSMG
+decoy/GMDS
+decreasing/Y
+decree/MDS
+decreeing
+decrement/GDS
+decrepit
+decrepitude/M
+decriminalization/M
+decry/GDS
+decryption
+dedicate/AGDS
+dedication/SM
+dedicator/SM
+dedicatory
+deduce/GDS
+deducible
+deduct/GVD
+deductible/SM
+deduction/SM
+deductive/Y
+deed/GD
+deejay/MS
+deem/ASGD
+deep/SPXTMNRY
+deepen/GD
+deepfake/SM
+deepness/M
+deer/M
+deerskin/M
+deerstalker/S
+def/Z
+defacement/M
+defacer/SM
+defalcate/DSXGN
+defalcation/M
+defamation/M
+defamatory
+defame/ZGDRS
+defamer/M
+defaulter/SM
+defeat/MDRZGS
+defeated/U
+defeater/M
+defeatism/M
+defeatist/MS
+defecate/GNDS
+defecation/M
+defect/MDGVS
+defection/MS
+defective/MPYS
+defectiveness/M
+defector/MS
+defendant/SM
+defended/U
+defenestration/S
+defense/DSMGV
+defenseless/YP
+defenselessness/M
+defensible/I
+defensibly/I
+defensive/MYP
+defensiveness/M
+deference/M
+deferential/Y
+deferral/MS
+deferred
+deferring
+deffer
+deffest
+defiant/Y
+defibrillation
+defibrillator/S
+deficiency/SM
+deficient
+deficit/SM
+defilement/M
+definable/IU
+define/AGDS
+defined/U
+definer/MS
+definite/IYVP
+definiteness/IM
+definition/AM
+definitions
+definitive/Y
+deflate/GNDS
+deflation/M
+deflationary
+deflect/DGVS
+deflection/MS
+deflector/SM
+defogger/SM
+defoliant/SM
+defoliate/DSGN
+defoliation/M
+defoliator/MS
+deformity/SM
+defraud/DRZGS
+defrauder/M
+defrayal/M
+defrock/DG
+defroster/MS
+deft/PTRY
+deftness/M
+defunct
+defy/GDS
+deg
+degeneracy/M
+degenerate/MV
+degrade/B
+degree/MS
+dehydrator/SM
+dehydrogenase
+deicer/MS
+deification/M
+deify/NGDS
+deign/GDS
+deist/MS
+deistic
+deity/SM
+deject/GDS
+dejected/Y
+dejection/M
+delay/ZDR
+delectable
+delectably
+delectation/M
+delegate/GD
+delete/XGNDS
+deleterious
+deletion/M
+delft/M
+delftware/M
+deli/SM
+deliberate/XYVP
+deliberateness/M
+delicacy/ISM
+delicate/IY
+delicateness/M
+delicatessen/SM
+delicious/PY
+deliciousness/M
+delighted/Y
+delightful/Y
+deliminator
+delineate/GNXDS
+delineation/M
+delinquency/SM
+delinquent/SMY
+deliquesce/DSG
+deliquescent
+delirious/YP
+deliriousness/M
+delirium/SM
+deliver/ADGS
+deliverable/S
+deliverance/M
+delivered/U
+deliverer/SM
+dell/SM
+delphinium/MS
+delta/MS
+delude/GDS
+deluge/MGDS
+delusion/MS
+delusional
+delusive/Y
+deluxe
+delve/ZGDRS
+delver/M
+demagogic
+demagogically
+demagogue/SM
+demagoguery/M
+demagogy/M
+demand/GMDS
+demanding/U
+demarcate/DSGNX
+demarcation/M
+demean/GDS
+demeanor/M
+demented/Y
+dementia/M
+demesne/MS
+demigod/MS
+demigoddess/MS
+demijohn/SM
+demimondaine/SM
+demimonde/M
+demise/MGDS
+demitasse/MS
+demo/GMD
+democracy/SM
+democrat/MS
+democratic/U
+democratically
+democratization/M
+democratize/GDS
+demode
+demographer/SM
+demographic/SM
+demographically
+demographics/M
+demography/M
+demolish/DSG
+demolition/MS
+demon/MS
+demonetization/M
+demoniac
+demoniacal/Y
+demonic
+demonically
+demonize/GDS
+demonology/SM
+demonstrability
+demonstrable/I
+demonstrably
+demonstrate/XGNVDS
+demonstration/M
+demonstrative/MYSP
+demonstrativeness/M
+demonstrator/MS
+demote/GD
+demotic
+demount
+demulcent/SM
+demur/TMRS
+demure/PY
+demureness/M
+demurral/SM
+demurred
+demurrer/SM
+demurring
+den/M
+denationalization
+denaturation
+denature/DG
+dendrite/SM
+dengue/M
+deniability
+deniable/U
+denial/MS
+denier/M
+denigrate/DSGN
+denigration/M
+denim/MS
+denitrification
+denizen/MS
+denominational
+denotative
+denouement/MS
+denounce/LDSG
+denouncement/SM
+dense/PYTR
+denseness/M
+density/SM
+dent/ISGMD
+dental/Y
+dentifrice/SM
+dentin/M
+dentine/M
+dentist/MS
+dentistry/M
+dentition/M
+denture/IMS
+denuclearize/GDS
+denudation/M
+denude/GDS
+denunciation/SM
+deny/ZGDRS
+deodorant/SM
+deodorization/M
+deodorize/DRSZG
+deodorizer/M
+departed/M
+department/MS
+departmental/Y
+departmentalization/M
+departmentalize/GDS
+departure/SM
+dependability/M
+dependable/U
+dependably
+dependence/IM
+dependency/SM
+dependent/IMYS
+depict/GDS
+depiction/MS
+depilatory/SM
+deplete/GNDS
+depletion/M
+deplorably
+deplore/BGDS
+deploy/ALGDS
+deployment/AM
+deployments
+deponent/MS
+deportation/MS
+deportee/MS
+deportment/M
+deposit/AGMDS
+depositor/MS
+depository/SM
+deprave/GDS
+depravity/SM
+deprecate/GNDS
+deprecating/Y
+deprecation/M
+deprecatory
+depreciate/DSGN
+depreciation/M
+depredation/SM
+depressant/SM
+depressing/Y
+depression/SM
+depressive/SM
+depressor/MS
+depressurization
+deprive/GDS
+deprogramming
+depth/M
+depths
+deputation/MS
+depute/DSG
+deputize/DSG
+deputy/SM
+derailleur/SM
+derailment/SM
+derangement/M
+derby/SM
+derelict/MS
+dereliction/M
+deride/GDS
+derision/M
+derisive/PY
+derisiveness/M
+derisory
+derivation/MS
+derivative/MS
+derive/B
+dermal
+dermatitis/M
+dermatological
+dermatologist/SM
+dermatology/M
+dermis/M
+derogate/DSGN
+derogation/M
+derogatorily
+derogatory
+derrick/SM
+derriere/SM
+derringer/SM
+derri竪re/SM
+derv
+dervish/MS
+desalinate/GNDS
+desalination/M
+desalinization/M
+desalinize/GDS
+descant/M
+descend/FGDS
+descendant/MS
+descender
+describable/I
+describe/BZGDR
+describer/M
+description/SM
+descriptive/PY
+descriptiveness/M
+descriptor/S
+descry/GDS
+desecrate/DSGN
+desecration/M
+deselection
+desert/SDRZGM
+deserter/M
+desertification
+desertion/SM
+deserved/UY
+deserving/U
+deshabille/M
+desiccant/SM
+desiccate/DSGN
+desiccation/M
+desiccator/SM
+desiderata
+desideratum/M
+design/ASDG
+designate/DSGNX
+designation/M
+desirability/UM
+desirableness/M
+desirably/U
+desire/B
+desired/U
+desirous
+desist/SDG
+desk/SM
+deskill/G
+desktop/SM
+desolate/PDSYGN
+desolateness/M
+desolation/M
+despair/SMDG
+despairing/Y
+desperado/M
+desperadoes
+desperate/YNP
+desperateness/M
+desperation/M
+despicable
+despicably
+despise/DSG
+despite
+despoilment/M
+despondence/M
+despondency/M
+despondent/Y
+despotic
+despotically
+despotism/M
+dessert/SM
+dessertspoon/S
+dessertspoonful/S
+destination/SM
+destine/DSG
+destiny/SM
+destitute/N
+destitution/M
+destroy/SZGDR
+destroyer/M
+destruct/GVMDS
+destructibility/IM
+destructible/I
+destruction/M
+destructive/PY
+destructiveness/M
+desuetude/M
+desultorily
+desultory
+detach/BLGDS
+detachment/MS
+detain/LGDS
+detainee/MS
+detainment/M
+detect/SDGVB
+detectable/U
+detected/U
+detection/M
+detective/SM
+detector/SM
+detente/SMNX
+detention/M
+deter/SL
+detergent/SM
+deteriorate/DSGN
+deterioration/M
+determent/M
+determinable/I
+determinant/SM
+determinate
+determine/AGDS
+determined/U
+determinedly
+determiner/SM
+determinism/M
+deterministic
+deterministically
+deterred/U
+deterrence/M
+deterrent/MS
+deterring
+detestably
+detestation/M
+dethrone/DSLG
+dethronement/M
+detonate/GNDSX
+detonation/M
+detonator/SM
+detox/MDSG
+detoxification/M
+detoxify/DSGN
+detract/GD
+detriment/SM
+detrimental/Y
+detritus/M
+deuce/SM
+deuterium/M
+devastate/GNDS
+devastating/Y
+devastation/M
+devastator/MS
+develop/ASGDL
+developed/U
+developer/SM
+development/ASM
+developmental/Y
+deviance/M
+deviancy/M
+deviant/SM
+deviate/DSMGNX
+deviating/U
+deviation/M
+devil/SMDGL
+devilish/YP
+devilishness/M
+devilment/M
+devilry/SM
+deviltry/SM
+devious/YP
+deviousness/M
+devoid
+devolution/M
+devolve/DSG
+devoted/Y
+devotee/SM
+devotion/MS
+devotional/SM
+devour/SDG
+devout/PRYT
+devoutness/M
+dew/M
+dewberry/SM
+dewclaw/SM
+dewdrop/SM
+dewiness/M
+dewlap/SM
+dewy/RTP
+dexterity/M
+dexterous/YP
+dexterousness/M
+dextrose/M
+dharma
+dhoti/SM
+dhow/MS
+diabetes/M
+diabetic/SM
+diabolic
+diabolical/Y
+diacritic/MS
+diacritical
+diadem/SM
+diaereses
+diaeresis/M
+diagnose/DSG
+diagnosis/M
+diagnostic/S
+diagnostically
+diagnostician/SM
+diagnostics/M
+diagonal/SMY
+diagram/SM
+diagrammatic
+diagrammatically
+diagrammed
+diagramming
+dial/AMDGS
+dialect/SM
+dialectal
+dialectic/SM
+dialectical
+dialectics/M
+dialing/S
+dialog
+dialogue/SM
+dialyses
+dialysis/M
+dialyzes
+diam
+diamagnetic
+diamagnetism
+diamante
+diamant辿
+diameter/SM
+diametric
+diametrical/Y
+diamond/SM
+diamondback/MS
+diapason/SM
+diaper/SMDG
+diaphanous
+diaphragm/SM
+diaphragmatic
+diarist/SM
+diarrhea/M
+diary/SM
+diaspora/SM
+diastase/M
+diastole/M
+diastolic
+diathermy/M
+diatom/SM
+diatomic
+diatonic
+diatribe/SM
+diazepam
+dibble/DSMG
+dibs/M
+dice/GDS
+dices/I
+dicey
+dichotomous
+dichotomy/SM
+dicier
+diciest
+dick/MRXZS
+dicker/DG
+dickey/SM
+dickhead/S
+dicky/SM
+dickybird/S
+dicotyledon/MS
+dicotyledonous
+dict
+dicta
+dictate/DSMGNX
+dictation/M
+dictator/SM
+dictatorial/Y
+dictatorship/SM
+diction/M
+dictionary/SM
+dictum/M
+did/AU
+didactic
+didactically
+diddle/DRSZG
+diddler/M
+diddly
+diddlysquat
+diddums
+didgeridoo/S
+didn't
+dido/MS
+didoes
+didst
+die/DSM
+diehard/SM
+dielectric/MS
+diereses
+dieresis/M
+diesel/SMDG
+diet/MDRZGS
+dietary/SM
+dieter/M
+dietetic/S
+dietetics/M
+dietician/MS
+dietitian/MS
+diff/DRZGS
+differ/DG
+difference/IM
+differences
+different/IY
+differentiable
+differential/SM
+differentiate/DSGN
+differentiated/U
+differentiation/M
+difficult/Y
+difficulty/SM
+diffidence/M
+diffident/Y
+diffract/GSD
+diffraction/M
+diffuse/DSYGNVP
+diffuseness/M
+diffusion/M
+diffusivity
+dig/SM
+digerati/M
+digest/SMDGV
+digested/U
+digestibility/M
+digestible/I
+digestion/IM
+digestions
+digestive/S
+digger/SM
+digging/S
+diggings/M
+digicam/S
+digit/SM
+digital/Y
+digitalis/M
+digitization
+digitize/GDS
+dignified/U
+dignify/DSG
+dignitary/SM
+dignity/ISM
+digraph/M
+digraphs
+digress/GVDS
+digression/MS
+dike/MGDS
+diktat/S
+dilapidated
+dilapidation/M
+dilatation/M
+dilate/DSGN
+dilation/M
+dilator/SM
+dilatory
+dildo/S
+dilemma/MS
+dilettante/SM
+dilettantish
+dilettantism/M
+diligence/M
+diligent/Y
+dill/MS
+dilly/SM
+dillydally/DSG
+diluent
+dilute/DSGNX
+diluted/U
+dilution/M
+dim/PSRY
+dime/MS
+dimension/SM
+dimensional
+dimensionless
+diminish/GDS
+diminished/U
+diminuendo/SM
+diminuendoes
+diminution/SM
+diminutive/SM
+dimity/M
+dimmed/U
+dimmer/SM
+dimmest
+dimming
+dimness/M
+dimple/DSMG
+dimply
+dimwit/SM
+dimwitted
+din/ZGSMDR
+dinar/SM
+dine/S
+diner/M
+dinette/MS
+ding/MDG
+dingbat/MS
+dingdong/SGMD
+dinghy/SM
+dingily
+dinginess/M
+dingle/SM
+dingo/M
+dingoes
+dingus/MS
+dingy/RPT
+dink/R
+dinky/RSMT
+dinned
+dinner/SMDG
+dinnertime/M
+dinnerware/M
+dinning
+dinosaur/SM
+dint/M
+diocesan/MS
+diocese/MS
+diode/SM
+diorama/SM
+dioxide/SM
+dioxin/SM
+dip/SM
+diphtheria/M
+diphthong/SM
+diploid/SM
+diploma/SM
+diplomacy/M
+diplomat/MS
+diplomata
+diplomatic/U
+diplomatically
+diplomatist/MS
+diplopia
+dipole/SM
+dipped
+dipper/SM
+dipping
+dippy/RT
+dipso/S
+dipsomania/M
+dipsomaniac/MS
+dipstick/SM
+dipterous
+diptych/M
+diptychs
+dire/YTR
+direct/ASDGVT
+directer
+direction/IM
+directional
+directionless
+directions
+directive/SM
+directly
+directness/IM
+director/MS
+directorate/SM
+directorial
+directorship/SM
+directory/SM
+direful
+dirge/SM
+dirigible/MS
+dirk/MS
+dirndl/SM
+dirt/M
+dirtball/S
+dirtily
+dirtiness/M
+dirty/DRSTGP
+dis/M
+disable/DSGL
+disablement/M
+disambiguate/N
+disappointing/Y
+disarming/Y
+disassembly
+disastrous/Y
+disbandment/M
+disbarment/M
+disbelieving/Y
+disbursal/M
+disburse/DSGL
+disbursement/MS
+disc/M
+discern/LSDG
+discernible/I
+discernibly
+discerning/Y
+discernment/M
+discharged/U
+disciple/SM
+discipleship/M
+disciplinarian/SM
+disciplinary
+discipline/DSMG
+disciplined/U
+disclose/DSG
+disclosed/U
+disco/MG
+discography/SM
+discoloration/S
+discombobulate/DSGN
+discombobulation/M
+discomfit/DG
+discomfiture/M
+discommode/DG
+disconcerting/Y
+disconnected/PY
+disconnectedness/M
+disconsolate/Y
+discordance/M
+discordant/Y
+discotheque/SM
+discourage/LGDS
+discouragement/SM
+discouraging/Y
+discover/ASDG
+discovered/U
+discoverer/MS
+discovery/ASM
+discreet/PRYT
+discreetness/M
+discrepancy/SM
+discrepant
+discrete/PYN
+discreteness/M
+discretion/IM
+discretionary
+discriminant
+discriminate/GNDS
+discriminating/U
+discrimination/M
+discriminator/MS
+discriminatory
+discursiveness/M
+discus/MS
+discussant/SM
+discussion/SM
+disdain/SMDG
+disdainful/Y
+disembowel/SDLG
+disembowelment/M
+disfigurement/SM
+disfranchisement/M
+disgorgement/M
+disgruntle/LGDS
+disgruntlement/M
+disguise/GD
+disguised/U
+disgusted/Y
+disgusting/Y
+dish/MDSG
+dishabille/M
+disharmonious
+dishcloth/M
+dishcloths
+disheartening/Y
+dishevel/DGLS
+dishevelment/M
+dishpan/SM
+dishrag/SM
+dishtowel/MS
+dishware/M
+dishwasher/MS
+dishwater/M
+dishy
+disillusion/GLD
+disillusionment/M
+disinfectant/MS
+disinfection/M
+disinterested/PY
+disinterestedness/M
+disjointed/YP
+disjointedness/M
+disjunctive
+disjuncture
+disk/MS
+diskette/MS
+dislodge/GDS
+dismal/Y
+dismantlement/M
+dismay/SMDG
+dismayed/U
+dismember/LGD
+dismemberment/M
+dismissive/Y
+disorder/Y
+disorganization/M
+disparage/DSGL
+disparagement/M
+disparaging/Y
+disparate/Y
+dispatcher/MS
+dispel/S
+dispelled
+dispelling
+dispensary/SM
+dispensation/MS
+dispense/BZGDRS
+dispenser/M
+dispersal/M
+disperse/GNDS
+dispersion/M
+dispirit/GDS
+displeasure/M
+disposable/SM
+disposal/SM
+disposed/I
+disposition/ISM
+dispossession/M
+disproof/SM
+disproportional
+disprove/B
+disputable/I
+disputably/I
+disputant/MS
+disputation/SM
+disputatious/Y
+dispute/DRSMZGB
+disputed/U
+disputer/M
+disquiet/GSMD
+disquisition/MS
+disregardful
+disrepair/M
+disrepute/MB
+disrupt/GVSD
+disruption/SM
+disruptive/Y
+dissect/SDG
+dissed
+dissemblance/M
+dissemble/ZGDRS
+dissembler/M
+disseminate/GNDS
+dissemination/M
+dissension/SM
+dissent/SMDRZG
+dissenter/M
+dissertation/SM
+disses
+dissidence/M
+dissident/MS
+dissimilar
+dissimilitude/S
+dissing
+dissipate/GNDS
+dissipation/M
+dissociate/GNVDS
+dissociation/M
+dissoluble/I
+dissolute/YNP
+dissoluteness/M
+dissolve/AGDS
+dissolved/U
+dissonance/SM
+dissonant
+dissuade/GDS
+dissuasive
+dist
+distaff/SM
+distal/Y
+distance/DSMG
+distant/Y
+distaste/SM
+distemper/M
+distention/SM
+distillate/SMNX
+distillation/M
+distillery/SM
+distinct/IYTVP
+distincter
+distinction/SM
+distinctive/YP
+distinctiveness/M
+distinctness/IM
+distinguish/GDSB
+distinguishable/I
+distinguished/U
+distort/GDR
+distortion/MS
+distract/DG
+distracted/Y
+distraction/S
+distrait
+distraught
+distress/DG
+distressful
+distressing/Y
+distribute/AGNVDS
+distributed/U
+distribution/AM
+distributional
+distributions
+distributive/Y
+distributor's
+distributor/AS
+distributorship/S
+district's
+district/AS
+disturb/ZGSDR
+disturbance/SM
+disturbed/U
+disturber/M
+disturbing/Y
+disunion/M
+disyllabic
+ditch/MDSG
+dither/SMDRZG
+ditherer/M
+ditransitive
+ditsy
+ditto/SMDG
+dittoes
+ditty/SM
+ditz/MS
+ditzy/R
+diuretic/MS
+diurnal/Y
+div
+diva/MS
+divalent
+divan/SM
+dive/MZTGDRS
+diver/M
+diverge/DSG
+divergence/MS
+divergent
+diverse/XYNP
+diverseness/M
+diversification/M
+diversify/GNDS
+diversion/M
+diversionary
+diversity/SM
+divert/SDG
+diverticulitis/M
+divest/SLDG
+divestiture/MS
+divestment/M
+divide/DRSMZGB
+divided/U
+dividend/MS
+divider/M
+divination/M
+divine/DRSMYZTG
+diviner/M
+diving/M
+divinity/SM
+divisibility/IM
+divisible/I
+division/MS
+divisional
+divisive/PY
+divisiveness/M
+divisor/SM
+divorce/DSLMG
+divorcee/MS
+divorcement/MS
+divorc辿e/MS
+divot/SM
+divulge/GDS
+divvy/DSMG
+dixieland/M
+dizzily
+dizziness/M
+dizzy/DRSPTG
+djellaba/MS
+djellabahs
+do/SJMRHZG
+doable
+dob/S
+dobbed
+dobbin/SM
+dobbing
+doberman/MS
+dobro
+doc/SM
+docent/SM
+docile/Y
+docility/M
+dock/MDRZGS
+docket/SMDG
+dockland/S
+dockside
+dockworker/MS
+dockyard/MS
+doctor/SMDG
+doctoral
+doctorate/MS
+doctrinaire/MS
+doctrinal
+doctrine/MS
+docudrama/SM
+document/GMDS
+documentary/SM
+documentation/SM
+documented/U
+dodder/SMDG
+doddery
+doddle
+dodge/DRSMZG
+dodgem/S
+dodger/M
+dodgy/RT
+dodo/MS
+doe/SM
+doer/M
+does/AU
+doeskin/MS
+doesn't
+doff/DGS
+dog/SM
+dogcart/SM
+dogcatcher/SM
+doge/MS
+dogear/SMDG
+dogfight/SM
+dogfish/MS
+dogged/PY
+doggedness/M
+doggerel/M
+doggie/M
+dogging
+doggone/TGDRS
+doggoned/TR
+doggy/RSMT
+doghouse/SM
+dogie/SM
+dogleg/SM
+doglegged
+doglegging
+doglike
+dogma/SM
+dogmatic
+dogmatically
+dogmatism/M
+dogmatist/SM
+dognapper
+dogsbody/S
+dogsled/S
+dogtrot/MS
+dogtrotted
+dogtrotting
+dogwood/MS
+doh/M
+doily/SM
+doing/USM
+doldrums/M
+dole's
+dole/FGDS
+doleful/YP
+dolefulness/M
+doll/MDGS
+dollar/SM
+dollhouse/SM
+dollop/SGMD
+dolly/SM
+dolmen/SM
+dolomite/M
+dolor/M
+dolorous/Y
+dolphin/MS
+dolt/MS
+doltish/YP
+doltishness/M
+domain/SM
+dome/MGDS
+domestic/SM
+domestically
+domesticate/DSGN
+domesticated/U
+domestication/M
+domesticity/M
+domicile/DSMG
+domiciliary
+dominance/M
+dominant/SMY
+dominate/DSGN
+domination/M
+dominatrices
+dominatrix/M
+domineer/SGD
+domineering/Y
+dominion/SM
+domino/M
+dominoes
+don't
+don/SM
+dona/MS
+donate/DSXGN
+donation/M
+done/FAU
+dong/MDGS
+dongle/SM
+donkey/SM
+donned
+donning
+donnish
+donnybrook/MS
+donor/SM
+donuts
+doodad/SM
+doodah
+doodahs
+doodle/DRSMZG
+doodlebug/SM
+doodler/M
+doohickey/SM
+doolally
+doom/MDGS
+doomsayer/MS
+doomsday/M
+doomster/S
+door's
+door/IS
+doorbell/MS
+doorjamb/S
+doorkeeper/MS
+doorknob/MS
+doorknocker/S
+doorman/M
+doormat/SM
+doormen
+doorplate/SM
+doorpost/S
+doorstep/MS
+doorstepped
+doorstepping
+doorstop/MS
+doorway/SM
+dooryard/MS
+dopa/M
+dopamine
+dope/MZGDRS
+doper/M
+dopey
+dopier
+dopiest
+dopiness/M
+doping/M
+doppelganger/S
+doppelg辰nger/S
+dork/MS
+dorky/RT
+dorm/MRZS
+dormancy/M
+dormant
+dormer/M
+dormice
+dormitory/SM
+dormouse/M
+dorsal/Y
+dory/SM
+dosage/SM
+dose/MGDS
+dosh
+dosimeter/SM
+doss/DRSZG
+dosshouse/S
+dossier/MS
+dost
+dot/ZGSMDR
+dotage/M
+dotard/SM
+dotcom/SM
+dote/S
+doter/M
+doting/Y
+dotted
+dotting
+dotty/RT
+double's
+double/ADSG
+doubleheader/MS
+doublespeak/M
+doublet/MS
+doubloon/SM
+doubly
+doubt/SMDRZG
+doubter/M
+doubtful/PY
+doubtfulness/M
+doubting/Y
+doubtless/Y
+douche/DSMG
+dough/M
+doughnut/SM
+doughty/RT
+doughy/TR
+dour/RYTP
+dourness/M
+douse/DSG
+dove/MS
+dovecot/S
+dovecote/SM
+dovetail/MDSG
+dovish
+dowager/MS
+dowdily
+dowdiness/M
+dowdy/RSPT
+dowel/SMDG
+dower/SMDG
+down/MDRZGS
+downbeat/SM
+downcast
+downdraft/MS
+downer/M
+downfall/SMN
+downfield
+downgrade/DSMG
+downhearted/PY
+downheartedness/M
+downhill/MS
+download/MDBSG
+downmarket
+downplay/DSG
+downpour/MS
+downrange
+downright
+downriver
+downscale
+downshift/SGD
+downside/MS
+downsize/GDS
+downsizing/M
+downspout/MS
+downstage
+downstairs/M
+downstate/M
+downstream
+downswing/MS
+downtempo
+downtime/M
+downtown/M
+downtrend/MS
+downtrodden
+downturn/MS
+downward/S
+downwind
+downy/RT
+dowry/SM
+dowse/DRSZG
+dowser/M
+doxology/SM
+doyen/SM
+doyenne/MS
+doz/XGDNS
+doze/M
+dozen/MH
+dozily
+dozy/RTP
+dpi
+dpt
+drab/MYSP
+drabber
+drabbest
+drabness/M
+drachma/MS
+draconian
+draft's
+draft/ASDG
+draftee/SM
+drafter/SM
+draftily
+draftiness/M
+drafting/M
+draftsman/M
+draftsmanship/M
+draftsmen
+draftswoman/M
+draftswomen
+drafty/RTP
+drag/MS
+dragged
+dragging
+draggy/TR
+dragnet/SM
+dragon/SM
+dragonfly/SM
+dragoon/SMDG
+dragster/S
+drain/SMDRZG
+drainage/M
+drainboard/SM
+drainer/M
+drainpipe/MS
+drake/SM
+dram/MS
+drama/SM
+dramatic/S
+dramatically
+dramatics/M
+dramatist/SM
+dramatization/SM
+dramatize/DSG
+drank
+drape/DRSMZG
+draper/M
+drapery/SM
+drastic
+drastically
+drat
+dratted
+draughtboard/S
+draw/MRZGSJ
+drawback/MS
+drawbridge/MS
+drawer/M
+drawing/M
+drawl/SMDG
+drawn/A
+drawstring/MS
+dray/MS
+dread/SMDG
+dreadful/PY
+dreadfulness/M
+dreadlocks/M
+dreadnought/MS
+dream/SMDRZG
+dreamboat/MS
+dreamed/U
+dreamer/M
+dreamily
+dreaminess/M
+dreamland/M
+dreamless
+dreamlike
+dreamworld/SM
+dreamy/RPT
+drear
+drearily
+dreariness/M
+dreary/RPT
+dredge/DRSMZG
+dredger/M
+dregs/M
+drench/GDS
+dress/AUGSDM
+dressage/M
+dresser/MS
+dressiness/M
+dressing/SM
+dressmaker/SM
+dressmaking/M
+dressy/TPR
+drew/A
+dribble/MZGDRS
+dribbler/M
+driblet/MS
+drier/M
+drift/SMDRZG
+drifter/M
+driftnet/S
+driftwood/M
+drill/SMDRZG
+driller/M
+drillmaster/SM
+drily
+drink/SMRBJZG
+drinkable/U
+drinker/M
+drip/MS
+dripped
+dripping/SM
+drippy/TR
+drive/RSMZGJ
+drivel/SZGMDR
+driveler/M
+driven
+driver/M
+driveshaft/SM
+driveway/MS
+drizzle/MGDS
+drizzly
+drogue/SM
+droid/S
+droll/RPT
+drollery/SM
+drollness/M
+drolly
+dromedary/SM
+drone/DSMG
+drool/SMDG
+droop/GSMD
+droopiness/M
+droopy/TPR
+drop/MS
+dropkick/MS
+droplet/SM
+dropout/SM
+dropped
+dropper/SM
+dropping/S
+droppings/M
+dropsical
+dropsy/M
+dross/M
+drought/SM
+drove/RSMZ
+drover/M
+drown/GSJD
+drowning/M
+drowse/MGDS
+drowsily
+drowsiness/M
+drowsy/RTP
+drub/S
+drubbed
+drubber/SM
+drubbing/MS
+drudge/MGDS
+drudgery/M
+drug/MS
+drugged
+druggie/SM
+drugging
+druggist/SM
+druggy
+drugstore/MS
+druid/SM
+druidism/M
+drum/MS
+drumbeat/SM
+drumlin/SM
+drummed
+drummer/SM
+drumming
+drumstick/SM
+drunk/STMNR
+drunkard/MS
+drunken/PY
+drunkenness/M
+drupe/SM
+druthers/M
+dry/ZTGDRSMY
+dryad/SM
+dryer/SM
+dryness/M
+drys
+drywall/M
+dual
+dualism/M
+duality/M
+dub/SM
+dubbed
+dubber/SM
+dubbin/M
+dubbing
+dubiety/M
+dubious/YP
+dubiousness/M
+ducal
+ducat/SM
+duchess/MS
+duchy/SM
+duck/MDGS
+duckbill/SM
+duckboards
+duckling/SM
+duckpins/M
+duckweed/M
+ducky/TRSM
+duct's/K
+duct/CKIFS
+ductile
+ductility/M
+ducting
+ductless
+dud/GSMD
+dude/MS
+dudgeon/M
+due's
+due/IS
+duel/MDRJZGS
+dueler/M
+duelist/SM
+duenna/MS
+duet/MS
+duff/MDRZGS
+duffer/M
+dug
+dugout/MS
+duh
+duke/MS
+dukedom/SM
+dulcet
+dulcimer/MS
+dull/DRPTGS
+dullard/SM
+dullness/M
+dully
+duly/U
+dumb/RYPT
+dumbbell/SM
+dumbfound/SDG
+dumbness/M
+dumbo/S
+dumbstruck
+dumbwaiter/SM
+dumdum/MS
+dummy/SM
+dump/MDRZGS
+dumpiness/M
+dumpling/SM
+dumpsite/S
+dumpster/SM
+dumpy/PTR
+dun/SM
+dunce/SM
+dunderhead/MS
+dune/MS
+dung/MDGS
+dungaree/MS
+dungeon/SM
+dunghill/MS
+dunk/MDGS
+dunned
+dunner
+dunnest
+dunning
+dunno
+duo/SM
+duodecimal
+duodena
+duodenal
+duodenum/M
+duopoly/S
+dupe/MZGDRS
+duper/M
+duple
+duplex/MS
+duplicate's
+duplicate/AGNDS
+duplication/AM
+duplicator/MS
+duplicitous
+duplicity/M
+durability/M
+durable
+durably
+durance/M
+duration/M
+duress/M
+during
+durst
+durum/M
+dusk/M
+duskiness/M
+dusky/RTP
+dust/MDRZGS
+dustbin/SM
+dustcart/S
+duster/M
+dustiness/M
+dustless
+dustman
+dustmen
+dustpan/SM
+dustsheet/S
+dusty/RTP
+dutch
+duteous/Y
+dutiable
+dutiful/YP
+dutifulness/M
+duty/SM
+duvet/SM
+dwarf/SGMD
+dwarfish
+dwarfism/M
+dweeb/SM
+dwell/SJZGR
+dweller/M
+dwelling/M
+dwelt/I
+dwindle/DSG
+dyadic
+dybbuk/SM
+dybbukim
+dye/DRSMZG
+dyeing/A
+dyer/M
+dyestuff/M
+dying/M
+dyke/MS
+dynamic/MS
+dynamical/Y
+dynamics/M
+dynamism/M
+dynamite/MZGDRS
+dynamiter/M
+dynamo/SM
+dynastic
+dynasty/SM
+dysentery/M
+dysfunction/MS
+dysfunctional
+dyslectic/SM
+dyslexia/M
+dyslexic/SM
+dyspepsia/M
+dyspeptic/MS
+dysphagia
+dysphoria
+dysphoric
+dysprosium/M
+dystonia
+dystopi
+dystopia
+dystopian
+dz
+d辿bridement
+d辿butante/SM
+d辿colletage/SM
+d辿collet辿
+d辿mod辿
+d辿railleur/MS
+d辿shabill辿/M
+d辿tente/M
+e'en
+e'er
+e/FDST
+eBay/M
+eMusic/M
+ea
+each
+eager/PTRY
+eagerness/M
+eagle/MS
+eaglet/MS
+ear/SMDY
+earache/SM
+earbud/SM
+eardrum/SM
+earful/SM
+earl/MS
+earldom/SM
+earliness/M
+earlobe/SM
+early/RTP
+earmark/SMDG
+earmuff/SM
+earn/DRZTGJS
+earned/U
+earner/M
+earnest/SMYP
+earnestness/M
+earnings/M
+earphone/MS
+earpiece/S
+earplug/SM
+earring/SM
+earshot/M
+earsplitting
+earth's
+earth/UDYG
+earthbound
+earthen
+earthenware/M
+earthiness/M
+earthling/MS
+earthly/RT
+earthquake/SM
+earths/U
+earthshaking
+earthward/S
+earthwork/MS
+earthworm/MS
+earthy/RTP
+earwax/M
+earwig/SM
+ease/EDSM
+easel/SM
+easement/SM
+easily/U
+easiness/UM
+easing
+east/M
+eastbound
+easterly/SM
+eastern/ZR
+easterner/M
+easternmost
+eastward/S
+easy/URTP
+easygoing
+eat/ZGBSNR
+eatable/SM
+eaten/U
+eater/M
+eatery/SM
+eave/MS
+eavesdrop/S
+eavesdropped
+eavesdropper/SM
+eavesdropping
+ebb/SMDG
+ebony/SM
+ebullience/M
+ebullient/Y
+ebullition/M
+eccentric/SM
+eccentrically
+eccentricity/SM
+eccl
+ecclesial
+ecclesiastic/SM
+ecclesiastical/Y
+echelon/SM
+echidna
+echinoderm/SM
+echo's
+echo/ADG
+echoes/A
+echoic
+echolocation/M
+echos
+eclair/SM
+eclat/M
+eclectic/SM
+eclectically
+eclecticism/M
+eclipse/DSMG
+ecliptic/M
+eclogue/SM
+ecocide/M
+ecol
+ecologic
+ecological/Y
+ecologist/MS
+ecology/M
+econ
+econometric/S
+economic/S
+economical/UY
+economics/M
+economist/SM
+economize/DRSZG
+economizer/M
+economy/SM
+ecosystem/MS
+ecotourism/M
+ecotourist/MS
+ecru/M
+ecstasy/SM
+ecstatic
+ecstatically
+ecu/S
+ecumenical/Y
+ecumenicism/M
+ecumenism/M
+eczema/M
+ed/ACSM
+edamame
+eddy/DSMG
+edelweiss/M
+edema/SM
+edge/MZGJDRS
+edger/M
+edgeways
+edgewise
+edgily
+edginess/M
+edging/M
+edgy/RTP
+edibility/M
+edible/SMP
+edibleness/M
+edict/SM
+edification/M
+edifice/SM
+edifier/M
+edify/DRSZGN
+edifying/U
+edit's
+edit/ADGS
+editable
+edited/U
+edition/MS
+editor/SM
+editorial/SMY
+editorialize/DSG
+editorship/M
+educ
+educability/M
+educable/I
+educate/ADSGNV
+educated/U
+education/AM
+educational/Y
+educationalist/S
+educationist/S
+educations
+educator/MS
+educe/DSGB
+edutainment/M
+eek
+eel/SM
+eerie/RT
+eerily
+eeriness/M
+eff/GSD
+efface/DSLG
+effacement/M
+effect/SMDGV
+effective/IPY
+effectiveness/IM
+effectual/IY
+effectuate/DSG
+effeminacy/M
+effeminate/Y
+effendi/SM
+efferent
+effervesce/GDS
+effervescence/M
+effervescent/Y
+effete/YP
+effeteness/M
+efficacious/Y
+efficacy/IM
+efficiency/ISM
+efficient/IY
+effigy/SM
+efflorescence/M
+efflorescent
+effluence/M
+effluent/MS
+effluvia
+effluvium/M
+efflux
+effort/SM
+effortful
+effortless/YP
+effortlessness/M
+effrontery/M
+effulgence/M
+effulgent
+effuse/DSGNVX
+effusion/M
+effusive/YP
+effusiveness/M
+egad
+egalitarian/SM
+egalitarianism/M
+egg/GSMD
+eggbeater/MS
+eggcup/SM
+egghead/SM
+eggnog/M
+eggplant/MS
+eggshell/SM
+eglantine/SM
+ego/SM
+egocentric/MS
+egocentrically
+egocentricity/M
+egoism/M
+egoist/SM
+egoistic
+egoistical/Y
+egomania/M
+egomaniac/MS
+egotism/M
+egotist/SM
+egotistic
+egotistical/Y
+egregious/PY
+egregiousness/M
+egress/MS
+egret/SM
+eh
+eider/SM
+eiderdown/MS
+eigenvalue/S
+eigenvector/S
+eight/SM
+eighteen/MHS
+eighteenth/M
+eighteenths
+eighth/M
+eighths
+eightieth/M
+eightieths
+eighty/SMH
+einsteinium/M
+eisteddfod/S
+either
+ejaculate/GNXDS
+ejaculation/M
+ejaculatory
+eject/SDG
+ejection/MS
+ejector/SM
+eke/DSG
+elaborate/YGNDSPX
+elaborateness/M
+elaboration/M
+elan/M
+eland/SM
+elapse/DSG
+elastic/MS
+elastically
+elasticated
+elasticity/M
+elasticize/DSG
+elate/DSGN
+elated/Y
+elation/M
+elbow/SMDG
+elbowroom/M
+elder/SMY
+elderberry/SM
+eldercare/M
+eldest
+eldritch
+elect's
+elect/ASDGV
+electable
+election/AMS
+electioneer/DGS
+elective/MS
+elector/MS
+electoral/Y
+electorate/MS
+electric/S
+electrical/Y
+electrician/MS
+electricity/M
+electrification/M
+electrifier/M
+electrify/ZGNDRS
+electrocardiogram/MS
+electrocardiograph/M
+electrocardiographs
+electrocardiography/M
+electrocute/DSXGN
+electrocution/M
+electrode/SM
+electrodynamics
+electroencephalogram/MS
+electroencephalograph/M
+electroencephalographic
+electroencephalographs
+electroencephalography/M
+electrologist/SM
+electrolysis/M
+electrolyte/MS
+electrolytic
+electromagnet/MS
+electromagnetic
+electromagnetically
+electromagnetism/M
+electromotive
+electron/MS
+electronic/S
+electronica/M
+electronically
+electronics/M
+electroplate/DSG
+electroscope/SM
+electroscopic
+electroshock/M
+electrostatic/S
+electrostatics/M
+electrotype/MS
+electroweak
+eleemosynary
+elegance/IM
+elegant/IY
+elegiac/MS
+elegiacal
+elegy/SM
+elem
+element/MS
+elemental/Y
+elementary
+elephant/SM
+elephantiasis/M
+elephantine
+elev
+elevate/XDSGN
+elevation/M
+elevator/MS
+eleven/SMH
+elevens/S
+eleventh/M
+elevenths
+elf/M
+elfin
+elfish
+elicit/SDG
+elicitation/M
+elide/DSG
+eligibility/IM
+eligible
+eliminate/XDSGN
+elimination/M
+eliminator/S
+elision/MS
+elite/SM
+elitism/M
+elitist/MS
+elixir/SM
+elk/SM
+ell/SM
+ellipse/MS
+ellipsis/M
+ellipsoid/SM
+ellipsoidal
+elliptic
+elliptical/Y
+elm/SM
+elocution/M
+elocutionary
+elocutionist/SM
+elodea/SM
+elongate/DSGNX
+elongation/M
+elope/DSGL
+elopement/MS
+eloquence/M
+eloquent/Y
+else
+elsewhere
+elucidate/DSGNX
+elucidation/M
+elude/DSG
+elusive/YP
+elusiveness/M
+elver/SM
+elves
+elvish
+em's
+em/S
+emaciate/GNDS
+emaciation/M
+email/SMDG
+emanate/XDSGN
+emanation/M
+emancipate/DSGN
+emancipation/M
+emancipator/MS
+emasculate/GNDS
+emasculation/M
+embalm/SZGDR
+embalmer/M
+embank/SLGD
+embankment/SM
+embargo/MDG
+embargoes
+embark/AEGDS
+embarkation/EM
+embarkations
+embarrass/GLDS
+embarrassed/U
+embarrassing/Y
+embarrassment/SM
+embassy/SM
+embattled
+embed/S
+embedded
+embedding
+embellish/LGDS
+embellishment/SM
+ember/SM
+embezzle/ZGLDRS
+embezzlement/M
+embezzler/M
+embitter/GLDS
+embitterment/M
+emblazon/GDLS
+emblazonment/M
+emblem/SM
+emblematic
+emblematically
+embodiment/EM
+embody/AEGSD
+embolden/DGS
+embolism/MS
+embolization
+emboss/DRSZG
+embosser/M
+embouchure/M
+embower/SGD
+embrace/DSMG
+embraceable
+embrasure/MS
+embrocation/MS
+embroider/SDRZG
+embroiderer/M
+embroidery/SM
+embroil/DGLS
+embroilment/M
+embryo/SM
+embryological
+embryologist/MS
+embryology/M
+embryonic
+emcee/DSM
+emceeing
+emend/SDG
+emendation/MS
+emerald/MS
+emerge/ADSG
+emergence/AM
+emergency/SM
+emergent
+emerita
+emeritus
+emery/M
+emetic/SM
+emf/S
+emigrant/SM
+emigrate/DSXGN
+emigration/M
+emigre/SM
+eminence/MS
+eminent/Y
+emir/MS
+emirate/MS
+emissary/SM
+emission/SM
+emit/S
+emitted
+emitter/MS
+emitting
+emo/SM
+emoji/SM
+emollient/MS
+emolument/MS
+emote/XDSGNV
+emoticon/SM
+emotion/M
+emotional/UY
+emotionalism/M
+emotionalize/GDS
+emotionless
+emotive/Y
+empanel/GDS
+empathetic
+empathically
+empathize/DSG
+empathy/M
+emperor/MS
+emphases
+emphasis/M
+emphasize/AGDS
+emphatic/U
+emphatically
+emphysema/M
+empire/SM
+empiric
+empirical/Y
+empiricism/M
+empiricist/SM
+emplacement/SM
+employ's
+employ/ADGLS
+employable/U
+employee/SM
+employer/SM
+employment/UAM
+employments
+emporium/SM
+empower/SDGL
+empowerment/M
+empress/MS
+emptily
+emptiness/M
+empty/TGPDRSM
+empyrean/M
+emu/SM
+emulate/DSGNVX
+emulation/M
+emulator/SM
+emulsification/M
+emulsifier/M
+emulsify/NDRSZG
+emulsion/MS
+en/SM
+enable/DRSZG
+enabler/M
+enact/ASLDG
+enactment/ASM
+enamel/JSZGMDR
+enameler/M
+enamelware/M
+enamor/SGD
+enc
+encamp/LSGD
+encampment/MS
+encapsulate/XGNDS
+encapsulation/M
+encase/LDSG
+encasement/M
+encephalitic
+encephalitis/M
+enchain/DGS
+enchant/ELDGS
+enchanter/MS
+enchanting/Y
+enchantment/EM
+enchantments
+enchantress/MS
+enchilada/SM
+encipher/SGD
+encircle/DSGL
+encirclement/M
+encl
+enclave/MS
+enclose/GDS
+enclosed/U
+enclosure/SM
+encode/DRSZG
+encoder/M
+encomium/MS
+encompass/GDS
+encore/DSMG
+encounter/GSMD
+encourage/DSLG
+encouragement/SM
+encouraging/Y
+encroach/GLDS
+encroachment/SM
+encrust/DGS
+encrustation/SM
+encrypt/DGS
+encryption
+encumber/EGSD
+encumbered/U
+encumbrance/MS
+ency
+encyclical/SM
+encyclopedia/MS
+encyclopedic
+encyst/LSGD
+encystment/M
+end/GVSJMD
+endanger/SGDL
+endangerment/M
+endear/SGLD
+endearing/Y
+endearment/SM
+endeavor/GSMD
+endemic/MS
+endemically
+endgame/S
+ending/M
+endive/SM
+endless/PY
+endlessness/M
+endmost
+endocarditis
+endocrine/MS
+endocrinologist/MS
+endocrinology/M
+endogenous/Y
+endometrial
+endometriosis
+endometrium
+endorphin/MS
+endorse/LZGDRS
+endorsement/MS
+endorser/M
+endoscope/MS
+endoscopic
+endoscopy/M
+endothelial
+endothermic
+endotracheal
+endow/SDLG
+endowment/MS
+endpoint/SM
+endue/DSG
+endurable/U
+endurance/M
+endure/DSBG
+endways
+enema/SM
+enemy/SM
+energetic
+energetically
+energize/ZGDRS
+energizer/M
+energy/SM
+enervate/GNDS
+enervation/M
+enfeeble/GDSL
+enfeeblement/M
+enfilade/DSMG
+enfold/SGD
+enforce/LZGDRS
+enforceable/U
+enforced/U
+enforcement/M
+enforcer/M
+enfranchise/EGDSL
+enfranchisement/EM
+engage/EADSG
+engagement/EMS
+engagingly
+engender/SGD
+engine/SM
+engineer/MDGS
+engineering/M
+engorge/LGDS
+engorgement/M
+engram/SM
+engrave/ZGJDRS
+engraver/M
+engraving/M
+engross/GLDS
+engrossment/M
+engulf/SLGD
+engulfment/M
+enhance/LZGDRS
+enhancement/SM
+enigma/SM
+enigmatic
+enigmatically
+enjambment/SM
+enjoin/SGD
+enjoy/GBLSD
+enjoyably
+enjoyment/SM
+enlarge/LZGDRS
+enlargeable
+enlargement/MS
+enlarger/M
+enlighten/SGLD
+enlightened/U
+enlightenment/M
+enlist/ADGSL
+enlistee/SM
+enlistment/AM
+enlistments
+enliven/SLDG
+enlivenment/M
+enmesh/DSGL
+enmeshment/M
+enmity/SM
+ennoble/DSGL
+ennoblement/M
+ennui/M
+enormity/SM
+enormous/PY
+enormousness/M
+enough/M
+enplane/DSG
+enqueue/DS
+enquirer/S
+enquiringly
+enrage/GDS
+enrapture/DSG
+enrich/DSLG
+enrichment/M
+enroll/DLSG
+enrollment/MS
+ensconce/DSG
+ensemble/SM
+enshrine/GLDS
+enshrinement/M
+enshroud/DGS
+ensign/MS
+ensilage/M
+enslave/DSGL
+enslavement/M
+ensnare/DSLG
+ensnarement/M
+ensue/DSG
+ensure/ZGDRS
+ensurer/M
+entail/DSGL
+entailment/M
+entangle/EDSLG
+entanglement/EM
+entanglements
+entente/SM
+enter/ASGD
+enteral
+enteric
+enteritis/M
+enterprise/MGS
+enterprising/Y
+entertain/ZGDRSL
+entertainer/M
+entertaining/MY
+entertainment/MS
+enthrall/GDSL
+enthrallment/M
+enthrone/GDSL
+enthronement/SM
+enthuse/DSG
+enthusiasm/MS
+enthusiast/MS
+enthusiastic/U
+enthusiastically
+entice/GDSL
+enticement/MS
+enticing/Y
+entire/Y
+entirety/M
+entitle/DSGL
+entitlement/SM
+entity/SM
+entomb/DSGL
+entombment/M
+entomological
+entomologist/MS
+entomology/M
+entourage/SM
+entr'acte
+entrails/M
+entrained
+entrance/LDSMG
+entrancement/M
+entrancing/Y
+entrant/SM
+entrap/LS
+entrapment/M
+entrapped
+entrapping
+entreat/GSD
+entreating/Y
+entreaty/SM
+entree/MS
+entrench/DSGL
+entrenchment/MS
+entrepreneur/SM
+entrepreneurial
+entrepreneurship
+entropy/M
+entrust/SGD
+entry/ASM
+entryphone/S
+entryway/MS
+entr辿e/MS
+entwine/DSG
+enumerable
+enumerate/DSGNX
+enumeration/M
+enumerator/SM
+enunciate/DSGN
+enunciation/M
+enure/DSG
+enuresis/M
+envelop/SLDRZG
+envelope/SM
+enveloper/M
+envelopment/M
+envenom/SDG
+enviable/U
+enviably
+envious/PY
+enviousness/M
+environment/MS
+environmental/Y
+environmentalism/M
+environmentalist/SM
+environs/M
+envisage/GDS
+envision/DGS
+envoy/SM
+envy/DSMG
+envying/Y
+enzymatic
+enzyme/SM
+eolian
+eon/SM
+eosinophil/S
+eosinophilic
+epaulet/SM
+epee/MS
+ephedrine/M
+ephemera/M
+ephemeral/Y
+epic/MS
+epicenter/MS
+epicure/SM
+epicurean/MS
+epidemic/SM
+epidemically
+epidemiological
+epidemiologist/SM
+epidemiology/M
+epidermal
+epidermic
+epidermis/MS
+epidural/S
+epiglottis/MS
+epigram/SM
+epigrammatic
+epigraph/M
+epigraphs
+epigraphy/M
+epilepsy/M
+epileptic/SM
+epilogue/MS
+epinephrine/M
+epiphany/SM
+episcopacy/M
+episcopal
+episcopate/M
+episode/SM
+episodic
+episodically
+epistemic
+epistemological
+epistemology
+epistle/SM
+epistolary
+epitaph/M
+epitaphs
+epithelial
+epithelium/M
+epithet/SM
+epitome/SM
+epitomize/GDS
+epoch/M
+epochal
+epochs
+eponymous
+epoxy/DSMG
+epsilon/SM
+equability/M
+equable
+equably
+equal/SMDYG
+equality/IM
+equalization/M
+equalize/ZGDRS
+equalizer/M
+equanimity/M
+equate/DSGNBX
+equation/M
+equator/SM
+equatorial
+equerry/SM
+equestrian/SM
+equestrianism/M
+equestrienne/SM
+equidistant/Y
+equilateral/SM
+equilibrium/EM
+equine/SM
+equinoctial
+equinox/MS
+equip/AS
+equipage/MS
+equipment/M
+equipoise/M
+equipped/UA
+equipping/A
+equitable/I
+equitably/I
+equitation/M
+equity/ISM
+equiv
+equivalence/MS
+equivalency/SM
+equivalent/MYS
+equivocal/UY
+equivocalness/M
+equivocate/GNXDS
+equivocation/M
+equivocator/SM
+er/C
+era/SM
+eradicable/I
+eradicate/DSGN
+eradication/M
+eradicator/MS
+erase/DRSBZG
+eraser/M
+erasure/SM
+erbium/M
+ere
+erect/PSGDY
+erectile
+erection/SM
+erectness/M
+erector/MS
+erelong
+eremite/MS
+erg/SM
+ergo
+ergonomic/S
+ergonomically
+ergonomics/M
+ergosterol/M
+ergot/M
+ermine/SM
+erode/DSG
+erodible
+erogenous
+erosion/M
+erosive
+erotic/S
+erotica/M
+erotically
+eroticism/M
+err/GSD
+errand/SM
+errant/I
+errata/SM
+erratic
+erratically
+erratum/M
+erroneous/Y
+error/SM
+ersatz/MS
+erst
+erstwhile
+eruct/SDG
+eructation/SM
+erudite/YN
+erudition/M
+erupt/SDGV
+eruption/MS
+erysipelas/M
+erythrocyte/SM
+erythromycin
+escalate/CDSGN
+escalation/CM
+escalations
+escalator/MS
+escallop/SGMD
+escalope/S
+escapade/MS
+escape/LMGDS
+escapee/MS
+escapement/SM
+escapism/M
+escapist/MS
+escapologist/S
+escapology
+escargot/MS
+escarole/MS
+escarpment/MS
+eschatological
+eschatology
+eschew/SDG
+escort/SMDG
+escritoire/MS
+escrow/SM
+escudo/SM
+escutcheon/SM
+esophageal
+esophagi
+esophagus/MS
+esoteric
+esoterically
+esp
+espadrille/MS
+espalier/MDSG
+especial/Y
+espionage/M
+esplanade/MS
+espousal/M
+espouse/GDS
+espresso/MS
+esprit/M
+espy/DSG
+esquire/SM
+essay/SMDRZG
+essayer/M
+essayist/SM
+essence/SM
+essential/IMS
+essentially
+establish/AESDGL
+establishment/AEM
+establishments
+estate/SM
+esteem/ESMDG
+ester/SM
+esthetic/S
+estimable/I
+estimate/MGNDSX
+estimation/M
+estimator/SM
+estoppel
+estradiol
+estrange/LDSG
+estrangement/MS
+estrogen/MS
+estrous
+estrus/MS
+estuary/SM
+eta/SM
+etc
+etch/DRSZGJ
+etcher/M
+etching/M
+eternal/YP
+eternalness/M
+eternity/SM
+ethane/M
+ethanol/M
+ether/M
+ethereal/Y
+ethic/SM
+ethical/UY
+ethics/M
+ethmoid
+ethnic/SM
+ethnically
+ethnicity/M
+ethnocentric
+ethnocentrism/M
+ethnographer/S
+ethnographic
+ethnographically
+ethnography
+ethnological/Y
+ethnologist/SM
+ethnology/M
+ethological
+ethologist/MS
+ethology/M
+ethos/M
+ethyl/M
+ethylene/M
+etiolated
+etiologic
+etiological
+etiology/SM
+etiquette/M
+etude/SM
+etymological/Y
+etymologist/SM
+etymology/SM
+eucalypti
+eucalyptus/MS
+eucaryote/SM
+eucaryotic
+euchre/DSMG
+euclidean
+eugenic/S
+eugenically
+eugenicist/MS
+eugenics/M
+eukaryote/SM
+eukaryotic
+eulogist/MS
+eulogistic
+eulogize/ZGDRS
+eulogizer/M
+eulogy/SM
+eunuch/M
+eunuchs
+euphemism/SM
+euphemistic
+euphemistically
+euphonious/Y
+euphony/M
+euphoria/M
+euphoric
+euphorically
+eureka
+euro/MS
+europium/M
+eutectic
+euthanasia/M
+euthanize/DSG
+euthenics/M
+eutrophication
+evacuate/XDSGN
+evacuation/M
+evacuee/MS
+evade/DRSZG
+evader/M
+evaluate/AGNVDSX
+evaluation/AM
+evaluator/S
+evanescence/M
+evanescent
+evangelic
+evangelical/SMY
+evangelicalism/M
+evangelism/M
+evangelist/MS
+evangelistic
+evangelize/GDS
+evaporate/GNDS
+evaporation/M
+evaporator/SM
+evasion/SM
+evasive/YP
+evasiveness/M
+eve/ASM
+even/MDRYTGSJP
+evenhanded/Y
+evening/M
+evenness/UM
+evensong/M
+event/SM
+eventful/UY
+eventfulness/M
+eventide/M
+eventual/Y
+eventuality/SM
+eventuate/GDS
+ever
+everglade/SM
+evergreen/SM
+everlasting/MYS
+evermore
+every
+everybody/M
+everyday
+everyone/M
+everyplace
+everything/M
+everywhere
+evict/SDG
+eviction/MS
+evidence/MGDS
+evident/Y
+evil/MRYTSP
+evildoer/SM
+evildoing/M
+eviller
+evillest
+evilness/M
+evince/DSG
+eviscerate/DSGN
+evisceration/M
+evocation/MS
+evocative/Y
+evoke/DSG
+evolution/M
+evolutionary
+evolutionist/SM
+evolve/DSG
+ewe/RSMZ
+ewer/M
+ex/MS
+exabyte/MS
+exacerbate/GNDS
+exacerbation/M
+exact/SPDRYTG
+exacting/Y
+exaction/M
+exactitude/M
+exactness/IM
+exaggerate/XDSGN
+exaggerated/Y
+exaggeration/M
+exaggerator/MS
+exajoule/S
+exalt/SDG
+exaltation/M
+exam/MS
+examination/AMS
+examine/AGDS
+examiner/MS
+example/MGDS
+exampled/U
+exasperate/DSGN
+exasperated/Y
+exasperating/Y
+exasperation/M
+excavate/GNDSX
+excavation/M
+excavator/SM
+exceed/GSD
+exceeding/Y
+excel/S
+excelled
+excellence/M
+excellency/SM
+excellent/Y
+excelling
+excelsior/M
+except/GSD
+exception/BSM
+exceptionable/U
+exceptional/UY
+exceptionalism
+excerpt/MDGS
+excess/VMS
+excessive/Y
+exchange/DSMG
+exchangeable
+exchequer/SM
+excise/XDSMGN
+excision/M
+excitability/M
+excitably
+excitation/M
+excite/BDRSLZG
+excited/Y
+excitement/SM
+exciter/M
+exciting/Y
+exciton
+excl
+exclaim/DGS
+exclamation/SM
+exclamatory
+exclude/GDS
+exclusion/MS
+exclusionary
+exclusive/PMYS
+exclusiveness/M
+exclusivity/M
+excommunicate/GNDSX
+excommunication/M
+excoriate/DSGNX
+excoriation/M
+excrement/M
+excremental
+excrescence/MS
+excrescent
+excreta/M
+excrete/XGNDS
+excretion/M
+excretory
+excruciating/Y
+exculpate/DSGN
+exculpation/M
+exculpatory
+excursion/MS
+excursionist/MS
+excursive/YP
+excursiveness/M
+excusable/I
+excusably/I
+excuse/DSBMG
+excused/U
+exec/MS
+execrable
+execrably
+execrate/DSGN
+execration/M
+execute/BXGNVDS
+execution/ZMR
+executioner/M
+executive/SM
+executor/MS
+executrices
+executrix/M
+exegeses
+exegesis/M
+exegetic
+exegetical
+exemplar/SM
+exemplary
+exemplification/M
+exemplify/GDSXN
+exempt/SGD
+exemption/SM
+exercise/DRSMZG
+exerciser/M
+exert/SDG
+exertion/MS
+exeunt
+exfoliate/GNDS
+exhalation/MS
+exhale/DSG
+exhaust/GVMDS
+exhaustible/I
+exhaustion/M
+exhaustive/YP
+exhaustiveness/M
+exhibit/GMDS
+exhibition/MS
+exhibitionism/M
+exhibitionist/MS
+exhibitor/SM
+exhilarate/DSGN
+exhilaration/M
+exhort/SDG
+exhortation/MS
+exhumation/MS
+exhume/DSG
+exigence/MS
+exigency/SM
+exigent
+exiguity/M
+exiguous
+exile/DSMG
+exilic
+exist/SDG
+existence/MS
+existent
+existential/Y
+existentialism/M
+existentialist/MS
+exit/MDGS
+exobiology/M
+exodus/MS
+exogenous
+exon/MS
+exonerate/GNDS
+exoneration/M
+exoplanet/MS
+exorbitance/M
+exorbitant/Y
+exorcise/DSG
+exorcism/SM
+exorcist/SM
+exoskeleton/SM
+exosphere/SM
+exothermic
+exotic/SM
+exotica
+exotically
+exoticism/M
+exp
+expand/BGSD
+expanse/XMNVS
+expansible
+expansion/M
+expansionary
+expansionism/M
+expansionist/MS
+expansive/YP
+expansiveness/M
+expat/S
+expatiate/GNDS
+expatiation/M
+expatriate/DSMGN
+expatriation/M
+expect/GSD
+expectancy/M
+expectant/Y
+expectation/SM
+expectorant/SM
+expectorate/DSGN
+expectoration/M
+expedience/IM
+expediences
+expediencies
+expediency/IM
+expedient/SMY
+expedite/DRSZGNX
+expediter/M
+expedition/M
+expeditionary
+expeditious/PY
+expeditiousness/M
+expel/S
+expelled
+expelling
+expend/GSBD
+expendable/SM
+expenditure/SM
+expense/MS
+expensive/IYP
+expensiveness/IM
+experience/IMD
+experiences
+experiencing
+experiential
+experiment/MDRSZG
+experimental/Y
+experimentation/M
+experimenter/M
+expert/SPMY
+expertise/M
+expertness/M
+expiate/GNDS
+expiation/M
+expiatory
+expiration/M
+expire/DSG
+expired/U
+expiry/M
+explain/ADGS
+explainable
+explained/U
+explanation/MS
+explanatory
+expletive/MS
+explicable/I
+explicate/XGNDS
+explication/M
+explicit/PY
+explicitness/M
+explode/GDS
+exploit/ZGBMDRS
+exploitation/M
+exploitative
+exploited/U
+exploiter/M
+exploration/MS
+exploratory
+explore/ZGDRS
+explored/U
+explorer/M
+explosion/SM
+explosive/SPMY
+explosiveness/M
+expo/MS
+exponent/MS
+exponential/Y
+exponentiation
+export/BSZGMDR
+exportation/M
+exporter/M
+expose/DSMG
+exposed/U
+exposition/SM
+expositor/SM
+expository
+expostulate/GNXDS
+expostulation/M
+exposure/MS
+expound/ZGDRS
+expounder/M
+express/GVMDSY
+expressed/U
+expressible/I
+expression/SM
+expressionism/M
+expressionist/SM
+expressionistic
+expressionless/Y
+expressive/PY
+expressiveness/M
+expressway/SM
+expropriate/GNXDS
+expropriation/M
+expropriator/SM
+expulsion/MS
+expunge/GDS
+expurgate/DSGNX
+expurgated/U
+expurgation/M
+exquisite/YP
+exquisiteness/M
+ext
+extant
+extemporaneous/PY
+extemporaneousness/M
+extempore
+extemporization/M
+extemporize/GDS
+extend/SZGDRB
+extender/M
+extendible
+extensibility
+extensible
+extension/SM
+extensional
+extensive/YP
+extensiveness/M
+extent/SM
+extenuate/DSGN
+extenuation/M
+exterior/MS
+exterminate/DSXGN
+extermination/M
+exterminator/MS
+external/MYS
+externalization/SM
+externalize/DSG
+extinct/GDS
+extinction/MS
+extinguish/ZGBDRS
+extinguishable/I
+extinguisher/M
+extirpate/GNDS
+extirpation/M
+extol/S
+extolled
+extolling
+extort/SGD
+extortion/MRZ
+extortionate/Y
+extortioner/M
+extortionist/MS
+extra/SM
+extracellular
+extract/MDGVS
+extraction/SM
+extractor/MS
+extracurricular
+extradite/GNBXDS
+extradition/M
+extrajudicial
+extralegal
+extramarital
+extramural
+extraneous/Y
+extraordinaire
+extraordinarily
+extraordinary
+extrapolate/XGNDS
+extrapolation/M
+extrasensory
+extraterrestrial/MS
+extraterritorial
+extraterritoriality/M
+extravagance/MS
+extravagant/Y
+extravaganza/MS
+extravehicular
+extreme/PMYTRS
+extremeness/M
+extremism/M
+extremist/MS
+extremity/SM
+extricable/I
+extricate/GNDS
+extrication/M
+extrinsic
+extrinsically
+extroversion/M
+extrovert/SMD
+extrude/GDS
+extrusion/SM
+extrusive
+exuberance/M
+exuberant/Y
+exudation/M
+exude/DSG
+exult/SDG
+exultant/Y
+exultation/M
+exurb/SM
+exurban
+exurbanite/SM
+exurbia/M
+eye/DSMG
+eyeball/GMDS
+eyebrow/SM
+eyedropper/SM
+eyeful/SM
+eyeglass/MS
+eyeing
+eyelash/MS
+eyeless
+eyelet/SM
+eyelid/SM
+eyeliner/MS
+eyeopener/MS
+eyeopening
+eyepiece/MS
+eyesight/M
+eyesore/MS
+eyestrain/M
+eyeteeth
+eyetooth/M
+eyewash/M
+eyewitness/MS
+f/CIAVTR
+fMRI
+fa/M
+fab
+fable/DSM
+fabric/SM
+fabricate/DSGNX
+fabrication/M
+fabricator/SM
+fabulous/Y
+facade/SM
+face's
+face/ACSDG
+facecloth/M
+facecloths
+faceless
+facelift/SM
+facepalm/SDG
+facet/SMDG
+facetious/YP
+facetiousness/M
+facial/SMY
+facile/Y
+facilitate/GNDS
+facilitation/M
+facilitator/MS
+facility/SM
+facing/SM
+facsimile/DSM
+facsimileing
+fact/MS
+faction/SM
+factional
+factionalism/M
+factious
+factitious
+factoid/SM
+factor's
+factor/ASDG
+factorial/MS
+factorization
+factorize/GDS
+factory/SM
+factotum/SM
+factual/Y
+faculty/SM
+fad/GSMD
+faddish/P
+faddist/MS
+faddy/P
+fade/MS
+fading/U
+faerie/SM
+faff/DGS
+fag/SM
+fagged
+fagging
+faggot/SMG
+fagot/SMG
+faience/M
+fail/DGJS
+failing/M
+faille/M
+failure/SM
+fain/RT
+faint/SMDRYTGP
+fainthearted
+faintness/M
+fair/MRYTGJPS
+fairground/MS
+fairing/M
+fairness/UM
+fairway/SM
+fairy/SM
+fairyland/SM
+faith/M
+faithful's
+faithful/UPY
+faithfulness/UM
+faithfuls
+faithless/PY
+faithlessness/M
+faiths
+fajita/SM
+fajitas/M
+fake/MZGDRS
+faker/M
+fakir/SM
+falcon/SMRZ
+falconer/M
+falconry/M
+fall/MNGS
+fallacious/Y
+fallacy/SM
+fallback
+fallibility/IM
+fallible/P
+fallibleness/M
+fallibly/I
+falloff/SM
+fallout/M
+fallow/SMDG
+false/PRYT
+falsehood/SM
+falseness/M
+falsetto/SM
+falsie/SM
+falsifiable
+falsification/M
+falsifier/M
+falsify/DRSZGNX
+falsity/SM
+falter/GSJMD
+faltering/Y
+fame's
+fame/D
+familial
+familiar/MYS
+familiarity/UM
+familiarization/M
+familiarize/GDS
+family/SM
+famine/SM
+famish/DSG
+famous/IY
+fan/SM
+fanatic/SM
+fanatical/Y
+fanaticism/M
+fanboy/SM
+fanciable
+fancier/M
+fanciful/YP
+fancifulness/M
+fancily
+fanciness/M
+fancy/DRSMZTGP
+fancywork/M
+fandango/MS
+fandom
+fanfare/SM
+fang/MDS
+fanlight/SM
+fanned
+fanning
+fanny/SM
+fantail/MS
+fantasia/SM
+fantasist/S
+fantasize/GDS
+fantastic
+fantastical/Y
+fantasy/DSMG
+fanzine/MS
+far
+farad/SM
+faradize/DG
+faraway
+farce/SM
+farcical/Y
+fare/MGDS
+farewell/SM
+farfetched
+farina/M
+farinaceous
+farm/MDRZGSJ
+farmer/M
+farmhand/SM
+farmhouse/SM
+farming/M
+farmland/MS
+farmstead/MS
+farmyard/MS
+faro/M
+farrago/M
+farragoes
+farrier/MS
+farrow/SMDG
+farseeing
+farsighted/P
+farsightedness/M
+fart/MDGS
+farther
+farthermost
+farthest
+farthing/SM
+fascia/SM
+fascicle/SM
+fascinate/GNDSX
+fascinating/Y
+fascination/M
+fascism/M
+fascist/MS
+fascistic
+fashion/ZGBMDRS
+fashionable/U
+fashionably/U
+fashioner/M
+fashionista/MS
+fast/MDRTGSP
+fastback/SM
+fastball/SM
+fasten/UAGDS
+fastener/SM
+fastening/MS
+fastidious/PY
+fastidiousness/M
+fastness/MS
+fat/GSPMD
+fatal/Y
+fatalism/M
+fatalist/SM
+fatalistic
+fatalistically
+fatality/SM
+fatback/M
+fate/MS
+fateful/YP
+fatefulness/M
+fathead/MDS
+father/SGMDY
+fatherhood/M
+fatherland/MS
+fatherless
+fathom/SMDGB
+fathomable/U
+fathomless
+fatigue/MDSG
+fatigues/M
+fatness/M
+fatso/S
+fatten/SDG
+fatter
+fattest
+fattiness/M
+fatty/RSMTP
+fatuity/M
+fatuous/YP
+fatuousness/M
+fatwa/SM
+faucet/SM
+fault/CSMDG
+faultfinder/SM
+faultfinding/M
+faultily
+faultiness/M
+faultless/PY
+faultlessness/M
+faulty/PRT
+faun/MS
+fauna/SM
+fauvism/M
+fauvist/SM
+faux
+fave/S
+favor/ESMDG
+favorable/U
+favorably/U
+favorite/SM
+favoritism/M
+fawn/MDRZGS
+fawner/M
+fax/GMDS
+fay/TSMR
+faze/GDS
+fazed/U
+fa誰ence/M
+fealty/M
+fear/MDGS
+fearful/YP
+fearfulness/M
+fearless/PY
+fearlessness/M
+fearsome
+feasibility/M
+feasible/IU
+feasibly
+feast/SMDRZG
+feaster/M
+feat/MS
+feather/SGMD
+featherbedding/M
+featherbrained
+featherless
+featherweight/MS
+feathery/TR
+feature/DSMG
+featureless
+febrile
+fecal
+feces/M
+feckless/PY
+fecund
+fecundate/GNDS
+fecundation/M
+fecundity/M
+fed/SM
+federal/SMY
+federalism/M
+federalist/MS
+federalization/M
+federalize/GDS
+federate/FXDSGN
+federation/FM
+fedora/SM
+fee/SM
+feeble/RTP
+feebleness/M
+feebly
+feed/MRZGSJ
+feedback/M
+feedbag/SM
+feeder/M
+feeding/M
+feedlot/SM
+feel/MRZGSJ
+feeler/M
+feelgood
+feeling/MY
+feet
+feign/SDG
+feigned/U
+feint/SMDG
+feisty/TR
+feldspar/M
+felicitate/GNXDS
+felicitation/M
+felicitous/Y
+felicity/ISM
+feline/SM
+fell/MDRZTGS
+fella/S
+fellatio/M
+fellow/SM
+fellowman/M
+fellowmen
+fellowship/MS
+felon/SM
+felonious
+felony/SM
+felt/MDGS
+fem
+female/PSM
+femaleness/M
+feminine/SMY
+femininity/M
+feminism/M
+feminist/SM
+feminize/DSG
+femoral
+femur/SM
+fen/SM
+fence/DRSMZG
+fencer/M
+fencing/M
+fend/CDRZGS
+fender/CM
+fenestration/M
+fennel/M
+fentanyl/M
+feral
+ferment/FCMS
+fermentation/M
+fermented
+fermenting
+fermium/M
+fern/MS
+ferny/RT
+ferocious/PY
+ferociousness/M
+ferocity/M
+ferret/GSMD
+ferric
+ferromagnetic
+ferromagnetism
+ferrous
+ferrule/MS
+ferry/DSMG
+ferryboat/SM
+ferryman/M
+ferrymen
+fertile/I
+fertility/IM
+fertilization/M
+fertilize/DRSZG
+fertilized/U
+fertilizer/M
+ferule/SM
+fervency/M
+fervent/Y
+fervid/Y
+fervor/M
+fess/FKGSD
+fest/MRZVS
+festal
+fester/GMD
+festival/SM
+festive/YP
+festiveness/M
+festivity/SM
+festoon/GMDS
+feta/M
+fetal
+fetch/DRSZG
+fetcher/M
+fetching/Y
+fete/MGDS
+fetid/P
+fetidness/M
+fetish/MS
+fetishism/M
+fetishist/SM
+fetishistic
+fetlock/MS
+fetter's
+fetter/USGD
+fettle/M
+fettuccine/M
+fetus/MS
+feud/MDGS
+feudal
+feudalism/M
+feudalistic
+fever/SMD
+feverish/YP
+feverishness/M
+few/TPMR
+fewness/M
+fey
+fez/M
+fezzes
+ff
+fiance/CM
+fiancee/MS
+fiances
+fianc辿/SM
+fianc辿e/MS
+fiasco/SM
+fiascoes
+fiat/MS
+fib/ZSMR
+fibbed
+fibber/SM
+fibbing
+fiber/M
+fiberboard/M
+fiberfill/M
+fiberglass/M
+fibril/SM
+fibrillate/GNDS
+fibrillation/M
+fibrin/M
+fibroid
+fibrosis/M
+fibrous
+fibula/M
+fibulae
+fibular
+fiche/SM
+fichu/SM
+fickle/RPT
+fickleness/M
+fiction/MS
+fictional/Y
+fictionalization/SM
+fictionalize/DSG
+fictitious/Y
+fictive
+ficus/M
+fiddle/DRSMZG
+fiddler/M
+fiddlesticks
+fiddly/TR
+fidelity/IM
+fidget/SGMD
+fidgety
+fiduciary/SM
+fie
+fief/MS
+fiefdom/MS
+field/ISMRZ
+fielded
+fielder/IM
+fielding
+fieldsman
+fieldsmen
+fieldwork/MRZ
+fieldworker/M
+fiend/SM
+fiendish/Y
+fierce/PRYT
+fierceness/M
+fieriness/M
+fiery/RPT
+fiesta/SM
+fife/MZRS
+fifer/M
+fifteen/MHS
+fifteenth/M
+fifteenths
+fifth/MY
+fifths
+fiftieth/M
+fiftieths
+fifty/SMH
+fig/SLM
+fight/SMRZG
+fightback
+fighter/IMS
+fighting/IM
+figment/MS
+figuration/FM
+figurative/Y
+figure's
+figure/FEGSD
+figurehead/SM
+figurine/MS
+filament/MS
+filamentous
+filbert/MS
+filch/DSG
+file's/KC
+file/CAKGDS
+filename/S
+filer/CSM
+filet
+filial
+filibuster/MDRSZG
+filibusterer/M
+filigree/DSM
+filigreeing
+filing's
+filings
+fill's
+fill/AIDGS
+filled/U
+filler/MS
+fillet/MDGS
+filling/SM
+fillip/MDGS
+filly/SM
+film/MDGS
+filminess/M
+filmmaker/SM
+filmstrip/MS
+filmy/TPR
+filo
+filter/MDRBSZG
+filtered/U
+filterer/M
+filth/M
+filthily
+filthiness/M
+filthy/RPT
+filtrate's
+filtrate/IGNDS
+filtration/IM
+fin/SMR
+finagle/DRSZG
+finagler/M
+final/SMY
+finale/MS
+finalist/SM
+finality/M
+finalization/M
+finalize/DSG
+finance's
+finance/ADSG
+financial/Y
+financier/MS
+financing/M
+finch/MS
+find/JMRZGS
+finder/M
+finding/M
+findings/M
+fine's/F
+fine/CAFTGDS
+finely
+fineness/M
+finery/AM
+finespun
+finesse/DSMG
+finger/MDGSJ
+fingerboard/SM
+fingering/M
+fingerling/SM
+fingermark/S
+fingernail/SM
+fingerprint/SGMD
+fingertip/MS
+finial/MS
+finical
+finickiness/M
+finicky/RPT
+finis/MS
+finish's
+finish/ADSG
+finished/U
+finisher/MS
+finite/IY
+fink/MDGS
+finned
+finny
+fir/ZGSJMDRH
+fire/MS
+firearm/SM
+fireball/MS
+firebomb/MDSJG
+firebox/MS
+firebrand/SM
+firebreak/SM
+firebrick/SM
+firebug/SM
+firecracker/SM
+firedamp/M
+firefight/MRSZG
+firefighter/M
+firefighting/M
+firefly/SM
+fireguard/S
+firehouse/SM
+firelight/ZMR
+fireman/M
+firemen
+fireplace/SM
+fireplug/MS
+firepower/M
+fireproof/DSG
+firer/M
+firescreen/S
+fireside/MS
+firestorm/MS
+firetrap/MS
+firetruck/MS
+firewall/MS
+firewater/M
+firewood/M
+firework/SM
+firm/MDRYPTGS
+firmament/SM
+firmness/M
+firmware/M
+first/SMY
+firstborn/SM
+firsthand
+firth/M
+firths
+fiscal/MYS
+fish/MDRSZG
+fishbowl/SM
+fishcake/SM
+fisher/M
+fisherman/M
+fishermen
+fishery/SM
+fishhook/SM
+fishily
+fishiness/M
+fishing/M
+fishmonger/MS
+fishnet/SM
+fishpond/MS
+fishtail/DGS
+fishwife/M
+fishwives
+fishy/TRP
+fissile
+fission/BM
+fissure/SM
+fist/MS
+fistfight/MS
+fistful/SM
+fisticuffs/M
+fistula/SM
+fistulous/M
+fit/KAMS
+fitful/YP
+fitfulness/M
+fitly
+fitment/S
+fitness/UM
+fitted/UA
+fitter/MS
+fittest
+fitting/SMY
+five/MZRS
+fix/ZGBJMDRS
+fixate/GNVDSX
+fixation/M
+fixative/MS
+fixed/Y
+fixer/M
+fixings/M
+fixity/M
+fixture/MS
+fizz/MDSG
+fizzle/DSMG
+fizzy/RT
+fjord/SM
+fl/JDG
+flab/M
+flabbergast/SGD
+flabbily
+flabbiness/M
+flabby/RPT
+flaccid/Y
+flaccidity/M
+flack/SM
+flag/MS
+flagella
+flagellant/S
+flagellate/GNDS
+flagellation/M
+flagellum/M
+flagged
+flagging/U
+flagman/M
+flagmen
+flagon/MS
+flagpole/SM
+flagrance/M
+flagrancy/M
+flagrant/Y
+flagship/SM
+flagstaff/MS
+flagstone/MS
+flail/SGMD
+flair/SM
+flak/M
+flake/DSMG
+flakiness/M
+flaky/TRP
+flamage
+flambe/MS
+flambeed
+flambeing
+flamboyance/M
+flamboyancy/M
+flamboyant/Y
+flamb辿/MD
+flame/DRSJMZG
+flamenco/MS
+flameproof/DGS
+flamethrower/SM
+flamingo/MS
+flammability/IM
+flammable/SM
+flan/MS
+flange/MS
+flank/SZGMDR
+flanker/M
+flannel/SGMD
+flannelette/M
+flap/MS
+flapjack/MS
+flapped
+flapper/SM
+flapping
+flare/DSMG
+flareup/SM
+flash/ZTGMDRS
+flashback/SM
+flashbulb/SM
+flashcard/SM
+flashcube/SM
+flasher/M
+flashgun/SM
+flashily
+flashiness/M
+flashing/M
+flashlight/MS
+flashpoint/SM
+flashy/RTP
+flask/SM
+flat/MYPS
+flatbed/SM
+flatboat/SM
+flatbread
+flatcar/SM
+flatfeet
+flatfish/MS
+flatfoot/SMD
+flatiron/SM
+flatland/M
+flatlet/S
+flatmate/S
+flatness/M
+flatted
+flatten/SDG
+flatter/SDRZG
+flatterer/M
+flattering/Y
+flattery/M
+flattest
+flatting
+flattish
+flattop/SM
+flatulence/M
+flatulent
+flatus/M
+flatware/M
+flatworm/SM
+flaunt/MDSG
+flaunting/Y
+flavor/MDSGJ
+flavored/U
+flavorful
+flavoring/M
+flavorless
+flavorsome
+flaw/MDGS
+flawless/PY
+flawlessness/M
+flax/MN
+flay/DGS
+flea/MS
+fleabag/SM
+fleabite/S
+fleapit/S
+fleck/SGMD
+fledged/U
+fledgling/MS
+flee/S
+fleece/MZGDRS
+fleecer/M
+fleeciness/M
+fleecy/RTP
+fleeing
+fleet/STGMDRYP
+fleetingly/M
+fleetingness/M
+fleetness/M
+flesh/GMDSY
+fleshly/TR
+fleshpot/MS
+fleshy/RT
+flew
+flex/AMS
+flexed
+flexibility/IM
+flexible/I
+flexibly/I
+flexing
+flexion
+flextime/M
+flibbertigibbet/SM
+flick/SZGMDR
+flicker/GMD
+flier/M
+flight/MS
+flightiness/M
+flightless
+flighty/PTR
+flimflam/SM
+flimflammed
+flimflamming
+flimsily
+flimsiness/M
+flimsy/TRP
+flinch/GMDS
+fling/GM
+flint/SM
+flintlock/SM
+flinty/TR
+flip/MS
+flippancy/M
+flippant/Y
+flipped
+flipper/MS
+flippest
+flipping
+flippy/S
+flirt/SGMD
+flirtation/MS
+flirtatious/YP
+flirtatiousness/M
+flirty
+flit/MS
+flitted
+flitting
+float/SMDRZG
+floater/M
+flock/SMDG
+flocking/M
+floe/MS
+flog/S
+flogged
+flogger/SM
+flogging/MS
+flood/SMDRG
+floodgate/MS
+floodlight/MDSG
+floodlit
+floodplain/MS
+floodwater/MS
+floor/SMDG
+floorboard/MS
+flooring/M
+floorwalker/SM
+floozie/M
+floozy/SM
+flop/MS
+flophouse/MS
+flopped
+floppily
+floppiness/M
+flopping
+floppy/PRSMT
+flora/SM
+floral
+florescence/IM
+florescent/I
+floret/SM
+florid/PY
+floridness/M
+florin/SM
+florist/SM
+floss/MDSG
+flossy/RT
+flotation/SM
+flotilla/MS
+flotsam/M
+flounce/DSMG
+flouncy
+flounder/MDSG
+flour/SMDG
+flourish/GMDS
+floury
+flout/SMDRZG
+flouter/M
+flow/MDGS
+flowchart/SM
+flower's
+flower/CSDG
+flowerbed/MS
+floweriness/M
+flowering/S
+flowerless
+flowerpot/MS
+flowery/PTR
+flown
+flt
+flu/M
+flub/MS
+flubbed
+flubbing
+fluctuate/GNDSX
+fluctuation/M
+flue/MS
+fluency/M
+fluent/Y
+fluff/SMDG
+fluffiness/M
+fluffy/RPT
+fluid/SMY
+fluidity/M
+fluke/SM
+fluky/RT
+flume/SM
+flummox/DSG
+flung
+flunk/SMDG
+flunky/SM
+fluoresce/DSG
+fluorescence/M
+fluorescent
+fluoridate/GNDS
+fluoridation/M
+fluoride/SM
+fluorine/M
+fluorite/M
+fluorocarbon/MS
+fluoroscope/SM
+fluoroscopic
+fluoxetine
+flurry/GDSM
+flush/MDRSTG
+fluster/MDSG
+flute/DSMG
+fluting/M
+flutist/MS
+flutter/MDSG
+fluttery
+fluvial
+flux/IMS
+fluxed
+fluxing
+fly/ZTGBDRSM
+flyaway
+flyblown
+flyby/M
+flybys
+flycatcher/MS
+flying/M
+flyleaf/M
+flyleaves
+flyover/MS
+flypaper/SM
+flypast/S
+flysheet/S
+flyspeck/GMDS
+flyswatter/MS
+flytrap/S
+flyway/SM
+flyweight/SM
+flywheel/MS
+fo'c'sle/MS
+foal/MDGS
+foam/MDGS
+foaminess/M
+foamy/RTP
+fob/SM
+fobbed
+fobbing
+focal/Y
+focus's
+focus/ADSG
+focused/U
+fodder/SM
+foe/SM
+fog's
+fog/CS
+fogbound
+fogged/C
+foggily
+fogginess/M
+fogging/C
+foggy/RTP
+foghorn/MS
+fogy/SM
+fogyish
+foible/SM
+foil/MDGS
+foist/SDG
+fol
+fold's
+fold/AUSGD
+foldaway
+folder/SM
+foldout/MS
+foliage/M
+folic
+folio/SM
+folk/MS
+folklore/M
+folkloric
+folklorist/MS
+folksiness/M
+folksinger/SM
+folksinging/M
+folksy/PTR
+folktale/MS
+folkway/MS
+foll
+follicle/MS
+follow/SDRZGJ
+follower/M
+following/M
+followup/S
+folly/SM
+foment/SGD
+fomentation/M
+fond/RYTP
+fondant/MS
+fondle/DSG
+fondness/M
+fondue/SM
+font/MS
+fontanel/MS
+fontanelle/MS
+foo
+foobar
+food/MS
+foodie/SM
+foodstuff/SM
+fool/MDGS
+foolery/SM
+foolhardily
+foolhardiness/M
+foolhardy/TPR
+foolish/YP
+foolishness/M
+foolproof
+foolscap/M
+foot/MDRZGSJ
+footage/M
+football/MRZGS
+footballer/M
+footbridge/SM
+footfall/MS
+foothill/MS
+foothold/MS
+footie
+footing/M
+footless
+footlights/M
+footling/MS
+footlocker/SM
+footloose
+footman/M
+footmen
+footnote/MGDS
+footpath/M
+footpaths
+footplate/S
+footprint/SM
+footrace/MS
+footrest/MS
+footsie/SM
+footslogging
+footsore
+footstep/MS
+footstool/SM
+footwear/M
+footwork/M
+footy
+fop/SM
+foppery/M
+foppish/P
+foppishness/M
+for/H
+fora
+forage/DRSMZG
+forager/M
+foray/SMDG
+forbade
+forbear/SMG
+forbearance/M
+forbid/S
+forbidden
+forbidding/YS
+forbore
+forborne
+force/DSMG
+forced/U
+forceful/PY
+forcefulness/M
+forceps/M
+forcible
+forcibly
+ford/MDGSB
+fore/MS
+forearm/GSMD
+forebear/MS
+forebode/GJDS
+foreboding/M
+forecast/MRZGS
+forecaster/M
+forecastle/MS
+foreclose/DSG
+foreclosure/MS
+forecourt/SM
+foredoom/DGS
+forefather/MS
+forefeet
+forefinger/SM
+forefoot/M
+forefront/SM
+foregather/GDS
+forego/G
+foregoes
+foregone
+foreground/GMDS
+forehand/MS
+forehead/MS
+foreign/ZRP
+foreigner/M
+foreignness/M
+foreknew
+foreknow/GS
+foreknowledge/M
+foreknown
+foreleg/SM
+forelimb/MS
+forelock/MS
+foreman/M
+foremast/MS
+foremen
+foremost
+forename/MDS
+forenoon/MS
+forensic/MS
+forensically
+forensics/M
+foreordain/GSD
+forepart/MS
+foreperson/SM
+foreplay/M
+forequarter/MS
+forerunner/MS
+foresail/MS
+foresaw
+foresee/RSBZ
+foreseeable/U
+foreseeing
+foreseen/U
+foreseer/M
+foreshadow/GDS
+foreshore/S
+foreshorten/DSG
+foresight/MD
+foresightedness/M
+foreskin/MS
+forest's
+forest/ACGDS
+forestall/SGD
+forestation/ACM
+forester/MS
+forestland/M
+forestry/M
+foretaste/DSMG
+foretell/GS
+forethought/M
+foretold
+forever/M
+forevermore
+forewarn/DSG
+forewent
+forewoman/M
+forewomen
+foreword/MS
+forfeit/GSMD
+forfeiture/SM
+forgather/SDG
+forgave
+forge/DRSMZGVJ
+forger/M
+forgery/SM
+forget/S
+forgetful/YP
+forgetfulness/M
+forgettable/U
+forgetting
+forging/M
+forgivable/U
+forgive/BRSZGP
+forgiven
+forgiveness/M
+forgiver/M
+forgiving/U
+forgo/RZG
+forgoer/M
+forgoes
+forgone
+forgot
+forgotten/U
+fork/MDGS
+forkful/SM
+forklift/MS
+forlorn/Y
+form's
+form/CAIFDGS
+formal/SMY
+formaldehyde/M
+formalin
+formalism/M
+formalist/MS
+formalities
+formality/IM
+formalization/M
+formalize/GDS
+format/SMV
+formation/CFASM
+formatted/A
+formatting/M
+formed/U
+former/FIAM
+formerly
+formfitting
+formic
+formidable
+formidably
+formless/PY
+formlessness/M
+formula/MS
+formulae
+formulaic
+formulate/ADSGNX
+formulated/U
+formulation/AM
+formulator/SM
+fornicate/GNDS
+fornication/M
+fornicator/MS
+forsake/GS
+forsaken
+forsook
+forsooth
+forswear/SG
+forswore
+forsworn
+forsythia/SM
+fort/MS
+forte/SM
+forthcoming/M
+forthright/YP
+forthrightness/M
+forthwith
+fortieth/M
+fortieths
+fortification/M
+fortified/U
+fortifier/M
+fortify/DRSNZGX
+fortissimo
+fortitude/M
+fortnight/MYS
+fortress/MS
+fortuitous/YP
+fortuitousness/M
+fortuity/M
+fortunate/UY
+fortune/MS
+fortuneteller/SM
+fortunetelling/M
+forty/SMH
+forum/SM
+forward/MDRYZTGSP
+forwarder/M
+forwardness/M
+forwent
+fossa
+fossil/SM
+fossilization/M
+fossilize/GDS
+foster/GSD
+fought
+foul/MDRYTGSP
+foulard/M
+foulmouthed
+foulness/M
+found/FSDG
+foundation/SM
+foundational
+founded/U
+founder/GMDS
+foundling/SM
+foundry/SM
+fount/SM
+fountain/SM
+fountainhead/MS
+four/MHS
+fourfold
+fourposter/SM
+fourscore/M
+foursome/SM
+foursquare
+fourteen/SMH
+fourteenth/M
+fourteenths
+fourth/MY
+fourths
+fowl/MDGS
+fox/GMDS
+foxfire/M
+foxglove/SM
+foxhole/MS
+foxhound/SM
+foxhunt/GS
+foxily
+foxiness/M
+foxtrot/MS
+foxtrotted
+foxtrotting
+foxy/RTP
+foyer/SM
+fps
+fr
+fracas/MS
+frack/SDG
+fractal/SM
+fraction/ISM
+fractional/Y
+fractious/YP
+fractiousness/M
+fracture/MGDS
+frag/S
+fragile/RT
+fragility/M
+fragment/GMDS
+fragmentary/M
+fragmentation/M
+fragrance/MS
+fragrant/Y
+frail/RYTP
+frailness/M
+frailty/SM
+frame/DRSMZG
+framed/U
+framer/M
+framework/SM
+franc/SM
+franchise's
+franchise/EDSG
+franchisee/SM
+franchiser/SM
+franchisor/SM
+francium/M
+francophone
+frangibility/M
+frangible
+frank/SMDRYTGP
+frankfurter/MS
+frankincense/M
+frankness/M
+frantic
+frantically
+frappe/SM
+frapp辿/M
+frat/MS
+fraternal/Y
+fraternity/FSM
+fraternization/M
+fraternize/ZGDRS
+fraternizer/M
+fratricidal
+fratricide/MS
+fraud's
+fraud/S
+fraudster/S
+fraudulence/M
+fraudulent/Y
+fraught
+fray's
+fray/CDGS
+frazzle/MGDS
+freak/SMDG
+freakish/YP
+freakishness/M
+freakout/MS
+freaky/RT
+freckle/DSMG
+freckly
+free/YTDRS
+freebase/MGDS
+freebee/SM
+freebie/SM
+freebooter/SM
+freeborn
+freedman/M
+freedmen
+freedom/SM
+freehand
+freehold/ZMRS
+freeholder/M
+freeing
+freelance/DRSMZG
+freelancer/M
+freeload/SDRZG
+freeloader/M
+freeman/M
+freemasonry
+freemen
+freephone
+freesia/S
+freestanding
+freestone/SM
+freestyle/SM
+freethinker/SM
+freethinking/M
+freeware/M
+freeway/MS
+freewheel/DGS
+freewill
+freezable
+freeze's
+freeze/UAGS
+freezer/MS
+freezing's
+freight/MDRZGS
+freighter/M
+french
+frenemy/S
+frenetic
+frenetically
+frenzied/Y
+frenzy/DSM
+freq
+frequencies
+frequency/IM
+frequent/DRYSZTG
+frequented/U
+frequenter/M
+fresco/M
+frescoes
+fresh/PNRYXZT
+freshen/ZGDR
+freshener/M
+freshet/MS
+freshman/M
+freshmen
+freshness/M
+freshwater/M
+fret/MS
+fretful/YP
+fretfulness/M
+fretsaw/MS
+fretted
+fretting
+fretwork/M
+friable
+friar/SM
+friary/SM
+fricassee/DSM
+fricasseeing
+fricative/SM
+friction/SM
+frictional
+fridge/SM
+friedcake/MS
+friend's
+friend/UGSDY
+friendless
+friendlies
+friendliness/UM
+friendly's
+friendly/UPTR
+friendship/MS
+frieze/SM
+frig/S
+frigate/MS
+frigged
+frigging
+fright/SXGMDN
+frighten/DG
+frightening/Y
+frightful/PY
+frightfulness/M
+frigid/YP
+frigidity/M
+frigidness/M
+frill/SMD
+frilly/TR
+fringe's
+fringe/IDSG
+frippery/SM
+frisk/SDG
+friskily
+friskiness/M
+frisky/TRP
+frisson/S
+fritter/MDSG
+fritz/M
+frivolity/SM
+frivolous/PY
+frivolousness/M
+frizz/MDSYG
+frizzle/MGDS
+frizzy/TR
+fro
+frock's
+frock/CUS
+frog/MS
+frogging/S
+frogman/M
+frogmarch/GDS
+frogmen
+frogspawn
+frolic/SM
+frolicked
+frolicker/SM
+frolicking
+frolicsome
+from
+frond/SM
+front's
+front/FSDG
+frontage/MS
+frontal/Y
+frontbench/ZRS
+frontier/MS
+frontiersman/M
+frontiersmen
+frontierswoman
+frontierswomen
+frontispiece/MS
+frontward/S
+frosh/M
+frost's
+frost/CSDG
+frostbit
+frostbite/MGS
+frostbitten
+frostily
+frostiness/M
+frosting/SM
+frosty/TPR
+froth/MDG
+frothiness/M
+froths
+frothy/TPR
+froufrou/M
+frown/SMDG
+frowsy/TR
+frowzily
+frowziness/M
+frowzy/TPR
+froze/AU
+frozen/UA
+fructify/DSG
+fructose/M
+frugal/Y
+frugality/M
+fruit/SMDG
+fruitcake/MS
+fruiterer/S
+fruitful/YP
+fruitfulness/M
+fruitiness/M
+fruition/M
+fruitless/PY
+fruitlessness/M
+fruity/TPR
+frump/SM
+frumpish
+frumpy/TR
+frustrate/GNXDS
+frustrating/Y
+frustration/M
+frustum/MS
+fry/GDSM
+fryer/SM
+ft
+ftp/ZGS
+fuchsia/MS
+fuck/SMGDRZ!
+fucker/M!
+fuckhead/S!
+fuddle/DSMG
+fudge/DSMG
+fuehrer/MS
+fuel's
+fuel/ADGS
+fug
+fugal
+fuggy
+fugitive/MS
+fugue/SM
+fuhrer/SM
+fulcrum/MS
+fulfill/LDGS
+fulfilled/U
+fulfilling/U
+fulfillment/M
+full/MDRZTGSP
+fullback/MS
+fuller/M
+fullness/M
+fully
+fulminate/DSXGN
+fulmination/M
+fulsome/PY
+fulsomeness/M
+fum/S
+fumble/DRSMZG
+fumbler/M
+fumbling/Y
+fume/MGDS
+fumigant/MS
+fumigate/GNDS
+fumigation/M
+fumigator/SM
+fumy/RT
+fun/M
+function/MDGS
+functional/Y
+functionalism
+functionalist/S
+functionality/S
+functionary/SM
+functor
+fund/AMDGS
+fundamental/SMY
+fundamentalism/M
+fundamentalist/SM
+funded/U
+funding/M
+fundraiser/MS
+fundraising
+funeral/MS
+funerary
+funereal/Y
+funfair/S
+fungal
+fungi
+fungible/MS
+fungicidal
+fungicide/MS
+fungoid
+fungous
+fungus/M
+funicular/SM
+funk/MDGS
+funkiness/M
+funky/PRT
+funnel/MDGS
+funner
+funnest
+funnily
+funniness/M
+funny/TPRSM
+funnyman/M
+funnymen
+fur/SM
+furbelow/M
+furbish/ADSG
+furious/Y
+furl's
+furl/UDGS
+furlong/SM
+furlough/GMD
+furloughs
+furn
+furnace/SM
+furnish/ADSG
+furnished/U
+furnishings/M
+furniture/M
+furor/SM
+furosemide
+furred
+furrier/M
+furriness/M
+furring/M
+furrow/MDSG
+furry/ZTRP
+further/SGD
+furtherance/M
+furthermore
+furthermost
+furthest
+furtive/YP
+furtiveness/M
+fury/SM
+furze/M
+fuse's/A
+fuse/CAIFGDS
+fusee/SM
+fuselage/SM
+fusibility/M
+fusible
+fusileer/SM
+fusilier/SM
+fusillade/MS
+fusion/IFKSM
+fuss/MDSG
+fussbudget/MS
+fussily
+fussiness/M
+fusspot/SM
+fussy/TRP
+fustian/M
+fustiness/M
+fusty/TRP
+fut
+futile/Y
+futility/M
+futon/SM
+future/MS
+futurism/M
+futurist/MS
+futuristic
+futurity/SM
+futurologist/MS
+futurology/M
+futz/DSG
+fuzz/MDSG
+fuzzball/S
+fuzzily
+fuzziness/M
+fuzzy/PTR
+fwd
+fwy
+f棚te/SM
+g/SNXVB
+gab/SM
+gabardine/SM
+gabbed
+gabbiness/M
+gabbing
+gabble/DSMG
+gabby/RTP
+gaberdine/SM
+gabfest/MS
+gable/DSM
+gad/S
+gadabout/SM
+gadded
+gadder/SM
+gadding
+gadfly/SM
+gadget/SM
+gadgetry/M
+gadolinium/M
+gaff/MDRZGS
+gaffe/SM
+gaffer/M
+gag/SM
+gaga
+gagged
+gagging
+gaggle/SM
+gaiety/M
+gaily
+gain's
+gain/ADGS
+gainer/SM
+gainful/Y
+gainsaid
+gainsay/ZGRS
+gainsayer/M
+gait/MRZS
+gaiter/M
+gal/SM
+gala/MS
+galactic
+galaxy/SM
+gale's
+gale/AS
+galena/M
+gall/MDGS
+gallant/SMY
+gallantry/M
+gallbladder/MS
+galleon/SM
+galleria/MS
+gallery/SM
+galley/SM
+gallimaufry/SM
+gallium/M
+gallivant/GSD
+gallon/SM
+gallop/SMDG
+gallows/M
+gallstone/MS
+galoot/SM
+galore
+galosh/MS
+galumph/DG
+galumphs
+galvanic
+galvanism/M
+galvanization/M
+galvanize/DSG
+galvanometer/MS
+gambit/SM
+gamble/DRSMZG
+gambler/M
+gambling/M
+gambol/SMDG
+game/MYTGDRSP
+gamecock/MS
+gamekeeper/MS
+gameness/M
+gamesmanship/M
+gamester/MS
+gamete/SM
+gametic
+gamey
+gamin/SM
+gamine/SM
+gaminess/M
+gaming/M
+gamma/SM
+gammon/M
+gammy
+gamut/SM
+gamy/RTP
+gander/SM
+gang/MDGS
+gangbusters/M
+gangland/M
+ganglia
+gangling
+ganglion/M
+ganglionic
+gangplank/SM
+gangrene/DSMG
+gangrenous
+gangsta/S
+gangster/SM
+gangway/MS
+ganja
+gannet/SM
+gantlet/MS
+gantry/SM
+gap/GSMD
+gape/MS
+gar/SLM
+garage/DSMG
+garb/MDGS
+garbage/M
+garbageman
+garbanzo/SM
+garble/DSG
+garcon/SM
+garden/SZGMDR
+gardener/M
+gardenia/MS
+gardening/M
+garfish/MS
+gargantuan
+gargle/DSMG
+gargoyle/SM
+garish/PY
+garishness/M
+garland/MDGS
+garlic/M
+garlicky
+garment/MS
+garner/SGD
+garnet/SM
+garnish/GLMDS
+garnishee/DSM
+garnisheeing
+garnishment/SM
+garotte/MGDS
+garret/SM
+garrison/MDSG
+garrote/MZGDRS
+garroter/M
+garrotte/MGDS
+garrulity/M
+garrulous/PY
+garrulousness/M
+garter/SM
+gar巽on/SM
+gas's
+gas/CS
+gasbag/SM
+gaseous
+gash/MDSG
+gasholder/S
+gasket/SM
+gaslight/MS
+gasman
+gasmen
+gasohol/M
+gasoline/M
+gasometer/S
+gasp/MDGS
+gassed/C
+gasses
+gassing/C
+gassy/RT
+gastric
+gastritis/M
+gastroenteritis/M
+gastrointestinal
+gastronome/S
+gastronomic
+gastronomical/Y
+gastronomy/M
+gastropod/SM
+gasworks/M
+gate/MGDS
+gateau
+gateaux
+gatecrash/DRSZG
+gatecrasher/M
+gatehouse/SM
+gatekeeper/MS
+gatepost/MS
+gateway/MS
+gather/SJZGMDR
+gatherer/M
+gathering/M
+gator/SM
+gauche/RPYT
+gaucheness/M
+gaucherie/M
+gaucho/SM
+gaudily
+gaudiness/M
+gaudy/RPT
+gauge/DSMG
+gaunt/RPT
+gauntlet/MS
+gauntness/M
+gauze/M
+gauziness/M
+gauzy/RPT
+gave
+gavel/SM
+gavotte/MS
+gawd
+gawk/DGS
+gawkily
+gawkiness/M
+gawky/RPT
+gawp/DGS
+gay/TSPMR
+gayness/M
+gaze/MZGDRS
+gazebo/SM
+gazelle/MS
+gazer/M
+gazette/MGDS
+gazetteer/MS
+gazillion/S
+gazpacho/M
+gazump/DGS
+gear/MDGS
+gearbox/MS
+gearing/M
+gearshift/MS
+gearwheel/SM
+gecko/SM
+geddit
+gee/DS
+geeing
+geek/MS
+geeky/RT
+geese
+geezer/MS
+geisha/M
+gel/SM
+gelatin/M
+gelatinous
+gelcap/M
+geld/DJGS
+gelding/M
+gelid
+gelignite/M
+gelled
+gelling
+gem/SM
+gemmology/M
+gemological
+gemologist/MS
+gemology/M
+gemstone/MS
+gendarme/MS
+gender/MDS
+gene/MS
+genealogical/Y
+genealogist/MS
+genealogy/SM
+genera
+general/SMY
+generalissimo/MS
+generalist/MS
+generality/SM
+generalization/MS
+generalize/GDS
+generalship/M
+generate/CAVNGSD
+generation/ACM
+generational
+generations
+generator/SM
+generic/SM
+generically
+generosity/SM
+generous/PY
+generousness/M
+genes/S
+genesis/M
+genetic/S
+genetically
+geneticist/MS
+genetics/M
+genial/FY
+geniality/FM
+geniculate
+genie/SM
+genii
+genital/FY
+genitalia/M
+genitals/M
+genitive/MS
+genitourinary
+genius/MS
+genned
+genning
+genocidal
+genocide/MS
+genome/MS
+genomics
+genre/SM
+gent/AMS
+genteel/YP
+genteelness/M
+gentian/SM
+gentile/SM
+gentility/M
+gentle/TGDRSP
+gentlefolk/MS
+gentlefolks/M
+gentleman/MY
+gentlemanly/U
+gentlemen
+gentleness/M
+gentlewoman/M
+gentlewomen
+gently
+gentrification/M
+gentrify/DSGN
+gentry/SM
+genuflect/DGS
+genuflection/MS
+genuine/PY
+genuineness/M
+genus/M
+geocache/DSG
+geocentric
+geocentrically
+geochemistry/M
+geode/SM
+geodesic/SM
+geodesy/M
+geodetic
+geoengineering
+geog
+geographer/SM
+geographic
+geographical/Y
+geography/SM
+geologic
+geological/Y
+geologist/MS
+geology/SM
+geom
+geomagnetic
+geomagnetism/M
+geometer
+geometric
+geometrical/Y
+geometry/SM
+geophysical
+geophysicist/SM
+geophysics/M
+geopolitical
+geopolitics/M
+geostationary
+geosynchronous
+geosyncline/MS
+geothermal
+geothermic
+geranium/MS
+gerbil/MS
+geriatric/S
+geriatrician/S
+geriatrics/M
+germ/MS
+germane
+germanium/M
+germicidal
+germicide/MS
+germinal/M
+germinate/GNDS
+germination/M
+gerontological
+gerontologist/MS
+gerontology/M
+gerrymander/GMDS
+gerrymandering/M
+gerund/MS
+gestalt/S
+gestapo/MS
+gestate/GNDS
+gestation/M
+gestational
+gesticulate/DSGNX
+gesticulation/M
+gestural
+gesture/MGDS
+gesundheit
+get/S
+getaway/SM
+getting
+getup/M
+gewgaw/SM
+geyser/SM
+ghastliness/M
+ghastly/TPR
+ghat/MS
+ghee
+gherkin/MS
+ghetto/SM
+ghettoize/GDS
+ghost/SMDYG
+ghostliness/M
+ghostly/RTP
+ghostwrite/ZGRS
+ghostwriter/M
+ghostwritten
+ghostwrote
+ghoul/SM
+ghoulish/YP
+ghoulishness/M
+giant/SM
+giantess/MS
+gibber/GDS
+gibberish/M
+gibbet/GMDS
+gibbon/MS
+gibbous
+gibe/MGDS
+giblet/SM
+giddily
+giddiness/M
+giddy/RTP
+gift/MDGS
+gig/SM
+gigabit/SM
+gigabyte/MS
+gigagram/S
+gigahertz/M
+gigajoule/S
+gigameter/S
+gigantic
+gigantically
+gigapascal/S
+gigapixel/MS
+gigawatt/SM
+gigged
+gigging
+giggle/DRSMZG
+giggler/M
+giggly/RT
+gigolo/SM
+gild/MDRZGS
+gilder/M
+gilding/M
+gill/MS
+gillie/S
+gillion/S
+gilt/MS
+gimbals/M
+gimcrack/SM
+gimcrackery/M
+gimlet/GSMD
+gimme/SM
+gimmick/MS
+gimmickry/M
+gimmicky
+gimp/MDGS
+gimpy
+gin/SM
+ginger/GSMDY
+gingerbread/M
+gingersnap/SM
+gingery
+gingham/M
+gingivitis/M
+ginkgo/SM
+ginkgoes
+ginned
+ginning
+ginormous
+ginseng/M
+giraffe/MS
+gird/DRZGS
+girder/M
+girdle/DSMG
+girl/MS
+girlfriend/MS
+girlhood/SM
+girlie
+girlish/YP
+girlishness/M
+girly/S
+giro/S
+girt/MDGS
+girth/M
+girths
+gist/M
+git/S
+gite/S
+give/ZGJRS
+giveaway/MS
+giveback/MS
+given/SM
+giver/M
+gizmo/SM
+gizzard/MS
+glace/S
+glaceed
+glaceing
+glacial/Y
+glaciate/XGNDS
+glaciation/M
+glacier/MS
+glac辿/SDG
+glad/MYSP
+gladden/GDS
+gladder
+gladdest
+glade/SM
+gladiator/SM
+gladiatorial
+gladiola/SM
+gladioli
+gladiolus/M
+gladness/M
+gladsome
+glam
+glamor/SGMD
+glamorization/M
+glamorize/DSG
+glamorous/Y
+glamour/GMDS
+glance/DSMG
+gland/SM
+glandes
+glandular
+glans/M
+glare/DSMG
+glaring/Y
+glasnost/M
+glass/MDSG
+glassblower/MS
+glassblowing/M
+glassful/SM
+glasshouse/S
+glassily
+glassiness/M
+glassware/M
+glassy/RTP
+glaucoma/M
+glaze/DSMG
+glazier/SM
+glazing/M
+gleam/SMDGJ
+glean/SDRZGJ
+gleaner/M
+gleanings/M
+glee/M
+gleeful/YP
+gleefulness/M
+glen/MS
+glenohumeral
+glenoid
+glib/YP
+glibber
+glibbest
+glibness/M
+glide/DRSMZG
+glider/M
+gliding/M
+glimmer/MDGJS
+glimmering/M
+glimpse/MGDS
+glint/SMDG
+glissandi
+glissando/M
+glisten/MDSG
+glister/DSG
+glitch/GMDS
+glitter/MDSG
+glitterati
+glittery
+glitz/M
+glitzy/TR
+gloaming/SM
+gloat/SMDG
+gloating/Y
+glob/MDGS
+global/Y
+globalism/M
+globalist/MS
+globalization/M
+globalize/GDS
+globe/SM
+globetrotter/MS
+globetrotting
+globular
+globule/MS
+globulin/M
+glockenspiel/SM
+gloom/M
+gloomily
+gloominess/M
+gloomy/TRP
+glop/M
+gloppy
+glorification/M
+glorify/GDSN
+glorious/IY
+glory/DSMG
+gloss/MDSG
+glossary/SM
+glossily
+glossiness/M
+glossolalia/M
+glossy/PTRSM
+glottal
+glottis/MS
+glove/DSMG
+glow/MDRZGS
+glower/GMD
+glowing/Y
+glowworm/MS
+glucagon
+glucose/M
+glue/MGDS
+glued/U
+gluey
+gluier
+gluiest
+glum/YP
+glummer
+glummest
+glumness/M
+gluon/S
+glut/MNS
+gluten/M
+glutenous
+glutinous/Y
+glutted
+glutting
+glutton/MS
+gluttonous/Y
+gluttony/M
+glycerin/M
+glycerine/M
+glycerol/M
+glycogen/M
+glycol
+glyph
+gm
+gnarl/SMDG
+gnarly/TR
+gnash/MDSG
+gnat/MS
+gnaw/DGS
+gneiss/M
+gnocchi
+gnome/SM
+gnomic
+gnomish
+gnu/SM
+go/JMRHZG
+goad/MDGS
+goal/MS
+goalie/SM
+goalkeeper/MS
+goalkeeping/M
+goalless
+goalmouth
+goalmouths
+goalpost/MS
+goalscorer/S
+goaltender/MS
+goat/MS
+goatee/SM
+goatherd/MS
+goatskin/MS
+gob/SM
+gobbed
+gobbet/SM
+gobbing
+gobble/DRSMZG
+gobbledygook/M
+gobbler/M
+goblet/SM
+goblin/SM
+gobsmacked
+gobstopper/S
+god/SM
+godawful
+godchild/M
+godchildren/M
+goddam/D
+goddammit
+goddamn/D
+goddaughter/MS
+goddess/MS
+godfather/SM
+godforsaken
+godhead/M
+godhood/M
+godless/PY
+godlessness/M
+godlike
+godliness/UM
+godly/URTP
+godmother/SM
+godparent/SM
+godsend/SM
+godson/SM
+godspeed
+goer/M
+goes
+gofer/SM
+goggle/DSMG
+goggles/M
+going/M
+goiter/SM
+gold/MNS
+goldbrick/ZGSMDR
+goldbricker/M
+golden/TR
+goldenrod/M
+goldfield/S
+goldfinch/MS
+goldfish/MS
+goldmine/SM
+goldsmith/M
+goldsmiths
+golf/MDRZGS
+golfer/M
+golliwog/S
+golly/SM
+gonad/SM
+gonadal
+gondola/MS
+gondolier/SM
+gone/ZR
+goner/M
+gong/MDGS
+gonk/S
+gonna
+gonorrhea/M
+gonorrheal
+gonzo
+goo/M
+goober/SM
+good/MYSP
+goodby/M
+goodbye/MS
+goodbys
+goodhearted
+goodie/M
+goodish
+goodly/TR
+goodness/M
+goodnight
+goods/M
+goodwill/M
+goody/SM
+gooey
+goof/MDGS
+goofball/SM
+goofiness/M
+goofy/RPT
+google/DSMG
+googly/S
+gooier
+gooiest
+gook/MS
+goon/MS
+goop/M
+goose/DSMG
+gooseberry/SM
+goosebumps/M
+gooseflesh/M
+goosestep/S
+goosestepped
+goosestepping
+gopher/SM
+gore/MGDS
+gorge's
+gorge/EDSG
+gorgeous/YP
+gorgeousness/M
+gorgon/SM
+gorilla/MS
+gorily
+goriness/M
+gormandize/DRSZG
+gormandizer/M
+gormless
+gorp/MS
+gorse/M
+gory/RTP
+gosh
+goshawk/MS
+gosling/SM
+gospel/MS
+gossamer/M
+gossip/MDRZGS
+gossiper/M
+gossipy
+got
+gotcha/S
+goths
+gotta
+gotten
+gouache/S
+gouge/DRSMZG
+gouger/M
+goulash/MS
+gourd/SM
+gourde/MS
+gourmand/SM
+gourmet/SM
+gout/M
+gouty/TR
+gov
+govern/DGSBL
+governable/U
+governance/M
+governed/U
+governess/MS
+government/MS
+governmental
+governor/SM
+governorship/M
+govt
+gown/MDGS
+gr
+grab/MS
+grabbed
+grabber/MS
+grabbing
+grabby/TR
+grace/EDSMG
+graceful/EPY
+gracefulness/EM
+graceless/PY
+gracelessness/M
+gracious/UY
+graciousness/M
+grackle/MS
+grad/MRZSB
+gradate/XGNDS
+gradation/CM
+grade's
+grade/CADSG
+graded/U
+grader/M
+gradient/MS
+gradual/PY
+gradualism/M
+gradualness/M
+graduate/XMGNDS
+graduation/M
+graffiti
+graffito/M
+graft/SMDRZG
+grafter/M
+graham/S
+grail
+grain/ISMD
+graininess/M
+grainy/PTR
+gram/KMS
+grammar/MS
+grammarian/SM
+grammatical/UY
+gramophone/MS
+grampus/MS
+gran/S
+granary/SM
+grand/SMRYPT
+grandad/MS
+grandam/MS
+grandaunt/MS
+grandchild/M
+grandchildren/M
+granddad/SM
+granddaddy/SM
+granddaughter/SM
+grandee/MS
+grandeur/M
+grandfather/GMDYS
+grandiloquence/M
+grandiloquent
+grandiose/Y
+grandiosity/M
+grandma/MS
+grandmother/MYS
+grandnephew/MS
+grandness/M
+grandniece/MS
+grandpa/MS
+grandparent/MS
+grandson/MS
+grandstand/SGMD
+granduncle/SM
+grange/SM
+granite/M
+granitic
+grannie/M
+granny/SM
+granola/M
+grant/SMDRZG
+grantee/MS
+granter/M
+grantsmanship/M
+granular
+granularity/M
+granulate/GNDS
+granulation/M
+granule/MS
+grape/SM
+grapefruit/MS
+grapeshot/M
+grapevine/SM
+graph/MDG
+graphic/MS
+graphical/Y
+graphite/M
+graphologist/MS
+graphology/M
+graphs
+grapnel/MS
+grapple/MGDS
+grasp/SMDBG
+grass/MDSG
+grasshopper/MS
+grassland/MS
+grassroots
+grassy/TR
+grate/DRSMZGJ
+grateful/UYP
+gratefulness/UM
+grater/M
+gratification/M
+gratify/GNXDS
+gratifying/Y
+gratin/S
+grating/MY
+gratis
+gratitude/IM
+gratuitous/YP
+gratuitousness/M
+gratuity/SM
+gravamen/MS
+grave/DRSMYTGP
+gravedigger/SM
+gravel/SGMDY
+graven
+graveness/M
+graveside/MS
+gravestone/SM
+graveyard/MS
+gravid
+gravimeter/MS
+gravitas
+gravitate/GNDS
+gravitation/M
+gravitational
+gravity/M
+gravy/SM
+gray/MDRTGSP
+graybeard/SM
+grayish
+grayness/M
+graze/DRSMZG
+grazer/M
+grease/DRSMZG
+greasepaint/M
+greasily
+greasiness/M
+greasy/PTR
+great/SMRYPT
+greatcoat/SM
+greathearted
+greatness/M
+grebe/SM
+greed/M
+greedily
+greediness/M
+greedy/PTR
+green/GPSMDRYT
+greenback/MS
+greenbelt/MS
+greenery/M
+greenfield
+greenfly/S
+greengage/MS
+greengrocer/SM
+greenhorn/SM
+greenhouse/SM
+greenish
+greenmail/M
+greenness/M
+greenroom/SM
+greenstone
+greensward/M
+greenwood/M
+greet/ZGJSDR
+greeter/M
+greeting/M
+gregarious/PY
+gregariousness/M
+gremlin/SM
+grenade/SM
+grenadier/MS
+grenadine/M
+grep/S
+grepped
+grepping
+grew/A
+greyhound/SM
+gribble/S
+grid/MS
+griddle/SM
+griddlecake/SM
+gridiron/SM
+gridlock/SMD
+grief/SM
+grievance/MS
+grieve/ZGDRS
+griever/M
+grievous/PY
+grievousness/M
+griffin/SM
+griffon/SM
+grill/SGMDJ
+grille/MS
+grim/DYPG
+grimace/DSMG
+grime/SM
+griminess/M
+grimmer
+grimmest
+grimness/M
+grimy/TRP
+grin/MS
+grind/SZGMRJ
+grinder/M
+grindstone/MS
+gringo/MS
+grinned
+grinning
+grip/MDRSZG
+gripe/SM
+griper/M
+grippe/MZGDR
+gripper/M
+grisliness/M
+grisly/RTP
+grist/MY
+gristle/M
+gristmill/MS
+grit/MS
+grits/M
+gritted
+gritter/SM
+grittiness/M
+gritting
+gritty/RTP
+grizzle/DSG
+grizzly/TRSM
+groan/SGMD
+groat/SM
+grocer/MS
+grocery/SM
+grog/M
+groggily
+grogginess/M
+groggy/PRT
+groin/SM
+grok/S
+grokked
+grokking
+grommet/SM
+groom/SZGMDR
+groomer/M
+grooming/M
+groomsman/M
+groomsmen
+groove/MGDS
+groovy/RT
+grope/DRSMZG
+groper/M
+grosbeak/MS
+grosgrain/M
+gross/PTGMDRSY
+grossness/M
+grotesque/SPMY
+grotesqueness/M
+grotto/M
+grottoes
+grotty/TR
+grouch/GMDS
+grouchily
+grouchiness/M
+grouchy/RTP
+ground/ZGMDRJS
+groundbreaking/MS
+groundcloth
+groundcloths
+grounder/M
+groundhog/MS
+grounding/M
+groundless/Y
+groundnut/MS
+groundsheet/S
+groundskeeper/S
+groundsman
+groundsmen
+groundswell/SM
+groundwater/M
+groundwork/M
+group/JSZGMDR
+grouper/M
+groupie/MS
+grouping/M
+groupware/M
+grouse/MZGDRS
+grouser/M
+grout/SGMD
+grove/SM
+grovel/ZGDRS
+groveler/M
+grovelled
+grovelling
+grow/AHSG
+grower/MS
+growing/I
+growl/SZGMDR
+growler/M
+grown/AI
+grownup/MS
+growth/AM
+growths
+grub/MS
+grubbed
+grubber/MS
+grubbily
+grubbiness/M
+grubbing
+grubby/TRP
+grubstake/M
+grudge/MGDS
+grudging/Y
+grue/S
+gruel/GJM
+grueling/Y
+gruesome/RYTP
+gruesomeness/M
+gruff/TPRY
+gruffness/M
+grumble/DRSMZGJ
+grumbler/M
+grump/SM
+grumpily
+grumpiness/M
+grumpy/PRT
+grunge/MS
+grungy/RT
+grunion/SM
+grunt/SGMD
+gt
+guacamole/M
+guanine/M
+guano/M
+guarani/MS
+guaranies
+guarantee/MDS
+guaranteeing
+guarantor/MS
+guaranty/GDSM
+guard/SZGMDR
+guarded/Y
+guarder/M
+guardhouse/SM
+guardian/SM
+guardianship/M
+guardrail/SM
+guardroom/SM
+guardsman/M
+guardsmen
+guava/SM
+gubernatorial
+guerilla/SM
+guerrilla/SM
+guess/ZGBMDRS
+guesser/M
+guesstimate/DSMG
+guesswork/M
+guest/SGMD
+guestbook/SM
+guesthouse/S
+guestroom/S
+guff/M
+guffaw/MDGS
+guidance/M
+guide/DRSMZG
+guidebook/SM
+guided/U
+guideline/SM
+guidepost/SM
+guider/M
+guild/SZMR
+guilder/M
+guildhall/MS
+guile/M
+guileful
+guileless/YP
+guilelessness/M
+guillemot/S
+guillotine/DSMG
+guilt/M
+guiltily
+guiltiness/M
+guiltless
+guilty/PRT
+guinea/MS
+guise/ESM
+guitar/MS
+guitarist/SM
+gulag/SM
+gulch/MS
+gulden/MS
+gulf/MS
+gull/MDSG
+gullet/MS
+gullibility/M
+gullible
+gully/SM
+gulp/MDRSZG
+gulper/M
+gum/SM
+gumball/S
+gumbo/SM
+gumboil/SM
+gumboot/S
+gumdrop/SM
+gummed
+gumming
+gummy/TR
+gumption/M
+gumshoe/MDS
+gumshoeing
+gun/SM
+gunboat/SM
+gunfight/MRZS
+gunfighter/M
+gunfire/M
+gunge
+gungy
+gunk/M
+gunky
+gunman/M
+gunmen
+gunmetal/M
+gunned
+gunnel/MS
+gunner/MS
+gunnery/M
+gunning
+gunny/M
+gunnysack/MS
+gunpoint/M
+gunpowder/M
+gunrunner/MS
+gunrunning/M
+gunship/MS
+gunshot/MS
+gunslinger/SM
+gunsmith/M
+gunsmiths
+gunwale/MS
+guppy/SM
+gurgle/MGDS
+gurney/MS
+guru/MS
+gush/MDRSZG
+gusher/M
+gushing/Y
+gushy/TR
+gusset/MSDG
+gussy/DSG
+gust/EMDSG
+gustatory
+gustily
+gusto/M
+gusty/RT
+gut/SM
+gutless/P
+gutlessness/M
+gutsy/RT
+gutted
+gutter/SMDG
+guttersnipe/MS
+gutting
+guttural/MS
+gutty/RT
+guv/S
+guvnor/S
+guy/SGMD
+guzzle/DRSZG
+guzzler/M
+gym/SM
+gymkhana/MS
+gymnasium/MS
+gymnast/MS
+gymnastic/S
+gymnastically
+gymnastics/M
+gymnosperm/SM
+gymslip/S
+gynecologic
+gynecological
+gynecologist/SM
+gynecology/M
+gyp/SM
+gypped
+gypper/SM
+gypping
+gypster/SM
+gypsum/M
+gypsy/SM
+gyrate/DSGNX
+gyration/M
+gyrator/SM
+gyrfalcon/MS
+gyro/MS
+gyroscope/MS
+gyroscopic
+gyve/MGDS
+h'm
+h/NRSXZGVJ
+ha/SH
+haberdasher/SM
+haberdashery/SM
+habiliment/SM
+habit's
+habit/ISB
+habitability/M
+habitat/SM
+habitation/MS
+habitual/YP
+habitualness/M
+habituate/GNDS
+habituation/M
+habitue/SM
+habitu辿/SM
+hacienda/SM
+hack/MDRZGS
+hacker/M
+hacking/M
+hackish
+hackle/MS
+hackney/SMDG
+hacksaw/SM
+hacktivist/MS
+hackwork/M
+had
+haddock/SM
+hadith
+hadn't
+hadst
+hafnium/M
+haft/MS
+hag/SM
+haggard/YP
+haggardness/M
+haggis/MS
+haggish
+haggle/MZGDRS
+haggler/M
+hagiographer/SM
+hagiography/SM
+hah
+hahnium/M
+haiku/M
+hail/MDGS
+hailstone/MS
+hailstorm/MS
+hair/MDS
+hairball/MS
+hairband/S
+hairbreadth/M
+hairbreadths
+hairbrush/MS
+haircloth/M
+haircut/SM
+hairdo/MS
+hairdresser/SM
+hairdressing/M
+hairdrier/MS
+hairdryer/MS
+hairgrip/S
+hairiness/M
+hairless
+hairlike
+hairline/SM
+hairnet/SM
+hairpiece/MS
+hairpin/SM
+hairsbreadth/M
+hairsbreadths
+hairsplitter/SM
+hairsplitting/M
+hairspray/S
+hairspring/MS
+hairstyle/MS
+hairstylist/SM
+hairy/TRP
+haj
+hajj/M
+hajjes
+hajji/SM
+hake/MS
+halal/M
+halberd/SM
+halcyon
+hale/ITGDRS
+half/M
+halfback/SM
+halfhearted/PY
+halfheartedness/M
+halfpence
+halfpenny/SM
+halftime/MS
+halftone/MS
+halfway
+halfwit/SM
+halibut/SM
+halite/M
+halitosis/M
+hall/MS
+hallelujah/M
+hallelujahs
+hallmark/GMDS
+halloo/MDSG
+hallow/DSG
+hallowed/U
+hallucinate/GNXDS
+hallucination/M
+hallucinatory
+hallucinogen/SM
+hallucinogenic/SM
+hallway/SM
+halo/MDGS
+halogen/SM
+halon
+halt/MDRZGS
+halter/GMD
+halterneck/S
+halting/Y
+halve/DSG
+halyard/MS
+ham/SM
+hamburg/SZMR
+hamburger/M
+hamlet/MS
+hammed
+hammer/MDRSJZG
+hammerer/M
+hammerhead/SM
+hammerlock/SM
+hammertoe/MS
+hamming
+hammock/SM
+hammy/TR
+hamper/GMDS
+hampered/U
+hamster/MS
+hamstring/GSM
+hamstrung
+hand's
+hand/UDGS
+handbag/SM
+handball/MS
+handbarrow/SM
+handbill/MS
+handbook/MS
+handbrake/S
+handcar/SM
+handcart/MS
+handclasp/MS
+handcraft/SMDG
+handcuff/MDGS
+handed/P
+handful/SM
+handgun/SM
+handheld/MS
+handhold/MS
+handicap/MS
+handicapped
+handicapper/MS
+handicapping
+handicraft/MS
+handily
+handiness/M
+handiwork/M
+handkerchief/MS
+handle/MZGDRS
+handlebar/MS
+handler/M
+handmade
+handmaid/XMNS
+handmaiden/M
+handout/SM
+handover/S
+handpick/GDS
+handrail/MS
+handsaw/SM
+handset/SM
+handshake/JMGS
+handsome/PYTR
+handsomeness/M
+handspring/MS
+handstand/SM
+handwork/M
+handwoven
+handwriting/M
+handwritten
+handy/UTR
+handyman/M
+handymen
+hang/MDRJZGS
+hangar/MS
+hangdog
+hanger/M
+hanging/M
+hangman/M
+hangmen
+hangnail/MS
+hangout/SM
+hangover/MS
+hangup/MS
+hank/MRZS
+hanker/GJD
+hankering/M
+hankie/M
+hanky/SM
+hansom/MS
+hap/MY
+haphazard/YP
+haphazardness/M
+hapless/YP
+haplessness/M
+haploid/MS
+happen/SDGJ
+happening/M
+happenstance/SM
+happily/U
+happiness/UM
+happy/URTP
+haptic
+harangue/MGDS
+harass/LZGDRS
+harasser/M
+harassment/M
+harbinger/SM
+harbor/GMDS
+harbormaster/S
+hard/NRYXTP
+hardback/MS
+hardball/M
+hardboard/M
+hardbound
+hardcore
+hardcover/SM
+harden/ZGDR
+hardened/U
+hardener/M
+hardhat/MS
+hardheaded/PY
+hardheadedness/M
+hardhearted/PY
+hardheartedness/M
+hardihood/M
+hardily
+hardiness/M
+hardliner/MS
+hardness/M
+hardscrabble
+hardship/SM
+hardstand/SM
+hardtack/M
+hardtop/SM
+hardware/M
+hardwired
+hardwood/SM
+hardworking
+hardy/PTR
+hare/MGDS
+harebell/MS
+harebrained
+harelip/SM
+harelipped
+harem/SM
+haricot/S
+hark/DGS
+harlequin/SM
+harlot/SM
+harlotry/M
+harm/MDGS
+harmed/U
+harmful/YP
+harmfulness/M
+harmless/PY
+harmlessness/M
+harmonic/SM
+harmonica/MS
+harmonically
+harmonies
+harmonious/PY
+harmoniousness/M
+harmonium/MS
+harmonization/M
+harmonize/ZGDRS
+harmonizer/M
+harmony/EM
+harness's
+harness/UDSG
+harp/MDGS
+harpist/SM
+harpoon/ZGSMDR
+harpooner/M
+harpsichord/MS
+harpsichordist/SM
+harpy/SM
+harridan/MS
+harrier/M
+harrow/SMDG
+harrumph/GD
+harrumphs
+harry/DRSZG
+harsh/RYTP
+harshness/M
+hart/MS
+harvest/SMDRZG
+harvested/U
+harvester/M
+hash/AMDSG
+hashish/M
+hashtag/SM
+hasn't
+hasp/MS
+hassle/DSMG
+hassock/SM
+hast/DNXG
+haste/SM
+hasten/DG
+hastily
+hastiness/M
+hasty/RTP
+hat/ZGSMDR
+hatband/S
+hatbox/MS
+hatch/MDSG
+hatchback/MS
+hatcheck/SM
+hatched/U
+hatchery/SM
+hatchet/SM
+hatching/M
+hatchway/SM
+hate/MS
+hateful/PY
+hatefulness/M
+hatemonger/MS
+hater/M
+hatpin/S
+hatred/SM
+hatstand/S
+hatted
+hatter/SM
+hatting
+hauberk/SM
+haughtily
+haughtiness/M
+haughty/PRT
+haul/MDRZGS
+haulage/M
+hauler/M
+haulier/S
+haunch/MS
+haunt/SMDRZG
+haunter/M
+haunting/Y
+hauteur/M
+have/MGS
+haven't
+haven/SM
+haversack/SM
+havoc/M
+haw/GSMD
+hawk/MDRZGS
+hawker/M
+hawkish/P
+hawkishness/M
+hawser/SM
+hawthorn/MS
+hay/GSMD
+haycock/SM
+hayloft/SM
+haymaker/S
+haymaking
+haymow/SM
+hayrick/MS
+hayride/MS
+hayseed/MS
+haystack/SM
+haywire
+hazard/SMDG
+hazardous/Y
+haze/MZGJDRS
+hazel/SM
+hazelnut/MS
+hazer/M
+hazily
+haziness/M
+hazing/M
+hazmat
+hazy/RTP
+hdqrs
+he'd
+he'll
+he/M
+head/MDRZGJS
+headache/MS
+headband/MS
+headbanger/S
+headbanging
+headboard/SM
+headbutt/DSG
+headcase/S
+headcheese
+headcount/S
+headdress/MS
+header/M
+headfirst
+headgear/M
+headhunt/DRSZG
+headhunter/M
+headhunting/M
+headily
+headiness/M
+heading/M
+headlamp/MS
+headland/MS
+headless
+headlight/MS
+headline/MZGDRS
+headliner/M
+headlock/MS
+headlong
+headman/M
+headmaster/SM
+headmen
+headmistress/MS
+headphone/MS
+headpiece/MS
+headpin/SM
+headquarter/SDG
+headquarters/M
+headrest/MS
+headroom/M
+headscarf
+headscarves
+headset/SM
+headship/SM
+headshrinker/SM
+headsman/M
+headsmen
+headstall/SM
+headstand/SM
+headstone/SM
+headstrong
+headteacher/S
+headwaiter/SM
+headwaters/M
+headway/M
+headwind/SM
+headword/SM
+heady/RTP
+heal/DRHZGS
+healed/U
+healer/M
+health/M
+healthcare
+healthful/PY
+healthfulness/M
+healthily/U
+healthiness/UM
+healthy/UTRP
+heap/MDGS
+hear/AHGJS
+heard/AU
+hearer/SM
+hearing/AM
+hearken/SGD
+hearsay/M
+hearse's
+hearse/AS
+heart/SM
+heartache/MS
+heartbeat/MS
+heartbreak/SMG
+heartbroken
+heartburn/M
+hearten/ESGD
+heartfelt
+hearth/M
+hearthrug/S
+hearths
+hearthstone/SM
+heartily
+heartiness/M
+heartland/MS
+heartless/PY
+heartlessness/M
+heartrending/Y
+heartsick/P
+heartsickness/M
+heartstrings/M
+heartthrob/MS
+heartwarming
+heartwood/M
+hearty/RSMPT
+heat's
+heat/ADGS
+heated/U
+heatedly
+heater/SM
+heath/MNRX
+heathen/M
+heathendom/M
+heathenish
+heathenism/M
+heather/M
+heaths
+heating/M
+heatproof
+heatstroke/M
+heatwave/S
+heave/DRSMZG
+heaven/SMY
+heavenly/TR
+heavens/M
+heavenward/S
+heaver/M
+heavily
+heaviness/M
+heavy/RSMTP
+heavyhearted
+heavyset
+heavyweight/MS
+heck/M
+heckle/DRSMZG
+heckler/M
+heckling/M
+hectare/SM
+hectic
+hectically
+hectogram/SM
+hectometer/MS
+hector/SMDG
+hedge/DRSMZG
+hedgehog/MS
+hedgehop/S
+hedgehopped
+hedgehopping
+hedger/M
+hedgerow/SM
+hedonism/M
+hedonist/MS
+hedonistic
+heed/MDGS
+heeded/U
+heedful/Y
+heedless/PY
+heedlessness/M
+heehaw/SMDG
+heel/MDGS
+heelless
+heft/MDGS
+heftily
+heftiness/M
+hefty/PRT
+hegemonic
+hegemony/M
+hegira/SM
+heifer/SM
+height/XSMN
+heighten/DG
+heinous/YP
+heinousness/M
+heir/MS
+heiress/MS
+heirloom/SM
+heist/SMDG
+held
+helical
+helices
+helicopter/SGMD
+heliocentric
+heliotrope/SM
+helipad/S
+heliport/MS
+helium/M
+helix/M
+hell/M
+hellbent
+hellcat/MS
+hellebore/M
+hellfire
+hellhole/MS
+hellion/MS
+hellish/YP
+hellishness/M
+hello/SM
+helluva
+helm/MS
+helmet/SMD
+helmsman/M
+helmsmen
+helot/SM
+help/MDRZGSJ
+helper/M
+helpful/UY
+helpfulness/M
+helping/M
+helpless/PY
+helplessness/M
+helpline/SM
+helpmate/SM
+helve/SM
+hem/SM
+hematite/M
+hematologic
+hematological
+hematologist/MS
+hematology/M
+heme/M
+hemiplegia
+hemisphere/SM
+hemispheric
+hemispherical
+hemline/SM
+hemlock/SM
+hemmed
+hemmer/SM
+hemming
+hemoglobin/M
+hemophilia/M
+hemophiliac/MS
+hemorrhage/MGDS
+hemorrhagic
+hemorrhoid/MS
+hemostat/MS
+hemp/MN
+hemstitch/MDSG
+hen/M
+hence
+henceforth
+henceforward
+henchman/M
+henchmen
+henna/SMDG
+henpeck/GSD
+hep
+heparin/M
+hepatic
+hepatitis/M
+hepatocyte/S
+hepper
+heppest
+heptagon/MS
+heptagonal
+heptathlon/SM
+herald/SMDG
+heralded/U
+heraldic
+heraldry/M
+herb/MS
+herbaceous
+herbage/M
+herbal/S
+herbalist/MS
+herbicidal
+herbicide/MS
+herbivore/SM
+herbivorous
+herculean
+herd/MDRZGS
+herder/M
+herdsman/M
+herdsmen
+here/M
+hereabout/S
+hereafter/SM
+hereby
+hereditary
+heredity/M
+herein
+hereinafter
+hereof
+hereon
+heresy/SM
+heretic/SM
+heretical
+hereto
+heretofore
+hereunder
+hereunto
+hereupon
+herewith
+heritable/I
+heritage/MS
+hermaphrodite/SM
+hermaphroditic
+hermetic
+hermetical/Y
+hermit/SM
+hermitage/MS
+hermitian
+hernia/SM
+hernial
+herniate/GNDS
+herniation/M
+hero/M
+heroes
+heroic/S
+heroically
+heroics/M
+heroin/SM
+heroine/SM
+heroism/M
+heron/SM
+herpes/M
+herpetologist/SM
+herpetology/M
+herring/MS
+herringbone/M
+herself
+hertz/M
+hesitance/M
+hesitancy/M
+hesitant/Y
+hesitate/DSGNX
+hesitating/UY
+hesitation/M
+hessian
+hetero/SM
+heterodox
+heterodoxy/M
+heterogeneity/M
+heterogeneous/Y
+heterosexual/MYS
+heterosexuality/M
+heuristic/MS
+heuristically
+heuristics/M
+hew/ZGSDR
+hewer/M
+hex/GMDS
+hexadecimal/S
+hexagon/MS
+hexagonal
+hexagram/SM
+hexameter/SM
+hey
+heyday/SM
+hf
+hgt
+hgwy
+hi/SD
+hiatus/MS
+hibachi/MS
+hibernate/GNDS
+hibernation/M
+hibernator/MS
+hibiscus/MS
+hiccough/DG
+hiccoughs
+hiccup/GSMD
+hick/MS
+hickey/SM
+hickory/SM
+hid
+hidden
+hide/MZGJDRS
+hideaway/SM
+hidebound
+hideous/YP
+hideousness/M
+hideout/MS
+hider/M
+hiding/M
+hie/S
+hieing
+hierarchic
+hierarchical/Y
+hierarchy/SM
+hieroglyph/M
+hieroglyphic/MS
+hieroglyphs
+high/MRYZTP
+highball/SM
+highborn
+highboy/MS
+highbrow/SM
+highchair/MS
+highfalutin
+highhanded/PY
+highhandedness/M
+highland/MRZS
+highlander/M
+highlight/SMDRZG
+highlighter/M
+highness/M
+highroad/MS
+highs
+hightail/DSG
+highway/MS
+highwayman/M
+highwaymen
+hijab/SM
+hijack/SJZGMDR
+hijacker/M
+hijacking/M
+hike/MZGDRS
+hiker/M
+hiking/M
+hilarious/PY
+hilariousness/M
+hilarity/M
+hill/MS
+hillbilly/SM
+hilliness/M
+hillock/MS
+hillside/SM
+hilltop/MS
+hilly/PRT
+hilt/MS
+him/S
+himself
+hind/MRZS
+hinder/GD
+hindered/U
+hindmost
+hindquarter/MS
+hindrance/SM
+hindsight/M
+hinge's
+hinge/UDSG
+hint/MDRZGS
+hinter/M
+hinterland/SM
+hip/SPM
+hipbath
+hipbaths
+hipbone/MS
+hiphuggers
+hipness/M
+hipped
+hipper
+hippest
+hippie/M
+hipping
+hippo/SM
+hippocampus
+hippodrome/SM
+hippopotamus/MS
+hippy/SM
+hipster/MS
+hiragana
+hire's
+hire/AGDS
+hireling/MS
+hirsute/P
+hirsuteness/M
+hiss/MDSG
+hist
+histamine/MS
+histogram/MS
+histologist/SM
+histology/M
+histopathology
+historian/MS
+historic
+historical/Y
+historicity/M
+historiographer/MS
+historiography/M
+history/SM
+histrionic/S
+histrionically
+histrionics/M
+hit/SM
+hitch's
+hitch/UDSG
+hitcher/MS
+hitchhike/DRSMZG
+hitchhiker/M
+hither
+hitherto
+hitter/SM
+hitting
+hive/MGDS
+hivemind/SM
+hiya
+hm
+hmm
+ho/SMDRYZ
+hoagie/MS
+hoard/SZGMDRJ
+hoarder/M
+hoarding/M
+hoarfrost/M
+hoariness/M
+hoarse/YTRP
+hoarseness/M
+hoary/TRP
+hoax/MDRSZG
+hoaxer/M
+hob/SM
+hobbit/S
+hobble/MZGDRS
+hobbler/M
+hobby/SM
+hobbyhorse/MS
+hobbyist/SM
+hobgoblin/MS
+hobnail/SGMD
+hobnob/S
+hobnobbed
+hobnobbing
+hobo/MS
+hoboes
+hoc
+hock/MDSG
+hockey/M
+hockshop/MS
+hod/SM
+hodgepodge/SM
+hoe/SM
+hoecake/SM
+hoedown/SM
+hoeing
+hoer/M
+hog/SM
+hogan/SM
+hogback/SM
+hogged
+hogging
+hoggish/Y
+hogshead/SM
+hogtie/DS
+hogtying
+hogwash/M
+hoick/SGD
+hoist/SGMD
+hoke/GDS
+hokey
+hokier
+hokiest
+hokum/M
+hold/MRJSZG
+holdall/S
+holder/M
+holding/M
+holdout/SM
+holdover/SM
+holdup/MS
+hole/MGDS
+holey
+holiday/SMDG
+holidaymaker/S
+holiness/UM
+holism
+holistic
+holistically
+holler/MDGS
+hollow/MDRYPSTG
+hollowness/M
+holly/SM
+hollyhock/MS
+holmium/M
+holocaust/SM
+hologram/MS
+holograph/M
+holographic
+holographs
+holography/M
+hols
+holster/SMDG
+holy/URPT
+homage/MS
+hombre/MS
+homburg/SM
+home/MYZGDRS
+homebody/SM
+homeboy/SM
+homecoming/SM
+homegrown
+homeland/MS
+homeless/MP
+homelessness/M
+homelike
+homeliness/M
+homely/PRT
+homemade
+homemaker/SM
+homemaking/M
+homeopath/M
+homeopathic
+homeopaths
+homeopathy/M
+homeostasis/M
+homeostatic
+homeowner/MS
+homepage/MS
+homer/GMD
+homeroom/MS
+homeschooling/M
+homesick/P
+homesickness/M
+homespun/M
+homestead/SMDRZG
+homesteader/M
+homestretch/MS
+hometown/MS
+homeward/S
+homework/MRZG
+homewrecker/SM
+homey/SMP
+homeyness/M
+homicidal
+homicide/MS
+homie/RSMT
+homiletic
+homily/SM
+hominess/M
+hominid/SM
+hominoid/S
+hominy/M
+homo/MS
+homoerotic
+homogeneity/M
+homogeneous/Y
+homogenization/M
+homogenize/DSG
+homograph/M
+homographs
+homologous
+homology
+homonym/SM
+homophobia/M
+homophobic
+homophone/MS
+homosexual/SM
+homosexuality/M
+hon/SZTGMDR
+honcho/MS
+hone/MS
+honer/M
+honest/EYT
+honester
+honesty/EM
+honey/SGMD
+honeybee/SM
+honeycomb/MDSG
+honeydew/SM
+honeylocust/M
+honeymoon/ZGMDRS
+honeymooner/M
+honeypot/S
+honeysuckle/SM
+honk/MDRSZG
+honker/M
+honkie/M
+honky/SM
+honor/ESGMDB
+honorableness/M
+honorably/E
+honorarily
+honorarium/MS
+honorary
+honoree/SM
+honorer/SM
+honorific/MS
+hooch/M
+hood/MDSG
+hoodie/MS
+hoodlum/SM
+hoodoo/MDSG
+hoodwink/DGS
+hooey/M
+hoof/MDRSZG
+hook's
+hook/UDSG
+hookah/M
+hookahs
+hooker/MS
+hookup/MS
+hookworm/MS
+hooky/M
+hooligan/MS
+hooliganism/M
+hoop/MDSG
+hoopla/M
+hooray/MS
+hoosegow/SM
+hoot/MDRSZG
+hootch/M
+hootenanny/SM
+hooter/M
+hoover/DSG
+hooves
+hop/SGMD
+hope/MS
+hopeful/PSMY
+hopefulness/M
+hopeless/YP
+hopelessness/M
+hopped
+hopper/MS
+hopping
+hopscotch/MDSG
+hora/MS
+horde/DSMG
+horehound/SM
+horizon/SM
+horizontal/SMY
+hormonal
+hormone/SM
+horn/MDS
+hornbeam
+hornblende/M
+hornet/MS
+hornless
+hornlike
+hornpipe/MS
+horny/TR
+horologic
+horological
+horologist/MS
+horology/M
+horoscope/SM
+horrendous/Y
+horrible/P
+horribleness/M
+horribly
+horrid/Y
+horrific
+horrifically
+horrify/DSG
+horrifying/Y
+horror/MS
+horse's
+horse/UDSG
+horseback/M
+horsebox/S
+horseflesh/M
+horsefly/SM
+horsehair/M
+horsehide/M
+horselaugh/M
+horselaughs
+horseless
+horseman/M
+horsemanship/M
+horsemen
+horseplay/M
+horsepower/M
+horseradish/MS
+horseshit/!
+horseshoe/DSM
+horseshoeing
+horsetail/SM
+horsetrading
+horsewhip/SM
+horsewhipped
+horsewhipping
+horsewoman/M
+horsewomen
+horsey
+horsy/TR
+hortatory
+horticultural
+horticulturalist/S
+horticulture/M
+horticulturist/MS
+hosanna/SM
+hose/MGDS
+hosepipe/S
+hosier/MS
+hosiery/M
+hosp
+hospholipase
+hospice/MS
+hospitable/I
+hospitably/I
+hospital/SM
+hospitality/M
+hospitalization/SM
+hospitalize/DSG
+host/MDSG
+hostage/MS
+hostel/ZGMDRS
+hosteler/M
+hostelry/SM
+hostess/MDSG
+hostile/MYS
+hostilities/M
+hostility/SM
+hostler/MS
+hot/SYP
+hotbed/MS
+hotblooded
+hotbox/MS
+hotcake/SM
+hotdog/MS
+hotdogged
+hotdogging
+hotel/SM
+hotelier/MS
+hotfoot/MDGS
+hothead/DSM
+hotheaded/YP
+hotheadedness/M
+hothouse/SM
+hotkey/S
+hotline/MS
+hotlink/S
+hotness/M
+hotplate/SM
+hotpot/S
+hots/M
+hotshot/MS
+hotted
+hotter
+hottest
+hottie/S
+hotting
+hound/SGMD
+hour/MYS
+hourglass/MS
+houri/SM
+house's
+house/ADSG
+houseboat/SM
+housebound
+houseboy/SM
+housebreak/RSZG
+housebreaker/M
+housebreaking/M
+housebroke
+housebroken
+houseclean/DSG
+housecleaning/M
+housecoat/SM
+housefly/SM
+houseful/SM
+household/SMRZ
+householder/M
+househusband/SM
+housekeeper/MS
+housekeeping/M
+houselights/M
+housemaid/SM
+houseman/M
+housemaster/S
+housemate/S
+housemen
+housemistress/S
+housemother/SM
+houseparent/SM
+houseplant/MS
+houseproud
+houseroom
+housetop/SM
+housewares/M
+housewarming/SM
+housewife/MY
+housewives
+housework/M
+housing/MS
+hove
+hovel/SM
+hover/SGD
+hoverboard/MS
+hovercraft/MS
+how'd
+how're
+how/SM
+howbeit
+howdah/M
+howdahs
+howdy
+however
+howitzer/SM
+howl/MDRSZG
+howler/M
+howsoever
+hoyden/MS
+hoydenish
+hp
+hr/S
+ht
+huarache/SM
+hub/SM
+hubbub/SM
+hubby/SM
+hubcap/SM
+hubris/M
+huckleberry/SM
+huckster/SGMD
+hucksterism/M
+huddle/DSMG
+hue/DSM
+huff/MDSG
+huffily
+huffiness/M
+huffy/PRT
+hug/STMR
+huge/YP
+hugeness/M
+hugged
+hugging
+huh
+hula/MS
+hulk/MSG
+hull/MDRSZG
+hullabaloo/SM
+huller/M
+hum/SM
+human/SMRYTP
+humane/PY
+humaneness/M
+humanism/M
+humanist/SM
+humanistic
+humanitarian/MS
+humanitarianism/M
+humanities/M
+humanity/ISM
+humanization/CM
+humanize/CDSG
+humanizer/SM
+humankind/M
+humanness/M
+humanoid/SM
+humble/DRSZTGJP
+humbleness/M
+humbler/M
+humbly
+humbug/SM
+humbugged
+humbugging
+humdinger/MS
+humdrum/M
+humeral
+humeri
+humerus/M
+humid/Y
+humidification/M
+humidifier/CM
+humidify/CZGDRS
+humidity/M
+humidor/SM
+humiliate/DSGNX
+humiliating/Y
+humiliation/M
+humility/M
+hummed
+hummer/SM
+humming
+hummingbird/SM
+hummock/SM
+hummocky
+hummus/M
+humongous
+humor/SMDG
+humoresque
+humorist/MS
+humorless/YP
+humorlessness/M
+humorous/PY
+humorousness/M
+hump/MDSG
+humpback/MDS
+humph/DG
+humphs
+humus/M
+hunch/MDSG
+hunchback/SMD
+hundred/SMH
+hundredfold
+hundredth/M
+hundredths
+hundredweight/SM
+hung
+hunger/SMDG
+hungover
+hungrily
+hungriness/M
+hungry/PRT
+hunk/MRSZ
+hunker/DG
+hunky/RT
+hunt/MDRSZG
+hunter/M
+hunting/M
+huntress/MS
+huntsman/M
+huntsmen
+hurdle/DRSMZG
+hurdler/M
+hurdling/M
+hurl/MDRSZG
+hurler/M
+hurling/M
+hurrah/GMD
+hurrahs
+hurray
+hurricane/MS
+hurried/UY
+hurry/DSMG
+hurt/MSG
+hurtful/YP
+hurtfulness/M
+hurtle/DSG
+husband/GMDS
+husbandman/M
+husbandmen
+husbandry/M
+hush/MDSG
+husk/MDRSZG
+husker/M
+huskily
+huskiness/M
+husky/PRSMT
+hussar/SM
+hussy/SM
+hustings/M
+hustle/DRSMZG
+hustler/M
+hut/SM
+hutch/MS
+huzza/GSMD
+huzzah/MDG
+huzzahs
+hwy
+hyacinth/M
+hyacinths
+hybrid/SM
+hybridism/M
+hybridization/M
+hybridize/DSG
+hydra/SM
+hydrangea/SM
+hydrant/MS
+hydrate's
+hydrate/CGNDS
+hydration/CM
+hydraulic/S
+hydraulically
+hydraulics/M
+hydro/M
+hydrocarbon/MS
+hydrocephalus/M
+hydrochloride
+hydrocortisone
+hydrodynamic/S
+hydrodynamics/M
+hydroelectric
+hydroelectrically
+hydroelectricity/M
+hydrofoil/MS
+hydrogen/M
+hydrogenate/CGDS
+hydrogenation/M
+hydrogenous
+hydrologist/MS
+hydrology/M
+hydrolyses
+hydrolysis/M
+hydrolyze/DSG
+hydrometer/SM
+hydrometry/M
+hydrophilic
+hydrophobia/M
+hydrophobic
+hydrophone/SM
+hydroplane/GDSM
+hydroponic/S
+hydroponically
+hydroponics/M
+hydrosphere/M
+hydrotherapy/M
+hydrothermal
+hydrous
+hydroxide/SM
+hyena/SM
+hygiene/M
+hygienic/U
+hygienically
+hygienist/MS
+hygrometer/SM
+hying
+hymen/SM
+hymeneal
+hymn/MDSG
+hymnal/MS
+hymnbook/SM
+hype/MGDRS
+hyperactive
+hyperactivity/M
+hyperbola/SM
+hyperbole/M
+hyperbolic
+hypercritical/Y
+hypercube
+hyperglycemia/M
+hyperinflation
+hyperlink/GSMD
+hypermarket/S
+hypermedia/M
+hyperparathyroidism
+hyperplane
+hypersensitive/P
+hypersensitiveness/M
+hypersensitivity/SM
+hyperspace/S
+hypertension/M
+hypertensive/SM
+hypertext/M
+hyperthyroid/M
+hyperthyroidism/M
+hypertrophy/DSMG
+hyperventilate/GNDS
+hyperventilation/M
+hypervisor/MS
+hyphen/MDSG
+hyphenate/XDSMGN
+hyphenation/M
+hypnoses
+hypnosis/M
+hypnotherapist/S
+hypnotherapy/M
+hypnotic/SM
+hypnotically
+hypnotism/M
+hypnotist/MS
+hypnotize/GDS
+hypo/MS
+hypoallergenic
+hypochondria/M
+hypochondriac/SM
+hypocrisy/SM
+hypocrite/MS
+hypocritical/Y
+hypodermic/MS
+hypoglycemia/M
+hypoglycemic/SM
+hypotenuse/MS
+hypothalami
+hypothalamus/M
+hypothermia/M
+hypotheses
+hypothesis/M
+hypothesize/DSG
+hypothetical/Y
+hypothyroid/M
+hypothyroidism/M
+hyssop/M
+hysterectomy/SM
+hysteresis
+hysteria/M
+hysteric/SM
+hysterical/Y
+hysterics/M
+i/US
+iOS/M
+iPad/M
+iPhone/M
+iPod/M
+iTunes/M
+iamb/MS
+iambi
+iambic/SM
+iambus/MS
+ibex/MS
+ibid
+ibidem
+ibis/MS
+ibuprofen/M
+ice's
+ice/CDSG
+iceberg/SM
+iceboat/SM
+icebound
+icebox/MS
+icebreaker/SM
+icecap/SM
+iceman/M
+icemen
+ichthyologist/MS
+ichthyology/M
+icicle/SM
+icily
+iciness/M
+icing/SM
+icky/RT
+icon/MS
+iconic
+iconoclasm/M
+iconoclast/SM
+iconoclastic
+iconography/M
+ictus/M
+icy/TPR
+id/SMY
+idea/MS
+ideal/SMY
+idealism/M
+idealist/SM
+idealistic
+idealistically
+idealization/MS
+idealize/DSG
+idem
+idempotent
+identical/Y
+identifiable/U
+identification/M
+identified/U
+identify/ZGNDRSX
+identikit/S
+identity/SM
+ideogram/SM
+ideograph/M
+ideographs
+ideological/Y
+ideologist/SM
+ideologue/MS
+ideology/SM
+ides/M
+idiocy/SM
+idiom/SM
+idiomatic/U
+idiomatically
+idiopathic
+idiosyncrasy/SM
+idiosyncratic
+idiosyncratically
+idiot/SM
+idiotic
+idiotically
+idle/MZTGDRSP
+idleness/M
+idler/M
+idol/MS
+idolater/SM
+idolatress/MS
+idolatrous
+idolatry/M
+idolization/M
+idolize/GDS
+idyll/SM
+idyllic
+idyllically
+if/SM
+iffiness/M
+iffy/RTP
+igloo/SM
+igneous
+ignitable
+ignite/AGDS
+ignition/MS
+ignoble
+ignobly
+ignominious/Y
+ignominy/SM
+ignoramus/MS
+ignorance/M
+ignorant/Y
+ignore/GDS
+iguana/MS
+ii
+iii
+ilea
+ileitis/M
+ileum/M
+ilia
+ilium/M
+ilk/SM
+ill/SMP
+illegal/MYS
+illegality/SM
+illegibility/M
+illegible
+illegibly
+illegitimacy/M
+illegitimate/Y
+illiberal/Y
+illiberality/M
+illicit/YP
+illicitness/M
+illimitable
+illiteracy/M
+illiterate/MYS
+illness/MS
+illogical/Y
+illogicality/M
+illuminate/GNXDS
+illuminating/Y
+illumination/M
+illumine/DSBG
+illus/V
+illusion/EMS
+illusionist/SM
+illusory
+illustrate/GNVXDS
+illustration/M
+illustrative/Y
+illustrator/SM
+illustrious/PY
+illustriousness/M
+image/DSMG
+imagery/M
+imaginable/U
+imaginably/U
+imaginal
+imaginary
+imagination/MS
+imaginative/UY
+imagine/DSBJG
+imago/M
+imagoes
+imam/MS
+imbalance/DSM
+imbecile/MS
+imbecilic
+imbecility/SM
+imbibe/ZGDRS
+imbiber/M
+imbrication/M
+imbroglio/SM
+imbue/DSG
+imitable/I
+imitate/DSGNVX
+imitation/M
+imitative/PY
+imitativeness/M
+imitator/SM
+immaculate/PY
+immaculateness/M
+immanence/M
+immanency/M
+immanent/Y
+immaterial/YP
+immateriality/M
+immaterialness/M
+immature/Y
+immaturity/M
+immeasurable
+immeasurably
+immediacies/M
+immediacy/SM
+immediate/PY
+immediateness/M
+immemorial/Y
+immense/Y
+immensity/SM
+immerse/XDSGNV
+immersible
+immersion/M
+immigrant/SM
+immigrate/DSGN
+immigration/M
+imminence/M
+imminent/Y
+immobile
+immobility/M
+immobilization/M
+immobilize/ZGDRS
+immoderate/Y
+immodest/Y
+immodesty/M
+immolate/DSGN
+immolation/M
+immoral/Y
+immorality/SM
+immortal/MYS
+immortality/M
+immortalize/DSG
+immovability/M
+immovable
+immovably
+immune
+immunity/M
+immunization/SM
+immunize/GDS
+immunodeficiency/M
+immunodeficient
+immunoglobulin/S
+immunologic
+immunological
+immunologist/MS
+immunology/M
+immure/DSG
+immutability/M
+immutable
+immutably
+imp/SMR
+impact/SMDG
+impair/SDGL
+impaired/U
+impairment/MS
+impala/SM
+impale/DSGL
+impalement/M
+impalpable
+impalpably
+impanel/SDG
+impart/SDG
+impartial/Y
+impartiality/M
+impassably
+impasse/BSMV
+impassibility/M
+impassible
+impassibly
+impassioned
+impassive/YP
+impassiveness/M
+impassivity/M
+impasto/M
+impatience/MS
+impatiens/M
+impatient/Y
+impeach/ZGBLDRS
+impeachable/U
+impeacher/M
+impeachment/SM
+impeccability/M
+impeccable
+impeccably
+impecunious/PY
+impecuniousness/M
+impedance/M
+impede/DSG
+impeded/U
+impediment/SM
+impedimenta/M
+impel/S
+impelled
+impeller/MS
+impelling
+impend/SDG
+impenetrability/M
+impenetrable
+impenetrably
+impenitence/M
+impenitent/Y
+imperative/SMY
+imperceptibility/M
+imperceptible
+imperceptibly
+imperceptive
+imperf
+imperfect/SMYP
+imperfection/MS
+imperfectness/M
+imperial/MYS
+imperialism/M
+imperialist/SM
+imperialistic
+imperialistically
+imperil/GSLD
+imperilment/M
+imperious/PY
+imperiousness/M
+imperishable
+imperishably
+impermanence/M
+impermanent/Y
+impermeability/M
+impermeable
+impermeably
+impermissible
+impersonal/Y
+impersonate/GNXDS
+impersonation/M
+impersonator/SM
+impertinence/MS
+impertinent/Y
+imperturbability/M
+imperturbable
+imperturbably
+impervious/Y
+impetigo/M
+impetuosity/M
+impetuous/YP
+impetuousness/M
+impetus/MS
+impiety/SM
+impinge/LDSG
+impingement/M
+impious/PY
+impiousness/M
+impish/YP
+impishness/M
+implacability/M
+implacable
+implacably
+implant/BSGMD
+implantation/M
+implausibility/SM
+implausible
+implausibly
+implement/GBMDRS
+implementable/U
+implementation/SM
+implemented/U
+implicate/DSG
+implication/M
+implicit/PY
+implicitness/M
+implode/DSG
+implore/DSG
+imploring/Y
+implosion/MS
+implosive
+imply/XDSGN
+impolite/YP
+impoliteness/MS
+impolitic
+imponderable/MS
+import/ZGBSMDR
+importance/M
+important/Y
+importation/MS
+importer/M
+importunate/Y
+importune/GDS
+importunity/M
+impose/ADSG
+imposer/MS
+imposing/U
+imposingly
+imposition/MS
+impossibility/SM
+impossible/S
+impossibly
+impost/ZSMR
+imposter/M
+impostor/SM
+imposture/MS
+impotence/M
+impotency/M
+impotent/Y
+impound/DGS
+impoverish/DSLG
+impoverishment/M
+impracticability
+impracticable
+impracticably
+impractical/Y
+impracticality/M
+imprecate/DSXGN
+imprecation/M
+imprecise/PYN
+impreciseness/M
+imprecision/M
+impregnability/M
+impregnable
+impregnably
+impregnate/GNDS
+impregnation/M
+impresario/SM
+impress/MDSGV
+impressed/U
+impressibility/M
+impressible
+impression/BSM
+impressionability/M
+impressionism/M
+impressionist/SM
+impressionistic
+impressive/PY
+impressiveness/M
+imprimatur/SM
+imprint/MDRZGS
+imprinter/M
+imprison/SDLG
+imprisonment/SM
+improbability/SM
+improbable
+improbably
+impromptu/SM
+improper/Y
+impropriety/SM
+improve/GBDSL
+improved/U
+improvement/MS
+improvidence/M
+improvident/Y
+improvisation/SM
+improvisational
+improvise/ZGDRS
+improviser/M
+improvisor/SM
+imprudence/M
+imprudent/Y
+impudence/M
+impudent/Y
+impugn/ZGSDR
+impugner/M
+impulse/MGNVDS
+impulsion/M
+impulsive/PY
+impulsiveness/M
+impulsivity
+impunity/M
+impure/RYT
+impurity/SM
+imputation/SM
+impute/BDSG
+in/ASM
+inaccuracy/S
+inaction/M
+inadequacy/S
+inadvertence/M
+inadvertent/Y
+inalienability/M
+inalienably
+inamorata/SM
+inane/RYT
+inanimate/PY
+inanimateness/M
+inanity/SM
+inappropriate/Y
+inarticulate/Y
+inasmuch
+inaudible
+inaugural/SM
+inaugurate/XGNDS
+inauguration/M
+inboard/MS
+inbound
+inbox/MS
+inbreed/S
+inc/TGD
+incalculably
+incandescence/M
+incandescent/Y
+incantation/SM
+incapacitate/GNDS
+incarcerate/XDSGN
+incarceration/M
+incarnadine/DSG
+incarnate/AXGNDS
+incarnation/AM
+incendiary/SM
+incense/MGDS
+incentive's
+incentive/ES
+inception/SM
+incessant/Y
+incest/M
+incestuous/PY
+incestuousness/M
+inch/MDSG
+inchoate
+inchworm/SM
+incidence/SM
+incident/SM
+incidental/MYS
+incinerate/DSGN
+incineration/M
+incinerator/MS
+incipience/M
+incipient/Y
+incise/XGNVDS
+incision/M
+incisive/PY
+incisiveness/M
+incisor/MS
+incitement/MS
+inciter/MS
+incl
+inclement
+inclination/EM
+inclinations
+incline's
+incline/EGDS
+include/GDS
+inclusion/MS
+inclusive/YP
+inclusiveness/M
+incognito/MS
+incombustible
+incommode/GD
+incommodious
+incommunicado
+incompatibility/S
+incompetent/MS
+incomplete/Y
+inconceivability/M
+incongruous/PY
+incongruousness/M
+inconsolably
+inconstant/Y
+incontestability/M
+incontestably
+incontinent
+incontrovertibly
+inconvenience/GD
+incorporate/ADSGN
+incorporated/U
+incorporation/AM
+incorporeal
+incorrect/Y
+incorrigibility/M
+incorrigible
+incorrigibly
+incorruptibly
+increasing/Y
+increment/SMDG
+incremental/Y
+incrementalism
+incrementalist/SM
+incriminate/GNDS
+incrimination/M
+incriminatory
+incrustation/SM
+incubate/GNDS
+incubation/M
+incubator/SM
+incubus/MS
+inculcate/DSGN
+inculcation/M
+inculpate/DSG
+incumbency/SM
+incumbent/SM
+incunabula
+incunabulum/M
+incur/SB
+incurable/MS
+incurably
+incurious
+incurred
+incurring
+incursion/MS
+ind
+indebted/P
+indebtedness/M
+indeed
+indefatigable
+indefatigably
+indefeasible
+indefeasibly
+indefinably
+indelible
+indelibly
+indemnification/M
+indemnify/GDSXN
+indemnity/SM
+indentation/MS
+indention/M
+indenture/DG
+indescribably
+indestructibly
+indeterminably
+indeterminacy/M
+indeterminate/Y
+index/ZGMDRS
+indexation/SM
+indexer/M
+indicate/XDSGNV
+indication/M
+indicative/SMY
+indicator/MS
+indict/GDSBL
+indictment/SM
+indie/S
+indigence/M
+indigenous
+indigent/SMY
+indignant/Y
+indignation/M
+indigo/M
+indirect/Y
+indiscipline
+indiscreet/Y
+indiscretion/S
+indiscriminate/Y
+indispensability/M
+indispensable/MS
+indispensably
+indissolubility
+indissolubly
+indistinguishably
+indite/GDS
+indium/M
+individual/MYS
+individualism/M
+individualist/MS
+individualistic
+individualistically
+individuality/M
+individualization/M
+individualize/GDS
+individuate/DSGN
+individuation/M
+indivisibly
+indoctrinate/GNDS
+indoctrination/M
+indolence/M
+indolent/Y
+indomitable
+indomitably
+indubitable
+indubitably
+induce/DRSZGL
+inducement/SM
+inducer/M
+induct/DGV
+inductance/M
+inductee/SM
+induction/MS
+inductive/Y
+indue/DG
+indulge/DSG
+indulgence/SM
+indulgent/Y
+industrial/Y
+industrialism/M
+industrialist/SM
+industrialization/M
+industrialize/DSG
+industrious/YP
+industriousness/M
+industry/SM
+indwell/SG
+inebriate/MGNDS
+inebriation/M
+inedible
+ineffability/M
+ineffable
+ineffably
+inelastic
+ineligible/MS
+ineligibly
+ineluctable
+ineluctably
+inept/YP
+ineptitude/M
+ineptness/M
+inequality/S
+inert/YP
+inertia/M
+inertial
+inertness/M
+inescapable
+inescapably
+inestimably
+inevitability/M
+inevitable/M
+inevitably
+inexact/Y
+inexhaustibly
+inexorability
+inexorable
+inexorably
+inexpedient
+inexpert/Y
+inexpiable
+inexplicably
+inexpressibly
+inexpressive
+inextricably
+inf/ZT
+infallible
+infamy/SM
+infancy/M
+infant/MS
+infanticide/MS
+infantile
+infantry/SM
+infantryman/M
+infantrymen
+infarct/MS
+infarction/M
+infatuate/DSXGN
+infatuation/M
+infect/AESDG
+infected/U
+infection/ASM
+infectious/PY
+infectiousness/M
+infelicitous
+inference/SM
+inferential
+inferior/MS
+inferiority/M
+infernal/Y
+inferno/MS
+inferred
+inferring
+infest/GDS
+infestation/MS
+infidel/MS
+infidelity/S
+infiltrator/SM
+infinite/MV
+infinitesimal/SMY
+infinitival
+infinitive/MS
+infinitude/M
+infinity/SM
+infirm
+infirmary/SM
+infirmity/SM
+infix
+inflame/DSG
+inflammable
+inflammation/SM
+inflammatory
+inflatable/SM
+inflate/ADSG
+inflation/EM
+inflationary
+inflect/SDG
+inflection/MS
+inflectional
+inflict/SDGV
+infliction/M
+inflight
+inflow/SM
+influence/MGDS
+influenced/U
+influential/Y
+influenza/M
+info/M
+infomercial/SM
+inform/Z
+informal/Y
+informant/SM
+informatics
+information/EM
+informational
+informative/PY
+informativeness/M
+informed/U
+infotainment/M
+infra
+infrared/M
+infrasonic
+infrastructural
+infrastructure/SM
+infrequence/M
+infrequent/Y
+infringement/MS
+infuriate/GDS
+infuriating/Y
+infuser/SM
+ingenious/PY
+ingeniousness/M
+ingenue/SM
+ingenuity/M
+ingenuous/EY
+ingenuousness/M
+ingest/SDG
+ingestion/M
+inglenook/SM
+ingot/SM
+ingrain/G
+ingrate/SM
+ingratiate/GNDS
+ingratiating/Y
+ingratiation/M
+ingredient/MS
+ingress/MS
+inguinal
+ing辿nue/SM
+inhabit/DG
+inhabitable/U
+inhabitant/SM
+inhabited/U
+inhalant/SM
+inhalation/MS
+inhalator/MS
+inhaler/SM
+inharmonious
+inhere/DSG
+inherent/Y
+inherit/EGSD
+inheritance/EM
+inheritances
+inheritor/SM
+inhibit/GSD
+inhibition/SM
+inhibitor/SM
+inhibitory
+inhuman/Y
+inhumane/Y
+inimical/Y
+inimitably
+iniquitous/Y
+iniquity/SM
+initial/SGMDY
+initialism
+initialization
+initialize/DSG
+initialized/AU
+initiate/XMGNVDS
+initiated/U
+initiation/M
+initiative/SM
+initiator/MS
+initiatory
+initio
+inject/SDG
+injection/SM
+injector/SM
+injunctive
+injure/DRSZG
+injured/U
+injurer/M
+injurious
+ink/MD
+inkblot/SM
+inkiness/M
+inkling/SM
+inkstand/SM
+inkwell/MS
+inky/RTP
+inland/M
+inline
+inmate/SM
+inmost
+inn/SGMRJ
+innards/M
+innate/PY
+innateness/M
+innermost
+innersole/SM
+innerspring
+innervate/GNDS
+innervation/M
+inning/M
+innit
+innkeeper/MS
+innocence/M
+innocent/MYS
+innocuous/PY
+innocuousness/M
+innovate/XDSGNV
+innovation/M
+innovator/MS
+innovatory
+innuendo/SM
+innuendoes
+innumerably
+innumerate
+inoculate/AGDS
+inoculation/MS
+inoperative
+inordinate/Y
+inorganic
+inositol
+inquire/ZGDR
+inquirer/M
+inquiring/Y
+inquiry/SM
+inquisition/MS
+inquisitional
+inquisitive/YP
+inquisitiveness/M
+inquisitor/SM
+inquisitorial
+inrush/MS
+insane/T
+insatiability/M
+insatiably
+inscribe/ZGDR
+inscriber/M
+inscription/MS
+inscrutability/M
+inscrutable/P
+inscrutableness/M
+inscrutably
+inseam/SM
+insecticidal
+insecticide/MS
+insectivore/MS
+insectivorous
+insecure/Y
+inseminate/DSGN
+insemination/M
+insensate
+insensible
+insensitive/Y
+inseparable/MS
+insert's
+insert/AGSD
+insertion/AM
+insertions
+insetting
+inshore
+inside/RSMZ
+insider/M
+insidious/YP
+insidiousness/M
+insight/MS
+insightful
+insignia/SM
+insinuate/GNVDSX
+insinuation/M
+insinuator/SM
+insipid/PY
+insipidity/M
+insist/SGD
+insistence/M
+insistent/Y
+insisting/Y
+insofar
+insole/SM
+insolence/M
+insolent/Y
+insoluble
+insolubly
+insolvency/S
+insomnia/M
+insomniac/SM
+insomuch
+insouciance/M
+insouciant
+inspect/AGDS
+inspection/SM
+inspector/MS
+inspectorate/MS
+inspiration/MS
+inspirational
+inspiratory
+inspired/U
+inspiring/U
+inst
+instability/S
+install/UBZRSDG
+installation/MS
+installer/UM
+installment/SM
+instance/GD
+instant/MRYS
+instantaneous/Y
+instantiate/DSG
+instar
+instate/AGDS
+instead
+instigate/DSGN
+instigation/M
+instigator/MS
+instillation/M
+instinct/VMS
+instinctive/Y
+instinctual
+institute/XMZGNDRS
+instituter/M
+institution/M
+institutional/Y
+institutionalization/M
+institutionalize/DSG
+institutor/MS
+instr
+instruct/SDGV
+instructed/U
+instruction/MS
+instructional
+instructive/Y
+instructor/MS
+instrument/MDSG
+instrumental/MYS
+instrumentalist/SM
+instrumentality/M
+instrumentation/M
+insubordinate
+insufferable
+insufferably
+insula
+insular
+insularity/M
+insulate/GNDS
+insulation/M
+insulator/MS
+insulin/M
+insult/SMDG
+insulting/Y
+insuperable
+insuperably
+insurance/SM
+insure/DRSZGB
+insured/SM
+insurer/M
+insurgence/SM
+insurgency/SM
+insurgent/MS
+insurmountably
+insurrection/SM
+insurrectionist/SM
+int
+intact
+intaglio/MS
+integer/MS
+integral/SMY
+integrate/AEVNGSD
+integration/EAM
+integrator
+integrity/M
+integument/SM
+intel/M
+intellect/MS
+intellectual/MYS
+intellectualism/M
+intellectualize/GDS
+intelligence/M
+intelligent/Y
+intelligentsia/M
+intelligibility/M
+intelligible/U
+intelligibly/U
+intended/SM
+intense/YTVR
+intensification/M
+intensifier/M
+intensify/DRSZGN
+intensity/S
+intensive/MYPS
+intensiveness/M
+intent/SMYP
+intention/MS
+intentional/UY
+intentness/M
+inter/ESL
+interact/SGVD
+interaction/SM
+interactive/Y
+interactivity
+interbred
+interbreed/GS
+intercede/GDS
+intercept/GMDS
+interception/MS
+interceptor/SM
+intercession/SM
+intercessor/MS
+intercessory
+interchange/DSMG
+interchangeability
+interchangeable
+interchangeably
+intercity
+intercollegiate
+intercom/SM
+intercommunicate/DSGN
+intercommunication/M
+interconnect/GDS
+interconnection/SM
+intercontinental
+intercourse/M
+intercultural
+interdenominational
+interdepartmental
+interdependence/M
+interdependent/Y
+interdict/GMDS
+interdiction/M
+interdisciplinary
+interest/ESMD
+interested/U
+interesting/Y
+interface/MGDS
+interfaith
+interfere/GDS
+interference/M
+interferon/M
+interfile/GDS
+intergalactic
+intergovernmental
+interim/M
+interior/SM
+interj
+interject/GDS
+interjection/SM
+interlace/GDS
+interlard/DGS
+interleave/DSG
+interleukin/M
+interline/GDSJ
+interlinear
+interlining/M
+interlink/DSG
+interlock/GMDS
+interlocutor/SM
+interlocutory
+interlope/ZGDRS
+interloper/M
+interlude/MGDS
+intermarriage/SM
+intermarry/GDS
+intermediary/SM
+intermediate/MYS
+interment/EM
+interments
+intermezzi
+intermezzo/MS
+interminably
+intermingle/DSG
+intermission/SM
+intermittence
+intermittency
+intermittent/Y
+intermix/GDS
+internal/SY
+internalization/M
+internalize/GDS
+international/SMY
+internationalism/M
+internationalist/SM
+internationalization
+internationalize/DSG
+interne/GDL
+internecine
+internee/SM
+interneship/S
+internet
+internist/MS
+internment/M
+internship/MS
+interoffice
+interoperability
+interoperable
+interoperate/S
+interpenetrate/DSGN
+interpersonal
+interplanetary
+interplay/M
+interpolate/XDSGN
+interpolation/M
+interpose/GDS
+interposition/M
+interpret/AGVDS
+interpretation/AMS
+interpretative
+interpreted/U
+interpreter/MS
+interracial
+interred/E
+interregnum/SM
+interrelate/XDSGN
+interrelation/M
+interrelationship/MS
+interring/E
+interrogate/DSGNVX
+interrogation/M
+interrogative/MYS
+interrogator/SM
+interrogatory/SM
+interrupt/ZGMDRS
+interrupter/M
+interruption/MS
+interscholastic
+intersect/GDS
+intersection/SM
+intersectional
+intersectionality
+intersession/SM
+intersex
+intersperse/GNDS
+interspersion/M
+interstate/MS
+interstellar
+interstice/MS
+interstitial
+intertwine/GDS
+interurban
+interval/SM
+intervene/GDS
+intervention/SM
+interventionism/M
+interventionist/SM
+interview/ZGMDRS
+interviewee/MS
+interviewer/M
+intervocalic
+interwar
+interweave/GS
+interwove
+interwoven
+intestacy/M
+intestate
+intestinal
+intestine/MS
+intifada
+intimacy/SM
+intimate/MYGNDSX
+intimation/M
+intimidate/GNDS
+intimidating/Y
+intimidation/M
+intonation/SM
+intoxicant/SM
+intoxicate/DSGN
+intoxication/M
+intracranial
+intramural
+intramuscular
+intranet/MS
+intransigence/M
+intransigent/MYS
+intrastate
+intrauterine
+intravenous/MSY
+intrepid/Y
+intrepidity/M
+intricacy/SM
+intricate/Y
+intrigue/DRSMZG
+intriguer/M
+intriguing/Y
+intrinsic
+intrinsically
+intro/SM
+introduce/AGDS
+introduction/AM
+introductions
+introductory
+introit/SM
+introspect/GVDS
+introspection/M
+introspective/Y
+introversion/M
+introvert/MDS
+intrude/DRSZG
+intruder/M
+intrusion/SM
+intrusive/YP
+intrusiveness/M
+intuit/SDGV
+intuition/S
+intuitive/PY
+intuitiveness/M
+inundate/XDSGN
+inundation/M
+inure/DSG
+invade/DRSZG
+invader/M
+invalid/GMDYS
+invalidism/M
+invaluable
+invaluably
+invariant
+invasion/MS
+invasive
+invective/M
+inveigh/GD
+inveighs
+inveigle/ZGDRS
+inveigler/M
+invent/ASGVD
+invention/AMS
+inventive/PY
+inventiveness/M
+inventor/MS
+inventory/DSMG
+inverse/SMY
+invert/SMDRZG
+inverter/M
+invest/ASDGL
+investigate/GNVDSX
+investigation/M
+investigator/SM
+investigatory
+investiture/MS
+investment/AEM
+investor/SM
+inveteracy/M
+inveterate
+invidious/YP
+invidiousness/M
+invigilate/GNDS
+invigilator/S
+invigorate/ADSG
+invigorating/Y
+invigoration/M
+invincibility/M
+invincibly
+inviolability/M
+inviolably
+inviolate
+invitation/SM
+invitational/SM
+invite/DSMG
+invited/U
+invitee/SM
+inviting/Y
+invoke/DSG
+involuntariness/M
+involuntary/P
+involution/M
+involve/LDSG
+involved/U
+involvement/SM
+inward/SY
+ioctl
+iodide/SM
+iodine/M
+iodize/DSG
+ion/USM
+ionic
+ionization/UM
+ionize/UDSG
+ionizer/MS
+ionosphere/MS
+ionospheric
+iota/MS
+ipecac/SM
+irascibility/M
+irascible
+irascibly
+irate/YP
+irateness/M
+ire/M
+ireful
+irenic
+irides
+iridescence/M
+iridescent/Y
+iridium/M
+iris/MS
+irk/SGD
+irksome/YP
+irksomeness/M
+iron/MDSG
+ironclad/MS
+ironic
+ironical/Y
+ironing/M
+ironmonger/S
+ironmongery
+ironstone/M
+ironware/M
+ironwood/MS
+ironwork/M
+irony/SM
+irradiate/DSGN
+irradiation/M
+irrational/SMY
+irrationality/M
+irreclaimable
+irreconcilability/M
+irreconcilable
+irreconcilably
+irrecoverable
+irrecoverably
+irredeemable
+irredeemably
+irreducible
+irreducibly
+irrefutable
+irrefutably
+irregular/MYS
+irregularity/SM
+irrelevance/MS
+irrelevancy/MS
+irrelevant/Y
+irreligion
+irreligious
+irremediable
+irremediably
+irremovable
+irreparable
+irreparably
+irreplaceable
+irrepressible
+irrepressibly
+irreproachable
+irreproachably
+irresistible
+irresistibly
+irresolute/PYN
+irresoluteness/M
+irresolution/M
+irrespective
+irresponsibility/M
+irresponsible
+irresponsibly
+irretrievable
+irretrievably
+irreverence/M
+irreverent/Y
+irreversible
+irreversibly
+irrevocable
+irrevocably
+irrigable
+irrigate/DSGN
+irrigation/M
+irritability/M
+irritable
+irritably
+irritant/SM
+irritate/DSXGN
+irritating/Y
+irritation/M
+irrupt/DGVS
+irruption/SM
+ischemia
+ischemic
+isinglass/M
+isl
+island/SZMR
+islander/M
+isle/MS
+islet/SM
+ism/CM
+isms
+isn't
+isobar/MS
+isobaric
+isolate/DSMGN
+isolation/M
+isolationism/M
+isolationist/SM
+isomer/MS
+isomeric
+isomerism/M
+isometric/S
+isometrically
+isometrics/M
+isomorphic
+isomorphism
+isosceles
+isotherm/SM
+isotope/SM
+isotopic
+isotropic
+issuance/M
+issue/ADSMG
+issuer/MS
+isthmian
+isthmus/MS
+it'd
+it'll
+it/USM
+ital
+italic/SM
+italicization/M
+italicize/GDS
+italics/M
+itch/MDSG
+itchiness/M
+itchy/RPT
+item/MS
+itemization/M
+itemize/GDS
+iterate/AXGNVDS
+iteration/AM
+iterator/S
+itinerant/SM
+itinerary/SM
+itself
+iv/U
+ivory/SM
+ivy/DSM
+ix
+j/F
+jab/SM
+jabbed
+jabber/SMDRZG
+jabberer/M
+jabbing
+jabot/SM
+jacaranda/MS
+jack/MDGS
+jackal/SM
+jackass/MS
+jackboot/SMD
+jackdaw/MS
+jacket/SMD
+jackhammer/MS
+jackknife/MGDS
+jackknives
+jackpot/MS
+jackrabbit/MS
+jackstraw/MS
+jacquard/M
+jade/MGDS
+jaded/PY
+jadedness/M
+jadeite/M
+jag/SM
+jagged/TPRY
+jaggedness/M
+jaggies
+jaguar/SM
+jail/MDRZGS
+jailbird/SM
+jailbreak/SM
+jailer/M
+jailhouse/S
+jalapeno/MS
+jalape単o/MS
+jalopy/SM
+jalousie/MS
+jam/SM
+jamb/MS
+jambalaya/M
+jamboree/MS
+jammed
+jamming
+jammy/RT
+jangle/DRSMZG
+jangler/M
+janitor/SM
+janitorial
+japan/SM
+japanned
+japanning
+jape/MGDS
+jar/SM
+jardiniere/SM
+jardini竪re/SM
+jarful/MS
+jargon/M
+jarred
+jarring/Y
+jasmine/SM
+jasper/M
+jato/MS
+jaundice/DSMG
+jaunt/SGMD
+jauntily
+jauntiness/M
+jaunty/RPT
+java/M
+javelin/SM
+jaw/SGMD
+jawbone/DSMG
+jawbreaker/MS
+jawline/S
+jay/SM
+jaybird/SM
+jaywalk/DRSZG
+jaywalker/M
+jaywalking/M
+jazz/MDSG
+jazzy/TR
+jct
+jealous/Y
+jealousy/SM
+jean/MS
+jeans/M
+jeep/MS
+jeer/MDSG
+jeering/MY
+jeez
+jejuna
+jejune
+jejunum/M
+jell/DSG
+jello/SM
+jelly/GDSM
+jellybean/MS
+jellyfish/MS
+jellylike
+jellyroll/SM
+jemmy/GDS
+jennet/MS
+jenny/SM
+jeopardize/GDS
+jeopardy/M
+jeremiad/MS
+jerk/MDSG
+jerkily
+jerkin/MS
+jerkiness/M
+jerkwater
+jerky/TRMP
+jeroboam/S
+jerrican/S
+jerrybuilt
+jerrycan/S
+jersey/MS
+jest/MDRSZG
+jester/M
+jesting/Y
+jet/SM
+jetliner/SM
+jetport/MS
+jetsam/M
+jetted
+jetting
+jettison/MDSG
+jetty/SM
+jewel/SZGMDR
+jeweler/M
+jewelry/SM
+jg
+jib/SGMD
+jibbed
+jibbing
+jibe/MS
+jiff/MS
+jiffy/SM
+jig's
+jig/AS
+jigged/A
+jigger's
+jigger/ASDG
+jigging/A
+jiggle/DSMG
+jiggly
+jigsaw/SMDG
+jihad/SM
+jihadist/SM
+jilt/MDSG
+jimmy/DSMG
+jimsonweed/M
+jingle/DSMG
+jingly
+jingoism/M
+jingoist/SM
+jingoistic
+jink/DSG
+jinn/MS
+jinni/M
+jinricksha/SM
+jinrikisha/SM
+jinx/MDSG
+jitney/SM
+jitterbug/MS
+jitterbugged
+jitterbugger/M
+jitterbugging
+jitters/M
+jittery/RT
+jive/MGDS
+job/SM
+jobbed
+jobber/SM
+jobbing
+jobholder/MS
+jobless/P
+joblessness/M
+jobshare/S
+jobsworth
+jobsworths
+jock/MS
+jockey/SGMD
+jockstrap/MS
+jocose/PY
+jocoseness/M
+jocosity/M
+jocular/Y
+jocularity/M
+jocund/Y
+jocundity/M
+jodhpurs/M
+joey/S
+jog/SM
+jogged
+jogger/SM
+jogging/M
+joggle/DSMG
+john/MS
+johnny/SM
+johnnycake/MS
+join's
+join/AFDSG
+joiner/FMS
+joinery/M
+joint's
+joint/EGSD
+jointly/F
+joist/SM
+jojoba
+joke/MZGDRS
+joker/M
+jokey
+jokier
+jokiest
+joking/Y
+jollification/SM
+jollily
+jolliness/M
+jollity/M
+jolly/TGPDRSM
+jolt/MDRSZG
+jolter/M
+jonquil/SM
+josh/MDRSZG
+josher/M
+jostle/MGDS
+jot/SM
+jotted
+jotter/MS
+jotting/MS
+joule/SM
+jounce/MGDS
+jouncy
+journal/MS
+journalese/M
+journalism/M
+journalist/SM
+journalistic
+journey/ZGMDRS
+journeyer/M
+journeyman/M
+journeymen
+journo/S
+joust/SZGMDR
+jouster/M
+jousting/M
+jovial/Y
+joviality/M
+jowl/MS
+jowly/TR
+joy/SGMD
+joyful/YP
+joyfuller
+joyfullest
+joyfulness/M
+joyless/PY
+joylessness/M
+joyous/YP
+joyousness/M
+joyridden
+joyride/RSMZG
+joyrider/M
+joyriding/M
+joyrode
+joystick/SM
+jr
+jubilant/Y
+jubilation/M
+jubilee/SM
+judder/GDS
+judge's
+judge/ADSG
+judgemental
+judgeship/M
+judgment/SM
+judgmental/Y
+judicatory/SM
+judicature/M
+judicial/Y
+judiciary/SM
+judicious/IYP
+judiciousness/IM
+judo/M
+jug/SM
+jugful/MS
+jugged
+juggernaut/SM
+jugging
+juggle/MZGDRS
+juggler/M
+jugglery/M
+jugular/SM
+juice/DRSMZG
+juicer/M
+juicily
+juiciness/M
+juicy/PTR
+jujitsu/M
+jujube/MS
+jukebox/MS
+julep/SM
+julienne
+jumble/MGDS
+jumbo/SM
+jump/MDRSZG
+jumper/M
+jumpily
+jumpiness/M
+jumpsuit/MS
+jumpy/TRP
+jun
+junco/SM
+junction/FISM
+juncture/FMS
+jungle/MS
+junior/MS
+juniper/SM
+junk/MDRSZG
+junker/M
+junket/MDRSZG
+junketeer/MS
+junketer/M
+junkie/M
+junky/TRSM
+junkyard/MS
+junta/SM
+juridic
+juridical/Y
+jurisdiction/SM
+jurisdictional
+jurisprudence/M
+jurist/MS
+juristic
+juror/FSM
+jury/ISM
+juryman/M
+jurymen
+jurywoman/M
+jurywomen
+just/RYPT
+justice/IMS
+justifiable/U
+justifiably/U
+justification/M
+justified/U
+justify/XGDSN
+justness/M
+jut/SM
+jute/M
+jutted
+jutting
+juvenile/SM
+juxtapose/DSG
+juxtaposition/SM
+k/IFGS
+kHz
+kW
+kWh
+kabbala
+kabbalah
+kabob/SM
+kaboom
+kabuki/M
+kaddish/MS
+kaffeeklatch/MS
+kaffeeklatsch/MS
+kahuna/S
+kaiser/MS
+kale/M
+kaleidoscope/MS
+kaleidoscopic
+kaleidoscopically
+kamikaze/MS
+kana
+kangaroo/MS
+kanji
+kaolin/M
+kapok/M
+kappa/SM
+kaput
+karakul/M
+karaoke/MS
+karat/SM
+karate/M
+karma/M
+karmic
+kart/MS
+katakana
+katydid/SM
+kayak/SMDG
+kayaking/M
+kayo/MDSG
+kazoo/SM
+kc
+kebab/SM
+kebob/SM
+kedgeree
+keel/MDSG
+keelhaul/DGS
+keen/MDRYSTGP
+keenness/M
+keep/MRSZG
+keeper/M
+keeping/M
+keepsake/MS
+keg/SM
+kelp/M
+kelvin/SM
+ken/SM
+kenned
+kennel/SGMD
+kenning
+keno/M
+kepi/MS
+kept
+keratin/M
+keratitis
+kerbside
+kerchief/SM
+kerfuffle/S
+kernel/SM
+kerosene/M
+kestrel/MS
+ketch/MS
+ketchup/M
+keto
+ketogenic
+ketone/S
+kettle/SM
+kettledrum/SM
+key/SGMD
+keybinding/S
+keyboard/ZGSMDR
+keyboarder/M
+keyboardist/SM
+keyhole/MS
+keynote/MZGDRS
+keynoter/M
+keypad/SM
+keypunch/ZGMDRS
+keypuncher/M
+keystone/MS
+keystroke/SM
+keyword/MS
+kg
+khaki/SM
+khan/MS
+kibble/DSMG
+kibbutz/MS
+kibbutzim
+kibitz/ZGDRS
+kibitzer/M
+kibosh/M
+kick/MDRSZG
+kickback/SM
+kickball/M
+kickboxing
+kicker/M
+kickoff/MS
+kickstand/MS
+kicky/RT
+kid/SM
+kidded
+kidder/SM
+kiddie/SM
+kidding
+kiddish
+kiddo/SM
+kidnap/S
+kidnapped
+kidnapper/MS
+kidnapping/MS
+kidney/SM
+kidskin/M
+kielbasa/MS
+kielbasi
+kike/S
+kill/JMDRSZG
+killdeer/SM
+killer/M
+killing/M
+killjoy/SM
+kiln/MDSG
+kilo/MS
+kilobyte/SM
+kilocoulomb/S
+kilocycle/SM
+kilogram/SM
+kilohertz/M
+kilojoule/S
+kiloliter/MS
+kilometer/MS
+kilonewton/S
+kilopascal/S
+kiloton/SM
+kilovolt/S
+kilowatt/SM
+kilt/MDRS
+kilter/M
+kimono/MS
+kin/M
+kinase
+kind's
+kind/UPRYT
+kinda
+kindergarten/MS
+kindergartner/SM
+kinderg辰rtner/SM
+kindhearted/PY
+kindheartedness/M
+kindle/AGDS
+kindliness/M
+kindling/M
+kindly/URT
+kindness/UM
+kindnesses
+kindred/M
+kinds
+kine/S
+kinematic/S
+kinematics/M
+kinetic/S
+kinetically
+kinetics/M
+kinfolk/SM
+kinfolks/M
+king/MYS
+kingdom/SM
+kingfisher/SM
+kingly/RT
+kingmaker/S
+kingpin/SM
+kingship/M
+kink/MDSG
+kinkily
+kinkiness/M
+kinky/TPR
+kinsfolk/M
+kinship/M
+kinsman/M
+kinsmen
+kinswoman/M
+kinswomen
+kiosk/SM
+kip/SM
+kipped
+kipper/MDGS
+kipping
+kirsch/MS
+kismet/M
+kiss/MDRSBZG
+kisser/M
+kissoff/SM
+kissogram/S
+kit/SGMD
+kitbag/MS
+kitchen/SM
+kitchenette/MS
+kitchenware/M
+kite/MS
+kith/M
+kitsch/M
+kitschy
+kitted
+kitten/MS
+kittenish
+kitting
+kitty/SM
+kiwi/MS
+kiwifruit/MS
+kl
+klaxon/S
+kleptocracy
+kleptomania/M
+kleptomaniac/SM
+kludge/GDS
+kluge/DS
+klutz/MS
+klutziness/M
+klutzy/TRP
+km
+kn
+knack/SZMR
+knacker/GD
+knackwurst/MS
+knapsack/MS
+knave/SM
+knavery/M
+knavish/Y
+knead/SZGDR
+kneader/M
+knee/MDS
+kneecap/SM
+kneecapped
+kneecapping
+kneeing
+kneel/SG
+knell/SGMD
+knelt
+knew
+knicker/S
+knickerbockers/M
+knickers/M
+knickknack/MS
+knife/DSMG
+knight/MDYSG
+knighthood/MS
+knightliness/M
+knish/MS
+knit/MS
+knitted
+knitter/SM
+knitting/M
+knitwear/M
+knives
+knob/MS
+knobbly
+knobby/TR
+knock/SZGMDR
+knockabout
+knockdown/SM
+knocker/M
+knockoff/SM
+knockout/SM
+knockwurst/SM
+knoll/SM
+knot/MS
+knothole/SM
+knotted
+knotting
+knotty/TR
+know/SB
+knowing/UYS
+knowledge/M
+knowledgeable
+knowledgeably
+known
+knuckle/DSMG
+knuckleduster/S
+knucklehead/MS
+knurl/SGMD
+koala/SM
+koan/S
+kohl
+kohlrabi/M
+kohlrabies
+kola/MS
+kook/MS
+kookaburra/SM
+kookiness/M
+kooky/TPR
+kopeck/MS
+kopek/SM
+korma
+kosher/DSG
+kowtow/GMDS
+kph
+kraal/SM
+kraut/SM!
+krill/M
+krona/M
+krone/RM
+kronor
+kronur
+krypton/M
+kr坦na/M
+kr坦nur
+kt
+kuchen/SM
+kudos/M
+kudzu/SM
+kumquat/MS
+kvetch/ZGMDRS
+kvetcher/M
+kw
+l/SDXTGJ
+la/M
+lab/SM
+label's
+label/ASDG
+labeled/U
+labia
+labial/SM
+labile
+labium/M
+labor/SMDRZG
+laboratory/SM
+laborer/M
+laborious/PY
+laboriousness/M
+laborsaving
+laburnum/MS
+labyrinth/M
+labyrinthine
+labyrinths
+lac/M
+lace's
+lace/UGDS
+lacerate/DSGNX
+laceration/M
+lacewing/SM
+lacework/M
+lachrymal
+lachrymose
+lack/MDSG
+lackadaisical/Y
+lackey/SM
+lackluster
+laconic
+laconically
+lacquer/GMDS
+lacrimal
+lacrosse/M
+lactate/GNDS
+lactation/M
+lacteal
+lactic
+lactose/M
+lacuna/M
+lacunae
+lacy/RT
+lad/SGMDNJ
+ladder/GSMD
+laddie/SM
+laddish/P
+lade/S
+laden/U
+lading/M
+ladle/DSMG
+lady/SM
+ladybird/SM
+ladybug/MS
+ladyfinger/MS
+ladylike/U
+ladylove/MS
+ladyship/MS
+laetrile/M
+lag/SZMR
+lager/M
+laggard/MYS
+lagged
+lagging/M
+lagniappe/SM
+lagoon/SM
+laid/IA
+lain
+lair/MS
+laird/SM
+laity/M
+lake/MS
+lakefront/S
+lakeside
+lallygag/S
+lallygagged
+lallygagging
+lam/SM
+lama/MS
+lamasery/SM
+lamb/MDSG
+lambada/MS
+lambast/GDS
+lambaste/S
+lambda/SM
+lambency/M
+lambent/Y
+lambkin/SM
+lambskin/SM
+lambswool
+lame/MYZTGDRSP
+lamebrain/MDS
+lameness/M
+lament/BSMDG
+lamentably
+lamentation/MS
+lamina/M
+laminae
+laminar
+laminate/MGNDS
+lamination/M
+lammed
+lamming
+lamp/MS
+lampblack/M
+lamplight/MRZ
+lamplighter/M
+lampoon/SGMD
+lamppost/SM
+lamprey/MS
+lampshade/SM
+lanai/SM
+lance/DRSMZG
+lancer/M
+lancet/SM
+land/MDRSGJ
+landau/SM
+landfall/MS
+landfill/MS
+landholder/SM
+landholding/MS
+landing/M
+landlady/SM
+landless/M
+landline/MS
+landlocked
+landlord/MS
+landlubber/MS
+landmark/MS
+landmass/MS
+landmine/S
+landowner/MS
+landownership
+landowning/SM
+landscape/MZGDRS
+landscaper/M
+landslid
+landslide/MGS
+landslip/S
+landsman/M
+landsmen
+landward/S
+lane/MS
+language/MS
+languid/PY
+languidness/M
+languish/DSG
+languor/SM
+languorous/Y
+lank/RYTP
+lankiness/M
+lankness/M
+lanky/RTP
+lanolin/M
+lantern/MS
+lanthanum/M
+lanyard/MS
+lap/SM
+laparoscopic
+laparoscopy
+laparotomy
+lapboard/SM
+lapdog/SM
+lapel/SM
+lapidary/SM
+lapin/SM
+lapped
+lappet/SM
+lapping
+lapse/AKGMSD
+laptop/SM
+lapwing/MS
+larboard/SM
+larcenist/SM
+larcenous
+larceny/SM
+larch/MS
+lard/MDRSZG
+larder/M
+lardy/RT
+large/RSPMYT
+largehearted
+largeness/M
+largess/M
+largish
+largo/SM
+lariat/SM
+lark/MDSG
+larkspur/SM
+larva/M
+larvae
+larval
+laryngeal
+larynges
+laryngitis/M
+larynx/M
+lasagna/MS
+lascivious/YP
+lasciviousness/M
+lase/ZGDRS
+laser/M
+lash/MDSGJ
+lashing/M
+lass/MS
+lassie/SM
+lassitude/M
+lasso/SMDG
+last/MDYSG
+lasting/Y
+lat/S
+latch's
+latch/UDSG
+latchkey/SM
+late/YTRP
+latecomer/MS
+latency/M
+lateness/M
+latent
+lateral/MDYSG
+latest/M
+latex/M
+lath/MDRSZG
+lathe/M
+lather/GMD
+lathery
+laths
+latices
+latish
+latitude/MS
+latitudinal
+latitudinarian/MS
+latrine/MS
+latte/RSM
+latter/MY
+lattice/MDS
+latticework/SM
+laud/MDSGB
+laudably
+laudanum/M
+laudatory
+laugh/BMDG
+laughably
+laughing/MY
+laughingstock/SM
+laughs
+laughter/M
+launch/AGMDS
+launcher/SM
+launchpad/SM
+launder/DRZGS
+launderer/M
+launderette/SM
+laundress/MS
+laundromat/MS
+laundry/SM
+laundryman/M
+laundrymen
+laundrywoman/M
+laundrywomen
+laureate/MS
+laureateship/M
+laurel/SM
+lav/SGD
+lava/M
+lavage/M
+lavaliere/SM
+lavatorial
+lavatory/SM
+lave/S
+lavender/SM
+lavish/PTGDRSY
+lavishness/M
+law/SM
+lawbreaker/SM
+lawbreaking/M
+lawful/UPY
+lawfulness/UM
+lawgiver/MS
+lawless/PY
+lawlessness/M
+lawmaker/MS
+lawmaking/M
+lawman/M
+lawmen
+lawn/MS
+lawnmower/SM
+lawrencium/M
+lawsuit/MS
+lawyer/SM
+lax/TRYP
+laxative/MS
+laxity/M
+laxness/M
+lay/AICSGM
+layabout/S
+layaway/M
+layer/CSM
+layered
+layering/M
+layette/MS
+layman/M
+laymen
+layoff/SM
+layout/SM
+layover/MS
+laypeople
+layperson/MS
+layup/SM
+laywoman/M
+laywomen
+laze/MGDS
+lazily
+laziness/M
+lazy/DRSTGP
+lazybones/M
+lb/S
+lbw
+lea/SM
+leach/DSG
+lead/MDNRSZG
+leader/M
+leaderless
+leadership/SM
+leading/M
+leaf/MDSG
+leafage/M
+leafless
+leaflet/GMDS
+leafstalk/MS
+leafy/RT
+league/DSMG
+leak/MDSG
+leakage/MS
+leakiness/M
+leaky/PRT
+lean/MDRSTGJP
+leaning/M
+leanness/M
+leap/MDRSZG
+leaper/M
+leapfrog/MS
+leapfrogged
+leapfrogging
+leapt
+learn/AUGDS
+learnability
+learnable
+learnedly
+learner/MS
+learning's
+lease/ADSMG
+leaseback/SM
+leasehold/MRSZ
+leaseholder/M
+leaser/SM
+leash's
+leash/UDSG
+least/M
+leastwise
+leather/MS
+leatherette/M
+leatherneck/MS
+leathery
+leave/DRSMZGJ
+leaven/SGMD
+leavened/U
+leavening/M
+leaver/M
+leavings/M
+lech/MDRSZG
+lecher/M
+lecherous/PY
+lecherousness/M
+lechery/M
+lecithin/M
+lectern/MS
+lecture/MZGDRS
+lecturer/M
+lectureship/SM
+ledge/RSMZ
+ledger/M
+lee/RSMZ
+leech/MDSG
+leek/MS
+leer/MDG
+leeriness/M
+leery/RPT
+leeward/SM
+leeway/M
+left/MRST
+leftism/M
+leftist/SM
+leftmost
+leftover/SM
+leftward/S
+lefty/SM
+leg/SM
+legacy/SM
+legal/SMY
+legalese/M
+legalism/MS
+legalistic
+legalistically
+legality/SM
+legalization/M
+legalize/GDS
+legate/CXMNS
+legatee/MS
+legation's/AC
+legato/SM
+legend/SM
+legendarily
+legendary
+legerdemain/M
+legged
+leggin/SM
+legginess/M
+legging/MS
+leggy/RPT
+leghorn/MS
+legibility/M
+legible
+legibly
+legion/SM
+legionary/SM
+legionnaire/SM
+legislate/DSGNV
+legislation/M
+legislative/Y
+legislator/MS
+legislature/SM
+legit
+legitimacy/M
+legitimate/DSYG
+legitimatize/GDS
+legitimization/M
+legitimize/DSG
+legless
+legman/M
+legmen
+legroom/SM
+legume/MS
+leguminous
+legwarmer/S
+legwork/M
+lei/SM
+leisure/DMY
+leisureliness/M
+leisurewear/M
+leitmotif/MS
+leitmotiv/MS
+lemma/S
+lemme/JG
+lemming/M
+lemon/SM
+lemonade/SM
+lemongrass
+lemony
+lemur/SM
+lend/RSZG
+lender/M
+length/MNX
+lengthen/GD
+lengthily
+lengthiness/M
+lengths
+lengthwise
+lengthy/PRT
+lenience/M
+leniency/M
+lenient/Y
+lenitive
+lens/MS
+lent
+lentil/MS
+lento
+leonine
+leopard/SM
+leopardess/MS
+leotard/SM
+leper/SM
+leprechaun/MS
+leprosy/M
+leprous
+lepta
+lepton/MS
+lesbian/SM
+lesbianism/M
+lesion/MS
+less/MNRX
+lessee/MS
+lessen/GD
+lesson/MS
+lessor/MS
+let/ISM
+letdown/SM
+lethal/Y
+lethargic
+lethargically
+lethargy/M
+letter/ZGMDRS
+letterbomb/S
+letterbox/S
+lettered/U
+letterer/M
+letterhead/MS
+lettering/M
+letterpress/M
+letting/S
+lettuce/MS
+letup/SM
+leucine
+leucotomy/S
+leukemia/M
+leukemic/SM
+leukocyte/MS
+levee/SM
+level/PSZGMDRY
+leveler/M
+levelheaded/P
+levelheadedness/M
+levelness/M
+lever/SGMD
+leverage's
+leverage/CDSG
+leviathan/MS
+levier/M
+levitate/DSGN
+levitation/M
+levity/M
+levy/DRSMZG
+lewd/RYPT
+lewdness/M
+lexer/S
+lexical
+lexicographer/MS
+lexicographic
+lexicographical
+lexicography/M
+lexicon/SM
+lexis
+lg
+liabilities
+liability/AM
+liable/A
+liaise/GDS
+liaison/MS
+liar/MS
+lib/M
+libation/SM
+libber/MS
+libel/SZGMDR
+libeler/M
+libelous
+liberal/MYPS
+liberalism/M
+liberality/M
+liberalization/SM
+liberalize/GDS
+liberalness/M
+liberate/CDSGN
+liberation/CM
+liberator/MS
+libertarian/SM
+libertine/MS
+liberty/SM
+libidinal
+libidinous
+libido/MS
+librarian/MS
+librarianship
+library/SM
+librettist/MS
+libretto/SM
+lice
+license/MGDS
+licensed/U
+licensee/MS
+licentiate/SM
+licentious/YP
+licentiousness/M
+lichen/MS
+licit/Y
+lick/MDJSG
+licking/M
+licorice/SM
+lid/SM
+lidded
+lidless
+lido/MS
+lie/DSM
+lied/MR
+lief/RT
+liege/SM
+lien/MS
+lieu/M
+lieutenancy/M
+lieutenant/MS
+life/MZR
+lifebelt/S
+lifeblood/M
+lifeboat/MS
+lifebuoy/MS
+lifeforms
+lifeguard/SM
+lifeless/YP
+lifelessness/M
+lifelike
+lifeline/MS
+lifelong
+lifer/M
+lifesaver/SM
+lifesaving/M
+lifespan/S
+lifestyle/SM
+lifetime/MS
+lifework/MS
+lift/MDRSZG
+lifter/M
+liftoff/SM
+ligament/MS
+ligate/GNDS
+ligation/M
+ligature/MGDS
+light's/C
+light/CASTGD
+lighted/U
+lighten/SDRZG
+lightener/M
+lighter/SM
+lightface/MD
+lightheaded
+lighthearted/YP
+lightheartedness/M
+lighthouse/MS
+lighting's
+lightly
+lightness/M
+lightning/MDS
+lightproof
+lightship/MS
+lightweight/SM
+ligneous
+lignin
+lignite/M
+lii
+likability/M
+likable/P
+likableness/M
+like/EMGDST
+likeability/M
+likeable/P
+likeableness/M
+likelihood/UM
+likelihoods
+likeliness/UM
+likely/UPRT
+liken/SGD
+likeness/UM
+likenesses
+liker
+likewise
+liking/M
+lilac/SM
+lilliputian
+lilo/S
+lilt/MDSG
+lily/SM
+limb/MS
+limber/UDSG
+limberness/M
+limbless
+limbo/SM
+lime/MGDS
+limeade/SM
+limelight/M
+limerick/SM
+limescale
+limestone/M
+limey/S
+limit's
+limit/CSZGDR
+limitation/CM
+limitations
+limited/U
+limiter's
+limiting/S
+limitless/P
+limitlessness/M
+limn/DSG
+limo/MS
+limousine/MS
+limp/MDRYSPTG
+limpet/MS
+limpid/YP
+limpidity/M
+limpidness/M
+limpness/M
+limy/RT
+linage/M
+linchpin/SM
+linden/MS
+line/MZGDRSJ
+lineage/MS
+lineal/Y
+lineament/SM
+linear/Y
+linearity/M
+linebacker/MS
+lined/U
+linefeed
+lineman/M
+linemen
+linen/SM
+linens/M
+liner/M
+linesman/M
+linesmen
+lineup/MS
+ling/M
+linger/ZGJDRS
+lingerer/M
+lingerie/M
+lingering/Y
+lingo/M
+lingoes
+lingual
+linguine/M
+linguini/SM
+linguist/SM
+linguistic/S
+linguistically
+linguistics/M
+liniment/SM
+lining/M
+link/MDRSG
+linkage/MS
+linkman
+linkmen
+linkup/MS
+linnet/MS
+lino
+linoleum/M
+linseed/M
+lint's
+lint/CDG
+lintel/MS
+lints
+linty/TR
+lion/MS
+lioness/MS
+lionhearted
+lionization/M
+lionize/GDS
+lip/SM
+lipid/SM
+liposuction/M
+lipped
+lippy
+lipread/GRS
+lipreader/M
+lipreading/M
+lipstick/MDSG
+liq
+liquefaction/M
+liquefy/DSG
+liqueur/SM
+liquid/MS
+liquidate/XGNDS
+liquidation/M
+liquidator/MS
+liquidity/M
+liquidize/ZGDRS
+liquidizer/M
+liquor/MDGS
+lira/M
+lire
+lisle/M
+lisp/MDRSZG
+lisper/M
+lissome
+list/MDNSJXG
+listed/U
+listen/BMDRZG
+listener/M
+listeria
+listing/M
+listless/YP
+listlessness/M
+lit/ZR
+litany/SM
+litchi/MS
+lite
+liter/M
+literacy/M
+literal/SMYP
+literalness/M
+literariness/M
+literary/P
+literate/SMY
+literati/M
+literature/M
+lithe/RPYT
+litheness/M
+lithesome
+lithium/M
+lithograph/MDRZG
+lithographer/M
+lithographic
+lithographically
+lithographs
+lithography/M
+lithosphere/SM
+litigant/SM
+litigate/DSGN
+litigation/M
+litigator/MS
+litigious/P
+litigiousness/M
+litmus/M
+litotes/M
+litter/MDRSZG
+litterateur/MS
+litterbug/MS
+litterer/M
+little/MTRP
+littleness/M
+littoral/SM
+litt辿rateur/SM
+liturgical/Y
+liturgist/SM
+liturgy/SM
+livability/M
+livable/U
+live/ATGDSB
+livelihood/SM
+liveliness/M
+livelong/S
+lively/PRT
+liven/SGD
+liver's
+liver/S
+liveried
+liverish
+liverwort/MS
+liverwurst/M
+livery/CSM
+liveryman/CM
+liverymen/C
+livestock/M
+liveware
+livid/Y
+living/MS
+lix/K
+lizard/MS
+ll
+llama/SM
+llano/SM
+lo
+load's
+load/AUGSD
+loadable
+loader/MS
+loading's
+loaf/MDRSZG
+loafer/M
+loam/M
+loamy/TR
+loan/MDRSZG
+loaner/M
+loansharking/M
+loanword/MS
+loath/JZGDRS
+loathe
+loather/M
+loathing/M
+loathsome/PY
+loathsomeness/M
+loaves
+lob/SMD
+lobar
+lobbed
+lobber/MS
+lobbing
+lobby/GDSM
+lobbyist/MS
+lobe/MS
+lobotomize/DSG
+lobotomy/SM
+lobster/MS
+local/SMY
+locale/MS
+locality/SM
+localization/M
+localize/DSG
+locate/EAGNDS
+location's/A
+location/ESM
+locator/MS
+locavore/SM
+loci
+lock/MDRSBZG
+locker/M
+locket/MS
+lockjaw/M
+lockout/MS
+locksmith/M
+locksmiths
+lockstep/M
+lockup/MS
+loco/S
+locomotion/M
+locomotive/MS
+locoweed/SM
+locum/S
+locus/M
+locust/SM
+locution/MS
+lode/MS
+lodestar/MS
+lodestone/MS
+lodge/DRSJMZG
+lodger/M
+lodging/M
+lodgings/M
+loft/MDSG
+loftily
+loftiness/M
+lofty/PRT
+log/SM
+loganberry/SM
+logarithm/SM
+logarithmic
+logbook/SM
+loge/MS
+logged
+logger/SM
+loggerhead/SM
+loggia/SM
+logging/M
+logic/M
+logical/Y
+logicality/M
+logician/MS
+login/SM
+logistic/S
+logistical/Y
+logistics/M
+logjam/SM
+logo/MS
+logoff/SM
+logon/SM
+logotype/SM
+logout/SM
+logrolling/M
+logy/RT
+loin/MS
+loincloth/M
+loincloths
+loiter/ZGSDR
+loiterer/M
+loitering/M
+lolcat/SM
+loll/DSG
+lollipop/SM
+lollop/GSD
+lolly/S
+lollygag/S
+lollygagged
+lollygagging
+lollypop/MS
+lone/YZR
+loneliness/M
+lonely/PTR
+loner/M
+lonesome/YP
+lonesomeness/M
+long's
+long/KDSTG
+longboat/MS
+longbow/MS
+longer
+longevity/M
+longhair/MS
+longhand/M
+longhorn/MS
+longhouse/S
+longing/MYS
+longish
+longitude/MS
+longitudinal/Y
+longshoreman/M
+longshoremen
+longsighted
+longstanding
+longtime
+longueur/SM
+longways
+loo
+loofah/M
+loofahs
+look/MDRSZG
+lookalike/MS
+looker/M
+lookout/MS
+lookup
+loom/MDSG
+loon/MS
+loonie/M
+loony/RSMT
+loop/MDSG
+loophole/MS
+loopy/RT
+loos/NRX
+loose/UDSTG
+loosely
+loosen/UGSD
+looseness/M
+loot/MDRSZG
+looter/M
+looting/M
+lop/S
+lope/MGDS
+lopped
+lopping
+lopsided/YP
+lopsidedness/M
+loquacious/PY
+loquaciousness/M
+loquacity/M
+lord/MDYSG
+lordliness/M
+lordly/TPR
+lordship/SM
+lore/M
+lorgnette/SM
+loris/MS
+lorn
+lorry/SM
+lose/ZGRSJ
+loser/M
+losing/M
+loss/MS
+lossless
+lost
+lot/SM
+lotion/SM
+lottery/SM
+lotto/M
+lotus/MS
+louche
+loud/RYTP
+loudhailer/SM
+loudmouth/MD
+loudmouths
+loudness/M
+loudspeaker/MS
+lough
+loughs
+lounge/MZGDRS
+lounger/M
+lour/DSG
+louse's
+louse/CDSG
+lousily
+lousiness/M
+lousy/TPR
+lout/MS
+loutish/PY
+louver/MDS
+lovableness/M
+lovably
+love/MYZGDRSB
+lovebird/SM
+lovechild/M
+loved/U
+loveless
+loveliness/M
+lovelorn
+lovely/RSMTP
+lovemaking/M
+lover/M
+loveseat/SM
+lovesick
+lovey/S
+loving/Y
+low/SZTGMDRYP
+lowborn
+lowboy/MS
+lowbrow/SM
+lowdown/M
+lower/GD
+lowercase/M
+lowermost
+lowish
+lowland/SZMR
+lowlander/M
+lowlife/SM
+lowliness/M
+lowly/TPR
+lowness/M
+lox/M
+loyal/ETY
+loyaler
+loyalism/M
+loyalist/SM
+loyalties
+loyalty/EM
+lozenge/SM
+ltd
+luau/MS
+lubber/MYS
+lube/MGDS
+lubricant/SM
+lubricate/DSGN
+lubrication/M
+lubricator/MS
+lubricious/Y
+lubricity/M
+lucid/PY
+lucidity/M
+lucidness/M
+luck/MDSG
+luckily/U
+luckiness/UM
+luckless
+lucky/UPTR
+lucrative/YP
+lucrativeness/M
+lucre/M
+lucubrate/GNDS
+lucubration/M
+ludicrous/YP
+ludicrousness/M
+ludo
+luff/DSG
+lug/SM
+luge/S
+luggage/M
+lugged
+lugger/MS
+lugging
+lughole/S
+lugsail/SM
+lugubrious/YP
+lugubriousness/M
+lukewarm/YP
+lukewarmness/M
+lull/MDSG
+lullaby/SM
+lulu/S
+lumbago/M
+lumbar
+lumber/MDRZGS
+lumberer/M
+lumbering/M
+lumberjack/SM
+lumberman/M
+lumbermen
+lumberyard/SM
+lumen
+luminary/SM
+luminescence/M
+luminescent
+luminosity/M
+luminous/Y
+lummox/MS
+lump/MDNSG
+lumpectomy/S
+lumpenproletariat
+lumpiness/M
+lumpish
+lumpy/TRP
+lunacy/SM
+lunar
+lunatic/SM
+lunch/GMDS
+lunchbox/S
+luncheon/SM
+luncheonette/SM
+lunchroom/MS
+lunchtime/MS
+lung/MDSG
+lunge/SM
+lungfish/MS
+lungful/S
+lunkhead/MS
+lupine/MS
+lupus/M
+lurch/GMDS
+lure/MGDS
+lurgy
+lurid/PY
+luridness/M
+lurk/DRSZG
+luscious/PY
+lusciousness/M
+lush/MRSYPT
+lushness/M
+lust/MDRSG
+luster/M
+lusterless
+lustful/Y
+lustily
+lustiness/M
+lustrous/Y
+lusty/PTR
+lutanist/SM
+lute/MS
+lutenist/SM
+lutetium/M
+lux
+luxuriance/M
+luxuriant/Y
+luxuriate/DSGN
+luxuriation/M
+luxurious/PY
+luxuriousness/M
+luxury/SM
+lvi
+lvii
+lxi
+lxii
+lxiv
+lxix
+lxvi
+lxvii
+lyceum/MS
+lychee/MS
+lychgate/S
+lye/MG
+lying/M
+lymph/M
+lymphatic/SM
+lymphocyte/SM
+lymphoid
+lymphoma/SM
+lynch/JZGDRS
+lyncher/M
+lynching/M
+lynx/MS
+lyre/MS
+lyrebird/MS
+lyric/SM
+lyrical/Y
+lyricism/M
+lyricist/SM
+lysosomal
+lysosomes
+m/KAS
+ma'am
+ma/SMH
+mac/SGMD
+macabre
+macadam/M
+macadamia/SM
+macadamize/GDS
+macaque/MS
+macaroni/MS
+macaroon/MS
+macaw/SM
+mace/MS
+macerate/DSGN
+maceration/M
+mach/M
+machete/SM
+machinate/GNDSX
+machination/M
+machine/DSMGB
+machinery/M
+machinist/MS
+machismo/M
+macho/M
+mack/MS
+mackerel/SM
+mackinaw/SM
+mackintosh/MS
+macrame/M
+macram辿/M
+macro/SM
+macrobiotic/S
+macrobiotics/M
+macrocosm/SM
+macroeconomic/S
+macroeconomics/M
+macrology/S
+macron/MS
+macrophages
+macroscopic
+mad/SMYP
+madam/SM
+madame/M
+madcap/MS
+madden/DGS
+maddening/Y
+madder/MS
+maddest
+madding
+made/AU
+mademoiselle/MS
+madhouse/SM
+madman/M
+madmen
+madness/M
+madras/MS
+madrasa/SM
+madrasah/M
+madrasahs
+madrassa/SM
+madrigal/SM
+madwoman/M
+madwomen
+maelstrom/SM
+maestro/SM
+mafia/SM
+mafiosi
+mafioso/M
+mag/SM
+magazine/SM
+mage/MS
+magenta/M
+maggot/MS
+maggoty
+magi/M
+magic/SM
+magical/Y
+magician/SM
+magicked
+magicking
+magisterial/Y
+magistracy/M
+magistrate/SM
+magma/M
+magnanimity/M
+magnanimous/Y
+magnate/SM
+magnesia/M
+magnesium/M
+magnet/MS
+magnetic
+magnetically
+magnetism/M
+magnetite/M
+magnetizable
+magnetization/CM
+magnetize/CGDS
+magneto/SM
+magnetometer/SM
+magnetosphere
+magnification/M
+magnificence/M
+magnificent/Y
+magnifier/M
+magnify/ZGXDRSN
+magniloquence/M
+magniloquent
+magnitude/SM
+magnolia/MS
+magnon
+magnum/MS
+magpie/MS
+magus/M
+maharaja/SM
+maharajah/M
+maharajahs
+maharanee/MS
+maharani/SM
+maharishi/SM
+mahatma/SM
+mahjong/M
+mahogany/SM
+mahout/MS
+maid/MNSX
+maiden/MY
+maidenhair/M
+maidenhead/SM
+maidenhood/M
+maidservant/SM
+mail/JMDRSZG
+mailbag/SM
+mailbomb/GSD
+mailbox/MS
+mailer/M
+mailing/M
+maillot/SM
+mailman/M
+mailmen
+mailshot/S
+maim/DSG
+main/MYS
+mainframe/SM
+mainland/MS
+mainline/MGDS
+mainmast/MS
+mainsail/MS
+mainspring/MS
+mainstay/MS
+mainstream/SMDG
+maintain/ZGBDRS
+maintainability
+maintainable/U
+maintained/U
+maintenance/M
+maintop/SM
+maisonette/MS
+maize/SM
+majestic
+majestically
+majesty/SM
+majolica/M
+major/SGMDY
+majordomo/MS
+majorette/MS
+majoritarian/SM
+majoritarianism
+majority/SM
+make's/A
+make/UAGS
+makeover/MS
+maker/SM
+makeshift/SM
+makeup/MS
+makeweight/S
+making/MS
+makings/M
+malachite/M
+maladjusted
+maladjustment/M
+maladministration
+maladroit/PY
+maladroitness/M
+malady/SM
+malaise/M
+malamute/MS
+malapropism/SM
+malaria/M
+malarial
+malarkey/M
+malathion/M
+malcontent/MS
+male/MPS
+malediction/SM
+malefaction/M
+malefactor/SM
+malefic
+maleficence/M
+maleficent
+maleness/M
+malevolence/M
+malevolent/Y
+malfeasance/M
+malformation/SM
+malformed
+malfunction/MDSG
+malice/M
+malicious/PY
+maliciousness/M
+malign/DSG
+malignancy/SM
+malignant/Y
+malignity/M
+malinger/ZGSDR
+malingerer/M
+mall/MS
+mallard/SM
+malleability/M
+malleable
+mallet/MS
+mallow/MS
+malnourished
+malnutrition/M
+malocclusion/M
+malodorous
+malpractice/SM
+malt/MDSG
+malted/MS
+maltose/M
+maltreat/GLDS
+maltreatment/M
+malty/TR
+malware/M
+mam/S
+mama/MS
+mamba/SM
+mambo/SGMD
+mamma/M
+mammal/MS
+mammalian/MS
+mammary
+mammogram/MS
+mammography/M
+mammon/M
+mammoth/M
+mammoths
+mammy/SM
+man's/F
+man/USY
+manacle/DSMG
+manage/ZGDRSL
+manageability/M
+manageable/U
+management/MS
+manager/M
+manageress/S
+managerial
+manana/MS
+manatee/SM
+mandala/SM
+mandamus/MS
+mandarin/MS
+mandate/DSMG
+mandatory
+mandible/MS
+mandibular
+mandolin/MS
+mandrake/MS
+mandrel/SM
+mandrill/MS
+mane/MDS
+manege/M
+maneuver/MDGSBJ
+maneuverability/M
+manful/Y
+manga/M
+manganese/M
+mange/DRMZ
+manger/M
+mangetout/S
+manginess/M
+mangle/MZGDRS
+mango/M
+mangoes
+mangrove/MS
+mangy/TRP
+manhandle/GDS
+manhole/SM
+manhood/M
+manhunt/SM
+mania/SM
+maniac/MS
+maniacal/Y
+manic/SM
+manically
+manicure/MGDS
+manicurist/MS
+manifest/MDYSG
+manifestation/SM
+manifesto/SM
+manifold/GMDS
+manikin/SM
+manila/M
+manioc/MS
+manipulable
+manipulate/XGNVDS
+manipulation/M
+manipulative/Y
+manipulator/MS
+mankind/M
+manky
+manlike
+manliness/M
+manly/UTR
+manna/M
+manned/U
+mannequin/SM
+manner/MDYS
+mannerism/SM
+mannerly/U
+manning/U
+mannish/YP
+mannishness/M
+manometer/SM
+manor/SM
+manorial
+manpower/M
+manque
+manqu辿
+mansard/MS
+manse/SXMN
+manservant/M
+mansion/M
+manslaughter/M
+manta/SM
+mantel/MS
+mantelpiece/SM
+mantelshelf
+mantelshelves
+mantes
+mantilla/SM
+mantis/MS
+mantissa/SM
+mantle's
+mantle/EGDS
+mantra/MS
+manual/MYS
+manufacture/DRSMZG
+manufacturer/M
+manufacturing/M
+manumission/SM
+manumit/S
+manumitted
+manumitting
+manure/MGDS
+manuscript/MS
+many/M
+man竪ge/M
+map's
+map/AS
+maple/SM
+mapmaker/SM
+mapped/A
+mapper/MS
+mapping/S
+mar/S
+marabou/MS
+marabout/SM
+maraca/MS
+maraschino/MS
+marathon/SMRZ
+marathoner/M
+maraud/ZGDRS
+marauder/M
+marble/MGDS
+marbleize/GDS
+marbling/M
+march/ZGMDRS
+marcher/M
+marchioness/MS
+mare/MS
+margarine/M
+margarita/MS
+marge
+margin/MS
+marginal/YS
+marginalia/M
+marginalization/M
+marginalize/GDS
+maria/M
+mariachi/MS
+marigold/MS
+marijuana/M
+marimba/SM
+marina/MS
+marinade/DSMG
+marinara/M
+marinate/DSGN
+marination/M
+marine/MZRS
+mariner/M
+marionette/MS
+marital/Y
+maritime
+marjoram/M
+mark/AMDSG
+markdown/SM
+marked/U
+markedly
+marker/MS
+market/MDRZGBS
+marketability/M
+marketable/U
+marketeer/SM
+marketer/M
+marketing/M
+marketplace/SM
+marking/SM
+markka/M
+markkaa
+marksman/M
+marksmanship/M
+marksmen
+markup/MS
+marl/M
+marlin/MS
+marlinespike/SM
+marmalade/M
+marmoreal
+marmoset/SM
+marmot/MS
+maroon/MDGS
+marque/MS
+marquee/SM
+marquess/MS
+marquetry/M
+marquis/MS
+marquise/M
+marquisette/M
+marred/U
+marriage/ASM
+marriageability/M
+marriageable
+married/SM
+marring
+marrow/MS
+marry/AGDS
+marsh/MS
+marshal/SMDG
+marshland/SM
+marshmallow/SM
+marshy/RT
+marsupial/MS
+mart/MNSX
+marten/M
+martensite
+martial/Y
+martian/S
+martin/MS
+martinet/MS
+martingale/MS
+martini/SM
+martyr/MDGS
+martyrdom/M
+marvel/MDGS
+marvelous/Y
+marzipan/M
+masc
+mascara/GMDS
+mascot/MS
+masculine/SM
+masculinity/M
+maser/SM
+mash/MDRSZG
+masher/M
+mashup/MS
+mask's
+mask/UDSG
+masker/MS
+masochism/M
+masochist/SM
+masochistic
+masochistically
+mason/SM
+masonic
+masonry/M
+masque/MS
+masquerade/DRSMZG
+masquerader/M
+mass/MDSGV
+massacre/MGDS
+massage/DSMG
+masseur/SM
+masseuse/MS
+massif/MS
+massive/PY
+massiveness/M
+mast/MDS
+mastectomy/SM
+master's
+master/ADGS
+masterclass/S
+masterful/Y
+masterly
+mastermind/SGMD
+masterpiece/MS
+masterstroke/SM
+masterwork/MS
+mastery/M
+masthead/MS
+mastic/M
+masticate/GNDS
+mastication/M
+mastiff/SM
+mastitis
+mastodon/SM
+mastoid/SM
+masturbate/GNDS
+masturbation/M
+masturbatory
+mat/SZGMDR
+matador/SM
+match/AMS
+matchbook/SM
+matchbox/MS
+matched/U
+matching
+matchless
+matchlock/SM
+matchmaker/MS
+matchmaking/M
+matchstick/MS
+matchwood/M
+mate/MS
+material/SMY
+materialism/M
+materialist/SM
+materialistic
+materialistically
+materialization/M
+materialize/DSG
+materiel/M
+maternal/Y
+maternity/M
+matey/S
+mathematical/Y
+mathematician/SM
+mathematics/M
+matinee/SM
+mating/M
+matins/M
+matin辿e/SM
+matriarch/M
+matriarchal
+matriarchs
+matriarchy/SM
+matrices
+matricidal
+matricide/MS
+matriculate/DSGN
+matriculation/M
+matrimonial
+matrimony/M
+matrix/M
+matron/MYS
+matte/DRSMZG
+matter/MDG
+matting/M
+mattock/SM
+mattress/MS
+maturate/GNDS
+maturation/M
+mature/YTGDRS
+maturity/SM
+matzo/SMH
+matzoh/M
+matzohs
+matzot
+mat辿riel/M
+maudlin
+maul/MDRSZG
+mauler/M
+maunder/SDG
+mausoleum/SM
+mauve/M
+maven/SM
+maverick/SM
+maw/SM
+mawkish/PY
+mawkishness/M
+max/GMDS
+maxi/MS
+maxilla/M
+maxillae
+maxillary
+maxim/SM
+maxima
+maximal/Y
+maximization/M
+maximize/GDS
+maximum/SM
+may/M
+maybe/SM
+mayday/MS
+mayflower/MS
+mayfly/SM
+mayhem/M
+mayn't
+mayo/M
+mayonnaise/M
+mayor/SM
+mayoral
+mayoralty/M
+mayoress/MS
+maypole/SM
+mayst
+maze/MS
+mazurka/MS
+ma単ana/M
+mdse
+me/DSH
+mead/M
+meadow/MS
+meadowlark/MS
+meager/PY
+meagerness/M
+meal/MS
+mealiness/M
+mealtime/SM
+mealy/TPR
+mealybug/SM
+mealymouthed
+mean/MRYJPSTG
+meander/SMDJG
+meanderings/M
+meanie/M
+meaning/M
+meaningful/PY
+meaningfulness/M
+meaningless/YP
+meaninglessness/M
+meanness/M
+meant/U
+meantime/M
+meanwhile/M
+meany/SM
+meas
+measles/M
+measly/RT
+measurable
+measurably
+measure's
+measure/ADSG
+measured/U
+measureless
+measurement/MS
+meat/MS
+meatball/MS
+meathead/MS
+meatiness/M
+meatless
+meatloaf/M
+meatloaves
+meatpacking/M
+meaty/TPR
+mecca/SM
+mechanic/MS
+mechanical/Y
+mechanics/M
+mechanism/SM
+mechanistic
+mechanistically
+mechanization/M
+mechanize/DSG
+medal/SM
+medalist/MS
+medallion/SM
+meddle/ZGDRS
+meddler/M
+meddlesome
+media/SM
+medial/AY
+median/MS
+mediate/ADSGN
+mediated/U
+mediation/AM
+mediator/MS
+medic/SM
+medicaid/M
+medical/SMY
+medicament/M
+medicare/M
+medicate/GNXDS
+medication/M
+medicinal/Y
+medicine/MS
+medico/MS
+medieval
+medievalist/MS
+mediocre
+mediocrity/SM
+meditate/DSGNVX
+meditation/M
+meditative/Y
+medium/MS
+medley/MS
+medulla/SM
+medusa
+medusae
+meed/M
+meek/RYPT
+meekness/M
+meerschaum/SM
+meet/MJSG
+meeting/M
+meetinghouse/SM
+meetup/MS
+meg/S
+mega
+megabit/SM
+megabucks/M
+megabyte/MS
+megachurch/MS
+megacycle/SM
+megadeath/M
+megadeaths
+megagram/S
+megahertz/M
+megajoule/S
+megalith/M
+megalithic
+megaliths
+megalomania/M
+megalomaniac/SM
+megalopolis/MS
+megameter/S
+megapascal/S
+megaphone/DSMG
+megapixel/SM
+megastar/S
+megaton/SM
+megawatt/MS
+meh
+meiosis/M
+meiotic
+melamine/M
+melancholia/M
+melancholic/S
+melancholy/M
+melange/MS
+melanin/M
+melanoma/SM
+meld/MDSG
+melee/SM
+meliorate/GNVDS
+melioration/M
+mellifluous/PY
+mellifluousness/M
+mellow/PTGDRYS
+mellowness/M
+melodic
+melodically
+melodious/YP
+melodiousness/M
+melodrama/MS
+melodramatic/S
+melodramatically
+melodramatics/M
+melody/SM
+melon/SM
+melt's
+melt/ADSG
+meltdown/SM
+member's
+member/EAS
+membership/SM
+membrane/SM
+membranous
+meme/MS
+memento/MS
+memo/MS
+memoir/MS
+memorabilia/M
+memorability/M
+memorable/U
+memorably
+memorandum/MS
+memorial/SM
+memorialize/DSG
+memorization/M
+memorize/DSG
+memory/SM
+memsahib/S
+men/M
+menace/MGDS
+menacing/Y
+menage/MS
+menagerie/MS
+mend/MDRSZG
+mendacious/Y
+mendacity/M
+mendelevium/M
+mender/M
+mendicancy/M
+mendicant/SM
+mending/M
+menfolk/MS
+menfolks/M
+menhaden/M
+menial/MYS
+meningeal
+meninges
+meningitis/M
+meninx/M
+menisci
+meniscus/M
+menopausal
+menopause/M
+menorah/M
+menorahs
+mensch/MS
+menservants
+menses/M
+menstrual
+menstruate/GNDS
+menstruation/M
+mensurable
+mensuration/M
+menswear/M
+mental/Y
+mentalist/SM
+mentality/SM
+menthol/M
+mentholated
+mention/GSMD
+mentioned/U
+mentor/MDSG
+mentorship
+menu/MS
+meow/MDSG
+mercantile
+mercantilism/M
+mercenary/SM
+mercer/MS
+mercerize/GDS
+merchandise/MZGDRS
+merchandiser/M
+merchandising/M
+merchant/MBS
+merchantman/M
+merchantmen
+merciful/UY
+merciless/PY
+mercilessness/M
+mercurial/Y
+mercuric
+mercury/M
+mercy/SM
+mere/MYTS
+meretricious/YP
+meretriciousness/M
+merganser/MS
+merge/DRSZG
+merger/M
+meridian/MS
+meringue/MS
+merino/MS
+merit/CSM
+merited/U
+meriting
+meritless
+meritocracy/SM
+meritocratic
+meritorious/PY
+meritoriousness/M
+mermaid/SM
+merman/M
+mermen
+merrily
+merriment/M
+merriness/M
+merry/TRP
+merrymaker/MS
+merrymaking/M
+mesa/MS
+mescal/MS
+mescalin
+mescaline/M
+mesdames
+mesdemoiselles
+mesh/MDSG
+mesmeric
+mesmerism/M
+mesmerize/ZGDRS
+mesmerizer/M
+mesomorph/M
+mesomorphs
+meson/SM
+mesosphere/SM
+mesquite/SM
+mess/MDSG
+message/MGDS
+messeigneurs
+messenger/SM
+messiah/M
+messiahs
+messianic
+messieurs
+messily
+messiness/M
+messmate/SM
+messy/PTR
+mestizo/MS
+met
+meta
+metabolic
+metabolically
+metabolism/SM
+metabolite/SM
+metabolize/DSG
+metacarpal/SM
+metacarpi
+metacarpus/M
+metadata
+metal/SMD
+metalanguage/MS
+metallic
+metallurgic
+metallurgical
+metallurgist/MS
+metallurgy/M
+metalwork/MRZG
+metalworker/M
+metalworking/M
+metamorphic
+metamorphism/M
+metamorphose/GDS
+metamorphosis/M
+metaphor/MS
+metaphoric
+metaphorical/Y
+metaphysical/Y
+metaphysics/M
+metastases
+metastasis/M
+metastasize/DSG
+metastatic
+metatarsal/MS
+metatarsi
+metatarsus/M
+metatheses
+metathesis/M
+mete/MZGDRS
+metempsychoses
+metempsychosis/M
+meteor/MS
+meteoric
+meteorically
+meteorite/SM
+meteoroid/SM
+meteorologic
+meteorological
+meteorologist/SM
+meteorology/M
+meter/GMD
+metformin
+methadone/M
+methamphetamine/M
+methane/M
+methanol/M
+methinks
+method/MS
+methodical/YP
+methodicalness/M
+methodological/Y
+methodology/SM
+methotrexate
+methought
+meths
+methyl/M
+meticulous/YP
+meticulousness/M
+metier/MS
+metric/S
+metrical/Y
+metricate/GNDS
+metrication/M
+metricize/GDS
+metro/SM
+metronome/MS
+metropolis/MS
+metropolitan
+mettle/M
+mettlesome
+mew/SGMD
+mewl/DSG
+mews/M
+mezzanine/MS
+mezzo/SM
+mfg
+mfr/S
+mg
+mgr
+mi/MNX
+miasma/MS
+mic/S
+mica/M
+mice
+mick/S
+mickey/MS
+micro/SM
+microaggression/SM
+microbe/MS
+microbial
+microbiological
+microbiologist/MS
+microbiology/M
+microbrewery/SM
+microchip/MS
+microcircuit/SM
+microcode
+microcomputer/MS
+microcosm/MS
+microcosmic
+microdot/SM
+microeconomics/M
+microelectronic/S
+microelectronics/M
+microfiber/MS
+microfiche/M
+microfilm/GMDS
+microfinance
+microfloppies
+microgroove/SM
+microlight/MS
+microloan/MS
+micromanage/ZGDRSL
+micromanagement/M
+micromanager/M
+micrometeorite/SM
+micrometer/MS
+micron/MS
+microorganism/MS
+microphone/SM
+microplastics
+microprocessor/MS
+microscope/SM
+microscopic
+microscopical/Y
+microscopy/M
+microsecond/MS
+microsurgery/M
+microwave/DSMGB
+microwaveable
+mid
+midair/M
+midday/M
+midden/MS
+middle/MGS
+middlebrow/SM
+middleman/M
+middlemen
+middlemost
+middleweight/MS
+middy/SM
+midfield/RZ
+midge/SM
+midget/MS
+midi/MS
+midland/MS
+midlife/M
+midmost
+midnight/M
+midpoint/MS
+midrib/MS
+midriff/MS
+midsection/MS
+midshipman/M
+midshipmen
+midships
+midsize
+midst/M
+midstream/M
+midsummer/M
+midterm/MS
+midtown/M
+midway/MS
+midweek/MS
+midwife/MGDS
+midwifery/SM
+midwinter/M
+midwived
+midwives
+midwiving
+midyear/MS
+mien/M
+miff/DSG
+might've
+might/M
+mightily
+mightiness/M
+mightn't
+mighty/TRP
+mignonette/SM
+migraine/MS
+migrant/MS
+migrate/AGDS
+migration/SM
+migratory
+mikado/MS
+mike/MGDS
+mil/SZMR
+milady/SM
+milch
+mild/MRYTP
+mildew/SMDG
+mildness/M
+mile/MS
+mileage/SM
+milepost/MS
+miler/M
+milestone/MS
+milf/MS
+milieu/SM
+militancy/M
+militant/MYS
+militarily
+militarism/M
+militarist/SM
+militaristic
+militarization/CM
+militarize/CDSG
+military/M
+militate/GDS
+militia/SM
+militiaman/M
+militiamen
+milk/MDRSZG
+milker/M
+milkiness/M
+milkmaid/MS
+milkman/M
+milkmen
+milkshake/SM
+milksop/MS
+milkweed/SM
+milky/RTP
+mill/MDRSZGJ
+millage/M
+millennia
+millennial/M
+millennium/MS
+miller/M
+millet/M
+milliard/MS
+millibar/MS
+milligram/MS
+milliliter/MS
+millimeter/MS
+milliner/MS
+millinery/M
+milling/M
+million/HSM
+millionaire/SM
+millionairess/S
+millionth/M
+millionths
+millipede/SM
+millisecond/SM
+millpond/SM
+millrace/SM
+millstone/SM
+millstream/MS
+millwright/SM
+milometer/S
+milquetoast/SM
+milt/MDSG
+mime/MGDS
+mimeograph/GMD
+mimeographs
+mimetic
+mimic/SM
+mimicked
+mimicker/SM
+mimicking
+mimicry/SM
+mimosa/SM
+min
+minaret/MS
+minatory
+mince/DRSMZG
+mincemeat/M
+mincer/M
+mind's
+mind/ADRSZG
+mindbogglingly
+minded/P
+mindful/YP
+mindfulness/M
+mindless/YP
+mindlessness/M
+mindset/MS
+mine/MZGNDRSX
+minefield/SM
+miner/M
+mineral/MS
+mineralogical
+mineralogist/MS
+mineralogy/M
+minestrone/M
+minesweeper/SM
+mingle/DSG
+mingy
+mini/MS
+miniature/MS
+miniaturist/MS
+miniaturization/M
+miniaturize/GDS
+minibar/S
+minibike/SM
+minibus/MS
+minicab/S
+minicam/MS
+minicomputer/SM
+minifloppies
+minim/SM
+minima
+minimal/Y
+minimalism/M
+minimalist/MS
+minimization/M
+minimize/DSG
+minimum/MS
+mining/M
+minion/M
+miniseries/M
+miniskirt/MS
+minister/SGMD
+ministerial
+ministrant/MS
+ministration/MS
+ministry/SM
+minivan/MS
+mink/MS
+minnesinger/MS
+minnow/SM
+minor/SMDG
+minority/SM
+minoxidil/M
+minster/MS
+minstrel/SM
+minstrelsy/M
+mint/MDRSZG
+mintage/M
+minter/M
+minty/RT
+minuend/MS
+minuet/SM
+minus/MS
+minuscule/MS
+minute/PDRSMYTG
+minuteman/M
+minutemen
+minuteness/M
+minutia/M
+minutiae
+minx/MS
+miracle/MS
+miraculous/Y
+mirage/SM
+mire/MGDS
+mirror/GSMD
+mirth/M
+mirthful/PY
+mirthfulness/M
+mirthless/Y
+miry/RT
+misaddress/DSG
+misadventure/MS
+misaligned
+misalignment/M
+misalliance/MS
+misanthrope/SM
+misanthropic
+misanthropically
+misanthropist/MS
+misanthropy/M
+misapplication/M
+misapply/DSGNX
+misapprehend/GSD
+misapprehension/MS
+misappropriate/XDSGN
+misappropriation/M
+misbegotten
+misbehave/GDS
+misbehavior/M
+misc
+miscalculate/DSXGN
+miscalculation/M
+miscall/DSG
+miscarriage/MS
+miscarry/GDS
+miscast/SG
+miscegenation/M
+miscellaneous/Y
+miscellany/SM
+mischance/SM
+mischief/M
+mischievous/YP
+mischievousness/M
+miscibility/M
+miscible
+misclassified
+miscommunication/S
+misconceive/GDS
+misconception/SM
+misconduct/MDGS
+misconstruction/MS
+misconstrue/GDS
+miscount/MDSG
+miscreant/SM
+miscue/DSMG
+misdeal/GMS
+misdealt
+misdeed/MS
+misdemeanor/MS
+misdiagnose/GDS
+misdiagnosis/M
+misdid
+misdirect/SDG
+misdirection/M
+misdo/JG
+misdoes
+misdoing/M
+misdone
+miser/SBMY
+miserableness/M
+miserably
+miserliness/M
+misery/SM
+misfeasance/M
+misfeature/S
+misfile/GDS
+misfire/MGDS
+misfit/SM
+misfitted
+misfitting
+misfortune/SM
+misgiving/MS
+misgovern/SDGL
+misgovernment/M
+misguidance/M
+misguide/DSG
+misguided/Y
+mishandle/DSG
+mishap/SM
+mishear/GS
+misheard
+mishit/S
+mishitting
+mishmash/MS
+misidentify/GDS
+misinform/DGS
+misinformation/M
+misinterpret/SGD
+misinterpretation/SM
+misjudge/DSG
+misjudgment/SM
+mislabel/GSD
+mislaid
+mislay/GS
+mislead/GS
+misleading/Y
+misled
+mismanage/LGDS
+mismanagement/M
+mismatch/GMDS
+misname/GDS
+misnomer/MS
+misogamist/MS
+misogamy/M
+misogynist/SM
+misogynistic
+misogynous
+misogyny/M
+misplace/GLDS
+misplacement/M
+misplay/GMDS
+misprint/GMDS
+misprision/M
+mispronounce/DSG
+mispronunciation/SM
+misquotation/MS
+misquote/MGDS
+misread/GJS
+misreading/M
+misremember/GDS
+misreport/MDGS
+misrepresent/GDS
+misrepresentation/MS
+misrule/MGDS
+miss's
+miss/EDSGV
+missal/ESM
+missed/U
+misshape/GDS
+misshapen
+missile/MS
+missilery/M
+mission/AMS
+missionary/SM
+missioner/SM
+missis/MS
+missive/MS
+misspeak/GS
+misspell/GDJS
+misspelling/M
+misspend/GS
+misspent
+misspoke
+misspoken
+misstate/GDSL
+misstatement/SM
+misstep/MS
+missus/MS
+mist's
+mist/CDRSZG
+mistakable/U
+mistake/BMGS
+mistaken/Y
+mister's
+mistily
+mistime/GDS
+mistiness/M
+mistletoe/M
+mistook
+mistral/MS
+mistranslated
+mistreat/LDGS
+mistreatment/M
+mistress/MS
+mistrial/MS
+mistrust/MDSG
+mistrustful/Y
+misty/PRT
+mistype/GS
+misunderstand/SGJ
+misunderstanding/M
+misunderstood
+misuse/DSMG
+mite/MZRS
+miter/MDG
+mitigate/DSGN
+mitigated/U
+mitigation/M
+mitochondria
+mitochondrial
+mitochondrion
+mitoses
+mitosis/M
+mitotic
+mitral
+mitt/MNSX
+mitten/M
+mitzvah
+mix/ZGMDRSB
+mixed/U
+mixer/M
+mixture/SM
+mizzen/MS
+mizzenmast/SM
+mkay
+mks
+ml
+mm
+mnemonic/MS
+mnemonically
+mo/CKHS
+moan/MDRSZG
+moaner/M
+moat/MDS
+mob's
+mob/CS
+mobbed/C
+mobbing/C
+mobile/MS
+mobility/M
+mobilization/CM
+mobilizations
+mobilize/CDSG
+mobilizer/SM
+mobster/SM
+moccasin/SM
+mocha/SM
+mock/DRSZG
+mocker/M
+mockery/SM
+mocking/Y
+mockingbird/SM
+mod/STM
+modal/SM
+modality/S
+modded
+modding
+mode/MS
+model/ZGSJMDR
+modeler/M
+modeling/M
+modem/SM
+moderate/MYGNPDS
+moderateness/M
+moderation/M
+moderator/SM
+modern/MYPS
+modernism/M
+modernist/SM
+modernistic
+modernity/M
+modernization/M
+modernize/DRSZG
+modernizer/M
+modernness/M
+modest/Y
+modesty/M
+modicum/SM
+modifiable
+modification/M
+modified/U
+modifier/M
+modify/DRSXZGN
+modish/YP
+modishness/M
+modular
+modularization
+modulate/CGNDS
+modulation/CM
+modulations
+modulator/MS
+module/MS
+modulo
+modulus
+moggy
+mogul/SM
+mohair/M
+moi
+moiety/SM
+moil/MDSG
+moire/SM
+moist/XTPNRY
+moisten/DRZG
+moistener/M
+moistness/M
+moisture/M
+moisturize/ZGDRS
+moisturizer/M
+molar/SM
+molasses/M
+mold/MDRJSZG
+moldboard/SM
+molder/GMD
+moldiness/M
+molding/M
+moldy/TPR
+mole/MS
+molecular
+molecularity/M
+molecule/SM
+molehill/SM
+moleskin/M
+molest/DRZGS
+molestation/M
+molested/U
+molester/M
+moll/MS
+mollification/M
+mollify/DSNG
+mollusc/SM
+molluscan/SM
+mollusk/SM
+molluskan/S
+molly/SM
+mollycoddle/DSMG
+molt/MDNRSZG
+molter/M
+molybdenum/M
+mom/SM
+moment/MS
+momenta
+momentarily
+momentariness/M
+momentary/P
+momentous/PY
+momentousness/M
+momentum/M
+mommy/SM
+monad
+monarch/M
+monarchic
+monarchical
+monarchism/M
+monarchist/MS
+monarchistic
+monarchs
+monarchy/SM
+monastery/SM
+monastic/MS
+monastical/Y
+monasticism/M
+monaural
+monetarily
+monetarism/M
+monetarist/MS
+monetary
+monetization/C
+monetize/CGDS
+money/SMD
+moneybag/MS
+moneybox/S
+moneygrubber/SM
+moneygrubbing/M
+moneylender/SM
+moneymaker/SM
+moneymaking/M
+monger/MDGS
+mongol/S
+mongolism/M
+mongoloid/MS
+mongoose/MS
+mongrel/SM
+monies
+moniker/SM
+monism/M
+monist/MS
+monition/SM
+monitor/SMDG
+monitory
+monk/MS
+monkey/MDGS
+monkeyshine/SM
+monkish
+monkshood/SM
+mono/M
+monochromatic
+monochrome/MS
+monocle/DSM
+monoclonal
+monocotyledon/SM
+monocotyledonous
+monocular
+monodic
+monodist/SM
+monody/SM
+monogamist/MS
+monogamous/Y
+monogamy/M
+monogram/SM
+monogrammed
+monogramming
+monograph/M
+monographs
+monolingual/MS
+monolith/M
+monolithic
+monoliths
+monologist/SM
+monologue/SM
+monologuist/SM
+monomania/M
+monomaniac/MS
+monomaniacal
+monomer/SM
+mononucleosis/M
+monophonic
+monoplane/SM
+monopolist/SM
+monopolistic
+monopolization/M
+monopolize/DRSZG
+monopolizer/M
+monopoly/SM
+monorail/MS
+monosyllabic
+monosyllable/MS
+monotheism/M
+monotheist/SM
+monotheistic
+monotone/MS
+monotonic
+monotonically
+monotonous/PY
+monotonousness/M
+monotony/M
+monounsaturated
+monoxide/MS
+monseigneur/M
+monsieur/M
+monsignor/SM
+monsoon/SM
+monsoonal
+monster/SM
+monstrance/ASM
+monstrosity/SM
+monstrous/Y
+montage/SM
+month/MY
+monthly/SM
+months
+monument/MS
+monumental/Y
+moo/SGMD
+mooch/ZGMDRS
+moocher/M
+mood/MS
+moodily
+moodiness/M
+moody/TPR
+moon/MDSG
+moonbeam/MS
+moonless
+moonlight/SMDRZG
+moonlighter/M
+moonlighting/M
+moonlit
+moonscape/SM
+moonshine/MZRS
+moonshiner/M
+moonshot/MS
+moonstone/MS
+moonstruck
+moonwalk/MS
+moor/MDJSG
+moorhen/S
+mooring/M
+moorland/MS
+moose/M
+moot/DSG
+mop/SZGMDR
+mope/MS
+moped/SM
+moper/M
+mopey
+mopier
+mopiest
+mopish
+mopped
+moppet/MS
+mopping
+moraine/SM
+moral/SMY
+morale/M
+moralism
+moralist/MS
+moralistic
+moralistically
+moralities
+morality/UM
+moralization/CM
+moralize/CGDS
+moralizer/MS
+morass/MS
+moratorium/SM
+moray/SM
+morbid/YP
+morbidity/M
+morbidness/M
+mordancy/M
+mordant/SMY
+more/MS
+moreish
+morel/SM
+moreover
+mores/M
+morgue/MS
+moribund
+morn/MJSG
+morning/M
+morocco/M
+moron/SM
+moronic
+moronically
+morose/YP
+moroseness/M
+morph/GD
+morpheme/MS
+morphemic
+morphia/M
+morphine/M
+morphing/M
+morphological
+morphology/M
+morphs
+morrow/MS
+morsel/MS
+mortal/MYS
+mortality/M
+mortar/MDSG
+mortarboard/SM
+mortgage's
+mortgage/AGDS
+mortgagee/MS
+mortgagor/MS
+mortician/MS
+mortification/M
+mortify/NGDS
+mortise/DSMG
+mortuary/SM
+mosaic/MS
+mosey/SGD
+mosh/DSG
+mosque/MS
+mosquito/M
+mosquitoes
+moss/MS
+mossback/SM
+mossy/TR
+most/MY
+mot/SM
+mote's
+mote/KCXSVN
+motel/SM
+motet/SM
+moth/M
+mothball/GMDS
+mother/MDYSG
+motherboard/SM
+motherfucker/MS!
+motherfucking/!
+motherhood/M
+motherland/MS
+motherless
+motherliness/M
+moths
+motif/SM
+motile/S
+motility/M
+motion/KCM
+motioned
+motioning
+motionless/YP
+motionlessness/M
+motivate/CDSG
+motivated/U
+motivation/SM
+motivational
+motivator/SM
+motive/MS
+motiveless
+motley/MS
+motlier
+motliest
+motocross/MS
+motor/SGMD
+motorbike/MGDS
+motorboat/MS
+motorcade/MS
+motorcar/SM
+motorcycle/DSMG
+motorcyclist/MS
+motorist/SM
+motorization/M
+motorize/DSG
+motorman/M
+motormen
+motormouth/M
+motormouths
+motorway/SM
+mottle/GDS
+motto/M
+mottoes
+moue/MS
+mound/SGMD
+mount/EASGMD
+mountable
+mountain/SM
+mountaineer/SMDG
+mountaineering/M
+mountainous
+mountainside/SM
+mountaintop/SM
+mountebank/MS
+mounted/U
+mounter/MS
+mounting/SM
+mourn/SZGDR
+mourned/U
+mourner/M
+mournful/YP
+mournfulness/M
+mourning/M
+mouse/DRSMZG
+mouser/M
+mousetrap/SM
+mousetrapped
+mousetrapping
+mousey
+mousiness/M
+moussaka/S
+mousse/MGDS
+mousy/PTR
+mouth/GMD
+mouthfeel
+mouthful/MS
+mouthiness/M
+mouthpiece/MS
+mouths
+mouthwash/MS
+mouthwatering
+mouthy/PTR
+mouton/M
+movable/SM
+move/AMZGDRSB
+moveable/SM
+moved/U
+movement/SM
+mover/AM
+movie/SM
+moviegoer/SM
+moving/Y
+mow/SZGMDR
+mower/M
+moxie/M
+mozzarella/M
+mp
+mpg
+mph
+mt
+mtg
+mtge
+mu/SM
+much/M
+mucilage/M
+mucilaginous
+muck/MDSG
+muckrake/DRSZG
+muckraker/M
+mucky/TR
+mucous
+mucus/M
+mud/M
+muddily
+muddiness/M
+muddle/MGDS
+muddleheaded
+muddy/PTGDRS
+mudflap/S
+mudflat/MS
+mudguard/SM
+mudpack/S
+mudroom/MS
+mudslide/MS
+mudslinger/SM
+mudslinging/M
+muenster/M
+muesli
+muezzin/MS
+muff/MDSG
+muffin/MS
+muffle/ZGDRS
+muffler/M
+mufti/SM
+mug/SM
+mugful/MS
+mugged
+mugger/MS
+mugginess/M
+mugging/MS
+muggins
+muggle/MS
+muggy/PTR
+mugshot/MS
+mugwump/MS
+mujaheddin
+mujahedin/M
+mukluk/MS
+mulatto/M
+mulattoes
+mulberry/SM
+mulch/GMDS
+mulct/SGMD
+mule/MS
+muleskinner/MS
+muleteer/MS
+mulish/PY
+mulishness/M
+mull/DSG
+mullah/M
+mullahs
+mullein/M
+mullet/MS
+mulligan/SM
+mulligatawny/M
+mullion/SMD
+multi
+multicellular
+multichannel
+multicolored
+multicultural
+multiculturalism/M
+multidimensional
+multidisciplinary
+multifaceted
+multifamily
+multifarious/PY
+multifariousness/M
+multiform
+multigrain
+multilateral/Y
+multilayered
+multilevel
+multilingual
+multilingualism/M
+multimedia/M
+multimillionaire/SM
+multinational/SM
+multipart
+multiparty
+multiplayer/M
+multiple/MS
+multiplex/ZGMDRS
+multiplexer/M
+multiplicand/MS
+multiplication/M
+multiplicative
+multiplicity/SM
+multiplier/M
+multiply/NZGDRSX
+multiprocessing
+multiprocessor/SM
+multipurpose
+multiracial
+multistage
+multistory
+multitask/GS
+multitasking/M
+multitude/SM
+multitudinous
+multivariate
+multiverse/SM
+multivitamin/MS
+multiyear
+mum
+mumble/MZGDRS
+mumbler/M
+mumbletypeg/M
+mummer/MS
+mummery/M
+mummification/M
+mummify/GNDS
+mummy/SM
+mumps/M
+mun
+munch/GDS
+munchie/S
+munchies/M
+munchkin/SM
+mundane/SY
+mung/DSG
+municipal/SMY
+municipality/SM
+munificence/M
+munificent/Y
+munition/MDGS
+mural/SM
+muralist/SM
+murder/ZGMDRS
+murderer/M
+murderess/MS
+murderous/Y
+murk/MS
+murkily
+murkiness/M
+murky/PTR
+murmur/ZGJMDRS
+murmurer/M
+murmuring/M
+murmurous
+murrain/M
+muscat/MS
+muscatel/SM
+muscle/MGDS
+musclebound
+muscleman
+musclemen
+muscly
+muscular/Y
+muscularity/M
+musculature/M
+musculoskeletal
+muse/MGDSJ
+musette/MS
+museum/MS
+mush/MDRSZG
+mushiness/M
+mushroom/GSMD
+mushy/PTR
+music/SM
+musical/MYS
+musicale/MS
+musicality/M
+musician/SMY
+musicianship/M
+musicological
+musicologist/MS
+musicology/M
+musing/MY
+musk/M
+muskeg/MS
+muskellunge/MS
+musket/MS
+musketeer/MS
+musketry/M
+muskie/M
+muskiness/M
+muskmelon/SM
+muskox/MN
+muskrat/MS
+musky/PTRS
+muslin/M
+muss/MDSG
+mussel/MS
+mussy/TR
+must've
+must/MRSZ
+mustache/MDS
+mustachio/SMD
+mustang/MS
+mustard/M
+muster/GMD
+mustily
+mustiness/M
+mustn't
+musty/PTR
+mutability/M
+mutably
+mutagen/MS
+mutagenic
+mutant/MS
+mutate/XGNVDS
+mutation/M
+mutational
+mute/MYTGDRSPB
+muteness/M
+mutilate/DSGNX
+mutilation/M
+mutilator/SM
+mutineer/SM
+mutinous/Y
+mutiny/GDSM
+mutt/MS
+mutter/ZGJMDRS
+mutterer/M
+muttering/M
+mutton/M
+muttonchops/M
+muttony
+mutual/Y
+mutuality/M
+muumuu/MS
+muzak
+muzzily
+muzzle/DSMG
+muzzy/P
+my
+mycologist/SM
+mycology/M
+myelitis/M
+myna/MS
+mynah/MS
+myocardial
+myocardium
+myopia/M
+myopic
+myopically
+myriad/SM
+myrmidon/MS
+myrrh/M
+myrtle/SM
+mys
+myself
+mysterious/PY
+mysteriousness/M
+mystery/SM
+mystic/SM
+mystical/Y
+mysticism/M
+mystification/CM
+mystify/CDSGN
+mystique/M
+myth/M
+mythic
+mythical
+mythological
+mythologist/SM
+mythologize/DSG
+mythology/SM
+myths
+myxomatosis
+m辿tier/MS
+m棚l辿e/MS
+n/IKTH
+naan/S
+nab/S
+nabbed
+nabbing
+nabob/SM
+nacelle/SM
+nacho/SM
+nacre/M
+nacreous
+nadir/SM
+nae
+naff/RT
+nag/SM
+nagged
+nagger/MS
+nagging
+nagware
+nah
+naiad/SM
+naif/MS
+nail/MDSG
+nailbrush/MS
+naive/RYT
+naivete/M
+naivety/M
+naivet辿/M
+naked/PY
+nakedness/M
+name's
+name/AGDS
+nameable/U
+named/U
+nameless/Y
+namely
+nameplate/MS
+namesake/SM
+nanny/SM
+nanobot/S
+nanometer/S
+nanosecond/SM
+nanotechnology/SM
+nanotube
+nap/SM
+napalm/MDSG
+nape/MS
+naphtha/M
+naphthalene/M
+napkin/MS
+napless
+napoleon/SM
+napped
+napper/MS
+napping
+nappy/TRSM
+narc/MS
+narcissism/M
+narcissist/MS
+narcissistic
+narcissus/M
+narcolepsy/M
+narcoleptic
+narcoses
+narcosis/M
+narcotic/SM
+narcotization/M
+narcotize/GDS
+nark
+narky
+narrate/GNVDSX
+narration/M
+narrative/SM
+narrator/SM
+narrow/PTGMDRYS
+narrowness/M
+narwhal/MS
+nary
+nasal/SMY
+nasality/M
+nasalization/M
+nasalize/DSG
+nascence/AM
+nascent/A
+nastily
+nastiness/M
+nasturtium/SM
+nasty/PTR
+natal
+natch
+nation/MS
+national/MYS
+nationalism/M
+nationalist/SM
+nationalistic
+nationalistically
+nationality/SM
+nationalization/MS
+nationalize/CDSG
+nationhood/M
+nationwide
+native/MS
+nativity/SM
+natl
+natter/GMDS
+nattily
+nattiness/M
+natty/PTR
+natural's
+natural/UPY
+naturalism/M
+naturalist/SM
+naturalistic
+naturalization/M
+naturalize/DSG
+naturalness/UM
+naturals
+nature's
+nature/CS
+naturism
+naturist/S
+naught/MS
+naughtily
+naughtiness/M
+naughty/PTR
+nausea/M
+nauseam
+nauseate/GDS
+nauseating/Y
+nauseous/PY
+nauseousness/M
+nautical/Y
+nautilus/MS
+naval
+nave/MS
+navel/SM
+navigability/M
+navigable
+navigate/DSGN
+navigation/M
+navigational
+navigator/MS
+navvy/S
+navy/SM
+nay/SM
+naysayer/MS
+ne'er
+neanderthal/MS
+neap/MS
+near/DRYSPTG
+nearby
+nearness/M
+nearshore
+nearside
+nearsighted/YP
+nearsightedness/M
+neat/NRYPXT
+neaten/GD
+neath
+neatness/M
+nebula/M
+nebulae
+nebular
+nebulous/PY
+nebulousness/M
+necessarily/U
+necessary/SM
+necessitate/DSG
+necessitous
+necessity/SM
+neck/MDSG
+neckband/S
+neckerchief/MS
+necking/M
+necklace/MGDSJ
+neckline/MS
+necktie/MS
+necrology/M
+necromancer/SM
+necromancy/M
+necrophilia
+necrophiliac/S
+necropolis/MS
+necroses
+necrosis/M
+necrotic
+nectar/M
+nectarine/MS
+nee
+need/MDSG
+needed/U
+needful/Y
+neediness/M
+needle/MGDS
+needlepoint/M
+needless/YP
+needlessness/M
+needlewoman/M
+needlewomen
+needlework/M
+needn't
+needy/PTR
+nefarious/YP
+nefariousness/M
+neg
+negate/DSGNVX
+negation/M
+negative/MYGPDS
+negativeness/M
+negativism/M
+negativity/M
+neglect/SGMD
+neglectful/YP
+neglectfulness/M
+negligee/MS
+negligence/M
+negligent/Y
+negligible
+negligibly
+negotiability/M
+negotiable/A
+negotiate/ADSGN
+negotiation/AM
+negotiations
+negotiator/MS
+negritude/M
+negro
+negroid
+neigh/MDG
+neighbor/SMDYG
+neighborhood/SM
+neighborliness/M
+neighs
+neither
+nelson/SM
+nematode/SM
+nemeses
+nemesis/M
+neoclassic
+neoclassical
+neoclassicism/M
+neocolonialism/M
+neocolonialist/MS
+neocon/SM
+neoconservative/SM
+neocortex
+neodymium/M
+neolithic
+neologism/SM
+neon/M
+neonatal
+neonate/MS
+neophilia
+neophyte/MS
+neoplasm/MS
+neoplastic
+neoprene/M
+nepenthe/M
+nephew/SM
+nephrite/M
+nephritic
+nephritis/M
+nephropathy
+nepotism/M
+nepotist/SM
+nepotistic
+neptunium/M
+nerd/MS
+nerdy/RT
+nerve's
+nerve/UDSG
+nerveless/YP
+nervelessness/M
+nerviness/M
+nervous/YP
+nervousness/M
+nervy/TPR
+nest/MDSG
+nestle/GJDS
+nestling/M
+net/SM
+netball
+netbook/MS
+nether
+nethermost
+netherworld/M
+netiquette/S
+netted
+netter/S
+netting/M
+nettle/MGDS
+nettlesome
+network/SGMD
+networking/M
+neural/Y
+neuralgia/M
+neuralgic
+neurasthenia/M
+neurasthenic/MS
+neuritic/MS
+neuritis/M
+neurological/Y
+neurologist/SM
+neurology/M
+neuron/MS
+neuronal
+neuroscience
+neuroses
+neurosis/M
+neurosurgeon/MS
+neurosurgery/M
+neurosurgical
+neurotic/MS
+neurotically
+neuroticism
+neurotransmitter/SM
+neut
+neuter/MDGS
+neutral/SMY
+neutralism/M
+neutralist/SM
+neutrality/M
+neutralization/M
+neutralize/DRSZG
+neutralizer/M
+neutrino/SM
+neutron/SM
+never
+nevermore
+nevertheless
+nevi
+nevus/M
+new/STMRYP
+newbie/MS
+newborn/SM
+newcomer/SM
+newel/SM
+newfangled
+newfound
+newline/S
+newlywed/SM
+newness/M
+news/M
+newsagent/S
+newsboy/SM
+newscast/SMRZ
+newscaster/M
+newsdealer/SM
+newsflash/S
+newsgirl/SM
+newsgroup/MS
+newshound/S
+newsletter/MS
+newsman/M
+newsmen
+newspaper/MS
+newspaperman/M
+newspapermen
+newspaperwoman/M
+newspaperwomen
+newspeak
+newsprint/M
+newsreader/S
+newsreel/MS
+newsroom/MS
+newsstand/SM
+newsweekly/SM
+newswoman/M
+newswomen
+newsworthiness/M
+newsworthy/P
+newsy/TR
+newt/MS
+newton/MS
+next/M
+nexus/MS
+niacin/M
+nib/SM
+nibble/MZGDRS
+nibbler/M
+nice/PYTR
+niceness/M
+nicety/SM
+niche/SM
+nick/MDRSZG
+nickel/MS
+nickelodeon/SM
+nicker/MDG
+nickle/S
+nickname/DSMG
+nicotine/M
+niece/SM
+nifedipine
+niff
+niffy
+nifty/TR
+nigga/MS!
+niggard/SMY
+niggardliness/M
+niggaz/!
+nigger/SM!
+niggle/MZGDRS
+niggler/M
+nigh/RT
+night/SMY
+nightcap/SM
+nightclothes/M
+nightclub/SM
+nightclubbed
+nightclubbing
+nightdress/MS
+nightfall/M
+nightgown/SM
+nighthawk/SM
+nightie/M
+nightingale/SM
+nightlife/M
+nightlight/S
+nightlong
+nightmare/SM
+nightmarish
+nightshade/SM
+nightshirt/SM
+nightspot/MS
+nightstand/SM
+nightstick/SM
+nighttime/M
+nightwatchman
+nightwatchmen
+nightwear/M
+nighty/SM
+nihilism/M
+nihilist/MS
+nihilistic
+nil/M
+nimbi
+nimble/TPR
+nimbleness/M
+nimbly
+nimbus/M
+nimby
+nimrod/MS
+nincompoop/SM
+nine/MS
+ninepin/MS
+ninepins/M
+nineteen/SMH
+nineteenth/M
+nineteenths
+ninetieth/M
+ninetieths
+ninety/HSM
+ninja/SM
+ninny/SM
+ninth/M
+ninths
+niobium/M
+nip/SM
+nipped
+nipper/MS
+nippiness/M
+nipping
+nipple/MS
+nippy/TPR
+nirvana/M
+nisei/M
+nit/SMR
+nite/MS
+niter/M
+nitpick/SZGDR
+nitpicker/M
+nitpicking/M
+nitrate/DSMGN
+nitration/M
+nitric
+nitrification/M
+nitrite/SM
+nitro
+nitrocellulose/M
+nitrogen/M
+nitrogenous
+nitroglycerin/M
+nitroglycerine/M
+nitwit/MS
+nix/GMDS
+no/SM
+nob/SY
+nobble/GDS
+nobelium/M
+nobility/M
+noble/RSPMT
+nobleman/M
+noblemen
+nobleness/M
+noblewoman/M
+noblewomen
+nobody/SM
+nocturnal/Y
+nocturne/MS
+nod/SM
+nodal
+nodded
+nodding
+noddle/MS
+noddy
+node/MS
+nodular
+nodule/MS
+noel/MS
+noes
+noggin/MS
+nohow
+noise/DSMG
+noiseless/PY
+noiselessness/M
+noisemaker/MS
+noisily
+noisiness/M
+noisome
+noisy/PTR
+nomad/SM
+nomadic
+nomenclature/MS
+nominal/Y
+nominate/ACGNVDS
+nomination's/A
+nomination/CSM
+nominative/SM
+nominator/CSM
+nominee/MS
+non
+nonabrasive
+nonabsorbent/SM
+nonacademic
+nonacceptance/M
+nonacid
+nonactive/MS
+nonaddictive
+nonadhesive
+nonadjacent
+nonadjustable
+nonadministrative
+nonage/MS
+nonagenarian/MS
+nonaggression/M
+nonalcoholic
+nonaligned
+nonalignment/M
+nonallergic
+nonappearance/MS
+nonassignable
+nonathletic
+nonattendance/M
+nonautomotive
+nonavailability/M
+nonbasic
+nonbeliever/MS
+nonbelligerent/MS
+nonbinding
+nonbreakable
+nonburnable
+noncaloric
+noncancerous
+nonce/M
+nonchalance/M
+nonchalant/Y
+nonchargeable
+nonclerical/MS
+nonclinical
+noncollectable
+noncom/MS
+noncombat
+noncombatant/MS
+noncombustible
+noncommercial/MS
+noncommittal/Y
+noncommunicable
+noncompeting
+noncompetitive
+noncompliance/M
+noncomplying
+noncomprehending
+nonconducting
+nonconductor/MS
+nonconforming
+nonconformism
+nonconformist/MS
+nonconformity/M
+nonconsecutive
+nonconstructive
+noncontagious
+noncontinuous
+noncontributing
+noncontributory
+noncontroversial
+nonconvertible
+noncooperation/M
+noncorroding
+noncorrosive
+noncredit
+noncriminal/SM
+noncritical
+noncrystalline
+noncumulative
+noncustodial
+nondairy
+nondeductible/M
+nondelivery/SM
+nondemocratic
+nondenominational
+nondepartmental
+nondepreciating
+nondescript
+nondestructive
+nondetachable
+nondeterminism
+nondeterministic
+nondisciplinary
+nondisclosure/M
+nondiscrimination/M
+nondiscriminatory
+nondramatic
+nondrinker/MS
+nondrying
+none
+noneducational
+noneffective
+nonelastic
+nonelectric
+nonelectrical
+nonempty
+nonenforceable
+nonentity/SM
+nonequivalent/MS
+nonessential
+nonesuch/MS
+nonetheless
+nonevent/MS
+nonexchangeable
+nonexclusive
+nonexempt/M
+nonexistence/M
+nonexistent
+nonexplosive/MS
+nonfactual
+nonfading
+nonfat
+nonfatal
+nonfattening
+nonferrous
+nonfiction/M
+nonfictional
+nonflammable
+nonflowering
+nonfluctuating
+nonflying
+nonfood/M
+nonfreezing
+nonfunctional
+nongovernmental
+nongranular
+nonhazardous
+nonhereditary
+nonhuman
+nonidentical
+noninclusive
+nonindependent
+nonindustrial
+noninfectious
+noninflammatory
+noninflationary
+noninflected
+nonintellectual/MS
+noninterchangeable
+noninterference/M
+nonintervention/M
+nonintoxicating
+noninvasive
+nonirritating
+nonissue
+nonjudgmental
+nonjudicial
+nonlegal
+nonlethal
+nonlinear
+nonliterary
+nonliving/M
+nonmagnetic
+nonmalignant
+nonmember/MS
+nonmetal/SM
+nonmetallic
+nonmigratory
+nonmilitant
+nonmilitary
+nonnarcotic/SM
+nonnative/MS
+nonnegotiable
+nonnuclear
+nonnumerical
+nonobjective
+nonobligatory
+nonobservance/M
+nonobservant
+nonoccupational
+nonoccurence
+nonofficial
+nonoperational
+nonoperative
+nonparallel/MS
+nonpareil/MS
+nonparticipant/MS
+nonparticipating
+nonpartisan/SM
+nonpaying
+nonpayment/SM
+nonperformance/M
+nonperforming
+nonperishable
+nonperson/MS
+nonphysical/Y
+nonplus/S
+nonplussed
+nonplussing
+nonpoisonous
+nonpolitical
+nonpolluting
+nonporous
+nonpracticing
+nonprejudicial
+nonprescription
+nonproductive
+nonprofessional/SM
+nonprofit/SMB
+nonproliferation/M
+nonpublic
+nonpunishable
+nonracial
+nonradioactive
+nonrandom
+nonreactive
+nonreciprocal/SM
+nonreciprocating
+nonrecognition/M
+nonrecoverable
+nonrecurring
+nonredeemable
+nonrefillable
+nonrefundable
+nonreligious
+nonrenewable
+nonrepresentational
+nonresident/MS
+nonresidential
+nonresidual/M
+nonresistance/M
+nonresistant
+nonrestrictive
+nonreturnable/MS
+nonrhythmic
+nonrigid
+nonsalaried
+nonscheduled
+nonscientific
+nonscoring
+nonseasonal
+nonsectarian
+nonsecular
+nonsegregated
+nonsense/M
+nonsensical/Y
+nonsensitive
+nonsexist
+nonsexual
+nonskid
+nonslip
+nonsmoker/SM
+nonsmoking
+nonsocial
+nonspeaking
+nonspecialist/MS
+nonspecializing
+nonspecific
+nonspiritual/SM
+nonstaining
+nonstandard
+nonstarter/MS
+nonstick
+nonstop
+nonstrategic
+nonstriking
+nonstructural
+nonsuccessive
+nonsupport/GM
+nonsurgical
+nonsustaining
+nonsympathizer/M
+nontarnishable
+nontaxable
+nontechnical
+nontenured
+nontheatrical
+nonthinking
+nonthreatening
+nontoxic
+nontraditional
+nontransferable
+nontransparent
+nontrivial
+nontropical
+nonuniform
+nonunion
+nonuser/MS
+nonvenomous
+nonverbal
+nonviable
+nonviolence/M
+nonviolent/Y
+nonvirulent
+nonvocal
+nonvocational
+nonvolatile
+nonvoter/MS
+nonvoting
+nonwhite/MS
+nonworking
+nonyielding
+nonzero
+noodle/MGDS
+nook/MS
+nookie
+nooky
+noon/M
+noonday/M
+noontide/M
+noontime/M
+noose/SM
+nope
+nor
+nor'easter
+norm/MS
+normal/MY
+normalcy/M
+normality/M
+normalization/M
+normalize/DSG
+normative
+north/ZMR
+northbound
+northeast/MRZ
+northeaster/MY
+northeastern
+northeastward/S
+norther/MY
+northerly/SM
+northern/ZR
+northerner/M
+northernmost
+northward/S
+northwest/ZMR
+northwester/MY
+northwestern
+northwestward/S
+nose/MGDS
+nosebag/S
+nosebleed/MS
+nosecone/SM
+nosedive/DSMG
+nosegay/SM
+nosh/MDRSZG
+nosher/M
+nosily
+nosiness/M
+nostalgia/M
+nostalgic
+nostalgically
+nostril/MS
+nostrum/MS
+nosy/RPT
+not/B
+notability/SM
+notable/SM
+notably
+notarial
+notarization/M
+notarize/GDS
+notary/SM
+notate/GDS
+notation/FCSM
+notch/GMDS
+note's
+note/FCSDG
+notebook/MS
+notelet/S
+notepad/S
+notepaper/M
+noteworthiness/M
+noteworthy/P
+nothing/PSM
+nothingness/M
+notice/MGDS
+noticeable/U
+noticeably
+noticeboard/S
+noticed/U
+notifiable
+notification/M
+notifier/M
+notify/NDRSXZG
+notion/MS
+notional/Y
+notoriety/M
+notorious/Y
+notwithstanding
+notwork/S
+nougat/MS
+nought/MS
+noun/KMS
+nourish/DSLG
+nourishment/M
+nous
+nova/MS
+novae
+novel/SM
+novelette/SM
+novelist/SM
+novelization/MS
+novelize/DSG
+novella/MS
+novelty/SM
+novena/MS
+novene
+novice/MS
+novitiate/MS
+now/M
+nowadays/M
+noway/S
+nowhere/M
+nowise
+nowt
+noxious
+nozzle/MS
+nu/SM
+nuance/MDS
+nub/SM
+nubbin/MS
+nubby/TR
+nubile
+nuclear/K
+nucleate/DSGN
+nucleation/M
+nuclei
+nucleic
+nucleoli
+nucleolus/M
+nucleon/SM
+nucleoside
+nucleotide
+nucleus/M
+nude/MTRS
+nudge/GDSM
+nudism/M
+nudist/SM
+nudity/M
+nugatory
+nugget/SM
+nuisance/MS
+nuke/MGDS
+null/S
+nullification/M
+nullify/NDSG
+nullity/M
+numb/ZTGPDRYS
+number's
+number/ASDG
+numbered/U
+numberless
+numbness/M
+numbskull/SM
+numerable/I
+numeracy/IM
+numeral/SM
+numerate/XGNDS
+numeration/M
+numerator/MS
+numeric
+numerical/Y
+numerologist/MS
+numerology/M
+numerous/Y
+numinous
+numismatic/S
+numismatics/M
+numismatist/SM
+numskull/MS
+nun/SM
+nuncio/SM
+nunnery/SM
+nuptial/MS
+nurse/MZGDRS
+nurselings
+nursemaid/MS
+nurser/M
+nursery/SM
+nurseryman/M
+nurserymen
+nursing/M
+nursling/SM
+nurture/DRSMZG
+nurturer/M
+nut/SM
+nutcase/S
+nutcracker/MS
+nuthatch/MS
+nuthouse/S
+nutmeat/SM
+nutmeg/SM
+nutpick/SM
+nutria/SM
+nutrient/MS
+nutriment/MS
+nutrition/M
+nutritional/Y
+nutritionist/SM
+nutritious/YP
+nutritiousness/M
+nutritive
+nutshell/MS
+nutted
+nutter/S
+nuttiness/M
+nutting
+nutty/RTP
+nuzzle/DRSMZG
+nuzzler/M
+nybble/S
+nylon/MS
+nylons/M
+nymph/M
+nymphet/MS
+nympho/S
+nymphomania/M
+nymphomaniac/SM
+nymphs
+n辿e
+o
+o'clock
+o'er
+oaf/SM
+oafish/PY
+oafishness/M
+oak/SMN
+oakum/M
+oar/SGMD
+oarlock/SM
+oarsman/M
+oarsmen
+oarswoman/M
+oarswomen
+oases
+oasis/M
+oat/SMN
+oatcake/SM
+oath/M
+oaths
+oatmeal/M
+oats/M
+ob/S
+obbligato/MS
+obduracy/M
+obdurate/PY
+obdurateness/M
+obedience/EM
+obedient/EY
+obeisance/SM
+obeisant
+obelisk/MS
+obese
+obesity/M
+obey/EDSG
+obfuscate/GNXDS
+obfuscation/M
+obi/SM
+obit/MS
+obituary/SM
+obj
+object/SGVMD
+objectify/NGDS
+objection/SMB
+objectionable/U
+objectionably
+objective/SMYP
+objectiveness/M
+objectivity/M
+objector/MS
+objurgate/XGNDS
+objurgation/M
+oblate/NX
+oblation/M
+obligate/DSXGN
+obligation/M
+obligatorily
+obligatory
+oblige/EGDS
+obliging/Y
+oblique/SMYP
+obliqueness/M
+obliquity/M
+obliterate/DSGN
+obliteration/M
+oblivion/M
+oblivious/YP
+obliviousness/M
+oblong/MS
+obloquy/M
+obnoxious/YP
+obnoxiousness/M
+oboe/MS
+oboist/MS
+obscene/RYT
+obscenity/SM
+obscurantism/M
+obscurantist/SM
+obscure/DRSYTG
+obscurity/SM
+obsequies
+obsequious/PY
+obsequiousness/M
+obsequy/M
+observably
+observance/MS
+observant/Y
+observation/SM
+observational
+observatory/SM
+observe/DRSBZG
+observed/U
+observer/M
+obsess/DSGV
+obsession/SM
+obsessional/Y
+obsessive/PSMY
+obsessiveness/M
+obsidian/M
+obsolesce/DSG
+obsolescence/M
+obsolescent
+obsolete/GDS
+obstacle/MS
+obstetric/S
+obstetrical
+obstetrician/SM
+obstetrics/M
+obstinacy/M
+obstinate/Y
+obstreperous/YP
+obstreperousness/M
+obstruct/DGVS
+obstructed/U
+obstruction/SM
+obstructionism/M
+obstructionist/MS
+obstructive/YP
+obstructiveness/M
+obtain/DBLGS
+obtainable/U
+obtainment/M
+obtrude/DSG
+obtrusion/M
+obtrusive/UPY
+obtrusiveness/UM
+obtuse/YTRP
+obtuseness/M
+obverse/SM
+obviate/DSGN
+obviation/M
+obvious/PY
+obviousness/M
+ocarina/MS
+occasion/GMDS
+occasional/Y
+occidental/SM
+occlude/GDS
+occlusion/SM
+occlusive
+occult/M
+occultism/M
+occultist/SM
+occupancy/M
+occupant/SM
+occupation/AM
+occupational/Y
+occupations
+occupied/U
+occupier/SM
+occupy/ADSG
+occur/AS
+occurred/A
+occurrence/SM
+occurring/A
+ocean/SM
+oceanfront/SM
+oceangoing
+oceanic/M
+oceanographer/SM
+oceanographic
+oceanography/M
+oceanology/M
+ocelot/MS
+och/R
+ocher/M
+ocker/S
+octagon/MS
+octagonal
+octal
+octane/MS
+octave/MS
+octavo/MS
+octet/SM
+octogenarian/SM
+octopus/MS
+ocular/MS
+oculist/SM
+oculomotor
+odalisque/SM
+odd/STRYLP
+oddball/SM
+oddity/SM
+oddment/SM
+oddness/M
+odds/M
+ode/SM
+odious/YP
+odiousness/M
+odium/M
+odometer/MS
+odor/MDS
+odoriferous
+odorless
+odorous
+odyssey/MS
+oedipal
+oenology/M
+oenophile/SM
+oeuvre/MS
+of
+off/SZGDRJ
+offal/M
+offbeat/MS
+offend/ZGDRS
+offender/M
+offense/MS
+offensive's
+offensive/IPY
+offensiveness/IM
+offensives
+offer/JGMD
+offering/M
+offertory/SM
+offhand
+offhanded/PY
+offhandedness/M
+office/MZRS
+officeholder/SM
+officer/M
+official/MYS
+officialdom/M
+officialese
+officialism/M
+officiant/SM
+officiate/DSG
+officiator/MS
+officious/PY
+officiousness/M
+offing/M
+offish
+offline
+offload/SDG
+offprint/SM
+offset/MS
+offsetting
+offshoot/MS
+offshore/G
+offside
+offsite
+offspring/M
+offstage/S
+offtrack
+oft
+often/TR
+oftentimes
+ofttimes
+ogle/MZGDRS
+ogler/M
+ogre/MS
+ogreish
+ogress/MS
+oh/M
+ohm/SM
+ohmmeter/MS
+oho
+ohs
+oi
+oik/S
+oil/SGMD
+oilcan/S
+oilcloth/M
+oilcloths
+oilfield/S
+oiliness/M
+oilman
+oilmen
+oilskin/MS
+oilskins/M
+oily/RPT
+oink/MDSG
+ointment/SM
+okapi/SM
+okay/MDSG
+okra/MS
+old/TMNRP
+oldie/SM
+oldish
+oldness/M
+oldster/MS
+ole/SMV
+oleaginous
+oleander/MS
+oleo/M
+oleomargarine/M
+olfactory/SM
+oligarch/M
+oligarchic
+oligarchical
+oligarchs
+oligarchy/SM
+oligonucleotide/S
+oligopoly/SM
+olive/SM
+ol辿/M
+om/SMNX
+ombudsman/M
+ombudsmen
+omega/SM
+omelet/MS
+omelette/MS
+omen/M
+omicron/MS
+ominous/YP
+ominousness/M
+omission/MS
+omit/S
+omitted
+omitting
+omnibus/MS
+omnipotence/M
+omnipotent
+omnipresence/M
+omnipresent
+omniscience/M
+omniscient
+omnivore/MS
+omnivorous/PY
+omnivorousness/M
+on/Y
+onboard
+once/M
+oncogene/SM
+oncologist/SM
+oncology/M
+oncoming
+one/SXMNP
+oneness/M
+onerous/PY
+onerousness/M
+oneself
+onetime
+ongoing
+onion/M
+onionskin/M
+online
+onlooker/SM
+onlooking
+onomatopoeia/M
+onomatopoeic
+onomatopoetic
+onrush/MSG
+onscreen
+onset/MS
+onshore
+onside
+onsite
+onslaught/MS
+onstage
+onto
+ontogeny/M
+ontological
+ontology/M
+onus/MS
+onward
+onyx/MS
+oodles/M
+ooh/GD
+oohs
+oomph
+oops
+ooze/MGDS
+oozy/TR
+op/SMDG
+opacity/M
+opal/MS
+opalescence/M
+opalescent
+opaque/PYTGDRS
+opaqueness/M
+opcode/S
+ope/S
+open/ZTGJPMDRYS
+opencast
+opened/U
+opener/M
+openhanded/P
+openhandedness/M
+openhearted
+opening/M
+openness/M
+openwork/M
+opera/MS
+operable/I
+operand/S
+operate/DSGNVX
+operatic
+operatically
+operation/M
+operational/Y
+operative/SM
+operator/SM
+operetta/SM
+ophthalmic
+ophthalmologist/SM
+ophthalmology/M
+opiate/SM
+opine/GNXDS
+opinion/M
+opinionated
+opioid/SM
+opium/M
+opossum/MS
+opp
+opponent/SM
+opportune/IY
+opportunism/M
+opportunist/SM
+opportunistic
+opportunistically
+opportunity/SM
+oppose/DSG
+opposed/U
+opposite/SMYNX
+opposition/M
+oppress/DSGV
+oppression/M
+oppressive/YP
+oppressiveness/M
+oppressor/MS
+opprobrious/Y
+opprobrium/M
+opt/SGD
+optic/MS
+optical/Y
+optician/SM
+optics/M
+optima
+optimal/Y
+optimism/SM
+optimist/SM
+optimistic
+optimistically
+optimization/MS
+optimize/DRSG
+optimum/SM
+option/SMDG
+optional/Y
+optometrist/MS
+optometry/M
+opulence/M
+opulent/Y
+opus/MS
+or
+oracle/SM
+oracular
+oral/MYS
+orality
+orange/SMP
+orangeade/MS
+orangery/SM
+orangutan/SM
+orate/GNXDS
+oration/M
+orator/SM
+oratorical/Y
+oratorio/MS
+oratory/SM
+orb/SM
+orbicular
+orbit/MDRZGS
+orbital/SM
+orbiter/M
+orc/SM
+orchard/SM
+orchestra/MS
+orchestral
+orchestrate/DSXGN
+orchestration/M
+orchid/SM
+ordain/SDLG
+ordainment/M
+ordeal/SM
+order/EAMDGS
+ordered/U
+orderings
+orderliness/EM
+orderly/PSM
+ordinal/SM
+ordinance/SM
+ordinarily
+ordinariness/M
+ordinary/SMP
+ordinate/MNSX
+ordination/M
+ordnance/M
+ordure/M
+ore/SM
+oregano/M
+org
+organ/MS
+organdy/M
+organelle/MS
+organic/SM
+organically/I
+organism/MS
+organismic
+organist/MS
+organization/ASM
+organizational/Y
+organize/AESDG
+organized/U
+organizer/MS
+organza/M
+orgasm/SM
+orgasmic
+orgiastic
+orgy/SM
+oriel/MS
+orient's
+orient/AEDGS
+oriental/MS
+orientalist/S
+orientate/EDSGN
+orientation/AEM
+orientations
+orienteering
+orifice/MS
+orig
+origami/M
+origin/SM
+original/MYS
+originality/M
+originate/DSGN
+origination/M
+originator/SM
+oriole/SM
+orison/SM
+ormolu/M
+ornament/SGMD
+ornamental
+ornamentation/M
+ornate/YP
+ornateness/M
+orneriness/M
+ornery/PRT
+ornithological
+ornithologist/MS
+ornithology/M
+orotund
+orotundity/SM
+orphan/SMDG
+orphanage/MS
+orris/MS
+orthodontia/M
+orthodontic/S
+orthodontics/M
+orthodontist/SM
+orthodox/U
+orthodoxy/SM
+orthogonal
+orthogonality
+orthographic
+orthographically
+orthography/SM
+orthopedic/S
+orthopedics/M
+orthopedist/MS
+orzo/M
+oscillate/GNDSX
+oscillation/M
+oscillator/SM
+oscillatory
+oscilloscope/MS
+osculate/DSXGN
+osculation/M
+osier/MS
+osmium/M
+osmosis/M
+osmotic
+osprey/SM
+ossicles
+ossification/M
+ossify/NGDS
+ostensible
+ostensibly
+ostentation/M
+ostentatious/Y
+osteoarthritis/M
+osteopath/M
+osteopathic
+osteopaths
+osteopathy/M
+osteoporosis/M
+ostler/S
+ostracism/M
+ostracize/GDS
+ostrich/MS
+other/MSP
+otherwise
+otherworldly
+otiose
+otter/MS
+ottoman/MS
+oubliette/MS
+ouch
+ought
+oughtn't
+ounce/MS
+our/S
+ourselves
+oust/ZGDRS
+ouster/M
+out/SJGMDR
+outage/SM
+outargue/GDS
+outback/MS
+outbalance/DSG
+outbid/S
+outbidding
+outboard/MS
+outboast/DSG
+outbound
+outbox/MS
+outbreak/MS
+outbuilding/MS
+outburst/SM
+outcast/MS
+outclass/DSG
+outcome/MS
+outcrop/MS
+outcropped
+outcropping/SM
+outcry/SM
+outdated
+outdid
+outdistance/GDS
+outdo/G
+outdoes
+outdone
+outdoor/S
+outdoors/M
+outdoorsy
+outdraw/GS
+outdrawn
+outdrew
+outercourse
+outermost
+outerwear/M
+outface/GDS
+outfall/S
+outfield/SMRZ
+outfielder/M
+outfight/SG
+outfit/SM
+outfitted
+outfitter/MS
+outfitting
+outflank/GSD
+outflow/MS
+outfought
+outfox/GDS
+outgo/MJG
+outgoes
+outgrew
+outgrow/HGS
+outgrown
+outgrowth/M
+outgrowths
+outguess/GDS
+outgun/S
+outgunned
+outgunning
+outhit/S
+outhitting
+outhouse/SM
+outing/M
+outlaid
+outlandish/PY
+outlandishness/M
+outlast/DSG
+outlaw/SGMD
+outlay/SGM
+outlet/SM
+outlier/S
+outline/MGDS
+outlive/GDS
+outlook/MS
+outlying
+outmaneuver/GDS
+outmatch/GDS
+outmoded
+outnumber/DSG
+outpace/GDS
+outpatient/MS
+outperform/GSD
+outplace/L
+outplacement/M
+outplay/GDS
+outpoint/DGS
+outpost/MS
+outpouring/MS
+outproduce/DSG
+output/SM
+outputted
+outputting
+outrace/GDS
+outrage/MGDS
+outrageous/Y
+outran
+outrank/GDS
+outre
+outreach/MDSG
+outrider/MS
+outrigger/SM
+outright
+outrun/S
+outrunning
+outr辿
+outscore/GDS
+outsell/GS
+outset/SM
+outshine/GS
+outshone
+outshout/GDS
+outside/MZRS
+outsider/M
+outsize/MS
+outskirt/MS
+outsmart/GDS
+outsold
+outsource/DSG
+outsourcing/M
+outspend/SG
+outspent
+outspoken/YP
+outspokenness/M
+outspread/GS
+outstanding/Y
+outstation/MS
+outstay/DGS
+outstretch/DSG
+outstrip/S
+outstripped
+outstripping
+outta
+outtake/MS
+outvote/GDS
+outward/YS
+outwear/GS
+outweigh/GD
+outweighs
+outwit/S
+outwith
+outwitted
+outwitting
+outwore
+outwork/MDRSZG
+outworn
+ouzo/MS
+ova
+oval/MS
+ovarian
+ovary/SM
+ovate/NX
+ovation/M
+oven/MS
+ovenbird/SM
+ovenproof
+ovenware
+over/MYS
+overabundance/M
+overabundant
+overachieve/ZGDRS
+overachiever/M
+overact/GVSD
+overage/SM
+overaggressive
+overall/SM
+overalls/M
+overambitious
+overanxious
+overarching
+overarm/GSD
+overate
+overattentive
+overawe/DSG
+overbalance/MGDS
+overbear/GS
+overbearing/Y
+overbid/SM
+overbidding
+overbite/MS
+overblown
+overboard
+overbold
+overbook/DGS
+overbore
+overborne
+overbought
+overbuild/SG
+overbuilt
+overburden/GSD
+overbuy/GS
+overcame
+overcapacity/M
+overcapitalize/DSG
+overcareful
+overcast/MGS
+overcautious
+overcharge/DSMG
+overclock/GD
+overcloud/SGD
+overcoat/MS
+overcome/GS
+overcompensate/DSGN
+overcompensation/M
+overconfidence/M
+overconfident
+overconscientious
+overcook/DGS
+overcritical
+overcrowd/SDG
+overcrowding/M
+overdecorate/DSG
+overdependent
+overdevelop/SDG
+overdid
+overdo/G
+overdoes
+overdone
+overdose/MGDS
+overdraft/SM
+overdraw/GS
+overdrawn
+overdress/GMDS
+overdrew
+overdrive/SM
+overdub/SM
+overdubbed
+overdubbing
+overdue
+overeager
+overeat/GSN
+overemotional
+overemphasis/M
+overemphasize/GDS
+overenthusiastic
+overestimate/MGNDS
+overestimation/M
+overexcite/DSG
+overexercise/GDS
+overexert/SDG
+overexertion/M
+overexpose/GDS
+overexposure/M
+overextend/DGS
+overfed
+overfeed/GS
+overfill/DGS
+overflew
+overflight/MS
+overflow/MDSG
+overflown
+overfly/GS
+overfond
+overfull
+overgeneralize/DSG
+overgenerous
+overgraze/DSG
+overgrew
+overground
+overgrow/HSG
+overgrown
+overgrowth/M
+overhand/MDS
+overhang/MSG
+overhasty
+overhaul/MDSG
+overhead/MS
+overhear/SG
+overheard
+overheat/DSG
+overhung
+overindulge/GDS
+overindulgence/M
+overindulgent
+overinflated
+overjoy/GSD
+overkill/M
+overladen
+overlaid
+overlain
+overland
+overlap/SM
+overlapped
+overlapping
+overlarge
+overlay/GSM
+overleaf
+overlie
+overload/GMDS
+overlong
+overlook/GMDS
+overlord/MS
+overly/SG
+overmanned
+overmanning
+overmaster/SDG
+overmodest
+overmuch/S
+overnice
+overnight/MS
+overoptimism/M
+overoptimistic
+overpaid
+overparticular
+overpass/MS
+overpay/GS
+overplay/GDS
+overpopulate/GNDS
+overpopulation/M
+overpower/SDG
+overpowering/Y
+overpraise/DSG
+overprecise
+overprice/DSG
+overprint/SMDG
+overproduce/GDS
+overproduction/M
+overprotect/SDGV
+overqualified
+overran
+overrate/GDS
+overreach/GDS
+overreact/SDG
+overreaction/SM
+overrefined
+overridden
+override/MGS
+overripe/M
+overrode
+overrule/GDS
+overrun/SM
+overrunning
+oversampling
+oversaw
+oversea/S
+oversee/RSZ
+overseeing
+overseen
+overseer/M
+oversell/GS
+oversensitive/P
+oversensitiveness/M
+oversexed
+overshadow/DSG
+overshare/DSG
+overshoe/MS
+overshoot/GS
+overshot
+oversight/SM
+oversimple
+oversimplification/M
+oversimplify/DSNGX
+oversize/D
+oversleep/GS
+overslept
+oversold
+overspecialization/M
+overspecialize/GDS
+overspend/SG
+overspent
+overspread/GS
+overstaffed
+overstate/DSLG
+overstatement/MS
+overstay/DSG
+overstep/S
+overstepped
+overstepping
+overstimulate/DSG
+overstock/GSD
+overstretch/GDS
+overstrict
+overstrung
+overstuffed
+oversubscribe/DSG
+oversubtle
+oversupply/GDS
+oversuspicious
+overt/Y
+overtake/GS
+overtaken
+overtax/GDS
+overthink/SG
+overthought
+overthrew
+overthrow/SMG
+overthrown
+overtime/MS
+overtire/GDS
+overtone/MS
+overtook
+overture/MS
+overturn/DSG
+overuse/DSMG
+overvaluation/S
+overvalue/DSG
+overview/MS
+overweening/Y
+overweight/M
+overwhelm/SGD
+overwhelming/Y
+overwinter/SDG
+overwork/GMDS
+overwrite/GS
+overwritten
+overwrote
+overwrought
+overzealous
+oviduct/SM
+oviparous
+ovoid/MS
+ovular
+ovulate/DSGN
+ovulation/M
+ovule/MS
+ovum/M
+ow
+owe/DSG
+owl/SM
+owlet/MS
+owlish/Y
+own/ESGD
+owner/MS
+ownership/M
+ox/MN
+oxalate
+oxblood/M
+oxbow/MS
+oxcart/SM
+oxford/SM
+oxidant/MS
+oxidase
+oxidation/M
+oxidative
+oxide/MS
+oxidization/M
+oxidize/ZGDRS
+oxidizer/M
+oxtail/S
+oxyacetylene/M
+oxygen/M
+oxygenate/DSGN
+oxygenation/M
+oxymora
+oxymoron/M
+oyster/SM
+oz
+ozone/M
+p/NRXTGJ
+pH
+pa/SMH
+pablum/M
+pabulum/M
+pace/MZGDRS
+pacemaker/SM
+pacer/M
+pacesetter/SM
+pacey
+pachyderm/MS
+pachysandra/MS
+pacific
+pacifically
+pacification/M
+pacifier/M
+pacifism/M
+pacifist/SM
+pacifistic
+pacify/ZGDRSN
+pack's
+pack/AUGSD
+package's
+package/AGDS
+packager/SM
+packaging/M
+packer/MS
+packet/MS
+packing's
+packinghouse/SM
+packsaddle/MS
+pact/MS
+pacy/RT
+pad/SM
+padded
+padding/M
+paddle/MZGDRS
+paddler/M
+paddock/MDGS
+paddy/SM
+padlock/MDSG
+padre/SM
+paean/SM
+paella/MS
+pagan/SM
+paganism/M
+page/MZGDRS
+pageant/MS
+pageantry/M
+pageboy/SM
+pager/M
+paginate/DSGN
+pagination/M
+pagoda/MS
+pah
+paid/AU
+pail/MS
+pailful/SM
+pain/MDSG
+painful/PY
+painfuller
+painfullest
+painfulness/M
+painkiller/MS
+painkilling
+painless/PY
+painlessness/M
+painstaking/MY
+paint/SZGJMDR
+paintball
+paintbox/MS
+paintbrush/MS
+painted/U
+painter/MY
+painting/M
+paintwork
+pair/AMDSG
+paired/U
+pairing/S
+pairwise
+paisley/SM
+pajama/S
+pajamas/M
+pal/SMY
+palace/MS
+paladin/SM
+palanquin/SM
+palatable/U
+palatal/SM
+palatalization/M
+palatalize/GDS
+palate/MBS
+palatial/Y
+palatinate/MS
+palatine/MS
+palaver/GSMD
+palazzi
+palazzo
+pale/MYTGPDRSJ
+paleface/MS
+paleness/M
+paleo
+paleographer/MS
+paleography/M
+paleolithic
+paleontologist/SM
+paleontology/M
+palette/SM
+palfrey/SM
+palimony/M
+palimpsest/MS
+palindrome/MS
+palindromic
+paling/M
+palisade/SM
+palish
+pall/MDSG
+palladium/M
+pallbearer/MS
+pallet/MS
+palliate/DSGNV
+palliation/M
+palliative/SM
+pallid/YP
+pallidness/M
+pallor/M
+palm/MDSG
+palmate
+palmetto/SM
+palmist/SM
+palmistry/M
+palmtop/SM
+palmy/TR
+palomino/MS
+palpable
+palpably
+palpate/DSGN
+palpation/M
+palpitate/XGNDS
+palpitation/M
+palsy/GDSM
+paltriness/M
+paltry/RPT
+pampas/M
+pamper/DSG
+pamphlet/MS
+pamphleteer/MS
+pan/SM
+panacea/SM
+panache/M
+panama/MS
+panatella/S
+pancake/DSMG
+panchromatic
+pancreas/MS
+pancreatic
+pancreatitis
+panda/SM
+pandemic/SM
+pandemonium/M
+pander/MDRZGS
+panderer/M
+pane/KM
+panegyric/SM
+panel/SGJMD
+paneling/M
+panelist/MS
+panes
+pang/MS
+panhandle/DRSMZG
+panhandler/M
+panic/SM
+panicked
+panicking
+panicky
+panned
+pannier/SM
+panning
+panoply/SM
+panorama/SM
+panoramic
+panpipes/M
+pansy/SM
+pant/MDSG
+pantaloons/M
+pantechnicon/S
+pantheism/M
+pantheist/SM
+pantheistic
+pantheon/SM
+panther/MS
+pantie/M
+panto/S
+pantomime/MGDS
+pantomimic
+pantomimist/SM
+pantry/SM
+pantsuit/SM
+panty/SM
+pantyhose/M
+pantyliner/M
+pantywaist/SM
+pap/SM
+papa/MS
+papacy/SM
+papal
+paparazzi/M
+paparazzo
+papaw/SM
+papaya/MS
+paper/SZGMDR
+paperback/SM
+paperbark/S
+paperboard/M
+paperboy/SM
+paperclip/S
+paperer/M
+papergirl/SM
+paperhanger/SM
+paperhanging/M
+paperless
+paperweight/MS
+paperwork/M
+papery
+papilla/M
+papillae
+papillary
+papist/MS
+papoose/MS
+pappy/SM
+paprika/M
+papyri
+papyrus/M
+par/SZGMDRBJ
+para/MS
+parable/MS
+parabola/SM
+parabolic
+paracetamol/S
+parachute/DSMG
+parachutist/MS
+parade/MZGDRS
+parader/M
+paradigm/SM
+paradigmatic
+paradisaical
+paradise/SM
+paradox/MS
+paradoxical/Y
+paraffin/M
+paragliding
+paragon/MS
+paragraph/GMD
+paragraphs
+parakeet/SM
+paralegal/MS
+parallax/MS
+parallel/SGMD
+paralleled/U
+parallelism/MS
+parallelization
+parallelized
+parallelogram/SM
+paralyses
+paralysis/M
+paralytic/SM
+paralyze/DSG
+paralyzing/Y
+paramagnetic
+paramecia
+paramecium/M
+paramedic/MS
+paramedical/MS
+parameter/MS
+parameterize/D
+parametric
+paramilitary/SM
+paramount
+paramountcy
+paramour/SM
+paranoia/M
+paranoiac/MS
+paranoid/SM
+paranormal
+parapet/MS
+paraphernalia/M
+paraphrase/DSMG
+paraplegia/M
+paraplegic/SM
+paraprofessional/MS
+parapsychologist/MS
+parapsychology/M
+paraquat/M
+parasailing
+parascending
+parasite/SM
+parasitic
+parasitical/Y
+parasitism/M
+parasol/MS
+parasympathetic/S
+parathion/M
+parathyroid/MS
+paratroop/RZS
+paratrooper/M
+paratroops/M
+paratyphoid/M
+parboil/DSG
+parcel/GMDS
+parch/LGDS
+parchment/SM
+pardner/S
+pardon/ZGMDRBS
+pardonable/U
+pardonably/U
+pardoner/M
+pare/S
+paregoric/M
+parent/GMDS
+parentage/M
+parental
+parentheses
+parenthesis/M
+parenthesize/DSG
+parenthetic
+parenthetical/Y
+parenthood/M
+parenting/M
+parer/M
+pares/S
+paresis/M
+parfait/MS
+pariah/M
+pariahs
+paribus
+parietal
+parimutuel/MS
+paring/M
+parish/MS
+parishioner/MS
+parity/ESM
+park/MDSG
+parka/SM
+parking/M
+parkland
+parkour
+parkway/MS
+parky
+parlance/M
+parlay/GMDS
+parley/GMDS
+parliament/SM
+parliamentarian/SM
+parliamentary
+parlor/MS
+parlous
+parmigiana
+parmigiano
+parochial/Y
+parochialism/M
+parodist/SM
+parody/GDSM
+parole/MGDS
+parolee/MS
+parotid
+paroxysm/SM
+paroxysmal
+parquet/MDSG
+parquetry/M
+parred
+parricidal
+parricide/MS
+parring
+parrot/GMDS
+parry/GDSM
+parse/DRSG
+parsec/MS
+parsimonious/Y
+parsimony/M
+parsley/M
+parsnip/MS
+parson/MS
+parsonage/MS
+part's
+part/CDSG
+partake/ZGRS
+partaken
+partaker/M
+parterre/SM
+parthenogenesis/M
+partial/MYS
+partiality/M
+participant/SM
+participate/DSGN
+participation/M
+participator/MS
+participatory
+participial/M
+participle/MS
+particle/SM
+particleboard/M
+particular/SMY
+particularity/SM
+particularization/M
+particularize/DSG
+particulate/SM
+parting/MS
+partisan/SM
+partisanship/M
+partition/GMDS
+partitive/MS
+partizan/SM
+partly
+partner/MDSG
+partnership/MS
+partook
+partridge/SM
+parturition/M
+partway
+party/GDSM
+parvenu/MS
+pascal/MS
+paschal
+pasha/SM
+pass/M
+passably
+passage/MS
+passageway/MS
+passbook/MS
+passe/DRSBXZGNV
+passel/MS
+passenger/SM
+passer/M
+passerby/M
+passersby
+passim
+passing/MY
+passion/EM
+passionate/EY
+passionflower/SM
+passionless
+passive/PMYS
+passiveness/M
+passivity/M
+passivization
+passivize/DSG
+passkey/MS
+passphrase/S
+passport/MS
+password/MS
+pass辿
+past/AMS
+pasta/SM
+paste/DSMG
+pasteboard/M
+pastel/MS
+pastern/MS
+pasteurization/M
+pasteurize/ZGDRS
+pasteurized/U
+pasteurizer/M
+pastiche/MS
+pastie
+pastille/MS
+pastime/MS
+pastiness/M
+pastor/MS
+pastoral/MS
+pastorate/MS
+pastrami/M
+pastry/SM
+pasturage/M
+pasture/DSMG
+pastureland/M
+pasty/PTRSM
+pat/SM
+patch/EGMDS
+patchily
+patchiness/M
+patchouli
+patchwork/SM
+patchy/TPR
+pate/MS
+patella/MS
+patellae
+patent/GMDYS
+paterfamilias/MS
+paternal/Y
+paternalism/M
+paternalist/S
+paternalistic
+paternity/M
+paternoster/MS
+path/M
+pathetic
+pathetically
+pathfinder/SM
+pathless
+pathogen/SM
+pathogenic
+pathological/Y
+pathologist/SM
+pathology/M
+pathos/M
+paths
+pathway/MS
+patience/M
+patient/IMST
+patienter
+patiently
+patina/MS
+patine
+patio/SM
+patisserie/S
+patois/M
+patresfamilias
+patriarch/M
+patriarchal
+patriarchate/MS
+patriarchs
+patriarchy/SM
+patrician/SM
+patricidal
+patricide/SM
+patrimonial
+patrimony/SM
+patriot/SM
+patriotic/U
+patriotically
+patriotism/M
+patrol/MS
+patrolled
+patrolling
+patrolman/M
+patrolmen
+patrolwoman/M
+patrolwomen
+patron/MS
+patronage/MS
+patroness/MS
+patronize/ZGDRS
+patronizer/M
+patronizing/Y
+patronymic/SM
+patronymically
+patroon/SM
+patsy/SM
+patted
+patter/MDGS
+pattern/SMDG
+patting
+patty/SM
+paucity/M
+paunch/MS
+paunchy/RT
+pauper/MS
+pauperism/M
+pauperize/DSG
+pause/DSMG
+pave/AGDS
+paved/U
+pavement/MS
+pavilion/SM
+paving/MS
+pavlova/S
+paw/SGMD
+pawl/MS
+pawn/MDSG
+pawnbroker/MS
+pawnbroking/M
+pawnshop/MS
+pawpaw/MS
+pay's
+pay/ASGBL
+payback/SM
+paycheck/MS
+payday/MS
+payed
+payee/SM
+payer/SM
+payload/SM
+paymaster/SM
+payment/ASM
+payoff/MS
+payola/M
+payout/MS
+payphone/S
+payroll/SM
+payslip/SM
+paywall/SM
+payware
+pct
+pd
+pea/SM
+peace/SM
+peaceable
+peaceably
+peaceful/PY
+peacefulness/M
+peacekeeper/SM
+peacekeeping/M
+peacemaker/MS
+peacemaking/M
+peacetime/M
+peach/MS
+peachy/TR
+peacock/MS
+peafowl/MS
+peahen/MS
+peak/MDSG
+peaky
+peal/AMDSG
+peanut/MS
+pear/MYS
+pearl/SGMD
+pearly/RT
+peasant/SM
+peasantry/M
+peashooter/SM
+peat/M
+peaty/TR
+pebble/MGDS
+pebbly
+pecan/SM
+peccadillo/M
+peccadilloes
+peccary/SM
+peck/MDRSZG
+peckish
+pecs
+pectic
+pectin/M
+pectoral/MS
+pectoralis
+peculate/GNDS
+peculation/M
+peculator/SM
+peculiar/Y
+peculiarity/SM
+pecuniary
+pedagogic
+pedagogical/Y
+pedagogue/SM
+pedagogy/M
+pedal/SGMD
+pedalo/S
+pedant/MS
+pedantic
+pedantically
+pedantry/M
+peddle/ZGDRS
+peddler/M
+pederast/MS
+pederasty/M
+pedestal/MS
+pedestrian/SM
+pedestrianization
+pedestrianize/GDS
+pediatric/S
+pediatrician/MS
+pediatrics/M
+pedicab/SM
+pedicure/MGDS
+pedicurist/MS
+pedigree/MDS
+pediment/MS
+pedometer/MS
+pedophile/S
+pedophilia
+peduncle/MS
+pee/DRSMZ
+peeing
+peek/MDSG
+peekaboo/M
+peel/MDRSJZG
+peeled/U
+peeler/M
+peeling/M
+peen/MS
+peep/MDRSZG
+peepbo
+peeper/M
+peephole/MS
+peepshow/MS
+peer/MDG
+peerage/SM
+peeress/MS
+peerless
+peeve/DSMG
+peevish/PY
+peevishness/M
+peewee/MS
+peewit/S
+peg/SM
+pegboard/MS
+pegged
+pegging
+peignoir/SM
+pejoration/M
+pejorative/SMY
+peke/MS
+pekinese/SM
+pekingese/SM
+pekoe/M
+pelagic
+pelf/M
+pelican/MS
+pellagra/M
+pellet/GMDS
+pellucid
+pelmet/S
+pelt/MDSG
+pelvic
+pelvis/MS
+pemmican/M
+pen/M
+penal
+penalization/M
+penalize/DSG
+penalty/SM
+penance/MS
+pence
+penchant/SM
+pencil/GMDJS
+pend/CDSG
+pendant/MS
+pendent/MS
+pendulous
+pendulum/MS
+penetrability/M
+penetrable
+penetrate/DSGNVX
+penetrating/Y
+penetration/M
+penfriend/S
+penguin/MS
+penicillin/M
+penile
+peninsula/SM
+peninsular
+penis/MS
+penitence/M
+penitent/SMY
+penitential
+penitentiary/SM
+penknife/M
+penknives
+penlight/SM
+penman/M
+penmanship/M
+penmen
+pennant/MS
+penned
+penniless
+penning
+pennon/MS
+penny/SM
+pennyweight/MS
+pennyworth
+penologist/MS
+penology/M
+pension/BZGMDRS
+pensioner/M
+pensive/PY
+pensiveness/M
+pent
+pentacle/MS
+pentagon/MS
+pentagonal
+pentagram/SM
+pentameter/SM
+pentathlete/MS
+pentathlon/MS
+penthouse/SM
+penuche/M
+penultimate/SM
+penumbra/MS
+penumbrae
+penurious/PY
+penuriousness/M
+penury/M
+peon/MS
+peonage/M
+peony/SM
+people/MGDS
+pep/SM
+pepped
+pepper/GMDS
+peppercorn/SM
+peppermint/SM
+pepperoni/MS
+peppery
+peppiness/M
+pepping
+peppy/TPR
+pepsin/M
+peptic/MS
+peptide/S
+peradventure/M
+perambulate/XGNDS
+perambulation/M
+perambulator/MS
+percale/MS
+perceive/BGDS
+perceived/U
+percent/MS
+percentage/SM
+percentile/SM
+perceptible
+perceptibly
+perception/SM
+perceptional
+perceptive/PY
+perceptiveness/M
+perceptual/Y
+perch/GMDS
+perchance
+percipience/M
+percipient
+percolate/GNDS
+percolation/M
+percolator/SM
+percussion/AM
+percussionist/MS
+percussive
+perdition/M
+perdurable
+peregrinate/DSXGN
+peregrination/M
+peregrine/MS
+peremptorily
+peremptory
+perennial/SMY
+perestroika/M
+perfect/PTGMDRYS
+perfecta/MS
+perfectibility/M
+perfectible
+perfection/SM
+perfectionism/M
+perfectionist/SM
+perfectness/M
+perfidious/Y
+perfidy/SM
+perforate/GNXDS
+perforation/M
+perforce
+perform/SDRZG
+performance/SM
+performative
+performed/U
+performer/M
+perfume/DRSMZG
+perfumer/M
+perfumery/SM
+perfunctorily
+perfunctory
+perfusion
+pergola/SM
+perhaps
+pericardia
+pericardial
+pericarditis
+pericardium/M
+perigee/SM
+perihelia
+perihelion/M
+peril/SGMD
+perilous/Y
+perimeter/SM
+perinatal
+perinea
+perineum/M
+period/MS
+periodic
+periodical/SMY
+periodicity/M
+periodontal
+periodontics/M
+periodontist/SM
+peripatetic/MS
+peripheral/MYS
+periphery/SM
+periphrases
+periphrasis/M
+periphrastic
+periscope/SM
+perish/BDRSZG
+perishable/MS
+peristalses
+peristalsis/M
+peristaltic
+peristyle/SM
+peritoneal
+peritoneum/MS
+peritonitis/M
+periwig/SM
+periwinkle/SM
+perjure/DRSZG
+perjurer/M
+perjury/SM
+perk/MDSG
+perkily
+perkiness/M
+perky/TPR
+perm/MDSG
+permafrost/M
+permanence/M
+permanency/M
+permanent/SMY
+permeability/M
+permeable
+permeate/GNDS
+permeation/M
+permissible
+permissibly
+permission/MS
+permissive/PY
+permissiveness/M
+permit/MS
+permitted
+permitting
+permittivity
+permutation/SM
+permute/DSG
+pernicious/YP
+perniciousness/M
+peroration/MS
+peroxide/MGDS
+perpendicular/SMY
+perpendicularity/M
+perpetrate/DSGN
+perpetration/M
+perpetrator/MS
+perpetual/SMY
+perpetuate/DSGN
+perpetuation/M
+perpetuity/M
+perplex/GDS
+perplexed/Y
+perplexing/Y
+perplexity/SM
+perquisite/SM
+persecute/GNXDS
+persecution/M
+persecutor/SM
+perseverance/M
+persevere/DSG
+persiflage/M
+persimmon/SM
+persist/SGD
+persistence/M
+persistent/Y
+persnickety
+person/UMS
+persona/SM
+personable
+personae
+personage/MS
+personal/MYS
+personality/SM
+personalize/CDSG
+personalty/M
+personification/M
+personify/GDSNX
+personnel/M
+perspective/MS
+perspex
+perspicacious/Y
+perspicacity/M
+perspicuity/M
+perspicuous
+perspiration/M
+perspire/GDS
+persuade/BZGDRS
+persuaded/U
+persuader/M
+persuasion/SM
+persuasive/PY
+persuasiveness/M
+pert/RYPT
+pertain/GSD
+pertinacious/Y
+pertinacity/M
+pertinence/M
+pertinent/Y
+pertness/M
+perturb/DGS
+perturbation/SM
+perturbed/U
+pertussis/M
+peruke/MS
+perusal/MS
+peruse/GDS
+perv/S
+pervade/DSG
+pervasive/PY
+pervasiveness/M
+perverse/PXYN
+perverseness/M
+perversion/M
+perversity/M
+pervert/SGMD
+peseta/MS
+peskily
+peskiness/M
+pesky/TPR
+peso/MS
+pessary/S
+pessimal
+pessimism/M
+pessimist/SM
+pessimistic
+pessimistically
+pest/MRSZ
+pester/GD
+pesticide/MS
+pestiferous
+pestilence/SM
+pestilent
+pestilential
+pestle/MGDS
+pesto/M
+pet/SZMR
+petabyte/MS
+petajoule/S
+petal/SMD
+petard/MS
+petawatt/S
+petcock/SM
+peter/GMD
+petiole/SM
+petite/MS
+petition/ZGMDRS
+petitionary
+petitioner/M
+petrel/MS
+petrifaction/M
+petrify/DSG
+petrochemical/SM
+petrodollar/MS
+petrol/M
+petrolatum/M
+petroleum/M
+petrologist/SM
+petrology/M
+petted
+petticoat/MS
+pettifog/S
+pettifogged
+pettifogger/SM
+pettifoggery/M
+pettifogging
+pettily
+pettiness/M
+petting/M
+pettish/Y
+petty/PTR
+petulance/M
+petulant/Y
+petunia/MS
+pew/SM
+pewee/SM
+pewit/SM
+pewter/MS
+peyote/M
+pf
+pfennig/MS
+pg
+phaeton/MS
+phage/S
+phagocyte/SM
+phalanger/SM
+phalanges
+phalanx/MS
+phalli
+phallic
+phallocentric
+phallocentrism
+phallus/M
+phantasm/MS
+phantasmagoria/MS
+phantasmagorical
+phantasmal
+phantom/SM
+pharaoh/M
+pharaohs
+pharisaic
+pharisee/SM
+pharmaceutic/MS
+pharmaceutical/SM
+pharmaceutics/M
+pharmacist/MS
+pharmacologic
+pharmacological
+pharmacologist/SM
+pharmacology/M
+pharmacopeia/SM
+pharmacopoeia/MS
+pharmacotherapy
+pharmacy/SM
+pharyngeal
+pharynges
+pharyngitis/M
+pharynx/M
+phase/DSMG
+phaseout/SM
+phat
+pheasant/MS
+phenacetin/M
+phenobarbital/M
+phenol/M
+phenom/MS
+phenomena
+phenomenal/Y
+phenomenological
+phenomenology
+phenomenon/MS
+phenotype
+phenytoin
+pheromone/MS
+phew
+phi/SM
+phial/SM
+philander/ZGDRS
+philanderer/M
+philandering/M
+philanthropic
+philanthropically
+philanthropist/MS
+philanthropy/SM
+philatelic
+philatelist/MS
+philately/M
+philharmonic/SM
+philippic/MS
+philistine/MS
+philistinism/M
+philodendron/SM
+philological
+philologist/MS
+philology/M
+philosopher/MS
+philosophic
+philosophical/Y
+philosophize/DRSZG
+philosophizer/M
+philosophy/SM
+philter/MS
+phish/ZGDR
+phisher/M
+phlebitis/M
+phlegm/M
+phlegmatic
+phlegmatically
+phloem/M
+phlox/M
+phobia/MS
+phobic/MS
+phoebe/MS
+phoenix/MS
+phone/DSMG
+phonecard/S
+phoneme/MS
+phonemic
+phonemically
+phonetic/S
+phonetically
+phonetician/SM
+phonetics/M
+phoneyed
+phoneying
+phonic/S
+phonically
+phonics/M
+phoniness/M
+phonograph/M
+phonographic
+phonographs
+phonological/Y
+phonologist/MS
+phonology/M
+phonon
+phony/PTGDRSM
+phooey
+phosphate/MS
+phosphodiesterase
+phosphor/MS
+phosphorescence/M
+phosphorescent/Y
+phosphoric
+phosphorous
+phosphorus/M
+phosphorylation
+photo/SGMD
+photocell/MS
+photocopier/M
+photocopy/DRSMZG
+photoelectric
+photoelectrically
+photoengrave/DRSJZG
+photoengraver/M
+photoengraving/M
+photofinishing/M
+photogenic
+photogenically
+photograph/MDRZG
+photographer/M
+photographic
+photographically
+photographs/A
+photography/M
+photojournalism/M
+photojournalist/SM
+photometer/MS
+photon/MS
+photosensitive
+photostat/SM
+photostatic
+photostatted
+photostatting
+photosynthesis/M
+photosynthesize/GDS
+photosynthetic
+phototropic
+phototropism
+phototypesetter
+phototypesetting
+photovoltaic
+phrasal
+phrase's
+phrase/AGDS
+phrasebook/S
+phraseology/M
+phrasing/MS
+phreaking
+phrenologist/SM
+phrenology/M
+phyla
+phylactery/SM
+phylogeny/M
+phylum/M
+phys
+physic/SM
+physical/MYS
+physicality
+physician/SM
+physicist/SM
+physicked
+physicking
+physics/M
+physio/S
+physiognomy/SM
+physiography/M
+physiologic
+physiological/Y
+physiologist/MS
+physiology/M
+physiotherapist/MS
+physiotherapy/M
+physique/MS
+phytoplankton
+pi/SMDRHZG
+pianissimo/SM
+pianist/MS
+piano/SM
+pianoforte/SM
+pianola/S
+piaster/MS
+piazza/MS
+pibroch/M
+pibrochs
+pic/SM
+pica/M
+picador/MS
+picante
+picaresque
+picayune
+piccalilli/M
+piccolo/MS
+pick/MDRSJZG
+pickax/GMDS
+picker/M
+pickerel/MS
+picket/ZGMDRS
+pickings/M
+pickle/MGDS
+pickpocket/SM
+pickup/MS
+picky/PTR
+picnic/MS
+picnicked
+picnicker/SM
+picnicking
+picot/SM
+pictogram/S
+pictograph/M
+pictographs
+pictorial/MYS
+picture/MGDS
+picturesque/PY
+picturesqueness/M
+piddle/MGDS
+piddly
+pidgin/MS
+pie/SM
+piebald/MS
+piece/DSMG
+piecemeal
+piecework/MRZ
+pieceworker/M
+piecrust/SM
+pieing
+pier/M
+pierce/JGDS
+piercing/MY
+piety/M
+piezoelectric
+piffle/MG
+pig/SML
+pigeon/MS
+pigeonhole/DSMG
+pigged
+piggery/S
+pigging
+piggish/PY
+piggishness/M
+piggy/TRSM
+piggyback/MDSG
+pigheaded/PY
+pigheadedness/M
+piglet/MS
+pigment/MDS
+pigmentation/M
+pigpen/MS
+pigskin/MS
+pigsty/SM
+pigswill
+pigtail/MS
+pike/MZGDRS
+piker/M
+pikestaff/SM
+pikestaves
+pilaf/SM
+pilaster/MS
+pilchard/MS
+pile/MGDSJ
+pileup/MS
+pilfer/ZGDRS
+pilferage/M
+pilferer/M
+pilgrim/MS
+pilgrimage/MS
+piling/M
+pill/MDSG
+pillage/MZGDRS
+pillager/M
+pillar/MDS
+pillbox/MS
+pillion/MS
+pillock/S
+pillory/GDSM
+pillow/GMDS
+pillowcase/MS
+pillowslip/MS
+pilot/DGSM
+pilothouse/SM
+pimento/MS
+pimiento/MS
+pimp/GMDYS
+pimpernel/MS
+pimple/DSM
+pimply/RT
+pin/SM
+pinafore/MS
+pinata/MS
+pinball/M
+pincer/MS
+pinch/GMDS
+pincushion/MS
+pine's
+pine/AGDS
+pineapple/MS
+pinewood/S
+piney
+pinfeather/SM
+ping/GMD
+pinhead/SM
+pinhole/SM
+pinion/SMDG
+pink/TGPMDRS
+pinkeye/M
+pinkie/M
+pinkish
+pinkness/M
+pinko/MS
+pinky/SM
+pinnacle/SM
+pinnate
+pinned/U
+pinning/U
+pinny/S
+pinochle/M
+pinon/MS
+pinpoint/SGMD
+pinprick/MS
+pinsetter/SM
+pinstripe/DSM
+pint/MS
+pinto/MS
+pinup/MS
+pinwheel/GSMD
+piny/TR
+pinyin/M
+pinyon/SM
+pioneer/SGMD
+pious/YP
+piousness/M
+pip/SZGMDR
+pipe/MS
+pipeline/SM
+piper/M
+pipette/SM
+pipework
+piping/M
+pipit/MS
+pipped
+pippin/SM
+pipping
+pipsqueak/SM
+piquancy/M
+piquant/Y
+pique/MGDS
+piracy/M
+piranha/SM
+pirate/DSMG
+piratical/Y
+pirogi/M
+piroshki/M
+pirouette/DSMG
+pirozhki/M
+piscatorial
+pismire/SM
+piss/ZGMDRS
+pissoir/S
+pistachio/SM
+piste/S
+pistil/SM
+pistillate
+pistol/SM
+piston/SM
+pit/SM
+pita/MS
+pitapat/SM
+pitch/MDRSZG
+pitchblende/M
+pitcher/M
+pitchfork/MDSG
+pitchman/M
+pitchmen
+piteous/YP
+piteousness/M
+pitfall/SM
+pith/M
+pithead/S
+pithily
+pithiness/M
+pithy/RTP
+pitiable
+pitiably
+pitiful/Y
+pitiless/PY
+pitilessness/M
+piton/MS
+pitta/S
+pittance/MS
+pitted
+pitting
+pituitary/SM
+pity/GDSM
+pitying/Y
+pivot/MDGS
+pivotal
+pix/M
+pixel/MS
+pixie/MS
+pizazz/M
+pizza/MS
+pizzazz/M
+pizzeria/SM
+pizzicati
+pizzicato/M
+pi単ata/MS
+pi単on/SM
+pj's
+pk
+pkg
+pkt
+pkwy
+pl
+placard/SMDG
+placate/DSGN
+placation/M
+placatory
+place's
+place/AESDLG
+placebo/SM
+placed/U
+placeholder/MS
+placekick/MDRZGS
+placekicker/M
+placement/EASM
+placenta/SM
+placental/S
+placer/SM
+placid/Y
+placidity/M
+placings
+placket/SM
+plagiarism/SM
+plagiarist/SM
+plagiarize/DRSZG
+plagiarizer/M
+plagiary/M
+plague/DSMG
+plaice
+plaid/MS
+plain/MRYTSP
+plainchant
+plainclothes
+plainclothesman/M
+plainclothesmen
+plainness/M
+plainsman/M
+plainsmen
+plainsong/M
+plainspoken
+plaint/SMV
+plaintiff/SM
+plaintive/Y
+plait/MDGS
+plan/ZMRS
+planar
+plane's
+plane/CGDS
+planeload/MS
+planer/M
+planet/SM
+planetarium/SM
+planetary
+plangency/M
+plangent
+plank/MDGS
+planking/M
+plankton/M
+planned/U
+planner/SM
+planning/S
+plant/MDRZGSJ
+plantain/SM
+plantar
+plantation/MS
+planter/M
+planting/M
+plantlike
+plaque/SM
+plash/MDSG
+plasma/M
+plasmon
+plaster/SZGMDR
+plasterboard/M
+plasterer/M
+plastic/SM
+plasticity/M
+plasticize/DSG
+plastique
+plat/XGMDNS
+plate/MS
+plateau/SMDG
+plateful/SM
+platelet/SM
+platen/M
+platform/SGMD
+plating/M
+platinum/M
+platitude/SM
+platitudinous
+platonic
+platoon/SGMD
+platted
+platter/SM
+platting
+platy/M
+platypus/MS
+platys
+plaudit/SM
+plausibility/M
+plausible
+plausibly
+play/AEGMDS
+playable/EU
+playact/SGD
+playacting/M
+playback/MS
+playbill/MS
+playbook/MS
+playboy/SM
+player/SM
+playfellow/SM
+playful/PY
+playfulness/M
+playgirl/MS
+playgoer/MS
+playground/SM
+playgroup/S
+playhouse/MS
+playlist/MS
+playmate/MS
+playoff/SM
+playpen/SM
+playroom/SM
+playschool/S
+plaything/SM
+playtime/M
+playwright/SM
+plaza/MS
+plea/MS
+plead/DRZGSJ
+pleader/M
+pleading/MY
+pleasant/UTYP
+pleasanter
+pleasantness/UM
+pleasantry/SM
+please/EDSG
+pleasing/YS
+pleasurably
+pleasure/MGDSB
+pleasureful
+pleat/MDGS
+pleb/S
+plebby
+plebe/MS
+plebeian/MS
+plebiscite/MS
+plectra
+plectrum/MS
+pledge/DSMG
+plenary/SM
+plenipotentiary/SM
+plenitude/SM
+plenteous
+plentiful/Y
+plenty/M
+plenum/S
+pleonasm/MS
+plethora/M
+pleura/M
+pleurae
+pleurisy/M
+plexiglass/M
+plexus/MS
+pliability/M
+pliable
+pliancy/M
+pliant/Y
+pliers/M
+plight/SMDG
+plimsoll/S
+plinth/M
+plinths
+plod/S
+plodded
+plodder/MS
+plodding/S
+plonk/DRSZG
+plop/MS
+plopped
+plopping
+plosive/S
+plot/MS
+plotted
+plotter/SM
+plotting
+plover/SM
+plow/GMDS
+plowman/M
+plowmen
+plowshare/MS
+ploy's
+ploy/S
+pluck/MDSG
+pluckily
+pluckiness/M
+plucky/RPT
+plug's
+plug/US
+plugged/U
+plugging/U
+plughole/S
+plugin/SM
+plum/GMDS
+plumage/M
+plumb/MDRSZGJ
+plumbed/U
+plumber/M
+plumbing/M
+plume/MS
+plummet/SGMD
+plummy
+plump/MDRYSTGP
+plumpness/M
+plumy/RT
+plunder/SZGMDR
+plunderer/M
+plunge/DRSMZG
+plunger/M
+plunk/MDSG
+pluperfect/SM
+plural/SM
+pluralism/M
+pluralist/MS
+pluralistic
+plurality/SM
+pluralization/M
+pluralize/GDS
+plus/MS
+plush/MRYTP
+plushness/M
+plushy/RT
+plutocracy/SM
+plutocrat/SM
+plutocratic
+plutonium/M
+pluvial
+ply/AGDSM
+plywood/M
+pm
+pneumatic
+pneumatically
+pneumococcal
+pneumococci
+pneumococcus
+pneumonia/M
+poach/DRSZG
+poacher/M
+poaching/M
+pock/GMDS
+pocket/SMDG
+pocketbook/SM
+pocketful/SM
+pocketknife/M
+pocketknives
+pockmark/MDGS
+pod/SM
+podcast/SMG
+podded
+podding
+podiatrist/SM
+podiatry/M
+podium/SM
+poem/MS
+poesy/M
+poet/MS
+poetaster/MS
+poetess/MS
+poetic/S
+poetical/Y
+poetry/M
+pogrom/SM
+poi/M
+poignancy/M
+poignant/Y
+poinciana/SM
+poinsettia/SM
+point/MDRSZG
+pointblank
+pointed/Y
+pointer/M
+pointillism/M
+pointillist/SM
+pointless/PY
+pointlessness/M
+pointy/TR
+poise/MGDS
+poison/SJZGMDR
+poisoner/M
+poisoning/M
+poisonous/Y
+poke/MZGDRS
+poker/M
+pokey/MS
+poky/TR
+pol/SGMD
+polar
+polarity/SM
+polarization/CM
+polarize/CDSG
+pole/MS
+poleaxe/GDS
+polecat/MS
+polemic/MS
+polemical/Y
+polemicist/SM
+polemics/M
+polestar/SM
+police/DSMG
+policeman/M
+policemen
+policewoman/M
+policewomen
+policy/SM
+policyholder/MS
+policymaker/S
+polio/MS
+poliomyelitis/M
+polish/ZGMDRS
+polished/U
+polisher/M
+politburo/MS
+polite/RYTP
+politeness/M
+politesse/M
+politic/S
+political/Y
+politician/SM
+politicization/M
+politicize/CDSG
+politicking/M
+politico/SM
+politics/M
+polity/SM
+polka/MDSG
+poll/GMDNS
+pollack/MS
+pollard/S
+pollen/M
+pollinate/GNDS
+pollination/M
+pollinator/SM
+polling/M
+polliwog/SM
+pollock/M
+pollster/SM
+pollutant/MS
+pollute/ZGNDRS
+polluted/U
+polluter/M
+pollution/M
+pollywog/MS
+polo/M
+polonaise/SM
+polonium/M
+poltergeist/MS
+poltroon/SM
+poly
+polyacrylamide
+polyamory/S
+polyandrous
+polyandry/M
+polyclinic/SM
+polyester/MS
+polyethylene/M
+polygamist/MS
+polygamous
+polygamy/M
+polyglot/SM
+polygon/SM
+polygonal
+polygraph/GMD
+polygraphs
+polyhedral
+polyhedron/SM
+polymath/M
+polymaths
+polymer/SM
+polymeric
+polymerization/M
+polymerize/GDS
+polymorphic
+polymorphous
+polynomial/MS
+polyp/MS
+polyphonic
+polyphony/M
+polypropylene/M
+polys
+polysemous
+polystyrene/M
+polysyllabic
+polysyllable/MS
+polytechnic/MS
+polytheism/M
+polytheist/SM
+polytheistic
+polythene
+polyunsaturate/DS
+polyurethane/MS
+polyvinyl
+pom/S
+pomade/DSMG
+pomander/SM
+pomegranate/MS
+pommel/SGMD
+pommy/S
+pomp/M
+pompadour/SMD
+pompano/MS
+pompom/SM
+pomposity/M
+pompous/YP
+pompousness/M
+ponce/GDS
+poncho/SM
+poncy
+pond/MS
+ponder/SZGDR
+ponderer/M
+ponderous/YP
+ponderousness/M
+pone/MS
+pong/GDS
+pongee/M
+poniard/MS
+pontiff/SM
+pontifical/Y
+pontificate/DSMG
+pontoon/SM
+pony/GDSM
+ponytail/MS
+poo/SGD
+pooch/MDSG
+poodle/SM
+poof/MS
+poofter/S
+pooh/GMD
+poohs
+pool/GMDS
+poolroom/MS
+poolside/S
+poop/GMDS
+poor/TRYP
+poorboy/M
+poorhouse/SM
+poorness/M
+pop/SM
+popcorn/M
+pope/MS
+popgun/SM
+popinjay/MS
+poplar/SM
+poplin/M
+popover/SM
+poppa/MS
+poppadom/S
+popped
+popper/SM
+poppet/S
+popping
+poppy/SM
+poppycock/M
+populace/MS
+popular/Y
+popularity/UM
+popularization/M
+popularize/DSG
+populate/ACGDS
+populated/U
+population/CM
+populations
+populism/M
+populist/MS
+populous/P
+populousness/M
+popup/MS
+porcelain/SM
+porch/MS
+porcine
+porcupine/SM
+pore/MGDS
+porgy/SM
+pork/ZMR
+porker/M
+porky/RSMT
+porn/M
+porno/M
+pornographer/MS
+pornographic
+pornographically
+pornography/M
+porosity/M
+porous/P
+porousness/M
+porphyritic
+porphyry/M
+porpoise/MGDS
+porridge/M
+porringer/SM
+port's/A
+port/CAEGDS
+portability/M
+portable/MS
+portage/DSMG
+portal/SM
+portcullis/MS
+portend/SGD
+portent/SM
+portentous/YP
+porter/ASM
+porterhouse/SM
+portfolio/MS
+porthole/MS
+portico/M
+porticoes
+portiere/MS
+portion/KSGMD
+porti竪re/MS
+portliness/M
+portly/RPT
+portmanteau/MS
+portrait/MS
+portraitist/SM
+portraiture/M
+portray/SGD
+portrayal/MS
+portulaca/M
+pose's/A
+pose/CAKEGDS
+poser/EKSM
+poseur/SM
+posh/TR
+posit/DSGV
+position/CKEMS
+positional/KE
+positioned/K
+positioning/AK
+positive/MYPS
+positiveness/M
+positivism
+positivist/S
+positron/MS
+poss
+posse/MS
+possess/AEVGSD
+possession/ASM
+possessive/SMYP
+possessiveness/M
+possessor/SM
+possibility/SM
+possible/SM
+possibly
+possum/SM
+post/ZGMDRSJ
+postage/M
+postal
+postbag/S
+postbox/S
+postcard/SM
+postcode/S
+postcolonial
+postconsonantal
+postdate/DSG
+postdoc/MS
+postdoctoral
+poster/M
+posterior/SM
+posterity/M
+postgraduate/SM
+posthaste
+posthumous/Y
+posthypnotic
+postie/S
+postilion/SM
+postillion/MS
+postindustrial
+posting/M
+postlude/SM
+postman/M
+postmark/SMDG
+postmaster/MS
+postmen
+postmenopausal
+postmeridian
+postmistress/MS
+postmodern
+postmodernism/M
+postmodernist/MS
+postmortem/SM
+postnasal
+postnatal
+postoperative
+postpaid
+postpartum
+postpone/DSGL
+postponement/SM
+postprandial
+postscript/SM
+postseason/SM
+postsynaptic
+postulate/XDSMGN
+postulation/M
+postural
+posture/MGJDS
+posturing/M
+postwar
+postwoman
+postwomen
+posy/SM
+pot/CSM
+potability/M
+potable/SM
+potash/M
+potassium/M
+potato/M
+potatoes
+potbelly/DSM
+potboiler/SM
+potency/M
+potent/Y
+potentate/MS
+potential/MYS
+potentiality/SM
+potentiate/GDS
+potful/SM
+pothead/SM
+pother/SMDG
+potherb/SM
+potholder/MS
+pothole/DRSMZG
+pothook/SM
+potion/SM
+potluck/MS
+potpie/SM
+potpourri/SM
+potsherd/SM
+potshot/MS
+pottage/M
+potted
+potter/GSMD
+pottery/SM
+potting
+potty/PRSMT
+pouch/MDSG
+pouf/S
+pouffe/S
+poulterer/MS
+poultice/DSMG
+poultry/M
+pounce/DSMG
+pound's
+pound/KDSG
+poundage/M
+pounding/SM
+pour/GDSJ
+pout/ZGMDRS
+pouter/M
+poverty/M
+pow
+powder/GSMD
+powdery
+power/MDSG
+powerboat/MS
+powerful/Y
+powerhouse/SM
+powerless/PY
+powerlessness/M
+powwow/SGMD
+pox/MS
+pp
+ppm
+ppr
+pr
+practicability/M
+practicably
+practical/SMY
+practicality/SM
+practice/DSMGB
+practiced/U
+practicum/SM
+practitioner/SM
+praetor/SM
+praetorian
+pragmatic/MS
+pragmatical/Y
+pragmatism/M
+pragmatist/MS
+prairie/SM
+praise/EDSMG
+praiseworthiness/M
+praiseworthy/P
+praline/SM
+pram/MS
+prance/DRSMZG
+prancer/M
+prancing/Y
+prang/DSG
+prank/MS
+prankster/SM
+praseodymium/M
+prat/S
+prate/MZGDRS
+prater/M
+pratfall/SM
+prattle/DRSMZG
+prattler/M
+prawn/MDSG
+pray/ZGDRS
+prayer/M
+prayerful/Y
+preach/DRSZGL
+preacher/M
+preachment/M
+preachy/RT
+preadolescence/SM
+preadolescent
+preamble/MGDS
+prearrange/LGDS
+prearrangement/M
+preassigned
+precancel/SMDG
+precancerous
+precarious/PY
+precariousness/M
+precast
+precaution/MS
+precautionary
+precede/DSG
+precedence/M
+precedent/SM
+precept/SM
+preceptor/SM
+precinct/MS
+preciosity/M
+precious/YP
+preciousness/M
+precipice/SM
+precipitant/MS
+precipitate/XMYGNDS
+precipitation/M
+precipitous/Y
+precis/M
+precise/DRSYTGNP
+preciseness/M
+precision/M
+preclude/GDS
+preclusion/M
+precocious/YP
+precociousness/M
+precocity/M
+precognition/M
+precognitive
+precolonial
+preconceive/GDS
+preconception/SM
+precondition/MDGS
+precook/GSD
+precursor/SM
+precursory
+predate/DSG
+predator/MS
+predatory
+predawn
+predecease/GDS
+predecessor/SM
+predefined
+predesignate/GDS
+predestination/M
+predestine/DSG
+predetermination/M
+predetermine/ZGDRS
+predeterminer/M
+predicable
+predicament/MS
+predicate/MGNVDS
+predication/M
+predicative/Y
+predict/BGVSD
+predictability/UM
+predictable/U
+predictably/U
+prediction/SM
+predictor/MS
+predigest/GDS
+predilection/SM
+predispose/GDS
+predisposition/MS
+prednisone
+predominance/M
+predominant/Y
+predominate/YGDS
+preemie/SM
+preeminence/M
+preeminent/Y
+preempt/GVSD
+preemption/M
+preemptive/Y
+preen/DSG
+preexist/DGS
+preexistence/M
+pref
+prefab/SM
+prefabbed
+prefabbing
+prefabricate/DSGN
+prefabrication/M
+preface/DSMG
+prefatory
+prefect/SM
+prefecture/MS
+prefer/SBL
+preferably
+preference/MS
+preferential/Y
+preferment/M
+preferred
+preferring
+prefigure/GDS
+prefix/MDSG
+preform/GSD
+prefrontal
+pregame/SM
+pregnancy/SM
+pregnant
+preheat/GSD
+prehensile
+prehistorian/S
+prehistoric
+prehistorical/Y
+prehistory/M
+prehuman
+preinstalled
+prejudge/GDS
+prejudgment/SM
+prejudice/MGDS
+prejudiced/U
+prejudicial
+prekindergarten/SM
+prelacy/M
+prelate/SM
+prelim/SM
+preliminary/SM
+preliterate
+prelude/MS
+premarital
+premature/Y
+premed/SM
+premedical
+premeditate/DSGN
+premeditated/U
+premeditation/M
+premenstrual
+premier/SGMD
+premiere/MS
+premiership/MS
+premise/DSMG
+premium/SM
+premix/GDS
+premolar/SM
+premonition/MS
+premonitory
+prenatal/Y
+prenup/SM
+prenuptial
+preoccupation/SM
+preoccupy/DSG
+preoperative
+preordain/GDS
+preowned
+prep/MS
+prepackage/DSG
+prepacked
+prepaid
+preparation/SM
+preparatory
+prepare/GDS
+prepared/UP
+preparedness/UM
+prepay/GSL
+prepayment/MS
+prepend
+preponderance/SM
+preponderant/Y
+preponderate/GDS
+preposition/SM
+prepositional/Y
+prepossess/GDS
+prepossessing/U
+prepossession/SM
+preposterous/Y
+prepped
+preppie/M
+prepping
+preppy/TRSM
+prepubescence/M
+prepubescent/SM
+prepuce/MS
+prequel/MS
+prerecord/GSD
+preregister/SGD
+preregistration/M
+prerequisite/MS
+prerogative/SM
+pres
+presage/MGDS
+presbyopia/M
+presbyter/SM
+presbytery/SM
+preschool/SZMR
+preschooler/M
+prescience/M
+prescient/Y
+prescribe/DSG
+prescript/SVM
+prescription/SM
+prescriptive/Y
+preseason/SM
+presence/SM
+present/LMDRYZGSB
+presentably
+presentation/ASM
+presenter/M
+presentiment/SM
+presentment/SM
+preservation/M
+preservationist/SM
+preservative/SM
+preserve/BDRSMZG
+preserver/M
+preset/S
+presetting
+preshrank
+preshrink/GS
+preshrunk
+preside/GDS
+presidency/SM
+president/MS
+presidential
+presidia
+presidium/M
+presort/DGS
+press's
+press/ACGSD
+pressed/U
+presser/MS
+pressie/S
+pressing/SMY
+pressman/M
+pressmen
+pressure/DSMG
+pressurization/M
+pressurize/CGDS
+pressurizer/SM
+prestidigitation/M
+prestige/M
+prestigious
+presto/SM
+presumably
+presume/GDSB
+presumption/SM
+presumptive
+presumptuous/YP
+presumptuousness/M
+presuppose/DSG
+presupposition/MS
+pretax
+preteen/MS
+pretend/DRZGS
+pretender/M
+pretense/SXMN
+pretension/M
+pretentious/UY
+pretentiousness/M
+preterit/SM
+preterite/MS
+preterm
+preternatural/Y
+pretest/DGS
+pretext/MS
+pretrial/S
+prettify/GDS
+prettily
+prettiness/M
+pretty/TGDRSMP
+pretzel/MS
+prevail/DGS
+prevalence/M
+prevalent
+prevaricate/DSGNX
+prevarication/M
+prevaricator/SM
+prevent/DBSGV
+preventable/U
+preventative/MS
+prevention/M
+preventive/SM
+preview/MDRSZG
+previous/Y
+prevision/MS
+prewar
+prey/GMDS
+prezzie/S
+priapic
+price's
+price/AGDS
+priceless
+pricey
+pricier
+priciest
+prick/MDRYSZG
+pricker/M
+prickle/MGDS
+prickliness/M
+prickly/PRT
+pride/MGDS
+prideful/Y
+prier/M
+priest/SMY
+priestess/MS
+priesthood/SM
+priestliness/M
+priestly/RTP
+prig/MS
+priggish/P
+priggishness/M
+prim/ZGDRYP
+primacy/M
+primal
+primarily
+primary/SM
+primate/MS
+prime/MS
+primer/M
+primeval
+priming/M
+primitive/SPMY
+primitiveness/M
+primmer
+primmest
+primness/M
+primogenitor/SM
+primogeniture/M
+primordial/Y
+primp/DSG
+primrose/SM
+primula/S
+prince/SMY
+princedom/SM
+princeliness/M
+princely/PRT
+princess/MS
+principal/SMY
+principality/SM
+principle/DSM
+principled/U
+print/AMDSG
+printable/U
+printer/MS
+printing/SM
+printmaking
+printout/SM
+prion/S
+prior/MS
+prioress/MS
+prioritization
+prioritize/DSG
+priority/SM
+priory/SM
+prism/MS
+prismatic
+prison/SZMR
+prisoner/M
+prissily
+prissiness/M
+prissy/PTR
+pristine
+prithee
+privacy/M
+private/XMYTNRS
+privateer/SM
+privation/CSM
+privatization/SM
+privatize/DSG
+privet/SM
+privilege/DSMG
+privileged/U
+privily
+privy/RSMT
+prize/MGDS
+prized/A
+prizefight/ZGSMR
+prizefighter/M
+prizefighting/M
+prizewinner/MS
+prizewinning
+pro/SM
+probabilistic
+probability/SM
+probable/SM
+probably
+probate/MN
+probation/ZMR
+probational
+probationary
+probationer/M
+probe/MGDSBJ
+probity/M
+problem/MS
+problematic/U
+problematical/Y
+probosces
+proboscis/MS
+procaine/M
+procaryote/SM
+procaryotic
+procedural
+procedure/SM
+proceed/GJDS
+proceeding/M
+proceeds/M
+process's
+process/AGDS
+processable
+processed/U
+procession/GD
+processional/MS
+processor/SM
+proclamation/MS
+proclivity/SM
+procrastinate/DSGN
+procrastination/M
+procrastinator/MS
+procreate/V
+proctor/GMDS
+procurement/M
+prod/MS
+prodigal/MYS
+prodigality/M
+prodigious/Y
+prodigy/SM
+produce's
+produce/AZGDRS
+producer/AM
+producible/A
+production/ASM
+productive/UY
+productiveness/M
+productivity/M
+prof/MS
+profanation/MS
+profane/PYGDS
+profaneness/M
+profanity/SM
+professed/Y
+profession/SM
+professional/MYS
+professionalism/M
+professionalization
+professionalize/DSG
+professor/SM
+professorial/Y
+professorship/SM
+proffer/GMDS
+proficiency/M
+proficient/MYS
+profit/BGD
+profitability/M
+profitable/U
+profitably/U
+profiteer/MDGS
+profiteering/M
+profiterole/SM
+profitless
+profligacy/M
+profligate/SMY
+proforma
+profound/RYTP
+profoundness/M
+profundity/SM
+profuse/PY
+profuseness/M
+progenitor/SM
+progeny/M
+progesterone/M
+progestin/S
+prognathous
+prognoses
+prognosis/M
+prognostic/MS
+prognosticate/XGNDS
+prognostication/M
+prognosticator/MS
+program/CAS
+programed
+programing
+programmable/MS
+programmatic
+programmed/AC
+programmer/MS
+programming/SM
+progress/MDSGV
+progression/MS
+progressive/PMYS
+progressiveness/M
+prohibit/DGVS
+prohibition/SM
+prohibitionist/MS
+prohibitive/Y
+prohibitory
+project/GMDS
+projectile/SM
+projection/SM
+projectionist/SM
+projector/MS
+prokaryote/MS
+prokaryotic
+prole/S
+proletarian/MS
+proletariat/M
+proliferate/DSGN
+proliferation/M
+prolific
+prolifically
+prolix/Y
+prolixity/M
+prologue/SM
+prolongation/SM
+prom/M
+promenade/MGDS
+promethium/M
+prominence/M
+prominent/Y
+promiscuity/M
+promiscuous/Y
+promise/DSMG
+promising/Y
+promissory
+promo/M
+promontory/SM
+promote/DRZG
+promoter/M
+promotional
+prompt/JPSMDRYZTG
+prompted/U
+prompter/M
+prompting/M
+promptitude/M
+promptness/M
+promulgate/GNDS
+promulgation/M
+promulgator/MS
+prone/P
+proneness/M
+prong/MDS
+pronghorn/MS
+pronominal/M
+pronounce/DSLG
+pronounceable/U
+pronouncement/SM
+pronto
+pronunciation/MS
+proof/ADGSM
+proofread/SRZG
+proofreader/M
+prop/MS
+propaganda/M
+propagandist/MS
+propagandize/GDS
+propagate/DSGN
+propagation/M
+propagator/SM
+propel/S
+propellant/MS
+propelled
+propeller/SM
+propelling
+propensity/SM
+proper/MRYT
+property/DSM
+prophecy/SM
+prophesier/M
+prophesy/DRSMZG
+prophet/SM
+prophetess/MS
+prophetic
+prophetical/Y
+prophylactic/SM
+prophylaxes
+prophylaxis/M
+propinquity/M
+propitiate/DSGN
+propitiation/M
+propitiatory
+propitious/Y
+proponent/SM
+proportion/ESM
+proportional/YS
+proportionality
+proportionate/EY
+proposal/MS
+propped
+propping
+propranolol
+proprietary/SM
+proprieties/M
+proprietor/SM
+proprietorial/Y
+proprietorship/M
+proprietress/MS
+propriety/SM
+propulsion/M
+propulsive
+prorate/DSG
+prorogation/M
+prorogue/GD
+prosaic
+prosaically
+proscenium/SM
+prosciutto/M
+proscribe/DG
+proscription/MS
+prose/M
+prosecute/DSXGN
+prosecution/M
+prosecutor/MS
+proselyte/DSMG
+proselytism/M
+proselytize/DRSZG
+proselytizer/M
+prosocial
+prosody/SM
+prospect/MDGVS
+prospective/Y
+prospector/SM
+prospectus/MS
+prosper/GSD
+prosperity/M
+prosperous/Y
+prostate/MS
+prostheses
+prosthesis/M
+prosthetic
+prostitute/MGNDS
+prostitution/M
+prostrate/GNXDS
+prostration/M
+prosy/RT
+protactinium/M
+protagonist/SM
+protean
+protect/GVSD
+protected/U
+protection/SM
+protectionism/M
+protectionist/MS
+protective/PY
+protectiveness/M
+protector/MS
+protectorate/MS
+protege/SM
+protegee/S
+protein/SM
+protestant/S
+protestation/MS
+protestor/MS
+protocol/MS
+proton/SM
+protoplasm/M
+protoplasmic
+prototype/MGS
+prototypical
+protozoa
+protozoan/MS
+protozoic
+protract/GD
+protrude/GDS
+protrusile
+protrusion/MS
+protuberance/MS
+protuberant
+prot辿g辿/MS
+prot辿g辿e/S
+proud/RYT
+prov/NB
+provability/M
+provably
+prove/EAGDS
+proved/U
+proven/U
+provenance/SM
+provender/M
+provenience/M
+proverbial/Y
+provide/DRSZG
+provided/U
+providence/M
+provident/Y
+providential/Y
+provider/M
+province/MS
+provincial/SMY
+provincialism/M
+provisional/Y
+proviso/SM
+provocateur/S
+provocative/PY
+provocativeness/M
+provoke/DRSZG
+provoked/U
+provoker/M
+provoking/Y
+provolone/M
+provost/SM
+prow/MS
+prowess/M
+prowl/MDRSZG
+prowler/M
+proximal
+proximate
+proximity/M
+proxy/SM
+prude/MS
+prudence/M
+prudent/Y
+prudential/Y
+prudery/M
+prudish/YP
+prudishness/M
+prune/MZGDRS
+pruner/M
+prurience/M
+prurient/Y
+pry/ZTGDRSM
+pr辿cis/MDG
+psalm/MS
+psalmist/SM
+psaltery/SM
+psephologist/S
+psephology
+pseud/S
+pseudo/S
+pseudonym/SM
+pseudonymous
+pseudoscience/MS
+pseudy
+pshaw/MS
+psi/SM
+psittacosis/M
+psoriasis/M
+psst
+psych/MDSG
+psyche/M
+psychedelia
+psychedelic/SM
+psychedelically
+psychiatric
+psychiatrist/SM
+psychiatry/M
+psychic/MS
+psychical/Y
+psycho/SM
+psychoactive
+psychoanalyses
+psychoanalysis/M
+psychoanalyst/SM
+psychoanalytic
+psychoanalytical/Y
+psychoanalyze/DSG
+psychobabble/M
+psychodrama/MS
+psychogenic
+psychokinesis
+psychokinetic
+psychological/Y
+psychologist/MS
+psychology/SM
+psychometric
+psychoneuroses
+psychoneurosis/M
+psychopath/M
+psychopathic
+psychopathology
+psychopaths
+psychopathy/M
+psychopharmacology
+psychophysiology
+psychos/S
+psychosis/M
+psychosomatic
+psychotherapist/MS
+psychotherapy/SM
+psychotic/SM
+psychotically
+psychotropic/MS
+psychs
+pt/C
+ptarmigan/MS
+pterodactyl/MS
+ptomaine/SM
+pub/SM
+pubertal
+puberty/M
+pubes/M
+pubescence/M
+pubescent
+pubic
+pubis/M
+public/AM
+publican/AMS
+publication/ASM
+publicist/MS
+publicity/M
+publicize/GDS
+publicly
+publish/AGDS
+publishable
+published/U
+publisher/MS
+publishing/M
+puce/M
+puck/ZMRS
+pucker/MDG
+puckish/YP
+puckishness/M
+pud/S
+pudding/SM
+puddle/DSMG
+puddling/M
+pudenda
+pudendum/M
+pudginess/M
+pudgy/PRT
+pueblo/SM
+puerile
+puerility/M
+puerperal
+puff/ZGMDRS
+puffball/SM
+puffer/M
+puffin/SM
+puffiness/M
+puffy/PRT
+pug/SM
+pugilism/M
+pugilist/SM
+pugilistic
+pugnacious/YP
+pugnaciousness/M
+pugnacity/M
+puke/MGDS
+pukka
+pulchritude/M
+pulchritudinous
+pule/GDS
+pull/ZGMDRS
+pullback/MS
+puller/M
+pullet/SM
+pulley/SM
+pullout/MS
+pullover/SM
+pulmonary
+pulp/GMDS
+pulpiness/M
+pulpit/SM
+pulpwood/M
+pulpy/RPT
+pulsar/SM
+pulsate/XGNDS
+pulsation/M
+pulse/AMGDS
+pulverization/M
+pulverize/DSG
+puma/MS
+pumice/SM
+pummel/SGD
+pump/ZGMDRS
+pumper/M
+pumpernickel/M
+pumpkin/MS
+pun/SM
+punch/MDRSZG
+punchbag/S
+puncheon/MS
+puncher/M
+punchline/S
+punchy/TR
+punctilio/M
+punctilious/PY
+punctiliousness/M
+punctual/Y
+punctuality/M
+punctuate/GNDS
+punctuation/M
+puncture/DSMG
+pundit/SM
+punditry/M
+pungency/M
+pungent/Y
+puniness/M
+punish/BLGDS
+punished/U
+punishing/Y
+punishment/MS
+punitive/Y
+punk/TMRS
+punned
+punnet/S
+punning
+punster/SM
+punt/ZGMDRS
+punter/M
+puny/TRP
+pup/SM
+pupa/M
+pupae
+pupal
+pupate/DSG
+pupil/MS
+pupped
+puppet/MS
+puppeteer/SM
+puppetry/M
+pupping
+puppy/SM
+purblind
+purchase/DRSMZGB
+purchaser/M
+purdah/M
+pure/PYTR
+purebred/SM
+puree/MDS
+pureeing
+pureness/M
+purgative/SM
+purgatorial
+purgatory/SM
+purge/MZGDRS
+purger/M
+purification/M
+purifier/M
+purify/NDRSZG
+purine/MS
+purism/M
+purist/MS
+puristic
+puritan/SM
+puritanical/Y
+puritanism/M
+purity/M
+purl/GMDS
+purlieu/SM
+purloin/SGD
+purple/MTRS
+purplish
+purport/SMDG
+purported/Y
+purpose/DSMYG
+purposed/A
+purposeful/YP
+purposefulness/M
+purposeless/PY
+purr/GMDS
+purse/MZGDRS
+purser/M
+pursuance/M
+pursuant
+pursue/ZGDRS
+pursuer/M
+pursuit/SM
+purulence/M
+purulent
+purvey/DSG
+purveyance/M
+purveyor/SM
+purview/M
+pus/M
+push/ZGMDRS
+pushbike/S
+pushcart/SM
+pushchair/S
+pusher/M
+pushily
+pushiness/M
+pushover/MS
+pushpin/S
+pushup/MS
+pushy/TRP
+pusillanimity/M
+pusillanimous/Y
+puss/MS
+pussy/TRSM
+pussycat/MS
+pussyfoot/DSG
+pustular
+pustule/SM
+put/ISM
+putative
+putdown/SM
+putout/MS
+putrefaction/M
+putrefactive
+putrefy/GDS
+putrescence/M
+putrescent
+putrid
+putsch/MS
+putt/ZGMDRS
+putted/I
+puttee/MS
+putter/MDRZG
+putterer/M
+putting/I
+putty/GDSM
+putz/S
+puzzle/MZGDRSL
+puzzlement/M
+puzzler/M
+pvt
+pwn/SGD
+pyelonephritis
+pygmy/SM
+pylon/SM
+pylori
+pyloric
+pylorus/M
+pyorrhea/M
+pyramid/GSMD
+pyramidal
+pyre/MS
+pyrimidine/MS
+pyrite/SM
+pyrites/M
+pyromania/M
+pyromaniac/SM
+pyrotechnic/S
+pyrotechnical
+pyrotechnics/M
+pyruvate
+python/SM
+pyx/MS
+pzazz
+q
+qr
+qt/S
+qty
+qua
+quack/GMDS
+quackery/M
+quad/MS
+quadrangle/SM
+quadrangular
+quadrant/MS
+quadraphonic
+quadratic/MS
+quadrature
+quadrennial
+quadrennium/MS
+quadriceps/MS
+quadrilateral/SM
+quadrille/XMNS
+quadrillion/M
+quadriplegia/M
+quadriplegic/SM
+quadrivium/M
+quadruped/MS
+quadrupedal
+quadruple/MGDS
+quadruplet/MS
+quadruplicate/MGNDS
+quadruplication/M
+quaff/GMDS
+quagmire/SM
+quahog/MS
+quail/GMDS
+quaint/PRYT
+quaintness/M
+quake/MGDS
+quaky
+qualification/EM
+qualified/U
+qualifier/SM
+qualify/EGXNDS
+qualitative/Y
+quality/SM
+qualm/MS
+qualmish
+quandary/SM
+quango/S
+quanta
+quantifiable
+quantification/M
+quantifier/M
+quantify/NDRSZG
+quantitation
+quantitative/Y
+quantity/SM
+quantization
+quantize
+quantum/M
+quarantine/MGDS
+quark/MS
+quarrel/SZGMDR
+quarreler/M
+quarrelsome/P
+quarrelsomeness/M
+quarry/DSMG
+quart/MS
+quarter/SGMDY
+quarterback/GMDS
+quarterdeck/MS
+quarterfinal/SM
+quarterly/SM
+quartermaster/MS
+quarterstaff/M
+quarterstaves
+quartet/SM
+quarto/MS
+quartz/M
+quasar/MS
+quash/GDS
+quasi
+quatrain/MS
+quaver/MDSG
+quavery
+quay/MS
+quayside/S
+queasily
+queasiness/M
+queasy/TPR
+queen/GMDYS
+queenly/RT
+queer/PTGMDRYS
+queerness/M
+quell/GDS
+quench/ZGDRSB
+quenchable/U
+quencher/M
+quenchless
+querulous/YP
+querulousness/M
+query/DSMG
+ques
+quesadilla/MS
+quest/IFAMS
+quested
+questing
+question/SMDRZGBJ
+questionable/U
+questionably/U
+questioned/U
+questioner/M
+questioning/MY
+questionnaire/SM
+queue's
+queue/CDS
+queuing
+quibble/DRSMZG
+quibbler/M
+quiche/SM
+quick/MNRYXTP
+quicken/DG
+quickfire
+quickie/SM
+quicklime/M
+quickness/M
+quicksand/MS
+quicksilver/M
+quickstep/MS
+quid/MS
+quiescence/M
+quiescent/Y
+quiet/SMDNRYXTGP
+quieten/DG
+quietism
+quietness/M
+quietude/IEM
+quietus/MS
+quiff/S
+quill/SM
+quilt/SMDRZG
+quilter/M
+quilting/M
+quin/S
+quince/SM
+quine/S
+quinidine
+quinine/M
+quinoa
+quinsy/M
+quint/SM
+quintessence/SM
+quintessential/Y
+quintet/SM
+quintuple/MGDS
+quintuplet/MS
+quip/MS
+quipped
+quipping
+quipster/SM
+quire's
+quire/IAS
+quirk/SMDG
+quirkiness/M
+quirky/RTP
+quirt/SM
+quisling/SM
+quit/S
+quitclaim/MS
+quite
+quittance/M
+quitter/SM
+quitting
+quiver/SMDG
+quivery
+quixotic
+quixotically
+quiz/M
+quizzed
+quizzer/SM
+quizzes
+quizzical/Y
+quizzing
+quo/H
+quoin/SM
+quoit/SMDG
+quondam
+quorate/I
+quorum/SM
+quot/B
+quota/SM
+quotability/M
+quotation/SM
+quote's
+quote/UDSG
+quotidian
+quotient/SM
+qwerty
+r/S
+rabbet/GMDS
+rabbi/SM
+rabbinate/M
+rabbinic
+rabbinical
+rabbit/GMDS
+rabble/MS
+rabid/PY
+rabidness/M
+rabies/M
+raccoon/MS
+race/MZGDRS
+racecourse/SM
+racegoer/S
+racehorse/MS
+raceme/MS
+racer/M
+racetrack/MS
+raceway/MS
+racial/Y
+racialism/M
+racialist/MS
+racily
+raciness/M
+racing/M
+racism/M
+racist/SM
+rack/GMDS
+racket/SMDG
+racketeer/SMDG
+racketeering/M
+raconteur/SM
+racquet/SM
+racquetball/SM
+racy/PRT
+rad/SM
+radar/SM
+radarscope/SM
+raddled
+radial/SMY
+radian/S
+radiance/M
+radiant/Y
+radiate/DSGNX
+radiation/M
+radiator/SM
+radical/SMY
+radicalism/M
+radicalization/M
+radicalize/DSG
+radicchio/M
+radii
+radio/MDGS
+radioactive/Y
+radioactivity/M
+radiocarbon/M
+radiogram/MS
+radiographer/SM
+radiography/M
+radioisotope/MS
+radiologist/SM
+radiology/M
+radioman/M
+radiomen
+radiometer/MS
+radiometric
+radiometry/M
+radiophone/SM
+radioscopy/M
+radiosonde/SM
+radiosurgery
+radiotelegraph/M
+radiotelegraphs
+radiotelegraphy/M
+radiotelephone/MS
+radiotherapist/MS
+radiotherapy/M
+radish/MS
+radium/M
+radius/M
+radon/M
+raffia/M
+raffish/YP
+raffishness/M
+raffle/DSMG
+raft/ZGMDRS
+rafter/M
+rafting/M
+rag/SGMD
+raga/MS
+ragamuffin/MS
+ragbag/M
+rage/MS
+ragga
+ragged/RYTP
+raggedness/M
+raggedy/RT
+ragging
+raging/Y
+raglan/SM
+ragout/SM
+ragtag/S
+ragtime/M
+ragweed/M
+ragwort
+rah
+raid/ZGMDRS
+raider/M
+rail's
+rail/CGDS
+railcard/S
+railing/SM
+raillery/SM
+railroad/SZGMDR
+railroader/M
+railroading/M
+railway/SM
+railwayman
+railwaymen
+raiment/M
+rain/GMDS
+rainbow/SM
+raincoat/SM
+raindrop/SM
+rainfall/SM
+rainmaker/SM
+rainmaking/M
+rainproof
+rainstorm/MS
+rainwater/M
+rainy/RT
+raise/MZGDRS
+raiser/M
+raisin/SM
+raja/MS
+rajah/M
+rajahs
+rake/MGDS
+rakish/YP
+rakishness/M
+rally/DSMG
+ram/SM
+ramble/DRSMZGJ
+rambler/M
+rambunctious/PY
+rambunctiousness/M
+ramekin/SM
+ramie/M
+ramification/M
+ramify/DSXNG
+ramjet/SM
+rammed
+ramming
+ramp/GMS
+rampage/DSMG
+rampancy/M
+rampant/Y
+rampart/SM
+ramrod/SM
+ramrodded
+ramrodding
+ramshackle
+ran/A
+ranch/MDRSZG
+rancher/M
+ranching/M
+rancid/P
+rancidity/M
+rancidness/M
+rancor/M
+rancorous/Y
+rand/M
+randiness/M
+random/PSY
+randomization/M
+randomize/DSG
+randomness/MS
+randy/RTP
+ranee/MS
+rang/ZR
+range's
+range/CGDS
+rangefinder/S
+ranger/M
+ranginess/M
+rangy/RTP
+rani/MS
+rank/TGJPMDRYS
+ranking/M
+rankle/DSG
+rankness/M
+ransack/SGD
+ransom/SZGMDR
+ransomer/M
+ransomware
+rant/ZGMDJRS
+ranter/M
+rap/SZGMDR
+rapacious/PY
+rapaciousness/M
+rapacity/M
+rape/MS
+raper/M
+rapeseed/M
+rapid/PMRYTS
+rapidity/M
+rapidness/M
+rapier/SM
+rapine/M
+rapist/SM
+rapped
+rappel/SM
+rappelled
+rappelling
+rapper/SM
+rapping
+rapport/MS
+rapporteur/S
+rapprochement/SM
+rapscallion/MS
+rapt/YP
+raptness/M
+raptor/S
+rapture/MS
+rapturous/Y
+rare/YTGPDRS
+rarebit/MS
+rarefaction/M
+rarefy/GDS
+rareness/M
+rarity/SM
+rascal/SMY
+rash/ZTMRSYP
+rasher/M
+rashness/M
+rasp/GMDS
+raspberry/SM
+raspy/RT
+raster
+rat/SM
+ratatouille/M
+ratbag/S
+ratchet/GMDS
+rate/JXMZGNDRS
+rated/U
+ratepayer/S
+rater/M
+rather
+rathskeller/SM
+ratification/M
+ratifier/M
+ratify/NDRSZG
+rating/M
+ratio/MS
+ratiocinate/GNDS
+ratiocination/M
+ration/MDG
+rational/SMY
+rationale/MS
+rationalism/M
+rationalist/SM
+rationalistic
+rationality/M
+rationalization/MS
+rationalize/DSG
+ratlike
+ratline/SM
+rattan/SM
+ratted
+ratter/SM
+ratting
+rattle/DRSMZGJ
+rattlebrain/SMD
+rattler/M
+rattlesnake/SM
+rattletrap/SM
+rattly
+rattrap/SM
+ratty/RT
+raucous/YP
+raucousness/M
+raunchily
+raunchiness/M
+raunchy/TRP
+ravage/DRSMZG
+ravager/M
+ravages/M
+rave/JMZGDRS
+ravel's
+ravel/UDSG
+raveling/S
+raven/MDSG
+ravenous/Y
+ravine/SM
+raving/M
+ravioli/SM
+ravish/DRSZGL
+ravisher/M
+ravishing/Y
+ravishment/M
+raw/PTMR
+rawboned
+rawhide/M
+rawness/M
+ray/SM
+rayon/M
+raze/GDS
+razor/MS
+razorback/MS
+razz/GMDS
+razzmatazz/M
+rcpt
+rd
+re/DSMYTGVJ
+reach/MDSGB
+reachable/U
+reacquire/DSG
+react/V
+reactance
+reactant/SM
+reactionary/SM
+reactivity
+read/ZGMRBJS
+readability/SM
+reader/M
+readership/SM
+readily
+readiness/M
+reading/M
+readmitted
+readout/SM
+ready/DRSTGP
+reafforestation
+real/TMRYPS
+realism/M
+realist/SM
+realistic/U
+realistically/U
+realities
+reality/UM
+realization/MS
+realize/DSBG
+realized/U
+realm/MS
+realness/M
+realpolitik/M
+realtor/SM
+realty/M
+ream/ZGMDRS
+reamer/M
+reap/ZGDRS
+reaper/M
+rear/GMDS
+rearguard/MS
+rearmost
+rearward/S
+reason/SMDRZGB
+reasonable/UP
+reasonableness/UM
+reasonably/U
+reasoner/M
+reasoning/M
+reassuring/Y
+rebate/M
+rebel/MS
+rebellion/MS
+rebellious/YP
+rebelliousness/M
+rebid/S
+rebidding
+rebirth/M
+reboil/SDG
+rebuild/SG
+rebuke/DSMG
+rebuking/Y
+rebuttal/MS
+rec'd
+rec/M
+recalcitrance/M
+recalcitrant
+recant/SDG
+recantation/SM
+recap/MS
+recapitalization
+recce/S
+recd
+receipt/SMDG
+receivables/M
+receive/DRSZGB
+receiver/M
+receivership/M
+recent/RYTP
+recentness/M
+receptacle/SM
+reception/MS
+receptionist/SM
+receptive/PY
+receptiveness/M
+receptivity/M
+receptor/SM
+recess/MDSGV
+recessional/SM
+recessionary
+recessive/SM
+recherche
+recherch辿
+recidivism/M
+recidivist/SM
+recipe/SM
+recipient/SM
+reciprocal/SMY
+reciprocate/GNDS
+reciprocation/M
+reciprocity/M
+recital/SM
+recitalist/MS
+recitative/MS
+reciter/SM
+reckless/YP
+recklessness/M
+reckon/SJDG
+reckoning/M
+reclamation/M
+recline/DRSZG
+recliner/M
+recluse/SMV
+recognizable/U
+recognizably/U
+recognize/DRSGB
+recognized/U
+recombination
+recompense/DSMG
+recompilation
+recompile/GD
+recon/S
+reconcile/GDSB
+reconciliation/S
+recondite
+reconfiguration
+reconfigure/D
+reconnaissance/MS
+reconnoiter/DGS
+reconstruct/V
+reconstructed/U
+recorded/U
+recorder/MS
+recording/MS
+recoup/DG
+recourse/M
+recoverable/U
+recovery/SM
+recreant/MS
+recreational
+recriminate/DSGNX
+recrimination/M
+recriminatory
+recrudesce/GDS
+recrudescence/M
+recrudescent
+recruit/LSMDRZG
+recruiter/M
+recruitment/M
+rectal/Y
+rectangle/MS
+rectangular
+rectifiable
+rectification/M
+rectifier/M
+rectify/XNDRSZG
+rectilinear
+rectitude/M
+recto/MS
+rector/SM
+rectory/SM
+rectum/SM
+recumbent
+recuperate/GNVDS
+recuperation/M
+recur/S
+recurred
+recurrence/SM
+recurring
+recursion/S
+recuse/DSG
+recyclable/SM
+recycling/M
+red/PSM
+redact/SDG
+redaction/M
+redactor/SM
+redbird/SM
+redbreast/MS
+redbrick
+redcap/SM
+redcoat/SM
+redcurrant/S
+redden/SDG
+redder
+reddest
+reddish
+redeem/RZB
+redeemer/M
+redemption/M
+redemptive
+redhead/SMD
+redirection
+redistrict/GD
+redivide/GDS
+redlining/M
+redneck/SM
+redness/M
+redo/G
+redolence/M
+redolent
+redoubt/SBM
+redoubtably
+redound/SDG
+redraw/SG
+redskin/SM
+reduce/DRSZG
+reducer/M
+reducible
+reductase/M
+reduction/SM
+reductionist
+reductive
+redundancy/SM
+redundant/Y
+redwood/SM
+redye/DS
+reediness/M
+reedy/RTP
+reef/ZGMDRS
+reefer/M
+reek/GMDS
+reel's
+reel/UGDS
+reeve/G
+reexport/SDG
+ref/SZM
+refashion/DGS
+refection/M
+refectory/SM
+refer/B
+referee/DSM
+refereeing
+reference/MGDS
+referendum/MS
+referent/SM
+referential
+referral/SM
+referred
+referrer/SM
+referring
+reffed
+reffing
+refill/BM
+refined/U
+refinement/SM
+refiner/SM
+refinery/S
+refitting
+reflate/XDSGN
+reflationary
+reflect/GVSD
+reflection/MS
+reflective/Y
+reflectivity
+reflector/MS
+reflexive/SMY
+reflexivity
+reflexology
+reforge/DSG
+reform/MZ
+reformat/V
+reformatory/SM
+reformatting
+reformed/U
+reformist/S
+refortify/GDS
+refract/SGVD
+refraction/M
+refractory/SM
+refrain/SGMD
+refresh/ZGLDRS
+refresher/M
+refreshing/Y
+refreshment/SM
+refreshments/M
+refrigerant/SM
+refrigerate/DSGN
+refrigeration/M
+refrigerator/MS
+refuge/SM
+refugee/SM
+refulgence/M
+refulgent
+refund/B
+refurbishment/MS
+refusal/MS
+refutation/MS
+refute/BDRSZG
+refuter/M
+reg
+regal/DYG
+regalement/M
+regalia/M
+regard/ESMDG
+regardless
+regards/M
+regather/DGS
+regatta/SM
+regency/SM
+regeneracy/M
+regenerate/V
+regex/M
+regexp/S
+reggae/M
+regicidal
+regicide/MS
+regime/SM
+regimen/SM
+regiment/MDGS
+regimental
+regimentation/M
+region/SM
+regional/Y
+regionalism/MS
+register/GMDS
+registered/U
+registrant/MS
+registrar/MS
+registration/SM
+registry/SM
+regnant
+regress/MDSGV
+regression/MS
+regret/SM
+regretful/Y
+regrettable
+regrettably
+regretted
+regretting
+regrind/GS
+reground
+regroup/DGS
+regular/MYS
+regularity/SM
+regularization/M
+regularize/DSG
+regulate/CDSGNV
+regulated/U
+regulation/CM
+regulations
+regulator/MS
+regulatory
+regurgitate/DSGN
+regurgitation/M
+rehab/MS
+rehabbed
+rehabbing
+rehabilitate/GNVDS
+rehabilitation/M
+rehang/SDG
+rehears/GD
+rehearsal/MS
+rehearsed/U
+rehi
+rehung
+reify/NDSG
+reign/MDSG
+reimburse/BDSGL
+reimbursement/MS
+rein/GD
+reindeer/M
+reinforce/LGDS
+reinforcement/SM
+reinitialize
+reinstall/DG
+reinstatement/M
+reinsurance
+reiterate/V
+reject/GSMD
+rejection/SM
+rejoice/JGDS
+rejoicing/M
+rejoinder/SM
+rejuvenate/DSGN
+rejuvenation/M
+rel
+relate/DRSBXZGNV
+relatedness/M
+relater/M
+relation/M
+relational
+relationship/MS
+relative/MYS
+relativism/M
+relativist/S
+relativistic
+relativity/M
+relax/DRSZG
+relaxant/MS
+relaxation/SM
+relaxer/M
+relay/D
+release/B
+released/U
+relegate/GNDS
+relent/SGD
+relentless/PY
+relentlessness/M
+relevance/M
+relevancy/M
+relevant/Y
+reliability/UM
+reliable/U
+reliably/U
+reliance/M
+reliant
+relic/MS
+relief/SM
+relieve/ZGDRS
+reliever/M
+religion/SM
+religiosity
+religious/MYP
+religiousness/M
+reline/DSG
+relinquish/LDSG
+relinquishment/M
+reliquary/SM
+relish/GMDS
+relist/SGD
+relocate/B
+reluctance/M
+reluctant/Y
+rely/GDS
+rem/M
+remain/SGD
+remainder/GMDS
+remand/SGD
+remapping
+remark/B
+remarkableness/M
+remarkably
+remarked/U
+remediable
+remedy/GDSM
+remember/DG
+remembered/U
+remembrance/MS
+reminder/M
+reminisce/GDS
+reminiscence/MS
+reminiscent/Y
+remiss/PY
+remissness/M
+remit/S
+remittance/SM
+remitted
+remitting/U
+remix/DSG
+remnant/MS
+remodel/GDS
+remold/SGD
+remonstrant/SM
+remonstrate/DSG
+remorse/M
+remorseful/Y
+remorseless/PY
+remorselessness/M
+remote/RSMYTP
+remoteness/M
+removal/SM
+remunerate/GNVXDS
+remuneration/M
+renaissance/MS
+renal
+renascence/S
+rend/GS
+render/SGMDJ
+rendering/M
+rendezvous/GMDS
+rendition/MS
+renegade/DSMG
+renege/DRSZG
+reneger/M
+renew/DSBG
+renewal/MS
+rennet/M
+rennin/M
+renounce/LDSG
+renouncement/M
+renovate/DSXGN
+renovation/M
+renovator/MS
+renown/MD
+rent/ZGMDRS
+rental/SM
+renter/M
+renunciation/SM
+reopen/SDG
+reorg/MDSG
+rep/SM
+repaint/GDS
+repair/BZR
+repairer/M
+repairman/M
+repairmen
+reparable
+reparation/MS
+reparations/M
+repartee/M
+repatriate/XDSMGN
+repatriation/M
+repeat/SMDRZGB
+repeatability
+repeatable/U
+repeatably
+repeated/Y
+repeater/M
+repeating/M
+repel/S
+repelled
+repellent/SM
+repelling
+repent/SDG
+repentance/M
+repentant/Y
+repercussion/S
+repertoire/MS
+repertory/SM
+repetition/MS
+repetitious/YP
+repetitiousness/M
+repetitive/YP
+repetitiveness/M
+rephotograph/DG
+replaceable
+replant/GSD
+replenish/LGDS
+replenishment/M
+replete/PDSGN
+repleteness/M
+repletion/M
+replica/SM
+replicate/DSGNX
+replication/M
+replicator/S
+reportage/M
+reported/Y
+reportorial
+reposeful
+reposition
+repository/SM
+reprehend/DGS
+reprehensibility/M
+reprehensible
+reprehensibly
+reprehension/M
+represent/GDS
+representational
+representative/MS
+represented/U
+repression/MS
+repressive/PY
+reprieve/DSMG
+reprimand/GSMD
+reprisal/SM
+reprise/SMG
+reproach/GMDSB
+reproachful/Y
+reprobate/MS
+reproductive
+reprogramming
+reproving/Y
+reptile/SM
+reptilian/MS
+republic/S
+republicanism/M
+repudiate/XGNDS
+repudiation/M
+repudiator/MS
+repugnance/M
+repugnant
+repulsion/M
+repulsive/YP
+repulsiveness/M
+repurchase/GDS
+reputability/M
+reputably/E
+reputation/MS
+repute/DSMGB
+reputed/Y
+request/GDR
+requiem/SM
+require/LDG
+requirement/MS
+requisite/XMNS
+requisition/GMD
+requital/M
+requite/DRSZG
+requited/U
+requiter/M
+reread/SG
+rerecord/GDS
+rerunning
+resample/GDS
+resat
+rescind/SDG
+rescission/M
+rescue/DRSMZG
+rescuer/M
+reseal/B
+resemble/DSG
+resend
+resent/LSDG
+resentful/YP
+resentfulness/M
+resentment/MS
+reserpine/M
+reservation/MS
+reserved/UY
+reservedness/M
+reservist/SM
+reservoir/SM
+resetting
+reshipping
+residence/SM
+residency/SM
+resident/MS
+residential
+residua
+residual/MS
+residue/SM
+residuum/M
+resignation/SM
+resigned/Y
+resilience/M
+resiliency/M
+resilient/Y
+resinous
+resist/SMDRZG
+resistance/SM
+resistant/U
+resistible
+resistivity
+resistless
+resistor/MS
+resit/S
+resitting
+resold
+resole/DSG
+resolute/PY
+resoluteness/M
+resolve/RBM
+resolved/U
+resonance/SM
+resonant/Y
+resonate/GDS
+resonator/SM
+resorption/M
+resound/SGD
+resounding/Y
+resourceful/YP
+resourcefulness/M
+resp
+respect/ESGVMD
+respectability/M
+respectable
+respectably
+respectful/EY
+respectfulness/M
+respective/Y
+respell/SGD
+respiration/M
+respirator/SM
+respiratory
+respire/DG
+resplendence/M
+resplendent/Y
+respond/SGD
+respondent/SM
+response/MS
+responsibility/SM
+responsible
+responsibly
+responsive/UYP
+responsiveness/UM
+rest/GVMDS
+restate/GDS
+restaurant/SM
+restaurateur/MS
+restful/YP
+restfuller
+restfullest
+restfulness/M
+restitution/M
+restive/YP
+restiveness/M
+restless/PY
+restlessness/M
+restoration/SM
+restorative/SM
+restorer/SM
+restrained/U
+restraint/MS
+restrict/SDGV
+restricted/U
+restriction/MS
+restrictive/YP
+restrictiveness/M
+restring/SG
+restroom/SM
+restructuring/SM
+result/GSMD
+resultant/SM
+resume/DSMG
+resumption/MS
+resupply/DSG
+resurgence/MS
+resurgent
+resurrect/GSD
+resurrection/MS
+resuscitate/GNDS
+resuscitation/M
+resuscitator/SM
+retailer/MS
+retain/SDRZG
+retainer/M
+retake/G
+retaliate/DSGNVX
+retaliation/M
+retaliatory
+retard/SMDRZG
+retardant/SM
+retardation/M
+retarder/M
+retch/DSG
+reteach/GS
+retention/M
+retentive/YP
+retentiveness/M
+rethink/SGM
+rethought
+reticence/M
+reticent/Y
+reticulated
+reticulation/MS
+reticulum
+retina/SM
+retinal
+retinoblastoma
+retinue/SM
+retiree/SM
+retirement/MS
+retort/GMD
+retrace/GDS
+retract/DBG
+retractile
+retraction/S
+retrain/DGS
+retread/D
+retrenchment/MS
+retribution/MS
+retributive
+retrieval/SM
+retrieve/DRSMZGB
+retriever/M
+retro/MS
+retroactive/Y
+retrofire/GDS
+retrofit/SM
+retrofitted
+retrofitting
+retrograde/DSG
+retrogress/GVDS
+retrogression/M
+retrorocket/MS
+retrospect/MDSGV
+retrospection/M
+retrospective/MYS
+retrovirus/MS
+retsina/M
+returnable/SM
+returnee/SM
+rev/ZVM
+revamping/M
+reveal/GJSD
+revealed/U
+revealing/Y
+reveille/M
+revel/JMDRSZG
+revelation/SM
+revelatory
+reveler/M
+revelry/SM
+revenge/MGDS
+revenuer/SM
+reverb
+reverberate/DSGNX
+reverberation/M
+revere/DSG
+reverence/DSMG
+reverend/SM
+reverent/Y
+reverential/Y
+reverie/MS
+revers/M
+reversal/SM
+reverse/Y
+reversibility
+reversible
+reversibly
+revert/GSD
+revertible
+revetment/SM
+revile/DRSLZG
+revilement/M
+reviler/M
+reviser/MS
+revision/SM
+revisionism/M
+revisionist/SM
+revival/MS
+revivalism/M
+revivalist/SM
+revive/DSG
+revivification/M
+revocable
+revoke/DSG
+revolt/GD
+revolting/Y
+revolution/SM
+revolutionary/SM
+revolutionist/SM
+revolutionize/DSG
+revolve/BZGDRS
+revolver/M
+revue/MS
+revulsion/M
+revved
+revving
+rewarded/U
+rewarding/U
+rewarm/GSD
+rewash/GDS
+reweave/GS
+rewedding
+rewind/MB
+rewound
+rewrite/MGS
+rhapsodic
+rhapsodical
+rhapsodize/GDS
+rhapsody/SM
+rhea/MS
+rhenium/M
+rheostat/SM
+rhesus/MS
+rhetoric/M
+rhetorical/Y
+rhetorician/SM
+rheum/M
+rheumatic/MS
+rheumatically
+rheumatism/M
+rheumatoid
+rheumy
+rhinestone/SM
+rhinitis/M
+rhino/MS
+rhinoceros/MS
+rhinoplasty
+rhinovirus/MS
+rhizome/MS
+rho/SM
+rhodium/M
+rhododendron/SM
+rhomboid/SM
+rhomboidal
+rhombus/MS
+rhubarb/MS
+rhyme/MZGDRS
+rhymer/M
+rhymester/MS
+rhythm/SM
+rhythmic
+rhythmical/Y
+rial/MS
+rib/SM
+ribald
+ribaldry/M
+ribbed
+ribber/SM
+ribbing
+ribbon/SM
+riboflavin/M
+rice/MZGDRS
+ricer/M
+rich/TMRSYP
+richness/M
+rick/GMDS
+rickets/M
+rickety/RT
+rickrack/M
+rickshaw/MS
+ricochet/GMDS
+ricotta/M
+rid/S
+riddance/M
+ridden
+ridding
+riddle/DSMG
+ride/MZGRS
+rider/M
+riderless
+ridership/M
+ridge/MGDS
+ridgepole/SM
+ridgy
+ridicule/MGDS
+ridiculous/YP
+ridiculousness/M
+riding/M
+rife/TR
+riff/GMDS
+riffle/DSMG
+riffraff/M
+rifle/MZGDRS
+rifleman/M
+riflemen
+rifler/M
+rifling/M
+rift/GMDS
+rig/SM
+rigamarole/SM
+rigatoni/M
+rigged
+rigger/SM
+rigging/M
+right/MDRYSPTG
+righteous/UP
+righteously
+righteousness/UM
+rightful/PY
+rightfulness/M
+rightism/M
+rightist/SM
+rightmost
+rightness/M
+righto
+rightsize/DSG
+rightward/S
+rigid/YP
+rigidity/M
+rigidness/M
+rigmarole/MS
+rigor/MS
+rigorous/YP
+rigorousness/M
+rile/GDS
+rill/MS
+rim/SGMD
+rime/MS
+rimless
+rimmed
+rimming
+rind/MS
+ring/ZGMDRJ
+ringer/M
+ringgit/MS
+ringleader/MS
+ringlet/MS
+ringlike
+ringmaster/MS
+ringside/M
+ringtone/SM
+ringworm/M
+rink/MS
+rinse/MGDS
+riot/ZGMDRS
+rioter/M
+rioting/M
+riotous/PY
+rip/SXTMNR
+riparian
+ripcord/MS
+ripe/YP
+ripen/DG
+ripened/U
+ripeness/M
+ripoff/SM
+riposte/MGDS
+ripped
+ripper/SM
+ripping
+ripple/DSMG
+ripply
+ripsaw/SM
+riptide/MS
+rise/JMZGRS
+risen
+riser/M
+risibility/M
+risible
+rising/M
+risk/GMDS
+riskily
+riskiness/M
+risky/RPT
+risotto/MS
+risque
+risqu辿
+rissole/S
+rite/MS
+ritual/SMY
+ritualism/M
+ritualistic
+ritualistically
+ritualized
+ritzy/RT
+riv/ZNR
+rival/MDSG
+rivaled/U
+rivalry/SM
+rive/CGDS
+river/M
+riverbank/SM
+riverbed/MS
+riverboat/SM
+riverfront
+riverside/MS
+rivet/MDRSZG
+riveter/M
+riviera/S
+rivulet/MS
+riyal/MS
+rm
+roach/GMDS
+road/IMS
+roadbed/SM
+roadblock/MDSG
+roadhouse/SM
+roadie/MS
+roadkill/M
+roadrunner/SM
+roadshow/SM
+roadside/SM
+roadster/SM
+roadway/SM
+roadwork/SM
+roadworthy
+roam/ZGDRS
+roamer/M
+roaming/M
+roan/MS
+roar/ZGMDRS
+roarer/M
+roaring/M
+roast/ZGMDRSJ
+roaster/M
+roasting/M
+rob/S
+robbed
+robber/MS
+robbery/SM
+robbing
+robe's
+robe/EGDS
+robin/MS
+robocall/SGMD
+robot/MS
+robotic/S
+robotics/M
+robotize/GDS
+robust/RYPT
+robustness/M
+rock/ZGMDRS
+rockabilly/M
+rockbound
+rocker/M
+rockery/S
+rocket/MDSG
+rocketry/M
+rockfall/SM
+rockiness/M
+rocky/TRP
+rococo/M
+rod/SM
+rode
+rodent/MS
+rodeo/MS
+roe/SM
+roebuck/SM
+roentgen/MS
+roger/GDS
+rogue's
+rogue/KS
+roguery/M
+roguish/YP
+roguishness/M
+roil/GDS
+roister/ZGDRS
+roisterer/M
+role/MS
+roll/MDRZGJS
+rollback/SM
+roller/M
+rollerblading
+rollerskating/M
+rollick/SDG
+rollicking/M
+rollmop/S
+rollover/SM
+romaine/MS
+roman/M
+romance/MZGDRS
+romancer/M
+romantic/MS
+romantically
+romanticism/M
+romanticist/SM
+romanticize/DSG
+romeo/MS
+romp/MDRZGS
+romper/M
+rondo/SM
+rood/MS
+roof/MDRZGS
+roofer/M
+roofing/M
+roofless
+rooftop/SM
+rook/MDGS
+rookery/SM
+rookie/SM
+room/MDRZGS
+roomer/M
+roomette/SM
+roomful/SM
+roominess/M
+roommate/SM
+roomy/RTP
+roost/SMDRZG
+rooster/M
+root/MDRZGS
+rooter/M
+rootkit/SM
+rootless/P
+rootlet/SM
+rope/MZGDRS
+roper/M
+ropy/RT
+rosary/SM
+rose/MS
+roseate
+rosebud/SM
+rosebush/MS
+rosemary/M
+rosette/SM
+rosewater/M
+rosewood/MS
+rosily
+rosin/SMDG
+rosiness/M
+roster/SM
+rostrum/MS
+rosy/RTP
+rot/SM
+rota/S
+rotary/SM
+rotate/DSGNX
+rotation/M
+rotational
+rotatory
+rote/M
+rotgut/M
+rotisserie/SM
+rotogravure/MS
+rotor/SM
+rototiller/MS
+rotted
+rotten/TPRY
+rottenness/M
+rotter/S
+rotting
+rottweiler/S
+rotund/P
+rotunda/MS
+rotundity/M
+rotundness/M
+roue/MS
+rouge/DSMG
+rough/MDNRYXTGP
+roughage/M
+roughcast
+roughen/GD
+roughhouse/MGDS
+roughneck/GMDS
+roughness/M
+roughs
+roughshod
+roulette/M
+round/PSMDRYZTG
+roundabout/SM
+roundel/S
+roundelay/MS
+roundhouse/SM
+roundish
+roundness/M
+roundup/MS
+roundworm/SM
+rouse/DSG
+roust/SDG
+roustabout/SM
+rout/MRZS
+route's
+route/ADSG
+routeing
+router/M
+routine/MYS
+routinize/GDS
+roux
+rou辿/MS
+rove/ZGDRS
+rover/M
+row/SZGMDR
+rowan/S
+rowboat/MS
+rowdily
+rowdiness/M
+rowdy/PRSMT
+rowdyism/M
+rowel/SMDG
+rower/M
+rowing/M
+rowlock/S
+royal/SMY
+royalist/SM
+royalties/M
+royalty/SM
+rpm
+rps
+rt
+rte
+rub/SM
+rubato/SM
+rubbed
+rubber/SM
+rubberize/GDS
+rubberneck/MDRSZG
+rubbernecker/M
+rubbery
+rubbing/S
+rubbish/MDSG
+rubbishy
+rubble/M
+rubdown/SM
+rube/MS
+rubella/M
+rubicund
+rubidium/M
+ruble/SM
+rubric/SM
+ruby/RSMT
+ruched
+ruck/DGS
+rucksack/MS
+ruckus/MS
+ructions
+rudder/SM
+rudderless
+ruddiness/M
+ruddy/RTP
+rude/YTRP
+rudeness/M
+rudiment/SM
+rudimentary
+rue/DSMG
+rueful/PY
+ruefulness/M
+ruff/MDYGS
+ruffian/MYS
+ruffle/DSMG
+ruffled/U
+rug/SM
+rugby/M
+rugged/PTRY
+ruggedness/M
+rugger
+rugrat/SM
+ruin/MDGS
+ruination/M
+ruinous/Y
+rule/MZGJDRS
+ruler/M
+ruling/M
+rum/SM
+rumba/SMDG
+rumble/DSJMG
+rumbling/M
+rumbustious
+ruminant/MS
+ruminate/XGNVDS
+rumination/M
+ruminative/Y
+rummage/DSMG
+rummer
+rummest
+rummy/M
+rumor/SMDG
+rumormonger/SM
+rump/MYS
+rumple/DSMG
+rumpus/MS
+run/ASM
+runabout/MS
+runaround/SM
+runaway/MS
+rundown/SM
+rune/MS
+rung/MS
+runic
+runlet/SM
+runnel/SM
+runner/SM
+running/M
+runny/RT
+runoff/SM
+runt/MS
+runtime
+runty/RT
+runway/SM
+rupee/SM
+rupiah/M
+rupiahs
+rupture/MGDS
+rural
+ruse/MS
+rush/MDRSZG
+rusher/M
+rushy
+rusk/MS
+russet/SM
+rust/MDGS
+rustic/SM
+rustically
+rusticate/GDS
+rustication/M
+rusticity/M
+rustiness/M
+rustle/DRSJMZG
+rustler/M
+rustproof/SDG
+rusty/RPNT
+rut/SM
+rutabaga/SM
+ruthenium/M
+rutherfordium/M
+ruthless/YP
+ruthlessness/M
+rutted
+rutting
+rutty/RT
+rye/M
+s/NYXB
+sabbath/M
+sabbaths
+sabbatical/SM
+saber/MS
+sable/MS
+sabot/MS
+sabotage/DSMG
+saboteur/SM
+sabra/MS
+sabre/MS
+sac/SM
+saccharin/M
+saccharine
+sacerdotal
+sachem/SM
+sachet/SM
+sack/ZGMDRJS
+sackcloth/M
+sacker/M
+sackful/MS
+sacking/M
+sacra
+sacrament/MS
+sacramental
+sacred/YP
+sacredness/M
+sacrifice/DSMG
+sacrificial/Y
+sacrilege/MS
+sacrilegious/Y
+sacristan/MS
+sacristy/SM
+sacroiliac/MS
+sacrosanct/P
+sacrosanctness/M
+sacrum/M
+sad/PY
+sadden/SDG
+sadder
+saddest
+saddle's
+saddle/UDSG
+saddlebag/MS
+saddler/S
+saddlery
+sades
+sadhu/S
+sadism/M
+sadist/SM
+sadistic
+sadistically
+sadness/M
+sadomasochism/M
+sadomasochist/MS
+sadomasochistic
+safari/SGMD
+safe/MYTPRS
+safeguard/SMDG
+safekeeping/M
+safeness/M
+safety/SM
+safflower/MS
+saffron/MS
+sag/SM
+saga/MS
+sagacious/Y
+sagacity/M
+sage/MYTRS
+sagebrush/M
+sagged
+sagging
+saggy/RT
+sago/M
+saguaro/MS
+sahib/MS
+said/U
+sail/GMDSJ
+sailboard/MRZGS
+sailboarder/M
+sailboarding/M
+sailboat/MS
+sailcloth/M
+sailfish/MS
+sailing/M
+sailor/SM
+sailplane/MS
+saint/MDYS
+sainthood/M
+saintlike
+saintliness/M
+saintly/PRT
+saith
+sake/M
+saki/M
+salaam/SMDG
+salable/U
+salacious/PY
+salaciousness/M
+salacity/M
+salad/MS
+salamander/SM
+salami/SM
+salary/DSM
+sale/ABMS
+saleable/U
+saleroom/S
+salesclerk/SM
+salesgirl/SM
+saleslady/SM
+salesman/M
+salesmanship/M
+salesmen
+salespeople/M
+salesperson/MS
+salesroom/S
+saleswoman/M
+saleswomen
+salience/M
+salient/SMY
+saline/SM
+salinity/M
+saliva/M
+salivary
+salivate/GNDS
+salivation/M
+sallow/RTP
+sallowness/M
+sally/DSMG
+salmon/SM
+salmonella/M
+salmonellae
+salon/MS
+saloon/SM
+salsa/MS
+salt's
+salt/CTGDS
+saltbox/MS
+saltcellar/SM
+salted/U
+salter
+saltine/SM
+saltiness/M
+saltpeter/M
+saltshaker/SM
+saltwater/M
+salty/RTP
+salubrious/I
+salutary
+salutation/MS
+salutatorian/MS
+salutatory
+salute/DSMG
+salvage/DSMG
+salvageable
+salvation/M
+salve/MZGDRS
+salver/M
+salvo/MS
+samarium/M
+samba/MDSG
+same/SP
+sameness/M
+samey
+samizdat/S
+samosa/S
+samovar/SM
+sampan/SM
+sample/DRSMZGJ
+sampler/M
+sampling/M
+samurai/SM
+sanatorium/SM
+sanctification/M
+sanctify/GDSN
+sanctimonious/YP
+sanctimoniousness/M
+sanctimony/M
+sanction/GSMD
+sanctioned/U
+sanctity/M
+sanctuary/SM
+sanctum/SM
+sand/ZGMDRS
+sandal/SM
+sandalwood/M
+sandbag/SM
+sandbagged
+sandbagger/SM
+sandbagging
+sandbank/MS
+sandbar/SM
+sandblast/ZGMDRS
+sandblaster/M
+sandbox/MS
+sandcastle/MS
+sander/M
+sandhog/SM
+sandiness/M
+sandlot/SM
+sandlotter/MS
+sandman/M
+sandmen
+sandpaper/GMDS
+sandpiper/MS
+sandpit/S
+sandstone/M
+sandstorm/SM
+sandwich/MDSG
+sandy/RTP
+sane/IYTR
+saneness/M
+sang/S
+sangfroid/M
+sangria/M
+sanguinary
+sanguine/Y
+sanitarian/SM
+sanitarium/SM
+sanitary/IU
+sanitation/M
+sanitize/ZGDRS
+sanity/IM
+sank
+sans
+sanserif
+sap/SM
+sapience/M
+sapiens
+sapient
+sapless
+sapling/MS
+sapped
+sapper/S
+sapphire/SM
+sappiness/M
+sapping
+sappy/PRT
+saprophyte/SM
+saprophytic
+sapsucker/SM
+sapwood/M
+saran/M
+sarcasm/MS
+sarcastic
+sarcastically
+sarcoma/MS
+sarcophagi
+sarcophagus/M
+sardine/MS
+sardonic
+sardonically
+sarge/MS
+sari/MS
+sarky
+sarnie/S
+sarong/SM
+sarsaparilla/MS
+sartorial/Y
+sash/MS
+sashay/SGMD
+sass/GMDS
+sassafras/MS
+sassy/RT
+sat
+satanic
+satanical/Y
+satanism/M
+satanist/MS
+satay
+satchel/MS
+sate/GDS
+sateen/M
+satellite/DSMG
+satiable/I
+satiate/GNDS
+satiation/M
+satiety/M
+satin/M
+satinwood/SM
+satiny
+satire/SM
+satiric
+satirical/Y
+satirist/SM
+satirize/DSG
+satisfaction/EM
+satisfactions
+satisfactorily/U
+satisfactory/U
+satisfied/U
+satisfy/EDSG
+satisfying/U
+satisfyingly
+satori/M
+satrap/SM
+satsuma/S
+saturate/DSGN
+saturated/U
+saturation/M
+saturnine
+satyr/MS
+satyriasis/M
+satyric
+sauce/MZGDRS
+saucepan/SM
+saucer/M
+saucily
+sauciness/M
+saucy/RPT
+sauerkraut/M
+sauna/MDSG
+saunter/MDGS
+saurian
+sauropod/SM
+sausage/MS
+saute/MS
+sauteed
+sauteing
+sauternes/M
+saut辿/MDSG
+savage/DRSMYTGP
+savageness/M
+savagery/SM
+savanna/MS
+savant/SM
+save/BJMZGDRS
+saveable
+saved/U
+saver/M
+saving/M
+savings/M
+savior/SM
+savor/MDSG
+savoriness/M
+savory/PTRSM
+savoy/MS
+savvy/DRSMTG
+saw/SGMD
+sawbones/M
+sawbuck/MS
+sawdust/M
+sawfly/SM
+sawhorse/SM
+sawmill/MS
+sawyer/SM
+sax/MS
+saxifrage/SM
+saxophone/MS
+saxophonist/SM
+say's
+say/USG
+saying/SM
+scab/MS
+scabbard/MS
+scabbed
+scabbiness/M
+scabbing
+scabby/PTR
+scabies/M
+scabrous
+scad/MS
+scaffold/SMG
+scaffolding/M
+scag/S
+scagged
+scalability
+scalar/S
+scalawag/MS
+scald/MDSG
+scale's
+scale/CGDS
+scaleless
+scalene
+scaliness/M
+scallion/MS
+scallop/GSMD
+scallywag/MS
+scalp/MDRSZG
+scalpel/SM
+scalper/M
+scaly/RTP
+scam/MS
+scammed
+scammer/S
+scamming
+scamp/MRSZ
+scamper/GMD
+scampi/M
+scan/MS
+scandal/SM
+scandalize/DSG
+scandalmonger/SM
+scandalous/Y
+scandium/M
+scanned
+scanner/SM
+scanning
+scansion/M
+scant/CDSTG
+scanter
+scantily
+scantiness/M
+scantly
+scantness/M
+scanty/RSPT
+scapegoat/SGMD
+scapegrace/MS
+scapula/M
+scapulae
+scapular/SM
+scar/GMDS
+scarab/SM
+scarce/RYTP
+scarceness/M
+scarcity/SM
+scare/MS
+scarecrow/MS
+scaremonger/SMG
+scarf/MDSG
+scarification/M
+scarify/NDSG
+scarily
+scariness/M
+scarlatina/M
+scarlet/M
+scarp/MDRSZG
+scarper/DG
+scarred
+scarring
+scarves
+scary/RTP
+scat/MS
+scathing/Y
+scatological
+scatology/M
+scatted
+scatter/GJSMD
+scatterbrain/SMD
+scattering/M
+scattershot
+scatting
+scatty
+scavenge/ZGDRS
+scavenger/M
+scenario/MS
+scenarist/MS
+scene/MS
+scenery/M
+scenic
+scenically
+scent/CMS
+scented/U
+scenting
+scentless
+scepter/MS
+sch
+schadenfreude
+schedule's
+schedule/ADSG
+scheduled/U
+scheduler/S
+schema
+schemata
+schematic/SM
+schematically
+schematize/GDS
+scheme/DRSMZG
+schemer/M
+scherzo/MS
+schilling/MS
+schism/SM
+schismatic/SM
+schist/M
+schistosomiasis
+schizo/SM
+schizoid/MS
+schizophrenia/M
+schizophrenic/SM
+schlemiel/SM
+schlep/SM
+schlepp/GMDS
+schlock/M
+schlocky
+schmaltz/M
+schmaltzy/TR
+schmo/M
+schmoe/SM
+schmooze/DRSZG
+schmuck/MS
+schnapps/M
+schnauzer/SM
+schnitzel/SM
+schnook/MS
+schnoz/MS
+schnozzle/SM
+scholar/MYS
+scholarship/MS
+scholastic
+scholastically
+scholasticism
+school/SGMD
+schoolbag/MS
+schoolbook/SM
+schoolboy/MS
+schoolchild/M
+schoolchildren/M
+schooldays
+schooled/U
+schoolfellow/SM
+schoolgirl/SM
+schoolhouse/SM
+schooling/M
+schoolkid/S
+schoolmarm/SM
+schoolmarmish
+schoolmaster/MS
+schoolmate/SM
+schoolmistress/MS
+schoolroom/SM
+schoolteacher/MS
+schoolwork/M
+schoolyard/SM
+schooner/SM
+schuss/GMDS
+schussboomer/MS
+schwa/MS
+sci
+sciatic
+sciatica/M
+science/FMS
+scientific/U
+scientifically/U
+scientist/SM
+scimitar/SM
+scintilla/MS
+scintillate/DSGN
+scintillation/M
+scion/MS
+scissor/GDS
+scleroses
+sclerosis/M
+sclerotic
+scoff/MDRSZG
+scoffer/M
+scofflaw/MS
+scold/MDSGJ
+scolding/M
+scoliosis/M
+sconce/SM
+scone/MS
+scoop/MDSG
+scoopful/MS
+scoot/DRSZG
+scooter/M
+scope/MGDS
+scorbutic
+scorch/MDRSZG
+scorcher/M
+score/MZGDRS
+scoreboard/SM
+scorecard/MS
+scorekeeper/MS
+scoreless
+scoreline/S
+scorer/M
+scorn/MDRSZG
+scorner/M
+scornful/Y
+scorpion/MS
+scotch/MDSG
+scotchs
+scoundrel/MS
+scour/DRSZG
+scourer/M
+scourge/DSMG
+scout/MDRSZG
+scouting/M
+scoutmaster/MS
+scow/MS
+scowl/MDSG
+scrabble/MZGDRS
+scrabbler/M
+scrag/MS
+scraggly/RT
+scraggy/TR
+scram/S
+scramble's
+scramble/UGDS
+scrambler/MS
+scrammed
+scramming
+scrap/MDRSZGJ
+scrapbook/SM
+scrape/SM
+scraper/M
+scrapheap/SM
+scrapie
+scrapped
+scrapper/MS
+scrapping
+scrappy/TR
+scrapyard/SM
+scratch/GMDS
+scratchcard/S
+scratched/U
+scratchily
+scratchiness/M
+scratchpad/S
+scratchy/PRT
+scrawl/SMDG
+scrawly
+scrawniness/M
+scrawny/PTR
+scream/SMDRZG
+screamer/M
+screaming/Y
+scree/MDS
+screech/GMDS
+screechy/TR
+screed/S
+screen/SJMDG
+screening/M
+screenplay/SM
+screensaver/SM
+screenshot/S
+screenwriter/SM
+screenwriting/M
+screw's
+screw/UDSG
+screwball/MS
+screwdriver/MS
+screwiness/M
+screwworm/SM
+screwy/PRT
+scribal
+scribble/MZGDRS
+scribbler/M
+scribe's
+scribe/CKIS
+scrim/MS
+scrimmage/MGDS
+scrimp/SDG
+scrimshaw/MDGS
+scrip/MS
+script/FSMDG
+scripted/U
+scriptural
+scripture/MS
+scriptwriter/SM
+scrivener/SM
+scrod/M
+scrofula/M
+scrofulous
+scrog/S
+scroll/GSMD
+scrooge/MS
+scrota
+scrotal
+scrotum/M
+scrounge/DRSZG
+scrounger/M
+scroungy/TR
+scrub/MS
+scrubbed
+scrubber/SM
+scrubbing
+scrubby/RT
+scruff/SM
+scruffily
+scruffiness/M
+scruffy/RPT
+scrum/S
+scrumhalf
+scrumhalves
+scrummage/S
+scrummed
+scrumming
+scrump/SGD
+scrumptious/Y
+scrumpy
+scrunch/MDSG
+scrunchie/M
+scrunchy/SM
+scruple/MGDS
+scrupulosity/M
+scrupulous/UPY
+scrupulousness/UM
+scrutineer/S
+scrutinize/GDS
+scrutiny/M
+scuba/MDSG
+scud/MS
+scudded
+scudding
+scuff/MDSG
+scuffle/MGDS
+scull/MDRSZG
+sculler/M
+scullery/SM
+scullion/SM
+sculpt/SGD
+sculptor/SM
+sculptress/MS
+sculptural
+sculpture/DSMG
+scum/MS
+scumbag/MS
+scummed
+scumming
+scummy/TR
+scupper/MDGS
+scurf/M
+scurfy
+scurrility/M
+scurrilous/PY
+scurrilousness/M
+scurry/GDSM
+scurvily
+scurvy/TRM
+scutcheon/SM
+scuttle/MGDS
+scuttlebutt/M
+scuzzy/TR
+scythe/DSMG
+sea/SM
+seabed/SM
+seabird/MS
+seaboard/SM
+seaborne
+seacoast/SM
+seafarer/SM
+seafaring/M
+seafloor/SM
+seafood/M
+seafront/SM
+seagoing
+seagull/MS
+seahorse/MS
+seal's
+seal/AUSDG
+sealant/MS
+sealer/SM
+sealskin/M
+seam/GMDNS
+seaman/M
+seamanship/M
+seamless/Y
+seamount/MS
+seamstress/MS
+seamy/RT
+seance/SM
+seaplane/SM
+seaport/MS
+sear/GMDS
+search/AZGMDRS
+searchable/U
+searcher/AM
+searching/Y
+searchlight/MS
+searing/Y
+seascape/SM
+seashell/SM
+seashore/SM
+seasick/P
+seasickness/M
+seaside/MS
+season/SGMDBJ
+seasonable/U
+seasonably/U
+seasonal/Y
+seasonality
+seasoned/U
+seasoning/M
+seat's
+seat/UGDS
+seating/M
+seatmate/SM
+seawall/MS
+seaward/MS
+seawater/M
+seaway/SM
+seaweed/MS
+seaworthiness/M
+seaworthy/P
+sebaceous
+seborrhea/M
+sebum
+sec'y
+sec/SM
+secant/SM
+secateurs
+secede/DSG
+secession/M
+secessionist/MS
+seclude/GDS
+seclusion/M
+seclusive
+second/SLZGMDRY
+secondarily
+secondary/SM
+seconder/M
+secondhand
+secondment/S
+secrecy/M
+secret/SGVMDY
+secretarial
+secretariat/MS
+secretary/SM
+secretaryship/M
+secrete/XNS
+secretion/M
+secretive/PY
+secretiveness/M
+secretory
+sect/IMS
+sectarian/MS
+sectarianism/M
+sectary/SM
+section/AESM
+sectional/MS
+sectionalism/M
+sectioned
+sectioning
+sector/ESM
+secular
+secularism/M
+secularist/SM
+secularization/M
+secularize/DSG
+secure/DRSYTG
+secured/U
+security/ISM
+secy
+sedan/MS
+sedate/DRSYTGNVP
+sedateness/M
+sedation/M
+sedative/SM
+sedentary
+sedge/M
+sedgy
+sediment/MS
+sedimentary
+sedimentation/M
+sedition/M
+seditious
+seduce/DRSZG
+seducer/M
+seduction/SM
+seductive/YP
+seductiveness/M
+seductress/MS
+sedulous/Y
+see/RSMZ
+seed's
+seed/AGDS
+seedbed/MS
+seedcase/MS
+seeded/U
+seeder/SM
+seediness/M
+seedless
+seedling/MS
+seedpod/MS
+seedy/RPT
+seeing/S
+seek/ZGRS
+seeker/M
+seem/GDS
+seeming/Y
+seemliness/UM
+seemly/URTP
+seen/U
+seep/GDS
+seepage/M
+seer/M
+seersucker/M
+seesaw/SMDG
+seethe/DSG
+segfault/S
+segment/GSMD
+segmentation/M
+segmented/U
+segregate/CDSGN
+segregated/U
+segregation/CM
+segregationist/MS
+segue/MGDS
+segueing
+seigneur/SM
+seignior/SM
+seigniorial
+seine/MZGDRS
+seiner/M
+seismic
+seismically
+seismograph/ZMR
+seismographer/M
+seismographic
+seismographs
+seismography/M
+seismologic
+seismological
+seismologist/MS
+seismology/M
+seize/GDS
+seizure/MS
+seldom
+select/CSGVD
+selection/SM
+selective/Y
+selectivity/M
+selectman/M
+selectmen
+selectness/M
+selector/MS
+selenium/M
+selenographer/MS
+selenography/M
+self/M
+selfie/SM
+selfish/UYP
+selfishness/UM
+selfless/PY
+selflessness/M
+selfsame
+sell's
+sell/AZGRS
+seller's
+selloff/MS
+sellotape/DSG
+sellout/MS
+seltzer/MS
+selvage/MS
+selvedge/MS
+selves
+semantic/S
+semantically
+semanticist/MS
+semantics/M
+semaphore/DSMG
+semblance/ASM
+semen/M
+semester/SM
+semi/MS
+semiannual/Y
+semiarid
+semiautomatic/MS
+semibreve/S
+semicircle/SM
+semicircular
+semicolon/MS
+semiconducting
+semiconductor/MS
+semiconscious
+semidarkness/M
+semidetached
+semifinal/SM
+semifinalist/MS
+semigloss/S
+semimonthly/SM
+seminal
+seminar/MS
+seminarian/SM
+seminary/SM
+semiofficial
+semiotic/S
+semiotics/M
+semipermeable
+semiprecious
+semiprivate
+semipro/S
+semiprofessional/SM
+semiquaver/S
+semiretired
+semiskilled
+semisolid
+semisweet
+semitone/SM
+semitrailer/MS
+semitransparent
+semitropical
+semivowel/SM
+semiweekly/SM
+semiyearly
+semolina/M
+sempstress/MS
+senate/SM
+senator/MS
+senatorial
+send/ZGRS
+sender/M
+sendoff/MS
+senescence/M
+senescent
+senile
+senility/M
+senior/SM
+seniority/M
+senna/M
+senor/MS
+senora/SM
+senorita/SM
+sensation/MS
+sensational/Y
+sensationalism/M
+sensationalist/MS
+sensationalize/GDS
+sense/MGDS
+senseless/PY
+senselessness/M
+sensibilities
+sensibility/IM
+sensible/P
+sensibleness/M
+sensibly/I
+sensitive/SMYP
+sensitiveness/M
+sensitivities
+sensitivity/IM
+sensitization/CM
+sensitize/CDSG
+sensor/SM
+sensory
+sensual/Y
+sensualist/SM
+sensuality/M
+sensuous/YP
+sensuousness/M
+sent/FAU
+sentence/MGDS
+sententious/Y
+sentience/IM
+sentient/I
+sentiment/SM
+sentimental/Y
+sentimentalism/M
+sentimentalist/MS
+sentimentality/M
+sentimentalization/M
+sentimentalize/GDS
+sentinel/MS
+sentry/SM
+sepal/MS
+separability/IM
+separable
+separably/I
+separate/XMYGNVDSP
+separateness/M
+separation/M
+separatism/M
+separatist/MS
+separator/MS
+sepia/M
+sepsis/M
+septa
+septal
+septet/SM
+septic
+septicemia/M
+septicemic
+septuagenarian/MS
+septum/M
+sepulcher/GMDS
+sepulchral
+seq
+sequel/SM
+sequence/MZGDRS
+sequencing/M
+sequential/FY
+sequester/SDG
+sequestrate/XGNDS
+sequestration/M
+sequin/SMD
+sequinned
+sequitur
+sequoia/MS
+seraglio/MS
+serape/SM
+seraph/M
+seraphic
+seraphs
+sere/TR
+serenade/MGDS
+serendipitous
+serendipity/M
+serene/RPYT
+sereneness/M
+serenity/M
+serf/MS
+serfdom/M
+serge/M
+sergeant/MS
+serial/SMY
+serialization/SM
+serialize/GDSB
+series/M
+serif/MS
+serigraph/M
+serigraphs
+serine
+serious/PY
+seriousness/M
+sermon/SM
+sermonize/GDS
+serology/M
+serotonin
+serous
+serpent/MS
+serpentine/M
+serrate/XND
+serration/M
+serried
+serum/MS
+servant/MS
+serve's/AF
+serve/FACGDS
+server/SM
+servery/S
+service/EMS
+serviceability/M
+serviceable
+serviced
+serviceman/M
+servicemen
+servicewoman/M
+servicewomen
+servicing
+serviette/MS
+servile
+servility/M
+serving's
+servings
+servitor/MS
+servitude/M
+servo/MS
+servomechanism/SM
+servomotor/MS
+sesame/SM
+sesquicentennial/MS
+session/MS
+set/AISM
+setback/MS
+setscrew/SM
+setsquare/S
+sett/BJZGRS
+settee/MS
+setter/M
+setting/M
+settle's
+settle/AUGDS
+settlement/AM
+settlements
+settler/SM
+setup/MS
+seven/MHS
+seventeen/SMH
+seventeenth/M
+seventeenths
+seventh/M
+sevenths
+seventieth/M
+seventieths
+seventy/SMH
+sever/ETGDS
+several/MY
+severance/SM
+severe/YPR
+severeness/M
+severity/M
+sew/ASGD
+sewage/M
+sewer/MS
+sewerage/M
+sewing/M
+sewn/A
+sex/GMDS
+sexagenarian/SM
+sexily
+sexiness/M
+sexism/M
+sexist/MS
+sexless
+sexologist/SM
+sexology/M
+sexpot/MS
+sextant/SM
+sextet/MS
+sexting
+sexton/MS
+sextuplet/SM
+sexual/Y
+sexuality/M
+sexy/PTR
+sf
+sh
+shabbily
+shabbiness/M
+shabby/PTR
+shack/MDSG
+shackle's
+shackle/UGDS
+shad/GMDSJ
+shade/MS
+shadily
+shadiness/M
+shading/M
+shadow/SGMD
+shadowbox/GDS
+shadowy/RT
+shady/RPT
+shaft/MDSG
+shag/MS
+shagged
+shagginess/M
+shagging
+shaggy/TPR
+shah/M
+shahs
+shake/MZGRS
+shakedown/SM
+shaken/U
+shakeout/MS
+shaker/M
+shakeup/MS
+shakily
+shakiness/M
+shaky/RPT
+shale/M
+shall
+shallot/MS
+shallow/TPMRYS
+shallowness/M
+shalom
+shalt
+sham/GMDS
+shaman/SM
+shamanic
+shamanism
+shamanistic
+shamble/MGDS
+shambles/M
+shambolic
+shame/MS
+shamefaced/Y
+shameful/PY
+shamefulness/M
+shameless/YP
+shamelessness/M
+shammed
+shamming
+shampoo/ZGMDRS
+shampooer/M
+shamrock/MS
+shan't
+shandy/S
+shanghai/DSG
+shank/MS
+shantung/M
+shanty/SM
+shantytown/SM
+shape's
+shape/AGDS
+shaped/U
+shapeless/YP
+shapelessness/M
+shapeliness/M
+shapely/PTR
+shard/MS
+share/MZGDRSB
+shareable
+sharecrop/S
+sharecropped
+sharecropper/MS
+sharecropping
+shareholder/SM
+shareholding/S
+sharer/M
+shareware/M
+sharia/M
+shariah
+shark/MDSG
+sharkskin/M
+sharp/MDNRYSPXZTG
+sharpen/ADGS
+sharpener/MS
+sharper/M
+sharpie/M
+sharpish
+sharpness/M
+sharpshooter/SM
+sharpshooting/M
+sharpy/SM
+shat
+shatter/GMDS
+shatterproof
+shave/MZGDRSJ
+shaven/U
+shaver/M
+shaving/M
+shawl/MS
+shay/MS
+she'd
+she'll
+she/DSM
+sheaf/M
+shear/MDRSZG
+shearer/M
+sheath/JM
+sheathe/UGDS
+sheathing/M
+sheaths
+sheave/DSMG
+shebang/MS
+shebeen/S
+shed/MS
+shedding
+sheen/M
+sheeny/TR
+sheep/M
+sheepdog/MS
+sheepfold/SM
+sheepherder/MS
+sheepish/YP
+sheepishness/M
+sheepskin/MS
+sheer/MDRSPTG
+sheerness/M
+sheet/MSG
+sheeting/M
+sheetlike
+sheik/MS
+sheikdom/MS
+sheikh/M
+sheikhdom/MS
+sheikhs
+sheila/S
+shekel/SM
+shelf/M
+shell/MDRSG
+shellac/MS
+shellacked
+shellacking/MS
+shellfire/M
+shellfish/MS
+shelter/GMDS
+shelve/GDS
+shelving/M
+shenanigan/SM
+shepherd/SMDG
+shepherdess/MS
+sherbet/SM
+sherd/MS
+sheriff/SM
+sherry/SM
+shew/GDS
+shewn
+shh
+shiatsu/M
+shibboleth/M
+shibboleths
+shield/MDGS
+shift/GMDS
+shiftily
+shiftiness/M
+shiftless/PY
+shiftlessness/M
+shifty/RPT
+shiitake/SM
+shill/GMDSJ
+shillelagh/M
+shillelaghs
+shilling/M
+shim/MS
+shimmed
+shimmer/SMDG
+shimmery
+shimming
+shimmy/DSMG
+shin/ZGMDRS
+shinbone/SM
+shindig/SM
+shine/MS
+shiner/M
+shingle/DSMG
+shinguard/M
+shininess/M
+shinned
+shinning
+shinny/DSG
+shinsplints/M
+shiny/TRP
+ship's
+ship/ALS
+shipboard/MS
+shipbuilder/SM
+shipbuilding/M
+shipload/SM
+shipmate/SM
+shipment/AM
+shipments
+shipowner/MS
+shipped/A
+shipper/SM
+shipping/M
+shipshape
+shipwreck/GMDS
+shipwright/MS
+shipyard/SM
+shire/MS
+shirk/ZGDRS
+shirker/M
+shirr/GMDSJ
+shirring/M
+shirt/GMDS
+shirtfront/SM
+shirting/M
+shirtless
+shirtsleeve/SM
+shirttail/SM
+shirtwaist/MS
+shirty
+shit/SM!
+shitfaced/!
+shithead/S!
+shitload/!
+shitted/!
+shitting/!
+shitty/RT!
+shiv/ZMRS
+shiver/MDG
+shivery
+shoal/GMDS
+shoat/MS
+shock/ZGMDRS
+shocker/M
+shocking/Y
+shockproof
+shod/U
+shoddily
+shoddiness/M
+shoddy/PRMT
+shoe/MS
+shoehorn/GMDS
+shoeing
+shoelace/MS
+shoemaker/SM
+shoeshine/SM
+shoestring/SM
+shoetree/MS
+shogun/MS
+shogunate/M
+shone
+shoo/GDS
+shook
+shoot/ZGMRSJ
+shooter/M
+shooting/M
+shootout/MS
+shop/MS
+shopaholic/MS
+shopfitter/S
+shopfitting
+shopfront/S
+shopkeeper/MS
+shoplift/DRZGS
+shoplifter/M
+shoplifting/M
+shoppe/MZGDRS
+shopper/M
+shopping/M
+shoptalk/M
+shopworn
+shore/MGDS
+shorebird/SM
+shoreline/MS
+shoring/M
+short/XTGMDNRYSP
+shortage/MS
+shortbread/M
+shortcake/MS
+shortchange/DSG
+shortcoming/MS
+shortcrust
+shortcut/MS
+shorten/JGD
+shortening/M
+shortfall/MS
+shorthand/MD
+shorthorn/MS
+shortie/M
+shortish
+shortlist/DGS
+shortness/M
+shortsighted/PY
+shortsightedness/M
+shortstop/MS
+shortwave/MS
+shorty/SM
+shot/MS
+shotgun/SM
+shotgunned
+shotgunning
+should
+should've
+shoulder/MDGS
+shouldn't
+shout/ZGMDRS
+shouter/M
+shove/MGDS
+shovel/MDSG
+shovelful/SM
+show/JZGMDRS
+showbiz/M
+showboat/MDGS
+showcase/MGDS
+showdown/MS
+shower/MDG
+showerproof
+showery
+showgirl/MS
+showground/S
+showily
+showiness/M
+showing/M
+showjumping
+showman/M
+showmanship/M
+showmen
+shown
+showoff/SM
+showpiece/SM
+showplace/SM
+showroom/MS
+showstopper/MS
+showstopping
+showtime
+showy/TRP
+shpt
+shrank
+shrapnel/M
+shred/MS
+shredded
+shredder/MS
+shredding
+shrew/MS
+shrewd/RYPT
+shrewdness/M
+shrewish
+shriek/MDSG
+shrift/M
+shrike/MS
+shrill/DRSPTG
+shrillness/M
+shrilly
+shrimp/MDRSZG
+shrine/MS
+shrink/MSBG
+shrinkage/M
+shrive/GDS
+shrivel/SGD
+shriven
+shroud/GMDS
+shrub/MS
+shrubbery/SM
+shrubby/RT
+shrug/MS
+shrugged
+shrugging
+shrunk/N
+shtick/MS
+shuck/GMDS
+shucks/S
+shudder/MDSG
+shuffle/AMGDS
+shuffleboard/SM
+shuffler/SM
+shun/S
+shunned
+shunning
+shunt/MSDG
+shush/DSG
+shut/S
+shutdown/SM
+shuteye/M
+shutoff/SM
+shutout/SM
+shutter/SMDG
+shutterbug/MS
+shutting
+shuttle/DSMG
+shuttlecock/GMDS
+shy/TGDRSMY
+shyer
+shyest
+shyness/M
+shyster/SM
+sibilant/SM
+sibling/SM
+sibyl/MS
+sibylline
+sic/S
+sicced
+siccing
+sick/PXTGDNRYS
+sickbay/S
+sickbed/SM
+sicken/DG
+sickening/Y
+sickie/MS
+sickish
+sickle/MS
+sickly/RT
+sickness/MS
+sicko/MS
+sickout/SM
+sickroom/MS
+side's
+side/AGDS
+sidearm/SM
+sidebar/SM
+sideboard/SM
+sideburns/M
+sidecar/SM
+sidekick/SM
+sidelight/MS
+sideline/DSMG
+sidelong
+sideman/M
+sidemen
+sidepiece/MS
+sidereal
+sidesaddle/MS
+sideshow/MS
+sidesplitting
+sidestep/MS
+sidestepped
+sidestepping
+sidestroke/DSMG
+sideswipe/DSMG
+sidetrack/SMDG
+sidewalk/MS
+sidewall/MS
+sideways
+sidewinder/SM
+siding/MS
+sidle/MGDS
+siege/MS
+sienna/M
+sierra/MS
+siesta/MS
+sieve/MGDS
+sift/ZGDRS
+sifted/U
+sifter/M
+sigh/GMD
+sighs
+sight/GMDYSJ
+sighting/M
+sightless
+sightly/UTR
+sightread
+sightseeing/M
+sightseer/MS
+sigma/MS
+sign's/C
+sign/AFCGDS
+signage/M
+signal/MDRYSZG
+signaler/M
+signalization/M
+signalize/GDS
+signalman/M
+signalmen
+signatory/SM
+signature/MS
+signboard/MS
+signed/U
+signer/CMS
+signet/MS
+significance/IM
+significant/IY
+signification/M
+signify/XDSNG
+signing's/C
+signings
+signor/FMS
+signora/SM
+signore
+signori
+signorina/MS
+signorine
+signpost/GSMD
+silage/M
+silence/DRSMZG
+silencer/M
+silent/MRYST
+silhouette/DSMG
+silica/M
+silicate/MS
+siliceous
+silicon/SM
+silicone/M
+silicosis/M
+silk/MNS
+silkily
+silkiness/M
+silkscreen/SM
+silkworm/MS
+silky/TRP
+sill/MS
+silliness/M
+silly/TRSMP
+silo/MS
+silt/GMDS
+silty/TR
+silvan
+silver/GMDS
+silverfish/MS
+silversmith/M
+silversmiths
+silverware/M
+silvery
+sim/SM
+simian/MS
+similar/Y
+similarity/ESM
+simile/MS
+similitude/EM
+simmer/GMDS
+simonize/DSG
+simony/M
+simpatico
+simper/GMDS
+simpering/Y
+simple/TRP
+simpleminded
+simpleness/M
+simpleton/SM
+simplex
+simplicity/M
+simplification/M
+simplify/DSXNG
+simplistic
+simplistically
+simply
+simulacra
+simulacrum/S
+simulate/EDSGN
+simulation/EM
+simulations
+simulator/EMS
+simulcast/GMDS
+simultaneity/M
+simultaneous/Y
+sin/ASM
+since
+sincere/IYT
+sincerer
+sincerity/IM
+sine/MS
+sinecure/MS
+sinew/MS
+sinewy
+sinful/PY
+sinfulness/M
+sing/BZGMDRYS
+singalong/S
+singe/MS
+singeing
+singer/M
+singing/M
+single/PMGDS
+singleness/M
+singles/M
+singlet/S
+singleton/SM
+singletree/SM
+singsong/SMDG
+singular/SMY
+singularity/SM
+sinister
+sink/BZGMRS
+sinkable/U
+sinker/M
+sinkhole/SM
+sinless
+sinned
+sinner/MS
+sinning
+sinology
+sinuosity/M
+sinuous/Y
+sinus/MS
+sinusitis/M
+sinusoidal
+sip/SM
+siphon/GMDS
+sipped
+sipper/SM
+sipping
+sir/SXMN
+sire/CMGDS
+siree/M
+siren/M
+sirloin/SM
+sirocco/SM
+sirrah
+sirree/M
+sis/MS
+sisal/M
+sissified
+sissy/RSMT
+sister/ASM
+sisterhood/MS
+sisterliness/M
+sisterly/P
+sit/S
+sitar/SM
+sitarist/MS
+sitcom/SM
+site/MGDS
+sitemap/SM
+sitter/SM
+sitting/SM
+situ
+situate/DSXGN
+situation/M
+situational
+six/MSH
+sixfold
+sixpence/MS
+sixshooter/M
+sixteen/SMH
+sixteenth/M
+sixteenths
+sixth/M
+sixths
+sixtieth/M
+sixtieths
+sixty/SMH
+sizable
+size's
+size/AGDS
+sizeable
+sizer
+sizing/M
+sizzle/DRSMZG
+ska/M
+skate/MZGDRS
+skateboard/MDRSZG
+skateboarder/M
+skateboarding/M
+skater/M
+skating/M
+skedaddle/MGDS
+skeet/ZMR
+skein/MS
+skeletal
+skeleton/SM
+skeptic/SM
+skeptical/Y
+skepticism/M
+sketch/MDRSZG
+sketchbook/S
+sketcher/M
+sketchily
+sketchiness/M
+sketchpad/S
+sketchy/RTP
+skew/MDRZGS
+skewbald/S
+skewer/MDG
+ski/SZGMDR
+skibob/S
+skid/MS
+skidded
+skidding
+skidpan/S
+skier/M
+skiff/SM
+skiffle
+skiing/M
+skill's
+skill/CSD
+skilled/U
+skillet/SM
+skillful/UY
+skillfulness/M
+skim/MS
+skimmed
+skimmer/SM
+skimming
+skimp/SDG
+skimpily
+skimpiness/M
+skimpy/RTP
+skin/MS
+skincare/M
+skinflick/MS
+skinflint/MS
+skinful
+skinhead/MS
+skinless
+skinned
+skinniness/M
+skinning
+skinny/RMTP
+skint
+skintight
+skip/MS
+skipped
+skipper/SMDG
+skipping
+skirmish/ZGMDRS
+skirt/SMDG
+skit/MS
+skitter/GSD
+skittish/YP
+skittishness/M
+skittle/S
+skive/DRSZG
+skivvy/DSMG
+skoal/SM
+skua/S
+skulduggery/M
+skulk/SDRZG
+skulker/M
+skull/SM
+skullcap/MS
+skullduggery/M
+skunk/SMDG
+sky/GSM
+skycap/SM
+skydive/DRSZG
+skydiver/M
+skydiving/M
+skyjack/JZGSDR
+skyjacker/M
+skyjacking/M
+skylark/SGMD
+skylight/MS
+skyline/SM
+skyrocket/GSMD
+skyscraper/SM
+skyward/S
+skywriter/SM
+skywriting/M
+slab/MS
+slabbed
+slabbing
+slack/PXZTGMDNRYS
+slacken/DG
+slacker/M
+slackness/M
+slacks/M
+slag/MS
+slagged
+slagging
+slagheap/S
+slain
+slake/GDS
+slalom/MSDG
+slam/MS
+slammed
+slammer/SM
+slamming
+slander/MZGDRS
+slanderer/M
+slanderous
+slang/M
+slangy/RT
+slant/MSDG
+slanting/Y
+slantwise
+slap/MS
+slapdash
+slaphappy
+slapped
+slapper/S
+slapping
+slapstick/M
+slash/MDRSZG
+slasher/M
+slat/MDGS
+slate/SM
+slather/SDG
+slatted
+slattern/SMY
+slaughter/MDRZGS
+slaughterer/M
+slaughterhouse/MS
+slave/DRSMZG
+slaveholder/MS
+slaver/MDG
+slavery/M
+slavish/PY
+slavishness/M
+slaw/M
+slay/DRZGJS
+slayer/M
+slaying/M
+sleaze/SM
+sleazebag/S
+sleazeball/S
+sleazily
+sleaziness/M
+sleazy/PRT
+sled/MS
+sledded
+sledder/SM
+sledding
+sledge/DSMG
+sledgehammer/GSMD
+sleek/SDRYTGP
+sleekness/M
+sleep/SMRZG
+sleeper/M
+sleepily
+sleepiness/M
+sleepless/PY
+sleeplessness/M
+sleepover/SM
+sleepwalk/ZGSDR
+sleepwalker/M
+sleepwalking/M
+sleepwear/M
+sleepy/RPT
+sleepyhead/MS
+sleet/SMDG
+sleety
+sleeve/DSM
+sleeveless
+sleigh/MDG
+sleighs
+sleight/SM
+slender/PRT
+slenderize/DSG
+slenderness/M
+slept
+sleuth/MG
+sleuths
+slew/MDGS
+slice/DRSMZG
+slicer/M
+slick/SMDRYZTGP
+slicker/M
+slickness/M
+slid
+slide/RSMZG
+slider/M
+slideshow/MS
+slight/SMDRYTGP
+slightness/M
+slim/PS
+slime/M
+sliminess/M
+slimline
+slimmed
+slimmer/S
+slimmest
+slimming/M
+slimness/M
+slimy/RTP
+sling/SMG
+slingback/S
+slingshot/SM
+slink/SG
+slinky/RT
+slip/MS
+slipcase/MS
+slipcover/MS
+slipknot/MS
+slippage/MS
+slipped
+slipper/SM
+slipperiness/M
+slippery/PRT
+slipping
+slippy
+slipshod
+slipstream/SM
+slipway/SM
+slit/MS
+slither/SGMD
+slithery
+slitter
+slitting
+sliver/GSMD
+slob/MS
+slobbed
+slobber/MDSG
+slobbery
+slobbing
+sloe/MS
+slog/MS
+slogan/SM
+sloganeering
+slogged
+slogging
+sloop/SM
+slop/MDGS
+slope/SM
+slopped
+sloppily
+sloppiness/M
+slopping
+sloppy/PTR
+slops/M
+slosh/DSG
+slot/MS
+sloth/M
+slothful/YP
+slothfulness/M
+sloths
+slotted
+slotting
+slouch/ZGMDRS
+sloucher/M
+slouchy/TR
+slough/GMD
+sloughs
+sloven/SMY
+slovenliness/M
+slovenly/PTR
+slow/DRYTGSP
+slowcoach/S
+slowdown/SM
+slowness/M
+slowpoke/SM
+sludge/M
+sludgy/RT
+slue/MGDS
+slug/MS
+sluggard/MS
+slugged
+slugger/SM
+slugging
+sluggish/PY
+sluggishness/M
+sluice/DSMG
+slum/MS
+slumber/GSMD
+slumberous
+slumbrous
+slumdog/SM
+slumlord/MS
+slummed
+slummer
+slumming
+slummy/RT
+slump/SMDG
+slung
+slunk
+slur/MS
+slurp/SMDG
+slurred
+slurring
+slurry/M
+slush/M
+slushiness/M
+slushy/RPT
+slut/MS
+sluttish
+slutty/RT
+sly/TRY
+slyer
+slyest
+slyness/M
+smack/SMDRZG
+smacker/M
+small/SMRTP
+smallholder/S
+smallholding/S
+smallish
+smallness/M
+smallpox/M
+smarmy/RT
+smart/SMDNRYXTGP
+smarten/DG
+smartness/M
+smartphone/SM
+smarts/M
+smartwatch/MS
+smarty/SM
+smartypants/M
+smash/MDRSZG
+smasher/M
+smashup/SM
+smattering/MS
+smear/SMDG
+smeary/RT
+smell/SMDG
+smelliness/M
+smelly/RPT
+smelt/SMDRZG
+smelter/M
+smidgen/MS
+smilax/M
+smile/DSMG
+smiley/SM
+smiling/Y
+smirch/GMDS
+smirk/SMDG
+smite/SG
+smith/M
+smithereens/M
+smiths
+smithy/SM
+smitten
+smock/SMDG
+smocking/M
+smog/MS
+smoggy/RT
+smoke/DRSMZG
+smokehouse/MS
+smokeless
+smoker/M
+smokescreen/SM
+smokestack/SM
+smokey
+smokiness/M
+smoking/M
+smoky/RTP
+smolder/SGMD
+smooch/MDSG
+smoochy
+smooth/PDRYTG
+smoothie/M
+smoothness/M
+smooths
+smoothy/SM
+smorgasbord/SM
+smote
+smother/GSMD
+smoulder/GMDS
+smudge/DSMG
+smudgy/TR
+smug/YP
+smugger
+smuggest
+smuggle/ZGDRS
+smuggler/M
+smuggling/M
+smugness/M
+smurf/S
+smut/MS
+smuttiness/M
+smutty/TRP
+sm旦rg奪sbord/MS
+snack/SMDG
+snaffle/DSMG
+snafu/SM
+snag/MS
+snagged
+snagging
+snail/SMDG
+snake/DSMG
+snakebite/MS
+snakelike
+snakeskin
+snaky/RT
+snap's
+snap/US
+snapdragon/SM
+snapped/U
+snapper/MS
+snappily
+snappiness/M
+snapping/U
+snappish/YP
+snappishness/M
+snappy/TRP
+snapshot/SM
+snare/DSMG
+snarf/SDG
+snark/S
+snarky/TR
+snarl's
+snarl/USDG
+snarling/Y
+snarly/TR
+snatch/ZGMDRS
+snatcher/M
+snazzily
+snazzy/TR
+sneak/SMDRZG
+sneaker/M
+sneakily
+sneakiness/M
+sneaking/Y
+sneaky/TRP
+sneer/SJMDG
+sneering/Y
+sneeze/DSMG
+snick/SDRZG
+snicker/MDG
+snide/RYT
+sniff/SMDRZG
+sniffer/M
+sniffle/DSMG
+sniffy/RT
+snifter/SM
+snigger/SMDG
+snip/MDRZGS
+snipe/SM
+sniper/M
+snipped
+snippet/SM
+snipping
+snippy/RT
+snips/M
+snit/MS
+snitch/MDSG
+snivel/SMDRZG
+sniveler/M
+snob/MS
+snobbery/M
+snobbish/PY
+snobbishness/M
+snobby/RT
+snog/S
+snogged
+snogging
+snood/SM
+snooker/MDSG
+snoop/SMDRZG
+snooper/M
+snoopy/TR
+snoot/SM
+snootily
+snootiness/M
+snooty/PTR
+snooze/DSMG
+snore/DRSMZG
+snorer/M
+snorkel/ZGMDRS
+snorkeler/M
+snorkeling/M
+snort/SMDRZG
+snorter/M
+snot/MS
+snottily
+snottiness/M
+snotty/TPR
+snout/SM
+snow/MDGS
+snowball/GSMD
+snowbank/SM
+snowbird/SM
+snowblower/MS
+snowboard/ZGMDRS
+snowboarder/M
+snowboarding/M
+snowbound
+snowdrift/SM
+snowdrop/SM
+snowfall/SM
+snowfield/SM
+snowflake/SM
+snowiness/M
+snowline
+snowman/M
+snowmen
+snowmobile/DSMG
+snowplow/SGMD
+snowshed
+snowshoe/SM
+snowshoeing
+snowstorm/SM
+snowsuit/SM
+snowy/PRT
+snub/MS
+snubbed
+snubbing
+snuff/SMDRYZG
+snuffbox/MS
+snuffer/M
+snuffle/MGDS
+snug/MYSP
+snugged
+snugger
+snuggest
+snugging
+snuggle/MGDS
+snugness/M
+so
+soak/MDGSJ
+soaking/M
+soap/MDGS
+soapbox/MS
+soapiness/M
+soapstone/M
+soapsuds/M
+soapy/RPT
+soar/MDGS
+sob/SM
+sobbed
+sobbing/Y
+sober/SDRYPTG
+soberness/M
+sobriety/IM
+sobriquet/SM
+soc
+soccer/M
+sociability/M
+sociable/SM
+sociably
+social/SMY
+socialism/M
+socialist/SM
+socialistic
+socialite/SM
+socialization/M
+socialize/DSG
+societal
+society/SM
+socioeconomic
+socioeconomically
+sociological/Y
+sociologist/SM
+sociology/M
+sociopath/M
+sociopaths
+sociopolitical
+sock/MDGS
+socket/SM
+sockeye/SM
+sod/SM
+soda/MS
+sodded
+sodden/Y
+sodding
+sodium/M
+sodomite/MS
+sodomize/GDS
+sodomy/M
+soever
+sofa/MS
+soft/NRYXTP
+softback
+softball/MS
+softbound
+softcover
+soften/DRZG
+softener/M
+softhearted
+softie/M
+softness/M
+software/M
+softwood/SM
+softy/SM
+soggily
+sogginess/M
+soggy/RTP
+soigne
+soignee
+soign辿
+soign辿e
+soil/MDGS
+soiled/U
+soiree/SM
+soir辿e/SM
+sojourn/ZGMDRS
+sojourner/M
+sol/SM
+solace/DSMG
+solar
+solaria
+solarium/M
+sold
+solder/ZGSMDR
+solderer/M
+soldier/MDYSG
+soldiery/M
+sole/FSDGM
+solecism/SM
+solely
+solemn/PTRY
+solemness/M
+solemnify/DSG
+solemnity/SM
+solemnization/M
+solemnize/DSG
+solemnness/M
+solenoid/MS
+solicit/GDS
+solicitation/SM
+solicited/U
+solicitor/SM
+solicitous/PY
+solicitousness/M
+solicitude/M
+solid/PSMRYT
+solidarity/M
+solidi
+solidification/M
+solidify/DSNG
+solidity/M
+solidness/M
+solidus/M
+soliloquies
+soliloquize/DSG
+soliloquy/M
+solipsism/M
+solipsistic
+solitaire/MS
+solitariness/M
+solitary/SMP
+solitude/M
+solo/MDGS
+soloist/MS
+solstice/MS
+solubility/IM
+soluble/MS
+solute's
+solute/AXN
+solutes
+solution's/AE
+solvable/IU
+solve/EADSG
+solved/U
+solvency/IM
+solvent/IMS
+solver/SM
+somatic
+somatosensory
+somber/PY
+somberness/M
+sombre/PY
+sombreness/M
+sombrero/MS
+some
+somebody/SM
+someday
+somehow
+someone/MS
+someplace
+somersault/MDGS
+somerset/SM
+somersetted
+somersetting
+something/SM
+sometime/S
+someway/S
+somewhat/S
+somewhere
+somnambulism/M
+somnambulist/SM
+somnolence/M
+somnolent
+son/SM
+sonar/SM
+sonata/SM
+sonatina/SM
+song/MS
+songbird/SM
+songbook/SM
+songfest/SM
+songster/MS
+songstress/MS
+songwriter/SM
+songwriting
+sonic
+sonnet/SM
+sonny/SM
+sonogram/SM
+sonority/M
+sonorous/YP
+sonorousness/M
+sonsofbitches
+soon/RT
+soot/M
+sooth/MDRSZG
+soothe
+soother/M
+soothing/Y
+soothsayer/MS
+soothsaying/M
+sooty/RT
+sop/SM
+soph
+sophism/M
+sophist/MS
+sophistic
+sophistical
+sophisticate/DSMGN
+sophisticated/U
+sophistication/M
+sophistry/SM
+sophomore/MS
+sophomoric
+soporific/MS
+soporifically
+sopped
+sopping
+soppy/RT
+soprano/MS
+sorbet/SM
+sorcerer/MS
+sorceress/MS
+sorcery/M
+sordid/PY
+sordidness/M
+sore/MYTRSP
+sorehead/MS
+soreness/M
+sorghum/M
+sorority/SM
+sorrel/SM
+sorrily
+sorriness/M
+sorrow/SMDG
+sorrowful/YP
+sorrowfulness/M
+sorry/RTP
+sort/FASGDM
+sorta
+sorted/U
+sorter/SM
+sortie/DSM
+sortieing
+sot/SM
+sottish
+sou'wester
+sou/SMH
+souffle/SM
+souffl辿/SM
+sough/MDG
+soughs
+sought/U
+souk/S
+soul/MS
+soulful/YP
+soulfulness/M
+soulless/YP
+soulmate/SM
+sound/JPSMDRYZTG
+soundalike/S
+soundbar/S
+soundbite/S
+soundboard/MS
+soundcheck/S
+sounder/M
+sounding/M
+soundless/Y
+soundness/UM
+soundproof/GDS
+soundproofing/M
+soundscape/S
+soundtrack/SM
+soup/MDGS
+soupcon/MS
+soupy/RT
+soup巽on/MS
+sour/MDRYTGSP
+source/ADSMG
+sourdough/M
+sourdoughs
+sourish
+sourness/M
+sourpuss/MS
+sousaphone/MS
+souse/DSMG
+south/M
+southbound
+southeast/ZMR
+southeaster/MY
+southeastern
+southeastward/S
+southerly/SM
+southern/SZMR
+southerner/M
+southernmost
+southpaw/SM
+southward/MS
+southwest/ZMR
+southwester/MY
+southwestern
+southwestward/S
+souvenir/SM
+sovereign/SM
+sovereignty/M
+soviet/SM
+sow's
+sow/ASGD
+sower/SM
+sown/A
+soy/M
+soybean/MS
+sozzled
+spa/SM
+space/DRSMZG
+spacecraft/MS
+spaceflight/MS
+spaceman/M
+spacemen
+spaceport/SM
+spacer/M
+spaceship/SM
+spacesuit/SM
+spacetime
+spacewalk/SGMD
+spacewoman/M
+spacewomen
+spacey
+spacial
+spacier
+spaciest
+spaciness/M
+spacing/M
+spacious/YP
+spaciousness/M
+spade/DSMG
+spadeful/MS
+spadework/M
+spadices
+spadix/M
+spaghetti/M
+spake
+spam/MS
+spammed
+spammer/SM
+spamming
+span/MS
+spandex/M
+spangle/DSMG
+spangly
+spaniel/SM
+spank/SMDGJ
+spanking/M
+spanned
+spanner/SM
+spanning
+spar/MS
+spare/DRSMYTGP
+spareness/M
+spareribs/M
+sparing/UY
+spark/SMDYG
+sparkle/DRSMZG
+sparkler/M
+sparky/RT
+sparred
+sparring
+sparrow/SM
+sparrowhawk/S
+sparse/RYTP
+sparseness/M
+sparsity/M
+spartan
+spasm/SM
+spasmodic
+spasmodically
+spastic/SM
+spat/MS
+spate/SM
+spathe/SM
+spatial/Y
+spatted
+spatter/SGMD
+spatting
+spatula/SM
+spavin/MD
+spawn/SMDG
+spay/DGS
+speak/SRZGJ
+speakeasy/SM
+speaker/M
+speakerphone/S
+spear/SMDG
+spearfish/GMDS
+speargun
+spearhead/GMDS
+spearmint/M
+spec/MS
+special/SMY
+specialism/S
+specialist/MS
+specialization/MS
+specialize/GDS
+specialty/SM
+specie/SM
+species/M
+specif
+specifiable
+specific/MS
+specifically
+specification/M
+specificity/M
+specified/U
+specify/XNZDRSG
+specimen/SM
+specious/YP
+speciousness/M
+speck/SMDG
+speckle/MGDS
+specs/M
+spectacle/SM
+spectacles/M
+spectacular/MYS
+spectate/DSG
+spectator/SM
+specter/AMS
+spectra
+spectral
+spectrometer/MS
+spectroscope/MS
+spectroscopic
+spectroscopy/M
+spectrum/M
+speculate/DSXGNV
+speculation/M
+speculative/Y
+speculator/MS
+sped
+speech/MS
+speechify/DSG
+speechless/YP
+speechlessness/M
+speechwriter/S
+speed/SMRZG
+speedboat/SM
+speeder/M
+speedily
+speediness/M
+speeding/M
+speedometer/MS
+speedster/SM
+speedup/MS
+speedway/SM
+speedwell/M
+speedy/TPR
+speleological
+speleologist/MS
+speleology/M
+spell/JSMDRZG
+spellbind/ZGRS
+spellbinder/M
+spellbound
+spellcheck/MDRZGS
+spellchecker/M
+spelldown/SM
+speller/M
+spelling/M
+spelunker/MS
+spelunking/M
+spend/BSRZG
+spender/M
+spending/M
+spendthrift/MS
+spent/U
+sperm/SM
+spermatozoa
+spermatozoon/M
+spermicidal
+spermicide/MS
+spew/MDRZGS
+spewer/M
+sphagnum/MS
+sphere/SM
+spherical/Y
+spheroid/SM
+spheroidal
+sphincter/MS
+sphinx/MS
+spic/S
+spice/DSMG
+spicily
+spiciness/M
+spicule/MS
+spicy/PRT
+spider/SM
+spiderweb/MS
+spidery
+spiel/SMDG
+spiff/SDG
+spiffy/TR
+spigot/SM
+spike/DSMG
+spikiness/M
+spiky/RPT
+spill/SMDG
+spillage/MS
+spillover/SM
+spillway/MS
+spin/MS
+spinach/M
+spinal/SMY
+spindle/MGDS
+spindly/TR
+spine/SM
+spineless/YP
+spinet/SM
+spinless
+spinnaker/SM
+spinner/MS
+spinneret/SM
+spinney/S
+spinning/M
+spinoff/MS
+spinster/SM
+spinsterhood/M
+spinsterish
+spiny/RT
+spiracle/SM
+spiraea/MS
+spiral/SGMDY
+spire's
+spire/IFAS
+spirea/SM
+spirit's
+spirit/ISGD
+spirited/Y
+spiritless
+spiritual/MYS
+spiritualism/M
+spiritualist/MS
+spiritualistic
+spirituality/M
+spirituous
+spirochete/SM
+spiry
+spit/MDGS
+spitball/SM
+spite/ASM
+spiteful/PY
+spitefuller
+spitefullest
+spitefulness/M
+spitfire/SM
+spitted
+spitting
+spittle/M
+spittoon/MS
+spiv/S
+splanchnic
+splash/GMDS
+splashdown/MS
+splashily
+splashiness/M
+splashy/RTP
+splat/SM
+splatted
+splatter/GSMD
+splatting
+splay/SMDG
+splayfeet
+splayfoot/MD
+spleen/SM
+splendid/RYT
+splendor/MS
+splendorous
+splenectomy
+splenetic
+splice/DRSMZG
+splicer/M
+spliff/S
+spline/S
+splint/SZGMDR
+splinter/MDG
+splintery
+split/SM
+splitting/MS
+splodge/S
+splosh/DSG
+splotch/MDSG
+splotchy/TR
+splurge/DSMG
+splutter/GMDS
+spoil's
+spoil/CSDRZG
+spoilage/M
+spoiled/U
+spoiler/CM
+spoilsport/MS
+spoke/SM
+spoken/U
+spokesman/M
+spokesmen
+spokespeople
+spokesperson/MS
+spokeswoman/M
+spokeswomen
+spoliation/CM
+sponge/DRSMZG
+sponger/M
+sponginess/M
+spongy/RPT
+sponsor/MDGS
+sponsorship/M
+spontaneity/M
+spontaneous/Y
+spoof/SMDG
+spook/SMDG
+spookiness/M
+spooky/RPT
+spool/SMDG
+spoon/SMDG
+spoonbill/MS
+spoonerism/MS
+spoonful/SM
+spoor/SMDG
+sporadic
+sporadically
+spore/DSMG
+sporran/S
+sport/SMDGV
+sportiness/M
+sporting/Y
+sportive/Y
+sportscast/MRZGS
+sportscaster/M
+sportsman/M
+sportsmanlike/U
+sportsmanship/M
+sportsmen
+sportspeople
+sportsperson
+sportswear/M
+sportswoman/M
+sportswomen
+sportswriter/SM
+sporty/TPR
+spot/CMS
+spotless/PY
+spotlessness/M
+spotlight/GSMD
+spotlit
+spotted
+spotter/MS
+spottily
+spottiness/M
+spotting
+spotty/TPR
+spousal/MS
+spouse/SM
+spout/SMDG
+sprain/GSMD
+sprang
+sprat/SM
+sprawl/GSMD
+spray's
+spray/ASDG
+sprayer/MS
+spread/ZGBSMR
+spreadeagled
+spreader/M
+spreadsheet/MS
+spree/DSM
+spreeing
+sprig/SM
+sprigged
+sprightliness/M
+sprightly/RTP
+spring/GSM
+springboard/MS
+springbok/MS
+springily
+springiness/M
+springlike
+springtime/M
+springy/RPT
+sprinkle/DRSJMZG
+sprinkler/M
+sprinkling/M
+sprint/ZGSMDR
+sprinter/M
+sprite/SM
+spritz/ZGMDRS
+spritzer/M
+sprocket/MS
+sprog/S
+sprout/GSMD
+spruce/DRSPMYTG
+spruceness/M
+sprung
+spry/RYT
+spryness/M
+spud/MS
+spume/DSMG
+spumoni/M
+spumy
+spun
+spunk/SM
+spunky/TR
+spur/MS
+spurge/M
+spurious/PY
+spuriousness/M
+spurn/SDG
+spurred
+spurring
+spurt/SMDG
+sputa
+sputnik/MS
+sputter/MDGS
+sputum/M
+spy/GDSM
+spyglass/MS
+spymaster/S
+spyware/M
+sq
+sqq
+squab/SM
+squabble/MZGDRS
+squabbler/M
+squad/SM
+squadron/MS
+squalid/PTRY
+squalidness/M
+squall/SGMD
+squally
+squalor/M
+squamous
+squander/GDS
+square/PDRSMYTG
+squareness/M
+squarish
+squash/GMDS
+squashy/TR
+squat/SMP
+squatness/M
+squatted
+squatter/MS
+squattest
+squatting
+squaw/SM
+squawk/SZGMDR
+squawker/M
+squeak/SZGMDR
+squeaker/M
+squeakily
+squeakiness/M
+squeaky/TRP
+squeal/SZGMDR
+squealer/M
+squeamish/PY
+squeamishness/M
+squeegee/MDS
+squeegeeing
+squeeze/BMZGDRS
+squeezebox/S
+squeezer/M
+squelch/GMDS
+squelchy
+squib/SM
+squid/SM
+squidgy
+squiffy
+squiggle/DSMG
+squiggly
+squint/STGMDR
+squire/DSMG
+squirm/SGMD
+squirmy/RT
+squirrel/SGMD
+squirt/SGMD
+squish/GMDS
+squishy/RT
+sriracha
+ssh
+st
+stab/MYS
+stabbed
+stabber/MS
+stabbing/MS
+stability/IM
+stabilization/CM
+stabilize/CDSG
+stabilizer/MS
+stable/DRSMTG
+stableman/M
+stablemate/S
+stablemen
+stably/U
+staccato/MS
+stack/SMDG
+stadium/MS
+staff's
+staff/ASDG
+staffer/MS
+staffing/M
+stag/MDGSJ
+stage/SM
+stagecoach/MS
+stagecraft/M
+stagehand/MS
+stagestruck
+stagey
+stagflation/M
+stagger/MDGS
+staggering/Y
+staging/M
+stagnancy/M
+stagnant/Y
+stagnate/DSGN
+stagnation/M
+stagy/RT
+staid/PRYT
+staidness/M
+stain/SMDG
+stained/U
+stainless/M
+stair/SM
+staircase/MS
+stairway/MS
+stairwell/SM
+stake/DSMG
+stakeholder/MS
+stakeout/SM
+stalactite/MS
+stalagmite/MS
+stale/DRSTGP
+stalemate/DSMG
+staleness/M
+stalk/SMDRJZG
+stalker/M
+stalking/M
+stall's
+stall/SDG
+stallholder/S
+stallion/MS
+stalwart/MYS
+stamen/SM
+stamina/M
+stammer/ZGMDRS
+stammerer/M
+stammering/Y
+stamp/SMDRZG
+stampede/MGDS
+stamper/M
+stance/ISM
+stanch/TGDRS
+stanchion/SM
+stand/SMRJZG
+standalone
+standard/MS
+standardization/M
+standardize/DSG
+standby/M
+standbys
+standee/MS
+stander/M
+standing/M
+standoff/MS
+standoffish
+standout/MS
+standpipe/SM
+standpoint/MS
+standstill/MS
+standup/M
+stank
+stanza/SM
+staph/M
+staphylococcal
+staphylococci
+staphylococcus/M
+staple/DRSMZG
+stapler/M
+star/MDRZGS
+starboard/M
+starburst/S
+starch/GMDS
+starchily
+starchiness/M
+starchy/PTR
+stardom/M
+stardust/M
+stare/SM
+starer/M
+starfish/MS
+starfruit
+stargaze/DRSZG
+stargazer/M
+stark/RYPZT
+starkness/M
+starless
+starlet/MS
+starlight/M
+starling/SM
+starlit
+starred
+starring
+starry/TR
+starstruck
+start/ASMDG
+starter/MS
+startle/GDS
+startling/Y
+startup/MS
+starvation/M
+starve/DSJG
+starveling/MS
+stash/MDSG
+stasis
+stat/MS
+state/DRSMYGNLX
+statecraft/M
+stated/U
+statehood/M
+statehouse/MS
+stateless/P
+statelessness/M
+stateliness/M
+stately/PRT
+statement/AMS
+statemented
+statementing
+stateroom/MS
+stateside
+statesman/M
+statesmanlike
+statesmanship/M
+statesmen
+stateswoman/M
+stateswomen
+statewide
+static/SM
+statically
+station/MDRZG
+stationary
+stationer/M
+stationery/M
+stationmaster/S
+statistic/MS
+statistical/Y
+statistician/SM
+statuary/M
+statue/SM
+statuesque
+statuette/MS
+stature/MS
+status/MS
+statute/MS
+statutorily
+statutory
+staunch/PDRSYTG
+staunchness/M
+stave/DSMG
+stay/MDRZGS
+std
+stdio
+stead/SM
+steadfast/YP
+steadfastness/M
+steadily/U
+steadiness/UM
+steady/TGPDRSM
+steak/SM
+steakhouse/SM
+steal/SMHG
+stealth/M
+stealthily
+stealthiness/M
+stealthy/TPR
+steam/SMDRZG
+steamboat/MS
+steamer/M
+steamfitter/SM
+steamfitting/M
+steaminess/M
+steampunk
+steamroll/ZGDRS
+steamroller/MDG
+steamship/MS
+steamy/TPR
+steed/SM
+steel/SMDG
+steeliness/M
+steelmaker/S
+steelworker/SM
+steelworks/M
+steely/PTR
+steelyard/SM
+steep/SMDNRYPXTG
+steepen/GD
+steeple/MS
+steeplechase/MS
+steeplejack/SM
+steepness/M
+steer/SMDBG
+steerage/M
+steering/M
+steersman/M
+steersmen
+stegosauri
+stegosaurus/MS
+stein/SM
+stellar
+stem/MS
+stemless
+stemmed
+stemming
+stemware/M
+stench/MS
+stencil/GMDS
+steno/SM
+stenographer/SM
+stenographic
+stenography/M
+stenosis
+stent/SM
+stentorian
+step/IMS
+stepbrother/SM
+stepchild/M
+stepchildren/M
+stepdad/MS
+stepdaughter/SM
+stepfather/SM
+stepladder/MS
+stepmom/MS
+stepmother/SM
+stepparent/SM
+steppe/DRSMZG
+stepper/M
+steppingstone/SM
+stepsister/MS
+stepson/MS
+stereo/SM
+stereophonic
+stereoscope/MS
+stereoscopic
+stereotype/DSMG
+stereotypical
+sterile
+sterility/M
+sterilization/SM
+sterilize/DRSZG
+sterilizer/M
+sterling/M
+stern/SMRYPT
+sternness/M
+sternum/MS
+steroid/MS
+steroidal
+stertorous
+stet/S
+stethoscope/MS
+stetson/MS
+stetted
+stetting
+stevedore/SM
+stew/MDGS
+steward/GMDS
+stewardess/MS
+stewardship/M
+stick/SMRZG
+sticker/M
+stickily
+stickiness/M
+stickleback/SM
+stickler/MS
+stickpin/MS
+stickup/MS
+sticky/PTRSM
+stiff/SMDNRYPXTG
+stiffen/ZGDR
+stiffener/M
+stiffening/M
+stiffness/M
+stifle/DSJG
+stifling/Y
+stigma/SM
+stigmata
+stigmatic
+stigmatization/M
+stigmatize/GDS
+stile/SM
+stiletto/SM
+still's
+still/ITGSD
+stillbirth/M
+stillbirths
+stillborn
+stiller
+stillness/M
+stilt/SMD
+stilted/Y
+stimulant/SM
+stimulate/DSGNV
+stimulation/M
+stimuli
+stimulus/M
+sting/ZGSMR
+stinger/M
+stingily
+stinginess/M
+stingray/SM
+stingy/RTP
+stink/ZGSMR
+stinkbug/SM
+stinker/M
+stinky/RT
+stint/GSMD
+stipend/SM
+stipendiary/S
+stipple/DSMG
+stippling/M
+stipulate/XDSGN
+stipulation/M
+stir/MS
+stirred
+stirrer/SM
+stirring/SY
+stirrup/SM
+stitch's
+stitch/ADSG
+stitchery/M
+stitching/M
+stoat/SM
+stochastic
+stock's
+stock/AGSD
+stockade/DSMG
+stockbreeder/MS
+stockbroker/SM
+stockbroking/M
+stockholder/SM
+stockily
+stockiness/M
+stockinet/M
+stockinette/M
+stocking/SM
+stockist/S
+stockpile/MGDS
+stockpot/SM
+stockroom/MS
+stocktaking/M
+stocky/RTP
+stockyard/MS
+stodge
+stodgily
+stodginess/M
+stodgy/RTP
+stogie/M
+stogy/SM
+stoic/SM
+stoical/Y
+stoicism/M
+stoke/DRSZG
+stoker/M
+stole/SM
+stolen
+stolid/RYTP
+stolidity/M
+stolidness/M
+stolon/MS
+stomach/MDRZG
+stomachache/SM
+stomacher/M
+stomachs
+stomp/GSMD
+stone/DRSMZG
+stonemason/MS
+stoner/M
+stonewall/GSD
+stoneware/M
+stonewashed
+stonework/M
+stonily
+stoniness/M
+stonkered
+stonking
+stony/TRP
+stood
+stooge/MS
+stool/SM
+stoop/GSMD
+stop's
+stop/US
+stopcock/SM
+stopgap/SM
+stoplight/MS
+stopover/MS
+stoppable/U
+stoppage/MS
+stopped/U
+stopper/GSMD
+stopping/U
+stopple/DSMG
+stopwatch/MS
+storage/M
+store's
+store/ADSG
+storefront/MS
+storehouse/MS
+storekeeper/SM
+storeroom/SM
+stork/SM
+storm/GSMD
+stormily
+storminess/M
+stormy/RPT
+story/DSM
+storyboard/MS
+storybook/SM
+storyteller/MS
+storytelling/M
+stoup/SM
+stout/TSMRYP
+stouthearted
+stoutness/M
+stove/SM
+stovepipe/SM
+stow/DGS
+stowage/M
+stowaway/MS
+straddle/DRSMZG
+straddler/M
+strafe/MGDS
+straggle/DRSZG
+straggler/M
+straggly/TR
+straight/SPXTMNRY
+straightaway/SM
+straightedge/SM
+straighten/ZGDR
+straightener/M
+straightforward/YPS
+straightforwardness/M
+straightness/M
+straightway
+strain's
+strain/FADSG
+strainer/ASM
+strait/MNSX
+straiten/GD
+straitjacket/SGMD
+straitlaced
+strand/MDSG
+strange/PRYZT
+strangeness/M
+stranger/M
+strangle/ZGDRS
+stranglehold/SM
+strangler/M
+strangulate/GNDS
+strangulation/M
+strap's
+strap/US
+strapless/MS
+strapped/U
+strapping/M
+strata
+stratagem/SM
+strategic/S
+strategical/Y
+strategics/M
+strategist/SM
+strategy/SM
+strati
+stratification/M
+stratify/DSGN
+stratosphere/SM
+stratospheric
+stratum/M
+stratus/M
+straw/GSMD
+strawberry/SM
+stray/GSMD
+streak/MDRSZG
+streaker/M
+streaky/TR
+stream/MDRSZG
+streamer/M
+streamline/DSG
+street/MS
+streetcar/MS
+streetlamp/S
+streetlight/SM
+streetwalker/SM
+streetwise
+strength/M
+strengthen/AGDS
+strengthener/MS
+strengths
+strenuous/PY
+strenuousness/M
+strep/M
+streptococcal
+streptococci
+streptococcus/M
+streptomycin/M
+stress/MDSG
+stressed/U
+stressful
+stressors
+stretch/BZGMDRS
+stretcher/MDG
+stretchmarks
+stretchy/TR
+strew/GSDH
+strewn
+stria/M
+striae
+striated
+striation/MS
+stricken
+strict/RYPT
+strictness/M
+stricture/SM
+stridden
+stride/MGS
+stridency/M
+strident/Y
+strife/M
+strike/MZGRSJ
+strikebound
+strikebreaker/SM
+strikebreaking
+strikeout/MS
+striker/M
+striking/Y
+string/MDRSZG
+stringency/M
+stringent/Y
+stringer/M
+stringiness/M
+stringy/PTR
+strip/GSMD
+stripe/MS
+stripey
+stripling/MS
+stripped
+stripper/MS
+stripping
+striptease/MZGDRS
+stripteaser/M
+stripy
+strive/GS
+striven
+strobe/MS
+stroboscope/MS
+stroboscopic
+strode
+stroke/MGDS
+stroll/MDRSZG
+stroller/M
+strong/RYT
+strongbox/MS
+stronghold/MS
+strongman/M
+strongmen
+strongroom/S
+strontium/M
+strop/SM
+strophe/SM
+strophic
+stropped
+stroppily
+stropping
+stroppy/TRP
+strove
+struck
+structural/Y
+structuralism
+structuralist/S
+structure's
+structure/AGDS
+structured/U
+strudel/SM
+struggle/MGDS
+strum/SM
+strummed
+strumming
+strumpet/MS
+strung/UA
+strut/SM
+strutted
+strutting
+strychnine/M
+stub/MS
+stubbed
+stubbing
+stubble/M
+stubbly
+stubborn/RYPT
+stubbornness/M
+stubby/RT
+stucco/MDG
+stuccoes
+stuck/U
+stud/MYS
+studbook/MS
+studded
+studding/M
+student/SM
+studentship/S
+studied/U
+studiedly
+studio/MS
+studious/PY
+studiousness/M
+studly/RT
+study's
+study/AGDS
+stuff/GSMDJ
+stuffily
+stuffiness/M
+stuffing/M
+stuffy/RPT
+stultification/M
+stultify/DSNG
+stumble/DRSMZG
+stumbler/M
+stump/GSMD
+stumpy/TR
+stun/S
+stung
+stunk
+stunned
+stunner/S
+stunning/Y
+stunt/GSMD
+stuntman
+stuntmen
+stupefaction/M
+stupefy/DSG
+stupendous/Y
+stupid/TMRYS
+stupidity/SM
+stupor/MS
+sturdily
+sturdiness/M
+sturdy/TRP
+sturgeon/SM
+stutter/MDRSZG
+stutterer/M
+sty/SM
+stye/MS
+style's
+style/ADSG
+styli
+stylish/PY
+stylishness/M
+stylist/SM
+stylistic/S
+stylistically
+stylize/DSG
+stylus/MS
+stymie/MDS
+stymieing
+styptic/SM
+suasion/EM
+suave/RYTP
+suaveness/M
+suavity/M
+sub/SM
+subaltern/MS
+subaqua
+subarctic
+subarea/MS
+subatomic
+subbasement/SM
+subbed
+subbing
+subbranch/MS
+subcategory/SM
+subclass
+subcommittee/SM
+subcompact/SM
+subconscious/PMY
+subconsciousness/M
+subcontinent/SM
+subcontinental
+subcontract/MDSG
+subcontractor/MS
+subculture/MS
+subcutaneous/Y
+subdivide/GDS
+subdivision/SM
+subdomain/MS
+subdominant
+subdue/DSG
+subeditor/S
+subfamily/SM
+subfreezing
+subgroup/MS
+subhead/GJMS
+subheading/M
+subhuman/MS
+subj
+subject/GVMDS
+subjection/M
+subjective/Y
+subjectivity/M
+subjoin/GDS
+subjugate/GNDS
+subjugation/M
+subjunctive/SM
+sublease/MGDS
+sublet/SM
+subletting
+sublieutenant/S
+sublimate/GNDS
+sublimation/M
+sublime/YTGDRS
+subliminal/Y
+sublimity/M
+sublingual
+submarginal
+submarine/MZRS
+submariner/M
+submerge/GDS
+submergence/M
+submerse/GNDS
+submersible/MS
+submersion/M
+submicroscopic
+submission/MS
+submissive/PY
+submissiveness/M
+submit/AS
+submitted/A
+submitter
+submitting/A
+subnormal
+suborbital
+suborder/MS
+subordinate/DSMGN
+subordination/IM
+suborn/SGD
+subornation/M
+subpar
+subparagraph
+subpart
+subplot/MS
+subpoena/GMDS
+subprime
+subprofessional/SM
+subprogram/S
+subroutine/SM
+subscribe/UASDG
+subscriber/MS
+subscript/MS
+subscription/MS
+subsection/MS
+subsequent/Y
+subservience/M
+subservient/Y
+subset/SM
+subside/GDS
+subsidence/M
+subsidiarity
+subsidiary/SM
+subsidization/M
+subsidize/ZGDRS
+subsidizer/M
+subsidy/SM
+subsist/SDG
+subsistence/M
+subsoil/M
+subsonic
+subspace
+subspecies/M
+substance/SM
+substandard
+substantial/IY
+substantiate/GNDSX
+substantiated/U
+substantiation/FM
+substantive/SMY
+substation/MS
+substituent
+substitute/XMGNDS
+substitution/M
+substrata
+substrate/MS
+substratum/M
+substructure/SM
+subsume/DSG
+subsumption
+subsurface/M
+subsystem/SM
+subteen/SM
+subtenancy/M
+subtenant/SM
+subtend/SDG
+subterfuge/SM
+subterranean
+subtext/SM
+subtitle/DSMG
+subtle/TR
+subtlety/SM
+subtly
+subtopic/SM
+subtotal/SGMD
+subtract/GSD
+subtraction/SM
+subtrahend/SM
+subtropic/S
+subtropical
+subtropics/M
+suburb/MS
+suburban/SM
+suburbanite/SM
+suburbia/M
+subvention/SM
+subversion/M
+subversive/SPMY
+subversiveness/M
+subvert/SDG
+subway/MS
+subzero
+succeed/GDS
+success/VMS
+successful/UY
+succession/SM
+successive/Y
+successor/SM
+succinct/RYTP
+succinctness/M
+succor/SGMD
+succotash/M
+succubi
+succubus
+succulence/M
+succulency/M
+succulent/SM
+succumb/GDS
+such
+suchlike
+suck/MDRZGS
+sucker/GMD
+suckle/DSJG
+suckling/M
+sucrose/M
+suction/SMDG
+sudden/PY
+suddenness/M
+suds/M
+sudsy/TR
+sue/DSG
+suede/M
+suet/M
+suety
+suffer/DRZGSJ
+sufferance/M
+sufferer/M
+suffering/M
+suffice/DSG
+sufficiency/IM
+sufficient/IY
+suffix/MDSG
+suffixation/M
+suffocate/GNDS
+suffocation/M
+suffragan/MS
+suffrage/M
+suffragette/SM
+suffragist/MS
+suffuse/DSGN
+suffusion/M
+sugar/GSMD
+sugarcane/M
+sugarcoat/GDS
+sugarless
+sugarplum/MS
+sugary/RT
+suggest/GVSDR
+suggestibility/M
+suggestible
+suggestion/SM
+suggestive/YP
+suggestiveness/M
+suicidal
+suicide/SM
+suit/BMDGS
+suitability/UM
+suitableness/M
+suitably/U
+suitcase/SM
+suite/SM
+suited/U
+suiting/M
+suitor/MS
+sukiyaki/M
+sulfa/M
+sulfate/SM
+sulfide/SM
+sulfonamides
+sulfur/MDSG
+sulfuric
+sulfurous
+sulk/MDGS
+sulkily
+sulkiness/M
+sulky/TRSMP
+sullen/RYPT
+sullenness/M
+sullied/U
+sully/GDS
+sultan/MS
+sultana/SM
+sultanate/MS
+sultrily
+sultriness/M
+sultry/RPT
+sum/SM
+sumac/M
+summarily
+summarize/GDS
+summary/SM
+summat
+summation/FMS
+summed
+summer/MDSG
+summerhouse/SM
+summertime/M
+summery
+summing
+summit/MS
+summitry/M
+summon/DRSZG
+summoner/M
+summons/GMDS
+sumo/M
+sump/MS
+sumptuous/PY
+sumptuousness/M
+sun/SM
+sunbath/ZGMDRS
+sunbathe
+sunbather/M
+sunbathing/M
+sunbaths
+sunbeam/SM
+sunbed/S
+sunbelt/SM
+sunblock/MS
+sunbonnet/SM
+sunburn/SGMD
+sunburst/MS
+sundae/MS
+sundeck/S
+sunder/DSG
+sundial/SM
+sundown/SM
+sundress/S
+sundries/M
+sundry/S
+sunfish/MS
+sunflower/MS
+sung/U
+sunglasses/M
+sunhat/S
+sunk/N
+sunlamp/SM
+sunless
+sunlight/M
+sunlit
+sunned
+sunniness/M
+sunning
+sunny/TRP
+sunrise/SM
+sunroof/SM
+sunscreen/MS
+sunset/MS
+sunshade/MS
+sunshine/M
+sunshiny
+sunspot/SM
+sunstroke/M
+suntan/MS
+suntanned
+suntanning
+suntrap/S
+sunup/M
+sup/SZMR
+super/M
+superabundance/MS
+superabundant
+superannuate/GNDS
+superannuation/M
+superb/RYT
+supercargo/M
+supercargoes
+supercharge/ZGDRS
+supercharger/M
+supercilious/PY
+superciliousness/M
+supercity/SM
+supercomputer/MS
+superconducting
+superconductive
+superconductivity/M
+superconductor/SM
+supercritical
+superego/MS
+supererogation/M
+supererogatory
+superficial/Y
+superficiality/M
+superfine
+superfluity/M
+superfluous/YP
+superfluousness/M
+superglue
+supergrass/S
+superhero/MS
+superheroes
+superhighway/SM
+superhuman
+superimpose/GDS
+superimposition/M
+superintend/DSG
+superintendence/M
+superintendency/M
+superintendent/SM
+superior/MS
+superiority/M
+superlative/SMY
+superman/M
+supermarket/SM
+supermassive
+supermen
+supermodel/SM
+supermom/MS
+supernal
+supernatural/SY
+supernova/MS
+supernovae
+supernumerary/SM
+superpose/GDS
+superposition/M
+superpower/SM
+supersaturate/GNDS
+supersaturation/M
+superscribe/GDS
+superscript/MS
+superscription/M
+supersede/GDS
+supersize/GDS
+supersonic
+superspreader/SM
+superstar/MS
+superstardom
+superstate/S
+superstition/MS
+superstitious/Y
+superstore/MS
+superstructure/MS
+supertanker/MS
+superuser/S
+supervene/GDS
+supervention/M
+supervise/XGNDS
+supervised/U
+supervision/M
+supervisor/MS
+supervisory
+superwoman/M
+superwomen
+supine/Y
+supp/DRZG
+supper/M
+suppertime
+suppl
+supplant/SDG
+supple/TLPR
+supplement/MDGS
+supplemental
+supplementary
+supplementation/M
+suppleness/M
+suppliant/SM
+supplicant/MS
+supplicate/GDS
+supplication/M
+supplier/M
+supply/ZGDRSMXN
+support/MDRSBZGV
+supportable/UI
+supported/U
+supporter/M
+suppose/GDS
+supposed/Y
+supposition/MS
+suppository/SM
+suppress/GVDS
+suppressant/MS
+suppressible
+suppression/M
+suppressor/SM
+suppurate/DSGN
+suppuration/M
+supra
+supranational
+supremacist/MS
+supremacy/M
+supreme/Y
+supremo/S
+supt
+surcease/DSMG
+surcharge/DSMG
+surcingle/SM
+sure/PYTR
+surefire
+surefooted
+sureness/M
+surety/SM
+surf/MDRZGS
+surface's
+surface/AGDS
+surfboard/MDSG
+surfeit/MDSG
+surfer/M
+surfing/M
+surge/DSMG
+surgeon/MS
+surgery/SM
+surgical/Y
+surliness/M
+surly/PTR
+surmise/MGDS
+surmount/DGSB
+surmountable/I
+surname/MS
+surpass/GDS
+surpassed/U
+surplice/MS
+surplus/MS
+surplussed
+surplussing
+surprise/DSMGJ
+surprising/UY
+surreal
+surrealism/M
+surrealist/SM
+surrealistic
+surrealistically
+surrender/MDSG
+surreptitious/PY
+surreptitiousness/M
+surrey/MS
+surrogacy/M
+surrogate/SM
+surround/GSDJ
+surrounding/M
+surroundings/M
+surtax/MDSG
+surtitle/S
+surveillance/M
+survey's
+survey/ADGS
+surveying/M
+surveyor/SM
+survival/SM
+survivalist/SM
+survive/DSGB
+survivor/SM
+susceptibility/SM
+susceptible/I
+sushi/M
+suspect/SMDG
+suspected/U
+suspend/SDRZG
+suspender/M
+suspense/XMN
+suspenseful
+suspension/M
+suspicion/SM
+suspicious/Y
+suss/DSG
+sustain/SDBG
+sustainability
+sustainable/U
+sustainably
+sustenance/M
+sutler/MS
+suttee
+suture/MGDS
+suzerain/MS
+suzerainty/M
+svelte/TR
+swab/MS
+swabbed
+swabbing
+swaddle/DSG
+swag/MS
+swagged
+swagger/SMDRG
+swagging
+swain/SM
+swallow/GSMD
+swallowtail/MS
+swam
+swami/SM
+swamp/GSMD
+swampland/M
+swampy/RT
+swan/MS
+swank/TGSMDR
+swankily
+swankiness/M
+swanky/RPT
+swanned
+swanning
+swansdown/M
+swansong/S
+swap/MS
+swapped
+swapping
+sward/SM
+swarm/GSMD
+swarthy/TR
+swash/GMDS
+swashbuckler/SM
+swashbuckling/M
+swastika/SM
+swat/MS
+swatch/MS
+swath/GMDS
+swathe/M
+swaths
+swatted
+swatter/SMDG
+swatting
+sway/MDGS
+swayback/MD
+swayed/U
+swear/ZGSR
+swearer/M
+swearword/MS
+sweat/ZGSMDR
+sweatband/MS
+sweater/M
+sweatpants/M
+sweats/M
+sweatshirt/SM
+sweatshop/MS
+sweatsuit/S
+sweaty/RT
+swede/SM
+sweep/ZGSMRJ
+sweeper/M
+sweeping/MY
+sweepings/M
+sweepstakes/M
+sweet/XTSMNRYP
+sweetbread/SM
+sweetbriar/SM
+sweetbrier/SM
+sweetcorn
+sweetened/U
+sweetener/MS
+sweetening/M
+sweetheart/SM
+sweetie/SM
+sweetish
+sweetmeat/MS
+sweetness/M
+swell/TGSMDRJ
+swellhead/MDS
+swelling/M
+swelter/SGMD
+swept
+sweptback
+swerve/MGDS
+swerving/U
+swift/PTSMRY
+swiftness/M
+swig/MS
+swigged
+swigging
+swill/GSMD
+swim/MS
+swimmer/SM
+swimming/MY
+swimsuit/SM
+swimwear
+swindle/DRSMZG
+swindler/M
+swine/SM
+swineherd/SM
+swing/ZGSMR
+swingeing
+swinger/M
+swinish
+swipe/DSMG
+swirl/GSMD
+swirly
+swish/TGMDRS
+switch/MDRSZGB
+switchback/MS
+switchblade/SM
+switchboard/SM
+switcher/M
+switchover
+swivel/MDGS
+swiz
+swizz
+swizzle/DSG
+swollen
+swoon/SGMD
+swoop/SGMD
+swoosh/MDSG
+sword/SM
+swordfish/MS
+swordplay/M
+swordsman/M
+swordsmanship/M
+swordsmen
+swore
+sworn
+swot/S
+swotted
+swotting
+swum
+swung
+sybarite/SM
+sybaritic
+sycamore/MS
+sycophancy/M
+sycophant/SM
+sycophantic
+syllabic
+syllabicate/GNDS
+syllabication/M
+syllabification/M
+syllabify/DSNG
+syllable/MS
+syllabub/S
+syllabus/MS
+syllogism/MS
+syllogistic
+sylph/M
+sylphic
+sylphlike
+sylphs
+sylvan
+symbioses
+symbiosis/M
+symbiotic
+symbiotically
+symbol/MS
+symbolic
+symbolical/Y
+symbolism/M
+symbolization/M
+symbolize/DSG
+symbology
+symmetric/Y
+symmetrical/Y
+symmetry/SM
+sympathetic/U
+sympathetically/U
+sympathies/M
+sympathize/ZGDRS
+sympathizer/M
+sympathy/SM
+symphonic
+symphony/SM
+symposium/MS
+symptom/MS
+symptomatic
+symptomatically
+syn/H
+synagogal
+synagogue/SM
+synapse/MS
+synaptic
+sync/MDSG
+synchronicity
+synchronization/SM
+synchronize/GDS
+synchronous/Y
+synchrony
+syncopate/DSGN
+syncopation/M
+syncope/M
+syndicalism
+syndicalist/S
+syndicate/DSMGN
+syndication/M
+syndrome/SM
+synergism/M
+synergistic
+synergy/SM
+synfuel/MS
+synod/SM
+synonym/SM
+synonymous
+synonymy/M
+synopses
+synopsis/M
+synoptic
+synovial
+syntactic
+syntactical/Y
+syntax/M
+syntheses
+synthesis/M
+synthesize/ZGDRS
+synthesizer/M
+synthetic/SM
+synthetically
+synths
+syphilis/M
+syphilitic/SM
+syringe/DSMG
+syrup/SM
+syrupy
+sysadmin/S
+sysop/S
+system/SM
+systematic/U
+systematical/Y
+systematization/M
+systematize/GDS
+systemic/MS
+systemically
+systole/SM
+systolic
+s辿ance/SM
+t/SDNXGBJ
+ta
+tab/SM
+tabbed
+tabbing
+tabbouleh/M
+tabby/SM
+tabernacle/SM
+tabla/MS
+table/MGDS
+tableau/M
+tableaux
+tablecloth/M
+tablecloths
+tableland/SM
+tablespoon/SM
+tablespoonful/SM
+tablet/SM
+tabletop/MS
+tableware/M
+tabloid/SM
+taboo/MDSG
+tabor/MS
+tabular
+tabulate/DSGNX
+tabulation/M
+tabulator/SM
+tachograph
+tachographs
+tachometer/SM
+tachycardia/M
+tachyon
+tacit/PY
+tacitness/M
+taciturn/Y
+taciturnity/M
+tack/ZGMDRS
+tacker/M
+tackiness/M
+tackle/DRSMZG
+tackler/M
+tacky/RTP
+taco/MS
+tact/FM
+tactful/YP
+tactfulness/M
+tactic/SM
+tactical/Y
+tactician/MS
+tactile
+tactility/M
+tactless/PY
+tactlessness/M
+tad/SM
+tadpole/MS
+taffeta/M
+taffrail/SM
+taffy/SM
+tag/SM
+tagged
+tagger/SM
+tagging
+tagliatelle
+tagline/MS
+taiga/MS
+tail/ACSDMG
+tailback/MS
+tailboard/S
+tailbone/S
+tailcoat/MS
+tailgate/MZGDRS
+tailgater/M
+tailless
+taillight/MS
+tailor/SGMD
+tailoring/M
+tailpiece/S
+tailpipe/SM
+tailspin/SM
+tailwind/SM
+taint/MDSG
+tainted/U
+take/AIMS
+takeaway/S
+taken/A
+takeoff/MS
+takeout/MS
+takeover/SM
+taker/MS
+taking/SM
+takings/M
+talc/M
+talcum/M
+tale/MS
+talebearer/MS
+talent/SMD
+talented/U
+tali
+talisman/MS
+talk/ZGMDRS
+talkative/PY
+talkativeness/M
+talker/M
+talkie/RSMT
+talky
+tall/TRP
+tallboy/MS
+tallier/M
+tallish
+tallness/M
+tallow/M
+tallowy
+tally/DRSMZG
+tallyho/MDGS
+talon/MS
+talus/MS
+tam/SM
+tamale/SM
+tamarack/MS
+tamarind/MS
+tambourine/MS
+tame/BYZTGDRSP
+tameable
+tamed/U
+tameness/M
+tamer/M
+tamoxifen
+tamp/ZGDRS
+tamper/ZGDR
+tamperer/M
+tampon/SM
+tan/SM
+tanager/MS
+tanbark/M
+tandem/SM
+tandoori/M
+tang/MS
+tangelo/MS
+tangent/MS
+tangential/Y
+tangerine/MS
+tangibility/IM
+tangible/IMS
+tangibleness/M
+tangibly/I
+tangle's
+tangle/UDSG
+tango/MDSG
+tangy/RT
+tank/ZGMDRS
+tankard/MS
+tanker/M
+tankful/MS
+tanned/U
+tanner/SM
+tannery/SM
+tannest
+tannin/M
+tanning/M
+tansy/M
+tantalization/M
+tantalize/ZGDRS
+tantalizer/M
+tantalizing/Y
+tantalum/M
+tantamount
+tantra/M
+tantrum/SM
+tap/SZGMDR
+tapas
+tape/MS
+tapeline/MS
+taper/MDG
+tapestry/SM
+tapeworm/MS
+tapioca/M
+tapir/MS
+tapped/U
+tapper/MS
+tappet/MS
+tapping
+taproom/SM
+taproot/SM
+tar/SGMD
+taramasalata
+tarantella/MS
+tarantula/SM
+tarball/S
+tardily
+tardiness/M
+tardy/TPR
+tare/MS
+target/MDGS
+tariff/MS
+tarmac/MS
+tarmacadam
+tarmacked
+tarmacking
+tarn/MS
+tarnish/GMDS
+tarnished/U
+taro/MS
+tarot/MS
+tarp/MS
+tarpaulin/MS
+tarpon/MS
+tarragon/SM
+tarred
+tarring
+tarry/TGDRS
+tarsal/MS
+tarsi
+tarsus/M
+tart/PTGMDRYS
+tartan/MS
+tartar/MS
+tartaric
+tartness/M
+tarty/T
+taser/GMDS
+task/GMDS
+taskbar
+taskmaster/MS
+taskmistress/MS
+tassel/MDSG
+taste/JMZGDRS
+tasted/U
+tasteful/EPY
+tastefulness/EM
+tasteless/PY
+tastelessness/M
+taster/M
+tastily
+tastiness/M
+tasting/M
+tasty/TRP
+tat/SZR
+tatami/MS
+tater/M
+tatted
+tatter/MDSG
+tatterdemalion/MS
+tattie
+tatting/M
+tattle/MZGDRS
+tattler/M
+tattletale/MS
+tattoo/MDRSZG
+tattooer/M
+tattooist/SM
+tatty/TRS
+tau/SM
+taught/UA
+taunt/ZGMDRS
+taunter/M
+taunting/Y
+taupe/M
+taut/PXTNRY
+tauten/DG
+tautness/M
+tautological/Y
+tautologous
+tautology/SM
+tavern/MS
+tawdrily
+tawdriness/M
+tawdry/RTP
+tawny/TRM
+tax/BZGMDRS
+taxa
+taxation/M
+taxer/M
+taxi/GMDS
+taxicab/SM
+taxidermist/SM
+taxidermy/M
+taximeter/MS
+taxiway/S
+taxman
+taxmen
+taxon
+taxonomic
+taxonomical
+taxonomist/MS
+taxonomy/SM
+taxpayer/MS
+taxpaying
+tb/S
+tbsp
+tea/SM
+teabag/S
+teacake/SM
+teach/ZGRSBJ
+teachable/U
+teacher/M
+teaching/M
+teacup/MS
+teacupful/MS
+teak/MS
+teakettle/SM
+teal/MS
+tealight/MS
+team/GMDS
+teammate/MS
+teamster/MS
+teamwork/M
+teapot/MS
+tear/GMDS
+tearaway/S
+teardrop/SM
+tearful/Y
+teargas/MS
+teargassed
+teargassing
+tearjerker/MS
+tearoom/SM
+teary/TR
+tease/MZGDRS
+teasel/MS
+teaser/M
+teasing/Y
+teaspoon/SM
+teaspoonful/SM
+teat/MS
+teatime/S
+tech/M
+techie/S
+technetium/M
+technical/Y
+technicality/SM
+technician/SM
+technicolor
+technique/SM
+techno
+technobabble
+technocracy/SM
+technocrat/MS
+technocratic
+technological/Y
+technologist/MS
+technology/SM
+technophobe/S
+techs
+tectonic/S
+tectonics/M
+ted/S
+teddy/S
+tedious/PY
+tediousness/M
+tedium/M
+tee/DSMH
+teeing
+teem/GDS
+teen/MS
+teenage/RZ
+teenager/M
+teeny/TR
+teenybopper/MS
+teepee/MS
+teeter/MDSG
+teethe/GDS
+teething/M
+teetotal/RZ
+teetotaler/M
+teetotalism/M
+tektite/SM
+tel
+telecast/SZGMR
+telecaster/M
+telecommunication/MS
+telecommunications/M
+telecommute/ZGDRS
+telecommuter/M
+telecommuting/M
+teleconference/MGDS
+teleconferencing/M
+telegenic
+telegram/MS
+telegraph/MDRZG
+telegrapher/M
+telegraphese
+telegraphic
+telegraphically
+telegraphist/SM
+telegraphs
+telegraphy/M
+telekinesis/M
+telekinetic
+telemarketer/SM
+telemarketing/M
+telemeter/SM
+telemetry/SM
+teleological
+teleology
+telepathic
+telepathically
+telepathy/M
+telephone/DRSMZG
+telephoner/M
+telephonic
+telephonist/S
+telephony/M
+telephoto/SM
+telephotography/M
+teleplay/MS
+teleport
+teleportation
+teleprinter/MS
+teleprocessing/M
+teleprompter/SM
+telesales
+telescope/DSMG
+telescopic
+telescopically
+teletext/MS
+telethon/MS
+teletype/S
+teletypewriter/MS
+televangelism/M
+televangelist/MS
+televise/XGNDS
+television/M
+teleworker/S
+teleworking
+telex/MDSG
+tell/AGS
+teller/SM
+telling/Y
+telltale/SM
+tellurium/M
+telly/SM
+telnet
+temblor/MS
+temerity/M
+temp/MDRZTGS
+temper/MDG
+tempera/LSM
+temperament/MS
+temperamental/Y
+temperance/IM
+temperate/IY
+temperateness/M
+temperature/SM
+tempest/SM
+tempestuous/YP
+tempestuousness/M
+tempi
+template's
+template/S
+temple/SM
+tempo/SM
+temporal/Y
+temporarily
+temporariness/M
+temporary/FSM
+temporize/ZGDRS
+temporizer/M
+tempt/SDRZG
+temptation/MS
+tempter/M
+tempting/Y
+temptress/MS
+tempura/M
+ten/BMH
+tenability/M
+tenable/U
+tenably
+tenacious/YP
+tenaciousness/M
+tenacity/M
+tenancy/SM
+tenant/SMDG
+tenanted/U
+tenantry/M
+tench
+tend/IEFDGS
+tended/U
+tendency/SM
+tendentious/YP
+tendentiousness/M
+tender/SMDRYTGP
+tenderfoot/MS
+tenderhearted/P
+tenderheartedness/M
+tenderize/ZGDRS
+tenderizer/M
+tenderloin/SM
+tenderness/M
+tendinitis/M
+tendon/SM
+tendonitis/M
+tendril/SM
+tenement/SM
+tenet/SM
+tenfold
+tenner/S
+tennis/M
+tenon/SMDG
+tenor/SM
+tenpin/SM
+tenpins/M
+tense/DRSMYTGNXP
+tenseness/M
+tensile
+tension/ESM
+tensity/IM
+tensor/S
+tent/DGSM
+tentacle/DSM
+tentative/PY
+tentativeness/M
+tenterhook/MS
+tenth/MY
+tenths
+tenuity/M
+tenuous/PY
+tenuousness/M
+tenure/DSMG
+tepee/SM
+tepid/YP
+tepidity/M
+tepidness/M
+tequila/SM
+terabit/SM
+terabyte/MS
+terahertz/M
+terajoule/S
+terapixel/MS
+terawatt/S
+terbium/M
+tercentenary/SM
+tercentennial/SM
+teriyaki
+term/MDYGS
+termagant/MS
+terminable/IC
+terminal/MYS
+terminate/DSGNX
+termination/CSM
+terminator/S
+termini
+terminological/Y
+terminology/SM
+terminus/M
+termite/SM
+tern/IMS
+ternary/SM
+terr
+terrace/DSMG
+terracotta/M
+terrain/SM
+terrapin/MS
+terrarium/SM
+terrazzo/MS
+terrestrial/SMY
+terrible/P
+terribleness/M
+terribly
+terrier/M
+terrific
+terrifically
+terrify/GDS
+terrifying/Y
+terrine/S
+territorial/MS
+territoriality
+territory/SM
+terror/SM
+terrorism/M
+terrorist/SM
+terrorize/DSG
+terry/RMZ
+terrycloth/M
+terse/RYTP
+terseness/M
+tertiary
+tessellate/DSXGN
+tessellation/M
+test's/AFK
+test/AKFCDGS
+testable/CF
+testament/MS
+testamentary
+testate/S
+testator/MS
+testatrices
+testatrix/M
+tested/U
+tester/KSM
+testes
+testicle/MS
+testicular
+testifier/M
+testify/ZGDRS
+testily
+testimonial/MS
+testimony/SM
+testiness/M
+testings
+testis/M
+testosterone/M
+testy/PRT
+tetanus/M
+tetchily
+tetchy/PRT
+tether/SMDG
+tetra/SM
+tetracycline/M
+tetrahedral
+tetrahedron/MS
+tetrameter/SM
+text/FMS
+textbook/SM
+texted
+textile/MS
+texting
+textual/FY
+textural
+texture/MGDS
+thalami
+thalamus/M
+thalidomide/M
+thallium/M
+than
+thane/SM
+thank/SDG
+thankful/YP
+thankfulness/M
+thankless/PY
+thanklessness/M
+thanksgiving/SM
+that'd
+that'll
+that/M
+thatch/MDRSZG
+thatcher/M
+thatching/M
+thaw/MDGS
+the/JG
+theater/SM
+theatergoer/SM
+theatrical/YS
+theatricality/M
+theatricals/M
+theatrics/M
+thee/S
+theft/SM
+their/S
+theism/M
+theist/SM
+theistic
+them
+thematic
+thematically
+theme/DSM
+themselves
+then/M
+thence
+thenceforth
+thenceforward
+theocracy/SM
+theocratic
+theodolite/S
+theologian/SM
+theological/Y
+theology/SM
+theorem/MS
+theoretic
+theoretical/Y
+theoretician/SM
+theorist/SM
+theorize/DSG
+theory/SM
+theosophic
+theosophical
+theosophist/SM
+theosophy/M
+therapeutic/S
+therapeutically
+therapeutics/M
+therapist/SM
+therapy/SM
+there/M
+thereabout/S
+thereafter
+thereat
+thereby
+therefor
+therefore
+therefrom
+therein
+theremin/SM
+thereof
+thereon
+thereto
+theretofore
+thereunder
+thereunto
+thereupon
+therewith
+therm/SM
+thermal/MYS
+thermionic
+thermodynamic/S
+thermodynamics/M
+thermometer/MS
+thermometric
+thermonuclear
+thermoplastic/SM
+thermos/MS
+thermostat/MS
+thermostatic
+thermostatically
+thesauri
+thesaurus/MS
+these/S
+thesis/M
+thespian/SM
+theta/SM
+thew/MS
+they
+they'd
+they'll
+they're
+they've
+thiamine/M
+thick/PMNRYXT
+thicken/DRJZG
+thickener/M
+thickening/M
+thicket/MS
+thickheaded/M
+thickness/MS
+thicko/S
+thickset
+thief/M
+thieve/DSG
+thievery/M
+thieving/M
+thievish
+thigh/M
+thighbone/MS
+thighs
+thimble/MS
+thimbleful/SM
+thin/YSP
+thine
+thing/M
+thingamabob/SM
+thingamajig/SM
+thingumabob/S
+thingummy/S
+thingy/S
+think/SRBZG
+thinkable/U
+thinker/M
+thinking's
+thinned
+thinner/MS
+thinness/M
+thinnest
+thinning
+third/SMY
+thirst/SGMD
+thirstily
+thirstiness/M
+thirsty/TPR
+thirteen/SMH
+thirteenth/M
+thirteenths
+thirtieth/M
+thirtieths
+thirty/HSM
+this
+thistle/MS
+thistledown/M
+thither
+tho
+thole/SM
+thong/SM
+thoracic
+thorax/MS
+thorium/M
+thorn/SM
+thorniness/M
+thorny/PRT
+thorough/RYPT
+thoroughbred/MS
+thoroughfare/MS
+thoroughgoing
+thoroughness/M
+those
+thou/MS
+though
+thought/SM
+thoughtful/YP
+thoughtfulness/M
+thoughtless/PY
+thoughtlessness/M
+thousand/MHS
+thousandfold
+thousandth/M
+thousandths
+thraldom/M
+thrall/SMDG
+thralldom/M
+thrash/JMDRSZG
+thrasher/M
+thrashing/M
+thread/SMDRZG
+threadbare
+threader/M
+threadlike
+thready/TR
+threat/SMNX
+threaten/DG
+threatening/Y
+three/SM
+threefold
+threepence/M
+threescore/MS
+threesome/SM
+threnody/SM
+thresh/MDRSZG
+thresher/M
+threshold/SM
+threw
+thrice
+thrift/SM
+thriftily
+thriftiness/M
+thriftless
+thrifty/PTR
+thrill/SMDRZG
+thriller/M
+thrilling/Y
+thrive/DSG
+throat/SM
+throatily
+throatiness/M
+throaty/RTP
+throb/SM
+throbbed
+throbbing
+throe/SM
+thrombi
+thrombolytic
+thromboses
+thrombosis/M
+thrombotic
+thrombus/M
+throne's
+throne/S
+throng/GSMD
+throttle/DRSMZG
+throttler/M
+through
+throughout
+throughput/M
+throughway/MS
+throw/SMRZG
+throwaway/SM
+throwback/SM
+thrower/M
+thrown
+thru
+thrum/SM
+thrummed
+thrumming
+thrush/MS
+thrust/GSM
+thruway/MS
+thud/MS
+thudded
+thudding
+thug/MS
+thuggery/M
+thuggish
+thulium/M
+thumb/SMDG
+thumbnail/SM
+thumbprint/SM
+thumbscrew/SM
+thumbtack/SM
+thump/SMDG
+thumping/M
+thunder/ZGMDRS
+thunderbolt/SM
+thunderclap/SM
+thundercloud/MS
+thunderer/M
+thunderhead/SM
+thunderous/Y
+thundershower/SM
+thunderstorm/SM
+thunderstruck
+thundery
+thunk/S
+thus
+thwack/ZGSMDR
+thwacker/M
+thwart/GSMD
+thy
+thyme/M
+thymine/M
+thymus/MS
+thyroid/MS
+thyroidal
+thyself
+ti/MRZ
+tiara/SM
+tibia/M
+tibiae
+tibial
+tic/SM
+tick/MDRZGS
+ticker/M
+ticket/GSMD
+ticking/M
+tickle/DRSMZG
+tickler/M
+ticklish/YP
+ticklishness/M
+ticktacktoe/M
+ticktock/MS
+tidal/Y
+tidbit/SM
+tiddler/S
+tiddly
+tiddlywink/S
+tiddlywinks/M
+tide/MGJDS
+tideland/SM
+tidemark/S
+tidewater/MS
+tideway/MS
+tidily/U
+tidiness/UM
+tidings/M
+tidy/DRSMTGP
+tie's
+tie/AUSD
+tieback/MS
+tiebreak/RSZ
+tiebreaker/M
+tiepin/S
+tier/MD
+tiff/MDGS
+tiger/SM
+tigerish
+tight/SNRYPXT
+tighten/ZGDR
+tightener/M
+tightfisted
+tightness/M
+tightrope/MS
+tights/M
+tightwad/MS
+tigress/MS
+til
+tilapia
+tilde/SM
+tile/MZGDRS
+tiler/M
+tiling/M
+till's
+till/EDRZGS
+tillable
+tillage/M
+tiller/EM
+tilt/MDGS
+timber/SMDG
+timberland/M
+timberline/MS
+timbre/SM
+timbrel/SM
+time/MYZGJDRS
+timekeeper/MS
+timekeeping/M
+timeless/PY
+timelessness/M
+timeline/MS
+timeliness/UM
+timely/UPRT
+timeout/SM
+timepiece/MS
+timer/M
+timescale/S
+timeserver/SM
+timeserving/M
+timeshare/S
+timestamp/SMD
+timetable/DSMG
+timeworn
+timezone
+timid/RYTP
+timidity/M
+timidness/M
+timing/M
+timorous/PY
+timorousness/M
+timothy/M
+timpani/M
+timpanist/SM
+tin/SM
+tincture/MGDS
+tinder/M
+tinderbox/MS
+tine/MS
+tinfoil/M
+ting/MDYG
+tinge/SM
+tingeing
+tingle/DSMGJ
+tingling/M
+tininess/M
+tinker/ZGSMDR
+tinkerer/M
+tinkle/DSMG
+tinned
+tinniness/M
+tinning
+tinnitus/M
+tinny/PRT
+tinplate/M
+tinpot
+tinsel/GSMD
+tinsmith/M
+tinsmiths
+tint/MDGS
+tintinnabulation/MS
+tintype/MS
+tinware/M
+tiny/RTP
+tip/SM
+tipped
+tipper/SM
+tippet/SM
+tippex/GDS
+tipping
+tipple/DRSMZG
+tippler/M
+tipsily
+tipsiness/M
+tipster/MS
+tipsy/RPT
+tiptoe/DSM
+tiptoeing
+tiptop/SM
+tirade/SM
+tiramisu/MS
+tire's
+tire/AGDS
+tired/PRYT
+tiredness/M
+tireless/YP
+tirelessness/M
+tiresome/PY
+tiresomeness/M
+tissue/SM
+tit/SM
+titan/SM
+titanic
+titanium/M
+titch/S
+titchy
+tithe/DRSMZG
+tither/M
+titian/M
+titillate/DSGN
+titillating/Y
+titillation/M
+titivate/DSGN
+titivation/M
+title/DSMG
+titled/U
+titleholder/MS
+titlist/MS
+titmice
+titmouse/M
+titter/SGMD
+tittivate/DSGN
+tittivation/M
+tittle/SM
+titty/S
+titular
+tizz
+tizzy/SM
+tn
+tnpk
+to/IU
+toad/MS
+toadstool/MS
+toady/DSMG
+toadyism/M
+toast/SMDRZG
+toaster/M
+toastmaster/SM
+toastmistress/MS
+toasty/TRS
+tobacco/MS
+tobacconist/SM
+toboggan/ZGSMDR
+tobogganer/M
+tobogganing/M
+toccata/S
+tocopherol
+tocsin/SM
+today/M
+toddle/DRSMZG
+toddler/M
+toddy/SM
+toe/DSM
+toecap/SM
+toehold/MS
+toeing
+toenail/MS
+toerag/S
+toff/S
+toffee/SM
+tofu/M
+tog/SM
+toga/MDS
+together/P
+togetherness/M
+togged
+togging
+toggle/DSMG
+togs/M
+toil/MDRZGS
+toiler/M
+toilet/MDGS
+toiletry/SM
+toilette/M
+toilsome
+toke/MGDS
+token/SM
+tokenism/M
+told/AU
+tole/M
+tolerable/I
+tolerably/I
+tolerance/IM
+tolerances
+tolerant/IY
+tolerate/GNDS
+toleration/M
+toll/MDGS
+tollbooth/M
+tollbooths
+tollgate/SM
+tollway/SM
+toluene/M
+tom/SM
+tomahawk/SGMD
+tomato/M
+tomatoes
+tomb/MDGS
+tombola/S
+tomboy/MS
+tomboyish
+tombstone/MS
+tomcat/MS
+tome/MS
+tomfoolery/SM
+tomographic
+tomography/M
+tomorrow/MS
+tomtit/MS
+ton/SM
+tonal/Y
+tonality/SM
+tone's
+tone/IZGDRS
+tonearm/SM
+toneless/Y
+toner/IM
+tong/MDGS
+tongue/MGDS
+tongueless
+tonic/SM
+tonight/M
+tonnage/SM
+tonne/SM
+tonsil/MS
+tonsillectomy/SM
+tonsillitis/M
+tonsorial
+tonsure/DSMG
+tony/RT
+too
+took/A
+tool's
+tool/ADGS
+toolbar/SM
+toolbox/MS
+toolkit
+toolmaker/MS
+toot/MDRZGS
+tooter/M
+tooth/MD
+toothache/MS
+toothbrush/MS
+toothily
+toothless
+toothpaste/SM
+toothpick/SM
+toothsome
+toothy/RT
+tootle/GDS
+tootsie/S
+top/SM
+topaz/MS
+topcoat/SM
+topdressing/SM
+topee/S
+topflight
+topi/S
+topiary/M
+topic/SM
+topical/Y
+topicality/M
+topknot/SM
+topless
+topmast/SM
+topmost
+topnotch
+topographer/SM
+topographic
+topographical/Y
+topography/SM
+topological/Y
+topology
+topped
+topper/MS
+topping/SM
+topple/GDS
+topsail/SM
+topside/SM
+topsoil/M
+topspin/M
+toque/SM
+tor/SM
+torah/M
+torahs
+torch/GMDS
+torchbearer/MS
+torchlight/M
+tore
+toreador/MS
+torment/SMDG
+tormenting/Y
+tormentor/MS
+torn
+tornado/M
+tornadoes
+torpedo/GMD
+torpedoes
+torpid/Y
+torpidity/M
+torpor/M
+torque/MGDS
+torrent/SM
+torrential
+torrid/YP
+torridity/M
+torridness/M
+torsion/M
+torsional
+torso/SM
+tort's
+tort/FEAS
+torte/SM
+tortellini/M
+tortilla/MS
+tortoise/MS
+tortoiseshell/SM
+tortoni/M
+tortuous/PY
+tortuousness/M
+torture/DRSMZG
+torturer/M
+torturous
+torus
+tosh
+toss/MDRSZG
+tossup/MS
+tot/SGMD
+total/GSMDY
+totalitarian/SM
+totalitarianism/M
+totality/SM
+totalizator/SM
+tote/MS
+totem/SM
+totemic
+totted
+totter/ZGMDRS
+totterer/M
+totting
+toucan/MS
+touch/AGMDS
+touchdown/SM
+touche/BJ
+touched/U
+touchily
+touchiness/M
+touching/Y
+touchline/S
+touchpaper/S
+touchscreen/MS
+touchstone/MS
+touchy/RPT
+touch辿
+tough/XTGMDNRYP
+toughen/ZGDR
+toughener/M
+toughie/SM
+toughness/M
+toughs
+toupee/MS
+tour/CFSGDM
+tourism/M
+tourist/MS
+touristic
+touristy
+tourmaline/M
+tournament/SM
+tourney/MS
+tourniquet/MS
+tousle/GDS
+tout/MDGS
+tow/SZGMDR
+toward/S
+towboat/MS
+towel/JGSMD
+towelette/SM
+toweling/M
+tower/GMD
+towhead/MDS
+towhee/MS
+towline/MS
+town/MS
+townee/S
+townhouse/MS
+townie/MS
+townsfolk/M
+township/MS
+townsman/M
+townsmen
+townspeople/M
+townswoman/M
+townswomen
+towpath/M
+towpaths
+towrope/SM
+toxemia/M
+toxic
+toxicity/SM
+toxicological
+toxicologist/SM
+toxicology/M
+toxin/SM
+toy/SGMD
+toyboy/S
+tr
+trabecula
+trabecular
+trabecule
+trace/JDRSMZG
+traceability
+traceable/U
+tracer/M
+tracery/SM
+trachea/M
+tracheae
+tracheal
+tracheotomy/SM
+tracing/M
+track/ZGSMDR
+trackball/SM
+tracker/M
+trackless
+tracksuit/S
+tract's
+tract/CEKFAS
+tractability/IM
+tractable/I
+tractably/I
+traction/EFACKM
+tractor/FCKMS
+trad
+trade/JDRSMZG
+trademark/SGMD
+trader/M
+tradesman/M
+tradesmen
+tradespeople/M
+tradeswoman/M
+tradeswomen
+trading/M
+tradition/MS
+traditional/Y
+traditionalism/M
+traditionalist/SM
+traduce/DRSZG
+traducer/M
+traffic/SM
+trafficked
+trafficker/SM
+trafficking/M
+tragedian/SM
+tragedienne/MS
+tragedy/SM
+tragic
+tragically
+tragicomedy/SM
+tragicomic
+trail/ZGSMDR
+trailblazer/MS
+trailblazing/M
+trailer/M
+train/ZGSMDRB
+trained/U
+trainee/SM
+trainer/M
+training/M
+trainload/MS
+trainman/M
+trainmen
+trainspotter/S
+trainspotting
+traipse/DSMG
+trait/SM
+traitor/SM
+traitorous/Y
+trajectory/SM
+tram/MS
+tramcar/S
+tramlines
+trammed
+trammel/SGMD
+trammeled/U
+tramming
+tramp/ZGSMDR
+tramper/M
+trample/DRSMZG
+trampler/M
+trampoline/MGDS
+tramway/S
+trance/MS
+tranche/S
+tranquil/RYT
+tranquility/M
+tranquilize/ZGDRS
+tranquilizer/M
+tranquillity/M
+trans/I
+transact/DGS
+transaction/SM
+transactional
+transactor/MS
+transatlantic
+transceiver/SM
+transcend/GSD
+transcendence/M
+transcendent
+transcendental/Y
+transcendentalism/M
+transcendentalist/SM
+transcontinental
+transcribe/ZGDRS
+transcriber/M
+transcript/MS
+transcription/SM
+transducer/MS
+transduction
+transect/DSG
+transept/MS
+transfer/MBS
+transferal/MS
+transference/M
+transferred
+transferring
+transfiguration/M
+transfigure/GDS
+transfinite
+transfix/DSG
+transform/BSZGMDR
+transformation/SM
+transformational
+transformer/M
+transfuse/DSXGN
+transfusion/M
+transgender/SD
+transgenic
+transgress/GDS
+transgression/SM
+transgressor/SM
+transience/M
+transiency/M
+transient/SMY
+transistor/SM
+transistorize/DSG
+transit/SGMD
+transition/GSMD
+transitional/Y
+transitive/ISMY
+transitiveness/M
+transitivity/M
+transitory
+transl
+translatable/U
+translate/DSGNBX
+translated/U
+translation/M
+translator/SM
+transliterate/DSGNX
+transliteration/M
+translocation
+translucence/M
+translucency/M
+translucent/Y
+transmigrate/GNDS
+transmigration/M
+transmissible
+transmission/MS
+transmit/S
+transmittable
+transmittal/M
+transmittance/M
+transmitted
+transmitter/SM
+transmitting
+transmogrification/M
+transmogrify/DSNG
+transmutation/SM
+transmute/BDSG
+transnational/MS
+transoceanic
+transom/SM
+transpacific
+transparency/SM
+transparent/Y
+transphobia/M
+transphobic
+transpiration/M
+transpire/DSG
+transplant/MDGS
+transplantation/M
+transpolar
+transponder/SM
+transport/BSZGMDR
+transportation/M
+transporter/M
+transpose/DSG
+transposition/MS
+transsexual/SM
+transsexualism/M
+transship/SL
+transshipment/M
+transshipped
+transshipping
+transubstantiation/M
+transversal
+transverse/MYS
+transvestism/M
+transvestite/MS
+trap/MS
+trapdoor/MS
+trapeze/SM
+trapezium/SM
+trapezoid/SM
+trapezoidal
+trappable
+trapped
+trapper/SM
+trapping/S
+trappings/M
+trapshooting/M
+trash/GMDS
+trashcan/MS
+trashiness/M
+trashy/RPT
+trauma/MS
+traumatic
+traumatically
+traumatize/GDS
+travail/SGMD
+travel/MDRSZGJ
+traveled/U
+traveler/M
+traveling/M
+travelog/SM
+travelogue/MS
+traversal/SM
+traverse/DSMG
+travesty/GDSM
+trawl/ZGSMDR
+trawler/M
+tray/MS
+treacherous/PY
+treacherousness/M
+treachery/SM
+treacle/M
+treacly
+tread/AGSM
+treadle/DSMG
+treadmill/MS
+treas
+treason/BM
+treasonous
+treasure/DRSMZG
+treasurer/M
+treasury/SM
+treat/AGSMD
+treatable
+treated/U
+treatise/SM
+treatment/MS
+treaty/SM
+treble/MGDS
+tree/MDS
+treeing
+treeless
+treelike
+treeline
+treetop/SM
+trefoil/SM
+trek/MS
+trekked
+trekker/SM
+trekking
+trellis/GMDS
+trematode/MS
+tremble/DSMG
+tremendous/Y
+tremolo/SM
+tremor/MS
+tremulous/PY
+tremulousness/M
+trench's
+trench/ADSG
+trenchancy/M
+trenchant/Y
+trencher/MS
+trencherman/M
+trenchermen
+trend/GSMD
+trendily
+trendiness/M
+trendsetter/S
+trendsetting
+trendy/RSMPT
+trepidation/M
+trespass/MDRSZG
+trespasser/M
+tress/EMS
+trestle/MS
+trews
+trey/MS
+triad/SM
+triage/MD
+trial/ASM
+trialed
+trialing
+triangle/SM
+triangular/Y
+triangulate/GNDS
+triangulation/M
+triathlete/S
+triathlon/SM
+tribal
+tribalism/M
+tribe/SM
+tribesman/M
+tribesmen
+tribeswoman/M
+tribeswomen
+tribulation/SM
+tribunal/SM
+tribune/MS
+tributary/SM
+tribute's
+tribute/FS
+trice/M
+tricentennial/MS
+triceps/MS
+triceratops/M
+trichina/M
+trichinae
+trichinosis/M
+trick/GSMD
+trickery/M
+trickily
+trickiness/M
+trickle/MGDS
+trickster/SM
+tricky/TRP
+tricolor/SM
+tricycle/SM
+trident/MS
+tried/U
+triennial/MYS
+trier/SM
+trifecta/SM
+trifle/MZGDRS
+trifler/M
+trifocals/M
+trig/M
+trigger/MDSG
+triglyceride/MS
+trigonometric
+trigonometrical
+trigonometry/M
+trike/SM
+trilateral/S
+trilby/SM
+trill/GSMD
+trillion/SMH
+trillionth/M
+trillionths
+trillium/M
+trilobite/SM
+trilogy/SM
+trim/PMYS
+trimaran/MS
+trimester/SM
+trimmed/U
+trimmer/SM
+trimmest
+trimming/SM
+trimmings/M
+trimness/M
+trimonthly
+trinitrotoluene/M
+trinity/SM
+trinket/SM
+trio/MS
+trip/MYS
+tripartite
+tripe/M
+triple/MGDS
+triplet/SM
+triplex/MS
+triplicate/MGDS
+tripod/MS
+tripodal
+tripos
+tripped
+tripper/SM
+tripping
+triptych/M
+triptychs
+tripwire/S
+trireme/SM
+trisect/SDG
+trisection/M
+trite/FPYT
+triteness/FM
+triter
+tritium/M
+triumph/GMD
+triumphal
+triumphalism
+triumphalist
+triumphant/Y
+triumphs
+triumvir/MS
+triumvirate/SM
+trivalent
+trivet/MS
+trivia/M
+trivial/Y
+triviality/SM
+trivialization/M
+trivialize/GDS
+trivium/M
+trochaic
+trochee/SM
+trod/AU
+trodden/A
+troglodyte/SM
+troika/MS
+troll/SGMD
+trolley/SM
+trolleybus/MS
+trollop/SM
+trombone/MS
+trombonist/MS
+tromp/SGD
+tron/S
+troop/SZGMDR
+trooper/M
+troopship/MS
+trope/SM
+trophy/SM
+tropic/MS
+tropical/Y
+tropics/M
+tropism/SM
+troposphere/SM
+trot/MS
+troth/M
+trotted
+trotter/SM
+trotting
+troubadour/MS
+trouble/DSMG
+troubled/U
+troublemaker/MS
+troubleshoot/DRZGS
+troubleshooter/M
+troubleshooting/M
+troubleshot
+troublesome/Y
+trough/M
+troughs
+trounce/DRSZG
+trouncer/M
+troupe/MZGDRS
+trouper/M
+trouser/SM
+trousers/M
+trousseau/M
+trousseaux
+trout/SM
+trove/SM
+trow/DSG
+trowel/MDSG
+troy/S
+truancy/M
+truant/GMDS
+truce/SM
+truck/SZGMDR
+trucker/M
+trucking/M
+truckle/MGDS
+truckload/SM
+truculence/M
+truculent/Y
+trudge/MGDS
+true/MTGDRS
+truelove/SM
+truffle/MS
+trug/S
+truism/MS
+truly/U
+trump/SGMD
+trumpery/M
+trumpet/ZGMDRS
+trumpeter/M
+truncate/GNDS
+truncation/M
+truncheon/SM
+trundle/MZGDRS
+trundler/M
+trunk/SGM
+truss/GMDS
+trust/ESGMD
+trustee/MS
+trusteeship/SM
+trustful/EY
+trustfulness/M
+trusting/Y
+trustworthiness/M
+trustworthy/TPR
+trusty/TRSM
+truth/ZMR
+truther/M
+truthful/UYP
+truthfulness/UM
+truthiness
+truths/U
+try's
+try/AGDS
+trying/Y
+tryout/SM
+tryptophan
+tryst/SMDG
+tsarists
+tsetse/MS
+tsp
+tsunami/SM
+ttys
+tub/SZGMDR
+tuba/MS
+tubal
+tubby/TR
+tube/MS
+tubeless/M
+tuber/M
+tubercle/SM
+tubercular
+tuberculin/M
+tuberculosis/M
+tuberculous
+tuberose/M
+tuberous
+tubful/MS
+tubing/M
+tubular
+tubule/MS
+tuck/MDRSZG
+tucker/MDG
+tuft/MDRSZG
+tufter/M
+tug/SM
+tugboat/MS
+tugged
+tugging
+tuition/IM
+tularemia/M
+tulip/SM
+tulle/M
+tum/S
+tumble/DRSMZG
+tumbledown
+tumbler/M
+tumbleweed/SM
+tumbling/M
+tumbrel/SM
+tumbril/SM
+tumescence/M
+tumescent
+tumid
+tumidity/M
+tummy/SM
+tumor/SM
+tumorous
+tumult/SM
+tumultuous/Y
+tun/SZGMDR
+tuna/MS
+tundra/SM
+tune/MS
+tuneful/YP
+tunefulness/M
+tuneless/Y
+tuner/M
+tuneup/SM
+tungsten/M
+tunic/SM
+tunnel/JSMDRZG
+tunneler/M
+tunny/SM
+tuple/S
+tuppence
+tuppenny
+tuque/SM
+turban/SMD
+turbid
+turbidity/M
+turbine/SM
+turbo/SM
+turbocharge/ZGDRS
+turbocharger/M
+turbofan/SM
+turbojet/SM
+turboprop/SM
+turbot/SM
+turbulence/M
+turbulent/Y
+turd/MS
+turducken/SM
+tureen/SM
+turf/MDSG
+turfy
+turgid/Y
+turgidity/M
+turkey/SM
+turmeric/SM
+turmoil/MS
+turn/AMDRSZG
+turnabout/SM
+turnaround/SM
+turnbuckle/SM
+turncoat/SM
+turner/AM
+turning/MS
+turnip/SM
+turnkey/MS
+turnoff/MS
+turnout/MS
+turnover/MS
+turnpike/MS
+turnstile/SM
+turntable/SM
+turpentine/M
+turpitude/M
+turps
+turquoise/SM
+turret/SMD
+turtle/SM
+turtledove/SM
+turtleneck/SMD
+tush/MS
+tusk/MDS
+tussle/DSMG
+tussock/MS
+tussocky
+tut/SM
+tutelage/M
+tutelary
+tutor/SMDG
+tutored/U
+tutorial/SM
+tutorship/M
+tutted
+tutti/SM
+tutting
+tutu/MS
+tux/MS
+tuxedo/SM
+twaddle/MZGDRS
+twaddler/M
+twain/M
+twang/SMDG
+twangy/RT
+twas
+twat/S
+tweak/SMDG
+twee
+tweed/SM
+tweeds/M
+tweedy/RT
+tween
+tweet's
+tweet/ASDG
+tweeter/SM
+tweezers/M
+twelfth/M
+twelfths
+twelve/SM
+twelvemonth/M
+twelvemonths
+twentieth/M
+twentieths
+twenty/SMH
+twerk/SDG
+twerp/SM
+twice
+twiddle/MGDS
+twiddly
+twig/MS
+twigged
+twigging
+twiggy/TR
+twilight/M
+twilit
+twill/MD
+twin/MDRSZG
+twine/SM
+twiner/M
+twinge/DSMG
+twinight
+twink/SY
+twinkle/MGJDS
+twinkling/M
+twinned
+twinning
+twinset/S
+twirl/SMDRZG
+twirler/M
+twirly
+twist's
+twist/USDG
+twister/MS
+twisty/TR
+twit/MS
+twitch/GMDS
+twitchy/RT
+twitted
+twitter/MDSG
+twittery
+twitting
+twixt
+two/SM
+twofer/SM
+twofold
+twopence/SM
+twopenny
+twosome/SM
+twp
+tycoon/SM
+tying/AU
+tyke/MS
+tympani/M
+tympanic
+tympanist/MS
+tympanum/SM
+type's
+type/AGDS
+typecast/GS
+typeface/MS
+typescript/MS
+typeset/S
+typesetter/MS
+typesetting/M
+typewrite/RSZG
+typewriter/M
+typewriting/M
+typewritten
+typewrote
+typhoid/M
+typhoon/MS
+typhus/M
+typical/UY
+typicality/M
+typification/M
+typify/NGDS
+typing/M
+typist/SM
+typo/MS
+typographer/SM
+typographic
+typographical/Y
+typography/M
+typology/SM
+tyrannic
+tyrannical/Y
+tyrannicidal
+tyrannicide/S
+tyrannize/GDS
+tyrannosaur/MS
+tyrannosaurus/MS
+tyrannous
+tyranny/SM
+tyrant/SM
+tyro/MS
+tzatziki
+u/S
+ubiquitous/Y
+ubiquity/M
+udder/SM
+ufologist/SM
+ufology/M
+ugh
+ugliness/M
+ugly/RTP
+uh
+uhf
+ukase/SM
+ukulele/SM
+ulcer/SM
+ulcerate/XDSGN
+ulceration/M
+ulcerous
+ulna/M
+ulnae
+ulnar
+ulster/MS
+ult
+ulterior
+ultimate/MY
+ultimatum/MS
+ultimo
+ultra/SM
+ultraconservative/SM
+ultrahigh
+ultralight/SM
+ultramarine/M
+ultramodern
+ultrasensitive
+ultrashort
+ultrasonic
+ultrasonically
+ultrasound/MS
+ultraviolet/M
+ululate/DSGNX
+ululation/M
+um
+umbel/SM
+umber/M
+umbilical
+umbilici
+umbilicus/M
+umbra/SM
+umbrage/M
+umbrella/SM
+umiak/SM
+umlaut/MS
+ump/SGMD
+umpire/MGDS
+umpteen/H
+unabridged/MS
+unacceptability
+unacceptable
+unaccommodating
+unaccountably
+unadventurous
+unaesthetic
+unalterably
+unambitious
+unanimity/M
+unanimous/Y
+unapparent
+unappetizing
+unappreciative
+unary
+unassertive
+unassimilable
+unassuming/Y
+unavailing/Y
+unaware/S
+unbeknown
+unbeknownst
+unbend/SG
+unbent
+unbid
+unblinking/Y
+unblushing/Y
+unbosom/DG
+unbound/D
+unbox/GDS
+unbreakable
+unbroken
+uncanny/T
+uncap/S
+uncaring
+unceasing/Y
+unchangeable
+uncharacteristic
+uncharitable
+unchaste/RT
+uncial/M
+uncle/SM
+unclean/DRPT
+uncleanly/T
+unclear/DRT
+uncomfortable
+uncommon/T
+uncompelling
+uncomplaining/Y
+uncomplicated
+uncomprehending/Y
+uncompromising/Y
+unconditional/Y
+uncongenial
+unconscionable
+unconscionably
+unconscious/M
+unconstitutional/Y
+uncontrollably
+uncontroversial
+uncool
+uncooperative
+uncouth/Y
+uncrushable
+unction/SM
+unctuous/YP
+unctuousness/M
+uncut
+undaunted/Y
+undecided/SM
+undemonstrative/Y
+undeniably
+under
+underachieve/LZGDRS
+underachiever/M
+underact/SDG
+underage
+underappreciated
+underarm/SM
+underbelly/SM
+underbid/S
+underbidding
+underbrush/M
+undercarriage/MS
+undercharge/MGDS
+underclass/MS
+underclassman/M
+underclassmen
+underclothes/M
+underclothing/M
+undercoat/GJSMD
+undercoating/M
+undercover
+undercurrent/SM
+undercut/SM
+undercutting
+underdeveloped
+underdevelopment/M
+underdog/SM
+underdone
+underemployed
+underemployment/M
+underestimate/DSMGNX
+underestimation/M
+underexpose/GDS
+underexposure/MS
+underfed
+underfeed/GS
+underfloor
+underflow
+underfoot
+underfunded
+underfur/M
+undergarment/SM
+undergo/G
+undergoes
+undergone
+undergrad/S
+undergraduate/SM
+underground/MS
+undergrowth/M
+underhand
+underhanded/PY
+underhandedness/M
+underinflated
+underlain
+underlay/SM
+underlie/S
+underline/MGDS
+underling/MS
+underlip/SM
+underlying
+undermanned
+undermentioned
+undermine/GDS
+undermost
+underneath/M
+underneaths
+undernourished
+undernourishment/M
+underpaid
+underpants/M
+underpart/MS
+underpass/MS
+underpay/GSL
+underpayment/SM
+underpin/S
+underpinned
+underpinning/MS
+underplay/DGS
+underpopulated
+underprivileged
+underproduction/M
+underrate/GDS
+underrepresented
+underscore/DSMG
+undersea/S
+undersecretary/SM
+undersell/GS
+undersexed
+undershirt/SM
+undershoot/SG
+undershorts/M
+undershot
+underside/MS
+undersign/DGS
+undersigned/M
+undersized
+underskirt/SM
+undersold
+understaffed
+understand/SGBJ
+understandably
+understanding/MY
+understate/DSLG
+understatement/SM
+understood
+understudy/GDSM
+undertake/ZGJRS
+undertaken
+undertaker/M
+undertaking/M
+underthings/M
+undertone/MS
+undertook
+undertow/SM
+underused
+underutilized
+undervaluation/M
+undervalue/DSG
+underwater
+underway
+underwear/M
+underweight/M
+underwent
+underwhelm/DGS
+underwire/DS
+underworld/MS
+underwrite/ZGRS
+underwriter/M
+underwritten
+underwrote
+undesirable/MS
+undies/M
+undo
+undoubted/Y
+undramatic
+undreamt
+undue
+undulant
+undulate/DSXGN
+undulation/M
+undying
+unearthliness/M
+unease/M
+uneasy/T
+uneatable
+uneconomic
+unemployed/M
+unending
+unenterprising
+unequal/DY
+unerring/Y
+unessential
+uneven/Y
+unexceptionably
+unexcited
+unexciting
+unexpected/YP
+unexpectedness/M
+unfailing/Y
+unfair/PTRY
+unfaltering
+unfamiliar
+unfathomably
+unfed
+unfeeling/Y
+unfeminine
+unfit/S
+unfitting
+unfix/GDS
+unflagging/Y
+unflappability/M
+unflappable
+unflappably
+unflattering
+unflinching/Y
+unforgettably
+unforgivably
+unfortunate/MS
+unfriendly/T
+unfrock/DG
+unfruitful
+unfunny
+ungainliness/M
+ungainly/RPT
+ungenerous
+ungentle
+ungodly/T
+ungraceful/Y
+ungrudging
+unguarded
+unguent/SM
+ungulate/MS
+unhandy/T
+unhappy/T
+unhealthful
+unhealthy/T
+unhistorical
+unholy/T
+unhurt
+unicameral
+unicellular
+unicorn/SM
+unicycle/SM
+unidirectional
+unification/AM
+uniform/SMDYG
+uniformity/M
+unify/AGDSN
+unilateral/Y
+unilateralism
+unimportant
+unimpressive
+uninformative
+uninhibited/Y
+uninsured
+unintelligent
+unintended
+uninteresting
+uninterrupted/Y
+uninterruptible
+uninviting
+union/ASM
+unionism/M
+unionist/MS
+unique/YTRP
+uniqueness/M
+unisex/M
+unison/M
+unitary
+unite/AEGSD
+unitedly
+unities
+unitize/DSG
+unity/EM
+univalent
+univalve/SM
+universal/MYS
+universalism
+universalist
+universality/M
+universalize/DSG
+universe/SM
+university/SM
+univocal
+unjust/Y
+unkempt
+unkind/T
+unkindly/T
+unknowable/M
+unknown/SM
+unleaded/M
+unless
+unlike/PB
+unlikely/T
+unlit
+unlock/DSG
+unlovable
+unlovely/TR
+unloving
+unlucky/T
+unmanly/T
+unmarried
+unmeaning
+unmentionable/MS
+unmentionables/M
+unmet
+unmindful
+unmissable
+unmistakably
+unmoral
+unmovable
+unmusical
+unnecessary
+unnerving/Y
+unobservant
+unoffensive
+unofficial/Y
+unoriginal
+unpeople
+unperceptive
+unpersuasive
+unpick/GDS
+unpin/S
+unpleasing
+unpolitical
+unpopular
+unpractical
+unprecedented/Y
+unprofessional/Y
+unpromising
+unpropitious
+unquestioning/Y
+unquiet/TR
+unread/B
+unready
+unreal
+unreasoning
+unregenerate
+unrelated
+unrelenting/Y
+unrelieved/Y
+unremarkable
+unremitting/Y
+unrepentant
+unreported
+unrepresentative
+unrest/M
+unrevealing
+unripe/TR
+unroll/GDS
+unromantic
+unruliness/M
+unruly/RTP
+unsafe/YTR
+unsavory
+unscathed
+unseeing/Y
+unseemly/T
+unseen/M
+unsentimental
+unset
+unshakable
+unshakably
+unshakeable
+unshapely
+unshockable
+unshorn
+unsightliness/M
+unsightly/PT
+unsmiling
+unsociable
+unsocial
+unsold
+unsound/PRYT
+unspeakable
+unspeakably
+unspecific
+unspectacular
+unsporting
+unstable
+unsteady/TRP
+unstinting/Y
+unstrapping
+unsubstantial
+unsubtle
+unsuitable
+unsure
+unsuspecting/Y
+unsymmetrical
+untactful
+unthinkably
+unthinking/Y
+untidy/PTR
+until
+untimely/T
+untiring/Y
+untouchable/MS
+untoward
+untrue/RT
+untrustworthy
+untruth/M
+unutterable
+unutterably
+unwarrantable
+unwary/T
+unwavering
+unwed
+unwelcome/G
+unwell
+unwieldiness/M
+unwieldy/TRP
+unwise/RYT
+unworried
+unworthy/T
+unwound
+unwrapping
+unyielding
+up/S
+upbeat/MS
+upbraid/SGD
+upbringing/MS
+upchuck/SGD
+upcoming
+upcountry/M
+update/MGDRS
+updraft/MS
+upend/SGD
+upfront
+upgrade/MGDS
+upheaval/MS
+upheld
+uphill/MS
+uphold/ZGRS
+upholder/M
+upholster/ASGD
+upholsterer/MS
+upholstery/M
+upkeep/M
+upland/MS
+uplift/JSMDG
+upload/SDG
+upmarket
+upmost
+upon
+upped
+upper/SM
+uppercase/M
+upperclassman/M
+upperclassmen
+upperclasswoman
+upperclasswomen
+uppercut/MS
+uppercutting
+uppermost
+upping
+uppish
+uppity
+upraise/DSG
+uprear/GSD
+upright/MYPS
+uprightness/M
+uprising/SM
+upriver
+uproar/SM
+uproarious/Y
+uproot/GSD
+upscale
+upset/SM
+upsetting
+upshot/SM
+upside/SM
+upsilon/MS
+upstage/GDS
+upstairs
+upstanding
+upstart/MDSG
+upstate/M
+upstream
+upstroke/SM
+upsurge/MGDS
+upswing/MS
+uptake/SM
+uptempo
+upthrust/GSM
+uptick/SM
+uptight
+uptown/M
+uptrend
+upturn/GSMD
+upward/SY
+upwind
+uracil/M
+uranium/M
+urban
+urbane/RYT
+urbanity/M
+urbanization/M
+urbanize/DSG
+urbanologist/MS
+urbanology/M
+urchin/SM
+urea/M
+uremia/M
+uremic
+ureter/SM
+urethane/M
+urethra/M
+urethrae
+urethral
+urge/MGDS
+urgency/M
+urgent/Y
+uric
+urinal/SM
+urinalyses
+urinalysis/M
+urinary
+urinate/GNDS
+urination/M
+urine/M
+urn/SM
+urogenital
+urological
+urologist/MS
+urology/M
+ursine
+urticaria/M
+usability/M
+usable/UA
+usage/SM
+use/AEDSMG
+used/U
+useful/PY
+usefulness/M
+useless/YP
+uselessness/M
+user/MS
+username/MS
+usher/SMDG
+usherette/SM
+usu
+usual's
+usual/UY
+usurer/SM
+usurious
+usurp/SDRZG
+usurpation/M
+usurper/M
+usury/M
+utensil/SM
+uteri
+uterine
+uterus/M
+utilitarian/MS
+utilitarianism/M
+utility/SM
+utilization/M
+utilize/GBDS
+utmost/M
+utopia/SM
+utopian/MS
+utter/SDYG
+utterance/SM
+uttermost/M
+uveitis
+uvula/SM
+uvular/MS
+uxorious
+v/AS
+vac/S
+vacancy/SM
+vacant/Y
+vacate/DSG
+vacation/ZGMDRS
+vacationer/M
+vacationist/SM
+vaccinate/GNDSX
+vaccination/M
+vaccine/SM
+vacillate/XGNDS
+vacillation/M
+vacuity/M
+vacuole/MS
+vacuous/YP
+vacuousness/M
+vacuum/GSMD
+vagabond/SMDG
+vagabondage/M
+vagarious
+vagary/SM
+vagina/SM
+vaginae
+vaginal/Y
+vaginitis
+vagrancy/M
+vagrant/MS
+vague/RYTP
+vagueness/M
+vagus
+vain/RYT
+vainglorious/Y
+vainglory/M
+val
+valance/MS
+vale/MS
+valediction/MS
+valedictorian/SM
+valedictory/SM
+valence/MS
+valency/SM
+valentine/SM
+valet/SMDG
+valetudinarian/MS
+valetudinarianism/M
+valiance/M
+valiant/Y
+valid/Y
+validate/IGNDS
+validation/IM
+validations
+validity/IM
+validness/M
+valise/SM
+valley/SM
+valor/M
+valorous/Y
+valuable/MS
+valuate/DSG
+valuation/CAMS
+value's
+value/CAGSD
+valueless
+valuer/SM
+valve/DSMG
+valveless
+valvular
+vamoose/DSG
+vamp/AMDGS
+vampire/SM
+van/SM
+vanadium/M
+vandal/SM
+vandalism/M
+vandalize/DSG
+vane/MS
+vanguard/MS
+vanilla/SM
+vanish/JDSG
+vanity/SM
+vanned
+vanning
+vanquish/ZGDRS
+vanquisher/M
+vantage/SM
+vape/GDS
+vapid/YP
+vapidity/M
+vapidness/M
+vapor/SM
+vaporization/M
+vaporize/DRSZG
+vaporizer/M
+vaporous
+vaporware
+vapory
+vaquero/MS
+var/S
+variability/IM
+variable/ISM
+variably/I
+variance/SM
+variant/MS
+variate/NX
+variation/M
+varicolored
+varicose
+varied/U
+variegate/DSGN
+variegation/M
+varietal/SM
+variety/SM
+various/Y
+varlet/SM
+varmint/MS
+varnish/GMDS
+varnished/U
+varsity/SM
+vary/DSG
+varying/U
+vascular
+vase/MS
+vasectomy/SM
+vasoconstriction
+vasomotor
+vassal/SM
+vassalage/M
+vast/MRYTSP
+vastness/M
+vat/SM
+vatted
+vatting
+vaudeville/M
+vaudevillian/MS
+vault/SMDRZG
+vaulter/M
+vaulting/M
+vaunt/SMDG
+vb
+veal/M
+vector/SGMD
+veejay/SM
+veep/MS
+veer/MDGS
+veg/SM
+vegan/SM
+veganism
+vegeburger/S
+veges
+vegetable/SM
+vegetarian/SM
+vegetarianism/M
+vegetate/GNVDS
+vegetation/M
+vegged
+vegges
+veggie/SM
+veggieburger/S
+vegging
+vehemence/M
+vehemency/M
+vehement/Y
+vehicle/MS
+vehicular
+veil's
+veil/UDGS
+vein/MDGS
+vela
+velar/SM
+veld/MS
+vellum/M
+velocipede/MS
+velocity/SM
+velodrome/S
+velour/MS
+velum/M
+velvet/M
+velveteen/M
+velvety
+venal/Y
+venality/M
+venation/M
+vend/DGS
+vendetta/SM
+vendible
+vendor/MS
+veneer/MDGS
+venerability/M
+venerable
+venerate/DSGN
+veneration/M
+venereal
+vengeance/M
+vengeful/AY
+venial
+venireman/M
+veniremen
+venison/M
+venom/M
+venomous/Y
+venous
+vent's
+vent/DGS
+ventilate/GNDS
+ventilation/M
+ventilator/SM
+ventilatory
+ventral
+ventricle/SM
+ventricular
+ventriloquism/M
+ventriloquist/SM
+ventriloquy/M
+venture/DSMG
+venturesome/PY
+venturesomeness/M
+venturous/PY
+venturousness/M
+venue/ASM
+veracious/Y
+veracity/M
+veranda/SM
+verandah/M
+verandahs
+verapamil
+verb/KMS
+verbal/MYS
+verbalization/M
+verbalize/GDS
+verbatim
+verbena/SM
+verbiage/MS
+verbose/Y
+verbosity/M
+verboten
+verdant/Y
+verdict/SM
+verdigris/GMDS
+verdure/M
+verge's
+verge/FDSG
+verger/MS
+verifiable/U
+verification/M
+verified/U
+verify/DSNG
+verily
+verisimilitude/M
+veritable
+veritably
+verity/SM
+vermicelli/M
+vermiculite/M
+vermiform
+vermilion/M
+vermin/M
+verminous
+vermouth/M
+vernacular/MS
+vernal
+vernier/SM
+veronica/M
+verruca/SM
+verrucae
+versa
+versatile
+versatility/M
+verse/AFNGMSDX
+versed/U
+versification/M
+versifier/M
+versify/ZGNDRS
+version/AFIMS
+versioned
+versioning
+verso/SM
+versus
+vert/A
+vertebra/M
+vertebrae
+vertebral
+vertebrate/IMS
+vertex/MS
+vertical/MYS
+vertices
+vertiginous
+vertigo/M
+verve/M
+very/RT
+vesicle/SM
+vesicular
+vesiculate
+vesper/MS
+vessel/MS
+vest's
+vest/ILDGS
+vestal/MS
+vestibule/MS
+vestige/SM
+vestigial/Y
+vesting/M
+vestment/IMS
+vestry/SM
+vestryman/M
+vestrymen
+vet/SM
+vetch/MS
+veteran/SM
+veterinarian/MS
+veterinary/SM
+veto/MDG
+vetoes
+vetted
+vetting
+vex/GDS
+vexation/SM
+vexatious/Y
+vhf
+vi
+via
+viability/M
+viable
+viably
+viaduct/SM
+vial/MS
+viand/SM
+vibe/MS
+vibes/M
+vibraharp/SM
+vibrancy/M
+vibrant/Y
+vibraphone/MS
+vibraphonist/MS
+vibrate/GNDSX
+vibration/M
+vibrato/MS
+vibrator/SM
+vibratory
+viburnum/SM
+vicar/SM
+vicarage/SM
+vicarious/YP
+vicariousness/M
+vice/CMS
+viced
+vicegerent/SM
+vicennial
+viceregal
+viceroy/MS
+vichyssoise/M
+vicing
+vicinity/M
+vicious/YP
+viciousness/M
+vicissitude/SM
+victim/MS
+victimization/M
+victimize/GDS
+victimless
+victor/MS
+victorious/Y
+victory/SM
+victual/SMDG
+vicuna/MS
+vicu単a/MS
+videlicet
+video/GSMD
+videocassette/SM
+videoconferencing
+videodisc/MS
+videophone/MS
+videotape/DSMG
+videotex
+vie/DS
+view/AMDRSZG
+viewable
+viewer/AM
+viewership/M
+viewfinder/SM
+viewing/SM
+viewpoint/MS
+vigesimal
+vigil/SM
+vigilance/M
+vigilant/Y
+vigilante/SM
+vigilantism/M
+vigilantist/M
+vignette/DSMG
+vignettist/MS
+vigor/M
+vigorous/Y
+vii
+viii
+viking/MS
+vile/YTPR
+vileness/M
+vilification/M
+vilify/DSNG
+villa/SM
+village/RSMZ
+villager/M
+villain/SM
+villainous
+villainy/SM
+villein/SM
+villeinage/M
+villi
+villus/M
+vim/M
+vinaigrette/M
+vincible/I
+vindicate/XDSGN
+vindication/M
+vindicator/MS
+vindictive/PY
+vindictiveness/M
+vine/MS
+vinegar/M
+vinegary
+vineyard/MS
+vino/M
+vinous
+vintage/MS
+vintner/MS
+vinyl/SM
+viol/MBS
+viola/SM
+violable/I
+violate/GNDSX
+violation/M
+violator/SM
+violence/M
+violent/Y
+violet/MS
+violin/MS
+violincello/S
+violinist/SM
+violist/MS
+violoncellist/SM
+violoncello/MS
+viper/SM
+viperous
+virago/M
+viragoes
+viral
+vireo/SM
+virgin/MS
+virginal/SM
+virginity/M
+virgule/MS
+virile
+virility/M
+virologist/SM
+virology/M
+virtual/Y
+virtualization
+virtue/SM
+virtuosity/M
+virtuoso/SM
+virtuous/YP
+virtuousness/M
+virulence/M
+virulent/Y
+virus/MS
+visa/MDSG
+visage/MS
+viscera
+visceral/Y
+viscid
+viscose/M
+viscosity/M
+viscount/SM
+viscountcy/SM
+viscountess/MS
+viscous
+viscus/M
+vise/ACMGDS
+visibility/IM
+visible/I
+visibly/I
+vision/KGDSM
+visionary/SM
+visit's
+visit/ASGD
+visitant/MS
+visitation/MS
+visitor/MS
+visor/SM
+vista/SM
+visual/SMY
+visualization/SM
+visualize/DRSZG
+visualizer/M
+vita/M
+vitae
+vital/SY
+vitality/M
+vitalization/AM
+vitalize/CAGSD
+vitals/M
+vitamin/MS
+vitiate/GNDS
+vitiation/M
+viticulture/M
+viticulturist/MS
+vitreous
+vitrifaction/M
+vitrification/M
+vitrify/GNDS
+vitrine/SM
+vitriol/M
+vitriolic
+vitriolically
+vittles/M
+vituperate/GNVDS
+vituperation/M
+viva/MS
+vivace
+vivacious/PY
+vivaciousness/M
+vivacity/M
+vivaria
+vivarium/SM
+vivid/RYTP
+vividness/M
+vivify/ADSG
+viviparous
+vivisect/DGS
+vivisection/M
+vivisectional
+vivisectionist/SM
+vixen/SM
+vixenish/Y
+viz
+vizier/SM
+vlf
+vocab
+vocable/MS
+vocabulary/SM
+vocal/SMY
+vocalic
+vocalist/SM
+vocalization/MS
+vocalize/DSG
+vocation/FIKASM
+vocational/Y
+vocative/MS
+vociferate/DSGN
+vociferation/M
+vociferous/YP
+vociferousness/M
+vodka/SM
+vogue/SM
+voguish
+voice/IDSMG
+voiced/U
+voiceless/PY
+voicelessness/M
+voicemail/SM
+void/MDSGB
+voila
+voile/M
+voil
+vol/S
+volatile
+volatility/M
+volatilize/DSG
+volcanic
+volcanism
+volcano/M
+volcanoes
+vole/MS
+volition/M
+volitional
+volley/GSMD
+volleyball/MS
+volt/AMS
+voltage/MS
+voltaic
+voltmeter/SM
+volubility/M
+voluble
+volubly
+volume/SM
+volumetric
+voluminous/YP
+voluminousness/M
+voluntarily/I
+voluntarism/M
+voluntary/SM
+volunteer/SGMD
+volunteerism/M
+voluptuary/SM
+voluptuous/PY
+voluptuousness/M
+volute/SM
+vomit/SMDG
+voodoo/GSMD
+voodooism/M
+voracious/PY
+voraciousness/M
+voracity/M
+vortex/MS
+votary/SM
+vote's
+vote/CGVDS
+voter/SM
+vouch/DRSZG
+voucher/M
+vouchsafe/DSG
+vow/SGMD
+vowel/SM
+voyage/MZGDRS
+voyager/M
+voyageur/SM
+voyeur/MS
+voyeurism/M
+voyeuristic
+vulcanism
+vulcanization/M
+vulcanize/GDS
+vulgar/RYT
+vulgarian/MS
+vulgarism/MS
+vulgarity/SM
+vulgarization/M
+vulgarize/ZGDRS
+vulgarizer/M
+vulnerabilities
+vulnerability/IM
+vulnerable/I
+vulnerably/I
+vulpine
+vulture/SM
+vulturous
+vulva/M
+vulvae
+vuvuzela/MS
+vying
+w/DNXTGVJ
+wabbit/S
+wack/MRTS
+wackiness/M
+wacko/SM
+wacky/RPT
+wad/SZGMDR
+wadded
+wadding/M
+waddle/DSMG
+wade/MS
+wader/M
+waders/M
+wadge/S
+wadi/MS
+wafer/SM
+waffle/MZGDRS
+waffler/M
+waft/MDGS
+wag/SZGMDR
+wage/MS
+waged/U
+wager/ZGMDR
+wagerer/M
+wagged
+waggery/SM
+wagging
+waggish/YP
+waggishness/M
+waggle/MGDS
+wagon/ZSMR
+wagoner/M
+wagtail/SM
+waif/MS
+wail/MDRZGS
+wailer/M
+wailing/M
+wain/MS
+wainscot/SJMDG
+wainscoting/M
+wainscotted
+wainscotting/MS
+wainwright/MS
+waist/SM
+waistband/MS
+waistcoat/MS
+waistline/MS
+wait/MDRZGS
+waiter/M
+waiting/M
+waitperson/MS
+waitress/MS
+waitstaff/M
+waive/DRSZG
+waiver/M
+wake/MGJDS
+wakeful/PY
+wakefulness/M
+waken/GSD
+waldo/S
+waldoes
+wale/MGDS
+walk/MDRZGS
+walkabout/S
+walkaway/MS
+walker/M
+walkies
+walking/M
+walkout/SM
+walkover/MS
+walkway/SM
+wall/MDGS
+wallaby/SM
+wallah
+wallahs
+wallboard/M
+wallet/MS
+walleye/DSM
+wallflower/MS
+wallop/MDSJG
+walloping/M
+wallow/MDSG
+wallpaper/SMDG
+wally/S
+walnut/MS
+walrus/MS
+waltz/ZGMDRS
+waltzer/M
+wampum/M
+wan/GPDY
+wand/MS
+wander/DRSJZG
+wanderer/M
+wanderings/M
+wanderlust/SM
+wane/MS
+wangle/MZGDRS
+wangler/M
+wank/DRZGS
+wanna
+wannabe/SM
+wannabee/S
+wanner
+wanness/M
+wannest
+want/MDGS
+wanted/U
+wanton/MDYSPG
+wantonness/M
+wapiti/MS
+war/SM
+warble/MZGDRS
+warbler/M
+warbonnet/SM
+ward/AMDGS
+warden/MS
+warder/MS
+wardress/S
+wardrobe/SM
+wardroom/SM
+ware/MS
+warehouse/DSMG
+warez
+warfare/M
+warfarin
+warhead/MS
+warhorse/SM
+warily/U
+wariness/UM
+warlike
+warlock/MS
+warlord/MS
+warm/PDRYHZTGS
+warmblooded
+warmer/M
+warmhearted/P
+warmheartedness/M
+warmish
+warmness/M
+warmonger/SMG
+warmongering/M
+warmth/M
+warmup/MS
+warn/JDGS
+warning/M
+warp/MDGS
+warpaint
+warpath/M
+warpaths
+warplane/MS
+warrant/GMDS
+warranted/U
+warranty/DSMG
+warred
+warren/MS
+warring
+warrior/SM
+warship/SM
+wart/MS
+warthog/SM
+wartime/M
+warty/TR
+wary/UPRT
+was
+wasabi
+wash/BJMDRSZG
+washable/SM
+washbasin/SM
+washboard/SM
+washbowl/SM
+washcloth/M
+washcloths
+washed/U
+washer/M
+washerwoman/M
+washerwomen
+washing/M
+washout/MS
+washrag/MS
+washroom/MS
+washstand/SM
+washtub/MS
+washy/TR
+wasn't
+wasp/MS
+waspish/YP
+waspishness/M
+wassail/SMDG
+wast
+wastage/M
+waste/DRSMZG
+wastebasket/MS
+wasteful/PY
+wastefulness/M
+wasteland/SM
+wastepaper/M
+waster/M
+wastewater
+wastrel/SM
+watch/BZGMDRS
+watchable/U
+watchband/MS
+watchdog/SM
+watcher/M
+watchful/YP
+watchfulness/M
+watchmaker/MS
+watchmaking/M
+watchman/M
+watchmen
+watchstrap/S
+watchtower/SM
+watchword/MS
+water/GSMD
+waterbed/MS
+waterbird/SM
+waterboard/MDJSG
+waterboarding/M
+waterborne
+watercolor/MS
+watercourse/SM
+watercraft/M
+watercress/M
+waterfall/SM
+waterfowl/SM
+waterfront/MS
+waterhole/SM
+wateriness/M
+waterlily/SM
+waterline/MS
+waterlogged
+watermark/MDGS
+watermelon/SM
+watermill/MS
+waterpower/M
+waterproof/SMDG
+waterproofing/M
+waters/M
+watershed/MS
+waterside/MS
+waterspout/SM
+watertight
+waterway/MS
+waterwheel/SM
+waterworks/M
+watery/PTR
+watt/MS
+wattage/M
+wattle/MGDS
+wave/MZGDRS
+waveband/S
+waveform
+wavefront
+wavelength/M
+wavelengths
+wavelet/SM
+wavelike
+waver/ZGMDR
+waverer/M
+wavering/Y
+waviness/M
+wavy/PRT
+wax/GMDNS
+waxiness/M
+waxwing/SM
+waxwork/SM
+waxy/RPT
+way/SM
+waybill/SM
+wayfarer/MS
+wayfaring/SM
+waylaid
+waylay/RSZG
+waylayer/M
+wayside/SM
+wayward/PY
+waywardness/M
+wazoo/S
+we
+we'd
+we'll
+we're
+we've
+weak/PNRYXT
+weaken/DRZG
+weakener/M
+weakfish/MS
+weakish
+weakling/SM
+weakness/MS
+weal/MHS
+wealth/M
+wealthiness/M
+wealthy/TRP
+wean/DGS
+weapon/MS
+weaponize/GDS
+weaponless
+weaponry/M
+wear/MRBJSZG
+wearable/U
+wearer/M
+wearied/U
+wearily
+weariness/M
+wearisome/Y
+weary/TGDRSP
+weasel/MDYSG
+weather/SMDG
+weatherboard/SG
+weathercock/MS
+weathering/M
+weatherization/M
+weatherize/DSG
+weatherman/M
+weathermen
+weatherperson/MS
+weatherproof/GSD
+weatherstrip/S
+weatherstripped
+weatherstripping/M
+weave/DRSMZG
+weaver/M
+weaving/M
+web/SM
+webbed
+webbing/M
+webcam/MS
+webcast/SMG
+webfeet
+webfoot/M
+webinar/SM
+webisode/MS
+weblog/MS
+webmaster/SM
+webmistress/MS
+website/SM
+wed/AS
+wedded/A
+wedder
+wedding/SM
+wedge/DSMG
+wedgie/MS
+wedlock/M
+wee/RSMT
+weed/MDRSZG
+weeder/M
+weedkiller/S
+weedless
+weedy/TR
+weeing
+week/MYS
+weekday/SM
+weekend/SZGMDR
+weekly/SM
+weeknight/SM
+ween/DSG
+weenie/MTRS
+weensy/RT
+weeny
+weep/MRJSZG
+weeper/M
+weepie
+weepy/TRSM
+weevil/MS
+weft/MS
+weigh's
+weigh/AGD
+weighbridge/S
+weighs/A
+weight/MDSJG
+weighted/U
+weightily
+weightiness/M
+weightless/YP
+weightlessness/M
+weightlifter/MS
+weightlifting/M
+weighty/PTR
+weir/MS
+weird/PTRY
+weirdie/MS
+weirdness/M
+weirdo/MS
+welcome/MGDS
+weld/MDRBSZG
+welder/M
+welfare/M
+welkin/M
+well/MDPSG
+wellhead/SM
+wellie
+wellington/MS
+wellness/M
+wellspring/MS
+welly/S
+welsh/ZGDRS
+welsher/M
+welt/MDRSZG
+welter/GMD
+welterweight/SM
+wen/M
+wench/MS
+wend/DSG
+went
+wept
+were
+weren't
+werewolf/M
+werewolves
+west/M
+westbound
+westerly/SM
+western/SZMR
+westerner/M
+westernization/M
+westernize/GDS
+westernmost
+westward/S
+wet/SMYP
+wetback/SM
+wetland/SM
+wetness/M
+wetter/SM
+wettest
+wetting
+wetware/S
+whack/SJZGMDR
+whacker/M
+whale/DRSMZG
+whaleboat/MS
+whalebone/M
+whaler/M
+whaling/M
+wham/MS
+whammed
+whamming
+whammy/SM
+wharf/M
+wharves
+what/MS
+whatchamacallit/MS
+whatever
+whatnot/M
+whatshername
+whatshisname
+whatsit/S
+whatsoever
+wheal/SM
+wheat/MN
+wheatgerm
+wheatmeal
+whee
+wheedle/DRSZG
+wheedler/M
+wheel/SMDRG
+wheelbarrow/SM
+wheelbase/SM
+wheelchair/SM
+wheelhouse/MS
+wheelie/SM
+wheelwright/MS
+wheeze/DSMG
+wheezily
+wheeziness/M
+wheezy/PRT
+whelk/SMD
+whelm/SDG
+whelp/SMDG
+when/MS
+whence
+whenever
+whensoever
+where/SM
+whereabouts/M
+whereas
+whereat
+whereby
+wherefore/MS
+wherein
+whereof
+whereon
+wheresoever
+whereto
+whereupon
+wherever
+wherewith
+wherewithal/M
+wherry/SM
+whet/S
+whether
+whetstone/SM
+whetted
+whetting
+whew
+whey/M
+which
+whichever
+whiff/SMDG
+whiffletree/MS
+while/DSMG
+whilom
+whilst
+whim/MS
+whimper/MDGS
+whimsical/Y
+whimsicality/M
+whimsy/SM
+whine/DRSMZG
+whiner/M
+whinge/DRSZG
+whingeing
+whinny/GDSM
+whiny/RT
+whip/MS
+whipcord/M
+whiplash/MS
+whipped
+whipper/MS
+whippersnapper/MS
+whippet/MS
+whipping/SM
+whippletree/SM
+whippoorwill/MS
+whipsaw/MDGS
+whir/MS
+whirl/SMDG
+whirligig/MS
+whirlpool/MS
+whirlwind/MS
+whirlybird/SM
+whirred
+whirring
+whisk/SMDRZG
+whisker/MD
+whiskery
+whiskey/MS
+whisky/SM
+whiskys
+whisper/MDRSZG
+whisperer/M
+whist/M
+whistle/MZGDRS
+whistler/M
+whit/MDNRSXTGJ
+white/SPM
+whitebait
+whiteboard/S
+whitecap/SM
+whitefish/MS
+whitehead/MS
+whitelist/GDS
+whiten/ZGDRJ
+whitener/M
+whiteness/M
+whitening/M
+whiteout/SM
+whitetail/MS
+whitewall/SM
+whitewash/MDSG
+whitewater/M
+whitey/SM
+whither
+whiting/M
+whitish
+whittle/ZGDRS
+whittler/M
+whiz/M
+whizkid/M
+whizz/MDSG
+whizzbang/MS
+who'd
+who'll
+who're
+who've
+who/M
+whoa
+whodunit/MS
+whoever
+whole/SMP
+wholefood/S
+wholegrain
+wholehearted/YP
+wholeheartedness/M
+wholemeal
+wholeness/M
+wholesale/MZGDRS
+wholesaler/M
+wholesome/UP
+wholesomely
+wholesomeness/UM
+wholewheat
+wholly
+whom
+whomever
+whomsoever
+whoop/SMDRZG
+whoopee/S
+whooper/M
+whoosh/MDSG
+whop/S
+whopped
+whopper/SM
+whopping
+whore/SMG
+whorehouse/MS
+whoreish
+whorish
+whorl/SMD
+whose
+whoso
+whosoever
+whup/S
+whupped
+whupping
+why'd
+why/M
+whys
+wick/MDRSZ
+wicked/TPRY
+wickedness/M
+wicker/M
+wickerwork/M
+wicket/SM
+wide/YTRP
+widemouthed
+widen/SDRZG
+widener/M
+wideness/M
+widescreen/MS
+widespread
+widgeon/MS
+widget/S
+widow/SMDRZG
+widower/M
+widowhood/M
+width/M
+widths
+wield/SDRZG
+wielder/M
+wiener/SM
+wienie/SM
+wife/MY
+wifeless
+wig/SM
+wigeon/SM
+wigged
+wigging
+wiggle/DRSMZG
+wiggler/M
+wiggly/TR
+wight/SM
+wiglet/SM
+wigwag/SM
+wigwagged
+wigwagging
+wigwam/SM
+wiki/MS
+wild/MRYSTP
+wildcard/MS
+wildcat/MS
+wildcatted
+wildcatter/MS
+wildcatting
+wildebeest/MS
+wilderness/MS
+wildfire/MS
+wildflower/SM
+wildfowl/M
+wildlife/M
+wildness/M
+wilds/M
+wile/MGDS
+wilful/P
+wilfulness/M
+wiliness/M
+will/MDS
+willful/PY
+willfulness/M
+willies/M
+willing/UPY
+willingness/UM
+williwaw/MS
+willow/SM
+willowy
+willpower/M
+willy/S
+wilt/MDSG
+wily/RTP
+wimp/MDSG
+wimpish
+wimple/DSMG
+wimpy/RT
+win/SGMD
+wince/DSMG
+winch/MDSG
+wind's
+wind/UASG
+windbag/SM
+windblown
+windbreak/SZMR
+windbreaker/M
+windburn/MD
+windcheater/S
+windchill/M
+winded
+winder/SM
+windfall/MS
+windflower/MS
+windily
+windiness/M
+winding's
+windjammer/SM
+windlass/MS
+windless
+windmill/MDGS
+window/SMDG
+windowless
+windowpane/SM
+windowsill/SM
+windpipe/MS
+windproof
+windrow/SM
+windscreen/SM
+windshield/SM
+windsock/MS
+windstorm/MS
+windsurf/ZGDRS
+windsurfer/M
+windsurfing/M
+windswept
+windup/SM
+windward/M
+windy/RTP
+wine/MS
+wineglass/MS
+winegrower/MS
+winemaker/MS
+winery/SM
+wing/MDRZG
+wingding/MS
+wingless
+winglike
+wingnut/SM
+wingspan/MS
+wingspread/SM
+wingtip/SM
+wink/MDRSZG
+winker/M
+winkle/DSMG
+winnable/U
+winner/SM
+winning/MYS
+winnow/ZGSDR
+winnower/M
+wino/MS
+winsome/YTRP
+winsomeness/M
+winter/GSMD
+wintergreen/M
+winterize/GDS
+wintertime/M
+wintry/TR
+winy/RT
+wipe/MZGDRS
+wiper/M
+wire's
+wire/AGDS
+wired/S
+wirehair/MS
+wireless/MS
+wiretap/MS
+wiretapped
+wiretapper/SM
+wiretapping/M
+wiriness/M
+wiring/M
+wiry/RTP
+wisdom/M
+wise/MYTGDRS
+wiseacre/SM
+wisecrack/MDSG
+wiseguy/S
+wish/MDRSZG
+wishbone/SM
+wisher/M
+wishful/Y
+wishlist's
+wisp/MS
+wispy/RT
+wist
+wisteria/SM
+wistful/YP
+wistfulness/M
+wit/SM
+witch/MDSG
+witchcraft/M
+witchery/M
+with
+withal
+withdraw/SG
+withdrawal/MS
+withdrawn
+withdrew
+withe/DRSMZG
+wither/JGD
+withering/Y
+withers/M
+withheld
+withhold/SG
+withholding/M
+within/M
+without
+withstand/GS
+withstood
+witless/PY
+witlessness/M
+witness/MDSG
+wits/M
+witted
+witter/SGD
+witticism/SM
+wittily
+wittiness/M
+witting/UY
+witty/RPT
+wive/GDS
+wiz/S
+wizard/SMY
+wizardry/M
+wizened
+wk/Y
+woad/M
+wobble/MGDS
+wobbliness/M
+wobbly/RTP
+wodge/S
+woe/SM
+woebegone
+woeful/YP
+woefuller
+woefullest
+woefulness/M
+wog/S
+wok/SMN
+woke
+wold/MS
+wolf/MDSG
+wolfhound/SM
+wolfish
+wolfram/M
+wolverine/SM
+wolves
+woman/M
+womanhood/M
+womanish
+womanize/DRSZG
+womanizer/M
+womankind/M
+womanlike/M
+womanliness/M
+womanly/RPT
+womb/MS
+wombat/MS
+womble/S
+women/M
+womenfolk/SM
+womenfolks/M
+won't
+won/M
+wonder/MDGLS
+wonderful/YP
+wonderfulness/M
+wondering/Y
+wonderland/MS
+wonderment/M
+wondrous/Y
+wonk/MS
+wonky/TR
+wont/MD
+wonted/U
+woo/SZGDR
+wood/MDNSG
+woodbine/M
+woodblock/MS
+woodcarver/MS
+woodcarving/SM
+woodchuck/MS
+woodcock/SM
+woodcraft/M
+woodcut/SM
+woodcutter/SM
+woodcutting/M
+wooden/RYTP
+woodenness/M
+woodiness/M
+woodland/SM
+woodlice
+woodlot/SM
+woodlouse
+woodman/M
+woodmen
+woodpecker/MS
+woodpile/SM
+woods/M
+woodshed/SM
+woodsiness/M
+woodsman/M
+woodsmen
+woodsy/RTP
+woodwind/MS
+woodwork/MRZG
+woodworker/M
+woodworking/M
+woodworm/S
+woody/TPRSM
+wooer/M
+woof/MDRSZG
+woofer/M
+wool/MNX
+woolen/M
+woolgathering/M
+wooliness
+woolliness/M
+woolly/RSMPT
+woozily
+wooziness/M
+woozy/TRP
+wop/S!
+word's
+word/ADSG
+wordage/M
+wordbook/SM
+wordily
+wordiness/M
+wording/SM
+wordless/Y
+wordplay/M
+wordsmith
+wordsmiths
+wordy/TPR
+wore
+work's
+work/ADJSG
+workable/U
+workaday
+workaholic/SM
+workaround/S
+workbasket/S
+workbench/MS
+workbook/MS
+workday/SM
+worker/MS
+workfare/M
+workflow/MS
+workforce/M
+workhorse/SM
+workhouse/SM
+working's
+workingman/M
+workingmen
+workings/M
+workingwoman/M
+workingwomen
+workload/MS
+workman/M
+workmanlike
+workmanship/M
+workmate/S
+workmen
+workout/SM
+workplace/MS
+workroom/MS
+works/M
+worksheet/MS
+workshop/MS
+workshy
+worksite/S
+workspace
+workstation/MS
+worktable/MS
+worktop/S
+workup/MS
+workweek/SM
+world/SM
+worldlier
+worldliness/UM
+worldly/UTP
+worldview/SM
+worldwide
+worm/MDSG
+wormhole/MS
+wormwood/M
+wormy/TR
+worn/U
+worried/Y
+worrier/M
+worriment/M
+worrisome
+worry/ZGDRSMJ
+worrying/Y
+worrywart/SM
+worse/M
+worsen/DSG
+worship/ZGSMDR
+worshiper/M
+worshipful
+worst/SGMD
+worsted/M
+wort/M
+worth/M
+worthies
+worthily/U
+worthiness/UM
+worthless/PY
+worthlessness/M
+worthwhile
+worthy's
+worthy/UPRT
+wot
+wotcha
+would've
+would/S
+wouldn't
+wouldst
+wound/SGMDR
+wove/A
+woven/AU
+wow/SGMD
+wpm
+wrack/GSMD
+wraith/M
+wraiths
+wrangle/DRSMZGJ
+wrangler/M
+wrap's
+wrap/US
+wraparound/SM
+wrapped/U
+wrapper/SM
+wrapping/MS
+wrasse/MS
+wrath/M
+wrathful/Y
+wreak/SGD
+wreath/MDSG
+wreathe
+wreaths
+wreck/SZGMDR
+wreckage/M
+wrecker/M
+wren/MS
+wrench/MDSG
+wrest/SGMD
+wrestle/MZGDRS
+wrestler/M
+wrestling/M
+wretch/MS
+wretched/TPRY
+wretchedness/M
+wriggle/MZGDRS
+wriggler/M
+wriggly
+wright/MS
+wring/SZGMR
+wringer/M
+wrinkle/MGDS
+wrinkled/U
+wrinkly/TRSM
+wrist/SM
+wristband/MS
+wristwatch/MS
+writ/MRBJSZG
+write/S
+writer/M
+writhe/MGDS
+writing/M
+written/AU
+wrong/STGMPDRY
+wrongdoer/SM
+wrongdoing/SM
+wrongful/PY
+wrongfulness/M
+wrongheaded/YP
+wrongheadedness/M
+wrongness/M
+wrote/A
+wroth
+wrought
+wrung
+wry/Y
+wryer
+wryest
+wryness/M
+wt
+wunderkind/S
+wurst/SM
+wuss/MS
+wussy/RSMT
+x
+xci
+xcii
+xciv
+xcix
+xcvi
+xcvii
+xenon/M
+xenophobe/MS
+xenophobia/M
+xenophobic
+xerographic
+xerography/M
+xerox/MDSG
+xi/SM
+xii
+xiii
+xiv
+xix
+xor
+xref/S
+xterm/M
+xv
+xvi
+xvii
+xviii
+xx
+xxi
+xxii
+xxiii
+xxiv
+xxix
+xxv
+xxvi
+xxvii
+xxviii
+xxx
+xxxi
+xxxii
+xxxiii
+xxxiv
+xxxix
+xxxv
+xxxvi
+xxxvii
+xxxviii
+xylem/M
+xylene
+xylophone/SM
+xylophonist/MS
+y
+y'all
+ya
+yacht/SMDG
+yachting/M
+yachtsman/M
+yachtsmen
+yachtswoman/M
+yachtswomen
+yahoo/SM
+yak/SM
+yakked
+yakking
+yam/SM
+yammer/SZGMDR
+yammerer/M
+yang/M
+yank/MDSG
+yap/SM
+yapped
+yapping
+yard/MS
+yardage/MS
+yardarm/MS
+yardman/M
+yardmaster/MS
+yardmen
+yardstick/MS
+yarmulke/SM
+yarn/MS
+yarrow/M
+yashmak/S
+yaw/SGMD
+yawl/MS
+yawn/MDRSZG
+yawner/M
+yaws/M
+yd
+ye/RST
+yea/SM
+yeah/M
+yeahs
+year/MYS
+yearbook/MS
+yearling/MS
+yearlong
+yearly/SM
+yearn/GSJD
+yearning/M
+yeast/SM
+yeasty/RT
+yegg/MS
+yell/MDSG
+yellow/MDRTGPS
+yellowhammer/S
+yellowish
+yellowness/M
+yellowy
+yelp/MDSG
+yen/SM
+yeoman/M
+yeomanry/M
+yeomen
+yep/SM
+yes/MS
+yeshiva/SM
+yeshivot
+yessed
+yessing
+yesterday/MS
+yesteryear/M
+yet
+yeti/MS
+yew/SM
+yid/S
+yield/JSGMD
+yikes
+yin/M
+yip/SM
+yipe
+yipped
+yippee
+yipping
+yo
+yob/S
+yobbo/S
+yodel/SMDRZG
+yodeler/M
+yoga/M
+yogi/MS
+yogic
+yogurt/SM
+yoke's
+yoke/UGDS
+yokel/SM
+yolk/MDS
+yon
+yonder
+yonks
+yore/M
+you'd
+you'll
+you're
+you've
+you/SMH
+young/TMR
+youngish
+youngster/MS
+your/S
+yourself
+yourselves
+youth/M
+youthful/YP
+youthfulness/M
+youths
+yow
+yowl/MDSG
+yr/S
+ytterbium/M
+yttrium/M
+yuan/M
+yucca/SM
+yuck/MDSG
+yucky/TR
+yuk/SM
+yukked
+yukking
+yukky
+yule/M
+yuletide/M
+yum
+yummy/TR
+yup/SM
+yuppie/MS
+yuppify/GDS
+yurt/MS
+z/DNXTGJ
+zaniness/M
+zany/RSMPT
+zap/SM
+zapped
+zapper/MS
+zapping
+zappy
+zeal/M
+zealot/MS
+zealotry/M
+zealous/YP
+zealousness/M
+zebra/SM
+zebu/MS
+zed/SM
+zeitgeist/SM
+zenith/M
+zeniths
+zenned
+zeolite/S
+zephyr/MS
+zeppelin/MS
+zero/MDHSG
+zeroes
+zest/MS
+zestful/YP
+zestfulness/M
+zesty/RT
+zeta/MS
+zigzag/SM
+zigzagged
+zigzagging
+zilch/M
+zillion/MS
+zinc/MS
+zincked
+zincking
+zine/S
+zinfandel/M
+zing/MDRZG
+zinger/M
+zingy/RT
+zinnia/MS
+zip's
+zip/US
+zipped/U
+zipper/MDGS
+zipping/U
+zippy/TR
+zircon/MS
+zirconium/M
+zit/SM
+zither/MS
+zloty/SM
+zlotys
+zodiac/MS
+zodiacal
+zombie/MS
+zonal/Y
+zone's
+zone/AGDS
+zoning/M
+zonked
+zoo/SM
+zookeeper/SM
+zoological/Y
+zoologist/SM
+zoology/M
+zoom/MDSG
+zoophyte/SM
+zoophytic
+zooplankton
+zorch
+zoster
+zounds
+zucchini/MS
+zwieback/M
+zydeco/M
+zygote/SM
+zygotic
+zymurgy/M
+ngstr旦m/M
+辿clair/SM
+辿clat/M
+辿lan/M
+辿migr辿/SM
+辿p辿e/MS
+辿tude/SM
diff --git a/extensions/spellcheck/locales/en-US/hunspell/dictionary-sources/utf8/en-US-utf8.aff b/extensions/spellcheck/locales/en-US/hunspell/dictionary-sources/utf8/en-US-utf8.aff
new file mode 100644
index 0000000000..d0cccb3dc7
--- /dev/null
+++ b/extensions/spellcheck/locales/en-US/hunspell/dictionary-sources/utf8/en-US-utf8.aff
@@ -0,0 +1,205 @@
+SET UTF-8
+TRY esianrtolcdugmphbyfvkwzESIANRTOLCDUGMPHBYFVKWZ'
+ICONV 1
+ICONV '
+NOSUGGEST !
+
+# ordinal numbers
+COMPOUNDMIN 1
+# only in compounds: 1th, 2th, 3th
+ONLYINCOMPOUND c
+# compound rules:
+# 1. [0-9]*1[0-9]th (10th, 11th, 12th, 56714th, etc.)
+# 2. [0-9]*[02-9](1st|2nd|3rd|[4-9]th) (21st, 22nd, 123rd, 1234th, etc.)
+COMPOUNDRULE 2
+COMPOUNDRULE n*1t
+COMPOUNDRULE n*mp
+WORDCHARS 0123456789
+
+PFX A Y 1
+PFX A 0 re .
+
+PFX I Y 1
+PFX I 0 in .
+
+PFX U Y 1
+PFX U 0 un .
+
+PFX C Y 1
+PFX C 0 de .
+
+PFX E Y 1
+PFX E 0 dis .
+
+PFX F Y 1
+PFX F 0 con .
+
+PFX K Y 1
+PFX K 0 pro .
+
+SFX V N 2
+SFX V e ive e
+SFX V 0 ive [^e]
+
+SFX N Y 3
+SFX N e ion e
+SFX N y ication y
+SFX N 0 en [^ey]
+
+SFX X Y 3
+SFX X e ions e
+SFX X y ications y
+SFX X 0 ens [^ey]
+
+SFX H N 2
+SFX H y ieth y
+SFX H 0 th [^y]
+
+SFX Y Y 1
+SFX Y 0 ly .
+
+SFX G Y 2
+SFX G e ing e
+SFX G 0 ing [^e]
+
+SFX J Y 2
+SFX J e ings e
+SFX J 0 ings [^e]
+
+SFX D Y 4
+SFX D 0 d e
+SFX D y ied [^aeiou]y
+SFX D 0 ed [^ey]
+SFX D 0 ed [aeiou]y
+
+SFX T N 4
+SFX T 0 st e
+SFX T y iest [^aeiou]y
+SFX T 0 est [aeiou]y
+SFX T 0 est [^ey]
+
+SFX R Y 4
+SFX R 0 r e
+SFX R y ier [^aeiou]y
+SFX R 0 er [aeiou]y
+SFX R 0 er [^ey]
+
+SFX Z Y 4
+SFX Z 0 rs e
+SFX Z y iers [^aeiou]y
+SFX Z 0 ers [aeiou]y
+SFX Z 0 ers [^ey]
+
+SFX S Y 4
+SFX S y ies [^aeiou]y
+SFX S 0 s [aeiou]y
+SFX S 0 es [sxzh]
+SFX S 0 s [^sxzhy]
+
+SFX P Y 3
+SFX P y iness [^aeiou]y
+SFX P 0 ness [aeiou]y
+SFX P 0 ness [^y]
+
+SFX M Y 1
+SFX M 0 's .
+
+SFX B Y 3
+SFX B 0 able [^aeiou]
+SFX B 0 able ee
+SFX B e able [^aeiou]e
+
+SFX L Y 1
+SFX L 0 ment .
+
+REP 90
+REP a ei
+REP ei a
+REP a ey
+REP ey a
+REP ai ie
+REP ie ai
+REP alot a_lot
+REP are air
+REP are ear
+REP are eir
+REP air are
+REP air ere
+REP ere air
+REP ere ear
+REP ere eir
+REP ear are
+REP ear air
+REP ear ere
+REP eir are
+REP eir ere
+REP ch te
+REP te ch
+REP ch ti
+REP ti ch
+REP ch tu
+REP tu ch
+REP ch s
+REP s ch
+REP ch k
+REP k ch
+REP f ph
+REP ph f
+REP gh f
+REP f gh
+REP i igh
+REP igh i
+REP i uy
+REP uy i
+REP i ee
+REP ee i
+REP j di
+REP di j
+REP j gg
+REP gg j
+REP j ge
+REP ge j
+REP s ti
+REP ti s
+REP s ci
+REP ci s
+REP k cc
+REP cc k
+REP k qu
+REP qu k
+REP kw qu
+REP o eau
+REP eau o
+REP o ew
+REP ew o
+REP oo ew
+REP ew oo
+REP ew ui
+REP ui ew
+REP oo ui
+REP ui oo
+REP ew u
+REP u ew
+REP oo u
+REP u oo
+REP u oe
+REP oe u
+REP u ieu
+REP ieu u
+REP ue ew
+REP ew ue
+REP uff ough
+REP oo ieu
+REP ieu oo
+REP ier ear
+REP ear ier
+REP ear air
+REP air ear
+REP w qu
+REP qu w
+REP z ss
+REP ss z
+REP shun tion
+REP shun sion
+REP shun cion
+REP size cise
diff --git a/extensions/spellcheck/locales/en-US/hunspell/dictionary-sources/utf8/en-US-utf8.dic b/extensions/spellcheck/locales/en-US/hunspell/dictionary-sources/utf8/en-US-utf8.dic
new file mode 100644
index 0000000000..3bf8d54757
--- /dev/null
+++ b/extensions/spellcheck/locales/en-US/hunspell/dictionary-sources/utf8/en-US-utf8.dic
@@ -0,0 +1,53554 @@
+53553
+0/nm
+0th/pt
+1/n1
+1st/p
+1th/tc
+2/nm
+2nd/p
+2th/tc
+3/nm
+3rd/p
+3th/tc
+4/nm
+4th/pt
+5/nm
+5th/pt
+6/nm
+6th/pt
+7/nm
+7th/pt
+8/nm
+8th/pt
+9/nm
+9th/pt
+A/SM
+AA/M
+AAA
+AB/M
+ABA
+ABC/M
+ABM/SM
+ABS
+AC/M
+ACLU/M
+ACT
+ACTH/M
+AD/M
+ADC
+ADD
+ADM
+ADP/M
+AF
+AFAIK
+AFB
+AFC/M
+AFDC
+AFN
+AFT
+AI/SM
+AIDS/M
+AK
+AL
+AM/M
+AMA
+AMD/M
+ANSI/S
+ANZUS/M
+AOL/M
+AP/M
+APB
+APC
+API/SM
+APO
+APR
+AR
+ARC
+ASAP
+ASCII/SM
+ASL/M
+ASPCA
+ATM/M
+ATP/M
+ATPase/M
+ATV
+AV
+AVI
+AWACS/M
+AWOL/M
+AWS/M
+AZ/M
+AZT/M
+Aachen/M
+Aaliyah/M
+Aaron/M
+Ab's
+Abba/S
+Abbas/M
+Abbasid/M
+Abbie/M
+Abbott/M
+Abby/M
+Abdel/M
+Abdul/M
+Abe/M
+AbeBooks
+Abel/M
+Abelard/M
+Abelson/M
+Aberdeen/M
+Abernathy/M
+Abidjan/M
+Abie/M
+Abigail/M
+Abilene/M
+Abner/M
+Aborigine/MS
+Abra/M
+Abraham/M
+Abram/MS
+Abramo/M
+Abrams/M
+Absalom/M
+Abuja/M
+Abyssinia/M
+Abyssinian/M
+Ac/M
+Acadia/M
+Acapulco/M
+Accenture/M
+Accra/M
+Acevedo/M
+Achaean/M
+Achebe/M
+Achernar/M
+Acheson/M
+Achilles/M
+Aconcagua/M
+Acosta/M
+Acropolis
+Acrux/M
+Actaeon/M
+ActiveX/M
+Acton/M
+Acts/M
+Acuff/M
+Acura/M
+Ada/SM
+Adah/M
+Adair/M
+Adaline/M
+Adam/SM
+Adamo/M
+Adams/M
+Adan/M
+Adana/M
+Adar/M
+AddThis/M
+Adda/M
+Addams/M
+Adderley/M
+Addi/M
+Addie/M
+Addison/M
+Addy/M
+Ade/M
+Adel/M
+Adela/M
+Adelaida/M
+Adelaide/M
+Adelbert/M
+Adele/M
+Adelheid/M
+Adelina/M
+Adeline/M
+Adelle/M
+Aden/M
+Adena/M
+Adenauer/M
+Adey/M
+Adham/M
+Adhara/M
+Adi/M
+Adidas/M
+Adina/M
+Adirondack/SM
+Adirondacks/M
+Adkins/M
+Adlai/M
+Adler/M
+Adm
+Admiralty
+Adolf/M
+Adolfo/M
+Adolph/M
+Adolphe/M
+Adolphus/M
+Adonis/MS
+Adore's
+Adrenalin/MS
+Adria/M
+Adrian/M
+Adriana/M
+Adriane/M
+Adrianna/M
+Adrianne/M
+Adriano/M
+Adriatic/M
+Adrien/M
+Adrienne/M
+Advent/MS
+Adventist/MS
+Advil/M
+Aegean/M
+Aelfric/M
+Aeneas/M
+Aeneid/M
+Aeolus/M
+Aeroflot/M
+Aeschylus/M
+Aesculapius/M
+Aesop/M
+Afghan/SM
+Afghani/M
+Afghanistan/M
+Afr
+Africa/M
+African/SM
+Afrikaans/M
+Afrikaner/SM
+Afro/SM
+Afrocentric
+Afrocentrism/M
+Afton/M
+Ag/M
+Agamemnon/M
+Agana
+Agassi/M
+Agassiz/M
+Agata/M
+Agatha/M
+Agathe/M
+Aggie/M
+Agilent
+Aglaia/M
+Agnes/M
+Agnese/M
+Agnew/M
+Agni/M
+Agosto/M
+Agra/M
+Agricola/M
+Agrippa/M
+Agrippina/M
+Aguadilla/M
+Aguascalientes
+Aguilar/M
+Aguinaldo/M
+Aguirre/M
+Agustin/M
+Ahab/M
+Aharon/M
+Ahmad/M
+Ahmadabad/M
+Ahmadinejad/M
+Ahmed/M
+Ahriman/M
+Aida/M
+Aidan/M
+Aiken/M
+Aila/M
+Aileen/M
+Ailey/M
+Aime/M
+Aimee/M
+Ainsley/M
+Ainslie/M
+Ainu/M
+Airedale/MS
+Aires/M
+Aisha/M
+Ajax/M
+Ajay/M
+Akbar/M
+Akhmatova/M
+Akihito/M
+Akim/M
+Akita/M
+Akiva/M
+Akkad/M
+Akron/M
+Al/M
+Ala/S
+Alabama/M
+Alabaman/MS
+Alabamian/SM
+Aladdin/M
+Alain/M
+Alameda/M
+Alamo/M
+Alamogordo/M
+Alan/M
+Alana/M
+Aland/M
+Alanna/M
+Alanson/M
+Alar/M
+Alaric/M
+Alasdair/M
+Alaska/M
+Alaskan/MS
+Alastair/M
+Alba/M
+Albania/M
+Albanian/MS
+Albany/M
+Albee/M
+Alberio/M
+Albert/M
+Alberta/M
+Albertan
+Albertina/M
+Albertine/M
+Alberto/M
+Albie/M
+Albigensian/M
+Albina/M
+Albion/M
+Albireo/M
+Albrecht/M
+Albuquerque/M
+Alcatraz/M
+Alcestis/M
+Alcibiades/M
+Alcindor/M
+Alcmena/M
+Alcoa/M
+Alcott/M
+Alcuin/M
+Alcyone/M
+Aldan/M
+Aldebaran/M
+Alden/M
+Alderamin/M
+Aldin/M
+Aldis/M
+Aldo/M
+Aldon/M
+Aldous/M
+Aldrich/M
+Aldridge/M
+Aldrin/M
+Aldus/M
+Alec/M
+Aleichem/M
+Alejandra/M
+Alejandro/M
+Aleksandr/M
+Alembert/M
+Alena/M
+Alene/M
+Aleppo/M
+Alessandra/M
+Alessandro/M
+Alethea/M
+Aleut/MS
+Aleutian/SM
+Alex/M
+Alexa/M
+Alexander/MS
+Alexandr/M
+Alexandra/M
+Alexandre/M
+Alexandria/M
+Alexandrian
+Alexandrina/M
+Alexandros
+Alexei/M
+Alexi/MS
+Alexia/M
+Alexina/M
+Alexis/M
+Alf/M
+Alfie/M
+Alfons/M
+Alfonse/M
+Alfonso/M
+Alfonzo/M
+Alford/M
+Alfred/M
+Alfreda/M
+Alfredo/M
+Algenib/M
+Alger/M
+Algeria/M
+Algerian/SM
+Algernon/M
+Algieba/M
+Algiers/M
+Algol/M
+Algonquian/SM
+Algonquin/MS
+Alhambra/M
+Alhena/M
+Ali/SM
+Alia/M
+Alice/M
+Alicia/M
+Alick/M
+Alida/M
+Alighieri/M
+Alina/M
+Aline/M
+Alioth/M
+Alisa/M
+Alisha/M
+Alison/M
+Alissa/M
+Alistair/M
+Alister/M
+Alix/M
+Alkaid/M
+Alla/M
+Allah/M
+Allahabad/M
+Allan/M
+Allard/M
+Alleghenies/M
+Allegheny/SM
+Allegra/M
+Allen/M
+Allende/M
+Allene/M
+Allentown/M
+Alleyn/M
+Allhallows/M
+Allie/MS
+Allison/M
+Allister/M
+Allstate/M
+Allyn/M
+Allyson/M
+Alma/M
+Almach/M
+Almaty/M
+Almeria/M
+Almighty/M
+Almira/M
+Almohad/M
+Almoravid/M
+Alnilam/M
+Alnitak/M
+Alon/M
+Alonso/M
+Alonzo/M
+Aloysius/M
+Alpert/M
+Alphard/M
+Alphecca/M
+Alpheratz/M
+Alphonse/M
+Alphonso/M
+Alpine/M
+Alpo/M
+Alps/M
+Alric/M
+Alsace/M
+Alsatian/SM
+Alsop/M
+Alston/M
+Alta/M
+Altaba/M
+Altai/M
+Altaic/M
+Altair/M
+Altamira/M
+Althea/M
+Altiplano/M
+Altman/M
+Altoids/M
+Alton/M
+Altoona/M
+Aludra/M
+Alva/M
+Alvan/M
+Alvarado/M
+Alvarez/M
+Alvaro/M
+Alvin/M
+Alvina/M
+Alvis/M
+Alvy/M
+Alwin/M
+Alwyn/M
+Alyce/M
+Alyosha/M
+Alys/M
+Alyson/M
+Alyss
+Alyssa/M
+Alzheimer/M
+Am/MNR
+Amabel/M
+Amadeus/M
+Amado/M
+Amalia/M
+Amalie/M
+Amanda/M
+Amara/M
+Amarillo/M
+Amaru/M
+Amata/M
+Amaterasu/M
+Amati/M
+Amazon/SM
+Amazonian
+Amber/M
+Ambros/M
+Ambrose
+Ambrosio/M
+Ambrosius/M
+Ame/SM
+Amelia/M
+Amelie/M
+Amen/M
+Amenhotep/M
+Amerasian/M
+America/SM
+American/MS
+Americana/M
+Americanism/MS
+Americanization/MS
+Americanize/GDS
+Amerigo/M
+Amerind/SM
+Amerindian/MS
+Amery/M
+Ames/M
+Ameslan/M
+Amgen/M
+Amharic/M
+Amherst/M
+Ami/M
+Amie/M
+Amiga/M
+Amil/M
+Amish/M
+Amman/M
+Amoco/M
+Amory/M
+Amos/M
+Amparo/M
+Ampere/M
+Amritsar/M
+Amsterdam/M
+Amtrak/M
+Amundsen/M
+Amur/M
+Amway/M
+Amy/M
+Ana/M
+Anabaptist/M
+Anabel/M
+Anacin/M
+Anacreon/M
+Anaheim/M
+Analects/M
+Analise/M
+Ananias/M
+Anasazi/M
+Anastasia/M
+Anatol/M
+Anatole/M
+Anatolia/M
+Anatolian/M
+Anaxagoras/M
+Anchorage/M
+Andalusia/M
+Andalusian/M
+Andaman/M
+Andean/M
+Anders/N
+Andersen/M
+Anderson/M
+Andes/M
+Andi/M
+Andie/M
+Andorra/M
+Andorran/SM
+Andra/MS
+Andre/MS
+Andrea/SM
+Andree/M
+Andrei/M
+Andrej/M
+Andres/M
+Andretti/M
+Andrew/SM
+Andrews/M
+Andrey/M
+Andria/M
+Andrianampoinimerina/M
+Android/M
+Andromache/M
+Andromeda/M
+Andropov/M
+Andros
+Andrus/M
+Andy/M
+Anet/M
+Angara/M
+Ange/M
+Angel/M
+Angela/M
+Angele/SM
+Angeles/M
+Angeli/M
+Angelia/M
+Angelica/M
+Angelico/M
+Angelika/M
+Angelina/M
+Angeline/M
+Angelique/M
+Angelita/M
+Angelo/M
+Angelou/M
+Angevin/M
+Angie/M
+Angkor/M
+Angle/MS
+Angleton/M
+Anglia/M
+Anglican/SM
+Anglicanism/MS
+Anglicism/MS
+Anglicization
+Anglicize
+Anglo/M
+Anglophile/M
+Anglophobe
+Angola/M
+Angolan/MS
+Angora/SM
+Angstrom/M
+Anguilla/M
+Angus/M
+Anhui/M
+Ania/M
+Aniakchak/M
+Anibal/M
+Anita/M
+Ankara/M
+Ann/M
+Anna/M
+Annabel/M
+Annabella/M
+Annabelle/M
+Annalise/M
+Annam/M
+Annapolis/M
+Annapurna/M
+Anne/M
+Anneliese/M
+Annelise/M
+Annemarie/M
+Annette/M
+Anni/SM
+Annie/M
+Anniston/M
+Annmarie/M
+Annunciation/SM
+Anny/M
+Anouilh/M
+Ansel/M
+Ansell/M
+Anselm/M
+Anselmo/M
+Anshan/M
+Ansley/M
+Anson/M
+Anstice/M
+Antaeus/M
+Antananarivo/M
+Antarctic/M
+Antarctica/M
+Antares/M
+Anthea/M
+Anthony/M
+Anthropocene
+Antichrist/SM
+Antietam/M
+Antifa/M
+Antigone/M
+Antigua/M
+Antillean
+Antilles/M
+Antin/M
+Antioch/M
+Antipas/M
+Antipodes
+Antofagasta/M
+Antoine/M
+Antoinette/M
+Anton/M
+Antone/M
+Antonella/M
+Antoni/M
+Antonia/M
+Antonie/M
+Antonietta/M
+Antonin/M
+Antonina/M
+Antonino/M
+Antoninus/M
+Antonio/M
+Antonius/M
+Antony/M
+Antwan/M
+Antwerp/M
+Anubis/M
+Any's
+Anya/M
+Anzac/M
+Apache/SM
+Apalachicola/M
+Apatosaurus
+Apennines/M
+Aphrodite/M
+Apia/M
+Apocalypse/M
+Apocrypha/M
+Apollinaire/M
+Apollo/SM
+Apollonian/M
+Apostle/M
+Appalachia/M
+Appalachian/SM
+Appalachians/M
+Appaloosa/SM
+Apple/M
+Appleseed/M
+Appleton/M
+Appomattox/M
+Apr/M
+April/MS
+Apuleius/M
+Aquafresh/M
+Aquarian
+Aquarius/MS
+Aquila/M
+Aquinas/M
+Aquino/M
+Aquitaine/M
+Ar/MY
+Ara/M
+Arab/SM
+Arabella/M
+Arabia/M
+Arabian/MS
+Arabic/M
+Arabidopsis
+Arabist/MS
+Araby/M
+Araceli/M
+Arafat/M
+Aragon
+Araguaya/M
+Aral/M
+Aramaic/M
+Aramco/M
+Arapaho/MS
+Arapahoes
+Ararat/M
+Araucanian/M
+Arawak/M
+Arawakan/M
+Arbitron/M
+Arcadia/M
+Arcadian/M
+Archambault/M
+Archean/M
+Archibald/M
+Archie/M
+Archimedes/M
+Archy/M
+Arctic/M
+Arcturus/M
+Arda/M
+Ardabil
+Arden/M
+Ardis/M
+Arduino/M
+Arecibo/M
+Arequipa/M
+Ares/M
+Aretha/M
+Argentina/M
+Argentine/M
+Argentinean
+Argentinian/MS
+Argo/SM
+Argonaut/MS
+Argonne/M
+Argos/M
+Argus/M
+Ari/M
+Ariadne/M
+Arial/M
+Ariana/M
+Arianism/M
+Arie/SM
+Ariel/M
+Arielle/M
+Aries/MS
+Arin/M
+Ariosto/M
+Aristarchus/M
+Aristides/M
+Aristophanes/M
+Aristotelian/M
+Aristotle/M
+Arius/M
+Ariz
+Arizona/M
+Arizonan/SM
+Arizonian/MS
+Arjuna/M
+Ark/M
+Arkansan/MS
+Arkansas/M
+Arkhangelsk/M
+Arkwright/M
+Arlen/M
+Arlene/M
+Arlette/M
+Arley/M
+Arlie/M
+Arlin/M
+Arline/M
+Arlington/M
+Arly/M
+Armageddon/SM
+Armagnac/M
+Arman/M
+Armand/M
+Armando/M
+Armani/M
+Armenia/M
+Armenian/SM
+Armin/M
+Arminius/M
+Armonk/M
+Armour/M
+Armstrong/M
+Arnaldo/M
+Arne
+Arneb/M
+Arnhem/M
+Arni/M
+Arnie/M
+Arno/M
+Arnold/M
+Arnoldo/M
+Arnulfo/M
+Aron/M
+Arrhenius/M
+Arron/M
+Art/M
+Artaxerxes/M
+Arte/M
+Artemas
+Artemis/M
+Artemus/M
+Arthur/M
+Arthurian/M
+Artie/M
+Artur/M
+Arturo/M
+Artus/M
+Arty's
+Aruba/M
+Arv/M
+Arvin/M
+Aryan/MS
+As/M
+Asa/M
+Asama/M
+Ascella/M
+Ascension/M
+Ase/M
+Asgard/M
+Ashanti/M
+Ashby/M
+Ashcroft/M
+Ashe/RM
+Asheville/M
+Ashgabat
+Ashikaga/M
+Ashkenazim/M
+Ashkhabad/M
+Ashlee/M
+Ashleigh/M
+Ashley/M
+Ashmolean/M
+Ashton
+Ashurbanipal/M
+Asia/M
+Asiago
+Asian/MS
+Asiatic/SM
+Asimov/M
+Asmara/M
+Asoka/M
+Aspell/M
+Aspen/M
+Asperger/M
+Aspidiske/M
+Asquith/M
+Assad/M
+Assam/M
+Assamese/M
+Assembly
+Assisi/M
+Assyria/M
+Assyriaca/M
+Assyrian/SM
+Astaire/M
+Astana/M
+Astarte/M
+Aston/M
+Astor/M
+Astoria/M
+Astra/M
+Astrakhan/M
+Astrid/M
+AstroTurf/M
+Asturias/M
+Asuncion/M
+Asunci坦n/M
+Aswan/M
+At/SM
+Atacama/M
+Atahualpa/M
+Atalanta/M
+Atari/M
+Atascadero/M
+Ataturk/M
+Atat端rk/M
+Athabasca/M
+Athabaska
+Athabaskan/SM
+Athanasius
+Athena/M
+Athene/M
+Athenian/SM
+Athens/M
+Athlon/M
+Atkins/M
+Atkinson/M
+Atlanta/M
+Atlantes
+Atlantic/M
+Atlantis/M
+Atlas/MS
+Atman/M
+Atonement
+Atreus/M
+Atria/M
+Atropos/M
+Attic/M
+Attica/M
+Attila/M
+Attlee/M
+Attn
+Attucks/M
+Atwood/M
+Au/M
+Aube
+Aubert/M
+Aubrey/M
+Aubry/M
+Auburn/M
+Auckland/M
+Auden/M
+Audi/M
+Audie/M
+Audion/M
+Audra/M
+Audre/M
+Audrey/M
+Audubon/M
+Aug/M
+Augean/M
+Augie/M
+Augsburg/M
+August/MS
+Augusta/M
+Augustan/M
+Auguste/M
+Augustin/M
+Augustine/M
+Augustinian/MS
+Augusto/M
+Augustus/M
+Aurangzeb/M
+Aurea/M
+Aurel/M
+Aurelia/M
+Aurelie/M
+Aurelio/M
+Aurelius/M
+Aureomycin/M
+Auriga/M
+Aurora/M
+Aurore/M
+Auschwitz/M
+Aussie/MS
+Austen/M
+Austerlitz/M
+Austin/MS
+Australasia/M
+Australasian
+Australia/M
+Australian/SM
+Australoid/M
+Australopithecus/M
+Austria/M
+Austrian/SM
+Austronesian/M
+Autumn/M
+Av/M
+Ava/M
+Avalon/M
+Ave/M
+Aveline/M
+Aventine/M
+Averell/M
+Averil/M
+Averill/M
+Avernus/M
+Averroes/M
+Avery/M
+Avesta/M
+Avicenna/M
+Avigdor/M
+Avignon/M
+Avila/M
+Avior/M
+Avis/M
+Aviva/M
+Avogadro/M
+Avon/M
+Avondale/M
+Avram/M
+Avril/M
+Axe/M
+Axel
+Axis
+Axum/M
+Ayala/M
+Ayers/M
+Aylmer/M
+Aymara/M
+Aymer/M
+Ayn/M
+Ayrshire/M
+Ayurveda/M
+Ayyubid/M
+Azana/M
+Azania/M
+Azazel/M
+Azerbaijan/M
+Azerbaijani/MS
+Azores/M
+Azov/M
+Aztec/SM
+Aztecan/M
+Aztlan/M
+B/MNRTG
+BA/M
+BASIC/SM
+BB/M
+BBB/M
+BBC/M
+BBQ
+BBS
+BBSes
+BC/M
+BFF
+BIA
+BIOS
+BITNET
+BLT/SM
+BM/M
+BMW/M
+BO
+BP/M
+BPOE
+BR
+BS/M
+BSA
+BSD/SM
+BTU
+BTW
+BYOB
+Ba/M
+Baal/SM
+Baath/M
+Baathist/M
+Bab/SM
+Babb/M
+Babbage/M
+Babbie/M
+Babbitt/M
+Babel/MS
+Babette/M
+Babylon/MS
+Babylonia/M
+Babylonian/SM
+Bacall/M
+Bacardi/M
+Bacchanalia/M
+Bacchic
+Bacchus/M
+Bach/M
+Backus/M
+Bacon/M
+Bactria/M
+Baden/M
+Badlands/M
+Baedeker/MS
+Baez/M
+Baffin/M
+Baggies/M
+Baghdad/M
+Baguio/M
+Baha'i/M
+Baha'ullah/M
+Bahama/SM
+Bahamanian
+Bahamas/M
+Bahamian/MS
+Bahasa/M
+Bahia/M
+Bahrain/M
+Baidu/M
+Baikal/M
+Bailey/M
+Bailie/M
+Baillie/M
+Baily/M
+Baird/M
+Bakelite/M
+Baker/M
+Bakersfield/M
+Baku/M
+Bakunin/M
+Balanchine/M
+Balaton/M
+Balboa/M
+Bald's
+Balder/M
+Baldwin/SM
+Balearic/M
+Balfour/M
+Bali/M
+Balinese/M
+Balkan/MS
+Balkans/M
+Balkhash/M
+Ball/M
+Ballard/M
+Balthazar/M
+Baltic/M
+Baltimore/M
+Baluchistan/M
+Balzac/M
+Bamako/M
+Bambi/M
+Banach/M
+Bancorp
+Bancroft/M
+Bandung/M
+Bangalore/M
+Bangkok/M
+Bangladesh/M
+Bangladeshi/SM
+Bangor/M
+Bangui/M
+Banjarmasin/M
+Banjul/M
+Banks/M
+Banneker/M
+Bannister/M
+Banting/M
+Bantu/MS
+Baotou/M
+Baptist/SM
+Baptiste/M
+Barabbas/M
+Barack/M
+Barbadian/SM
+Barbados/M
+Barbara/M
+Barbarella/M
+Barbarossa/M
+Barbary/M
+Barbe/MR
+Barbee/M
+Barber/M
+Barbette/M
+Barbey/M
+Barbie/M
+Barbour/M
+Barbra/M
+Barbuda/M
+Barcelona/M
+Barceloneta/M
+Barclay/SM
+Barclays/M
+Barde/M
+Bardeen/M
+Barents/M
+Bari/M
+Barker/M
+Barkley/M
+Barlow/M
+Barnabas/M
+Barnaby/M
+Barnard/M
+Barnaul/M
+Barnes/M
+Barnett/M
+Barney/M
+Barnum/M
+Baroda/M
+Barquisimeto/M
+Barr/M
+Barranquilla/M
+Barrera/M
+Barret/M
+Barrett/M
+Barri/MS
+Barrie/M
+Barron/M
+Barry/M
+Barrymore/M
+Bart/M
+Bartel/M
+Barth/MS
+Barthel/M
+Bartholdi/M
+Bartholomew/M
+Bartlet/M
+Bartlett/M
+Bartok/M
+Bartolomeo/M
+Barton/M
+Bartram/M
+Barty/M
+Bart坦k/M
+Baruch/M
+Bary/M
+Baryshnikov/M
+Basel/M
+Basho/M
+Basia/M
+Basic
+Basie/M
+Basil/M
+Basile/M
+Basilio/M
+Basilius/M
+Basque/MS
+Basra/M
+Bass/M
+Basseterre/M
+Bastian/M
+Bastien/M
+Bastille/M
+Basutoland/M
+Bataan/M
+Bates/M
+Bathsheba/M
+Batista/M
+Batman/M
+Battle/M
+Batu/M
+Baudelaire/M
+Baudoin/M
+Baudouin/M
+Baudrillard/M
+Bauer/M
+Bauhaus/M
+Baum/M
+Bavaria/M
+Bavarian/M
+Bax
+Baxter/M
+Bayamon
+Bayard
+Bayer/M
+Bayes/M
+Bayesian/M
+Bayeux/M
+Baylor/M
+Bayonne/M
+Bayreuth/M
+Baywatch/M
+Be/MH
+Bea/M
+Beach/M
+Beadle/M
+Beale/M
+Bean/M
+Beard/M
+Beardmore/M
+Beardsley/M
+Bearnaise/M
+Beasley/M
+Beatlemania/M
+Beatles/M
+Beatrice/M
+Beatrix/M
+Beatriz/M
+Beatty/M
+Beau/M
+Beaufort/M
+Beaujolais/M
+Beaumarchais/M
+Beaumont/M
+Beauregard/M
+Beauvoir/M
+Bebe/M
+Becca/M
+Bechtel/M
+Beck/MR
+Becka/M
+Becker/M
+Becket/M
+Beckett/M
+Beckham/M
+Beckie/M
+Beckley/M
+Beckman
+Becky/M
+Becquerel/M
+Bede/M
+Bedouin/SM
+Beebe/M
+Beecher/M
+Beefaroni/M
+Beelzebub/M
+Beerbohm/M
+Beethoven/M
+Beeton/M
+Begin/M
+Behan/M
+Behring/M
+Beiderbecke/M
+Beijing/M
+Beirut/M
+Bekesy/M
+Bel/M
+Bela/M
+Belarus/M
+Belarusian
+Belau/M
+Belem/M
+Belfast/M
+Belg
+Belgian/SM
+Belgium/M
+Belgrade/M
+Belinda/M
+Belize/M
+Belkin/M
+Bell/M
+Bella/M
+Bellamy/M
+Bellatrix/M
+Belleek/M
+Bellevue/M
+Bellingham/M
+Bellini/M
+Bellow/M
+Belmont/M
+Belmopan/M
+Beloit/M
+Belorussian/MS
+Belshazzar/M
+Beltane/M
+Beltran/M
+Belushi/M
+Belva/M
+Ben/M
+Benacerraf/M
+Benares/M
+Benchley/M
+Bend/MR
+Bender/M
+Bendictus
+Bendix/M
+Benedetta/M
+Benedetto/M
+Benedick/M
+Benedict/M
+Benedicta/M
+Benedictine/MS
+Benedicto/M
+Benedikt/M
+Benelux/M
+Benet/M
+Benetton/M
+Bengal/SM
+Bengali/M
+Benghazi/M
+Bengt/M
+Benin/M
+Beninese/M
+Benita/M
+Benito/M
+Benjamin/M
+Benji/M
+Benjie/M
+Benjy/M
+Benn/M
+Bennett/M
+Bennie/M
+Benny/M
+Benoit/M
+Benson/M
+Bentham/M
+Bentley/M
+Benton/M
+Benz/M
+Benzedrine/M
+Beowulf/M
+Ber/MG
+Berber/SM
+Berenice/M
+Beretta/M
+Berg/MNR
+Bergen/M
+Berger/M
+Bergerac/M
+Bergman/M
+Bergson/M
+Beria/M
+Bering/M
+Berk/M
+Berke/M
+Berkeley/M
+Berkley/M
+Berkshire/SM
+Berkshires/M
+Berle/M
+Berlin/SZMR
+Berliner/M
+Berlioz/M
+Berlitz/M
+Bermuda/SM
+Bermudan/SM
+Bermudian/SM
+Bern/M
+Bernadette/M
+Bernadine/M
+Bernanke/M
+Bernard/M
+Bernardine
+Bernardo/M
+Bernays/M
+Bernbach/M
+Bernese
+Bernhard/M
+Bernhardt/M
+Berni/M
+Bernice/M
+Bernie/M
+Bernini/M
+Bernoulli/M
+Bernstein/M
+Berra/M
+Berri/M
+Berry/M
+Bert/M
+Berta/M
+Bertelsmann/M
+Bertha/M
+Berthe/M
+Berti/M
+Bertie/M
+Bertillon/M
+Berton/M
+Bertram/M
+Bertrand/M
+Berwick/M
+Beryl/M
+Berzelius/M
+Bess/M
+Bessel/M
+Bessemer/M
+Bessie/M
+Bessy/M
+Best/M
+Betelgeuse/M
+Beth/M
+Bethany/M
+Bethe/M
+Bethesda/M
+Bethlehem/M
+Bethune/M
+Betsey/M
+Betsy/M
+Betta/M
+Bette/M
+Betti
+Bettie/M
+Bettina/M
+Betty/M
+Bettye/M
+Beulah/M
+Bevan
+Beveridge
+Beverley/M
+Beverly/M
+Bevin
+Bevvy's
+Beyer/M
+Bharat/M
+Bhopal/M
+Bhutan/M
+Bhutanese/M
+Bhutto/M
+Bi/M
+Bialystok/M
+Bianca/M
+Bib
+BibSonomy/M
+BibTeX/M
+Bibby/M
+Bibi/M
+Bible/MS
+Biblical/M
+Bic/M
+Biddle/M
+Biden/M
+Bierce/M
+BigQuery/M
+Bigfoot/M
+Biggles/M
+Biko/M
+Bil/MY
+Bilbao/M
+Bilbo/M
+Bili/M
+Bill/MJ
+Billie/M
+Billings/M
+Billy/M
+Bimini/M
+Bing/M
+Binghamton/M
+Bink/M
+Binky/M
+Binnie/M
+Biogen/M
+Bioko/M
+Bird/M
+Birdseye/M
+Birgit/M
+Birgitta/M
+Birk/M
+Birkenstock/M
+Birmingham/M
+Biro/M
+Biron/M
+Biscay/M
+Biscayne/M
+Bishkek/M
+Bishop/M
+Bismarck/M
+Bismark/M
+Bisquick/M
+Bissau/M
+BitTorrent/M
+BizRate/M
+Bizet/M
+Bjerknes/M
+Bjork/M
+Bjorn/M
+Bk/M
+Black/MS
+BlackBerry/M
+Blackbeard/M
+Blackburn/M
+Blackfeet/M
+Blackfoot/M
+Blackpool/M
+Blacksburg/M
+Blackshirt/M
+Blackstone/M
+Blackwell/M
+Blaine/M
+Blair/M
+Blake/M
+Blakeley/M
+Blanca/M
+Blanch's
+Blanchard/M
+Blanche/M
+Blane/M
+Blankenship/M
+Blantyre/M
+Blatz/M
+Blavatsky/M
+Blenheim/M
+Blevins/M
+Bligh/M
+BlinkList/M
+Blithe's
+Bloch/M
+Blockbuster/M
+Bloemfontein/M
+Blondel/M
+Blondie/M
+Bloom/MR
+Bloomberg/M
+Bloomer/M
+Bloomfield/M
+Bloomingdale/M
+Bloomington/M
+Bloomsburg/M
+Bloomsbury/M
+Blu
+Blucher/M
+Bluebeard/M
+Bluetooth/M
+Blvd
+Blythe/M
+Bo/MRZ
+Boadicea
+Boas/M
+Bob/M
+Bobbi/M
+Bobbie/M
+Bobbitt/M
+Bobby/M
+Boccaccio/M
+Bodhidharma/M
+Bodhisattva/M
+Bodleian
+Boeing/M
+Boeotia/M
+Boeotian/M
+Boer/M
+Boethius/M
+Bogart/M
+Bogota/M
+Bogot叩/M
+Bohemia/M
+Bohemian/SM
+Bohr/M
+Boise/M
+Bojangles/M
+Boleyn/M
+Bolivar/M
+Bolivia/M
+Bolivian/MS
+Bollywood/M
+Bologna/M
+Bolshevik/SM
+Bolsheviki
+Bolshevism/M
+Bolshevist/M
+Bolshoi/M
+Bolton/M
+Boltzmann/M
+Bombay/M
+Bonaparte/M
+Bonaventure/M
+Bond/M
+Bondy/M
+Bonhoeffer/M
+Boniface/M
+Bonita/M
+Bonn/MR
+Bonner/M
+Bonneville/M
+Bonnie/M
+Bono/M
+Booker/M
+Boole/M
+Boolean/M
+Boone/M
+Bootes/M
+Booth/M
+Boothe/M
+Bord/MN
+Bordeaux/M
+Borden/M
+Bordon/M
+Boreas/M
+Borg/SM
+Borges/M
+Borgia/M
+Borglum/M
+Boris/M
+Bork/M
+Borlaug/M
+Born/M
+Borneo/M
+Borobudur/M
+Borodin/M
+Boru/M
+Bosch/M
+Bose/M
+Bosnia/M
+Bosnian
+Bosporus/M
+Boston/MS
+Bostonian/M
+Boswell/M
+Botha
+Botox
+Botswana/M
+Botticelli/M
+Boulder/M
+Boulez/M
+Bourbaki/M
+Bourbon/SM
+Bourke/M
+Bournemouth/M
+Bovary/M
+Bowditch/M
+Bowell/M
+Bowen/M
+Bowers/M
+Bowery/M
+Bowie/M
+Bowman/M
+Boyce/M
+Boyd/M
+Boyer/M
+Boyle/M
+Bo旦tes/M
+Br/MNT
+Brad/MNY
+Bradbury/M
+Braddock/M
+Braden/M
+Bradenton/M
+Bradford/M
+Bradley/M
+Bradly/M
+Bradshaw/M
+Bradstreet/M
+Brady/M
+Bragg/M
+Brahe/M
+Brahma/MS
+Brahmagupta/M
+Brahman/MS
+Brahmani
+Brahmanism/SM
+Brahmaputra/M
+Brahms/M
+Braille/MS
+Brain/M
+Bram/M
+Brampton/M
+Bran/M
+Branch/M
+Brande/MR
+Brandeis/M
+Branden/M
+Brandenburg/M
+Brander/M
+Brandi/M
+Brandie/M
+Brando/M
+Brandon/M
+Brandt/M
+Brandy/M
+Brannon/M
+Brant/M
+Brantley/M
+Braque/M
+Brasilia/M
+Bratislava/M
+Brattain/M
+Bray/M
+Brazil/M
+Brazilian/MS
+Brazos/M
+Brazzaville/M
+Breakspear/M
+Breathalyzer
+Brecht/M
+Breckenridge/M
+Bree/M
+Bremen/M
+Bremerton/M
+Bren/M
+Brenda/M
+Brendan/M
+Brenden/M
+Brendon/M
+Brenna/M
+Brennan/M
+Brenner/M
+Brent/M
+Brenton/M
+Brest/M
+Bret/M
+Breton/M
+Brett/M
+Brewer/M
+Brewster/M
+Brexit
+Brezhnev/M
+Brian/M
+Briana/M
+Brianna/M
+Brianne/M
+Briant/M
+Brice/M
+Bridalveil/M
+Bridgeport/M
+Bridger/M
+Bridges/M
+Bridget/M
+Bridgetown/M
+Bridgett/M
+Bridgette/M
+Bridgman/M
+Bridie/M
+Brie/SM
+Brien/M
+Brigadoon/M
+Brigg/MS
+Briggs/M
+Brigham/M
+Bright/M
+Brighton/M
+Brigid/M
+Brigida/M
+Brigit/M
+Brigitta/M
+Brigitte/M
+Brillo/M
+Brillouin
+Brinkley/M
+Briny's
+Brion/M
+Brisbane/M
+Bristol/M
+Brit/SM
+Brita/M
+Britain/M
+Britannia/M
+Britannic/M
+Britannica/M
+Briticism/SM
+British/MRZ
+Britisher/M
+Britney/M
+Briton/MS
+Britt/MN
+Britta/M
+Brittan/M
+Brittany/SM
+Britten/M
+Brittney/M
+Brno/M
+Broadway/SM
+Brobdingnag/M
+Brobdingnagian/M
+Brock/M
+Brod/M
+Broderick/M
+Brodie/M
+Brody/M
+Brokaw/M
+Bron/M
+Bronson/M
+Bronte/M
+Brontosaurus
+Bronx/M
+Brooke/MS
+Brooklyn/M
+Brooks/M
+Bros
+Brose/M
+Brown/MG
+Browne/M
+Brownian/M
+Brownie/S
+Browning/M
+Brownshirt/M
+Brownsville/M
+Brubeck/M
+Bruce/M
+Bruckner/M
+Bruegel
+Brummel/M
+Brunei/M
+Bruneian/MS
+Brunelleschi/M
+Brunhilde/M
+Bruno/M
+Brunswick/M
+Brussels/M
+Brut/M
+Brutus/M
+Bryan/M
+Bryant/M
+Bryce/M
+Bryn/M
+Brynn/MR
+Brynner/M
+Bryon/M
+Brzezinski/M
+Btu/M
+Buber/M
+Buchanan/M
+Bucharest/M
+Buchenwald/M
+Buchwald/M
+Buck/M
+Buckingham/M
+Buckley/M
+Buckner/M
+Bucky/M
+Bud/M
+Budapest/M
+Budd/M
+Buddha/SM
+Buddhism/SM
+Buddhist/SM
+Buddy/M
+Budweiser/M
+Buenos
+Buffalo/M
+Buffy/M
+Buford/M
+Bugatti/M
+Bugzilla/M
+Buick/M
+Bujumbura/M
+Bukhara/M
+Bukharin/M
+Bulawayo/M
+Bulfinch/M
+Bulganin/M
+Bulgar/M
+Bulgari/M
+Bulgaria/M
+Bulgarian/SM
+Bullock/M
+Bullwinkle/M
+Bultmann/M
+Bumppo/M
+Bunche/M
+Bundesbank/M
+Bundestag/M
+Bunin/M
+Bunker/M
+Bunsen/M
+Bunuel/M
+Bunyan/M
+Burbank/M
+Burberry/M
+Burch/M
+Burger/M
+Burgess/M
+Burgoyne/M
+Burgundian/M
+Burgundy/SM
+Burk/SM
+Burke/M
+Burkina/M
+Burks/M
+Burl/M
+Burlington/M
+Burma/M
+Burmese/M
+Burnaby/M
+Burnard/M
+Burnett/M
+Burns/M
+Burnside/M
+Burr/M
+Burris/M
+Burroughs/M
+Bursa/M
+Burt/M
+Burton/M
+Burundi/M
+Burundian/MS
+Busch/M
+Bush/M
+Bushido/M
+Bushnell/M
+Butler/M
+Butterfingers/M
+Buxtehude/M
+Bu単uel/M
+Byblos/M
+Byers/M
+Byram/M
+Byrd/M
+Byrom/M
+Byron/M
+Byronic/M
+Byzantine/MS
+Byzantium/M
+C/SMD
+CA
+CAD/M
+CAI
+CAM
+CAP
+CAPTCHA
+CARE
+CATV
+CB
+CBC/M
+CBS/M
+CCTV
+CCU
+CD/SM
+CDC
+CDT
+CEO/SM
+CF
+CFC/SM
+CFO
+CGI
+CIA/M
+CID
+CNN/M
+CNS/M
+CO/M
+COBOL/SM
+COD
+COL
+COLA
+COVID
+CPA/M
+CPI/M
+CPO
+CPR/M
+CPU/M
+CRT/SM
+CSS/M
+CST/M
+CT/M
+CV
+CVS/M
+CZ
+Ca/M
+Cabernet/M
+Cabot/M
+Cabral/M
+Cabrera/M
+Cabrini/M
+Cad/M
+Cadette
+Cadillac/M
+Cadiz/M
+Caedmon/M
+Caerphilly/M
+Caesar/SM
+Cage/M
+Cagney/M
+Cahokia/M
+Caiaphas/M
+Caicos/M
+Cain/SM
+Cairo/M
+Caitlin/M
+Cajun/MS
+Cal/MY
+Calais/M
+Calcutta/M
+Calder/M
+Calderon/M
+Caldwell/M
+Cale/M
+Caleb/M
+Caledonia/M
+Calexico/M
+Calgary/M
+Calhoun/M
+Cali/M
+Caliban/M
+Calif
+California/M
+Californian/SM
+Caligula/M
+Callaghan/M
+Callahan/M
+Callao/M
+Callas/M
+Calley/M
+Calli/M
+Callie/M
+Calliope/M
+Callisto/M
+Cally/M
+Caloocan/M
+Calvary/M
+Calvert/M
+Calvin/M
+Calvinism/MS
+Calvinist/MS
+Calvinistic
+Camacho/M
+Camarillo/M
+Cambodia/M
+Cambodian/SM
+Cambrian/SM
+Cambridge/M
+Cambridgeshire/M
+Camden/M
+Camel/M
+Camelopardalis/M
+Camelot/MS
+Camembert/MS
+Cameron/M
+Cameroon/SM
+Cameroonian/MS
+Cami/M
+Camila/M
+Camilla/M
+Camille/M
+Cammie/M
+Cammy/M
+Camoens/M
+Campanella/M
+Campbell/M
+Campinas/M
+Campos/M
+Camry/M
+Camus/M
+Can/M
+Canaan/M
+Canaanite/MS
+Canad
+Canada/M
+Canadian/SM
+Canadianism
+Canaletto/M
+Canaries/M
+Canaveral/M
+Canberra/M
+Cancer/SM
+Cancun/M
+Candace/M
+Candi/M
+Candice/M
+Candida/M
+Candide/M
+Candra/M
+Candy/M
+Cannes/M
+Cannon/M
+Canon/M
+Canopus/M
+Cantabrigian/M
+Canterbury/M
+Canton/M
+Cantonese/M
+Cantor/M
+Cantrell/M
+Cantu/M
+Canute/M
+Capablanca/M
+Capek/M
+Capella/M
+Capet/M
+Capetian/M
+Capetown/M
+Caph/M
+Capistrano/M
+Capitol/SM
+Capitoline/M
+Capone/M
+Capote/M
+Capra/M
+Capri/M
+Capricorn/MS
+Capt
+Capuchin/M
+Capulet/M
+Cara/M
+Caracalla/M
+Caracas/M
+Caravaggio/M
+Carboloy/M
+Carbondale/M
+Carboniferous/M
+Carborundum/M
+Cardenas/M
+Cardiff/M
+Cardin/M
+Cardozo/M
+CareerBuilder/M
+Caren/M
+Carey/M
+Cari/M
+Caria
+Carib/MS
+Caribbean/MS
+Carin/M
+Carina/M
+Carine/M
+Carissa/M
+Carita/M
+Carl/GMN
+Carla/M
+Carlen/M
+Carlene/M
+Carleton/M
+Carley/M
+Carlie/M
+Carlin/M
+Carling/M
+Carlisle/M
+Carlo/MS
+Carlos/M
+Carlota
+Carlotta/M
+Carlsbad/M
+Carlson/M
+Carlton/M
+Carly/M
+Carlyle/M
+Carmel
+Carmela/M
+Carmelita/M
+Carmella/M
+Carmelo/M
+Carmen/M
+Carmichael/M
+Carmina/M
+Carmine/M
+Carnap/M
+Carnation/M
+Carnegie/M
+Carney/M
+Carnot/M
+Caro/M
+Carol/M
+Carola/M
+Carolan/M
+Carole/M
+Carolina/M
+Caroline/M
+Carolingian/M
+Carolinian/M
+Carolus/M
+Carolyn/M
+Carolyne/M
+Caron/M
+Carpathian/SM
+Carpathians/M
+Carpenter/M
+Carr/M
+Carranza/M
+Carrie/RM
+Carrier/M
+Carrillo/M
+Carrol/M
+Carroll/M
+Carson/M
+Carter/M
+Cartersville/M
+Cartesian/M
+Carthage/M
+Carthaginian/MS
+Cartier/M
+Cartwright/M
+Caruso/M
+Carver/M
+Cary/M
+Caryl/M
+Caryn/M
+Casablanca/M
+Casals/M
+Casandra/M
+Casanova/SM
+Casar/M
+Cascades/M
+Case/M
+Casey/M
+Cash/M
+Casi/M
+Casio/M
+Caspar/M
+Casper/M
+Caspian/M
+Cass/M
+Cassandra/SM
+Cassatt/M
+Cassi/M
+Cassidy/M
+Cassie/M
+Cassini/M
+Cassiopeia/M
+Cassius/M
+Cassy/M
+Castaneda/M
+Castile/M
+Castilian
+Castillo/M
+Castlereagh/M
+Castor/M
+Castries/M
+Castro/M
+Catalan/SM
+Catalina/M
+Catalonia/M
+Catarina/M
+Catawba/M
+Cate/M
+Caterina/M
+Caterpillar/M
+Catharina/M
+Catharine/M
+Cathay/M
+Cather/M
+Catherine/M
+Cathie/M
+Cathleen/M
+Catholic/MS
+Catholicism/MS
+Cathryn/M
+Cathy/M
+Cati/M
+Catie/M
+Catiline/M
+Catlin/M
+Cato/M
+Catrina/M
+Catriona/M
+Catskill/SM
+Catskills/M
+Catt/M
+Catullus/M
+Caucasian/MS
+Caucasoid
+Caucasus/M
+Cauchy/M
+Cavendish/M
+Cavour/M
+Caxton/M
+Caye/M
+Cayenne/M
+Cayman/M
+Cayuga/SM
+Cayuse
+Caz/M
+Cb
+Cd/M
+Ce/M
+Ceausescu/M
+Cebu/M
+Cebuano/M
+Cece/M
+Cecelia/M
+Cecil/M
+Cecile/M
+Cecilia/M
+Cecilio/M
+Cecily/M
+Ced/M
+Cedric/M
+Ceil/M
+Cele/M
+Celebes/M
+Celeste/M
+Celestia/M
+Celestina/M
+Celestine/M
+Celgene/M
+Celia/M
+Celie/M
+Celina/M
+Celine/M
+Celle/M
+Cellini/M
+Celsius/M
+Celt/SM
+Celtic/SM
+Cenozoic/M
+Centaurus/M
+Centigrade
+Central
+Centro/M
+Cepheid/M
+Cepheus/M
+Cerberus/M
+Cerenkov/M
+Ceres/M
+Cerf/M
+Cervantes/M
+Cesar/M
+Cesare/M
+Cesarean/M
+Cessna/M
+Cetus/M
+Ceylon/M
+Ceylonese
+Cezanne/M
+Cf/M
+Ch'in/M
+Ch/NRS
+Chablis/M
+Chad/M
+Chadian/MS
+Chadwick/M
+Chagall/M
+Chaim/M
+Chaitanya/M
+Chaitin/M
+Chaldea
+Chaldean/M
+Challenger/M
+Chalmers
+Chamberlain/M
+Chambers/M
+Chambersburg/M
+Champaign/M
+Champlain/M
+Champollion/M
+Chan/M
+Chance/M
+Chancellorsville/M
+Chancey/M
+Chanda/M
+Chandigarh/M
+Chandler/M
+Chandon/M
+Chandra/M
+Chandragupta/M
+Chandrasekhar/M
+Chane/M
+Chanel/M
+Chaney/M
+Chang/M
+Changchun/M
+Changsha/M
+Channa/M
+Chantal/M
+Chantilly/M
+Chaplin/M
+Chaplinesque
+Chapman/M
+Chappaquiddick/M
+Chapultepec/M
+Chara
+Charbray/M
+Chardonnay/M
+Charis
+Charisse/M
+Charity/M
+Charlemagne/M
+Charlene/M
+Charles/M
+Charleston/MS
+Charley/M
+Charlie/M
+Charlot/M
+Charlotta/M
+Charlotte/M
+Charlottesville/M
+Charlottetown/M
+Charlton
+Charmaine/M
+Charmian/M
+Charmin/M
+Charolais/M
+Charon/M
+Chartism/M
+Chartres/M
+Charybdis/M
+Chas
+Chase/M
+Chasity/M
+ChatZilla/M
+Chateaubriand/M
+Chatham/M
+Chattahoochee/M
+Chattanooga/M
+Chatterley/M
+Chatterton/M
+Chaucer/M
+Chauncey/M
+Chautauqua/M
+Chavez/M
+Chayefsky/M
+Che/M
+Chechen/M
+Chechnya/M
+Cheddar/M
+Cheer/M
+Cheerios/M
+Cheetos/M
+Cheever/M
+Chekhov/M
+Chekhovian
+Chelsea/M
+Chelyabinsk/M
+Chen/M
+Cheney/M
+Chengdu/M
+Chennai/M
+Cheops/M
+Chere/M
+Cheri/M
+Cherie/M
+Cherise/M
+Cherish's
+Chernenko/M
+Chernobyl/M
+Chernomyrdin/M
+Cherokee/MS
+Cherry/M
+Cheryl/M
+Chesapeake/M
+Cheshire/M
+Chester/M
+Chesterfield/M
+Chesterton/M
+Chet/M
+Chev/M
+Chevalier/M
+Cheviot/M
+Chevrolet/M
+Chevron/M
+Chevy/M
+Cheyenne/SM
+Chi/M
+Chianti/MS
+Chiba/M
+Chibcha/M
+Chicago/M
+Chicagoan/M
+Chicana/M
+Chicano/M
+Chickasaw/MS
+Chiclets/M
+Chico/M
+Chihuahua/MS
+Chile/M
+Chilean/MS
+Chilton/M
+Chimborazo/M
+Chimera/MS
+Chimu/M
+Chin/M
+China/M
+Chinatown/M
+Chinese/M
+Chinook/MS
+Chipewyan/M
+Chippendale/M
+Chippewa/SM
+Chiquita/M
+Chirico/M
+Chisholm/M
+Chisinau/M
+Chittagong/M
+Chivas/M
+Chloe/M
+Chloris/M
+Choctaw/SM
+Choi/M
+Chomsky/M
+Chongqing/M
+Chopin/M
+Chopra/M
+Chou/M
+Chretien/M
+Chris/M
+Chrissie/M
+Chrissy/M
+Christ/MS
+Christa/M
+Christabel/M
+Christchurch/M
+Christel/M
+Christen's
+Christendom/MS
+Christensen/M
+Christi/M
+Christian/SM
+Christiana/M
+Christiane/M
+Christianity/SM
+Christianize/DG
+Christie/M
+Christina/M
+Christine/M
+Christlike
+Christmas/MS
+Christmastide/MS
+Christmastime/MS
+Christoper/M
+Christoph/MR
+Christophe
+Christopher/M
+Christos/M
+Chromebook/MS
+Chronicles
+Chrysler/M
+Chrysostom/M
+Chrystal/M
+Chuck/M
+Chukchi/M
+Chumash/M
+Chung/M
+Church/M
+Churchill/M
+Churriguera/M
+Chuvash/M
+Ci/M
+Cicely/M
+Cicero/M
+Cid/M
+Ciel/M
+Cimabue/M
+Cincinnati/M
+Cinderella/MS
+Cindi/M
+Cindy/M
+CinemaScope/M
+Cinerama/M
+Cingular/M
+Cipro/M
+Circe/M
+Cirillo/M
+Ciro/M
+Cisco/M
+Cissy/M
+Citibank/M
+Citigroup/M
+Citroen/M
+Cl/MV
+Claiborne/M
+Clair/M
+Claire/M
+Clairol/M
+Clancy/M
+Clapeyron/M
+Clapton/M
+Clara/M
+Clare/M
+Clarence/M
+Clarendon/M
+Clari/M
+Claribel/M
+Clarice/M
+Clarinda/M
+Clarissa/M
+Clarisse/M
+Clarita/M
+Clark/M
+Clarke/M
+Clarkson/M
+Clarksville/M
+Clary/M
+Claude/M
+Claudette/M
+Claudia/M
+Claudian/M
+Claudine/M
+Claudio/M
+Claudius/M
+Claus/M
+Clausewitz/M
+Clausius/M
+Clay/M
+Clayborne/M
+Clayton/M
+Clea/M
+Clearasil/M
+Clem/XM
+Clemence/M
+Clemenceau/M
+Clemens/M
+Clement/MS
+Clemente/M
+Clementina/M
+Clementine/M
+Clements/M
+Clemmie/M
+Clemons/M
+Clemson/M
+Cleo/M
+Cleon
+Cleopatra/M
+Clerc/M
+Cletus/M
+Cleve/M
+Cleveland/M
+Cliburn/M
+Cliff/M
+Clifford/M
+Clifton/M
+Cline/M
+Clint/M
+Clinton/M
+Clio/M
+Clive/M
+Clo/M
+Clojure/M
+Clorets/M
+Clorox/M
+Closure/M
+Clotho/M
+Clotilda/M
+Clouseau/M
+Clovis/M
+Clyde/M
+Clydesdale/M
+Clytemnestra/M
+Cm/M
+Cmdr
+Co/M
+Cobain/M
+Cobb/M
+Cochabamba/M
+Cochin/M
+Cochise/M
+Cochran/M
+Cockney/M
+Cocteau/M
+Cod
+Cody/M
+Coffey/M
+Cognac/M
+Cohan/M
+Cohen/M
+Coimbatore/M
+Cointreau/M
+Coke/SM
+Col/M
+Colbert/M
+Colby/M
+ColdFusion/M
+Cole/M
+Coleen/M
+Coleman/M
+Coleridge/M
+Colet
+Coletta/M
+Colette/M
+Colfax/M
+Colgate/M
+Colin/M
+Colleen/M
+Collen/M
+Collette/M
+Collier/M
+Collin/SM
+Colline/M
+Collins/M
+Colman/M
+Colo
+Cologne/M
+Colombia/M
+Colombian/MS
+Colombo/M
+Colon/M
+Coloradan/SM
+Colorado/M
+Coloradoan
+Colosseum/M
+Colt/M
+Coltrane/M
+Columbia/M
+Columbine/M
+Columbus/M
+Com
+Comanche/MS
+Combs/M
+Comcast/M
+Comdr
+Comintern/M
+Commandment
+Commons/M
+Commonwealth
+Communion/SM
+Communism
+Communist/SM
+Como/M
+Comoran
+Comoros/M
+Compaq/M
+Compton/M
+CompuServe/M
+Computerworld/M
+Comte/M
+Conakry/M
+Conan/M
+Conant/M
+Concepcion/M
+Concepci坦n/M
+Concetta/M
+Conchita/M
+Concord/SM
+Concorde/M
+Concordia/M
+Condillac/M
+Condorcet/M
+Conestoga/M
+Confederacy/M
+Confederate/MS
+Confucian/SM
+Confucianism/MS
+Confucius/M
+Cong/M
+Congo/M
+Congolese/M
+Congregational
+Congregationalist/MS
+Congress/MS
+Congressional/Y
+Congreve/M
+Conley/M
+Conn/MR
+Connecticut/M
+Connellsville/M
+Connemara/M
+Conner/M
+Connery/M
+Connie/M
+Connolly/M
+Connor/SM
+Connors/M
+Conny/M
+Conrad/M
+Conrado/M
+Conrail/M
+Conroe/M
+Conroy/M
+Conservative
+Constable/M
+Constance/M
+Constancia/M
+Constanta/M
+Constantia
+Constantin/M
+Constantine/M
+Constantino/M
+Constantinople/M
+Constitution
+Consuela/M
+Consuelo/M
+Continent/M
+Continental/M
+Contreras/M
+Conway/M
+Cook/M
+Cooke/M
+Cooley/M
+Coolidge/M
+Cooper/M
+Cooperstown/M
+Coors/M
+Copacabana/M
+Copeland/M
+Copenhagen/M
+Copernican/M
+Copernicus/M
+Copland/M
+Copley/M
+Copperfield/M
+Coppertone/M
+Coppola/M
+Coptic/M
+Cora/M
+Coralie/M
+Corbet/M
+Corbett/M
+Corbie/M
+Corbin/M
+Corby
+Cordelia/M
+Cordell/M
+Cordilleras/M
+Cordoba/M
+Cordy/M
+Coretta/M
+Corey/M
+Corfu/M
+Cori/M
+Corina/M
+Corine/M
+Corinna/M
+Corinne/M
+Corinth/M
+Corinthian/MS
+Corinthians/M
+Coriolanus/M
+Coriolis/M
+Cork
+Corleone/M
+Corliss/M
+Cormack/M
+Corneille/M
+Cornelia/M
+Cornelius/M
+Cornell/M
+Corney/M
+Corning/M
+Cornish/MS
+Cornwall/M
+Cornwallis/M
+Corny's
+Coronado/M
+Corot/M
+Corp
+Correggio/M
+Corrie/M
+Corrine/M
+Corry/M
+Corsica/M
+Corsican/M
+Cort/M
+Cortes/MS
+Cortland/M
+Corvallis/M
+Corvette/M
+Corvus/M
+Cory/M
+Cosby/M
+Cosette/M
+Cosimo/M
+Cosme/M
+Cosmo/M
+CosmosDB/M
+Cossack/M
+Costa/M
+Costanza/M
+Costco/M
+Costello/M
+Costner/M
+Cote/M
+Cotonou/M
+Cotopaxi/M
+Cotswold/M
+Cotton/M
+Coulomb/M
+Coulter/M
+Councillor/MS
+Couperin/M
+Courbet/M
+Courtenay/M
+Courtney/M
+Cousteau/M
+Coventry/SM
+Covington/M
+Coward/M
+Cowell/M
+Cowley/M
+Cowper/M
+Cox/M
+Coy/M
+Coyle/M
+Cozumel/M
+Cpl
+Cr/MT
+Crabbe/M
+Craft/M
+Craggy's
+Craig/M
+Craigslist/M
+Cranach/M
+Crane/M
+Cranmer/M
+Crater/M
+Crawford/M
+Cray/M
+Crayola/M
+Creation/M
+Creator/M
+Crecy/M
+Cree/DSM
+Creek/SM
+Creighton/M
+Creole/SM
+Creon/M
+Cressida/M
+Crest/M
+Cretaceous/M
+Cretan/SM
+Crete/M
+Crichton/M
+Crick/M
+Crimea/M
+Crimean/M
+Criollo/M
+Cris/M
+Crisco/M
+Crissy/M
+Crista/M
+Cristal/M
+Cristian/M
+Cristiano/M
+Cristina/M
+Cristobal/M
+Croat/SM
+Croatia/M
+Croatian/MS
+Croce/M
+Crockett/M
+Croesus/M
+Cromwell/M
+Cromwellian/M
+Cronin/M
+Cronkite/M
+Cronus/M
+Crookes/M
+Crosby/M
+Cross/M
+Crow/SM
+Crowley/M
+Crucifixion/MS
+Cruikshank/M
+Cruise/M
+Crusades's
+Crusoe/M
+Crux/M
+Cruz/M
+Cryptozoic/M
+Crystal/M
+Csonka/M
+Ct
+Ctesiphon/M
+Cthulhu/M
+Cu/M
+Cuba/M
+Cuban/SM
+Cuchulain/M
+Cuisinart/M
+Culbertson/M
+Cullen/M
+Culley/M
+Cully/M
+Culver/M
+Cumberland/M
+Cumbria/M
+Cummings/M
+Cunard/M
+Cunningham/M
+Cupid/M
+Curacao/M
+Curcio/M
+Curie/M
+Curitiba/M
+Curr/M
+Curran/M
+Currey/M
+Currie/M
+Currier/M
+Curry/RM
+Curt/M
+Curtice/M
+Curtis/M
+Custer/M
+Cuvier/M
+Cuzco/M
+Cy
+Cybele/M
+Cybil/M
+Cyclades/M
+Cyclopes/M
+Cyclops/M
+Cygnus/M
+Cymbeline/M
+Cyndi/M
+Cynthia/M
+Cynthy/M
+Cyprian/M
+Cypriot/MS
+Cyprus/M
+Cyrano/M
+Cyril/M
+Cyrille/M
+Cyrillic/M
+Cyrus/M
+Czech/M
+Czechia/M
+Czechoslovak
+Czechoslovakia/M
+Czechoslovakian/SM
+Czechs
+Czerny/M
+D'Arcy
+D/M
+DA/M
+DAR
+DAT/M
+DBMS/M
+DC/M
+DD/M
+DDS/M
+DDT/S
+DE
+DEA
+DEC/SD
+DH
+DHS
+DI
+DJ
+DMCA
+DMD/M
+DMZ
+DNA/M
+DOA
+DOB
+DOD
+DOE
+DOS/M
+DOT
+DP/SM
+DPT
+DRM
+DST
+DTP
+DUI
+DVD/S
+DVR/SM
+DWI
+Dacey/M
+Dachau/M
+Dacia
+Dacron/SM
+Dada/M
+Dadaism/M
+Daedalus/M
+Daffy's
+Dag's
+Dagmar/M
+Dagny/M
+Daguerre/M
+Dagwood/M
+Dahomey/M
+Daimler/M
+Daisy/M
+Dakar/M
+Dakota/SM
+Dakotan/M
+Dal/M
+Dalai
+Dale/M
+Daley/M
+Dali/M
+Dalia/M
+Dalian/M
+Dalila/M
+Dall/M
+Dallas/M
+Dalmatia/M
+Dalmatian/SM
+Dalton/M
+Damara/M
+Damaris/M
+Damascus/M
+Dame/MN
+Damian/M
+Damiano/M
+Damien/M
+Damion/M
+Damocles/M
+Damon/M
+Dan/M
+Dana/M
+Danae/M
+Dana谷/M
+Danbury/M
+Dane/SM
+Danelaw/M
+Danette/M
+Dangerfield/M
+Dani/M
+Dania/M
+Danial/M
+Danica/M
+Daniel/SM
+Daniela/M
+Daniele/M
+Daniella/M
+Danielle/M
+Daniels/M
+Danish/M
+Danna/M
+Danni/M
+Dannie/M
+Danny/M
+Danone/M
+Dante/M
+Danton/M
+Danube/M
+Danubian/M
+Danville/M
+Daphne/M
+Dar/MNH
+Dara/M
+Darby/M
+Darcey/M
+Darci/M
+Darcie/M
+Darcy/M
+Dardanelles/M
+Dare/M
+Daren/M
+Darfur/M
+Dari/M
+Daria/M
+Darin/M
+Dario/M
+Darius/M
+Darjeeling/M
+Darla/M
+Darlene/M
+Darling/M
+Darnell/M
+Daron/M
+Darrel/M
+Darrell/M
+Darren/M
+Darrin/M
+Darrow/M
+Darryl/M
+Darsie/M
+Darth/M
+Dartmoor/M
+Dartmouth/M
+Darvon/M
+Darwin/M
+Darwinian/M
+Darwinism/SM
+Darwinist
+Darya/M
+Daryl/M
+Dasha/M
+Datamation
+Daugherty/M
+Daumier/M
+Dav/M
+Davao/M
+Dave/M
+Davenport/M
+Davey/M
+David/MS
+Davida/M
+Davide/M
+Davidson/M
+Davie/M
+Davies/M
+Davin/M
+Davina/M
+Davis/M
+Davy/SM
+Dawes/M
+Dawkins
+Dawn/M
+Dawson/M
+Day/M
+Dayan
+Dayna/M
+Dayton/M
+Daytona/M
+De/RSMN
+DeGeneres/M
+DeKalb/M
+Deadhead/M
+DealTime/M
+Dean/M
+Deana/M
+Deandre/M
+Deane/M
+Deann/M
+Deanna/M
+Deanne/M
+Death/M
+Deb/SM
+Debbi/M
+Debbie/M
+Debby/M
+Debi/M
+Debian/M
+Debora/M
+Deborah/M
+Debouillet/M
+Debra/M
+Debs/M
+Debussy/M
+Dec/M
+Decalogue/M
+Decatur/M
+Decca/M
+Deccan/M
+December/SM
+Decker/M
+Dede/M
+Dedekind/M
+Dee/M
+Deedee/M
+Deena/M
+Deere/M
+Defoe/M
+Degas/M
+Deidre/M
+Deimos/M
+Deirdre/M
+Deity
+Dejesus/M
+Del/M
+Dela/M
+Delacroix/M
+Delacruz/M
+Delaney/M
+Delano/M
+Delaware/MS
+Delawarean/SM
+Delbert/M
+Deleon/M
+Delgado/M
+Delhi/M
+Delia/M
+Delibes/M
+Delicious/M
+Delilah/M
+Delilahs
+Delius/M
+Dell/M
+Della/M
+Delmar/M
+Delmarva/M
+Delmer/M
+Delmonico/M
+Delmore/M
+Deloitte/M
+Delores/M
+Deloria/M
+Deloris/M
+Delphi/M
+Delphic/M
+Delphine/M
+Delphinus/M
+Delta/M
+Deltona/M
+Dem/G
+Demavend/M
+Demerol/M
+Demeter/M
+Demetri/M
+Demetria/M
+Demetrius/M
+Deming/M
+Democrat/SM
+Democratic
+Democritus/M
+Demosthenes/M
+Demott/M
+Dempsey/M
+Dena/M
+Denali
+Dene
+Deneb/M
+Denebola/M
+Deng/M
+Deni/SM
+Denis/M
+Denise/M
+Denmark/M
+Denney/M
+Dennie/M
+Dennis/M
+Dennison/M
+Denny/M
+Denton/M
+Denver/M
+Deny's
+Denys
+Deon/M
+Depp/M
+Der/M
+Derby/M
+Derek/M
+Derick/M
+Derk/M
+Dermot/M
+Derrick/M
+Derrida/M
+Derry
+Descartes/M
+Desdemona/M
+Deseret/M
+Desi/M
+Desiree/M
+Desmond/M
+Detroit/M
+Deuteronomy/M
+Deutschmark/SM
+Dev/M
+Deva/M
+Devan/M
+Devanagari/M
+Devi/M
+Devil/M
+Devin/M
+Devlin/M
+Devon/M
+Devonian/M
+Dewar/M
+Dewayne/M
+Dewey/M
+Dewitt/M
+Dex/M
+Dexedrine/M
+Dexter/M
+Dhabi
+Dhaka/M
+Dhaulagiri/M
+Di/SM
+DiCaprio/M
+DiMaggio/M
+Diaghilev/M
+Dial/M
+Dian/M
+Diana/M
+Diane/M
+Diann/M
+Dianna/M
+Dianne/M
+Dias
+Diaspora/MS
+Dick/XM
+Dickens/M
+Dickensian
+Dickerson/M
+Dickie/M
+Dickinson/M
+Dickson/M
+Dicky/M
+Dictaphone/SM
+Diderot/M
+Didi/M
+Dido/M
+Didrikson/M
+Diefenbaker/M
+Diego/M
+Diem/M
+Dierdre/M
+Dieter/M
+Dietrich/M
+Digg/SM
+Dijkstra/M
+Dijon/M
+Dilbert/MS
+Dillard/M
+Dillinger/M
+Dillon/M
+Dimitri/M
+Dina/M
+Dinah/M
+Dinny/M
+Dino/M
+Diocletian/M
+Diogenes/M
+Dion/M
+Dione
+Dionisio/M
+Dionne/M
+Dionysian/M
+Dionysus/M
+Diophantine/M
+Dior/M
+Dipper/M
+Dir
+Dirac/M
+Dirichlet/M
+Dirk/M
+Dis/M
+Disney/M
+Disneyland/M
+Disraeli/M
+Dita/M
+DivX/M
+Divine/M
+Diwali/M
+Dix/M
+Dixie/M
+Dixiecrat/M
+Dixieland/SM
+Dixon/M
+Django/M
+Djibouti/M
+Dmitri/M
+Dnepr
+Dnepropetrovsk/M
+Dnieper/M
+Dniester/M
+Dobbin/M
+Doberman/M
+Dobro/M
+Doctor
+Doctorow/M
+Dodge/M
+Dodgson/M
+Dodi/M
+Dodie/M
+Dodoma/M
+Dodson/M
+Doe/M
+Doha/M
+Dolby/M
+Dole/M
+Dolf/M
+Dolley/M
+Dollie/M
+Dolly/M
+Dolores/M
+Dolph/M
+Dom
+Domenic/M
+Domenico/M
+Domesday/M
+Domingo/M
+Dominguez/M
+Domini/M
+Dominic/M
+Dominica/M
+Dominican/MS
+Dominick/M
+Dominik/M
+Dominion
+Dominique/M
+Domitian/M
+Don/SM
+Dona/M
+Donahue/M
+Donal/M
+Donald/M
+Donaldson/M
+Donatello/M
+Donetsk/M
+Donizetti/M
+Donn/MR
+Donna/M
+Donne/M
+Donnell/M
+Donner/M
+Donnie/M
+Donny/M
+Donovan/M
+Dooley/M
+Doolittle/M
+Doonesbury/M
+Doppler/M
+Dora/M
+Dorcas/M
+Dore/M
+Doreen/M
+Dorey/M
+Dori/SM
+Doria/M
+Dorian/M
+Doric/M
+Dorie/M
+Doris/M
+Dorise/M
+Doritos/M
+Doro/M
+Dorotea/M
+Dorothea/M
+Dorothee/M
+Dorothy/M
+Dorrie/M
+Dorris
+Dorset/M
+Dorsey/M
+Dorthy/M
+Dortmund/M
+Dosi/M
+Dostoevsky/M
+Dot/M
+Dothan/M
+Dotson/M
+Dottie/M
+Dotty's
+Douala/M
+Douay/M
+Doubleday/M
+Doug/M
+Dougie/M
+Douglas/M
+Douglass/M
+Douro/M
+Dov/MR
+Dover/M
+Dow/M
+Downs/M
+Downy/M
+Doy/M
+Doyle/M
+Dr
+Draco/M
+Draconian/M
+Dracula/M
+Drake/M
+Dramamine/SM
+Drambuie/M
+Drano/M
+Dravidian/M
+Dre/M
+Dreamweaver/M
+Dreiser/M
+Dresden/M
+Drew/M
+Dreyfus/M
+Dristan/M
+Drona/M
+Dropbox/M
+Dru/M
+Drudge/M
+Druid/M
+Drupal/M
+Drusilla/M
+Dryden/M
+Dschubba/M
+Du
+DuPont/M
+Duane/M
+Dubai/M
+Dubcek/M
+Dubhe/M
+Dublin/M
+Dubrovnik/M
+Dubuque/M
+Duchamp/M
+Dudley/M
+Duff/M
+Duffie/M
+Duffy/M
+Dugald/M
+Duisburg/M
+Duke/M
+Dulce/M
+Dulcie/M
+Dulcinea/M
+Dulles/M
+Duluth/M
+Dumas/M
+Dumbledore/M
+Dumbo/M
+Dunant/M
+Dunbar/M
+Duncan/M
+Dundee
+Dunedin/M
+Dunkirk/M
+Dunlap/M
+Dunn/M
+Dunne/M
+Dunstan
+Dur/R
+Duracell/M
+Duran/M
+Durand/M
+Durant/M
+Durante/M
+Durban/M
+Durer/M
+Durex/M
+Durham/MS
+Durkheim/M
+Duroc/M
+Durocher/M
+Durward/M
+Duse/M
+Dushanbe/M
+Dusseldorf/M
+Dustbuster/M
+Dustin/M
+Dusty/M
+Dutch/M
+Dutchman/M
+Dutchmen/M
+Dutchwoman
+Duvalier/M
+Dvina/M
+Dvorak/M
+Dvor叩k/M
+Dwayne/M
+Dwight/M
+Dy/M
+Dyan/M
+Dyer/M
+Dylan/M
+Dyna/M
+DynamoDB/M
+Dyson/M
+Dzerzhinsky/M
+Dzungaria/M
+D端rer/M
+D端sseldorf/M
+E/SMY
+EC
+ECG/M
+ECMAScript/M
+EDP/M
+EDT
+EEC/M
+EEG/M
+EEO
+EEOC
+EFL
+EFT
+EKG/M
+ELF/M
+EM
+EMT
+ENE/M
+EOE
+EPA/M
+ER
+ERA
+ESE/M
+ESL
+ESP/M
+ESPN/M
+ESR
+EST/M
+ET
+ETA
+ETD
+EU
+EULA/S
+Eadie/M
+Eakins/M
+Eal/M
+Eamon/M
+Earhart/M
+Earl/M
+Earle/M
+Earlene/M
+Earline/M
+Early's
+Earnest/M
+Earnestine/M
+Earnhardt/M
+Earp/M
+East/SZMR
+Easter/M
+Eastern/R
+Eastman/M
+Easton/M
+Eastwood/M
+Eaton/M
+Eb/MN
+Eba/M
+Ebba/M
+Eben/M
+Ebeneezer/M
+Ebenezer/M
+Eberhard/M
+Ebert/M
+Ebola/M
+Ebonics/M
+Ebony/M
+Ebro/M
+Ecclesiastes/M
+Ecma/M
+Eco/M
+Ecstasy
+Ecuador/M
+Ecuadoran/SM
+Ecuadorean
+Ecuadorian/SM
+Ed/MNX
+Eda/M
+Edam/SM
+Edd/M
+Edda/M
+Eddie/M
+Eddington/M
+Eddy/M
+Ede
+Eden/M
+Edgar/M
+Edgard/M
+Edgardo/M
+Edi/MH
+Edie/M
+Edin/M
+Edinburgh/M
+Edison/M
+Edith/M
+Editha/M
+Edlin/M
+Edmond/M
+Edmonton/M
+Edmund/M
+Edna/M
+Edouard/M
+Edsel/M
+Eduard/M
+Eduardo/M
+Edvard/M
+Edward/SM
+Edwardian/M
+Edwardo/M
+Edwards/M
+Edwin/M
+Edwina/M
+Edy/M
+Edythe/M
+Eeyore/M
+Effie/M
+Efrain/M
+Efrem/M
+Efren/M
+Egan/M
+Egbert
+Eggo/M
+Egon/M
+Egor/M
+Egypt/M
+Egyptian/MS
+Egyptology/M
+Ehrenberg/M
+Ehrlich/M
+Eichmann/M
+Eiffel/M
+Eileen/M
+Einstein/MS
+Einsteinian/M
+Eire/M
+Eisenhower/M
+Eisenstein/M
+Eisner/M
+Ekaterina/M
+El/Y
+Elaina/M
+Elaine/M
+Elam/M
+Elana/M
+Elanor/M
+Elasticsearch/M
+Elastoplast/M
+Elayne/M
+Elba/M
+Elbe/M
+Elbert/M
+Elbrus/M
+Elden/M
+Eldersburg/M
+Eldin/M
+Eldon/M
+Eldredge/M
+Eldridge/M
+Eleanor/M
+Eleanora/M
+Eleanore/M
+Eleazar/M
+Electra/M
+Elena/M
+Elene/M
+Eleni/M
+Eleonora/M
+Eleonore/M
+Elfreda/M
+Elfrida/M
+Elgar/M
+Eli/M
+Elia/S
+Elias/M
+Elie/M
+Elihu/M
+Elijah/M
+Elinor/M
+Eliot/M
+Elisa/M
+Elisabet/M
+Elisabeth/M
+Elisabetta/M
+Elise/M
+Eliseo/M
+Elisha/M
+Elissa/M
+Eliza/M
+Elizabeth/M
+Elizabethan/SM
+Elizabethtown/M
+Elke/M
+Elkhart/M
+Ella/M
+Elle/M
+Ellen/M
+Ellery/M
+Ellesmere/M
+Elli/SM
+Ellie/M
+Ellington/M
+Elliot/M
+Elliott/M
+Ellis/M
+Ellison/M
+Ellsworth/M
+Ellwood/M
+Elly/M
+Ellyn/M
+Elma/M
+Elmer/M
+Elmira/M
+Elmo/M
+Elmore/M
+Elnath/M
+Elnora/M
+Elohim/M
+Eloisa/M
+Eloise/M
+Eloy/M
+Elroy/M
+Elsa/M
+Elsbeth/M
+Else's
+Elsevier/M
+Elsey/M
+Elsie/M
+Elsinore/M
+Elspeth/M
+Elston/M
+Eltanin/M
+Elton/M
+Elul/M
+Elva/M
+Elvia/M
+Elvin/M
+Elvira/M
+Elvis/M
+Elway/M
+Elwin/M
+Elwood/M
+Elwyn/M
+Elyria/M
+Elyse/M
+Elysee/M
+Elysian/M
+Elysium/SM
+Elyssa/M
+Elys辿e/M
+Ema/M
+Emacs/M
+Emanuel/M
+Emanuele/M
+Emeline/M
+Emerson/M
+Emery/M
+Emeryville/M
+Emil/M
+Emile/M
+Emilia/M
+Emilie/M
+Emilio/M
+Emily/M
+Eminem/M
+Eminence
+Emlen/M
+Emlyn/M
+Emma/M
+Emmaline/M
+Emmanuel/M
+Emmeline/M
+Emmerich/M
+Emmet/M
+Emmett/M
+Emmie/M
+Emmy/M
+Emory/M
+Encarta/M
+EndNote/M
+Endymion/M
+Eng/M
+Engelbert/M
+Engels/M
+England/M
+English/MRS
+Englishman/M
+Englishmen/M
+Englishwoman/M
+Englishwomen/M
+Enid/M
+Enif/M
+Eniwetok/M
+Enkidu/M
+Ennis
+Enoch/M
+Enos/M
+Enrica/M
+Enrico/M
+Enrique/M
+Enron/M
+Enterprise/M
+Eocene/M
+Epcot/M
+Ephesian/MS
+Ephesus/M
+Ephraim/M
+Ephrem/M
+Epictetus/M
+Epicurean/M
+Epicurus/M
+Epimethius/M
+Epiphany/SM
+Episcopal
+Episcopalian/MS
+Epistle
+Epsom/M
+Epson/M
+Epstein/M
+Equuleus/M
+Er/M
+Eran/M
+Erasmus/M
+Erastus/M
+Erato/M
+Eratosthenes/M
+Erda/M
+Erebus/M
+Erector/M
+Erewhon/M
+Erhard/M
+Eric/M
+Erica/M
+Erich/M
+Erick/M
+Ericka/M
+Erickson/M
+Ericson/M
+Ericsson/M
+Eridanus/M
+Erie/M
+Erik/M
+Erika/M
+Erin/M
+Eris/MS
+Eritrea/M
+Eritrean/SM
+Erl/M
+Erlang/M
+Erlenmeyer/M
+Erma/M
+Erna/M
+Ernest/M
+Ernestine/M
+Ernesto/M
+Ernie/M
+Ernst/M
+Eros/MS
+Errol/M
+Erroll/M
+Erse/M
+Erskine
+Erv/M
+ErvIn/M
+Erwin/M
+Esau/M
+Escher/M
+Escherichia/M
+Escondido
+Esdras
+Eskimo/MS
+Esme/M
+Esmeralda/M
+Esperanto/M
+Esperanza/M
+Espinoza/M
+Esq/M
+Esquire/MS
+Essa/M
+Essen/M
+Essene/M
+Essequibo/M
+Essex/M
+Essie/M
+Esta/M
+Establishment
+Esteban/M
+Estela/M
+Estella/M
+Estelle/M
+Ester/M
+Esterhazy/M
+Esterh叩zy/M
+Estes/M
+Estevan/M
+Esther/M
+Estonia/M
+Estonian/SM
+Estrada/M
+Estrella/M
+Ethan/M
+Ethel/M
+Ethelbert
+Ethelred/M
+Ethelyn/M
+Ethernet/M
+Ethiopia/M
+Ethiopian/SM
+Etienne/M
+Etna/M
+Eton/M
+Etruria/M
+Etruscan/M
+Etta/M
+Ettie/M
+Ettore/M
+Etty/M
+Eu/M
+Eucharist/MS
+Eucharistic
+Euclid/M
+Euclidean/M
+Eudora/M
+Eugen/M
+Eugene/M
+Eugenia/M
+Eugenie/M
+Eugenio/M
+Eugenius/M
+Eula/M
+Eulalie/M
+Euler/M
+Eumenides/M
+Eunice/M
+Euphemia/M
+Euphrates/M
+Eur
+Eurasia/M
+Eurasian/MS
+Euripides/M
+Eurodollar/SM
+Europa/M
+Europaea/M
+Europe/M
+European/MS
+Eurydice/M
+Eustace/M
+Eustachian/M
+Eustacia/M
+Eustis/M
+Euterpe/M
+Ev/M
+Eva/M
+Evan/SM
+Evangelical
+Evangelina/M
+Evangeline/M
+Evangelist/M
+Evans/M
+Evansville/M
+Eve/M
+Evelina/M
+Eveline/M
+Evelyn/M
+Evenki/M
+EverReady/M
+Everard/M
+Everest/M
+Everett/M
+Everette/M
+Everglades/M
+Evert/M
+Evey/M
+Evian/M
+Evie/M
+Evin/M
+Evita/M
+Evy/M
+Ewan/M
+Ewart/M
+Ewell/M
+Ewen/M
+Ewing/M
+Excalibur/M
+Excedrin/M
+Excellency/SM
+Exchequer
+Exercycle/M
+Exocet/M
+Exodus/M
+Expedia/M
+Exxon/M
+Eyck/M
+Eyre/M
+Eysenck/M
+Ezekiel/M
+Ezequiel/M
+Ezra/M
+F/MD
+FAA
+FAQ/SM
+FBI/M
+FCC
+FD
+FDA
+FDIC/M
+FDR/M
+FHA/M
+FICA/M
+FIFO
+FL
+FM/SM
+FNMA/M
+FOFL
+FORTRAN/M
+FPO
+FSF/M
+FSLIC
+FTC
+FTM/SM
+FUD/S
+FWD
+FWIW
+FY
+FYI
+Faber/M
+Faberge/M
+Faberg辿/M
+Fabian/MS
+Fabien/M
+Fabio/M
+Facebook/M
+Fae/M
+Faeroe/M
+Fafnir/M
+Fagin/M
+Fahd/M
+Fahrenheit/M
+Fairbanks/M
+Fairfax
+Fairfield/M
+Fairhope/M
+Fairleigh/M
+Fairlie/M
+Faisal/M
+Faisalabad/M
+Faith/M
+Fajardo/M
+Falasha/M
+Falkland/SM
+Falklands/M
+Falkner
+Fallon/M
+Fallopian/M
+Falstaff/M
+Falwell/M
+Fania/M
+Fannie/M
+Fanny/M
+Far's
+Fara/M
+Faraday/M
+Farah/M
+Fargo/M
+Farley/M
+Farmer/M
+Farmington/M
+Farr/M
+Farragut/M
+Farrah/M
+Farrakhan/M
+Farrand/M
+Farrel/M
+Farrell/M
+Farris/M
+Farrow/M
+Farsi/M
+Fascist
+Faso/M
+Fassbinder/M
+Fatah/M
+Fates/M
+Father/SM
+Fatima/M
+Fatimid/M
+Faulkner/M
+Faulknerian/M
+Fauntleroy/M
+Faust/M
+Faustian/M
+Faustina/M
+Faustino/M
+Faustus/M
+Fawkes/M
+Fay/M
+Faye/M
+Fayette/M
+Fayetteville/M
+Fayre/M
+Fe/M
+Feb/M
+February/SM
+Fed/SM
+FedEx/M
+Federal/MS
+Federalist/M
+Federico/M
+Feds/M
+Felecia/M
+Felice/M
+Felicia/M
+Felicity/M
+Feliks/M
+Felipe/M
+Felix/M
+Fellini/M
+Feng/M
+Fenian/M
+Fenix/M
+Fennec/M
+Feodor/M
+Ferber/M
+Ferd/M
+Ferdie/M
+Ferdinand/M
+Ferdy/M
+Fergus/M
+Ferguson/M
+Ferlinghetti/M
+Fermat/M
+Fermi/M
+Fern/M
+Fernanda/M
+Fernande/M
+Fernandez/M
+Fernandina/M
+Fernando/M
+Ferne/M
+Ferrari/M
+Ferraro/M
+Ferrel/M
+Ferrell/M
+Ferris/M
+Fey's
+Feynman/M
+Fez/M
+Fianna
+Fiat/M
+Fiberglas/M
+Fibonacci/M
+Fichte/M
+Fidel/M
+Fidelia/M
+Fidelio/M
+Fido/M
+Fielding/M
+Fields/M
+Fifi/M
+Figaro/M
+Figueroa/M
+Fiji/M
+Fijian/MS
+Filip/M
+Filipino/MS
+Filippo/M
+Fillmore/M
+FilmSpot/M
+Filmer/M
+Filofax/M
+Fina/M
+Finch/M
+FindArticles/M
+FindLaw/M
+Findlay/M
+Findley/M
+Finland/M
+Finlay/M
+Finley/M
+Finn/SM
+Finnbogadottir/M
+Finnegan/M
+Finnish/M
+Fiona/M
+Firebase/M
+Firefox/M
+Firestone/M
+Fischer/M
+Fisher/M
+Fisk/M
+Fitch/M
+Fitchburg/M
+Fitz/M
+Fitzgerald/M
+Fitzpatrick/M
+Fitzroy/M
+Fizeau/M
+Fla
+Flagstaff/M
+Flanagan/M
+Flanders/M
+Flathead
+Flatt/M
+Flaubert/M
+Fleischer/M
+Flem/G
+Fleming/M
+Flemish/M
+Flemming/M
+Fletch/MR
+Fletcher/M
+Fleur/M
+Flickr/M
+Flin/M
+Flinn/M
+Flint/M
+Flintstones/M
+Flo/M
+Flor/M
+Flora/M
+Flore/SM
+Florence/M
+Florencia/M
+Florentine/M
+Flores/M
+Florette/M
+Florian/M
+Florida/M
+Floridan/M
+Floridian/SM
+Florinda/M
+Florine/M
+Floris
+Florrie/M
+Florsheim/M
+Flory/M
+Flossie/M
+Flossy's
+Flowers/M
+Floyd/M
+Flynn/M
+Fm/M
+Foch/M
+Fokker/M
+Foley/M
+Folgers/M
+Folsom/M
+Fomalhaut/M
+Fonda/M
+Fons
+Foosball/M
+Forbes/M
+Ford/M
+Foreman/M
+Forest/MR
+Forester/M
+Forex/M
+Formica/MS
+Formosa/M
+Formosan/M
+Forrest/MR
+Forrester/M
+Forster/M
+Fortaleza/M
+Fortran
+Foss/M
+Fosse/M
+Foster/M
+Fotomat/M
+Foucault/M
+Fourier/M
+Fourneyron/M
+Fourth
+Fowler/M
+Fox/MS
+Fr/MD
+Fragonard/M
+Fran/SM
+France/SM
+Frances/M
+Francesca/M
+Francesco/M
+Francine/M
+Francis/M
+Francisca/M
+Franciscan/MS
+Francisco/M
+Franck/M
+Franco/M
+Francois/M
+Francoise/M
+Francophile
+Franglais/M
+Frank/SM
+Frankel/M
+Frankenstein/M
+Frankfort/M
+Frankfurt/MR
+Frankfurter/M
+Frankie/M
+Frankish
+Franklin/M
+Franklyn/M
+Franks/M
+Franky/M
+Frannie/M
+Franny/M
+Fransisco/M
+Franz/MN
+Franzen/M
+Fraser/M
+Frasier/M
+Frau/MN
+Fraulein
+Frazer
+Frazier/M
+Fred/M
+Freda/M
+Freddie/M
+Freddy/M
+Frederic/M
+Frederica/M
+Frederich/M
+Frederick/M
+Fredericksburg/M
+Frederico/M
+Fredericton/M
+Frederik/M
+Frederique/M
+Fredric/M
+Fredrick/M
+Fredrika/M
+Free's
+FreeBSD/M
+Freeland/M
+Freeman/M
+Freemason/SM
+Freemasonry/SM
+Freetown/M
+Freida/M
+Fremont/M
+French/MS
+Frenchman/M
+Frenchmen/M
+Frenchwoman/M
+Frenchwomen/M
+Freon/M
+Fresnel/M
+Fresno/M
+Freud/M
+Freudian/M
+Frey/M
+Freya/M
+Fri/M
+Friday/SM
+Frieda/M
+Friedan/M
+Friederike/M
+Friedman/M
+Friedmann/M
+Friedrich
+Friend/SM
+Frigga/M
+Frigidaire/M
+Frisbee/M
+Frisco/M
+Frisian/MS
+Frito/M
+Fritz/M
+Friulian/M
+Frobisher/M
+Frodo/M
+Froissart/M
+Fromm/M
+Fronde/M
+FrontPage/M
+Frontenac/M
+Frost/M
+Frostbelt/M
+Frunze/M
+Fry/M
+Frye/M
+Fuchs/M
+Fuentes/M
+Fugger/M
+Fuji/M
+Fujian/M
+Fujitsu/M
+Fujiwara/M
+Fujiyama/M
+Fukuoka/M
+Fukushima/M
+Fukuyama/M
+Fulani/M
+Fulbright/M
+Fuller/M
+Fullerton/M
+Fulton/M
+Fulvia/M
+Funafuti/M
+Fundy/M
+Furies/M
+Furman/M
+Furtwangler/M
+Furtw辰ngler/M
+Fushun/M
+Fuzhou/M
+Fuzzbuster/M
+G/MNRB
+GA
+GAO
+GATT/M
+GB/M
+GCC/M
+GDP/M
+GDPR
+GE/M
+GED
+GHQ/M
+GHz/M
+GI
+GIF
+GIGO
+GM/M
+GMAT
+GMO
+GMT/M
+GNP/M
+GNU/M
+GOP/M
+GP/M
+GPA
+GPO
+GPS
+GPU
+GSA
+GTE/M
+GU
+GUI/M
+Ga/M
+GaAs
+Gabby/M
+Gabe/M
+Gabi/M
+Gable/M
+Gabon/M
+Gabonese/M
+Gaborone/M
+Gabriel/M
+Gabriela/M
+Gabriele/M
+Gabriella/M
+Gabrielle/M
+Gaby/M
+Gacrux/M
+Gadsden/M
+Gae/M
+Gaea/M
+Gael/SM
+Gaelic/M
+Gagarin/M
+Gage/M
+Gaia/M
+Gail/M
+Gaiman/M
+Gaines/M
+Gainesville/M
+Gainsborough/M
+Galahad/SM
+Galapagos/M
+Galatea/M
+Galatia/M
+Galatians/M
+Galaxy
+Galbraith/M
+Gale/M
+Galen/M
+Galibi/M
+Galilean/SM
+Galilee/M
+Galileo/M
+Galina/M
+Gall/M
+Gallagher/M
+Gallegos/M
+Gallic/M
+Gallicism/SM
+Gallo/M
+Galloway/M
+Gallup/M
+Galois/M
+Galsworthy/M
+Galvan/M
+Galvani/M
+Galveston/M
+Galvin/M
+Gama
+Gamaliel/M
+Gamay/M
+Gambia/M
+Gambian/SM
+Gamble/M
+GameCube/M
+GameFAQs/M
+GameSpot/M
+Gamow/M
+Gan/M
+Gandalf/M
+Gandhi/M
+Gandhian/M
+Ganesha/M
+Ganges/M
+Gangtok/M
+Gannon/M
+Gansu/M
+Gantry/M
+Ganymede/M
+Gap/M
+Garamond
+Garbo/M
+Garcia/M
+Gard
+Gardiner
+Gardner/M
+Gare/MH
+Gareth/M
+Garey/M
+Garfield/M
+Garfunkel/M
+Gargantua/M
+Garibaldi/M
+Garland/M
+Garner/M
+Garrard/M
+Garrett/M
+Garrick/M
+Garrison/M
+Garry/M
+Garth/M
+Garvey/M
+Garvin/M
+Garwood/M
+Gary/M
+Garza/M
+Gascony/M
+Gaspar
+Gaspard/M
+Gasparo/M
+Gasper/M
+Gasser/M
+Gaston/M
+Gastonia/M
+Gastroenterology
+Gates/M
+Gatling/M
+Gatorade/M
+Gatsby/M
+Gatun/M
+Gauguin/M
+Gaul/SM
+Gaulish
+Gauss/M
+Gaussian/M
+Gautama/M
+Gauthier/M
+Gautier/M
+Gav/MN
+Gavan/M
+Gaven/M
+Gavin/M
+Gawain/M
+Gay/M
+Gaye/M
+Gayle/M
+Gaylord/M
+Gaynor/M
+Gaza/M
+Gaziantep/M
+Gbps
+Gd/M
+Gdansk/M
+Ge/M
+Gecko/M
+Geffen/M
+Gehenna/M
+Gehrig/M
+Geiger/M
+Gelbvieh/M
+Geller/M
+Gemini/MS
+Gen/M
+GenBank/M
+Gena/M
+Genaro/M
+Gene/M
+Genesis/M
+Genet/M
+Geneva/M
+Genevieve/M
+Genevra/M
+Genghis/M
+Genia/M
+Genna/M
+Genny/M
+Geno/M
+Genoa/SM
+Gentoo/M
+Gentry/M
+Geo/M
+Geoff/M
+Geoffrey/M
+Geordie
+Georg/M
+George/MS
+Georgetown/M
+Georgette/M
+Georgi/M
+Georgia/M
+Georgian/MS
+Georgiana/M
+Georgianna/M
+Georgie/M
+Georgina/M
+Georgy/M
+Ger/M
+Gerald/M
+Geraldine/M
+Gerard/M
+Gerardo/M
+Gerber/M
+Gerda/M
+Gere/M
+Gerhard/M
+Gerhardt/M
+Geri/M
+Geritol/M
+Germain/M
+Germaine/M
+German/MS
+Germanic/M
+Germany/M
+Gerome/M
+Geronimo/M
+Gerrard/M
+Gerri/M
+Gerry/M
+Gershwin/M
+Gert/M
+Gertie/M
+Gertrud/M
+Gertrude/M
+Gertrudis/M
+Gerty/M
+Gery/M
+Gestapo/SM
+Gethsemane/M
+Getty/M
+Gettysburg/M
+Gewurztraminer/M
+Gew端rztraminer/M
+Ghana/M
+Ghanaian
+Ghats/M
+Ghazvanid/M
+Ghent/M
+Ghibelline/M
+Giacometti/M
+Giacomo/M
+Gian/M
+Gianna/M
+Gianni/M
+Giannini/M
+Giauque/M
+Gib/M
+Gibb/SM
+Gibbon/M
+Gibbs/M
+Gibraltar/MS
+Gibson/M
+Gide/M
+Gideon/M
+Gielgud/M
+Gienah/M
+Giff/M
+Giffard/M
+Gifford/M
+Gigi/M
+Gil/MY
+Gila/M
+Gilbert/M
+Gilberte/M
+Gilberto/M
+Gilchrist/M
+Gilda/M
+Gilead/M
+Giles/M
+Gilgamesh/M
+Gill/M
+Gillan/M
+Gilles
+Gillespie/M
+Gillette/M
+Gilliam/M
+Gillian/M
+Gillie's
+Gilligan/M
+Gilly/M
+Gilman
+Gilmore/M
+Gilroy/M
+Gina/M
+Ginevra/M
+Ginger/M
+Gingrich/M
+Ginnie/M
+Ginny/M
+Gino/M
+Ginsberg/M
+Ginsburg/M
+Ginsu/M
+Giordano/M
+Giorgi/M
+Giorgio/M
+Giorgione/M
+Giotto/M
+Giovanna/M
+Giovanni/M
+Giraud
+Giraudoux/M
+Gisela/M
+Gisele/M
+Giselle/M
+Gish/M
+GitHub/M
+Giulia/M
+Giuliani/M
+Giulietta/M
+Giulio/M
+Giuseppe/M
+Giusto/M
+Giza/M
+Gk
+Gladstone/MS
+Gladys/M
+Glaser/M
+Glasgow/M
+Glass/M
+Glastonbury/M
+Glaswegian/SM
+Glaxo/M
+Gleason/M
+Glen/M
+Glenda/M
+Glendale
+Glendon/M
+Glenlivet/M
+Glenn/M
+Glenna/M
+Glennie/M
+Gloria/M
+Gloriana/M
+Gloucester/M
+Gloucestershire/M
+Glover/M
+Glyn/M
+Glynis/M
+Glynn/M
+GmbH
+Gnostic/M
+Gnosticism/M
+GnuPG
+Goa/M
+Gobi/M
+God/M
+Godard/M
+Goddard/M
+Godel/M
+Godfrey/M
+Godhead/M
+Godiva/M
+Godot/M
+Godspeed/SM
+Godthaab/M
+Godunov/M
+Godwin
+Godzilla/M
+Goebbels/M
+Goering/M
+Goethals/M
+Goethe/M
+Goff/M
+Gog/M
+Gogol/M
+Goiania/M
+Golan/M
+Golconda/M
+Golda/M
+Goldberg/M
+Golden/M
+Goldie/M
+Goldilocks/M
+Golding/M
+Goldman/M
+Goldsboro/M
+Goldsmith/M
+Goldwater/M
+Goldwyn/M
+Goldy/M
+Golgi/M
+Golgotha/M
+Goliath/M
+Gomez/M
+Gomorrah/M
+Gompers/M
+Gomulka/M
+Gondwanaland/M
+Gonzales/M
+Gonzalez/M
+Gonzalo/M
+Good/M
+Goodall/M
+Goode/M
+Goodman/M
+Goodrich/M
+Goodwill/M
+Goodwin/M
+Goodyear/M
+Google/M
+Goolagong/M
+Gopher
+Goran/M
+Gorbachev/M
+Gordan/M
+Gorden/M
+Gordian/M
+Gordie/M
+Gordimer/M
+Gordon/M
+Gordy/M
+Gore/M
+Goren/M
+Gorey/M
+Gorgas/M
+Gorgon/M
+Gorgonzola/M
+Gorky/M
+Gospel/MS
+Goteborg/M
+Goth/M
+Gotham/M
+Gothic/MS
+Goths
+Gottfried/M
+Gouda/SM
+Gould/M
+Gounod/M
+Governor
+Goya/M
+Gr/B
+Grable/M
+Gracchus/M
+Grace/M
+Graceland/M
+Gracia/M
+Gracie/M
+Graciela/M
+Grady/M
+Graeme/M
+Graffias/M
+Grafton/M
+Graham/M
+Grahame/M
+Grail/M
+Grammy/M
+Grampians/M
+Gran's
+Granada/M
+Grange/R
+Grannie/M
+Grant/M
+Grantham/M
+Grantley/M
+Granville/M
+Grass/M
+Grata/M
+Gratia/M
+Graves/M
+Gray/M
+Grayslake/M
+Grazia/M
+Grecian/M
+Greece/M
+Greek/SM
+Greeley/M
+Green/SM
+Greene/M
+Greenland/M
+Greenlandic
+Greenpeace/M
+Greensboro/M
+Greensleeves/M
+Greenspan/M
+Greenville/M
+Greenwich/M
+Greer/M
+Greg/M
+Gregg/M
+Gregoire/M
+Gregor/M
+Gregorian/M
+Gregorio/M
+Gregorius/M
+Gregory/M
+Grenada/M
+Grenadian/MS
+Grenadines/M
+Grendel/M
+Grenoble/M
+Grenville
+Gresham/M
+Greta/M
+Gretchen/M
+Grete/M
+Gretel/M
+Gretna/M
+Gretta/M
+Gretzky/M
+Grey/M
+Grieg/M
+Grier/M
+Griff/M
+Griffin/M
+Griffith/M
+Griffiths
+Grimes/M
+Grimm/M
+Grinch/M
+Gris/M
+Griselda
+Griswold/M
+Gromyko/M
+Gropius/M
+Gross/M
+Grosz/M
+Grotius/M
+Grover/M
+Grozny
+Grumman/M
+Grundy/M
+Grunewald/M
+Grus/M
+Gruyere/SM
+Gruy竪re/M
+Gr端newald/M
+Guadalajara/M
+Guadalcanal/M
+Guadalquivir/M
+Guadalupe/M
+Guadeloupe/M
+Guallatiri/M
+Guam/M
+Guamanian
+Guangdong/M
+Guangzhou/M
+Guantanamo/M
+Guarani/M
+Guarnieri/M
+Guatemala/M
+Guatemalan/MS
+Guayama/M
+Guayaquil/M
+Gucci/M
+Guelph/M
+Guenevere/M
+Guernsey/MS
+Guerra/M
+Guerrero/M
+Guevara/M
+Guggenheim/M
+Guglielmo/M
+Gui/M
+Guiana/M
+Guido/M
+Guilbert/M
+Guildford/M
+Guillaume/M
+Guillermo/M
+Guinea/M
+Guinean/MS
+Guinevere/M
+Guinness/M
+Guiyang/M
+Guizhou/M
+Guizot/M
+Gujarat/M
+Gujarati/M
+Gujranwala/M
+Gulfport/M
+Gullah/M
+Gulliver/M
+Gumbel/M
+Gunilla/M
+Gunter
+Gunther/M
+Guofeng/M
+Gupta/M
+Gurkha/M
+Gus/M
+Gussie/M
+Gussy's
+Gusta/M
+Gustaf/M
+Gustav/M
+Gustave/M
+Gustavo/M
+Gustavus/M
+Gusti/M
+Gusty's
+Gutenberg/M
+Guthrie/M
+Gutierrez/M
+Guy/M
+Guyana/M
+Guyanese/M
+Guzman/M
+Gwalior/M
+Gwen/M
+Gwendolen/M
+Gwendoline/M
+Gwendolyn/M
+Gwyn/M
+Gwyneth/M
+Gwynne/M
+Gypsy/SM
+G旦del/M
+G旦teborg/M
+H/M
+HBO/M
+HBase/M
+HDD
+HDMI
+HDTV
+HF/M
+HHS
+HI
+HIV/M
+HM
+HMO/M
+HMS
+HOV
+HP/M
+HPV
+HQ/M
+HR
+HRH
+HS
+HSBC/M
+HST
+HT
+HTML/M
+HTTP
+HTTPS
+HUD/M
+HVAC
+Ha/M
+Haas/M
+Habakkuk/M
+Haber/M
+Had's
+Hadar/M
+Hades/M
+Hadleigh/M
+Hadley/M
+Hadoop/M
+Hadria/M
+Hadrian/M
+Hafiz/M
+Hagan/M
+Hagar/M
+Hagen
+Hagerstown/M
+Haggai/M
+Hagiographa/M
+Hague/M
+Hahn/M
+Haida/SM
+Haifa/M
+Hailey/M
+Hainan/M
+Haiphong/M
+Haiti/M
+Haitian/MS
+Hakeem/M
+Hakim/M
+Hakka/M
+Hakluyt/M
+Hal/SMY
+Haldane/M
+Hale/M
+Haleakala/M
+Haley/M
+Hali/M
+Halifax/M
+Hall/M
+Halley/M
+Halliburton/M
+Hallie/M
+Hallmark/M
+Halloween/MS
+Hallstatt/M
+Hally/M
+Halon/M
+Hals/M
+Halsey/M
+Ham/M
+Haman/M
+Hamas/M
+Hamburg/MS
+Hamel/M
+Hamhung/M
+Hamid/M
+Hamil/M
+Hamilcar/M
+Hamill/M
+Hamilton/M
+Hamiltonian/M
+Hamish/M
+Hamitic/M
+Hamlet/M
+Hamlin/M
+Hammad/M
+Hammarskjold/M
+Hammerstein/M
+Hammett/M
+Hammond/M
+Hammurabi/M
+Hampshire/M
+Hampton/M
+Hamsun/M
+Han/SM
+Hana/M
+Hanan/M
+Hancock/M
+Handel/M
+Handy/M
+Haney/M
+Hanford/M
+Hangul/M
+Hangzhou/M
+Hank/M
+Hanna/M
+Hannah/M
+Hanni/M
+Hannibal/M
+Hanoi/M
+Hanover/M
+Hanoverian/M
+Hans/MN
+Hansel/M
+Hansen/M
+Hanson/M
+Hanuka
+Hanukah/M
+Hanukkah/M
+Hanukkahs
+Happy's
+Hapsburg/M
+Harald/M
+Harare/M
+Harbert/M
+Harbin/M
+Harcourt/M
+Hardin/M
+Harding/M
+Hardy/M
+Hargreaves/M
+Harlan/M
+Harland/M
+Harlem/M
+Harlequin/M
+Harley/M
+Harlin/M
+Harlingen/M
+Harlow/M
+Harman/M
+Harmon/M
+Harmonia/M
+Harmonie/M
+Harold/M
+Haroun/M
+Harper/M
+Harpy/SM
+Harrell/M
+Harri/SM
+Harriet/M
+Harriett/M
+Harriette/M
+Harrington/M
+Harriot/M
+Harriott/M
+Harris/M
+Harrisburg/M
+Harrison/M
+Harrisonburg/M
+Harrods/M
+Harry/M
+Hart/M
+Harte/M
+Hartford/M
+Hartley
+Hartline/M
+Hartman/M
+Hartwell/M
+Harv/M
+Harvard/M
+Harvey/M
+Harwell/M
+Hasbro/M
+Hashim/M
+Hasidim/M
+Haskell/M
+Haslett/M
+Hassan/M
+Hastie/M
+Hastings/M
+Hasty's
+Hatfield/M
+Hathaway/M
+Hatsheput/M
+Hatteras/M
+Hatti/M
+Hattie/M
+Hattiesburg/M
+Hatty/M
+Hauptmann/M
+Hausa/M
+Hausdorff/M
+Havana/MS
+Havarti/M
+Havel/M
+Havoline/M
+Haw
+Hawaii/M
+Hawaiian/SM
+Hawking/M
+Hawkins/M
+Hawks
+Hawthorne/M
+Hay/SM
+Hayden/M
+Haydn/M
+Haydon/M
+Hayek/M
+Hayes/M
+Hayley/M
+Haynes/M
+Hays/M
+Hayward/M
+Haywood/M
+Hayworth/M
+Hayyim/M
+Hazel/M
+Hazleton/M
+Hazlett/M
+Hazlitt/M
+He/M
+Head/M
+Hearst/M
+Heath/MR
+Heather/M
+Heaviside/M
+Heb
+Hebe/M
+Hebei/M
+Hebert/M
+Hebraic/M
+Hebraism/SM
+Hebrew/MS
+Hebrews/M
+Hebrides/M
+Hecate/M
+Hector/M
+Hecuba/M
+Hedda/M
+Hedi/M
+Hedwig/M
+Hedy/M
+Heep/M
+Hefner/M
+Hegel/M
+Hegelian/M
+Hegira/M
+Heidegger/M
+Heidelberg/M
+Heidi/M
+Heifetz/M
+Heilongjiang/M
+Heimlich/M
+Heine/M
+Heineken/M
+Heinlein/M
+Heinrich/M
+Heinz/M
+Heisenberg/M
+Heisman/M
+Hejira's
+Helaina/M
+Helen/M
+Helena/M
+Helene/M
+Helga/M
+Helge/M
+Helicobacter
+Helicon/M
+Heliopolis/M
+Helios/M
+Hellene/SM
+Hellenic/M
+Hellenism/MS
+Hellenist
+Hellenistic/M
+Hellenization/M
+Hellenize/MD
+Heller/M
+Hellespont/M
+Hellman/M
+Helmholtz/M
+Heloise/M
+Helsinki/M
+Helvetian
+Helvetica
+Helvetius/M
+Hemet/M
+Hemingway/M
+Henan/M
+Hench/M
+Henderson/M
+Hendrick/MS
+Hendricks/M
+Hendrik/M
+Hendrix/M
+Henley/M
+Hennessy/M
+Henri/M
+Henrietta/M
+Henriette/M
+Henrik/M
+Henry/M
+Hensley/M
+Henson/M
+Hepburn/M
+Hephaestus/M
+Hephzibah/M
+Hepplewhite/M
+Hera/M
+Heracles/M
+Heraclitus/M
+Herakles/M
+Herbart/M
+Herbert/M
+Herbie/M
+Herby/M
+Herc/M
+Herculaneum/M
+Hercule/MS
+Herculean
+Hercules/M
+Herder/M
+Hereford/SM
+Herero/M
+Heriberto/M
+Herman/M
+Hermann/M
+Hermaphroditus/M
+Hermes/M
+Hermia/M
+Hermine/M
+Herminia/M
+Hermione/M
+Hermitage/M
+Hermite/M
+Hermon
+Hermosillo/M
+Hernandez/M
+Hernando/M
+Herod/M
+Herodotus/M
+Heroku/M
+Herold/M
+Herr/MG
+Herrera/M
+Herrick/M
+Herring/M
+Hersch/M
+Herschel/M
+Hersey/M
+Hersh/M
+Hershel/M
+Hershey/M
+Herta/M
+Hertfordshire/M
+Hertha/M
+Hertz/M
+Hertzsprung/M
+Herve/M
+Hervey/M
+Herzegovina/M
+Herzl/M
+Heshvan/M
+Hesiod/M
+Hesperia/M
+Hesperus/M
+Hess/M
+Hesse/M
+Hessian/M
+Hester/M
+Hestia/M
+Heston/M
+Hettie/M
+Hetty/M
+Hew's
+Hewett/M
+Hewitt/M
+Hewlett/M
+Heyerdahl/M
+Heywood/M
+Hezbollah/M
+Hezekiah/M
+Hf/M
+Hg/M
+Hi's
+Hialeah/M
+Hiawatha/M
+Hibernia/M
+Hibernian
+Hickman/M
+Hickok/M
+Hickory/M
+Hicks/M
+Hieronymus/M
+Higashiosaka
+Higgins/M
+Highlander/SM
+Highlands
+Highness/M
+Hightstown/M
+Hilario/M
+Hilary/M
+Hilbert/M
+Hilda/M
+Hilde/M
+Hildebrand/M
+Hildegarde/M
+Hildy/M
+Hilfiger/M
+Hill/M
+Hillard/M
+Hillary/M
+Hillel/M
+Hillery/M
+Hilliard
+Hillier/M
+Hillsborough/M
+Hilly's
+Hillyer/M
+Hilton/M
+Himalaya/SM
+Himalayan
+Himalayas/M
+Himmler/M
+Hinayana/M
+Hindemith/M
+Hindenburg/M
+Hindi/M
+Hindu/SM
+Hinduism/SM
+Hindustan/M
+Hindustani/SM
+Hines/M
+Hinesville/M
+Hinton/M
+Hinze/M
+Hipparchus/M
+Hippocrates/M
+Hippocratic/M
+Hiram/M
+Hirobumi/M
+Hirohito/M
+Hiroshima/M
+Hirsch/M
+Hispanic/SM
+Hispanica/M
+Hispaniola/M
+Hiss/M
+Hitachi/M
+Hitchcock/M
+Hitler/MS
+Hittite/SM
+Hmong/M
+Ho/M
+Hobart/M
+Hobbes/M
+Hobbs/M
+Hobie/M
+Hockney/M
+Hodge/SM
+Hodges/M
+Hodgkin/M
+Hoff/M
+Hoffa/M
+Hoffman/M
+Hofstadter/M
+Hogan/M
+Hogarth/M
+Hogwarts/M
+Hohenlohe/M
+Hohenstaufen/M
+Hohenzollern/M
+Hohhot/M
+Hohokam/M
+Hokkaido/M
+Hokusai/M
+Holbein/M
+Holcomb/M
+Holden/M
+Holder/M
+Holiday/M
+Holiness
+Holland/ZSMR
+Hollander/M
+Hollandica/M
+Hollerith/M
+Holley/M
+Hollie/M
+Hollis/M
+Holloway/M
+Holly/M
+Hollywood/M
+Holman/M
+Holmes/M
+Holocaust/M
+Holocene/M
+Holst/M
+Holstein/SM
+Holt/M
+Homer/M
+Homeric/M
+Hon
+Honda/M
+Honduran/MS
+Honduras/M
+Honecker/M
+Honeywell/M
+Hong
+Honiara/M
+Honolulu/M
+Honorable
+Honoria/M
+Honshu/M
+Hood/M
+Hooke/RM
+Hooker/M
+Hooper/M
+Hoosier/MS
+Hooters/M
+Hoover/MS
+Hope/M
+Hopewell/M
+Hopi/SM
+Hopkins/M
+Hopper/M
+Horace/M
+Horacio/M
+Horatia/M
+Horatio/M
+Horatius/M
+Hormel/M
+Hormuz/M
+Horn/M
+Hornblower/M
+Horne/M
+Horowitz/M
+Horst/M
+Hort/M
+Hortense
+Hortensia/M
+Horthy/M
+Horton/M
+Horus/M
+Hosea/M
+Host/SM
+Hotmail/M
+Hotpoint/M
+Hottentot/SM
+Houdini/M
+Houghton/M
+Houma/M
+House/M
+Housman/M
+Houston/M
+Houyhnhnm/M
+Hovhaness/M
+Howard/M
+Howe/M
+Howell/MS
+Howells/M
+Howey/M
+Howie/M
+Howrah
+Hoyle/M
+Hoyt/M
+Hrothgar/M
+Hts
+Huang/M
+Hubbard/M
+Hubble/M
+Hubei/M
+Huber/M
+Hubert/M
+Huck/M
+Huddersfield
+Hudson/M
+Huerta/M
+Huey/M
+Huff/M
+Huffman/M
+Huggins/M
+Hugh/MS
+Hughes/M
+Hughie
+Hugo/M
+Huguenot/MS
+Hugues/M
+Hui/M
+Huitzilopotchli/M
+Hulda/M
+Hull/M
+Humbert/M
+Humberto/M
+Humboldt/M
+Hume/M
+Humfrey/M
+Hummel/M
+Hummer/M
+Humphrey/SM
+Humvee/M
+Hun/SM
+Hunan/M
+Hung/M
+Hungarian/SM
+Hungary/M
+Hunspell/M
+Hunt/MR
+Hunter/M
+Huntington/M
+Huntley/M
+Huntsville/M
+Hurd/M
+Hurley/M
+Huron/M
+Hurst/M
+Hus/M
+Husein/M
+Hussein/M
+Husserl/M
+Hussite/M
+Huston/M
+Hutchinson/M
+Hutton/M
+Hutu/M
+Huxley/M
+Huygens/M
+Hy/M
+Hyacinthe/M
+Hyades/M
+Hyatt/M
+Hyde/M
+Hyderabad/M
+Hydra/M
+Hyman/M
+Hymen/M
+Hymie
+Hyperion/M
+Hyundai/M
+Hz/M
+H辿loise/M
+I'd
+I'll
+I'm
+I've
+I/M
+IA
+IANAL
+IBM/M
+ICBM/SM
+ICC
+ICU
+ID/SM
+IDE
+IE
+IED
+IEEE
+IIRC
+IKEA/M
+IL
+IMDb/M
+IMDbPro/M
+IMF/M
+IMHO
+IMNSHO
+IMO
+IN
+ING/M
+INRI
+INS
+IOU/M
+IP
+IPA
+IPO/SM
+IQ/M
+IRA/SM
+IRC
+IRS/M
+ISBN
+ISIS
+ISO/M
+ISP/SM
+ISS
+IT
+IUD
+IV/SM
+IVF
+Ia
+Iaccoca/M
+Iago/M
+Iain/M
+Ian/M
+Ianthe/M
+Iapetus/M
+Ibadan/M
+Iberia/M
+Iberian/M
+Ibiza/M
+Iblis/M
+Ibo/M
+Ibrahim/M
+Ibsen/M
+Icahn/M
+Icarus/M
+Ice
+Iceland/MRZ
+Icelander/M
+Icelandic/M
+Ichabod/M
+Ida/M
+Idaho/SM
+Idahoan/MS
+Idahoes
+Ieyasu/M
+Iggy/M
+Ignace/M
+Ignacio/M
+Ignatius/M
+Ignaz/M
+Ignazio/M
+Igor/M
+Iguassu/M
+Ijsselmeer/M
+Ike/M
+Ikey/M
+Ikhnaton/M
+Ila/M
+Ileana/M
+Ilene/M
+Iliad/SM
+Ilka/M
+Ill
+Illa/M
+Illinois/M
+Illinoisan/MS
+Illuminati/M
+Ilsa/M
+Ilse/M
+Ilyushin/M
+Imam
+Imelda/M
+Imhotep/M
+Immanuel
+Imodium/M
+Imogen/M
+Imogene/M
+Imus/M
+In/MP
+Ina/M
+Inc
+Inca/SM
+Inchon/M
+Incorporated
+Ind
+Independence/M
+India/M
+Indian/MS
+Indiana/M
+Indianan/SM
+Indianapolis/M
+Indianian
+Indies/M
+Indio/M
+Indira/M
+Indochina/M
+Indochinese/M
+Indonesia/M
+Indonesian/SM
+Indore/M
+Indra/M
+Indus/M
+Indy/SM
+Ines/M
+Inez/M
+Inga/M
+Inge/RM
+Ingeborg/M
+Ingemar/M
+Inger/M
+Inglewood
+Inglis/M
+Ingmar/M
+Ingram/M
+Ingres/M
+Ingrid/M
+Inigo/M
+Inna/M
+Inness/M
+Innis/M
+Innocent/M
+Innsbruck
+Inonu/M
+Inquisition/M
+Inst
+Instagram/M
+Instamatic/M
+Intel/M
+Intelsat/M
+Internationale/M
+Internet/SM
+Interpol/M
+Inuit/MS
+Inuktitut/M
+Invar/M
+Io/M
+Iona
+Ionesco/M
+Ionian/MS
+Ionic/SM
+Iowa/SM
+Iowan/MS
+Iphigenia/M
+Ipswich
+Iqaluit/M
+Iqbal/M
+Iquitos/M
+Ir/M
+Ira/M
+Iran/M
+Iranian/SM
+Iraq/M
+Iraqi/MS
+Ireland/M
+Irena/M
+Irene/M
+Irina/M
+Iris/M
+Irish/MR
+Irishman/M
+Irishmen/M
+Irishwoman/M
+Irishwomen/M
+Irkutsk/M
+Irma/M
+Iroquoian/SM
+Iroquois/M
+Irrawaddy/M
+Irtish/M
+Irv/MG
+Irvin/M
+Irvine/M
+Irving/M
+Irwin/M
+Isa
+Isaac/M
+Isaak/M
+Isabel/M
+Isabela/M
+Isabella/M
+Isabelle/M
+Isadora/M
+Isadore/M
+Isaiah/M
+Isak/M
+Iscariot/M
+Isfahan/M
+Isherwood/M
+Ishim/M
+Ishmael/M
+Ishtar/M
+Isiah/M
+Isidor/M
+Isidora/M
+Isidore/M
+Isidoro/M
+Isidro/M
+Isis/M
+Islam/MS
+Islamabad/M
+Islamic/M
+Islamica/M
+Islamism/M
+Islamist/M
+Islamophobia
+Islamophobic
+Ismael/M
+Ismail/M
+Isobel/M
+Isolde/M
+Ispell/M
+Israel/SM
+Israeli/SM
+Israelite/M
+Issac/M
+Issachar/M
+Issy/M
+Istanbul/M
+Isuzu/M
+It
+Itaipu/M
+Ital
+Italia/M
+Italian/SM
+Italianate
+Italy/M
+Itasca/M
+Ithaca/M
+Ithacan/M
+Ito/M
+Iva/M
+Ivan/M
+Ivanhoe/M
+Ivar/M
+Ive/RSM
+Iver/M
+Ives/M
+Ivie/M
+Ivoire
+Ivor/M
+Ivorian
+Ivory/M
+Ivy/M
+Iyar/M
+Izaak/M
+Izanagi/M
+Izanami/M
+Izhevsk/M
+Izmir/M
+Izod/M
+Izvestia/M
+Izzy/M
+J/MDNX
+JCS
+JD
+JFK/M
+JP
+JPEG/SM
+JSON
+JV
+Jabez/M
+Jacinta/M
+Jack/M
+Jacki/M
+Jackie/M
+Jacklin/M
+Jacklyn/M
+Jackson/M
+Jacksonian/M
+Jacksonville/M
+Jacky/M
+Jaclyn/M
+Jacob/SM
+Jacobean/M
+Jacobi/M
+Jacobin/M
+Jacobite/M
+Jacobo/M
+Jacobs/M
+Jacobson/M
+Jacquard/M
+Jacqueline/M
+Jacquelyn/M
+Jacques/M
+Jacqui/M
+Jacquie/M
+Jacuzzi/M
+Jada/M
+Jae/M
+Jagger/M
+Jagiellon/M
+Jaguar/M
+Jahangir/M
+Jaime/M
+Jain/M
+Jainism/M
+Jaipur/M
+Jakarta/M
+Jake/M
+Jakob/M
+Jamaal/M
+Jamaica/M
+Jamaican/SM
+Jamal/M
+Jamar/M
+Jame/SM
+Jamel/M
+James/M
+Jameson
+Jamestown/M
+Jamey/M
+Jami/M
+Jamie/M
+Jamil/M
+Jamison/M
+Jan/M
+Jana/M
+Janacek/M
+Jane/M
+Janek/M
+Janell/M
+Janelle/M
+Janesville/M
+Janet/M
+Janette/M
+Janey/M
+Janice/M
+Janie/M
+Janina
+Janine/M
+Janis/M
+Janissary/M
+Janjaweed/M
+Janna/M
+Jannie/M
+Janos/M
+Jansen/M
+Jansenist/M
+January/SM
+Janus/M
+Jany/M
+Jap/SM
+Japan/M
+Japanese/MS
+Japura/M
+Jared/M
+Jarlsberg/M
+Jarred/M
+Jarret/M
+Jarrett/M
+Jarrod/M
+Jarvis/M
+Jase/M
+Jasmin/M
+Jasmine/M
+Jason/M
+Jasper/M
+Jataka/M
+Java/SM
+JavaScript/M
+Javanese/M
+Javier/M
+Jaxartes/M
+Jay/M
+Jayapura/M
+Jayawardene/M
+Jaycee/MS
+Jaycees/M
+Jaye/M
+Jayme/M
+Jayne/M
+Jayson/M
+Jean/M
+Jeana/M
+Jeane/M
+Jeanette/M
+Jeanie/M
+Jeanine/M
+Jeanne/M
+Jeannette/M
+Jeannie/M
+Jeannine/M
+Jed/M
+Jedediah/M
+Jedi/M
+Jedidiah/M
+Jeep/M
+Jeeves/M
+Jeff/M
+Jefferey/M
+Jefferson/M
+Jeffersonian/M
+Jeffery/M
+Jeffrey/M
+Jeffry/M
+Jehoshaphat/M
+Jehovah/M
+Jehu
+Jekyll/M
+Jemima/M
+Jemmy/M
+Jen/M
+Jena/M
+Jenifer/M
+Jenkins/M
+Jenn/MRJ
+Jenna/M
+Jenner/M
+Jenni/M
+Jennie/M
+Jennifer/M
+Jennings/M
+Jenny/M
+Jeno/M
+Jensen/M
+Jephthah/M
+Jerald/M
+Jere/M
+Jeremiah/M
+Jeremiahs
+Jeremias/M
+Jeremie/M
+Jeremy/M
+Jeri/M
+Jericho/M
+Jermaine/M
+Jeroboam/M
+Jerold/M
+Jerome/M
+Jerri/M
+Jerrie/M
+Jerrod/M
+Jerrold/M
+Jerry/M
+Jersey/MS
+Jerusalem/M
+Jervis/M
+Jess/M
+Jessamine/M
+Jessamyn/M
+Jesse/M
+Jessey/M
+Jessi/M
+Jessica/M
+Jessie/M
+Jessy/M
+Jesuit/MS
+Jesus/M
+Jethro
+Jetway/M
+Jew/SM
+Jewel/M
+Jewell/M
+Jewess/MS
+Jewish/PM
+Jewry/M
+Jezebel/SM
+Jiangsu/M
+Jiangxi/M
+Jidda/M
+Jilin/M
+Jill/M
+Jillian/M
+Jilly/M
+Jim/M
+Jimenez/M
+Jimmie/M
+Jimmy/M
+Jinan/M
+Jinnah/M
+Jinny/M
+Jivaro/M
+Jo/MY
+Joachim
+Joan/M
+Joana/M
+Joane/M
+Joanie/M
+Joann/M
+Joanna/M
+Joanne/SM
+Joaquin/M
+Job/SM
+Jobs/M
+Joby/M
+Jocasta/M
+Jocelin/M
+Jocelyn/M
+Jocelyne/M
+Jock/M
+Jockey/M
+Jocko/M
+Jodi/M
+Jodie/M
+Jody/M
+Joe/M
+Joel/M
+Joelle/M
+Joey/M
+Jogjakarta/M
+Johan/M
+Johann/M
+Johanna/M
+Johannes/M
+Johannesburg/M
+John/SM
+Johnathan/M
+Johnathon/M
+Johnie/M
+Johnnie/M
+Johnny/M
+Johns/M
+Johnson/M
+Johnston/M
+Johnstown/M
+Jojo/M
+Jolene/M
+Joli/M
+Jolie/M
+Joliet/M
+Jolson/M
+Joly/M
+Jon/M
+Jonah/M
+Jonahs
+Jonas/M
+Jonathan/M
+Jonathon/M
+Jone/SM
+Jones/M
+Jonesboro/M
+Joni/M
+Jonson/M
+Joplin/M
+Jordan/M
+Jordana/M
+Jordanian/MS
+Jordon/M
+Jorge/M
+Jori/M
+Jory/M
+Joscelin/M
+Jose/M
+Josef/M
+Josefa/M
+Josefina/M
+Joseph/M
+Josepha/M
+Josephine/M
+Josephs
+Josephson/M
+Josephus/M
+Josey/M
+Josh/M
+Joshua/M
+Josiah/M
+Josias/M
+Josie/M
+Josselyn/M
+Josue/M
+Joule/M
+Jourdain/M
+Jourdan/M
+Jove/M
+Jovian/M
+Joy/M
+Joya/M
+Joyce/M
+Joycean/M
+Joye/M
+Joyner/M
+Jozef/M
+Jpn
+Jr/M
+Juan/M
+Juana/M
+Juanita/M
+Juarez/M
+Jubal/M
+Jud
+Judaeo
+Judah/M
+Judaic
+Judaical
+Judaism/MS
+Judas/MS
+Judd/M
+Jude/M
+Judea/M
+Judges
+Judi/MH
+Judith/M
+Judson/M
+Judy/M
+Juggernaut/M
+Jul
+Jule/SM
+Jules/M
+Juli/M
+Julia/M
+Julian/M
+Juliana/M
+Juliane/M
+Julianna/M
+Julianne/M
+Julie/M
+Julienne's
+Juliet/M
+Juliette/M
+Julio/M
+Julius/M
+Julliard/M
+July/SM
+Jun/M
+June/SM
+Juneau/M
+Juneteenth/M
+Jung/M
+Jungfrau/M
+Jungian/M
+Junia/M
+Junie/M
+Junior/SM
+Junker/SM
+Juno/M
+Jupiter/M
+Jurassic/M
+Jurua/M
+Justice/M
+Justin/M
+Justina/M
+Justine/M
+Justinian/M
+Justus/M
+Jutland/M
+Juvenal/M
+Jyoti/M
+K/SMNRGJ
+KB/M
+KC
+KFC/M
+KGB/M
+KIA
+KKK/M
+KO/M
+KP
+KS
+KY
+Kaaba/M
+Kabul/M
+Kafka/M
+Kafkaesque/M
+Kagoshima/M
+Kahlil/M
+Kahlua/M
+Kahului/M
+Kai/M
+Kaia/M
+Kaifeng/M
+Kaila/M
+Kailua/M
+Kain/M
+Kaine/M
+Kaiser/MS
+Kaitlin/M
+Kaitlyn/M
+Kaja/M
+Kala/M
+Kalahari/M
+Kalamazoo/M
+Kalashnikov/M
+Kalb/M
+Kalevala/M
+Kalgoorlie/M
+Kali/M
+Kalil/M
+Kalina/M
+Kalle/M
+Kalmyk/M
+Kama/M
+Kamchatka/M
+Kamehameha/M
+Kampala/M
+Kampuchea/M
+Kan/SM
+Kanchenjunga/M
+Kandahar/M
+Kandinsky/M
+Kandy
+Kane/M
+Kaneohe/M
+Kania/M
+Kankakee/M
+Kannada/M
+Kano/M
+Kanpur/M
+Kansan/MS
+Kansas/M
+Kant/M
+Kantian/M
+Kanya/M
+Kaohsiung/M
+Kaposi/M
+Kara/M
+Karachi/M
+Karaganda/M
+Karakorum/M
+Karamazov/M
+Kare/M
+Kareem/M
+Karel/M
+Karen/M
+Karenina/M
+Kari/M
+Karim/M
+Karin/M
+Karina/M
+Karine/M
+Karl/MN
+Karla/M
+Karlen/M
+Karloff/M
+Karly/M
+Karna/M
+Karnataka/M
+Karo/MY
+Karol/M
+Karolina/M
+Karoline/M
+Karoly/M
+Karon/M
+Karroo/M
+Karyn/M
+Kasai/M
+Kasey/M
+Kashmir/SM
+Kaspar/M
+Kasparov/M
+Kasper/M
+Kass
+Kassandra/M
+Kat/M
+Kata/M
+Katalin/M
+Kate/M
+Katelyn/M
+Katerina/M
+Kath/M
+Katha/M
+Katharina/M
+Katharine/M
+Kathe/M
+Katherina/M
+Katherine/M
+Katheryn/M
+Kathi/M
+Kathiawar/M
+Kathie/M
+Kathleen/M
+Kathmandu/M
+Kathrine/M
+Kathryn/M
+Kathy/M
+Kati/M
+Katie/M
+Katina/M
+Katinka/M
+Katmai/M
+Katmandu/M
+Katowice/M
+Katrina/M
+Katrine
+Katrinka/M
+Katy/M
+Katya/M
+Kauai/M
+Kaufman/M
+Kaunas/M
+Kaunda/M
+Kavanaugh/M
+Kawabata/M
+Kawasaki/M
+Kay/M
+Kaycee/M
+Kaye/M
+Kayla/M
+Kaylee/M
+Kayne/M
+Kazakh/M
+Kazakhs
+Kazakhstan/M
+Kazan/M
+Kazantzakis/M
+Kb/M
+Kean
+Keane/M
+Kearney/M
+Keaton/M
+Keats/M
+Keck/M
+Keefe/RM
+Keefer/M
+Keeley/M
+Keely/M
+Keenan/M
+Keene/M
+Keewatin/M
+Keillor/M
+Keir/M
+Keisha/M
+Keith/M
+Kellen/M
+Keller/M
+Kelley/M
+Kelli/M
+Kellie/M
+Kellogg/M
+Kelly/M
+Kelsey/M
+Kelvin/M
+Kemerovo/M
+Kemp/M
+Kempis/M
+Ken/M
+Kendal/M
+Kendall/M
+Kendell/M
+Kendra/M
+Kendrick/MS
+Kenmore/M
+Kenn/M
+Kenna/M
+Kennan/M
+Kennedy/M
+Kenneth/M
+Kennett/M
+Kennewick/M
+Kennith/M
+Kenny/M
+Kenosha/M
+Kent/M
+Kenton/M
+Kentuckian/MS
+Kentucky/M
+Kenya/M
+Kenyan/SM
+Kenyatta/M
+Kenyon/M
+Keogh/M
+Keokuk/M
+Kepler/M
+Ker/M
+Kerala/M
+Kerby/M
+Kerensky/M
+Keri/M
+Kerk/M
+Kermit/M
+Kern/M
+Kerouac/M
+Kerr/M
+Kerri/M
+Kerrie/M
+Kerry/M
+Kerstin/M
+Kerwin/M
+Kettering/M
+Kev/MN
+Kevan/M
+Keven/M
+Kevin/M
+Kevlar/M
+Kevorkian/M
+Kewpie/M
+Key/M
+Keynes/M
+Keynesian/M
+Khabarovsk/M
+Khachaturian/M
+Khalid/M
+Khalil/M
+Khan/M
+Kharkov/M
+Khartoum/M
+Khayyam/M
+Khazar/M
+Khazarica/M
+Khmer/M
+Khoikhoi/M
+Khoisan/M
+Khomeini/M
+Khorana/M
+Khrushchev/M
+Khufu/M
+Khulna/M
+Khwarizmi/M
+Khyber/M
+Ki/M
+Kickapoo/M
+Kidd/M
+Kiel/M
+Kierkegaard/M
+Kieth/M
+Kiev/M
+Kigali/M
+Kikuyu/M
+Kilauea/M
+Kile/M
+Kiley/M
+Kilian/M
+Kilimanjaro/M
+Killeen/M
+Killian/M
+Kilroy/M
+Kim/M
+Kimball/M
+Kimbell/M
+Kimberley/M
+Kimberly/M
+Kimble/M
+Kimmy/M
+Kincaid/M
+King/M
+Kingsley
+Kingsport/M
+Kingston/M
+Kingstown/M
+Kinko/M
+Kinney/M
+Kinsey/M
+Kinshasa/M
+Kinsley/M
+Kiowa/MS
+Kip/M
+Kipling/M
+Kipp/M
+Kira/M
+Kirby/M
+Kirchhoff/M
+Kirchner/M
+Kirghistan/M
+Kirghiz/M
+Kirghizia/M
+Kiri/M
+Kiribati/M
+Kirinyaga/M
+Kirk/M
+Kirkland/M
+Kirkpatrick/M
+Kirov/M
+Kirsten/M
+Kisangani/M
+Kishinev/M
+Kislev/M
+Kissimmee/M
+Kissinger/M
+Kit/M
+Kitakyushu/M
+Kitchener/M
+Kitts/M
+Kitty/M
+Kiwanis/M
+Klan/M
+Klansman/M
+Klara/M
+Klaus/M
+Klee/M
+Kleenex/MS
+Klein/M
+Klemens/M
+Klement/M
+Klimt/M
+Kline/M
+Klingon/M
+Klondike/MS
+Kmart/M
+Knapp/M
+Knesset/M
+Kngwarreye/M
+Knickerbocker/M
+Knievel/M
+Knight/M
+Knopf/M
+Knossos/M
+Knowles/M
+Knox/M
+Knoxville/M
+Knudsen/M
+Knuth/M
+Knuths
+Kobe/M
+Koch/M
+Kochab/M
+Kodachrome/M
+Kodak/M
+Kodaly/M
+Kodiak/M
+Koestler/M
+Kohinoor/M
+Kohl/M
+Koizumi/M
+Kojak/M
+Kokomo/M
+Kolyma/M
+Kommunizma/M
+Kong/M
+Kongo/M
+Konrad/M
+Konstantin/M
+Koo/M
+Koontz/M
+Koppel/M
+Kora/M
+Koran/MS
+Koranic
+Kore/M
+Korea/M
+Korean/SM
+Koren/M
+Kori/M
+Kornberg/M
+Kort/M
+Kory/M
+Korzybski/M
+Kosciusko/M
+Kosovo/M
+Kossuth/M
+Kosygin/M
+Kotlin/M
+Koufax/M
+Kowloon/M
+Kr/M
+Kraft/M
+Krakatau/M
+Krakatoa/M
+Krakow/M
+Kramer/M
+Krasnodar/M
+Krasnoyarsk/M
+Krebs/M
+Kremlin/M
+Kremlinologist
+Kremlinology
+Kresge/M
+Kringle/M
+Kris/M
+Krishna/M
+Krishnamurti/M
+Krista/M
+Kristen/M
+Kristi/M
+Kristian/M
+Kristie/M
+Kristin/M
+Kristina/M
+Kristine/M
+Kristopher/M
+Kristy/M
+Kroc/M
+Kroger/M
+Kronecker/M
+Kropotkin/M
+Kruger/M
+Krugerrand/M
+Krupp/M
+Krystal/M
+Krystyna/M
+Kshatriya/M
+Kuala/M
+Kubernetes/M
+Kublai/M
+Kubrick/M
+Kuhn/M
+Kuibyshev/M
+Kulthumm/M
+Kunming/M
+Kuomintang/M
+Kurd/M
+Kurdish/M
+Kurdistan/M
+Kurosawa/M
+Kurt/M
+Kurtis/M
+Kusch/M
+Kutuzov/M
+Kuwait/M
+Kuwaiti/SM
+Kuznets/M
+Kuznetsk/M
+Kwakiutl/M
+Kwan/M
+Kwangchow/M
+Kwangju/M
+Kwanzaa/MS
+Ky/MH
+Kyiv/M
+Kyla/M
+Kyle/M
+Kylie/M
+Kym/M
+Kyoto/M
+Kyrgyzstan/M
+Kyushu/M
+L'Amour/M
+L'Enfant
+L'Oreal/M
+L'Ouverture/M
+L/MN
+LA
+LAN/M
+LBJ/M
+LC
+LCD/M
+LCM
+LDC
+LED/M
+LG/M
+LGBT
+LIFO
+LISTSERV/M
+LL
+LLB/M
+LLD/M
+LNG
+LOGO
+LP/M
+LPG
+LPN/SM
+LSAT
+LSD/M
+LVN
+La/SM
+Lab
+Laban/M
+Labrador/SM
+Labradorean
+Labradorian
+Lacey/M
+Lachesis/M
+Lactobacillus
+Lacy/M
+Ladoga/M
+Ladonna/M
+Lady/M
+Ladyship/MS
+Laetitia/M
+Lafayette/M
+Lafitte/M
+Lagos/M
+Lagrange/M
+Lagrangian/M
+Lahore/M
+Lainey/M
+Laius/M
+Lajos/M
+Lakeisha/M
+Lakeland/M
+Lakers/M
+Lakewood
+Lakisha/M
+Lakota/M
+Lakshmi/M
+Lalo/M
+Lamaism/SM
+Lamar/M
+Lamarck/M
+Lamaze/M
+Lamb/M
+Lambert/M
+Lamborghini/M
+Lambrusco/M
+Lamentations
+Lamond/M
+Lamont/M
+Lana/M
+Lanai/M
+Lancashire/M
+Lancaster/M
+Lance/M
+Lancelot/M
+Land/M
+Landon/M
+Landry/M
+Landsat/M
+Landsteiner/M
+Lane/M
+Laney/M
+Lang/M
+Langerhans/M
+Langland/M
+Langley/M
+Langmuir/M
+Langston/M
+Lani/M
+Lanie/M
+Lanka/M
+Lankan/M
+Lanna/M
+Lanny/M
+Lansing/M
+Lanzhou/M
+Lao/SM
+Laocoon/M
+Laos/M
+Laotian/SM
+Laplace/M
+Laplacian
+Lapland/MR
+Lapp/SM
+Lara/M
+Laramie/M
+Lardner/M
+Laredo/M
+Lari/M
+Larisa/M
+Larissa/M
+Larousse/M
+Larry/M
+Lars/MN
+Larsen/M
+Larson/M
+Lascaux/M
+Lassa/M
+Lassen/M
+Lassie/M
+Lat/M
+Latasha/M
+Lateran/M
+Latham/M
+Latin/MRS
+Latina
+Latino/SM
+Latinx
+Latisha/M
+Latonya/M
+Latoya/M
+Latrobe/M
+Latvia/M
+Latvian/MS
+Laud/MR
+Lauder/M
+Laue/M
+Laughton
+Launce/M
+Laundromat/M
+Laura/M
+Laurasia/M
+Laure/M
+Laurel/M
+Lauren/SM
+Laurence/M
+Laurent/M
+Lauretta/M
+Laurette/M
+Lauri/M
+Laurie/M
+Lauryn/M
+Laval/M
+Lavern/M
+Laverne/M
+Lavina/M
+Lavinia/M
+Lavoisier/M
+Lavonne/M
+Lawanda/M
+Lawrence/M
+Lawry/M
+Lawson/M
+Lawton/M
+Layamon/M
+Layla/M
+Layne/M
+Layton/M
+Lazar/M
+Lazare/M
+Lazaro/M
+Lazarus/M
+Le/SM
+Lea/M
+Leach/M
+Leadbelly/M
+Leah/M
+Leakey/M
+Lean/M
+Leander/M
+Leandra/M
+Leann/M
+Leanna/M
+Leanne/M
+Lear/M
+Learjet/M
+Leary/M
+Leavenworth/M
+Lebanese/M
+Lebanon/M
+Lebesgue/M
+Leblanc/M
+Leda/M
+Lederberg/M
+Lee/M
+Leeds/M
+Leela/M
+Leena/M
+Leesburg/M
+Leese/M
+Leeuwenhoek/M
+Leeward/M
+Left
+Legendre/M
+Leger/M
+Leghorn/M
+Lego/M
+Legree/M
+Lehman/M
+Leia/M
+Leibniz/M
+Leica/M
+Leicester/SM
+Leiden/M
+Leif/M
+Leigh/M
+Leighton/M
+Leila/M
+Leipzig/M
+Lek/M
+Lela/M
+Leland/M
+Lelia/M
+Lem/M
+Lemaitre/M
+Lemuel/M
+Lemuria/M
+Len/M
+Lena/M
+Lenard/M
+Lenin/M
+Leningrad/M
+Leninism/M
+Leninist/M
+Lennard/M
+Lennie/M
+Lennon/M
+Lenny/M
+Leno/M
+Lenoir/M
+Lenora/M
+Lenore/M
+Lent/SMN
+Lenten/M
+Leo/SM
+Leola/M
+Leominster/M
+Leon/M
+Leona/M
+Leonard/M
+Leonardo/M
+Leoncavallo/M
+Leone/M
+Leonel/M
+Leonhard/M
+Leonid/M
+Leonidas/M
+Leonie/M
+Leonor/M
+Leonora/M
+Leonore/M
+Leontine/M
+Leopold/M
+Leopoldo/M
+Leora/M
+Lepidus/M
+Lepke/M
+Lepus/M
+Lerner/M
+Leroi/M
+Leroy/M
+Les/M
+Lesa/M
+Lesley/M
+Leslie/M
+Lesotho/M
+Lesseps/M
+Lessie/M
+Lester/M
+Lestrade/M
+Leta/M
+Letha/M
+Lethe/M
+Leticia/M
+Letitia/M
+Letizia/M
+Letterman/M
+Lettie/M
+Letty/M
+Lev
+Levant/M
+Levesque/M
+Levey/M
+Levi/SM
+Leviathan/M
+Levin/M
+Levine/M
+Leviticus/M
+Levitt/M
+Levon/M
+Levy/M
+Lew/M
+Lewes
+Lewinsky/M
+Lewis/M
+Lewiston/M
+Lewisville/M
+Lexi/M
+Lexie/M
+Lexington/M
+LexisNexis/M
+Lexus/M
+Lexy/M
+Leyla/M
+Lhasa/MS
+Lhotse/M
+Li/MY
+Lia/M
+Liam/M
+Lian/M
+Liana/M
+Liane/M
+Lianne/M
+Liaoning/M
+Libbey/M
+Libbie/M
+Libby/M
+Liberace/M
+Liberal
+Liberia/M
+Liberian/SM
+Libra/MS
+LibreOffice/M
+Libreville/M
+Librium/M
+Libya/M
+Libyan/SM
+Lichtenstein/M
+Lida/M
+Lidia/M
+Lie/M
+Lieberman/M
+Liebfraumilch/M
+Liechtenstein/ZMR
+Liechtensteiner/M
+Lief's
+Liege/M
+Lieut
+Lil/MY
+Lila/M
+Lilah/M
+Lilia/MS
+Lilian/M
+Liliana/M
+Liliane/M
+Lilith/M
+Liliuokalani/M
+Lilla/M
+Lille/M
+Lilli/M
+Lillian/M
+Lillie/M
+Lilliput/M
+Lilliputian/MS
+Lilly/M
+Lilongwe/M
+Lily/M
+Lima/M
+Limbaugh/M
+Limbo
+Limburger/M
+Limoges/M
+Limousin/M
+Limpopo/M
+Lin/M
+Lina/M
+Linc/M
+Lincoln/MS
+Lincolnshire/M
+Lind/M
+Linda/M
+Lindbergh/M
+Lindi/M
+Lindon/M
+Lindsay/M
+Lindsey/M
+Lindy/M
+Linea/M
+LinkedIn/M
+Linn/M
+Linnaeus/M
+Linnea/M
+Linnell/M
+Linotype/M
+Linton/M
+Linus/M
+Linux/MS
+Linwood/M
+Lionel/M
+Lipizzaner/M
+Lippi/M
+Lippmann/M
+Lipscomb/M
+Lipton/M
+Lisa/M
+Lisbeth/M
+Lisbon/M
+Lise/M
+Lisette/M
+Lisle/M
+Lissa/M
+Lissajous/M
+Lissy/M
+Lister/M
+Listerine/M
+Liston/M
+Liszt/M
+Lita/M
+Lithuania/M
+Lithuanian/MS
+Little/M
+Litton/M
+Liv/M
+LiveJournal/M
+Livermore/M
+Liverpool/M
+Liverpudlian/SM
+Livia/M
+Livingston/M
+Livingstone/M
+Livonia/M
+Livvy/M
+Livy/M
+Liz/M
+Liza/M
+Lizabeth/M
+Lizbeth/M
+Lizette/M
+Lizzie/M
+Lizzy/M
+Ljubljana/M
+Llewellyn/M
+Lloyd/M
+Ln
+Loafer/SM
+Lobachevsky/M
+Lochinvar/M
+Locke/M
+Lockean/M
+Lockheed/M
+Lockwood/M
+Lodge/M
+Lodi/M
+Lodovico/M
+Lodz/M
+Loewe/M
+Loewi/M
+Loews/M
+Logan/M
+Logitech/M
+Lohengrin/M
+Loire/M
+Lois/M
+Loki/M
+Lola/M
+Lolita/M
+Lollard/M
+Lollobrigida/M
+Lolly's
+Lombard/M
+Lombardi/M
+Lombardy/M
+Lome/M
+Lompoc/M
+Lon/M
+Lona/M
+London/MRZ
+Londoner/M
+Long/M
+Longfellow/M
+Longmont/M
+Longstreet/M
+Longueuil
+Longview/M
+Loni/M
+Lonnie/M
+Lonny/M
+LookSmart/M
+Lopez/M
+Lora/M
+Lorain/M
+Loraine/M
+Lorant/M
+Lord/SM
+Lordship/SM
+Lorelei/M
+Loren/M
+Lorena/M
+Lorene/M
+Lorentz/M
+Lorentzian
+Lorenz/M
+Lorenza/M
+Lorenzo/M
+Loretta/M
+Lorette/M
+Lori/M
+Loria/M
+Lorie/M
+Lorin/M
+Lorinda/M
+Lorna/M
+Lorne/M
+Lorraine/M
+Lorre/M
+Lorrie/M
+Lory/M
+Los
+Lot/M
+Lothario/SM
+Lott/M
+Lotta/M
+Lotte/M
+Lotti/M
+Lottie/M
+Lotty/M
+Lou/M
+Louella/M
+Louie/M
+Louis/M
+Louisa/M
+Louise/M
+Louisiana/M
+Louisianan/MS
+Louisianian/MS
+Louisville/M
+Lourdes/M
+Louvre/M
+Love/M
+Lovecraft/M
+Lovelace/M
+Lovell
+Lowe/M
+Lowell/M
+Lowenbrau/M
+Lowery/M
+Lowlands
+Loy/M
+Loyang/M
+Loyd/M
+Loyola/M
+Lr
+Lt
+Ltd
+Lu/M
+Luanda/M
+Luann/M
+Lubavitcher/M
+Lubbock/M
+Lubumbashi/M
+Luca/SM
+Lucas/M
+Luce/M
+Luci/MN
+Lucia/M
+Lucian/M
+Luciana/M
+Luciano/M
+Lucie/M
+Lucien/M
+Lucienne/M
+Lucifer/M
+Lucile/M
+Lucille/M
+Lucina
+Lucinda/M
+Lucio/M
+Lucite/SM
+Lucius/M
+Lucknow/M
+Lucky's
+Lucretia/M
+Lucretius/M
+Lucy/M
+Luddite/MS
+Ludhiana/M
+Ludovico/M
+Ludvig/M
+Ludwig/M
+Luella/M
+Lufthansa/M
+Luftwaffe/M
+Luger/M
+Lugosi/M
+Luigi/M
+Luis/M
+Luisa/M
+Luise/M
+Lukas/M
+Luke/M
+Lula/M
+Lully/M
+Lulu/M
+Lumiere/M
+Lumi竪re/M
+Luna/M
+Lupe/M
+Lupercalia/M
+Lupus/M
+Lura/M
+Luria/M
+Lusaka/M
+Lusitania/M
+Luther/M
+Lutheran/SM
+Lutheranism/MS
+Luvs/M
+Luxembourg/ZMR
+Luxembourger/M
+Luxembourgian
+Luz/M
+Luzon/M
+Lvov/M
+Ly/MY
+LyX/M
+Lyallpur
+Lycos/M
+Lycra/M
+Lycurgus/M
+Lyda/M
+Lydia/M
+Lydian/SM
+Lydie/M
+Lydon/M
+Lyell/M
+Lyle/M
+Lyly/M
+Lyman/M
+Lyme/M
+Lyn/M
+Lynch/M
+Lynchburg/M
+Lynda/M
+Lynde/M
+Lyndon/M
+Lyndsay/M
+Lyndsey/M
+Lynette/M
+Lynn/M
+Lynne/M
+Lynnette/M
+Lyon/SM
+Lyons/M
+Lyra/M
+Lysenko/M
+Lysistrata/M
+Lysol/M
+Lyssa/M
+M/SMGB
+MA/M
+MASH
+MB/M
+MBA/M
+MC
+MCI/M
+MD/M
+MDF
+MDT
+ME
+MEGO/S
+MFA/M
+MGM/M
+MHz/M
+MI/M
+MIA
+MIDI/M
+MIPS
+MIRV
+MIT/M
+MM
+MN
+MO
+MOOC
+MP/M
+MPEG/SM
+MRI/M
+MS/M
+MSG/M
+MST/M
+MSW
+MT/M
+MTF/SM
+MTV/M
+MVP/M
+MW
+Maalox/M
+Mab
+Mabel/M
+Mable/M
+Mac/M
+MacArthur/M
+MacBride/M
+MacDonald/M
+MacLeish/M
+Macao/M
+Macau/M
+Macaulay/M
+Macbeth/M
+Maccabees
+Maccabeus/M
+Mace/M
+Macedon/M
+Macedonia/M
+Macedonian/SM
+Mach/M
+Machiavelli/M
+Machiavellian/M
+Macias/M
+Macintosh/M
+Mack/M
+Mackenzie/M
+Mackinac/M
+Mackinaw/M
+Macmillan/M
+Macon/M
+Macromedia/M
+Macumba/M
+Macy/M
+Mada/M
+Madagascan/SM
+Madagascar/M
+Madalyn/M
+Madam
+Maddalena/M
+Madden/M
+Maddi/M
+Maddie/M
+Maddox/M
+Maddy/M
+Madeira/SM
+Madelaine/M
+Madeleine/M
+Madeline/M
+Madelon/M
+Madelyn/M
+Madera/M
+Madge/M
+Madison/M
+Madonna/SM
+Madras/M
+Madrid/M
+Madurai/M
+Mae/M
+Maeterlinck/M
+Mafia/MS
+Mafioso/M
+Magda/M
+Magdalen
+Magdalena/M
+Magdalene/M
+Magellan/M
+Magellanic/M
+Maggi/M
+Maggie/M
+Maggy/M
+Maghreb/M
+Magi
+Maginot/M
+Magnificat
+Magnitogorsk/M
+Magog/M
+Magoo/M
+Magritte/M
+Magsaysay/M
+Magus
+Magyar/SM
+Mahabharata/M
+Mahala/M
+Mahalia/M
+Maharashtra/M
+Mahavira/M
+Mahayana/M
+Mahayanist/M
+Mahdi/M
+Mahfouz/M
+Mahican/SM
+Mahler/M
+Mahmoud/M
+Mahmud/M
+Mai/M
+Maia/M
+Maidenform/M
+Maigret/M
+Mailer/M
+Maillol/M
+Maiman/M
+Maimonides/M
+Maine/MZR
+Mainer/M
+Mair/M
+Maire/M
+Maisie/M
+Maison/M
+Maitreya/M
+Maj
+Majesty
+Major/M
+Majorca/M
+Majuro/M
+Makarios/M
+Maker/M
+Mal
+Mala/M
+Malabar/M
+Malabo/M
+Malacca/M
+Malachi/M
+Malagasy/M
+Malamud/M
+Malaprop/M
+Malawi/M
+Malawian/SM
+Malay/MS
+Malaya/M
+Malayalam/M
+Malayan/MS
+Malaysia/M
+Malaysian/MS
+Malcolm/M
+Maldive/MS
+Maldives/M
+Maldivian/MS
+Maldonado/M
+Male/M
+Mali/M
+Malia/M
+Malian/SM
+Malibu/M
+Malina/M
+Malinda/M
+Malinowski/M
+Malissa/M
+Mallarme/M
+Mallarm辿/M
+Mallomars/M
+Mallory/M
+Malone/M
+Malory/M
+Malplaquet/M
+Malraux/M
+Malta/M
+Maltese/M
+Malthus/M
+Malthusian/SM
+Malva/M
+Malvin/M
+Malvina/M
+Mame/M
+Mameluke/M
+Mamet/M
+Mamie/M
+Mammon/SM
+Mamore/M
+Man/M
+Managua/M
+Manama/M
+Manasseh/M
+Manchester/M
+Manchu/SM
+Manchuria/M
+Manchurian/M
+Mancini/M
+Mancunian/MS
+Manda/M
+Mandalay/M
+Mandarin/M
+Mandel/M
+Mandela/M
+Mandelbrot/M
+Mandeville/M
+Mandi/M
+Mandie/M
+Mandingo/M
+Mandrell/M
+Mandy/M
+Manet/M
+Manfred/M
+Manhattan/SM
+Mani/M
+Manichean/M
+Manila/SM
+Manitoba/M
+Manitoulin/M
+Mankato/M
+Manley/M
+Mann/GM
+Mannheim/M
+Mannie/M
+Manning/M
+Manny/M
+Mano/M
+Manolo/M
+Manon/M
+Mansfield/M
+Manson/M
+Manteca/M
+Mantegna/M
+Mantle/M
+Manuel/M
+Manuela/M
+Manx/M
+Manya/M
+Mao/M
+Maoism/SM
+Maoist/SM
+Maori/MS
+MapQuest/M
+Mapplethorpe/M
+Maputo/M
+Mar/SMN
+Mara/M
+Maracaibo/M
+Marat/M
+Maratha/M
+Marathi/M
+Marathon/M
+Marc/M
+Marceau/M
+Marcel/M
+Marcela/M
+Marcelino/M
+Marcella/M
+Marcelle/M
+Marcello/M
+Marcellus
+Marcelo/M
+March/MS
+Marci/M
+Marcia/M
+Marciano/M
+Marcie/M
+Marco/MS
+Marconi/M
+Marcos/M
+Marcus/M
+Marcuse
+Marcy/M
+Marduk/M
+Maren/M
+Marga/M
+Margalit/M
+Margaret/M
+Margareta/M
+Margarete/M
+Margaretha/M
+Margarethe/M
+Margaretta/M
+Margarita/M
+Margarito/M
+Margaux
+Marge/M
+Margery/M
+Marget/M
+Margie/M
+Margit/M
+Margo/M
+Margot/M
+Margret/M
+Margrethe/M
+Marguerite/M
+Margy/M
+Mari/SM
+Maria/M
+MariaDB/M
+Mariam/M
+Marian/M
+Mariana/SM
+Marianas/M
+Marianna/M
+Marianne/M
+Mariano/M
+Maribel/M
+Maribeth/M
+Maricela/M
+Marie/M
+Mariel/M
+Marielle/M
+Marietta/M
+Mariette/M
+Marika/M
+Marilee/M
+Marilyn/M
+Marin/M
+Marina/M
+Marine/SM
+Mario/M
+Marion/M
+Maris/M
+Marisa/M
+Mariska/M
+Marisol/M
+Marissa/M
+Marita/M
+Maritain/M
+Maritza/M
+Mariupol
+Marius/M
+Marj/M
+Marja/M
+Marjorie/M
+Marjory/M
+Mark/SM
+Markab/M
+Markham/M
+Markos
+Markov/M
+Marks/M
+Markus/M
+Marla/M
+Marlboro/M
+Marlborough/M
+Marlee/M
+Marleen/M
+Marlena/M
+Marlene/M
+Marley/M
+Marlin/M
+Marline/M
+Marlo/M
+Marlon/M
+Marlow/M
+Marlowe/M
+Marmaduke/M
+Marmara/M
+Marne/M
+Marney/M
+Marni/M
+Marnie/M
+Maronite/M
+Marple/M
+Marquesas/M
+Marquette/M
+Marquez/M
+Marquis/M
+Marquita/M
+Marrakesh/M
+Marriott/M
+Marris/M
+Mars/MS
+Marsala/M
+Marseillaise/MS
+Marseilles/M
+Marsh/M
+Marsha/M
+Marshall/M
+Marta/M
+Martel/M
+Martha/M
+Marthe/M
+Marti/M
+Martial/M
+Martian/SM
+Martie/M
+Martin/M
+Martina/M
+Martinez/M
+Martinique/M
+Martino/M
+Marty/M
+Martyn/M
+Marv/M
+Marva/M
+Marvell/M
+Marvin/M
+Marx/M
+Marxian
+Marxism/SM
+Marxist/SM
+Mary/M
+Marya/M
+Maryann/M
+Maryanne/M
+Marybeth/M
+Maryellen/M
+Maryland/MR
+Marylander/M
+Marylin/M
+Marylou/M
+Marys
+Marysville/M
+Masada/M
+Masai/M
+Masaryk/M
+Mascagni/M
+Masefield/M
+Maserati/M
+Maseru/M
+Masha/M
+Mashhad/M
+Mason/MS
+Masonic/M
+Masonite/M
+Mass/MS
+Massachusetts/M
+Massasoit/M
+Massenet/M
+Massey/M
+Massimiliano/M
+Massimo/M
+Master/S
+MasterCard/M
+Masters/M
+Mata/M
+Mateo/M
+MathML/M
+Mathe/MR
+Mather/M
+Matheson/M
+Mathew/SM
+Mathews/M
+Mathewson/M
+Mathias/M
+Mathilda/M
+Mathilde/M
+Mathis/M
+Matias/M
+Matilda/M
+Matilde/M
+Matisse/M
+Matlab/M
+Matt/M
+Mattel/M
+Matteo/M
+Matterhorn/M
+Matthew/SM
+Matthews/M
+Matthias/M
+Matthieu/M
+Matti/M
+Mattias/M
+Mattie/M
+Matty/M
+Maud/M
+Maude/M
+Maudie/M
+Maugham/M
+Maui/M
+Mauldin/M
+Maupassant/M
+Maura/M
+Maureen/M
+Mauriac/M
+Maurice/M
+Mauricio/M
+Maurie/M
+Maurine/M
+Mauritania/M
+Mauritanian/SM
+Mauritian/SM
+Mauritius/M
+Maurits/M
+Maurizio/M
+Mauro/M
+Maurois/M
+Maury
+Mauryan/M
+Mauser/M
+Mavis/M
+Max/M
+Maxie/M
+Maximilian/M
+Maximilien/M
+Maximo/M
+Maxine/M
+Maxwell/M
+May/SMR
+Maya/SM
+Mayan/MS
+Maybelle/M
+Maye/M
+Mayer/M
+Mayfair/M
+Mayflower/M
+Maynard/M
+Mayne/M
+Mayo/M
+Maypole
+Mayra/M
+Mays/M
+Maytag/M
+Mazama/M
+Mazarin/M
+Mazatlan/M
+Mazda/M
+Mazola/M
+Mazzini/M
+Mb/M
+Mbabane/M
+Mbini/M
+Mbps
+McAdam/M
+McAfee/M
+McAllen/M
+McBride/M
+McCain/M
+McCall/M
+McCann/M
+McCarthy/M
+McCarthyism/M
+McCartney/M
+McCarty/M
+McClain/M
+McClellan/M
+McClure/M
+McConnell/M
+McCormick/M
+McCoy/M
+McCray/M
+McCullough/M
+McDaniel/M
+McDonald/M
+McDonnell/M
+McDowell/M
+McEnroe/M
+McFadden/M
+McFarland/M
+McGee/M
+McGovern/M
+McGowan/M
+McGuffey/M
+McGuire/M
+McHenry/M
+McIntosh/M
+McIntyre/M
+McJob
+McKay/M
+McKee/M
+McKenzie/M
+McKinley/M
+McKinney/M
+McKnight/M
+McLaughlin/M
+McLean/M
+McLeod/M
+McLuhan/M
+McMahon/M
+McMillan/M
+McNamara/M
+McNaughton/M
+McNeil/M
+McPherson/M
+McQueen/M
+McVeigh/M
+Md/M
+Me
+Mead/M
+Meade/M
+Meadows/M
+Meagan/M
+Meaghan/M
+Meany/M
+Meara/M
+Mecca/MS
+Medan/M
+Medea/M
+Medellin/M
+Medford/M
+Media/M
+Medicaid/SM
+Medicare/SM
+Medici/M
+Medina/M
+Mediterranean/MS
+Medline/M
+Medusa/M
+Meg/M
+Megan/M
+Meggie/M
+Meghan/M
+Mei/MR
+Meier/M
+Meighen/M
+Meiji/M
+Meir/M
+Mejia/M
+Mekong/M
+Mel/MY
+Mela/M
+Melanesia/M
+Melanesian/M
+Melania/M
+Melanie/M
+Melba/M
+Melbourne/M
+Melchior/M
+Melchizedek/M
+Melendez/M
+Melicent/M
+Melina/M
+Melinda/M
+Melisa/M
+Melisande/M
+Melissa/M
+Melita/M
+Mella/M
+Melli/M
+Mellie/M
+Mellon/M
+Melly/M
+Melodie/M
+Melody/M
+Melony/M
+Melpomene/M
+Melton/M
+Melva/M
+Melville/M
+Melvin/M
+Melvyn/M
+Memcached/M
+Memling/M
+Memphis/M
+Menander/M
+Menard/M
+Mencius/M
+Mencken/M
+Mendel/M
+Mendeleev/M
+Mendelian/M
+Mendelssohn/M
+Mendez/M
+Mendocino/M
+Mendoza/M
+Menelaus/M
+Menelik/M
+Menes/M
+Mengzi
+Menifee/M
+Menkalinan/M
+Menkar/M
+Menkent/M
+Mennen/M
+Mennonite/MS
+Menominee/M
+Menotti/M
+Mensa/M
+Mentholatum/M
+Menuhin/M
+Menzies/M
+Mephisto
+Mephistopheles/M
+Merak/M
+Mercado/M
+Mercator/M
+Merced/M
+Mercedes/M
+Mercer/M
+Merci/M
+Mercia/M
+Merck/M
+Mercurochrome/M
+Mercury/SM
+Meredith/M
+Meriel/M
+Merino/M
+Merl/M
+Merle/M
+Merlin/M
+Merlot/M
+Merovingian/M
+Merriam/M
+Merrick/M
+Merrie/M
+Merrill/M
+Merrily's
+Merrimack/M
+Merritt/M
+Merry's
+Mersey
+Merthiolate/M
+Merton/M
+Merv/M
+Mervin/M
+Merwin/M
+Merwyn/M
+Meryl/M
+Mesa/M
+Mesabi/M
+Meshed/M
+Mesmer/M
+Mesolithic/M
+Mesopotamia/M
+Mesopotamian
+Mesozoic/M
+Messerschmidt/M
+Messiaen/M
+Messiah/M
+Messiahs
+Messianic
+Messieurs
+Metacafe/M
+Metallica/M
+Metamucil/M
+Methodism/SM
+Methodist/SM
+Methuselah/M
+Metternich/M
+Meuse/M
+Mex
+Mexicali/M
+Mexican/MS
+Mexico/M
+Meyer/MS
+Meyerbeer/M
+Meyers/M
+Mfume/M
+Mg/M
+Mgr
+MiG/M
+Mia/M
+Miami/MS
+Miaplacidus/M
+Micaela/M
+Micah/M
+Micawber/M
+Mich/M
+Michael/M
+Michaela/M
+Michaelmas/MS
+Michail/M
+Michal/M
+Micheal/M
+Michel/M
+Michelangelo/M
+Michele/M
+Michelin/M
+Micheline/M
+Michell/M
+Michelle/M
+Michelob/M
+Michelson/M
+Michigan/M
+Michigander/MS
+Michiganite
+Mick/M
+Mickey/M
+Micki/M
+Mickie/M
+Micky/M
+Micmac/SM
+Micronesia/M
+Micronesian/M
+Microsoft/M
+Midas/M
+Middleton/M
+Middletown/M
+Mideast
+Mideastern
+Midland/MS
+Midway/M
+Midwest/M
+Midwestern/MR
+Mignon/M
+Miguel/M
+Mikael/M
+Mike/M
+Mikel/M
+Mikey/M
+Mikhail/M
+Mikkel/M
+Mikoyan/M
+Milagros/M
+Milan/M
+Milanese
+Mildred/M
+Milena/M
+Miles/M
+Milford/M
+Milken/M
+Mill/SMR
+Millard/M
+Millay/M
+Miller/M
+Millet/M
+Milli/M
+Millicent/M
+Millie/M
+Millikan/M
+Mills/M
+Milly/M
+Milne/M
+Milo/M
+Milosevic/M
+Milquetoast/M
+Miltiades/M
+Milton/M
+Miltonian
+Miltonic/M
+Miltown/M
+Milwaukee/M
+Mimi/M
+Mimosa/M
+Min/M
+Mina/M
+Minamoto/M
+Minda/M
+Mindanao/M
+Mindoro/M
+Mindy/M
+Minerva/M
+Minette/M
+Ming/M
+Mingus/M
+Minn
+Minna
+Minne/M
+Minneapolis/M
+Minnelli/M
+Minnesota/M
+Minnesotan/SM
+Minnie/M
+Minny/M
+Minoan/MS
+Minolta/M
+Minos/M
+Minot/M
+Minotaur/M
+Minsk/M
+Minsky/M
+Minta/M
+Mintaka/M
+Minuit/M
+Minuteman/M
+Miocene/M
+Mir/M
+Mira/M
+Mirabeau/M
+Mirabel/M
+Mirabella/M
+Mirabelle/M
+Mirach/M
+Miran/M
+Miranda/M
+Mireille/M
+Mirella/M
+Mirfak/M
+Miriam/M
+Mirna/M
+Miro/M
+Mirzam/M
+Mischa/M
+Misha/M
+Miskito/M
+Miss
+Missie/M
+Mississauga/M
+Mississippi/M
+Mississippian/SM
+Missoula/M
+Missouri/M
+Missourian/MS
+Missy/M
+Mistassini/M
+Mister
+Mistress
+Misty/M
+Mitch/M
+Mitchel/M
+Mitchell/M
+Mitford/M
+Mithra/M
+Mithridates/M
+Mitsubishi/M
+Mitterrand/M
+Mitty/M
+Mitzi/M
+Mixtec/M
+Mizar/M
+Mk
+Mlle
+Mme/S
+Mn/M
+Mnemosyne/M
+Mo/M
+Mobil/M
+Mobile/M
+Mobutu/M
+Modesto/M
+Modigliani/M
+Moe/M
+Moet/M
+Mogadishu/M
+Mogul/MS
+Mohacs/M
+Mohamed/M
+Mohammad/M
+Mohammedan/SM
+Mohammedanism/SM
+Mohandas/M
+Mohave/SM
+Mohawk/SM
+Mohegan
+Moho/M
+Mohorovicic/M
+Moira/M
+Moise/MS
+Moises/M
+Moiseyev/M
+Moishe/M
+Mojave/SM
+Moldavia/M
+Moldavian
+Moldova/M
+Moldovan
+Moliere/M
+Molina/M
+Moll/M
+Mollie/M
+Molly/M
+Molnar/M
+Moloch/M
+Molokai/M
+Molotov/M
+Moluccas/M
+Mombasa/M
+Mon/SM
+Mona/M
+Monacan
+Monaco/M
+Mondale/M
+Monday/SM
+Mondrian/M
+Monegasque/SM
+Monera/M
+Monessen/M
+Monet/M
+MongoDB/M
+Mongol/SM
+Mongolia/M
+Mongolian/SM
+Mongolic/M
+Mongolica/M
+Mongoloid
+Monica/M
+Monika/M
+Monique/M
+Monk/M
+Monmouth/M
+Monongahela/M
+Monro/M
+Monroe/M
+Monrovia/M
+Monsanto/M
+Monsieur/M
+Monsignor/SM
+Mont/M
+Montague/M
+Montaigne/M
+Montana/M
+Montanan/SM
+Montcalm/M
+Monte/M
+Montenegrin/M
+Montenegro/M
+Monterey/M
+Monterrey/M
+Montesquieu/M
+Montessori/M
+Monteverdi/M
+Montevideo/M
+Montezuma/M
+Montgolfier/M
+Montgomery/M
+Monti/M
+Monticello/M
+Montoya/M
+Montpelier/M
+Montrachet/M
+Montreal/M
+Montserrat/M
+Monty/M
+Moody/M
+Moog/M
+Moon/M
+Mooney/M
+Moor/SM
+Moore/M
+Moorish/M
+Mora/M
+Morales/M
+Moran/M
+Moravia/M
+Moravian/M
+Mord/M
+Mordecai
+Mordred/M
+More/M
+Morena/M
+Moreno/M
+Morey/M
+Morgan/SM
+Morgana/M
+Morgantown/M
+Morgen/M
+Moria/M
+Moriarty/M
+Morin/M
+Morison/M
+Morita/M
+Moritz/M
+Morley/M
+Mormon/SM
+Mormonism/SM
+Morna/M
+Moro/M
+Moroccan/SM
+Morocco/M
+Moroni/M
+Morpheus/M
+Morphy/M
+Morrie/M
+Morris/M
+Morrison/M
+Morristown/M
+Morrow/M
+Morse/M
+Mort/MN
+Morten/M
+Mortimer/M
+Morton/M
+Morty/M
+Mosaic/M
+Moscow/M
+Mose/SM
+Moseley/M
+Moselle/M
+Moses/M
+Moshe/M
+Moslem/M
+Mosley/M
+Moss/M
+Mosul/M
+Motorola/M
+Motown/M
+Motrin/M
+Mott/M
+Moulton/M
+Mount/M
+Mountbatten/M
+Mountie/MS
+Moussorgsky/M
+Mouthe/M
+Mouton/M
+Mowgli/M
+Moyra/M
+Mozambican/SM
+Mozambique/M
+Mozart/M
+Mozilla/M
+Mozillian/MS
+Mr/SM
+Ms/S
+Msgr
+Mt
+Muawiya/M
+Mubarak/M
+Mueller/M
+Muenster/MS
+Mugabe/M
+Muhammad/M
+Muhammadan/MS
+Muhammadanism/SM
+Muir/M
+Mujib/M
+Mulder/M
+Mullen/M
+Muller/M
+Mulligan/M
+Mullikan/M
+Mullins/M
+Mulroney/M
+Multan/M
+Multics
+Mumbai/M
+Mumford/M
+Munch/M
+Munchausen/M
+Muncie/M
+Munich/M
+Munoz/M
+Munro/M
+Munroe/M
+Munster/M
+Muppet/M
+Murasaki/M
+Murat/M
+Murchison/M
+Murcia
+Murdoch/M
+Murdock/M
+Murfreesboro/M
+Muriel/M
+Murillo/M
+Murine/M
+Murmansk/M
+Murphy/M
+Murray/M
+Murrieta/M
+Murrow/M
+Murrumbidgee/M
+Murry/M
+Muscat/M
+Muscovite/M
+Muscovy/M
+Muse/M
+Musharraf/M
+Musial/M
+Muskegon/M
+Muskogee/M
+Muslim/MS
+Mussolini/M
+Mussorgsky/M
+Mutsuhito/M
+Muzak/M
+My's
+MySQL/M
+MySpace/M
+MySpell/M
+Myanmar/M
+Mycenae/M
+Mycenaean/M
+Myer/SM
+Myers/M
+Mylar/MS
+Myles/M
+Myra/M
+Myrdal/M
+Myriam/M
+Myrna/M
+Myron/M
+Myrtle/M
+Mysore/M
+Myst/M
+M端nchhausen/M
+N'Djamena
+N/MD
+NAACP/M
+NAFTA/M
+NASA/M
+NASCAR/M
+NASDAQ/M
+NATO/M
+NB
+NBA/M
+NBC/M
+NBS
+NC
+NCAA/M
+NCO
+ND
+NE/M
+NEH
+NF
+NFC
+NFL/M
+NGO/SM
+NH
+NHL/M
+NIH
+NIMBY
+NJ
+NLRB
+NM
+NORAD/M
+NOW
+NP
+NPR/M
+NR
+NRA
+NRC
+NS
+NSA/M
+NSC
+NSF
+NSFW
+NSPR/M
+NSS/M
+NT
+NV
+NVIDIA/M
+NW/M
+NWT
+NY
+NYC
+NYSE
+NZ
+Na/M
+Nabisco/M
+Nabokov/M
+Nada/M
+Nader/M
+Nadia/M
+Nadine/M
+Nadu/M
+Nadya/M
+Nagasaki/M
+Nagoya/M
+Nagpur/M
+Nagy/M
+Nahuatl/MS
+Nahum/M
+Naipaul/M
+Nair/M
+Nairobi/M
+Naismith/M
+Nam/M
+Namath/M
+Namibia/M
+Namibian/MS
+Nampa/M
+Nan/M
+Nana/M
+Nanak/M
+Nance/M
+Nanchang/M
+Nanci/M
+Nancy/M
+Nanette/M
+Nani/M
+Nanjing/M
+Nanni/M
+Nannie/M
+Nanon/M
+Nanook/M
+Nansen/M
+Nantes/M
+Nantucket/M
+Naomi/M
+Napa/M
+Naphtali/M
+Napier/M
+Naples/M
+Napoleon/MS
+Napoleonic/M
+Napster/M
+Nara
+Narcissus/M
+Nari/M
+Narmada/M
+Narnia/M
+Narraganset
+Narragansett/M
+Naruto/M
+Nash/M
+Nashua/M
+Nashville/M
+Nassau/M
+Nasser/M
+Nat/M
+Nata/M
+Natal's
+Natale/M
+Natalia/M
+Natalie/M
+Natalya/M
+Natasha/M
+Natchez/M
+Nate/MN
+Nathalie/M
+Nathan/SM
+Nathanael
+Nathanial/M
+Nathaniel/M
+Nathans/M
+Nation/M
+Nationwide/M
+Natividad/M
+Nativity/M
+Natty's
+Nature
+Naugahyde/M
+Nauru/M
+Nautilus/M
+Navajo/SM
+Navajoes
+Navarre/M
+Navarro/M
+Navratilova/M
+Navy
+Nazarene/M
+Nazareth/M
+Nazca/M
+Nazi/SM
+Nazism/MS
+Nb/M
+Nd/M
+Ndjamena/M
+Ne/M
+NeWS
+NeWSes
+Neal/M
+Neale/M
+Nealy/M
+Neanderthal/SM
+Neapolitan/M
+Neb
+Nebr
+Nebraska/M
+Nebraskan/MS
+Nebuchadnezzar/M
+Necko/M
+Ned/M
+Neda/M
+Nedda/M
+Neddy/M
+Nederland/SM
+Neel/M
+Neely/M
+Nefertiti/M
+Negev/M
+Negress/MS
+Negritude
+Negro/MS
+Negroes
+Negroid/SM
+Negros/M
+Nehemiah/M
+Nehru/M
+Neil/SM
+Neill/M
+Nelda/M
+Nell/M
+Nelle/M
+Nelli/M
+Nellie/M
+Nelly/M
+Nels/N
+Nelsen/M
+Nelson/M
+Nembutal/M
+Nemesis/M
+Neo/M
+Neogene/M
+Neolithic
+Nepal/M
+Nepalese/M
+Nepali/MS
+Neptune/M
+Nereid/M
+Nerf/M
+Nerissa/M
+Nero/M
+Neruda/M
+Nescafe/M
+Nessa/M
+Nesselrode/M
+Nessie/M
+Nesta/M
+Nester/M
+Nestle/M
+Nestor/M
+Nestorius/M
+NetBSD/M
+Netflix/M
+Netherlander/SM
+Netherlands/M
+Netscape/M
+Netta/M
+Nettie/M
+Netzahualcoyotl/M
+Nev/M
+Neva/M
+Nevada/M
+Nevadan/SM
+Nevadian
+Nevil/M
+Nevile/M
+Neville/M
+Nevin/MS
+Nevis/M
+Nevsky/M
+Newark/M
+Newburgh/M
+Newcastle/M
+Newfoundland/MRS
+Newman/M
+Newport/M
+Newsweek/M
+Newton/M
+Newtonian/M
+NexTag/M
+Nexis/M
+Nextel/M
+Ngaliema/M
+Nguyen/M
+Ni/M
+Niagara/M
+Nial/M
+Niall/M
+Niamey/M
+Nibelung/M
+Nicaea/M
+Nicaragua/M
+Nicaraguan/SM
+Niccolo/M
+Nice/M
+Nicene/M
+Nicephori/M
+Nichiren/M
+Nichol/SM
+Nicholas/M
+Nichole/M
+Nichols/M
+Nicholson/M
+Nick/M
+Nickelodeon/M
+Nicki/M
+Nickie/M
+Nicklaus/M
+Nicko/M
+Nickolas/M
+Nicky/M
+Nico/M
+Nicobar/M
+Nicodemus/M
+Nicol/M
+Nicola/SM
+Nicolai
+Nicolas/M
+Nicole/M
+Nicolette/M
+Nicolis
+Nicolle/M
+Nicosia/M
+Niebuhr/M
+Niel/SM
+Nielsen/M
+Nietzsche/M
+Nieves/M
+Nigel/M
+Niger/M
+Nigeria/M
+Nigerian/MS
+Nigeriana/M
+Nigerien/M
+Nightingale/M
+Nijinsky/M
+Nike/M
+Niki/M
+Nikita/M
+Nikkei/M
+Nikki/M
+Niko/SM
+Nikola/SM
+Nikolai/M
+Nikolaos/M
+Nikolaus/M
+Nikolayev/M
+Nikon/M
+Nile/SM
+Nils
+Nilson/M
+Nimitz/M
+Nimrod/M
+Nina/M
+Ninette/M
+Nineveh/M
+Ninon/M
+Nintendo/M
+Niobe/M
+Nippon/M
+Nipponese/M
+Nirenberg/M
+Nirvana/M
+Nisan/M
+Nisei/M
+Nissan/M
+Nita/M
+Niue/M
+Nivea/M
+Niven/M
+Nixon/M
+Nkrumah/M
+No/SM
+NoDoz/M
+Noah/M
+Noam/M
+Nobel/M
+Nobelist/MS
+Noble/M
+Noe/M
+Noel/SM
+Noelle/M
+Noemi/M
+Nokia/M
+Nola/M
+Nolan/M
+Noland/M
+Noll/M
+Nome/M
+Nomi/M
+Nona/M
+Noni/M
+Nonie/M
+Nonna/M
+Nootka/M
+Nora/M
+Norah/M
+Norbert/M
+Norberto/M
+Nordic/MS
+Noreen/M
+Norfolk/M
+Noriega/M
+Norma/M
+Normal/M
+Norman/MS
+Normand/M
+Normandy/M
+Norplant/M
+Norrie/M
+Norris/M
+Norse/M
+Norseman/M
+Norsemen/M
+Nortel/M
+North/M
+Northampton/M
+Northeast/MS
+Northern/MR
+Northerner/M
+Northrop/M
+Northrup/M
+Norths
+Northwest/SM
+Norton/M
+Norw
+Norway/M
+Norwegian/SM
+Norwich/M
+Nosferatu/M
+Nostradamus/M
+Notre
+Nottingham/M
+Nouakchott/M
+Noumea/M
+Nov/M
+Nova/M
+Novartis/M
+November/MS
+Novgorod/M
+Novocain/MS
+Novocaine
+Novokuznetsk/M
+Novosibirsk/M
+Nowell/M
+Noxzema/M
+Noyce/M
+Noyes/M
+Np/M
+Nubia/M
+Nubian/M
+Nukualofa/M
+Numbers/M
+Nunavut/M
+Nunez/M
+Nunki/M
+Nuremberg/M
+Nureyev/M
+NutraSweet/M
+NyQuil/M
+Nyasa/M
+Nye/M
+Nyerere/M
+Nyssa/M
+O'Brien/M
+O'Casey/M
+O'Connell/M
+O'Connor/M
+O'Donnell/M
+O'Hara/M
+O'Higgins/M
+O'Keeffe/M
+O'Neil/M
+O'Neill/M
+O'Rourke/M
+O'Toole/M
+O/SM
+OAS/M
+OB
+OCR
+OD/SM
+OE
+OED
+OH
+OHSA/M
+OJ
+OK/SMDG
+OMB/M
+OMG
+ON
+OPEC/M
+OR
+OS/M
+OSHA/M
+OSes
+OT
+OTB
+OTC
+OTOH
+Oahu/M
+Oakland/M
+Oakley/M
+Oates/M
+Oaxaca/M
+Ob/MD
+Obadiah/M
+Obama/M
+Obamacare
+Obed/M
+Oberlin/M
+Oberon/M
+Obie
+Ocala/M
+Ocaml/M
+Occam/M
+Occident
+Occidental/MS
+Oceania/M
+Oceanside
+Oceanus/M
+Ochoa/M
+Oct/M
+Octavia/M
+Octavian/M
+Octavio/M
+Octavius/M
+October/SM
+Odell/M
+Oder/M
+Odessa/M
+Odets/M
+Odette/M
+Odie/M
+Odin/M
+Odis/M
+Odo/M
+Odom/M
+Ody/M
+Odysseus/M
+Odyssey/M
+Oedipal/M
+Oedipus/M
+Oersted/M
+Ofelia/M
+Offenbach/M
+OfficeMax/M
+Ogbomosho/M
+Ogden/M
+Ogilvy/M
+Oglethorpe/M
+Ohio/M
+Ohioan/SM
+Oise/M
+Ojibwa/SM
+Okayama
+Okeechobee/M
+Okefenokee/M
+Okhotsk/M
+Okinawa/M
+Okinawan
+Okla
+Oklahoma/M
+Oklahoman/M
+Oktoberfest/M
+Ola/M
+Olaf/M
+Olajuwon/M
+Olav/M
+Oldenburg/M
+Oldfield/M
+Oldsmobile/M
+Olduvai/M
+Olen/M
+Olenek/M
+Olga/M
+Oligocene/M
+Olimpia/M
+Olin/M
+Olive/MR
+Oliver/M
+Olivetti/M
+Olivia/M
+Olivier/M
+Ollie/M
+Olly/M
+Olmec/M
+Olmsted/M
+Olsen/M
+Olson/M
+Olwen/M
+Olympe/M
+Olympia/SM
+Olympiad/MS
+Olympian/MS
+Olympic/SM
+Olympics/M
+Olympus/M
+Omaha/MS
+Oman/M
+Omani/MS
+Omar/M
+Omayyad/M
+Omdurman/M
+Omnipotent
+Omsk/M
+Onassis/M
+Oneal/M
+Onega/M
+Onegin/M
+Oneida/MS
+Onion/M
+Ono/M
+Onondaga/MS
+Onsager/M
+Ont
+Ontarian
+Ontario/M
+Oona/M
+Oort/M
+Opal/M
+Opaline/M
+Opel/M
+OpenBSD/M
+OpenOffice/M
+Ophelia/M
+Ophiuchus/M
+Oppenheimer/M
+Opposition
+Oprah/M
+Ora/M
+Oracle/M
+Oran/M
+Orange/M
+Oranjestad/M
+Orazio/M
+Orbison/M
+Ordovician/M
+Ore/N
+Oreg
+Oregon/M
+Oregonian/SM
+Orel
+Orem/M
+Oren/M
+Oreo/M
+Orestes/M
+Oriana/M
+Orient/M
+Oriental/MS
+Orientalism
+Orin/M
+Orinoco/M
+Orion/M
+Oriya/M
+Orizaba/M
+Orkney/M
+Orlan/M
+Orland/M
+Orlando/M
+Orleans/M
+Orlon/MS
+Orly/M
+Orpheus/M
+Orphic/M
+Orr/MN
+Orren/M
+Orrin/M
+Orson/M
+Ortega/M
+Orthodox
+Ortiz/M
+Orton/M
+Orv/M
+Orval/M
+Orville/M
+Orwell/M
+Orwellian/M
+Oryza/M
+Os/M
+Osage/MS
+Osaka/M
+Osbert/M
+Osborn/M
+Osborne/M
+Osbourne/M
+Oscar/MS
+Osceola/M
+Osgood/M
+Oshawa/M
+Oshkosh/M
+Osiris/M
+Oslo/M
+Osman/M
+Osmond/M
+Osmund/M
+Ossie/M
+Ostrogoth/M
+Ostwald/M
+Osvaldo/M
+Oswald/M
+Othello/M
+Otho/M
+Otis/M
+Ottawa/SM
+Ottilie/M
+Otto/M
+Ottoman/M
+Ottomana/M
+Ouagadougou/M
+Ouija/MS
+Ovid/M
+Owen/SM
+Owens/M
+Owensboro/M
+Oxford/SM
+Oxley/M
+Oxnard/M
+Oxonian/M
+Oxus/M
+Oxycontin/M
+Oz/M
+Ozark/MS
+Ozarks/M
+Ozymandias/M
+Ozzie/M
+Ozzy/M
+P/MN
+PA/M
+PAC/M
+PARC/S
+PASCAL
+PBS/M
+PBX
+PC/SM
+PCB
+PCMCIA
+PCP/M
+PD
+PDA/SM
+PDF/SM
+PDQ
+PDT
+PE
+PET/M
+PFC
+PG
+PGP
+PHP/M
+PIN
+PJ's
+PLO/M
+PM/SMDG
+PMS/M
+PNG/SM
+PO
+POTUS/M
+POW/M
+PP
+PPS
+PR
+PRC/M
+PRNewswire/M
+PRO
+PS/M
+PST/M
+PT
+PTA/M
+PTO
+PVC/M
+PW
+PX
+Pa/M
+Paar/M
+Pablo/M
+Pablum/M
+Pabst/M
+Pace/M
+Pacheco/M
+Pacific/M
+Pacino/M
+Packard/M
+Paco/M
+Padang
+Paderewski/M
+Padgett/M
+Padilla/M
+Padraic/M
+Padraig/M
+Paganini/M
+Page/M
+Paglia/M
+Pahlavi/M
+Paige/M
+Paine/M
+Paiute/SM
+Pakistan/M
+Pakistani/SM
+Palau/M
+Palembang/M
+Paleocene/M
+Paleogene/M
+Paleolithic/M
+Paleozoic/M
+Palermo/M
+Palestine/M
+Palestinian/SM
+Palestrina/M
+Paley/M
+Palikir/M
+Palin/M
+Palisades/M
+Palladio/M
+Palmdale/M
+Palmer/M
+Palmerston/M
+Palmolive/M
+Palmyra/M
+Paloma/M
+Palomar/M
+Pam/M
+Pamela/M
+Pamirs/M
+Pampers/M
+Pan/M
+Panama/SM
+Panamanian/MS
+Panasonic/M
+Pancho/M
+Pandora/M
+Pangaea/M
+Pankhurst/M
+Panmunjom/M
+Pansy/M
+Pantagruel/M
+Pantaloon/M
+Pantheon/M
+Panza/M
+Paola/M
+Paolina/M
+Paolo/M
+Papageno/M
+Papua/M
+Paracelsus/M
+Paraclete/M
+Paradise
+Paraguay/M
+Paraguayan/MS
+Paralympic/S
+Paramaribo/M
+Paramount/M
+Parana/M
+Paran叩/M
+Parcheesi/M
+Pareto/M
+Paris/M
+Parisian/MS
+Park/SMR
+Parke/M
+Parker/M
+Parkersburg/M
+Parkinson/M
+Parkinsonism
+Parkman/M
+Parks/M
+Parliament/M
+Parmenides
+Parmesan/MS
+Parnassus/MS
+Parnell/M
+Parr/M
+Parrish/M
+Parsee/SM
+Parsi/MS
+Parsifal/M
+Parsons/M
+Parthenon/M
+Parthia/M
+Pasadena/M
+Pascagoula/M
+Pascal/SM
+Pascale/M
+Pasco/M
+Pasquale/M
+Passion/SM
+Passover/MS
+Pasternak/M
+Pasteur/M
+Pat/MN
+Patagonia/M
+Patagonian/M
+Pate/M
+Patel/M
+Paten/M
+Paterson/M
+Patna/M
+Paton
+Patric/M
+Patrica/M
+Patrice/M
+Patricia/M
+Patricio/M
+Patrick/M
+Patrizia/M
+Patsy/M
+Patten/M
+Patterson/M
+Patti/M
+Pattie/M
+Patton/M
+Patty/M
+Paul/GM
+Paula/M
+Paule/M
+Paulette/M
+Pauli/M
+Paulie/M
+Paulina/M
+Pauline/M
+Pauling/M
+Paulo/M
+Pauly/M
+Pavarotti/M
+Pavel/M
+Pavia/M
+Pavlov/M
+Pavlova/M
+Pavlovian/M
+Pawnee/SM
+Paxton
+PayPal/M
+Payne/M
+Payton/M
+Pb/M
+Pd/M
+Peabody/M
+Peace/M
+Peadar/M
+Peale/M
+Pearce/M
+Pearl/M
+Pearle/M
+Pearlie/M
+Pearson/M
+Peary/M
+Pechora/M
+Peck/M
+Peckinpah/M
+Pecos/M
+Peder/M
+Pedro/M
+Peel/M
+Peg/M
+Pegasus/MS
+Pegeen/M
+Peggy/M
+Pei/M
+Peiping/M
+Peirce/M
+Pekinese/M
+Peking/SM
+Pekingese/SM
+Pele/M
+Pelee/M
+Peloponnese/M
+Pembroke/M
+Pen/M
+Pena/M
+Penderecki/M
+Penelope/M
+Penn/M
+Penna
+Penney/M
+Pennington/M
+Pennsylvania/M
+Pennsylvanian/MS
+Penny/M
+Pennzoil/M
+Penrod/M
+Pensacola/M
+Pentagon/M
+Pentateuch/M
+Pentax/M
+Pentecost/SM
+Pentecostal/MS
+Pentecostalism
+Pentium/SM
+Peoria/M
+Pepe/M
+Pepi/M
+Pepin/M
+Pepita/M
+Pepsi/M
+Pepys/M
+Pequot/M
+Perceval
+Percheron/M
+Percival/M
+Percy/M
+Perelman/M
+Perez/M
+Peri/M
+Periclean/M
+Pericles/M
+Perkin/MS
+Perkins/M
+Perl/SM
+Perla/M
+Perle/M
+Perm/M
+Permalloy/M
+Permian/M
+Pernod/M
+Peron/M
+Perot/M
+Perri/MR
+Perrier/M
+Perrine/M
+Perry/M
+Perseid/M
+Persephone/M
+Persepolis/M
+Perseus/M
+Pershing/M
+Persia/M
+Persian/SM
+Persis
+Perth/M
+Peru/M
+Peruvian/MS
+Peshawar/M
+Peta/M
+Petain/M
+Petaluma/M
+Pete/RMZ
+Peter/M
+Peterborough/M
+Peters/MN
+Petersen/M
+Peterson/M
+Petey/M
+Petr/M
+Petra/M
+Petrarch/M
+Petronella/M
+Petronilla/M
+Petty/M
+Peugeot/M
+Peyronie's
+Peyton/M
+Pfc
+Pfizer/M
+PhD/M
+Phaedra/M
+Phaethon/M
+Phanerozoic/M
+Pharaoh/M
+Pharaohs
+Pharisaic
+Pharisaical
+Pharisee/MS
+Phebe
+Phekda/M
+Phelps/M
+Phidias/M
+Phil/MY
+Philadelphia/M
+Philby/M
+Philemon/M
+Philip/MS
+Philippa/M
+Philippe/M
+Philippians/M
+Philippine/SM
+Philippines/M
+Philips/M
+Philistine/M
+Phillida/M
+Phillip/SM
+Phillipa/M
+Phillipe/M
+Phillips/M
+Phillis/M
+Philly/M
+Philomena/M
+Phineas/M
+Phipps/M
+Phobos/M
+Phoebe/M
+Phoenicia/M
+Phoenician/SM
+Phoenix/M
+Photoshop/M
+Photostat/MS
+Photostatted
+Photostatting
+Phrygia/M
+Phyllida/M
+Phyllis/M
+Pia/M
+Piaf/M
+Piaget/M
+Pianola/M
+Picasso/M
+Piccadilly/M
+Pickering/M
+Pickett/M
+Pickford/M
+Pickwick/M
+Pict/M
+Pictor
+Piedmont/M
+Pierce/M
+Pierre/M
+Pierrette/M
+Pierrot/M
+Pierson/M
+Pieter/M
+Pietra/M
+Pietro/M
+Pike/M
+Pilate/MS
+Pilates/M
+Pilcomayo/M
+Pilgrim/SM
+Pillsbury/M
+Pinatubo/M
+Pinchas/M
+Pincus/M
+Pindar/M
+Pinkerton/M
+Pinocchio/M
+Pinochet/M
+Pinter/M
+Pinyin
+Piotr/M
+Pippa/M
+Pippin/M
+Piraeus/M
+Pirandello/M
+Pisa/M
+Pisces/M
+Pisistratus/M
+Pissaro/M
+Pitcairn/M
+Pitt/SM
+Pittman/M
+Pitts/M
+Pittsburgh/M
+Pittsfield/M
+Pius/M
+Pixar/M
+Pizarro/M
+Pkwy
+Pl
+Place
+Planck/M
+Plano
+Plantagenet/M
+Plasticine/M
+Plataea/M
+Plath/M
+Plato/M
+Platonic
+Platonism/M
+Platonist/M
+Platte/M
+Plautus/M
+PlayStation/M
+Playboy/M
+Playtex/M
+Pleiades/M
+Pleistocene/M
+Plexiglas/MS
+Pliny/M
+Pliocene/SM
+Plutarch/M
+Pluto/M
+Plymouth/M
+Pm/M
+Po/M
+Pocahontas/M
+Pocatello/M
+Pocono/SM
+Poconos/M
+Podgorica/M
+Podhoretz/M
+Podunk/M
+Poe/M
+Pogo/M
+Poincare/M
+Poincar辿/M
+Poiret/M
+Poirot/M
+Poisson/M
+Poitier/M
+Pokemon/M
+Pok辿mon/M
+Pol/MY
+Poland/M
+Polanski/M
+Polaris/M
+Polaroid/MS
+Pole/SM
+Polish/M
+Politburo/M
+Polk/M
+Pollard/M
+Pollock/M
+Pollux/M
+Polly/M
+Pollyanna/M
+Polo/M
+Polska
+Poltava/M
+Polyhymnia/M
+Polynesia/M
+Polynesian/MS
+Polyphemus/M
+Pomerania/M
+Pomeranian/M
+Pomona/M
+Pompadour/M
+Pompeian
+Pompeii/M
+Pompey/M
+Ponce/M
+Pontchartrain/M
+Pontiac/M
+Pontianak/M
+Pooh/M
+Poole/M
+Poona/M
+Pope/M
+Popeye/M
+Popocatepetl/M
+Popper/M
+Poppins/M
+Popsicle/M
+Porfirio/M
+Porrima/M
+Porsche/M
+Port/MR
+Porter/M
+Porterville/M
+Portia/M
+Portland/M
+Porto/M
+Portsmouth/M
+Portugal/M
+Portuguese/M
+Poseidon/M
+Post/M
+PostScript/M
+PostgreSQL/M
+Potemkin/M
+Potomac/M
+Potsdam/M
+Pottawatomie/M
+Potter/M
+Potts/M
+Pottstown/M
+Poughkeepsie/M
+Poul/M
+Pound/M
+Poussin/M
+Powell/M
+PowerPC/M
+PowerPoint/M
+Powers/M
+Powhatan/M
+Poynter/M
+Poznan/M
+Pr/M
+Prada/M
+Prado/M
+Praetorian/M
+Praetoriana/M
+Prague/M
+Praia/M
+Prakrit/M
+Pratchett/M
+Pratt/M
+Pravda/M
+Praxiteles/M
+Preakness/M
+Precambrian/M
+Preminger/M
+Premyslid/M
+Prensa/M
+Prentice/M
+Prentiss/M
+Pres
+Presbyterian/SM
+Presbyterianism/MS
+Prescott/M
+Presley/M
+Preston/M
+Pretoria/M
+Priam/M
+Pribilof/M
+Price/M
+Priceline/M
+Priestley/M
+Prince/M
+Princeton/M
+Principe/M
+Prinz
+Pris
+Prisca/M
+Priscilla/M
+Prius/M
+Private
+Prix
+ProQuest/M
+Procrustean/M
+Procrustes/M
+Procter/M
+Procyon/M
+Prof
+Prohibition
+Prokofiev/M
+Promethean/M
+Prometheus/M
+Prophets
+Proserpina/M
+Proserpine/M
+Protagoras/M
+Proterozoic/M
+Protestant/MS
+Protestantism/SM
+Proteus/M
+Proudhon/M
+Proust/M
+Provencal/MS
+Provence/M
+Proven巽al/M
+Proverbs
+Providence/SM
+Provo/M
+Prozac/MS
+Pru/M
+Prudence/M
+Prudential/M
+Prudy/M
+Prue/M
+Pruitt/M
+Prussia/M
+Prussian/MS
+Prut/M
+Pryce/M
+Pryor/M
+Psalms/M
+Psalter/MS
+Pseudomonas/M
+Psyche/M
+Pt/M
+Ptah/M
+Ptolemaic/M
+Ptolemy/SM
+Pu/M
+PubMed/M
+Puccini/M
+Puck/M
+Puckett/M
+Puebla/M
+Pueblo/M
+Puerto
+Puget/M
+Pugh/M
+Pulaski/M
+Pulitzer/M
+Pullman/MS
+Punch/M
+Punic/M
+Punjab/M
+Punjabi/M
+Purana/M
+Purcell/M
+Purdue/M
+Purgatory
+Purim/MS
+Purina/M
+Puritan/M
+Puritanism/MS
+Purus/M
+Pusan/M
+Pusey/M
+Pushkin/M
+Pushtu/M
+Putin/M
+Putnam/M
+Puzo/M
+Pvt
+PyTorch/M
+Pygmalion/M
+Pygmy/SM
+Pyle/M
+Pym/M
+Pynchon/M
+Pyongyang/M
+Pyotr/M
+Pyrenees/M
+Pyrex/MS
+Pyrrhic/M
+Pythagoras/M
+Pythagorean/M
+Pythias/M
+Python/M
+P辿tain/M
+P担rto/M
+Q
+QA
+QB
+QC
+QED
+QM
+QWERTY
+Qaddafi/M
+Qaeda/M
+Qantas/M
+Qatar/M
+Qatari/MS
+Qingdao/M
+Qinghai/M
+Qiqihar/M
+Qom/M
+Quaalude/M
+Quaker/MS
+Quakerism/SM
+Qualcomm/M
+Quaoar/M
+Quasimodo/M
+Quaternary/M
+Quayle/M
+Que
+Quebec/M
+Quebecker
+Quebecois/M
+Quechua/M
+Queen/MS
+Queenie/M
+Queens/M
+Queensland/M
+Quent/M
+Quentin/M
+Quetzalcoatl/M
+Quezon/M
+QuickList/M
+QuickTime/M
+Quillan/M
+Quincey/M
+Quincy/M
+Quinlan/M
+Quinn/M
+Quint/M
+Quinta/M
+Quintana/M
+Quintilian/M
+Quintin/M
+Quinton/M
+Quintus/M
+Quirinal/M
+Quisling/M
+Quito/M
+Quixote/M
+Quixotism/M
+Qumran/M
+Quonset/M
+Qur'an/MS
+Qur'anic
+Quran
+Quranic
+Qu辿becois/M
+Qwest/M
+R/MD
+RAF/M
+RAM/SM
+RBI
+RC
+RCA/M
+RCMP
+RD
+RDA
+RDS/M
+REIT
+REM/SM
+RF
+RFC/S
+RFD
+RI
+RIF
+RIP
+RISC
+RN/M
+RNA/M
+ROFL
+ROM/M
+ROTC/M
+RP
+RR
+RSFSR
+RSI
+RSV
+RSVP
+RTFM
+RV/SM
+Ra/M
+Rab/M
+Rabat/M
+Rabelais/M
+Rabelaisian/M
+Rabi
+Rabin/M
+Rachael/M
+Rachel/M
+Rachelle/M
+Rachmaninoff/M
+Racine/M
+Radcliff/M
+Radcliffe/M
+Rae/M
+Raf/M
+Rafa/M
+Rafael/M
+Rafe/M
+Raff/M
+Raffaello/M
+Rafferty/M
+Raffles/M
+Rafi/M
+Ragnar/M
+Ragnarok/M
+Ragnar旦k/M
+Rahel/M
+Raimondo/M
+Raimund/M
+Raimundo/M
+Raina/M
+Raine/MR
+Rainer/M
+Rainier/M
+Raleigh/M
+Ralf/M
+Ralph/M
+Rama/M
+Ramada/M
+Ramadan/MS
+Ramakrishna/M
+Ramanujan/M
+Ramayana/M
+Rambo/M
+Ramirez/M
+Ramiro/M
+Ramon/M
+Ramona/M
+Ramos/M
+Ramsay/M
+Ramses/M
+Ramsey/M
+Rana/M
+Rance/M
+Rand/M
+Randa/M
+Randal/M
+Randall/M
+Randell/M
+Randi/M
+Randolph/M
+Randy/M
+Rangoon/M
+Rani/M
+Rankin/M
+Rankine/M
+Raoul/M
+Raphael/M
+Rappaport/M
+Rapunzel/M
+Raquel/M
+Rasalgethi/M
+Rasalhague/M
+Rasmussen/M
+Rasputin/M
+Rasta
+Rastaban/M
+Rastafarian/MS
+Rastafarianism
+Rather/M
+Ratliff/M
+Raul/M
+Ravel/M
+Ravi/M
+Ravid/M
+Raviv/M
+Rawalpindi/M
+Rawley/M
+Ray/M
+RayBan/M
+Rayburn/M
+Raye/M
+Rayleigh/M
+Raymond/M
+Raymund/M
+Raymundo/M
+Rayna/M
+Rayner/M
+Raynor/M
+Rb/M
+Rd
+Re/M
+Rea/M
+Reade/G
+Reading/M
+Reagan/M
+Reaganomics/M
+Realtor/M
+Reasoner/M
+Reba/M
+Rebeca/M
+Rebecca/M
+Rebecka/M
+Rebekah/M
+Recife/M
+Reconstruction/M
+Red/SM
+Redd/GM
+Redding/M
+Redeemer/M
+Redford/M
+Redgrave/M
+Redis/M
+Redmond/M
+Redshift/M
+Ree/DSM
+Reebok/M
+Reece/M
+Reed/M
+Reena/M
+Reese/M
+Reeves/M
+Reformation/MS
+Refugio/M
+Regan/M
+Regen/M
+Reggie/M
+Regina/M
+Reginae/M
+Reginald/M
+Regine/M
+Regor/M
+Regulus/M
+Rehnquist/M
+Reich/M
+Reichstag's
+Reid/M
+Reiko/M
+Reilly/M
+Reina/M
+Reinaldo/M
+Reine/M
+Reinhard/M
+Reinhardt/M
+Reinhold/M
+Remanence
+Remanent
+Remarque/M
+Rembrandt/M
+Remington/M
+Remus/M
+Remy/M
+Rena/M
+Renae/M
+Renaissance/SM
+Renaldo/M
+Renard/M
+Renascence
+Renata/M
+Renate/M
+Renato/M
+Renaud/M
+Renault/M
+Rene/M
+Renee/M
+Renie/M
+Rennie/M
+Reno/M
+Renoir/M
+Rep
+Representative
+Republican/SM
+Republicanism
+Requiem/MS
+Resistance
+Restoration/M
+Resurrection
+Reta/M
+Reuben/M
+Reunion/M
+Reuters/M
+Reuther/M
+Reuven/M
+Rev
+Reva/M
+Revelation/SM
+Revelations/M
+Revere/M
+Reverend/M
+Revlon/M
+Rex/M
+Rey/M
+Reyes/M
+Reykjavik/M
+Reyna/M
+Reynaldo/M
+Reynard/M
+Reynold/MS
+Reynolds/M
+Rf/M
+Rh/M
+Rhea/M
+Rhee/M
+Rheingau/M
+Rhenish/M
+Rhett/M
+Rhianna/M
+Rhiannon/M
+Rhine/M
+Rhineland/M
+Rhoda/M
+Rhode/S
+Rhodes/M
+Rhodesia/M
+Rhodesian
+Rhona/M
+Rhonda/M
+Rhone/M
+Rhys/M
+Ribbentrop/M
+Ric/M
+Rica/M
+Ricard/M
+Ricardo/M
+Riccardo/M
+Rice/M
+Rich/M
+Richard/MS
+Richards/M
+Richardson/M
+Richart/M
+Richelieu/M
+Richie/M
+Richmond/M
+Richter/M
+Richthofen/M
+Rick/M
+Rickard/M
+Rickenbacker/M
+Rickert/M
+Rickey/M
+Ricki/M
+Rickie/M
+Rickover/M
+Ricky/M
+Rico/M
+Riddle/M
+Ride/M
+Riefenstahl/M
+Riel/M
+Riemann/M
+Riesling/MS
+Riga/M
+Rigel/M
+Riggs/M
+Right
+Rigoberto/M
+Rigoletto/M
+Rik/M
+Riki/M
+Rikki/M
+Riley/M
+Rilke/M
+Rimbaud/M
+Rina/M
+Rinaldo/M
+Ringling/M
+Ringo/M
+Rio/SM
+Riordan/M
+Rios/M
+Ripley/M
+Risa/M
+Risorgimento/M
+Rita/M
+Ritalin/M
+Ritchie/M
+Ritz/M
+Riva/SM
+Rivas/M
+Rivera/M
+Rivers/M
+Riverside/M
+Riviera/MS
+Riyadh/M
+Rizal/M
+Rn/M
+Roach/M
+Roanoke/M
+Roarke/M
+Rob/M
+Robb/M
+Robbie/M
+Robbin/MS
+Robbins/M
+Robby/M
+Roberson/M
+Robert/MS
+Roberta/M
+Roberto/M
+Roberts/M
+Robertson/M
+Robeson/M
+Robespierre/M
+Robin/M
+Robina/M
+Robinet/M
+Robinette/M
+Robinia/M
+Robinson/M
+Robitussin/M
+Robles/M
+Robson/M
+Robt/M
+Roby/M
+Robyn/M
+Rocco/M
+Roch/M
+Rocha/M
+Rochambeau/M
+Roche/M
+Rochelle/M
+Rochester/M
+Rock/M
+Rockefeller/M
+Rockford/M
+Rockies/M
+Rockne/M
+Rockwell/M
+Rocky/SM
+Rod/M
+Roda/M
+Rodd/M
+Roddenberry/M
+Roddy/M
+Roderic/M
+Roderick/M
+Roderigo/M
+Rodger/MS
+Rodgers/M
+Rodham/M
+Rodi/M
+Rodin/M
+Rodney/M
+Rodolfo/M
+Rodolph/M
+Rodolphe/M
+Rodrick/M
+Rodrigo/M
+Rodriguez/M
+Rodriquez/M
+Roeg/M
+Roentgen
+Rog/MRZ
+Rogelio/M
+Roger/M
+Rogers/M
+Roget/M
+Roi/SM
+Rojas/M
+Roku/M
+Rolaids/M
+Roland/M
+Rolando/M
+Roldan/M
+Rolex/M
+Rolf
+Rolfe/M
+Rolland/M
+Rollerblade/M
+Rollie/M
+Rollin/MS
+Rollins/M
+Rollo
+Rolodex/M
+Rolph/M
+Rolvaag/M
+Rom
+Roma/M
+Romain/M
+Roman/MS
+Romana/M
+Romanesque/MS
+Romania/M
+Romanian/MS
+Romano/M
+Romanov/M
+Romans/M
+Romansh/M
+Romantic
+Romanticism
+Romany/SM
+Rome/SM
+Romeo/M
+Romero/M
+Rommel/M
+Romney/M
+Romola/M
+Romulus/M
+Romy/M
+Ron/M
+Rona/M
+Ronald/M
+Ronda/M
+Ronni/M
+Ronnie/M
+Ronny/M
+Ronstadt/M
+Rontgen
+Rooney/M
+Roosevelt/M
+Root/M
+Roquefort/SM
+Rorke/M
+Rorschach/M
+Rory/M
+Ros
+Rosa/M
+Rosaleen/M
+Rosales/M
+Rosalia/M
+Rosalie/M
+Rosalind/M
+Rosalinda/M
+Rosaline/M
+Rosalyn/M
+Rosamond/M
+Rosamund/M
+Rosanna/M
+Rosanne/M
+Rosario/M
+Rosco/M
+Roscoe/M
+Rose/M
+Roseann/M
+Roseanne/M
+Roseau/M
+Rosecrans/M
+Rosella/M
+Roselle/M
+Rosemarie/M
+Rosemary/M
+Rosenberg/M
+Rosendo/M
+Rosenzweig/M
+Rosetta/M
+Rosicrucian/M
+Rosie/M
+Rosina/M
+Rosita/M
+Roslyn/M
+Ross/M
+Rossetti/M
+Rossie/M
+Rossini/M
+Rostand/M
+Rostov/M
+Rostropovich/M
+Roswell/M
+Rosy's
+Rotarian/M
+Roth/M
+Rothko/M
+Rothschild/M
+Rotterdam/M
+Rottweiler/M
+Rouault/M
+Rourke/M
+Rousseau/M
+Routledge/M
+Rove/RM
+Rover/M
+Rowan/M
+Rowe/M
+Rowen/M
+Rowena/M
+Rowland/M
+Rowling/M
+Roxana/M
+Roxane/M
+Roxanna/M
+Roxanne/M
+Roxie/M
+Roxy/M
+Roy/M
+Royal/M
+Royall/M
+Royce/M
+Roz/M
+Rozelle/M
+Rte
+Ru/MH
+Rubaiyat/M
+Rubbermaid/M
+Ruben/SM
+Rubens/M
+Rubi/M
+Rubia/M
+Rubicon/MS
+Rubik/M
+Rubin/M
+Rubinstein/M
+Ruby/M
+Ruchbah/M
+Rudd/M
+Ruddy's
+Rudiger/M
+Rudolf/M
+Rudolfo/M
+Rudolph/M
+Rudy/M
+Rudyard/M
+Rufe/M
+Rufus/M
+Rugby
+Ruggiero/M
+Ruhr/M
+Ruiz/M
+Rukeyser/M
+Rumanian/SM
+Rumpelstiltskin/M
+Rumsfeld/M
+Runnymede/M
+Runyon/M
+Rupert/M
+Ruprecht/M
+Rurik
+Rush/M
+Rushdie/M
+Rushmore/M
+Ruskin/M
+Russ/M
+Russel/M
+Russell/M
+Russia/M
+Russian/SM
+Russo/M
+Rustbelt/M
+Rustin/M
+Rusty/M
+Rutan/M
+Rutger/MS
+Rutgers/M
+Ruth/M
+Rutherford/M
+Ruthie/M
+Rutledge/M
+Rutter/M
+Ruy/M
+Rwanda/MS
+Rwandan/SM
+Rwy
+Rx
+Ry
+Ryan/M
+Rydberg/M
+Ryder/M
+Ryukyu/M
+S/MN
+SA
+SAC
+SALT/M
+SAM/M
+SAP/M
+SARS/M
+SASE
+SAT
+SBA
+SC/M
+SCOTUS/M
+SCSI/M
+SD
+SDI
+SE/M
+SEATO
+SEC/M
+SF
+SGML/M
+SIDS/M
+SJ
+SJW
+SK
+SLR
+SME/SM
+SMEs/M
+SNP/SM
+SO/S
+SOB/M
+SOP/M
+SOS/M
+SOSes
+SPCA
+SPF
+SQL
+SQLite/M
+SRO
+SS
+SSA
+SSE/M
+SSN
+SSS
+SST
+SSW/M
+ST
+STD
+STOL
+SUSE/M
+SUV
+SVN/M
+SW/M
+SWAK
+SWAT
+Saab/M
+Saar/M
+Saarinen/M
+Saatchi/M
+Saba/M
+Sabbath/M
+Sabbaths
+Sabik/M
+Sabin/M
+Sabina/M
+Sabine/M
+Sabre/M
+Sabrina/M
+Sacajawea/M
+Saccharomyces/M
+Sacco/M
+Sacha/M
+Sachs/M
+Sacramento/M
+Sada/M
+Sadat/M
+Saddam/M
+Sadducee/M
+Sade/M
+Sadie/M
+Sadr/M
+Safavid/M
+Safeway/M
+Sagan/M
+Saginaw/M
+Sagittarius/MS
+Sahara/M
+Saharan/M
+Sahel/M
+Saigon/M
+Saiph/M
+Sakai/M
+Sakha/M
+Sakhalin/M
+Sakharov/M
+Saki/M
+Saks/M
+Sal/MY
+Saladin/M
+Salado/M
+Salamis/M
+Salas/M
+Salazar/M
+Saleem/M
+Salem/M
+Salerno/M
+Salesforce/M
+Salim/M
+Salinas/M
+Salinger/M
+Salisbury/M
+Salish/M
+Salk/M
+Sallee/M
+Sallie/M
+Sallust/M
+Sally/M
+Salome/M
+Salomon/M
+Salonika/M
+Salton/M
+Salvador/M
+Salvadoran/SM
+Salvadorean/MS
+Salvadorian/MS
+Salvatore/M
+Salween/M
+Salyut/M
+Sam/M
+Samantha/M
+Samar/M
+Samara/M
+Samaria
+Samaritan/MS
+Samarkand/M
+Sammie/M
+Sammy/M
+Samoa/M
+Samoan/SM
+Samoset/M
+Samoyed/M
+Sampson/M
+Samson/M
+Samsonite/M
+Samsung/M
+Samuel/M
+Samuelson/M
+San'a
+San/M
+Sana/M
+Sanaa/M
+Sanchez/M
+Sancho/M
+Sand/ZM
+Sandburg/M
+Sande/M
+Sanders/M
+Sanderson/M
+Sandi/M
+Sandie/M
+Sandinista/M
+Sandor/M
+Sandoval/M
+Sandra/M
+Sandro/M
+Sandy/M
+Sanford/M
+Sanforized/M
+Sang/MR
+Sanger/M
+Sanhedrin/M
+Sanka/M
+Sankara/M
+Sanskrit/M
+Sanson/M
+Sansone/M
+Santa/M
+Santana/M
+Santayana/M
+Santeria/M
+Santiago/M
+Santos/M
+Sapphira
+Sappho/M
+Sapporo/M
+Sara/M
+Saracen/MS
+Saragossa/M
+Sarah/M
+Sarajevo/M
+Saran/M
+Sarasota/M
+Saratov/M
+Sarawak/M
+Sarbanes/M
+Sardinia/M
+Sardinian/M
+Saree/M
+Sargasso/M
+Sarge/M
+Sargent/M
+Sargon/M
+Sarina/M
+Sarita/M
+Sarnoff/M
+Saroyan/M
+Sarto/M
+Sartre/M
+Sascha/M
+Sasha/M
+Sask
+Saskatchewan/M
+Saskatoon/M
+Sasquatch/MS
+Sassanian/M
+Sassoon/M
+Sat/M
+Satan/M
+Satanism/M
+Satanist/M
+Saturday/MS
+Saturn/M
+Saturnalia/M
+Saudi/MS
+Saul/M
+Saunders/M
+Saunderson/M
+Saundra/M
+Saussure/M
+Sauternes
+Sauveur/M
+Savage/M
+Savannah/M
+Savina/M
+Savior/M
+Savonarola/M
+Savoy/M
+Savoyard/M
+Sawyer/M
+Saxe/M
+Saxon/MS
+Saxony/M
+Sayer/MS
+Sayers/M
+Sayre/M
+Sb/M
+Sc/M
+Scala/M
+Scan
+Scandinavia/M
+Scandinavian/MS
+Scaramouch/M
+Scarborough/M
+Scarface/M
+Scarlatti/M
+Scarlett/M
+Scheat/M
+Schedar/M
+Scheherazade/M
+Schelling/M
+Schenectady/M
+Schiaparelli/M
+Schick/M
+Schiller/M
+Schindler/M
+Schlesinger/M
+Schliemann/M
+Schlitz/M
+Schloss/M
+Schmidt/M
+Schnabel/M
+Schnauzer/M
+Schneider/M
+Schoenberg/M
+Schopenhauer/M
+Schrieffer/M
+Schrodinger/M
+Schroeder/M
+Schr旦dinger/M
+Schubert/M
+Schultz/M
+Schulz/M
+Schumann/M
+Schumpeter/M
+Schuyler/M
+Schuylkill/M
+Schwartz/M
+Schwarz/M
+Schwarzenegger/M
+Schwarzkopf/M
+Schweitzer/M
+Schweppes/M
+Schwinger/M
+Schwinn/M
+Scientologist/SM
+Scientology/M
+Scipio/M
+Scopes/M
+Scorpio/SM
+Scorpius/M
+Scorsese/M
+Scot/SM
+Scotch/MS
+Scotchman/M
+Scotchmen/M
+Scotchwoman/M
+Scotchwomen/M
+Scotia/M
+Scotland/M
+Scotsman/M
+Scotsmen/M
+Scotswoman/M
+Scotswomen/M
+Scott/M
+Scotti/M
+Scottie/SM
+Scottish/M
+Scottsdale/M
+Scrabble/MS
+Scranton/M
+Scriabin/M
+Scribner/M
+Scripture/SM
+Scrooge/M
+Scruggs/M
+Scud/M
+Sculley/M
+Scunthorpe/M
+Scylla/M
+Scythia/M
+Scythian/M
+Se/MHN
+SeaMonkey/M
+Seaborg/M
+Seagram/M
+Seamus/M
+Sean/M
+Sears/M
+Seaside/M
+Seattle/M
+Sebastian/M
+Sebastiano/M
+Sebastien/M
+Sebring/M
+Sec
+Seconal/M
+Secretariat/M
+Secretary
+Seder/MS
+Sedna/M
+Seebeck/M
+Seeger/M
+Sega/M
+Segovia/M
+Segre/M
+Segundo/M
+Segway/S
+Seiko/M
+Seine/M
+Seinfeld/M
+Sejong/M
+Sela/M
+Selassie/M
+Selby/M
+Selectric/M
+Selena/M
+Selene/M
+Seleucid/M
+Seleucus/M
+Selig/M
+Selim/M
+Selina/M
+Seljuk/M
+Selkirk/M
+Sella/M
+Selle/MZ
+Sellers/M
+Selma/M
+Selznick/M
+Semarang/M
+Seminole/MS
+Semiramis/M
+Semite/MS
+Semitic/SM
+Semtex/M
+Sena/M
+Senate/MS
+Sendai/M
+Seneca/MS
+Senegal/M
+Senegalese/M
+Senghor/M
+Senior/M
+Sennacherib/M
+Sennett/M
+Sensurround/M
+Seoul/M
+Sep
+Sephardi/M
+Sepoy/M
+Sept/M
+September/MS
+Septuagint/MS
+Sequoya/M
+Serb/SM
+Serbia/M
+Serbian/MS
+Serena/M
+Serengeti/M
+Sergei/M
+Sergent/M
+Sergio/M
+Serpens/M
+Serra/M
+Serrano/M
+Set/M
+Seth/M
+Seton/M
+Seurat/M
+Seuss/M
+Sevastopol/M
+Severn/M
+Severus/M
+Seville/M
+Sevres/M
+Seward/M
+Sextans/M
+Sexton/M
+Seychelles/M
+Seyfert/M
+Seymour/M
+Sgt
+Shaanxi/M
+Shackleton/M
+Shaffer/M
+Shah/M
+Shaka/M
+Shaker
+Shakespeare/M
+Shakespearean/M
+Shalom's
+Shamus/M
+Shana/M
+Shandong/M
+Shandy/M
+Shane/M
+Shanghai/M
+Shani/M
+Shankara/M
+Shanna/M
+Shannon/M
+Shanta/M
+Shantung/M
+Shanxi/M
+Shapiro/M
+Shara/M
+SharePoint/M
+Shari'a/M
+Shari/M
+Sharif/M
+Sharlene/M
+Sharma/M
+Sharon/M
+Sharp/M
+Sharpe/M
+Sharron/M
+Shasta/M
+Shaula/M
+Shaun/M
+Shauna/M
+Shavian/M
+Shavuot/M
+Shaw/M
+Shawn/M
+Shawna/M
+Shawnee/SM
+Shayla/M
+Shayna/M
+Shayne/M
+Shcharansky/M
+Shea/M
+Sheba/M
+Shebeli/M
+Sheboygan/M
+Sheela/M
+Sheena/M
+Sheetrock/M
+Sheffield/M
+Sheila/M
+Sheilah/M
+Shel/MY
+Shelagh/M
+Shelby/M
+Sheldon/M
+Shelia/M
+Shell/M
+Shelley/M
+Shelly/M
+Shelton/M
+Shem/M
+Shen/M
+Shenandoah/M
+Shenyang/M
+Shenzhen/M
+Sheol/M
+Shep/M
+Shepard/M
+Shepherd/M
+Sheppard/M
+Sher/M
+Sheratan/M
+Sheraton/M
+Sheree/M
+Sheri/M
+Sheridan/M
+Sherlock/M
+Sherm/M
+Sherman/M
+Sherpa/M
+Sherri/M
+Sherrie/M
+Sherry/M
+Sherwin/M
+Sherwood/M
+Sheryl/M
+Shetland/SM
+Shetlands/M
+Shevardnadze/M
+Shevat/M
+Shi'ite/M
+Shields/M
+Shiite/MS
+Shijiazhuang/M
+Shikoku/M
+Shillong/M
+Shiloh/M
+Shina/M
+Shinto/MS
+Shintoism/MS
+Shintoist/MS
+Shir/M
+Shiraz/M
+Shirl/M
+Shirley/M
+Shiva/M
+Shockley/M
+Sholom/M
+Short/M
+Shorthorn/M
+Shoshana/M
+Shoshone/SM
+Shostakovitch/M
+Shrek/M
+Shreveport/M
+Shriner/M
+Shropshire/M
+Shula/M
+Shylock/M
+Shylockian/M
+Si/M
+Siam/M
+Siamese/M
+Sian/M
+Sib/M
+Sibelius/M
+Siberia/M
+Siberian/MS
+Sibley/M
+Sibyl/M
+Sibylla/M
+Sibylle/M
+Sichuan/M
+Sicilian/SM
+Sicily/M
+Sid/M
+Siddhartha/M
+Sidney/M
+Sidonia/M
+Siegfried/M
+Siemens/M
+Sierpinski/M
+Sierras
+Sig
+Sigismondo/M
+Sigismund/M
+Sigmund/M
+Sigrid/M
+Sigurd/M
+Sihanouk/M
+Sikh/M
+Sikhism
+Sikhs
+Sikkim/M
+Sikkimese/M
+Sikorsky/M
+Silas/M
+Silesia/M
+Silurian/SM
+Silva/M
+Silvan/M
+Silvana/M
+Silvano/M
+Silvanus/M
+Silvester/M
+Silvia/M
+Silvie/M
+Silvio/M
+Sim's
+Simenon/M
+Simeon/M
+Simmental/M
+Simmonds/M
+Simmons/M
+Simon/M
+Simona/M
+Simone/M
+Simpson/SM
+Simpsons/M
+Simpsonville/M
+Sims/M
+Sinai/M
+Sinatra/M
+Sinbad/M
+Sinclair/M
+Sindbad/M
+Sindhi/M
+Singapore/M
+Singaporean/SM
+Singer/M
+Singh/M
+Singleton/M
+Sinhalese/M
+Sinica/M
+Sinkiang/M
+Siobhan/M
+Sioux/M
+Sir/SM
+Sirius/M
+Sissie/M
+Sister/MS
+Sistine/M
+Sisyphean/M
+Sisyphus/M
+Siva/M
+Sivan/M
+Siward/M
+Sjaelland/M
+Skelly/M
+Skinner/M
+Skippy/M
+Skipton/M
+Skopje/M
+Skye/M
+Skylab/M
+Skylar/M
+Skyler/M
+Skype/M
+Slackware/M
+Slade/M
+Slashdot/M
+Slater/M
+Slav/SM
+Slavic/M
+Slavonic/M
+Slidell/M
+Slinky/M
+Sloan/M
+Sloane/M
+Slocum/M
+Slovak/SM
+Slovakia/M
+Slovakian
+Slovene/SM
+Slovenia/M
+Slovenian/MS
+Slurpee/M
+Sly's
+Sm/M
+Small/M
+Smetana/M
+Smirnoff/M
+Smith/M
+Smithson/M
+Smithsonian/M
+Smitty/M
+Smokey/M
+Smolensk/M
+Smollett/M
+Smuts/M
+Smyrna
+Sn/M
+Snake/M
+Snapple/M
+Snead/M
+Snell/M
+Snickers/M
+Snider/M
+Snoopy/M
+Snow/M
+Snowbelt/M
+Snyder/M
+Soave/M
+Soc
+Socastee/M
+Socorro/M
+Socrates/M
+Socratic/M
+Soddy/M
+Sodom/M
+Sofia/M
+Sofie/M
+Soho/M
+Sol/MY
+Solaris/M
+Solis/M
+Solly/M
+Solomon/M
+Solon/M
+Solzhenitsyn/M
+Somali/SM
+Somalia/M
+Somalian/MS
+Somerset
+Somme/M
+Somoza/M
+Son/M
+Sondheim/M
+Sondra/M
+Songhai/M
+Songhua/M
+Sonia/M
+Sonja/M
+Sonny/M
+Sonora/M
+Sontag/M
+Sony/M
+Sonya/M
+Sophi/M
+Sophia/M
+Sophie/M
+Sophoclean/M
+Sophocles/M
+Sophronia/M
+Sopwith/M
+Sorbonne/M
+Sorcha/M
+Sosa/M
+Soto/M
+Souphanouvong/M
+Sourceforge/M
+Sousa/M
+South/M
+Southampton/M
+Southeast/MS
+Southern/ZR
+Southerner/M
+Southey/M
+Souths
+Southwest/MS
+Soviet/M
+Sovietica/M
+Soweto/M
+Soyinka/M
+Soyuz/M
+Sp
+Spaatz/M
+Spackle/M
+Spahn/M
+Spain/M
+Spam/M
+Span
+Spanglish
+Spaniard/SM
+Spanish/M
+Sparc
+Sparks/M
+Sparta/M
+Spartacus/M
+Spartan/MS
+Spartanburg/M
+Spears/M
+Speer/M
+Spence/RM
+Spencer/M
+Spencerian/M
+Spengler/M
+Spenglerian/M
+Spenser/M
+Spenserian/M
+Sperry/M
+Sphinx/M
+Spica/M
+SpiderMonkey/M
+Spielberg/M
+Spillane/M
+Spinoza/M
+Spinx/M
+Spiro/M
+Spirograph/M
+Spitsbergen/M
+Spitz/M
+Spock/M
+Spokane/M
+Springdale/M
+Springfield/M
+Springsteen/M
+Sprint/M
+Sprite/M
+Sputnik/M
+Sq
+Squanto/M
+Squibb/M
+Sr/M
+Srinagar/M
+Srivijaya/M
+St
+Sta
+Stace/M
+Stacey/M
+Staci/M
+Stacie/M
+Stacy/M
+Stael/M
+Stafford/M
+StairMaster/M
+Stalin/M
+Stalingrad/M
+Stalinist/M
+Stallone/M
+Stamford/M
+Stan/MY
+Standford/M
+Standish/M
+Stanfield/M
+Stanford/M
+Stanislas/M
+Stanislaus/M
+Stanislavsky/M
+Stanislaw/M
+Stanley/M
+Stanly/M
+Stanton/M
+Stanwood/M
+Staples/M
+Starbucks/M
+Stark/M
+Starkey/M
+Starr/M
+Statehouse/MS
+Staten/M
+States
+Stateside
+Staubach/M
+Staunton/M
+Stavros
+Ste
+Steadicam/M
+Stearn/M
+Steele/M
+Stefan/M
+Stefania/M
+Stefanie/M
+Stefano/M
+Steffen/M
+Steffi/M
+Stein/MR
+Steinbeck/M
+Steinem/M
+Steiner/M
+Steinmetz/M
+Steinway/M
+Stella/M
+Stendhal/M
+Stengel/M
+Stephan/M
+Stephani/M
+Stephanie/M
+Stephanus/M
+Stephen/MS
+Stephens/M
+Stephenson/M
+Sterling/M
+Stern/M
+Sterne/M
+Sterno/M
+Stetson/M
+Steuben/M
+Steubenville/M
+Steve/M
+Steven/MS
+Stevens/M
+Stevenson/M
+Stevie/M
+Stewart/M
+Stieglitz/M
+Stillman/M
+Stilton/SM
+Stimson/M
+Stine/M
+Stinky's
+Stirling/M
+Stockhausen/M
+Stockholm/M
+Stockton/M
+Stoddard/M
+Stoic/SM
+Stoicism/MS
+Stokes/M
+Stolichnaya/M
+Stolypin/M
+Stone/M
+Stonehenge/M
+Stoppard/M
+Stormy's
+Stout/M
+Stowe/M
+Strabo/M
+Stradivari
+Stradivarius/M
+Strasbourg/M
+Strauss/M
+Stravinsky/M
+Streisand/M
+Strickland/M
+Strindberg/M
+Stromboli/M
+Strong/M
+Stu/M
+Stuart/MS
+Studebaker/M
+StumbleUpon/M
+Stuttgart/M
+Stuyvesant/M
+Stygian/M
+Styrofoam/SM
+Styron/M
+Styx/M
+Suarez/M
+Subaru/M
+Sucre/M
+Sucrets/M
+Sudan/M
+Sudanese/M
+Sudetenland/M
+Sudoku/M
+Sudra/M
+Sue/M
+Suetonius/M
+Suez/M
+Suffolk/M
+Sufi/M
+Sufism/M
+Suharto/M
+Sui/M
+Sukarno/M
+Sukey/M
+Suki/M
+Sukkot
+Sukkoth/M
+Sukkoths
+Sula/M
+Sulawesi/M
+Suleiman/M
+Sulla/M
+Sullivan/M
+Sumatra/M
+Sumatran/SM
+Sumeria/M
+Sumerian/SM
+Sumerica/M
+Summer/MS
+Summers/M
+Sumner/M
+Sumter/M
+Sun/SM
+Sunbeam/M
+Sunbelt/M
+Sundanese/M
+Sundas/M
+Sunday/MS
+Sunderland/M
+Sung/M
+Sunkist/M
+Sunni/SM
+Sunnite/MS
+Sunny's
+Sunnyvale/M
+Suomi/M
+Superbowl/M
+Superfund/M
+Superglue/M
+Superior/M
+Superman/M
+Supt
+Surabaja
+Surabaya/M
+Surat/M
+Suriname/M
+Surinamese
+Surya/M
+Susan/M
+Susana/M
+Susann/M
+Susanna/M
+Susannah/M
+Susanne/M
+Susi/M
+Susie/M
+Susquehanna/M
+Sussex/M
+Susy/M
+Sutherland/M
+Sutton/M
+Suva/M
+Suwanee/M
+Suzanna/M
+Suzanne/M
+Suzette/M
+Suzhou/M
+Suzi/M
+Suzie/M
+Suzuki/M
+Suzy/M
+Svalbard/M
+Sven/M
+Svend/M
+Svengali/M
+Sverdlovsk
+Swahili/SM
+Swammerdam/M
+Swanee/M
+Swansea/M
+Swanson/M
+Swazi/SM
+Swaziland/M
+Swed/N
+Swede/SM
+Sweden/M
+Swedenborg/M
+Swedish/M
+Sweeney/M
+Sweet/M
+Swift/M
+Swinburne/M
+Swindon/M
+Swiss/MS
+Swissair/M
+Switz
+Switzerland/M
+Sybil/M
+Sybilla/M
+Sybille/M
+Syd/M
+Sydney/M
+Sykes/M
+Sylvan's
+Sylvester/M
+Sylvia/M
+Sylvie/M
+Symantec/M
+Symbian/M
+Symon/M
+Synge/M
+Syracuse/M
+Syria/M
+Syriac/M
+Syrian/MS
+Syriana/M
+Szilard/M
+Szymborska/M
+S竪vres/M
+T'ang/M
+T/MDG
+TA
+TARP
+TB/M
+TBA
+TD
+TDD
+TEFL
+TELNET/S
+TELNETTed
+TELNETTing
+TESL
+TESOL
+TEirtza/M
+TGIF
+THC
+THz/M
+TIF/SM
+TIFF/SM
+TKO/M
+TLC/M
+TM
+TN
+TNT/M
+TOEFL
+TQM
+TV/SM
+TVA
+TWA/M
+TWX
+TX
+Ta/M
+Tabasco/SM
+Tabatha/M
+Tabb/M
+Taber/M
+Tabernacle/MS
+Tabitha/M
+Tabor
+Tabriz/MS
+Tacitus/M
+Tacoma/M
+Tad/M
+Taddeo/M
+Tadzhik/M
+Taegu/M
+Taejon/M
+Taft/M
+Tagalog/SM
+Tagore/M
+Tagus/M
+Tahiti/M
+Tahitian/MS
+Tahoe/M
+Taichung/M
+Tainan
+Taine/M
+Taipei/M
+Taiping/M
+Tait/M
+Taiwan/M
+Taiwanese/M
+Taiyuan/M
+Tajikistan/M
+Taklamakan/M
+Talbert/M
+Talbot/M
+Talia/M
+Taliban/M
+Taliesin/M
+Tallahassee/M
+Tallchief/M
+Talley/M
+Talleyrand/M
+Tallinn/M
+Tallulah/M
+Talmud/MS
+Talmudic
+Talmudist
+Talya/M
+Tamar/M
+Tamara/M
+Tamas
+Tameka/M
+Tamera/M
+Tamerlane/M
+Tami/M
+Tamika/M
+Tamil/MS
+Tammany/M
+Tammi/M
+Tammie/M
+Tammuz/M
+Tammy/M
+Tampa/M
+Tampax/M
+Tamra/M
+Tamworth/M
+Tana
+Tancred/M
+Tandy/M
+Taney/M
+Tanganyika/M
+Tangier/MS
+Tangshan/M
+Tani/M
+Tania/M
+Tanisha/M
+Tann/MR
+Tanner/M
+Tannhauser/M
+Tannh辰user/M
+Tantalus/M
+Tanya/M
+Tanzania/M
+Tanzanian/SM
+Tao/M
+Taoism/MS
+Taoist/MS
+Tara/M
+Tarantino/M
+Tarawa/M
+Tarazed/M
+Tarbell/M
+Target/M
+Tarim/M
+Tarkenton/M
+Tarkington/M
+Tartar/MS
+Tartary/M
+Tartuffe/M
+Taryn/M
+Tarzan/M
+Tasha/M
+Tashkent/M
+Tasman/M
+Tasmania/M
+Tasmanian/M
+Tass/M
+Tatar/MS
+Tate/M
+Tatiana/M
+Tatum/M
+Taurus/MS
+Tavares/M
+Tawney/M
+Taylor/M
+Tb/M
+Tbilisi/M
+Tc/M
+Tchaikovsky/M
+Te/M
+TeX
+TeXes
+Teasdale/M
+TechRepublic/M
+Technicolor/M
+Technorati/M
+Tecumseh/M
+Ted/M
+Teddie/M
+Teddy/M
+Tedi/M
+Teena/M
+Teflon/MS
+Tegucigalpa/M
+Tehran
+TelePrompTer
+TelePrompter/M
+Telemachus/M
+Telemann/M
+Teletype
+Tell/MR
+Teller/M
+Telugu/M
+Temecula/M
+Tempe
+Templar/M
+Temple/M
+Templeton/M
+Tenn/M
+Tennessean/SM
+Tennessee/M
+Tennyson/M
+Tennysonian
+Tenochtitlan/M
+TensorFlow/M
+Teodor/M
+Teodora/M
+Teodoro/M
+Teotihuacan/M
+Tera/M
+Terence/M
+Teresa/M
+Terese/M
+Tereshkova/M
+Teresita/M
+Teri/M
+Terkel/M
+Terpsichore/M
+Terr/M
+Terra/M
+Terran/M
+Terrance/M
+Terrell/M
+Terrence/M
+Terri/M
+Terrie/M
+Terrill/M
+Territory
+Terry/M
+Tertiary/M
+Terza/M
+Tesco/M
+Tesla/M
+Tess/M
+Tessa/M
+Tessie/M
+Tet/M
+Tethys/M
+Tetons/M
+Teuton/MS
+Teutonic/M
+Tevet/M
+Tex/M
+Texaco/M
+Texan/MS
+Texarkana/M
+Texas/M
+TextEdit/M
+Th/M
+Thacher/M
+Thackeray/M
+Thad/M
+Thaddeus/M
+Thai/SM
+Thailand/M
+Thales/M
+Thalia/M
+Thames/M
+Thanh/M
+Thanksgiving/MS
+Thant/M
+Thar/M
+Tharp/M
+Thatcher/M
+Thatcherism
+Thaxter/M
+Thea/M
+Thebes/M
+Theda/M
+Theia
+Theiler/M
+Thekla/M
+Thelma/M
+Themistocles/M
+Theo/M
+Theobald/M
+Theocritus/M
+Theodor/M
+Theodora/M
+Theodore/M
+Theodoric/M
+Theodosia/M
+Theodosius/M
+Theosophy/M
+Theravada/M
+Theresa/M
+Therese/M
+Thermopylae/M
+Thermos
+Theron/M
+Theseus/M
+Thespian/M
+Thespis/M
+Thessalonian/SM
+Thessaloniki/M
+Thessalon鱈ki/M
+Thessaly/M
+Thia/M
+Thibaut/M
+Thieu/M
+Thimbu/M
+Thimphu
+Thom/M
+Thoma/SM
+Thomas/M
+Thomasin/M
+Thomasina/M
+Thomism/M
+Thomistic/M
+Thompson/M
+Thomson/M
+Thor/M
+Thorazine/M
+Thoreau/M
+Thorin/M
+Thorndike
+Thornton/M
+Thorny's
+Thoroughbred/M
+Thorpe/M
+Thorstein/M
+Thorsten/M
+Thorvald/M
+Thoth/M
+Thrace/M
+Thracian/M
+Thu
+Thucydides/M
+Thule/M
+Thunderbird/M
+Thur/S
+Thurber/M
+Thurman/M
+Thurmond/M
+Thursday/SM
+Thurstan/M
+Thurston/M
+Thutmose/M
+Ti/M
+Tia/M
+Tianjin/M
+Tiber/M
+Tiberius/M
+Tibet/M
+Tibetan/MS
+Ticketmaster/M
+Ticonderoga/M
+Tide/M
+Tiebout/M
+Tienanmen/M
+Tientsin/M
+Tierney/M
+Tiffany/M
+Tigris/M
+Tijuana/M
+Tilda/M
+Tildi/M
+Tildy/M
+Tillich/M
+Tillie/M
+Tillman/M
+Tilly/M
+Tilsit/M
+Tim/M
+Timbuktu/M
+Timex/M
+Timi/M
+Timmy/M
+Timon/M
+Timor/M
+Timotheus/M
+Timothy/M
+Timur/M
+Timurid/M
+Tina/M
+Ting/M
+Tinkerbell/M
+Tinkertoy/M
+Tinseltown/M
+Tintoretto/M
+Tippecanoe/M
+Tipperary/M
+Tirane
+Tiresias/M
+Tirol/M
+Tirolean
+Tish/M
+Tisha/M
+Tishri/M
+Titan/SM
+Titania/M
+Titanic/M
+Titian/M
+Titicaca/M
+Tito/M
+Titus/M
+Titusville/M
+Tl/M
+Tlaloc/M
+Tlingit/M
+Tm/M
+Tobago/M
+Tobe/M
+Tobey
+Tobi/M
+Tobias/M
+Tobie/M
+Tobin/M
+Tobit/M
+Toby/M
+Tocantins/M
+Tocqueville/M
+Tod/M
+Todd/M
+Togo/M
+Togolese/M
+Tojo/M
+Tokay/M
+Tokugawa/M
+Tokyo/M
+Tokyoite
+Toledo/MS
+Tolkien/M
+Tolstoy/M
+Toltec/M
+Tolyatti/M
+Tom/M
+Toma/SM
+Tomas/M
+Tomaso/M
+Tombaugh/M
+Tomi/M
+Tomlin/M
+Tommie/M
+Tommy/M
+Tompkins/M
+Tomsk/M
+Tonga/M
+Tongan/MS
+Toni/M
+Tonia/M
+Tonto/M
+Tony/M
+Tonya/M
+Tootsie/M
+Topeka/M
+Topsy/M
+Torah/M
+Torahs
+Tore's
+Torey/M
+Tori/M
+Torin/M
+Toronto/M
+Torquemada/M
+Torr/MX
+Torrance/M
+Torre/SM
+Torrence/M
+Torrens/M
+Torres/M
+Torrey/M
+Torricelli/M
+Torrie/M
+Torry/M
+Tortola/M
+Tortuga/M
+Torvalds/M
+Tory/SM
+Tosca/M
+Toscanini/M
+Toshiba/M
+Toto/M
+Toulouse/M
+Tova/M
+Tove/M
+Townes/M
+Townsend/M
+Toynbee/M
+Toyoda/M
+Toyota/M
+Tracey/M
+Traci/M
+Tracie/M
+Tracy/M
+Trafalgar/M
+Trailways/M
+Trajan/M
+Tran/M
+Transcaucasia/M
+Transvaal/M
+Transylvania/M
+Transylvanian/M
+Trappist/SM
+Traver/MS
+Travis/M
+Travolta/M
+Treasury/SM
+Treblinka/M
+Trekkie/M
+Tremain/M
+Tremaine/M
+Tremayne/M
+Trent/M
+Trenton/M
+Treo/M
+Trev/M
+Trevelyan/M
+Trevino/M
+Trevor/M
+Trey/M
+Triangulum/M
+Triassic/M
+Tricia/M
+Trident/M
+Trieste/M
+Trimurti/M
+Trina/M
+Trinidad/M
+Trinidadian/MS
+Trinity/SM
+TripAdvisor/M
+Tripitaka/M
+Tripoli/M
+Tripp/M
+Trippe/M
+Tris
+Trish/M
+Trisha/M
+Trista/M
+Tristan/M
+Triton/M
+Trix/M
+Trixie/M
+Trobriand/M
+Troilus/M
+Trojan/MS
+Trollope/M
+Trondheim/M
+Tropicana/M
+Trotsky/M
+Troy/M
+Troyes
+Truckee/M
+Trude/M
+Trudeau/M
+Trudi/M
+Trudy/M
+Trueman/M
+Truffaut/M
+Trujillo/M
+Truman/M
+Trumbull/M
+Trump/M
+Truth/M
+Tsimshian/M
+Tsiolkovsky/M
+Tsitsihar/M
+Tsongkhapa/M
+Tswana/M
+Tu/M
+Tuamotu/M
+Tuareg/M
+Tubman/M
+Tucker/M
+Tucson/M
+Tucuman/M
+Tudor/SM
+Tue/S
+Tues/M
+Tuesday/MS
+Tulane/M
+Tull/M
+Tully/M
+Tulsa/M
+Tulsidas/M
+Tums/M
+Tungus/M
+Tunguska/M
+Tunis/M
+Tunisia/M
+Tunisian/MS
+Tunney/M
+Tupi/M
+Tupperware/M
+Tupungato/M
+Turgenev/M
+Turin/M
+Turing/M
+Turk/SM
+Turkestan/M
+Turkey/M
+Turkic/MS
+Turkish/M
+Turkmenistan/M
+Turlock/M
+Turner/M
+Turpin/M
+Tuscaloosa/M
+Tuscan/M
+Tuscany/M
+Tuscarora/MS
+Tuscon/M
+Tuskegee/M
+Tussaud/M
+Tut/M
+Tutankhamen/M
+Tutsi/M
+Tutu/M
+Tuvalu/M
+Tuvaluan
+Twain/M
+Tweed/M
+Tweedledee/M
+Tweedledum/M
+Twila/M
+Twinkies/M
+Twitter/M
+Twizzlers/M
+Twp
+Twyla/M
+Ty/M
+Tybalt/M
+Tycho/M
+Tye/M
+Tylenol/M
+Tyler/M
+Tynan/M
+Tyndale/M
+Tyndall/M
+Tyne/M
+Tyre/M
+Tyree/M
+Tyrolean
+Tyrone/M
+Tyrus/M
+Tyson/M
+U/M
+UAR
+UAW
+UBS/M
+UCLA/M
+UFO/SM
+UHF/M
+UI/SM
+UK/M
+UL
+UN/M
+UNESCO/M
+UNICEF/M
+UNIX/M
+UPC
+UPI/M
+UPS/M
+URL/S
+US/M
+USA/M
+USAF
+USB
+USCG
+USDA/M
+USIA
+USMC
+USN
+USO
+USP
+USPS
+USS
+USSR/M
+UT/M
+UTC
+UV/M
+Ubangi/M
+Ubuntu/M
+Ucayali/M
+Uccello/M
+Udall/M
+Udell/M
+Ufa/M
+Uganda/M
+Ugandan/MS
+Ugo/M
+Uighur/M
+Ujungpandang/M
+Ukraine/M
+Ukrainian/SM
+Ula/M
+Ulick/M
+Ulises/M
+Ulla/M
+Ulric/M
+Ulrica/M
+Ulrich/M
+Ulrike/M
+Ulster/M
+Ultrasuede/M
+Ulyanovsk/M
+Ulysses/M
+Umberto/M
+Umbriel/M
+Una/M
+Underwood/M
+Ungava/M
+Unicode/M
+Unilever/M
+Union/SM
+Unionist
+Uniontown/M
+Uniroyal/M
+Unitarian/MS
+Unitarianism/MS
+Unitas/M
+Unix/S
+Unukalhai/M
+Upanishads/M
+Updike/M
+Upjohn/M
+Upton/M
+Ur/M
+Ural/SM
+Urals/M
+Urania/M
+Uranus/M
+Urbain/M
+Urban/M
+Urbano/M
+Urdu/M
+Urey/M
+Uri/SM
+Uriah/M
+Uriel/M
+Uris/M
+Urquhart/M
+Ursa/M
+Ursula/M
+Ursuline/M
+Uruguay/M
+Uruguayan/MS
+Urumqi/M
+Usenet/MS
+Ustinov/M
+Ut
+Uta/M
+Utah/M
+Utahan/MS
+Ute/SM
+Utica/M
+Utopia/SM
+Utopian/SM
+Utrecht/M
+Utrillo/M
+Uzbek/M
+Uzbekistan/M
+Uzi/SM
+V/M
+VA
+VAT/M
+VAX
+VAXes
+VBA/M
+VCR/M
+VD/M
+VDT
+VDU
+VF
+VFW/M
+VG
+VGA
+VHF/M
+VHS
+VI/M
+VIP/SM
+VISTA
+VJ
+VLF/M
+VOA
+VP
+VPN/SM
+VT
+VTOL
+Va/M
+Vacaville/M
+Vachel/M
+Vaclav/M
+Vader/M
+Vaduz/M
+Vail/M
+Val/M
+Valarie/M
+Valdemar/M
+Valdez/M
+Valdosta/M
+Valencia/SM
+Valenti/M
+Valentia/M
+Valentin/M
+Valentina/M
+Valentine/M
+Valentino/M
+Valenzuela/M
+Valera
+Valeria/M
+Valerian/M
+Valerie/M
+Valery/M
+Valhalla/M
+Valium/MS
+Valkyrie/SM
+Valle/M
+Vallejo/M
+Valletta/M
+Valli/M
+Valois/M
+Valparaiso/M
+Valvoline/M
+Val辿ry/M
+Van/M
+Vance/M
+Vancouver/M
+Vanda/M
+Vandal/MS
+Vanderbilt/M
+Vandyke/M
+Vanessa/M
+Vang/M
+Vania/M
+Vanna/M
+Vanni/M
+Vanuatu/M
+Vanya/M
+Vanzetti/M
+Varanasi/M
+Varese/M
+Vargas/M
+Vaseline/SM
+Vasili/M
+Vasily/M
+Vasquez/M
+Vassar/M
+Vassili/M
+Vassily/M
+Vatican/M
+Vauban/M
+Vaughan/M
+Vaughn/M
+Vazquez/M
+Veblen/M
+Veda/SM
+Vedanta/M
+Veep
+Vega/SM
+Vegas/M
+Vegemite/M
+Vela/M
+Velasquez/M
+Velazquez/M
+Velcro/MS
+Velez/M
+Velma/M
+Velveeta/M
+Vel叩squez/M
+Vel叩zquez/M
+Venetian/SM
+Venezuela/M
+Venezuelan/SM
+Venice/M
+Venn/M
+Ventolin/M
+Venus/MS
+Venusian/M
+Vera/M
+Veracruz/M
+Verde/M
+Verdi/M
+Verdun/M
+Vere/M
+Verena/M
+Verizon/M
+Verlaine/M
+Vermeer/M
+Vermont/ZMR
+Vermonter/M
+Vern/M
+Verna/M
+Verne/M
+Verney/M
+Vernon/M
+Vernor/M
+Verona/M
+Veronese/M
+Veronica/M
+Veronika/M
+Veronique
+Versailles/M
+Vesalius/M
+Vespasian/M
+Vespucci/M
+Vesta/M
+Vesuvius/M
+Vi/M
+Viacom/M
+Viagra/M
+Vic/M
+Vicente/M
+Vichy/M
+Vick/M
+Vicki/M
+Vickie/M
+Vicksburg/M
+Vicky/M
+Vicodin/M
+Victor/M
+Victoria/M
+Victorian/MS
+Victorianism
+Victorville/M
+Victrola/M
+Vida/M
+Vidal/M
+Vienna/M
+Viennese/M
+Vientiane/M
+Vietcong/M
+Vietminh/M
+Vietnam/M
+Vietnamese/M
+Vijayanagar/M
+Vijayawada/M
+Viking/MS
+Vikki/M
+Vila/M
+Villa/SM
+Villarreal/M
+Villas/M
+Villon/M
+Vilma/M
+Vilnius/M
+Vilyui/M
+Vin/M
+Vina/M
+Vince/M
+Vincent/M
+Vindemiatrix/M
+Vineland/M
+Vinnie/M
+Vinny/M
+Vinson/M
+Viola/M
+Violante/M
+Violet/M
+Violetta/M
+Violette/M
+Virgie/M
+Virgil/M
+Virgilio/M
+Virginia/M
+Virginian/SM
+Virginie/M
+Virgo/SM
+Visa/M
+Visakhapatnam/M
+Visalia/M
+Visayans/M
+Vishnu/M
+Visigoth/M
+Visigoths
+Vistula/M
+Vite/M
+Vitim/M
+Vito/M
+Vitoria
+Vittoria/M
+Vittorio/M
+Vitus/M
+Viv/M
+Vivaldi/M
+Vivekananda/M
+Vivi/MN
+Vivian/M
+Viviana/M
+Vivie/M
+Vivien/M
+Vivienne/M
+Vlad/M
+Vladimir/M
+Vladivostok/M
+Vlaminck/M
+Vlasic/M
+VoIP
+Vodafone/M
+Vogue/M
+Volcker/M
+Voldemort/M
+Volga/M
+Volgograd/M
+Volkswagen/M
+Volstead/M
+Volta/M
+Voltaire/M
+Volvo/M
+Von/M
+Vonda/M
+Vonnegut/M
+Voronezh/M
+Vorster/M
+Voyager/M
+Vt
+Vuitton/M
+Vulcan/M
+Vulg
+Vulgate/SM
+W/MDT
+WA
+WAC
+WASP/SM
+WATS/M
+WC
+WHO/M
+WI
+WMD
+WNW/M
+WP
+WSW/M
+WTF
+WTO
+WV
+WW
+WWI
+WWII
+WWW/M
+WY
+WYSIWYG
+Wabash/M
+Wac
+Waco/M
+Wade/M
+Wadsworth/M
+Wagner/M
+Wagnerian/M
+Wahhabi/M
+Waikiki/M
+Wainwright/M
+Waite/M
+Wake/M
+Wakefield
+Waksman/M
+Wald/MN
+Waldemar/M
+Walden/M
+Waldensian/M
+Waldheim/M
+Waldo/M
+Waldorf/M
+Wales/M
+Walesa/M
+Walgreen/SM
+Walgreens/M
+Walker/M
+Walkman/M
+Wall/SMR
+Wallace/M
+Wallas/M
+Wallenstein/M
+Waller/M
+Wallie/M
+Wallis/M
+Walloon/M
+Walls/M
+Wally/M
+Walmart/M
+Walpole/M
+Walpurgisnacht/M
+Walsh/M
+Walt/MRZ
+Walter/M
+Walters/M
+Walther/M
+Walton/M
+Wanamaker/M
+Wanda/M
+Wang/M
+Wankel/M
+Warcraft/M
+Ward/M
+Warde/M
+Ware/MG
+Warhol/M
+Waring/M
+Warner/M
+Warren/M
+Warsaw/M
+Warwick/M
+Warwickshire/M
+Wasatch/M
+Wash/M
+Washington/M
+Washingtonian/MS
+Wassermann/M
+Wat/MZ
+Waterbury/M
+Waterford/M
+Watergate/M
+Waterloo/MS
+Waters/M
+Watertown/M
+Watkins/M
+Watson/M
+Watsonville/M
+Watt/SM
+Watteau/M
+Watts/M
+Watusi/M
+Waugh/M
+Wausau/M
+Wave
+Waverley/M
+Waverly/M
+Wayland/M
+Waylon/M
+Wayne/M
+Waynesboro/M
+Weaver/M
+Web/MR
+WebSphere/M
+Webb/M
+Weber/M
+Webern/M
+Webster/MS
+Wed/M
+Weddell/M
+Wedgwood/M
+Wednesday/MS
+Weeks/M
+Wehrmacht/M
+Wei/M
+Weider/M
+Weierstrass/M
+Weill/M
+Weinberg/M
+Weirton/M
+Weiss/M
+Weissmuller/M
+Weizmann/M
+Welby/M
+Weldon/M
+Welland/M
+Weller/M
+Welles/M
+Wellington/SM
+Wells/M
+Welsh/M
+Welshman/M
+Welshmen/M
+Welshwoman
+Wenatchee/M
+Wendel/M
+Wendell/M
+Wendi/M
+Wendy/M
+Werner/M
+Wernher/M
+Wes
+Wesak/M
+Wesley/M
+Wesleyan/M
+Wessex/M
+Wesson/M
+West/SM
+Westbrook/M
+Western/MRS
+Westinghouse/M
+Westley/M
+Westminster/M
+Weston/M
+Westphalia/M
+Weyden/M
+Wezen/M
+Wharton/M
+Wheaties/M
+Wheatstone/M
+Wheeler/M
+Wheeling/M
+Whig/SM
+Whipple/M
+Whirlpool/M
+Whistler/M
+Whitaker/M
+Whitby/M
+White/SM
+Whitefield/M
+Whitehall/M
+Whitehead/M
+Whitehorse/M
+Whiteley/M
+Whitfield/M
+Whitley/M
+Whitman/M
+Whitney/M
+Whitsunday/MS
+Whittaker/M
+Whittier/M
+Wi-Fi/M
+WiFi/M
+Wicca/M
+Wichita/M
+Wiemar/M
+Wiesel/M
+Wiesenthal/M
+Wiggins/M
+Wigner/M
+Wii/M
+WikiPatents/M
+Wikibooks/M
+Wikileaks
+Wikimedia/M
+Wikinews/M
+Wikipedia/M
+Wikiquote/M
+Wikisource/M
+Wiktionary/M
+Wilberforce/M
+Wilbert/M
+Wilbur/M
+Wilburn/M
+Wilcox/M
+Wilda/M
+Wilde/MR
+Wilden/M
+Wilder/M
+Wiles/M
+Wiley/M
+Wilford/M
+Wilfred/M
+Wilfredo/M
+Wilfrid/M
+Wilhelm/M
+Wilhelmina/M
+Wilhelmine
+Wilkerson/M
+Wilkes/M
+Wilkins/M
+Wilkinson/M
+Will/M
+Willa/M
+Willamette/M
+Willard/M
+Willem/M
+Willemstad/M
+Willey/M
+Willi/MS
+William/SM
+Williams/M
+Williamsburg/M
+Williamson/M
+Williamsport/M
+Willie/M
+Willis/M
+Willy/M
+Wilma/M
+Wilmer/M
+Wilmette/M
+Wilmington/M
+Wilson/M
+Wilsonian/M
+Wilton/M
+Wiltshire/M
+Wimbledon/M
+Wimsey/M
+Winchell/M
+Winchester/MS
+Windbreaker/M
+Windex/M
+Windham/M
+Windhoek/M
+Windows/M
+Windsor/SM
+Windward/M
+Windy's
+Winesap/M
+Winfield/M
+Winfred/M
+Winfrey/M
+Winifred/M
+Winkle/M
+Winn/M
+Winna/M
+Winne/M
+Winnebago/M
+Winnie/M
+Winnifred/M
+Winnipeg/M
+Winny/M
+Winona/M
+Winslow/M
+Winston/M
+Winters/M
+Winthrop/M
+Wis
+Wisc
+Wisconsin/M
+Wisconsinite/MS
+Wise/M
+Witt/M
+Wittgenstein/M
+Witty's
+Witwatersrand/M
+Wm/M
+Wobegon/M
+Wodehouse/M
+Wolf/M
+Wolfe/M
+Wolff/M
+Wolfgang/M
+Wollongong/M
+Wollstonecraft/M
+Wolsey/M
+Wolverhampton
+Wonder/M
+Wonderbra/M
+Wong/M
+Wood/SM
+Woodard/M
+Woodhull/M
+Woodie/M
+Woodland/M
+Woodrow/M
+Woods/M
+Woodstock/M
+Woodward/M
+Woolf/M
+Woolite/M
+Woolongong/M
+Woolworth/M
+Wooster/M
+Wooten/M
+Worcester/SM
+Worcestershire/M
+WordPress/M
+Worden/M
+Wordsworth/M
+Workman/M
+WorldCat/M
+Worms/M
+Worthington/M
+Wotan/M
+Wovoka/M
+Wozniak/M
+Wozzeck/M
+Wrangell/M
+Wren/M
+Wright/M
+Wrigley/M
+Wroclaw/M
+Wu/M
+Wuhan/M
+Wurlitzer/M
+Wyatt/M
+Wycherley/M
+Wycliffe/M
+Wye/H
+Wyeth/M
+Wylie/M
+Wyn/M
+Wyndham/M
+Wynn/M
+Wynne/M
+Wyo
+Wyoming/M
+Wyomingite/SM
+X/M
+XBL/M
+XEmacs/M
+XL/M
+XLS/SM
+XLSX/SM
+XML
+XPCOM/M
+XPConnect/M
+XPInstall/M
+XS
+XUL/M
+XULRunner/M
+XXL
+Xamarin/M
+Xanadu/M
+Xanax/M
+Xanthippe/M
+Xavier/M
+Xbox/M
+Xe/SM
+Xena/M
+Xenakis/M
+Xenia/M
+Xenophon/M
+Xerox/MS
+Xerxes/M
+Xhosa/M
+Xi'an/M
+Xian/SM
+Xiaoping/M
+Ximenes/M
+Ximenez/M
+Xingu/M
+Xinjiang/M
+Xiongnu/M
+Xizang/M
+Xmas/MS
+Xochipilli/M
+Xuzhou/M
+Y/M
+YMCA/M
+YMHA
+YMMV
+YT
+YWCA/M
+YWHA
+Yacc/M
+Yahoo/M
+Yahtzee/M
+Yahweh/M
+Yakima/M
+Yakut/M
+Yakutsk/M
+Yale/M
+Yalow/M
+Yalta/M
+Yalu/M
+Yamagata/M
+Yamaha/M
+Yamoussoukro/M
+Yancey/M
+Yancy/M
+Yang/M
+Yangon/M
+Yangtze/M
+Yank/SM
+Yankee/SM
+Yaobang/M
+Yaounde/M
+Yaqui/M
+Yardley/M
+Yaren
+Yaroslavl/M
+Yasmin/M
+Yataro/M
+Yates/M
+Yauco/M
+Yb/M
+Yeager/M
+Yeats/M
+Yehudi/M
+Yekaterinburg/M
+Yelena/M
+Yellowknife/M
+Yellowstone/M
+Yeltsin/M
+Yemen/M
+Yemeni/SM
+Yemenite
+Yenisei/M
+Yerevan/M
+Yerkes/M
+Yesenia/M
+Yetta/M
+Yevtushenko/M
+Yggdrasil/M
+Yiddish/M
+Ymir/M
+Ynez/M
+Yoda/M
+Yoknapatawpha/M
+Yoko/M
+Yokohama/M
+Yolanda/M
+Yolande/M
+Yong/M
+Yonkers/M
+York/MR
+Yorke/M
+Yorker/M
+Yorkie/M
+Yorkshire/MS
+Yorktown/M
+Yoruba/M
+Yosemite/M
+Yoshi/M
+Yoshiko/M
+Yossarian/M
+YouTube/M
+Young/M
+Youngstown/M
+Ypres/M
+Ypsilanti/M
+Ysabel/M
+Yuan/M
+Yucatan/M
+Yugo/M
+Yugoslav/MS
+Yugoslavia/M
+Yugoslavian/SM
+Yukon/M
+Yul/M
+Yule/SM
+Yuletide/MS
+Yuma/SM
+Yunnan/M
+Yuri/M
+Yves/M
+Yvette/M
+Yvon/M
+Yvonne/M
+Yvor/M
+Z/SMNXT
+ZDNet/M
+Zaccaria/M
+Zach
+Zachariah/M
+Zacharias
+Zachary/M
+Zachery/M
+Zack/M
+Zagreb/M
+Zahara/M
+Zaire/M
+Zairian
+Zak/M
+Zambezi/M
+Zambia/M
+Zambian/SM
+Zamboni/M
+Zamenhof/M
+Zamora/M
+Zane/M
+Zanuck/M
+Zanzibar/M
+Zapata/M
+Zaporozhye/M
+Zapotec/M
+Zappa/M
+Zara/M
+Zarah/M
+Zarathustra/M
+Zaria/M
+Zea/M
+Zealand/M
+Zeb/M
+Zebedee/M
+Zebulon/M
+Zechariah/M
+Zedekiah/M
+Zedong/M
+Zeffirelli/M
+Zeke/M
+Zelda/M
+Zelig/M
+Zelma/M
+Zen/M
+Zena/M
+Zenger/M
+Zenia/M
+Zeno/M
+Zephaniah/M
+Zephyrhills/M
+Zephyrus/M
+Zeppelin/M
+Zest/M
+Zeus/M
+Zhang/M
+Zhao/M
+Zhdanov
+Zhejiang/M
+Zhengzhou/M
+Zhivago/M
+Zhou/M
+Zhukov/M
+Zia/M
+Zibo/M
+Ziegfeld/M
+Ziegler/M
+Ziff/M
+Ziggy/M
+Zika
+Zimbabwe/M
+Zimbabwean/SM
+Zimmerman/M
+Zinfandel/M
+Zion/SM
+Zionism/SM
+Zionist/SM
+Ziploc/M
+Zita/M
+Zn/M
+Zoe/M
+Zola/M
+Zollverein/M
+Zoloft/M
+Zomba/M
+Zora/M
+Zorn/M
+Zoroaster/M
+Zoroastrian/MS
+Zoroastrianism/SM
+Zorro/M
+Zosma/M
+Zr/M
+Zsigmondy/M
+Zubenelgenubi/M
+Zubeneschamali/M
+Zukor/M
+Zulu/SM
+Zululand
+Zune/M
+Zuni/M
+Zurich/M
+Zwingli/M
+Zworykin/M
+Zyrtec/M
+Zyuganov/M
+Zzz
+Z端rich/M
+a/S
+aah
+aardvark/SM
+ab/SDY
+aback
+abacus/MS
+abaft
+abalone/SM
+abandon/LSDG
+abandonment/M
+abase/LGDS
+abasement/M
+abash/GLDS
+abashed/UY
+abashment/M
+abate/LGDS
+abated/U
+abatement/M
+abattoir/MS
+abbe/SM
+abbess/MS
+abbey/MS
+abbot/MS
+abbr
+abbrev/S
+abbreviate/DSGNX
+abbreviation/M
+abb辿/SM
+abdicate/GNDSX
+abdication/M
+abdomen/SM
+abdominal
+abduct/DSG
+abductee/MS
+abduction/SM
+abductor/MS
+abeam
+aberrant
+aberration/MS
+aberrational
+abet/S
+abetted
+abetter/SM
+abetting
+abettor/SM
+abeyance/M
+abhor/S
+abhorred
+abhorrence/M
+abhorrent/Y
+abhorring
+abidance/M
+abide/GS
+abiding/Y
+ability/IEMS
+abject/YP
+abjection/M
+abjectness/M
+abjuration/SM
+abjuratory
+abjure/ZGDRS
+abjurer/M
+ablate/XGNVDS
+ablation/M
+ablative/MS
+ablaze
+able/UT
+abler
+abloom
+ablution/SM
+abnegate/GNDS
+abnegation/M
+abnormal/Y
+abnormality/SM
+aboard
+abode/MS
+abolish/GDS
+abolition/M
+abolitionism/M
+abolitionist/SM
+abominable
+abominably
+abominate/DSGNX
+abomination/M
+aboriginal/MS
+aborigine/SM
+aborning
+abort/GVDS
+abortion/MS
+abortionist/MS
+abortive/Y
+abound/DSG
+about
+above/M
+aboveboard
+abracadabra/M
+abrade/GDS
+abrasion/MS
+abrasive/MYPS
+abrasiveness/M
+abreast
+abridge/DSLG
+abridgement/MS
+abridgment/MS
+abroad
+abrogate/XGNDS
+abrogation/M
+abrogator/MS
+abrupt/TPRY
+abruptness/M
+abs/M
+abscess/MDSG
+abscissa/SM
+abscission/M
+abscond/ZGSDR
+absconder/M
+abseil/MDSG
+absence/SM
+absent/DYSG
+absentee/MS
+absenteeism/M
+absentminded/YP
+absentmindedness/M
+absinthe/M
+absolute/PMYTNS
+absoluteness/M
+absolution/M
+absolutism/M
+absolutist/MS
+absolve/DSG
+absorb/AZGDRS
+absorbance/S
+absorbancy/M
+absorbency/M
+absorbent/SM
+absorbing/Y
+absorption/M
+absorptive
+abstain/DRZGS
+abstainer/M
+abstemious/PY
+abstemiousness/M
+abstention/MS
+abstinence/M
+abstinent
+abstract/GSPMDY
+abstracted/YP
+abstractedness/M
+abstraction/SM
+abstractness/MS
+abstruse/YP
+abstruseness/M
+absurd/TPRY
+absurdist/MS
+absurdity/SM
+absurdness/M
+abundance/SM
+abundant/Y
+abuse's
+abuse/EGVDS
+abuser/MS
+abusive/YP
+abusiveness/M
+abut/SL
+abutment/MS
+abutted
+abutting
+abuzz
+abysmal/Y
+abyss/MS
+abyssal
+ac
+acacia/MS
+academe/M
+academia/M
+academic/SM
+academical/Y
+academician/MS
+academy/SM
+acanthus/MS
+accede/GDS
+accelerate/GNXDS
+acceleration/M
+accelerator/SM
+accelerometer/SM
+accent/MDSG
+accented/U
+accentual
+accentuate/GNDS
+accentuation/M
+accept/DSBG
+acceptability/M
+acceptableness/M
+acceptably/U
+acceptance/SM
+acceptation/MS
+accepted/U
+access/MDSG
+accessibility/IM
+accessible/I
+accessibly/I
+accession/MDGS
+accessorize/DSG
+accessory/SM
+accident/MS
+accidental/SMY
+acclaim/MDGS
+acclamation/M
+acclimate/DSGN
+acclimation/M
+acclimatization/M
+acclimatize/DSG
+acclivity/SM
+accolade/SM
+accommodate/XGNDS
+accommodating/Y
+accommodation/M
+accompanied/U
+accompaniment/MS
+accompanist/SM
+accompany/DSG
+accomplice/SM
+accomplish/DSLG
+accomplished/U
+accomplishment/MS
+accord/GMDS
+accordance/M
+accordant
+according/Y
+accordion/MS
+accordionist/MS
+accost/GMDS
+account/MDSBG
+accountability/SM
+accountable/U
+accountancy/M
+accountant/MS
+accounted/U
+accounting/M
+accouter/SGD
+accouterments/M
+accoutre/DSG
+accoutrements
+accredit/SGD
+accreditation/M
+accredited/U
+accrete/NDSX
+accretion/M
+accrual/MS
+accrue/GDS
+acct
+acculturate/DSGN
+acculturation/M
+accumulate/XGNVDS
+accumulation/M
+accumulator/MS
+accuracy/IM
+accurate/IY
+accurateness/M
+accursed/P
+accursedness/M
+accusation/MS
+accusative/MS
+accusatory
+accuse/ZGDRS
+accuser/M
+accusing/Y
+accustom/DSG
+accustomed/U
+ace/DSMG
+acerbate/DSG
+acerbic
+acerbically
+acerbity/M
+acetabular
+acetabulum
+acetaminophen/M
+acetate/MS
+acetic
+acetone/M
+acetonic
+acetyl
+acetylene/M
+ache/DSMG
+achene/MS
+achievable/U
+achieve/BLZGDRS
+achievement/SM
+achiever/M
+aching/Y
+achoo/M
+achromatic
+achy/TR
+acid/SMY
+acidic
+acidify/GDS
+acidity/M
+acidosis/M
+acidulous
+acknowledge/DSGL
+acknowledged/U
+acknowledgement/MS
+acknowledgment/SM
+acme/SM
+acne/M
+acolyte/MS
+aconite/MS
+acorn/MS
+acoustic/S
+acoustical/Y
+acoustics/M
+acquaint/AGSD
+acquaintance/SM
+acquaintanceship/M
+acquainted/U
+acquiesce/DSG
+acquiescence/M
+acquiescent/Y
+acquire/ZGBDRSL
+acquirement/M
+acquisition/MS
+acquisitive/YP
+acquisitiveness/M
+acquit/S
+acquittal/MS
+acquitted
+acquitting
+acre/SM
+acreage/MS
+acrid/PTRY
+acridity/M
+acridness/M
+acrimonious/YP
+acrimoniousness/M
+acrimony/M
+acrobat/MS
+acrobatic/S
+acrobatically
+acrobatics/M
+acronym/MS
+acrophobia/M
+acropolis/MS
+across
+acrostic/SM
+acrylamide
+acrylic/MS
+act's
+act/ASDGV
+actin
+acting/M
+actinium/M
+action/ASM
+actionable
+activate/ICANGSD
+activation/ICAM
+activator/MS
+active's
+active/ISY
+activeness/M
+activism/M
+activist/MS
+activity/ISM
+actor/AMS
+actress/MS
+actual/Y
+actuality/SM
+actualization/M
+actualize/GDS
+actuarial
+actuary/SM
+actuate/GNDS
+actuation/M
+actuator/SM
+acuity/M
+acumen/M
+acupressure/M
+acupuncture/M
+acupuncturist/SM
+acute/PMYTRS
+acuteness/M
+acyclovir/M
+acyl
+ad/SM
+adage/MS
+adagio/MS
+adamant/MY
+adapt/BZGVDRS
+adaptability/M
+adaptation/MS
+adapter/M
+adaption/S
+add-on/S
+add/SDRBZG
+addend/MS
+addenda
+addendum/MS
+adder/M
+addible
+addict/GVMDS
+addiction/SM
+addictive/P
+addition/SM
+additional/Y
+additive/SM
+addle/GDS
+address's
+address/AGDS
+addressable
+addressed/U
+addressee/SM
+adduce/GDS
+adduction/SM
+adenine/M
+adenocarcinoma
+adenoid/SM
+adenoidal
+adept/MYPS
+adeptness/M
+adequacy/IM
+adequate/IY
+adequateness/M
+adhere/GDS
+adherence/M
+adherent/SM
+adhesion/M
+adhesive/PSM
+adhesiveness/M
+adiabatic
+adieu/MS
+adios
+adipose
+adi坦s
+adj
+adjacency/M
+adjacent/Y
+adjectival/Y
+adjective/MS
+adjoin/GDS
+adjourn/DGLS
+adjournment/SM
+adjudge/GDS
+adjudicate/GNVXDS
+adjudication/M
+adjudicator/SM
+adjudicatory
+adjunct/MS
+adjuration/MS
+adjure/GDS
+adjust/AGDSL
+adjustable
+adjuster/SM
+adjustment/AMS
+adjutant/SM
+adman/M
+admen
+admin/MS
+administer/DGS
+administrate/XDSGNV
+administration/M
+administrative/Y
+administrator/MS
+admirably
+admiral/MS
+admiralty/M
+admiration/M
+admire/BZGDRS
+admirer/M
+admiring/Y
+admissibility/IM
+admissible/I
+admissibly
+admission/AM
+admissions
+admit/AS
+admittance/M
+admitted/Y
+admitting/A
+admix/GDS
+admixture/SM
+admonish/LDSG
+admonishment/MS
+admonition/MS
+admonitory
+ado/M
+adobe/MS
+adolescence/SM
+adolescent/SM
+adopt/AGVDS
+adoptable
+adoptee/MS
+adopter/MS
+adoption/SM
+adorableness/M
+adorably
+adoration/M
+adorbs
+adore/BZGDRS
+adorer/M
+adoring/Y
+adorn/LGDS
+adorned/U
+adornment/MS
+adrenal/MS
+adrenalin's
+adrenaline/M
+adrenergic
+adrift
+adroit/PY
+adroitness/M
+adsorb/SDG
+adsorbent/MS
+adsorption/SM
+adulate/DSGN
+adulation/M
+adulator/MS
+adulatory
+adult/MS
+adulterant/MS
+adulterate/GNDS
+adulterated/U
+adulteration/M
+adulterer/SM
+adulteress/MS
+adulterous
+adultery/SM
+adulthood/M
+adumbrate/GNDS
+adumbration/M
+adv
+advance/LDSMG
+advancement/SM
+advantage/EDSMG
+advantageous/EY
+advent/SM
+adventitious/Y
+adventure/DRSMZG
+adventurer/M
+adventuresome
+adventuress/MS
+adventurism
+adventurist/S
+adventurous/YP
+adventurousness/M
+adverb/SM
+adverbial/SMY
+adversarial
+adversary/SM
+adverse/PRYT
+adverseness/M
+adversity/SM
+advert/SMDG
+advertise/LZGDRS
+advertised/U
+advertisement/MS
+advertiser/M
+advertising/M
+advertorial/SM
+advice/M
+advisability/IM
+advisable/I
+advisably
+advise/LDRSZGB
+advised/UY
+advisement/M
+adviser/M
+advisor/SM
+advisory/SM
+advocacy/M
+advocate/MGDS
+advocator/MS
+advt
+adware/SM
+adz/MS
+adze/M
+aegis/M
+aeon/SM
+aerate/DSGN
+aeration/M
+aerator/SM
+aerial/SMY
+aerialist/MS
+aerie/MS
+aerobatic/S
+aerobatics/M
+aerobic/S
+aerobically
+aerobics/M
+aerodrome/MS
+aerodynamic/S
+aerodynamically
+aerodynamics/M
+aerogram/S
+aerogramme/S
+aeronautic/S
+aeronautical
+aeronautics/M
+aerosol/MS
+aerospace/M
+aery
+aesthete/MS
+aesthetic/S
+aesthetically
+aestheticism/M
+aesthetics/M
+afar
+affability/M
+affable
+affably
+affair/MS
+affect's
+affect/EGVDS
+affectation/SM
+affected/UY
+affecting/Y
+affection/EM
+affectionate/Y
+affections
+afferent
+affiance/GDS
+affidavit/SM
+affiliate's
+affiliate/EGNDS
+affiliated/U
+affiliation/EM
+affiliations
+affine
+affinity/SM
+affirm/AGDS
+affirmation/AMS
+affirmative/MYS
+affix/GMDS
+afflatus/M
+afflict/GDS
+affliction/SM
+affluence/M
+affluent/Y
+afford/GDSB
+affordability
+affordable/U
+affordably/U
+affordance/S
+afforest/EGSD
+afforestation/M
+affray/MS
+affront/GMDS
+afghan/MS
+aficionado/MS
+afield
+afire
+aflame
+afloat
+aflutter
+afoot
+aforementioned
+aforesaid
+aforethought
+afoul
+afraid/U
+afresh
+aft/RZ
+afterbirth/M
+afterbirths
+afterburner/MS
+aftercare/M
+aftereffect/MS
+afterglow/SM
+afterimage/MS
+afterlife/M
+afterlives
+aftermarket/MS
+aftermath/M
+aftermaths
+afternoon/MS
+aftershave/SM
+aftershock/SM
+aftertaste/SM
+afterthought/SM
+afterward/S
+afterword/MS
+again
+against
+agape/M
+agar/M
+agate/MS
+agave/M
+age/DSMGJ
+ageing/SM
+ageism/M
+ageist/SM
+ageless/YP
+agelessness/M
+agency/SM
+agenda/SM
+agenesis
+agent/AMS
+ageratum/M
+agglomerate/DSMGNX
+agglomeration/M
+agglutinate/DSXGN
+agglutination/M
+aggrandize/GLDS
+aggrandizement/M
+aggravate/GNXDS
+aggravating/Y
+aggravation/M
+aggregate/MGNDSX
+aggregation/M
+aggregator/SM
+aggression/M
+aggressive/PY
+aggressiveness/M
+aggressor/SM
+aggrieve/DSG
+aggro
+aghast
+agile/Y
+agility/M
+aging/M
+agitate/XGNDS
+agitation/M
+agitator/MS
+agitprop/M
+agleam
+aglitter
+aglow
+agnostic/MS
+agnosticism/M
+ago
+agog
+agonist/S
+agonize/GDS
+agonizing/Y
+agony/SM
+agoraphobia/M
+agoraphobic/MS
+agrarian/MS
+agrarianism/M
+agree/EBLDS
+agreeableness/EM
+agreeably/E
+agreeing/E
+agreement/ESM
+agribusiness/MS
+agricultural/Y
+agriculturalist/MS
+agriculture/M
+agriculturist/MS
+agronomic
+agronomist/MS
+agronomy/M
+aground
+ague/M
+ah
+aha
+ahchoo
+ahead
+ahem
+ahoy
+aid/SMDRG
+aide/SM
+aided/U
+aider/M
+aigrette/MS
+ail/SDLG
+aileron/SM
+ailment/SM
+aim/SMDG
+aimless/YP
+aimlessness/M
+ain't
+air/SMDJG
+airbag/MS
+airbase/SM
+airbed/S
+airborne
+airbrush/MDSG
+airbus/MS
+aircraft/M
+aircraftman
+aircraftmen
+aircrew/S
+airdrome/S
+airdrop/SM
+airdropped
+airdropping
+airfare/SM
+airfield/SM
+airflow/M
+airfoil/SM
+airfreight/M
+airgun/S
+airhead/SM
+airily
+airiness/M
+airing/M
+airless/P
+airlessness/M
+airletter/S
+airlift/SGMD
+airline/RSMZ
+airliner/M
+airlock/SM
+airmail/GSMD
+airman/M
+airmen
+airplane/MS
+airplay/M
+airport/SM
+airship/SM
+airshow/S
+airsick/P
+airsickness/M
+airspace/M
+airspeed
+airstrike/MS
+airstrip/SM
+airtight
+airtime/M
+airwaves/M
+airway/MS
+airwoman
+airwomen
+airworthiness/M
+airworthy/P
+airy/PTR
+aisle/MS
+aitch/MS
+ajar
+aka
+akimbo
+akin
+al/YV
+alabaster/M
+alack
+alacrity/M
+alarm/GMDS
+alarming/Y
+alarmist/SM
+alas
+alb/SM
+albacore/SM
+albatross/MS
+albeit
+albinism/M
+albino/MS
+album/MNS
+albumen/M
+albumin/M
+albuminous
+alchemist/SM
+alchemy/M
+alcohol/SM
+alcoholic/MS
+alcoholically
+alcoholism/M
+alcove/MS
+alder/MS
+alderman/M
+aldermen
+alderwoman/M
+alderwomen
+ale/SM
+aleatory
+alehouse/SM
+alembic/SM
+alert/GMDYPS
+alertness/M
+alewife/M
+alewives
+alfalfa/M
+alfresco
+alga/M
+algae
+algal
+algebra/SM
+algebraic
+algebraically
+algorithm/SM
+algorithmic
+algorithmically
+alias/GMDS
+alibi/GMDS
+alien/BGMDS
+alienable/IU
+alienate/DSGN
+alienation/M
+alienist/SM
+alight/GDS
+align/ALGDS
+aligned/U
+aligner/MS
+alignment/AMS
+alike/U
+aliment/MDSG
+alimentary
+alimony/M
+aliveness/M
+aliyah/M
+aliyahs
+alkali/MS
+alkalies
+alkaline
+alkalinity/M
+alkalize/DSG
+alkaloid/SM
+alkoxy
+alkyd/MS
+all-nighter/S
+all/M
+allay/GDS
+allegation/MS
+allege/GDS
+alleged/Y
+allegiance/MS
+allegoric
+allegorical/Y
+allegorist/MS
+allegory/SM
+allegretto/MS
+allegro/MS
+allele/MS
+alleluia/SM
+allergen/SM
+allergenic
+allergic
+allergically
+allergist/SM
+allergy/SM
+alleviate/DSGN
+alleviation/M
+alley/MS
+alleyway/SM
+alliance/SM
+alligator/MS
+alliterate/DSXGNV
+alliteration/M
+alliterative/Y
+allocate/ADSGN
+allocation/AM
+allocations
+allot/LS
+allotment/SM
+allotted
+allotting
+allover
+allow/EGDS
+allowable/U
+allowably
+allowance/SM
+alloy/GMDS
+alloyed/U
+allspice/M
+allude/GDS
+allure/MGLDS
+allurement/MS
+alluring/Y
+allusion/SM
+allusive/PY
+allusiveness/M
+alluvial/M
+alluvium/SM
+ally/GDSM
+almanac/SM
+almighty
+almond/MS
+almoner/SM
+almost
+alms/M
+almshouse/MS
+aloe/SM
+aloft
+aloha/MS
+alone
+along
+alongshore
+alongside
+aloof/PY
+aloofness/M
+aloud
+alp/SM
+alpaca/MS
+alpha/MS
+alphabet/SM
+alphabetic
+alphabetical/Y
+alphabetization/SM
+alphabetize/ZGDRS
+alphabetizer/M
+alphanumeric
+alphanumerical/Y
+alpine/S
+already
+alright
+also
+alt/S
+altar/MS
+altarpiece/SM
+alter/GDBS
+alterable/U
+alteration/MS
+altercation/SM
+altered/U
+alternate/DSMYGNVX
+alternation/M
+alternative/MYS
+alternator/SM
+although
+altimeter/MS
+altitude/MS
+alto/SM
+altogether
+altruism/M
+altruist/SM
+altruistic
+altruistically
+alum/SM
+alumina/M
+aluminize/D
+aluminum/M
+alumna/M
+alumnae
+alumni
+alumnus/M
+alveolar/S
+always
+am/N
+amalgam/SM
+amalgamate/XGNDS
+amalgamation/M
+amanuenses
+amanuensis/M
+amaranth/M
+amaranths
+amaretto/M
+amaryllis/MS
+amass/GDS
+amateur/SM
+amateurish/YP
+amateurishness/M
+amateurism/M
+amatory
+amaze/LMGDS
+amazement/M
+amazing/Y
+amazon/MS
+amazonian
+ambassador/SM
+ambassadorial
+ambassadorship/MS
+ambassadress/MS
+amber/M
+ambergris/M
+ambiance/MS
+ambidexterity/M
+ambidextrous/Y
+ambience/MS
+ambient
+ambiguity/SM
+ambiguous/UY
+ambit
+ambition/MS
+ambitious/YP
+ambitiousness/M
+ambivalence/M
+ambivalent/Y
+amble/MZGDRS
+ambler/M
+ambrosia/M
+ambrosial
+ambulance/MS
+ambulanceman
+ambulancemen
+ambulancewoman
+ambulancewomen
+ambulant
+ambulate/DSXGN
+ambulation/M
+ambulatory/SM
+ambuscade/MGDS
+ambush/GMDS
+ameba/MS
+amebae
+amebic
+ameboid
+ameliorate/GNVDS
+amelioration/M
+amen/B
+amenability/M
+amenably
+amend/BLGDS
+amendment/SM
+amenity/SM
+amerce/GLDS
+amercement/SM
+americium/M
+amethyst/SM
+amiability/M
+amiable
+amiably
+amicability/M
+amicable
+amicably
+amici
+amicus
+amid
+amide/MS
+amidship/S
+amidst
+amigo/MS
+amine/S
+amino
+amir/SM
+amiss
+amitriptyline
+amity/M
+ammeter/SM
+ammo/M
+ammonia/M
+ammonium
+ammunition/M
+amnesia/M
+amnesiac/MS
+amnesic/SM
+amnesty/GDSM
+amniocenteses
+amniocentesis/M
+amnion/MS
+amniotic
+amoeba/MS
+amoebae
+amoebic
+amok
+among
+amongst
+amontillado/SM
+amoral/Y
+amorality/M
+amorous/YP
+amorousness/M
+amorphous/PY
+amorphousness/M
+amortization/SM
+amortize/DSGB
+amount/GMDS
+amour/MS
+amoxicillin
+amp/SMDY
+amperage/M
+ampere/MS
+ampersand/MS
+amphetamine/SM
+amphibian/MS
+amphibious/Y
+amphitheater/SM
+amphora/M
+amphorae
+ampicillin
+ample/TR
+amplification/M
+amplifier/M
+amplify/NDRSXZG
+amplitude/SM
+ampoule/MS
+ampule/MS
+amputate/GNDSX
+amputation/M
+amputee/MS
+amt
+amuck
+amulet/MS
+amuse/LGDS
+amusement/MS
+amusing/Y
+amygdala
+amylase/M
+amyloid
+an/CS
+anabolism/M
+anachronism/SM
+anachronistic
+anachronistically
+anaconda/SM
+anaerobe/SM
+anaerobic
+anaerobically
+anagram/MS
+anal/Y
+analgesia/M
+analgesic/SM
+analog/MS
+analogical/Y
+analogize/GDS
+analogous/YP
+analogousness/M
+analogue/SM
+analogy/SM
+analysand/MS
+analyses/A
+analysis/AM
+analyst/SM
+analytic/S
+analytical/Y
+analyticalally
+analyzable
+analyze/ADSG
+analyzer/SM
+anapest/SM
+anapestic/MS
+anaphylactic
+anaphylaxes
+anaphylaxis
+anarchic
+anarchically
+anarchism/M
+anarchist/MS
+anarchistic
+anarchy/M
+anathema/SM
+anathematize/DSG
+anatomic
+anatomical/Y
+anatomist/SM
+anatomize/DSG
+anatomy/SM
+ancestor/SM
+ancestral/Y
+ancestress/MS
+ancestry/SM
+anchor/MDGS
+anchorage/MS
+anchorite/MS
+anchorman/M
+anchormen
+anchorpeople
+anchorperson/SM
+anchorwoman/M
+anchorwomen
+anchovy/SM
+ancient/SPMRYT
+ancientness/M
+ancillary/SM
+and
+andante/SM
+andiron/SM
+androgen/M
+androgenic
+androgynous
+androgyny/M
+android/SM
+anecdotal/Y
+anecdote/MS
+anemia/M
+anemic
+anemically
+anemometer/SM
+anemone/SM
+anent
+anesthesia/M
+anesthesiologist/SM
+anesthesiology/M
+anesthetic/SM
+anesthetist/MS
+anesthetization/M
+anesthetize/GDS
+aneurysm/SM
+anew
+angel/MS
+angelfish/MS
+angelic
+angelica/M
+angelical/Y
+anger/GMDS
+angina/M
+angioplasty/SM
+angiosperm/SM
+angle/MZGDRS
+angler/M
+angleworm/MS
+anglicism/S
+anglicize/GDS
+angling/M
+anglophile/S
+anglophone/S
+angora/MS
+angostura
+angrily
+angry/TR
+angst/M
+angstrom/MS
+anguish/GMDS
+angular
+angularity/SM
+angulation
+anhydrous
+aniline/M
+anilingus
+animadversion/MS
+animadvert/GSD
+animal/MS
+animalcule/SM
+animate/ADSGN
+animated/Y
+animation/AM
+animations
+animator/MS
+anime/M
+animism/M
+animist/SM
+animistic
+animosity/SM
+animus/M
+anion/MS
+anionic
+anise/M
+aniseed/M
+anisette/M
+ankh/M
+ankhs
+ankle/MS
+anklebone/MS
+anklet/MS
+annalist/SM
+annals/M
+anneal/GDS
+annelid/MS
+annex/GMDS
+annexation/MS
+annihilate/DSGN
+annihilation/M
+annihilator/SM
+anniversary/SM
+annotate/DSXGNV
+annotation/M
+annotator/MS
+announce/DRSLZG
+announced/U
+announcement/MS
+announcer/M
+annoy/GDS
+annoyance/MS
+annoying/Y
+annual/MYS
+annualize/DG
+annuitant/SM
+annuity/SM
+annul/LS
+annular
+annulled
+annulling
+annulment/SM
+annulus
+annunciation/SM
+anode/MS
+anodize/GDS
+anodyne/MS
+anoint/GDLS
+anointment/M
+anomalous/Y
+anomaly/SM
+anon/S
+anonymity/M
+anonymization/MS
+anonymize/DSG
+anonymous/Y
+anopheles/M
+anorak/MS
+anorectic/SM
+anorexia/M
+anorexic/MS
+another/M
+answer/BMDGS
+answerable/U
+answered/U
+answerphone/S
+ant/SMD
+antacid/SM
+antagonism/SM
+antagonist/SM
+antagonistic
+antagonistically
+antagonize/DSG
+antarctic
+ante/SM
+anteater/MS
+antebellum
+antecedence/M
+antecedent/SM
+antechamber/SM
+antedate/GDS
+antediluvian
+anteing
+antelope/MS
+antenatal
+antenna/SM
+antennae
+anterior
+anteroom/MS
+anthem/MS
+anther/MS
+anthill/SM
+anthologist/SM
+anthologize/DSG
+anthology/SM
+anthracite/M
+anthrax/M
+anthropocentric
+anthropoid/MS
+anthropological/Y
+anthropologist/SM
+anthropology/M
+anthropomorphic
+anthropomorphically
+anthropomorphism/M
+anthropomorphize/DS
+anthropomorphous
+anti/SM
+antiabortion
+antiabortionist/MS
+antiaircraft
+antibacterial/MS
+antibiotic/MS
+antibody/SM
+antic/MS
+anticancer
+antichrist/SM
+anticipate/GNXDS
+anticipated/U
+anticipation/M
+anticipatory
+anticked
+anticking
+anticlerical
+anticlimactic
+anticlimactically
+anticlimax/MS
+anticline/SM
+anticlockwise
+anticoagulant/MS
+anticommunism/M
+anticommunist/SM
+anticyclone/SM
+anticyclonic
+antidemocratic
+antidepressant/MS
+antiderivative/S
+antidote/MS
+antifa
+antifascist/MS
+antiferromagnetic
+antifreeze/M
+antigen/SM
+antigenic
+antigenicity/M
+antihero/M
+antiheroes
+antihistamine/SM
+antiknock/M
+antilabor
+antilogarithm/SM
+antimacassar/MS
+antimalarial
+antimatter/M
+antimicrobial
+antimissile
+antimony/M
+antineutrino/SM
+antineutron/MS
+antinuclear
+antioxidant/MS
+antiparticle/SM
+antipasti
+antipasto/MS
+antipathetic
+antipathy/SM
+antipersonnel
+antiperspirant/SM
+antiphon/SM
+antiphonal/MYS
+antipodal/S
+antipodean/MS
+antipodes/M
+antipollution
+antipoverty
+antiproton/MS
+antiquarian/SM
+antiquarianism/M
+antiquary/SM
+antiquate/GDS
+antique/DSMG
+antiquity/SM
+antirrhinum/S
+antiscience
+antisemitic
+antisemitism/M
+antisense
+antisepsis/M
+antiseptic/SM
+antiseptically
+antiserum/MS
+antislavery
+antisocial/Y
+antispasmodic/MS
+antisubmarine
+antitank
+antitheses
+antithesis/M
+antithetic
+antithetical/Y
+antitoxin/MS
+antitrust
+antivenin/MS
+antivenom
+antiviral/MS
+antivirus/M
+antivivisectionist/MS
+antiwar
+antler/MDS
+antonym/SM
+antonymous
+antrum
+antsy/TR
+anus/MS
+anvil/MS
+anxiety/SM
+anxious/YP
+anxiousness/M
+any
+anybody/SM
+anyhow
+anymore
+anyone/M
+anyplace
+anything/SM
+anytime
+anyway/S
+anywhere
+anywise
+aorta/MS
+aortic
+apace
+apart
+apartheid/M
+apartment/MS
+apathetic
+apathetically
+apathy/M
+apatite/M
+apatosaurus/M
+ape/DSMG
+apelike
+aperitif/MS
+aperture/SM
+apex/MS
+aphasia/M
+aphasic/MS
+aphelia
+aphelion/SM
+aphid/MS
+aphorism/MS
+aphoristic
+aphoristically
+aphrodisiac/SM
+apiarist/SM
+apiary/SM
+apical/Y
+apiece
+apish/Y
+aplenty
+aplomb/M
+apocalypse/SM
+apocalyptic
+apocrypha/M
+apocryphal/Y
+apogee/MS
+apolitical/Y
+apologetic/U
+apologetically
+apologia/SM
+apologist/MS
+apologize/GDS
+apology/SM
+apoplectic
+apoplexy/SM
+apoptosis
+apoptotic
+apostasy/SM
+apostate/SM
+apostatize/GDS
+apostle/MS
+apostleship/M
+apostolic
+apostrophe/MS
+apothecary/SM
+apothegm/SM
+apotheoses
+apotheosis/M
+app/SM
+appall/GDS
+appalling/Y
+appaloosa/MS
+apparatchik/S
+apparatus/MS
+apparel/MDGS
+apparent/Y
+apparition/SM
+appeal/GBMDS
+appealing/UY
+appear/AESDG
+appearance/EAMS
+appease/LZGDRS
+appeasement/SM
+appeaser/M
+appellant/SM
+appellate/XN
+appellation/M
+append/GDS
+appendage/SM
+appendectomy/SM
+appendices
+appendicitis/M
+appendix/MS
+appertain/GDS
+appetite/SM
+appetizer/MS
+appetizing/Y
+applaud/ZGDRS
+applauder/M
+applause/M
+apple/MS
+applejack/M
+applesauce/M
+applet/MS
+appliance/SM
+applicability/M
+applicable/I
+applicably
+applicant/SM
+application/AM
+applicator/SM
+applier/MS
+applique/DSM
+appliqueing
+appliqu辿/SMG
+appliqu辿d
+apply/ANXGDS
+appoint/AELSVGZRD
+appointee/SM
+appointment/AESM
+apportion/AGDLS
+apportionment/AM
+appose/GDS
+apposite/YNVP
+appositeness/M
+apposition/M
+appositive/SM
+appraisal/AMS
+appraise/ADSG
+appraiser/MS
+appreciable/I
+appreciably/I
+appreciate/DSXGNV
+appreciated/U
+appreciation/M
+appreciative/Y
+appreciator/MS
+appreciatory
+apprehend/GDS
+apprehension/MS
+apprehensive/YP
+apprehensiveness/M
+apprentice/DSMG
+apprenticeship/MS
+apprise/GDS
+apprize/GDS
+approach/GBMDS
+approachable/UI
+approbation/EM
+approbations
+appropriate/PYGNXDS
+appropriated/U
+appropriateness/IM
+appropriation/M
+appropriator/SM
+approval/EM
+approvals
+approve/EGDS
+approved/U
+approving/EY
+approx
+approximate/DSXYGN
+approximation/M
+appurtenance/SM
+appurtenant
+apricot/MS
+apron/MS
+apropos
+apse/SM
+apt/IYPT
+apter
+aptitude/SM
+aptness/IM
+aqua/SM
+aquaculture/M
+aqualung/MS
+aquamarine/SM
+aquanaut/MS
+aquaplane/MGDS
+aquarium/MS
+aquatic/SM
+aquatically
+aquatics/M
+aquatint/S
+aquavit/M
+aqueduct/MS
+aqueous
+aquifer/SM
+aquiline
+arXiv/M
+arabesque/MS
+arability/M
+arachnid/MS
+arachnophobia
+arbiter/SM
+arbitrage/MZGDRS
+arbitrager/M
+arbitrageur/SM
+arbitrament/SM
+arbitrarily
+arbitrariness/M
+arbitrary/P
+arbitrate/GNDS
+arbitration/M
+arbitrator/MS
+arbor/MS
+arboreal
+arboretum/SM
+arborvitae/SM
+arbutus/MS
+arc/SMDG
+arcade/MS
+arcane
+arch/PZTGVMDRSY
+archaeoastronomy/M
+archaeologic
+archaeological/Y
+archaeologist/SM
+archaeology/M
+archaeomagnetic
+archaeomagnetism
+archaic
+archaically
+archaism/MS
+archaist/MS
+archangel/MS
+archbishop/SM
+archbishopric/SM
+archdeacon/SM
+archdiocesan
+archdiocese/MS
+archduchess/MS
+archduke/MS
+archenemy/SM
+archeological/Y
+archeologist/SM
+archeology/M
+archer/M
+archery/M
+archetypal
+archetype/MS
+archfiend/MS
+archiepiscopal
+archipelago/MS
+archipelagoes
+architect/SM
+architectonic/S
+architectonics/M
+architectural/Y
+architecture/MS
+architrave/SM
+archival
+archive/DSMG
+archivist/MS
+archness/M
+archway/SM
+arctic/MS
+ardent/Y
+ardor/MS
+arduous/YP
+arduousness/M
+are/SMB
+area/SM
+areal
+aren't
+arena/MS
+areola/S
+areolae
+areolar
+areolate
+argent/M
+arginine
+argon/M
+argosy/SM
+argot/MS
+arguable/IU
+arguably/U
+argue/ZGDRS
+arguer/M
+argument/MS
+argumentation/M
+argumentative/PY
+argumentativeness/M
+argyle/MS
+aria/SM
+arid/Y
+aridity/M
+aright
+arise/GS
+arisen
+aristocracy/SM
+aristocrat/SM
+aristocratic
+aristocratically
+arithmetic/M
+arithmetical/Y
+arithmetician/MS
+ark/SM
+arm's
+arm/EAGDS
+armada/MS
+armadillo/SM
+armament/AEM
+armaments
+armature/MS
+armband/MS
+armchair/MS
+armed/U
+armful/MS
+armhole/SM
+armistice/SM
+armlet/MS
+armload/S
+armor/ZGMDRS
+armored/U
+armorer/M
+armorial
+armory/SM
+armpit/MS
+armrest/SM
+army/SM
+aroma/MS
+aromatherapist/MS
+aromatherapy/M
+aromatic/MS
+aromatically
+arose
+around
+arousal/M
+arouse/GDS
+arpeggio/MS
+arr
+arraign/DGSL
+arraignment/SM
+arrange/AESDLG
+arrangement/AESM
+arranger/SM
+arrant
+arras/MS
+array/EGMDS
+arrears/M
+arrest/AGMDS
+arrestee/S
+arrhythmia/M
+arrhythmic
+arrhythmical
+arrival/MS
+arrive/GDS
+arrogance/M
+arrogant/Y
+arrogate/GNDS
+arrogation/M
+arrow/MS
+arrowhead/MS
+arrowroot/M
+arroyo/MS
+arsed
+arsenal/MS
+arsenic/M
+arsing
+arson/M
+arsonist/SM
+art/SM
+arterial
+arteriole/MS
+arteriosclerosis/M
+artery/SM
+artful/PY
+artfulness/M
+arthritic/MS
+arthritis/M
+arthroplasty
+arthropod/MS
+arthroscope/SM
+arthroscopic
+arthroscopy
+artichoke/SM
+article/MDS
+articulacy/I
+articular
+articulate/YGNPDSX
+articulateness/IM
+articulation/M
+artifact/SM
+artifice/RSMZ
+artificer/M
+artificial/Y
+artificiality/M
+artillery/M
+artilleryman/M
+artillerymen
+artiness/M
+artisan/MS
+artisanal/Y
+artisanship/S
+artist/MS
+artiste/MS
+artistic/I
+artistically
+artistry/M
+artless/PY
+artlessness/M
+artsy/TR
+artwork/MS
+arty/PTR
+arugula
+arum/SM
+aryl/SM
+asap
+asbestos/M
+ascend/AGDS
+ascendance/M
+ascendancy/M
+ascendant/SM
+ascension/MS
+ascent/MS
+ascertain/GDSBL
+ascertainment/M
+ascetic/MS
+ascetically
+asceticism/M
+ascot/MS
+ascribe/GBDS
+ascription/M
+aseptic
+aseptically
+asexual/SY
+asexuality/M
+ash/MDNSG
+ashamed/UY
+ashcan/MS
+ashlar/MS
+ashore
+ashram/MS
+ashtray/SM
+ashy/TR
+aside/MS
+asinine/Y
+asininity/SM
+ask/SDG
+askance
+asked/U
+askew
+aslant
+asleep
+asocial
+asp/SMNX
+asparagus/M
+aspartame/M
+aspect/MS
+aspen/M
+asperity/SM
+aspersion/MS
+asphalt/MDGS
+asphodel/SM
+asphyxia/M
+asphyxiate/DSXGN
+asphyxiation/M
+aspic/MS
+aspidistra/MS
+aspirant/MS
+aspirate/MGNDSX
+aspiration/M
+aspirational/Y
+aspirator/SM
+aspire/GDS
+aspirin/MS
+ass/MS
+assail/GBDS
+assailable/U
+assailant/SM
+assassin/SM
+assassinate/GNXDS
+assassination/M
+assault/MDRGS
+assay/ZGMDRS
+assayer/M
+assemblage/SM
+assemble/ERZGSD
+assembler/EM
+assemblies
+assembly/EAM
+assemblyman/M
+assemblymen
+assemblywoman/M
+assemblywomen
+assent/GMDS
+assert/AGVDS
+assertion/AM
+assertions
+assertive/YP
+assertiveness/M
+assess/ALGDS
+assessment/ASM
+assessor/MS
+asset/MS
+asseverate/DSGN
+asseveration/M
+asshole/MS!
+assiduity/M
+assiduous/PY
+assiduousness/M
+assign's
+assign/ALGDS
+assignable
+assignation/MS
+assigned/U
+assignee/M
+assigner/MS
+assignment/AMS
+assignor/MS
+assimilate/DSGN
+assimilated/U
+assimilation/M
+assist/GVMDS
+assistance/M
+assistant/SM
+assisted/U
+assize/MS
+assn
+assoc
+associate's
+associate/EDSGNV
+association/EM
+associations
+associativity
+assonance/M
+assonant/MS
+assort/GLDS
+assortative
+assortment/MS
+asst
+assuage/GDS
+assume/BGDS
+assumption/SM
+assumptive
+assurance/ASM
+assure/AGDS
+assured/MYS
+astatine/M
+aster/EMS
+asterisk/GMDS
+astern
+asteroid/MS
+asthma/M
+asthmatic/SM
+asthmatically
+astigmatic
+astigmatism/SM
+astir
+astonish/DSLG
+astonishing/Y
+astonishment/M
+astound/GDS
+astounding/Y
+astraddle
+astrakhan/M
+astral
+astray
+astride
+astringency/M
+astringent/SMY
+astroarchaeology/SM
+astrobiology/M
+astrobleme/S
+astrolabe/SM
+astrologer/SM
+astrological/Y
+astrologist/MS
+astrology/M
+astronaut/MS
+astronautic/S
+astronautical
+astronautics/M
+astronomer/SM
+astronomic
+astronomical/Y
+astronomy/M
+astrophysical
+astrophysicist/MS
+astrophysics/M
+astute/PYTR
+astuteness/M
+asunder
+asylum/SM
+asymmetric
+asymmetrical/Y
+asymmetry/SM
+asymptomatic
+asymptote/S
+asymptotic
+asymptotically
+asynchronicity
+asynchronous/Y
+at
+atavism/M
+atavist/SM
+atavistic
+ataxia/M
+ataxic/MS
+ate
+atelier/SM
+atheism/M
+atheist/MS
+atheistic
+atherosclerosis/M
+atherosclerotic
+athirst
+athlete/MS
+athletic/S
+athletically
+athleticism
+athletics/M
+athwart
+atilt
+atishoo
+atlas/MS
+atmosphere/MS
+atmospheric/S
+atmospherically
+atmospherics/M
+atoll/MS
+atom/SM
+atomic
+atomically
+atomize/ZGDRS
+atomizer/M
+atonal/Y
+atonality/M
+atone/LGDS
+atonement/M
+atop
+atria
+atrial
+atrioventricular
+atrium/M
+atrocious/PY
+atrociousness/M
+atrocity/SM
+atrophy/DSMG
+atropine/M
+attach/ALGDS
+attache/BM
+attached/U
+attachment/AM
+attachments
+attach辿/MS
+attack/ZGMDRS
+attacker/M
+attain/AGDS
+attainability/M
+attainable/U
+attainder/M
+attainment/SM
+attar/M
+attempt's
+attempt/ASDG
+attend/SDRZG
+attendance/SM
+attendant/SM
+attended/U
+attendee/SM
+attention/IM
+attentions
+attentive/IPY
+attentiveness/IM
+attenuate/DSGN
+attenuated/U
+attenuation/M
+attest/SDG
+attestation/SM
+attested/U
+attic/SM
+attire/DSMG
+attitude/SM
+attitudinal
+attitudinize/GDS
+attn
+attorney/MS
+attract/SGVDB
+attractant/MS
+attraction/MS
+attractive/UY
+attractiveness/M
+attribute/DSMGNVBX
+attributed/U
+attribution/M
+attributive/MYS
+attrition/M
+attune/DSG
+atty
+atwitter
+atypical/Y
+aubergine/S
+auburn/M
+auction/MDGS
+auctioneer/SM
+audacious/YP
+audaciousness/M
+audacity/M
+audibility/IM
+audible/MS
+audibly/I
+audience/MS
+audio/MS
+audiological
+audiologist/SM
+audiology/M
+audiometer/SM
+audiophile/SM
+audiotape/SM
+audiovisual/S
+audiovisuals/M
+audit/BGMDS
+auditability
+auditee
+audition/SMDG
+auditor/MS
+auditorium/SM
+auditory
+auger/MS
+aught/MS
+augment/DRZGS
+augmentation/MS
+augmentative
+augmenter/M
+augur/GMDS
+augury/SM
+august/PTRY
+augustness/M
+auk/SM
+aunt/SM
+auntie/SM
+aura/MS
+aural/Y
+aurei
+aureola/M
+aureole/SM
+aureus
+auricle/SM
+auricular
+aurora/SM
+auscultate/GNDSX
+auscultation/M
+auspice/SM
+auspicious/IY
+auspiciousness/M
+austere/RYT
+austerity/SM
+austral
+auteur/SM
+authentic/IU
+authentically
+authenticate/XGNDS
+authenticated/U
+authentication/M
+authenticity/M
+author/SMDG
+authoress/MS
+authorial
+authoritarian/MS
+authoritarianism/M
+authoritative/YP
+authoritativeness/M
+authority/SM
+authorization/MS
+authorize/AGDS
+authorized/U
+authorship/M
+autism/M
+autistic
+auto/MS
+autobahn/SM
+autobiographer/SM
+autobiographic
+autobiographical/Y
+autobiography/SM
+autoclave/MS
+autocomplete/S
+autocorrect/SGMD
+autocracy/SM
+autocrat/SM
+autocratic
+autocratically
+autocross
+autodidact/SM
+autograph/MDG
+autographs
+autoimmune
+autoimmunity/M
+automaker/SM
+automata
+automate/GNDS
+automatic/SM
+automatically
+automation/M
+automatism/M
+automatize/GDS
+automaton/SM
+automobile/DSMG
+automotive
+autonomic
+autonomous/Y
+autonomy/M
+autopilot/SM
+autopsy/GDSM
+autosuggestion
+autoworker/MS
+autumn/SM
+autumnal
+aux
+auxiliary/SM
+auxin/M
+av/RZ
+avail/BGMDS
+availability/UM
+available/U
+avalanche/SM
+avant-garde
+avarice/M
+avaricious/Y
+avast
+avatar/MS
+avaunt
+avdp
+ave
+avenge/ZGDRS
+avenger/M
+avenue/MS
+average/MYGDS
+averred
+averring
+averse/XN
+aversion/M
+avert/GDS
+avg
+avian
+aviary/SM
+aviation/M
+aviator/MS
+aviatrices
+aviatrix/MS
+avid/Y
+avidity/M
+avionic/S
+avionics/M
+avitaminosis/M
+avo/S
+avocado/SM
+avocation/MS
+avocational
+avoid/SDGB
+avoidable/U
+avoidably/U
+avoidance/M
+avoidant
+avoirdupois/M
+avouch/DSG
+avow/EDGS
+avowal/ESM
+avowed/Y
+avuncular/Y
+aw
+await/GDS
+awake/GS
+awaken/AGDS
+awakening/SM
+award/GMDS
+awardee/S
+aware/UP
+awareness/UM
+awash
+away
+awe/DSMG
+aweigh
+awesome/YP
+awesomeness/M
+awestruck
+awful/YP
+awfuller
+awfullest
+awfulness/M
+awhile
+awkward/RYPT
+awkwardness/M
+awl/SM
+awn/GJSM
+awning/M
+awoke
+awoken
+awol
+awry
+ax/MDSG
+axe/M
+axial/Y
+axiom/SM
+axiomatic
+axiomatically
+axis/M
+axle/MS
+axletree/SM
+axolotl/SM
+axon/MS
+ayah/M
+ayahs
+ayatollah/M
+ayatollahs
+aye/SM
+azalea/SM
+azimuth/M
+azimuths
+azure/SM
+b/KDT
+baa/SMDG
+babble/MZGDRS
+babbler/M
+babe/SM
+babel/MS
+baboon/MS
+babushka/SM
+baby/TGDRSM
+babyhood/M
+babyish
+babysat
+babysit/S
+babysitter/MS
+babysitting/M
+baccalaureate/SM
+baccarat/M
+bacchanal/MS
+bacchanalia/M
+bacchanalian/MS
+baccy
+bachelor/SM
+bachelorhood/M
+bacillary
+bacilli
+bacillus/M
+back/SJZGMDR
+backache/MS
+backbench/S
+backbit
+backbite/ZGRS
+backbiter/M
+backbitten
+backboard/SM
+backbone/MS
+backbreaking
+backchat
+backcloth
+backcloths
+backcomb/DSG
+backdate/GDS
+backdoor
+backdrop/MS
+backer/M
+backfield/SM
+backfire/MGDS
+backgammon/M
+background/MRZS
+backgrounder/M
+backhand/MDRSZG
+backhanded/Y
+backhander/M
+backhoe/MS
+backing/M
+backlash/MS
+backless
+backlight/MSG
+backlighting/M
+backlit
+backlog/MS
+backlogged
+backlogging
+backpack/ZGMDRS
+backpacker/M
+backpacking/M
+backpedal/SDG
+backrest/SM
+backroom/S
+backscratching/M
+backseat/SM
+backside/SM
+backslapper/SM
+backslapping/M
+backslash/MS
+backslid
+backslide/RSZG
+backslider/M
+backspace/DSMG
+backspin/M
+backsplash/S
+backstab/S
+backstabber/MS
+backstabbing
+backstabby
+backstage/M
+backstair/S
+backstop/SM
+backstopped
+backstopping
+backstory/S
+backstreet/S
+backstretch/MS
+backstroke/MGDS
+backtalk/M
+backtrack/SDG
+backup/MS
+backward/PSY
+backwardness/M
+backwash/M
+backwater/SM
+backwoods/M
+backwoodsman/M
+backwoodsmen
+backyard/SM
+bacon/M
+bacteria/M
+bacterial
+bactericidal
+bactericide/SM
+bacteriologic
+bacteriological
+bacteriologist/SM
+bacteriology/M
+bacterium/M
+bad/MYP
+badass/S
+badder
+baddest
+baddie/M
+baddy/SM
+bade
+badge/MZGRS
+badger/GMD
+badinage/M
+badlands/M
+badman/M
+badmen
+badminton/M
+badmouth/GD
+badmouths
+badness/M
+baffle/MZGDRSL
+bafflement/M
+baffler/M
+bag/SM
+bagatelle/SM
+bagel/MS
+bagful/MS
+baggage/M
+bagged
+baggie/M
+baggily
+bagginess/M
+bagging
+baggy/PTRS
+bagpipe/MZRS
+bagpiper/M
+baguette/MS
+bah
+baht/SM
+bail/SBGMD
+bailey/S
+bailiff/S
+bailiwick/MS
+bailout/SM
+bailsman/M
+bailsmen
+bairn/MS
+bait/SGMD
+baize/M
+bake/DRSMZG
+baked/U
+baker/M
+bakery/SM
+bakeshop/MS
+baklava/M
+baksheesh/M
+balaclava/MS
+balalaika/MS
+balance's
+balance/UDSG
+balancer/S
+balanitis
+balanoposthitis
+balboa/SM
+balcony/SM
+bald/STGPDRY
+balderdash/M
+baldfaced
+baldness/M
+baldric/SM
+baldy/S
+bale/DRSMZG
+baleen/M
+baleful/PY
+balefulness/M
+baler/M
+balk/SGMD
+balkanization
+balkanize/GDS
+balky/RT
+ball/SGMD
+ballad/SM
+balladeer/MS
+balladry/M
+ballast/GSMD
+ballcock/MS
+ballerina/SM
+ballet/SM
+balletic
+ballgame/MS
+ballgirl/S
+ballgown/S
+ballistic/S
+ballistically
+ballistics/M
+balloon/SGMD
+balloonist/MS
+ballot/SMDG
+ballpark/MS
+ballplayer/MS
+ballpoint/MS
+ballroom/MS
+balls/DSG
+ballsy/RT
+bally
+ballyhoo/SMDG
+balm/SM
+balminess/M
+balmy/RTP
+baloney/M
+balsa/MS
+balsam/SM
+balsamic
+baluster/SM
+balustrade/MS
+bamboo/SM
+bamboozle/DSG
+ban/SM
+banal/Y
+banality/SM
+banana/SM
+banc/S
+band's
+band/ESGD
+bandage/DSMG
+bandana/SM
+bandanna/MS
+bandbox/MS
+bandeau/M
+bandeaux
+bandicoot/MS
+bandit/SM
+banditry/M
+bandleader/S
+bandmaster/SM
+bandoleer/SM
+bandolier/SM
+bandsman/M
+bandsmen
+bandstand/SM
+bandwagon/SM
+bandwidth
+bandwidths
+bandy/DRSTG
+bane/SM
+baneful
+bang/SGMDR
+bangle/SM
+bani
+banish/GLDS
+banishment/M
+banister/SM
+banjo/MS
+banjoist/SM
+bank/SZGBMDR
+bankbook/SM
+bankcard/SM
+banker/M
+banking/M
+banknote/SM
+bankroll/SGMD
+bankrupt/SGMD
+bankruptcy/SM
+banned
+banner/SM
+banning
+bannock/MS
+banns/M
+banquet/ZGMDRS
+banqueter/M
+banquette/SM
+banshee/MS
+bantam/SM
+bantamweight/SM
+banter/GSMD
+bantering/Y
+banyan/SM
+banzai/SM
+baobab/SM
+bap/S
+baptism/MS
+baptismal
+baptist/S
+baptistery/SM
+baptistry/SM
+baptize/ZGDRS
+baptized/U
+baptizer/M
+bar's
+bar/ECAUTS
+barb/SZGMDR
+barbacoa
+barbarian/SM
+barbarianism/MS
+barbaric
+barbarically
+barbarism/SM
+barbarity/SM
+barbarize/DSG
+barbarous/Y
+barbecue/DSMG
+barbel/SM
+barbell/MS
+barber/GMD
+barberry/SM
+barbershop/MS
+barbie/S
+barbiturate/SM
+barbwire/M
+barcarole/SM
+barcode/GDS
+bard/SM
+bardic
+bare/DRSPYG
+bareback/D
+barefaced/Y
+barefoot/D
+barehanded
+bareheaded
+barelegged
+bareness/M
+barf/SGMDY
+barfly/SM
+bargain/MDRZGS
+bargainer/M
+barge/MGDS
+bargeman/M
+bargemen
+barhop/S
+barhopped
+barhopping
+barista/MS
+baritone/MS
+barium/M
+bark's
+bark/CSGD
+barkeep/ZMRS
+barkeeper/M
+barker/SM
+barley/M
+barmaid/MS
+barman/M
+barmen
+barmy/RT
+barn/SM
+barnacle/MDS
+barney/S
+barnstorm/SDRZG
+barnstormer/M
+barnyard/SM
+barometer/MS
+barometric
+barometrically
+baron/MS
+baronage/MS
+baroness/MS
+baronet/MS
+baronetcy/SM
+baronial
+barony/SM
+baroque/M
+barque/SM
+barrack/MDGS
+barracuda/SM
+barrage/MGDS
+barre/MGJDS
+barred/UEC
+barrel/GSMD
+barrelled
+barrelling
+barren/TPSMR
+barrenness/M
+barrette/SM
+barricade/MGDS
+barrier/MS
+barring/ECU
+barrio/SM
+barrister/MS
+barroom/MS
+barrow/SM
+bartender/SM
+barter/ZGSMDR
+barterer/M
+baryon/SM
+baryonic
+basal/Y
+basalt/M
+basaltic
+base's
+base/CDSLTG
+baseball/SM
+baseboard/MS
+baseless
+baseline/MS
+basely
+baseman/M
+basemen
+basement/CMS
+baseness/M
+baser
+bash/GMDS
+bashful/PY
+bashfulness/M
+bashing/M
+basic/MS
+basically
+basil/M
+basilar
+basilica/MS
+basilisk/MS
+basin/MS
+basinful/MS
+basis/M
+bask/SGD
+basket/SM
+basketball/MS
+basketry/M
+basketwork/M
+basque/S
+bass/MS
+basset/SM
+bassinet/MS
+bassist/MS
+basso/MS
+bassoon/MS
+bassoonist/SM
+basswood/MS
+bast/M
+bastard/MS
+bastardization/MS
+bastardize/GDS
+bastardy/M
+baste/ZGNXDRS
+baster/M
+bastion/M
+bat/SM
+batch/MDSG
+bate/KACGSD
+bath/ZGMDRS
+bathe/M
+bather/M
+bathetic
+bathhouse/MS
+bathing/M
+bathmat/MS
+bathos/M
+bathrobe/SM
+bathroom/SM
+baths
+bathtub/MS
+bathwater
+bathyscaph/MS
+bathyscaphe/M
+bathyscaphs
+bathysphere/MS
+batik/MS
+batiste/M
+batman/M
+batmen
+baton/MS
+batsman/M
+batsmen
+battalion/SM
+batted
+batten/GSMD
+batter/JZGSMDR
+batterer/M
+battery/SM
+batting/M
+battle/LDRSMZG
+battleax/MS
+battleaxe/M
+battledore/SM
+battledress
+battlefield/MS
+battlefront/MS
+battleground/MS
+battlement/SM
+battler/M
+battleship/SM
+batty/RT
+bauble/SM
+baud/SM
+bauxite/M
+bawd/SM
+bawdily
+bawdiness/M
+bawdy/PRT
+bawl/SGMD
+bay/SMDG
+bayberry/SM
+bayonet/SMDG
+bayou/MS
+bazaar/SM
+bazillion/S
+bazooka/SM
+bbl
+bdrm
+be
+beach/MDSG
+beachcomber/SM
+beachfront
+beachhead/MS
+beachwear/M
+beacon/SM
+bead/SGMD
+beading/M
+beadle/SM
+beady/RT
+beagle/SM
+beak/SZMDR
+beaker/M
+beam/SGMD
+bean/SGMD
+beanbag/MS
+beanfeast/S
+beanie/SM
+beanpole/MS
+beansprout/S
+beanstalk/MS
+bear/SZGBJMR
+bearable/U
+bearably/U
+beard/MDGS
+beardless
+bearer/M
+bearing/M
+bearish/PY
+bearishness/M
+bearlike
+bearskin/MS
+beast/MS
+beastliness/M
+beastly/TPRM
+beat/SZGBMNRJ
+beatable/U
+beaten/U
+beater/M
+beatific
+beatifically
+beatification/M
+beatify/GXNDS
+beating/M
+beatitude/SM
+beatnik/MS
+beau/SM
+beaucoup
+beaut/MS
+beauteous/Y
+beautician/SM
+beautification/M
+beautifier/M
+beautiful/Y
+beautify/NDRSZG
+beauty/SM
+beaux
+beaver/SGMD
+bebop/MS
+becalm/GSD
+became
+because
+beck/SM
+beckon/SGD
+becloud/GDS
+become/S
+becoming/UY
+becquerel/S
+bed/SM
+bedaub/GSD
+bedazzle/GDSL
+bedazzlement/M
+bedbug/SM
+bedchamber/S
+bedclothes/M
+bedded
+bedder
+bedding/M
+bedeck/GSD
+bedevil/LGDS
+bedevilment/M
+bedfellow/SM
+bedhead/S
+bedim/S
+bedimmed
+bedimming
+bedizen/GDS
+bedlam/SM
+bedpan/SM
+bedpost/SM
+bedraggle/GDS
+bedridden
+bedrock/SM
+bedroll/SM
+bedroom/SM
+bedside/SM
+bedsit/S
+bedsitter/S
+bedsore/SM
+bedspread/SM
+bedstead/SM
+bedtime/SM
+bee/RSMZGJ
+beebread/M
+beech/MS
+beechnut/MS
+beef/SGMD
+beefburger/SM
+beefcake/MS
+beefiness/M
+beefsteak/MS
+beefy/RPT
+beehive/MS
+beekeeper/MS
+beekeeping/M
+beeline/MS
+been
+beep/SZGMDR
+beeper/M
+beer/M
+beery/TR
+beeswax/M
+beet/SM
+beetle/MGDS
+beetroot/S
+beeves
+befall/SGN
+befell
+befit/S
+befitted
+befitting/Y
+befog/S
+befogged
+befogging
+before
+beforehand
+befoul/DGS
+befriend/SGD
+befuddle/GLDS
+befuddlement/M
+beg/S
+began
+begat
+beget/S
+begetter/S
+begetting
+beggar/MDYGS
+beggary/M
+begged
+begging
+begin/S
+beginner/SM
+beginning/MS
+begone
+begonia/SM
+begot
+begotten
+begrime/DSG
+begrudge/DSG
+begrudging/Y
+beguile/DRSZGL
+beguilement/M
+beguiler/M
+beguiling/Y
+beguine/SM
+begum/MS
+begun
+behalf/M
+behalves
+behave/GDS
+behavior/SM
+behavioral/Y
+behaviorism/M
+behaviorist/MS
+behead/DGS
+beheld
+behemoth/M
+behemoths
+behest/MS
+behind/MS
+behindhand
+behold/NRZGS
+beholder/M
+behoove/DSG
+beige/M
+being/M
+bejewel/SDG
+belabor/SDG
+belated/Y
+belay/GDS
+belch/ZGMDRS
+belcher/M
+beleaguer/GSD
+belfry/SM
+belie/DS
+belief/EUM
+beliefs
+believable/U
+believably/U
+believe/EDRSZG
+believer/EUMS
+believing/U
+belittle/LDSG
+belittlement/M
+bell/SGMD
+belladonna/M
+bellboy/SM
+belle/MS
+belled/A
+belletrist/MS
+belletristic
+bellhop/SM
+bellicose
+bellicosity/M
+belligerence/M
+belligerency/M
+belligerent/MYS
+belling/A
+bellman/M
+bellmen
+bellow/MDGS
+bellwether/MS
+belly/GDSM
+bellyache/MGDS
+bellybutton/SM
+bellyful/MS
+belong/JDGS
+belonging/M
+beloved/SM
+below
+belt/SGMD
+beltway/SM
+beluga/MS
+belying
+bemire/GDS
+bemoan/DGS
+bemuse/LGDS
+bemused/Y
+bemusement/M
+bench/GMDS
+benchmark/MS
+bend/BSZGMR
+bender/M
+bendy/TR
+beneath
+benedictine
+benediction/SM
+benedictory
+benefaction/SM
+benefactor/MS
+benefactress/MS
+benefice/SM
+beneficence/M
+beneficent/Y
+beneficial/Y
+beneficiary/SM
+benefit/SMDG
+benevolence/SM
+benevolent/Y
+benighted/Y
+benign/Y
+benignant
+benignity/M
+bent/SM
+bentonite
+bentwood/M
+benumb/DSG
+benzene/M
+benzine/M
+benzyl
+bequeath/DG
+bequeaths
+bequest/MS
+berate/GDS
+bereave/DSLG
+bereavement/MS
+bereft
+beret/MS
+berg/SM
+beriberi/M
+berk/S
+berkelium/M
+berm/SM
+berry/GDSM
+berrylike
+berserk
+berth/GMD
+berths
+beryl/MS
+beryllium/M
+beseech/ZGRS
+beseecher/M
+beseeching/Y
+beseem/DSG
+beset/S
+besetting
+beside/S
+besiege/ZGDRS
+besieger/M
+besmear/DSG
+besmirch/GDS
+besom/MS
+besot/S
+besotted
+besotting
+besought
+bespangle/DSG
+bespatter/GSD
+bespeak/SG
+bespectacled
+bespoke
+bespoken
+best/SGMD
+bestial/Y
+bestiality/M
+bestiary/SM
+bestir/S
+bestirred
+bestirring
+bestow/DGS
+bestowal/SM
+bestrew/SDG
+bestrewn
+bestridden
+bestride/SG
+bestrode
+bestseller/MS
+bestselling
+bet/SM
+beta/SM
+betake/GS
+betaken
+betcha
+betel/M
+bethink/SG
+bethought
+betide/GDS
+betimes
+betoken/GDS
+betook
+betray/DRZGS
+betrayal/SM
+betrayer/M
+betroth/DG
+betrothal/SM
+betrothed/M
+betroths
+better/MDGLS
+betterment/M
+betting
+bettor/MS
+between
+betwixt
+bevel/GMDS
+beverage/SM
+bevvy/S
+bevy/SM
+bewail/DGS
+beware/GDS
+bewhiskered
+bewigged
+bewilder/LSGD
+bewildering/Y
+bewilderment/M
+bewitch/GLDS
+bewitching/Y
+bewitchment/M
+bey/SM
+beyond
+bezel/MS
+bf
+bhaji
+bi/SMRZ
+biannual/Y
+bias/GMDS
+biased/U
+biassed
+biassing
+biathlon/SM
+bib/SM
+bible/MS
+biblical/Y
+bibliographer/MS
+bibliographic
+bibliographical/Y
+bibliography/SM
+bibliophile/SM
+bibulous
+bicameral
+bicameralism/M
+bicarb/MS
+bicarbonate/MS
+bicentenary/SM
+bicentennial/SM
+bicep/MS
+biceps/M
+bicker/MDRZGS
+bickerer/M
+biconcave
+biconvex
+bicuspid/MS
+bicycle/DRSMZG
+bicycler/M
+bicyclist/SM
+bid/SMG
+biddable
+bidden/U
+bidder/MS
+bidding/M
+biddy/SM
+bide/S
+bidet/MS
+bidirectional/Y
+biennial/MYS
+biennium/MS
+bier/M
+biff/SGD
+bifida
+bifocal/S
+bifocals/M
+bifurcate/XDSGN
+bifurcation/M
+big/P
+bigamist/SM
+bigamous
+bigamy/M
+bigger
+biggest
+biggie/MS
+biggish
+bighead/SM
+bighearted/P
+bigheartedness/M
+bighorn/SM
+bight/MS
+bigmouth/M
+bigmouths
+bigness/M
+bigot/MDS
+bigotry/SM
+bigwig/MS
+bijection/S
+bijou/M
+bijoux
+bike/DRSMZG
+biker/M
+bikini/MS
+bilabial/MS
+bilateral/Y
+bilberry/S
+bile/M
+bilge/MS
+bilingual/SMY
+bilingualism/M
+bilious/P
+biliousness/M
+bilirubin
+bilk/SZGDR
+bilker/M
+bill/SBJGMD
+billboard/MS
+billet/GMDS
+billfold/SM
+billhook/S
+billiard/S
+billiards/M
+billing/M
+billingsgate/M
+billion/MHS
+billionaire/SM
+billionth/M
+billionths
+billow/GMDS
+billowy
+billy/SM
+billycan/S
+bimbo/MS
+bimetallic/SM
+bimetallism/M
+bimodal
+bimonthly/SM
+bin/SM
+binary/SM
+binaural
+bind's
+bind/AUGS
+binder/MS
+bindery/SM
+binding/MS
+bindweed/M
+binge/MGDS
+bingeable
+bingeing
+bingo/M
+binman
+binmen
+binnacle/SM
+binned
+binning
+binocular/MS
+binomial/SM
+bio/SM
+biochem
+biochemical/SMY
+biochemist/MS
+biochemistry/M
+biocomputing/M
+biodegradability/M
+biodegrade/DSGB
+biodiesel/M
+biodiversity/M
+bioethics/M
+biofeedback/M
+biofilm/MS
+biog
+biograph/ZGMDR
+biographer/M
+biographic
+biographical/Y
+biographs
+biography/SM
+biohacker/MS
+biohacking
+bioinformatic/MS
+biol
+biologic
+biological/Y
+biologist/MS
+biology/SM
+biomarker/MS
+biomass/MS
+biomechanics
+biomedical
+biomedicine
+bionic/S
+bionically
+bionics/M
+biophysical
+biophysicist/MS
+biophysics/M
+biopic/MS
+biopsy/GDSM
+bioreactor/S
+biorhythm/MS
+biorobotics
+biosecurity/M
+biosensor/S
+biosphere/SM
+biostatistics
+biosyntheses
+biosynthesis
+biotech/M
+biotechnological
+biotechnology/SM
+biotherapy/SM
+biotin/M
+biotope/SM
+biozone/SM
+bipartisan
+bipartisanship/M
+bipartite
+biped/MS
+bipedal
+biplane/MS
+bipolar
+bipolarity/M
+biracial
+birch/GMDS
+bird/SZGMDR
+birdbath/M
+birdbaths
+birdbrain/SMD
+birdcage/S
+birder/M
+birdhouse/MS
+birdie/MDS
+birdieing
+birdlike
+birdlime/M
+birdseed/M
+birdsong
+birdwatcher/SM
+birdying
+biretta/SM
+birth/ZGMDR
+birthday/MS
+birther/M
+birthmark/MS
+birthplace/MS
+birthrate/MS
+birthright/MS
+births/A
+birthstone/SM
+biscotti
+biscotto
+biscuit/SM
+bisect/DGS
+bisection/MS
+bisector/SM
+bisexual/MYS
+bisexuality/M
+bishop/MS
+bishopric/SM
+bismuth/M
+bison/M
+bisque/M
+bistro/MS
+bit/CSMG
+bitch/GMDS
+bitchily
+bitchiness/M
+bitchy/PRT
+bitcoin/SM
+bite/RSMZ
+biter/M
+biting/Y
+bitmap/S
+bitten
+bitter/PMRYTS
+bittern/SM
+bitterness/M
+bitters/M
+bittersweet/MS
+bitty/TR
+bitumen/M
+bituminous
+bivalent
+bivalve/SM
+bivouac/MS
+bivouacked
+bivouacking
+biweekly/SM
+biyearly
+biz/M
+bizarre/Y
+bk
+bl/DG
+blab/SM
+blabbed
+blabber/DGS
+blabbermouth/M
+blabbermouths
+blabbing
+black/PXTGMDNRYS
+blackamoor/MS
+blackball/SGMD
+blackberry/GSM
+blackbird/SM
+blackboard/MS
+blackcurrant/S
+blacken/DG
+blackface
+blackguard/SM
+blackhead/MS
+blacking/M
+blackish
+blackjack/MDGS
+blackleg/S
+blacklist/MDSG
+blackmail/MDRSZG
+blackmailer/M
+blackness/M
+blackout/SM
+blacksmith/MG
+blacksmiths
+blacksnake/SM
+blackthorn/SM
+blacktop/SM
+blacktopped
+blacktopping
+bladder/MS
+blade/MDS
+blag/S
+blagged
+blagging
+blah/M
+blahs/M
+blame/BMGDRS
+blameable
+blameless/YP
+blamelessness/M
+blameworthiness/M
+blameworthy/P
+blammo
+blanch/GDS
+blanche
+blancmange/MS
+bland/PTRY
+blandish/DSLG
+blandishment/SM
+blandness/M
+blank/TGPMDRYS
+blanket/GMDS
+blankness/M
+blare/MGDS
+blarney/SMDG
+blase
+blaspheme/ZGDRS
+blasphemer/M
+blasphemous/Y
+blasphemy/SM
+blast/ZGMDRS
+blaster/M
+blastoff/MS
+blas辿
+blat/S
+blatancy/SM
+blatant/Y
+blather/SMDG
+blaze/MZGDRS
+blazer/M
+blazon/MDGS
+bldg
+bleach/MDRSZG
+bleached/U
+bleacher/M
+bleak/TPRY
+bleakness/M
+blear
+blearily
+bleariness/M
+bleary/PRT
+bleat/GMDS
+bleed/ZGRS
+bleeder/M
+bleeding/M
+bleep/ZGMDRS
+bleeper/M
+blemish/GMDS
+blemished/U
+blench/DSG
+blend/ZGMDRS
+blender/M
+bless/GDSJ
+blessed/YP
+blessedness/M
+blessing/M
+bletch
+blew
+blight/ZGMDRS
+blimey
+blimp/MS
+blimpish
+blind/PZTGMDRYS
+blinder/M
+blindfold/SMDG
+blinding/Y
+blindness/M
+blindside/DSG
+blini/MS
+blink/ZGMDRS
+blinker/MDG
+blintz/MS
+blintze/M
+blip/SM
+bliss/M
+blissful/YP
+blissfulness/M
+blister/GMDS
+blistering/Y
+blistery
+blithe/PYTR
+blitheness/M
+blither/G
+blithesome
+blitz/GMDS
+blitzkrieg/MS
+blivet/S
+blizzard/SM
+bloat/ZGDRS
+bloatware
+blob/SM
+blobbed
+blobbing
+bloc/SM
+block's
+block/UGDS
+blockade/MZGDRS
+blockader/M
+blockage/MS
+blockbuster/SM
+blockbusting/M
+blockchain/MS
+blocker/MS
+blockhead/SM
+blockhouse/MS
+blog/SM
+blogged
+blogger/MS
+blogging
+blogroll/SM
+bloke/MS
+blokish
+blond/PTMRS
+blonde/MS
+blondish
+blondness/M
+blood/GMDS
+bloodbath/M
+bloodbaths
+bloodcurdling
+bloodhound/SM
+bloodily
+bloodiness/M
+bloodless/YP
+bloodlessness/M
+bloodletting/M
+bloodline/SM
+bloodmobile/MS
+bloodshed/M
+bloodshot
+bloodstain/SMD
+bloodstock/M
+bloodstream/SM
+bloodsucker/SM
+bloodsucking
+bloodthirstily
+bloodthirstiness/M
+bloodthirsty/RPT
+bloody/PTGDRS
+bloom/ZGMDRS
+bloomer/M
+bloop/ZGMDRS
+blooper/M
+blossom/GMDS
+blossomy
+blot/SM
+blotch/GMDS
+blotchy/TR
+blotted
+blotter/MS
+blotting
+blotto
+blouse/MGDS
+bloviate/GNDS
+bloviator/MS
+blow/SZGMR
+blower/M
+blowfly/SM
+blowgun/MS
+blowhard/MS
+blowhole/S
+blowjob/SM
+blowlamp/S
+blown
+blowout/SM
+blowpipe/SM
+blowsy/RT
+blowtorch/MS
+blowup/MS
+blowy/TR
+blowzy/RT
+blubber/GSMD
+blubbery
+bludgeon/MDGS
+blue/DRSPMTG
+bluebell/MS
+blueberry/SM
+bluebird/MS
+bluebonnet/SM
+bluebottle/SM
+bluefish/MS
+bluegill/MS
+bluegrass/M
+blueing/M
+blueish
+bluejacket/SM
+bluejay/SM
+bluejeans/M
+blueness/M
+bluenose/MS
+bluepoint/MS
+blueprint/MDGS
+bluestocking/SM
+bluesy/RT
+bluet/MS
+bluff/ZTGPMDRYS
+bluffer/M
+bluffness/M
+bluing/M
+bluish
+blunder/MDRZGS
+blunderbuss/MS
+blunderer/M
+blunt/PTGDRYS
+bluntness/M
+blur/SM
+blurb/MS
+blurred
+blurriness/M
+blurring
+blurry/TRP
+blurt/GDS
+blush/ZGMDRS
+blusher/M
+bluster/MDRSZG
+blusterer/M
+blusterous
+blustery
+blvd
+boa/SM
+boar/SM
+board/ZGMDRS
+boarder/M
+boarding/M
+boardinghouse/MS
+boardroom/MS
+boardwalk/MS
+boast/ZGMDRS
+boaster/M
+boastful/PY
+boastfulness/M
+boat/SZGMDR
+boater/M
+boathouse/MS
+boating/M
+boatload/S
+boatman/M
+boatmen
+boatswain/SM
+boatyard/S
+bob/SM
+bobbed
+bobbin/MS
+bobbing
+bobble/MGDS
+bobby/SM
+bobbysoxer/SM
+bobcat/MS
+bobolink/SM
+bobsled/SM
+bobsledded
+bobsledder/MS
+bobsledding
+bobsleigh/M
+bobsleighs
+bobtail/SM
+bobwhite/MS
+bocce/M
+bocci/M
+boccie/M
+bock/M
+bod/SMDG
+bodacious
+bode/S
+bodega/MS
+bodge/GDS
+bodice/MS
+bodily
+bodkin/MS
+body/DSM
+bodybuilder/SM
+bodybuilding/M
+bodyguard/MS
+bodysuit/SM
+bodywork/M
+boffin/S
+boffo
+bog/SM
+boga
+bogey/GMDS
+bogeyman/M
+bogeymen
+bogged
+bogging
+boggle/GDS
+boggy/TR
+bogie/MS
+bogon
+bogosity
+bogus
+bogyman/M
+bogymen
+bohemian/SM
+bohemianism/M
+boil/SJZGMDR
+boiler/M
+boilermaker/SM
+boilerplate/M
+boink/GDS
+boisterous/YP
+boisterousness/M
+bola/SM
+bold/PTRY
+boldface/DM
+boldness/M
+bole/SM
+bolero/MS
+bolivar/MS
+bolivares
+boll/SM
+bollard/S
+bollix/GMDS
+bollocking/S
+bollocks
+bologna/M
+bolshevik/SM
+bolshie
+bolshy
+bolster/GMDS
+bolt's
+bolt/USGD
+bolthole/S
+bolus/MS
+bomb/SJZGMDR
+bombard/GDLS
+bombardier/MS
+bombardment/SM
+bombast/M
+bombastic
+bombastically
+bomber/M
+bombproof
+bombshell/SM
+bombsite/S
+bon/S
+bona
+bonanza/MS
+bonbon/MS
+bonce/S
+bond/SGMD
+bondage/M
+bondholder/MS
+bonding/M
+bondman/M
+bondmen
+bondsman/M
+bondsmen
+bondwoman/M
+bondwomen
+bone/DRSMZG
+bonehead/SMD
+boneless
+boner/M
+boneshaker/S
+boneyard
+bonfire/MS
+bong/SGMD
+bongo/MS
+bonhomie/M
+boniness/M
+bonito/MS
+bonk/SZGD
+bonnet/MS
+bonny/TR
+bono
+bonobo/MS
+bonsai/M
+bonus/MS
+bony/PTR
+boo/SMDHG
+boob/SGMD
+booboo/MS
+booby/SM
+boodle/MS
+booger/S
+boogeyman/M
+boogeymen
+boogie/MDS
+boogieing
+boogieman/M
+boohoo/GMDS
+book/SBJGMD
+bookbinder/SM
+bookbindery/SM
+bookbinding/M
+bookcase/MS
+bookend/MS
+bookie/MS
+booking/M
+bookish
+bookkeeper/MS
+bookkeeping/M
+booklet/MS
+bookmaker/SM
+bookmaking/M
+bookmark/SMDG
+bookmobile/SM
+bookplate/MS
+bookseller/MS
+bookselling
+bookshelf/M
+bookshelves
+bookshop/SM
+bookstall/S
+bookstore/MS
+bookworm/SM
+boolean
+boom/SZGMDR
+boombox/MS
+boomerang/MDGS
+boon/SM
+boondocks/M
+boondoggle/MZGDRS
+boondoggler/M
+boonies/M
+boor/SM
+boorish/PY
+boorishness/MS
+boost/ZGMDRS
+booster/M
+boot's
+boot/ASGD
+bootblack/SM
+bootee/MS
+booth/M
+booths
+bootie/M
+bootlace/S
+bootleg/MS
+bootlegged
+bootlegger/MS
+bootlegging/M
+bootless
+bootstrap/MS
+bootstrapped
+bootstrapping
+booty/SM
+booze/MZGDRS
+boozer/M
+boozy/TR
+bop/SM
+bopped
+bopping
+borax/M
+bordello/MS
+border/GMDS
+borderland/MS
+borderline/MS
+bore/DRSMZG
+boredom/M
+borehole/S
+borer/M
+boring/Y
+born/IAU
+borne
+boron/M
+borough/M
+boroughs
+borrow/SDRZGJ
+borrower/M
+borrowing/M
+borsch/M
+borscht/M
+borstal/S
+borzoi/SM
+bosh/M
+bosom's
+bosom/US
+bosomy
+boson
+boss/DSGM
+bossily
+bossiness/M
+bossism/M
+bossy/RTP
+bosun/SM
+bot/S
+botanic
+botanical/Y
+botanist/SM
+botany/M
+botch/DRSZGM
+botcher/M
+both
+bother/SMDG
+botheration
+bothered/U
+bothersome
+botnet/SM
+bottle/DRSMZG
+bottleneck/MS
+bottler/M
+bottom/SMDG
+bottomless
+botulinum
+botulism/M
+boudoir/SM
+bouffant/SM
+bougainvillea/MS
+bough/M
+boughs
+bought
+bougie/S
+bouillabaisse/SM
+bouillon/MS
+boulder/SGMR
+boulderer/M
+boules
+boulevard/SM
+bounce/DRSMZG
+bouncer/M
+bouncily
+bounciness/M
+bouncy/RTP
+bound/ASMGD
+boundary/SM
+bounden
+bounder/SM
+boundless/PY
+boundlessness/M
+bounteous/YP
+bounteousness/M
+bountiful/YP
+bountifulness/M
+bounty/SM
+bouquet/SM
+bourbon/SM
+bourgeois/M
+bourgeoisie/M
+boustrophedon
+bout/MS
+boutique/SM
+boutonniere/MS
+boutonni竪re/MS
+bouzouki/MS
+bovine/SM
+bovver
+bow/ZGSMDR
+bowdlerization/MS
+bowdlerize/DSG
+bowed/U
+bowel/SM
+bower/M
+bowl/MDRZGS
+bowleg/SM
+bowlegged
+bowler/M
+bowlful/SM
+bowline/SM
+bowling/M
+bowman/M
+bowmen
+bowsprit/SM
+bowstring/SM
+bowwow/SM
+box/ZGMDNRS
+boxcar/SM
+boxer/M
+boxing/M
+boxlike
+boxroom/S
+boxwood/M
+boxy/RT
+boy/SM
+boycott/SGMD
+boyfriend/MS
+boyhood/SM
+boyish/YP
+boyishness/M
+boysenberry/SM
+bozo/MS
+bpm
+bps
+bra/SM
+brace/MZGDRS
+bracelet/MS
+bracer/M
+bracero/MS
+bracken/M
+bracket/GMDS
+brackish/P
+brackishness/M
+bract/MS
+brad/SM
+bradawl/S
+bradycardia
+brae/SM
+brag/SM
+braggadocio/SM
+braggart/SM
+bragged
+bragger/MS
+bragging
+braid/GMDS
+braiding/M
+braille/M
+brain/GMDS
+brainchild/M
+brainchildren/M
+braininess/M
+brainless/Y
+brainpower
+brainstorm/SMDG
+brainstorming/M
+brainteaser/SM
+brainwash/DSG
+brainwashing/M
+brainwave/S
+brainy/PTR
+braise/GDS
+brake/MGDS
+brakeman/M
+brakemen
+bramble/MS
+brambly
+bran/M
+branch/GMDS
+branchlike
+brand/ZGMDRS
+branded/UA
+brander/M
+brandish/DSG
+brandy/GDSM
+brash/PTRY
+brashness/M
+brass/MS
+brasserie/MS
+brassiere/MS
+brassily
+brassiness/M
+brassy/PTR
+brat/SM
+bratty/RT
+bratwurst/SM
+bravado/M
+brave/GPMYDTRS
+braveness/M
+bravery/M
+bravo/SM
+bravura/SM
+brawl/SDRZGM
+brawler/M
+brawn/M
+brawniness/M
+brawny/RTP
+bray/DGSM
+braze/DRSZG
+brazen/SDYGP
+brazenness/M
+brazer/M
+brazier/SM
+breach/GMDS
+bread/GMDHS
+breadbasket/SM
+breadboard/SM
+breadbox/MS
+breadcrumb/MS
+breadfruit/SM
+breadline/MS
+breadth/M
+breadths
+breadwinner/SM
+break/BMZGRS
+breakable/MS
+breakage/MS
+breakaway/MS
+breakdown/MS
+breaker/M
+breakeven/M
+breakfast/MDGS
+breakfront/MS
+breakneck
+breakout/MS
+breakpoints
+breakthrough/M
+breakthroughs
+breakup/SM
+breakwater/SM
+bream/MS
+breast/SMDG
+breastbone/MS
+breastfed
+breastfeed/GS
+breastplate/SM
+breaststroke/SM
+breastwork/MS
+breath/MDRSZGB
+breathalyze/ZGDRS
+breathe
+breather/M
+breathing/M
+breathless/PY
+breathlessness/M
+breaths
+breathtaking/Y
+breathy/RT
+bred/I
+breech/MS
+breed/SRZGM
+breeder/M
+breeding/IM
+breeze/DSMG
+breezeway/SM
+breezily
+breeziness/M
+breezy/RTP
+brethren
+breve/SM
+brevet/SM
+brevetted
+brevetting
+breviary/SM
+brevity/M
+brew/MDRZGS
+brewer/M
+brewery/SM
+brewpub/SM
+briar/SM
+bribe/DRSMZG
+briber/M
+bribery/M
+brick/SMDG
+brickbat/SM
+brickie/S
+bricklayer/MS
+bricklaying/M
+brickwork/M
+brickyard/S
+bridal/SM
+bride/SM
+bridegroom/SM
+bridesmaid/MS
+bridesman/M
+bridesmen
+bridge/DSMG
+bridgeable/U
+bridgehead/SM
+bridgework/M
+bridle/DSMG
+bridled/U
+bridleway/S
+brie/MZR
+brief's
+brief/CSDTGJ
+briefcase/SM
+briefer
+briefing/CM
+briefly
+briefness/M
+brier/M
+brig/MS
+brigade/SM
+brigadier/MS
+brigand/SM
+brigandage/M
+brigantine/MS
+bright/SPNRYXT
+brighten/DRZG
+brightener/M
+brightness/M
+brights/M
+brill
+brilliance/M
+brilliancy/M
+brilliant/MYS
+brilliantine/M
+brim/MS
+brimful
+brimless
+brimmed
+brimming
+brimstone/M
+brindle/DM
+brine/M
+bring/SRZG
+bringer/M
+brininess/M
+brink/SM
+brinkmanship/M
+briny/RTP
+brioche/SM
+briquet/SM
+briquette/MS
+brisk/SDRYTGP
+brisket/SM
+briskness/M
+bristle/DSMG
+bristly/TR
+britches/M
+brittle/PRMT
+brittleness/M
+bro/SMH
+broach/MDSG
+broad/SMNRYXTP
+broadband/M
+broadcast/AMDGS
+broadcaster/MS
+broadcasting/M
+broadcloth/M
+broaden/DG
+broadloom/M
+broadminded
+broadness/M
+broadsheet/SM
+broadside/MGDS
+broadsword/SM
+brocade/DSMG
+broccoli/M
+brochette/SM
+brochure/MS
+brogan/SM
+brogue/SM
+broil/SMDRZG
+broiler/M
+broke
+broken/YP
+brokenhearted/Y
+brokenness/M
+broker/SMDG
+brokerage/MS
+brolly/S
+bromide/SM
+bromidic
+bromine/M
+bronc/SM
+bronchi
+bronchial
+bronchitic
+bronchitis/M
+bronchus/M
+bronco/SM
+broncobuster/SM
+brontosaur/MS
+brontosaurus/MS
+bronze/DSMG
+brooch/MS
+brood/SMDRZG
+brooder/M
+broodily
+brooding/MY
+broodmare/MS
+broody/RMPT
+brook/SMDG
+brooklet/SM
+broom/SM
+broomstick/MS
+broth/MRZ
+brothel/MS
+brother/MY
+brotherhood/MS
+brotherliness/M
+broths
+brougham/SM
+brought
+brouhaha/SM
+brow/MS
+browbeat/SNG
+brown/SMDRPTG
+brownfield
+brownie/MS
+brownish
+brownness/M
+brownout/SM
+brownstone/MS
+browse/DRSMZG
+browser/M
+brr
+bruin/SM
+bruise/DRSMZG
+bruiser/M
+bruising/M
+bruit/SDG
+brunch/MDSG
+brunet/SM
+brunette/MS
+brunt/M
+brush/MDSG
+brushoff/SM
+brushstroke/S
+brushwood/M
+brushwork/M
+brusque/RPYT
+brusqueness/M
+brutal/Y
+brutality/SM
+brutalization/M
+brutalize/GDS
+brute/SM
+brutish/PY
+brutishness/M
+bu
+bub/SM
+bubble/DSMG
+bubblegum/M
+bubbly/RMT
+bubo/M
+buboes
+bubonic
+buccaneer/SGMD
+buck/MDGS
+buckaroo/SM
+buckboard/MS
+bucket/SGMD
+bucketful/MS
+buckeye/MS
+buckle's
+buckle/UDSG
+buckler/MS
+buckram/M
+bucksaw/MS
+buckshot/M
+buckskin/MS
+buckteeth
+bucktooth/MD
+buckwheat/M
+buckyball/SM
+bucolic/MS
+bucolically
+bud/SM
+budded
+budding/S
+buddy/SM
+budge/DSG
+budgerigar/MS
+budget/SGMD
+budgetary
+budgie/SM
+buff/AMDGS
+buffalo/MDG
+buffaloes
+buffer/SMDG
+buffet/SMDGJ
+buffoon/SM
+buffoonery/M
+buffoonish
+bug's
+bug/CS
+bugaboo/SM
+bugbear/SM
+bugged/C
+bugger/SMDG
+buggery
+bugging/C
+buggy/RSMT
+bugle/DRSMZG
+bugler/M
+build/SMRZGJ
+builder/M
+building/M
+buildup/SM
+built/AI
+builtin
+bulb/MS
+bulbous
+bulge/DSMG
+bulgy/RT
+bulimarexia/M
+bulimia/M
+bulimic/SM
+bulk/MDGS
+bulkhead/MS
+bulkiness/M
+bulky/RTP
+bull/MDGS
+bulldog/SM
+bulldogged
+bulldogging
+bulldoze/ZGDRS
+bulldozer/M
+bullet/SMD
+bulletin/MDGS
+bulletproof/SDG
+bullfight/SMRZG
+bullfighter/M
+bullfighting/M
+bullfinch/MS
+bullfrog/MS
+bullhead/MDS
+bullheaded/PY
+bullheadedness/M
+bullhorn/MS
+bullion/M
+bullish/YP
+bullishness/M
+bullock/SM
+bullpen/SM
+bullring/MS
+bullseye/S
+bullshit/MS!
+bullshitted/!
+bullshitter/SM!
+bullshitting/!
+bullwhip/S
+bully/DSMG
+bulrush/MS
+bulwark/MS
+bum/SM
+bumbag/S
+bumble/DRSZG
+bumblebee/SM
+bumbler/M
+bumf
+bummed
+bummer/SM
+bummest
+bumming
+bump/MDRZGS
+bumper/M
+bumph
+bumpiness/M
+bumpkin/MS
+bumptious/PY
+bumptiousness/M
+bumpy/PRT
+bun/SM
+bunch/MDSG
+bunchy/RT
+bunco/SMDG
+buncombe/M
+bundle/DSMG
+bung/MDGS
+bungalow/MS
+bungee/SM
+bunghole/MS
+bungle/DRSMZG
+bungler/M
+bunion/SM
+bunk's
+bunk/CDGS
+bunker/SM
+bunkhouse/SM
+bunko/SMDG
+bunkum/M
+bunny/SM
+bunt/MDGSJ
+bunting/M
+buoy/MDGS
+buoyancy/M
+buoyant/Y
+bupkis
+bur/SMY
+burble/DSMG
+burbs/M
+burden's
+burden/USGD
+burdensome
+burdock/M
+bureau/SM
+bureaucracy/SM
+bureaucrat/MS
+bureaucratic
+bureaucratically
+bureaucratization/M
+bureaucratize/GDS
+burg/MRZS
+burgeon/DSG
+burger/M
+burgh/MRZ
+burgher/M
+burghs
+burglar/MS
+burglarize/GDS
+burglarproof
+burglary/SM
+burgle/DSG
+burgomaster/SM
+burgundy/SM
+burial/ASM
+burka/SM
+burl/MDS
+burlap/M
+burlesque/MGDS
+burliness/M
+burly/RPT
+burn/MDRZGSB
+burnable/SM
+burner/M
+burnish/ZGMDRS
+burnisher/M
+burnoose/MS
+burnous/MS
+burnout/MS
+burnt
+burp/MDGS
+burr/MDGS
+burrito/MS
+burro/SM
+burrow/SMDRZG
+burrower/M
+bursa/M
+bursae
+bursar/SM
+bursary/SM
+bursitis/M
+burst/SMG
+bury/ADSG
+bus/AMS
+busboy/SM
+busby/SM
+bused
+busgirl/MS
+bush/MDSGJ
+bushel/SGMD
+bushiness/M
+bushing/M
+bushman/M
+bushmaster/SM
+bushmen
+bushwhack/DRSZG
+bushwhacker/M
+bushy/RPT
+busily
+business/MS
+businesslike
+businessman/M
+businessmen
+businessperson/SM
+businesswoman/M
+businesswomen
+busing/M
+busk/DRZGS
+buskin/SM
+busload/S
+buss/MDSG
+bust/MDRZGS
+buster/M
+bustle/DSMG
+busty/RZT
+busy/DRSTGP
+busybody/SM
+busyness/M
+busywork/M
+but/ACS
+butane/M
+butch/MRSZ
+butcher/MDG
+butchery/SM
+butler/SM
+butt/MDRZGS
+butte/SM
+butted/A
+butter/MDG
+butterball/MS
+buttercream
+buttercup/SM
+butterfat/M
+butterfingered
+butterfingers/M
+butterfly/GDSM
+buttermilk/M
+butternut/SM
+butterscotch/M
+buttery/TRSM
+butting/A
+buttock/SM
+button's
+button/USDG
+buttonhole/DSMG
+buttonwood/MS
+buttress/MDSG
+butty/S
+buxom
+buy/ZGSMR
+buyback/SM
+buyer/M
+buyout/SM
+buzz/MDRSZG
+buzzard/MS
+buzzer/M
+buzzkill/SM
+buzzword/SM
+bx
+bxs
+by/M
+bye/SM
+bygone/SM
+bylaw/SM
+byline/SM
+bypass/GMDS
+bypath/M
+bypaths
+byplay/M
+byproduct/MS
+byre/S
+byroad/SM
+bystander/MS
+byte/MS
+byway/SM
+byword/SM
+byzantine
+c/IES
+cDNA
+ca
+cab/SMRZ
+cabal/MS
+cabala/M
+caballero/MS
+cabana/SM
+cabaret/SM
+cabbage/MS
+cabbed
+cabbie/M
+cabbing
+cabby/SM
+cabdriver/SM
+cabin/MS
+cabinet/SM
+cabinetmaker/MS
+cabinetmaking/M
+cabinetry/M
+cabinetwork/M
+cable/MGDS
+cablecast/GMS
+cablegram/MS
+cabochon/SM
+caboodle/M
+caboose/SM
+cabriolet/SM
+cabstand/SM
+cacao/MS
+cache/MGDS
+cachepot/SM
+cachet/MS
+cackle/MZGDRS
+cackler/M
+cacophonous
+cacophony/SM
+cacti
+cactus/M
+cad/SM
+cadaver/SM
+cadaverous
+caddie/MDS
+caddish/YP
+caddishness/M
+caddying
+cadence/DSM
+cadenza/SM
+cadet/MS
+cadge/ZGDRS
+cadger/M
+cadmium/M
+cadre/MS
+caducei
+caduceus/M
+caesarean/MS
+caesura/SM
+cafe/SM
+cafeteria/MS
+cafetiere/S
+caff/CS
+caffeinated
+caffeine/M
+caftan/MS
+caf辿/SM
+cage/DSMG
+cagey
+cagier
+cagiest
+cagily
+caginess/M
+cagoule/S
+cahoot/MS
+caiman/MS
+cairn/MS
+caisson/SM
+caitiff/SM
+cajole/ZGLDRS
+cajolement/M
+cajoler/M
+cajolery/M
+cake/DSMG
+cakewalk/SM
+cal
+calabash/MS
+calaboose/SM
+calamari/SM
+calamine/M
+calamitous/Y
+calamity/SM
+calcareous
+calciferous
+calcification/M
+calcify/GNDS
+calcimine/DSMG
+calcine/DSG
+calcite/M
+calcium/M
+calculable/I
+calculate/AGNVDSX
+calculated/Y
+calculating/Y
+calculation/AM
+calculator/SM
+calculi
+calculus/M
+caldera/SM
+caldron/SM
+calendar/MDGS
+calf/M
+calfskin/M
+caliber/SM
+calibrate/GNDSX
+calibration/M
+calibrator/SM
+calico/MS
+calicoes
+californium/M
+caliper/SGMD
+caliph/M
+caliphate/MS
+caliphs
+calisthenic/S
+calisthenics/M
+calk/SGMD
+call/ASGMD
+calla/MS
+callable
+callback/MS
+called/U
+caller/MS
+calligrapher/SM
+calligraphic
+calligraphist/MS
+calligraphy/M
+calling/SM
+calliope/MS
+callosity/SM
+callous/PGDSY
+callousness/M
+callow/RPT
+callowness/M
+callus/MDSG
+calm/PSTGMDRY
+calmness/M
+caloric
+calorie/MS
+calorific
+calumet/MS
+calumniate/GNDS
+calumniation/M
+calumniator/MS
+calumnious
+calumny/SM
+calve/GDS
+calypso/MS
+calyx/MS
+cam/SM
+camaraderie/M
+camber/MDSG
+cambial
+cambium/SM
+cambric/M
+camcorder/SM
+came
+camel/MS
+camelhair/M
+camellia/MS
+cameo/MS
+camera/MS
+cameraman/M
+cameramen
+camerapeople
+cameraperson
+camerawoman/M
+camerawomen
+camerawork
+camiknickers
+camisole/SM
+camomile/SM
+camouflage/MZGDRS
+camouflager/M
+camp's
+camp/CSGD
+campaign/SMDRZG
+campaigner/M
+campanile/SM
+campanologist/MS
+campanology/M
+camper/MS
+campfire/SM
+campground/SM
+camphor/M
+camping/M
+campsite/SM
+campus/MS
+campy/TR
+camshaft/SM
+can't
+can/SMDRZG
+canal/MS
+canalization/M
+canalize/GDS
+canape/MS
+canap辿/MS
+canard/MS
+canary/SM
+canasta/M
+cancan/MS
+cancel/DRSZG
+canceler/M
+cancellation/SM
+cancelled/U
+canceller/M
+cancelling
+cancelous
+cancer/MS
+cancerous
+candelabra/SM
+candelabrum/M
+candid/YP
+candida
+candidacy/SM
+candidate/MS
+candidature/SM
+candidness/M
+candle/MZGDRS
+candlelight/M
+candlelit
+candlepower/M
+candler/M
+candlestick/MS
+candlewick/SM
+candor/M
+candy/GDSM
+candyfloss
+cane/SM
+canebrake/MS
+caner/M
+canine/MS
+canister/SM
+canker/GMDS
+cankerous
+cannabis/MS
+canned
+cannelloni/M
+cannery/SM
+cannibal/SM
+cannibalism/M
+cannibalistic
+cannibalization/M
+cannibalize/GDS
+cannily/U
+canniness/M
+canning
+cannon/GMDS
+cannonade/MGDS
+cannonball/SM
+cannot
+canny/UTR
+canoe/MDS
+canoeing
+canoeist/SM
+canola/M
+canon/MS
+canonical/Y
+canonicalization/MS
+canonicalize/GDS
+canonization/SM
+canonize/DSG
+canoodle/DSG
+canopy/GDSM
+canst
+cant's
+cant/CZRDGS
+cantabile
+cantaloupe/SM
+cantankerous/PY
+cantankerousness/M
+cantata/MS
+canteen/MS
+canter/CM
+cantered
+cantering
+canticle/MS
+cantilever/MDGS
+cantina/S
+canto/MS
+canton/MLS
+cantonal
+cantonment/MS
+cantor/MS
+canvas/MGDS
+canvasback/SM
+canvass/MDRSZG
+canvasser/M
+canyon/MGS
+cap/SMDRBZ
+capabilities
+capability/IM
+capable/I
+capably/I
+capacious/PY
+capaciousness/M
+capacitance/M
+capacities
+capacitor/SM
+capacity/IM
+caparison/MDGS
+cape/SM
+caper/GMD
+capeskin/M
+capillarity/M
+capillary/SM
+capita
+capital/MSY
+capitalism/M
+capitalist/SM
+capitalistic
+capitalistically
+capitalization/M
+capitalize/ADSG
+capitation/CSM
+capitol/SM
+capitulate/ADSXGN
+capitulation/AM
+caplet/MS
+capo/SM
+capon/MS
+capped/UA
+capping/UA
+cappuccino/SM
+caprice/SM
+capricious/PY
+capriciousness/M
+capsicum/SM
+capsize/DSG
+capstan/SM
+capstone/MS
+capsular
+capsule/DSMG
+capsulize/DSG
+capt
+captain/SMDG
+captaincy/SM
+captcha
+caption/SMDG
+captious/YP
+captiousness/M
+captivate/DSGN
+captivation/M
+captivator/SM
+captive/SM
+captivity/SM
+captor/MS
+capture/ADSMG
+car/SMDRZG
+carabiner
+carafe/MS
+caramel/SM
+caramelize/DSG
+carapace/SM
+carat/MS
+caravan/SM
+caravansarai/S
+caravansary/SM
+caravanserai/M
+caravel/SM
+caraway/SM
+carbide/SM
+carbine/SM
+carbohydrate/SM
+carbolic
+carbon/MS
+carbonaceous
+carbonate/MGNDS
+carbonation/M
+carboniferous
+carbonize/GDS
+carborundum/M
+carboxylic
+carboy/MS
+carbs
+carbuncle/SM
+carbuncular
+carburetor/SM
+carcass/MS
+carcinogen/SM
+carcinogenic/MS
+carcinogenicity/M
+carcinoma/MS
+card/ESGMD
+cardamom/SM
+cardamon/S
+cardboard/M
+carder/MS
+cardholder/S
+cardiac
+cardie/S
+cardigan/SM
+cardinal/SMY
+cardinality/S
+cardio
+cardiogram/SM
+cardiograph/M
+cardiographs
+cardiologist/MS
+cardiology/M
+cardiomegaly
+cardiomyopathy
+cardiopulmonary
+cardiovascular
+cardsharp/MRZS
+cardsharper/M
+care/SM
+careen/DGS
+career/MDGS
+careerism
+careerist/SM
+carefree
+careful/YP
+carefuller
+carefullest
+carefulness/M
+caregiver/SM
+careless/PY
+carelessness/M
+carer/M
+caress/MDSG
+caret/MS
+caretaker/MS
+careworn
+carfare/M
+cargo/M
+cargoes
+carhop/MS
+caribou/SM
+caricature/MGDS
+caricaturist/SM
+caries/M
+carillon/SM
+caring/M
+carious
+carjack/JSDRZG
+carjacker/M
+carjacking/M
+carload/SM
+carmaker/S
+carmine/SM
+carnage/M
+carnal/Y
+carnality/M
+carnation/IMS
+carnelian/MS
+carney/MS
+carnie/M
+carnitas
+carnival/MS
+carnivora
+carnivore/SM
+carnivorous/PY
+carnivorousness/M
+carny/SM
+carob/MS
+carol/ZGMDRS
+caroler/M
+carom/GMDS
+carotene/M
+carotid/SM
+carousal/SM
+carouse/DRSMZG
+carousel/SM
+carouser/M
+carp/SZGMDR
+carpal/MS
+carpel/MS
+carpenter/MDGS
+carpentry/M
+carper/M
+carpet/MDGS
+carpetbag/MS
+carpetbagged
+carpetbagger/MS
+carpetbagging
+carpeting/M
+carpi
+carpool/SMDG
+carport/SM
+carpus/M
+carrel/MS
+carriage/SM
+carriageway/S
+carrier/M
+carrion/M
+carrot/MS
+carroty
+carry/ZGDRSM
+carryall/SM
+carrycot/S
+carryout
+carryover/MS
+carsick/P
+carsickness/M
+cart/SZGMDR
+cartage/M
+carte/S
+cartel/MS
+carter/M
+carthorse/SM
+cartilage/SM
+cartilaginous
+cartload/SM
+cartographer/SM
+cartographic
+cartography/M
+carton/MS
+cartoon/SMDG
+cartoonist/MS
+cartridge/MS
+cartwheel/GMDS
+carve/JZGDRS
+carver/M
+carvery/S
+carving/M
+caryatid/MS
+casaba/MS
+cascade/DSMG
+cascara/SM
+case/LDSJMG
+casebook/S
+cased/U
+caseharden/DGS
+casein/M
+caseload/MS
+casement/MS
+casework/ZMR
+caseworker/M
+cash/GMDS
+cashback/M
+cashbook/MS
+cashew/MS
+cashier/GSMD
+cashless
+cashmere/M
+casing/M
+casino/MS
+cask/SM
+casket/MS
+cassava/SM
+casserole/DSMG
+cassette/MS
+cassia/MS
+cassock/SM
+cassowary/SM
+cast/ASGM
+castanet/MS
+castaway/MS
+caste/JMZRS
+castellated
+caster/M
+castigate/DSGN
+castigation/M
+castigator/SM
+casting/AM
+castle/MGDS
+castoff/SM
+castor/MS
+castrate/GNXDS
+castration/M
+casual/PMYS
+casualness/M
+casualty/SM
+casuist/SM
+casuistic
+casuistry/M
+cat/SM
+cataclysm/MS
+cataclysmal
+cataclysmic
+catacomb/SM
+catafalque/MS
+catalepsy/M
+cataleptic/MS
+catalog/ZGSMDR
+cataloger/M
+catalogue/DSMG
+catalogued/U
+catalpa/SM
+catalyses
+catalysis/M
+catalyst/MS
+catalytic/M
+catalyze/GDS
+catamaran/SM
+catapult/GMDS
+cataract/MS
+catarrh/M
+catastrophe/MS
+catastrophic
+catastrophically
+catatonia/M
+catatonic/SM
+catbird/SM
+catboat/SM
+catcall/GSMD
+catch/ZGJLMRS
+catchall/MS
+catcher/M
+catchment/MS
+catchpenny
+catchphrase/SM
+catchword/MS
+catchy/RT
+catechism/SM
+catechist/SM
+catechize/DSG
+categorical/Y
+categorization/MS
+categorize/GDS
+category/SM
+cater/ZGJDRS
+catercorner
+caterer/M
+caterpillar/MS
+caterwaul/SMDG
+catfish/MS
+catgut/M
+catharses
+catharsis/M
+cathartic/SM
+cathedral/SM
+catheter/SM
+catheterize/DSG
+cathode/SM
+cathodic
+catholic
+catholicity/M
+cation/MS
+catkin/MS
+catlike
+catnap/MS
+catnapped
+catnapping
+catnip/M
+catsuit/S
+catsup/MS
+cattail/SM
+catted
+cattery/S
+cattily
+cattiness/M
+catting
+cattle/M
+cattleman/M
+cattlemen
+catty/TPR
+catwalk/SM
+caucus/MDSG
+caudal/Y
+caught/U
+cauldron/MS
+cauliflower/SM
+caulk/ZGMDRS
+caulker/M
+causal/Y
+causality/SM
+causation/M
+causative
+cause/MZGDRS
+causeless
+causer/M
+causerie/SM
+causeway/SM
+caustic/SM
+caustically
+causticity/M
+cauterization/M
+cauterize/GDS
+caution/SMDG
+cautionary
+cautious/IY
+cautiousness/M
+cavalcade/MS
+cavalier/SMY
+cavalry/SM
+cavalryman/M
+cavalrymen
+cave/DRSMZG
+caveat/MS
+caveman/M
+cavemen
+cavern/MS
+cavernous/Y
+caviar/M
+cavil/ZGJMDRS
+caviler/M
+caving/M
+cavitation
+cavity/FSM
+cavort/DGS
+caw/SMDG
+cay/CSM
+cayenne/M
+cayuse/MS
+cc
+cease/CMGDS
+ceasefire/MS
+ceaseless/YP
+ceaselessness/M
+ceca
+cecal
+cecum/M
+cedar/MS
+cede/FAGSD
+ceder/MS
+cedilla/SM
+ceilidh
+ceilidhs
+ceiling/MS
+celandine/M
+celeb/S
+celebrant/SM
+celebrate/DSGNX
+celebration/M
+celebrator/SM
+celebratory
+celebrity/SM
+celeriac
+celerity/M
+celery/M
+celesta/MS
+celestial/Y
+celibacy/M
+celibate/MS
+cell/SMD
+cellar/MS
+cellist/SM
+cellmate/SM
+cello/MS
+cellophane/M
+cellphone/MS
+cellular/SM
+cellulite/M
+cellulitis
+celluloid/M
+cellulose/M
+cement/MDRZGS
+cementer/M
+cementum/M
+cemetery/SM
+cenobite/MS
+cenobitic
+cenotaph/M
+cenotaphs
+censer/MS
+censor/MDGS
+censored/U
+censorial
+censorious/PY
+censoriousness/M
+censorship/M
+censure/BDRSMZG
+censurer/M
+census/MDSG
+cent/SZMR
+centaur/SM
+centavo/SM
+centenarian/MS
+centenary/SM
+centennial/MYS
+center/MDG
+centerboard/SM
+centerfold/MS
+centerpiece/MS
+centigrade
+centigram/SM
+centiliter/MS
+centime/SM
+centimeter/MS
+centipede/SM
+central/SMY
+centralism
+centralist
+centrality/M
+centralization/CM
+centralize/CGDS
+centralizer/MS
+centrifugal/Y
+centrifuge/DSMG
+centripetal/Y
+centrism/M
+centrist/MS
+centurion/SM
+century/SM
+cephalic
+ceramic/SM
+ceramicist/SM
+ceramics/M
+ceramist/MS
+cereal/MS
+cerebellar
+cerebellum/SM
+cerebra
+cerebral
+cerebrate/GNDS
+cerebration/M
+cerebrovascular
+cerebrum/MS
+cerement/MS
+ceremonial/SMY
+ceremonious/UY
+ceremoniousness/M
+ceremony/SM
+cerevisiae/MS
+cerise/M
+cerium/M
+cermet/M
+cert/S
+certain/UY
+certainty/USM
+certifiable
+certifiably
+certificate/MGDS
+certification/AMS
+certify/CDSNXG
+certitude/IM
+certitudes
+cerulean/M
+cervical
+cervices
+cervix/M
+cesarean/MS
+cesium/M
+cessation/MS
+cession/KAFSM
+cesspit/S
+cesspool/MS
+cetacean/MS
+ceteris
+cf
+cg
+ch/IFVT
+chad/S
+chafe/GDS
+chaff/GMDS
+chaffinch/MS
+chagrin/GSMD
+chain's
+chain/UGDS
+chainsaw/MDGS
+chair/GMDS
+chairlift/MS
+chairman/M
+chairmanship/SM
+chairmen
+chairperson/SM
+chairwoman/M
+chairwomen
+chaise/MS
+chalcedony/M
+chalet/MS
+chalice/SM
+chalk/GMDS
+chalkboard/SM
+chalkiness/M
+chalky/PRT
+challenge/DRSMZG
+challenged/U
+challenger/M
+challis/M
+chamber/SMD
+chamberlain/MS
+chambermaid/MS
+chambray/M
+chameleon/SM
+chamois/M
+chamomile/MS
+champ/ZGMDS
+champagne/MS
+champertous
+champerty
+champion/GMDS
+championship/MS
+chance/MGDS
+chancel/SM
+chancellery/SM
+chancellor/MS
+chancellorship/M
+chancery/SM
+chanciness/M
+chancre/SM
+chancy/PRT
+chandelier/SM
+chandler/MS
+change/MZGDRS
+changeability/M
+changeable/P
+changeableness/M
+changeably
+changed/U
+changeless/Y
+changeling/SM
+changeover/SM
+changer/M
+changing/U
+channel/GSMD
+channelization/M
+channelize/DSG
+chanson/SM
+chant/ZGMDRS
+chanter/M
+chanteuse/MS
+chantey/SM
+chanticleer/MS
+chaos/M
+chaotic
+chaotically
+chap/SM
+chaparral/SM
+chapati/S
+chapatti/S
+chapbook/MS
+chapeau/SM
+chapel/MS
+chaperon/MDGS
+chaperonage/M
+chaperone/SM
+chaperoned/U
+chaplain/MS
+chaplaincy/SM
+chaplet/SM
+chapped
+chapping
+chappy/S
+chapter/SM
+char/SM
+charabanc/MS
+character/MS
+characterful
+characteristic/SM
+characteristically/U
+characterization/MS
+characterize/DSG
+characterless
+charade/SM
+charbroil/GDS
+charcoal/MS
+charcuterie
+chard/M
+chardonnay/SM
+charge/AESDGM
+chargeable/A
+charged/U
+charger/SM
+charily
+chariness/M
+chariot/SM
+charioteer/MS
+charisma/M
+charismatic/MS
+charitable/P
+charitableness/M
+charitably/U
+charity/SM
+charlady/S
+charlatan/SM
+charlatanism/M
+charlatanry/M
+charlie/S
+charm/ZGMDRS
+charmer/M
+charming/Y
+charmless
+charred
+charring
+chart/GMDS
+charted/U
+charter's
+charter/ASGD
+charterer/MS
+chartreuse/M
+charwoman/M
+charwomen
+chary/TRP
+chase/MZGDRS
+chaser/M
+chasm/MS
+chassis/M
+chaste/PYTR
+chasten/DGS
+chasteness/M
+chastise/DRSZGL
+chastisement/SM
+chastiser/M
+chastity/M
+chasuble/SM
+chat/SM
+chateau/SM
+chateaux
+chatelaine/SM
+chatline/S
+chatroom/M
+chatted
+chattel/MS
+chatter/MDRZGS
+chatterbox/MS
+chatterer/M
+chattily
+chattiness/M
+chatting
+chatty/TPR
+chauffeur/GMDS
+chauvinism/M
+chauvinist/SM
+chauvinistic
+chauvinistically
+cheap/PXTNRY
+cheapen/DG
+cheapness/M
+cheapo
+cheapskate/MS
+cheat/ZGMDRS
+cheater/M
+check's/A
+check/UAGDS
+checkbook/SM
+checkbox
+checker/MDGS
+checkerboard/SM
+checkers/M
+checklist/MS
+checkmate/MGDS
+checkoff/SM
+checkout/SM
+checkpoint/SM
+checkroom/MS
+checksum
+checkup/MS
+cheddar/M
+cheek/GMDS
+cheekbone/SM
+cheekily
+cheekiness/M
+cheeky/TPR
+cheep/GMDS
+cheer/ZGMDRS
+cheerer/M
+cheerful/YP
+cheerfuller
+cheerfullest
+cheerfulness/M
+cheerily
+cheeriness/M
+cheerio/MS
+cheerleader/SM
+cheerless/PY
+cheerlessness/M
+cheery/TPR
+cheese/MGDS
+cheeseboard/S
+cheeseburger/SM
+cheesecake/SM
+cheesecloth/M
+cheeseparing/M
+cheesiness/M
+cheesy/TPR
+cheetah/M
+cheetahs
+chef/SM
+chem
+chemical/SMY
+chemise/MS
+chemist/MS
+chemistry/SM
+chemo/M
+chemotherapeutic
+chemotherapy/M
+chemurgy/M
+chenille/M
+cherish/DSG
+cheroot/MS
+cherry/SM
+chert/M
+cherub/MS
+cherubic
+cherubim
+chervil/M
+chess/M
+chessboard/MS
+chessman/M
+chessmen
+chest/MDS
+chesterfield/SM
+chestful/SM
+chestnut/SM
+chesty/TR
+chevalier/SM
+cheviot/M
+chevron/MS
+chew/SBZGMDR
+chewer/M
+chewiness/M
+chewy/PTR
+chg
+chge
+chi/SM
+chiaroscuro/M
+chic/PTMR
+chicane/MS
+chicanery/SM
+chichi/MS
+chick/XMNS
+chickadee/SM
+chicken/MDG
+chickenfeed/M
+chickenhearted
+chickenpox/M
+chickenshit/MS!
+chickpea/SM
+chickweed/M
+chicle/M
+chicness/M
+chicory/SM
+chide/GDS
+chiding/Y
+chief/TMRYS
+chiefdom/M
+chieftain/MS
+chieftainship/SM
+chiffon/M
+chiffonier/MS
+chigger/MS
+chignon/MS
+chihuahua/SM
+chilblain/SM
+child/M
+childbearing/M
+childbirth/M
+childbirths
+childcare/M
+childhood/SM
+childish/YP
+childishness/M
+childless/P
+childlessness/M
+childlike
+childminder/S
+childminding
+childproof/GSD
+children/M
+chili/M
+chilies
+chill/JPZTGMDRS
+chiller/M
+chilliness/M
+chilling/Y
+chillness/M
+chilly/TPR
+chimaera/MS
+chime/MZGDRS
+chimer/M
+chimera/MS
+chimeric
+chimerical
+chimney/MS
+chimp/MS
+chimpanzee/SM
+chin/SM
+china/M
+chinaware/M
+chinchilla/MS
+chine/MS
+chink/GMDS
+chinless
+chinned
+chinning
+chino/MS
+chinstrap/MS
+chintz/M
+chintzy/RT
+chinwag/S
+chip/SM
+chipboard
+chipmunk/SM
+chipolata/S
+chipped
+chipper/MS
+chippie
+chipping/S
+chippy/S
+chiral
+chirality
+chirography/M
+chiropodist/MS
+chiropody/M
+chiropractic/SM
+chiropractor/SM
+chirp/GMDS
+chirpily
+chirpy/PTR
+chirrup/GMDS
+chisel/ZGMDRS
+chiseler/M
+chiselled
+chiseller/MS
+chiselling
+chit/SM
+chitchat/SM
+chitchatted
+chitchatting
+chitin/M
+chitinous
+chitlins/M
+chitosan
+chitterlings/M
+chivalrous/PY
+chivalrousness/M
+chivalry/M
+chive/MS
+chivvy/GDS
+chivy/GDS
+chlamydia/MS
+chlamydiae
+chloral/M
+chlordane/M
+chloride/MS
+chlorinate/GNDS
+chlorination/M
+chlorine/M
+chlorofluorocarbon/SM
+chloroform/SGMD
+chlorophyll/M
+chloroplast/MS
+chm
+choc/S
+chock/GMDS
+chockablock
+chocoholic/SM
+chocolate/MS
+chocolatey
+chocolaty
+choice/MTRS
+choir/MS
+choirboy/MS
+choirmaster/SM
+choke/MZGDRS
+chokecherry/SM
+choker/M
+cholecystectomy
+cholecystitis
+choler/M
+cholera/M
+choleric
+cholesterol/M
+chomp/ZGMDRS
+choose/ZGRS
+chooser/M
+choosiness/M
+choosy/TPR
+chop/SM
+chophouse/SM
+chopped
+chopper/MDGS
+choppily
+choppiness/M
+chopping
+choppy/TPR
+chopstick/SM
+choral/MYS
+chorale/MS
+chord/MS
+chordal
+chordate/SM
+chore/MS
+chorea/M
+choreograph/DRZG
+choreographer/M
+choreographic
+choreographically
+choreographs
+choreography/M
+chorister/SM
+choroid/MS
+chortle/MZGDRS
+chortler/M
+chorus/GMDS
+chose
+chosen
+chow/SGMD
+chowder/MS
+chrism/M
+christen/ASGD
+christening/MS
+christian/U
+christology
+chromatic
+chromatically
+chromatin/M
+chromatography
+chrome/MGDS
+chromium/M
+chromosomal
+chromosome/MS
+chronic
+chronically
+chronicle/DRSMZG
+chronicler/M
+chronograph/M
+chronographs
+chronological/Y
+chronologist/MS
+chronology/SM
+chronometer/SM
+chrysalis/MS
+chrysanthemum/MS
+chub/SM
+chubbiness/M
+chubby/TPR
+chuck/GMDS
+chuckhole/SM
+chuckle/MGDS
+chuffed
+chug/SM
+chugged
+chugging
+chukka/MS
+chum/SM
+chummed
+chummily
+chumminess/M
+chumming
+chummy/PTR
+chump/MS
+chunder/GDS
+chunk/GMDS
+chunkiness/M
+chunky/PTR
+chunter/DGS
+church/MS
+churchgoer/SM
+churchgoing/M
+churchman/M
+churchmen
+churchwarden/MS
+churchwoman
+churchwomen
+churchyard/SM
+churl/MS
+churlish/PY
+churlishness/M
+churn/ZGMDRS
+churner/M
+chute/MS
+chutney/MS
+chutzpah/M
+chyme/M
+chyron/MS
+ch但teau/M
+ch但teaux
+ch但telaine/SM
+ciabatta/SM
+ciao/S
+cicada/MS
+cicatrices
+cicatrix/M
+cicerone/SM
+ciceroni
+cider's
+cider/S
+cigar/MS
+cigarette/MS
+cigarillo/MS
+cilantro/M
+cilia
+cilium/M
+cinch/GMDS
+cinchona/SM
+cincture/SM
+cinder/GMDS
+cine
+cinema/MS
+cinematic
+cinematographer/MS
+cinematographic
+cinematography/M
+cinnabar/M
+cinnamon/M
+cipher's
+cipher/CGDS
+ciphertext/S
+cir
+circa
+circadian
+circle/MGDS
+circlet/MS
+circuit/MDGS
+circuital
+circuitous/YP
+circuitousness/M
+circuitry/M
+circuity/M
+circular/SMY
+circularity/M
+circularize/DSG
+circulate/ADSG
+circulation/SM
+circulatory
+circumcise/XDSGN
+circumcised/U
+circumcision/M
+circumference/MS
+circumferential
+circumflex/MS
+circumlocution/MS
+circumlocutory
+circumnavigate/XGNDS
+circumnavigation/M
+circumpolar
+circumscribe/GDS
+circumscription/MS
+circumspect/Y
+circumspection/M
+circumstance/MGDS
+circumstantial/Y
+circumvent/DSG
+circumvention/M
+circus/MS
+cirque/MS
+cirrhosis/M
+cirrhotic/SM
+cirri
+cirrus/M
+cis
+cisgender/D
+cistern/MS
+cit
+citadel/MS
+citation/AMS
+cite's
+cite/IAGSD
+citified
+citizen/MS
+citizenry/M
+citizenship/M
+citric
+citron/MS
+citronella/M
+citrous
+citrus/MS
+city/SM
+citywide
+civet/MS
+civic/S
+civically
+civics/M
+civil/UY
+civilian/MS
+civility/ISM
+civilization/MS
+civilize/GDS
+civilized/U
+civvies/M
+ck
+cl
+clack/GMDS
+clad/U
+cladding/M
+clade
+claim's
+claim/CKEAGDS
+claimable/AKE
+claimant/MS
+claimed/U
+claimer/ECSM
+clairvoyance/M
+clairvoyant/MS
+clam/SM
+clambake/MS
+clamber/ZGMDRS
+clamberer/M
+clammed
+clammily
+clamminess/M
+clamming
+clammy/PTR
+clamor/GMDS
+clamorous
+clamp/GMDS
+clampdown/MS
+clan/SM
+clandestine/Y
+clang/ZGMDRS
+clangor/M
+clangorous/Y
+clank/GMDS
+clannish/P
+clannishness/M
+clansman/M
+clansmen
+clanswoman
+clanswomen
+clap/SM
+clapboard/MDGS
+clapped
+clapper/MS
+clapperboard/S
+clapping/M
+claptrap/M
+claque/MS
+claret/MS
+clarification/M
+clarify/XDSNG
+clarinet/SM
+clarinetist/SM
+clarinettist/MS
+clarion/MDGS
+clarity/M
+clash/GMDS
+clasp's
+clasp/UGDS
+class/GMDS
+classic/MS
+classical/MY
+classicism/M
+classicist/MS
+classifiable
+classification/CAM
+classifications
+classified's
+classified/U
+classifieds
+classifier/MS
+classify/ACSDGN
+classiness/M
+classism
+classless/P
+classmate/MS
+classroom/MS
+classwork/M
+classy/TRP
+clatter/GMDS
+clausal
+clause/MS
+claustrophobia/M
+claustrophobic
+clavichord/SM
+clavicle/MS
+clavier/MS
+claw's
+claw/CSGD
+clay/M
+clayey
+clayier
+clayiest
+clean/BJPZTGDRYS
+cleaner/M
+cleaning/M
+cleanliness/UM
+cleanly/UTPR
+cleanness/UM
+cleanse/ZGDRS
+cleanser/M
+cleanup/MS
+clear/JPTGMDRYS
+clearance/SM
+clearheaded
+clearing/M
+clearinghouse/SM
+clearness/M
+clearway/S
+cleat/MS
+cleavage/MS
+cleave/ZGDRS
+cleaver/M
+clef/SM
+cleft/MS
+clematis/MS
+clemency/IM
+clement/Y
+clementine/S
+clench/GMDS
+clerestory/SM
+clergy/SM
+clergyman/M
+clergymen
+clergywoman/M
+clergywomen
+cleric/MS
+clerical/Y
+clericalism/M
+clerk/GMDS
+clerkship/M
+clever/PTRY
+cleverness/M
+clevis/MS
+clew/SGMD
+cliche/MDS
+clich辿/MS
+clich辿d
+click/BZGMDRS
+clickbait
+clicker/M
+client/MS
+clientele/MS
+client竪le/MS
+cliff/MS
+cliffhanger/SM
+cliffhanging
+clifftop/S
+clii
+climacteric/M
+climactic
+climate/SM
+climatic
+climatically
+climatologist/SM
+climatology/M
+climax/MDSG
+climb/SMDRZGB
+climber/M
+climbing/M
+clime/SM
+clinch/MDRSZG
+clincher/M
+cling/SMRZG
+clinger/M
+clingfilm
+clingy/RT
+clinic/SM
+clinical/Y
+clinician/SM
+clink/SMDRZG
+clinker/M
+cliometric/S
+cliometrician/MS
+cliometrics/M
+clip/SM
+clipboard/MS
+clipped
+clipper/SM
+clipping/SM
+clique/SM
+cliquey
+cliquish/YP
+cliquishness/M
+clit/SM
+clitoral
+clitorides
+clitoris/MS
+clix
+cloaca/M
+cloacae
+cloak's
+cloak/USDG
+cloakroom/MS
+clobber/SMDG
+cloche/SM
+clock/SMDG
+clockwise
+clockwork/SM
+clod/MS
+cloddish
+clodhopper/MS
+clog's
+clog/US
+clogged/U
+clogging/U
+cloisonne/M
+cloisonn辿/M
+cloister/SMDG
+cloistral
+clomp/SDG
+clonal
+clone/DSMG
+clonidine
+clonk/SMDG
+clop/MS
+clopped
+clopping
+closable/I
+close/DRSMYTGBJP
+closefisted
+closemouthed
+closeness/M
+closeout/MS
+closet/SMDG
+closeup/SM
+closing/M
+closure/ESM
+clot/MS
+cloth/M
+clothe/UDSG
+clotheshorse/MS
+clothesline/SM
+clothespin/SM
+clothier/MS
+clothing/M
+cloths
+clotted
+clotting
+cloture/SM
+cloud/SMDG
+cloudburst/SM
+clouded/U
+cloudiness/M
+cloudless
+cloudy/RPT
+clout/SMDG
+clove/RSMZ
+cloven
+clover/M
+cloverleaf/SM
+cloverleaves
+clown/SMDG
+clownish/YP
+clownishness/M
+cloy/DGS
+cloying/Y
+club/MS
+clubbable
+clubbed
+clubber/S
+clubbing
+clubfeet
+clubfoot/MD
+clubhouse/SM
+clubland
+cluck/SMDG
+clue/MGDS
+clueless
+clump/SMDG
+clumpy/TR
+clumsily
+clumsiness/M
+clumsy/TRP
+clung
+clunk/SMDRZG
+clunker/M
+clunky/TR
+cluster/MDSG
+clutch/GMDS
+clutter's
+clutter/UDSG
+clvi
+clvii
+clxi
+clxii
+clxiv
+clxix
+clxvi
+clxvii
+cm
+cnidarian/MS
+co/ESD
+coach/MDSG
+coachload/S
+coachman/M
+coachmen
+coachwork
+coadjutor/MS
+coagulant/MS
+coagulate/GNDS
+coagulation/M
+coagulator/MS
+coal/MDGS
+coalesce/GDS
+coalescence/M
+coalescent
+coalface/MS
+coalfield/S
+coalition/MS
+coalitionist/MS
+coalmine/S
+coarse/RYTP
+coarsen/SDG
+coarseness/M
+coast/SMDRZG
+coastal
+coaster/M
+coastguard/S
+coastline/MS
+coat/MDGJS
+coating/M
+coatroom/S
+coattail/SM
+coauthor/MDGS
+coax/DRSZG
+coaxer/M
+coaxial/Y
+coaxing/Y
+cob/SM
+cobalt/M
+cobber/S
+cobble/DRSMZG
+cobbler/M
+cobblestone/SM
+cobnut/S
+cobra/SM
+cobweb/SM
+cobwebbed
+cobwebby/RT
+coca/M
+cocaine/M
+cocci/S
+coccus/M
+coccyges
+coccyx/M
+cochineal/M
+cochlea/SM
+cochleae
+cochlear
+cock/MDGS
+cockade/SM
+cockamamie
+cockatiel/MS
+cockatoo/SM
+cockatrice/SM
+cockchafer/S
+cockcrow/SM
+cockerel/SM
+cockeyed
+cockfight/MGS
+cockfighting/M
+cockily
+cockiness/M
+cockle/SM
+cockleshell/SM
+cockney/SM
+cockpit/SM
+cockroach/MS
+cockscomb/SM
+cocksucker/MS!
+cocksure
+cocktail/MS
+cocky/RTP
+coco/MS
+cocoa/SM
+coconut/SM
+cocoon/SMDG
+cod/SM
+coda/MS
+codded
+codding
+coddle/DSG
+code's
+code/CZGDRS
+codebook/M
+codec/SM
+codeine/M
+codependency/M
+codependent/SM
+coder/CM
+codex/M
+codfish/MS
+codger/SM
+codices
+codicil/SM
+codification/M
+codifier/M
+codify/XDRSNZG
+codon/SM
+codpiece/MS
+codswallop
+coed/MS
+coeducation/M
+coeducational
+coefficient/MS
+coelenterate/MS
+coenzyme
+coequal/MYS
+coerce/DRSZGNV
+coercer/M
+coercion/M
+coeval/SMY
+coexist/DSG
+coexistence/M
+coexistent
+coextensive
+coffee/SM
+coffeecake/SM
+coffeehouse/MS
+coffeemaker/SM
+coffeepot/MS
+coffer/SM
+cofferdam/MS
+coffin/SMDG
+cofunction/MS
+cog/SM
+cogency/M
+cogent/Y
+cogitate/DSXGNV
+cogitation/M
+cogitator/MS
+cognac/SM
+cognate/MS
+cognition/AM
+cognitional
+cognitive/Y
+cognizable
+cognizance/AM
+cognizant
+cognomen/SM
+cognoscente/M
+cognoscenti
+cogwheel/SM
+cohabit/SGD
+cohabitant/MS
+cohabitation/M
+coheir/SM
+cohere/DSG
+coherence/IM
+coherency/M
+coherent/IY
+cohesion/M
+cohesive/YP
+cohesiveness/M
+coho/MS
+cohort/SM
+coif/MDGS
+coiffed
+coiffing
+coiffure/DSMG
+coil's/A
+coil/UADGS
+coin/MDRZGS
+coinage/SM
+coincide/DSG
+coincidence/MS
+coincident
+coincidental/Y
+coiner/M
+coinsurance/M
+coir
+coital
+coitus/M
+coke/MGDS
+col/S
+cola/MS
+colander/SM
+cold/MRYTPS
+coldblooded
+coldness/M
+coleslaw/M
+coleus/MS
+coley/S
+coli
+colic/M
+colicky
+coliseum/MS
+colitis/M
+coll
+collaborate/DSXGNV
+collaboration/M
+collaborationist
+collaborative/Y
+collaborator/MS
+collage/SM
+collagen
+collapse/MGDS
+collapsible
+collar/SMDG
+collarbone/SM
+collard/SM
+collarless
+collate/DSXGN
+collateral/MY
+collateralize
+collation/M
+collator/MS
+colleague/MS
+collect's
+collect/ASGVD
+collectable/MS
+collected/U
+collectedly
+collectible/SM
+collection/AMS
+collective/MYS
+collectivism/M
+collectivist/SM
+collectivization/M
+collectivize/DSG
+collector/MS
+colleen/SM
+college/SM
+collegial
+collegiality/M
+collegian/MS
+collegiate
+collide/DRSZG
+collie/RSMZ
+collier/M
+colliery/SM
+collimate/DGN
+collinear
+collinearity
+collision/SM
+collocate/MGNDSX
+collocation/M
+colloid/SM
+colloidal
+colloq
+colloquial/Y
+colloquialism/SM
+colloquies
+colloquium/MS
+colloquy/M
+collude/DSG
+collusion/M
+collusive
+colocate/XDSGN
+cologne/SM
+colon/SM
+colonel/SM
+colonelcy/M
+colones
+colonial/SMY
+colonialism/M
+colonialist/MS
+colonist/SM
+colonization/ACM
+colonize/CAGSD
+colonizer/MS
+colonnade/MDS
+colonoscope/MS
+colonoscopy/SM
+colony/SM
+colophon/SM
+color's
+color/AEGDS
+colorant/SM
+coloration/EM
+coloratura/MS
+colorblind/P
+colorblindness/M
+colored's
+colored/U
+coloreds
+colorfast/P
+colorfastness/M
+colorful/PY
+colorfulness/M
+colorimeter/SM
+coloring's
+colorist/S
+colorization/M
+colorize/DSG
+colorless/PY
+colorlessness/M
+colorway/S
+colossal/Y
+colossi
+colossus/M
+colostomy/SM
+colostrum/M
+colt/MS
+coltish
+columbine/SM
+column/SMD
+columnar
+columnist/SM
+com/J
+coma/MS
+comaker/SM
+comatose
+comb/MDRZGJS
+combat/SMDGV
+combatant/SM
+combativeness/M
+combed/U
+comber/M
+combination/SM
+combinatorics
+combine's
+combine/ADSG
+combined/U
+combiner/MS
+combings/M
+combo/SM
+combust/SGVD
+combustibility/M
+combustible/MS
+combustion/M
+come/IMZGRS
+comeback/MS
+comedian/MS
+comedic
+comedienne/MS
+comedown/MS
+comedy/SM
+comeliness/M
+comely/RPT
+comer's
+comestible/SM
+comet/SM
+comeuppance/SM
+comfit's
+comfit/ES
+comfort/ESMDG
+comfortable/P
+comfortableness/M
+comfortably/U
+comforter/MS
+comforting/Y
+comfortless
+comfy/RT
+comic/SM
+comical/Y
+comicality/M
+coming/M
+comity/M
+comm
+comma/SM
+command/SMDRLZG
+commandant/MS
+commandeer/GDS
+commander/M
+commandment/MS
+commando/SM
+commemorate/XGNVDS
+commemoration/M
+commemorator/MS
+commence/ADSLG
+commencement/AM
+commencements
+commend/ASDBG
+commendably
+commendation/AMS
+commendatory
+commensurability
+commensurable
+commensurate/IY
+comment/ZGSMDR
+commentary/SM
+commentate/DSG
+commentator/SM
+commenter/M
+commerce/M
+commercial/SMY
+commercialism/M
+commercialization/M
+commercialize/GDS
+commie/SM
+commingle/DSG
+commiserate/GNVDSX
+commiseration/M
+commissar/SM
+commissariat/SM
+commissary/SM
+commission's
+commission/ACSGD
+commissionaire/S
+commissioner/SM
+commit/AS
+commitment/MS
+committal/SM
+committed/AU
+committee/SM
+committeeman/M
+committeemen
+committeewoman/M
+committeewomen
+committer/S
+committing/A
+commode's
+commode/EIS
+commodification
+commodious/Y
+commoditization
+commodity/SM
+commodore/SM
+common's
+common/UPRYT
+commonality/S
+commonalty/M
+commoner/MS
+commonness/UM
+commonplace/MS
+commons
+commonsense
+commonweal/MH
+commonwealth/M
+commonwealths
+commotion/SM
+communal/Y
+commune/XDSMGN
+communicability/M
+communicable/I
+communicably
+communicant/MS
+communicate/GNVDSX
+communication/M
+communicative/U
+communicator/SM
+communion/M
+communique/SM
+communism/M
+communist/SM
+communistic
+community/SM
+commutation/MS
+commutative
+commutativity
+commutator/SM
+commute/BDRSMZG
+commuter/M
+comorbidity/S
+comp/MDYGS
+compact/TGSMDRYP
+compaction
+compactness/M
+compactor/SM
+companion/SBM
+companionably
+companionship/M
+companionway/MS
+company/SM
+comparability/M
+comparable/I
+comparably/I
+comparative/MYS
+compare/BDSG
+comparison/MS
+compartment/SM
+compartmental
+compartmentalization/M
+compartmentalize/DSG
+compass/GMDS
+compassion/M
+compassionate/UY
+compatibility/ISM
+compatible/IMS
+compatibly/I
+compatriot/MS
+compeer/SM
+compel/S
+compelled
+compelling/Y
+compendious
+compendium/SM
+compensate/DSXGN
+compensated/U
+compensation/M
+compensatory
+compere/DSG
+compete/DSG
+competence/IM
+competences
+competencies
+competency/IM
+competent/IY
+competition/SM
+competitive/PY
+competitiveness/M
+competitor/SM
+compilation/AM
+compilations
+compile/DRSZG
+compiler/M
+complacence/M
+complacency/M
+complacent/Y
+complain/DRZGS
+complainant/MS
+complainer/M
+complaint/SM
+complaisance/M
+complaisant/Y
+complected
+complement/SGMD
+complementarity/SM
+complementary
+complete/PYTGNXDRS
+completed/U
+completeness/IM
+completion/M
+complex/MSY
+complexion/MDS
+complexional
+complexity/SM
+compliance/M
+compliant/Y
+complicate/GDS
+complicated/Y
+complication/M
+complicit
+complicity/M
+compliment/MDGS
+complimentary/U
+comply/NDSXG
+compo
+component/SM
+comport/LSGD
+comportment/M
+compos/RBZ
+compose/AECGSD
+composedly
+composer/M
+composite/MYGNXPDS
+composition/CM
+compositional
+compositor/SM
+compost/SGMD
+composure/EM
+compote/SM
+compound/GMDBS
+compounded/U
+comprehend/SDG
+comprehensibility/IM
+comprehensible/I
+comprehensibly/I
+comprehension/IM
+comprehensions
+comprehensive/PMYS
+comprehensiveness/M
+compress's
+compress/CGVDS
+compressed/U
+compressible
+compression/CMS
+compressor/SM
+comprise/GDS
+compromise/MGDS
+comptroller/MS
+compulsion/MS
+compulsive/YP
+compulsiveness/M
+compulsorily
+compulsory/SM
+compunction/SM
+computation/SM
+computational/Y
+compute/ADSG
+computer/MS
+computerate
+computerization/M
+computerize/GDS
+computing/M
+comp竪re/DSG
+comrade/SMY
+comradery
+comradeship/M
+con/GSM
+concatenate/XDSGN
+concatenation/M
+concave/YP
+concaveness/M
+conceal/SDRZGBL
+concealed/U
+concealer/M
+concealment/M
+conceit/SMD
+conceited/PY
+conceitedness/M
+conceivable/I
+conceivably/I
+conceive/DSGB
+concentrate/DSMGNX
+concentration/M
+concentric
+concentrically
+concept/SM
+conception/SM
+conceptional
+conceptual/Y
+conceptualization/MS
+conceptualize/DSG
+concern/UMD
+concerned/UY
+concerning
+concerns
+concert's
+concert/ESDG
+concerted/Y
+concertgoer/S
+concertina/SGMD
+concertize/DSG
+concertmaster/MS
+concerto/SM
+concessionaire/MS
+concessional
+concessionary
+conch/M
+conchie/S
+conchs
+concierge/MS
+conciliate/DSGN
+conciliation/AM
+conciliator/SM
+conciliatory
+concise/RPYTN
+conciseness/M
+concision/M
+conclave/SM
+conclude/DSG
+conclusion/MS
+conclusive/IYP
+conclusiveness/IM
+concoct/SDG
+concoction/MS
+concomitant/MYS
+concord/M
+concordance/SM
+concordant
+concordat/SM
+concourse/SM
+concrete/DSPMYGNX
+concreteness/M
+concretion/M
+concubinage/M
+concubine/MS
+concupiscence/M
+concupiscent
+concur/S
+concurred
+concurrence/SM
+concurrency
+concurring
+concuss/V
+concussion/SM
+condemn/SDRZG
+condemnation/MS
+condemnatory
+condemner/M
+condensate/MNXS
+condensation/M
+condense/DRSZG
+condenser/M
+condescending/Y
+condescension/M
+condign
+condiment/MS
+condition's
+condition/AGSD
+conditional/SMY
+conditionality
+conditioned/U
+conditioner/SM
+conditioning/M
+condo/SM
+condolence/SM
+condom/SM
+condominium/MS
+condone/DSG
+condor/SM
+conduce/DSGV
+conduct/MDGV
+conductance/M
+conductibility/M
+conductible
+conduction/M
+conductivity/M
+conductor/MS
+conductress/MS
+conduit/SM
+cone/M
+coney/SM
+confab/SM
+confabbed
+confabbing
+confabulate/XDSGN
+confabulation/M
+confection/SZMR
+confectioner/M
+confectionery/SM
+confederacy/SM
+confederate/M
+confer/SB
+conferee/SM
+conference/MGDS
+conferrable
+conferral/M
+conferred
+conferrer/MS
+conferring
+confessed/Y
+confession/SM
+confessional/SM
+confessor/MS
+confetti/M
+confidant/MS
+confidante/SM
+confide/DRSZG
+confidence/SM
+confident/Y
+confidential/Y
+confidentiality/M
+confider/M
+confiding/Y
+configuration/S
+configure/ABD
+confined/U
+confinement/MS
+confirm/ASDG
+confirmation/ASM
+confirmatory
+confirmed/U
+confiscate/DSGNX
+confiscation/M
+confiscator/SM
+confiscatory
+conflagration/MS
+conflate/XDSGN
+conflation/M
+conflict/SGMD
+confluence/MS
+confluent
+conform/ZB
+conformable/U
+conformal
+conformance/M
+conformant
+conformism/M
+conformist/SM
+conformity/M
+confrere/MS
+confrontation/SM
+confrontational
+confr竪re/SM
+confuse/RZ
+confused/Y
+confusing/Y
+confutation/M
+confute/DSG
+conga/SMDG
+congeal/SLDG
+congealment/M
+conger/SM
+congeries/M
+congest/SDGV
+congestion/M
+conglomerate/DSXMGN
+conglomeration/M
+congrats/M
+congratulate/XGNDS
+congratulation/M
+congratulatory
+congregant/MS
+congregate/GNDSX
+congregation/M
+congregational
+congregationalism/M
+congregationalist/MS
+congress/MS
+congressional/Y
+congressman/M
+congressmen
+congresspeople
+congressperson/MS
+congresswoman/M
+congresswomen
+congruence/M
+congruent/IY
+congruity/ISM
+congruous
+conic/SM
+conical/Y
+conifer/SM
+coniferous
+conjectural
+conjecture/MGDS
+conjoint
+conjugal/Y
+conjugate/DSXGN
+conjugation/M
+conjunct/VMS
+conjunctiva/SM
+conjunctive/SM
+conjunctivitis/M
+conjuration/MS
+conjure/DRSZG
+conjurer/M
+conk/MDRZ
+connect/AEDVGS
+connectable
+connected/U
+connection/EMS
+connective/MS
+connectivity/M
+connector/MS
+conned
+conning
+conniption/MS
+connivance/M
+connive/DRSZG
+conniver/M
+connoisseur/SM
+connotative
+connubial
+conquer/ASDG
+conquerable/U
+conquered/U
+conqueror/MS
+conquest/AM
+conquistador/SM
+cons/DSG
+consanguineous
+consanguinity/M
+conscienceless
+conscientious/PY
+conscientiousness/M
+conscious/UYP
+consciousness/UM
+consciousnesses
+conscription/M
+consecrate/ADSGN
+consecrated/U
+consecration/AM
+consecrations
+consecutive/Y
+consensual
+consensus/MS
+consent/SMDG
+consequence/SM
+consequent/Y
+consequential/IY
+conservancy/SM
+conservation/M
+conservationism/M
+conservationist/SM
+conservatism/M
+conservative/MYS
+conservatoire/S
+conservator/SM
+conservatory/SM
+consider/AGSD
+considerable/I
+considerably
+considerate/IPYN
+considerateness/IM
+consideration/AIM
+considerations
+considered/U
+consign/ASDG
+consignee/MS
+consignment/MS
+consist/SDG
+consistence/MS
+consistency/ISM
+consistent/IY
+consistory/SM
+consolable/I
+consolation/MS
+consolatory
+consolidate/XDSGN
+consolidated/U
+consolidation/M
+consolidator/MS
+consoling/Y
+consomme/M
+consomm辿/M
+consonance/SM
+consonant/SMY
+consortia
+consortium/M
+conspectus/MS
+conspicuous/IPY
+conspicuousness/IM
+conspiracy/SM
+conspirator/MS
+conspiratorial/Y
+conspire/GD
+constable/SM
+constabulary/SM
+constancy/IM
+constant/MYS
+constellation/SM
+consternation/M
+constipate/GNDS
+constipation/M
+constituency/SM
+constituent/SM
+constitute/ADSGNV
+constitution/AM
+constitutional/MYS
+constitutionalism
+constitutionality/UM
+constitutions
+constrained/U
+constraint/SM
+constrict/GVSD
+constriction/SM
+constrictor/SM
+construable
+construct/CADVGS
+construction/CAMS
+constructional
+constructionist/CSM
+constructive/YP
+constructiveness/M
+constructor/MS
+construe/GDS
+consul/KSM
+consular/K
+consulate/SM
+consulship/M
+consult/GSD
+consultancy/SM
+consultant/MS
+consultation/MS
+consultative
+consumable/SM
+consume/BDRSZG
+consumed/U
+consumer/M
+consumerism/M
+consumerist/MS
+consummate/YGNXDS
+consummated/U
+consumption/M
+consumptive/SM
+cont
+contact/ASDG
+contactable
+contactless
+contagion/MS
+contagious/PY
+contagiousness/M
+contain/SBLDRZG
+contained/U
+container/M
+containerization/M
+containerize/DSG
+containment/M
+contaminant/SM
+contaminate/ACDSG
+contaminated/U
+contamination/CM
+contaminator/SM
+contd
+contemn/SDG
+contemplate/DSGNV
+contemplation/M
+contemplative/SMY
+contemporaneity/M
+contemporaneous/Y
+contempt/M
+contemptible
+contemptibly
+contemptuous/YP
+contemptuousness/M
+contender/MS
+content/ESLMDG
+contented/EY
+contentedness/M
+contention/SM
+contentious/YP
+contentiousness/M
+contently
+contentment/EM
+conterminous/Y
+contestable/I
+contestant/MS
+contested/U
+contextualization
+contextualize/CDSG
+contiguity/M
+contiguous/Y
+continence/IM
+continent/SM
+continental/SM
+continentalism/M
+contingency/SM
+contingent/SMY
+continua
+continual/Y
+continuance/EMS
+continuation/EMS
+continue/EGDS
+continuity/ESM
+continuous/EY
+continuum/M
+contort/GD
+contortion/MS
+contortionist/SM
+contra
+contraband/M
+contrabass/MS
+contrabassoon/S
+contraception/M
+contraceptive/SM
+contract/MDG
+contractible
+contractile
+contractility
+contraction/S
+contractual/Y
+contradict/SDG
+contradicted/U
+contradiction/SM
+contradictory
+contradistinction/MS
+contraflow/S
+contrail/MS
+contraindicate/GNXDS
+contraindication/M
+contralto/SM
+contraption/SM
+contrapuntal/Y
+contrarian/SM
+contrarianism
+contrariety/M
+contrarily
+contrariness/M
+contrariwise
+contrary/PSM
+contrast/MDGS
+contravene/GDS
+contravention/SM
+contretemps/M
+contribute/XGND
+contribution/M
+contributor/MS
+contributory
+contrition/M
+contrivance/MS
+contrive/ZGDRS
+contriver/M
+control's
+control/CS
+controllable/U
+controlled/UC
+controller/MS
+controlling/C
+controversial/Y
+controversy/SM
+controvert/DSG
+controvertible/I
+contumacious/Y
+contumacy/M
+contumelious
+contumely/SM
+contuse/XDSGN
+contusion/M
+conundrum/SM
+conurbation/MS
+convalesce/DSG
+convalescence/MS
+convalescent/SM
+convection/M
+convectional
+convective
+convector/S
+convene/ADSG
+convener/MS
+convenience/IMS
+convenient/IY
+convenor/MS
+convent/SM
+conventicle/MS
+convention/SM
+conventional/UY
+conventionality/UM
+conventionalize/GDS
+conventioneer/S
+convergence/MS
+convergent
+conversant
+conversation/MS
+conversational/Y
+conversationalist/SM
+converse/Y
+convert's
+convert/AGSD
+converted/U
+converter/SM
+convertibility/M
+convertible/SM
+convertor/SM
+convex/Y
+convexity/M
+convey/SBDG
+conveyance/MGS
+conveyor/MS
+convict/GSMD
+conviction/MS
+convince/GDS
+convinced/U
+convincing/UY
+convivial/Y
+conviviality/M
+convoke/DSG
+convoluted
+convolution/MS
+convolutional
+convoy/SMDG
+convulse/GNVXDS
+convulsion/M
+convulsive/Y
+cony/SM
+coo/GSMD
+cook's
+cook/ADGS
+cookbook/MS
+cooked/U
+cooker/SM
+cookery/SM
+cookhouse/S
+cookie/M
+cooking/M
+cookout/SM
+cookware/SM
+cooky/SM
+cool/MDRYZTGPS
+coolant/SM
+cooler/M
+coolie/SM
+coolness/M
+coon/MS!
+coonskin/MS
+coop/MDRZGS
+cooper/MDG
+cooperage/M
+cooperate/DSGNV
+cooperation/M
+cooperative/PMYS
+cooperativeness/M
+cooperator/SM
+coordinate/DSMYGN
+coordinated/U
+coordination/M
+coordinator/MS
+coot/MS
+cootie/SM
+cop/GJSMD
+copacetic
+copay/M
+cope/MS
+copier/SM
+copilot/SM
+coping/M
+copious/PY
+copiousness/M
+copped
+copper/SM
+copperhead/SM
+copperplate/M
+coppery
+copping
+copra/M
+coproduct/MS
+copse/SM
+copter/SM
+copula/SM
+copulate/GNVDS
+copulation/M
+copulative/SM
+copy's
+copy/ADSG
+copybook/SM
+copycat/MS
+copycatted
+copycatting
+copyist/MS
+copyleft
+copyright/GSBMD
+copyrightable/U
+copywriter/MS
+coquetry/SM
+coquette/DSMG
+coquettish/Y
+cor
+coracle/SM
+coral/SM
+corbel/SM
+cord/EASGDM
+cordage/M
+cordial/SMY
+cordiality/M
+cordillera/MS
+cordite/M
+cordless
+cordon/SMDG
+cordovan/M
+corduroy/MS
+corduroys/M
+core/MZGDRS
+coreligionist/S
+corer/M
+corespondent/MS
+corgi/SM
+coriander/M
+cork's
+cork/UDGS
+corkage
+corker/SM
+corkscrew/SMDG
+corm/MS
+cormorant/SM
+corn/MDRZGS
+cornball/MS
+cornbread/M
+corncob/MS
+corncrake/S
+cornea/SM
+corneal
+corner/GMD
+cornerstone/SM
+cornet/SM
+cornfield/S
+cornflakes/M
+cornflour
+cornflower/SM
+cornice/MS
+cornily
+corniness/M
+cornmeal/M
+cornrow/MDGS
+cornstalk/SM
+cornstarch/M
+cornucopia/MS
+corny/PRT
+corolla/MS
+corollary/SM
+corona/SM
+coronal/MS
+coronary/SM
+coronation/SM
+coronavirus/MS
+coroner/MS
+coronet/MS
+corp
+corpora
+corporal/SM
+corporate/XYN
+corporation/IM
+corporatism
+corporeal/Y
+corporeality/M
+corps/MS
+corpse/M
+corpsman/M
+corpsmen
+corpulence/M
+corpulent
+corpus/M
+corpuscle/MS
+corpuscular
+corr
+corral/SM
+corralled
+corralling
+correct/DRYTGVSBP
+corrected/U
+correction/SM
+correctional
+corrective/SM
+correctness/IM
+corrector
+correlate/XDSMGNV
+correlated/U
+correlation/M
+correlational
+correlative/MS
+correspond/SDG
+correspondence/SM
+correspondent/SM
+corresponding/Y
+corridor/SM
+corrie/S
+corrigibility/IM
+corrigible/I
+corroborate/GNVDSX
+corroborated/U
+corroboration/M
+corroborator/SM
+corroboratory
+corrode/GDS
+corrosion/M
+corrosive/SMY
+corrugate/GNXDS
+corrugation/M
+corrupt/DRYPSTG
+corruptibility/IM
+corruptible/I
+corruptibly/I
+corruption/MS
+corruptness/M
+corsage/MS
+corsair/MS
+corset/SGMD
+cortege/MS
+cortex/M
+cortical
+cortices
+cortisol
+cortisone/M
+cort竪ge/SM
+corundum/M
+coruscate/GNDS
+coruscation/M
+corvette/SM
+cos/M
+cosh/DSG
+cosign/ZGSDR
+cosignatory/SM
+cosigner/M
+cosine/SM
+cosmetic/SM
+cosmetically
+cosmetician/MS
+cosmetologist/MS
+cosmetology/M
+cosmic
+cosmically
+cosmogonist/SM
+cosmogony/SM
+cosmological
+cosmologist/SM
+cosmology/SM
+cosmonaut/SM
+cosmopolitan/MS
+cosmopolitanism/M
+cosmos/MS
+cosplay/DRSZG
+cosponsor/GSMD
+cosset/SGD
+cossetted
+cossetting
+cost/MDYGSJ
+costar/SM
+costarred
+costarring
+costliness/M
+costly/PTR
+costume/MZGDRS
+costumer/M
+costumier/S
+cot/SM
+cotangent/MS
+cote/MS
+coterie/MS
+coterminous
+cotillion/SM
+cottage/MZGRS
+cottager/M
+cottar/SM
+cotter/SM
+cotton/SGMD
+cottonmouth/M
+cottonmouths
+cottonseed/MS
+cottontail/MS
+cottonwood/SM
+cottony
+cotyledon/MS
+couch/MDSG
+couchette/S
+cougar/SM
+cough/MDG
+coughs
+could
+could've
+couldn't
+coulee/SM
+coulis
+coulomb/MS
+coul辿e/SM
+council/MS
+councilman/M
+councilmen
+councilor/MS
+councilperson/SM
+councilwoman/M
+councilwomen
+counsel/JMDGS
+counselor/MS
+count/EASMDG
+countable/U
+countably
+countdown/MS
+counted/U
+countenance/EMGDS
+counter/EMS
+counteract/SGVD
+counteraction/MS
+counterargument/S
+counterattack/GMDS
+counterbalance/MGDS
+counterblast/S
+counterclaim/GSMD
+counterclockwise
+counterculture/SM
+countered
+counterespionage/M
+counterexample/S
+counterfactual
+counterfeit/ZGMDRS
+counterfeiter/M
+counterfoil/MS
+countering
+counterinsurgency/SM
+counterintelligence/M
+counterintuitive/Y
+counterman/M
+countermand/GMDS
+countermeasure/SM
+countermelody/S
+countermen
+countermove/S
+counteroffensive/SM
+counteroffer/SM
+counterpane/SM
+counterpart/SM
+counterpetition
+counterpoint/MDGS
+counterpoise/MGDS
+counterproductive
+counterproposal
+counterrevolution/SM
+counterrevolutionary/SM
+countersign/GSMD
+countersignature/MS
+countersink/GSM
+counterspy/SM
+counterstrike/SM
+counterstroke/SM
+countersunk
+countertenor/MS
+countertop/S
+countervail/GSD
+counterweight/MS
+countess/MS
+countless
+countrified
+country/SM
+countryman/M
+countrymen
+countryside/MS
+countrywide
+countrywoman/M
+countrywomen
+county/SM
+countywide
+coup's
+coup/AS
+coupe/SM
+couple's
+couple/UCGZSRD
+couplet/MS
+coupling/SM
+coupon/SM
+courage/M
+courageous/YP
+courageousness/M
+courgette/S
+courier/MDSG
+course/EDGMS
+coursebook/S
+courser/MS
+coursework
+court-martial/SGD
+court/SMDYG
+courteous/EY
+courteousness/M
+courtesan/SM
+courtesy/ESM
+courthouse/MS
+courtier/SM
+courtliness/M
+courtly/PRT
+courtroom/MS
+courtship/MS
+courtyard/MS
+couscous/M
+cousin/SM
+couture/M
+couturier/MS
+covalent
+covariance
+covariant
+covariate/S
+cove/MS
+coven/SM
+covenant/MDSG
+cover's
+cover/AEUGDS
+coverage/M
+coverall/MS
+covering's
+coverings
+coverlet/MS
+covert/SPMY
+covertness/M
+coverup/MS
+covet/SDG
+covetous/YP
+covetousness/M
+covey/SM
+cow/ZGSMDR
+coward/SMY
+cowardice/M
+cowardliness/M
+cowbell/MS
+cowbird/MS
+cowboy/SM
+cowcatcher/MS
+cower/DG
+cowgirl/MS
+cowhand/MS
+cowherd/MS
+cowhide/MS
+cowl/MGSJ
+cowlick/MS
+cowling/M
+cowman/M
+cowmen
+coworker/MS
+cowpat/S
+cowpoke/MS
+cowpox/M
+cowpuncher/SM
+cowrie/SM
+cowshed/S
+cowslip/SM
+cox/GDS
+coxcomb/MS
+coxswain/MS
+coy/TPRY
+coyness/M
+coyote/SM
+coypu/SM
+cozen/SDG
+cozenage/M
+cozily
+coziness/M
+cozy/RSMTP
+cpd
+cpl
+cps
+crab/MS
+crabbed
+crabber/SM
+crabbily
+crabbiness/M
+crabbing
+crabby/PRT
+crabgrass/M
+crablike
+crabwise
+crack/SMDRYZGJ
+crackdown/MS
+cracker/M
+crackerjack/MS
+crackhead/MS
+crackle/DSJMG
+crackling/M
+crackpot/MS
+crackup/SM
+cradle/DSMG
+craft/SMDG
+craftily
+craftiness/M
+craftsman/M
+craftsmanship/M
+craftsmen
+craftspeople
+craftswoman/M
+craftswomen
+crafty/RTP
+crag/MS
+cragginess/M
+craggy/RPT
+cram/S
+crammed
+crammer/S
+cramming
+cramp/SMDG
+cramping/M
+crampon/SM
+cranberry/SM
+crane/DSMG
+cranial
+cranium/SM
+crank/SMDG
+crankcase/SM
+crankily
+crankiness/M
+crankshaft/MS
+cranky/PRT
+cranny/DSM
+crap/MS
+crape/SM
+crapola
+crapped
+crapper/S
+crappie/M
+crapping
+crappy/RSPT
+craps/M
+crapshooter/MS
+crash/MDSG
+crass/RYTP
+crassness/M
+crate/DRSMZG
+crater/MDG
+cravat/SM
+crave/DSGJ
+craven/SMYP
+cravenness/M
+craving/M
+craw/MS
+crawdad/SM
+crawl/SMDRZG
+crawler/M
+crawlspace/SM
+crawly/TRSM
+cray/S
+crayfish/MS
+crayola/S
+crayon/GSMD
+craze/DSMG
+crazily
+craziness/M
+crazy/PRSMT
+creak/SMDG
+creakily
+creakiness/M
+creaky/RPT
+cream/SMDRZG
+creamer/M
+creamery/SM
+creamily
+creaminess/M
+creamy/RPT
+crease/ICGMSD
+create/AKVNGSDX
+creatine
+creation/KAM
+creationism/SM
+creationist/SM
+creative/SMYP
+creativeness/M
+creativity/M
+creator/MS
+creature/SM
+creche/SM
+cred
+credence/M
+credential/SGMD
+credenza/SM
+credibility/IM
+credible/I
+credibly/I
+credit/EGSBMD
+creditably/E
+creditor/SM
+creditworthy/P
+credo/SM
+credulity/IM
+credulous/IY
+credulousness/M
+creed/SM
+creek/SM
+creel/SM
+creep/SMRZG
+creeper/M
+creepily
+creepiness/M
+creepy/TPR
+cremains/M
+cremate/GNDSX
+cremation/M
+crematoria
+crematorium/MS
+crematory/SM
+creme/SM
+crenelate/XGNDS
+crenelation/M
+creole/SM
+creosote/MGDS
+crepe/SM
+crept
+crepuscular
+crescendo/CSM
+crescent/MS
+cress/M
+crest/SMDG
+crestfallen
+crestless
+cretaceous
+cretin/SM
+cretinism/M
+cretinous
+cretonne/M
+crevasse/SM
+crevice/MS
+crew/MDGS
+crewel/M
+crewelwork/M
+crewman/M
+crewmen
+crib/MS
+cribbage/M
+cribbed
+cribber/MS
+cribbing
+crick/SMDG
+cricket/MRSZG
+cricketer/M
+crier/M
+crikey
+crime/SM
+crimeware/M
+criminal/MYS
+criminality/M
+criminalization/C
+criminalize/CGDS
+criminologist/MS
+criminology/M
+crimp/SMDG
+crimson/SMDG
+cringe/DSMG
+crinkle/DSMG
+crinkly/RT
+crinoline/SM
+cripes
+cripple/DRSMZG
+crippler/M
+crippleware
+crippling/Y
+crises
+crisis/M
+crisp/SMDRYTGP
+crispbread/S
+crispiness/M
+crispness/M
+crispy/PRT
+crisscross/GMDS
+criteria
+criterion/M
+critic/SM
+critical/UY
+criticality
+criticism/MS
+criticize/ZGDRS
+criticizer/M
+critique/MGDS
+critter/SM
+croak/SMDG
+croaky/RT
+crochet/SMDRZG
+crocheter/M
+crocheting/M
+crock/SMD
+crockery/M
+crocodile/SM
+crocus/MS
+croft/SRZG
+croissant/MS
+crone/SM
+crony/SM
+cronyism/M
+crook/SMDG
+crooked/PTRY
+crookedness/M
+crookneck/SM
+croon/SMDRZG
+crooner/M
+crop/MS
+cropland/SM
+cropped
+cropper/MS
+cropping
+croquet/M
+croquette/SM
+crore/SM
+crosier/MS
+cross's
+cross/AUGTSD
+crossbar/SM
+crossbeam/MS
+crossbones/M
+crossbow/SM
+crossbowman/M
+crossbowmen
+crossbred
+crossbreed/SGM
+crosscheck/SMDG
+crosscurrent/MS
+crosscut/SM
+crosscutting
+crosser
+crossfire/MS
+crosshair/MS
+crosshatch/GDS
+crossing/SM
+crossly
+crossness/M
+crossover/MS
+crosspatch/MS
+crosspiece/SM
+crossroad/MS
+crossroads/M
+crosstown
+crosswalk/MS
+crosswind/MS
+crosswise
+crossword/MS
+crotch/MS
+crotchet/SM
+crotchety
+crouch/GMDS
+croup/M
+croupier/M
+croupy/ZTR
+crouton/MS
+crow/MDGS
+crowbar/MS
+crowd/SMDG
+crowded/U
+crowdfund/SDG
+crowdsource/DSG
+crowfeet
+crowfoot/SM
+crown/SMDG
+crowned/U
+crozier/MS
+cro短ton/MS
+crucial/Y
+crucible/SM
+crucifix/MS
+crucifixion/SM
+cruciform/SM
+crucify/DSG
+crud/M
+cruddy/TR
+crude/RMYTP
+crudeness/M
+crudites/M
+crudity/SM
+crudit辿s/M
+cruel/RYPT
+cruelness/M
+cruelty/SM
+cruet/SM
+cruft/SD
+crufty
+cruise/DRSMZG
+cruiser/M
+cruller/MS
+crumb/SMDYG
+crumble/MGDS
+crumbliness/M
+crumbly/TPR
+crumby/TR
+crumminess/M
+crummy/PTR
+crumpet/MS
+crumple/MGDS
+crunch/GMDRS
+crunchiness/M
+crunchy/TRP
+crupper/MS
+crusade/MZGDRS
+crusader/M
+cruse/SM
+crush/MDRSZG
+crusher/M
+crushing/Y
+crust/SMDG
+crustacean/SM
+crustal
+crustily
+crustiness/M
+crusty/TRP
+crutch/MS
+crux/MS
+cry/ZGJDRSM
+crybaby/SM
+cryogenic/S
+cryogenics/M
+cryonic/S
+cryosurgery/M
+crypt's
+crypt/S
+cryptanalysis
+cryptic
+cryptically
+crypto/M
+cryptocurrency/SM
+cryptogram/SM
+cryptographer/SM
+cryptographic
+cryptography/M
+cryptologist/MS
+cryptosystem/S
+crystal/SM
+crystalize/DSG
+crystalline
+crystallization/M
+crystallize/ADSG
+crystallographic
+crystallography
+cr竪che/MS
+ct
+ctn
+ctr
+cu
+cub/ZGSMDR
+cubbyhole/MS
+cube/MS
+cuber/M
+cubic
+cubical
+cubicle/MS
+cubism/M
+cubist/SM
+cubit/SM
+cuboid/S
+cuckold/MDSG
+cuckoldry/M
+cuckoo/SM
+cucumber/SM
+cud/SM
+cuddle/DSMG
+cuddly/TR
+cudgel/SGMDJ
+cue/DSMG
+cuff/MDGS
+cuisine/SM
+cul-de-sac
+culinary
+cull/MDGS
+cullender/MS
+culminate/XDSGN
+culmination/M
+culotte/SM
+culpa/S
+culpability/M
+culpable/I
+culpably
+culprit/SM
+cult/MS
+cultism/M
+cultist/MS
+cultivable
+cultivar/SM
+cultivate/BDSGN
+cultivated/U
+cultivation/M
+cultivator/MS
+cultural/Y
+culture/MGDS
+cultured/U
+culvert/MS
+cum/SM
+cumber/SDG
+cumbersome/P
+cumbersomeness/M
+cumbrous
+cumin/M
+cummerbund/MS
+cumming
+cumulative/Y
+cumuli
+cumulonimbi
+cumulonimbus/M
+cumulus/M
+cuneiform/M
+cunnilingus/M
+cunning/MRYT
+cunt/MS!
+cup/SM
+cupboard/SM
+cupcake/MS
+cupful/SM
+cupid/SM
+cupidity/M
+cupola/SMD
+cuppa/S
+cupped
+cupping
+cupric
+cur/SMY
+curability/M
+curacao
+curacy/SM
+curare/M
+curate/DSMGNV
+curative/MS
+curator/KMS
+curatorial
+cura巽ao
+curb/MDGS
+curbing/M
+curbside
+curbstone/SM
+curd/MS
+curdle/DSG
+cure's
+cure/KZGBDRS
+cured/U
+curer/KM
+curettage/M
+curfew/SM
+curia/M
+curiae
+curie/SM
+curio/SM
+curiosity/SM
+curious/YP
+curiousness/M
+curium/M
+curl's
+curl/UDGS
+curler/SM
+curlew/SM
+curlicue/DSMG
+curliness/M
+curling/M
+curly/RPT
+curmudgeon/MYS
+currant/MS
+currency/SM
+current's
+current/FSY
+curricula
+curricular
+curriculum/M
+curry/DSMG
+currycomb/SGMD
+curse's
+curse/ADSGV
+cursed/Y
+cursive's
+cursive/EAY
+cursor/SM
+cursorily
+cursoriness/M
+cursory/P
+curt/RYTP
+curtail/GDSL
+curtailment/SM
+curtain/GMDS
+curtness/M
+curtsy/GDSM
+curvaceous/P
+curvaceousness/M
+curvature/SM
+curve/DSMG
+curvy/RT
+cushion/MDSG
+cushy/RT
+cusp/MS
+cuspid/SM
+cuspidor/SM
+cuss's
+cuss/EFGSD
+cussed/PY
+custard/MS
+custodial
+custodian/MS
+custodianship/M
+custody/M
+custom/SZMR
+customarily
+customary/U
+customer/M
+customhouse/SM
+customization/M
+customize/DSGB
+cut/TSMR
+cutaneous
+cutaway/MS
+cutback/MS
+cute/YP
+cuteness/M
+cutesy/TR
+cutey/S
+cuticle/MS
+cutie/SM
+cutlass/MS
+cutler/SM
+cutlery/M
+cutlet/SM
+cutoff/SM
+cutout/SM
+cutter/SM
+cutthroat/SM
+cutting/MYS
+cuttlefish/MS
+cutup/SM
+cutworm/MS
+cw
+cwt
+cyan/M
+cyanide/M
+cyanobacteria
+cyber
+cyberattack/SM
+cyberbully/SM
+cybercafe/S
+cybercaf辿/S
+cybernetic/S
+cybernetics/M
+cyberpunk/SM
+cybersecurity
+cybersex
+cyberspace/MS
+cyborg/SM
+cyclamen/MS
+cycle/ADSMG
+cyclic
+cyclical/Y
+cyclist/MS
+cyclometer/MS
+cyclone/MS
+cyclonic
+cyclopaedia/MS
+cyclopedia/MS
+cyclopes
+cyclops/M
+cyclotron/MS
+cygnet/MS
+cylinder/MS
+cylindrical
+cymbal/MS
+cymbalist/MS
+cynic/SM
+cynical/Y
+cynicism/M
+cynosure/MS
+cypher/M
+cypress/MS
+cyst/MS
+cysteine/SM
+cystic
+cysticerci
+cysticercoid/S
+cysticercoses
+cysticercosis
+cysticercus
+cystitis
+cystoscope
+cystoscopic
+cystoscopy
+cytokine/SM
+cytologist/SM
+cytology/M
+cytoplasm/M
+cytoplasmic
+cytosine/M
+czar/MS
+czarina/SM
+czarism
+czarist/SM
+d'Arezzo/M
+d'Estaing/M
+d/NXGJ
+dB
+dab/SM
+dabbed
+dabber/MS
+dabbing
+dabble/ZGDRS
+dabbler/M
+dace/SM
+dacha/MS
+dachshund/MS
+dactyl/MS
+dactylic/MS
+dad/SM
+dadaism/M
+dadaist/MS
+daddy/SM
+dado/SM
+dadoes
+daemon/MS
+daemonic
+daffiness/M
+daffodil/SM
+daffy/PTR
+daft/PTRY
+daftness/M
+dag/S
+dagger/MS
+dago/S
+dagoes
+daguerreotype/DSMG
+dahlia/MS
+dailiness/M
+daily/PSM
+daintily
+daintiness/M
+dainty/RSMTP
+daiquiri/MS
+dairy/GSM
+dairying/M
+dairymaid/MS
+dairyman/M
+dairymen
+dairywoman/M
+dairywomen
+dais/MS
+daisy/SM
+dale/SM
+dalliance/MS
+dallier/M
+dally/ZGDRS
+dalmatian/MS
+dam/SM
+damage/MGDS
+damageable
+damaged/U
+damages/M
+damask/MDGS
+dame/SM
+dammed
+damming
+dammit
+damn/SBGMD
+damnably
+damnation/M
+damned/T
+damp/SPXZTGMDNRY
+dampen/ZGDR
+dampener/M
+damper/M
+dampness/M
+damsel/MS
+damselfly/SM
+damson/MS
+dance/MZGDRS
+dancer/M
+dancing/M
+dandelion/SM
+dander/M
+dandify/GDS
+dandle/GDS
+dandruff/M
+dandy/TRSM
+dang/SZGDR
+danger/M
+dangerous/Y
+dangle/ZGDRS
+dangler/M
+danish/MS
+dank/PTRY
+dankness/M
+danseuse/MS
+dapper/TR
+dapple/MGDS
+dare/DRSMZG
+daredevil/MS
+daredevilry/M
+darer/M
+daresay
+daring/MY
+dark/PXTMNRY
+darken/ZGDR
+darkener/M
+darkie/S
+darkness/M
+darkroom/MS
+darling/MS
+darn/SZGMDR
+darned/TR
+darner/M
+dart/SZGMDR
+dartboard/MS
+darter/M
+dash/ZGMDRS
+dashboard/SM
+dasher/M
+dashiki/MS
+dashing/Y
+dastard/MYS
+dastardliness/M
+data
+database/SM
+dataset/MS
+datasheet/SM
+datatype
+date/DRSMZGV
+datebook/S
+dated/U
+dateless
+dateline/MGDS
+dater/M
+dateset
+dative/MS
+datum/M
+daub/SZGMDR
+dauber/M
+daughter/SMY
+daunt/GDS
+daunting/Y
+dauntless/YP
+dauntlessness/M
+dauphin/MS
+davenport/MS
+davit/MS
+dawdle/ZGDRS
+dawdler/M
+dawn/SGMD
+day/SM
+daybed/MS
+daybreak/M
+daycare/M
+daydream/MDRZGS
+daydreamer/M
+daylight/MS
+daylights/M
+daylong
+daytime/M
+daze/DSMG
+dazed/Y
+dazzle/MZGDRS
+dazzler/M
+dazzling/Y
+db
+dbl
+dc
+dd/SDG
+dded/K
+dding/K
+de
+deacon/MS
+deaconess/MS
+dead/XTMNRY
+deadbeat/MS
+deadbolt/SM
+deaden/GD
+deadhead/SDG
+deadline/SM
+deadliness/M
+deadlock/GSMD
+deadly/TPR
+deadpan/MS
+deadpanned
+deadpanning
+deadwood/M
+deaf/PXTNR
+deafen/GD
+deafening/Y
+deafness/M
+deal/SJZGMR
+dealer/M
+dealership/SM
+dealing/M
+dealt
+dean/M
+deanery/SM
+deanship/M
+dear/SPTMRYH
+dearest/S
+dearie/M
+dearness/M
+dearth/M
+dearths
+deary/SM
+death/MY
+deathbed/SM
+deathblow/MS
+deathless/Y
+deathlike
+deaths
+deathtrap/MS
+deathwatch/MS
+deaves
+deb/SM
+debacle/MS
+debarkation/M
+debarment/M
+debate/BMZR
+debater/M
+debating/M
+debauch/MDSG
+debauchee/MS
+debauchery/SM
+debenture/MS
+debilitate/DSGN
+debilitation/M
+debility/SM
+debit/D
+debonair/PY
+debonairness/M
+debouch/GDS
+debridement
+debris/M
+debt/SM
+debtor/MS
+debugger/S
+debut/GMD
+debutante/SM
+decade/MS
+decadence/M
+decadency/M
+decadent/MYS
+decaf/MS
+decaffeinate/DSG
+decagon/MS
+decal/MS
+decampment/M
+decapitate/XGNDS
+decapitator/MS
+decathlete/S
+decathlon/SM
+decay/GD
+deceased/M
+decedent/MS
+deceit/MS
+deceitful/YP
+deceitfulness/M
+deceive/UGDS
+deceiver/MS
+deceiving/Y
+decelerate/GNDS
+deceleration/M
+decelerator/SM
+decency/ISM
+decennial/SM
+decent/IY
+deception/MS
+deceptive/YP
+deceptiveness/M
+decibel/MS
+decidable/U
+decide/BZGDRS
+decided/Y
+deciduous
+decile/S
+deciliter/MS
+decimal/SM
+decimalization
+decimate/DSGN
+decimation/M
+decimeter/MS
+decipherable/UI
+decision/IM
+decisions
+decisis
+decisive/IPY
+decisiveness/IM
+deck/SGMD
+deckchair/S
+deckhand/SM
+deckle/S
+declamation/MS
+declamatory
+declaration/MS
+declarative
+declaratory
+declare/DRSZGB
+declared/U
+declarer/M
+declension/SM
+declination/M
+decline/DRSMZG
+decliner/M
+declivity/SM
+decoherence
+decolletage/SM
+decollete
+decongestant/MS
+deconstructionism
+decor/MS
+decorate/AGNVDS
+decorating/M
+decoration/AM
+decorations
+decorative/Y
+decorator/MS
+decorous/IY
+decorousness/M
+decorum/M
+decoupage/DSMG
+decoy/GMDS
+decreasing/Y
+decree/MDS
+decreeing
+decrement/GDS
+decrepit
+decrepitude/M
+decriminalization/M
+decry/GDS
+decrypt/BSGD
+decryption
+dedendum/SM
+dedicate/AGDS
+dedication/SM
+dedicator/SM
+dedicatory
+deduce/GDS
+deducible
+deduct/GVD
+deductible/SM
+deduction/SM
+deductive/Y
+deed/GD
+deejay/MS
+deem/ASGD
+deep/SPXTMNRY
+deepen/GD
+deepfake/SM
+deepness/M
+deer/M
+deerskin/M
+deerstalker/S
+def/Z
+defacement/M
+defacer/SM
+defalcate/DSXGN
+defalcation/M
+defamation/M
+defamatory
+defame/ZGDRS
+defamer/M
+defaulter/SM
+defeat/MDRZGS
+defeated/U
+defeater/M
+defeatism/M
+defeatist/MS
+defecate/GNDS
+defecation/M
+defect/MDGVS
+defection/MS
+defective/MPYS
+defectiveness/M
+defector/MS
+defendant/SM
+defended/U
+defenestration/S
+defense/DSMGV
+defenseless/YP
+defenselessness/M
+defensible/I
+defensibly/I
+defensive/MYP
+defensiveness/M
+deference/M
+deferential/Y
+deferral/MS
+deferred
+deferring
+deffer
+deffest
+defiant/Y
+defibrillation
+defibrillator/S
+deficiency/SM
+deficient
+deficit/SM
+defilement/M
+definable/IU
+define/AGDS
+defined/U
+definer/MS
+definite/IYVP
+definiteness/IM
+definition/AM
+definitional/Y
+definitions
+definitive/Y
+deflate/GNDS
+deflation/M
+deflationary
+deflect/DGVS
+deflection/MS
+deflector/SM
+defogger/SM
+defoliant/SM
+defoliate/DSGN
+defoliation/M
+defoliator/MS
+deformity/SM
+defraud/DRZGS
+defrauder/M
+defrayal/M
+defrock/DG
+defroster/MS
+deft/PTRY
+deftness/M
+defunct
+defy/GDS
+deg
+degeneracy/M
+degenerate/MVX
+degrade/B
+degree/MS
+dehydrator/SM
+dehydrogenase/M
+deicer/MS
+deification/M
+deify/NGDS
+deign/GDS
+deist/MS
+deistic
+deity/SM
+deject/GDS
+dejected/Y
+dejection/M
+delay/ZDR
+delectable
+delectably
+delectation/M
+delegate/GD
+delete/XGNDS
+deleterious
+deletion/M
+delft/M
+delftware/M
+deli/SM
+deliberate/XYVP
+deliberateness/M
+delicacy/ISM
+delicate/IY
+delicateness/M
+delicatessen/SM
+delicious/PY
+deliciousness/M
+delighted/Y
+delightful/Y
+deliminator
+delineate/GNXDS
+delineation/M
+delinquency/SM
+delinquent/SMY
+deliquesce/DSG
+deliquescent
+delirious/YP
+deliriousness/M
+delirium/SM
+deliver/ADGS
+deliverable/S
+deliverables/U
+deliverance/M
+delivered/U
+deliverer/SM
+dell/SM
+delphinium/MS
+delta/MS
+delude/GDS
+deluge/MGDS
+delusion/MS
+delusional
+delusive/Y
+deluxe
+delve/ZGDRS
+delver/M
+demagogic
+demagogically
+demagogue/SM
+demagoguery/M
+demagogy/M
+demand/GMDS
+demanding/U
+demarcate/DSGNX
+demarcation/M
+demean/GDS
+demeanor/M
+demented/Y
+dementia/M
+demesne/MS
+demigod/MS
+demigoddess/MS
+demijohn/SM
+demimondaine/SM
+demimonde/M
+demise/MGD
+demitasse/MS
+demo/GMD
+democracy/SM
+democrat/MS
+democratic/U
+democratically
+democratization/M
+democratize/GDS
+demode
+demographer/SM
+demographic/SM
+demographically
+demographics/M
+demography/M
+demolish/DSG
+demolition/MS
+demon/MS
+demonetization/M
+demoniac
+demoniacal/Y
+demonic
+demonically
+demonize/GDS
+demonology/SM
+demonstrability
+demonstrable/I
+demonstrably
+demonstrate/XGNVDS
+demonstration/M
+demonstrative/MYSP
+demonstrativeness/M
+demonstrator/MS
+demonym/S
+demote/GD
+demotic
+demount
+demulcent/SM
+demur/TMRS
+demure/PY
+demureness/M
+demurral/SM
+demurred
+demurrer/SM
+demurring
+den/M
+denationalization
+denaturation
+denature/DG
+dendrite/SM
+dengue/M
+deniability
+deniable/U
+denial/MS
+denier/M
+denigrate/DSGN
+denigration/M
+denim/MS
+denitrification
+denizen/MS
+denominational
+denotative
+denouement/MS
+denounce/LDSG
+denouncement/SM
+dense/PYTR
+denseness/M
+density/SM
+dent/ISGMD
+dental/Y
+dentifrice/SM
+dentin/M
+dentine/M
+dentist/MS
+dentistry/M
+dentition/M
+denture/IMS
+denuclearize/GDS
+denudation/M
+denude/GDS
+denunciation/SM
+deny/ZGDRS
+deodorant/SM
+deodorization/M
+deodorize/DRSZG
+deodorizer/M
+departed/M
+department/MS
+departmental/Y
+departmentalization/M
+departmentalize/GDS
+departure/SM
+dependability/M
+dependable/U
+dependably
+dependence/IM
+dependency/SM
+dependent/IMYS
+depict/GDS
+depiction/MS
+depilatory/SM
+deplete/GNDS
+depletion/M
+deplorably
+deplore/BGDS
+deploy/ALGDS
+deployment/AM
+deployments
+deponent/MS
+deportation/MS
+deportee/MS
+deportment/M
+deposit/AGMDS
+depositor/MS
+depository/SM
+deprave/GDS
+depravity/SM
+deprecate/GNDS
+deprecating/Y
+deprecation/M
+deprecatory
+depreciate/DSGN
+depreciation/M
+depredation/SM
+depressant/SM
+depressing/Y
+depression/SM
+depressive/SM
+depressor/MS
+depressurization
+deprive/GDS
+deprogramming
+depth/M
+depths
+deputation/MS
+depute/DSG
+deputize/DSG
+deputy/SM
+derailleur/SM
+derailment/SM
+derangement/M
+derby/SM
+dereliction/M
+deride/GDS
+derision/M
+derisive/PY
+derisiveness/M
+derisory
+derivation/MS
+derivative/MS
+derive/B
+dermal
+dermatitis/M
+dermatological
+dermatologist/SM
+dermatology/M
+dermis/M
+derogate/DSGN
+derogation/M
+derogatorily
+derogatory
+derrick/SM
+derriere/SM
+derringer/SM
+derri竪re/SM
+derv
+dervish/MS
+desalinate/GNDS
+desalination/M
+desalinization/M
+desalinize/GDS
+descant/M
+descend/FGDS
+descendant/MS
+descender
+describable/I
+describe/BZGDR
+describer/M
+description/SM
+descriptive/PY
+descriptiveness/M
+descriptor/S
+descry/GDS
+desecrate/DSGN
+desecration/M
+deselection
+desert/SDRZGM
+deserter/M
+desertification
+desertion/SM
+deserved/UY
+deserving/U
+deshabille/M
+desiccant/SM
+desiccate/DSGN
+desiccation/M
+desiccator/SM
+desiderata
+desideratum/M
+designate/DSGNX
+designated/U
+designation/M
+designee
+desirability/UM
+desirableness/M
+desirably/U
+desire/B
+desired/U
+desirous
+desist/SDG
+desk/SM
+deskill/G
+desktop/SM
+desolate/PDSYGN
+desolateness/M
+desolation/M
+despair/SMDG
+despairing/Y
+desperado/M
+desperadoes
+desperate/YNP
+desperateness/M
+desperation/M
+despicable
+despicably
+despise/DSG
+despite
+despoilment/M
+despondence/M
+despondency/M
+despondent/Y
+despotic
+despotically
+despotism/M
+dessert/SM
+dessertspoon/S
+dessertspoonful/S
+destination/SM
+destine/DSG
+destiny/SM
+destitute/N
+destitution/M
+destroy/SZGDR
+destroyer/M
+destruct/GVD
+destructibility/IM
+destructible/I
+destruction/M
+destructive/PY
+destructiveness/M
+desuetude/M
+desultorily
+desultory
+detach/BLGDS
+detachment/MS
+detain/LGDS
+detainee/MS
+detainment/M
+detect/SDGVB
+detectable/U
+detected/U
+detection/M
+detective/SM
+detector/SM
+detente/SMNX
+detention/M
+deter/SL
+detergent/SM
+deteriorate/DSGN
+deterioration/M
+determent/M
+determinable/I
+determinant/SM
+determinate
+determine/AGDS
+determined/U
+determinedly
+determiner/SM
+determinism/M
+deterministic
+deterministically
+deterred/U
+deterrence/M
+deterrent/MS
+deterring
+detestably
+detestation/M
+dethrone/DSLG
+dethronement/M
+detonate/GNDSX
+detonation/M
+detonator/SM
+detox/MDSG
+detoxification/M
+detoxify/DSGN
+detract/GD
+detriment/SM
+detrimental/Y
+detritus/M
+deuce/SM
+deuteride/S
+deuterium/M
+devastate/GNDS
+devastating/Y
+devastation/M
+devastator/MS
+develop/ASGDL
+developed/U
+developer/SM
+development/ASM
+developmental/Y
+deviance/M
+deviancy/M
+deviant/SM
+deviate/DSMGNX
+deviating/U
+deviation/M
+devil/SMDGL
+devilish/YP
+devilishness/M
+devilment/M
+devilry/SM
+deviltry/SM
+devious/YP
+deviousness/M
+devoid
+devolution/M
+devolve/DSG
+devoted/Y
+devotee/SM
+devotion/MS
+devotional/SM
+devour/SDG
+devout/PRYT
+devoutness/M
+dew/M
+dewberry/SM
+dewclaw/SM
+dewdrop/SM
+dewiness/M
+dewlap/SM
+dewy/RTP
+dexterity/M
+dexterous/YP
+dexterousness/M
+dextrose/M
+dharma
+dhoti/SM
+dhow/MS
+diabetes/M
+diabetic/SM
+diabolic
+diabolical/Y
+diacritic/MS
+diacritical
+diadem/SM
+diaereses
+diaeresis/M
+diagnose/DSG
+diagnosis/M
+diagnostic/S
+diagnostically
+diagnostician/SM
+diagnostics/M
+diagonal/SMY
+diagram/SM
+diagrammatic
+diagrammatically
+diagrammed
+diagramming
+dial/AMDGS
+dialect/SM
+dialectal
+dialectic/SM
+dialectical
+dialectics/M
+dialing/S
+dialog/SDG
+dialogue/DRSMG
+dialyses
+dialysis/M
+dialyzes
+diam
+diamagnetic
+diamagnetism
+diamante
+diamant辿
+diameter/SM
+diametric
+diametrical/Y
+diamond/SM
+diamondback/MS
+diapason/SM
+diaper/SMDG
+diaphanous
+diaphragm/SM
+diaphragmatic
+diarist/SM
+diarrhea/M
+diary/SM
+diaspora/SM
+diastase/M
+diastole/M
+diastolic
+diathermy/M
+diatom/SM
+diatomaceous
+diatomic
+diatonic
+diatribe/SM
+diazepam
+dibble/DSMG
+dibs/M
+dice/GDS
+dices/I
+dicey
+dichotomous
+dichotomy/SM
+dicier
+diciest
+dick/MRXZS
+dicker/DG
+dickey/SM
+dickhead/S
+dicky/SM
+dickybird/S
+dicotyledon/MS
+dicotyledonous
+dict
+dicta
+dictate/DSMGNX
+dictation/M
+dictator/SM
+dictatorial/Y
+dictatorship/SM
+diction/M
+dictionary/SM
+dictum/M
+did/AU
+didactic
+didactically
+diddle/DRSZG
+diddler/M
+diddly
+diddlysquat
+diddums
+didgeridoo/S
+didn't
+dido/MS
+didoes
+didst
+die/DSM
+diehard/SM
+dielectric/MS
+diereses
+dieresis/M
+diesel/SMDG
+diet/MDRZGS
+dietary/SM
+dieter/M
+dietetic/S
+dietetics/M
+dietician/MS
+dietitian/MS
+diff/DRZGS
+differ/DG
+difference/IM
+differences
+different/IY
+differentiable
+differential/SM
+differentiate/DSGN
+differentiated/U
+differentiation/M
+differentiator/S
+difficult/Y
+difficulty/SM
+diffidence/M
+diffident/Y
+diffract/GSD
+diffraction/M
+diffuse/DSYGNVP
+diffuseness/M
+diffusion/M
+diffusivity
+dig/SM
+digerati/M
+digest/SMDGV
+digested/U
+digestibility/M
+digestible/I
+digestion/IM
+digestions
+digestive/S
+digger/SM
+digging/S
+diggings/M
+digicam/S
+digit/SM
+digital/Y
+digitalis/M
+digitalize/DSG
+digitization
+digitize/GDS
+dignified/U
+dignify/DSG
+dignitary/SM
+dignity/ISM
+digraph/M
+digraphs
+digress/GVDS
+digression/MS
+dihydro
+dike/MGDS
+diktat/S
+dilapidated
+dilapidation/M
+dilatation/M
+dilate/DSGN
+dilation/M
+dilator/SM
+dilatory
+dildo/S
+dilemma/MS
+dilettante/SM
+dilettantish
+dilettantism/M
+diligence/M
+diligent/Y
+dill/MS
+dilly/SM
+dillydally/DSG
+diluent
+dilute/DSGNX
+diluted/U
+dilution/M
+dim/PSRY
+dime/MS
+dimension/SM
+dimensional
+dimensionless
+diminish/GDS
+diminished/U
+diminuendo/SM
+diminuendoes
+diminution/SM
+diminutive/SM
+dimity/M
+dimmed/U
+dimmer/SM
+dimmest
+dimming
+dimness/M
+dimple/DSMG
+dimply
+dimwit/SM
+dimwitted
+din/ZGSMDR
+dinar/SM
+dine/S
+diner/M
+dinette/MS
+ding/MDG
+dingbat/MS
+dingdong/SGMD
+dinghy/SM
+dingily
+dinginess/M
+dingle/SM
+dingo/M
+dingoes
+dingus/MS
+dingy/RPT
+dink/R
+dinky/RSMT
+dinned
+dinner/SMDG
+dinnertime/M
+dinnerware/M
+dinning
+dinosaur/SM
+dint/M
+diocesan/MS
+diocese/MS
+diode/SM
+diorama/SM
+dioxide/SM
+dioxin/SM
+dip/SM
+diphtheria/M
+diphthong/SM
+diploid/SM
+diploma/SM
+diplomacy/M
+diplomat/MS
+diplomata
+diplomatic/U
+diplomatically
+diplomatist/MS
+diplopia
+dipole/SM
+dipped
+dipper/SM
+dipping
+dippy/RT
+dipso/S
+dipsomania/M
+dipsomaniac/MS
+dipstick/SM
+dipterous
+diptych/M
+diptychs
+dire/YTR
+direct/ASDGVT
+directer
+direction/IM
+directional
+directionality/SM
+directionless
+directions/A
+directive/SM
+directly
+directness/IM
+director/MS
+directorate/SM
+directorial
+directorship/SM
+directory/SM
+direful
+dirge/SM
+dirigible/MS
+dirk/MS
+dirndl/SM
+dirt/M
+dirtball/S
+dirtily
+dirtiness/M
+dirty/DRSTGP
+dis/M
+disable/DSGL
+disablement/M
+disambiguate/DSGN
+disappointing/Y
+disarming/Y
+disastrous/Y
+disbandment/M
+disbarment/SM
+disbelieving/Y
+disbursal/M
+disburse/DSGL
+disbursement/MS
+disc/M
+discern/LSDG
+discernible/I
+discernibly
+discerning/Y
+discernment/M
+discharged/U
+disciple/SM
+discipleship/M
+disciplinarian/SM
+disciplinary
+discipline/DSMG
+disciplined/U
+disclose/DSBG
+disclosed/U
+disco/MG
+discography/SM
+discoloration/S
+discombobulate/DSGN
+discombobulation/M
+discomfit/DG
+discomfiture/M
+discommode/DG
+disconcerting/Y
+disconnected/PY
+disconnectedness/M
+disconsolate/Y
+discordance/M
+discordant/Y
+discotheque/SM
+discourage/LGDS
+discouragement/SM
+discouraging/Y
+discover/ABSDG
+discoverability
+discovered/U
+discoverer/MS
+discovery/ASM
+discreet/PRYT
+discreetness/M
+discrepancy/SM
+discrepant
+discrete/PYN
+discreteness/M
+discretion/IM
+discretionary
+discriminant
+discriminate/GNDS
+discriminating/U
+discrimination/M
+discriminator/MS
+discriminatory
+discursiveness/M
+discus/MS
+discussant/SM
+discussion/SM
+disdain/SMDG
+disdainful/Y
+disembowel/SDLG
+disembowelment/M
+disfigurement/SM
+disfranchisement/M
+disgorgement/M
+disgruntle/LGDS
+disgruntlement/M
+disguise/GD
+disguised/U
+disgusted/Y
+disgusting/Y
+dish/MDSG
+dishabille/M
+disharmonious
+dishcloth/M
+dishcloths
+disheartening/Y
+dishevel/DGLS
+dishevelment/M
+dishpan/SM
+dishrag/SM
+dishtowel/MS
+dishware/M
+dishwasher/MS
+dishwater/M
+dishy
+disillusion/GLD
+disillusionment/M
+disinfectant/MS
+disinfection/M
+disinterested/PY
+disinterestedness/M
+disjointed/YP
+disjointedness/M
+disjunctive
+disjuncture
+disk/MS
+diskette/MS
+dislodge/GDS
+dismal/Y
+dismantlement/M
+dismay/SMDG
+dismayed/U
+dismember/LGD
+dismemberment/M
+dismissive/Y
+disorder/Y
+disorganization/M
+disparage/DSGL
+disparagement/M
+disparaging/Y
+disparate/Y
+dispatcher/MS
+dispel/S
+dispelled
+dispelling
+dispensary/SM
+dispensation/MS
+dispense/BZGDRS
+dispenser/M
+dispersal/M
+disperse/GNDS
+dispersion/M
+dispirit/GDS
+displeasure/M
+disposable/SM
+disposal/SM
+disposed/I
+disposition/ISM
+dispossession/M
+disproof/SM
+disproportional
+disprove/B
+disputable/I
+disputably/I
+disputant/MS
+disputation/SM
+disputatious/Y
+dispute/DRSMZGB
+disputed/U
+disputer/M
+disquiet/GSMD
+disquisition/MS
+disregardful
+disrepair/M
+disrepute/MB
+disrupt/GVSD
+disruption/SM
+disruptive/Y
+dissect/SDG
+dissed
+dissemblance/M
+dissemble/ZGDRS
+dissembler/M
+disseminate/GNDS
+dissemination/M
+dissension/SM
+dissent/SMDRZG
+dissenter/M
+dissentious
+dissertation/SM
+disses
+dissidence/M
+dissident/MS
+dissimilar
+dissimilitude/S
+dissing
+dissipate/GNDS
+dissipation/M
+dissociate/GNVDS
+dissociation/M
+dissoluble/I
+dissolute/YNP
+dissoluteness/M
+dissolve/AGDS
+dissolved/U
+dissonance/SM
+dissonant
+dissuade/GDS
+dissuasive
+dist
+distaff/SM
+distal/Y
+distance/DSMG
+distant/Y
+distaste/SM
+distemper/M
+distention/SM
+distillate/SMNX
+distillation/M
+distillery/SM
+distinct/IYTVP
+distincter
+distinction/SM
+distinctive/YP
+distinctiveness/M
+distinctness/IM
+distinguish/GDSB
+distinguishable/I
+distinguished/U
+distort/GDR
+distortion/MS
+distract/DGB
+distractability
+distracted/Y
+distractible
+distraction/S
+distrait
+distraught
+distress/DG
+distressful
+distressing/Y
+distribute/AGNVDS
+distributed/U
+distribution/AM
+distributional
+distributions
+distributive/Y
+distributor's
+distributor/AS
+distributorship/S
+district's
+district/AS
+disturb/ZGSDR
+disturbance/SM
+disturbed/U
+disturber/M
+disturbing/Y
+disunion/M
+disyllabic
+ditch/MDSG
+dither/SMDRZG
+ditherer/M
+ditransitive
+ditsy
+ditto/SMDG
+dittoes
+ditty/SM
+ditz/MS
+ditzy/R
+diuretic/MS
+diurnal/Y
+div
+diva/MS
+divalent
+divan/SM
+dive/MZTGDRS
+diver/M
+diverge/DSG
+divergence/MS
+divergent
+diverse/XYNP
+diverseness/M
+diversification/M
+diversify/GNDS
+diversion/M
+diversionary
+diversity/SM
+divert/SDRZG
+diverticulitis/M
+divest/SLDG
+divestiture/MS
+divestment/M
+divide/DRSMZGB
+divided/U
+dividend/MS
+divider/M
+divination/M
+divine/DRSMYZTG
+diviner/M
+diving/M
+divinity/SM
+divisibility/IM
+divisible/I
+division/MS
+divisional
+divisive/PY
+divisiveness/M
+divisor/SM
+divorce/DSLMG
+divorcee/MS
+divorcement/MS
+divorc辿e/MS
+divot/SM
+divulge/GDS
+divvy/DSMG
+dixieland/M
+dizygotic
+dizygous
+dizzily
+dizziness/M
+dizzy/DRSPTG
+djellaba/MS
+djellabahs
+djinn
+do/SJMRHZG
+doable
+dob/S
+dobbed
+dobbin/SM
+dobbing
+doberman/MS
+dobro
+doc/SM
+docent/SM
+docile/Y
+docility/M
+dock/MDRZGS
+docket/SMDG
+dockland/S
+dockside
+dockworker/MS
+dockyard/MS
+doctor/SMDG
+doctoral
+doctorate/MS
+doctrinaire/MS
+doctrinal
+doctrine/MS
+docudrama/SM
+document/GMDS
+documentary/SM
+documentation/SM
+documented/U
+dodder/SMDG
+doddery
+doddle
+dodge/DRSMZG
+dodgem/S
+dodger/M
+dodgy/RT
+dodo/MS
+doe/SM
+doer/M
+does/AU
+doeskin/MS
+doesn't
+doff/DGS
+dog/SM
+dogcart/SM
+dogcatcher/SM
+doge/MS
+dogear/SMDG
+dogfight/SM
+dogfish/MS
+dogged/PY
+doggedness/M
+doggerel/M
+doggie/M
+dogging
+doggone/TGDRS
+doggoned/TR
+doggy/RSMT
+doghouse/SM
+dogie/SM
+dogleg/SM
+doglegged
+doglegging
+doglike
+dogma/SM
+dogmatic
+dogmatically
+dogmatism/M
+dogmatist/SM
+dognapper
+dogsbody/S
+dogsled/S
+dogtrot/MS
+dogtrotted
+dogtrotting
+dogwood/MS
+doh/M
+doily/SM
+doing/USM
+doldrums/M
+dole's
+dole/FGDS
+doleful/YP
+dolefulness/M
+doll/MDGS
+dollar/SM
+dollhouse/SM
+dollop/SGMD
+dolly/SM
+dolmen/SM
+dolomite/M
+dolor/M
+dolorous/Y
+dolphin/MS
+dolt/MS
+doltish/YP
+doltishness/M
+domain/SM
+dome/MGDS
+domestic/SM
+domestically
+domesticate/DSGN
+domesticated/U
+domestication/M
+domesticity/M
+domicile/DSMG
+domiciliary
+dominance/M
+dominant/SMY
+dominate/DSGNV
+domination/M
+dominator
+dominatrices
+dominatrix/M
+domineer/SGD
+domineering/Y
+dominion/SM
+domino/M
+dominoes
+don't
+don/SM
+dona/MS
+donate/DSXGN
+donation/M
+donator/MS
+done/FAU
+dong/MDGS
+dongle/SM
+donkey/SM
+donned
+donning
+donnish
+donnybrook/MS
+donor/SM
+donuts
+doodad/SM
+doodah
+doodahs
+doodle/DRSMZG
+doodlebug/SM
+doodler/M
+doohickey/SM
+doolally
+doom/MDGS
+doomsayer/MS
+doomsday/M
+doomster/S
+door's
+door/IS
+doorbell/MS
+doorjamb/S
+doorkeeper/MS
+doorknob/MS
+doorknocker/S
+doorman/M
+doormat/SM
+doormen
+doorplate/SM
+doorpost/S
+doorstep/MS
+doorstepped
+doorstepping
+doorstop/MS
+doorway/SM
+dooryard/MS
+doozie
+doozy
+dopa/M
+dopamine
+dope/MZGDRS
+doper/M
+dopey
+dopier
+dopiest
+dopiness/M
+doping/M
+doppelganger/S
+doppelg辰nger/S
+dork/MS
+dorky/RT
+dorm/MRZS
+dormancy/M
+dormant
+dormer/M
+dormice
+dormitory/SM
+dormouse/M
+dorsal/Y
+dory/SM
+dosage/SM
+dose/MGDS
+dosh
+dosimeter/SM
+doss/DRSZG
+dosshouse/S
+dossier/MS
+dost
+dot/ZGSMDR
+dotage/M
+dotard/SM
+dotcom/SM
+dote/S
+doter/M
+doting/Y
+dotted
+dotting
+dotty/RT
+double's
+double/ADSG
+doubleheader/MS
+doublespeak/M
+doublet/MS
+doubloon/SM
+doubly
+doubt/SMDRZG
+doubter/M
+doubtful/PY
+doubtfulness/M
+doubting/Y
+doubtless/Y
+douche/DSMG
+dough/M
+doughnut/SM
+doughty/RT
+doughy/TR
+dour/RYTP
+dourness/M
+douse/DSG
+dove/MS
+dovecot/S
+dovecote/SM
+dovetail/MDSG
+dovish
+dowager/MS
+dowdily
+dowdiness/M
+dowdy/RSPT
+dowel/SMDG
+dower/SMDG
+down/MDRZGS
+downbeat/SM
+downcast
+downdraft/MS
+downer/M
+downfall/SMN
+downfield
+downgrade/DSMG
+downhearted/PY
+downheartedness/M
+downhill/MS
+download/MDBSG
+downmarket
+downplay/DSG
+downpour/MS
+downrange
+downright
+downriver
+downscale
+downshift/SGD
+downside/MS
+downsize/GDS
+downsizing/M
+downspout/MS
+downstage
+downstairs/M
+downstate/M
+downstream
+downswing/MS
+downtempo
+downtime/M
+downtown/M
+downtrend/MS
+downtrodden
+downturn/MS
+downward/S
+downwind
+downy/RT
+dowry/SM
+dowse/DRSZG
+dowser/M
+dox/GDS
+doxastic
+doxology/SM
+doxx/DSG
+doyen/SM
+doyenne/MS
+doz/XGDNS
+doze/M
+dozen/MH
+dozily
+dozy/RTP
+dpi
+dpt
+drab/MYSP
+drabber
+drabbest
+drabness/M
+drachma/MS
+draconian
+draft's
+draft/ASDG
+draftee/SM
+drafter/SM
+draftily
+draftiness/M
+drafting/M
+draftsman/M
+draftsmanship/M
+draftsmen
+draftswoman/M
+draftswomen
+drafty/RTP
+drag/MS
+dragged
+dragging
+draggy/TR
+dragnet/SM
+dragon/SM
+dragonfly/SM
+dragoon/SMDG
+dragster/S
+drain/SMDRZG
+drainage/M
+drainboard/SM
+drainer/M
+drainpipe/MS
+drake/SM
+dram/MS
+drama/SM
+dramatic/S
+dramatically
+dramatics/M
+dramatist/SM
+dramatization/SM
+dramatize/DSG
+drank
+drape/DRSMZG
+draper/M
+drapery/SM
+drastic
+drastically
+drat
+dratted
+draughtboard/S
+draw/MRZGSJ
+drawback/MS
+drawbridge/MS
+drawer/M
+drawing/M
+drawl/SMDG
+drawn/A
+drawstring/MS
+dray/MS
+dread/SMDG
+dreadful/PY
+dreadfulness/M
+dreadlocks/M
+dreadnought/MS
+dream/SMDRZG
+dreamboat/MS
+dreamed/U
+dreamer/M
+dreamily
+dreaminess/M
+dreamland/M
+dreamless
+dreamlike
+dreamworld/SM
+dreamy/RPT
+drear
+drearily
+dreariness/M
+dreary/RPT
+dreck
+dreckish
+drecky
+dredge/DRSMZG
+dredger/M
+dregs/M
+drek
+drench/GDS
+dress/AUGSDM
+dressage/M
+dresser/MS
+dressiness/M
+dressing/SM
+dressmaker/SM
+dressmaking/M
+dressy/TPR
+drew/A
+dribble/MZGDRS
+dribbler/M
+driblet/MS
+drier/M
+drift/SMDRZG
+drifter/M
+driftnet/S
+driftwood/M
+drill/SMDRZG
+driller/M
+drillmaster/SM
+drily
+drink/SMRBJZG
+drinkable/U
+drinker/M
+drip/MS
+dripped
+dripping/SM
+drippy/TR
+drive/RSMZGJ
+drivel/SZGMDR
+driveler/M
+driven
+driver/M
+driveshaft/SM
+driveway/MS
+drizzle/MGDS
+drizzly
+drogue/SM
+droid/S
+droll/RPT
+drollery/SM
+drollness/M
+drolly
+dromedary/SM
+drone/DSMG
+drool/SMDG
+droop/GSMD
+droopiness/M
+droopy/TPR
+drop/MS
+dropkick/MS
+droplet/SM
+dropout/SM
+dropped
+dropper/SM
+dropping/S
+droppings/M
+dropsical
+dropsy/M
+dross/M
+drought/SM
+drove/RSMZ
+drover/M
+drown/GSJD
+drowning/M
+drowse/MGDS
+drowsily
+drowsiness/M
+drowsy/RTP
+drub/S
+drubbed
+drubber/SM
+drubbing/MS
+drudge/MGDS
+drudgery/M
+drug/MS
+drugged
+druggie/SM
+drugging
+druggist/SM
+druggy
+drugstore/MS
+druid/SM
+druidism/M
+drum/MS
+drumbeat/SM
+drumlin/SM
+drummed
+drummer/SM
+drumming
+drumstick/SM
+drunk/STMNR
+drunkard/MS
+drunken/PY
+drunkenness/M
+drupe/SM
+druthers/M
+dry/ZTGDRSMY
+dryad/SM
+dryer/SM
+dryness/M
+drys
+drywall/M
+dual
+dualism/M
+duality/M
+dub/SM
+dubbed
+dubber/SM
+dubbin/M
+dubbing
+dubiety/M
+dubious/YP
+dubiousness/M
+ducal
+ducat/SM
+duchess/MS
+duchy/SM
+duck/MDGS
+duckbill/SM
+duckboards
+duckling/SM
+duckpins/M
+duckweed/M
+ducky/TRSM
+duct's/K
+duct/CKIFS
+ductile
+ductility/M
+ducting
+ductless
+dud/GSMD
+dude/MS
+dudgeon/M
+due's
+due/IS
+duel/MDRJZGS
+dueler/M
+duelist/SM
+duenna/MS
+duet/MS
+duff/MDRZGS
+duffel/S
+duffer/M
+dug
+dugout/MS
+duh
+duke/MS
+dukedom/SM
+dulcet
+dulcimer/MS
+dull/DRPTGS
+dullard/SM
+dullness/M
+dully
+duly/U
+dumb/DRYPT
+dumbbell/SM
+dumbfound/SDG
+dumbness/M
+dumbo/S
+dumbstruck
+dumbwaiter/SM
+dumdum/MS
+dummy/SM
+dump/MDRZGS
+dumpiness/M
+dumpling/SM
+dumpsite/S
+dumpster/SM
+dumpy/PTR
+dun/SM
+dunce/SM
+dunderhead/MS
+dune/MS
+dung/MDGS
+dungaree/MS
+dungeon/SM
+dunghill/MS
+dunk/MDGS
+dunned
+dunner
+dunnest
+dunning
+dunno
+duo/SM
+duodecimal
+duodena
+duodenal
+duodenum/M
+duopoly/S
+dupe/MZGDRS
+duper/M
+duple
+duplex/MS
+duplicate's
+duplicate/AGNVDS
+duplication/AM
+duplicator/MS
+duplicitous
+duplicity/M
+durability/M
+durable
+durably
+durance/M
+duration/M
+duress/M
+durian/SM
+during
+durst
+durum/M
+dusk/M
+duskiness/M
+dusky/RTP
+dust/MDRZGS
+dustbin/SM
+dustcart/S
+duster/M
+dustiness/M
+dustless
+dustman
+dustmen
+dustpan/SM
+dustsheet/S
+dusty/RTP
+dutch
+duteous/Y
+dutiable
+dutiful/YP
+dutifulness/M
+duty/SM
+duvet/SM
+dwarf/SGMD
+dwarfish
+dwarfism/M
+dweeb/SM
+dwell/SJZGR
+dweller/M
+dwelling/M
+dwelt/I
+dwindle/DSG
+dyad
+dyadic
+dyadically
+dybbuk/SM
+dybbukim
+dye/DRSMZG
+dyeing/A
+dyer/M
+dyestuff/M
+dying/M
+dyke/MS
+dynamic/MS
+dynamical/Y
+dynamics/M
+dynamism/M
+dynamite/MZGDRS
+dynamiter/M
+dynamo/SM
+dynastic
+dynasty/SM
+dysentery/M
+dysfunction/MS
+dysfunctional
+dyslectic/SM
+dyslexia/M
+dyslexic/SM
+dyspepsia/M
+dyspeptic/MS
+dysphagia
+dysphoria
+dysphoric
+dysprosium/M
+dystonia
+dystopi
+dystopia/S
+dystopian/S
+dz
+d辿bridement
+d辿butante/SM
+d辿colletage/SM
+d辿collet辿
+d辿mod辿
+d辿railleur/MS
+d辿shabill辿/M
+d辿tente/M
+e'en
+e'er
+e/FDST
+eBay/M
+eBook/MS
+eCommerce/M
+eMusic/M
+ea
+each
+eager/PTRY
+eagerness/M
+eagle/MS
+eaglet/MS
+ear/SMDY
+earache/SM
+earbud/SM
+eardrum/SM
+earful/SM
+earl/MS
+earldom/SM
+earliness/M
+earlobe/SM
+early/RTP
+earmark/SMDG
+earmuff/SM
+earn/DRZTGJS
+earned/U
+earner/M
+earnest/SMYP
+earnestness/M
+earnings/M
+earphone/MS
+earpiece/S
+earplug/SM
+earring/SM
+earshot/M
+earsplitting
+earth's
+earth/UDYG
+earthbound
+earthen
+earthenware/M
+earthiness/M
+earthling/MS
+earthly/RT
+earthquake/SM
+earths/U
+earthshaking
+earthward/S
+earthwork/MS
+earthworm/MS
+earthy/RTP
+earwax/M
+earwig/SM
+ease/EDSM
+easel/SM
+easement/SM
+easily/U
+easiness/UM
+easing
+east/M
+eastbound
+easterly/SM
+eastern/ZR
+easterner/M
+easternmost
+eastward/S
+easy/URTP
+easygoing
+eat/ZGBSNR
+eatable/SM
+eaten/U
+eater/M
+eatery/SM
+eave/MS
+eavesdrop/S
+eavesdropped
+eavesdropper/SM
+eavesdropping
+ebb/SMDG
+ebony/SM
+ebullience/M
+ebullient/Y
+ebullition/M
+eccentric/SM
+eccentrically
+eccentricity/SM
+eccl
+ecclesial
+ecclesiastic/SM
+ecclesiastical/Y
+echelon/SM
+echidna
+echinoderm/SM
+echo's
+echo/ADG
+echoes/A
+echoic
+echolocation/M
+echos
+eclair/SM
+eclat/M
+eclectic/SM
+eclectically
+eclecticism/M
+eclipse/DSMG
+ecliptic/M
+eclogue/SM
+ecocide/M
+ecol
+ecologic
+ecological/Y
+ecologist/MS
+ecology/M
+econ
+econometric/S
+economic/S
+economical/UY
+economics/M
+economist/SM
+economize/DRSZG
+economizer/M
+economy/SM
+ecosystem/MS
+ecotourism/M
+ecotourist/MS
+ecru/M
+ecstasy/SM
+ecstatic
+ecstatically
+ectopic
+ectopically
+ecu/S
+ecumenical/Y
+ecumenicism/M
+ecumenism/M
+eczema/M
+ed/ACSM
+edamame
+eddy/DSMG
+edelweiss/M
+edema/SM
+edge/MZGJDRS
+edger/M
+edgeways
+edgewise
+edgily
+edginess/M
+edging/M
+edgy/RTP
+edibility/M
+edible/SMP
+edibleness/M
+edict/SM
+edification/M
+edifice/SM
+edifier/M
+edify/DRSZGN
+edifying/U
+edit's
+edit/ADGS
+editable
+edited/U
+edition/MS
+editor/SM
+editorial/SMY
+editorialize/DSG
+editorship/M
+educ
+educability/M
+educable/I
+educate/ADSGNV
+educated/U
+education/AM
+educational/Y
+educationalist/S
+educationist/S
+educations
+educator/MS
+educe/DSGB
+edutainment/M
+eek
+eel/SM
+eerie/RT
+eerily
+eeriness/M
+eff/GSD
+efface/DSLG
+effacement/M
+effect/SMDGV
+effective/IPY
+effectiveness/IM
+effectual/IY
+effectuate/DSG
+effeminacy/M
+effeminate/Y
+effendi/SM
+efferent
+effervesce/GDS
+effervescence/M
+effervescent/Y
+effete/YP
+effeteness/M
+efficacious/Y
+efficacy/IM
+efficiency/ISM
+efficient/IY
+effigy/SM
+efflorescence/M
+efflorescent
+effluence/M
+effluent/MS
+effluvia
+effluvium/M
+efflux
+effort/SM
+effortful
+effortless/YP
+effortlessness/M
+effrontery/M
+effulgence/M
+effulgent
+effuse/DSGNVX
+effusion/M
+effusive/YP
+effusiveness/M
+egad/S
+egalitarian/SM
+egalitarianism/M
+egg/GSMD
+eggbeater/MS
+eggcup/SM
+egghead/SM
+eggnog/M
+eggplant/MS
+eggshell/SM
+eglantine/SM
+ego/SM
+egocentric/MS
+egocentrically
+egocentricity/M
+egoism/M
+egoist/SM
+egoistic
+egoistical/Y
+egomania/M
+egomaniac/MS
+egotism/M
+egotist/SM
+egotistic
+egotistical/Y
+egregious/PY
+egregiousness/M
+egress/MS
+egret/SM
+eh
+eider/SM
+eiderdown/MS
+eigenvalue/S
+eigenvector/S
+eight/SM
+eighteen/MHS
+eighteenth/M
+eighteenths
+eighth/M
+eighths
+eightieth/M
+eightieths
+eighty/SMH
+einsteinium/M
+eisteddfod/S
+either
+ejaculate/GNXDS
+ejaculation/M
+ejaculatory
+eject/SDG
+ejection/MS
+ejector/SM
+eke/DSG
+elaborate/YGNDSPX
+elaborateness/M
+elaboration/M
+elan/M
+eland/SM
+elapse/DSG
+elastic/MS
+elastically
+elasticated
+elasticity/M
+elasticize/DSG
+elate/DSGN
+elated/Y
+elation/M
+elbow/SMDG
+elbowroom/M
+elder/SMY
+elderberry/SM
+eldercare/M
+eldest
+eldritch
+elect's
+elect/ASDGV
+electable
+election/AMS
+electioneer/DGS
+elective/MS
+elector/MS
+electoral/Y
+electorate/MS
+electric/S
+electrical/Y
+electrician/MS
+electricity/M
+electrification/M
+electrifier/M
+electrify/ZGNDRS
+electrocardiogram/MS
+electrocardiograph/M
+electrocardiographs
+electrocardiography/M
+electrocute/DSXGN
+electrocution/M
+electrode/SM
+electrodynamics
+electroencephalogram/MS
+electroencephalograph/M
+electroencephalographic
+electroencephalographs
+electroencephalography/M
+electrologist/SM
+electrolysis/M
+electrolyte/MS
+electrolytic
+electromagnet/MS
+electromagnetic
+electromagnetically
+electromagnetism/M
+electromotive
+electron/MS
+electronic/S
+electronica/M
+electronically
+electronics/M
+electroplate/DSG
+electroscope/SM
+electroscopic
+electroshock/M
+electrostatic/S
+electrostatics/M
+electrotype/MS
+electroweak
+eleemosynary
+elegance/IM
+elegant/IY
+elegiac/MS
+elegiacal
+elegy/SM
+elem
+element/MS
+elemental/Y
+elementary
+elephant/SM
+elephantiasis/M
+elephantine
+elev
+elevate/XDSGN
+elevation/M
+elevator/MS
+eleven/SMH
+elevens/S
+eleventh/M
+elevenths
+elf/M
+elfin
+elfish
+elicit/SDG
+elicitation/M
+elicitor/MS
+elide/DSG
+eligibility/IM
+eligible
+eliminate/XDSGN
+elimination/M
+eliminator/S
+elision/MS
+elite/SM
+elitism/M
+elitist/MS
+elixir/SM
+elk/SM
+ell/SM
+ellipse/MS
+ellipsis/M
+ellipsoid/SM
+ellipsoidal
+elliptic
+elliptical/Y
+elm/SM
+elocution/M
+elocutionary
+elocutionist/SM
+elodea/SM
+elongate/DSGNX
+elongation/M
+elope/DSGL
+elopement/MS
+eloquence/M
+eloquent/Y
+else/M
+elsewhere
+elucidate/DSGNX
+elucidation/M
+elude/DSG
+elusive/YP
+elusiveness/M
+elver/SM
+elves
+elvish
+em's
+em/S
+emaciate/GNDS
+emaciation/M
+email/SMDG
+emanate/XDSGN
+emanation/M
+emancipate/DSGN
+emancipation/M
+emancipator/MS
+emasculate/GNDS
+emasculation/M
+embalm/SZGDR
+embalmer/M
+embank/SLGD
+embankment/SM
+embargo/MDG
+embargoes
+embark/AEGDS
+embarkation/EM
+embarkations
+embarrass/GLDS
+embarrassed/U
+embarrassing/Y
+embarrassment/SM
+embassy/SM
+embattled
+embattlement/SM
+embed/S
+embedded
+embedding
+embellish/LGDS
+embellishment/SM
+ember/SM
+embezzle/ZGLDRS
+embezzlement/M
+embezzler/M
+embiggen
+embitter/GLDS
+embitterment/M
+emblazon/GDLS
+emblazonment/M
+emblem/SM
+emblematic
+emblematically
+embodiment/EM
+embody/AEGSD
+embolden/DGS
+embolism/MS
+embolization
+emboss/DRSZG
+embosser/M
+embouchure/M
+embower/SGD
+embrace/DSMG
+embraceable
+embrasure/MS
+embrocation/MS
+embroider/SDRZG
+embroiderer/M
+embroidery/SM
+embroil/DGLS
+embroilment/M
+embryo/SM
+embryological
+embryologist/MS
+embryology/M
+embryonic
+emcee/DSM
+emceeing
+emend/SDG
+emendation/MS
+emerald/MS
+emerge/ADSG
+emergence/AM
+emergency/SM
+emergent
+emerita
+emeritus
+emery/M
+emetic/SM
+emf/S
+emigrant/SM
+emigrate/DSXGN
+emigration/M
+emigre/SM
+eminence/MS
+eminent/Y
+emir/MS
+emirate/MS
+emissary/SM
+emission/SM
+emit/S
+emitted
+emitter/MS
+emitting
+emo/SM
+emoji/SM
+emollient/MS
+emolument/MS
+emote/XDSGNV
+emoticon/SM
+emotion/M
+emotional/UY
+emotionalism/M
+emotionalize/GDS
+emotionless
+emotive/Y
+empanel/GDS
+empathetic
+empathic
+empathically
+empathize/DSG
+empathy/M
+emperor/MS
+emphases
+emphasis/M
+emphasize/AGDS
+emphatic/U
+emphatically
+emphysema/M
+empire/SM
+empiric
+empirical/Y
+empiricism/M
+empiricist/SM
+emplace/LGDS
+emplacement/SM
+employ's
+employ/ADGLS
+employable/U
+employee/SM
+employer/SM
+employment/UAM
+employments
+emporium/SM
+empower/SDGL
+empowerment/M
+empress/MS
+emptily
+emptiness/M
+empty/TGPDRSM
+empyrean/M
+emu/SM
+emulate/DSGNVX
+emulation/M
+emulator/SM
+emulsification/M
+emulsifier/M
+emulsify/NDRSZG
+emulsion/MS
+en/SM
+enable/DRSZG
+enabler/M
+enact/ASLDG
+enactment/ASM
+enamel/JSZGMDR
+enameler/M
+enamelware/M
+enamor/SGD
+enc
+encamp/LSGD
+encampment/MS
+encapsulate/XGNDS
+encapsulation/M
+encase/LDSG
+encasement/M
+encephalitic
+encephalitis/M
+enchain/DGS
+enchant/ELDGS
+enchanter/MS
+enchanting/Y
+enchantment/EM
+enchantments
+enchantress/MS
+enchilada/SM
+encipher/SGD
+encircle/DSGL
+encirclement/M
+encl
+enclave/MS
+enclose/GDS
+enclosed/U
+enclosure/SM
+encode/DRSJZG
+encoder/M
+encomium/MS
+encompass/GDS
+encore/DSMG
+encounter/GSMD
+encourage/DSLG
+encouragement/SM
+encouraging/Y
+encroach/GLDS
+encroachment/SM
+encrust/DGS
+encrustation/SM
+encrypt/DGS
+encrypted/U
+encryption
+encumber/EGSD
+encumbered/U
+encumbrance/MS
+ency
+encyclical/SM
+encyclopaedia
+encyclopedia/MS
+encyclopedic
+encyclopedist/MS
+encyst/LSGD
+encystment/M
+end/GVSJMD
+endanger/SGDL
+endangerment/M
+endear/SGLD
+endearing/Y
+endearment/SM
+endeavor/GSMD
+endemic/MS
+endemically
+endgame/S
+ending/M
+endive/SM
+endless/PY
+endlessness/M
+endmost
+endocarditis
+endocrine/MS
+endocrinologist/MS
+endocrinology/M
+endogenous/Y
+endometrial
+endometriosis
+endometrium
+endorphin/MS
+endorse/LZGDRS
+endorsement/MS
+endorser/M
+endoscope/MS
+endoscopic
+endoscopy/M
+endothelial
+endothermic
+endotracheal
+endow/SDLG
+endowment/MS
+endpoint/SM
+endue/DSG
+endurable/U
+endurance/M
+endure/DSBG
+endways
+enema/SM
+enemy/SM
+energetic
+energetically
+energize/ZGDRS
+energizer/M
+energy/SM
+enervate/GNDS
+enervation/M
+enfeeble/GDSL
+enfeeblement/M
+enfilade/DSMG
+enfold/SGD
+enforce/LZGDRS
+enforceable/U
+enforced/U
+enforcement/M
+enforcer/M
+enfranchise/EGDSL
+enfranchisement/EM
+engage/EADSG
+engagement/EMS
+engagingly
+engender/SGD
+engine/SM
+engineer/MDGS
+engineering/M
+engorge/LGDS
+engorgement/M
+engram/SM
+engrave/ZGJDRS
+engraver/M
+engraving/M
+engross/GLDS
+engrossment/M
+engulf/SLGD
+engulfment/M
+enhance/LZGDRS
+enhancement/SM
+enigma/SM
+enigmatic
+enigmatically
+enjambment/SM
+enjoin/SGD
+enjoy/GBLSD
+enjoyably
+enjoyment/SM
+enlarge/LZGDRS
+enlargeable
+enlargement/MS
+enlarger/M
+enlighten/SGLD
+enlightened/U
+enlightenment/M
+enlist/ADGSL
+enlistee/SM
+enlistment/AM
+enlistments
+enliven/SLDG
+enlivenment/M
+enmesh/DSGL
+enmeshment/M
+enmity/SM
+ennoble/DSGL
+ennoblement/M
+ennui/M
+enormity/SM
+enormous/PY
+enormousness/M
+enough/M
+enplane/DSG
+enqueue/DSG
+enquirer/S
+enquiringly
+enrage/GDS
+enrapture/DSG
+enrich/DSLG
+enrichment/M
+enroll/DLSG
+enrollment/MS
+ensconce/DSG
+ensemble/SM
+enshrine/GLDS
+enshrinement/M
+enshroud/DGS
+ensign/MS
+ensilage/M
+enslave/DSGL
+enslavement/M
+ensnare/DSLG
+ensnarement/M
+ensue/DSG
+ensure/ZGDRS
+ensurer/M
+entail/DSGL
+entailment/M
+entangle/EDSLG
+entanglement/EM
+entanglements
+entente/SM
+enter/ASGD
+enteral
+enteric
+enteritis/M
+enterprise/MGS
+enterprising/Y
+entertain/ZGDRSL
+entertainer/M
+entertaining/MY
+entertainment/MS
+enthrall/GDSL
+enthrallment/M
+enthrone/GDSL
+enthronement/SM
+enthuse/DSG
+enthusiasm/MS
+enthusiast/MS
+enthusiastic/U
+enthusiastically
+entice/GDSL
+enticement/MS
+enticing/Y
+entire/Y
+entirety/M
+entitle/DSGL
+entitlement/SM
+entity/SM
+entomb/DSGL
+entombment/M
+entomological
+entomologist/MS
+entomology/M
+entourage/SM
+entr'acte
+entrails/M
+entrained
+entrance/LDSMG
+entrancement/M
+entrancing/Y
+entrant/SM
+entrap/LS
+entrapment/M
+entrapped
+entrapping
+entreat/GSD
+entreating/Y
+entreaty/SM
+entree/MS
+entrench/DSGL
+entrenchment/MS
+entrepreneur/SM
+entrepreneurial
+entrepreneurship
+entropy/M
+entrust/SGD
+entry/ASM
+entryphone/S
+entryway/MS
+entr辿e/MS
+entwine/DSG
+enumerable
+enumerate/DSGNX
+enumeration/M
+enumerator/SM
+enunciate/DSGN
+enunciation/M
+enure/DSG
+enuresis/M
+envelop/SLDRZG
+envelope/SM
+enveloper/M
+envelopment/M
+envenom/SDG
+enviable/U
+enviably
+envious/PY
+enviousness/M
+environment/MS
+environmental/Y
+environmentalism/M
+environmentalist/SM
+environs/M
+envisage/GDS
+envision/DGS
+envoy/SM
+envy/DSMG
+envying/Y
+enzymatic
+enzyme/SM
+eolian
+eon/SM
+eosinophil/S
+eosinophilic
+epaulet/SM
+epee/MS
+ephedrine/M
+ephemera/M
+ephemeral/Y
+epic/MS
+epical/Y
+epicenter/MS
+epicure/SM
+epicurean/MS
+epicycle
+epidemic/SM
+epidemically
+epidemiological
+epidemiologist/SM
+epidemiology/M
+epidermal
+epidermic
+epidermis/MS
+epidural/S
+epiglottis/MS
+epigram/SM
+epigrammatic
+epigraph/M
+epigraphs
+epigraphy/M
+epilepsy/M
+epileptic/SM
+epilogue/MS
+epinephrine/M
+epiphany/SM
+episcopacy/M
+episcopal
+episcopate/M
+episode/SM
+episodic
+episodically
+epistemic
+epistemological
+epistemology
+epistle/SM
+epistolary
+epitaph/M
+epitaphs
+epithelial
+epithelium/M
+epithet/SM
+epitome/SM
+epitomize/GDS
+epoch/M
+epochal
+epochs
+eponymous
+epoxy/DSMG
+epsilon/SM
+equability/M
+equable
+equably
+equal/SMDYG
+equality/IM
+equalization/M
+equalize/ZGDRS
+equalizer/M
+equanimity/M
+equate/DSGNBX
+equation/M
+equator/SM
+equatorial
+equerry/SM
+equestrian/SM
+equestrianism/M
+equestrienne/SM
+equidistant/Y
+equilateral/SM
+equilibrium/EM
+equine/SM
+equinoctial
+equinox/MS
+equip/AS
+equipage/MS
+equipment/M
+equipoise/M
+equipped/UA
+equipping/A
+equitable/I
+equitably/I
+equitation/M
+equity/ISM
+equiv
+equivalence/MS
+equivalency/SM
+equivalent/MYS
+equivocal/UY
+equivocalness/M
+equivocate/GNXDS
+equivocation/M
+equivocator/SM
+er/C
+era/SM
+eradicable/I
+eradicate/DSGN
+eradication/M
+eradicator/MS
+erase/DRSBZG
+eraser/M
+erasure/SM
+erbium/M
+ere
+erect/PSGDY
+erectile
+erection/SM
+erectness/M
+erector/MS
+erelong
+eremite/MS
+erg/SM
+ergo
+ergodic
+ergodicity
+ergonomic/S
+ergonomically
+ergonomics/M
+ergosterol/M
+ergot/M
+ermine/SM
+erode/DSG
+erodible
+erogenous
+erosion/M
+erosive
+erotic/S
+erotica/M
+erotically
+eroticism/M
+err/GSD
+errand/SM
+errant/I
+errata/SM
+erratic
+erratically
+erratum/M
+erroneous/Y
+error/SM
+ersatz/MS
+erst
+erstwhile
+eruct/SDG
+eructation/SM
+erudite/YN
+erudition/M
+erupt/SDGV
+eruption/MS
+erysipelas/M
+erythrocyte/SM
+erythromycin
+escalate/CDSGN
+escalation/CM
+escalations
+escalator/MS
+escallop/SGMD
+escalope/S
+escapade/MS
+escape/LMGDS
+escapee/MS
+escapement/SM
+escapism/M
+escapist/MS
+escapologist/S
+escapology
+escargot/MS
+escarole/MS
+escarpment/MS
+eschatological
+eschatologist/SM
+eschatology
+eschew/SDG
+escort/SMDG
+escritoire/MS
+escrow/SM
+escudo/SM
+escutcheon/SM
+esophageal
+esophagi
+esophagus/MS
+esoteric
+esoterically
+esp
+espadrille/MS
+espalier/MDSG
+especial/Y
+espionage/M
+esplanade/MS
+espousal/M
+espouse/GDS
+espresso/MS
+esprit/M
+espy/DSG
+esquire/SM
+essay/SMDRZG
+essayer/M
+essayist/SM
+essence/SM
+essential/IMS
+essentially
+establish/AESDGL
+establishment/AEM
+establishments
+estate/SM
+esteem/ESMDG
+ester/SM
+esthetic/S
+estimable/I
+estimate/MGNDSX
+estimation/M
+estimator/SM
+estoppel
+estradiol
+estrange/LDSG
+estrangement/MS
+estrogen/MS
+estrous
+estrus/MS
+estuary/SM
+et
+eta/SM
+etc
+etch/DRSZGJ
+etcher/M
+etching/M
+eternal/YP
+eternalness/M
+eternity/SM
+ethane/M
+ethanol/M
+ether/M
+ethereal/Y
+ethic/SM
+ethical/UY
+ethicist/SM
+ethics/M
+ethmoid
+ethnic/SM
+ethnically
+ethnicity/M
+ethnocentric
+ethnocentrism/M
+ethnographer/S
+ethnographic
+ethnographically
+ethnography
+ethnological/Y
+ethnologist/SM
+ethnology/M
+ethological
+ethologist/MS
+ethology/M
+ethos/M
+ethyl/M
+ethylene/M
+etiolated
+etiologic
+etiological
+etiology/SM
+etiquette/M
+etude/SM
+etymological/Y
+etymologist/SM
+etymology/SM
+eucalypti
+eucalyptus/MS
+eucaryote/SM
+eucaryotic
+euchre/DSMG
+euclidean
+eugenic/S
+eugenically
+eugenicist/MS
+eugenics/M
+eukaryote/SM
+eukaryotic
+eulogist/MS
+eulogistic
+eulogize/ZGDRS
+eulogizer/M
+eulogy/SM
+eunuch/M
+eunuchs
+euphemism/SM
+euphemistic
+euphemistically
+euphonious/Y
+euphony/M
+euphoria/M
+euphoric
+euphorically
+eureka
+euro/MS
+europium/M
+eutectic
+euthanasia/M
+euthanize/DSG
+euthenics/M
+eutrophic
+eutrophication
+evacuate/XDSGN
+evacuation/M
+evacuee/MS
+evade/DRSZG
+evader/M
+evaluate/AGNVDSX
+evaluation/AM
+evaluator/S
+evanescence/M
+evanescent
+evangelic
+evangelical/SMY
+evangelicalism/M
+evangelism/M
+evangelist/MS
+evangelistic
+evangelize/GDS
+evaporate/GNDS
+evaporation/M
+evaporator/SM
+evasion/SM
+evasive/YP
+evasiveness/M
+eve/ASM
+even/MDRYTGSJP
+evenhanded/Y
+evening/M
+evenness/UM
+evensong/M
+event/SM
+eventful/UY
+eventfulness/M
+eventide/M
+eventual/Y
+eventuality/SM
+eventuate/GDS
+ever
+everglade/SM
+evergreen/SM
+everlasting/MYS
+evermore
+every
+everybody/M
+everyday
+everyone/M
+everyplace
+everything/M
+everywhere
+evict/SDG
+eviction/MS
+evidence/MGDS
+evident/Y
+evidential/Y
+evidentiality
+evidentiary
+evil/MRYTSP
+evildoer/SM
+evildoing/M
+eviller
+evillest
+evilness/M
+evince/DSG
+eviscerate/DSGN
+evisceration/M
+evocation/MS
+evocative/Y
+evoke/DSG
+evolution/M
+evolutionary
+evolutionist/SM
+evolve/DSG
+ewe/RSMZ
+ewer/M
+ex/MS
+exabyte/MS
+exacerbate/GNDS
+exacerbation/M
+exact/SBPDRYTG
+exacta/S
+exacting/PY
+exaction/SM
+exactitude/M
+exactness/IM
+exactor/MS
+exaggerate/XDSGN
+exaggerated/Y
+exaggeration/M
+exaggerator/MS
+exajoule/S
+exalt/SDG
+exaltation/M
+exam/MS
+examination/AMS
+examine/AGDS
+examined/U
+examiner/MS
+example/MGDS
+exampled/U
+exasperate/DSGN
+exasperated/Y
+exasperating/Y
+exasperation/M
+exbibyte/MS
+excavate/GNDSX
+excavation/M
+excavator/SM
+exceed/GSD
+exceeding/Y
+excel/S
+excelled
+excellence/M
+excellency/SM
+excellent/Y
+excelling
+excelsior/M
+except/GSD
+exception/BSM
+exceptionable/U
+exceptional/UY
+exceptionalism
+excerpt/MDGS
+excess/VMS
+excessive/Y
+exchange/DSMG
+exchangeable
+exchequer/SM
+excise/XDSMGN
+excision/M
+excitability/M
+excitably
+excitation/M
+excite/BDRSLZG
+excited/Y
+excitement/SM
+exciter/M
+exciting/Y
+exciton
+excl
+exclaim/DGS
+exclamation/SM
+exclamatory
+exclude/GDS
+exclusion/MS
+exclusionary
+exclusive/PMYS
+exclusiveness/M
+exclusivity/M
+excommunicate/GNDSX
+excommunication/M
+excoriate/DSGNX
+excoriation/M
+excrement/M
+excremental
+excrescence/MS
+excrescent
+excreta/M
+excrete/XGNDS
+excretion/M
+excretory
+excruciating/Y
+exculpate/DSGN
+exculpation/M
+exculpatory
+excursion/MS
+excursionist/MS
+excursive/YP
+excursiveness/M
+excusable/I
+excusably/I
+excuse/DSBMG
+excused/U
+exec/MS
+execrable
+execrably
+execrate/DSGN
+execration/M
+execute/BXGNVDS
+execution/ZMR
+executioner/M
+executive/SM
+executor/MS
+executrices
+executrix/M
+exegeses
+exegesis/M
+exegetic
+exegetical
+exemplar/SM
+exemplary
+exemplification/M
+exemplify/GDSXN
+exempt/SGD
+exemption/SM
+exercise/DRSMZG
+exerciser/M
+exert/SDG
+exertion/MS
+exeunt
+exfiltrate/GNXDS
+exfoliate/GNDS
+exhalation/MS
+exhale/DSG
+exhaust/GVMDS
+exhaustible/I
+exhaustion/M
+exhaustive/YP
+exhaustiveness/M
+exhibit/GMDS
+exhibition/MS
+exhibitionism/M
+exhibitionist/MS
+exhibitor/SM
+exhilarate/DSGN
+exhilaration/M
+exhort/SDG
+exhortation/MS
+exhumation/MS
+exhume/DSG
+exigence/MS
+exigency/SM
+exigent
+exiguity/M
+exiguous
+exile/DSMG
+exilic
+exist/SDG
+existence/MS
+existent
+existential/Y
+existentialism/M
+existentialist/MS
+exit/MDGS
+exobiology/M
+exodus/MS
+exogenous
+exon/MS
+exonerate/GNDSX
+exoneration/M
+exoplanet/MS
+exorbitance/M
+exorbitant/Y
+exorcise/DSG
+exorcism/SM
+exorcist/SM
+exoskeleton/SM
+exosphere/SM
+exothermic
+exotic/SM
+exotica
+exotically
+exoticism/M
+exp
+expand/BGSD
+expanse/XMNVS
+expansible
+expansion/M
+expansionary
+expansionism/M
+expansionist/MS
+expansive/YP
+expansiveness/M
+expat/S
+expatiate/GNDS
+expatiation/M
+expatriate/DSMGN
+expatriation/M
+expect/GSD
+expectancy/M
+expectant/Y
+expectation/SM
+expectorant/SM
+expectorate/DSGN
+expectoration/M
+expedience/IM
+expediences
+expediencies
+expediency/IM
+expedient/SMY
+expedite/DRSZGNX
+expediter/M
+expedition/M
+expeditionary
+expeditious/PY
+expeditiousness/M
+expel/S
+expelled
+expelling
+expend/GSBD
+expendable/SM
+expenditure/SM
+expense/MS
+expensive/IYP
+expensiveness/IM
+experience/IMD
+experiences
+experiencing
+experiential
+experiment/MDRSZG
+experimental/Y
+experimentalism
+experimentalist
+experimentation/M
+experimenter/M
+expert/SPMY
+expertise/M
+expertness/M
+expiate/GNDS
+expiation/M
+expiatory
+expiration/M
+expire/DSG
+expired/U
+expiry/M
+explain/ADGS
+explainable/U
+explained/U
+explainer/S
+explanation/MS
+explanatory
+expletive/MS
+explicable/I
+explicate/XGNDS
+explication/M
+explicit/PY
+explicitness/M
+explode/GDS
+exploded/U
+exploit/ZGVBMDRS
+exploitation/M
+exploitative
+exploited/U
+exploiter/M
+exploration/MS
+explorative
+exploratory
+explore/ZGDRS
+explored/U
+explorer/M
+explosion/SM
+explosive/SPMY
+explosiveness/M
+expo/MS
+exponent/MS
+exponential/Y
+exponentiation
+export/BSZGMDR
+exportation/M
+exporter/M
+expose/DSMG
+exposed/U
+exposition/SM
+expositor/SM
+expository
+expostulate/GNXDS
+expostulation/M
+exposure/MS
+expos辿
+expound/ZGDRS
+expounder/M
+express/GVMDSY
+expressed/U
+expressible/I
+expression/SM
+expressionism/M
+expressionist/SM
+expressionistic
+expressionless/Y
+expressive/PY
+expressiveness/M
+expressway/SM
+expropriate/GNXDS
+expropriation/M
+expropriator/SM
+expulsion/MS
+expunction
+expunge/LGDS
+expungement/S
+expurgate/DSGNX
+expurgated/U
+expurgation/M
+exquisite/YP
+exquisiteness/M
+ext
+extant
+extemporaneous/PY
+extemporaneousness/M
+extempore
+extemporization/M
+extemporize/GDS
+extend/SZGDRB
+extender/M
+extendible
+extensibility
+extensible
+extension/SM
+extensional
+extensive/YP
+extensiveness/M
+extensor/MS
+extent/SM
+extenuate/DSGN
+extenuation/M
+exterior/MS
+exterminate/DSXGN
+extermination/M
+exterminator/MS
+external/MYS
+externalization/SM
+externalize/DSG
+extinct/GDS
+extinction/MS
+extinguish/ZGBDRS
+extinguishable/I
+extinguisher/M
+extirpate/GNDS
+extirpation/M
+extol/S
+extolled
+extolling
+extort/SGD
+extortion/MRZ
+extortionary
+extortionate/Y
+extortioner/M
+extortionist/MS
+extra/SM
+extracellular
+extract/MDGVS
+extraction/SM
+extractor/MS
+extracurricular
+extradite/GNBXDS
+extradition/M
+extrajudicial
+extralegal
+extramarital
+extramural
+extraneous/Y
+extraordinaire
+extraordinarily
+extraordinary
+extrapolate/XGNDS
+extrapolation/M
+extrasensory
+extraterrestrial/MS
+extraterritorial
+extraterritoriality/M
+extravagance/MS
+extravagant/Y
+extravaganza/MS
+extravehicular
+extrema
+extreme/PMYTRS
+extremeness/M
+extremism/M
+extremist/MS
+extremity/SM
+extremum/S
+extricable/I
+extricate/GNDS
+extrication/M
+extrinsic
+extrinsically
+extroversion/M
+extrovert/SMD
+extrude/GDS
+extrusion/SM
+extrusive
+exuberance/M
+exuberant/Y
+exudation/M
+exude/DSG
+exult/SDG
+exultant/Y
+exultation/M
+exurb/SM
+exurban
+exurbanite/SM
+exurbia/M
+eye/DSMG
+eyeball/GMDS
+eyebrow/SM
+eyedropper/SM
+eyeful/SM
+eyeglass/MS
+eyeing
+eyelash/MS
+eyeless
+eyelet/SM
+eyelid/SM
+eyeliner/MS
+eyeopener/MS
+eyeopening
+eyepiece/MS
+eyesight/M
+eyesore/MS
+eyestrain/M
+eyeteeth
+eyetooth/M
+eyewash/M
+eyewitness/MS
+f/CIAVTR
+fMRI
+fa/M
+fab
+fable/DSM
+fabric/SM
+fabricate/DSGNX
+fabrication/M
+fabricator/SM
+fabulous/Y
+facade/SM
+face's
+face/ACSDG
+facecloth/M
+facecloths
+faceless
+facelift/SM
+facepalm/SDG
+facet/SMDG
+facetious/YP
+facetiousness/M
+facial/SMY
+facile/Y
+facilitate/GNDS
+facilitation/M
+facilitator/MS
+facility/SM
+facing/SM
+facsimile/DSM
+facsimileing
+fact/MS
+faction/SM
+factional
+factionalism/M
+factious
+factitious
+facto
+factoid/SM
+factor's
+factor/ASDG
+factorial/MS
+factorization
+factorize/GDS
+factory/SM
+factotum/SM
+factual/Y
+faculty/SM
+fad/GSMD
+faddish/P
+faddist/MS
+faddy/P
+fade/MS
+fading/U
+faerie/SM
+faff/DGS
+fag/SM
+fagged
+fagging
+faggot/SMG
+fagot/SMG
+faience/M
+fail/DGJS
+failing/M
+faille/M
+failure/SM
+fain/RT
+faint/SMDRYTGP
+fainthearted
+faintness/M
+fair/MRYTGJPS
+fairground/MS
+fairing/M
+fairness/UM
+fairway/SM
+fairy/SM
+fairyland/SM
+faith/M
+faithful's
+faithful/UPY
+faithfulness/UM
+faithfuls
+faithless/PY
+faithlessness/M
+faiths
+fajita/SM
+fajitas/M
+fake/MZGDRS
+faker/M
+fakir/SM
+falcon/SMRZ
+falconer/M
+falconry/M
+fall/MNGS
+fallacious/Y
+fallacy/SM
+fallback
+fallibility/IM
+fallible/P
+fallibleness/M
+fallibly/I
+falloff/SM
+fallout/M
+fallow/SMDG
+false/PRYT
+falsehood/SM
+falseness/M
+falsetto/SM
+falsie/SM
+falsifiable/U
+falsification/M
+falsifier/M
+falsify/DRSZGNX
+falsity/SM
+falter/GSJMD
+faltering/Y
+fame's
+fame/D
+familial
+familiar/MYS
+familiarity/UM
+familiarization/M
+familiarize/GDS
+family/SM
+famine/SM
+famish/DSG
+famous/IY
+fan/SM
+fanatic/SM
+fanatical/Y
+fanaticism/M
+fanboy/SM
+fanciable
+fancier/M
+fanciful/YP
+fancifulness/M
+fancily
+fanciness/M
+fancy/DRSMZTGP
+fancywork/M
+fandango/MS
+fandom
+fanfare/SM
+fang/MDS
+fanlight/SM
+fanned
+fanning
+fanny/SM
+fantail/MS
+fantasia/SM
+fantasist/S
+fantasize/GDS
+fantastic
+fantastical/Y
+fantasy/DSMG
+fanzine/MS
+far
+farad/SM
+faradize/DG
+faraway
+farce/SM
+farcical/Y
+fare/MGDS
+farewell/SM
+farfetched
+farina/M
+farinaceous
+farm/MDRZGSJ
+farmer/M
+farmhand/SM
+farmhouse/SM
+farming/M
+farmland/MS
+farmstead/MS
+farmyard/MS
+faro/M
+farrago/M
+farragoes
+farrier/MS
+farrow/SMDG
+farseeing
+farsighted/P
+farsightedness/M
+fart/MDGS
+farther
+farthermost
+farthest
+farthing/SM
+fascia/SM
+fascicle/SM
+fascinate/GNDSX
+fascinating/Y
+fascination/M
+fascism/M
+fascist/MS
+fascistic
+fashion/ZGBMDRS
+fashionable/U
+fashionably/U
+fashioner/M
+fashionista/MS
+fast/MDRTGSP
+fastback/SM
+fastball/SM
+fasten/UAGDS
+fastener/SM
+fastening/MS
+fastidious/PY
+fastidiousness/M
+fastness/MS
+fat/GSPMD
+fatal/Y
+fatalism/M
+fatalist/SM
+fatalistic
+fatalistically
+fatality/SM
+fatback/M
+fate/MS
+fateful/YP
+fatefulness/M
+fathead/MDS
+father/SGMDY
+fatherhood/M
+fatherland/MS
+fatherless
+fathom/SMDGB
+fathomable/U
+fathomless
+fatigue/MDSG
+fatigues/M
+fatness/M
+fatso/S
+fatten/SDG
+fatter
+fattest
+fattiness/M
+fatty/RSMTP
+fatuity/M
+fatuous/YP
+fatuousness/M
+fatwa/SM
+faucet/SM
+fault/CSMDG
+faultfinder/SM
+faultfinding/M
+faultily
+faultiness/M
+faultless/PY
+faultlessness/M
+faulty/PRT
+faun/MS
+fauna/SM
+fauvism/M
+fauvist/SM
+faux
+fav/S
+fave/S
+favor/ESMDG
+favorable/U
+favorably/U
+favorite/SM
+favoritism/M
+fawn/MDRZGS
+fawner/M
+fax/GMDS
+fay/TSMR
+faze/GDS
+fazed/U
+fa誰ence/M
+fealty/M
+fear/MDGS
+fearful/YP
+fearfulness/M
+fearless/PY
+fearlessness/M
+fearmonger/MSG
+fearsome
+feasibility/M
+feasible/IU
+feasibly
+feast/SMDRZG
+feaster/M
+feat/MS
+feather/SGMD
+featherbedding/M
+featherbrained
+featherless
+featherweight/MS
+feathery/TR
+feature/DSMG
+featureless
+febrile
+fecal
+feces/M
+feckless/PY
+fecund
+fecundate/GNDS
+fecundation/M
+fecundity/M
+fed/SM
+federal/SMY
+federalism/M
+federalist/MS
+federalization/M
+federalize/GDS
+federate/FXDSGN
+federation/FM
+fedora/SM
+fee/SM
+feeble/RTP
+feebleness/M
+feebly
+feed/MRZGSJ
+feedback/M
+feedbag/SM
+feeder/M
+feeding/M
+feedlot/SM
+feel/MRZGSJ
+feeler/M
+feelgood
+feeling/MY
+feet
+feign/SDG
+feigned/U
+feint/SMDG
+feisty/TR
+feldspar/M
+felicitate/GNXDS
+felicitation/M
+felicitous/Y
+felicity/ISM
+feline/SM
+fell/MDRZTGS
+fella/S
+fellatio/M
+fellow/SM
+fellowman/M
+fellowmen
+fellowship/MS
+felon/SM
+felonious
+felony/SM
+felt/MDGS
+fem
+female/PSM
+femaleness/M
+feminine/SMY
+femininity/M
+feminism/M
+feminist/SM
+feminize/DSG
+femoral
+femur/SM
+fen/SM
+fence/DRSMZG
+fencer/M
+fencing/M
+fend/CDRZGS
+fender/CM
+fenestration/M
+fennel/M
+fentanyl/M
+feral
+ferment/FCMS
+fermentation/M
+fermented
+fermenting
+fermion
+fermium/M
+fern/MS
+ferny/RT
+ferocious/PY
+ferociousness/M
+ferocity/M
+ferret/GSMD
+ferric
+ferrite
+ferritin
+ferromagnetic
+ferromagnetism
+ferrous
+ferrule/MS
+ferry/DSMG
+ferryboat/SM
+ferryman/M
+ferrymen
+fertile/I
+fertility/IM
+fertilization/M
+fertilize/DRSZG
+fertilized/U
+fertilizer/M
+ferule/SM
+fervency/M
+fervent/Y
+fervid/Y
+fervor/M
+fess/FKGSD
+fest/MRZVS
+festal
+fester/GMD
+festival/SM
+festive/YP
+festiveness/M
+festivity/SM
+festoon/GMDS
+feta/M
+fetal
+fetch/DRSZG
+fetcher/M
+fetching/Y
+fete/MGDS
+fetid/P
+fetidness/M
+fetish/MS
+fetishism/M
+fetishist/SM
+fetishistic
+fetlock/MS
+fetter's
+fetter/USGD
+fettle/M
+fettuccine/M
+fetus/MS
+feud/MDGS
+feudal
+feudalism/M
+feudalistic
+fever/SMD
+feverish/YP
+feverishness/M
+few/TPMR
+fewness/M
+fey
+fez/M
+fezzes
+ff
+fiance/CM
+fiancee/MS
+fiances
+fianc辿/SM
+fianc辿e/MS
+fiasco/SM
+fiascoes
+fiat/MS
+fib/ZSMR
+fibbed
+fibber/SM
+fibbing
+fiber/M
+fiberboard/M
+fiberfill/M
+fiberglass/M
+fibril/SM
+fibrillate/GNDS
+fibrillation/M
+fibrin/M
+fibroid
+fibromyalgia/M
+fibromyalgic/S
+fibrosis/M
+fibrous
+fibula/M
+fibulae
+fibular
+fiche/SM
+fichu/SM
+fickle/RPT
+fickleness/M
+fiction/MS
+fictional/Y
+fictionalization/SM
+fictionalize/DSG
+fictitious/Y
+fictive
+ficus/M
+fiddle/DRSMZG
+fiddler/M
+fiddlesticks
+fiddly/TR
+fidelity/IM
+fides
+fidget/SGMD
+fidgety
+fiduciary/SM
+fie
+fief/MS
+fiefdom/MS
+field/ISMRZ
+fielded
+fielder/IM
+fielding
+fieldsman
+fieldsmen
+fieldwork/MRZ
+fieldworker/M
+fiend/SM
+fiendish/Y
+fierce/PRYT
+fierceness/M
+fieriness/M
+fiery/RPT
+fiesta/SM
+fife/MZRS
+fifer/M
+fifteen/MHS
+fifteenth/M
+fifteenths
+fifth/MY
+fifths
+fiftieth/M
+fiftieths
+fifty/SMH
+fig/FSM
+fight/SMRZG
+fightback
+fighter/IMS
+fighting/IM
+figment/MS
+figuration/FM
+figurative/Y
+figure's
+figure/EFGSD
+figurehead/SM
+figurine/MS
+filament/MS
+filamentous
+filbert/MS
+filch/DSG
+file/KCSRDGZM
+filename/S
+filer/KCM
+filesystem/SM
+filet
+filial
+filibuster/MDRSZG
+filibusterer/M
+filigree/DSM
+filigreeing
+filing's
+filings
+fill's
+fill/AIDGS
+filled/U
+filler/MS
+fillet/MDGS
+filling/SM
+fillip/MDGS
+filly/SM
+film/MDGS
+filminess/M
+filmmaker/SM
+filmography
+filmstrip/MS
+filmy/TPR
+filo
+filter/MDRBSZG
+filtered/U
+filterer/M
+filth/M
+filthily
+filthiness/M
+filthy/RPT
+filtrate's
+filtrate/IGNDS
+filtration/IM
+fin/SMR
+finagle/DRSZG
+finagler/M
+final/SMY
+finale/MS
+finalist/SM
+finality/M
+finalization/M
+finalize/DSG
+finance's
+finance/ADSG
+financial/YS
+financier/MS
+financing/M
+finch/MS
+find/BJMRZGS
+finder/M
+finding/M
+findings/M
+fine's/F
+fine/CAFTGDS
+fineable
+finely
+fineness/M
+finery/AM
+finespun
+finesse/DSMG
+finger/MDGSJ
+fingerboard/SM
+fingering/M
+fingerling/SM
+fingermark/S
+fingernail/SM
+fingerprint/SGMD
+fingertip/MS
+finial/MS
+finical
+finickiness/M
+finicky/RPT
+finis/MS
+finish's
+finish/ADSG
+finished/U
+finisher/MS
+finite/IY
+fink/MDGS
+finned
+finny
+fintech
+fintechs
+fir/ZGSJMDRH
+fire/MS
+firearm/SM
+fireball/MS
+firebomb/MDSJG
+firebox/MS
+firebrand/SM
+firebreak/SM
+firebrick/SM
+firebug/SM
+firecracker/SM
+firedamp/M
+firefight/MRSZG
+firefighter/M
+firefighting/M
+firefly/SM
+fireguard/S
+firehouse/SM
+firelight/ZMR
+fireman/M
+firemen
+fireplace/SM
+fireplug/MS
+firepower/M
+fireproof/DSG
+firer/M
+firescreen/S
+fireside/MS
+firestorm/MS
+firetrap/MS
+firetruck/MS
+firewall/MS
+firewater/M
+firewood/M
+firework/SM
+firm/MDRYPTGS
+firmament/SM
+firmness/M
+firmware/M
+first/SMY
+firstborn/SM
+firsthand
+firth/M
+firths
+fiscal/MYS
+fish/MDRSZG
+fishbowl/SM
+fishcake/SM
+fisher/M
+fisherman/M
+fishermen
+fishery/SM
+fishhook/SM
+fishily
+fishiness/M
+fishing/M
+fishmonger/MS
+fishnet/SM
+fishpond/MS
+fishtail/DGS
+fishwife/M
+fishwives
+fishy/TRP
+fissile
+fission/BM
+fissionable/S
+fissure/SM
+fist/MS
+fistfight/MS
+fistful/SM
+fisticuffs/M
+fistula/SM
+fistulous/M
+fit/KAMS
+fitful/YP
+fitfulness/M
+fitly
+fitment/S
+fitness/UM
+fitted/UA
+fitter/MS
+fittest
+fitting/SMY
+five/MZRS
+fix/ZGBJMDRS
+fixate/GNVDSX
+fixation/M
+fixative/MS
+fixed/Y
+fixer/M
+fixings/M
+fixity/M
+fixture/MS
+fizz/MDSG
+fizzle/DSMG
+fizzy/RT
+fjord/SM
+fl/JDG
+flab/M
+flabbergast/SGD
+flabbily
+flabbiness/M
+flabby/RPT
+flaccid/Y
+flaccidity/M
+flack/SM
+flag/MS
+flagella
+flagellant/S
+flagellate/GNDS
+flagellation/M
+flagellum/M
+flagged
+flagging/U
+flagman/M
+flagmen
+flagon/MS
+flagpole/SM
+flagrance/M
+flagrancy/M
+flagrant/Y
+flagship/SM
+flagstaff/MS
+flagstone/MS
+flail/SGMD
+flair/SM
+flak/M
+flake/DSMG
+flakiness/M
+flaky/TRP
+flamage
+flambe/MS
+flambeed
+flambeing
+flamboyance/M
+flamboyancy/M
+flamboyant/Y
+flamb辿/MD
+flame/DRSJMZG
+flamenco/MS
+flameproof/DGS
+flamethrower/SM
+flamingo/MS
+flammability/IM
+flammable/SM
+flan/MS
+flaneur/SM
+flange/MS
+flank/SZGMDR
+flanker/M
+flannel/SGMD
+flannelette/M
+flap/MS
+flapjack/MS
+flapped
+flapper/SM
+flapping
+flare/DSMG
+flareup/SM
+flash/ZTGMDRS
+flashback/SM
+flashbulb/SM
+flashcard/SM
+flashcube/SM
+flasher/M
+flashgun/SM
+flashily
+flashiness/M
+flashing/M
+flashlight/MS
+flashpoint/SM
+flashy/RTP
+flask/SM
+flat/MYPS
+flatbed/SM
+flatboat/SM
+flatbread
+flatcar/SM
+flatfeet
+flatfish/MS
+flatfoot/SMD
+flatiron/SM
+flatland/M
+flatlet/S
+flatmate/S
+flatness/M
+flatted
+flatten/SDG
+flatter/SDRZG
+flatterer/M
+flattering/Y
+flattery/M
+flattest
+flatting
+flattish
+flattop/SM
+flatulence/M
+flatulent
+flatus/M
+flatware/M
+flatworm/SM
+flaunt/MDSG
+flaunting/Y
+flavor/MDSGJ
+flavored/U
+flavorful
+flavoring/M
+flavorless
+flavorsome
+flaw/MDGS
+flawless/PY
+flawlessness/M
+flax/MN
+flay/DGS
+flea/MS
+fleabag/SM
+fleabite/S
+fleapit/S
+fleck/SGMD
+fledged/U
+fledgling/MS
+flee/S
+fleece/MZGDRS
+fleecer/M
+fleeciness/M
+fleecy/RTP
+fleeing
+fleet/STGMDRYP
+fleetingly/M
+fleetingness/M
+fleetness/M
+flesh/GMDSY
+fleshly/TR
+fleshpot/MS
+fleshy/RT
+flew
+flex/AMS
+flexed
+flexibility/IM
+flexible/I
+flexibly/I
+flexing
+flexion
+flexor/MS
+flextime/M
+flibbertigibbet/SM
+flick/SZGMDR
+flicker/GMD
+flier/M
+flight/MS
+flightiness/M
+flightless
+flighty/PTR
+flimflam/SM
+flimflammed
+flimflamming
+flimsily
+flimsiness/M
+flimsy/TRP
+flinch/GMDS
+fling/GM
+flint/SM
+flintlock/SM
+flinty/TR
+flip/MS
+flippancy/M
+flippant/Y
+flipped
+flipper/MS
+flippest
+flipping
+flippy/S
+flirt/SGMD
+flirtation/MS
+flirtatious/YP
+flirtatiousness/M
+flirty
+flit/MS
+flitted
+flitting
+float/SMDRZG
+floater/M
+flock/SMDG
+flocking/M
+floe/MS
+flog/S
+flogged
+flogger/SM
+flogging/MS
+flood/SMDRG
+floodgate/MS
+floodlight/MDSG
+floodlit
+floodplain/MS
+floodwater/MS
+floor/SMDG
+floorboard/MS
+flooring/M
+floorwalker/SM
+floozie/M
+floozy/SM
+flop/MS
+flophouse/MS
+flopped
+floppily
+floppiness/M
+flopping
+floppy/PRSMT
+flora/SM
+floral
+florescence/IM
+florescent/I
+floret/SM
+florid/PY
+floridness/M
+florin/SM
+florist/SM
+floss/MDSG
+flossy/RT
+flotation/SM
+flotilla/MS
+flotsam/M
+flounce/DSMG
+flouncy
+flounder/MDSG
+flour/SMDG
+flourish/GMDS
+floury
+flout/SMDRZG
+flouter/M
+flow/MDGS
+flowchart/SM
+flower's
+flower/CSDG
+flowerbed/MS
+floweriness/M
+flowering/S
+flowerless
+flowerpot/MS
+flowery/PTR
+flown
+flt
+flu/M
+flub/MS
+flubbed
+flubbing
+fluctuate/GNDSX
+fluctuation/M
+flue/MS
+fluency/M
+fluent/Y
+fluff/SMDG
+fluffiness/M
+fluffy/RPT
+fluid/SMY
+fluidity/M
+fluidize/GS
+fluke/SM
+fluky/RT
+flume/SM
+flummox/DSG
+flung
+flunk/SMDG
+flunky/SM
+fluoresce/DSG
+fluorescence/M
+fluorescent
+fluoridate/GNDS
+fluoridation/M
+fluoride/SM
+fluorine/M
+fluorite/M
+fluorocarbon/MS
+fluoroscope/SM
+fluoroscopic
+fluoxetine
+flurry/GDSM
+flush/MDRSTG
+fluster/MDSG
+flute/DSMG
+fluting/M
+flutist/MS
+flutter/MDSG
+fluttery
+fluvial
+flux/ADGSM
+fly/ZTGBDRSM
+flyaway
+flyblown
+flyby/M
+flybys
+flycatcher/MS
+flyer/SM
+flying/M
+flyleaf/M
+flyleaves
+flyover/MS
+flypaper/SM
+flypast/S
+flysheet/S
+flyspeck/GMDS
+flyswatter/MS
+flytrap/S
+flyway/SM
+flyweight/SM
+flywheel/MS
+fo'c'sle/MS
+foal/MDGS
+foam/MDGS
+foaminess/M
+foamy/RTP
+fob/SM
+fobbed
+fobbing
+focal/Y
+foci
+focus's
+focus/ADSG
+focused/U
+fodder/SM
+foe/SM
+fog's
+fog/CS
+fogbound
+fogged/C
+foggily
+fogginess/M
+fogging/C
+foggy/RTP
+foghorn/MS
+fogy/SM
+fogyish
+foible/SM
+foil/MDGS
+foist/SDG
+fol
+fold's
+fold/AUSGD
+foldaway
+folder/SM
+foldout/MS
+foliage/M
+folic
+folio/SM
+folk/MS
+folklore/M
+folkloric
+folklorist/MS
+folksiness/M
+folksinger/SM
+folksinging/M
+folksy/PTR
+folktale/MS
+folkway/MS
+foll
+follicle/MS
+follow/SDRZGJ
+follower/M
+following/M
+followup/S
+folly/SM
+foment/SGD
+fomentation/M
+fomite/S
+fond/RYTP
+fondant/MS
+fondle/DSG
+fondness/M
+fondue/SM
+font/MS
+fontanel/MS
+fontanelle/MS
+foo
+foobar
+food/MS
+foodie/SM
+foodstuff/SM
+fool/MDGS
+foolery/SM
+foolhardily
+foolhardiness/M
+foolhardy/TPR
+foolish/YP
+foolishness/M
+foolproof
+foolscap/M
+foot/MDRZGSJ
+footage/M
+football/MRZGS
+footballer/M
+footbridge/SM
+footfall/MS
+foothill/MS
+foothold/MS
+footie
+footing/M
+footless
+footlights/M
+footling/MS
+footlocker/SM
+footloose
+footman/M
+footmen
+footnote/MGDS
+footpath/M
+footpaths
+footplate/S
+footprint/SM
+footrace/MS
+footrest/MS
+footsie/SM
+footslogging
+footsore
+footstep/MS
+footstool/SM
+footwear/M
+footwork/M
+footy
+fop/SM
+foppery/M
+foppish/P
+foppishness/M
+for/H
+fora
+forage/DRSMZG
+forager/M
+foray/SMDG
+forbade
+forbear/SMG
+forbearance/M
+forbid/S
+forbidden
+forbidding/YS
+forbore
+forborne
+force/DSMG
+forced/U
+forceful/PY
+forcefulness/M
+forceps/M
+forcible
+forcibly
+ford/MDGSB
+fore/MS
+forearm/GSMD
+forebear/MS
+forebode/GJDS
+foreboding/M
+forecast/MRZGS
+forecaster/M
+forecastle/MS
+foreclose/DSG
+foreclosure/MS
+forecourt/SM
+foredoom/DGS
+forefather/MS
+forefeet
+forefinger/SM
+forefoot/M
+forefront/SM
+foregather/GDS
+forego/G
+foregoes
+foregone
+foreground/GMDS
+forehand/MS
+forehead/MS
+foreign/ZRP
+foreigner/M
+foreignness/M
+foreknew
+foreknow/GS
+foreknowledge/M
+foreknown
+foreleg/SM
+forelimb/MS
+forelock/MS
+foreman/M
+foremast/MS
+foremen
+foremost
+forename/MDS
+forenoon/MS
+forensic/MS
+forensically
+forensics/M
+foreordain/GSD
+forepart/MS
+foreperson/SM
+foreplay/M
+forequarter/MS
+forerunner/MS
+foresail/MS
+foresaw
+foresee/RSBZ
+foreseeable/U
+foreseeing
+foreseen/U
+foreseer/M
+foreshadow/GDS
+foreshore/S
+foreshorten/DSG
+foresight/MD
+foresightedness/M
+foreskin/MS
+forest's
+forest/ACGDS
+forestall/SGD
+forestation/ACM
+forester/MS
+forestland/M
+forestry/M
+foretaste/DSMG
+foretell/GS
+forethought/M
+foretold
+forever/M
+forevermore
+forewarn/DSG
+forewent
+forewoman/M
+forewomen
+foreword/MS
+forfeit/GSMD
+forfeiture/SM
+forgather/SDG
+forgave
+forge/DRSMZGVJ
+forger/M
+forgery/SM
+forget/S
+forgetful/YP
+forgetfulness/M
+forgettable/U
+forgetting
+forging/M
+forgivable/U
+forgive/BRSZGP
+forgiven
+forgiveness/M
+forgiver/M
+forgiving/U
+forgo/RZG
+forgoer/M
+forgoes
+forgone
+forgot
+forgotten/U
+fork/MDGS
+forkful/SM
+forklift/MS
+forlorn/Y
+form's
+form/CAIFDGS
+forma/K
+formal/SMY
+formaldehyde/M
+formalin
+formalism/M
+formalist/MS
+formalities
+formality/IM
+formalization/M
+formalize/GDS
+format/SMV
+formation/CFASM
+formatted/A
+formatting/M
+formed/U
+former/FIAM
+formerly
+formfitting
+formic
+formidable
+formidably
+formless/PY
+formlessness/M
+formula/MS
+formulae
+formulaic
+formulate/ADSGNX
+formulated/U
+formulation/AM
+formulator/SM
+fornicate/GNDS
+fornication/M
+fornicator/MS
+forsake/GS
+forsaken
+forsook
+forsooth
+forswear/SG
+forswore
+forsworn
+forsythia/SM
+fort/MS
+forte/SM
+forthcoming/M
+forthright/YP
+forthrightness/M
+forthwith
+fortieth/M
+fortieths
+fortification/M
+fortified/U
+fortifier/M
+fortify/DRSNZGX
+fortissimo
+fortitude/M
+fortnight/MYS
+fortress/MS
+fortuitous/YP
+fortuitousness/M
+fortuity/M
+fortunate/UY
+fortune/MS
+fortuneteller/SM
+fortunetelling/M
+forty/SMH
+forum/SM
+forward/MDRYZTGSP
+forwarder/M
+forwardness/M
+forwent
+fossa
+fossil/SM
+fossilization/M
+fossilize/GDS
+foster/GSD
+fought
+foul/MDRYTGSP
+foulard/M
+foulmouthed
+foulness/M
+found/FSDG
+foundation/SM
+foundational
+founded/U
+founder/GMDS
+foundling/SM
+foundry/SM
+fount/SM
+fountain/SM
+fountainhead/MS
+four/MHS
+fourfold
+fourposter/SM
+fourscore/M
+foursome/SM
+foursquare
+fourteen/SMH
+fourteenth/M
+fourteenths
+fourth/MY
+fourths
+fowl/MDGS
+fox/GMDS
+foxfire/M
+foxglove/SM
+foxhole/MS
+foxhound/SM
+foxhunt/GS
+foxily
+foxiness/M
+foxtrot/MS
+foxtrotted
+foxtrotting
+foxy/RTP
+foyer/SM
+fps
+fr
+fracas/MS
+frack/SDRZG
+fractal/SM
+fraction/ISM
+fractional/Y
+fractious/YP
+fractiousness/M
+fracture/MGDS
+frag/S
+fragile/RT
+fragility/M
+fragment/GMDS
+fragmentary/M
+fragmentation/M
+fragrance/MS
+fragrant/Y
+frail/RYTP
+frailness/M
+frailty/SM
+frame/DRSMZG
+framed/U
+framer/M
+framework/SM
+franc/SM
+franca
+franchise's
+franchise/EDSG
+franchisee/SM
+franchiser/SM
+franchisor/SM
+francium/M
+francophone
+frangibility/M
+frangible
+frank/SMDRYTGP
+frankfurter/MS
+frankincense/M
+frankness/M
+frantic
+frantically
+frappe/SM
+frapp辿/M
+frat/MS
+fraternal/Y
+fraternity/FSM
+fraternization/M
+fraternize/ZGDRS
+fraternizer/M
+fratricidal
+fratricide/MS
+fraud's
+fraud/S
+fraudster/S
+fraudulence/M
+fraudulent/Y
+fraught
+fray's
+fray/CDGS
+frazzle/MGDS
+freak/SMDG
+freakish/YP
+freakishness/M
+freakout/MS
+freaky/RT
+freckle/DSMG
+freckly
+free/YTDRS
+freebase/MGDS
+freebee/SM
+freebie/SM
+freebooter/SM
+freeborn
+freedman/M
+freedmen
+freedom/SM
+freegan/S
+freehand
+freehold/ZMRS
+freeholder/M
+freeing
+freelance/DRSMZG
+freelancer/M
+freeload/SDRZG
+freeloader/M
+freeman/M
+freemasonry
+freemen
+freephone
+freesia/S
+freestanding
+freestone/SM
+freestyle/SM
+freethinker/SM
+freethinking/M
+freeware/M
+freeway/MS
+freewheel/DGS
+freewill
+freezable
+freeze's
+freeze/UAGS
+freezer/MS
+freezing's
+freight/MDRZGS
+freighter/M
+french
+frenemy/S
+frenetic
+frenetically
+frenzied/Y
+frenzy/DSM
+freq
+frequencies
+frequency/IM
+frequent/DRYSZTG
+frequented/U
+frequenter/M
+fresco/M
+frescoes
+fresh/PNRYXZT
+freshen/ZGDR
+freshener/M
+freshet/MS
+freshman/M
+freshmen
+freshness/M
+freshwater/M
+fret/MS
+fretful/YP
+fretfulness/M
+fretsaw/MS
+fretted
+fretting
+fretwork/M
+friable
+friar/SM
+friary/SM
+fricassee/DSM
+fricasseeing
+fricative/SM
+friction/SM
+frictional
+fridge/SM
+friedcake/MS
+friend's
+friend/UGSDY
+friendless
+friendlies
+friendliness/UM
+friendly's
+friendly/UPTR
+friendship/MS
+frieze/SM
+frig/S
+frigate/MS
+frigged
+frigging
+fright/SXGMDN
+frighten/DG
+frightening/Y
+frightful/PY
+frightfulness/M
+frigid/YP
+frigidity/M
+frigidness/M
+frill/SMD
+frilly/TR
+fringe's
+fringe/IDSG
+frippery/SM
+frisk/SDG
+friskily
+friskiness/M
+frisky/TRP
+frisson/S
+fritter/MDSG
+fritz/M
+frivolity/SM
+frivolous/PY
+frivolousness/M
+frizz/MDSYG
+frizzle/MGDS
+frizzy/TR
+fro
+frock's
+frock/CUS
+frog/MS
+frogging/S
+frogman/M
+frogmarch/GDS
+frogmen
+frogspawn
+frolic/SM
+frolicked
+frolicker/SM
+frolicking
+frolicsome
+from
+frond/SM
+front's
+front/FSDG
+frontage/MS
+frontal/Y
+frontbench/ZRS
+frontier/MS
+frontiersman/M
+frontiersmen
+frontierswoman
+frontierswomen
+frontispiece/MS
+frontward/S
+frosh/M
+frost's
+frost/CSDG
+frostbit
+frostbite/MGS
+frostbitten
+frostily
+frostiness/M
+frosting/SM
+frosty/TPR
+froth/MDG
+frothiness/M
+froths
+frothy/TPR
+froufrou/M
+frown/SMDG
+frowsy/TR
+frowzily
+frowziness/M
+frowzy/TPR
+froze/AU
+frozen/UA
+fructify/DSG
+fructose/M
+frugal/Y
+frugality/M
+fruit/SMDG
+fruitcake/MS
+fruiterer/S
+fruitful/YP
+fruitfulness/M
+fruitiness/M
+fruition/M
+fruitless/PY
+fruitlessness/M
+fruity/TPR
+frump/SM
+frumpish
+frumpy/TR
+frustrate/GNXDS
+frustrating/Y
+frustration/M
+frustum/MS
+fry/GDSM
+fryer/SM
+ft
+ftp/ZGS
+fuchsia/MS
+fuck/SMGDRZ!
+fucker/M!
+fuckhead/SM!
+fuddle/DSMG
+fudge/DSMG
+fuehrer/MS
+fuel's
+fuel/ADGS
+fug
+fugacious/PY
+fugal
+fuggy
+fugitive/MS
+fugue/SM
+fuhrer/SM
+fulcrum/MS
+fulfill/LDGS
+fulfilled/U
+fulfilling/U
+fulfillment/M
+full/MDRZTGSP
+fullback/MS
+fuller/M
+fullness/M
+fully
+fulminate/DSXGN
+fulmination/M
+fulsome/PY
+fulsomeness/M
+fum/S
+fumble/DRSMZG
+fumbler/M
+fumbling/Y
+fume/MGDS
+fumigant/MS
+fumigate/GNDS
+fumigation/M
+fumigator/SM
+fumy/RT
+fun/M
+function/MDGS
+functional/Y
+functionalism
+functionalist/S
+functionality/S
+functionary/SM
+functor
+fund/AMDRZGS
+fundamental/SMY
+fundamentalism/M
+fundamentalist/SM
+funded/U
+funding/M
+fundraiser/MS
+fundraising
+funeral/MS
+funerary
+funereal/Y
+funfair/S
+fungal
+fungi
+fungible/MS
+fungicidal
+fungicide/MS
+fungoid
+fungous
+fungus/M
+funicular/SM
+funk/MDGS
+funkiness/M
+funky/PRT
+funnel/MDGS
+funner
+funnest
+funnily
+funniness/M
+funny/TPRSM
+funnyman/M
+funnymen
+fur/SM
+furbelow/M
+furbish/ADSG
+furious/Y
+furl's
+furl/UDGS
+furlong/SM
+furlough/GMD
+furloughs
+furn
+furnace/SM
+furnish/ADSG
+furnished/U
+furnishings/M
+furniture/M
+furor/SM
+furosemide
+furred
+furrier/M
+furriness/M
+furring/M
+furrow/MDSG
+furry/ZTRP
+further/SGD
+furtherance/M
+furthermore
+furthermost
+furthest
+furtive/YP
+furtiveness/M
+fury/SM
+furze/M
+fuse's/A
+fuse/CAIFGDS
+fusee/SM
+fuselage/SM
+fusibility/M
+fusible
+fusileer/SM
+fusilier/SM
+fusillade/MS
+fusion/IFKSM
+fuss/MDSG
+fussbudget/MS
+fussily
+fussiness/M
+fusspot/SM
+fussy/TRP
+fustian/M
+fustiness/M
+fusty/TRP
+fut
+futile/Y
+futility/M
+futon/SM
+future/MS
+futurism/M
+futurist/MS
+futuristic
+futurity/SM
+futurologist/MS
+futurology/M
+futz/DSG
+fuzz/MDSG
+fuzzball/S
+fuzzily
+fuzziness/M
+fuzzy/PTR
+fwd
+fwy
+f棚te/SM
+g/SNXVB
+gab/SM
+gabardine/SM
+gabbed
+gabbiness/M
+gabbing
+gabble/DSMG
+gabby/RTP
+gaberdine/SM
+gabfest/MS
+gable/DSM
+gad/S
+gadabout/SM
+gadded
+gadder/SM
+gadding
+gadfly/SM
+gadget/SM
+gadgetry/M
+gadolinium/M
+gaff/MDRZGS
+gaffe/SM
+gaffer/M
+gag/SM
+gaga
+gagged
+gagging
+gaggle/SM
+gaiety/M
+gaily
+gain's
+gain/ADGS
+gainer/SM
+gainful/Y
+gainsaid
+gainsay/ZGRS
+gainsayer/M
+gait/MRZS
+gaiter/M
+gal/SM
+gala/MS
+galactic
+galaxy/SM
+gale's
+gale/AS
+galena/M
+gall/MDGS
+gallant/SMY
+gallantry/M
+gallbladder/MS
+galleon/SM
+galleria/MS
+gallery/SM
+galley/SM
+gallimaufry/SM
+gallium/M
+gallivant/GSD
+gallon/SM
+gallop/SMDG
+gallows/M
+gallstone/MS
+galoot/SM
+galore
+galosh/MS
+galumph/DG
+galumphs
+galvanic
+galvanism/M
+galvanization/M
+galvanize/DSG
+galvanometer/MS
+gambit/SM
+gamble/DRSMZG
+gambler/M
+gambling/M
+gambol/SMDG
+game/MYTGDRSP
+gamecock/MS
+gamekeeper/MS
+gameness/M
+gamesmanship/M
+gamester/MS
+gamete/SM
+gametic
+gamey
+gamify/DSNG
+gamin/SM
+gamine/SM
+gaminess/M
+gaming/M
+gamma/SM
+gammon/M
+gammy
+gamut/SM
+gamy/RTP
+gander/SM
+gang/MDGS
+gangbusters/M
+gangland/M
+ganglia
+gangling
+ganglion/M
+ganglionic
+gangplank/SM
+gangrene/DSMG
+gangrenous
+gangsta/S
+gangster/SM
+gangway/MS
+ganja
+gannet/SM
+gantlet/MS
+gantry/SM
+gap/GSMD
+gape/MS
+gar/SLM
+garage/DSMG
+garb/MDGS
+garbage/M
+garbageman
+garbanzo/SM
+garble/DSG
+garcon/SM
+garden/SZGMDR
+gardener/M
+gardenia/MS
+gardening/M
+garfish/MS
+gargantuan
+gargle/DSMG
+gargoyle/SM
+garish/PY
+garishness/M
+garland/MDGS
+garlic/M
+garlicky
+garment/MS
+garner/SGD
+garnet/SM
+garnish/GLMDS
+garnishee/DSM
+garnisheeing
+garnishment/SM
+garotte/MGDS
+garret/SM
+garrison/MDSG
+garrote/MZGDRS
+garroter/M
+garrotte/MGDS
+garrulity/M
+garrulous/PY
+garrulousness/M
+garter/SM
+gar巽on/SM
+gas's
+gas/CS
+gasbag/SM
+gaseous
+gash/MDSG
+gasholder/S
+gasket/SM
+gaslight/MDGS
+gasman
+gasmen
+gasohol/M
+gasoline/M
+gasometer/S
+gasp/MDGS
+gassed/C
+gasses
+gassing/C
+gassy/RT
+gastric
+gastritis/M
+gastroenteritis/M
+gastroenterologist/M
+gastroenterology
+gastrointestinal
+gastronome/S
+gastronomic
+gastronomical/Y
+gastronomy/M
+gastropod/SM
+gasworks/M
+gate/MGDS
+gateau
+gateaux
+gatecrash/DRSZG
+gatecrasher/M
+gatehouse/SM
+gatekeeper/MS
+gatekeeping/M
+gatepost/MS
+gateway/MS
+gather/SJZGMDR
+gatherer/M
+gathering/M
+gator/SM
+gauche/RPYT
+gaucheness/M
+gaucherie/M
+gaucho/SM
+gaudily
+gaudiness/M
+gaudy/RPT
+gauge/DSMG
+gaunt/RPT
+gauntlet/MS
+gauntness/M
+gauze/M
+gauziness/M
+gauzy/RPT
+gave
+gavel/SM
+gavotte/MS
+gawd
+gawk/DGS
+gawkily
+gawkiness/M
+gawky/RPT
+gawp/DGS
+gay/TSPMR
+gayness/M
+gaze/MZGDRS
+gazebo/SM
+gazelle/MS
+gazer/M
+gazette/MGDS
+gazetteer/MS
+gazillion/HS
+gazpacho/M
+gazump/DGS
+gear/MDGS
+gearbox/MS
+gearing/M
+gearshift/MS
+gearwheel/SM
+gecko/SM
+geddit
+gee/DS
+geeing
+geek/MS
+geeky/RT
+geese
+geezer/MS
+geisha/M
+gel/SM
+gelatin/M
+gelatinous
+gelcap/M
+geld/DJGS
+gelding/M
+gelid
+gelignite/M
+gelled
+gelling
+gem/SM
+gemmology/M
+gemological
+gemologist/MS
+gemology/M
+gemstone/MS
+gendarme/MS
+gender/MDSG
+gene/MS
+genealogical/Y
+genealogist/MS
+genealogy/SM
+genera
+general/SMY
+generalissimo/MS
+generalist/MS
+generality/SM
+generalization/MS
+generalize/GDS
+generalship/M
+generate/ACDSGNV
+generation's/A
+generation/CSM
+generational
+generator/SM
+generic/SM
+generically
+generosity/SM
+generous/PY
+generousness/M
+genes/S
+genesis/M
+genetic/S
+genetically
+geneticist/MS
+genetics/M
+genial/FY
+geniality/FM
+geniculate
+genie/SM
+genii
+genital/FY
+genitalia/M
+genitals/M
+genitive/MS
+genitourinary
+genius/MS
+genned
+genning
+genocidal
+genocide/MS
+genome/MS
+genomic/SM
+genre/SM
+gent/AMS
+genteel/YP
+genteelness/M
+gentian/SM
+gentile/SM
+gentility/M
+gentle/TGDRSP
+gentlefolk/MS
+gentlefolks/M
+gentleman/MY
+gentlemanly/U
+gentlemen
+gentleness/M
+gentlewoman/M
+gentlewomen
+gently
+gentrification/M
+gentrify/DSGN
+gentry/SM
+genuflect/DGS
+genuflection/MS
+genuine/PY
+genuineness/M
+genus/M
+geocache/DSG
+geocentric
+geocentrically
+geocentricism
+geocentrism
+geochemistry/M
+geode/SM
+geodesic/SM
+geodesy/M
+geodetic
+geoengineering
+geog
+geographer/SM
+geographic
+geographical/Y
+geography/SM
+geologic
+geological/Y
+geologist/MS
+geology/SM
+geom
+geomagnetic
+geomagnetism/M
+geometer
+geometric
+geometrical/Y
+geometry/SM
+geophysical
+geophysicist/SM
+geophysics/M
+geopolitical/Y
+geopolitics/M
+geostationary
+geosynchronous
+geosyncline/MS
+geothermal
+geothermic
+geranium/MS
+gerbil/MS
+geriatric/S
+geriatrician/S
+geriatrics/M
+germ/MS
+germane
+germanium/M
+germicidal
+germicide/MS
+germinal/M
+germinate/GNDS
+germination/M
+gerontocracy
+gerontological
+gerontologist/MS
+gerontology/M
+gerrymander/GMDS
+gerrymandering/M
+gerund/MS
+gestalt/S
+gestapo/MS
+gestate/GNDS
+gestation/M
+gestational
+gesticulate/DSGNX
+gesticulation/M
+gestural
+gesture/MGDS
+gesundheit
+get/S
+getaway/SM
+getting
+getup/M
+gewgaw/SM
+geyser/SM
+ghastliness/M
+ghastly/TPR
+ghat/MS
+ghee
+gherkin/MS
+ghetto/SM
+ghettoize/GDS
+ghost/SMDYG
+ghostliness/M
+ghostly/RTP
+ghostwrite/ZGRS
+ghostwriter/M
+ghostwritten
+ghostwrote
+ghoul/SM
+ghoulish/YP
+ghoulishness/M
+giant/SM
+giantess/MS
+gibber/GDS
+gibberish/M
+gibbet/GMDS
+gibbon/MS
+gibbous
+gibe/MGDS
+gibibyte/MS
+giblet/SM
+giddily
+giddiness/M
+giddy/RTP
+gift/MDGS
+gig/SM
+gigabit/SM
+gigabyte/MS
+gigagram/S
+gigahertz/M
+gigajoule/SM
+gigameter/S
+gigantic
+gigantically
+gigapascal/S
+gigapixel/MS
+gigawatt/SM
+gigged
+gigging
+giggle/DRSMZG
+giggler/M
+giggly/RT
+gigolo/SM
+gild/MDRZGS
+gilder/M
+gilding/M
+gill/MS
+gillie/S
+gillion/S
+gilt/MS
+gimbals/M
+gimcrack/SM
+gimcrackery/M
+gimlet/GSMD
+gimme/SM
+gimmick/MS
+gimmickry/M
+gimmicky
+gimp/MDGS
+gimpy
+gin/SM
+ginger/GSMDY
+gingerbread/M
+gingersnap/SM
+gingery
+gingham/M
+gingivitis/M
+ginkgo/SM
+ginkgoes
+ginned
+ginning
+ginormous
+ginseng/M
+giraffe/MS
+gird/DRZGS
+girder/M
+girdle/DSMG
+girl/MS
+girlfriend/MS
+girlhood/SM
+girlie
+girlish/YP
+girlishness/M
+girly/S
+giro/S
+girt/MDGS
+girth/M
+girths
+gist/M
+git/S
+gite/S
+give/ZGJRS
+giveaway/MS
+giveback/MS
+given/SM
+giver/M
+gizmo/SM
+gizzard/MS
+glace/S
+glaceed
+glaceing
+glacial/Y
+glaciate/XGNDS
+glaciation/M
+glacier/MS
+glac辿/SDG
+glad/MYSP
+gladden/GDS
+gladder
+gladdest
+glade/SM
+gladiator/SM
+gladiatorial
+gladiola/SM
+gladioli
+gladiolus/M
+gladness/M
+gladsome
+glam
+glamor/SGMD
+glamorization/M
+glamorize/DSG
+glamorous/Y
+glamour/GMDS
+glamping
+glance/DSMG
+gland/SM
+glandes
+glandular
+glans/M
+glare/DSMG
+glaring/Y
+glasnost/M
+glass/MDSG
+glassblower/MS
+glassblowing/M
+glassful/SM
+glasshouse/S
+glassily
+glassiness/M
+glassware/M
+glassy/RTP
+glaucoma/M
+glaze/DSMG
+glazier/SM
+glazing/M
+gleam/SMDGJ
+glean/SDRZGJ
+gleaner/M
+gleanings/M
+glee/M
+gleeful/YP
+gleefulness/M
+glen/MS
+glenohumeral
+glenoid
+glib/YP
+glibber
+glibbest
+glibness/M
+glide/DRSMZG
+glider/M
+gliding/M
+glimmer/MDGJS
+glimmering/M
+glimpse/MGDS
+glint/SMDG
+glissandi
+glissando/M
+glisten/MDSG
+glister/DSG
+glitch/GMDS
+glitter/MDSG
+glitterati
+glittery
+glitz/M
+glitzy/TR
+gloaming/SM
+gloat/SMDG
+gloating/Y
+glob/MDGS
+global/Y
+globalism/M
+globalist/MS
+globalization/M
+globalize/GDS
+globe/SM
+globetrotter/MS
+globetrotting
+globular
+globule/MS
+globulin/M
+glockenspiel/SM
+glom/DGS
+gloom/M
+gloomily
+gloominess/M
+gloomy/TRP
+glop/M
+gloppy
+glorification/M
+glorify/GDSN
+glorious/IY
+glory/DSMG
+gloss/MDSG
+glossary/SM
+glossily
+glossiness/M
+glossolalia/M
+glossy/PTRSM
+glottal
+glottis/MS
+glove/DSMG
+glow/MDRZGS
+glower/GMD
+glowing/Y
+glowworm/MS
+glucagon
+glucose/M
+glue/MGDS
+glued/U
+gluey
+gluier
+gluiest
+glum/YP
+glummer
+glummest
+glumness/M
+gluon/S
+glut/MNS
+gluten/M
+glutenous
+glutinous/Y
+glutted
+glutting
+glutton/MS
+gluttonous/Y
+gluttony/M
+glycerin/M
+glycerine/M
+glycerol/M
+glycogen/M
+glycol
+glyph
+gm
+gnarl/SMDG
+gnarly/TR
+gnash/MDSG
+gnat/MS
+gnaw/DGS
+gneiss/M
+gnocchi
+gnome/SM
+gnomic
+gnomish
+gnu/SM
+go/JMRHZG
+goad/MDGS
+goal/MS
+goalie/SM
+goalkeeper/MS
+goalkeeping/M
+goalless
+goalmouth
+goalmouths
+goalpost/MS
+goalscorer/S
+goaltender/MS
+goat/MS
+goatee/SM
+goatherd/MS
+goatskin/MS
+gob/SM
+gobbed
+gobbet/SM
+gobbing
+gobble/DRSMZG
+gobbledygook/M
+gobbler/M
+goblet/SM
+goblin/SM
+gobsmacked
+gobstopper/S
+gochujang
+god/SM
+godawful
+godchild/M
+godchildren/M
+goddam/D
+goddammit
+goddamn/D
+goddaughter/MS
+goddess/MS
+godfather/SM
+godforsaken
+godhead/M
+godhood/M
+godless/PY
+godlessness/M
+godlike
+godliness/UM
+godly/URTP
+godmother/SM
+godparent/SM
+godsend/SM
+godson/SM
+godspeed
+goer/M
+goes
+gofer/SM
+goggle/DSMG
+goggles/M
+going/M
+goiter/SM
+gold/MNS
+goldbrick/ZGSMDR
+goldbricker/M
+golden/TR
+goldenrod/M
+goldfield/S
+goldfinch/MS
+goldfish/MS
+goldmine/SM
+goldsmith/M
+goldsmiths
+golem
+golf/MDRZGS
+golfer/M
+golliwog/S
+golly/SM
+gonad/SM
+gonadal
+gondola/MS
+gondolier/SM
+gone/ZR
+goner/M
+gong/MDGS
+gonk/S
+gonna
+gonorrhea/M
+gonorrheal
+gonzo
+goo/M
+goober/SM
+good/MYSP
+goodby/M
+goodbye/MS
+goodbys
+goodhearted
+goodie/M
+goodish
+goodly/TR
+goodness/M
+goodnight
+goods/M
+goodwill/M
+goody/SM
+gooey
+goof/MDGS
+goofball/SM
+goofiness/M
+goofy/RPT
+google/DSMG
+googly/S
+gooier
+gooiest
+gook/MS
+goon/MS
+goop/M
+goose/DSMG
+gooseberry/SM
+goosebumps/M
+gooseflesh/M
+goosestep/S
+goosestepped
+goosestepping
+gopher/SM
+gore/MGDS
+gorge's
+gorge/EDSG
+gorgeous/YP
+gorgeousness/M
+gorgon/SM
+gorilla/MS
+gorily
+goriness/M
+gormandize/DRSZG
+gormandizer/M
+gormless
+gorp/MS
+gorse/M
+gory/RTP
+gosh
+goshawk/MS
+gosling/SM
+gospel/MS
+gossamer/M
+gossip/MDRZGS
+gossiper/M
+gossipy
+got
+gotcha/S
+gothic/P
+gothically
+goths
+gotta
+gotten
+gouache/S
+gouge/DRSMZG
+gouger/M
+goulash/MS
+gourd/SM
+gourde/MS
+gourmand/SM
+gourmet/SM
+gout/M
+gouty/TR
+gov
+govern/DGSBL
+governable/U
+governance/M
+governed/U
+governess/MS
+government/MS
+governmental
+governor/SM
+governorship/M
+govt
+gown/MDGS
+gr
+grab/MS
+grabbed
+grabber/MS
+grabbing
+grabby/TR
+grace/EDSMG
+graceful/EPY
+gracefulness/EM
+graceless/PY
+gracelessness/M
+gracious/UY
+graciousness/M
+grackle/MS
+grad/MRZSB
+gradate/XGNDS
+gradation/CM
+grade's
+grade/CADSG
+graded/U
+grader/M
+gradient/MS
+gradual/PY
+gradualism/M
+gradualness/M
+graduate/XMGNDS
+graduation/M
+graffiti
+graffito/M
+graft/SMDRZG
+grafter/M
+graham/S
+grail
+grain/ISMD
+graininess/M
+grainy/PTR
+gram/KMS
+grammar/MS
+grammarian/SM
+grammatical/UY
+grammatically/K
+gramophone/MS
+grampus/MS
+gran/S
+granary/SM
+grand/SMRYPT
+grandad/MS
+grandam/MS
+grandaunt/MS
+grandchild/M
+grandchildren/M
+granddad/SM
+granddaddy/SM
+granddaughter/SM
+grande
+grandee/MS
+grandeur/M
+grandfather/GMDYS
+grandiloquence/M
+grandiloquent
+grandiose/Y
+grandiosity/M
+grandma/MS
+grandmother/MYS
+grandnephew/MS
+grandness/M
+grandniece/MS
+grandpa/MS
+grandparent/MS
+grandson/MS
+grandstand/SGMD
+granduncle/SM
+grange/SM
+granite/M
+granitic
+grannie/M
+granny/SM
+granola/M
+grant/SMDRZG
+grantee/MS
+granter/M
+grantor/MS
+grantsmanship/M
+granular
+granularity/M
+granulate/GNDS
+granulation/M
+granule/MS
+grape/SM
+grapefruit/MS
+grapeshot/M
+grapevine/SM
+graph/MDG
+graphic/MS
+graphical/Y
+graphite/M
+graphologist/MS
+graphology/M
+graphs
+grapnel/MS
+grapple/MGDS
+grasp/SMDBG
+grass/MDSG
+grasshopper/MS
+grassland/MS
+grassroots
+grassy/TR
+grate/DRSMZGJ
+grateful/UYP
+gratefulness/UM
+grater/M
+gratification/M
+gratify/GNXDS
+gratifying/Y
+gratin/S
+grating/MY
+gratis
+gratitude/IM
+gratuitous/YP
+gratuitousness/M
+gratuity/SM
+gravamen/MS
+grave/DRSMYTGP
+gravedigger/SM
+gravel/SGMDY
+graven
+graveness/M
+graveside/MS
+gravestone/SM
+graveyard/MS
+gravid
+gravimeter/MS
+gravitas
+gravitate/GNDS
+gravitation/M
+gravitational
+gravity/M
+gravy/SM
+gray/MDRTGSP
+graybeard/SM
+grayish
+grayness/M
+grayscale
+graze/DRSMZG
+grazer/M
+grease/DRSMZG
+greasepaint/M
+greasily
+greasiness/M
+greasy/PTR
+great/SMRYPT
+greatcoat/SM
+greathearted
+greatness/M
+grebe/SM
+greed/M
+greedily
+greediness/M
+greedy/PTR
+green/GPSMDRYT
+greenback/MS
+greenbelt/MS
+greenery/M
+greenfield
+greenfly/S
+greengage/MS
+greengrocer/SM
+greenhorn/SM
+greenhouse/SM
+greenish
+greenmail/M
+greenness/M
+greenroom/SM
+greenstone
+greensward/M
+greenwood/M
+greet/ZGJSDR
+greeter/M
+greeting/M
+gregarious/PY
+gregariousness/M
+gremlin/SM
+grenade/SM
+grenadier/MS
+grenadine/M
+grep/S
+grepped
+grepping
+grew/A
+grey/MDRTGS
+greybeard's
+greybeards
+greyhound/SM
+greyness's
+gribble/S
+grid/MS
+griddle/SM
+griddlecake/SM
+gridiron/SM
+gridlock/SMD
+grief/SM
+grievance/MS
+grieve/ZGDRS
+griever/M
+grievous/PY
+grievousness/M
+griffin/SM
+griffon/SM
+grill/SGMDJ
+grille/MS
+grim/DYPG
+grimace/DSMG
+grime/SM
+griminess/M
+grimmer
+grimmest
+grimness/M
+grimy/TRP
+grin/MS
+grind/SZGMRJ
+grinder/M
+grindstone/MS
+gringo/MS
+grinned
+grinning
+grip/MDRSZG
+gripe/SM
+griper/M
+grippe/MZGDR
+gripper/M
+grisliness/M
+grisly/RTP
+grist/MY
+gristle/M
+gristmill/MS
+grit/MS
+grits/M
+gritted
+gritter/SM
+grittiness/M
+gritting
+gritty/RTP
+grizzle/DSG
+grizzly/TRSM
+groan/SGMD
+groat/SM
+grocer/MS
+grocery/SM
+grog/M
+groggily
+grogginess/M
+groggy/PRT
+groin/SM
+grok/S
+grokked
+grokking
+grommet/SM
+groom/SZGMDR
+groomer/M
+grooming/M
+groomsman/M
+groomsmen
+groove/MGDS
+groovy/RT
+grope/DRSMZG
+groper/M
+grosbeak/MS
+grosgrain/M
+gross/PTGMDRSY
+grossness/M
+grotesque/SPMY
+grotesqueness/M
+grotto/M
+grottoes
+grotty/TR
+grouch/GMDS
+grouchily
+grouchiness/M
+grouchy/RTP
+ground/ZGMDRJS
+groundbreaking/MS
+groundcloth
+groundcloths
+grounder/M
+groundhog/MS
+grounding/M
+groundless/Y
+groundnut/MS
+groundsheet/S
+groundskeeper/S
+groundsman
+groundsmen
+groundswell/SM
+groundwater/M
+groundwork/M
+group/JSZGMDR
+grouper/M
+groupie/MS
+grouping/M
+groupware/M
+grouse/MZGDRS
+grouser/M
+grout/SGMD
+grove/SM
+grovel/ZGDRS
+groveler/M
+grovelled
+grovelling
+grow/AHSG
+grower/MS
+growing/I
+growl/SZGMDR
+growler/M
+grown/AI
+grownup/MS
+growth/AM
+growths
+grub/MS
+grubbed
+grubber/MS
+grubbily
+grubbiness/M
+grubbing
+grubby/TRP
+grubstake/M
+grudge/MGDS
+grudging/Y
+grue/S
+gruel/GJM
+grueling/Y
+gruesome/RYTP
+gruesomeness/M
+gruff/TPRY
+gruffness/M
+grumble/DRSMZGJ
+grumbler/M
+grump/SM
+grumpily
+grumpiness/M
+grumpy/PRT
+grunge/MS
+grungy/RT
+grunion/SM
+grunt/SGMD
+gt
+guac
+guacamole/M
+guanine/M
+guano/M
+guarani/MS
+guaranies
+guarantee/MDS
+guaranteeing
+guarantor/MS
+guaranty/GDSM
+guard/SZGMDR
+guarded/Y
+guarder/M
+guardhouse/SM
+guardian/SM
+guardianship/M
+guardrail/SM
+guardroom/SM
+guardsman/M
+guardsmen
+guava/SM
+gubernatorial
+guerilla/SM
+guerrilla/SM
+guess/ZGBMDRS
+guesser/M
+guesstimate/DSMG
+guesswork/M
+guest/SGMD
+guestbook/SM
+guesthouse/S
+guestroom/S
+guff/M
+guffaw/MDGS
+guidance/M
+guide/DRSMZG
+guidebook/SM
+guided/U
+guideline/SM
+guidepost/SM
+guider/M
+guild/SZMR
+guilder/M
+guildhall/MS
+guile/M
+guileful
+guileless/YP
+guilelessness/M
+guillemot/S
+guillotine/DSMG
+guilt/M
+guiltily
+guiltiness/M
+guiltless
+guilty/PRT
+guinea/MS
+guise/ESM
+guitar/MS
+guitarist/SM
+gulag/SM
+gulch/MS
+gulden/MS
+gulf/MS
+gull/MDSG
+gullet/MS
+gullibility/M
+gullible
+gully/SM
+gulp/MDRSZG
+gulper/M
+gum/SM
+gumball/S
+gumbo/SM
+gumboil/SM
+gumboot/S
+gumdrop/SM
+gummed
+gumming
+gummy/TR
+gumption/M
+gumshoe/MDS
+gumshoeing
+gun/SM
+gunboat/SM
+gunfight/MRZS
+gunfighter/M
+gunfire/M
+gunge
+gungy
+gunk/M
+gunky
+gunman/M
+gunmen
+gunmetal/M
+gunned
+gunnel/MS
+gunner/MS
+gunnery/M
+gunning
+gunny/M
+gunnysack/MS
+gunpoint/M
+gunpowder/M
+gunrunner/MS
+gunrunning/M
+gunship/MS
+gunshot/MS
+gunslinger/SM
+gunsmith/M
+gunsmiths
+gunsmoke
+gunwale/MS
+guppy/SM
+gurgle/MGDS
+gurney/MS
+guru/MS
+gush/MDRSZG
+gusher/M
+gushing/Y
+gushy/TR
+gusset/MSDG
+gussy/DSG
+gust/EMDSG
+gustatory
+gustily
+gusto/M
+gusty/RT
+gut/SM
+gutless/P
+gutlessness/M
+gutsy/RT
+gutted
+gutter/SMDG
+guttersnipe/MS
+gutting
+guttural/MS
+gutty/RT
+guv/S
+guvnor/S
+guy/SGMD
+guzzle/DRSZG
+guzzler/M
+gym/SM
+gymkhana/MS
+gymnasium/MS
+gymnast/MS
+gymnastic/S
+gymnastically
+gymnastics/M
+gymnosperm/SM
+gymslip/S
+gynecologic
+gynecological
+gynecologist/SM
+gynecology/M
+gyp/SM
+gypped
+gypper/SM
+gypping
+gypster/SM
+gypsum/M
+gypsy/SM
+gyrate/DSGNX
+gyration/M
+gyrator/SM
+gyrfalcon/MS
+gyro/MS
+gyroscope/MS
+gyroscopic
+gyve/MGDS
+h'm
+h/NRSXZGVJ
+ha/SH
+habeas
+haberdasher/SM
+haberdashery/SM
+habiliment/SM
+habit's
+habit/ISB
+habitability/M
+habitat/SM
+habitation/MS
+habitual/YP
+habitualness/M
+habituate/GNDS
+habituation/M
+habitue/SM
+habitu辿/SM
+hacienda/SM
+hack/MDRZGS
+hacker/M
+hacking/M
+hackish
+hackle/MS
+hackney/SMDG
+hacksaw/SM
+hacktivist/MS
+hackwork/M
+had
+haddock/SM
+hadith/S
+hadn't
+hadron
+hadronic
+hadst
+hafnium/M
+haft/MS
+hag/SM
+haggard/YP
+haggardness/M
+haggis/MS
+haggish
+haggle/MZGDRS
+haggler/M
+hagiographer/SM
+hagiography/SM
+hah
+hahnium/M
+haiku/M
+hail/MDGS
+hailstone/MS
+hailstorm/MS
+hair/MDS
+hairball/MS
+hairband/S
+hairbreadth/M
+hairbreadths
+hairbrush/MS
+haircloth/M
+haircut/SM
+hairdo/MS
+hairdresser/SM
+hairdressing/M
+hairdrier/MS
+hairdryer/MS
+hairgrip/S
+hairiness/M
+hairless
+hairlike
+hairline/SM
+hairnet/SM
+hairpiece/MS
+hairpin/SM
+hairsbreadth/M
+hairsbreadths
+hairsplitter/SM
+hairsplitting/M
+hairspray/S
+hairspring/MS
+hairstyle/MS
+hairstylist/SM
+hairy/TRP
+haj
+hajj/M
+hajjes
+hajji/SM
+hake/MS
+halal/M
+halberd/SM
+halcyon
+hale/ITGDRS
+half/M
+halfback/SM
+halfhearted/PY
+halfheartedness/M
+halfpence
+halfpenny/SM
+halftime/MS
+halftone/MS
+halfway
+halfwit/SM
+halibut/SM
+halite/M
+halitosis/M
+hall/MS
+hallelujah/M
+hallelujahs
+hallmark/GMDS
+halloo/MDSG
+hallow/DSG
+hallowed/U
+hallucinate/GNXDS
+hallucination/M
+hallucinatory
+hallucinogen/SM
+hallucinogenic/SM
+hallway/SM
+halo/MDGS
+halogen/SM
+halon
+halt/MDRZGS
+halter/GMD
+halterneck/S
+halting/Y
+halve/DSG
+halyard/MS
+ham/SM
+hamburg/SZMR
+hamburger/M
+hamlet/MS
+hammed
+hammer/MDRSJZG
+hammerer/M
+hammerhead/SM
+hammerlock/SM
+hammertoe/MS
+hamming
+hammock/SM
+hammy/TR
+hamper/GMDS
+hampered/U
+hamster/MS
+hamstring/GSM
+hamstrung
+hand's
+hand/UDGS
+handbag/SM
+handball/MS
+handbarrow/SM
+handbill/MS
+handbook/MS
+handbrake/S
+handcar/SM
+handcart/MS
+handclasp/MS
+handcraft/SMDG
+handcuff/MDGS
+handed/P
+handful/SM
+handgun/SM
+handheld/MS
+handhold/MS
+handicap/MS
+handicapped
+handicapper/MS
+handicapping
+handicraft/MS
+handily
+handiness/M
+handiwork/M
+handkerchief/MS
+handle/MZGDRS
+handlebar/MS
+handler/M
+handmade
+handmaid/XMNS
+handmaiden/M
+handout/SM
+handover/S
+handpick/GDS
+handrail/MS
+handsaw/SM
+handset/SM
+handshake/JMGS
+handsome/PYTR
+handsomeness/M
+handspring/MS
+handstand/SM
+handwashing
+handwork/M
+handwoven
+handwrite/GS
+handwriting/M
+handwritten
+handwrote
+handy/UTR
+handyman/M
+handymen
+hang/MDRJZGS
+hangar/MS
+hangdog
+hanger/M
+hanging/M
+hangman/M
+hangmen
+hangnail/MS
+hangout/SM
+hangover/MS
+hangup/MS
+hank/MRZS
+hanker/GJD
+hankering/M
+hankie/M
+hanky/SM
+hansom/MS
+hap/MY
+haphazard/YP
+haphazardness/M
+hapless/YP
+haplessness/M
+haploid/MS
+happen/SDGJ
+happening/M
+happenstance/SM
+happily/U
+happiness/UM
+happy/URTP
+haptic/S
+haptical/Y
+harangue/MGDS
+harass/LZGDRS
+harasser/M
+harassment/M
+harbinger/SM
+harbor/GMDS
+harbormaster/S
+hard/NRYXTP
+hardback/MS
+hardball/M
+hardboard/M
+hardbound
+hardcore
+hardcover/SM
+harden/ZGDR
+hardened/U
+hardener/M
+hardhat/MS
+hardheaded/PY
+hardheadedness/M
+hardhearted/PY
+hardheartedness/M
+hardihood/M
+hardily
+hardiness/M
+hardliner/MS
+hardness/M
+hardscrabble
+hardship/SM
+hardstand/SM
+hardtack/M
+hardtop/SM
+hardware/M
+hardwired
+hardwood/SM
+hardworking
+hardy/PTR
+hare/MGDS
+harebell/MS
+harebrained
+harelip/SM
+harelipped
+harem/SM
+haricot/S
+harissa
+hark/DGS
+harlequin/SM
+harlot/SM
+harlotry/M
+harm/MDGS
+harmed/U
+harmful/YP
+harmfulness/M
+harmless/PY
+harmlessness/M
+harmonic/SM
+harmonica/MS
+harmonically
+harmonies
+harmonious/PY
+harmoniousness/M
+harmonium/MS
+harmonization/M
+harmonize/ZGDRS
+harmonizer/M
+harmony/EM
+harness's
+harness/UDSG
+harp/MDGS
+harpist/SM
+harpoon/ZGSMDR
+harpooner/M
+harpsichord/MS
+harpsichordist/SM
+harpy/SM
+harridan/MS
+harrier/M
+harrow/SMDG
+harrumph/GD
+harrumphs
+harry/DRSZG
+harsh/RYTP
+harshness/M
+hart/MS
+harvest/SMDRZG
+harvested/U
+harvester/M
+hash/AMDSG
+hashish/M
+hashtag/SM
+hasn't
+hasp/MS
+hassle/DSMG
+hassock/SM
+hast/DNXG
+haste/SM
+hasten/DG
+hastily
+hastiness/M
+hasty/RTP
+hat/ZGSMDR
+hatband/S
+hatbox/MS
+hatch/MDSG
+hatchback/MS
+hatcheck/SM
+hatched/U
+hatchery/SM
+hatchet/SM
+hatching/M
+hatchling
+hatchway/SM
+hate/MS
+hateful/PY
+hatefulness/M
+hatemonger/MS
+hater/M
+hatpin/S
+hatred/SM
+hatstand/S
+hatted
+hatter/SM
+hatting
+hauberk/SM
+haughtily
+haughtiness/M
+haughty/PRT
+haul/MDRZGS
+haulage/M
+hauler/M
+haulier/S
+haunch/MS
+haunt/SMDRZG
+haunter/M
+haunting/Y
+hauteur/M
+have/MGS
+haven't
+haven/SM
+haversack/SM
+havoc/M
+haw/GSMD
+hawk/MDRZGS
+hawker/M
+hawkish/P
+hawkishness/M
+hawser/SM
+hawthorn/MS
+hay/GSMD
+haycock/SM
+hayloft/SM
+haymaker/S
+haymaking
+haymow/SM
+hayrick/MS
+hayride/MS
+hayseed/MS
+haystack/SM
+haywire
+hazard/SMDG
+hazardous/Y
+haze/MZGJDRS
+hazel/SM
+hazelnut/MS
+hazer/M
+hazily
+haziness/M
+hazing/M
+hazmat
+hazy/RTP
+hdqrs
+he'd
+he'll
+he/M
+head/MDRZGJS
+headache/MS
+headband/MS
+headbanger/S
+headbanging
+headboard/SM
+headbutt/DSG
+headcase/S
+headcheese
+headcount/S
+headdress/MS
+header/M
+headfirst
+headgear/M
+headhunt/DRSZG
+headhunter/M
+headhunting/M
+headily
+headiness/M
+heading/M
+headlamp/MS
+headland/MS
+headless
+headlight/MS
+headline/MZGDRS
+headliner/M
+headlock/MS
+headlong
+headman/M
+headmaster/SM
+headmen
+headmistress/MS
+headphone/MS
+headpiece/MS
+headpin/SM
+headquarter/SDG
+headquarters/M
+headrest/MS
+headroom/M
+headscarf
+headscarves
+headset/SM
+headship/SM
+headshrinker/SM
+headsman/M
+headsmen
+headspace
+headstall/SM
+headstand/SM
+headstone/SM
+headstrong
+headteacher/S
+headwaiter/SM
+headwaters/M
+headway/M
+headwind/SM
+headword/SM
+heady/RTP
+heal/DRHZGS
+healed/U
+healer/M
+health/M
+healthcare
+healthful/PY
+healthfulness/M
+healthily/U
+healthiness/UM
+healthy/UTRP
+heap/MDGS
+hear/AHGJS
+heard/AU
+hearer/SM
+hearing/AM
+hearken/SGD
+hearsay/M
+hearse's
+hearse/AS
+heart/SM
+heartache/MS
+heartbeat/MS
+heartbreak/SMG
+heartbroken
+heartburn/M
+hearten/ESGD
+heartfelt
+hearth/M
+hearthrug/S
+hearths
+hearthstone/SM
+heartily
+heartiness/M
+heartland/MS
+heartless/PY
+heartlessness/M
+heartrending/Y
+heartsick/P
+heartsickness/M
+heartstrings/M
+heartthrob/MS
+heartwarming
+heartwood/M
+hearty/RSMPT
+heat's
+heat/ADGS
+heated/U
+heatedly
+heater/SM
+heath/MNRX
+heathen/M
+heathendom/M
+heathenish
+heathenism/M
+heather/M
+heaths
+heating/M
+heatproof
+heatstroke/M
+heatwave/S
+heave/DRSMZG
+heaven/SMY
+heavenly/TR
+heavens/M
+heavenward/S
+heaver/M
+heavily
+heaviness/M
+heavy/RSMTP
+heavyhearted
+heavyset
+heavyweight/MS
+heck/M
+heckle/DRSMZG
+heckler/M
+heckling/M
+hectare/SM
+hectic
+hectically
+hectogram/SM
+hectometer/MS
+hector/SMDG
+hedge/DRSMZG
+hedgehog/MS
+hedgehop/S
+hedgehopped
+hedgehopping
+hedger/M
+hedgerow/SM
+hedonism/M
+hedonist/MS
+hedonistic
+heed/MDGS
+heeded/U
+heedful/Y
+heedless/PY
+heedlessness/M
+heehaw/SMDG
+heel/MDGS
+heelless
+heft/MDGS
+heftily
+heftiness/M
+hefty/PRT
+hegemonic
+hegemony/M
+hegira/SM
+heifer/SM
+height/XSMN
+heighten/DG
+heinous/YP
+heinousness/M
+heir/MS
+heiress/MS
+heirloom/SM
+heist/SMDG
+held
+helical
+helices
+helicity/S
+helicopter/SGMD
+heliocentric
+heliocentrically
+heliocentricism
+heliocentrism
+heliotrope/SM
+helipad/S
+heliport/MS
+helium/M
+helix/M
+hell/M
+hellbent
+hellcat/MS
+hellebore/M
+hellfire
+hellhole/MS
+hellion/MS
+hellish/YP
+hellishness/M
+hello/SM
+helluva
+helm/MS
+helmet/SMD
+helmsman/M
+helmsmen
+helot/SM
+help/MDRZGSJ
+helper/M
+helpful/UY
+helpfulness/M
+helping/M
+helpless/PY
+helplessness/M
+helpline/SM
+helpmate/SM
+helve/SM
+hem/SM
+hematite/M
+hematologic
+hematological
+hematologist/MS
+hematology/M
+heme/M
+hemiplegia
+hemisphere/SM
+hemispheric
+hemispherical
+hemline/SM
+hemlock/SM
+hemmed
+hemmer/SM
+hemming
+hemoglobin/M
+hemophilia/M
+hemophiliac/MS
+hemorrhage/MGDS
+hemorrhagic
+hemorrhoid/MS
+hemostat/MS
+hemp/MN
+hemstitch/MDSG
+hen/M
+hence
+henceforth
+henceforward
+henchman/M
+henchmen
+henna/SMDG
+henpeck/GSD
+hentai
+hep
+heparin/M
+hepatic
+hepatitis/M
+hepatocyte/S
+hepper
+heppest
+heptagon/MS
+heptagonal
+heptathlon/SM
+herald/SMDG
+heralded/U
+heraldic
+heraldry/M
+herb/MS
+herbaceous
+herbage/M
+herbal/S
+herbalist/MS
+herbicidal
+herbicide/MS
+herbivore/SM
+herbivorous
+herculean
+herd/MDRZGS
+herder/M
+herdsman/M
+herdsmen
+here/M
+hereabout/S
+hereafter/SM
+hereby
+hereditary
+heredity/M
+herein
+hereinafter
+hereof
+hereon
+heresy/SM
+heretic/SM
+heretical
+hereto
+heretofore
+hereunder
+hereunto
+hereupon
+herewith
+heritability
+heritable/I
+heritage/MS
+hermaphrodite/SM
+hermaphroditic
+hermetic
+hermetical/Y
+hermit/SM
+hermitage/MS
+hermitian
+hernia/SM
+hernial
+herniate/GNDS
+herniation/M
+hero/M
+heroes
+heroic/S
+heroically
+heroics/M
+heroin/SM
+heroine/SM
+heroism/M
+heron/SM
+herpes/M
+herpetologist/SM
+herpetology/M
+herring/MS
+herringbone/M
+herself
+hertz/M
+hesitance/M
+hesitancy/M
+hesitant/Y
+hesitate/DSGNX
+hesitating/UY
+hesitation/M
+hessian
+hetero/SM
+heterodox
+heterodoxy/M
+heterogeneity/M
+heterogeneous/Y
+heterosexual/MYS
+heterosexuality/M
+heuristic/MS
+heuristically
+heuristics/M
+hew/ZGSDR
+hewer/M
+hex/GMDS
+hexadecimal/S
+hexagon/MS
+hexagonal
+hexagram/SM
+hexameter/SM
+hexane/SM
+hey
+heyday/SM
+hf
+hgt
+hgwy
+hi/SD
+hiatus/MS
+hibachi/MS
+hibernate/GNDS
+hibernation/M
+hibernator/MS
+hibiscus/MS
+hiccough/DG
+hiccoughs
+hiccup/GSMD
+hick/MS
+hickey/SM
+hickory/SM
+hid
+hidden
+hide/MZGJDRS
+hideaway/SM
+hidebound
+hideous/YP
+hideousness/M
+hideout/MS
+hider/M
+hiding/M
+hie/S
+hieing
+hierarchic
+hierarchical/Y
+hierarchy/SM
+hieroglyph/M
+hieroglyphic/MS
+hieroglyphs
+high/MRYZTP
+highball/SM
+highborn
+highboy/MS
+highbrow/SM
+highchair/MS
+highfalutin
+highhanded/PY
+highhandedness/M
+highland/MRZS
+highlander/M
+highlight/SMDRZG
+highlighter/M
+highness/M
+highroad/MS
+highs
+hightail/DSG
+highway/MS
+highwayman/M
+highwaymen
+hijab/SM
+hijack/SJZGMDR
+hijacker/M
+hijacking/M
+hike/MZGDRS
+hiker/M
+hiking/M
+hilarious/PY
+hilariousness/M
+hilarity/M
+hill/MS
+hillbilly/SM
+hilliness/M
+hillock/MS
+hillside/SM
+hilltop/MS
+hilly/PRT
+hilt/MS
+him/S
+himself
+hind/MRZS
+hinder/GD
+hindered/U
+hindmost
+hindquarter/MS
+hindrance/SM
+hindsight/M
+hinge's
+hinge/UDSG
+hint/MDRZGS
+hinter/M
+hinterland/SM
+hip/SPM
+hipbath
+hipbaths
+hipbone/MS
+hiphuggers
+hipness/M
+hipped
+hipper
+hippest
+hippie/M
+hipping
+hippo/SM
+hippocampus
+hippodrome/SM
+hippopotami
+hippopotamus/MS
+hippy/SM
+hipster/MS
+hiragana
+hire's
+hire/AGDS
+hireling/MS
+hirsute/P
+hirsuteness/M
+hiss/MDSG
+hist
+histamine/MS
+histogram/MS
+histologist/SM
+histology/M
+histopathology
+historian/MS
+historic
+historical/Y
+historicity/M
+historiographer/MS
+historiography/M
+history/SM
+histrionic/S
+histrionically
+histrionics/M
+hit/SM
+hitch's
+hitch/UDSG
+hitcher/MS
+hitchhike/DRSMZG
+hitchhiker/M
+hither
+hitherto
+hitter/SM
+hitting
+hive/MGDS
+hivemind/SM
+hiya
+hm
+hmm
+ho/SMDRYZ
+hoagie/MS
+hoard/SZGMDRJ
+hoarder/M
+hoarding/M
+hoarfrost/M
+hoariness/M
+hoarse/YTRP
+hoarseness/M
+hoary/TRP
+hoax/MDRSZG
+hoaxer/M
+hob/SM
+hobbit/S
+hobble/MZGDRS
+hobbler/M
+hobby/SM
+hobbyhorse/MS
+hobbyist/SM
+hobgoblin/MS
+hobnail/SGMD
+hobnob/S
+hobnobbed
+hobnobbing
+hobo/MS
+hoboes
+hoc
+hock/MDSG
+hockey/M
+hockshop/MS
+hod/SM
+hodgepodge/SM
+hoe/SM
+hoecake/SM
+hoedown/SM
+hoeing
+hoer/M
+hog/SM
+hogan/SM
+hogback/SM
+hogged
+hogging
+hoggish/Y
+hogshead/SM
+hogtie/DS
+hogtying
+hogwash/M
+hoick/SGD
+hoist/SGMD
+hoke/GDS
+hokey
+hokier
+hokiest
+hokum/M
+hold/MRJSZG
+holdall/S
+holdem
+holder/M
+holding/M
+holdout/SM
+holdover/SM
+holdup/MS
+hole/MGDS
+holey
+holiday/SMDG
+holidaymaker/S
+holiness/UM
+holism
+holistic
+holistically
+holler/MDGS
+hollow/MDRYPSTG
+hollowness/M
+holly/SM
+hollyhock/MS
+holmium/M
+holocaust/SM
+hologram/MS
+holograph/M
+holographic
+holographs
+holography/M
+hols
+holster/SMDG
+holy/URPT
+homage/MS
+hombre/MS
+homburg/SM
+home/MYZGDRS
+homebody/SM
+homeboy/SM
+homecoming/SM
+homegrown
+homeland/MS
+homeless/MP
+homelessness/M
+homelike
+homeliness/M
+homely/PRT
+homemade
+homemaker/SM
+homemaking/M
+homeopath/M
+homeopathic
+homeopaths
+homeopathy/M
+homeostasis/M
+homeostatic
+homeowner/MS
+homepage/MS
+homer/GMD
+homeroom/MS
+homeschooling/M
+homesick/P
+homesickness/M
+homespun/M
+homestead/SMDRZG
+homesteader/M
+homestretch/MS
+hometown/MS
+homeward/S
+homework/MRZG
+homewrecker/SM
+homey/SMP
+homeyness/M
+homicidal
+homicide/MS
+homie/RSMT
+homiletic
+homily/SM
+hominess/M
+hominid/SM
+hominoid/S
+hominy/M
+homo/MS
+homoerotic
+homogeneity/M
+homogeneous/Y
+homogenization/M
+homogenize/DSG
+homograph/M
+homographs
+homologous
+homology
+homonym/SM
+homophobia/M
+homophobic
+homophone/MS
+homosexual/SM
+homosexuality/M
+hon/SZTGMDR
+honcho/MS
+hone/MS
+honer/M
+honest/EYT
+honester
+honesty/EM
+honey/SGMD
+honeybee/SM
+honeycomb/MDSG
+honeydew/SM
+honeylocust/M
+honeymoon/ZGMDRS
+honeymooner/M
+honeypot/S
+honeysuckle/SM
+honk/MDRSZG
+honker/M
+honkie/M
+honky/SM
+honor/ESGMDB
+honorableness/M
+honorably/E
+honorarily
+honorarium/MS
+honorary
+honoree/SM
+honorer/SM
+honorific/MS
+hooch/M
+hood/MDSG
+hoodie/MS
+hoodlum/SM
+hoodoo/MDSG
+hoodwink/DGS
+hooey/M
+hoof/MDRSZG
+hook's
+hook/UDSG
+hookah/M
+hookahs
+hooker/MS
+hookup/MS
+hookworm/MS
+hooky/M
+hooligan/MS
+hooliganism/M
+hoop/MDSG
+hoopla/M
+hooray/MS
+hoosegow/SM
+hoot/MDRSZG
+hootch/M
+hootenanny/SM
+hooter/M
+hoover/DSG
+hooves
+hop/SGMD
+hope/MS
+hopeful/PSMY
+hopefulness/M
+hopeless/YP
+hopelessness/M
+hophead/S
+hopped
+hopper/MS
+hopping
+hopscotch/MDSG
+hora/MS
+horde/DSMG
+horehound/SM
+horizon/SM
+horizontal/SMY
+hormesis
+hormonal
+hormone/SM
+horn/MDS
+hornbeam/S
+hornblende/M
+hornet/MS
+hornless
+hornlike
+hornpipe/MS
+horny/TR
+horologic
+horological
+horologist/MS
+horology/M
+horoscope/SM
+horrendous/Y
+horrible/P
+horribleness/M
+horribly
+horrid/Y
+horrific
+horrifically
+horrify/DSG
+horrifying/Y
+horror/MS
+horse's
+horse/UDSG
+horseback/M
+horsebox/S
+horseflesh/M
+horsefly/SM
+horsehair/M
+horsehide/M
+horselaugh/M
+horselaughs
+horseless
+horseman/M
+horsemanship/M
+horsemen
+horseplay/M
+horsepower/M
+horseradish/MS
+horseshit/!
+horseshoe/DSM
+horseshoeing
+horsetail/SM
+horsetrading
+horsewhip/SM
+horsewhipped
+horsewhipping
+horsewoman/M
+horsewomen
+horsey
+horsy/TR
+hortatory
+horticultural
+horticulturalist/S
+horticulture/M
+horticulturist/MS
+hosanna/SM
+hose/MGDS
+hosepipe/S
+hosier/MS
+hosiery/M
+hosp
+hospholipase
+hospice/MS
+hospitable/I
+hospitably/I
+hospital/SM
+hospitality/M
+hospitalization/SM
+hospitalize/DSG
+host/MDSG
+hostage/MS
+hostel/ZGMDRS
+hosteler/M
+hostelry/SM
+hostess/MDSG
+hostile/MYS
+hostilities/M
+hostility/SM
+hostler/MS
+hot/SYP
+hotbed/MS
+hotblooded
+hotbox/MS
+hotcake/SM
+hotdog/MS
+hotdogged
+hotdogging
+hotel/SM
+hotelier/MS
+hotfoot/MDGS
+hothead/DSM
+hotheaded/YP
+hotheadedness/M
+hothouse/SM
+hotkey/S
+hotline/MS
+hotlink/S
+hotness/M
+hotplate/SM
+hotpot/S
+hots/M
+hotshot/MS
+hotted
+hotter
+hottest
+hottie/S
+hotting
+hound/SGMD
+hour/MYS
+hourglass/MS
+houri/SM
+house's
+house/ADSG
+houseboat/SM
+housebound
+houseboy/SM
+housebreak/RSZG
+housebreaker/M
+housebreaking/M
+housebroke
+housebroken
+houseclean/DSG
+housecleaning/M
+housecoat/SM
+housefly/SM
+houseful/SM
+household/SMRZ
+householder/M
+househusband/SM
+housekeeper/MS
+housekeeping/M
+houselights/M
+housemaid/SM
+houseman/M
+housemaster/S
+housemate/S
+housemen
+housemistress/S
+housemother/SM
+houseparent/SM
+houseplant/MS
+houseproud
+houseroom
+housetop/SM
+housewares/M
+housewarming/SM
+housewife/MY
+housewives
+housework/M
+housing/MS
+hove
+hovel/SM
+hover/SGD
+hoverboard/MS
+hovercraft/MS
+how'd
+how're
+how/SM
+howbeit
+howdah/M
+howdahs
+howdy
+however
+howitzer/SM
+howl/MDRSZG
+howler/M
+howsoever
+howto/SM
+hoyden/MS
+hoydenish
+hp
+hr/S
+ht
+huarache/SM
+hub/SM
+hubbub/SM
+hubby/SM
+hubcap/SM
+hubris/M
+huckleberry/SM
+huckster/SGMD
+hucksterism/M
+huddle/DSMG
+hue/DSM
+huff/MDSG
+huffily
+huffiness/M
+huffy/PRT
+hug/STMR
+huge/YP
+hugeness/M
+hugged
+hugging
+huh
+hula/MS
+hulk/MSG
+hull/MDRSZG
+hullabaloo/SM
+huller/M
+hum/SM
+human/SMRYTP
+humane/PY
+humaneness/M
+humanism/M
+humanist/SM
+humanistic
+humanitarian/MS
+humanitarianism/M
+humanities/M
+humanity/ISM
+humanization/CM
+humanize/CDSG
+humanizer/SM
+humankind/M
+humanness/M
+humanoid/SM
+humble/DRSZTGJP
+humbleness/M
+humbler/M
+humbly
+humbug/SM
+humbugged
+humbugging
+humdinger/MS
+humdrum/M
+humeral
+humeri
+humerus/M
+humid/Y
+humidification/M
+humidifier/CM
+humidify/CZGDRS
+humidity/M
+humidor/SM
+humiliate/DSGNX
+humiliating/Y
+humiliation/M
+humility/M
+hummed
+hummer/SM
+humming
+hummingbird/SM
+hummock/SM
+hummocky
+hummus/M
+humongous
+humor/SMDG
+humoresque
+humorist/MS
+humorless/YP
+humorlessness/M
+humorous/PY
+humorousness/M
+hump/MDSG
+humpback/MDS
+humph/DG
+humphs
+humus/M
+hunch/MDSG
+hunchback/SMD
+hundred/SMH
+hundredfold
+hundredth/M
+hundredths
+hundredweight/SM
+hung
+hunger/SMDG
+hungover
+hungrily
+hungriness/M
+hungry/PRT
+hunk/MRSZ
+hunker/DG
+hunky/RT
+hunt/MDRSZG
+hunter/M
+hunting/M
+huntress/MS
+huntsman/M
+huntsmen
+hurdle/DRSMZG
+hurdler/M
+hurdling/M
+hurl/MDRSZG
+hurler/M
+hurling/M
+hurrah/GMD
+hurrahs
+hurray
+hurricane/MS
+hurried/UY
+hurry/DSMG
+hurt/MSG
+hurtful/YP
+hurtfulness/M
+hurtle/DSG
+husband/GMDS
+husbandman/M
+husbandmen
+husbandry/M
+hush/MDSG
+husk/MDRSZG
+husker/M
+huskily
+huskiness/M
+husky/PRSMT
+hussar/SM
+hussy/SM
+hustings/M
+hustle/DRSMZG
+hustler/M
+hut/SM
+hutch/MS
+huzza/GSMD
+huzzah/MDG
+huzzahs
+hwy
+hyacinth/M
+hyacinths
+hybrid/SM
+hybridism/M
+hybridization/M
+hybridize/DSG
+hydra/SM
+hydrangea/SM
+hydrant/MS
+hydrate's
+hydrate/CGNDS
+hydration/CM
+hydraulic/S
+hydraulically
+hydraulics/M
+hydride
+hydro/M
+hydrocarbon/MS
+hydrocephalus/M
+hydrochloride
+hydrocortisone
+hydrodynamic/S
+hydrodynamics/M
+hydroelectric
+hydroelectrically
+hydroelectricity/M
+hydrofoil/MS
+hydrogen/M
+hydrogenate/CGDS
+hydrogenation/M
+hydrogenous
+hydrologist/MS
+hydrology/M
+hydrolyses
+hydrolysis/M
+hydrolyze/DSG
+hydrometer/SM
+hydrometry/M
+hydrophilic
+hydrophobia/M
+hydrophobic
+hydrophone/SM
+hydroplane/GDSM
+hydroponic/S
+hydroponically
+hydroponics/M
+hydrosphere/M
+hydrotherapy/M
+hydrothermal
+hydrous
+hydroxide/SM
+hyena/SM
+hygiene/M
+hygienic/U
+hygienically
+hygienist/MS
+hygrometer/SM
+hying
+hymen/SM
+hymeneal
+hymn/MDSG
+hymnal/MS
+hymnbook/SM
+hype/MGDRS
+hyperactive
+hyperactivity/M
+hyperbola/SM
+hyperbole/M
+hyperbolic
+hypercritical/Y
+hypercube
+hyperglycemia/M
+hyperinflation
+hyperlink/GSMD
+hypermarket/S
+hypermedia/M
+hyperparathyroidism
+hyperplane
+hypersensitive/P
+hypersensitiveness/M
+hypersensitivity/SM
+hyperspace/S
+hypertension/M
+hypertensive/SM
+hypertext/M
+hyperthyroid/M
+hyperthyroidism/M
+hypertrophy/DSMG
+hyperventilate/GNDS
+hyperventilation/M
+hypervisor/MS
+hyphen/MDSG
+hyphenate/XDSMGN
+hyphenation/M
+hypnoses
+hypnosis/M
+hypnotherapist/S
+hypnotherapy/M
+hypnotic/SM
+hypnotically
+hypnotism/M
+hypnotist/MS
+hypnotize/GDS
+hypo/MS
+hypoallergenic
+hypochondria/M
+hypochondriac/SM
+hypocrisy/SM
+hypocrite/MS
+hypocritical/Y
+hypodermic/MS
+hypoglycemia/M
+hypoglycemic/SM
+hypotenuse/MS
+hypothalami
+hypothalamus/M
+hypothermia/M
+hypotheses
+hypothesis/M
+hypothesize/DSG
+hypothetical/Y
+hypothyroid/M
+hypothyroidism/M
+hyssop/M
+hysterectomy/SM
+hysteresis
+hysteria/M
+hysteric/SM
+hysterical/Y
+hysterics/M
+i/US
+iOS/M
+iPad/M
+iPhone/M
+iPod/MS
+iTunes/M
+iamb/MS
+iambi
+iambic/SM
+iambus/MS
+iatrogenesis
+iatrogenic
+ibex/MS
+ibid
+ibidem
+ibis/MS
+ibuprofen/M
+ice's
+ice/CDSG
+iceberg/SM
+iceboat/SM
+icebound
+icebox/MS
+icebreaker/SM
+icecap/SM
+iceman/M
+icemen
+ichthyologist/MS
+ichthyology/M
+icicle/SM
+icily
+iciness/M
+icing/SM
+icky/RT
+icon/MS
+iconic
+iconoclasm/M
+iconoclast/SM
+iconoclastic
+iconography/M
+ictus/M
+icy/TPR
+id/SMY
+idea/MS
+ideal/SMY
+idealism/M
+idealist/SM
+idealistic
+idealistically
+idealization/MS
+idealize/DSG
+idem
+idempotent
+identical/Y
+identifiable/U
+identification/M
+identified/U
+identify/ZGNDRSX
+identikit/S
+identity/SM
+ideogram/SM
+ideograph/M
+ideographs
+ideological/Y
+ideologist/SM
+ideologue/MS
+ideology/SM
+ides/M
+idiocy/SM
+idiom/SM
+idiomatic/U
+idiomatically
+idiopathic
+idiosyncrasy/SM
+idiosyncratic
+idiosyncratically
+idiot/SM
+idiotic
+idiotically
+idle/MZTGDRSP
+idleness/M
+idler/M
+idol/MS
+idolater/SM
+idolator/SM
+idolatress/MS
+idolatrous
+idolatry/M
+idolization/M
+idolize/GDS
+idyll/SM
+idyllic
+idyllically
+if/SM
+iffiness/M
+iffy/RTP
+iftar/S
+igloo/SM
+igneous
+ignite/ZGNBXDRS
+igniter/M
+ignition/M
+ignoble
+ignobly
+ignominious/Y
+ignominy/SM
+ignoramus/MS
+ignorance/M
+ignorant/Y
+ignore/GDS
+iguana/MS
+ii
+iii
+ilea
+ileitis/M
+ileum/M
+ilia
+ilium/M
+ilk/SM
+ill/SMP
+illegal/MYS
+illegality/SM
+illegibility/M
+illegible
+illegibly
+illegitimacy/M
+illegitimate/Y
+illiberal/Y
+illiberality/M
+illicit/YP
+illicitness/M
+illimitable
+illiteracy/M
+illiterate/MYS
+illness/MS
+illogical/Y
+illogicality/M
+illuminate/GNXDS
+illuminating/Y
+illumination/M
+illumine/DSBG
+illus/V
+illusion/EMS
+illusionist/SM
+illusory
+illustrate/GNVXDS
+illustration/M
+illustrative/Y
+illustrator/SM
+illustrious/PY
+illustriousness/M
+image/DSMG
+imagery/M
+imaginable/U
+imaginably/U
+imaginal
+imaginary
+imagination/MS
+imaginative/UY
+imagine/DSBJG
+imago/M
+imagoes
+imam/MS
+imbalance/DSM
+imbecile/MS
+imbecilic
+imbecility/SM
+imbibe/ZGDRS
+imbiber/M
+imbrication/M
+imbroglio/SM
+imbue/DSG
+imitable/I
+imitate/DSGNVX
+imitation/M
+imitative/PY
+imitativeness/M
+imitator/SM
+immaculate/PY
+immaculateness/M
+immanence/M
+immanency/M
+immanent/Y
+immaterial/YP
+immateriality/M
+immaterialness/M
+immature/Y
+immaturity/M
+immeasurable
+immeasurably
+immediacies/M
+immediacy/SM
+immediate/PY
+immediateness/M
+immemorial/Y
+immense/Y
+immensity/SM
+immerse/XDSGNV
+immersible
+immersion/M
+immigrant/SM
+immigrate/DSGN
+immigration/M
+imminence/M
+imminent/Y
+immobile
+immobility/M
+immobilization/M
+immobilize/ZGDRS
+immoderate/Y
+immodest/Y
+immodesty/M
+immolate/DSGN
+immolation/M
+immoral/Y
+immorality/SM
+immortal/MYS
+immortality/M
+immortalize/DSG
+immovability/M
+immovable
+immovably
+immune
+immunity/M
+immunization/SM
+immunize/GDS
+immunodeficiency/M
+immunodeficient
+immunoglobulin/S
+immunologic
+immunological
+immunologist/MS
+immunology/M
+immure/DSG
+immutability/M
+immutable
+immutably
+imp/SMR
+impact/SMDG
+impactful
+impaction
+impair/SDGL
+impaired/U
+impairment/MS
+impala/SM
+impale/DSGL
+impalement/M
+impalpable
+impalpably
+impanel/SDG
+impart/SDG
+impartial/Y
+impartiality/M
+impassably
+impasse/BSMV
+impassibility/M
+impassible
+impassibly
+impassioned
+impassive/YP
+impassiveness/M
+impassivity/M
+impasto/M
+impatience/MS
+impatiens/M
+impatient/Y
+impeach/ZGBLDRS
+impeachable/U
+impeacher/M
+impeachment/SM
+impeccability/M
+impeccable
+impeccably
+impecunious/PY
+impecuniousness/M
+impedance/M
+impede/DSG
+impeded/U
+impediment/SM
+impedimenta/M
+impel/S
+impelled
+impeller/MS
+impelling
+impend/SDG
+impenetrability/M
+impenetrable
+impenetrably
+impenitence/M
+impenitent/Y
+imperative/SMY
+imperceptibility/M
+imperceptible
+imperceptibly
+imperceptive
+imperf
+imperfect/SMYP
+imperfection/MS
+imperfectness/M
+imperial/MYS
+imperialism/M
+imperialist/SM
+imperialistic
+imperialistically
+imperil/GSLD
+imperilment/M
+imperious/PY
+imperiousness/M
+imperishable
+imperishably
+impermanence/M
+impermanent/Y
+impermeability/M
+impermeable
+impermeably
+impermissible
+impersonal/Y
+impersonate/GNXDS
+impersonation/M
+impersonator/SM
+impertinence/MS
+impertinent/Y
+imperturbability/M
+imperturbable
+imperturbably
+impervious/Y
+impetigo/M
+impetuosity/M
+impetuous/YP
+impetuousness/M
+impetus/MS
+impiety/SM
+impinge/LDSG
+impingement/M
+impious/PY
+impiousness/M
+impish/YP
+impishness/M
+implacability/M
+implacable
+implacably
+implant/BSGMD
+implantation/M
+implausibility/SM
+implausible
+implausibly
+implement/ZGBMDRS
+implementable/U
+implementation/SM
+implemented/U
+implicate/DSG
+implication/M
+implicit/PY
+implicitness/M
+implode/DSG
+implore/DSG
+imploring/Y
+implosion/MS
+implosive
+imply/XDSGN
+impolite/YP
+impoliteness/MS
+impolitic
+imponderable/MS
+import/ZGBSMDR
+importance/M
+important/Y
+importation/MS
+importer/M
+importunate/Y
+importune/GDS
+importunity/M
+impose/ADSG
+imposer/MS
+imposing/U
+imposingly
+imposition/MS
+impossibility/SM
+impossible/S
+impossibly
+impost/ZSMR
+imposter/M
+impostor/SM
+imposture/MS
+impotence/M
+impotency/M
+impotent/Y
+impound/DGS
+impoverish/DSLG
+impoverishment/M
+impracticability
+impracticable
+impracticably
+impractical/Y
+impracticality/M
+imprecate/DSXGN
+imprecation/M
+imprecise/PYN
+impreciseness/M
+imprecision/M
+impregnability/M
+impregnable
+impregnably
+impregnate/GNDS
+impregnation/M
+impresario/SM
+impress/MDSGV
+impressed/U
+impressibility/M
+impressible
+impression/BSM
+impressionability/M
+impressionism/M
+impressionist/SM
+impressionistic
+impressive/PY
+impressiveness/M
+imprimatur/SM
+imprint/MDRZGS
+imprinter/M
+imprison/SDLG
+imprisonment/SM
+improbability/SM
+improbable
+improbably
+impromptu/SM
+improper/Y
+impropriety/SM
+improve/GBDSL
+improved/U
+improvement/MS
+improvidence/M
+improvident/Y
+improvisation/SM
+improvisational
+improvise/ZGDRS
+improviser/M
+improvisor/SM
+imprudence/M
+imprudent/Y
+impudence/M
+impudent/Y
+impugn/ZGSDR
+impugner/M
+impulse/MGNVDS
+impulsion/M
+impulsive/PY
+impulsiveness/M
+impulsivity
+impunity/M
+impure/RYT
+impurity/SM
+imputation/SM
+impute/BDSG
+in/ASM
+inaccuracy/S
+inaction/M
+inadequacy/S
+inadvertence/M
+inadvertent/Y
+inalienability/M
+inalienably
+inamorata/SM
+inane/RYT
+inanimate/PY
+inanimateness/M
+inanity/SM
+inappropriate/Y
+inarticulate/Y
+inasmuch
+inaudible
+inaugural/SM
+inaugurate/XGNDS
+inauguration/M
+inboard/MS
+inbound
+inbox/MS
+inbreed/S
+inc/TGD
+incalculably
+incandescence/M
+incandescent/Y
+incantation/SM
+incapacitate/GNDS
+incarcerate/XDSGN
+incarceration/M
+incarnadine/DSG
+incarnate/AXGNDS
+incarnation/AM
+incendiary/SM
+incense/MGDS
+incentive's
+incentive/ES
+incentivize/EDSG
+inception/SM
+incessant/Y
+incest/M
+incestuous/PY
+incestuousness/M
+inch/MDSG
+inchoate
+inchworm/SM
+incidence/SM
+incident/SM
+incidental/MYS
+incinerate/DSGN
+incineration/M
+incinerator/MS
+incipience/M
+incipient/Y
+incise/XGNVDS
+incision/M
+incisive/PY
+incisiveness/M
+incisor/MS
+incitement/MS
+inciter/MS
+incl
+inclement
+inclination/EM
+inclinations
+incline's
+incline/EGDS
+include/GDS
+inclusion/MS
+inclusive/YP
+inclusiveness/M
+incognito/MS
+incombustible
+incommode/GD
+incommodious
+incommunicado
+incompetent/MS
+incomplete/Y
+inconceivability/M
+incongruous/PY
+incongruousness/M
+inconsolably
+inconstant/Y
+incontestability/M
+incontestably
+incontinent
+incontrovertibly
+inconvenience/GD
+incorporate/ADSGN
+incorporated/U
+incorporation/AM
+incorporator/S
+incorporeal
+incorrect/Y
+incorrigible/P
+incorrigibly
+increasing/Y
+increment/SMDG
+incremental/Y
+incrementalism
+incrementalist/SM
+incriminate/GNDS
+incrimination/M
+incriminatory
+incrustation/SM
+incubate/GNDS
+incubation/M
+incubator/SM
+incubus/MS
+inculcate/DSGN
+inculcation/M
+inculpate/DSG
+incumbency/SM
+incumbent/SM
+incunabula
+incunabulum/M
+incur/SB
+incurable/MS
+incurably
+incurious
+incurred
+incurring
+incursion/MS
+ind
+indebted/P
+indebtedness/M
+indeed
+indefatigable
+indefatigably
+indefeasible
+indefeasibly
+indefinably
+indelible
+indelibly
+indemnification/M
+indemnify/GDSXN
+indemnity/SM
+indentation/MS
+indention/M
+indenture/DG
+indescribably
+indestructibly
+indeterminably
+indeterminacy/M
+indeterminate/Y
+index/ZGMDRS
+indexation/SM
+indexer/M
+indicate/XDSGNV
+indication/M
+indicative/SMY
+indicator/MS
+indict/GDSBL
+indictment/SM
+indie/S
+indigence/M
+indigenous
+indigent/SMY
+indignant/Y
+indignation/M
+indigo/M
+indirect/Y
+indiscipline
+indiscreet/Y
+indiscretion/S
+indiscriminate/Y
+indispensability/M
+indispensable/MS
+indispensably
+indissolubility
+indissolubly
+indistinguishably
+indite/GDS
+indium/M
+individual/MYS
+individualism/M
+individualist/MS
+individualistic
+individualistically
+individuality/M
+individualization/M
+individualize/GDS
+individuate/DSGN
+individuation/M
+indivisibly
+indoctrinate/GNDS
+indoctrination/M
+indolence/M
+indolent/Y
+indomitable
+indomitably
+indubitable
+indubitably
+induce/DRSZGL
+inducement/SM
+inducer/M
+induct/DGV
+inductance/M
+inductee/SM
+induction/MS
+inductive/Y
+inductor/SM
+indue/DG
+indulge/DSG
+indulgence/SM
+indulgent/Y
+industrial/Y
+industrialism/M
+industrialist/SM
+industrialization/M
+industrialize/DSG
+industrious/YP
+industriousness/M
+industry/SM
+indwell/SG
+inebriate/MGNDS
+inebriation/M
+inedible
+ineffability/M
+ineffable
+ineffably
+inelastic
+ineligible/MS
+ineligibly
+ineluctable
+ineluctably
+inept/YP
+ineptitude/M
+ineptness/M
+inequality/S
+inert/YP
+inertia/M
+inertial
+inertness/M
+inescapable
+inescapably
+inestimably
+inevitability/M
+inevitable/M
+inevitably
+inexact/Y
+inexhaustibly
+inexorability
+inexorable
+inexorably
+inexpedient
+inexpert/Y
+inexpiable
+inexplicably
+inexpressibly
+inexpressive
+inextricably
+inf/ZT
+infallible
+infamy/SM
+infancy/M
+infant/MS
+infanticide/MS
+infantile
+infantry/SM
+infantryman/M
+infantrymen
+infarct/MS
+infarction/M
+infatuate/DSXGN
+infatuation/M
+infect/AESDG
+infected/U
+infection/ASM
+infectious/PY
+infectiousness/M
+infelicitous
+inference/SM
+inferential
+inferior/MS
+inferiority/M
+infernal/Y
+inferno/MS
+inferred
+inferring
+infest/GDS
+infestation/MS
+infidel/MS
+infidelity/S
+infiltrator/SM
+infinite/MV
+infinitesimal/SMY
+infinitival
+infinitive/MS
+infinitude/M
+infinitum
+infinity/SM
+infirm
+infirmary/SM
+infirmity/SM
+infix
+inflame/DSG
+inflammable
+inflammation/SM
+inflammatory
+inflatable/SM
+inflate/ADSG
+inflation/EM
+inflationary
+inflect/SDG
+inflection/MS
+inflectional
+inflict/SDGV
+infliction/M
+inflight
+inflow/SM
+influence/MGDS
+influenced/U
+influential/Y
+influenza/M
+influx/MS
+info/M
+infomercial/SM
+inform/Z
+informal/Y
+informant/SM
+informatics
+information/EM
+informational
+informative/PY
+informativeness/M
+informed/U
+infotainment/M
+infra
+infrared/M
+infrasonic
+infrastructural
+infrastructure/SM
+infrequence/M
+infrequent/Y
+infringe/LZR
+infringement/MS
+infuriate/GDS
+infuriating/Y
+infuser/SM
+ingenious/PY
+ingeniousness/M
+ingenue/SM
+ingenuity/M
+ingenuous/EY
+ingenuousness/M
+ingest/SDG
+ingestion/M
+inglenook/SM
+ingot/SM
+ingrain/G
+ingrate/SM
+ingratiate/GNDS
+ingratiating/Y
+ingratiation/M
+ingredient/MS
+ingress/MS
+inguinal
+ing辿nue/SM
+inhabit/DG
+inhabitable/U
+inhabitant/SM
+inhabited/U
+inhalant/SM
+inhalation/MS
+inhalator/MS
+inhaler/SM
+inharmonious
+inhere/DSG
+inherent/Y
+inherit/EGSD
+inheritance/EM
+inheritances
+inheritor/SM
+inhibit/GSD
+inhibition/SM
+inhibitor/SM
+inhibitory
+inhuman/Y
+inhumane/Y
+inimical/Y
+inimitably
+iniquitous/Y
+iniquity/SM
+initial/SGMDY
+initialism/S
+initialization
+initialize/DRSZG
+initialized/AU
+initiate/XMGNVDS
+initiated/U
+initiation/M
+initiative/SM
+initiator/MS
+initiatory
+initio
+inject/SDG
+injection/SM
+injector/SM
+injunctive
+injure/DRSZG
+injured/U
+injurer/M
+injurious
+ink/MD
+inkblot/SM
+inkiness/M
+inkjet/SM
+inkling/SM
+inkstand/SM
+inkwell/MS
+inky/RTP
+inland/M
+inline
+inmate/SM
+inmost
+inn/SGMRJ
+innards/M
+innate/PY
+innateness/M
+innermost
+innersole/SM
+innerspring
+innervate/GNDS
+innervation/M
+inning/M
+innit
+innkeeper/MS
+innocence/M
+innocent/MYS
+innocuous/PY
+innocuousness/M
+innovate/XDSGNV
+innovation/M
+innovator/MS
+innovatory
+innuendo/SM
+innuendoes
+innumerably
+innumerate
+inoculate/AGDS
+inoculation/MS
+inoperative
+inordinate/Y
+inorganic
+inositol
+inquire/ZGDR
+inquirer/M
+inquiring/Y
+inquiry/SM
+inquisition/MS
+inquisitional
+inquisitive/YP
+inquisitiveness/M
+inquisitor/SM
+inquisitorial
+inrush/MS
+insane/T
+insatiability/M
+insatiably
+inscribe/ZGDR
+inscriber/M
+inscription/MS
+inscrutability/M
+inscrutable/P
+inscrutableness/M
+inscrutably
+inseam/SM
+insecticidal
+insecticide/MS
+insectivore/MS
+insectivorous
+insecure/Y
+inseminate/DSGN
+insemination/M
+insensate
+insensible
+insensitive/Y
+insentient
+inseparable/MS
+insert's
+insert/AGSD
+insertion/AM
+insertions
+insetting
+inshore
+inside/RSMZ
+insider/M
+insidious/YP
+insidiousness/M
+insight/MS
+insightful
+insignia/SM
+insinuate/GNVDSX
+insinuation/M
+insinuator/SM
+insipid/PY
+insipidity/M
+insist/SGD
+insistence/M
+insistent/Y
+insisting/Y
+insofar
+insole/SM
+insolence/M
+insolent/Y
+insoluble
+insolubly
+insolvency/S
+insomnia/M
+insomniac/SM
+insomuch
+insouciance/M
+insouciant
+inspect/AGDS
+inspection/SM
+inspector/MS
+inspectorate/MS
+inspiration/MS
+inspirational
+inspiratory
+inspired/U
+inspiring/U
+inst
+instability/S
+install/UBZRSDG
+installation/MS
+installer/UM
+installment/SM
+instance/GD
+instant/MRYS
+instantaneous/Y
+instantiate/DSXGN
+instar
+instate/AGDS
+instead
+instigate/DSGN
+instigation/M
+instigator/MS
+instillation/M
+instinct/VMS
+instinctive/Y
+instinctual
+institute/XMZGNDRS
+instituter/M
+institution/M
+institutional/Y
+institutionalization/M
+institutionalize/DSG
+institutor/MS
+instr
+instruct/SDGV
+instructed/U
+instruction/MS
+instructional
+instructive/Y
+instructor/MS
+instrument/MDSG
+instrumental/MYS
+instrumentalist/SM
+instrumentality/M
+instrumentation/M
+insubordinate
+insufferable
+insufferably
+insula
+insular
+insularity/M
+insulate/GNDS
+insulation/M
+insulator/MS
+insulin/M
+insult/SMDG
+insulting/Y
+insuperable
+insuperably
+insurance/SM
+insure/DRSZGB
+insured/SM
+insurer/M
+insurgence/SM
+insurgency/SM
+insurgent/MS
+insurmountably
+insurrection/SM
+insurrectionist/SM
+int
+intact
+intaglio/MS
+integer/MS
+integral/SMY
+integrand
+integrate/AEVNGXSD
+integration/AEM
+integrationist/SM
+integrator
+integrity/M
+integument/SM
+intel/M
+intellect/MS
+intellectual/MYS
+intellectualism/M
+intellectualize/GDS
+intelligence/M
+intelligent/Y
+intelligentsia/M
+intelligibility/M
+intelligible/U
+intelligibly/U
+intended/SM
+intense/YTVR
+intensification/M
+intensifier/M
+intensify/DRSZGN
+intensity/S
+intensive/MYPS
+intensiveness/M
+intent/SMYP
+intention/MS
+intentional/UY
+intentness/M
+inter/ESL
+interact/SGVD
+interaction/SM
+interactive/Y
+interactivity
+interbred
+interbreed/GS
+intercede/GDS
+intercellular
+intercept/GMDS
+interception/MS
+interceptor/SM
+intercession/SM
+intercessor/MS
+intercessory
+interchange/DSMG
+interchangeability
+interchangeable
+interchangeably
+intercity
+intercollegiate
+intercom/SM
+intercommunicate/DSGN
+intercommunication/M
+interconnect/GDS
+interconnection/SM
+intercontinental
+intercourse/M
+intercultural
+interdenominational
+interdepartmental
+interdependence/M
+interdependent/Y
+interdict/GMDS
+interdiction/M
+interdisciplinary
+interest/ESMD
+interested/U
+interesting/Y
+interface/MGDS
+interfaith
+interfere/GDS
+interference/M
+interferon/M
+interfile/GDS
+intergalactic
+intergovernmental
+interim/M
+interior/SM
+interj
+interject/GDS
+interjection/SM
+interlace/GDS
+interlard/DGS
+interleave/DSG
+interleukin/M
+interline/GDSJ
+interlinear
+interlining/M
+interlink/DSG
+interlock/GMDS
+interlocutor/SM
+interlocutory
+interlope/ZGDRS
+interloper/M
+interlude/MGDS
+intermarriage/SM
+intermarry/GDS
+intermediacy/S
+intermediary/SM
+intermediate/XMYGNPDS
+intermediation/ES
+intermediator/MS
+interment/EM
+interments
+intermezzi
+intermezzo/MS
+interminably
+intermingle/DSG
+intermission/SM
+intermittence/S
+intermittency/S
+intermittent/Y
+intermix/GDS
+intermolecular/Y
+internal/SY
+internalization/M
+internalize/GDS
+international/SMY
+internationalism/M
+internationalist/SM
+internationalization
+internationalize/DSG
+interne/GDL
+internecine
+internee/SM
+interneship/S
+internet
+internist/MS
+internment/M
+internship/MS
+interoffice
+interoperability
+interoperable
+interoperate/S
+interpenetrate/DSGN
+interpersonal
+interplanetary
+interplay/M
+interpolate/XDSGN
+interpolation/M
+interpose/GDS
+interposition/M
+interpret/AGVDS
+interpretation/AMS
+interpretative
+interpreted/U
+interpreter/MS
+interquartile
+interracial
+interred/E
+interregnum/SM
+interrelate/XDSGN
+interrelation/M
+interrelationship/MS
+interring/E
+interrogate/DSGNVX
+interrogation/M
+interrogative/MYS
+interrogator/SM
+interrogatory/SM
+interrupt/ZGMDRS
+interrupter/M
+interruptible/U
+interruption/MS
+interscholastic
+intersect/GDS
+intersection/SM
+intersectional
+intersectionality
+intersession/SM
+intersex
+intersexual/MS
+intersexualism
+intersexuality
+intersperse/GNDS
+interspersion/M
+interstate/MS
+interstellar
+interstice/MS
+interstitial
+intertwine/GDS
+interurban
+interval/SM
+intervene/GDS
+intervention/SM
+interventionism/M
+interventionist/SM
+interview/ZGMDRS
+interviewee/MS
+interviewer/M
+intervocalic
+interwar
+interweave/GS
+interwove
+interwoven
+intestacy/M
+intestate
+intestinal
+intestine/MS
+intifada/S
+intimacy/SM
+intimate/MYGNDSX
+intimation/M
+intimidate/GNDS
+intimidating/Y
+intimidation/M
+intl
+intonation/SM
+intoxicant/SM
+intoxicate/DSGN
+intoxication/M
+intracranial
+intramural
+intramuscular
+intranet/MS
+intransigence/M
+intransigent/MYS
+intrastate
+intrauterine
+intravenous/MSY
+intrepid/Y
+intrepidity/M
+intricacy/SM
+intricate/Y
+intrigue/DRSMZG
+intriguer/M
+intriguing/Y
+intrinsic
+intrinsically
+intro/SM
+introduce/AGDS
+introduction/AM
+introductions
+introductory
+introit/SM
+introspect/GVDS
+introspection/M
+introspective/Y
+introversion/M
+introvert/MDS
+intrude/DRSZG
+intruder/M
+intrusion/SM
+intrusive/YP
+intrusiveness/M
+intuit/SDGV
+intuition/S
+intuitive/PY
+intuitiveness/M
+inundate/XDSGN
+inundation/M
+inure/DSG
+invade/DRSZG
+invader/M
+invalid/GMDYS
+invalidism/M
+invaluable
+invaluably
+invariant
+invasion/MS
+invasive
+invective/M
+inveigh/GD
+inveighs
+inveigle/ZGDRS
+inveigler/M
+invent/ASGVD
+invention/AMS
+inventive/PY
+inventiveness/M
+inventor/MS
+inventory/DSMG
+inverse/SMY
+invert/SMDRZG
+inverter/M
+invertible
+invest/ASDGL
+investigate/GNVDSX
+investigation/M
+investigator/SM
+investigatory
+investiture/MS
+investment/AEM
+investor/SM
+inveteracy/M
+inveterate
+invidious/YP
+invidiousness/M
+invigilate/GNDS
+invigilator/S
+invigorate/ADSG
+invigorating/Y
+invigoration/M
+invincibility/M
+invincibly
+inviolability/M
+inviolably
+inviolate
+invitation/SM
+invitational/SM
+invite/DSMG
+invited/U
+invitee/SM
+inviting/Y
+invoke/DSG
+involuntariness/M
+involuntary/P
+involution/M
+involve/LDSG
+involved/U
+involvement/SM
+inward/SY
+ioctl
+iodide/SM
+iodine/M
+iodize/DSG
+ion/USM
+ionic
+ionization/UM
+ionize/UDSG
+ionizer/MS
+ionosphere/MS
+ionospheric
+iota/MS
+ipecac/SM
+irascibility/M
+irascible
+irascibly
+irate/YP
+irateness/M
+ire/M
+ireful
+irenic
+irides
+iridescence/M
+iridescent/Y
+iridium/M
+iris/MS
+irk/SGD
+irksome/YP
+irksomeness/M
+iron/MDSG
+ironclad/MS
+ironic/U
+ironical/Y
+ironically/U
+ironing/M
+ironmonger/S
+ironmongery
+ironstone/M
+ironware/M
+ironwood/MS
+ironwork/M
+irony/SM
+irradiate/DSGN
+irradiation/M
+irrational/SMY
+irrationality/M
+irreclaimable
+irreconcilability/M
+irreconcilable
+irreconcilably
+irrecoverable
+irrecoverably
+irredeemable
+irredeemably
+irreducible
+irreducibly
+irrefutable
+irrefutably
+irregular/MYS
+irregularity/SM
+irrelevance/MS
+irrelevancy/MS
+irrelevant/Y
+irreligion
+irreligious
+irremediable
+irremediably
+irremovable
+irreparable
+irreparably
+irreplaceable
+irrepressible
+irrepressibly
+irreproachable
+irreproachably
+irresistible
+irresistibly
+irresolute/PYN
+irresoluteness/M
+irresolution/M
+irrespective
+irresponsibility/M
+irresponsible
+irresponsibly
+irretrievable
+irretrievably
+irreverence/M
+irreverent/Y
+irreversible
+irreversibly
+irrevocability
+irrevocable/P
+irrevocably
+irrigable
+irrigate/DSGN
+irrigation/M
+irritability/M
+irritable
+irritably
+irritant/SM
+irritate/DSXGN
+irritating/Y
+irritation/M
+irrupt/DGVS
+irruption/SM
+ischemia
+ischemic
+isinglass/M
+isl
+island/SZMR
+islander/M
+isle/MS
+islet/SM
+ism/CM
+isms
+isn't
+isobar/MS
+isobaric
+isolate/DSMGN
+isolation/M
+isolationism/M
+isolationist/SM
+isomer/MS
+isomeric
+isomerism/M
+isometric/S
+isometrically
+isometrics/M
+isometry
+isomorphic
+isomorphism
+isosceles
+isospin/S
+isotherm/SM
+isotope/SM
+isotopic
+isotropic
+issuance/M
+issue/ADSMG
+issuer/MS
+isthmian
+isthmus/MS
+it'd
+it'll
+it/USM
+ital
+italic/SM
+italicization/M
+italicize/GDS
+italics/M
+itch/MDSG
+itchiness/M
+itchy/RPT
+item/MS
+itemization/M
+itemize/GDS
+iterate/AXGNVDS
+iteration/AM
+iterative/Y
+iterator/S
+itinerant/SM
+itinerary/SM
+itself
+iv/U
+ivory/SM
+ivy/DSM
+ix
+j/F
+jab/SM
+jabbed
+jabber/SMDRZG
+jabberer/M
+jabbing
+jabot/SM
+jacaranda/MS
+jack/MDGS
+jackal/SM
+jackass/MS
+jackboot/SMD
+jackdaw/MS
+jacket/SMD
+jackhammer/MS
+jackknife/MGDS
+jackknives
+jackpot/MS
+jackrabbit/MS
+jackstraw/MS
+jacquard/M
+jade/MGDS
+jaded/PY
+jadedness/M
+jadeite/M
+jag/SM
+jagged/TPRY
+jaggedness/M
+jaggies
+jaguar/SM
+jail/MDRZGS
+jailbird/SM
+jailbreak/SM
+jailer/M
+jailhouse/S
+jalapeno/MS
+jalape単o/MS
+jalopy/SM
+jalousie/MS
+jam/SM
+jamb/MS
+jambalaya/M
+jamboree/MS
+jammed
+jamming
+jammy/RT
+jangle/DRSMZG
+jangler/M
+janitor/SM
+janitorial
+japan/SM
+japanned
+japanning
+jape/MGDS
+japonica
+jar/SM
+jardiniere/SM
+jardini竪re/SM
+jarful/MS
+jargon/M
+jarred
+jarring/Y
+jasmine/SM
+jasper/M
+jato/MS
+jaundice/DSMG
+jaunt/SGMD
+jauntily
+jauntiness/M
+jaunty/RPT
+java/M
+javelin/SM
+jaw/SGMD
+jawbone/DSMG
+jawbreaker/MS
+jawline/S
+jay/SM
+jaybird/SM
+jaywalk/DRSZG
+jaywalker/M
+jaywalking/M
+jazz/MDSG
+jazzy/TR
+jct
+jealous/Y
+jealousy/SM
+jean/MS
+jeans/M
+jeep/MS
+jeer/MDSG
+jeering/MY
+jeez
+jejuna
+jejune
+jejunum/M
+jell/DSG
+jello/SM
+jelly/GDSM
+jellybean/MS
+jellyfish/MS
+jellylike
+jellyroll/SM
+jemmy/GDS
+jennet/MS
+jenny/SM
+jeopardize/GDS
+jeopardy/M
+jeremiad/MS
+jerk/MDSG
+jerkily
+jerkin/MS
+jerkiness/M
+jerkwater
+jerky/TRMP
+jeroboam/S
+jerrican/S
+jerrybuilt
+jerrycan/S
+jersey/MS
+jest/MDRSZG
+jester/M
+jesting/Y
+jet/SM
+jetliner/SM
+jetport/MS
+jetsam/M
+jetted
+jetting
+jettison/MDSG
+jetty/SM
+jewel/SZGMDR
+jeweler/M
+jewellery
+jewelry/SM
+jg
+jib/SGMD
+jibbed
+jibbing
+jibe/MS
+jiff/MS
+jiffy/SM
+jig's
+jig/AS
+jigged/A
+jigger's
+jigger/ASDG
+jigging/A
+jiggle/DSMG
+jiggly
+jigsaw/SMDG
+jihad/SM
+jihadist/SM
+jilt/MDSG
+jimmy/DSMG
+jimsonweed/M
+jingle/DSMG
+jingly
+jingoism/M
+jingoist/SM
+jingoistic
+jink/DSG
+jinn/MS
+jinni/M
+jinricksha/SM
+jinrikisha/SM
+jinx/MDSG
+jitney/SM
+jitter/SDG
+jitterbug/MS
+jitterbugged
+jitterbugger/M
+jitterbugging
+jitters/M
+jittery/RT
+jive/MGDS
+job/SM
+jobbed
+jobber/SM
+jobbing
+jobholder/MS
+jobless/P
+joblessness/M
+jobshare/S
+jobsworth
+jobsworths
+jock/MS
+jockey/SGMD
+jockstrap/MS
+jocose/PY
+jocoseness/M
+jocosity/M
+jocular/Y
+jocularity/M
+jocund/Y
+jocundity/M
+jodhpurs/M
+joey/S
+jog/SM
+jogged
+jogger/SM
+jogging/M
+joggle/DSMG
+john/MS
+johnny/SM
+johnnycake/MS
+join's
+join/AFDSG
+joiner/FMS
+joinery/M
+joint's
+joint/EGSD
+jointly/F
+joist/SM
+jojoba
+joke/MZGDRS
+joker/M
+jokester/S
+jokey
+jokier
+jokiest
+joking/Y
+jollification/SM
+jollily
+jolliness/M
+jollity/M
+jolly/TGPDRSM
+jolt/MDRSZG
+jolter/M
+jonquil/SM
+josh/MDRSZG
+josher/M
+jostle/MGDS
+jot/SM
+jotted
+jotter/MS
+jotting/MS
+joule/SM
+jounce/MGDS
+jouncy
+journal/MS
+journalese/M
+journalism/M
+journalist/SM
+journalistic
+journey/ZGMDRS
+journeyer/M
+journeyman/M
+journeymen
+journo/S
+joust/SZGMDR
+jouster/M
+jousting/M
+jovial/Y
+joviality/M
+jowl/MS
+jowly/TR
+joy/SGMD
+joyful/YP
+joyfuller
+joyfullest
+joyfulness/M
+joyless/PY
+joylessness/M
+joyous/YP
+joyousness/M
+joyridden
+joyride/RSMZG
+joyrider/M
+joyriding/M
+joyrode
+joystick/SM
+jr
+jubilant/Y
+jubilation/M
+jubilee/SM
+judder/GDS
+judge's
+judge/ADSG
+judgement/SM
+judgemental
+judgeship/MS
+judgey
+judgment/SM
+judgmental/Y
+judgy
+judicatory/SM
+judicature/M
+judicial/Y
+judiciary/SM
+judicious/IYP
+judiciousness/IM
+judo/M
+jug/SM
+jugful/MS
+jugged
+juggernaut/SM
+jugging
+juggle/MZGDRS
+juggler/M
+jugglery/M
+jugular/SM
+juice/DRSMZG
+juicer/M
+juicily
+juiciness/M
+juicy/PTR
+jujitsu/M
+jujube/MS
+jukebox/MS
+julep/SM
+julienne
+jumble/MGDS
+jumbo/SM
+jump/MDRSZG
+jumper/M
+jumpily
+jumpiness/M
+jumpsuit/MS
+jumpy/TRP
+jun
+junco/SM
+junction/FISM
+juncture/FMS
+jungle/MS
+junior/MS
+juniper/SM
+junk/MDRSZG
+junker/M
+junket/MDRSZG
+junketeer/MS
+junketer/M
+junkie/M
+junky/TRSM
+junkyard/MS
+junta/SM
+juridic
+juridical/Y
+jurisdiction/SM
+jurisdictional
+jurisprudence/M
+jurist/MS
+juristic
+juror/FSM
+jury/ISM
+juryman/M
+jurymen
+jurywoman/M
+jurywomen
+just/RYPT
+justice/IMS
+justifiable/U
+justifiably/U
+justification/M
+justified/U
+justify/XGDSN
+justness/M
+jut/SM
+jute/M
+jutted
+jutting
+juvenile/SM
+juxtapose/DSG
+juxtaposition/SM
+k/IFGS
+kHz
+kW
+kWh
+kabbala
+kabbalah
+kabob/SM
+kabocha
+kaboom
+kabuki/M
+kaddish/MS
+kaffeeklatch/MS
+kaffeeklatsch/MS
+kahuna/S
+kaiser/MS
+kakistocracy
+kale/M
+kaleidoscope/MS
+kaleidoscopic
+kaleidoscopically
+kamikaze/MS
+kana
+kangaroo/MS
+kanji
+kaolin/M
+kapok/M
+kappa/SM
+kaput
+karakul/M
+karaoke/MS
+karat/SM
+karate/M
+karma/M
+karmic
+kart/MS
+katakana
+katydid/SM
+kayak/SMDG
+kayaking/M
+kayo/MDSG
+kazoo/SM
+kbps
+kc
+kebab/SM
+kebob/SM
+kedgeree
+keel/MDSG
+keelhaul/DGS
+keen/MDRYSTGP
+keenness/M
+keep/MRSZG
+keeper/M
+keeping/M
+keepsake/MS
+keester/S
+keg/SM
+keister/S
+kelp/M
+kelvin/SM
+ken/SM
+kenned
+kennel/SGMD
+kenning
+keno/M
+kepi/MS
+kept
+keratin/M
+keratitis
+kerbside
+kerchief/SM
+kerfuffle/S
+kern/G
+kerne
+kernel/SM
+kerosene/M
+kestrel/MS
+ketch/MS
+ketchup/M
+keto
+ketogenic
+ketone/S
+kettle/SM
+kettledrum/SM
+key/SGMD
+keybinding/S
+keyboard/ZGSMDR
+keyboarder/M
+keyboardist/SM
+keyhole/MS
+keylogger/MS
+keylogging/SM
+keynote/MZGDRS
+keynoter/M
+keypad/SM
+keypunch/ZGMDRS
+keypuncher/M
+keystone/MS
+keystroke/SM
+keyword/MS
+kg
+khaki/SM
+khan/MS
+kibble/DSMG
+kibbutz/MS
+kibbutzim
+kibibyte/SM
+kibitz/ZGDRS
+kibitzer/M
+kibosh/M
+kick/MDRSZG
+kickback/SM
+kickball/M
+kickboxing
+kicker/M
+kickoff/MS
+kickstand/MS
+kicky/RT
+kid/SM
+kidded
+kidder/SM
+kiddie/SM
+kidding
+kiddish
+kiddo/SM
+kidnap/S
+kidnapped
+kidnapper/MS
+kidnapping/MS
+kidney/SM
+kidskin/M
+kielbasa/MS
+kielbasi
+kike/S
+kill/JMDRSZG
+killdeer/SM
+killer/M
+killing/M
+killjoy/SM
+kiln/MDSG
+kilo/MS
+kilobyte/SM
+kilocoulomb/S
+kilocycle/SM
+kilogram/SM
+kilohertz/M
+kilojoule/S
+kiloliter/MS
+kilometer/MS
+kilonewton/S
+kilopascal/S
+kiloton/SM
+kilovolt/S
+kilowatt/SM
+kilt/MDRS
+kilter/M
+kimono/MS
+kin/M
+kinase
+kind's
+kind/UPRYT
+kinda
+kindergarten/MS
+kindergartner/SM
+kinderg辰rtner/SM
+kindhearted/PY
+kindheartedness/M
+kindle/AGDS
+kindliness/M
+kindling/M
+kindly/URT
+kindness/UM
+kindnesses
+kindred/M
+kinds
+kine/S
+kinematic/S
+kinematics/M
+kinetic/S
+kinetically
+kinetics/M
+kinfolk/SM
+kinfolks/M
+king/MYS
+kingdom/SM
+kingfisher/SM
+kingly/RT
+kingmaker/S
+kingpin/SM
+kingship/M
+kink/MDSG
+kinkily
+kinkiness/M
+kinky/TPR
+kinsfolk/M
+kinship/M
+kinsman/M
+kinsmen
+kinswoman/M
+kinswomen
+kiosk/SM
+kip/SM
+kipped
+kipper/MDGS
+kipping
+kirsch/MS
+kismet/M
+kiss/MDRSBZG
+kisser/M
+kissoff/SM
+kissogram/S
+kit/SGMD
+kitbag/MS
+kitchen/SM
+kitchenette/MS
+kitchenware/M
+kite/MS
+kith/M
+kitsch/M
+kitschy
+kitted
+kitten/MS
+kittenish
+kitting
+kitty/SM
+kiwi/MS
+kiwifruit/MS
+kl
+klaxon/S
+kleptocracy
+kleptomania/M
+kleptomaniac/SM
+kludge/GDS
+kludgy
+kluge/DS
+klutz/MS
+klutziness/M
+klutzy/TRP
+km
+kn
+knack/SZMR
+knacker/GD
+knackwurst/MS
+knapsack/MS
+knave/SM
+knavery/M
+knavish/Y
+knead/SZGDR
+kneader/M
+knee/MDS
+kneecap/SM
+kneecapped
+kneecapping
+kneeing
+kneel/SG
+knell/SGMD
+knelt
+knew
+knicker/S
+knickerbockers/M
+knickers/M
+knickknack/MS
+knife/DSMG
+knight/MDYSG
+knighthood/MS
+knightliness/M
+knish/MS
+knit/MS
+knitted
+knitter/SM
+knitting/M
+knitwear/M
+knives
+knob/MS
+knobbly
+knobby/TR
+knock/SZGMDR
+knockabout
+knockdown/SM
+knocker/M
+knockoff/SM
+knockout/SM
+knockwurst/SM
+knoll/SM
+knot/MS
+knothole/SM
+knotted
+knotting
+knotty/TR
+know/SB
+knowing/UYS
+knowledge/M
+knowledgeable
+knowledgeably
+known
+knuckle/DSMG
+knuckleduster/S
+knucklehead/MS
+knurl/SGMD
+koala/SM
+koan/S
+kohl
+kohlrabi/M
+kohlrabies
+kola/MS
+kombucha
+kook/MS
+kookaburra/SM
+kookiness/M
+kooky/TPR
+kopeck/MS
+kopek/SM
+korma
+kosher/DSG
+kowtow/GMDS
+kph
+kraal/SM
+kraut/SM!
+krill/M
+krona/M
+krone/RM
+kronor
+kronur
+krypton/M
+kryptonite
+kr坦na/M
+kr坦nur
+kt
+kuchen/SM
+kudos/M
+kudzu/SM
+kumquat/MS
+kvetch/ZGMDRS
+kvetcher/M
+kw
+l/SDXTGJ
+la/M
+lab/SM
+label's
+label/ASDG
+labeled/U
+labelled/U
+labia
+labial/SM
+labile
+labium/M
+labor/SMDRZG
+laboratory/SM
+laborer/M
+laborious/PY
+laboriousness/M
+laborsaving
+laburnum/MS
+labyrinth/M
+labyrinthine
+labyrinths
+lac/M
+lace's
+lace/UGDS
+lacerate/DSGNX
+laceration/M
+lacewing/SM
+lacework/M
+lachrymal
+lachrymose
+lack/MDSG
+lackadaisical/Y
+lackey/SM
+lackluster
+laconic
+laconically
+lacquer/GMDS
+lacrimal
+lacrosse/M
+lactate/GNDS
+lactation/M
+lacteal
+lactic
+lactose/M
+lacuna/M
+lacunae
+lacy/RT
+lad/SGMDNJ
+ladder/GSMD
+laddie/SM
+laddish/P
+lade/S
+laden/U
+lading/M
+ladle/DSMG
+lady/SM
+ladybird/SM
+ladybug/MS
+ladyfinger/MS
+ladylike/U
+ladylove/MS
+ladyship/MS
+laetrile/M
+lag/SZMR
+lager/M
+laggard/MYS
+lagged
+lagging/M
+lagniappe/SM
+lagoon/SM
+laid/IA
+lain
+lair/MS
+laird/SM
+laissez-faire
+laity/M
+lake/MS
+lakefront/S
+lakeside
+lallygag/S
+lallygagged
+lallygagging
+lam/SM
+lama/MS
+lamasery/SM
+lamb/MDSG
+lambada/MS
+lambast/GDS
+lambaste/S
+lambda/SM
+lambency/M
+lambent/Y
+lambkin/SM
+lambskin/SM
+lambswool
+lame/MYZTGDRSP
+lamebrain/MDS
+lameness/M
+lament/BSMDG
+lamentably
+lamentation/MS
+lamina/M
+laminae
+laminar
+laminate/MGNDS
+lamination/M
+lammed
+lamming
+lamp/MS
+lampblack/M
+lamplight/MRZ
+lamplighter/M
+lampoon/SGMD
+lamppost/SM
+lamprey/MS
+lampshade/SM
+lanai/SM
+lance/DRSMZG
+lancer/M
+lancet/SM
+land/MDRSGJ
+landau/SM
+landfall/MS
+landfill/MS
+landholder/SM
+landholding/MS
+landing/M
+landlady/SM
+landless/M
+landline/MS
+landlocked
+landlord/MS
+landlubber/MS
+landmark/MS
+landmass/MS
+landmine/S
+landowner/MS
+landownership
+landowning/SM
+landscape/MZGDRS
+landscaper/M
+landslid
+landslide/MGS
+landslip/S
+landsman/M
+landsmen
+landward/S
+lane/MS
+language/MS
+langue/SM
+languid/PY
+languidness/M
+languish/DSG
+languor/SM
+languorous/Y
+lank/RYTP
+lankiness/M
+lankness/M
+lanky/RTP
+lanolin/M
+lantern/MS
+lanthanum/M
+lanyard/MS
+lap/SM
+laparoscopic
+laparoscopy
+laparotomy
+lapboard/SM
+lapdog/SM
+lapel/SM
+lapidary/SM
+lapin/SM
+lapped
+lappet/SM
+lapping
+lapse/AKGMSD
+laptop/SM
+lapwing/MS
+larboard/SM
+larcenist/SM
+larcenous
+larceny/SM
+larch/MS
+lard/MDRSZG
+larder/M
+lardy/RT
+large/RSPMYT
+largehearted
+largeness/M
+largess/M
+largish
+largo/SM
+lariat/SM
+lark/MDSG
+larkspur/SM
+larva/M
+larvae
+larval
+laryngeal
+larynges
+laryngitis/M
+larynx/M
+lasagna/MS
+lascivious/YP
+lasciviousness/M
+lase/ZGDRS
+laser/M
+lash/MDSGJ
+lashing/M
+lass/MS
+lassie/SM
+lassitude/M
+lasso/SMDG
+last/MDYSG
+lasting/UY
+lat/S
+latch's
+latch/UDSG
+latchkey/SM
+late/YTRP
+latecomer/MS
+latency/M
+lateness/M
+latent
+lateral/MDYSG
+latest/M
+latex/M
+lath/MDRSZG
+lathe/M
+lather/GMD
+lathery
+laths
+latices
+latish
+latitude/MS
+latitudinal
+latitudinarian/MS
+latrine/MS
+latte/RSM
+latter/MY
+lattice/MDS
+latticework/SM
+laud/MDSGB
+laudably
+laudanum/M
+laudatory
+laugh/BMDG
+laughably
+laughing/MY
+laughingstock/SM
+laughs
+laughter/M
+launch/AGMDS
+launcher/SM
+launchpad/SM
+launder/DRZGS
+launderer/M
+launderette/SM
+laundress/MS
+laundromat/MS
+laundry/SM
+laundryman/M
+laundrymen
+laundrywoman/M
+laundrywomen
+laureate/MS
+laureateship/M
+laurel/SM
+lav/SGD
+lava/M
+lavage/M
+lavaliere/SM
+lavatorial
+lavatory/SM
+lave/S
+lavender/SM
+lavish/PTGDRSY
+lavishness/M
+law/SM
+lawbreaker/SM
+lawbreaking/M
+lawful/UPY
+lawfulness/UM
+lawgiver/MS
+lawless/PY
+lawlessness/M
+lawmaker/MS
+lawmaking/M
+lawman/M
+lawmen
+lawn/MS
+lawnmower/SM
+lawrencium/M
+lawsuit/MS
+lawyer/SMY
+lax/TRYP
+laxative/MS
+laxity/M
+laxness/M
+lay/AICSGM
+layabout/S
+layaway/M
+layer/CSM
+layered
+layering/M
+layette/MS
+layman/M
+laymen
+layoff/SM
+layout/SM
+layover/MS
+laypeople
+layperson/MS
+layup/SM
+laywoman/M
+laywomen
+laze/MGDS
+lazily
+laziness/M
+lazy/DRSTGP
+lazybones/M
+lb/S
+lbw
+lea/SM
+leach/DSG
+leachate/S
+lead/MDNRSZG
+leader/M
+leaderless
+leadership/SM
+leading/M
+leaf/MDSG
+leafage/M
+leafless
+leaflet/GMDS
+leafstalk/MS
+leafy/RT
+league/DSMG
+leak/MDSG
+leakage/MS
+leakiness/M
+leaky/PRT
+lean/MDRSTGJP
+leaning/M
+leanness/M
+leap/MDRSZG
+leaper/M
+leapfrog/MS
+leapfrogged
+leapfrogging
+leapt
+learn/AUGDS
+learnability
+learnable
+learnedly
+learner/MS
+learning's
+learnt
+lease/ADSMG
+leaseback/SM
+leasehold/MRSZ
+leaseholder/M
+leaser/SM
+leash's
+leash/UDSG
+least/M
+leastwise
+leather/MS
+leatherette/M
+leatherneck/MS
+leathery
+leave/DRSMZGJ
+leaven/SGMD
+leavened/U
+leavening/M
+leaver/M
+leavings/M
+lech/MDRSZG
+lecher/M
+lecherous/PY
+lecherousness/M
+lechery/M
+lecithin/M
+lectern/MS
+lector/SM
+lecture/MZGDRS
+lecturer/M
+lectureship/SM
+lede
+ledge/RSMZ
+ledger/M
+lee/RSMZ
+leech/MDSG
+leek/MS
+leer/MDG
+leeriness/M
+leery/RPT
+leeward/SM
+leeway/M
+left/MRST
+leftism/M
+leftist/SM
+leftmost
+leftover/SM
+leftward/S
+lefty/SM
+leg/SM
+legacy/SM
+legal/SMY
+legalese/M
+legalism/MS
+legalistic
+legalistically
+legality/SM
+legalization/M
+legalize/GDS
+legate/CXMNS
+legatee/MS
+legation's/AC
+legato/SM
+legend/SM
+legendarily
+legendary
+legerdemain/M
+legged
+leggin/SM
+legginess/M
+legging/MS
+leggy/RPT
+leghorn/MS
+legibility/M
+legible
+legibly
+legion/SM
+legionary/SM
+legionnaire/SM
+legislate/DSGNV
+legislation/M
+legislative/Y
+legislator/MS
+legislature/SM
+legit
+legitimacy/M
+legitimate/DSYG
+legitimatize/GDS
+legitimization/M
+legitimize/DSG
+legless
+legman/M
+legmen
+legroom/SM
+legume/MS
+leguminous
+legwarmer/S
+legwork/M
+lei/SM
+leisure/DMY
+leisureliness/M
+leisurewear/M
+leitmotif/MS
+leitmotiv/MS
+lemma/S
+lemme/JG
+lemming/M
+lemon/SM
+lemonade/SM
+lemongrass
+lemony
+lemur/SM
+lend/RSZG
+lender/M
+length/MNX
+lengthen/GD
+lengthily
+lengthiness/M
+lengths
+lengthwise
+lengthy/PRT
+lenience/M
+leniency/M
+lenient/Y
+lenitive
+lens/MS
+lent
+lentil/MS
+lento
+leonine
+leopard/SM
+leopardess/MS
+leotard/SM
+leper/SM
+lepidopterist/MS
+leprechaun/MS
+leprosy/M
+leprous
+lepta
+lepton/MS
+lesbian/SM
+lesbianism/M
+lesion/MS
+less/MNRX
+lessee/MS
+lessen/GD
+lesson/MS
+lessor/MS
+let/ISM
+letdown/SM
+lethal/Y
+lethality
+lethargic
+lethargically
+lethargy/M
+letter/ZGMDRS
+letterbomb/S
+letterbox/S
+lettered/U
+letterer/M
+letterhead/MS
+lettering/M
+letterpress/M
+letting/S
+lettuce/MS
+letup/SM
+leucine
+leucotomy/S
+leukemia/M
+leukemic/SM
+leukocyte/MS
+levee/SM
+level/PSZGMDRY
+leveler/M
+levelheaded/P
+levelheadedness/M
+levelness/M
+lever/SGMD
+leverage's
+leverage/CDSG
+leviathan/MS
+levier/M
+levitate/DSGN
+levitation/M
+levity/M
+levy/DRSMZG
+lewd/RYPT
+lewdness/M
+lexer/S
+lexical
+lexicographer/MS
+lexicographic
+lexicographical
+lexicography/M
+lexicological
+lexicologist/M
+lexicology/SM
+lexicon/SM
+lexis
+lg
+liabilities
+liability/AM
+liable/A
+liaise/GDS
+liaison/MS
+liar/MS
+lib/M
+libation/SM
+libber/MS
+libel/SZGMDR
+libeler/M
+libelous
+liberal/MYPS
+liberalism/M
+liberality/M
+liberalization/SM
+liberalize/GDS
+liberalness/M
+liberate/CDSGN
+liberation/CM
+liberator/MS
+libertarian/SM
+libertine/MS
+liberty/SM
+libidinal
+libidinous
+libido/MS
+librarian/MS
+librarianship
+library/SM
+librettist/MS
+libretto/SM
+lice
+license/MGDS
+licensed/U
+licensee/MS
+licensor
+licentiate/SM
+licentious/YP
+licentiousness/M
+lichen/MS
+licit/Y
+lick/MDJSG
+licking/M
+licorice/SM
+lid/SM
+lidded
+lidless
+lido/MS
+lie/DSM
+lied/MR
+lief/RT
+liege/SM
+lien/MS
+lieu/M
+lieutenancy/M
+lieutenant/MS
+life/MZR
+lifebelt/S
+lifeblood/M
+lifeboat/MS
+lifebuoy/MS
+lifecycle
+lifeforms
+lifeguard/SM
+lifeless/YP
+lifelessness/M
+lifelike
+lifeline/MS
+lifelong
+lifer/M
+lifesaver/SM
+lifesaving/M
+lifespan/S
+lifestyle/SM
+lifetime/MS
+lifework/MS
+lift/MDRSZG
+lifter/M
+liftoff/SM
+ligament/MS
+ligate/GNDS
+ligation/M
+ligature/MGDS
+light's/C
+light/CASTGD
+lighted/U
+lighten/SDRZG
+lightener/M
+lighter/SM
+lightface/MD
+lightheaded
+lighthearted/YP
+lightheartedness/M
+lighthouse/MS
+lighting's
+lightly
+lightness/M
+lightning/MDS
+lightproof
+lightship/MS
+lightweight/SM
+ligneous
+lignin
+lignite/M
+lii
+likability/M
+likable/P
+likableness/M
+like/EMGDST
+likeability/M
+likeable/P
+likeableness/M
+likelihood/UM
+likelihoods
+likeliness/UM
+likely/UPRT
+liken/SGD
+likeness/UM
+likenesses
+liker
+likewise
+liking/M
+lilac/SM
+lilliputian
+lilo/S
+lilt/MDSG
+lily/SM
+limb/MS
+limber/UDSG
+limberness/M
+limbless
+limbo/SM
+lime/MGDS
+limeade/SM
+limelight/M
+limerick/SM
+limescale
+limestone/M
+limey/S
+limit's
+limit/CSZGDR
+limitation/CM
+limitations
+limited/U
+limiter's
+limiting/S
+limitless/P
+limitlessness/M
+limn/DSG
+limnological
+limnologist/MS
+limnology/M
+limo/MS
+limousine/MS
+limp/MDRYSPTG
+limpet/MS
+limpid/YP
+limpidity/M
+limpidness/M
+limpness/M
+limy/RT
+linage/M
+linchpin/SM
+linden/MS
+line/MZGDRSJ
+lineage/MS
+lineal/Y
+lineament/SM
+linear/Y
+linearity/M
+linebacker/MS
+lined/U
+linefeed
+lineman/M
+linemen
+linen/SM
+linens/M
+liner/M
+linesman/M
+linesmen
+lineup/MS
+ling/M
+linger/ZGJDRS
+lingerer/M
+lingerie/M
+lingering/Y
+lingo/M
+lingoes
+lingua
+lingual
+linguine/M
+linguini/SM
+linguist/SM
+linguistic/S
+linguistical/Y
+linguistics/M
+liniment/SM
+lining/M
+link's
+link/UDSG
+linkage/MS
+linker
+linkman
+linkmen
+linkup/MS
+linnet/MS
+lino
+linoleum/M
+linseed/M
+lint's
+lint/CDG
+lintel/MS
+lints
+linty/TR
+lion/MS
+lioness/MS
+lionhearted
+lionization/M
+lionize/GDS
+lip/SM
+lipid/SM
+liposuction/M
+lipped
+lippy
+lipread/GRS
+lipreader/M
+lipreading/M
+lipstick/MDSG
+liq
+liquefaction/M
+liquefy/DSG
+liqueur/SM
+liquid/MS
+liquidate/XGNDS
+liquidation/M
+liquidator/MS
+liquidity/M
+liquidize/ZGDRS
+liquidizer/M
+liquor/MDGS
+lira/M
+lire
+lisle/M
+lisp/MDRSZG
+lisper/M
+lissome
+list/MDNSJXG
+listed/U
+listen/BMDRZG
+listener/M
+listeria
+listing/M
+listless/YP
+listlessness/M
+listserv/M
+lit/ZR
+litany/SM
+litchi/MS
+lite
+liter/M
+literacy/M
+literal/SMYP
+literalness/M
+literariness/M
+literary/P
+literate/SMY
+literati/M
+literature/M
+lithe/RPYT
+litheness/M
+lithesome
+lithium/M
+lithograph/MDRZG
+lithographer/M
+lithographic
+lithographically
+lithographs
+lithography/M
+lithosphere/SM
+litigant/SM
+litigate/DSGN
+litigation/M
+litigator/MS
+litigious/P
+litigiousness/M
+litmus/M
+litotes/M
+litter/MDRSZG
+litterateur/MS
+litterbug/MS
+litterer/M
+little/MTRP
+littleness/M
+littoral/SM
+litt辿rateur/SM
+liturgical/Y
+liturgist/SM
+liturgy/SM
+livability/M
+livable/U
+live/ATGDSB
+livelihood/SM
+liveliness/M
+livelong/S
+lively/PRT
+liven/SGD
+liver's
+liver/S
+liveried
+liverish
+liverwort/MS
+liverwurst/M
+livery/CSM
+liveryman/CM
+liverymen/C
+livestock/M
+liveware
+livid/Y
+living/MS
+lix/K
+lizard/MS
+ll
+llama/SM
+llano/SM
+lo
+load's
+load/AUGSD
+loadable
+loader/MS
+loading's
+loaf/MDRSZG
+loafer/M
+loam/M
+loamy/TR
+loan/MDRSZG
+loaner/M
+loansharking/M
+loanword/MS
+loath/JZGDRS
+loathe
+loather/M
+loathing/M
+loathsome/PY
+loathsomeness/M
+loaves
+lob/SMD
+lobar
+lobbed
+lobber/MS
+lobbing
+lobby/GDSM
+lobbyist/MS
+lobe/MS
+lobotomize/DSG
+lobotomy/SM
+lobster/MS
+local/SMY
+locale/MS
+locality/SM
+localization/M
+localize/DRSZG
+locate/AESDNGX
+location/EAM
+locator/MS
+locavore/SM
+loci
+lock/MDRSBZG
+locker/M
+locket/MS
+lockjaw/M
+lockout/MS
+locksmith/M
+locksmiths
+lockstep/M
+lockup/MS
+loco/S
+locomotion/M
+locomotive/MS
+locoweed/SM
+locum/S
+locus/M
+locust/SM
+locution/MS
+lode/MS
+lodestar/MS
+lodestone/MS
+lodge/DRSJMZG
+lodger/M
+lodging/M
+lodgings/M
+loft/MDSG
+loftily
+loftiness/M
+lofty/PRT
+log/SM
+loganberry/SM
+logarithm/SM
+logarithmic
+logbook/SM
+loge/MS
+logged
+logger/SM
+loggerhead/SM
+loggia/SM
+logging/M
+logic/M
+logical/Y
+logicality/M
+logician/MS
+login/SM
+logistic/S
+logistical/Y
+logistics/M
+logjam/SM
+logo/MS
+logoff/SM
+logon/SM
+logotype/SM
+logout/SM
+logrolling/M
+logy/RT
+loin/MS
+loincloth/M
+loincloths
+loiter/ZGSDR
+loiterer/M
+loitering/M
+lolcat/SM
+loll/DSG
+lollipop/SM
+lollop/GSD
+lolly/S
+lollygag/S
+lollygagged
+lollygagging
+lollypop/MS
+lone/YZR
+loneliness/M
+lonely/PTR
+loner/M
+lonesome/YP
+lonesomeness/M
+long's
+long/KDSTG
+longboat/MS
+longbow/MS
+longer
+longevity/M
+longhair/MS
+longhand/M
+longhorn/MS
+longhouse/S
+longing/MYS
+longish
+longitude/MS
+longitudinal/Y
+longshoreman/M
+longshoremen
+longsighted
+longstanding
+longtime
+longueur/SM
+longways
+loo
+loofah/M
+loofahs
+look/MDRSZG
+lookalike/MS
+looker/M
+lookout/MS
+lookup
+loom/MDSG
+loon/MS
+loonie/M
+loony/RSMT
+loop/MDSG
+loophole/MS
+loopy/RT
+loos/NRX
+loose/UDSTG
+loosely
+loosen/UGSD
+looseness/M
+loot/MDRSZG
+looter/M
+looting/M
+lop/S
+lope/MGDS
+lopped
+lopping
+lopsided/YP
+lopsidedness/M
+loquacious/PY
+loquaciousness/M
+loquacity/M
+lord/MDYSG
+lordliness/M
+lordly/TPR
+lordship/SM
+lore/M
+lorgnette/SM
+loris/MS
+lorn
+lorry/SM
+lose/ZGRSJ
+loser/M
+losing/M
+loss/MS
+lossless
+lost
+lot/SM
+lotion/SM
+lottery/SM
+lotto/M
+lotus/MS
+louche
+loud/RYTP
+loudhailer/SM
+loudmouth/MD
+loudmouths
+loudness/M
+loudspeaker/MS
+lough
+loughs
+lounge/MZGDRS
+lounger/M
+lour/DSG
+louse's
+louse/CDSG
+lousily
+lousiness/M
+lousy/TPR
+lout/MS
+loutish/PY
+louver/MDS
+lovableness/M
+lovably
+love/MYZGDRSB
+lovebird/SM
+lovechild/M
+loved/U
+loveless
+loveliness/M
+lovelorn
+lovely/RSMTP
+lovemaking/M
+lover/M
+loveseat/SM
+lovesick
+lovey/S
+loving/Y
+low/SZTGMDRYP
+lowborn
+lowboy/MS
+lowbrow/SM
+lowdown/M
+lower/GD
+lowercase/M
+lowermost
+lowish
+lowland/SZMR
+lowlander/M
+lowlife/SM
+lowliness/M
+lowly/TPR
+lowness/M
+lox/M
+loyal/ETY
+loyaler
+loyalism/M
+loyalist/SM
+loyalties
+loyalty/EM
+lozenge/SM
+ltd
+luau/MS
+lubber/MYS
+lube/MGDS
+lubricant/SM
+lubricate/DSGN
+lubrication/M
+lubricator/MS
+lubricious/Y
+lubricity/M
+lucid/PY
+lucidity/M
+lucidness/M
+luck/MDSG
+luckily/U
+luckiness/UM
+luckless
+lucky/UPTR
+lucrative/YP
+lucrativeness/M
+lucre/M
+lucubrate/GNDS
+lucubration/M
+ludicrous/YP
+ludicrousness/M
+ludo
+luff/DSG
+lug/SM
+luge/S
+luggage/M
+lugged
+lugger/MS
+lugging
+lughole/S
+lugsail/SM
+lugubrious/YP
+lugubriousness/M
+lukewarm/YP
+lukewarmness/M
+lull/MDSG
+lullaby/SM
+lulu/S
+lumbago/M
+lumbar
+lumber/MDRZGS
+lumberer/M
+lumbering/M
+lumberjack/SM
+lumberman/M
+lumbermen
+lumberyard/SM
+lumen/S
+lumina
+luminary/SM
+luminescence/M
+luminescent
+luminosity/M
+luminous/Y
+lummox/MS
+lump/MDNSG
+lumpectomy/S
+lumpenproletariat
+lumpiness/M
+lumpish
+lumpy/TRP
+lunacy/SM
+lunar
+lunatic/SM
+lunch/GMDS
+lunchbox/S
+luncheon/SM
+luncheonette/SM
+lunchroom/MS
+lunchtime/MS
+lung/MDSG
+lunge/SM
+lungfish/MS
+lungful/S
+lunkhead/MS
+lupine/MS
+lupus/M
+lurch/GMDS
+lure/MGDS
+lurgy
+lurid/PY
+luridness/M
+lurk/DRSZG
+luscious/PY
+lusciousness/M
+lush/MRSYPT
+lushness/M
+lust/MDRSG
+luster/M
+lusterless
+lustful/Y
+lustily
+lustiness/M
+lustrous/Y
+lusty/PTR
+lutanist/SM
+lute/MS
+lutenist/SM
+lutetium/M
+lux
+luxuriance/M
+luxuriant/Y
+luxuriate/DSGN
+luxuriation/M
+luxurious/PY
+luxuriousness/M
+luxury/SM
+lvi
+lvii
+lxi
+lxii
+lxiv
+lxix
+lxvi
+lxvii
+lyceum/MS
+lychee/MS
+lychgate/S
+lye/MG
+lying/M
+lymph/M
+lymphatic/SM
+lymphocyte/SM
+lymphoid
+lymphoma/SM
+lynch/JZGDRS
+lyncher/M
+lynching/M
+lynx/MS
+lyre/MS
+lyrebird/MS
+lyric/SM
+lyrical/Y
+lyricism/M
+lyricist/SM
+lysosomal
+lysosomes
+m/KAS
+mRNA
+ma'am
+ma/SMH
+mac/SGMD
+macOS/M
+macabre
+macadam/M
+macadamia/SM
+macadamize/GDS
+macaque/MS
+macaroni/MS
+macaroon/MS
+macaw/SM
+mace/MS
+macerate/DSGN
+maceration/M
+mach/M
+machete/SM
+machinate/GNDSX
+machination/M
+machine/DSMGB
+machinery/M
+machinist/MS
+machismo/M
+macho/M
+mack/MS
+mackerel/SM
+mackinaw/SM
+mackintosh/MS
+macrame/M
+macram辿/M
+macro/SM
+macrobiotic/S
+macrobiotics/M
+macrocosm/SM
+macroeconomic/S
+macroeconomics/M
+macrology/S
+macron/MS
+macrophages
+macroscopic
+macroscopically
+mad/SMYP
+madam/SM
+madame/M
+madcap/MS
+madden/DGS
+maddening/Y
+madder/MS
+maddest
+madding
+made/AU
+mademoiselle/MS
+madhouse/SM
+madman/M
+madmen
+madness/M
+madras/MS
+madrasa/SM
+madrasah/M
+madrasahs
+madrassa/SM
+madrigal/SM
+madwoman/M
+madwomen
+maelstrom/SM
+maestro/SM
+mafia/SM
+mafiosi
+mafioso/M
+mag/SM
+magazine/SM
+mage/MS
+magenta/M
+maggot/MS
+maggoty
+magi/M
+magic/SM
+magical/Y
+magician/SM
+magicked
+magicking
+magisterial/Y
+magistracy/M
+magistrate/SM
+magma/M
+magnanimity/M
+magnanimous/Y
+magnate/SM
+magnesia/M
+magnesium/M
+magnet/MS
+magnetic
+magnetically
+magnetism/M
+magnetite/M
+magnetizable
+magnetization/CM
+magnetize/CGDS
+magneto/SM
+magnetometer/SM
+magnetosphere
+magnification/M
+magnificence/M
+magnificent/Y
+magnifier/M
+magnify/ZGXDRSN
+magniloquence/M
+magniloquent
+magnitude/SM
+magnolia/MS
+magnon
+magnum/MS
+magpie/MS
+magus/M
+maharaja/SM
+maharajah/M
+maharajahs
+maharanee/MS
+maharani/SM
+maharishi/SM
+mahatma/SM
+mahjong/M
+mahogany/SM
+mahout/MS
+maid/MNSX
+maiden/MY
+maidenhair/M
+maidenhead/SM
+maidenhood/M
+maidservant/SM
+mail/JMDRSZG
+mailbag/SM
+mailbomb/GSD
+mailbox/MS
+mailer/M
+mailing/M
+maillot/SM
+mailman/M
+mailmen
+mailshot/S
+maim/DSG
+main/MYS
+mainframe/SM
+mainland/MS
+mainline/MGDS
+mainmast/MS
+mainsail/MS
+mainspring/MS
+mainstay/MS
+mainstream/SMDG
+maintain/ZGBDRS
+maintainability
+maintainable/U
+maintained/U
+maintenance/M
+maintop/SM
+maisonette/MS
+maize/SM
+majestic
+majestically
+majesty/SM
+majolica/M
+major/SGMDY
+majordomo/MS
+majorette/MS
+majoritarian/SM
+majoritarianism
+majority/SM
+make's/A
+make/UAGS
+makeover/MS
+maker/SM
+makeshift/SM
+makeup/MS
+makeweight/S
+making/MS
+makings/M
+malachite/M
+maladjusted
+maladjustment/M
+maladministration
+maladroit/PY
+maladroitness/M
+malady/SM
+malaise/M
+malamute/MS
+malapropism/SM
+malaria/M
+malarial
+malarkey/M
+malathion/M
+malcontent/MS
+male/MPS
+malediction/SM
+malefaction/M
+malefactor/SM
+malefic
+maleficence/M
+maleficent
+maleness/M
+malevolence/M
+malevolent/Y
+malfeasance/M
+malform/SD
+malformation/SM
+malfunction/MDSG
+malice/M
+malicious/PY
+maliciousness/M
+malign/DSG
+malignancy/SM
+malignant/Y
+malignity/M
+malinger/ZGSDR
+malingerer/M
+mall/MS
+mallard/SM
+malleability/M
+malleable
+mallet/MS
+mallow/MS
+malnourished
+malnutrition/M
+malocclusion/M
+malodorous
+malpractice/SM
+malt/MDSG
+malted/MS
+maltose/M
+maltreat/GLDS
+maltreatment/M
+malty/TR
+malware/SM
+mam/S
+mama/MS
+mamba/SM
+mambo/SGMD
+mamma/M
+mammal/MS
+mammalia
+mammalian/MS
+mammary
+mammogram/MS
+mammography/M
+mammon/M
+mammoth/M
+mammoths
+mammy/SM
+man's/F
+man/UFY
+manacle/DSMG
+manage/ZGDRSL
+manageability/M
+manageable/U
+management/MS
+manager/M
+manageress/S
+managerial
+manana/MS
+manatee/SM
+mandala/SM
+mandamus/MS
+mandarin/MS
+mandate/DSMG
+mandatory
+mandible/MS
+mandibular
+mandolin/MS
+mandrake/MS
+mandrel/SM
+mandrill/MS
+mane/MDS
+manege/M
+maneuver/MDGSBJ
+maneuverability/M
+manful/Y
+manga/M
+manganese/M
+mange/DRMZ
+manger/M
+mangetout/S
+manginess/M
+mangle/MZGDRS
+mango/M
+mangoes
+mangrove/MS
+mangy/TRP
+manhandle/GDS
+manhole/SM
+manhood/M
+manhunt/SM
+mania/SM
+maniac/MS
+maniacal/Y
+manic/SM
+manically
+manicure/MGDS
+manicurist/MS
+manifest/MDYSG
+manifestation/SM
+manifesto/SM
+manifold/GMDS
+manikin/SM
+manila/M
+manioc/MS
+manipulable
+manipulate/XGNVDS
+manipulation/M
+manipulative/Y
+manipulator/MS
+mankind/M
+manky
+manlike
+manliness/M
+manly/URT
+manna/M
+manned/U
+mannequin/SM
+manner/MDYS
+mannerism/SM
+mannerly/U
+manning/U
+mannish/YP
+mannishness/M
+manometer/SM
+manor/SM
+manorial
+manpower/M
+manque
+manqu辿
+mans
+mansard/MS
+manse/SXMN
+manservant/M
+mansion/M
+manslaughter/M
+manta/SM
+mantel/MS
+mantelpiece/SM
+mantelshelf
+mantelshelves
+mantes
+manticore
+mantilla/SM
+mantis/MS
+mantissa/SM
+mantle's
+mantle/EGDS
+mantra/MS
+manual/MYS
+manufacture/DRSMZG
+manufacturer/M
+manufacturing/M
+manumission/SM
+manumit/S
+manumitted
+manumitting
+manure/MGDS
+manuscript/MS
+many/M
+man竪ge/M
+map's
+map/AS
+maple/SM
+mapmaker/SM
+mapped/A
+mapper/MS
+mapping/S
+mar/S
+marabou/MS
+marabout/SM
+maraca/MS
+maraschino/MS
+marathon/SMRZ
+marathoner/M
+maraud/ZGDRS
+marauder/M
+marble/MGDS
+marbleize/GDS
+marbling/M
+march/ZGMDRS
+marcher/M
+marchioness/MS
+mare/MS
+margarine/M
+margarita/MS
+marge
+margin/MS
+marginal/YS
+marginalia/M
+marginalization/M
+marginalize/GDS
+maria/M
+mariachi/MS
+marigold/MS
+marijuana/M
+marimba/SM
+marina/MS
+marinade/DSMG
+marinara/M
+marinate/DSGN
+marination/M
+marine/MZRS
+mariner/M
+marionette/MS
+marital/Y
+maritime
+marjoram/M
+mark/AMDSG
+markdown/SM
+marked/U
+markedly
+marker/MS
+market/MDRZGBS
+marketability/M
+marketable/U
+marketeer/SM
+marketer/M
+marketing/M
+marketplace/SM
+marking/SM
+markka/M
+markkaa
+marksman/M
+marksmanship/M
+marksmen
+markup/MS
+marl/M
+marlin/MS
+marlinespike/SM
+marmalade/M
+marmoreal
+marmoset/SM
+marmot/MS
+maroon/MDGS
+marque/MS
+marquee/SM
+marquess/MS
+marquetry/M
+marquis/MS
+marquise/M
+marquisette/M
+marred/U
+marriage/ASM
+marriageability/M
+marriageable
+married/SM
+marring
+marrow/MS
+marry/AGDS
+marsh/MS
+marshal/SMDG
+marshland/SM
+marshmallow/SM
+marshy/RT
+marsupial/MS
+mart/MNSX
+marten/M
+martensite
+martial/Y
+martian/S
+martin/MS
+martinet/MS
+martingale/MS
+martini/SM
+martyr/MDGS
+martyrdom/M
+marvel/MDGS
+marvelous/Y
+marzipan/M
+masc
+mascara/GMDS
+mascot/MS
+masculine/SM
+masculinity/M
+maser/SM
+mash/MDRSZG
+masher/M
+mashup/MS
+mask's
+mask/UDSG
+masker/MS
+masochism/M
+masochist/SM
+masochistic
+masochistically
+mason/SM
+masonic
+masonry/M
+masque/MS
+masquerade/DRSMZG
+masquerader/M
+mass/MDSGV
+massacre/MGDS
+massage/DSMG
+masse
+masseur/SM
+masseuse/MS
+massif/MS
+massive/PY
+massiveness/M
+massless
+mast/MDS
+mastectomy/SM
+master's
+master/ADGS
+masterclass/S
+masterful/Y
+masterly
+mastermind/SGMD
+masterpiece/MS
+masterstroke/SM
+masterwork/MS
+mastery/M
+masthead/MS
+mastic/M
+masticate/GNDS
+mastication/M
+mastiff/SM
+mastitis
+mastodon/SM
+mastoid/SM
+masturbate/GNDS
+masturbation/M
+masturbatory
+mat/SZGMDR
+matador/SM
+match/AMS
+matchbook/SM
+matchbox/MS
+matched/U
+matching
+matchless
+matchlock/SM
+matchmaker/MS
+matchmaking/M
+matchstick/MS
+matchwood/M
+mate/MS
+material/SMY
+materialism/M
+materialist/SM
+materialistic
+materialistically
+materialization/M
+materialize/DSG
+materiel/M
+maternal/Y
+maternity/M
+matey/S
+mathematical/Y
+mathematician/SM
+mathematics/M
+matinee/SM
+mating/M
+matins/M
+matin辿e/SM
+matriarch/M
+matriarchal
+matriarchs
+matriarchy/SM
+matrices
+matricidal
+matricide/MS
+matriculate/DSGN
+matriculation/M
+matrimonial
+matrimony/M
+matrix/M
+matron/MYS
+matte/DRSMZG
+matter/MDG
+matting/M
+mattock/SM
+mattress/MS
+maturate/GNDS
+maturation/M
+mature/YTGDRS
+maturity/SM
+matzo/SMH
+matzoh/M
+matzohs
+matzot
+mat辿riel/M
+maudlin
+maul/MDRSZG
+mauler/M
+maunder/SDG
+mausoleum/SM
+mauve/M
+maven/SM
+maverick/SM
+maw/SM
+mawkish/PY
+mawkishness/M
+max/GMDS
+maxi/MS
+maxilla/M
+maxillae
+maxillary
+maxim/SM
+maxima
+maximal/Y
+maximalist/SM
+maximization/M
+maximize/GDS
+maximum/SM
+may/M
+maybe/SM
+mayday/MS
+mayflower/MS
+mayfly/SM
+mayhem/M
+mayn't
+mayo/M
+mayonnaise/M
+mayor/SM
+mayoral
+mayoralty/M
+mayoress/MS
+maypole/SM
+mayst
+maze/MS
+mazurka/MS
+ma単ana/M
+mdse
+me/DSH
+mea/S
+mead/M
+meadow/MS
+meadowlark/MS
+meager/PY
+meagerness/M
+meal/MS
+mealiness/M
+mealtime/SM
+mealy/TPR
+mealybug/SM
+mealymouthed
+mean/MRYJPSTG
+meander/SMDJG
+meanderings/M
+meanie/M
+meaning/M
+meaningful/PY
+meaningfulness/M
+meaningless/YP
+meaninglessness/M
+meanness/M
+meant/U
+meantime/M
+meanwhile/M
+meany/SM
+measles/M
+measly/RT
+measurably
+measure/LDRSBMG
+measured/U
+measureless
+measurement/MS
+meat/MS
+meatball/MS
+meathead/MS
+meatiness/M
+meatless
+meatloaf/M
+meatloaves
+meatpacking/M
+meaty/TPR
+mebibyte/SM
+mecca/SM
+mechanic/MS
+mechanical/Y
+mechanics/M
+mechanism/SM
+mechanistic
+mechanistically
+mechanization/M
+mechanize/DSG
+medal/SM
+medalist/MS
+medallion/SM
+meddle/ZGDRS
+meddler/M
+meddlesome
+media/SM
+medial/AY
+median/MS
+mediate/ADSGN
+mediated/U
+mediation/AM
+mediator/MS
+medic/SM
+medicaid/M
+medical/SMY
+medicament/M
+medicare/M
+medicate/GNXDS
+medication/M
+medicinal/Y
+medicine/MS
+medico/MS
+medieval
+medievalist/MS
+mediocre
+mediocrity/SM
+meditate/DSGNVX
+meditation/M
+meditative/Y
+medium/MS
+medley/MS
+medulla/SM
+medusa
+medusae
+meed/M
+meek/RYPT
+meekness/M
+meerkats
+meerschaum/SM
+meet/MJSG
+meeting/M
+meetinghouse/SM
+meetup/MS
+meg/S
+mega
+megabit/SM
+megabucks/M
+megabyte/MS
+megachurch/MS
+megacycle/SM
+megadeath/M
+megadeaths
+megagram/S
+megahertz/M
+megajoule/MS
+megalith/M
+megalithic
+megaliths
+megalomania/M
+megalomaniac/SM
+megalopolis/MS
+megameter/S
+megapascal/S
+megaphone/DSMG
+megapixel/SM
+megastar/S
+megaton/SM
+megawatt/MS
+meh
+meiosis/M
+meiotic
+melamine/M
+melancholia/M
+melancholic/S
+melancholy/M
+melange/MS
+melanin/M
+melanoma/SM
+meld/MDSG
+melee/SM
+meliorate/GNVDS
+melioration/M
+mellifluous/PY
+mellifluousness/M
+mellow/PTGDRYS
+mellowness/M
+melodic
+melodically
+melodious/YP
+melodiousness/M
+melodrama/MS
+melodramatic/S
+melodramatically
+melodramatics/M
+melody/SM
+melon/SM
+melt's
+melt/ADSG
+meltdown/SM
+member's
+member/EAS
+membership/SM
+membrane/SM
+membranous
+meme/MS
+memento/MS
+memo/MS
+memoir/MS
+memorabilia/M
+memorability/M
+memorable/U
+memorably
+memorandum/MS
+memorial/SM
+memorialize/DSG
+memorization/M
+memorize/DSG
+memory/SM
+memsahib/S
+men/M
+menace/MGDS
+menacing/Y
+menage/MS
+menagerie/MS
+mend/MDRSZG
+mendacious/Y
+mendacity/M
+mendelevium/M
+mender/M
+mendicancy/M
+mendicant/SM
+mending/M
+menfolk/MS
+menfolks/M
+menhaden/M
+menial/MYS
+meningeal
+meninges
+meningitis/M
+meninx/M
+menisci
+meniscus/M
+menopausal
+menopause/M
+menorah/M
+menorahs
+mensch/MS
+menservants
+menses/M
+menstrual
+menstruate/GNDS
+menstruation/M
+mensurable
+mensuration/M
+menswear/M
+mental/Y
+mentalist/SM
+mentality/SM
+menthol/M
+mentholated
+mention/GSMD
+mentioned/U
+mentor/MDSG
+mentorship
+menu/MS
+meow/MDSG
+mercantile
+mercantilism/M
+mercenary/SM
+mercer/MS
+mercerize/GDS
+merchandise/MZGDRS
+merchandiser/M
+merchandising/M
+merchant/GMBS
+merchantability
+merchantman/M
+merchantmen
+merciful/UY
+merciless/PY
+mercilessness/M
+mercurial/Y
+mercuric
+mercury/M
+mercy/SM
+mere/MYTS
+meretricious/YP
+meretriciousness/M
+merganser/MS
+merge/DRSZG
+merger/M
+meridian/MS
+meringue/MS
+merino/MS
+merit/CSM
+merited/U
+meriting
+meritless
+meritocracy/SM
+meritocratic
+meritorious/PY
+meritoriousness/M
+mermaid/SM
+merman/M
+mermen
+merrily
+merriment/M
+merriness/M
+merry/TRP
+merrymaker/MS
+merrymaking/M
+mesa/MS
+mescal/MS
+mescalin
+mescaline/M
+mesdames
+mesdemoiselles
+mesh/MDSG
+mesmeric
+mesmerism/M
+mesmerize/ZGDRS
+mesmerizer/M
+mesomorph/M
+mesomorphs
+meson/SM
+mesosphere/SM
+mesothelioma/M
+mesquite/SM
+mess/MDSG
+message/MGDS
+messeigneurs
+messenger/SM
+messiah/M
+messiahs
+messianic
+messieurs
+messily
+messiness/M
+messmate/SM
+messy/PTR
+mestizo/MS
+met
+meta
+metabolic
+metabolically
+metabolism/SM
+metabolite/SM
+metabolize/DSG
+metacarpal/SM
+metacarpi
+metacarpus/M
+metadata/M
+metal/SMD
+metalanguage/MS
+metallic
+metallurgic
+metallurgical
+metallurgist/MS
+metallurgy/M
+metalwork/MRZG
+metalworker/M
+metalworking/M
+metamorphic
+metamorphism/M
+metamorphose/GDS
+metamorphosis/M
+metaphor/MS
+metaphoric
+metaphorical/Y
+metaphysical/Y
+metaphysics/M
+metastases
+metastasis/M
+metastasize/DSG
+metastatic
+metatarsal/MS
+metatarsi
+metatarsus/M
+metatheses
+metathesis/M
+mete/MZGDRS
+metempsychoses
+metempsychosis/M
+meteor/MS
+meteoric
+meteorically
+meteorite/SM
+meteoroid/SM
+meteorologic
+meteorological
+meteorologist/SM
+meteorology/M
+meter/GMD
+metformin
+methadone/M
+methamphetamine/M
+methane/M
+methanol/M
+methinks
+method/MS
+methodical/YP
+methodicalness/M
+methodological/Y
+methodology/SM
+methotrexate
+methought
+methoxy
+meths
+methyl/M
+meticulous/YP
+meticulousness/M
+metier/MS
+metric/S
+metrical/Y
+metricate/GNDS
+metrication/M
+metricize/GDS
+metro/SM
+metronome/MS
+metropolis/MS
+metropolitan
+mettle/M
+mettlesome
+mew/SGMD
+mewl/DSG
+mews/M
+mezzanine/MS
+mezzo/SM
+mfg
+mfr/S
+mg
+mgr
+mi/MNX
+miasma/MS
+mic/S
+mica/M
+mice
+mick/S
+mickey/MS
+micro/SM
+microaggression/SM
+microbe/MS
+microbial
+microbiological
+microbiologist/MS
+microbiology/M
+microbrewery/SM
+microchip/MS
+microcircuit/SM
+microcode
+microcomputer/MS
+microcosm/MS
+microcosmic
+microcredit
+microdot/SM
+microeconomics/M
+microelectronic/S
+microelectronics/M
+microfiber/MS
+microfiche/M
+microfilm/GMDS
+microfinance
+microfloppies
+microgram
+microgroove/SM
+microlight/MS
+microloan/MS
+micromanage/ZGDRSL
+micromanagement/M
+micromanager/M
+micrometeorite/SM
+micrometer/MS
+micron/MS
+microorganism/MS
+micropayment/S
+microphone/SM
+microplastics
+microprocessor/MS
+microscope/SM
+microscopic
+microscopical/Y
+microscopy/M
+microsecond/MS
+microsurgery/M
+microwave/DSMGB
+microwaveable
+mid
+midair/M
+midday/M
+midden/MS
+middle/MGS
+middlebrow/SM
+middleman/M
+middlemen
+middlemost
+middleweight/MS
+middy/SM
+midfield/RZ
+midge/SM
+midget/MS
+midi/MS
+midland/MS
+midlife/M
+midmost
+midnight/M
+midpoint/MS
+midrib/MS
+midriff/MS
+midsection/MS
+midshipman/M
+midshipmen
+midships
+midsize
+midst/M
+midstream/M
+midsummer/M
+midterm/MS
+midtown/M
+midway/MS
+midweek/MS
+midwife/MGDS
+midwifery/SM
+midwinter/M
+midwived
+midwives
+midwiving
+midyear/MS
+mien/M
+miff/DSG
+might've
+might/M
+mightily
+mightiness/M
+mightn't
+mighty/TRP
+mignonette/SM
+migraine/MS
+migrant/MS
+migrate/AGDS
+migration/SM
+migrator/MS
+migratory
+mikado/MS
+mike/MGDS
+mil/SZMR
+milady/SM
+milch
+mild/MRYTP
+mildew/SMDG
+mildness/M
+mile/MS
+mileage/SM
+milepost/MS
+miler/M
+milestone/MS
+milf/MS
+milieu/SM
+militancy/M
+militant/MYS
+militarily
+militarism/M
+militarist/SM
+militaristic
+militarization/CM
+militarize/CDSG
+military/M
+militate/GDS
+militia/SM
+militiaman/M
+militiamen
+milk/MDRSZG
+milker/M
+milkiness/M
+milkmaid/MS
+milkman/M
+milkmen
+milkshake/SM
+milksop/MS
+milkweed/SM
+milky/RTP
+mill/MDRSZGJ
+millage/M
+millennia
+millennial/MS
+millennium/MS
+miller/M
+millet/M
+milliard/MS
+millibar/MS
+milligram/MS
+milliliter/MS
+millimeter/MS
+milliner/MS
+millinery/M
+milling/M
+million/HSM
+millionaire/SM
+millionairess/S
+millionth/M
+millionths
+millipede/SM
+millisecond/SM
+millisievert/S
+millpond/SM
+millrace/SM
+millstone/SM
+millstream/MS
+millwright/SM
+milometer/S
+milquetoast/SM
+milt/MDSG
+mime/MGDS
+mimeograph/GMD
+mimeographs
+mimetic
+mimic/SM
+mimicked
+mimicker/SM
+mimicking
+mimicry/SM
+mimosa/SM
+min/S
+minaret/MS
+minatory
+mince/DRSMZG
+mincemeat/M
+mincer/M
+mind's
+mind/ADRSZG
+mindbogglingly
+minded/P
+mindful/YP
+mindfulness/M
+mindless/YP
+mindlessness/M
+mindset/MS
+mine/MZGNDRSX
+minefield/SM
+miner/M
+mineral/MS
+mineralogical
+mineralogist/MS
+mineralogy/M
+minestrone/M
+minesweeper/SM
+mingle/DSG
+mingy
+mini/MS
+miniature/MS
+miniaturist/MS
+miniaturization/M
+miniaturize/GDS
+minibar/S
+minibike/SM
+minibus/MS
+minicab/S
+minicam/MS
+minicomputer/SM
+minifloppies
+minim/SM
+minima
+minimal/Y
+minimalism/M
+minimalist/MS
+minimization/M
+minimize/DSG
+minimum/MS
+mining/M
+minion/M
+miniseries/M
+miniskirt/MS
+minister/SGMD
+ministerial
+ministrant/MS
+ministration/MS
+ministry/SM
+minivan/MS
+mink/MS
+minnesinger/MS
+minnow/SM
+minor/SMDG
+minority/SM
+minoxidil/M
+minster/MS
+minstrel/SM
+minstrelsy/M
+mint/MDRSZG
+mintage/M
+minter/M
+minty/RT
+minuend/MS
+minuet/SM
+minus/MS
+minuscule/MS
+minute/PDRSMYTG
+minuteman/M
+minutemen
+minuteness/M
+minutia/M
+minutiae
+minx/MS
+miracle/MS
+miraculous/Y
+mirage/SM
+mire/MGDS
+mirror/GSMD
+mirth/M
+mirthful/PY
+mirthfulness/M
+mirthless/Y
+miry/RT
+misaddress/DSG
+misadventure/MS
+misaligned
+misalignment/M
+misalliance/MS
+misandrist/MS
+misandry
+misanthrope/SM
+misanthropic
+misanthropically
+misanthropist/MS
+misanthropy/M
+misapplication/M
+misapply/DSGNX
+misapprehend/GSD
+misapprehension/MS
+misappropriate/XDSGN
+misappropriation/M
+misbegotten
+misbehave/GDS
+misbehavior/M
+misc
+miscalculate/DSXGN
+miscalculation/M
+miscall/DSG
+miscarriage/MS
+miscarry/GDS
+miscast/SG
+miscegenation/M
+miscellanea
+miscellaneous/Y
+miscellany/SM
+mischance/SM
+mischaracterization/S
+mischaracterize/GD
+mischief/M
+mischievous/YP
+mischievousness/M
+miscibility/M
+miscible
+misclassify/DGXN
+miscommunication/S
+misconceive/GDS
+misconception/SM
+misconduct/MDGS
+misconfiguration
+misconstruction/MS
+misconstrue/GDS
+miscount/MDSG
+miscreant/SM
+miscue/DSMG
+misdeal/GMS
+misdealt
+misdeed/MS
+misdemeanor/MS
+misdiagnose/GDS
+misdiagnosis/M
+misdid
+misdirect/SDG
+misdirection/M
+misdo/JG
+misdoes
+misdoing/M
+misdone
+mise/CKS
+miser/SBMY
+miserableness/M
+miserably
+miserliness/M
+misery/SM
+misfeasance/M
+misfeature/S
+misfile/GDS
+misfire/MGDS
+misfit/SM
+misfitted
+misfitting
+misfortune/SM
+misgender/SDG
+misgiving/MS
+misgovern/SDGL
+misgovernment/M
+misguidance/M
+misguide/DSG
+misguided/Y
+mishandle/DSG
+mishap/SM
+mishear/GS
+misheard
+mishit/S
+mishitting
+mishmash/MS
+misidentify/GDS
+misinform/DGS
+misinformation/M
+misinterpret/SGD
+misinterpretation/SM
+misjudge/LDSG
+misjudgement/SM
+misjudgment/SM
+mislabel/GSD
+mislaid
+mislay/GS
+mislead/GS
+misleading/Y
+misled
+mismanage/LGDS
+mismanagement/M
+mismatch/GMDS
+misname/GDS
+misnomer/MS
+misogamist/MS
+misogamy/M
+misogynist/SM
+misogynistic
+misogynous
+misogyny/M
+misplace/GLDS
+misplacement/M
+misplay/GMDS
+misprint/GMDS
+misprision/M
+mispronounce/DSG
+mispronunciation/SM
+misquotation/MS
+misquote/MGDS
+misread/GJS
+misreading/M
+misremember/GDS
+misreport/MDGS
+misrepresent/GDS
+misrepresentation/MS
+misrule/MGDS
+miss's
+miss/EDSGV
+missal/ESM
+missed/U
+misshape/GDS
+misshapen
+missile/MS
+missileer
+missilery/M
+mission/AMS
+missionary/SM
+missioner/SM
+missis/MS
+missive/MS
+misspeak/GS
+misspell/GDJS
+misspelling/M
+misspend/GS
+misspent
+misspoke
+misspoken
+misstate/GDSL
+misstatement/SM
+misstep/MS
+missus/MS
+mist's
+mist/CDRSZG
+mistakable/U
+mistake/BMGS
+mistaken/Y
+mister's
+mistily
+mistime/GDS
+mistiness/M
+mistletoe/M
+mistook
+mistral/MS
+mistranslated
+mistreat/LDGS
+mistreatment/M
+mistress/MS
+mistrial/MS
+mistrust/MDSG
+mistrustful/Y
+misty/PRT
+mistype/GDS
+misunderstand/SGJ
+misunderstanding/M
+misunderstood
+misuse/DSMG
+mite/MZRS
+miter/MDG
+mitigable
+mitigate/XDSGN
+mitigated/U
+mitigation/M
+mitochondria
+mitochondrial
+mitochondrion
+mitoses
+mitosis/M
+mitotic
+mitral
+mitt/MNSX
+mitten/M
+mitzvah
+mix/ZGMDRSB
+mixed/U
+mixer/M
+mixture/SM
+mizzen/MS
+mizzenmast/SM
+mkay
+mks
+ml
+mm
+mnemonic/MS
+mnemonically
+mo/CKHS
+moan/MDRSZG
+moaner/M
+moat/MDS
+mob's
+mob/CS
+mobbed/C
+mobbing/C
+mobile/MS
+mobility/M
+mobilization/CM
+mobilizations
+mobilize/CDSG
+mobilizer/SM
+mobster/SM
+moccasin/SM
+mocha/SM
+mock/DRSZG
+mocker/M
+mockery/SM
+mocking/Y
+mockingbird/SM
+mocktail/S
+mockumentary/S
+mod/STM
+modal/SM
+modality/S
+modded
+modding
+mode/MS
+model/ZGSJMDR
+modeler/M
+modeling/M
+modeller/MS
+modelling/MS
+modem/SM
+moderate/MYGNPDS
+moderateness/M
+moderation/M
+moderator/SM
+modern/MYPS
+modernism/M
+modernist/SM
+modernistic
+modernity/M
+modernization/M
+modernize/DRSZG
+modernizer/M
+modernness/M
+modest/Y
+modesty/M
+modicum/SM
+modifiable
+modification/M
+modified/U
+modifier/M
+modify/DRSXZGN
+modish/YP
+modishness/M
+modular
+modularization
+modulate/CGNDS
+modulation/CM
+modulations
+modulator/MS
+module/MS
+modulo
+modulus
+moggy
+mogul/SM
+mohair/M
+moi
+moiety/SM
+moil/MDSG
+moire/SM
+moist/XTPNRY
+moisten/DRZG
+moistener/M
+moistness/M
+moisture/M
+moisturize/ZGDRS
+moisturizer/M
+mojo/S
+molar/SM
+molasses/M
+mold/MDRJSZG
+moldboard/SM
+molder/GMD
+moldiness/M
+molding/M
+moldy/TPR
+mole/MS
+molecular
+molecularity/M
+molecule/SM
+molehill/SM
+moleskin/M
+molest/DRZGS
+molestation/M
+molested/U
+molester/M
+moll/MS
+mollification/M
+mollify/DSNG
+mollusc/SM
+molluscan/SM
+mollusk/SM
+molluskan/S
+molly/SM
+mollycoddle/DSMG
+molt/MDNRSZG
+molter/M
+molybdenum/M
+mom/SM
+moment/MS
+momenta
+momentarily
+momentariness/M
+momentary/P
+momentous/PY
+momentousness/M
+momentum/M
+mommy/SM
+monad
+monarch/M
+monarchic
+monarchical
+monarchism/M
+monarchist/MS
+monarchistic
+monarchs
+monarchy/SM
+monastery/SM
+monastic/MS
+monastical/Y
+monasticism/M
+monaural
+monetarily
+monetarism/M
+monetarist/MS
+monetary
+monetization/C
+monetize/CGDS
+money/SMD
+moneybag/MS
+moneybox/S
+moneygrubber/SM
+moneygrubbing/M
+moneylender/SM
+moneymaker/SM
+moneymaking/M
+monger/MDGS
+mongol/S
+mongolism/M
+mongoloid/MS
+mongoose/MS
+mongrel/SM
+monied
+monies
+moniker/SM
+monism/M
+monist/MS
+monition/SM
+monitor/SMDG
+monitory
+monk/MS
+monkey/MDGS
+monkeyshine/SM
+monkish
+monkshood/SM
+mono/M
+monochromatic
+monochrome/MS
+monocle/DSM
+monoclonal
+monocotyledon/SM
+monocotyledonous
+monocular
+monodic
+monodist/SM
+monody/SM
+monofilament
+monogamist/MS
+monogamous/Y
+monogamy/M
+monogram/SM
+monogrammed
+monogramming
+monograph/M
+monographs
+monolingual/MS
+monolith/M
+monolithic
+monoliths
+monologist/SM
+monologue/SM
+monologuist/SM
+monomania/M
+monomaniac/MS
+monomaniacal
+monomer/SM
+monomial
+mononucleosis/M
+monophonic
+monoplane/SM
+monopolist/SM
+monopolistic
+monopolization/M
+monopolize/DRSZG
+monopolizer/M
+monopoly/SM
+monorail/MS
+monosyllabic
+monosyllable/MS
+monotheism/M
+monotheist/SM
+monotheistic
+monotone/MS
+monotonic
+monotonically
+monotonous/PY
+monotonousness/M
+monotony/M
+monounsaturated
+monoxide/MS
+monozygotic
+monozygous
+monseigneur/M
+monsieur/M
+monsignor/SM
+monsoon/SM
+monsoonal
+monster/SM
+monstrance/ASM
+monstrosity/SM
+monstrous/Y
+montage/SM
+month/MY
+monthly/SM
+months
+monument/MS
+monumental/Y
+moo/SGMD
+mooch/ZGMDRS
+moocher/M
+mood/MS
+moodily
+moodiness/M
+moody/TPR
+moon/MDSG
+moonbeam/MS
+moonless
+moonlight/SMDRZG
+moonlighter/M
+moonlighting/M
+moonlit
+moonscape/SM
+moonshine/MZRS
+moonshiner/M
+moonshot/MS
+moonstone/MS
+moonstruck
+moonwalk/MS
+moor/MDJSG
+moorhen/S
+mooring/M
+moorland/MS
+moose/M
+moot/DSG
+mop/SZGMDR
+mope/MS
+moped/SM
+moper/M
+mopey
+mopier
+mopiest
+mopish
+mopped
+moppet/MS
+mopping
+moraine/SM
+moral/SMY
+morale/M
+moralism
+moralist/MS
+moralistic
+moralistically
+moralities
+morality/UM
+moralization/CM
+moralize/CGDS
+moralizer/MS
+morass/MS
+moratorium/SM
+moray/SM
+morbid/YP
+morbidity/M
+morbidness/M
+mordancy/M
+mordant/SMY
+more/MS
+moreish
+morel/SM
+moreover
+mores/M
+morgue/MS
+moribund
+morn/MJSG
+morning/M
+morocco/M
+moron/SM
+moronic
+moronically
+morose/YP
+moroseness/M
+morph/GD
+morpheme/MS
+morphemic
+morphia/M
+morphine/M
+morphing/M
+morphological
+morphology/M
+morphs
+morrow/MS
+morsel/MS
+mortal/MYS
+mortality/M
+mortar/MDSG
+mortarboard/SM
+mortgage's
+mortgage/AGDS
+mortgagee/MS
+mortgagor/MS
+mortician/MS
+mortification/M
+mortify/NGDS
+mortise/DSMG
+mortuary/SM
+mosaic/MS
+mosey/SGD
+mosh/DSG
+mosque/MS
+mosquito/SM
+mosquitoes
+moss/MS
+mossback/SM
+mossy/TR
+most/MY
+mot/SM
+mote's
+mote/KCXSVN
+motel/SM
+motet/SM
+moth/M
+mothball/GMDS
+mother/MDYSG
+motherboard/SM
+motherfucker/MS!
+motherfucking/!
+motherhood/M
+motherland/MS
+motherless
+motherliness/M
+moths
+motif/SM
+motile/S
+motility/M
+motion/KCM
+motioned
+motioning
+motionless/YP
+motionlessness/M
+motivate/CDSG
+motivated/U
+motivation/SM
+motivational
+motivator/SM
+motive/MS
+motiveless
+motley/MS
+motlier
+motliest
+motocross/MS
+motor/SGMD
+motorbike/MGDS
+motorboat/MS
+motorcade/MS
+motorcar/SM
+motorcycle/DSMG
+motorcyclist/MS
+motorist/SM
+motorization/M
+motorize/DSG
+motorman/M
+motormen
+motormouth/M
+motormouths
+motorsport/SM
+motorway/SM
+mottle/GDS
+motto/M
+mottoes
+moue/MS
+mound/SGMD
+mount/EASGMD
+mountable
+mountain/SM
+mountaineer/SMDG
+mountaineering/M
+mountainous
+mountainside/SM
+mountaintop/SM
+mountebank/MS
+mounted/U
+mounter/MS
+mounting/SM
+mourn/SZGDR
+mourned/U
+mourner/M
+mournful/YP
+mournfulness/M
+mourning/M
+mouse/DRSMZG
+mouser/M
+mousetrap/SM
+mousetrapped
+mousetrapping
+mousey
+mousiness/M
+moussaka/S
+mousse/MGDS
+mousy/PTR
+mouth/GMD
+mouthfeel
+mouthful/MS
+mouthiness/M
+mouthpiece/MS
+mouths
+mouthwash/MS
+mouthwatering
+mouthy/PTR
+mouton/M
+movable/SM
+movant
+move/AMZGDRSB
+moveable/SM
+moved/U
+movement/SM
+movent
+mover/AM
+movie/SM
+moviegoer/SM
+moving/Y
+mow/SZGMDR
+mower/M
+moxie/M
+mozzarella/M
+mp
+mpg
+mph
+mt
+mtg
+mtge
+mu/SM
+much/M
+mucilage/M
+mucilaginous
+muck/MDSG
+muckrake/DRSZG
+muckraker/M
+mucky/TR
+mucous
+mucus/M
+mud/M
+muddily
+muddiness/M
+muddle/MGDS
+muddleheaded
+muddy/PTGDRS
+mudflap/S
+mudflat/MS
+mudguard/SM
+mudpack/S
+mudroom/MS
+mudslide/MS
+mudslinger/SM
+mudslinging/M
+muenster/M
+muesli
+muezzin/MS
+muff/MDSG
+muffin/MS
+muffle/ZGDRS
+muffler/M
+mufti/SM
+mug/SM
+mugful/MS
+mugged
+mugger/MS
+mugginess/M
+mugging/MS
+muggins
+muggle/MS
+muggy/PTR
+mugshot/MS
+mugwump/MS
+mujaheddin
+mujahedin/M
+mukluk/MS
+mulatto/M
+mulattoes
+mulberry/SM
+mulch/GMDS
+mulct/SGMD
+mule/MS
+muleskinner/MS
+muleteer/MS
+mulish/PY
+mulishness/M
+mull/DSG
+mullah/M
+mullahs
+mullein/M
+mullet/MS
+mulligan/SM
+mulligatawny/M
+mullion/SMD
+multi
+multicast
+multicellular
+multichannel
+multicolored
+multicultural
+multiculturalism/M
+multidimensional
+multidisciplinary
+multifaceted
+multifamily
+multifarious/PY
+multifariousness/M
+multiform
+multigrain
+multilateral/Y
+multilayered
+multilevel
+multilingual
+multilingualism/M
+multimedia/M
+multimillionaire/SM
+multinational/SM
+multipart
+multiparty
+multiplayer/M
+multiple/MS
+multiplex/ZGMDRS
+multiplexer/M
+multiplicand/MS
+multiplication/M
+multiplicative
+multiplicity/SM
+multiplier/M
+multiply/NZGDRSX
+multiprocessing
+multiprocessor/SM
+multipurpose
+multiracial
+multistage
+multistory
+multitask/GS
+multitasking/M
+multitude/SM
+multitudinous
+multivariable
+multivariate
+multiverse/SM
+multivitamin/MS
+multiyear
+mum
+mumble/MZGDRS
+mumbler/M
+mumbletypeg/M
+mummer/MS
+mummery/M
+mummification/M
+mummify/GNDS
+mummy/SM
+mumps/M
+mun
+munch/GDS
+munchie/S
+munchies/M
+munchkin/SM
+mundane/SY
+mung/DSG
+municipal/SMY
+municipality/SM
+munificence/M
+munificent/Y
+munition/MDGS
+mural/SM
+muralist/SM
+murder/ZGMDRS
+murderer/M
+murderess/MS
+murderous/Y
+murine
+murk/MS
+murkily
+murkiness/M
+murky/PTR
+murmur/ZGJMDRS
+murmurer/M
+murmuring/M
+murmurous
+murrain/M
+muscat/MS
+muscatel/SM
+muscle/MGDS
+musclebound
+muscleman
+musclemen
+muscly
+muscular/Y
+muscularity/M
+musculature/M
+musculoskeletal
+musculus
+muse/MGDSJ
+musette/MS
+museum/MS
+mush/MDRSZG
+mushiness/M
+mushroom/GSMD
+mushy/PTR
+music/SM
+musical/MYS
+musicale/MS
+musicality/M
+musician/SMY
+musicianship/M
+musicological
+musicologist/MS
+musicology/M
+musing/MY
+musk/M
+muskeg/MS
+muskellunge/MS
+musket/MS
+musketeer/MS
+musketry/M
+muskie/M
+muskiness/M
+muskmelon/SM
+muskox/MN
+muskrat/MS
+musky/PTRS
+muslin/M
+muss/MDSG
+mussel/MS
+mussy/TR
+must've
+must/MRSZ
+mustache/MDS
+mustachio/SMD
+mustang/MS
+mustard/M
+muster/GMD
+mustily
+mustiness/M
+mustn't
+musty/PTR
+mutability/M
+mutably
+mutagen/MS
+mutagenic
+mutant/MS
+mutate/XGNVDS
+mutation/M
+mutational
+mute/MYTGDRSPB
+muteness/M
+mutilate/DSGNX
+mutilation/M
+mutilator/SM
+mutineer/SM
+mutinous/Y
+mutiny/GDSM
+mutt/MS
+mutter/ZGJMDRS
+mutterer/M
+muttering/M
+mutton/M
+muttonchops/M
+muttony
+mutual/Y
+mutuality/M
+muumuu/MS
+muzak
+muzzily
+muzzle/DSMG
+muzzy/P
+my
+mycologist/SM
+mycology/M
+myelitis/M
+myna/MS
+mynah/MS
+myocardial
+myocardium
+myopia/M
+myopic
+myopically
+myriad/SM
+myrmidon/MS
+myrrh/M
+myrtle/SM
+mys
+myself
+mysterious/PY
+mysteriousness/M
+mystery/SM
+mystic/SM
+mystical/Y
+mysticism/M
+mystification/CM
+mystify/CDSGN
+mystique/M
+myth/M
+mythic
+mythical
+mythological
+mythologist/SM
+mythologize/DSG
+mythology/SM
+myths
+myxomatosis
+m辿tier/MS
+m棚l辿e/MS
+n/IKTH
+naan/S
+nab/S
+nabbed
+nabbing
+nabob/SM
+nacelle/SM
+nacho/SM
+nacre/M
+nacreous
+nadir/SM
+nae
+naff/RT
+nag/SM
+nagged
+nagger/MS
+nagging
+nagware
+nah
+naiad/SM
+naif/MS
+nail/MDSG
+nailbrush/MS
+naive/RYT
+naivete/M
+naivety/M
+naivet辿/M
+naked/PY
+nakedness/M
+name's
+name/AGDS
+nameable/U
+named/U
+nameless/Y
+namely
+nameplate/MS
+namesake/SM
+namespace/SM
+nanny/SM
+nano
+nanobot/S
+nanometer/S
+nanosecond/SM
+nanotechnology/SM
+nanotube
+nap/SM
+napalm/MDSG
+nape/MS
+naphtha/M
+naphthalene/M
+napkin/MS
+napless
+napoleon/SM
+napped
+napper/MS
+napping
+nappy/TRSM
+narc/MS
+narcissism/M
+narcissist/MS
+narcissistic
+narcissus/M
+narcolepsy/M
+narcoleptic
+narcoses
+narcosis/M
+narcotic/SM
+narcotization/M
+narcotize/GDS
+nark
+narky
+narrate/GNVDSX
+narration/M
+narrative/SM
+narrator/SM
+narrow/PTGMDRYS
+narrowness/M
+narwhal/MS
+nary
+nasal/SMY
+nasality/M
+nasalization/M
+nasalize/DSG
+nascence/AM
+nascent/A
+nastily
+nastiness/M
+nasturtium/SM
+nasty/PTR
+natal
+natch
+nation/MS
+national/MYS
+nationalism/M
+nationalist/SM
+nationalistic
+nationalistically
+nationality/SM
+nationalization/MS
+nationalize/CDSG
+nationhood/M
+nationwide
+native/MYS
+nativity/SM
+natl
+natter/GMDS
+nattily
+nattiness/M
+natty/PTR
+natural's
+natural/UPY
+naturalism/M
+naturalist/SM
+naturalistic
+naturalization/M
+naturalize/DSG
+naturalness/UM
+naturals
+nature's
+nature/CS
+naturism
+naturist/S
+naught/MS
+naughtily
+naughtiness/M
+naughty/PTR
+nausea/M
+nauseam
+nauseate/GDS
+nauseating/Y
+nauseous/PY
+nauseousness/M
+nautical/Y
+nautilus/MS
+naval
+nave/MS
+navel/SM
+navigability/M
+navigable
+navigate/DSGN
+navigation/M
+navigational
+navigator/MS
+navvy/S
+navy/SM
+nay/SM
+naysayer/MS
+na誰ve/RYT
+na誰vety/M
+na誰vet辿/M
+ne'er
+neanderthal/MS
+neap/MS
+near/DRYSPTG
+nearby
+nearness/M
+nearshore
+nearside
+nearsighted/YP
+nearsightedness/M
+neat/NRYPXT
+neaten/GD
+neath
+neatness/M
+neato
+nebula/M
+nebulae
+nebular
+nebulous/PY
+nebulousness/M
+necessarily/U
+necessary/SM
+necessitate/DSG
+necessitous
+necessity/SM
+neck/MDSG
+neckband/S
+neckerchief/MS
+necking/M
+necklace/MGDSJ
+neckline/MS
+necktie/MS
+necrology/M
+necromancer/SM
+necromancy/M
+necrophilia
+necrophiliac/S
+necropolis/MS
+necroses
+necrosis/M
+necrotic
+nectar/M
+nectarine/MS
+nee
+need/MDSG
+needed/U
+needful/Y
+neediness/M
+needle/MGDS
+needlepoint/M
+needless/YP
+needlessness/M
+needlewoman/M
+needlewomen
+needlework/M
+needn't
+needy/PTR
+nefarious/YP
+nefariousness/M
+neg
+negate/DSGNVX
+negation/M
+negative/MYGPDS
+negativeness/M
+negativism/M
+negativity/M
+neglect/SGMD
+neglectful/YP
+neglectfulness/M
+negligee/MS
+negligence/M
+negligent/Y
+negligible
+negligibly
+negotiability/M
+negotiable/A
+negotiate/ADSGN
+negotiation/AM
+negotiations
+negotiator/MS
+negritude/M
+negro
+negroid
+neigh/MDG
+neighbor/SMDYG
+neighborhood/SM
+neighborliness/M
+neighs
+neither
+nelson/SM
+nematode/SM
+nemeses
+nemesis/M
+neoadjuvant
+neoclassic
+neoclassical
+neoclassicism/M
+neocolonialism/M
+neocolonialist/MS
+neocon/SM
+neoconservative/SM
+neocortex
+neodymium/M
+neolithic
+neologism/SM
+neon/M
+neonatal
+neonate/MS
+neophilia
+neophyte/MS
+neoplasm/MS
+neoplastic
+neoprene/M
+nepenthe/M
+nephew/SM
+nephrite/M
+nephritic
+nephritis/M
+nephropathy
+nepotism/M
+nepotist/SM
+nepotistic
+neptunium/M
+nerd/MS
+nerdy/RT
+nerve's
+nerve/UDSG
+nerveless/YP
+nervelessness/M
+nerviness/M
+nervous/YP
+nervousness/M
+nervy/TPR
+nest/MDSG
+nestle/GJDS
+nestling/M
+net/SM
+netball
+netbook/MS
+nether
+nethermost
+netherworld/M
+netiquette/S
+netted
+netter/S
+netting/M
+nettle/MGDS
+nettlesome
+network/SGMD
+networking/M
+neural/Y
+neuralgia/M
+neuralgic
+neurasthenia/M
+neurasthenic/MS
+neuritic/MS
+neuritis/M
+neurocysticercoses
+neurocysticercosis
+neurological/Y
+neurologist/SM
+neurology/M
+neuron/MS
+neuronal
+neurophysiology's
+neuroscience/MS
+neuroscientist/MS
+neuroses
+neurosis/M
+neurosurgeon/MS
+neurosurgery/M
+neurosurgical
+neurotic/MS
+neurotically
+neuroticism
+neurotoxin/S
+neurotransmitter/SM
+neut
+neuter/MDGS
+neutral/SMY
+neutralism/M
+neutralist/SM
+neutrality/M
+neutralization/M
+neutralize/DRSZG
+neutralizer/M
+neutrino/SM
+neutron/SM
+never
+nevermore
+nevertheless
+nevi
+nevus/M
+new/STMRYP
+newbie/MS
+newborn/SM
+newcomer/SM
+newel/SM
+newfangled
+newfound
+newish
+newline/S
+newlywed/SM
+newness/M
+news/M
+newsagent/S
+newsboy/SM
+newscast/SMRZ
+newscaster/M
+newsdealer/SM
+newsflash/S
+newsgirl/SM
+newsgroup/MS
+newshound/S
+newsletter/MS
+newsman/M
+newsmen
+newspaper/MS
+newspaperman/M
+newspapermen
+newspaperwoman/M
+newspaperwomen
+newspeak
+newsprint/M
+newsreader/S
+newsreel/MS
+newsroom/MS
+newsstand/SM
+newsweekly/SM
+newswires
+newswoman/M
+newswomen
+newsworthiness/M
+newsworthy/P
+newsy/TR
+newt/MS
+newton/MS
+next/M
+nexus/MS
+niacin/M
+nib/SM
+nibble/MZGDRS
+nibbler/M
+nice/PYTR
+niceness/M
+nicety/SM
+niche/SM
+nick/MDRSZG
+nickel/MS
+nickelodeon/SM
+nicker/MDG
+nickle/S
+nickname/DSMG
+nicotine/M
+niece/SM
+nifedipine
+niff
+niffy
+nifty/TR
+nigga/MS!
+niggard/SMY
+niggardliness/M
+niggaz/!
+nigger/SM!
+niggle/MZGDRS
+niggler/M
+nigh/RT
+night/SMY
+nightcap/SM
+nightclothes/M
+nightclub/SM
+nightclubbed
+nightclubbing
+nightdress/MS
+nightfall/M
+nightgown/SM
+nighthawk/SM
+nightie/M
+nightingale/SM
+nightlife/M
+nightlight/S
+nightlong
+nightmare/SM
+nightmarish
+nightshade/SM
+nightshirt/SM
+nightspot/MS
+nightstand/SM
+nightstick/SM
+nighttime/M
+nightwatchman
+nightwatchmen
+nightwear/M
+nighty/SM
+nihilism/M
+nihilist/MS
+nihilistic
+nil/M
+nimbi
+nimble/TPR
+nimbleness/M
+nimbly
+nimbus/M
+nimby
+nimrod/MS
+nincompoop/SM
+nine/MS
+ninepin/MS
+ninepins/M
+nineteen/SMH
+nineteenth/M
+nineteenths
+ninetieth/M
+ninetieths
+ninety/HSM
+ninja/SM
+ninny/SM
+ninth/M
+ninths
+niobium/M
+nip/SM
+nipped
+nipper/MS
+nippiness/M
+nipping
+nipple/MS
+nippy/TPR
+nirvana/M
+nisei/M
+nit/SMR
+nite/MS
+niter/M
+nitpick/SZGDR
+nitpicker/M
+nitpicking/M
+nitrate/DSMGN
+nitration/M
+nitric
+nitrification/M
+nitrile/S
+nitrite/SM
+nitro
+nitrocellulose/M
+nitrogen/M
+nitrogenous
+nitroglycerin/M
+nitroglycerine/M
+nitty
+nitty-gritty
+nitwit/MS
+nix/GMDS
+no/SM
+nob/SY
+nobble/GDS
+nobelium/M
+nobility/M
+noble/RSPMT
+nobleman/M
+noblemen
+nobleness/M
+noblewoman/M
+noblewomen
+nobody/SM
+nocturnal/Y
+nocturne/MS
+nod/SM
+nodal
+nodded
+nodding
+noddle/MS
+noddy
+node/MS
+nodular
+nodule/MS
+noel/MS
+noes
+noggin/MS
+nohow
+noise/DSMG
+noiseless/PY
+noiselessness/M
+noisemaker/MS
+noisily
+noisiness/M
+noisome
+noisy/PTR
+nomad/SM
+nomadic
+nomenclature/MS
+nominal/Y
+nominate/CASDXVNG
+nomination/ACM
+nominative/SM
+nominator/CSM
+nominee/MS
+non
+nonabrasive
+nonabsorbent/SM
+nonacademic
+nonacceptance/M
+nonacid
+nonactive/MS
+nonaddictive
+nonadhesive
+nonadjacent
+nonadjustable
+nonadministrative
+nonage/MS
+nonagenarian/MS
+nonaggression/M
+nonalcoholic
+nonaligned
+nonalignment/M
+nonallergic
+nonappearance/MS
+nonassignable
+nonathletic
+nonattendance/M
+nonautomotive
+nonavailability/M
+nonbasic
+nonbeliever/MS
+nonbelligerent/MS
+nonbinary
+nonbinding
+nonbreakable
+nonburnable
+noncaloric
+noncancerous
+nonce/M
+nonchalance/M
+nonchalant/Y
+nonchargeable
+nonclerical/MS
+nonclinical
+noncollectable
+noncom/MS
+noncombat
+noncombatant/MS
+noncombustible
+noncommercial/MS
+noncommittal/Y
+noncommunicable
+noncompeting
+noncompetitive
+noncompliance/M
+noncomplying
+noncomprehending
+nonconducting
+nonconductor/MS
+nonconforming
+nonconformism
+nonconformist/MS
+nonconformity/M
+nonconsecutive
+nonconstructive
+noncontagious
+noncontinuous
+noncontributing
+noncontributory
+noncontroversial
+nonconvertible
+noncooperation/M
+noncorroding
+noncorrosive
+noncredit
+noncriminal/SM
+noncritical
+noncrystalline
+noncumulative
+noncustodial
+nondairy
+nondeductible/M
+nondelivery/SM
+nondemocratic
+nondenominational
+nondepartmental
+nondepreciating
+nondescript
+nondestructive
+nondetachable
+nondeterminism
+nondeterministic
+nondisciplinary
+nondisclosure/M
+nondiscrimination/M
+nondiscriminatory
+nondramatic
+nondrinker/MS
+nondrying
+none
+noneducational
+noneffective
+nonelastic
+nonelectric
+nonelectrical
+nonempty
+nonenforceable
+nonentity/SM
+nonequivalent/MS
+nonessential
+nonesuch/MS
+nonetheless
+nonevent/MS
+nonexchangeable
+nonexclusive
+nonexempt/M
+nonexistence/M
+nonexistent
+nonexplosive/MS
+nonfactual
+nonfading
+nonfat
+nonfatal
+nonfattening
+nonferrous
+nonfiction/M
+nonfictional
+nonflammable
+nonflowering
+nonfluctuating
+nonflying
+nonfood/M
+nonfreezing
+nonfunctional
+nongovernmental
+nongranular
+nonhazardous
+nonhereditary
+nonhuman
+nonidentical
+noninclusive
+nonindependent
+nonindustrial
+noninfectious
+noninflammatory
+noninflationary
+noninflected
+nonintellectual/MS
+noninterchangeable
+noninterference/M
+nonintervention/M
+nonintoxicating
+noninvasive
+nonirritating
+nonissue
+nonjudgmental
+nonjudicial
+nonlegal
+nonlethal
+nonlinear
+nonliterary
+nonliving/M
+nonmagnetic
+nonmalignant
+nonmember/MS
+nonmetal/SM
+nonmetallic
+nonmigratory
+nonmilitant
+nonmilitary
+nonnarcotic/SM
+nonnative/MS
+nonnegative
+nonnegotiable
+nonnuclear
+nonnumerical
+nonobjective
+nonobligatory
+nonobservance/M
+nonobservant
+nonoccupational
+nonoccurence
+nonofficial
+nonoperational
+nonoperative
+nonparallel/MS
+nonpareil/MS
+nonparticipant/MS
+nonparticipating
+nonpartisan/SM
+nonpaying
+nonpayment/SM
+nonperformance/M
+nonperforming
+nonperishable
+nonperson/MS
+nonphysical/Y
+nonplus/S
+nonplussed
+nonplussing
+nonpoisonous
+nonpolitical
+nonpolluting
+nonporous
+nonpracticing
+nonprejudicial
+nonprescription
+nonproductive
+nonprofessional/SM
+nonprofit/SMB
+nonproliferation/M
+nonpublic
+nonpunishable
+nonracial
+nonradioactive
+nonrandom
+nonreactive
+nonreal
+nonreciprocal/SM
+nonreciprocating
+nonrecognition/M
+nonrecoverable
+nonrecurring
+nonredeemable
+nonrefillable
+nonrefundable
+nonreligious
+nonrenewable
+nonrepresentational
+nonresident/MS
+nonresidential
+nonresidual/M
+nonresistance/M
+nonresistant
+nonrestrictive
+nonreturnable/MS
+nonrhythmic
+nonrigid
+nonsalaried
+nonscheduled
+nonscientific
+nonscoring
+nonseasonal
+nonsectarian
+nonsecular
+nonsegregated
+nonsense/M
+nonsensical/Y
+nonsensitive
+nonsexist
+nonsexual
+nonskid
+nonslip
+nonsmoker/SM
+nonsmoking
+nonsocial
+nonspeaking
+nonspecialist/MS
+nonspecializing
+nonspecific
+nonspiritual/SM
+nonstaining
+nonstandard
+nonstarter/MS
+nonstick
+nonstop
+nonstrategic
+nonstriking
+nonstructural
+nonsuccessive
+nonsupport/GM
+nonsurgical
+nonsustaining
+nonsympathizer/M
+nontarnishable
+nontaxable
+nontechnical
+nontenured
+nontheatrical
+nonthinking
+nonthreatening
+nontoxic
+nontraditional
+nontransferable
+nontransparent
+nontrivial
+nontropical
+nonuniform
+nonunion
+nonuser/MS
+nonvenomous
+nonverbal
+nonviable
+nonviolence/M
+nonviolent/Y
+nonvirulent
+nonvocal
+nonvocational
+nonvolatile
+nonvoter/MS
+nonvoting
+nonwhite/MS
+nonworking
+nonyielding
+nonzero
+noodle/MGDS
+nook/MS
+nookie
+nooky
+noon/M
+noonday/M
+noontide/M
+noontime/M
+noose/SM
+nope
+nor
+nor'easter
+norm/MS
+normal/MY
+normalcy/M
+normality/M
+normalization/M
+normalize/DSG
+normative
+north/ZMR
+northbound
+northeast/MRZ
+northeaster/MY
+northeastern
+northeastward/S
+norther/MY
+northerly/SM
+northern/ZR
+northerner/M
+northernmost
+northward/S
+northwest/ZMR
+northwester/MY
+northwestern
+northwestward/S
+nose/MGDSJ
+nosebag/S
+nosebleed/MS
+nosecone/SM
+nosedive/DSMG
+nosegay/SM
+nosh/MDRSZG
+nosher/M
+nosily
+nosiness/M
+nostalgia/M
+nostalgic
+nostalgically
+nostril/MS
+nostrum/MS
+nosy/RPT
+not/B
+notability/SM
+notable/SM
+notably
+notarial
+notarization/M
+notarize/GDS
+notary/SM
+notate/GDS
+notation/FCSM
+notch/GMDS
+note's
+note/FCSDG
+notebook/MS
+notelet/S
+notepad/S
+notepaper/M
+noteworthiness/M
+noteworthy/P
+nothing/PSM
+nothingness/M
+notice/MGDS
+noticeable/U
+noticeably
+noticeboard/S
+noticed/U
+notifiable
+notification/M
+notifier/M
+notify/NDRSXZG
+notion/MS
+notional/Y
+notoriety/M
+notorious/Y
+notwithstanding
+notwork/S
+nougat/MS
+nought/MS
+noun/KMS
+nourish/DSLG
+nourishment/M
+nous
+nova/MS
+novae
+novel/SM
+novelette/SM
+novelist/SM
+novelization/MS
+novelize/DSG
+novella/MS
+novelty/SM
+novena/MS
+novene
+novice/MS
+novitiate/MS
+now/M
+nowadays/M
+noway/S
+nowhere/M
+nowise
+nowt
+noxious
+nozzle/MS
+nu/SM
+nuance/MDS
+nub/SM
+nubbin/MS
+nubby/TR
+nubile
+nuclear/K
+nucleate/DSGN
+nucleation/M
+nuclei
+nucleic
+nucleoli
+nucleolus/M
+nucleon/SM
+nucleoside
+nucleotide
+nucleus/M
+nuclide/S
+nude/MTRS
+nudge/GDSM
+nudism/M
+nudist/SM
+nudity/M
+nugatory
+nugget/SM
+nuisance/MS
+nuke/MGDS
+null/S
+nullification/M
+nullify/NDSG
+nullity/M
+numb/ZTGPDRYS
+number's
+number/ASDG
+numbered/U
+numberless
+numbing/Y
+numbness/M
+numbskull/SM
+numerable/I
+numeracy/IM
+numeral/SM
+numerate/XGNDS
+numeration/M
+numerator/MS
+numeric
+numerical/Y
+numerologist/MS
+numerology/M
+numerous/Y
+numinous
+numismatic/S
+numismatics/M
+numismatist/SM
+numskull/MS
+nun/SM
+nuncio/SM
+nunnery/SM
+nuptial/MS
+nurse/MZGDRS
+nurselings
+nursemaid/MS
+nurser/M
+nursery/SM
+nurseryman/M
+nurserymen
+nursing/M
+nursling/SM
+nurture/DRSMZG
+nurturer/M
+nut/SM
+nutcase/S
+nutcracker/MS
+nuthatch/MS
+nuthouse/S
+nutjob/S
+nutmeat/SM
+nutmeg/SM
+nutpick/SM
+nutria/SM
+nutrient/MS
+nutriment/MS
+nutrition/M
+nutritional/Y
+nutritionist/SM
+nutritious/YP
+nutritiousness/M
+nutritive
+nutshell/MS
+nutted
+nutter/S
+nuttiness/M
+nutting
+nutty/RTP
+nuzzle/DRSMZG
+nuzzler/M
+nybble/S
+nylon/MS
+nylons/M
+nymph/M
+nymphet/MS
+nympho/S
+nymphomania/M
+nymphomaniac/SM
+nymphs
+nystagmus
+n辿e
+o
+o'clock
+o'er
+oaf/SM
+oafish/PY
+oafishness/M
+oak/SMN
+oakum/M
+oar/SGMD
+oarlock/SM
+oarsman/M
+oarsmen
+oarswoman/M
+oarswomen
+oases
+oasis/M
+oat/SMN
+oatcake/SM
+oath/M
+oaths
+oatmeal/M
+oats/M
+ob/S
+obbligato/MS
+obduracy/M
+obdurate/PY
+obdurateness/M
+obedience/EM
+obedient/EY
+obeisance/SM
+obeisant
+obelisk/MS
+obese
+obesity/M
+obey/EDSG
+obfuscate/GNXDS
+obfuscation/M
+obi/SM
+obit/MS
+obituary/SM
+obj
+object/SGVMD
+objectify/NGDS
+objection/SMB
+objectionable/U
+objectionably
+objective/SMYP
+objectiveness/M
+objectivity/M
+objector/MS
+objurgate/XGNDS
+objurgation/M
+oblate/NX
+oblation/M
+obligate/DSXGN
+obligation/M
+obligatorily
+obligatory
+oblige/EGDS
+obliging/Y
+oblique/SMYP
+obliqueness/M
+obliquity/M
+obliterate/DSGN
+obliteration/M
+oblivion/M
+oblivious/YP
+obliviousness/M
+oblong/MS
+obloquy/M
+obnoxious/YP
+obnoxiousness/M
+oboe/MS
+oboist/MS
+obscene/RYT
+obscenity/SM
+obscurantism/M
+obscurantist/SM
+obscure/DRSYTG
+obscurity/SM
+obsequies
+obsequious/PY
+obsequiousness/M
+obsequy/M
+observable/U
+observably
+observance/MS
+observant/Y
+observation/SM
+observational
+observatory/SM
+observe/DRSBZG
+observed/U
+observer/M
+obsess/DSGV
+obsession/SM
+obsessional/Y
+obsessive/PSMY
+obsessiveness/M
+obsidian/M
+obsolesce/DSG
+obsolescence/M
+obsolescent
+obsolete/GDS
+obstacle/MS
+obstetric/S
+obstetrical
+obstetrician/SM
+obstetrics/M
+obstinacy/M
+obstinate/Y
+obstreperous/YP
+obstreperousness/M
+obstruct/DGVS
+obstructed/U
+obstruction/SM
+obstructionism/M
+obstructionist/MS
+obstructive/YP
+obstructiveness/M
+obtain/DBLGS
+obtainable/U
+obtainment/M
+obtrude/DSG
+obtrusion/M
+obtrusive/UPY
+obtrusiveness/UM
+obtuse/YTRP
+obtuseness/M
+obverse/SM
+obviate/DSGN
+obviation/M
+obvious/PY
+obviousness/M
+ocarina/MS
+occasion/GMDS
+occasional/Y
+occidental/SM
+occlude/GDS
+occlusion/SM
+occlusive
+occult/M
+occultism/M
+occultist/SM
+occupancy/M
+occupant/SM
+occupation/AM
+occupational/Y
+occupations
+occupied/U
+occupier/SM
+occupy/ADSG
+occur/AS
+occurred/A
+occurrence/SM
+occurring/A
+ocean/SM
+oceanfront/SM
+oceangoing
+oceanic/M
+oceanographer/SM
+oceanographic
+oceanography/M
+oceanology/M
+ocelot/MS
+och/R
+ocher/M
+ocker/S
+octagon/MS
+octagonal
+octal
+octane/MS
+octant/S
+octantal
+octave/MS
+octavo/MS
+octet/SM
+octogenarian/SM
+octopi
+octopus/MS
+octothorp
+octothorpe
+ocular/MS
+oculist/SM
+oculomotor
+odalisque/SM
+odd/STRYLP
+oddball/SM
+oddity/SM
+oddment/SM
+oddness/M
+odds/M
+ode/SM
+odious/YP
+odiousness/M
+odium/M
+odometer/MS
+odor/MDS
+odoriferous
+odorless
+odorous
+odyssey/MS
+oedipal
+oenology/M
+oenophile/SM
+oeuvre/MS
+of
+off/SZGDRJ
+offal/M
+offbeat/MS
+offend/ZGDRS
+offender/M
+offense/MS
+offensive's
+offensive/IPY
+offensiveness/IM
+offensives
+offer/JGMD
+offering/M
+offertory/SM
+offhand
+offhanded/PY
+offhandedness/M
+office/MZRS
+officeholder/SM
+officer/M
+official/MYS
+officialdom/M
+officialese
+officialism/M
+officiant/SM
+officiate/DSG
+officiator/MS
+officious/PY
+officiousness/M
+offing/M
+offish
+offline
+offload/SDG
+offprint/SM
+offset/MS
+offsetting
+offshoot/MS
+offshore/G
+offside
+offsite
+offspring/M
+offstage/S
+offtrack
+oft
+often/TR
+oftentimes
+ofttimes
+ogle/MZGDRS
+ogler/M
+ogre/MS
+ogreish
+ogress/MS
+oh/M
+ohm/SM
+ohmmeter/MS
+oho
+ohs
+oi
+oik/S
+oil/SGMD
+oilcan/S
+oilcloth/M
+oilcloths
+oilfield/S
+oiliness/M
+oilman
+oilmen
+oilskin/MS
+oilskins/M
+oily/RPT
+oink/MDSG
+ointment/SM
+okapi/SM
+okay/MDSG
+okra/MS
+old/STMNRP
+oldie/SM
+oldish
+oldness/M
+oldster/MS
+ole/SMV
+oleaginous
+oleander/MS
+oleo/M
+oleomargarine/M
+olfactory/SM
+oligarch/M
+oligarchic
+oligarchical
+oligarchs
+oligarchy/SM
+oligo
+oligonucleotide/S
+oligopoly/SM
+olive/SM
+ol辿/M
+om/SMNX
+ombudsman/M
+ombudsmen
+omega/SM
+omelet/MS
+omelette/MS
+omen/M
+omicron/MS
+ominous/YP
+ominousness/M
+omission/MS
+omit/S
+omitted
+omitting
+omnibus/MS
+omnidirectional
+omnipotence/M
+omnipotent
+omnipresence/M
+omnipresent
+omniscience/M
+omniscient
+omnivore/MS
+omnivorous/PY
+omnivorousness/M
+on/Y
+onboard
+once/M
+oncogene/SM
+oncologist/SM
+oncology/M
+oncoming
+one/SXMNP
+oneness/M
+onerous/PY
+onerousness/M
+oneself
+onetime
+ongoing
+onion/M
+onionskin/M
+online
+onlooker/SM
+onlooking
+onomatopoeia/M
+onomatopoeic
+onomatopoetic
+onrush/MSG
+onscreen
+onset/MS
+onshore
+onside
+onsite
+onslaught/MS
+onstage
+onto
+ontogeny/M
+ontological
+ontology/M
+onus/MS
+onward
+onyx/MS
+oodles/M
+ooh/GD
+oohs
+oomph
+oops
+ooze/MGDS
+oozy/TR
+op/SMDG
+opacity/M
+opal/MS
+opalescence/M
+opalescent
+opaque/PYTGDRS
+opaqueness/M
+opcode/S
+ope/S
+open/ZTGJPMDRYS
+opencast
+opened/U
+opener/M
+openhanded/P
+openhandedness/M
+openhearted
+opening/M
+openness/M
+opensource
+openwork/M
+opera/MS
+operable/I
+operand/S
+operate/DSGNVX
+operatic
+operatically
+operation/M
+operational/Y
+operationalize/GDS
+operative/SM
+operator/SM
+operetta/SM
+ophthalmic
+ophthalmologist/SM
+ophthalmology/M
+opiate/SM
+opine/GNXDS
+opinion/M
+opinionated
+opioid/SM
+opium/M
+opossum/MS
+opp
+opponent/SM
+opportune/IY
+opportunism/M
+opportunist/SM
+opportunistic
+opportunistically
+opportunity/SM
+oppose/DRSBG
+opposed/U
+opposite/SMYNX
+opposition/M
+oppositional
+oppress/DSGV
+oppression/M
+oppressive/YP
+oppressiveness/M
+oppressor/MS
+opprobrious/Y
+opprobrium/M
+opt/SGD
+optic/MS
+optical/Y
+optician/SM
+optics/M
+optima
+optimal/Y
+optimism/SM
+optimist/SM
+optimistic
+optimistically
+optimization/MS
+optimize/DRSG
+optimum/SM
+option/SMDG
+optional/Y
+optometrist/MS
+optometry/M
+opulence/M
+opulent/Y
+opus/MS
+or
+oracle/SM
+oracular
+oral/MYS
+orality
+orange/SMP
+orangeade/MS
+orangery/SM
+orangutan/SM
+orate/GNXDS
+oration/M
+orator/SM
+oratorical/Y
+oratorio/MS
+oratory/SM
+orb/SM
+orbicular
+orbit/MDRZGS
+orbital/SM
+orbiter/M
+orc/SM
+orchard/SM
+orchestra/MS
+orchestral
+orchestrate/DSXGN
+orchestration/M
+orchid/SM
+ordain/SDLG
+ordainment/M
+ordeal/SM
+order/EAMDGS
+ordered/U
+orderings
+orderliness/EM
+orderly/PSM
+ordinal/SM
+ordinance/SM
+ordinarily
+ordinariness/M
+ordinary/SMP
+ordinate/MNSX
+ordination/M
+ordnance/M
+ordure/M
+ore/SM
+oregano/M
+org
+organ/MS
+organdy/M
+organelle/MS
+organic/SM
+organically/I
+organism/MS
+organismic
+organist/MS
+organization/ASM
+organizational/Y
+organize/AESDG
+organized/U
+organizer/MS
+organza/M
+orgasm/SM
+orgasmic
+orgiastic
+orgy/SM
+oriel/MS
+orient's
+orient/AEDGS
+oriental/MS
+orientalist/S
+orientate/EDSGN
+orientation/AEM
+orientations
+orienteering
+orifice/MS
+orig
+origami/M
+origin/SM
+original/MYS
+originality/M
+originate/DSGN
+origination/M
+originator/SM
+oriole/SM
+orison/SM
+ormolu/M
+ornament/SGMD
+ornamental
+ornamentation/M
+ornate/YP
+ornateness/M
+orneriness/M
+ornery/PRT
+ornithological
+ornithologist/MS
+ornithology/M
+orotund
+orotundity/SM
+orphan/SMDG
+orphanage/MS
+orris/MS
+orthodontia/M
+orthodontic/S
+orthodontics/M
+orthodontist/SM
+orthodox/U
+orthodoxy/SM
+orthogonal
+orthogonality
+orthographic
+orthographically
+orthography/SM
+orthopedic/S
+orthopedics/M
+orthopedist/MS
+orzo/M
+oscillate/GNDSX
+oscillation/M
+oscillator/SM
+oscillatory
+oscilloscope/MS
+osculate/DSXGN
+osculation/M
+osier/MS
+osmium/M
+osmosis/M
+osmotic
+osprey/SM
+ossicles
+ossification/M
+ossify/NGDS
+ostensible
+ostensibly
+ostentation/M
+ostentatious/Y
+osteoarthritis/M
+osteopath/M
+osteopathic
+osteopaths
+osteopathy/M
+osteoporosis/M
+ostler/S
+ostracism/M
+ostracize/GDS
+ostrich/MS
+other/MSP
+otherwise
+otherworldly
+otiose
+otter/MS
+ottoman/MS
+oubliette/MS
+ouch
+ought
+oughtn't
+ounce/MS
+our/S
+ourselves
+oust/ZGDRS
+ouster/M
+out/SJGMDR
+outage/SM
+outargue/GDS
+outback/MS
+outbalance/DSG
+outbid/S
+outbidding
+outboard/MS
+outboast/DSG
+outbound
+outbox/MS
+outbreak/MS
+outbuilding/MS
+outburst/SM
+outcast/MS
+outclass/DSG
+outcome/MS
+outcrop/MS
+outcropped
+outcropping/SM
+outcry/SM
+outdated
+outdid
+outdistance/GDS
+outdo/G
+outdoes
+outdone
+outdoor/S
+outdoors/M
+outdoorsy
+outdraw/GS
+outdrawn
+outdrew
+outercourse
+outermost
+outerwear/M
+outface/GDS
+outfall/S
+outfield/SMRZ
+outfielder/M
+outfight/SG
+outfit/SM
+outfitted
+outfitter/MS
+outfitting
+outflank/GSD
+outflow/MS
+outfought
+outfox/GDS
+outgo/MJG
+outgoes
+outgrew
+outgrow/HGS
+outgrown
+outgrowth/M
+outgrowths
+outguess/GDS
+outgun/S
+outgunned
+outgunning
+outhit/S
+outhitting
+outhouse/SM
+outing/M
+outlaid
+outlandish/PY
+outlandishness/M
+outlast/DSG
+outlaw/SGMD
+outlay/SGM
+outlet/SM
+outlier/MS
+outline/MGDS
+outlive/GDS
+outlook/MS
+outlying
+outmaneuver/GDS
+outmatch/GDS
+outmoded
+outnumber/DSG
+outpace/GDS
+outpatient/MS
+outperform/GSD
+outplace/L
+outplacement/M
+outplay/GDS
+outpoint/DGS
+outpost/MS
+outpouring/MS
+outproduce/DSG
+output/SM
+outputted
+outputting
+outrace/GDS
+outrage/MGDS
+outrageous/Y
+outran
+outrank/GDS
+outre
+outreach/MDSG
+outrider/MS
+outrigger/SM
+outright
+outrun/S
+outrunning
+outr辿
+outscore/GDS
+outsell/GS
+outset/SM
+outshine/GS
+outshone
+outshout/GDS
+outside/MZRS
+outsider/M
+outsize/MDS
+outskirt/MS
+outsmart/GDS
+outsold
+outsource/DSG
+outsourcing/M
+outspend/SG
+outspent
+outspoken/YP
+outspokenness/M
+outspread/GS
+outstanding/Y
+outstation/MS
+outstay/DGS
+outstretch/DSG
+outstrip/S
+outstripped
+outstripping
+outta
+outtake/MS
+outvote/GDS
+outward/YS
+outwear/GS
+outweigh/GD
+outweighs
+outwit/S
+outwith
+outwitted
+outwitting
+outwore
+outwork/MDRSZG
+outworn
+ouzo/MS
+ova
+oval/MS
+ovarian
+ovary/SM
+ovate/NX
+ovation/M
+oven/MS
+ovenbird/SM
+ovenproof
+ovenware
+over/MYS
+overabundance/M
+overabundant
+overachieve/ZGDRS
+overachiever/M
+overact/GVSD
+overage/SM
+overaggressive
+overall/SM
+overalls/M
+overambitious
+overanxious
+overarching
+overarm/GSD
+overate
+overattentive
+overawe/DSG
+overbalance/MGDS
+overbear/GS
+overbearing/Y
+overbid/SM
+overbidding
+overbite/MS
+overblown
+overboard
+overbold
+overbook/DGS
+overbore
+overborne
+overbought
+overbroad
+overbuild/SG
+overbuilt
+overburden/GSD
+overbuy/GS
+overcame
+overcapacity/M
+overcapitalize/DSG
+overcareful
+overcast/MGS
+overcautious
+overcharge/DSMG
+overclock/GD
+overcloud/SGD
+overcoat/MS
+overcome/GS
+overcompensate/DSGN
+overcompensation/M
+overconfidence/M
+overconfident
+overconscientious
+overcook/DGS
+overcritical
+overcrowd/SDG
+overcrowding/M
+overdecorate/DSG
+overdependent
+overdevelop/SDG
+overdid
+overdo/G
+overdoes
+overdone
+overdose/MGDS
+overdraft/SM
+overdraw/GS
+overdrawn
+overdress/GMDS
+overdrew
+overdrive/SM
+overdub/SM
+overdubbed
+overdubbing
+overdue
+overeager
+overeat/GSN
+overemotional
+overemphasis/M
+overemphasize/GDS
+overenthusiastic
+overestimate/MGNDS
+overestimation/M
+overexcite/DSG
+overexercise/GDS
+overexert/SDG
+overexertion/M
+overexpose/GDS
+overexposure/M
+overextend/DGS
+overfed
+overfeed/GS
+overfill/DGS
+overflew
+overflight/MS
+overflow/MDSG
+overflown
+overfly/GS
+overfond
+overfull
+overgeneralize/DSG
+overgenerous
+overgraze/DSG
+overgrew
+overground
+overgrow/HSG
+overgrown
+overgrowth/M
+overhand/MDS
+overhang/MSG
+overhasty
+overhaul/MDSG
+overhead/MS
+overhear/SG
+overheard
+overheat/DSG
+overhung
+overinclusion
+overinclusive
+overindulge/GDS
+overindulgence/M
+overindulgent
+overinflated
+overjoy/GSD
+overkill/M
+overladen
+overlaid
+overlain
+overland
+overlap/SM
+overlapped
+overlapping
+overlarge
+overlay/GSM
+overleaf
+overlie
+overload/GMDS
+overlong
+overlook/GMDS
+overlord/MS
+overly/SG
+overmanned
+overmanning
+overmaster/SDG
+overmodest
+overmuch/S
+overnice
+overnight/MS
+overoptimism/M
+overoptimistic
+overpaid
+overparticular
+overpass/MS
+overpay/GS
+overplay/GDS
+overpopulate/GNDS
+overpopulation/M
+overpower/SDG
+overpowering/Y
+overpraise/DSG
+overprecise
+overprice/DSG
+overprint/SMDG
+overproduce/GDS
+overproduction/M
+overprotect/SDGV
+overqualified
+overran
+overrate/GDS
+overreach/GDS
+overreact/SDG
+overreaction/SM
+overrefined
+overrich/P
+overridden
+override/MGS
+overripe/M
+overrode
+overrule/GDS
+overrun/SM
+overrunning
+oversampling
+oversaw
+oversea/S
+oversee/RSZ
+overseeing
+overseen
+overseer/M
+oversell/GS
+oversensitive/P
+oversensitiveness/M
+oversexed
+overshadow/DSG
+overshare/DSG
+overshoe/MS
+overshoot/GS
+overshot
+oversight/SM
+oversimple
+oversimplification/M
+oversimplify/DSNGX
+oversize/D
+oversleep/GS
+overslept
+oversold
+overspecialization/M
+overspecialize/GDS
+overspend/SG
+overspent
+overspread/GS
+overstaffed
+overstate/DSLG
+overstatement/MS
+overstay/DSG
+overstep/S
+overstepped
+overstepping
+overstimulate/DSG
+overstock/GSD
+overstretch/GDS
+overstrict
+overstrung
+overstuffed
+oversubscribe/DSG
+oversubtle
+oversupply/GDS
+oversuspicious
+overt/Y
+overtake/GS
+overtaken
+overtax/GDS
+overthink/SG
+overthought
+overthrew
+overthrow/SMG
+overthrown
+overtime/MS
+overtire/GDS
+overtone/MS
+overtook
+overture/MS
+overturn/DSG
+overuse/DSMG
+overvaluation/S
+overvalue/DSG
+overview/MS
+overweening/Y
+overweight/M
+overwhelm/SGD
+overwhelming/Y
+overwinter/SDG
+overwork/GMDS
+overwrite/GS
+overwritten
+overwrote
+overwrought
+overzealous
+oviduct/SM
+oviparous
+ovoid/MS
+ovular
+ovulate/DSGN
+ovulation/M
+ovule/MS
+ovum/M
+ow
+owe/DSG
+owl/SM
+owlet/MS
+owlish/Y
+own/ESGD
+owner/MS
+ownership/M
+ox/MN
+oxalate
+oxblood/M
+oxbow/MS
+oxcart/SM
+oxford/SM
+oxidant/MS
+oxidase
+oxidation/M
+oxidative
+oxide/MS
+oxidization/M
+oxidize/ZGDRS
+oxidizer/M
+oxtail/S
+oxyacetylene/M
+oxygen/M
+oxygenate/DSGN
+oxygenation/M
+oxymora
+oxymoron/M
+oxymoronic
+oxymoronically
+oy
+oyes
+oyez
+oyster/SM
+oz
+ozone/M
+p/NRXTGJ
+pH
+pa/SMH
+pablum/M
+pabulum/M
+pace/MZGDRS
+pacemaker/SM
+pacer/M
+pacesetter/SM
+pacey
+pachyderm/MS
+pachysandra/MS
+pacific
+pacifically
+pacification/M
+pacifier/M
+pacifism/M
+pacifist/SM
+pacifistic
+pacify/ZGDRSN
+pack's
+pack/AUGSD
+package's
+package/AGDS
+packager/SM
+packaging/M
+packer/MS
+packet/MS
+packing's
+packinghouse/SM
+packsaddle/MS
+pact/MS
+pacy/RT
+pad/SM
+padded
+padding/M
+paddle/MZGDRS
+paddler/M
+paddock/MDGS
+paddy/SM
+padlock/MDSG
+padre/SM
+paean/SM
+paella/MS
+pagan/SM
+paganism/M
+page/MZGDRS
+pageant/MS
+pageantry/M
+pageboy/SM
+pager/M
+paginate/DSGN
+pagination/M
+pagoda/MS
+pah
+paid/AU
+pail/MS
+pailful/SM
+pain/MDSG
+painful/PY
+painfuller
+painfullest
+painfulness/M
+painkiller/MS
+painkilling
+painless/PY
+painlessness/M
+painstaking/MY
+paint/SZGJMDR
+paintball
+paintbox/MS
+paintbrush/MS
+painted/U
+painter/MY
+painting/M
+paintwork
+pair/AMDSG
+paired/U
+pairing/S
+pairwise
+paisley/SM
+pajama/S
+pajamas/M
+pal/SMY
+palace/MS
+paladin/SM
+palanquin/SM
+palatable/U
+palatal/SM
+palatalization/M
+palatalize/GDS
+palate/MBS
+palatial/Y
+palatinate/MS
+palatine/MS
+palaver/GSMD
+palazzi
+palazzo
+pale/MYTGPDRSJ
+paleface/MS
+paleness/M
+paleo
+paleographer/MS
+paleography/M
+paleolithic
+paleontologist/SM
+paleontology/M
+palette/SM
+palfrey/SM
+palimony/M
+palimpsest/MS
+palindrome/MS
+palindromic
+paling/M
+palisade/SM
+palish
+pall/MDSG
+palladium/M
+pallbearer/MS
+pallet/MS
+palliate/DSGNV
+palliation/M
+palliative/SM
+pallid/YP
+pallidness/M
+pallor/M
+palm/MDSG
+palmate
+palmetto/SM
+palmist/SM
+palmistry/M
+palmtop/SM
+palmy/TR
+palomino/MS
+palpable
+palpably
+palpate/DSGN
+palpation/M
+palpitate/XGNDS
+palpitation/M
+palsy/GDSM
+paltriness/M
+paltry/RPT
+pampas/M
+pamper/DSG
+pamphlet/MS
+pamphleteer/MS
+pan/SM
+panacea/SM
+panache/M
+panama/MS
+panatella/S
+pancake/DSMG
+panchromatic
+pancreas/MS
+pancreatic
+pancreatitis
+panda/SM
+pandemic/SM
+pandemonium/M
+pander/MDRZGS
+panderer/M
+pane/KM
+panegyric/SM
+panel/SGJMD
+paneling/M
+panelist/MS
+panes
+pang/MS
+panhandle/DRSMZG
+panhandler/M
+panic/SM
+panicked
+panicking
+panicky
+panned
+pannier/SM
+panning
+panoply/SM
+panorama/SM
+panoramic
+panpipes/M
+pansy/SM
+pant/MDSG
+pantaloons/M
+pantechnicon/S
+pantheism/M
+pantheist/SM
+pantheistic
+pantheon/SM
+panther/MS
+pantie/M
+panto/S
+pantomime/MGDS
+pantomimic
+pantomimist/SM
+pantry/SM
+pantsuit/SM
+panty/SM
+pantyhose/M
+pantyliner/M
+pantywaist/SM
+pap/SM
+papa/MS
+papacy/SM
+papal
+paparazzi/M
+paparazzo
+papaw/SM
+papaya/MS
+paper/SZGMDR
+paperback/SM
+paperbark/S
+paperboard/M
+paperboy/SM
+paperclip/S
+paperer/M
+papergirl/SM
+paperhanger/SM
+paperhanging/M
+paperless
+paperweight/MS
+paperwork/M
+papery
+papilla/M
+papillae
+papillary
+papist/MS
+papoose/MS
+pappy/SM
+paprika/M
+papyri
+papyrus/M
+par/SZGMDRBJ
+para/MS
+parable/MS
+parabola/SM
+parabolic
+paracetamol/S
+parachute/DSMG
+parachutist/MS
+paracord
+parade/MZGDRS
+parader/M
+paradigm/SM
+paradigmatic
+paradisaical
+paradise/SM
+paradox/MS
+paradoxical/Y
+paraffin/M
+paragliding
+paragon/MS
+paragraph/GMD
+paragraphs
+parakeet/SM
+paralegal/MS
+parallax/MS
+parallel/SGMD
+paralleled/U
+parallelism/MS
+parallelization/MS
+parallelize/GDS
+parallelogram/SM
+paralyses
+paralysis/M
+paralytic/SM
+paralyze/DSG
+paralyzing/Y
+paramagnetic
+paramecia
+paramecium/M
+paramedic/MS
+paramedical/MS
+parameter/MS
+parameterize/D
+parametric
+parametrize/D
+paramilitary/SM
+paramount
+paramountcy
+paramour/SM
+paranoia/M
+paranoiac/MS
+paranoid/SM
+paranormal
+parapet/MS
+paraphernalia/M
+paraphrase/DSMG
+paraplegia/M
+paraplegic/SM
+paraprofessional/MS
+parapsychologist/MS
+parapsychology/M
+paraquat/M
+parasailing
+parascending
+parasite/SM
+parasitic
+parasitical/Y
+parasitism/M
+parasol/MS
+parasympathetic/S
+parathion/M
+parathyroid/MS
+paratroop/RZS
+paratrooper/M
+paratroops/M
+paratyphoid/M
+parboil/DSG
+parcel/GMDS
+parch/LGDS
+parchment/SM
+pardner/S
+pardon/ZGMDRBS
+pardonable/U
+pardonably/U
+pardoner/M
+pare/S
+paregoric/M
+parent/GMDS
+parentage/M
+parental
+parentheses
+parenthesis/M
+parenthesize/DSG
+parenthetic
+parenthetical/Y
+parenthood/M
+parenting/M
+parer/M
+pares/S
+paresis/M
+parfait/MS
+pariah/M
+pariahs
+paribus
+parietal
+parimutuel/MS
+paring/M
+parish/MS
+parishioner/MS
+parity/ESM
+park/MDSG
+parka/SM
+parking/M
+parkland
+parkour
+parkway/MS
+parky
+parlance/M
+parlay/GMDS
+parley/GMDS
+parliament/SM
+parliamentarian/SM
+parliamentary
+parlor/MS
+parlous
+parmigiana
+parmigiano
+parochial/Y
+parochialism/M
+parodist/SM
+parody/GDSM
+parole/MGDS
+parolee/MS
+paronychia
+parotid
+paroxysm/SM
+paroxysmal
+parquet/MDSG
+parquetry/M
+parred
+parricidal
+parricide/MS
+parring
+parrot/GMDS
+parry/GDSM
+parse/DRSZG
+parsec/MS
+parsimonious/Y
+parsimony/M
+parsley/M
+parsnip/MS
+parson/MS
+parsonage/MS
+part's
+part/CDSG
+partake/ZGRS
+partaken
+partaker/M
+parterre/SM
+parthenogenesis/M
+partial/MYS
+partiality/M
+participant/SM
+participate/DSGN
+participation/M
+participator/MS
+participatory
+participial/M
+participle/MS
+particle/SM
+particleboard/M
+particular/SMY
+particularity/SM
+particularization/M
+particularize/DSG
+particulate/SM
+parting/MS
+partisan/SM
+partisanship/M
+partition/GMDS
+partitions/A
+partitive/MS
+partizan/SM
+partly
+partner/MDSG
+partnership/MS
+partook
+partridge/SM
+parturition/M
+partway
+party/GDSM
+partygoers
+parvenu/MS
+pascal/MS
+paschal
+pasha/SM
+pass/M
+passably
+passage/MS
+passageway/MS
+passbook/MS
+passe/DRSBXZGNV
+passel/MS
+passenger/SM
+passer/M
+passerby/M
+passersby
+passim
+passing/MY
+passion/EM
+passionate/EY
+passionflower/SM
+passionless
+passive/PMYS
+passiveness/M
+passivity/M
+passivization
+passivize/DSG
+passkey/MS
+passphrase/S
+passport/MS
+password/MS
+pass辿
+past/AMS
+pasta/SM
+paste/DSMG
+pasteboard/M
+pastel/MS
+pastern/MS
+pasteurization/M
+pasteurize/ZGDRS
+pasteurized/U
+pasteurizer/M
+pastiche/MS
+pastie
+pastille/MS
+pastime/MS
+pastiness/M
+pastor/MS
+pastoral/MS
+pastorate/MS
+pastrami/M
+pastry/SM
+pasturage/M
+pasture/DSMG
+pastureland/M
+pasty/PTRSM
+pat/SM
+patch/EGMDS
+patchily
+patchiness/M
+patchouli
+patchwork/SM
+patchy/TPR
+pate/MS
+patella/MS
+patellae
+patent/GMDYS
+paterfamilias/MS
+paternal/Y
+paternalism/M
+paternalist/S
+paternalistic
+paternity/M
+paternoster/MS
+path/M
+pathetic
+pathetically
+pathfinder/SM
+pathless
+pathogen/SM
+pathogenic
+pathological/Y
+pathologist/SM
+pathology/M
+pathos/M
+paths
+pathway/MS
+patience/M
+patient/IMST
+patienter
+patiently
+patina/MS
+patine
+patio/SM
+patisserie/S
+patois/M
+patresfamilias
+patriarch/M
+patriarchal
+patriarchate/MS
+patriarchs
+patriarchy/SM
+patrician/SM
+patricidal
+patricide/SM
+patrimonial
+patrimony/SM
+patriot/SM
+patriotic/U
+patriotically
+patriotism/M
+patrol/MS
+patrolled
+patrolling
+patrolman/M
+patrolmen
+patrolwoman/M
+patrolwomen
+patron/MS
+patronage/MS
+patroness/MS
+patronize/ZGDRS
+patronizer/M
+patronizing/Y
+patronymic/SM
+patronymically
+patroon/SM
+patsy/SM
+patted
+patter/MDGS
+pattern/SMDG
+patting
+patty/SM
+paucity/M
+paunch/MS
+paunchy/RT
+pauper/MS
+pauperism/M
+pauperize/DSG
+pause/DSMG
+pave/AZGDRS
+paved/U
+pavement/MS
+pavilion/SM
+paving/MS
+pavlova/S
+paw/SGMD
+pawl/MS
+pawn/MDSG
+pawnbroker/MS
+pawnbroking/M
+pawnshop/MS
+pawpaw/MS
+pax
+pay's
+pay/ASGBL
+payback/SM
+paycheck/MS
+payday/MS
+payed
+payee/SM
+payer/SM
+payload/SM
+paymaster/SM
+payment/ASM
+payoff/MS
+payola/M
+payout/MS
+payphone/S
+payroll/SM
+payslip/SM
+paywall/SM
+payware
+pct
+pd
+pea/SM
+peace/SM
+peaceable
+peaceably
+peaceful/PY
+peacefulness/M
+peacekeeper/SM
+peacekeeping/M
+peacemaker/MS
+peacemaking/M
+peacetime/M
+peach/MS
+peachy/TR
+peacock/MS
+peafowl/MS
+peahen/MS
+peak/MDSG
+peaky
+peal/AMDSG
+peanut/MS
+pear/MYS
+pearl/SGMD
+pearly/RT
+peasant/SM
+peasantry/M
+peashooter/SM
+peat/M
+peaty/TR
+pebble/MGDS
+pebbly
+pebibyte/SM
+pecan/SM
+peccadillo/M
+peccadilloes
+peccary/SM
+peck/MDRSZG
+peckish
+pecs
+pectic
+pectin/M
+pectoral/MS
+pectoralis
+peculate/GNDS
+peculation/M
+peculator/SM
+peculiar/Y
+peculiarity/SM
+pecuniary
+pedagogic
+pedagogical/Y
+pedagogue/SM
+pedagogy/M
+pedal/SGMD
+pedalo/S
+pedant/MS
+pedantic
+pedantically
+pedantry/M
+peddle/ZGDRS
+peddler/M
+pederast/MS
+pederasty/M
+pedestal/MS
+pedestrian/SM
+pedestrianization
+pedestrianize/GDS
+pediatric/S
+pediatrician/MS
+pediatrics/M
+pedicab/SM
+pedicure/MGDS
+pedicurist/MS
+pedigree/MDS
+pediment/MS
+pedometer/MS
+pedophile/S
+pedophilia
+peduncle/MS
+pee/DRSMZ
+peeing
+peek/MDSG
+peekaboo/M
+peel/MDRSJZG
+peeled/U
+peeler/M
+peeling/M
+peen/MS
+peep/MDRSZG
+peepbo
+peeper/M
+peephole/MS
+peepshow/MS
+peer/MDG
+peerage/SM
+peeress/MS
+peerless
+peeve/DSMG
+peevish/PY
+peevishness/M
+peewee/MS
+peewit/S
+peg/SM
+pegboard/MS
+pegged
+pegging
+peignoir/SM
+pejoration/M
+pejorative/SMY
+peke/MS
+pekinese/SM
+pekingese/SM
+pekoe/M
+pelagic
+pelf/M
+pelican/MS
+pellagra/M
+pellet/GMDS
+pellucid
+pelmet/S
+pelt/MDSG
+pelvic
+pelvis/MS
+pemmican/M
+pen/M
+penal
+penalization/M
+penalize/DSG
+penalty/SM
+penance/MS
+pence
+penchant/SM
+pencil/GMDJS
+pend/CDSG
+pendant/MS
+pendency
+pendent/MS
+pendulous
+pendulum/MS
+penetrability/M
+penetrable
+penetrate/DSGNVX
+penetrating/Y
+penetration/M
+penfriend/S
+penguin/MS
+penicillin/M
+penile
+peninsula/SM
+peninsular
+penis/MS
+penitence/M
+penitent/SMY
+penitential
+penitentiary/SM
+penknife/M
+penknives
+penlight/SM
+penman/M
+penmanship/M
+penmen
+pennant/MS
+penned
+penniless
+penning
+pennon/MS
+penny/SM
+pennyweight/MS
+pennyworth
+penologist/MS
+penology/M
+pension/BZGMDRS
+pensioner/M
+pensive/PY
+pensiveness/M
+pent
+pentacle/MS
+pentagon/MS
+pentagonal
+pentagram/SM
+pentameter/SM
+pentathlete/MS
+pentathlon/MS
+penthouse/SM
+penuche/M
+penultimate/SM
+penumbra/MS
+penumbrae
+penurious/PY
+penuriousness/M
+penury/M
+peon/MS
+peonage/M
+peony/SM
+people/MGDS
+pep/SM
+pepped
+pepper/GMDS
+peppercorn/SM
+peppermint/SM
+pepperoni/MS
+peppery
+peppiness/M
+pepping
+peppy/TPR
+pepsin/M
+peptic/MS
+peptide/S
+peradventure/M
+perambulate/XGNDS
+perambulation/M
+perambulator/MS
+percale/MS
+perceive/BGDS
+perceived/U
+percent/MS
+percentage/SM
+percentile/SM
+perceptible
+perceptibly
+perception/SM
+perceptional
+perceptive/PY
+perceptiveness/M
+perceptual/Y
+perch/GMDS
+perchance
+percipience/M
+percipient
+percolate/GNDS
+percolation/M
+percolator/SM
+percussion/AM
+percussionist/MS
+percussive
+perdition/M
+perdurable
+peregrinate/DSXGN
+peregrination/M
+peregrine/MS
+peremptorily
+peremptory
+perennial/SMY
+perestroika/M
+perfect/PTGMDRYS
+perfecta/MS
+perfectibility/M
+perfectible
+perfection/SM
+perfectionism/M
+perfectionist/SM
+perfectness/M
+perfidious/Y
+perfidy/SM
+perforate/GNXDS
+perforation/M
+perforce
+perform/SDRZG
+performance/SM
+performant
+performative
+performed/U
+performer/M
+perfume/DRSMZG
+perfumer/M
+perfumery/SM
+perfunctorily
+perfunctory
+perfusion
+pergola/SM
+perhaps
+pericardia
+pericardial
+pericarditis
+pericardium/M
+perigee/SM
+perihelia
+perihelion/M
+peril/SGMD
+perilous/Y
+perimeter/SM
+perinatal
+perinea
+perineum/M
+period/MS
+periodic
+periodical/SMY
+periodicity/M
+periodontal
+periodontics/M
+periodontist/SM
+peripatetic/MS
+peripheral/MYS
+periphery/SM
+periphrases
+periphrasis/M
+periphrastic
+periscope/SM
+perish/BDRSZG
+perishable/MS
+peristalses
+peristalsis/M
+peristaltic
+peristyle/SM
+peritoneal
+peritoneum/MS
+peritonitis/M
+periwig/SM
+periwinkle/SM
+perjure/DRSZG
+perjurer/M
+perjury/SM
+perk/MDSG
+perkily
+perkiness/M
+perky/TPR
+perm/MDSG
+permafrost/M
+permalink/SM
+permanence/M
+permanency/M
+permanent/SMY
+permeability/M
+permeable
+permeate/GNDS
+permeation/M
+permissibility
+permissible
+permissibly
+permission/MS
+permissive/PY
+permissiveness/M
+permit/MS
+permitted
+permittee
+permitting
+permittivity
+permutation/SM
+permute/DSG
+pernicious/YP
+perniciousness/M
+peroration/MS
+peroxide/MGDS
+perpendicular/SMY
+perpendicularity/M
+perpetrate/DSGN
+perpetration/M
+perpetrator/MS
+perpetual/SMY
+perpetuate/DSGN
+perpetuation/M
+perpetuity/M
+perplex/GDS
+perplexed/Y
+perplexing/Y
+perplexity/SM
+perquisite/SM
+persecute/GNXDS
+persecution/M
+persecutor/SM
+perseverance/M
+persevere/DSG
+persiflage/M
+persimmon/SM
+persist/SGD
+persistence/M
+persistent/Y
+persnickety
+person/UMS
+persona/SM
+personable
+personae
+personage/MS
+personal/MYS
+personality/SM
+personalization
+personalize/CDSG
+personalty/M
+personification/M
+personify/GDSNX
+personnel/M
+perspective/MS
+perspex
+perspicacious/Y
+perspicacity/M
+perspicuity/M
+perspicuous
+perspiration/M
+perspire/GDS
+persuade/BZGDRS
+persuaded/U
+persuader/M
+persuasion/SM
+persuasive/PY
+persuasiveness/M
+pert/RYPT
+pertain/GSD
+pertinacious/Y
+pertinacity/M
+pertinence/M
+pertinent/Y
+pertness/M
+perturb/DGS
+perturbation/SM
+perturbed/U
+pertussis/M
+peruke/MS
+perusal/MS
+peruse/GDS
+perv/S
+pervade/DSG
+pervasive/PY
+pervasiveness/M
+perverse/PXYN
+perverseness/M
+perversion/M
+perversity/M
+pervert/SGMD
+peseta/MS
+peskily
+peskiness/M
+pesky/TPR
+peso/MS
+pessary/S
+pessimal
+pessimism/M
+pessimist/SM
+pessimistic
+pessimistically
+pest/MRSZ
+pester/GD
+pesticide/MS
+pestiferous
+pestilence/SM
+pestilent
+pestilential
+pestle/MGDS
+pesto/M
+pet/SZMR
+petabyte/MS
+petajoule/S
+petal/SMD
+petard/MS
+petawatt/S
+petcock/SM
+peter/GMD
+petiole/SM
+petite/MS
+petition/ZGMDRS
+petitionary
+petitioner/M
+petrel/MS
+petrifaction/M
+petrify/DSG
+petrochemical/SM
+petrodollar/MS
+petrol/M
+petrolatum/M
+petroleum/M
+petrologist/SM
+petrology/M
+petted
+petticoat/MS
+pettifog/S
+pettifogged
+pettifogger/SM
+pettifoggery/M
+pettifogging
+pettily
+pettiness/M
+petting/M
+pettish/Y
+petty/PTR
+petulance/M
+petulant/Y
+petunia/MS
+pew/SM
+pewee/SM
+pewit/SM
+pewter/MS
+peyote/M
+pf
+pfennig/MS
+pg
+phaeton/MS
+phage/S
+phagocyte/SM
+phalanger/SM
+phalanges
+phalanx/MS
+phalli
+phallic
+phallocentric
+phallocentrism
+phallus/M
+phantasm/MS
+phantasmagoria/MS
+phantasmagorical
+phantasmal
+phantom/SM
+pharaoh/M
+pharaohs
+pharisaic
+pharisee/SM
+pharma/MS
+pharmaceutic/MS
+pharmaceutical/SM
+pharmaceutics/M
+pharmacist/MS
+pharmacologic
+pharmacological
+pharmacologist/SM
+pharmacology/M
+pharmacopeia/SM
+pharmacopoeia/MS
+pharmacotherapy
+pharmacy/SM
+pharyngeal
+pharynges
+pharyngitis/M
+pharynx/M
+phase/DSMG
+phaseout/SM
+phat
+pheasant/MS
+phenacetin/M
+phenobarbital/M
+phenol/M
+phenom/MS
+phenomena
+phenomenal/Y
+phenomenological
+phenomenology
+phenomenon/MS
+phenotype
+phenytoin
+pheromone/MS
+phew
+phi/SM
+phial/SM
+philander/ZGDRS
+philanderer/M
+philandering/M
+philanthropic
+philanthropically
+philanthropist/MS
+philanthropy/SM
+philatelic
+philatelist/MS
+philately/M
+philharmonic/SM
+philippic/MS
+philistine/MS
+philistinism/M
+philodendron/SM
+philological
+philologist/MS
+philology/M
+philosopher/MS
+philosophic
+philosophical/Y
+philosophize/DRSZG
+philosophizer/M
+philosophy/SM
+philter/MS
+phimosis/S
+phish/ZGDR
+phisher/M
+phlebitis/M
+phlebotomist/MS
+phlebotomize/GDS
+phlebotomy
+phlegm/M
+phlegmatic
+phlegmatically
+phloem/M
+phlogiston/S
+phlox/M
+pho
+phobia/MS
+phobic/MS
+phoebe/MS
+phoenix/MS
+phone/DSMG
+phonecard/S
+phoneme/MS
+phonemic
+phonemically
+phonetic/S
+phonetically
+phonetician/SM
+phonetics/M
+phoneyed
+phoneying
+phonic/S
+phonically
+phonics/M
+phoniness/M
+phonograph/M
+phonographic
+phonographs
+phonological/Y
+phonologist/MS
+phonology/M
+phonon
+phony/PTGDRSM
+phooey
+phosphate/MS
+phosphine/MS
+phosphodiesterase
+phosphor/MS
+phosphorescence/M
+phosphorescent/Y
+phosphoric
+phosphorous
+phosphorus/M
+phosphorylate/DSGN
+photo/SGMD
+photocell/MS
+photocopier/M
+photocopy/DRSMZG
+photodetector/S
+photoelectric
+photoelectrically
+photoengrave/DRSJZG
+photoengraver/M
+photoengraving/M
+photofinishing/M
+photogenic
+photogenically
+photograph/MDRZG
+photographer/M
+photographic
+photographically
+photographs/A
+photography/M
+photojournalism/M
+photojournalist/SM
+photometer/MS
+photon/MS
+photosensitive
+photosensor/S
+photosensory
+photostat/SM
+photostatic
+photostatted
+photostatting
+photosynthesis/M
+photosynthesize/GDS
+photosynthetic
+phototropic
+phototropism
+phototypesetter
+phototypesetting
+photovoltaic
+phrasal
+phrase's
+phrase/AGDS
+phrasebook/S
+phraseology/M
+phrasing/MS
+phreaking
+phrenologist/SM
+phrenology/M
+phyla
+phylactery/SM
+phyllo
+phylogeny/M
+phylum/M
+phys
+physic/SM
+physical/MYS
+physicality
+physician/SM
+physicist/SM
+physicked
+physicking
+physics/M
+physio/S
+physiognomy/SM
+physiography/M
+physiologic
+physiological/Y
+physiologist/MS
+physiology/M
+physiotherapist/MS
+physiotherapy/M
+physique/MS
+phytoplankton
+pi/SMDRHZG
+pianissimo/SM
+pianist/MS
+piano/SM
+pianoforte/SM
+pianola/S
+piaster/MS
+piazza/MS
+pibroch/M
+pibrochs
+pic/SM
+pica/M
+picador/MS
+picante
+picaresque
+picayune
+piccalilli/M
+piccolo/MS
+pick/MDRSJZG
+pickax/GMDS
+picker/M
+pickerel/MS
+picket/ZGMDRS
+pickings/M
+pickle/MGDS
+pickpocket/SM
+pickup/MS
+picky/PTR
+picnic/MS
+picnicked
+picnicker/SM
+picnicking
+picot/SM
+pictogram/S
+pictograph/M
+pictographs
+pictorial/MYS
+picture/MGDS
+picturesque/PY
+picturesqueness/M
+piddle/MGDS
+piddly
+pidgin/MS
+pie/SM
+piebald/MS
+piece/DSMG
+piecemeal
+piecewise
+piecework/MRZ
+pieceworker/M
+piecrust/SM
+pieing
+pier/M
+pierce/JGDS
+piercing/MY
+piety/M
+piezoelectric
+piffle/MG
+pig/SML
+pigeon/MS
+pigeonhole/DSMG
+pigged
+piggery/S
+pigging
+piggish/PY
+piggishness/M
+piggy/TRSM
+piggyback/MDSG
+pigheaded/PY
+pigheadedness/M
+piglet/MS
+pigment/MDS
+pigmentation/M
+pigpen/MS
+pigskin/MS
+pigsty/SM
+pigswill
+pigtail/MS
+pike/MZGDRS
+piker/M
+pikestaff/SM
+pikestaves
+pilaf/SM
+pilaster/MS
+pilchard/MS
+pile/MGDSJ
+pileup/MS
+pilfer/ZGDRS
+pilferage/M
+pilferer/M
+pilgrim/MS
+pilgrimage/MGDS
+piling/M
+pill/MDSG
+pillage/MZGDRS
+pillager/M
+pillar/MDS
+pillbox/MS
+pillion/MS
+pillock/S
+pillory/GDSM
+pillow/GMDS
+pillowcase/MS
+pillowslip/MS
+pilot/DGSM
+pilothouse/SM
+pimento/MS
+pimiento/MS
+pimp/GMDYS
+pimpernel/MS
+pimple/DSM
+pimply/RT
+pin/SM
+pinafore/MS
+pinata/MS
+pinball/M
+pincer/MS
+pinch/GMDS
+pincushion/MS
+pine's
+pine/AGDS
+pineapple/MS
+pinewood/S
+piney
+pinfeather/SM
+ping/GMD
+pinhead/SM
+pinhole/SM
+pinion/SMDG
+pink/TGPMDRS
+pinkeye/M
+pinkie/M
+pinkish
+pinkness/M
+pinko/MS
+pinky/SM
+pinnacle/SM
+pinnate
+pinned/U
+pinning/U
+pinny/S
+pinochle/M
+pinon/MS
+pinpoint/SGMD
+pinprick/MS
+pinsetter/SM
+pinstripe/DSM
+pint/MS
+pinto/MS
+pinup/MS
+pinwheel/GSMD
+piny/TR
+pinyin/M
+pinyon/SM
+pioneer/SGMD
+pious/YP
+piousness/M
+pip/SZGMDR
+pipe/MS
+pipeline/SM
+piper/M
+pipette/SM
+pipework
+piping/M
+pipit/MS
+pipped
+pippin/SM
+pipping
+pipsqueak/SM
+piquancy/M
+piquant/Y
+pique/MGDS
+piracy/M
+piranha/SM
+pirate/DSMG
+piratical/Y
+pirogi/M
+piroshki/M
+pirouette/DSMG
+pirozhki/M
+piscatorial
+pismire/SM
+piss/ZGMDRS
+pissoir/S
+pistachio/SM
+piste/S
+pistil/SM
+pistillate
+pistol/SM
+piston/SM
+pit/SM
+pita/MS
+pitapat/SM
+pitch/MDRSZG
+pitchblende/M
+pitcher/M
+pitchfork/MDSG
+pitchman/M
+pitchmen
+piteous/YP
+piteousness/M
+pitfall/SM
+pith/M
+pithead/S
+pithily
+pithiness/M
+pithy/RTP
+pitiable
+pitiably
+pitiful/Y
+pitiless/PY
+pitilessness/M
+piton/MS
+pitta/S
+pittance/MS
+pitted
+pitting
+pituitary/SM
+pity/GDSM
+pitying/Y
+pivot/MDGS
+pivotal
+pix/M
+pixel/MS
+pixelate/DS
+pixie/MS
+pizazz/M
+pizza/MS
+pizzazz/M
+pizzeria/SM
+pizzicati
+pizzicato/M
+pi単ata/MS
+pi単on/SM
+pj's
+pk
+pkg
+pkt
+pkwy
+pl
+placard/SMDG
+placate/DSGN
+placation/M
+placatory
+place's
+place/AESDLG
+placebo/SM
+placed/U
+placeholder/MS
+placekick/MDRZGS
+placekicker/M
+placement/EASM
+placenta/SM
+placental/S
+placer/SM
+placid/Y
+placidity/M
+placings
+placket/SM
+plagiarism/SM
+plagiarist/SM
+plagiarize/DRSZG
+plagiarizer/M
+plagiary/M
+plague/DSMG
+plaice
+plaid/MS
+plain/MRYTSP
+plainchant
+plainclothes
+plainclothesman/M
+plainclothesmen
+plainness/M
+plainsman/M
+plainsmen
+plainsong/M
+plainspoken
+plaint/SMV
+plaintext
+plaintiff/SM
+plaintive/Y
+plait/MDGS
+plan/ZMRS
+planar
+plane's
+plane/CGDS
+planeload/MS
+planer/M
+planet/SM
+planetarium/SM
+planetary
+plangency/M
+plangent
+plank/MDGS
+planking/M
+plankton/M
+planned/U
+planner/SM
+planning/S
+plant/MDRZGSJ
+plantain/SM
+plantar
+plantation/MS
+planter/M
+planting/M
+plantlike
+plaque/SM
+plash/MDSG
+plasma/M
+plasmon
+plaster/SZGMDR
+plasterboard/M
+plasterer/M
+plastic/SM
+plasticity/M
+plasticize/DSG
+plastique
+plat/XGMDNS
+plate/MS
+plateau/SMDG
+plateful/SM
+platelet/SM
+platen/M
+platform/SGMD
+plating/M
+platinum/M
+platitude/SM
+platitudinous
+platonic
+platoon/SGMD
+platted
+platter/SM
+platting
+platy/M
+platypus/MS
+platys
+plaudit/SM
+plausibility/M
+plausible
+plausibly
+play/AEGMDS
+playable/EU
+playact/SGD
+playacting/M
+playback/MS
+playbill/MS
+playbook/MS
+playboy/SM
+player/SM
+playfellow/SM
+playful/PY
+playfulness/M
+playgirl/MS
+playgoer/MS
+playground/SM
+playgroup/S
+playhouse/MS
+playlist/MS
+playmate/MS
+playoff/SM
+playpen/SM
+playroom/SM
+playschool/S
+plaything/SM
+playtime/M
+playwright/SM
+plaza/MS
+plea/MS
+plead/ADRZGSJ
+pleader's
+pleading/MY
+pleasant/UTYP
+pleasanter
+pleasantness/UM
+pleasantry/SM
+please/EDSG
+pleasing/YS
+pleasurably
+pleasure/MGDSB
+pleasureful
+pleat/MDGS
+pleb/S
+plebby
+plebe/MS
+plebeian/MS
+plebiscite/MS
+plectra
+plectrum/MS
+pledge/DSMG
+plenary/SM
+plenipotentiary/SM
+plenitude/SM
+plenteous
+plentiful/Y
+plenty/M
+plenum/S
+pleonasm/MS
+plethora/M
+pleura/M
+pleurae
+pleurisy/M
+plexiglass/M
+plexus/MS
+pliability/M
+pliable
+pliancy/M
+pliant/Y
+pliers/M
+plight/SMDG
+plimsoll/S
+plinth/M
+plinths
+plod/S
+plodded
+plodder/MS
+plodding/S
+plonk/DRSZG
+plop/MS
+plopped
+plopping
+plosive/S
+plot/MS
+plotted
+plotter/SM
+plotting
+plover/SM
+plow/GMDS
+plowman/M
+plowmen
+plowshare/MS
+ploy's
+ploy/S
+pluck/MDSG
+pluckily
+pluckiness/M
+plucky/RPT
+plug's
+plug/US
+plugged/U
+plugging/U
+plughole/S
+plugin/SM
+plum/GMDS
+plumage/M
+plumb/MDRSZGJ
+plumbed/U
+plumber/M
+plumbing/M
+plume/MS
+plummet/SGMD
+plummy
+plump/MDRYSTGP
+plumpness/M
+plumy/RT
+plunder/SZGMDR
+plunderer/M
+plunge/DRSMZG
+plunger/M
+plunk/MDSG
+pluperfect/SM
+plural/SM
+pluralism/M
+pluralist/MS
+pluralistic
+plurality/SM
+pluralization/M
+pluralize/GDS
+plus/MS
+plush/MRYTP
+plushness/M
+plushy/RT
+plusses
+plutocracy/SM
+plutocrat/SM
+plutocratic
+plutonium/M
+pluvial
+ply/AGDSM
+plywood/M
+pm
+pneumatic
+pneumatically
+pneumococcal
+pneumococci
+pneumococcus
+pneumonia/M
+poach/DRSZG
+poacher/M
+poaching/M
+pock/GMDS
+pocket/SMDG
+pocketbook/SM
+pocketful/SM
+pocketknife/M
+pocketknives
+pockmark/MDGS
+pod/SM
+podcast/SMG
+podded
+podding
+podiatrist/SM
+podiatry/M
+podium/SM
+poem/MS
+poesy/M
+poet/MS
+poetaster/MS
+poetess/MS
+poetic/S
+poetical/Y
+poetry/M
+pogrom/SM
+poi/M
+poignancy/M
+poignant/Y
+poinciana/SM
+poinsettia/SM
+point/MDRSZG
+pointblank
+pointed/Y
+pointer/M
+pointillism/M
+pointillist/SM
+pointless/PY
+pointlessness/M
+pointy/TR
+poise/MGDS
+poison/SJZGMDR
+poisoner/M
+poisoning/M
+poisonous/Y
+poke/MZGDRS
+poker/M
+pokey/MS
+poky/TR
+pol/SGMD
+polar
+polarity/SM
+polarization/CM
+polarize/CDSG
+polarizer/S
+pole/MS
+poleaxe/GDS
+polecat/MS
+polemic/MS
+polemical/Y
+polemicist/SM
+polemics/M
+polestar/SM
+police/DSMG
+policeman/M
+policemen
+policewoman/M
+policewomen
+policy/SM
+policyholder/MS
+policymaker/S
+polio/MS
+poliomyelitis/M
+polish/ZGMDRS
+polished/U
+polisher/M
+politburo/MS
+polite/RYTP
+politeness/M
+politesse/M
+politic/S
+political/Y
+politician/SM
+politicization/M
+politicize/CDSG
+politicking/M
+politico/SM
+politics/M
+polity/SM
+polka/MDSG
+poll/GMDNS
+pollack/MS
+pollard/S
+pollen/M
+pollinate/GNDS
+pollination/M
+pollinator/SM
+polling/M
+polliwog/SM
+pollock/M
+pollster/SM
+pollutant/MS
+pollute/ZGNDRS
+polluted/U
+polluter/M
+pollution/M
+pollywog/MS
+polo/M
+polonaise/SM
+polonium/M
+poltergeist/MS
+poltroon/SM
+poly
+polyacrylamide
+polyamory/S
+polyandrous
+polyandry/M
+polyclinic/SM
+polyester/MS
+polyethylene/M
+polygamist/MS
+polygamous
+polygamy/M
+polyglot/SM
+polygon/SM
+polygonal
+polygraph/GMD
+polygraphs
+polyhedral
+polyhedron/SM
+polymath/M
+polymaths
+polymer/SM
+polymeric
+polymerization/M
+polymerize/GDS
+polymorphic
+polymorphically
+polymorphism
+polymorphous
+polynomial/MS
+polynucleotide/SM
+polyp/MS
+polypeptide/SM
+polyphonic
+polyphony/M
+polypropylene/M
+polys
+polysemous
+polystyrene/M
+polysyllabic
+polysyllable/MS
+polytechnic/MS
+polytheism/M
+polytheist/SM
+polytheistic
+polythene
+polyunsaturate/DS
+polyurethane/MS
+polyvinyl
+pom/S
+pomade/DSMG
+pomander/SM
+pomegranate/MS
+pommel/SGMD
+pommy/S
+pomp/M
+pompadour/SMD
+pompano/MS
+pompom/SM
+pomposity/M
+pompous/YP
+pompousness/M
+ponce/GDS
+poncho/SM
+poncy
+pond/MS
+ponder/SZGDR
+ponderer/M
+ponderous/YP
+ponderousness/M
+pone/MS
+pong/GDS
+pongee/M
+poniard/MS
+pontiff/SM
+pontifical/Y
+pontificate/DSMG
+pontoon/SM
+pony/GDSM
+ponytail/MS
+poo/SGD
+pooch/MDSG
+poodle/SM
+poof/MS
+poofter/S
+pooh/GMD
+poohs
+pool/GMDS
+poolroom/MS
+poolside/S
+poop/GMDS
+poor/TRYP
+poorboy/M
+poorhouse/SM
+poorness/M
+pop/SM
+popcorn/M
+pope/MS
+popgun/SM
+popinjay/MS
+poplar/SM
+poplin/M
+popover/SM
+poppa/MS
+poppadom/S
+popped
+popper/SM
+poppet/S
+popping
+poppy/SM
+poppycock/M
+populace/MS
+popular/Y
+popularity/UM
+popularization/M
+popularize/DSG
+populate/ACGDS
+populated/U
+population/CM
+populations
+populism/M
+populist/MS
+populous/P
+populousness/M
+popup/MS
+porcelain/SM
+porch/MS
+porcine
+porcupine/SM
+pore/MGDS
+porgy/SM
+pork/ZMR
+porker/M
+porky/RSMT
+porn/M
+porno/M
+pornographer/MS
+pornographic
+pornographically
+pornography/M
+porosity/M
+porous/P
+porousness/M
+porphyritic
+porphyry/M
+porpoise/MGDS
+porridge/M
+porringer/SM
+port's/A
+port/CAEGDS
+portability/M
+portable/MS
+portage/DSMG
+portal/SM
+portcullis/MS
+portend/SGD
+portent/SM
+portentous/YP
+porter/ASM
+porterhouse/SM
+portfolio/MS
+porthole/MS
+portico/M
+porticoes
+portiere/MS
+portion/KSGMD
+porti竪re/MS
+portlet/SM
+portliness/M
+portly/RPT
+portmanteau/MS
+portrait/MS
+portraitist/SM
+portraiture/M
+portray/SGD
+portrayal/MS
+portulaca/M
+pose's/A
+pose/CAKEGDS
+poser/EKSM
+poseur/SM
+posh/TR
+posit/DSG
+position/CKEMS
+positional/KE
+positioned/K
+positioning/AK
+positive/EMYPS
+positiveness/M
+positivism
+positivist/S
+positivity/SM
+positron/MS
+poss
+posse/MS
+possess/AEVGSD
+possession/ASM
+possessive/SMYP
+possessiveness/M
+possessor/SM
+possibility/SM
+possible/SM
+possibly
+possum/SM
+post-partum
+post/ZGMDRSJ
+postage/M
+postal
+postbag/S
+postbox/S
+postcard/SM
+postcode/S
+postcolonial
+postconsonantal
+postdate/DSG
+postdoc/MS
+postdoctoral
+poster/M
+posterior/SM
+posterity/M
+postgraduate/SM
+posthaste
+posthitides
+posthitis
+posthumous/Y
+posthypnotic
+postie/S
+postilion/SM
+postillion/MS
+postindustrial
+posting/M
+postlude/SM
+postman/M
+postmark/SMDG
+postmaster/MS
+postmen
+postmenopausal
+postmeridian
+postmistress/MS
+postmodern
+postmodernism/M
+postmodernist/MS
+postmortem/SM
+postnasal
+postnatal/Y
+postoperative
+postpaid
+postpartum
+postpone/DSGL
+postponement/SM
+postprandial
+postscript/SM
+postseason/SM
+postsynaptic
+postulate/XDSMGN
+postulation/M
+postural
+posture/MGJDS
+posturing/M
+postwar
+postwoman
+postwomen
+posy/SM
+pot/CSM
+potability/M
+potable/SM
+potash/M
+potassium/M
+potato/M
+potatoes
+potbelly/DSM
+potboiler/SM
+potency/M
+potent/Y
+potentate/MS
+potential/MYS
+potentiality/SM
+potentiate/GDS
+potful/SM
+pothead/SM
+pother/SMDG
+potherb/SM
+potholder/MS
+pothole/DRSMZG
+pothook/SM
+potion/SM
+potluck/MS
+potpie/SM
+potpourri/SM
+potsherd/SM
+potshot/MS
+pottage/M
+potted
+potter/GSMD
+pottery/SM
+potting
+potty/PRSMT
+pouch/MDSG
+pouf/S
+pouffe/S
+poulterer/MS
+poultice/DSMG
+poultry/M
+pounce/DSMG
+pound's
+pound/KDRSZG
+poundage/M
+pounding/SM
+pour/GDSJ
+pout/ZGMDRS
+pouter/M
+poutine/S
+poverty/M
+pow
+powder/GSMD
+powdery
+power/MDSG
+powerboat/MS
+powerful/Y
+powerhouse/SM
+powerless/PY
+powerlessness/M
+powwow/SGMD
+pox/MS
+pp
+ppm
+ppr
+pr
+practicability/M
+practicably
+practical/SMY
+practicality/SM
+practice/DSMGB
+practiced/U
+practicum/SM
+practitioner/SM
+praecipe
+praetor/SM
+praetorian
+pragmatic/MS
+pragmatical/Y
+pragmatism/M
+pragmatist/MS
+prairie/SM
+praise/EDSMG
+praiseworthiness/M
+praiseworthy/P
+praline/SM
+pram/MS
+prance/DRSMZG
+prancer/M
+prancing/Y
+prang/DSG
+prank/MDSG
+prankster/SM
+praseodymium/M
+prat/S
+prate/MZGDRS
+prater/M
+pratfall/SM
+prattle/DRSMZG
+prattler/M
+prawn/MDSG
+pray/ZGDRS
+prayer/M
+prayerful/Y
+pre-fill/GDS
+pre-programmed
+pre-programming
+preach/DRSZGL
+preacher/M
+preachment/M
+preachy/RT
+preadolescence/SM
+preadolescent
+preamble/MGDS
+prearrange/LGDS
+prearrangement/M
+preassigned
+precancel/SMDG
+precancerous
+precarious/PY
+precariousness/M
+precast
+precaution/MS
+precautionary
+precede/DSG
+precedence/M
+precedent/SM
+precedential
+precept/SM
+preceptor/SM
+precession
+precessional
+precinct/MS
+preciosity/M
+precious/YP
+preciousness/M
+precipice/SM
+precipitant/MS
+precipitate/XMYGNDS
+precipitation/M
+precipitous/Y
+precis/M
+precise/DRSYTGNP
+preciseness/M
+precision/M
+preclude/GDS
+preclusion/SM
+precocious/YP
+precociousness/M
+precocity/M
+precognition/M
+precognitive
+precolonial
+preconceive/GDS
+preconception/SM
+precondition/MDGS
+precook/GSD
+precursor/SM
+precursory
+predate/DSG
+predator/MS
+predatory
+predawn
+predecease/GDS
+predecessor/SM
+predefined
+predesignate/GDS
+predestination/M
+predestine/DSG
+predetermination/M
+predetermine/ZGDRS
+predeterminer/M
+predicable
+predicament/MS
+predicate/MGNVDS
+predication/M
+predicative/Y
+predict/BGVSD
+predictability/UM
+predictable/U
+predictably/U
+prediction/SM
+predictor/MS
+predigest/GDS
+predilection/SM
+predispose/GDS
+predisposition/MS
+prednisone
+predominance/M
+predominant/Y
+predominate/YGDS
+preemie/SM
+preeminence/M
+preeminent/Y
+preempt/GVSD
+preemption/M
+preemptive/Y
+preen/DSG
+preexist/DGS
+preexistence/M
+pref
+prefab/SM
+prefabbed
+prefabbing
+prefabricate/DSGN
+prefabrication/M
+preface/DSMG
+prefatory
+prefect/SM
+prefecture/MS
+prefer/SBL
+preferably
+preference/MS
+preferential/Y
+preferment/M
+preferred
+preferring
+prefigure/GDS
+prefill/GSD
+prefix/MDSG
+preform/GSD
+prefrontal
+pregame/SM
+pregnancy/SM
+pregnant
+preheat/GSD
+prehensile
+prehistorian/S
+prehistoric
+prehistorical/Y
+prehistory/M
+prehuman
+preinstall/D
+prejudge/LGDS
+prejudgement/MS
+prejudgment/SM
+prejudice/MGDS
+prejudiced/U
+prejudicial
+prekindergarten/SM
+prelacy/M
+prelate/SM
+prelim/SM
+preliminarily
+preliminary/SM
+preliterate
+preload/SGD
+prelude/MS
+premarital
+premature/Y
+premed/SM
+premedical
+premeditate/DSGN
+premeditated/U
+premeditation/M
+premenstrual
+premier/SGMD
+premiere/MS
+premiership/MS
+premise/DSMG
+premium/SM
+premix/GDS
+premolar/SM
+premonition/MS
+premonitory
+prenatal/Y
+prenup/SM
+prenuptial
+preoccupation/SM
+preoccupy/DSG
+preoperative
+preordain/GDS
+preowned
+prep/MS
+prepackage/DSG
+prepacked
+prepaid
+preparation/SM
+preparatory
+prepare/ZGDRS
+prepared/UP
+preparedness/UM
+prepay/GSL
+prepayment/MS
+prepend/DGS
+preponderance/SM
+preponderant/Y
+preponderate/GDS
+preposition/SM
+prepositional/Y
+prepossess/GDS
+prepossessing/U
+prepossession/SM
+preposterous/Y
+prepped
+preppie/M
+prepping
+preppy/TRSM
+preprocess/DSG
+preprogrammed
+preprogramming
+prepubescence/M
+prepubescent/SM
+prepuce/MS
+prequel/MS
+prerecord/GSD
+preregister/SGD
+preregistration/M
+prerequisite/MS
+prerogative/SM
+pres
+presage/MGDS
+presbyopia/M
+presbyter/SM
+presbytery/SM
+preschool/SZMR
+preschooler/M
+prescience/M
+prescient/Y
+prescribe/DSG
+prescript/SVM
+prescription/SM
+prescriptive/Y
+preseason/SM
+presence/SM
+present/LMDRYZGSB
+presentably
+presentation/ASM
+presenter/M
+presentiment/SM
+presentment/SM
+preservation/M
+preservationist/SM
+preservative/SM
+preserve/BDRSMZG
+preserver/M
+preset/S
+presetting
+preshrank
+preshrink/GS
+preshrunk
+preside/GDS
+presidency/SM
+president/MS
+presidential
+presidia
+presidium/M
+presort/DGS
+press's
+press/ACGSD
+pressed/U
+presser/MS
+pressie/S
+pressing/SMY
+pressman/M
+pressmen
+pressure/DSMG
+pressured/U
+pressurization/M
+pressurize/CGDS
+pressurized/U
+pressurizer/SM
+prestidigitation/M
+prestige/M
+prestigious
+presto/SM
+presumably
+presume/GDSB
+presumption/SM
+presumptive
+presumptuous/YP
+presumptuousness/M
+presuppose/DSG
+presupposition/MS
+pretax
+preteen/MS
+pretend/DRZGS
+pretender/M
+pretense/SXMN
+pretension/M
+pretentious/UY
+pretentiousness/M
+preterit/SM
+preterite/MS
+preterm
+preternatural/Y
+pretest/DGS
+pretext/MS
+pretrial/S
+prettify/GDS
+prettily
+prettiness/M
+pretty/TGDRSMP
+pretzel/MS
+prev
+prevail/DGS
+prevalence/M
+prevalent
+prevaricate/DSGNX
+prevarication/M
+prevaricator/SM
+prevent/DBSGV
+preventable/U
+preventative/MS
+prevention/M
+preventive/SM
+preview/MDRSZG
+previous/Y
+prevision/MS
+prewar
+prey/GMDS
+prezzie/S
+priapic
+price's
+price/AGDS
+priceless
+pricey
+pricier
+priciest
+prick/MDRYSZG
+pricker/M
+prickle/MGDS
+prickliness/M
+prickly/PRT
+pride/MGDS
+prideful/Y
+prier/M
+priest/SMY
+priestess/MS
+priesthood/SM
+priestliness/M
+priestly/RTP
+prig/MS
+priggish/P
+priggishness/M
+prim/ZGDRYP
+primacy/M
+primal
+primarily
+primary/SM
+primate/MS
+prime/MS
+primer/M
+primeval
+priming/M
+primitive/SPMY
+primitiveness/M
+primmer
+primmest
+primness/M
+primogenitor/SM
+primogeniture/M
+primordial/Y
+primp/DSG
+primrose/SM
+primula/S
+prince/SMY
+princedom/SM
+princeliness/M
+princely/PRT
+princess/MS
+principal/SMY
+principality/SM
+principle/DSM
+principled/U
+print/AMDSG
+printable/U
+printer/MS
+printing/SM
+printmaking
+printout/SM
+prion/S
+prior/MS
+prioress/MS
+prioritization
+prioritize/DSG
+priority/SM
+priory/SM
+prism/MS
+prismatic
+prison/SZMR
+prisoner/M
+prissily
+prissiness/M
+prissy/PTR
+pristine
+prithee
+privacy/M
+private/XMYTNRS
+privateer/SM
+privation/CSM
+privatization/SM
+privatize/DSG
+privet/SM
+privilege/DSMG
+privileged/U
+privily
+privy/RSMT
+prize/MGDS
+prized/A
+prizefight/ZGSMR
+prizefighter/M
+prizefighting/M
+prizewinner/MS
+prizewinning
+pro/SM
+proactive/Y
+probabilistic
+probability/SM
+probable/SM
+probably
+probate/MN
+probation/ZMR
+probational
+probationary
+probationer/M
+probe/MGDSBJ
+probity/M
+problem/MS
+problematic/U
+problematical/Y
+probosces
+proboscis/MS
+procaine/M
+procaryote/SM
+procaryotic
+procedural
+procedure/SM
+proceed/GJDS
+proceeding/M
+proceeds/M
+process's
+process/AGDS
+processable
+processed/U
+procession/GD
+processional/MS
+processor/SM
+proclamation/MS
+proclivity/SM
+procrastinate/DSGN
+procrastination/M
+procrastinator/MS
+procreate/V
+proctor/GMDS
+procurement/M
+prod/MS
+prodigal/MYS
+prodigality/M
+prodigious/Y
+prodigy/SM
+produce's
+produce/AZGDRS
+producer/AM
+producible/A
+production/ASM
+productive/UY
+productiveness/M
+productivity/M
+prof/MS
+profanation/MS
+profane/PYGDS
+profaneness/M
+profanity/SM
+professed/Y
+profession/SM
+professional/MYS
+professionalism/M
+professionalization
+professionalize/DSG
+professor/SM
+professorial/Y
+professorship/SM
+proffer/GMDS
+proficiency/M
+proficient/MYS
+profit/BGD
+profitability/M
+profitable/U
+profitably/U
+profiteer/MDGS
+profiteering/M
+profiterole/SM
+profitless
+profligacy/M
+profligate/SMY
+profound/RYTP
+profoundness/M
+profundity/SM
+profuse/PY
+profuseness/M
+progenitor/SM
+progeny/M
+progesterone/M
+progestin/S
+prognathous
+prognoses
+prognosis/M
+prognostic/MS
+prognosticate/XGNDS
+prognostication/M
+prognosticator/MS
+program/CAS
+programed
+programing
+programmability
+programmable/MS
+programmatic
+programmed/AC
+programmer/MS
+programming/SM
+progress/MDSGV
+progression/MS
+progressive/PMYS
+progressiveness/M
+prohibit/DGVS
+prohibition/SM
+prohibitionist/MS
+prohibitive/Y
+prohibitory
+project/GMDS
+projectile/SM
+projection/SM
+projectionist/SM
+projector/MS
+prokaryote/MS
+prokaryotic
+prole/S
+proletarian/MS
+proletariat/M
+proliferate/DSGN
+proliferation/M
+prolific
+prolifically
+prolix/Y
+prolixity/M
+prologue/SM
+prolongation/SM
+prom/M
+promenade/MGDS
+promethium/M
+prominence/M
+prominent/Y
+promiscuity/M
+promiscuous/Y
+promise/DMG
+promising/Y
+promissory
+promo/M
+promontory/SM
+promote/DRZG
+promoter/M
+promotional
+prompt/JPSMDRYZTG
+prompted/U
+prompter/M
+prompting/M
+promptitude/M
+promptness/M
+promulgate/GNDS
+promulgation/M
+promulgator/MS
+pronate/DSGN
+pronator/SM
+prone/P
+proneness/M
+prong/MDS
+pronghorn/MS
+pronominal/M
+pronounce/DSLG
+pronounceable/U
+pronouncement/SM
+pronto
+pronunciation/MS
+proof/ADGSM
+proofread/SRZG
+proofreader/M
+prop/MS
+propaganda/M
+propagandist/MS
+propagandize/GDS
+propagate/DSGN
+propagation/M
+propagator/SM
+propel/S
+propellant/MS
+propelled
+propeller/SM
+propelling
+propensity/SM
+proper/MRYT
+property/DSM
+prophecy/SM
+prophesier/M
+prophesy/DRSMZG
+prophet/SM
+prophetess/MS
+prophetic
+prophetical/Y
+prophylactic/SM
+prophylaxes
+prophylaxis/M
+propinquity/M
+propitiate/DSGN
+propitiation/M
+propitiatory
+propitious/Y
+proponent/SM
+proportion/ESM
+proportional/YS
+proportionality
+proportionate/EY
+proposal/MS
+propped
+propping
+propranolol
+proprietary/SM
+proprieties/M
+proprietor/SM
+proprietorial/Y
+proprietorship/SM
+proprietress/MS
+propriety/SM
+propulsion/M
+propulsive
+propyl
+prorate/DSGN
+prorogation/M
+prorogue/GD
+prosaic
+prosaically
+proscenium/SM
+prosciutto/M
+proscribe/DG
+proscription/MS
+prose/M
+prosecute/DSBXGN
+prosecution/M
+prosecutor/MS
+prosecutorial
+proselyte/DSMG
+proselytism/M
+proselytize/DRSZG
+proselytizer/M
+prosocial
+prosody/SM
+prospect/MDGVS
+prospective/Y
+prospector/SM
+prospectus/MS
+prosper/GSD
+prosperity/M
+prosperous/Y
+prostate/MS
+prostheses
+prosthesis/M
+prosthetic/S
+prostitute/MGNDS
+prostitution/M
+prostrate/GNXDS
+prostration/M
+prosy/RT
+protactinium/M
+protagonist/SM
+protean
+protect/GVSD
+protected/U
+protection/SM
+protectionism/M
+protectionist/MS
+protective/PY
+protectiveness/M
+protector/MS
+protectorate/MS
+protege/SM
+protegee/S
+protein/SM
+protestant/S
+protestation/MS
+protestor/MS
+prothonotarial
+prothonotary/S
+protocol/MS
+proton/SM
+protoplasm/M
+protoplasmic
+prototype/MGS
+prototypical
+protozoa
+protozoan/MS
+protozoic
+protract/GD
+protrude/GDS
+protrusile
+protrusion/MS
+protuberance/MS
+protuberant
+prot辿g辿/MS
+prot辿g辿e/S
+proud/RYT
+prov/NB
+provability/M
+provably
+prove/EAGDS
+proved/U
+proven/U
+provenance/SM
+provender/M
+provenience/M
+proverbial/Y
+provide/DRSZG
+provided/U
+providence/M
+provident/Y
+providential/Y
+provider/M
+province/MS
+provincial/SMY
+provincialism/M
+provisional/Y
+proviso/SM
+provocateur/S
+provocative/PY
+provocativeness/M
+provoke/DRSZG
+provoked/U
+provoker/M
+provoking/Y
+provolone/M
+provost/SM
+prow/MS
+prowess/M
+prowl/MDRSZG
+prowler/M
+proximal
+proximate
+proximity/M
+proxy/SM
+prude/MS
+prudence/M
+prudent/Y
+prudential/Y
+prudery/M
+prudish/YP
+prudishness/M
+prune/MZGDRS
+pruner/M
+pruno
+prurience/M
+prurient/Y
+pry/ZTGDRSM
+pr辿cis/MDG
+psalm/MS
+psalmist/SM
+psaltery/SM
+psephologist/S
+psephology
+pseud/S
+pseudo/S
+pseudonym/SM
+pseudonymous
+pseudorandom/Y
+pseudoscience/MS
+pseudy
+pshaw/MS
+psi/SM
+psittacosis/M
+psoriasis/M
+psst
+psych/MDSG
+psyche/M
+psychedelia
+psychedelic/SM
+psychedelically
+psychiatric
+psychiatrist/SM
+psychiatry/M
+psychic/MS
+psychical/Y
+psycho/SM
+psychoactive
+psychoanalyses
+psychoanalysis/M
+psychoanalyst/SM
+psychoanalytic
+psychoanalytical/Y
+psychoanalyze/DSG
+psychobabble/M
+psychodrama/MS
+psychogenic
+psychokinesis
+psychokinetic
+psychological/Y
+psychologist/MS
+psychology/SM
+psychometric
+psychomotor
+psychoneuroses
+psychoneurosis/M
+psychopath/M
+psychopathic
+psychopathology
+psychopaths
+psychopathy/M
+psychopharmacology
+psychophysiology
+psychos/S
+psychosis/M
+psychosomatic
+psychotherapist/MS
+psychotherapy/SM
+psychotic/SM
+psychotically
+psychotropic/MS
+psychs
+pt/C
+ptarmigan/MS
+pterodactyl/MS
+ptomaine/SM
+pub/SM
+pubertal
+puberty/M
+pubes/M
+pubescence/M
+pubescent
+pubic
+pubis/M
+public/AM
+publican/AMS
+publication/ASM
+publicist/MS
+publicity/M
+publicize/GDS
+publicly
+publish/AGDS
+publishable
+published/U
+publisher/MS
+publishing/M
+puce/M
+puck/ZMRS
+pucker/MDG
+puckish/YP
+puckishness/M
+pud/S
+pudding/SM
+puddle/DSMG
+puddling/M
+pudenda
+pudendum/M
+pudginess/M
+pudgy/PRT
+pueblo/SM
+puerile
+puerility/M
+puerperal
+puff/ZGMDRS
+puffball/SM
+puffer/M
+puffin/SM
+puffiness/M
+puffy/PRT
+pug/SM
+pugilism/M
+pugilist/SM
+pugilistic
+pugnacious/YP
+pugnaciousness/M
+pugnacity/M
+puke/MGDS
+pukka
+pulchritude/M
+pulchritudinous
+pule/GDS
+pull/ZGMDRS
+pullback/MS
+puller/M
+pullet/SM
+pulley/SM
+pullout/MS
+pullover/SM
+pulmonary
+pulp/GMDS
+pulpiness/M
+pulpit/SM
+pulpwood/M
+pulpy/RPT
+pulsar/SM
+pulsate/XGNDS
+pulsation/M
+pulse/AMGDS
+pulverization/M
+pulverize/DSG
+puma/MS
+pumice/SM
+pummel/SGD
+pump/ZGMDRS
+pumper/M
+pumpernickel/M
+pumpkin/MS
+pun/SM
+punch/MDRSZG
+punchbag/S
+puncheon/MS
+puncher/M
+punchline/S
+punchy/TR
+punctilio/M
+punctilious/PY
+punctiliousness/M
+punctual/Y
+punctuality/M
+punctuate/GNDS
+punctuation/M
+puncture/DSMG
+pundit/SM
+punditry/M
+pungency/M
+pungent/Y
+puniness/M
+punish/BLGDS
+punished/U
+punishing/Y
+punishment/MS
+punitive/Y
+punk/TMRS
+punned
+punnet/S
+punning
+punster/SM
+punt/ZGMDRS
+punter/M
+puny/TRP
+pup/SM
+pupa/M
+pupae
+pupal
+pupate/DSG
+pupil/MS
+pupped
+puppet/MS
+puppeteer/SM
+puppetry/M
+pupping
+puppy/SM
+purblind
+purchase/DRSMZGB
+purchaser/M
+purdah/M
+pure/PYTR
+purebred/SM
+puree/MDS
+pureeing
+pureness/M
+purgative/SM
+purgatorial
+purgatory/SM
+purge/MZGDRS
+purger/M
+purification/M
+purifier/M
+purify/NDRSZG
+purine/MS
+purism/M
+purist/MS
+puristic
+puritan/SM
+puritanical/Y
+puritanism/M
+purity/M
+purl/GMDS
+purlieu/SM
+purloin/SGD
+purple/MTRS
+purplish
+purport/SMDG
+purported/Y
+purpose's
+purpose/ADSG
+purposeful/YP
+purposefulness/M
+purposeless/PY
+purposely
+purr/GMDS
+purse/MZGDRS
+purser/M
+pursuance/M
+pursuant
+pursue/ZGDRS
+pursuer/M
+pursuit/SM
+purulence/M
+purulent
+purvey/DSG
+purveyance/M
+purveyor/SM
+purview/M
+pus/M
+push/ZGMDRS
+pushbike/S
+pushcart/SM
+pushchair/S
+pusher/M
+pushily
+pushiness/M
+pushover/MS
+pushpin/S
+pushup/MS
+pushy/TRP
+pusillanimity/M
+pusillanimous/Y
+puss/MS
+pussy/TRSM
+pussycat/MS
+pussyfoot/DSG
+pustular
+pustule/SM
+put/ISM
+putative
+putdown/SM
+putout/MS
+putrefaction/M
+putrefactive
+putrefy/GDS
+putrescence/M
+putrescent
+putrid
+putsch/MS
+putt/ZGMDRS
+putted/I
+puttee/MS
+putter/MDRZG
+putterer/M
+putting/I
+putty/GDSM
+putz/S
+puzzle/MZGDRSL
+puzzlement/M
+puzzler/M
+pvt
+pwn/SGD
+pyelonephritis
+pygmy/SM
+pylon/SM
+pylori
+pyloric
+pylorus/M
+pyorrhea/M
+pyramid/GSMD
+pyramidal
+pyre/MS
+pyrimidine/MS
+pyrite/SM
+pyrites/M
+pyromania/M
+pyromaniac/SM
+pyrotechnic/S
+pyrotechnical
+pyrotechnics/M
+pyruvate
+python/SM
+pyx/MS
+pzazz
+q
+qr
+qt/S
+qty
+qua
+quack/GMDS
+quackery/M
+quad/MS
+quadrangle/SM
+quadrangular
+quadrant/MS
+quadraphonic
+quadratic/MS
+quadrature
+quadrennial
+quadrennium/MS
+quadriceps/MS
+quadrilateral/SM
+quadrille/XMNS
+quadrillion/M
+quadriplegia/M
+quadriplegic/SM
+quadrivium/M
+quadruped/MS
+quadrupedal
+quadruple/MGDS
+quadruplet/MS
+quadruplicate/MGNDS
+quadruplication/M
+quaff/GMDS
+quagmire/SM
+quahog/MS
+quail/GMDS
+quaint/PRYT
+quaintness/M
+quake/MGDS
+quaky
+qualification/EM
+qualified/U
+qualifier/SM
+qualify/EGXNDS
+qualitative/Y
+quality/SM
+qualm/MS
+qualmish
+quandary/SM
+quango/S
+quanta
+quantifiable
+quantification/M
+quantifier/M
+quantify/NDRSZG
+quantitation
+quantitative/Y
+quantity/SM
+quantization
+quantize/D
+quantum/M
+quarantine/MGDS
+quark/MS
+quarrel/SZGMDR
+quarreler/M
+quarrelsome/P
+quarrelsomeness/M
+quarry/DSMG
+quart/MS
+quarter/SGMDY
+quarterback/GMDS
+quarterdeck/MS
+quarterfinal/SM
+quarterly/SM
+quartermaster/MS
+quarterstaff/M
+quarterstaves
+quartet/SM
+quartile/S
+quarto/MS
+quartz/M
+quasar/MS
+quash/GDS
+quasi
+quatrain/MS
+quaver/MDSG
+quavery
+quay/MS
+quayside/S
+queasily
+queasiness/M
+queasy/TPR
+queen/GMDYS
+queenly/RT
+queer/PTGMDRYS
+queerness/M
+quell/GDS
+quench/ZGDRSB
+quenchable/U
+quencher/M
+quenchless
+querulous/YP
+querulousness/M
+query/DSMG
+ques
+quesadilla/MS
+quest/IFAMS
+quested
+questing
+question/SMDRZGBJ
+questionable/U
+questionably/U
+questioned/U
+questioner/M
+questioning/MY
+questionnaire/SM
+queue's
+queue/CDSG
+quibble/DRSMZG
+quibbler/M
+quiche/SM
+quick/MNRYXTP
+quicken/DG
+quickfire
+quickie/SM
+quicklime/M
+quickness/M
+quicksand/MS
+quicksilver/M
+quickstep/MS
+quid/MS
+quiescence/M
+quiescent/Y
+quiet/SMDNRYXTGP
+quieten/DG
+quietism
+quietness/M
+quietude/IEM
+quietus/MS
+quiff/S
+quill/SM
+quilt/SMDRZG
+quilter/M
+quilting/M
+quin/S
+quince/SM
+quine/S
+quinidine
+quinine/M
+quinoa
+quinsy/M
+quint/SM
+quintessence/SM
+quintessential/Y
+quintet/SM
+quintuple/MGDS
+quintuplet/MS
+quip/MS
+quipped
+quipping
+quipster/SM
+quire's
+quire/IAS
+quirk/SMDG
+quirkiness/M
+quirky/RTP
+quirt/SM
+quisling/SM
+quit/S
+quitclaim/MS
+quite
+quittance/M
+quitter/SM
+quitting
+quiver/SMDG
+quivery
+quixotic
+quixotically
+quiz/M
+quizzed
+quizzer/SM
+quizzes
+quizzical/Y
+quizzing
+quo/H
+quoin/SM
+quoit/SMDG
+quondam
+quorate/I
+quorum/SM
+quot/B
+quota/SM
+quotability/M
+quotation/SM
+quote's
+quote/UDSG
+quotidian
+quotient/SM
+qwerty
+r/S
+rabbet/GMDS
+rabbi/SM
+rabbinate/M
+rabbinic
+rabbinical
+rabbit/GMDS
+rabble/MS
+rabid/PY
+rabidness/M
+rabies/M
+raccoon/MS
+race/MZGDRS
+racecourse/SM
+racegoer/S
+racehorse/MS
+raceme/MS
+racer/M
+racetrack/MS
+raceway/MS
+racial/Y
+racialism/M
+racialist/MS
+racily
+raciness/M
+racing/M
+racism/M
+racist/SM
+rack/GMDS
+racket/SMDG
+racketeer/SMDG
+racketeering/M
+raconteur/SM
+racoon
+racquet/SM
+racquetball/SM
+racy/PRT
+rad/SM
+radar/SM
+radarscope/SM
+raddled
+radial/SMY
+radian/S
+radiance/M
+radiant/Y
+radiate/DSGNX
+radiation/M
+radiator/SM
+radical/SMY
+radicalism/M
+radicalization/M
+radicalize/DSG
+radicchio/M
+radii
+radio/MDGS
+radioactive/Y
+radioactivity/M
+radiocarbon/M
+radiogram/MS
+radiographer/SM
+radiography/M
+radioisotope/MS
+radiologist/SM
+radiology/M
+radioman/M
+radiomen
+radiometer/MS
+radiometric
+radiometry/M
+radiophone/SM
+radioscopy/M
+radiosonde/SM
+radiosurgery
+radiotelegraph/M
+radiotelegraphs
+radiotelegraphy/M
+radiotelephone/MS
+radiotherapist/MS
+radiotherapy/M
+radish/MS
+radium/M
+radius/M
+radon/M
+raffia/M
+raffish/YP
+raffishness/M
+raffle/DSMG
+raft/ZGMDRS
+rafter/M
+rafting/M
+rag/SGMD
+raga/MS
+ragamuffin/MS
+ragbag/M
+rage/MS
+ragga
+ragged/RYTP
+raggedness/M
+raggedy/RT
+ragging
+raging/Y
+raglan/SM
+ragout/SM
+ragtag/S
+ragtime/M
+ragweed/M
+ragwort
+rah
+raid/ZGMDRS
+raider/M
+rail's
+rail/CGDS
+railcard/S
+railing/SM
+raillery/SM
+railroad/SZGMDR
+railroader/M
+railroading/M
+railway/SM
+railwayman
+railwaymen
+raiment/M
+rain/GMDS
+rainbow/SM
+raincoat/SM
+raindrop/SM
+rainfall/SM
+rainmaker/SM
+rainmaking/M
+rainproof
+rainstorm/MS
+rainwater/M
+rainy/RT
+raise/MZGDRS
+raiser/M
+raisin/SM
+raja/MS
+rajah/M
+rajahs
+rake/MGDS
+rakish/YP
+rakishness/M
+rally/DSMG
+ram/SMN
+ramble/DRSMZGJ
+rambler/M
+rambunctious/PY
+rambunctiousness/M
+rambutan/S
+ramekin/SM
+ramie/M
+ramification/M
+ramify/DSXNG
+ramjet/SM
+rammed
+ramming
+ramp/GMDS
+rampage/DSMG
+rampancy/M
+rampant/Y
+rampart/SM
+ramrod/SM
+ramrodded
+ramrodding
+ramshackle
+ran/A
+ranch/MDRSZG
+rancher/M
+ranching/M
+rancid/P
+rancidity/M
+rancidness/M
+rancor/M
+rancorous/Y
+rand/M
+randiness/M
+rando/S
+random/PSY
+randomization/M
+randomize/DSG
+randomness/MS
+randy/RTP
+ranee/MS
+rang/ZR
+range's
+range/CGDS
+rangefinder/S
+ranger/M
+ranginess/M
+rangy/RTP
+rani/MS
+rank/TGJPMDRYS
+ranking/M
+rankle/DSG
+rankness/M
+ransack/SGD
+ransom/SZGMDR
+ransomer/M
+ransomware
+rant/ZGMDJRS
+ranter/M
+rap/SZGMDR
+rapacious/PY
+rapaciousness/M
+rapacity/M
+rape/MS
+raper/M
+rapeseed/M
+rapid/PMRYTS
+rapidity/M
+rapidness/M
+rapier/SM
+rapine/M
+rapist/SM
+rapped
+rappel/SM
+rappelled
+rappelling
+rapper/SM
+rapping
+rapport/MS
+rapporteur/S
+rapprochement/SM
+rapscallion/MS
+rapt/YP
+raptness/M
+raptor/S
+rapture/MS
+rapturous/Y
+rare/YTGPDRS
+rarebit/MS
+rarefaction/M
+rarefy/GDS
+rareness/M
+rarity/SM
+rascal/SMY
+rash/ZTMRSYP
+rasher/M
+rashness/M
+rasp/GMDS
+raspberry/SM
+raspy/RT
+raster
+rasterization/M
+rasterize/DRSG
+rat/SM
+ratatouille/M
+ratbag/S
+ratchet/GMDS
+rate/JXMZGNDRS
+rated/U
+ratepayer/S
+rater/M
+rather
+rathskeller/SM
+ratification/M
+ratifier/M
+ratify/NDRSZG
+rating/M
+ratio/MS
+ratiocinate/GNDS
+ratiocination/M
+ration/MDG
+rational/SMY
+rationale/MS
+rationalism/M
+rationalist/SM
+rationalistic
+rationality/M
+rationalization/MS
+rationalize/DSG
+ratlike
+ratline/SM
+rattan/SM
+ratted
+ratter/SM
+ratting
+rattle/DRSMZGJ
+rattlebrain/SMD
+rattler/M
+rattlesnake/SM
+rattletrap/SM
+rattly
+rattrap/SM
+ratty/RT
+raucous/YP
+raucousness/M
+raunchily
+raunchiness/M
+raunchy/TRP
+ravage/DRSMZG
+ravager/M
+ravages/M
+rave/JMZGDRS
+ravel's
+ravel/UDSG
+raveling/S
+raven/MDSG
+ravenous/Y
+ravine/SM
+raving/M
+ravioli/SM
+ravish/DRSZGL
+ravisher/M
+ravishing/Y
+ravishment/M
+raw/PTMR
+rawboned
+rawhide/M
+rawness/M
+ray/SM
+rayon/M
+raze/GDS
+razor/MS
+razorback/MS
+razz/GMDS
+razzmatazz/M
+rcpt
+rd
+re/DSMYTGVJ
+reach/MDSGB
+reachable/U
+reacquire/DSG
+react/V
+reactance
+reactant/SM
+reactionary/SM
+reactivity/M
+read/ZGMRBJS
+readability/SM
+reader/M
+readership/SM
+readily
+readiness/M
+reading/M
+readmitted
+readout/SM
+ready/DRSTGP
+reafforestation
+real/TMRYPS
+realism/M
+realist/SM
+realistic/U
+realistically/U
+realities
+reality/UM
+realization/MS
+realize/DSBG
+realized/U
+realm/MS
+realness/M
+realpolitik/M
+realtor/SM
+realty/M
+ream/ZGMDRS
+reamer/M
+reap/ZGDRS
+reaper/M
+rear/GMDS
+rearguard/MS
+rearmost
+rearward/S
+reason/SMDRZGB
+reasonable/UP
+reasonableness/UM
+reasonably/U
+reasoner/M
+reasoning/M
+reassemble/DSG
+reassuring/Y
+rebate/M
+rebel/MS
+rebellion/MS
+rebellious/YP
+rebelliousness/M
+rebid/S
+rebidding
+rebirth/M
+reboil/SDG
+rebrand/G
+rebuild/SG
+rebuke/DSMG
+rebuking/Y
+rebuttable
+rebuttal/MS
+rec'd
+rec/M
+recalcitrance/M
+recalcitrant
+recant/SDG
+recantation/SM
+recap/MS
+recapitalization
+recce/S
+recd
+receipt/SMDG
+receivables/M
+receive/DRSZGB
+receiver/M
+receivership/M
+recency
+recent/RYTP
+recentness/M
+receptacle/SM
+reception/MS
+receptionist/SM
+receptive/PY
+receptiveness/M
+receptivity/M
+receptor/SM
+recess/MDSGV
+recessional/SM
+recessionary
+recessive/SM
+recherche
+recherch辿
+recidivism/M
+recidivist/SM
+recipe/SM
+recipient/SM
+reciprocal/SMY
+reciprocate/GNDS
+reciprocation/M
+reciprocity/M
+recital/SM
+recitalist/MS
+recitative/MS
+reciter/SM
+reckless/YP
+recklessness/M
+reckon/SJDG
+reckoning/M
+reclamation/M
+recline/DRSZG
+recliner/M
+recluse/SMV
+recognizable/U
+recognizably/U
+recognize/DRSGB
+recognized/U
+recoilless
+recombination
+recommend/ZR
+recompense/DSMG
+recompile/GD
+recon/S
+reconcile/GDSB
+reconciliation/S
+recondite
+reconfiguration
+reconnaissance/MS
+reconnoiter/DGS
+reconstruct/V
+reconstructed/U
+recorded/U
+recorder/MS
+recording/MS
+recoup/DG
+recourse/M
+recoverable/U
+recovery/SM
+recreant/MS
+recreational
+recriminate/DSGNX
+recrimination/M
+recriminatory
+recrudesce/GDS
+recrudescence/M
+recrudescent
+recruit/LSMDRZG
+recruiter/M
+recruitment/M
+rectal/Y
+rectangle/MS
+rectangular
+rectifiable
+rectification/M
+rectifier/M
+rectify/XNDRSZG
+rectilinear
+rectitude/M
+recto/MS
+rector/SM
+rectory/SM
+rectum/SM
+recumbent
+recuperate/GNVDS
+recuperation/M
+recur/S
+recurred
+recurrence/SM
+recurrent/Y
+recurring
+recurse/XNV
+recusal/S
+recuse/DSG
+recyclable/SM
+recycling/M
+red/PSM
+redact/SDG
+redacted/U
+redaction/SM
+redactor/SM
+redbird/SM
+redbreast/MS
+redbrick
+redcap/SM
+redcoat/SM
+redcurrant/S
+redden/SDG
+redder
+reddest
+reddish
+redeem/RZB
+redeemer/M
+redemption/M
+redemptive
+redesign/DSG
+redhead/SMD
+redirection
+redistrict/GD
+redivide/GDS
+redlining/M
+redneck/SM
+redness/M
+redo/G
+redolence/M
+redolent
+redoubt/SBM
+redoubtably
+redound/SDG
+redraw/SG
+redskin/SM
+reduce/DRSZG
+reducer/M
+reducible
+reductase/M
+reduction/SM
+reductionist
+reductive
+redundancy/SM
+redundant/Y
+redwood/SM
+redye/DS
+reediness/M
+reedy/RTP
+reef/ZGMDRS
+reefer/M
+reek/GMDS
+reel's
+reel/UGDS
+reeve/G
+reexport/SDG
+ref/SZM
+refashion/DGS
+refection/M
+refectory/SM
+refer/B
+referee/DSM
+refereeing
+reference/MGDS
+referendum/MS
+referent/SM
+referential
+referral/SM
+referred
+referrer/SM
+referring
+reffed
+reffing
+refile/DSG
+refill/BM
+refined/U
+refinement/SM
+refiner/SM
+refinery/S
+refitting
+reflate/XDSGN
+reflationary
+reflect/GVSD
+reflection/MS
+reflective/Y
+reflectivity
+reflector/MS
+reflexive/SMY
+reflexivity
+reflexology
+reforge/DSG
+reform/MZ
+reformat/V
+reformatory/SM
+reformatting
+reformed/U
+reformist/S
+refortify/GDS
+refract/SGVD
+refraction/M
+refractory/SM
+refrain/SGMD
+refresh/ZGLDRS
+refresher/M
+refreshing/Y
+refreshment/SM
+refreshments/M
+refrigerant/SM
+refrigerate/DSGN
+refrigeration/M
+refrigerator/MS
+refuge/SM
+refugee/SM
+refulgence/M
+refulgent
+refund/B
+refurbishment/MS
+refusal/MS
+refutation/MS
+refute/BDRSZG
+refuter/M
+reg
+regal/DYG
+regalement/M
+regalia/M
+regard/ESMDG
+regardless
+regards/M
+regather/DGS
+regatta/SM
+regency/SM
+regeneracy/M
+regenerate/V
+regex/M
+regexp/S
+reggae/M
+regicidal
+regicide/MS
+regime/SM
+regimen/SM
+regiment/MDGS
+regimental
+regimentation/M
+region/SM
+regional/Y
+regionalism/MS
+register/GMDS
+registered/U
+registrant/MS
+registrar/MS
+registration/SM
+registry/SM
+reglet
+regnant
+regress/MDSGV
+regression/MS
+regret/SM
+regretful/Y
+regrettable
+regrettably
+regretted
+regretting
+regrind/GS
+reground
+regroup/DGS
+regular/MYS
+regularity/SM
+regularization/M
+regularize/DSG
+regulate/CDSGNV
+regulated/U
+regulation/CM
+regulations
+regulator/MS
+regulatory
+regurgitate/DSGN
+regurgitation/M
+rehab/MS
+rehabbed
+rehabbing
+rehabilitate/GNVDS
+rehabilitation/M
+rehang/SDG
+rehears/GD
+rehearsal/MS
+rehearsed/U
+rehi
+rehung
+reify/NDSG
+reign/MDSG
+reignite/DSG
+reimburse/BDSGL
+reimbursement/MS
+rein/GD
+reindeer/M
+reinforce/LGDS
+reinforcement/SM
+reinitialize
+reinstall/DG
+reinstatement/M
+reinsurance
+reiterate/V
+reject/GSMD
+rejection/SM
+rejoice/JGDS
+rejoicing/M
+rejoinder/SM
+rejuvenate/DSGN
+rejuvenation/M
+rel
+relate/DRSBXZGNV
+related/YP
+relatedness/M
+relater/M
+relation/M
+relational
+relationship/MS
+relative/MYS
+relativism/M
+relativist/S
+relativistic
+relativity/M
+relax/DRSZG
+relaxant/MS
+relaxation/SM
+relaxer/M
+relay/D
+release/B
+released/U
+relegate/GNDS
+relent/SGD
+relentless/PY
+relentlessness/M
+relevance/M
+relevancy/M
+relevant/Y
+reliability/UM
+reliable/U
+reliably/U
+reliance/M
+reliant
+relic/MS
+relict/CSM
+relief/SM
+relieve/ZGDRS
+reliever/M
+religion/SM
+religiosity
+religious/MYP
+religiousness/M
+reline/DSG
+relinquish/LDSG
+relinquishment/M
+reliquary/SM
+relish/GMDS
+relist/SGD
+relocate/B
+reluctance/M
+reluctant/Y
+rely/GDS
+rem/M
+remain/SGD
+remainder/GMDS
+remand/SGD
+remapping
+remark/B
+remarkableness/M
+remarkably
+remarked/U
+remeasure/GDS
+remediable
+remedy/GDSM
+remember/DG
+remembered/U
+remembrance/MS
+reminder/M
+reminisce/GDS
+reminiscence/MS
+reminiscent/Y
+remiss/PY
+remissness/M
+remit/S
+remittance/SM
+remitted
+remitting/U
+remix/DSG
+remnant/MS
+remodel/GDS
+remold/SGD
+remonstrant/SM
+remonstrate/DSG
+remorse/M
+remorseful/Y
+remorseless/PY
+remorselessness/M
+remote/RSMYTP
+remoteness/M
+removal/SM
+remunerate/GNVXDS
+remuneration/M
+renaissance/MS
+renal
+renascence/S
+rend/GS
+render/SZGMDRJ
+renderer/M
+rendering/M
+rendezvous/GMDS
+rendition/MS
+renegade/DSMG
+renege/DRSZG
+reneger/M
+renew/DSBG
+renewable/S
+renewal/MS
+rennet/M
+rennin/M
+renounce/LDSG
+renouncement/M
+renovate/DSXGN
+renovation/M
+renovator/MS
+renown/MD
+rent/ZGMDRS
+rental/SM
+renter/M
+renunciation/SM
+reopen/SDG
+reorg/MDSG
+rep/SM
+repaint/GDS
+repair/BZR
+repairer/M
+repairman/M
+repairmen
+reparable
+reparation/MS
+reparations/M
+repartee/M
+repatriate/XDSMGN
+repatriation/M
+repeat/SMDRZGB
+repeatability
+repeatable/U
+repeatably
+repeated/Y
+repeater/M
+repeating/M
+repel/S
+repelled
+repellent/SM
+repelling
+repent/SDG
+repentance/M
+repentant/Y
+repercussion/S
+repertoire/MS
+repertory/SM
+repetition/MS
+repetitious/YP
+repetitiousness/M
+repetitive/YP
+repetitiveness/M
+rephotograph/DG
+replaceable
+replant/GSD
+replenish/LGDS
+replenishment/M
+replete/PDSGN
+repleteness/M
+repletion/M
+replica/SM
+replicate/DSGNX
+replication/M
+replicator/S
+reportage/M
+reported/Y
+reportorial
+reposeful
+reposition
+repository/SM
+reprehend/DGS
+reprehensibility/M
+reprehensible
+reprehensibly
+reprehension/M
+represent/GDS
+representational
+representative/MS
+represented/U
+repression/MS
+repressive/PY
+reprieve/DSMG
+reprimand/GSMD
+reprisal/SM
+reprise/SMG
+reproach/GMDSB
+reproachful/Y
+reprobate/MS
+reproducibility
+reproductive
+reprogramming
+reproving/Y
+reptile/SM
+reptilian/MS
+republic/S
+republicanism/M
+repudiate/XGNDS
+repudiation/M
+repudiator/MS
+repugnance/M
+repugnant
+repulsion/M
+repulsive/YP
+repulsiveness/M
+repurchase/GDS
+reputability/M
+reputably/E
+reputation/MS
+reputational
+repute/DSMGB
+reputed/Y
+request/GDR
+requestor
+requiem/SM
+require/LDG
+requirement/MS
+requisite/XMNS
+requisition/GMD
+requital/M
+requite/DRSZG
+requited/U
+requiter/M
+reread/SG
+rerecord/GDS
+rerunning
+resample/GDS
+resat
+rescind/SDG
+rescission/M
+rescue/DRSMZG
+rescuer/M
+reseal/B
+resemble/DSG
+resend
+resent/LSDG
+resentful/YP
+resentfulness/M
+resentment/MS
+reserpine/M
+reservation/MS
+reserved/UY
+reservedness/M
+reservist/SM
+reservoir/SM
+resetting
+reshipping
+residence/SM
+residency/SM
+resident/MS
+residential
+residua
+residual/MS
+residue/SM
+residuum/M
+resignation/SM
+resigned/Y
+resilience/M
+resiliency/M
+resilient/Y
+resinous
+resist/SMDRZGV
+resistance/SM
+resistant/U
+resistible
+resistive/YP
+resistivity
+resistless
+resistor/MS
+resit/S
+resitting
+resold
+resole/DSG
+resolute/PY
+resoluteness/M
+resolve/RBM
+resolved/U
+resonance/SM
+resonant/Y
+resonate/GDS
+resonator/SM
+resorption/M
+resound/SGD
+resounding/Y
+resourceful/YP
+resourcefulness/M
+resp
+respect/ESGVMD
+respectability/M
+respectable
+respectably
+respectful/EY
+respectfulness/M
+respective/Y
+respiration/M
+respirator/SM
+respiratory
+respire/DG
+resplendence/M
+resplendent/Y
+respond/SZGDR
+respondent/SM
+responder/M
+response/MS
+responsibility/SM
+responsible
+responsibly
+responsive/UYP
+responsiveness/UM
+responsivity/M
+rest/GVMDS
+restate/GDS
+restaurant/SM
+restaurateur/MS
+restful/YP
+restfuller
+restfullest
+restfulness/M
+restitution/M
+restive/YP
+restiveness/M
+restless/PY
+restlessness/M
+restoration/SM
+restorative/SM
+restorer/SM
+restrained/U
+restraint/MS
+restrict/SDGV
+restricted/U
+restriction/MS
+restrictive/YP
+restrictiveness/M
+restring/SG
+restroom/SM
+restructuring/SM
+result/GSMD
+resultant/SM
+resume/DSMG
+resumption/MS
+resupply/DSG
+resurgence/MS
+resurgent
+resurrect/GSD
+resurrection/MS
+resuscitate/GNDS
+resuscitation/M
+resuscitator/SM
+retailer/MS
+retain/SDRZG
+retainage/S
+retainer/M
+retake/G
+retaliate/DSGNVX
+retaliation/M
+retaliatory
+retard/SMDRZG
+retardant/SM
+retardation/M
+retarder/M
+retch/DSG
+reteach/GS
+retention/M
+retentive/YP
+retentiveness/M
+rethink/SGM
+rethought
+reticence/M
+reticent/Y
+reticle/SM
+reticulated
+reticulation/MS
+reticulum
+retina/SM
+retinal
+retinoblastoma
+retinue/SM
+retiree/SM
+retirement/MS
+retort/GMD
+retrace/GDS
+retract/DBG
+retractile
+retraction/S
+retrain/DGS
+retread/D
+retrenchment/MS
+retribution/MS
+retributive
+retrieval/SM
+retrieve/DRSMZGB
+retriever/M
+retro/MS
+retroactive/Y
+retrofire/GDS
+retrofit/SM
+retrofitted
+retrofitting
+retrograde/DSG
+retrogress/GVDS
+retrogression/M
+retroreflector/S
+retrorocket/MS
+retrospect/MDSGV
+retrospection/M
+retrospective/MYS
+retrovirus/MS
+retsina/M
+returnable/SM
+returnee/SM
+rev/ZVM
+revamping/M
+reveal/GJSD
+revealed/U
+revealing/Y
+reveille/M
+revel/JMDRSZG
+revelation/SM
+revelatory
+reveler/M
+revelry/SM
+revenge/MGDS
+revenuer/SM
+reverb
+reverberate/DSGNX
+reverberation/M
+revere/DSG
+reverence/DSMG
+reverend/SM
+reverent/Y
+reverential/Y
+reverie/MS
+revers/M
+reversal/SM
+reverse/Y
+reversibility
+reversible
+reversibly
+revert/GSD
+revertible
+revetment/SM
+reviewability
+revile/DRSLZG
+revilement/M
+reviler/M
+reviser/MS
+revision/SM
+revisionism/M
+revisionist/SM
+revival/MS
+revivalism/M
+revivalist/SM
+revive/DSG
+revivification/M
+revocable
+revoke/DSG
+revolt/GD
+revolting/Y
+revolution/SM
+revolutionary/SM
+revolutionist/SM
+revolutionize/DSG
+revolve/BZGDRS
+revolver/M
+revue/MS
+revulsion/M
+revved
+revving
+rewarded/U
+rewarding/U
+rewarm/GSD
+rewash/GDS
+reweave/GS
+rewedding
+rewind/MB
+rewound
+rewrite/MGS
+rhapsodic
+rhapsodical
+rhapsodize/GDS
+rhapsody/SM
+rhea/MS
+rhenium/M
+rheostat/SM
+rhesus/MS
+rhetoric/M
+rhetorical/Y
+rhetorician/SM
+rheum/M
+rheumatic/MS
+rheumatically
+rheumatism/M
+rheumatoid
+rheumatological
+rheumatologist/MS
+rheumatology/M
+rheumy
+rhinestone/SM
+rhinitis/M
+rhino/MS
+rhinoceros/MS
+rhinoplasty
+rhinovirus/MS
+rhizome/MS
+rho/SM
+rhodium/M
+rhododendron/SM
+rhomboid/SM
+rhomboidal
+rhombus/MS
+rhubarb/MS
+rhyme/MZGDRS
+rhymer/M
+rhymester/MS
+rhythm/SM
+rhythmic
+rhythmical/Y
+rial/MS
+rib/SM
+ribald
+ribaldry/M
+ribbed
+ribber/SM
+ribbie/S
+ribbing
+ribbon/SM
+riboflavin/M
+rice/MZGDRS
+ricer/M
+rich/TMRSYP
+richness/M
+rick/GMDS
+rickets/M
+rickety/RT
+rickrack/M
+rickshaw/MS
+ricochet/GMDS
+ricotta/M
+rid/S
+riddance/M
+ridden
+ridding
+riddle/DSMG
+ride/MZGRS
+rider/M
+riderless
+ridership/M
+ridge/MGDS
+ridgepole/SM
+ridgy
+ridicule/MGDS
+ridiculous/YP
+ridiculousness/M
+riding/M
+rife/TR
+riff/GMDS
+riffle/DSMG
+riffraff/M
+rifle/MZGDRS
+rifleman/M
+riflemen
+rifler/M
+rifling/M
+rift/GMDS
+rig/SM
+rigamarole/SM
+rigatoni/M
+rigged
+rigger/SM
+rigging/M
+right/MDRYSPTG
+righteous/UP
+righteously
+righteousness/UM
+rightful/PY
+rightfulness/M
+rightism/M
+rightist/SM
+rightmost
+rightness/M
+righto
+rightsize/DSG
+rightward/S
+rigid/YP
+rigidity/M
+rigidness/M
+rigmarole/MS
+rigor/MS
+rigorous/YP
+rigorousness/M
+rile/GDS
+rill/MS
+rim/SGMD
+rime/MS
+rimless
+rimmed
+rimming
+rind/MS
+ring/ZGMDRJ
+ringer/M
+ringgit/MS
+ringleader/MS
+ringlet/MS
+ringlike
+ringmaster/MS
+ringside/M
+ringtone/SM
+ringworm/M
+rink/MS
+rinse/MGDS
+riot/ZGMDRS
+rioter/M
+rioting/M
+riotous/PY
+rip/SXTMNR
+riparian
+ripcord/MS
+ripe/YP
+ripen/DG
+ripened/U
+ripeness/M
+ripoff/SM
+riposte/MGDS
+ripped
+ripper/SM
+ripping
+ripple/DSMG
+ripply
+ripsaw/SM
+riptide/MS
+rise/JMZGRS
+risen
+riser/M
+risibility/M
+risible
+rising/M
+risk/GMDS
+riskily
+riskiness/M
+risky/RPT
+risotto/MS
+risque
+risqu辿
+rissole/S
+rite/MS
+ritual/SMY
+ritualism/M
+ritualistic
+ritualistically
+ritualized
+ritzy/RT
+riv/ZNR
+rival/MDSG
+rivaled/U
+rivalry/SM
+rive/CGDS
+river/M
+riverbank/SM
+riverbed/MS
+riverboat/SM
+riverfront
+riverside/MS
+rivet/MDRSZG
+riveter/M
+riviera/S
+rivulet/MS
+riyal/MS
+rm
+roach/GMDS
+road/IMS
+roadbed/SM
+roadblock/MDSG
+roadhouse/SM
+roadie/MS
+roadkill/M
+roadmap/S
+roadrunner/SM
+roadshow/SM
+roadside/SM
+roadster/SM
+roadway/SM
+roadwork/SM
+roadworthy
+roam/ZGDRS
+roamer/M
+roaming/M
+roan/MS
+roar/ZGMDRS
+roarer/M
+roaring/M
+roast/ZGMDRSJ
+roaster/M
+roasting/M
+rob/S
+robbed
+robber/MS
+robbery/SM
+robbing
+robe's
+robe/EGDS
+robin/MS
+robocall/SGMD
+robot/MS
+robotic/S
+robotics/M
+robotize/GDS
+robust/RYPT
+robustness/M
+rock/ZGMDRS
+rockabilly/M
+rockbound
+rocker/M
+rockery/S
+rocket/MDSG
+rocketry/M
+rockfall/SM
+rockiness/M
+rocky/TRP
+rococo/M
+rod/SM
+rode
+rodent/MS
+rodeo/MS
+roe/SM
+roebuck/SM
+roentgen/MS
+roger/GDS
+rogue's
+rogue/KS
+roguery/M
+roguish/YP
+roguishness/M
+roil/GDS
+roister/ZGDRS
+roisterer/M
+role/MS
+roll/MDRZGJS
+rollback/SM
+roller/M
+rollerblading
+rollerskating/M
+rollick/SDG
+rollicking/M
+rollmop/S
+rollout
+rollover/SM
+romaine/MS
+roman/M
+romance/MZGDRS
+romancer/M
+romantic/MS
+romantically
+romanticism/M
+romanticist/SM
+romanticize/DSG
+romeo/MS
+romp/MDRZGS
+romper/M
+rondo/SM
+rood/MS
+roof/MDRZGS
+roofer/M
+roofing/M
+roofless
+rooftop/SM
+rook/MDGS
+rookery/SM
+rookie/SM
+room/MDRZGS
+roomer/M
+roomette/SM
+roomful/SM
+roominess/M
+roommate/SM
+roomy/RTP
+roost/SMDRZG
+rooster/M
+root/MDRZGS
+rooter/M
+rootkit/SM
+rootless/P
+rootlet/SM
+rope/MZGDRS
+roper/M
+ropy/RT
+rosary/SM
+rose/MS
+roseate
+rosebud/SM
+rosebush/MS
+rosemary/M
+rosette/SM
+rosewater/M
+rosewood/MS
+rosily
+rosin/SMDG
+rosiness/M
+roster/SM
+rostrum/MS
+rosy/RTP
+rot/SM
+rota/S
+rotary/SM
+rotatably
+rotate/DSGNBX
+rotation/M
+rotational
+rotator
+rotatory
+rote/M
+rotgut/M
+rotisserie/SM
+rotogravure/MS
+rotor/SM
+rototiller/MS
+rotted
+rotten/TPRY
+rottenness/M
+rotter/S
+rotting
+rottweiler/S
+rotund/P
+rotunda/MS
+rotundity/M
+rotundness/M
+roue/MS
+rouge/DSMG
+rough/MDNRYXTGP
+roughage/M
+roughcast
+roughen/GD
+roughhouse/MGDS
+roughneck/GMDS
+roughness/M
+roughs
+roughshod
+roulette/M
+round/PSMDRYZTG
+roundabout/SM
+roundel/S
+roundelay/MS
+roundhouse/SM
+roundish
+roundness/M
+roundup/MS
+roundworm/SM
+rouse/DSG
+roust/SDG
+roustabout/SM
+rout/MRZS
+route's
+route/ADSG
+routeing
+router/M
+routine/MYS
+routinize/GDS
+roux
+rou辿/MS
+rove/ZGDRS
+rover/M
+row/SZGMDR
+rowan/S
+rowboat/MS
+rowdily
+rowdiness/M
+rowdy/PRSMT
+rowdyism/M
+rowel/SMDG
+rower/M
+rowing/M
+rowlock/S
+royal/SMY
+royalist/SM
+royalties/M
+royalty/SM
+rpm
+rps
+rt
+rte
+rub/SM
+rubato/SM
+rubbed
+rubber/SM
+rubberize/GDS
+rubberneck/MDRSZG
+rubbernecker/M
+rubbery
+rubbing/S
+rubbish/MDSG
+rubbishy
+rubble/M
+rubdown/SM
+rube/MS
+rubella/M
+rubicund
+rubidium/M
+ruble/SM
+rubric/SM
+ruby/RSMT
+ruched
+ruck/DGS
+rucksack/MS
+ruckus/MS
+ructions
+rudder/SM
+rudderless
+ruddiness/M
+ruddy/RTP
+rude/YTRP
+rudeness/M
+rudiment/SM
+rudimentary
+rue/DSMG
+rueful/PY
+ruefulness/M
+ruff/MDYGS
+ruffian/MYS
+ruffle/DSMG
+ruffled/U
+rug/SM
+rugby/M
+rugged/PTRY
+ruggedness/M
+rugger
+rugrat/SM
+ruin/MDGS
+ruination/M
+ruinous/Y
+rule/MZGJDRS
+ruler/M
+ruling/M
+rum/SM
+rumba/SMDG
+rumble/DSJMG
+rumbling/M
+rumbustious
+ruminant/MS
+ruminate/XGNVDS
+rumination/M
+ruminative/Y
+rummage/DSMG
+rummer
+rummest
+rummy/M
+rumor/SMDG
+rumormonger/SM
+rump/MYS
+rumple/DSMG
+rumpus/MS
+run/ASM
+runabout/MS
+runaround/SM
+runaway/MS
+rundown/SM
+rune/MS
+rung/MS
+runic
+runlet/SM
+runnel/SM
+runner/SM
+running/M
+runny/RT
+runoff/SM
+runt/MS
+runtime
+runty/RT
+runway/SM
+rupee/SM
+rupiah/M
+rupiahs
+rupture/MGDS
+rural
+ruse/MS
+rush/MDRSZG
+rusher/M
+rushy
+rusk/MS
+russet/SM
+rust/MDGS
+rustic/SM
+rustically
+rusticate/GDS
+rustication/M
+rusticity/M
+rustiness/M
+rustle/DRSJMZG
+rustler/M
+rustproof/SDG
+rusty/RPNT
+rut/SM
+rutabaga/SM
+ruthenium/M
+rutherfordium/M
+ruthless/YP
+ruthlessness/M
+rutted
+rutting
+rutty/RT
+rye/M
+s/NYXB
+sabbath/M
+sabbaths
+sabbatical/SM
+saber/MS
+sable/MS
+sabot/MS
+sabotage/DSMG
+saboteur/SM
+sabra/MS
+sabre/MS
+sac/SM
+saccharin/M
+saccharine
+sacerdotal
+sachem/SM
+sachet/SM
+sack/ZGMDRJS
+sackcloth/M
+sacker/M
+sackful/MS
+sacking/M
+sacra
+sacrament/MS
+sacramental
+sacred/YP
+sacredness/M
+sacrifice/DSMG
+sacrificial/Y
+sacrilege/MS
+sacrilegious/Y
+sacristan/MS
+sacristy/SM
+sacroiliac/MS
+sacrosanct/P
+sacrosanctness/M
+sacrum/M
+sad/PY
+sadden/SDG
+sadder
+saddest
+saddle's
+saddle/UDSG
+saddlebag/MS
+saddler/S
+saddlery
+sades
+sadhu/S
+sadism/M
+sadist/SM
+sadistic
+sadistically
+sadness/M
+sadomasochism/M
+sadomasochist/MS
+sadomasochistic
+safari/SGMD
+safe/MYTPRS
+safeguard/SMDG
+safekeeping/M
+safeness/M
+safety/SM
+safflower/MS
+saffron/MS
+sag/SM
+saga/MS
+sagacious/Y
+sagacity/M
+sage/MYTRS
+sagebrush/M
+sagged
+sagging
+saggy/RT
+sago/M
+saguaro/MS
+sahib/MS
+said/U
+sail/GMDSJ
+sailboard/MRZGS
+sailboarder/M
+sailboarding/M
+sailboat/MS
+sailcloth/M
+sailfish/MS
+sailing/M
+sailor/SM
+sailplane/MS
+saint/MDYS
+sainthood/M
+saintlike
+saintliness/M
+saintly/PRT
+saith
+sake/M
+saki/M
+salaam/SMDG
+salability
+salable/U
+salacious/PY
+salaciousness/M
+salacity/M
+salad/MS
+salamander/SM
+salami/SM
+salary/DSM
+sale/ABMS
+saleable/U
+saleroom/S
+salesclerk/SM
+salesgirl/SM
+saleslady/SM
+salesman/M
+salesmanship/M
+salesmen
+salespeople/M
+salesperson/MS
+salesroom/S
+saleswoman/M
+saleswomen
+salience/M
+salient/SMY
+saline/SM
+salinity/M
+saliva/M
+salivary
+salivate/GNDS
+salivation/M
+sallow/RTP
+sallowness/M
+sally/DSMG
+salmon/SM
+salmonella/M
+salmonellae
+salon/MS
+saloon/SM
+salsa/MS
+salt's
+salt/CTGDS
+saltbox/MS
+saltcellar/SM
+salted/U
+salter
+saltine/SM
+saltiness/M
+saltpeter/M
+saltshaker/SM
+saltwater/M
+salty/RTP
+salubrious/I
+salutary
+salutation/MS
+salutatorian/MS
+salutatory
+salute/DSMG
+salvage/DSMG
+salvageable
+salvation/M
+salve/MZGDRS
+salver/M
+salvo/MS
+samarium/M
+samba/MDSG
+same/SP
+sameness/M
+samey
+samizdat/S
+samosa/S
+samovar/SM
+sampan/SM
+sample/DRSMZGJ
+sampler/M
+sampling/M
+samurai/SM
+sanatorium/SM
+sanctification/M
+sanctify/GDSN
+sanctimonious/YP
+sanctimoniousness/M
+sanctimony/M
+sanction/GSMD
+sanctioned/U
+sanctity/M
+sanctuary/SM
+sanctum/SM
+sand/ZGMDRS
+sandal/SM
+sandalwood/M
+sandbag/SM
+sandbagged
+sandbagger/SM
+sandbagging
+sandbank/MS
+sandbar/SM
+sandblast/ZGMDRS
+sandblaster/M
+sandbox/MS
+sandcastle/MS
+sander/M
+sandhog/SM
+sandiness/M
+sandlot/SM
+sandlotter/MS
+sandman/M
+sandmen
+sandpaper/GMDS
+sandpiper/MS
+sandpit/S
+sandstone/M
+sandstorm/SM
+sandwich/MDSG
+sandy/RTP
+sane/IYTR
+saneness/M
+sang/S
+sangfroid/M
+sangria/M
+sanguinary
+sanguine/Y
+sanitarian/SM
+sanitarium/SM
+sanitary/IU
+sanitation/M
+sanitize/ZGDRS
+sanity/IM
+sank
+sans
+sanserif
+sap/SM
+sapience/M
+sapiens
+sapient
+sapless
+sapling/MS
+sapped
+sapper/S
+sapphire/SM
+sappiness/M
+sapping
+sappy/PRT
+saprophyte/SM
+saprophytic
+sapsucker/SM
+sapwood/M
+saran/M
+sarcasm/MS
+sarcastic
+sarcastically
+sarcoma/MS
+sarcophagi
+sarcophagus/M
+sardine/MS
+sardonic
+sardonically
+sarge/MS
+sari/MS
+sarky
+sarnie/S
+sarong/SM
+sarsaparilla/MS
+sartorial/Y
+sash/MS
+sashay/SGMD
+sass/GMDS
+sassafras/MS
+sassy/RT
+sat
+satanic
+satanical/Y
+satanism/M
+satanist/MS
+satay
+satchel/MS
+sate/GDS
+sateen/M
+satellite/DSMG
+satiable/I
+satiate/GNDS
+satiation/M
+satiety/M
+satin/M
+satinwood/SM
+satiny
+satire/SM
+satiric
+satirical/Y
+satirist/SM
+satirize/DSG
+satisfaction/EM
+satisfactions
+satisfactorily/U
+satisfactory/U
+satisfied/U
+satisfy/EDSG
+satisfying/U
+satisfyingly
+sativa
+satori/M
+satrap/SM
+satsuma/S
+saturate/DSGN
+saturated/U
+saturation/M
+saturnine
+satyr/MS
+satyriasis/M
+satyric
+sauce/MZGDRS
+saucepan/SM
+saucer/M
+saucily
+sauciness/M
+saucy/RPT
+sauerkraut/M
+sauna/MDSG
+saunter/MDGS
+saurian
+sauropod/SM
+sausage/MS
+saute/MS
+sauteed
+sauteing
+sauternes/M
+saut辿/MDSG
+savage/DRSMYTGP
+savageness/M
+savagery/SM
+savanna/MS
+savant/SM
+save/BJMZGDRS
+saveable
+saved/U
+saver/M
+saving/M
+savings/M
+savior/SM
+savoir
+savor/MDSG
+savoriness/M
+savory/PTRSM
+savoy/MS
+savvy/DRSMTG
+saw/SGMD
+sawbones/M
+sawbuck/MS
+sawdust/M
+sawfly/SM
+sawhorse/SM
+sawmill/MS
+sawyer/SM
+sax/MS
+saxifrage/SM
+saxophone/MS
+saxophonist/SM
+say's
+say/USG
+saying/SM
+sayonara/S
+scab/MS
+scabbard/MS
+scabbed
+scabbiness/M
+scabbing
+scabby/PTR
+scabies/M
+scabrous
+scad/MS
+scaffold/SMG
+scaffolding/M
+scag/S
+scagged
+scalability
+scalar/S
+scalawag/MS
+scald/MDSG
+scale's
+scale/CGDSB
+scaleless
+scalene
+scaliness/M
+scallion/MS
+scallop/GSMD
+scallywag/MS
+scalp/MDRSZG
+scalpel/SM
+scalper/M
+scaly/RTP
+scam/MS
+scammed
+scammer/S
+scamming
+scamp/MRSZ
+scamper/GMD
+scampi/M
+scan/MS
+scandal/SM
+scandalize/DSG
+scandalmonger/SM
+scandalous/Y
+scandium/M
+scanned
+scanner/SM
+scanning
+scansion/M
+scant/CDSTG
+scanter
+scantily
+scantiness/M
+scantly
+scantness/M
+scanty/RSPT
+scapegoat/SGMD
+scapegrace/MS
+scapula/M
+scapulae
+scapular/SM
+scar/GMDS
+scarab/SM
+scarce/RYTP
+scarceness/M
+scarcity/SM
+scare/MS
+scarecrow/MS
+scaremonger/SMG
+scarf/MDSG
+scarification/M
+scarify/NDSG
+scarily
+scariness/M
+scarlatina/M
+scarlet/M
+scarp/MDRSZG
+scarper/DG
+scarred
+scarring
+scarves
+scary/RTP
+scat/MS
+scathing/Y
+scatological
+scatology/M
+scatted
+scatter/GJSMD
+scatterbrain/SMD
+scattering/M
+scattershot
+scatting
+scatty
+scavenge/ZGDRS
+scavenger/M
+scenario/MS
+scenarist/MS
+scene/MS
+scenery/M
+scenic
+scenically
+scent/CMS
+scented/U
+scenting
+scentless
+scepter/MS
+sch
+schadenfreude
+schedule's
+schedule/ADSG
+scheduled/U
+scheduler/S
+schema/S
+schemata
+schematic/SM
+schematically
+schematize/GDS
+scheme/DRSMZG
+schemer/M
+scherzo/MS
+schilling/MS
+schism/SM
+schismatic/SM
+schist/M
+schistosomiasis
+schizo/SM
+schizoid/MS
+schizophrenia/M
+schizophrenic/SM
+schlemiel/SM
+schlep/SM
+schlepp/GMDS
+schlock/M
+schlocky
+schmaltz/M
+schmaltzy/TR
+schmo/M
+schmoe/SM
+schmooze/DRSZG
+schmuck/MS
+schnapps/M
+schnaps
+schnauzer/SM
+schnitzel/SM
+schnook/MS
+schnoz/MS
+schnozzle/SM
+scholar/MYS
+scholarship/MS
+scholastic
+scholastically
+scholasticism
+school/SGMD
+schoolbag/MS
+schoolbook/SM
+schoolboy/MS
+schoolchild/M
+schoolchildren/M
+schooldays
+schooled/U
+schoolfellow/SM
+schoolgirl/SM
+schoolhouse/SM
+schooling/M
+schoolkid/S
+schoolmarm/SM
+schoolmarmish
+schoolmaster/MS
+schoolmate/SM
+schoolmistress/MS
+schoolroom/SM
+schoolteacher/MS
+schoolwork/M
+schoolyard/SM
+schooner/SM
+schrod/S
+schuss/GMDS
+schussboomer/MS
+schwa/MS
+sci
+sciatic
+sciatica/M
+science/FMS
+scientific/U
+scientifically/U
+scientist/SM
+scimitar/SM
+scintilla/MS
+scintillate/DSGN
+scintillation/M
+scion/MS
+scissor/GDS
+scleroses
+sclerosis/M
+sclerotic
+scoff/MDRSZG
+scoffer/M
+scofflaw/MS
+scold/MDSGJ
+scolding/M
+scoliosis/M
+sconce/SM
+scone/MS
+scooch/DSG
+scoop/MDSG
+scoopful/MS
+scoot/DRSZG
+scooter/M
+scope/MGDS
+scorbutic
+scorch/MDRSZG
+scorcher/M
+score/MZGDRS
+scoreboard/SM
+scorebook/SM
+scorecard/MS
+scorekeeper/MS
+scoreless
+scoreline/S
+scorer/M
+scoresheet/SM
+scorn/MDRSZG
+scorner/M
+scornful/Y
+scorpion/MS
+scot-free
+scotch/MDSG
+scotchs
+scoundrel/MS
+scour/DRSZG
+scourer/M
+scourge/DSMG
+scout/MDRSZG
+scouting/M
+scoutmaster/MS
+scow/MS
+scowl/MDSG
+scrabble/MZGDRS
+scrabbler/M
+scrag/MS
+scraggly/RT
+scraggy/TR
+scram/S
+scramble's
+scramble/UGDS
+scrambler/MS
+scrammed
+scramming
+scrap/MDRSZGJ
+scrapbook/SM
+scrape/SM
+scraper/M
+scrapheap/SM
+scrapie
+scrapped
+scrapper/MS
+scrapping
+scrappy/TR
+scrapyard/SM
+scratch/GMDS
+scratchcard/S
+scratched/U
+scratchily
+scratchiness/M
+scratchpad/S
+scratchy/PRT
+scrawl/SMDG
+scrawly
+scrawniness/M
+scrawny/PTR
+scream/SMDRZG
+screamer/M
+screaming/Y
+scree/MDS
+screech/GMDS
+screechy/TR
+screed/S
+screen/SJMDRZG
+screening/M
+screenplay/SM
+screensaver/SM
+screenshot/SM
+screenwriter/SM
+screenwriting/M
+screw's
+screw/UDSG
+screwball/MS
+screwdriver/MS
+screwiness/M
+screwworm/SM
+screwy/PRT
+scribal
+scribble/MZGDRS
+scribbler/M
+scribe's
+scribe/CKIS
+scrim/MS
+scrimmage/MGDS
+scrimp/SDG
+scrimshaw/MDGS
+scrip/MS
+script/FSMDG
+scripted/U
+scriptural
+scripture/MS
+scriptwriter/SM
+scrivener/SM
+scrod/M
+scrofula/M
+scrofulous
+scrog/S
+scroll/GSMD
+scrollbar/S
+scrooge/MS
+scrota
+scrotal
+scrotum/M
+scrounge/DRSZG
+scrounger/M
+scroungy/TR
+scrub/MS
+scrubbed
+scrubber/SM
+scrubbing
+scrubby/RT
+scruff/SM
+scruffily
+scruffiness/M
+scruffy/RPT
+scrum/S
+scrumhalf
+scrumhalves
+scrummage/S
+scrummed
+scrumming
+scrump/SGD
+scrumptious/Y
+scrumpy
+scrunch/MDSG
+scrunchie/M
+scrunchy/SM
+scruple/MGDS
+scrupulosity/M
+scrupulous/UPY
+scrupulousness/UM
+scrutineer/S
+scrutinize/GDS
+scrutiny/M
+scuba/MDSG
+scud/MS
+scudded
+scudding
+scuff/MDSG
+scuffle/MGDS
+scull/MDRSZG
+sculler/M
+scullery/SM
+scullion/SM
+sculpt/SGD
+sculptor/SM
+sculptress/MS
+sculptural
+sculpture/DSMG
+scum/MS
+scumbag/MS
+scummed
+scumming
+scummy/TR
+scupper/MDGS
+scurf/M
+scurfy
+scurrility/M
+scurrilous/PY
+scurrilousness/M
+scurry/GDSM
+scurvily
+scurvy/TRM
+scutcheon/SM
+scuttle/MGDS
+scuttlebutt/M
+scuzzy/TR
+scythe/DSMG
+se
+sea/SM
+seabed/SM
+seabird/MS
+seaboard/SM
+seaborne
+seacoast/SM
+seafarer/SM
+seafaring/M
+seafloor/SM
+seafood/M
+seafront/SM
+seagoing
+seagull/MS
+seahorse/MS
+seal's
+seal/AUSDG
+sealant/MS
+sealer/SM
+sealskin/M
+seam/GMDNS
+seaman/M
+seamanship/M
+seamless/Y
+seamount/MS
+seamstress/MS
+seamy/RT
+seance/SM
+seaplane/SM
+seaport/MS
+sear/GMDS
+search/AZGMDRS
+searchable/U
+searcher/AM
+searching/Y
+searchlight/MS
+searing/Y
+seascape/SM
+seashell/SM
+seashore/SM
+seasick/P
+seasickness/M
+seaside/MS
+season/SGMDBJ
+seasonable/U
+seasonably/U
+seasonal/Y
+seasonality
+seasoned/U
+seasoning/M
+seat's
+seat/UGDS
+seating/M
+seatmate/SM
+seawall/MS
+seaward/MS
+seawater/M
+seaway/SM
+seaweed/MS
+seaworthiness/M
+seaworthy/P
+sebaceous
+seborrhea/M
+sebum
+sec'y
+sec/SM
+secant/SM
+secateurs
+secede/DSG
+secession/M
+secessionist/MS
+seclude/GDS
+seclusion/M
+seclusive
+second/SLZGMDRY
+secondarily
+secondary/SM
+seconder/M
+secondhand
+secondment/S
+secrecy/M
+secret/SGVMDY
+secretarial
+secretariat/MS
+secretary/SM
+secretaryship/M
+secrete/XNS
+secretion/M
+secretive/PY
+secretiveness/M
+secretory
+sect/IMS
+sectarian/MS
+sectarianism/M
+sectary/SM
+section/AESM
+sectional/MS
+sectionalism/M
+sectioned
+sectioning
+sector/ESM
+secular
+secularism/M
+secularist/SM
+secularization/M
+secularize/DSG
+secure/DRSYTG
+secured/U
+security/ISM
+secy
+sedan/MS
+sedate/DRSYTGNVP
+sedateness/M
+sedation/M
+sedative/SM
+sedentary
+sedge/M
+sedgy
+sediment/MS
+sedimentary
+sedimentation/M
+sedition/M
+seditious
+seduce/DRSZG
+seducer/M
+seduction/SM
+seductive/YP
+seductiveness/M
+seductress/MS
+sedulous/Y
+see/RSMZ
+seed's
+seed/AGDS
+seedbed/MS
+seedcase/MS
+seeded/U
+seeder/SM
+seediness/M
+seedless
+seedling/MS
+seedpod/MS
+seedy/RPT
+seeing/S
+seek/ZGRS
+seeker/M
+seem/GDS
+seeming/Y
+seemliness/UM
+seemly/URTP
+seen/U
+seep/GDS
+seepage/M
+seer/M
+seersucker/M
+seesaw/SMDG
+seethe/DSG
+segfault/S
+segment/GSMD
+segmentation/M
+segmented/U
+segregable
+segregate/CDSGN
+segregated/U
+segregation/CM
+segregationist/MS
+segue/MGDS
+segueing
+seigneur/SM
+seignior/SM
+seigniorial
+seine/MZGDRS
+seiner/M
+seismic
+seismically
+seismograph/ZMR
+seismographer/M
+seismographic
+seismographs
+seismography/M
+seismologic
+seismological
+seismologist/MS
+seismology/M
+seize/GDS
+seizure/MS
+seldom/Y
+select/CSGVD
+selection/SM
+selective/Y
+selectivity/M
+selectman/M
+selectmen
+selectness/M
+selector/MS
+selenium/M
+selenographer/MS
+selenography/M
+self/GM
+selfie/SM
+selfish/UYP
+selfishness/UM
+selfism
+selfist/S
+selfless/PY
+selflessness/M
+selfsame
+sell's
+sell/AZGRS
+seller's
+selloff/MS
+sellotape/DSG
+sellout/MS
+seltzer/MS
+selvage/MS
+selvedge/MS
+selves
+semantic/S
+semantically
+semanticist/MS
+semantics/M
+semaphore/DSMG
+semblance/ASM
+semen/M
+semester/SM
+semi/MS
+semiannual/Y
+semiarid
+semiautomatic/MS
+semibreve/S
+semicircle/SM
+semicircular
+semicolon/MS
+semiconducting
+semiconductor/MS
+semiconscious
+semidarkness/M
+semidetached
+semifinal/SM
+semifinalist/MS
+semigloss/S
+semimonthly/SM
+seminal
+seminar/MS
+seminarian/SM
+seminary/SM
+semiofficial
+semiotic/S
+semiotics/M
+semipermeable
+semiprecious
+semiprivate
+semipro/S
+semiprofessional/SM
+semiquaver/S
+semiretired
+semiskilled
+semisolid
+semisweet
+semitone/SM
+semitrailer/MS
+semitransparent
+semitropical
+semivowel/SM
+semiweekly/SM
+semiyearly
+semolina/M
+sempstress/MS
+senate/SM
+senator/MS
+senatorial
+send/ZGRS
+sender/M
+sendoff/MS
+senescence/M
+senescent
+senile
+senility/M
+senior/SM
+seniority/M
+senna/M
+senor/MS
+senora/SM
+senorita/SM
+sensation/MS
+sensational/Y
+sensationalism/M
+sensationalist/MS
+sensationalistic
+sensationalize/GDS
+sense/MGDS
+senseless/PY
+senselessness/M
+sensibilities
+sensibility/IM
+sensible/P
+sensibleness/M
+sensibly/I
+sensitive/SMYP
+sensitiveness/M
+sensitivities
+sensitivity/IM
+sensitization/CM
+sensitize/CDSG
+sensor/SM
+sensory
+sensual/Y
+sensualist/SM
+sensuality/M
+sensuous/YP
+sensuousness/M
+sent/FAU
+sentence/MGDS
+sententious/Y
+sentience/IM
+sentient/Y
+sentiment/SM
+sentimental/Y
+sentimentalism/M
+sentimentalist/MS
+sentimentality/M
+sentimentalization/M
+sentimentalize/GDS
+sentinel/MS
+sentry/SM
+sepal/MS
+separability/IM
+separable
+separably/I
+separate/XMYGNVDSP
+separateness/M
+separation/M
+separatism/M
+separatist/MS
+separator/MS
+sepia/M
+sepsis/M
+septa
+septal
+septet/SM
+septic
+septicemia/M
+septicemic
+septuagenarian/MS
+septum/M
+sepulcher/GMDS
+sepulchral
+seq
+sequel/SM
+sequence/MZGDRS
+sequencing/M
+sequential/FY
+sequester/SDG
+sequestrate/XGNDS
+sequestration/M
+sequin/SMD
+sequinned
+sequitur
+sequoia/MS
+sera
+seraglio/MS
+serape/SM
+seraph/M
+seraphic
+seraphim
+seraphs
+sere/TR
+serenade/MGDS
+serendipitous
+serendipity/M
+serene/RPYT
+sereneness/M
+serenity/M
+serf/MS
+serfdom/M
+serge/M
+sergeant/MS
+serial/SMY
+serialization/SM
+serialize/GDSB
+series/M
+serif/MS
+serigraph/M
+serigraphs
+serine
+serious/PY
+seriousness/M
+sermon/SM
+sermonize/GDS
+serology/M
+serotonin
+serous
+serpent/MS
+serpentine/M
+serrate/XND
+serration/M
+serried
+serum/MS
+servant/MS
+serve's/AF
+serve/FACGDS
+server/SM
+servery/S
+service/EMS
+serviceability/M
+serviceable
+serviced
+serviceman/M
+servicemen
+servicewoman/M
+servicewomen
+servicing
+serviette/MS
+servile
+servility/M
+serving's
+servings
+servitor/MS
+servitude/M
+servo/MS
+servomechanism/SM
+servomotor/MS
+sesame/SM
+sesquicentennial/MS
+session/MS
+set/AISM
+setback/MS
+setscrew/SM
+setsquare/S
+sett/BJZGRS
+settee/MS
+setter/M
+setting/M
+settle's
+settle/AUGDS
+settlement/AM
+settlements
+settler/SM
+setup/MS
+seven/MHS
+seventeen/SMH
+seventeenth/M
+seventeenths
+seventh/M
+sevenths
+seventieth/M
+seventieths
+seventy/SMH
+sever/ETGDS
+severability
+several/MY
+severance/SM
+severe/YPR
+severeness/M
+severity/M
+sew/ASGD
+sewage/M
+sewer/MS
+sewerage/M
+sewing/M
+sewn/A
+sex/GMDS
+sexagenarian/SM
+sexily
+sexiness/M
+sexism/M
+sexist/MS
+sexless
+sexologist/SM
+sexology/M
+sexpot/MS
+sextant/SM
+sextet/MS
+sexting
+sexton/MS
+sextuplet/SM
+sexual/Y
+sexuality/M
+sexy/PTR
+sf
+sh
+shabbily
+shabbiness/M
+shabby/PTR
+shack/MDSG
+shackle's
+shackle/UGDS
+shad/GMDSJ
+shade/MS
+shadily
+shadiness/M
+shading/M
+shadow/SGMD
+shadowbox/GDS
+shadowy/RT
+shady/RPT
+shaft/MDSG
+shag/MS
+shagged
+shagginess/M
+shagging
+shaggy/TPR
+shah/M
+shahs
+shake/MZGRS
+shakedown/SM
+shaken/U
+shakeout/MS
+shaker/M
+shakeup/MS
+shakily
+shakiness/M
+shaky/RPT
+shale/M
+shall
+shallot/MS
+shallow/TPMRYS
+shallowness/M
+shalom
+shalt
+sham/GMDS
+shaman/SM
+shamanic
+shamanism
+shamanistic
+shamble/MGDS
+shambles/M
+shambolic
+shame/MS
+shamefaced/Y
+shameful/PY
+shamefulness/M
+shameless/YP
+shamelessness/M
+shammed
+shamming
+shampoo/ZGMDRS
+shampooer/M
+shamrock/MS
+shan't
+shandy/S
+shanghai/DSG
+shank/MS
+shantung/M
+shanty/SM
+shantytown/SM
+shape's
+shape/AGDS
+shaped/U
+shapeless/YP
+shapelessness/M
+shapeliness/M
+shapely/PTR
+shapeshift/ZGDR
+shard/MS
+share/MZGDRSB
+shareable
+sharecrop/S
+sharecropped
+sharecropper/MS
+sharecropping
+shareholder/SM
+shareholding/S
+sharer/M
+shareware/M
+sharia/M
+shariah
+shark/MDSG
+sharkskin/M
+sharp/MDNRYSPXZTG
+sharpen/ADGS
+sharpener/MS
+sharper/M
+sharpie/M
+sharpish
+sharpness/M
+sharpshooter/SM
+sharpshooting/M
+sharpy/SM
+shat
+shatter/GMDS
+shatterproof
+shave/MZGDRSJ
+shaven/U
+shaver/M
+shaving/M
+shawl/MS
+shay/MS
+she'd
+she'll
+she/DSM
+sheaf/M
+shear/MDRSZG
+shearer/M
+sheath/JM
+sheathe/UGDS
+sheathing/M
+sheaths
+sheave/DSMG
+shebang/MS
+shebeen/S
+shed/MS
+shedding
+sheen/M
+sheeny/TR
+sheep/M
+sheepdog/MS
+sheepfold/SM
+sheepherder/MS
+sheepish/YP
+sheepishness/M
+sheepskin/MS
+sheer/MDRSPTG
+sheerness/M
+sheet/MSG
+sheeting/M
+sheetlike
+sheik/MS
+sheikdom/MS
+sheikh/M
+sheikhdom/MS
+sheikhs
+sheila/S
+shekel/SM
+shelf/M
+shell/MDRSG
+shellac/MS
+shellacked
+shellacking/MS
+shellfire/M
+shellfish/MS
+shelter/GMDS
+shelve/GDS
+shelving/M
+shemale/MS
+shenanigan/SM
+shepherd/SMDG
+shepherdess/MS
+sherbet/SM
+sherd/MS
+sheriff/SM
+sherry/SM
+shew/GDS
+shewn
+shh
+shiatsu/M
+shibboleth/M
+shibboleths
+shield/MDGS
+shift/ZGMDRS
+shiftily
+shiftiness/M
+shiftless/PY
+shiftlessness/M
+shifty/RPT
+shiitake/SM
+shill/GMDSJ
+shillelagh/M
+shillelaghs
+shilling/M
+shim/MS
+shimmed
+shimmer/SMDG
+shimmery
+shimming
+shimmy/DSMG
+shin/ZGMDRS
+shinbone/SM
+shindig/SM
+shine/MS
+shiner/M
+shingle/DSMG
+shinguard/M
+shininess/M
+shinned
+shinning
+shinny/DSG
+shinsplints/M
+shiny/TRP
+ship's
+ship/ALS
+shipboard/MS
+shipbuilder/SM
+shipbuilding/M
+shipload/SM
+shipmate/SM
+shipment/AM
+shipments
+shipowner/MS
+shipped/A
+shipper/SM
+shipping/M
+shipshape
+shipwreck/GMDS
+shipwright/MS
+shipyard/SM
+shire/MS
+shirk/ZGDRS
+shirker/M
+shirr/GMDSJ
+shirring/M
+shirt/GMDS
+shirtfront/SM
+shirting/M
+shirtless
+shirtsleeve/SM
+shirttail/SM
+shirtwaist/MS
+shirty
+shit/SM!
+shitfaced/!
+shithead/MS!
+shitload/MS!
+shitted/!
+shitting/!
+shitty/RT!
+shiv/ZMRS
+shiver/MDG
+shivery
+shoal/GMDS
+shoat/MS
+shock/ZGMDRS
+shocker/M
+shocking/Y
+shockproof
+shod/U
+shoddily
+shoddiness/M
+shoddy/PRMT
+shoe/MS
+shoehorn/GMDS
+shoeing
+shoelace/MS
+shoemaker/SM
+shoeshine/SM
+shoestring/SM
+shoetree/MS
+shogun/MS
+shogunate/M
+shone
+shoo/GDS
+shook
+shoot/ZGMRSJ
+shooter/M
+shooting/M
+shootout/MS
+shop/MS
+shopaholic/MS
+shopfitter/S
+shopfitting
+shopfront/S
+shopkeeper/MS
+shoplift/DRZGS
+shoplifter/M
+shoplifting/M
+shoppe/MZGDRS
+shopper/M
+shopping/M
+shoptalk/M
+shopworn
+shore/MGDS
+shorebird/SM
+shoreline/MS
+shoring/M
+short/XTGMDNRYSP
+shortage/MS
+shortbread/M
+shortcake/MS
+shortchange/DSG
+shortcoming/MS
+shortcrust
+shortcut/MS
+shorten/JGD
+shortening/M
+shortfall/MS
+shorthand/MD
+shorthorn/MS
+shortie/M
+shortish
+shortlist/DGS
+shortness/M
+shortsighted/PY
+shortsightedness/M
+shortstop/MS
+shortwave/MS
+shorty/SM
+shot/MS
+shotgun/SM
+shotgunned
+shotgunning
+should
+should've
+shoulder/MDGS
+shouldn't
+shout/ZGMDRS
+shouter/M
+shove/MGDS
+shovel/MDSG
+shovelful/SM
+show/JZGMDRS
+showbiz/M
+showboat/MDGS
+showcase/MGDS
+showdown/MS
+shower/MDG
+showerproof
+showery
+showgirl/MS
+showground/S
+showily
+showiness/M
+showing/M
+showjumping
+showman/M
+showmanship/M
+showmen
+shown
+showoff/SM
+showpiece/SM
+showplace/SM
+showroom/MS
+showstopper/MS
+showstopping
+showtime/MS
+showy/TRP
+shpt
+shrank
+shrapnel/M
+shred/MS
+shredded
+shredder/MS
+shredding
+shrew/MS
+shrewd/RYPT
+shrewdness/M
+shrewish
+shriek/MDSG
+shrift/M
+shrike/MS
+shrill/DRSPTG
+shrillness/M
+shrilly
+shrimp/MDRSZG
+shrine/MS
+shrink/MSBG
+shrinkage/M
+shrive/GDS
+shrivel/SGD
+shriven
+shroom/S
+shroud/GMDS
+shrub/MS
+shrubbery/SM
+shrubby/RT
+shrug/MS
+shrugged
+shrugging
+shrunk/N
+shtick/MS
+shuck/GMDS
+shucks/S
+shudder/MDSG
+shuffle/AMGDS
+shuffleboard/SM
+shuffler/SM
+shun/S
+shunned
+shunning
+shunt/MSDG
+shush/DSG
+shut/S
+shutdown/SM
+shuteye/M
+shutoff/SM
+shutout/SM
+shutter/SMDG
+shutterbug/MS
+shutting
+shuttle/DSMG
+shuttlecock/GMDS
+shy/TGDRSMY
+shyer
+shyest
+shyness/M
+shyster/SM
+sibilant/SM
+sibling/SM
+sibyl/MS
+sibylline
+sic/S
+sicced
+siccing
+sick/PXTGDNRYS
+sickbay/S
+sickbed/SM
+sicken/DG
+sickening/Y
+sickie/MS
+sickish
+sickle/MS
+sickly/RT
+sickness/MS
+sicko/MS
+sickout/SM
+sickroom/MS
+side's
+side/AGDS
+sidearm/SM
+sidebar/SM
+sideboard/SM
+sideburns/M
+sidecar/SM
+sidekick/SM
+sidelight/MS
+sideline/DSMG
+sidelong
+sideman/M
+sidemen
+sidepiece/MS
+sidereal
+sidesaddle/MS
+sideshow/MS
+sidesplitting
+sidestep/MS
+sidestepped
+sidestepping
+sidestroke/DSMG
+sideswipe/DSMG
+sidetrack/SMDG
+sidewalk/MS
+sidewall/MS
+sideways
+sidewinder/SM
+siding/MS
+sidle/MGDS
+siege/MS
+sienna/M
+sierra/MS
+siesta/MS
+sieve/MGDS
+sift/ZGDRS
+sifted/U
+sifter/M
+sigh/GMD
+sighs
+sight/GMDYSJ
+sighting/M
+sightless
+sightly/UTR
+sightread
+sightseeing/M
+sightseer/MS
+sigma/MS
+sign's/C
+sign/AFCGDS
+signage/M
+signal/MDRYSZG
+signaler/M
+signalization/M
+signalize/GDS
+signalling
+signalman/M
+signalmen
+signatory/SM
+signature/MS
+signboard/MS
+signed/U
+signer/CMS
+signet/MS
+significance/IM
+significant/IY
+signification/M
+signify/XDSNG
+signing/CSM
+signor/FMS
+signora/SM
+signore
+signori
+signorina/MS
+signorine
+signpost/GSMD
+signup/MS
+silage/M
+silence/DRSMZG
+silencer/M
+silent/MRYST
+silhouette/DSMG
+silica/M
+silicate/MS
+siliceous
+silicon/SM
+silicone/M
+silicosis/M
+silk/MNS
+silkily
+silkiness/M
+silkscreen/SM
+silkworm/MS
+silky/TRP
+sill/MS
+silliness/M
+silly/TRSMP
+silo/MDS
+silt/GMDS
+silty/TR
+silvan
+silver/GMDS
+silverfish/MS
+silversmith/M
+silversmiths
+silverware/M
+silvery
+sim/SM
+simian/MS
+similar/Y
+similarity/ESM
+simile/MS
+similitude/EM
+simmer/GMDS
+simonize/DSG
+simony/M
+simpatico
+simper/GMDS
+simpering/Y
+simple/TRP
+simpleminded
+simpleness/M
+simpleton/SM
+simplex
+simplicity/M
+simplification/M
+simplify/DSXNG
+simplistic
+simplistically
+simply
+simulacra
+simulacrum/S
+simulate/EDSGN
+simulation/EM
+simulations
+simulator/EMS
+simulcast/GMDS
+simultaneity/M
+simultaneous/Y
+sin/ASM
+since
+sincere/IYT
+sincerer
+sincerity/IM
+sine/MS
+sinecure/MS
+sinew/MS
+sinewy
+sinful/PY
+sinfulness/M
+sing/BZGMDRYS
+singalong/S
+singe/MS
+singeing
+singer/M
+singing/M
+single-handedly
+single/PMGDS
+singleness/M
+singles/M
+singlet/S
+singleton/SM
+singletree/SM
+singsong/SMDG
+singular/SMY
+singularity/SM
+sinister
+sink/BZGMRS
+sinkable/U
+sinker/M
+sinkhole/SM
+sinless
+sinned
+sinner/MS
+sinning
+sinology
+sinuosity/M
+sinuous/Y
+sinus/MS
+sinusitis/M
+sinusoidal
+sip/SM
+siphon/GMDS
+sipped
+sipper/SM
+sipping
+sir/SXMN
+sire/CMGDS
+siree/M
+siren/M
+sirloin/SM
+sirocco/SM
+sirrah
+sirree/M
+sis/MS
+sisal/M
+sissified
+sissy/RSMT
+sister/ASM
+sisterhood/MS
+sisterliness/M
+sisterly/P
+sit/S
+sitar/SM
+sitarist/MS
+sitcom/SM
+site/MGDS
+sitemap/SM
+sitter/SM
+sitting/SM
+situ
+situate/DSXGN
+situation/M
+situational
+six/MSH
+sixfold
+sixpence/MS
+sixshooter/M
+sixteen/SMH
+sixteenth/M
+sixteenths
+sixth/M
+sixths
+sixtieth/M
+sixtieths
+sixty/SMH
+size's
+size/AGBDRS
+sizeable
+sizing/M
+sizzle/DRSMZG
+ska/M
+skate/MZGDRS
+skateboard/MDRSZG
+skateboarder/M
+skateboarding/M
+skater/M
+skating/M
+skedaddle/MGDS
+skeet/ZMR
+skein/MS
+skeletal
+skeleton/SM
+skeptic/SM
+skeptical/Y
+skepticism/M
+sketch/MDRSZG
+sketchbook/S
+sketcher/M
+sketchily
+sketchiness/M
+sketchpad/S
+sketchy/RTP
+skeuomorph
+skeuomorphic
+skeuomorphism
+skeuomorphs
+skew/MDRZGS
+skewbald/S
+skewer/MDG
+ski/SZGMDR
+skibob/S
+skid/MS
+skidded
+skidding
+skidpan/S
+skier/M
+skiff/SM
+skiffle
+skiing/M
+skill's
+skill/CSD
+skilled/U
+skillet/SM
+skillful/UY
+skillfulness/M
+skim/MS
+skimmed
+skimmer/SM
+skimming
+skimp/SDG
+skimpily
+skimpiness/M
+skimpy/RTP
+skin/AMS
+skincare/M
+skinflick/MS
+skinflint/MS
+skinful
+skinhead/MS
+skinless
+skinned/A
+skinniness/M
+skinning/A
+skinny/RMTP
+skint
+skintight
+skip/MS
+skipped
+skipper/SMDG
+skipping
+skirmish/ZGMDRS
+skirt/SMDG
+skit/MS
+skitter/GSD
+skittish/YP
+skittishness/M
+skittle/S
+skive/DRSZG
+skivvy/DSMG
+skoal/SM
+skua/S
+skulduggery/M
+skulk/SDRZG
+skulker/M
+skull/SM
+skullcap/MS
+skullduggery/M
+skunk/SMDG
+sky/GSM
+skycap/SM
+skydive/DRSZG
+skydiver/M
+skydiving/M
+skyjack/JZGSDR
+skyjacker/M
+skyjacking/M
+skylark/SGMD
+skylight/MS
+skyline/SM
+skyrocket/GSMD
+skyscraper/SM
+skyward/S
+skywriter/SM
+skywriting/M
+slab/MS
+slabbed
+slabbing
+slack/PXZTGMDNRYS
+slacken/DG
+slacker/M
+slackness/M
+slacks/M
+slag/MS
+slagged
+slagging
+slagheap/S
+slain
+slake/GDS
+slalom/MSDG
+slam/MS
+slammed
+slammer/SM
+slamming
+slander/MZGDRS
+slanderer/M
+slanderous
+slang/M
+slangy/RT
+slant/MSDG
+slanting/Y
+slantwise
+slap/MS
+slapdash
+slaphappy
+slapped
+slapper/S
+slapping
+slapstick/M
+slash/MDRSZG
+slasher/M
+slat/MDGS
+slate/SM
+slather/SDG
+slatted
+slattern/SMY
+slaughter/MDRZGS
+slaughterer/M
+slaughterhouse/MS
+slave/DRSMZG
+slaveholder/MS
+slaver/MDG
+slavery/M
+slavish/PY
+slavishness/M
+slaw/M
+slay/DRZGJS
+slayer/M
+slaying/M
+sleaze/SM
+sleazebag/S
+sleazeball/S
+sleazily
+sleaziness/M
+sleazy/PRT
+sled/MS
+sledded
+sledder/SM
+sledding
+sledge/DSMG
+sledgehammer/GSMD
+sleek/SDRYTGP
+sleekness/M
+sleep/SMRZG
+sleeper/M
+sleepily
+sleepiness/M
+sleepless/PY
+sleeplessness/M
+sleepover/SM
+sleepwalk/ZGSDR
+sleepwalker/M
+sleepwalking/M
+sleepwear/M
+sleepy/RPT
+sleepyhead/MS
+sleet/SMDG
+sleety
+sleeve/DSM
+sleeveless
+sleigh/MDG
+sleighs
+sleight/SM
+slender/PRT
+slenderize/DSG
+slenderness/M
+slept
+sleuth/MG
+sleuths
+slew/MDGS
+slice/DRSMZG
+slicer/M
+slick/SMDRYZTGP
+slicker/M
+slickness/M
+slid
+slide/RSMZG
+slider/M
+slideshow/MS
+slight/SMDRYTGP
+slightness/M
+slim/PS
+slime/M
+sliminess/M
+slimline
+slimmed
+slimmer/S
+slimmest
+slimming/M
+slimness/M
+slimy/RTP
+sling/SMG
+slingback/S
+slingshot/SM
+slink/SG
+slinky/RT
+slip/MS
+slipcase/MS
+slipcover/MS
+slipknot/MS
+slippage/MS
+slipped
+slipper/SM
+slipperiness/M
+slippery/PRT
+slipping
+slippy
+slipshod
+slipstream/SM
+slipway/SM
+slit/MS
+slither/SGMD
+slithery
+slitter
+slitting
+sliver/GSMD
+slob/MS
+slobbed
+slobber/MDSG
+slobbery
+slobbing
+sloe/MS
+slog/MS
+slogan/SM
+sloganeering
+slogged
+slogging
+sloop/SM
+slop/MDGS
+slope/SM
+slopped
+sloppily
+sloppiness/M
+slopping
+sloppy/PTR
+slops/M
+slosh/DSG
+slot/MS
+sloth/M
+slothful/YP
+slothfulness/M
+sloths
+slotted
+slotting
+slouch/ZGMDRS
+sloucher/M
+slouchy/TR
+slough/GMD
+sloughs
+sloven/SMY
+slovenliness/M
+slovenly/PTR
+slow/DRYTGSP
+slowcoach/S
+slowdown/SM
+slowness/M
+slowpoke/SM
+sludge/M
+sludgy/RT
+slue/MGDS
+slug/MS
+sluggard/MS
+slugged
+slugger/SM
+slugging
+sluggish/PY
+sluggishness/M
+sluice/DSMG
+slum/MS
+slumber/GSMD
+slumberous
+slumbrous
+slumdog/SM
+slumlord/MS
+slummed
+slummer
+slumming
+slummy/RT
+slump/SMDG
+slung
+slunk
+slur/MS
+slurp/SMDG
+slurred
+slurring
+slurry/M
+slush/MDSG
+slushiness/M
+slushy/RPT
+slut/MS
+sluttish
+slutty/RT
+sly/TRY
+slyer
+slyest
+slyness/M
+smack/SMDRZG
+smacker/M
+small/SMRTP
+smallholder/S
+smallholding/S
+smallish
+smallness/M
+smallpox/M
+smarmy/RT
+smart/SMDNRYXTGP
+smarten/DG
+smartness/M
+smartphone/SM
+smarts/M
+smartwatch/MS
+smarty/SM
+smartypants/M
+smash/MDRSZG
+smasher/M
+smashup/SM
+smattering/MS
+smear/SMDG
+smeary/RT
+smell/SMDG
+smelliness/M
+smelly/RPT
+smelt/SMDRZG
+smelter/M
+smidge/SM
+smidgen/MS
+smilax/M
+smile/DSMG
+smiley/SM
+smiling/Y
+smirch/GMDS
+smirk/SMDG
+smite/SG
+smith/M
+smithereens/M
+smiths
+smithy/SM
+smitten
+smock/SMDG
+smocking/M
+smog/MS
+smoggy/RT
+smoke/DRSMZG
+smokehouse/MS
+smokeless
+smoker/M
+smokescreen/SM
+smokestack/SM
+smokey
+smokiness/M
+smoking/M
+smoky/RTP
+smolder/SGMD
+smooch/MDSG
+smoochy
+smooth/PDRYTG
+smoothie/M
+smoothness/M
+smooths
+smoothy/SM
+smorgasbord/SM
+smote
+smother/GSMD
+smoulder/GMDS
+smudge/DSMG
+smudgy/TR
+smug/YP
+smugger
+smuggest
+smuggle/ZGDRS
+smuggler/M
+smuggling/M
+smugness/M
+smurf/S
+smut/MS
+smuttiness/M
+smutty/TRP
+sm旦rg奪sbord/MS
+snack/SMDG
+snaffle/DSMG
+snafu/SM
+snag/MS
+snagged
+snagging
+snail/SMDG
+snake/DSMG
+snakebite/MS
+snakelike
+snakeskin
+snaky/RT
+snap's
+snap/US
+snapdragon/SM
+snapped/U
+snapper/MS
+snappily
+snappiness/M
+snapping/U
+snappish/YP
+snappishness/M
+snappy/TRP
+snapshot/SM
+snare/DSMG
+snarf/SDG
+snark/S
+snarkily
+snarky/TR
+snarl's
+snarl/USDG
+snarling/Y
+snarly/TR
+snatch/ZGMDRS
+snatcher/M
+snazzily
+snazzy/TRP
+sneak/SMDRZG
+sneaker/M
+sneakily
+sneakiness/M
+sneaking/Y
+sneaky/TRP
+sneer/SJMDG
+sneering/Y
+sneeze/DSMG
+snick/SDRZG
+snicker/MDG
+snide/RYT
+sniff/SMDRYZG
+sniffer/M
+sniffle/DSMG
+sniffly/RT
+sniffy/RT
+snifter/SM
+snigger/SMDG
+snip/MDRZGS
+snipe/SM
+sniper/M
+snipped
+snippet/SM
+snipping
+snippy/RT
+snips/M
+snit/MS
+snitch/MDSG
+snivel/SMDRZG
+sniveler/M
+snob/MS
+snobbery/M
+snobbish/PY
+snobbishness/M
+snobby/RT
+snog/S
+snogged
+snogging
+snood/SM
+snooker/MDSG
+snoop/SMDRZG
+snooper/M
+snoopy/TR
+snoot/SM
+snootily
+snootiness/M
+snooty/PTR
+snooze/DSMG
+snore/DRSMZG
+snorer/M
+snorkel/ZGMDRS
+snorkeler/M
+snorkeling/M
+snort/SMDRZG
+snorter/M
+snot/MS
+snottily
+snottiness/M
+snotty/TPR
+snout/SM
+snow/MDGS
+snowball/GSMD
+snowbank/SM
+snowbird/SM
+snowblower/MS
+snowboard/ZGMDRS
+snowboarder/M
+snowboarding/M
+snowbound
+snowcap/MS
+snowcat/MS
+snowdrift/SM
+snowdrop/SM
+snowfall/SM
+snowfield/SM
+snowflake/SM
+snowiness/M
+snowline
+snowman/M
+snowmen
+snowmobile/DSMG
+snowplow/SGMD
+snowshed
+snowshoe/SM
+snowshoeing
+snowstorm/SM
+snowsuit/SM
+snowy/PRT
+snub/MS
+snubbed
+snubbing
+snuff/SMDRYZG
+snuffbox/MS
+snuffer/M
+snuffle/MGDS
+snug/MYSP
+snugged
+snugger
+snuggest
+snugging
+snuggle/MGDS
+snugness/M
+so
+soak/MDGSJ
+soaking/M
+soap/MDGS
+soapbox/MS
+soapiness/M
+soapstone/M
+soapsuds/M
+soapy/RPT
+soar/MDGS
+sob/SM
+sobbed
+sobbing/Y
+sober/SDRYPTG
+soberness/M
+sobriety/IM
+sobriquet/SM
+soc
+soccer/M
+sociability/M
+sociable/SM
+sociably
+social/SMY
+socialism/M
+socialist/SM
+socialistic
+socialite/SM
+socialization/M
+socialize/DSG
+societal
+society/SM
+socioeconomic
+socioeconomically
+sociological/Y
+sociologist/SM
+sociology/M
+sociopath/M
+sociopaths
+sociopolitical
+sock/MDGS
+socket/SM
+sockeye/SM
+sod/SM
+soda/MS
+sodded
+sodden/Y
+sodding
+sodium/M
+sodomite/MS
+sodomize/GDS
+sodomy/M
+soever
+sofa/MS
+soffit/S
+soft/NRYXTP
+softback
+softball/MS
+softbound
+softcover
+soften/DRZG
+softener/M
+softhearted
+softie/M
+softness/M
+software/M
+softwood/SM
+softy/SM
+soggily
+sogginess/M
+soggy/RTP
+soigne
+soignee
+soign辿
+soign辿e
+soil/MDGS
+soiled/U
+soiree/SM
+soir辿e/SM
+sojourn/ZGMDRS
+sojourner/M
+sol/SM
+solace/DSMG
+solar
+solaria
+solarium/M
+sold
+solder/ZGSMDR
+solderer/M
+soldier/MDYSG
+soldiery/M
+sole/FSDGM
+solecism/SM
+solely
+solemn/PTRY
+solemness/M
+solemnify/DSG
+solemnity/SM
+solemnization/M
+solemnize/DSG
+solemnness/M
+solenoid/MS
+solicit/GDS
+solicitation/SM
+solicited/U
+solicitor/SM
+solicitous/PY
+solicitousness/M
+solicitude/M
+solid/PSMRYT
+solidarity/M
+solidi
+solidification/M
+solidify/DSNG
+solidity/M
+solidness/M
+solidus/M
+soliloquies
+soliloquize/DSG
+soliloquy/M
+solipsism/M
+solipsistic
+solitaire/MS
+solitariness/M
+solitary/SMP
+solitude/M
+solo/MDGS
+soloist/MS
+solstice/MS
+solubility/IM
+soluble/MS
+solute's
+solute/AXN
+solutes
+solution's/AE
+solvability
+solvable/IU
+solve/EADSG
+solved/U
+solvency/IM
+solvent/IMS
+solver/SM
+somatic
+somatosensory
+somber/PY
+somberness/M
+sombre/PY
+sombreness/M
+sombrero/MS
+some
+somebody/SM
+someday
+somehow
+someone/MS
+someplace
+somersault/MDGS
+somerset/SM
+somersetted
+somersetting
+something/SM
+sometime/S
+someway/S
+somewhat/S
+somewhere
+sommelier/MS
+somnambulism/M
+somnambulist/SM
+somnolence/M
+somnolent
+son/SM
+sonar/SM
+sonata/SM
+sonatina/SM
+song/MS
+songbird/SM
+songbook/SM
+songfest/SM
+songster/MS
+songstress/MS
+songwriter/SM
+songwriting
+sonic
+sonnet/SM
+sonny/SM
+sonogram/SM
+sonority/M
+sonorous/YP
+sonorousness/M
+sonsofbitches
+soon/RT
+soot/M
+sooth/MDRSZG
+soothe
+soother/M
+soothing/Y
+soothsayer/MS
+soothsaying/M
+sooty/RT
+sop/SM
+soph
+sophism/M
+sophist/MS
+sophistic
+sophistical
+sophisticate/DSMGN
+sophisticated/U
+sophistication/M
+sophistry/SM
+sophomore/MS
+sophomoric
+soporific/MS
+soporifically
+sopped
+sopping
+soppy/RT
+soprano/MS
+sorbet/SM
+sorcerer/MS
+sorceress/MS
+sorcery/M
+sordid/PY
+sordidness/M
+sore/MYTRSP
+sorehead/MS
+soreness/M
+sorghum/M
+sorority/SM
+sorrel/SM
+sorrily
+sorriness/M
+sorrow/SMDG
+sorrowful/YP
+sorrowfulness/M
+sorry/RTP
+sort/FASGDM
+sorta
+sorted/U
+sorter/SM
+sortie/DSM
+sortieing
+sot/SM
+sottish
+sou'wester
+sou/SMH
+souffle/SM
+souffl辿/SM
+sough/MDG
+soughs
+sought/U
+souk/S
+soul/MS
+soulful/YP
+soulfulness/M
+soulless/YP
+soulmate/SM
+sound/JPSMDRYZTG
+soundalike/S
+soundbar/S
+soundbite/S
+soundboard/MS
+soundcheck/S
+sounder/M
+sounding/M
+soundless/Y
+soundness/UM
+soundproof/GDS
+soundproofing/M
+soundscape/S
+soundtrack/SM
+soup/MDGS
+soupcon/MS
+soupy/RT
+soup巽on/MS
+sour/MDRYTGSP
+source/ADSMG
+sourdough/M
+sourdoughs
+sourish
+sourness/M
+sourpuss/MS
+sousaphone/MS
+souse/DSMG
+south/M
+southbound
+southeast/ZMR
+southeaster/MY
+southeastern
+southeastward/S
+southerly/SM
+southern/SZMR
+southerner/M
+southernmost
+southpaw/SM
+southward/MS
+southwest/ZMR
+southwester/MY
+southwestern
+southwestward/S
+souvenir/SM
+sovereign/SM
+sovereignty/M
+soviet/SM
+sow's
+sow/ASGD
+sower/SM
+sown/A
+soy/M
+soybean/MS
+sozzled
+spa/SM
+space/DRSMZG
+spacecraft/MS
+spaceflight/MS
+spaceman/M
+spacemen
+spaceport/SM
+spacer/M
+spaceship/SM
+spacesuit/SM
+spacetime
+spacewalk/SGMD
+spacewoman/M
+spacewomen
+spacey
+spacial
+spacier
+spaciest
+spaciness/M
+spacing/M
+spacious/YP
+spaciousness/M
+spade/DSMG
+spadeful/MS
+spadework/M
+spadices
+spadix/M
+spaghetti/M
+spake
+spam/MS
+spammed
+spammer/SM
+spamming
+span/MS
+spandex/M
+spangle/DSMG
+spangly
+spaniel/SM
+spank/SMDGJ
+spanking/M
+spanned
+spanner/SM
+spanning
+spar/MS
+spare/DRSMYTGP
+spareness/M
+spareribs/M
+sparing/UY
+spark/SMDYG
+sparkle/DRSMZG
+sparkler/M
+sparky/RT
+sparred
+sparring
+sparrow/SM
+sparrowhawk/S
+sparse/RYTP
+sparseness/M
+sparsity/M
+spartan
+spasm/SM
+spasmodic
+spasmodically
+spastic/SM
+spat/MS
+spate/SM
+spathe/SM
+spatial/Y
+spatted
+spatter/SGMD
+spatting
+spatula/SM
+spavin/MD
+spawn/SMDG
+spay/DGS
+speak/SRZGJ
+speakeasy/SM
+speaker/M
+speakerphone/S
+spear/SMDG
+spearfish/GMDS
+speargun
+spearhead/GMDS
+spearmint/M
+spec/MS
+special/SMY
+specialism/S
+specialist/MS
+specialization/MS
+specialize/GDS
+specialty/SM
+specie/SM
+species/M
+specif
+specifiable
+specific/MS
+specifically
+specification/M
+specificity/M
+specified/U
+specify/XNZDRSG
+specimen/SM
+specious/YP
+speciousness/M
+speck/SMDG
+speckle/MGDS
+specs/M
+spectacle/SM
+spectacles/M
+spectacular/MYS
+spectate/DSG
+spectator/SM
+specter/AMS
+spectra
+spectral
+spectrogram/SM
+spectrometer/MS
+spectroscope/MS
+spectroscopic
+spectroscopy/M
+spectrum/M
+specula
+specular/Y
+specularity
+speculate/DSXGNV
+speculation/M
+speculative/Y
+speculator/MS
+speculum/S
+sped
+speech/MS
+speechify/DSG
+speechless/YP
+speechlessness/M
+speechwriter/S
+speed/SMRZG
+speedboat/SM
+speeder/M
+speedily
+speediness/M
+speeding/M
+speedometer/MS
+speedster/SM
+speedup/MS
+speedway/SM
+speedwell/M
+speedy/TPR
+speleological
+speleologist/MS
+speleology/M
+spell's
+spell/AJSDG
+spellbind/ZGRS
+spellbinder/M
+spellbound
+spellcheck/MDRZGS
+spellchecker/M
+spelldown/SM
+speller/MS
+spelling's
+spelt
+spelunker/MS
+spelunking/M
+spend/BSRZG
+spender/M
+spending/M
+spendthrift/MS
+spent/U
+sperm/SM
+spermatozoa
+spermatozoon/M
+spermicidal
+spermicide/MS
+spew/MDRZGS
+spewer/M
+sphagnum/MS
+sphere/SM
+spherical/Y
+spheroid/SM
+spheroidal
+sphincter/MS
+sphinx/MS
+spic/S
+spice/DSMG
+spicily
+spiciness/M
+spick/S
+spicule/MS
+spicy/PRT
+spider/SM
+spiderweb/MS
+spidery
+spiel/SMDG
+spiff/SDG
+spiffy/TR
+spigot/SM
+spike/DSMG
+spikiness/M
+spiky/RPT
+spill/SMDG
+spillage/MS
+spillover/SM
+spillway/MS
+spin/MS
+spina
+spinach/M
+spinal/SMY
+spindle/MGDS
+spindly/TR
+spine/SM
+spineless/YP
+spinet/SM
+spinless
+spinnaker/SM
+spinner/MS
+spinneret/SM
+spinney/S
+spinning/M
+spinoff/MS
+spinster/SM
+spinsterhood/M
+spinsterish
+spiny/RT
+spiracle/SM
+spiraea/MS
+spiral/SGMDY
+spire's
+spire/IFAS
+spirea/SM
+spirit's
+spirit/ISGD
+spirited/Y
+spiritless
+spiritual/MYS
+spiritualism/M
+spiritualist/MS
+spiritualistic
+spirituality/M
+spirituous
+spirochete/SM
+spiry
+spit/MDGS
+spitball/ZGSMR
+spite/ASM
+spiteful/PY
+spitefuller
+spitefullest
+spitefulness/M
+spitfire/SM
+spitted
+spitting
+spittle/M
+spittoon/MS
+spiv/S
+splanchnic
+splash/GMDS
+splashdown/MS
+splashily
+splashiness/M
+splashy/RTP
+splat/SM
+splatted
+splatter/GSMD
+splatting
+splay/SMDG
+splayfeet
+splayfoot/MD
+spleen/SM
+splendid/RYT
+splendor/MS
+splendorous
+splenectomy
+splenetic
+splice/DRSMZG
+splicer/M
+spliff/S
+spline/S
+splint/SZGMDR
+splinter/MDG
+splintery
+split/SM
+splitter/MS
+splitting/MS
+splodge/S
+splosh/DSG
+splotch/MDSG
+splotchy/TR
+splurge/DSMG
+splutter/GMDS
+spoil's
+spoil/CSDRZG
+spoilage/M
+spoiled/U
+spoiler/CM
+spoilsport/MS
+spoke/SM
+spoken/U
+spokesman/M
+spokesmen
+spokespeople
+spokesperson/MS
+spokeswoman/M
+spokeswomen
+spoliation/CM
+sponge/DRSMZG
+sponger/M
+sponginess/M
+spongy/RPT
+sponsor/MDGS
+sponsorship/SM
+spontaneity/M
+spontaneous/Y
+spoof/SMDG
+spook/SMDG
+spookiness/M
+spooky/RPT
+spool/SMDG
+spoon/SMDG
+spoonbill/MS
+spoonerism/MS
+spoonful/SM
+spoor/SMDG
+sporadic
+sporadically
+spore/DSMG
+sporran/S
+sport/SMDGV
+sportiness/M
+sporting/Y
+sportive/Y
+sportscast/MRZGS
+sportscaster/M
+sportsman/M
+sportsmanlike/U
+sportsmanship/M
+sportsmen
+sportspeople
+sportsperson
+sportswear/M
+sportswoman/M
+sportswomen
+sportswriter/SM
+sporty/TPR
+spot/CMS
+spotless/PY
+spotlessness/M
+spotlight/GSMD
+spotlit
+spotted
+spotter/MS
+spottily
+spottiness/M
+spotting
+spotty/TPR
+spousal/MS
+spouse/SM
+spout/SMDG
+sprain/GSMD
+sprang
+sprat/SM
+sprawl/GSMD
+spray's
+spray/ASDG
+sprayer/MS
+spread/ZGBSMR
+spreadeagled
+spreader/M
+spreadsheet/MS
+spree/DSM
+spreeing
+sprig/SM
+sprigged
+sprightliness/M
+sprightly/RTP
+spring/GSM
+springboard/MS
+springbok/MS
+springily
+springiness/M
+springlike
+springtime/M
+springy/RPT
+sprinkle/DRSJMZG
+sprinkler/M
+sprinkling/M
+sprint/ZGSMDR
+sprinter/M
+sprite/SM
+spritz/ZGMDRS
+spritzer/M
+sprocket/MS
+sprog/S
+sprout/GSMD
+spruce/DRSPMYTG
+spruceness/M
+sprung
+spry/RYT
+spryness/M
+spud/MS
+spume/DSMG
+spumoni/M
+spumy
+spun
+spunk/SM
+spunky/TR
+spur/MS
+spurge/M
+spurious/PY
+spuriousness/M
+spurn/SDG
+spurred
+spurring
+spurt/SMDG
+sputa
+sputnik/MS
+sputter/MDGS
+sputum/M
+spy/GDSM
+spyglass/MS
+spymaster/S
+spyware/MS
+sq
+sqq
+squab/SM
+squabble/MZGDRS
+squabbler/M
+squad/SM
+squadron/MS
+squalid/PTRY
+squalidness/M
+squall/SGMD
+squally
+squalor/M
+squamous
+squander/GDS
+square/PDRSMYTG
+squareness/M
+squarish
+squash/GMDS
+squashy/TR
+squat/SMP
+squatness/M
+squatted
+squatter/MS
+squattest
+squatting
+squaw/SM
+squawk/SZGMDR
+squawker/M
+squeak/SZGMDR
+squeaker/M
+squeakily
+squeakiness/M
+squeaky/TRP
+squeal/SZGMDR
+squealer/M
+squeamish/PY
+squeamishness/M
+squeegee/MDS
+squeegeeing
+squeeze/BMZGDRS
+squeezebox/S
+squeezer/M
+squelch/GMDS
+squelchy
+squib/SM
+squid/SM
+squidgy
+squiffy
+squiggle/DSMG
+squiggly
+squint/STGMDR
+squire/DSMG
+squirm/SGMD
+squirmy/RT
+squirrel/SGMD
+squirt/SGMD
+squish/GMDS
+squishy/RT
+sriracha
+ssh
+st
+stab/MYS
+stabbed
+stabber/MS
+stabbing/MS
+stability/IM
+stabilization/CM
+stabilize/CDSG
+stabilizer/MS
+stable/DRSMTG
+stableman/M
+stablemate/S
+stablemen
+stably/U
+staccato/MS
+stack/SMDG
+stadium/MS
+staff's
+staff/ASDG
+staffer/MS
+staffing/M
+stag/MDGSJ
+stage/SM
+stagecoach/MS
+stagecraft/M
+stagehand/MS
+stagestruck
+stagey
+stagflation/M
+stagger/MDGS
+staggering/Y
+staging/M
+stagnancy/M
+stagnant/Y
+stagnate/DSGN
+stagnation/M
+stagy/RT
+staid/PRYT
+staidness/M
+stain/SMDG
+stained/U
+stainless/M
+stair/SM
+staircase/MS
+stairway/MS
+stairwell/SM
+stake/DSMG
+stakeholder/MS
+stakeout/SM
+stalactite/MS
+stalagmite/MS
+stale/DRSTGP
+stalemate/DSMG
+staleness/M
+stalk/SMDRJZG
+stalker/M
+stalking/M
+stall's
+stall/SDG
+stallholder/S
+stallion/MS
+stalwart/MYS
+stamen/SM
+stamina/M
+stammer/ZGMDRS
+stammerer/M
+stammering/Y
+stamp/SMDRZG
+stampede/MGDS
+stamper/M
+stance/ISM
+stanch/TGDRS
+stanchion/SM
+stand/SMRJZG
+standalone
+standard/MS
+standardization/M
+standardize/DSG
+standby/M
+standbys
+standee/MS
+stander/M
+standing/M
+standoff/MS
+standoffish
+standout/MS
+standpipe/SM
+standpoint/MS
+standstill/MS
+standup/M
+stank
+stanza/SM
+staph/M
+staphylococcal
+staphylococci
+staphylococcus/M
+staple/DRSMZG
+stapler/M
+star/MDRZGS
+starboard/M
+starburst/S
+starch/GMDS
+starchily
+starchiness/M
+starchy/PTR
+stardom/M
+stardust/M
+stare/SM
+starer/M
+starfish/MS
+starfruit
+stargaze/DRSZG
+stargazer/M
+stark/RYPZT
+starkness/M
+starless
+starlet/MS
+starlight/M
+starling/SM
+starlit
+starred
+starring
+starry/TR
+starstruck
+start/ASMDG
+starter/MS
+startle/GDS
+startling/Y
+startup/MS
+starvation/M
+starve/DSJG
+starveling/MS
+stash/MDSG
+stasis
+stat/MS
+state/DRSMYGNLX
+statecraft/M
+stated/U
+statehood/M
+statehouse/MS
+stateless/P
+statelessness/M
+stateliness/M
+stately/PRT
+statement/AMS
+statemented
+statementing
+stateroom/MS
+stateside
+statesman/M
+statesmanlike
+statesmanship/M
+statesmen
+stateswoman/M
+stateswomen
+statewide
+static/SM
+statically
+station/MDRZG
+stationary
+stationer/M
+stationery/M
+stationmaster/S
+statistic/MS
+statistical/Y
+statistician/SM
+statuary/M
+statue/SM
+statuesque
+statuette/MS
+stature/MS
+status/MS
+statute/MS
+statutorily
+statutory
+staunch/PDRSYTG
+staunchness/M
+stave/DSMG
+stay/MDRZGS
+std
+stdio
+stead/SM
+steadfast/YP
+steadfastness/M
+steadily/U
+steadiness/UM
+steady/TGPDRSM
+steak/SM
+steakhouse/SM
+steal/SMRHZG
+stealth/M
+stealthily
+stealthiness/M
+stealthy/TPR
+steam/SMDRZG
+steamboat/MS
+steamer/M
+steamfitter/SM
+steamfitting/M
+steaminess/M
+steampunk
+steamroll/ZGDRS
+steamroller/MDG
+steamship/MS
+steamy/TPR
+steed/SM
+steel/SMDG
+steeliness/M
+steelmaker/S
+steelworker/SM
+steelworks/M
+steely/PTR
+steelyard/SM
+steep/SMDNRYPXTG
+steepen/GD
+steeple/MS
+steeplechase/MS
+steeplejack/SM
+steepness/M
+steer/SMDBG
+steerage/M
+steering/M
+steersman/M
+steersmen
+stegosauri
+stegosaurus/MS
+stein/SM
+stellar
+stem/MS
+stemless
+stemmed
+stemming
+stemware/M
+stench/MS
+stencil/GMDS
+steno/SM
+stenographer/SM
+stenographic
+stenography/M
+stenosis
+stent/SM
+stentorian
+step/IMS
+stepbrother/SM
+stepchild/M
+stepchildren/M
+stepdad/MS
+stepdaughter/SM
+stepfather/SM
+stepladder/MS
+stepmom/MS
+stepmother/SM
+stepparent/SM
+steppe/DRSMZG
+stepper/M
+steppingstone/SM
+stepsister/MS
+stepson/MS
+steradian
+stereo/SM
+stereogram/MS
+stereophonic
+stereoscope/MS
+stereoscopic
+stereotype/DSMG
+stereotypical
+sterile
+sterility/M
+sterilization/SM
+sterilize/DRSZG
+sterilizer/M
+sterling/M
+stern/SMRYPT
+sternness/M
+sternum/MS
+steroid/MS
+steroidal
+stertorous
+stet/S
+stethoscope/MS
+stetson/MS
+stetted
+stetting
+stevedore/SM
+stevia/M
+stew/MDGS
+steward/GMDS
+stewardess/MS
+stewardship/M
+stick/SMRZG
+sticker/M
+stickily
+stickiness/M
+stickleback/SM
+stickler/MS
+stickpin/MS
+stickup/MS
+sticky/PTRSM
+stiff/SMDNRYPXTG
+stiffen/ZGDR
+stiffener/M
+stiffening/M
+stiffness/M
+stifle/DSJG
+stifling/Y
+stigma/SM
+stigmata
+stigmatic
+stigmatization/M
+stigmatize/GDS
+stile/SM
+stiletto/SM
+still's
+still/ITGSD
+stillbirth/M
+stillbirths
+stillborn
+stiller
+stillness/M
+stilt/SMD
+stilted/Y
+stimulant/SM
+stimulate/DSGNV
+stimulation/M
+stimuli
+stimulus/M
+sting/ZGSMR
+stinger/M
+stingily
+stinginess/M
+stingray/SM
+stingy/RTP
+stink/ZGSMR
+stinkbug/SM
+stinker/M
+stinky/RT
+stint/GSMD
+stipend/SM
+stipendiary/S
+stipple/DSMG
+stippling/M
+stipulate/XDSGN
+stipulation/M
+stir/MS
+stirred
+stirrer/SM
+stirring/SY
+stirrup/SM
+stitch's
+stitch/ADSG
+stitchery/M
+stitching/M
+stoat/SM
+stochastic
+stock's
+stock/AGSD
+stockade/DSMG
+stockbreeder/MS
+stockbroker/SM
+stockbroking/M
+stockholder/SM
+stockily
+stockiness/M
+stockinet/M
+stockinette/M
+stocking/SM
+stockist/S
+stockpile/MGDS
+stockpot/SM
+stockroom/MS
+stocktaking/M
+stocky/RTP
+stockyard/MS
+stodge
+stodgily
+stodginess/M
+stodgy/RTP
+stogie/M
+stogy/SM
+stoic/SM
+stoical/Y
+stoicism/M
+stoke/DRSZG
+stoker/M
+stole/SM
+stolen
+stolid/RYTP
+stolidity/M
+stolidness/M
+stolon/MS
+stomach/MDRZG
+stomachache/SM
+stomacher/M
+stomachs
+stomp/GSMD
+stone/DRSMZG
+stonemason/MS
+stoner/M
+stonewall/GSD
+stoneware/M
+stonewashed
+stonework/M
+stonily
+stoniness/M
+stonkered
+stonking
+stony/TRP
+stood
+stooge/MS
+stool/SM
+stoolie/SM
+stoop/GSMD
+stop's
+stop/US
+stopcock/SM
+stopgap/SM
+stoplight/MS
+stopover/MS
+stoppable/U
+stoppage/MS
+stopped/U
+stopper/GSMD
+stopping/U
+stopple/DSMG
+stopwatch/MS
+stopword/S
+storage/M
+store's
+store/ADSG
+storefront/MS
+storehouse/MS
+storekeeper/SM
+storeroom/SM
+stork/SM
+storm/GSMD
+stormily
+storminess/M
+stormy/RPT
+story/DSM
+storyboard/MS
+storybook/SM
+storyteller/MS
+storytelling/M
+stoup/SM
+stout/TSMRYP
+stouthearted
+stoutness/M
+stove/SM
+stovepipe/SM
+stow/DGS
+stowage/M
+stowaway/MS
+straddle/DRSMZG
+straddler/M
+strafe/MGDS
+straggle/DRSZG
+straggler/M
+straggly/TR
+straight/SPXTMNRY
+straightaway/SM
+straightedge/SM
+straighten/ZGDR
+straightener/M
+straightforward/YPS
+straightforwardness/M
+straightness/M
+straightway
+strain's
+strain/FADSG
+strainer/ASM
+strait/MNSX
+straiten/GD
+straitjacket/SGMD
+straitlaced
+strand/MDSG
+strange/PRYZT
+strangeness/M
+stranger/M
+strangle/ZGDRS
+stranglehold/SM
+strangler/M
+strangulate/GNDS
+strangulation/M
+strap's
+strap/US
+strapless/MS
+strapped/U
+strapping/M
+strata
+stratagem/SM
+strategic/S
+strategical/Y
+strategics/M
+strategist/SM
+strategize/DG
+strategy/SM
+strati
+stratification/M
+stratify/DSGN
+stratosphere/SM
+stratospheric
+stratum/M
+stratus/M
+straw/GSMD
+strawberry/SM
+stray/GSMD
+streak/MDRSZG
+streaker/M
+streaky/TR
+stream/MDRSZG
+streamer/M
+streamline/DSG
+street/MS
+streetcar/MS
+streetlamp/S
+streetlight/SM
+streetwalker/SM
+streetwalking
+streetwise
+strength/M
+strengthen/AGDS
+strengthener/MS
+strengths
+strenuous/PY
+strenuousness/M
+strep/M
+streptococcal
+streptococci
+streptococcus/M
+streptomycin/M
+stress/MDSG
+stressed/U
+stressful
+stressors
+stretch/BZGMDRS
+stretcher/MDG
+stretchmarks
+stretchy/TR
+strew/GSDH
+strewn
+stria/M
+striae
+striated
+striation/MS
+stricken
+strict/RYPT
+strictness/M
+stricture/SM
+stridden
+stride/MGS
+stridency/M
+strident/Y
+strife/M
+strike/MZGRSJ
+strikebound
+strikebreaker/SM
+strikebreaking
+strikeout/MS
+striker/M
+striking/Y
+string/MDRSZG
+stringency/M
+stringent/Y
+stringer/M
+stringiness/M
+stringy/PTR
+strip/GSMD
+stripe/MS
+stripey
+stripling/MS
+stripped
+stripper/MS
+stripping
+striptease/MZGDRS
+stripteaser/M
+stripy
+strive/GS
+striven
+strobe/MS
+stroboscope/MS
+stroboscopic
+strode
+stroke/MGDS
+stroll/MDRSZG
+stroller/M
+strong/RYT
+strongbox/MS
+stronghold/MS
+strongman/M
+strongmen
+strongroom/S
+strontium/M
+strop/SM
+strophe/SM
+strophic
+stropped
+stroppily
+stropping
+stroppy/TRP
+strove
+struck
+struct/CFSM
+structural/Y
+structuralism
+structuralist/S
+structure's
+structure/AGDS
+structured/U
+strudel/SM
+struggle/MGDS
+strum/SM
+strummed
+strumming
+strumpet/MS
+strung/UA
+strut/SM
+strutted
+strutting
+strychnine/M
+stub/MS
+stubbed
+stubbing
+stubble/M
+stubbly
+stubborn/RYPT
+stubbornness/M
+stubby/RT
+stucco/MDG
+stuccoes
+stuck/U
+stud/MYS
+studbook/MS
+studded
+studding/M
+student/SM
+studentship/S
+studied/U
+studiedly
+studio/MS
+studious/PY
+studiousness/M
+studly/RT
+study's
+study/AGDS
+stuff/GSMDJ
+stuffily
+stuffiness/M
+stuffing/M
+stuffy/RPT
+stultification/M
+stultify/DSNG
+stumble/DRSMZG
+stumbler/M
+stump/GSMD
+stumpy/TR
+stun/S
+stung
+stunk
+stunned
+stunner/S
+stunning/Y
+stunt/GSMD
+stuntman
+stuntmen
+stupefaction/M
+stupefy/DSG
+stupefying/Y
+stupendous/Y
+stupid/TMRYS
+stupidity/SM
+stupor/MS
+sturdily
+sturdiness/M
+sturdy/TRP
+sturgeon/SM
+stutter/MDRSZG
+stutterer/M
+sty/SM
+stye/MS
+style's
+style/ADSG
+styli
+stylish/PY
+stylishness/M
+stylist/SM
+stylistic/S
+stylistically
+stylize/DSG
+stylometric
+stylometry/S
+stylus/MS
+stymie/MDS
+stymieing
+styptic/SM
+suasion/EM
+suave/RYTP
+suaveness/M
+suavity/M
+sub/SM
+subaltern/MS
+subaqua
+subarctic
+subarea/MS
+subatomic
+subbasement/SM
+subbed
+subbing
+subbranch/MS
+subcategory/SM
+subclass
+subcommittee/SM
+subcompact/SM
+subconscious/PMY
+subconsciousness/M
+subcontinent/SM
+subcontinental
+subcontract/MDSG
+subcontractor/MS
+subculture/MS
+subcutaneous/Y
+subdivide/GDS
+subdivision/SM
+subdomain/MS
+subdominant
+subdue/DSG
+subeditor/S
+subfamily/SM
+subfreezing
+subgroup/MS
+subhead/GJMS
+subheading/M
+subhuman/MS
+subj
+subject/GVMDS
+subjection/M
+subjective/Y
+subjectivity/M
+subjoin/GDS
+subjugate/GNDS
+subjugation/M
+subjunctive/SM
+sublate/MGDS
+sublease/MGDS
+sublet/SM
+subletting
+sublieutenant/S
+sublimate/GNDS
+sublimation/M
+sublime/YTGDRS
+subliminal/Y
+sublimity/M
+sublingual
+submarginal
+submarine/MZRS
+submariner/M
+submerge/GDS
+submergence/M
+submerse/GNDS
+submersible/MS
+submersion/M
+submicroscopic
+submission's/A
+submission/MS
+submissive/PY
+submissiveness/M
+submit/AS
+submitted/A
+submitter
+submitting/A
+subnormal
+suborbital
+suborder/MS
+subordinate/DSMGN
+subordination/IM
+suborn/SGD
+subornation/M
+subpar
+subparagraph
+subparagraphs
+subpart
+subplot/MS
+subpoena/GMDS
+subpoenable
+subprime
+subprofessional/SM
+subprogram/S
+subrogate/DSN
+subroutine/SM
+subscribe/UASDG
+subscriber/MS
+subscript/MS
+subscription/MS
+subsection/MS
+subsequent/Y
+subservience/M
+subservient/Y
+subset/SM
+subside/GDS
+subsidence/M
+subsidiarity
+subsidiary/SM
+subsidization/M
+subsidize/ZGDRS
+subsidizer/M
+subsidy/SM
+subsist/SDG
+subsistence/M
+subsoil/M
+subsonic
+subspace
+subspecies/M
+substance/SM
+substandard
+substantial/IY
+substantiate/GNDSX
+substantiated/U
+substantiation/FM
+substantive/SMY
+substation/MS
+substituent/MS
+substitute/XMGNDS
+substitution/M
+substrata
+substrate/MS
+substratum/M
+substructure/SM
+subsume/DSG
+subsumption/S
+subsurface/M
+subsystem/SM
+subteen/SM
+subtenancy/M
+subtenant/SM
+subtend/SDG
+subterfuge/SM
+subterranean
+subtext/SM
+subtitle/DSMG
+subtle/TR
+subtlety/SM
+subtly
+subtopic/SM
+subtotal/SGMD
+subtract/GVSD
+subtraction/SM
+subtrahend/SM
+subtropic/S
+subtropical
+subtropics/M
+subtweet/S
+suburb/MS
+suburban/SM
+suburbanite/SM
+suburbia/M
+subvention/SM
+subversion/M
+subversive/SPMY
+subversiveness/M
+subvert/SDG
+subway/MS
+subwoofer/S
+subzero
+succeed/GDS
+success/VMS
+successful/UY
+succession/SM
+successive/Y
+successor/SM
+succinct/RYTP
+succinctness/M
+succor/SGMD
+succotash/M
+succubi
+succubus
+succulence/M
+succulency/M
+succulent/SM
+succumb/GDS
+such
+suchlike
+suck/MDRZGS
+sucker/GMD
+suckle/DSJG
+suckling/M
+sucky
+sucrose/M
+suction/SMDG
+sudden/PY
+suddenness/M
+suds/M
+sudsy/TR
+sue/DSG
+suede/M
+suet/M
+suety
+suffer/DRZGSJ
+sufferance/M
+sufferer/M
+suffering/M
+suffice/DSG
+sufficiency/IM
+sufficient/IY
+suffix/MDSG
+suffixation/M
+suffocate/GNDS
+suffocation/M
+suffragan/MS
+suffrage/M
+suffragette/SM
+suffragist/MS
+suffuse/DSGN
+suffusion/M
+sugar/GSMD
+sugarcane/M
+sugarcoat/GDS
+sugarless
+sugarplum/MS
+sugary/RT
+suggest/GVSDR
+suggestibility/M
+suggestible
+suggestion/SM
+suggestive/YP
+suggestiveness/M
+suicidal
+suicide/SM
+suit/BMDGS
+suitability/UM
+suitableness/M
+suitably/U
+suitcase/SM
+suite/SM
+suited/U
+suiting/M
+suitor/MS
+sukiyaki/M
+sulfa/M
+sulfate/SM
+sulfide/SM
+sulfonamides
+sulfur/MDSG
+sulfuric
+sulfurous
+sulk/MDGS
+sulkily
+sulkiness/M
+sulky/TRSMP
+sullen/RYPT
+sullenness/M
+sullied/U
+sully/GDS
+sultan/MS
+sultana/SM
+sultanate/MS
+sultrily
+sultriness/M
+sultry/RPT
+sum/SM
+sumac/M
+summarily
+summarize/GDS
+summary/SM
+summat
+summation/FMS
+summed
+summer/MDSG
+summerhouse/SM
+summertime/M
+summery
+summing
+summit/MDS
+summitry/M
+summon/DRSZG
+summoner/M
+summons/GMDS
+sumo/M
+sump/MS
+sumptuous/PY
+sumptuousness/M
+sun/SM
+sunbath/ZGMDRS
+sunbathe
+sunbather/M
+sunbathing/M
+sunbaths
+sunbeam/SM
+sunbed/S
+sunbelt/SM
+sunblock/MS
+sunbonnet/SM
+sunburn/SGMD
+sunburst/MS
+sundae/MS
+sundeck/S
+sunder/DSG
+sundial/SM
+sundown/SM
+sundress/S
+sundries/M
+sundry/S
+sunfish/MS
+sunflower/MS
+sung/U
+sunglasses/M
+sunhat/S
+sunk/N
+sunlamp/SM
+sunless
+sunlight/M
+sunlit
+sunned
+sunniness/M
+sunning
+sunny/TRP
+sunrise/SM
+sunroof/SM
+sunscreen/MS
+sunset/MS
+sunshade/MS
+sunshine/M
+sunshiny
+sunspot/SM
+sunstroke/M
+suntan/MS
+suntanned
+suntanning
+suntrap/S
+sunup/M
+sup/SZMR
+super/M
+superabundance/MS
+superabundant
+superannuate/GNDS
+superannuation/M
+superb/RYT
+supercargo/M
+supercargoes
+supercharge/ZGDRS
+supercharger/M
+supercilious/PY
+superciliousness/M
+supercity/SM
+supercomputer/MS
+superconducting
+superconductive
+superconductivity/M
+superconductor/SM
+supercritical
+superego/MS
+supererogation/M
+supererogatory
+superficial/Y
+superficiality/M
+superfine
+superfluity/M
+superfluous/YP
+superfluousness/M
+superglue
+supergrass/S
+superhero/MS
+superheroes
+superhighway/SM
+superhuman
+superimpose/GDS
+superimposition/M
+superintend/DSG
+superintendence/M
+superintendency/M
+superintendent/SM
+superior/MS
+superiority/M
+superlative/SMY
+superman/M
+supermarket/SM
+supermassive
+supermen
+supermodel/SM
+supermom/MS
+supernal
+supernatural/SY
+supernova/MS
+supernovae
+supernumerary/SM
+superpose/GDS
+superposition/M
+superpower/SM
+supersaturate/GNDS
+supersaturation/M
+superscribe/GDS
+superscript/MS
+superscription/M
+supersede/GDS
+superset
+supersize/GDS
+supersonic
+superspreader/SM
+superstar/MS
+superstardom
+superstate/S
+superstition/MS
+superstitious/Y
+superstore/MS
+superstructure/MS
+supertanker/MS
+superuser/S
+supervene/GDS
+supervention/M
+supervillain/MS
+supervise/XGNDS
+supervised/U
+supervision/M
+supervisor/MS
+supervisory
+superwoman/M
+superwomen
+supine/Y
+supp/DRZG
+supper/M
+suppertime
+suppl
+supplant/SDG
+supple/TLPR
+supplement/MDGS
+supplemental
+supplementary
+supplementation/M
+suppleness/M
+suppliant/SM
+supplicant/MS
+supplicate/GDS
+supplication/M
+supplier/M
+supply/ZGDRSMXN
+support/MDRSBZGV
+supportable/UI
+supported/U
+supporter/M
+suppose/GDS
+supposed/Y
+supposition/MS
+suppository/SM
+suppress/GVDS
+suppressant/MS
+suppressible
+suppression/M
+suppressor/SM
+suppurate/DSGN
+suppuration/M
+supra
+supranational
+supremacist/MS
+supremacy/M
+supreme/Y
+supremo/S
+supt
+surcease/DSMG
+surcharge/DSMG
+surcingle/SM
+sure/PYTR
+surefire
+surefooted
+sureness/M
+surety/SM
+surf/MDRZGS
+surface's
+surface/AGDS
+surfboard/MDSG
+surfeit/MDSG
+surfer/M
+surfing/M
+surge/DSMG
+surgeon/MS
+surgery/SM
+surgical/Y
+surjection/S
+surliness/M
+surly/PTR
+surmise/MGDS
+surmount/DGSB
+surmountable/I
+surname/MS
+surpass/GDS
+surpassed/U
+surplice/MS
+surplus/MS
+surplussed
+surplussing
+surprise/DSMGJ
+surprising/UY
+surreal
+surrealism/M
+surrealist/SM
+surrealistic
+surrealistically
+surrender/MDSG
+surreptitious/PY
+surreptitiousness/M
+surrey/MS
+surrogacy/M
+surrogate/SM
+surround/GSDJ
+surrounding/M
+surroundings/M
+surtax/MDSG
+surtitle/S
+surveil/S
+surveillance/SM
+surveillant/MS
+surveilled
+surveilling
+survey's
+survey/ADGS
+surveying/M
+surveyor/SM
+survival/SM
+survivalist/SM
+survive/DSGB
+survivor/SM
+survivorship
+susceptibility/SM
+susceptible/I
+sushi/M
+suspect/SMDG
+suspected/U
+suspend/SDRZG
+suspender/M
+suspense/XMN
+suspenseful
+suspension/M
+suspicion/SM
+suspicious/Y
+suss/DSG
+sustain/SDBG
+sustainability
+sustainable/U
+sustainably
+sustenance/M
+sutler/MS
+suttee
+suture/MGDS
+suzerain/MS
+suzerainty/M
+svelte/TR
+swab/MS
+swabbed
+swabbing
+swaddle/DSG
+swag/MS
+swagged
+swagger/SMDRG
+swagging
+swain/SM
+swallow/GSMD
+swallowtail/MS
+swam
+swami/SM
+swamp/GSMD
+swampland/M
+swampy/RT
+swan/MS
+swank/TGSMDR
+swankily
+swankiness/M
+swanky/RPT
+swanned
+swanning
+swansdown/M
+swansong/S
+swap/MS
+swapped
+swapping
+sward/SM
+swarm/GSMD
+swarthy/TR
+swash/GMDS
+swashbuckler/SM
+swashbuckling/M
+swastika/SM
+swat/MS
+swatch/MS
+swath/GMDS
+swathe/M
+swaths
+swatted
+swatter/SMDG
+swatting
+sway/MDGS
+swayback/MD
+swayed/U
+swear/ZGSR
+swearer/M
+swearword/MS
+sweat/ZGSMDR
+sweatband/MS
+sweater/M
+sweatpants/M
+sweats/M
+sweatshirt/SM
+sweatshop/MS
+sweatsuit/S
+sweaty/RT
+swede/SM
+sweep/ZGSMRJ
+sweeper/M
+sweeping/MY
+sweepings/M
+sweepstakes/M
+sweet/XTSMNRYP
+sweetbread/SM
+sweetbriar/SM
+sweetbrier/SM
+sweetcorn
+sweetened/U
+sweetener/MS
+sweetening/M
+sweetheart/SM
+sweetie/SM
+sweetish
+sweetmeat/MS
+sweetness/M
+swell/TGSMDRJ
+swellhead/MDS
+swelling/M
+swelter/SGMD
+swept
+sweptback
+swerve/MGDS
+swerving/U
+swift/PTSMRY
+swiftness/M
+swig/MS
+swigged
+swigging
+swill/GSMD
+swim/MS
+swimmer/SM
+swimming/MY
+swimsuit/SM
+swimwear
+swindle/DRSMZG
+swindler/M
+swine/SM
+swineherd/SM
+swing/ZGSMR
+swingeing
+swinger/M
+swinish
+swipe/DSMG
+swirl/GSMD
+swirly
+swish/TGMDRS
+switch/MDRSZGB
+switchback/MS
+switchblade/SM
+switchboard/SM
+switcher/M
+switcheroo/S
+switchover
+swivel/MDGS
+swiz
+swizz
+swizzle/DSG
+swollen
+swoon/SGMD
+swoop/SGMD
+swoosh/MDSG
+sword/SM
+swordfish/MS
+swordplay/M
+swordsman/M
+swordsmanship/M
+swordsmen
+swore
+sworn
+swot/S
+swotted
+swotting
+swum
+swung
+sybarite/SM
+sybaritic
+sycamore/MS
+sycophancy/M
+sycophant/SM
+sycophantic
+syllabi
+syllabic
+syllabicate/GNDS
+syllabication/M
+syllabification/M
+syllabify/DSNG
+syllable/MS
+syllabub/S
+syllabus/MS
+syllogism/MS
+syllogistic
+sylph/M
+sylphic
+sylphlike
+sylphs
+sylvan
+symbioses
+symbiosis/M
+symbiote/S
+symbiotic
+symbiotically
+symbol/MS
+symbolic
+symbolical/Y
+symbolism/M
+symbolization/M
+symbolize/DSG
+symbology
+symmetric/Y
+symmetrical/Y
+symmetry/SM
+sympathetic/U
+sympathetically/U
+sympathies/M
+sympathize/ZGDRS
+sympathizer/M
+sympathy/SM
+symphonic
+symphony/SM
+symposium/MS
+symptom/MS
+symptomatic
+symptomatically
+syn/H
+synagogal
+synagogue/SM
+synapse/MS
+synaptic
+sync/MDSG
+synches
+synchronicity
+synchronism/M
+synchronization/SM
+synchronize/ZGDRS
+synchronizer/M
+synchronous/Y
+synchrony
+syncopate/DSGN
+syncopation/M
+syncope/M
+syndicalism
+syndicalist/S
+syndicate/DSMGN
+syndication/M
+syndrome/SM
+synergism/M
+synergistic
+synergy/SM
+synesthesia
+synesthete/S
+synesthetic
+synfuel/MS
+synod/SM
+synonym/SM
+synonymous
+synonymy/M
+synopses
+synopsis/M
+synoptic
+synovial
+syntactic
+syntactical/Y
+syntax/M
+synthase/SM
+syntheses
+synthesis/M
+synthesize/ZGDRS
+synthesizer/M
+synthetic/SM
+synthetically
+synths
+syphilis/M
+syphilitic/SM
+syringe/DSMG
+syrup/SM
+syrupy
+sysadmin/MS
+sysop/SM
+system/SM
+systematic/U
+systematical/Y
+systematization/M
+systematize/GDS
+systemic/MS
+systemically
+systole/SM
+systolic
+s辿ance/SM
+t/SDNXGBJ
+tRNA/M
+ta
+tab/SM
+tabbed
+tabbing
+tabbouleh/M
+tabby/SM
+tabernacle/SM
+tabla/MS
+table/MGDS
+tableau/M
+tableaux
+tablecloth/M
+tablecloths
+tableland/SM
+tablespoon/SM
+tablespoonful/SM
+tablet/SM
+tabletop/MS
+tableware/M
+tabloid/SM
+taboo/MDSG
+tabor/MS
+tabular
+tabulate/DSGNX
+tabulation/M
+tabulator/SM
+tachograph
+tachographs
+tachometer/SM
+tachycardia/M
+tachyon
+tacit/PY
+tacitness/M
+taciturn/Y
+taciturnity/M
+tack/ZGMDRS
+tacker/M
+tackiness/M
+tackle/DRSMZG
+tackler/M
+tacky/RTP
+taco/MS
+tact/FM
+tactful/YP
+tactfulness/M
+tactic/SM
+tactical/Y
+tactician/MS
+tactile
+tactility/M
+tactless/PY
+tactlessness/M
+tad/SM
+tadpole/MS
+taffeta/M
+taffrail/SM
+taffy/SM
+tag/SM
+tagged
+tagger/SM
+tagging
+tagliatelle
+tagline/MS
+taiga/MS
+tail/ACSDMG
+tailback/MS
+tailboard/S
+tailbone/S
+tailcoat/MS
+tailgate/MZGDRS
+tailgater/M
+tailless
+taillight/MS
+tailor/SGMD
+tailoring/M
+tailpiece/S
+tailpipe/SM
+tailspin/SM
+tailwind/SM
+taint/MDSG
+tainted/U
+take/AIMS
+takeaway/S
+taken/A
+takeoff/MS
+takeout/MS
+takeover/SM
+taker/MS
+taking/SM
+takings/M
+talc/M
+talcum/M
+tale/MS
+talebearer/MS
+talent/SMD
+talented/U
+tali
+talisman/MS
+talk/ZGMDRS
+talkative/PY
+talkativeness/M
+talker/M
+talkie/RSMT
+talky
+tall/TRP
+tallboy/MS
+tallier/M
+tallish
+tallness/M
+tallow/M
+tallowy
+tally/DRSMZG
+tallyho/MDGS
+talon/MS
+talus/MS
+tam/SM
+tamale/SM
+tamarack/MS
+tamarind/MS
+tambourine/MS
+tame/BYZTGDRSP
+tameable
+tamed/U
+tameness/M
+tamer/M
+tamoxifen
+tamp/ZGDRS
+tamper/ZGDR
+tamperer/M
+tampon/SM
+tan/SM
+tanager/MS
+tanbark/M
+tandem/SM
+tandoori/M
+tang/MS
+tangelo/MS
+tangent/MS
+tangential/Y
+tangerine/MS
+tangibility/IM
+tangible/IMS
+tangibleness/M
+tangibly/I
+tangle's
+tangle/UDSG
+tango/MDSG
+tangy/RT
+tank/ZGMDRS
+tankard/MS
+tanker/M
+tankful/MS
+tanned/U
+tanner/SM
+tannery/SM
+tannest
+tannin/M
+tanning/M
+tansy/M
+tantalization/M
+tantalize/ZGDRS
+tantalizer/M
+tantalizing/Y
+tantalum/M
+tantamount
+tantra/M
+tantrum/SM
+tap/SZGMDR
+tapas
+tape/MS
+tapeline/MS
+taper/MDG
+tapestry/SM
+tapeworm/MS
+tapioca/M
+tapir/MS
+tapped/U
+tapper/MS
+tappet/MS
+tapping
+taproom/SM
+taproot/SM
+tar/SGMD
+taramasalata
+tarantella/MS
+tarantula/SM
+tarball/S
+tardily
+tardiness/M
+tardy/TPR
+tare/MS
+target/MDGS
+tariff/MS
+tarmac/MS
+tarmacadam
+tarmacked
+tarmacking
+tarn/MS
+tarnish/GMDS
+tarnished/U
+taro/MS
+tarot/MS
+tarp/MS
+tarpaulin/MS
+tarpon/MS
+tarragon/SM
+tarred
+tarring
+tarry/TGDRS
+tarsal/MS
+tarsi
+tarsus/M
+tart/PTGMDRYS
+tartan/MS
+tartar/MS
+tartaric
+tartness/M
+tarty/T
+taser/GMDS
+task/GMDS
+taskbar
+taskmaster/MS
+taskmistress/MS
+tassel/MDSG
+taste/JMZGDRS
+tasted/U
+tasteful/EPY
+tastefulness/EM
+tasteless/PY
+tastelessness/M
+taster/M
+tastily
+tastiness/M
+tasting/M
+tasty/TRP
+tat/SZR
+tatami/MS
+tater/M
+tatted
+tatter/MDSG
+tatterdemalion/MS
+tattie
+tatting/M
+tattle/MZGDRS
+tattler/M
+tattletale/MS
+tattoo/MDRSZG
+tattooer/M
+tattooist/SM
+tatty/TRS
+tau/SM
+taught/UA
+taunt/ZGMDRS
+taunter/M
+taunting/Y
+taupe/M
+taut/PXTNRY
+tauten/DG
+tautness/M
+tautological/Y
+tautologous
+tautology/SM
+tavern/MS
+tawdrily
+tawdriness/M
+tawdry/RTP
+tawny/TRM
+tax/BZGMDRS
+taxa
+taxation/M
+taxer/M
+taxi/GMDS
+taxicab/SM
+taxidermist/SM
+taxidermy/M
+taximeter/MS
+taxiway/S
+taxman
+taxmen
+taxon
+taxonomic
+taxonomical
+taxonomist/MS
+taxonomy/SM
+taxpayer/MS
+taxpaying
+tb/S
+tbsp
+tea/SM
+teabag/S
+teacake/SM
+teach/ZGRSBJ
+teachable/U
+teacher/M
+teaching/M
+teacup/MS
+teacupful/MS
+teak/MS
+teakettle/SM
+teal/MS
+tealight/MS
+team/GMDS
+teammate/MS
+teamster/MS
+teamwork/M
+teapot/MS
+tear/GMDS
+tearaway/S
+teardrop/SM
+tearful/Y
+teargas/MS
+teargassed
+teargassing
+tearjerker/MS
+tearoom/SM
+teary/TR
+tease/MZGDRS
+teasel/MS
+teaser/M
+teasing/Y
+teaspoon/SM
+teaspoonful/SM
+teat/MS
+teatime/S
+tebibyte/MS
+tech/M
+techie/S
+technetium/M
+technical/Y
+technicality/SM
+technician/SM
+technicolor
+technique/SM
+techno
+technobabble
+technocracy/SM
+technocrat/MS
+technocratic
+technological/Y
+technologist/MS
+technology/SM
+technophobe/S
+techs
+tectonic/S
+tectonics/M
+ted/S
+teddy/S
+tedious/PY
+tediousness/M
+tedium/M
+tee/DSMH
+teeing
+teem/GDS
+teen/MS
+teenage/RZ
+teenager/M
+teeny/TR
+teenybopper/MS
+teepee/MS
+teeter/MDSG
+teethe/GDS
+teething/M
+teetotal/RZ
+teetotaler/M
+teetotalism/M
+tektite/SM
+tel
+telecast/SZGMR
+telecaster/M
+telecom/M
+telecommunication/MS
+telecommunications/M
+telecommute/ZGDRS
+telecommuter/M
+telecommuting/M
+teleconference/MGDS
+teleconferencing/M
+telegenic
+telegram/MS
+telegraph/MDRZG
+telegrapher/M
+telegraphese
+telegraphic
+telegraphically
+telegraphist/SM
+telegraphs
+telegraphy/M
+telekinesis/M
+telekinetic
+telemarketer/SM
+telemarketing/M
+telemeter/SM
+telemetry/SM
+teleological
+teleology
+telepathic
+telepathically
+telepathy/M
+telephone/DRSMZG
+telephoner/M
+telephonic
+telephonist/S
+telephony/M
+telephoto/SM
+telephotography/M
+teleplay/MS
+teleport/DSG
+teleportation
+teleprinter/MS
+teleprocessing/M
+teleprompter/SM
+telesales
+telescope/DSMG
+telescopic
+telescopically
+teletext/MS
+telethon/MS
+teletype/S
+teletypewriter/MS
+televangelism/M
+televangelist/MS
+televise/XGNDS
+television/M
+teleworker/S
+teleworking
+telex/MDSG
+tell/AGS
+teller/SM
+telling/Y
+telltale/SM
+tellurium/M
+telly/SM
+telnet
+temblor/MS
+temerity/M
+temp/MDRZTGS
+temper/MDG
+tempera/LSM
+temperament/MS
+temperamental/Y
+temperance/IM
+temperate/IY
+temperateness/M
+temperature/SM
+tempest/SM
+tempestuous/YP
+tempestuousness/M
+tempi
+template's
+template/S
+temple/SM
+tempo/SM
+temporal/Y
+temporarily
+temporariness/M
+temporary/FSM
+temporize/ZGDRS
+temporizer/M
+tempt/SDRZG
+temptation/MS
+tempter/M
+tempting/Y
+temptress/MS
+tempura/M
+ten/BMH
+tenability/M
+tenable/U
+tenably
+tenacious/YP
+tenaciousness/M
+tenacity/M
+tenancy/SM
+tenant/SMDG
+tenanted/U
+tenantry/M
+tench
+tend/IFEDGS
+tended/U
+tendency/SM
+tendentious/YP
+tendentiousness/M
+tender/SMDRYTGP
+tenderfoot/MS
+tenderhearted/P
+tenderheartedness/M
+tenderize/ZGDRS
+tenderizer/M
+tenderloin/SM
+tenderness/M
+tendinitis/M
+tendon/SM
+tendonitis/M
+tendril/SM
+tenement/SM
+tenet/SM
+tenfold
+tenner/S
+tennis/M
+tenon/SMDG
+tenor/SM
+tenpin/SM
+tenpins/M
+tense/DRSMYTGNXP
+tenseness/M
+tensile
+tension/ESM
+tensity/IM
+tensor/S
+tent/DGSM
+tentacle/DSM
+tentative/PY
+tentativeness/M
+tenterhook/MS
+tenth/MY
+tenths
+tenuity/M
+tenuous/PY
+tenuousness/M
+tenure/DSMG
+tepee/SM
+tepid/YP
+tepidity/M
+tepidness/M
+tequila/SM
+terabit/SM
+terabyte/MS
+terahertz/M
+terajoule/S
+terapixel/MS
+terawatt/S
+terbium/M
+tercentenary/SM
+tercentennial/SM
+teriyaki
+term/MDYGS
+termagant/MS
+terminable/IC
+terminal/MYS
+terminate/DSGNX
+termination/CSM
+terminator/S
+termini
+terminological/Y
+terminology/SM
+terminus/M
+termite/SM
+tern/IMS
+ternary/SM
+terr
+terrace/DSMG
+terracotta/M
+terraforming/M
+terrain/SM
+terrapin/MS
+terrarium/SM
+terrazzo/MS
+terrestrial/SMY
+terrible/P
+terribleness/M
+terribly
+terrier/M
+terrific
+terrifically
+terrify/GDS
+terrifying/Y
+terrine/S
+territorial/MS
+territoriality
+territory/SM
+terror/SM
+terrorism/M
+terrorist/SM
+terrorize/DSG
+terry/RMZ
+terrycloth/M
+terse/RYTP
+terseness/M
+tertiary
+tessellate/DSXGN
+tessellation/M
+test's/AFK
+test/AKFCDGS
+testable/CF
+testament/MS
+testamentary
+testate/S
+testator/MS
+testatrices
+testatrix/M
+testcase/MS
+tested/U
+tester/KSM
+testes
+testicle/MS
+testicular
+testifier/M
+testify/ZGDRS
+testily
+testimonial/MS
+testimony/SM
+testiness/M
+testings
+testis/M
+testosterone/M
+testsuite/SM
+testy/PRT
+tetanus/M
+tetchily
+tetchy/PRT
+tether/SMDG
+tetra/SM
+tetracycline/M
+tetrahedral
+tetrahedron/MS
+tetrameter/SM
+text/FMS
+textbook/SM
+textbox/MS
+texted
+textile/MS
+texting
+textual/FY
+textural
+texture/MGDS
+thalami
+thalamus/M
+thaliana
+thalidomide/M
+thallium/M
+than
+thane/SM
+thank/SDG
+thankful/YP
+thankfulness/M
+thankless/PY
+thanklessness/M
+thanksgiving/SM
+that'd
+that'll
+that/M
+thatch/MDRSZG
+thatcher/M
+thatching/M
+thaw/MDGS
+the/JG
+theater/SM
+theatergoer/SM
+theatrical/YS
+theatricality/M
+theatricals/M
+theatrics/M
+thee/S
+theft/SM
+their/S
+theism/M
+theist/SM
+theistic
+them
+thematic
+thematically
+theme/DSMG
+themself
+themselves
+then/M
+thence
+thenceforth
+thenceforward
+theocracy/SM
+theocratic
+theodolite/S
+theologian/SM
+theological/Y
+theology/SM
+theorem/MS
+theoretic
+theoretical/Y
+theoretician/SM
+theorist/SM
+theorize/DSG
+theory/SM
+theosophic
+theosophical
+theosophist/SM
+theosophy/M
+therapeutic/S
+therapeutically
+therapeutics/M
+therapist/SM
+therapy/SM
+there/M
+thereabout/S
+thereafter
+thereat
+therebetween
+thereby
+therefor
+therefore
+therefrom
+therein
+theremin/SM
+thereof
+thereon
+thereto
+theretofore
+thereunder
+thereunto
+thereupon
+therewith
+therm/SM
+thermal/MYS
+thermionic
+thermobaric
+thermodynamic/S
+thermodynamics/M
+thermometer/MS
+thermometric
+thermonuclear
+thermoplastic/SM
+thermos/MS
+thermostat/MS
+thermostatic
+thermostatically
+thesauri
+thesaurus/MS
+these/S
+thesis/M
+thespian/SM
+theta/SM
+thew/MS
+they
+they'd
+they'll
+they're
+they've
+thiamine/M
+thick/PMNRYXT
+thicken/DRJZG
+thickener/M
+thickening/M
+thicket/MS
+thickheaded/M
+thickness/MS
+thicko/S
+thickset
+thief/M
+thieve/DSG
+thievery/M
+thieving/M
+thievish
+thigh/M
+thighbone/MS
+thighs
+thimble/MS
+thimbleful/SM
+thin/YSP
+thine
+thing/M
+thingamabob/SM
+thingamajig/SM
+thingumabob/S
+thingummy/S
+thingy/S
+think/SRBZG
+thinkable/U
+thinker/M
+thinking's
+thinned
+thinner/MS
+thinness/M
+thinnest
+thinning
+third/SMY
+thirst/SGMD
+thirstily
+thirstiness/M
+thirsty/TPR
+thirteen/SMH
+thirteenth/M
+thirteenths
+thirtieth/M
+thirtieths
+thirty/HSM
+this
+thistle/MS
+thistledown/M
+thither
+tho
+thole/SM
+thong/SM
+thoracic
+thoracotomy
+thorax/MS
+thorium/M
+thorn/SM
+thorniness/M
+thorny/PRT
+thorough/RYPT
+thoroughbred/MS
+thoroughfare/MS
+thoroughgoing
+thoroughness/M
+those
+thou/MS
+though
+thought/SM
+thoughtful/YP
+thoughtfulness/M
+thoughtless/PY
+thoughtlessness/M
+thousand/MHS
+thousandfold
+thousandth/M
+thousandths
+thraldom/M
+thrall/SMDG
+thralldom/M
+thrash/JMDRSZG
+thrasher/M
+thrashing/M
+thread/SMDRZG
+threadbare
+threader/M
+threadlike
+thready/TR
+threat/SMNX
+threaten/DG
+threatening/Y
+three/SM
+threefold
+threepence/M
+threescore/MS
+threesome/SM
+threnody/SM
+thresh/MDRSZG
+thresher/M
+threshold/SM
+threw
+thrice
+thrift/SM
+thriftily
+thriftiness/M
+thriftless
+thrifty/PTR
+thrill/SMDRZG
+thriller/M
+thrilling/Y
+thrive/DSG
+throat/SM
+throatily
+throatiness/M
+throaty/RTP
+throb/SM
+throbbed
+throbber
+throbbing
+throe/SM
+thrombi
+thrombolytic
+thromboses
+thrombosis/M
+thrombotic
+thrombus/M
+throne's
+throne/S
+throng/GSMD
+throttle/DRSMZG
+throttler/M
+through
+throughout
+throughput/M
+throughway/MS
+throw/SMRZG
+throwaway/SM
+throwback/SM
+thrower/M
+thrown
+thru
+thrum/SM
+thrummed
+thrumming
+thrush/MS
+thrust/ZGSMR
+thruway/MS
+thud/MS
+thudded
+thudding
+thug/MS
+thuggery/M
+thuggish
+thulium/M
+thumb/SMDG
+thumbnail/SM
+thumbprint/SM
+thumbscrew/SM
+thumbtack/SM
+thump/SMDG
+thumping/M
+thunder/ZGMDRS
+thunderbolt/SM
+thunderclap/SM
+thundercloud/MS
+thunderer/M
+thunderhead/SM
+thunderous/Y
+thundershower/SM
+thunderstorm/SM
+thunderstruck
+thundery
+thunk/S
+thus/Y
+thwack/ZGSMDR
+thwacker/M
+thwart/GSMD
+thy
+thyme/M
+thymine/M
+thymus/MS
+thyroid/MS
+thyroidal
+thyself
+ti/MRZ
+tiara/SM
+tibia/M
+tibiae
+tibial
+tic/SM
+tick/MDRZGS
+ticker/M
+ticket/GSMD
+ticking/M
+tickle/DRSMZG
+tickler/M
+ticklish/YP
+ticklishness/M
+ticktacktoe/M
+ticktock/MS
+tidal/Y
+tidbit/SM
+tiddler/S
+tiddly
+tiddlywink/S
+tiddlywinks/M
+tide/MGJDS
+tideland/SM
+tidemark/S
+tidewater/MS
+tideway/MS
+tidily/U
+tidiness/UM
+tidings/M
+tidy/DRSMTGP
+tie's
+tie/AUSD
+tieback/MS
+tiebreak/RSZ
+tiebreaker/M
+tiepin/S
+tier/MD
+tiff/MDGS
+tiger/SM
+tigerish
+tight/SNRYPXT
+tighten/ZGDR
+tightener/M
+tightfisted
+tightness/M
+tightrope/MS
+tights/M
+tightwad/MS
+tigress/MS
+til
+tilapia
+tilde/SM
+tile/MZGDRS
+tiler/M
+tiling/M
+till's
+till/EDRZGS
+tillable
+tillage/M
+tiller/EM
+tilt/MDGS
+timber/SMDG
+timberland/M
+timberline/MS
+timbre/SM
+timbrel/SM
+time/MYZGJDRS
+timekeeper/MS
+timekeeping/M
+timeless/PY
+timelessness/M
+timeline/MS
+timeliness/UM
+timely/UPRT
+timeout/SM
+timepiece/MS
+timer/M
+timescale/S
+timeserver/SM
+timeserving/M
+timeshare/S
+timestamp/SMD
+timetable/DSMG
+timeworn
+timezone
+timid/RYTP
+timidity/M
+timidness/M
+timing/M
+timorous/PY
+timorousness/M
+timothy/M
+timpani/M
+timpanist/SM
+tin/SM
+tincture/MGDS
+tinder/M
+tinderbox/MS
+tine/MS
+tinfoil/M
+ting/MDYG
+tinge/SM
+tingeing
+tingle/DSMGJ
+tingling/M
+tininess/M
+tinker/ZGSMDR
+tinkerer/M
+tinkle/DSMG
+tinned
+tinniness/M
+tinning
+tinnitus/M
+tinny/PRT
+tinplate/M
+tinpot
+tinsel/GSMD
+tinsmith/M
+tinsmiths
+tint/MDGS
+tintinnabulation/MS
+tintype/MS
+tinware/M
+tiny/RTP
+tip/SM
+tipped
+tipper/SM
+tippet/SM
+tippex/GDS
+tipping
+tipple/DRSMZG
+tippler/M
+tipsily
+tipsiness/M
+tipster/MS
+tipsy/RPT
+tiptoe/DSM
+tiptoeing
+tiptop/SM
+tirade/SM
+tiramisu/MS
+tire's
+tire/AGDS
+tired/PRYT
+tiredness/M
+tireless/YP
+tirelessness/M
+tiresome/PY
+tiresomeness/M
+tissue/SM
+tit/SM
+titan/SM
+titanic
+titanium/M
+titch/S
+titchy
+tithe/DRSMZG
+tither/M
+titian/M
+titillate/DSGN
+titillating/Y
+titillation/M
+titivate/DSGN
+titivation/M
+title/DSMG
+titled/U
+titleholder/MS
+titlist/MS
+titmice
+titmouse/M
+titter/SGMD
+tittivate/DSGN
+tittivation/M
+tittle/SM
+titty/S
+titular
+tizz
+tizzy/SM
+tn
+tnpk
+to/IU
+toad/MS
+toadstool/MS
+toady/DSMG
+toadyism/M
+toast/SMDRZG
+toaster/M
+toastmaster/SM
+toastmistress/MS
+toasty/TRS
+tobacco/MS
+tobacconist/SM
+toboggan/ZGSMDR
+tobogganer/M
+tobogganing/M
+toccata/S
+tocopherol
+tocsin/SM
+today/M
+toddle/DRSMZG
+toddler/M
+toddy/SM
+toe/DSM
+toecap/SM
+toehold/MS
+toeing
+toenail/MS
+toerag/S
+toff/S
+toffee/SM
+tofu/M
+tog/SM
+toga/MDS
+together/P
+togetherness/M
+togged
+togging
+toggle/DSMG
+togs/M
+toil/MDRZGS
+toiler/M
+toilet/MDGS
+toiletry/SM
+toilette/M
+toilsome
+toke/MGDS
+token/SM
+tokenism/M
+told/AU
+tole/M
+tolerable/I
+tolerably/I
+tolerance/IM
+tolerances
+tolerant/IY
+tolerate/GNDS
+toleration/M
+toll/MDGS
+tollbooth/M
+tollbooths
+tollgate/SM
+tollway/SM
+toluene/M
+tom/SM
+tomahawk/SGMD
+tomato/M
+tomatoes
+tomb/MDGS
+tombola/S
+tomboy/MS
+tomboyish
+tombstone/MS
+tomcat/MS
+tome/MS
+tomfoolery/SM
+tomographic
+tomography/M
+tomorrow/MS
+tomtit/MS
+ton/SM
+tonal/Y
+tonality/SM
+tone's
+tone/IZGDRS
+tonearm/SM
+toneless/Y
+toner/IM
+tong/MDGS
+tongue/MGDS
+tongueless
+tonic/SM
+tonight/M
+tonnage/SM
+tonne/SM
+tonsil/MS
+tonsillectomy/SM
+tonsillitis/M
+tonsorial
+tonsure/DSMG
+tony/RT
+too
+toodles
+took/A
+tool's
+tool/ADGS
+toolbar/SM
+toolbox/MS
+toolkit
+toolmaker/MS
+toot/MDRZGS
+tooter/M
+tooth/MD
+toothache/MS
+toothbrush/MS
+toothily
+toothless
+toothpaste/SM
+toothpick/SM
+toothsome
+toothy/RT
+tootle/GDS
+tootsie/S
+top/SM
+topaz/MS
+topcoat/SM
+topdressing/SM
+topee/S
+topflight
+topi/S
+topiary/M
+topic/SM
+topical/Y
+topicality/M
+topknot/SM
+topless
+topmast/SM
+topmost
+topnotch
+topographer/SM
+topographic
+topographical/Y
+topography/SM
+topological/Y
+topology
+topped
+topper/MS
+topping/SM
+topple/GDS
+topsail/SM
+topside/SM
+topsoil/M
+topspin/M
+toque/SM
+tor/SM
+torah/M
+torahs
+torch/GMDS
+torchbearer/MS
+torchlight/M
+tore
+toreador/MS
+torment/SMDG
+tormenting/Y
+tormentor/MS
+torn
+tornado/M
+tornadoes
+torpedo/GMD
+torpedoes
+torpid/Y
+torpidity/M
+torpor/M
+torque/MGDS
+torrent/SM
+torrential
+torrid/YP
+torridity/M
+torridness/M
+torsion/M
+torsional
+torso/SM
+tort's
+tort/EFAS
+torte/SM
+tortellini/M
+tortilla/MS
+tortoise/MS
+tortoiseshell/SM
+tortoni/M
+tortuous/PY
+tortuousness/M
+torture/DRSMZG
+torturer/M
+torturous
+torus
+tosh
+toss/MDRSZG
+tossup/MS
+tot/SGMD
+total/GSMDY
+totalitarian/SM
+totalitarianism/M
+totality/SM
+totalizator/SM
+tote/MS
+totem/SM
+totemic
+totted
+totter/ZGMDRS
+totterer/M
+totting
+toucan/MS
+touch/AGMDS
+touchdown/SM
+touche/BJ
+touched/U
+touchily
+touchiness/M
+touching/Y
+touchline/S
+touchpaper/S
+touchscreen/MS
+touchstone/MS
+touchy/RPT
+touch辿
+tough/XTGMDNRYP
+toughen/ZGDR
+toughener/M
+toughie/SM
+toughness/M
+toughs
+toupee/MS
+tour/CFSGDM
+tourism/M
+tourist/MS
+touristic
+touristy
+tourmaline/M
+tournament/SM
+tourney/MS
+tourniquet/MS
+tousle/GDS
+tout/MDGS
+tow/SZGMDR
+toward/S
+towboat/MS
+towel/JGSMD
+towelette/SM
+toweling/M
+tower/GMD
+towhead/MDS
+towhee/MS
+towline/MS
+town/MS
+townee/S
+townhouse/MS
+townie/MS
+townsfolk/M
+township/MS
+townsman/M
+townsmen
+townspeople/M
+townswoman/M
+townswomen
+towpath/M
+towpaths
+towrope/SM
+toxemia/M
+toxic
+toxicity/SM
+toxicological
+toxicologist/SM
+toxicology/M
+toxin/SM
+toy/SGMD
+toyboy/S
+tr
+trabecula
+trabecular
+trabecule
+trace/JDRSMZG
+traceability
+traceable/U
+tracer/M
+tracery/SM
+traceur/SM
+trachea/M
+tracheae
+tracheal
+tracheotomy/SM
+tracing/M
+track/ZGSMDR
+trackback/SM
+trackball/SM
+tracker/M
+trackless
+tracksuit/S
+tract's
+tract/CKFEAS
+tractability/IM
+tractable/I
+tractably/I
+traction/FEACKM
+tractor/FCKMS
+trad
+trade/BJDRSMZG
+trademark/SGMD
+tradeoff/S
+trader/M
+tradesman/M
+tradesmen
+tradespeople/M
+tradeswoman/M
+tradeswomen
+trading/M
+tradition/MS
+traditional/Y
+traditionalism/M
+traditionalist/SM
+traduce/DRSZG
+traducer/M
+traffic/SM
+trafficked
+trafficker/SM
+trafficking/M
+tragedian/SM
+tragedienne/MS
+tragedy/SM
+tragic
+tragically
+tragicomedy/SM
+tragicomic
+trail/ZGSMDR
+trailblazer/MS
+trailblazing/M
+trailer/M
+trailhead/S
+train/ZGSMDRBJ
+trained/U
+trainee/SM
+trainer/M
+training/M
+trainload/MS
+trainman/M
+trainmen
+trainspotter/S
+trainspotting
+traipse/DSMG
+trait/SM
+traitor/SM
+traitorous/Y
+trajectory/SM
+tram/MS
+tramcar/S
+tramlines
+trammed
+trammel/SGMD
+trammeled/U
+tramming
+tramp/ZGSMDR
+tramper/M
+trample/DRSMZG
+trampler/M
+trampoline/MGDS
+tramway/S
+trance/MS
+tranche/S
+tranquil/RYT
+tranquility/M
+tranquilize/ZGDRS
+tranquilizer/M
+tranquillity/M
+trans/I
+transact/DGS
+transaction/SM
+transactional
+transactor/MS
+transatlantic
+transceiver/SM
+transcend/GSD
+transcendence/M
+transcendent
+transcendental/Y
+transcendentalism/M
+transcendentalist/SM
+transcontinental
+transcreation/M
+transcribe/ZGDRS
+transcriber/M
+transcript/MS
+transcription/SM
+transcriptional
+transducer/MS
+transduction
+transect/DSG
+transept/MS
+transfect/SGD
+transfeminine
+transfer/MBS
+transferal/MS
+transference/M
+transferred
+transferring
+transfiguration/M
+transfigure/GDS
+transfinite
+transfix/DSG
+transform/BSZGMDR
+transformation/SM
+transformational
+transformative
+transformer/M
+transfuse/DSXGN
+transfusion/M
+transgender/SD
+transgenderism
+transgene/S
+transgenic
+transgress/GVDS
+transgression/SM
+transgressor/SM
+transience/M
+transiency/M
+transient/SMY
+transistor/SM
+transistorize/DSG
+transit/SGMD
+transition/GSMD
+transitional/Y
+transitive/ISMY
+transitiveness/M
+transitivity/M
+transitory
+transl
+translatable/U
+translate/DSGNBX
+translated/U
+translation/M
+translator/SM
+transliterate/DSGNX
+transliteration/M
+translocation
+translucence/M
+translucency/M
+translucent/Y
+transmasculine
+transmigrate/GNDS
+transmigration/M
+transmissible
+transmission/AMS
+transmit/S
+transmittable
+transmittal/M
+transmittance/M
+transmitted
+transmitter/SM
+transmitting
+transmogrification/M
+transmogrify/DSNG
+transmutation/SM
+transmute/BDSG
+transnational/MS
+transoceanic
+transom/SM
+transpacific
+transparency/SM
+transparent/Y
+transphobia/M
+transphobic
+transpiration/M
+transpire/DSG
+transplant/MDGS
+transplantation/M
+transpolar
+transponder/SM
+transport/BSZGMDR
+transportation/M
+transporter/M
+transpose/DSG
+transposition/MS
+transsexual/SM
+transsexualism/M
+transship/SL
+transshipment/M
+transshipped
+transshipping
+transubstantiation/M
+transversal
+transverse/MYS
+transvestism/M
+transvestite/MS
+trap/MS
+trapdoor/MS
+trapeze/SM
+trapezium/SM
+trapezoid/SM
+trapezoidal
+trappable
+trapped
+trapper/SM
+trapping/S
+trappings/M
+trapshooting/M
+trash/GMDS
+trashcan/MS
+trashiness/M
+trashy/RPT
+trauma/MS
+traumatic
+traumatically
+traumatize/GDS
+travail/SGMD
+travel/MDRSZGJ
+traveled/U
+traveler/M
+traveling/M
+travelog/SM
+travelogue/MS
+traversal/SM
+traverse/DSMG
+travesty/GDSM
+trawl/ZGSMDR
+trawler/M
+tray/MS
+treacherous/PY
+treacherousness/M
+treachery/SM
+treacle/M
+treacly
+tread/AGSM
+treadle/DSMG
+treadmill/MS
+treas
+treason/BM
+treasonous
+treasure/DRSMZG
+treasurer/M
+treasury/SM
+treat/AGSMD
+treatable
+treated/U
+treatise/SM
+treatment/MS
+treaty/SM
+treble/MGDS
+trebuchet/S
+tree/MDS
+treeing
+treeless
+treelike
+treeline
+treetop/SM
+trefoil/SM
+trek/MS
+trekked
+trekker/SM
+trekking
+trellis/GMDS
+trematode/MS
+tremble/DSMG
+tremendous/Y
+tremolo/SM
+tremor/MS
+tremulous/PY
+tremulousness/M
+trench's
+trench/ADSG
+trenchancy/M
+trenchant/Y
+trencher/MS
+trencherman/M
+trenchermen
+trend/GSMD
+trendily
+trendiness/M
+trendsetter/S
+trendsetting
+trendy/RSMPT
+trepidation/M
+trespass/MDRSZG
+trespasser/M
+tress/EMS
+trestle/MS
+trews
+trey/MS
+triad/SM
+triage/MGDS
+trial/ASM
+trialed
+trialing
+triangle/SM
+triangular/Y
+triangulate/GNDS
+triangulation/M
+triathlete/S
+triathlon/SM
+tribal
+tribalism/M
+tribe/SM
+tribesman/M
+tribesmen
+tribeswoman/M
+tribeswomen
+tribulation/SM
+tribunal/SM
+tribune/MS
+tributary/SM
+tribute's
+tribute/FS
+trice/M
+tricentennial/MS
+triceps/MS
+triceratops/M
+trichina/M
+trichinae
+trichinosis/M
+trichotomy/S
+trick/GSMD
+trickery/M
+trickily
+trickiness/M
+trickle/MGDS
+trickster/SM
+tricky/TRP
+tricolor/SM
+tricorn/MS
+tricycle/SM
+trident/MS
+tried/U
+triennial/MYS
+trier/SM
+trifecta/SM
+trifle/MZGDRS
+trifler/M
+trifocals/M
+trig/M
+trigger/MDSG
+triglyceride/MS
+trigonometric
+trigonometrical
+trigonometry/M
+trike/SM
+trilateral/S
+trilby/SM
+trill/GSMD
+trillion/SMH
+trillionth/M
+trillionths
+trillium/M
+trilobite/SM
+trilogy/SM
+trim/PMYS
+trimaran/MS
+trimester/SM
+trimmed/U
+trimmer/SM
+trimmest
+trimming/SM
+trimmings/M
+trimness/M
+trimonthly
+trinitrotoluene/M
+trinity/SM
+trinket/SM
+trio/MS
+trip/MYS
+tripartite
+tripe/M
+triplane/SM
+triple/MGDS
+triplet/SM
+triplex/MS
+triplicate/MGDS
+tripod/MS
+tripodal
+tripos
+tripped
+tripper/SM
+tripping
+triptych/M
+triptychs
+tripwire/S
+trireme/SM
+trisect/SDG
+trisection/M
+trite/FPYT
+triteness/FM
+triter
+tritium/M
+triumph/GMD
+triumphal
+triumphalism
+triumphalist
+triumphant/Y
+triumphs
+triumvir/MS
+triumvirate/SM
+trivalent
+trivet/MS
+trivia/M
+trivial/Y
+triviality/SM
+trivialization/M
+trivialize/GDS
+trivium/M
+trochaic
+trochee/SM
+trod/AU
+trodden/A
+troglodyte/SM
+troika/MS
+troll/SGMD
+trolley/SM
+trolleybus/MS
+trollop/SM
+trombone/MS
+trombonist/MS
+tromp/SGD
+tron/S
+troop/SZGMDR
+trooper/M
+troopship/MS
+trope/SM
+trophy/SM
+tropic/MS
+tropical/Y
+tropics/M
+tropism/SM
+troposphere/SM
+trot/MS
+troth/M
+trotted
+trotter/SM
+trotting
+troubadour/MS
+trouble/DSMG
+troubled/U
+troublemaker/MS
+troubleshoot/DRZGS
+troubleshooter/M
+troubleshooting/M
+troubleshot
+troublesome/Y
+trough/M
+troughs
+trounce/DRSZG
+trouncer/M
+troupe/MZGDRS
+trouper/M
+trouser/SM
+trousers/M
+trousseau/M
+trousseaux
+trout/SM
+trove/SM
+trow/DSG
+trowel/MDSG
+troy/S
+truancy/M
+truant/GMDS
+truce/SM
+truck/SZGMDR
+trucker/M
+trucking/M
+truckle/MGDS
+truckload/SM
+truculence/M
+truculent/Y
+trudge/MGDS
+true/MTGDRS
+truelove/SM
+truffle/MS
+trug/S
+truism/MS
+truly/U
+trump/SGMD
+trumpery/M
+trumpet/ZGMDRS
+trumpeter/M
+truncate/GNDS
+truncation/M
+truncheon/SM
+trundle/MZGDRS
+trundler/M
+trunk/SGM
+truss/GMDS
+trust/ESGMD
+trustee/MS
+trusteeship/SM
+trustful/EY
+trustfulness/M
+trusting/Y
+trustworthiness/M
+trustworthy/TPR
+trusty/TRSM
+truth/ZMR
+truther/M
+truthful/UYP
+truthfulness/UM
+truthiness
+truths/U
+try's
+try/AGDS
+trying/Y
+tryout/SM
+tryptophan
+tryst/SMDG
+tsarists
+tsetse/MS
+tsp
+tsunami/SM
+ttys
+tub/SZGMDR
+tuba/MS
+tubal
+tubby/TR
+tube/MS
+tubeless/M
+tuber/M
+tubercle/SM
+tubercular
+tuberculin/M
+tuberculosis/M
+tuberculous
+tuberose/M
+tuberous
+tubful/MS
+tubing/M
+tubular
+tubule/MS
+tuck/MDRSZG
+tucker/MDG
+tuft/MDRSZG
+tufter/M
+tug/SM
+tugboat/MS
+tugged
+tugging
+tuition/IM
+tularemia/M
+tulip/SM
+tulle/M
+tum/S
+tumble/DRSMZG
+tumbledown
+tumbler/M
+tumbleweed/SM
+tumbling/M
+tumbrel/SM
+tumbril/SM
+tumescence/M
+tumescent
+tumid
+tumidity/M
+tummy/SM
+tumor/SM
+tumorous
+tumult/SM
+tumultuous/Y
+tun/SZGMDRB
+tuna/MS
+tundra/SM
+tune/MS
+tuneful/YP
+tunefulness/M
+tuneless/Y
+tuner/M
+tuneup/SM
+tung
+tungsten/M
+tunic/SM
+tunnel/JSMDRZG
+tunneler/M
+tunny/SM
+tuple/S
+tuppence
+tuppenny
+tuque/SM
+turban/SMD
+turbid
+turbidity/M
+turbine/SM
+turbo/SM
+turbocharge/ZGDRS
+turbocharger/M
+turbofan/SM
+turbojet/SM
+turboprop/SM
+turbot/SM
+turbulence/M
+turbulent/Y
+turd/MS
+turducken/SM
+tureen/SM
+turf/MDSG
+turfy
+turgid/Y
+turgidity/M
+turkey/SM
+turmeric/SM
+turmoil/MS
+turn/AMDRSZG
+turnabout/SM
+turnaround/SM
+turnbuckle/SM
+turncoat/SM
+turner/AM
+turning/MS
+turnip/SM
+turnkey/MS
+turnoff/MS
+turnout/MS
+turnover/MS
+turnpike/MS
+turnstile/SM
+turntable/SM
+turpentine/M
+turpitude/M
+turps
+turquoise/SM
+turret/SMD
+turtle/SM
+turtleback/S
+turtledove/SM
+turtleneck/SMD
+tush/MS
+tusk/MDS
+tussle/DSMG
+tussock/MS
+tussocky
+tut/SM
+tutelage/M
+tutelary
+tutor/SMDG
+tutored/U
+tutorial/SM
+tutorship/M
+tutted
+tutti/SM
+tutting
+tutu/MS
+tux/MS
+tuxedo/SM
+twaddle/MZGDRS
+twaddler/M
+twain/M
+twang/SMDG
+twangy/RT
+twas
+twat/S
+tweak/SMDG
+twee
+tweed/SM
+tweedle/DSG
+tweeds/M
+tweedy/RT
+tween
+tweep/S
+tweet's
+tweet/ASDG
+tweeter/SM
+tweezers/M
+twelfth/M
+twelfths
+twelve/SM
+twelvemonth/M
+twelvemonths
+twentieth/M
+twentieths
+twenty/SMH
+twerk/SDG
+twerp/SM
+twice
+twiddle/MGDS
+twiddly
+twig/MS
+twigged
+twigging
+twiggy/TR
+twilight/M
+twilit
+twill/MD
+twin/MDRSZG
+twine/SM
+twiner/M
+twinge/DSMG
+twinight
+twink/SY
+twinkle/MGJDS
+twinkling/M
+twinned
+twinning
+twinset/S
+twirl/SMDRZG
+twirler/M
+twirly
+twist's
+twist/USDG
+twister/MS
+twisty/TR
+twit/MS
+twitch/GMDS
+twitchy/RT
+twitted
+twitter/MDSG
+twittery
+twitting
+twixt
+two/SM
+twofer/SM
+twofold
+twopence/SM
+twopenny
+twosome/SM
+twp
+tycoon/SM
+tying/AU
+tyke/MS
+tympani/M
+tympanic
+tympanist/MS
+tympanum/SM
+type's
+type/AGDS
+typecast/GS
+typeface/MS
+typescript/MS
+typeset/S
+typesetter/MS
+typesetting/M
+typewrite/RSZG
+typewriter/M
+typewriting/M
+typewritten
+typewrote
+typhoid/M
+typhoon/MS
+typhus/M
+typical/UY
+typicality/M
+typification/M
+typify/NGDS
+typing/M
+typist/SM
+typo/MS
+typographer/SM
+typographic
+typographical/Y
+typography/M
+typology/SM
+tyrannic
+tyrannical/Y
+tyrannicidal
+tyrannicide/S
+tyrannize/GDS
+tyrannosaur/MS
+tyrannosaurus/MS
+tyrannous
+tyranny/SM
+tyrant/SM
+tyro/MS
+tzatziki
+u/S
+ubiquitous/Y
+ubiquity/M
+udder/SM
+udon
+ufologist/SM
+ufology/M
+ugh
+ugliness/M
+ugly/RTP
+uh
+uhf
+ukase/SM
+ukulele/SM
+ulcer/SM
+ulcerate/XDSGNV
+ulceration/M
+ulcerous
+ulna/M
+ulnae
+ulnar
+ulster/MS
+ult
+ulterior
+ultimate/MY
+ultimatum/MS
+ultimo
+ultra/SM
+ultraconservative/SM
+ultrahigh
+ultralight/SM
+ultramarine/M
+ultramodern
+ultrasensitive
+ultrashort
+ultrasonic
+ultrasonically
+ultrasound/MS
+ultraviolet/M
+ululate/DSGNX
+ululation/M
+um
+umbel/SM
+umber/M
+umbilical
+umbilici
+umbilicus/M
+umbra/SM
+umbrage/M
+umbrella/SM
+umiak/SM
+umlaut/MS
+ump/SGMD
+umpire/MGDS
+umpteen/H
+unabridged/MS
+unacceptability
+unacceptable
+unaccommodating
+unaccountably
+unadventurous
+unaesthetic
+unalterably
+unambitious
+unanimity/M
+unanimous/Y
+unapparent
+unappetizing
+unappreciative
+unary
+unassertive
+unassimilable
+unassuming/Y
+unavailing/Y
+unaware/S
+unbeknown
+unbeknownst
+unbend/SG
+unbent
+unbid
+unblinking/Y
+unblushing/Y
+unbosom/DG
+unbound/D
+unbox/JGDS
+unbreakable
+unbroken
+uncanny/T
+uncap/S
+uncaring
+unceasing/Y
+unchangeable
+uncharacteristic
+uncharitable
+unchaste/RT
+uncial/M
+uncle/SM
+unclean/DRPT
+uncleanly/T
+unclear/DRT
+uncomfortable
+uncommon/T
+uncompelling
+uncomplaining/Y
+uncomplicated
+uncomprehending/Y
+uncompromising/Y
+unconditional/Y
+uncongenial
+unconscionable
+unconscionably
+unconscious/M
+unconstitutional/Y
+uncontrollably
+uncontroversial
+uncool
+uncooperative
+uncouth/Y
+uncrushable
+unction/SM
+unctuous/YP
+unctuousness/M
+uncut
+undaunted/Y
+undecided/SM
+undemonstrative/Y
+undeniably
+under
+underachieve/LZGDRS
+underachiever/M
+underact/SDG
+underage
+underappreciated
+underarm/SM
+underbelly/SM
+underbid/S
+underbidding
+underbrush/M
+undercarriage/MS
+undercharge/MGDS
+underclass/MS
+underclassman/M
+underclassmen
+underclothes/M
+underclothing/M
+undercoat/GJSMD
+undercoating/M
+undercover
+undercurrent/SM
+undercut/SM
+undercutting
+underdeveloped
+underdevelopment/M
+underdog/SM
+underdone
+underemployed
+underemployment/M
+underestimate/DSMGNX
+underestimation/M
+underexpose/GDS
+underexposure/MS
+underfed
+underfeed/GS
+underfloor
+underflow
+underfoot
+underfunded
+underfur/M
+undergarment/SM
+undergo/G
+undergoes
+undergone
+undergrad/S
+undergraduate/SM
+underground/MS
+undergrowth/M
+underhand
+underhanded/PY
+underhandedness/M
+underinclusive
+underinflated
+underlain
+underlay/ZSMR
+underlayer/M
+underlie/S
+underline/MGDS
+underling/MS
+underlip/SM
+underlying
+undermanned
+undermentioned
+undermine/GDS
+undermost
+underneath/M
+underneaths
+undernourished
+undernourishment/M
+underpaid
+underpants/M
+underpart/MS
+underpass/MS
+underpay/GSL
+underpayment/SM
+underpin/S
+underpinned
+underpinning/MS
+underplay/DGS
+underpopulated
+underprivileged
+underproduction/M
+underrate/GDS
+underrepresented
+underscore/DSMG
+undersea/S
+undersecretary/SM
+undersell/GS
+undersexed
+undershirt/SM
+undershoot/SG
+undershorts/M
+undershot
+underside/MS
+undersign/DGS
+undersigned/M
+undersized
+underskirt/SM
+undersold
+understaffed
+understand/SGBJ
+understandably
+understanding/MY
+understate/DSLG
+understatement/SM
+understood
+understudy/GDSM
+undertake/ZGJRS
+undertaken
+undertaker/M
+undertaking/M
+underthings/M
+undertone/MS
+undertook
+undertow/SM
+underused
+underutilized
+undervaluation/M
+undervalue/DSG
+underwater
+underway
+underwear/M
+underweight/M
+underwent
+underwhelm/DGS
+underwing/MS
+underwire/DS
+underworld/MS
+underwrite/ZGRS
+underwriter/M
+underwritten
+underwrote
+undesirable/MS
+undies/M
+undo
+undoubted/Y
+undramatic
+undreamt
+undue
+undulant
+undulate/DSXGN
+undulation/M
+undying
+unearthliness/M
+unease/M
+uneasy/T
+uneatable
+uneconomic
+unemployed/M
+unending
+unenterprising
+unequal/DY
+unerring/Y
+unessential
+uneven/Y
+unexceptionably
+unexcited
+unexciting
+unexpected/YP
+unexpectedness/M
+unexplainably
+unfailing/Y
+unfair/PTRY
+unfaltering
+unfamiliar
+unfathomably
+unfed
+unfeeling/Y
+unfeminine
+unfit/S
+unfitting
+unfix/GDS
+unflagging/Y
+unflappability/M
+unflappable
+unflappably
+unflattering
+unflinching/Y
+unforgettably
+unforgivably
+unfortunate/MS
+unfriendly/T
+unfrock/DG
+unfruitful
+unfunny
+ungainliness/M
+ungainly/RPT
+ungenerous
+ungentle
+ungodly/T
+ungraceful/Y
+ungrudging
+unguarded
+unguent/SM
+ungulate/MS
+unhandy/T
+unhappy/T
+unhealthful
+unhealthy/T
+unhistorical
+unholy/T
+unhurt
+unicameral
+unicellular
+unicorn/SM
+unicycle/SM
+unidirectional
+unification/AM
+uniform/SMDYG
+uniformity/M
+unify/AGDSN
+unilateral/Y
+unilateralism
+unimportant
+unimpressive
+uninformative
+uninhibited/Y
+uninsured
+unintelligent
+unintended
+uninteresting
+uninterrupted/Y
+uninviting
+union/ASM
+unionism/M
+unionist/MS
+unique/YTRP
+uniqueness/M
+unisex/M
+unison/M
+unitary
+unite/AEGSD
+unitedly
+unities
+unitize/DSG
+unity/EM
+univalent
+univalve/SM
+universal/MYS
+universalism
+universalist
+universality/M
+universalize/DSG
+universe/SM
+university/SM
+univocal
+unjust/Y
+unkempt
+unkind/T
+unkindly/T
+unknowable/M
+unknown/SM
+unleaded/M
+unless
+unlike/PB
+unlikely/T
+unlit
+unlock/DSG
+unlovable
+unlovely/TR
+unloving
+unlucky/T
+unman/S
+unmanly/T
+unmarried
+unmeaning
+unmentionable/MS
+unmentionables/M
+unmet
+unmindful
+unmissable
+unmistakably
+unmoral
+unmovable
+unmusical
+unnecessary
+unnerving/Y
+unobservant
+unoffensive
+unofficial/Y
+unoriginal
+unpeople
+unperceptive
+unpersuasive
+unpick/GDS
+unpin/S
+unpleasing
+unpolitical
+unpopular
+unpractical
+unprecedented/Y
+unprofessional/Y
+unpromising
+unpropitious
+unquestioning/Y
+unquiet/TR
+unread/B
+unready
+unreal
+unreasoning
+unregenerate
+unrelated
+unrelenting/Y
+unrelieved/Y
+unremarkable
+unremitting/Y
+unrepentant
+unreported
+unrepresentative
+unrequest/D
+unrest/M
+unrevealing
+unrideable
+unripe/TR
+unroll/GDS
+unromantic
+unruliness/M
+unruly/RTP
+unsafe/YTR
+unsavory
+unsaw
+unscathed
+unsee/S
+unseeing/Y
+unseemly/T
+unseen/M
+unsentimental
+unset
+unshakable
+unshakably
+unshakeable
+unshapely
+unsharp
+unshockable
+unshorn
+unsightliness/M
+unsightly/PT
+unsmiling
+unsociable
+unsocial
+unsold
+unsound/PRYT
+unspeakable
+unspeakably
+unspecific
+unspectacular
+unsporting
+unstable
+unsteady/TRP
+unstinting/Y
+unstrapping
+unsubstantial
+unsubtle
+unsuitable
+unsure
+unsuspecting/Y
+unsymmetrical
+untactful
+unthinkably
+unthinking/Y
+untidy/PTR
+until
+untimely/T
+untiring/Y
+untouchable/MS
+untoward
+untrue/RT
+untrustworthy
+untruth/M
+unutterable
+unutterably
+unwarrantable
+unwary/T
+unwavering
+unwed
+unwelcome/G
+unwell
+unwieldiness/M
+unwieldy/TRP
+unwise/RYT
+unworried
+unworthy/T
+unwound
+unwrapping
+unyielding
+up/S
+upbeat/MS
+upbraid/SGD
+upbringing/MS
+upchuck/SGD
+upcoming
+upcountry/M
+update/MGDRS
+updraft/MS
+upend/SGD
+upfront
+upgrade/MGDS
+upheaval/MS
+upheld
+uphill/MS
+uphold/ZGRS
+upholder/M
+upholster/ASGD
+upholsterer/MS
+upholstery/M
+upkeep/M
+upland/MS
+uplift/JSMDG
+uplink/SM
+upload/SDG
+upmarket
+upmost
+upon
+upped
+upper/SM
+uppercase/M
+upperclassman/M
+upperclassmen
+upperclasswoman
+upperclasswomen
+uppercut/MS
+uppercutting
+uppermost
+upping
+uppish
+uppity
+upraise/DSG
+uprear/GSD
+upright/MYPS
+uprightness/M
+uprising/SM
+upriver
+uproar/SM
+uproarious/Y
+uproot/GSD
+upscale
+upset/SM
+upsetting
+upshot/SM
+upside/SM
+upsilon/MS
+upstage/GDS
+upstairs
+upstanding
+upstart/MDSG
+upstate/M
+upstream
+upstroke/SM
+upsurge/MGDS
+upswing/MS
+uptake/SM
+uptempo
+upthrust/GSM
+uptick/SM
+uptight
+uptime
+uptown/M
+uptrend
+upturn/GSMD
+upvote/DS
+upward/SY
+upwind
+uracil/M
+uranium/M
+urban
+urbane/RYT
+urbanity/M
+urbanization/M
+urbanize/DSG
+urbanologist/MS
+urbanology/M
+urchin/SM
+urea/M
+uremia/M
+uremic
+ureter/SM
+urethane/M
+urethra/M
+urethrae
+urethral
+urge/MGDS
+urgency/M
+urgent/Y
+uric
+urinal/SM
+urinalyses
+urinalysis/M
+urinary
+urinate/GNDS
+urination/M
+urine/M
+urn/SM
+urogenital
+urological
+urologist/MS
+urology/M
+ursine
+urticaria/M
+usability/M
+usable/UA
+usage/SM
+use/AEDSMG
+used/U
+useful/PY
+usefulness/M
+useless/YP
+uselessness/M
+user/MS
+username/MS
+usher/SMDG
+usherette/SM
+usu
+usual's
+usual/UY
+usufruct/SM
+usurer/SM
+usurious
+usurp/SDRZG
+usurpation/M
+usurper/M
+usury/M
+utensil/SM
+uteri
+uterine
+utero
+uterus/M
+utilitarian/MS
+utilitarianism/M
+utility/SM
+utilization/M
+utilize/GBDS
+utmost/M
+utopia/SM
+utopian/MS
+utter/SDYG
+utterance/SM
+uttermost/M
+uveitis
+uvula/SM
+uvular/MS
+uxorious
+v/AS
+vac/S
+vacancy/SM
+vacant/Y
+vacate/DSG
+vacation/ZGMDRS
+vacationer/M
+vacationist/SM
+vaccinate/GNDSX
+vaccinated/U
+vaccination/M
+vaccinator/S
+vaccine/SM
+vacillate/XGNDS
+vacillation/M
+vacinal
+vacuity/M
+vacuole/MS
+vacuous/YP
+vacuousness/M
+vacuum/GSMD
+vagabond/SMDG
+vagabondage/M
+vagarious
+vagary/SM
+vagina/SM
+vaginae
+vaginal/Y
+vaginitis
+vagrancy/M
+vagrant/MS
+vague/RYTP
+vagueness/M
+vagus
+vain/RYT
+vainglorious/Y
+vainglory/M
+val
+valance/MS
+vale/MS
+valediction/MS
+valedictorian/SM
+valedictory/SM
+valence/MS
+valency/SM
+valentine/SM
+valet/SMDG
+valetudinarian/MS
+valetudinarianism/M
+valiance/M
+valiant/Y
+valid/Y
+validate/IGNDS
+validation/IM
+validations
+validator/S
+validities
+validity/IM
+validness/M
+valise/SM
+valley/SM
+valor/M
+valorous/Y
+valuable/MS
+valuate/DSG
+valuation/CAMS
+value's
+value/CAGSD
+valueless
+valuer/SM
+valve/DSMG
+valveless
+valvular
+vamoose/DSG
+vamp/AMDGS
+vampire/SM
+van/SM
+vanadium/M
+vandal/SM
+vandalism/M
+vandalize/DSG
+vane/MS
+vanguard/MS
+vanilla/SM
+vanish/JDSG
+vanishing/Y
+vanity/SM
+vanned
+vanning
+vanquish/ZGDRS
+vanquisher/M
+vantage/SM
+vape/GDS
+vapid/YP
+vapidity/M
+vapidness/M
+vapor/SM
+vaporization/M
+vaporize/DRSZG
+vaporizer/M
+vaporous
+vaporware
+vapory
+vaquero/MS
+var/S
+variability/IM
+variable/ISM
+variably/I
+variance/SM
+variant/MS
+variate/NX
+variation/M
+varicolored
+varicose
+varied/U
+variegate/DSGN
+variegation/M
+varietal/SM
+variety/SM
+various/Y
+varlet/SM
+varmint/MS
+varnish/GMDS
+varnished/U
+varsity/SM
+vary/DSG
+varying/U
+vascular
+vase/MS
+vasectomy/SM
+vasoconstriction
+vasomotor
+vasopressor/SM
+vassal/SM
+vassalage/M
+vast/MRYTSP
+vastness/M
+vat/SM
+vatted
+vatting
+vaudeville/M
+vaudevillian/MS
+vault/SMDRZG
+vaulter/M
+vaulting/M
+vaunt/SMDG
+vb
+veal/M
+vector/SGMD
+veejay/SM
+veep/MS
+veer/MDGS
+veg/SM
+vegan/SM
+veganism
+vegeburger/S
+veges
+vegetable/SM
+vegetarian/SM
+vegetarianism/M
+vegetate/GNVDS
+vegetation/M
+vegged
+vegges
+veggie/SM
+veggieburger/S
+vegging
+vehemence/M
+vehemency/M
+vehement/Y
+vehicle/MS
+vehicular
+veil's
+veil/UDGS
+vein/MDGS
+vela
+velar/SM
+veld/MS
+vellum/M
+velocipede/MS
+velocity/SM
+velodrome/S
+velour/MS
+velum/M
+velvet/M
+velveteen/M
+velvety
+venal/Y
+venality/M
+venation/M
+vend/DGS
+vendetta/SM
+vendible
+vendor/MS
+veneer/MDGS
+venerability/M
+venerable
+venerate/DSGN
+veneration/M
+venereal
+vengeance/M
+vengeful/AY
+venial
+venireman/M
+veniremen
+venison/M
+venom/M
+venomous/Y
+venous
+vent's
+vent/DGS
+ventilate/GNDS
+ventilation/M
+ventilator/SM
+ventilatory
+ventral
+ventricle/SM
+ventricular
+ventriloquism/M
+ventriloquist/SM
+ventriloquy/M
+venture/DSMG
+venturesome/PY
+venturesomeness/M
+venturous/PY
+venturousness/M
+venue/ASM
+veracious/Y
+veracity/M
+veranda/SM
+verandah/M
+verandahs
+verapamil
+verb/KMDGS
+verbal/MYS
+verbalization/M
+verbalize/GDS
+verbatim
+verbena/SM
+verbiage/MS
+verbose/Y
+verbosity/M
+verboten
+verdant/Y
+verdict/SM
+verdigris/GMDS
+verdure/M
+verge's
+verge/FDSG
+verger/MS
+verifiability
+verifiable/U
+verifiably
+verification/M
+verified/U
+verifier/M
+verify/DRSNZG
+verily
+verisimilitude/M
+veritable
+veritably
+verity/SM
+vermicelli/M
+vermiculite/M
+vermiform
+vermilion/M
+vermin/M
+verminous
+vermouth/M
+vernacular/MS
+vernal
+vernier/SM
+veronica/M
+verruca/SM
+verrucae
+versa
+versatile
+versatility/M
+verse/AFNGMSDX
+versed/U
+versification/M
+versifier/M
+versify/ZGNDRS
+version/AFIMS
+versioned
+versioning
+verso/SM
+versus
+vert/A
+vertebra/M
+vertebrae
+vertebral
+vertebrata
+vertebrate/IMS
+vertebrobasilar
+vertex/MS
+vertical/MYS
+vertices
+vertiginous
+vertigo/M
+verve/M
+very/RT
+vesicle/SM
+vesicular
+vesiculate
+vesper/MS
+vessel/MS
+vest's
+vest/ILDGS
+vestal/MS
+vestibule/MS
+vestige/SM
+vestigial/Y
+vesting/M
+vestment/IMS
+vestry/SM
+vestryman/M
+vestrymen
+vet/SM
+vetch/MS
+veteran/SM
+veterinarian/MS
+veterinary/SM
+veto/MDG
+vetoes
+vetted
+vetting
+vex/GDS
+vexation/SM
+vexatious/Y
+vhf
+vi
+via
+viability/M
+viable
+viably
+viaduct/SM
+vial/MS
+viand/SM
+vibe/MS
+vibes/M
+vibraharp/SM
+vibrancy/M
+vibrant/Y
+vibraphone/MS
+vibraphonist/MS
+vibrate/GNDSX
+vibration/M
+vibrational
+vibrationless
+vibrato/MS
+vibrator/SM
+vibratory
+viburnum/SM
+vicar/SM
+vicarage/SM
+vicarious/YP
+vicariousness/M
+vice/CMS
+viced
+vicegerent/SM
+vicennial
+viceregal
+viceroy/MS
+vichyssoise/M
+vicing
+vicinity/M
+vicious/YP
+viciousness/M
+vicissitude/SM
+victim/MS
+victimization/M
+victimize/GDS
+victimless
+victor/MS
+victorious/Y
+victory/SM
+victual/SMDG
+vicuna/MS
+vicu単a/MS
+videlicet
+video/GSMD
+videocassette/SM
+videoconferencing
+videodisc/MS
+videographer/MS
+videography/SM
+videophile/MS
+videophone/MS
+videotape/DSMG
+videotex
+vie/DS
+view/AMDRBSZG
+viewer/AM
+viewership/M
+viewfinder/SM
+viewing/SM
+viewpoint/MS
+vigesimal
+vigil/SM
+vigilance/M
+vigilant/Y
+vigilante/SM
+vigilantism/M
+vigilantist/M
+vignette/DSMG
+vignettist/MS
+vigor/M
+vigorous/Y
+vii
+viii
+viking/MS
+vile/YTPR
+vileness/M
+vilification/M
+vilify/DSNG
+villa/SM
+village/RSMZ
+villager/M
+villain/SM
+villainous
+villainy/SM
+villein/SM
+villeinage/M
+villi
+villus/M
+vim/M
+vinaigrette/M
+vincible/I
+vindicate/XDSGN
+vindication/M
+vindicator/MS
+vindictive/PY
+vindictiveness/M
+vine/MS
+vinegar/M
+vinegary
+vineyard/MS
+vino/M
+vinous
+vintage/MS
+vintner/MS
+vinyl/SM
+viol/MBS
+viola/SM
+violable/I
+violate/GNDSX
+violation/M
+violator/SM
+violence/M
+violent/Y
+violet/MS
+violin/MS
+violincello/S
+violinist/SM
+violist/MS
+violoncellist/SM
+violoncello/MS
+viper/SM
+viperous
+virago/M
+viragoes
+viral
+vireo/SM
+virgin/MS
+virginal/SM
+virginity/M
+virgule/MS
+virile
+virility/M
+virologist/SM
+virology/M
+virtual/Y
+virtualization
+virtue/SM
+virtuosity/M
+virtuoso/SM
+virtuous/YP
+virtuousness/M
+virulence/M
+virulent/Y
+virus/MS
+visa/MDSG
+visage/MS
+viscera
+visceral/Y
+viscid
+viscose/M
+viscosity/M
+viscount/SM
+viscountcy/SM
+viscountess/MS
+viscous
+viscus/M
+vise/ACMGDS
+visibility/IM
+visible/I
+visibly/I
+vision/KGDSM
+visionary/SM
+visit's
+visit/ASGD
+visitant/MS
+visitation/MS
+visitor/MS
+visor/SM
+vista/SM
+visual/SMY
+visualization/SM
+visualize/DRSZG
+visualizer/M
+vita/M
+vitae
+vital/SY
+vitality/M
+vitalization/AM
+vitalize/CAGSD
+vitals/M
+vitamin/MS
+vitiate/GNDS
+vitiation/M
+viticulture/M
+viticulturist/MS
+vitreous
+vitrifaction/M
+vitrification/M
+vitrify/GNDS
+vitrine/SM
+vitriol/M
+vitriolic
+vitriolically
+vittles/M
+vituperate/GNVDS
+vituperation/M
+viva/MS
+vivace
+vivacious/PY
+vivaciousness/M
+vivacity/M
+vivant/S
+vivaria
+vivarium/SM
+vivid/RYTP
+vividness/M
+vivify/ADSG
+viviparous
+vivisect/DGS
+vivisection/M
+vivisectional
+vivisectionist/SM
+vixen/SM
+vixenish/Y
+viz
+vizier/SM
+vlf
+vlogged
+vlogger/M
+vlogging
+vocab
+vocable/MS
+vocabulary/SM
+vocal/SMY
+vocalic
+vocalist/SM
+vocalization/MS
+vocalize/DSG
+vocation/FIKASM
+vocational/Y
+vocative/MS
+vociferate/DSGN
+vociferation/M
+vociferous/YP
+vociferousness/M
+vocoder/S
+vodka/SM
+vogue/SM
+voguish
+voice/IDSMG
+voiced/U
+voiceless/PY
+voicelessness/M
+voicemail/SM
+void/MDSGB
+voila
+voile/M
+voil
+vol/S
+volatile/S
+volatility/M
+volatilize/DSG
+volcanic
+volcanism
+volcano/M
+volcanoes
+volcanological
+volcanologist/MS
+volcanology/M
+vole/MS
+volition/M
+volitional
+volley/GSMD
+volleyball/MS
+volt/AMS
+voltage/MS
+voltaic
+voltmeter/SM
+volubility/M
+voluble
+volubly
+volume/SM
+volumetric
+voluminous/YP
+voluminousness/M
+voluntarily/I
+voluntarism/M
+voluntary/SM
+volunteer/SGMD
+volunteerism/M
+voluptuary/SM
+voluptuous/PY
+voluptuousness/M
+volute/SM
+vomit/SMDG
+voodoo/GSMD
+voodooism/M
+voracious/PY
+voraciousness/M
+voracity/M
+vortex/MS
+votary/SM
+vote's
+vote/CGVDS
+voter/SM
+vouch/DRSZG
+voucher/M
+vouchsafe/DSG
+vow/SGMD
+vowel/SM
+voyage/MZGDRS
+voyager/M
+voyageur/SM
+voyeur/MS
+voyeurism/M
+voyeuristic
+vulcanism
+vulcanization/M
+vulcanize/GDS
+vulgar/RYT
+vulgarian/MS
+vulgarism/MS
+vulgarity/SM
+vulgarization/M
+vulgarize/ZGDRS
+vulgarizer/M
+vulnerabilities
+vulnerability/IM
+vulnerable/I
+vulnerably/I
+vulpine
+vulture/SM
+vulturous
+vulva/M
+vulvae
+vuvuzela/MS
+vying
+w/DNXTGVJ
+wabbit/S
+wack/MRTS
+wackiness/M
+wacko/SM
+wacky/RPT
+wad/SZGMDR
+wadded
+wadding/M
+waddle/DSMG
+wade/MS
+wader/M
+waders/M
+wadge/S
+wadi/MS
+wafer/SM
+waffle/MZGDRS
+waffler/M
+waft/MDGS
+wag/SZGMDR
+wage/MS
+waged/U
+wager/ZGMDR
+wagerer/M
+wagged
+waggery/SM
+wagging
+waggish/YP
+waggishness/M
+waggle/MGDS
+wagon/ZSMR
+wagoner/M
+wagtail/SM
+waif/MS
+wail/MDRZGS
+wailer/M
+wailing/M
+wain/MS
+wainscot/SJMDG
+wainscoting/M
+wainscotted
+wainscotting/MS
+wainwright/MS
+waist/SM
+waistband/MS
+waistcoat/MS
+waistline/MS
+wait/MDRZGS
+waiter/M
+waiting/M
+waitperson/MS
+waitress/MS
+waitstaff/M
+waive/DRSZG
+waiver/M
+wake/MGJDS
+wakeful/PY
+wakefulness/M
+waken/GSD
+waldo/S
+waldoes
+wale/MGDS
+walk/MDRZGS
+walkabout/S
+walkaway/MS
+walker/M
+walkies
+walking/M
+walkout/SM
+walkover/MS
+walkway/SM
+wall/MDGS
+wallaby/SM
+wallah
+wallahs
+wallboard/M
+wallet/MS
+walleye/DSM
+wallflower/MS
+wallop/MDSJG
+walloping/M
+wallow/MDSG
+wallpaper/SMDG
+wally/S
+walnut/MS
+walrus/MS
+waltz/ZGMDRS
+waltzer/M
+wampum/M
+wan/GPDY
+wand/MS
+wander/DRSJZG
+wanderer/M
+wanderings/M
+wanderlust/SM
+wane/MS
+wangle/MZGDRS
+wangler/M
+wank/DRZGS
+wanna
+wannabe/SM
+wannabee/S
+wanner
+wanness/M
+wannest
+want/MDGS
+wanted/U
+wanton/MDYSPG
+wantonness/M
+wapiti/MS
+war/SM
+warble/MZGDRS
+warbler/M
+warbonnet/SM
+ward/AMDGS
+warden/MS
+warder/MS
+wardress/S
+wardrobe/SM
+wardroom/SM
+ware/MS
+warehouse/DSMG
+warez
+warfare/M
+warfarin
+warhead/MS
+warhorse/SM
+warily/U
+wariness/UM
+warlike
+warlock/MS
+warlord/MS
+warm/PDRYHZTGS
+warmblooded
+warmer/M
+warmhearted/P
+warmheartedness/M
+warmish
+warmness/M
+warmonger/SMG
+warmongering/M
+warmth/M
+warmup/MS
+warn/JDGS
+warning/M
+warp/MDGS
+warpaint
+warpath/M
+warpaths
+warplane/MS
+warrant/GMDS
+warranted/U
+warranty/DSMG
+warred
+warren/MS
+warring
+warrior/SM
+warship/SM
+wart/MS
+warthog/SM
+wartime/M
+warty/TR
+wary/UPRT
+was
+wasabi
+wash/BJMDRSZG
+washable/SM
+washbasin/SM
+washboard/SM
+washbowl/SM
+washcloth/M
+washcloths
+washed/U
+washer/M
+washerwoman/M
+washerwomen
+washing/M
+washout/MS
+washrag/MS
+washroom/MS
+washstand/SM
+washtub/MS
+washy/TR
+wasn't
+wasp/MS
+waspish/YP
+waspishness/M
+wassail/SMDG
+wast
+wastage/M
+waste/DRSMZG
+wastebasket/MS
+wasteful/PY
+wastefulness/M
+wasteland/SM
+wastepaper/M
+waster/M
+wastewater
+wastrel/SM
+watch/BZGMDRS
+watchable/U
+watchband/MS
+watchdog/SM
+watcher/M
+watchful/YP
+watchfulness/M
+watchmaker/MS
+watchmaking/M
+watchman/M
+watchmen
+watchstrap/S
+watchtower/SM
+watchword/MS
+water/GSMD
+waterbed/MS
+waterbird/SM
+waterboard/MDJSG
+waterboarding/M
+waterborne
+watercolor/MS
+watercourse/SM
+watercraft/M
+watercress/M
+waterfall/SM
+waterfowl/SM
+waterfront/MS
+waterhole/SM
+wateriness/M
+waterlily/SM
+waterline/MS
+waterlogged
+watermark/MDGS
+watermelon/SM
+watermill/MS
+waterpower/M
+waterproof/SMDG
+waterproofing/M
+waters/M
+watershed/MS
+waterside/MS
+waterspout/SM
+watertight
+waterway/MS
+waterwheel/SM
+waterworks/M
+watery/PTR
+watt/MS
+wattage/M
+wattle/MGDS
+wave/MZGDRS
+waveband/S
+waveform
+wavefront
+wavelength/M
+wavelengths
+wavelet/SM
+wavelike
+waver/ZGMDR
+waverer/M
+wavering/Y
+waviness/M
+wavy/PRT
+wax/GMDNS
+waxiness/M
+waxwing/SM
+waxwork/SM
+waxy/RPT
+way/SM
+waybill/SM
+wayfarer/MS
+wayfaring/SM
+waylaid
+waylay/RSZG
+waylayer/M
+wayside/SM
+wayward/PY
+waywardness/M
+wazoo/S
+we
+we'd
+we'll
+we're
+we've
+weak/PNRYXT
+weaken/DRZG
+weakener/M
+weakfish/MS
+weakish
+weakling/SM
+weakness/MS
+weal/MHS
+wealth/M
+wealthiness/M
+wealthy/TRP
+wean/DGS
+weapon/MS
+weaponize/GDS
+weaponless
+weaponry/M
+wear/MRBJSZG
+wearable/U
+wearer/M
+wearied/U
+wearily
+weariness/M
+wearisome/Y
+weary/TGDRSP
+weasel/MDYSG
+weather/SMDG
+weatherboard/SG
+weathercock/MS
+weathering/M
+weatherization/M
+weatherize/DSG
+weatherman/M
+weathermen
+weatherperson/MS
+weatherproof/GSD
+weatherstrip/S
+weatherstripped
+weatherstripping/M
+weave/DRSMZG
+weaver/M
+weaving/M
+web/SM
+webbed
+webbing/M
+webcam/MS
+webcast/SMG
+webdesign/MS
+webfeet
+webfoot/M
+webinar/SM
+webisode/MS
+weblog/MS
+webmail/SM
+webmaster/SM
+webmistress/MS
+webpage/SM
+website/SM
+wed/AS
+wedded/A
+wedder
+wedding/SM
+wedge/DSMG
+wedgie/MS
+wedlock/M
+wee/RSMT
+weed/MDRSZG
+weeder/M
+weedkiller/S
+weedless
+weedy/TR
+weeing
+week/MYS
+weekday/SM
+weekend/SZGMDR
+weekly/SM
+weeknight/SM
+ween/DSG
+weenie/MTRS
+weensy/RT
+weeny
+weep/MRJSZG
+weeper/M
+weepie
+weepy/TRSM
+weevil/MS
+weft/MS
+weigh's
+weigh/AGD
+weighbridge/S
+weighs/A
+weight/MDSJG
+weighted/U
+weightily
+weightiness/M
+weightless/YP
+weightlessness/M
+weightlifter/MS
+weightlifting/M
+weighty/PTR
+weir/MS
+weird/PTGDRY
+weirdie/MS
+weirdness/M
+weirdo/MS
+welcome/MGDS
+weld/MDRBSZG
+welder/M
+welfare/M
+welkin/M
+well/MDPSG
+wellhead/SM
+wellie
+wellington/MS
+wellness/M
+wellspring/MS
+welly/S
+welp
+welsh/ZGDRS
+welsher/M
+welt/MDRSZG
+welter/GMD
+welterweight/SM
+wen/M
+wench/MS
+wend/DSG
+went
+wept
+were
+weren't
+werewolf/M
+werewolves
+west/M
+westbound
+westerly/SM
+western/SZMR
+westerner/M
+westernization/M
+westernize/GDS
+westernmost
+westward/S
+wet/SMYP
+wetback/SM
+wetland/SM
+wetness/M
+wetter/SM
+wettest
+wetting
+wetware/S
+whack/SJZGMDR
+whacker/M
+whale/DRSMZG
+whaleboat/MS
+whalebone/M
+whaler/M
+whaling/M
+wham/MS
+whammed
+whamming
+whammy/SM
+wharf/M
+wharves
+what/MS
+whatchamacallit/MS
+whatever
+whatnot/M
+whatshername
+whatshisname
+whatsit/S
+whatsoever
+wheal/SM
+wheat/MN
+wheatgerm
+wheatmeal
+whee
+wheedle/DRSZG
+wheedler/M
+wheel/SMDRG
+wheelbarrow/SM
+wheelbase/SM
+wheelchair/SM
+wheelhouse/MS
+wheelie/SM
+wheelwright/MS
+wheeze/DSMG
+wheezily
+wheeziness/M
+wheezy/PRT
+whelk/SMD
+whelm/SDG
+whelp/SMDG
+when/MS
+whence
+whenever
+whensoever
+where/SM
+whereabouts/M
+whereas
+whereat
+whereby
+wherefore/MS
+wherein
+whereof
+whereon
+wheresoever
+whereto
+whereupon
+wherever
+wherewith
+wherewithal/M
+wherry/SM
+whet/S
+whether
+whetstone/SM
+whetted
+whetting
+whew
+whey/M
+which
+whichever
+whiff/SMDG
+whiffletree/MS
+while/DSMG
+whilom
+whilst
+whim/MS
+whimper/MDGS
+whimsical/Y
+whimsicality/M
+whimsy/SM
+whine/DRSMZG
+whiner/M
+whinge/DRSZG
+whingeing
+whinny/GDSM
+whiny/RT
+whip/MS
+whipcord/M
+whiplash/MS
+whipped
+whipper/MS
+whippersnapper/MS
+whippet/MS
+whipping/SM
+whippletree/SM
+whippoorwill/MS
+whipsaw/MDGS
+whir/MS
+whirl/SMDG
+whirligig/MS
+whirlpool/MS
+whirlwind/MS
+whirlybird/SM
+whirred
+whirring
+whisk/SMDRZG
+whisker/MD
+whiskery
+whiskey/MS
+whisky/SM
+whiskys
+whisper/MDRSZG
+whisperer/M
+whist/M
+whistle/MZGDRS
+whistleblower/GMS
+whistler/M
+whit/MDNRSXTGJ
+white/SPM
+whitebait
+whiteboard/S
+whitecap/SM
+whitefish/MS
+whitehead/MS
+whitelist/GDS
+whiten/ZGDRJ
+whitener/M
+whiteness/M
+whitening/M
+whiteout/SM
+whitepaper/MS
+whitetail/MS
+whitewall/SM
+whitewash/MDSG
+whitewater/M
+whitey/SM
+whither
+whiting/M
+whitish
+whittle/ZGDRS
+whittler/M
+whiz/M
+whizkid/M
+whizz/MDSG
+whizzbang/MS
+who'd
+who'll
+who're
+who've
+who/M
+whoa
+whodunit/MS
+whoever
+whole/SMP
+wholefood/S
+wholegrain
+wholehearted/YP
+wholeheartedness/M
+wholemeal
+wholeness/M
+wholesale/MZGDRS
+wholesaler/M
+wholesome/UP
+wholesomely
+wholesomeness/UM
+wholewheat
+wholly
+whom
+whomever
+whomsoever
+whoop/SMDRZG
+whoopee/S
+whooper/M
+whoosh/MDSG
+whop/S
+whopped
+whopper/SM
+whopping
+whore/SMG
+whorehouse/MS
+whoreish
+whorish
+whorl/SMD
+whose
+whoso
+whosoever
+whup/S
+whupped
+whupping
+why'd
+why/M
+whys
+wick/MDRSZGJ
+wicked/TPRY
+wickedness/M
+wicker/M
+wickerwork/M
+wicket/SM
+wide/YTRP
+widemouthed
+widen/SDRZG
+widener/M
+wideness/M
+widescreen/MS
+widespread
+widgeon/MS
+widget/S
+widow/SMDRZG
+widower/M
+widowhood/M
+width/M
+widths
+wield/SDRZG
+wielder/M
+wiener/SM
+wienie/SM
+wife/MY
+wifeless
+wig/SM
+wigeon/SM
+wigged
+wigging
+wiggle/DRSMZG
+wiggler/M
+wiggly/TR
+wight/SM
+wiglet/SM
+wigwag/SM
+wigwagged
+wigwagging
+wigwam/SM
+wiki/MS
+wild/MRYSTP
+wildcard/MS
+wildcat/MS
+wildcatted
+wildcatter/MS
+wildcatting
+wildebeest/MS
+wilderness/MS
+wildfire/MS
+wildflower/SM
+wildfowl/M
+wildlife/M
+wildness/M
+wilds/M
+wile/MGDS
+wilful/P
+wilfulness/M
+wiliness/M
+will/MDS
+willful/PY
+willfulness/M
+willies/M
+willing/UPY
+willingness/UM
+williwaw/MS
+willow/SM
+willowy
+willpower/M
+willy-nilly
+willy/S
+wilt/MDSG
+wily/RTP
+wimp/MDSG
+wimpish
+wimple/DSMG
+wimpy/RT
+win/SGMD
+wince/DSMG
+winch/MDSG
+wind's
+wind/UASG
+windbag/SM
+windblown
+windbreak/SZMR
+windbreaker/M
+windburn/MD
+windcheater/S
+windchill/M
+winded
+winder/SM
+windfall/MS
+windflower/MS
+windily
+windiness/M
+winding/SM
+windjammer/SM
+windlass/MS
+windless
+windmill/MDGS
+window/SMDG
+windowless
+windowpane/SM
+windowsill/SM
+windpipe/MS
+windproof
+windrow/SM
+windscreen/SM
+windshield/SM
+windsock/MS
+windstorm/MS
+windsurf/ZGDRS
+windsurfer/M
+windsurfing/M
+windswept
+windup/SM
+windward/M
+windy/RTP
+wine/MS
+wineglass/MS
+winegrower/MS
+winemaker/MS
+winery/SM
+wineshop/MS
+wing/MDRZG
+wingding/MS
+wingless
+winglike
+wingnut/SM
+wingspan/MS
+wingspread/SM
+wingtip/SM
+wink/MDRSZG
+winker/M
+winkle/DSMG
+winnable/U
+winner/SM
+winning/MYS
+winnow/ZGSDR
+winnower/M
+wino/MS
+winsome/YTRP
+winsomeness/M
+winsorization
+winsorize/GDS
+winter/GSMD
+wintergreen/M
+winterize/GDS
+wintertime/M
+wintry/TR
+winy/RT
+wipe/MZGDRS
+wiper/M
+wire's
+wire/AGDS
+wired/S
+wirehair/MS
+wireless/MS
+wiretap/MS
+wiretapped
+wiretapper/SM
+wiretapping/M
+wiriness/M
+wiring/M
+wiry/RTP
+wisdom/M
+wise/MYTGDRS
+wiseacre/SM
+wisecrack/MDSG
+wiseguy/S
+wish/MDRSZG
+wishbone/SM
+wisher/M
+wishful/Y
+wishlist's
+wishy-washy
+wisp/MS
+wispy/RT
+wist
+wisteria/SM
+wistful/YP
+wistfulness/M
+wit/SM
+witch/MDSG
+witchcraft/M
+witchery/M
+with
+withal
+withdraw/SG
+withdrawal/MS
+withdrawn
+withdrew
+withe/DRSMZG
+wither/JGD
+withering/Y
+withers/M
+withheld
+withhold/SG
+withholding/M
+within/M
+without
+withstand/GS
+withstood
+witless/PY
+witlessness/M
+witness/MDSG
+wits/M
+witted
+witter/SGD
+witticism/SM
+wittily
+wittiness/M
+witting/UY
+witty/RPT
+wive/GDS
+wiz/S
+wizard/SMY
+wizardry/M
+wizened
+wk/Y
+woad/M
+woah
+wobble/MGDS
+wobbliness/M
+wobbly/RTP
+wodge/S
+woe/SM
+woebegone
+woeful/YP
+woefuller
+woefullest
+woefulness/M
+wog/S
+wok/SMN
+woke
+wold/MS
+wolf/MDSG
+wolfhound/SM
+wolfish
+wolfram/M
+wolverine/SM
+wolves
+woman/M
+womanhood/M
+womanish
+womanize/DRSZG
+womanizer/M
+womankind/M
+womanlike/M
+womanliness/M
+womanly/RPT
+womb/MS
+wombat/MS
+womble/S
+women/M
+womenfolk/SM
+womenfolks/M
+won't
+won/M
+wonder/MDGLS
+wonderful/YP
+wonderfulness/M
+wondering/Y
+wonderland/MS
+wonderment/M
+wondrous/Y
+wonk/MS
+wonky/TR
+wont/MD
+wonted/U
+woo/SZGDR
+wood/MDNSG
+woodbine/M
+woodblock/MS
+woodcarver/MS
+woodcarving/SM
+woodchuck/MS
+woodcock/SM
+woodcraft/M
+woodcut/SM
+woodcutter/SM
+woodcutting/M
+wooden/RYTP
+woodenness/M
+woodiness/M
+woodland/SM
+woodlice
+woodlot/SM
+woodlouse
+woodman/M
+woodmen
+woodpecker/MS
+woodpile/SM
+woods/M
+woodshed/SM
+woodsiness/M
+woodsman/M
+woodsmen
+woodsy/RTP
+woodwind/MS
+woodwork/MRZG
+woodworker/M
+woodworking/M
+woodworm/S
+woody/TPRSM
+wooer/M
+woof/MDRSZG
+woofer/M
+wool/MNX
+woolen/M
+woolgathering/M
+wooliness
+woolliness/M
+woolly/RSMPT
+woozily
+wooziness/M
+woozy/TRP
+wop/MS!
+word's
+word/ADSG
+wordage/M
+wordbook/SM
+wordie
+wordily
+wordiness/M
+wording/SM
+wordless/Y
+wordplay/M
+wordsmith
+wordsmiths
+wordy/TPRS
+wore
+work's
+work/ADJSG
+workable/U
+workaday
+workaholic/SM
+workaround/S
+workbasket/S
+workbench/MS
+workbook/MS
+workday/SM
+worker/MS
+workfare/M
+workflow/MS
+workforce/M
+workhorse/SM
+workhouse/SM
+working's
+workingman/M
+workingmen
+workings/M
+workingwoman/M
+workingwomen
+workload/MS
+workman/M
+workmanlike
+workmanship/M
+workmate/S
+workmen
+workout/SM
+workplace/MS
+workroom/MS
+works/M
+worksheet/MS
+workshop/MS
+workshy
+worksite/S
+workspace
+workstation/MS
+worktable/MS
+worktop/S
+workup/MS
+workweek/SM
+world/SM
+worldlier
+worldliness/UM
+worldly/UTP
+worldview/SM
+worldwide
+worm/MDSG
+wormhole/MS
+wormwood/M
+wormy/TR
+worn/U
+worried/Y
+worrier/M
+worriment/M
+worrisome
+worry/ZGDRSMJ
+worrying/Y
+worrywart/SM
+worse/M
+worsen/DSG
+worship/ZGSMDR
+worshiper/M
+worshipful
+worst/SGMD
+worsted/M
+wort/M
+worth/M
+worthies
+worthily/U
+worthiness/UM
+worthless/PY
+worthlessness/M
+worthwhile
+worthy's
+worthy/UPRT
+wot
+wotcha
+would've
+would/S
+wouldn't
+wouldst
+wound/SGMDR
+wove/A
+woven/AU
+wow/SGMD
+wpm
+wrack/GSMD
+wraith/M
+wraiths
+wrangle/DRSMZGJ
+wrangler/M
+wrap's
+wrap/US
+wraparound/SM
+wrapped/U
+wrapper/SM
+wrapping/MS
+wrasse/MS
+wrath/M
+wrathful/Y
+wreak/SGD
+wreath/MDSG
+wreathe
+wreaths
+wreck/SZGMDR
+wreckage/M
+wrecker/M
+wren/MS
+wrench/MDSG
+wrest/SGMD
+wrestle/MZGDRS
+wrestler/M
+wrestling/M
+wretch/MS
+wretched/TPRY
+wretchedness/M
+wriggle/MZGDRS
+wriggler/M
+wriggly
+wright/MS
+wring/SZGMR
+wringer/M
+wrinkle/MGDS
+wrinkled/U
+wrinkly/TRSM
+wrist/SM
+wristband/MS
+wristwatch/MS
+writ/MRBJSZG
+write/S
+writer/M
+writhe/MGDS
+writing/M
+written/AU
+wrong/STGMPDRY
+wrongdoer/SM
+wrongdoing/SM
+wrongful/PY
+wrongfulness/M
+wrongheaded/YP
+wrongheadedness/M
+wrongness/M
+wrote/A
+wroth
+wrought
+wrung
+wry/Y
+wryer
+wryest
+wryness/M
+wt
+wunderkind/S
+wurst/SM
+wuss/MS
+wussy/RSMT
+x
+xci
+xcii
+xciv
+xcix
+xcvi
+xcvii
+xenon/M
+xenophile/S
+xenophobe/MS
+xenophobia/M
+xenophobic
+xerographic
+xerography/M
+xerox/MDSG
+xi/SM
+xii
+xiii
+xiv
+xix
+xor
+xref/S
+xterm/M
+xv
+xvi
+xvii
+xviii
+xx
+xxi
+xxii
+xxiii
+xxiv
+xxix
+xxv
+xxvi
+xxvii
+xxviii
+xxx
+xxxi
+xxxii
+xxxiii
+xxxiv
+xxxix
+xxxv
+xxxvi
+xxxvii
+xxxviii
+xylem/M
+xylene
+xylophone/SM
+xylophonist/MS
+y
+y'all
+ya
+yacht/SMDG
+yachting/M
+yachtsman/M
+yachtsmen
+yachtswoman/M
+yachtswomen
+yahoo/SM
+yak/SM
+yakked
+yakking
+yam/SM
+yammer/SZGMDR
+yammerer/M
+yang/M
+yank/MDSG
+yap/SM
+yapped
+yapping
+yard/MS
+yardage/MS
+yardarm/MS
+yardman/M
+yardmaster/MS
+yardmen
+yardstick/MS
+yarmulke/SM
+yarn/MS
+yarrow/M
+yashmak/S
+yaw/SGMD
+yawl/MS
+yawn/MDRSZG
+yawner/M
+yaws/M
+yay
+yd
+ye/RST
+yea/SM
+yeah/M
+yeahs
+year/MYS
+yearbook/MS
+yearling/MS
+yearlong
+yearly/SM
+yearn/GSJD
+yearning/M
+yeast/SM
+yeasty/RT
+yeet/DSG
+yegg/MS
+yell/MDSG
+yellow/MDRTGPS
+yellowhammer/S
+yellowish
+yellowness/M
+yellowy
+yelp/MDSG
+yen/SM
+yeoman/M
+yeomanry/M
+yeomen
+yep/SM
+yes/MS
+yeshiva/SM
+yeshivot
+yessed
+yessing
+yesterday/MS
+yesteryear/M
+yet
+yeti/MS
+yew/SM
+yid/S
+yield/JSGMD
+yikes
+yin/M
+yip/SM
+yipe
+yipped
+yippee
+yipping
+yo
+yob/S
+yobbo/S
+yobibyte/SM
+yodel/SMDRZG
+yodeler/M
+yoga/M
+yogi/MS
+yogic
+yogurt/SM
+yoke's
+yoke/UGDS
+yokel/SM
+yolk/MDS
+yon
+yonder
+yonks
+yore/M
+you'd
+you'll
+you're
+you've
+you/SMH
+young/TMR
+youngish
+youngster/MS
+your/S
+yourself
+yourselves
+youth/M
+youthful/YP
+youthfulness/M
+youths
+yow
+yowl/MDSG
+yowsa
+yowsah
+yowza
+yowzah
+yr/S
+ytterbium/M
+yttrium/M
+yuan/M
+yucca/SM
+yuck/MDSG
+yucky/TR
+yuk/SM
+yukked
+yukking
+yukky
+yule/M
+yuletide/M
+yum
+yummy/TR
+yup/SM
+yuppie/MS
+yuppify/GDS
+yurt/MS
+z/DNXTGJ
+zaniness/M
+zany/RSMPT
+zap/SM
+zapped
+zapper/MS
+zapping
+zappy
+zeal/M
+zealot/MS
+zealotry/M
+zealous/YP
+zealousness/M
+zebibyte/SM
+zebra/SM
+zebu/MS
+zed/SM
+zeitgeist/SM
+zenith/M
+zeniths
+zenned
+zeolite/S
+zephyr/MS
+zeppelin/MS
+zero/MDHSG
+zeroes
+zest/MS
+zestful/YP
+zestfulness/M
+zesty/RT
+zeta/MS
+zigzag/SM
+zigzagged
+zigzagging
+zilch/M
+zillion/MS
+zinc/MS
+zincked
+zincking
+zine/S
+zinfandel/M
+zing/MDRZG
+zinger/M
+zingy/RT
+zinnia/MS
+zip's
+zip/US
+zipped/U
+zipper/MDGS
+zipping/U
+zippy/TR
+zircon/MS
+zirconium/M
+zit/SM
+zither/MS
+zloty/SM
+zlotys
+zodiac/MS
+zodiacal
+zombie/MS
+zonal/Y
+zone's
+zone/AGDS
+zoning/M
+zonked
+zoo/SM
+zookeeper/SM
+zoological/Y
+zoologist/SM
+zoology/M
+zoom/MDSG
+zoomorphism/M
+zoonosis
+zoonotic
+zoophilia/M
+zoophyte/SM
+zoophytic
+zooplankton
+zorch
+zoster
+zounds
+zucchini/MS
+zuke/S
+zwieback/M
+zydeco/M
+zygote/SM
+zygotic
+zymurgy/M
+ngstr旦m/M
+辿clair/SM
+辿clat/M
+辿lan/M
+辿migr辿/SM
+辿p辿e/MS
+辿tude/SM
diff --git a/extensions/spellcheck/locales/en-US/hunspell/en-US.aff b/extensions/spellcheck/locales/en-US/hunspell/en-US.aff
new file mode 100644
index 0000000000..900aae6095
--- /dev/null
+++ b/extensions/spellcheck/locales/en-US/hunspell/en-US.aff
@@ -0,0 +1,203 @@
+SET ISO8859-1
+TRY esianrtolcdugmphbyfvkwzESIANRTOLCDUGMPHBYFVKWZ'
+NOSUGGEST !
+
+# ordinal numbers
+COMPOUNDMIN 1
+# only in compounds: 1th, 2th, 3th
+ONLYINCOMPOUND c
+# compound rules:
+# 1. [0-9]*1[0-9]th (10th, 11th, 12th, 56714th, etc.)
+# 2. [0-9]*[02-9](1st|2nd|3rd|[4-9]th) (21st, 22nd, 123rd, 1234th, etc.)
+COMPOUNDRULE 2
+COMPOUNDRULE n*1t
+COMPOUNDRULE n*mp
+WORDCHARS 0123456789
+
+PFX A Y 1
+PFX A 0 re .
+
+PFX I Y 1
+PFX I 0 in .
+
+PFX U Y 1
+PFX U 0 un .
+
+PFX C Y 1
+PFX C 0 de .
+
+PFX E Y 1
+PFX E 0 dis .
+
+PFX F Y 1
+PFX F 0 con .
+
+PFX K Y 1
+PFX K 0 pro .
+
+SFX V N 2
+SFX V e ive e
+SFX V 0 ive [^e]
+
+SFX N Y 3
+SFX N e ion e
+SFX N y ication y
+SFX N 0 en [^ey]
+
+SFX X Y 3
+SFX X e ions e
+SFX X y ications y
+SFX X 0 ens [^ey]
+
+SFX H N 2
+SFX H y ieth y
+SFX H 0 th [^y]
+
+SFX Y Y 1
+SFX Y 0 ly .
+
+SFX G Y 2
+SFX G e ing e
+SFX G 0 ing [^e]
+
+SFX J Y 2
+SFX J e ings e
+SFX J 0 ings [^e]
+
+SFX D Y 4
+SFX D 0 d e
+SFX D y ied [^aeiou]y
+SFX D 0 ed [^ey]
+SFX D 0 ed [aeiou]y
+
+SFX T N 4
+SFX T 0 st e
+SFX T y iest [^aeiou]y
+SFX T 0 est [aeiou]y
+SFX T 0 est [^ey]
+
+SFX R Y 4
+SFX R 0 r e
+SFX R y ier [^aeiou]y
+SFX R 0 er [aeiou]y
+SFX R 0 er [^ey]
+
+SFX Z Y 4
+SFX Z 0 rs e
+SFX Z y iers [^aeiou]y
+SFX Z 0 ers [aeiou]y
+SFX Z 0 ers [^ey]
+
+SFX S Y 4
+SFX S y ies [^aeiou]y
+SFX S 0 s [aeiou]y
+SFX S 0 es [sxzh]
+SFX S 0 s [^sxzhy]
+
+SFX P Y 3
+SFX P y iness [^aeiou]y
+SFX P 0 ness [aeiou]y
+SFX P 0 ness [^y]
+
+SFX M Y 1
+SFX M 0 's .
+
+SFX B Y 3
+SFX B 0 able [^aeiou]
+SFX B 0 able ee
+SFX B e able [^aeiou]e
+
+SFX L Y 1
+SFX L 0 ment .
+
+REP 90
+REP a ei
+REP ei a
+REP a ey
+REP ey a
+REP ai ie
+REP ie ai
+REP alot a_lot
+REP are air
+REP are ear
+REP are eir
+REP air are
+REP air ere
+REP ere air
+REP ere ear
+REP ere eir
+REP ear are
+REP ear air
+REP ear ere
+REP eir are
+REP eir ere
+REP ch te
+REP te ch
+REP ch ti
+REP ti ch
+REP ch tu
+REP tu ch
+REP ch s
+REP s ch
+REP ch k
+REP k ch
+REP f ph
+REP ph f
+REP gh f
+REP f gh
+REP i igh
+REP igh i
+REP i uy
+REP uy i
+REP i ee
+REP ee i
+REP j di
+REP di j
+REP j gg
+REP gg j
+REP j ge
+REP ge j
+REP s ti
+REP ti s
+REP s ci
+REP ci s
+REP k cc
+REP cc k
+REP k qu
+REP qu k
+REP kw qu
+REP o eau
+REP eau o
+REP o ew
+REP ew o
+REP oo ew
+REP ew oo
+REP ew ui
+REP ui ew
+REP oo ui
+REP ui oo
+REP ew u
+REP u ew
+REP oo u
+REP u oo
+REP u oe
+REP oe u
+REP u ieu
+REP ieu u
+REP ue ew
+REP ew ue
+REP uff ough
+REP oo ieu
+REP ieu oo
+REP ier ear
+REP ear ier
+REP ear air
+REP air ear
+REP w qu
+REP qu w
+REP z ss
+REP ss z
+REP shun tion
+REP shun sion
+REP shun cion
+REP size cise
diff --git a/extensions/spellcheck/locales/en-US/hunspell/en-US.dic b/extensions/spellcheck/locales/en-US/hunspell/en-US.dic
new file mode 100644
index 0000000000..2daab957e8
--- /dev/null
+++ b/extensions/spellcheck/locales/en-US/hunspell/en-US.dic
@@ -0,0 +1,53554 @@
+53553
+0/nm
+0th/pt
+1/n1
+1st/p
+1th/tc
+2/nm
+2nd/p
+2th/tc
+3/nm
+3rd/p
+3th/tc
+4/nm
+4th/pt
+5/nm
+5th/pt
+6/nm
+6th/pt
+7/nm
+7th/pt
+8/nm
+8th/pt
+9/nm
+9th/pt
+A/SM
+AA/M
+AAA
+AB/M
+ABA
+ABC/M
+ABM/SM
+ABS
+AC/M
+ACLU/M
+ACT
+ACTH/M
+AD/M
+ADC
+ADD
+ADM
+ADP/M
+AF
+AFAIK
+AFB
+AFC/M
+AFDC
+AFN
+AFT
+AI/SM
+AIDS/M
+AK
+AL
+AM/M
+AMA
+AMD/M
+ANSI/S
+ANZUS/M
+AOL/M
+AP/M
+APB
+APC
+API/SM
+APO
+APR
+AR
+ARC
+ASAP
+ASCII/SM
+ASL/M
+ASPCA
+ATM/M
+ATP/M
+ATPase/M
+ATV
+AV
+AVI
+AWACS/M
+AWOL/M
+AWS/M
+AZ/M
+AZT/M
+Aachen/M
+Aaliyah/M
+Aaron/M
+Ab's
+Abba/S
+Abbas/M
+Abbasid/M
+Abbie/M
+Abbott/M
+Abby/M
+Abdel/M
+Abdul/M
+Abe/M
+AbeBooks
+Abel/M
+Abelard/M
+Abelson/M
+Aberdeen/M
+Abernathy/M
+Abidjan/M
+Abie/M
+Abigail/M
+Abilene/M
+Abner/M
+Aborigine/MS
+Abra/M
+Abraham/M
+Abram/MS
+Abramo/M
+Abrams/M
+Absalom/M
+Abuja/M
+Abyssinia/M
+Abyssinian/M
+Ac/M
+Acadia/M
+Acapulco/M
+Accenture/M
+Accra/M
+Acevedo/M
+Achaean/M
+Achebe/M
+Achernar/M
+Acheson/M
+Achilles/M
+Aconcagua/M
+Acosta/M
+Acropolis
+Acrux/M
+Actaeon/M
+ActiveX/M
+Acton/M
+Acts/M
+Acuff/M
+Acura/M
+Ada/SM
+Adah/M
+Adair/M
+Adaline/M
+Adam/SM
+Adamo/M
+Adams/M
+Adan/M
+Adana/M
+Adar/M
+AddThis/M
+Adda/M
+Addams/M
+Adderley/M
+Addi/M
+Addie/M
+Addison/M
+Addy/M
+Ade/M
+Adel/M
+Adela/M
+Adelaida/M
+Adelaide/M
+Adelbert/M
+Adele/M
+Adelheid/M
+Adelina/M
+Adeline/M
+Adelle/M
+Aden/M
+Adena/M
+Adenauer/M
+Adey/M
+Adham/M
+Adhara/M
+Adi/M
+Adidas/M
+Adina/M
+Adirondack/SM
+Adirondacks/M
+Adkins/M
+Adlai/M
+Adler/M
+Adm
+Admiralty
+Adolf/M
+Adolfo/M
+Adolph/M
+Adolphe/M
+Adolphus/M
+Adonis/MS
+Adore's
+Adrenalin/MS
+Adria/M
+Adrian/M
+Adriana/M
+Adriane/M
+Adrianna/M
+Adrianne/M
+Adriano/M
+Adriatic/M
+Adrien/M
+Adrienne/M
+Advent/MS
+Adventist/MS
+Advil/M
+Aegean/M
+Aelfric/M
+Aeneas/M
+Aeneid/M
+Aeolus/M
+Aeroflot/M
+Aeschylus/M
+Aesculapius/M
+Aesop/M
+Afghan/SM
+Afghani/M
+Afghanistan/M
+Afr
+Africa/M
+African/SM
+Afrikaans/M
+Afrikaner/SM
+Afro/SM
+Afrocentric
+Afrocentrism/M
+Afton/M
+Ag/M
+Agamemnon/M
+Agana
+Agassi/M
+Agassiz/M
+Agata/M
+Agatha/M
+Agathe/M
+Aggie/M
+Agilent
+Aglaia/M
+Agnes/M
+Agnese/M
+Agnew/M
+Agni/M
+Agosto/M
+Agra/M
+Agricola/M
+Agrippa/M
+Agrippina/M
+Aguadilla/M
+Aguascalientes
+Aguilar/M
+Aguinaldo/M
+Aguirre/M
+Agustin/M
+Ahab/M
+Aharon/M
+Ahmad/M
+Ahmadabad/M
+Ahmadinejad/M
+Ahmed/M
+Ahriman/M
+Aida/M
+Aidan/M
+Aiken/M
+Aila/M
+Aileen/M
+Ailey/M
+Aime/M
+Aimee/M
+Ainsley/M
+Ainslie/M
+Ainu/M
+Airedale/MS
+Aires/M
+Aisha/M
+Ajax/M
+Ajay/M
+Akbar/M
+Akhmatova/M
+Akihito/M
+Akim/M
+Akita/M
+Akiva/M
+Akkad/M
+Akron/M
+Al/M
+Ala/S
+Alabama/M
+Alabaman/MS
+Alabamian/SM
+Aladdin/M
+Alain/M
+Alameda/M
+Alamo/M
+Alamogordo/M
+Alan/M
+Alana/M
+Aland/M
+Alanna/M
+Alanson/M
+Alar/M
+Alaric/M
+Alasdair/M
+Alaska/M
+Alaskan/MS
+Alastair/M
+Alba/M
+Albania/M
+Albanian/MS
+Albany/M
+Albee/M
+Alberio/M
+Albert/M
+Alberta/M
+Albertan
+Albertina/M
+Albertine/M
+Alberto/M
+Albie/M
+Albigensian/M
+Albina/M
+Albion/M
+Albireo/M
+Albrecht/M
+Albuquerque/M
+Alcatraz/M
+Alcestis/M
+Alcibiades/M
+Alcindor/M
+Alcmena/M
+Alcoa/M
+Alcott/M
+Alcuin/M
+Alcyone/M
+Aldan/M
+Aldebaran/M
+Alden/M
+Alderamin/M
+Aldin/M
+Aldis/M
+Aldo/M
+Aldon/M
+Aldous/M
+Aldrich/M
+Aldridge/M
+Aldrin/M
+Aldus/M
+Alec/M
+Aleichem/M
+Alejandra/M
+Alejandro/M
+Aleksandr/M
+Alembert/M
+Alena/M
+Alene/M
+Aleppo/M
+Alessandra/M
+Alessandro/M
+Alethea/M
+Aleut/MS
+Aleutian/SM
+Alex/M
+Alexa/M
+Alexander/MS
+Alexandr/M
+Alexandra/M
+Alexandre/M
+Alexandria/M
+Alexandrian
+Alexandrina/M
+Alexandros
+Alexei/M
+Alexi/MS
+Alexia/M
+Alexina/M
+Alexis/M
+Alf/M
+Alfie/M
+Alfons/M
+Alfonse/M
+Alfonso/M
+Alfonzo/M
+Alford/M
+Alfred/M
+Alfreda/M
+Alfredo/M
+Algenib/M
+Alger/M
+Algeria/M
+Algerian/SM
+Algernon/M
+Algieba/M
+Algiers/M
+Algol/M
+Algonquian/SM
+Algonquin/MS
+Alhambra/M
+Alhena/M
+Ali/SM
+Alia/M
+Alice/M
+Alicia/M
+Alick/M
+Alida/M
+Alighieri/M
+Alina/M
+Aline/M
+Alioth/M
+Alisa/M
+Alisha/M
+Alison/M
+Alissa/M
+Alistair/M
+Alister/M
+Alix/M
+Alkaid/M
+Alla/M
+Allah/M
+Allahabad/M
+Allan/M
+Allard/M
+Alleghenies/M
+Allegheny/SM
+Allegra/M
+Allen/M
+Allende/M
+Allene/M
+Allentown/M
+Alleyn/M
+Allhallows/M
+Allie/MS
+Allison/M
+Allister/M
+Allstate/M
+Allyn/M
+Allyson/M
+Alma/M
+Almach/M
+Almaty/M
+Almeria/M
+Almighty/M
+Almira/M
+Almohad/M
+Almoravid/M
+Alnilam/M
+Alnitak/M
+Alon/M
+Alonso/M
+Alonzo/M
+Aloysius/M
+Alpert/M
+Alphard/M
+Alphecca/M
+Alpheratz/M
+Alphonse/M
+Alphonso/M
+Alpine/M
+Alpo/M
+Alps/M
+Alric/M
+Alsace/M
+Alsatian/SM
+Alsop/M
+Alston/M
+Alta/M
+Altaba/M
+Altai/M
+Altaic/M
+Altair/M
+Altamira/M
+Althea/M
+Altiplano/M
+Altman/M
+Altoids/M
+Alton/M
+Altoona/M
+Aludra/M
+Alva/M
+Alvan/M
+Alvarado/M
+Alvarez/M
+Alvaro/M
+Alvin/M
+Alvina/M
+Alvis/M
+Alvy/M
+Alwin/M
+Alwyn/M
+Alyce/M
+Alyosha/M
+Alys/M
+Alyson/M
+Alyss
+Alyssa/M
+Alzheimer/M
+Am/MNR
+Amabel/M
+Amadeus/M
+Amado/M
+Amalia/M
+Amalie/M
+Amanda/M
+Amara/M
+Amarillo/M
+Amaru/M
+Amata/M
+Amaterasu/M
+Amati/M
+Amazon/SM
+Amazonian
+Amber/M
+Ambros/M
+Ambrose
+Ambrosio/M
+Ambrosius/M
+Ame/SM
+Amelia/M
+Amelie/M
+Amen/M
+Amenhotep/M
+Amerasian/M
+America/SM
+American/MS
+Americana/M
+Americanism/MS
+Americanization/MS
+Americanize/GDS
+Amerigo/M
+Amerind/SM
+Amerindian/MS
+Amery/M
+Ames/M
+Ameslan/M
+Amgen/M
+Amharic/M
+Amherst/M
+Ami/M
+Amie/M
+Amiga/M
+Amil/M
+Amish/M
+Amman/M
+Amoco/M
+Amory/M
+Amos/M
+Amparo/M
+Ampere/M
+Amritsar/M
+Amsterdam/M
+Amtrak/M
+Amundsen/M
+Amur/M
+Amway/M
+Amy/M
+Ana/M
+Anabaptist/M
+Anabel/M
+Anacin/M
+Anacreon/M
+Anaheim/M
+Analects/M
+Analise/M
+Ananias/M
+Anasazi/M
+Anastasia/M
+Anatol/M
+Anatole/M
+Anatolia/M
+Anatolian/M
+Anaxagoras/M
+Anchorage/M
+Andalusia/M
+Andalusian/M
+Andaman/M
+Andean/M
+Anders/N
+Andersen/M
+Anderson/M
+Andes/M
+Andi/M
+Andie/M
+Andorra/M
+Andorran/SM
+Andra/MS
+Andre/MS
+Andrea/SM
+Andree/M
+Andrei/M
+Andrej/M
+Andres/M
+Andretti/M
+Andrew/SM
+Andrews/M
+Andrey/M
+Andria/M
+Andrianampoinimerina/M
+Android/M
+Andromache/M
+Andromeda/M
+Andropov/M
+Andros
+Andrus/M
+Andy/M
+Anet/M
+Angara/M
+Ange/M
+Angel/M
+Angela/M
+Angele/SM
+Angeles/M
+Angeli/M
+Angelia/M
+Angelica/M
+Angelico/M
+Angelika/M
+Angelina/M
+Angeline/M
+Angelique/M
+Angelita/M
+Angelo/M
+Angelou/M
+Angevin/M
+Angie/M
+Angkor/M
+Angle/MS
+Angleton/M
+Anglia/M
+Anglican/SM
+Anglicanism/MS
+Anglicism/MS
+Anglicization
+Anglicize
+Anglo/M
+Anglophile/M
+Anglophobe
+Angola/M
+Angolan/MS
+Angora/SM
+Angstrom/M
+Anguilla/M
+Angus/M
+Anhui/M
+Ania/M
+Aniakchak/M
+Anibal/M
+Anita/M
+Ankara/M
+Ann/M
+Anna/M
+Annabel/M
+Annabella/M
+Annabelle/M
+Annalise/M
+Annam/M
+Annapolis/M
+Annapurna/M
+Anne/M
+Anneliese/M
+Annelise/M
+Annemarie/M
+Annette/M
+Anni/SM
+Annie/M
+Anniston/M
+Annmarie/M
+Annunciation/SM
+Anny/M
+Anouilh/M
+Ansel/M
+Ansell/M
+Anselm/M
+Anselmo/M
+Anshan/M
+Ansley/M
+Anson/M
+Anstice/M
+Antaeus/M
+Antananarivo/M
+Antarctic/M
+Antarctica/M
+Antares/M
+Anthea/M
+Anthony/M
+Anthropocene
+Antichrist/SM
+Antietam/M
+Antifa/M
+Antigone/M
+Antigua/M
+Antillean
+Antilles/M
+Antin/M
+Antioch/M
+Antipas/M
+Antipodes
+Antofagasta/M
+Antoine/M
+Antoinette/M
+Anton/M
+Antone/M
+Antonella/M
+Antoni/M
+Antonia/M
+Antonie/M
+Antonietta/M
+Antonin/M
+Antonina/M
+Antonino/M
+Antoninus/M
+Antonio/M
+Antonius/M
+Antony/M
+Antwan/M
+Antwerp/M
+Anubis/M
+Any's
+Anya/M
+Anzac/M
+Apache/SM
+Apalachicola/M
+Apatosaurus
+Apennines/M
+Aphrodite/M
+Apia/M
+Apocalypse/M
+Apocrypha/M
+Apollinaire/M
+Apollo/SM
+Apollonian/M
+Apostle/M
+Appalachia/M
+Appalachian/SM
+Appalachians/M
+Appaloosa/SM
+Apple/M
+Appleseed/M
+Appleton/M
+Appomattox/M
+Apr/M
+April/MS
+Apuleius/M
+Aquafresh/M
+Aquarian
+Aquarius/MS
+Aquila/M
+Aquinas/M
+Aquino/M
+Aquitaine/M
+Ar/MY
+Ara/M
+Arab/SM
+Arabella/M
+Arabia/M
+Arabian/MS
+Arabic/M
+Arabidopsis
+Arabist/MS
+Araby/M
+Araceli/M
+Arafat/M
+Aragon
+Araguaya/M
+Aral/M
+Aramaic/M
+Aramco/M
+Arapaho/MS
+Arapahoes
+Ararat/M
+Araucanian/M
+Arawak/M
+Arawakan/M
+Arbitron/M
+Arcadia/M
+Arcadian/M
+Archambault/M
+Archean/M
+Archibald/M
+Archie/M
+Archimedes/M
+Archy/M
+Arctic/M
+Arcturus/M
+Arda/M
+Ardabil
+Arden/M
+Ardis/M
+Arduino/M
+Arecibo/M
+Arequipa/M
+Ares/M
+Aretha/M
+Argentina/M
+Argentine/M
+Argentinean
+Argentinian/MS
+Argo/SM
+Argonaut/MS
+Argonne/M
+Argos/M
+Argus/M
+Ari/M
+Ariadne/M
+Arial/M
+Ariana/M
+Arianism/M
+Arie/SM
+Ariel/M
+Arielle/M
+Aries/MS
+Arin/M
+Ariosto/M
+Aristarchus/M
+Aristides/M
+Aristophanes/M
+Aristotelian/M
+Aristotle/M
+Arius/M
+Ariz
+Arizona/M
+Arizonan/SM
+Arizonian/MS
+Arjuna/M
+Ark/M
+Arkansan/MS
+Arkansas/M
+Arkhangelsk/M
+Arkwright/M
+Arlen/M
+Arlene/M
+Arlette/M
+Arley/M
+Arlie/M
+Arlin/M
+Arline/M
+Arlington/M
+Arly/M
+Armageddon/SM
+Armagnac/M
+Arman/M
+Armand/M
+Armando/M
+Armani/M
+Armenia/M
+Armenian/SM
+Armin/M
+Arminius/M
+Armonk/M
+Armour/M
+Armstrong/M
+Arnaldo/M
+Arne
+Arneb/M
+Arnhem/M
+Arni/M
+Arnie/M
+Arno/M
+Arnold/M
+Arnoldo/M
+Arnulfo/M
+Aron/M
+Arrhenius/M
+Arron/M
+Art/M
+Artaxerxes/M
+Arte/M
+Artemas
+Artemis/M
+Artemus/M
+Arthur/M
+Arthurian/M
+Artie/M
+Artur/M
+Arturo/M
+Artus/M
+Arty's
+Aruba/M
+Arv/M
+Arvin/M
+Aryan/MS
+As/M
+Asa/M
+Asama/M
+Ascella/M
+Ascension/M
+Ase/M
+Asgard/M
+Ashanti/M
+Ashby/M
+Ashcroft/M
+Ashe/RM
+Asheville/M
+Ashgabat
+Ashikaga/M
+Ashkenazim/M
+Ashkhabad/M
+Ashlee/M
+Ashleigh/M
+Ashley/M
+Ashmolean/M
+Ashton
+Ashurbanipal/M
+Asia/M
+Asiago
+Asian/MS
+Asiatic/SM
+Asimov/M
+Asmara/M
+Asoka/M
+Aspell/M
+Aspen/M
+Asperger/M
+Aspidiske/M
+Asquith/M
+Assad/M
+Assam/M
+Assamese/M
+Assembly
+Assisi/M
+Assyria/M
+Assyriaca/M
+Assyrian/SM
+Astaire/M
+Astana/M
+Astarte/M
+Aston/M
+Astor/M
+Astoria/M
+Astra/M
+Astrakhan/M
+Astrid/M
+AstroTurf/M
+Asturias/M
+Asuncion/M
+Asuncin/M
+Aswan/M
+At/SM
+Atacama/M
+Atahualpa/M
+Atalanta/M
+Atari/M
+Atascadero/M
+Ataturk/M
+Atatrk/M
+Athabasca/M
+Athabaska
+Athabaskan/SM
+Athanasius
+Athena/M
+Athene/M
+Athenian/SM
+Athens/M
+Athlon/M
+Atkins/M
+Atkinson/M
+Atlanta/M
+Atlantes
+Atlantic/M
+Atlantis/M
+Atlas/MS
+Atman/M
+Atonement
+Atreus/M
+Atria/M
+Atropos/M
+Attic/M
+Attica/M
+Attila/M
+Attlee/M
+Attn
+Attucks/M
+Atwood/M
+Au/M
+Aube
+Aubert/M
+Aubrey/M
+Aubry/M
+Auburn/M
+Auckland/M
+Auden/M
+Audi/M
+Audie/M
+Audion/M
+Audra/M
+Audre/M
+Audrey/M
+Audubon/M
+Aug/M
+Augean/M
+Augie/M
+Augsburg/M
+August/MS
+Augusta/M
+Augustan/M
+Auguste/M
+Augustin/M
+Augustine/M
+Augustinian/MS
+Augusto/M
+Augustus/M
+Aurangzeb/M
+Aurea/M
+Aurel/M
+Aurelia/M
+Aurelie/M
+Aurelio/M
+Aurelius/M
+Aureomycin/M
+Auriga/M
+Aurora/M
+Aurore/M
+Auschwitz/M
+Aussie/MS
+Austen/M
+Austerlitz/M
+Austin/MS
+Australasia/M
+Australasian
+Australia/M
+Australian/SM
+Australoid/M
+Australopithecus/M
+Austria/M
+Austrian/SM
+Austronesian/M
+Autumn/M
+Av/M
+Ava/M
+Avalon/M
+Ave/M
+Aveline/M
+Aventine/M
+Averell/M
+Averil/M
+Averill/M
+Avernus/M
+Averroes/M
+Avery/M
+Avesta/M
+Avicenna/M
+Avigdor/M
+Avignon/M
+Avila/M
+Avior/M
+Avis/M
+Aviva/M
+Avogadro/M
+Avon/M
+Avondale/M
+Avram/M
+Avril/M
+Axe/M
+Axel
+Axis
+Axum/M
+Ayala/M
+Ayers/M
+Aylmer/M
+Aymara/M
+Aymer/M
+Ayn/M
+Ayrshire/M
+Ayurveda/M
+Ayyubid/M
+Azana/M
+Azania/M
+Azazel/M
+Azerbaijan/M
+Azerbaijani/MS
+Azores/M
+Azov/M
+Aztec/SM
+Aztecan/M
+Aztlan/M
+B/MNRTG
+BA/M
+BASIC/SM
+BB/M
+BBB/M
+BBC/M
+BBQ
+BBS
+BBSes
+BC/M
+BFF
+BIA
+BIOS
+BITNET
+BLT/SM
+BM/M
+BMW/M
+BO
+BP/M
+BPOE
+BR
+BS/M
+BSA
+BSD/SM
+BTU
+BTW
+BYOB
+Ba/M
+Baal/SM
+Baath/M
+Baathist/M
+Bab/SM
+Babb/M
+Babbage/M
+Babbie/M
+Babbitt/M
+Babel/MS
+Babette/M
+Babylon/MS
+Babylonia/M
+Babylonian/SM
+Bacall/M
+Bacardi/M
+Bacchanalia/M
+Bacchic
+Bacchus/M
+Bach/M
+Backus/M
+Bacon/M
+Bactria/M
+Baden/M
+Badlands/M
+Baedeker/MS
+Baez/M
+Baffin/M
+Baggies/M
+Baghdad/M
+Baguio/M
+Baha'i/M
+Baha'ullah/M
+Bahama/SM
+Bahamanian
+Bahamas/M
+Bahamian/MS
+Bahasa/M
+Bahia/M
+Bahrain/M
+Baidu/M
+Baikal/M
+Bailey/M
+Bailie/M
+Baillie/M
+Baily/M
+Baird/M
+Bakelite/M
+Baker/M
+Bakersfield/M
+Baku/M
+Bakunin/M
+Balanchine/M
+Balaton/M
+Balboa/M
+Bald's
+Balder/M
+Baldwin/SM
+Balearic/M
+Balfour/M
+Bali/M
+Balinese/M
+Balkan/MS
+Balkans/M
+Balkhash/M
+Ball/M
+Ballard/M
+Balthazar/M
+Baltic/M
+Baltimore/M
+Baluchistan/M
+Balzac/M
+Bamako/M
+Bambi/M
+Banach/M
+Bancorp
+Bancroft/M
+Bandung/M
+Bangalore/M
+Bangkok/M
+Bangladesh/M
+Bangladeshi/SM
+Bangor/M
+Bangui/M
+Banjarmasin/M
+Banjul/M
+Banks/M
+Banneker/M
+Bannister/M
+Banting/M
+Bantu/MS
+Baotou/M
+Baptist/SM
+Baptiste/M
+Barabbas/M
+Barack/M
+Barbadian/SM
+Barbados/M
+Barbara/M
+Barbarella/M
+Barbarossa/M
+Barbary/M
+Barbe/MR
+Barbee/M
+Barber/M
+Barbette/M
+Barbey/M
+Barbie/M
+Barbour/M
+Barbra/M
+Barbuda/M
+Barcelona/M
+Barceloneta/M
+Barclay/SM
+Barclays/M
+Barde/M
+Bardeen/M
+Barents/M
+Bari/M
+Barker/M
+Barkley/M
+Barlow/M
+Barnabas/M
+Barnaby/M
+Barnard/M
+Barnaul/M
+Barnes/M
+Barnett/M
+Barney/M
+Barnum/M
+Baroda/M
+Barquisimeto/M
+Barr/M
+Barranquilla/M
+Barrera/M
+Barret/M
+Barrett/M
+Barri/MS
+Barrie/M
+Barron/M
+Barry/M
+Barrymore/M
+Bart/M
+Bartel/M
+Barth/MS
+Barthel/M
+Bartholdi/M
+Bartholomew/M
+Bartlet/M
+Bartlett/M
+Bartok/M
+Bartolomeo/M
+Barton/M
+Bartram/M
+Barty/M
+Bartk/M
+Baruch/M
+Bary/M
+Baryshnikov/M
+Basel/M
+Basho/M
+Basia/M
+Basic
+Basie/M
+Basil/M
+Basile/M
+Basilio/M
+Basilius/M
+Basque/MS
+Basra/M
+Bass/M
+Basseterre/M
+Bastian/M
+Bastien/M
+Bastille/M
+Basutoland/M
+Bataan/M
+Bates/M
+Bathsheba/M
+Batista/M
+Batman/M
+Battle/M
+Batu/M
+Baudelaire/M
+Baudoin/M
+Baudouin/M
+Baudrillard/M
+Bauer/M
+Bauhaus/M
+Baum/M
+Bavaria/M
+Bavarian/M
+Bax
+Baxter/M
+Bayamon
+Bayard
+Bayer/M
+Bayes/M
+Bayesian/M
+Bayeux/M
+Baylor/M
+Bayonne/M
+Bayreuth/M
+Baywatch/M
+Be/MH
+Bea/M
+Beach/M
+Beadle/M
+Beale/M
+Bean/M
+Beard/M
+Beardmore/M
+Beardsley/M
+Bearnaise/M
+Beasley/M
+Beatlemania/M
+Beatles/M
+Beatrice/M
+Beatrix/M
+Beatriz/M
+Beatty/M
+Beau/M
+Beaufort/M
+Beaujolais/M
+Beaumarchais/M
+Beaumont/M
+Beauregard/M
+Beauvoir/M
+Bebe/M
+Becca/M
+Bechtel/M
+Beck/MR
+Becka/M
+Becker/M
+Becket/M
+Beckett/M
+Beckham/M
+Beckie/M
+Beckley/M
+Beckman
+Becky/M
+Becquerel/M
+Bede/M
+Bedouin/SM
+Beebe/M
+Beecher/M
+Beefaroni/M
+Beelzebub/M
+Beerbohm/M
+Beethoven/M
+Beeton/M
+Begin/M
+Behan/M
+Behring/M
+Beiderbecke/M
+Beijing/M
+Beirut/M
+Bekesy/M
+Bel/M
+Bela/M
+Belarus/M
+Belarusian
+Belau/M
+Belem/M
+Belfast/M
+Belg
+Belgian/SM
+Belgium/M
+Belgrade/M
+Belinda/M
+Belize/M
+Belkin/M
+Bell/M
+Bella/M
+Bellamy/M
+Bellatrix/M
+Belleek/M
+Bellevue/M
+Bellingham/M
+Bellini/M
+Bellow/M
+Belmont/M
+Belmopan/M
+Beloit/M
+Belorussian/MS
+Belshazzar/M
+Beltane/M
+Beltran/M
+Belushi/M
+Belva/M
+Ben/M
+Benacerraf/M
+Benares/M
+Benchley/M
+Bend/MR
+Bender/M
+Bendictus
+Bendix/M
+Benedetta/M
+Benedetto/M
+Benedick/M
+Benedict/M
+Benedicta/M
+Benedictine/MS
+Benedicto/M
+Benedikt/M
+Benelux/M
+Benet/M
+Benetton/M
+Bengal/SM
+Bengali/M
+Benghazi/M
+Bengt/M
+Benin/M
+Beninese/M
+Benita/M
+Benito/M
+Benjamin/M
+Benji/M
+Benjie/M
+Benjy/M
+Benn/M
+Bennett/M
+Bennie/M
+Benny/M
+Benoit/M
+Benson/M
+Bentham/M
+Bentley/M
+Benton/M
+Benz/M
+Benzedrine/M
+Beowulf/M
+Ber/MG
+Berber/SM
+Berenice/M
+Beretta/M
+Berg/MNR
+Bergen/M
+Berger/M
+Bergerac/M
+Bergman/M
+Bergson/M
+Beria/M
+Bering/M
+Berk/M
+Berke/M
+Berkeley/M
+Berkley/M
+Berkshire/SM
+Berkshires/M
+Berle/M
+Berlin/SZMR
+Berliner/M
+Berlioz/M
+Berlitz/M
+Bermuda/SM
+Bermudan/SM
+Bermudian/SM
+Bern/M
+Bernadette/M
+Bernadine/M
+Bernanke/M
+Bernard/M
+Bernardine
+Bernardo/M
+Bernays/M
+Bernbach/M
+Bernese
+Bernhard/M
+Bernhardt/M
+Berni/M
+Bernice/M
+Bernie/M
+Bernini/M
+Bernoulli/M
+Bernstein/M
+Berra/M
+Berri/M
+Berry/M
+Bert/M
+Berta/M
+Bertelsmann/M
+Bertha/M
+Berthe/M
+Berti/M
+Bertie/M
+Bertillon/M
+Berton/M
+Bertram/M
+Bertrand/M
+Berwick/M
+Beryl/M
+Berzelius/M
+Bess/M
+Bessel/M
+Bessemer/M
+Bessie/M
+Bessy/M
+Best/M
+Betelgeuse/M
+Beth/M
+Bethany/M
+Bethe/M
+Bethesda/M
+Bethlehem/M
+Bethune/M
+Betsey/M
+Betsy/M
+Betta/M
+Bette/M
+Betti
+Bettie/M
+Bettina/M
+Betty/M
+Bettye/M
+Beulah/M
+Bevan
+Beveridge
+Beverley/M
+Beverly/M
+Bevin
+Bevvy's
+Beyer/M
+Bharat/M
+Bhopal/M
+Bhutan/M
+Bhutanese/M
+Bhutto/M
+Bi/M
+Bialystok/M
+Bianca/M
+Bib
+BibSonomy/M
+BibTeX/M
+Bibby/M
+Bibi/M
+Bible/MS
+Biblical/M
+Bic/M
+Biddle/M
+Biden/M
+Bierce/M
+BigQuery/M
+Bigfoot/M
+Biggles/M
+Biko/M
+Bil/MY
+Bilbao/M
+Bilbo/M
+Bili/M
+Bill/MJ
+Billie/M
+Billings/M
+Billy/M
+Bimini/M
+Bing/M
+Binghamton/M
+Bink/M
+Binky/M
+Binnie/M
+Biogen/M
+Bioko/M
+Bird/M
+Birdseye/M
+Birgit/M
+Birgitta/M
+Birk/M
+Birkenstock/M
+Birmingham/M
+Biro/M
+Biron/M
+Biscay/M
+Biscayne/M
+Bishkek/M
+Bishop/M
+Bismarck/M
+Bismark/M
+Bisquick/M
+Bissau/M
+BitTorrent/M
+BizRate/M
+Bizet/M
+Bjerknes/M
+Bjork/M
+Bjorn/M
+Bk/M
+Black/MS
+BlackBerry/M
+Blackbeard/M
+Blackburn/M
+Blackfeet/M
+Blackfoot/M
+Blackpool/M
+Blacksburg/M
+Blackshirt/M
+Blackstone/M
+Blackwell/M
+Blaine/M
+Blair/M
+Blake/M
+Blakeley/M
+Blanca/M
+Blanch's
+Blanchard/M
+Blanche/M
+Blane/M
+Blankenship/M
+Blantyre/M
+Blatz/M
+Blavatsky/M
+Blenheim/M
+Blevins/M
+Bligh/M
+BlinkList/M
+Blithe's
+Bloch/M
+Blockbuster/M
+Bloemfontein/M
+Blondel/M
+Blondie/M
+Bloom/MR
+Bloomberg/M
+Bloomer/M
+Bloomfield/M
+Bloomingdale/M
+Bloomington/M
+Bloomsburg/M
+Bloomsbury/M
+Blu
+Blucher/M
+Bluebeard/M
+Bluetooth/M
+Blvd
+Blythe/M
+Bo/MRZ
+Boadicea
+Boas/M
+Bob/M
+Bobbi/M
+Bobbie/M
+Bobbitt/M
+Bobby/M
+Boccaccio/M
+Bodhidharma/M
+Bodhisattva/M
+Bodleian
+Boeing/M
+Boeotia/M
+Boeotian/M
+Boer/M
+Boethius/M
+Bogart/M
+Bogota/M
+Bogot/M
+Bohemia/M
+Bohemian/SM
+Bohr/M
+Boise/M
+Bojangles/M
+Boleyn/M
+Bolivar/M
+Bolivia/M
+Bolivian/MS
+Bollywood/M
+Bologna/M
+Bolshevik/SM
+Bolsheviki
+Bolshevism/M
+Bolshevist/M
+Bolshoi/M
+Bolton/M
+Boltzmann/M
+Bombay/M
+Bonaparte/M
+Bonaventure/M
+Bond/M
+Bondy/M
+Bonhoeffer/M
+Boniface/M
+Bonita/M
+Bonn/MR
+Bonner/M
+Bonneville/M
+Bonnie/M
+Bono/M
+Booker/M
+Boole/M
+Boolean/M
+Boone/M
+Bootes/M
+Booth/M
+Boothe/M
+Bord/MN
+Bordeaux/M
+Borden/M
+Bordon/M
+Boreas/M
+Borg/SM
+Borges/M
+Borgia/M
+Borglum/M
+Boris/M
+Bork/M
+Borlaug/M
+Born/M
+Borneo/M
+Borobudur/M
+Borodin/M
+Boru/M
+Bosch/M
+Bose/M
+Bosnia/M
+Bosnian
+Bosporus/M
+Boston/MS
+Bostonian/M
+Boswell/M
+Botha
+Botox
+Botswana/M
+Botticelli/M
+Boulder/M
+Boulez/M
+Bourbaki/M
+Bourbon/SM
+Bourke/M
+Bournemouth/M
+Bovary/M
+Bowditch/M
+Bowell/M
+Bowen/M
+Bowers/M
+Bowery/M
+Bowie/M
+Bowman/M
+Boyce/M
+Boyd/M
+Boyer/M
+Boyle/M
+Botes/M
+Br/MNT
+Brad/MNY
+Bradbury/M
+Braddock/M
+Braden/M
+Bradenton/M
+Bradford/M
+Bradley/M
+Bradly/M
+Bradshaw/M
+Bradstreet/M
+Brady/M
+Bragg/M
+Brahe/M
+Brahma/MS
+Brahmagupta/M
+Brahman/MS
+Brahmani
+Brahmanism/SM
+Brahmaputra/M
+Brahms/M
+Braille/MS
+Brain/M
+Bram/M
+Brampton/M
+Bran/M
+Branch/M
+Brande/MR
+Brandeis/M
+Branden/M
+Brandenburg/M
+Brander/M
+Brandi/M
+Brandie/M
+Brando/M
+Brandon/M
+Brandt/M
+Brandy/M
+Brannon/M
+Brant/M
+Brantley/M
+Braque/M
+Brasilia/M
+Bratislava/M
+Brattain/M
+Bray/M
+Brazil/M
+Brazilian/MS
+Brazos/M
+Brazzaville/M
+Breakspear/M
+Breathalyzer
+Brecht/M
+Breckenridge/M
+Bree/M
+Bremen/M
+Bremerton/M
+Bren/M
+Brenda/M
+Brendan/M
+Brenden/M
+Brendon/M
+Brenna/M
+Brennan/M
+Brenner/M
+Brent/M
+Brenton/M
+Brest/M
+Bret/M
+Breton/M
+Brett/M
+Brewer/M
+Brewster/M
+Brexit
+Brezhnev/M
+Brian/M
+Briana/M
+Brianna/M
+Brianne/M
+Briant/M
+Brice/M
+Bridalveil/M
+Bridgeport/M
+Bridger/M
+Bridges/M
+Bridget/M
+Bridgetown/M
+Bridgett/M
+Bridgette/M
+Bridgman/M
+Bridie/M
+Brie/SM
+Brien/M
+Brigadoon/M
+Brigg/MS
+Briggs/M
+Brigham/M
+Bright/M
+Brighton/M
+Brigid/M
+Brigida/M
+Brigit/M
+Brigitta/M
+Brigitte/M
+Brillo/M
+Brillouin
+Brinkley/M
+Briny's
+Brion/M
+Brisbane/M
+Bristol/M
+Brit/SM
+Brita/M
+Britain/M
+Britannia/M
+Britannic/M
+Britannica/M
+Briticism/SM
+British/MRZ
+Britisher/M
+Britney/M
+Briton/MS
+Britt/MN
+Britta/M
+Brittan/M
+Brittany/SM
+Britten/M
+Brittney/M
+Brno/M
+Broadway/SM
+Brobdingnag/M
+Brobdingnagian/M
+Brock/M
+Brod/M
+Broderick/M
+Brodie/M
+Brody/M
+Brokaw/M
+Bron/M
+Bronson/M
+Bronte/M
+Brontosaurus
+Bronx/M
+Brooke/MS
+Brooklyn/M
+Brooks/M
+Bros
+Brose/M
+Brown/MG
+Browne/M
+Brownian/M
+Brownie/S
+Browning/M
+Brownshirt/M
+Brownsville/M
+Brubeck/M
+Bruce/M
+Bruckner/M
+Bruegel
+Brummel/M
+Brunei/M
+Bruneian/MS
+Brunelleschi/M
+Brunhilde/M
+Bruno/M
+Brunswick/M
+Brussels/M
+Brut/M
+Brutus/M
+Bryan/M
+Bryant/M
+Bryce/M
+Bryn/M
+Brynn/MR
+Brynner/M
+Bryon/M
+Brzezinski/M
+Btu/M
+Buber/M
+Buchanan/M
+Bucharest/M
+Buchenwald/M
+Buchwald/M
+Buck/M
+Buckingham/M
+Buckley/M
+Buckner/M
+Bucky/M
+Bud/M
+Budapest/M
+Budd/M
+Buddha/SM
+Buddhism/SM
+Buddhist/SM
+Buddy/M
+Budweiser/M
+Buenos
+Buffalo/M
+Buffy/M
+Buford/M
+Bugatti/M
+Bugzilla/M
+Buick/M
+Bujumbura/M
+Bukhara/M
+Bukharin/M
+Bulawayo/M
+Bulfinch/M
+Bulganin/M
+Bulgar/M
+Bulgari/M
+Bulgaria/M
+Bulgarian/SM
+Bullock/M
+Bullwinkle/M
+Bultmann/M
+Bumppo/M
+Bunche/M
+Bundesbank/M
+Bundestag/M
+Bunin/M
+Bunker/M
+Bunsen/M
+Bunuel/M
+Bunyan/M
+Burbank/M
+Burberry/M
+Burch/M
+Burger/M
+Burgess/M
+Burgoyne/M
+Burgundian/M
+Burgundy/SM
+Burk/SM
+Burke/M
+Burkina/M
+Burks/M
+Burl/M
+Burlington/M
+Burma/M
+Burmese/M
+Burnaby/M
+Burnard/M
+Burnett/M
+Burns/M
+Burnside/M
+Burr/M
+Burris/M
+Burroughs/M
+Bursa/M
+Burt/M
+Burton/M
+Burundi/M
+Burundian/MS
+Busch/M
+Bush/M
+Bushido/M
+Bushnell/M
+Butler/M
+Butterfingers/M
+Buxtehude/M
+Buuel/M
+Byblos/M
+Byers/M
+Byram/M
+Byrd/M
+Byrom/M
+Byron/M
+Byronic/M
+Byzantine/MS
+Byzantium/M
+C/SMD
+CA
+CAD/M
+CAI
+CAM
+CAP
+CAPTCHA
+CARE
+CATV
+CB
+CBC/M
+CBS/M
+CCTV
+CCU
+CD/SM
+CDC
+CDT
+CEO/SM
+CF
+CFC/SM
+CFO
+CGI
+CIA/M
+CID
+CNN/M
+CNS/M
+CO/M
+COBOL/SM
+COD
+COL
+COLA
+COVID
+CPA/M
+CPI/M
+CPO
+CPR/M
+CPU/M
+CRT/SM
+CSS/M
+CST/M
+CT/M
+CV
+CVS/M
+CZ
+Ca/M
+Cabernet/M
+Cabot/M
+Cabral/M
+Cabrera/M
+Cabrini/M
+Cad/M
+Cadette
+Cadillac/M
+Cadiz/M
+Caedmon/M
+Caerphilly/M
+Caesar/SM
+Cage/M
+Cagney/M
+Cahokia/M
+Caiaphas/M
+Caicos/M
+Cain/SM
+Cairo/M
+Caitlin/M
+Cajun/MS
+Cal/MY
+Calais/M
+Calcutta/M
+Calder/M
+Calderon/M
+Caldwell/M
+Cale/M
+Caleb/M
+Caledonia/M
+Calexico/M
+Calgary/M
+Calhoun/M
+Cali/M
+Caliban/M
+Calif
+California/M
+Californian/SM
+Caligula/M
+Callaghan/M
+Callahan/M
+Callao/M
+Callas/M
+Calley/M
+Calli/M
+Callie/M
+Calliope/M
+Callisto/M
+Cally/M
+Caloocan/M
+Calvary/M
+Calvert/M
+Calvin/M
+Calvinism/MS
+Calvinist/MS
+Calvinistic
+Camacho/M
+Camarillo/M
+Cambodia/M
+Cambodian/SM
+Cambrian/SM
+Cambridge/M
+Cambridgeshire/M
+Camden/M
+Camel/M
+Camelopardalis/M
+Camelot/MS
+Camembert/MS
+Cameron/M
+Cameroon/SM
+Cameroonian/MS
+Cami/M
+Camila/M
+Camilla/M
+Camille/M
+Cammie/M
+Cammy/M
+Camoens/M
+Campanella/M
+Campbell/M
+Campinas/M
+Campos/M
+Camry/M
+Camus/M
+Can/M
+Canaan/M
+Canaanite/MS
+Canad
+Canada/M
+Canadian/SM
+Canadianism
+Canaletto/M
+Canaries/M
+Canaveral/M
+Canberra/M
+Cancer/SM
+Cancun/M
+Candace/M
+Candi/M
+Candice/M
+Candida/M
+Candide/M
+Candra/M
+Candy/M
+Cannes/M
+Cannon/M
+Canon/M
+Canopus/M
+Cantabrigian/M
+Canterbury/M
+Canton/M
+Cantonese/M
+Cantor/M
+Cantrell/M
+Cantu/M
+Canute/M
+Capablanca/M
+Capek/M
+Capella/M
+Capet/M
+Capetian/M
+Capetown/M
+Caph/M
+Capistrano/M
+Capitol/SM
+Capitoline/M
+Capone/M
+Capote/M
+Capra/M
+Capri/M
+Capricorn/MS
+Capt
+Capuchin/M
+Capulet/M
+Cara/M
+Caracalla/M
+Caracas/M
+Caravaggio/M
+Carboloy/M
+Carbondale/M
+Carboniferous/M
+Carborundum/M
+Cardenas/M
+Cardiff/M
+Cardin/M
+Cardozo/M
+CareerBuilder/M
+Caren/M
+Carey/M
+Cari/M
+Caria
+Carib/MS
+Caribbean/MS
+Carin/M
+Carina/M
+Carine/M
+Carissa/M
+Carita/M
+Carl/GMN
+Carla/M
+Carlen/M
+Carlene/M
+Carleton/M
+Carley/M
+Carlie/M
+Carlin/M
+Carling/M
+Carlisle/M
+Carlo/MS
+Carlos/M
+Carlota
+Carlotta/M
+Carlsbad/M
+Carlson/M
+Carlton/M
+Carly/M
+Carlyle/M
+Carmel
+Carmela/M
+Carmelita/M
+Carmella/M
+Carmelo/M
+Carmen/M
+Carmichael/M
+Carmina/M
+Carmine/M
+Carnap/M
+Carnation/M
+Carnegie/M
+Carney/M
+Carnot/M
+Caro/M
+Carol/M
+Carola/M
+Carolan/M
+Carole/M
+Carolina/M
+Caroline/M
+Carolingian/M
+Carolinian/M
+Carolus/M
+Carolyn/M
+Carolyne/M
+Caron/M
+Carpathian/SM
+Carpathians/M
+Carpenter/M
+Carr/M
+Carranza/M
+Carrie/RM
+Carrier/M
+Carrillo/M
+Carrol/M
+Carroll/M
+Carson/M
+Carter/M
+Cartersville/M
+Cartesian/M
+Carthage/M
+Carthaginian/MS
+Cartier/M
+Cartwright/M
+Caruso/M
+Carver/M
+Cary/M
+Caryl/M
+Caryn/M
+Casablanca/M
+Casals/M
+Casandra/M
+Casanova/SM
+Casar/M
+Cascades/M
+Case/M
+Casey/M
+Cash/M
+Casi/M
+Casio/M
+Caspar/M
+Casper/M
+Caspian/M
+Cass/M
+Cassandra/SM
+Cassatt/M
+Cassi/M
+Cassidy/M
+Cassie/M
+Cassini/M
+Cassiopeia/M
+Cassius/M
+Cassy/M
+Castaneda/M
+Castile/M
+Castilian
+Castillo/M
+Castlereagh/M
+Castor/M
+Castries/M
+Castro/M
+Catalan/SM
+Catalina/M
+Catalonia/M
+Catarina/M
+Catawba/M
+Cate/M
+Caterina/M
+Caterpillar/M
+Catharina/M
+Catharine/M
+Cathay/M
+Cather/M
+Catherine/M
+Cathie/M
+Cathleen/M
+Catholic/MS
+Catholicism/MS
+Cathryn/M
+Cathy/M
+Cati/M
+Catie/M
+Catiline/M
+Catlin/M
+Cato/M
+Catrina/M
+Catriona/M
+Catskill/SM
+Catskills/M
+Catt/M
+Catullus/M
+Caucasian/MS
+Caucasoid
+Caucasus/M
+Cauchy/M
+Cavendish/M
+Cavour/M
+Caxton/M
+Caye/M
+Cayenne/M
+Cayman/M
+Cayuga/SM
+Cayuse
+Caz/M
+Cb
+Cd/M
+Ce/M
+Ceausescu/M
+Cebu/M
+Cebuano/M
+Cece/M
+Cecelia/M
+Cecil/M
+Cecile/M
+Cecilia/M
+Cecilio/M
+Cecily/M
+Ced/M
+Cedric/M
+Ceil/M
+Cele/M
+Celebes/M
+Celeste/M
+Celestia/M
+Celestina/M
+Celestine/M
+Celgene/M
+Celia/M
+Celie/M
+Celina/M
+Celine/M
+Celle/M
+Cellini/M
+Celsius/M
+Celt/SM
+Celtic/SM
+Cenozoic/M
+Centaurus/M
+Centigrade
+Central
+Centro/M
+Cepheid/M
+Cepheus/M
+Cerberus/M
+Cerenkov/M
+Ceres/M
+Cerf/M
+Cervantes/M
+Cesar/M
+Cesare/M
+Cesarean/M
+Cessna/M
+Cetus/M
+Ceylon/M
+Ceylonese
+Cezanne/M
+Cf/M
+Ch'in/M
+Ch/NRS
+Chablis/M
+Chad/M
+Chadian/MS
+Chadwick/M
+Chagall/M
+Chaim/M
+Chaitanya/M
+Chaitin/M
+Chaldea
+Chaldean/M
+Challenger/M
+Chalmers
+Chamberlain/M
+Chambers/M
+Chambersburg/M
+Champaign/M
+Champlain/M
+Champollion/M
+Chan/M
+Chance/M
+Chancellorsville/M
+Chancey/M
+Chanda/M
+Chandigarh/M
+Chandler/M
+Chandon/M
+Chandra/M
+Chandragupta/M
+Chandrasekhar/M
+Chane/M
+Chanel/M
+Chaney/M
+Chang/M
+Changchun/M
+Changsha/M
+Channa/M
+Chantal/M
+Chantilly/M
+Chaplin/M
+Chaplinesque
+Chapman/M
+Chappaquiddick/M
+Chapultepec/M
+Chara
+Charbray/M
+Chardonnay/M
+Charis
+Charisse/M
+Charity/M
+Charlemagne/M
+Charlene/M
+Charles/M
+Charleston/MS
+Charley/M
+Charlie/M
+Charlot/M
+Charlotta/M
+Charlotte/M
+Charlottesville/M
+Charlottetown/M
+Charlton
+Charmaine/M
+Charmian/M
+Charmin/M
+Charolais/M
+Charon/M
+Chartism/M
+Chartres/M
+Charybdis/M
+Chas
+Chase/M
+Chasity/M
+ChatZilla/M
+Chateaubriand/M
+Chatham/M
+Chattahoochee/M
+Chattanooga/M
+Chatterley/M
+Chatterton/M
+Chaucer/M
+Chauncey/M
+Chautauqua/M
+Chavez/M
+Chayefsky/M
+Che/M
+Chechen/M
+Chechnya/M
+Cheddar/M
+Cheer/M
+Cheerios/M
+Cheetos/M
+Cheever/M
+Chekhov/M
+Chekhovian
+Chelsea/M
+Chelyabinsk/M
+Chen/M
+Cheney/M
+Chengdu/M
+Chennai/M
+Cheops/M
+Chere/M
+Cheri/M
+Cherie/M
+Cherise/M
+Cherish's
+Chernenko/M
+Chernobyl/M
+Chernomyrdin/M
+Cherokee/MS
+Cherry/M
+Cheryl/M
+Chesapeake/M
+Cheshire/M
+Chester/M
+Chesterfield/M
+Chesterton/M
+Chet/M
+Chev/M
+Chevalier/M
+Cheviot/M
+Chevrolet/M
+Chevron/M
+Chevy/M
+Cheyenne/SM
+Chi/M
+Chianti/MS
+Chiba/M
+Chibcha/M
+Chicago/M
+Chicagoan/M
+Chicana/M
+Chicano/M
+Chickasaw/MS
+Chiclets/M
+Chico/M
+Chihuahua/MS
+Chile/M
+Chilean/MS
+Chilton/M
+Chimborazo/M
+Chimera/MS
+Chimu/M
+Chin/M
+China/M
+Chinatown/M
+Chinese/M
+Chinook/MS
+Chipewyan/M
+Chippendale/M
+Chippewa/SM
+Chiquita/M
+Chirico/M
+Chisholm/M
+Chisinau/M
+Chittagong/M
+Chivas/M
+Chloe/M
+Chloris/M
+Choctaw/SM
+Choi/M
+Chomsky/M
+Chongqing/M
+Chopin/M
+Chopra/M
+Chou/M
+Chretien/M
+Chris/M
+Chrissie/M
+Chrissy/M
+Christ/MS
+Christa/M
+Christabel/M
+Christchurch/M
+Christel/M
+Christen's
+Christendom/MS
+Christensen/M
+Christi/M
+Christian/SM
+Christiana/M
+Christiane/M
+Christianity/SM
+Christianize/DG
+Christie/M
+Christina/M
+Christine/M
+Christlike
+Christmas/MS
+Christmastide/MS
+Christmastime/MS
+Christoper/M
+Christoph/MR
+Christophe
+Christopher/M
+Christos/M
+Chromebook/MS
+Chronicles
+Chrysler/M
+Chrysostom/M
+Chrystal/M
+Chuck/M
+Chukchi/M
+Chumash/M
+Chung/M
+Church/M
+Churchill/M
+Churriguera/M
+Chuvash/M
+Ci/M
+Cicely/M
+Cicero/M
+Cid/M
+Ciel/M
+Cimabue/M
+Cincinnati/M
+Cinderella/MS
+Cindi/M
+Cindy/M
+CinemaScope/M
+Cinerama/M
+Cingular/M
+Cipro/M
+Circe/M
+Cirillo/M
+Ciro/M
+Cisco/M
+Cissy/M
+Citibank/M
+Citigroup/M
+Citroen/M
+Cl/MV
+Claiborne/M
+Clair/M
+Claire/M
+Clairol/M
+Clancy/M
+Clapeyron/M
+Clapton/M
+Clara/M
+Clare/M
+Clarence/M
+Clarendon/M
+Clari/M
+Claribel/M
+Clarice/M
+Clarinda/M
+Clarissa/M
+Clarisse/M
+Clarita/M
+Clark/M
+Clarke/M
+Clarkson/M
+Clarksville/M
+Clary/M
+Claude/M
+Claudette/M
+Claudia/M
+Claudian/M
+Claudine/M
+Claudio/M
+Claudius/M
+Claus/M
+Clausewitz/M
+Clausius/M
+Clay/M
+Clayborne/M
+Clayton/M
+Clea/M
+Clearasil/M
+Clem/XM
+Clemence/M
+Clemenceau/M
+Clemens/M
+Clement/MS
+Clemente/M
+Clementina/M
+Clementine/M
+Clements/M
+Clemmie/M
+Clemons/M
+Clemson/M
+Cleo/M
+Cleon
+Cleopatra/M
+Clerc/M
+Cletus/M
+Cleve/M
+Cleveland/M
+Cliburn/M
+Cliff/M
+Clifford/M
+Clifton/M
+Cline/M
+Clint/M
+Clinton/M
+Clio/M
+Clive/M
+Clo/M
+Clojure/M
+Clorets/M
+Clorox/M
+Closure/M
+Clotho/M
+Clotilda/M
+Clouseau/M
+Clovis/M
+Clyde/M
+Clydesdale/M
+Clytemnestra/M
+Cm/M
+Cmdr
+Co/M
+Cobain/M
+Cobb/M
+Cochabamba/M
+Cochin/M
+Cochise/M
+Cochran/M
+Cockney/M
+Cocteau/M
+Cod
+Cody/M
+Coffey/M
+Cognac/M
+Cohan/M
+Cohen/M
+Coimbatore/M
+Cointreau/M
+Coke/SM
+Col/M
+Colbert/M
+Colby/M
+ColdFusion/M
+Cole/M
+Coleen/M
+Coleman/M
+Coleridge/M
+Colet
+Coletta/M
+Colette/M
+Colfax/M
+Colgate/M
+Colin/M
+Colleen/M
+Collen/M
+Collette/M
+Collier/M
+Collin/SM
+Colline/M
+Collins/M
+Colman/M
+Colo
+Cologne/M
+Colombia/M
+Colombian/MS
+Colombo/M
+Colon/M
+Coloradan/SM
+Colorado/M
+Coloradoan
+Colosseum/M
+Colt/M
+Coltrane/M
+Columbia/M
+Columbine/M
+Columbus/M
+Com
+Comanche/MS
+Combs/M
+Comcast/M
+Comdr
+Comintern/M
+Commandment
+Commons/M
+Commonwealth
+Communion/SM
+Communism
+Communist/SM
+Como/M
+Comoran
+Comoros/M
+Compaq/M
+Compton/M
+CompuServe/M
+Computerworld/M
+Comte/M
+Conakry/M
+Conan/M
+Conant/M
+Concepcion/M
+Concepcin/M
+Concetta/M
+Conchita/M
+Concord/SM
+Concorde/M
+Concordia/M
+Condillac/M
+Condorcet/M
+Conestoga/M
+Confederacy/M
+Confederate/MS
+Confucian/SM
+Confucianism/MS
+Confucius/M
+Cong/M
+Congo/M
+Congolese/M
+Congregational
+Congregationalist/MS
+Congress/MS
+Congressional/Y
+Congreve/M
+Conley/M
+Conn/MR
+Connecticut/M
+Connellsville/M
+Connemara/M
+Conner/M
+Connery/M
+Connie/M
+Connolly/M
+Connor/SM
+Connors/M
+Conny/M
+Conrad/M
+Conrado/M
+Conrail/M
+Conroe/M
+Conroy/M
+Conservative
+Constable/M
+Constance/M
+Constancia/M
+Constanta/M
+Constantia
+Constantin/M
+Constantine/M
+Constantino/M
+Constantinople/M
+Constitution
+Consuela/M
+Consuelo/M
+Continent/M
+Continental/M
+Contreras/M
+Conway/M
+Cook/M
+Cooke/M
+Cooley/M
+Coolidge/M
+Cooper/M
+Cooperstown/M
+Coors/M
+Copacabana/M
+Copeland/M
+Copenhagen/M
+Copernican/M
+Copernicus/M
+Copland/M
+Copley/M
+Copperfield/M
+Coppertone/M
+Coppola/M
+Coptic/M
+Cora/M
+Coralie/M
+Corbet/M
+Corbett/M
+Corbie/M
+Corbin/M
+Corby
+Cordelia/M
+Cordell/M
+Cordilleras/M
+Cordoba/M
+Cordy/M
+Coretta/M
+Corey/M
+Corfu/M
+Cori/M
+Corina/M
+Corine/M
+Corinna/M
+Corinne/M
+Corinth/M
+Corinthian/MS
+Corinthians/M
+Coriolanus/M
+Coriolis/M
+Cork
+Corleone/M
+Corliss/M
+Cormack/M
+Corneille/M
+Cornelia/M
+Cornelius/M
+Cornell/M
+Corney/M
+Corning/M
+Cornish/MS
+Cornwall/M
+Cornwallis/M
+Corny's
+Coronado/M
+Corot/M
+Corp
+Correggio/M
+Corrie/M
+Corrine/M
+Corry/M
+Corsica/M
+Corsican/M
+Cort/M
+Cortes/MS
+Cortland/M
+Corvallis/M
+Corvette/M
+Corvus/M
+Cory/M
+Cosby/M
+Cosette/M
+Cosimo/M
+Cosme/M
+Cosmo/M
+CosmosDB/M
+Cossack/M
+Costa/M
+Costanza/M
+Costco/M
+Costello/M
+Costner/M
+Cote/M
+Cotonou/M
+Cotopaxi/M
+Cotswold/M
+Cotton/M
+Coulomb/M
+Coulter/M
+Councillor/MS
+Couperin/M
+Courbet/M
+Courtenay/M
+Courtney/M
+Cousteau/M
+Coventry/SM
+Covington/M
+Coward/M
+Cowell/M
+Cowley/M
+Cowper/M
+Cox/M
+Coy/M
+Coyle/M
+Cozumel/M
+Cpl
+Cr/MT
+Crabbe/M
+Craft/M
+Craggy's
+Craig/M
+Craigslist/M
+Cranach/M
+Crane/M
+Cranmer/M
+Crater/M
+Crawford/M
+Cray/M
+Crayola/M
+Creation/M
+Creator/M
+Crecy/M
+Cree/DSM
+Creek/SM
+Creighton/M
+Creole/SM
+Creon/M
+Cressida/M
+Crest/M
+Cretaceous/M
+Cretan/SM
+Crete/M
+Crichton/M
+Crick/M
+Crimea/M
+Crimean/M
+Criollo/M
+Cris/M
+Crisco/M
+Crissy/M
+Crista/M
+Cristal/M
+Cristian/M
+Cristiano/M
+Cristina/M
+Cristobal/M
+Croat/SM
+Croatia/M
+Croatian/MS
+Croce/M
+Crockett/M
+Croesus/M
+Cromwell/M
+Cromwellian/M
+Cronin/M
+Cronkite/M
+Cronus/M
+Crookes/M
+Crosby/M
+Cross/M
+Crow/SM
+Crowley/M
+Crucifixion/MS
+Cruikshank/M
+Cruise/M
+Crusades's
+Crusoe/M
+Crux/M
+Cruz/M
+Cryptozoic/M
+Crystal/M
+Csonka/M
+Ct
+Ctesiphon/M
+Cthulhu/M
+Cu/M
+Cuba/M
+Cuban/SM
+Cuchulain/M
+Cuisinart/M
+Culbertson/M
+Cullen/M
+Culley/M
+Cully/M
+Culver/M
+Cumberland/M
+Cumbria/M
+Cummings/M
+Cunard/M
+Cunningham/M
+Cupid/M
+Curacao/M
+Curcio/M
+Curie/M
+Curitiba/M
+Curr/M
+Curran/M
+Currey/M
+Currie/M
+Currier/M
+Curry/RM
+Curt/M
+Curtice/M
+Curtis/M
+Custer/M
+Cuvier/M
+Cuzco/M
+Cy
+Cybele/M
+Cybil/M
+Cyclades/M
+Cyclopes/M
+Cyclops/M
+Cygnus/M
+Cymbeline/M
+Cyndi/M
+Cynthia/M
+Cynthy/M
+Cyprian/M
+Cypriot/MS
+Cyprus/M
+Cyrano/M
+Cyril/M
+Cyrille/M
+Cyrillic/M
+Cyrus/M
+Czech/M
+Czechia/M
+Czechoslovak
+Czechoslovakia/M
+Czechoslovakian/SM
+Czechs
+Czerny/M
+D'Arcy
+D/M
+DA/M
+DAR
+DAT/M
+DBMS/M
+DC/M
+DD/M
+DDS/M
+DDT/S
+DE
+DEA
+DEC/SD
+DH
+DHS
+DI
+DJ
+DMCA
+DMD/M
+DMZ
+DNA/M
+DOA
+DOB
+DOD
+DOE
+DOS/M
+DOT
+DP/SM
+DPT
+DRM
+DST
+DTP
+DUI
+DVD/S
+DVR/SM
+DWI
+Dacey/M
+Dachau/M
+Dacia
+Dacron/SM
+Dada/M
+Dadaism/M
+Daedalus/M
+Daffy's
+Dag's
+Dagmar/M
+Dagny/M
+Daguerre/M
+Dagwood/M
+Dahomey/M
+Daimler/M
+Daisy/M
+Dakar/M
+Dakota/SM
+Dakotan/M
+Dal/M
+Dalai
+Dale/M
+Daley/M
+Dali/M
+Dalia/M
+Dalian/M
+Dalila/M
+Dall/M
+Dallas/M
+Dalmatia/M
+Dalmatian/SM
+Dalton/M
+Damara/M
+Damaris/M
+Damascus/M
+Dame/MN
+Damian/M
+Damiano/M
+Damien/M
+Damion/M
+Damocles/M
+Damon/M
+Dan/M
+Dana/M
+Danae/M
+Dana/M
+Danbury/M
+Dane/SM
+Danelaw/M
+Danette/M
+Dangerfield/M
+Dani/M
+Dania/M
+Danial/M
+Danica/M
+Daniel/SM
+Daniela/M
+Daniele/M
+Daniella/M
+Danielle/M
+Daniels/M
+Danish/M
+Danna/M
+Danni/M
+Dannie/M
+Danny/M
+Danone/M
+Dante/M
+Danton/M
+Danube/M
+Danubian/M
+Danville/M
+Daphne/M
+Dar/MNH
+Dara/M
+Darby/M
+Darcey/M
+Darci/M
+Darcie/M
+Darcy/M
+Dardanelles/M
+Dare/M
+Daren/M
+Darfur/M
+Dari/M
+Daria/M
+Darin/M
+Dario/M
+Darius/M
+Darjeeling/M
+Darla/M
+Darlene/M
+Darling/M
+Darnell/M
+Daron/M
+Darrel/M
+Darrell/M
+Darren/M
+Darrin/M
+Darrow/M
+Darryl/M
+Darsie/M
+Darth/M
+Dartmoor/M
+Dartmouth/M
+Darvon/M
+Darwin/M
+Darwinian/M
+Darwinism/SM
+Darwinist
+Darya/M
+Daryl/M
+Dasha/M
+Datamation
+Daugherty/M
+Daumier/M
+Dav/M
+Davao/M
+Dave/M
+Davenport/M
+Davey/M
+David/MS
+Davida/M
+Davide/M
+Davidson/M
+Davie/M
+Davies/M
+Davin/M
+Davina/M
+Davis/M
+Davy/SM
+Dawes/M
+Dawkins
+Dawn/M
+Dawson/M
+Day/M
+Dayan
+Dayna/M
+Dayton/M
+Daytona/M
+De/RSMN
+DeGeneres/M
+DeKalb/M
+Deadhead/M
+DealTime/M
+Dean/M
+Deana/M
+Deandre/M
+Deane/M
+Deann/M
+Deanna/M
+Deanne/M
+Death/M
+Deb/SM
+Debbi/M
+Debbie/M
+Debby/M
+Debi/M
+Debian/M
+Debora/M
+Deborah/M
+Debouillet/M
+Debra/M
+Debs/M
+Debussy/M
+Dec/M
+Decalogue/M
+Decatur/M
+Decca/M
+Deccan/M
+December/SM
+Decker/M
+Dede/M
+Dedekind/M
+Dee/M
+Deedee/M
+Deena/M
+Deere/M
+Defoe/M
+Degas/M
+Deidre/M
+Deimos/M
+Deirdre/M
+Deity
+Dejesus/M
+Del/M
+Dela/M
+Delacroix/M
+Delacruz/M
+Delaney/M
+Delano/M
+Delaware/MS
+Delawarean/SM
+Delbert/M
+Deleon/M
+Delgado/M
+Delhi/M
+Delia/M
+Delibes/M
+Delicious/M
+Delilah/M
+Delilahs
+Delius/M
+Dell/M
+Della/M
+Delmar/M
+Delmarva/M
+Delmer/M
+Delmonico/M
+Delmore/M
+Deloitte/M
+Delores/M
+Deloria/M
+Deloris/M
+Delphi/M
+Delphic/M
+Delphine/M
+Delphinus/M
+Delta/M
+Deltona/M
+Dem/G
+Demavend/M
+Demerol/M
+Demeter/M
+Demetri/M
+Demetria/M
+Demetrius/M
+Deming/M
+Democrat/SM
+Democratic
+Democritus/M
+Demosthenes/M
+Demott/M
+Dempsey/M
+Dena/M
+Denali
+Dene
+Deneb/M
+Denebola/M
+Deng/M
+Deni/SM
+Denis/M
+Denise/M
+Denmark/M
+Denney/M
+Dennie/M
+Dennis/M
+Dennison/M
+Denny/M
+Denton/M
+Denver/M
+Deny's
+Denys
+Deon/M
+Depp/M
+Der/M
+Derby/M
+Derek/M
+Derick/M
+Derk/M
+Dermot/M
+Derrick/M
+Derrida/M
+Derry
+Descartes/M
+Desdemona/M
+Deseret/M
+Desi/M
+Desiree/M
+Desmond/M
+Detroit/M
+Deuteronomy/M
+Deutschmark/SM
+Dev/M
+Deva/M
+Devan/M
+Devanagari/M
+Devi/M
+Devil/M
+Devin/M
+Devlin/M
+Devon/M
+Devonian/M
+Dewar/M
+Dewayne/M
+Dewey/M
+Dewitt/M
+Dex/M
+Dexedrine/M
+Dexter/M
+Dhabi
+Dhaka/M
+Dhaulagiri/M
+Di/SM
+DiCaprio/M
+DiMaggio/M
+Diaghilev/M
+Dial/M
+Dian/M
+Diana/M
+Diane/M
+Diann/M
+Dianna/M
+Dianne/M
+Dias
+Diaspora/MS
+Dick/XM
+Dickens/M
+Dickensian
+Dickerson/M
+Dickie/M
+Dickinson/M
+Dickson/M
+Dicky/M
+Dictaphone/SM
+Diderot/M
+Didi/M
+Dido/M
+Didrikson/M
+Diefenbaker/M
+Diego/M
+Diem/M
+Dierdre/M
+Dieter/M
+Dietrich/M
+Digg/SM
+Dijkstra/M
+Dijon/M
+Dilbert/MS
+Dillard/M
+Dillinger/M
+Dillon/M
+Dimitri/M
+Dina/M
+Dinah/M
+Dinny/M
+Dino/M
+Diocletian/M
+Diogenes/M
+Dion/M
+Dione
+Dionisio/M
+Dionne/M
+Dionysian/M
+Dionysus/M
+Diophantine/M
+Dior/M
+Dipper/M
+Dir
+Dirac/M
+Dirichlet/M
+Dirk/M
+Dis/M
+Disney/M
+Disneyland/M
+Disraeli/M
+Dita/M
+DivX/M
+Divine/M
+Diwali/M
+Dix/M
+Dixie/M
+Dixiecrat/M
+Dixieland/SM
+Dixon/M
+Django/M
+Djibouti/M
+Dmitri/M
+Dnepr
+Dnepropetrovsk/M
+Dnieper/M
+Dniester/M
+Dobbin/M
+Doberman/M
+Dobro/M
+Doctor
+Doctorow/M
+Dodge/M
+Dodgson/M
+Dodi/M
+Dodie/M
+Dodoma/M
+Dodson/M
+Doe/M
+Doha/M
+Dolby/M
+Dole/M
+Dolf/M
+Dolley/M
+Dollie/M
+Dolly/M
+Dolores/M
+Dolph/M
+Dom
+Domenic/M
+Domenico/M
+Domesday/M
+Domingo/M
+Dominguez/M
+Domini/M
+Dominic/M
+Dominica/M
+Dominican/MS
+Dominick/M
+Dominik/M
+Dominion
+Dominique/M
+Domitian/M
+Don/SM
+Dona/M
+Donahue/M
+Donal/M
+Donald/M
+Donaldson/M
+Donatello/M
+Donetsk/M
+Donizetti/M
+Donn/MR
+Donna/M
+Donne/M
+Donnell/M
+Donner/M
+Donnie/M
+Donny/M
+Donovan/M
+Dooley/M
+Doolittle/M
+Doonesbury/M
+Doppler/M
+Dora/M
+Dorcas/M
+Dore/M
+Doreen/M
+Dorey/M
+Dori/SM
+Doria/M
+Dorian/M
+Doric/M
+Dorie/M
+Doris/M
+Dorise/M
+Doritos/M
+Doro/M
+Dorotea/M
+Dorothea/M
+Dorothee/M
+Dorothy/M
+Dorrie/M
+Dorris
+Dorset/M
+Dorsey/M
+Dorthy/M
+Dortmund/M
+Dosi/M
+Dostoevsky/M
+Dot/M
+Dothan/M
+Dotson/M
+Dottie/M
+Dotty's
+Douala/M
+Douay/M
+Doubleday/M
+Doug/M
+Dougie/M
+Douglas/M
+Douglass/M
+Douro/M
+Dov/MR
+Dover/M
+Dow/M
+Downs/M
+Downy/M
+Doy/M
+Doyle/M
+Dr
+Draco/M
+Draconian/M
+Dracula/M
+Drake/M
+Dramamine/SM
+Drambuie/M
+Drano/M
+Dravidian/M
+Dre/M
+Dreamweaver/M
+Dreiser/M
+Dresden/M
+Drew/M
+Dreyfus/M
+Dristan/M
+Drona/M
+Dropbox/M
+Dru/M
+Drudge/M
+Druid/M
+Drupal/M
+Drusilla/M
+Dryden/M
+Dschubba/M
+Du
+DuPont/M
+Duane/M
+Dubai/M
+Dubcek/M
+Dubhe/M
+Dublin/M
+Dubrovnik/M
+Dubuque/M
+Duchamp/M
+Dudley/M
+Duff/M
+Duffie/M
+Duffy/M
+Dugald/M
+Duisburg/M
+Duke/M
+Dulce/M
+Dulcie/M
+Dulcinea/M
+Dulles/M
+Duluth/M
+Dumas/M
+Dumbledore/M
+Dumbo/M
+Dunant/M
+Dunbar/M
+Duncan/M
+Dundee
+Dunedin/M
+Dunkirk/M
+Dunlap/M
+Dunn/M
+Dunne/M
+Dunstan
+Dur/R
+Duracell/M
+Duran/M
+Durand/M
+Durant/M
+Durante/M
+Durban/M
+Durer/M
+Durex/M
+Durham/MS
+Durkheim/M
+Duroc/M
+Durocher/M
+Durward/M
+Duse/M
+Dushanbe/M
+Dusseldorf/M
+Dustbuster/M
+Dustin/M
+Dusty/M
+Dutch/M
+Dutchman/M
+Dutchmen/M
+Dutchwoman
+Duvalier/M
+Dvina/M
+Dvorak/M
+Dvork/M
+Dwayne/M
+Dwight/M
+Dy/M
+Dyan/M
+Dyer/M
+Dylan/M
+Dyna/M
+DynamoDB/M
+Dyson/M
+Dzerzhinsky/M
+Dzungaria/M
+Drer/M
+Dsseldorf/M
+E/SMY
+EC
+ECG/M
+ECMAScript/M
+EDP/M
+EDT
+EEC/M
+EEG/M
+EEO
+EEOC
+EFL
+EFT
+EKG/M
+ELF/M
+EM
+EMT
+ENE/M
+EOE
+EPA/M
+ER
+ERA
+ESE/M
+ESL
+ESP/M
+ESPN/M
+ESR
+EST/M
+ET
+ETA
+ETD
+EU
+EULA/S
+Eadie/M
+Eakins/M
+Eal/M
+Eamon/M
+Earhart/M
+Earl/M
+Earle/M
+Earlene/M
+Earline/M
+Early's
+Earnest/M
+Earnestine/M
+Earnhardt/M
+Earp/M
+East/SZMR
+Easter/M
+Eastern/R
+Eastman/M
+Easton/M
+Eastwood/M
+Eaton/M
+Eb/MN
+Eba/M
+Ebba/M
+Eben/M
+Ebeneezer/M
+Ebenezer/M
+Eberhard/M
+Ebert/M
+Ebola/M
+Ebonics/M
+Ebony/M
+Ebro/M
+Ecclesiastes/M
+Ecma/M
+Eco/M
+Ecstasy
+Ecuador/M
+Ecuadoran/SM
+Ecuadorean
+Ecuadorian/SM
+Ed/MNX
+Eda/M
+Edam/SM
+Edd/M
+Edda/M
+Eddie/M
+Eddington/M
+Eddy/M
+Ede
+Eden/M
+Edgar/M
+Edgard/M
+Edgardo/M
+Edi/MH
+Edie/M
+Edin/M
+Edinburgh/M
+Edison/M
+Edith/M
+Editha/M
+Edlin/M
+Edmond/M
+Edmonton/M
+Edmund/M
+Edna/M
+Edouard/M
+Edsel/M
+Eduard/M
+Eduardo/M
+Edvard/M
+Edward/SM
+Edwardian/M
+Edwardo/M
+Edwards/M
+Edwin/M
+Edwina/M
+Edy/M
+Edythe/M
+Eeyore/M
+Effie/M
+Efrain/M
+Efrem/M
+Efren/M
+Egan/M
+Egbert
+Eggo/M
+Egon/M
+Egor/M
+Egypt/M
+Egyptian/MS
+Egyptology/M
+Ehrenberg/M
+Ehrlich/M
+Eichmann/M
+Eiffel/M
+Eileen/M
+Einstein/MS
+Einsteinian/M
+Eire/M
+Eisenhower/M
+Eisenstein/M
+Eisner/M
+Ekaterina/M
+El/Y
+Elaina/M
+Elaine/M
+Elam/M
+Elana/M
+Elanor/M
+Elasticsearch/M
+Elastoplast/M
+Elayne/M
+Elba/M
+Elbe/M
+Elbert/M
+Elbrus/M
+Elden/M
+Eldersburg/M
+Eldin/M
+Eldon/M
+Eldredge/M
+Eldridge/M
+Eleanor/M
+Eleanora/M
+Eleanore/M
+Eleazar/M
+Electra/M
+Elena/M
+Elene/M
+Eleni/M
+Eleonora/M
+Eleonore/M
+Elfreda/M
+Elfrida/M
+Elgar/M
+Eli/M
+Elia/S
+Elias/M
+Elie/M
+Elihu/M
+Elijah/M
+Elinor/M
+Eliot/M
+Elisa/M
+Elisabet/M
+Elisabeth/M
+Elisabetta/M
+Elise/M
+Eliseo/M
+Elisha/M
+Elissa/M
+Eliza/M
+Elizabeth/M
+Elizabethan/SM
+Elizabethtown/M
+Elke/M
+Elkhart/M
+Ella/M
+Elle/M
+Ellen/M
+Ellery/M
+Ellesmere/M
+Elli/SM
+Ellie/M
+Ellington/M
+Elliot/M
+Elliott/M
+Ellis/M
+Ellison/M
+Ellsworth/M
+Ellwood/M
+Elly/M
+Ellyn/M
+Elma/M
+Elmer/M
+Elmira/M
+Elmo/M
+Elmore/M
+Elnath/M
+Elnora/M
+Elohim/M
+Eloisa/M
+Eloise/M
+Eloy/M
+Elroy/M
+Elsa/M
+Elsbeth/M
+Else's
+Elsevier/M
+Elsey/M
+Elsie/M
+Elsinore/M
+Elspeth/M
+Elston/M
+Eltanin/M
+Elton/M
+Elul/M
+Elva/M
+Elvia/M
+Elvin/M
+Elvira/M
+Elvis/M
+Elway/M
+Elwin/M
+Elwood/M
+Elwyn/M
+Elyria/M
+Elyse/M
+Elysee/M
+Elysian/M
+Elysium/SM
+Elyssa/M
+Elyse/M
+Ema/M
+Emacs/M
+Emanuel/M
+Emanuele/M
+Emeline/M
+Emerson/M
+Emery/M
+Emeryville/M
+Emil/M
+Emile/M
+Emilia/M
+Emilie/M
+Emilio/M
+Emily/M
+Eminem/M
+Eminence
+Emlen/M
+Emlyn/M
+Emma/M
+Emmaline/M
+Emmanuel/M
+Emmeline/M
+Emmerich/M
+Emmet/M
+Emmett/M
+Emmie/M
+Emmy/M
+Emory/M
+Encarta/M
+EndNote/M
+Endymion/M
+Eng/M
+Engelbert/M
+Engels/M
+England/M
+English/MRS
+Englishman/M
+Englishmen/M
+Englishwoman/M
+Englishwomen/M
+Enid/M
+Enif/M
+Eniwetok/M
+Enkidu/M
+Ennis
+Enoch/M
+Enos/M
+Enrica/M
+Enrico/M
+Enrique/M
+Enron/M
+Enterprise/M
+Eocene/M
+Epcot/M
+Ephesian/MS
+Ephesus/M
+Ephraim/M
+Ephrem/M
+Epictetus/M
+Epicurean/M
+Epicurus/M
+Epimethius/M
+Epiphany/SM
+Episcopal
+Episcopalian/MS
+Epistle
+Epsom/M
+Epson/M
+Epstein/M
+Equuleus/M
+Er/M
+Eran/M
+Erasmus/M
+Erastus/M
+Erato/M
+Eratosthenes/M
+Erda/M
+Erebus/M
+Erector/M
+Erewhon/M
+Erhard/M
+Eric/M
+Erica/M
+Erich/M
+Erick/M
+Ericka/M
+Erickson/M
+Ericson/M
+Ericsson/M
+Eridanus/M
+Erie/M
+Erik/M
+Erika/M
+Erin/M
+Eris/MS
+Eritrea/M
+Eritrean/SM
+Erl/M
+Erlang/M
+Erlenmeyer/M
+Erma/M
+Erna/M
+Ernest/M
+Ernestine/M
+Ernesto/M
+Ernie/M
+Ernst/M
+Eros/MS
+Errol/M
+Erroll/M
+Erse/M
+Erskine
+Erv/M
+ErvIn/M
+Erwin/M
+Esau/M
+Escher/M
+Escherichia/M
+Escondido
+Esdras
+Eskimo/MS
+Esme/M
+Esmeralda/M
+Esperanto/M
+Esperanza/M
+Espinoza/M
+Esq/M
+Esquire/MS
+Essa/M
+Essen/M
+Essene/M
+Essequibo/M
+Essex/M
+Essie/M
+Esta/M
+Establishment
+Esteban/M
+Estela/M
+Estella/M
+Estelle/M
+Ester/M
+Esterhazy/M
+Esterhzy/M
+Estes/M
+Estevan/M
+Esther/M
+Estonia/M
+Estonian/SM
+Estrada/M
+Estrella/M
+Ethan/M
+Ethel/M
+Ethelbert
+Ethelred/M
+Ethelyn/M
+Ethernet/M
+Ethiopia/M
+Ethiopian/SM
+Etienne/M
+Etna/M
+Eton/M
+Etruria/M
+Etruscan/M
+Etta/M
+Ettie/M
+Ettore/M
+Etty/M
+Eu/M
+Eucharist/MS
+Eucharistic
+Euclid/M
+Euclidean/M
+Eudora/M
+Eugen/M
+Eugene/M
+Eugenia/M
+Eugenie/M
+Eugenio/M
+Eugenius/M
+Eula/M
+Eulalie/M
+Euler/M
+Eumenides/M
+Eunice/M
+Euphemia/M
+Euphrates/M
+Eur
+Eurasia/M
+Eurasian/MS
+Euripides/M
+Eurodollar/SM
+Europa/M
+Europaea/M
+Europe/M
+European/MS
+Eurydice/M
+Eustace/M
+Eustachian/M
+Eustacia/M
+Eustis/M
+Euterpe/M
+Ev/M
+Eva/M
+Evan/SM
+Evangelical
+Evangelina/M
+Evangeline/M
+Evangelist/M
+Evans/M
+Evansville/M
+Eve/M
+Evelina/M
+Eveline/M
+Evelyn/M
+Evenki/M
+EverReady/M
+Everard/M
+Everest/M
+Everett/M
+Everette/M
+Everglades/M
+Evert/M
+Evey/M
+Evian/M
+Evie/M
+Evin/M
+Evita/M
+Evy/M
+Ewan/M
+Ewart/M
+Ewell/M
+Ewen/M
+Ewing/M
+Excalibur/M
+Excedrin/M
+Excellency/SM
+Exchequer
+Exercycle/M
+Exocet/M
+Exodus/M
+Expedia/M
+Exxon/M
+Eyck/M
+Eyre/M
+Eysenck/M
+Ezekiel/M
+Ezequiel/M
+Ezra/M
+F/MD
+FAA
+FAQ/SM
+FBI/M
+FCC
+FD
+FDA
+FDIC/M
+FDR/M
+FHA/M
+FICA/M
+FIFO
+FL
+FM/SM
+FNMA/M
+FOFL
+FORTRAN/M
+FPO
+FSF/M
+FSLIC
+FTC
+FTM/SM
+FUD/S
+FWD
+FWIW
+FY
+FYI
+Faber/M
+Faberge/M
+Faberg/M
+Fabian/MS
+Fabien/M
+Fabio/M
+Facebook/M
+Fae/M
+Faeroe/M
+Fafnir/M
+Fagin/M
+Fahd/M
+Fahrenheit/M
+Fairbanks/M
+Fairfax
+Fairfield/M
+Fairhope/M
+Fairleigh/M
+Fairlie/M
+Faisal/M
+Faisalabad/M
+Faith/M
+Fajardo/M
+Falasha/M
+Falkland/SM
+Falklands/M
+Falkner
+Fallon/M
+Fallopian/M
+Falstaff/M
+Falwell/M
+Fania/M
+Fannie/M
+Fanny/M
+Far's
+Fara/M
+Faraday/M
+Farah/M
+Fargo/M
+Farley/M
+Farmer/M
+Farmington/M
+Farr/M
+Farragut/M
+Farrah/M
+Farrakhan/M
+Farrand/M
+Farrel/M
+Farrell/M
+Farris/M
+Farrow/M
+Farsi/M
+Fascist
+Faso/M
+Fassbinder/M
+Fatah/M
+Fates/M
+Father/SM
+Fatima/M
+Fatimid/M
+Faulkner/M
+Faulknerian/M
+Fauntleroy/M
+Faust/M
+Faustian/M
+Faustina/M
+Faustino/M
+Faustus/M
+Fawkes/M
+Fay/M
+Faye/M
+Fayette/M
+Fayetteville/M
+Fayre/M
+Fe/M
+Feb/M
+February/SM
+Fed/SM
+FedEx/M
+Federal/MS
+Federalist/M
+Federico/M
+Feds/M
+Felecia/M
+Felice/M
+Felicia/M
+Felicity/M
+Feliks/M
+Felipe/M
+Felix/M
+Fellini/M
+Feng/M
+Fenian/M
+Fenix/M
+Fennec/M
+Feodor/M
+Ferber/M
+Ferd/M
+Ferdie/M
+Ferdinand/M
+Ferdy/M
+Fergus/M
+Ferguson/M
+Ferlinghetti/M
+Fermat/M
+Fermi/M
+Fern/M
+Fernanda/M
+Fernande/M
+Fernandez/M
+Fernandina/M
+Fernando/M
+Ferne/M
+Ferrari/M
+Ferraro/M
+Ferrel/M
+Ferrell/M
+Ferris/M
+Fey's
+Feynman/M
+Fez/M
+Fianna
+Fiat/M
+Fiberglas/M
+Fibonacci/M
+Fichte/M
+Fidel/M
+Fidelia/M
+Fidelio/M
+Fido/M
+Fielding/M
+Fields/M
+Fifi/M
+Figaro/M
+Figueroa/M
+Fiji/M
+Fijian/MS
+Filip/M
+Filipino/MS
+Filippo/M
+Fillmore/M
+FilmSpot/M
+Filmer/M
+Filofax/M
+Fina/M
+Finch/M
+FindArticles/M
+FindLaw/M
+Findlay/M
+Findley/M
+Finland/M
+Finlay/M
+Finley/M
+Finn/SM
+Finnbogadottir/M
+Finnegan/M
+Finnish/M
+Fiona/M
+Firebase/M
+Firefox/M
+Firestone/M
+Fischer/M
+Fisher/M
+Fisk/M
+Fitch/M
+Fitchburg/M
+Fitz/M
+Fitzgerald/M
+Fitzpatrick/M
+Fitzroy/M
+Fizeau/M
+Fla
+Flagstaff/M
+Flanagan/M
+Flanders/M
+Flathead
+Flatt/M
+Flaubert/M
+Fleischer/M
+Flem/G
+Fleming/M
+Flemish/M
+Flemming/M
+Fletch/MR
+Fletcher/M
+Fleur/M
+Flickr/M
+Flin/M
+Flinn/M
+Flint/M
+Flintstones/M
+Flo/M
+Flor/M
+Flora/M
+Flore/SM
+Florence/M
+Florencia/M
+Florentine/M
+Flores/M
+Florette/M
+Florian/M
+Florida/M
+Floridan/M
+Floridian/SM
+Florinda/M
+Florine/M
+Floris
+Florrie/M
+Florsheim/M
+Flory/M
+Flossie/M
+Flossy's
+Flowers/M
+Floyd/M
+Flynn/M
+Fm/M
+Foch/M
+Fokker/M
+Foley/M
+Folgers/M
+Folsom/M
+Fomalhaut/M
+Fonda/M
+Fons
+Foosball/M
+Forbes/M
+Ford/M
+Foreman/M
+Forest/MR
+Forester/M
+Forex/M
+Formica/MS
+Formosa/M
+Formosan/M
+Forrest/MR
+Forrester/M
+Forster/M
+Fortaleza/M
+Fortran
+Foss/M
+Fosse/M
+Foster/M
+Fotomat/M
+Foucault/M
+Fourier/M
+Fourneyron/M
+Fourth
+Fowler/M
+Fox/MS
+Fr/MD
+Fragonard/M
+Fran/SM
+France/SM
+Frances/M
+Francesca/M
+Francesco/M
+Francine/M
+Francis/M
+Francisca/M
+Franciscan/MS
+Francisco/M
+Franck/M
+Franco/M
+Francois/M
+Francoise/M
+Francophile
+Franglais/M
+Frank/SM
+Frankel/M
+Frankenstein/M
+Frankfort/M
+Frankfurt/MR
+Frankfurter/M
+Frankie/M
+Frankish
+Franklin/M
+Franklyn/M
+Franks/M
+Franky/M
+Frannie/M
+Franny/M
+Fransisco/M
+Franz/MN
+Franzen/M
+Fraser/M
+Frasier/M
+Frau/MN
+Fraulein
+Frazer
+Frazier/M
+Fred/M
+Freda/M
+Freddie/M
+Freddy/M
+Frederic/M
+Frederica/M
+Frederich/M
+Frederick/M
+Fredericksburg/M
+Frederico/M
+Fredericton/M
+Frederik/M
+Frederique/M
+Fredric/M
+Fredrick/M
+Fredrika/M
+Free's
+FreeBSD/M
+Freeland/M
+Freeman/M
+Freemason/SM
+Freemasonry/SM
+Freetown/M
+Freida/M
+Fremont/M
+French/MS
+Frenchman/M
+Frenchmen/M
+Frenchwoman/M
+Frenchwomen/M
+Freon/M
+Fresnel/M
+Fresno/M
+Freud/M
+Freudian/M
+Frey/M
+Freya/M
+Fri/M
+Friday/SM
+Frieda/M
+Friedan/M
+Friederike/M
+Friedman/M
+Friedmann/M
+Friedrich
+Friend/SM
+Frigga/M
+Frigidaire/M
+Frisbee/M
+Frisco/M
+Frisian/MS
+Frito/M
+Fritz/M
+Friulian/M
+Frobisher/M
+Frodo/M
+Froissart/M
+Fromm/M
+Fronde/M
+FrontPage/M
+Frontenac/M
+Frost/M
+Frostbelt/M
+Frunze/M
+Fry/M
+Frye/M
+Fuchs/M
+Fuentes/M
+Fugger/M
+Fuji/M
+Fujian/M
+Fujitsu/M
+Fujiwara/M
+Fujiyama/M
+Fukuoka/M
+Fukushima/M
+Fukuyama/M
+Fulani/M
+Fulbright/M
+Fuller/M
+Fullerton/M
+Fulton/M
+Fulvia/M
+Funafuti/M
+Fundy/M
+Furies/M
+Furman/M
+Furtwangler/M
+Furtwngler/M
+Fushun/M
+Fuzhou/M
+Fuzzbuster/M
+G/MNRB
+GA
+GAO
+GATT/M
+GB/M
+GCC/M
+GDP/M
+GDPR
+GE/M
+GED
+GHQ/M
+GHz/M
+GI
+GIF
+GIGO
+GM/M
+GMAT
+GMO
+GMT/M
+GNP/M
+GNU/M
+GOP/M
+GP/M
+GPA
+GPO
+GPS
+GPU
+GSA
+GTE/M
+GU
+GUI/M
+Ga/M
+GaAs
+Gabby/M
+Gabe/M
+Gabi/M
+Gable/M
+Gabon/M
+Gabonese/M
+Gaborone/M
+Gabriel/M
+Gabriela/M
+Gabriele/M
+Gabriella/M
+Gabrielle/M
+Gaby/M
+Gacrux/M
+Gadsden/M
+Gae/M
+Gaea/M
+Gael/SM
+Gaelic/M
+Gagarin/M
+Gage/M
+Gaia/M
+Gail/M
+Gaiman/M
+Gaines/M
+Gainesville/M
+Gainsborough/M
+Galahad/SM
+Galapagos/M
+Galatea/M
+Galatia/M
+Galatians/M
+Galaxy
+Galbraith/M
+Gale/M
+Galen/M
+Galibi/M
+Galilean/SM
+Galilee/M
+Galileo/M
+Galina/M
+Gall/M
+Gallagher/M
+Gallegos/M
+Gallic/M
+Gallicism/SM
+Gallo/M
+Galloway/M
+Gallup/M
+Galois/M
+Galsworthy/M
+Galvan/M
+Galvani/M
+Galveston/M
+Galvin/M
+Gama
+Gamaliel/M
+Gamay/M
+Gambia/M
+Gambian/SM
+Gamble/M
+GameCube/M
+GameFAQs/M
+GameSpot/M
+Gamow/M
+Gan/M
+Gandalf/M
+Gandhi/M
+Gandhian/M
+Ganesha/M
+Ganges/M
+Gangtok/M
+Gannon/M
+Gansu/M
+Gantry/M
+Ganymede/M
+Gap/M
+Garamond
+Garbo/M
+Garcia/M
+Gard
+Gardiner
+Gardner/M
+Gare/MH
+Gareth/M
+Garey/M
+Garfield/M
+Garfunkel/M
+Gargantua/M
+Garibaldi/M
+Garland/M
+Garner/M
+Garrard/M
+Garrett/M
+Garrick/M
+Garrison/M
+Garry/M
+Garth/M
+Garvey/M
+Garvin/M
+Garwood/M
+Gary/M
+Garza/M
+Gascony/M
+Gaspar
+Gaspard/M
+Gasparo/M
+Gasper/M
+Gasser/M
+Gaston/M
+Gastonia/M
+Gastroenterology
+Gates/M
+Gatling/M
+Gatorade/M
+Gatsby/M
+Gatun/M
+Gauguin/M
+Gaul/SM
+Gaulish
+Gauss/M
+Gaussian/M
+Gautama/M
+Gauthier/M
+Gautier/M
+Gav/MN
+Gavan/M
+Gaven/M
+Gavin/M
+Gawain/M
+Gay/M
+Gaye/M
+Gayle/M
+Gaylord/M
+Gaynor/M
+Gaza/M
+Gaziantep/M
+Gbps
+Gd/M
+Gdansk/M
+Ge/M
+Gecko/M
+Geffen/M
+Gehenna/M
+Gehrig/M
+Geiger/M
+Gelbvieh/M
+Geller/M
+Gemini/MS
+Gen/M
+GenBank/M
+Gena/M
+Genaro/M
+Gene/M
+Genesis/M
+Genet/M
+Geneva/M
+Genevieve/M
+Genevra/M
+Genghis/M
+Genia/M
+Genna/M
+Genny/M
+Geno/M
+Genoa/SM
+Gentoo/M
+Gentry/M
+Geo/M
+Geoff/M
+Geoffrey/M
+Geordie
+Georg/M
+George/MS
+Georgetown/M
+Georgette/M
+Georgi/M
+Georgia/M
+Georgian/MS
+Georgiana/M
+Georgianna/M
+Georgie/M
+Georgina/M
+Georgy/M
+Ger/M
+Gerald/M
+Geraldine/M
+Gerard/M
+Gerardo/M
+Gerber/M
+Gerda/M
+Gere/M
+Gerhard/M
+Gerhardt/M
+Geri/M
+Geritol/M
+Germain/M
+Germaine/M
+German/MS
+Germanic/M
+Germany/M
+Gerome/M
+Geronimo/M
+Gerrard/M
+Gerri/M
+Gerry/M
+Gershwin/M
+Gert/M
+Gertie/M
+Gertrud/M
+Gertrude/M
+Gertrudis/M
+Gerty/M
+Gery/M
+Gestapo/SM
+Gethsemane/M
+Getty/M
+Gettysburg/M
+Gewurztraminer/M
+Gewrztraminer/M
+Ghana/M
+Ghanaian
+Ghats/M
+Ghazvanid/M
+Ghent/M
+Ghibelline/M
+Giacometti/M
+Giacomo/M
+Gian/M
+Gianna/M
+Gianni/M
+Giannini/M
+Giauque/M
+Gib/M
+Gibb/SM
+Gibbon/M
+Gibbs/M
+Gibraltar/MS
+Gibson/M
+Gide/M
+Gideon/M
+Gielgud/M
+Gienah/M
+Giff/M
+Giffard/M
+Gifford/M
+Gigi/M
+Gil/MY
+Gila/M
+Gilbert/M
+Gilberte/M
+Gilberto/M
+Gilchrist/M
+Gilda/M
+Gilead/M
+Giles/M
+Gilgamesh/M
+Gill/M
+Gillan/M
+Gilles
+Gillespie/M
+Gillette/M
+Gilliam/M
+Gillian/M
+Gillie's
+Gilligan/M
+Gilly/M
+Gilman
+Gilmore/M
+Gilroy/M
+Gina/M
+Ginevra/M
+Ginger/M
+Gingrich/M
+Ginnie/M
+Ginny/M
+Gino/M
+Ginsberg/M
+Ginsburg/M
+Ginsu/M
+Giordano/M
+Giorgi/M
+Giorgio/M
+Giorgione/M
+Giotto/M
+Giovanna/M
+Giovanni/M
+Giraud
+Giraudoux/M
+Gisela/M
+Gisele/M
+Giselle/M
+Gish/M
+GitHub/M
+Giulia/M
+Giuliani/M
+Giulietta/M
+Giulio/M
+Giuseppe/M
+Giusto/M
+Giza/M
+Gk
+Gladstone/MS
+Gladys/M
+Glaser/M
+Glasgow/M
+Glass/M
+Glastonbury/M
+Glaswegian/SM
+Glaxo/M
+Gleason/M
+Glen/M
+Glenda/M
+Glendale
+Glendon/M
+Glenlivet/M
+Glenn/M
+Glenna/M
+Glennie/M
+Gloria/M
+Gloriana/M
+Gloucester/M
+Gloucestershire/M
+Glover/M
+Glyn/M
+Glynis/M
+Glynn/M
+GmbH
+Gnostic/M
+Gnosticism/M
+GnuPG
+Goa/M
+Gobi/M
+God/M
+Godard/M
+Goddard/M
+Godel/M
+Godfrey/M
+Godhead/M
+Godiva/M
+Godot/M
+Godspeed/SM
+Godthaab/M
+Godunov/M
+Godwin
+Godzilla/M
+Goebbels/M
+Goering/M
+Goethals/M
+Goethe/M
+Goff/M
+Gog/M
+Gogol/M
+Goiania/M
+Golan/M
+Golconda/M
+Golda/M
+Goldberg/M
+Golden/M
+Goldie/M
+Goldilocks/M
+Golding/M
+Goldman/M
+Goldsboro/M
+Goldsmith/M
+Goldwater/M
+Goldwyn/M
+Goldy/M
+Golgi/M
+Golgotha/M
+Goliath/M
+Gomez/M
+Gomorrah/M
+Gompers/M
+Gomulka/M
+Gondwanaland/M
+Gonzales/M
+Gonzalez/M
+Gonzalo/M
+Good/M
+Goodall/M
+Goode/M
+Goodman/M
+Goodrich/M
+Goodwill/M
+Goodwin/M
+Goodyear/M
+Google/M
+Goolagong/M
+Gopher
+Goran/M
+Gorbachev/M
+Gordan/M
+Gorden/M
+Gordian/M
+Gordie/M
+Gordimer/M
+Gordon/M
+Gordy/M
+Gore/M
+Goren/M
+Gorey/M
+Gorgas/M
+Gorgon/M
+Gorgonzola/M
+Gorky/M
+Gospel/MS
+Goteborg/M
+Goth/M
+Gotham/M
+Gothic/MS
+Goths
+Gottfried/M
+Gouda/SM
+Gould/M
+Gounod/M
+Governor
+Goya/M
+Gr/B
+Grable/M
+Gracchus/M
+Grace/M
+Graceland/M
+Gracia/M
+Gracie/M
+Graciela/M
+Grady/M
+Graeme/M
+Graffias/M
+Grafton/M
+Graham/M
+Grahame/M
+Grail/M
+Grammy/M
+Grampians/M
+Gran's
+Granada/M
+Grange/R
+Grannie/M
+Grant/M
+Grantham/M
+Grantley/M
+Granville/M
+Grass/M
+Grata/M
+Gratia/M
+Graves/M
+Gray/M
+Grayslake/M
+Grazia/M
+Grecian/M
+Greece/M
+Greek/SM
+Greeley/M
+Green/SM
+Greene/M
+Greenland/M
+Greenlandic
+Greenpeace/M
+Greensboro/M
+Greensleeves/M
+Greenspan/M
+Greenville/M
+Greenwich/M
+Greer/M
+Greg/M
+Gregg/M
+Gregoire/M
+Gregor/M
+Gregorian/M
+Gregorio/M
+Gregorius/M
+Gregory/M
+Grenada/M
+Grenadian/MS
+Grenadines/M
+Grendel/M
+Grenoble/M
+Grenville
+Gresham/M
+Greta/M
+Gretchen/M
+Grete/M
+Gretel/M
+Gretna/M
+Gretta/M
+Gretzky/M
+Grey/M
+Grieg/M
+Grier/M
+Griff/M
+Griffin/M
+Griffith/M
+Griffiths
+Grimes/M
+Grimm/M
+Grinch/M
+Gris/M
+Griselda
+Griswold/M
+Gromyko/M
+Gropius/M
+Gross/M
+Grosz/M
+Grotius/M
+Grover/M
+Grozny
+Grumman/M
+Grundy/M
+Grunewald/M
+Grus/M
+Gruyere/SM
+Gruyre/M
+Grnewald/M
+Guadalajara/M
+Guadalcanal/M
+Guadalquivir/M
+Guadalupe/M
+Guadeloupe/M
+Guallatiri/M
+Guam/M
+Guamanian
+Guangdong/M
+Guangzhou/M
+Guantanamo/M
+Guarani/M
+Guarnieri/M
+Guatemala/M
+Guatemalan/MS
+Guayama/M
+Guayaquil/M
+Gucci/M
+Guelph/M
+Guenevere/M
+Guernsey/MS
+Guerra/M
+Guerrero/M
+Guevara/M
+Guggenheim/M
+Guglielmo/M
+Gui/M
+Guiana/M
+Guido/M
+Guilbert/M
+Guildford/M
+Guillaume/M
+Guillermo/M
+Guinea/M
+Guinean/MS
+Guinevere/M
+Guinness/M
+Guiyang/M
+Guizhou/M
+Guizot/M
+Gujarat/M
+Gujarati/M
+Gujranwala/M
+Gulfport/M
+Gullah/M
+Gulliver/M
+Gumbel/M
+Gunilla/M
+Gunter
+Gunther/M
+Guofeng/M
+Gupta/M
+Gurkha/M
+Gus/M
+Gussie/M
+Gussy's
+Gusta/M
+Gustaf/M
+Gustav/M
+Gustave/M
+Gustavo/M
+Gustavus/M
+Gusti/M
+Gusty's
+Gutenberg/M
+Guthrie/M
+Gutierrez/M
+Guy/M
+Guyana/M
+Guyanese/M
+Guzman/M
+Gwalior/M
+Gwen/M
+Gwendolen/M
+Gwendoline/M
+Gwendolyn/M
+Gwyn/M
+Gwyneth/M
+Gwynne/M
+Gypsy/SM
+Gdel/M
+Gteborg/M
+H/M
+HBO/M
+HBase/M
+HDD
+HDMI
+HDTV
+HF/M
+HHS
+HI
+HIV/M
+HM
+HMO/M
+HMS
+HOV
+HP/M
+HPV
+HQ/M
+HR
+HRH
+HS
+HSBC/M
+HST
+HT
+HTML/M
+HTTP
+HTTPS
+HUD/M
+HVAC
+Ha/M
+Haas/M
+Habakkuk/M
+Haber/M
+Had's
+Hadar/M
+Hades/M
+Hadleigh/M
+Hadley/M
+Hadoop/M
+Hadria/M
+Hadrian/M
+Hafiz/M
+Hagan/M
+Hagar/M
+Hagen
+Hagerstown/M
+Haggai/M
+Hagiographa/M
+Hague/M
+Hahn/M
+Haida/SM
+Haifa/M
+Hailey/M
+Hainan/M
+Haiphong/M
+Haiti/M
+Haitian/MS
+Hakeem/M
+Hakim/M
+Hakka/M
+Hakluyt/M
+Hal/SMY
+Haldane/M
+Hale/M
+Haleakala/M
+Haley/M
+Hali/M
+Halifax/M
+Hall/M
+Halley/M
+Halliburton/M
+Hallie/M
+Hallmark/M
+Halloween/MS
+Hallstatt/M
+Hally/M
+Halon/M
+Hals/M
+Halsey/M
+Ham/M
+Haman/M
+Hamas/M
+Hamburg/MS
+Hamel/M
+Hamhung/M
+Hamid/M
+Hamil/M
+Hamilcar/M
+Hamill/M
+Hamilton/M
+Hamiltonian/M
+Hamish/M
+Hamitic/M
+Hamlet/M
+Hamlin/M
+Hammad/M
+Hammarskjold/M
+Hammerstein/M
+Hammett/M
+Hammond/M
+Hammurabi/M
+Hampshire/M
+Hampton/M
+Hamsun/M
+Han/SM
+Hana/M
+Hanan/M
+Hancock/M
+Handel/M
+Handy/M
+Haney/M
+Hanford/M
+Hangul/M
+Hangzhou/M
+Hank/M
+Hanna/M
+Hannah/M
+Hanni/M
+Hannibal/M
+Hanoi/M
+Hanover/M
+Hanoverian/M
+Hans/MN
+Hansel/M
+Hansen/M
+Hanson/M
+Hanuka
+Hanukah/M
+Hanukkah/M
+Hanukkahs
+Happy's
+Hapsburg/M
+Harald/M
+Harare/M
+Harbert/M
+Harbin/M
+Harcourt/M
+Hardin/M
+Harding/M
+Hardy/M
+Hargreaves/M
+Harlan/M
+Harland/M
+Harlem/M
+Harlequin/M
+Harley/M
+Harlin/M
+Harlingen/M
+Harlow/M
+Harman/M
+Harmon/M
+Harmonia/M
+Harmonie/M
+Harold/M
+Haroun/M
+Harper/M
+Harpy/SM
+Harrell/M
+Harri/SM
+Harriet/M
+Harriett/M
+Harriette/M
+Harrington/M
+Harriot/M
+Harriott/M
+Harris/M
+Harrisburg/M
+Harrison/M
+Harrisonburg/M
+Harrods/M
+Harry/M
+Hart/M
+Harte/M
+Hartford/M
+Hartley
+Hartline/M
+Hartman/M
+Hartwell/M
+Harv/M
+Harvard/M
+Harvey/M
+Harwell/M
+Hasbro/M
+Hashim/M
+Hasidim/M
+Haskell/M
+Haslett/M
+Hassan/M
+Hastie/M
+Hastings/M
+Hasty's
+Hatfield/M
+Hathaway/M
+Hatsheput/M
+Hatteras/M
+Hatti/M
+Hattie/M
+Hattiesburg/M
+Hatty/M
+Hauptmann/M
+Hausa/M
+Hausdorff/M
+Havana/MS
+Havarti/M
+Havel/M
+Havoline/M
+Haw
+Hawaii/M
+Hawaiian/SM
+Hawking/M
+Hawkins/M
+Hawks
+Hawthorne/M
+Hay/SM
+Hayden/M
+Haydn/M
+Haydon/M
+Hayek/M
+Hayes/M
+Hayley/M
+Haynes/M
+Hays/M
+Hayward/M
+Haywood/M
+Hayworth/M
+Hayyim/M
+Hazel/M
+Hazleton/M
+Hazlett/M
+Hazlitt/M
+He/M
+Head/M
+Hearst/M
+Heath/MR
+Heather/M
+Heaviside/M
+Heb
+Hebe/M
+Hebei/M
+Hebert/M
+Hebraic/M
+Hebraism/SM
+Hebrew/MS
+Hebrews/M
+Hebrides/M
+Hecate/M
+Hector/M
+Hecuba/M
+Hedda/M
+Hedi/M
+Hedwig/M
+Hedy/M
+Heep/M
+Hefner/M
+Hegel/M
+Hegelian/M
+Hegira/M
+Heidegger/M
+Heidelberg/M
+Heidi/M
+Heifetz/M
+Heilongjiang/M
+Heimlich/M
+Heine/M
+Heineken/M
+Heinlein/M
+Heinrich/M
+Heinz/M
+Heisenberg/M
+Heisman/M
+Hejira's
+Helaina/M
+Helen/M
+Helena/M
+Helene/M
+Helga/M
+Helge/M
+Helicobacter
+Helicon/M
+Heliopolis/M
+Helios/M
+Hellene/SM
+Hellenic/M
+Hellenism/MS
+Hellenist
+Hellenistic/M
+Hellenization/M
+Hellenize/MD
+Heller/M
+Hellespont/M
+Hellman/M
+Helmholtz/M
+Heloise/M
+Helsinki/M
+Helvetian
+Helvetica
+Helvetius/M
+Hemet/M
+Hemingway/M
+Henan/M
+Hench/M
+Henderson/M
+Hendrick/MS
+Hendricks/M
+Hendrik/M
+Hendrix/M
+Henley/M
+Hennessy/M
+Henri/M
+Henrietta/M
+Henriette/M
+Henrik/M
+Henry/M
+Hensley/M
+Henson/M
+Hepburn/M
+Hephaestus/M
+Hephzibah/M
+Hepplewhite/M
+Hera/M
+Heracles/M
+Heraclitus/M
+Herakles/M
+Herbart/M
+Herbert/M
+Herbie/M
+Herby/M
+Herc/M
+Herculaneum/M
+Hercule/MS
+Herculean
+Hercules/M
+Herder/M
+Hereford/SM
+Herero/M
+Heriberto/M
+Herman/M
+Hermann/M
+Hermaphroditus/M
+Hermes/M
+Hermia/M
+Hermine/M
+Herminia/M
+Hermione/M
+Hermitage/M
+Hermite/M
+Hermon
+Hermosillo/M
+Hernandez/M
+Hernando/M
+Herod/M
+Herodotus/M
+Heroku/M
+Herold/M
+Herr/MG
+Herrera/M
+Herrick/M
+Herring/M
+Hersch/M
+Herschel/M
+Hersey/M
+Hersh/M
+Hershel/M
+Hershey/M
+Herta/M
+Hertfordshire/M
+Hertha/M
+Hertz/M
+Hertzsprung/M
+Herve/M
+Hervey/M
+Herzegovina/M
+Herzl/M
+Heshvan/M
+Hesiod/M
+Hesperia/M
+Hesperus/M
+Hess/M
+Hesse/M
+Hessian/M
+Hester/M
+Hestia/M
+Heston/M
+Hettie/M
+Hetty/M
+Hew's
+Hewett/M
+Hewitt/M
+Hewlett/M
+Heyerdahl/M
+Heywood/M
+Hezbollah/M
+Hezekiah/M
+Hf/M
+Hg/M
+Hi's
+Hialeah/M
+Hiawatha/M
+Hibernia/M
+Hibernian
+Hickman/M
+Hickok/M
+Hickory/M
+Hicks/M
+Hieronymus/M
+Higashiosaka
+Higgins/M
+Highlander/SM
+Highlands
+Highness/M
+Hightstown/M
+Hilario/M
+Hilary/M
+Hilbert/M
+Hilda/M
+Hilde/M
+Hildebrand/M
+Hildegarde/M
+Hildy/M
+Hilfiger/M
+Hill/M
+Hillard/M
+Hillary/M
+Hillel/M
+Hillery/M
+Hilliard
+Hillier/M
+Hillsborough/M
+Hilly's
+Hillyer/M
+Hilton/M
+Himalaya/SM
+Himalayan
+Himalayas/M
+Himmler/M
+Hinayana/M
+Hindemith/M
+Hindenburg/M
+Hindi/M
+Hindu/SM
+Hinduism/SM
+Hindustan/M
+Hindustani/SM
+Hines/M
+Hinesville/M
+Hinton/M
+Hinze/M
+Hipparchus/M
+Hippocrates/M
+Hippocratic/M
+Hiram/M
+Hirobumi/M
+Hirohito/M
+Hiroshima/M
+Hirsch/M
+Hispanic/SM
+Hispanica/M
+Hispaniola/M
+Hiss/M
+Hitachi/M
+Hitchcock/M
+Hitler/MS
+Hittite/SM
+Hmong/M
+Ho/M
+Hobart/M
+Hobbes/M
+Hobbs/M
+Hobie/M
+Hockney/M
+Hodge/SM
+Hodges/M
+Hodgkin/M
+Hoff/M
+Hoffa/M
+Hoffman/M
+Hofstadter/M
+Hogan/M
+Hogarth/M
+Hogwarts/M
+Hohenlohe/M
+Hohenstaufen/M
+Hohenzollern/M
+Hohhot/M
+Hohokam/M
+Hokkaido/M
+Hokusai/M
+Holbein/M
+Holcomb/M
+Holden/M
+Holder/M
+Holiday/M
+Holiness
+Holland/ZSMR
+Hollander/M
+Hollandica/M
+Hollerith/M
+Holley/M
+Hollie/M
+Hollis/M
+Holloway/M
+Holly/M
+Hollywood/M
+Holman/M
+Holmes/M
+Holocaust/M
+Holocene/M
+Holst/M
+Holstein/SM
+Holt/M
+Homer/M
+Homeric/M
+Hon
+Honda/M
+Honduran/MS
+Honduras/M
+Honecker/M
+Honeywell/M
+Hong
+Honiara/M
+Honolulu/M
+Honorable
+Honoria/M
+Honshu/M
+Hood/M
+Hooke/RM
+Hooker/M
+Hooper/M
+Hoosier/MS
+Hooters/M
+Hoover/MS
+Hope/M
+Hopewell/M
+Hopi/SM
+Hopkins/M
+Hopper/M
+Horace/M
+Horacio/M
+Horatia/M
+Horatio/M
+Horatius/M
+Hormel/M
+Hormuz/M
+Horn/M
+Hornblower/M
+Horne/M
+Horowitz/M
+Horst/M
+Hort/M
+Hortense
+Hortensia/M
+Horthy/M
+Horton/M
+Horus/M
+Hosea/M
+Host/SM
+Hotmail/M
+Hotpoint/M
+Hottentot/SM
+Houdini/M
+Houghton/M
+Houma/M
+House/M
+Housman/M
+Houston/M
+Houyhnhnm/M
+Hovhaness/M
+Howard/M
+Howe/M
+Howell/MS
+Howells/M
+Howey/M
+Howie/M
+Howrah
+Hoyle/M
+Hoyt/M
+Hrothgar/M
+Hts
+Huang/M
+Hubbard/M
+Hubble/M
+Hubei/M
+Huber/M
+Hubert/M
+Huck/M
+Huddersfield
+Hudson/M
+Huerta/M
+Huey/M
+Huff/M
+Huffman/M
+Huggins/M
+Hugh/MS
+Hughes/M
+Hughie
+Hugo/M
+Huguenot/MS
+Hugues/M
+Hui/M
+Huitzilopotchli/M
+Hulda/M
+Hull/M
+Humbert/M
+Humberto/M
+Humboldt/M
+Hume/M
+Humfrey/M
+Hummel/M
+Hummer/M
+Humphrey/SM
+Humvee/M
+Hun/SM
+Hunan/M
+Hung/M
+Hungarian/SM
+Hungary/M
+Hunspell/M
+Hunt/MR
+Hunter/M
+Huntington/M
+Huntley/M
+Huntsville/M
+Hurd/M
+Hurley/M
+Huron/M
+Hurst/M
+Hus/M
+Husein/M
+Hussein/M
+Husserl/M
+Hussite/M
+Huston/M
+Hutchinson/M
+Hutton/M
+Hutu/M
+Huxley/M
+Huygens/M
+Hy/M
+Hyacinthe/M
+Hyades/M
+Hyatt/M
+Hyde/M
+Hyderabad/M
+Hydra/M
+Hyman/M
+Hymen/M
+Hymie
+Hyperion/M
+Hyundai/M
+Hz/M
+Hloise/M
+I'd
+I'll
+I'm
+I've
+I/M
+IA
+IANAL
+IBM/M
+ICBM/SM
+ICC
+ICU
+ID/SM
+IDE
+IE
+IED
+IEEE
+IIRC
+IKEA/M
+IL
+IMDb/M
+IMDbPro/M
+IMF/M
+IMHO
+IMNSHO
+IMO
+IN
+ING/M
+INRI
+INS
+IOU/M
+IP
+IPA
+IPO/SM
+IQ/M
+IRA/SM
+IRC
+IRS/M
+ISBN
+ISIS
+ISO/M
+ISP/SM
+ISS
+IT
+IUD
+IV/SM
+IVF
+Ia
+Iaccoca/M
+Iago/M
+Iain/M
+Ian/M
+Ianthe/M
+Iapetus/M
+Ibadan/M
+Iberia/M
+Iberian/M
+Ibiza/M
+Iblis/M
+Ibo/M
+Ibrahim/M
+Ibsen/M
+Icahn/M
+Icarus/M
+Ice
+Iceland/MRZ
+Icelander/M
+Icelandic/M
+Ichabod/M
+Ida/M
+Idaho/SM
+Idahoan/MS
+Idahoes
+Ieyasu/M
+Iggy/M
+Ignace/M
+Ignacio/M
+Ignatius/M
+Ignaz/M
+Ignazio/M
+Igor/M
+Iguassu/M
+Ijsselmeer/M
+Ike/M
+Ikey/M
+Ikhnaton/M
+Ila/M
+Ileana/M
+Ilene/M
+Iliad/SM
+Ilka/M
+Ill
+Illa/M
+Illinois/M
+Illinoisan/MS
+Illuminati/M
+Ilsa/M
+Ilse/M
+Ilyushin/M
+Imam
+Imelda/M
+Imhotep/M
+Immanuel
+Imodium/M
+Imogen/M
+Imogene/M
+Imus/M
+In/MP
+Ina/M
+Inc
+Inca/SM
+Inchon/M
+Incorporated
+Ind
+Independence/M
+India/M
+Indian/MS
+Indiana/M
+Indianan/SM
+Indianapolis/M
+Indianian
+Indies/M
+Indio/M
+Indira/M
+Indochina/M
+Indochinese/M
+Indonesia/M
+Indonesian/SM
+Indore/M
+Indra/M
+Indus/M
+Indy/SM
+Ines/M
+Inez/M
+Inga/M
+Inge/RM
+Ingeborg/M
+Ingemar/M
+Inger/M
+Inglewood
+Inglis/M
+Ingmar/M
+Ingram/M
+Ingres/M
+Ingrid/M
+Inigo/M
+Inna/M
+Inness/M
+Innis/M
+Innocent/M
+Innsbruck
+Inonu/M
+Inquisition/M
+Inst
+Instagram/M
+Instamatic/M
+Intel/M
+Intelsat/M
+Internationale/M
+Internet/SM
+Interpol/M
+Inuit/MS
+Inuktitut/M
+Invar/M
+Io/M
+Iona
+Ionesco/M
+Ionian/MS
+Ionic/SM
+Iowa/SM
+Iowan/MS
+Iphigenia/M
+Ipswich
+Iqaluit/M
+Iqbal/M
+Iquitos/M
+Ir/M
+Ira/M
+Iran/M
+Iranian/SM
+Iraq/M
+Iraqi/MS
+Ireland/M
+Irena/M
+Irene/M
+Irina/M
+Iris/M
+Irish/MR
+Irishman/M
+Irishmen/M
+Irishwoman/M
+Irishwomen/M
+Irkutsk/M
+Irma/M
+Iroquoian/SM
+Iroquois/M
+Irrawaddy/M
+Irtish/M
+Irv/MG
+Irvin/M
+Irvine/M
+Irving/M
+Irwin/M
+Isa
+Isaac/M
+Isaak/M
+Isabel/M
+Isabela/M
+Isabella/M
+Isabelle/M
+Isadora/M
+Isadore/M
+Isaiah/M
+Isak/M
+Iscariot/M
+Isfahan/M
+Isherwood/M
+Ishim/M
+Ishmael/M
+Ishtar/M
+Isiah/M
+Isidor/M
+Isidora/M
+Isidore/M
+Isidoro/M
+Isidro/M
+Isis/M
+Islam/MS
+Islamabad/M
+Islamic/M
+Islamica/M
+Islamism/M
+Islamist/M
+Islamophobia
+Islamophobic
+Ismael/M
+Ismail/M
+Isobel/M
+Isolde/M
+Ispell/M
+Israel/SM
+Israeli/SM
+Israelite/M
+Issac/M
+Issachar/M
+Issy/M
+Istanbul/M
+Isuzu/M
+It
+Itaipu/M
+Ital
+Italia/M
+Italian/SM
+Italianate
+Italy/M
+Itasca/M
+Ithaca/M
+Ithacan/M
+Ito/M
+Iva/M
+Ivan/M
+Ivanhoe/M
+Ivar/M
+Ive/RSM
+Iver/M
+Ives/M
+Ivie/M
+Ivoire
+Ivor/M
+Ivorian
+Ivory/M
+Ivy/M
+Iyar/M
+Izaak/M
+Izanagi/M
+Izanami/M
+Izhevsk/M
+Izmir/M
+Izod/M
+Izvestia/M
+Izzy/M
+J/MDNX
+JCS
+JD
+JFK/M
+JP
+JPEG/SM
+JSON
+JV
+Jabez/M
+Jacinta/M
+Jack/M
+Jacki/M
+Jackie/M
+Jacklin/M
+Jacklyn/M
+Jackson/M
+Jacksonian/M
+Jacksonville/M
+Jacky/M
+Jaclyn/M
+Jacob/SM
+Jacobean/M
+Jacobi/M
+Jacobin/M
+Jacobite/M
+Jacobo/M
+Jacobs/M
+Jacobson/M
+Jacquard/M
+Jacqueline/M
+Jacquelyn/M
+Jacques/M
+Jacqui/M
+Jacquie/M
+Jacuzzi/M
+Jada/M
+Jae/M
+Jagger/M
+Jagiellon/M
+Jaguar/M
+Jahangir/M
+Jaime/M
+Jain/M
+Jainism/M
+Jaipur/M
+Jakarta/M
+Jake/M
+Jakob/M
+Jamaal/M
+Jamaica/M
+Jamaican/SM
+Jamal/M
+Jamar/M
+Jame/SM
+Jamel/M
+James/M
+Jameson
+Jamestown/M
+Jamey/M
+Jami/M
+Jamie/M
+Jamil/M
+Jamison/M
+Jan/M
+Jana/M
+Janacek/M
+Jane/M
+Janek/M
+Janell/M
+Janelle/M
+Janesville/M
+Janet/M
+Janette/M
+Janey/M
+Janice/M
+Janie/M
+Janina
+Janine/M
+Janis/M
+Janissary/M
+Janjaweed/M
+Janna/M
+Jannie/M
+Janos/M
+Jansen/M
+Jansenist/M
+January/SM
+Janus/M
+Jany/M
+Jap/SM
+Japan/M
+Japanese/MS
+Japura/M
+Jared/M
+Jarlsberg/M
+Jarred/M
+Jarret/M
+Jarrett/M
+Jarrod/M
+Jarvis/M
+Jase/M
+Jasmin/M
+Jasmine/M
+Jason/M
+Jasper/M
+Jataka/M
+Java/SM
+JavaScript/M
+Javanese/M
+Javier/M
+Jaxartes/M
+Jay/M
+Jayapura/M
+Jayawardene/M
+Jaycee/MS
+Jaycees/M
+Jaye/M
+Jayme/M
+Jayne/M
+Jayson/M
+Jean/M
+Jeana/M
+Jeane/M
+Jeanette/M
+Jeanie/M
+Jeanine/M
+Jeanne/M
+Jeannette/M
+Jeannie/M
+Jeannine/M
+Jed/M
+Jedediah/M
+Jedi/M
+Jedidiah/M
+Jeep/M
+Jeeves/M
+Jeff/M
+Jefferey/M
+Jefferson/M
+Jeffersonian/M
+Jeffery/M
+Jeffrey/M
+Jeffry/M
+Jehoshaphat/M
+Jehovah/M
+Jehu
+Jekyll/M
+Jemima/M
+Jemmy/M
+Jen/M
+Jena/M
+Jenifer/M
+Jenkins/M
+Jenn/MRJ
+Jenna/M
+Jenner/M
+Jenni/M
+Jennie/M
+Jennifer/M
+Jennings/M
+Jenny/M
+Jeno/M
+Jensen/M
+Jephthah/M
+Jerald/M
+Jere/M
+Jeremiah/M
+Jeremiahs
+Jeremias/M
+Jeremie/M
+Jeremy/M
+Jeri/M
+Jericho/M
+Jermaine/M
+Jeroboam/M
+Jerold/M
+Jerome/M
+Jerri/M
+Jerrie/M
+Jerrod/M
+Jerrold/M
+Jerry/M
+Jersey/MS
+Jerusalem/M
+Jervis/M
+Jess/M
+Jessamine/M
+Jessamyn/M
+Jesse/M
+Jessey/M
+Jessi/M
+Jessica/M
+Jessie/M
+Jessy/M
+Jesuit/MS
+Jesus/M
+Jethro
+Jetway/M
+Jew/SM
+Jewel/M
+Jewell/M
+Jewess/MS
+Jewish/PM
+Jewry/M
+Jezebel/SM
+Jiangsu/M
+Jiangxi/M
+Jidda/M
+Jilin/M
+Jill/M
+Jillian/M
+Jilly/M
+Jim/M
+Jimenez/M
+Jimmie/M
+Jimmy/M
+Jinan/M
+Jinnah/M
+Jinny/M
+Jivaro/M
+Jo/MY
+Joachim
+Joan/M
+Joana/M
+Joane/M
+Joanie/M
+Joann/M
+Joanna/M
+Joanne/SM
+Joaquin/M
+Job/SM
+Jobs/M
+Joby/M
+Jocasta/M
+Jocelin/M
+Jocelyn/M
+Jocelyne/M
+Jock/M
+Jockey/M
+Jocko/M
+Jodi/M
+Jodie/M
+Jody/M
+Joe/M
+Joel/M
+Joelle/M
+Joey/M
+Jogjakarta/M
+Johan/M
+Johann/M
+Johanna/M
+Johannes/M
+Johannesburg/M
+John/SM
+Johnathan/M
+Johnathon/M
+Johnie/M
+Johnnie/M
+Johnny/M
+Johns/M
+Johnson/M
+Johnston/M
+Johnstown/M
+Jojo/M
+Jolene/M
+Joli/M
+Jolie/M
+Joliet/M
+Jolson/M
+Joly/M
+Jon/M
+Jonah/M
+Jonahs
+Jonas/M
+Jonathan/M
+Jonathon/M
+Jone/SM
+Jones/M
+Jonesboro/M
+Joni/M
+Jonson/M
+Joplin/M
+Jordan/M
+Jordana/M
+Jordanian/MS
+Jordon/M
+Jorge/M
+Jori/M
+Jory/M
+Joscelin/M
+Jose/M
+Josef/M
+Josefa/M
+Josefina/M
+Joseph/M
+Josepha/M
+Josephine/M
+Josephs
+Josephson/M
+Josephus/M
+Josey/M
+Josh/M
+Joshua/M
+Josiah/M
+Josias/M
+Josie/M
+Josselyn/M
+Josue/M
+Joule/M
+Jourdain/M
+Jourdan/M
+Jove/M
+Jovian/M
+Joy/M
+Joya/M
+Joyce/M
+Joycean/M
+Joye/M
+Joyner/M
+Jozef/M
+Jpn
+Jr/M
+Juan/M
+Juana/M
+Juanita/M
+Juarez/M
+Jubal/M
+Jud
+Judaeo
+Judah/M
+Judaic
+Judaical
+Judaism/MS
+Judas/MS
+Judd/M
+Jude/M
+Judea/M
+Judges
+Judi/MH
+Judith/M
+Judson/M
+Judy/M
+Juggernaut/M
+Jul
+Jule/SM
+Jules/M
+Juli/M
+Julia/M
+Julian/M
+Juliana/M
+Juliane/M
+Julianna/M
+Julianne/M
+Julie/M
+Julienne's
+Juliet/M
+Juliette/M
+Julio/M
+Julius/M
+Julliard/M
+July/SM
+Jun/M
+June/SM
+Juneau/M
+Juneteenth/M
+Jung/M
+Jungfrau/M
+Jungian/M
+Junia/M
+Junie/M
+Junior/SM
+Junker/SM
+Juno/M
+Jupiter/M
+Jurassic/M
+Jurua/M
+Justice/M
+Justin/M
+Justina/M
+Justine/M
+Justinian/M
+Justus/M
+Jutland/M
+Juvenal/M
+Jyoti/M
+K/SMNRGJ
+KB/M
+KC
+KFC/M
+KGB/M
+KIA
+KKK/M
+KO/M
+KP
+KS
+KY
+Kaaba/M
+Kabul/M
+Kafka/M
+Kafkaesque/M
+Kagoshima/M
+Kahlil/M
+Kahlua/M
+Kahului/M
+Kai/M
+Kaia/M
+Kaifeng/M
+Kaila/M
+Kailua/M
+Kain/M
+Kaine/M
+Kaiser/MS
+Kaitlin/M
+Kaitlyn/M
+Kaja/M
+Kala/M
+Kalahari/M
+Kalamazoo/M
+Kalashnikov/M
+Kalb/M
+Kalevala/M
+Kalgoorlie/M
+Kali/M
+Kalil/M
+Kalina/M
+Kalle/M
+Kalmyk/M
+Kama/M
+Kamchatka/M
+Kamehameha/M
+Kampala/M
+Kampuchea/M
+Kan/SM
+Kanchenjunga/M
+Kandahar/M
+Kandinsky/M
+Kandy
+Kane/M
+Kaneohe/M
+Kania/M
+Kankakee/M
+Kannada/M
+Kano/M
+Kanpur/M
+Kansan/MS
+Kansas/M
+Kant/M
+Kantian/M
+Kanya/M
+Kaohsiung/M
+Kaposi/M
+Kara/M
+Karachi/M
+Karaganda/M
+Karakorum/M
+Karamazov/M
+Kare/M
+Kareem/M
+Karel/M
+Karen/M
+Karenina/M
+Kari/M
+Karim/M
+Karin/M
+Karina/M
+Karine/M
+Karl/MN
+Karla/M
+Karlen/M
+Karloff/M
+Karly/M
+Karna/M
+Karnataka/M
+Karo/MY
+Karol/M
+Karolina/M
+Karoline/M
+Karoly/M
+Karon/M
+Karroo/M
+Karyn/M
+Kasai/M
+Kasey/M
+Kashmir/SM
+Kaspar/M
+Kasparov/M
+Kasper/M
+Kass
+Kassandra/M
+Kat/M
+Kata/M
+Katalin/M
+Kate/M
+Katelyn/M
+Katerina/M
+Kath/M
+Katha/M
+Katharina/M
+Katharine/M
+Kathe/M
+Katherina/M
+Katherine/M
+Katheryn/M
+Kathi/M
+Kathiawar/M
+Kathie/M
+Kathleen/M
+Kathmandu/M
+Kathrine/M
+Kathryn/M
+Kathy/M
+Kati/M
+Katie/M
+Katina/M
+Katinka/M
+Katmai/M
+Katmandu/M
+Katowice/M
+Katrina/M
+Katrine
+Katrinka/M
+Katy/M
+Katya/M
+Kauai/M
+Kaufman/M
+Kaunas/M
+Kaunda/M
+Kavanaugh/M
+Kawabata/M
+Kawasaki/M
+Kay/M
+Kaycee/M
+Kaye/M
+Kayla/M
+Kaylee/M
+Kayne/M
+Kazakh/M
+Kazakhs
+Kazakhstan/M
+Kazan/M
+Kazantzakis/M
+Kb/M
+Kean
+Keane/M
+Kearney/M
+Keaton/M
+Keats/M
+Keck/M
+Keefe/RM
+Keefer/M
+Keeley/M
+Keely/M
+Keenan/M
+Keene/M
+Keewatin/M
+Keillor/M
+Keir/M
+Keisha/M
+Keith/M
+Kellen/M
+Keller/M
+Kelley/M
+Kelli/M
+Kellie/M
+Kellogg/M
+Kelly/M
+Kelsey/M
+Kelvin/M
+Kemerovo/M
+Kemp/M
+Kempis/M
+Ken/M
+Kendal/M
+Kendall/M
+Kendell/M
+Kendra/M
+Kendrick/MS
+Kenmore/M
+Kenn/M
+Kenna/M
+Kennan/M
+Kennedy/M
+Kenneth/M
+Kennett/M
+Kennewick/M
+Kennith/M
+Kenny/M
+Kenosha/M
+Kent/M
+Kenton/M
+Kentuckian/MS
+Kentucky/M
+Kenya/M
+Kenyan/SM
+Kenyatta/M
+Kenyon/M
+Keogh/M
+Keokuk/M
+Kepler/M
+Ker/M
+Kerala/M
+Kerby/M
+Kerensky/M
+Keri/M
+Kerk/M
+Kermit/M
+Kern/M
+Kerouac/M
+Kerr/M
+Kerri/M
+Kerrie/M
+Kerry/M
+Kerstin/M
+Kerwin/M
+Kettering/M
+Kev/MN
+Kevan/M
+Keven/M
+Kevin/M
+Kevlar/M
+Kevorkian/M
+Kewpie/M
+Key/M
+Keynes/M
+Keynesian/M
+Khabarovsk/M
+Khachaturian/M
+Khalid/M
+Khalil/M
+Khan/M
+Kharkov/M
+Khartoum/M
+Khayyam/M
+Khazar/M
+Khazarica/M
+Khmer/M
+Khoikhoi/M
+Khoisan/M
+Khomeini/M
+Khorana/M
+Khrushchev/M
+Khufu/M
+Khulna/M
+Khwarizmi/M
+Khyber/M
+Ki/M
+Kickapoo/M
+Kidd/M
+Kiel/M
+Kierkegaard/M
+Kieth/M
+Kiev/M
+Kigali/M
+Kikuyu/M
+Kilauea/M
+Kile/M
+Kiley/M
+Kilian/M
+Kilimanjaro/M
+Killeen/M
+Killian/M
+Kilroy/M
+Kim/M
+Kimball/M
+Kimbell/M
+Kimberley/M
+Kimberly/M
+Kimble/M
+Kimmy/M
+Kincaid/M
+King/M
+Kingsley
+Kingsport/M
+Kingston/M
+Kingstown/M
+Kinko/M
+Kinney/M
+Kinsey/M
+Kinshasa/M
+Kinsley/M
+Kiowa/MS
+Kip/M
+Kipling/M
+Kipp/M
+Kira/M
+Kirby/M
+Kirchhoff/M
+Kirchner/M
+Kirghistan/M
+Kirghiz/M
+Kirghizia/M
+Kiri/M
+Kiribati/M
+Kirinyaga/M
+Kirk/M
+Kirkland/M
+Kirkpatrick/M
+Kirov/M
+Kirsten/M
+Kisangani/M
+Kishinev/M
+Kislev/M
+Kissimmee/M
+Kissinger/M
+Kit/M
+Kitakyushu/M
+Kitchener/M
+Kitts/M
+Kitty/M
+Kiwanis/M
+Klan/M
+Klansman/M
+Klara/M
+Klaus/M
+Klee/M
+Kleenex/MS
+Klein/M
+Klemens/M
+Klement/M
+Klimt/M
+Kline/M
+Klingon/M
+Klondike/MS
+Kmart/M
+Knapp/M
+Knesset/M
+Kngwarreye/M
+Knickerbocker/M
+Knievel/M
+Knight/M
+Knopf/M
+Knossos/M
+Knowles/M
+Knox/M
+Knoxville/M
+Knudsen/M
+Knuth/M
+Knuths
+Kobe/M
+Koch/M
+Kochab/M
+Kodachrome/M
+Kodak/M
+Kodaly/M
+Kodiak/M
+Koestler/M
+Kohinoor/M
+Kohl/M
+Koizumi/M
+Kojak/M
+Kokomo/M
+Kolyma/M
+Kommunizma/M
+Kong/M
+Kongo/M
+Konrad/M
+Konstantin/M
+Koo/M
+Koontz/M
+Koppel/M
+Kora/M
+Koran/MS
+Koranic
+Kore/M
+Korea/M
+Korean/SM
+Koren/M
+Kori/M
+Kornberg/M
+Kort/M
+Kory/M
+Korzybski/M
+Kosciusko/M
+Kosovo/M
+Kossuth/M
+Kosygin/M
+Kotlin/M
+Koufax/M
+Kowloon/M
+Kr/M
+Kraft/M
+Krakatau/M
+Krakatoa/M
+Krakow/M
+Kramer/M
+Krasnodar/M
+Krasnoyarsk/M
+Krebs/M
+Kremlin/M
+Kremlinologist
+Kremlinology
+Kresge/M
+Kringle/M
+Kris/M
+Krishna/M
+Krishnamurti/M
+Krista/M
+Kristen/M
+Kristi/M
+Kristian/M
+Kristie/M
+Kristin/M
+Kristina/M
+Kristine/M
+Kristopher/M
+Kristy/M
+Kroc/M
+Kroger/M
+Kronecker/M
+Kropotkin/M
+Kruger/M
+Krugerrand/M
+Krupp/M
+Krystal/M
+Krystyna/M
+Kshatriya/M
+Kuala/M
+Kubernetes/M
+Kublai/M
+Kubrick/M
+Kuhn/M
+Kuibyshev/M
+Kulthumm/M
+Kunming/M
+Kuomintang/M
+Kurd/M
+Kurdish/M
+Kurdistan/M
+Kurosawa/M
+Kurt/M
+Kurtis/M
+Kusch/M
+Kutuzov/M
+Kuwait/M
+Kuwaiti/SM
+Kuznets/M
+Kuznetsk/M
+Kwakiutl/M
+Kwan/M
+Kwangchow/M
+Kwangju/M
+Kwanzaa/MS
+Ky/MH
+Kyiv/M
+Kyla/M
+Kyle/M
+Kylie/M
+Kym/M
+Kyoto/M
+Kyrgyzstan/M
+Kyushu/M
+L'Amour/M
+L'Enfant
+L'Oreal/M
+L'Ouverture/M
+L/MN
+LA
+LAN/M
+LBJ/M
+LC
+LCD/M
+LCM
+LDC
+LED/M
+LG/M
+LGBT
+LIFO
+LISTSERV/M
+LL
+LLB/M
+LLD/M
+LNG
+LOGO
+LP/M
+LPG
+LPN/SM
+LSAT
+LSD/M
+LVN
+La/SM
+Lab
+Laban/M
+Labrador/SM
+Labradorean
+Labradorian
+Lacey/M
+Lachesis/M
+Lactobacillus
+Lacy/M
+Ladoga/M
+Ladonna/M
+Lady/M
+Ladyship/MS
+Laetitia/M
+Lafayette/M
+Lafitte/M
+Lagos/M
+Lagrange/M
+Lagrangian/M
+Lahore/M
+Lainey/M
+Laius/M
+Lajos/M
+Lakeisha/M
+Lakeland/M
+Lakers/M
+Lakewood
+Lakisha/M
+Lakota/M
+Lakshmi/M
+Lalo/M
+Lamaism/SM
+Lamar/M
+Lamarck/M
+Lamaze/M
+Lamb/M
+Lambert/M
+Lamborghini/M
+Lambrusco/M
+Lamentations
+Lamond/M
+Lamont/M
+Lana/M
+Lanai/M
+Lancashire/M
+Lancaster/M
+Lance/M
+Lancelot/M
+Land/M
+Landon/M
+Landry/M
+Landsat/M
+Landsteiner/M
+Lane/M
+Laney/M
+Lang/M
+Langerhans/M
+Langland/M
+Langley/M
+Langmuir/M
+Langston/M
+Lani/M
+Lanie/M
+Lanka/M
+Lankan/M
+Lanna/M
+Lanny/M
+Lansing/M
+Lanzhou/M
+Lao/SM
+Laocoon/M
+Laos/M
+Laotian/SM
+Laplace/M
+Laplacian
+Lapland/MR
+Lapp/SM
+Lara/M
+Laramie/M
+Lardner/M
+Laredo/M
+Lari/M
+Larisa/M
+Larissa/M
+Larousse/M
+Larry/M
+Lars/MN
+Larsen/M
+Larson/M
+Lascaux/M
+Lassa/M
+Lassen/M
+Lassie/M
+Lat/M
+Latasha/M
+Lateran/M
+Latham/M
+Latin/MRS
+Latina
+Latino/SM
+Latinx
+Latisha/M
+Latonya/M
+Latoya/M
+Latrobe/M
+Latvia/M
+Latvian/MS
+Laud/MR
+Lauder/M
+Laue/M
+Laughton
+Launce/M
+Laundromat/M
+Laura/M
+Laurasia/M
+Laure/M
+Laurel/M
+Lauren/SM
+Laurence/M
+Laurent/M
+Lauretta/M
+Laurette/M
+Lauri/M
+Laurie/M
+Lauryn/M
+Laval/M
+Lavern/M
+Laverne/M
+Lavina/M
+Lavinia/M
+Lavoisier/M
+Lavonne/M
+Lawanda/M
+Lawrence/M
+Lawry/M
+Lawson/M
+Lawton/M
+Layamon/M
+Layla/M
+Layne/M
+Layton/M
+Lazar/M
+Lazare/M
+Lazaro/M
+Lazarus/M
+Le/SM
+Lea/M
+Leach/M
+Leadbelly/M
+Leah/M
+Leakey/M
+Lean/M
+Leander/M
+Leandra/M
+Leann/M
+Leanna/M
+Leanne/M
+Lear/M
+Learjet/M
+Leary/M
+Leavenworth/M
+Lebanese/M
+Lebanon/M
+Lebesgue/M
+Leblanc/M
+Leda/M
+Lederberg/M
+Lee/M
+Leeds/M
+Leela/M
+Leena/M
+Leesburg/M
+Leese/M
+Leeuwenhoek/M
+Leeward/M
+Left
+Legendre/M
+Leger/M
+Leghorn/M
+Lego/M
+Legree/M
+Lehman/M
+Leia/M
+Leibniz/M
+Leica/M
+Leicester/SM
+Leiden/M
+Leif/M
+Leigh/M
+Leighton/M
+Leila/M
+Leipzig/M
+Lek/M
+Lela/M
+Leland/M
+Lelia/M
+Lem/M
+Lemaitre/M
+Lemuel/M
+Lemuria/M
+Len/M
+Lena/M
+Lenard/M
+Lenin/M
+Leningrad/M
+Leninism/M
+Leninist/M
+Lennard/M
+Lennie/M
+Lennon/M
+Lenny/M
+Leno/M
+Lenoir/M
+Lenora/M
+Lenore/M
+Lent/SMN
+Lenten/M
+Leo/SM
+Leola/M
+Leominster/M
+Leon/M
+Leona/M
+Leonard/M
+Leonardo/M
+Leoncavallo/M
+Leone/M
+Leonel/M
+Leonhard/M
+Leonid/M
+Leonidas/M
+Leonie/M
+Leonor/M
+Leonora/M
+Leonore/M
+Leontine/M
+Leopold/M
+Leopoldo/M
+Leora/M
+Lepidus/M
+Lepke/M
+Lepus/M
+Lerner/M
+Leroi/M
+Leroy/M
+Les/M
+Lesa/M
+Lesley/M
+Leslie/M
+Lesotho/M
+Lesseps/M
+Lessie/M
+Lester/M
+Lestrade/M
+Leta/M
+Letha/M
+Lethe/M
+Leticia/M
+Letitia/M
+Letizia/M
+Letterman/M
+Lettie/M
+Letty/M
+Lev
+Levant/M
+Levesque/M
+Levey/M
+Levi/SM
+Leviathan/M
+Levin/M
+Levine/M
+Leviticus/M
+Levitt/M
+Levon/M
+Levy/M
+Lew/M
+Lewes
+Lewinsky/M
+Lewis/M
+Lewiston/M
+Lewisville/M
+Lexi/M
+Lexie/M
+Lexington/M
+LexisNexis/M
+Lexus/M
+Lexy/M
+Leyla/M
+Lhasa/MS
+Lhotse/M
+Li/MY
+Lia/M
+Liam/M
+Lian/M
+Liana/M
+Liane/M
+Lianne/M
+Liaoning/M
+Libbey/M
+Libbie/M
+Libby/M
+Liberace/M
+Liberal
+Liberia/M
+Liberian/SM
+Libra/MS
+LibreOffice/M
+Libreville/M
+Librium/M
+Libya/M
+Libyan/SM
+Lichtenstein/M
+Lida/M
+Lidia/M
+Lie/M
+Lieberman/M
+Liebfraumilch/M
+Liechtenstein/ZMR
+Liechtensteiner/M
+Lief's
+Liege/M
+Lieut
+Lil/MY
+Lila/M
+Lilah/M
+Lilia/MS
+Lilian/M
+Liliana/M
+Liliane/M
+Lilith/M
+Liliuokalani/M
+Lilla/M
+Lille/M
+Lilli/M
+Lillian/M
+Lillie/M
+Lilliput/M
+Lilliputian/MS
+Lilly/M
+Lilongwe/M
+Lily/M
+Lima/M
+Limbaugh/M
+Limbo
+Limburger/M
+Limoges/M
+Limousin/M
+Limpopo/M
+Lin/M
+Lina/M
+Linc/M
+Lincoln/MS
+Lincolnshire/M
+Lind/M
+Linda/M
+Lindbergh/M
+Lindi/M
+Lindon/M
+Lindsay/M
+Lindsey/M
+Lindy/M
+Linea/M
+LinkedIn/M
+Linn/M
+Linnaeus/M
+Linnea/M
+Linnell/M
+Linotype/M
+Linton/M
+Linus/M
+Linux/MS
+Linwood/M
+Lionel/M
+Lipizzaner/M
+Lippi/M
+Lippmann/M
+Lipscomb/M
+Lipton/M
+Lisa/M
+Lisbeth/M
+Lisbon/M
+Lise/M
+Lisette/M
+Lisle/M
+Lissa/M
+Lissajous/M
+Lissy/M
+Lister/M
+Listerine/M
+Liston/M
+Liszt/M
+Lita/M
+Lithuania/M
+Lithuanian/MS
+Little/M
+Litton/M
+Liv/M
+LiveJournal/M
+Livermore/M
+Liverpool/M
+Liverpudlian/SM
+Livia/M
+Livingston/M
+Livingstone/M
+Livonia/M
+Livvy/M
+Livy/M
+Liz/M
+Liza/M
+Lizabeth/M
+Lizbeth/M
+Lizette/M
+Lizzie/M
+Lizzy/M
+Ljubljana/M
+Llewellyn/M
+Lloyd/M
+Ln
+Loafer/SM
+Lobachevsky/M
+Lochinvar/M
+Locke/M
+Lockean/M
+Lockheed/M
+Lockwood/M
+Lodge/M
+Lodi/M
+Lodovico/M
+Lodz/M
+Loewe/M
+Loewi/M
+Loews/M
+Logan/M
+Logitech/M
+Lohengrin/M
+Loire/M
+Lois/M
+Loki/M
+Lola/M
+Lolita/M
+Lollard/M
+Lollobrigida/M
+Lolly's
+Lombard/M
+Lombardi/M
+Lombardy/M
+Lome/M
+Lompoc/M
+Lon/M
+Lona/M
+London/MRZ
+Londoner/M
+Long/M
+Longfellow/M
+Longmont/M
+Longstreet/M
+Longueuil
+Longview/M
+Loni/M
+Lonnie/M
+Lonny/M
+LookSmart/M
+Lopez/M
+Lora/M
+Lorain/M
+Loraine/M
+Lorant/M
+Lord/SM
+Lordship/SM
+Lorelei/M
+Loren/M
+Lorena/M
+Lorene/M
+Lorentz/M
+Lorentzian
+Lorenz/M
+Lorenza/M
+Lorenzo/M
+Loretta/M
+Lorette/M
+Lori/M
+Loria/M
+Lorie/M
+Lorin/M
+Lorinda/M
+Lorna/M
+Lorne/M
+Lorraine/M
+Lorre/M
+Lorrie/M
+Lory/M
+Los
+Lot/M
+Lothario/SM
+Lott/M
+Lotta/M
+Lotte/M
+Lotti/M
+Lottie/M
+Lotty/M
+Lou/M
+Louella/M
+Louie/M
+Louis/M
+Louisa/M
+Louise/M
+Louisiana/M
+Louisianan/MS
+Louisianian/MS
+Louisville/M
+Lourdes/M
+Louvre/M
+Love/M
+Lovecraft/M
+Lovelace/M
+Lovell
+Lowe/M
+Lowell/M
+Lowenbrau/M
+Lowery/M
+Lowlands
+Loy/M
+Loyang/M
+Loyd/M
+Loyola/M
+Lr
+Lt
+Ltd
+Lu/M
+Luanda/M
+Luann/M
+Lubavitcher/M
+Lubbock/M
+Lubumbashi/M
+Luca/SM
+Lucas/M
+Luce/M
+Luci/MN
+Lucia/M
+Lucian/M
+Luciana/M
+Luciano/M
+Lucie/M
+Lucien/M
+Lucienne/M
+Lucifer/M
+Lucile/M
+Lucille/M
+Lucina
+Lucinda/M
+Lucio/M
+Lucite/SM
+Lucius/M
+Lucknow/M
+Lucky's
+Lucretia/M
+Lucretius/M
+Lucy/M
+Luddite/MS
+Ludhiana/M
+Ludovico/M
+Ludvig/M
+Ludwig/M
+Luella/M
+Lufthansa/M
+Luftwaffe/M
+Luger/M
+Lugosi/M
+Luigi/M
+Luis/M
+Luisa/M
+Luise/M
+Lukas/M
+Luke/M
+Lula/M
+Lully/M
+Lulu/M
+Lumiere/M
+Lumire/M
+Luna/M
+Lupe/M
+Lupercalia/M
+Lupus/M
+Lura/M
+Luria/M
+Lusaka/M
+Lusitania/M
+Luther/M
+Lutheran/SM
+Lutheranism/MS
+Luvs/M
+Luxembourg/ZMR
+Luxembourger/M
+Luxembourgian
+Luz/M
+Luzon/M
+Lvov/M
+Ly/MY
+LyX/M
+Lyallpur
+Lycos/M
+Lycra/M
+Lycurgus/M
+Lyda/M
+Lydia/M
+Lydian/SM
+Lydie/M
+Lydon/M
+Lyell/M
+Lyle/M
+Lyly/M
+Lyman/M
+Lyme/M
+Lyn/M
+Lynch/M
+Lynchburg/M
+Lynda/M
+Lynde/M
+Lyndon/M
+Lyndsay/M
+Lyndsey/M
+Lynette/M
+Lynn/M
+Lynne/M
+Lynnette/M
+Lyon/SM
+Lyons/M
+Lyra/M
+Lysenko/M
+Lysistrata/M
+Lysol/M
+Lyssa/M
+M/SMGB
+MA/M
+MASH
+MB/M
+MBA/M
+MC
+MCI/M
+MD/M
+MDF
+MDT
+ME
+MEGO/S
+MFA/M
+MGM/M
+MHz/M
+MI/M
+MIA
+MIDI/M
+MIPS
+MIRV
+MIT/M
+MM
+MN
+MO
+MOOC
+MP/M
+MPEG/SM
+MRI/M
+MS/M
+MSG/M
+MST/M
+MSW
+MT/M
+MTF/SM
+MTV/M
+MVP/M
+MW
+Maalox/M
+Mab
+Mabel/M
+Mable/M
+Mac/M
+MacArthur/M
+MacBride/M
+MacDonald/M
+MacLeish/M
+Macao/M
+Macau/M
+Macaulay/M
+Macbeth/M
+Maccabees
+Maccabeus/M
+Mace/M
+Macedon/M
+Macedonia/M
+Macedonian/SM
+Mach/M
+Machiavelli/M
+Machiavellian/M
+Macias/M
+Macintosh/M
+Mack/M
+Mackenzie/M
+Mackinac/M
+Mackinaw/M
+Macmillan/M
+Macon/M
+Macromedia/M
+Macumba/M
+Macy/M
+Mada/M
+Madagascan/SM
+Madagascar/M
+Madalyn/M
+Madam
+Maddalena/M
+Madden/M
+Maddi/M
+Maddie/M
+Maddox/M
+Maddy/M
+Madeira/SM
+Madelaine/M
+Madeleine/M
+Madeline/M
+Madelon/M
+Madelyn/M
+Madera/M
+Madge/M
+Madison/M
+Madonna/SM
+Madras/M
+Madrid/M
+Madurai/M
+Mae/M
+Maeterlinck/M
+Mafia/MS
+Mafioso/M
+Magda/M
+Magdalen
+Magdalena/M
+Magdalene/M
+Magellan/M
+Magellanic/M
+Maggi/M
+Maggie/M
+Maggy/M
+Maghreb/M
+Magi
+Maginot/M
+Magnificat
+Magnitogorsk/M
+Magog/M
+Magoo/M
+Magritte/M
+Magsaysay/M
+Magus
+Magyar/SM
+Mahabharata/M
+Mahala/M
+Mahalia/M
+Maharashtra/M
+Mahavira/M
+Mahayana/M
+Mahayanist/M
+Mahdi/M
+Mahfouz/M
+Mahican/SM
+Mahler/M
+Mahmoud/M
+Mahmud/M
+Mai/M
+Maia/M
+Maidenform/M
+Maigret/M
+Mailer/M
+Maillol/M
+Maiman/M
+Maimonides/M
+Maine/MZR
+Mainer/M
+Mair/M
+Maire/M
+Maisie/M
+Maison/M
+Maitreya/M
+Maj
+Majesty
+Major/M
+Majorca/M
+Majuro/M
+Makarios/M
+Maker/M
+Mal
+Mala/M
+Malabar/M
+Malabo/M
+Malacca/M
+Malachi/M
+Malagasy/M
+Malamud/M
+Malaprop/M
+Malawi/M
+Malawian/SM
+Malay/MS
+Malaya/M
+Malayalam/M
+Malayan/MS
+Malaysia/M
+Malaysian/MS
+Malcolm/M
+Maldive/MS
+Maldives/M
+Maldivian/MS
+Maldonado/M
+Male/M
+Mali/M
+Malia/M
+Malian/SM
+Malibu/M
+Malina/M
+Malinda/M
+Malinowski/M
+Malissa/M
+Mallarme/M
+Mallarm/M
+Mallomars/M
+Mallory/M
+Malone/M
+Malory/M
+Malplaquet/M
+Malraux/M
+Malta/M
+Maltese/M
+Malthus/M
+Malthusian/SM
+Malva/M
+Malvin/M
+Malvina/M
+Mame/M
+Mameluke/M
+Mamet/M
+Mamie/M
+Mammon/SM
+Mamore/M
+Man/M
+Managua/M
+Manama/M
+Manasseh/M
+Manchester/M
+Manchu/SM
+Manchuria/M
+Manchurian/M
+Mancini/M
+Mancunian/MS
+Manda/M
+Mandalay/M
+Mandarin/M
+Mandel/M
+Mandela/M
+Mandelbrot/M
+Mandeville/M
+Mandi/M
+Mandie/M
+Mandingo/M
+Mandrell/M
+Mandy/M
+Manet/M
+Manfred/M
+Manhattan/SM
+Mani/M
+Manichean/M
+Manila/SM
+Manitoba/M
+Manitoulin/M
+Mankato/M
+Manley/M
+Mann/GM
+Mannheim/M
+Mannie/M
+Manning/M
+Manny/M
+Mano/M
+Manolo/M
+Manon/M
+Mansfield/M
+Manson/M
+Manteca/M
+Mantegna/M
+Mantle/M
+Manuel/M
+Manuela/M
+Manx/M
+Manya/M
+Mao/M
+Maoism/SM
+Maoist/SM
+Maori/MS
+MapQuest/M
+Mapplethorpe/M
+Maputo/M
+Mar/SMN
+Mara/M
+Maracaibo/M
+Marat/M
+Maratha/M
+Marathi/M
+Marathon/M
+Marc/M
+Marceau/M
+Marcel/M
+Marcela/M
+Marcelino/M
+Marcella/M
+Marcelle/M
+Marcello/M
+Marcellus
+Marcelo/M
+March/MS
+Marci/M
+Marcia/M
+Marciano/M
+Marcie/M
+Marco/MS
+Marconi/M
+Marcos/M
+Marcus/M
+Marcuse
+Marcy/M
+Marduk/M
+Maren/M
+Marga/M
+Margalit/M
+Margaret/M
+Margareta/M
+Margarete/M
+Margaretha/M
+Margarethe/M
+Margaretta/M
+Margarita/M
+Margarito/M
+Margaux
+Marge/M
+Margery/M
+Marget/M
+Margie/M
+Margit/M
+Margo/M
+Margot/M
+Margret/M
+Margrethe/M
+Marguerite/M
+Margy/M
+Mari/SM
+Maria/M
+MariaDB/M
+Mariam/M
+Marian/M
+Mariana/SM
+Marianas/M
+Marianna/M
+Marianne/M
+Mariano/M
+Maribel/M
+Maribeth/M
+Maricela/M
+Marie/M
+Mariel/M
+Marielle/M
+Marietta/M
+Mariette/M
+Marika/M
+Marilee/M
+Marilyn/M
+Marin/M
+Marina/M
+Marine/SM
+Mario/M
+Marion/M
+Maris/M
+Marisa/M
+Mariska/M
+Marisol/M
+Marissa/M
+Marita/M
+Maritain/M
+Maritza/M
+Mariupol
+Marius/M
+Marj/M
+Marja/M
+Marjorie/M
+Marjory/M
+Mark/SM
+Markab/M
+Markham/M
+Markos
+Markov/M
+Marks/M
+Markus/M
+Marla/M
+Marlboro/M
+Marlborough/M
+Marlee/M
+Marleen/M
+Marlena/M
+Marlene/M
+Marley/M
+Marlin/M
+Marline/M
+Marlo/M
+Marlon/M
+Marlow/M
+Marlowe/M
+Marmaduke/M
+Marmara/M
+Marne/M
+Marney/M
+Marni/M
+Marnie/M
+Maronite/M
+Marple/M
+Marquesas/M
+Marquette/M
+Marquez/M
+Marquis/M
+Marquita/M
+Marrakesh/M
+Marriott/M
+Marris/M
+Mars/MS
+Marsala/M
+Marseillaise/MS
+Marseilles/M
+Marsh/M
+Marsha/M
+Marshall/M
+Marta/M
+Martel/M
+Martha/M
+Marthe/M
+Marti/M
+Martial/M
+Martian/SM
+Martie/M
+Martin/M
+Martina/M
+Martinez/M
+Martinique/M
+Martino/M
+Marty/M
+Martyn/M
+Marv/M
+Marva/M
+Marvell/M
+Marvin/M
+Marx/M
+Marxian
+Marxism/SM
+Marxist/SM
+Mary/M
+Marya/M
+Maryann/M
+Maryanne/M
+Marybeth/M
+Maryellen/M
+Maryland/MR
+Marylander/M
+Marylin/M
+Marylou/M
+Marys
+Marysville/M
+Masada/M
+Masai/M
+Masaryk/M
+Mascagni/M
+Masefield/M
+Maserati/M
+Maseru/M
+Masha/M
+Mashhad/M
+Mason/MS
+Masonic/M
+Masonite/M
+Mass/MS
+Massachusetts/M
+Massasoit/M
+Massenet/M
+Massey/M
+Massimiliano/M
+Massimo/M
+Master/S
+MasterCard/M
+Masters/M
+Mata/M
+Mateo/M
+MathML/M
+Mathe/MR
+Mather/M
+Matheson/M
+Mathew/SM
+Mathews/M
+Mathewson/M
+Mathias/M
+Mathilda/M
+Mathilde/M
+Mathis/M
+Matias/M
+Matilda/M
+Matilde/M
+Matisse/M
+Matlab/M
+Matt/M
+Mattel/M
+Matteo/M
+Matterhorn/M
+Matthew/SM
+Matthews/M
+Matthias/M
+Matthieu/M
+Matti/M
+Mattias/M
+Mattie/M
+Matty/M
+Maud/M
+Maude/M
+Maudie/M
+Maugham/M
+Maui/M
+Mauldin/M
+Maupassant/M
+Maura/M
+Maureen/M
+Mauriac/M
+Maurice/M
+Mauricio/M
+Maurie/M
+Maurine/M
+Mauritania/M
+Mauritanian/SM
+Mauritian/SM
+Mauritius/M
+Maurits/M
+Maurizio/M
+Mauro/M
+Maurois/M
+Maury
+Mauryan/M
+Mauser/M
+Mavis/M
+Max/M
+Maxie/M
+Maximilian/M
+Maximilien/M
+Maximo/M
+Maxine/M
+Maxwell/M
+May/SMR
+Maya/SM
+Mayan/MS
+Maybelle/M
+Maye/M
+Mayer/M
+Mayfair/M
+Mayflower/M
+Maynard/M
+Mayne/M
+Mayo/M
+Maypole
+Mayra/M
+Mays/M
+Maytag/M
+Mazama/M
+Mazarin/M
+Mazatlan/M
+Mazda/M
+Mazola/M
+Mazzini/M
+Mb/M
+Mbabane/M
+Mbini/M
+Mbps
+McAdam/M
+McAfee/M
+McAllen/M
+McBride/M
+McCain/M
+McCall/M
+McCann/M
+McCarthy/M
+McCarthyism/M
+McCartney/M
+McCarty/M
+McClain/M
+McClellan/M
+McClure/M
+McConnell/M
+McCormick/M
+McCoy/M
+McCray/M
+McCullough/M
+McDaniel/M
+McDonald/M
+McDonnell/M
+McDowell/M
+McEnroe/M
+McFadden/M
+McFarland/M
+McGee/M
+McGovern/M
+McGowan/M
+McGuffey/M
+McGuire/M
+McHenry/M
+McIntosh/M
+McIntyre/M
+McJob
+McKay/M
+McKee/M
+McKenzie/M
+McKinley/M
+McKinney/M
+McKnight/M
+McLaughlin/M
+McLean/M
+McLeod/M
+McLuhan/M
+McMahon/M
+McMillan/M
+McNamara/M
+McNaughton/M
+McNeil/M
+McPherson/M
+McQueen/M
+McVeigh/M
+Md/M
+Me
+Mead/M
+Meade/M
+Meadows/M
+Meagan/M
+Meaghan/M
+Meany/M
+Meara/M
+Mecca/MS
+Medan/M
+Medea/M
+Medellin/M
+Medford/M
+Media/M
+Medicaid/SM
+Medicare/SM
+Medici/M
+Medina/M
+Mediterranean/MS
+Medline/M
+Medusa/M
+Meg/M
+Megan/M
+Meggie/M
+Meghan/M
+Mei/MR
+Meier/M
+Meighen/M
+Meiji/M
+Meir/M
+Mejia/M
+Mekong/M
+Mel/MY
+Mela/M
+Melanesia/M
+Melanesian/M
+Melania/M
+Melanie/M
+Melba/M
+Melbourne/M
+Melchior/M
+Melchizedek/M
+Melendez/M
+Melicent/M
+Melina/M
+Melinda/M
+Melisa/M
+Melisande/M
+Melissa/M
+Melita/M
+Mella/M
+Melli/M
+Mellie/M
+Mellon/M
+Melly/M
+Melodie/M
+Melody/M
+Melony/M
+Melpomene/M
+Melton/M
+Melva/M
+Melville/M
+Melvin/M
+Melvyn/M
+Memcached/M
+Memling/M
+Memphis/M
+Menander/M
+Menard/M
+Mencius/M
+Mencken/M
+Mendel/M
+Mendeleev/M
+Mendelian/M
+Mendelssohn/M
+Mendez/M
+Mendocino/M
+Mendoza/M
+Menelaus/M
+Menelik/M
+Menes/M
+Mengzi
+Menifee/M
+Menkalinan/M
+Menkar/M
+Menkent/M
+Mennen/M
+Mennonite/MS
+Menominee/M
+Menotti/M
+Mensa/M
+Mentholatum/M
+Menuhin/M
+Menzies/M
+Mephisto
+Mephistopheles/M
+Merak/M
+Mercado/M
+Mercator/M
+Merced/M
+Mercedes/M
+Mercer/M
+Merci/M
+Mercia/M
+Merck/M
+Mercurochrome/M
+Mercury/SM
+Meredith/M
+Meriel/M
+Merino/M
+Merl/M
+Merle/M
+Merlin/M
+Merlot/M
+Merovingian/M
+Merriam/M
+Merrick/M
+Merrie/M
+Merrill/M
+Merrily's
+Merrimack/M
+Merritt/M
+Merry's
+Mersey
+Merthiolate/M
+Merton/M
+Merv/M
+Mervin/M
+Merwin/M
+Merwyn/M
+Meryl/M
+Mesa/M
+Mesabi/M
+Meshed/M
+Mesmer/M
+Mesolithic/M
+Mesopotamia/M
+Mesopotamian
+Mesozoic/M
+Messerschmidt/M
+Messiaen/M
+Messiah/M
+Messiahs
+Messianic
+Messieurs
+Metacafe/M
+Metallica/M
+Metamucil/M
+Methodism/SM
+Methodist/SM
+Methuselah/M
+Metternich/M
+Meuse/M
+Mex
+Mexicali/M
+Mexican/MS
+Mexico/M
+Meyer/MS
+Meyerbeer/M
+Meyers/M
+Mfume/M
+Mg/M
+Mgr
+MiG/M
+Mia/M
+Miami/MS
+Miaplacidus/M
+Micaela/M
+Micah/M
+Micawber/M
+Mich/M
+Michael/M
+Michaela/M
+Michaelmas/MS
+Michail/M
+Michal/M
+Micheal/M
+Michel/M
+Michelangelo/M
+Michele/M
+Michelin/M
+Micheline/M
+Michell/M
+Michelle/M
+Michelob/M
+Michelson/M
+Michigan/M
+Michigander/MS
+Michiganite
+Mick/M
+Mickey/M
+Micki/M
+Mickie/M
+Micky/M
+Micmac/SM
+Micronesia/M
+Micronesian/M
+Microsoft/M
+Midas/M
+Middleton/M
+Middletown/M
+Mideast
+Mideastern
+Midland/MS
+Midway/M
+Midwest/M
+Midwestern/MR
+Mignon/M
+Miguel/M
+Mikael/M
+Mike/M
+Mikel/M
+Mikey/M
+Mikhail/M
+Mikkel/M
+Mikoyan/M
+Milagros/M
+Milan/M
+Milanese
+Mildred/M
+Milena/M
+Miles/M
+Milford/M
+Milken/M
+Mill/SMR
+Millard/M
+Millay/M
+Miller/M
+Millet/M
+Milli/M
+Millicent/M
+Millie/M
+Millikan/M
+Mills/M
+Milly/M
+Milne/M
+Milo/M
+Milosevic/M
+Milquetoast/M
+Miltiades/M
+Milton/M
+Miltonian
+Miltonic/M
+Miltown/M
+Milwaukee/M
+Mimi/M
+Mimosa/M
+Min/M
+Mina/M
+Minamoto/M
+Minda/M
+Mindanao/M
+Mindoro/M
+Mindy/M
+Minerva/M
+Minette/M
+Ming/M
+Mingus/M
+Minn
+Minna
+Minne/M
+Minneapolis/M
+Minnelli/M
+Minnesota/M
+Minnesotan/SM
+Minnie/M
+Minny/M
+Minoan/MS
+Minolta/M
+Minos/M
+Minot/M
+Minotaur/M
+Minsk/M
+Minsky/M
+Minta/M
+Mintaka/M
+Minuit/M
+Minuteman/M
+Miocene/M
+Mir/M
+Mira/M
+Mirabeau/M
+Mirabel/M
+Mirabella/M
+Mirabelle/M
+Mirach/M
+Miran/M
+Miranda/M
+Mireille/M
+Mirella/M
+Mirfak/M
+Miriam/M
+Mirna/M
+Miro/M
+Mirzam/M
+Mischa/M
+Misha/M
+Miskito/M
+Miss
+Missie/M
+Mississauga/M
+Mississippi/M
+Mississippian/SM
+Missoula/M
+Missouri/M
+Missourian/MS
+Missy/M
+Mistassini/M
+Mister
+Mistress
+Misty/M
+Mitch/M
+Mitchel/M
+Mitchell/M
+Mitford/M
+Mithra/M
+Mithridates/M
+Mitsubishi/M
+Mitterrand/M
+Mitty/M
+Mitzi/M
+Mixtec/M
+Mizar/M
+Mk
+Mlle
+Mme/S
+Mn/M
+Mnemosyne/M
+Mo/M
+Mobil/M
+Mobile/M
+Mobutu/M
+Modesto/M
+Modigliani/M
+Moe/M
+Moet/M
+Mogadishu/M
+Mogul/MS
+Mohacs/M
+Mohamed/M
+Mohammad/M
+Mohammedan/SM
+Mohammedanism/SM
+Mohandas/M
+Mohave/SM
+Mohawk/SM
+Mohegan
+Moho/M
+Mohorovicic/M
+Moira/M
+Moise/MS
+Moises/M
+Moiseyev/M
+Moishe/M
+Mojave/SM
+Moldavia/M
+Moldavian
+Moldova/M
+Moldovan
+Moliere/M
+Molina/M
+Moll/M
+Mollie/M
+Molly/M
+Molnar/M
+Moloch/M
+Molokai/M
+Molotov/M
+Moluccas/M
+Mombasa/M
+Mon/SM
+Mona/M
+Monacan
+Monaco/M
+Mondale/M
+Monday/SM
+Mondrian/M
+Monegasque/SM
+Monera/M
+Monessen/M
+Monet/M
+MongoDB/M
+Mongol/SM
+Mongolia/M
+Mongolian/SM
+Mongolic/M
+Mongolica/M
+Mongoloid
+Monica/M
+Monika/M
+Monique/M
+Monk/M
+Monmouth/M
+Monongahela/M
+Monro/M
+Monroe/M
+Monrovia/M
+Monsanto/M
+Monsieur/M
+Monsignor/SM
+Mont/M
+Montague/M
+Montaigne/M
+Montana/M
+Montanan/SM
+Montcalm/M
+Monte/M
+Montenegrin/M
+Montenegro/M
+Monterey/M
+Monterrey/M
+Montesquieu/M
+Montessori/M
+Monteverdi/M
+Montevideo/M
+Montezuma/M
+Montgolfier/M
+Montgomery/M
+Monti/M
+Monticello/M
+Montoya/M
+Montpelier/M
+Montrachet/M
+Montreal/M
+Montserrat/M
+Monty/M
+Moody/M
+Moog/M
+Moon/M
+Mooney/M
+Moor/SM
+Moore/M
+Moorish/M
+Mora/M
+Morales/M
+Moran/M
+Moravia/M
+Moravian/M
+Mord/M
+Mordecai
+Mordred/M
+More/M
+Morena/M
+Moreno/M
+Morey/M
+Morgan/SM
+Morgana/M
+Morgantown/M
+Morgen/M
+Moria/M
+Moriarty/M
+Morin/M
+Morison/M
+Morita/M
+Moritz/M
+Morley/M
+Mormon/SM
+Mormonism/SM
+Morna/M
+Moro/M
+Moroccan/SM
+Morocco/M
+Moroni/M
+Morpheus/M
+Morphy/M
+Morrie/M
+Morris/M
+Morrison/M
+Morristown/M
+Morrow/M
+Morse/M
+Mort/MN
+Morten/M
+Mortimer/M
+Morton/M
+Morty/M
+Mosaic/M
+Moscow/M
+Mose/SM
+Moseley/M
+Moselle/M
+Moses/M
+Moshe/M
+Moslem/M
+Mosley/M
+Moss/M
+Mosul/M
+Motorola/M
+Motown/M
+Motrin/M
+Mott/M
+Moulton/M
+Mount/M
+Mountbatten/M
+Mountie/MS
+Moussorgsky/M
+Mouthe/M
+Mouton/M
+Mowgli/M
+Moyra/M
+Mozambican/SM
+Mozambique/M
+Mozart/M
+Mozilla/M
+Mozillian/MS
+Mr/SM
+Ms/S
+Msgr
+Mt
+Muawiya/M
+Mubarak/M
+Mueller/M
+Muenster/MS
+Mugabe/M
+Muhammad/M
+Muhammadan/MS
+Muhammadanism/SM
+Muir/M
+Mujib/M
+Mulder/M
+Mullen/M
+Muller/M
+Mulligan/M
+Mullikan/M
+Mullins/M
+Mulroney/M
+Multan/M
+Multics
+Mumbai/M
+Mumford/M
+Munch/M
+Munchausen/M
+Muncie/M
+Munich/M
+Munoz/M
+Munro/M
+Munroe/M
+Munster/M
+Muppet/M
+Murasaki/M
+Murat/M
+Murchison/M
+Murcia
+Murdoch/M
+Murdock/M
+Murfreesboro/M
+Muriel/M
+Murillo/M
+Murine/M
+Murmansk/M
+Murphy/M
+Murray/M
+Murrieta/M
+Murrow/M
+Murrumbidgee/M
+Murry/M
+Muscat/M
+Muscovite/M
+Muscovy/M
+Muse/M
+Musharraf/M
+Musial/M
+Muskegon/M
+Muskogee/M
+Muslim/MS
+Mussolini/M
+Mussorgsky/M
+Mutsuhito/M
+Muzak/M
+My's
+MySQL/M
+MySpace/M
+MySpell/M
+Myanmar/M
+Mycenae/M
+Mycenaean/M
+Myer/SM
+Myers/M
+Mylar/MS
+Myles/M
+Myra/M
+Myrdal/M
+Myriam/M
+Myrna/M
+Myron/M
+Myrtle/M
+Mysore/M
+Myst/M
+Mnchhausen/M
+N'Djamena
+N/MD
+NAACP/M
+NAFTA/M
+NASA/M
+NASCAR/M
+NASDAQ/M
+NATO/M
+NB
+NBA/M
+NBC/M
+NBS
+NC
+NCAA/M
+NCO
+ND
+NE/M
+NEH
+NF
+NFC
+NFL/M
+NGO/SM
+NH
+NHL/M
+NIH
+NIMBY
+NJ
+NLRB
+NM
+NORAD/M
+NOW
+NP
+NPR/M
+NR
+NRA
+NRC
+NS
+NSA/M
+NSC
+NSF
+NSFW
+NSPR/M
+NSS/M
+NT
+NV
+NVIDIA/M
+NW/M
+NWT
+NY
+NYC
+NYSE
+NZ
+Na/M
+Nabisco/M
+Nabokov/M
+Nada/M
+Nader/M
+Nadia/M
+Nadine/M
+Nadu/M
+Nadya/M
+Nagasaki/M
+Nagoya/M
+Nagpur/M
+Nagy/M
+Nahuatl/MS
+Nahum/M
+Naipaul/M
+Nair/M
+Nairobi/M
+Naismith/M
+Nam/M
+Namath/M
+Namibia/M
+Namibian/MS
+Nampa/M
+Nan/M
+Nana/M
+Nanak/M
+Nance/M
+Nanchang/M
+Nanci/M
+Nancy/M
+Nanette/M
+Nani/M
+Nanjing/M
+Nanni/M
+Nannie/M
+Nanon/M
+Nanook/M
+Nansen/M
+Nantes/M
+Nantucket/M
+Naomi/M
+Napa/M
+Naphtali/M
+Napier/M
+Naples/M
+Napoleon/MS
+Napoleonic/M
+Napster/M
+Nara
+Narcissus/M
+Nari/M
+Narmada/M
+Narnia/M
+Narraganset
+Narragansett/M
+Naruto/M
+Nash/M
+Nashua/M
+Nashville/M
+Nassau/M
+Nasser/M
+Nat/M
+Nata/M
+Natal's
+Natale/M
+Natalia/M
+Natalie/M
+Natalya/M
+Natasha/M
+Natchez/M
+Nate/MN
+Nathalie/M
+Nathan/SM
+Nathanael
+Nathanial/M
+Nathaniel/M
+Nathans/M
+Nation/M
+Nationwide/M
+Natividad/M
+Nativity/M
+Natty's
+Nature
+Naugahyde/M
+Nauru/M
+Nautilus/M
+Navajo/SM
+Navajoes
+Navarre/M
+Navarro/M
+Navratilova/M
+Navy
+Nazarene/M
+Nazareth/M
+Nazca/M
+Nazi/SM
+Nazism/MS
+Nb/M
+Nd/M
+Ndjamena/M
+Ne/M
+NeWS
+NeWSes
+Neal/M
+Neale/M
+Nealy/M
+Neanderthal/SM
+Neapolitan/M
+Neb
+Nebr
+Nebraska/M
+Nebraskan/MS
+Nebuchadnezzar/M
+Necko/M
+Ned/M
+Neda/M
+Nedda/M
+Neddy/M
+Nederland/SM
+Neel/M
+Neely/M
+Nefertiti/M
+Negev/M
+Negress/MS
+Negritude
+Negro/MS
+Negroes
+Negroid/SM
+Negros/M
+Nehemiah/M
+Nehru/M
+Neil/SM
+Neill/M
+Nelda/M
+Nell/M
+Nelle/M
+Nelli/M
+Nellie/M
+Nelly/M
+Nels/N
+Nelsen/M
+Nelson/M
+Nembutal/M
+Nemesis/M
+Neo/M
+Neogene/M
+Neolithic
+Nepal/M
+Nepalese/M
+Nepali/MS
+Neptune/M
+Nereid/M
+Nerf/M
+Nerissa/M
+Nero/M
+Neruda/M
+Nescafe/M
+Nessa/M
+Nesselrode/M
+Nessie/M
+Nesta/M
+Nester/M
+Nestle/M
+Nestor/M
+Nestorius/M
+NetBSD/M
+Netflix/M
+Netherlander/SM
+Netherlands/M
+Netscape/M
+Netta/M
+Nettie/M
+Netzahualcoyotl/M
+Nev/M
+Neva/M
+Nevada/M
+Nevadan/SM
+Nevadian
+Nevil/M
+Nevile/M
+Neville/M
+Nevin/MS
+Nevis/M
+Nevsky/M
+Newark/M
+Newburgh/M
+Newcastle/M
+Newfoundland/MRS
+Newman/M
+Newport/M
+Newsweek/M
+Newton/M
+Newtonian/M
+NexTag/M
+Nexis/M
+Nextel/M
+Ngaliema/M
+Nguyen/M
+Ni/M
+Niagara/M
+Nial/M
+Niall/M
+Niamey/M
+Nibelung/M
+Nicaea/M
+Nicaragua/M
+Nicaraguan/SM
+Niccolo/M
+Nice/M
+Nicene/M
+Nicephori/M
+Nichiren/M
+Nichol/SM
+Nicholas/M
+Nichole/M
+Nichols/M
+Nicholson/M
+Nick/M
+Nickelodeon/M
+Nicki/M
+Nickie/M
+Nicklaus/M
+Nicko/M
+Nickolas/M
+Nicky/M
+Nico/M
+Nicobar/M
+Nicodemus/M
+Nicol/M
+Nicola/SM
+Nicolai
+Nicolas/M
+Nicole/M
+Nicolette/M
+Nicolis
+Nicolle/M
+Nicosia/M
+Niebuhr/M
+Niel/SM
+Nielsen/M
+Nietzsche/M
+Nieves/M
+Nigel/M
+Niger/M
+Nigeria/M
+Nigerian/MS
+Nigeriana/M
+Nigerien/M
+Nightingale/M
+Nijinsky/M
+Nike/M
+Niki/M
+Nikita/M
+Nikkei/M
+Nikki/M
+Niko/SM
+Nikola/SM
+Nikolai/M
+Nikolaos/M
+Nikolaus/M
+Nikolayev/M
+Nikon/M
+Nile/SM
+Nils
+Nilson/M
+Nimitz/M
+Nimrod/M
+Nina/M
+Ninette/M
+Nineveh/M
+Ninon/M
+Nintendo/M
+Niobe/M
+Nippon/M
+Nipponese/M
+Nirenberg/M
+Nirvana/M
+Nisan/M
+Nisei/M
+Nissan/M
+Nita/M
+Niue/M
+Nivea/M
+Niven/M
+Nixon/M
+Nkrumah/M
+No/SM
+NoDoz/M
+Noah/M
+Noam/M
+Nobel/M
+Nobelist/MS
+Noble/M
+Noe/M
+Noel/SM
+Noelle/M
+Noemi/M
+Nokia/M
+Nola/M
+Nolan/M
+Noland/M
+Noll/M
+Nome/M
+Nomi/M
+Nona/M
+Noni/M
+Nonie/M
+Nonna/M
+Nootka/M
+Nora/M
+Norah/M
+Norbert/M
+Norberto/M
+Nordic/MS
+Noreen/M
+Norfolk/M
+Noriega/M
+Norma/M
+Normal/M
+Norman/MS
+Normand/M
+Normandy/M
+Norplant/M
+Norrie/M
+Norris/M
+Norse/M
+Norseman/M
+Norsemen/M
+Nortel/M
+North/M
+Northampton/M
+Northeast/MS
+Northern/MR
+Northerner/M
+Northrop/M
+Northrup/M
+Norths
+Northwest/SM
+Norton/M
+Norw
+Norway/M
+Norwegian/SM
+Norwich/M
+Nosferatu/M
+Nostradamus/M
+Notre
+Nottingham/M
+Nouakchott/M
+Noumea/M
+Nov/M
+Nova/M
+Novartis/M
+November/MS
+Novgorod/M
+Novocain/MS
+Novocaine
+Novokuznetsk/M
+Novosibirsk/M
+Nowell/M
+Noxzema/M
+Noyce/M
+Noyes/M
+Np/M
+Nubia/M
+Nubian/M
+Nukualofa/M
+Numbers/M
+Nunavut/M
+Nunez/M
+Nunki/M
+Nuremberg/M
+Nureyev/M
+NutraSweet/M
+NyQuil/M
+Nyasa/M
+Nye/M
+Nyerere/M
+Nyssa/M
+O'Brien/M
+O'Casey/M
+O'Connell/M
+O'Connor/M
+O'Donnell/M
+O'Hara/M
+O'Higgins/M
+O'Keeffe/M
+O'Neil/M
+O'Neill/M
+O'Rourke/M
+O'Toole/M
+O/SM
+OAS/M
+OB
+OCR
+OD/SM
+OE
+OED
+OH
+OHSA/M
+OJ
+OK/SMDG
+OMB/M
+OMG
+ON
+OPEC/M
+OR
+OS/M
+OSHA/M
+OSes
+OT
+OTB
+OTC
+OTOH
+Oahu/M
+Oakland/M
+Oakley/M
+Oates/M
+Oaxaca/M
+Ob/MD
+Obadiah/M
+Obama/M
+Obamacare
+Obed/M
+Oberlin/M
+Oberon/M
+Obie
+Ocala/M
+Ocaml/M
+Occam/M
+Occident
+Occidental/MS
+Oceania/M
+Oceanside
+Oceanus/M
+Ochoa/M
+Oct/M
+Octavia/M
+Octavian/M
+Octavio/M
+Octavius/M
+October/SM
+Odell/M
+Oder/M
+Odessa/M
+Odets/M
+Odette/M
+Odie/M
+Odin/M
+Odis/M
+Odo/M
+Odom/M
+Ody/M
+Odysseus/M
+Odyssey/M
+Oedipal/M
+Oedipus/M
+Oersted/M
+Ofelia/M
+Offenbach/M
+OfficeMax/M
+Ogbomosho/M
+Ogden/M
+Ogilvy/M
+Oglethorpe/M
+Ohio/M
+Ohioan/SM
+Oise/M
+Ojibwa/SM
+Okayama
+Okeechobee/M
+Okefenokee/M
+Okhotsk/M
+Okinawa/M
+Okinawan
+Okla
+Oklahoma/M
+Oklahoman/M
+Oktoberfest/M
+Ola/M
+Olaf/M
+Olajuwon/M
+Olav/M
+Oldenburg/M
+Oldfield/M
+Oldsmobile/M
+Olduvai/M
+Olen/M
+Olenek/M
+Olga/M
+Oligocene/M
+Olimpia/M
+Olin/M
+Olive/MR
+Oliver/M
+Olivetti/M
+Olivia/M
+Olivier/M
+Ollie/M
+Olly/M
+Olmec/M
+Olmsted/M
+Olsen/M
+Olson/M
+Olwen/M
+Olympe/M
+Olympia/SM
+Olympiad/MS
+Olympian/MS
+Olympic/SM
+Olympics/M
+Olympus/M
+Omaha/MS
+Oman/M
+Omani/MS
+Omar/M
+Omayyad/M
+Omdurman/M
+Omnipotent
+Omsk/M
+Onassis/M
+Oneal/M
+Onega/M
+Onegin/M
+Oneida/MS
+Onion/M
+Ono/M
+Onondaga/MS
+Onsager/M
+Ont
+Ontarian
+Ontario/M
+Oona/M
+Oort/M
+Opal/M
+Opaline/M
+Opel/M
+OpenBSD/M
+OpenOffice/M
+Ophelia/M
+Ophiuchus/M
+Oppenheimer/M
+Opposition
+Oprah/M
+Ora/M
+Oracle/M
+Oran/M
+Orange/M
+Oranjestad/M
+Orazio/M
+Orbison/M
+Ordovician/M
+Ore/N
+Oreg
+Oregon/M
+Oregonian/SM
+Orel
+Orem/M
+Oren/M
+Oreo/M
+Orestes/M
+Oriana/M
+Orient/M
+Oriental/MS
+Orientalism
+Orin/M
+Orinoco/M
+Orion/M
+Oriya/M
+Orizaba/M
+Orkney/M
+Orlan/M
+Orland/M
+Orlando/M
+Orleans/M
+Orlon/MS
+Orly/M
+Orpheus/M
+Orphic/M
+Orr/MN
+Orren/M
+Orrin/M
+Orson/M
+Ortega/M
+Orthodox
+Ortiz/M
+Orton/M
+Orv/M
+Orval/M
+Orville/M
+Orwell/M
+Orwellian/M
+Oryza/M
+Os/M
+Osage/MS
+Osaka/M
+Osbert/M
+Osborn/M
+Osborne/M
+Osbourne/M
+Oscar/MS
+Osceola/M
+Osgood/M
+Oshawa/M
+Oshkosh/M
+Osiris/M
+Oslo/M
+Osman/M
+Osmond/M
+Osmund/M
+Ossie/M
+Ostrogoth/M
+Ostwald/M
+Osvaldo/M
+Oswald/M
+Othello/M
+Otho/M
+Otis/M
+Ottawa/SM
+Ottilie/M
+Otto/M
+Ottoman/M
+Ottomana/M
+Ouagadougou/M
+Ouija/MS
+Ovid/M
+Owen/SM
+Owens/M
+Owensboro/M
+Oxford/SM
+Oxley/M
+Oxnard/M
+Oxonian/M
+Oxus/M
+Oxycontin/M
+Oz/M
+Ozark/MS
+Ozarks/M
+Ozymandias/M
+Ozzie/M
+Ozzy/M
+P/MN
+PA/M
+PAC/M
+PARC/S
+PASCAL
+PBS/M
+PBX
+PC/SM
+PCB
+PCMCIA
+PCP/M
+PD
+PDA/SM
+PDF/SM
+PDQ
+PDT
+PE
+PET/M
+PFC
+PG
+PGP
+PHP/M
+PIN
+PJ's
+PLO/M
+PM/SMDG
+PMS/M
+PNG/SM
+PO
+POTUS/M
+POW/M
+PP
+PPS
+PR
+PRC/M
+PRNewswire/M
+PRO
+PS/M
+PST/M
+PT
+PTA/M
+PTO
+PVC/M
+PW
+PX
+Pa/M
+Paar/M
+Pablo/M
+Pablum/M
+Pabst/M
+Pace/M
+Pacheco/M
+Pacific/M
+Pacino/M
+Packard/M
+Paco/M
+Padang
+Paderewski/M
+Padgett/M
+Padilla/M
+Padraic/M
+Padraig/M
+Paganini/M
+Page/M
+Paglia/M
+Pahlavi/M
+Paige/M
+Paine/M
+Paiute/SM
+Pakistan/M
+Pakistani/SM
+Palau/M
+Palembang/M
+Paleocene/M
+Paleogene/M
+Paleolithic/M
+Paleozoic/M
+Palermo/M
+Palestine/M
+Palestinian/SM
+Palestrina/M
+Paley/M
+Palikir/M
+Palin/M
+Palisades/M
+Palladio/M
+Palmdale/M
+Palmer/M
+Palmerston/M
+Palmolive/M
+Palmyra/M
+Paloma/M
+Palomar/M
+Pam/M
+Pamela/M
+Pamirs/M
+Pampers/M
+Pan/M
+Panama/SM
+Panamanian/MS
+Panasonic/M
+Pancho/M
+Pandora/M
+Pangaea/M
+Pankhurst/M
+Panmunjom/M
+Pansy/M
+Pantagruel/M
+Pantaloon/M
+Pantheon/M
+Panza/M
+Paola/M
+Paolina/M
+Paolo/M
+Papageno/M
+Papua/M
+Paracelsus/M
+Paraclete/M
+Paradise
+Paraguay/M
+Paraguayan/MS
+Paralympic/S
+Paramaribo/M
+Paramount/M
+Parana/M
+Paran/M
+Parcheesi/M
+Pareto/M
+Paris/M
+Parisian/MS
+Park/SMR
+Parke/M
+Parker/M
+Parkersburg/M
+Parkinson/M
+Parkinsonism
+Parkman/M
+Parks/M
+Parliament/M
+Parmenides
+Parmesan/MS
+Parnassus/MS
+Parnell/M
+Parr/M
+Parrish/M
+Parsee/SM
+Parsi/MS
+Parsifal/M
+Parsons/M
+Parthenon/M
+Parthia/M
+Pasadena/M
+Pascagoula/M
+Pascal/SM
+Pascale/M
+Pasco/M
+Pasquale/M
+Passion/SM
+Passover/MS
+Pasternak/M
+Pasteur/M
+Pat/MN
+Patagonia/M
+Patagonian/M
+Pate/M
+Patel/M
+Paten/M
+Paterson/M
+Patna/M
+Paton
+Patric/M
+Patrica/M
+Patrice/M
+Patricia/M
+Patricio/M
+Patrick/M
+Patrizia/M
+Patsy/M
+Patten/M
+Patterson/M
+Patti/M
+Pattie/M
+Patton/M
+Patty/M
+Paul/GM
+Paula/M
+Paule/M
+Paulette/M
+Pauli/M
+Paulie/M
+Paulina/M
+Pauline/M
+Pauling/M
+Paulo/M
+Pauly/M
+Pavarotti/M
+Pavel/M
+Pavia/M
+Pavlov/M
+Pavlova/M
+Pavlovian/M
+Pawnee/SM
+Paxton
+PayPal/M
+Payne/M
+Payton/M
+Pb/M
+Pd/M
+Peabody/M
+Peace/M
+Peadar/M
+Peale/M
+Pearce/M
+Pearl/M
+Pearle/M
+Pearlie/M
+Pearson/M
+Peary/M
+Pechora/M
+Peck/M
+Peckinpah/M
+Pecos/M
+Peder/M
+Pedro/M
+Peel/M
+Peg/M
+Pegasus/MS
+Pegeen/M
+Peggy/M
+Pei/M
+Peiping/M
+Peirce/M
+Pekinese/M
+Peking/SM
+Pekingese/SM
+Pele/M
+Pelee/M
+Peloponnese/M
+Pembroke/M
+Pen/M
+Pena/M
+Penderecki/M
+Penelope/M
+Penn/M
+Penna
+Penney/M
+Pennington/M
+Pennsylvania/M
+Pennsylvanian/MS
+Penny/M
+Pennzoil/M
+Penrod/M
+Pensacola/M
+Pentagon/M
+Pentateuch/M
+Pentax/M
+Pentecost/SM
+Pentecostal/MS
+Pentecostalism
+Pentium/SM
+Peoria/M
+Pepe/M
+Pepi/M
+Pepin/M
+Pepita/M
+Pepsi/M
+Pepys/M
+Pequot/M
+Perceval
+Percheron/M
+Percival/M
+Percy/M
+Perelman/M
+Perez/M
+Peri/M
+Periclean/M
+Pericles/M
+Perkin/MS
+Perkins/M
+Perl/SM
+Perla/M
+Perle/M
+Perm/M
+Permalloy/M
+Permian/M
+Pernod/M
+Peron/M
+Perot/M
+Perri/MR
+Perrier/M
+Perrine/M
+Perry/M
+Perseid/M
+Persephone/M
+Persepolis/M
+Perseus/M
+Pershing/M
+Persia/M
+Persian/SM
+Persis
+Perth/M
+Peru/M
+Peruvian/MS
+Peshawar/M
+Peta/M
+Petain/M
+Petaluma/M
+Pete/RMZ
+Peter/M
+Peterborough/M
+Peters/MN
+Petersen/M
+Peterson/M
+Petey/M
+Petr/M
+Petra/M
+Petrarch/M
+Petronella/M
+Petronilla/M
+Petty/M
+Peugeot/M
+Peyronie's
+Peyton/M
+Pfc
+Pfizer/M
+PhD/M
+Phaedra/M
+Phaethon/M
+Phanerozoic/M
+Pharaoh/M
+Pharaohs
+Pharisaic
+Pharisaical
+Pharisee/MS
+Phebe
+Phekda/M
+Phelps/M
+Phidias/M
+Phil/MY
+Philadelphia/M
+Philby/M
+Philemon/M
+Philip/MS
+Philippa/M
+Philippe/M
+Philippians/M
+Philippine/SM
+Philippines/M
+Philips/M
+Philistine/M
+Phillida/M
+Phillip/SM
+Phillipa/M
+Phillipe/M
+Phillips/M
+Phillis/M
+Philly/M
+Philomena/M
+Phineas/M
+Phipps/M
+Phobos/M
+Phoebe/M
+Phoenicia/M
+Phoenician/SM
+Phoenix/M
+Photoshop/M
+Photostat/MS
+Photostatted
+Photostatting
+Phrygia/M
+Phyllida/M
+Phyllis/M
+Pia/M
+Piaf/M
+Piaget/M
+Pianola/M
+Picasso/M
+Piccadilly/M
+Pickering/M
+Pickett/M
+Pickford/M
+Pickwick/M
+Pict/M
+Pictor
+Piedmont/M
+Pierce/M
+Pierre/M
+Pierrette/M
+Pierrot/M
+Pierson/M
+Pieter/M
+Pietra/M
+Pietro/M
+Pike/M
+Pilate/MS
+Pilates/M
+Pilcomayo/M
+Pilgrim/SM
+Pillsbury/M
+Pinatubo/M
+Pinchas/M
+Pincus/M
+Pindar/M
+Pinkerton/M
+Pinocchio/M
+Pinochet/M
+Pinter/M
+Pinyin
+Piotr/M
+Pippa/M
+Pippin/M
+Piraeus/M
+Pirandello/M
+Pisa/M
+Pisces/M
+Pisistratus/M
+Pissaro/M
+Pitcairn/M
+Pitt/SM
+Pittman/M
+Pitts/M
+Pittsburgh/M
+Pittsfield/M
+Pius/M
+Pixar/M
+Pizarro/M
+Pkwy
+Pl
+Place
+Planck/M
+Plano
+Plantagenet/M
+Plasticine/M
+Plataea/M
+Plath/M
+Plato/M
+Platonic
+Platonism/M
+Platonist/M
+Platte/M
+Plautus/M
+PlayStation/M
+Playboy/M
+Playtex/M
+Pleiades/M
+Pleistocene/M
+Plexiglas/MS
+Pliny/M
+Pliocene/SM
+Plutarch/M
+Pluto/M
+Plymouth/M
+Pm/M
+Po/M
+Pocahontas/M
+Pocatello/M
+Pocono/SM
+Poconos/M
+Podgorica/M
+Podhoretz/M
+Podunk/M
+Poe/M
+Pogo/M
+Poincare/M
+Poincar/M
+Poiret/M
+Poirot/M
+Poisson/M
+Poitier/M
+Pokemon/M
+Pokmon/M
+Pol/MY
+Poland/M
+Polanski/M
+Polaris/M
+Polaroid/MS
+Pole/SM
+Polish/M
+Politburo/M
+Polk/M
+Pollard/M
+Pollock/M
+Pollux/M
+Polly/M
+Pollyanna/M
+Polo/M
+Polska
+Poltava/M
+Polyhymnia/M
+Polynesia/M
+Polynesian/MS
+Polyphemus/M
+Pomerania/M
+Pomeranian/M
+Pomona/M
+Pompadour/M
+Pompeian
+Pompeii/M
+Pompey/M
+Ponce/M
+Pontchartrain/M
+Pontiac/M
+Pontianak/M
+Pooh/M
+Poole/M
+Poona/M
+Pope/M
+Popeye/M
+Popocatepetl/M
+Popper/M
+Poppins/M
+Popsicle/M
+Porfirio/M
+Porrima/M
+Porsche/M
+Port/MR
+Porter/M
+Porterville/M
+Portia/M
+Portland/M
+Porto/M
+Portsmouth/M
+Portugal/M
+Portuguese/M
+Poseidon/M
+Post/M
+PostScript/M
+PostgreSQL/M
+Potemkin/M
+Potomac/M
+Potsdam/M
+Pottawatomie/M
+Potter/M
+Potts/M
+Pottstown/M
+Poughkeepsie/M
+Poul/M
+Pound/M
+Poussin/M
+Powell/M
+PowerPC/M
+PowerPoint/M
+Powers/M
+Powhatan/M
+Poynter/M
+Poznan/M
+Pr/M
+Prada/M
+Prado/M
+Praetorian/M
+Praetoriana/M
+Prague/M
+Praia/M
+Prakrit/M
+Pratchett/M
+Pratt/M
+Pravda/M
+Praxiteles/M
+Preakness/M
+Precambrian/M
+Preminger/M
+Premyslid/M
+Prensa/M
+Prentice/M
+Prentiss/M
+Pres
+Presbyterian/SM
+Presbyterianism/MS
+Prescott/M
+Presley/M
+Preston/M
+Pretoria/M
+Priam/M
+Pribilof/M
+Price/M
+Priceline/M
+Priestley/M
+Prince/M
+Princeton/M
+Principe/M
+Prinz
+Pris
+Prisca/M
+Priscilla/M
+Prius/M
+Private
+Prix
+ProQuest/M
+Procrustean/M
+Procrustes/M
+Procter/M
+Procyon/M
+Prof
+Prohibition
+Prokofiev/M
+Promethean/M
+Prometheus/M
+Prophets
+Proserpina/M
+Proserpine/M
+Protagoras/M
+Proterozoic/M
+Protestant/MS
+Protestantism/SM
+Proteus/M
+Proudhon/M
+Proust/M
+Provencal/MS
+Provence/M
+Provenal/M
+Proverbs
+Providence/SM
+Provo/M
+Prozac/MS
+Pru/M
+Prudence/M
+Prudential/M
+Prudy/M
+Prue/M
+Pruitt/M
+Prussia/M
+Prussian/MS
+Prut/M
+Pryce/M
+Pryor/M
+Psalms/M
+Psalter/MS
+Pseudomonas/M
+Psyche/M
+Pt/M
+Ptah/M
+Ptolemaic/M
+Ptolemy/SM
+Pu/M
+PubMed/M
+Puccini/M
+Puck/M
+Puckett/M
+Puebla/M
+Pueblo/M
+Puerto
+Puget/M
+Pugh/M
+Pulaski/M
+Pulitzer/M
+Pullman/MS
+Punch/M
+Punic/M
+Punjab/M
+Punjabi/M
+Purana/M
+Purcell/M
+Purdue/M
+Purgatory
+Purim/MS
+Purina/M
+Puritan/M
+Puritanism/MS
+Purus/M
+Pusan/M
+Pusey/M
+Pushkin/M
+Pushtu/M
+Putin/M
+Putnam/M
+Puzo/M
+Pvt
+PyTorch/M
+Pygmalion/M
+Pygmy/SM
+Pyle/M
+Pym/M
+Pynchon/M
+Pyongyang/M
+Pyotr/M
+Pyrenees/M
+Pyrex/MS
+Pyrrhic/M
+Pythagoras/M
+Pythagorean/M
+Pythias/M
+Python/M
+Ptain/M
+Prto/M
+Q
+QA
+QB
+QC
+QED
+QM
+QWERTY
+Qaddafi/M
+Qaeda/M
+Qantas/M
+Qatar/M
+Qatari/MS
+Qingdao/M
+Qinghai/M
+Qiqihar/M
+Qom/M
+Quaalude/M
+Quaker/MS
+Quakerism/SM
+Qualcomm/M
+Quaoar/M
+Quasimodo/M
+Quaternary/M
+Quayle/M
+Que
+Quebec/M
+Quebecker
+Quebecois/M
+Quechua/M
+Queen/MS
+Queenie/M
+Queens/M
+Queensland/M
+Quent/M
+Quentin/M
+Quetzalcoatl/M
+Quezon/M
+QuickList/M
+QuickTime/M
+Quillan/M
+Quincey/M
+Quincy/M
+Quinlan/M
+Quinn/M
+Quint/M
+Quinta/M
+Quintana/M
+Quintilian/M
+Quintin/M
+Quinton/M
+Quintus/M
+Quirinal/M
+Quisling/M
+Quito/M
+Quixote/M
+Quixotism/M
+Qumran/M
+Quonset/M
+Qur'an/MS
+Qur'anic
+Quran
+Quranic
+Qubecois/M
+Qwest/M
+R/MD
+RAF/M
+RAM/SM
+RBI
+RC
+RCA/M
+RCMP
+RD
+RDA
+RDS/M
+REIT
+REM/SM
+RF
+RFC/S
+RFD
+RI
+RIF
+RIP
+RISC
+RN/M
+RNA/M
+ROFL
+ROM/M
+ROTC/M
+RP
+RR
+RSFSR
+RSI
+RSV
+RSVP
+RTFM
+RV/SM
+Ra/M
+Rab/M
+Rabat/M
+Rabelais/M
+Rabelaisian/M
+Rabi
+Rabin/M
+Rachael/M
+Rachel/M
+Rachelle/M
+Rachmaninoff/M
+Racine/M
+Radcliff/M
+Radcliffe/M
+Rae/M
+Raf/M
+Rafa/M
+Rafael/M
+Rafe/M
+Raff/M
+Raffaello/M
+Rafferty/M
+Raffles/M
+Rafi/M
+Ragnar/M
+Ragnarok/M
+Ragnark/M
+Rahel/M
+Raimondo/M
+Raimund/M
+Raimundo/M
+Raina/M
+Raine/MR
+Rainer/M
+Rainier/M
+Raleigh/M
+Ralf/M
+Ralph/M
+Rama/M
+Ramada/M
+Ramadan/MS
+Ramakrishna/M
+Ramanujan/M
+Ramayana/M
+Rambo/M
+Ramirez/M
+Ramiro/M
+Ramon/M
+Ramona/M
+Ramos/M
+Ramsay/M
+Ramses/M
+Ramsey/M
+Rana/M
+Rance/M
+Rand/M
+Randa/M
+Randal/M
+Randall/M
+Randell/M
+Randi/M
+Randolph/M
+Randy/M
+Rangoon/M
+Rani/M
+Rankin/M
+Rankine/M
+Raoul/M
+Raphael/M
+Rappaport/M
+Rapunzel/M
+Raquel/M
+Rasalgethi/M
+Rasalhague/M
+Rasmussen/M
+Rasputin/M
+Rasta
+Rastaban/M
+Rastafarian/MS
+Rastafarianism
+Rather/M
+Ratliff/M
+Raul/M
+Ravel/M
+Ravi/M
+Ravid/M
+Raviv/M
+Rawalpindi/M
+Rawley/M
+Ray/M
+RayBan/M
+Rayburn/M
+Raye/M
+Rayleigh/M
+Raymond/M
+Raymund/M
+Raymundo/M
+Rayna/M
+Rayner/M
+Raynor/M
+Rb/M
+Rd
+Re/M
+Rea/M
+Reade/G
+Reading/M
+Reagan/M
+Reaganomics/M
+Realtor/M
+Reasoner/M
+Reba/M
+Rebeca/M
+Rebecca/M
+Rebecka/M
+Rebekah/M
+Recife/M
+Reconstruction/M
+Red/SM
+Redd/GM
+Redding/M
+Redeemer/M
+Redford/M
+Redgrave/M
+Redis/M
+Redmond/M
+Redshift/M
+Ree/DSM
+Reebok/M
+Reece/M
+Reed/M
+Reena/M
+Reese/M
+Reeves/M
+Reformation/MS
+Refugio/M
+Regan/M
+Regen/M
+Reggie/M
+Regina/M
+Reginae/M
+Reginald/M
+Regine/M
+Regor/M
+Regulus/M
+Rehnquist/M
+Reich/M
+Reichstag's
+Reid/M
+Reiko/M
+Reilly/M
+Reina/M
+Reinaldo/M
+Reine/M
+Reinhard/M
+Reinhardt/M
+Reinhold/M
+Remanence
+Remanent
+Remarque/M
+Rembrandt/M
+Remington/M
+Remus/M
+Remy/M
+Rena/M
+Renae/M
+Renaissance/SM
+Renaldo/M
+Renard/M
+Renascence
+Renata/M
+Renate/M
+Renato/M
+Renaud/M
+Renault/M
+Rene/M
+Renee/M
+Renie/M
+Rennie/M
+Reno/M
+Renoir/M
+Rep
+Representative
+Republican/SM
+Republicanism
+Requiem/MS
+Resistance
+Restoration/M
+Resurrection
+Reta/M
+Reuben/M
+Reunion/M
+Reuters/M
+Reuther/M
+Reuven/M
+Rev
+Reva/M
+Revelation/SM
+Revelations/M
+Revere/M
+Reverend/M
+Revlon/M
+Rex/M
+Rey/M
+Reyes/M
+Reykjavik/M
+Reyna/M
+Reynaldo/M
+Reynard/M
+Reynold/MS
+Reynolds/M
+Rf/M
+Rh/M
+Rhea/M
+Rhee/M
+Rheingau/M
+Rhenish/M
+Rhett/M
+Rhianna/M
+Rhiannon/M
+Rhine/M
+Rhineland/M
+Rhoda/M
+Rhode/S
+Rhodes/M
+Rhodesia/M
+Rhodesian
+Rhona/M
+Rhonda/M
+Rhone/M
+Rhys/M
+Ribbentrop/M
+Ric/M
+Rica/M
+Ricard/M
+Ricardo/M
+Riccardo/M
+Rice/M
+Rich/M
+Richard/MS
+Richards/M
+Richardson/M
+Richart/M
+Richelieu/M
+Richie/M
+Richmond/M
+Richter/M
+Richthofen/M
+Rick/M
+Rickard/M
+Rickenbacker/M
+Rickert/M
+Rickey/M
+Ricki/M
+Rickie/M
+Rickover/M
+Ricky/M
+Rico/M
+Riddle/M
+Ride/M
+Riefenstahl/M
+Riel/M
+Riemann/M
+Riesling/MS
+Riga/M
+Rigel/M
+Riggs/M
+Right
+Rigoberto/M
+Rigoletto/M
+Rik/M
+Riki/M
+Rikki/M
+Riley/M
+Rilke/M
+Rimbaud/M
+Rina/M
+Rinaldo/M
+Ringling/M
+Ringo/M
+Rio/SM
+Riordan/M
+Rios/M
+Ripley/M
+Risa/M
+Risorgimento/M
+Rita/M
+Ritalin/M
+Ritchie/M
+Ritz/M
+Riva/SM
+Rivas/M
+Rivera/M
+Rivers/M
+Riverside/M
+Riviera/MS
+Riyadh/M
+Rizal/M
+Rn/M
+Roach/M
+Roanoke/M
+Roarke/M
+Rob/M
+Robb/M
+Robbie/M
+Robbin/MS
+Robbins/M
+Robby/M
+Roberson/M
+Robert/MS
+Roberta/M
+Roberto/M
+Roberts/M
+Robertson/M
+Robeson/M
+Robespierre/M
+Robin/M
+Robina/M
+Robinet/M
+Robinette/M
+Robinia/M
+Robinson/M
+Robitussin/M
+Robles/M
+Robson/M
+Robt/M
+Roby/M
+Robyn/M
+Rocco/M
+Roch/M
+Rocha/M
+Rochambeau/M
+Roche/M
+Rochelle/M
+Rochester/M
+Rock/M
+Rockefeller/M
+Rockford/M
+Rockies/M
+Rockne/M
+Rockwell/M
+Rocky/SM
+Rod/M
+Roda/M
+Rodd/M
+Roddenberry/M
+Roddy/M
+Roderic/M
+Roderick/M
+Roderigo/M
+Rodger/MS
+Rodgers/M
+Rodham/M
+Rodi/M
+Rodin/M
+Rodney/M
+Rodolfo/M
+Rodolph/M
+Rodolphe/M
+Rodrick/M
+Rodrigo/M
+Rodriguez/M
+Rodriquez/M
+Roeg/M
+Roentgen
+Rog/MRZ
+Rogelio/M
+Roger/M
+Rogers/M
+Roget/M
+Roi/SM
+Rojas/M
+Roku/M
+Rolaids/M
+Roland/M
+Rolando/M
+Roldan/M
+Rolex/M
+Rolf
+Rolfe/M
+Rolland/M
+Rollerblade/M
+Rollie/M
+Rollin/MS
+Rollins/M
+Rollo
+Rolodex/M
+Rolph/M
+Rolvaag/M
+Rom
+Roma/M
+Romain/M
+Roman/MS
+Romana/M
+Romanesque/MS
+Romania/M
+Romanian/MS
+Romano/M
+Romanov/M
+Romans/M
+Romansh/M
+Romantic
+Romanticism
+Romany/SM
+Rome/SM
+Romeo/M
+Romero/M
+Rommel/M
+Romney/M
+Romola/M
+Romulus/M
+Romy/M
+Ron/M
+Rona/M
+Ronald/M
+Ronda/M
+Ronni/M
+Ronnie/M
+Ronny/M
+Ronstadt/M
+Rontgen
+Rooney/M
+Roosevelt/M
+Root/M
+Roquefort/SM
+Rorke/M
+Rorschach/M
+Rory/M
+Ros
+Rosa/M
+Rosaleen/M
+Rosales/M
+Rosalia/M
+Rosalie/M
+Rosalind/M
+Rosalinda/M
+Rosaline/M
+Rosalyn/M
+Rosamond/M
+Rosamund/M
+Rosanna/M
+Rosanne/M
+Rosario/M
+Rosco/M
+Roscoe/M
+Rose/M
+Roseann/M
+Roseanne/M
+Roseau/M
+Rosecrans/M
+Rosella/M
+Roselle/M
+Rosemarie/M
+Rosemary/M
+Rosenberg/M
+Rosendo/M
+Rosenzweig/M
+Rosetta/M
+Rosicrucian/M
+Rosie/M
+Rosina/M
+Rosita/M
+Roslyn/M
+Ross/M
+Rossetti/M
+Rossie/M
+Rossini/M
+Rostand/M
+Rostov/M
+Rostropovich/M
+Roswell/M
+Rosy's
+Rotarian/M
+Roth/M
+Rothko/M
+Rothschild/M
+Rotterdam/M
+Rottweiler/M
+Rouault/M
+Rourke/M
+Rousseau/M
+Routledge/M
+Rove/RM
+Rover/M
+Rowan/M
+Rowe/M
+Rowen/M
+Rowena/M
+Rowland/M
+Rowling/M
+Roxana/M
+Roxane/M
+Roxanna/M
+Roxanne/M
+Roxie/M
+Roxy/M
+Roy/M
+Royal/M
+Royall/M
+Royce/M
+Roz/M
+Rozelle/M
+Rte
+Ru/MH
+Rubaiyat/M
+Rubbermaid/M
+Ruben/SM
+Rubens/M
+Rubi/M
+Rubia/M
+Rubicon/MS
+Rubik/M
+Rubin/M
+Rubinstein/M
+Ruby/M
+Ruchbah/M
+Rudd/M
+Ruddy's
+Rudiger/M
+Rudolf/M
+Rudolfo/M
+Rudolph/M
+Rudy/M
+Rudyard/M
+Rufe/M
+Rufus/M
+Rugby
+Ruggiero/M
+Ruhr/M
+Ruiz/M
+Rukeyser/M
+Rumanian/SM
+Rumpelstiltskin/M
+Rumsfeld/M
+Runnymede/M
+Runyon/M
+Rupert/M
+Ruprecht/M
+Rurik
+Rush/M
+Rushdie/M
+Rushmore/M
+Ruskin/M
+Russ/M
+Russel/M
+Russell/M
+Russia/M
+Russian/SM
+Russo/M
+Rustbelt/M
+Rustin/M
+Rusty/M
+Rutan/M
+Rutger/MS
+Rutgers/M
+Ruth/M
+Rutherford/M
+Ruthie/M
+Rutledge/M
+Rutter/M
+Ruy/M
+Rwanda/MS
+Rwandan/SM
+Rwy
+Rx
+Ry
+Ryan/M
+Rydberg/M
+Ryder/M
+Ryukyu/M
+S/MN
+SA
+SAC
+SALT/M
+SAM/M
+SAP/M
+SARS/M
+SASE
+SAT
+SBA
+SC/M
+SCOTUS/M
+SCSI/M
+SD
+SDI
+SE/M
+SEATO
+SEC/M
+SF
+SGML/M
+SIDS/M
+SJ
+SJW
+SK
+SLR
+SME/SM
+SMEs/M
+SNP/SM
+SO/S
+SOB/M
+SOP/M
+SOS/M
+SOSes
+SPCA
+SPF
+SQL
+SQLite/M
+SRO
+SS
+SSA
+SSE/M
+SSN
+SSS
+SST
+SSW/M
+ST
+STD
+STOL
+SUSE/M
+SUV
+SVN/M
+SW/M
+SWAK
+SWAT
+Saab/M
+Saar/M
+Saarinen/M
+Saatchi/M
+Saba/M
+Sabbath/M
+Sabbaths
+Sabik/M
+Sabin/M
+Sabina/M
+Sabine/M
+Sabre/M
+Sabrina/M
+Sacajawea/M
+Saccharomyces/M
+Sacco/M
+Sacha/M
+Sachs/M
+Sacramento/M
+Sada/M
+Sadat/M
+Saddam/M
+Sadducee/M
+Sade/M
+Sadie/M
+Sadr/M
+Safavid/M
+Safeway/M
+Sagan/M
+Saginaw/M
+Sagittarius/MS
+Sahara/M
+Saharan/M
+Sahel/M
+Saigon/M
+Saiph/M
+Sakai/M
+Sakha/M
+Sakhalin/M
+Sakharov/M
+Saki/M
+Saks/M
+Sal/MY
+Saladin/M
+Salado/M
+Salamis/M
+Salas/M
+Salazar/M
+Saleem/M
+Salem/M
+Salerno/M
+Salesforce/M
+Salim/M
+Salinas/M
+Salinger/M
+Salisbury/M
+Salish/M
+Salk/M
+Sallee/M
+Sallie/M
+Sallust/M
+Sally/M
+Salome/M
+Salomon/M
+Salonika/M
+Salton/M
+Salvador/M
+Salvadoran/SM
+Salvadorean/MS
+Salvadorian/MS
+Salvatore/M
+Salween/M
+Salyut/M
+Sam/M
+Samantha/M
+Samar/M
+Samara/M
+Samaria
+Samaritan/MS
+Samarkand/M
+Sammie/M
+Sammy/M
+Samoa/M
+Samoan/SM
+Samoset/M
+Samoyed/M
+Sampson/M
+Samson/M
+Samsonite/M
+Samsung/M
+Samuel/M
+Samuelson/M
+San'a
+San/M
+Sana/M
+Sanaa/M
+Sanchez/M
+Sancho/M
+Sand/ZM
+Sandburg/M
+Sande/M
+Sanders/M
+Sanderson/M
+Sandi/M
+Sandie/M
+Sandinista/M
+Sandor/M
+Sandoval/M
+Sandra/M
+Sandro/M
+Sandy/M
+Sanford/M
+Sanforized/M
+Sang/MR
+Sanger/M
+Sanhedrin/M
+Sanka/M
+Sankara/M
+Sanskrit/M
+Sanson/M
+Sansone/M
+Santa/M
+Santana/M
+Santayana/M
+Santeria/M
+Santiago/M
+Santos/M
+Sapphira
+Sappho/M
+Sapporo/M
+Sara/M
+Saracen/MS
+Saragossa/M
+Sarah/M
+Sarajevo/M
+Saran/M
+Sarasota/M
+Saratov/M
+Sarawak/M
+Sarbanes/M
+Sardinia/M
+Sardinian/M
+Saree/M
+Sargasso/M
+Sarge/M
+Sargent/M
+Sargon/M
+Sarina/M
+Sarita/M
+Sarnoff/M
+Saroyan/M
+Sarto/M
+Sartre/M
+Sascha/M
+Sasha/M
+Sask
+Saskatchewan/M
+Saskatoon/M
+Sasquatch/MS
+Sassanian/M
+Sassoon/M
+Sat/M
+Satan/M
+Satanism/M
+Satanist/M
+Saturday/MS
+Saturn/M
+Saturnalia/M
+Saudi/MS
+Saul/M
+Saunders/M
+Saunderson/M
+Saundra/M
+Saussure/M
+Sauternes
+Sauveur/M
+Savage/M
+Savannah/M
+Savina/M
+Savior/M
+Savonarola/M
+Savoy/M
+Savoyard/M
+Sawyer/M
+Saxe/M
+Saxon/MS
+Saxony/M
+Sayer/MS
+Sayers/M
+Sayre/M
+Sb/M
+Sc/M
+Scala/M
+Scan
+Scandinavia/M
+Scandinavian/MS
+Scaramouch/M
+Scarborough/M
+Scarface/M
+Scarlatti/M
+Scarlett/M
+Scheat/M
+Schedar/M
+Scheherazade/M
+Schelling/M
+Schenectady/M
+Schiaparelli/M
+Schick/M
+Schiller/M
+Schindler/M
+Schlesinger/M
+Schliemann/M
+Schlitz/M
+Schloss/M
+Schmidt/M
+Schnabel/M
+Schnauzer/M
+Schneider/M
+Schoenberg/M
+Schopenhauer/M
+Schrieffer/M
+Schrodinger/M
+Schroeder/M
+Schrdinger/M
+Schubert/M
+Schultz/M
+Schulz/M
+Schumann/M
+Schumpeter/M
+Schuyler/M
+Schuylkill/M
+Schwartz/M
+Schwarz/M
+Schwarzenegger/M
+Schwarzkopf/M
+Schweitzer/M
+Schweppes/M
+Schwinger/M
+Schwinn/M
+Scientologist/SM
+Scientology/M
+Scipio/M
+Scopes/M
+Scorpio/SM
+Scorpius/M
+Scorsese/M
+Scot/SM
+Scotch/MS
+Scotchman/M
+Scotchmen/M
+Scotchwoman/M
+Scotchwomen/M
+Scotia/M
+Scotland/M
+Scotsman/M
+Scotsmen/M
+Scotswoman/M
+Scotswomen/M
+Scott/M
+Scotti/M
+Scottie/SM
+Scottish/M
+Scottsdale/M
+Scrabble/MS
+Scranton/M
+Scriabin/M
+Scribner/M
+Scripture/SM
+Scrooge/M
+Scruggs/M
+Scud/M
+Sculley/M
+Scunthorpe/M
+Scylla/M
+Scythia/M
+Scythian/M
+Se/MHN
+SeaMonkey/M
+Seaborg/M
+Seagram/M
+Seamus/M
+Sean/M
+Sears/M
+Seaside/M
+Seattle/M
+Sebastian/M
+Sebastiano/M
+Sebastien/M
+Sebring/M
+Sec
+Seconal/M
+Secretariat/M
+Secretary
+Seder/MS
+Sedna/M
+Seebeck/M
+Seeger/M
+Sega/M
+Segovia/M
+Segre/M
+Segundo/M
+Segway/S
+Seiko/M
+Seine/M
+Seinfeld/M
+Sejong/M
+Sela/M
+Selassie/M
+Selby/M
+Selectric/M
+Selena/M
+Selene/M
+Seleucid/M
+Seleucus/M
+Selig/M
+Selim/M
+Selina/M
+Seljuk/M
+Selkirk/M
+Sella/M
+Selle/MZ
+Sellers/M
+Selma/M
+Selznick/M
+Semarang/M
+Seminole/MS
+Semiramis/M
+Semite/MS
+Semitic/SM
+Semtex/M
+Sena/M
+Senate/MS
+Sendai/M
+Seneca/MS
+Senegal/M
+Senegalese/M
+Senghor/M
+Senior/M
+Sennacherib/M
+Sennett/M
+Sensurround/M
+Seoul/M
+Sep
+Sephardi/M
+Sepoy/M
+Sept/M
+September/MS
+Septuagint/MS
+Sequoya/M
+Serb/SM
+Serbia/M
+Serbian/MS
+Serena/M
+Serengeti/M
+Sergei/M
+Sergent/M
+Sergio/M
+Serpens/M
+Serra/M
+Serrano/M
+Set/M
+Seth/M
+Seton/M
+Seurat/M
+Seuss/M
+Sevastopol/M
+Severn/M
+Severus/M
+Seville/M
+Sevres/M
+Seward/M
+Sextans/M
+Sexton/M
+Seychelles/M
+Seyfert/M
+Seymour/M
+Sgt
+Shaanxi/M
+Shackleton/M
+Shaffer/M
+Shah/M
+Shaka/M
+Shaker
+Shakespeare/M
+Shakespearean/M
+Shalom's
+Shamus/M
+Shana/M
+Shandong/M
+Shandy/M
+Shane/M
+Shanghai/M
+Shani/M
+Shankara/M
+Shanna/M
+Shannon/M
+Shanta/M
+Shantung/M
+Shanxi/M
+Shapiro/M
+Shara/M
+SharePoint/M
+Shari'a/M
+Shari/M
+Sharif/M
+Sharlene/M
+Sharma/M
+Sharon/M
+Sharp/M
+Sharpe/M
+Sharron/M
+Shasta/M
+Shaula/M
+Shaun/M
+Shauna/M
+Shavian/M
+Shavuot/M
+Shaw/M
+Shawn/M
+Shawna/M
+Shawnee/SM
+Shayla/M
+Shayna/M
+Shayne/M
+Shcharansky/M
+Shea/M
+Sheba/M
+Shebeli/M
+Sheboygan/M
+Sheela/M
+Sheena/M
+Sheetrock/M
+Sheffield/M
+Sheila/M
+Sheilah/M
+Shel/MY
+Shelagh/M
+Shelby/M
+Sheldon/M
+Shelia/M
+Shell/M
+Shelley/M
+Shelly/M
+Shelton/M
+Shem/M
+Shen/M
+Shenandoah/M
+Shenyang/M
+Shenzhen/M
+Sheol/M
+Shep/M
+Shepard/M
+Shepherd/M
+Sheppard/M
+Sher/M
+Sheratan/M
+Sheraton/M
+Sheree/M
+Sheri/M
+Sheridan/M
+Sherlock/M
+Sherm/M
+Sherman/M
+Sherpa/M
+Sherri/M
+Sherrie/M
+Sherry/M
+Sherwin/M
+Sherwood/M
+Sheryl/M
+Shetland/SM
+Shetlands/M
+Shevardnadze/M
+Shevat/M
+Shi'ite/M
+Shields/M
+Shiite/MS
+Shijiazhuang/M
+Shikoku/M
+Shillong/M
+Shiloh/M
+Shina/M
+Shinto/MS
+Shintoism/MS
+Shintoist/MS
+Shir/M
+Shiraz/M
+Shirl/M
+Shirley/M
+Shiva/M
+Shockley/M
+Sholom/M
+Short/M
+Shorthorn/M
+Shoshana/M
+Shoshone/SM
+Shostakovitch/M
+Shrek/M
+Shreveport/M
+Shriner/M
+Shropshire/M
+Shula/M
+Shylock/M
+Shylockian/M
+Si/M
+Siam/M
+Siamese/M
+Sian/M
+Sib/M
+Sibelius/M
+Siberia/M
+Siberian/MS
+Sibley/M
+Sibyl/M
+Sibylla/M
+Sibylle/M
+Sichuan/M
+Sicilian/SM
+Sicily/M
+Sid/M
+Siddhartha/M
+Sidney/M
+Sidonia/M
+Siegfried/M
+Siemens/M
+Sierpinski/M
+Sierras
+Sig
+Sigismondo/M
+Sigismund/M
+Sigmund/M
+Sigrid/M
+Sigurd/M
+Sihanouk/M
+Sikh/M
+Sikhism
+Sikhs
+Sikkim/M
+Sikkimese/M
+Sikorsky/M
+Silas/M
+Silesia/M
+Silurian/SM
+Silva/M
+Silvan/M
+Silvana/M
+Silvano/M
+Silvanus/M
+Silvester/M
+Silvia/M
+Silvie/M
+Silvio/M
+Sim's
+Simenon/M
+Simeon/M
+Simmental/M
+Simmonds/M
+Simmons/M
+Simon/M
+Simona/M
+Simone/M
+Simpson/SM
+Simpsons/M
+Simpsonville/M
+Sims/M
+Sinai/M
+Sinatra/M
+Sinbad/M
+Sinclair/M
+Sindbad/M
+Sindhi/M
+Singapore/M
+Singaporean/SM
+Singer/M
+Singh/M
+Singleton/M
+Sinhalese/M
+Sinica/M
+Sinkiang/M
+Siobhan/M
+Sioux/M
+Sir/SM
+Sirius/M
+Sissie/M
+Sister/MS
+Sistine/M
+Sisyphean/M
+Sisyphus/M
+Siva/M
+Sivan/M
+Siward/M
+Sjaelland/M
+Skelly/M
+Skinner/M
+Skippy/M
+Skipton/M
+Skopje/M
+Skye/M
+Skylab/M
+Skylar/M
+Skyler/M
+Skype/M
+Slackware/M
+Slade/M
+Slashdot/M
+Slater/M
+Slav/SM
+Slavic/M
+Slavonic/M
+Slidell/M
+Slinky/M
+Sloan/M
+Sloane/M
+Slocum/M
+Slovak/SM
+Slovakia/M
+Slovakian
+Slovene/SM
+Slovenia/M
+Slovenian/MS
+Slurpee/M
+Sly's
+Sm/M
+Small/M
+Smetana/M
+Smirnoff/M
+Smith/M
+Smithson/M
+Smithsonian/M
+Smitty/M
+Smokey/M
+Smolensk/M
+Smollett/M
+Smuts/M
+Smyrna
+Sn/M
+Snake/M
+Snapple/M
+Snead/M
+Snell/M
+Snickers/M
+Snider/M
+Snoopy/M
+Snow/M
+Snowbelt/M
+Snyder/M
+Soave/M
+Soc
+Socastee/M
+Socorro/M
+Socrates/M
+Socratic/M
+Soddy/M
+Sodom/M
+Sofia/M
+Sofie/M
+Soho/M
+Sol/MY
+Solaris/M
+Solis/M
+Solly/M
+Solomon/M
+Solon/M
+Solzhenitsyn/M
+Somali/SM
+Somalia/M
+Somalian/MS
+Somerset
+Somme/M
+Somoza/M
+Son/M
+Sondheim/M
+Sondra/M
+Songhai/M
+Songhua/M
+Sonia/M
+Sonja/M
+Sonny/M
+Sonora/M
+Sontag/M
+Sony/M
+Sonya/M
+Sophi/M
+Sophia/M
+Sophie/M
+Sophoclean/M
+Sophocles/M
+Sophronia/M
+Sopwith/M
+Sorbonne/M
+Sorcha/M
+Sosa/M
+Soto/M
+Souphanouvong/M
+Sourceforge/M
+Sousa/M
+South/M
+Southampton/M
+Southeast/MS
+Southern/ZR
+Southerner/M
+Southey/M
+Souths
+Southwest/MS
+Soviet/M
+Sovietica/M
+Soweto/M
+Soyinka/M
+Soyuz/M
+Sp
+Spaatz/M
+Spackle/M
+Spahn/M
+Spain/M
+Spam/M
+Span
+Spanglish
+Spaniard/SM
+Spanish/M
+Sparc
+Sparks/M
+Sparta/M
+Spartacus/M
+Spartan/MS
+Spartanburg/M
+Spears/M
+Speer/M
+Spence/RM
+Spencer/M
+Spencerian/M
+Spengler/M
+Spenglerian/M
+Spenser/M
+Spenserian/M
+Sperry/M
+Sphinx/M
+Spica/M
+SpiderMonkey/M
+Spielberg/M
+Spillane/M
+Spinoza/M
+Spinx/M
+Spiro/M
+Spirograph/M
+Spitsbergen/M
+Spitz/M
+Spock/M
+Spokane/M
+Springdale/M
+Springfield/M
+Springsteen/M
+Sprint/M
+Sprite/M
+Sputnik/M
+Sq
+Squanto/M
+Squibb/M
+Sr/M
+Srinagar/M
+Srivijaya/M
+St
+Sta
+Stace/M
+Stacey/M
+Staci/M
+Stacie/M
+Stacy/M
+Stael/M
+Stafford/M
+StairMaster/M
+Stalin/M
+Stalingrad/M
+Stalinist/M
+Stallone/M
+Stamford/M
+Stan/MY
+Standford/M
+Standish/M
+Stanfield/M
+Stanford/M
+Stanislas/M
+Stanislaus/M
+Stanislavsky/M
+Stanislaw/M
+Stanley/M
+Stanly/M
+Stanton/M
+Stanwood/M
+Staples/M
+Starbucks/M
+Stark/M
+Starkey/M
+Starr/M
+Statehouse/MS
+Staten/M
+States
+Stateside
+Staubach/M
+Staunton/M
+Stavros
+Ste
+Steadicam/M
+Stearn/M
+Steele/M
+Stefan/M
+Stefania/M
+Stefanie/M
+Stefano/M
+Steffen/M
+Steffi/M
+Stein/MR
+Steinbeck/M
+Steinem/M
+Steiner/M
+Steinmetz/M
+Steinway/M
+Stella/M
+Stendhal/M
+Stengel/M
+Stephan/M
+Stephani/M
+Stephanie/M
+Stephanus/M
+Stephen/MS
+Stephens/M
+Stephenson/M
+Sterling/M
+Stern/M
+Sterne/M
+Sterno/M
+Stetson/M
+Steuben/M
+Steubenville/M
+Steve/M
+Steven/MS
+Stevens/M
+Stevenson/M
+Stevie/M
+Stewart/M
+Stieglitz/M
+Stillman/M
+Stilton/SM
+Stimson/M
+Stine/M
+Stinky's
+Stirling/M
+Stockhausen/M
+Stockholm/M
+Stockton/M
+Stoddard/M
+Stoic/SM
+Stoicism/MS
+Stokes/M
+Stolichnaya/M
+Stolypin/M
+Stone/M
+Stonehenge/M
+Stoppard/M
+Stormy's
+Stout/M
+Stowe/M
+Strabo/M
+Stradivari
+Stradivarius/M
+Strasbourg/M
+Strauss/M
+Stravinsky/M
+Streisand/M
+Strickland/M
+Strindberg/M
+Stromboli/M
+Strong/M
+Stu/M
+Stuart/MS
+Studebaker/M
+StumbleUpon/M
+Stuttgart/M
+Stuyvesant/M
+Stygian/M
+Styrofoam/SM
+Styron/M
+Styx/M
+Suarez/M
+Subaru/M
+Sucre/M
+Sucrets/M
+Sudan/M
+Sudanese/M
+Sudetenland/M
+Sudoku/M
+Sudra/M
+Sue/M
+Suetonius/M
+Suez/M
+Suffolk/M
+Sufi/M
+Sufism/M
+Suharto/M
+Sui/M
+Sukarno/M
+Sukey/M
+Suki/M
+Sukkot
+Sukkoth/M
+Sukkoths
+Sula/M
+Sulawesi/M
+Suleiman/M
+Sulla/M
+Sullivan/M
+Sumatra/M
+Sumatran/SM
+Sumeria/M
+Sumerian/SM
+Sumerica/M
+Summer/MS
+Summers/M
+Sumner/M
+Sumter/M
+Sun/SM
+Sunbeam/M
+Sunbelt/M
+Sundanese/M
+Sundas/M
+Sunday/MS
+Sunderland/M
+Sung/M
+Sunkist/M
+Sunni/SM
+Sunnite/MS
+Sunny's
+Sunnyvale/M
+Suomi/M
+Superbowl/M
+Superfund/M
+Superglue/M
+Superior/M
+Superman/M
+Supt
+Surabaja
+Surabaya/M
+Surat/M
+Suriname/M
+Surinamese
+Surya/M
+Susan/M
+Susana/M
+Susann/M
+Susanna/M
+Susannah/M
+Susanne/M
+Susi/M
+Susie/M
+Susquehanna/M
+Sussex/M
+Susy/M
+Sutherland/M
+Sutton/M
+Suva/M
+Suwanee/M
+Suzanna/M
+Suzanne/M
+Suzette/M
+Suzhou/M
+Suzi/M
+Suzie/M
+Suzuki/M
+Suzy/M
+Svalbard/M
+Sven/M
+Svend/M
+Svengali/M
+Sverdlovsk
+Swahili/SM
+Swammerdam/M
+Swanee/M
+Swansea/M
+Swanson/M
+Swazi/SM
+Swaziland/M
+Swed/N
+Swede/SM
+Sweden/M
+Swedenborg/M
+Swedish/M
+Sweeney/M
+Sweet/M
+Swift/M
+Swinburne/M
+Swindon/M
+Swiss/MS
+Swissair/M
+Switz
+Switzerland/M
+Sybil/M
+Sybilla/M
+Sybille/M
+Syd/M
+Sydney/M
+Sykes/M
+Sylvan's
+Sylvester/M
+Sylvia/M
+Sylvie/M
+Symantec/M
+Symbian/M
+Symon/M
+Synge/M
+Syracuse/M
+Syria/M
+Syriac/M
+Syrian/MS
+Syriana/M
+Szilard/M
+Szymborska/M
+Svres/M
+T'ang/M
+T/MDG
+TA
+TARP
+TB/M
+TBA
+TD
+TDD
+TEFL
+TELNET/S
+TELNETTed
+TELNETTing
+TESL
+TESOL
+TEirtza/M
+TGIF
+THC
+THz/M
+TIF/SM
+TIFF/SM
+TKO/M
+TLC/M
+TM
+TN
+TNT/M
+TOEFL
+TQM
+TV/SM
+TVA
+TWA/M
+TWX
+TX
+Ta/M
+Tabasco/SM
+Tabatha/M
+Tabb/M
+Taber/M
+Tabernacle/MS
+Tabitha/M
+Tabor
+Tabriz/MS
+Tacitus/M
+Tacoma/M
+Tad/M
+Taddeo/M
+Tadzhik/M
+Taegu/M
+Taejon/M
+Taft/M
+Tagalog/SM
+Tagore/M
+Tagus/M
+Tahiti/M
+Tahitian/MS
+Tahoe/M
+Taichung/M
+Tainan
+Taine/M
+Taipei/M
+Taiping/M
+Tait/M
+Taiwan/M
+Taiwanese/M
+Taiyuan/M
+Tajikistan/M
+Taklamakan/M
+Talbert/M
+Talbot/M
+Talia/M
+Taliban/M
+Taliesin/M
+Tallahassee/M
+Tallchief/M
+Talley/M
+Talleyrand/M
+Tallinn/M
+Tallulah/M
+Talmud/MS
+Talmudic
+Talmudist
+Talya/M
+Tamar/M
+Tamara/M
+Tamas
+Tameka/M
+Tamera/M
+Tamerlane/M
+Tami/M
+Tamika/M
+Tamil/MS
+Tammany/M
+Tammi/M
+Tammie/M
+Tammuz/M
+Tammy/M
+Tampa/M
+Tampax/M
+Tamra/M
+Tamworth/M
+Tana
+Tancred/M
+Tandy/M
+Taney/M
+Tanganyika/M
+Tangier/MS
+Tangshan/M
+Tani/M
+Tania/M
+Tanisha/M
+Tann/MR
+Tanner/M
+Tannhauser/M
+Tannhuser/M
+Tantalus/M
+Tanya/M
+Tanzania/M
+Tanzanian/SM
+Tao/M
+Taoism/MS
+Taoist/MS
+Tara/M
+Tarantino/M
+Tarawa/M
+Tarazed/M
+Tarbell/M
+Target/M
+Tarim/M
+Tarkenton/M
+Tarkington/M
+Tartar/MS
+Tartary/M
+Tartuffe/M
+Taryn/M
+Tarzan/M
+Tasha/M
+Tashkent/M
+Tasman/M
+Tasmania/M
+Tasmanian/M
+Tass/M
+Tatar/MS
+Tate/M
+Tatiana/M
+Tatum/M
+Taurus/MS
+Tavares/M
+Tawney/M
+Taylor/M
+Tb/M
+Tbilisi/M
+Tc/M
+Tchaikovsky/M
+Te/M
+TeX
+TeXes
+Teasdale/M
+TechRepublic/M
+Technicolor/M
+Technorati/M
+Tecumseh/M
+Ted/M
+Teddie/M
+Teddy/M
+Tedi/M
+Teena/M
+Teflon/MS
+Tegucigalpa/M
+Tehran
+TelePrompTer
+TelePrompter/M
+Telemachus/M
+Telemann/M
+Teletype
+Tell/MR
+Teller/M
+Telugu/M
+Temecula/M
+Tempe
+Templar/M
+Temple/M
+Templeton/M
+Tenn/M
+Tennessean/SM
+Tennessee/M
+Tennyson/M
+Tennysonian
+Tenochtitlan/M
+TensorFlow/M
+Teodor/M
+Teodora/M
+Teodoro/M
+Teotihuacan/M
+Tera/M
+Terence/M
+Teresa/M
+Terese/M
+Tereshkova/M
+Teresita/M
+Teri/M
+Terkel/M
+Terpsichore/M
+Terr/M
+Terra/M
+Terran/M
+Terrance/M
+Terrell/M
+Terrence/M
+Terri/M
+Terrie/M
+Terrill/M
+Territory
+Terry/M
+Tertiary/M
+Terza/M
+Tesco/M
+Tesla/M
+Tess/M
+Tessa/M
+Tessie/M
+Tet/M
+Tethys/M
+Tetons/M
+Teuton/MS
+Teutonic/M
+Tevet/M
+Tex/M
+Texaco/M
+Texan/MS
+Texarkana/M
+Texas/M
+TextEdit/M
+Th/M
+Thacher/M
+Thackeray/M
+Thad/M
+Thaddeus/M
+Thai/SM
+Thailand/M
+Thales/M
+Thalia/M
+Thames/M
+Thanh/M
+Thanksgiving/MS
+Thant/M
+Thar/M
+Tharp/M
+Thatcher/M
+Thatcherism
+Thaxter/M
+Thea/M
+Thebes/M
+Theda/M
+Theia
+Theiler/M
+Thekla/M
+Thelma/M
+Themistocles/M
+Theo/M
+Theobald/M
+Theocritus/M
+Theodor/M
+Theodora/M
+Theodore/M
+Theodoric/M
+Theodosia/M
+Theodosius/M
+Theosophy/M
+Theravada/M
+Theresa/M
+Therese/M
+Thermopylae/M
+Thermos
+Theron/M
+Theseus/M
+Thespian/M
+Thespis/M
+Thessalonian/SM
+Thessaloniki/M
+Thessalonki/M
+Thessaly/M
+Thia/M
+Thibaut/M
+Thieu/M
+Thimbu/M
+Thimphu
+Thom/M
+Thoma/SM
+Thomas/M
+Thomasin/M
+Thomasina/M
+Thomism/M
+Thomistic/M
+Thompson/M
+Thomson/M
+Thor/M
+Thorazine/M
+Thoreau/M
+Thorin/M
+Thorndike
+Thornton/M
+Thorny's
+Thoroughbred/M
+Thorpe/M
+Thorstein/M
+Thorsten/M
+Thorvald/M
+Thoth/M
+Thrace/M
+Thracian/M
+Thu
+Thucydides/M
+Thule/M
+Thunderbird/M
+Thur/S
+Thurber/M
+Thurman/M
+Thurmond/M
+Thursday/SM
+Thurstan/M
+Thurston/M
+Thutmose/M
+Ti/M
+Tia/M
+Tianjin/M
+Tiber/M
+Tiberius/M
+Tibet/M
+Tibetan/MS
+Ticketmaster/M
+Ticonderoga/M
+Tide/M
+Tiebout/M
+Tienanmen/M
+Tientsin/M
+Tierney/M
+Tiffany/M
+Tigris/M
+Tijuana/M
+Tilda/M
+Tildi/M
+Tildy/M
+Tillich/M
+Tillie/M
+Tillman/M
+Tilly/M
+Tilsit/M
+Tim/M
+Timbuktu/M
+Timex/M
+Timi/M
+Timmy/M
+Timon/M
+Timor/M
+Timotheus/M
+Timothy/M
+Timur/M
+Timurid/M
+Tina/M
+Ting/M
+Tinkerbell/M
+Tinkertoy/M
+Tinseltown/M
+Tintoretto/M
+Tippecanoe/M
+Tipperary/M
+Tirane
+Tiresias/M
+Tirol/M
+Tirolean
+Tish/M
+Tisha/M
+Tishri/M
+Titan/SM
+Titania/M
+Titanic/M
+Titian/M
+Titicaca/M
+Tito/M
+Titus/M
+Titusville/M
+Tl/M
+Tlaloc/M
+Tlingit/M
+Tm/M
+Tobago/M
+Tobe/M
+Tobey
+Tobi/M
+Tobias/M
+Tobie/M
+Tobin/M
+Tobit/M
+Toby/M
+Tocantins/M
+Tocqueville/M
+Tod/M
+Todd/M
+Togo/M
+Togolese/M
+Tojo/M
+Tokay/M
+Tokugawa/M
+Tokyo/M
+Tokyoite
+Toledo/MS
+Tolkien/M
+Tolstoy/M
+Toltec/M
+Tolyatti/M
+Tom/M
+Toma/SM
+Tomas/M
+Tomaso/M
+Tombaugh/M
+Tomi/M
+Tomlin/M
+Tommie/M
+Tommy/M
+Tompkins/M
+Tomsk/M
+Tonga/M
+Tongan/MS
+Toni/M
+Tonia/M
+Tonto/M
+Tony/M
+Tonya/M
+Tootsie/M
+Topeka/M
+Topsy/M
+Torah/M
+Torahs
+Tore's
+Torey/M
+Tori/M
+Torin/M
+Toronto/M
+Torquemada/M
+Torr/MX
+Torrance/M
+Torre/SM
+Torrence/M
+Torrens/M
+Torres/M
+Torrey/M
+Torricelli/M
+Torrie/M
+Torry/M
+Tortola/M
+Tortuga/M
+Torvalds/M
+Tory/SM
+Tosca/M
+Toscanini/M
+Toshiba/M
+Toto/M
+Toulouse/M
+Tova/M
+Tove/M
+Townes/M
+Townsend/M
+Toynbee/M
+Toyoda/M
+Toyota/M
+Tracey/M
+Traci/M
+Tracie/M
+Tracy/M
+Trafalgar/M
+Trailways/M
+Trajan/M
+Tran/M
+Transcaucasia/M
+Transvaal/M
+Transylvania/M
+Transylvanian/M
+Trappist/SM
+Traver/MS
+Travis/M
+Travolta/M
+Treasury/SM
+Treblinka/M
+Trekkie/M
+Tremain/M
+Tremaine/M
+Tremayne/M
+Trent/M
+Trenton/M
+Treo/M
+Trev/M
+Trevelyan/M
+Trevino/M
+Trevor/M
+Trey/M
+Triangulum/M
+Triassic/M
+Tricia/M
+Trident/M
+Trieste/M
+Trimurti/M
+Trina/M
+Trinidad/M
+Trinidadian/MS
+Trinity/SM
+TripAdvisor/M
+Tripitaka/M
+Tripoli/M
+Tripp/M
+Trippe/M
+Tris
+Trish/M
+Trisha/M
+Trista/M
+Tristan/M
+Triton/M
+Trix/M
+Trixie/M
+Trobriand/M
+Troilus/M
+Trojan/MS
+Trollope/M
+Trondheim/M
+Tropicana/M
+Trotsky/M
+Troy/M
+Troyes
+Truckee/M
+Trude/M
+Trudeau/M
+Trudi/M
+Trudy/M
+Trueman/M
+Truffaut/M
+Trujillo/M
+Truman/M
+Trumbull/M
+Trump/M
+Truth/M
+Tsimshian/M
+Tsiolkovsky/M
+Tsitsihar/M
+Tsongkhapa/M
+Tswana/M
+Tu/M
+Tuamotu/M
+Tuareg/M
+Tubman/M
+Tucker/M
+Tucson/M
+Tucuman/M
+Tudor/SM
+Tue/S
+Tues/M
+Tuesday/MS
+Tulane/M
+Tull/M
+Tully/M
+Tulsa/M
+Tulsidas/M
+Tums/M
+Tungus/M
+Tunguska/M
+Tunis/M
+Tunisia/M
+Tunisian/MS
+Tunney/M
+Tupi/M
+Tupperware/M
+Tupungato/M
+Turgenev/M
+Turin/M
+Turing/M
+Turk/SM
+Turkestan/M
+Turkey/M
+Turkic/MS
+Turkish/M
+Turkmenistan/M
+Turlock/M
+Turner/M
+Turpin/M
+Tuscaloosa/M
+Tuscan/M
+Tuscany/M
+Tuscarora/MS
+Tuscon/M
+Tuskegee/M
+Tussaud/M
+Tut/M
+Tutankhamen/M
+Tutsi/M
+Tutu/M
+Tuvalu/M
+Tuvaluan
+Twain/M
+Tweed/M
+Tweedledee/M
+Tweedledum/M
+Twila/M
+Twinkies/M
+Twitter/M
+Twizzlers/M
+Twp
+Twyla/M
+Ty/M
+Tybalt/M
+Tycho/M
+Tye/M
+Tylenol/M
+Tyler/M
+Tynan/M
+Tyndale/M
+Tyndall/M
+Tyne/M
+Tyre/M
+Tyree/M
+Tyrolean
+Tyrone/M
+Tyrus/M
+Tyson/M
+U/M
+UAR
+UAW
+UBS/M
+UCLA/M
+UFO/SM
+UHF/M
+UI/SM
+UK/M
+UL
+UN/M
+UNESCO/M
+UNICEF/M
+UNIX/M
+UPC
+UPI/M
+UPS/M
+URL/S
+US/M
+USA/M
+USAF
+USB
+USCG
+USDA/M
+USIA
+USMC
+USN
+USO
+USP
+USPS
+USS
+USSR/M
+UT/M
+UTC
+UV/M
+Ubangi/M
+Ubuntu/M
+Ucayali/M
+Uccello/M
+Udall/M
+Udell/M
+Ufa/M
+Uganda/M
+Ugandan/MS
+Ugo/M
+Uighur/M
+Ujungpandang/M
+Ukraine/M
+Ukrainian/SM
+Ula/M
+Ulick/M
+Ulises/M
+Ulla/M
+Ulric/M
+Ulrica/M
+Ulrich/M
+Ulrike/M
+Ulster/M
+Ultrasuede/M
+Ulyanovsk/M
+Ulysses/M
+Umberto/M
+Umbriel/M
+Una/M
+Underwood/M
+Ungava/M
+Unicode/M
+Unilever/M
+Union/SM
+Unionist
+Uniontown/M
+Uniroyal/M
+Unitarian/MS
+Unitarianism/MS
+Unitas/M
+Unix/S
+Unukalhai/M
+Upanishads/M
+Updike/M
+Upjohn/M
+Upton/M
+Ur/M
+Ural/SM
+Urals/M
+Urania/M
+Uranus/M
+Urbain/M
+Urban/M
+Urbano/M
+Urdu/M
+Urey/M
+Uri/SM
+Uriah/M
+Uriel/M
+Uris/M
+Urquhart/M
+Ursa/M
+Ursula/M
+Ursuline/M
+Uruguay/M
+Uruguayan/MS
+Urumqi/M
+Usenet/MS
+Ustinov/M
+Ut
+Uta/M
+Utah/M
+Utahan/MS
+Ute/SM
+Utica/M
+Utopia/SM
+Utopian/SM
+Utrecht/M
+Utrillo/M
+Uzbek/M
+Uzbekistan/M
+Uzi/SM
+V/M
+VA
+VAT/M
+VAX
+VAXes
+VBA/M
+VCR/M
+VD/M
+VDT
+VDU
+VF
+VFW/M
+VG
+VGA
+VHF/M
+VHS
+VI/M
+VIP/SM
+VISTA
+VJ
+VLF/M
+VOA
+VP
+VPN/SM
+VT
+VTOL
+Va/M
+Vacaville/M
+Vachel/M
+Vaclav/M
+Vader/M
+Vaduz/M
+Vail/M
+Val/M
+Valarie/M
+Valdemar/M
+Valdez/M
+Valdosta/M
+Valencia/SM
+Valenti/M
+Valentia/M
+Valentin/M
+Valentina/M
+Valentine/M
+Valentino/M
+Valenzuela/M
+Valera
+Valeria/M
+Valerian/M
+Valerie/M
+Valery/M
+Valhalla/M
+Valium/MS
+Valkyrie/SM
+Valle/M
+Vallejo/M
+Valletta/M
+Valli/M
+Valois/M
+Valparaiso/M
+Valvoline/M
+Valry/M
+Van/M
+Vance/M
+Vancouver/M
+Vanda/M
+Vandal/MS
+Vanderbilt/M
+Vandyke/M
+Vanessa/M
+Vang/M
+Vania/M
+Vanna/M
+Vanni/M
+Vanuatu/M
+Vanya/M
+Vanzetti/M
+Varanasi/M
+Varese/M
+Vargas/M
+Vaseline/SM
+Vasili/M
+Vasily/M
+Vasquez/M
+Vassar/M
+Vassili/M
+Vassily/M
+Vatican/M
+Vauban/M
+Vaughan/M
+Vaughn/M
+Vazquez/M
+Veblen/M
+Veda/SM
+Vedanta/M
+Veep
+Vega/SM
+Vegas/M
+Vegemite/M
+Vela/M
+Velasquez/M
+Velazquez/M
+Velcro/MS
+Velez/M
+Velma/M
+Velveeta/M
+Velsquez/M
+Velzquez/M
+Venetian/SM
+Venezuela/M
+Venezuelan/SM
+Venice/M
+Venn/M
+Ventolin/M
+Venus/MS
+Venusian/M
+Vera/M
+Veracruz/M
+Verde/M
+Verdi/M
+Verdun/M
+Vere/M
+Verena/M
+Verizon/M
+Verlaine/M
+Vermeer/M
+Vermont/ZMR
+Vermonter/M
+Vern/M
+Verna/M
+Verne/M
+Verney/M
+Vernon/M
+Vernor/M
+Verona/M
+Veronese/M
+Veronica/M
+Veronika/M
+Veronique
+Versailles/M
+Vesalius/M
+Vespasian/M
+Vespucci/M
+Vesta/M
+Vesuvius/M
+Vi/M
+Viacom/M
+Viagra/M
+Vic/M
+Vicente/M
+Vichy/M
+Vick/M
+Vicki/M
+Vickie/M
+Vicksburg/M
+Vicky/M
+Vicodin/M
+Victor/M
+Victoria/M
+Victorian/MS
+Victorianism
+Victorville/M
+Victrola/M
+Vida/M
+Vidal/M
+Vienna/M
+Viennese/M
+Vientiane/M
+Vietcong/M
+Vietminh/M
+Vietnam/M
+Vietnamese/M
+Vijayanagar/M
+Vijayawada/M
+Viking/MS
+Vikki/M
+Vila/M
+Villa/SM
+Villarreal/M
+Villas/M
+Villon/M
+Vilma/M
+Vilnius/M
+Vilyui/M
+Vin/M
+Vina/M
+Vince/M
+Vincent/M
+Vindemiatrix/M
+Vineland/M
+Vinnie/M
+Vinny/M
+Vinson/M
+Viola/M
+Violante/M
+Violet/M
+Violetta/M
+Violette/M
+Virgie/M
+Virgil/M
+Virgilio/M
+Virginia/M
+Virginian/SM
+Virginie/M
+Virgo/SM
+Visa/M
+Visakhapatnam/M
+Visalia/M
+Visayans/M
+Vishnu/M
+Visigoth/M
+Visigoths
+Vistula/M
+Vite/M
+Vitim/M
+Vito/M
+Vitoria
+Vittoria/M
+Vittorio/M
+Vitus/M
+Viv/M
+Vivaldi/M
+Vivekananda/M
+Vivi/MN
+Vivian/M
+Viviana/M
+Vivie/M
+Vivien/M
+Vivienne/M
+Vlad/M
+Vladimir/M
+Vladivostok/M
+Vlaminck/M
+Vlasic/M
+VoIP
+Vodafone/M
+Vogue/M
+Volcker/M
+Voldemort/M
+Volga/M
+Volgograd/M
+Volkswagen/M
+Volstead/M
+Volta/M
+Voltaire/M
+Volvo/M
+Von/M
+Vonda/M
+Vonnegut/M
+Voronezh/M
+Vorster/M
+Voyager/M
+Vt
+Vuitton/M
+Vulcan/M
+Vulg
+Vulgate/SM
+W/MDT
+WA
+WAC
+WASP/SM
+WATS/M
+WC
+WHO/M
+WI
+WMD
+WNW/M
+WP
+WSW/M
+WTF
+WTO
+WV
+WW
+WWI
+WWII
+WWW/M
+WY
+WYSIWYG
+Wabash/M
+Wac
+Waco/M
+Wade/M
+Wadsworth/M
+Wagner/M
+Wagnerian/M
+Wahhabi/M
+Waikiki/M
+Wainwright/M
+Waite/M
+Wake/M
+Wakefield
+Waksman/M
+Wald/MN
+Waldemar/M
+Walden/M
+Waldensian/M
+Waldheim/M
+Waldo/M
+Waldorf/M
+Wales/M
+Walesa/M
+Walgreen/SM
+Walgreens/M
+Walker/M
+Walkman/M
+Wall/SMR
+Wallace/M
+Wallas/M
+Wallenstein/M
+Waller/M
+Wallie/M
+Wallis/M
+Walloon/M
+Walls/M
+Wally/M
+Walmart/M
+Walpole/M
+Walpurgisnacht/M
+Walsh/M
+Walt/MRZ
+Walter/M
+Walters/M
+Walther/M
+Walton/M
+Wanamaker/M
+Wanda/M
+Wang/M
+Wankel/M
+Warcraft/M
+Ward/M
+Warde/M
+Ware/MG
+Warhol/M
+Waring/M
+Warner/M
+Warren/M
+Warsaw/M
+Warwick/M
+Warwickshire/M
+Wasatch/M
+Wash/M
+Washington/M
+Washingtonian/MS
+Wassermann/M
+Wat/MZ
+Waterbury/M
+Waterford/M
+Watergate/M
+Waterloo/MS
+Waters/M
+Watertown/M
+Watkins/M
+Watson/M
+Watsonville/M
+Watt/SM
+Watteau/M
+Watts/M
+Watusi/M
+Waugh/M
+Wausau/M
+Wave
+Waverley/M
+Waverly/M
+Wayland/M
+Waylon/M
+Wayne/M
+Waynesboro/M
+Weaver/M
+Web/MR
+WebSphere/M
+Webb/M
+Weber/M
+Webern/M
+Webster/MS
+Wed/M
+Weddell/M
+Wedgwood/M
+Wednesday/MS
+Weeks/M
+Wehrmacht/M
+Wei/M
+Weider/M
+Weierstrass/M
+Weill/M
+Weinberg/M
+Weirton/M
+Weiss/M
+Weissmuller/M
+Weizmann/M
+Welby/M
+Weldon/M
+Welland/M
+Weller/M
+Welles/M
+Wellington/SM
+Wells/M
+Welsh/M
+Welshman/M
+Welshmen/M
+Welshwoman
+Wenatchee/M
+Wendel/M
+Wendell/M
+Wendi/M
+Wendy/M
+Werner/M
+Wernher/M
+Wes
+Wesak/M
+Wesley/M
+Wesleyan/M
+Wessex/M
+Wesson/M
+West/SM
+Westbrook/M
+Western/MRS
+Westinghouse/M
+Westley/M
+Westminster/M
+Weston/M
+Westphalia/M
+Weyden/M
+Wezen/M
+Wharton/M
+Wheaties/M
+Wheatstone/M
+Wheeler/M
+Wheeling/M
+Whig/SM
+Whipple/M
+Whirlpool/M
+Whistler/M
+Whitaker/M
+Whitby/M
+White/SM
+Whitefield/M
+Whitehall/M
+Whitehead/M
+Whitehorse/M
+Whiteley/M
+Whitfield/M
+Whitley/M
+Whitman/M
+Whitney/M
+Whitsunday/MS
+Whittaker/M
+Whittier/M
+Wi-Fi/M
+WiFi/M
+Wicca/M
+Wichita/M
+Wiemar/M
+Wiesel/M
+Wiesenthal/M
+Wiggins/M
+Wigner/M
+Wii/M
+WikiPatents/M
+Wikibooks/M
+Wikileaks
+Wikimedia/M
+Wikinews/M
+Wikipedia/M
+Wikiquote/M
+Wikisource/M
+Wiktionary/M
+Wilberforce/M
+Wilbert/M
+Wilbur/M
+Wilburn/M
+Wilcox/M
+Wilda/M
+Wilde/MR
+Wilden/M
+Wilder/M
+Wiles/M
+Wiley/M
+Wilford/M
+Wilfred/M
+Wilfredo/M
+Wilfrid/M
+Wilhelm/M
+Wilhelmina/M
+Wilhelmine
+Wilkerson/M
+Wilkes/M
+Wilkins/M
+Wilkinson/M
+Will/M
+Willa/M
+Willamette/M
+Willard/M
+Willem/M
+Willemstad/M
+Willey/M
+Willi/MS
+William/SM
+Williams/M
+Williamsburg/M
+Williamson/M
+Williamsport/M
+Willie/M
+Willis/M
+Willy/M
+Wilma/M
+Wilmer/M
+Wilmette/M
+Wilmington/M
+Wilson/M
+Wilsonian/M
+Wilton/M
+Wiltshire/M
+Wimbledon/M
+Wimsey/M
+Winchell/M
+Winchester/MS
+Windbreaker/M
+Windex/M
+Windham/M
+Windhoek/M
+Windows/M
+Windsor/SM
+Windward/M
+Windy's
+Winesap/M
+Winfield/M
+Winfred/M
+Winfrey/M
+Winifred/M
+Winkle/M
+Winn/M
+Winna/M
+Winne/M
+Winnebago/M
+Winnie/M
+Winnifred/M
+Winnipeg/M
+Winny/M
+Winona/M
+Winslow/M
+Winston/M
+Winters/M
+Winthrop/M
+Wis
+Wisc
+Wisconsin/M
+Wisconsinite/MS
+Wise/M
+Witt/M
+Wittgenstein/M
+Witty's
+Witwatersrand/M
+Wm/M
+Wobegon/M
+Wodehouse/M
+Wolf/M
+Wolfe/M
+Wolff/M
+Wolfgang/M
+Wollongong/M
+Wollstonecraft/M
+Wolsey/M
+Wolverhampton
+Wonder/M
+Wonderbra/M
+Wong/M
+Wood/SM
+Woodard/M
+Woodhull/M
+Woodie/M
+Woodland/M
+Woodrow/M
+Woods/M
+Woodstock/M
+Woodward/M
+Woolf/M
+Woolite/M
+Woolongong/M
+Woolworth/M
+Wooster/M
+Wooten/M
+Worcester/SM
+Worcestershire/M
+WordPress/M
+Worden/M
+Wordsworth/M
+Workman/M
+WorldCat/M
+Worms/M
+Worthington/M
+Wotan/M
+Wovoka/M
+Wozniak/M
+Wozzeck/M
+Wrangell/M
+Wren/M
+Wright/M
+Wrigley/M
+Wroclaw/M
+Wu/M
+Wuhan/M
+Wurlitzer/M
+Wyatt/M
+Wycherley/M
+Wycliffe/M
+Wye/H
+Wyeth/M
+Wylie/M
+Wyn/M
+Wyndham/M
+Wynn/M
+Wynne/M
+Wyo
+Wyoming/M
+Wyomingite/SM
+X/M
+XBL/M
+XEmacs/M
+XL/M
+XLS/SM
+XLSX/SM
+XML
+XPCOM/M
+XPConnect/M
+XPInstall/M
+XS
+XUL/M
+XULRunner/M
+XXL
+Xamarin/M
+Xanadu/M
+Xanax/M
+Xanthippe/M
+Xavier/M
+Xbox/M
+Xe/SM
+Xena/M
+Xenakis/M
+Xenia/M
+Xenophon/M
+Xerox/MS
+Xerxes/M
+Xhosa/M
+Xi'an/M
+Xian/SM
+Xiaoping/M
+Ximenes/M
+Ximenez/M
+Xingu/M
+Xinjiang/M
+Xiongnu/M
+Xizang/M
+Xmas/MS
+Xochipilli/M
+Xuzhou/M
+Y/M
+YMCA/M
+YMHA
+YMMV
+YT
+YWCA/M
+YWHA
+Yacc/M
+Yahoo/M
+Yahtzee/M
+Yahweh/M
+Yakima/M
+Yakut/M
+Yakutsk/M
+Yale/M
+Yalow/M
+Yalta/M
+Yalu/M
+Yamagata/M
+Yamaha/M
+Yamoussoukro/M
+Yancey/M
+Yancy/M
+Yang/M
+Yangon/M
+Yangtze/M
+Yank/SM
+Yankee/SM
+Yaobang/M
+Yaounde/M
+Yaqui/M
+Yardley/M
+Yaren
+Yaroslavl/M
+Yasmin/M
+Yataro/M
+Yates/M
+Yauco/M
+Yb/M
+Yeager/M
+Yeats/M
+Yehudi/M
+Yekaterinburg/M
+Yelena/M
+Yellowknife/M
+Yellowstone/M
+Yeltsin/M
+Yemen/M
+Yemeni/SM
+Yemenite
+Yenisei/M
+Yerevan/M
+Yerkes/M
+Yesenia/M
+Yetta/M
+Yevtushenko/M
+Yggdrasil/M
+Yiddish/M
+Ymir/M
+Ynez/M
+Yoda/M
+Yoknapatawpha/M
+Yoko/M
+Yokohama/M
+Yolanda/M
+Yolande/M
+Yong/M
+Yonkers/M
+York/MR
+Yorke/M
+Yorker/M
+Yorkie/M
+Yorkshire/MS
+Yorktown/M
+Yoruba/M
+Yosemite/M
+Yoshi/M
+Yoshiko/M
+Yossarian/M
+YouTube/M
+Young/M
+Youngstown/M
+Ypres/M
+Ypsilanti/M
+Ysabel/M
+Yuan/M
+Yucatan/M
+Yugo/M
+Yugoslav/MS
+Yugoslavia/M
+Yugoslavian/SM
+Yukon/M
+Yul/M
+Yule/SM
+Yuletide/MS
+Yuma/SM
+Yunnan/M
+Yuri/M
+Yves/M
+Yvette/M
+Yvon/M
+Yvonne/M
+Yvor/M
+Z/SMNXT
+ZDNet/M
+Zaccaria/M
+Zach
+Zachariah/M
+Zacharias
+Zachary/M
+Zachery/M
+Zack/M
+Zagreb/M
+Zahara/M
+Zaire/M
+Zairian
+Zak/M
+Zambezi/M
+Zambia/M
+Zambian/SM
+Zamboni/M
+Zamenhof/M
+Zamora/M
+Zane/M
+Zanuck/M
+Zanzibar/M
+Zapata/M
+Zaporozhye/M
+Zapotec/M
+Zappa/M
+Zara/M
+Zarah/M
+Zarathustra/M
+Zaria/M
+Zea/M
+Zealand/M
+Zeb/M
+Zebedee/M
+Zebulon/M
+Zechariah/M
+Zedekiah/M
+Zedong/M
+Zeffirelli/M
+Zeke/M
+Zelda/M
+Zelig/M
+Zelma/M
+Zen/M
+Zena/M
+Zenger/M
+Zenia/M
+Zeno/M
+Zephaniah/M
+Zephyrhills/M
+Zephyrus/M
+Zeppelin/M
+Zest/M
+Zeus/M
+Zhang/M
+Zhao/M
+Zhdanov
+Zhejiang/M
+Zhengzhou/M
+Zhivago/M
+Zhou/M
+Zhukov/M
+Zia/M
+Zibo/M
+Ziegfeld/M
+Ziegler/M
+Ziff/M
+Ziggy/M
+Zika
+Zimbabwe/M
+Zimbabwean/SM
+Zimmerman/M
+Zinfandel/M
+Zion/SM
+Zionism/SM
+Zionist/SM
+Ziploc/M
+Zita/M
+Zn/M
+Zoe/M
+Zola/M
+Zollverein/M
+Zoloft/M
+Zomba/M
+Zora/M
+Zorn/M
+Zoroaster/M
+Zoroastrian/MS
+Zoroastrianism/SM
+Zorro/M
+Zosma/M
+Zr/M
+Zsigmondy/M
+Zubenelgenubi/M
+Zubeneschamali/M
+Zukor/M
+Zulu/SM
+Zululand
+Zune/M
+Zuni/M
+Zurich/M
+Zwingli/M
+Zworykin/M
+Zyrtec/M
+Zyuganov/M
+Zzz
+Zrich/M
+a/S
+aah
+aardvark/SM
+ab/SDY
+aback
+abacus/MS
+abaft
+abalone/SM
+abandon/LSDG
+abandonment/M
+abase/LGDS
+abasement/M
+abash/GLDS
+abashed/UY
+abashment/M
+abate/LGDS
+abated/U
+abatement/M
+abattoir/MS
+abbe/SM
+abbess/MS
+abbey/MS
+abbot/MS
+abbr
+abbrev/S
+abbreviate/DSGNX
+abbreviation/M
+abb/SM
+abdicate/GNDSX
+abdication/M
+abdomen/SM
+abdominal
+abduct/DSG
+abductee/MS
+abduction/SM
+abductor/MS
+abeam
+aberrant
+aberration/MS
+aberrational
+abet/S
+abetted
+abetter/SM
+abetting
+abettor/SM
+abeyance/M
+abhor/S
+abhorred
+abhorrence/M
+abhorrent/Y
+abhorring
+abidance/M
+abide/GS
+abiding/Y
+ability/IEMS
+abject/YP
+abjection/M
+abjectness/M
+abjuration/SM
+abjuratory
+abjure/ZGDRS
+abjurer/M
+ablate/XGNVDS
+ablation/M
+ablative/MS
+ablaze
+able/UT
+abler
+abloom
+ablution/SM
+abnegate/GNDS
+abnegation/M
+abnormal/Y
+abnormality/SM
+aboard
+abode/MS
+abolish/GDS
+abolition/M
+abolitionism/M
+abolitionist/SM
+abominable
+abominably
+abominate/DSGNX
+abomination/M
+aboriginal/MS
+aborigine/SM
+aborning
+abort/GVDS
+abortion/MS
+abortionist/MS
+abortive/Y
+abound/DSG
+about
+above/M
+aboveboard
+abracadabra/M
+abrade/GDS
+abrasion/MS
+abrasive/MYPS
+abrasiveness/M
+abreast
+abridge/DSLG
+abridgement/MS
+abridgment/MS
+abroad
+abrogate/XGNDS
+abrogation/M
+abrogator/MS
+abrupt/TPRY
+abruptness/M
+abs/M
+abscess/MDSG
+abscissa/SM
+abscission/M
+abscond/ZGSDR
+absconder/M
+abseil/MDSG
+absence/SM
+absent/DYSG
+absentee/MS
+absenteeism/M
+absentminded/YP
+absentmindedness/M
+absinthe/M
+absolute/PMYTNS
+absoluteness/M
+absolution/M
+absolutism/M
+absolutist/MS
+absolve/DSG
+absorb/AZGDRS
+absorbance/S
+absorbancy/M
+absorbency/M
+absorbent/SM
+absorbing/Y
+absorption/M
+absorptive
+abstain/DRZGS
+abstainer/M
+abstemious/PY
+abstemiousness/M
+abstention/MS
+abstinence/M
+abstinent
+abstract/GSPMDY
+abstracted/YP
+abstractedness/M
+abstraction/SM
+abstractness/MS
+abstruse/YP
+abstruseness/M
+absurd/TPRY
+absurdist/MS
+absurdity/SM
+absurdness/M
+abundance/SM
+abundant/Y
+abuse's
+abuse/EGVDS
+abuser/MS
+abusive/YP
+abusiveness/M
+abut/SL
+abutment/MS
+abutted
+abutting
+abuzz
+abysmal/Y
+abyss/MS
+abyssal
+ac
+acacia/MS
+academe/M
+academia/M
+academic/SM
+academical/Y
+academician/MS
+academy/SM
+acanthus/MS
+accede/GDS
+accelerate/GNXDS
+acceleration/M
+accelerator/SM
+accelerometer/SM
+accent/MDSG
+accented/U
+accentual
+accentuate/GNDS
+accentuation/M
+accept/DSBG
+acceptability/M
+acceptableness/M
+acceptably/U
+acceptance/SM
+acceptation/MS
+accepted/U
+access/MDSG
+accessibility/IM
+accessible/I
+accessibly/I
+accession/MDGS
+accessorize/DSG
+accessory/SM
+accident/MS
+accidental/SMY
+acclaim/MDGS
+acclamation/M
+acclimate/DSGN
+acclimation/M
+acclimatization/M
+acclimatize/DSG
+acclivity/SM
+accolade/SM
+accommodate/XGNDS
+accommodating/Y
+accommodation/M
+accompanied/U
+accompaniment/MS
+accompanist/SM
+accompany/DSG
+accomplice/SM
+accomplish/DSLG
+accomplished/U
+accomplishment/MS
+accord/GMDS
+accordance/M
+accordant
+according/Y
+accordion/MS
+accordionist/MS
+accost/GMDS
+account/MDSBG
+accountability/SM
+accountable/U
+accountancy/M
+accountant/MS
+accounted/U
+accounting/M
+accouter/SGD
+accouterments/M
+accoutre/DSG
+accoutrements
+accredit/SGD
+accreditation/M
+accredited/U
+accrete/NDSX
+accretion/M
+accrual/MS
+accrue/GDS
+acct
+acculturate/DSGN
+acculturation/M
+accumulate/XGNVDS
+accumulation/M
+accumulator/MS
+accuracy/IM
+accurate/IY
+accurateness/M
+accursed/P
+accursedness/M
+accusation/MS
+accusative/MS
+accusatory
+accuse/ZGDRS
+accuser/M
+accusing/Y
+accustom/DSG
+accustomed/U
+ace/DSMG
+acerbate/DSG
+acerbic
+acerbically
+acerbity/M
+acetabular
+acetabulum
+acetaminophen/M
+acetate/MS
+acetic
+acetone/M
+acetonic
+acetyl
+acetylene/M
+ache/DSMG
+achene/MS
+achievable/U
+achieve/BLZGDRS
+achievement/SM
+achiever/M
+aching/Y
+achoo/M
+achromatic
+achy/TR
+acid/SMY
+acidic
+acidify/GDS
+acidity/M
+acidosis/M
+acidulous
+acknowledge/DSGL
+acknowledged/U
+acknowledgement/MS
+acknowledgment/SM
+acme/SM
+acne/M
+acolyte/MS
+aconite/MS
+acorn/MS
+acoustic/S
+acoustical/Y
+acoustics/M
+acquaint/AGSD
+acquaintance/SM
+acquaintanceship/M
+acquainted/U
+acquiesce/DSG
+acquiescence/M
+acquiescent/Y
+acquire/ZGBDRSL
+acquirement/M
+acquisition/MS
+acquisitive/YP
+acquisitiveness/M
+acquit/S
+acquittal/MS
+acquitted
+acquitting
+acre/SM
+acreage/MS
+acrid/PTRY
+acridity/M
+acridness/M
+acrimonious/YP
+acrimoniousness/M
+acrimony/M
+acrobat/MS
+acrobatic/S
+acrobatically
+acrobatics/M
+acronym/MS
+acrophobia/M
+acropolis/MS
+across
+acrostic/SM
+acrylamide
+acrylic/MS
+act's
+act/ASDGV
+actin
+acting/M
+actinium/M
+action/ASM
+actionable
+activate/ICANGSD
+activation/ICAM
+activator/MS
+active's
+active/ISY
+activeness/M
+activism/M
+activist/MS
+activity/ISM
+actor/AMS
+actress/MS
+actual/Y
+actuality/SM
+actualization/M
+actualize/GDS
+actuarial
+actuary/SM
+actuate/GNDS
+actuation/M
+actuator/SM
+acuity/M
+acumen/M
+acupressure/M
+acupuncture/M
+acupuncturist/SM
+acute/PMYTRS
+acuteness/M
+acyclovir/M
+acyl
+ad/SM
+adage/MS
+adagio/MS
+adamant/MY
+adapt/BZGVDRS
+adaptability/M
+adaptation/MS
+adapter/M
+adaption/S
+add-on/S
+add/SDRBZG
+addend/MS
+addenda
+addendum/MS
+adder/M
+addible
+addict/GVMDS
+addiction/SM
+addictive/P
+addition/SM
+additional/Y
+additive/SM
+addle/GDS
+address's
+address/AGDS
+addressable
+addressed/U
+addressee/SM
+adduce/GDS
+adduction/SM
+adenine/M
+adenocarcinoma
+adenoid/SM
+adenoidal
+adept/MYPS
+adeptness/M
+adequacy/IM
+adequate/IY
+adequateness/M
+adhere/GDS
+adherence/M
+adherent/SM
+adhesion/M
+adhesive/PSM
+adhesiveness/M
+adiabatic
+adieu/MS
+adios
+adipose
+adis
+adj
+adjacency/M
+adjacent/Y
+adjectival/Y
+adjective/MS
+adjoin/GDS
+adjourn/DGLS
+adjournment/SM
+adjudge/GDS
+adjudicate/GNVXDS
+adjudication/M
+adjudicator/SM
+adjudicatory
+adjunct/MS
+adjuration/MS
+adjure/GDS
+adjust/AGDSL
+adjustable
+adjuster/SM
+adjustment/AMS
+adjutant/SM
+adman/M
+admen
+admin/MS
+administer/DGS
+administrate/XDSGNV
+administration/M
+administrative/Y
+administrator/MS
+admirably
+admiral/MS
+admiralty/M
+admiration/M
+admire/BZGDRS
+admirer/M
+admiring/Y
+admissibility/IM
+admissible/I
+admissibly
+admission/AM
+admissions
+admit/AS
+admittance/M
+admitted/Y
+admitting/A
+admix/GDS
+admixture/SM
+admonish/LDSG
+admonishment/MS
+admonition/MS
+admonitory
+ado/M
+adobe/MS
+adolescence/SM
+adolescent/SM
+adopt/AGVDS
+adoptable
+adoptee/MS
+adopter/MS
+adoption/SM
+adorableness/M
+adorably
+adoration/M
+adorbs
+adore/BZGDRS
+adorer/M
+adoring/Y
+adorn/LGDS
+adorned/U
+adornment/MS
+adrenal/MS
+adrenalin's
+adrenaline/M
+adrenergic
+adrift
+adroit/PY
+adroitness/M
+adsorb/SDG
+adsorbent/MS
+adsorption/SM
+adulate/DSGN
+adulation/M
+adulator/MS
+adulatory
+adult/MS
+adulterant/MS
+adulterate/GNDS
+adulterated/U
+adulteration/M
+adulterer/SM
+adulteress/MS
+adulterous
+adultery/SM
+adulthood/M
+adumbrate/GNDS
+adumbration/M
+adv
+advance/LDSMG
+advancement/SM
+advantage/EDSMG
+advantageous/EY
+advent/SM
+adventitious/Y
+adventure/DRSMZG
+adventurer/M
+adventuresome
+adventuress/MS
+adventurism
+adventurist/S
+adventurous/YP
+adventurousness/M
+adverb/SM
+adverbial/SMY
+adversarial
+adversary/SM
+adverse/PRYT
+adverseness/M
+adversity/SM
+advert/SMDG
+advertise/LZGDRS
+advertised/U
+advertisement/MS
+advertiser/M
+advertising/M
+advertorial/SM
+advice/M
+advisability/IM
+advisable/I
+advisably
+advise/LDRSZGB
+advised/UY
+advisement/M
+adviser/M
+advisor/SM
+advisory/SM
+advocacy/M
+advocate/MGDS
+advocator/MS
+advt
+adware/SM
+adz/MS
+adze/M
+aegis/M
+aeon/SM
+aerate/DSGN
+aeration/M
+aerator/SM
+aerial/SMY
+aerialist/MS
+aerie/MS
+aerobatic/S
+aerobatics/M
+aerobic/S
+aerobically
+aerobics/M
+aerodrome/MS
+aerodynamic/S
+aerodynamically
+aerodynamics/M
+aerogram/S
+aerogramme/S
+aeronautic/S
+aeronautical
+aeronautics/M
+aerosol/MS
+aerospace/M
+aery
+aesthete/MS
+aesthetic/S
+aesthetically
+aestheticism/M
+aesthetics/M
+afar
+affability/M
+affable
+affably
+affair/MS
+affect's
+affect/EGVDS
+affectation/SM
+affected/UY
+affecting/Y
+affection/EM
+affectionate/Y
+affections
+afferent
+affiance/GDS
+affidavit/SM
+affiliate's
+affiliate/EGNDS
+affiliated/U
+affiliation/EM
+affiliations
+affine
+affinity/SM
+affirm/AGDS
+affirmation/AMS
+affirmative/MYS
+affix/GMDS
+afflatus/M
+afflict/GDS
+affliction/SM
+affluence/M
+affluent/Y
+afford/GDSB
+affordability
+affordable/U
+affordably/U
+affordance/S
+afforest/EGSD
+afforestation/M
+affray/MS
+affront/GMDS
+afghan/MS
+aficionado/MS
+afield
+afire
+aflame
+afloat
+aflutter
+afoot
+aforementioned
+aforesaid
+aforethought
+afoul
+afraid/U
+afresh
+aft/RZ
+afterbirth/M
+afterbirths
+afterburner/MS
+aftercare/M
+aftereffect/MS
+afterglow/SM
+afterimage/MS
+afterlife/M
+afterlives
+aftermarket/MS
+aftermath/M
+aftermaths
+afternoon/MS
+aftershave/SM
+aftershock/SM
+aftertaste/SM
+afterthought/SM
+afterward/S
+afterword/MS
+again
+against
+agape/M
+agar/M
+agate/MS
+agave/M
+age/DSMGJ
+ageing/SM
+ageism/M
+ageist/SM
+ageless/YP
+agelessness/M
+agency/SM
+agenda/SM
+agenesis
+agent/AMS
+ageratum/M
+agglomerate/DSMGNX
+agglomeration/M
+agglutinate/DSXGN
+agglutination/M
+aggrandize/GLDS
+aggrandizement/M
+aggravate/GNXDS
+aggravating/Y
+aggravation/M
+aggregate/MGNDSX
+aggregation/M
+aggregator/SM
+aggression/M
+aggressive/PY
+aggressiveness/M
+aggressor/SM
+aggrieve/DSG
+aggro
+aghast
+agile/Y
+agility/M
+aging/M
+agitate/XGNDS
+agitation/M
+agitator/MS
+agitprop/M
+agleam
+aglitter
+aglow
+agnostic/MS
+agnosticism/M
+ago
+agog
+agonist/S
+agonize/GDS
+agonizing/Y
+agony/SM
+agoraphobia/M
+agoraphobic/MS
+agrarian/MS
+agrarianism/M
+agree/EBLDS
+agreeableness/EM
+agreeably/E
+agreeing/E
+agreement/ESM
+agribusiness/MS
+agricultural/Y
+agriculturalist/MS
+agriculture/M
+agriculturist/MS
+agronomic
+agronomist/MS
+agronomy/M
+aground
+ague/M
+ah
+aha
+ahchoo
+ahead
+ahem
+ahoy
+aid/SMDRG
+aide/SM
+aided/U
+aider/M
+aigrette/MS
+ail/SDLG
+aileron/SM
+ailment/SM
+aim/SMDG
+aimless/YP
+aimlessness/M
+ain't
+air/SMDJG
+airbag/MS
+airbase/SM
+airbed/S
+airborne
+airbrush/MDSG
+airbus/MS
+aircraft/M
+aircraftman
+aircraftmen
+aircrew/S
+airdrome/S
+airdrop/SM
+airdropped
+airdropping
+airfare/SM
+airfield/SM
+airflow/M
+airfoil/SM
+airfreight/M
+airgun/S
+airhead/SM
+airily
+airiness/M
+airing/M
+airless/P
+airlessness/M
+airletter/S
+airlift/SGMD
+airline/RSMZ
+airliner/M
+airlock/SM
+airmail/GSMD
+airman/M
+airmen
+airplane/MS
+airplay/M
+airport/SM
+airship/SM
+airshow/S
+airsick/P
+airsickness/M
+airspace/M
+airspeed
+airstrike/MS
+airstrip/SM
+airtight
+airtime/M
+airwaves/M
+airway/MS
+airwoman
+airwomen
+airworthiness/M
+airworthy/P
+airy/PTR
+aisle/MS
+aitch/MS
+ajar
+aka
+akimbo
+akin
+al/YV
+alabaster/M
+alack
+alacrity/M
+alarm/GMDS
+alarming/Y
+alarmist/SM
+alas
+alb/SM
+albacore/SM
+albatross/MS
+albeit
+albinism/M
+albino/MS
+album/MNS
+albumen/M
+albumin/M
+albuminous
+alchemist/SM
+alchemy/M
+alcohol/SM
+alcoholic/MS
+alcoholically
+alcoholism/M
+alcove/MS
+alder/MS
+alderman/M
+aldermen
+alderwoman/M
+alderwomen
+ale/SM
+aleatory
+alehouse/SM
+alembic/SM
+alert/GMDYPS
+alertness/M
+alewife/M
+alewives
+alfalfa/M
+alfresco
+alga/M
+algae
+algal
+algebra/SM
+algebraic
+algebraically
+algorithm/SM
+algorithmic
+algorithmically
+alias/GMDS
+alibi/GMDS
+alien/BGMDS
+alienable/IU
+alienate/DSGN
+alienation/M
+alienist/SM
+alight/GDS
+align/ALGDS
+aligned/U
+aligner/MS
+alignment/AMS
+alike/U
+aliment/MDSG
+alimentary
+alimony/M
+aliveness/M
+aliyah/M
+aliyahs
+alkali/MS
+alkalies
+alkaline
+alkalinity/M
+alkalize/DSG
+alkaloid/SM
+alkoxy
+alkyd/MS
+all-nighter/S
+all/M
+allay/GDS
+allegation/MS
+allege/GDS
+alleged/Y
+allegiance/MS
+allegoric
+allegorical/Y
+allegorist/MS
+allegory/SM
+allegretto/MS
+allegro/MS
+allele/MS
+alleluia/SM
+allergen/SM
+allergenic
+allergic
+allergically
+allergist/SM
+allergy/SM
+alleviate/DSGN
+alleviation/M
+alley/MS
+alleyway/SM
+alliance/SM
+alligator/MS
+alliterate/DSXGNV
+alliteration/M
+alliterative/Y
+allocate/ADSGN
+allocation/AM
+allocations
+allot/LS
+allotment/SM
+allotted
+allotting
+allover
+allow/EGDS
+allowable/U
+allowably
+allowance/SM
+alloy/GMDS
+alloyed/U
+allspice/M
+allude/GDS
+allure/MGLDS
+allurement/MS
+alluring/Y
+allusion/SM
+allusive/PY
+allusiveness/M
+alluvial/M
+alluvium/SM
+ally/GDSM
+almanac/SM
+almighty
+almond/MS
+almoner/SM
+almost
+alms/M
+almshouse/MS
+aloe/SM
+aloft
+aloha/MS
+alone
+along
+alongshore
+alongside
+aloof/PY
+aloofness/M
+aloud
+alp/SM
+alpaca/MS
+alpha/MS
+alphabet/SM
+alphabetic
+alphabetical/Y
+alphabetization/SM
+alphabetize/ZGDRS
+alphabetizer/M
+alphanumeric
+alphanumerical/Y
+alpine/S
+already
+alright
+also
+alt/S
+altar/MS
+altarpiece/SM
+alter/GDBS
+alterable/U
+alteration/MS
+altercation/SM
+altered/U
+alternate/DSMYGNVX
+alternation/M
+alternative/MYS
+alternator/SM
+although
+altimeter/MS
+altitude/MS
+alto/SM
+altogether
+altruism/M
+altruist/SM
+altruistic
+altruistically
+alum/SM
+alumina/M
+aluminize/D
+aluminum/M
+alumna/M
+alumnae
+alumni
+alumnus/M
+alveolar/S
+always
+am/N
+amalgam/SM
+amalgamate/XGNDS
+amalgamation/M
+amanuenses
+amanuensis/M
+amaranth/M
+amaranths
+amaretto/M
+amaryllis/MS
+amass/GDS
+amateur/SM
+amateurish/YP
+amateurishness/M
+amateurism/M
+amatory
+amaze/LMGDS
+amazement/M
+amazing/Y
+amazon/MS
+amazonian
+ambassador/SM
+ambassadorial
+ambassadorship/MS
+ambassadress/MS
+amber/M
+ambergris/M
+ambiance/MS
+ambidexterity/M
+ambidextrous/Y
+ambience/MS
+ambient
+ambiguity/SM
+ambiguous/UY
+ambit
+ambition/MS
+ambitious/YP
+ambitiousness/M
+ambivalence/M
+ambivalent/Y
+amble/MZGDRS
+ambler/M
+ambrosia/M
+ambrosial
+ambulance/MS
+ambulanceman
+ambulancemen
+ambulancewoman
+ambulancewomen
+ambulant
+ambulate/DSXGN
+ambulation/M
+ambulatory/SM
+ambuscade/MGDS
+ambush/GMDS
+ameba/MS
+amebae
+amebic
+ameboid
+ameliorate/GNVDS
+amelioration/M
+amen/B
+amenability/M
+amenably
+amend/BLGDS
+amendment/SM
+amenity/SM
+amerce/GLDS
+amercement/SM
+americium/M
+amethyst/SM
+amiability/M
+amiable
+amiably
+amicability/M
+amicable
+amicably
+amici
+amicus
+amid
+amide/MS
+amidship/S
+amidst
+amigo/MS
+amine/S
+amino
+amir/SM
+amiss
+amitriptyline
+amity/M
+ammeter/SM
+ammo/M
+ammonia/M
+ammonium
+ammunition/M
+amnesia/M
+amnesiac/MS
+amnesic/SM
+amnesty/GDSM
+amniocenteses
+amniocentesis/M
+amnion/MS
+amniotic
+amoeba/MS
+amoebae
+amoebic
+amok
+among
+amongst
+amontillado/SM
+amoral/Y
+amorality/M
+amorous/YP
+amorousness/M
+amorphous/PY
+amorphousness/M
+amortization/SM
+amortize/DSGB
+amount/GMDS
+amour/MS
+amoxicillin
+amp/SMDY
+amperage/M
+ampere/MS
+ampersand/MS
+amphetamine/SM
+amphibian/MS
+amphibious/Y
+amphitheater/SM
+amphora/M
+amphorae
+ampicillin
+ample/TR
+amplification/M
+amplifier/M
+amplify/NDRSXZG
+amplitude/SM
+ampoule/MS
+ampule/MS
+amputate/GNDSX
+amputation/M
+amputee/MS
+amt
+amuck
+amulet/MS
+amuse/LGDS
+amusement/MS
+amusing/Y
+amygdala
+amylase/M
+amyloid
+an/CS
+anabolism/M
+anachronism/SM
+anachronistic
+anachronistically
+anaconda/SM
+anaerobe/SM
+anaerobic
+anaerobically
+anagram/MS
+anal/Y
+analgesia/M
+analgesic/SM
+analog/MS
+analogical/Y
+analogize/GDS
+analogous/YP
+analogousness/M
+analogue/SM
+analogy/SM
+analysand/MS
+analyses/A
+analysis/AM
+analyst/SM
+analytic/S
+analytical/Y
+analyticalally
+analyzable
+analyze/ADSG
+analyzer/SM
+anapest/SM
+anapestic/MS
+anaphylactic
+anaphylaxes
+anaphylaxis
+anarchic
+anarchically
+anarchism/M
+anarchist/MS
+anarchistic
+anarchy/M
+anathema/SM
+anathematize/DSG
+anatomic
+anatomical/Y
+anatomist/SM
+anatomize/DSG
+anatomy/SM
+ancestor/SM
+ancestral/Y
+ancestress/MS
+ancestry/SM
+anchor/MDGS
+anchorage/MS
+anchorite/MS
+anchorman/M
+anchormen
+anchorpeople
+anchorperson/SM
+anchorwoman/M
+anchorwomen
+anchovy/SM
+ancient/SPMRYT
+ancientness/M
+ancillary/SM
+and
+andante/SM
+andiron/SM
+androgen/M
+androgenic
+androgynous
+androgyny/M
+android/SM
+anecdotal/Y
+anecdote/MS
+anemia/M
+anemic
+anemically
+anemometer/SM
+anemone/SM
+anent
+anesthesia/M
+anesthesiologist/SM
+anesthesiology/M
+anesthetic/SM
+anesthetist/MS
+anesthetization/M
+anesthetize/GDS
+aneurysm/SM
+anew
+angel/MS
+angelfish/MS
+angelic
+angelica/M
+angelical/Y
+anger/GMDS
+angina/M
+angioplasty/SM
+angiosperm/SM
+angle/MZGDRS
+angler/M
+angleworm/MS
+anglicism/S
+anglicize/GDS
+angling/M
+anglophile/S
+anglophone/S
+angora/MS
+angostura
+angrily
+angry/TR
+angst/M
+angstrom/MS
+anguish/GMDS
+angular
+angularity/SM
+angulation
+anhydrous
+aniline/M
+anilingus
+animadversion/MS
+animadvert/GSD
+animal/MS
+animalcule/SM
+animate/ADSGN
+animated/Y
+animation/AM
+animations
+animator/MS
+anime/M
+animism/M
+animist/SM
+animistic
+animosity/SM
+animus/M
+anion/MS
+anionic
+anise/M
+aniseed/M
+anisette/M
+ankh/M
+ankhs
+ankle/MS
+anklebone/MS
+anklet/MS
+annalist/SM
+annals/M
+anneal/GDS
+annelid/MS
+annex/GMDS
+annexation/MS
+annihilate/DSGN
+annihilation/M
+annihilator/SM
+anniversary/SM
+annotate/DSXGNV
+annotation/M
+annotator/MS
+announce/DRSLZG
+announced/U
+announcement/MS
+announcer/M
+annoy/GDS
+annoyance/MS
+annoying/Y
+annual/MYS
+annualize/DG
+annuitant/SM
+annuity/SM
+annul/LS
+annular
+annulled
+annulling
+annulment/SM
+annulus
+annunciation/SM
+anode/MS
+anodize/GDS
+anodyne/MS
+anoint/GDLS
+anointment/M
+anomalous/Y
+anomaly/SM
+anon/S
+anonymity/M
+anonymization/MS
+anonymize/DSG
+anonymous/Y
+anopheles/M
+anorak/MS
+anorectic/SM
+anorexia/M
+anorexic/MS
+another/M
+answer/BMDGS
+answerable/U
+answered/U
+answerphone/S
+ant/SMD
+antacid/SM
+antagonism/SM
+antagonist/SM
+antagonistic
+antagonistically
+antagonize/DSG
+antarctic
+ante/SM
+anteater/MS
+antebellum
+antecedence/M
+antecedent/SM
+antechamber/SM
+antedate/GDS
+antediluvian
+anteing
+antelope/MS
+antenatal
+antenna/SM
+antennae
+anterior
+anteroom/MS
+anthem/MS
+anther/MS
+anthill/SM
+anthologist/SM
+anthologize/DSG
+anthology/SM
+anthracite/M
+anthrax/M
+anthropocentric
+anthropoid/MS
+anthropological/Y
+anthropologist/SM
+anthropology/M
+anthropomorphic
+anthropomorphically
+anthropomorphism/M
+anthropomorphize/DS
+anthropomorphous
+anti/SM
+antiabortion
+antiabortionist/MS
+antiaircraft
+antibacterial/MS
+antibiotic/MS
+antibody/SM
+antic/MS
+anticancer
+antichrist/SM
+anticipate/GNXDS
+anticipated/U
+anticipation/M
+anticipatory
+anticked
+anticking
+anticlerical
+anticlimactic
+anticlimactically
+anticlimax/MS
+anticline/SM
+anticlockwise
+anticoagulant/MS
+anticommunism/M
+anticommunist/SM
+anticyclone/SM
+anticyclonic
+antidemocratic
+antidepressant/MS
+antiderivative/S
+antidote/MS
+antifa
+antifascist/MS
+antiferromagnetic
+antifreeze/M
+antigen/SM
+antigenic
+antigenicity/M
+antihero/M
+antiheroes
+antihistamine/SM
+antiknock/M
+antilabor
+antilogarithm/SM
+antimacassar/MS
+antimalarial
+antimatter/M
+antimicrobial
+antimissile
+antimony/M
+antineutrino/SM
+antineutron/MS
+antinuclear
+antioxidant/MS
+antiparticle/SM
+antipasti
+antipasto/MS
+antipathetic
+antipathy/SM
+antipersonnel
+antiperspirant/SM
+antiphon/SM
+antiphonal/MYS
+antipodal/S
+antipodean/MS
+antipodes/M
+antipollution
+antipoverty
+antiproton/MS
+antiquarian/SM
+antiquarianism/M
+antiquary/SM
+antiquate/GDS
+antique/DSMG
+antiquity/SM
+antirrhinum/S
+antiscience
+antisemitic
+antisemitism/M
+antisense
+antisepsis/M
+antiseptic/SM
+antiseptically
+antiserum/MS
+antislavery
+antisocial/Y
+antispasmodic/MS
+antisubmarine
+antitank
+antitheses
+antithesis/M
+antithetic
+antithetical/Y
+antitoxin/MS
+antitrust
+antivenin/MS
+antivenom
+antiviral/MS
+antivirus/M
+antivivisectionist/MS
+antiwar
+antler/MDS
+antonym/SM
+antonymous
+antrum
+antsy/TR
+anus/MS
+anvil/MS
+anxiety/SM
+anxious/YP
+anxiousness/M
+any
+anybody/SM
+anyhow
+anymore
+anyone/M
+anyplace
+anything/SM
+anytime
+anyway/S
+anywhere
+anywise
+aorta/MS
+aortic
+apace
+apart
+apartheid/M
+apartment/MS
+apathetic
+apathetically
+apathy/M
+apatite/M
+apatosaurus/M
+ape/DSMG
+apelike
+aperitif/MS
+aperture/SM
+apex/MS
+aphasia/M
+aphasic/MS
+aphelia
+aphelion/SM
+aphid/MS
+aphorism/MS
+aphoristic
+aphoristically
+aphrodisiac/SM
+apiarist/SM
+apiary/SM
+apical/Y
+apiece
+apish/Y
+aplenty
+aplomb/M
+apocalypse/SM
+apocalyptic
+apocrypha/M
+apocryphal/Y
+apogee/MS
+apolitical/Y
+apologetic/U
+apologetically
+apologia/SM
+apologist/MS
+apologize/GDS
+apology/SM
+apoplectic
+apoplexy/SM
+apoptosis
+apoptotic
+apostasy/SM
+apostate/SM
+apostatize/GDS
+apostle/MS
+apostleship/M
+apostolic
+apostrophe/MS
+apothecary/SM
+apothegm/SM
+apotheoses
+apotheosis/M
+app/SM
+appall/GDS
+appalling/Y
+appaloosa/MS
+apparatchik/S
+apparatus/MS
+apparel/MDGS
+apparent/Y
+apparition/SM
+appeal/GBMDS
+appealing/UY
+appear/AESDG
+appearance/EAMS
+appease/LZGDRS
+appeasement/SM
+appeaser/M
+appellant/SM
+appellate/XN
+appellation/M
+append/GDS
+appendage/SM
+appendectomy/SM
+appendices
+appendicitis/M
+appendix/MS
+appertain/GDS
+appetite/SM
+appetizer/MS
+appetizing/Y
+applaud/ZGDRS
+applauder/M
+applause/M
+apple/MS
+applejack/M
+applesauce/M
+applet/MS
+appliance/SM
+applicability/M
+applicable/I
+applicably
+applicant/SM
+application/AM
+applicator/SM
+applier/MS
+applique/DSM
+appliqueing
+appliqu/SMG
+appliqud
+apply/ANXGDS
+appoint/AELSVGZRD
+appointee/SM
+appointment/AESM
+apportion/AGDLS
+apportionment/AM
+appose/GDS
+apposite/YNVP
+appositeness/M
+apposition/M
+appositive/SM
+appraisal/AMS
+appraise/ADSG
+appraiser/MS
+appreciable/I
+appreciably/I
+appreciate/DSXGNV
+appreciated/U
+appreciation/M
+appreciative/Y
+appreciator/MS
+appreciatory
+apprehend/GDS
+apprehension/MS
+apprehensive/YP
+apprehensiveness/M
+apprentice/DSMG
+apprenticeship/MS
+apprise/GDS
+apprize/GDS
+approach/GBMDS
+approachable/UI
+approbation/EM
+approbations
+appropriate/PYGNXDS
+appropriated/U
+appropriateness/IM
+appropriation/M
+appropriator/SM
+approval/EM
+approvals
+approve/EGDS
+approved/U
+approving/EY
+approx
+approximate/DSXYGN
+approximation/M
+appurtenance/SM
+appurtenant
+apricot/MS
+apron/MS
+apropos
+apse/SM
+apt/IYPT
+apter
+aptitude/SM
+aptness/IM
+aqua/SM
+aquaculture/M
+aqualung/MS
+aquamarine/SM
+aquanaut/MS
+aquaplane/MGDS
+aquarium/MS
+aquatic/SM
+aquatically
+aquatics/M
+aquatint/S
+aquavit/M
+aqueduct/MS
+aqueous
+aquifer/SM
+aquiline
+arXiv/M
+arabesque/MS
+arability/M
+arachnid/MS
+arachnophobia
+arbiter/SM
+arbitrage/MZGDRS
+arbitrager/M
+arbitrageur/SM
+arbitrament/SM
+arbitrarily
+arbitrariness/M
+arbitrary/P
+arbitrate/GNDS
+arbitration/M
+arbitrator/MS
+arbor/MS
+arboreal
+arboretum/SM
+arborvitae/SM
+arbutus/MS
+arc/SMDG
+arcade/MS
+arcane
+arch/PZTGVMDRSY
+archaeoastronomy/M
+archaeologic
+archaeological/Y
+archaeologist/SM
+archaeology/M
+archaeomagnetic
+archaeomagnetism
+archaic
+archaically
+archaism/MS
+archaist/MS
+archangel/MS
+archbishop/SM
+archbishopric/SM
+archdeacon/SM
+archdiocesan
+archdiocese/MS
+archduchess/MS
+archduke/MS
+archenemy/SM
+archeological/Y
+archeologist/SM
+archeology/M
+archer/M
+archery/M
+archetypal
+archetype/MS
+archfiend/MS
+archiepiscopal
+archipelago/MS
+archipelagoes
+architect/SM
+architectonic/S
+architectonics/M
+architectural/Y
+architecture/MS
+architrave/SM
+archival
+archive/DSMG
+archivist/MS
+archness/M
+archway/SM
+arctic/MS
+ardent/Y
+ardor/MS
+arduous/YP
+arduousness/M
+are/SMB
+area/SM
+areal
+aren't
+arena/MS
+areola/S
+areolae
+areolar
+areolate
+argent/M
+arginine
+argon/M
+argosy/SM
+argot/MS
+arguable/IU
+arguably/U
+argue/ZGDRS
+arguer/M
+argument/MS
+argumentation/M
+argumentative/PY
+argumentativeness/M
+argyle/MS
+aria/SM
+arid/Y
+aridity/M
+aright
+arise/GS
+arisen
+aristocracy/SM
+aristocrat/SM
+aristocratic
+aristocratically
+arithmetic/M
+arithmetical/Y
+arithmetician/MS
+ark/SM
+arm's
+arm/EAGDS
+armada/MS
+armadillo/SM
+armament/AEM
+armaments
+armature/MS
+armband/MS
+armchair/MS
+armed/U
+armful/MS
+armhole/SM
+armistice/SM
+armlet/MS
+armload/S
+armor/ZGMDRS
+armored/U
+armorer/M
+armorial
+armory/SM
+armpit/MS
+armrest/SM
+army/SM
+aroma/MS
+aromatherapist/MS
+aromatherapy/M
+aromatic/MS
+aromatically
+arose
+around
+arousal/M
+arouse/GDS
+arpeggio/MS
+arr
+arraign/DGSL
+arraignment/SM
+arrange/AESDLG
+arrangement/AESM
+arranger/SM
+arrant
+arras/MS
+array/EGMDS
+arrears/M
+arrest/AGMDS
+arrestee/S
+arrhythmia/M
+arrhythmic
+arrhythmical
+arrival/MS
+arrive/GDS
+arrogance/M
+arrogant/Y
+arrogate/GNDS
+arrogation/M
+arrow/MS
+arrowhead/MS
+arrowroot/M
+arroyo/MS
+arsed
+arsenal/MS
+arsenic/M
+arsing
+arson/M
+arsonist/SM
+art/SM
+arterial
+arteriole/MS
+arteriosclerosis/M
+artery/SM
+artful/PY
+artfulness/M
+arthritic/MS
+arthritis/M
+arthroplasty
+arthropod/MS
+arthroscope/SM
+arthroscopic
+arthroscopy
+artichoke/SM
+article/MDS
+articulacy/I
+articular
+articulate/YGNPDSX
+articulateness/IM
+articulation/M
+artifact/SM
+artifice/RSMZ
+artificer/M
+artificial/Y
+artificiality/M
+artillery/M
+artilleryman/M
+artillerymen
+artiness/M
+artisan/MS
+artisanal/Y
+artisanship/S
+artist/MS
+artiste/MS
+artistic/I
+artistically
+artistry/M
+artless/PY
+artlessness/M
+artsy/TR
+artwork/MS
+arty/PTR
+arugula
+arum/SM
+aryl/SM
+asap
+asbestos/M
+ascend/AGDS
+ascendance/M
+ascendancy/M
+ascendant/SM
+ascension/MS
+ascent/MS
+ascertain/GDSBL
+ascertainment/M
+ascetic/MS
+ascetically
+asceticism/M
+ascot/MS
+ascribe/GBDS
+ascription/M
+aseptic
+aseptically
+asexual/SY
+asexuality/M
+ash/MDNSG
+ashamed/UY
+ashcan/MS
+ashlar/MS
+ashore
+ashram/MS
+ashtray/SM
+ashy/TR
+aside/MS
+asinine/Y
+asininity/SM
+ask/SDG
+askance
+asked/U
+askew
+aslant
+asleep
+asocial
+asp/SMNX
+asparagus/M
+aspartame/M
+aspect/MS
+aspen/M
+asperity/SM
+aspersion/MS
+asphalt/MDGS
+asphodel/SM
+asphyxia/M
+asphyxiate/DSXGN
+asphyxiation/M
+aspic/MS
+aspidistra/MS
+aspirant/MS
+aspirate/MGNDSX
+aspiration/M
+aspirational/Y
+aspirator/SM
+aspire/GDS
+aspirin/MS
+ass/MS
+assail/GBDS
+assailable/U
+assailant/SM
+assassin/SM
+assassinate/GNXDS
+assassination/M
+assault/MDRGS
+assay/ZGMDRS
+assayer/M
+assemblage/SM
+assemble/ERZGSD
+assembler/EM
+assemblies
+assembly/EAM
+assemblyman/M
+assemblymen
+assemblywoman/M
+assemblywomen
+assent/GMDS
+assert/AGVDS
+assertion/AM
+assertions
+assertive/YP
+assertiveness/M
+assess/ALGDS
+assessment/ASM
+assessor/MS
+asset/MS
+asseverate/DSGN
+asseveration/M
+asshole/MS!
+assiduity/M
+assiduous/PY
+assiduousness/M
+assign's
+assign/ALGDS
+assignable
+assignation/MS
+assigned/U
+assignee/M
+assigner/MS
+assignment/AMS
+assignor/MS
+assimilate/DSGN
+assimilated/U
+assimilation/M
+assist/GVMDS
+assistance/M
+assistant/SM
+assisted/U
+assize/MS
+assn
+assoc
+associate's
+associate/EDSGNV
+association/EM
+associations
+associativity
+assonance/M
+assonant/MS
+assort/GLDS
+assortative
+assortment/MS
+asst
+assuage/GDS
+assume/BGDS
+assumption/SM
+assumptive
+assurance/ASM
+assure/AGDS
+assured/MYS
+astatine/M
+aster/EMS
+asterisk/GMDS
+astern
+asteroid/MS
+asthma/M
+asthmatic/SM
+asthmatically
+astigmatic
+astigmatism/SM
+astir
+astonish/DSLG
+astonishing/Y
+astonishment/M
+astound/GDS
+astounding/Y
+astraddle
+astrakhan/M
+astral
+astray
+astride
+astringency/M
+astringent/SMY
+astroarchaeology/SM
+astrobiology/M
+astrobleme/S
+astrolabe/SM
+astrologer/SM
+astrological/Y
+astrologist/MS
+astrology/M
+astronaut/MS
+astronautic/S
+astronautical
+astronautics/M
+astronomer/SM
+astronomic
+astronomical/Y
+astronomy/M
+astrophysical
+astrophysicist/MS
+astrophysics/M
+astute/PYTR
+astuteness/M
+asunder
+asylum/SM
+asymmetric
+asymmetrical/Y
+asymmetry/SM
+asymptomatic
+asymptote/S
+asymptotic
+asymptotically
+asynchronicity
+asynchronous/Y
+at
+atavism/M
+atavist/SM
+atavistic
+ataxia/M
+ataxic/MS
+ate
+atelier/SM
+atheism/M
+atheist/MS
+atheistic
+atherosclerosis/M
+atherosclerotic
+athirst
+athlete/MS
+athletic/S
+athletically
+athleticism
+athletics/M
+athwart
+atilt
+atishoo
+atlas/MS
+atmosphere/MS
+atmospheric/S
+atmospherically
+atmospherics/M
+atoll/MS
+atom/SM
+atomic
+atomically
+atomize/ZGDRS
+atomizer/M
+atonal/Y
+atonality/M
+atone/LGDS
+atonement/M
+atop
+atria
+atrial
+atrioventricular
+atrium/M
+atrocious/PY
+atrociousness/M
+atrocity/SM
+atrophy/DSMG
+atropine/M
+attach/ALGDS
+attache/BM
+attached/U
+attachment/AM
+attachments
+attach/MS
+attack/ZGMDRS
+attacker/M
+attain/AGDS
+attainability/M
+attainable/U
+attainder/M
+attainment/SM
+attar/M
+attempt's
+attempt/ASDG
+attend/SDRZG
+attendance/SM
+attendant/SM
+attended/U
+attendee/SM
+attention/IM
+attentions
+attentive/IPY
+attentiveness/IM
+attenuate/DSGN
+attenuated/U
+attenuation/M
+attest/SDG
+attestation/SM
+attested/U
+attic/SM
+attire/DSMG
+attitude/SM
+attitudinal
+attitudinize/GDS
+attn
+attorney/MS
+attract/SGVDB
+attractant/MS
+attraction/MS
+attractive/UY
+attractiveness/M
+attribute/DSMGNVBX
+attributed/U
+attribution/M
+attributive/MYS
+attrition/M
+attune/DSG
+atty
+atwitter
+atypical/Y
+aubergine/S
+auburn/M
+auction/MDGS
+auctioneer/SM
+audacious/YP
+audaciousness/M
+audacity/M
+audibility/IM
+audible/MS
+audibly/I
+audience/MS
+audio/MS
+audiological
+audiologist/SM
+audiology/M
+audiometer/SM
+audiophile/SM
+audiotape/SM
+audiovisual/S
+audiovisuals/M
+audit/BGMDS
+auditability
+auditee
+audition/SMDG
+auditor/MS
+auditorium/SM
+auditory
+auger/MS
+aught/MS
+augment/DRZGS
+augmentation/MS
+augmentative
+augmenter/M
+augur/GMDS
+augury/SM
+august/PTRY
+augustness/M
+auk/SM
+aunt/SM
+auntie/SM
+aura/MS
+aural/Y
+aurei
+aureola/M
+aureole/SM
+aureus
+auricle/SM
+auricular
+aurora/SM
+auscultate/GNDSX
+auscultation/M
+auspice/SM
+auspicious/IY
+auspiciousness/M
+austere/RYT
+austerity/SM
+austral
+auteur/SM
+authentic/IU
+authentically
+authenticate/XGNDS
+authenticated/U
+authentication/M
+authenticity/M
+author/SMDG
+authoress/MS
+authorial
+authoritarian/MS
+authoritarianism/M
+authoritative/YP
+authoritativeness/M
+authority/SM
+authorization/MS
+authorize/AGDS
+authorized/U
+authorship/M
+autism/M
+autistic
+auto/MS
+autobahn/SM
+autobiographer/SM
+autobiographic
+autobiographical/Y
+autobiography/SM
+autoclave/MS
+autocomplete/S
+autocorrect/SGMD
+autocracy/SM
+autocrat/SM
+autocratic
+autocratically
+autocross
+autodidact/SM
+autograph/MDG
+autographs
+autoimmune
+autoimmunity/M
+automaker/SM
+automata
+automate/GNDS
+automatic/SM
+automatically
+automation/M
+automatism/M
+automatize/GDS
+automaton/SM
+automobile/DSMG
+automotive
+autonomic
+autonomous/Y
+autonomy/M
+autopilot/SM
+autopsy/GDSM
+autosuggestion
+autoworker/MS
+autumn/SM
+autumnal
+aux
+auxiliary/SM
+auxin/M
+av/RZ
+avail/BGMDS
+availability/UM
+available/U
+avalanche/SM
+avant-garde
+avarice/M
+avaricious/Y
+avast
+avatar/MS
+avaunt
+avdp
+ave
+avenge/ZGDRS
+avenger/M
+avenue/MS
+average/MYGDS
+averred
+averring
+averse/XN
+aversion/M
+avert/GDS
+avg
+avian
+aviary/SM
+aviation/M
+aviator/MS
+aviatrices
+aviatrix/MS
+avid/Y
+avidity/M
+avionic/S
+avionics/M
+avitaminosis/M
+avo/S
+avocado/SM
+avocation/MS
+avocational
+avoid/SDGB
+avoidable/U
+avoidably/U
+avoidance/M
+avoidant
+avoirdupois/M
+avouch/DSG
+avow/EDGS
+avowal/ESM
+avowed/Y
+avuncular/Y
+aw
+await/GDS
+awake/GS
+awaken/AGDS
+awakening/SM
+award/GMDS
+awardee/S
+aware/UP
+awareness/UM
+awash
+away
+awe/DSMG
+aweigh
+awesome/YP
+awesomeness/M
+awestruck
+awful/YP
+awfuller
+awfullest
+awfulness/M
+awhile
+awkward/RYPT
+awkwardness/M
+awl/SM
+awn/GJSM
+awning/M
+awoke
+awoken
+awol
+awry
+ax/MDSG
+axe/M
+axial/Y
+axiom/SM
+axiomatic
+axiomatically
+axis/M
+axle/MS
+axletree/SM
+axolotl/SM
+axon/MS
+ayah/M
+ayahs
+ayatollah/M
+ayatollahs
+aye/SM
+azalea/SM
+azimuth/M
+azimuths
+azure/SM
+b/KDT
+baa/SMDG
+babble/MZGDRS
+babbler/M
+babe/SM
+babel/MS
+baboon/MS
+babushka/SM
+baby/TGDRSM
+babyhood/M
+babyish
+babysat
+babysit/S
+babysitter/MS
+babysitting/M
+baccalaureate/SM
+baccarat/M
+bacchanal/MS
+bacchanalia/M
+bacchanalian/MS
+baccy
+bachelor/SM
+bachelorhood/M
+bacillary
+bacilli
+bacillus/M
+back/SJZGMDR
+backache/MS
+backbench/S
+backbit
+backbite/ZGRS
+backbiter/M
+backbitten
+backboard/SM
+backbone/MS
+backbreaking
+backchat
+backcloth
+backcloths
+backcomb/DSG
+backdate/GDS
+backdoor
+backdrop/MS
+backer/M
+backfield/SM
+backfire/MGDS
+backgammon/M
+background/MRZS
+backgrounder/M
+backhand/MDRSZG
+backhanded/Y
+backhander/M
+backhoe/MS
+backing/M
+backlash/MS
+backless
+backlight/MSG
+backlighting/M
+backlit
+backlog/MS
+backlogged
+backlogging
+backpack/ZGMDRS
+backpacker/M
+backpacking/M
+backpedal/SDG
+backrest/SM
+backroom/S
+backscratching/M
+backseat/SM
+backside/SM
+backslapper/SM
+backslapping/M
+backslash/MS
+backslid
+backslide/RSZG
+backslider/M
+backspace/DSMG
+backspin/M
+backsplash/S
+backstab/S
+backstabber/MS
+backstabbing
+backstabby
+backstage/M
+backstair/S
+backstop/SM
+backstopped
+backstopping
+backstory/S
+backstreet/S
+backstretch/MS
+backstroke/MGDS
+backtalk/M
+backtrack/SDG
+backup/MS
+backward/PSY
+backwardness/M
+backwash/M
+backwater/SM
+backwoods/M
+backwoodsman/M
+backwoodsmen
+backyard/SM
+bacon/M
+bacteria/M
+bacterial
+bactericidal
+bactericide/SM
+bacteriologic
+bacteriological
+bacteriologist/SM
+bacteriology/M
+bacterium/M
+bad/MYP
+badass/S
+badder
+baddest
+baddie/M
+baddy/SM
+bade
+badge/MZGRS
+badger/GMD
+badinage/M
+badlands/M
+badman/M
+badmen
+badminton/M
+badmouth/GD
+badmouths
+badness/M
+baffle/MZGDRSL
+bafflement/M
+baffler/M
+bag/SM
+bagatelle/SM
+bagel/MS
+bagful/MS
+baggage/M
+bagged
+baggie/M
+baggily
+bagginess/M
+bagging
+baggy/PTRS
+bagpipe/MZRS
+bagpiper/M
+baguette/MS
+bah
+baht/SM
+bail/SBGMD
+bailey/S
+bailiff/S
+bailiwick/MS
+bailout/SM
+bailsman/M
+bailsmen
+bairn/MS
+bait/SGMD
+baize/M
+bake/DRSMZG
+baked/U
+baker/M
+bakery/SM
+bakeshop/MS
+baklava/M
+baksheesh/M
+balaclava/MS
+balalaika/MS
+balance's
+balance/UDSG
+balancer/S
+balanitis
+balanoposthitis
+balboa/SM
+balcony/SM
+bald/STGPDRY
+balderdash/M
+baldfaced
+baldness/M
+baldric/SM
+baldy/S
+bale/DRSMZG
+baleen/M
+baleful/PY
+balefulness/M
+baler/M
+balk/SGMD
+balkanization
+balkanize/GDS
+balky/RT
+ball/SGMD
+ballad/SM
+balladeer/MS
+balladry/M
+ballast/GSMD
+ballcock/MS
+ballerina/SM
+ballet/SM
+balletic
+ballgame/MS
+ballgirl/S
+ballgown/S
+ballistic/S
+ballistically
+ballistics/M
+balloon/SGMD
+balloonist/MS
+ballot/SMDG
+ballpark/MS
+ballplayer/MS
+ballpoint/MS
+ballroom/MS
+balls/DSG
+ballsy/RT
+bally
+ballyhoo/SMDG
+balm/SM
+balminess/M
+balmy/RTP
+baloney/M
+balsa/MS
+balsam/SM
+balsamic
+baluster/SM
+balustrade/MS
+bamboo/SM
+bamboozle/DSG
+ban/SM
+banal/Y
+banality/SM
+banana/SM
+banc/S
+band's
+band/ESGD
+bandage/DSMG
+bandana/SM
+bandanna/MS
+bandbox/MS
+bandeau/M
+bandeaux
+bandicoot/MS
+bandit/SM
+banditry/M
+bandleader/S
+bandmaster/SM
+bandoleer/SM
+bandolier/SM
+bandsman/M
+bandsmen
+bandstand/SM
+bandwagon/SM
+bandwidth
+bandwidths
+bandy/DRSTG
+bane/SM
+baneful
+bang/SGMDR
+bangle/SM
+bani
+banish/GLDS
+banishment/M
+banister/SM
+banjo/MS
+banjoist/SM
+bank/SZGBMDR
+bankbook/SM
+bankcard/SM
+banker/M
+banking/M
+banknote/SM
+bankroll/SGMD
+bankrupt/SGMD
+bankruptcy/SM
+banned
+banner/SM
+banning
+bannock/MS
+banns/M
+banquet/ZGMDRS
+banqueter/M
+banquette/SM
+banshee/MS
+bantam/SM
+bantamweight/SM
+banter/GSMD
+bantering/Y
+banyan/SM
+banzai/SM
+baobab/SM
+bap/S
+baptism/MS
+baptismal
+baptist/S
+baptistery/SM
+baptistry/SM
+baptize/ZGDRS
+baptized/U
+baptizer/M
+bar's
+bar/ECAUTS
+barb/SZGMDR
+barbacoa
+barbarian/SM
+barbarianism/MS
+barbaric
+barbarically
+barbarism/SM
+barbarity/SM
+barbarize/DSG
+barbarous/Y
+barbecue/DSMG
+barbel/SM
+barbell/MS
+barber/GMD
+barberry/SM
+barbershop/MS
+barbie/S
+barbiturate/SM
+barbwire/M
+barcarole/SM
+barcode/GDS
+bard/SM
+bardic
+bare/DRSPYG
+bareback/D
+barefaced/Y
+barefoot/D
+barehanded
+bareheaded
+barelegged
+bareness/M
+barf/SGMDY
+barfly/SM
+bargain/MDRZGS
+bargainer/M
+barge/MGDS
+bargeman/M
+bargemen
+barhop/S
+barhopped
+barhopping
+barista/MS
+baritone/MS
+barium/M
+bark's
+bark/CSGD
+barkeep/ZMRS
+barkeeper/M
+barker/SM
+barley/M
+barmaid/MS
+barman/M
+barmen
+barmy/RT
+barn/SM
+barnacle/MDS
+barney/S
+barnstorm/SDRZG
+barnstormer/M
+barnyard/SM
+barometer/MS
+barometric
+barometrically
+baron/MS
+baronage/MS
+baroness/MS
+baronet/MS
+baronetcy/SM
+baronial
+barony/SM
+baroque/M
+barque/SM
+barrack/MDGS
+barracuda/SM
+barrage/MGDS
+barre/MGJDS
+barred/UEC
+barrel/GSMD
+barrelled
+barrelling
+barren/TPSMR
+barrenness/M
+barrette/SM
+barricade/MGDS
+barrier/MS
+barring/ECU
+barrio/SM
+barrister/MS
+barroom/MS
+barrow/SM
+bartender/SM
+barter/ZGSMDR
+barterer/M
+baryon/SM
+baryonic
+basal/Y
+basalt/M
+basaltic
+base's
+base/CDSLTG
+baseball/SM
+baseboard/MS
+baseless
+baseline/MS
+basely
+baseman/M
+basemen
+basement/CMS
+baseness/M
+baser
+bash/GMDS
+bashful/PY
+bashfulness/M
+bashing/M
+basic/MS
+basically
+basil/M
+basilar
+basilica/MS
+basilisk/MS
+basin/MS
+basinful/MS
+basis/M
+bask/SGD
+basket/SM
+basketball/MS
+basketry/M
+basketwork/M
+basque/S
+bass/MS
+basset/SM
+bassinet/MS
+bassist/MS
+basso/MS
+bassoon/MS
+bassoonist/SM
+basswood/MS
+bast/M
+bastard/MS
+bastardization/MS
+bastardize/GDS
+bastardy/M
+baste/ZGNXDRS
+baster/M
+bastion/M
+bat/SM
+batch/MDSG
+bate/KACGSD
+bath/ZGMDRS
+bathe/M
+bather/M
+bathetic
+bathhouse/MS
+bathing/M
+bathmat/MS
+bathos/M
+bathrobe/SM
+bathroom/SM
+baths
+bathtub/MS
+bathwater
+bathyscaph/MS
+bathyscaphe/M
+bathyscaphs
+bathysphere/MS
+batik/MS
+batiste/M
+batman/M
+batmen
+baton/MS
+batsman/M
+batsmen
+battalion/SM
+batted
+batten/GSMD
+batter/JZGSMDR
+batterer/M
+battery/SM
+batting/M
+battle/LDRSMZG
+battleax/MS
+battleaxe/M
+battledore/SM
+battledress
+battlefield/MS
+battlefront/MS
+battleground/MS
+battlement/SM
+battler/M
+battleship/SM
+batty/RT
+bauble/SM
+baud/SM
+bauxite/M
+bawd/SM
+bawdily
+bawdiness/M
+bawdy/PRT
+bawl/SGMD
+bay/SMDG
+bayberry/SM
+bayonet/SMDG
+bayou/MS
+bazaar/SM
+bazillion/S
+bazooka/SM
+bbl
+bdrm
+be
+beach/MDSG
+beachcomber/SM
+beachfront
+beachhead/MS
+beachwear/M
+beacon/SM
+bead/SGMD
+beading/M
+beadle/SM
+beady/RT
+beagle/SM
+beak/SZMDR
+beaker/M
+beam/SGMD
+bean/SGMD
+beanbag/MS
+beanfeast/S
+beanie/SM
+beanpole/MS
+beansprout/S
+beanstalk/MS
+bear/SZGBJMR
+bearable/U
+bearably/U
+beard/MDGS
+beardless
+bearer/M
+bearing/M
+bearish/PY
+bearishness/M
+bearlike
+bearskin/MS
+beast/MS
+beastliness/M
+beastly/TPRM
+beat/SZGBMNRJ
+beatable/U
+beaten/U
+beater/M
+beatific
+beatifically
+beatification/M
+beatify/GXNDS
+beating/M
+beatitude/SM
+beatnik/MS
+beau/SM
+beaucoup
+beaut/MS
+beauteous/Y
+beautician/SM
+beautification/M
+beautifier/M
+beautiful/Y
+beautify/NDRSZG
+beauty/SM
+beaux
+beaver/SGMD
+bebop/MS
+becalm/GSD
+became
+because
+beck/SM
+beckon/SGD
+becloud/GDS
+become/S
+becoming/UY
+becquerel/S
+bed/SM
+bedaub/GSD
+bedazzle/GDSL
+bedazzlement/M
+bedbug/SM
+bedchamber/S
+bedclothes/M
+bedded
+bedder
+bedding/M
+bedeck/GSD
+bedevil/LGDS
+bedevilment/M
+bedfellow/SM
+bedhead/S
+bedim/S
+bedimmed
+bedimming
+bedizen/GDS
+bedlam/SM
+bedpan/SM
+bedpost/SM
+bedraggle/GDS
+bedridden
+bedrock/SM
+bedroll/SM
+bedroom/SM
+bedside/SM
+bedsit/S
+bedsitter/S
+bedsore/SM
+bedspread/SM
+bedstead/SM
+bedtime/SM
+bee/RSMZGJ
+beebread/M
+beech/MS
+beechnut/MS
+beef/SGMD
+beefburger/SM
+beefcake/MS
+beefiness/M
+beefsteak/MS
+beefy/RPT
+beehive/MS
+beekeeper/MS
+beekeeping/M
+beeline/MS
+been
+beep/SZGMDR
+beeper/M
+beer/M
+beery/TR
+beeswax/M
+beet/SM
+beetle/MGDS
+beetroot/S
+beeves
+befall/SGN
+befell
+befit/S
+befitted
+befitting/Y
+befog/S
+befogged
+befogging
+before
+beforehand
+befoul/DGS
+befriend/SGD
+befuddle/GLDS
+befuddlement/M
+beg/S
+began
+begat
+beget/S
+begetter/S
+begetting
+beggar/MDYGS
+beggary/M
+begged
+begging
+begin/S
+beginner/SM
+beginning/MS
+begone
+begonia/SM
+begot
+begotten
+begrime/DSG
+begrudge/DSG
+begrudging/Y
+beguile/DRSZGL
+beguilement/M
+beguiler/M
+beguiling/Y
+beguine/SM
+begum/MS
+begun
+behalf/M
+behalves
+behave/GDS
+behavior/SM
+behavioral/Y
+behaviorism/M
+behaviorist/MS
+behead/DGS
+beheld
+behemoth/M
+behemoths
+behest/MS
+behind/MS
+behindhand
+behold/NRZGS
+beholder/M
+behoove/DSG
+beige/M
+being/M
+bejewel/SDG
+belabor/SDG
+belated/Y
+belay/GDS
+belch/ZGMDRS
+belcher/M
+beleaguer/GSD
+belfry/SM
+belie/DS
+belief/EUM
+beliefs
+believable/U
+believably/U
+believe/EDRSZG
+believer/EUMS
+believing/U
+belittle/LDSG
+belittlement/M
+bell/SGMD
+belladonna/M
+bellboy/SM
+belle/MS
+belled/A
+belletrist/MS
+belletristic
+bellhop/SM
+bellicose
+bellicosity/M
+belligerence/M
+belligerency/M
+belligerent/MYS
+belling/A
+bellman/M
+bellmen
+bellow/MDGS
+bellwether/MS
+belly/GDSM
+bellyache/MGDS
+bellybutton/SM
+bellyful/MS
+belong/JDGS
+belonging/M
+beloved/SM
+below
+belt/SGMD
+beltway/SM
+beluga/MS
+belying
+bemire/GDS
+bemoan/DGS
+bemuse/LGDS
+bemused/Y
+bemusement/M
+bench/GMDS
+benchmark/MS
+bend/BSZGMR
+bender/M
+bendy/TR
+beneath
+benedictine
+benediction/SM
+benedictory
+benefaction/SM
+benefactor/MS
+benefactress/MS
+benefice/SM
+beneficence/M
+beneficent/Y
+beneficial/Y
+beneficiary/SM
+benefit/SMDG
+benevolence/SM
+benevolent/Y
+benighted/Y
+benign/Y
+benignant
+benignity/M
+bent/SM
+bentonite
+bentwood/M
+benumb/DSG
+benzene/M
+benzine/M
+benzyl
+bequeath/DG
+bequeaths
+bequest/MS
+berate/GDS
+bereave/DSLG
+bereavement/MS
+bereft
+beret/MS
+berg/SM
+beriberi/M
+berk/S
+berkelium/M
+berm/SM
+berry/GDSM
+berrylike
+berserk
+berth/GMD
+berths
+beryl/MS
+beryllium/M
+beseech/ZGRS
+beseecher/M
+beseeching/Y
+beseem/DSG
+beset/S
+besetting
+beside/S
+besiege/ZGDRS
+besieger/M
+besmear/DSG
+besmirch/GDS
+besom/MS
+besot/S
+besotted
+besotting
+besought
+bespangle/DSG
+bespatter/GSD
+bespeak/SG
+bespectacled
+bespoke
+bespoken
+best/SGMD
+bestial/Y
+bestiality/M
+bestiary/SM
+bestir/S
+bestirred
+bestirring
+bestow/DGS
+bestowal/SM
+bestrew/SDG
+bestrewn
+bestridden
+bestride/SG
+bestrode
+bestseller/MS
+bestselling
+bet/SM
+beta/SM
+betake/GS
+betaken
+betcha
+betel/M
+bethink/SG
+bethought
+betide/GDS
+betimes
+betoken/GDS
+betook
+betray/DRZGS
+betrayal/SM
+betrayer/M
+betroth/DG
+betrothal/SM
+betrothed/M
+betroths
+better/MDGLS
+betterment/M
+betting
+bettor/MS
+between
+betwixt
+bevel/GMDS
+beverage/SM
+bevvy/S
+bevy/SM
+bewail/DGS
+beware/GDS
+bewhiskered
+bewigged
+bewilder/LSGD
+bewildering/Y
+bewilderment/M
+bewitch/GLDS
+bewitching/Y
+bewitchment/M
+bey/SM
+beyond
+bezel/MS
+bf
+bhaji
+bi/SMRZ
+biannual/Y
+bias/GMDS
+biased/U
+biassed
+biassing
+biathlon/SM
+bib/SM
+bible/MS
+biblical/Y
+bibliographer/MS
+bibliographic
+bibliographical/Y
+bibliography/SM
+bibliophile/SM
+bibulous
+bicameral
+bicameralism/M
+bicarb/MS
+bicarbonate/MS
+bicentenary/SM
+bicentennial/SM
+bicep/MS
+biceps/M
+bicker/MDRZGS
+bickerer/M
+biconcave
+biconvex
+bicuspid/MS
+bicycle/DRSMZG
+bicycler/M
+bicyclist/SM
+bid/SMG
+biddable
+bidden/U
+bidder/MS
+bidding/M
+biddy/SM
+bide/S
+bidet/MS
+bidirectional/Y
+biennial/MYS
+biennium/MS
+bier/M
+biff/SGD
+bifida
+bifocal/S
+bifocals/M
+bifurcate/XDSGN
+bifurcation/M
+big/P
+bigamist/SM
+bigamous
+bigamy/M
+bigger
+biggest
+biggie/MS
+biggish
+bighead/SM
+bighearted/P
+bigheartedness/M
+bighorn/SM
+bight/MS
+bigmouth/M
+bigmouths
+bigness/M
+bigot/MDS
+bigotry/SM
+bigwig/MS
+bijection/S
+bijou/M
+bijoux
+bike/DRSMZG
+biker/M
+bikini/MS
+bilabial/MS
+bilateral/Y
+bilberry/S
+bile/M
+bilge/MS
+bilingual/SMY
+bilingualism/M
+bilious/P
+biliousness/M
+bilirubin
+bilk/SZGDR
+bilker/M
+bill/SBJGMD
+billboard/MS
+billet/GMDS
+billfold/SM
+billhook/S
+billiard/S
+billiards/M
+billing/M
+billingsgate/M
+billion/MHS
+billionaire/SM
+billionth/M
+billionths
+billow/GMDS
+billowy
+billy/SM
+billycan/S
+bimbo/MS
+bimetallic/SM
+bimetallism/M
+bimodal
+bimonthly/SM
+bin/SM
+binary/SM
+binaural
+bind's
+bind/AUGS
+binder/MS
+bindery/SM
+binding/MS
+bindweed/M
+binge/MGDS
+bingeable
+bingeing
+bingo/M
+binman
+binmen
+binnacle/SM
+binned
+binning
+binocular/MS
+binomial/SM
+bio/SM
+biochem
+biochemical/SMY
+biochemist/MS
+biochemistry/M
+biocomputing/M
+biodegradability/M
+biodegrade/DSGB
+biodiesel/M
+biodiversity/M
+bioethics/M
+biofeedback/M
+biofilm/MS
+biog
+biograph/ZGMDR
+biographer/M
+biographic
+biographical/Y
+biographs
+biography/SM
+biohacker/MS
+biohacking
+bioinformatic/MS
+biol
+biologic
+biological/Y
+biologist/MS
+biology/SM
+biomarker/MS
+biomass/MS
+biomechanics
+biomedical
+biomedicine
+bionic/S
+bionically
+bionics/M
+biophysical
+biophysicist/MS
+biophysics/M
+biopic/MS
+biopsy/GDSM
+bioreactor/S
+biorhythm/MS
+biorobotics
+biosecurity/M
+biosensor/S
+biosphere/SM
+biostatistics
+biosyntheses
+biosynthesis
+biotech/M
+biotechnological
+biotechnology/SM
+biotherapy/SM
+biotin/M
+biotope/SM
+biozone/SM
+bipartisan
+bipartisanship/M
+bipartite
+biped/MS
+bipedal
+biplane/MS
+bipolar
+bipolarity/M
+biracial
+birch/GMDS
+bird/SZGMDR
+birdbath/M
+birdbaths
+birdbrain/SMD
+birdcage/S
+birder/M
+birdhouse/MS
+birdie/MDS
+birdieing
+birdlike
+birdlime/M
+birdseed/M
+birdsong
+birdwatcher/SM
+birdying
+biretta/SM
+birth/ZGMDR
+birthday/MS
+birther/M
+birthmark/MS
+birthplace/MS
+birthrate/MS
+birthright/MS
+births/A
+birthstone/SM
+biscotti
+biscotto
+biscuit/SM
+bisect/DGS
+bisection/MS
+bisector/SM
+bisexual/MYS
+bisexuality/M
+bishop/MS
+bishopric/SM
+bismuth/M
+bison/M
+bisque/M
+bistro/MS
+bit/CSMG
+bitch/GMDS
+bitchily
+bitchiness/M
+bitchy/PRT
+bitcoin/SM
+bite/RSMZ
+biter/M
+biting/Y
+bitmap/S
+bitten
+bitter/PMRYTS
+bittern/SM
+bitterness/M
+bitters/M
+bittersweet/MS
+bitty/TR
+bitumen/M
+bituminous
+bivalent
+bivalve/SM
+bivouac/MS
+bivouacked
+bivouacking
+biweekly/SM
+biyearly
+biz/M
+bizarre/Y
+bk
+bl/DG
+blab/SM
+blabbed
+blabber/DGS
+blabbermouth/M
+blabbermouths
+blabbing
+black/PXTGMDNRYS
+blackamoor/MS
+blackball/SGMD
+blackberry/GSM
+blackbird/SM
+blackboard/MS
+blackcurrant/S
+blacken/DG
+blackface
+blackguard/SM
+blackhead/MS
+blacking/M
+blackish
+blackjack/MDGS
+blackleg/S
+blacklist/MDSG
+blackmail/MDRSZG
+blackmailer/M
+blackness/M
+blackout/SM
+blacksmith/MG
+blacksmiths
+blacksnake/SM
+blackthorn/SM
+blacktop/SM
+blacktopped
+blacktopping
+bladder/MS
+blade/MDS
+blag/S
+blagged
+blagging
+blah/M
+blahs/M
+blame/BMGDRS
+blameable
+blameless/YP
+blamelessness/M
+blameworthiness/M
+blameworthy/P
+blammo
+blanch/GDS
+blanche
+blancmange/MS
+bland/PTRY
+blandish/DSLG
+blandishment/SM
+blandness/M
+blank/TGPMDRYS
+blanket/GMDS
+blankness/M
+blare/MGDS
+blarney/SMDG
+blase
+blaspheme/ZGDRS
+blasphemer/M
+blasphemous/Y
+blasphemy/SM
+blast/ZGMDRS
+blaster/M
+blastoff/MS
+blas
+blat/S
+blatancy/SM
+blatant/Y
+blather/SMDG
+blaze/MZGDRS
+blazer/M
+blazon/MDGS
+bldg
+bleach/MDRSZG
+bleached/U
+bleacher/M
+bleak/TPRY
+bleakness/M
+blear
+blearily
+bleariness/M
+bleary/PRT
+bleat/GMDS
+bleed/ZGRS
+bleeder/M
+bleeding/M
+bleep/ZGMDRS
+bleeper/M
+blemish/GMDS
+blemished/U
+blench/DSG
+blend/ZGMDRS
+blender/M
+bless/GDSJ
+blessed/YP
+blessedness/M
+blessing/M
+bletch
+blew
+blight/ZGMDRS
+blimey
+blimp/MS
+blimpish
+blind/PZTGMDRYS
+blinder/M
+blindfold/SMDG
+blinding/Y
+blindness/M
+blindside/DSG
+blini/MS
+blink/ZGMDRS
+blinker/MDG
+blintz/MS
+blintze/M
+blip/SM
+bliss/M
+blissful/YP
+blissfulness/M
+blister/GMDS
+blistering/Y
+blistery
+blithe/PYTR
+blitheness/M
+blither/G
+blithesome
+blitz/GMDS
+blitzkrieg/MS
+blivet/S
+blizzard/SM
+bloat/ZGDRS
+bloatware
+blob/SM
+blobbed
+blobbing
+bloc/SM
+block's
+block/UGDS
+blockade/MZGDRS
+blockader/M
+blockage/MS
+blockbuster/SM
+blockbusting/M
+blockchain/MS
+blocker/MS
+blockhead/SM
+blockhouse/MS
+blog/SM
+blogged
+blogger/MS
+blogging
+blogroll/SM
+bloke/MS
+blokish
+blond/PTMRS
+blonde/MS
+blondish
+blondness/M
+blood/GMDS
+bloodbath/M
+bloodbaths
+bloodcurdling
+bloodhound/SM
+bloodily
+bloodiness/M
+bloodless/YP
+bloodlessness/M
+bloodletting/M
+bloodline/SM
+bloodmobile/MS
+bloodshed/M
+bloodshot
+bloodstain/SMD
+bloodstock/M
+bloodstream/SM
+bloodsucker/SM
+bloodsucking
+bloodthirstily
+bloodthirstiness/M
+bloodthirsty/RPT
+bloody/PTGDRS
+bloom/ZGMDRS
+bloomer/M
+bloop/ZGMDRS
+blooper/M
+blossom/GMDS
+blossomy
+blot/SM
+blotch/GMDS
+blotchy/TR
+blotted
+blotter/MS
+blotting
+blotto
+blouse/MGDS
+bloviate/GNDS
+bloviator/MS
+blow/SZGMR
+blower/M
+blowfly/SM
+blowgun/MS
+blowhard/MS
+blowhole/S
+blowjob/SM
+blowlamp/S
+blown
+blowout/SM
+blowpipe/SM
+blowsy/RT
+blowtorch/MS
+blowup/MS
+blowy/TR
+blowzy/RT
+blubber/GSMD
+blubbery
+bludgeon/MDGS
+blue/DRSPMTG
+bluebell/MS
+blueberry/SM
+bluebird/MS
+bluebonnet/SM
+bluebottle/SM
+bluefish/MS
+bluegill/MS
+bluegrass/M
+blueing/M
+blueish
+bluejacket/SM
+bluejay/SM
+bluejeans/M
+blueness/M
+bluenose/MS
+bluepoint/MS
+blueprint/MDGS
+bluestocking/SM
+bluesy/RT
+bluet/MS
+bluff/ZTGPMDRYS
+bluffer/M
+bluffness/M
+bluing/M
+bluish
+blunder/MDRZGS
+blunderbuss/MS
+blunderer/M
+blunt/PTGDRYS
+bluntness/M
+blur/SM
+blurb/MS
+blurred
+blurriness/M
+blurring
+blurry/TRP
+blurt/GDS
+blush/ZGMDRS
+blusher/M
+bluster/MDRSZG
+blusterer/M
+blusterous
+blustery
+blvd
+boa/SM
+boar/SM
+board/ZGMDRS
+boarder/M
+boarding/M
+boardinghouse/MS
+boardroom/MS
+boardwalk/MS
+boast/ZGMDRS
+boaster/M
+boastful/PY
+boastfulness/M
+boat/SZGMDR
+boater/M
+boathouse/MS
+boating/M
+boatload/S
+boatman/M
+boatmen
+boatswain/SM
+boatyard/S
+bob/SM
+bobbed
+bobbin/MS
+bobbing
+bobble/MGDS
+bobby/SM
+bobbysoxer/SM
+bobcat/MS
+bobolink/SM
+bobsled/SM
+bobsledded
+bobsledder/MS
+bobsledding
+bobsleigh/M
+bobsleighs
+bobtail/SM
+bobwhite/MS
+bocce/M
+bocci/M
+boccie/M
+bock/M
+bod/SMDG
+bodacious
+bode/S
+bodega/MS
+bodge/GDS
+bodice/MS
+bodily
+bodkin/MS
+body/DSM
+bodybuilder/SM
+bodybuilding/M
+bodyguard/MS
+bodysuit/SM
+bodywork/M
+boffin/S
+boffo
+bog/SM
+boga
+bogey/GMDS
+bogeyman/M
+bogeymen
+bogged
+bogging
+boggle/GDS
+boggy/TR
+bogie/MS
+bogon
+bogosity
+bogus
+bogyman/M
+bogymen
+bohemian/SM
+bohemianism/M
+boil/SJZGMDR
+boiler/M
+boilermaker/SM
+boilerplate/M
+boink/GDS
+boisterous/YP
+boisterousness/M
+bola/SM
+bold/PTRY
+boldface/DM
+boldness/M
+bole/SM
+bolero/MS
+bolivar/MS
+bolivares
+boll/SM
+bollard/S
+bollix/GMDS
+bollocking/S
+bollocks
+bologna/M
+bolshevik/SM
+bolshie
+bolshy
+bolster/GMDS
+bolt's
+bolt/USGD
+bolthole/S
+bolus/MS
+bomb/SJZGMDR
+bombard/GDLS
+bombardier/MS
+bombardment/SM
+bombast/M
+bombastic
+bombastically
+bomber/M
+bombproof
+bombshell/SM
+bombsite/S
+bon/S
+bona
+bonanza/MS
+bonbon/MS
+bonce/S
+bond/SGMD
+bondage/M
+bondholder/MS
+bonding/M
+bondman/M
+bondmen
+bondsman/M
+bondsmen
+bondwoman/M
+bondwomen
+bone/DRSMZG
+bonehead/SMD
+boneless
+boner/M
+boneshaker/S
+boneyard
+bonfire/MS
+bong/SGMD
+bongo/MS
+bonhomie/M
+boniness/M
+bonito/MS
+bonk/SZGD
+bonnet/MS
+bonny/TR
+bono
+bonobo/MS
+bonsai/M
+bonus/MS
+bony/PTR
+boo/SMDHG
+boob/SGMD
+booboo/MS
+booby/SM
+boodle/MS
+booger/S
+boogeyman/M
+boogeymen
+boogie/MDS
+boogieing
+boogieman/M
+boohoo/GMDS
+book/SBJGMD
+bookbinder/SM
+bookbindery/SM
+bookbinding/M
+bookcase/MS
+bookend/MS
+bookie/MS
+booking/M
+bookish
+bookkeeper/MS
+bookkeeping/M
+booklet/MS
+bookmaker/SM
+bookmaking/M
+bookmark/SMDG
+bookmobile/SM
+bookplate/MS
+bookseller/MS
+bookselling
+bookshelf/M
+bookshelves
+bookshop/SM
+bookstall/S
+bookstore/MS
+bookworm/SM
+boolean
+boom/SZGMDR
+boombox/MS
+boomerang/MDGS
+boon/SM
+boondocks/M
+boondoggle/MZGDRS
+boondoggler/M
+boonies/M
+boor/SM
+boorish/PY
+boorishness/MS
+boost/ZGMDRS
+booster/M
+boot's
+boot/ASGD
+bootblack/SM
+bootee/MS
+booth/M
+booths
+bootie/M
+bootlace/S
+bootleg/MS
+bootlegged
+bootlegger/MS
+bootlegging/M
+bootless
+bootstrap/MS
+bootstrapped
+bootstrapping
+booty/SM
+booze/MZGDRS
+boozer/M
+boozy/TR
+bop/SM
+bopped
+bopping
+borax/M
+bordello/MS
+border/GMDS
+borderland/MS
+borderline/MS
+bore/DRSMZG
+boredom/M
+borehole/S
+borer/M
+boring/Y
+born/IAU
+borne
+boron/M
+borough/M
+boroughs
+borrow/SDRZGJ
+borrower/M
+borrowing/M
+borsch/M
+borscht/M
+borstal/S
+borzoi/SM
+bosh/M
+bosom's
+bosom/US
+bosomy
+boson
+boss/DSGM
+bossily
+bossiness/M
+bossism/M
+bossy/RTP
+bosun/SM
+bot/S
+botanic
+botanical/Y
+botanist/SM
+botany/M
+botch/DRSZGM
+botcher/M
+both
+bother/SMDG
+botheration
+bothered/U
+bothersome
+botnet/SM
+bottle/DRSMZG
+bottleneck/MS
+bottler/M
+bottom/SMDG
+bottomless
+botulinum
+botulism/M
+boudoir/SM
+bouffant/SM
+bougainvillea/MS
+bough/M
+boughs
+bought
+bougie/S
+bouillabaisse/SM
+bouillon/MS
+boulder/SGMR
+boulderer/M
+boules
+boulevard/SM
+bounce/DRSMZG
+bouncer/M
+bouncily
+bounciness/M
+bouncy/RTP
+bound/ASMGD
+boundary/SM
+bounden
+bounder/SM
+boundless/PY
+boundlessness/M
+bounteous/YP
+bounteousness/M
+bountiful/YP
+bountifulness/M
+bounty/SM
+bouquet/SM
+bourbon/SM
+bourgeois/M
+bourgeoisie/M
+boustrophedon
+bout/MS
+boutique/SM
+boutonniere/MS
+boutonnire/MS
+bouzouki/MS
+bovine/SM
+bovver
+bow/ZGSMDR
+bowdlerization/MS
+bowdlerize/DSG
+bowed/U
+bowel/SM
+bower/M
+bowl/MDRZGS
+bowleg/SM
+bowlegged
+bowler/M
+bowlful/SM
+bowline/SM
+bowling/M
+bowman/M
+bowmen
+bowsprit/SM
+bowstring/SM
+bowwow/SM
+box/ZGMDNRS
+boxcar/SM
+boxer/M
+boxing/M
+boxlike
+boxroom/S
+boxwood/M
+boxy/RT
+boy/SM
+boycott/SGMD
+boyfriend/MS
+boyhood/SM
+boyish/YP
+boyishness/M
+boysenberry/SM
+bozo/MS
+bpm
+bps
+bra/SM
+brace/MZGDRS
+bracelet/MS
+bracer/M
+bracero/MS
+bracken/M
+bracket/GMDS
+brackish/P
+brackishness/M
+bract/MS
+brad/SM
+bradawl/S
+bradycardia
+brae/SM
+brag/SM
+braggadocio/SM
+braggart/SM
+bragged
+bragger/MS
+bragging
+braid/GMDS
+braiding/M
+braille/M
+brain/GMDS
+brainchild/M
+brainchildren/M
+braininess/M
+brainless/Y
+brainpower
+brainstorm/SMDG
+brainstorming/M
+brainteaser/SM
+brainwash/DSG
+brainwashing/M
+brainwave/S
+brainy/PTR
+braise/GDS
+brake/MGDS
+brakeman/M
+brakemen
+bramble/MS
+brambly
+bran/M
+branch/GMDS
+branchlike
+brand/ZGMDRS
+branded/UA
+brander/M
+brandish/DSG
+brandy/GDSM
+brash/PTRY
+brashness/M
+brass/MS
+brasserie/MS
+brassiere/MS
+brassily
+brassiness/M
+brassy/PTR
+brat/SM
+bratty/RT
+bratwurst/SM
+bravado/M
+brave/GPMYDTRS
+braveness/M
+bravery/M
+bravo/SM
+bravura/SM
+brawl/SDRZGM
+brawler/M
+brawn/M
+brawniness/M
+brawny/RTP
+bray/DGSM
+braze/DRSZG
+brazen/SDYGP
+brazenness/M
+brazer/M
+brazier/SM
+breach/GMDS
+bread/GMDHS
+breadbasket/SM
+breadboard/SM
+breadbox/MS
+breadcrumb/MS
+breadfruit/SM
+breadline/MS
+breadth/M
+breadths
+breadwinner/SM
+break/BMZGRS
+breakable/MS
+breakage/MS
+breakaway/MS
+breakdown/MS
+breaker/M
+breakeven/M
+breakfast/MDGS
+breakfront/MS
+breakneck
+breakout/MS
+breakpoints
+breakthrough/M
+breakthroughs
+breakup/SM
+breakwater/SM
+bream/MS
+breast/SMDG
+breastbone/MS
+breastfed
+breastfeed/GS
+breastplate/SM
+breaststroke/SM
+breastwork/MS
+breath/MDRSZGB
+breathalyze/ZGDRS
+breathe
+breather/M
+breathing/M
+breathless/PY
+breathlessness/M
+breaths
+breathtaking/Y
+breathy/RT
+bred/I
+breech/MS
+breed/SRZGM
+breeder/M
+breeding/IM
+breeze/DSMG
+breezeway/SM
+breezily
+breeziness/M
+breezy/RTP
+brethren
+breve/SM
+brevet/SM
+brevetted
+brevetting
+breviary/SM
+brevity/M
+brew/MDRZGS
+brewer/M
+brewery/SM
+brewpub/SM
+briar/SM
+bribe/DRSMZG
+briber/M
+bribery/M
+brick/SMDG
+brickbat/SM
+brickie/S
+bricklayer/MS
+bricklaying/M
+brickwork/M
+brickyard/S
+bridal/SM
+bride/SM
+bridegroom/SM
+bridesmaid/MS
+bridesman/M
+bridesmen
+bridge/DSMG
+bridgeable/U
+bridgehead/SM
+bridgework/M
+bridle/DSMG
+bridled/U
+bridleway/S
+brie/MZR
+brief's
+brief/CSDTGJ
+briefcase/SM
+briefer
+briefing/CM
+briefly
+briefness/M
+brier/M
+brig/MS
+brigade/SM
+brigadier/MS
+brigand/SM
+brigandage/M
+brigantine/MS
+bright/SPNRYXT
+brighten/DRZG
+brightener/M
+brightness/M
+brights/M
+brill
+brilliance/M
+brilliancy/M
+brilliant/MYS
+brilliantine/M
+brim/MS
+brimful
+brimless
+brimmed
+brimming
+brimstone/M
+brindle/DM
+brine/M
+bring/SRZG
+bringer/M
+brininess/M
+brink/SM
+brinkmanship/M
+briny/RTP
+brioche/SM
+briquet/SM
+briquette/MS
+brisk/SDRYTGP
+brisket/SM
+briskness/M
+bristle/DSMG
+bristly/TR
+britches/M
+brittle/PRMT
+brittleness/M
+bro/SMH
+broach/MDSG
+broad/SMNRYXTP
+broadband/M
+broadcast/AMDGS
+broadcaster/MS
+broadcasting/M
+broadcloth/M
+broaden/DG
+broadloom/M
+broadminded
+broadness/M
+broadsheet/SM
+broadside/MGDS
+broadsword/SM
+brocade/DSMG
+broccoli/M
+brochette/SM
+brochure/MS
+brogan/SM
+brogue/SM
+broil/SMDRZG
+broiler/M
+broke
+broken/YP
+brokenhearted/Y
+brokenness/M
+broker/SMDG
+brokerage/MS
+brolly/S
+bromide/SM
+bromidic
+bromine/M
+bronc/SM
+bronchi
+bronchial
+bronchitic
+bronchitis/M
+bronchus/M
+bronco/SM
+broncobuster/SM
+brontosaur/MS
+brontosaurus/MS
+bronze/DSMG
+brooch/MS
+brood/SMDRZG
+brooder/M
+broodily
+brooding/MY
+broodmare/MS
+broody/RMPT
+brook/SMDG
+brooklet/SM
+broom/SM
+broomstick/MS
+broth/MRZ
+brothel/MS
+brother/MY
+brotherhood/MS
+brotherliness/M
+broths
+brougham/SM
+brought
+brouhaha/SM
+brow/MS
+browbeat/SNG
+brown/SMDRPTG
+brownfield
+brownie/MS
+brownish
+brownness/M
+brownout/SM
+brownstone/MS
+browse/DRSMZG
+browser/M
+brr
+bruin/SM
+bruise/DRSMZG
+bruiser/M
+bruising/M
+bruit/SDG
+brunch/MDSG
+brunet/SM
+brunette/MS
+brunt/M
+brush/MDSG
+brushoff/SM
+brushstroke/S
+brushwood/M
+brushwork/M
+brusque/RPYT
+brusqueness/M
+brutal/Y
+brutality/SM
+brutalization/M
+brutalize/GDS
+brute/SM
+brutish/PY
+brutishness/M
+bu
+bub/SM
+bubble/DSMG
+bubblegum/M
+bubbly/RMT
+bubo/M
+buboes
+bubonic
+buccaneer/SGMD
+buck/MDGS
+buckaroo/SM
+buckboard/MS
+bucket/SGMD
+bucketful/MS
+buckeye/MS
+buckle's
+buckle/UDSG
+buckler/MS
+buckram/M
+bucksaw/MS
+buckshot/M
+buckskin/MS
+buckteeth
+bucktooth/MD
+buckwheat/M
+buckyball/SM
+bucolic/MS
+bucolically
+bud/SM
+budded
+budding/S
+buddy/SM
+budge/DSG
+budgerigar/MS
+budget/SGMD
+budgetary
+budgie/SM
+buff/AMDGS
+buffalo/MDG
+buffaloes
+buffer/SMDG
+buffet/SMDGJ
+buffoon/SM
+buffoonery/M
+buffoonish
+bug's
+bug/CS
+bugaboo/SM
+bugbear/SM
+bugged/C
+bugger/SMDG
+buggery
+bugging/C
+buggy/RSMT
+bugle/DRSMZG
+bugler/M
+build/SMRZGJ
+builder/M
+building/M
+buildup/SM
+built/AI
+builtin
+bulb/MS
+bulbous
+bulge/DSMG
+bulgy/RT
+bulimarexia/M
+bulimia/M
+bulimic/SM
+bulk/MDGS
+bulkhead/MS
+bulkiness/M
+bulky/RTP
+bull/MDGS
+bulldog/SM
+bulldogged
+bulldogging
+bulldoze/ZGDRS
+bulldozer/M
+bullet/SMD
+bulletin/MDGS
+bulletproof/SDG
+bullfight/SMRZG
+bullfighter/M
+bullfighting/M
+bullfinch/MS
+bullfrog/MS
+bullhead/MDS
+bullheaded/PY
+bullheadedness/M
+bullhorn/MS
+bullion/M
+bullish/YP
+bullishness/M
+bullock/SM
+bullpen/SM
+bullring/MS
+bullseye/S
+bullshit/MS!
+bullshitted/!
+bullshitter/SM!
+bullshitting/!
+bullwhip/S
+bully/DSMG
+bulrush/MS
+bulwark/MS
+bum/SM
+bumbag/S
+bumble/DRSZG
+bumblebee/SM
+bumbler/M
+bumf
+bummed
+bummer/SM
+bummest
+bumming
+bump/MDRZGS
+bumper/M
+bumph
+bumpiness/M
+bumpkin/MS
+bumptious/PY
+bumptiousness/M
+bumpy/PRT
+bun/SM
+bunch/MDSG
+bunchy/RT
+bunco/SMDG
+buncombe/M
+bundle/DSMG
+bung/MDGS
+bungalow/MS
+bungee/SM
+bunghole/MS
+bungle/DRSMZG
+bungler/M
+bunion/SM
+bunk's
+bunk/CDGS
+bunker/SM
+bunkhouse/SM
+bunko/SMDG
+bunkum/M
+bunny/SM
+bunt/MDGSJ
+bunting/M
+buoy/MDGS
+buoyancy/M
+buoyant/Y
+bupkis
+bur/SMY
+burble/DSMG
+burbs/M
+burden's
+burden/USGD
+burdensome
+burdock/M
+bureau/SM
+bureaucracy/SM
+bureaucrat/MS
+bureaucratic
+bureaucratically
+bureaucratization/M
+bureaucratize/GDS
+burg/MRZS
+burgeon/DSG
+burger/M
+burgh/MRZ
+burgher/M
+burghs
+burglar/MS
+burglarize/GDS
+burglarproof
+burglary/SM
+burgle/DSG
+burgomaster/SM
+burgundy/SM
+burial/ASM
+burka/SM
+burl/MDS
+burlap/M
+burlesque/MGDS
+burliness/M
+burly/RPT
+burn/MDRZGSB
+burnable/SM
+burner/M
+burnish/ZGMDRS
+burnisher/M
+burnoose/MS
+burnous/MS
+burnout/MS
+burnt
+burp/MDGS
+burr/MDGS
+burrito/MS
+burro/SM
+burrow/SMDRZG
+burrower/M
+bursa/M
+bursae
+bursar/SM
+bursary/SM
+bursitis/M
+burst/SMG
+bury/ADSG
+bus/AMS
+busboy/SM
+busby/SM
+bused
+busgirl/MS
+bush/MDSGJ
+bushel/SGMD
+bushiness/M
+bushing/M
+bushman/M
+bushmaster/SM
+bushmen
+bushwhack/DRSZG
+bushwhacker/M
+bushy/RPT
+busily
+business/MS
+businesslike
+businessman/M
+businessmen
+businessperson/SM
+businesswoman/M
+businesswomen
+busing/M
+busk/DRZGS
+buskin/SM
+busload/S
+buss/MDSG
+bust/MDRZGS
+buster/M
+bustle/DSMG
+busty/RZT
+busy/DRSTGP
+busybody/SM
+busyness/M
+busywork/M
+but/ACS
+butane/M
+butch/MRSZ
+butcher/MDG
+butchery/SM
+butler/SM
+butt/MDRZGS
+butte/SM
+butted/A
+butter/MDG
+butterball/MS
+buttercream
+buttercup/SM
+butterfat/M
+butterfingered
+butterfingers/M
+butterfly/GDSM
+buttermilk/M
+butternut/SM
+butterscotch/M
+buttery/TRSM
+butting/A
+buttock/SM
+button's
+button/USDG
+buttonhole/DSMG
+buttonwood/MS
+buttress/MDSG
+butty/S
+buxom
+buy/ZGSMR
+buyback/SM
+buyer/M
+buyout/SM
+buzz/MDRSZG
+buzzard/MS
+buzzer/M
+buzzkill/SM
+buzzword/SM
+bx
+bxs
+by/M
+bye/SM
+bygone/SM
+bylaw/SM
+byline/SM
+bypass/GMDS
+bypath/M
+bypaths
+byplay/M
+byproduct/MS
+byre/S
+byroad/SM
+bystander/MS
+byte/MS
+byway/SM
+byword/SM
+byzantine
+c/IES
+cDNA
+ca
+cab/SMRZ
+cabal/MS
+cabala/M
+caballero/MS
+cabana/SM
+cabaret/SM
+cabbage/MS
+cabbed
+cabbie/M
+cabbing
+cabby/SM
+cabdriver/SM
+cabin/MS
+cabinet/SM
+cabinetmaker/MS
+cabinetmaking/M
+cabinetry/M
+cabinetwork/M
+cable/MGDS
+cablecast/GMS
+cablegram/MS
+cabochon/SM
+caboodle/M
+caboose/SM
+cabriolet/SM
+cabstand/SM
+cacao/MS
+cache/MGDS
+cachepot/SM
+cachet/MS
+cackle/MZGDRS
+cackler/M
+cacophonous
+cacophony/SM
+cacti
+cactus/M
+cad/SM
+cadaver/SM
+cadaverous
+caddie/MDS
+caddish/YP
+caddishness/M
+caddying
+cadence/DSM
+cadenza/SM
+cadet/MS
+cadge/ZGDRS
+cadger/M
+cadmium/M
+cadre/MS
+caducei
+caduceus/M
+caesarean/MS
+caesura/SM
+cafe/SM
+cafeteria/MS
+cafetiere/S
+caff/CS
+caffeinated
+caffeine/M
+caftan/MS
+caf/SM
+cage/DSMG
+cagey
+cagier
+cagiest
+cagily
+caginess/M
+cagoule/S
+cahoot/MS
+caiman/MS
+cairn/MS
+caisson/SM
+caitiff/SM
+cajole/ZGLDRS
+cajolement/M
+cajoler/M
+cajolery/M
+cake/DSMG
+cakewalk/SM
+cal
+calabash/MS
+calaboose/SM
+calamari/SM
+calamine/M
+calamitous/Y
+calamity/SM
+calcareous
+calciferous
+calcification/M
+calcify/GNDS
+calcimine/DSMG
+calcine/DSG
+calcite/M
+calcium/M
+calculable/I
+calculate/AGNVDSX
+calculated/Y
+calculating/Y
+calculation/AM
+calculator/SM
+calculi
+calculus/M
+caldera/SM
+caldron/SM
+calendar/MDGS
+calf/M
+calfskin/M
+caliber/SM
+calibrate/GNDSX
+calibration/M
+calibrator/SM
+calico/MS
+calicoes
+californium/M
+caliper/SGMD
+caliph/M
+caliphate/MS
+caliphs
+calisthenic/S
+calisthenics/M
+calk/SGMD
+call/ASGMD
+calla/MS
+callable
+callback/MS
+called/U
+caller/MS
+calligrapher/SM
+calligraphic
+calligraphist/MS
+calligraphy/M
+calling/SM
+calliope/MS
+callosity/SM
+callous/PGDSY
+callousness/M
+callow/RPT
+callowness/M
+callus/MDSG
+calm/PSTGMDRY
+calmness/M
+caloric
+calorie/MS
+calorific
+calumet/MS
+calumniate/GNDS
+calumniation/M
+calumniator/MS
+calumnious
+calumny/SM
+calve/GDS
+calypso/MS
+calyx/MS
+cam/SM
+camaraderie/M
+camber/MDSG
+cambial
+cambium/SM
+cambric/M
+camcorder/SM
+came
+camel/MS
+camelhair/M
+camellia/MS
+cameo/MS
+camera/MS
+cameraman/M
+cameramen
+camerapeople
+cameraperson
+camerawoman/M
+camerawomen
+camerawork
+camiknickers
+camisole/SM
+camomile/SM
+camouflage/MZGDRS
+camouflager/M
+camp's
+camp/CSGD
+campaign/SMDRZG
+campaigner/M
+campanile/SM
+campanologist/MS
+campanology/M
+camper/MS
+campfire/SM
+campground/SM
+camphor/M
+camping/M
+campsite/SM
+campus/MS
+campy/TR
+camshaft/SM
+can't
+can/SMDRZG
+canal/MS
+canalization/M
+canalize/GDS
+canape/MS
+canap/MS
+canard/MS
+canary/SM
+canasta/M
+cancan/MS
+cancel/DRSZG
+canceler/M
+cancellation/SM
+cancelled/U
+canceller/M
+cancelling
+cancelous
+cancer/MS
+cancerous
+candelabra/SM
+candelabrum/M
+candid/YP
+candida
+candidacy/SM
+candidate/MS
+candidature/SM
+candidness/M
+candle/MZGDRS
+candlelight/M
+candlelit
+candlepower/M
+candler/M
+candlestick/MS
+candlewick/SM
+candor/M
+candy/GDSM
+candyfloss
+cane/SM
+canebrake/MS
+caner/M
+canine/MS
+canister/SM
+canker/GMDS
+cankerous
+cannabis/MS
+canned
+cannelloni/M
+cannery/SM
+cannibal/SM
+cannibalism/M
+cannibalistic
+cannibalization/M
+cannibalize/GDS
+cannily/U
+canniness/M
+canning
+cannon/GMDS
+cannonade/MGDS
+cannonball/SM
+cannot
+canny/UTR
+canoe/MDS
+canoeing
+canoeist/SM
+canola/M
+canon/MS
+canonical/Y
+canonicalization/MS
+canonicalize/GDS
+canonization/SM
+canonize/DSG
+canoodle/DSG
+canopy/GDSM
+canst
+cant's
+cant/CZRDGS
+cantabile
+cantaloupe/SM
+cantankerous/PY
+cantankerousness/M
+cantata/MS
+canteen/MS
+canter/CM
+cantered
+cantering
+canticle/MS
+cantilever/MDGS
+cantina/S
+canto/MS
+canton/MLS
+cantonal
+cantonment/MS
+cantor/MS
+canvas/MGDS
+canvasback/SM
+canvass/MDRSZG
+canvasser/M
+canyon/MGS
+cap/SMDRBZ
+capabilities
+capability/IM
+capable/I
+capably/I
+capacious/PY
+capaciousness/M
+capacitance/M
+capacities
+capacitor/SM
+capacity/IM
+caparison/MDGS
+cape/SM
+caper/GMD
+capeskin/M
+capillarity/M
+capillary/SM
+capita
+capital/MSY
+capitalism/M
+capitalist/SM
+capitalistic
+capitalistically
+capitalization/M
+capitalize/ADSG
+capitation/CSM
+capitol/SM
+capitulate/ADSXGN
+capitulation/AM
+caplet/MS
+capo/SM
+capon/MS
+capped/UA
+capping/UA
+cappuccino/SM
+caprice/SM
+capricious/PY
+capriciousness/M
+capsicum/SM
+capsize/DSG
+capstan/SM
+capstone/MS
+capsular
+capsule/DSMG
+capsulize/DSG
+capt
+captain/SMDG
+captaincy/SM
+captcha
+caption/SMDG
+captious/YP
+captiousness/M
+captivate/DSGN
+captivation/M
+captivator/SM
+captive/SM
+captivity/SM
+captor/MS
+capture/ADSMG
+car/SMDRZG
+carabiner
+carafe/MS
+caramel/SM
+caramelize/DSG
+carapace/SM
+carat/MS
+caravan/SM
+caravansarai/S
+caravansary/SM
+caravanserai/M
+caravel/SM
+caraway/SM
+carbide/SM
+carbine/SM
+carbohydrate/SM
+carbolic
+carbon/MS
+carbonaceous
+carbonate/MGNDS
+carbonation/M
+carboniferous
+carbonize/GDS
+carborundum/M
+carboxylic
+carboy/MS
+carbs
+carbuncle/SM
+carbuncular
+carburetor/SM
+carcass/MS
+carcinogen/SM
+carcinogenic/MS
+carcinogenicity/M
+carcinoma/MS
+card/ESGMD
+cardamom/SM
+cardamon/S
+cardboard/M
+carder/MS
+cardholder/S
+cardiac
+cardie/S
+cardigan/SM
+cardinal/SMY
+cardinality/S
+cardio
+cardiogram/SM
+cardiograph/M
+cardiographs
+cardiologist/MS
+cardiology/M
+cardiomegaly
+cardiomyopathy
+cardiopulmonary
+cardiovascular
+cardsharp/MRZS
+cardsharper/M
+care/SM
+careen/DGS
+career/MDGS
+careerism
+careerist/SM
+carefree
+careful/YP
+carefuller
+carefullest
+carefulness/M
+caregiver/SM
+careless/PY
+carelessness/M
+carer/M
+caress/MDSG
+caret/MS
+caretaker/MS
+careworn
+carfare/M
+cargo/M
+cargoes
+carhop/MS
+caribou/SM
+caricature/MGDS
+caricaturist/SM
+caries/M
+carillon/SM
+caring/M
+carious
+carjack/JSDRZG
+carjacker/M
+carjacking/M
+carload/SM
+carmaker/S
+carmine/SM
+carnage/M
+carnal/Y
+carnality/M
+carnation/IMS
+carnelian/MS
+carney/MS
+carnie/M
+carnitas
+carnival/MS
+carnivora
+carnivore/SM
+carnivorous/PY
+carnivorousness/M
+carny/SM
+carob/MS
+carol/ZGMDRS
+caroler/M
+carom/GMDS
+carotene/M
+carotid/SM
+carousal/SM
+carouse/DRSMZG
+carousel/SM
+carouser/M
+carp/SZGMDR
+carpal/MS
+carpel/MS
+carpenter/MDGS
+carpentry/M
+carper/M
+carpet/MDGS
+carpetbag/MS
+carpetbagged
+carpetbagger/MS
+carpetbagging
+carpeting/M
+carpi
+carpool/SMDG
+carport/SM
+carpus/M
+carrel/MS
+carriage/SM
+carriageway/S
+carrier/M
+carrion/M
+carrot/MS
+carroty
+carry/ZGDRSM
+carryall/SM
+carrycot/S
+carryout
+carryover/MS
+carsick/P
+carsickness/M
+cart/SZGMDR
+cartage/M
+carte/S
+cartel/MS
+carter/M
+carthorse/SM
+cartilage/SM
+cartilaginous
+cartload/SM
+cartographer/SM
+cartographic
+cartography/M
+carton/MS
+cartoon/SMDG
+cartoonist/MS
+cartridge/MS
+cartwheel/GMDS
+carve/JZGDRS
+carver/M
+carvery/S
+carving/M
+caryatid/MS
+casaba/MS
+cascade/DSMG
+cascara/SM
+case/LDSJMG
+casebook/S
+cased/U
+caseharden/DGS
+casein/M
+caseload/MS
+casement/MS
+casework/ZMR
+caseworker/M
+cash/GMDS
+cashback/M
+cashbook/MS
+cashew/MS
+cashier/GSMD
+cashless
+cashmere/M
+casing/M
+casino/MS
+cask/SM
+casket/MS
+cassava/SM
+casserole/DSMG
+cassette/MS
+cassia/MS
+cassock/SM
+cassowary/SM
+cast/ASGM
+castanet/MS
+castaway/MS
+caste/JMZRS
+castellated
+caster/M
+castigate/DSGN
+castigation/M
+castigator/SM
+casting/AM
+castle/MGDS
+castoff/SM
+castor/MS
+castrate/GNXDS
+castration/M
+casual/PMYS
+casualness/M
+casualty/SM
+casuist/SM
+casuistic
+casuistry/M
+cat/SM
+cataclysm/MS
+cataclysmal
+cataclysmic
+catacomb/SM
+catafalque/MS
+catalepsy/M
+cataleptic/MS
+catalog/ZGSMDR
+cataloger/M
+catalogue/DSMG
+catalogued/U
+catalpa/SM
+catalyses
+catalysis/M
+catalyst/MS
+catalytic/M
+catalyze/GDS
+catamaran/SM
+catapult/GMDS
+cataract/MS
+catarrh/M
+catastrophe/MS
+catastrophic
+catastrophically
+catatonia/M
+catatonic/SM
+catbird/SM
+catboat/SM
+catcall/GSMD
+catch/ZGJLMRS
+catchall/MS
+catcher/M
+catchment/MS
+catchpenny
+catchphrase/SM
+catchword/MS
+catchy/RT
+catechism/SM
+catechist/SM
+catechize/DSG
+categorical/Y
+categorization/MS
+categorize/GDS
+category/SM
+cater/ZGJDRS
+catercorner
+caterer/M
+caterpillar/MS
+caterwaul/SMDG
+catfish/MS
+catgut/M
+catharses
+catharsis/M
+cathartic/SM
+cathedral/SM
+catheter/SM
+catheterize/DSG
+cathode/SM
+cathodic
+catholic
+catholicity/M
+cation/MS
+catkin/MS
+catlike
+catnap/MS
+catnapped
+catnapping
+catnip/M
+catsuit/S
+catsup/MS
+cattail/SM
+catted
+cattery/S
+cattily
+cattiness/M
+catting
+cattle/M
+cattleman/M
+cattlemen
+catty/TPR
+catwalk/SM
+caucus/MDSG
+caudal/Y
+caught/U
+cauldron/MS
+cauliflower/SM
+caulk/ZGMDRS
+caulker/M
+causal/Y
+causality/SM
+causation/M
+causative
+cause/MZGDRS
+causeless
+causer/M
+causerie/SM
+causeway/SM
+caustic/SM
+caustically
+causticity/M
+cauterization/M
+cauterize/GDS
+caution/SMDG
+cautionary
+cautious/IY
+cautiousness/M
+cavalcade/MS
+cavalier/SMY
+cavalry/SM
+cavalryman/M
+cavalrymen
+cave/DRSMZG
+caveat/MS
+caveman/M
+cavemen
+cavern/MS
+cavernous/Y
+caviar/M
+cavil/ZGJMDRS
+caviler/M
+caving/M
+cavitation
+cavity/FSM
+cavort/DGS
+caw/SMDG
+cay/CSM
+cayenne/M
+cayuse/MS
+cc
+cease/CMGDS
+ceasefire/MS
+ceaseless/YP
+ceaselessness/M
+ceca
+cecal
+cecum/M
+cedar/MS
+cede/FAGSD
+ceder/MS
+cedilla/SM
+ceilidh
+ceilidhs
+ceiling/MS
+celandine/M
+celeb/S
+celebrant/SM
+celebrate/DSGNX
+celebration/M
+celebrator/SM
+celebratory
+celebrity/SM
+celeriac
+celerity/M
+celery/M
+celesta/MS
+celestial/Y
+celibacy/M
+celibate/MS
+cell/SMD
+cellar/MS
+cellist/SM
+cellmate/SM
+cello/MS
+cellophane/M
+cellphone/MS
+cellular/SM
+cellulite/M
+cellulitis
+celluloid/M
+cellulose/M
+cement/MDRZGS
+cementer/M
+cementum/M
+cemetery/SM
+cenobite/MS
+cenobitic
+cenotaph/M
+cenotaphs
+censer/MS
+censor/MDGS
+censored/U
+censorial
+censorious/PY
+censoriousness/M
+censorship/M
+censure/BDRSMZG
+censurer/M
+census/MDSG
+cent/SZMR
+centaur/SM
+centavo/SM
+centenarian/MS
+centenary/SM
+centennial/MYS
+center/MDG
+centerboard/SM
+centerfold/MS
+centerpiece/MS
+centigrade
+centigram/SM
+centiliter/MS
+centime/SM
+centimeter/MS
+centipede/SM
+central/SMY
+centralism
+centralist
+centrality/M
+centralization/CM
+centralize/CGDS
+centralizer/MS
+centrifugal/Y
+centrifuge/DSMG
+centripetal/Y
+centrism/M
+centrist/MS
+centurion/SM
+century/SM
+cephalic
+ceramic/SM
+ceramicist/SM
+ceramics/M
+ceramist/MS
+cereal/MS
+cerebellar
+cerebellum/SM
+cerebra
+cerebral
+cerebrate/GNDS
+cerebration/M
+cerebrovascular
+cerebrum/MS
+cerement/MS
+ceremonial/SMY
+ceremonious/UY
+ceremoniousness/M
+ceremony/SM
+cerevisiae/MS
+cerise/M
+cerium/M
+cermet/M
+cert/S
+certain/UY
+certainty/USM
+certifiable
+certifiably
+certificate/MGDS
+certification/AMS
+certify/CDSNXG
+certitude/IM
+certitudes
+cerulean/M
+cervical
+cervices
+cervix/M
+cesarean/MS
+cesium/M
+cessation/MS
+cession/KAFSM
+cesspit/S
+cesspool/MS
+cetacean/MS
+ceteris
+cf
+cg
+ch/IFVT
+chad/S
+chafe/GDS
+chaff/GMDS
+chaffinch/MS
+chagrin/GSMD
+chain's
+chain/UGDS
+chainsaw/MDGS
+chair/GMDS
+chairlift/MS
+chairman/M
+chairmanship/SM
+chairmen
+chairperson/SM
+chairwoman/M
+chairwomen
+chaise/MS
+chalcedony/M
+chalet/MS
+chalice/SM
+chalk/GMDS
+chalkboard/SM
+chalkiness/M
+chalky/PRT
+challenge/DRSMZG
+challenged/U
+challenger/M
+challis/M
+chamber/SMD
+chamberlain/MS
+chambermaid/MS
+chambray/M
+chameleon/SM
+chamois/M
+chamomile/MS
+champ/ZGMDS
+champagne/MS
+champertous
+champerty
+champion/GMDS
+championship/MS
+chance/MGDS
+chancel/SM
+chancellery/SM
+chancellor/MS
+chancellorship/M
+chancery/SM
+chanciness/M
+chancre/SM
+chancy/PRT
+chandelier/SM
+chandler/MS
+change/MZGDRS
+changeability/M
+changeable/P
+changeableness/M
+changeably
+changed/U
+changeless/Y
+changeling/SM
+changeover/SM
+changer/M
+changing/U
+channel/GSMD
+channelization/M
+channelize/DSG
+chanson/SM
+chant/ZGMDRS
+chanter/M
+chanteuse/MS
+chantey/SM
+chanticleer/MS
+chaos/M
+chaotic
+chaotically
+chap/SM
+chaparral/SM
+chapati/S
+chapatti/S
+chapbook/MS
+chapeau/SM
+chapel/MS
+chaperon/MDGS
+chaperonage/M
+chaperone/SM
+chaperoned/U
+chaplain/MS
+chaplaincy/SM
+chaplet/SM
+chapped
+chapping
+chappy/S
+chapter/SM
+char/SM
+charabanc/MS
+character/MS
+characterful
+characteristic/SM
+characteristically/U
+characterization/MS
+characterize/DSG
+characterless
+charade/SM
+charbroil/GDS
+charcoal/MS
+charcuterie
+chard/M
+chardonnay/SM
+charge/AESDGM
+chargeable/A
+charged/U
+charger/SM
+charily
+chariness/M
+chariot/SM
+charioteer/MS
+charisma/M
+charismatic/MS
+charitable/P
+charitableness/M
+charitably/U
+charity/SM
+charlady/S
+charlatan/SM
+charlatanism/M
+charlatanry/M
+charlie/S
+charm/ZGMDRS
+charmer/M
+charming/Y
+charmless
+charred
+charring
+chart/GMDS
+charted/U
+charter's
+charter/ASGD
+charterer/MS
+chartreuse/M
+charwoman/M
+charwomen
+chary/TRP
+chase/MZGDRS
+chaser/M
+chasm/MS
+chassis/M
+chaste/PYTR
+chasten/DGS
+chasteness/M
+chastise/DRSZGL
+chastisement/SM
+chastiser/M
+chastity/M
+chasuble/SM
+chat/SM
+chateau/SM
+chateaux
+chatelaine/SM
+chatline/S
+chatroom/M
+chatted
+chattel/MS
+chatter/MDRZGS
+chatterbox/MS
+chatterer/M
+chattily
+chattiness/M
+chatting
+chatty/TPR
+chauffeur/GMDS
+chauvinism/M
+chauvinist/SM
+chauvinistic
+chauvinistically
+cheap/PXTNRY
+cheapen/DG
+cheapness/M
+cheapo
+cheapskate/MS
+cheat/ZGMDRS
+cheater/M
+check's/A
+check/UAGDS
+checkbook/SM
+checkbox
+checker/MDGS
+checkerboard/SM
+checkers/M
+checklist/MS
+checkmate/MGDS
+checkoff/SM
+checkout/SM
+checkpoint/SM
+checkroom/MS
+checksum
+checkup/MS
+cheddar/M
+cheek/GMDS
+cheekbone/SM
+cheekily
+cheekiness/M
+cheeky/TPR
+cheep/GMDS
+cheer/ZGMDRS
+cheerer/M
+cheerful/YP
+cheerfuller
+cheerfullest
+cheerfulness/M
+cheerily
+cheeriness/M
+cheerio/MS
+cheerleader/SM
+cheerless/PY
+cheerlessness/M
+cheery/TPR
+cheese/MGDS
+cheeseboard/S
+cheeseburger/SM
+cheesecake/SM
+cheesecloth/M
+cheeseparing/M
+cheesiness/M
+cheesy/TPR
+cheetah/M
+cheetahs
+chef/SM
+chem
+chemical/SMY
+chemise/MS
+chemist/MS
+chemistry/SM
+chemo/M
+chemotherapeutic
+chemotherapy/M
+chemurgy/M
+chenille/M
+cherish/DSG
+cheroot/MS
+cherry/SM
+chert/M
+cherub/MS
+cherubic
+cherubim
+chervil/M
+chess/M
+chessboard/MS
+chessman/M
+chessmen
+chest/MDS
+chesterfield/SM
+chestful/SM
+chestnut/SM
+chesty/TR
+chevalier/SM
+cheviot/M
+chevron/MS
+chew/SBZGMDR
+chewer/M
+chewiness/M
+chewy/PTR
+chg
+chge
+chi/SM
+chiaroscuro/M
+chic/PTMR
+chicane/MS
+chicanery/SM
+chichi/MS
+chick/XMNS
+chickadee/SM
+chicken/MDG
+chickenfeed/M
+chickenhearted
+chickenpox/M
+chickenshit/MS!
+chickpea/SM
+chickweed/M
+chicle/M
+chicness/M
+chicory/SM
+chide/GDS
+chiding/Y
+chief/TMRYS
+chiefdom/M
+chieftain/MS
+chieftainship/SM
+chiffon/M
+chiffonier/MS
+chigger/MS
+chignon/MS
+chihuahua/SM
+chilblain/SM
+child/M
+childbearing/M
+childbirth/M
+childbirths
+childcare/M
+childhood/SM
+childish/YP
+childishness/M
+childless/P
+childlessness/M
+childlike
+childminder/S
+childminding
+childproof/GSD
+children/M
+chili/M
+chilies
+chill/JPZTGMDRS
+chiller/M
+chilliness/M
+chilling/Y
+chillness/M
+chilly/TPR
+chimaera/MS
+chime/MZGDRS
+chimer/M
+chimera/MS
+chimeric
+chimerical
+chimney/MS
+chimp/MS
+chimpanzee/SM
+chin/SM
+china/M
+chinaware/M
+chinchilla/MS
+chine/MS
+chink/GMDS
+chinless
+chinned
+chinning
+chino/MS
+chinstrap/MS
+chintz/M
+chintzy/RT
+chinwag/S
+chip/SM
+chipboard
+chipmunk/SM
+chipolata/S
+chipped
+chipper/MS
+chippie
+chipping/S
+chippy/S
+chiral
+chirality
+chirography/M
+chiropodist/MS
+chiropody/M
+chiropractic/SM
+chiropractor/SM
+chirp/GMDS
+chirpily
+chirpy/PTR
+chirrup/GMDS
+chisel/ZGMDRS
+chiseler/M
+chiselled
+chiseller/MS
+chiselling
+chit/SM
+chitchat/SM
+chitchatted
+chitchatting
+chitin/M
+chitinous
+chitlins/M
+chitosan
+chitterlings/M
+chivalrous/PY
+chivalrousness/M
+chivalry/M
+chive/MS
+chivvy/GDS
+chivy/GDS
+chlamydia/MS
+chlamydiae
+chloral/M
+chlordane/M
+chloride/MS
+chlorinate/GNDS
+chlorination/M
+chlorine/M
+chlorofluorocarbon/SM
+chloroform/SGMD
+chlorophyll/M
+chloroplast/MS
+chm
+choc/S
+chock/GMDS
+chockablock
+chocoholic/SM
+chocolate/MS
+chocolatey
+chocolaty
+choice/MTRS
+choir/MS
+choirboy/MS
+choirmaster/SM
+choke/MZGDRS
+chokecherry/SM
+choker/M
+cholecystectomy
+cholecystitis
+choler/M
+cholera/M
+choleric
+cholesterol/M
+chomp/ZGMDRS
+choose/ZGRS
+chooser/M
+choosiness/M
+choosy/TPR
+chop/SM
+chophouse/SM
+chopped
+chopper/MDGS
+choppily
+choppiness/M
+chopping
+choppy/TPR
+chopstick/SM
+choral/MYS
+chorale/MS
+chord/MS
+chordal
+chordate/SM
+chore/MS
+chorea/M
+choreograph/DRZG
+choreographer/M
+choreographic
+choreographically
+choreographs
+choreography/M
+chorister/SM
+choroid/MS
+chortle/MZGDRS
+chortler/M
+chorus/GMDS
+chose
+chosen
+chow/SGMD
+chowder/MS
+chrism/M
+christen/ASGD
+christening/MS
+christian/U
+christology
+chromatic
+chromatically
+chromatin/M
+chromatography
+chrome/MGDS
+chromium/M
+chromosomal
+chromosome/MS
+chronic
+chronically
+chronicle/DRSMZG
+chronicler/M
+chronograph/M
+chronographs
+chronological/Y
+chronologist/MS
+chronology/SM
+chronometer/SM
+chrysalis/MS
+chrysanthemum/MS
+chub/SM
+chubbiness/M
+chubby/TPR
+chuck/GMDS
+chuckhole/SM
+chuckle/MGDS
+chuffed
+chug/SM
+chugged
+chugging
+chukka/MS
+chum/SM
+chummed
+chummily
+chumminess/M
+chumming
+chummy/PTR
+chump/MS
+chunder/GDS
+chunk/GMDS
+chunkiness/M
+chunky/PTR
+chunter/DGS
+church/MS
+churchgoer/SM
+churchgoing/M
+churchman/M
+churchmen
+churchwarden/MS
+churchwoman
+churchwomen
+churchyard/SM
+churl/MS
+churlish/PY
+churlishness/M
+churn/ZGMDRS
+churner/M
+chute/MS
+chutney/MS
+chutzpah/M
+chyme/M
+chyron/MS
+chteau/M
+chteaux
+chtelaine/SM
+ciabatta/SM
+ciao/S
+cicada/MS
+cicatrices
+cicatrix/M
+cicerone/SM
+ciceroni
+cider's
+cider/S
+cigar/MS
+cigarette/MS
+cigarillo/MS
+cilantro/M
+cilia
+cilium/M
+cinch/GMDS
+cinchona/SM
+cincture/SM
+cinder/GMDS
+cine
+cinema/MS
+cinematic
+cinematographer/MS
+cinematographic
+cinematography/M
+cinnabar/M
+cinnamon/M
+cipher's
+cipher/CGDS
+ciphertext/S
+cir
+circa
+circadian
+circle/MGDS
+circlet/MS
+circuit/MDGS
+circuital
+circuitous/YP
+circuitousness/M
+circuitry/M
+circuity/M
+circular/SMY
+circularity/M
+circularize/DSG
+circulate/ADSG
+circulation/SM
+circulatory
+circumcise/XDSGN
+circumcised/U
+circumcision/M
+circumference/MS
+circumferential
+circumflex/MS
+circumlocution/MS
+circumlocutory
+circumnavigate/XGNDS
+circumnavigation/M
+circumpolar
+circumscribe/GDS
+circumscription/MS
+circumspect/Y
+circumspection/M
+circumstance/MGDS
+circumstantial/Y
+circumvent/DSG
+circumvention/M
+circus/MS
+cirque/MS
+cirrhosis/M
+cirrhotic/SM
+cirri
+cirrus/M
+cis
+cisgender/D
+cistern/MS
+cit
+citadel/MS
+citation/AMS
+cite's
+cite/IAGSD
+citified
+citizen/MS
+citizenry/M
+citizenship/M
+citric
+citron/MS
+citronella/M
+citrous
+citrus/MS
+city/SM
+citywide
+civet/MS
+civic/S
+civically
+civics/M
+civil/UY
+civilian/MS
+civility/ISM
+civilization/MS
+civilize/GDS
+civilized/U
+civvies/M
+ck
+cl
+clack/GMDS
+clad/U
+cladding/M
+clade
+claim's
+claim/CKEAGDS
+claimable/AKE
+claimant/MS
+claimed/U
+claimer/ECSM
+clairvoyance/M
+clairvoyant/MS
+clam/SM
+clambake/MS
+clamber/ZGMDRS
+clamberer/M
+clammed
+clammily
+clamminess/M
+clamming
+clammy/PTR
+clamor/GMDS
+clamorous
+clamp/GMDS
+clampdown/MS
+clan/SM
+clandestine/Y
+clang/ZGMDRS
+clangor/M
+clangorous/Y
+clank/GMDS
+clannish/P
+clannishness/M
+clansman/M
+clansmen
+clanswoman
+clanswomen
+clap/SM
+clapboard/MDGS
+clapped
+clapper/MS
+clapperboard/S
+clapping/M
+claptrap/M
+claque/MS
+claret/MS
+clarification/M
+clarify/XDSNG
+clarinet/SM
+clarinetist/SM
+clarinettist/MS
+clarion/MDGS
+clarity/M
+clash/GMDS
+clasp's
+clasp/UGDS
+class/GMDS
+classic/MS
+classical/MY
+classicism/M
+classicist/MS
+classifiable
+classification/CAM
+classifications
+classified's
+classified/U
+classifieds
+classifier/MS
+classify/ACSDGN
+classiness/M
+classism
+classless/P
+classmate/MS
+classroom/MS
+classwork/M
+classy/TRP
+clatter/GMDS
+clausal
+clause/MS
+claustrophobia/M
+claustrophobic
+clavichord/SM
+clavicle/MS
+clavier/MS
+claw's
+claw/CSGD
+clay/M
+clayey
+clayier
+clayiest
+clean/BJPZTGDRYS
+cleaner/M
+cleaning/M
+cleanliness/UM
+cleanly/UTPR
+cleanness/UM
+cleanse/ZGDRS
+cleanser/M
+cleanup/MS
+clear/JPTGMDRYS
+clearance/SM
+clearheaded
+clearing/M
+clearinghouse/SM
+clearness/M
+clearway/S
+cleat/MS
+cleavage/MS
+cleave/ZGDRS
+cleaver/M
+clef/SM
+cleft/MS
+clematis/MS
+clemency/IM
+clement/Y
+clementine/S
+clench/GMDS
+clerestory/SM
+clergy/SM
+clergyman/M
+clergymen
+clergywoman/M
+clergywomen
+cleric/MS
+clerical/Y
+clericalism/M
+clerk/GMDS
+clerkship/M
+clever/PTRY
+cleverness/M
+clevis/MS
+clew/SGMD
+cliche/MDS
+clich/MS
+clichd
+click/BZGMDRS
+clickbait
+clicker/M
+client/MS
+clientele/MS
+clientle/MS
+cliff/MS
+cliffhanger/SM
+cliffhanging
+clifftop/S
+clii
+climacteric/M
+climactic
+climate/SM
+climatic
+climatically
+climatologist/SM
+climatology/M
+climax/MDSG
+climb/SMDRZGB
+climber/M
+climbing/M
+clime/SM
+clinch/MDRSZG
+clincher/M
+cling/SMRZG
+clinger/M
+clingfilm
+clingy/RT
+clinic/SM
+clinical/Y
+clinician/SM
+clink/SMDRZG
+clinker/M
+cliometric/S
+cliometrician/MS
+cliometrics/M
+clip/SM
+clipboard/MS
+clipped
+clipper/SM
+clipping/SM
+clique/SM
+cliquey
+cliquish/YP
+cliquishness/M
+clit/SM
+clitoral
+clitorides
+clitoris/MS
+clix
+cloaca/M
+cloacae
+cloak's
+cloak/USDG
+cloakroom/MS
+clobber/SMDG
+cloche/SM
+clock/SMDG
+clockwise
+clockwork/SM
+clod/MS
+cloddish
+clodhopper/MS
+clog's
+clog/US
+clogged/U
+clogging/U
+cloisonne/M
+cloisonn/M
+cloister/SMDG
+cloistral
+clomp/SDG
+clonal
+clone/DSMG
+clonidine
+clonk/SMDG
+clop/MS
+clopped
+clopping
+closable/I
+close/DRSMYTGBJP
+closefisted
+closemouthed
+closeness/M
+closeout/MS
+closet/SMDG
+closeup/SM
+closing/M
+closure/ESM
+clot/MS
+cloth/M
+clothe/UDSG
+clotheshorse/MS
+clothesline/SM
+clothespin/SM
+clothier/MS
+clothing/M
+cloths
+clotted
+clotting
+cloture/SM
+cloud/SMDG
+cloudburst/SM
+clouded/U
+cloudiness/M
+cloudless
+cloudy/RPT
+clout/SMDG
+clove/RSMZ
+cloven
+clover/M
+cloverleaf/SM
+cloverleaves
+clown/SMDG
+clownish/YP
+clownishness/M
+cloy/DGS
+cloying/Y
+club/MS
+clubbable
+clubbed
+clubber/S
+clubbing
+clubfeet
+clubfoot/MD
+clubhouse/SM
+clubland
+cluck/SMDG
+clue/MGDS
+clueless
+clump/SMDG
+clumpy/TR
+clumsily
+clumsiness/M
+clumsy/TRP
+clung
+clunk/SMDRZG
+clunker/M
+clunky/TR
+cluster/MDSG
+clutch/GMDS
+clutter's
+clutter/UDSG
+clvi
+clvii
+clxi
+clxii
+clxiv
+clxix
+clxvi
+clxvii
+cm
+cnidarian/MS
+co/ESD
+coach/MDSG
+coachload/S
+coachman/M
+coachmen
+coachwork
+coadjutor/MS
+coagulant/MS
+coagulate/GNDS
+coagulation/M
+coagulator/MS
+coal/MDGS
+coalesce/GDS
+coalescence/M
+coalescent
+coalface/MS
+coalfield/S
+coalition/MS
+coalitionist/MS
+coalmine/S
+coarse/RYTP
+coarsen/SDG
+coarseness/M
+coast/SMDRZG
+coastal
+coaster/M
+coastguard/S
+coastline/MS
+coat/MDGJS
+coating/M
+coatroom/S
+coattail/SM
+coauthor/MDGS
+coax/DRSZG
+coaxer/M
+coaxial/Y
+coaxing/Y
+cob/SM
+cobalt/M
+cobber/S
+cobble/DRSMZG
+cobbler/M
+cobblestone/SM
+cobnut/S
+cobra/SM
+cobweb/SM
+cobwebbed
+cobwebby/RT
+coca/M
+cocaine/M
+cocci/S
+coccus/M
+coccyges
+coccyx/M
+cochineal/M
+cochlea/SM
+cochleae
+cochlear
+cock/MDGS
+cockade/SM
+cockamamie
+cockatiel/MS
+cockatoo/SM
+cockatrice/SM
+cockchafer/S
+cockcrow/SM
+cockerel/SM
+cockeyed
+cockfight/MGS
+cockfighting/M
+cockily
+cockiness/M
+cockle/SM
+cockleshell/SM
+cockney/SM
+cockpit/SM
+cockroach/MS
+cockscomb/SM
+cocksucker/MS!
+cocksure
+cocktail/MS
+cocky/RTP
+coco/MS
+cocoa/SM
+coconut/SM
+cocoon/SMDG
+cod/SM
+coda/MS
+codded
+codding
+coddle/DSG
+code's
+code/CZGDRS
+codebook/M
+codec/SM
+codeine/M
+codependency/M
+codependent/SM
+coder/CM
+codex/M
+codfish/MS
+codger/SM
+codices
+codicil/SM
+codification/M
+codifier/M
+codify/XDRSNZG
+codon/SM
+codpiece/MS
+codswallop
+coed/MS
+coeducation/M
+coeducational
+coefficient/MS
+coelenterate/MS
+coenzyme
+coequal/MYS
+coerce/DRSZGNV
+coercer/M
+coercion/M
+coeval/SMY
+coexist/DSG
+coexistence/M
+coexistent
+coextensive
+coffee/SM
+coffeecake/SM
+coffeehouse/MS
+coffeemaker/SM
+coffeepot/MS
+coffer/SM
+cofferdam/MS
+coffin/SMDG
+cofunction/MS
+cog/SM
+cogency/M
+cogent/Y
+cogitate/DSXGNV
+cogitation/M
+cogitator/MS
+cognac/SM
+cognate/MS
+cognition/AM
+cognitional
+cognitive/Y
+cognizable
+cognizance/AM
+cognizant
+cognomen/SM
+cognoscente/M
+cognoscenti
+cogwheel/SM
+cohabit/SGD
+cohabitant/MS
+cohabitation/M
+coheir/SM
+cohere/DSG
+coherence/IM
+coherency/M
+coherent/IY
+cohesion/M
+cohesive/YP
+cohesiveness/M
+coho/MS
+cohort/SM
+coif/MDGS
+coiffed
+coiffing
+coiffure/DSMG
+coil's/A
+coil/UADGS
+coin/MDRZGS
+coinage/SM
+coincide/DSG
+coincidence/MS
+coincident
+coincidental/Y
+coiner/M
+coinsurance/M
+coir
+coital
+coitus/M
+coke/MGDS
+col/S
+cola/MS
+colander/SM
+cold/MRYTPS
+coldblooded
+coldness/M
+coleslaw/M
+coleus/MS
+coley/S
+coli
+colic/M
+colicky
+coliseum/MS
+colitis/M
+coll
+collaborate/DSXGNV
+collaboration/M
+collaborationist
+collaborative/Y
+collaborator/MS
+collage/SM
+collagen
+collapse/MGDS
+collapsible
+collar/SMDG
+collarbone/SM
+collard/SM
+collarless
+collate/DSXGN
+collateral/MY
+collateralize
+collation/M
+collator/MS
+colleague/MS
+collect's
+collect/ASGVD
+collectable/MS
+collected/U
+collectedly
+collectible/SM
+collection/AMS
+collective/MYS
+collectivism/M
+collectivist/SM
+collectivization/M
+collectivize/DSG
+collector/MS
+colleen/SM
+college/SM
+collegial
+collegiality/M
+collegian/MS
+collegiate
+collide/DRSZG
+collie/RSMZ
+collier/M
+colliery/SM
+collimate/DGN
+collinear
+collinearity
+collision/SM
+collocate/MGNDSX
+collocation/M
+colloid/SM
+colloidal
+colloq
+colloquial/Y
+colloquialism/SM
+colloquies
+colloquium/MS
+colloquy/M
+collude/DSG
+collusion/M
+collusive
+colocate/XDSGN
+cologne/SM
+colon/SM
+colonel/SM
+colonelcy/M
+colones
+colonial/SMY
+colonialism/M
+colonialist/MS
+colonist/SM
+colonization/ACM
+colonize/CAGSD
+colonizer/MS
+colonnade/MDS
+colonoscope/MS
+colonoscopy/SM
+colony/SM
+colophon/SM
+color's
+color/AEGDS
+colorant/SM
+coloration/EM
+coloratura/MS
+colorblind/P
+colorblindness/M
+colored's
+colored/U
+coloreds
+colorfast/P
+colorfastness/M
+colorful/PY
+colorfulness/M
+colorimeter/SM
+coloring's
+colorist/S
+colorization/M
+colorize/DSG
+colorless/PY
+colorlessness/M
+colorway/S
+colossal/Y
+colossi
+colossus/M
+colostomy/SM
+colostrum/M
+colt/MS
+coltish
+columbine/SM
+column/SMD
+columnar
+columnist/SM
+com/J
+coma/MS
+comaker/SM
+comatose
+comb/MDRZGJS
+combat/SMDGV
+combatant/SM
+combativeness/M
+combed/U
+comber/M
+combination/SM
+combinatorics
+combine's
+combine/ADSG
+combined/U
+combiner/MS
+combings/M
+combo/SM
+combust/SGVD
+combustibility/M
+combustible/MS
+combustion/M
+come/IMZGRS
+comeback/MS
+comedian/MS
+comedic
+comedienne/MS
+comedown/MS
+comedy/SM
+comeliness/M
+comely/RPT
+comer's
+comestible/SM
+comet/SM
+comeuppance/SM
+comfit's
+comfit/ES
+comfort/ESMDG
+comfortable/P
+comfortableness/M
+comfortably/U
+comforter/MS
+comforting/Y
+comfortless
+comfy/RT
+comic/SM
+comical/Y
+comicality/M
+coming/M
+comity/M
+comm
+comma/SM
+command/SMDRLZG
+commandant/MS
+commandeer/GDS
+commander/M
+commandment/MS
+commando/SM
+commemorate/XGNVDS
+commemoration/M
+commemorator/MS
+commence/ADSLG
+commencement/AM
+commencements
+commend/ASDBG
+commendably
+commendation/AMS
+commendatory
+commensurability
+commensurable
+commensurate/IY
+comment/ZGSMDR
+commentary/SM
+commentate/DSG
+commentator/SM
+commenter/M
+commerce/M
+commercial/SMY
+commercialism/M
+commercialization/M
+commercialize/GDS
+commie/SM
+commingle/DSG
+commiserate/GNVDSX
+commiseration/M
+commissar/SM
+commissariat/SM
+commissary/SM
+commission's
+commission/ACSGD
+commissionaire/S
+commissioner/SM
+commit/AS
+commitment/MS
+committal/SM
+committed/AU
+committee/SM
+committeeman/M
+committeemen
+committeewoman/M
+committeewomen
+committer/S
+committing/A
+commode's
+commode/EIS
+commodification
+commodious/Y
+commoditization
+commodity/SM
+commodore/SM
+common's
+common/UPRYT
+commonality/S
+commonalty/M
+commoner/MS
+commonness/UM
+commonplace/MS
+commons
+commonsense
+commonweal/MH
+commonwealth/M
+commonwealths
+commotion/SM
+communal/Y
+commune/XDSMGN
+communicability/M
+communicable/I
+communicably
+communicant/MS
+communicate/GNVDSX
+communication/M
+communicative/U
+communicator/SM
+communion/M
+communique/SM
+communism/M
+communist/SM
+communistic
+community/SM
+commutation/MS
+commutative
+commutativity
+commutator/SM
+commute/BDRSMZG
+commuter/M
+comorbidity/S
+comp/MDYGS
+compact/TGSMDRYP
+compaction
+compactness/M
+compactor/SM
+companion/SBM
+companionably
+companionship/M
+companionway/MS
+company/SM
+comparability/M
+comparable/I
+comparably/I
+comparative/MYS
+compare/BDSG
+comparison/MS
+compartment/SM
+compartmental
+compartmentalization/M
+compartmentalize/DSG
+compass/GMDS
+compassion/M
+compassionate/UY
+compatibility/ISM
+compatible/IMS
+compatibly/I
+compatriot/MS
+compeer/SM
+compel/S
+compelled
+compelling/Y
+compendious
+compendium/SM
+compensate/DSXGN
+compensated/U
+compensation/M
+compensatory
+compere/DSG
+compete/DSG
+competence/IM
+competences
+competencies
+competency/IM
+competent/IY
+competition/SM
+competitive/PY
+competitiveness/M
+competitor/SM
+compilation/AM
+compilations
+compile/DRSZG
+compiler/M
+complacence/M
+complacency/M
+complacent/Y
+complain/DRZGS
+complainant/MS
+complainer/M
+complaint/SM
+complaisance/M
+complaisant/Y
+complected
+complement/SGMD
+complementarity/SM
+complementary
+complete/PYTGNXDRS
+completed/U
+completeness/IM
+completion/M
+complex/MSY
+complexion/MDS
+complexional
+complexity/SM
+compliance/M
+compliant/Y
+complicate/GDS
+complicated/Y
+complication/M
+complicit
+complicity/M
+compliment/MDGS
+complimentary/U
+comply/NDSXG
+compo
+component/SM
+comport/LSGD
+comportment/M
+compos/RBZ
+compose/AECGSD
+composedly
+composer/M
+composite/MYGNXPDS
+composition/CM
+compositional
+compositor/SM
+compost/SGMD
+composure/EM
+compote/SM
+compound/GMDBS
+compounded/U
+comprehend/SDG
+comprehensibility/IM
+comprehensible/I
+comprehensibly/I
+comprehension/IM
+comprehensions
+comprehensive/PMYS
+comprehensiveness/M
+compress's
+compress/CGVDS
+compressed/U
+compressible
+compression/CMS
+compressor/SM
+comprise/GDS
+compromise/MGDS
+comptroller/MS
+compulsion/MS
+compulsive/YP
+compulsiveness/M
+compulsorily
+compulsory/SM
+compunction/SM
+computation/SM
+computational/Y
+compute/ADSG
+computer/MS
+computerate
+computerization/M
+computerize/GDS
+computing/M
+compre/DSG
+comrade/SMY
+comradery
+comradeship/M
+con/GSM
+concatenate/XDSGN
+concatenation/M
+concave/YP
+concaveness/M
+conceal/SDRZGBL
+concealed/U
+concealer/M
+concealment/M
+conceit/SMD
+conceited/PY
+conceitedness/M
+conceivable/I
+conceivably/I
+conceive/DSGB
+concentrate/DSMGNX
+concentration/M
+concentric
+concentrically
+concept/SM
+conception/SM
+conceptional
+conceptual/Y
+conceptualization/MS
+conceptualize/DSG
+concern/UMD
+concerned/UY
+concerning
+concerns
+concert's
+concert/ESDG
+concerted/Y
+concertgoer/S
+concertina/SGMD
+concertize/DSG
+concertmaster/MS
+concerto/SM
+concessionaire/MS
+concessional
+concessionary
+conch/M
+conchie/S
+conchs
+concierge/MS
+conciliate/DSGN
+conciliation/AM
+conciliator/SM
+conciliatory
+concise/RPYTN
+conciseness/M
+concision/M
+conclave/SM
+conclude/DSG
+conclusion/MS
+conclusive/IYP
+conclusiveness/IM
+concoct/SDG
+concoction/MS
+concomitant/MYS
+concord/M
+concordance/SM
+concordant
+concordat/SM
+concourse/SM
+concrete/DSPMYGNX
+concreteness/M
+concretion/M
+concubinage/M
+concubine/MS
+concupiscence/M
+concupiscent
+concur/S
+concurred
+concurrence/SM
+concurrency
+concurring
+concuss/V
+concussion/SM
+condemn/SDRZG
+condemnation/MS
+condemnatory
+condemner/M
+condensate/MNXS
+condensation/M
+condense/DRSZG
+condenser/M
+condescending/Y
+condescension/M
+condign
+condiment/MS
+condition's
+condition/AGSD
+conditional/SMY
+conditionality
+conditioned/U
+conditioner/SM
+conditioning/M
+condo/SM
+condolence/SM
+condom/SM
+condominium/MS
+condone/DSG
+condor/SM
+conduce/DSGV
+conduct/MDGV
+conductance/M
+conductibility/M
+conductible
+conduction/M
+conductivity/M
+conductor/MS
+conductress/MS
+conduit/SM
+cone/M
+coney/SM
+confab/SM
+confabbed
+confabbing
+confabulate/XDSGN
+confabulation/M
+confection/SZMR
+confectioner/M
+confectionery/SM
+confederacy/SM
+confederate/M
+confer/SB
+conferee/SM
+conference/MGDS
+conferrable
+conferral/M
+conferred
+conferrer/MS
+conferring
+confessed/Y
+confession/SM
+confessional/SM
+confessor/MS
+confetti/M
+confidant/MS
+confidante/SM
+confide/DRSZG
+confidence/SM
+confident/Y
+confidential/Y
+confidentiality/M
+confider/M
+confiding/Y
+configuration/S
+configure/ABD
+confined/U
+confinement/MS
+confirm/ASDG
+confirmation/ASM
+confirmatory
+confirmed/U
+confiscate/DSGNX
+confiscation/M
+confiscator/SM
+confiscatory
+conflagration/MS
+conflate/XDSGN
+conflation/M
+conflict/SGMD
+confluence/MS
+confluent
+conform/ZB
+conformable/U
+conformal
+conformance/M
+conformant
+conformism/M
+conformist/SM
+conformity/M
+confrere/MS
+confrontation/SM
+confrontational
+confrre/SM
+confuse/RZ
+confused/Y
+confusing/Y
+confutation/M
+confute/DSG
+conga/SMDG
+congeal/SLDG
+congealment/M
+conger/SM
+congeries/M
+congest/SDGV
+congestion/M
+conglomerate/DSXMGN
+conglomeration/M
+congrats/M
+congratulate/XGNDS
+congratulation/M
+congratulatory
+congregant/MS
+congregate/GNDSX
+congregation/M
+congregational
+congregationalism/M
+congregationalist/MS
+congress/MS
+congressional/Y
+congressman/M
+congressmen
+congresspeople
+congressperson/MS
+congresswoman/M
+congresswomen
+congruence/M
+congruent/IY
+congruity/ISM
+congruous
+conic/SM
+conical/Y
+conifer/SM
+coniferous
+conjectural
+conjecture/MGDS
+conjoint
+conjugal/Y
+conjugate/DSXGN
+conjugation/M
+conjunct/VMS
+conjunctiva/SM
+conjunctive/SM
+conjunctivitis/M
+conjuration/MS
+conjure/DRSZG
+conjurer/M
+conk/MDRZ
+connect/AEDVGS
+connectable
+connected/U
+connection/EMS
+connective/MS
+connectivity/M
+connector/MS
+conned
+conning
+conniption/MS
+connivance/M
+connive/DRSZG
+conniver/M
+connoisseur/SM
+connotative
+connubial
+conquer/ASDG
+conquerable/U
+conquered/U
+conqueror/MS
+conquest/AM
+conquistador/SM
+cons/DSG
+consanguineous
+consanguinity/M
+conscienceless
+conscientious/PY
+conscientiousness/M
+conscious/UYP
+consciousness/UM
+consciousnesses
+conscription/M
+consecrate/ADSGN
+consecrated/U
+consecration/AM
+consecrations
+consecutive/Y
+consensual
+consensus/MS
+consent/SMDG
+consequence/SM
+consequent/Y
+consequential/IY
+conservancy/SM
+conservation/M
+conservationism/M
+conservationist/SM
+conservatism/M
+conservative/MYS
+conservatoire/S
+conservator/SM
+conservatory/SM
+consider/AGSD
+considerable/I
+considerably
+considerate/IPYN
+considerateness/IM
+consideration/AIM
+considerations
+considered/U
+consign/ASDG
+consignee/MS
+consignment/MS
+consist/SDG
+consistence/MS
+consistency/ISM
+consistent/IY
+consistory/SM
+consolable/I
+consolation/MS
+consolatory
+consolidate/XDSGN
+consolidated/U
+consolidation/M
+consolidator/MS
+consoling/Y
+consomme/M
+consomm/M
+consonance/SM
+consonant/SMY
+consortia
+consortium/M
+conspectus/MS
+conspicuous/IPY
+conspicuousness/IM
+conspiracy/SM
+conspirator/MS
+conspiratorial/Y
+conspire/GD
+constable/SM
+constabulary/SM
+constancy/IM
+constant/MYS
+constellation/SM
+consternation/M
+constipate/GNDS
+constipation/M
+constituency/SM
+constituent/SM
+constitute/ADSGNV
+constitution/AM
+constitutional/MYS
+constitutionalism
+constitutionality/UM
+constitutions
+constrained/U
+constraint/SM
+constrict/GVSD
+constriction/SM
+constrictor/SM
+construable
+construct/CADVGS
+construction/CAMS
+constructional
+constructionist/CSM
+constructive/YP
+constructiveness/M
+constructor/MS
+construe/GDS
+consul/KSM
+consular/K
+consulate/SM
+consulship/M
+consult/GSD
+consultancy/SM
+consultant/MS
+consultation/MS
+consultative
+consumable/SM
+consume/BDRSZG
+consumed/U
+consumer/M
+consumerism/M
+consumerist/MS
+consummate/YGNXDS
+consummated/U
+consumption/M
+consumptive/SM
+cont
+contact/ASDG
+contactable
+contactless
+contagion/MS
+contagious/PY
+contagiousness/M
+contain/SBLDRZG
+contained/U
+container/M
+containerization/M
+containerize/DSG
+containment/M
+contaminant/SM
+contaminate/ACDSG
+contaminated/U
+contamination/CM
+contaminator/SM
+contd
+contemn/SDG
+contemplate/DSGNV
+contemplation/M
+contemplative/SMY
+contemporaneity/M
+contemporaneous/Y
+contempt/M
+contemptible
+contemptibly
+contemptuous/YP
+contemptuousness/M
+contender/MS
+content/ESLMDG
+contented/EY
+contentedness/M
+contention/SM
+contentious/YP
+contentiousness/M
+contently
+contentment/EM
+conterminous/Y
+contestable/I
+contestant/MS
+contested/U
+contextualization
+contextualize/CDSG
+contiguity/M
+contiguous/Y
+continence/IM
+continent/SM
+continental/SM
+continentalism/M
+contingency/SM
+contingent/SMY
+continua
+continual/Y
+continuance/EMS
+continuation/EMS
+continue/EGDS
+continuity/ESM
+continuous/EY
+continuum/M
+contort/GD
+contortion/MS
+contortionist/SM
+contra
+contraband/M
+contrabass/MS
+contrabassoon/S
+contraception/M
+contraceptive/SM
+contract/MDG
+contractible
+contractile
+contractility
+contraction/S
+contractual/Y
+contradict/SDG
+contradicted/U
+contradiction/SM
+contradictory
+contradistinction/MS
+contraflow/S
+contrail/MS
+contraindicate/GNXDS
+contraindication/M
+contralto/SM
+contraption/SM
+contrapuntal/Y
+contrarian/SM
+contrarianism
+contrariety/M
+contrarily
+contrariness/M
+contrariwise
+contrary/PSM
+contrast/MDGS
+contravene/GDS
+contravention/SM
+contretemps/M
+contribute/XGND
+contribution/M
+contributor/MS
+contributory
+contrition/M
+contrivance/MS
+contrive/ZGDRS
+contriver/M
+control's
+control/CS
+controllable/U
+controlled/UC
+controller/MS
+controlling/C
+controversial/Y
+controversy/SM
+controvert/DSG
+controvertible/I
+contumacious/Y
+contumacy/M
+contumelious
+contumely/SM
+contuse/XDSGN
+contusion/M
+conundrum/SM
+conurbation/MS
+convalesce/DSG
+convalescence/MS
+convalescent/SM
+convection/M
+convectional
+convective
+convector/S
+convene/ADSG
+convener/MS
+convenience/IMS
+convenient/IY
+convenor/MS
+convent/SM
+conventicle/MS
+convention/SM
+conventional/UY
+conventionality/UM
+conventionalize/GDS
+conventioneer/S
+convergence/MS
+convergent
+conversant
+conversation/MS
+conversational/Y
+conversationalist/SM
+converse/Y
+convert's
+convert/AGSD
+converted/U
+converter/SM
+convertibility/M
+convertible/SM
+convertor/SM
+convex/Y
+convexity/M
+convey/SBDG
+conveyance/MGS
+conveyor/MS
+convict/GSMD
+conviction/MS
+convince/GDS
+convinced/U
+convincing/UY
+convivial/Y
+conviviality/M
+convoke/DSG
+convoluted
+convolution/MS
+convolutional
+convoy/SMDG
+convulse/GNVXDS
+convulsion/M
+convulsive/Y
+cony/SM
+coo/GSMD
+cook's
+cook/ADGS
+cookbook/MS
+cooked/U
+cooker/SM
+cookery/SM
+cookhouse/S
+cookie/M
+cooking/M
+cookout/SM
+cookware/SM
+cooky/SM
+cool/MDRYZTGPS
+coolant/SM
+cooler/M
+coolie/SM
+coolness/M
+coon/MS!
+coonskin/MS
+coop/MDRZGS
+cooper/MDG
+cooperage/M
+cooperate/DSGNV
+cooperation/M
+cooperative/PMYS
+cooperativeness/M
+cooperator/SM
+coordinate/DSMYGN
+coordinated/U
+coordination/M
+coordinator/MS
+coot/MS
+cootie/SM
+cop/GJSMD
+copacetic
+copay/M
+cope/MS
+copier/SM
+copilot/SM
+coping/M
+copious/PY
+copiousness/M
+copped
+copper/SM
+copperhead/SM
+copperplate/M
+coppery
+copping
+copra/M
+coproduct/MS
+copse/SM
+copter/SM
+copula/SM
+copulate/GNVDS
+copulation/M
+copulative/SM
+copy's
+copy/ADSG
+copybook/SM
+copycat/MS
+copycatted
+copycatting
+copyist/MS
+copyleft
+copyright/GSBMD
+copyrightable/U
+copywriter/MS
+coquetry/SM
+coquette/DSMG
+coquettish/Y
+cor
+coracle/SM
+coral/SM
+corbel/SM
+cord/EASGDM
+cordage/M
+cordial/SMY
+cordiality/M
+cordillera/MS
+cordite/M
+cordless
+cordon/SMDG
+cordovan/M
+corduroy/MS
+corduroys/M
+core/MZGDRS
+coreligionist/S
+corer/M
+corespondent/MS
+corgi/SM
+coriander/M
+cork's
+cork/UDGS
+corkage
+corker/SM
+corkscrew/SMDG
+corm/MS
+cormorant/SM
+corn/MDRZGS
+cornball/MS
+cornbread/M
+corncob/MS
+corncrake/S
+cornea/SM
+corneal
+corner/GMD
+cornerstone/SM
+cornet/SM
+cornfield/S
+cornflakes/M
+cornflour
+cornflower/SM
+cornice/MS
+cornily
+corniness/M
+cornmeal/M
+cornrow/MDGS
+cornstalk/SM
+cornstarch/M
+cornucopia/MS
+corny/PRT
+corolla/MS
+corollary/SM
+corona/SM
+coronal/MS
+coronary/SM
+coronation/SM
+coronavirus/MS
+coroner/MS
+coronet/MS
+corp
+corpora
+corporal/SM
+corporate/XYN
+corporation/IM
+corporatism
+corporeal/Y
+corporeality/M
+corps/MS
+corpse/M
+corpsman/M
+corpsmen
+corpulence/M
+corpulent
+corpus/M
+corpuscle/MS
+corpuscular
+corr
+corral/SM
+corralled
+corralling
+correct/DRYTGVSBP
+corrected/U
+correction/SM
+correctional
+corrective/SM
+correctness/IM
+corrector
+correlate/XDSMGNV
+correlated/U
+correlation/M
+correlational
+correlative/MS
+correspond/SDG
+correspondence/SM
+correspondent/SM
+corresponding/Y
+corridor/SM
+corrie/S
+corrigibility/IM
+corrigible/I
+corroborate/GNVDSX
+corroborated/U
+corroboration/M
+corroborator/SM
+corroboratory
+corrode/GDS
+corrosion/M
+corrosive/SMY
+corrugate/GNXDS
+corrugation/M
+corrupt/DRYPSTG
+corruptibility/IM
+corruptible/I
+corruptibly/I
+corruption/MS
+corruptness/M
+corsage/MS
+corsair/MS
+corset/SGMD
+cortege/MS
+cortex/M
+cortical
+cortices
+cortisol
+cortisone/M
+cortge/SM
+corundum/M
+coruscate/GNDS
+coruscation/M
+corvette/SM
+cos/M
+cosh/DSG
+cosign/ZGSDR
+cosignatory/SM
+cosigner/M
+cosine/SM
+cosmetic/SM
+cosmetically
+cosmetician/MS
+cosmetologist/MS
+cosmetology/M
+cosmic
+cosmically
+cosmogonist/SM
+cosmogony/SM
+cosmological
+cosmologist/SM
+cosmology/SM
+cosmonaut/SM
+cosmopolitan/MS
+cosmopolitanism/M
+cosmos/MS
+cosplay/DRSZG
+cosponsor/GSMD
+cosset/SGD
+cossetted
+cossetting
+cost/MDYGSJ
+costar/SM
+costarred
+costarring
+costliness/M
+costly/PTR
+costume/MZGDRS
+costumer/M
+costumier/S
+cot/SM
+cotangent/MS
+cote/MS
+coterie/MS
+coterminous
+cotillion/SM
+cottage/MZGRS
+cottager/M
+cottar/SM
+cotter/SM
+cotton/SGMD
+cottonmouth/M
+cottonmouths
+cottonseed/MS
+cottontail/MS
+cottonwood/SM
+cottony
+cotyledon/MS
+couch/MDSG
+couchette/S
+cougar/SM
+cough/MDG
+coughs
+could
+could've
+couldn't
+coulee/SM
+coulis
+coulomb/MS
+coule/SM
+council/MS
+councilman/M
+councilmen
+councilor/MS
+councilperson/SM
+councilwoman/M
+councilwomen
+counsel/JMDGS
+counselor/MS
+count/EASMDG
+countable/U
+countably
+countdown/MS
+counted/U
+countenance/EMGDS
+counter/EMS
+counteract/SGVD
+counteraction/MS
+counterargument/S
+counterattack/GMDS
+counterbalance/MGDS
+counterblast/S
+counterclaim/GSMD
+counterclockwise
+counterculture/SM
+countered
+counterespionage/M
+counterexample/S
+counterfactual
+counterfeit/ZGMDRS
+counterfeiter/M
+counterfoil/MS
+countering
+counterinsurgency/SM
+counterintelligence/M
+counterintuitive/Y
+counterman/M
+countermand/GMDS
+countermeasure/SM
+countermelody/S
+countermen
+countermove/S
+counteroffensive/SM
+counteroffer/SM
+counterpane/SM
+counterpart/SM
+counterpetition
+counterpoint/MDGS
+counterpoise/MGDS
+counterproductive
+counterproposal
+counterrevolution/SM
+counterrevolutionary/SM
+countersign/GSMD
+countersignature/MS
+countersink/GSM
+counterspy/SM
+counterstrike/SM
+counterstroke/SM
+countersunk
+countertenor/MS
+countertop/S
+countervail/GSD
+counterweight/MS
+countess/MS
+countless
+countrified
+country/SM
+countryman/M
+countrymen
+countryside/MS
+countrywide
+countrywoman/M
+countrywomen
+county/SM
+countywide
+coup's
+coup/AS
+coupe/SM
+couple's
+couple/UCGZSRD
+couplet/MS
+coupling/SM
+coupon/SM
+courage/M
+courageous/YP
+courageousness/M
+courgette/S
+courier/MDSG
+course/EDGMS
+coursebook/S
+courser/MS
+coursework
+court-martial/SGD
+court/SMDYG
+courteous/EY
+courteousness/M
+courtesan/SM
+courtesy/ESM
+courthouse/MS
+courtier/SM
+courtliness/M
+courtly/PRT
+courtroom/MS
+courtship/MS
+courtyard/MS
+couscous/M
+cousin/SM
+couture/M
+couturier/MS
+covalent
+covariance
+covariant
+covariate/S
+cove/MS
+coven/SM
+covenant/MDSG
+cover's
+cover/AEUGDS
+coverage/M
+coverall/MS
+covering's
+coverings
+coverlet/MS
+covert/SPMY
+covertness/M
+coverup/MS
+covet/SDG
+covetous/YP
+covetousness/M
+covey/SM
+cow/ZGSMDR
+coward/SMY
+cowardice/M
+cowardliness/M
+cowbell/MS
+cowbird/MS
+cowboy/SM
+cowcatcher/MS
+cower/DG
+cowgirl/MS
+cowhand/MS
+cowherd/MS
+cowhide/MS
+cowl/MGSJ
+cowlick/MS
+cowling/M
+cowman/M
+cowmen
+coworker/MS
+cowpat/S
+cowpoke/MS
+cowpox/M
+cowpuncher/SM
+cowrie/SM
+cowshed/S
+cowslip/SM
+cox/GDS
+coxcomb/MS
+coxswain/MS
+coy/TPRY
+coyness/M
+coyote/SM
+coypu/SM
+cozen/SDG
+cozenage/M
+cozily
+coziness/M
+cozy/RSMTP
+cpd
+cpl
+cps
+crab/MS
+crabbed
+crabber/SM
+crabbily
+crabbiness/M
+crabbing
+crabby/PRT
+crabgrass/M
+crablike
+crabwise
+crack/SMDRYZGJ
+crackdown/MS
+cracker/M
+crackerjack/MS
+crackhead/MS
+crackle/DSJMG
+crackling/M
+crackpot/MS
+crackup/SM
+cradle/DSMG
+craft/SMDG
+craftily
+craftiness/M
+craftsman/M
+craftsmanship/M
+craftsmen
+craftspeople
+craftswoman/M
+craftswomen
+crafty/RTP
+crag/MS
+cragginess/M
+craggy/RPT
+cram/S
+crammed
+crammer/S
+cramming
+cramp/SMDG
+cramping/M
+crampon/SM
+cranberry/SM
+crane/DSMG
+cranial
+cranium/SM
+crank/SMDG
+crankcase/SM
+crankily
+crankiness/M
+crankshaft/MS
+cranky/PRT
+cranny/DSM
+crap/MS
+crape/SM
+crapola
+crapped
+crapper/S
+crappie/M
+crapping
+crappy/RSPT
+craps/M
+crapshooter/MS
+crash/MDSG
+crass/RYTP
+crassness/M
+crate/DRSMZG
+crater/MDG
+cravat/SM
+crave/DSGJ
+craven/SMYP
+cravenness/M
+craving/M
+craw/MS
+crawdad/SM
+crawl/SMDRZG
+crawler/M
+crawlspace/SM
+crawly/TRSM
+cray/S
+crayfish/MS
+crayola/S
+crayon/GSMD
+craze/DSMG
+crazily
+craziness/M
+crazy/PRSMT
+creak/SMDG
+creakily
+creakiness/M
+creaky/RPT
+cream/SMDRZG
+creamer/M
+creamery/SM
+creamily
+creaminess/M
+creamy/RPT
+crease/ICGMSD
+create/AKVNGSDX
+creatine
+creation/KAM
+creationism/SM
+creationist/SM
+creative/SMYP
+creativeness/M
+creativity/M
+creator/MS
+creature/SM
+creche/SM
+cred
+credence/M
+credential/SGMD
+credenza/SM
+credibility/IM
+credible/I
+credibly/I
+credit/EGSBMD
+creditably/E
+creditor/SM
+creditworthy/P
+credo/SM
+credulity/IM
+credulous/IY
+credulousness/M
+creed/SM
+creek/SM
+creel/SM
+creep/SMRZG
+creeper/M
+creepily
+creepiness/M
+creepy/TPR
+cremains/M
+cremate/GNDSX
+cremation/M
+crematoria
+crematorium/MS
+crematory/SM
+creme/SM
+crenelate/XGNDS
+crenelation/M
+creole/SM
+creosote/MGDS
+crepe/SM
+crept
+crepuscular
+crescendo/CSM
+crescent/MS
+cress/M
+crest/SMDG
+crestfallen
+crestless
+cretaceous
+cretin/SM
+cretinism/M
+cretinous
+cretonne/M
+crevasse/SM
+crevice/MS
+crew/MDGS
+crewel/M
+crewelwork/M
+crewman/M
+crewmen
+crib/MS
+cribbage/M
+cribbed
+cribber/MS
+cribbing
+crick/SMDG
+cricket/MRSZG
+cricketer/M
+crier/M
+crikey
+crime/SM
+crimeware/M
+criminal/MYS
+criminality/M
+criminalization/C
+criminalize/CGDS
+criminologist/MS
+criminology/M
+crimp/SMDG
+crimson/SMDG
+cringe/DSMG
+crinkle/DSMG
+crinkly/RT
+crinoline/SM
+cripes
+cripple/DRSMZG
+crippler/M
+crippleware
+crippling/Y
+crises
+crisis/M
+crisp/SMDRYTGP
+crispbread/S
+crispiness/M
+crispness/M
+crispy/PRT
+crisscross/GMDS
+criteria
+criterion/M
+critic/SM
+critical/UY
+criticality
+criticism/MS
+criticize/ZGDRS
+criticizer/M
+critique/MGDS
+critter/SM
+croak/SMDG
+croaky/RT
+crochet/SMDRZG
+crocheter/M
+crocheting/M
+crock/SMD
+crockery/M
+crocodile/SM
+crocus/MS
+croft/SRZG
+croissant/MS
+crone/SM
+crony/SM
+cronyism/M
+crook/SMDG
+crooked/PTRY
+crookedness/M
+crookneck/SM
+croon/SMDRZG
+crooner/M
+crop/MS
+cropland/SM
+cropped
+cropper/MS
+cropping
+croquet/M
+croquette/SM
+crore/SM
+crosier/MS
+cross's
+cross/AUGTSD
+crossbar/SM
+crossbeam/MS
+crossbones/M
+crossbow/SM
+crossbowman/M
+crossbowmen
+crossbred
+crossbreed/SGM
+crosscheck/SMDG
+crosscurrent/MS
+crosscut/SM
+crosscutting
+crosser
+crossfire/MS
+crosshair/MS
+crosshatch/GDS
+crossing/SM
+crossly
+crossness/M
+crossover/MS
+crosspatch/MS
+crosspiece/SM
+crossroad/MS
+crossroads/M
+crosstown
+crosswalk/MS
+crosswind/MS
+crosswise
+crossword/MS
+crotch/MS
+crotchet/SM
+crotchety
+crouch/GMDS
+croup/M
+croupier/M
+croupy/ZTR
+crouton/MS
+crow/MDGS
+crowbar/MS
+crowd/SMDG
+crowded/U
+crowdfund/SDG
+crowdsource/DSG
+crowfeet
+crowfoot/SM
+crown/SMDG
+crowned/U
+crozier/MS
+croton/MS
+crucial/Y
+crucible/SM
+crucifix/MS
+crucifixion/SM
+cruciform/SM
+crucify/DSG
+crud/M
+cruddy/TR
+crude/RMYTP
+crudeness/M
+crudites/M
+crudity/SM
+crudits/M
+cruel/RYPT
+cruelness/M
+cruelty/SM
+cruet/SM
+cruft/SD
+crufty
+cruise/DRSMZG
+cruiser/M
+cruller/MS
+crumb/SMDYG
+crumble/MGDS
+crumbliness/M
+crumbly/TPR
+crumby/TR
+crumminess/M
+crummy/PTR
+crumpet/MS
+crumple/MGDS
+crunch/GMDRS
+crunchiness/M
+crunchy/TRP
+crupper/MS
+crusade/MZGDRS
+crusader/M
+cruse/SM
+crush/MDRSZG
+crusher/M
+crushing/Y
+crust/SMDG
+crustacean/SM
+crustal
+crustily
+crustiness/M
+crusty/TRP
+crutch/MS
+crux/MS
+cry/ZGJDRSM
+crybaby/SM
+cryogenic/S
+cryogenics/M
+cryonic/S
+cryosurgery/M
+crypt's
+crypt/S
+cryptanalysis
+cryptic
+cryptically
+crypto/M
+cryptocurrency/SM
+cryptogram/SM
+cryptographer/SM
+cryptographic
+cryptography/M
+cryptologist/MS
+cryptosystem/S
+crystal/SM
+crystalize/DSG
+crystalline
+crystallization/M
+crystallize/ADSG
+crystallographic
+crystallography
+crche/MS
+ct
+ctn
+ctr
+cu
+cub/ZGSMDR
+cubbyhole/MS
+cube/MS
+cuber/M
+cubic
+cubical
+cubicle/MS
+cubism/M
+cubist/SM
+cubit/SM
+cuboid/S
+cuckold/MDSG
+cuckoldry/M
+cuckoo/SM
+cucumber/SM
+cud/SM
+cuddle/DSMG
+cuddly/TR
+cudgel/SGMDJ
+cue/DSMG
+cuff/MDGS
+cuisine/SM
+cul-de-sac
+culinary
+cull/MDGS
+cullender/MS
+culminate/XDSGN
+culmination/M
+culotte/SM
+culpa/S
+culpability/M
+culpable/I
+culpably
+culprit/SM
+cult/MS
+cultism/M
+cultist/MS
+cultivable
+cultivar/SM
+cultivate/BDSGN
+cultivated/U
+cultivation/M
+cultivator/MS
+cultural/Y
+culture/MGDS
+cultured/U
+culvert/MS
+cum/SM
+cumber/SDG
+cumbersome/P
+cumbersomeness/M
+cumbrous
+cumin/M
+cummerbund/MS
+cumming
+cumulative/Y
+cumuli
+cumulonimbi
+cumulonimbus/M
+cumulus/M
+cuneiform/M
+cunnilingus/M
+cunning/MRYT
+cunt/MS!
+cup/SM
+cupboard/SM
+cupcake/MS
+cupful/SM
+cupid/SM
+cupidity/M
+cupola/SMD
+cuppa/S
+cupped
+cupping
+cupric
+cur/SMY
+curability/M
+curacao
+curacy/SM
+curare/M
+curate/DSMGNV
+curative/MS
+curator/KMS
+curatorial
+curaao
+curb/MDGS
+curbing/M
+curbside
+curbstone/SM
+curd/MS
+curdle/DSG
+cure's
+cure/KZGBDRS
+cured/U
+curer/KM
+curettage/M
+curfew/SM
+curia/M
+curiae
+curie/SM
+curio/SM
+curiosity/SM
+curious/YP
+curiousness/M
+curium/M
+curl's
+curl/UDGS
+curler/SM
+curlew/SM
+curlicue/DSMG
+curliness/M
+curling/M
+curly/RPT
+curmudgeon/MYS
+currant/MS
+currency/SM
+current's
+current/FSY
+curricula
+curricular
+curriculum/M
+curry/DSMG
+currycomb/SGMD
+curse's
+curse/ADSGV
+cursed/Y
+cursive's
+cursive/EAY
+cursor/SM
+cursorily
+cursoriness/M
+cursory/P
+curt/RYTP
+curtail/GDSL
+curtailment/SM
+curtain/GMDS
+curtness/M
+curtsy/GDSM
+curvaceous/P
+curvaceousness/M
+curvature/SM
+curve/DSMG
+curvy/RT
+cushion/MDSG
+cushy/RT
+cusp/MS
+cuspid/SM
+cuspidor/SM
+cuss's
+cuss/EFGSD
+cussed/PY
+custard/MS
+custodial
+custodian/MS
+custodianship/M
+custody/M
+custom/SZMR
+customarily
+customary/U
+customer/M
+customhouse/SM
+customization/M
+customize/DSGB
+cut/TSMR
+cutaneous
+cutaway/MS
+cutback/MS
+cute/YP
+cuteness/M
+cutesy/TR
+cutey/S
+cuticle/MS
+cutie/SM
+cutlass/MS
+cutler/SM
+cutlery/M
+cutlet/SM
+cutoff/SM
+cutout/SM
+cutter/SM
+cutthroat/SM
+cutting/MYS
+cuttlefish/MS
+cutup/SM
+cutworm/MS
+cw
+cwt
+cyan/M
+cyanide/M
+cyanobacteria
+cyber
+cyberattack/SM
+cyberbully/SM
+cybercafe/S
+cybercaf/S
+cybernetic/S
+cybernetics/M
+cyberpunk/SM
+cybersecurity
+cybersex
+cyberspace/MS
+cyborg/SM
+cyclamen/MS
+cycle/ADSMG
+cyclic
+cyclical/Y
+cyclist/MS
+cyclometer/MS
+cyclone/MS
+cyclonic
+cyclopaedia/MS
+cyclopedia/MS
+cyclopes
+cyclops/M
+cyclotron/MS
+cygnet/MS
+cylinder/MS
+cylindrical
+cymbal/MS
+cymbalist/MS
+cynic/SM
+cynical/Y
+cynicism/M
+cynosure/MS
+cypher/M
+cypress/MS
+cyst/MS
+cysteine/SM
+cystic
+cysticerci
+cysticercoid/S
+cysticercoses
+cysticercosis
+cysticercus
+cystitis
+cystoscope
+cystoscopic
+cystoscopy
+cytokine/SM
+cytologist/SM
+cytology/M
+cytoplasm/M
+cytoplasmic
+cytosine/M
+czar/MS
+czarina/SM
+czarism
+czarist/SM
+d'Arezzo/M
+d'Estaing/M
+d/NXGJ
+dB
+dab/SM
+dabbed
+dabber/MS
+dabbing
+dabble/ZGDRS
+dabbler/M
+dace/SM
+dacha/MS
+dachshund/MS
+dactyl/MS
+dactylic/MS
+dad/SM
+dadaism/M
+dadaist/MS
+daddy/SM
+dado/SM
+dadoes
+daemon/MS
+daemonic
+daffiness/M
+daffodil/SM
+daffy/PTR
+daft/PTRY
+daftness/M
+dag/S
+dagger/MS
+dago/S
+dagoes
+daguerreotype/DSMG
+dahlia/MS
+dailiness/M
+daily/PSM
+daintily
+daintiness/M
+dainty/RSMTP
+daiquiri/MS
+dairy/GSM
+dairying/M
+dairymaid/MS
+dairyman/M
+dairymen
+dairywoman/M
+dairywomen
+dais/MS
+daisy/SM
+dale/SM
+dalliance/MS
+dallier/M
+dally/ZGDRS
+dalmatian/MS
+dam/SM
+damage/MGDS
+damageable
+damaged/U
+damages/M
+damask/MDGS
+dame/SM
+dammed
+damming
+dammit
+damn/SBGMD
+damnably
+damnation/M
+damned/T
+damp/SPXZTGMDNRY
+dampen/ZGDR
+dampener/M
+damper/M
+dampness/M
+damsel/MS
+damselfly/SM
+damson/MS
+dance/MZGDRS
+dancer/M
+dancing/M
+dandelion/SM
+dander/M
+dandify/GDS
+dandle/GDS
+dandruff/M
+dandy/TRSM
+dang/SZGDR
+danger/M
+dangerous/Y
+dangle/ZGDRS
+dangler/M
+danish/MS
+dank/PTRY
+dankness/M
+danseuse/MS
+dapper/TR
+dapple/MGDS
+dare/DRSMZG
+daredevil/MS
+daredevilry/M
+darer/M
+daresay
+daring/MY
+dark/PXTMNRY
+darken/ZGDR
+darkener/M
+darkie/S
+darkness/M
+darkroom/MS
+darling/MS
+darn/SZGMDR
+darned/TR
+darner/M
+dart/SZGMDR
+dartboard/MS
+darter/M
+dash/ZGMDRS
+dashboard/SM
+dasher/M
+dashiki/MS
+dashing/Y
+dastard/MYS
+dastardliness/M
+data
+database/SM
+dataset/MS
+datasheet/SM
+datatype
+date/DRSMZGV
+datebook/S
+dated/U
+dateless
+dateline/MGDS
+dater/M
+dateset
+dative/MS
+datum/M
+daub/SZGMDR
+dauber/M
+daughter/SMY
+daunt/GDS
+daunting/Y
+dauntless/YP
+dauntlessness/M
+dauphin/MS
+davenport/MS
+davit/MS
+dawdle/ZGDRS
+dawdler/M
+dawn/SGMD
+day/SM
+daybed/MS
+daybreak/M
+daycare/M
+daydream/MDRZGS
+daydreamer/M
+daylight/MS
+daylights/M
+daylong
+daytime/M
+daze/DSMG
+dazed/Y
+dazzle/MZGDRS
+dazzler/M
+dazzling/Y
+db
+dbl
+dc
+dd/SDG
+dded/K
+dding/K
+de
+deacon/MS
+deaconess/MS
+dead/XTMNRY
+deadbeat/MS
+deadbolt/SM
+deaden/GD
+deadhead/SDG
+deadline/SM
+deadliness/M
+deadlock/GSMD
+deadly/TPR
+deadpan/MS
+deadpanned
+deadpanning
+deadwood/M
+deaf/PXTNR
+deafen/GD
+deafening/Y
+deafness/M
+deal/SJZGMR
+dealer/M
+dealership/SM
+dealing/M
+dealt
+dean/M
+deanery/SM
+deanship/M
+dear/SPTMRYH
+dearest/S
+dearie/M
+dearness/M
+dearth/M
+dearths
+deary/SM
+death/MY
+deathbed/SM
+deathblow/MS
+deathless/Y
+deathlike
+deaths
+deathtrap/MS
+deathwatch/MS
+deaves
+deb/SM
+debacle/MS
+debarkation/M
+debarment/M
+debate/BMZR
+debater/M
+debating/M
+debauch/MDSG
+debauchee/MS
+debauchery/SM
+debenture/MS
+debilitate/DSGN
+debilitation/M
+debility/SM
+debit/D
+debonair/PY
+debonairness/M
+debouch/GDS
+debridement
+debris/M
+debt/SM
+debtor/MS
+debugger/S
+debut/GMD
+debutante/SM
+decade/MS
+decadence/M
+decadency/M
+decadent/MYS
+decaf/MS
+decaffeinate/DSG
+decagon/MS
+decal/MS
+decampment/M
+decapitate/XGNDS
+decapitator/MS
+decathlete/S
+decathlon/SM
+decay/GD
+deceased/M
+decedent/MS
+deceit/MS
+deceitful/YP
+deceitfulness/M
+deceive/UGDS
+deceiver/MS
+deceiving/Y
+decelerate/GNDS
+deceleration/M
+decelerator/SM
+decency/ISM
+decennial/SM
+decent/IY
+deception/MS
+deceptive/YP
+deceptiveness/M
+decibel/MS
+decidable/U
+decide/BZGDRS
+decided/Y
+deciduous
+decile/S
+deciliter/MS
+decimal/SM
+decimalization
+decimate/DSGN
+decimation/M
+decimeter/MS
+decipherable/UI
+decision/IM
+decisions
+decisis
+decisive/IPY
+decisiveness/IM
+deck/SGMD
+deckchair/S
+deckhand/SM
+deckle/S
+declamation/MS
+declamatory
+declaration/MS
+declarative
+declaratory
+declare/DRSZGB
+declared/U
+declarer/M
+declension/SM
+declination/M
+decline/DRSMZG
+decliner/M
+declivity/SM
+decoherence
+decolletage/SM
+decollete
+decongestant/MS
+deconstructionism
+decor/MS
+decorate/AGNVDS
+decorating/M
+decoration/AM
+decorations
+decorative/Y
+decorator/MS
+decorous/IY
+decorousness/M
+decorum/M
+decoupage/DSMG
+decoy/GMDS
+decreasing/Y
+decree/MDS
+decreeing
+decrement/GDS
+decrepit
+decrepitude/M
+decriminalization/M
+decry/GDS
+decrypt/BSGD
+decryption
+dedendum/SM
+dedicate/AGDS
+dedication/SM
+dedicator/SM
+dedicatory
+deduce/GDS
+deducible
+deduct/GVD
+deductible/SM
+deduction/SM
+deductive/Y
+deed/GD
+deejay/MS
+deem/ASGD
+deep/SPXTMNRY
+deepen/GD
+deepfake/SM
+deepness/M
+deer/M
+deerskin/M
+deerstalker/S
+def/Z
+defacement/M
+defacer/SM
+defalcate/DSXGN
+defalcation/M
+defamation/M
+defamatory
+defame/ZGDRS
+defamer/M
+defaulter/SM
+defeat/MDRZGS
+defeated/U
+defeater/M
+defeatism/M
+defeatist/MS
+defecate/GNDS
+defecation/M
+defect/MDGVS
+defection/MS
+defective/MPYS
+defectiveness/M
+defector/MS
+defendant/SM
+defended/U
+defenestration/S
+defense/DSMGV
+defenseless/YP
+defenselessness/M
+defensible/I
+defensibly/I
+defensive/MYP
+defensiveness/M
+deference/M
+deferential/Y
+deferral/MS
+deferred
+deferring
+deffer
+deffest
+defiant/Y
+defibrillation
+defibrillator/S
+deficiency/SM
+deficient
+deficit/SM
+defilement/M
+definable/IU
+define/AGDS
+defined/U
+definer/MS
+definite/IYVP
+definiteness/IM
+definition/AM
+definitional/Y
+definitions
+definitive/Y
+deflate/GNDS
+deflation/M
+deflationary
+deflect/DGVS
+deflection/MS
+deflector/SM
+defogger/SM
+defoliant/SM
+defoliate/DSGN
+defoliation/M
+defoliator/MS
+deformity/SM
+defraud/DRZGS
+defrauder/M
+defrayal/M
+defrock/DG
+defroster/MS
+deft/PTRY
+deftness/M
+defunct
+defy/GDS
+deg
+degeneracy/M
+degenerate/MVX
+degrade/B
+degree/MS
+dehydrator/SM
+dehydrogenase/M
+deicer/MS
+deification/M
+deify/NGDS
+deign/GDS
+deist/MS
+deistic
+deity/SM
+deject/GDS
+dejected/Y
+dejection/M
+delay/ZDR
+delectable
+delectably
+delectation/M
+delegate/GD
+delete/XGNDS
+deleterious
+deletion/M
+delft/M
+delftware/M
+deli/SM
+deliberate/XYVP
+deliberateness/M
+delicacy/ISM
+delicate/IY
+delicateness/M
+delicatessen/SM
+delicious/PY
+deliciousness/M
+delighted/Y
+delightful/Y
+deliminator
+delineate/GNXDS
+delineation/M
+delinquency/SM
+delinquent/SMY
+deliquesce/DSG
+deliquescent
+delirious/YP
+deliriousness/M
+delirium/SM
+deliver/ADGS
+deliverable/S
+deliverables/U
+deliverance/M
+delivered/U
+deliverer/SM
+dell/SM
+delphinium/MS
+delta/MS
+delude/GDS
+deluge/MGDS
+delusion/MS
+delusional
+delusive/Y
+deluxe
+delve/ZGDRS
+delver/M
+demagogic
+demagogically
+demagogue/SM
+demagoguery/M
+demagogy/M
+demand/GMDS
+demanding/U
+demarcate/DSGNX
+demarcation/M
+demean/GDS
+demeanor/M
+demented/Y
+dementia/M
+demesne/MS
+demigod/MS
+demigoddess/MS
+demijohn/SM
+demimondaine/SM
+demimonde/M
+demise/MGD
+demitasse/MS
+demo/GMD
+democracy/SM
+democrat/MS
+democratic/U
+democratically
+democratization/M
+democratize/GDS
+demode
+demographer/SM
+demographic/SM
+demographically
+demographics/M
+demography/M
+demolish/DSG
+demolition/MS
+demon/MS
+demonetization/M
+demoniac
+demoniacal/Y
+demonic
+demonically
+demonize/GDS
+demonology/SM
+demonstrability
+demonstrable/I
+demonstrably
+demonstrate/XGNVDS
+demonstration/M
+demonstrative/MYSP
+demonstrativeness/M
+demonstrator/MS
+demonym/S
+demote/GD
+demotic
+demount
+demulcent/SM
+demur/TMRS
+demure/PY
+demureness/M
+demurral/SM
+demurred
+demurrer/SM
+demurring
+den/M
+denationalization
+denaturation
+denature/DG
+dendrite/SM
+dengue/M
+deniability
+deniable/U
+denial/MS
+denier/M
+denigrate/DSGN
+denigration/M
+denim/MS
+denitrification
+denizen/MS
+denominational
+denotative
+denouement/MS
+denounce/LDSG
+denouncement/SM
+dense/PYTR
+denseness/M
+density/SM
+dent/ISGMD
+dental/Y
+dentifrice/SM
+dentin/M
+dentine/M
+dentist/MS
+dentistry/M
+dentition/M
+denture/IMS
+denuclearize/GDS
+denudation/M
+denude/GDS
+denunciation/SM
+deny/ZGDRS
+deodorant/SM
+deodorization/M
+deodorize/DRSZG
+deodorizer/M
+departed/M
+department/MS
+departmental/Y
+departmentalization/M
+departmentalize/GDS
+departure/SM
+dependability/M
+dependable/U
+dependably
+dependence/IM
+dependency/SM
+dependent/IMYS
+depict/GDS
+depiction/MS
+depilatory/SM
+deplete/GNDS
+depletion/M
+deplorably
+deplore/BGDS
+deploy/ALGDS
+deployment/AM
+deployments
+deponent/MS
+deportation/MS
+deportee/MS
+deportment/M
+deposit/AGMDS
+depositor/MS
+depository/SM
+deprave/GDS
+depravity/SM
+deprecate/GNDS
+deprecating/Y
+deprecation/M
+deprecatory
+depreciate/DSGN
+depreciation/M
+depredation/SM
+depressant/SM
+depressing/Y
+depression/SM
+depressive/SM
+depressor/MS
+depressurization
+deprive/GDS
+deprogramming
+depth/M
+depths
+deputation/MS
+depute/DSG
+deputize/DSG
+deputy/SM
+derailleur/SM
+derailment/SM
+derangement/M
+derby/SM
+dereliction/M
+deride/GDS
+derision/M
+derisive/PY
+derisiveness/M
+derisory
+derivation/MS
+derivative/MS
+derive/B
+dermal
+dermatitis/M
+dermatological
+dermatologist/SM
+dermatology/M
+dermis/M
+derogate/DSGN
+derogation/M
+derogatorily
+derogatory
+derrick/SM
+derriere/SM
+derringer/SM
+derrire/SM
+derv
+dervish/MS
+desalinate/GNDS
+desalination/M
+desalinization/M
+desalinize/GDS
+descant/M
+descend/FGDS
+descendant/MS
+descender
+describable/I
+describe/BZGDR
+describer/M
+description/SM
+descriptive/PY
+descriptiveness/M
+descriptor/S
+descry/GDS
+desecrate/DSGN
+desecration/M
+deselection
+desert/SDRZGM
+deserter/M
+desertification
+desertion/SM
+deserved/UY
+deserving/U
+deshabille/M
+desiccant/SM
+desiccate/DSGN
+desiccation/M
+desiccator/SM
+desiderata
+desideratum/M
+designate/DSGNX
+designated/U
+designation/M
+designee
+desirability/UM
+desirableness/M
+desirably/U
+desire/B
+desired/U
+desirous
+desist/SDG
+desk/SM
+deskill/G
+desktop/SM
+desolate/PDSYGN
+desolateness/M
+desolation/M
+despair/SMDG
+despairing/Y
+desperado/M
+desperadoes
+desperate/YNP
+desperateness/M
+desperation/M
+despicable
+despicably
+despise/DSG
+despite
+despoilment/M
+despondence/M
+despondency/M
+despondent/Y
+despotic
+despotically
+despotism/M
+dessert/SM
+dessertspoon/S
+dessertspoonful/S
+destination/SM
+destine/DSG
+destiny/SM
+destitute/N
+destitution/M
+destroy/SZGDR
+destroyer/M
+destruct/GVD
+destructibility/IM
+destructible/I
+destruction/M
+destructive/PY
+destructiveness/M
+desuetude/M
+desultorily
+desultory
+detach/BLGDS
+detachment/MS
+detain/LGDS
+detainee/MS
+detainment/M
+detect/SDGVB
+detectable/U
+detected/U
+detection/M
+detective/SM
+detector/SM
+detente/SMNX
+detention/M
+deter/SL
+detergent/SM
+deteriorate/DSGN
+deterioration/M
+determent/M
+determinable/I
+determinant/SM
+determinate
+determine/AGDS
+determined/U
+determinedly
+determiner/SM
+determinism/M
+deterministic
+deterministically
+deterred/U
+deterrence/M
+deterrent/MS
+deterring
+detestably
+detestation/M
+dethrone/DSLG
+dethronement/M
+detonate/GNDSX
+detonation/M
+detonator/SM
+detox/MDSG
+detoxification/M
+detoxify/DSGN
+detract/GD
+detriment/SM
+detrimental/Y
+detritus/M
+deuce/SM
+deuteride/S
+deuterium/M
+devastate/GNDS
+devastating/Y
+devastation/M
+devastator/MS
+develop/ASGDL
+developed/U
+developer/SM
+development/ASM
+developmental/Y
+deviance/M
+deviancy/M
+deviant/SM
+deviate/DSMGNX
+deviating/U
+deviation/M
+devil/SMDGL
+devilish/YP
+devilishness/M
+devilment/M
+devilry/SM
+deviltry/SM
+devious/YP
+deviousness/M
+devoid
+devolution/M
+devolve/DSG
+devoted/Y
+devotee/SM
+devotion/MS
+devotional/SM
+devour/SDG
+devout/PRYT
+devoutness/M
+dew/M
+dewberry/SM
+dewclaw/SM
+dewdrop/SM
+dewiness/M
+dewlap/SM
+dewy/RTP
+dexterity/M
+dexterous/YP
+dexterousness/M
+dextrose/M
+dharma
+dhoti/SM
+dhow/MS
+diabetes/M
+diabetic/SM
+diabolic
+diabolical/Y
+diacritic/MS
+diacritical
+diadem/SM
+diaereses
+diaeresis/M
+diagnose/DSG
+diagnosis/M
+diagnostic/S
+diagnostically
+diagnostician/SM
+diagnostics/M
+diagonal/SMY
+diagram/SM
+diagrammatic
+diagrammatically
+diagrammed
+diagramming
+dial/AMDGS
+dialect/SM
+dialectal
+dialectic/SM
+dialectical
+dialectics/M
+dialing/S
+dialog/SDG
+dialogue/DRSMG
+dialyses
+dialysis/M
+dialyzes
+diam
+diamagnetic
+diamagnetism
+diamante
+diamant
+diameter/SM
+diametric
+diametrical/Y
+diamond/SM
+diamondback/MS
+diapason/SM
+diaper/SMDG
+diaphanous
+diaphragm/SM
+diaphragmatic
+diarist/SM
+diarrhea/M
+diary/SM
+diaspora/SM
+diastase/M
+diastole/M
+diastolic
+diathermy/M
+diatom/SM
+diatomaceous
+diatomic
+diatonic
+diatribe/SM
+diazepam
+dibble/DSMG
+dibs/M
+dice/GDS
+dices/I
+dicey
+dichotomous
+dichotomy/SM
+dicier
+diciest
+dick/MRXZS
+dicker/DG
+dickey/SM
+dickhead/S
+dicky/SM
+dickybird/S
+dicotyledon/MS
+dicotyledonous
+dict
+dicta
+dictate/DSMGNX
+dictation/M
+dictator/SM
+dictatorial/Y
+dictatorship/SM
+diction/M
+dictionary/SM
+dictum/M
+did/AU
+didactic
+didactically
+diddle/DRSZG
+diddler/M
+diddly
+diddlysquat
+diddums
+didgeridoo/S
+didn't
+dido/MS
+didoes
+didst
+die/DSM
+diehard/SM
+dielectric/MS
+diereses
+dieresis/M
+diesel/SMDG
+diet/MDRZGS
+dietary/SM
+dieter/M
+dietetic/S
+dietetics/M
+dietician/MS
+dietitian/MS
+diff/DRZGS
+differ/DG
+difference/IM
+differences
+different/IY
+differentiable
+differential/SM
+differentiate/DSGN
+differentiated/U
+differentiation/M
+differentiator/S
+difficult/Y
+difficulty/SM
+diffidence/M
+diffident/Y
+diffract/GSD
+diffraction/M
+diffuse/DSYGNVP
+diffuseness/M
+diffusion/M
+diffusivity
+dig/SM
+digerati/M
+digest/SMDGV
+digested/U
+digestibility/M
+digestible/I
+digestion/IM
+digestions
+digestive/S
+digger/SM
+digging/S
+diggings/M
+digicam/S
+digit/SM
+digital/Y
+digitalis/M
+digitalize/DSG
+digitization
+digitize/GDS
+dignified/U
+dignify/DSG
+dignitary/SM
+dignity/ISM
+digraph/M
+digraphs
+digress/GVDS
+digression/MS
+dihydro
+dike/MGDS
+diktat/S
+dilapidated
+dilapidation/M
+dilatation/M
+dilate/DSGN
+dilation/M
+dilator/SM
+dilatory
+dildo/S
+dilemma/MS
+dilettante/SM
+dilettantish
+dilettantism/M
+diligence/M
+diligent/Y
+dill/MS
+dilly/SM
+dillydally/DSG
+diluent
+dilute/DSGNX
+diluted/U
+dilution/M
+dim/PSRY
+dime/MS
+dimension/SM
+dimensional
+dimensionless
+diminish/GDS
+diminished/U
+diminuendo/SM
+diminuendoes
+diminution/SM
+diminutive/SM
+dimity/M
+dimmed/U
+dimmer/SM
+dimmest
+dimming
+dimness/M
+dimple/DSMG
+dimply
+dimwit/SM
+dimwitted
+din/ZGSMDR
+dinar/SM
+dine/S
+diner/M
+dinette/MS
+ding/MDG
+dingbat/MS
+dingdong/SGMD
+dinghy/SM
+dingily
+dinginess/M
+dingle/SM
+dingo/M
+dingoes
+dingus/MS
+dingy/RPT
+dink/R
+dinky/RSMT
+dinned
+dinner/SMDG
+dinnertime/M
+dinnerware/M
+dinning
+dinosaur/SM
+dint/M
+diocesan/MS
+diocese/MS
+diode/SM
+diorama/SM
+dioxide/SM
+dioxin/SM
+dip/SM
+diphtheria/M
+diphthong/SM
+diploid/SM
+diploma/SM
+diplomacy/M
+diplomat/MS
+diplomata
+diplomatic/U
+diplomatically
+diplomatist/MS
+diplopia
+dipole/SM
+dipped
+dipper/SM
+dipping
+dippy/RT
+dipso/S
+dipsomania/M
+dipsomaniac/MS
+dipstick/SM
+dipterous
+diptych/M
+diptychs
+dire/YTR
+direct/ASDGVT
+directer
+direction/IM
+directional
+directionality/SM
+directionless
+directions/A
+directive/SM
+directly
+directness/IM
+director/MS
+directorate/SM
+directorial
+directorship/SM
+directory/SM
+direful
+dirge/SM
+dirigible/MS
+dirk/MS
+dirndl/SM
+dirt/M
+dirtball/S
+dirtily
+dirtiness/M
+dirty/DRSTGP
+dis/M
+disable/DSGL
+disablement/M
+disambiguate/DSGN
+disappointing/Y
+disarming/Y
+disastrous/Y
+disbandment/M
+disbarment/SM
+disbelieving/Y
+disbursal/M
+disburse/DSGL
+disbursement/MS
+disc/M
+discern/LSDG
+discernible/I
+discernibly
+discerning/Y
+discernment/M
+discharged/U
+disciple/SM
+discipleship/M
+disciplinarian/SM
+disciplinary
+discipline/DSMG
+disciplined/U
+disclose/DSBG
+disclosed/U
+disco/MG
+discography/SM
+discoloration/S
+discombobulate/DSGN
+discombobulation/M
+discomfit/DG
+discomfiture/M
+discommode/DG
+disconcerting/Y
+disconnected/PY
+disconnectedness/M
+disconsolate/Y
+discordance/M
+discordant/Y
+discotheque/SM
+discourage/LGDS
+discouragement/SM
+discouraging/Y
+discover/ABSDG
+discoverability
+discovered/U
+discoverer/MS
+discovery/ASM
+discreet/PRYT
+discreetness/M
+discrepancy/SM
+discrepant
+discrete/PYN
+discreteness/M
+discretion/IM
+discretionary
+discriminant
+discriminate/GNDS
+discriminating/U
+discrimination/M
+discriminator/MS
+discriminatory
+discursiveness/M
+discus/MS
+discussant/SM
+discussion/SM
+disdain/SMDG
+disdainful/Y
+disembowel/SDLG
+disembowelment/M
+disfigurement/SM
+disfranchisement/M
+disgorgement/M
+disgruntle/LGDS
+disgruntlement/M
+disguise/GD
+disguised/U
+disgusted/Y
+disgusting/Y
+dish/MDSG
+dishabille/M
+disharmonious
+dishcloth/M
+dishcloths
+disheartening/Y
+dishevel/DGLS
+dishevelment/M
+dishpan/SM
+dishrag/SM
+dishtowel/MS
+dishware/M
+dishwasher/MS
+dishwater/M
+dishy
+disillusion/GLD
+disillusionment/M
+disinfectant/MS
+disinfection/M
+disinterested/PY
+disinterestedness/M
+disjointed/YP
+disjointedness/M
+disjunctive
+disjuncture
+disk/MS
+diskette/MS
+dislodge/GDS
+dismal/Y
+dismantlement/M
+dismay/SMDG
+dismayed/U
+dismember/LGD
+dismemberment/M
+dismissive/Y
+disorder/Y
+disorganization/M
+disparage/DSGL
+disparagement/M
+disparaging/Y
+disparate/Y
+dispatcher/MS
+dispel/S
+dispelled
+dispelling
+dispensary/SM
+dispensation/MS
+dispense/BZGDRS
+dispenser/M
+dispersal/M
+disperse/GNDS
+dispersion/M
+dispirit/GDS
+displeasure/M
+disposable/SM
+disposal/SM
+disposed/I
+disposition/ISM
+dispossession/M
+disproof/SM
+disproportional
+disprove/B
+disputable/I
+disputably/I
+disputant/MS
+disputation/SM
+disputatious/Y
+dispute/DRSMZGB
+disputed/U
+disputer/M
+disquiet/GSMD
+disquisition/MS
+disregardful
+disrepair/M
+disrepute/MB
+disrupt/GVSD
+disruption/SM
+disruptive/Y
+dissect/SDG
+dissed
+dissemblance/M
+dissemble/ZGDRS
+dissembler/M
+disseminate/GNDS
+dissemination/M
+dissension/SM
+dissent/SMDRZG
+dissenter/M
+dissentious
+dissertation/SM
+disses
+dissidence/M
+dissident/MS
+dissimilar
+dissimilitude/S
+dissing
+dissipate/GNDS
+dissipation/M
+dissociate/GNVDS
+dissociation/M
+dissoluble/I
+dissolute/YNP
+dissoluteness/M
+dissolve/AGDS
+dissolved/U
+dissonance/SM
+dissonant
+dissuade/GDS
+dissuasive
+dist
+distaff/SM
+distal/Y
+distance/DSMG
+distant/Y
+distaste/SM
+distemper/M
+distention/SM
+distillate/SMNX
+distillation/M
+distillery/SM
+distinct/IYTVP
+distincter
+distinction/SM
+distinctive/YP
+distinctiveness/M
+distinctness/IM
+distinguish/GDSB
+distinguishable/I
+distinguished/U
+distort/GDR
+distortion/MS
+distract/DGB
+distractability
+distracted/Y
+distractible
+distraction/S
+distrait
+distraught
+distress/DG
+distressful
+distressing/Y
+distribute/AGNVDS
+distributed/U
+distribution/AM
+distributional
+distributions
+distributive/Y
+distributor's
+distributor/AS
+distributorship/S
+district's
+district/AS
+disturb/ZGSDR
+disturbance/SM
+disturbed/U
+disturber/M
+disturbing/Y
+disunion/M
+disyllabic
+ditch/MDSG
+dither/SMDRZG
+ditherer/M
+ditransitive
+ditsy
+ditto/SMDG
+dittoes
+ditty/SM
+ditz/MS
+ditzy/R
+diuretic/MS
+diurnal/Y
+div
+diva/MS
+divalent
+divan/SM
+dive/MZTGDRS
+diver/M
+diverge/DSG
+divergence/MS
+divergent
+diverse/XYNP
+diverseness/M
+diversification/M
+diversify/GNDS
+diversion/M
+diversionary
+diversity/SM
+divert/SDRZG
+diverticulitis/M
+divest/SLDG
+divestiture/MS
+divestment/M
+divide/DRSMZGB
+divided/U
+dividend/MS
+divider/M
+divination/M
+divine/DRSMYZTG
+diviner/M
+diving/M
+divinity/SM
+divisibility/IM
+divisible/I
+division/MS
+divisional
+divisive/PY
+divisiveness/M
+divisor/SM
+divorce/DSLMG
+divorcee/MS
+divorcement/MS
+divorce/MS
+divot/SM
+divulge/GDS
+divvy/DSMG
+dixieland/M
+dizygotic
+dizygous
+dizzily
+dizziness/M
+dizzy/DRSPTG
+djellaba/MS
+djellabahs
+djinn
+do/SJMRHZG
+doable
+dob/S
+dobbed
+dobbin/SM
+dobbing
+doberman/MS
+dobro
+doc/SM
+docent/SM
+docile/Y
+docility/M
+dock/MDRZGS
+docket/SMDG
+dockland/S
+dockside
+dockworker/MS
+dockyard/MS
+doctor/SMDG
+doctoral
+doctorate/MS
+doctrinaire/MS
+doctrinal
+doctrine/MS
+docudrama/SM
+document/GMDS
+documentary/SM
+documentation/SM
+documented/U
+dodder/SMDG
+doddery
+doddle
+dodge/DRSMZG
+dodgem/S
+dodger/M
+dodgy/RT
+dodo/MS
+doe/SM
+doer/M
+does/AU
+doeskin/MS
+doesn't
+doff/DGS
+dog/SM
+dogcart/SM
+dogcatcher/SM
+doge/MS
+dogear/SMDG
+dogfight/SM
+dogfish/MS
+dogged/PY
+doggedness/M
+doggerel/M
+doggie/M
+dogging
+doggone/TGDRS
+doggoned/TR
+doggy/RSMT
+doghouse/SM
+dogie/SM
+dogleg/SM
+doglegged
+doglegging
+doglike
+dogma/SM
+dogmatic
+dogmatically
+dogmatism/M
+dogmatist/SM
+dognapper
+dogsbody/S
+dogsled/S
+dogtrot/MS
+dogtrotted
+dogtrotting
+dogwood/MS
+doh/M
+doily/SM
+doing/USM
+doldrums/M
+dole's
+dole/FGDS
+doleful/YP
+dolefulness/M
+doll/MDGS
+dollar/SM
+dollhouse/SM
+dollop/SGMD
+dolly/SM
+dolmen/SM
+dolomite/M
+dolor/M
+dolorous/Y
+dolphin/MS
+dolt/MS
+doltish/YP
+doltishness/M
+domain/SM
+dome/MGDS
+domestic/SM
+domestically
+domesticate/DSGN
+domesticated/U
+domestication/M
+domesticity/M
+domicile/DSMG
+domiciliary
+dominance/M
+dominant/SMY
+dominate/DSGNV
+domination/M
+dominator
+dominatrices
+dominatrix/M
+domineer/SGD
+domineering/Y
+dominion/SM
+domino/M
+dominoes
+don't
+don/SM
+dona/MS
+donate/DSXGN
+donation/M
+donator/MS
+done/FAU
+dong/MDGS
+dongle/SM
+donkey/SM
+donned
+donning
+donnish
+donnybrook/MS
+donor/SM
+donuts
+doodad/SM
+doodah
+doodahs
+doodle/DRSMZG
+doodlebug/SM
+doodler/M
+doohickey/SM
+doolally
+doom/MDGS
+doomsayer/MS
+doomsday/M
+doomster/S
+door's
+door/IS
+doorbell/MS
+doorjamb/S
+doorkeeper/MS
+doorknob/MS
+doorknocker/S
+doorman/M
+doormat/SM
+doormen
+doorplate/SM
+doorpost/S
+doorstep/MS
+doorstepped
+doorstepping
+doorstop/MS
+doorway/SM
+dooryard/MS
+doozie
+doozy
+dopa/M
+dopamine
+dope/MZGDRS
+doper/M
+dopey
+dopier
+dopiest
+dopiness/M
+doping/M
+doppelganger/S
+doppelgnger/S
+dork/MS
+dorky/RT
+dorm/MRZS
+dormancy/M
+dormant
+dormer/M
+dormice
+dormitory/SM
+dormouse/M
+dorsal/Y
+dory/SM
+dosage/SM
+dose/MGDS
+dosh
+dosimeter/SM
+doss/DRSZG
+dosshouse/S
+dossier/MS
+dost
+dot/ZGSMDR
+dotage/M
+dotard/SM
+dotcom/SM
+dote/S
+doter/M
+doting/Y
+dotted
+dotting
+dotty/RT
+double's
+double/ADSG
+doubleheader/MS
+doublespeak/M
+doublet/MS
+doubloon/SM
+doubly
+doubt/SMDRZG
+doubter/M
+doubtful/PY
+doubtfulness/M
+doubting/Y
+doubtless/Y
+douche/DSMG
+dough/M
+doughnut/SM
+doughty/RT
+doughy/TR
+dour/RYTP
+dourness/M
+douse/DSG
+dove/MS
+dovecot/S
+dovecote/SM
+dovetail/MDSG
+dovish
+dowager/MS
+dowdily
+dowdiness/M
+dowdy/RSPT
+dowel/SMDG
+dower/SMDG
+down/MDRZGS
+downbeat/SM
+downcast
+downdraft/MS
+downer/M
+downfall/SMN
+downfield
+downgrade/DSMG
+downhearted/PY
+downheartedness/M
+downhill/MS
+download/MDBSG
+downmarket
+downplay/DSG
+downpour/MS
+downrange
+downright
+downriver
+downscale
+downshift/SGD
+downside/MS
+downsize/GDS
+downsizing/M
+downspout/MS
+downstage
+downstairs/M
+downstate/M
+downstream
+downswing/MS
+downtempo
+downtime/M
+downtown/M
+downtrend/MS
+downtrodden
+downturn/MS
+downward/S
+downwind
+downy/RT
+dowry/SM
+dowse/DRSZG
+dowser/M
+dox/GDS
+doxastic
+doxology/SM
+doxx/DSG
+doyen/SM
+doyenne/MS
+doz/XGDNS
+doze/M
+dozen/MH
+dozily
+dozy/RTP
+dpi
+dpt
+drab/MYSP
+drabber
+drabbest
+drabness/M
+drachma/MS
+draconian
+draft's
+draft/ASDG
+draftee/SM
+drafter/SM
+draftily
+draftiness/M
+drafting/M
+draftsman/M
+draftsmanship/M
+draftsmen
+draftswoman/M
+draftswomen
+drafty/RTP
+drag/MS
+dragged
+dragging
+draggy/TR
+dragnet/SM
+dragon/SM
+dragonfly/SM
+dragoon/SMDG
+dragster/S
+drain/SMDRZG
+drainage/M
+drainboard/SM
+drainer/M
+drainpipe/MS
+drake/SM
+dram/MS
+drama/SM
+dramatic/S
+dramatically
+dramatics/M
+dramatist/SM
+dramatization/SM
+dramatize/DSG
+drank
+drape/DRSMZG
+draper/M
+drapery/SM
+drastic
+drastically
+drat
+dratted
+draughtboard/S
+draw/MRZGSJ
+drawback/MS
+drawbridge/MS
+drawer/M
+drawing/M
+drawl/SMDG
+drawn/A
+drawstring/MS
+dray/MS
+dread/SMDG
+dreadful/PY
+dreadfulness/M
+dreadlocks/M
+dreadnought/MS
+dream/SMDRZG
+dreamboat/MS
+dreamed/U
+dreamer/M
+dreamily
+dreaminess/M
+dreamland/M
+dreamless
+dreamlike
+dreamworld/SM
+dreamy/RPT
+drear
+drearily
+dreariness/M
+dreary/RPT
+dreck
+dreckish
+drecky
+dredge/DRSMZG
+dredger/M
+dregs/M
+drek
+drench/GDS
+dress/AUGSDM
+dressage/M
+dresser/MS
+dressiness/M
+dressing/SM
+dressmaker/SM
+dressmaking/M
+dressy/TPR
+drew/A
+dribble/MZGDRS
+dribbler/M
+driblet/MS
+drier/M
+drift/SMDRZG
+drifter/M
+driftnet/S
+driftwood/M
+drill/SMDRZG
+driller/M
+drillmaster/SM
+drily
+drink/SMRBJZG
+drinkable/U
+drinker/M
+drip/MS
+dripped
+dripping/SM
+drippy/TR
+drive/RSMZGJ
+drivel/SZGMDR
+driveler/M
+driven
+driver/M
+driveshaft/SM
+driveway/MS
+drizzle/MGDS
+drizzly
+drogue/SM
+droid/S
+droll/RPT
+drollery/SM
+drollness/M
+drolly
+dromedary/SM
+drone/DSMG
+drool/SMDG
+droop/GSMD
+droopiness/M
+droopy/TPR
+drop/MS
+dropkick/MS
+droplet/SM
+dropout/SM
+dropped
+dropper/SM
+dropping/S
+droppings/M
+dropsical
+dropsy/M
+dross/M
+drought/SM
+drove/RSMZ
+drover/M
+drown/GSJD
+drowning/M
+drowse/MGDS
+drowsily
+drowsiness/M
+drowsy/RTP
+drub/S
+drubbed
+drubber/SM
+drubbing/MS
+drudge/MGDS
+drudgery/M
+drug/MS
+drugged
+druggie/SM
+drugging
+druggist/SM
+druggy
+drugstore/MS
+druid/SM
+druidism/M
+drum/MS
+drumbeat/SM
+drumlin/SM
+drummed
+drummer/SM
+drumming
+drumstick/SM
+drunk/STMNR
+drunkard/MS
+drunken/PY
+drunkenness/M
+drupe/SM
+druthers/M
+dry/ZTGDRSMY
+dryad/SM
+dryer/SM
+dryness/M
+drys
+drywall/M
+dual
+dualism/M
+duality/M
+dub/SM
+dubbed
+dubber/SM
+dubbin/M
+dubbing
+dubiety/M
+dubious/YP
+dubiousness/M
+ducal
+ducat/SM
+duchess/MS
+duchy/SM
+duck/MDGS
+duckbill/SM
+duckboards
+duckling/SM
+duckpins/M
+duckweed/M
+ducky/TRSM
+duct's/K
+duct/CKIFS
+ductile
+ductility/M
+ducting
+ductless
+dud/GSMD
+dude/MS
+dudgeon/M
+due's
+due/IS
+duel/MDRJZGS
+dueler/M
+duelist/SM
+duenna/MS
+duet/MS
+duff/MDRZGS
+duffel/S
+duffer/M
+dug
+dugout/MS
+duh
+duke/MS
+dukedom/SM
+dulcet
+dulcimer/MS
+dull/DRPTGS
+dullard/SM
+dullness/M
+dully
+duly/U
+dumb/DRYPT
+dumbbell/SM
+dumbfound/SDG
+dumbness/M
+dumbo/S
+dumbstruck
+dumbwaiter/SM
+dumdum/MS
+dummy/SM
+dump/MDRZGS
+dumpiness/M
+dumpling/SM
+dumpsite/S
+dumpster/SM
+dumpy/PTR
+dun/SM
+dunce/SM
+dunderhead/MS
+dune/MS
+dung/MDGS
+dungaree/MS
+dungeon/SM
+dunghill/MS
+dunk/MDGS
+dunned
+dunner
+dunnest
+dunning
+dunno
+duo/SM
+duodecimal
+duodena
+duodenal
+duodenum/M
+duopoly/S
+dupe/MZGDRS
+duper/M
+duple
+duplex/MS
+duplicate's
+duplicate/AGNVDS
+duplication/AM
+duplicator/MS
+duplicitous
+duplicity/M
+durability/M
+durable
+durably
+durance/M
+duration/M
+duress/M
+durian/SM
+during
+durst
+durum/M
+dusk/M
+duskiness/M
+dusky/RTP
+dust/MDRZGS
+dustbin/SM
+dustcart/S
+duster/M
+dustiness/M
+dustless
+dustman
+dustmen
+dustpan/SM
+dustsheet/S
+dusty/RTP
+dutch
+duteous/Y
+dutiable
+dutiful/YP
+dutifulness/M
+duty/SM
+duvet/SM
+dwarf/SGMD
+dwarfish
+dwarfism/M
+dweeb/SM
+dwell/SJZGR
+dweller/M
+dwelling/M
+dwelt/I
+dwindle/DSG
+dyad
+dyadic
+dyadically
+dybbuk/SM
+dybbukim
+dye/DRSMZG
+dyeing/A
+dyer/M
+dyestuff/M
+dying/M
+dyke/MS
+dynamic/MS
+dynamical/Y
+dynamics/M
+dynamism/M
+dynamite/MZGDRS
+dynamiter/M
+dynamo/SM
+dynastic
+dynasty/SM
+dysentery/M
+dysfunction/MS
+dysfunctional
+dyslectic/SM
+dyslexia/M
+dyslexic/SM
+dyspepsia/M
+dyspeptic/MS
+dysphagia
+dysphoria
+dysphoric
+dysprosium/M
+dystonia
+dystopi
+dystopia/S
+dystopian/S
+dz
+dbridement
+dbutante/SM
+dcolletage/SM
+dcollet
+dmod
+drailleur/MS
+dshabill/M
+dtente/M
+e'en
+e'er
+e/FDST
+eBay/M
+eBook/MS
+eCommerce/M
+eMusic/M
+ea
+each
+eager/PTRY
+eagerness/M
+eagle/MS
+eaglet/MS
+ear/SMDY
+earache/SM
+earbud/SM
+eardrum/SM
+earful/SM
+earl/MS
+earldom/SM
+earliness/M
+earlobe/SM
+early/RTP
+earmark/SMDG
+earmuff/SM
+earn/DRZTGJS
+earned/U
+earner/M
+earnest/SMYP
+earnestness/M
+earnings/M
+earphone/MS
+earpiece/S
+earplug/SM
+earring/SM
+earshot/M
+earsplitting
+earth's
+earth/UDYG
+earthbound
+earthen
+earthenware/M
+earthiness/M
+earthling/MS
+earthly/RT
+earthquake/SM
+earths/U
+earthshaking
+earthward/S
+earthwork/MS
+earthworm/MS
+earthy/RTP
+earwax/M
+earwig/SM
+ease/EDSM
+easel/SM
+easement/SM
+easily/U
+easiness/UM
+easing
+east/M
+eastbound
+easterly/SM
+eastern/ZR
+easterner/M
+easternmost
+eastward/S
+easy/URTP
+easygoing
+eat/ZGBSNR
+eatable/SM
+eaten/U
+eater/M
+eatery/SM
+eave/MS
+eavesdrop/S
+eavesdropped
+eavesdropper/SM
+eavesdropping
+ebb/SMDG
+ebony/SM
+ebullience/M
+ebullient/Y
+ebullition/M
+eccentric/SM
+eccentrically
+eccentricity/SM
+eccl
+ecclesial
+ecclesiastic/SM
+ecclesiastical/Y
+echelon/SM
+echidna
+echinoderm/SM
+echo's
+echo/ADG
+echoes/A
+echoic
+echolocation/M
+echos
+eclair/SM
+eclat/M
+eclectic/SM
+eclectically
+eclecticism/M
+eclipse/DSMG
+ecliptic/M
+eclogue/SM
+ecocide/M
+ecol
+ecologic
+ecological/Y
+ecologist/MS
+ecology/M
+econ
+econometric/S
+economic/S
+economical/UY
+economics/M
+economist/SM
+economize/DRSZG
+economizer/M
+economy/SM
+ecosystem/MS
+ecotourism/M
+ecotourist/MS
+ecru/M
+ecstasy/SM
+ecstatic
+ecstatically
+ectopic
+ectopically
+ecu/S
+ecumenical/Y
+ecumenicism/M
+ecumenism/M
+eczema/M
+ed/ACSM
+edamame
+eddy/DSMG
+edelweiss/M
+edema/SM
+edge/MZGJDRS
+edger/M
+edgeways
+edgewise
+edgily
+edginess/M
+edging/M
+edgy/RTP
+edibility/M
+edible/SMP
+edibleness/M
+edict/SM
+edification/M
+edifice/SM
+edifier/M
+edify/DRSZGN
+edifying/U
+edit's
+edit/ADGS
+editable
+edited/U
+edition/MS
+editor/SM
+editorial/SMY
+editorialize/DSG
+editorship/M
+educ
+educability/M
+educable/I
+educate/ADSGNV
+educated/U
+education/AM
+educational/Y
+educationalist/S
+educationist/S
+educations
+educator/MS
+educe/DSGB
+edutainment/M
+eek
+eel/SM
+eerie/RT
+eerily
+eeriness/M
+eff/GSD
+efface/DSLG
+effacement/M
+effect/SMDGV
+effective/IPY
+effectiveness/IM
+effectual/IY
+effectuate/DSG
+effeminacy/M
+effeminate/Y
+effendi/SM
+efferent
+effervesce/GDS
+effervescence/M
+effervescent/Y
+effete/YP
+effeteness/M
+efficacious/Y
+efficacy/IM
+efficiency/ISM
+efficient/IY
+effigy/SM
+efflorescence/M
+efflorescent
+effluence/M
+effluent/MS
+effluvia
+effluvium/M
+efflux
+effort/SM
+effortful
+effortless/YP
+effortlessness/M
+effrontery/M
+effulgence/M
+effulgent
+effuse/DSGNVX
+effusion/M
+effusive/YP
+effusiveness/M
+egad/S
+egalitarian/SM
+egalitarianism/M
+egg/GSMD
+eggbeater/MS
+eggcup/SM
+egghead/SM
+eggnog/M
+eggplant/MS
+eggshell/SM
+eglantine/SM
+ego/SM
+egocentric/MS
+egocentrically
+egocentricity/M
+egoism/M
+egoist/SM
+egoistic
+egoistical/Y
+egomania/M
+egomaniac/MS
+egotism/M
+egotist/SM
+egotistic
+egotistical/Y
+egregious/PY
+egregiousness/M
+egress/MS
+egret/SM
+eh
+eider/SM
+eiderdown/MS
+eigenvalue/S
+eigenvector/S
+eight/SM
+eighteen/MHS
+eighteenth/M
+eighteenths
+eighth/M
+eighths
+eightieth/M
+eightieths
+eighty/SMH
+einsteinium/M
+eisteddfod/S
+either
+ejaculate/GNXDS
+ejaculation/M
+ejaculatory
+eject/SDG
+ejection/MS
+ejector/SM
+eke/DSG
+elaborate/YGNDSPX
+elaborateness/M
+elaboration/M
+elan/M
+eland/SM
+elapse/DSG
+elastic/MS
+elastically
+elasticated
+elasticity/M
+elasticize/DSG
+elate/DSGN
+elated/Y
+elation/M
+elbow/SMDG
+elbowroom/M
+elder/SMY
+elderberry/SM
+eldercare/M
+eldest
+eldritch
+elect's
+elect/ASDGV
+electable
+election/AMS
+electioneer/DGS
+elective/MS
+elector/MS
+electoral/Y
+electorate/MS
+electric/S
+electrical/Y
+electrician/MS
+electricity/M
+electrification/M
+electrifier/M
+electrify/ZGNDRS
+electrocardiogram/MS
+electrocardiograph/M
+electrocardiographs
+electrocardiography/M
+electrocute/DSXGN
+electrocution/M
+electrode/SM
+electrodynamics
+electroencephalogram/MS
+electroencephalograph/M
+electroencephalographic
+electroencephalographs
+electroencephalography/M
+electrologist/SM
+electrolysis/M
+electrolyte/MS
+electrolytic
+electromagnet/MS
+electromagnetic
+electromagnetically
+electromagnetism/M
+electromotive
+electron/MS
+electronic/S
+electronica/M
+electronically
+electronics/M
+electroplate/DSG
+electroscope/SM
+electroscopic
+electroshock/M
+electrostatic/S
+electrostatics/M
+electrotype/MS
+electroweak
+eleemosynary
+elegance/IM
+elegant/IY
+elegiac/MS
+elegiacal
+elegy/SM
+elem
+element/MS
+elemental/Y
+elementary
+elephant/SM
+elephantiasis/M
+elephantine
+elev
+elevate/XDSGN
+elevation/M
+elevator/MS
+eleven/SMH
+elevens/S
+eleventh/M
+elevenths
+elf/M
+elfin
+elfish
+elicit/SDG
+elicitation/M
+elicitor/MS
+elide/DSG
+eligibility/IM
+eligible
+eliminate/XDSGN
+elimination/M
+eliminator/S
+elision/MS
+elite/SM
+elitism/M
+elitist/MS
+elixir/SM
+elk/SM
+ell/SM
+ellipse/MS
+ellipsis/M
+ellipsoid/SM
+ellipsoidal
+elliptic
+elliptical/Y
+elm/SM
+elocution/M
+elocutionary
+elocutionist/SM
+elodea/SM
+elongate/DSGNX
+elongation/M
+elope/DSGL
+elopement/MS
+eloquence/M
+eloquent/Y
+else/M
+elsewhere
+elucidate/DSGNX
+elucidation/M
+elude/DSG
+elusive/YP
+elusiveness/M
+elver/SM
+elves
+elvish
+em's
+em/S
+emaciate/GNDS
+emaciation/M
+email/SMDG
+emanate/XDSGN
+emanation/M
+emancipate/DSGN
+emancipation/M
+emancipator/MS
+emasculate/GNDS
+emasculation/M
+embalm/SZGDR
+embalmer/M
+embank/SLGD
+embankment/SM
+embargo/MDG
+embargoes
+embark/AEGDS
+embarkation/EM
+embarkations
+embarrass/GLDS
+embarrassed/U
+embarrassing/Y
+embarrassment/SM
+embassy/SM
+embattled
+embattlement/SM
+embed/S
+embedded
+embedding
+embellish/LGDS
+embellishment/SM
+ember/SM
+embezzle/ZGLDRS
+embezzlement/M
+embezzler/M
+embiggen
+embitter/GLDS
+embitterment/M
+emblazon/GDLS
+emblazonment/M
+emblem/SM
+emblematic
+emblematically
+embodiment/EM
+embody/AEGSD
+embolden/DGS
+embolism/MS
+embolization
+emboss/DRSZG
+embosser/M
+embouchure/M
+embower/SGD
+embrace/DSMG
+embraceable
+embrasure/MS
+embrocation/MS
+embroider/SDRZG
+embroiderer/M
+embroidery/SM
+embroil/DGLS
+embroilment/M
+embryo/SM
+embryological
+embryologist/MS
+embryology/M
+embryonic
+emcee/DSM
+emceeing
+emend/SDG
+emendation/MS
+emerald/MS
+emerge/ADSG
+emergence/AM
+emergency/SM
+emergent
+emerita
+emeritus
+emery/M
+emetic/SM
+emf/S
+emigrant/SM
+emigrate/DSXGN
+emigration/M
+emigre/SM
+eminence/MS
+eminent/Y
+emir/MS
+emirate/MS
+emissary/SM
+emission/SM
+emit/S
+emitted
+emitter/MS
+emitting
+emo/SM
+emoji/SM
+emollient/MS
+emolument/MS
+emote/XDSGNV
+emoticon/SM
+emotion/M
+emotional/UY
+emotionalism/M
+emotionalize/GDS
+emotionless
+emotive/Y
+empanel/GDS
+empathetic
+empathic
+empathically
+empathize/DSG
+empathy/M
+emperor/MS
+emphases
+emphasis/M
+emphasize/AGDS
+emphatic/U
+emphatically
+emphysema/M
+empire/SM
+empiric
+empirical/Y
+empiricism/M
+empiricist/SM
+emplace/LGDS
+emplacement/SM
+employ's
+employ/ADGLS
+employable/U
+employee/SM
+employer/SM
+employment/UAM
+employments
+emporium/SM
+empower/SDGL
+empowerment/M
+empress/MS
+emptily
+emptiness/M
+empty/TGPDRSM
+empyrean/M
+emu/SM
+emulate/DSGNVX
+emulation/M
+emulator/SM
+emulsification/M
+emulsifier/M
+emulsify/NDRSZG
+emulsion/MS
+en/SM
+enable/DRSZG
+enabler/M
+enact/ASLDG
+enactment/ASM
+enamel/JSZGMDR
+enameler/M
+enamelware/M
+enamor/SGD
+enc
+encamp/LSGD
+encampment/MS
+encapsulate/XGNDS
+encapsulation/M
+encase/LDSG
+encasement/M
+encephalitic
+encephalitis/M
+enchain/DGS
+enchant/ELDGS
+enchanter/MS
+enchanting/Y
+enchantment/EM
+enchantments
+enchantress/MS
+enchilada/SM
+encipher/SGD
+encircle/DSGL
+encirclement/M
+encl
+enclave/MS
+enclose/GDS
+enclosed/U
+enclosure/SM
+encode/DRSJZG
+encoder/M
+encomium/MS
+encompass/GDS
+encore/DSMG
+encounter/GSMD
+encourage/DSLG
+encouragement/SM
+encouraging/Y
+encroach/GLDS
+encroachment/SM
+encrust/DGS
+encrustation/SM
+encrypt/DGS
+encrypted/U
+encryption
+encumber/EGSD
+encumbered/U
+encumbrance/MS
+ency
+encyclical/SM
+encyclopaedia
+encyclopedia/MS
+encyclopedic
+encyclopedist/MS
+encyst/LSGD
+encystment/M
+end/GVSJMD
+endanger/SGDL
+endangerment/M
+endear/SGLD
+endearing/Y
+endearment/SM
+endeavor/GSMD
+endemic/MS
+endemically
+endgame/S
+ending/M
+endive/SM
+endless/PY
+endlessness/M
+endmost
+endocarditis
+endocrine/MS
+endocrinologist/MS
+endocrinology/M
+endogenous/Y
+endometrial
+endometriosis
+endometrium
+endorphin/MS
+endorse/LZGDRS
+endorsement/MS
+endorser/M
+endoscope/MS
+endoscopic
+endoscopy/M
+endothelial
+endothermic
+endotracheal
+endow/SDLG
+endowment/MS
+endpoint/SM
+endue/DSG
+endurable/U
+endurance/M
+endure/DSBG
+endways
+enema/SM
+enemy/SM
+energetic
+energetically
+energize/ZGDRS
+energizer/M
+energy/SM
+enervate/GNDS
+enervation/M
+enfeeble/GDSL
+enfeeblement/M
+enfilade/DSMG
+enfold/SGD
+enforce/LZGDRS
+enforceable/U
+enforced/U
+enforcement/M
+enforcer/M
+enfranchise/EGDSL
+enfranchisement/EM
+engage/EADSG
+engagement/EMS
+engagingly
+engender/SGD
+engine/SM
+engineer/MDGS
+engineering/M
+engorge/LGDS
+engorgement/M
+engram/SM
+engrave/ZGJDRS
+engraver/M
+engraving/M
+engross/GLDS
+engrossment/M
+engulf/SLGD
+engulfment/M
+enhance/LZGDRS
+enhancement/SM
+enigma/SM
+enigmatic
+enigmatically
+enjambment/SM
+enjoin/SGD
+enjoy/GBLSD
+enjoyably
+enjoyment/SM
+enlarge/LZGDRS
+enlargeable
+enlargement/MS
+enlarger/M
+enlighten/SGLD
+enlightened/U
+enlightenment/M
+enlist/ADGSL
+enlistee/SM
+enlistment/AM
+enlistments
+enliven/SLDG
+enlivenment/M
+enmesh/DSGL
+enmeshment/M
+enmity/SM
+ennoble/DSGL
+ennoblement/M
+ennui/M
+enormity/SM
+enormous/PY
+enormousness/M
+enough/M
+enplane/DSG
+enqueue/DSG
+enquirer/S
+enquiringly
+enrage/GDS
+enrapture/DSG
+enrich/DSLG
+enrichment/M
+enroll/DLSG
+enrollment/MS
+ensconce/DSG
+ensemble/SM
+enshrine/GLDS
+enshrinement/M
+enshroud/DGS
+ensign/MS
+ensilage/M
+enslave/DSGL
+enslavement/M
+ensnare/DSLG
+ensnarement/M
+ensue/DSG
+ensure/ZGDRS
+ensurer/M
+entail/DSGL
+entailment/M
+entangle/EDSLG
+entanglement/EM
+entanglements
+entente/SM
+enter/ASGD
+enteral
+enteric
+enteritis/M
+enterprise/MGS
+enterprising/Y
+entertain/ZGDRSL
+entertainer/M
+entertaining/MY
+entertainment/MS
+enthrall/GDSL
+enthrallment/M
+enthrone/GDSL
+enthronement/SM
+enthuse/DSG
+enthusiasm/MS
+enthusiast/MS
+enthusiastic/U
+enthusiastically
+entice/GDSL
+enticement/MS
+enticing/Y
+entire/Y
+entirety/M
+entitle/DSGL
+entitlement/SM
+entity/SM
+entomb/DSGL
+entombment/M
+entomological
+entomologist/MS
+entomology/M
+entourage/SM
+entr'acte
+entrails/M
+entrained
+entrance/LDSMG
+entrancement/M
+entrancing/Y
+entrant/SM
+entrap/LS
+entrapment/M
+entrapped
+entrapping
+entreat/GSD
+entreating/Y
+entreaty/SM
+entree/MS
+entrench/DSGL
+entrenchment/MS
+entrepreneur/SM
+entrepreneurial
+entrepreneurship
+entropy/M
+entrust/SGD
+entry/ASM
+entryphone/S
+entryway/MS
+entre/MS
+entwine/DSG
+enumerable
+enumerate/DSGNX
+enumeration/M
+enumerator/SM
+enunciate/DSGN
+enunciation/M
+enure/DSG
+enuresis/M
+envelop/SLDRZG
+envelope/SM
+enveloper/M
+envelopment/M
+envenom/SDG
+enviable/U
+enviably
+envious/PY
+enviousness/M
+environment/MS
+environmental/Y
+environmentalism/M
+environmentalist/SM
+environs/M
+envisage/GDS
+envision/DGS
+envoy/SM
+envy/DSMG
+envying/Y
+enzymatic
+enzyme/SM
+eolian
+eon/SM
+eosinophil/S
+eosinophilic
+epaulet/SM
+epee/MS
+ephedrine/M
+ephemera/M
+ephemeral/Y
+epic/MS
+epical/Y
+epicenter/MS
+epicure/SM
+epicurean/MS
+epicycle
+epidemic/SM
+epidemically
+epidemiological
+epidemiologist/SM
+epidemiology/M
+epidermal
+epidermic
+epidermis/MS
+epidural/S
+epiglottis/MS
+epigram/SM
+epigrammatic
+epigraph/M
+epigraphs
+epigraphy/M
+epilepsy/M
+epileptic/SM
+epilogue/MS
+epinephrine/M
+epiphany/SM
+episcopacy/M
+episcopal
+episcopate/M
+episode/SM
+episodic
+episodically
+epistemic
+epistemological
+epistemology
+epistle/SM
+epistolary
+epitaph/M
+epitaphs
+epithelial
+epithelium/M
+epithet/SM
+epitome/SM
+epitomize/GDS
+epoch/M
+epochal
+epochs
+eponymous
+epoxy/DSMG
+epsilon/SM
+equability/M
+equable
+equably
+equal/SMDYG
+equality/IM
+equalization/M
+equalize/ZGDRS
+equalizer/M
+equanimity/M
+equate/DSGNBX
+equation/M
+equator/SM
+equatorial
+equerry/SM
+equestrian/SM
+equestrianism/M
+equestrienne/SM
+equidistant/Y
+equilateral/SM
+equilibrium/EM
+equine/SM
+equinoctial
+equinox/MS
+equip/AS
+equipage/MS
+equipment/M
+equipoise/M
+equipped/UA
+equipping/A
+equitable/I
+equitably/I
+equitation/M
+equity/ISM
+equiv
+equivalence/MS
+equivalency/SM
+equivalent/MYS
+equivocal/UY
+equivocalness/M
+equivocate/GNXDS
+equivocation/M
+equivocator/SM
+er/C
+era/SM
+eradicable/I
+eradicate/DSGN
+eradication/M
+eradicator/MS
+erase/DRSBZG
+eraser/M
+erasure/SM
+erbium/M
+ere
+erect/PSGDY
+erectile
+erection/SM
+erectness/M
+erector/MS
+erelong
+eremite/MS
+erg/SM
+ergo
+ergodic
+ergodicity
+ergonomic/S
+ergonomically
+ergonomics/M
+ergosterol/M
+ergot/M
+ermine/SM
+erode/DSG
+erodible
+erogenous
+erosion/M
+erosive
+erotic/S
+erotica/M
+erotically
+eroticism/M
+err/GSD
+errand/SM
+errant/I
+errata/SM
+erratic
+erratically
+erratum/M
+erroneous/Y
+error/SM
+ersatz/MS
+erst
+erstwhile
+eruct/SDG
+eructation/SM
+erudite/YN
+erudition/M
+erupt/SDGV
+eruption/MS
+erysipelas/M
+erythrocyte/SM
+erythromycin
+escalate/CDSGN
+escalation/CM
+escalations
+escalator/MS
+escallop/SGMD
+escalope/S
+escapade/MS
+escape/LMGDS
+escapee/MS
+escapement/SM
+escapism/M
+escapist/MS
+escapologist/S
+escapology
+escargot/MS
+escarole/MS
+escarpment/MS
+eschatological
+eschatologist/SM
+eschatology
+eschew/SDG
+escort/SMDG
+escritoire/MS
+escrow/SM
+escudo/SM
+escutcheon/SM
+esophageal
+esophagi
+esophagus/MS
+esoteric
+esoterically
+esp
+espadrille/MS
+espalier/MDSG
+especial/Y
+espionage/M
+esplanade/MS
+espousal/M
+espouse/GDS
+espresso/MS
+esprit/M
+espy/DSG
+esquire/SM
+essay/SMDRZG
+essayer/M
+essayist/SM
+essence/SM
+essential/IMS
+essentially
+establish/AESDGL
+establishment/AEM
+establishments
+estate/SM
+esteem/ESMDG
+ester/SM
+esthetic/S
+estimable/I
+estimate/MGNDSX
+estimation/M
+estimator/SM
+estoppel
+estradiol
+estrange/LDSG
+estrangement/MS
+estrogen/MS
+estrous
+estrus/MS
+estuary/SM
+et
+eta/SM
+etc
+etch/DRSZGJ
+etcher/M
+etching/M
+eternal/YP
+eternalness/M
+eternity/SM
+ethane/M
+ethanol/M
+ether/M
+ethereal/Y
+ethic/SM
+ethical/UY
+ethicist/SM
+ethics/M
+ethmoid
+ethnic/SM
+ethnically
+ethnicity/M
+ethnocentric
+ethnocentrism/M
+ethnographer/S
+ethnographic
+ethnographically
+ethnography
+ethnological/Y
+ethnologist/SM
+ethnology/M
+ethological
+ethologist/MS
+ethology/M
+ethos/M
+ethyl/M
+ethylene/M
+etiolated
+etiologic
+etiological
+etiology/SM
+etiquette/M
+etude/SM
+etymological/Y
+etymologist/SM
+etymology/SM
+eucalypti
+eucalyptus/MS
+eucaryote/SM
+eucaryotic
+euchre/DSMG
+euclidean
+eugenic/S
+eugenically
+eugenicist/MS
+eugenics/M
+eukaryote/SM
+eukaryotic
+eulogist/MS
+eulogistic
+eulogize/ZGDRS
+eulogizer/M
+eulogy/SM
+eunuch/M
+eunuchs
+euphemism/SM
+euphemistic
+euphemistically
+euphonious/Y
+euphony/M
+euphoria/M
+euphoric
+euphorically
+eureka
+euro/MS
+europium/M
+eutectic
+euthanasia/M
+euthanize/DSG
+euthenics/M
+eutrophic
+eutrophication
+evacuate/XDSGN
+evacuation/M
+evacuee/MS
+evade/DRSZG
+evader/M
+evaluate/AGNVDSX
+evaluation/AM
+evaluator/S
+evanescence/M
+evanescent
+evangelic
+evangelical/SMY
+evangelicalism/M
+evangelism/M
+evangelist/MS
+evangelistic
+evangelize/GDS
+evaporate/GNDS
+evaporation/M
+evaporator/SM
+evasion/SM
+evasive/YP
+evasiveness/M
+eve/ASM
+even/MDRYTGSJP
+evenhanded/Y
+evening/M
+evenness/UM
+evensong/M
+event/SM
+eventful/UY
+eventfulness/M
+eventide/M
+eventual/Y
+eventuality/SM
+eventuate/GDS
+ever
+everglade/SM
+evergreen/SM
+everlasting/MYS
+evermore
+every
+everybody/M
+everyday
+everyone/M
+everyplace
+everything/M
+everywhere
+evict/SDG
+eviction/MS
+evidence/MGDS
+evident/Y
+evidential/Y
+evidentiality
+evidentiary
+evil/MRYTSP
+evildoer/SM
+evildoing/M
+eviller
+evillest
+evilness/M
+evince/DSG
+eviscerate/DSGN
+evisceration/M
+evocation/MS
+evocative/Y
+evoke/DSG
+evolution/M
+evolutionary
+evolutionist/SM
+evolve/DSG
+ewe/RSMZ
+ewer/M
+ex/MS
+exabyte/MS
+exacerbate/GNDS
+exacerbation/M
+exact/SBPDRYTG
+exacta/S
+exacting/PY
+exaction/SM
+exactitude/M
+exactness/IM
+exactor/MS
+exaggerate/XDSGN
+exaggerated/Y
+exaggeration/M
+exaggerator/MS
+exajoule/S
+exalt/SDG
+exaltation/M
+exam/MS
+examination/AMS
+examine/AGDS
+examined/U
+examiner/MS
+example/MGDS
+exampled/U
+exasperate/DSGN
+exasperated/Y
+exasperating/Y
+exasperation/M
+exbibyte/MS
+excavate/GNDSX
+excavation/M
+excavator/SM
+exceed/GSD
+exceeding/Y
+excel/S
+excelled
+excellence/M
+excellency/SM
+excellent/Y
+excelling
+excelsior/M
+except/GSD
+exception/BSM
+exceptionable/U
+exceptional/UY
+exceptionalism
+excerpt/MDGS
+excess/VMS
+excessive/Y
+exchange/DSMG
+exchangeable
+exchequer/SM
+excise/XDSMGN
+excision/M
+excitability/M
+excitably
+excitation/M
+excite/BDRSLZG
+excited/Y
+excitement/SM
+exciter/M
+exciting/Y
+exciton
+excl
+exclaim/DGS
+exclamation/SM
+exclamatory
+exclude/GDS
+exclusion/MS
+exclusionary
+exclusive/PMYS
+exclusiveness/M
+exclusivity/M
+excommunicate/GNDSX
+excommunication/M
+excoriate/DSGNX
+excoriation/M
+excrement/M
+excremental
+excrescence/MS
+excrescent
+excreta/M
+excrete/XGNDS
+excretion/M
+excretory
+excruciating/Y
+exculpate/DSGN
+exculpation/M
+exculpatory
+excursion/MS
+excursionist/MS
+excursive/YP
+excursiveness/M
+excusable/I
+excusably/I
+excuse/DSBMG
+excused/U
+exec/MS
+execrable
+execrably
+execrate/DSGN
+execration/M
+execute/BXGNVDS
+execution/ZMR
+executioner/M
+executive/SM
+executor/MS
+executrices
+executrix/M
+exegeses
+exegesis/M
+exegetic
+exegetical
+exemplar/SM
+exemplary
+exemplification/M
+exemplify/GDSXN
+exempt/SGD
+exemption/SM
+exercise/DRSMZG
+exerciser/M
+exert/SDG
+exertion/MS
+exeunt
+exfiltrate/GNXDS
+exfoliate/GNDS
+exhalation/MS
+exhale/DSG
+exhaust/GVMDS
+exhaustible/I
+exhaustion/M
+exhaustive/YP
+exhaustiveness/M
+exhibit/GMDS
+exhibition/MS
+exhibitionism/M
+exhibitionist/MS
+exhibitor/SM
+exhilarate/DSGN
+exhilaration/M
+exhort/SDG
+exhortation/MS
+exhumation/MS
+exhume/DSG
+exigence/MS
+exigency/SM
+exigent
+exiguity/M
+exiguous
+exile/DSMG
+exilic
+exist/SDG
+existence/MS
+existent
+existential/Y
+existentialism/M
+existentialist/MS
+exit/MDGS
+exobiology/M
+exodus/MS
+exogenous
+exon/MS
+exonerate/GNDSX
+exoneration/M
+exoplanet/MS
+exorbitance/M
+exorbitant/Y
+exorcise/DSG
+exorcism/SM
+exorcist/SM
+exoskeleton/SM
+exosphere/SM
+exothermic
+exotic/SM
+exotica
+exotically
+exoticism/M
+exp
+expand/BGSD
+expanse/XMNVS
+expansible
+expansion/M
+expansionary
+expansionism/M
+expansionist/MS
+expansive/YP
+expansiveness/M
+expat/S
+expatiate/GNDS
+expatiation/M
+expatriate/DSMGN
+expatriation/M
+expect/GSD
+expectancy/M
+expectant/Y
+expectation/SM
+expectorant/SM
+expectorate/DSGN
+expectoration/M
+expedience/IM
+expediences
+expediencies
+expediency/IM
+expedient/SMY
+expedite/DRSZGNX
+expediter/M
+expedition/M
+expeditionary
+expeditious/PY
+expeditiousness/M
+expel/S
+expelled
+expelling
+expend/GSBD
+expendable/SM
+expenditure/SM
+expense/MS
+expensive/IYP
+expensiveness/IM
+experience/IMD
+experiences
+experiencing
+experiential
+experiment/MDRSZG
+experimental/Y
+experimentalism
+experimentalist
+experimentation/M
+experimenter/M
+expert/SPMY
+expertise/M
+expertness/M
+expiate/GNDS
+expiation/M
+expiatory
+expiration/M
+expire/DSG
+expired/U
+expiry/M
+explain/ADGS
+explainable/U
+explained/U
+explainer/S
+explanation/MS
+explanatory
+expletive/MS
+explicable/I
+explicate/XGNDS
+explication/M
+explicit/PY
+explicitness/M
+explode/GDS
+exploded/U
+exploit/ZGVBMDRS
+exploitation/M
+exploitative
+exploited/U
+exploiter/M
+exploration/MS
+explorative
+exploratory
+explore/ZGDRS
+explored/U
+explorer/M
+explosion/SM
+explosive/SPMY
+explosiveness/M
+expo/MS
+exponent/MS
+exponential/Y
+exponentiation
+export/BSZGMDR
+exportation/M
+exporter/M
+expose/DSMG
+exposed/U
+exposition/SM
+expositor/SM
+expository
+expostulate/GNXDS
+expostulation/M
+exposure/MS
+expos
+expound/ZGDRS
+expounder/M
+express/GVMDSY
+expressed/U
+expressible/I
+expression/SM
+expressionism/M
+expressionist/SM
+expressionistic
+expressionless/Y
+expressive/PY
+expressiveness/M
+expressway/SM
+expropriate/GNXDS
+expropriation/M
+expropriator/SM
+expulsion/MS
+expunction
+expunge/LGDS
+expungement/S
+expurgate/DSGNX
+expurgated/U
+expurgation/M
+exquisite/YP
+exquisiteness/M
+ext
+extant
+extemporaneous/PY
+extemporaneousness/M
+extempore
+extemporization/M
+extemporize/GDS
+extend/SZGDRB
+extender/M
+extendible
+extensibility
+extensible
+extension/SM
+extensional
+extensive/YP
+extensiveness/M
+extensor/MS
+extent/SM
+extenuate/DSGN
+extenuation/M
+exterior/MS
+exterminate/DSXGN
+extermination/M
+exterminator/MS
+external/MYS
+externalization/SM
+externalize/DSG
+extinct/GDS
+extinction/MS
+extinguish/ZGBDRS
+extinguishable/I
+extinguisher/M
+extirpate/GNDS
+extirpation/M
+extol/S
+extolled
+extolling
+extort/SGD
+extortion/MRZ
+extortionary
+extortionate/Y
+extortioner/M
+extortionist/MS
+extra/SM
+extracellular
+extract/MDGVS
+extraction/SM
+extractor/MS
+extracurricular
+extradite/GNBXDS
+extradition/M
+extrajudicial
+extralegal
+extramarital
+extramural
+extraneous/Y
+extraordinaire
+extraordinarily
+extraordinary
+extrapolate/XGNDS
+extrapolation/M
+extrasensory
+extraterrestrial/MS
+extraterritorial
+extraterritoriality/M
+extravagance/MS
+extravagant/Y
+extravaganza/MS
+extravehicular
+extrema
+extreme/PMYTRS
+extremeness/M
+extremism/M
+extremist/MS
+extremity/SM
+extremum/S
+extricable/I
+extricate/GNDS
+extrication/M
+extrinsic
+extrinsically
+extroversion/M
+extrovert/SMD
+extrude/GDS
+extrusion/SM
+extrusive
+exuberance/M
+exuberant/Y
+exudation/M
+exude/DSG
+exult/SDG
+exultant/Y
+exultation/M
+exurb/SM
+exurban
+exurbanite/SM
+exurbia/M
+eye/DSMG
+eyeball/GMDS
+eyebrow/SM
+eyedropper/SM
+eyeful/SM
+eyeglass/MS
+eyeing
+eyelash/MS
+eyeless
+eyelet/SM
+eyelid/SM
+eyeliner/MS
+eyeopener/MS
+eyeopening
+eyepiece/MS
+eyesight/M
+eyesore/MS
+eyestrain/M
+eyeteeth
+eyetooth/M
+eyewash/M
+eyewitness/MS
+f/CIAVTR
+fMRI
+fa/M
+fab
+fable/DSM
+fabric/SM
+fabricate/DSGNX
+fabrication/M
+fabricator/SM
+fabulous/Y
+facade/SM
+face's
+face/ACSDG
+facecloth/M
+facecloths
+faceless
+facelift/SM
+facepalm/SDG
+facet/SMDG
+facetious/YP
+facetiousness/M
+facial/SMY
+facile/Y
+facilitate/GNDS
+facilitation/M
+facilitator/MS
+facility/SM
+facing/SM
+facsimile/DSM
+facsimileing
+fact/MS
+faction/SM
+factional
+factionalism/M
+factious
+factitious
+facto
+factoid/SM
+factor's
+factor/ASDG
+factorial/MS
+factorization
+factorize/GDS
+factory/SM
+factotum/SM
+factual/Y
+faculty/SM
+fad/GSMD
+faddish/P
+faddist/MS
+faddy/P
+fade/MS
+fading/U
+faerie/SM
+faff/DGS
+fag/SM
+fagged
+fagging
+faggot/SMG
+fagot/SMG
+faience/M
+fail/DGJS
+failing/M
+faille/M
+failure/SM
+fain/RT
+faint/SMDRYTGP
+fainthearted
+faintness/M
+fair/MRYTGJPS
+fairground/MS
+fairing/M
+fairness/UM
+fairway/SM
+fairy/SM
+fairyland/SM
+faith/M
+faithful's
+faithful/UPY
+faithfulness/UM
+faithfuls
+faithless/PY
+faithlessness/M
+faiths
+fajita/SM
+fajitas/M
+fake/MZGDRS
+faker/M
+fakir/SM
+falcon/SMRZ
+falconer/M
+falconry/M
+fall/MNGS
+fallacious/Y
+fallacy/SM
+fallback
+fallibility/IM
+fallible/P
+fallibleness/M
+fallibly/I
+falloff/SM
+fallout/M
+fallow/SMDG
+false/PRYT
+falsehood/SM
+falseness/M
+falsetto/SM
+falsie/SM
+falsifiable/U
+falsification/M
+falsifier/M
+falsify/DRSZGNX
+falsity/SM
+falter/GSJMD
+faltering/Y
+fame's
+fame/D
+familial
+familiar/MYS
+familiarity/UM
+familiarization/M
+familiarize/GDS
+family/SM
+famine/SM
+famish/DSG
+famous/IY
+fan/SM
+fanatic/SM
+fanatical/Y
+fanaticism/M
+fanboy/SM
+fanciable
+fancier/M
+fanciful/YP
+fancifulness/M
+fancily
+fanciness/M
+fancy/DRSMZTGP
+fancywork/M
+fandango/MS
+fandom
+fanfare/SM
+fang/MDS
+fanlight/SM
+fanned
+fanning
+fanny/SM
+fantail/MS
+fantasia/SM
+fantasist/S
+fantasize/GDS
+fantastic
+fantastical/Y
+fantasy/DSMG
+fanzine/MS
+far
+farad/SM
+faradize/DG
+faraway
+farce/SM
+farcical/Y
+fare/MGDS
+farewell/SM
+farfetched
+farina/M
+farinaceous
+farm/MDRZGSJ
+farmer/M
+farmhand/SM
+farmhouse/SM
+farming/M
+farmland/MS
+farmstead/MS
+farmyard/MS
+faro/M
+farrago/M
+farragoes
+farrier/MS
+farrow/SMDG
+farseeing
+farsighted/P
+farsightedness/M
+fart/MDGS
+farther
+farthermost
+farthest
+farthing/SM
+fascia/SM
+fascicle/SM
+fascinate/GNDSX
+fascinating/Y
+fascination/M
+fascism/M
+fascist/MS
+fascistic
+fashion/ZGBMDRS
+fashionable/U
+fashionably/U
+fashioner/M
+fashionista/MS
+fast/MDRTGSP
+fastback/SM
+fastball/SM
+fasten/UAGDS
+fastener/SM
+fastening/MS
+fastidious/PY
+fastidiousness/M
+fastness/MS
+fat/GSPMD
+fatal/Y
+fatalism/M
+fatalist/SM
+fatalistic
+fatalistically
+fatality/SM
+fatback/M
+fate/MS
+fateful/YP
+fatefulness/M
+fathead/MDS
+father/SGMDY
+fatherhood/M
+fatherland/MS
+fatherless
+fathom/SMDGB
+fathomable/U
+fathomless
+fatigue/MDSG
+fatigues/M
+fatness/M
+fatso/S
+fatten/SDG
+fatter
+fattest
+fattiness/M
+fatty/RSMTP
+fatuity/M
+fatuous/YP
+fatuousness/M
+fatwa/SM
+faucet/SM
+fault/CSMDG
+faultfinder/SM
+faultfinding/M
+faultily
+faultiness/M
+faultless/PY
+faultlessness/M
+faulty/PRT
+faun/MS
+fauna/SM
+fauvism/M
+fauvist/SM
+faux
+fav/S
+fave/S
+favor/ESMDG
+favorable/U
+favorably/U
+favorite/SM
+favoritism/M
+fawn/MDRZGS
+fawner/M
+fax/GMDS
+fay/TSMR
+faze/GDS
+fazed/U
+faence/M
+fealty/M
+fear/MDGS
+fearful/YP
+fearfulness/M
+fearless/PY
+fearlessness/M
+fearmonger/MSG
+fearsome
+feasibility/M
+feasible/IU
+feasibly
+feast/SMDRZG
+feaster/M
+feat/MS
+feather/SGMD
+featherbedding/M
+featherbrained
+featherless
+featherweight/MS
+feathery/TR
+feature/DSMG
+featureless
+febrile
+fecal
+feces/M
+feckless/PY
+fecund
+fecundate/GNDS
+fecundation/M
+fecundity/M
+fed/SM
+federal/SMY
+federalism/M
+federalist/MS
+federalization/M
+federalize/GDS
+federate/FXDSGN
+federation/FM
+fedora/SM
+fee/SM
+feeble/RTP
+feebleness/M
+feebly
+feed/MRZGSJ
+feedback/M
+feedbag/SM
+feeder/M
+feeding/M
+feedlot/SM
+feel/MRZGSJ
+feeler/M
+feelgood
+feeling/MY
+feet
+feign/SDG
+feigned/U
+feint/SMDG
+feisty/TR
+feldspar/M
+felicitate/GNXDS
+felicitation/M
+felicitous/Y
+felicity/ISM
+feline/SM
+fell/MDRZTGS
+fella/S
+fellatio/M
+fellow/SM
+fellowman/M
+fellowmen
+fellowship/MS
+felon/SM
+felonious
+felony/SM
+felt/MDGS
+fem
+female/PSM
+femaleness/M
+feminine/SMY
+femininity/M
+feminism/M
+feminist/SM
+feminize/DSG
+femoral
+femur/SM
+fen/SM
+fence/DRSMZG
+fencer/M
+fencing/M
+fend/CDRZGS
+fender/CM
+fenestration/M
+fennel/M
+fentanyl/M
+feral
+ferment/FCMS
+fermentation/M
+fermented
+fermenting
+fermion
+fermium/M
+fern/MS
+ferny/RT
+ferocious/PY
+ferociousness/M
+ferocity/M
+ferret/GSMD
+ferric
+ferrite
+ferritin
+ferromagnetic
+ferromagnetism
+ferrous
+ferrule/MS
+ferry/DSMG
+ferryboat/SM
+ferryman/M
+ferrymen
+fertile/I
+fertility/IM
+fertilization/M
+fertilize/DRSZG
+fertilized/U
+fertilizer/M
+ferule/SM
+fervency/M
+fervent/Y
+fervid/Y
+fervor/M
+fess/FKGSD
+fest/MRZVS
+festal
+fester/GMD
+festival/SM
+festive/YP
+festiveness/M
+festivity/SM
+festoon/GMDS
+feta/M
+fetal
+fetch/DRSZG
+fetcher/M
+fetching/Y
+fete/MGDS
+fetid/P
+fetidness/M
+fetish/MS
+fetishism/M
+fetishist/SM
+fetishistic
+fetlock/MS
+fetter's
+fetter/USGD
+fettle/M
+fettuccine/M
+fetus/MS
+feud/MDGS
+feudal
+feudalism/M
+feudalistic
+fever/SMD
+feverish/YP
+feverishness/M
+few/TPMR
+fewness/M
+fey
+fez/M
+fezzes
+ff
+fiance/CM
+fiancee/MS
+fiances
+fianc/SM
+fiance/MS
+fiasco/SM
+fiascoes
+fiat/MS
+fib/ZSMR
+fibbed
+fibber/SM
+fibbing
+fiber/M
+fiberboard/M
+fiberfill/M
+fiberglass/M
+fibril/SM
+fibrillate/GNDS
+fibrillation/M
+fibrin/M
+fibroid
+fibromyalgia/M
+fibromyalgic/S
+fibrosis/M
+fibrous
+fibula/M
+fibulae
+fibular
+fiche/SM
+fichu/SM
+fickle/RPT
+fickleness/M
+fiction/MS
+fictional/Y
+fictionalization/SM
+fictionalize/DSG
+fictitious/Y
+fictive
+ficus/M
+fiddle/DRSMZG
+fiddler/M
+fiddlesticks
+fiddly/TR
+fidelity/IM
+fides
+fidget/SGMD
+fidgety
+fiduciary/SM
+fie
+fief/MS
+fiefdom/MS
+field/ISMRZ
+fielded
+fielder/IM
+fielding
+fieldsman
+fieldsmen
+fieldwork/MRZ
+fieldworker/M
+fiend/SM
+fiendish/Y
+fierce/PRYT
+fierceness/M
+fieriness/M
+fiery/RPT
+fiesta/SM
+fife/MZRS
+fifer/M
+fifteen/MHS
+fifteenth/M
+fifteenths
+fifth/MY
+fifths
+fiftieth/M
+fiftieths
+fifty/SMH
+fig/FSM
+fight/SMRZG
+fightback
+fighter/IMS
+fighting/IM
+figment/MS
+figuration/FM
+figurative/Y
+figure's
+figure/EFGSD
+figurehead/SM
+figurine/MS
+filament/MS
+filamentous
+filbert/MS
+filch/DSG
+file/KCSRDGZM
+filename/S
+filer/KCM
+filesystem/SM
+filet
+filial
+filibuster/MDRSZG
+filibusterer/M
+filigree/DSM
+filigreeing
+filing's
+filings
+fill's
+fill/AIDGS
+filled/U
+filler/MS
+fillet/MDGS
+filling/SM
+fillip/MDGS
+filly/SM
+film/MDGS
+filminess/M
+filmmaker/SM
+filmography
+filmstrip/MS
+filmy/TPR
+filo
+filter/MDRBSZG
+filtered/U
+filterer/M
+filth/M
+filthily
+filthiness/M
+filthy/RPT
+filtrate's
+filtrate/IGNDS
+filtration/IM
+fin/SMR
+finagle/DRSZG
+finagler/M
+final/SMY
+finale/MS
+finalist/SM
+finality/M
+finalization/M
+finalize/DSG
+finance's
+finance/ADSG
+financial/YS
+financier/MS
+financing/M
+finch/MS
+find/BJMRZGS
+finder/M
+finding/M
+findings/M
+fine's/F
+fine/CAFTGDS
+fineable
+finely
+fineness/M
+finery/AM
+finespun
+finesse/DSMG
+finger/MDGSJ
+fingerboard/SM
+fingering/M
+fingerling/SM
+fingermark/S
+fingernail/SM
+fingerprint/SGMD
+fingertip/MS
+finial/MS
+finical
+finickiness/M
+finicky/RPT
+finis/MS
+finish's
+finish/ADSG
+finished/U
+finisher/MS
+finite/IY
+fink/MDGS
+finned
+finny
+fintech
+fintechs
+fir/ZGSJMDRH
+fire/MS
+firearm/SM
+fireball/MS
+firebomb/MDSJG
+firebox/MS
+firebrand/SM
+firebreak/SM
+firebrick/SM
+firebug/SM
+firecracker/SM
+firedamp/M
+firefight/MRSZG
+firefighter/M
+firefighting/M
+firefly/SM
+fireguard/S
+firehouse/SM
+firelight/ZMR
+fireman/M
+firemen
+fireplace/SM
+fireplug/MS
+firepower/M
+fireproof/DSG
+firer/M
+firescreen/S
+fireside/MS
+firestorm/MS
+firetrap/MS
+firetruck/MS
+firewall/MS
+firewater/M
+firewood/M
+firework/SM
+firm/MDRYPTGS
+firmament/SM
+firmness/M
+firmware/M
+first/SMY
+firstborn/SM
+firsthand
+firth/M
+firths
+fiscal/MYS
+fish/MDRSZG
+fishbowl/SM
+fishcake/SM
+fisher/M
+fisherman/M
+fishermen
+fishery/SM
+fishhook/SM
+fishily
+fishiness/M
+fishing/M
+fishmonger/MS
+fishnet/SM
+fishpond/MS
+fishtail/DGS
+fishwife/M
+fishwives
+fishy/TRP
+fissile
+fission/BM
+fissionable/S
+fissure/SM
+fist/MS
+fistfight/MS
+fistful/SM
+fisticuffs/M
+fistula/SM
+fistulous/M
+fit/KAMS
+fitful/YP
+fitfulness/M
+fitly
+fitment/S
+fitness/UM
+fitted/UA
+fitter/MS
+fittest
+fitting/SMY
+five/MZRS
+fix/ZGBJMDRS
+fixate/GNVDSX
+fixation/M
+fixative/MS
+fixed/Y
+fixer/M
+fixings/M
+fixity/M
+fixture/MS
+fizz/MDSG
+fizzle/DSMG
+fizzy/RT
+fjord/SM
+fl/JDG
+flab/M
+flabbergast/SGD
+flabbily
+flabbiness/M
+flabby/RPT
+flaccid/Y
+flaccidity/M
+flack/SM
+flag/MS
+flagella
+flagellant/S
+flagellate/GNDS
+flagellation/M
+flagellum/M
+flagged
+flagging/U
+flagman/M
+flagmen
+flagon/MS
+flagpole/SM
+flagrance/M
+flagrancy/M
+flagrant/Y
+flagship/SM
+flagstaff/MS
+flagstone/MS
+flail/SGMD
+flair/SM
+flak/M
+flake/DSMG
+flakiness/M
+flaky/TRP
+flamage
+flambe/MS
+flambeed
+flambeing
+flamboyance/M
+flamboyancy/M
+flamboyant/Y
+flamb/MD
+flame/DRSJMZG
+flamenco/MS
+flameproof/DGS
+flamethrower/SM
+flamingo/MS
+flammability/IM
+flammable/SM
+flan/MS
+flaneur/SM
+flange/MS
+flank/SZGMDR
+flanker/M
+flannel/SGMD
+flannelette/M
+flap/MS
+flapjack/MS
+flapped
+flapper/SM
+flapping
+flare/DSMG
+flareup/SM
+flash/ZTGMDRS
+flashback/SM
+flashbulb/SM
+flashcard/SM
+flashcube/SM
+flasher/M
+flashgun/SM
+flashily
+flashiness/M
+flashing/M
+flashlight/MS
+flashpoint/SM
+flashy/RTP
+flask/SM
+flat/MYPS
+flatbed/SM
+flatboat/SM
+flatbread
+flatcar/SM
+flatfeet
+flatfish/MS
+flatfoot/SMD
+flatiron/SM
+flatland/M
+flatlet/S
+flatmate/S
+flatness/M
+flatted
+flatten/SDG
+flatter/SDRZG
+flatterer/M
+flattering/Y
+flattery/M
+flattest
+flatting
+flattish
+flattop/SM
+flatulence/M
+flatulent
+flatus/M
+flatware/M
+flatworm/SM
+flaunt/MDSG
+flaunting/Y
+flavor/MDSGJ
+flavored/U
+flavorful
+flavoring/M
+flavorless
+flavorsome
+flaw/MDGS
+flawless/PY
+flawlessness/M
+flax/MN
+flay/DGS
+flea/MS
+fleabag/SM
+fleabite/S
+fleapit/S
+fleck/SGMD
+fledged/U
+fledgling/MS
+flee/S
+fleece/MZGDRS
+fleecer/M
+fleeciness/M
+fleecy/RTP
+fleeing
+fleet/STGMDRYP
+fleetingly/M
+fleetingness/M
+fleetness/M
+flesh/GMDSY
+fleshly/TR
+fleshpot/MS
+fleshy/RT
+flew
+flex/AMS
+flexed
+flexibility/IM
+flexible/I
+flexibly/I
+flexing
+flexion
+flexor/MS
+flextime/M
+flibbertigibbet/SM
+flick/SZGMDR
+flicker/GMD
+flier/M
+flight/MS
+flightiness/M
+flightless
+flighty/PTR
+flimflam/SM
+flimflammed
+flimflamming
+flimsily
+flimsiness/M
+flimsy/TRP
+flinch/GMDS
+fling/GM
+flint/SM
+flintlock/SM
+flinty/TR
+flip/MS
+flippancy/M
+flippant/Y
+flipped
+flipper/MS
+flippest
+flipping
+flippy/S
+flirt/SGMD
+flirtation/MS
+flirtatious/YP
+flirtatiousness/M
+flirty
+flit/MS
+flitted
+flitting
+float/SMDRZG
+floater/M
+flock/SMDG
+flocking/M
+floe/MS
+flog/S
+flogged
+flogger/SM
+flogging/MS
+flood/SMDRG
+floodgate/MS
+floodlight/MDSG
+floodlit
+floodplain/MS
+floodwater/MS
+floor/SMDG
+floorboard/MS
+flooring/M
+floorwalker/SM
+floozie/M
+floozy/SM
+flop/MS
+flophouse/MS
+flopped
+floppily
+floppiness/M
+flopping
+floppy/PRSMT
+flora/SM
+floral
+florescence/IM
+florescent/I
+floret/SM
+florid/PY
+floridness/M
+florin/SM
+florist/SM
+floss/MDSG
+flossy/RT
+flotation/SM
+flotilla/MS
+flotsam/M
+flounce/DSMG
+flouncy
+flounder/MDSG
+flour/SMDG
+flourish/GMDS
+floury
+flout/SMDRZG
+flouter/M
+flow/MDGS
+flowchart/SM
+flower's
+flower/CSDG
+flowerbed/MS
+floweriness/M
+flowering/S
+flowerless
+flowerpot/MS
+flowery/PTR
+flown
+flt
+flu/M
+flub/MS
+flubbed
+flubbing
+fluctuate/GNDSX
+fluctuation/M
+flue/MS
+fluency/M
+fluent/Y
+fluff/SMDG
+fluffiness/M
+fluffy/RPT
+fluid/SMY
+fluidity/M
+fluidize/GS
+fluke/SM
+fluky/RT
+flume/SM
+flummox/DSG
+flung
+flunk/SMDG
+flunky/SM
+fluoresce/DSG
+fluorescence/M
+fluorescent
+fluoridate/GNDS
+fluoridation/M
+fluoride/SM
+fluorine/M
+fluorite/M
+fluorocarbon/MS
+fluoroscope/SM
+fluoroscopic
+fluoxetine
+flurry/GDSM
+flush/MDRSTG
+fluster/MDSG
+flute/DSMG
+fluting/M
+flutist/MS
+flutter/MDSG
+fluttery
+fluvial
+flux/ADGSM
+fly/ZTGBDRSM
+flyaway
+flyblown
+flyby/M
+flybys
+flycatcher/MS
+flyer/SM
+flying/M
+flyleaf/M
+flyleaves
+flyover/MS
+flypaper/SM
+flypast/S
+flysheet/S
+flyspeck/GMDS
+flyswatter/MS
+flytrap/S
+flyway/SM
+flyweight/SM
+flywheel/MS
+fo'c'sle/MS
+foal/MDGS
+foam/MDGS
+foaminess/M
+foamy/RTP
+fob/SM
+fobbed
+fobbing
+focal/Y
+foci
+focus's
+focus/ADSG
+focused/U
+fodder/SM
+foe/SM
+fog's
+fog/CS
+fogbound
+fogged/C
+foggily
+fogginess/M
+fogging/C
+foggy/RTP
+foghorn/MS
+fogy/SM
+fogyish
+foible/SM
+foil/MDGS
+foist/SDG
+fol
+fold's
+fold/AUSGD
+foldaway
+folder/SM
+foldout/MS
+foliage/M
+folic
+folio/SM
+folk/MS
+folklore/M
+folkloric
+folklorist/MS
+folksiness/M
+folksinger/SM
+folksinging/M
+folksy/PTR
+folktale/MS
+folkway/MS
+foll
+follicle/MS
+follow/SDRZGJ
+follower/M
+following/M
+followup/S
+folly/SM
+foment/SGD
+fomentation/M
+fomite/S
+fond/RYTP
+fondant/MS
+fondle/DSG
+fondness/M
+fondue/SM
+font/MS
+fontanel/MS
+fontanelle/MS
+foo
+foobar
+food/MS
+foodie/SM
+foodstuff/SM
+fool/MDGS
+foolery/SM
+foolhardily
+foolhardiness/M
+foolhardy/TPR
+foolish/YP
+foolishness/M
+foolproof
+foolscap/M
+foot/MDRZGSJ
+footage/M
+football/MRZGS
+footballer/M
+footbridge/SM
+footfall/MS
+foothill/MS
+foothold/MS
+footie
+footing/M
+footless
+footlights/M
+footling/MS
+footlocker/SM
+footloose
+footman/M
+footmen
+footnote/MGDS
+footpath/M
+footpaths
+footplate/S
+footprint/SM
+footrace/MS
+footrest/MS
+footsie/SM
+footslogging
+footsore
+footstep/MS
+footstool/SM
+footwear/M
+footwork/M
+footy
+fop/SM
+foppery/M
+foppish/P
+foppishness/M
+for/H
+fora
+forage/DRSMZG
+forager/M
+foray/SMDG
+forbade
+forbear/SMG
+forbearance/M
+forbid/S
+forbidden
+forbidding/YS
+forbore
+forborne
+force/DSMG
+forced/U
+forceful/PY
+forcefulness/M
+forceps/M
+forcible
+forcibly
+ford/MDGSB
+fore/MS
+forearm/GSMD
+forebear/MS
+forebode/GJDS
+foreboding/M
+forecast/MRZGS
+forecaster/M
+forecastle/MS
+foreclose/DSG
+foreclosure/MS
+forecourt/SM
+foredoom/DGS
+forefather/MS
+forefeet
+forefinger/SM
+forefoot/M
+forefront/SM
+foregather/GDS
+forego/G
+foregoes
+foregone
+foreground/GMDS
+forehand/MS
+forehead/MS
+foreign/ZRP
+foreigner/M
+foreignness/M
+foreknew
+foreknow/GS
+foreknowledge/M
+foreknown
+foreleg/SM
+forelimb/MS
+forelock/MS
+foreman/M
+foremast/MS
+foremen
+foremost
+forename/MDS
+forenoon/MS
+forensic/MS
+forensically
+forensics/M
+foreordain/GSD
+forepart/MS
+foreperson/SM
+foreplay/M
+forequarter/MS
+forerunner/MS
+foresail/MS
+foresaw
+foresee/RSBZ
+foreseeable/U
+foreseeing
+foreseen/U
+foreseer/M
+foreshadow/GDS
+foreshore/S
+foreshorten/DSG
+foresight/MD
+foresightedness/M
+foreskin/MS
+forest's
+forest/ACGDS
+forestall/SGD
+forestation/ACM
+forester/MS
+forestland/M
+forestry/M
+foretaste/DSMG
+foretell/GS
+forethought/M
+foretold
+forever/M
+forevermore
+forewarn/DSG
+forewent
+forewoman/M
+forewomen
+foreword/MS
+forfeit/GSMD
+forfeiture/SM
+forgather/SDG
+forgave
+forge/DRSMZGVJ
+forger/M
+forgery/SM
+forget/S
+forgetful/YP
+forgetfulness/M
+forgettable/U
+forgetting
+forging/M
+forgivable/U
+forgive/BRSZGP
+forgiven
+forgiveness/M
+forgiver/M
+forgiving/U
+forgo/RZG
+forgoer/M
+forgoes
+forgone
+forgot
+forgotten/U
+fork/MDGS
+forkful/SM
+forklift/MS
+forlorn/Y
+form's
+form/CAIFDGS
+forma/K
+formal/SMY
+formaldehyde/M
+formalin
+formalism/M
+formalist/MS
+formalities
+formality/IM
+formalization/M
+formalize/GDS
+format/SMV
+formation/CFASM
+formatted/A
+formatting/M
+formed/U
+former/FIAM
+formerly
+formfitting
+formic
+formidable
+formidably
+formless/PY
+formlessness/M
+formula/MS
+formulae
+formulaic
+formulate/ADSGNX
+formulated/U
+formulation/AM
+formulator/SM
+fornicate/GNDS
+fornication/M
+fornicator/MS
+forsake/GS
+forsaken
+forsook
+forsooth
+forswear/SG
+forswore
+forsworn
+forsythia/SM
+fort/MS
+forte/SM
+forthcoming/M
+forthright/YP
+forthrightness/M
+forthwith
+fortieth/M
+fortieths
+fortification/M
+fortified/U
+fortifier/M
+fortify/DRSNZGX
+fortissimo
+fortitude/M
+fortnight/MYS
+fortress/MS
+fortuitous/YP
+fortuitousness/M
+fortuity/M
+fortunate/UY
+fortune/MS
+fortuneteller/SM
+fortunetelling/M
+forty/SMH
+forum/SM
+forward/MDRYZTGSP
+forwarder/M
+forwardness/M
+forwent
+fossa
+fossil/SM
+fossilization/M
+fossilize/GDS
+foster/GSD
+fought
+foul/MDRYTGSP
+foulard/M
+foulmouthed
+foulness/M
+found/FSDG
+foundation/SM
+foundational
+founded/U
+founder/GMDS
+foundling/SM
+foundry/SM
+fount/SM
+fountain/SM
+fountainhead/MS
+four/MHS
+fourfold
+fourposter/SM
+fourscore/M
+foursome/SM
+foursquare
+fourteen/SMH
+fourteenth/M
+fourteenths
+fourth/MY
+fourths
+fowl/MDGS
+fox/GMDS
+foxfire/M
+foxglove/SM
+foxhole/MS
+foxhound/SM
+foxhunt/GS
+foxily
+foxiness/M
+foxtrot/MS
+foxtrotted
+foxtrotting
+foxy/RTP
+foyer/SM
+fps
+fr
+fracas/MS
+frack/SDRZG
+fractal/SM
+fraction/ISM
+fractional/Y
+fractious/YP
+fractiousness/M
+fracture/MGDS
+frag/S
+fragile/RT
+fragility/M
+fragment/GMDS
+fragmentary/M
+fragmentation/M
+fragrance/MS
+fragrant/Y
+frail/RYTP
+frailness/M
+frailty/SM
+frame/DRSMZG
+framed/U
+framer/M
+framework/SM
+franc/SM
+franca
+franchise's
+franchise/EDSG
+franchisee/SM
+franchiser/SM
+franchisor/SM
+francium/M
+francophone
+frangibility/M
+frangible
+frank/SMDRYTGP
+frankfurter/MS
+frankincense/M
+frankness/M
+frantic
+frantically
+frappe/SM
+frapp/M
+frat/MS
+fraternal/Y
+fraternity/FSM
+fraternization/M
+fraternize/ZGDRS
+fraternizer/M
+fratricidal
+fratricide/MS
+fraud's
+fraud/S
+fraudster/S
+fraudulence/M
+fraudulent/Y
+fraught
+fray's
+fray/CDGS
+frazzle/MGDS
+freak/SMDG
+freakish/YP
+freakishness/M
+freakout/MS
+freaky/RT
+freckle/DSMG
+freckly
+free/YTDRS
+freebase/MGDS
+freebee/SM
+freebie/SM
+freebooter/SM
+freeborn
+freedman/M
+freedmen
+freedom/SM
+freegan/S
+freehand
+freehold/ZMRS
+freeholder/M
+freeing
+freelance/DRSMZG
+freelancer/M
+freeload/SDRZG
+freeloader/M
+freeman/M
+freemasonry
+freemen
+freephone
+freesia/S
+freestanding
+freestone/SM
+freestyle/SM
+freethinker/SM
+freethinking/M
+freeware/M
+freeway/MS
+freewheel/DGS
+freewill
+freezable
+freeze's
+freeze/UAGS
+freezer/MS
+freezing's
+freight/MDRZGS
+freighter/M
+french
+frenemy/S
+frenetic
+frenetically
+frenzied/Y
+frenzy/DSM
+freq
+frequencies
+frequency/IM
+frequent/DRYSZTG
+frequented/U
+frequenter/M
+fresco/M
+frescoes
+fresh/PNRYXZT
+freshen/ZGDR
+freshener/M
+freshet/MS
+freshman/M
+freshmen
+freshness/M
+freshwater/M
+fret/MS
+fretful/YP
+fretfulness/M
+fretsaw/MS
+fretted
+fretting
+fretwork/M
+friable
+friar/SM
+friary/SM
+fricassee/DSM
+fricasseeing
+fricative/SM
+friction/SM
+frictional
+fridge/SM
+friedcake/MS
+friend's
+friend/UGSDY
+friendless
+friendlies
+friendliness/UM
+friendly's
+friendly/UPTR
+friendship/MS
+frieze/SM
+frig/S
+frigate/MS
+frigged
+frigging
+fright/SXGMDN
+frighten/DG
+frightening/Y
+frightful/PY
+frightfulness/M
+frigid/YP
+frigidity/M
+frigidness/M
+frill/SMD
+frilly/TR
+fringe's
+fringe/IDSG
+frippery/SM
+frisk/SDG
+friskily
+friskiness/M
+frisky/TRP
+frisson/S
+fritter/MDSG
+fritz/M
+frivolity/SM
+frivolous/PY
+frivolousness/M
+frizz/MDSYG
+frizzle/MGDS
+frizzy/TR
+fro
+frock's
+frock/CUS
+frog/MS
+frogging/S
+frogman/M
+frogmarch/GDS
+frogmen
+frogspawn
+frolic/SM
+frolicked
+frolicker/SM
+frolicking
+frolicsome
+from
+frond/SM
+front's
+front/FSDG
+frontage/MS
+frontal/Y
+frontbench/ZRS
+frontier/MS
+frontiersman/M
+frontiersmen
+frontierswoman
+frontierswomen
+frontispiece/MS
+frontward/S
+frosh/M
+frost's
+frost/CSDG
+frostbit
+frostbite/MGS
+frostbitten
+frostily
+frostiness/M
+frosting/SM
+frosty/TPR
+froth/MDG
+frothiness/M
+froths
+frothy/TPR
+froufrou/M
+frown/SMDG
+frowsy/TR
+frowzily
+frowziness/M
+frowzy/TPR
+froze/AU
+frozen/UA
+fructify/DSG
+fructose/M
+frugal/Y
+frugality/M
+fruit/SMDG
+fruitcake/MS
+fruiterer/S
+fruitful/YP
+fruitfulness/M
+fruitiness/M
+fruition/M
+fruitless/PY
+fruitlessness/M
+fruity/TPR
+frump/SM
+frumpish
+frumpy/TR
+frustrate/GNXDS
+frustrating/Y
+frustration/M
+frustum/MS
+fry/GDSM
+fryer/SM
+ft
+ftp/ZGS
+fuchsia/MS
+fuck/SMGDRZ!
+fucker/M!
+fuckhead/SM!
+fuddle/DSMG
+fudge/DSMG
+fuehrer/MS
+fuel's
+fuel/ADGS
+fug
+fugacious/PY
+fugal
+fuggy
+fugitive/MS
+fugue/SM
+fuhrer/SM
+fulcrum/MS
+fulfill/LDGS
+fulfilled/U
+fulfilling/U
+fulfillment/M
+full/MDRZTGSP
+fullback/MS
+fuller/M
+fullness/M
+fully
+fulminate/DSXGN
+fulmination/M
+fulsome/PY
+fulsomeness/M
+fum/S
+fumble/DRSMZG
+fumbler/M
+fumbling/Y
+fume/MGDS
+fumigant/MS
+fumigate/GNDS
+fumigation/M
+fumigator/SM
+fumy/RT
+fun/M
+function/MDGS
+functional/Y
+functionalism
+functionalist/S
+functionality/S
+functionary/SM
+functor
+fund/AMDRZGS
+fundamental/SMY
+fundamentalism/M
+fundamentalist/SM
+funded/U
+funding/M
+fundraiser/MS
+fundraising
+funeral/MS
+funerary
+funereal/Y
+funfair/S
+fungal
+fungi
+fungible/MS
+fungicidal
+fungicide/MS
+fungoid
+fungous
+fungus/M
+funicular/SM
+funk/MDGS
+funkiness/M
+funky/PRT
+funnel/MDGS
+funner
+funnest
+funnily
+funniness/M
+funny/TPRSM
+funnyman/M
+funnymen
+fur/SM
+furbelow/M
+furbish/ADSG
+furious/Y
+furl's
+furl/UDGS
+furlong/SM
+furlough/GMD
+furloughs
+furn
+furnace/SM
+furnish/ADSG
+furnished/U
+furnishings/M
+furniture/M
+furor/SM
+furosemide
+furred
+furrier/M
+furriness/M
+furring/M
+furrow/MDSG
+furry/ZTRP
+further/SGD
+furtherance/M
+furthermore
+furthermost
+furthest
+furtive/YP
+furtiveness/M
+fury/SM
+furze/M
+fuse's/A
+fuse/CAIFGDS
+fusee/SM
+fuselage/SM
+fusibility/M
+fusible
+fusileer/SM
+fusilier/SM
+fusillade/MS
+fusion/IFKSM
+fuss/MDSG
+fussbudget/MS
+fussily
+fussiness/M
+fusspot/SM
+fussy/TRP
+fustian/M
+fustiness/M
+fusty/TRP
+fut
+futile/Y
+futility/M
+futon/SM
+future/MS
+futurism/M
+futurist/MS
+futuristic
+futurity/SM
+futurologist/MS
+futurology/M
+futz/DSG
+fuzz/MDSG
+fuzzball/S
+fuzzily
+fuzziness/M
+fuzzy/PTR
+fwd
+fwy
+fte/SM
+g/SNXVB
+gab/SM
+gabardine/SM
+gabbed
+gabbiness/M
+gabbing
+gabble/DSMG
+gabby/RTP
+gaberdine/SM
+gabfest/MS
+gable/DSM
+gad/S
+gadabout/SM
+gadded
+gadder/SM
+gadding
+gadfly/SM
+gadget/SM
+gadgetry/M
+gadolinium/M
+gaff/MDRZGS
+gaffe/SM
+gaffer/M
+gag/SM
+gaga
+gagged
+gagging
+gaggle/SM
+gaiety/M
+gaily
+gain's
+gain/ADGS
+gainer/SM
+gainful/Y
+gainsaid
+gainsay/ZGRS
+gainsayer/M
+gait/MRZS
+gaiter/M
+gal/SM
+gala/MS
+galactic
+galaxy/SM
+gale's
+gale/AS
+galena/M
+gall/MDGS
+gallant/SMY
+gallantry/M
+gallbladder/MS
+galleon/SM
+galleria/MS
+gallery/SM
+galley/SM
+gallimaufry/SM
+gallium/M
+gallivant/GSD
+gallon/SM
+gallop/SMDG
+gallows/M
+gallstone/MS
+galoot/SM
+galore
+galosh/MS
+galumph/DG
+galumphs
+galvanic
+galvanism/M
+galvanization/M
+galvanize/DSG
+galvanometer/MS
+gambit/SM
+gamble/DRSMZG
+gambler/M
+gambling/M
+gambol/SMDG
+game/MYTGDRSP
+gamecock/MS
+gamekeeper/MS
+gameness/M
+gamesmanship/M
+gamester/MS
+gamete/SM
+gametic
+gamey
+gamify/DSNG
+gamin/SM
+gamine/SM
+gaminess/M
+gaming/M
+gamma/SM
+gammon/M
+gammy
+gamut/SM
+gamy/RTP
+gander/SM
+gang/MDGS
+gangbusters/M
+gangland/M
+ganglia
+gangling
+ganglion/M
+ganglionic
+gangplank/SM
+gangrene/DSMG
+gangrenous
+gangsta/S
+gangster/SM
+gangway/MS
+ganja
+gannet/SM
+gantlet/MS
+gantry/SM
+gap/GSMD
+gape/MS
+gar/SLM
+garage/DSMG
+garb/MDGS
+garbage/M
+garbageman
+garbanzo/SM
+garble/DSG
+garcon/SM
+garden/SZGMDR
+gardener/M
+gardenia/MS
+gardening/M
+garfish/MS
+gargantuan
+gargle/DSMG
+gargoyle/SM
+garish/PY
+garishness/M
+garland/MDGS
+garlic/M
+garlicky
+garment/MS
+garner/SGD
+garnet/SM
+garnish/GLMDS
+garnishee/DSM
+garnisheeing
+garnishment/SM
+garotte/MGDS
+garret/SM
+garrison/MDSG
+garrote/MZGDRS
+garroter/M
+garrotte/MGDS
+garrulity/M
+garrulous/PY
+garrulousness/M
+garter/SM
+garon/SM
+gas's
+gas/CS
+gasbag/SM
+gaseous
+gash/MDSG
+gasholder/S
+gasket/SM
+gaslight/MDGS
+gasman
+gasmen
+gasohol/M
+gasoline/M
+gasometer/S
+gasp/MDGS
+gassed/C
+gasses
+gassing/C
+gassy/RT
+gastric
+gastritis/M
+gastroenteritis/M
+gastroenterologist/M
+gastroenterology
+gastrointestinal
+gastronome/S
+gastronomic
+gastronomical/Y
+gastronomy/M
+gastropod/SM
+gasworks/M
+gate/MGDS
+gateau
+gateaux
+gatecrash/DRSZG
+gatecrasher/M
+gatehouse/SM
+gatekeeper/MS
+gatekeeping/M
+gatepost/MS
+gateway/MS
+gather/SJZGMDR
+gatherer/M
+gathering/M
+gator/SM
+gauche/RPYT
+gaucheness/M
+gaucherie/M
+gaucho/SM
+gaudily
+gaudiness/M
+gaudy/RPT
+gauge/DSMG
+gaunt/RPT
+gauntlet/MS
+gauntness/M
+gauze/M
+gauziness/M
+gauzy/RPT
+gave
+gavel/SM
+gavotte/MS
+gawd
+gawk/DGS
+gawkily
+gawkiness/M
+gawky/RPT
+gawp/DGS
+gay/TSPMR
+gayness/M
+gaze/MZGDRS
+gazebo/SM
+gazelle/MS
+gazer/M
+gazette/MGDS
+gazetteer/MS
+gazillion/HS
+gazpacho/M
+gazump/DGS
+gear/MDGS
+gearbox/MS
+gearing/M
+gearshift/MS
+gearwheel/SM
+gecko/SM
+geddit
+gee/DS
+geeing
+geek/MS
+geeky/RT
+geese
+geezer/MS
+geisha/M
+gel/SM
+gelatin/M
+gelatinous
+gelcap/M
+geld/DJGS
+gelding/M
+gelid
+gelignite/M
+gelled
+gelling
+gem/SM
+gemmology/M
+gemological
+gemologist/MS
+gemology/M
+gemstone/MS
+gendarme/MS
+gender/MDSG
+gene/MS
+genealogical/Y
+genealogist/MS
+genealogy/SM
+genera
+general/SMY
+generalissimo/MS
+generalist/MS
+generality/SM
+generalization/MS
+generalize/GDS
+generalship/M
+generate/ACDSGNV
+generation's/A
+generation/CSM
+generational
+generator/SM
+generic/SM
+generically
+generosity/SM
+generous/PY
+generousness/M
+genes/S
+genesis/M
+genetic/S
+genetically
+geneticist/MS
+genetics/M
+genial/FY
+geniality/FM
+geniculate
+genie/SM
+genii
+genital/FY
+genitalia/M
+genitals/M
+genitive/MS
+genitourinary
+genius/MS
+genned
+genning
+genocidal
+genocide/MS
+genome/MS
+genomic/SM
+genre/SM
+gent/AMS
+genteel/YP
+genteelness/M
+gentian/SM
+gentile/SM
+gentility/M
+gentle/TGDRSP
+gentlefolk/MS
+gentlefolks/M
+gentleman/MY
+gentlemanly/U
+gentlemen
+gentleness/M
+gentlewoman/M
+gentlewomen
+gently
+gentrification/M
+gentrify/DSGN
+gentry/SM
+genuflect/DGS
+genuflection/MS
+genuine/PY
+genuineness/M
+genus/M
+geocache/DSG
+geocentric
+geocentrically
+geocentricism
+geocentrism
+geochemistry/M
+geode/SM
+geodesic/SM
+geodesy/M
+geodetic
+geoengineering
+geog
+geographer/SM
+geographic
+geographical/Y
+geography/SM
+geologic
+geological/Y
+geologist/MS
+geology/SM
+geom
+geomagnetic
+geomagnetism/M
+geometer
+geometric
+geometrical/Y
+geometry/SM
+geophysical
+geophysicist/SM
+geophysics/M
+geopolitical/Y
+geopolitics/M
+geostationary
+geosynchronous
+geosyncline/MS
+geothermal
+geothermic
+geranium/MS
+gerbil/MS
+geriatric/S
+geriatrician/S
+geriatrics/M
+germ/MS
+germane
+germanium/M
+germicidal
+germicide/MS
+germinal/M
+germinate/GNDS
+germination/M
+gerontocracy
+gerontological
+gerontologist/MS
+gerontology/M
+gerrymander/GMDS
+gerrymandering/M
+gerund/MS
+gestalt/S
+gestapo/MS
+gestate/GNDS
+gestation/M
+gestational
+gesticulate/DSGNX
+gesticulation/M
+gestural
+gesture/MGDS
+gesundheit
+get/S
+getaway/SM
+getting
+getup/M
+gewgaw/SM
+geyser/SM
+ghastliness/M
+ghastly/TPR
+ghat/MS
+ghee
+gherkin/MS
+ghetto/SM
+ghettoize/GDS
+ghost/SMDYG
+ghostliness/M
+ghostly/RTP
+ghostwrite/ZGRS
+ghostwriter/M
+ghostwritten
+ghostwrote
+ghoul/SM
+ghoulish/YP
+ghoulishness/M
+giant/SM
+giantess/MS
+gibber/GDS
+gibberish/M
+gibbet/GMDS
+gibbon/MS
+gibbous
+gibe/MGDS
+gibibyte/MS
+giblet/SM
+giddily
+giddiness/M
+giddy/RTP
+gift/MDGS
+gig/SM
+gigabit/SM
+gigabyte/MS
+gigagram/S
+gigahertz/M
+gigajoule/SM
+gigameter/S
+gigantic
+gigantically
+gigapascal/S
+gigapixel/MS
+gigawatt/SM
+gigged
+gigging
+giggle/DRSMZG
+giggler/M
+giggly/RT
+gigolo/SM
+gild/MDRZGS
+gilder/M
+gilding/M
+gill/MS
+gillie/S
+gillion/S
+gilt/MS
+gimbals/M
+gimcrack/SM
+gimcrackery/M
+gimlet/GSMD
+gimme/SM
+gimmick/MS
+gimmickry/M
+gimmicky
+gimp/MDGS
+gimpy
+gin/SM
+ginger/GSMDY
+gingerbread/M
+gingersnap/SM
+gingery
+gingham/M
+gingivitis/M
+ginkgo/SM
+ginkgoes
+ginned
+ginning
+ginormous
+ginseng/M
+giraffe/MS
+gird/DRZGS
+girder/M
+girdle/DSMG
+girl/MS
+girlfriend/MS
+girlhood/SM
+girlie
+girlish/YP
+girlishness/M
+girly/S
+giro/S
+girt/MDGS
+girth/M
+girths
+gist/M
+git/S
+gite/S
+give/ZGJRS
+giveaway/MS
+giveback/MS
+given/SM
+giver/M
+gizmo/SM
+gizzard/MS
+glace/S
+glaceed
+glaceing
+glacial/Y
+glaciate/XGNDS
+glaciation/M
+glacier/MS
+glac/SDG
+glad/MYSP
+gladden/GDS
+gladder
+gladdest
+glade/SM
+gladiator/SM
+gladiatorial
+gladiola/SM
+gladioli
+gladiolus/M
+gladness/M
+gladsome
+glam
+glamor/SGMD
+glamorization/M
+glamorize/DSG
+glamorous/Y
+glamour/GMDS
+glamping
+glance/DSMG
+gland/SM
+glandes
+glandular
+glans/M
+glare/DSMG
+glaring/Y
+glasnost/M
+glass/MDSG
+glassblower/MS
+glassblowing/M
+glassful/SM
+glasshouse/S
+glassily
+glassiness/M
+glassware/M
+glassy/RTP
+glaucoma/M
+glaze/DSMG
+glazier/SM
+glazing/M
+gleam/SMDGJ
+glean/SDRZGJ
+gleaner/M
+gleanings/M
+glee/M
+gleeful/YP
+gleefulness/M
+glen/MS
+glenohumeral
+glenoid
+glib/YP
+glibber
+glibbest
+glibness/M
+glide/DRSMZG
+glider/M
+gliding/M
+glimmer/MDGJS
+glimmering/M
+glimpse/MGDS
+glint/SMDG
+glissandi
+glissando/M
+glisten/MDSG
+glister/DSG
+glitch/GMDS
+glitter/MDSG
+glitterati
+glittery
+glitz/M
+glitzy/TR
+gloaming/SM
+gloat/SMDG
+gloating/Y
+glob/MDGS
+global/Y
+globalism/M
+globalist/MS
+globalization/M
+globalize/GDS
+globe/SM
+globetrotter/MS
+globetrotting
+globular
+globule/MS
+globulin/M
+glockenspiel/SM
+glom/DGS
+gloom/M
+gloomily
+gloominess/M
+gloomy/TRP
+glop/M
+gloppy
+glorification/M
+glorify/GDSN
+glorious/IY
+glory/DSMG
+gloss/MDSG
+glossary/SM
+glossily
+glossiness/M
+glossolalia/M
+glossy/PTRSM
+glottal
+glottis/MS
+glove/DSMG
+glow/MDRZGS
+glower/GMD
+glowing/Y
+glowworm/MS
+glucagon
+glucose/M
+glue/MGDS
+glued/U
+gluey
+gluier
+gluiest
+glum/YP
+glummer
+glummest
+glumness/M
+gluon/S
+glut/MNS
+gluten/M
+glutenous
+glutinous/Y
+glutted
+glutting
+glutton/MS
+gluttonous/Y
+gluttony/M
+glycerin/M
+glycerine/M
+glycerol/M
+glycogen/M
+glycol
+glyph
+gm
+gnarl/SMDG
+gnarly/TR
+gnash/MDSG
+gnat/MS
+gnaw/DGS
+gneiss/M
+gnocchi
+gnome/SM
+gnomic
+gnomish
+gnu/SM
+go/JMRHZG
+goad/MDGS
+goal/MS
+goalie/SM
+goalkeeper/MS
+goalkeeping/M
+goalless
+goalmouth
+goalmouths
+goalpost/MS
+goalscorer/S
+goaltender/MS
+goat/MS
+goatee/SM
+goatherd/MS
+goatskin/MS
+gob/SM
+gobbed
+gobbet/SM
+gobbing
+gobble/DRSMZG
+gobbledygook/M
+gobbler/M
+goblet/SM
+goblin/SM
+gobsmacked
+gobstopper/S
+gochujang
+god/SM
+godawful
+godchild/M
+godchildren/M
+goddam/D
+goddammit
+goddamn/D
+goddaughter/MS
+goddess/MS
+godfather/SM
+godforsaken
+godhead/M
+godhood/M
+godless/PY
+godlessness/M
+godlike
+godliness/UM
+godly/URTP
+godmother/SM
+godparent/SM
+godsend/SM
+godson/SM
+godspeed
+goer/M
+goes
+gofer/SM
+goggle/DSMG
+goggles/M
+going/M
+goiter/SM
+gold/MNS
+goldbrick/ZGSMDR
+goldbricker/M
+golden/TR
+goldenrod/M
+goldfield/S
+goldfinch/MS
+goldfish/MS
+goldmine/SM
+goldsmith/M
+goldsmiths
+golem
+golf/MDRZGS
+golfer/M
+golliwog/S
+golly/SM
+gonad/SM
+gonadal
+gondola/MS
+gondolier/SM
+gone/ZR
+goner/M
+gong/MDGS
+gonk/S
+gonna
+gonorrhea/M
+gonorrheal
+gonzo
+goo/M
+goober/SM
+good/MYSP
+goodby/M
+goodbye/MS
+goodbys
+goodhearted
+goodie/M
+goodish
+goodly/TR
+goodness/M
+goodnight
+goods/M
+goodwill/M
+goody/SM
+gooey
+goof/MDGS
+goofball/SM
+goofiness/M
+goofy/RPT
+google/DSMG
+googly/S
+gooier
+gooiest
+gook/MS
+goon/MS
+goop/M
+goose/DSMG
+gooseberry/SM
+goosebumps/M
+gooseflesh/M
+goosestep/S
+goosestepped
+goosestepping
+gopher/SM
+gore/MGDS
+gorge's
+gorge/EDSG
+gorgeous/YP
+gorgeousness/M
+gorgon/SM
+gorilla/MS
+gorily
+goriness/M
+gormandize/DRSZG
+gormandizer/M
+gormless
+gorp/MS
+gorse/M
+gory/RTP
+gosh
+goshawk/MS
+gosling/SM
+gospel/MS
+gossamer/M
+gossip/MDRZGS
+gossiper/M
+gossipy
+got
+gotcha/S
+gothic/P
+gothically
+goths
+gotta
+gotten
+gouache/S
+gouge/DRSMZG
+gouger/M
+goulash/MS
+gourd/SM
+gourde/MS
+gourmand/SM
+gourmet/SM
+gout/M
+gouty/TR
+gov
+govern/DGSBL
+governable/U
+governance/M
+governed/U
+governess/MS
+government/MS
+governmental
+governor/SM
+governorship/M
+govt
+gown/MDGS
+gr
+grab/MS
+grabbed
+grabber/MS
+grabbing
+grabby/TR
+grace/EDSMG
+graceful/EPY
+gracefulness/EM
+graceless/PY
+gracelessness/M
+gracious/UY
+graciousness/M
+grackle/MS
+grad/MRZSB
+gradate/XGNDS
+gradation/CM
+grade's
+grade/CADSG
+graded/U
+grader/M
+gradient/MS
+gradual/PY
+gradualism/M
+gradualness/M
+graduate/XMGNDS
+graduation/M
+graffiti
+graffito/M
+graft/SMDRZG
+grafter/M
+graham/S
+grail
+grain/ISMD
+graininess/M
+grainy/PTR
+gram/KMS
+grammar/MS
+grammarian/SM
+grammatical/UY
+grammatically/K
+gramophone/MS
+grampus/MS
+gran/S
+granary/SM
+grand/SMRYPT
+grandad/MS
+grandam/MS
+grandaunt/MS
+grandchild/M
+grandchildren/M
+granddad/SM
+granddaddy/SM
+granddaughter/SM
+grande
+grandee/MS
+grandeur/M
+grandfather/GMDYS
+grandiloquence/M
+grandiloquent
+grandiose/Y
+grandiosity/M
+grandma/MS
+grandmother/MYS
+grandnephew/MS
+grandness/M
+grandniece/MS
+grandpa/MS
+grandparent/MS
+grandson/MS
+grandstand/SGMD
+granduncle/SM
+grange/SM
+granite/M
+granitic
+grannie/M
+granny/SM
+granola/M
+grant/SMDRZG
+grantee/MS
+granter/M
+grantor/MS
+grantsmanship/M
+granular
+granularity/M
+granulate/GNDS
+granulation/M
+granule/MS
+grape/SM
+grapefruit/MS
+grapeshot/M
+grapevine/SM
+graph/MDG
+graphic/MS
+graphical/Y
+graphite/M
+graphologist/MS
+graphology/M
+graphs
+grapnel/MS
+grapple/MGDS
+grasp/SMDBG
+grass/MDSG
+grasshopper/MS
+grassland/MS
+grassroots
+grassy/TR
+grate/DRSMZGJ
+grateful/UYP
+gratefulness/UM
+grater/M
+gratification/M
+gratify/GNXDS
+gratifying/Y
+gratin/S
+grating/MY
+gratis
+gratitude/IM
+gratuitous/YP
+gratuitousness/M
+gratuity/SM
+gravamen/MS
+grave/DRSMYTGP
+gravedigger/SM
+gravel/SGMDY
+graven
+graveness/M
+graveside/MS
+gravestone/SM
+graveyard/MS
+gravid
+gravimeter/MS
+gravitas
+gravitate/GNDS
+gravitation/M
+gravitational
+gravity/M
+gravy/SM
+gray/MDRTGSP
+graybeard/SM
+grayish
+grayness/M
+grayscale
+graze/DRSMZG
+grazer/M
+grease/DRSMZG
+greasepaint/M
+greasily
+greasiness/M
+greasy/PTR
+great/SMRYPT
+greatcoat/SM
+greathearted
+greatness/M
+grebe/SM
+greed/M
+greedily
+greediness/M
+greedy/PTR
+green/GPSMDRYT
+greenback/MS
+greenbelt/MS
+greenery/M
+greenfield
+greenfly/S
+greengage/MS
+greengrocer/SM
+greenhorn/SM
+greenhouse/SM
+greenish
+greenmail/M
+greenness/M
+greenroom/SM
+greenstone
+greensward/M
+greenwood/M
+greet/ZGJSDR
+greeter/M
+greeting/M
+gregarious/PY
+gregariousness/M
+gremlin/SM
+grenade/SM
+grenadier/MS
+grenadine/M
+grep/S
+grepped
+grepping
+grew/A
+grey/MDRTGS
+greybeard's
+greybeards
+greyhound/SM
+greyness's
+gribble/S
+grid/MS
+griddle/SM
+griddlecake/SM
+gridiron/SM
+gridlock/SMD
+grief/SM
+grievance/MS
+grieve/ZGDRS
+griever/M
+grievous/PY
+grievousness/M
+griffin/SM
+griffon/SM
+grill/SGMDJ
+grille/MS
+grim/DYPG
+grimace/DSMG
+grime/SM
+griminess/M
+grimmer
+grimmest
+grimness/M
+grimy/TRP
+grin/MS
+grind/SZGMRJ
+grinder/M
+grindstone/MS
+gringo/MS
+grinned
+grinning
+grip/MDRSZG
+gripe/SM
+griper/M
+grippe/MZGDR
+gripper/M
+grisliness/M
+grisly/RTP
+grist/MY
+gristle/M
+gristmill/MS
+grit/MS
+grits/M
+gritted
+gritter/SM
+grittiness/M
+gritting
+gritty/RTP
+grizzle/DSG
+grizzly/TRSM
+groan/SGMD
+groat/SM
+grocer/MS
+grocery/SM
+grog/M
+groggily
+grogginess/M
+groggy/PRT
+groin/SM
+grok/S
+grokked
+grokking
+grommet/SM
+groom/SZGMDR
+groomer/M
+grooming/M
+groomsman/M
+groomsmen
+groove/MGDS
+groovy/RT
+grope/DRSMZG
+groper/M
+grosbeak/MS
+grosgrain/M
+gross/PTGMDRSY
+grossness/M
+grotesque/SPMY
+grotesqueness/M
+grotto/M
+grottoes
+grotty/TR
+grouch/GMDS
+grouchily
+grouchiness/M
+grouchy/RTP
+ground/ZGMDRJS
+groundbreaking/MS
+groundcloth
+groundcloths
+grounder/M
+groundhog/MS
+grounding/M
+groundless/Y
+groundnut/MS
+groundsheet/S
+groundskeeper/S
+groundsman
+groundsmen
+groundswell/SM
+groundwater/M
+groundwork/M
+group/JSZGMDR
+grouper/M
+groupie/MS
+grouping/M
+groupware/M
+grouse/MZGDRS
+grouser/M
+grout/SGMD
+grove/SM
+grovel/ZGDRS
+groveler/M
+grovelled
+grovelling
+grow/AHSG
+grower/MS
+growing/I
+growl/SZGMDR
+growler/M
+grown/AI
+grownup/MS
+growth/AM
+growths
+grub/MS
+grubbed
+grubber/MS
+grubbily
+grubbiness/M
+grubbing
+grubby/TRP
+grubstake/M
+grudge/MGDS
+grudging/Y
+grue/S
+gruel/GJM
+grueling/Y
+gruesome/RYTP
+gruesomeness/M
+gruff/TPRY
+gruffness/M
+grumble/DRSMZGJ
+grumbler/M
+grump/SM
+grumpily
+grumpiness/M
+grumpy/PRT
+grunge/MS
+grungy/RT
+grunion/SM
+grunt/SGMD
+gt
+guac
+guacamole/M
+guanine/M
+guano/M
+guarani/MS
+guaranies
+guarantee/MDS
+guaranteeing
+guarantor/MS
+guaranty/GDSM
+guard/SZGMDR
+guarded/Y
+guarder/M
+guardhouse/SM
+guardian/SM
+guardianship/M
+guardrail/SM
+guardroom/SM
+guardsman/M
+guardsmen
+guava/SM
+gubernatorial
+guerilla/SM
+guerrilla/SM
+guess/ZGBMDRS
+guesser/M
+guesstimate/DSMG
+guesswork/M
+guest/SGMD
+guestbook/SM
+guesthouse/S
+guestroom/S
+guff/M
+guffaw/MDGS
+guidance/M
+guide/DRSMZG
+guidebook/SM
+guided/U
+guideline/SM
+guidepost/SM
+guider/M
+guild/SZMR
+guilder/M
+guildhall/MS
+guile/M
+guileful
+guileless/YP
+guilelessness/M
+guillemot/S
+guillotine/DSMG
+guilt/M
+guiltily
+guiltiness/M
+guiltless
+guilty/PRT
+guinea/MS
+guise/ESM
+guitar/MS
+guitarist/SM
+gulag/SM
+gulch/MS
+gulden/MS
+gulf/MS
+gull/MDSG
+gullet/MS
+gullibility/M
+gullible
+gully/SM
+gulp/MDRSZG
+gulper/M
+gum/SM
+gumball/S
+gumbo/SM
+gumboil/SM
+gumboot/S
+gumdrop/SM
+gummed
+gumming
+gummy/TR
+gumption/M
+gumshoe/MDS
+gumshoeing
+gun/SM
+gunboat/SM
+gunfight/MRZS
+gunfighter/M
+gunfire/M
+gunge
+gungy
+gunk/M
+gunky
+gunman/M
+gunmen
+gunmetal/M
+gunned
+gunnel/MS
+gunner/MS
+gunnery/M
+gunning
+gunny/M
+gunnysack/MS
+gunpoint/M
+gunpowder/M
+gunrunner/MS
+gunrunning/M
+gunship/MS
+gunshot/MS
+gunslinger/SM
+gunsmith/M
+gunsmiths
+gunsmoke
+gunwale/MS
+guppy/SM
+gurgle/MGDS
+gurney/MS
+guru/MS
+gush/MDRSZG
+gusher/M
+gushing/Y
+gushy/TR
+gusset/MSDG
+gussy/DSG
+gust/EMDSG
+gustatory
+gustily
+gusto/M
+gusty/RT
+gut/SM
+gutless/P
+gutlessness/M
+gutsy/RT
+gutted
+gutter/SMDG
+guttersnipe/MS
+gutting
+guttural/MS
+gutty/RT
+guv/S
+guvnor/S
+guy/SGMD
+guzzle/DRSZG
+guzzler/M
+gym/SM
+gymkhana/MS
+gymnasium/MS
+gymnast/MS
+gymnastic/S
+gymnastically
+gymnastics/M
+gymnosperm/SM
+gymslip/S
+gynecologic
+gynecological
+gynecologist/SM
+gynecology/M
+gyp/SM
+gypped
+gypper/SM
+gypping
+gypster/SM
+gypsum/M
+gypsy/SM
+gyrate/DSGNX
+gyration/M
+gyrator/SM
+gyrfalcon/MS
+gyro/MS
+gyroscope/MS
+gyroscopic
+gyve/MGDS
+h'm
+h/NRSXZGVJ
+ha/SH
+habeas
+haberdasher/SM
+haberdashery/SM
+habiliment/SM
+habit's
+habit/ISB
+habitability/M
+habitat/SM
+habitation/MS
+habitual/YP
+habitualness/M
+habituate/GNDS
+habituation/M
+habitue/SM
+habitu/SM
+hacienda/SM
+hack/MDRZGS
+hacker/M
+hacking/M
+hackish
+hackle/MS
+hackney/SMDG
+hacksaw/SM
+hacktivist/MS
+hackwork/M
+had
+haddock/SM
+hadith/S
+hadn't
+hadron
+hadronic
+hadst
+hafnium/M
+haft/MS
+hag/SM
+haggard/YP
+haggardness/M
+haggis/MS
+haggish
+haggle/MZGDRS
+haggler/M
+hagiographer/SM
+hagiography/SM
+hah
+hahnium/M
+haiku/M
+hail/MDGS
+hailstone/MS
+hailstorm/MS
+hair/MDS
+hairball/MS
+hairband/S
+hairbreadth/M
+hairbreadths
+hairbrush/MS
+haircloth/M
+haircut/SM
+hairdo/MS
+hairdresser/SM
+hairdressing/M
+hairdrier/MS
+hairdryer/MS
+hairgrip/S
+hairiness/M
+hairless
+hairlike
+hairline/SM
+hairnet/SM
+hairpiece/MS
+hairpin/SM
+hairsbreadth/M
+hairsbreadths
+hairsplitter/SM
+hairsplitting/M
+hairspray/S
+hairspring/MS
+hairstyle/MS
+hairstylist/SM
+hairy/TRP
+haj
+hajj/M
+hajjes
+hajji/SM
+hake/MS
+halal/M
+halberd/SM
+halcyon
+hale/ITGDRS
+half/M
+halfback/SM
+halfhearted/PY
+halfheartedness/M
+halfpence
+halfpenny/SM
+halftime/MS
+halftone/MS
+halfway
+halfwit/SM
+halibut/SM
+halite/M
+halitosis/M
+hall/MS
+hallelujah/M
+hallelujahs
+hallmark/GMDS
+halloo/MDSG
+hallow/DSG
+hallowed/U
+hallucinate/GNXDS
+hallucination/M
+hallucinatory
+hallucinogen/SM
+hallucinogenic/SM
+hallway/SM
+halo/MDGS
+halogen/SM
+halon
+halt/MDRZGS
+halter/GMD
+halterneck/S
+halting/Y
+halve/DSG
+halyard/MS
+ham/SM
+hamburg/SZMR
+hamburger/M
+hamlet/MS
+hammed
+hammer/MDRSJZG
+hammerer/M
+hammerhead/SM
+hammerlock/SM
+hammertoe/MS
+hamming
+hammock/SM
+hammy/TR
+hamper/GMDS
+hampered/U
+hamster/MS
+hamstring/GSM
+hamstrung
+hand's
+hand/UDGS
+handbag/SM
+handball/MS
+handbarrow/SM
+handbill/MS
+handbook/MS
+handbrake/S
+handcar/SM
+handcart/MS
+handclasp/MS
+handcraft/SMDG
+handcuff/MDGS
+handed/P
+handful/SM
+handgun/SM
+handheld/MS
+handhold/MS
+handicap/MS
+handicapped
+handicapper/MS
+handicapping
+handicraft/MS
+handily
+handiness/M
+handiwork/M
+handkerchief/MS
+handle/MZGDRS
+handlebar/MS
+handler/M
+handmade
+handmaid/XMNS
+handmaiden/M
+handout/SM
+handover/S
+handpick/GDS
+handrail/MS
+handsaw/SM
+handset/SM
+handshake/JMGS
+handsome/PYTR
+handsomeness/M
+handspring/MS
+handstand/SM
+handwashing
+handwork/M
+handwoven
+handwrite/GS
+handwriting/M
+handwritten
+handwrote
+handy/UTR
+handyman/M
+handymen
+hang/MDRJZGS
+hangar/MS
+hangdog
+hanger/M
+hanging/M
+hangman/M
+hangmen
+hangnail/MS
+hangout/SM
+hangover/MS
+hangup/MS
+hank/MRZS
+hanker/GJD
+hankering/M
+hankie/M
+hanky/SM
+hansom/MS
+hap/MY
+haphazard/YP
+haphazardness/M
+hapless/YP
+haplessness/M
+haploid/MS
+happen/SDGJ
+happening/M
+happenstance/SM
+happily/U
+happiness/UM
+happy/URTP
+haptic/S
+haptical/Y
+harangue/MGDS
+harass/LZGDRS
+harasser/M
+harassment/M
+harbinger/SM
+harbor/GMDS
+harbormaster/S
+hard/NRYXTP
+hardback/MS
+hardball/M
+hardboard/M
+hardbound
+hardcore
+hardcover/SM
+harden/ZGDR
+hardened/U
+hardener/M
+hardhat/MS
+hardheaded/PY
+hardheadedness/M
+hardhearted/PY
+hardheartedness/M
+hardihood/M
+hardily
+hardiness/M
+hardliner/MS
+hardness/M
+hardscrabble
+hardship/SM
+hardstand/SM
+hardtack/M
+hardtop/SM
+hardware/M
+hardwired
+hardwood/SM
+hardworking
+hardy/PTR
+hare/MGDS
+harebell/MS
+harebrained
+harelip/SM
+harelipped
+harem/SM
+haricot/S
+harissa
+hark/DGS
+harlequin/SM
+harlot/SM
+harlotry/M
+harm/MDGS
+harmed/U
+harmful/YP
+harmfulness/M
+harmless/PY
+harmlessness/M
+harmonic/SM
+harmonica/MS
+harmonically
+harmonies
+harmonious/PY
+harmoniousness/M
+harmonium/MS
+harmonization/M
+harmonize/ZGDRS
+harmonizer/M
+harmony/EM
+harness's
+harness/UDSG
+harp/MDGS
+harpist/SM
+harpoon/ZGSMDR
+harpooner/M
+harpsichord/MS
+harpsichordist/SM
+harpy/SM
+harridan/MS
+harrier/M
+harrow/SMDG
+harrumph/GD
+harrumphs
+harry/DRSZG
+harsh/RYTP
+harshness/M
+hart/MS
+harvest/SMDRZG
+harvested/U
+harvester/M
+hash/AMDSG
+hashish/M
+hashtag/SM
+hasn't
+hasp/MS
+hassle/DSMG
+hassock/SM
+hast/DNXG
+haste/SM
+hasten/DG
+hastily
+hastiness/M
+hasty/RTP
+hat/ZGSMDR
+hatband/S
+hatbox/MS
+hatch/MDSG
+hatchback/MS
+hatcheck/SM
+hatched/U
+hatchery/SM
+hatchet/SM
+hatching/M
+hatchling
+hatchway/SM
+hate/MS
+hateful/PY
+hatefulness/M
+hatemonger/MS
+hater/M
+hatpin/S
+hatred/SM
+hatstand/S
+hatted
+hatter/SM
+hatting
+hauberk/SM
+haughtily
+haughtiness/M
+haughty/PRT
+haul/MDRZGS
+haulage/M
+hauler/M
+haulier/S
+haunch/MS
+haunt/SMDRZG
+haunter/M
+haunting/Y
+hauteur/M
+have/MGS
+haven't
+haven/SM
+haversack/SM
+havoc/M
+haw/GSMD
+hawk/MDRZGS
+hawker/M
+hawkish/P
+hawkishness/M
+hawser/SM
+hawthorn/MS
+hay/GSMD
+haycock/SM
+hayloft/SM
+haymaker/S
+haymaking
+haymow/SM
+hayrick/MS
+hayride/MS
+hayseed/MS
+haystack/SM
+haywire
+hazard/SMDG
+hazardous/Y
+haze/MZGJDRS
+hazel/SM
+hazelnut/MS
+hazer/M
+hazily
+haziness/M
+hazing/M
+hazmat
+hazy/RTP
+hdqrs
+he'd
+he'll
+he/M
+head/MDRZGJS
+headache/MS
+headband/MS
+headbanger/S
+headbanging
+headboard/SM
+headbutt/DSG
+headcase/S
+headcheese
+headcount/S
+headdress/MS
+header/M
+headfirst
+headgear/M
+headhunt/DRSZG
+headhunter/M
+headhunting/M
+headily
+headiness/M
+heading/M
+headlamp/MS
+headland/MS
+headless
+headlight/MS
+headline/MZGDRS
+headliner/M
+headlock/MS
+headlong
+headman/M
+headmaster/SM
+headmen
+headmistress/MS
+headphone/MS
+headpiece/MS
+headpin/SM
+headquarter/SDG
+headquarters/M
+headrest/MS
+headroom/M
+headscarf
+headscarves
+headset/SM
+headship/SM
+headshrinker/SM
+headsman/M
+headsmen
+headspace
+headstall/SM
+headstand/SM
+headstone/SM
+headstrong
+headteacher/S
+headwaiter/SM
+headwaters/M
+headway/M
+headwind/SM
+headword/SM
+heady/RTP
+heal/DRHZGS
+healed/U
+healer/M
+health/M
+healthcare
+healthful/PY
+healthfulness/M
+healthily/U
+healthiness/UM
+healthy/UTRP
+heap/MDGS
+hear/AHGJS
+heard/AU
+hearer/SM
+hearing/AM
+hearken/SGD
+hearsay/M
+hearse's
+hearse/AS
+heart/SM
+heartache/MS
+heartbeat/MS
+heartbreak/SMG
+heartbroken
+heartburn/M
+hearten/ESGD
+heartfelt
+hearth/M
+hearthrug/S
+hearths
+hearthstone/SM
+heartily
+heartiness/M
+heartland/MS
+heartless/PY
+heartlessness/M
+heartrending/Y
+heartsick/P
+heartsickness/M
+heartstrings/M
+heartthrob/MS
+heartwarming
+heartwood/M
+hearty/RSMPT
+heat's
+heat/ADGS
+heated/U
+heatedly
+heater/SM
+heath/MNRX
+heathen/M
+heathendom/M
+heathenish
+heathenism/M
+heather/M
+heaths
+heating/M
+heatproof
+heatstroke/M
+heatwave/S
+heave/DRSMZG
+heaven/SMY
+heavenly/TR
+heavens/M
+heavenward/S
+heaver/M
+heavily
+heaviness/M
+heavy/RSMTP
+heavyhearted
+heavyset
+heavyweight/MS
+heck/M
+heckle/DRSMZG
+heckler/M
+heckling/M
+hectare/SM
+hectic
+hectically
+hectogram/SM
+hectometer/MS
+hector/SMDG
+hedge/DRSMZG
+hedgehog/MS
+hedgehop/S
+hedgehopped
+hedgehopping
+hedger/M
+hedgerow/SM
+hedonism/M
+hedonist/MS
+hedonistic
+heed/MDGS
+heeded/U
+heedful/Y
+heedless/PY
+heedlessness/M
+heehaw/SMDG
+heel/MDGS
+heelless
+heft/MDGS
+heftily
+heftiness/M
+hefty/PRT
+hegemonic
+hegemony/M
+hegira/SM
+heifer/SM
+height/XSMN
+heighten/DG
+heinous/YP
+heinousness/M
+heir/MS
+heiress/MS
+heirloom/SM
+heist/SMDG
+held
+helical
+helices
+helicity/S
+helicopter/SGMD
+heliocentric
+heliocentrically
+heliocentricism
+heliocentrism
+heliotrope/SM
+helipad/S
+heliport/MS
+helium/M
+helix/M
+hell/M
+hellbent
+hellcat/MS
+hellebore/M
+hellfire
+hellhole/MS
+hellion/MS
+hellish/YP
+hellishness/M
+hello/SM
+helluva
+helm/MS
+helmet/SMD
+helmsman/M
+helmsmen
+helot/SM
+help/MDRZGSJ
+helper/M
+helpful/UY
+helpfulness/M
+helping/M
+helpless/PY
+helplessness/M
+helpline/SM
+helpmate/SM
+helve/SM
+hem/SM
+hematite/M
+hematologic
+hematological
+hematologist/MS
+hematology/M
+heme/M
+hemiplegia
+hemisphere/SM
+hemispheric
+hemispherical
+hemline/SM
+hemlock/SM
+hemmed
+hemmer/SM
+hemming
+hemoglobin/M
+hemophilia/M
+hemophiliac/MS
+hemorrhage/MGDS
+hemorrhagic
+hemorrhoid/MS
+hemostat/MS
+hemp/MN
+hemstitch/MDSG
+hen/M
+hence
+henceforth
+henceforward
+henchman/M
+henchmen
+henna/SMDG
+henpeck/GSD
+hentai
+hep
+heparin/M
+hepatic
+hepatitis/M
+hepatocyte/S
+hepper
+heppest
+heptagon/MS
+heptagonal
+heptathlon/SM
+herald/SMDG
+heralded/U
+heraldic
+heraldry/M
+herb/MS
+herbaceous
+herbage/M
+herbal/S
+herbalist/MS
+herbicidal
+herbicide/MS
+herbivore/SM
+herbivorous
+herculean
+herd/MDRZGS
+herder/M
+herdsman/M
+herdsmen
+here/M
+hereabout/S
+hereafter/SM
+hereby
+hereditary
+heredity/M
+herein
+hereinafter
+hereof
+hereon
+heresy/SM
+heretic/SM
+heretical
+hereto
+heretofore
+hereunder
+hereunto
+hereupon
+herewith
+heritability
+heritable/I
+heritage/MS
+hermaphrodite/SM
+hermaphroditic
+hermetic
+hermetical/Y
+hermit/SM
+hermitage/MS
+hermitian
+hernia/SM
+hernial
+herniate/GNDS
+herniation/M
+hero/M
+heroes
+heroic/S
+heroically
+heroics/M
+heroin/SM
+heroine/SM
+heroism/M
+heron/SM
+herpes/M
+herpetologist/SM
+herpetology/M
+herring/MS
+herringbone/M
+herself
+hertz/M
+hesitance/M
+hesitancy/M
+hesitant/Y
+hesitate/DSGNX
+hesitating/UY
+hesitation/M
+hessian
+hetero/SM
+heterodox
+heterodoxy/M
+heterogeneity/M
+heterogeneous/Y
+heterosexual/MYS
+heterosexuality/M
+heuristic/MS
+heuristically
+heuristics/M
+hew/ZGSDR
+hewer/M
+hex/GMDS
+hexadecimal/S
+hexagon/MS
+hexagonal
+hexagram/SM
+hexameter/SM
+hexane/SM
+hey
+heyday/SM
+hf
+hgt
+hgwy
+hi/SD
+hiatus/MS
+hibachi/MS
+hibernate/GNDS
+hibernation/M
+hibernator/MS
+hibiscus/MS
+hiccough/DG
+hiccoughs
+hiccup/GSMD
+hick/MS
+hickey/SM
+hickory/SM
+hid
+hidden
+hide/MZGJDRS
+hideaway/SM
+hidebound
+hideous/YP
+hideousness/M
+hideout/MS
+hider/M
+hiding/M
+hie/S
+hieing
+hierarchic
+hierarchical/Y
+hierarchy/SM
+hieroglyph/M
+hieroglyphic/MS
+hieroglyphs
+high/MRYZTP
+highball/SM
+highborn
+highboy/MS
+highbrow/SM
+highchair/MS
+highfalutin
+highhanded/PY
+highhandedness/M
+highland/MRZS
+highlander/M
+highlight/SMDRZG
+highlighter/M
+highness/M
+highroad/MS
+highs
+hightail/DSG
+highway/MS
+highwayman/M
+highwaymen
+hijab/SM
+hijack/SJZGMDR
+hijacker/M
+hijacking/M
+hike/MZGDRS
+hiker/M
+hiking/M
+hilarious/PY
+hilariousness/M
+hilarity/M
+hill/MS
+hillbilly/SM
+hilliness/M
+hillock/MS
+hillside/SM
+hilltop/MS
+hilly/PRT
+hilt/MS
+him/S
+himself
+hind/MRZS
+hinder/GD
+hindered/U
+hindmost
+hindquarter/MS
+hindrance/SM
+hindsight/M
+hinge's
+hinge/UDSG
+hint/MDRZGS
+hinter/M
+hinterland/SM
+hip/SPM
+hipbath
+hipbaths
+hipbone/MS
+hiphuggers
+hipness/M
+hipped
+hipper
+hippest
+hippie/M
+hipping
+hippo/SM
+hippocampus
+hippodrome/SM
+hippopotami
+hippopotamus/MS
+hippy/SM
+hipster/MS
+hiragana
+hire's
+hire/AGDS
+hireling/MS
+hirsute/P
+hirsuteness/M
+hiss/MDSG
+hist
+histamine/MS
+histogram/MS
+histologist/SM
+histology/M
+histopathology
+historian/MS
+historic
+historical/Y
+historicity/M
+historiographer/MS
+historiography/M
+history/SM
+histrionic/S
+histrionically
+histrionics/M
+hit/SM
+hitch's
+hitch/UDSG
+hitcher/MS
+hitchhike/DRSMZG
+hitchhiker/M
+hither
+hitherto
+hitter/SM
+hitting
+hive/MGDS
+hivemind/SM
+hiya
+hm
+hmm
+ho/SMDRYZ
+hoagie/MS
+hoard/SZGMDRJ
+hoarder/M
+hoarding/M
+hoarfrost/M
+hoariness/M
+hoarse/YTRP
+hoarseness/M
+hoary/TRP
+hoax/MDRSZG
+hoaxer/M
+hob/SM
+hobbit/S
+hobble/MZGDRS
+hobbler/M
+hobby/SM
+hobbyhorse/MS
+hobbyist/SM
+hobgoblin/MS
+hobnail/SGMD
+hobnob/S
+hobnobbed
+hobnobbing
+hobo/MS
+hoboes
+hoc
+hock/MDSG
+hockey/M
+hockshop/MS
+hod/SM
+hodgepodge/SM
+hoe/SM
+hoecake/SM
+hoedown/SM
+hoeing
+hoer/M
+hog/SM
+hogan/SM
+hogback/SM
+hogged
+hogging
+hoggish/Y
+hogshead/SM
+hogtie/DS
+hogtying
+hogwash/M
+hoick/SGD
+hoist/SGMD
+hoke/GDS
+hokey
+hokier
+hokiest
+hokum/M
+hold/MRJSZG
+holdall/S
+holdem
+holder/M
+holding/M
+holdout/SM
+holdover/SM
+holdup/MS
+hole/MGDS
+holey
+holiday/SMDG
+holidaymaker/S
+holiness/UM
+holism
+holistic
+holistically
+holler/MDGS
+hollow/MDRYPSTG
+hollowness/M
+holly/SM
+hollyhock/MS
+holmium/M
+holocaust/SM
+hologram/MS
+holograph/M
+holographic
+holographs
+holography/M
+hols
+holster/SMDG
+holy/URPT
+homage/MS
+hombre/MS
+homburg/SM
+home/MYZGDRS
+homebody/SM
+homeboy/SM
+homecoming/SM
+homegrown
+homeland/MS
+homeless/MP
+homelessness/M
+homelike
+homeliness/M
+homely/PRT
+homemade
+homemaker/SM
+homemaking/M
+homeopath/M
+homeopathic
+homeopaths
+homeopathy/M
+homeostasis/M
+homeostatic
+homeowner/MS
+homepage/MS
+homer/GMD
+homeroom/MS
+homeschooling/M
+homesick/P
+homesickness/M
+homespun/M
+homestead/SMDRZG
+homesteader/M
+homestretch/MS
+hometown/MS
+homeward/S
+homework/MRZG
+homewrecker/SM
+homey/SMP
+homeyness/M
+homicidal
+homicide/MS
+homie/RSMT
+homiletic
+homily/SM
+hominess/M
+hominid/SM
+hominoid/S
+hominy/M
+homo/MS
+homoerotic
+homogeneity/M
+homogeneous/Y
+homogenization/M
+homogenize/DSG
+homograph/M
+homographs
+homologous
+homology
+homonym/SM
+homophobia/M
+homophobic
+homophone/MS
+homosexual/SM
+homosexuality/M
+hon/SZTGMDR
+honcho/MS
+hone/MS
+honer/M
+honest/EYT
+honester
+honesty/EM
+honey/SGMD
+honeybee/SM
+honeycomb/MDSG
+honeydew/SM
+honeylocust/M
+honeymoon/ZGMDRS
+honeymooner/M
+honeypot/S
+honeysuckle/SM
+honk/MDRSZG
+honker/M
+honkie/M
+honky/SM
+honor/ESGMDB
+honorableness/M
+honorably/E
+honorarily
+honorarium/MS
+honorary
+honoree/SM
+honorer/SM
+honorific/MS
+hooch/M
+hood/MDSG
+hoodie/MS
+hoodlum/SM
+hoodoo/MDSG
+hoodwink/DGS
+hooey/M
+hoof/MDRSZG
+hook's
+hook/UDSG
+hookah/M
+hookahs
+hooker/MS
+hookup/MS
+hookworm/MS
+hooky/M
+hooligan/MS
+hooliganism/M
+hoop/MDSG
+hoopla/M
+hooray/MS
+hoosegow/SM
+hoot/MDRSZG
+hootch/M
+hootenanny/SM
+hooter/M
+hoover/DSG
+hooves
+hop/SGMD
+hope/MS
+hopeful/PSMY
+hopefulness/M
+hopeless/YP
+hopelessness/M
+hophead/S
+hopped
+hopper/MS
+hopping
+hopscotch/MDSG
+hora/MS
+horde/DSMG
+horehound/SM
+horizon/SM
+horizontal/SMY
+hormesis
+hormonal
+hormone/SM
+horn/MDS
+hornbeam/S
+hornblende/M
+hornet/MS
+hornless
+hornlike
+hornpipe/MS
+horny/TR
+horologic
+horological
+horologist/MS
+horology/M
+horoscope/SM
+horrendous/Y
+horrible/P
+horribleness/M
+horribly
+horrid/Y
+horrific
+horrifically
+horrify/DSG
+horrifying/Y
+horror/MS
+horse's
+horse/UDSG
+horseback/M
+horsebox/S
+horseflesh/M
+horsefly/SM
+horsehair/M
+horsehide/M
+horselaugh/M
+horselaughs
+horseless
+horseman/M
+horsemanship/M
+horsemen
+horseplay/M
+horsepower/M
+horseradish/MS
+horseshit/!
+horseshoe/DSM
+horseshoeing
+horsetail/SM
+horsetrading
+horsewhip/SM
+horsewhipped
+horsewhipping
+horsewoman/M
+horsewomen
+horsey
+horsy/TR
+hortatory
+horticultural
+horticulturalist/S
+horticulture/M
+horticulturist/MS
+hosanna/SM
+hose/MGDS
+hosepipe/S
+hosier/MS
+hosiery/M
+hosp
+hospholipase
+hospice/MS
+hospitable/I
+hospitably/I
+hospital/SM
+hospitality/M
+hospitalization/SM
+hospitalize/DSG
+host/MDSG
+hostage/MS
+hostel/ZGMDRS
+hosteler/M
+hostelry/SM
+hostess/MDSG
+hostile/MYS
+hostilities/M
+hostility/SM
+hostler/MS
+hot/SYP
+hotbed/MS
+hotblooded
+hotbox/MS
+hotcake/SM
+hotdog/MS
+hotdogged
+hotdogging
+hotel/SM
+hotelier/MS
+hotfoot/MDGS
+hothead/DSM
+hotheaded/YP
+hotheadedness/M
+hothouse/SM
+hotkey/S
+hotline/MS
+hotlink/S
+hotness/M
+hotplate/SM
+hotpot/S
+hots/M
+hotshot/MS
+hotted
+hotter
+hottest
+hottie/S
+hotting
+hound/SGMD
+hour/MYS
+hourglass/MS
+houri/SM
+house's
+house/ADSG
+houseboat/SM
+housebound
+houseboy/SM
+housebreak/RSZG
+housebreaker/M
+housebreaking/M
+housebroke
+housebroken
+houseclean/DSG
+housecleaning/M
+housecoat/SM
+housefly/SM
+houseful/SM
+household/SMRZ
+householder/M
+househusband/SM
+housekeeper/MS
+housekeeping/M
+houselights/M
+housemaid/SM
+houseman/M
+housemaster/S
+housemate/S
+housemen
+housemistress/S
+housemother/SM
+houseparent/SM
+houseplant/MS
+houseproud
+houseroom
+housetop/SM
+housewares/M
+housewarming/SM
+housewife/MY
+housewives
+housework/M
+housing/MS
+hove
+hovel/SM
+hover/SGD
+hoverboard/MS
+hovercraft/MS
+how'd
+how're
+how/SM
+howbeit
+howdah/M
+howdahs
+howdy
+however
+howitzer/SM
+howl/MDRSZG
+howler/M
+howsoever
+howto/SM
+hoyden/MS
+hoydenish
+hp
+hr/S
+ht
+huarache/SM
+hub/SM
+hubbub/SM
+hubby/SM
+hubcap/SM
+hubris/M
+huckleberry/SM
+huckster/SGMD
+hucksterism/M
+huddle/DSMG
+hue/DSM
+huff/MDSG
+huffily
+huffiness/M
+huffy/PRT
+hug/STMR
+huge/YP
+hugeness/M
+hugged
+hugging
+huh
+hula/MS
+hulk/MSG
+hull/MDRSZG
+hullabaloo/SM
+huller/M
+hum/SM
+human/SMRYTP
+humane/PY
+humaneness/M
+humanism/M
+humanist/SM
+humanistic
+humanitarian/MS
+humanitarianism/M
+humanities/M
+humanity/ISM
+humanization/CM
+humanize/CDSG
+humanizer/SM
+humankind/M
+humanness/M
+humanoid/SM
+humble/DRSZTGJP
+humbleness/M
+humbler/M
+humbly
+humbug/SM
+humbugged
+humbugging
+humdinger/MS
+humdrum/M
+humeral
+humeri
+humerus/M
+humid/Y
+humidification/M
+humidifier/CM
+humidify/CZGDRS
+humidity/M
+humidor/SM
+humiliate/DSGNX
+humiliating/Y
+humiliation/M
+humility/M
+hummed
+hummer/SM
+humming
+hummingbird/SM
+hummock/SM
+hummocky
+hummus/M
+humongous
+humor/SMDG
+humoresque
+humorist/MS
+humorless/YP
+humorlessness/M
+humorous/PY
+humorousness/M
+hump/MDSG
+humpback/MDS
+humph/DG
+humphs
+humus/M
+hunch/MDSG
+hunchback/SMD
+hundred/SMH
+hundredfold
+hundredth/M
+hundredths
+hundredweight/SM
+hung
+hunger/SMDG
+hungover
+hungrily
+hungriness/M
+hungry/PRT
+hunk/MRSZ
+hunker/DG
+hunky/RT
+hunt/MDRSZG
+hunter/M
+hunting/M
+huntress/MS
+huntsman/M
+huntsmen
+hurdle/DRSMZG
+hurdler/M
+hurdling/M
+hurl/MDRSZG
+hurler/M
+hurling/M
+hurrah/GMD
+hurrahs
+hurray
+hurricane/MS
+hurried/UY
+hurry/DSMG
+hurt/MSG
+hurtful/YP
+hurtfulness/M
+hurtle/DSG
+husband/GMDS
+husbandman/M
+husbandmen
+husbandry/M
+hush/MDSG
+husk/MDRSZG
+husker/M
+huskily
+huskiness/M
+husky/PRSMT
+hussar/SM
+hussy/SM
+hustings/M
+hustle/DRSMZG
+hustler/M
+hut/SM
+hutch/MS
+huzza/GSMD
+huzzah/MDG
+huzzahs
+hwy
+hyacinth/M
+hyacinths
+hybrid/SM
+hybridism/M
+hybridization/M
+hybridize/DSG
+hydra/SM
+hydrangea/SM
+hydrant/MS
+hydrate's
+hydrate/CGNDS
+hydration/CM
+hydraulic/S
+hydraulically
+hydraulics/M
+hydride
+hydro/M
+hydrocarbon/MS
+hydrocephalus/M
+hydrochloride
+hydrocortisone
+hydrodynamic/S
+hydrodynamics/M
+hydroelectric
+hydroelectrically
+hydroelectricity/M
+hydrofoil/MS
+hydrogen/M
+hydrogenate/CGDS
+hydrogenation/M
+hydrogenous
+hydrologist/MS
+hydrology/M
+hydrolyses
+hydrolysis/M
+hydrolyze/DSG
+hydrometer/SM
+hydrometry/M
+hydrophilic
+hydrophobia/M
+hydrophobic
+hydrophone/SM
+hydroplane/GDSM
+hydroponic/S
+hydroponically
+hydroponics/M
+hydrosphere/M
+hydrotherapy/M
+hydrothermal
+hydrous
+hydroxide/SM
+hyena/SM
+hygiene/M
+hygienic/U
+hygienically
+hygienist/MS
+hygrometer/SM
+hying
+hymen/SM
+hymeneal
+hymn/MDSG
+hymnal/MS
+hymnbook/SM
+hype/MGDRS
+hyperactive
+hyperactivity/M
+hyperbola/SM
+hyperbole/M
+hyperbolic
+hypercritical/Y
+hypercube
+hyperglycemia/M
+hyperinflation
+hyperlink/GSMD
+hypermarket/S
+hypermedia/M
+hyperparathyroidism
+hyperplane
+hypersensitive/P
+hypersensitiveness/M
+hypersensitivity/SM
+hyperspace/S
+hypertension/M
+hypertensive/SM
+hypertext/M
+hyperthyroid/M
+hyperthyroidism/M
+hypertrophy/DSMG
+hyperventilate/GNDS
+hyperventilation/M
+hypervisor/MS
+hyphen/MDSG
+hyphenate/XDSMGN
+hyphenation/M
+hypnoses
+hypnosis/M
+hypnotherapist/S
+hypnotherapy/M
+hypnotic/SM
+hypnotically
+hypnotism/M
+hypnotist/MS
+hypnotize/GDS
+hypo/MS
+hypoallergenic
+hypochondria/M
+hypochondriac/SM
+hypocrisy/SM
+hypocrite/MS
+hypocritical/Y
+hypodermic/MS
+hypoglycemia/M
+hypoglycemic/SM
+hypotenuse/MS
+hypothalami
+hypothalamus/M
+hypothermia/M
+hypotheses
+hypothesis/M
+hypothesize/DSG
+hypothetical/Y
+hypothyroid/M
+hypothyroidism/M
+hyssop/M
+hysterectomy/SM
+hysteresis
+hysteria/M
+hysteric/SM
+hysterical/Y
+hysterics/M
+i/US
+iOS/M
+iPad/M
+iPhone/M
+iPod/MS
+iTunes/M
+iamb/MS
+iambi
+iambic/SM
+iambus/MS
+iatrogenesis
+iatrogenic
+ibex/MS
+ibid
+ibidem
+ibis/MS
+ibuprofen/M
+ice's
+ice/CDSG
+iceberg/SM
+iceboat/SM
+icebound
+icebox/MS
+icebreaker/SM
+icecap/SM
+iceman/M
+icemen
+ichthyologist/MS
+ichthyology/M
+icicle/SM
+icily
+iciness/M
+icing/SM
+icky/RT
+icon/MS
+iconic
+iconoclasm/M
+iconoclast/SM
+iconoclastic
+iconography/M
+ictus/M
+icy/TPR
+id/SMY
+idea/MS
+ideal/SMY
+idealism/M
+idealist/SM
+idealistic
+idealistically
+idealization/MS
+idealize/DSG
+idem
+idempotent
+identical/Y
+identifiable/U
+identification/M
+identified/U
+identify/ZGNDRSX
+identikit/S
+identity/SM
+ideogram/SM
+ideograph/M
+ideographs
+ideological/Y
+ideologist/SM
+ideologue/MS
+ideology/SM
+ides/M
+idiocy/SM
+idiom/SM
+idiomatic/U
+idiomatically
+idiopathic
+idiosyncrasy/SM
+idiosyncratic
+idiosyncratically
+idiot/SM
+idiotic
+idiotically
+idle/MZTGDRSP
+idleness/M
+idler/M
+idol/MS
+idolater/SM
+idolator/SM
+idolatress/MS
+idolatrous
+idolatry/M
+idolization/M
+idolize/GDS
+idyll/SM
+idyllic
+idyllically
+if/SM
+iffiness/M
+iffy/RTP
+iftar/S
+igloo/SM
+igneous
+ignite/ZGNBXDRS
+igniter/M
+ignition/M
+ignoble
+ignobly
+ignominious/Y
+ignominy/SM
+ignoramus/MS
+ignorance/M
+ignorant/Y
+ignore/GDS
+iguana/MS
+ii
+iii
+ilea
+ileitis/M
+ileum/M
+ilia
+ilium/M
+ilk/SM
+ill/SMP
+illegal/MYS
+illegality/SM
+illegibility/M
+illegible
+illegibly
+illegitimacy/M
+illegitimate/Y
+illiberal/Y
+illiberality/M
+illicit/YP
+illicitness/M
+illimitable
+illiteracy/M
+illiterate/MYS
+illness/MS
+illogical/Y
+illogicality/M
+illuminate/GNXDS
+illuminating/Y
+illumination/M
+illumine/DSBG
+illus/V
+illusion/EMS
+illusionist/SM
+illusory
+illustrate/GNVXDS
+illustration/M
+illustrative/Y
+illustrator/SM
+illustrious/PY
+illustriousness/M
+image/DSMG
+imagery/M
+imaginable/U
+imaginably/U
+imaginal
+imaginary
+imagination/MS
+imaginative/UY
+imagine/DSBJG
+imago/M
+imagoes
+imam/MS
+imbalance/DSM
+imbecile/MS
+imbecilic
+imbecility/SM
+imbibe/ZGDRS
+imbiber/M
+imbrication/M
+imbroglio/SM
+imbue/DSG
+imitable/I
+imitate/DSGNVX
+imitation/M
+imitative/PY
+imitativeness/M
+imitator/SM
+immaculate/PY
+immaculateness/M
+immanence/M
+immanency/M
+immanent/Y
+immaterial/YP
+immateriality/M
+immaterialness/M
+immature/Y
+immaturity/M
+immeasurable
+immeasurably
+immediacies/M
+immediacy/SM
+immediate/PY
+immediateness/M
+immemorial/Y
+immense/Y
+immensity/SM
+immerse/XDSGNV
+immersible
+immersion/M
+immigrant/SM
+immigrate/DSGN
+immigration/M
+imminence/M
+imminent/Y
+immobile
+immobility/M
+immobilization/M
+immobilize/ZGDRS
+immoderate/Y
+immodest/Y
+immodesty/M
+immolate/DSGN
+immolation/M
+immoral/Y
+immorality/SM
+immortal/MYS
+immortality/M
+immortalize/DSG
+immovability/M
+immovable
+immovably
+immune
+immunity/M
+immunization/SM
+immunize/GDS
+immunodeficiency/M
+immunodeficient
+immunoglobulin/S
+immunologic
+immunological
+immunologist/MS
+immunology/M
+immure/DSG
+immutability/M
+immutable
+immutably
+imp/SMR
+impact/SMDG
+impactful
+impaction
+impair/SDGL
+impaired/U
+impairment/MS
+impala/SM
+impale/DSGL
+impalement/M
+impalpable
+impalpably
+impanel/SDG
+impart/SDG
+impartial/Y
+impartiality/M
+impassably
+impasse/BSMV
+impassibility/M
+impassible
+impassibly
+impassioned
+impassive/YP
+impassiveness/M
+impassivity/M
+impasto/M
+impatience/MS
+impatiens/M
+impatient/Y
+impeach/ZGBLDRS
+impeachable/U
+impeacher/M
+impeachment/SM
+impeccability/M
+impeccable
+impeccably
+impecunious/PY
+impecuniousness/M
+impedance/M
+impede/DSG
+impeded/U
+impediment/SM
+impedimenta/M
+impel/S
+impelled
+impeller/MS
+impelling
+impend/SDG
+impenetrability/M
+impenetrable
+impenetrably
+impenitence/M
+impenitent/Y
+imperative/SMY
+imperceptibility/M
+imperceptible
+imperceptibly
+imperceptive
+imperf
+imperfect/SMYP
+imperfection/MS
+imperfectness/M
+imperial/MYS
+imperialism/M
+imperialist/SM
+imperialistic
+imperialistically
+imperil/GSLD
+imperilment/M
+imperious/PY
+imperiousness/M
+imperishable
+imperishably
+impermanence/M
+impermanent/Y
+impermeability/M
+impermeable
+impermeably
+impermissible
+impersonal/Y
+impersonate/GNXDS
+impersonation/M
+impersonator/SM
+impertinence/MS
+impertinent/Y
+imperturbability/M
+imperturbable
+imperturbably
+impervious/Y
+impetigo/M
+impetuosity/M
+impetuous/YP
+impetuousness/M
+impetus/MS
+impiety/SM
+impinge/LDSG
+impingement/M
+impious/PY
+impiousness/M
+impish/YP
+impishness/M
+implacability/M
+implacable
+implacably
+implant/BSGMD
+implantation/M
+implausibility/SM
+implausible
+implausibly
+implement/ZGBMDRS
+implementable/U
+implementation/SM
+implemented/U
+implicate/DSG
+implication/M
+implicit/PY
+implicitness/M
+implode/DSG
+implore/DSG
+imploring/Y
+implosion/MS
+implosive
+imply/XDSGN
+impolite/YP
+impoliteness/MS
+impolitic
+imponderable/MS
+import/ZGBSMDR
+importance/M
+important/Y
+importation/MS
+importer/M
+importunate/Y
+importune/GDS
+importunity/M
+impose/ADSG
+imposer/MS
+imposing/U
+imposingly
+imposition/MS
+impossibility/SM
+impossible/S
+impossibly
+impost/ZSMR
+imposter/M
+impostor/SM
+imposture/MS
+impotence/M
+impotency/M
+impotent/Y
+impound/DGS
+impoverish/DSLG
+impoverishment/M
+impracticability
+impracticable
+impracticably
+impractical/Y
+impracticality/M
+imprecate/DSXGN
+imprecation/M
+imprecise/PYN
+impreciseness/M
+imprecision/M
+impregnability/M
+impregnable
+impregnably
+impregnate/GNDS
+impregnation/M
+impresario/SM
+impress/MDSGV
+impressed/U
+impressibility/M
+impressible
+impression/BSM
+impressionability/M
+impressionism/M
+impressionist/SM
+impressionistic
+impressive/PY
+impressiveness/M
+imprimatur/SM
+imprint/MDRZGS
+imprinter/M
+imprison/SDLG
+imprisonment/SM
+improbability/SM
+improbable
+improbably
+impromptu/SM
+improper/Y
+impropriety/SM
+improve/GBDSL
+improved/U
+improvement/MS
+improvidence/M
+improvident/Y
+improvisation/SM
+improvisational
+improvise/ZGDRS
+improviser/M
+improvisor/SM
+imprudence/M
+imprudent/Y
+impudence/M
+impudent/Y
+impugn/ZGSDR
+impugner/M
+impulse/MGNVDS
+impulsion/M
+impulsive/PY
+impulsiveness/M
+impulsivity
+impunity/M
+impure/RYT
+impurity/SM
+imputation/SM
+impute/BDSG
+in/ASM
+inaccuracy/S
+inaction/M
+inadequacy/S
+inadvertence/M
+inadvertent/Y
+inalienability/M
+inalienably
+inamorata/SM
+inane/RYT
+inanimate/PY
+inanimateness/M
+inanity/SM
+inappropriate/Y
+inarticulate/Y
+inasmuch
+inaudible
+inaugural/SM
+inaugurate/XGNDS
+inauguration/M
+inboard/MS
+inbound
+inbox/MS
+inbreed/S
+inc/TGD
+incalculably
+incandescence/M
+incandescent/Y
+incantation/SM
+incapacitate/GNDS
+incarcerate/XDSGN
+incarceration/M
+incarnadine/DSG
+incarnate/AXGNDS
+incarnation/AM
+incendiary/SM
+incense/MGDS
+incentive's
+incentive/ES
+incentivize/EDSG
+inception/SM
+incessant/Y
+incest/M
+incestuous/PY
+incestuousness/M
+inch/MDSG
+inchoate
+inchworm/SM
+incidence/SM
+incident/SM
+incidental/MYS
+incinerate/DSGN
+incineration/M
+incinerator/MS
+incipience/M
+incipient/Y
+incise/XGNVDS
+incision/M
+incisive/PY
+incisiveness/M
+incisor/MS
+incitement/MS
+inciter/MS
+incl
+inclement
+inclination/EM
+inclinations
+incline's
+incline/EGDS
+include/GDS
+inclusion/MS
+inclusive/YP
+inclusiveness/M
+incognito/MS
+incombustible
+incommode/GD
+incommodious
+incommunicado
+incompetent/MS
+incomplete/Y
+inconceivability/M
+incongruous/PY
+incongruousness/M
+inconsolably
+inconstant/Y
+incontestability/M
+incontestably
+incontinent
+incontrovertibly
+inconvenience/GD
+incorporate/ADSGN
+incorporated/U
+incorporation/AM
+incorporator/S
+incorporeal
+incorrect/Y
+incorrigible/P
+incorrigibly
+increasing/Y
+increment/SMDG
+incremental/Y
+incrementalism
+incrementalist/SM
+incriminate/GNDS
+incrimination/M
+incriminatory
+incrustation/SM
+incubate/GNDS
+incubation/M
+incubator/SM
+incubus/MS
+inculcate/DSGN
+inculcation/M
+inculpate/DSG
+incumbency/SM
+incumbent/SM
+incunabula
+incunabulum/M
+incur/SB
+incurable/MS
+incurably
+incurious
+incurred
+incurring
+incursion/MS
+ind
+indebted/P
+indebtedness/M
+indeed
+indefatigable
+indefatigably
+indefeasible
+indefeasibly
+indefinably
+indelible
+indelibly
+indemnification/M
+indemnify/GDSXN
+indemnity/SM
+indentation/MS
+indention/M
+indenture/DG
+indescribably
+indestructibly
+indeterminably
+indeterminacy/M
+indeterminate/Y
+index/ZGMDRS
+indexation/SM
+indexer/M
+indicate/XDSGNV
+indication/M
+indicative/SMY
+indicator/MS
+indict/GDSBL
+indictment/SM
+indie/S
+indigence/M
+indigenous
+indigent/SMY
+indignant/Y
+indignation/M
+indigo/M
+indirect/Y
+indiscipline
+indiscreet/Y
+indiscretion/S
+indiscriminate/Y
+indispensability/M
+indispensable/MS
+indispensably
+indissolubility
+indissolubly
+indistinguishably
+indite/GDS
+indium/M
+individual/MYS
+individualism/M
+individualist/MS
+individualistic
+individualistically
+individuality/M
+individualization/M
+individualize/GDS
+individuate/DSGN
+individuation/M
+indivisibly
+indoctrinate/GNDS
+indoctrination/M
+indolence/M
+indolent/Y
+indomitable
+indomitably
+indubitable
+indubitably
+induce/DRSZGL
+inducement/SM
+inducer/M
+induct/DGV
+inductance/M
+inductee/SM
+induction/MS
+inductive/Y
+inductor/SM
+indue/DG
+indulge/DSG
+indulgence/SM
+indulgent/Y
+industrial/Y
+industrialism/M
+industrialist/SM
+industrialization/M
+industrialize/DSG
+industrious/YP
+industriousness/M
+industry/SM
+indwell/SG
+inebriate/MGNDS
+inebriation/M
+inedible
+ineffability/M
+ineffable
+ineffably
+inelastic
+ineligible/MS
+ineligibly
+ineluctable
+ineluctably
+inept/YP
+ineptitude/M
+ineptness/M
+inequality/S
+inert/YP
+inertia/M
+inertial
+inertness/M
+inescapable
+inescapably
+inestimably
+inevitability/M
+inevitable/M
+inevitably
+inexact/Y
+inexhaustibly
+inexorability
+inexorable
+inexorably
+inexpedient
+inexpert/Y
+inexpiable
+inexplicably
+inexpressibly
+inexpressive
+inextricably
+inf/ZT
+infallible
+infamy/SM
+infancy/M
+infant/MS
+infanticide/MS
+infantile
+infantry/SM
+infantryman/M
+infantrymen
+infarct/MS
+infarction/M
+infatuate/DSXGN
+infatuation/M
+infect/AESDG
+infected/U
+infection/ASM
+infectious/PY
+infectiousness/M
+infelicitous
+inference/SM
+inferential
+inferior/MS
+inferiority/M
+infernal/Y
+inferno/MS
+inferred
+inferring
+infest/GDS
+infestation/MS
+infidel/MS
+infidelity/S
+infiltrator/SM
+infinite/MV
+infinitesimal/SMY
+infinitival
+infinitive/MS
+infinitude/M
+infinitum
+infinity/SM
+infirm
+infirmary/SM
+infirmity/SM
+infix
+inflame/DSG
+inflammable
+inflammation/SM
+inflammatory
+inflatable/SM
+inflate/ADSG
+inflation/EM
+inflationary
+inflect/SDG
+inflection/MS
+inflectional
+inflict/SDGV
+infliction/M
+inflight
+inflow/SM
+influence/MGDS
+influenced/U
+influential/Y
+influenza/M
+influx/MS
+info/M
+infomercial/SM
+inform/Z
+informal/Y
+informant/SM
+informatics
+information/EM
+informational
+informative/PY
+informativeness/M
+informed/U
+infotainment/M
+infra
+infrared/M
+infrasonic
+infrastructural
+infrastructure/SM
+infrequence/M
+infrequent/Y
+infringe/LZR
+infringement/MS
+infuriate/GDS
+infuriating/Y
+infuser/SM
+ingenious/PY
+ingeniousness/M
+ingenue/SM
+ingenuity/M
+ingenuous/EY
+ingenuousness/M
+ingest/SDG
+ingestion/M
+inglenook/SM
+ingot/SM
+ingrain/G
+ingrate/SM
+ingratiate/GNDS
+ingratiating/Y
+ingratiation/M
+ingredient/MS
+ingress/MS
+inguinal
+ingnue/SM
+inhabit/DG
+inhabitable/U
+inhabitant/SM
+inhabited/U
+inhalant/SM
+inhalation/MS
+inhalator/MS
+inhaler/SM
+inharmonious
+inhere/DSG
+inherent/Y
+inherit/EGSD
+inheritance/EM
+inheritances
+inheritor/SM
+inhibit/GSD
+inhibition/SM
+inhibitor/SM
+inhibitory
+inhuman/Y
+inhumane/Y
+inimical/Y
+inimitably
+iniquitous/Y
+iniquity/SM
+initial/SGMDY
+initialism/S
+initialization
+initialize/DRSZG
+initialized/AU
+initiate/XMGNVDS
+initiated/U
+initiation/M
+initiative/SM
+initiator/MS
+initiatory
+initio
+inject/SDG
+injection/SM
+injector/SM
+injunctive
+injure/DRSZG
+injured/U
+injurer/M
+injurious
+ink/MD
+inkblot/SM
+inkiness/M
+inkjet/SM
+inkling/SM
+inkstand/SM
+inkwell/MS
+inky/RTP
+inland/M
+inline
+inmate/SM
+inmost
+inn/SGMRJ
+innards/M
+innate/PY
+innateness/M
+innermost
+innersole/SM
+innerspring
+innervate/GNDS
+innervation/M
+inning/M
+innit
+innkeeper/MS
+innocence/M
+innocent/MYS
+innocuous/PY
+innocuousness/M
+innovate/XDSGNV
+innovation/M
+innovator/MS
+innovatory
+innuendo/SM
+innuendoes
+innumerably
+innumerate
+inoculate/AGDS
+inoculation/MS
+inoperative
+inordinate/Y
+inorganic
+inositol
+inquire/ZGDR
+inquirer/M
+inquiring/Y
+inquiry/SM
+inquisition/MS
+inquisitional
+inquisitive/YP
+inquisitiveness/M
+inquisitor/SM
+inquisitorial
+inrush/MS
+insane/T
+insatiability/M
+insatiably
+inscribe/ZGDR
+inscriber/M
+inscription/MS
+inscrutability/M
+inscrutable/P
+inscrutableness/M
+inscrutably
+inseam/SM
+insecticidal
+insecticide/MS
+insectivore/MS
+insectivorous
+insecure/Y
+inseminate/DSGN
+insemination/M
+insensate
+insensible
+insensitive/Y
+insentient
+inseparable/MS
+insert's
+insert/AGSD
+insertion/AM
+insertions
+insetting
+inshore
+inside/RSMZ
+insider/M
+insidious/YP
+insidiousness/M
+insight/MS
+insightful
+insignia/SM
+insinuate/GNVDSX
+insinuation/M
+insinuator/SM
+insipid/PY
+insipidity/M
+insist/SGD
+insistence/M
+insistent/Y
+insisting/Y
+insofar
+insole/SM
+insolence/M
+insolent/Y
+insoluble
+insolubly
+insolvency/S
+insomnia/M
+insomniac/SM
+insomuch
+insouciance/M
+insouciant
+inspect/AGDS
+inspection/SM
+inspector/MS
+inspectorate/MS
+inspiration/MS
+inspirational
+inspiratory
+inspired/U
+inspiring/U
+inst
+instability/S
+install/UBZRSDG
+installation/MS
+installer/UM
+installment/SM
+instance/GD
+instant/MRYS
+instantaneous/Y
+instantiate/DSXGN
+instar
+instate/AGDS
+instead
+instigate/DSGN
+instigation/M
+instigator/MS
+instillation/M
+instinct/VMS
+instinctive/Y
+instinctual
+institute/XMZGNDRS
+instituter/M
+institution/M
+institutional/Y
+institutionalization/M
+institutionalize/DSG
+institutor/MS
+instr
+instruct/SDGV
+instructed/U
+instruction/MS
+instructional
+instructive/Y
+instructor/MS
+instrument/MDSG
+instrumental/MYS
+instrumentalist/SM
+instrumentality/M
+instrumentation/M
+insubordinate
+insufferable
+insufferably
+insula
+insular
+insularity/M
+insulate/GNDS
+insulation/M
+insulator/MS
+insulin/M
+insult/SMDG
+insulting/Y
+insuperable
+insuperably
+insurance/SM
+insure/DRSZGB
+insured/SM
+insurer/M
+insurgence/SM
+insurgency/SM
+insurgent/MS
+insurmountably
+insurrection/SM
+insurrectionist/SM
+int
+intact
+intaglio/MS
+integer/MS
+integral/SMY
+integrand
+integrate/AEVNGXSD
+integration/AEM
+integrationist/SM
+integrator
+integrity/M
+integument/SM
+intel/M
+intellect/MS
+intellectual/MYS
+intellectualism/M
+intellectualize/GDS
+intelligence/M
+intelligent/Y
+intelligentsia/M
+intelligibility/M
+intelligible/U
+intelligibly/U
+intended/SM
+intense/YTVR
+intensification/M
+intensifier/M
+intensify/DRSZGN
+intensity/S
+intensive/MYPS
+intensiveness/M
+intent/SMYP
+intention/MS
+intentional/UY
+intentness/M
+inter/ESL
+interact/SGVD
+interaction/SM
+interactive/Y
+interactivity
+interbred
+interbreed/GS
+intercede/GDS
+intercellular
+intercept/GMDS
+interception/MS
+interceptor/SM
+intercession/SM
+intercessor/MS
+intercessory
+interchange/DSMG
+interchangeability
+interchangeable
+interchangeably
+intercity
+intercollegiate
+intercom/SM
+intercommunicate/DSGN
+intercommunication/M
+interconnect/GDS
+interconnection/SM
+intercontinental
+intercourse/M
+intercultural
+interdenominational
+interdepartmental
+interdependence/M
+interdependent/Y
+interdict/GMDS
+interdiction/M
+interdisciplinary
+interest/ESMD
+interested/U
+interesting/Y
+interface/MGDS
+interfaith
+interfere/GDS
+interference/M
+interferon/M
+interfile/GDS
+intergalactic
+intergovernmental
+interim/M
+interior/SM
+interj
+interject/GDS
+interjection/SM
+interlace/GDS
+interlard/DGS
+interleave/DSG
+interleukin/M
+interline/GDSJ
+interlinear
+interlining/M
+interlink/DSG
+interlock/GMDS
+interlocutor/SM
+interlocutory
+interlope/ZGDRS
+interloper/M
+interlude/MGDS
+intermarriage/SM
+intermarry/GDS
+intermediacy/S
+intermediary/SM
+intermediate/XMYGNPDS
+intermediation/ES
+intermediator/MS
+interment/EM
+interments
+intermezzi
+intermezzo/MS
+interminably
+intermingle/DSG
+intermission/SM
+intermittence/S
+intermittency/S
+intermittent/Y
+intermix/GDS
+intermolecular/Y
+internal/SY
+internalization/M
+internalize/GDS
+international/SMY
+internationalism/M
+internationalist/SM
+internationalization
+internationalize/DSG
+interne/GDL
+internecine
+internee/SM
+interneship/S
+internet
+internist/MS
+internment/M
+internship/MS
+interoffice
+interoperability
+interoperable
+interoperate/S
+interpenetrate/DSGN
+interpersonal
+interplanetary
+interplay/M
+interpolate/XDSGN
+interpolation/M
+interpose/GDS
+interposition/M
+interpret/AGVDS
+interpretation/AMS
+interpretative
+interpreted/U
+interpreter/MS
+interquartile
+interracial
+interred/E
+interregnum/SM
+interrelate/XDSGN
+interrelation/M
+interrelationship/MS
+interring/E
+interrogate/DSGNVX
+interrogation/M
+interrogative/MYS
+interrogator/SM
+interrogatory/SM
+interrupt/ZGMDRS
+interrupter/M
+interruptible/U
+interruption/MS
+interscholastic
+intersect/GDS
+intersection/SM
+intersectional
+intersectionality
+intersession/SM
+intersex
+intersexual/MS
+intersexualism
+intersexuality
+intersperse/GNDS
+interspersion/M
+interstate/MS
+interstellar
+interstice/MS
+interstitial
+intertwine/GDS
+interurban
+interval/SM
+intervene/GDS
+intervention/SM
+interventionism/M
+interventionist/SM
+interview/ZGMDRS
+interviewee/MS
+interviewer/M
+intervocalic
+interwar
+interweave/GS
+interwove
+interwoven
+intestacy/M
+intestate
+intestinal
+intestine/MS
+intifada/S
+intimacy/SM
+intimate/MYGNDSX
+intimation/M
+intimidate/GNDS
+intimidating/Y
+intimidation/M
+intl
+intonation/SM
+intoxicant/SM
+intoxicate/DSGN
+intoxication/M
+intracranial
+intramural
+intramuscular
+intranet/MS
+intransigence/M
+intransigent/MYS
+intrastate
+intrauterine
+intravenous/MSY
+intrepid/Y
+intrepidity/M
+intricacy/SM
+intricate/Y
+intrigue/DRSMZG
+intriguer/M
+intriguing/Y
+intrinsic
+intrinsically
+intro/SM
+introduce/AGDS
+introduction/AM
+introductions
+introductory
+introit/SM
+introspect/GVDS
+introspection/M
+introspective/Y
+introversion/M
+introvert/MDS
+intrude/DRSZG
+intruder/M
+intrusion/SM
+intrusive/YP
+intrusiveness/M
+intuit/SDGV
+intuition/S
+intuitive/PY
+intuitiveness/M
+inundate/XDSGN
+inundation/M
+inure/DSG
+invade/DRSZG
+invader/M
+invalid/GMDYS
+invalidism/M
+invaluable
+invaluably
+invariant
+invasion/MS
+invasive
+invective/M
+inveigh/GD
+inveighs
+inveigle/ZGDRS
+inveigler/M
+invent/ASGVD
+invention/AMS
+inventive/PY
+inventiveness/M
+inventor/MS
+inventory/DSMG
+inverse/SMY
+invert/SMDRZG
+inverter/M
+invertible
+invest/ASDGL
+investigate/GNVDSX
+investigation/M
+investigator/SM
+investigatory
+investiture/MS
+investment/AEM
+investor/SM
+inveteracy/M
+inveterate
+invidious/YP
+invidiousness/M
+invigilate/GNDS
+invigilator/S
+invigorate/ADSG
+invigorating/Y
+invigoration/M
+invincibility/M
+invincibly
+inviolability/M
+inviolably
+inviolate
+invitation/SM
+invitational/SM
+invite/DSMG
+invited/U
+invitee/SM
+inviting/Y
+invoke/DSG
+involuntariness/M
+involuntary/P
+involution/M
+involve/LDSG
+involved/U
+involvement/SM
+inward/SY
+ioctl
+iodide/SM
+iodine/M
+iodize/DSG
+ion/USM
+ionic
+ionization/UM
+ionize/UDSG
+ionizer/MS
+ionosphere/MS
+ionospheric
+iota/MS
+ipecac/SM
+irascibility/M
+irascible
+irascibly
+irate/YP
+irateness/M
+ire/M
+ireful
+irenic
+irides
+iridescence/M
+iridescent/Y
+iridium/M
+iris/MS
+irk/SGD
+irksome/YP
+irksomeness/M
+iron/MDSG
+ironclad/MS
+ironic/U
+ironical/Y
+ironically/U
+ironing/M
+ironmonger/S
+ironmongery
+ironstone/M
+ironware/M
+ironwood/MS
+ironwork/M
+irony/SM
+irradiate/DSGN
+irradiation/M
+irrational/SMY
+irrationality/M
+irreclaimable
+irreconcilability/M
+irreconcilable
+irreconcilably
+irrecoverable
+irrecoverably
+irredeemable
+irredeemably
+irreducible
+irreducibly
+irrefutable
+irrefutably
+irregular/MYS
+irregularity/SM
+irrelevance/MS
+irrelevancy/MS
+irrelevant/Y
+irreligion
+irreligious
+irremediable
+irremediably
+irremovable
+irreparable
+irreparably
+irreplaceable
+irrepressible
+irrepressibly
+irreproachable
+irreproachably
+irresistible
+irresistibly
+irresolute/PYN
+irresoluteness/M
+irresolution/M
+irrespective
+irresponsibility/M
+irresponsible
+irresponsibly
+irretrievable
+irretrievably
+irreverence/M
+irreverent/Y
+irreversible
+irreversibly
+irrevocability
+irrevocable/P
+irrevocably
+irrigable
+irrigate/DSGN
+irrigation/M
+irritability/M
+irritable
+irritably
+irritant/SM
+irritate/DSXGN
+irritating/Y
+irritation/M
+irrupt/DGVS
+irruption/SM
+ischemia
+ischemic
+isinglass/M
+isl
+island/SZMR
+islander/M
+isle/MS
+islet/SM
+ism/CM
+isms
+isn't
+isobar/MS
+isobaric
+isolate/DSMGN
+isolation/M
+isolationism/M
+isolationist/SM
+isomer/MS
+isomeric
+isomerism/M
+isometric/S
+isometrically
+isometrics/M
+isometry
+isomorphic
+isomorphism
+isosceles
+isospin/S
+isotherm/SM
+isotope/SM
+isotopic
+isotropic
+issuance/M
+issue/ADSMG
+issuer/MS
+isthmian
+isthmus/MS
+it'd
+it'll
+it/USM
+ital
+italic/SM
+italicization/M
+italicize/GDS
+italics/M
+itch/MDSG
+itchiness/M
+itchy/RPT
+item/MS
+itemization/M
+itemize/GDS
+iterate/AXGNVDS
+iteration/AM
+iterative/Y
+iterator/S
+itinerant/SM
+itinerary/SM
+itself
+iv/U
+ivory/SM
+ivy/DSM
+ix
+j/F
+jab/SM
+jabbed
+jabber/SMDRZG
+jabberer/M
+jabbing
+jabot/SM
+jacaranda/MS
+jack/MDGS
+jackal/SM
+jackass/MS
+jackboot/SMD
+jackdaw/MS
+jacket/SMD
+jackhammer/MS
+jackknife/MGDS
+jackknives
+jackpot/MS
+jackrabbit/MS
+jackstraw/MS
+jacquard/M
+jade/MGDS
+jaded/PY
+jadedness/M
+jadeite/M
+jag/SM
+jagged/TPRY
+jaggedness/M
+jaggies
+jaguar/SM
+jail/MDRZGS
+jailbird/SM
+jailbreak/SM
+jailer/M
+jailhouse/S
+jalapeno/MS
+jalapeo/MS
+jalopy/SM
+jalousie/MS
+jam/SM
+jamb/MS
+jambalaya/M
+jamboree/MS
+jammed
+jamming
+jammy/RT
+jangle/DRSMZG
+jangler/M
+janitor/SM
+janitorial
+japan/SM
+japanned
+japanning
+jape/MGDS
+japonica
+jar/SM
+jardiniere/SM
+jardinire/SM
+jarful/MS
+jargon/M
+jarred
+jarring/Y
+jasmine/SM
+jasper/M
+jato/MS
+jaundice/DSMG
+jaunt/SGMD
+jauntily
+jauntiness/M
+jaunty/RPT
+java/M
+javelin/SM
+jaw/SGMD
+jawbone/DSMG
+jawbreaker/MS
+jawline/S
+jay/SM
+jaybird/SM
+jaywalk/DRSZG
+jaywalker/M
+jaywalking/M
+jazz/MDSG
+jazzy/TR
+jct
+jealous/Y
+jealousy/SM
+jean/MS
+jeans/M
+jeep/MS
+jeer/MDSG
+jeering/MY
+jeez
+jejuna
+jejune
+jejunum/M
+jell/DSG
+jello/SM
+jelly/GDSM
+jellybean/MS
+jellyfish/MS
+jellylike
+jellyroll/SM
+jemmy/GDS
+jennet/MS
+jenny/SM
+jeopardize/GDS
+jeopardy/M
+jeremiad/MS
+jerk/MDSG
+jerkily
+jerkin/MS
+jerkiness/M
+jerkwater
+jerky/TRMP
+jeroboam/S
+jerrican/S
+jerrybuilt
+jerrycan/S
+jersey/MS
+jest/MDRSZG
+jester/M
+jesting/Y
+jet/SM
+jetliner/SM
+jetport/MS
+jetsam/M
+jetted
+jetting
+jettison/MDSG
+jetty/SM
+jewel/SZGMDR
+jeweler/M
+jewellery
+jewelry/SM
+jg
+jib/SGMD
+jibbed
+jibbing
+jibe/MS
+jiff/MS
+jiffy/SM
+jig's
+jig/AS
+jigged/A
+jigger's
+jigger/ASDG
+jigging/A
+jiggle/DSMG
+jiggly
+jigsaw/SMDG
+jihad/SM
+jihadist/SM
+jilt/MDSG
+jimmy/DSMG
+jimsonweed/M
+jingle/DSMG
+jingly
+jingoism/M
+jingoist/SM
+jingoistic
+jink/DSG
+jinn/MS
+jinni/M
+jinricksha/SM
+jinrikisha/SM
+jinx/MDSG
+jitney/SM
+jitter/SDG
+jitterbug/MS
+jitterbugged
+jitterbugger/M
+jitterbugging
+jitters/M
+jittery/RT
+jive/MGDS
+job/SM
+jobbed
+jobber/SM
+jobbing
+jobholder/MS
+jobless/P
+joblessness/M
+jobshare/S
+jobsworth
+jobsworths
+jock/MS
+jockey/SGMD
+jockstrap/MS
+jocose/PY
+jocoseness/M
+jocosity/M
+jocular/Y
+jocularity/M
+jocund/Y
+jocundity/M
+jodhpurs/M
+joey/S
+jog/SM
+jogged
+jogger/SM
+jogging/M
+joggle/DSMG
+john/MS
+johnny/SM
+johnnycake/MS
+join's
+join/AFDSG
+joiner/FMS
+joinery/M
+joint's
+joint/EGSD
+jointly/F
+joist/SM
+jojoba
+joke/MZGDRS
+joker/M
+jokester/S
+jokey
+jokier
+jokiest
+joking/Y
+jollification/SM
+jollily
+jolliness/M
+jollity/M
+jolly/TGPDRSM
+jolt/MDRSZG
+jolter/M
+jonquil/SM
+josh/MDRSZG
+josher/M
+jostle/MGDS
+jot/SM
+jotted
+jotter/MS
+jotting/MS
+joule/SM
+jounce/MGDS
+jouncy
+journal/MS
+journalese/M
+journalism/M
+journalist/SM
+journalistic
+journey/ZGMDRS
+journeyer/M
+journeyman/M
+journeymen
+journo/S
+joust/SZGMDR
+jouster/M
+jousting/M
+jovial/Y
+joviality/M
+jowl/MS
+jowly/TR
+joy/SGMD
+joyful/YP
+joyfuller
+joyfullest
+joyfulness/M
+joyless/PY
+joylessness/M
+joyous/YP
+joyousness/M
+joyridden
+joyride/RSMZG
+joyrider/M
+joyriding/M
+joyrode
+joystick/SM
+jr
+jubilant/Y
+jubilation/M
+jubilee/SM
+judder/GDS
+judge's
+judge/ADSG
+judgement/SM
+judgemental
+judgeship/MS
+judgey
+judgment/SM
+judgmental/Y
+judgy
+judicatory/SM
+judicature/M
+judicial/Y
+judiciary/SM
+judicious/IYP
+judiciousness/IM
+judo/M
+jug/SM
+jugful/MS
+jugged
+juggernaut/SM
+jugging
+juggle/MZGDRS
+juggler/M
+jugglery/M
+jugular/SM
+juice/DRSMZG
+juicer/M
+juicily
+juiciness/M
+juicy/PTR
+jujitsu/M
+jujube/MS
+jukebox/MS
+julep/SM
+julienne
+jumble/MGDS
+jumbo/SM
+jump/MDRSZG
+jumper/M
+jumpily
+jumpiness/M
+jumpsuit/MS
+jumpy/TRP
+jun
+junco/SM
+junction/FISM
+juncture/FMS
+jungle/MS
+junior/MS
+juniper/SM
+junk/MDRSZG
+junker/M
+junket/MDRSZG
+junketeer/MS
+junketer/M
+junkie/M
+junky/TRSM
+junkyard/MS
+junta/SM
+juridic
+juridical/Y
+jurisdiction/SM
+jurisdictional
+jurisprudence/M
+jurist/MS
+juristic
+juror/FSM
+jury/ISM
+juryman/M
+jurymen
+jurywoman/M
+jurywomen
+just/RYPT
+justice/IMS
+justifiable/U
+justifiably/U
+justification/M
+justified/U
+justify/XGDSN
+justness/M
+jut/SM
+jute/M
+jutted
+jutting
+juvenile/SM
+juxtapose/DSG
+juxtaposition/SM
+k/IFGS
+kHz
+kW
+kWh
+kabbala
+kabbalah
+kabob/SM
+kabocha
+kaboom
+kabuki/M
+kaddish/MS
+kaffeeklatch/MS
+kaffeeklatsch/MS
+kahuna/S
+kaiser/MS
+kakistocracy
+kale/M
+kaleidoscope/MS
+kaleidoscopic
+kaleidoscopically
+kamikaze/MS
+kana
+kangaroo/MS
+kanji
+kaolin/M
+kapok/M
+kappa/SM
+kaput
+karakul/M
+karaoke/MS
+karat/SM
+karate/M
+karma/M
+karmic
+kart/MS
+katakana
+katydid/SM
+kayak/SMDG
+kayaking/M
+kayo/MDSG
+kazoo/SM
+kbps
+kc
+kebab/SM
+kebob/SM
+kedgeree
+keel/MDSG
+keelhaul/DGS
+keen/MDRYSTGP
+keenness/M
+keep/MRSZG
+keeper/M
+keeping/M
+keepsake/MS
+keester/S
+keg/SM
+keister/S
+kelp/M
+kelvin/SM
+ken/SM
+kenned
+kennel/SGMD
+kenning
+keno/M
+kepi/MS
+kept
+keratin/M
+keratitis
+kerbside
+kerchief/SM
+kerfuffle/S
+kern/G
+kerne
+kernel/SM
+kerosene/M
+kestrel/MS
+ketch/MS
+ketchup/M
+keto
+ketogenic
+ketone/S
+kettle/SM
+kettledrum/SM
+key/SGMD
+keybinding/S
+keyboard/ZGSMDR
+keyboarder/M
+keyboardist/SM
+keyhole/MS
+keylogger/MS
+keylogging/SM
+keynote/MZGDRS
+keynoter/M
+keypad/SM
+keypunch/ZGMDRS
+keypuncher/M
+keystone/MS
+keystroke/SM
+keyword/MS
+kg
+khaki/SM
+khan/MS
+kibble/DSMG
+kibbutz/MS
+kibbutzim
+kibibyte/SM
+kibitz/ZGDRS
+kibitzer/M
+kibosh/M
+kick/MDRSZG
+kickback/SM
+kickball/M
+kickboxing
+kicker/M
+kickoff/MS
+kickstand/MS
+kicky/RT
+kid/SM
+kidded
+kidder/SM
+kiddie/SM
+kidding
+kiddish
+kiddo/SM
+kidnap/S
+kidnapped
+kidnapper/MS
+kidnapping/MS
+kidney/SM
+kidskin/M
+kielbasa/MS
+kielbasi
+kike/S
+kill/JMDRSZG
+killdeer/SM
+killer/M
+killing/M
+killjoy/SM
+kiln/MDSG
+kilo/MS
+kilobyte/SM
+kilocoulomb/S
+kilocycle/SM
+kilogram/SM
+kilohertz/M
+kilojoule/S
+kiloliter/MS
+kilometer/MS
+kilonewton/S
+kilopascal/S
+kiloton/SM
+kilovolt/S
+kilowatt/SM
+kilt/MDRS
+kilter/M
+kimono/MS
+kin/M
+kinase
+kind's
+kind/UPRYT
+kinda
+kindergarten/MS
+kindergartner/SM
+kindergrtner/SM
+kindhearted/PY
+kindheartedness/M
+kindle/AGDS
+kindliness/M
+kindling/M
+kindly/URT
+kindness/UM
+kindnesses
+kindred/M
+kinds
+kine/S
+kinematic/S
+kinematics/M
+kinetic/S
+kinetically
+kinetics/M
+kinfolk/SM
+kinfolks/M
+king/MYS
+kingdom/SM
+kingfisher/SM
+kingly/RT
+kingmaker/S
+kingpin/SM
+kingship/M
+kink/MDSG
+kinkily
+kinkiness/M
+kinky/TPR
+kinsfolk/M
+kinship/M
+kinsman/M
+kinsmen
+kinswoman/M
+kinswomen
+kiosk/SM
+kip/SM
+kipped
+kipper/MDGS
+kipping
+kirsch/MS
+kismet/M
+kiss/MDRSBZG
+kisser/M
+kissoff/SM
+kissogram/S
+kit/SGMD
+kitbag/MS
+kitchen/SM
+kitchenette/MS
+kitchenware/M
+kite/MS
+kith/M
+kitsch/M
+kitschy
+kitted
+kitten/MS
+kittenish
+kitting
+kitty/SM
+kiwi/MS
+kiwifruit/MS
+kl
+klaxon/S
+kleptocracy
+kleptomania/M
+kleptomaniac/SM
+kludge/GDS
+kludgy
+kluge/DS
+klutz/MS
+klutziness/M
+klutzy/TRP
+km
+kn
+knack/SZMR
+knacker/GD
+knackwurst/MS
+knapsack/MS
+knave/SM
+knavery/M
+knavish/Y
+knead/SZGDR
+kneader/M
+knee/MDS
+kneecap/SM
+kneecapped
+kneecapping
+kneeing
+kneel/SG
+knell/SGMD
+knelt
+knew
+knicker/S
+knickerbockers/M
+knickers/M
+knickknack/MS
+knife/DSMG
+knight/MDYSG
+knighthood/MS
+knightliness/M
+knish/MS
+knit/MS
+knitted
+knitter/SM
+knitting/M
+knitwear/M
+knives
+knob/MS
+knobbly
+knobby/TR
+knock/SZGMDR
+knockabout
+knockdown/SM
+knocker/M
+knockoff/SM
+knockout/SM
+knockwurst/SM
+knoll/SM
+knot/MS
+knothole/SM
+knotted
+knotting
+knotty/TR
+know/SB
+knowing/UYS
+knowledge/M
+knowledgeable
+knowledgeably
+known
+knuckle/DSMG
+knuckleduster/S
+knucklehead/MS
+knurl/SGMD
+koala/SM
+koan/S
+kohl
+kohlrabi/M
+kohlrabies
+kola/MS
+kombucha
+kook/MS
+kookaburra/SM
+kookiness/M
+kooky/TPR
+kopeck/MS
+kopek/SM
+korma
+kosher/DSG
+kowtow/GMDS
+kph
+kraal/SM
+kraut/SM!
+krill/M
+krona/M
+krone/RM
+kronor
+kronur
+krypton/M
+kryptonite
+krna/M
+krnur
+kt
+kuchen/SM
+kudos/M
+kudzu/SM
+kumquat/MS
+kvetch/ZGMDRS
+kvetcher/M
+kw
+l/SDXTGJ
+la/M
+lab/SM
+label's
+label/ASDG
+labeled/U
+labelled/U
+labia
+labial/SM
+labile
+labium/M
+labor/SMDRZG
+laboratory/SM
+laborer/M
+laborious/PY
+laboriousness/M
+laborsaving
+laburnum/MS
+labyrinth/M
+labyrinthine
+labyrinths
+lac/M
+lace's
+lace/UGDS
+lacerate/DSGNX
+laceration/M
+lacewing/SM
+lacework/M
+lachrymal
+lachrymose
+lack/MDSG
+lackadaisical/Y
+lackey/SM
+lackluster
+laconic
+laconically
+lacquer/GMDS
+lacrimal
+lacrosse/M
+lactate/GNDS
+lactation/M
+lacteal
+lactic
+lactose/M
+lacuna/M
+lacunae
+lacy/RT
+lad/SGMDNJ
+ladder/GSMD
+laddie/SM
+laddish/P
+lade/S
+laden/U
+lading/M
+ladle/DSMG
+lady/SM
+ladybird/SM
+ladybug/MS
+ladyfinger/MS
+ladylike/U
+ladylove/MS
+ladyship/MS
+laetrile/M
+lag/SZMR
+lager/M
+laggard/MYS
+lagged
+lagging/M
+lagniappe/SM
+lagoon/SM
+laid/IA
+lain
+lair/MS
+laird/SM
+laissez-faire
+laity/M
+lake/MS
+lakefront/S
+lakeside
+lallygag/S
+lallygagged
+lallygagging
+lam/SM
+lama/MS
+lamasery/SM
+lamb/MDSG
+lambada/MS
+lambast/GDS
+lambaste/S
+lambda/SM
+lambency/M
+lambent/Y
+lambkin/SM
+lambskin/SM
+lambswool
+lame/MYZTGDRSP
+lamebrain/MDS
+lameness/M
+lament/BSMDG
+lamentably
+lamentation/MS
+lamina/M
+laminae
+laminar
+laminate/MGNDS
+lamination/M
+lammed
+lamming
+lamp/MS
+lampblack/M
+lamplight/MRZ
+lamplighter/M
+lampoon/SGMD
+lamppost/SM
+lamprey/MS
+lampshade/SM
+lanai/SM
+lance/DRSMZG
+lancer/M
+lancet/SM
+land/MDRSGJ
+landau/SM
+landfall/MS
+landfill/MS
+landholder/SM
+landholding/MS
+landing/M
+landlady/SM
+landless/M
+landline/MS
+landlocked
+landlord/MS
+landlubber/MS
+landmark/MS
+landmass/MS
+landmine/S
+landowner/MS
+landownership
+landowning/SM
+landscape/MZGDRS
+landscaper/M
+landslid
+landslide/MGS
+landslip/S
+landsman/M
+landsmen
+landward/S
+lane/MS
+language/MS
+langue/SM
+languid/PY
+languidness/M
+languish/DSG
+languor/SM
+languorous/Y
+lank/RYTP
+lankiness/M
+lankness/M
+lanky/RTP
+lanolin/M
+lantern/MS
+lanthanum/M
+lanyard/MS
+lap/SM
+laparoscopic
+laparoscopy
+laparotomy
+lapboard/SM
+lapdog/SM
+lapel/SM
+lapidary/SM
+lapin/SM
+lapped
+lappet/SM
+lapping
+lapse/AKGMSD
+laptop/SM
+lapwing/MS
+larboard/SM
+larcenist/SM
+larcenous
+larceny/SM
+larch/MS
+lard/MDRSZG
+larder/M
+lardy/RT
+large/RSPMYT
+largehearted
+largeness/M
+largess/M
+largish
+largo/SM
+lariat/SM
+lark/MDSG
+larkspur/SM
+larva/M
+larvae
+larval
+laryngeal
+larynges
+laryngitis/M
+larynx/M
+lasagna/MS
+lascivious/YP
+lasciviousness/M
+lase/ZGDRS
+laser/M
+lash/MDSGJ
+lashing/M
+lass/MS
+lassie/SM
+lassitude/M
+lasso/SMDG
+last/MDYSG
+lasting/UY
+lat/S
+latch's
+latch/UDSG
+latchkey/SM
+late/YTRP
+latecomer/MS
+latency/M
+lateness/M
+latent
+lateral/MDYSG
+latest/M
+latex/M
+lath/MDRSZG
+lathe/M
+lather/GMD
+lathery
+laths
+latices
+latish
+latitude/MS
+latitudinal
+latitudinarian/MS
+latrine/MS
+latte/RSM
+latter/MY
+lattice/MDS
+latticework/SM
+laud/MDSGB
+laudably
+laudanum/M
+laudatory
+laugh/BMDG
+laughably
+laughing/MY
+laughingstock/SM
+laughs
+laughter/M
+launch/AGMDS
+launcher/SM
+launchpad/SM
+launder/DRZGS
+launderer/M
+launderette/SM
+laundress/MS
+laundromat/MS
+laundry/SM
+laundryman/M
+laundrymen
+laundrywoman/M
+laundrywomen
+laureate/MS
+laureateship/M
+laurel/SM
+lav/SGD
+lava/M
+lavage/M
+lavaliere/SM
+lavatorial
+lavatory/SM
+lave/S
+lavender/SM
+lavish/PTGDRSY
+lavishness/M
+law/SM
+lawbreaker/SM
+lawbreaking/M
+lawful/UPY
+lawfulness/UM
+lawgiver/MS
+lawless/PY
+lawlessness/M
+lawmaker/MS
+lawmaking/M
+lawman/M
+lawmen
+lawn/MS
+lawnmower/SM
+lawrencium/M
+lawsuit/MS
+lawyer/SMY
+lax/TRYP
+laxative/MS
+laxity/M
+laxness/M
+lay/AICSGM
+layabout/S
+layaway/M
+layer/CSM
+layered
+layering/M
+layette/MS
+layman/M
+laymen
+layoff/SM
+layout/SM
+layover/MS
+laypeople
+layperson/MS
+layup/SM
+laywoman/M
+laywomen
+laze/MGDS
+lazily
+laziness/M
+lazy/DRSTGP
+lazybones/M
+lb/S
+lbw
+lea/SM
+leach/DSG
+leachate/S
+lead/MDNRSZG
+leader/M
+leaderless
+leadership/SM
+leading/M
+leaf/MDSG
+leafage/M
+leafless
+leaflet/GMDS
+leafstalk/MS
+leafy/RT
+league/DSMG
+leak/MDSG
+leakage/MS
+leakiness/M
+leaky/PRT
+lean/MDRSTGJP
+leaning/M
+leanness/M
+leap/MDRSZG
+leaper/M
+leapfrog/MS
+leapfrogged
+leapfrogging
+leapt
+learn/AUGDS
+learnability
+learnable
+learnedly
+learner/MS
+learning's
+learnt
+lease/ADSMG
+leaseback/SM
+leasehold/MRSZ
+leaseholder/M
+leaser/SM
+leash's
+leash/UDSG
+least/M
+leastwise
+leather/MS
+leatherette/M
+leatherneck/MS
+leathery
+leave/DRSMZGJ
+leaven/SGMD
+leavened/U
+leavening/M
+leaver/M
+leavings/M
+lech/MDRSZG
+lecher/M
+lecherous/PY
+lecherousness/M
+lechery/M
+lecithin/M
+lectern/MS
+lector/SM
+lecture/MZGDRS
+lecturer/M
+lectureship/SM
+lede
+ledge/RSMZ
+ledger/M
+lee/RSMZ
+leech/MDSG
+leek/MS
+leer/MDG
+leeriness/M
+leery/RPT
+leeward/SM
+leeway/M
+left/MRST
+leftism/M
+leftist/SM
+leftmost
+leftover/SM
+leftward/S
+lefty/SM
+leg/SM
+legacy/SM
+legal/SMY
+legalese/M
+legalism/MS
+legalistic
+legalistically
+legality/SM
+legalization/M
+legalize/GDS
+legate/CXMNS
+legatee/MS
+legation's/AC
+legato/SM
+legend/SM
+legendarily
+legendary
+legerdemain/M
+legged
+leggin/SM
+legginess/M
+legging/MS
+leggy/RPT
+leghorn/MS
+legibility/M
+legible
+legibly
+legion/SM
+legionary/SM
+legionnaire/SM
+legislate/DSGNV
+legislation/M
+legislative/Y
+legislator/MS
+legislature/SM
+legit
+legitimacy/M
+legitimate/DSYG
+legitimatize/GDS
+legitimization/M
+legitimize/DSG
+legless
+legman/M
+legmen
+legroom/SM
+legume/MS
+leguminous
+legwarmer/S
+legwork/M
+lei/SM
+leisure/DMY
+leisureliness/M
+leisurewear/M
+leitmotif/MS
+leitmotiv/MS
+lemma/S
+lemme/JG
+lemming/M
+lemon/SM
+lemonade/SM
+lemongrass
+lemony
+lemur/SM
+lend/RSZG
+lender/M
+length/MNX
+lengthen/GD
+lengthily
+lengthiness/M
+lengths
+lengthwise
+lengthy/PRT
+lenience/M
+leniency/M
+lenient/Y
+lenitive
+lens/MS
+lent
+lentil/MS
+lento
+leonine
+leopard/SM
+leopardess/MS
+leotard/SM
+leper/SM
+lepidopterist/MS
+leprechaun/MS
+leprosy/M
+leprous
+lepta
+lepton/MS
+lesbian/SM
+lesbianism/M
+lesion/MS
+less/MNRX
+lessee/MS
+lessen/GD
+lesson/MS
+lessor/MS
+let/ISM
+letdown/SM
+lethal/Y
+lethality
+lethargic
+lethargically
+lethargy/M
+letter/ZGMDRS
+letterbomb/S
+letterbox/S
+lettered/U
+letterer/M
+letterhead/MS
+lettering/M
+letterpress/M
+letting/S
+lettuce/MS
+letup/SM
+leucine
+leucotomy/S
+leukemia/M
+leukemic/SM
+leukocyte/MS
+levee/SM
+level/PSZGMDRY
+leveler/M
+levelheaded/P
+levelheadedness/M
+levelness/M
+lever/SGMD
+leverage's
+leverage/CDSG
+leviathan/MS
+levier/M
+levitate/DSGN
+levitation/M
+levity/M
+levy/DRSMZG
+lewd/RYPT
+lewdness/M
+lexer/S
+lexical
+lexicographer/MS
+lexicographic
+lexicographical
+lexicography/M
+lexicological
+lexicologist/M
+lexicology/SM
+lexicon/SM
+lexis
+lg
+liabilities
+liability/AM
+liable/A
+liaise/GDS
+liaison/MS
+liar/MS
+lib/M
+libation/SM
+libber/MS
+libel/SZGMDR
+libeler/M
+libelous
+liberal/MYPS
+liberalism/M
+liberality/M
+liberalization/SM
+liberalize/GDS
+liberalness/M
+liberate/CDSGN
+liberation/CM
+liberator/MS
+libertarian/SM
+libertine/MS
+liberty/SM
+libidinal
+libidinous
+libido/MS
+librarian/MS
+librarianship
+library/SM
+librettist/MS
+libretto/SM
+lice
+license/MGDS
+licensed/U
+licensee/MS
+licensor
+licentiate/SM
+licentious/YP
+licentiousness/M
+lichen/MS
+licit/Y
+lick/MDJSG
+licking/M
+licorice/SM
+lid/SM
+lidded
+lidless
+lido/MS
+lie/DSM
+lied/MR
+lief/RT
+liege/SM
+lien/MS
+lieu/M
+lieutenancy/M
+lieutenant/MS
+life/MZR
+lifebelt/S
+lifeblood/M
+lifeboat/MS
+lifebuoy/MS
+lifecycle
+lifeforms
+lifeguard/SM
+lifeless/YP
+lifelessness/M
+lifelike
+lifeline/MS
+lifelong
+lifer/M
+lifesaver/SM
+lifesaving/M
+lifespan/S
+lifestyle/SM
+lifetime/MS
+lifework/MS
+lift/MDRSZG
+lifter/M
+liftoff/SM
+ligament/MS
+ligate/GNDS
+ligation/M
+ligature/MGDS
+light's/C
+light/CASTGD
+lighted/U
+lighten/SDRZG
+lightener/M
+lighter/SM
+lightface/MD
+lightheaded
+lighthearted/YP
+lightheartedness/M
+lighthouse/MS
+lighting's
+lightly
+lightness/M
+lightning/MDS
+lightproof
+lightship/MS
+lightweight/SM
+ligneous
+lignin
+lignite/M
+lii
+likability/M
+likable/P
+likableness/M
+like/EMGDST
+likeability/M
+likeable/P
+likeableness/M
+likelihood/UM
+likelihoods
+likeliness/UM
+likely/UPRT
+liken/SGD
+likeness/UM
+likenesses
+liker
+likewise
+liking/M
+lilac/SM
+lilliputian
+lilo/S
+lilt/MDSG
+lily/SM
+limb/MS
+limber/UDSG
+limberness/M
+limbless
+limbo/SM
+lime/MGDS
+limeade/SM
+limelight/M
+limerick/SM
+limescale
+limestone/M
+limey/S
+limit's
+limit/CSZGDR
+limitation/CM
+limitations
+limited/U
+limiter's
+limiting/S
+limitless/P
+limitlessness/M
+limn/DSG
+limnological
+limnologist/MS
+limnology/M
+limo/MS
+limousine/MS
+limp/MDRYSPTG
+limpet/MS
+limpid/YP
+limpidity/M
+limpidness/M
+limpness/M
+limy/RT
+linage/M
+linchpin/SM
+linden/MS
+line/MZGDRSJ
+lineage/MS
+lineal/Y
+lineament/SM
+linear/Y
+linearity/M
+linebacker/MS
+lined/U
+linefeed
+lineman/M
+linemen
+linen/SM
+linens/M
+liner/M
+linesman/M
+linesmen
+lineup/MS
+ling/M
+linger/ZGJDRS
+lingerer/M
+lingerie/M
+lingering/Y
+lingo/M
+lingoes
+lingua
+lingual
+linguine/M
+linguini/SM
+linguist/SM
+linguistic/S
+linguistical/Y
+linguistics/M
+liniment/SM
+lining/M
+link's
+link/UDSG
+linkage/MS
+linker
+linkman
+linkmen
+linkup/MS
+linnet/MS
+lino
+linoleum/M
+linseed/M
+lint's
+lint/CDG
+lintel/MS
+lints
+linty/TR
+lion/MS
+lioness/MS
+lionhearted
+lionization/M
+lionize/GDS
+lip/SM
+lipid/SM
+liposuction/M
+lipped
+lippy
+lipread/GRS
+lipreader/M
+lipreading/M
+lipstick/MDSG
+liq
+liquefaction/M
+liquefy/DSG
+liqueur/SM
+liquid/MS
+liquidate/XGNDS
+liquidation/M
+liquidator/MS
+liquidity/M
+liquidize/ZGDRS
+liquidizer/M
+liquor/MDGS
+lira/M
+lire
+lisle/M
+lisp/MDRSZG
+lisper/M
+lissome
+list/MDNSJXG
+listed/U
+listen/BMDRZG
+listener/M
+listeria
+listing/M
+listless/YP
+listlessness/M
+listserv/M
+lit/ZR
+litany/SM
+litchi/MS
+lite
+liter/M
+literacy/M
+literal/SMYP
+literalness/M
+literariness/M
+literary/P
+literate/SMY
+literati/M
+literature/M
+lithe/RPYT
+litheness/M
+lithesome
+lithium/M
+lithograph/MDRZG
+lithographer/M
+lithographic
+lithographically
+lithographs
+lithography/M
+lithosphere/SM
+litigant/SM
+litigate/DSGN
+litigation/M
+litigator/MS
+litigious/P
+litigiousness/M
+litmus/M
+litotes/M
+litter/MDRSZG
+litterateur/MS
+litterbug/MS
+litterer/M
+little/MTRP
+littleness/M
+littoral/SM
+littrateur/SM
+liturgical/Y
+liturgist/SM
+liturgy/SM
+livability/M
+livable/U
+live/ATGDSB
+livelihood/SM
+liveliness/M
+livelong/S
+lively/PRT
+liven/SGD
+liver's
+liver/S
+liveried
+liverish
+liverwort/MS
+liverwurst/M
+livery/CSM
+liveryman/CM
+liverymen/C
+livestock/M
+liveware
+livid/Y
+living/MS
+lix/K
+lizard/MS
+ll
+llama/SM
+llano/SM
+lo
+load's
+load/AUGSD
+loadable
+loader/MS
+loading's
+loaf/MDRSZG
+loafer/M
+loam/M
+loamy/TR
+loan/MDRSZG
+loaner/M
+loansharking/M
+loanword/MS
+loath/JZGDRS
+loathe
+loather/M
+loathing/M
+loathsome/PY
+loathsomeness/M
+loaves
+lob/SMD
+lobar
+lobbed
+lobber/MS
+lobbing
+lobby/GDSM
+lobbyist/MS
+lobe/MS
+lobotomize/DSG
+lobotomy/SM
+lobster/MS
+local/SMY
+locale/MS
+locality/SM
+localization/M
+localize/DRSZG
+locate/AESDNGX
+location/EAM
+locator/MS
+locavore/SM
+loci
+lock/MDRSBZG
+locker/M
+locket/MS
+lockjaw/M
+lockout/MS
+locksmith/M
+locksmiths
+lockstep/M
+lockup/MS
+loco/S
+locomotion/M
+locomotive/MS
+locoweed/SM
+locum/S
+locus/M
+locust/SM
+locution/MS
+lode/MS
+lodestar/MS
+lodestone/MS
+lodge/DRSJMZG
+lodger/M
+lodging/M
+lodgings/M
+loft/MDSG
+loftily
+loftiness/M
+lofty/PRT
+log/SM
+loganberry/SM
+logarithm/SM
+logarithmic
+logbook/SM
+loge/MS
+logged
+logger/SM
+loggerhead/SM
+loggia/SM
+logging/M
+logic/M
+logical/Y
+logicality/M
+logician/MS
+login/SM
+logistic/S
+logistical/Y
+logistics/M
+logjam/SM
+logo/MS
+logoff/SM
+logon/SM
+logotype/SM
+logout/SM
+logrolling/M
+logy/RT
+loin/MS
+loincloth/M
+loincloths
+loiter/ZGSDR
+loiterer/M
+loitering/M
+lolcat/SM
+loll/DSG
+lollipop/SM
+lollop/GSD
+lolly/S
+lollygag/S
+lollygagged
+lollygagging
+lollypop/MS
+lone/YZR
+loneliness/M
+lonely/PTR
+loner/M
+lonesome/YP
+lonesomeness/M
+long's
+long/KDSTG
+longboat/MS
+longbow/MS
+longer
+longevity/M
+longhair/MS
+longhand/M
+longhorn/MS
+longhouse/S
+longing/MYS
+longish
+longitude/MS
+longitudinal/Y
+longshoreman/M
+longshoremen
+longsighted
+longstanding
+longtime
+longueur/SM
+longways
+loo
+loofah/M
+loofahs
+look/MDRSZG
+lookalike/MS
+looker/M
+lookout/MS
+lookup
+loom/MDSG
+loon/MS
+loonie/M
+loony/RSMT
+loop/MDSG
+loophole/MS
+loopy/RT
+loos/NRX
+loose/UDSTG
+loosely
+loosen/UGSD
+looseness/M
+loot/MDRSZG
+looter/M
+looting/M
+lop/S
+lope/MGDS
+lopped
+lopping
+lopsided/YP
+lopsidedness/M
+loquacious/PY
+loquaciousness/M
+loquacity/M
+lord/MDYSG
+lordliness/M
+lordly/TPR
+lordship/SM
+lore/M
+lorgnette/SM
+loris/MS
+lorn
+lorry/SM
+lose/ZGRSJ
+loser/M
+losing/M
+loss/MS
+lossless
+lost
+lot/SM
+lotion/SM
+lottery/SM
+lotto/M
+lotus/MS
+louche
+loud/RYTP
+loudhailer/SM
+loudmouth/MD
+loudmouths
+loudness/M
+loudspeaker/MS
+lough
+loughs
+lounge/MZGDRS
+lounger/M
+lour/DSG
+louse's
+louse/CDSG
+lousily
+lousiness/M
+lousy/TPR
+lout/MS
+loutish/PY
+louver/MDS
+lovableness/M
+lovably
+love/MYZGDRSB
+lovebird/SM
+lovechild/M
+loved/U
+loveless
+loveliness/M
+lovelorn
+lovely/RSMTP
+lovemaking/M
+lover/M
+loveseat/SM
+lovesick
+lovey/S
+loving/Y
+low/SZTGMDRYP
+lowborn
+lowboy/MS
+lowbrow/SM
+lowdown/M
+lower/GD
+lowercase/M
+lowermost
+lowish
+lowland/SZMR
+lowlander/M
+lowlife/SM
+lowliness/M
+lowly/TPR
+lowness/M
+lox/M
+loyal/ETY
+loyaler
+loyalism/M
+loyalist/SM
+loyalties
+loyalty/EM
+lozenge/SM
+ltd
+luau/MS
+lubber/MYS
+lube/MGDS
+lubricant/SM
+lubricate/DSGN
+lubrication/M
+lubricator/MS
+lubricious/Y
+lubricity/M
+lucid/PY
+lucidity/M
+lucidness/M
+luck/MDSG
+luckily/U
+luckiness/UM
+luckless
+lucky/UPTR
+lucrative/YP
+lucrativeness/M
+lucre/M
+lucubrate/GNDS
+lucubration/M
+ludicrous/YP
+ludicrousness/M
+ludo
+luff/DSG
+lug/SM
+luge/S
+luggage/M
+lugged
+lugger/MS
+lugging
+lughole/S
+lugsail/SM
+lugubrious/YP
+lugubriousness/M
+lukewarm/YP
+lukewarmness/M
+lull/MDSG
+lullaby/SM
+lulu/S
+lumbago/M
+lumbar
+lumber/MDRZGS
+lumberer/M
+lumbering/M
+lumberjack/SM
+lumberman/M
+lumbermen
+lumberyard/SM
+lumen/S
+lumina
+luminary/SM
+luminescence/M
+luminescent
+luminosity/M
+luminous/Y
+lummox/MS
+lump/MDNSG
+lumpectomy/S
+lumpenproletariat
+lumpiness/M
+lumpish
+lumpy/TRP
+lunacy/SM
+lunar
+lunatic/SM
+lunch/GMDS
+lunchbox/S
+luncheon/SM
+luncheonette/SM
+lunchroom/MS
+lunchtime/MS
+lung/MDSG
+lunge/SM
+lungfish/MS
+lungful/S
+lunkhead/MS
+lupine/MS
+lupus/M
+lurch/GMDS
+lure/MGDS
+lurgy
+lurid/PY
+luridness/M
+lurk/DRSZG
+luscious/PY
+lusciousness/M
+lush/MRSYPT
+lushness/M
+lust/MDRSG
+luster/M
+lusterless
+lustful/Y
+lustily
+lustiness/M
+lustrous/Y
+lusty/PTR
+lutanist/SM
+lute/MS
+lutenist/SM
+lutetium/M
+lux
+luxuriance/M
+luxuriant/Y
+luxuriate/DSGN
+luxuriation/M
+luxurious/PY
+luxuriousness/M
+luxury/SM
+lvi
+lvii
+lxi
+lxii
+lxiv
+lxix
+lxvi
+lxvii
+lyceum/MS
+lychee/MS
+lychgate/S
+lye/MG
+lying/M
+lymph/M
+lymphatic/SM
+lymphocyte/SM
+lymphoid
+lymphoma/SM
+lynch/JZGDRS
+lyncher/M
+lynching/M
+lynx/MS
+lyre/MS
+lyrebird/MS
+lyric/SM
+lyrical/Y
+lyricism/M
+lyricist/SM
+lysosomal
+lysosomes
+m/KAS
+mRNA
+ma'am
+ma/SMH
+mac/SGMD
+macOS/M
+macabre
+macadam/M
+macadamia/SM
+macadamize/GDS
+macaque/MS
+macaroni/MS
+macaroon/MS
+macaw/SM
+mace/MS
+macerate/DSGN
+maceration/M
+mach/M
+machete/SM
+machinate/GNDSX
+machination/M
+machine/DSMGB
+machinery/M
+machinist/MS
+machismo/M
+macho/M
+mack/MS
+mackerel/SM
+mackinaw/SM
+mackintosh/MS
+macrame/M
+macram/M
+macro/SM
+macrobiotic/S
+macrobiotics/M
+macrocosm/SM
+macroeconomic/S
+macroeconomics/M
+macrology/S
+macron/MS
+macrophages
+macroscopic
+macroscopically
+mad/SMYP
+madam/SM
+madame/M
+madcap/MS
+madden/DGS
+maddening/Y
+madder/MS
+maddest
+madding
+made/AU
+mademoiselle/MS
+madhouse/SM
+madman/M
+madmen
+madness/M
+madras/MS
+madrasa/SM
+madrasah/M
+madrasahs
+madrassa/SM
+madrigal/SM
+madwoman/M
+madwomen
+maelstrom/SM
+maestro/SM
+mafia/SM
+mafiosi
+mafioso/M
+mag/SM
+magazine/SM
+mage/MS
+magenta/M
+maggot/MS
+maggoty
+magi/M
+magic/SM
+magical/Y
+magician/SM
+magicked
+magicking
+magisterial/Y
+magistracy/M
+magistrate/SM
+magma/M
+magnanimity/M
+magnanimous/Y
+magnate/SM
+magnesia/M
+magnesium/M
+magnet/MS
+magnetic
+magnetically
+magnetism/M
+magnetite/M
+magnetizable
+magnetization/CM
+magnetize/CGDS
+magneto/SM
+magnetometer/SM
+magnetosphere
+magnification/M
+magnificence/M
+magnificent/Y
+magnifier/M
+magnify/ZGXDRSN
+magniloquence/M
+magniloquent
+magnitude/SM
+magnolia/MS
+magnon
+magnum/MS
+magpie/MS
+magus/M
+maharaja/SM
+maharajah/M
+maharajahs
+maharanee/MS
+maharani/SM
+maharishi/SM
+mahatma/SM
+mahjong/M
+mahogany/SM
+mahout/MS
+maid/MNSX
+maiden/MY
+maidenhair/M
+maidenhead/SM
+maidenhood/M
+maidservant/SM
+mail/JMDRSZG
+mailbag/SM
+mailbomb/GSD
+mailbox/MS
+mailer/M
+mailing/M
+maillot/SM
+mailman/M
+mailmen
+mailshot/S
+maim/DSG
+main/MYS
+mainframe/SM
+mainland/MS
+mainline/MGDS
+mainmast/MS
+mainsail/MS
+mainspring/MS
+mainstay/MS
+mainstream/SMDG
+maintain/ZGBDRS
+maintainability
+maintainable/U
+maintained/U
+maintenance/M
+maintop/SM
+maisonette/MS
+maize/SM
+majestic
+majestically
+majesty/SM
+majolica/M
+major/SGMDY
+majordomo/MS
+majorette/MS
+majoritarian/SM
+majoritarianism
+majority/SM
+make's/A
+make/UAGS
+makeover/MS
+maker/SM
+makeshift/SM
+makeup/MS
+makeweight/S
+making/MS
+makings/M
+malachite/M
+maladjusted
+maladjustment/M
+maladministration
+maladroit/PY
+maladroitness/M
+malady/SM
+malaise/M
+malamute/MS
+malapropism/SM
+malaria/M
+malarial
+malarkey/M
+malathion/M
+malcontent/MS
+male/MPS
+malediction/SM
+malefaction/M
+malefactor/SM
+malefic
+maleficence/M
+maleficent
+maleness/M
+malevolence/M
+malevolent/Y
+malfeasance/M
+malform/SD
+malformation/SM
+malfunction/MDSG
+malice/M
+malicious/PY
+maliciousness/M
+malign/DSG
+malignancy/SM
+malignant/Y
+malignity/M
+malinger/ZGSDR
+malingerer/M
+mall/MS
+mallard/SM
+malleability/M
+malleable
+mallet/MS
+mallow/MS
+malnourished
+malnutrition/M
+malocclusion/M
+malodorous
+malpractice/SM
+malt/MDSG
+malted/MS
+maltose/M
+maltreat/GLDS
+maltreatment/M
+malty/TR
+malware/SM
+mam/S
+mama/MS
+mamba/SM
+mambo/SGMD
+mamma/M
+mammal/MS
+mammalia
+mammalian/MS
+mammary
+mammogram/MS
+mammography/M
+mammon/M
+mammoth/M
+mammoths
+mammy/SM
+man's/F
+man/UFY
+manacle/DSMG
+manage/ZGDRSL
+manageability/M
+manageable/U
+management/MS
+manager/M
+manageress/S
+managerial
+manana/MS
+manatee/SM
+mandala/SM
+mandamus/MS
+mandarin/MS
+mandate/DSMG
+mandatory
+mandible/MS
+mandibular
+mandolin/MS
+mandrake/MS
+mandrel/SM
+mandrill/MS
+mane/MDS
+manege/M
+maneuver/MDGSBJ
+maneuverability/M
+manful/Y
+manga/M
+manganese/M
+mange/DRMZ
+manger/M
+mangetout/S
+manginess/M
+mangle/MZGDRS
+mango/M
+mangoes
+mangrove/MS
+mangy/TRP
+manhandle/GDS
+manhole/SM
+manhood/M
+manhunt/SM
+mania/SM
+maniac/MS
+maniacal/Y
+manic/SM
+manically
+manicure/MGDS
+manicurist/MS
+manifest/MDYSG
+manifestation/SM
+manifesto/SM
+manifold/GMDS
+manikin/SM
+manila/M
+manioc/MS
+manipulable
+manipulate/XGNVDS
+manipulation/M
+manipulative/Y
+manipulator/MS
+mankind/M
+manky
+manlike
+manliness/M
+manly/URT
+manna/M
+manned/U
+mannequin/SM
+manner/MDYS
+mannerism/SM
+mannerly/U
+manning/U
+mannish/YP
+mannishness/M
+manometer/SM
+manor/SM
+manorial
+manpower/M
+manque
+manqu
+mans
+mansard/MS
+manse/SXMN
+manservant/M
+mansion/M
+manslaughter/M
+manta/SM
+mantel/MS
+mantelpiece/SM
+mantelshelf
+mantelshelves
+mantes
+manticore
+mantilla/SM
+mantis/MS
+mantissa/SM
+mantle's
+mantle/EGDS
+mantra/MS
+manual/MYS
+manufacture/DRSMZG
+manufacturer/M
+manufacturing/M
+manumission/SM
+manumit/S
+manumitted
+manumitting
+manure/MGDS
+manuscript/MS
+many/M
+mange/M
+map's
+map/AS
+maple/SM
+mapmaker/SM
+mapped/A
+mapper/MS
+mapping/S
+mar/S
+marabou/MS
+marabout/SM
+maraca/MS
+maraschino/MS
+marathon/SMRZ
+marathoner/M
+maraud/ZGDRS
+marauder/M
+marble/MGDS
+marbleize/GDS
+marbling/M
+march/ZGMDRS
+marcher/M
+marchioness/MS
+mare/MS
+margarine/M
+margarita/MS
+marge
+margin/MS
+marginal/YS
+marginalia/M
+marginalization/M
+marginalize/GDS
+maria/M
+mariachi/MS
+marigold/MS
+marijuana/M
+marimba/SM
+marina/MS
+marinade/DSMG
+marinara/M
+marinate/DSGN
+marination/M
+marine/MZRS
+mariner/M
+marionette/MS
+marital/Y
+maritime
+marjoram/M
+mark/AMDSG
+markdown/SM
+marked/U
+markedly
+marker/MS
+market/MDRZGBS
+marketability/M
+marketable/U
+marketeer/SM
+marketer/M
+marketing/M
+marketplace/SM
+marking/SM
+markka/M
+markkaa
+marksman/M
+marksmanship/M
+marksmen
+markup/MS
+marl/M
+marlin/MS
+marlinespike/SM
+marmalade/M
+marmoreal
+marmoset/SM
+marmot/MS
+maroon/MDGS
+marque/MS
+marquee/SM
+marquess/MS
+marquetry/M
+marquis/MS
+marquise/M
+marquisette/M
+marred/U
+marriage/ASM
+marriageability/M
+marriageable
+married/SM
+marring
+marrow/MS
+marry/AGDS
+marsh/MS
+marshal/SMDG
+marshland/SM
+marshmallow/SM
+marshy/RT
+marsupial/MS
+mart/MNSX
+marten/M
+martensite
+martial/Y
+martian/S
+martin/MS
+martinet/MS
+martingale/MS
+martini/SM
+martyr/MDGS
+martyrdom/M
+marvel/MDGS
+marvelous/Y
+marzipan/M
+masc
+mascara/GMDS
+mascot/MS
+masculine/SM
+masculinity/M
+maser/SM
+mash/MDRSZG
+masher/M
+mashup/MS
+mask's
+mask/UDSG
+masker/MS
+masochism/M
+masochist/SM
+masochistic
+masochistically
+mason/SM
+masonic
+masonry/M
+masque/MS
+masquerade/DRSMZG
+masquerader/M
+mass/MDSGV
+massacre/MGDS
+massage/DSMG
+masse
+masseur/SM
+masseuse/MS
+massif/MS
+massive/PY
+massiveness/M
+massless
+mast/MDS
+mastectomy/SM
+master's
+master/ADGS
+masterclass/S
+masterful/Y
+masterly
+mastermind/SGMD
+masterpiece/MS
+masterstroke/SM
+masterwork/MS
+mastery/M
+masthead/MS
+mastic/M
+masticate/GNDS
+mastication/M
+mastiff/SM
+mastitis
+mastodon/SM
+mastoid/SM
+masturbate/GNDS
+masturbation/M
+masturbatory
+mat/SZGMDR
+matador/SM
+match/AMS
+matchbook/SM
+matchbox/MS
+matched/U
+matching
+matchless
+matchlock/SM
+matchmaker/MS
+matchmaking/M
+matchstick/MS
+matchwood/M
+mate/MS
+material/SMY
+materialism/M
+materialist/SM
+materialistic
+materialistically
+materialization/M
+materialize/DSG
+materiel/M
+maternal/Y
+maternity/M
+matey/S
+mathematical/Y
+mathematician/SM
+mathematics/M
+matinee/SM
+mating/M
+matins/M
+matine/SM
+matriarch/M
+matriarchal
+matriarchs
+matriarchy/SM
+matrices
+matricidal
+matricide/MS
+matriculate/DSGN
+matriculation/M
+matrimonial
+matrimony/M
+matrix/M
+matron/MYS
+matte/DRSMZG
+matter/MDG
+matting/M
+mattock/SM
+mattress/MS
+maturate/GNDS
+maturation/M
+mature/YTGDRS
+maturity/SM
+matzo/SMH
+matzoh/M
+matzohs
+matzot
+matriel/M
+maudlin
+maul/MDRSZG
+mauler/M
+maunder/SDG
+mausoleum/SM
+mauve/M
+maven/SM
+maverick/SM
+maw/SM
+mawkish/PY
+mawkishness/M
+max/GMDS
+maxi/MS
+maxilla/M
+maxillae
+maxillary
+maxim/SM
+maxima
+maximal/Y
+maximalist/SM
+maximization/M
+maximize/GDS
+maximum/SM
+may/M
+maybe/SM
+mayday/MS
+mayflower/MS
+mayfly/SM
+mayhem/M
+mayn't
+mayo/M
+mayonnaise/M
+mayor/SM
+mayoral
+mayoralty/M
+mayoress/MS
+maypole/SM
+mayst
+maze/MS
+mazurka/MS
+maana/M
+mdse
+me/DSH
+mea/S
+mead/M
+meadow/MS
+meadowlark/MS
+meager/PY
+meagerness/M
+meal/MS
+mealiness/M
+mealtime/SM
+mealy/TPR
+mealybug/SM
+mealymouthed
+mean/MRYJPSTG
+meander/SMDJG
+meanderings/M
+meanie/M
+meaning/M
+meaningful/PY
+meaningfulness/M
+meaningless/YP
+meaninglessness/M
+meanness/M
+meant/U
+meantime/M
+meanwhile/M
+meany/SM
+measles/M
+measly/RT
+measurably
+measure/LDRSBMG
+measured/U
+measureless
+measurement/MS
+meat/MS
+meatball/MS
+meathead/MS
+meatiness/M
+meatless
+meatloaf/M
+meatloaves
+meatpacking/M
+meaty/TPR
+mebibyte/SM
+mecca/SM
+mechanic/MS
+mechanical/Y
+mechanics/M
+mechanism/SM
+mechanistic
+mechanistically
+mechanization/M
+mechanize/DSG
+medal/SM
+medalist/MS
+medallion/SM
+meddle/ZGDRS
+meddler/M
+meddlesome
+media/SM
+medial/AY
+median/MS
+mediate/ADSGN
+mediated/U
+mediation/AM
+mediator/MS
+medic/SM
+medicaid/M
+medical/SMY
+medicament/M
+medicare/M
+medicate/GNXDS
+medication/M
+medicinal/Y
+medicine/MS
+medico/MS
+medieval
+medievalist/MS
+mediocre
+mediocrity/SM
+meditate/DSGNVX
+meditation/M
+meditative/Y
+medium/MS
+medley/MS
+medulla/SM
+medusa
+medusae
+meed/M
+meek/RYPT
+meekness/M
+meerkats
+meerschaum/SM
+meet/MJSG
+meeting/M
+meetinghouse/SM
+meetup/MS
+meg/S
+mega
+megabit/SM
+megabucks/M
+megabyte/MS
+megachurch/MS
+megacycle/SM
+megadeath/M
+megadeaths
+megagram/S
+megahertz/M
+megajoule/MS
+megalith/M
+megalithic
+megaliths
+megalomania/M
+megalomaniac/SM
+megalopolis/MS
+megameter/S
+megapascal/S
+megaphone/DSMG
+megapixel/SM
+megastar/S
+megaton/SM
+megawatt/MS
+meh
+meiosis/M
+meiotic
+melamine/M
+melancholia/M
+melancholic/S
+melancholy/M
+melange/MS
+melanin/M
+melanoma/SM
+meld/MDSG
+melee/SM
+meliorate/GNVDS
+melioration/M
+mellifluous/PY
+mellifluousness/M
+mellow/PTGDRYS
+mellowness/M
+melodic
+melodically
+melodious/YP
+melodiousness/M
+melodrama/MS
+melodramatic/S
+melodramatically
+melodramatics/M
+melody/SM
+melon/SM
+melt's
+melt/ADSG
+meltdown/SM
+member's
+member/EAS
+membership/SM
+membrane/SM
+membranous
+meme/MS
+memento/MS
+memo/MS
+memoir/MS
+memorabilia/M
+memorability/M
+memorable/U
+memorably
+memorandum/MS
+memorial/SM
+memorialize/DSG
+memorization/M
+memorize/DSG
+memory/SM
+memsahib/S
+men/M
+menace/MGDS
+menacing/Y
+menage/MS
+menagerie/MS
+mend/MDRSZG
+mendacious/Y
+mendacity/M
+mendelevium/M
+mender/M
+mendicancy/M
+mendicant/SM
+mending/M
+menfolk/MS
+menfolks/M
+menhaden/M
+menial/MYS
+meningeal
+meninges
+meningitis/M
+meninx/M
+menisci
+meniscus/M
+menopausal
+menopause/M
+menorah/M
+menorahs
+mensch/MS
+menservants
+menses/M
+menstrual
+menstruate/GNDS
+menstruation/M
+mensurable
+mensuration/M
+menswear/M
+mental/Y
+mentalist/SM
+mentality/SM
+menthol/M
+mentholated
+mention/GSMD
+mentioned/U
+mentor/MDSG
+mentorship
+menu/MS
+meow/MDSG
+mercantile
+mercantilism/M
+mercenary/SM
+mercer/MS
+mercerize/GDS
+merchandise/MZGDRS
+merchandiser/M
+merchandising/M
+merchant/GMBS
+merchantability
+merchantman/M
+merchantmen
+merciful/UY
+merciless/PY
+mercilessness/M
+mercurial/Y
+mercuric
+mercury/M
+mercy/SM
+mere/MYTS
+meretricious/YP
+meretriciousness/M
+merganser/MS
+merge/DRSZG
+merger/M
+meridian/MS
+meringue/MS
+merino/MS
+merit/CSM
+merited/U
+meriting
+meritless
+meritocracy/SM
+meritocratic
+meritorious/PY
+meritoriousness/M
+mermaid/SM
+merman/M
+mermen
+merrily
+merriment/M
+merriness/M
+merry/TRP
+merrymaker/MS
+merrymaking/M
+mesa/MS
+mescal/MS
+mescalin
+mescaline/M
+mesdames
+mesdemoiselles
+mesh/MDSG
+mesmeric
+mesmerism/M
+mesmerize/ZGDRS
+mesmerizer/M
+mesomorph/M
+mesomorphs
+meson/SM
+mesosphere/SM
+mesothelioma/M
+mesquite/SM
+mess/MDSG
+message/MGDS
+messeigneurs
+messenger/SM
+messiah/M
+messiahs
+messianic
+messieurs
+messily
+messiness/M
+messmate/SM
+messy/PTR
+mestizo/MS
+met
+meta
+metabolic
+metabolically
+metabolism/SM
+metabolite/SM
+metabolize/DSG
+metacarpal/SM
+metacarpi
+metacarpus/M
+metadata/M
+metal/SMD
+metalanguage/MS
+metallic
+metallurgic
+metallurgical
+metallurgist/MS
+metallurgy/M
+metalwork/MRZG
+metalworker/M
+metalworking/M
+metamorphic
+metamorphism/M
+metamorphose/GDS
+metamorphosis/M
+metaphor/MS
+metaphoric
+metaphorical/Y
+metaphysical/Y
+metaphysics/M
+metastases
+metastasis/M
+metastasize/DSG
+metastatic
+metatarsal/MS
+metatarsi
+metatarsus/M
+metatheses
+metathesis/M
+mete/MZGDRS
+metempsychoses
+metempsychosis/M
+meteor/MS
+meteoric
+meteorically
+meteorite/SM
+meteoroid/SM
+meteorologic
+meteorological
+meteorologist/SM
+meteorology/M
+meter/GMD
+metformin
+methadone/M
+methamphetamine/M
+methane/M
+methanol/M
+methinks
+method/MS
+methodical/YP
+methodicalness/M
+methodological/Y
+methodology/SM
+methotrexate
+methought
+methoxy
+meths
+methyl/M
+meticulous/YP
+meticulousness/M
+metier/MS
+metric/S
+metrical/Y
+metricate/GNDS
+metrication/M
+metricize/GDS
+metro/SM
+metronome/MS
+metropolis/MS
+metropolitan
+mettle/M
+mettlesome
+mew/SGMD
+mewl/DSG
+mews/M
+mezzanine/MS
+mezzo/SM
+mfg
+mfr/S
+mg
+mgr
+mi/MNX
+miasma/MS
+mic/S
+mica/M
+mice
+mick/S
+mickey/MS
+micro/SM
+microaggression/SM
+microbe/MS
+microbial
+microbiological
+microbiologist/MS
+microbiology/M
+microbrewery/SM
+microchip/MS
+microcircuit/SM
+microcode
+microcomputer/MS
+microcosm/MS
+microcosmic
+microcredit
+microdot/SM
+microeconomics/M
+microelectronic/S
+microelectronics/M
+microfiber/MS
+microfiche/M
+microfilm/GMDS
+microfinance
+microfloppies
+microgram
+microgroove/SM
+microlight/MS
+microloan/MS
+micromanage/ZGDRSL
+micromanagement/M
+micromanager/M
+micrometeorite/SM
+micrometer/MS
+micron/MS
+microorganism/MS
+micropayment/S
+microphone/SM
+microplastics
+microprocessor/MS
+microscope/SM
+microscopic
+microscopical/Y
+microscopy/M
+microsecond/MS
+microsurgery/M
+microwave/DSMGB
+microwaveable
+mid
+midair/M
+midday/M
+midden/MS
+middle/MGS
+middlebrow/SM
+middleman/M
+middlemen
+middlemost
+middleweight/MS
+middy/SM
+midfield/RZ
+midge/SM
+midget/MS
+midi/MS
+midland/MS
+midlife/M
+midmost
+midnight/M
+midpoint/MS
+midrib/MS
+midriff/MS
+midsection/MS
+midshipman/M
+midshipmen
+midships
+midsize
+midst/M
+midstream/M
+midsummer/M
+midterm/MS
+midtown/M
+midway/MS
+midweek/MS
+midwife/MGDS
+midwifery/SM
+midwinter/M
+midwived
+midwives
+midwiving
+midyear/MS
+mien/M
+miff/DSG
+might've
+might/M
+mightily
+mightiness/M
+mightn't
+mighty/TRP
+mignonette/SM
+migraine/MS
+migrant/MS
+migrate/AGDS
+migration/SM
+migrator/MS
+migratory
+mikado/MS
+mike/MGDS
+mil/SZMR
+milady/SM
+milch
+mild/MRYTP
+mildew/SMDG
+mildness/M
+mile/MS
+mileage/SM
+milepost/MS
+miler/M
+milestone/MS
+milf/MS
+milieu/SM
+militancy/M
+militant/MYS
+militarily
+militarism/M
+militarist/SM
+militaristic
+militarization/CM
+militarize/CDSG
+military/M
+militate/GDS
+militia/SM
+militiaman/M
+militiamen
+milk/MDRSZG
+milker/M
+milkiness/M
+milkmaid/MS
+milkman/M
+milkmen
+milkshake/SM
+milksop/MS
+milkweed/SM
+milky/RTP
+mill/MDRSZGJ
+millage/M
+millennia
+millennial/MS
+millennium/MS
+miller/M
+millet/M
+milliard/MS
+millibar/MS
+milligram/MS
+milliliter/MS
+millimeter/MS
+milliner/MS
+millinery/M
+milling/M
+million/HSM
+millionaire/SM
+millionairess/S
+millionth/M
+millionths
+millipede/SM
+millisecond/SM
+millisievert/S
+millpond/SM
+millrace/SM
+millstone/SM
+millstream/MS
+millwright/SM
+milometer/S
+milquetoast/SM
+milt/MDSG
+mime/MGDS
+mimeograph/GMD
+mimeographs
+mimetic
+mimic/SM
+mimicked
+mimicker/SM
+mimicking
+mimicry/SM
+mimosa/SM
+min/S
+minaret/MS
+minatory
+mince/DRSMZG
+mincemeat/M
+mincer/M
+mind's
+mind/ADRSZG
+mindbogglingly
+minded/P
+mindful/YP
+mindfulness/M
+mindless/YP
+mindlessness/M
+mindset/MS
+mine/MZGNDRSX
+minefield/SM
+miner/M
+mineral/MS
+mineralogical
+mineralogist/MS
+mineralogy/M
+minestrone/M
+minesweeper/SM
+mingle/DSG
+mingy
+mini/MS
+miniature/MS
+miniaturist/MS
+miniaturization/M
+miniaturize/GDS
+minibar/S
+minibike/SM
+minibus/MS
+minicab/S
+minicam/MS
+minicomputer/SM
+minifloppies
+minim/SM
+minima
+minimal/Y
+minimalism/M
+minimalist/MS
+minimization/M
+minimize/DSG
+minimum/MS
+mining/M
+minion/M
+miniseries/M
+miniskirt/MS
+minister/SGMD
+ministerial
+ministrant/MS
+ministration/MS
+ministry/SM
+minivan/MS
+mink/MS
+minnesinger/MS
+minnow/SM
+minor/SMDG
+minority/SM
+minoxidil/M
+minster/MS
+minstrel/SM
+minstrelsy/M
+mint/MDRSZG
+mintage/M
+minter/M
+minty/RT
+minuend/MS
+minuet/SM
+minus/MS
+minuscule/MS
+minute/PDRSMYTG
+minuteman/M
+minutemen
+minuteness/M
+minutia/M
+minutiae
+minx/MS
+miracle/MS
+miraculous/Y
+mirage/SM
+mire/MGDS
+mirror/GSMD
+mirth/M
+mirthful/PY
+mirthfulness/M
+mirthless/Y
+miry/RT
+misaddress/DSG
+misadventure/MS
+misaligned
+misalignment/M
+misalliance/MS
+misandrist/MS
+misandry
+misanthrope/SM
+misanthropic
+misanthropically
+misanthropist/MS
+misanthropy/M
+misapplication/M
+misapply/DSGNX
+misapprehend/GSD
+misapprehension/MS
+misappropriate/XDSGN
+misappropriation/M
+misbegotten
+misbehave/GDS
+misbehavior/M
+misc
+miscalculate/DSXGN
+miscalculation/M
+miscall/DSG
+miscarriage/MS
+miscarry/GDS
+miscast/SG
+miscegenation/M
+miscellanea
+miscellaneous/Y
+miscellany/SM
+mischance/SM
+mischaracterization/S
+mischaracterize/GD
+mischief/M
+mischievous/YP
+mischievousness/M
+miscibility/M
+miscible
+misclassify/DGXN
+miscommunication/S
+misconceive/GDS
+misconception/SM
+misconduct/MDGS
+misconfiguration
+misconstruction/MS
+misconstrue/GDS
+miscount/MDSG
+miscreant/SM
+miscue/DSMG
+misdeal/GMS
+misdealt
+misdeed/MS
+misdemeanor/MS
+misdiagnose/GDS
+misdiagnosis/M
+misdid
+misdirect/SDG
+misdirection/M
+misdo/JG
+misdoes
+misdoing/M
+misdone
+mise/CKS
+miser/SBMY
+miserableness/M
+miserably
+miserliness/M
+misery/SM
+misfeasance/M
+misfeature/S
+misfile/GDS
+misfire/MGDS
+misfit/SM
+misfitted
+misfitting
+misfortune/SM
+misgender/SDG
+misgiving/MS
+misgovern/SDGL
+misgovernment/M
+misguidance/M
+misguide/DSG
+misguided/Y
+mishandle/DSG
+mishap/SM
+mishear/GS
+misheard
+mishit/S
+mishitting
+mishmash/MS
+misidentify/GDS
+misinform/DGS
+misinformation/M
+misinterpret/SGD
+misinterpretation/SM
+misjudge/LDSG
+misjudgement/SM
+misjudgment/SM
+mislabel/GSD
+mislaid
+mislay/GS
+mislead/GS
+misleading/Y
+misled
+mismanage/LGDS
+mismanagement/M
+mismatch/GMDS
+misname/GDS
+misnomer/MS
+misogamist/MS
+misogamy/M
+misogynist/SM
+misogynistic
+misogynous
+misogyny/M
+misplace/GLDS
+misplacement/M
+misplay/GMDS
+misprint/GMDS
+misprision/M
+mispronounce/DSG
+mispronunciation/SM
+misquotation/MS
+misquote/MGDS
+misread/GJS
+misreading/M
+misremember/GDS
+misreport/MDGS
+misrepresent/GDS
+misrepresentation/MS
+misrule/MGDS
+miss's
+miss/EDSGV
+missal/ESM
+missed/U
+misshape/GDS
+misshapen
+missile/MS
+missileer
+missilery/M
+mission/AMS
+missionary/SM
+missioner/SM
+missis/MS
+missive/MS
+misspeak/GS
+misspell/GDJS
+misspelling/M
+misspend/GS
+misspent
+misspoke
+misspoken
+misstate/GDSL
+misstatement/SM
+misstep/MS
+missus/MS
+mist's
+mist/CDRSZG
+mistakable/U
+mistake/BMGS
+mistaken/Y
+mister's
+mistily
+mistime/GDS
+mistiness/M
+mistletoe/M
+mistook
+mistral/MS
+mistranslated
+mistreat/LDGS
+mistreatment/M
+mistress/MS
+mistrial/MS
+mistrust/MDSG
+mistrustful/Y
+misty/PRT
+mistype/GDS
+misunderstand/SGJ
+misunderstanding/M
+misunderstood
+misuse/DSMG
+mite/MZRS
+miter/MDG
+mitigable
+mitigate/XDSGN
+mitigated/U
+mitigation/M
+mitochondria
+mitochondrial
+mitochondrion
+mitoses
+mitosis/M
+mitotic
+mitral
+mitt/MNSX
+mitten/M
+mitzvah
+mix/ZGMDRSB
+mixed/U
+mixer/M
+mixture/SM
+mizzen/MS
+mizzenmast/SM
+mkay
+mks
+ml
+mm
+mnemonic/MS
+mnemonically
+mo/CKHS
+moan/MDRSZG
+moaner/M
+moat/MDS
+mob's
+mob/CS
+mobbed/C
+mobbing/C
+mobile/MS
+mobility/M
+mobilization/CM
+mobilizations
+mobilize/CDSG
+mobilizer/SM
+mobster/SM
+moccasin/SM
+mocha/SM
+mock/DRSZG
+mocker/M
+mockery/SM
+mocking/Y
+mockingbird/SM
+mocktail/S
+mockumentary/S
+mod/STM
+modal/SM
+modality/S
+modded
+modding
+mode/MS
+model/ZGSJMDR
+modeler/M
+modeling/M
+modeller/MS
+modelling/MS
+modem/SM
+moderate/MYGNPDS
+moderateness/M
+moderation/M
+moderator/SM
+modern/MYPS
+modernism/M
+modernist/SM
+modernistic
+modernity/M
+modernization/M
+modernize/DRSZG
+modernizer/M
+modernness/M
+modest/Y
+modesty/M
+modicum/SM
+modifiable
+modification/M
+modified/U
+modifier/M
+modify/DRSXZGN
+modish/YP
+modishness/M
+modular
+modularization
+modulate/CGNDS
+modulation/CM
+modulations
+modulator/MS
+module/MS
+modulo
+modulus
+moggy
+mogul/SM
+mohair/M
+moi
+moiety/SM
+moil/MDSG
+moire/SM
+moist/XTPNRY
+moisten/DRZG
+moistener/M
+moistness/M
+moisture/M
+moisturize/ZGDRS
+moisturizer/M
+mojo/S
+molar/SM
+molasses/M
+mold/MDRJSZG
+moldboard/SM
+molder/GMD
+moldiness/M
+molding/M
+moldy/TPR
+mole/MS
+molecular
+molecularity/M
+molecule/SM
+molehill/SM
+moleskin/M
+molest/DRZGS
+molestation/M
+molested/U
+molester/M
+moll/MS
+mollification/M
+mollify/DSNG
+mollusc/SM
+molluscan/SM
+mollusk/SM
+molluskan/S
+molly/SM
+mollycoddle/DSMG
+molt/MDNRSZG
+molter/M
+molybdenum/M
+mom/SM
+moment/MS
+momenta
+momentarily
+momentariness/M
+momentary/P
+momentous/PY
+momentousness/M
+momentum/M
+mommy/SM
+monad
+monarch/M
+monarchic
+monarchical
+monarchism/M
+monarchist/MS
+monarchistic
+monarchs
+monarchy/SM
+monastery/SM
+monastic/MS
+monastical/Y
+monasticism/M
+monaural
+monetarily
+monetarism/M
+monetarist/MS
+monetary
+monetization/C
+monetize/CGDS
+money/SMD
+moneybag/MS
+moneybox/S
+moneygrubber/SM
+moneygrubbing/M
+moneylender/SM
+moneymaker/SM
+moneymaking/M
+monger/MDGS
+mongol/S
+mongolism/M
+mongoloid/MS
+mongoose/MS
+mongrel/SM
+monied
+monies
+moniker/SM
+monism/M
+monist/MS
+monition/SM
+monitor/SMDG
+monitory
+monk/MS
+monkey/MDGS
+monkeyshine/SM
+monkish
+monkshood/SM
+mono/M
+monochromatic
+monochrome/MS
+monocle/DSM
+monoclonal
+monocotyledon/SM
+monocotyledonous
+monocular
+monodic
+monodist/SM
+monody/SM
+monofilament
+monogamist/MS
+monogamous/Y
+monogamy/M
+monogram/SM
+monogrammed
+monogramming
+monograph/M
+monographs
+monolingual/MS
+monolith/M
+monolithic
+monoliths
+monologist/SM
+monologue/SM
+monologuist/SM
+monomania/M
+monomaniac/MS
+monomaniacal
+monomer/SM
+monomial
+mononucleosis/M
+monophonic
+monoplane/SM
+monopolist/SM
+monopolistic
+monopolization/M
+monopolize/DRSZG
+monopolizer/M
+monopoly/SM
+monorail/MS
+monosyllabic
+monosyllable/MS
+monotheism/M
+monotheist/SM
+monotheistic
+monotone/MS
+monotonic
+monotonically
+monotonous/PY
+monotonousness/M
+monotony/M
+monounsaturated
+monoxide/MS
+monozygotic
+monozygous
+monseigneur/M
+monsieur/M
+monsignor/SM
+monsoon/SM
+monsoonal
+monster/SM
+monstrance/ASM
+monstrosity/SM
+monstrous/Y
+montage/SM
+month/MY
+monthly/SM
+months
+monument/MS
+monumental/Y
+moo/SGMD
+mooch/ZGMDRS
+moocher/M
+mood/MS
+moodily
+moodiness/M
+moody/TPR
+moon/MDSG
+moonbeam/MS
+moonless
+moonlight/SMDRZG
+moonlighter/M
+moonlighting/M
+moonlit
+moonscape/SM
+moonshine/MZRS
+moonshiner/M
+moonshot/MS
+moonstone/MS
+moonstruck
+moonwalk/MS
+moor/MDJSG
+moorhen/S
+mooring/M
+moorland/MS
+moose/M
+moot/DSG
+mop/SZGMDR
+mope/MS
+moped/SM
+moper/M
+mopey
+mopier
+mopiest
+mopish
+mopped
+moppet/MS
+mopping
+moraine/SM
+moral/SMY
+morale/M
+moralism
+moralist/MS
+moralistic
+moralistically
+moralities
+morality/UM
+moralization/CM
+moralize/CGDS
+moralizer/MS
+morass/MS
+moratorium/SM
+moray/SM
+morbid/YP
+morbidity/M
+morbidness/M
+mordancy/M
+mordant/SMY
+more/MS
+moreish
+morel/SM
+moreover
+mores/M
+morgue/MS
+moribund
+morn/MJSG
+morning/M
+morocco/M
+moron/SM
+moronic
+moronically
+morose/YP
+moroseness/M
+morph/GD
+morpheme/MS
+morphemic
+morphia/M
+morphine/M
+morphing/M
+morphological
+morphology/M
+morphs
+morrow/MS
+morsel/MS
+mortal/MYS
+mortality/M
+mortar/MDSG
+mortarboard/SM
+mortgage's
+mortgage/AGDS
+mortgagee/MS
+mortgagor/MS
+mortician/MS
+mortification/M
+mortify/NGDS
+mortise/DSMG
+mortuary/SM
+mosaic/MS
+mosey/SGD
+mosh/DSG
+mosque/MS
+mosquito/SM
+mosquitoes
+moss/MS
+mossback/SM
+mossy/TR
+most/MY
+mot/SM
+mote's
+mote/KCXSVN
+motel/SM
+motet/SM
+moth/M
+mothball/GMDS
+mother/MDYSG
+motherboard/SM
+motherfucker/MS!
+motherfucking/!
+motherhood/M
+motherland/MS
+motherless
+motherliness/M
+moths
+motif/SM
+motile/S
+motility/M
+motion/KCM
+motioned
+motioning
+motionless/YP
+motionlessness/M
+motivate/CDSG
+motivated/U
+motivation/SM
+motivational
+motivator/SM
+motive/MS
+motiveless
+motley/MS
+motlier
+motliest
+motocross/MS
+motor/SGMD
+motorbike/MGDS
+motorboat/MS
+motorcade/MS
+motorcar/SM
+motorcycle/DSMG
+motorcyclist/MS
+motorist/SM
+motorization/M
+motorize/DSG
+motorman/M
+motormen
+motormouth/M
+motormouths
+motorsport/SM
+motorway/SM
+mottle/GDS
+motto/M
+mottoes
+moue/MS
+mound/SGMD
+mount/EASGMD
+mountable
+mountain/SM
+mountaineer/SMDG
+mountaineering/M
+mountainous
+mountainside/SM
+mountaintop/SM
+mountebank/MS
+mounted/U
+mounter/MS
+mounting/SM
+mourn/SZGDR
+mourned/U
+mourner/M
+mournful/YP
+mournfulness/M
+mourning/M
+mouse/DRSMZG
+mouser/M
+mousetrap/SM
+mousetrapped
+mousetrapping
+mousey
+mousiness/M
+moussaka/S
+mousse/MGDS
+mousy/PTR
+mouth/GMD
+mouthfeel
+mouthful/MS
+mouthiness/M
+mouthpiece/MS
+mouths
+mouthwash/MS
+mouthwatering
+mouthy/PTR
+mouton/M
+movable/SM
+movant
+move/AMZGDRSB
+moveable/SM
+moved/U
+movement/SM
+movent
+mover/AM
+movie/SM
+moviegoer/SM
+moving/Y
+mow/SZGMDR
+mower/M
+moxie/M
+mozzarella/M
+mp
+mpg
+mph
+mt
+mtg
+mtge
+mu/SM
+much/M
+mucilage/M
+mucilaginous
+muck/MDSG
+muckrake/DRSZG
+muckraker/M
+mucky/TR
+mucous
+mucus/M
+mud/M
+muddily
+muddiness/M
+muddle/MGDS
+muddleheaded
+muddy/PTGDRS
+mudflap/S
+mudflat/MS
+mudguard/SM
+mudpack/S
+mudroom/MS
+mudslide/MS
+mudslinger/SM
+mudslinging/M
+muenster/M
+muesli
+muezzin/MS
+muff/MDSG
+muffin/MS
+muffle/ZGDRS
+muffler/M
+mufti/SM
+mug/SM
+mugful/MS
+mugged
+mugger/MS
+mugginess/M
+mugging/MS
+muggins
+muggle/MS
+muggy/PTR
+mugshot/MS
+mugwump/MS
+mujaheddin
+mujahedin/M
+mukluk/MS
+mulatto/M
+mulattoes
+mulberry/SM
+mulch/GMDS
+mulct/SGMD
+mule/MS
+muleskinner/MS
+muleteer/MS
+mulish/PY
+mulishness/M
+mull/DSG
+mullah/M
+mullahs
+mullein/M
+mullet/MS
+mulligan/SM
+mulligatawny/M
+mullion/SMD
+multi
+multicast
+multicellular
+multichannel
+multicolored
+multicultural
+multiculturalism/M
+multidimensional
+multidisciplinary
+multifaceted
+multifamily
+multifarious/PY
+multifariousness/M
+multiform
+multigrain
+multilateral/Y
+multilayered
+multilevel
+multilingual
+multilingualism/M
+multimedia/M
+multimillionaire/SM
+multinational/SM
+multipart
+multiparty
+multiplayer/M
+multiple/MS
+multiplex/ZGMDRS
+multiplexer/M
+multiplicand/MS
+multiplication/M
+multiplicative
+multiplicity/SM
+multiplier/M
+multiply/NZGDRSX
+multiprocessing
+multiprocessor/SM
+multipurpose
+multiracial
+multistage
+multistory
+multitask/GS
+multitasking/M
+multitude/SM
+multitudinous
+multivariable
+multivariate
+multiverse/SM
+multivitamin/MS
+multiyear
+mum
+mumble/MZGDRS
+mumbler/M
+mumbletypeg/M
+mummer/MS
+mummery/M
+mummification/M
+mummify/GNDS
+mummy/SM
+mumps/M
+mun
+munch/GDS
+munchie/S
+munchies/M
+munchkin/SM
+mundane/SY
+mung/DSG
+municipal/SMY
+municipality/SM
+munificence/M
+munificent/Y
+munition/MDGS
+mural/SM
+muralist/SM
+murder/ZGMDRS
+murderer/M
+murderess/MS
+murderous/Y
+murine
+murk/MS
+murkily
+murkiness/M
+murky/PTR
+murmur/ZGJMDRS
+murmurer/M
+murmuring/M
+murmurous
+murrain/M
+muscat/MS
+muscatel/SM
+muscle/MGDS
+musclebound
+muscleman
+musclemen
+muscly
+muscular/Y
+muscularity/M
+musculature/M
+musculoskeletal
+musculus
+muse/MGDSJ
+musette/MS
+museum/MS
+mush/MDRSZG
+mushiness/M
+mushroom/GSMD
+mushy/PTR
+music/SM
+musical/MYS
+musicale/MS
+musicality/M
+musician/SMY
+musicianship/M
+musicological
+musicologist/MS
+musicology/M
+musing/MY
+musk/M
+muskeg/MS
+muskellunge/MS
+musket/MS
+musketeer/MS
+musketry/M
+muskie/M
+muskiness/M
+muskmelon/SM
+muskox/MN
+muskrat/MS
+musky/PTRS
+muslin/M
+muss/MDSG
+mussel/MS
+mussy/TR
+must've
+must/MRSZ
+mustache/MDS
+mustachio/SMD
+mustang/MS
+mustard/M
+muster/GMD
+mustily
+mustiness/M
+mustn't
+musty/PTR
+mutability/M
+mutably
+mutagen/MS
+mutagenic
+mutant/MS
+mutate/XGNVDS
+mutation/M
+mutational
+mute/MYTGDRSPB
+muteness/M
+mutilate/DSGNX
+mutilation/M
+mutilator/SM
+mutineer/SM
+mutinous/Y
+mutiny/GDSM
+mutt/MS
+mutter/ZGJMDRS
+mutterer/M
+muttering/M
+mutton/M
+muttonchops/M
+muttony
+mutual/Y
+mutuality/M
+muumuu/MS
+muzak
+muzzily
+muzzle/DSMG
+muzzy/P
+my
+mycologist/SM
+mycology/M
+myelitis/M
+myna/MS
+mynah/MS
+myocardial
+myocardium
+myopia/M
+myopic
+myopically
+myriad/SM
+myrmidon/MS
+myrrh/M
+myrtle/SM
+mys
+myself
+mysterious/PY
+mysteriousness/M
+mystery/SM
+mystic/SM
+mystical/Y
+mysticism/M
+mystification/CM
+mystify/CDSGN
+mystique/M
+myth/M
+mythic
+mythical
+mythological
+mythologist/SM
+mythologize/DSG
+mythology/SM
+myths
+myxomatosis
+mtier/MS
+mle/MS
+n/IKTH
+naan/S
+nab/S
+nabbed
+nabbing
+nabob/SM
+nacelle/SM
+nacho/SM
+nacre/M
+nacreous
+nadir/SM
+nae
+naff/RT
+nag/SM
+nagged
+nagger/MS
+nagging
+nagware
+nah
+naiad/SM
+naif/MS
+nail/MDSG
+nailbrush/MS
+naive/RYT
+naivete/M
+naivety/M
+naivet/M
+naked/PY
+nakedness/M
+name's
+name/AGDS
+nameable/U
+named/U
+nameless/Y
+namely
+nameplate/MS
+namesake/SM
+namespace/SM
+nanny/SM
+nano
+nanobot/S
+nanometer/S
+nanosecond/SM
+nanotechnology/SM
+nanotube
+nap/SM
+napalm/MDSG
+nape/MS
+naphtha/M
+naphthalene/M
+napkin/MS
+napless
+napoleon/SM
+napped
+napper/MS
+napping
+nappy/TRSM
+narc/MS
+narcissism/M
+narcissist/MS
+narcissistic
+narcissus/M
+narcolepsy/M
+narcoleptic
+narcoses
+narcosis/M
+narcotic/SM
+narcotization/M
+narcotize/GDS
+nark
+narky
+narrate/GNVDSX
+narration/M
+narrative/SM
+narrator/SM
+narrow/PTGMDRYS
+narrowness/M
+narwhal/MS
+nary
+nasal/SMY
+nasality/M
+nasalization/M
+nasalize/DSG
+nascence/AM
+nascent/A
+nastily
+nastiness/M
+nasturtium/SM
+nasty/PTR
+natal
+natch
+nation/MS
+national/MYS
+nationalism/M
+nationalist/SM
+nationalistic
+nationalistically
+nationality/SM
+nationalization/MS
+nationalize/CDSG
+nationhood/M
+nationwide
+native/MYS
+nativity/SM
+natl
+natter/GMDS
+nattily
+nattiness/M
+natty/PTR
+natural's
+natural/UPY
+naturalism/M
+naturalist/SM
+naturalistic
+naturalization/M
+naturalize/DSG
+naturalness/UM
+naturals
+nature's
+nature/CS
+naturism
+naturist/S
+naught/MS
+naughtily
+naughtiness/M
+naughty/PTR
+nausea/M
+nauseam
+nauseate/GDS
+nauseating/Y
+nauseous/PY
+nauseousness/M
+nautical/Y
+nautilus/MS
+naval
+nave/MS
+navel/SM
+navigability/M
+navigable
+navigate/DSGN
+navigation/M
+navigational
+navigator/MS
+navvy/S
+navy/SM
+nay/SM
+naysayer/MS
+nave/RYT
+navety/M
+navet/M
+ne'er
+neanderthal/MS
+neap/MS
+near/DRYSPTG
+nearby
+nearness/M
+nearshore
+nearside
+nearsighted/YP
+nearsightedness/M
+neat/NRYPXT
+neaten/GD
+neath
+neatness/M
+neato
+nebula/M
+nebulae
+nebular
+nebulous/PY
+nebulousness/M
+necessarily/U
+necessary/SM
+necessitate/DSG
+necessitous
+necessity/SM
+neck/MDSG
+neckband/S
+neckerchief/MS
+necking/M
+necklace/MGDSJ
+neckline/MS
+necktie/MS
+necrology/M
+necromancer/SM
+necromancy/M
+necrophilia
+necrophiliac/S
+necropolis/MS
+necroses
+necrosis/M
+necrotic
+nectar/M
+nectarine/MS
+nee
+need/MDSG
+needed/U
+needful/Y
+neediness/M
+needle/MGDS
+needlepoint/M
+needless/YP
+needlessness/M
+needlewoman/M
+needlewomen
+needlework/M
+needn't
+needy/PTR
+nefarious/YP
+nefariousness/M
+neg
+negate/DSGNVX
+negation/M
+negative/MYGPDS
+negativeness/M
+negativism/M
+negativity/M
+neglect/SGMD
+neglectful/YP
+neglectfulness/M
+negligee/MS
+negligence/M
+negligent/Y
+negligible
+negligibly
+negotiability/M
+negotiable/A
+negotiate/ADSGN
+negotiation/AM
+negotiations
+negotiator/MS
+negritude/M
+negro
+negroid
+neigh/MDG
+neighbor/SMDYG
+neighborhood/SM
+neighborliness/M
+neighs
+neither
+nelson/SM
+nematode/SM
+nemeses
+nemesis/M
+neoadjuvant
+neoclassic
+neoclassical
+neoclassicism/M
+neocolonialism/M
+neocolonialist/MS
+neocon/SM
+neoconservative/SM
+neocortex
+neodymium/M
+neolithic
+neologism/SM
+neon/M
+neonatal
+neonate/MS
+neophilia
+neophyte/MS
+neoplasm/MS
+neoplastic
+neoprene/M
+nepenthe/M
+nephew/SM
+nephrite/M
+nephritic
+nephritis/M
+nephropathy
+nepotism/M
+nepotist/SM
+nepotistic
+neptunium/M
+nerd/MS
+nerdy/RT
+nerve's
+nerve/UDSG
+nerveless/YP
+nervelessness/M
+nerviness/M
+nervous/YP
+nervousness/M
+nervy/TPR
+nest/MDSG
+nestle/GJDS
+nestling/M
+net/SM
+netball
+netbook/MS
+nether
+nethermost
+netherworld/M
+netiquette/S
+netted
+netter/S
+netting/M
+nettle/MGDS
+nettlesome
+network/SGMD
+networking/M
+neural/Y
+neuralgia/M
+neuralgic
+neurasthenia/M
+neurasthenic/MS
+neuritic/MS
+neuritis/M
+neurocysticercoses
+neurocysticercosis
+neurological/Y
+neurologist/SM
+neurology/M
+neuron/MS
+neuronal
+neurophysiology's
+neuroscience/MS
+neuroscientist/MS
+neuroses
+neurosis/M
+neurosurgeon/MS
+neurosurgery/M
+neurosurgical
+neurotic/MS
+neurotically
+neuroticism
+neurotoxin/S
+neurotransmitter/SM
+neut
+neuter/MDGS
+neutral/SMY
+neutralism/M
+neutralist/SM
+neutrality/M
+neutralization/M
+neutralize/DRSZG
+neutralizer/M
+neutrino/SM
+neutron/SM
+never
+nevermore
+nevertheless
+nevi
+nevus/M
+new/STMRYP
+newbie/MS
+newborn/SM
+newcomer/SM
+newel/SM
+newfangled
+newfound
+newish
+newline/S
+newlywed/SM
+newness/M
+news/M
+newsagent/S
+newsboy/SM
+newscast/SMRZ
+newscaster/M
+newsdealer/SM
+newsflash/S
+newsgirl/SM
+newsgroup/MS
+newshound/S
+newsletter/MS
+newsman/M
+newsmen
+newspaper/MS
+newspaperman/M
+newspapermen
+newspaperwoman/M
+newspaperwomen
+newspeak
+newsprint/M
+newsreader/S
+newsreel/MS
+newsroom/MS
+newsstand/SM
+newsweekly/SM
+newswires
+newswoman/M
+newswomen
+newsworthiness/M
+newsworthy/P
+newsy/TR
+newt/MS
+newton/MS
+next/M
+nexus/MS
+niacin/M
+nib/SM
+nibble/MZGDRS
+nibbler/M
+nice/PYTR
+niceness/M
+nicety/SM
+niche/SM
+nick/MDRSZG
+nickel/MS
+nickelodeon/SM
+nicker/MDG
+nickle/S
+nickname/DSMG
+nicotine/M
+niece/SM
+nifedipine
+niff
+niffy
+nifty/TR
+nigga/MS!
+niggard/SMY
+niggardliness/M
+niggaz/!
+nigger/SM!
+niggle/MZGDRS
+niggler/M
+nigh/RT
+night/SMY
+nightcap/SM
+nightclothes/M
+nightclub/SM
+nightclubbed
+nightclubbing
+nightdress/MS
+nightfall/M
+nightgown/SM
+nighthawk/SM
+nightie/M
+nightingale/SM
+nightlife/M
+nightlight/S
+nightlong
+nightmare/SM
+nightmarish
+nightshade/SM
+nightshirt/SM
+nightspot/MS
+nightstand/SM
+nightstick/SM
+nighttime/M
+nightwatchman
+nightwatchmen
+nightwear/M
+nighty/SM
+nihilism/M
+nihilist/MS
+nihilistic
+nil/M
+nimbi
+nimble/TPR
+nimbleness/M
+nimbly
+nimbus/M
+nimby
+nimrod/MS
+nincompoop/SM
+nine/MS
+ninepin/MS
+ninepins/M
+nineteen/SMH
+nineteenth/M
+nineteenths
+ninetieth/M
+ninetieths
+ninety/HSM
+ninja/SM
+ninny/SM
+ninth/M
+ninths
+niobium/M
+nip/SM
+nipped
+nipper/MS
+nippiness/M
+nipping
+nipple/MS
+nippy/TPR
+nirvana/M
+nisei/M
+nit/SMR
+nite/MS
+niter/M
+nitpick/SZGDR
+nitpicker/M
+nitpicking/M
+nitrate/DSMGN
+nitration/M
+nitric
+nitrification/M
+nitrile/S
+nitrite/SM
+nitro
+nitrocellulose/M
+nitrogen/M
+nitrogenous
+nitroglycerin/M
+nitroglycerine/M
+nitty
+nitty-gritty
+nitwit/MS
+nix/GMDS
+no/SM
+nob/SY
+nobble/GDS
+nobelium/M
+nobility/M
+noble/RSPMT
+nobleman/M
+noblemen
+nobleness/M
+noblewoman/M
+noblewomen
+nobody/SM
+nocturnal/Y
+nocturne/MS
+nod/SM
+nodal
+nodded
+nodding
+noddle/MS
+noddy
+node/MS
+nodular
+nodule/MS
+noel/MS
+noes
+noggin/MS
+nohow
+noise/DSMG
+noiseless/PY
+noiselessness/M
+noisemaker/MS
+noisily
+noisiness/M
+noisome
+noisy/PTR
+nomad/SM
+nomadic
+nomenclature/MS
+nominal/Y
+nominate/CASDXVNG
+nomination/ACM
+nominative/SM
+nominator/CSM
+nominee/MS
+non
+nonabrasive
+nonabsorbent/SM
+nonacademic
+nonacceptance/M
+nonacid
+nonactive/MS
+nonaddictive
+nonadhesive
+nonadjacent
+nonadjustable
+nonadministrative
+nonage/MS
+nonagenarian/MS
+nonaggression/M
+nonalcoholic
+nonaligned
+nonalignment/M
+nonallergic
+nonappearance/MS
+nonassignable
+nonathletic
+nonattendance/M
+nonautomotive
+nonavailability/M
+nonbasic
+nonbeliever/MS
+nonbelligerent/MS
+nonbinary
+nonbinding
+nonbreakable
+nonburnable
+noncaloric
+noncancerous
+nonce/M
+nonchalance/M
+nonchalant/Y
+nonchargeable
+nonclerical/MS
+nonclinical
+noncollectable
+noncom/MS
+noncombat
+noncombatant/MS
+noncombustible
+noncommercial/MS
+noncommittal/Y
+noncommunicable
+noncompeting
+noncompetitive
+noncompliance/M
+noncomplying
+noncomprehending
+nonconducting
+nonconductor/MS
+nonconforming
+nonconformism
+nonconformist/MS
+nonconformity/M
+nonconsecutive
+nonconstructive
+noncontagious
+noncontinuous
+noncontributing
+noncontributory
+noncontroversial
+nonconvertible
+noncooperation/M
+noncorroding
+noncorrosive
+noncredit
+noncriminal/SM
+noncritical
+noncrystalline
+noncumulative
+noncustodial
+nondairy
+nondeductible/M
+nondelivery/SM
+nondemocratic
+nondenominational
+nondepartmental
+nondepreciating
+nondescript
+nondestructive
+nondetachable
+nondeterminism
+nondeterministic
+nondisciplinary
+nondisclosure/M
+nondiscrimination/M
+nondiscriminatory
+nondramatic
+nondrinker/MS
+nondrying
+none
+noneducational
+noneffective
+nonelastic
+nonelectric
+nonelectrical
+nonempty
+nonenforceable
+nonentity/SM
+nonequivalent/MS
+nonessential
+nonesuch/MS
+nonetheless
+nonevent/MS
+nonexchangeable
+nonexclusive
+nonexempt/M
+nonexistence/M
+nonexistent
+nonexplosive/MS
+nonfactual
+nonfading
+nonfat
+nonfatal
+nonfattening
+nonferrous
+nonfiction/M
+nonfictional
+nonflammable
+nonflowering
+nonfluctuating
+nonflying
+nonfood/M
+nonfreezing
+nonfunctional
+nongovernmental
+nongranular
+nonhazardous
+nonhereditary
+nonhuman
+nonidentical
+noninclusive
+nonindependent
+nonindustrial
+noninfectious
+noninflammatory
+noninflationary
+noninflected
+nonintellectual/MS
+noninterchangeable
+noninterference/M
+nonintervention/M
+nonintoxicating
+noninvasive
+nonirritating
+nonissue
+nonjudgmental
+nonjudicial
+nonlegal
+nonlethal
+nonlinear
+nonliterary
+nonliving/M
+nonmagnetic
+nonmalignant
+nonmember/MS
+nonmetal/SM
+nonmetallic
+nonmigratory
+nonmilitant
+nonmilitary
+nonnarcotic/SM
+nonnative/MS
+nonnegative
+nonnegotiable
+nonnuclear
+nonnumerical
+nonobjective
+nonobligatory
+nonobservance/M
+nonobservant
+nonoccupational
+nonoccurence
+nonofficial
+nonoperational
+nonoperative
+nonparallel/MS
+nonpareil/MS
+nonparticipant/MS
+nonparticipating
+nonpartisan/SM
+nonpaying
+nonpayment/SM
+nonperformance/M
+nonperforming
+nonperishable
+nonperson/MS
+nonphysical/Y
+nonplus/S
+nonplussed
+nonplussing
+nonpoisonous
+nonpolitical
+nonpolluting
+nonporous
+nonpracticing
+nonprejudicial
+nonprescription
+nonproductive
+nonprofessional/SM
+nonprofit/SMB
+nonproliferation/M
+nonpublic
+nonpunishable
+nonracial
+nonradioactive
+nonrandom
+nonreactive
+nonreal
+nonreciprocal/SM
+nonreciprocating
+nonrecognition/M
+nonrecoverable
+nonrecurring
+nonredeemable
+nonrefillable
+nonrefundable
+nonreligious
+nonrenewable
+nonrepresentational
+nonresident/MS
+nonresidential
+nonresidual/M
+nonresistance/M
+nonresistant
+nonrestrictive
+nonreturnable/MS
+nonrhythmic
+nonrigid
+nonsalaried
+nonscheduled
+nonscientific
+nonscoring
+nonseasonal
+nonsectarian
+nonsecular
+nonsegregated
+nonsense/M
+nonsensical/Y
+nonsensitive
+nonsexist
+nonsexual
+nonskid
+nonslip
+nonsmoker/SM
+nonsmoking
+nonsocial
+nonspeaking
+nonspecialist/MS
+nonspecializing
+nonspecific
+nonspiritual/SM
+nonstaining
+nonstandard
+nonstarter/MS
+nonstick
+nonstop
+nonstrategic
+nonstriking
+nonstructural
+nonsuccessive
+nonsupport/GM
+nonsurgical
+nonsustaining
+nonsympathizer/M
+nontarnishable
+nontaxable
+nontechnical
+nontenured
+nontheatrical
+nonthinking
+nonthreatening
+nontoxic
+nontraditional
+nontransferable
+nontransparent
+nontrivial
+nontropical
+nonuniform
+nonunion
+nonuser/MS
+nonvenomous
+nonverbal
+nonviable
+nonviolence/M
+nonviolent/Y
+nonvirulent
+nonvocal
+nonvocational
+nonvolatile
+nonvoter/MS
+nonvoting
+nonwhite/MS
+nonworking
+nonyielding
+nonzero
+noodle/MGDS
+nook/MS
+nookie
+nooky
+noon/M
+noonday/M
+noontide/M
+noontime/M
+noose/SM
+nope
+nor
+nor'easter
+norm/MS
+normal/MY
+normalcy/M
+normality/M
+normalization/M
+normalize/DSG
+normative
+north/ZMR
+northbound
+northeast/MRZ
+northeaster/MY
+northeastern
+northeastward/S
+norther/MY
+northerly/SM
+northern/ZR
+northerner/M
+northernmost
+northward/S
+northwest/ZMR
+northwester/MY
+northwestern
+northwestward/S
+nose/MGDSJ
+nosebag/S
+nosebleed/MS
+nosecone/SM
+nosedive/DSMG
+nosegay/SM
+nosh/MDRSZG
+nosher/M
+nosily
+nosiness/M
+nostalgia/M
+nostalgic
+nostalgically
+nostril/MS
+nostrum/MS
+nosy/RPT
+not/B
+notability/SM
+notable/SM
+notably
+notarial
+notarization/M
+notarize/GDS
+notary/SM
+notate/GDS
+notation/FCSM
+notch/GMDS
+note's
+note/FCSDG
+notebook/MS
+notelet/S
+notepad/S
+notepaper/M
+noteworthiness/M
+noteworthy/P
+nothing/PSM
+nothingness/M
+notice/MGDS
+noticeable/U
+noticeably
+noticeboard/S
+noticed/U
+notifiable
+notification/M
+notifier/M
+notify/NDRSXZG
+notion/MS
+notional/Y
+notoriety/M
+notorious/Y
+notwithstanding
+notwork/S
+nougat/MS
+nought/MS
+noun/KMS
+nourish/DSLG
+nourishment/M
+nous
+nova/MS
+novae
+novel/SM
+novelette/SM
+novelist/SM
+novelization/MS
+novelize/DSG
+novella/MS
+novelty/SM
+novena/MS
+novene
+novice/MS
+novitiate/MS
+now/M
+nowadays/M
+noway/S
+nowhere/M
+nowise
+nowt
+noxious
+nozzle/MS
+nu/SM
+nuance/MDS
+nub/SM
+nubbin/MS
+nubby/TR
+nubile
+nuclear/K
+nucleate/DSGN
+nucleation/M
+nuclei
+nucleic
+nucleoli
+nucleolus/M
+nucleon/SM
+nucleoside
+nucleotide
+nucleus/M
+nuclide/S
+nude/MTRS
+nudge/GDSM
+nudism/M
+nudist/SM
+nudity/M
+nugatory
+nugget/SM
+nuisance/MS
+nuke/MGDS
+null/S
+nullification/M
+nullify/NDSG
+nullity/M
+numb/ZTGPDRYS
+number's
+number/ASDG
+numbered/U
+numberless
+numbing/Y
+numbness/M
+numbskull/SM
+numerable/I
+numeracy/IM
+numeral/SM
+numerate/XGNDS
+numeration/M
+numerator/MS
+numeric
+numerical/Y
+numerologist/MS
+numerology/M
+numerous/Y
+numinous
+numismatic/S
+numismatics/M
+numismatist/SM
+numskull/MS
+nun/SM
+nuncio/SM
+nunnery/SM
+nuptial/MS
+nurse/MZGDRS
+nurselings
+nursemaid/MS
+nurser/M
+nursery/SM
+nurseryman/M
+nurserymen
+nursing/M
+nursling/SM
+nurture/DRSMZG
+nurturer/M
+nut/SM
+nutcase/S
+nutcracker/MS
+nuthatch/MS
+nuthouse/S
+nutjob/S
+nutmeat/SM
+nutmeg/SM
+nutpick/SM
+nutria/SM
+nutrient/MS
+nutriment/MS
+nutrition/M
+nutritional/Y
+nutritionist/SM
+nutritious/YP
+nutritiousness/M
+nutritive
+nutshell/MS
+nutted
+nutter/S
+nuttiness/M
+nutting
+nutty/RTP
+nuzzle/DRSMZG
+nuzzler/M
+nybble/S
+nylon/MS
+nylons/M
+nymph/M
+nymphet/MS
+nympho/S
+nymphomania/M
+nymphomaniac/SM
+nymphs
+nystagmus
+ne
+o
+o'clock
+o'er
+oaf/SM
+oafish/PY
+oafishness/M
+oak/SMN
+oakum/M
+oar/SGMD
+oarlock/SM
+oarsman/M
+oarsmen
+oarswoman/M
+oarswomen
+oases
+oasis/M
+oat/SMN
+oatcake/SM
+oath/M
+oaths
+oatmeal/M
+oats/M
+ob/S
+obbligato/MS
+obduracy/M
+obdurate/PY
+obdurateness/M
+obedience/EM
+obedient/EY
+obeisance/SM
+obeisant
+obelisk/MS
+obese
+obesity/M
+obey/EDSG
+obfuscate/GNXDS
+obfuscation/M
+obi/SM
+obit/MS
+obituary/SM
+obj
+object/SGVMD
+objectify/NGDS
+objection/SMB
+objectionable/U
+objectionably
+objective/SMYP
+objectiveness/M
+objectivity/M
+objector/MS
+objurgate/XGNDS
+objurgation/M
+oblate/NX
+oblation/M
+obligate/DSXGN
+obligation/M
+obligatorily
+obligatory
+oblige/EGDS
+obliging/Y
+oblique/SMYP
+obliqueness/M
+obliquity/M
+obliterate/DSGN
+obliteration/M
+oblivion/M
+oblivious/YP
+obliviousness/M
+oblong/MS
+obloquy/M
+obnoxious/YP
+obnoxiousness/M
+oboe/MS
+oboist/MS
+obscene/RYT
+obscenity/SM
+obscurantism/M
+obscurantist/SM
+obscure/DRSYTG
+obscurity/SM
+obsequies
+obsequious/PY
+obsequiousness/M
+obsequy/M
+observable/U
+observably
+observance/MS
+observant/Y
+observation/SM
+observational
+observatory/SM
+observe/DRSBZG
+observed/U
+observer/M
+obsess/DSGV
+obsession/SM
+obsessional/Y
+obsessive/PSMY
+obsessiveness/M
+obsidian/M
+obsolesce/DSG
+obsolescence/M
+obsolescent
+obsolete/GDS
+obstacle/MS
+obstetric/S
+obstetrical
+obstetrician/SM
+obstetrics/M
+obstinacy/M
+obstinate/Y
+obstreperous/YP
+obstreperousness/M
+obstruct/DGVS
+obstructed/U
+obstruction/SM
+obstructionism/M
+obstructionist/MS
+obstructive/YP
+obstructiveness/M
+obtain/DBLGS
+obtainable/U
+obtainment/M
+obtrude/DSG
+obtrusion/M
+obtrusive/UPY
+obtrusiveness/UM
+obtuse/YTRP
+obtuseness/M
+obverse/SM
+obviate/DSGN
+obviation/M
+obvious/PY
+obviousness/M
+ocarina/MS
+occasion/GMDS
+occasional/Y
+occidental/SM
+occlude/GDS
+occlusion/SM
+occlusive
+occult/M
+occultism/M
+occultist/SM
+occupancy/M
+occupant/SM
+occupation/AM
+occupational/Y
+occupations
+occupied/U
+occupier/SM
+occupy/ADSG
+occur/AS
+occurred/A
+occurrence/SM
+occurring/A
+ocean/SM
+oceanfront/SM
+oceangoing
+oceanic/M
+oceanographer/SM
+oceanographic
+oceanography/M
+oceanology/M
+ocelot/MS
+och/R
+ocher/M
+ocker/S
+octagon/MS
+octagonal
+octal
+octane/MS
+octant/S
+octantal
+octave/MS
+octavo/MS
+octet/SM
+octogenarian/SM
+octopi
+octopus/MS
+octothorp
+octothorpe
+ocular/MS
+oculist/SM
+oculomotor
+odalisque/SM
+odd/STRYLP
+oddball/SM
+oddity/SM
+oddment/SM
+oddness/M
+odds/M
+ode/SM
+odious/YP
+odiousness/M
+odium/M
+odometer/MS
+odor/MDS
+odoriferous
+odorless
+odorous
+odyssey/MS
+oedipal
+oenology/M
+oenophile/SM
+oeuvre/MS
+of
+off/SZGDRJ
+offal/M
+offbeat/MS
+offend/ZGDRS
+offender/M
+offense/MS
+offensive's
+offensive/IPY
+offensiveness/IM
+offensives
+offer/JGMD
+offering/M
+offertory/SM
+offhand
+offhanded/PY
+offhandedness/M
+office/MZRS
+officeholder/SM
+officer/M
+official/MYS
+officialdom/M
+officialese
+officialism/M
+officiant/SM
+officiate/DSG
+officiator/MS
+officious/PY
+officiousness/M
+offing/M
+offish
+offline
+offload/SDG
+offprint/SM
+offset/MS
+offsetting
+offshoot/MS
+offshore/G
+offside
+offsite
+offspring/M
+offstage/S
+offtrack
+oft
+often/TR
+oftentimes
+ofttimes
+ogle/MZGDRS
+ogler/M
+ogre/MS
+ogreish
+ogress/MS
+oh/M
+ohm/SM
+ohmmeter/MS
+oho
+ohs
+oi
+oik/S
+oil/SGMD
+oilcan/S
+oilcloth/M
+oilcloths
+oilfield/S
+oiliness/M
+oilman
+oilmen
+oilskin/MS
+oilskins/M
+oily/RPT
+oink/MDSG
+ointment/SM
+okapi/SM
+okay/MDSG
+okra/MS
+old/STMNRP
+oldie/SM
+oldish
+oldness/M
+oldster/MS
+ole/SMV
+oleaginous
+oleander/MS
+oleo/M
+oleomargarine/M
+olfactory/SM
+oligarch/M
+oligarchic
+oligarchical
+oligarchs
+oligarchy/SM
+oligo
+oligonucleotide/S
+oligopoly/SM
+olive/SM
+ol/M
+om/SMNX
+ombudsman/M
+ombudsmen
+omega/SM
+omelet/MS
+omelette/MS
+omen/M
+omicron/MS
+ominous/YP
+ominousness/M
+omission/MS
+omit/S
+omitted
+omitting
+omnibus/MS
+omnidirectional
+omnipotence/M
+omnipotent
+omnipresence/M
+omnipresent
+omniscience/M
+omniscient
+omnivore/MS
+omnivorous/PY
+omnivorousness/M
+on/Y
+onboard
+once/M
+oncogene/SM
+oncologist/SM
+oncology/M
+oncoming
+one/SXMNP
+oneness/M
+onerous/PY
+onerousness/M
+oneself
+onetime
+ongoing
+onion/M
+onionskin/M
+online
+onlooker/SM
+onlooking
+onomatopoeia/M
+onomatopoeic
+onomatopoetic
+onrush/MSG
+onscreen
+onset/MS
+onshore
+onside
+onsite
+onslaught/MS
+onstage
+onto
+ontogeny/M
+ontological
+ontology/M
+onus/MS
+onward
+onyx/MS
+oodles/M
+ooh/GD
+oohs
+oomph
+oops
+ooze/MGDS
+oozy/TR
+op/SMDG
+opacity/M
+opal/MS
+opalescence/M
+opalescent
+opaque/PYTGDRS
+opaqueness/M
+opcode/S
+ope/S
+open/ZTGJPMDRYS
+opencast
+opened/U
+opener/M
+openhanded/P
+openhandedness/M
+openhearted
+opening/M
+openness/M
+opensource
+openwork/M
+opera/MS
+operable/I
+operand/S
+operate/DSGNVX
+operatic
+operatically
+operation/M
+operational/Y
+operationalize/GDS
+operative/SM
+operator/SM
+operetta/SM
+ophthalmic
+ophthalmologist/SM
+ophthalmology/M
+opiate/SM
+opine/GNXDS
+opinion/M
+opinionated
+opioid/SM
+opium/M
+opossum/MS
+opp
+opponent/SM
+opportune/IY
+opportunism/M
+opportunist/SM
+opportunistic
+opportunistically
+opportunity/SM
+oppose/DRSBG
+opposed/U
+opposite/SMYNX
+opposition/M
+oppositional
+oppress/DSGV
+oppression/M
+oppressive/YP
+oppressiveness/M
+oppressor/MS
+opprobrious/Y
+opprobrium/M
+opt/SGD
+optic/MS
+optical/Y
+optician/SM
+optics/M
+optima
+optimal/Y
+optimism/SM
+optimist/SM
+optimistic
+optimistically
+optimization/MS
+optimize/DRSG
+optimum/SM
+option/SMDG
+optional/Y
+optometrist/MS
+optometry/M
+opulence/M
+opulent/Y
+opus/MS
+or
+oracle/SM
+oracular
+oral/MYS
+orality
+orange/SMP
+orangeade/MS
+orangery/SM
+orangutan/SM
+orate/GNXDS
+oration/M
+orator/SM
+oratorical/Y
+oratorio/MS
+oratory/SM
+orb/SM
+orbicular
+orbit/MDRZGS
+orbital/SM
+orbiter/M
+orc/SM
+orchard/SM
+orchestra/MS
+orchestral
+orchestrate/DSXGN
+orchestration/M
+orchid/SM
+ordain/SDLG
+ordainment/M
+ordeal/SM
+order/EAMDGS
+ordered/U
+orderings
+orderliness/EM
+orderly/PSM
+ordinal/SM
+ordinance/SM
+ordinarily
+ordinariness/M
+ordinary/SMP
+ordinate/MNSX
+ordination/M
+ordnance/M
+ordure/M
+ore/SM
+oregano/M
+org
+organ/MS
+organdy/M
+organelle/MS
+organic/SM
+organically/I
+organism/MS
+organismic
+organist/MS
+organization/ASM
+organizational/Y
+organize/AESDG
+organized/U
+organizer/MS
+organza/M
+orgasm/SM
+orgasmic
+orgiastic
+orgy/SM
+oriel/MS
+orient's
+orient/AEDGS
+oriental/MS
+orientalist/S
+orientate/EDSGN
+orientation/AEM
+orientations
+orienteering
+orifice/MS
+orig
+origami/M
+origin/SM
+original/MYS
+originality/M
+originate/DSGN
+origination/M
+originator/SM
+oriole/SM
+orison/SM
+ormolu/M
+ornament/SGMD
+ornamental
+ornamentation/M
+ornate/YP
+ornateness/M
+orneriness/M
+ornery/PRT
+ornithological
+ornithologist/MS
+ornithology/M
+orotund
+orotundity/SM
+orphan/SMDG
+orphanage/MS
+orris/MS
+orthodontia/M
+orthodontic/S
+orthodontics/M
+orthodontist/SM
+orthodox/U
+orthodoxy/SM
+orthogonal
+orthogonality
+orthographic
+orthographically
+orthography/SM
+orthopedic/S
+orthopedics/M
+orthopedist/MS
+orzo/M
+oscillate/GNDSX
+oscillation/M
+oscillator/SM
+oscillatory
+oscilloscope/MS
+osculate/DSXGN
+osculation/M
+osier/MS
+osmium/M
+osmosis/M
+osmotic
+osprey/SM
+ossicles
+ossification/M
+ossify/NGDS
+ostensible
+ostensibly
+ostentation/M
+ostentatious/Y
+osteoarthritis/M
+osteopath/M
+osteopathic
+osteopaths
+osteopathy/M
+osteoporosis/M
+ostler/S
+ostracism/M
+ostracize/GDS
+ostrich/MS
+other/MSP
+otherwise
+otherworldly
+otiose
+otter/MS
+ottoman/MS
+oubliette/MS
+ouch
+ought
+oughtn't
+ounce/MS
+our/S
+ourselves
+oust/ZGDRS
+ouster/M
+out/SJGMDR
+outage/SM
+outargue/GDS
+outback/MS
+outbalance/DSG
+outbid/S
+outbidding
+outboard/MS
+outboast/DSG
+outbound
+outbox/MS
+outbreak/MS
+outbuilding/MS
+outburst/SM
+outcast/MS
+outclass/DSG
+outcome/MS
+outcrop/MS
+outcropped
+outcropping/SM
+outcry/SM
+outdated
+outdid
+outdistance/GDS
+outdo/G
+outdoes
+outdone
+outdoor/S
+outdoors/M
+outdoorsy
+outdraw/GS
+outdrawn
+outdrew
+outercourse
+outermost
+outerwear/M
+outface/GDS
+outfall/S
+outfield/SMRZ
+outfielder/M
+outfight/SG
+outfit/SM
+outfitted
+outfitter/MS
+outfitting
+outflank/GSD
+outflow/MS
+outfought
+outfox/GDS
+outgo/MJG
+outgoes
+outgrew
+outgrow/HGS
+outgrown
+outgrowth/M
+outgrowths
+outguess/GDS
+outgun/S
+outgunned
+outgunning
+outhit/S
+outhitting
+outhouse/SM
+outing/M
+outlaid
+outlandish/PY
+outlandishness/M
+outlast/DSG
+outlaw/SGMD
+outlay/SGM
+outlet/SM
+outlier/MS
+outline/MGDS
+outlive/GDS
+outlook/MS
+outlying
+outmaneuver/GDS
+outmatch/GDS
+outmoded
+outnumber/DSG
+outpace/GDS
+outpatient/MS
+outperform/GSD
+outplace/L
+outplacement/M
+outplay/GDS
+outpoint/DGS
+outpost/MS
+outpouring/MS
+outproduce/DSG
+output/SM
+outputted
+outputting
+outrace/GDS
+outrage/MGDS
+outrageous/Y
+outran
+outrank/GDS
+outre
+outreach/MDSG
+outrider/MS
+outrigger/SM
+outright
+outrun/S
+outrunning
+outr
+outscore/GDS
+outsell/GS
+outset/SM
+outshine/GS
+outshone
+outshout/GDS
+outside/MZRS
+outsider/M
+outsize/MDS
+outskirt/MS
+outsmart/GDS
+outsold
+outsource/DSG
+outsourcing/M
+outspend/SG
+outspent
+outspoken/YP
+outspokenness/M
+outspread/GS
+outstanding/Y
+outstation/MS
+outstay/DGS
+outstretch/DSG
+outstrip/S
+outstripped
+outstripping
+outta
+outtake/MS
+outvote/GDS
+outward/YS
+outwear/GS
+outweigh/GD
+outweighs
+outwit/S
+outwith
+outwitted
+outwitting
+outwore
+outwork/MDRSZG
+outworn
+ouzo/MS
+ova
+oval/MS
+ovarian
+ovary/SM
+ovate/NX
+ovation/M
+oven/MS
+ovenbird/SM
+ovenproof
+ovenware
+over/MYS
+overabundance/M
+overabundant
+overachieve/ZGDRS
+overachiever/M
+overact/GVSD
+overage/SM
+overaggressive
+overall/SM
+overalls/M
+overambitious
+overanxious
+overarching
+overarm/GSD
+overate
+overattentive
+overawe/DSG
+overbalance/MGDS
+overbear/GS
+overbearing/Y
+overbid/SM
+overbidding
+overbite/MS
+overblown
+overboard
+overbold
+overbook/DGS
+overbore
+overborne
+overbought
+overbroad
+overbuild/SG
+overbuilt
+overburden/GSD
+overbuy/GS
+overcame
+overcapacity/M
+overcapitalize/DSG
+overcareful
+overcast/MGS
+overcautious
+overcharge/DSMG
+overclock/GD
+overcloud/SGD
+overcoat/MS
+overcome/GS
+overcompensate/DSGN
+overcompensation/M
+overconfidence/M
+overconfident
+overconscientious
+overcook/DGS
+overcritical
+overcrowd/SDG
+overcrowding/M
+overdecorate/DSG
+overdependent
+overdevelop/SDG
+overdid
+overdo/G
+overdoes
+overdone
+overdose/MGDS
+overdraft/SM
+overdraw/GS
+overdrawn
+overdress/GMDS
+overdrew
+overdrive/SM
+overdub/SM
+overdubbed
+overdubbing
+overdue
+overeager
+overeat/GSN
+overemotional
+overemphasis/M
+overemphasize/GDS
+overenthusiastic
+overestimate/MGNDS
+overestimation/M
+overexcite/DSG
+overexercise/GDS
+overexert/SDG
+overexertion/M
+overexpose/GDS
+overexposure/M
+overextend/DGS
+overfed
+overfeed/GS
+overfill/DGS
+overflew
+overflight/MS
+overflow/MDSG
+overflown
+overfly/GS
+overfond
+overfull
+overgeneralize/DSG
+overgenerous
+overgraze/DSG
+overgrew
+overground
+overgrow/HSG
+overgrown
+overgrowth/M
+overhand/MDS
+overhang/MSG
+overhasty
+overhaul/MDSG
+overhead/MS
+overhear/SG
+overheard
+overheat/DSG
+overhung
+overinclusion
+overinclusive
+overindulge/GDS
+overindulgence/M
+overindulgent
+overinflated
+overjoy/GSD
+overkill/M
+overladen
+overlaid
+overlain
+overland
+overlap/SM
+overlapped
+overlapping
+overlarge
+overlay/GSM
+overleaf
+overlie
+overload/GMDS
+overlong
+overlook/GMDS
+overlord/MS
+overly/SG
+overmanned
+overmanning
+overmaster/SDG
+overmodest
+overmuch/S
+overnice
+overnight/MS
+overoptimism/M
+overoptimistic
+overpaid
+overparticular
+overpass/MS
+overpay/GS
+overplay/GDS
+overpopulate/GNDS
+overpopulation/M
+overpower/SDG
+overpowering/Y
+overpraise/DSG
+overprecise
+overprice/DSG
+overprint/SMDG
+overproduce/GDS
+overproduction/M
+overprotect/SDGV
+overqualified
+overran
+overrate/GDS
+overreach/GDS
+overreact/SDG
+overreaction/SM
+overrefined
+overrich/P
+overridden
+override/MGS
+overripe/M
+overrode
+overrule/GDS
+overrun/SM
+overrunning
+oversampling
+oversaw
+oversea/S
+oversee/RSZ
+overseeing
+overseen
+overseer/M
+oversell/GS
+oversensitive/P
+oversensitiveness/M
+oversexed
+overshadow/DSG
+overshare/DSG
+overshoe/MS
+overshoot/GS
+overshot
+oversight/SM
+oversimple
+oversimplification/M
+oversimplify/DSNGX
+oversize/D
+oversleep/GS
+overslept
+oversold
+overspecialization/M
+overspecialize/GDS
+overspend/SG
+overspent
+overspread/GS
+overstaffed
+overstate/DSLG
+overstatement/MS
+overstay/DSG
+overstep/S
+overstepped
+overstepping
+overstimulate/DSG
+overstock/GSD
+overstretch/GDS
+overstrict
+overstrung
+overstuffed
+oversubscribe/DSG
+oversubtle
+oversupply/GDS
+oversuspicious
+overt/Y
+overtake/GS
+overtaken
+overtax/GDS
+overthink/SG
+overthought
+overthrew
+overthrow/SMG
+overthrown
+overtime/MS
+overtire/GDS
+overtone/MS
+overtook
+overture/MS
+overturn/DSG
+overuse/DSMG
+overvaluation/S
+overvalue/DSG
+overview/MS
+overweening/Y
+overweight/M
+overwhelm/SGD
+overwhelming/Y
+overwinter/SDG
+overwork/GMDS
+overwrite/GS
+overwritten
+overwrote
+overwrought
+overzealous
+oviduct/SM
+oviparous
+ovoid/MS
+ovular
+ovulate/DSGN
+ovulation/M
+ovule/MS
+ovum/M
+ow
+owe/DSG
+owl/SM
+owlet/MS
+owlish/Y
+own/ESGD
+owner/MS
+ownership/M
+ox/MN
+oxalate
+oxblood/M
+oxbow/MS
+oxcart/SM
+oxford/SM
+oxidant/MS
+oxidase
+oxidation/M
+oxidative
+oxide/MS
+oxidization/M
+oxidize/ZGDRS
+oxidizer/M
+oxtail/S
+oxyacetylene/M
+oxygen/M
+oxygenate/DSGN
+oxygenation/M
+oxymora
+oxymoron/M
+oxymoronic
+oxymoronically
+oy
+oyes
+oyez
+oyster/SM
+oz
+ozone/M
+p/NRXTGJ
+pH
+pa/SMH
+pablum/M
+pabulum/M
+pace/MZGDRS
+pacemaker/SM
+pacer/M
+pacesetter/SM
+pacey
+pachyderm/MS
+pachysandra/MS
+pacific
+pacifically
+pacification/M
+pacifier/M
+pacifism/M
+pacifist/SM
+pacifistic
+pacify/ZGDRSN
+pack's
+pack/AUGSD
+package's
+package/AGDS
+packager/SM
+packaging/M
+packer/MS
+packet/MS
+packing's
+packinghouse/SM
+packsaddle/MS
+pact/MS
+pacy/RT
+pad/SM
+padded
+padding/M
+paddle/MZGDRS
+paddler/M
+paddock/MDGS
+paddy/SM
+padlock/MDSG
+padre/SM
+paean/SM
+paella/MS
+pagan/SM
+paganism/M
+page/MZGDRS
+pageant/MS
+pageantry/M
+pageboy/SM
+pager/M
+paginate/DSGN
+pagination/M
+pagoda/MS
+pah
+paid/AU
+pail/MS
+pailful/SM
+pain/MDSG
+painful/PY
+painfuller
+painfullest
+painfulness/M
+painkiller/MS
+painkilling
+painless/PY
+painlessness/M
+painstaking/MY
+paint/SZGJMDR
+paintball
+paintbox/MS
+paintbrush/MS
+painted/U
+painter/MY
+painting/M
+paintwork
+pair/AMDSG
+paired/U
+pairing/S
+pairwise
+paisley/SM
+pajama/S
+pajamas/M
+pal/SMY
+palace/MS
+paladin/SM
+palanquin/SM
+palatable/U
+palatal/SM
+palatalization/M
+palatalize/GDS
+palate/MBS
+palatial/Y
+palatinate/MS
+palatine/MS
+palaver/GSMD
+palazzi
+palazzo
+pale/MYTGPDRSJ
+paleface/MS
+paleness/M
+paleo
+paleographer/MS
+paleography/M
+paleolithic
+paleontologist/SM
+paleontology/M
+palette/SM
+palfrey/SM
+palimony/M
+palimpsest/MS
+palindrome/MS
+palindromic
+paling/M
+palisade/SM
+palish
+pall/MDSG
+palladium/M
+pallbearer/MS
+pallet/MS
+palliate/DSGNV
+palliation/M
+palliative/SM
+pallid/YP
+pallidness/M
+pallor/M
+palm/MDSG
+palmate
+palmetto/SM
+palmist/SM
+palmistry/M
+palmtop/SM
+palmy/TR
+palomino/MS
+palpable
+palpably
+palpate/DSGN
+palpation/M
+palpitate/XGNDS
+palpitation/M
+palsy/GDSM
+paltriness/M
+paltry/RPT
+pampas/M
+pamper/DSG
+pamphlet/MS
+pamphleteer/MS
+pan/SM
+panacea/SM
+panache/M
+panama/MS
+panatella/S
+pancake/DSMG
+panchromatic
+pancreas/MS
+pancreatic
+pancreatitis
+panda/SM
+pandemic/SM
+pandemonium/M
+pander/MDRZGS
+panderer/M
+pane/KM
+panegyric/SM
+panel/SGJMD
+paneling/M
+panelist/MS
+panes
+pang/MS
+panhandle/DRSMZG
+panhandler/M
+panic/SM
+panicked
+panicking
+panicky
+panned
+pannier/SM
+panning
+panoply/SM
+panorama/SM
+panoramic
+panpipes/M
+pansy/SM
+pant/MDSG
+pantaloons/M
+pantechnicon/S
+pantheism/M
+pantheist/SM
+pantheistic
+pantheon/SM
+panther/MS
+pantie/M
+panto/S
+pantomime/MGDS
+pantomimic
+pantomimist/SM
+pantry/SM
+pantsuit/SM
+panty/SM
+pantyhose/M
+pantyliner/M
+pantywaist/SM
+pap/SM
+papa/MS
+papacy/SM
+papal
+paparazzi/M
+paparazzo
+papaw/SM
+papaya/MS
+paper/SZGMDR
+paperback/SM
+paperbark/S
+paperboard/M
+paperboy/SM
+paperclip/S
+paperer/M
+papergirl/SM
+paperhanger/SM
+paperhanging/M
+paperless
+paperweight/MS
+paperwork/M
+papery
+papilla/M
+papillae
+papillary
+papist/MS
+papoose/MS
+pappy/SM
+paprika/M
+papyri
+papyrus/M
+par/SZGMDRBJ
+para/MS
+parable/MS
+parabola/SM
+parabolic
+paracetamol/S
+parachute/DSMG
+parachutist/MS
+paracord
+parade/MZGDRS
+parader/M
+paradigm/SM
+paradigmatic
+paradisaical
+paradise/SM
+paradox/MS
+paradoxical/Y
+paraffin/M
+paragliding
+paragon/MS
+paragraph/GMD
+paragraphs
+parakeet/SM
+paralegal/MS
+parallax/MS
+parallel/SGMD
+paralleled/U
+parallelism/MS
+parallelization/MS
+parallelize/GDS
+parallelogram/SM
+paralyses
+paralysis/M
+paralytic/SM
+paralyze/DSG
+paralyzing/Y
+paramagnetic
+paramecia
+paramecium/M
+paramedic/MS
+paramedical/MS
+parameter/MS
+parameterize/D
+parametric
+parametrize/D
+paramilitary/SM
+paramount
+paramountcy
+paramour/SM
+paranoia/M
+paranoiac/MS
+paranoid/SM
+paranormal
+parapet/MS
+paraphernalia/M
+paraphrase/DSMG
+paraplegia/M
+paraplegic/SM
+paraprofessional/MS
+parapsychologist/MS
+parapsychology/M
+paraquat/M
+parasailing
+parascending
+parasite/SM
+parasitic
+parasitical/Y
+parasitism/M
+parasol/MS
+parasympathetic/S
+parathion/M
+parathyroid/MS
+paratroop/RZS
+paratrooper/M
+paratroops/M
+paratyphoid/M
+parboil/DSG
+parcel/GMDS
+parch/LGDS
+parchment/SM
+pardner/S
+pardon/ZGMDRBS
+pardonable/U
+pardonably/U
+pardoner/M
+pare/S
+paregoric/M
+parent/GMDS
+parentage/M
+parental
+parentheses
+parenthesis/M
+parenthesize/DSG
+parenthetic
+parenthetical/Y
+parenthood/M
+parenting/M
+parer/M
+pares/S
+paresis/M
+parfait/MS
+pariah/M
+pariahs
+paribus
+parietal
+parimutuel/MS
+paring/M
+parish/MS
+parishioner/MS
+parity/ESM
+park/MDSG
+parka/SM
+parking/M
+parkland
+parkour
+parkway/MS
+parky
+parlance/M
+parlay/GMDS
+parley/GMDS
+parliament/SM
+parliamentarian/SM
+parliamentary
+parlor/MS
+parlous
+parmigiana
+parmigiano
+parochial/Y
+parochialism/M
+parodist/SM
+parody/GDSM
+parole/MGDS
+parolee/MS
+paronychia
+parotid
+paroxysm/SM
+paroxysmal
+parquet/MDSG
+parquetry/M
+parred
+parricidal
+parricide/MS
+parring
+parrot/GMDS
+parry/GDSM
+parse/DRSZG
+parsec/MS
+parsimonious/Y
+parsimony/M
+parsley/M
+parsnip/MS
+parson/MS
+parsonage/MS
+part's
+part/CDSG
+partake/ZGRS
+partaken
+partaker/M
+parterre/SM
+parthenogenesis/M
+partial/MYS
+partiality/M
+participant/SM
+participate/DSGN
+participation/M
+participator/MS
+participatory
+participial/M
+participle/MS
+particle/SM
+particleboard/M
+particular/SMY
+particularity/SM
+particularization/M
+particularize/DSG
+particulate/SM
+parting/MS
+partisan/SM
+partisanship/M
+partition/GMDS
+partitions/A
+partitive/MS
+partizan/SM
+partly
+partner/MDSG
+partnership/MS
+partook
+partridge/SM
+parturition/M
+partway
+party/GDSM
+partygoers
+parvenu/MS
+pascal/MS
+paschal
+pasha/SM
+pass/M
+passably
+passage/MS
+passageway/MS
+passbook/MS
+passe/DRSBXZGNV
+passel/MS
+passenger/SM
+passer/M
+passerby/M
+passersby
+passim
+passing/MY
+passion/EM
+passionate/EY
+passionflower/SM
+passionless
+passive/PMYS
+passiveness/M
+passivity/M
+passivization
+passivize/DSG
+passkey/MS
+passphrase/S
+passport/MS
+password/MS
+pass
+past/AMS
+pasta/SM
+paste/DSMG
+pasteboard/M
+pastel/MS
+pastern/MS
+pasteurization/M
+pasteurize/ZGDRS
+pasteurized/U
+pasteurizer/M
+pastiche/MS
+pastie
+pastille/MS
+pastime/MS
+pastiness/M
+pastor/MS
+pastoral/MS
+pastorate/MS
+pastrami/M
+pastry/SM
+pasturage/M
+pasture/DSMG
+pastureland/M
+pasty/PTRSM
+pat/SM
+patch/EGMDS
+patchily
+patchiness/M
+patchouli
+patchwork/SM
+patchy/TPR
+pate/MS
+patella/MS
+patellae
+patent/GMDYS
+paterfamilias/MS
+paternal/Y
+paternalism/M
+paternalist/S
+paternalistic
+paternity/M
+paternoster/MS
+path/M
+pathetic
+pathetically
+pathfinder/SM
+pathless
+pathogen/SM
+pathogenic
+pathological/Y
+pathologist/SM
+pathology/M
+pathos/M
+paths
+pathway/MS
+patience/M
+patient/IMST
+patienter
+patiently
+patina/MS
+patine
+patio/SM
+patisserie/S
+patois/M
+patresfamilias
+patriarch/M
+patriarchal
+patriarchate/MS
+patriarchs
+patriarchy/SM
+patrician/SM
+patricidal
+patricide/SM
+patrimonial
+patrimony/SM
+patriot/SM
+patriotic/U
+patriotically
+patriotism/M
+patrol/MS
+patrolled
+patrolling
+patrolman/M
+patrolmen
+patrolwoman/M
+patrolwomen
+patron/MS
+patronage/MS
+patroness/MS
+patronize/ZGDRS
+patronizer/M
+patronizing/Y
+patronymic/SM
+patronymically
+patroon/SM
+patsy/SM
+patted
+patter/MDGS
+pattern/SMDG
+patting
+patty/SM
+paucity/M
+paunch/MS
+paunchy/RT
+pauper/MS
+pauperism/M
+pauperize/DSG
+pause/DSMG
+pave/AZGDRS
+paved/U
+pavement/MS
+pavilion/SM
+paving/MS
+pavlova/S
+paw/SGMD
+pawl/MS
+pawn/MDSG
+pawnbroker/MS
+pawnbroking/M
+pawnshop/MS
+pawpaw/MS
+pax
+pay's
+pay/ASGBL
+payback/SM
+paycheck/MS
+payday/MS
+payed
+payee/SM
+payer/SM
+payload/SM
+paymaster/SM
+payment/ASM
+payoff/MS
+payola/M
+payout/MS
+payphone/S
+payroll/SM
+payslip/SM
+paywall/SM
+payware
+pct
+pd
+pea/SM
+peace/SM
+peaceable
+peaceably
+peaceful/PY
+peacefulness/M
+peacekeeper/SM
+peacekeeping/M
+peacemaker/MS
+peacemaking/M
+peacetime/M
+peach/MS
+peachy/TR
+peacock/MS
+peafowl/MS
+peahen/MS
+peak/MDSG
+peaky
+peal/AMDSG
+peanut/MS
+pear/MYS
+pearl/SGMD
+pearly/RT
+peasant/SM
+peasantry/M
+peashooter/SM
+peat/M
+peaty/TR
+pebble/MGDS
+pebbly
+pebibyte/SM
+pecan/SM
+peccadillo/M
+peccadilloes
+peccary/SM
+peck/MDRSZG
+peckish
+pecs
+pectic
+pectin/M
+pectoral/MS
+pectoralis
+peculate/GNDS
+peculation/M
+peculator/SM
+peculiar/Y
+peculiarity/SM
+pecuniary
+pedagogic
+pedagogical/Y
+pedagogue/SM
+pedagogy/M
+pedal/SGMD
+pedalo/S
+pedant/MS
+pedantic
+pedantically
+pedantry/M
+peddle/ZGDRS
+peddler/M
+pederast/MS
+pederasty/M
+pedestal/MS
+pedestrian/SM
+pedestrianization
+pedestrianize/GDS
+pediatric/S
+pediatrician/MS
+pediatrics/M
+pedicab/SM
+pedicure/MGDS
+pedicurist/MS
+pedigree/MDS
+pediment/MS
+pedometer/MS
+pedophile/S
+pedophilia
+peduncle/MS
+pee/DRSMZ
+peeing
+peek/MDSG
+peekaboo/M
+peel/MDRSJZG
+peeled/U
+peeler/M
+peeling/M
+peen/MS
+peep/MDRSZG
+peepbo
+peeper/M
+peephole/MS
+peepshow/MS
+peer/MDG
+peerage/SM
+peeress/MS
+peerless
+peeve/DSMG
+peevish/PY
+peevishness/M
+peewee/MS
+peewit/S
+peg/SM
+pegboard/MS
+pegged
+pegging
+peignoir/SM
+pejoration/M
+pejorative/SMY
+peke/MS
+pekinese/SM
+pekingese/SM
+pekoe/M
+pelagic
+pelf/M
+pelican/MS
+pellagra/M
+pellet/GMDS
+pellucid
+pelmet/S
+pelt/MDSG
+pelvic
+pelvis/MS
+pemmican/M
+pen/M
+penal
+penalization/M
+penalize/DSG
+penalty/SM
+penance/MS
+pence
+penchant/SM
+pencil/GMDJS
+pend/CDSG
+pendant/MS
+pendency
+pendent/MS
+pendulous
+pendulum/MS
+penetrability/M
+penetrable
+penetrate/DSGNVX
+penetrating/Y
+penetration/M
+penfriend/S
+penguin/MS
+penicillin/M
+penile
+peninsula/SM
+peninsular
+penis/MS
+penitence/M
+penitent/SMY
+penitential
+penitentiary/SM
+penknife/M
+penknives
+penlight/SM
+penman/M
+penmanship/M
+penmen
+pennant/MS
+penned
+penniless
+penning
+pennon/MS
+penny/SM
+pennyweight/MS
+pennyworth
+penologist/MS
+penology/M
+pension/BZGMDRS
+pensioner/M
+pensive/PY
+pensiveness/M
+pent
+pentacle/MS
+pentagon/MS
+pentagonal
+pentagram/SM
+pentameter/SM
+pentathlete/MS
+pentathlon/MS
+penthouse/SM
+penuche/M
+penultimate/SM
+penumbra/MS
+penumbrae
+penurious/PY
+penuriousness/M
+penury/M
+peon/MS
+peonage/M
+peony/SM
+people/MGDS
+pep/SM
+pepped
+pepper/GMDS
+peppercorn/SM
+peppermint/SM
+pepperoni/MS
+peppery
+peppiness/M
+pepping
+peppy/TPR
+pepsin/M
+peptic/MS
+peptide/S
+peradventure/M
+perambulate/XGNDS
+perambulation/M
+perambulator/MS
+percale/MS
+perceive/BGDS
+perceived/U
+percent/MS
+percentage/SM
+percentile/SM
+perceptible
+perceptibly
+perception/SM
+perceptional
+perceptive/PY
+perceptiveness/M
+perceptual/Y
+perch/GMDS
+perchance
+percipience/M
+percipient
+percolate/GNDS
+percolation/M
+percolator/SM
+percussion/AM
+percussionist/MS
+percussive
+perdition/M
+perdurable
+peregrinate/DSXGN
+peregrination/M
+peregrine/MS
+peremptorily
+peremptory
+perennial/SMY
+perestroika/M
+perfect/PTGMDRYS
+perfecta/MS
+perfectibility/M
+perfectible
+perfection/SM
+perfectionism/M
+perfectionist/SM
+perfectness/M
+perfidious/Y
+perfidy/SM
+perforate/GNXDS
+perforation/M
+perforce
+perform/SDRZG
+performance/SM
+performant
+performative
+performed/U
+performer/M
+perfume/DRSMZG
+perfumer/M
+perfumery/SM
+perfunctorily
+perfunctory
+perfusion
+pergola/SM
+perhaps
+pericardia
+pericardial
+pericarditis
+pericardium/M
+perigee/SM
+perihelia
+perihelion/M
+peril/SGMD
+perilous/Y
+perimeter/SM
+perinatal
+perinea
+perineum/M
+period/MS
+periodic
+periodical/SMY
+periodicity/M
+periodontal
+periodontics/M
+periodontist/SM
+peripatetic/MS
+peripheral/MYS
+periphery/SM
+periphrases
+periphrasis/M
+periphrastic
+periscope/SM
+perish/BDRSZG
+perishable/MS
+peristalses
+peristalsis/M
+peristaltic
+peristyle/SM
+peritoneal
+peritoneum/MS
+peritonitis/M
+periwig/SM
+periwinkle/SM
+perjure/DRSZG
+perjurer/M
+perjury/SM
+perk/MDSG
+perkily
+perkiness/M
+perky/TPR
+perm/MDSG
+permafrost/M
+permalink/SM
+permanence/M
+permanency/M
+permanent/SMY
+permeability/M
+permeable
+permeate/GNDS
+permeation/M
+permissibility
+permissible
+permissibly
+permission/MS
+permissive/PY
+permissiveness/M
+permit/MS
+permitted
+permittee
+permitting
+permittivity
+permutation/SM
+permute/DSG
+pernicious/YP
+perniciousness/M
+peroration/MS
+peroxide/MGDS
+perpendicular/SMY
+perpendicularity/M
+perpetrate/DSGN
+perpetration/M
+perpetrator/MS
+perpetual/SMY
+perpetuate/DSGN
+perpetuation/M
+perpetuity/M
+perplex/GDS
+perplexed/Y
+perplexing/Y
+perplexity/SM
+perquisite/SM
+persecute/GNXDS
+persecution/M
+persecutor/SM
+perseverance/M
+persevere/DSG
+persiflage/M
+persimmon/SM
+persist/SGD
+persistence/M
+persistent/Y
+persnickety
+person/UMS
+persona/SM
+personable
+personae
+personage/MS
+personal/MYS
+personality/SM
+personalization
+personalize/CDSG
+personalty/M
+personification/M
+personify/GDSNX
+personnel/M
+perspective/MS
+perspex
+perspicacious/Y
+perspicacity/M
+perspicuity/M
+perspicuous
+perspiration/M
+perspire/GDS
+persuade/BZGDRS
+persuaded/U
+persuader/M
+persuasion/SM
+persuasive/PY
+persuasiveness/M
+pert/RYPT
+pertain/GSD
+pertinacious/Y
+pertinacity/M
+pertinence/M
+pertinent/Y
+pertness/M
+perturb/DGS
+perturbation/SM
+perturbed/U
+pertussis/M
+peruke/MS
+perusal/MS
+peruse/GDS
+perv/S
+pervade/DSG
+pervasive/PY
+pervasiveness/M
+perverse/PXYN
+perverseness/M
+perversion/M
+perversity/M
+pervert/SGMD
+peseta/MS
+peskily
+peskiness/M
+pesky/TPR
+peso/MS
+pessary/S
+pessimal
+pessimism/M
+pessimist/SM
+pessimistic
+pessimistically
+pest/MRSZ
+pester/GD
+pesticide/MS
+pestiferous
+pestilence/SM
+pestilent
+pestilential
+pestle/MGDS
+pesto/M
+pet/SZMR
+petabyte/MS
+petajoule/S
+petal/SMD
+petard/MS
+petawatt/S
+petcock/SM
+peter/GMD
+petiole/SM
+petite/MS
+petition/ZGMDRS
+petitionary
+petitioner/M
+petrel/MS
+petrifaction/M
+petrify/DSG
+petrochemical/SM
+petrodollar/MS
+petrol/M
+petrolatum/M
+petroleum/M
+petrologist/SM
+petrology/M
+petted
+petticoat/MS
+pettifog/S
+pettifogged
+pettifogger/SM
+pettifoggery/M
+pettifogging
+pettily
+pettiness/M
+petting/M
+pettish/Y
+petty/PTR
+petulance/M
+petulant/Y
+petunia/MS
+pew/SM
+pewee/SM
+pewit/SM
+pewter/MS
+peyote/M
+pf
+pfennig/MS
+pg
+phaeton/MS
+phage/S
+phagocyte/SM
+phalanger/SM
+phalanges
+phalanx/MS
+phalli
+phallic
+phallocentric
+phallocentrism
+phallus/M
+phantasm/MS
+phantasmagoria/MS
+phantasmagorical
+phantasmal
+phantom/SM
+pharaoh/M
+pharaohs
+pharisaic
+pharisee/SM
+pharma/MS
+pharmaceutic/MS
+pharmaceutical/SM
+pharmaceutics/M
+pharmacist/MS
+pharmacologic
+pharmacological
+pharmacologist/SM
+pharmacology/M
+pharmacopeia/SM
+pharmacopoeia/MS
+pharmacotherapy
+pharmacy/SM
+pharyngeal
+pharynges
+pharyngitis/M
+pharynx/M
+phase/DSMG
+phaseout/SM
+phat
+pheasant/MS
+phenacetin/M
+phenobarbital/M
+phenol/M
+phenom/MS
+phenomena
+phenomenal/Y
+phenomenological
+phenomenology
+phenomenon/MS
+phenotype
+phenytoin
+pheromone/MS
+phew
+phi/SM
+phial/SM
+philander/ZGDRS
+philanderer/M
+philandering/M
+philanthropic
+philanthropically
+philanthropist/MS
+philanthropy/SM
+philatelic
+philatelist/MS
+philately/M
+philharmonic/SM
+philippic/MS
+philistine/MS
+philistinism/M
+philodendron/SM
+philological
+philologist/MS
+philology/M
+philosopher/MS
+philosophic
+philosophical/Y
+philosophize/DRSZG
+philosophizer/M
+philosophy/SM
+philter/MS
+phimosis/S
+phish/ZGDR
+phisher/M
+phlebitis/M
+phlebotomist/MS
+phlebotomize/GDS
+phlebotomy
+phlegm/M
+phlegmatic
+phlegmatically
+phloem/M
+phlogiston/S
+phlox/M
+pho
+phobia/MS
+phobic/MS
+phoebe/MS
+phoenix/MS
+phone/DSMG
+phonecard/S
+phoneme/MS
+phonemic
+phonemically
+phonetic/S
+phonetically
+phonetician/SM
+phonetics/M
+phoneyed
+phoneying
+phonic/S
+phonically
+phonics/M
+phoniness/M
+phonograph/M
+phonographic
+phonographs
+phonological/Y
+phonologist/MS
+phonology/M
+phonon
+phony/PTGDRSM
+phooey
+phosphate/MS
+phosphine/MS
+phosphodiesterase
+phosphor/MS
+phosphorescence/M
+phosphorescent/Y
+phosphoric
+phosphorous
+phosphorus/M
+phosphorylate/DSGN
+photo/SGMD
+photocell/MS
+photocopier/M
+photocopy/DRSMZG
+photodetector/S
+photoelectric
+photoelectrically
+photoengrave/DRSJZG
+photoengraver/M
+photoengraving/M
+photofinishing/M
+photogenic
+photogenically
+photograph/MDRZG
+photographer/M
+photographic
+photographically
+photographs/A
+photography/M
+photojournalism/M
+photojournalist/SM
+photometer/MS
+photon/MS
+photosensitive
+photosensor/S
+photosensory
+photostat/SM
+photostatic
+photostatted
+photostatting
+photosynthesis/M
+photosynthesize/GDS
+photosynthetic
+phototropic
+phototropism
+phototypesetter
+phototypesetting
+photovoltaic
+phrasal
+phrase's
+phrase/AGDS
+phrasebook/S
+phraseology/M
+phrasing/MS
+phreaking
+phrenologist/SM
+phrenology/M
+phyla
+phylactery/SM
+phyllo
+phylogeny/M
+phylum/M
+phys
+physic/SM
+physical/MYS
+physicality
+physician/SM
+physicist/SM
+physicked
+physicking
+physics/M
+physio/S
+physiognomy/SM
+physiography/M
+physiologic
+physiological/Y
+physiologist/MS
+physiology/M
+physiotherapist/MS
+physiotherapy/M
+physique/MS
+phytoplankton
+pi/SMDRHZG
+pianissimo/SM
+pianist/MS
+piano/SM
+pianoforte/SM
+pianola/S
+piaster/MS
+piazza/MS
+pibroch/M
+pibrochs
+pic/SM
+pica/M
+picador/MS
+picante
+picaresque
+picayune
+piccalilli/M
+piccolo/MS
+pick/MDRSJZG
+pickax/GMDS
+picker/M
+pickerel/MS
+picket/ZGMDRS
+pickings/M
+pickle/MGDS
+pickpocket/SM
+pickup/MS
+picky/PTR
+picnic/MS
+picnicked
+picnicker/SM
+picnicking
+picot/SM
+pictogram/S
+pictograph/M
+pictographs
+pictorial/MYS
+picture/MGDS
+picturesque/PY
+picturesqueness/M
+piddle/MGDS
+piddly
+pidgin/MS
+pie/SM
+piebald/MS
+piece/DSMG
+piecemeal
+piecewise
+piecework/MRZ
+pieceworker/M
+piecrust/SM
+pieing
+pier/M
+pierce/JGDS
+piercing/MY
+piety/M
+piezoelectric
+piffle/MG
+pig/SML
+pigeon/MS
+pigeonhole/DSMG
+pigged
+piggery/S
+pigging
+piggish/PY
+piggishness/M
+piggy/TRSM
+piggyback/MDSG
+pigheaded/PY
+pigheadedness/M
+piglet/MS
+pigment/MDS
+pigmentation/M
+pigpen/MS
+pigskin/MS
+pigsty/SM
+pigswill
+pigtail/MS
+pike/MZGDRS
+piker/M
+pikestaff/SM
+pikestaves
+pilaf/SM
+pilaster/MS
+pilchard/MS
+pile/MGDSJ
+pileup/MS
+pilfer/ZGDRS
+pilferage/M
+pilferer/M
+pilgrim/MS
+pilgrimage/MGDS
+piling/M
+pill/MDSG
+pillage/MZGDRS
+pillager/M
+pillar/MDS
+pillbox/MS
+pillion/MS
+pillock/S
+pillory/GDSM
+pillow/GMDS
+pillowcase/MS
+pillowslip/MS
+pilot/DGSM
+pilothouse/SM
+pimento/MS
+pimiento/MS
+pimp/GMDYS
+pimpernel/MS
+pimple/DSM
+pimply/RT
+pin/SM
+pinafore/MS
+pinata/MS
+pinball/M
+pincer/MS
+pinch/GMDS
+pincushion/MS
+pine's
+pine/AGDS
+pineapple/MS
+pinewood/S
+piney
+pinfeather/SM
+ping/GMD
+pinhead/SM
+pinhole/SM
+pinion/SMDG
+pink/TGPMDRS
+pinkeye/M
+pinkie/M
+pinkish
+pinkness/M
+pinko/MS
+pinky/SM
+pinnacle/SM
+pinnate
+pinned/U
+pinning/U
+pinny/S
+pinochle/M
+pinon/MS
+pinpoint/SGMD
+pinprick/MS
+pinsetter/SM
+pinstripe/DSM
+pint/MS
+pinto/MS
+pinup/MS
+pinwheel/GSMD
+piny/TR
+pinyin/M
+pinyon/SM
+pioneer/SGMD
+pious/YP
+piousness/M
+pip/SZGMDR
+pipe/MS
+pipeline/SM
+piper/M
+pipette/SM
+pipework
+piping/M
+pipit/MS
+pipped
+pippin/SM
+pipping
+pipsqueak/SM
+piquancy/M
+piquant/Y
+pique/MGDS
+piracy/M
+piranha/SM
+pirate/DSMG
+piratical/Y
+pirogi/M
+piroshki/M
+pirouette/DSMG
+pirozhki/M
+piscatorial
+pismire/SM
+piss/ZGMDRS
+pissoir/S
+pistachio/SM
+piste/S
+pistil/SM
+pistillate
+pistol/SM
+piston/SM
+pit/SM
+pita/MS
+pitapat/SM
+pitch/MDRSZG
+pitchblende/M
+pitcher/M
+pitchfork/MDSG
+pitchman/M
+pitchmen
+piteous/YP
+piteousness/M
+pitfall/SM
+pith/M
+pithead/S
+pithily
+pithiness/M
+pithy/RTP
+pitiable
+pitiably
+pitiful/Y
+pitiless/PY
+pitilessness/M
+piton/MS
+pitta/S
+pittance/MS
+pitted
+pitting
+pituitary/SM
+pity/GDSM
+pitying/Y
+pivot/MDGS
+pivotal
+pix/M
+pixel/MS
+pixelate/DS
+pixie/MS
+pizazz/M
+pizza/MS
+pizzazz/M
+pizzeria/SM
+pizzicati
+pizzicato/M
+piata/MS
+pion/SM
+pj's
+pk
+pkg
+pkt
+pkwy
+pl
+placard/SMDG
+placate/DSGN
+placation/M
+placatory
+place's
+place/AESDLG
+placebo/SM
+placed/U
+placeholder/MS
+placekick/MDRZGS
+placekicker/M
+placement/EASM
+placenta/SM
+placental/S
+placer/SM
+placid/Y
+placidity/M
+placings
+placket/SM
+plagiarism/SM
+plagiarist/SM
+plagiarize/DRSZG
+plagiarizer/M
+plagiary/M
+plague/DSMG
+plaice
+plaid/MS
+plain/MRYTSP
+plainchant
+plainclothes
+plainclothesman/M
+plainclothesmen
+plainness/M
+plainsman/M
+plainsmen
+plainsong/M
+plainspoken
+plaint/SMV
+plaintext
+plaintiff/SM
+plaintive/Y
+plait/MDGS
+plan/ZMRS
+planar
+plane's
+plane/CGDS
+planeload/MS
+planer/M
+planet/SM
+planetarium/SM
+planetary
+plangency/M
+plangent
+plank/MDGS
+planking/M
+plankton/M
+planned/U
+planner/SM
+planning/S
+plant/MDRZGSJ
+plantain/SM
+plantar
+plantation/MS
+planter/M
+planting/M
+plantlike
+plaque/SM
+plash/MDSG
+plasma/M
+plasmon
+plaster/SZGMDR
+plasterboard/M
+plasterer/M
+plastic/SM
+plasticity/M
+plasticize/DSG
+plastique
+plat/XGMDNS
+plate/MS
+plateau/SMDG
+plateful/SM
+platelet/SM
+platen/M
+platform/SGMD
+plating/M
+platinum/M
+platitude/SM
+platitudinous
+platonic
+platoon/SGMD
+platted
+platter/SM
+platting
+platy/M
+platypus/MS
+platys
+plaudit/SM
+plausibility/M
+plausible
+plausibly
+play/AEGMDS
+playable/EU
+playact/SGD
+playacting/M
+playback/MS
+playbill/MS
+playbook/MS
+playboy/SM
+player/SM
+playfellow/SM
+playful/PY
+playfulness/M
+playgirl/MS
+playgoer/MS
+playground/SM
+playgroup/S
+playhouse/MS
+playlist/MS
+playmate/MS
+playoff/SM
+playpen/SM
+playroom/SM
+playschool/S
+plaything/SM
+playtime/M
+playwright/SM
+plaza/MS
+plea/MS
+plead/ADRZGSJ
+pleader's
+pleading/MY
+pleasant/UTYP
+pleasanter
+pleasantness/UM
+pleasantry/SM
+please/EDSG
+pleasing/YS
+pleasurably
+pleasure/MGDSB
+pleasureful
+pleat/MDGS
+pleb/S
+plebby
+plebe/MS
+plebeian/MS
+plebiscite/MS
+plectra
+plectrum/MS
+pledge/DSMG
+plenary/SM
+plenipotentiary/SM
+plenitude/SM
+plenteous
+plentiful/Y
+plenty/M
+plenum/S
+pleonasm/MS
+plethora/M
+pleura/M
+pleurae
+pleurisy/M
+plexiglass/M
+plexus/MS
+pliability/M
+pliable
+pliancy/M
+pliant/Y
+pliers/M
+plight/SMDG
+plimsoll/S
+plinth/M
+plinths
+plod/S
+plodded
+plodder/MS
+plodding/S
+plonk/DRSZG
+plop/MS
+plopped
+plopping
+plosive/S
+plot/MS
+plotted
+plotter/SM
+plotting
+plover/SM
+plow/GMDS
+plowman/M
+plowmen
+plowshare/MS
+ploy's
+ploy/S
+pluck/MDSG
+pluckily
+pluckiness/M
+plucky/RPT
+plug's
+plug/US
+plugged/U
+plugging/U
+plughole/S
+plugin/SM
+plum/GMDS
+plumage/M
+plumb/MDRSZGJ
+plumbed/U
+plumber/M
+plumbing/M
+plume/MS
+plummet/SGMD
+plummy
+plump/MDRYSTGP
+plumpness/M
+plumy/RT
+plunder/SZGMDR
+plunderer/M
+plunge/DRSMZG
+plunger/M
+plunk/MDSG
+pluperfect/SM
+plural/SM
+pluralism/M
+pluralist/MS
+pluralistic
+plurality/SM
+pluralization/M
+pluralize/GDS
+plus/MS
+plush/MRYTP
+plushness/M
+plushy/RT
+plusses
+plutocracy/SM
+plutocrat/SM
+plutocratic
+plutonium/M
+pluvial
+ply/AGDSM
+plywood/M
+pm
+pneumatic
+pneumatically
+pneumococcal
+pneumococci
+pneumococcus
+pneumonia/M
+poach/DRSZG
+poacher/M
+poaching/M
+pock/GMDS
+pocket/SMDG
+pocketbook/SM
+pocketful/SM
+pocketknife/M
+pocketknives
+pockmark/MDGS
+pod/SM
+podcast/SMG
+podded
+podding
+podiatrist/SM
+podiatry/M
+podium/SM
+poem/MS
+poesy/M
+poet/MS
+poetaster/MS
+poetess/MS
+poetic/S
+poetical/Y
+poetry/M
+pogrom/SM
+poi/M
+poignancy/M
+poignant/Y
+poinciana/SM
+poinsettia/SM
+point/MDRSZG
+pointblank
+pointed/Y
+pointer/M
+pointillism/M
+pointillist/SM
+pointless/PY
+pointlessness/M
+pointy/TR
+poise/MGDS
+poison/SJZGMDR
+poisoner/M
+poisoning/M
+poisonous/Y
+poke/MZGDRS
+poker/M
+pokey/MS
+poky/TR
+pol/SGMD
+polar
+polarity/SM
+polarization/CM
+polarize/CDSG
+polarizer/S
+pole/MS
+poleaxe/GDS
+polecat/MS
+polemic/MS
+polemical/Y
+polemicist/SM
+polemics/M
+polestar/SM
+police/DSMG
+policeman/M
+policemen
+policewoman/M
+policewomen
+policy/SM
+policyholder/MS
+policymaker/S
+polio/MS
+poliomyelitis/M
+polish/ZGMDRS
+polished/U
+polisher/M
+politburo/MS
+polite/RYTP
+politeness/M
+politesse/M
+politic/S
+political/Y
+politician/SM
+politicization/M
+politicize/CDSG
+politicking/M
+politico/SM
+politics/M
+polity/SM
+polka/MDSG
+poll/GMDNS
+pollack/MS
+pollard/S
+pollen/M
+pollinate/GNDS
+pollination/M
+pollinator/SM
+polling/M
+polliwog/SM
+pollock/M
+pollster/SM
+pollutant/MS
+pollute/ZGNDRS
+polluted/U
+polluter/M
+pollution/M
+pollywog/MS
+polo/M
+polonaise/SM
+polonium/M
+poltergeist/MS
+poltroon/SM
+poly
+polyacrylamide
+polyamory/S
+polyandrous
+polyandry/M
+polyclinic/SM
+polyester/MS
+polyethylene/M
+polygamist/MS
+polygamous
+polygamy/M
+polyglot/SM
+polygon/SM
+polygonal
+polygraph/GMD
+polygraphs
+polyhedral
+polyhedron/SM
+polymath/M
+polymaths
+polymer/SM
+polymeric
+polymerization/M
+polymerize/GDS
+polymorphic
+polymorphically
+polymorphism
+polymorphous
+polynomial/MS
+polynucleotide/SM
+polyp/MS
+polypeptide/SM
+polyphonic
+polyphony/M
+polypropylene/M
+polys
+polysemous
+polystyrene/M
+polysyllabic
+polysyllable/MS
+polytechnic/MS
+polytheism/M
+polytheist/SM
+polytheistic
+polythene
+polyunsaturate/DS
+polyurethane/MS
+polyvinyl
+pom/S
+pomade/DSMG
+pomander/SM
+pomegranate/MS
+pommel/SGMD
+pommy/S
+pomp/M
+pompadour/SMD
+pompano/MS
+pompom/SM
+pomposity/M
+pompous/YP
+pompousness/M
+ponce/GDS
+poncho/SM
+poncy
+pond/MS
+ponder/SZGDR
+ponderer/M
+ponderous/YP
+ponderousness/M
+pone/MS
+pong/GDS
+pongee/M
+poniard/MS
+pontiff/SM
+pontifical/Y
+pontificate/DSMG
+pontoon/SM
+pony/GDSM
+ponytail/MS
+poo/SGD
+pooch/MDSG
+poodle/SM
+poof/MS
+poofter/S
+pooh/GMD
+poohs
+pool/GMDS
+poolroom/MS
+poolside/S
+poop/GMDS
+poor/TRYP
+poorboy/M
+poorhouse/SM
+poorness/M
+pop/SM
+popcorn/M
+pope/MS
+popgun/SM
+popinjay/MS
+poplar/SM
+poplin/M
+popover/SM
+poppa/MS
+poppadom/S
+popped
+popper/SM
+poppet/S
+popping
+poppy/SM
+poppycock/M
+populace/MS
+popular/Y
+popularity/UM
+popularization/M
+popularize/DSG
+populate/ACGDS
+populated/U
+population/CM
+populations
+populism/M
+populist/MS
+populous/P
+populousness/M
+popup/MS
+porcelain/SM
+porch/MS
+porcine
+porcupine/SM
+pore/MGDS
+porgy/SM
+pork/ZMR
+porker/M
+porky/RSMT
+porn/M
+porno/M
+pornographer/MS
+pornographic
+pornographically
+pornography/M
+porosity/M
+porous/P
+porousness/M
+porphyritic
+porphyry/M
+porpoise/MGDS
+porridge/M
+porringer/SM
+port's/A
+port/CAEGDS
+portability/M
+portable/MS
+portage/DSMG
+portal/SM
+portcullis/MS
+portend/SGD
+portent/SM
+portentous/YP
+porter/ASM
+porterhouse/SM
+portfolio/MS
+porthole/MS
+portico/M
+porticoes
+portiere/MS
+portion/KSGMD
+portire/MS
+portlet/SM
+portliness/M
+portly/RPT
+portmanteau/MS
+portrait/MS
+portraitist/SM
+portraiture/M
+portray/SGD
+portrayal/MS
+portulaca/M
+pose's/A
+pose/CAKEGDS
+poser/EKSM
+poseur/SM
+posh/TR
+posit/DSG
+position/CKEMS
+positional/KE
+positioned/K
+positioning/AK
+positive/EMYPS
+positiveness/M
+positivism
+positivist/S
+positivity/SM
+positron/MS
+poss
+posse/MS
+possess/AEVGSD
+possession/ASM
+possessive/SMYP
+possessiveness/M
+possessor/SM
+possibility/SM
+possible/SM
+possibly
+possum/SM
+post-partum
+post/ZGMDRSJ
+postage/M
+postal
+postbag/S
+postbox/S
+postcard/SM
+postcode/S
+postcolonial
+postconsonantal
+postdate/DSG
+postdoc/MS
+postdoctoral
+poster/M
+posterior/SM
+posterity/M
+postgraduate/SM
+posthaste
+posthitides
+posthitis
+posthumous/Y
+posthypnotic
+postie/S
+postilion/SM
+postillion/MS
+postindustrial
+posting/M
+postlude/SM
+postman/M
+postmark/SMDG
+postmaster/MS
+postmen
+postmenopausal
+postmeridian
+postmistress/MS
+postmodern
+postmodernism/M
+postmodernist/MS
+postmortem/SM
+postnasal
+postnatal/Y
+postoperative
+postpaid
+postpartum
+postpone/DSGL
+postponement/SM
+postprandial
+postscript/SM
+postseason/SM
+postsynaptic
+postulate/XDSMGN
+postulation/M
+postural
+posture/MGJDS
+posturing/M
+postwar
+postwoman
+postwomen
+posy/SM
+pot/CSM
+potability/M
+potable/SM
+potash/M
+potassium/M
+potato/M
+potatoes
+potbelly/DSM
+potboiler/SM
+potency/M
+potent/Y
+potentate/MS
+potential/MYS
+potentiality/SM
+potentiate/GDS
+potful/SM
+pothead/SM
+pother/SMDG
+potherb/SM
+potholder/MS
+pothole/DRSMZG
+pothook/SM
+potion/SM
+potluck/MS
+potpie/SM
+potpourri/SM
+potsherd/SM
+potshot/MS
+pottage/M
+potted
+potter/GSMD
+pottery/SM
+potting
+potty/PRSMT
+pouch/MDSG
+pouf/S
+pouffe/S
+poulterer/MS
+poultice/DSMG
+poultry/M
+pounce/DSMG
+pound's
+pound/KDRSZG
+poundage/M
+pounding/SM
+pour/GDSJ
+pout/ZGMDRS
+pouter/M
+poutine/S
+poverty/M
+pow
+powder/GSMD
+powdery
+power/MDSG
+powerboat/MS
+powerful/Y
+powerhouse/SM
+powerless/PY
+powerlessness/M
+powwow/SGMD
+pox/MS
+pp
+ppm
+ppr
+pr
+practicability/M
+practicably
+practical/SMY
+practicality/SM
+practice/DSMGB
+practiced/U
+practicum/SM
+practitioner/SM
+praecipe
+praetor/SM
+praetorian
+pragmatic/MS
+pragmatical/Y
+pragmatism/M
+pragmatist/MS
+prairie/SM
+praise/EDSMG
+praiseworthiness/M
+praiseworthy/P
+praline/SM
+pram/MS
+prance/DRSMZG
+prancer/M
+prancing/Y
+prang/DSG
+prank/MDSG
+prankster/SM
+praseodymium/M
+prat/S
+prate/MZGDRS
+prater/M
+pratfall/SM
+prattle/DRSMZG
+prattler/M
+prawn/MDSG
+pray/ZGDRS
+prayer/M
+prayerful/Y
+pre-fill/GDS
+pre-programmed
+pre-programming
+preach/DRSZGL
+preacher/M
+preachment/M
+preachy/RT
+preadolescence/SM
+preadolescent
+preamble/MGDS
+prearrange/LGDS
+prearrangement/M
+preassigned
+precancel/SMDG
+precancerous
+precarious/PY
+precariousness/M
+precast
+precaution/MS
+precautionary
+precede/DSG
+precedence/M
+precedent/SM
+precedential
+precept/SM
+preceptor/SM
+precession
+precessional
+precinct/MS
+preciosity/M
+precious/YP
+preciousness/M
+precipice/SM
+precipitant/MS
+precipitate/XMYGNDS
+precipitation/M
+precipitous/Y
+precis/M
+precise/DRSYTGNP
+preciseness/M
+precision/M
+preclude/GDS
+preclusion/SM
+precocious/YP
+precociousness/M
+precocity/M
+precognition/M
+precognitive
+precolonial
+preconceive/GDS
+preconception/SM
+precondition/MDGS
+precook/GSD
+precursor/SM
+precursory
+predate/DSG
+predator/MS
+predatory
+predawn
+predecease/GDS
+predecessor/SM
+predefined
+predesignate/GDS
+predestination/M
+predestine/DSG
+predetermination/M
+predetermine/ZGDRS
+predeterminer/M
+predicable
+predicament/MS
+predicate/MGNVDS
+predication/M
+predicative/Y
+predict/BGVSD
+predictability/UM
+predictable/U
+predictably/U
+prediction/SM
+predictor/MS
+predigest/GDS
+predilection/SM
+predispose/GDS
+predisposition/MS
+prednisone
+predominance/M
+predominant/Y
+predominate/YGDS
+preemie/SM
+preeminence/M
+preeminent/Y
+preempt/GVSD
+preemption/M
+preemptive/Y
+preen/DSG
+preexist/DGS
+preexistence/M
+pref
+prefab/SM
+prefabbed
+prefabbing
+prefabricate/DSGN
+prefabrication/M
+preface/DSMG
+prefatory
+prefect/SM
+prefecture/MS
+prefer/SBL
+preferably
+preference/MS
+preferential/Y
+preferment/M
+preferred
+preferring
+prefigure/GDS
+prefill/GSD
+prefix/MDSG
+preform/GSD
+prefrontal
+pregame/SM
+pregnancy/SM
+pregnant
+preheat/GSD
+prehensile
+prehistorian/S
+prehistoric
+prehistorical/Y
+prehistory/M
+prehuman
+preinstall/D
+prejudge/LGDS
+prejudgement/MS
+prejudgment/SM
+prejudice/MGDS
+prejudiced/U
+prejudicial
+prekindergarten/SM
+prelacy/M
+prelate/SM
+prelim/SM
+preliminarily
+preliminary/SM
+preliterate
+preload/SGD
+prelude/MS
+premarital
+premature/Y
+premed/SM
+premedical
+premeditate/DSGN
+premeditated/U
+premeditation/M
+premenstrual
+premier/SGMD
+premiere/MS
+premiership/MS
+premise/DSMG
+premium/SM
+premix/GDS
+premolar/SM
+premonition/MS
+premonitory
+prenatal/Y
+prenup/SM
+prenuptial
+preoccupation/SM
+preoccupy/DSG
+preoperative
+preordain/GDS
+preowned
+prep/MS
+prepackage/DSG
+prepacked
+prepaid
+preparation/SM
+preparatory
+prepare/ZGDRS
+prepared/UP
+preparedness/UM
+prepay/GSL
+prepayment/MS
+prepend/DGS
+preponderance/SM
+preponderant/Y
+preponderate/GDS
+preposition/SM
+prepositional/Y
+prepossess/GDS
+prepossessing/U
+prepossession/SM
+preposterous/Y
+prepped
+preppie/M
+prepping
+preppy/TRSM
+preprocess/DSG
+preprogrammed
+preprogramming
+prepubescence/M
+prepubescent/SM
+prepuce/MS
+prequel/MS
+prerecord/GSD
+preregister/SGD
+preregistration/M
+prerequisite/MS
+prerogative/SM
+pres
+presage/MGDS
+presbyopia/M
+presbyter/SM
+presbytery/SM
+preschool/SZMR
+preschooler/M
+prescience/M
+prescient/Y
+prescribe/DSG
+prescript/SVM
+prescription/SM
+prescriptive/Y
+preseason/SM
+presence/SM
+present/LMDRYZGSB
+presentably
+presentation/ASM
+presenter/M
+presentiment/SM
+presentment/SM
+preservation/M
+preservationist/SM
+preservative/SM
+preserve/BDRSMZG
+preserver/M
+preset/S
+presetting
+preshrank
+preshrink/GS
+preshrunk
+preside/GDS
+presidency/SM
+president/MS
+presidential
+presidia
+presidium/M
+presort/DGS
+press's
+press/ACGSD
+pressed/U
+presser/MS
+pressie/S
+pressing/SMY
+pressman/M
+pressmen
+pressure/DSMG
+pressured/U
+pressurization/M
+pressurize/CGDS
+pressurized/U
+pressurizer/SM
+prestidigitation/M
+prestige/M
+prestigious
+presto/SM
+presumably
+presume/GDSB
+presumption/SM
+presumptive
+presumptuous/YP
+presumptuousness/M
+presuppose/DSG
+presupposition/MS
+pretax
+preteen/MS
+pretend/DRZGS
+pretender/M
+pretense/SXMN
+pretension/M
+pretentious/UY
+pretentiousness/M
+preterit/SM
+preterite/MS
+preterm
+preternatural/Y
+pretest/DGS
+pretext/MS
+pretrial/S
+prettify/GDS
+prettily
+prettiness/M
+pretty/TGDRSMP
+pretzel/MS
+prev
+prevail/DGS
+prevalence/M
+prevalent
+prevaricate/DSGNX
+prevarication/M
+prevaricator/SM
+prevent/DBSGV
+preventable/U
+preventative/MS
+prevention/M
+preventive/SM
+preview/MDRSZG
+previous/Y
+prevision/MS
+prewar
+prey/GMDS
+prezzie/S
+priapic
+price's
+price/AGDS
+priceless
+pricey
+pricier
+priciest
+prick/MDRYSZG
+pricker/M
+prickle/MGDS
+prickliness/M
+prickly/PRT
+pride/MGDS
+prideful/Y
+prier/M
+priest/SMY
+priestess/MS
+priesthood/SM
+priestliness/M
+priestly/RTP
+prig/MS
+priggish/P
+priggishness/M
+prim/ZGDRYP
+primacy/M
+primal
+primarily
+primary/SM
+primate/MS
+prime/MS
+primer/M
+primeval
+priming/M
+primitive/SPMY
+primitiveness/M
+primmer
+primmest
+primness/M
+primogenitor/SM
+primogeniture/M
+primordial/Y
+primp/DSG
+primrose/SM
+primula/S
+prince/SMY
+princedom/SM
+princeliness/M
+princely/PRT
+princess/MS
+principal/SMY
+principality/SM
+principle/DSM
+principled/U
+print/AMDSG
+printable/U
+printer/MS
+printing/SM
+printmaking
+printout/SM
+prion/S
+prior/MS
+prioress/MS
+prioritization
+prioritize/DSG
+priority/SM
+priory/SM
+prism/MS
+prismatic
+prison/SZMR
+prisoner/M
+prissily
+prissiness/M
+prissy/PTR
+pristine
+prithee
+privacy/M
+private/XMYTNRS
+privateer/SM
+privation/CSM
+privatization/SM
+privatize/DSG
+privet/SM
+privilege/DSMG
+privileged/U
+privily
+privy/RSMT
+prize/MGDS
+prized/A
+prizefight/ZGSMR
+prizefighter/M
+prizefighting/M
+prizewinner/MS
+prizewinning
+pro/SM
+proactive/Y
+probabilistic
+probability/SM
+probable/SM
+probably
+probate/MN
+probation/ZMR
+probational
+probationary
+probationer/M
+probe/MGDSBJ
+probity/M
+problem/MS
+problematic/U
+problematical/Y
+probosces
+proboscis/MS
+procaine/M
+procaryote/SM
+procaryotic
+procedural
+procedure/SM
+proceed/GJDS
+proceeding/M
+proceeds/M
+process's
+process/AGDS
+processable
+processed/U
+procession/GD
+processional/MS
+processor/SM
+proclamation/MS
+proclivity/SM
+procrastinate/DSGN
+procrastination/M
+procrastinator/MS
+procreate/V
+proctor/GMDS
+procurement/M
+prod/MS
+prodigal/MYS
+prodigality/M
+prodigious/Y
+prodigy/SM
+produce's
+produce/AZGDRS
+producer/AM
+producible/A
+production/ASM
+productive/UY
+productiveness/M
+productivity/M
+prof/MS
+profanation/MS
+profane/PYGDS
+profaneness/M
+profanity/SM
+professed/Y
+profession/SM
+professional/MYS
+professionalism/M
+professionalization
+professionalize/DSG
+professor/SM
+professorial/Y
+professorship/SM
+proffer/GMDS
+proficiency/M
+proficient/MYS
+profit/BGD
+profitability/M
+profitable/U
+profitably/U
+profiteer/MDGS
+profiteering/M
+profiterole/SM
+profitless
+profligacy/M
+profligate/SMY
+profound/RYTP
+profoundness/M
+profundity/SM
+profuse/PY
+profuseness/M
+progenitor/SM
+progeny/M
+progesterone/M
+progestin/S
+prognathous
+prognoses
+prognosis/M
+prognostic/MS
+prognosticate/XGNDS
+prognostication/M
+prognosticator/MS
+program/CAS
+programed
+programing
+programmability
+programmable/MS
+programmatic
+programmed/AC
+programmer/MS
+programming/SM
+progress/MDSGV
+progression/MS
+progressive/PMYS
+progressiveness/M
+prohibit/DGVS
+prohibition/SM
+prohibitionist/MS
+prohibitive/Y
+prohibitory
+project/GMDS
+projectile/SM
+projection/SM
+projectionist/SM
+projector/MS
+prokaryote/MS
+prokaryotic
+prole/S
+proletarian/MS
+proletariat/M
+proliferate/DSGN
+proliferation/M
+prolific
+prolifically
+prolix/Y
+prolixity/M
+prologue/SM
+prolongation/SM
+prom/M
+promenade/MGDS
+promethium/M
+prominence/M
+prominent/Y
+promiscuity/M
+promiscuous/Y
+promise/DMG
+promising/Y
+promissory
+promo/M
+promontory/SM
+promote/DRZG
+promoter/M
+promotional
+prompt/JPSMDRYZTG
+prompted/U
+prompter/M
+prompting/M
+promptitude/M
+promptness/M
+promulgate/GNDS
+promulgation/M
+promulgator/MS
+pronate/DSGN
+pronator/SM
+prone/P
+proneness/M
+prong/MDS
+pronghorn/MS
+pronominal/M
+pronounce/DSLG
+pronounceable/U
+pronouncement/SM
+pronto
+pronunciation/MS
+proof/ADGSM
+proofread/SRZG
+proofreader/M
+prop/MS
+propaganda/M
+propagandist/MS
+propagandize/GDS
+propagate/DSGN
+propagation/M
+propagator/SM
+propel/S
+propellant/MS
+propelled
+propeller/SM
+propelling
+propensity/SM
+proper/MRYT
+property/DSM
+prophecy/SM
+prophesier/M
+prophesy/DRSMZG
+prophet/SM
+prophetess/MS
+prophetic
+prophetical/Y
+prophylactic/SM
+prophylaxes
+prophylaxis/M
+propinquity/M
+propitiate/DSGN
+propitiation/M
+propitiatory
+propitious/Y
+proponent/SM
+proportion/ESM
+proportional/YS
+proportionality
+proportionate/EY
+proposal/MS
+propped
+propping
+propranolol
+proprietary/SM
+proprieties/M
+proprietor/SM
+proprietorial/Y
+proprietorship/SM
+proprietress/MS
+propriety/SM
+propulsion/M
+propulsive
+propyl
+prorate/DSGN
+prorogation/M
+prorogue/GD
+prosaic
+prosaically
+proscenium/SM
+prosciutto/M
+proscribe/DG
+proscription/MS
+prose/M
+prosecute/DSBXGN
+prosecution/M
+prosecutor/MS
+prosecutorial
+proselyte/DSMG
+proselytism/M
+proselytize/DRSZG
+proselytizer/M
+prosocial
+prosody/SM
+prospect/MDGVS
+prospective/Y
+prospector/SM
+prospectus/MS
+prosper/GSD
+prosperity/M
+prosperous/Y
+prostate/MS
+prostheses
+prosthesis/M
+prosthetic/S
+prostitute/MGNDS
+prostitution/M
+prostrate/GNXDS
+prostration/M
+prosy/RT
+protactinium/M
+protagonist/SM
+protean
+protect/GVSD
+protected/U
+protection/SM
+protectionism/M
+protectionist/MS
+protective/PY
+protectiveness/M
+protector/MS
+protectorate/MS
+protege/SM
+protegee/S
+protein/SM
+protestant/S
+protestation/MS
+protestor/MS
+prothonotarial
+prothonotary/S
+protocol/MS
+proton/SM
+protoplasm/M
+protoplasmic
+prototype/MGS
+prototypical
+protozoa
+protozoan/MS
+protozoic
+protract/GD
+protrude/GDS
+protrusile
+protrusion/MS
+protuberance/MS
+protuberant
+protg/MS
+protge/S
+proud/RYT
+prov/NB
+provability/M
+provably
+prove/EAGDS
+proved/U
+proven/U
+provenance/SM
+provender/M
+provenience/M
+proverbial/Y
+provide/DRSZG
+provided/U
+providence/M
+provident/Y
+providential/Y
+provider/M
+province/MS
+provincial/SMY
+provincialism/M
+provisional/Y
+proviso/SM
+provocateur/S
+provocative/PY
+provocativeness/M
+provoke/DRSZG
+provoked/U
+provoker/M
+provoking/Y
+provolone/M
+provost/SM
+prow/MS
+prowess/M
+prowl/MDRSZG
+prowler/M
+proximal
+proximate
+proximity/M
+proxy/SM
+prude/MS
+prudence/M
+prudent/Y
+prudential/Y
+prudery/M
+prudish/YP
+prudishness/M
+prune/MZGDRS
+pruner/M
+pruno
+prurience/M
+prurient/Y
+pry/ZTGDRSM
+prcis/MDG
+psalm/MS
+psalmist/SM
+psaltery/SM
+psephologist/S
+psephology
+pseud/S
+pseudo/S
+pseudonym/SM
+pseudonymous
+pseudorandom/Y
+pseudoscience/MS
+pseudy
+pshaw/MS
+psi/SM
+psittacosis/M
+psoriasis/M
+psst
+psych/MDSG
+psyche/M
+psychedelia
+psychedelic/SM
+psychedelically
+psychiatric
+psychiatrist/SM
+psychiatry/M
+psychic/MS
+psychical/Y
+psycho/SM
+psychoactive
+psychoanalyses
+psychoanalysis/M
+psychoanalyst/SM
+psychoanalytic
+psychoanalytical/Y
+psychoanalyze/DSG
+psychobabble/M
+psychodrama/MS
+psychogenic
+psychokinesis
+psychokinetic
+psychological/Y
+psychologist/MS
+psychology/SM
+psychometric
+psychomotor
+psychoneuroses
+psychoneurosis/M
+psychopath/M
+psychopathic
+psychopathology
+psychopaths
+psychopathy/M
+psychopharmacology
+psychophysiology
+psychos/S
+psychosis/M
+psychosomatic
+psychotherapist/MS
+psychotherapy/SM
+psychotic/SM
+psychotically
+psychotropic/MS
+psychs
+pt/C
+ptarmigan/MS
+pterodactyl/MS
+ptomaine/SM
+pub/SM
+pubertal
+puberty/M
+pubes/M
+pubescence/M
+pubescent
+pubic
+pubis/M
+public/AM
+publican/AMS
+publication/ASM
+publicist/MS
+publicity/M
+publicize/GDS
+publicly
+publish/AGDS
+publishable
+published/U
+publisher/MS
+publishing/M
+puce/M
+puck/ZMRS
+pucker/MDG
+puckish/YP
+puckishness/M
+pud/S
+pudding/SM
+puddle/DSMG
+puddling/M
+pudenda
+pudendum/M
+pudginess/M
+pudgy/PRT
+pueblo/SM
+puerile
+puerility/M
+puerperal
+puff/ZGMDRS
+puffball/SM
+puffer/M
+puffin/SM
+puffiness/M
+puffy/PRT
+pug/SM
+pugilism/M
+pugilist/SM
+pugilistic
+pugnacious/YP
+pugnaciousness/M
+pugnacity/M
+puke/MGDS
+pukka
+pulchritude/M
+pulchritudinous
+pule/GDS
+pull/ZGMDRS
+pullback/MS
+puller/M
+pullet/SM
+pulley/SM
+pullout/MS
+pullover/SM
+pulmonary
+pulp/GMDS
+pulpiness/M
+pulpit/SM
+pulpwood/M
+pulpy/RPT
+pulsar/SM
+pulsate/XGNDS
+pulsation/M
+pulse/AMGDS
+pulverization/M
+pulverize/DSG
+puma/MS
+pumice/SM
+pummel/SGD
+pump/ZGMDRS
+pumper/M
+pumpernickel/M
+pumpkin/MS
+pun/SM
+punch/MDRSZG
+punchbag/S
+puncheon/MS
+puncher/M
+punchline/S
+punchy/TR
+punctilio/M
+punctilious/PY
+punctiliousness/M
+punctual/Y
+punctuality/M
+punctuate/GNDS
+punctuation/M
+puncture/DSMG
+pundit/SM
+punditry/M
+pungency/M
+pungent/Y
+puniness/M
+punish/BLGDS
+punished/U
+punishing/Y
+punishment/MS
+punitive/Y
+punk/TMRS
+punned
+punnet/S
+punning
+punster/SM
+punt/ZGMDRS
+punter/M
+puny/TRP
+pup/SM
+pupa/M
+pupae
+pupal
+pupate/DSG
+pupil/MS
+pupped
+puppet/MS
+puppeteer/SM
+puppetry/M
+pupping
+puppy/SM
+purblind
+purchase/DRSMZGB
+purchaser/M
+purdah/M
+pure/PYTR
+purebred/SM
+puree/MDS
+pureeing
+pureness/M
+purgative/SM
+purgatorial
+purgatory/SM
+purge/MZGDRS
+purger/M
+purification/M
+purifier/M
+purify/NDRSZG
+purine/MS
+purism/M
+purist/MS
+puristic
+puritan/SM
+puritanical/Y
+puritanism/M
+purity/M
+purl/GMDS
+purlieu/SM
+purloin/SGD
+purple/MTRS
+purplish
+purport/SMDG
+purported/Y
+purpose's
+purpose/ADSG
+purposeful/YP
+purposefulness/M
+purposeless/PY
+purposely
+purr/GMDS
+purse/MZGDRS
+purser/M
+pursuance/M
+pursuant
+pursue/ZGDRS
+pursuer/M
+pursuit/SM
+purulence/M
+purulent
+purvey/DSG
+purveyance/M
+purveyor/SM
+purview/M
+pus/M
+push/ZGMDRS
+pushbike/S
+pushcart/SM
+pushchair/S
+pusher/M
+pushily
+pushiness/M
+pushover/MS
+pushpin/S
+pushup/MS
+pushy/TRP
+pusillanimity/M
+pusillanimous/Y
+puss/MS
+pussy/TRSM
+pussycat/MS
+pussyfoot/DSG
+pustular
+pustule/SM
+put/ISM
+putative
+putdown/SM
+putout/MS
+putrefaction/M
+putrefactive
+putrefy/GDS
+putrescence/M
+putrescent
+putrid
+putsch/MS
+putt/ZGMDRS
+putted/I
+puttee/MS
+putter/MDRZG
+putterer/M
+putting/I
+putty/GDSM
+putz/S
+puzzle/MZGDRSL
+puzzlement/M
+puzzler/M
+pvt
+pwn/SGD
+pyelonephritis
+pygmy/SM
+pylon/SM
+pylori
+pyloric
+pylorus/M
+pyorrhea/M
+pyramid/GSMD
+pyramidal
+pyre/MS
+pyrimidine/MS
+pyrite/SM
+pyrites/M
+pyromania/M
+pyromaniac/SM
+pyrotechnic/S
+pyrotechnical
+pyrotechnics/M
+pyruvate
+python/SM
+pyx/MS
+pzazz
+q
+qr
+qt/S
+qty
+qua
+quack/GMDS
+quackery/M
+quad/MS
+quadrangle/SM
+quadrangular
+quadrant/MS
+quadraphonic
+quadratic/MS
+quadrature
+quadrennial
+quadrennium/MS
+quadriceps/MS
+quadrilateral/SM
+quadrille/XMNS
+quadrillion/M
+quadriplegia/M
+quadriplegic/SM
+quadrivium/M
+quadruped/MS
+quadrupedal
+quadruple/MGDS
+quadruplet/MS
+quadruplicate/MGNDS
+quadruplication/M
+quaff/GMDS
+quagmire/SM
+quahog/MS
+quail/GMDS
+quaint/PRYT
+quaintness/M
+quake/MGDS
+quaky
+qualification/EM
+qualified/U
+qualifier/SM
+qualify/EGXNDS
+qualitative/Y
+quality/SM
+qualm/MS
+qualmish
+quandary/SM
+quango/S
+quanta
+quantifiable
+quantification/M
+quantifier/M
+quantify/NDRSZG
+quantitation
+quantitative/Y
+quantity/SM
+quantization
+quantize/D
+quantum/M
+quarantine/MGDS
+quark/MS
+quarrel/SZGMDR
+quarreler/M
+quarrelsome/P
+quarrelsomeness/M
+quarry/DSMG
+quart/MS
+quarter/SGMDY
+quarterback/GMDS
+quarterdeck/MS
+quarterfinal/SM
+quarterly/SM
+quartermaster/MS
+quarterstaff/M
+quarterstaves
+quartet/SM
+quartile/S
+quarto/MS
+quartz/M
+quasar/MS
+quash/GDS
+quasi
+quatrain/MS
+quaver/MDSG
+quavery
+quay/MS
+quayside/S
+queasily
+queasiness/M
+queasy/TPR
+queen/GMDYS
+queenly/RT
+queer/PTGMDRYS
+queerness/M
+quell/GDS
+quench/ZGDRSB
+quenchable/U
+quencher/M
+quenchless
+querulous/YP
+querulousness/M
+query/DSMG
+ques
+quesadilla/MS
+quest/IFAMS
+quested
+questing
+question/SMDRZGBJ
+questionable/U
+questionably/U
+questioned/U
+questioner/M
+questioning/MY
+questionnaire/SM
+queue's
+queue/CDSG
+quibble/DRSMZG
+quibbler/M
+quiche/SM
+quick/MNRYXTP
+quicken/DG
+quickfire
+quickie/SM
+quicklime/M
+quickness/M
+quicksand/MS
+quicksilver/M
+quickstep/MS
+quid/MS
+quiescence/M
+quiescent/Y
+quiet/SMDNRYXTGP
+quieten/DG
+quietism
+quietness/M
+quietude/IEM
+quietus/MS
+quiff/S
+quill/SM
+quilt/SMDRZG
+quilter/M
+quilting/M
+quin/S
+quince/SM
+quine/S
+quinidine
+quinine/M
+quinoa
+quinsy/M
+quint/SM
+quintessence/SM
+quintessential/Y
+quintet/SM
+quintuple/MGDS
+quintuplet/MS
+quip/MS
+quipped
+quipping
+quipster/SM
+quire's
+quire/IAS
+quirk/SMDG
+quirkiness/M
+quirky/RTP
+quirt/SM
+quisling/SM
+quit/S
+quitclaim/MS
+quite
+quittance/M
+quitter/SM
+quitting
+quiver/SMDG
+quivery
+quixotic
+quixotically
+quiz/M
+quizzed
+quizzer/SM
+quizzes
+quizzical/Y
+quizzing
+quo/H
+quoin/SM
+quoit/SMDG
+quondam
+quorate/I
+quorum/SM
+quot/B
+quota/SM
+quotability/M
+quotation/SM
+quote's
+quote/UDSG
+quotidian
+quotient/SM
+qwerty
+r/S
+rabbet/GMDS
+rabbi/SM
+rabbinate/M
+rabbinic
+rabbinical
+rabbit/GMDS
+rabble/MS
+rabid/PY
+rabidness/M
+rabies/M
+raccoon/MS
+race/MZGDRS
+racecourse/SM
+racegoer/S
+racehorse/MS
+raceme/MS
+racer/M
+racetrack/MS
+raceway/MS
+racial/Y
+racialism/M
+racialist/MS
+racily
+raciness/M
+racing/M
+racism/M
+racist/SM
+rack/GMDS
+racket/SMDG
+racketeer/SMDG
+racketeering/M
+raconteur/SM
+racoon
+racquet/SM
+racquetball/SM
+racy/PRT
+rad/SM
+radar/SM
+radarscope/SM
+raddled
+radial/SMY
+radian/S
+radiance/M
+radiant/Y
+radiate/DSGNX
+radiation/M
+radiator/SM
+radical/SMY
+radicalism/M
+radicalization/M
+radicalize/DSG
+radicchio/M
+radii
+radio/MDGS
+radioactive/Y
+radioactivity/M
+radiocarbon/M
+radiogram/MS
+radiographer/SM
+radiography/M
+radioisotope/MS
+radiologist/SM
+radiology/M
+radioman/M
+radiomen
+radiometer/MS
+radiometric
+radiometry/M
+radiophone/SM
+radioscopy/M
+radiosonde/SM
+radiosurgery
+radiotelegraph/M
+radiotelegraphs
+radiotelegraphy/M
+radiotelephone/MS
+radiotherapist/MS
+radiotherapy/M
+radish/MS
+radium/M
+radius/M
+radon/M
+raffia/M
+raffish/YP
+raffishness/M
+raffle/DSMG
+raft/ZGMDRS
+rafter/M
+rafting/M
+rag/SGMD
+raga/MS
+ragamuffin/MS
+ragbag/M
+rage/MS
+ragga
+ragged/RYTP
+raggedness/M
+raggedy/RT
+ragging
+raging/Y
+raglan/SM
+ragout/SM
+ragtag/S
+ragtime/M
+ragweed/M
+ragwort
+rah
+raid/ZGMDRS
+raider/M
+rail's
+rail/CGDS
+railcard/S
+railing/SM
+raillery/SM
+railroad/SZGMDR
+railroader/M
+railroading/M
+railway/SM
+railwayman
+railwaymen
+raiment/M
+rain/GMDS
+rainbow/SM
+raincoat/SM
+raindrop/SM
+rainfall/SM
+rainmaker/SM
+rainmaking/M
+rainproof
+rainstorm/MS
+rainwater/M
+rainy/RT
+raise/MZGDRS
+raiser/M
+raisin/SM
+raja/MS
+rajah/M
+rajahs
+rake/MGDS
+rakish/YP
+rakishness/M
+rally/DSMG
+ram/SMN
+ramble/DRSMZGJ
+rambler/M
+rambunctious/PY
+rambunctiousness/M
+rambutan/S
+ramekin/SM
+ramie/M
+ramification/M
+ramify/DSXNG
+ramjet/SM
+rammed
+ramming
+ramp/GMDS
+rampage/DSMG
+rampancy/M
+rampant/Y
+rampart/SM
+ramrod/SM
+ramrodded
+ramrodding
+ramshackle
+ran/A
+ranch/MDRSZG
+rancher/M
+ranching/M
+rancid/P
+rancidity/M
+rancidness/M
+rancor/M
+rancorous/Y
+rand/M
+randiness/M
+rando/S
+random/PSY
+randomization/M
+randomize/DSG
+randomness/MS
+randy/RTP
+ranee/MS
+rang/ZR
+range's
+range/CGDS
+rangefinder/S
+ranger/M
+ranginess/M
+rangy/RTP
+rani/MS
+rank/TGJPMDRYS
+ranking/M
+rankle/DSG
+rankness/M
+ransack/SGD
+ransom/SZGMDR
+ransomer/M
+ransomware
+rant/ZGMDJRS
+ranter/M
+rap/SZGMDR
+rapacious/PY
+rapaciousness/M
+rapacity/M
+rape/MS
+raper/M
+rapeseed/M
+rapid/PMRYTS
+rapidity/M
+rapidness/M
+rapier/SM
+rapine/M
+rapist/SM
+rapped
+rappel/SM
+rappelled
+rappelling
+rapper/SM
+rapping
+rapport/MS
+rapporteur/S
+rapprochement/SM
+rapscallion/MS
+rapt/YP
+raptness/M
+raptor/S
+rapture/MS
+rapturous/Y
+rare/YTGPDRS
+rarebit/MS
+rarefaction/M
+rarefy/GDS
+rareness/M
+rarity/SM
+rascal/SMY
+rash/ZTMRSYP
+rasher/M
+rashness/M
+rasp/GMDS
+raspberry/SM
+raspy/RT
+raster
+rasterization/M
+rasterize/DRSG
+rat/SM
+ratatouille/M
+ratbag/S
+ratchet/GMDS
+rate/JXMZGNDRS
+rated/U
+ratepayer/S
+rater/M
+rather
+rathskeller/SM
+ratification/M
+ratifier/M
+ratify/NDRSZG
+rating/M
+ratio/MS
+ratiocinate/GNDS
+ratiocination/M
+ration/MDG
+rational/SMY
+rationale/MS
+rationalism/M
+rationalist/SM
+rationalistic
+rationality/M
+rationalization/MS
+rationalize/DSG
+ratlike
+ratline/SM
+rattan/SM
+ratted
+ratter/SM
+ratting
+rattle/DRSMZGJ
+rattlebrain/SMD
+rattler/M
+rattlesnake/SM
+rattletrap/SM
+rattly
+rattrap/SM
+ratty/RT
+raucous/YP
+raucousness/M
+raunchily
+raunchiness/M
+raunchy/TRP
+ravage/DRSMZG
+ravager/M
+ravages/M
+rave/JMZGDRS
+ravel's
+ravel/UDSG
+raveling/S
+raven/MDSG
+ravenous/Y
+ravine/SM
+raving/M
+ravioli/SM
+ravish/DRSZGL
+ravisher/M
+ravishing/Y
+ravishment/M
+raw/PTMR
+rawboned
+rawhide/M
+rawness/M
+ray/SM
+rayon/M
+raze/GDS
+razor/MS
+razorback/MS
+razz/GMDS
+razzmatazz/M
+rcpt
+rd
+re/DSMYTGVJ
+reach/MDSGB
+reachable/U
+reacquire/DSG
+react/V
+reactance
+reactant/SM
+reactionary/SM
+reactivity/M
+read/ZGMRBJS
+readability/SM
+reader/M
+readership/SM
+readily
+readiness/M
+reading/M
+readmitted
+readout/SM
+ready/DRSTGP
+reafforestation
+real/TMRYPS
+realism/M
+realist/SM
+realistic/U
+realistically/U
+realities
+reality/UM
+realization/MS
+realize/DSBG
+realized/U
+realm/MS
+realness/M
+realpolitik/M
+realtor/SM
+realty/M
+ream/ZGMDRS
+reamer/M
+reap/ZGDRS
+reaper/M
+rear/GMDS
+rearguard/MS
+rearmost
+rearward/S
+reason/SMDRZGB
+reasonable/UP
+reasonableness/UM
+reasonably/U
+reasoner/M
+reasoning/M
+reassemble/DSG
+reassuring/Y
+rebate/M
+rebel/MS
+rebellion/MS
+rebellious/YP
+rebelliousness/M
+rebid/S
+rebidding
+rebirth/M
+reboil/SDG
+rebrand/G
+rebuild/SG
+rebuke/DSMG
+rebuking/Y
+rebuttable
+rebuttal/MS
+rec'd
+rec/M
+recalcitrance/M
+recalcitrant
+recant/SDG
+recantation/SM
+recap/MS
+recapitalization
+recce/S
+recd
+receipt/SMDG
+receivables/M
+receive/DRSZGB
+receiver/M
+receivership/M
+recency
+recent/RYTP
+recentness/M
+receptacle/SM
+reception/MS
+receptionist/SM
+receptive/PY
+receptiveness/M
+receptivity/M
+receptor/SM
+recess/MDSGV
+recessional/SM
+recessionary
+recessive/SM
+recherche
+recherch
+recidivism/M
+recidivist/SM
+recipe/SM
+recipient/SM
+reciprocal/SMY
+reciprocate/GNDS
+reciprocation/M
+reciprocity/M
+recital/SM
+recitalist/MS
+recitative/MS
+reciter/SM
+reckless/YP
+recklessness/M
+reckon/SJDG
+reckoning/M
+reclamation/M
+recline/DRSZG
+recliner/M
+recluse/SMV
+recognizable/U
+recognizably/U
+recognize/DRSGB
+recognized/U
+recoilless
+recombination
+recommend/ZR
+recompense/DSMG
+recompile/GD
+recon/S
+reconcile/GDSB
+reconciliation/S
+recondite
+reconfiguration
+reconnaissance/MS
+reconnoiter/DGS
+reconstruct/V
+reconstructed/U
+recorded/U
+recorder/MS
+recording/MS
+recoup/DG
+recourse/M
+recoverable/U
+recovery/SM
+recreant/MS
+recreational
+recriminate/DSGNX
+recrimination/M
+recriminatory
+recrudesce/GDS
+recrudescence/M
+recrudescent
+recruit/LSMDRZG
+recruiter/M
+recruitment/M
+rectal/Y
+rectangle/MS
+rectangular
+rectifiable
+rectification/M
+rectifier/M
+rectify/XNDRSZG
+rectilinear
+rectitude/M
+recto/MS
+rector/SM
+rectory/SM
+rectum/SM
+recumbent
+recuperate/GNVDS
+recuperation/M
+recur/S
+recurred
+recurrence/SM
+recurrent/Y
+recurring
+recurse/XNV
+recusal/S
+recuse/DSG
+recyclable/SM
+recycling/M
+red/PSM
+redact/SDG
+redacted/U
+redaction/SM
+redactor/SM
+redbird/SM
+redbreast/MS
+redbrick
+redcap/SM
+redcoat/SM
+redcurrant/S
+redden/SDG
+redder
+reddest
+reddish
+redeem/RZB
+redeemer/M
+redemption/M
+redemptive
+redesign/DSG
+redhead/SMD
+redirection
+redistrict/GD
+redivide/GDS
+redlining/M
+redneck/SM
+redness/M
+redo/G
+redolence/M
+redolent
+redoubt/SBM
+redoubtably
+redound/SDG
+redraw/SG
+redskin/SM
+reduce/DRSZG
+reducer/M
+reducible
+reductase/M
+reduction/SM
+reductionist
+reductive
+redundancy/SM
+redundant/Y
+redwood/SM
+redye/DS
+reediness/M
+reedy/RTP
+reef/ZGMDRS
+reefer/M
+reek/GMDS
+reel's
+reel/UGDS
+reeve/G
+reexport/SDG
+ref/SZM
+refashion/DGS
+refection/M
+refectory/SM
+refer/B
+referee/DSM
+refereeing
+reference/MGDS
+referendum/MS
+referent/SM
+referential
+referral/SM
+referred
+referrer/SM
+referring
+reffed
+reffing
+refile/DSG
+refill/BM
+refined/U
+refinement/SM
+refiner/SM
+refinery/S
+refitting
+reflate/XDSGN
+reflationary
+reflect/GVSD
+reflection/MS
+reflective/Y
+reflectivity
+reflector/MS
+reflexive/SMY
+reflexivity
+reflexology
+reforge/DSG
+reform/MZ
+reformat/V
+reformatory/SM
+reformatting
+reformed/U
+reformist/S
+refortify/GDS
+refract/SGVD
+refraction/M
+refractory/SM
+refrain/SGMD
+refresh/ZGLDRS
+refresher/M
+refreshing/Y
+refreshment/SM
+refreshments/M
+refrigerant/SM
+refrigerate/DSGN
+refrigeration/M
+refrigerator/MS
+refuge/SM
+refugee/SM
+refulgence/M
+refulgent
+refund/B
+refurbishment/MS
+refusal/MS
+refutation/MS
+refute/BDRSZG
+refuter/M
+reg
+regal/DYG
+regalement/M
+regalia/M
+regard/ESMDG
+regardless
+regards/M
+regather/DGS
+regatta/SM
+regency/SM
+regeneracy/M
+regenerate/V
+regex/M
+regexp/S
+reggae/M
+regicidal
+regicide/MS
+regime/SM
+regimen/SM
+regiment/MDGS
+regimental
+regimentation/M
+region/SM
+regional/Y
+regionalism/MS
+register/GMDS
+registered/U
+registrant/MS
+registrar/MS
+registration/SM
+registry/SM
+reglet
+regnant
+regress/MDSGV
+regression/MS
+regret/SM
+regretful/Y
+regrettable
+regrettably
+regretted
+regretting
+regrind/GS
+reground
+regroup/DGS
+regular/MYS
+regularity/SM
+regularization/M
+regularize/DSG
+regulate/CDSGNV
+regulated/U
+regulation/CM
+regulations
+regulator/MS
+regulatory
+regurgitate/DSGN
+regurgitation/M
+rehab/MS
+rehabbed
+rehabbing
+rehabilitate/GNVDS
+rehabilitation/M
+rehang/SDG
+rehears/GD
+rehearsal/MS
+rehearsed/U
+rehi
+rehung
+reify/NDSG
+reign/MDSG
+reignite/DSG
+reimburse/BDSGL
+reimbursement/MS
+rein/GD
+reindeer/M
+reinforce/LGDS
+reinforcement/SM
+reinitialize
+reinstall/DG
+reinstatement/M
+reinsurance
+reiterate/V
+reject/GSMD
+rejection/SM
+rejoice/JGDS
+rejoicing/M
+rejoinder/SM
+rejuvenate/DSGN
+rejuvenation/M
+rel
+relate/DRSBXZGNV
+related/YP
+relatedness/M
+relater/M
+relation/M
+relational
+relationship/MS
+relative/MYS
+relativism/M
+relativist/S
+relativistic
+relativity/M
+relax/DRSZG
+relaxant/MS
+relaxation/SM
+relaxer/M
+relay/D
+release/B
+released/U
+relegate/GNDS
+relent/SGD
+relentless/PY
+relentlessness/M
+relevance/M
+relevancy/M
+relevant/Y
+reliability/UM
+reliable/U
+reliably/U
+reliance/M
+reliant
+relic/MS
+relict/CSM
+relief/SM
+relieve/ZGDRS
+reliever/M
+religion/SM
+religiosity
+religious/MYP
+religiousness/M
+reline/DSG
+relinquish/LDSG
+relinquishment/M
+reliquary/SM
+relish/GMDS
+relist/SGD
+relocate/B
+reluctance/M
+reluctant/Y
+rely/GDS
+rem/M
+remain/SGD
+remainder/GMDS
+remand/SGD
+remapping
+remark/B
+remarkableness/M
+remarkably
+remarked/U
+remeasure/GDS
+remediable
+remedy/GDSM
+remember/DG
+remembered/U
+remembrance/MS
+reminder/M
+reminisce/GDS
+reminiscence/MS
+reminiscent/Y
+remiss/PY
+remissness/M
+remit/S
+remittance/SM
+remitted
+remitting/U
+remix/DSG
+remnant/MS
+remodel/GDS
+remold/SGD
+remonstrant/SM
+remonstrate/DSG
+remorse/M
+remorseful/Y
+remorseless/PY
+remorselessness/M
+remote/RSMYTP
+remoteness/M
+removal/SM
+remunerate/GNVXDS
+remuneration/M
+renaissance/MS
+renal
+renascence/S
+rend/GS
+render/SZGMDRJ
+renderer/M
+rendering/M
+rendezvous/GMDS
+rendition/MS
+renegade/DSMG
+renege/DRSZG
+reneger/M
+renew/DSBG
+renewable/S
+renewal/MS
+rennet/M
+rennin/M
+renounce/LDSG
+renouncement/M
+renovate/DSXGN
+renovation/M
+renovator/MS
+renown/MD
+rent/ZGMDRS
+rental/SM
+renter/M
+renunciation/SM
+reopen/SDG
+reorg/MDSG
+rep/SM
+repaint/GDS
+repair/BZR
+repairer/M
+repairman/M
+repairmen
+reparable
+reparation/MS
+reparations/M
+repartee/M
+repatriate/XDSMGN
+repatriation/M
+repeat/SMDRZGB
+repeatability
+repeatable/U
+repeatably
+repeated/Y
+repeater/M
+repeating/M
+repel/S
+repelled
+repellent/SM
+repelling
+repent/SDG
+repentance/M
+repentant/Y
+repercussion/S
+repertoire/MS
+repertory/SM
+repetition/MS
+repetitious/YP
+repetitiousness/M
+repetitive/YP
+repetitiveness/M
+rephotograph/DG
+replaceable
+replant/GSD
+replenish/LGDS
+replenishment/M
+replete/PDSGN
+repleteness/M
+repletion/M
+replica/SM
+replicate/DSGNX
+replication/M
+replicator/S
+reportage/M
+reported/Y
+reportorial
+reposeful
+reposition
+repository/SM
+reprehend/DGS
+reprehensibility/M
+reprehensible
+reprehensibly
+reprehension/M
+represent/GDS
+representational
+representative/MS
+represented/U
+repression/MS
+repressive/PY
+reprieve/DSMG
+reprimand/GSMD
+reprisal/SM
+reprise/SMG
+reproach/GMDSB
+reproachful/Y
+reprobate/MS
+reproducibility
+reproductive
+reprogramming
+reproving/Y
+reptile/SM
+reptilian/MS
+republic/S
+republicanism/M
+repudiate/XGNDS
+repudiation/M
+repudiator/MS
+repugnance/M
+repugnant
+repulsion/M
+repulsive/YP
+repulsiveness/M
+repurchase/GDS
+reputability/M
+reputably/E
+reputation/MS
+reputational
+repute/DSMGB
+reputed/Y
+request/GDR
+requestor
+requiem/SM
+require/LDG
+requirement/MS
+requisite/XMNS
+requisition/GMD
+requital/M
+requite/DRSZG
+requited/U
+requiter/M
+reread/SG
+rerecord/GDS
+rerunning
+resample/GDS
+resat
+rescind/SDG
+rescission/M
+rescue/DRSMZG
+rescuer/M
+reseal/B
+resemble/DSG
+resend
+resent/LSDG
+resentful/YP
+resentfulness/M
+resentment/MS
+reserpine/M
+reservation/MS
+reserved/UY
+reservedness/M
+reservist/SM
+reservoir/SM
+resetting
+reshipping
+residence/SM
+residency/SM
+resident/MS
+residential
+residua
+residual/MS
+residue/SM
+residuum/M
+resignation/SM
+resigned/Y
+resilience/M
+resiliency/M
+resilient/Y
+resinous
+resist/SMDRZGV
+resistance/SM
+resistant/U
+resistible
+resistive/YP
+resistivity
+resistless
+resistor/MS
+resit/S
+resitting
+resold
+resole/DSG
+resolute/PY
+resoluteness/M
+resolve/RBM
+resolved/U
+resonance/SM
+resonant/Y
+resonate/GDS
+resonator/SM
+resorption/M
+resound/SGD
+resounding/Y
+resourceful/YP
+resourcefulness/M
+resp
+respect/ESGVMD
+respectability/M
+respectable
+respectably
+respectful/EY
+respectfulness/M
+respective/Y
+respiration/M
+respirator/SM
+respiratory
+respire/DG
+resplendence/M
+resplendent/Y
+respond/SZGDR
+respondent/SM
+responder/M
+response/MS
+responsibility/SM
+responsible
+responsibly
+responsive/UYP
+responsiveness/UM
+responsivity/M
+rest/GVMDS
+restate/GDS
+restaurant/SM
+restaurateur/MS
+restful/YP
+restfuller
+restfullest
+restfulness/M
+restitution/M
+restive/YP
+restiveness/M
+restless/PY
+restlessness/M
+restoration/SM
+restorative/SM
+restorer/SM
+restrained/U
+restraint/MS
+restrict/SDGV
+restricted/U
+restriction/MS
+restrictive/YP
+restrictiveness/M
+restring/SG
+restroom/SM
+restructuring/SM
+result/GSMD
+resultant/SM
+resume/DSMG
+resumption/MS
+resupply/DSG
+resurgence/MS
+resurgent
+resurrect/GSD
+resurrection/MS
+resuscitate/GNDS
+resuscitation/M
+resuscitator/SM
+retailer/MS
+retain/SDRZG
+retainage/S
+retainer/M
+retake/G
+retaliate/DSGNVX
+retaliation/M
+retaliatory
+retard/SMDRZG
+retardant/SM
+retardation/M
+retarder/M
+retch/DSG
+reteach/GS
+retention/M
+retentive/YP
+retentiveness/M
+rethink/SGM
+rethought
+reticence/M
+reticent/Y
+reticle/SM
+reticulated
+reticulation/MS
+reticulum
+retina/SM
+retinal
+retinoblastoma
+retinue/SM
+retiree/SM
+retirement/MS
+retort/GMD
+retrace/GDS
+retract/DBG
+retractile
+retraction/S
+retrain/DGS
+retread/D
+retrenchment/MS
+retribution/MS
+retributive
+retrieval/SM
+retrieve/DRSMZGB
+retriever/M
+retro/MS
+retroactive/Y
+retrofire/GDS
+retrofit/SM
+retrofitted
+retrofitting
+retrograde/DSG
+retrogress/GVDS
+retrogression/M
+retroreflector/S
+retrorocket/MS
+retrospect/MDSGV
+retrospection/M
+retrospective/MYS
+retrovirus/MS
+retsina/M
+returnable/SM
+returnee/SM
+rev/ZVM
+revamping/M
+reveal/GJSD
+revealed/U
+revealing/Y
+reveille/M
+revel/JMDRSZG
+revelation/SM
+revelatory
+reveler/M
+revelry/SM
+revenge/MGDS
+revenuer/SM
+reverb
+reverberate/DSGNX
+reverberation/M
+revere/DSG
+reverence/DSMG
+reverend/SM
+reverent/Y
+reverential/Y
+reverie/MS
+revers/M
+reversal/SM
+reverse/Y
+reversibility
+reversible
+reversibly
+revert/GSD
+revertible
+revetment/SM
+reviewability
+revile/DRSLZG
+revilement/M
+reviler/M
+reviser/MS
+revision/SM
+revisionism/M
+revisionist/SM
+revival/MS
+revivalism/M
+revivalist/SM
+revive/DSG
+revivification/M
+revocable
+revoke/DSG
+revolt/GD
+revolting/Y
+revolution/SM
+revolutionary/SM
+revolutionist/SM
+revolutionize/DSG
+revolve/BZGDRS
+revolver/M
+revue/MS
+revulsion/M
+revved
+revving
+rewarded/U
+rewarding/U
+rewarm/GSD
+rewash/GDS
+reweave/GS
+rewedding
+rewind/MB
+rewound
+rewrite/MGS
+rhapsodic
+rhapsodical
+rhapsodize/GDS
+rhapsody/SM
+rhea/MS
+rhenium/M
+rheostat/SM
+rhesus/MS
+rhetoric/M
+rhetorical/Y
+rhetorician/SM
+rheum/M
+rheumatic/MS
+rheumatically
+rheumatism/M
+rheumatoid
+rheumatological
+rheumatologist/MS
+rheumatology/M
+rheumy
+rhinestone/SM
+rhinitis/M
+rhino/MS
+rhinoceros/MS
+rhinoplasty
+rhinovirus/MS
+rhizome/MS
+rho/SM
+rhodium/M
+rhododendron/SM
+rhomboid/SM
+rhomboidal
+rhombus/MS
+rhubarb/MS
+rhyme/MZGDRS
+rhymer/M
+rhymester/MS
+rhythm/SM
+rhythmic
+rhythmical/Y
+rial/MS
+rib/SM
+ribald
+ribaldry/M
+ribbed
+ribber/SM
+ribbie/S
+ribbing
+ribbon/SM
+riboflavin/M
+rice/MZGDRS
+ricer/M
+rich/TMRSYP
+richness/M
+rick/GMDS
+rickets/M
+rickety/RT
+rickrack/M
+rickshaw/MS
+ricochet/GMDS
+ricotta/M
+rid/S
+riddance/M
+ridden
+ridding
+riddle/DSMG
+ride/MZGRS
+rider/M
+riderless
+ridership/M
+ridge/MGDS
+ridgepole/SM
+ridgy
+ridicule/MGDS
+ridiculous/YP
+ridiculousness/M
+riding/M
+rife/TR
+riff/GMDS
+riffle/DSMG
+riffraff/M
+rifle/MZGDRS
+rifleman/M
+riflemen
+rifler/M
+rifling/M
+rift/GMDS
+rig/SM
+rigamarole/SM
+rigatoni/M
+rigged
+rigger/SM
+rigging/M
+right/MDRYSPTG
+righteous/UP
+righteously
+righteousness/UM
+rightful/PY
+rightfulness/M
+rightism/M
+rightist/SM
+rightmost
+rightness/M
+righto
+rightsize/DSG
+rightward/S
+rigid/YP
+rigidity/M
+rigidness/M
+rigmarole/MS
+rigor/MS
+rigorous/YP
+rigorousness/M
+rile/GDS
+rill/MS
+rim/SGMD
+rime/MS
+rimless
+rimmed
+rimming
+rind/MS
+ring/ZGMDRJ
+ringer/M
+ringgit/MS
+ringleader/MS
+ringlet/MS
+ringlike
+ringmaster/MS
+ringside/M
+ringtone/SM
+ringworm/M
+rink/MS
+rinse/MGDS
+riot/ZGMDRS
+rioter/M
+rioting/M
+riotous/PY
+rip/SXTMNR
+riparian
+ripcord/MS
+ripe/YP
+ripen/DG
+ripened/U
+ripeness/M
+ripoff/SM
+riposte/MGDS
+ripped
+ripper/SM
+ripping
+ripple/DSMG
+ripply
+ripsaw/SM
+riptide/MS
+rise/JMZGRS
+risen
+riser/M
+risibility/M
+risible
+rising/M
+risk/GMDS
+riskily
+riskiness/M
+risky/RPT
+risotto/MS
+risque
+risqu
+rissole/S
+rite/MS
+ritual/SMY
+ritualism/M
+ritualistic
+ritualistically
+ritualized
+ritzy/RT
+riv/ZNR
+rival/MDSG
+rivaled/U
+rivalry/SM
+rive/CGDS
+river/M
+riverbank/SM
+riverbed/MS
+riverboat/SM
+riverfront
+riverside/MS
+rivet/MDRSZG
+riveter/M
+riviera/S
+rivulet/MS
+riyal/MS
+rm
+roach/GMDS
+road/IMS
+roadbed/SM
+roadblock/MDSG
+roadhouse/SM
+roadie/MS
+roadkill/M
+roadmap/S
+roadrunner/SM
+roadshow/SM
+roadside/SM
+roadster/SM
+roadway/SM
+roadwork/SM
+roadworthy
+roam/ZGDRS
+roamer/M
+roaming/M
+roan/MS
+roar/ZGMDRS
+roarer/M
+roaring/M
+roast/ZGMDRSJ
+roaster/M
+roasting/M
+rob/S
+robbed
+robber/MS
+robbery/SM
+robbing
+robe's
+robe/EGDS
+robin/MS
+robocall/SGMD
+robot/MS
+robotic/S
+robotics/M
+robotize/GDS
+robust/RYPT
+robustness/M
+rock/ZGMDRS
+rockabilly/M
+rockbound
+rocker/M
+rockery/S
+rocket/MDSG
+rocketry/M
+rockfall/SM
+rockiness/M
+rocky/TRP
+rococo/M
+rod/SM
+rode
+rodent/MS
+rodeo/MS
+roe/SM
+roebuck/SM
+roentgen/MS
+roger/GDS
+rogue's
+rogue/KS
+roguery/M
+roguish/YP
+roguishness/M
+roil/GDS
+roister/ZGDRS
+roisterer/M
+role/MS
+roll/MDRZGJS
+rollback/SM
+roller/M
+rollerblading
+rollerskating/M
+rollick/SDG
+rollicking/M
+rollmop/S
+rollout
+rollover/SM
+romaine/MS
+roman/M
+romance/MZGDRS
+romancer/M
+romantic/MS
+romantically
+romanticism/M
+romanticist/SM
+romanticize/DSG
+romeo/MS
+romp/MDRZGS
+romper/M
+rondo/SM
+rood/MS
+roof/MDRZGS
+roofer/M
+roofing/M
+roofless
+rooftop/SM
+rook/MDGS
+rookery/SM
+rookie/SM
+room/MDRZGS
+roomer/M
+roomette/SM
+roomful/SM
+roominess/M
+roommate/SM
+roomy/RTP
+roost/SMDRZG
+rooster/M
+root/MDRZGS
+rooter/M
+rootkit/SM
+rootless/P
+rootlet/SM
+rope/MZGDRS
+roper/M
+ropy/RT
+rosary/SM
+rose/MS
+roseate
+rosebud/SM
+rosebush/MS
+rosemary/M
+rosette/SM
+rosewater/M
+rosewood/MS
+rosily
+rosin/SMDG
+rosiness/M
+roster/SM
+rostrum/MS
+rosy/RTP
+rot/SM
+rota/S
+rotary/SM
+rotatably
+rotate/DSGNBX
+rotation/M
+rotational
+rotator
+rotatory
+rote/M
+rotgut/M
+rotisserie/SM
+rotogravure/MS
+rotor/SM
+rototiller/MS
+rotted
+rotten/TPRY
+rottenness/M
+rotter/S
+rotting
+rottweiler/S
+rotund/P
+rotunda/MS
+rotundity/M
+rotundness/M
+roue/MS
+rouge/DSMG
+rough/MDNRYXTGP
+roughage/M
+roughcast
+roughen/GD
+roughhouse/MGDS
+roughneck/GMDS
+roughness/M
+roughs
+roughshod
+roulette/M
+round/PSMDRYZTG
+roundabout/SM
+roundel/S
+roundelay/MS
+roundhouse/SM
+roundish
+roundness/M
+roundup/MS
+roundworm/SM
+rouse/DSG
+roust/SDG
+roustabout/SM
+rout/MRZS
+route's
+route/ADSG
+routeing
+router/M
+routine/MYS
+routinize/GDS
+roux
+rou/MS
+rove/ZGDRS
+rover/M
+row/SZGMDR
+rowan/S
+rowboat/MS
+rowdily
+rowdiness/M
+rowdy/PRSMT
+rowdyism/M
+rowel/SMDG
+rower/M
+rowing/M
+rowlock/S
+royal/SMY
+royalist/SM
+royalties/M
+royalty/SM
+rpm
+rps
+rt
+rte
+rub/SM
+rubato/SM
+rubbed
+rubber/SM
+rubberize/GDS
+rubberneck/MDRSZG
+rubbernecker/M
+rubbery
+rubbing/S
+rubbish/MDSG
+rubbishy
+rubble/M
+rubdown/SM
+rube/MS
+rubella/M
+rubicund
+rubidium/M
+ruble/SM
+rubric/SM
+ruby/RSMT
+ruched
+ruck/DGS
+rucksack/MS
+ruckus/MS
+ructions
+rudder/SM
+rudderless
+ruddiness/M
+ruddy/RTP
+rude/YTRP
+rudeness/M
+rudiment/SM
+rudimentary
+rue/DSMG
+rueful/PY
+ruefulness/M
+ruff/MDYGS
+ruffian/MYS
+ruffle/DSMG
+ruffled/U
+rug/SM
+rugby/M
+rugged/PTRY
+ruggedness/M
+rugger
+rugrat/SM
+ruin/MDGS
+ruination/M
+ruinous/Y
+rule/MZGJDRS
+ruler/M
+ruling/M
+rum/SM
+rumba/SMDG
+rumble/DSJMG
+rumbling/M
+rumbustious
+ruminant/MS
+ruminate/XGNVDS
+rumination/M
+ruminative/Y
+rummage/DSMG
+rummer
+rummest
+rummy/M
+rumor/SMDG
+rumormonger/SM
+rump/MYS
+rumple/DSMG
+rumpus/MS
+run/ASM
+runabout/MS
+runaround/SM
+runaway/MS
+rundown/SM
+rune/MS
+rung/MS
+runic
+runlet/SM
+runnel/SM
+runner/SM
+running/M
+runny/RT
+runoff/SM
+runt/MS
+runtime
+runty/RT
+runway/SM
+rupee/SM
+rupiah/M
+rupiahs
+rupture/MGDS
+rural
+ruse/MS
+rush/MDRSZG
+rusher/M
+rushy
+rusk/MS
+russet/SM
+rust/MDGS
+rustic/SM
+rustically
+rusticate/GDS
+rustication/M
+rusticity/M
+rustiness/M
+rustle/DRSJMZG
+rustler/M
+rustproof/SDG
+rusty/RPNT
+rut/SM
+rutabaga/SM
+ruthenium/M
+rutherfordium/M
+ruthless/YP
+ruthlessness/M
+rutted
+rutting
+rutty/RT
+rye/M
+s/NYXB
+sabbath/M
+sabbaths
+sabbatical/SM
+saber/MS
+sable/MS
+sabot/MS
+sabotage/DSMG
+saboteur/SM
+sabra/MS
+sabre/MS
+sac/SM
+saccharin/M
+saccharine
+sacerdotal
+sachem/SM
+sachet/SM
+sack/ZGMDRJS
+sackcloth/M
+sacker/M
+sackful/MS
+sacking/M
+sacra
+sacrament/MS
+sacramental
+sacred/YP
+sacredness/M
+sacrifice/DSMG
+sacrificial/Y
+sacrilege/MS
+sacrilegious/Y
+sacristan/MS
+sacristy/SM
+sacroiliac/MS
+sacrosanct/P
+sacrosanctness/M
+sacrum/M
+sad/PY
+sadden/SDG
+sadder
+saddest
+saddle's
+saddle/UDSG
+saddlebag/MS
+saddler/S
+saddlery
+sades
+sadhu/S
+sadism/M
+sadist/SM
+sadistic
+sadistically
+sadness/M
+sadomasochism/M
+sadomasochist/MS
+sadomasochistic
+safari/SGMD
+safe/MYTPRS
+safeguard/SMDG
+safekeeping/M
+safeness/M
+safety/SM
+safflower/MS
+saffron/MS
+sag/SM
+saga/MS
+sagacious/Y
+sagacity/M
+sage/MYTRS
+sagebrush/M
+sagged
+sagging
+saggy/RT
+sago/M
+saguaro/MS
+sahib/MS
+said/U
+sail/GMDSJ
+sailboard/MRZGS
+sailboarder/M
+sailboarding/M
+sailboat/MS
+sailcloth/M
+sailfish/MS
+sailing/M
+sailor/SM
+sailplane/MS
+saint/MDYS
+sainthood/M
+saintlike
+saintliness/M
+saintly/PRT
+saith
+sake/M
+saki/M
+salaam/SMDG
+salability
+salable/U
+salacious/PY
+salaciousness/M
+salacity/M
+salad/MS
+salamander/SM
+salami/SM
+salary/DSM
+sale/ABMS
+saleable/U
+saleroom/S
+salesclerk/SM
+salesgirl/SM
+saleslady/SM
+salesman/M
+salesmanship/M
+salesmen
+salespeople/M
+salesperson/MS
+salesroom/S
+saleswoman/M
+saleswomen
+salience/M
+salient/SMY
+saline/SM
+salinity/M
+saliva/M
+salivary
+salivate/GNDS
+salivation/M
+sallow/RTP
+sallowness/M
+sally/DSMG
+salmon/SM
+salmonella/M
+salmonellae
+salon/MS
+saloon/SM
+salsa/MS
+salt's
+salt/CTGDS
+saltbox/MS
+saltcellar/SM
+salted/U
+salter
+saltine/SM
+saltiness/M
+saltpeter/M
+saltshaker/SM
+saltwater/M
+salty/RTP
+salubrious/I
+salutary
+salutation/MS
+salutatorian/MS
+salutatory
+salute/DSMG
+salvage/DSMG
+salvageable
+salvation/M
+salve/MZGDRS
+salver/M
+salvo/MS
+samarium/M
+samba/MDSG
+same/SP
+sameness/M
+samey
+samizdat/S
+samosa/S
+samovar/SM
+sampan/SM
+sample/DRSMZGJ
+sampler/M
+sampling/M
+samurai/SM
+sanatorium/SM
+sanctification/M
+sanctify/GDSN
+sanctimonious/YP
+sanctimoniousness/M
+sanctimony/M
+sanction/GSMD
+sanctioned/U
+sanctity/M
+sanctuary/SM
+sanctum/SM
+sand/ZGMDRS
+sandal/SM
+sandalwood/M
+sandbag/SM
+sandbagged
+sandbagger/SM
+sandbagging
+sandbank/MS
+sandbar/SM
+sandblast/ZGMDRS
+sandblaster/M
+sandbox/MS
+sandcastle/MS
+sander/M
+sandhog/SM
+sandiness/M
+sandlot/SM
+sandlotter/MS
+sandman/M
+sandmen
+sandpaper/GMDS
+sandpiper/MS
+sandpit/S
+sandstone/M
+sandstorm/SM
+sandwich/MDSG
+sandy/RTP
+sane/IYTR
+saneness/M
+sang/S
+sangfroid/M
+sangria/M
+sanguinary
+sanguine/Y
+sanitarian/SM
+sanitarium/SM
+sanitary/IU
+sanitation/M
+sanitize/ZGDRS
+sanity/IM
+sank
+sans
+sanserif
+sap/SM
+sapience/M
+sapiens
+sapient
+sapless
+sapling/MS
+sapped
+sapper/S
+sapphire/SM
+sappiness/M
+sapping
+sappy/PRT
+saprophyte/SM
+saprophytic
+sapsucker/SM
+sapwood/M
+saran/M
+sarcasm/MS
+sarcastic
+sarcastically
+sarcoma/MS
+sarcophagi
+sarcophagus/M
+sardine/MS
+sardonic
+sardonically
+sarge/MS
+sari/MS
+sarky
+sarnie/S
+sarong/SM
+sarsaparilla/MS
+sartorial/Y
+sash/MS
+sashay/SGMD
+sass/GMDS
+sassafras/MS
+sassy/RT
+sat
+satanic
+satanical/Y
+satanism/M
+satanist/MS
+satay
+satchel/MS
+sate/GDS
+sateen/M
+satellite/DSMG
+satiable/I
+satiate/GNDS
+satiation/M
+satiety/M
+satin/M
+satinwood/SM
+satiny
+satire/SM
+satiric
+satirical/Y
+satirist/SM
+satirize/DSG
+satisfaction/EM
+satisfactions
+satisfactorily/U
+satisfactory/U
+satisfied/U
+satisfy/EDSG
+satisfying/U
+satisfyingly
+sativa
+satori/M
+satrap/SM
+satsuma/S
+saturate/DSGN
+saturated/U
+saturation/M
+saturnine
+satyr/MS
+satyriasis/M
+satyric
+sauce/MZGDRS
+saucepan/SM
+saucer/M
+saucily
+sauciness/M
+saucy/RPT
+sauerkraut/M
+sauna/MDSG
+saunter/MDGS
+saurian
+sauropod/SM
+sausage/MS
+saute/MS
+sauteed
+sauteing
+sauternes/M
+saut/MDSG
+savage/DRSMYTGP
+savageness/M
+savagery/SM
+savanna/MS
+savant/SM
+save/BJMZGDRS
+saveable
+saved/U
+saver/M
+saving/M
+savings/M
+savior/SM
+savoir
+savor/MDSG
+savoriness/M
+savory/PTRSM
+savoy/MS
+savvy/DRSMTG
+saw/SGMD
+sawbones/M
+sawbuck/MS
+sawdust/M
+sawfly/SM
+sawhorse/SM
+sawmill/MS
+sawyer/SM
+sax/MS
+saxifrage/SM
+saxophone/MS
+saxophonist/SM
+say's
+say/USG
+saying/SM
+sayonara/S
+scab/MS
+scabbard/MS
+scabbed
+scabbiness/M
+scabbing
+scabby/PTR
+scabies/M
+scabrous
+scad/MS
+scaffold/SMG
+scaffolding/M
+scag/S
+scagged
+scalability
+scalar/S
+scalawag/MS
+scald/MDSG
+scale's
+scale/CGDSB
+scaleless
+scalene
+scaliness/M
+scallion/MS
+scallop/GSMD
+scallywag/MS
+scalp/MDRSZG
+scalpel/SM
+scalper/M
+scaly/RTP
+scam/MS
+scammed
+scammer/S
+scamming
+scamp/MRSZ
+scamper/GMD
+scampi/M
+scan/MS
+scandal/SM
+scandalize/DSG
+scandalmonger/SM
+scandalous/Y
+scandium/M
+scanned
+scanner/SM
+scanning
+scansion/M
+scant/CDSTG
+scanter
+scantily
+scantiness/M
+scantly
+scantness/M
+scanty/RSPT
+scapegoat/SGMD
+scapegrace/MS
+scapula/M
+scapulae
+scapular/SM
+scar/GMDS
+scarab/SM
+scarce/RYTP
+scarceness/M
+scarcity/SM
+scare/MS
+scarecrow/MS
+scaremonger/SMG
+scarf/MDSG
+scarification/M
+scarify/NDSG
+scarily
+scariness/M
+scarlatina/M
+scarlet/M
+scarp/MDRSZG
+scarper/DG
+scarred
+scarring
+scarves
+scary/RTP
+scat/MS
+scathing/Y
+scatological
+scatology/M
+scatted
+scatter/GJSMD
+scatterbrain/SMD
+scattering/M
+scattershot
+scatting
+scatty
+scavenge/ZGDRS
+scavenger/M
+scenario/MS
+scenarist/MS
+scene/MS
+scenery/M
+scenic
+scenically
+scent/CMS
+scented/U
+scenting
+scentless
+scepter/MS
+sch
+schadenfreude
+schedule's
+schedule/ADSG
+scheduled/U
+scheduler/S
+schema/S
+schemata
+schematic/SM
+schematically
+schematize/GDS
+scheme/DRSMZG
+schemer/M
+scherzo/MS
+schilling/MS
+schism/SM
+schismatic/SM
+schist/M
+schistosomiasis
+schizo/SM
+schizoid/MS
+schizophrenia/M
+schizophrenic/SM
+schlemiel/SM
+schlep/SM
+schlepp/GMDS
+schlock/M
+schlocky
+schmaltz/M
+schmaltzy/TR
+schmo/M
+schmoe/SM
+schmooze/DRSZG
+schmuck/MS
+schnapps/M
+schnaps
+schnauzer/SM
+schnitzel/SM
+schnook/MS
+schnoz/MS
+schnozzle/SM
+scholar/MYS
+scholarship/MS
+scholastic
+scholastically
+scholasticism
+school/SGMD
+schoolbag/MS
+schoolbook/SM
+schoolboy/MS
+schoolchild/M
+schoolchildren/M
+schooldays
+schooled/U
+schoolfellow/SM
+schoolgirl/SM
+schoolhouse/SM
+schooling/M
+schoolkid/S
+schoolmarm/SM
+schoolmarmish
+schoolmaster/MS
+schoolmate/SM
+schoolmistress/MS
+schoolroom/SM
+schoolteacher/MS
+schoolwork/M
+schoolyard/SM
+schooner/SM
+schrod/S
+schuss/GMDS
+schussboomer/MS
+schwa/MS
+sci
+sciatic
+sciatica/M
+science/FMS
+scientific/U
+scientifically/U
+scientist/SM
+scimitar/SM
+scintilla/MS
+scintillate/DSGN
+scintillation/M
+scion/MS
+scissor/GDS
+scleroses
+sclerosis/M
+sclerotic
+scoff/MDRSZG
+scoffer/M
+scofflaw/MS
+scold/MDSGJ
+scolding/M
+scoliosis/M
+sconce/SM
+scone/MS
+scooch/DSG
+scoop/MDSG
+scoopful/MS
+scoot/DRSZG
+scooter/M
+scope/MGDS
+scorbutic
+scorch/MDRSZG
+scorcher/M
+score/MZGDRS
+scoreboard/SM
+scorebook/SM
+scorecard/MS
+scorekeeper/MS
+scoreless
+scoreline/S
+scorer/M
+scoresheet/SM
+scorn/MDRSZG
+scorner/M
+scornful/Y
+scorpion/MS
+scot-free
+scotch/MDSG
+scotchs
+scoundrel/MS
+scour/DRSZG
+scourer/M
+scourge/DSMG
+scout/MDRSZG
+scouting/M
+scoutmaster/MS
+scow/MS
+scowl/MDSG
+scrabble/MZGDRS
+scrabbler/M
+scrag/MS
+scraggly/RT
+scraggy/TR
+scram/S
+scramble's
+scramble/UGDS
+scrambler/MS
+scrammed
+scramming
+scrap/MDRSZGJ
+scrapbook/SM
+scrape/SM
+scraper/M
+scrapheap/SM
+scrapie
+scrapped
+scrapper/MS
+scrapping
+scrappy/TR
+scrapyard/SM
+scratch/GMDS
+scratchcard/S
+scratched/U
+scratchily
+scratchiness/M
+scratchpad/S
+scratchy/PRT
+scrawl/SMDG
+scrawly
+scrawniness/M
+scrawny/PTR
+scream/SMDRZG
+screamer/M
+screaming/Y
+scree/MDS
+screech/GMDS
+screechy/TR
+screed/S
+screen/SJMDRZG
+screening/M
+screenplay/SM
+screensaver/SM
+screenshot/SM
+screenwriter/SM
+screenwriting/M
+screw's
+screw/UDSG
+screwball/MS
+screwdriver/MS
+screwiness/M
+screwworm/SM
+screwy/PRT
+scribal
+scribble/MZGDRS
+scribbler/M
+scribe's
+scribe/CKIS
+scrim/MS
+scrimmage/MGDS
+scrimp/SDG
+scrimshaw/MDGS
+scrip/MS
+script/FSMDG
+scripted/U
+scriptural
+scripture/MS
+scriptwriter/SM
+scrivener/SM
+scrod/M
+scrofula/M
+scrofulous
+scrog/S
+scroll/GSMD
+scrollbar/S
+scrooge/MS
+scrota
+scrotal
+scrotum/M
+scrounge/DRSZG
+scrounger/M
+scroungy/TR
+scrub/MS
+scrubbed
+scrubber/SM
+scrubbing
+scrubby/RT
+scruff/SM
+scruffily
+scruffiness/M
+scruffy/RPT
+scrum/S
+scrumhalf
+scrumhalves
+scrummage/S
+scrummed
+scrumming
+scrump/SGD
+scrumptious/Y
+scrumpy
+scrunch/MDSG
+scrunchie/M
+scrunchy/SM
+scruple/MGDS
+scrupulosity/M
+scrupulous/UPY
+scrupulousness/UM
+scrutineer/S
+scrutinize/GDS
+scrutiny/M
+scuba/MDSG
+scud/MS
+scudded
+scudding
+scuff/MDSG
+scuffle/MGDS
+scull/MDRSZG
+sculler/M
+scullery/SM
+scullion/SM
+sculpt/SGD
+sculptor/SM
+sculptress/MS
+sculptural
+sculpture/DSMG
+scum/MS
+scumbag/MS
+scummed
+scumming
+scummy/TR
+scupper/MDGS
+scurf/M
+scurfy
+scurrility/M
+scurrilous/PY
+scurrilousness/M
+scurry/GDSM
+scurvily
+scurvy/TRM
+scutcheon/SM
+scuttle/MGDS
+scuttlebutt/M
+scuzzy/TR
+scythe/DSMG
+se
+sea/SM
+seabed/SM
+seabird/MS
+seaboard/SM
+seaborne
+seacoast/SM
+seafarer/SM
+seafaring/M
+seafloor/SM
+seafood/M
+seafront/SM
+seagoing
+seagull/MS
+seahorse/MS
+seal's
+seal/AUSDG
+sealant/MS
+sealer/SM
+sealskin/M
+seam/GMDNS
+seaman/M
+seamanship/M
+seamless/Y
+seamount/MS
+seamstress/MS
+seamy/RT
+seance/SM
+seaplane/SM
+seaport/MS
+sear/GMDS
+search/AZGMDRS
+searchable/U
+searcher/AM
+searching/Y
+searchlight/MS
+searing/Y
+seascape/SM
+seashell/SM
+seashore/SM
+seasick/P
+seasickness/M
+seaside/MS
+season/SGMDBJ
+seasonable/U
+seasonably/U
+seasonal/Y
+seasonality
+seasoned/U
+seasoning/M
+seat's
+seat/UGDS
+seating/M
+seatmate/SM
+seawall/MS
+seaward/MS
+seawater/M
+seaway/SM
+seaweed/MS
+seaworthiness/M
+seaworthy/P
+sebaceous
+seborrhea/M
+sebum
+sec'y
+sec/SM
+secant/SM
+secateurs
+secede/DSG
+secession/M
+secessionist/MS
+seclude/GDS
+seclusion/M
+seclusive
+second/SLZGMDRY
+secondarily
+secondary/SM
+seconder/M
+secondhand
+secondment/S
+secrecy/M
+secret/SGVMDY
+secretarial
+secretariat/MS
+secretary/SM
+secretaryship/M
+secrete/XNS
+secretion/M
+secretive/PY
+secretiveness/M
+secretory
+sect/IMS
+sectarian/MS
+sectarianism/M
+sectary/SM
+section/AESM
+sectional/MS
+sectionalism/M
+sectioned
+sectioning
+sector/ESM
+secular
+secularism/M
+secularist/SM
+secularization/M
+secularize/DSG
+secure/DRSYTG
+secured/U
+security/ISM
+secy
+sedan/MS
+sedate/DRSYTGNVP
+sedateness/M
+sedation/M
+sedative/SM
+sedentary
+sedge/M
+sedgy
+sediment/MS
+sedimentary
+sedimentation/M
+sedition/M
+seditious
+seduce/DRSZG
+seducer/M
+seduction/SM
+seductive/YP
+seductiveness/M
+seductress/MS
+sedulous/Y
+see/RSMZ
+seed's
+seed/AGDS
+seedbed/MS
+seedcase/MS
+seeded/U
+seeder/SM
+seediness/M
+seedless
+seedling/MS
+seedpod/MS
+seedy/RPT
+seeing/S
+seek/ZGRS
+seeker/M
+seem/GDS
+seeming/Y
+seemliness/UM
+seemly/URTP
+seen/U
+seep/GDS
+seepage/M
+seer/M
+seersucker/M
+seesaw/SMDG
+seethe/DSG
+segfault/S
+segment/GSMD
+segmentation/M
+segmented/U
+segregable
+segregate/CDSGN
+segregated/U
+segregation/CM
+segregationist/MS
+segue/MGDS
+segueing
+seigneur/SM
+seignior/SM
+seigniorial
+seine/MZGDRS
+seiner/M
+seismic
+seismically
+seismograph/ZMR
+seismographer/M
+seismographic
+seismographs
+seismography/M
+seismologic
+seismological
+seismologist/MS
+seismology/M
+seize/GDS
+seizure/MS
+seldom/Y
+select/CSGVD
+selection/SM
+selective/Y
+selectivity/M
+selectman/M
+selectmen
+selectness/M
+selector/MS
+selenium/M
+selenographer/MS
+selenography/M
+self/GM
+selfie/SM
+selfish/UYP
+selfishness/UM
+selfism
+selfist/S
+selfless/PY
+selflessness/M
+selfsame
+sell's
+sell/AZGRS
+seller's
+selloff/MS
+sellotape/DSG
+sellout/MS
+seltzer/MS
+selvage/MS
+selvedge/MS
+selves
+semantic/S
+semantically
+semanticist/MS
+semantics/M
+semaphore/DSMG
+semblance/ASM
+semen/M
+semester/SM
+semi/MS
+semiannual/Y
+semiarid
+semiautomatic/MS
+semibreve/S
+semicircle/SM
+semicircular
+semicolon/MS
+semiconducting
+semiconductor/MS
+semiconscious
+semidarkness/M
+semidetached
+semifinal/SM
+semifinalist/MS
+semigloss/S
+semimonthly/SM
+seminal
+seminar/MS
+seminarian/SM
+seminary/SM
+semiofficial
+semiotic/S
+semiotics/M
+semipermeable
+semiprecious
+semiprivate
+semipro/S
+semiprofessional/SM
+semiquaver/S
+semiretired
+semiskilled
+semisolid
+semisweet
+semitone/SM
+semitrailer/MS
+semitransparent
+semitropical
+semivowel/SM
+semiweekly/SM
+semiyearly
+semolina/M
+sempstress/MS
+senate/SM
+senator/MS
+senatorial
+send/ZGRS
+sender/M
+sendoff/MS
+senescence/M
+senescent
+senile
+senility/M
+senior/SM
+seniority/M
+senna/M
+senor/MS
+senora/SM
+senorita/SM
+sensation/MS
+sensational/Y
+sensationalism/M
+sensationalist/MS
+sensationalistic
+sensationalize/GDS
+sense/MGDS
+senseless/PY
+senselessness/M
+sensibilities
+sensibility/IM
+sensible/P
+sensibleness/M
+sensibly/I
+sensitive/SMYP
+sensitiveness/M
+sensitivities
+sensitivity/IM
+sensitization/CM
+sensitize/CDSG
+sensor/SM
+sensory
+sensual/Y
+sensualist/SM
+sensuality/M
+sensuous/YP
+sensuousness/M
+sent/FAU
+sentence/MGDS
+sententious/Y
+sentience/IM
+sentient/Y
+sentiment/SM
+sentimental/Y
+sentimentalism/M
+sentimentalist/MS
+sentimentality/M
+sentimentalization/M
+sentimentalize/GDS
+sentinel/MS
+sentry/SM
+sepal/MS
+separability/IM
+separable
+separably/I
+separate/XMYGNVDSP
+separateness/M
+separation/M
+separatism/M
+separatist/MS
+separator/MS
+sepia/M
+sepsis/M
+septa
+septal
+septet/SM
+septic
+septicemia/M
+septicemic
+septuagenarian/MS
+septum/M
+sepulcher/GMDS
+sepulchral
+seq
+sequel/SM
+sequence/MZGDRS
+sequencing/M
+sequential/FY
+sequester/SDG
+sequestrate/XGNDS
+sequestration/M
+sequin/SMD
+sequinned
+sequitur
+sequoia/MS
+sera
+seraglio/MS
+serape/SM
+seraph/M
+seraphic
+seraphim
+seraphs
+sere/TR
+serenade/MGDS
+serendipitous
+serendipity/M
+serene/RPYT
+sereneness/M
+serenity/M
+serf/MS
+serfdom/M
+serge/M
+sergeant/MS
+serial/SMY
+serialization/SM
+serialize/GDSB
+series/M
+serif/MS
+serigraph/M
+serigraphs
+serine
+serious/PY
+seriousness/M
+sermon/SM
+sermonize/GDS
+serology/M
+serotonin
+serous
+serpent/MS
+serpentine/M
+serrate/XND
+serration/M
+serried
+serum/MS
+servant/MS
+serve's/AF
+serve/FACGDS
+server/SM
+servery/S
+service/EMS
+serviceability/M
+serviceable
+serviced
+serviceman/M
+servicemen
+servicewoman/M
+servicewomen
+servicing
+serviette/MS
+servile
+servility/M
+serving's
+servings
+servitor/MS
+servitude/M
+servo/MS
+servomechanism/SM
+servomotor/MS
+sesame/SM
+sesquicentennial/MS
+session/MS
+set/AISM
+setback/MS
+setscrew/SM
+setsquare/S
+sett/BJZGRS
+settee/MS
+setter/M
+setting/M
+settle's
+settle/AUGDS
+settlement/AM
+settlements
+settler/SM
+setup/MS
+seven/MHS
+seventeen/SMH
+seventeenth/M
+seventeenths
+seventh/M
+sevenths
+seventieth/M
+seventieths
+seventy/SMH
+sever/ETGDS
+severability
+several/MY
+severance/SM
+severe/YPR
+severeness/M
+severity/M
+sew/ASGD
+sewage/M
+sewer/MS
+sewerage/M
+sewing/M
+sewn/A
+sex/GMDS
+sexagenarian/SM
+sexily
+sexiness/M
+sexism/M
+sexist/MS
+sexless
+sexologist/SM
+sexology/M
+sexpot/MS
+sextant/SM
+sextet/MS
+sexting
+sexton/MS
+sextuplet/SM
+sexual/Y
+sexuality/M
+sexy/PTR
+sf
+sh
+shabbily
+shabbiness/M
+shabby/PTR
+shack/MDSG
+shackle's
+shackle/UGDS
+shad/GMDSJ
+shade/MS
+shadily
+shadiness/M
+shading/M
+shadow/SGMD
+shadowbox/GDS
+shadowy/RT
+shady/RPT
+shaft/MDSG
+shag/MS
+shagged
+shagginess/M
+shagging
+shaggy/TPR
+shah/M
+shahs
+shake/MZGRS
+shakedown/SM
+shaken/U
+shakeout/MS
+shaker/M
+shakeup/MS
+shakily
+shakiness/M
+shaky/RPT
+shale/M
+shall
+shallot/MS
+shallow/TPMRYS
+shallowness/M
+shalom
+shalt
+sham/GMDS
+shaman/SM
+shamanic
+shamanism
+shamanistic
+shamble/MGDS
+shambles/M
+shambolic
+shame/MS
+shamefaced/Y
+shameful/PY
+shamefulness/M
+shameless/YP
+shamelessness/M
+shammed
+shamming
+shampoo/ZGMDRS
+shampooer/M
+shamrock/MS
+shan't
+shandy/S
+shanghai/DSG
+shank/MS
+shantung/M
+shanty/SM
+shantytown/SM
+shape's
+shape/AGDS
+shaped/U
+shapeless/YP
+shapelessness/M
+shapeliness/M
+shapely/PTR
+shapeshift/ZGDR
+shard/MS
+share/MZGDRSB
+shareable
+sharecrop/S
+sharecropped
+sharecropper/MS
+sharecropping
+shareholder/SM
+shareholding/S
+sharer/M
+shareware/M
+sharia/M
+shariah
+shark/MDSG
+sharkskin/M
+sharp/MDNRYSPXZTG
+sharpen/ADGS
+sharpener/MS
+sharper/M
+sharpie/M
+sharpish
+sharpness/M
+sharpshooter/SM
+sharpshooting/M
+sharpy/SM
+shat
+shatter/GMDS
+shatterproof
+shave/MZGDRSJ
+shaven/U
+shaver/M
+shaving/M
+shawl/MS
+shay/MS
+she'd
+she'll
+she/DSM
+sheaf/M
+shear/MDRSZG
+shearer/M
+sheath/JM
+sheathe/UGDS
+sheathing/M
+sheaths
+sheave/DSMG
+shebang/MS
+shebeen/S
+shed/MS
+shedding
+sheen/M
+sheeny/TR
+sheep/M
+sheepdog/MS
+sheepfold/SM
+sheepherder/MS
+sheepish/YP
+sheepishness/M
+sheepskin/MS
+sheer/MDRSPTG
+sheerness/M
+sheet/MSG
+sheeting/M
+sheetlike
+sheik/MS
+sheikdom/MS
+sheikh/M
+sheikhdom/MS
+sheikhs
+sheila/S
+shekel/SM
+shelf/M
+shell/MDRSG
+shellac/MS
+shellacked
+shellacking/MS
+shellfire/M
+shellfish/MS
+shelter/GMDS
+shelve/GDS
+shelving/M
+shemale/MS
+shenanigan/SM
+shepherd/SMDG
+shepherdess/MS
+sherbet/SM
+sherd/MS
+sheriff/SM
+sherry/SM
+shew/GDS
+shewn
+shh
+shiatsu/M
+shibboleth/M
+shibboleths
+shield/MDGS
+shift/ZGMDRS
+shiftily
+shiftiness/M
+shiftless/PY
+shiftlessness/M
+shifty/RPT
+shiitake/SM
+shill/GMDSJ
+shillelagh/M
+shillelaghs
+shilling/M
+shim/MS
+shimmed
+shimmer/SMDG
+shimmery
+shimming
+shimmy/DSMG
+shin/ZGMDRS
+shinbone/SM
+shindig/SM
+shine/MS
+shiner/M
+shingle/DSMG
+shinguard/M
+shininess/M
+shinned
+shinning
+shinny/DSG
+shinsplints/M
+shiny/TRP
+ship's
+ship/ALS
+shipboard/MS
+shipbuilder/SM
+shipbuilding/M
+shipload/SM
+shipmate/SM
+shipment/AM
+shipments
+shipowner/MS
+shipped/A
+shipper/SM
+shipping/M
+shipshape
+shipwreck/GMDS
+shipwright/MS
+shipyard/SM
+shire/MS
+shirk/ZGDRS
+shirker/M
+shirr/GMDSJ
+shirring/M
+shirt/GMDS
+shirtfront/SM
+shirting/M
+shirtless
+shirtsleeve/SM
+shirttail/SM
+shirtwaist/MS
+shirty
+shit/SM!
+shitfaced/!
+shithead/MS!
+shitload/MS!
+shitted/!
+shitting/!
+shitty/RT!
+shiv/ZMRS
+shiver/MDG
+shivery
+shoal/GMDS
+shoat/MS
+shock/ZGMDRS
+shocker/M
+shocking/Y
+shockproof
+shod/U
+shoddily
+shoddiness/M
+shoddy/PRMT
+shoe/MS
+shoehorn/GMDS
+shoeing
+shoelace/MS
+shoemaker/SM
+shoeshine/SM
+shoestring/SM
+shoetree/MS
+shogun/MS
+shogunate/M
+shone
+shoo/GDS
+shook
+shoot/ZGMRSJ
+shooter/M
+shooting/M
+shootout/MS
+shop/MS
+shopaholic/MS
+shopfitter/S
+shopfitting
+shopfront/S
+shopkeeper/MS
+shoplift/DRZGS
+shoplifter/M
+shoplifting/M
+shoppe/MZGDRS
+shopper/M
+shopping/M
+shoptalk/M
+shopworn
+shore/MGDS
+shorebird/SM
+shoreline/MS
+shoring/M
+short/XTGMDNRYSP
+shortage/MS
+shortbread/M
+shortcake/MS
+shortchange/DSG
+shortcoming/MS
+shortcrust
+shortcut/MS
+shorten/JGD
+shortening/M
+shortfall/MS
+shorthand/MD
+shorthorn/MS
+shortie/M
+shortish
+shortlist/DGS
+shortness/M
+shortsighted/PY
+shortsightedness/M
+shortstop/MS
+shortwave/MS
+shorty/SM
+shot/MS
+shotgun/SM
+shotgunned
+shotgunning
+should
+should've
+shoulder/MDGS
+shouldn't
+shout/ZGMDRS
+shouter/M
+shove/MGDS
+shovel/MDSG
+shovelful/SM
+show/JZGMDRS
+showbiz/M
+showboat/MDGS
+showcase/MGDS
+showdown/MS
+shower/MDG
+showerproof
+showery
+showgirl/MS
+showground/S
+showily
+showiness/M
+showing/M
+showjumping
+showman/M
+showmanship/M
+showmen
+shown
+showoff/SM
+showpiece/SM
+showplace/SM
+showroom/MS
+showstopper/MS
+showstopping
+showtime/MS
+showy/TRP
+shpt
+shrank
+shrapnel/M
+shred/MS
+shredded
+shredder/MS
+shredding
+shrew/MS
+shrewd/RYPT
+shrewdness/M
+shrewish
+shriek/MDSG
+shrift/M
+shrike/MS
+shrill/DRSPTG
+shrillness/M
+shrilly
+shrimp/MDRSZG
+shrine/MS
+shrink/MSBG
+shrinkage/M
+shrive/GDS
+shrivel/SGD
+shriven
+shroom/S
+shroud/GMDS
+shrub/MS
+shrubbery/SM
+shrubby/RT
+shrug/MS
+shrugged
+shrugging
+shrunk/N
+shtick/MS
+shuck/GMDS
+shucks/S
+shudder/MDSG
+shuffle/AMGDS
+shuffleboard/SM
+shuffler/SM
+shun/S
+shunned
+shunning
+shunt/MSDG
+shush/DSG
+shut/S
+shutdown/SM
+shuteye/M
+shutoff/SM
+shutout/SM
+shutter/SMDG
+shutterbug/MS
+shutting
+shuttle/DSMG
+shuttlecock/GMDS
+shy/TGDRSMY
+shyer
+shyest
+shyness/M
+shyster/SM
+sibilant/SM
+sibling/SM
+sibyl/MS
+sibylline
+sic/S
+sicced
+siccing
+sick/PXTGDNRYS
+sickbay/S
+sickbed/SM
+sicken/DG
+sickening/Y
+sickie/MS
+sickish
+sickle/MS
+sickly/RT
+sickness/MS
+sicko/MS
+sickout/SM
+sickroom/MS
+side's
+side/AGDS
+sidearm/SM
+sidebar/SM
+sideboard/SM
+sideburns/M
+sidecar/SM
+sidekick/SM
+sidelight/MS
+sideline/DSMG
+sidelong
+sideman/M
+sidemen
+sidepiece/MS
+sidereal
+sidesaddle/MS
+sideshow/MS
+sidesplitting
+sidestep/MS
+sidestepped
+sidestepping
+sidestroke/DSMG
+sideswipe/DSMG
+sidetrack/SMDG
+sidewalk/MS
+sidewall/MS
+sideways
+sidewinder/SM
+siding/MS
+sidle/MGDS
+siege/MS
+sienna/M
+sierra/MS
+siesta/MS
+sieve/MGDS
+sift/ZGDRS
+sifted/U
+sifter/M
+sigh/GMD
+sighs
+sight/GMDYSJ
+sighting/M
+sightless
+sightly/UTR
+sightread
+sightseeing/M
+sightseer/MS
+sigma/MS
+sign's/C
+sign/AFCGDS
+signage/M
+signal/MDRYSZG
+signaler/M
+signalization/M
+signalize/GDS
+signalling
+signalman/M
+signalmen
+signatory/SM
+signature/MS
+signboard/MS
+signed/U
+signer/CMS
+signet/MS
+significance/IM
+significant/IY
+signification/M
+signify/XDSNG
+signing/CSM
+signor/FMS
+signora/SM
+signore
+signori
+signorina/MS
+signorine
+signpost/GSMD
+signup/MS
+silage/M
+silence/DRSMZG
+silencer/M
+silent/MRYST
+silhouette/DSMG
+silica/M
+silicate/MS
+siliceous
+silicon/SM
+silicone/M
+silicosis/M
+silk/MNS
+silkily
+silkiness/M
+silkscreen/SM
+silkworm/MS
+silky/TRP
+sill/MS
+silliness/M
+silly/TRSMP
+silo/MDS
+silt/GMDS
+silty/TR
+silvan
+silver/GMDS
+silverfish/MS
+silversmith/M
+silversmiths
+silverware/M
+silvery
+sim/SM
+simian/MS
+similar/Y
+similarity/ESM
+simile/MS
+similitude/EM
+simmer/GMDS
+simonize/DSG
+simony/M
+simpatico
+simper/GMDS
+simpering/Y
+simple/TRP
+simpleminded
+simpleness/M
+simpleton/SM
+simplex
+simplicity/M
+simplification/M
+simplify/DSXNG
+simplistic
+simplistically
+simply
+simulacra
+simulacrum/S
+simulate/EDSGN
+simulation/EM
+simulations
+simulator/EMS
+simulcast/GMDS
+simultaneity/M
+simultaneous/Y
+sin/ASM
+since
+sincere/IYT
+sincerer
+sincerity/IM
+sine/MS
+sinecure/MS
+sinew/MS
+sinewy
+sinful/PY
+sinfulness/M
+sing/BZGMDRYS
+singalong/S
+singe/MS
+singeing
+singer/M
+singing/M
+single-handedly
+single/PMGDS
+singleness/M
+singles/M
+singlet/S
+singleton/SM
+singletree/SM
+singsong/SMDG
+singular/SMY
+singularity/SM
+sinister
+sink/BZGMRS
+sinkable/U
+sinker/M
+sinkhole/SM
+sinless
+sinned
+sinner/MS
+sinning
+sinology
+sinuosity/M
+sinuous/Y
+sinus/MS
+sinusitis/M
+sinusoidal
+sip/SM
+siphon/GMDS
+sipped
+sipper/SM
+sipping
+sir/SXMN
+sire/CMGDS
+siree/M
+siren/M
+sirloin/SM
+sirocco/SM
+sirrah
+sirree/M
+sis/MS
+sisal/M
+sissified
+sissy/RSMT
+sister/ASM
+sisterhood/MS
+sisterliness/M
+sisterly/P
+sit/S
+sitar/SM
+sitarist/MS
+sitcom/SM
+site/MGDS
+sitemap/SM
+sitter/SM
+sitting/SM
+situ
+situate/DSXGN
+situation/M
+situational
+six/MSH
+sixfold
+sixpence/MS
+sixshooter/M
+sixteen/SMH
+sixteenth/M
+sixteenths
+sixth/M
+sixths
+sixtieth/M
+sixtieths
+sixty/SMH
+size's
+size/AGBDRS
+sizeable
+sizing/M
+sizzle/DRSMZG
+ska/M
+skate/MZGDRS
+skateboard/MDRSZG
+skateboarder/M
+skateboarding/M
+skater/M
+skating/M
+skedaddle/MGDS
+skeet/ZMR
+skein/MS
+skeletal
+skeleton/SM
+skeptic/SM
+skeptical/Y
+skepticism/M
+sketch/MDRSZG
+sketchbook/S
+sketcher/M
+sketchily
+sketchiness/M
+sketchpad/S
+sketchy/RTP
+skeuomorph
+skeuomorphic
+skeuomorphism
+skeuomorphs
+skew/MDRZGS
+skewbald/S
+skewer/MDG
+ski/SZGMDR
+skibob/S
+skid/MS
+skidded
+skidding
+skidpan/S
+skier/M
+skiff/SM
+skiffle
+skiing/M
+skill's
+skill/CSD
+skilled/U
+skillet/SM
+skillful/UY
+skillfulness/M
+skim/MS
+skimmed
+skimmer/SM
+skimming
+skimp/SDG
+skimpily
+skimpiness/M
+skimpy/RTP
+skin/AMS
+skincare/M
+skinflick/MS
+skinflint/MS
+skinful
+skinhead/MS
+skinless
+skinned/A
+skinniness/M
+skinning/A
+skinny/RMTP
+skint
+skintight
+skip/MS
+skipped
+skipper/SMDG
+skipping
+skirmish/ZGMDRS
+skirt/SMDG
+skit/MS
+skitter/GSD
+skittish/YP
+skittishness/M
+skittle/S
+skive/DRSZG
+skivvy/DSMG
+skoal/SM
+skua/S
+skulduggery/M
+skulk/SDRZG
+skulker/M
+skull/SM
+skullcap/MS
+skullduggery/M
+skunk/SMDG
+sky/GSM
+skycap/SM
+skydive/DRSZG
+skydiver/M
+skydiving/M
+skyjack/JZGSDR
+skyjacker/M
+skyjacking/M
+skylark/SGMD
+skylight/MS
+skyline/SM
+skyrocket/GSMD
+skyscraper/SM
+skyward/S
+skywriter/SM
+skywriting/M
+slab/MS
+slabbed
+slabbing
+slack/PXZTGMDNRYS
+slacken/DG
+slacker/M
+slackness/M
+slacks/M
+slag/MS
+slagged
+slagging
+slagheap/S
+slain
+slake/GDS
+slalom/MSDG
+slam/MS
+slammed
+slammer/SM
+slamming
+slander/MZGDRS
+slanderer/M
+slanderous
+slang/M
+slangy/RT
+slant/MSDG
+slanting/Y
+slantwise
+slap/MS
+slapdash
+slaphappy
+slapped
+slapper/S
+slapping
+slapstick/M
+slash/MDRSZG
+slasher/M
+slat/MDGS
+slate/SM
+slather/SDG
+slatted
+slattern/SMY
+slaughter/MDRZGS
+slaughterer/M
+slaughterhouse/MS
+slave/DRSMZG
+slaveholder/MS
+slaver/MDG
+slavery/M
+slavish/PY
+slavishness/M
+slaw/M
+slay/DRZGJS
+slayer/M
+slaying/M
+sleaze/SM
+sleazebag/S
+sleazeball/S
+sleazily
+sleaziness/M
+sleazy/PRT
+sled/MS
+sledded
+sledder/SM
+sledding
+sledge/DSMG
+sledgehammer/GSMD
+sleek/SDRYTGP
+sleekness/M
+sleep/SMRZG
+sleeper/M
+sleepily
+sleepiness/M
+sleepless/PY
+sleeplessness/M
+sleepover/SM
+sleepwalk/ZGSDR
+sleepwalker/M
+sleepwalking/M
+sleepwear/M
+sleepy/RPT
+sleepyhead/MS
+sleet/SMDG
+sleety
+sleeve/DSM
+sleeveless
+sleigh/MDG
+sleighs
+sleight/SM
+slender/PRT
+slenderize/DSG
+slenderness/M
+slept
+sleuth/MG
+sleuths
+slew/MDGS
+slice/DRSMZG
+slicer/M
+slick/SMDRYZTGP
+slicker/M
+slickness/M
+slid
+slide/RSMZG
+slider/M
+slideshow/MS
+slight/SMDRYTGP
+slightness/M
+slim/PS
+slime/M
+sliminess/M
+slimline
+slimmed
+slimmer/S
+slimmest
+slimming/M
+slimness/M
+slimy/RTP
+sling/SMG
+slingback/S
+slingshot/SM
+slink/SG
+slinky/RT
+slip/MS
+slipcase/MS
+slipcover/MS
+slipknot/MS
+slippage/MS
+slipped
+slipper/SM
+slipperiness/M
+slippery/PRT
+slipping
+slippy
+slipshod
+slipstream/SM
+slipway/SM
+slit/MS
+slither/SGMD
+slithery
+slitter
+slitting
+sliver/GSMD
+slob/MS
+slobbed
+slobber/MDSG
+slobbery
+slobbing
+sloe/MS
+slog/MS
+slogan/SM
+sloganeering
+slogged
+slogging
+sloop/SM
+slop/MDGS
+slope/SM
+slopped
+sloppily
+sloppiness/M
+slopping
+sloppy/PTR
+slops/M
+slosh/DSG
+slot/MS
+sloth/M
+slothful/YP
+slothfulness/M
+sloths
+slotted
+slotting
+slouch/ZGMDRS
+sloucher/M
+slouchy/TR
+slough/GMD
+sloughs
+sloven/SMY
+slovenliness/M
+slovenly/PTR
+slow/DRYTGSP
+slowcoach/S
+slowdown/SM
+slowness/M
+slowpoke/SM
+sludge/M
+sludgy/RT
+slue/MGDS
+slug/MS
+sluggard/MS
+slugged
+slugger/SM
+slugging
+sluggish/PY
+sluggishness/M
+sluice/DSMG
+slum/MS
+slumber/GSMD
+slumberous
+slumbrous
+slumdog/SM
+slumlord/MS
+slummed
+slummer
+slumming
+slummy/RT
+slump/SMDG
+slung
+slunk
+slur/MS
+slurp/SMDG
+slurred
+slurring
+slurry/M
+slush/MDSG
+slushiness/M
+slushy/RPT
+slut/MS
+sluttish
+slutty/RT
+sly/TRY
+slyer
+slyest
+slyness/M
+smack/SMDRZG
+smacker/M
+small/SMRTP
+smallholder/S
+smallholding/S
+smallish
+smallness/M
+smallpox/M
+smarmy/RT
+smart/SMDNRYXTGP
+smarten/DG
+smartness/M
+smartphone/SM
+smarts/M
+smartwatch/MS
+smarty/SM
+smartypants/M
+smash/MDRSZG
+smasher/M
+smashup/SM
+smattering/MS
+smear/SMDG
+smeary/RT
+smell/SMDG
+smelliness/M
+smelly/RPT
+smelt/SMDRZG
+smelter/M
+smidge/SM
+smidgen/MS
+smilax/M
+smile/DSMG
+smiley/SM
+smiling/Y
+smirch/GMDS
+smirk/SMDG
+smite/SG
+smith/M
+smithereens/M
+smiths
+smithy/SM
+smitten
+smock/SMDG
+smocking/M
+smog/MS
+smoggy/RT
+smoke/DRSMZG
+smokehouse/MS
+smokeless
+smoker/M
+smokescreen/SM
+smokestack/SM
+smokey
+smokiness/M
+smoking/M
+smoky/RTP
+smolder/SGMD
+smooch/MDSG
+smoochy
+smooth/PDRYTG
+smoothie/M
+smoothness/M
+smooths
+smoothy/SM
+smorgasbord/SM
+smote
+smother/GSMD
+smoulder/GMDS
+smudge/DSMG
+smudgy/TR
+smug/YP
+smugger
+smuggest
+smuggle/ZGDRS
+smuggler/M
+smuggling/M
+smugness/M
+smurf/S
+smut/MS
+smuttiness/M
+smutty/TRP
+smrgsbord/MS
+snack/SMDG
+snaffle/DSMG
+snafu/SM
+snag/MS
+snagged
+snagging
+snail/SMDG
+snake/DSMG
+snakebite/MS
+snakelike
+snakeskin
+snaky/RT
+snap's
+snap/US
+snapdragon/SM
+snapped/U
+snapper/MS
+snappily
+snappiness/M
+snapping/U
+snappish/YP
+snappishness/M
+snappy/TRP
+snapshot/SM
+snare/DSMG
+snarf/SDG
+snark/S
+snarkily
+snarky/TR
+snarl's
+snarl/USDG
+snarling/Y
+snarly/TR
+snatch/ZGMDRS
+snatcher/M
+snazzily
+snazzy/TRP
+sneak/SMDRZG
+sneaker/M
+sneakily
+sneakiness/M
+sneaking/Y
+sneaky/TRP
+sneer/SJMDG
+sneering/Y
+sneeze/DSMG
+snick/SDRZG
+snicker/MDG
+snide/RYT
+sniff/SMDRYZG
+sniffer/M
+sniffle/DSMG
+sniffly/RT
+sniffy/RT
+snifter/SM
+snigger/SMDG
+snip/MDRZGS
+snipe/SM
+sniper/M
+snipped
+snippet/SM
+snipping
+snippy/RT
+snips/M
+snit/MS
+snitch/MDSG
+snivel/SMDRZG
+sniveler/M
+snob/MS
+snobbery/M
+snobbish/PY
+snobbishness/M
+snobby/RT
+snog/S
+snogged
+snogging
+snood/SM
+snooker/MDSG
+snoop/SMDRZG
+snooper/M
+snoopy/TR
+snoot/SM
+snootily
+snootiness/M
+snooty/PTR
+snooze/DSMG
+snore/DRSMZG
+snorer/M
+snorkel/ZGMDRS
+snorkeler/M
+snorkeling/M
+snort/SMDRZG
+snorter/M
+snot/MS
+snottily
+snottiness/M
+snotty/TPR
+snout/SM
+snow/MDGS
+snowball/GSMD
+snowbank/SM
+snowbird/SM
+snowblower/MS
+snowboard/ZGMDRS
+snowboarder/M
+snowboarding/M
+snowbound
+snowcap/MS
+snowcat/MS
+snowdrift/SM
+snowdrop/SM
+snowfall/SM
+snowfield/SM
+snowflake/SM
+snowiness/M
+snowline
+snowman/M
+snowmen
+snowmobile/DSMG
+snowplow/SGMD
+snowshed
+snowshoe/SM
+snowshoeing
+snowstorm/SM
+snowsuit/SM
+snowy/PRT
+snub/MS
+snubbed
+snubbing
+snuff/SMDRYZG
+snuffbox/MS
+snuffer/M
+snuffle/MGDS
+snug/MYSP
+snugged
+snugger
+snuggest
+snugging
+snuggle/MGDS
+snugness/M
+so
+soak/MDGSJ
+soaking/M
+soap/MDGS
+soapbox/MS
+soapiness/M
+soapstone/M
+soapsuds/M
+soapy/RPT
+soar/MDGS
+sob/SM
+sobbed
+sobbing/Y
+sober/SDRYPTG
+soberness/M
+sobriety/IM
+sobriquet/SM
+soc
+soccer/M
+sociability/M
+sociable/SM
+sociably
+social/SMY
+socialism/M
+socialist/SM
+socialistic
+socialite/SM
+socialization/M
+socialize/DSG
+societal
+society/SM
+socioeconomic
+socioeconomically
+sociological/Y
+sociologist/SM
+sociology/M
+sociopath/M
+sociopaths
+sociopolitical
+sock/MDGS
+socket/SM
+sockeye/SM
+sod/SM
+soda/MS
+sodded
+sodden/Y
+sodding
+sodium/M
+sodomite/MS
+sodomize/GDS
+sodomy/M
+soever
+sofa/MS
+soffit/S
+soft/NRYXTP
+softback
+softball/MS
+softbound
+softcover
+soften/DRZG
+softener/M
+softhearted
+softie/M
+softness/M
+software/M
+softwood/SM
+softy/SM
+soggily
+sogginess/M
+soggy/RTP
+soigne
+soignee
+soign
+soigne
+soil/MDGS
+soiled/U
+soiree/SM
+soire/SM
+sojourn/ZGMDRS
+sojourner/M
+sol/SM
+solace/DSMG
+solar
+solaria
+solarium/M
+sold
+solder/ZGSMDR
+solderer/M
+soldier/MDYSG
+soldiery/M
+sole/FSDGM
+solecism/SM
+solely
+solemn/PTRY
+solemness/M
+solemnify/DSG
+solemnity/SM
+solemnization/M
+solemnize/DSG
+solemnness/M
+solenoid/MS
+solicit/GDS
+solicitation/SM
+solicited/U
+solicitor/SM
+solicitous/PY
+solicitousness/M
+solicitude/M
+solid/PSMRYT
+solidarity/M
+solidi
+solidification/M
+solidify/DSNG
+solidity/M
+solidness/M
+solidus/M
+soliloquies
+soliloquize/DSG
+soliloquy/M
+solipsism/M
+solipsistic
+solitaire/MS
+solitariness/M
+solitary/SMP
+solitude/M
+solo/MDGS
+soloist/MS
+solstice/MS
+solubility/IM
+soluble/MS
+solute's
+solute/AXN
+solutes
+solution's/AE
+solvability
+solvable/IU
+solve/EADSG
+solved/U
+solvency/IM
+solvent/IMS
+solver/SM
+somatic
+somatosensory
+somber/PY
+somberness/M
+sombre/PY
+sombreness/M
+sombrero/MS
+some
+somebody/SM
+someday
+somehow
+someone/MS
+someplace
+somersault/MDGS
+somerset/SM
+somersetted
+somersetting
+something/SM
+sometime/S
+someway/S
+somewhat/S
+somewhere
+sommelier/MS
+somnambulism/M
+somnambulist/SM
+somnolence/M
+somnolent
+son/SM
+sonar/SM
+sonata/SM
+sonatina/SM
+song/MS
+songbird/SM
+songbook/SM
+songfest/SM
+songster/MS
+songstress/MS
+songwriter/SM
+songwriting
+sonic
+sonnet/SM
+sonny/SM
+sonogram/SM
+sonority/M
+sonorous/YP
+sonorousness/M
+sonsofbitches
+soon/RT
+soot/M
+sooth/MDRSZG
+soothe
+soother/M
+soothing/Y
+soothsayer/MS
+soothsaying/M
+sooty/RT
+sop/SM
+soph
+sophism/M
+sophist/MS
+sophistic
+sophistical
+sophisticate/DSMGN
+sophisticated/U
+sophistication/M
+sophistry/SM
+sophomore/MS
+sophomoric
+soporific/MS
+soporifically
+sopped
+sopping
+soppy/RT
+soprano/MS
+sorbet/SM
+sorcerer/MS
+sorceress/MS
+sorcery/M
+sordid/PY
+sordidness/M
+sore/MYTRSP
+sorehead/MS
+soreness/M
+sorghum/M
+sorority/SM
+sorrel/SM
+sorrily
+sorriness/M
+sorrow/SMDG
+sorrowful/YP
+sorrowfulness/M
+sorry/RTP
+sort/FASGDM
+sorta
+sorted/U
+sorter/SM
+sortie/DSM
+sortieing
+sot/SM
+sottish
+sou'wester
+sou/SMH
+souffle/SM
+souffl/SM
+sough/MDG
+soughs
+sought/U
+souk/S
+soul/MS
+soulful/YP
+soulfulness/M
+soulless/YP
+soulmate/SM
+sound/JPSMDRYZTG
+soundalike/S
+soundbar/S
+soundbite/S
+soundboard/MS
+soundcheck/S
+sounder/M
+sounding/M
+soundless/Y
+soundness/UM
+soundproof/GDS
+soundproofing/M
+soundscape/S
+soundtrack/SM
+soup/MDGS
+soupcon/MS
+soupy/RT
+soupon/MS
+sour/MDRYTGSP
+source/ADSMG
+sourdough/M
+sourdoughs
+sourish
+sourness/M
+sourpuss/MS
+sousaphone/MS
+souse/DSMG
+south/M
+southbound
+southeast/ZMR
+southeaster/MY
+southeastern
+southeastward/S
+southerly/SM
+southern/SZMR
+southerner/M
+southernmost
+southpaw/SM
+southward/MS
+southwest/ZMR
+southwester/MY
+southwestern
+southwestward/S
+souvenir/SM
+sovereign/SM
+sovereignty/M
+soviet/SM
+sow's
+sow/ASGD
+sower/SM
+sown/A
+soy/M
+soybean/MS
+sozzled
+spa/SM
+space/DRSMZG
+spacecraft/MS
+spaceflight/MS
+spaceman/M
+spacemen
+spaceport/SM
+spacer/M
+spaceship/SM
+spacesuit/SM
+spacetime
+spacewalk/SGMD
+spacewoman/M
+spacewomen
+spacey
+spacial
+spacier
+spaciest
+spaciness/M
+spacing/M
+spacious/YP
+spaciousness/M
+spade/DSMG
+spadeful/MS
+spadework/M
+spadices
+spadix/M
+spaghetti/M
+spake
+spam/MS
+spammed
+spammer/SM
+spamming
+span/MS
+spandex/M
+spangle/DSMG
+spangly
+spaniel/SM
+spank/SMDGJ
+spanking/M
+spanned
+spanner/SM
+spanning
+spar/MS
+spare/DRSMYTGP
+spareness/M
+spareribs/M
+sparing/UY
+spark/SMDYG
+sparkle/DRSMZG
+sparkler/M
+sparky/RT
+sparred
+sparring
+sparrow/SM
+sparrowhawk/S
+sparse/RYTP
+sparseness/M
+sparsity/M
+spartan
+spasm/SM
+spasmodic
+spasmodically
+spastic/SM
+spat/MS
+spate/SM
+spathe/SM
+spatial/Y
+spatted
+spatter/SGMD
+spatting
+spatula/SM
+spavin/MD
+spawn/SMDG
+spay/DGS
+speak/SRZGJ
+speakeasy/SM
+speaker/M
+speakerphone/S
+spear/SMDG
+spearfish/GMDS
+speargun
+spearhead/GMDS
+spearmint/M
+spec/MS
+special/SMY
+specialism/S
+specialist/MS
+specialization/MS
+specialize/GDS
+specialty/SM
+specie/SM
+species/M
+specif
+specifiable
+specific/MS
+specifically
+specification/M
+specificity/M
+specified/U
+specify/XNZDRSG
+specimen/SM
+specious/YP
+speciousness/M
+speck/SMDG
+speckle/MGDS
+specs/M
+spectacle/SM
+spectacles/M
+spectacular/MYS
+spectate/DSG
+spectator/SM
+specter/AMS
+spectra
+spectral
+spectrogram/SM
+spectrometer/MS
+spectroscope/MS
+spectroscopic
+spectroscopy/M
+spectrum/M
+specula
+specular/Y
+specularity
+speculate/DSXGNV
+speculation/M
+speculative/Y
+speculator/MS
+speculum/S
+sped
+speech/MS
+speechify/DSG
+speechless/YP
+speechlessness/M
+speechwriter/S
+speed/SMRZG
+speedboat/SM
+speeder/M
+speedily
+speediness/M
+speeding/M
+speedometer/MS
+speedster/SM
+speedup/MS
+speedway/SM
+speedwell/M
+speedy/TPR
+speleological
+speleologist/MS
+speleology/M
+spell's
+spell/AJSDG
+spellbind/ZGRS
+spellbinder/M
+spellbound
+spellcheck/MDRZGS
+spellchecker/M
+spelldown/SM
+speller/MS
+spelling's
+spelt
+spelunker/MS
+spelunking/M
+spend/BSRZG
+spender/M
+spending/M
+spendthrift/MS
+spent/U
+sperm/SM
+spermatozoa
+spermatozoon/M
+spermicidal
+spermicide/MS
+spew/MDRZGS
+spewer/M
+sphagnum/MS
+sphere/SM
+spherical/Y
+spheroid/SM
+spheroidal
+sphincter/MS
+sphinx/MS
+spic/S
+spice/DSMG
+spicily
+spiciness/M
+spick/S
+spicule/MS
+spicy/PRT
+spider/SM
+spiderweb/MS
+spidery
+spiel/SMDG
+spiff/SDG
+spiffy/TR
+spigot/SM
+spike/DSMG
+spikiness/M
+spiky/RPT
+spill/SMDG
+spillage/MS
+spillover/SM
+spillway/MS
+spin/MS
+spina
+spinach/M
+spinal/SMY
+spindle/MGDS
+spindly/TR
+spine/SM
+spineless/YP
+spinet/SM
+spinless
+spinnaker/SM
+spinner/MS
+spinneret/SM
+spinney/S
+spinning/M
+spinoff/MS
+spinster/SM
+spinsterhood/M
+spinsterish
+spiny/RT
+spiracle/SM
+spiraea/MS
+spiral/SGMDY
+spire's
+spire/IFAS
+spirea/SM
+spirit's
+spirit/ISGD
+spirited/Y
+spiritless
+spiritual/MYS
+spiritualism/M
+spiritualist/MS
+spiritualistic
+spirituality/M
+spirituous
+spirochete/SM
+spiry
+spit/MDGS
+spitball/ZGSMR
+spite/ASM
+spiteful/PY
+spitefuller
+spitefullest
+spitefulness/M
+spitfire/SM
+spitted
+spitting
+spittle/M
+spittoon/MS
+spiv/S
+splanchnic
+splash/GMDS
+splashdown/MS
+splashily
+splashiness/M
+splashy/RTP
+splat/SM
+splatted
+splatter/GSMD
+splatting
+splay/SMDG
+splayfeet
+splayfoot/MD
+spleen/SM
+splendid/RYT
+splendor/MS
+splendorous
+splenectomy
+splenetic
+splice/DRSMZG
+splicer/M
+spliff/S
+spline/S
+splint/SZGMDR
+splinter/MDG
+splintery
+split/SM
+splitter/MS
+splitting/MS
+splodge/S
+splosh/DSG
+splotch/MDSG
+splotchy/TR
+splurge/DSMG
+splutter/GMDS
+spoil's
+spoil/CSDRZG
+spoilage/M
+spoiled/U
+spoiler/CM
+spoilsport/MS
+spoke/SM
+spoken/U
+spokesman/M
+spokesmen
+spokespeople
+spokesperson/MS
+spokeswoman/M
+spokeswomen
+spoliation/CM
+sponge/DRSMZG
+sponger/M
+sponginess/M
+spongy/RPT
+sponsor/MDGS
+sponsorship/SM
+spontaneity/M
+spontaneous/Y
+spoof/SMDG
+spook/SMDG
+spookiness/M
+spooky/RPT
+spool/SMDG
+spoon/SMDG
+spoonbill/MS
+spoonerism/MS
+spoonful/SM
+spoor/SMDG
+sporadic
+sporadically
+spore/DSMG
+sporran/S
+sport/SMDGV
+sportiness/M
+sporting/Y
+sportive/Y
+sportscast/MRZGS
+sportscaster/M
+sportsman/M
+sportsmanlike/U
+sportsmanship/M
+sportsmen
+sportspeople
+sportsperson
+sportswear/M
+sportswoman/M
+sportswomen
+sportswriter/SM
+sporty/TPR
+spot/CMS
+spotless/PY
+spotlessness/M
+spotlight/GSMD
+spotlit
+spotted
+spotter/MS
+spottily
+spottiness/M
+spotting
+spotty/TPR
+spousal/MS
+spouse/SM
+spout/SMDG
+sprain/GSMD
+sprang
+sprat/SM
+sprawl/GSMD
+spray's
+spray/ASDG
+sprayer/MS
+spread/ZGBSMR
+spreadeagled
+spreader/M
+spreadsheet/MS
+spree/DSM
+spreeing
+sprig/SM
+sprigged
+sprightliness/M
+sprightly/RTP
+spring/GSM
+springboard/MS
+springbok/MS
+springily
+springiness/M
+springlike
+springtime/M
+springy/RPT
+sprinkle/DRSJMZG
+sprinkler/M
+sprinkling/M
+sprint/ZGSMDR
+sprinter/M
+sprite/SM
+spritz/ZGMDRS
+spritzer/M
+sprocket/MS
+sprog/S
+sprout/GSMD
+spruce/DRSPMYTG
+spruceness/M
+sprung
+spry/RYT
+spryness/M
+spud/MS
+spume/DSMG
+spumoni/M
+spumy
+spun
+spunk/SM
+spunky/TR
+spur/MS
+spurge/M
+spurious/PY
+spuriousness/M
+spurn/SDG
+spurred
+spurring
+spurt/SMDG
+sputa
+sputnik/MS
+sputter/MDGS
+sputum/M
+spy/GDSM
+spyglass/MS
+spymaster/S
+spyware/MS
+sq
+sqq
+squab/SM
+squabble/MZGDRS
+squabbler/M
+squad/SM
+squadron/MS
+squalid/PTRY
+squalidness/M
+squall/SGMD
+squally
+squalor/M
+squamous
+squander/GDS
+square/PDRSMYTG
+squareness/M
+squarish
+squash/GMDS
+squashy/TR
+squat/SMP
+squatness/M
+squatted
+squatter/MS
+squattest
+squatting
+squaw/SM
+squawk/SZGMDR
+squawker/M
+squeak/SZGMDR
+squeaker/M
+squeakily
+squeakiness/M
+squeaky/TRP
+squeal/SZGMDR
+squealer/M
+squeamish/PY
+squeamishness/M
+squeegee/MDS
+squeegeeing
+squeeze/BMZGDRS
+squeezebox/S
+squeezer/M
+squelch/GMDS
+squelchy
+squib/SM
+squid/SM
+squidgy
+squiffy
+squiggle/DSMG
+squiggly
+squint/STGMDR
+squire/DSMG
+squirm/SGMD
+squirmy/RT
+squirrel/SGMD
+squirt/SGMD
+squish/GMDS
+squishy/RT
+sriracha
+ssh
+st
+stab/MYS
+stabbed
+stabber/MS
+stabbing/MS
+stability/IM
+stabilization/CM
+stabilize/CDSG
+stabilizer/MS
+stable/DRSMTG
+stableman/M
+stablemate/S
+stablemen
+stably/U
+staccato/MS
+stack/SMDG
+stadium/MS
+staff's
+staff/ASDG
+staffer/MS
+staffing/M
+stag/MDGSJ
+stage/SM
+stagecoach/MS
+stagecraft/M
+stagehand/MS
+stagestruck
+stagey
+stagflation/M
+stagger/MDGS
+staggering/Y
+staging/M
+stagnancy/M
+stagnant/Y
+stagnate/DSGN
+stagnation/M
+stagy/RT
+staid/PRYT
+staidness/M
+stain/SMDG
+stained/U
+stainless/M
+stair/SM
+staircase/MS
+stairway/MS
+stairwell/SM
+stake/DSMG
+stakeholder/MS
+stakeout/SM
+stalactite/MS
+stalagmite/MS
+stale/DRSTGP
+stalemate/DSMG
+staleness/M
+stalk/SMDRJZG
+stalker/M
+stalking/M
+stall's
+stall/SDG
+stallholder/S
+stallion/MS
+stalwart/MYS
+stamen/SM
+stamina/M
+stammer/ZGMDRS
+stammerer/M
+stammering/Y
+stamp/SMDRZG
+stampede/MGDS
+stamper/M
+stance/ISM
+stanch/TGDRS
+stanchion/SM
+stand/SMRJZG
+standalone
+standard/MS
+standardization/M
+standardize/DSG
+standby/M
+standbys
+standee/MS
+stander/M
+standing/M
+standoff/MS
+standoffish
+standout/MS
+standpipe/SM
+standpoint/MS
+standstill/MS
+standup/M
+stank
+stanza/SM
+staph/M
+staphylococcal
+staphylococci
+staphylococcus/M
+staple/DRSMZG
+stapler/M
+star/MDRZGS
+starboard/M
+starburst/S
+starch/GMDS
+starchily
+starchiness/M
+starchy/PTR
+stardom/M
+stardust/M
+stare/SM
+starer/M
+starfish/MS
+starfruit
+stargaze/DRSZG
+stargazer/M
+stark/RYPZT
+starkness/M
+starless
+starlet/MS
+starlight/M
+starling/SM
+starlit
+starred
+starring
+starry/TR
+starstruck
+start/ASMDG
+starter/MS
+startle/GDS
+startling/Y
+startup/MS
+starvation/M
+starve/DSJG
+starveling/MS
+stash/MDSG
+stasis
+stat/MS
+state/DRSMYGNLX
+statecraft/M
+stated/U
+statehood/M
+statehouse/MS
+stateless/P
+statelessness/M
+stateliness/M
+stately/PRT
+statement/AMS
+statemented
+statementing
+stateroom/MS
+stateside
+statesman/M
+statesmanlike
+statesmanship/M
+statesmen
+stateswoman/M
+stateswomen
+statewide
+static/SM
+statically
+station/MDRZG
+stationary
+stationer/M
+stationery/M
+stationmaster/S
+statistic/MS
+statistical/Y
+statistician/SM
+statuary/M
+statue/SM
+statuesque
+statuette/MS
+stature/MS
+status/MS
+statute/MS
+statutorily
+statutory
+staunch/PDRSYTG
+staunchness/M
+stave/DSMG
+stay/MDRZGS
+std
+stdio
+stead/SM
+steadfast/YP
+steadfastness/M
+steadily/U
+steadiness/UM
+steady/TGPDRSM
+steak/SM
+steakhouse/SM
+steal/SMRHZG
+stealth/M
+stealthily
+stealthiness/M
+stealthy/TPR
+steam/SMDRZG
+steamboat/MS
+steamer/M
+steamfitter/SM
+steamfitting/M
+steaminess/M
+steampunk
+steamroll/ZGDRS
+steamroller/MDG
+steamship/MS
+steamy/TPR
+steed/SM
+steel/SMDG
+steeliness/M
+steelmaker/S
+steelworker/SM
+steelworks/M
+steely/PTR
+steelyard/SM
+steep/SMDNRYPXTG
+steepen/GD
+steeple/MS
+steeplechase/MS
+steeplejack/SM
+steepness/M
+steer/SMDBG
+steerage/M
+steering/M
+steersman/M
+steersmen
+stegosauri
+stegosaurus/MS
+stein/SM
+stellar
+stem/MS
+stemless
+stemmed
+stemming
+stemware/M
+stench/MS
+stencil/GMDS
+steno/SM
+stenographer/SM
+stenographic
+stenography/M
+stenosis
+stent/SM
+stentorian
+step/IMS
+stepbrother/SM
+stepchild/M
+stepchildren/M
+stepdad/MS
+stepdaughter/SM
+stepfather/SM
+stepladder/MS
+stepmom/MS
+stepmother/SM
+stepparent/SM
+steppe/DRSMZG
+stepper/M
+steppingstone/SM
+stepsister/MS
+stepson/MS
+steradian
+stereo/SM
+stereogram/MS
+stereophonic
+stereoscope/MS
+stereoscopic
+stereotype/DSMG
+stereotypical
+sterile
+sterility/M
+sterilization/SM
+sterilize/DRSZG
+sterilizer/M
+sterling/M
+stern/SMRYPT
+sternness/M
+sternum/MS
+steroid/MS
+steroidal
+stertorous
+stet/S
+stethoscope/MS
+stetson/MS
+stetted
+stetting
+stevedore/SM
+stevia/M
+stew/MDGS
+steward/GMDS
+stewardess/MS
+stewardship/M
+stick/SMRZG
+sticker/M
+stickily
+stickiness/M
+stickleback/SM
+stickler/MS
+stickpin/MS
+stickup/MS
+sticky/PTRSM
+stiff/SMDNRYPXTG
+stiffen/ZGDR
+stiffener/M
+stiffening/M
+stiffness/M
+stifle/DSJG
+stifling/Y
+stigma/SM
+stigmata
+stigmatic
+stigmatization/M
+stigmatize/GDS
+stile/SM
+stiletto/SM
+still's
+still/ITGSD
+stillbirth/M
+stillbirths
+stillborn
+stiller
+stillness/M
+stilt/SMD
+stilted/Y
+stimulant/SM
+stimulate/DSGNV
+stimulation/M
+stimuli
+stimulus/M
+sting/ZGSMR
+stinger/M
+stingily
+stinginess/M
+stingray/SM
+stingy/RTP
+stink/ZGSMR
+stinkbug/SM
+stinker/M
+stinky/RT
+stint/GSMD
+stipend/SM
+stipendiary/S
+stipple/DSMG
+stippling/M
+stipulate/XDSGN
+stipulation/M
+stir/MS
+stirred
+stirrer/SM
+stirring/SY
+stirrup/SM
+stitch's
+stitch/ADSG
+stitchery/M
+stitching/M
+stoat/SM
+stochastic
+stock's
+stock/AGSD
+stockade/DSMG
+stockbreeder/MS
+stockbroker/SM
+stockbroking/M
+stockholder/SM
+stockily
+stockiness/M
+stockinet/M
+stockinette/M
+stocking/SM
+stockist/S
+stockpile/MGDS
+stockpot/SM
+stockroom/MS
+stocktaking/M
+stocky/RTP
+stockyard/MS
+stodge
+stodgily
+stodginess/M
+stodgy/RTP
+stogie/M
+stogy/SM
+stoic/SM
+stoical/Y
+stoicism/M
+stoke/DRSZG
+stoker/M
+stole/SM
+stolen
+stolid/RYTP
+stolidity/M
+stolidness/M
+stolon/MS
+stomach/MDRZG
+stomachache/SM
+stomacher/M
+stomachs
+stomp/GSMD
+stone/DRSMZG
+stonemason/MS
+stoner/M
+stonewall/GSD
+stoneware/M
+stonewashed
+stonework/M
+stonily
+stoniness/M
+stonkered
+stonking
+stony/TRP
+stood
+stooge/MS
+stool/SM
+stoolie/SM
+stoop/GSMD
+stop's
+stop/US
+stopcock/SM
+stopgap/SM
+stoplight/MS
+stopover/MS
+stoppable/U
+stoppage/MS
+stopped/U
+stopper/GSMD
+stopping/U
+stopple/DSMG
+stopwatch/MS
+stopword/S
+storage/M
+store's
+store/ADSG
+storefront/MS
+storehouse/MS
+storekeeper/SM
+storeroom/SM
+stork/SM
+storm/GSMD
+stormily
+storminess/M
+stormy/RPT
+story/DSM
+storyboard/MS
+storybook/SM
+storyteller/MS
+storytelling/M
+stoup/SM
+stout/TSMRYP
+stouthearted
+stoutness/M
+stove/SM
+stovepipe/SM
+stow/DGS
+stowage/M
+stowaway/MS
+straddle/DRSMZG
+straddler/M
+strafe/MGDS
+straggle/DRSZG
+straggler/M
+straggly/TR
+straight/SPXTMNRY
+straightaway/SM
+straightedge/SM
+straighten/ZGDR
+straightener/M
+straightforward/YPS
+straightforwardness/M
+straightness/M
+straightway
+strain's
+strain/FADSG
+strainer/ASM
+strait/MNSX
+straiten/GD
+straitjacket/SGMD
+straitlaced
+strand/MDSG
+strange/PRYZT
+strangeness/M
+stranger/M
+strangle/ZGDRS
+stranglehold/SM
+strangler/M
+strangulate/GNDS
+strangulation/M
+strap's
+strap/US
+strapless/MS
+strapped/U
+strapping/M
+strata
+stratagem/SM
+strategic/S
+strategical/Y
+strategics/M
+strategist/SM
+strategize/DG
+strategy/SM
+strati
+stratification/M
+stratify/DSGN
+stratosphere/SM
+stratospheric
+stratum/M
+stratus/M
+straw/GSMD
+strawberry/SM
+stray/GSMD
+streak/MDRSZG
+streaker/M
+streaky/TR
+stream/MDRSZG
+streamer/M
+streamline/DSG
+street/MS
+streetcar/MS
+streetlamp/S
+streetlight/SM
+streetwalker/SM
+streetwalking
+streetwise
+strength/M
+strengthen/AGDS
+strengthener/MS
+strengths
+strenuous/PY
+strenuousness/M
+strep/M
+streptococcal
+streptococci
+streptococcus/M
+streptomycin/M
+stress/MDSG
+stressed/U
+stressful
+stressors
+stretch/BZGMDRS
+stretcher/MDG
+stretchmarks
+stretchy/TR
+strew/GSDH
+strewn
+stria/M
+striae
+striated
+striation/MS
+stricken
+strict/RYPT
+strictness/M
+stricture/SM
+stridden
+stride/MGS
+stridency/M
+strident/Y
+strife/M
+strike/MZGRSJ
+strikebound
+strikebreaker/SM
+strikebreaking
+strikeout/MS
+striker/M
+striking/Y
+string/MDRSZG
+stringency/M
+stringent/Y
+stringer/M
+stringiness/M
+stringy/PTR
+strip/GSMD
+stripe/MS
+stripey
+stripling/MS
+stripped
+stripper/MS
+stripping
+striptease/MZGDRS
+stripteaser/M
+stripy
+strive/GS
+striven
+strobe/MS
+stroboscope/MS
+stroboscopic
+strode
+stroke/MGDS
+stroll/MDRSZG
+stroller/M
+strong/RYT
+strongbox/MS
+stronghold/MS
+strongman/M
+strongmen
+strongroom/S
+strontium/M
+strop/SM
+strophe/SM
+strophic
+stropped
+stroppily
+stropping
+stroppy/TRP
+strove
+struck
+struct/CFSM
+structural/Y
+structuralism
+structuralist/S
+structure's
+structure/AGDS
+structured/U
+strudel/SM
+struggle/MGDS
+strum/SM
+strummed
+strumming
+strumpet/MS
+strung/UA
+strut/SM
+strutted
+strutting
+strychnine/M
+stub/MS
+stubbed
+stubbing
+stubble/M
+stubbly
+stubborn/RYPT
+stubbornness/M
+stubby/RT
+stucco/MDG
+stuccoes
+stuck/U
+stud/MYS
+studbook/MS
+studded
+studding/M
+student/SM
+studentship/S
+studied/U
+studiedly
+studio/MS
+studious/PY
+studiousness/M
+studly/RT
+study's
+study/AGDS
+stuff/GSMDJ
+stuffily
+stuffiness/M
+stuffing/M
+stuffy/RPT
+stultification/M
+stultify/DSNG
+stumble/DRSMZG
+stumbler/M
+stump/GSMD
+stumpy/TR
+stun/S
+stung
+stunk
+stunned
+stunner/S
+stunning/Y
+stunt/GSMD
+stuntman
+stuntmen
+stupefaction/M
+stupefy/DSG
+stupefying/Y
+stupendous/Y
+stupid/TMRYS
+stupidity/SM
+stupor/MS
+sturdily
+sturdiness/M
+sturdy/TRP
+sturgeon/SM
+stutter/MDRSZG
+stutterer/M
+sty/SM
+stye/MS
+style's
+style/ADSG
+styli
+stylish/PY
+stylishness/M
+stylist/SM
+stylistic/S
+stylistically
+stylize/DSG
+stylometric
+stylometry/S
+stylus/MS
+stymie/MDS
+stymieing
+styptic/SM
+suasion/EM
+suave/RYTP
+suaveness/M
+suavity/M
+sub/SM
+subaltern/MS
+subaqua
+subarctic
+subarea/MS
+subatomic
+subbasement/SM
+subbed
+subbing
+subbranch/MS
+subcategory/SM
+subclass
+subcommittee/SM
+subcompact/SM
+subconscious/PMY
+subconsciousness/M
+subcontinent/SM
+subcontinental
+subcontract/MDSG
+subcontractor/MS
+subculture/MS
+subcutaneous/Y
+subdivide/GDS
+subdivision/SM
+subdomain/MS
+subdominant
+subdue/DSG
+subeditor/S
+subfamily/SM
+subfreezing
+subgroup/MS
+subhead/GJMS
+subheading/M
+subhuman/MS
+subj
+subject/GVMDS
+subjection/M
+subjective/Y
+subjectivity/M
+subjoin/GDS
+subjugate/GNDS
+subjugation/M
+subjunctive/SM
+sublate/MGDS
+sublease/MGDS
+sublet/SM
+subletting
+sublieutenant/S
+sublimate/GNDS
+sublimation/M
+sublime/YTGDRS
+subliminal/Y
+sublimity/M
+sublingual
+submarginal
+submarine/MZRS
+submariner/M
+submerge/GDS
+submergence/M
+submerse/GNDS
+submersible/MS
+submersion/M
+submicroscopic
+submission's/A
+submission/MS
+submissive/PY
+submissiveness/M
+submit/AS
+submitted/A
+submitter
+submitting/A
+subnormal
+suborbital
+suborder/MS
+subordinate/DSMGN
+subordination/IM
+suborn/SGD
+subornation/M
+subpar
+subparagraph
+subparagraphs
+subpart
+subplot/MS
+subpoena/GMDS
+subpoenable
+subprime
+subprofessional/SM
+subprogram/S
+subrogate/DSN
+subroutine/SM
+subscribe/UASDG
+subscriber/MS
+subscript/MS
+subscription/MS
+subsection/MS
+subsequent/Y
+subservience/M
+subservient/Y
+subset/SM
+subside/GDS
+subsidence/M
+subsidiarity
+subsidiary/SM
+subsidization/M
+subsidize/ZGDRS
+subsidizer/M
+subsidy/SM
+subsist/SDG
+subsistence/M
+subsoil/M
+subsonic
+subspace
+subspecies/M
+substance/SM
+substandard
+substantial/IY
+substantiate/GNDSX
+substantiated/U
+substantiation/FM
+substantive/SMY
+substation/MS
+substituent/MS
+substitute/XMGNDS
+substitution/M
+substrata
+substrate/MS
+substratum/M
+substructure/SM
+subsume/DSG
+subsumption/S
+subsurface/M
+subsystem/SM
+subteen/SM
+subtenancy/M
+subtenant/SM
+subtend/SDG
+subterfuge/SM
+subterranean
+subtext/SM
+subtitle/DSMG
+subtle/TR
+subtlety/SM
+subtly
+subtopic/SM
+subtotal/SGMD
+subtract/GVSD
+subtraction/SM
+subtrahend/SM
+subtropic/S
+subtropical
+subtropics/M
+subtweet/S
+suburb/MS
+suburban/SM
+suburbanite/SM
+suburbia/M
+subvention/SM
+subversion/M
+subversive/SPMY
+subversiveness/M
+subvert/SDG
+subway/MS
+subwoofer/S
+subzero
+succeed/GDS
+success/VMS
+successful/UY
+succession/SM
+successive/Y
+successor/SM
+succinct/RYTP
+succinctness/M
+succor/SGMD
+succotash/M
+succubi
+succubus
+succulence/M
+succulency/M
+succulent/SM
+succumb/GDS
+such
+suchlike
+suck/MDRZGS
+sucker/GMD
+suckle/DSJG
+suckling/M
+sucky
+sucrose/M
+suction/SMDG
+sudden/PY
+suddenness/M
+suds/M
+sudsy/TR
+sue/DSG
+suede/M
+suet/M
+suety
+suffer/DRZGSJ
+sufferance/M
+sufferer/M
+suffering/M
+suffice/DSG
+sufficiency/IM
+sufficient/IY
+suffix/MDSG
+suffixation/M
+suffocate/GNDS
+suffocation/M
+suffragan/MS
+suffrage/M
+suffragette/SM
+suffragist/MS
+suffuse/DSGN
+suffusion/M
+sugar/GSMD
+sugarcane/M
+sugarcoat/GDS
+sugarless
+sugarplum/MS
+sugary/RT
+suggest/GVSDR
+suggestibility/M
+suggestible
+suggestion/SM
+suggestive/YP
+suggestiveness/M
+suicidal
+suicide/SM
+suit/BMDGS
+suitability/UM
+suitableness/M
+suitably/U
+suitcase/SM
+suite/SM
+suited/U
+suiting/M
+suitor/MS
+sukiyaki/M
+sulfa/M
+sulfate/SM
+sulfide/SM
+sulfonamides
+sulfur/MDSG
+sulfuric
+sulfurous
+sulk/MDGS
+sulkily
+sulkiness/M
+sulky/TRSMP
+sullen/RYPT
+sullenness/M
+sullied/U
+sully/GDS
+sultan/MS
+sultana/SM
+sultanate/MS
+sultrily
+sultriness/M
+sultry/RPT
+sum/SM
+sumac/M
+summarily
+summarize/GDS
+summary/SM
+summat
+summation/FMS
+summed
+summer/MDSG
+summerhouse/SM
+summertime/M
+summery
+summing
+summit/MDS
+summitry/M
+summon/DRSZG
+summoner/M
+summons/GMDS
+sumo/M
+sump/MS
+sumptuous/PY
+sumptuousness/M
+sun/SM
+sunbath/ZGMDRS
+sunbathe
+sunbather/M
+sunbathing/M
+sunbaths
+sunbeam/SM
+sunbed/S
+sunbelt/SM
+sunblock/MS
+sunbonnet/SM
+sunburn/SGMD
+sunburst/MS
+sundae/MS
+sundeck/S
+sunder/DSG
+sundial/SM
+sundown/SM
+sundress/S
+sundries/M
+sundry/S
+sunfish/MS
+sunflower/MS
+sung/U
+sunglasses/M
+sunhat/S
+sunk/N
+sunlamp/SM
+sunless
+sunlight/M
+sunlit
+sunned
+sunniness/M
+sunning
+sunny/TRP
+sunrise/SM
+sunroof/SM
+sunscreen/MS
+sunset/MS
+sunshade/MS
+sunshine/M
+sunshiny
+sunspot/SM
+sunstroke/M
+suntan/MS
+suntanned
+suntanning
+suntrap/S
+sunup/M
+sup/SZMR
+super/M
+superabundance/MS
+superabundant
+superannuate/GNDS
+superannuation/M
+superb/RYT
+supercargo/M
+supercargoes
+supercharge/ZGDRS
+supercharger/M
+supercilious/PY
+superciliousness/M
+supercity/SM
+supercomputer/MS
+superconducting
+superconductive
+superconductivity/M
+superconductor/SM
+supercritical
+superego/MS
+supererogation/M
+supererogatory
+superficial/Y
+superficiality/M
+superfine
+superfluity/M
+superfluous/YP
+superfluousness/M
+superglue
+supergrass/S
+superhero/MS
+superheroes
+superhighway/SM
+superhuman
+superimpose/GDS
+superimposition/M
+superintend/DSG
+superintendence/M
+superintendency/M
+superintendent/SM
+superior/MS
+superiority/M
+superlative/SMY
+superman/M
+supermarket/SM
+supermassive
+supermen
+supermodel/SM
+supermom/MS
+supernal
+supernatural/SY
+supernova/MS
+supernovae
+supernumerary/SM
+superpose/GDS
+superposition/M
+superpower/SM
+supersaturate/GNDS
+supersaturation/M
+superscribe/GDS
+superscript/MS
+superscription/M
+supersede/GDS
+superset
+supersize/GDS
+supersonic
+superspreader/SM
+superstar/MS
+superstardom
+superstate/S
+superstition/MS
+superstitious/Y
+superstore/MS
+superstructure/MS
+supertanker/MS
+superuser/S
+supervene/GDS
+supervention/M
+supervillain/MS
+supervise/XGNDS
+supervised/U
+supervision/M
+supervisor/MS
+supervisory
+superwoman/M
+superwomen
+supine/Y
+supp/DRZG
+supper/M
+suppertime
+suppl
+supplant/SDG
+supple/TLPR
+supplement/MDGS
+supplemental
+supplementary
+supplementation/M
+suppleness/M
+suppliant/SM
+supplicant/MS
+supplicate/GDS
+supplication/M
+supplier/M
+supply/ZGDRSMXN
+support/MDRSBZGV
+supportable/UI
+supported/U
+supporter/M
+suppose/GDS
+supposed/Y
+supposition/MS
+suppository/SM
+suppress/GVDS
+suppressant/MS
+suppressible
+suppression/M
+suppressor/SM
+suppurate/DSGN
+suppuration/M
+supra
+supranational
+supremacist/MS
+supremacy/M
+supreme/Y
+supremo/S
+supt
+surcease/DSMG
+surcharge/DSMG
+surcingle/SM
+sure/PYTR
+surefire
+surefooted
+sureness/M
+surety/SM
+surf/MDRZGS
+surface's
+surface/AGDS
+surfboard/MDSG
+surfeit/MDSG
+surfer/M
+surfing/M
+surge/DSMG
+surgeon/MS
+surgery/SM
+surgical/Y
+surjection/S
+surliness/M
+surly/PTR
+surmise/MGDS
+surmount/DGSB
+surmountable/I
+surname/MS
+surpass/GDS
+surpassed/U
+surplice/MS
+surplus/MS
+surplussed
+surplussing
+surprise/DSMGJ
+surprising/UY
+surreal
+surrealism/M
+surrealist/SM
+surrealistic
+surrealistically
+surrender/MDSG
+surreptitious/PY
+surreptitiousness/M
+surrey/MS
+surrogacy/M
+surrogate/SM
+surround/GSDJ
+surrounding/M
+surroundings/M
+surtax/MDSG
+surtitle/S
+surveil/S
+surveillance/SM
+surveillant/MS
+surveilled
+surveilling
+survey's
+survey/ADGS
+surveying/M
+surveyor/SM
+survival/SM
+survivalist/SM
+survive/DSGB
+survivor/SM
+survivorship
+susceptibility/SM
+susceptible/I
+sushi/M
+suspect/SMDG
+suspected/U
+suspend/SDRZG
+suspender/M
+suspense/XMN
+suspenseful
+suspension/M
+suspicion/SM
+suspicious/Y
+suss/DSG
+sustain/SDBG
+sustainability
+sustainable/U
+sustainably
+sustenance/M
+sutler/MS
+suttee
+suture/MGDS
+suzerain/MS
+suzerainty/M
+svelte/TR
+swab/MS
+swabbed
+swabbing
+swaddle/DSG
+swag/MS
+swagged
+swagger/SMDRG
+swagging
+swain/SM
+swallow/GSMD
+swallowtail/MS
+swam
+swami/SM
+swamp/GSMD
+swampland/M
+swampy/RT
+swan/MS
+swank/TGSMDR
+swankily
+swankiness/M
+swanky/RPT
+swanned
+swanning
+swansdown/M
+swansong/S
+swap/MS
+swapped
+swapping
+sward/SM
+swarm/GSMD
+swarthy/TR
+swash/GMDS
+swashbuckler/SM
+swashbuckling/M
+swastika/SM
+swat/MS
+swatch/MS
+swath/GMDS
+swathe/M
+swaths
+swatted
+swatter/SMDG
+swatting
+sway/MDGS
+swayback/MD
+swayed/U
+swear/ZGSR
+swearer/M
+swearword/MS
+sweat/ZGSMDR
+sweatband/MS
+sweater/M
+sweatpants/M
+sweats/M
+sweatshirt/SM
+sweatshop/MS
+sweatsuit/S
+sweaty/RT
+swede/SM
+sweep/ZGSMRJ
+sweeper/M
+sweeping/MY
+sweepings/M
+sweepstakes/M
+sweet/XTSMNRYP
+sweetbread/SM
+sweetbriar/SM
+sweetbrier/SM
+sweetcorn
+sweetened/U
+sweetener/MS
+sweetening/M
+sweetheart/SM
+sweetie/SM
+sweetish
+sweetmeat/MS
+sweetness/M
+swell/TGSMDRJ
+swellhead/MDS
+swelling/M
+swelter/SGMD
+swept
+sweptback
+swerve/MGDS
+swerving/U
+swift/PTSMRY
+swiftness/M
+swig/MS
+swigged
+swigging
+swill/GSMD
+swim/MS
+swimmer/SM
+swimming/MY
+swimsuit/SM
+swimwear
+swindle/DRSMZG
+swindler/M
+swine/SM
+swineherd/SM
+swing/ZGSMR
+swingeing
+swinger/M
+swinish
+swipe/DSMG
+swirl/GSMD
+swirly
+swish/TGMDRS
+switch/MDRSZGB
+switchback/MS
+switchblade/SM
+switchboard/SM
+switcher/M
+switcheroo/S
+switchover
+swivel/MDGS
+swiz
+swizz
+swizzle/DSG
+swollen
+swoon/SGMD
+swoop/SGMD
+swoosh/MDSG
+sword/SM
+swordfish/MS
+swordplay/M
+swordsman/M
+swordsmanship/M
+swordsmen
+swore
+sworn
+swot/S
+swotted
+swotting
+swum
+swung
+sybarite/SM
+sybaritic
+sycamore/MS
+sycophancy/M
+sycophant/SM
+sycophantic
+syllabi
+syllabic
+syllabicate/GNDS
+syllabication/M
+syllabification/M
+syllabify/DSNG
+syllable/MS
+syllabub/S
+syllabus/MS
+syllogism/MS
+syllogistic
+sylph/M
+sylphic
+sylphlike
+sylphs
+sylvan
+symbioses
+symbiosis/M
+symbiote/S
+symbiotic
+symbiotically
+symbol/MS
+symbolic
+symbolical/Y
+symbolism/M
+symbolization/M
+symbolize/DSG
+symbology
+symmetric/Y
+symmetrical/Y
+symmetry/SM
+sympathetic/U
+sympathetically/U
+sympathies/M
+sympathize/ZGDRS
+sympathizer/M
+sympathy/SM
+symphonic
+symphony/SM
+symposium/MS
+symptom/MS
+symptomatic
+symptomatically
+syn/H
+synagogal
+synagogue/SM
+synapse/MS
+synaptic
+sync/MDSG
+synches
+synchronicity
+synchronism/M
+synchronization/SM
+synchronize/ZGDRS
+synchronizer/M
+synchronous/Y
+synchrony
+syncopate/DSGN
+syncopation/M
+syncope/M
+syndicalism
+syndicalist/S
+syndicate/DSMGN
+syndication/M
+syndrome/SM
+synergism/M
+synergistic
+synergy/SM
+synesthesia
+synesthete/S
+synesthetic
+synfuel/MS
+synod/SM
+synonym/SM
+synonymous
+synonymy/M
+synopses
+synopsis/M
+synoptic
+synovial
+syntactic
+syntactical/Y
+syntax/M
+synthase/SM
+syntheses
+synthesis/M
+synthesize/ZGDRS
+synthesizer/M
+synthetic/SM
+synthetically
+synths
+syphilis/M
+syphilitic/SM
+syringe/DSMG
+syrup/SM
+syrupy
+sysadmin/MS
+sysop/SM
+system/SM
+systematic/U
+systematical/Y
+systematization/M
+systematize/GDS
+systemic/MS
+systemically
+systole/SM
+systolic
+sance/SM
+t/SDNXGBJ
+tRNA/M
+ta
+tab/SM
+tabbed
+tabbing
+tabbouleh/M
+tabby/SM
+tabernacle/SM
+tabla/MS
+table/MGDS
+tableau/M
+tableaux
+tablecloth/M
+tablecloths
+tableland/SM
+tablespoon/SM
+tablespoonful/SM
+tablet/SM
+tabletop/MS
+tableware/M
+tabloid/SM
+taboo/MDSG
+tabor/MS
+tabular
+tabulate/DSGNX
+tabulation/M
+tabulator/SM
+tachograph
+tachographs
+tachometer/SM
+tachycardia/M
+tachyon
+tacit/PY
+tacitness/M
+taciturn/Y
+taciturnity/M
+tack/ZGMDRS
+tacker/M
+tackiness/M
+tackle/DRSMZG
+tackler/M
+tacky/RTP
+taco/MS
+tact/FM
+tactful/YP
+tactfulness/M
+tactic/SM
+tactical/Y
+tactician/MS
+tactile
+tactility/M
+tactless/PY
+tactlessness/M
+tad/SM
+tadpole/MS
+taffeta/M
+taffrail/SM
+taffy/SM
+tag/SM
+tagged
+tagger/SM
+tagging
+tagliatelle
+tagline/MS
+taiga/MS
+tail/ACSDMG
+tailback/MS
+tailboard/S
+tailbone/S
+tailcoat/MS
+tailgate/MZGDRS
+tailgater/M
+tailless
+taillight/MS
+tailor/SGMD
+tailoring/M
+tailpiece/S
+tailpipe/SM
+tailspin/SM
+tailwind/SM
+taint/MDSG
+tainted/U
+take/AIMS
+takeaway/S
+taken/A
+takeoff/MS
+takeout/MS
+takeover/SM
+taker/MS
+taking/SM
+takings/M
+talc/M
+talcum/M
+tale/MS
+talebearer/MS
+talent/SMD
+talented/U
+tali
+talisman/MS
+talk/ZGMDRS
+talkative/PY
+talkativeness/M
+talker/M
+talkie/RSMT
+talky
+tall/TRP
+tallboy/MS
+tallier/M
+tallish
+tallness/M
+tallow/M
+tallowy
+tally/DRSMZG
+tallyho/MDGS
+talon/MS
+talus/MS
+tam/SM
+tamale/SM
+tamarack/MS
+tamarind/MS
+tambourine/MS
+tame/BYZTGDRSP
+tameable
+tamed/U
+tameness/M
+tamer/M
+tamoxifen
+tamp/ZGDRS
+tamper/ZGDR
+tamperer/M
+tampon/SM
+tan/SM
+tanager/MS
+tanbark/M
+tandem/SM
+tandoori/M
+tang/MS
+tangelo/MS
+tangent/MS
+tangential/Y
+tangerine/MS
+tangibility/IM
+tangible/IMS
+tangibleness/M
+tangibly/I
+tangle's
+tangle/UDSG
+tango/MDSG
+tangy/RT
+tank/ZGMDRS
+tankard/MS
+tanker/M
+tankful/MS
+tanned/U
+tanner/SM
+tannery/SM
+tannest
+tannin/M
+tanning/M
+tansy/M
+tantalization/M
+tantalize/ZGDRS
+tantalizer/M
+tantalizing/Y
+tantalum/M
+tantamount
+tantra/M
+tantrum/SM
+tap/SZGMDR
+tapas
+tape/MS
+tapeline/MS
+taper/MDG
+tapestry/SM
+tapeworm/MS
+tapioca/M
+tapir/MS
+tapped/U
+tapper/MS
+tappet/MS
+tapping
+taproom/SM
+taproot/SM
+tar/SGMD
+taramasalata
+tarantella/MS
+tarantula/SM
+tarball/S
+tardily
+tardiness/M
+tardy/TPR
+tare/MS
+target/MDGS
+tariff/MS
+tarmac/MS
+tarmacadam
+tarmacked
+tarmacking
+tarn/MS
+tarnish/GMDS
+tarnished/U
+taro/MS
+tarot/MS
+tarp/MS
+tarpaulin/MS
+tarpon/MS
+tarragon/SM
+tarred
+tarring
+tarry/TGDRS
+tarsal/MS
+tarsi
+tarsus/M
+tart/PTGMDRYS
+tartan/MS
+tartar/MS
+tartaric
+tartness/M
+tarty/T
+taser/GMDS
+task/GMDS
+taskbar
+taskmaster/MS
+taskmistress/MS
+tassel/MDSG
+taste/JMZGDRS
+tasted/U
+tasteful/EPY
+tastefulness/EM
+tasteless/PY
+tastelessness/M
+taster/M
+tastily
+tastiness/M
+tasting/M
+tasty/TRP
+tat/SZR
+tatami/MS
+tater/M
+tatted
+tatter/MDSG
+tatterdemalion/MS
+tattie
+tatting/M
+tattle/MZGDRS
+tattler/M
+tattletale/MS
+tattoo/MDRSZG
+tattooer/M
+tattooist/SM
+tatty/TRS
+tau/SM
+taught/UA
+taunt/ZGMDRS
+taunter/M
+taunting/Y
+taupe/M
+taut/PXTNRY
+tauten/DG
+tautness/M
+tautological/Y
+tautologous
+tautology/SM
+tavern/MS
+tawdrily
+tawdriness/M
+tawdry/RTP
+tawny/TRM
+tax/BZGMDRS
+taxa
+taxation/M
+taxer/M
+taxi/GMDS
+taxicab/SM
+taxidermist/SM
+taxidermy/M
+taximeter/MS
+taxiway/S
+taxman
+taxmen
+taxon
+taxonomic
+taxonomical
+taxonomist/MS
+taxonomy/SM
+taxpayer/MS
+taxpaying
+tb/S
+tbsp
+tea/SM
+teabag/S
+teacake/SM
+teach/ZGRSBJ
+teachable/U
+teacher/M
+teaching/M
+teacup/MS
+teacupful/MS
+teak/MS
+teakettle/SM
+teal/MS
+tealight/MS
+team/GMDS
+teammate/MS
+teamster/MS
+teamwork/M
+teapot/MS
+tear/GMDS
+tearaway/S
+teardrop/SM
+tearful/Y
+teargas/MS
+teargassed
+teargassing
+tearjerker/MS
+tearoom/SM
+teary/TR
+tease/MZGDRS
+teasel/MS
+teaser/M
+teasing/Y
+teaspoon/SM
+teaspoonful/SM
+teat/MS
+teatime/S
+tebibyte/MS
+tech/M
+techie/S
+technetium/M
+technical/Y
+technicality/SM
+technician/SM
+technicolor
+technique/SM
+techno
+technobabble
+technocracy/SM
+technocrat/MS
+technocratic
+technological/Y
+technologist/MS
+technology/SM
+technophobe/S
+techs
+tectonic/S
+tectonics/M
+ted/S
+teddy/S
+tedious/PY
+tediousness/M
+tedium/M
+tee/DSMH
+teeing
+teem/GDS
+teen/MS
+teenage/RZ
+teenager/M
+teeny/TR
+teenybopper/MS
+teepee/MS
+teeter/MDSG
+teethe/GDS
+teething/M
+teetotal/RZ
+teetotaler/M
+teetotalism/M
+tektite/SM
+tel
+telecast/SZGMR
+telecaster/M
+telecom/M
+telecommunication/MS
+telecommunications/M
+telecommute/ZGDRS
+telecommuter/M
+telecommuting/M
+teleconference/MGDS
+teleconferencing/M
+telegenic
+telegram/MS
+telegraph/MDRZG
+telegrapher/M
+telegraphese
+telegraphic
+telegraphically
+telegraphist/SM
+telegraphs
+telegraphy/M
+telekinesis/M
+telekinetic
+telemarketer/SM
+telemarketing/M
+telemeter/SM
+telemetry/SM
+teleological
+teleology
+telepathic
+telepathically
+telepathy/M
+telephone/DRSMZG
+telephoner/M
+telephonic
+telephonist/S
+telephony/M
+telephoto/SM
+telephotography/M
+teleplay/MS
+teleport/DSG
+teleportation
+teleprinter/MS
+teleprocessing/M
+teleprompter/SM
+telesales
+telescope/DSMG
+telescopic
+telescopically
+teletext/MS
+telethon/MS
+teletype/S
+teletypewriter/MS
+televangelism/M
+televangelist/MS
+televise/XGNDS
+television/M
+teleworker/S
+teleworking
+telex/MDSG
+tell/AGS
+teller/SM
+telling/Y
+telltale/SM
+tellurium/M
+telly/SM
+telnet
+temblor/MS
+temerity/M
+temp/MDRZTGS
+temper/MDG
+tempera/LSM
+temperament/MS
+temperamental/Y
+temperance/IM
+temperate/IY
+temperateness/M
+temperature/SM
+tempest/SM
+tempestuous/YP
+tempestuousness/M
+tempi
+template's
+template/S
+temple/SM
+tempo/SM
+temporal/Y
+temporarily
+temporariness/M
+temporary/FSM
+temporize/ZGDRS
+temporizer/M
+tempt/SDRZG
+temptation/MS
+tempter/M
+tempting/Y
+temptress/MS
+tempura/M
+ten/BMH
+tenability/M
+tenable/U
+tenably
+tenacious/YP
+tenaciousness/M
+tenacity/M
+tenancy/SM
+tenant/SMDG
+tenanted/U
+tenantry/M
+tench
+tend/IFEDGS
+tended/U
+tendency/SM
+tendentious/YP
+tendentiousness/M
+tender/SMDRYTGP
+tenderfoot/MS
+tenderhearted/P
+tenderheartedness/M
+tenderize/ZGDRS
+tenderizer/M
+tenderloin/SM
+tenderness/M
+tendinitis/M
+tendon/SM
+tendonitis/M
+tendril/SM
+tenement/SM
+tenet/SM
+tenfold
+tenner/S
+tennis/M
+tenon/SMDG
+tenor/SM
+tenpin/SM
+tenpins/M
+tense/DRSMYTGNXP
+tenseness/M
+tensile
+tension/ESM
+tensity/IM
+tensor/S
+tent/DGSM
+tentacle/DSM
+tentative/PY
+tentativeness/M
+tenterhook/MS
+tenth/MY
+tenths
+tenuity/M
+tenuous/PY
+tenuousness/M
+tenure/DSMG
+tepee/SM
+tepid/YP
+tepidity/M
+tepidness/M
+tequila/SM
+terabit/SM
+terabyte/MS
+terahertz/M
+terajoule/S
+terapixel/MS
+terawatt/S
+terbium/M
+tercentenary/SM
+tercentennial/SM
+teriyaki
+term/MDYGS
+termagant/MS
+terminable/IC
+terminal/MYS
+terminate/DSGNX
+termination/CSM
+terminator/S
+termini
+terminological/Y
+terminology/SM
+terminus/M
+termite/SM
+tern/IMS
+ternary/SM
+terr
+terrace/DSMG
+terracotta/M
+terraforming/M
+terrain/SM
+terrapin/MS
+terrarium/SM
+terrazzo/MS
+terrestrial/SMY
+terrible/P
+terribleness/M
+terribly
+terrier/M
+terrific
+terrifically
+terrify/GDS
+terrifying/Y
+terrine/S
+territorial/MS
+territoriality
+territory/SM
+terror/SM
+terrorism/M
+terrorist/SM
+terrorize/DSG
+terry/RMZ
+terrycloth/M
+terse/RYTP
+terseness/M
+tertiary
+tessellate/DSXGN
+tessellation/M
+test's/AFK
+test/AKFCDGS
+testable/CF
+testament/MS
+testamentary
+testate/S
+testator/MS
+testatrices
+testatrix/M
+testcase/MS
+tested/U
+tester/KSM
+testes
+testicle/MS
+testicular
+testifier/M
+testify/ZGDRS
+testily
+testimonial/MS
+testimony/SM
+testiness/M
+testings
+testis/M
+testosterone/M
+testsuite/SM
+testy/PRT
+tetanus/M
+tetchily
+tetchy/PRT
+tether/SMDG
+tetra/SM
+tetracycline/M
+tetrahedral
+tetrahedron/MS
+tetrameter/SM
+text/FMS
+textbook/SM
+textbox/MS
+texted
+textile/MS
+texting
+textual/FY
+textural
+texture/MGDS
+thalami
+thalamus/M
+thaliana
+thalidomide/M
+thallium/M
+than
+thane/SM
+thank/SDG
+thankful/YP
+thankfulness/M
+thankless/PY
+thanklessness/M
+thanksgiving/SM
+that'd
+that'll
+that/M
+thatch/MDRSZG
+thatcher/M
+thatching/M
+thaw/MDGS
+the/JG
+theater/SM
+theatergoer/SM
+theatrical/YS
+theatricality/M
+theatricals/M
+theatrics/M
+thee/S
+theft/SM
+their/S
+theism/M
+theist/SM
+theistic
+them
+thematic
+thematically
+theme/DSMG
+themself
+themselves
+then/M
+thence
+thenceforth
+thenceforward
+theocracy/SM
+theocratic
+theodolite/S
+theologian/SM
+theological/Y
+theology/SM
+theorem/MS
+theoretic
+theoretical/Y
+theoretician/SM
+theorist/SM
+theorize/DSG
+theory/SM
+theosophic
+theosophical
+theosophist/SM
+theosophy/M
+therapeutic/S
+therapeutically
+therapeutics/M
+therapist/SM
+therapy/SM
+there/M
+thereabout/S
+thereafter
+thereat
+therebetween
+thereby
+therefor
+therefore
+therefrom
+therein
+theremin/SM
+thereof
+thereon
+thereto
+theretofore
+thereunder
+thereunto
+thereupon
+therewith
+therm/SM
+thermal/MYS
+thermionic
+thermobaric
+thermodynamic/S
+thermodynamics/M
+thermometer/MS
+thermometric
+thermonuclear
+thermoplastic/SM
+thermos/MS
+thermostat/MS
+thermostatic
+thermostatically
+thesauri
+thesaurus/MS
+these/S
+thesis/M
+thespian/SM
+theta/SM
+thew/MS
+they
+they'd
+they'll
+they're
+they've
+thiamine/M
+thick/PMNRYXT
+thicken/DRJZG
+thickener/M
+thickening/M
+thicket/MS
+thickheaded/M
+thickness/MS
+thicko/S
+thickset
+thief/M
+thieve/DSG
+thievery/M
+thieving/M
+thievish
+thigh/M
+thighbone/MS
+thighs
+thimble/MS
+thimbleful/SM
+thin/YSP
+thine
+thing/M
+thingamabob/SM
+thingamajig/SM
+thingumabob/S
+thingummy/S
+thingy/S
+think/SRBZG
+thinkable/U
+thinker/M
+thinking's
+thinned
+thinner/MS
+thinness/M
+thinnest
+thinning
+third/SMY
+thirst/SGMD
+thirstily
+thirstiness/M
+thirsty/TPR
+thirteen/SMH
+thirteenth/M
+thirteenths
+thirtieth/M
+thirtieths
+thirty/HSM
+this
+thistle/MS
+thistledown/M
+thither
+tho
+thole/SM
+thong/SM
+thoracic
+thoracotomy
+thorax/MS
+thorium/M
+thorn/SM
+thorniness/M
+thorny/PRT
+thorough/RYPT
+thoroughbred/MS
+thoroughfare/MS
+thoroughgoing
+thoroughness/M
+those
+thou/MS
+though
+thought/SM
+thoughtful/YP
+thoughtfulness/M
+thoughtless/PY
+thoughtlessness/M
+thousand/MHS
+thousandfold
+thousandth/M
+thousandths
+thraldom/M
+thrall/SMDG
+thralldom/M
+thrash/JMDRSZG
+thrasher/M
+thrashing/M
+thread/SMDRZG
+threadbare
+threader/M
+threadlike
+thready/TR
+threat/SMNX
+threaten/DG
+threatening/Y
+three/SM
+threefold
+threepence/M
+threescore/MS
+threesome/SM
+threnody/SM
+thresh/MDRSZG
+thresher/M
+threshold/SM
+threw
+thrice
+thrift/SM
+thriftily
+thriftiness/M
+thriftless
+thrifty/PTR
+thrill/SMDRZG
+thriller/M
+thrilling/Y
+thrive/DSG
+throat/SM
+throatily
+throatiness/M
+throaty/RTP
+throb/SM
+throbbed
+throbber
+throbbing
+throe/SM
+thrombi
+thrombolytic
+thromboses
+thrombosis/M
+thrombotic
+thrombus/M
+throne's
+throne/S
+throng/GSMD
+throttle/DRSMZG
+throttler/M
+through
+throughout
+throughput/M
+throughway/MS
+throw/SMRZG
+throwaway/SM
+throwback/SM
+thrower/M
+thrown
+thru
+thrum/SM
+thrummed
+thrumming
+thrush/MS
+thrust/ZGSMR
+thruway/MS
+thud/MS
+thudded
+thudding
+thug/MS
+thuggery/M
+thuggish
+thulium/M
+thumb/SMDG
+thumbnail/SM
+thumbprint/SM
+thumbscrew/SM
+thumbtack/SM
+thump/SMDG
+thumping/M
+thunder/ZGMDRS
+thunderbolt/SM
+thunderclap/SM
+thundercloud/MS
+thunderer/M
+thunderhead/SM
+thunderous/Y
+thundershower/SM
+thunderstorm/SM
+thunderstruck
+thundery
+thunk/S
+thus/Y
+thwack/ZGSMDR
+thwacker/M
+thwart/GSMD
+thy
+thyme/M
+thymine/M
+thymus/MS
+thyroid/MS
+thyroidal
+thyself
+ti/MRZ
+tiara/SM
+tibia/M
+tibiae
+tibial
+tic/SM
+tick/MDRZGS
+ticker/M
+ticket/GSMD
+ticking/M
+tickle/DRSMZG
+tickler/M
+ticklish/YP
+ticklishness/M
+ticktacktoe/M
+ticktock/MS
+tidal/Y
+tidbit/SM
+tiddler/S
+tiddly
+tiddlywink/S
+tiddlywinks/M
+tide/MGJDS
+tideland/SM
+tidemark/S
+tidewater/MS
+tideway/MS
+tidily/U
+tidiness/UM
+tidings/M
+tidy/DRSMTGP
+tie's
+tie/AUSD
+tieback/MS
+tiebreak/RSZ
+tiebreaker/M
+tiepin/S
+tier/MD
+tiff/MDGS
+tiger/SM
+tigerish
+tight/SNRYPXT
+tighten/ZGDR
+tightener/M
+tightfisted
+tightness/M
+tightrope/MS
+tights/M
+tightwad/MS
+tigress/MS
+til
+tilapia
+tilde/SM
+tile/MZGDRS
+tiler/M
+tiling/M
+till's
+till/EDRZGS
+tillable
+tillage/M
+tiller/EM
+tilt/MDGS
+timber/SMDG
+timberland/M
+timberline/MS
+timbre/SM
+timbrel/SM
+time/MYZGJDRS
+timekeeper/MS
+timekeeping/M
+timeless/PY
+timelessness/M
+timeline/MS
+timeliness/UM
+timely/UPRT
+timeout/SM
+timepiece/MS
+timer/M
+timescale/S
+timeserver/SM
+timeserving/M
+timeshare/S
+timestamp/SMD
+timetable/DSMG
+timeworn
+timezone
+timid/RYTP
+timidity/M
+timidness/M
+timing/M
+timorous/PY
+timorousness/M
+timothy/M
+timpani/M
+timpanist/SM
+tin/SM
+tincture/MGDS
+tinder/M
+tinderbox/MS
+tine/MS
+tinfoil/M
+ting/MDYG
+tinge/SM
+tingeing
+tingle/DSMGJ
+tingling/M
+tininess/M
+tinker/ZGSMDR
+tinkerer/M
+tinkle/DSMG
+tinned
+tinniness/M
+tinning
+tinnitus/M
+tinny/PRT
+tinplate/M
+tinpot
+tinsel/GSMD
+tinsmith/M
+tinsmiths
+tint/MDGS
+tintinnabulation/MS
+tintype/MS
+tinware/M
+tiny/RTP
+tip/SM
+tipped
+tipper/SM
+tippet/SM
+tippex/GDS
+tipping
+tipple/DRSMZG
+tippler/M
+tipsily
+tipsiness/M
+tipster/MS
+tipsy/RPT
+tiptoe/DSM
+tiptoeing
+tiptop/SM
+tirade/SM
+tiramisu/MS
+tire's
+tire/AGDS
+tired/PRYT
+tiredness/M
+tireless/YP
+tirelessness/M
+tiresome/PY
+tiresomeness/M
+tissue/SM
+tit/SM
+titan/SM
+titanic
+titanium/M
+titch/S
+titchy
+tithe/DRSMZG
+tither/M
+titian/M
+titillate/DSGN
+titillating/Y
+titillation/M
+titivate/DSGN
+titivation/M
+title/DSMG
+titled/U
+titleholder/MS
+titlist/MS
+titmice
+titmouse/M
+titter/SGMD
+tittivate/DSGN
+tittivation/M
+tittle/SM
+titty/S
+titular
+tizz
+tizzy/SM
+tn
+tnpk
+to/IU
+toad/MS
+toadstool/MS
+toady/DSMG
+toadyism/M
+toast/SMDRZG
+toaster/M
+toastmaster/SM
+toastmistress/MS
+toasty/TRS
+tobacco/MS
+tobacconist/SM
+toboggan/ZGSMDR
+tobogganer/M
+tobogganing/M
+toccata/S
+tocopherol
+tocsin/SM
+today/M
+toddle/DRSMZG
+toddler/M
+toddy/SM
+toe/DSM
+toecap/SM
+toehold/MS
+toeing
+toenail/MS
+toerag/S
+toff/S
+toffee/SM
+tofu/M
+tog/SM
+toga/MDS
+together/P
+togetherness/M
+togged
+togging
+toggle/DSMG
+togs/M
+toil/MDRZGS
+toiler/M
+toilet/MDGS
+toiletry/SM
+toilette/M
+toilsome
+toke/MGDS
+token/SM
+tokenism/M
+told/AU
+tole/M
+tolerable/I
+tolerably/I
+tolerance/IM
+tolerances
+tolerant/IY
+tolerate/GNDS
+toleration/M
+toll/MDGS
+tollbooth/M
+tollbooths
+tollgate/SM
+tollway/SM
+toluene/M
+tom/SM
+tomahawk/SGMD
+tomato/M
+tomatoes
+tomb/MDGS
+tombola/S
+tomboy/MS
+tomboyish
+tombstone/MS
+tomcat/MS
+tome/MS
+tomfoolery/SM
+tomographic
+tomography/M
+tomorrow/MS
+tomtit/MS
+ton/SM
+tonal/Y
+tonality/SM
+tone's
+tone/IZGDRS
+tonearm/SM
+toneless/Y
+toner/IM
+tong/MDGS
+tongue/MGDS
+tongueless
+tonic/SM
+tonight/M
+tonnage/SM
+tonne/SM
+tonsil/MS
+tonsillectomy/SM
+tonsillitis/M
+tonsorial
+tonsure/DSMG
+tony/RT
+too
+toodles
+took/A
+tool's
+tool/ADGS
+toolbar/SM
+toolbox/MS
+toolkit
+toolmaker/MS
+toot/MDRZGS
+tooter/M
+tooth/MD
+toothache/MS
+toothbrush/MS
+toothily
+toothless
+toothpaste/SM
+toothpick/SM
+toothsome
+toothy/RT
+tootle/GDS
+tootsie/S
+top/SM
+topaz/MS
+topcoat/SM
+topdressing/SM
+topee/S
+topflight
+topi/S
+topiary/M
+topic/SM
+topical/Y
+topicality/M
+topknot/SM
+topless
+topmast/SM
+topmost
+topnotch
+topographer/SM
+topographic
+topographical/Y
+topography/SM
+topological/Y
+topology
+topped
+topper/MS
+topping/SM
+topple/GDS
+topsail/SM
+topside/SM
+topsoil/M
+topspin/M
+toque/SM
+tor/SM
+torah/M
+torahs
+torch/GMDS
+torchbearer/MS
+torchlight/M
+tore
+toreador/MS
+torment/SMDG
+tormenting/Y
+tormentor/MS
+torn
+tornado/M
+tornadoes
+torpedo/GMD
+torpedoes
+torpid/Y
+torpidity/M
+torpor/M
+torque/MGDS
+torrent/SM
+torrential
+torrid/YP
+torridity/M
+torridness/M
+torsion/M
+torsional
+torso/SM
+tort's
+tort/EFAS
+torte/SM
+tortellini/M
+tortilla/MS
+tortoise/MS
+tortoiseshell/SM
+tortoni/M
+tortuous/PY
+tortuousness/M
+torture/DRSMZG
+torturer/M
+torturous
+torus
+tosh
+toss/MDRSZG
+tossup/MS
+tot/SGMD
+total/GSMDY
+totalitarian/SM
+totalitarianism/M
+totality/SM
+totalizator/SM
+tote/MS
+totem/SM
+totemic
+totted
+totter/ZGMDRS
+totterer/M
+totting
+toucan/MS
+touch/AGMDS
+touchdown/SM
+touche/BJ
+touched/U
+touchily
+touchiness/M
+touching/Y
+touchline/S
+touchpaper/S
+touchscreen/MS
+touchstone/MS
+touchy/RPT
+touch
+tough/XTGMDNRYP
+toughen/ZGDR
+toughener/M
+toughie/SM
+toughness/M
+toughs
+toupee/MS
+tour/CFSGDM
+tourism/M
+tourist/MS
+touristic
+touristy
+tourmaline/M
+tournament/SM
+tourney/MS
+tourniquet/MS
+tousle/GDS
+tout/MDGS
+tow/SZGMDR
+toward/S
+towboat/MS
+towel/JGSMD
+towelette/SM
+toweling/M
+tower/GMD
+towhead/MDS
+towhee/MS
+towline/MS
+town/MS
+townee/S
+townhouse/MS
+townie/MS
+townsfolk/M
+township/MS
+townsman/M
+townsmen
+townspeople/M
+townswoman/M
+townswomen
+towpath/M
+towpaths
+towrope/SM
+toxemia/M
+toxic
+toxicity/SM
+toxicological
+toxicologist/SM
+toxicology/M
+toxin/SM
+toy/SGMD
+toyboy/S
+tr
+trabecula
+trabecular
+trabecule
+trace/JDRSMZG
+traceability
+traceable/U
+tracer/M
+tracery/SM
+traceur/SM
+trachea/M
+tracheae
+tracheal
+tracheotomy/SM
+tracing/M
+track/ZGSMDR
+trackback/SM
+trackball/SM
+tracker/M
+trackless
+tracksuit/S
+tract's
+tract/CKFEAS
+tractability/IM
+tractable/I
+tractably/I
+traction/FEACKM
+tractor/FCKMS
+trad
+trade/BJDRSMZG
+trademark/SGMD
+tradeoff/S
+trader/M
+tradesman/M
+tradesmen
+tradespeople/M
+tradeswoman/M
+tradeswomen
+trading/M
+tradition/MS
+traditional/Y
+traditionalism/M
+traditionalist/SM
+traduce/DRSZG
+traducer/M
+traffic/SM
+trafficked
+trafficker/SM
+trafficking/M
+tragedian/SM
+tragedienne/MS
+tragedy/SM
+tragic
+tragically
+tragicomedy/SM
+tragicomic
+trail/ZGSMDR
+trailblazer/MS
+trailblazing/M
+trailer/M
+trailhead/S
+train/ZGSMDRBJ
+trained/U
+trainee/SM
+trainer/M
+training/M
+trainload/MS
+trainman/M
+trainmen
+trainspotter/S
+trainspotting
+traipse/DSMG
+trait/SM
+traitor/SM
+traitorous/Y
+trajectory/SM
+tram/MS
+tramcar/S
+tramlines
+trammed
+trammel/SGMD
+trammeled/U
+tramming
+tramp/ZGSMDR
+tramper/M
+trample/DRSMZG
+trampler/M
+trampoline/MGDS
+tramway/S
+trance/MS
+tranche/S
+tranquil/RYT
+tranquility/M
+tranquilize/ZGDRS
+tranquilizer/M
+tranquillity/M
+trans/I
+transact/DGS
+transaction/SM
+transactional
+transactor/MS
+transatlantic
+transceiver/SM
+transcend/GSD
+transcendence/M
+transcendent
+transcendental/Y
+transcendentalism/M
+transcendentalist/SM
+transcontinental
+transcreation/M
+transcribe/ZGDRS
+transcriber/M
+transcript/MS
+transcription/SM
+transcriptional
+transducer/MS
+transduction
+transect/DSG
+transept/MS
+transfect/SGD
+transfeminine
+transfer/MBS
+transferal/MS
+transference/M
+transferred
+transferring
+transfiguration/M
+transfigure/GDS
+transfinite
+transfix/DSG
+transform/BSZGMDR
+transformation/SM
+transformational
+transformative
+transformer/M
+transfuse/DSXGN
+transfusion/M
+transgender/SD
+transgenderism
+transgene/S
+transgenic
+transgress/GVDS
+transgression/SM
+transgressor/SM
+transience/M
+transiency/M
+transient/SMY
+transistor/SM
+transistorize/DSG
+transit/SGMD
+transition/GSMD
+transitional/Y
+transitive/ISMY
+transitiveness/M
+transitivity/M
+transitory
+transl
+translatable/U
+translate/DSGNBX
+translated/U
+translation/M
+translator/SM
+transliterate/DSGNX
+transliteration/M
+translocation
+translucence/M
+translucency/M
+translucent/Y
+transmasculine
+transmigrate/GNDS
+transmigration/M
+transmissible
+transmission/AMS
+transmit/S
+transmittable
+transmittal/M
+transmittance/M
+transmitted
+transmitter/SM
+transmitting
+transmogrification/M
+transmogrify/DSNG
+transmutation/SM
+transmute/BDSG
+transnational/MS
+transoceanic
+transom/SM
+transpacific
+transparency/SM
+transparent/Y
+transphobia/M
+transphobic
+transpiration/M
+transpire/DSG
+transplant/MDGS
+transplantation/M
+transpolar
+transponder/SM
+transport/BSZGMDR
+transportation/M
+transporter/M
+transpose/DSG
+transposition/MS
+transsexual/SM
+transsexualism/M
+transship/SL
+transshipment/M
+transshipped
+transshipping
+transubstantiation/M
+transversal
+transverse/MYS
+transvestism/M
+transvestite/MS
+trap/MS
+trapdoor/MS
+trapeze/SM
+trapezium/SM
+trapezoid/SM
+trapezoidal
+trappable
+trapped
+trapper/SM
+trapping/S
+trappings/M
+trapshooting/M
+trash/GMDS
+trashcan/MS
+trashiness/M
+trashy/RPT
+trauma/MS
+traumatic
+traumatically
+traumatize/GDS
+travail/SGMD
+travel/MDRSZGJ
+traveled/U
+traveler/M
+traveling/M
+travelog/SM
+travelogue/MS
+traversal/SM
+traverse/DSMG
+travesty/GDSM
+trawl/ZGSMDR
+trawler/M
+tray/MS
+treacherous/PY
+treacherousness/M
+treachery/SM
+treacle/M
+treacly
+tread/AGSM
+treadle/DSMG
+treadmill/MS
+treas
+treason/BM
+treasonous
+treasure/DRSMZG
+treasurer/M
+treasury/SM
+treat/AGSMD
+treatable
+treated/U
+treatise/SM
+treatment/MS
+treaty/SM
+treble/MGDS
+trebuchet/S
+tree/MDS
+treeing
+treeless
+treelike
+treeline
+treetop/SM
+trefoil/SM
+trek/MS
+trekked
+trekker/SM
+trekking
+trellis/GMDS
+trematode/MS
+tremble/DSMG
+tremendous/Y
+tremolo/SM
+tremor/MS
+tremulous/PY
+tremulousness/M
+trench's
+trench/ADSG
+trenchancy/M
+trenchant/Y
+trencher/MS
+trencherman/M
+trenchermen
+trend/GSMD
+trendily
+trendiness/M
+trendsetter/S
+trendsetting
+trendy/RSMPT
+trepidation/M
+trespass/MDRSZG
+trespasser/M
+tress/EMS
+trestle/MS
+trews
+trey/MS
+triad/SM
+triage/MGDS
+trial/ASM
+trialed
+trialing
+triangle/SM
+triangular/Y
+triangulate/GNDS
+triangulation/M
+triathlete/S
+triathlon/SM
+tribal
+tribalism/M
+tribe/SM
+tribesman/M
+tribesmen
+tribeswoman/M
+tribeswomen
+tribulation/SM
+tribunal/SM
+tribune/MS
+tributary/SM
+tribute's
+tribute/FS
+trice/M
+tricentennial/MS
+triceps/MS
+triceratops/M
+trichina/M
+trichinae
+trichinosis/M
+trichotomy/S
+trick/GSMD
+trickery/M
+trickily
+trickiness/M
+trickle/MGDS
+trickster/SM
+tricky/TRP
+tricolor/SM
+tricorn/MS
+tricycle/SM
+trident/MS
+tried/U
+triennial/MYS
+trier/SM
+trifecta/SM
+trifle/MZGDRS
+trifler/M
+trifocals/M
+trig/M
+trigger/MDSG
+triglyceride/MS
+trigonometric
+trigonometrical
+trigonometry/M
+trike/SM
+trilateral/S
+trilby/SM
+trill/GSMD
+trillion/SMH
+trillionth/M
+trillionths
+trillium/M
+trilobite/SM
+trilogy/SM
+trim/PMYS
+trimaran/MS
+trimester/SM
+trimmed/U
+trimmer/SM
+trimmest
+trimming/SM
+trimmings/M
+trimness/M
+trimonthly
+trinitrotoluene/M
+trinity/SM
+trinket/SM
+trio/MS
+trip/MYS
+tripartite
+tripe/M
+triplane/SM
+triple/MGDS
+triplet/SM
+triplex/MS
+triplicate/MGDS
+tripod/MS
+tripodal
+tripos
+tripped
+tripper/SM
+tripping
+triptych/M
+triptychs
+tripwire/S
+trireme/SM
+trisect/SDG
+trisection/M
+trite/FPYT
+triteness/FM
+triter
+tritium/M
+triumph/GMD
+triumphal
+triumphalism
+triumphalist
+triumphant/Y
+triumphs
+triumvir/MS
+triumvirate/SM
+trivalent
+trivet/MS
+trivia/M
+trivial/Y
+triviality/SM
+trivialization/M
+trivialize/GDS
+trivium/M
+trochaic
+trochee/SM
+trod/AU
+trodden/A
+troglodyte/SM
+troika/MS
+troll/SGMD
+trolley/SM
+trolleybus/MS
+trollop/SM
+trombone/MS
+trombonist/MS
+tromp/SGD
+tron/S
+troop/SZGMDR
+trooper/M
+troopship/MS
+trope/SM
+trophy/SM
+tropic/MS
+tropical/Y
+tropics/M
+tropism/SM
+troposphere/SM
+trot/MS
+troth/M
+trotted
+trotter/SM
+trotting
+troubadour/MS
+trouble/DSMG
+troubled/U
+troublemaker/MS
+troubleshoot/DRZGS
+troubleshooter/M
+troubleshooting/M
+troubleshot
+troublesome/Y
+trough/M
+troughs
+trounce/DRSZG
+trouncer/M
+troupe/MZGDRS
+trouper/M
+trouser/SM
+trousers/M
+trousseau/M
+trousseaux
+trout/SM
+trove/SM
+trow/DSG
+trowel/MDSG
+troy/S
+truancy/M
+truant/GMDS
+truce/SM
+truck/SZGMDR
+trucker/M
+trucking/M
+truckle/MGDS
+truckload/SM
+truculence/M
+truculent/Y
+trudge/MGDS
+true/MTGDRS
+truelove/SM
+truffle/MS
+trug/S
+truism/MS
+truly/U
+trump/SGMD
+trumpery/M
+trumpet/ZGMDRS
+trumpeter/M
+truncate/GNDS
+truncation/M
+truncheon/SM
+trundle/MZGDRS
+trundler/M
+trunk/SGM
+truss/GMDS
+trust/ESGMD
+trustee/MS
+trusteeship/SM
+trustful/EY
+trustfulness/M
+trusting/Y
+trustworthiness/M
+trustworthy/TPR
+trusty/TRSM
+truth/ZMR
+truther/M
+truthful/UYP
+truthfulness/UM
+truthiness
+truths/U
+try's
+try/AGDS
+trying/Y
+tryout/SM
+tryptophan
+tryst/SMDG
+tsarists
+tsetse/MS
+tsp
+tsunami/SM
+ttys
+tub/SZGMDR
+tuba/MS
+tubal
+tubby/TR
+tube/MS
+tubeless/M
+tuber/M
+tubercle/SM
+tubercular
+tuberculin/M
+tuberculosis/M
+tuberculous
+tuberose/M
+tuberous
+tubful/MS
+tubing/M
+tubular
+tubule/MS
+tuck/MDRSZG
+tucker/MDG
+tuft/MDRSZG
+tufter/M
+tug/SM
+tugboat/MS
+tugged
+tugging
+tuition/IM
+tularemia/M
+tulip/SM
+tulle/M
+tum/S
+tumble/DRSMZG
+tumbledown
+tumbler/M
+tumbleweed/SM
+tumbling/M
+tumbrel/SM
+tumbril/SM
+tumescence/M
+tumescent
+tumid
+tumidity/M
+tummy/SM
+tumor/SM
+tumorous
+tumult/SM
+tumultuous/Y
+tun/SZGMDRB
+tuna/MS
+tundra/SM
+tune/MS
+tuneful/YP
+tunefulness/M
+tuneless/Y
+tuner/M
+tuneup/SM
+tung
+tungsten/M
+tunic/SM
+tunnel/JSMDRZG
+tunneler/M
+tunny/SM
+tuple/S
+tuppence
+tuppenny
+tuque/SM
+turban/SMD
+turbid
+turbidity/M
+turbine/SM
+turbo/SM
+turbocharge/ZGDRS
+turbocharger/M
+turbofan/SM
+turbojet/SM
+turboprop/SM
+turbot/SM
+turbulence/M
+turbulent/Y
+turd/MS
+turducken/SM
+tureen/SM
+turf/MDSG
+turfy
+turgid/Y
+turgidity/M
+turkey/SM
+turmeric/SM
+turmoil/MS
+turn/AMDRSZG
+turnabout/SM
+turnaround/SM
+turnbuckle/SM
+turncoat/SM
+turner/AM
+turning/MS
+turnip/SM
+turnkey/MS
+turnoff/MS
+turnout/MS
+turnover/MS
+turnpike/MS
+turnstile/SM
+turntable/SM
+turpentine/M
+turpitude/M
+turps
+turquoise/SM
+turret/SMD
+turtle/SM
+turtleback/S
+turtledove/SM
+turtleneck/SMD
+tush/MS
+tusk/MDS
+tussle/DSMG
+tussock/MS
+tussocky
+tut/SM
+tutelage/M
+tutelary
+tutor/SMDG
+tutored/U
+tutorial/SM
+tutorship/M
+tutted
+tutti/SM
+tutting
+tutu/MS
+tux/MS
+tuxedo/SM
+twaddle/MZGDRS
+twaddler/M
+twain/M
+twang/SMDG
+twangy/RT
+twas
+twat/S
+tweak/SMDG
+twee
+tweed/SM
+tweedle/DSG
+tweeds/M
+tweedy/RT
+tween
+tweep/S
+tweet's
+tweet/ASDG
+tweeter/SM
+tweezers/M
+twelfth/M
+twelfths
+twelve/SM
+twelvemonth/M
+twelvemonths
+twentieth/M
+twentieths
+twenty/SMH
+twerk/SDG
+twerp/SM
+twice
+twiddle/MGDS
+twiddly
+twig/MS
+twigged
+twigging
+twiggy/TR
+twilight/M
+twilit
+twill/MD
+twin/MDRSZG
+twine/SM
+twiner/M
+twinge/DSMG
+twinight
+twink/SY
+twinkle/MGJDS
+twinkling/M
+twinned
+twinning
+twinset/S
+twirl/SMDRZG
+twirler/M
+twirly
+twist's
+twist/USDG
+twister/MS
+twisty/TR
+twit/MS
+twitch/GMDS
+twitchy/RT
+twitted
+twitter/MDSG
+twittery
+twitting
+twixt
+two/SM
+twofer/SM
+twofold
+twopence/SM
+twopenny
+twosome/SM
+twp
+tycoon/SM
+tying/AU
+tyke/MS
+tympani/M
+tympanic
+tympanist/MS
+tympanum/SM
+type's
+type/AGDS
+typecast/GS
+typeface/MS
+typescript/MS
+typeset/S
+typesetter/MS
+typesetting/M
+typewrite/RSZG
+typewriter/M
+typewriting/M
+typewritten
+typewrote
+typhoid/M
+typhoon/MS
+typhus/M
+typical/UY
+typicality/M
+typification/M
+typify/NGDS
+typing/M
+typist/SM
+typo/MS
+typographer/SM
+typographic
+typographical/Y
+typography/M
+typology/SM
+tyrannic
+tyrannical/Y
+tyrannicidal
+tyrannicide/S
+tyrannize/GDS
+tyrannosaur/MS
+tyrannosaurus/MS
+tyrannous
+tyranny/SM
+tyrant/SM
+tyro/MS
+tzatziki
+u/S
+ubiquitous/Y
+ubiquity/M
+udder/SM
+udon
+ufologist/SM
+ufology/M
+ugh
+ugliness/M
+ugly/RTP
+uh
+uhf
+ukase/SM
+ukulele/SM
+ulcer/SM
+ulcerate/XDSGNV
+ulceration/M
+ulcerous
+ulna/M
+ulnae
+ulnar
+ulster/MS
+ult
+ulterior
+ultimate/MY
+ultimatum/MS
+ultimo
+ultra/SM
+ultraconservative/SM
+ultrahigh
+ultralight/SM
+ultramarine/M
+ultramodern
+ultrasensitive
+ultrashort
+ultrasonic
+ultrasonically
+ultrasound/MS
+ultraviolet/M
+ululate/DSGNX
+ululation/M
+um
+umbel/SM
+umber/M
+umbilical
+umbilici
+umbilicus/M
+umbra/SM
+umbrage/M
+umbrella/SM
+umiak/SM
+umlaut/MS
+ump/SGMD
+umpire/MGDS
+umpteen/H
+unabridged/MS
+unacceptability
+unacceptable
+unaccommodating
+unaccountably
+unadventurous
+unaesthetic
+unalterably
+unambitious
+unanimity/M
+unanimous/Y
+unapparent
+unappetizing
+unappreciative
+unary
+unassertive
+unassimilable
+unassuming/Y
+unavailing/Y
+unaware/S
+unbeknown
+unbeknownst
+unbend/SG
+unbent
+unbid
+unblinking/Y
+unblushing/Y
+unbosom/DG
+unbound/D
+unbox/JGDS
+unbreakable
+unbroken
+uncanny/T
+uncap/S
+uncaring
+unceasing/Y
+unchangeable
+uncharacteristic
+uncharitable
+unchaste/RT
+uncial/M
+uncle/SM
+unclean/DRPT
+uncleanly/T
+unclear/DRT
+uncomfortable
+uncommon/T
+uncompelling
+uncomplaining/Y
+uncomplicated
+uncomprehending/Y
+uncompromising/Y
+unconditional/Y
+uncongenial
+unconscionable
+unconscionably
+unconscious/M
+unconstitutional/Y
+uncontrollably
+uncontroversial
+uncool
+uncooperative
+uncouth/Y
+uncrushable
+unction/SM
+unctuous/YP
+unctuousness/M
+uncut
+undaunted/Y
+undecided/SM
+undemonstrative/Y
+undeniably
+under
+underachieve/LZGDRS
+underachiever/M
+underact/SDG
+underage
+underappreciated
+underarm/SM
+underbelly/SM
+underbid/S
+underbidding
+underbrush/M
+undercarriage/MS
+undercharge/MGDS
+underclass/MS
+underclassman/M
+underclassmen
+underclothes/M
+underclothing/M
+undercoat/GJSMD
+undercoating/M
+undercover
+undercurrent/SM
+undercut/SM
+undercutting
+underdeveloped
+underdevelopment/M
+underdog/SM
+underdone
+underemployed
+underemployment/M
+underestimate/DSMGNX
+underestimation/M
+underexpose/GDS
+underexposure/MS
+underfed
+underfeed/GS
+underfloor
+underflow
+underfoot
+underfunded
+underfur/M
+undergarment/SM
+undergo/G
+undergoes
+undergone
+undergrad/S
+undergraduate/SM
+underground/MS
+undergrowth/M
+underhand
+underhanded/PY
+underhandedness/M
+underinclusive
+underinflated
+underlain
+underlay/ZSMR
+underlayer/M
+underlie/S
+underline/MGDS
+underling/MS
+underlip/SM
+underlying
+undermanned
+undermentioned
+undermine/GDS
+undermost
+underneath/M
+underneaths
+undernourished
+undernourishment/M
+underpaid
+underpants/M
+underpart/MS
+underpass/MS
+underpay/GSL
+underpayment/SM
+underpin/S
+underpinned
+underpinning/MS
+underplay/DGS
+underpopulated
+underprivileged
+underproduction/M
+underrate/GDS
+underrepresented
+underscore/DSMG
+undersea/S
+undersecretary/SM
+undersell/GS
+undersexed
+undershirt/SM
+undershoot/SG
+undershorts/M
+undershot
+underside/MS
+undersign/DGS
+undersigned/M
+undersized
+underskirt/SM
+undersold
+understaffed
+understand/SGBJ
+understandably
+understanding/MY
+understate/DSLG
+understatement/SM
+understood
+understudy/GDSM
+undertake/ZGJRS
+undertaken
+undertaker/M
+undertaking/M
+underthings/M
+undertone/MS
+undertook
+undertow/SM
+underused
+underutilized
+undervaluation/M
+undervalue/DSG
+underwater
+underway
+underwear/M
+underweight/M
+underwent
+underwhelm/DGS
+underwing/MS
+underwire/DS
+underworld/MS
+underwrite/ZGRS
+underwriter/M
+underwritten
+underwrote
+undesirable/MS
+undies/M
+undo
+undoubted/Y
+undramatic
+undreamt
+undue
+undulant
+undulate/DSXGN
+undulation/M
+undying
+unearthliness/M
+unease/M
+uneasy/T
+uneatable
+uneconomic
+unemployed/M
+unending
+unenterprising
+unequal/DY
+unerring/Y
+unessential
+uneven/Y
+unexceptionably
+unexcited
+unexciting
+unexpected/YP
+unexpectedness/M
+unexplainably
+unfailing/Y
+unfair/PTRY
+unfaltering
+unfamiliar
+unfathomably
+unfed
+unfeeling/Y
+unfeminine
+unfit/S
+unfitting
+unfix/GDS
+unflagging/Y
+unflappability/M
+unflappable
+unflappably
+unflattering
+unflinching/Y
+unforgettably
+unforgivably
+unfortunate/MS
+unfriendly/T
+unfrock/DG
+unfruitful
+unfunny
+ungainliness/M
+ungainly/RPT
+ungenerous
+ungentle
+ungodly/T
+ungraceful/Y
+ungrudging
+unguarded
+unguent/SM
+ungulate/MS
+unhandy/T
+unhappy/T
+unhealthful
+unhealthy/T
+unhistorical
+unholy/T
+unhurt
+unicameral
+unicellular
+unicorn/SM
+unicycle/SM
+unidirectional
+unification/AM
+uniform/SMDYG
+uniformity/M
+unify/AGDSN
+unilateral/Y
+unilateralism
+unimportant
+unimpressive
+uninformative
+uninhibited/Y
+uninsured
+unintelligent
+unintended
+uninteresting
+uninterrupted/Y
+uninviting
+union/ASM
+unionism/M
+unionist/MS
+unique/YTRP
+uniqueness/M
+unisex/M
+unison/M
+unitary
+unite/AEGSD
+unitedly
+unities
+unitize/DSG
+unity/EM
+univalent
+univalve/SM
+universal/MYS
+universalism
+universalist
+universality/M
+universalize/DSG
+universe/SM
+university/SM
+univocal
+unjust/Y
+unkempt
+unkind/T
+unkindly/T
+unknowable/M
+unknown/SM
+unleaded/M
+unless
+unlike/PB
+unlikely/T
+unlit
+unlock/DSG
+unlovable
+unlovely/TR
+unloving
+unlucky/T
+unman/S
+unmanly/T
+unmarried
+unmeaning
+unmentionable/MS
+unmentionables/M
+unmet
+unmindful
+unmissable
+unmistakably
+unmoral
+unmovable
+unmusical
+unnecessary
+unnerving/Y
+unobservant
+unoffensive
+unofficial/Y
+unoriginal
+unpeople
+unperceptive
+unpersuasive
+unpick/GDS
+unpin/S
+unpleasing
+unpolitical
+unpopular
+unpractical
+unprecedented/Y
+unprofessional/Y
+unpromising
+unpropitious
+unquestioning/Y
+unquiet/TR
+unread/B
+unready
+unreal
+unreasoning
+unregenerate
+unrelated
+unrelenting/Y
+unrelieved/Y
+unremarkable
+unremitting/Y
+unrepentant
+unreported
+unrepresentative
+unrequest/D
+unrest/M
+unrevealing
+unrideable
+unripe/TR
+unroll/GDS
+unromantic
+unruliness/M
+unruly/RTP
+unsafe/YTR
+unsavory
+unsaw
+unscathed
+unsee/S
+unseeing/Y
+unseemly/T
+unseen/M
+unsentimental
+unset
+unshakable
+unshakably
+unshakeable
+unshapely
+unsharp
+unshockable
+unshorn
+unsightliness/M
+unsightly/PT
+unsmiling
+unsociable
+unsocial
+unsold
+unsound/PRYT
+unspeakable
+unspeakably
+unspecific
+unspectacular
+unsporting
+unstable
+unsteady/TRP
+unstinting/Y
+unstrapping
+unsubstantial
+unsubtle
+unsuitable
+unsure
+unsuspecting/Y
+unsymmetrical
+untactful
+unthinkably
+unthinking/Y
+untidy/PTR
+until
+untimely/T
+untiring/Y
+untouchable/MS
+untoward
+untrue/RT
+untrustworthy
+untruth/M
+unutterable
+unutterably
+unwarrantable
+unwary/T
+unwavering
+unwed
+unwelcome/G
+unwell
+unwieldiness/M
+unwieldy/TRP
+unwise/RYT
+unworried
+unworthy/T
+unwound
+unwrapping
+unyielding
+up/S
+upbeat/MS
+upbraid/SGD
+upbringing/MS
+upchuck/SGD
+upcoming
+upcountry/M
+update/MGDRS
+updraft/MS
+upend/SGD
+upfront
+upgrade/MGDS
+upheaval/MS
+upheld
+uphill/MS
+uphold/ZGRS
+upholder/M
+upholster/ASGD
+upholsterer/MS
+upholstery/M
+upkeep/M
+upland/MS
+uplift/JSMDG
+uplink/SM
+upload/SDG
+upmarket
+upmost
+upon
+upped
+upper/SM
+uppercase/M
+upperclassman/M
+upperclassmen
+upperclasswoman
+upperclasswomen
+uppercut/MS
+uppercutting
+uppermost
+upping
+uppish
+uppity
+upraise/DSG
+uprear/GSD
+upright/MYPS
+uprightness/M
+uprising/SM
+upriver
+uproar/SM
+uproarious/Y
+uproot/GSD
+upscale
+upset/SM
+upsetting
+upshot/SM
+upside/SM
+upsilon/MS
+upstage/GDS
+upstairs
+upstanding
+upstart/MDSG
+upstate/M
+upstream
+upstroke/SM
+upsurge/MGDS
+upswing/MS
+uptake/SM
+uptempo
+upthrust/GSM
+uptick/SM
+uptight
+uptime
+uptown/M
+uptrend
+upturn/GSMD
+upvote/DS
+upward/SY
+upwind
+uracil/M
+uranium/M
+urban
+urbane/RYT
+urbanity/M
+urbanization/M
+urbanize/DSG
+urbanologist/MS
+urbanology/M
+urchin/SM
+urea/M
+uremia/M
+uremic
+ureter/SM
+urethane/M
+urethra/M
+urethrae
+urethral
+urge/MGDS
+urgency/M
+urgent/Y
+uric
+urinal/SM
+urinalyses
+urinalysis/M
+urinary
+urinate/GNDS
+urination/M
+urine/M
+urn/SM
+urogenital
+urological
+urologist/MS
+urology/M
+ursine
+urticaria/M
+usability/M
+usable/UA
+usage/SM
+use/AEDSMG
+used/U
+useful/PY
+usefulness/M
+useless/YP
+uselessness/M
+user/MS
+username/MS
+usher/SMDG
+usherette/SM
+usu
+usual's
+usual/UY
+usufruct/SM
+usurer/SM
+usurious
+usurp/SDRZG
+usurpation/M
+usurper/M
+usury/M
+utensil/SM
+uteri
+uterine
+utero
+uterus/M
+utilitarian/MS
+utilitarianism/M
+utility/SM
+utilization/M
+utilize/GBDS
+utmost/M
+utopia/SM
+utopian/MS
+utter/SDYG
+utterance/SM
+uttermost/M
+uveitis
+uvula/SM
+uvular/MS
+uxorious
+v/AS
+vac/S
+vacancy/SM
+vacant/Y
+vacate/DSG
+vacation/ZGMDRS
+vacationer/M
+vacationist/SM
+vaccinate/GNDSX
+vaccinated/U
+vaccination/M
+vaccinator/S
+vaccine/SM
+vacillate/XGNDS
+vacillation/M
+vacinal
+vacuity/M
+vacuole/MS
+vacuous/YP
+vacuousness/M
+vacuum/GSMD
+vagabond/SMDG
+vagabondage/M
+vagarious
+vagary/SM
+vagina/SM
+vaginae
+vaginal/Y
+vaginitis
+vagrancy/M
+vagrant/MS
+vague/RYTP
+vagueness/M
+vagus
+vain/RYT
+vainglorious/Y
+vainglory/M
+val
+valance/MS
+vale/MS
+valediction/MS
+valedictorian/SM
+valedictory/SM
+valence/MS
+valency/SM
+valentine/SM
+valet/SMDG
+valetudinarian/MS
+valetudinarianism/M
+valiance/M
+valiant/Y
+valid/Y
+validate/IGNDS
+validation/IM
+validations
+validator/S
+validities
+validity/IM
+validness/M
+valise/SM
+valley/SM
+valor/M
+valorous/Y
+valuable/MS
+valuate/DSG
+valuation/CAMS
+value's
+value/CAGSD
+valueless
+valuer/SM
+valve/DSMG
+valveless
+valvular
+vamoose/DSG
+vamp/AMDGS
+vampire/SM
+van/SM
+vanadium/M
+vandal/SM
+vandalism/M
+vandalize/DSG
+vane/MS
+vanguard/MS
+vanilla/SM
+vanish/JDSG
+vanishing/Y
+vanity/SM
+vanned
+vanning
+vanquish/ZGDRS
+vanquisher/M
+vantage/SM
+vape/GDS
+vapid/YP
+vapidity/M
+vapidness/M
+vapor/SM
+vaporization/M
+vaporize/DRSZG
+vaporizer/M
+vaporous
+vaporware
+vapory
+vaquero/MS
+var/S
+variability/IM
+variable/ISM
+variably/I
+variance/SM
+variant/MS
+variate/NX
+variation/M
+varicolored
+varicose
+varied/U
+variegate/DSGN
+variegation/M
+varietal/SM
+variety/SM
+various/Y
+varlet/SM
+varmint/MS
+varnish/GMDS
+varnished/U
+varsity/SM
+vary/DSG
+varying/U
+vascular
+vase/MS
+vasectomy/SM
+vasoconstriction
+vasomotor
+vasopressor/SM
+vassal/SM
+vassalage/M
+vast/MRYTSP
+vastness/M
+vat/SM
+vatted
+vatting
+vaudeville/M
+vaudevillian/MS
+vault/SMDRZG
+vaulter/M
+vaulting/M
+vaunt/SMDG
+vb
+veal/M
+vector/SGMD
+veejay/SM
+veep/MS
+veer/MDGS
+veg/SM
+vegan/SM
+veganism
+vegeburger/S
+veges
+vegetable/SM
+vegetarian/SM
+vegetarianism/M
+vegetate/GNVDS
+vegetation/M
+vegged
+vegges
+veggie/SM
+veggieburger/S
+vegging
+vehemence/M
+vehemency/M
+vehement/Y
+vehicle/MS
+vehicular
+veil's
+veil/UDGS
+vein/MDGS
+vela
+velar/SM
+veld/MS
+vellum/M
+velocipede/MS
+velocity/SM
+velodrome/S
+velour/MS
+velum/M
+velvet/M
+velveteen/M
+velvety
+venal/Y
+venality/M
+venation/M
+vend/DGS
+vendetta/SM
+vendible
+vendor/MS
+veneer/MDGS
+venerability/M
+venerable
+venerate/DSGN
+veneration/M
+venereal
+vengeance/M
+vengeful/AY
+venial
+venireman/M
+veniremen
+venison/M
+venom/M
+venomous/Y
+venous
+vent's
+vent/DGS
+ventilate/GNDS
+ventilation/M
+ventilator/SM
+ventilatory
+ventral
+ventricle/SM
+ventricular
+ventriloquism/M
+ventriloquist/SM
+ventriloquy/M
+venture/DSMG
+venturesome/PY
+venturesomeness/M
+venturous/PY
+venturousness/M
+venue/ASM
+veracious/Y
+veracity/M
+veranda/SM
+verandah/M
+verandahs
+verapamil
+verb/KMDGS
+verbal/MYS
+verbalization/M
+verbalize/GDS
+verbatim
+verbena/SM
+verbiage/MS
+verbose/Y
+verbosity/M
+verboten
+verdant/Y
+verdict/SM
+verdigris/GMDS
+verdure/M
+verge's
+verge/FDSG
+verger/MS
+verifiability
+verifiable/U
+verifiably
+verification/M
+verified/U
+verifier/M
+verify/DRSNZG
+verily
+verisimilitude/M
+veritable
+veritably
+verity/SM
+vermicelli/M
+vermiculite/M
+vermiform
+vermilion/M
+vermin/M
+verminous
+vermouth/M
+vernacular/MS
+vernal
+vernier/SM
+veronica/M
+verruca/SM
+verrucae
+versa
+versatile
+versatility/M
+verse/AFNGMSDX
+versed/U
+versification/M
+versifier/M
+versify/ZGNDRS
+version/AFIMS
+versioned
+versioning
+verso/SM
+versus
+vert/A
+vertebra/M
+vertebrae
+vertebral
+vertebrata
+vertebrate/IMS
+vertebrobasilar
+vertex/MS
+vertical/MYS
+vertices
+vertiginous
+vertigo/M
+verve/M
+very/RT
+vesicle/SM
+vesicular
+vesiculate
+vesper/MS
+vessel/MS
+vest's
+vest/ILDGS
+vestal/MS
+vestibule/MS
+vestige/SM
+vestigial/Y
+vesting/M
+vestment/IMS
+vestry/SM
+vestryman/M
+vestrymen
+vet/SM
+vetch/MS
+veteran/SM
+veterinarian/MS
+veterinary/SM
+veto/MDG
+vetoes
+vetted
+vetting
+vex/GDS
+vexation/SM
+vexatious/Y
+vhf
+vi
+via
+viability/M
+viable
+viably
+viaduct/SM
+vial/MS
+viand/SM
+vibe/MS
+vibes/M
+vibraharp/SM
+vibrancy/M
+vibrant/Y
+vibraphone/MS
+vibraphonist/MS
+vibrate/GNDSX
+vibration/M
+vibrational
+vibrationless
+vibrato/MS
+vibrator/SM
+vibratory
+viburnum/SM
+vicar/SM
+vicarage/SM
+vicarious/YP
+vicariousness/M
+vice/CMS
+viced
+vicegerent/SM
+vicennial
+viceregal
+viceroy/MS
+vichyssoise/M
+vicing
+vicinity/M
+vicious/YP
+viciousness/M
+vicissitude/SM
+victim/MS
+victimization/M
+victimize/GDS
+victimless
+victor/MS
+victorious/Y
+victory/SM
+victual/SMDG
+vicuna/MS
+vicua/MS
+videlicet
+video/GSMD
+videocassette/SM
+videoconferencing
+videodisc/MS
+videographer/MS
+videography/SM
+videophile/MS
+videophone/MS
+videotape/DSMG
+videotex
+vie/DS
+view/AMDRBSZG
+viewer/AM
+viewership/M
+viewfinder/SM
+viewing/SM
+viewpoint/MS
+vigesimal
+vigil/SM
+vigilance/M
+vigilant/Y
+vigilante/SM
+vigilantism/M
+vigilantist/M
+vignette/DSMG
+vignettist/MS
+vigor/M
+vigorous/Y
+vii
+viii
+viking/MS
+vile/YTPR
+vileness/M
+vilification/M
+vilify/DSNG
+villa/SM
+village/RSMZ
+villager/M
+villain/SM
+villainous
+villainy/SM
+villein/SM
+villeinage/M
+villi
+villus/M
+vim/M
+vinaigrette/M
+vincible/I
+vindicate/XDSGN
+vindication/M
+vindicator/MS
+vindictive/PY
+vindictiveness/M
+vine/MS
+vinegar/M
+vinegary
+vineyard/MS
+vino/M
+vinous
+vintage/MS
+vintner/MS
+vinyl/SM
+viol/MBS
+viola/SM
+violable/I
+violate/GNDSX
+violation/M
+violator/SM
+violence/M
+violent/Y
+violet/MS
+violin/MS
+violincello/S
+violinist/SM
+violist/MS
+violoncellist/SM
+violoncello/MS
+viper/SM
+viperous
+virago/M
+viragoes
+viral
+vireo/SM
+virgin/MS
+virginal/SM
+virginity/M
+virgule/MS
+virile
+virility/M
+virologist/SM
+virology/M
+virtual/Y
+virtualization
+virtue/SM
+virtuosity/M
+virtuoso/SM
+virtuous/YP
+virtuousness/M
+virulence/M
+virulent/Y
+virus/MS
+visa/MDSG
+visage/MS
+viscera
+visceral/Y
+viscid
+viscose/M
+viscosity/M
+viscount/SM
+viscountcy/SM
+viscountess/MS
+viscous
+viscus/M
+vise/ACMGDS
+visibility/IM
+visible/I
+visibly/I
+vision/KGDSM
+visionary/SM
+visit's
+visit/ASGD
+visitant/MS
+visitation/MS
+visitor/MS
+visor/SM
+vista/SM
+visual/SMY
+visualization/SM
+visualize/DRSZG
+visualizer/M
+vita/M
+vitae
+vital/SY
+vitality/M
+vitalization/AM
+vitalize/CAGSD
+vitals/M
+vitamin/MS
+vitiate/GNDS
+vitiation/M
+viticulture/M
+viticulturist/MS
+vitreous
+vitrifaction/M
+vitrification/M
+vitrify/GNDS
+vitrine/SM
+vitriol/M
+vitriolic
+vitriolically
+vittles/M
+vituperate/GNVDS
+vituperation/M
+viva/MS
+vivace
+vivacious/PY
+vivaciousness/M
+vivacity/M
+vivant/S
+vivaria
+vivarium/SM
+vivid/RYTP
+vividness/M
+vivify/ADSG
+viviparous
+vivisect/DGS
+vivisection/M
+vivisectional
+vivisectionist/SM
+vixen/SM
+vixenish/Y
+viz
+vizier/SM
+vlf
+vlogged
+vlogger/M
+vlogging
+vocab
+vocable/MS
+vocabulary/SM
+vocal/SMY
+vocalic
+vocalist/SM
+vocalization/MS
+vocalize/DSG
+vocation/FIKASM
+vocational/Y
+vocative/MS
+vociferate/DSGN
+vociferation/M
+vociferous/YP
+vociferousness/M
+vocoder/S
+vodka/SM
+vogue/SM
+voguish
+voice/IDSMG
+voiced/U
+voiceless/PY
+voicelessness/M
+voicemail/SM
+void/MDSGB
+voila
+voile/M
+voil
+vol/S
+volatile/S
+volatility/M
+volatilize/DSG
+volcanic
+volcanism
+volcano/M
+volcanoes
+volcanological
+volcanologist/MS
+volcanology/M
+vole/MS
+volition/M
+volitional
+volley/GSMD
+volleyball/MS
+volt/AMS
+voltage/MS
+voltaic
+voltmeter/SM
+volubility/M
+voluble
+volubly
+volume/SM
+volumetric
+voluminous/YP
+voluminousness/M
+voluntarily/I
+voluntarism/M
+voluntary/SM
+volunteer/SGMD
+volunteerism/M
+voluptuary/SM
+voluptuous/PY
+voluptuousness/M
+volute/SM
+vomit/SMDG
+voodoo/GSMD
+voodooism/M
+voracious/PY
+voraciousness/M
+voracity/M
+vortex/MS
+votary/SM
+vote's
+vote/CGVDS
+voter/SM
+vouch/DRSZG
+voucher/M
+vouchsafe/DSG
+vow/SGMD
+vowel/SM
+voyage/MZGDRS
+voyager/M
+voyageur/SM
+voyeur/MS
+voyeurism/M
+voyeuristic
+vulcanism
+vulcanization/M
+vulcanize/GDS
+vulgar/RYT
+vulgarian/MS
+vulgarism/MS
+vulgarity/SM
+vulgarization/M
+vulgarize/ZGDRS
+vulgarizer/M
+vulnerabilities
+vulnerability/IM
+vulnerable/I
+vulnerably/I
+vulpine
+vulture/SM
+vulturous
+vulva/M
+vulvae
+vuvuzela/MS
+vying
+w/DNXTGVJ
+wabbit/S
+wack/MRTS
+wackiness/M
+wacko/SM
+wacky/RPT
+wad/SZGMDR
+wadded
+wadding/M
+waddle/DSMG
+wade/MS
+wader/M
+waders/M
+wadge/S
+wadi/MS
+wafer/SM
+waffle/MZGDRS
+waffler/M
+waft/MDGS
+wag/SZGMDR
+wage/MS
+waged/U
+wager/ZGMDR
+wagerer/M
+wagged
+waggery/SM
+wagging
+waggish/YP
+waggishness/M
+waggle/MGDS
+wagon/ZSMR
+wagoner/M
+wagtail/SM
+waif/MS
+wail/MDRZGS
+wailer/M
+wailing/M
+wain/MS
+wainscot/SJMDG
+wainscoting/M
+wainscotted
+wainscotting/MS
+wainwright/MS
+waist/SM
+waistband/MS
+waistcoat/MS
+waistline/MS
+wait/MDRZGS
+waiter/M
+waiting/M
+waitperson/MS
+waitress/MS
+waitstaff/M
+waive/DRSZG
+waiver/M
+wake/MGJDS
+wakeful/PY
+wakefulness/M
+waken/GSD
+waldo/S
+waldoes
+wale/MGDS
+walk/MDRZGS
+walkabout/S
+walkaway/MS
+walker/M
+walkies
+walking/M
+walkout/SM
+walkover/MS
+walkway/SM
+wall/MDGS
+wallaby/SM
+wallah
+wallahs
+wallboard/M
+wallet/MS
+walleye/DSM
+wallflower/MS
+wallop/MDSJG
+walloping/M
+wallow/MDSG
+wallpaper/SMDG
+wally/S
+walnut/MS
+walrus/MS
+waltz/ZGMDRS
+waltzer/M
+wampum/M
+wan/GPDY
+wand/MS
+wander/DRSJZG
+wanderer/M
+wanderings/M
+wanderlust/SM
+wane/MS
+wangle/MZGDRS
+wangler/M
+wank/DRZGS
+wanna
+wannabe/SM
+wannabee/S
+wanner
+wanness/M
+wannest
+want/MDGS
+wanted/U
+wanton/MDYSPG
+wantonness/M
+wapiti/MS
+war/SM
+warble/MZGDRS
+warbler/M
+warbonnet/SM
+ward/AMDGS
+warden/MS
+warder/MS
+wardress/S
+wardrobe/SM
+wardroom/SM
+ware/MS
+warehouse/DSMG
+warez
+warfare/M
+warfarin
+warhead/MS
+warhorse/SM
+warily/U
+wariness/UM
+warlike
+warlock/MS
+warlord/MS
+warm/PDRYHZTGS
+warmblooded
+warmer/M
+warmhearted/P
+warmheartedness/M
+warmish
+warmness/M
+warmonger/SMG
+warmongering/M
+warmth/M
+warmup/MS
+warn/JDGS
+warning/M
+warp/MDGS
+warpaint
+warpath/M
+warpaths
+warplane/MS
+warrant/GMDS
+warranted/U
+warranty/DSMG
+warred
+warren/MS
+warring
+warrior/SM
+warship/SM
+wart/MS
+warthog/SM
+wartime/M
+warty/TR
+wary/UPRT
+was
+wasabi
+wash/BJMDRSZG
+washable/SM
+washbasin/SM
+washboard/SM
+washbowl/SM
+washcloth/M
+washcloths
+washed/U
+washer/M
+washerwoman/M
+washerwomen
+washing/M
+washout/MS
+washrag/MS
+washroom/MS
+washstand/SM
+washtub/MS
+washy/TR
+wasn't
+wasp/MS
+waspish/YP
+waspishness/M
+wassail/SMDG
+wast
+wastage/M
+waste/DRSMZG
+wastebasket/MS
+wasteful/PY
+wastefulness/M
+wasteland/SM
+wastepaper/M
+waster/M
+wastewater
+wastrel/SM
+watch/BZGMDRS
+watchable/U
+watchband/MS
+watchdog/SM
+watcher/M
+watchful/YP
+watchfulness/M
+watchmaker/MS
+watchmaking/M
+watchman/M
+watchmen
+watchstrap/S
+watchtower/SM
+watchword/MS
+water/GSMD
+waterbed/MS
+waterbird/SM
+waterboard/MDJSG
+waterboarding/M
+waterborne
+watercolor/MS
+watercourse/SM
+watercraft/M
+watercress/M
+waterfall/SM
+waterfowl/SM
+waterfront/MS
+waterhole/SM
+wateriness/M
+waterlily/SM
+waterline/MS
+waterlogged
+watermark/MDGS
+watermelon/SM
+watermill/MS
+waterpower/M
+waterproof/SMDG
+waterproofing/M
+waters/M
+watershed/MS
+waterside/MS
+waterspout/SM
+watertight
+waterway/MS
+waterwheel/SM
+waterworks/M
+watery/PTR
+watt/MS
+wattage/M
+wattle/MGDS
+wave/MZGDRS
+waveband/S
+waveform
+wavefront
+wavelength/M
+wavelengths
+wavelet/SM
+wavelike
+waver/ZGMDR
+waverer/M
+wavering/Y
+waviness/M
+wavy/PRT
+wax/GMDNS
+waxiness/M
+waxwing/SM
+waxwork/SM
+waxy/RPT
+way/SM
+waybill/SM
+wayfarer/MS
+wayfaring/SM
+waylaid
+waylay/RSZG
+waylayer/M
+wayside/SM
+wayward/PY
+waywardness/M
+wazoo/S
+we
+we'd
+we'll
+we're
+we've
+weak/PNRYXT
+weaken/DRZG
+weakener/M
+weakfish/MS
+weakish
+weakling/SM
+weakness/MS
+weal/MHS
+wealth/M
+wealthiness/M
+wealthy/TRP
+wean/DGS
+weapon/MS
+weaponize/GDS
+weaponless
+weaponry/M
+wear/MRBJSZG
+wearable/U
+wearer/M
+wearied/U
+wearily
+weariness/M
+wearisome/Y
+weary/TGDRSP
+weasel/MDYSG
+weather/SMDG
+weatherboard/SG
+weathercock/MS
+weathering/M
+weatherization/M
+weatherize/DSG
+weatherman/M
+weathermen
+weatherperson/MS
+weatherproof/GSD
+weatherstrip/S
+weatherstripped
+weatherstripping/M
+weave/DRSMZG
+weaver/M
+weaving/M
+web/SM
+webbed
+webbing/M
+webcam/MS
+webcast/SMG
+webdesign/MS
+webfeet
+webfoot/M
+webinar/SM
+webisode/MS
+weblog/MS
+webmail/SM
+webmaster/SM
+webmistress/MS
+webpage/SM
+website/SM
+wed/AS
+wedded/A
+wedder
+wedding/SM
+wedge/DSMG
+wedgie/MS
+wedlock/M
+wee/RSMT
+weed/MDRSZG
+weeder/M
+weedkiller/S
+weedless
+weedy/TR
+weeing
+week/MYS
+weekday/SM
+weekend/SZGMDR
+weekly/SM
+weeknight/SM
+ween/DSG
+weenie/MTRS
+weensy/RT
+weeny
+weep/MRJSZG
+weeper/M
+weepie
+weepy/TRSM
+weevil/MS
+weft/MS
+weigh's
+weigh/AGD
+weighbridge/S
+weighs/A
+weight/MDSJG
+weighted/U
+weightily
+weightiness/M
+weightless/YP
+weightlessness/M
+weightlifter/MS
+weightlifting/M
+weighty/PTR
+weir/MS
+weird/PTGDRY
+weirdie/MS
+weirdness/M
+weirdo/MS
+welcome/MGDS
+weld/MDRBSZG
+welder/M
+welfare/M
+welkin/M
+well/MDPSG
+wellhead/SM
+wellie
+wellington/MS
+wellness/M
+wellspring/MS
+welly/S
+welp
+welsh/ZGDRS
+welsher/M
+welt/MDRSZG
+welter/GMD
+welterweight/SM
+wen/M
+wench/MS
+wend/DSG
+went
+wept
+were
+weren't
+werewolf/M
+werewolves
+west/M
+westbound
+westerly/SM
+western/SZMR
+westerner/M
+westernization/M
+westernize/GDS
+westernmost
+westward/S
+wet/SMYP
+wetback/SM
+wetland/SM
+wetness/M
+wetter/SM
+wettest
+wetting
+wetware/S
+whack/SJZGMDR
+whacker/M
+whale/DRSMZG
+whaleboat/MS
+whalebone/M
+whaler/M
+whaling/M
+wham/MS
+whammed
+whamming
+whammy/SM
+wharf/M
+wharves
+what/MS
+whatchamacallit/MS
+whatever
+whatnot/M
+whatshername
+whatshisname
+whatsit/S
+whatsoever
+wheal/SM
+wheat/MN
+wheatgerm
+wheatmeal
+whee
+wheedle/DRSZG
+wheedler/M
+wheel/SMDRG
+wheelbarrow/SM
+wheelbase/SM
+wheelchair/SM
+wheelhouse/MS
+wheelie/SM
+wheelwright/MS
+wheeze/DSMG
+wheezily
+wheeziness/M
+wheezy/PRT
+whelk/SMD
+whelm/SDG
+whelp/SMDG
+when/MS
+whence
+whenever
+whensoever
+where/SM
+whereabouts/M
+whereas
+whereat
+whereby
+wherefore/MS
+wherein
+whereof
+whereon
+wheresoever
+whereto
+whereupon
+wherever
+wherewith
+wherewithal/M
+wherry/SM
+whet/S
+whether
+whetstone/SM
+whetted
+whetting
+whew
+whey/M
+which
+whichever
+whiff/SMDG
+whiffletree/MS
+while/DSMG
+whilom
+whilst
+whim/MS
+whimper/MDGS
+whimsical/Y
+whimsicality/M
+whimsy/SM
+whine/DRSMZG
+whiner/M
+whinge/DRSZG
+whingeing
+whinny/GDSM
+whiny/RT
+whip/MS
+whipcord/M
+whiplash/MS
+whipped
+whipper/MS
+whippersnapper/MS
+whippet/MS
+whipping/SM
+whippletree/SM
+whippoorwill/MS
+whipsaw/MDGS
+whir/MS
+whirl/SMDG
+whirligig/MS
+whirlpool/MS
+whirlwind/MS
+whirlybird/SM
+whirred
+whirring
+whisk/SMDRZG
+whisker/MD
+whiskery
+whiskey/MS
+whisky/SM
+whiskys
+whisper/MDRSZG
+whisperer/M
+whist/M
+whistle/MZGDRS
+whistleblower/GMS
+whistler/M
+whit/MDNRSXTGJ
+white/SPM
+whitebait
+whiteboard/S
+whitecap/SM
+whitefish/MS
+whitehead/MS
+whitelist/GDS
+whiten/ZGDRJ
+whitener/M
+whiteness/M
+whitening/M
+whiteout/SM
+whitepaper/MS
+whitetail/MS
+whitewall/SM
+whitewash/MDSG
+whitewater/M
+whitey/SM
+whither
+whiting/M
+whitish
+whittle/ZGDRS
+whittler/M
+whiz/M
+whizkid/M
+whizz/MDSG
+whizzbang/MS
+who'd
+who'll
+who're
+who've
+who/M
+whoa
+whodunit/MS
+whoever
+whole/SMP
+wholefood/S
+wholegrain
+wholehearted/YP
+wholeheartedness/M
+wholemeal
+wholeness/M
+wholesale/MZGDRS
+wholesaler/M
+wholesome/UP
+wholesomely
+wholesomeness/UM
+wholewheat
+wholly
+whom
+whomever
+whomsoever
+whoop/SMDRZG
+whoopee/S
+whooper/M
+whoosh/MDSG
+whop/S
+whopped
+whopper/SM
+whopping
+whore/SMG
+whorehouse/MS
+whoreish
+whorish
+whorl/SMD
+whose
+whoso
+whosoever
+whup/S
+whupped
+whupping
+why'd
+why/M
+whys
+wick/MDRSZGJ
+wicked/TPRY
+wickedness/M
+wicker/M
+wickerwork/M
+wicket/SM
+wide/YTRP
+widemouthed
+widen/SDRZG
+widener/M
+wideness/M
+widescreen/MS
+widespread
+widgeon/MS
+widget/S
+widow/SMDRZG
+widower/M
+widowhood/M
+width/M
+widths
+wield/SDRZG
+wielder/M
+wiener/SM
+wienie/SM
+wife/MY
+wifeless
+wig/SM
+wigeon/SM
+wigged
+wigging
+wiggle/DRSMZG
+wiggler/M
+wiggly/TR
+wight/SM
+wiglet/SM
+wigwag/SM
+wigwagged
+wigwagging
+wigwam/SM
+wiki/MS
+wild/MRYSTP
+wildcard/MS
+wildcat/MS
+wildcatted
+wildcatter/MS
+wildcatting
+wildebeest/MS
+wilderness/MS
+wildfire/MS
+wildflower/SM
+wildfowl/M
+wildlife/M
+wildness/M
+wilds/M
+wile/MGDS
+wilful/P
+wilfulness/M
+wiliness/M
+will/MDS
+willful/PY
+willfulness/M
+willies/M
+willing/UPY
+willingness/UM
+williwaw/MS
+willow/SM
+willowy
+willpower/M
+willy-nilly
+willy/S
+wilt/MDSG
+wily/RTP
+wimp/MDSG
+wimpish
+wimple/DSMG
+wimpy/RT
+win/SGMD
+wince/DSMG
+winch/MDSG
+wind's
+wind/UASG
+windbag/SM
+windblown
+windbreak/SZMR
+windbreaker/M
+windburn/MD
+windcheater/S
+windchill/M
+winded
+winder/SM
+windfall/MS
+windflower/MS
+windily
+windiness/M
+winding/SM
+windjammer/SM
+windlass/MS
+windless
+windmill/MDGS
+window/SMDG
+windowless
+windowpane/SM
+windowsill/SM
+windpipe/MS
+windproof
+windrow/SM
+windscreen/SM
+windshield/SM
+windsock/MS
+windstorm/MS
+windsurf/ZGDRS
+windsurfer/M
+windsurfing/M
+windswept
+windup/SM
+windward/M
+windy/RTP
+wine/MS
+wineglass/MS
+winegrower/MS
+winemaker/MS
+winery/SM
+wineshop/MS
+wing/MDRZG
+wingding/MS
+wingless
+winglike
+wingnut/SM
+wingspan/MS
+wingspread/SM
+wingtip/SM
+wink/MDRSZG
+winker/M
+winkle/DSMG
+winnable/U
+winner/SM
+winning/MYS
+winnow/ZGSDR
+winnower/M
+wino/MS
+winsome/YTRP
+winsomeness/M
+winsorization
+winsorize/GDS
+winter/GSMD
+wintergreen/M
+winterize/GDS
+wintertime/M
+wintry/TR
+winy/RT
+wipe/MZGDRS
+wiper/M
+wire's
+wire/AGDS
+wired/S
+wirehair/MS
+wireless/MS
+wiretap/MS
+wiretapped
+wiretapper/SM
+wiretapping/M
+wiriness/M
+wiring/M
+wiry/RTP
+wisdom/M
+wise/MYTGDRS
+wiseacre/SM
+wisecrack/MDSG
+wiseguy/S
+wish/MDRSZG
+wishbone/SM
+wisher/M
+wishful/Y
+wishlist's
+wishy-washy
+wisp/MS
+wispy/RT
+wist
+wisteria/SM
+wistful/YP
+wistfulness/M
+wit/SM
+witch/MDSG
+witchcraft/M
+witchery/M
+with
+withal
+withdraw/SG
+withdrawal/MS
+withdrawn
+withdrew
+withe/DRSMZG
+wither/JGD
+withering/Y
+withers/M
+withheld
+withhold/SG
+withholding/M
+within/M
+without
+withstand/GS
+withstood
+witless/PY
+witlessness/M
+witness/MDSG
+wits/M
+witted
+witter/SGD
+witticism/SM
+wittily
+wittiness/M
+witting/UY
+witty/RPT
+wive/GDS
+wiz/S
+wizard/SMY
+wizardry/M
+wizened
+wk/Y
+woad/M
+woah
+wobble/MGDS
+wobbliness/M
+wobbly/RTP
+wodge/S
+woe/SM
+woebegone
+woeful/YP
+woefuller
+woefullest
+woefulness/M
+wog/S
+wok/SMN
+woke
+wold/MS
+wolf/MDSG
+wolfhound/SM
+wolfish
+wolfram/M
+wolverine/SM
+wolves
+woman/M
+womanhood/M
+womanish
+womanize/DRSZG
+womanizer/M
+womankind/M
+womanlike/M
+womanliness/M
+womanly/RPT
+womb/MS
+wombat/MS
+womble/S
+women/M
+womenfolk/SM
+womenfolks/M
+won't
+won/M
+wonder/MDGLS
+wonderful/YP
+wonderfulness/M
+wondering/Y
+wonderland/MS
+wonderment/M
+wondrous/Y
+wonk/MS
+wonky/TR
+wont/MD
+wonted/U
+woo/SZGDR
+wood/MDNSG
+woodbine/M
+woodblock/MS
+woodcarver/MS
+woodcarving/SM
+woodchuck/MS
+woodcock/SM
+woodcraft/M
+woodcut/SM
+woodcutter/SM
+woodcutting/M
+wooden/RYTP
+woodenness/M
+woodiness/M
+woodland/SM
+woodlice
+woodlot/SM
+woodlouse
+woodman/M
+woodmen
+woodpecker/MS
+woodpile/SM
+woods/M
+woodshed/SM
+woodsiness/M
+woodsman/M
+woodsmen
+woodsy/RTP
+woodwind/MS
+woodwork/MRZG
+woodworker/M
+woodworking/M
+woodworm/S
+woody/TPRSM
+wooer/M
+woof/MDRSZG
+woofer/M
+wool/MNX
+woolen/M
+woolgathering/M
+wooliness
+woolliness/M
+woolly/RSMPT
+woozily
+wooziness/M
+woozy/TRP
+wop/MS!
+word's
+word/ADSG
+wordage/M
+wordbook/SM
+wordie
+wordily
+wordiness/M
+wording/SM
+wordless/Y
+wordplay/M
+wordsmith
+wordsmiths
+wordy/TPRS
+wore
+work's
+work/ADJSG
+workable/U
+workaday
+workaholic/SM
+workaround/S
+workbasket/S
+workbench/MS
+workbook/MS
+workday/SM
+worker/MS
+workfare/M
+workflow/MS
+workforce/M
+workhorse/SM
+workhouse/SM
+working's
+workingman/M
+workingmen
+workings/M
+workingwoman/M
+workingwomen
+workload/MS
+workman/M
+workmanlike
+workmanship/M
+workmate/S
+workmen
+workout/SM
+workplace/MS
+workroom/MS
+works/M
+worksheet/MS
+workshop/MS
+workshy
+worksite/S
+workspace
+workstation/MS
+worktable/MS
+worktop/S
+workup/MS
+workweek/SM
+world/SM
+worldlier
+worldliness/UM
+worldly/UTP
+worldview/SM
+worldwide
+worm/MDSG
+wormhole/MS
+wormwood/M
+wormy/TR
+worn/U
+worried/Y
+worrier/M
+worriment/M
+worrisome
+worry/ZGDRSMJ
+worrying/Y
+worrywart/SM
+worse/M
+worsen/DSG
+worship/ZGSMDR
+worshiper/M
+worshipful
+worst/SGMD
+worsted/M
+wort/M
+worth/M
+worthies
+worthily/U
+worthiness/UM
+worthless/PY
+worthlessness/M
+worthwhile
+worthy's
+worthy/UPRT
+wot
+wotcha
+would've
+would/S
+wouldn't
+wouldst
+wound/SGMDR
+wove/A
+woven/AU
+wow/SGMD
+wpm
+wrack/GSMD
+wraith/M
+wraiths
+wrangle/DRSMZGJ
+wrangler/M
+wrap's
+wrap/US
+wraparound/SM
+wrapped/U
+wrapper/SM
+wrapping/MS
+wrasse/MS
+wrath/M
+wrathful/Y
+wreak/SGD
+wreath/MDSG
+wreathe
+wreaths
+wreck/SZGMDR
+wreckage/M
+wrecker/M
+wren/MS
+wrench/MDSG
+wrest/SGMD
+wrestle/MZGDRS
+wrestler/M
+wrestling/M
+wretch/MS
+wretched/TPRY
+wretchedness/M
+wriggle/MZGDRS
+wriggler/M
+wriggly
+wright/MS
+wring/SZGMR
+wringer/M
+wrinkle/MGDS
+wrinkled/U
+wrinkly/TRSM
+wrist/SM
+wristband/MS
+wristwatch/MS
+writ/MRBJSZG
+write/S
+writer/M
+writhe/MGDS
+writing/M
+written/AU
+wrong/STGMPDRY
+wrongdoer/SM
+wrongdoing/SM
+wrongful/PY
+wrongfulness/M
+wrongheaded/YP
+wrongheadedness/M
+wrongness/M
+wrote/A
+wroth
+wrought
+wrung
+wry/Y
+wryer
+wryest
+wryness/M
+wt
+wunderkind/S
+wurst/SM
+wuss/MS
+wussy/RSMT
+x
+xci
+xcii
+xciv
+xcix
+xcvi
+xcvii
+xenon/M
+xenophile/S
+xenophobe/MS
+xenophobia/M
+xenophobic
+xerographic
+xerography/M
+xerox/MDSG
+xi/SM
+xii
+xiii
+xiv
+xix
+xor
+xref/S
+xterm/M
+xv
+xvi
+xvii
+xviii
+xx
+xxi
+xxii
+xxiii
+xxiv
+xxix
+xxv
+xxvi
+xxvii
+xxviii
+xxx
+xxxi
+xxxii
+xxxiii
+xxxiv
+xxxix
+xxxv
+xxxvi
+xxxvii
+xxxviii
+xylem/M
+xylene
+xylophone/SM
+xylophonist/MS
+y
+y'all
+ya
+yacht/SMDG
+yachting/M
+yachtsman/M
+yachtsmen
+yachtswoman/M
+yachtswomen
+yahoo/SM
+yak/SM
+yakked
+yakking
+yam/SM
+yammer/SZGMDR
+yammerer/M
+yang/M
+yank/MDSG
+yap/SM
+yapped
+yapping
+yard/MS
+yardage/MS
+yardarm/MS
+yardman/M
+yardmaster/MS
+yardmen
+yardstick/MS
+yarmulke/SM
+yarn/MS
+yarrow/M
+yashmak/S
+yaw/SGMD
+yawl/MS
+yawn/MDRSZG
+yawner/M
+yaws/M
+yay
+yd
+ye/RST
+yea/SM
+yeah/M
+yeahs
+year/MYS
+yearbook/MS
+yearling/MS
+yearlong
+yearly/SM
+yearn/GSJD
+yearning/M
+yeast/SM
+yeasty/RT
+yeet/DSG
+yegg/MS
+yell/MDSG
+yellow/MDRTGPS
+yellowhammer/S
+yellowish
+yellowness/M
+yellowy
+yelp/MDSG
+yen/SM
+yeoman/M
+yeomanry/M
+yeomen
+yep/SM
+yes/MS
+yeshiva/SM
+yeshivot
+yessed
+yessing
+yesterday/MS
+yesteryear/M
+yet
+yeti/MS
+yew/SM
+yid/S
+yield/JSGMD
+yikes
+yin/M
+yip/SM
+yipe
+yipped
+yippee
+yipping
+yo
+yob/S
+yobbo/S
+yobibyte/SM
+yodel/SMDRZG
+yodeler/M
+yoga/M
+yogi/MS
+yogic
+yogurt/SM
+yoke's
+yoke/UGDS
+yokel/SM
+yolk/MDS
+yon
+yonder
+yonks
+yore/M
+you'd
+you'll
+you're
+you've
+you/SMH
+young/TMR
+youngish
+youngster/MS
+your/S
+yourself
+yourselves
+youth/M
+youthful/YP
+youthfulness/M
+youths
+yow
+yowl/MDSG
+yowsa
+yowsah
+yowza
+yowzah
+yr/S
+ytterbium/M
+yttrium/M
+yuan/M
+yucca/SM
+yuck/MDSG
+yucky/TR
+yuk/SM
+yukked
+yukking
+yukky
+yule/M
+yuletide/M
+yum
+yummy/TR
+yup/SM
+yuppie/MS
+yuppify/GDS
+yurt/MS
+z/DNXTGJ
+zaniness/M
+zany/RSMPT
+zap/SM
+zapped
+zapper/MS
+zapping
+zappy
+zeal/M
+zealot/MS
+zealotry/M
+zealous/YP
+zealousness/M
+zebibyte/SM
+zebra/SM
+zebu/MS
+zed/SM
+zeitgeist/SM
+zenith/M
+zeniths
+zenned
+zeolite/S
+zephyr/MS
+zeppelin/MS
+zero/MDHSG
+zeroes
+zest/MS
+zestful/YP
+zestfulness/M
+zesty/RT
+zeta/MS
+zigzag/SM
+zigzagged
+zigzagging
+zilch/M
+zillion/MS
+zinc/MS
+zincked
+zincking
+zine/S
+zinfandel/M
+zing/MDRZG
+zinger/M
+zingy/RT
+zinnia/MS
+zip's
+zip/US
+zipped/U
+zipper/MDGS
+zipping/U
+zippy/TR
+zircon/MS
+zirconium/M
+zit/SM
+zither/MS
+zloty/SM
+zlotys
+zodiac/MS
+zodiacal
+zombie/MS
+zonal/Y
+zone's
+zone/AGDS
+zoning/M
+zonked
+zoo/SM
+zookeeper/SM
+zoological/Y
+zoologist/SM
+zoology/M
+zoom/MDSG
+zoomorphism/M
+zoonosis
+zoonotic
+zoophilia/M
+zoophyte/SM
+zoophytic
+zooplankton
+zorch
+zoster
+zounds
+zucchini/MS
+zuke/S
+zwieback/M
+zydeco/M
+zygote/SM
+zygotic
+zymurgy/M
+ngstrm/M
+clair/SM
+clat/M
+lan/M
+migr/SM
+pe/MS
+tude/SM
diff --git a/extensions/spellcheck/locales/moz.build b/extensions/spellcheck/locales/moz.build
new file mode 100644
index 0000000000..aae8e8ca67
--- /dev/null
+++ b/extensions/spellcheck/locales/moz.build
@@ -0,0 +1,10 @@
+# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
+# vim: set filetype=python:
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+LOCALIZED_FILES.dictionaries += [
+ "en-US/hunspell/*.aff",
+ "en-US/hunspell/*.dic",
+]
diff --git a/extensions/spellcheck/moz.build b/extensions/spellcheck/moz.build
new file mode 100644
index 0000000000..7493edfd62
--- /dev/null
+++ b/extensions/spellcheck/moz.build
@@ -0,0 +1,19 @@
+# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
+# vim: set filetype=python:
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+DIRS += ["idl", "hunspell", "src"]
+
+if CONFIG["MOZ_WIDGET_TOOLKIT"] != "android":
+ # GeckoView disables hunspell spellchecker.
+ DIRS += ["locales"]
+
+MOCHITEST_CHROME_MANIFESTS += ["tests/chrome/chrome.ini"]
+MOCHITEST_MANIFESTS += ["tests/mochitest/mochitest.ini"]
+
+SPHINX_TREES["/extensions/spellcheck"] = "docs"
+
+with Files("**"):
+ BUG_COMPONENT = ("Core", "Spelling checker")
diff --git a/extensions/spellcheck/src/components.conf b/extensions/spellcheck/src/components.conf
new file mode 100644
index 0000000000..7fc73c1a17
--- /dev/null
+++ b/extensions/spellcheck/src/components.conf
@@ -0,0 +1,20 @@
+# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
+# vim: set filetype=python:
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+Classes = [
+ {
+ 'cid': '{56c778e4-1bee-45f3-a689-886692a97fe7}',
+ 'contract_ids': ['@mozilla.org/spellchecker/engine;1'],
+ 'type': 'mozHunspell',
+ },
+ {
+ 'cid': '{7ef52eaf-b7e1-462b-87e2-5d1dbaca9048}',
+ 'contract_ids': ['@mozilla.org/spellchecker/personaldictionary;1'],
+ 'type': 'mozPersonalDictionary',
+ 'headers': ['/extensions/spellcheck/src/mozPersonalDictionary.h'],
+ 'init_method': 'Init',
+ },
+]
diff --git a/extensions/spellcheck/src/moz.build b/extensions/spellcheck/src/moz.build
new file mode 100644
index 0000000000..7ba7826a1e
--- /dev/null
+++ b/extensions/spellcheck/src/moz.build
@@ -0,0 +1,30 @@
+# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
+# vim: set filetype=python:
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+include("/ipc/chromium/chromium-config.mozbuild")
+UNIFIED_SOURCES += [
+ "mozEnglishWordUtils.cpp",
+ "mozInlineSpellChecker.cpp",
+ "mozInlineSpellWordUtil.cpp",
+ "mozPersonalDictionary.cpp",
+ "mozSpellChecker.cpp",
+]
+
+XPCOM_MANIFESTS += [
+ "components.conf",
+]
+
+FINAL_LIBRARY = "xul"
+
+LOCAL_INCLUDES += [
+ "../hunspell/glue",
+ "../hunspell/src",
+ "/dom/base",
+]
+EXPORTS.mozilla += [
+ "mozInlineSpellChecker.h",
+ "mozSpellChecker.h",
+]
diff --git a/extensions/spellcheck/src/mozEnglishWordUtils.cpp b/extensions/spellcheck/src/mozEnglishWordUtils.cpp
new file mode 100644
index 0000000000..f3ae8a0a73
--- /dev/null
+++ b/extensions/spellcheck/src/mozEnglishWordUtils.cpp
@@ -0,0 +1,102 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "mozEnglishWordUtils.h"
+#include "nsComponentManagerUtils.h"
+#include "nsReadableUtils.h"
+#include "nsUnicharUtils.h"
+#include "nsUnicodeProperties.h"
+#include "nsCRT.h"
+#include "mozilla/Likely.h"
+
+NS_IMPL_CYCLE_COLLECTION(mozEnglishWordUtils, mURLDetector)
+
+mozEnglishWordUtils::mozEnglishWordUtils() {
+ mURLDetector = do_CreateInstance(MOZ_TXTTOHTMLCONV_CONTRACTID);
+}
+
+mozEnglishWordUtils::~mozEnglishWordUtils() {}
+
+// This needs vast improvement
+
+// static
+bool mozEnglishWordUtils::ucIsAlpha(char16_t aChar) {
+ // XXX we have to fix callers to handle the full Unicode range
+ return nsUGenCategory::kLetter == mozilla::unicode::GetGenCategory(aChar);
+}
+
+bool mozEnglishWordUtils::FindNextWord(const nsAString& aWord, uint32_t offset,
+ int32_t* begin, int32_t* end) {
+ if (offset >= aWord.Length()) {
+ *begin = -1;
+ *end = -1;
+ return false;
+ }
+
+ const char16_t* word = aWord.BeginReading();
+ uint32_t length = aWord.Length();
+ const char16_t* p = word + offset;
+ const char16_t* endbuf = word + length;
+ const char16_t* startWord = p;
+
+ // XXX These loops should be modified to handle non-BMP characters.
+ // if previous character is a word character, need to advance out of the
+ // word
+ if (offset > 0 && ucIsAlpha(*(p - 1))) {
+ while (p < endbuf && ucIsAlpha(*p)) {
+ p++;
+ }
+ }
+ while ((p < endbuf) && (!ucIsAlpha(*p))) {
+ p++;
+ }
+ startWord = p;
+ while ((p < endbuf) && ((ucIsAlpha(*p)) || (*p == '\''))) {
+ p++;
+ }
+
+ // we could be trying to break down a url, we don't want to break a url into
+ // parts, instead we want to find out if it really is a url and if so, skip
+ // it, advancing startWord to a point after the url.
+
+ // before we spend more time looking to see if the word is a url, look for a
+ // url identifer and make sure that identifer isn't the last character in
+ // the word fragment.
+ if ((p < endbuf - 1) && (*p == ':' || *p == '@' || *p == '.')) {
+ // ok, we have a possible url...do more research to find out if we really
+ // have one and determine the length of the url so we can skip over it.
+
+ if (mURLDetector) {
+ int32_t startPos = -1;
+ int32_t endPos = -1;
+
+ mURLDetector->FindURLInPlaintext(startWord, endbuf - startWord,
+ p - startWord, &startPos, &endPos);
+
+ // ok, if we got a url, adjust the array bounds, skip the current url
+ // text and find the next word again
+ if (startPos != -1 && endPos != -1) {
+ startWord = p + endPos + 1; // skip over the url
+
+ // now recursively call FindNextWord to search for the next word now
+ // that we have skipped the url
+ return FindNextWord(aWord, startWord - word, begin, end);
+ }
+ }
+ }
+
+ while ((p > startWord) && (*(p - 1) == '\'')) { // trim trailing apostrophes
+ p--;
+ }
+
+ if (startWord == endbuf) {
+ *begin = -1;
+ *end = -1;
+ return false;
+ }
+ *begin = startWord - word;
+ *end = p - word;
+ return true;
+}
diff --git a/extensions/spellcheck/src/mozEnglishWordUtils.h b/extensions/spellcheck/src/mozEnglishWordUtils.h
new file mode 100644
index 0000000000..64338fe2c6
--- /dev/null
+++ b/extensions/spellcheck/src/mozEnglishWordUtils.h
@@ -0,0 +1,40 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef mozEnglishWordUtils_h__
+#define mozEnglishWordUtils_h__
+
+#include "nsCOMPtr.h"
+#include "nsString.h"
+
+#include "mozITXTToHTMLConv.h"
+#include "nsCycleCollectionParticipant.h"
+
+class mozEnglishWordUtils final {
+ public:
+ NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(mozEnglishWordUtils)
+ NS_DECL_CYCLE_COLLECTION_NATIVE_CLASS(mozEnglishWordUtils)
+
+ mozEnglishWordUtils();
+
+ /**
+ * Given a unicode string and an offset, find the beginning and end of the
+ * next word. Return false, begin and end are -1 if there are no words
+ * remaining in the string. This should really be folded into the
+ * Line/WordBreaker.
+ */
+ bool FindNextWord(const nsAString& aWord, uint32_t offset, int32_t* begin,
+ int32_t* end);
+
+ protected:
+ virtual ~mozEnglishWordUtils();
+
+ static bool ucIsAlpha(char16_t aChar);
+
+ nsCOMPtr<mozITXTToHTMLConv>
+ mURLDetector; // used to detect urls so the spell checker can skip them.
+};
+
+#endif
diff --git a/extensions/spellcheck/src/mozInlineSpellChecker.cpp b/extensions/spellcheck/src/mozInlineSpellChecker.cpp
new file mode 100644
index 0000000000..d144fff317
--- /dev/null
+++ b/extensions/spellcheck/src/mozInlineSpellChecker.cpp
@@ -0,0 +1,2120 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set sw=2 ts=2 sts=2 tw=80: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+/**
+ * This class is called by the editor to handle spellchecking after various
+ * events. The main entrypoint is SpellCheckAfterEditorChange, which is called
+ * when the text is changed.
+ *
+ * It is VERY IMPORTANT that we do NOT do any operations that might cause DOM
+ * notifications to be flushed when we are called from the editor. This is
+ * because the call might originate from a frame, and flushing the
+ * notifications might cause that frame to be deleted.
+ *
+ * We post an event and do all of the spellchecking in that event handler.
+ * We store all DOM pointers in ranges because they are kept up-to-date with
+ * DOM changes that may have happened while the event was on the queue.
+ *
+ * We also allow the spellcheck to be suspended and resumed later. This makes
+ * large pastes or initializations with a lot of text not hang the browser UI.
+ *
+ * An optimization is the mNeedsCheckAfterNavigation flag. This is set to
+ * true when we get any change, and false once there is no possibility
+ * something changed that we need to check on navigation. Navigation events
+ * tend to be a little tricky because we want to check the current word on
+ * exit if something has changed. If we navigate inside the word, we don't want
+ * to do anything. As a result, this flag is cleared in FinishNavigationEvent
+ * when we know that we are checking as a result of navigation.
+ */
+
+#include "mozInlineSpellChecker.h"
+
+#include "mozilla/Assertions.h"
+#include "mozilla/Attributes.h"
+#include "mozilla/EditAction.h"
+#include "mozilla/EditorBase.h"
+#include "mozilla/EditorDOMPoint.h"
+#include "mozilla/EditorSpellCheck.h"
+#include "mozilla/EventListenerManager.h"
+#include "mozilla/HTMLEditor.h"
+#include "mozilla/IntegerRange.h"
+#include "mozilla/Logging.h"
+#include "mozilla/RangeUtils.h"
+#include "mozilla/Services.h"
+#include "mozilla/StaticPrefs_extensions.h"
+#include "mozilla/TextEvents.h"
+#include "mozilla/dom/Event.h"
+#include "mozilla/dom/KeyboardEvent.h"
+#include "mozilla/dom/KeyboardEventBinding.h"
+#include "mozilla/dom/MouseEvent.h"
+#include "mozilla/dom/Selection.h"
+#include "mozInlineSpellWordUtil.h"
+#ifdef ACCESSIBILITY
+# include "nsAccessibilityService.h"
+#endif
+#include "nsCOMPtr.h"
+#include "nsCRT.h"
+#include "nsGenericHTMLElement.h"
+#include "nsRange.h"
+#include "nsIPrefBranch.h"
+#include "nsIPrefService.h"
+#include "nsIRunnable.h"
+#include "nsServiceManagerUtils.h"
+#include "nsString.h"
+#include "nsThreadUtils.h"
+#include "nsUnicharUtils.h"
+#include "nsIContent.h"
+#include "nsIContentInlines.h"
+#include "nsRange.h"
+#include "nsContentUtils.h"
+#include "nsIObserverService.h"
+#include "prtime.h"
+
+using mozilla::LogLevel;
+using namespace mozilla;
+using namespace mozilla::dom;
+using namespace mozilla::ipc;
+
+// the number of milliseconds that we will take at once to do spellchecking
+#define INLINESPELL_CHECK_TIMEOUT 1
+
+// The number of words to check before we look at the time to see if
+// INLINESPELL_CHECK_TIMEOUT ms have elapsed. This prevents us from getting
+// stuck and not moving forward because the INLINESPELL_CHECK_TIMEOUT might
+// be too short to a low-end machine.
+#define INLINESPELL_MINIMUM_WORDS_BEFORE_TIMEOUT 5
+
+// The maximum number of words to check word via IPC.
+#define INLINESPELL_MAXIMUM_CHUNKED_WORDS_PER_TASK 25
+
+// These notifications are broadcast when spell check starts and ends. STARTED
+// must always be followed by ENDED.
+#define INLINESPELL_STARTED_TOPIC "inlineSpellChecker-spellCheck-started"
+#define INLINESPELL_ENDED_TOPIC "inlineSpellChecker-spellCheck-ended"
+
+static mozilla::LazyLogModule sInlineSpellCheckerLog("InlineSpellChecker");
+
+static const PRTime kMaxSpellCheckTimeInUsec =
+ INLINESPELL_CHECK_TIMEOUT * PR_USEC_PER_MSEC;
+
+mozInlineSpellStatus::mozInlineSpellStatus(
+ mozInlineSpellChecker* aSpellChecker, const Operation aOp,
+ RefPtr<nsRange>&& aRange, RefPtr<nsRange>&& aCreatedRange,
+ RefPtr<nsRange>&& aAnchorRange, const bool aForceNavigationWordCheck,
+ const int32_t aNewNavigationPositionOffset)
+ : mSpellChecker(aSpellChecker),
+ mRange(std::move(aRange)),
+ mOp(aOp),
+ mCreatedRange(std::move(aCreatedRange)),
+ mAnchorRange(std::move(aAnchorRange)),
+ mForceNavigationWordCheck(aForceNavigationWordCheck),
+ mNewNavigationPositionOffset(aNewNavigationPositionOffset) {}
+
+// mozInlineSpellStatus::CreateForEditorChange
+//
+// This is the most complicated case. For changes, we need to compute the
+// range of stuff that changed based on the old and new caret positions,
+// as well as use a range possibly provided by the editor (start and end,
+// which are usually nullptr) to get a range with the union of these.
+
+// static
+Result<UniquePtr<mozInlineSpellStatus>, nsresult>
+mozInlineSpellStatus::CreateForEditorChange(
+ mozInlineSpellChecker& aSpellChecker, const EditSubAction aEditSubAction,
+ nsINode* aAnchorNode, uint32_t aAnchorOffset, nsINode* aPreviousNode,
+ uint32_t aPreviousOffset, nsINode* aStartNode, uint32_t aStartOffset,
+ nsINode* aEndNode, uint32_t aEndOffset) {
+ MOZ_LOG(sInlineSpellCheckerLog, LogLevel::Verbose, ("%s", __FUNCTION__));
+
+ if (NS_WARN_IF(!aAnchorNode) || NS_WARN_IF(!aPreviousNode)) {
+ return Err(NS_ERROR_FAILURE);
+ }
+
+ bool deleted = aEditSubAction == EditSubAction::eDeleteSelectedContent;
+ if (aEditSubAction == EditSubAction::eInsertTextComingFromIME) {
+ // IME may remove the previous node if it cancels composition when
+ // there is no text around the composition.
+ deleted = !aPreviousNode->IsInComposedDoc();
+ }
+
+ // save the anchor point as a range so we can find the current word later
+ RefPtr<nsRange> anchorRange = mozInlineSpellStatus::PositionToCollapsedRange(
+ aAnchorNode, aAnchorOffset);
+ if (NS_WARN_IF(!anchorRange)) {
+ return Err(NS_ERROR_FAILURE);
+ }
+
+ // Deletes are easy, the range is just the current anchor. We set the range
+ // to check to be empty, FinishInitOnEvent will fill in the range to be
+ // the current word.
+ RefPtr<nsRange> range = deleted ? nullptr : nsRange::Create(aPreviousNode);
+
+ // On insert save this range: DoSpellCheck optimizes things in this range.
+ // Otherwise, just leave this nullptr.
+ RefPtr<nsRange> createdRange =
+ (aEditSubAction == EditSubAction::eInsertText) ? range : nullptr;
+
+ UniquePtr<mozInlineSpellStatus> status{
+ /* The constructor is `private`, hence the explicit allocation. */
+ new mozInlineSpellStatus{&aSpellChecker,
+ deleted ? eOpChangeDelete : eOpChange,
+ std::move(range), std::move(createdRange),
+ std::move(anchorRange), false, 0}};
+ if (deleted) {
+ return status;
+ }
+
+ // ...we need to put the start and end in the correct order
+ ErrorResult errorResult;
+ int16_t cmpResult = status->mAnchorRange->ComparePoint(
+ *aPreviousNode, aPreviousOffset, errorResult);
+ if (NS_WARN_IF(errorResult.Failed())) {
+ return Err(errorResult.StealNSResult());
+ }
+ nsresult rv;
+ if (cmpResult < 0) {
+ // previous anchor node is before the current anchor
+ rv = status->mRange->SetStartAndEnd(aPreviousNode, aPreviousOffset,
+ aAnchorNode, aAnchorOffset);
+ if (NS_WARN_IF(NS_FAILED(rv))) {
+ return Err(rv);
+ }
+ } else {
+ // previous anchor node is after (or the same as) the current anchor
+ rv = status->mRange->SetStartAndEnd(aAnchorNode, aAnchorOffset,
+ aPreviousNode, aPreviousOffset);
+ if (NS_WARN_IF(NS_FAILED(rv))) {
+ return Err(rv);
+ }
+ }
+
+ // if we were given a range, we need to expand our range to encompass it
+ if (aStartNode && aEndNode) {
+ cmpResult =
+ status->mRange->ComparePoint(*aStartNode, aStartOffset, errorResult);
+ if (NS_WARN_IF(errorResult.Failed())) {
+ return Err(errorResult.StealNSResult());
+ }
+ if (cmpResult < 0) { // given range starts before
+ rv = status->mRange->SetStart(aStartNode, aStartOffset);
+ if (NS_WARN_IF(NS_FAILED(rv))) {
+ return Err(rv);
+ }
+ }
+
+ cmpResult =
+ status->mRange->ComparePoint(*aEndNode, aEndOffset, errorResult);
+ if (NS_WARN_IF(errorResult.Failed())) {
+ return Err(errorResult.StealNSResult());
+ }
+ if (cmpResult > 0) { // given range ends after
+ rv = status->mRange->SetEnd(aEndNode, aEndOffset);
+ if (NS_WARN_IF(NS_FAILED(rv))) {
+ return Err(rv);
+ }
+ }
+ }
+
+ return status;
+}
+
+// mozInlineSpellStatus::CreateForNavigation
+//
+// For navigation events, we just need to store the new and old positions.
+//
+// In some cases, we detect that we shouldn't check. If this event should
+// not be processed, *aContinue will be false.
+
+// static
+Result<UniquePtr<mozInlineSpellStatus>, nsresult>
+mozInlineSpellStatus::CreateForNavigation(
+ mozInlineSpellChecker& aSpellChecker, bool aForceCheck,
+ int32_t aNewPositionOffset, nsINode* aOldAnchorNode,
+ uint32_t aOldAnchorOffset, nsINode* aNewAnchorNode,
+ uint32_t aNewAnchorOffset, bool* aContinue) {
+ MOZ_LOG(sInlineSpellCheckerLog, LogLevel::Verbose, ("%s", __FUNCTION__));
+
+ RefPtr<nsRange> anchorRange = mozInlineSpellStatus::PositionToCollapsedRange(
+ aNewAnchorNode, aNewAnchorOffset);
+ if (NS_WARN_IF(!anchorRange)) {
+ return Err(NS_ERROR_FAILURE);
+ }
+
+ UniquePtr<mozInlineSpellStatus> status{
+ /* The constructor is `private`, hence the explicit allocation. */
+ new mozInlineSpellStatus{&aSpellChecker, eOpNavigation, nullptr, nullptr,
+ std::move(anchorRange), aForceCheck,
+ aNewPositionOffset}};
+
+ // get the root node for checking
+ EditorBase* editorBase = status->mSpellChecker->mEditorBase;
+ if (NS_WARN_IF(!editorBase)) {
+ return Err(NS_ERROR_FAILURE);
+ }
+ Element* root = editorBase->GetRoot();
+ if (NS_WARN_IF(!root)) {
+ return Err(NS_ERROR_FAILURE);
+ }
+ // the anchor node might not be in the DOM anymore, check
+ if (root && aOldAnchorNode &&
+ !aOldAnchorNode->IsShadowIncludingInclusiveDescendantOf(root)) {
+ *aContinue = false;
+ return status;
+ }
+
+ status->mOldNavigationAnchorRange =
+ mozInlineSpellStatus::PositionToCollapsedRange(aOldAnchorNode,
+ aOldAnchorOffset);
+ if (NS_WARN_IF(!status->mOldNavigationAnchorRange)) {
+ return Err(NS_ERROR_FAILURE);
+ }
+
+ *aContinue = true;
+ return status;
+}
+
+// mozInlineSpellStatus::CreateForSelection
+//
+// It is easy for selections since we always re-check the spellcheck
+// selection.
+
+// static
+UniquePtr<mozInlineSpellStatus> mozInlineSpellStatus::CreateForSelection(
+ mozInlineSpellChecker& aSpellChecker) {
+ MOZ_LOG(sInlineSpellCheckerLog, LogLevel::Verbose, ("%s", __FUNCTION__));
+
+ UniquePtr<mozInlineSpellStatus> status{
+ /* The constructor is `private`, hence the explicit allocation. */
+ new mozInlineSpellStatus{&aSpellChecker, eOpSelection, nullptr, nullptr,
+ nullptr, false, 0}};
+ return status;
+}
+
+// mozInlineSpellStatus::CreateForRange
+//
+// Called to cause the spellcheck of the given range. This will look like
+// a change operation over the given range.
+
+// static
+UniquePtr<mozInlineSpellStatus> mozInlineSpellStatus::CreateForRange(
+ mozInlineSpellChecker& aSpellChecker, nsRange* aRange) {
+ MOZ_LOG(sInlineSpellCheckerLog, LogLevel::Debug,
+ ("%s: range=%p", __FUNCTION__, aRange));
+
+ UniquePtr<mozInlineSpellStatus> status{
+ /* The constructor is `private`, hence the explicit allocation. */
+ new mozInlineSpellStatus{&aSpellChecker, eOpChange, nullptr, nullptr,
+ nullptr, false, 0}};
+
+ status->mRange = aRange;
+ return status;
+}
+
+// mozInlineSpellStatus::FinishInitOnEvent
+//
+// Called when the event is triggered to complete initialization that
+// might require the WordUtil. This calls to the operation-specific
+// initializer, and also sets the range to be the entire element if it
+// is nullptr.
+//
+// Watch out: the range might still be nullptr if there is nothing to do,
+// the caller will have to check for this.
+
+nsresult mozInlineSpellStatus::FinishInitOnEvent(
+ mozInlineSpellWordUtil& aWordUtil) {
+ MOZ_LOG(sInlineSpellCheckerLog, LogLevel::Verbose,
+ ("%s: mRange=%p", __FUNCTION__, mRange.get()));
+
+ nsresult rv;
+ if (!mRange) {
+ rv = mSpellChecker->MakeSpellCheckRange(nullptr, 0, nullptr, 0,
+ getter_AddRefs(mRange));
+ NS_ENSURE_SUCCESS(rv, rv);
+ }
+
+ switch (mOp) {
+ case eOpChange:
+ if (mAnchorRange) return FillNoCheckRangeFromAnchor(aWordUtil);
+ break;
+ case eOpChangeDelete:
+ if (mAnchorRange) {
+ rv = FillNoCheckRangeFromAnchor(aWordUtil);
+ NS_ENSURE_SUCCESS(rv, rv);
+ }
+ // Delete events will have no range for the changed text (because it was
+ // deleted), and CreateForEditorChange will set it to nullptr. Here, we
+ // select the entire word to cause any underlining to be removed.
+ mRange = mNoCheckRange;
+ break;
+ case eOpNavigation:
+ return FinishNavigationEvent(aWordUtil);
+ case eOpSelection:
+ // this gets special handling in ResumeCheck
+ break;
+ case eOpResume:
+ // everything should be initialized already in this case
+ break;
+ default:
+ MOZ_ASSERT_UNREACHABLE("Bad operation");
+ return NS_ERROR_NOT_INITIALIZED;
+ }
+ return NS_OK;
+}
+
+// mozInlineSpellStatus::FinishNavigationEvent
+//
+// This verifies that we need to check the word at the previous caret
+// position. Now that we have the word util, we can find the word belonging
+// to the previous caret position. If the new position is inside that word,
+// we don't want to do anything. In this case, we'll nullptr out mRange so
+// that the caller will know not to continue.
+//
+// Notice that we don't set mNoCheckRange. We check here whether the cursor
+// is in the word that needs checking, so it isn't necessary. Plus, the
+// spellchecker isn't guaranteed to only check the given word, and it could
+// remove the underline from the new word under the cursor.
+
+nsresult mozInlineSpellStatus::FinishNavigationEvent(
+ mozInlineSpellWordUtil& aWordUtil) {
+ MOZ_LOG(sInlineSpellCheckerLog, LogLevel::Verbose, ("%s", __FUNCTION__));
+
+ RefPtr<EditorBase> editorBase = mSpellChecker->mEditorBase;
+ if (!editorBase) {
+ return NS_ERROR_FAILURE; // editor is gone
+ }
+
+ MOZ_ASSERT(mAnchorRange, "No anchor for navigation!");
+
+ if (!mOldNavigationAnchorRange->IsPositioned()) {
+ return NS_ERROR_NOT_INITIALIZED;
+ }
+
+ // get the DOM position of the old caret, the range should be collapsed
+ nsCOMPtr<nsINode> oldAnchorNode =
+ mOldNavigationAnchorRange->GetStartContainer();
+ uint32_t oldAnchorOffset = mOldNavigationAnchorRange->StartOffset();
+
+ // find the word on the old caret position, this is the one that we MAY need
+ // to check
+ RefPtr<nsRange> oldWord;
+ nsresult rv = aWordUtil.GetRangeForWord(oldAnchorNode,
+ static_cast<int32_t>(oldAnchorOffset),
+ getter_AddRefs(oldWord));
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ // aWordUtil.GetRangeForWord flushes pending notifications, check editor
+ // again.
+ if (!mSpellChecker->mEditorBase) {
+ return NS_ERROR_FAILURE; // editor is gone
+ }
+
+ // get the DOM position of the new caret, the range should be collapsed
+ nsCOMPtr<nsINode> newAnchorNode = mAnchorRange->GetStartContainer();
+ uint32_t newAnchorOffset = mAnchorRange->StartOffset();
+
+ // see if the new cursor position is in the word of the old cursor position
+ bool isInRange = false;
+ if (!mForceNavigationWordCheck) {
+ ErrorResult err;
+ isInRange = oldWord->IsPointInRange(
+ *newAnchorNode, newAnchorOffset + mNewNavigationPositionOffset, err);
+ if (NS_WARN_IF(err.Failed())) {
+ return err.StealNSResult();
+ }
+ }
+
+ if (isInRange) {
+ // caller should give up
+ mRange = nullptr;
+ } else {
+ // check the old word
+ mRange = oldWord;
+
+ // Once we've spellchecked the current word, we don't need to spellcheck
+ // for any more navigation events.
+ mSpellChecker->mNeedsCheckAfterNavigation = false;
+ }
+ return NS_OK;
+}
+
+// mozInlineSpellStatus::FillNoCheckRangeFromAnchor
+//
+// Given the mAnchorRange object, computes the range of the word it is on
+// (if any) and fills that range into mNoCheckRange. This is used for
+// change and navigation events to know which word we should skip spell
+// checking on
+
+nsresult mozInlineSpellStatus::FillNoCheckRangeFromAnchor(
+ mozInlineSpellWordUtil& aWordUtil) {
+ MOZ_LOG(sInlineSpellCheckerLog, LogLevel::Verbose, ("%s", __FUNCTION__));
+
+ if (!mAnchorRange->IsPositioned()) {
+ return NS_ERROR_NOT_INITIALIZED;
+ }
+ nsCOMPtr<nsINode> anchorNode = mAnchorRange->GetStartContainer();
+ uint32_t anchorOffset = mAnchorRange->StartOffset();
+ return aWordUtil.GetRangeForWord(anchorNode,
+ static_cast<int32_t>(anchorOffset),
+ getter_AddRefs(mNoCheckRange));
+}
+
+// mozInlineSpellStatus::GetDocument
+//
+// Returns the Document object for the document for the
+// current spellchecker.
+
+Document* mozInlineSpellStatus::GetDocument() const {
+ if (!mSpellChecker->mEditorBase) {
+ return nullptr;
+ }
+
+ return mSpellChecker->mEditorBase->GetDocument();
+}
+
+// mozInlineSpellStatus::PositionToCollapsedRange
+//
+// Converts a given DOM position to a collapsed range covering that
+// position. We use ranges to store DOM positions becuase they stay
+// updated as the DOM is changed.
+
+// static
+already_AddRefed<nsRange> mozInlineSpellStatus::PositionToCollapsedRange(
+ nsINode* aNode, uint32_t aOffset) {
+ if (NS_WARN_IF(!aNode)) {
+ return nullptr;
+ }
+ IgnoredErrorResult ignoredError;
+ RefPtr<nsRange> range =
+ nsRange::Create(aNode, aOffset, aNode, aOffset, ignoredError);
+ NS_WARNING_ASSERTION(!ignoredError.Failed(),
+ "Creating collapsed range failed");
+ return range.forget();
+}
+
+// mozInlineSpellResume
+
+class mozInlineSpellResume : public Runnable {
+ public:
+ mozInlineSpellResume(UniquePtr<mozInlineSpellStatus>&& aStatus,
+ uint32_t aDisabledAsyncToken)
+ : Runnable("mozInlineSpellResume"),
+ mDisabledAsyncToken(aDisabledAsyncToken),
+ mStatus(std::move(aStatus)) {}
+
+ nsresult Post() {
+ nsCOMPtr<nsIRunnable> runnable(this);
+ return NS_DispatchToCurrentThreadQueue(runnable.forget(), 1000,
+ EventQueuePriority::Idle);
+ }
+
+ NS_IMETHOD Run() override {
+ // Discard the resumption if the spell checker was disabled after the
+ // resumption was scheduled.
+ if (mDisabledAsyncToken ==
+ mStatus->mSpellChecker->GetDisabledAsyncToken()) {
+ mStatus->mSpellChecker->ResumeCheck(std::move(mStatus));
+ }
+ return NS_OK;
+ }
+
+ private:
+ uint32_t mDisabledAsyncToken;
+ UniquePtr<mozInlineSpellStatus> mStatus;
+};
+
+// Used as the nsIEditorSpellCheck::InitSpellChecker callback.
+class InitEditorSpellCheckCallback final : public nsIEditorSpellCheckCallback {
+ ~InitEditorSpellCheckCallback() {}
+
+ public:
+ NS_DECL_ISUPPORTS
+
+ explicit InitEditorSpellCheckCallback(mozInlineSpellChecker* aSpellChecker)
+ : mSpellChecker(aSpellChecker) {}
+
+ NS_IMETHOD EditorSpellCheckDone() override {
+ return mSpellChecker ? mSpellChecker->EditorSpellCheckInited() : NS_OK;
+ }
+
+ void Cancel() { mSpellChecker = nullptr; }
+
+ private:
+ RefPtr<mozInlineSpellChecker> mSpellChecker;
+};
+NS_IMPL_ISUPPORTS(InitEditorSpellCheckCallback, nsIEditorSpellCheckCallback)
+
+NS_INTERFACE_MAP_BEGIN(mozInlineSpellChecker)
+ NS_INTERFACE_MAP_ENTRY(nsIInlineSpellChecker)
+ NS_INTERFACE_MAP_ENTRY(nsISupportsWeakReference)
+ NS_INTERFACE_MAP_ENTRY(nsIDOMEventListener)
+ NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIDOMEventListener)
+ NS_INTERFACE_MAP_ENTRIES_CYCLE_COLLECTION(mozInlineSpellChecker)
+NS_INTERFACE_MAP_END
+
+NS_IMPL_CYCLE_COLLECTING_ADDREF(mozInlineSpellChecker)
+NS_IMPL_CYCLE_COLLECTING_RELEASE(mozInlineSpellChecker)
+
+NS_IMPL_CYCLE_COLLECTION_WEAK(mozInlineSpellChecker, mEditorBase, mSpellCheck,
+ mCurrentSelectionAnchorNode)
+
+mozInlineSpellChecker::SpellCheckingState
+ mozInlineSpellChecker::gCanEnableSpellChecking =
+ mozInlineSpellChecker::SpellCheck_Uninitialized;
+
+mozInlineSpellChecker::mozInlineSpellChecker()
+ : mNumWordsInSpellSelection(0),
+ mMaxNumWordsInSpellSelection(
+ StaticPrefs::extensions_spellcheck_inline_max_misspellings()),
+ mNumPendingSpellChecks(0),
+ mNumPendingUpdateCurrentDictionary(0),
+ mDisabledAsyncToken(0),
+ mNeedsCheckAfterNavigation(false),
+ mFullSpellCheckScheduled(false),
+ mIsListeningToEditSubActions(false) {}
+
+mozInlineSpellChecker::~mozInlineSpellChecker() {}
+
+EditorSpellCheck* mozInlineSpellChecker::GetEditorSpellCheck() {
+ return mSpellCheck ? mSpellCheck : mPendingSpellCheck;
+}
+
+NS_IMETHODIMP
+mozInlineSpellChecker::GetSpellChecker(nsIEditorSpellCheck** aSpellCheck) {
+ *aSpellCheck = mSpellCheck;
+ NS_IF_ADDREF(*aSpellCheck);
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+mozInlineSpellChecker::Init(nsIEditor* aEditor) {
+ mEditorBase = aEditor ? aEditor->AsEditorBase() : nullptr;
+ return NS_OK;
+}
+
+// mozInlineSpellChecker::Cleanup
+//
+// Called by the editor when the editor is going away. This is important
+// because we remove listeners. We do NOT clean up anything else in this
+// function, because it can get called while DoSpellCheck is running!
+//
+// Getting the style information there can cause DOM notifications to be
+// flushed, which can cause editors to go away which will bring us here.
+// We can not do anything that will cause DoSpellCheck to freak out.
+
+MOZ_CAN_RUN_SCRIPT_BOUNDARY nsresult
+mozInlineSpellChecker::Cleanup(bool aDestroyingFrames) {
+ mNumWordsInSpellSelection = 0;
+ RefPtr<Selection> spellCheckSelection = GetSpellCheckSelection();
+ nsresult rv = NS_OK;
+ if (!spellCheckSelection) {
+ // Ensure we still unregister event listeners (but return a failure code)
+ UnregisterEventListeners();
+ rv = NS_ERROR_FAILURE;
+ } else {
+ if (!aDestroyingFrames) {
+ spellCheckSelection->RemoveAllRanges(IgnoreErrors());
+ }
+
+ rv = UnregisterEventListeners();
+ }
+
+ // Notify ENDED observers now. If we wait to notify as we normally do when
+ // these async operations finish, then in the meantime the editor may create
+ // another inline spell checker and cause more STARTED and ENDED
+ // notifications to be broadcast. Interleaved notifications for the same
+ // editor but different inline spell checkers could easily confuse
+ // observers. They may receive two consecutive STARTED notifications for
+ // example, which we guarantee will not happen.
+
+ RefPtr<EditorBase> editorBase = std::move(mEditorBase);
+ if (mPendingSpellCheck) {
+ // Cancel the pending editor spell checker initialization.
+ mPendingSpellCheck = nullptr;
+ mPendingInitEditorSpellCheckCallback->Cancel();
+ mPendingInitEditorSpellCheckCallback = nullptr;
+ ChangeNumPendingSpellChecks(-1, editorBase);
+ }
+
+ // Increment this token so that pending UpdateCurrentDictionary calls and
+ // scheduled spell checks are discarded when they finish.
+ mDisabledAsyncToken++;
+
+ if (mNumPendingUpdateCurrentDictionary > 0) {
+ // Account for pending UpdateCurrentDictionary calls.
+ ChangeNumPendingSpellChecks(-mNumPendingUpdateCurrentDictionary,
+ editorBase);
+ mNumPendingUpdateCurrentDictionary = 0;
+ }
+ if (mNumPendingSpellChecks > 0) {
+ // If mNumPendingSpellChecks is still > 0 at this point, the remainder is
+ // pending scheduled spell checks.
+ ChangeNumPendingSpellChecks(-mNumPendingSpellChecks, editorBase);
+ }
+
+ mFullSpellCheckScheduled = false;
+
+ return rv;
+}
+
+// mozInlineSpellChecker::CanEnableInlineSpellChecking
+//
+// This function can be called to see if it seems likely that we can enable
+// spellchecking before actually creating the InlineSpellChecking objects.
+//
+// The problem is that we can't get the dictionary list without actually
+// creating a whole bunch of spellchecking objects. This function tries to
+// do that and caches the result so we don't have to keep allocating those
+// objects if there are no dictionaries or spellchecking.
+//
+// Whenever dictionaries are added or removed at runtime, this value must be
+// updated before an observer notification is sent out about the change, to
+// avoid editors getting a wrong cached result.
+
+bool // static
+mozInlineSpellChecker::CanEnableInlineSpellChecking() {
+ if (gCanEnableSpellChecking == SpellCheck_Uninitialized) {
+ gCanEnableSpellChecking = SpellCheck_NotAvailable;
+
+ nsCOMPtr<nsIEditorSpellCheck> spellchecker = new EditorSpellCheck();
+
+ bool canSpellCheck = false;
+ nsresult rv = spellchecker->CanSpellCheck(&canSpellCheck);
+ NS_ENSURE_SUCCESS(rv, false);
+
+ if (canSpellCheck) gCanEnableSpellChecking = SpellCheck_Available;
+ }
+ return (gCanEnableSpellChecking == SpellCheck_Available);
+}
+
+void // static
+mozInlineSpellChecker::UpdateCanEnableInlineSpellChecking() {
+ gCanEnableSpellChecking = SpellCheck_Uninitialized;
+}
+
+// mozInlineSpellChecker::RegisterEventListeners
+//
+// The inline spell checker listens to mouse events and keyboard navigation
+// events.
+
+nsresult mozInlineSpellChecker::RegisterEventListeners() {
+ if (MOZ_UNLIKELY(NS_WARN_IF(!mEditorBase))) {
+ return NS_ERROR_FAILURE;
+ }
+
+ StartToListenToEditSubActions();
+
+ RefPtr<Document> doc = mEditorBase->GetDocument();
+ if (MOZ_UNLIKELY(NS_WARN_IF(!doc))) {
+ return NS_ERROR_FAILURE;
+ }
+ EventListenerManager* eventListenerManager =
+ doc->GetOrCreateListenerManager();
+ if (MOZ_UNLIKELY(NS_WARN_IF(!eventListenerManager))) {
+ return NS_ERROR_FAILURE;
+ }
+ eventListenerManager->AddEventListenerByType(
+ this, u"blur"_ns, TrustedEventsAtSystemGroupCapture());
+ eventListenerManager->AddEventListenerByType(
+ this, u"click"_ns, TrustedEventsAtSystemGroupCapture());
+ eventListenerManager->AddEventListenerByType(
+ this, u"keydown"_ns, TrustedEventsAtSystemGroupCapture());
+ return NS_OK;
+}
+
+// mozInlineSpellChecker::UnregisterEventListeners
+
+nsresult mozInlineSpellChecker::UnregisterEventListeners() {
+ if (MOZ_UNLIKELY(NS_WARN_IF(!mEditorBase))) {
+ return NS_ERROR_FAILURE;
+ }
+
+ EndListeningToEditSubActions();
+
+ RefPtr<Document> doc = mEditorBase->GetDocument();
+ if (MOZ_UNLIKELY(NS_WARN_IF(!doc))) {
+ return NS_ERROR_FAILURE;
+ }
+ EventListenerManager* eventListenerManager =
+ doc->GetOrCreateListenerManager();
+ if (MOZ_UNLIKELY(NS_WARN_IF(!eventListenerManager))) {
+ return NS_ERROR_FAILURE;
+ }
+ eventListenerManager->RemoveEventListenerByType(
+ this, u"blur"_ns, TrustedEventsAtSystemGroupCapture());
+ eventListenerManager->RemoveEventListenerByType(
+ this, u"click"_ns, TrustedEventsAtSystemGroupCapture());
+ eventListenerManager->RemoveEventListenerByType(
+ this, u"keydown"_ns, TrustedEventsAtSystemGroupCapture());
+ return NS_OK;
+}
+
+// mozInlineSpellChecker::GetEnableRealTimeSpell
+
+NS_IMETHODIMP
+mozInlineSpellChecker::GetEnableRealTimeSpell(bool* aEnabled) {
+ NS_ENSURE_ARG_POINTER(aEnabled);
+ *aEnabled = mSpellCheck != nullptr || mPendingSpellCheck != nullptr;
+ return NS_OK;
+}
+
+// mozInlineSpellChecker::SetEnableRealTimeSpell
+
+NS_IMETHODIMP
+mozInlineSpellChecker::SetEnableRealTimeSpell(bool aEnabled) {
+ if (!aEnabled) {
+ mSpellCheck = nullptr;
+ return Cleanup(false);
+ }
+
+ if (mSpellCheck) {
+ // spellcheck the current contents. SpellCheckRange doesn't supply a created
+ // range to DoSpellCheck, which in our case is the entire range. But this
+ // optimization doesn't matter because there is nothing in the spellcheck
+ // selection when starting, which triggers a better optimization.
+ return SpellCheckRange(nullptr);
+ }
+
+ if (mPendingSpellCheck) {
+ // The editor spell checker is already being initialized.
+ return NS_OK;
+ }
+
+ mPendingSpellCheck = new EditorSpellCheck();
+ mPendingSpellCheck->SetFilterType(nsIEditorSpellCheck::FILTERTYPE_MAIL);
+
+ mPendingInitEditorSpellCheckCallback = new InitEditorSpellCheckCallback(this);
+ nsresult rv = mPendingSpellCheck->InitSpellChecker(
+ mEditorBase, false, mPendingInitEditorSpellCheckCallback);
+ if (NS_FAILED(rv)) {
+ mPendingSpellCheck = nullptr;
+ mPendingInitEditorSpellCheckCallback = nullptr;
+ NS_ENSURE_SUCCESS(rv, rv);
+ }
+
+ ChangeNumPendingSpellChecks(1);
+
+ return NS_OK;
+}
+
+// Called when nsIEditorSpellCheck::InitSpellChecker completes.
+nsresult mozInlineSpellChecker::EditorSpellCheckInited() {
+ MOZ_ASSERT(mPendingSpellCheck, "Spell check should be pending!");
+
+ // spell checking is enabled, register our event listeners to track navigation
+ RegisterEventListeners();
+
+ mSpellCheck = mPendingSpellCheck;
+ mPendingSpellCheck = nullptr;
+ mPendingInitEditorSpellCheckCallback = nullptr;
+ ChangeNumPendingSpellChecks(-1);
+
+ // spellcheck the current contents. SpellCheckRange doesn't supply a created
+ // range to DoSpellCheck, which in our case is the entire range. But this
+ // optimization doesn't matter because there is nothing in the spellcheck
+ // selection when starting, which triggers a better optimization.
+ return SpellCheckRange(nullptr);
+}
+
+// Changes the number of pending spell checks by the given delta. If the number
+// becomes zero or nonzero, observers are notified. See NotifyObservers for
+// info on the aEditor parameter.
+void mozInlineSpellChecker::ChangeNumPendingSpellChecks(
+ int32_t aDelta, EditorBase* aEditorBase) {
+ int8_t oldNumPending = mNumPendingSpellChecks;
+ mNumPendingSpellChecks += aDelta;
+ MOZ_ASSERT(mNumPendingSpellChecks >= 0,
+ "Unbalanced ChangeNumPendingSpellChecks calls!");
+ if (oldNumPending == 0 && mNumPendingSpellChecks > 0) {
+ NotifyObservers(INLINESPELL_STARTED_TOPIC, aEditorBase);
+ } else if (oldNumPending > 0 && mNumPendingSpellChecks == 0) {
+ NotifyObservers(INLINESPELL_ENDED_TOPIC, aEditorBase);
+ }
+}
+
+// Broadcasts the given topic to observers. aEditor is passed to observers if
+// nonnull; otherwise mEditorBase is passed.
+void mozInlineSpellChecker::NotifyObservers(const char* aTopic,
+ EditorBase* aEditorBase) {
+ nsCOMPtr<nsIObserverService> os = mozilla::services::GetObserverService();
+ if (!os) return;
+ // XXX Do we need to grab the editor here? If it's necessary, each observer
+ // should do it instead.
+ RefPtr<EditorBase> editorBase = aEditorBase ? aEditorBase : mEditorBase.get();
+ os->NotifyObservers(static_cast<nsIEditor*>(editorBase.get()), aTopic,
+ nullptr);
+}
+
+// mozInlineSpellChecker::SpellCheckAfterEditorChange
+//
+// Called by the editor when nearly anything happens to change the content.
+//
+// The start and end positions specify a range for the thing that happened,
+// but these are usually nullptr, even when you'd think they would be useful
+// because you want the range (for example, pasting). We ignore them in
+// this case.
+
+nsresult mozInlineSpellChecker::SpellCheckAfterEditorChange(
+ EditSubAction aEditSubAction, Selection& aSelection,
+ nsINode* aPreviousSelectedNode, uint32_t aPreviousSelectedOffset,
+ nsINode* aStartNode, uint32_t aStartOffset, nsINode* aEndNode,
+ uint32_t aEndOffset) {
+ nsresult rv;
+ if (!mSpellCheck) return NS_OK; // disabling spell checking is not an error
+
+ // this means something has changed, and we never check the current word,
+ // therefore, we should spellcheck for subsequent caret navigations
+ mNeedsCheckAfterNavigation = true;
+
+ // the anchor node is the position of the caret
+ Result<UniquePtr<mozInlineSpellStatus>, nsresult> res =
+ mozInlineSpellStatus::CreateForEditorChange(
+ *this, aEditSubAction, aSelection.GetAnchorNode(),
+ aSelection.AnchorOffset(), aPreviousSelectedNode,
+ aPreviousSelectedOffset, aStartNode, aStartOffset, aEndNode,
+ aEndOffset);
+ if (NS_WARN_IF(res.isErr())) {
+ return res.unwrapErr();
+ }
+
+ rv = ScheduleSpellCheck(res.unwrap());
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ // remember the current caret position after every change
+ SaveCurrentSelectionPosition();
+ return NS_OK;
+}
+
+// mozInlineSpellChecker::SpellCheckRange
+//
+// Spellchecks all the words in the given range.
+// Supply a nullptr range and this will check the entire editor.
+
+nsresult mozInlineSpellChecker::SpellCheckRange(nsRange* aRange) {
+ if (!mSpellCheck) {
+ NS_WARNING_ASSERTION(
+ mPendingSpellCheck,
+ "Trying to spellcheck, but checking seems to be disabled");
+ return NS_ERROR_NOT_INITIALIZED;
+ }
+
+ UniquePtr<mozInlineSpellStatus> status =
+ mozInlineSpellStatus::CreateForRange(*this, aRange);
+ return ScheduleSpellCheck(std::move(status));
+}
+
+// mozInlineSpellChecker::GetMisspelledWord
+
+NS_IMETHODIMP
+mozInlineSpellChecker::GetMisspelledWord(nsINode* aNode, uint32_t aOffset,
+ nsRange** newword) {
+ if (NS_WARN_IF(!aNode)) {
+ return NS_ERROR_INVALID_ARG;
+ }
+ RefPtr<Selection> spellCheckSelection = GetSpellCheckSelection();
+ if (NS_WARN_IF(!spellCheckSelection)) {
+ return NS_ERROR_FAILURE;
+ }
+ return IsPointInSelection(*spellCheckSelection, aNode, aOffset, newword);
+}
+
+// mozInlineSpellChecker::ReplaceWord
+
+NS_IMETHODIMP
+mozInlineSpellChecker::ReplaceWord(nsINode* aNode, uint32_t aOffset,
+ const nsAString& aNewWord) {
+ if (NS_WARN_IF(!mEditorBase) || NS_WARN_IF(aNewWord.IsEmpty())) {
+ return NS_ERROR_FAILURE;
+ }
+
+ RefPtr<nsRange> range;
+ nsresult res = GetMisspelledWord(aNode, aOffset, getter_AddRefs(range));
+ NS_ENSURE_SUCCESS(res, res);
+
+ if (!range) {
+ return NS_OK;
+ }
+
+ // In usual cases, any words shouldn't include line breaks, but technically,
+ // they may include and we need to avoid `HTMLTextAreaElement.value` returns
+ // \r. Therefore, we need to handle it here.
+ nsString newWord(aNewWord);
+ if (mEditorBase->IsTextEditor()) {
+ nsContentUtils::PlatformToDOMLineBreaks(newWord);
+ }
+
+ // Blink dispatches cancelable `beforeinput` event at collecting misspelled
+ // word so that we should allow to dispatch cancelable event.
+ RefPtr<EditorBase> editorBase(mEditorBase);
+ DebugOnly<nsresult> rv = editorBase->ReplaceTextAsAction(
+ newWord, range, EditorBase::AllowBeforeInputEventCancelable::Yes);
+ NS_WARNING_ASSERTION(NS_SUCCEEDED(rv), "Failed to insert the new word");
+ return NS_OK;
+}
+
+// mozInlineSpellChecker::AddWordToDictionary
+
+NS_IMETHODIMP
+mozInlineSpellChecker::AddWordToDictionary(const nsAString& word) {
+ NS_ENSURE_TRUE(mSpellCheck, NS_ERROR_NOT_INITIALIZED);
+
+ nsresult rv = mSpellCheck->AddWordToDictionary(word);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ UniquePtr<mozInlineSpellStatus> status =
+ mozInlineSpellStatus::CreateForSelection(*this);
+ return ScheduleSpellCheck(std::move(status));
+}
+
+// mozInlineSpellChecker::RemoveWordFromDictionary
+
+NS_IMETHODIMP
+mozInlineSpellChecker::RemoveWordFromDictionary(const nsAString& word) {
+ NS_ENSURE_TRUE(mSpellCheck, NS_ERROR_NOT_INITIALIZED);
+
+ nsresult rv = mSpellCheck->RemoveWordFromDictionary(word);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ UniquePtr<mozInlineSpellStatus> status =
+ mozInlineSpellStatus::CreateForRange(*this, nullptr);
+ return ScheduleSpellCheck(std::move(status));
+}
+
+// mozInlineSpellChecker::IgnoreWord
+
+NS_IMETHODIMP
+mozInlineSpellChecker::IgnoreWord(const nsAString& word) {
+ NS_ENSURE_TRUE(mSpellCheck, NS_ERROR_NOT_INITIALIZED);
+
+ nsresult rv = mSpellCheck->IgnoreWordAllOccurrences(word);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ UniquePtr<mozInlineSpellStatus> status =
+ mozInlineSpellStatus::CreateForSelection(*this);
+ return ScheduleSpellCheck(std::move(status));
+}
+
+// mozInlineSpellChecker::IgnoreWords
+
+NS_IMETHODIMP
+mozInlineSpellChecker::IgnoreWords(const nsTArray<nsString>& aWordsToIgnore) {
+ NS_ENSURE_TRUE(mSpellCheck, NS_ERROR_NOT_INITIALIZED);
+
+ // add each word to the ignore list and then recheck the document
+ for (auto& word : aWordsToIgnore) {
+ mSpellCheck->IgnoreWordAllOccurrences(word);
+ }
+
+ UniquePtr<mozInlineSpellStatus> status =
+ mozInlineSpellStatus::CreateForSelection(*this);
+ return ScheduleSpellCheck(std::move(status));
+}
+
+// mozInlineSpellChecker::MakeSpellCheckRange
+//
+// Given begin and end positions, this function constructs a range as
+// required for ScheduleSpellCheck. If the start and end nodes are nullptr,
+// then the entire range will be selected, and you can supply -1 as the
+// offset to the end range to select all of that node.
+//
+// If the resulting range would be empty, nullptr is put into *aRange and the
+// function succeeds.
+
+nsresult mozInlineSpellChecker::MakeSpellCheckRange(nsINode* aStartNode,
+ int32_t aStartOffset,
+ nsINode* aEndNode,
+ int32_t aEndOffset,
+ nsRange** aRange) const {
+ nsresult rv;
+ *aRange = nullptr;
+
+ if (NS_WARN_IF(!mEditorBase)) {
+ return NS_ERROR_FAILURE;
+ }
+
+ RefPtr<Document> doc = mEditorBase->GetDocument();
+ if (NS_WARN_IF(!doc)) {
+ return NS_ERROR_FAILURE;
+ }
+
+ RefPtr<nsRange> range = nsRange::Create(doc);
+
+ // possibly use full range of the editor
+ if (!aStartNode || !aEndNode) {
+ Element* domRootElement = mEditorBase->GetRoot();
+ if (NS_WARN_IF(!domRootElement)) {
+ return NS_ERROR_FAILURE;
+ }
+ aStartNode = aEndNode = domRootElement;
+ aStartOffset = 0;
+ aEndOffset = -1;
+ }
+
+ if (aEndOffset == -1) {
+ // It's hard to say whether it's better to just do nsINode::GetChildCount or
+ // get the ChildNodes() and then its length. The latter is faster if we
+ // keep going through this code for the same nodes (because it caches the
+ // length). The former is faster if we keep getting different nodes here...
+ //
+ // Let's do the thing which can't end up with bad O(N^2) behavior.
+ aEndOffset = aEndNode->ChildNodes()->Length();
+ }
+
+ // sometimes we are are requested to check an empty range (possibly an empty
+ // document). This will result in assertions later.
+ if (aStartNode == aEndNode && aStartOffset == aEndOffset) return NS_OK;
+
+ if (aEndOffset) {
+ rv = range->SetStartAndEnd(aStartNode, aStartOffset, aEndNode, aEndOffset);
+ if (NS_WARN_IF(NS_FAILED(rv))) {
+ return rv;
+ }
+ } else {
+ rv = range->SetStartAndEnd(RawRangeBoundary(aStartNode, aStartOffset),
+ RangeUtils::GetRawRangeBoundaryAfter(aEndNode));
+ if (NS_WARN_IF(NS_FAILED(rv))) {
+ return rv;
+ }
+ }
+
+ range.swap(*aRange);
+ return NS_OK;
+}
+
+nsresult mozInlineSpellChecker::SpellCheckBetweenNodes(nsINode* aStartNode,
+ int32_t aStartOffset,
+ nsINode* aEndNode,
+ int32_t aEndOffset) {
+ RefPtr<nsRange> range;
+ nsresult rv = MakeSpellCheckRange(aStartNode, aStartOffset, aEndNode,
+ aEndOffset, getter_AddRefs(range));
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ if (!range) return NS_OK; // range is empty: nothing to do
+
+ UniquePtr<mozInlineSpellStatus> status =
+ mozInlineSpellStatus::CreateForRange(*this, range);
+ return ScheduleSpellCheck(std::move(status));
+}
+
+// mozInlineSpellChecker::ShouldSpellCheckNode
+//
+// There are certain conditions when we don't want to spell check a node. In
+// particular quotations, moz signatures, etc. This routine returns false
+// for these cases.
+
+// static
+bool mozInlineSpellChecker::ShouldSpellCheckNode(EditorBase* aEditorBase,
+ nsINode* aNode) {
+ MOZ_ASSERT(aNode);
+ if (!aNode->IsContent()) return false;
+
+ nsIContent* content = aNode->AsContent();
+
+ if (aEditorBase->IsMailEditor()) {
+ nsIContent* parent = content->GetParent();
+ while (parent) {
+ if (parent->IsHTMLElement(nsGkAtoms::blockquote) &&
+ parent->AsElement()->AttrValueIs(kNameSpaceID_None, nsGkAtoms::type,
+ nsGkAtoms::cite, eIgnoreCase)) {
+ return false;
+ }
+ if (parent->IsAnyOfHTMLElements(nsGkAtoms::pre, nsGkAtoms::div) &&
+ parent->AsElement()->AttrValueIs(kNameSpaceID_None, nsGkAtoms::_class,
+ nsGkAtoms::mozsignature,
+ eIgnoreCase)) {
+ return false;
+ }
+ if (parent->IsHTMLElement(nsGkAtoms::div) &&
+ parent->AsElement()->AttrValueIs(kNameSpaceID_None, nsGkAtoms::_class,
+ nsGkAtoms::mozfwcontainer,
+ eIgnoreCase)) {
+ return false;
+ }
+
+ parent = parent->GetParent();
+ }
+ } else {
+ // Check spelling only if the node is editable, and GetSpellcheck() is true
+ // on the nearest HTMLElement ancestor.
+ if (!content->IsEditable()) {
+ return false;
+ }
+
+ // Make sure that we can always turn on spell checking for inputs/textareas.
+ // Note that because of the previous check, at this point we know that the
+ // node is editable.
+ if (content->IsInNativeAnonymousSubtree()) {
+ nsIContent* node = content->GetParent();
+ while (node && node->IsInNativeAnonymousSubtree()) {
+ node = node->GetParent();
+ }
+ if (node && node->IsTextControlElement()) {
+ return true;
+ }
+ }
+
+ // Get HTML element ancestor (might be aNode itself, although probably that
+ // has to be a text node in real life here)
+ nsIContent* parent = content;
+ while (!parent->IsHTMLElement()) {
+ parent = parent->GetParent();
+ if (!parent) {
+ return true;
+ }
+ }
+
+ // See if it's spellcheckable
+ return static_cast<nsGenericHTMLElement*>(parent)->Spellcheck();
+ }
+
+ return true;
+}
+
+// mozInlineSpellChecker::ScheduleSpellCheck
+//
+// This is called by code to do the actual spellchecking. We will set up
+// the proper structures for calls to DoSpellCheck.
+
+nsresult mozInlineSpellChecker::ScheduleSpellCheck(
+ UniquePtr<mozInlineSpellStatus>&& aStatus) {
+ MOZ_LOG(sInlineSpellCheckerLog, LogLevel::Debug,
+ ("%s: mFullSpellCheckScheduled=%i", __FUNCTION__,
+ mFullSpellCheckScheduled));
+
+ if (mFullSpellCheckScheduled) {
+ // Just ignore this; we're going to spell-check everything anyway
+ return NS_OK;
+ }
+ // Cache the value because we are going to move aStatus's ownership to
+ // the new created mozInlineSpellResume instance.
+ bool isFullSpellCheck = aStatus->IsFullSpellCheck();
+
+ RefPtr<mozInlineSpellResume> resume =
+ new mozInlineSpellResume(std::move(aStatus), mDisabledAsyncToken);
+ NS_ENSURE_TRUE(resume, NS_ERROR_OUT_OF_MEMORY);
+
+ nsresult rv = resume->Post();
+ if (NS_SUCCEEDED(rv)) {
+ if (isFullSpellCheck) {
+ // We're going to check everything. Suppress further spell-check attempts
+ // until that happens.
+ mFullSpellCheckScheduled = true;
+ }
+ ChangeNumPendingSpellChecks(1);
+ }
+ return rv;
+}
+
+// mozInlineSpellChecker::DoSpellCheckSelection
+//
+// Called to re-check all misspelled words. We iterate over all ranges in
+// the selection and call DoSpellCheck on them. This is used when a word
+// is ignored or added to the dictionary: all instances of that word should
+// be removed from the selection.
+//
+// FIXME-PERFORMANCE: This takes as long as it takes and is not resumable.
+// Typically, checking this small amount of text is relatively fast, but
+// for large numbers of words, a lag may be noticeable.
+
+nsresult mozInlineSpellChecker::DoSpellCheckSelection(
+ mozInlineSpellWordUtil& aWordUtil, Selection* aSpellCheckSelection) {
+ nsresult rv;
+
+ // clear out mNumWordsInSpellSelection since we'll be rebuilding the ranges.
+ mNumWordsInSpellSelection = 0;
+
+ // Since we could be modifying the ranges for the spellCheckSelection while
+ // looping on the spell check selection, keep a separate array of range
+ // elements inside the selection
+ nsTArray<RefPtr<nsRange>> ranges;
+
+ const uint32_t rangeCount = aSpellCheckSelection->RangeCount();
+ for (const uint32_t idx : IntegerRange(rangeCount)) {
+ MOZ_ASSERT(aSpellCheckSelection->RangeCount() == rangeCount);
+ nsRange* range = aSpellCheckSelection->GetRangeAt(idx);
+ MOZ_ASSERT(range);
+ if (MOZ_LIKELY(range)) {
+ ranges.AppendElement(range);
+ }
+ }
+
+ // We have saved the ranges above. Clearing the spellcheck selection here
+ // isn't necessary (rechecking each word will modify it as necessary) but
+ // provides better performance. By ensuring that no ranges need to be
+ // removed in DoSpellCheck, we can save checking range inclusion which is
+ // slow.
+ aSpellCheckSelection->RemoveAllRanges(IgnoreErrors());
+
+ // We use this state object for all calls, and just update its range. Note
+ // that we don't need to call FinishInit since we will be filling in the
+ // necessary information.
+ UniquePtr<mozInlineSpellStatus> status =
+ mozInlineSpellStatus::CreateForRange(*this, nullptr);
+
+ bool doneChecking;
+ for (uint32_t idx : IntegerRange(rangeCount)) {
+ // We can consider this word as "added" since we know it has no spell
+ // check range over it that needs to be deleted. All the old ranges
+ // were cleared above. We also need to clear the word count so that we
+ // check all words instead of stopping early.
+ status->mRange = ranges[idx];
+ rv = DoSpellCheck(aWordUtil, aSpellCheckSelection, status, &doneChecking);
+ NS_ENSURE_SUCCESS(rv, rv);
+ MOZ_ASSERT(
+ doneChecking,
+ "We gave the spellchecker one word, but it didn't finish checking?!?!");
+ }
+
+ return NS_OK;
+}
+
+class MOZ_STACK_CLASS mozInlineSpellChecker::SpellCheckerSlice {
+ public:
+ /**
+ * @param aStatus must be non-nullptr.
+ */
+ SpellCheckerSlice(mozInlineSpellChecker& aInlineSpellChecker,
+ mozInlineSpellWordUtil& aWordUtil,
+ mozilla::dom::Selection& aSpellCheckSelection,
+ const mozilla::UniquePtr<mozInlineSpellStatus>& aStatus,
+ bool& aDoneChecking)
+ : mInlineSpellChecker{aInlineSpellChecker},
+ mWordUtil{aWordUtil},
+ mSpellCheckSelection{aSpellCheckSelection},
+ mStatus{aStatus},
+ mDoneChecking{aDoneChecking} {
+ MOZ_ASSERT(aStatus);
+ }
+
+ [[nodiscard]] nsresult Execute();
+
+ private:
+ // Creates an async request to check the words and update the ranges for the
+ // misspellings.
+ //
+ // @param aWords normalized words corresponding to aNodeOffsetRangesForWords.
+ // @param aOldRangesForSomeWords ranges from previous spellcheckings which
+ // might need to be removed. Its length might
+ // differ from `aWords.Length()`.
+ // @param aNodeOffsetRangesForWords One range for each word in aWords. So
+ // `aNodeOffsetRangesForWords.Length() ==
+ // aWords.Length()`.
+ void CheckWordsAndUpdateRangesForMisspellings(
+ const nsTArray<nsString>& aWords,
+ nsTArray<RefPtr<nsRange>>&& aOldRangesForSomeWords,
+ nsTArray<NodeOffsetRange>&& aNodeOffsetRangesForWords);
+
+ void RemoveRanges(const nsTArray<RefPtr<nsRange>>& aRanges);
+
+ bool ShouldSpellCheckRange(const nsRange& aRange) const;
+
+ bool IsInNoCheckRange(const nsINode& aNode, int32_t aOffset) const;
+
+ mozInlineSpellChecker& mInlineSpellChecker;
+ mozInlineSpellWordUtil& mWordUtil;
+ mozilla::dom::Selection& mSpellCheckSelection;
+ const mozilla::UniquePtr<mozInlineSpellStatus>& mStatus;
+ bool& mDoneChecking;
+};
+
+bool mozInlineSpellChecker::SpellCheckerSlice::ShouldSpellCheckRange(
+ const nsRange& aRange) const {
+ if (aRange.Collapsed()) {
+ return false;
+ }
+
+ nsINode* beginNode = aRange.GetStartContainer();
+ nsINode* endNode = aRange.GetEndContainer();
+
+ const nsINode* rootNode = mWordUtil.GetRootNode();
+ return beginNode->IsInComposedDoc() && endNode->IsInComposedDoc() &&
+ beginNode->IsShadowIncludingInclusiveDescendantOf(rootNode) &&
+ endNode->IsShadowIncludingInclusiveDescendantOf(rootNode);
+}
+
+bool mozInlineSpellChecker::SpellCheckerSlice::IsInNoCheckRange(
+ const nsINode& aNode, int32_t aOffset) const {
+ ErrorResult erv;
+ return mStatus->GetNoCheckRange() &&
+ mStatus->GetNoCheckRange()->IsPointInRange(aNode, aOffset, erv);
+}
+
+void mozInlineSpellChecker::SpellCheckerSlice::RemoveRanges(
+ const nsTArray<RefPtr<nsRange>>& aRanges) {
+ for (uint32_t i = 0; i < aRanges.Length(); i++) {
+ mInlineSpellChecker.RemoveRange(&mSpellCheckSelection, aRanges[i]);
+ }
+}
+
+// mozInlineSpellChecker::SpellCheckerSlice::Execute
+//
+// This function checks words intersecting the given range, excluding those
+// inside mStatus->mNoCheckRange (can be nullptr). Words inside aNoCheckRange
+// will have any spell selection removed (this is used to hide the
+// underlining for the word that the caret is in). aNoCheckRange should be
+// on word boundaries.
+//
+// mResume->mCreatedRange is a possibly nullptr range of new text that was
+// inserted. Inside this range, we don't bother to check whether things are
+// inside the spellcheck selection, which speeds up large paste operations
+// considerably.
+//
+// Normal case when editing text by typing
+// h e l l o w o r k d h o w a r e y o u
+// ^ caret
+// [-------] mRange
+// [-------] mNoCheckRange
+// -> does nothing (range is the same as the no check range)
+//
+// Case when pasting:
+// [---------- pasted text ----------]
+// h e l l o w o r k d h o w a r e y o u
+// ^ caret
+// [---] aNoCheckRange
+// -> recheck all words in range except those in aNoCheckRange
+//
+// If checking is complete, *aDoneChecking will be set. If there is more
+// but we ran out of time, this will be false and the range will be
+// updated with the stuff that still needs checking.
+
+nsresult mozInlineSpellChecker::SpellCheckerSlice::Execute() {
+ MOZ_LOG(sInlineSpellCheckerLog, LogLevel::Debug, ("%s", __FUNCTION__));
+
+ mDoneChecking = true;
+
+ if (NS_WARN_IF(!mInlineSpellChecker.mSpellCheck)) {
+ return NS_ERROR_NOT_INITIALIZED;
+ }
+
+ if (mInlineSpellChecker.IsSpellCheckSelectionFull()) {
+ return NS_OK;
+ }
+
+ // get the editor for ShouldSpellCheckNode, this may fail in reasonable
+ // circumstances since the editor could have gone away
+ RefPtr<EditorBase> editorBase = mInlineSpellChecker.mEditorBase;
+ if (!editorBase || editorBase->Destroyed()) {
+ return NS_ERROR_FAILURE;
+ }
+
+ if (!ShouldSpellCheckRange(*mStatus->mRange)) {
+ // Just bail out and don't try to spell-check this
+ return NS_OK;
+ }
+
+ // see if the selection has any ranges, if not, then we can optimize checking
+ // range inclusion later (we have no ranges when we are initially checking or
+ // when there are no misspelled words yet).
+ const int32_t originalRangeCount = mSpellCheckSelection.RangeCount();
+
+ // set the starting DOM position to be the beginning of our range
+ if (nsresult rv = mWordUtil.SetPositionAndEnd(
+ mStatus->mRange->GetStartContainer(), mStatus->mRange->StartOffset(),
+ mStatus->mRange->GetEndContainer(), mStatus->mRange->EndOffset());
+ NS_FAILED(rv)) {
+ // Just bail out and don't try to spell-check this
+ return NS_OK;
+ }
+
+ // aWordUtil.SetPosition flushes pending notifications, check editor again.
+ if (!mInlineSpellChecker.mEditorBase) {
+ return NS_ERROR_FAILURE;
+ }
+
+ int32_t wordsChecked = 0;
+ PRTime beginTime = PR_Now();
+
+ nsTArray<nsString> normalizedWords;
+ nsTArray<RefPtr<nsRange>> oldRangesToRemove;
+ nsTArray<NodeOffsetRange> checkRanges;
+ mozInlineSpellWordUtil::Word word;
+ static const size_t requestChunkSize =
+ INLINESPELL_MAXIMUM_CHUNKED_WORDS_PER_TASK;
+
+ while (mWordUtil.GetNextWord(word)) {
+ // get the range for the current word.
+ nsINode* const beginNode = word.mNodeOffsetRange.Begin().Node();
+ nsINode* const endNode = word.mNodeOffsetRange.End().Node();
+ // TODO: Make them `uint32_t`
+ const int32_t beginOffset = word.mNodeOffsetRange.Begin().Offset();
+ const int32_t endOffset = word.mNodeOffsetRange.End().Offset();
+
+ // see if we've done enough words in this round and run out of time.
+ if (wordsChecked >= INLINESPELL_MINIMUM_WORDS_BEFORE_TIMEOUT &&
+ PR_Now() > PRTime(beginTime + kMaxSpellCheckTimeInUsec)) {
+ // stop checking, our time limit has been exceeded.
+ MOZ_LOG(
+ sInlineSpellCheckerLog, LogLevel::Verbose,
+ ("%s: we have run out of time, schedule next round.", __FUNCTION__));
+
+ CheckWordsAndUpdateRangesForMisspellings(normalizedWords,
+ std::move(oldRangesToRemove),
+ std::move(checkRanges));
+
+ // move the range to encompass the stuff that needs checking.
+ nsresult rv = mStatus->mRange->SetStart(
+ beginNode, AssertedCast<uint32_t>(beginOffset));
+ if (NS_FAILED(rv)) {
+ // The range might be unhappy because the beginning is after the
+ // end. This is possible when the requested end was in the middle
+ // of a word, just ignore this situation and assume we're done.
+ return NS_OK;
+ }
+ mDoneChecking = false;
+ return NS_OK;
+ }
+
+ MOZ_LOG(sInlineSpellCheckerLog, LogLevel::Debug,
+ ("%s: got word \"%s\"%s", __FUNCTION__,
+ NS_ConvertUTF16toUTF8(word.mText).get(),
+ word.mSkipChecking ? " (not checking)" : ""));
+
+ // see if there is a spellcheck range that already intersects the word
+ // and remove it. We only need to remove old ranges, so don't bother if
+ // there were no ranges when we started out.
+ if (originalRangeCount > 0) {
+ ErrorResult erv;
+ // likewise, if this word is inside new text, we won't bother testing
+ if (!mStatus->GetCreatedRange() ||
+ !mStatus->GetCreatedRange()->IsPointInRange(
+ *beginNode, AssertedCast<uint32_t>(beginOffset), erv)) {
+ MOZ_LOG(sInlineSpellCheckerLog, LogLevel::Debug,
+ ("%s: removing ranges for some interval.", __FUNCTION__));
+
+ nsTArray<RefPtr<nsRange>> ranges;
+ mSpellCheckSelection.GetRangesForInterval(
+ *beginNode, AssertedCast<uint32_t>(beginOffset), *endNode,
+ AssertedCast<uint32_t>(endOffset), true, ranges, erv);
+ ENSURE_SUCCESS(erv, erv.StealNSResult());
+ oldRangesToRemove.AppendElements(std::move(ranges));
+ }
+ }
+
+ // some words are special and don't need checking
+ if (word.mSkipChecking) {
+ continue;
+ }
+
+ // some nodes we don't spellcheck
+ if (!mozInlineSpellChecker::ShouldSpellCheckNode(editorBase, beginNode)) {
+ continue;
+ }
+
+ // Don't check spelling if we're inside the noCheckRange. This needs to
+ // be done after we clear any old selection because the excluded word
+ // might have been previously marked.
+ //
+ // We do a simple check to see if the beginning of our word is in the
+ // exclusion range. Because the exclusion range is a multiple of a word,
+ // this is sufficient.
+ if (IsInNoCheckRange(*beginNode, beginOffset)) {
+ continue;
+ }
+
+ // check spelling and add to selection if misspelled
+ mozInlineSpellWordUtil::NormalizeWord(word.mText);
+ normalizedWords.AppendElement(word.mText);
+ checkRanges.AppendElement(word.mNodeOffsetRange);
+ wordsChecked++;
+ if (normalizedWords.Length() >= requestChunkSize) {
+ CheckWordsAndUpdateRangesForMisspellings(normalizedWords,
+ std::move(oldRangesToRemove),
+ std::move(checkRanges));
+ normalizedWords.Clear();
+ oldRangesToRemove = {};
+ // Set new empty data for spellcheck range in DOM to avoid
+ // clang-tidy detection.
+ checkRanges = nsTArray<NodeOffsetRange>();
+ }
+ }
+
+ CheckWordsAndUpdateRangesForMisspellings(
+ normalizedWords, std::move(oldRangesToRemove), std::move(checkRanges));
+
+ return NS_OK;
+}
+
+nsresult mozInlineSpellChecker::DoSpellCheck(
+ mozInlineSpellWordUtil& aWordUtil, Selection* aSpellCheckSelection,
+ const UniquePtr<mozInlineSpellStatus>& aStatus, bool* aDoneChecking) {
+ MOZ_ASSERT(aDoneChecking);
+
+ SpellCheckerSlice spellCheckerSlice{*this, aWordUtil, *aSpellCheckSelection,
+ aStatus, *aDoneChecking};
+
+ return spellCheckerSlice.Execute();
+}
+
+// An RAII helper that calls ChangeNumPendingSpellChecks on destruction.
+class MOZ_RAII AutoChangeNumPendingSpellChecks final {
+ public:
+ explicit AutoChangeNumPendingSpellChecks(mozInlineSpellChecker* aSpellChecker,
+ int32_t aDelta)
+ : mSpellChecker(aSpellChecker), mDelta(aDelta) {}
+
+ ~AutoChangeNumPendingSpellChecks() {
+ mSpellChecker->ChangeNumPendingSpellChecks(mDelta);
+ }
+
+ private:
+ RefPtr<mozInlineSpellChecker> mSpellChecker;
+ int32_t mDelta;
+};
+
+void mozInlineSpellChecker::SpellCheckerSlice::
+ CheckWordsAndUpdateRangesForMisspellings(
+ const nsTArray<nsString>& aWords,
+ nsTArray<RefPtr<nsRange>>&& aOldRangesForSomeWords,
+ nsTArray<NodeOffsetRange>&& aNodeOffsetRangesForWords) {
+ MOZ_LOG(sInlineSpellCheckerLog, LogLevel::Verbose,
+ ("%s: aWords.Length()=%i", __FUNCTION__,
+ static_cast<int>(aWords.Length())));
+
+ MOZ_ASSERT(aWords.Length() == aNodeOffsetRangesForWords.Length());
+
+ // TODO:
+ // aOldRangesForSomeWords is sorted in the same order as aWords. Could be used
+ // to remove ranges more efficiently.
+
+ if (aWords.IsEmpty()) {
+ RemoveRanges(aOldRangesForSomeWords);
+ return;
+ }
+
+ mInlineSpellChecker.ChangeNumPendingSpellChecks(1);
+
+ RefPtr<mozInlineSpellChecker> inlineSpellChecker = &mInlineSpellChecker;
+ RefPtr<Selection> spellCheckerSelection = &mSpellCheckSelection;
+ uint32_t token = mInlineSpellChecker.mDisabledAsyncToken;
+ mInlineSpellChecker.mSpellCheck->CheckCurrentWordsNoSuggest(aWords)->Then(
+ GetMainThreadSerialEventTarget(), __func__,
+ [inlineSpellChecker, spellCheckerSelection,
+ nodeOffsetRangesForWords = std::move(aNodeOffsetRangesForWords),
+ oldRangesForSomeWords = std::move(aOldRangesForSomeWords),
+ token](const nsTArray<bool>& aIsMisspelled) {
+ if (token != inlineSpellChecker->GetDisabledAsyncToken()) {
+ // This result is never used
+ return;
+ }
+
+ if (!inlineSpellChecker->mEditorBase ||
+ inlineSpellChecker->mEditorBase->Destroyed()) {
+ return;
+ }
+
+ AutoChangeNumPendingSpellChecks pendingChecks(inlineSpellChecker, -1);
+
+ if (inlineSpellChecker->IsSpellCheckSelectionFull()) {
+ return;
+ }
+
+ inlineSpellChecker->UpdateRangesForMisspelledWords(
+ nodeOffsetRangesForWords, oldRangesForSomeWords, aIsMisspelled,
+ *spellCheckerSelection);
+ },
+ [inlineSpellChecker, token](nsresult aRv) {
+ if (!inlineSpellChecker->mEditorBase ||
+ inlineSpellChecker->mEditorBase->Destroyed()) {
+ return;
+ }
+
+ if (token != inlineSpellChecker->GetDisabledAsyncToken()) {
+ // This result is never used
+ return;
+ }
+
+ inlineSpellChecker->ChangeNumPendingSpellChecks(-1);
+ });
+}
+
+// mozInlineSpellChecker::ResumeCheck
+//
+// Called by the resume event when it fires. We will try to pick up where
+// the last resume left off.
+
+nsresult mozInlineSpellChecker::ResumeCheck(
+ UniquePtr<mozInlineSpellStatus>&& aStatus) {
+ MOZ_LOG(sInlineSpellCheckerLog, LogLevel::Debug, ("%s", __FUNCTION__));
+
+ // Observers should be notified that spell check has ended only after spell
+ // check is done below, but since there are many early returns in this method
+ // and the number of pending spell checks must be decremented regardless of
+ // whether the spell check actually happens, use this RAII object.
+ AutoChangeNumPendingSpellChecks autoChangeNumPending(this, -1);
+
+ if (aStatus->IsFullSpellCheck()) {
+ // Allow posting new spellcheck resume events from inside
+ // ResumeCheck, now that we're actually firing.
+ MOZ_ASSERT(mFullSpellCheckScheduled,
+ "How could this be false? The full spell check is "
+ "calling us!!");
+ mFullSpellCheckScheduled = false;
+ }
+
+ if (!mSpellCheck) return NS_OK; // spell checking has been turned off
+
+ if (!mEditorBase) {
+ return NS_OK;
+ }
+
+ Maybe<mozInlineSpellWordUtil> wordUtil{
+ mozInlineSpellWordUtil::Create(*mEditorBase)};
+ if (!wordUtil) {
+ return NS_OK; // editor doesn't like us, don't assert
+ }
+
+ RefPtr<Selection> spellCheckSelection = GetSpellCheckSelection();
+ if (NS_WARN_IF(!spellCheckSelection)) {
+ return NS_ERROR_FAILURE;
+ }
+
+ nsTArray<nsCString> currentDictionaries;
+ nsresult rv = mSpellCheck->GetCurrentDictionaries(currentDictionaries);
+ if (NS_FAILED(rv)) {
+ MOZ_LOG(sInlineSpellCheckerLog, LogLevel::Debug,
+ ("%s: no active dictionary.", __FUNCTION__));
+
+ // no active dictionary
+ for (const uint32_t index :
+ Reversed(IntegerRange(spellCheckSelection->RangeCount()))) {
+ RefPtr<nsRange> checkRange = spellCheckSelection->GetRangeAt(index);
+ if (MOZ_LIKELY(checkRange)) {
+ RemoveRange(spellCheckSelection, checkRange);
+ }
+ }
+ return NS_OK;
+ }
+
+ CleanupRangesInSelection(spellCheckSelection);
+
+ rv = aStatus->FinishInitOnEvent(*wordUtil);
+ NS_ENSURE_SUCCESS(rv, rv);
+ if (!aStatus->mRange) return NS_OK; // empty range, nothing to do
+
+ bool doneChecking = true;
+ if (aStatus->GetOperation() == mozInlineSpellStatus::eOpSelection)
+ rv = DoSpellCheckSelection(*wordUtil, spellCheckSelection);
+ else
+ rv = DoSpellCheck(*wordUtil, spellCheckSelection, aStatus, &doneChecking);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ if (!doneChecking) rv = ScheduleSpellCheck(std::move(aStatus));
+ return rv;
+}
+
+// mozInlineSpellChecker::IsPointInSelection
+//
+// Determines if a given (node,offset) point is inside the given
+// selection. If so, the specific range of the selection that
+// intersects is places in *aRange. (There may be multiple disjoint
+// ranges in a selection.)
+//
+// If there is no intersection, *aRange will be nullptr.
+
+// static
+nsresult mozInlineSpellChecker::IsPointInSelection(Selection& aSelection,
+ nsINode* aNode,
+ uint32_t aOffset,
+ nsRange** aRange) {
+ *aRange = nullptr;
+
+ nsTArray<nsRange*> ranges;
+ nsresult rv = aSelection.GetDynamicRangesForIntervalArray(
+ aNode, aOffset, aNode, aOffset, true, &ranges);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ if (ranges.Length() == 0) return NS_OK; // no matches
+
+ // there may be more than one range returned, and we don't know what do
+ // do with that, so just get the first one
+ NS_ADDREF(*aRange = ranges[0]);
+ return NS_OK;
+}
+
+nsresult mozInlineSpellChecker::CleanupRangesInSelection(
+ Selection* aSelection) {
+ // integrity check - remove ranges that have collapsed to nothing. This
+ // can happen if the node containing a highlighted word was removed.
+ if (!aSelection) return NS_ERROR_FAILURE;
+
+ // TODO: Rewrite this with reversed ranged-loop, it might make this simpler.
+ int64_t count = aSelection->RangeCount();
+ for (int64_t index = 0; index < count; index++) {
+ nsRange* checkRange = aSelection->GetRangeAt(static_cast<uint32_t>(index));
+ if (MOZ_LIKELY(checkRange)) {
+ if (checkRange->Collapsed()) {
+ RemoveRange(aSelection, checkRange);
+ index--;
+ count--;
+ }
+ }
+ }
+
+ return NS_OK;
+}
+
+// mozInlineSpellChecker::RemoveRange
+//
+// For performance reasons, we have an upper bound on the number of word
+// ranges in the spell check selection. When removing a range from the
+// selection, we need to decrement mNumWordsInSpellSelection
+
+nsresult mozInlineSpellChecker::RemoveRange(Selection* aSpellCheckSelection,
+ nsRange* aRange) {
+ MOZ_LOG(sInlineSpellCheckerLog, LogLevel::Debug, ("%s", __FUNCTION__));
+
+ NS_ENSURE_ARG_POINTER(aSpellCheckSelection);
+ NS_ENSURE_ARG_POINTER(aRange);
+
+ ErrorResult rv;
+ RefPtr<nsRange> range{aRange};
+ RefPtr<Selection> selection{aSpellCheckSelection};
+ selection->RemoveRangeAndUnselectFramesAndNotifyListeners(*range, rv);
+ if (!rv.Failed()) {
+ if (mNumWordsInSpellSelection) {
+ mNumWordsInSpellSelection--;
+ }
+#ifdef ACCESSIBILITY
+ if (nsAccessibilityService* accService = GetAccService()) {
+ accService->SpellCheckRangeChanged(*aRange);
+ }
+#endif
+ }
+
+ return rv.StealNSResult();
+}
+
+struct mozInlineSpellChecker::CompareRangeAndNodeOffsetRange {
+ static bool Equals(const RefPtr<nsRange>& aRange,
+ const NodeOffsetRange& aNodeOffsetRange) {
+ return aNodeOffsetRange == *aRange;
+ }
+};
+
+void mozInlineSpellChecker::UpdateRangesForMisspelledWords(
+ const nsTArray<NodeOffsetRange>& aNodeOffsetRangesForWords,
+ const nsTArray<RefPtr<nsRange>>& aOldRangesForSomeWords,
+ const nsTArray<bool>& aIsMisspelled, Selection& aSpellCheckerSelection) {
+ MOZ_LOG(sInlineSpellCheckerLog, LogLevel::Verbose, ("%s", __FUNCTION__));
+
+ MOZ_ASSERT(aNodeOffsetRangesForWords.Length() == aIsMisspelled.Length());
+
+ // When the spellchecker checks text containing words separated by "/", it may
+ // happen that some words checked in one timeslice, are checked again in a
+ // following timeslice. E.g. for "foo/baz/qwertz", it may happen that "foo"
+ // and "baz" are checked in one timeslice and two ranges are added for them.
+ // In the following timeslice "foo" and "baz" are checked again but since
+ // their corresponding ranges are already in the spellcheck-Selection
+ // they don't have to be added again and since "foo" and "baz" still contain
+ // spelling mistakes, they don't have to be removed.
+ //
+ // In this case, it's more efficient to keep the existing ranges.
+
+ AutoTArray<bool, INLINESPELL_MAXIMUM_CHUNKED_WORDS_PER_TASK>
+ oldRangesMarkedForRemoval;
+ for (size_t i = 0; i < aOldRangesForSomeWords.Length(); ++i) {
+ oldRangesMarkedForRemoval.AppendElement(true);
+ }
+
+ AutoTArray<bool, INLINESPELL_MAXIMUM_CHUNKED_WORDS_PER_TASK>
+ nodeOffsetRangesMarkedForAdding;
+ for (size_t i = 0; i < aNodeOffsetRangesForWords.Length(); ++i) {
+ nodeOffsetRangesMarkedForAdding.AppendElement(false);
+ }
+
+ for (size_t i = 0; i < aIsMisspelled.Length(); i++) {
+ if (!aIsMisspelled[i]) {
+ continue;
+ }
+
+ const NodeOffsetRange& nodeOffsetRange = aNodeOffsetRangesForWords[i];
+ const size_t indexOfOldRangeToKeep = aOldRangesForSomeWords.IndexOf(
+ nodeOffsetRange, 0, CompareRangeAndNodeOffsetRange{});
+ if (indexOfOldRangeToKeep != aOldRangesForSomeWords.NoIndex &&
+ aOldRangesForSomeWords[indexOfOldRangeToKeep]->IsInSelection(
+ aSpellCheckerSelection)) {
+ /** TODO: warn in case the old range doesn't
+ belong to the selection. This is not critical,
+ because other code can always remove them
+ before the actual spellchecking happens. */
+ MOZ_LOG(sInlineSpellCheckerLog, LogLevel::Verbose,
+ ("%s: reusing old range.", __FUNCTION__));
+
+ oldRangesMarkedForRemoval[indexOfOldRangeToKeep] = false;
+ } else {
+ nodeOffsetRangesMarkedForAdding[i] = true;
+ }
+ }
+
+ for (size_t i = 0; i < oldRangesMarkedForRemoval.Length(); ++i) {
+ if (oldRangesMarkedForRemoval[i]) {
+ RemoveRange(&aSpellCheckerSelection, aOldRangesForSomeWords[i]);
+ }
+ }
+
+ // Add ranges after removing the marked old ones, so that the Selection can
+ // become full again.
+ for (size_t i = 0; i < nodeOffsetRangesMarkedForAdding.Length(); ++i) {
+ if (nodeOffsetRangesMarkedForAdding[i]) {
+ RefPtr<nsRange> wordRange =
+ mozInlineSpellWordUtil::MakeRange(aNodeOffsetRangesForWords[i]);
+ // If we somehow can't make a range for this word, just ignore
+ // it.
+ if (wordRange) {
+ AddRange(&aSpellCheckerSelection, wordRange);
+ }
+ }
+ }
+}
+
+// mozInlineSpellChecker::AddRange
+//
+// For performance reasons, we have an upper bound on the number of word
+// ranges we'll add to the spell check selection. Once we reach that upper
+// bound, stop adding the ranges
+
+nsresult mozInlineSpellChecker::AddRange(Selection* aSpellCheckSelection,
+ nsRange* aRange) {
+ NS_ENSURE_ARG_POINTER(aSpellCheckSelection);
+ NS_ENSURE_ARG_POINTER(aRange);
+
+ nsresult rv = NS_OK;
+
+ if (!IsSpellCheckSelectionFull()) {
+ IgnoredErrorResult err;
+ aSpellCheckSelection->AddRangeAndSelectFramesAndNotifyListeners(*aRange,
+ err);
+ if (err.Failed()) {
+ rv = err.StealNSResult();
+ } else {
+ mNumWordsInSpellSelection++;
+#ifdef ACCESSIBILITY
+ if (nsAccessibilityService* accService = GetAccService()) {
+ accService->SpellCheckRangeChanged(*aRange);
+ }
+#endif
+ }
+ }
+
+ return rv;
+}
+
+already_AddRefed<Selection> mozInlineSpellChecker::GetSpellCheckSelection() {
+ if (NS_WARN_IF(!mEditorBase)) {
+ return nullptr;
+ }
+ RefPtr<Selection> selection =
+ mEditorBase->GetSelection(SelectionType::eSpellCheck);
+ if (!selection) {
+ return nullptr;
+ }
+ return selection.forget();
+}
+
+nsresult mozInlineSpellChecker::SaveCurrentSelectionPosition() {
+ if (NS_WARN_IF(!mEditorBase)) {
+ return NS_OK; // XXX Why NS_OK?
+ }
+
+ // figure out the old caret position based on the current selection
+ RefPtr<Selection> selection = mEditorBase->GetSelection();
+ if (NS_WARN_IF(!selection)) {
+ return NS_ERROR_FAILURE;
+ }
+
+ mCurrentSelectionAnchorNode = selection->GetFocusNode();
+ mCurrentSelectionOffset = selection->FocusOffset();
+
+ return NS_OK;
+}
+
+// mozInlineSpellChecker::HandleNavigationEvent
+//
+// Acts upon mouse clicks and keyboard navigation changes, spell checking
+// the previous word if the new navigation location moves us to another
+// word.
+//
+// This is complicated by the fact that our mouse events are happening after
+// selection has been changed to account for the mouse click. But keyboard
+// events are happening before the caret selection has changed. Working
+// around this by letting keyboard events setting forceWordSpellCheck to
+// true. aNewPositionOffset also tries to work around this for the
+// DOM_VK_RIGHT and DOM_VK_LEFT cases.
+
+nsresult mozInlineSpellChecker::HandleNavigationEvent(
+ bool aForceWordSpellCheck, int32_t aNewPositionOffset) {
+ nsresult rv;
+
+ // If we already handled the navigation event and there is no possibility
+ // anything has changed since then, we don't have to do anything. This
+ // optimization makes a noticeable difference when you hold down a navigation
+ // key like Page Down.
+ if (!mNeedsCheckAfterNavigation) return NS_OK;
+
+ nsCOMPtr<nsINode> currentAnchorNode = mCurrentSelectionAnchorNode;
+ uint32_t currentAnchorOffset = mCurrentSelectionOffset;
+
+ // now remember the new focus position resulting from the event
+ rv = SaveCurrentSelectionPosition();
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ bool shouldPost;
+ Result<UniquePtr<mozInlineSpellStatus>, nsresult> res =
+ mozInlineSpellStatus::CreateForNavigation(
+ *this, aForceWordSpellCheck, aNewPositionOffset, currentAnchorNode,
+ currentAnchorOffset, mCurrentSelectionAnchorNode,
+ mCurrentSelectionOffset, &shouldPost);
+
+ if (NS_WARN_IF(res.isErr())) {
+ return res.unwrapErr();
+ }
+
+ if (shouldPost) {
+ rv = ScheduleSpellCheck(res.unwrap());
+ NS_ENSURE_SUCCESS(rv, rv);
+ }
+
+ return NS_OK;
+}
+
+NS_IMETHODIMP mozInlineSpellChecker::HandleEvent(Event* aEvent) {
+ WidgetEvent* widgetEvent = aEvent->WidgetEventPtr();
+ if (MOZ_UNLIKELY(!widgetEvent)) {
+ return NS_OK;
+ }
+
+ switch (widgetEvent->mMessage) {
+ case eBlur:
+ OnBlur(*aEvent);
+ return NS_OK;
+ case eMouseClick:
+ OnMouseClick(*aEvent);
+ return NS_OK;
+ case eKeyDown:
+ OnKeyDown(*aEvent);
+ return NS_OK;
+ default:
+ MOZ_ASSERT_UNREACHABLE("You must forgot to handle new event type");
+ return NS_OK;
+ }
+}
+
+void mozInlineSpellChecker::OnBlur(Event& aEvent) {
+ // force spellcheck on blur, for instance when tabbing out of a textbox
+ HandleNavigationEvent(true);
+}
+
+void mozInlineSpellChecker::OnMouseClick(Event& aMouseEvent) {
+ MouseEvent* mouseEvent = aMouseEvent.AsMouseEvent();
+ if (MOZ_UNLIKELY(!mouseEvent)) {
+ return;
+ }
+
+ // ignore any errors from HandleNavigationEvent as we don't want to prevent
+ // anyone else from seeing this event.
+ HandleNavigationEvent(mouseEvent->Button() != 0);
+}
+
+void mozInlineSpellChecker::OnKeyDown(Event& aKeyEvent) {
+ WidgetKeyboardEvent* widgetKeyboardEvent =
+ aKeyEvent.WidgetEventPtr()->AsKeyboardEvent();
+ if (MOZ_UNLIKELY(!widgetKeyboardEvent)) {
+ return;
+ }
+
+ // we only care about navigation keys that moved selection
+ switch (widgetKeyboardEvent->mKeyNameIndex) {
+ case KEY_NAME_INDEX_ArrowRight:
+ // XXX Does this work with RTL text?
+ HandleNavigationEvent(false, 1);
+ return;
+ case KEY_NAME_INDEX_ArrowLeft:
+ // XXX Does this work with RTL text?
+ HandleNavigationEvent(false, -1);
+ return;
+ case KEY_NAME_INDEX_ArrowUp:
+ case KEY_NAME_INDEX_ArrowDown:
+ case KEY_NAME_INDEX_Home:
+ case KEY_NAME_INDEX_End:
+ case KEY_NAME_INDEX_PageDown:
+ case KEY_NAME_INDEX_PageUp:
+ HandleNavigationEvent(true /* force a spelling correction */);
+ return;
+ default:
+ return;
+ }
+}
+
+// Used as the nsIEditorSpellCheck::UpdateCurrentDictionary callback.
+class UpdateCurrentDictionaryCallback final
+ : public nsIEditorSpellCheckCallback {
+ public:
+ NS_DECL_ISUPPORTS
+
+ explicit UpdateCurrentDictionaryCallback(mozInlineSpellChecker* aSpellChecker,
+ uint32_t aDisabledAsyncToken)
+ : mSpellChecker(aSpellChecker),
+ mDisabledAsyncToken(aDisabledAsyncToken) {}
+
+ NS_IMETHOD EditorSpellCheckDone() override {
+ // Ignore this callback if SetEnableRealTimeSpell(false) was called after
+ // the UpdateCurrentDictionary call that triggered it.
+ return mSpellChecker->GetDisabledAsyncToken() > mDisabledAsyncToken
+ ? NS_OK
+ : mSpellChecker->CurrentDictionaryUpdated();
+ }
+
+ private:
+ ~UpdateCurrentDictionaryCallback() {}
+
+ RefPtr<mozInlineSpellChecker> mSpellChecker;
+ uint32_t mDisabledAsyncToken;
+};
+NS_IMPL_ISUPPORTS(UpdateCurrentDictionaryCallback, nsIEditorSpellCheckCallback)
+
+NS_IMETHODIMP mozInlineSpellChecker::UpdateCurrentDictionary() {
+ // mSpellCheck is null and mPendingSpellCheck is nonnull while the spell
+ // checker is being initialized. Calling UpdateCurrentDictionary on
+ // mPendingSpellCheck simply queues the dictionary update after the init.
+ RefPtr<EditorSpellCheck> spellCheck =
+ mSpellCheck ? mSpellCheck : mPendingSpellCheck;
+ if (!spellCheck) {
+ return NS_OK;
+ }
+
+ RefPtr<UpdateCurrentDictionaryCallback> cb =
+ new UpdateCurrentDictionaryCallback(this, mDisabledAsyncToken);
+ NS_ENSURE_STATE(cb);
+ nsresult rv = spellCheck->UpdateCurrentDictionary(cb);
+ if (NS_FAILED(rv)) {
+ cb = nullptr;
+ return rv;
+ }
+ mNumPendingUpdateCurrentDictionary++;
+ ChangeNumPendingSpellChecks(1);
+
+ return NS_OK;
+}
+
+// Called when nsIEditorSpellCheck::UpdateCurrentDictionary completes.
+nsresult mozInlineSpellChecker::CurrentDictionaryUpdated() {
+ mNumPendingUpdateCurrentDictionary--;
+ MOZ_ASSERT(mNumPendingUpdateCurrentDictionary >= 0,
+ "CurrentDictionaryUpdated called without corresponding "
+ "UpdateCurrentDictionary call!");
+ ChangeNumPendingSpellChecks(-1);
+
+ nsresult rv = SpellCheckRange(nullptr);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+mozInlineSpellChecker::GetSpellCheckPending(bool* aPending) {
+ *aPending = mNumPendingSpellChecks > 0;
+ return NS_OK;
+}
diff --git a/extensions/spellcheck/src/mozInlineSpellChecker.h b/extensions/spellcheck/src/mozInlineSpellChecker.h
new file mode 100644
index 0000000000..0e304c93a2
--- /dev/null
+++ b/extensions/spellcheck/src/mozInlineSpellChecker.h
@@ -0,0 +1,338 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef mozilla_mozInlineSpellChecker_h
+#define mozilla_mozInlineSpellChecker_h
+
+#include "nsCycleCollectionParticipant.h"
+#include "nsIDOMEventListener.h"
+#include "nsIEditorSpellCheck.h"
+#include "nsIInlineSpellChecker.h"
+#include "mozInlineSpellWordUtil.h"
+#include "mozilla/EditorDOMPoint.h"
+#include "mozilla/Result.h"
+#include "nsRange.h"
+#include "nsWeakReference.h"
+
+class InitEditorSpellCheckCallback;
+class mozInlineSpellChecker;
+class mozInlineSpellResume;
+class UpdateCurrentDictionaryCallback;
+
+namespace mozilla {
+class EditorBase;
+class EditorSpellCheck;
+enum class EditSubAction : int32_t;
+enum class JoinNodesDirection;
+
+namespace dom {
+class Event;
+} // namespace dom
+} // namespace mozilla
+
+class mozInlineSpellStatus {
+ public:
+ static mozilla::Result<mozilla::UniquePtr<mozInlineSpellStatus>, nsresult>
+ CreateForEditorChange(mozInlineSpellChecker& aSpellChecker,
+ mozilla::EditSubAction aEditSubAction,
+ nsINode* aAnchorNode, uint32_t aAnchorOffset,
+ nsINode* aPreviousNode, uint32_t aPreviousOffset,
+ nsINode* aStartNode, uint32_t aStartOffset,
+ nsINode* aEndNode, uint32_t aEndOffset);
+
+ static mozilla::Result<mozilla::UniquePtr<mozInlineSpellStatus>, nsresult>
+ CreateForNavigation(mozInlineSpellChecker& aSpellChecker, bool aForceCheck,
+ int32_t aNewPositionOffset, nsINode* aOldAnchorNode,
+ uint32_t aOldAnchorOffset, nsINode* aNewAnchorNode,
+ uint32_t aNewAnchorOffset, bool* aContinue);
+
+ static mozilla::UniquePtr<mozInlineSpellStatus> CreateForSelection(
+ mozInlineSpellChecker& aSpellChecker);
+
+ static mozilla::UniquePtr<mozInlineSpellStatus> CreateForRange(
+ mozInlineSpellChecker& aSpellChecker, nsRange* aRange);
+
+ nsresult FinishInitOnEvent(mozInlineSpellWordUtil& aWordUtil);
+
+ // Return true if we plan to spell-check everything
+ bool IsFullSpellCheck() const { return mOp == eOpChange && !mRange; }
+
+ const RefPtr<mozInlineSpellChecker> mSpellChecker;
+
+ enum Operation {
+ eOpChange, // for SpellCheckAfterEditorChange except
+ // deleteSelection
+ eOpChangeDelete, // for SpellCheckAfterEditorChange with
+ // deleteSelection
+ eOpNavigation, // for HandleNavigationEvent
+ eOpSelection, // re-check all misspelled words
+ eOpResume
+ };
+
+ // See `mOp`.
+ Operation GetOperation() const { return mOp; }
+
+ // Used for events where we have already computed the range to use. It can
+ // also be nullptr in these cases where we need to check the entire range.
+ RefPtr<nsRange> mRange;
+
+ // See `mCreatedRange`.
+ const nsRange* GetCreatedRange() const { return mCreatedRange; }
+
+ // See `mNoCheckRange`.
+ const nsRange* GetNoCheckRange() const { return mNoCheckRange; }
+
+ private:
+ // @param aSpellChecker must be non-nullptr.
+ // @param aOp see mOp.
+ // @param aRange see mRange.
+ // @param aCreatedRange see mCreatedRange.
+ // @param aAnchorRange see mAnchorRange.
+ // @param aForceNavigationWordCheck see mForceNavigationWordCheck.
+ // @param aNewNavigationPositionOffset see mNewNavigationPositionOffset.
+ explicit mozInlineSpellStatus(mozInlineSpellChecker* aSpellChecker,
+ Operation aOp, RefPtr<nsRange>&& aRange,
+ RefPtr<nsRange>&& aCreatedRange,
+ RefPtr<nsRange>&& aAnchorRange,
+ bool aForceNavigationWordCheck,
+ int32_t aNewNavigationPositionOffset);
+
+ // For resuming a previously started check.
+ const Operation mOp;
+
+ //
+ // If we happen to know something was inserted, this is that range.
+ // Can be nullptr (this only allows an optimization, so not setting doesn't
+ // hurt)
+ const RefPtr<const nsRange> mCreatedRange;
+
+ // Contains the range computed for the current word. Can be nullptr.
+ RefPtr<nsRange> mNoCheckRange;
+
+ // Indicates the position of the cursor for the event (so we can compute
+ // mNoCheckRange). It can be nullptr if we don't care about the cursor
+ // position (such as for the intial check of everything).
+ //
+ // For mOp == eOpNavigation, this is the NEW position of the cursor
+ const RefPtr<const nsRange> mAnchorRange;
+
+ // -----
+ // The following members are only for navigation events and are only
+ // stored for FinishNavigationEvent to initialize the other members.
+ // -----
+
+ // this is the OLD position of the cursor
+ RefPtr<nsRange> mOldNavigationAnchorRange;
+
+ // Set when we should force checking the current word. See
+ // mozInlineSpellChecker::HandleNavigationEvent for a description of why we
+ // have this.
+ const bool mForceNavigationWordCheck;
+
+ // Contains the offset passed in to HandleNavigationEvent
+ const int32_t mNewNavigationPositionOffset;
+
+ nsresult FinishNavigationEvent(mozInlineSpellWordUtil& aWordUtil);
+
+ nsresult FillNoCheckRangeFromAnchor(mozInlineSpellWordUtil& aWordUtil);
+
+ mozilla::dom::Document* GetDocument() const;
+ static already_AddRefed<nsRange> PositionToCollapsedRange(nsINode* aNode,
+ uint32_t aOffset);
+};
+
+class mozInlineSpellChecker final : public nsIInlineSpellChecker,
+ public nsIDOMEventListener,
+ public nsSupportsWeakReference {
+ private:
+ friend class mozInlineSpellStatus;
+ friend class InitEditorSpellCheckCallback;
+ friend class UpdateCurrentDictionaryCallback;
+ friend class AutoChangeNumPendingSpellChecks;
+
+ // Access with CanEnableInlineSpellChecking
+ enum SpellCheckingState {
+ SpellCheck_Uninitialized = -1,
+ SpellCheck_NotAvailable = 0,
+ SpellCheck_Available = 1
+ };
+ static SpellCheckingState gCanEnableSpellChecking;
+
+ RefPtr<mozilla::EditorBase> mEditorBase;
+ RefPtr<mozilla::EditorSpellCheck> mSpellCheck;
+ RefPtr<mozilla::EditorSpellCheck> mPendingSpellCheck;
+
+ int32_t mNumWordsInSpellSelection;
+ const int32_t mMaxNumWordsInSpellSelection;
+
+ // we need to keep track of the current text position in the document
+ // so we can spell check the old word when the user clicks around the
+ // document.
+ nsCOMPtr<nsINode> mCurrentSelectionAnchorNode;
+ uint32_t mCurrentSelectionOffset;
+
+ // Tracks the number of pending spell checks *and* async operations that may
+ // lead to spell checks, like updating the current dictionary. This is
+ // necessary so that observers can know when to wait for spell check to
+ // complete.
+ int32_t mNumPendingSpellChecks;
+
+ // The number of calls to UpdateCurrentDictionary that haven't finished yet.
+ int32_t mNumPendingUpdateCurrentDictionary;
+
+ // This number is incremented each time the spell checker is disabled so that
+ // pending scheduled spell checks and UpdateCurrentDictionary calls can be
+ // ignored when they finish.
+ uint32_t mDisabledAsyncToken;
+
+ // When mPendingSpellCheck is non-null, this is the callback passed when
+ // it was initialized.
+ RefPtr<InitEditorSpellCheckCallback> mPendingInitEditorSpellCheckCallback;
+
+ // Set when we have spellchecked after the last edit operation. See the
+ // commment at the top of the .cpp file for more info.
+ bool mNeedsCheckAfterNavigation;
+
+ // Set when we have a pending mozInlineSpellResume which will check
+ // the whole document.
+ bool mFullSpellCheckScheduled;
+
+ // Set to true when this instance needs to listen to edit actions of
+ // the editor.
+ bool mIsListeningToEditSubActions;
+
+ class SpellCheckerSlice;
+
+ public:
+ NS_DECL_CYCLE_COLLECTING_ISUPPORTS
+ NS_DECL_NSIINLINESPELLCHECKER
+ NS_DECL_NSIDOMEVENTLISTENER
+ NS_DECL_CYCLE_COLLECTION_CLASS_AMBIGUOUS(mozInlineSpellChecker,
+ nsIDOMEventListener)
+
+ mozilla::EditorSpellCheck* GetEditorSpellCheck();
+
+ // See `mDisabledAsyncToken`.
+ uint32_t GetDisabledAsyncToken() const { return mDisabledAsyncToken; }
+
+ // returns true if there are any spell checking dictionaries available
+ static bool CanEnableInlineSpellChecking();
+ // update the cached value whenever the list of available dictionaries changes
+ static void UpdateCanEnableInlineSpellChecking();
+
+ mozInlineSpellChecker();
+
+ // spell checks all of the words between two nodes
+ nsresult SpellCheckBetweenNodes(nsINode* aStartNode, int32_t aStartOffset,
+ nsINode* aEndNode, int32_t aEndOffset);
+
+ // examines the dom node in question and returns true if the inline spell
+ // checker should skip the node (i.e. the text is inside of a block quote
+ // or an e-mail signature...)
+ static bool ShouldSpellCheckNode(mozilla::EditorBase* aEditorBase,
+ nsINode* aNode);
+
+ // spell check the text contained within aRange, potentially scheduling
+ // another check in the future if the time threshold is reached
+ nsresult ScheduleSpellCheck(
+ mozilla::UniquePtr<mozInlineSpellStatus>&& aStatus);
+
+ MOZ_CAN_RUN_SCRIPT_BOUNDARY nsresult
+ DoSpellCheckSelection(mozInlineSpellWordUtil& aWordUtil,
+ mozilla::dom::Selection* aSpellCheckSelection);
+
+ nsresult DoSpellCheck(mozInlineSpellWordUtil& aWordUtil,
+ mozilla::dom::Selection* aSpellCheckSelection,
+ const mozilla::UniquePtr<mozInlineSpellStatus>& aStatus,
+ bool* aDoneChecking);
+
+ // helper routine to determine if a point is inside of the passed in
+ // selection.
+ static nsresult IsPointInSelection(mozilla::dom::Selection& aSelection,
+ nsINode* aNode, uint32_t aOffset,
+ nsRange** aRange);
+
+ nsresult CleanupRangesInSelection(mozilla::dom::Selection* aSelection);
+
+ /**
+ * @param aRange needs to be kept alive by the caller.
+ */
+ // TODO: annotate with `MOZ_CAN_RUN_SCRIPT` instead
+ // (https://bugzilla.mozilla.org/show_bug.cgi?id=1620540).
+ MOZ_CAN_RUN_SCRIPT_BOUNDARY nsresult
+ RemoveRange(mozilla::dom::Selection* aSpellCheckSelection, nsRange* aRange);
+
+ MOZ_CAN_RUN_SCRIPT_BOUNDARY nsresult
+ AddRange(mozilla::dom::Selection* aSpellCheckSelection, nsRange* aRange);
+ bool IsSpellCheckSelectionFull() const {
+ return mNumWordsInSpellSelection >= mMaxNumWordsInSpellSelection;
+ }
+
+ nsresult MakeSpellCheckRange(nsINode* aStartNode, int32_t aStartOffset,
+ nsINode* aEndNode, int32_t aEndOffset,
+ nsRange** aRange) const;
+
+ // DOM and editor event registration helper routines
+ nsresult RegisterEventListeners();
+ nsresult UnregisterEventListeners();
+ nsresult HandleNavigationEvent(bool aForceWordSpellCheck,
+ int32_t aNewPositionOffset = 0);
+
+ already_AddRefed<mozilla::dom::Selection> GetSpellCheckSelection();
+ nsresult SaveCurrentSelectionPosition();
+
+ nsresult ResumeCheck(mozilla::UniquePtr<mozInlineSpellStatus>&& aStatus);
+
+ nsresult SpellCheckAfterEditorChange(mozilla::EditSubAction aEditSubAction,
+ mozilla::dom::Selection& aSelection,
+ nsINode* aPreviousSelectedNode,
+ uint32_t aPreviousSelectedOffset,
+ nsINode* aStartNode,
+ uint32_t aStartOffset, nsINode* aEndNode,
+ uint32_t aEndOffset);
+
+ protected:
+ virtual ~mozInlineSpellChecker();
+
+ struct CompareRangeAndNodeOffsetRange;
+
+ // Ensures that all misspelled words have corresponding ranges in
+ // aSpellCheckerSelection. Reuses those of the old ranges, which still
+ // correspond to misspelled words and adds new ranges for those misspelled
+ // words for which no corresponding old range exists.
+ // Removes the old ranges which aren't reused from aSpellCheckerSelection.
+ //
+ // @param aNodeOffsetRangesForWords corresponds to aIsMisspelled.
+ // `aNodeOffsetRangesForWords.Length() ==
+ // aIsMisspelled.Length()`.
+ // @param aOldRangesForSomeWords ranges belonging to aSpellCheckerSelection.
+ // Its length may differ from
+ // `aNodeOffsetRangesForWords.Length()`.
+ // @param aIsMisspelled indicates which words are misspelled.
+ MOZ_CAN_RUN_SCRIPT_BOUNDARY void UpdateRangesForMisspelledWords(
+ const nsTArray<NodeOffsetRange>& aNodeOffsetRangesForWords,
+ const nsTArray<RefPtr<nsRange>>& aOldRangesForSomeWords,
+ const nsTArray<bool>& aIsMisspelled,
+ mozilla::dom::Selection& aSpellCheckerSelection);
+
+ // called when async nsIEditorSpellCheck methods complete
+ nsresult EditorSpellCheckInited();
+ nsresult CurrentDictionaryUpdated();
+
+ // track the number of pending spell checks and async operations that may lead
+ // to spell checks, notifying observers accordingly
+ void ChangeNumPendingSpellChecks(int32_t aDelta,
+ mozilla::EditorBase* aEditorBase = nullptr);
+ void NotifyObservers(const char* aTopic, mozilla::EditorBase* aEditorBase);
+
+ void StartToListenToEditSubActions() { mIsListeningToEditSubActions = true; }
+ void EndListeningToEditSubActions() { mIsListeningToEditSubActions = false; }
+
+ void OnBlur(mozilla::dom::Event& aEvent);
+ void OnMouseClick(mozilla::dom::Event& aMouseEvent);
+ void OnKeyDown(mozilla::dom::Event& aKeyEvent);
+};
+
+#endif // #ifndef mozilla_mozInlineSpellChecker_h
diff --git a/extensions/spellcheck/src/mozInlineSpellWordUtil.cpp b/extensions/spellcheck/src/mozInlineSpellWordUtil.cpp
new file mode 100644
index 0000000000..731059f04b
--- /dev/null
+++ b/extensions/spellcheck/src/mozInlineSpellWordUtil.cpp
@@ -0,0 +1,1174 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "mozInlineSpellWordUtil.h"
+
+#include <algorithm>
+#include <utility>
+
+#include "mozilla/BinarySearch.h"
+#include "mozilla/EditorBase.h"
+#include "mozilla/HTMLEditor.h"
+#include "mozilla/Logging.h"
+#include "mozilla/dom/Element.h"
+
+#include "nsDebug.h"
+#include "nsAtom.h"
+#include "nsComponentManagerUtils.h"
+#include "nsUnicodeProperties.h"
+#include "nsServiceManagerUtils.h"
+#include "nsIContent.h"
+#include "nsTextFragment.h"
+#include "nsRange.h"
+#include "nsContentUtils.h"
+#include "nsIFrame.h"
+
+using namespace mozilla;
+
+static LazyLogModule sInlineSpellWordUtilLog{"InlineSpellWordUtil"};
+
+// IsIgnorableCharacter
+//
+// These characters are ones that we should ignore in input.
+
+inline bool IsIgnorableCharacter(char ch) {
+ return (ch == static_cast<char>(0xAD)); // SOFT HYPHEN
+}
+
+inline bool IsIgnorableCharacter(char16_t ch) {
+ return (ch == 0xAD || // SOFT HYPHEN
+ ch == 0x1806); // MONGOLIAN TODO SOFT HYPHEN
+}
+
+// IsConditionalPunctuation
+//
+// Some characters (like apostrophes) require characters on each side to be
+// part of a word, and are otherwise punctuation.
+
+inline bool IsConditionalPunctuation(char ch) {
+ return (ch == '\'' || // RIGHT SINGLE QUOTATION MARK
+ ch == static_cast<char>(0xB7)); // MIDDLE DOT
+}
+
+inline bool IsConditionalPunctuation(char16_t ch) {
+ return (ch == '\'' || ch == 0x2019 || // RIGHT SINGLE QUOTATION MARK
+ ch == 0x00B7); // MIDDLE DOT
+}
+
+static bool IsAmbiguousDOMWordSeprator(char16_t ch) {
+ // This class may be CHAR_CLASS_SEPARATOR, but it depends on context.
+ return (ch == '@' || ch == ':' || ch == '.' || ch == '/' || ch == '-' ||
+ IsConditionalPunctuation(ch));
+}
+
+static bool IsAmbiguousDOMWordSeprator(char ch) {
+ // This class may be CHAR_CLASS_SEPARATOR, but it depends on context.
+ return IsAmbiguousDOMWordSeprator(static_cast<char16_t>(ch));
+}
+
+// IsDOMWordSeparator
+//
+// Determines if the given character should be considered as a DOM Word
+// separator. Basically, this is whitespace, although it could also have
+// certain punctuation that we know ALWAYS breaks words. This is important.
+// For example, we can't have any punctuation that could appear in a URL
+// or email address in this, because those need to always fit into a single
+// DOM word.
+
+static bool IsDOMWordSeparator(char ch) {
+ // simple spaces or no-break space
+ return (ch == ' ' || ch == '\t' || ch == '\n' || ch == '\r' ||
+ ch == static_cast<char>(0xA0));
+}
+
+static bool IsDOMWordSeparator(char16_t ch) {
+ // simple spaces
+ if (ch == ' ' || ch == '\t' || ch == '\n' || ch == '\r') return true;
+
+ // complex spaces - check only if char isn't ASCII (uncommon)
+ if (ch >= 0xA0 && (ch == 0x00A0 || // NO-BREAK SPACE
+ ch == 0x2002 || // EN SPACE
+ ch == 0x2003 || // EM SPACE
+ ch == 0x2009 || // THIN SPACE
+ ch == 0x3000)) // IDEOGRAPHIC SPACE
+ return true;
+
+ // otherwise not a space
+ return false;
+}
+
+bool NodeOffset::operator==(
+ const mozilla::RangeBoundary& aRangeBoundary) const {
+ if (aRangeBoundary.Container() != mNode) {
+ return false;
+ }
+
+ const Maybe<uint32_t> rangeBoundaryOffset =
+ aRangeBoundary.Offset(RangeBoundary::OffsetFilter::kValidOffsets);
+
+ MOZ_ASSERT(mOffset >= 0);
+ return rangeBoundaryOffset &&
+ (*rangeBoundaryOffset == static_cast<uint32_t>(mOffset));
+}
+
+bool NodeOffsetRange::operator==(const nsRange& aRange) const {
+ return mBegin == aRange.StartRef() && mEnd == aRange.EndRef();
+}
+
+// static
+Maybe<mozInlineSpellWordUtil> mozInlineSpellWordUtil::Create(
+ const EditorBase& aEditorBase) {
+ dom::Document* document = aEditorBase.GetDocument();
+ if (NS_WARN_IF(!document)) {
+ return Nothing();
+ }
+
+ const bool isContentEditableOrDesignMode = aEditorBase.IsHTMLEditor();
+
+ // Find the root node for the editor. For contenteditable the mRootNode could
+ // change to shadow root if the begin and end are inside the shadowDOM.
+ nsINode* rootNode = aEditorBase.GetRoot();
+ if (NS_WARN_IF(!rootNode)) {
+ return Nothing();
+ }
+
+ mozInlineSpellWordUtil util{*document, isContentEditableOrDesignMode,
+ *rootNode};
+ return Some(std::move(util));
+}
+
+static inline bool IsSpellCheckingTextNode(nsINode* aNode) {
+ nsIContent* parent = aNode->GetParent();
+ if (parent &&
+ parent->IsAnyOfHTMLElements(nsGkAtoms::script, nsGkAtoms::style))
+ return false;
+ return aNode->IsText();
+}
+
+typedef void (*OnLeaveNodeFunPtr)(nsINode* aNode, void* aClosure);
+
+// Find the next node in the DOM tree in preorder.
+// Calls OnLeaveNodeFunPtr when the traversal leaves a node, which is
+// why we can't just use GetNextNode here, sadly.
+static nsINode* FindNextNode(nsINode* aNode, const nsINode* aRoot,
+ OnLeaveNodeFunPtr aOnLeaveNode, void* aClosure) {
+ MOZ_ASSERT(aNode, "Null starting node?");
+
+ nsINode* next = aNode->GetFirstChild();
+ if (next) return next;
+
+ // Don't look at siblings or otherwise outside of aRoot
+ if (aNode == aRoot) return nullptr;
+
+ next = aNode->GetNextSibling();
+ if (next) return next;
+
+ // Go up
+ for (;;) {
+ if (aOnLeaveNode) {
+ aOnLeaveNode(aNode, aClosure);
+ }
+
+ next = aNode->GetParent();
+ if (next == aRoot || !next) return nullptr;
+ aNode = next;
+
+ next = aNode->GetNextSibling();
+ if (next) return next;
+ }
+}
+
+// aNode is not a text node. Find the first text node starting at aNode/aOffset
+// in a preorder DOM traversal.
+static nsINode* FindNextTextNode(nsINode* aNode, int32_t aOffset,
+ const nsINode* aRoot) {
+ MOZ_ASSERT(aNode, "Null starting node?");
+ MOZ_ASSERT(!IsSpellCheckingTextNode(aNode),
+ "FindNextTextNode should start with a non-text node");
+
+ nsINode* checkNode;
+ // Need to start at the aOffset'th child
+ nsIContent* child = aNode->GetChildAt_Deprecated(aOffset);
+
+ if (child) {
+ checkNode = child;
+ } else {
+ // aOffset was beyond the end of the child list.
+ // goto next node after the last descendant of aNode in
+ // a preorder DOM traversal.
+ checkNode = aNode->GetNextNonChildNode(aRoot);
+ }
+
+ while (checkNode && !IsSpellCheckingTextNode(checkNode)) {
+ checkNode = checkNode->GetNextNode(aRoot);
+ }
+ return checkNode;
+}
+
+// mozInlineSpellWordUtil::SetPositionAndEnd
+//
+// We have two ranges "hard" and "soft". The hard boundary is simply
+// the scope of the root node. The soft boundary is that which is set
+// by the caller of this class by calling this function. If this function is
+// not called, the soft boundary is the same as the hard boundary.
+//
+// When we reach the soft boundary (mSoftText.GetEnd()), we keep
+// going until we reach the end of a word. This allows the caller to set the
+// end of the range to anything, and we will always check whole multiples of
+// words. When we reach the hard boundary we stop no matter what.
+//
+// There is no beginning soft boundary. This is because we only go to the
+// previous node once, when finding the previous word boundary in
+// SetPosition(). You might think of the soft boundary as being this initial
+// position.
+
+nsresult mozInlineSpellWordUtil::SetPositionAndEnd(nsINode* aPositionNode,
+ int32_t aPositionOffset,
+ nsINode* aEndNode,
+ int32_t aEndOffset) {
+ MOZ_LOG(sInlineSpellWordUtilLog, LogLevel::Debug,
+ ("%s: pos=(%p, %i), end=(%p, %i)", __FUNCTION__, aPositionNode,
+ aPositionOffset, aEndNode, aEndOffset));
+
+ MOZ_ASSERT(aPositionNode, "Null begin node?");
+ MOZ_ASSERT(aEndNode, "Null end node?");
+
+ MOZ_ASSERT(mRootNode, "Not initialized");
+
+ // Find a appropriate root if we are dealing with contenteditable nodes which
+ // are in the shadow DOM.
+ if (mIsContentEditableOrDesignMode) {
+ nsINode* rootNode = aPositionNode->SubtreeRoot();
+ if (rootNode != aEndNode->SubtreeRoot()) {
+ return NS_ERROR_FAILURE;
+ }
+
+ if (mozilla::dom::ShadowRoot::FromNode(rootNode)) {
+ mRootNode = rootNode;
+ }
+ }
+
+ mSoftText.Invalidate();
+
+ if (!IsSpellCheckingTextNode(aPositionNode)) {
+ // Start at the start of the first text node after aNode/aOffset.
+ aPositionNode = FindNextTextNode(aPositionNode, aPositionOffset, mRootNode);
+ aPositionOffset = 0;
+ }
+ NodeOffset softBegin = NodeOffset(aPositionNode, aPositionOffset);
+
+ if (!IsSpellCheckingTextNode(aEndNode)) {
+ // End at the start of the first text node after aEndNode/aEndOffset.
+ aEndNode = FindNextTextNode(aEndNode, aEndOffset, mRootNode);
+ aEndOffset = 0;
+ }
+ NodeOffset softEnd = NodeOffset(aEndNode, aEndOffset);
+
+ nsresult rv = EnsureWords(std::move(softBegin), std::move(softEnd));
+ if (NS_FAILED(rv)) {
+ return rv;
+ }
+
+ int32_t textOffset = MapDOMPositionToSoftTextOffset(mSoftText.GetBegin());
+ if (textOffset < 0) {
+ return NS_OK;
+ }
+
+ mNextWordIndex = FindRealWordContaining(textOffset, HINT_END, true);
+ return NS_OK;
+}
+
+nsresult mozInlineSpellWordUtil::EnsureWords(NodeOffset aSoftBegin,
+ NodeOffset aSoftEnd) {
+ if (mSoftText.mIsValid) return NS_OK;
+ mSoftText.AdjustBeginAndBuildText(std::move(aSoftBegin), std::move(aSoftEnd),
+ mRootNode);
+
+ mRealWords.Clear();
+ Result<RealWords, nsresult> realWords = BuildRealWords();
+ if (realWords.isErr()) {
+ return realWords.unwrapErr();
+ }
+
+ mRealWords = realWords.unwrap();
+ mSoftText.mIsValid = true;
+ return NS_OK;
+}
+
+nsresult mozInlineSpellWordUtil::MakeRangeForWord(const RealWord& aWord,
+ nsRange** aRange) const {
+ NodeOffset begin =
+ MapSoftTextOffsetToDOMPosition(aWord.mSoftTextOffset, HINT_BEGIN);
+ NodeOffset end = MapSoftTextOffsetToDOMPosition(aWord.EndOffset(), HINT_END);
+ return MakeRange(begin, end, aRange);
+}
+void mozInlineSpellWordUtil::MakeNodeOffsetRangeForWord(
+ const RealWord& aWord, NodeOffsetRange* aNodeOffsetRange) {
+ NodeOffset begin =
+ MapSoftTextOffsetToDOMPosition(aWord.mSoftTextOffset, HINT_BEGIN);
+ NodeOffset end = MapSoftTextOffsetToDOMPosition(aWord.EndOffset(), HINT_END);
+ *aNodeOffsetRange = NodeOffsetRange(begin, end);
+}
+
+// mozInlineSpellWordUtil::GetRangeForWord
+
+nsresult mozInlineSpellWordUtil::GetRangeForWord(nsINode* aWordNode,
+ int32_t aWordOffset,
+ nsRange** aRange) {
+ // Set our soft end and start
+ NodeOffset pt(aWordNode, aWordOffset);
+
+ if (!mSoftText.mIsValid || pt != mSoftText.GetBegin() ||
+ pt != mSoftText.GetEnd()) {
+ mSoftText.Invalidate();
+ NodeOffset softBegin = pt;
+ NodeOffset softEnd = pt;
+ nsresult rv = EnsureWords(std::move(softBegin), std::move(softEnd));
+ if (NS_FAILED(rv)) {
+ return rv;
+ }
+ }
+
+ int32_t offset = MapDOMPositionToSoftTextOffset(pt);
+ if (offset < 0) return MakeRange(pt, pt, aRange);
+ int32_t wordIndex = FindRealWordContaining(offset, HINT_BEGIN, false);
+ if (wordIndex < 0) return MakeRange(pt, pt, aRange);
+ return MakeRangeForWord(mRealWords[wordIndex], aRange);
+}
+
+// This is to fix characters that the spellchecker may not like
+static void NormalizeWord(const nsAString& aInput, int32_t aPos, int32_t aLen,
+ nsAString& aOutput) {
+ aOutput.Truncate();
+ for (int32_t i = 0; i < aLen; i++) {
+ char16_t ch = aInput.CharAt(i + aPos);
+
+ // remove ignorable characters from the word
+ if (IsIgnorableCharacter(ch)) continue;
+
+ // the spellchecker doesn't handle curly apostrophes in all languages
+ if (ch == 0x2019) { // RIGHT SINGLE QUOTATION MARK
+ ch = '\'';
+ }
+
+ aOutput.Append(ch);
+ }
+}
+
+// mozInlineSpellWordUtil::GetNextWord
+//
+// FIXME-optimization: we shouldn't have to generate a range every single
+// time. It would be better if the inline spellchecker didn't require a
+// range unless the word was misspelled. This may or may not be possible.
+
+bool mozInlineSpellWordUtil::GetNextWord(Word& aWord) {
+ MOZ_LOG(sInlineSpellWordUtilLog, LogLevel::Debug,
+ ("%s: mNextWordIndex=%d", __FUNCTION__, mNextWordIndex));
+
+ if (mNextWordIndex < 0 || mNextWordIndex >= int32_t(mRealWords.Length())) {
+ mNextWordIndex = -1;
+ aWord.mSkipChecking = true;
+ return false;
+ }
+
+ const RealWord& realWord = mRealWords[mNextWordIndex];
+ MakeNodeOffsetRangeForWord(realWord, &aWord.mNodeOffsetRange);
+ ++mNextWordIndex;
+ aWord.mSkipChecking = !realWord.mCheckableWord;
+ ::NormalizeWord(mSoftText.GetValue(), realWord.mSoftTextOffset,
+ realWord.mLength, aWord.mText);
+
+ MOZ_LOG(sInlineSpellWordUtilLog, LogLevel::Debug,
+ ("%s: returning: %s (skip=%d)", __FUNCTION__,
+ NS_ConvertUTF16toUTF8(aWord.mText).get(), aWord.mSkipChecking));
+
+ return true;
+}
+
+// mozInlineSpellWordUtil::MakeRange
+//
+// Convenience function for creating a range over the current document.
+
+nsresult mozInlineSpellWordUtil::MakeRange(NodeOffset aBegin, NodeOffset aEnd,
+ nsRange** aRange) const {
+ NS_ENSURE_ARG_POINTER(aBegin.mNode);
+ if (!mDocument) {
+ return NS_ERROR_NOT_INITIALIZED;
+ }
+
+ ErrorResult error;
+ RefPtr<nsRange> range = nsRange::Create(aBegin.mNode, aBegin.mOffset,
+ aEnd.mNode, aEnd.mOffset, error);
+ if (NS_WARN_IF(error.Failed())) {
+ return error.StealNSResult();
+ }
+ MOZ_ASSERT(range);
+ range.forget(aRange);
+ return NS_OK;
+}
+
+// static
+already_AddRefed<nsRange> mozInlineSpellWordUtil::MakeRange(
+ const NodeOffsetRange& aRange) {
+ IgnoredErrorResult ignoredError;
+ RefPtr<nsRange> range =
+ nsRange::Create(aRange.Begin().Node(), aRange.Begin().Offset(),
+ aRange.End().Node(), aRange.End().Offset(), ignoredError);
+ NS_WARNING_ASSERTION(!ignoredError.Failed(), "Creating a range failed");
+ return range.forget();
+}
+
+/*********** Word Splitting ************/
+
+// classifies a given character in the DOM word
+enum CharClass {
+ CHAR_CLASS_WORD,
+ CHAR_CLASS_SEPARATOR,
+ CHAR_CLASS_END_OF_INPUT
+};
+
+// Encapsulates DOM-word to real-word splitting
+template <class T>
+struct MOZ_STACK_CLASS WordSplitState {
+ const T& mDOMWordText;
+ int32_t mDOMWordOffset;
+ CharClass mCurCharClass;
+
+ explicit WordSplitState(const T& aString)
+ : mDOMWordText(aString),
+ mDOMWordOffset(0),
+ mCurCharClass(CHAR_CLASS_END_OF_INPUT) {}
+
+ CharClass ClassifyCharacter(int32_t aIndex, bool aRecurse) const;
+ void Advance();
+ void AdvanceThroughSeparators();
+ void AdvanceThroughWord();
+
+ // Finds special words like email addresses and URLs that may start at the
+ // current position, and returns their length, or 0 if not found. This allows
+ // arbitrary word breaking rules to be used for these special entities, as
+ // long as they can not contain whitespace.
+ bool IsSpecialWord() const;
+
+ // Similar to IsSpecialWord except that this takes a split word as
+ // input. This checks for things that do not require special word-breaking
+ // rules.
+ bool ShouldSkipWord(int32_t aStart, int32_t aLength) const;
+
+ // Finds the last sequence of DOM word separators before aBeforeOffset and
+ // returns the offset to its first element.
+ Maybe<int32_t> FindOffsetOfLastDOMWordSeparatorSequence(
+ int32_t aBeforeOffset) const;
+
+ char16_t GetUnicharAt(int32_t aIndex) const;
+};
+
+// WordSplitState::ClassifyCharacter
+template <class T>
+CharClass WordSplitState<T>::ClassifyCharacter(int32_t aIndex,
+ bool aRecurse) const {
+ MOZ_ASSERT(aIndex >= 0 && aIndex <= int32_t(mDOMWordText.Length()),
+ "Index out of range");
+ if (aIndex == int32_t(mDOMWordText.Length())) return CHAR_CLASS_SEPARATOR;
+
+ // this will classify the character, we want to treat "ignorable" characters
+ // such as soft hyphens, and also ZWJ and ZWNJ as word characters.
+ nsUGenCategory charCategory =
+ mozilla::unicode::GetGenCategory(GetUnicharAt(aIndex));
+ if (charCategory == nsUGenCategory::kLetter ||
+ IsIgnorableCharacter(mDOMWordText[aIndex]) ||
+ mDOMWordText[aIndex] == 0x200C /* ZWNJ */ ||
+ mDOMWordText[aIndex] == 0x200D /* ZWJ */)
+ return CHAR_CLASS_WORD;
+
+ // If conditional punctuation is surrounded immediately on both sides by word
+ // characters it also counts as a word character.
+ if (IsConditionalPunctuation(mDOMWordText[aIndex])) {
+ if (!aRecurse) {
+ // not allowed to look around, this punctuation counts like a separator
+ return CHAR_CLASS_SEPARATOR;
+ }
+
+ // check the left-hand character
+ if (aIndex == 0) return CHAR_CLASS_SEPARATOR;
+ if (ClassifyCharacter(aIndex - 1, false) != CHAR_CLASS_WORD)
+ return CHAR_CLASS_SEPARATOR;
+ // If the previous charatcer is a word-char, make sure that it's not a
+ // special dot character.
+ if (mDOMWordText[aIndex - 1] == '.') return CHAR_CLASS_SEPARATOR;
+
+ // now we know left char is a word-char, check the right-hand character
+ if (aIndex == int32_t(mDOMWordText.Length() - 1)) {
+ return CHAR_CLASS_SEPARATOR;
+ }
+
+ if (ClassifyCharacter(aIndex + 1, false) != CHAR_CLASS_WORD)
+ return CHAR_CLASS_SEPARATOR;
+ // If the next charatcer is a word-char, make sure that it's not a
+ // special dot character.
+ if (mDOMWordText[aIndex + 1] == '.') return CHAR_CLASS_SEPARATOR;
+
+ // char on either side is a word, this counts as a word
+ return CHAR_CLASS_WORD;
+ }
+
+ // The dot character, if appearing at the end of a word, should
+ // be considered part of that word. Example: "etc.", or
+ // abbreviations
+ if (aIndex > 0 && mDOMWordText[aIndex] == '.' &&
+ mDOMWordText[aIndex - 1] != '.' &&
+ ClassifyCharacter(aIndex - 1, false) != CHAR_CLASS_WORD) {
+ return CHAR_CLASS_WORD;
+ }
+
+ // all other punctuation
+ if (charCategory == nsUGenCategory::kSeparator ||
+ charCategory == nsUGenCategory::kOther ||
+ charCategory == nsUGenCategory::kPunctuation ||
+ charCategory == nsUGenCategory::kSymbol) {
+ // Don't break on hyphens, as hunspell handles them on its own.
+ if (aIndex > 0 && mDOMWordText[aIndex] == '-' &&
+ mDOMWordText[aIndex - 1] != '-' &&
+ ClassifyCharacter(aIndex - 1, false) == CHAR_CLASS_WORD) {
+ // A hyphen is only meaningful as a separator inside a word
+ // if the previous and next characters are a word character.
+ if (aIndex == int32_t(mDOMWordText.Length()) - 1)
+ return CHAR_CLASS_SEPARATOR;
+ if (mDOMWordText[aIndex + 1] != '.' &&
+ ClassifyCharacter(aIndex + 1, false) == CHAR_CLASS_WORD)
+ return CHAR_CLASS_WORD;
+ }
+ return CHAR_CLASS_SEPARATOR;
+ }
+
+ // any other character counts as a word
+ return CHAR_CLASS_WORD;
+}
+
+// WordSplitState::Advance
+template <class T>
+void WordSplitState<T>::Advance() {
+ MOZ_ASSERT(mDOMWordOffset >= 0, "Negative word index");
+ MOZ_ASSERT(mDOMWordOffset < (int32_t)mDOMWordText.Length(),
+ "Length beyond end");
+
+ mDOMWordOffset++;
+ if (mDOMWordOffset >= (int32_t)mDOMWordText.Length())
+ mCurCharClass = CHAR_CLASS_END_OF_INPUT;
+ else
+ mCurCharClass = ClassifyCharacter(mDOMWordOffset, true);
+}
+
+// WordSplitState::AdvanceThroughSeparators
+template <class T>
+void WordSplitState<T>::AdvanceThroughSeparators() {
+ while (mCurCharClass == CHAR_CLASS_SEPARATOR) Advance();
+}
+
+// WordSplitState::AdvanceThroughWord
+template <class T>
+void WordSplitState<T>::AdvanceThroughWord() {
+ while (mCurCharClass == CHAR_CLASS_WORD) Advance();
+}
+
+// WordSplitState::IsSpecialWord
+template <class T>
+bool WordSplitState<T>::IsSpecialWord() const {
+ // Search for email addresses. We simply define these as any sequence of
+ // characters with an '@' character in the middle. The DOM word is already
+ // split on whitepace, so we know that everything to the end is the address
+ int32_t firstColon = -1;
+ for (int32_t i = mDOMWordOffset; i < int32_t(mDOMWordText.Length()); i++) {
+ if (mDOMWordText[i] == '@') {
+ // only accept this if there are unambiguous word characters (don't bother
+ // recursing to disambiguate apostrophes) on each side. This prevents
+ // classifying, e.g. "@home" as an email address
+
+ // Use this condition to only accept words with '@' in the middle of
+ // them. It works, but the inlinespellcker doesn't like this. The problem
+ // is that you type "fhsgfh@" that's a misspelled word followed by a
+ // symbol, but when you type another letter "fhsgfh@g" that first word
+ // need to be unmarked misspelled. It doesn't do this. it only checks the
+ // current position for potentially removing a spelling range.
+ if (i > 0 && ClassifyCharacter(i - 1, false) == CHAR_CLASS_WORD &&
+ i < (int32_t)mDOMWordText.Length() - 1 &&
+ ClassifyCharacter(i + 1, false) == CHAR_CLASS_WORD) {
+ return true;
+ }
+ } else if (mDOMWordText[i] == ':' && firstColon < 0) {
+ firstColon = i;
+
+ // If the first colon is followed by a slash, consider it a URL
+ // This will catch things like asdf://foo.com
+ if (firstColon < (int32_t)mDOMWordText.Length() - 1 &&
+ mDOMWordText[firstColon + 1] == '/') {
+ return true;
+ }
+ }
+ }
+
+ // Check the text before the first colon against some known protocols. It
+ // is impossible to check against all protocols, especially since you can
+ // plug in new protocols. We also don't want to waste time here checking
+ // against a lot of obscure protocols.
+ if (firstColon > mDOMWordOffset) {
+ nsString protocol(
+ Substring(mDOMWordText, mDOMWordOffset, firstColon - mDOMWordOffset));
+ if (protocol.EqualsIgnoreCase("http") ||
+ protocol.EqualsIgnoreCase("https") ||
+ protocol.EqualsIgnoreCase("news") ||
+ protocol.EqualsIgnoreCase("file") ||
+ protocol.EqualsIgnoreCase("javascript") ||
+ protocol.EqualsIgnoreCase("data") || protocol.EqualsIgnoreCase("ftp")) {
+ return true;
+ }
+ }
+
+ // not anything special
+ return false;
+}
+
+// WordSplitState::ShouldSkipWord
+template <class T>
+bool WordSplitState<T>::ShouldSkipWord(int32_t aStart, int32_t aLength) const {
+ int32_t last = aStart + aLength;
+
+ // check to see if the word contains a digit
+ for (int32_t i = aStart; i < last; i++) {
+ if (mozilla::unicode::GetGenCategory(GetUnicharAt(i)) ==
+ nsUGenCategory::kNumber) {
+ return true;
+ }
+ }
+
+ // not special
+ return false;
+}
+
+template <class T>
+Maybe<int32_t> WordSplitState<T>::FindOffsetOfLastDOMWordSeparatorSequence(
+ const int32_t aBeforeOffset) const {
+ for (int32_t i = aBeforeOffset - 1; i >= 0; --i) {
+ if (IsDOMWordSeparator(mDOMWordText[i]) ||
+ (!IsAmbiguousDOMWordSeprator(mDOMWordText[i]) &&
+ ClassifyCharacter(i, true) == CHAR_CLASS_SEPARATOR)) {
+ // Be greedy, find as many separators as we can
+ for (int32_t j = i - 1; j >= 0; --j) {
+ if (IsDOMWordSeparator(mDOMWordText[j]) ||
+ (!IsAmbiguousDOMWordSeprator(mDOMWordText[j]) &&
+ ClassifyCharacter(j, true) == CHAR_CLASS_SEPARATOR)) {
+ i = j;
+ } else {
+ break;
+ }
+ }
+ return Some(i);
+ }
+ }
+ return Nothing();
+}
+
+template <>
+char16_t WordSplitState<nsDependentSubstring>::GetUnicharAt(
+ int32_t aIndex) const {
+ return mDOMWordText[aIndex];
+}
+
+template <>
+char16_t WordSplitState<nsDependentCSubstring>::GetUnicharAt(
+ int32_t aIndex) const {
+ return static_cast<char16_t>(static_cast<uint8_t>(mDOMWordText[aIndex]));
+}
+
+static inline bool IsBRElement(nsINode* aNode) {
+ return aNode->IsHTMLElement(nsGkAtoms::br);
+}
+
+/**
+ * Given a TextNode, finds the last sequence of DOM word separators before
+ * aBeforeOffset and returns the offset to its first element.
+ *
+ * @param aContent the TextNode to check.
+ * @param aBeforeOffset the offset in the TextNode before which we will search
+ * for the DOM separator. You can pass INT32_MAX to search the entire
+ * length of the string.
+ */
+static Maybe<int32_t> FindOffsetOfLastDOMWordSeparatorSequence(
+ nsIContent* aContent, int32_t aBeforeOffset) {
+ const nsTextFragment* textFragment = aContent->GetText();
+ MOZ_ASSERT(textFragment, "Where is our text?");
+ int32_t end = std::min(aBeforeOffset, int32_t(textFragment->GetLength()));
+
+ if (textFragment->Is2b()) {
+ nsDependentSubstring targetText(textFragment->Get2b(), end);
+ WordSplitState<nsDependentSubstring> state(targetText);
+ return state.FindOffsetOfLastDOMWordSeparatorSequence(end);
+ }
+
+ nsDependentCSubstring targetText(textFragment->Get1b(), end);
+ WordSplitState<nsDependentCSubstring> state(targetText);
+ return state.FindOffsetOfLastDOMWordSeparatorSequence(end);
+}
+
+/**
+ * Check if there's a DOM word separator before aBeforeOffset in this node.
+ * Always returns true if it's a BR element.
+ * aSeparatorOffset is set to the index of the first character in the last
+ * separator if any is found (0 for BR elements).
+ *
+ * This function does not modify aSeparatorOffset when it returns false.
+ */
+static bool ContainsDOMWordSeparator(nsINode* aNode, int32_t aBeforeOffset,
+ int32_t* aSeparatorOffset) {
+ if (IsBRElement(aNode)) {
+ *aSeparatorOffset = 0;
+ return true;
+ }
+
+ if (!IsSpellCheckingTextNode(aNode)) return false;
+
+ const Maybe<int32_t> separatorOffset =
+ FindOffsetOfLastDOMWordSeparatorSequence(aNode->AsContent(),
+ aBeforeOffset);
+ if (separatorOffset) {
+ *aSeparatorOffset = *separatorOffset;
+ return true;
+ }
+
+ return false;
+}
+
+static bool IsBreakElement(nsINode* aNode) {
+ if (!aNode->IsElement()) {
+ return false;
+ }
+
+ dom::Element* element = aNode->AsElement();
+ if (element->IsHTMLElement(nsGkAtoms::br)) {
+ return true;
+ }
+
+ // If we don't have a frame, we don't consider ourselves a break
+ // element. In particular, words can span us.
+ nsIFrame* frame = element->GetPrimaryFrame();
+ if (!frame) {
+ return false;
+ }
+
+ auto* disp = frame->StyleDisplay();
+ // Anything that's not an inline element is a break element.
+ // XXXbz should replaced inlines be break elements, though?
+ // Also should inline-block and such be break elements?
+ //
+ // FIXME(emilio): We should teach the spell checker to deal with generated
+ // content (it doesn't at all), then remove the IsListItem() check, as there
+ // could be no marker, etc...
+ return !disp->IsInlineFlow() || disp->IsListItem();
+}
+
+struct CheckLeavingBreakElementClosure {
+ bool mLeftBreakElement;
+};
+
+static void CheckLeavingBreakElement(nsINode* aNode, void* aClosure) {
+ CheckLeavingBreakElementClosure* cl =
+ static_cast<CheckLeavingBreakElementClosure*>(aClosure);
+ if (!cl->mLeftBreakElement && IsBreakElement(aNode)) {
+ cl->mLeftBreakElement = true;
+ }
+}
+
+void mozInlineSpellWordUtil::NormalizeWord(nsAString& aWord) {
+ nsAutoString result;
+ ::NormalizeWord(aWord, 0, aWord.Length(), result);
+ aWord = result;
+}
+
+void mozInlineSpellWordUtil::SoftText::AdjustBeginAndBuildText(
+ NodeOffset aBegin, NodeOffset aEnd, const nsINode* aRootNode) {
+ MOZ_LOG(sInlineSpellWordUtilLog, LogLevel::Debug, ("%s", __FUNCTION__));
+
+ mBegin = std::move(aBegin);
+ mEnd = std::move(aEnd);
+
+ // First we have to work backwards from mBegin to find a text node
+ // containing a DOM word separator, a non-inline-element
+ // boundary, or the hard start node. That's where we'll start building the
+ // soft string from.
+ nsINode* node = mBegin.mNode;
+ int32_t firstOffsetInNode = 0;
+ int32_t checkBeforeOffset = mBegin.mOffset;
+ while (node) {
+ if (ContainsDOMWordSeparator(node, checkBeforeOffset, &firstOffsetInNode)) {
+ if (node == mBegin.mNode) {
+ // If we find a word separator on the first node, look at the preceding
+ // word on the text node as well.
+ if (firstOffsetInNode > 0) {
+ // Try to find the previous word boundary in the current node. If
+ // we can't find one, start checking previous sibling nodes (if any
+ // adjacent ones exist) to see if we can find any text nodes with
+ // DOM word separators. We bail out as soon as we see a node that is
+ // not a text node, or we run out of previous sibling nodes. In the
+ // event that we simply cannot find any preceding word separator, the
+ // offset is set to 0, and the soft text beginning node is set to the
+ // "most previous" text node before the original starting node, or
+ // kept at the original starting node if no previous text nodes exist.
+ int32_t newOffset = 0;
+ if (!ContainsDOMWordSeparator(node, firstOffsetInNode - 1,
+ &newOffset)) {
+ nsIContent* prevNode = node->GetPreviousSibling();
+ while (prevNode && IsSpellCheckingTextNode(prevNode)) {
+ mBegin.mNode = prevNode;
+ const Maybe<int32_t> separatorOffset =
+ FindOffsetOfLastDOMWordSeparatorSequence(prevNode, INT32_MAX);
+ if (separatorOffset) {
+ newOffset = *separatorOffset;
+ break;
+ }
+ prevNode = prevNode->GetPreviousSibling();
+ }
+ }
+ firstOffsetInNode = newOffset;
+ } else {
+ firstOffsetInNode = 0;
+ }
+
+ MOZ_LOG(sInlineSpellWordUtilLog, LogLevel::Debug,
+ ("%s: adjusting mBegin.mOffset from %i to %i.", __FUNCTION__,
+ mBegin.mOffset, firstOffsetInNode));
+ mBegin.mOffset = firstOffsetInNode;
+ }
+ break;
+ }
+ checkBeforeOffset = INT32_MAX;
+ if (IsBreakElement(node)) {
+ // Since GetPreviousContent follows tree *preorder*, we're about to
+ // traverse up out of 'node'. Since node induces breaks (e.g., it's a
+ // block), don't bother trying to look outside it, just stop now.
+ break;
+ }
+ // GetPreviousContent below expects aRootNode to be an ancestor of node.
+ if (!node->IsInclusiveDescendantOf(aRootNode)) {
+ break;
+ }
+ node = node->GetPreviousContent(aRootNode);
+ }
+
+ // Now build up the string moving forward through the DOM until we reach
+ // the soft end and *then* see a DOM word separator, a non-inline-element
+ // boundary, or the hard end node.
+ mValue.Truncate();
+ mDOMMapping.Clear();
+ bool seenSoftEnd = false;
+ // Leave this outside the loop so large heap string allocations can be reused
+ // across iterations
+ while (node) {
+ if (node == mEnd.mNode) {
+ seenSoftEnd = true;
+ }
+
+ bool exit = false;
+ if (IsSpellCheckingTextNode(node)) {
+ nsIContent* content = static_cast<nsIContent*>(node);
+ MOZ_ASSERT(content, "Where is our content?");
+ const nsTextFragment* textFragment = content->GetText();
+ MOZ_ASSERT(textFragment, "Where is our text?");
+ uint32_t lastOffsetInNode = textFragment->GetLength();
+
+ if (seenSoftEnd) {
+ // check whether we can stop after this
+ for (uint32_t i =
+ node == mEnd.mNode ? AssertedCast<uint32_t>(mEnd.mOffset) : 0;
+ i < textFragment->GetLength(); ++i) {
+ if (IsDOMWordSeparator(textFragment->CharAt(i))) {
+ exit = true;
+ // stop at the first separator after the soft end point
+ lastOffsetInNode = i;
+ break;
+ }
+ }
+ }
+
+ if (firstOffsetInNode >= 0 &&
+ static_cast<uint32_t>(firstOffsetInNode) < lastOffsetInNode) {
+ const uint32_t len = lastOffsetInNode - firstOffsetInNode;
+ mDOMMapping.AppendElement(DOMTextMapping(
+ NodeOffset(node, firstOffsetInNode), mValue.Length(), len));
+
+ const bool ok = textFragment->AppendTo(
+ mValue, static_cast<uint32_t>(firstOffsetInNode), len,
+ mozilla::fallible);
+ if (!ok) {
+ // probably out of memory, remove from mDOMMapping
+ mDOMMapping.RemoveLastElement();
+ exit = true;
+ }
+ }
+
+ firstOffsetInNode = 0;
+ }
+
+ if (exit) break;
+
+ CheckLeavingBreakElementClosure closure = {false};
+ node = FindNextNode(node, aRootNode, CheckLeavingBreakElement, &closure);
+ if (closure.mLeftBreakElement || (node && IsBreakElement(node))) {
+ // We left, or are entering, a break element (e.g., block). Maybe we can
+ // stop now.
+ if (seenSoftEnd) break;
+ // Record the break
+ mValue.Append(' ');
+ }
+ }
+
+ MOZ_LOG(sInlineSpellWordUtilLog, LogLevel::Debug,
+ ("%s: got DOM string: %s", __FUNCTION__,
+ NS_ConvertUTF16toUTF8(mValue).get()));
+}
+
+auto mozInlineSpellWordUtil::BuildRealWords() const
+ -> Result<RealWords, nsresult> {
+ // This is pretty simple. We just have to walk mSoftText.GetValue(),
+ // tokenizing it into "real words". We do an outer traversal of words
+ // delimited by IsDOMWordSeparator, calling SplitDOMWordAndAppendTo on each of
+ // those DOM words
+ int32_t wordStart = -1;
+ RealWords realWords;
+ for (int32_t i = 0; i < int32_t(mSoftText.GetValue().Length()); ++i) {
+ if (IsDOMWordSeparator(mSoftText.GetValue().CharAt(i))) {
+ if (wordStart >= 0) {
+ nsresult rv = SplitDOMWordAndAppendTo(wordStart, i, realWords);
+ if (NS_FAILED(rv)) {
+ return Err(rv);
+ }
+ wordStart = -1;
+ }
+ } else {
+ if (wordStart < 0) {
+ wordStart = i;
+ }
+ }
+ }
+ if (wordStart >= 0) {
+ nsresult rv = SplitDOMWordAndAppendTo(
+ wordStart, mSoftText.GetValue().Length(), realWords);
+ if (NS_FAILED(rv)) {
+ return Err(rv);
+ }
+ }
+
+ return realWords;
+}
+
+/*********** DOM/realwords<->mSoftText.GetValue() mapping functions
+ * ************/
+
+int32_t mozInlineSpellWordUtil::MapDOMPositionToSoftTextOffset(
+ const NodeOffset& aNodeOffset) const {
+ if (!mSoftText.mIsValid) {
+ NS_ERROR("Soft text must be valid if we're to map into it");
+ return -1;
+ }
+
+ for (int32_t i = 0; i < int32_t(mSoftText.GetDOMMapping().Length()); ++i) {
+ const DOMTextMapping& map = mSoftText.GetDOMMapping()[i];
+ if (map.mNodeOffset.mNode == aNodeOffset.mNode) {
+ // Allow offsets at either end of the string, in particular, allow the
+ // offset that's at the end of the contributed string
+ int32_t offsetInContributedString =
+ aNodeOffset.mOffset - map.mNodeOffset.mOffset;
+ if (offsetInContributedString >= 0 &&
+ offsetInContributedString <= map.mLength)
+ return map.mSoftTextOffset + offsetInContributedString;
+ return -1;
+ }
+ }
+ return -1;
+}
+
+namespace {
+
+template <class T>
+class FirstLargerOffset {
+ int32_t mSoftTextOffset;
+
+ public:
+ explicit FirstLargerOffset(int32_t aSoftTextOffset)
+ : mSoftTextOffset(aSoftTextOffset) {}
+ int operator()(const T& t) const {
+ // We want the first larger offset, so never return 0 (which would
+ // short-circuit evaluation before finding the last such offset).
+ return mSoftTextOffset < t.mSoftTextOffset ? -1 : 1;
+ }
+};
+
+template <class T>
+bool FindLastNongreaterOffset(const nsTArray<T>& aContainer,
+ int32_t aSoftTextOffset, size_t* aIndex) {
+ if (aContainer.Length() == 0) {
+ return false;
+ }
+
+ BinarySearchIf(aContainer, 0, aContainer.Length(),
+ FirstLargerOffset<T>(aSoftTextOffset), aIndex);
+ if (*aIndex > 0) {
+ // There was at least one mapping with offset <= aSoftTextOffset. Step back
+ // to find the last element with |mSoftTextOffset <= aSoftTextOffset|.
+ *aIndex -= 1;
+ } else {
+ // Every mapping had offset greater than aSoftTextOffset.
+ MOZ_ASSERT(aContainer[*aIndex].mSoftTextOffset > aSoftTextOffset);
+ }
+ return true;
+}
+
+} // namespace
+
+NodeOffset mozInlineSpellWordUtil::MapSoftTextOffsetToDOMPosition(
+ int32_t aSoftTextOffset, DOMMapHint aHint) const {
+ MOZ_ASSERT(mSoftText.mIsValid,
+ "Soft text must be valid if we're to map out of it");
+ if (!mSoftText.mIsValid) return NodeOffset(nullptr, -1);
+
+ // Find the last mapping, if any, such that mSoftTextOffset <= aSoftTextOffset
+ size_t index;
+ bool found = FindLastNongreaterOffset(mSoftText.GetDOMMapping(),
+ aSoftTextOffset, &index);
+ if (!found) {
+ return NodeOffset(nullptr, -1);
+ }
+
+ // 'index' is now the last mapping, if any, such that
+ // mSoftTextOffset <= aSoftTextOffset.
+ // If we're doing HINT_END, then we may want to return the end of the
+ // the previous mapping instead of the start of this mapping
+ if (aHint == HINT_END && index > 0) {
+ const DOMTextMapping& map = mSoftText.GetDOMMapping()[index - 1];
+ if (map.mSoftTextOffset + map.mLength == aSoftTextOffset)
+ return NodeOffset(map.mNodeOffset.mNode,
+ map.mNodeOffset.mOffset + map.mLength);
+ }
+
+ // We allow ourselves to return the end of this mapping even if we're
+ // doing HINT_START. This will only happen if there is no mapping which this
+ // point is the start of. I'm not 100% sure this is OK...
+ const DOMTextMapping& map = mSoftText.GetDOMMapping()[index];
+ int32_t offset = aSoftTextOffset - map.mSoftTextOffset;
+ if (offset >= 0 && offset <= map.mLength)
+ return NodeOffset(map.mNodeOffset.mNode, map.mNodeOffset.mOffset + offset);
+
+ return NodeOffset(nullptr, -1);
+}
+
+// static
+void mozInlineSpellWordUtil::ToString(const DOMMapHint aHint,
+ nsACString& aResult) {
+ switch (aHint) {
+ case HINT_BEGIN:
+ aResult.AssignLiteral("begin");
+ break;
+ case HINT_END:
+ aResult.AssignLiteral("end");
+ break;
+ }
+}
+
+int32_t mozInlineSpellWordUtil::FindRealWordContaining(
+ int32_t aSoftTextOffset, DOMMapHint aHint, bool aSearchForward) const {
+ if (MOZ_LOG_TEST(sInlineSpellWordUtilLog, LogLevel::Debug)) {
+ nsAutoCString hint;
+ mozInlineSpellWordUtil::ToString(aHint, hint);
+
+ MOZ_LOG(
+ sInlineSpellWordUtilLog, LogLevel::Debug,
+ ("%s: offset=%i, hint=%s, searchForward=%i.", __FUNCTION__,
+ aSoftTextOffset, hint.get(), static_cast<int32_t>(aSearchForward)));
+ }
+
+ MOZ_ASSERT(mSoftText.mIsValid,
+ "Soft text must be valid if we're to map out of it");
+ if (!mSoftText.mIsValid) return -1;
+
+ // Find the last word, if any, such that mRealWords[index].mSoftTextOffset
+ // <= aSoftTextOffset
+ size_t index;
+ bool found = FindLastNongreaterOffset(mRealWords, aSoftTextOffset, &index);
+ if (!found) {
+ return -1;
+ }
+
+ // 'index' is now the last word, if any, such that
+ // mSoftTextOffset <= aSoftTextOffset.
+ // If we're doing HINT_END, then we may want to return the end of the
+ // the previous word instead of the start of this word
+ if (aHint == HINT_END && index > 0) {
+ const RealWord& word = mRealWords[index - 1];
+ if (word.EndOffset() == aSoftTextOffset) {
+ return index - 1;
+ }
+ }
+
+ // We allow ourselves to return the end of this word even if we're
+ // doing HINT_BEGIN. This will only happen if there is no word which this
+ // point is the start of. I'm not 100% sure this is OK...
+ const RealWord& word = mRealWords[index];
+ int32_t offset = aSoftTextOffset - word.mSoftTextOffset;
+ if (offset >= 0 && offset <= static_cast<int32_t>(word.mLength)) return index;
+
+ if (aSearchForward) {
+ if (mRealWords[0].mSoftTextOffset > aSoftTextOffset) {
+ // All words have mSoftTextOffset > aSoftTextOffset
+ return 0;
+ }
+ // 'index' is the last word such that mSoftTextOffset <= aSoftTextOffset.
+ // Word index+1, if it exists, will be the first with
+ // mSoftTextOffset > aSoftTextOffset.
+ if (index + 1 < mRealWords.Length()) return index + 1;
+ }
+
+ return -1;
+}
+
+// mozInlineSpellWordUtil::SplitDOMWordAndAppendTo
+
+nsresult mozInlineSpellWordUtil::SplitDOMWordAndAppendTo(
+ int32_t aStart, int32_t aEnd, nsTArray<RealWord>& aRealWords) const {
+ nsDependentSubstring targetText(mSoftText.GetValue(), aStart, aEnd - aStart);
+ WordSplitState<nsDependentSubstring> state(targetText);
+ state.mCurCharClass = state.ClassifyCharacter(0, true);
+
+ state.AdvanceThroughSeparators();
+ if (state.mCurCharClass != CHAR_CLASS_END_OF_INPUT && state.IsSpecialWord()) {
+ int32_t specialWordLength =
+ state.mDOMWordText.Length() - state.mDOMWordOffset;
+ if (!aRealWords.AppendElement(
+ RealWord(aStart + state.mDOMWordOffset, specialWordLength, false),
+ fallible)) {
+ return NS_ERROR_OUT_OF_MEMORY;
+ }
+
+ return NS_OK;
+ }
+
+ while (state.mCurCharClass != CHAR_CLASS_END_OF_INPUT) {
+ state.AdvanceThroughSeparators();
+ if (state.mCurCharClass == CHAR_CLASS_END_OF_INPUT) break;
+
+ // save the beginning of the word
+ int32_t wordOffset = state.mDOMWordOffset;
+
+ // find the end of the word
+ state.AdvanceThroughWord();
+ int32_t wordLen = state.mDOMWordOffset - wordOffset;
+ if (!aRealWords.AppendElement(
+ RealWord(aStart + wordOffset, wordLen,
+ !state.ShouldSkipWord(wordOffset, wordLen)),
+ fallible)) {
+ return NS_ERROR_OUT_OF_MEMORY;
+ }
+ }
+
+ return NS_OK;
+}
diff --git a/extensions/spellcheck/src/mozInlineSpellWordUtil.h b/extensions/spellcheck/src/mozInlineSpellWordUtil.h
new file mode 100644
index 0000000000..2a1b4b912e
--- /dev/null
+++ b/extensions/spellcheck/src/mozInlineSpellWordUtil.h
@@ -0,0 +1,253 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef mozInlineSpellWordUtil_h
+#define mozInlineSpellWordUtil_h
+
+#include <utility>
+
+#include "mozilla/Attributes.h"
+#include "mozilla/Maybe.h"
+#include "mozilla/RangeBoundary.h"
+#include "mozilla/Result.h"
+#include "mozilla/dom/Document.h"
+#include "nsCOMPtr.h"
+#include "nsString.h"
+#include "nsTArray.h"
+
+// #define DEBUG_SPELLCHECK
+
+class nsRange;
+class nsINode;
+
+namespace mozilla {
+class EditorBase;
+
+namespace dom {
+class Document;
+}
+} // namespace mozilla
+
+struct NodeOffset {
+ nsCOMPtr<nsINode> mNode;
+ int32_t mOffset;
+
+ NodeOffset() : mOffset(0) {}
+ NodeOffset(nsINode* aNode, int32_t aOffset)
+ : mNode(aNode), mOffset(aOffset) {}
+
+ bool operator==(const NodeOffset& aOther) const {
+ return mNode == aOther.mNode && mOffset == aOther.mOffset;
+ }
+
+ bool operator==(const mozilla::RangeBoundary& aRangeBoundary) const;
+
+ bool operator!=(const NodeOffset& aOther) const { return !(*this == aOther); }
+
+ nsINode* Node() const { return mNode.get(); }
+ int32_t Offset() const { return mOffset; }
+};
+
+class NodeOffsetRange {
+ private:
+ NodeOffset mBegin;
+ NodeOffset mEnd;
+
+ public:
+ NodeOffsetRange() {}
+ NodeOffsetRange(NodeOffset b, NodeOffset e)
+ : mBegin(std::move(b)), mEnd(std::move(e)) {}
+
+ bool operator==(const nsRange& aRange) const;
+
+ const NodeOffset& Begin() const { return mBegin; }
+
+ const NodeOffset& End() const { return mEnd; }
+};
+
+/**
+ * This class extracts text from the DOM and builds it into a single string.
+ * The string includes whitespace breaks whereever non-inline elements begin
+ * and end. This string is broken into "real words", following somewhat
+ * complex rules; for example substrings that look like URLs or
+ * email addresses are treated as single words, but otherwise many kinds of
+ * punctuation are treated as word separators. GetNextWord provides a way
+ * to iterate over these "real words".
+ *
+ * The basic operation is:
+ *
+ * 1. Call Init with the editor that you're using.
+ * 2. Call SetPositionAndEnd to to initialize the current position inside the
+ * previously given range and set where you want to stop spellchecking.
+ * We'll stop at the word boundary after that. If SetEnd is not called,
+ * we'll stop at the end of the root element.
+ * 3. Call GetNextWord over and over until it returns false.
+ */
+
+class MOZ_STACK_CLASS mozInlineSpellWordUtil {
+ public:
+ static mozilla::Maybe<mozInlineSpellWordUtil> Create(
+ const mozilla::EditorBase& aEditorBase);
+
+ // sets the current position, this should be inside the range. If we are in
+ // the middle of a word, we'll move to its start.
+ nsresult SetPositionAndEnd(nsINode* aPositionNode, int32_t aPositionOffset,
+ nsINode* aEndNode, int32_t aEndOffset);
+
+ // Given a point inside or immediately following a word, this returns the
+ // DOM range that exactly encloses that word's characters. The current
+ // position will be at the end of the word. This will find the previous
+ // word if the current position is space, so if you care that the point is
+ // inside the word, you should check the range.
+ //
+ // THIS CHANGES THE CURRENT POSITION AND RANGE. It is designed to be called
+ // before you actually generate the range you are interested in and iterate
+ // the words in it.
+ nsresult GetRangeForWord(nsINode* aWordNode, int32_t aWordOffset,
+ nsRange** aRange);
+
+ // Convenience functions, object must be initialized
+ nsresult MakeRange(NodeOffset aBegin, NodeOffset aEnd,
+ nsRange** aRange) const;
+ static already_AddRefed<nsRange> MakeRange(const NodeOffsetRange& aRange);
+
+ struct Word {
+ nsAutoString mText;
+ NodeOffsetRange mNodeOffsetRange;
+ bool mSkipChecking = false;
+ };
+
+ // Moves to the the next word in the range, and retrieves it's text and range.
+ // `false` is returned when we are done checking.
+ // mSkipChecking will be set if the word is "special" and shouldn't be
+ // checked (e.g., an email address).
+ bool GetNextWord(Word& aWord);
+
+ // Call to normalize some punctuation. This function takes an autostring
+ // so we can access characters directly.
+ static void NormalizeWord(nsAString& aWord);
+
+ mozilla::dom::Document* GetDocument() const { return mDocument; }
+ const nsINode* GetRootNode() const { return mRootNode; }
+
+ private:
+ // A list of where we extracted text from, ordered by mSoftTextOffset. A given
+ // DOM node appears at most once in this list.
+ struct DOMTextMapping {
+ NodeOffset mNodeOffset;
+ int32_t mSoftTextOffset;
+ int32_t mLength;
+
+ DOMTextMapping(NodeOffset aNodeOffset, int32_t aSoftTextOffset,
+ int32_t aLength)
+ : mNodeOffset(std::move(aNodeOffset)),
+ mSoftTextOffset(aSoftTextOffset),
+ mLength(aLength) {}
+ };
+
+ struct SoftText {
+ void AdjustBeginAndBuildText(NodeOffset aBegin, NodeOffset aEnd,
+ const nsINode* aRootNode);
+
+ void Invalidate() { mIsValid = false; }
+
+ const NodeOffset& GetBegin() const { return mBegin; }
+ const NodeOffset& GetEnd() const { return mEnd; }
+
+ const nsTArray<DOMTextMapping>& GetDOMMapping() const {
+ return mDOMMapping;
+ }
+
+ const nsString& GetValue() const { return mValue; }
+
+ bool mIsValid = false;
+
+ private:
+ NodeOffset mBegin = NodeOffset(nullptr, 0);
+ NodeOffset mEnd = NodeOffset(nullptr, 0);
+
+ nsTArray<DOMTextMapping> mDOMMapping;
+
+ // DOM text covering the soft range, with newlines added at block boundaries
+ nsString mValue;
+ };
+
+ SoftText mSoftText;
+
+ mozInlineSpellWordUtil(mozilla::dom::Document& aDocument,
+ bool aIsContentEditableOrDesignMode, nsINode& aRootNode
+
+ )
+ : mDocument(&aDocument),
+ mIsContentEditableOrDesignMode(aIsContentEditableOrDesignMode),
+ mRootNode(&aRootNode),
+ mNextWordIndex(-1) {}
+
+ // cached stuff for the editor
+ const RefPtr<mozilla::dom::Document> mDocument;
+ const bool mIsContentEditableOrDesignMode;
+
+ // range to check, see SetPosition and SetEnd
+ const nsINode* mRootNode;
+
+ // A list of the "real words" in mSoftText.mValue, ordered by mSoftTextOffset
+ struct RealWord {
+ int32_t mSoftTextOffset;
+ uint32_t mLength : 31;
+ uint32_t mCheckableWord : 1;
+
+ RealWord(int32_t aOffset, uint32_t aLength, bool aCheckable)
+ : mSoftTextOffset(aOffset),
+ mLength(aLength),
+ mCheckableWord(aCheckable) {
+ static_assert(sizeof(RealWord) == 8,
+ "RealWord should be limited to 8 bytes");
+ MOZ_ASSERT(aLength < INT32_MAX,
+ "Word length is too large to fit in the bitfield");
+ }
+
+ int32_t EndOffset() const { return mSoftTextOffset + mLength; }
+ };
+ using RealWords = nsTArray<RealWord>;
+ RealWords mRealWords;
+ int32_t mNextWordIndex;
+
+ nsresult EnsureWords(NodeOffset aSoftBegin, NodeOffset aSoftEnd);
+
+ int32_t MapDOMPositionToSoftTextOffset(const NodeOffset& aNodeOffset) const;
+ // Map an offset into mSoftText.mValue to a DOM position. Note that two DOM
+ // positions can map to the same mSoftText.mValue offset, e.g. given nodes
+ // A=aaaa and B=bbbb forming aaaabbbb, (A,4) and (B,0) give the same string
+ // offset. So, aHintBefore controls which position we return ... if aHint is
+ // eEnd then the position indicates the END of a range so we return (A,4).
+ // Otherwise the position indicates the START of a range so we return (B,0).
+ enum DOMMapHint { HINT_BEGIN, HINT_END };
+ NodeOffset MapSoftTextOffsetToDOMPosition(int32_t aSoftTextOffset,
+ DOMMapHint aHint) const;
+
+ static void ToString(DOMMapHint aHint, nsACString& aResult);
+
+ // Finds the index of the real word containing aSoftTextOffset, or -1 if none.
+ //
+ // If it's exactly between two words, then if aHint is HINT_BEGIN, return the
+ // later word (favouring the assumption that it's the BEGINning of a word),
+ // otherwise return the earlier word (assuming it's the END of a word).
+ // If aSearchForward is true, then if we don't find a word at the given
+ // position, search forward until we do find a word and return that (if
+ // found).
+ int32_t FindRealWordContaining(int32_t aSoftTextOffset, DOMMapHint aHint,
+ bool aSearchForward) const;
+
+ mozilla::Result<RealWords, nsresult> BuildRealWords() const;
+
+ nsresult SplitDOMWordAndAppendTo(int32_t aStart, int32_t aEnd,
+ nsTArray<RealWord>& aRealWords) const;
+
+ nsresult MakeRangeForWord(const RealWord& aWord, nsRange** aRange) const;
+ void MakeNodeOffsetRangeForWord(const RealWord& aWord,
+ NodeOffsetRange* aNodeOffsetRange);
+};
+
+#endif
diff --git a/extensions/spellcheck/src/mozPersonalDictionary.cpp b/extensions/spellcheck/src/mozPersonalDictionary.cpp
new file mode 100644
index 0000000000..752369c034
--- /dev/null
+++ b/extensions/spellcheck/src/mozPersonalDictionary.cpp
@@ -0,0 +1,433 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "mozPersonalDictionary.h"
+
+#include <utility>
+
+#include "nsAppDirectoryServiceDefs.h"
+#include "nsCRT.h"
+#include "nsIFile.h"
+#include "nsIInputStream.h"
+#include "nsIObserverService.h"
+#include "nsIOutputStream.h"
+#include "nsIRunnable.h"
+#include "nsISafeOutputStream.h"
+#include "nsIUnicharInputStream.h"
+#include "nsIWeakReference.h"
+#include "nsNetCID.h"
+#include "nsNetUtil.h"
+#include "nsProxyRelease.h"
+#include "nsReadableUtils.h"
+#include "nsStringEnumerator.h"
+#include "nsTArray.h"
+#include "nsThreadUtils.h"
+#include "nsUnicharInputStream.h"
+#include "prio.h"
+
+#define MOZ_PERSONAL_DICT_NAME u"persdict.dat"
+
+/**
+ * This is the most braindead implementation of a personal dictionary possible.
+ * There is not much complexity needed, though. It could be made much faster,
+ * and probably should, but I don't see much need for more in terms of
+ * interface.
+ *
+ * Allowing personal words to be associated with only certain dictionaries
+ * maybe.
+ *
+ * TODO:
+ * Implement the suggestion record.
+ */
+
+NS_IMPL_ADDREF(mozPersonalDictionary)
+NS_IMPL_RELEASE(mozPersonalDictionary)
+
+NS_INTERFACE_MAP_BEGIN(mozPersonalDictionary)
+ NS_INTERFACE_MAP_ENTRY(mozIPersonalDictionary)
+ NS_INTERFACE_MAP_ENTRY(nsIObserver)
+ NS_INTERFACE_MAP_ENTRY(nsISupportsWeakReference)
+ NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, mozIPersonalDictionary)
+NS_INTERFACE_MAP_END
+
+class mozPersonalDictionaryLoader final : public mozilla::Runnable {
+ public:
+ explicit mozPersonalDictionaryLoader(mozPersonalDictionary* dict)
+ : mozilla::Runnable("mozPersonalDictionaryLoader"), mDict(dict) {}
+
+ NS_IMETHOD Run() override {
+ mDict->SyncLoad();
+
+ // Release the dictionary on the main thread
+ NS_ReleaseOnMainThread("mozPersonalDictionaryLoader::mDict",
+ mDict.forget().downcast<mozIPersonalDictionary>());
+
+ return NS_OK;
+ }
+
+ private:
+ RefPtr<mozPersonalDictionary> mDict;
+};
+
+class mozPersonalDictionarySave final : public mozilla::Runnable {
+ public:
+ explicit mozPersonalDictionarySave(mozPersonalDictionary* aDict,
+ nsCOMPtr<nsIFile> aFile,
+ nsTArray<nsString>&& aDictWords)
+ : mozilla::Runnable("mozPersonalDictionarySave"),
+ mDictWords(std::move(aDictWords)),
+ mFile(aFile),
+ mDict(aDict) {}
+
+ NS_IMETHOD Run() override {
+ nsresult res;
+
+ MOZ_ASSERT(!NS_IsMainThread());
+
+ {
+ mozilla::MonitorAutoLock mon(mDict->mMonitorSave);
+
+ nsCOMPtr<nsIOutputStream> outStream;
+ NS_NewSafeLocalFileOutputStream(getter_AddRefs(outStream), mFile,
+ PR_CREATE_FILE | PR_WRONLY | PR_TRUNCATE,
+ 0664);
+
+ // Get a buffered output stream 4096 bytes big, to optimize writes.
+ nsCOMPtr<nsIOutputStream> bufferedOutputStream;
+ res = NS_NewBufferedOutputStream(getter_AddRefs(bufferedOutputStream),
+ outStream.forget(), 4096);
+ if (NS_FAILED(res)) {
+ return res;
+ }
+
+ uint32_t bytesWritten;
+ nsAutoCString utf8Key;
+ for (uint32_t i = 0; i < mDictWords.Length(); ++i) {
+ CopyUTF16toUTF8(mDictWords[i], utf8Key);
+
+ bufferedOutputStream->Write(utf8Key.get(), utf8Key.Length(),
+ &bytesWritten);
+ bufferedOutputStream->Write("\n", 1, &bytesWritten);
+ }
+ nsCOMPtr<nsISafeOutputStream> safeStream =
+ do_QueryInterface(bufferedOutputStream);
+ NS_ASSERTION(safeStream, "expected a safe output stream!");
+ if (safeStream) {
+ res = safeStream->Finish();
+ if (NS_FAILED(res)) {
+ NS_WARNING(
+ "failed to save personal dictionary file! possible data loss");
+ }
+ }
+
+ // Save is done, reset the state variable and notify those who are
+ // waiting.
+ mDict->mSavePending = false;
+ mon.Notify();
+
+ // Leaving the block where 'mon' was declared will call the destructor
+ // and unlock.
+ }
+
+ // Release the dictionary on the main thread.
+ NS_ReleaseOnMainThread("mozPersonalDictionarySave::mDict",
+ mDict.forget().downcast<mozIPersonalDictionary>());
+
+ return NS_OK;
+ }
+
+ private:
+ nsTArray<nsString> mDictWords;
+ nsCOMPtr<nsIFile> mFile;
+ RefPtr<mozPersonalDictionary> mDict;
+};
+
+mozPersonalDictionary::mozPersonalDictionary()
+ : mIsLoaded(false),
+ mSavePending(false),
+ mMonitor("mozPersonalDictionary::mMonitor"),
+ mMonitorSave("mozPersonalDictionary::mMonitorSave") {}
+
+mozPersonalDictionary::~mozPersonalDictionary() {}
+
+nsresult mozPersonalDictionary::Init() {
+ nsCOMPtr<nsIObserverService> svc =
+ do_GetService("@mozilla.org/observer-service;1");
+
+ NS_ENSURE_STATE(svc);
+ // we want to reload the dictionary if the profile switches
+ nsresult rv = svc->AddObserver(this, "profile-do-change", true);
+ if (NS_WARN_IF(NS_FAILED(rv))) {
+ return rv;
+ }
+
+ rv = svc->AddObserver(this, "profile-before-change", true);
+ if (NS_WARN_IF(NS_FAILED(rv))) {
+ return rv;
+ }
+
+ Load();
+
+ return NS_OK;
+}
+
+void mozPersonalDictionary::WaitForLoad() {
+ // If the dictionary is already loaded, we return straight away.
+ if (mIsLoaded) {
+ return;
+ }
+
+ // If the dictionary hasn't been loaded, we try to lock the same monitor
+ // that the thread uses that does the load. This way the main thread will
+ // be suspended until the monitor becomes available.
+ mozilla::MonitorAutoLock mon(mMonitor);
+
+ // The monitor has become available. This can have two reasons:
+ // 1: The thread that does the load has finished.
+ // 2: The thread that does the load hasn't even started.
+ // In this case we need to wait.
+ if (!mIsLoaded) {
+ mon.Wait();
+ }
+}
+
+nsresult mozPersonalDictionary::LoadInternal() {
+ nsresult rv;
+ mozilla::MonitorAutoLock mon(mMonitor);
+
+ if (mIsLoaded) {
+ return NS_OK;
+ }
+
+ rv =
+ NS_GetSpecialDirectory(NS_APP_USER_PROFILE_50_DIR, getter_AddRefs(mFile));
+ if (NS_WARN_IF(NS_FAILED(rv))) {
+ return rv;
+ }
+
+ if (!mFile) {
+ return NS_ERROR_FAILURE;
+ }
+
+ rv = mFile->Append(nsLiteralString(MOZ_PERSONAL_DICT_NAME));
+ if (NS_WARN_IF(NS_FAILED(rv))) {
+ return rv;
+ }
+
+ nsCOMPtr<nsIEventTarget> target =
+ do_GetService(NS_STREAMTRANSPORTSERVICE_CONTRACTID, &rv);
+ if (NS_WARN_IF(NS_FAILED(rv))) {
+ return rv;
+ }
+
+ nsCOMPtr<nsIRunnable> runnable = new mozPersonalDictionaryLoader(this);
+ rv = target->Dispatch(runnable, NS_DISPATCH_NORMAL);
+ if (NS_WARN_IF(NS_FAILED(rv))) {
+ return rv;
+ }
+
+ return NS_OK;
+}
+
+NS_IMETHODIMP mozPersonalDictionary::Load() {
+ nsresult rv = LoadInternal();
+
+ if (NS_FAILED(rv)) {
+ mIsLoaded = true;
+ }
+
+ return rv;
+}
+
+void mozPersonalDictionary::SyncLoad() {
+ MOZ_ASSERT(!NS_IsMainThread());
+
+ mozilla::MonitorAutoLock mon(mMonitor);
+
+ if (mIsLoaded) {
+ return;
+ }
+
+ SyncLoadInternal();
+ mIsLoaded = true;
+ mon.Notify();
+}
+
+void mozPersonalDictionary::SyncLoadInternal() {
+ MOZ_ASSERT(!NS_IsMainThread());
+
+ // FIXME Deinst -- get dictionary name from prefs;
+ nsresult rv;
+ bool dictExists;
+
+ rv = mFile->Exists(&dictExists);
+ if (NS_FAILED(rv)) {
+ return;
+ }
+
+ if (!dictExists) {
+ // Nothing is really wrong...
+ return;
+ }
+
+ nsCOMPtr<nsIInputStream> inStream;
+ NS_NewLocalFileInputStream(getter_AddRefs(inStream), mFile);
+
+ nsCOMPtr<nsIUnicharInputStream> convStream;
+ rv = NS_NewUnicharInputStream(inStream, getter_AddRefs(convStream));
+ if (NS_FAILED(rv)) {
+ return;
+ }
+
+ // we're rereading to get rid of the old data -- we shouldn't have any,
+ // but...
+ mDictionaryTable.Clear();
+
+ char16_t c;
+ uint32_t nRead;
+ bool done = false;
+ do { // read each line of text into the string array.
+ if ((NS_OK != convStream->Read(&c, 1, &nRead)) || (nRead != 1)) break;
+ while (!done && ((c == '\n') || (c == '\r'))) {
+ if ((NS_OK != convStream->Read(&c, 1, &nRead)) || (nRead != 1))
+ done = true;
+ }
+ if (!done) {
+ nsAutoString word;
+ while ((c != '\n') && (c != '\r') && !done) {
+ word.Append(c);
+ if ((NS_OK != convStream->Read(&c, 1, &nRead)) || (nRead != 1))
+ done = true;
+ }
+ mDictionaryTable.Insert(word);
+ }
+ } while (!done);
+}
+
+void mozPersonalDictionary::WaitForSave() {
+ // If no save is pending, we return straight away.
+ if (!mSavePending) {
+ return;
+ }
+
+ // If a save is pending, we try to lock the same monitor that the thread uses
+ // that does the save. This way the main thread will be suspended until the
+ // monitor becomes available.
+ mozilla::MonitorAutoLock mon(mMonitorSave);
+
+ // The monitor has become available. This can have two reasons:
+ // 1: The thread that does the save has finished.
+ // 2: The thread that does the save hasn't even started.
+ // In this case we need to wait.
+ if (mSavePending) {
+ mon.Wait();
+ }
+}
+
+NS_IMETHODIMP mozPersonalDictionary::Save() {
+ nsCOMPtr<nsIFile> theFile;
+ nsresult res;
+
+ WaitForSave();
+
+ mSavePending = true;
+
+ // FIXME Deinst -- get dictionary name from prefs;
+ res = NS_GetSpecialDirectory(NS_APP_USER_PROFILE_50_DIR,
+ getter_AddRefs(theFile));
+ if (NS_FAILED(res)) return res;
+ if (!theFile) return NS_ERROR_FAILURE;
+ res = theFile->Append(nsLiteralString(MOZ_PERSONAL_DICT_NAME));
+ if (NS_FAILED(res)) return res;
+
+ nsCOMPtr<nsIEventTarget> target =
+ do_GetService(NS_STREAMTRANSPORTSERVICE_CONTRACTID, &res);
+ if (NS_WARN_IF(NS_FAILED(res))) {
+ return res;
+ }
+
+ nsCOMPtr<nsIRunnable> runnable = new mozPersonalDictionarySave(
+ this, theFile, mozilla::ToTArray<nsTArray<nsString>>(mDictionaryTable));
+ res = target->Dispatch(runnable, NS_DISPATCH_NORMAL);
+ if (NS_WARN_IF(NS_FAILED(res))) {
+ return res;
+ }
+ return res;
+}
+
+NS_IMETHODIMP mozPersonalDictionary::GetWordList(nsIStringEnumerator** aWords) {
+ NS_ENSURE_ARG_POINTER(aWords);
+ *aWords = nullptr;
+
+ WaitForLoad();
+
+ nsTArray<nsString>* array = new nsTArray<nsString>(
+ mozilla::ToTArray<nsTArray<nsString>>(mDictionaryTable));
+
+ array->Sort();
+
+ return NS_NewAdoptingStringEnumerator(aWords, array);
+}
+
+NS_IMETHODIMP
+mozPersonalDictionary::Check(const nsAString& aWord, bool* aResult) {
+ NS_ENSURE_ARG_POINTER(aResult);
+
+ WaitForLoad();
+
+ *aResult = (mDictionaryTable.Contains(aWord) || mIgnoreTable.Contains(aWord));
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+mozPersonalDictionary::AddWord(const nsAString& aWord) {
+ nsresult res;
+ WaitForLoad();
+
+ mDictionaryTable.Insert(aWord);
+ res = Save();
+ return res;
+}
+
+NS_IMETHODIMP
+mozPersonalDictionary::RemoveWord(const nsAString& aWord) {
+ nsresult res;
+ WaitForLoad();
+
+ mDictionaryTable.Remove(aWord);
+ res = Save();
+ return res;
+}
+
+NS_IMETHODIMP
+mozPersonalDictionary::IgnoreWord(const nsAString& aWord) {
+ // avoid adding duplicate words to the ignore list
+ mIgnoreTable.EnsureInserted(aWord);
+ return NS_OK;
+}
+
+NS_IMETHODIMP mozPersonalDictionary::EndSession() {
+ WaitForLoad();
+
+ WaitForSave();
+ mIgnoreTable.Clear();
+ return NS_OK;
+}
+
+NS_IMETHODIMP mozPersonalDictionary::Observe(nsISupports* aSubject,
+ const char* aTopic,
+ const char16_t* aData) {
+ if (!nsCRT::strcmp(aTopic, "profile-do-change")) {
+ // The observer is registered in Init() which calls Load and in turn
+ // LoadInternal(); i.e. Observe() can't be called before Load().
+ WaitForLoad();
+ mIsLoaded = false;
+ Load(); // load automatically clears out the existing dictionary table
+ } else if (!nsCRT::strcmp(aTopic, "profile-before-change")) {
+ WaitForSave();
+ }
+
+ return NS_OK;
+}
diff --git a/extensions/spellcheck/src/mozPersonalDictionary.h b/extensions/spellcheck/src/mozPersonalDictionary.h
new file mode 100644
index 0000000000..584c7edf56
--- /dev/null
+++ b/extensions/spellcheck/src/mozPersonalDictionary.h
@@ -0,0 +1,80 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef mozPersonalDictionary_h__
+#define mozPersonalDictionary_h__
+
+#include "nsCOMPtr.h"
+#include "nsString.h"
+#include "mozIPersonalDictionary.h"
+#include "nsIObserver.h"
+#include "nsWeakReference.h"
+#include "nsTHashSet.h"
+#include "nsCRT.h"
+#include "nsCycleCollectionParticipant.h"
+#include "nsHashKeys.h"
+#include <mozilla/Monitor.h>
+
+#define MOZ_PERSONALDICTIONARY_CONTRACTID \
+ "@mozilla.org/spellchecker/personaldictionary;1"
+#define MOZ_PERSONALDICTIONARY_CID \
+ { /* 7EF52EAF-B7E1-462B-87E2-5D1DBACA9048 */ \
+ 0X7EF52EAF, 0XB7E1, 0X462B, { \
+ 0X87, 0XE2, 0X5D, 0X1D, 0XBA, 0XCA, 0X90, 0X48 \
+ } \
+ }
+
+class mozPersonalDictionaryLoader;
+class mozPersonalDictionarySave;
+
+class mozPersonalDictionary final : public mozIPersonalDictionary,
+ public nsIObserver,
+ public nsSupportsWeakReference {
+ public:
+ NS_DECL_ISUPPORTS
+ NS_DECL_MOZIPERSONALDICTIONARY
+ NS_DECL_NSIOBSERVER
+
+ mozPersonalDictionary();
+
+ nsresult Init();
+
+ protected:
+ virtual ~mozPersonalDictionary();
+
+ /* true if the dictionary has been loaded from disk */
+ bool mIsLoaded;
+
+ /* true if a dictionary save is pending */
+ bool mSavePending;
+
+ nsCOMPtr<nsIFile> mFile;
+ mozilla::Monitor mMonitor MOZ_UNANNOTATED;
+ mozilla::Monitor mMonitorSave MOZ_UNANNOTATED;
+ nsTHashSet<nsString> mDictionaryTable;
+ nsTHashSet<nsString> mIgnoreTable;
+
+ private:
+ /* wait for the asynchronous load of the dictionary to be completed */
+ void WaitForLoad();
+
+ /* enter the monitor before starting a synchronous load off the main-thread */
+ void SyncLoad();
+
+ /* launch an asynchrounous load of the dictionary from the main-thread
+ * after successfully initializing mFile with the path of the dictionary */
+ nsresult LoadInternal();
+
+ /* perform a synchronous load of the dictionary from disk */
+ void SyncLoadInternal();
+
+ /* wait for the asynchronous save of the dictionary to be completed */
+ void WaitForSave();
+
+ friend class mozPersonalDictionaryLoader;
+ friend class mozPersonalDictionarySave;
+};
+
+#endif
diff --git a/extensions/spellcheck/src/mozSpellChecker.cpp b/extensions/spellcheck/src/mozSpellChecker.cpp
new file mode 100644
index 0000000000..d5b0537bfe
--- /dev/null
+++ b/extensions/spellcheck/src/mozSpellChecker.cpp
@@ -0,0 +1,681 @@
+/* vim: set ts=2 sts=2 sw=2 tw=80: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "mozSpellChecker.h"
+#include "nsIStringEnumerator.h"
+#include "nsICategoryManager.h"
+#include "nsISupportsPrimitives.h"
+#include "nsISimpleEnumerator.h"
+#include "mozEnglishWordUtils.h"
+#include "mozilla/dom/ContentChild.h"
+#include "mozilla/Logging.h"
+#include "mozilla/PRemoteSpellcheckEngineChild.h"
+#include "mozilla/TextServicesDocument.h"
+#include "nsXULAppAPI.h"
+#include "RemoteSpellCheckEngineChild.h"
+
+using mozilla::AssertedCast;
+using mozilla::GenericPromise;
+using mozilla::LogLevel;
+using mozilla::RemoteSpellcheckEngineChild;
+using mozilla::TextServicesDocument;
+using mozilla::dom::ContentChild;
+
+#define DEFAULT_SPELL_CHECKER "@mozilla.org/spellchecker/engine;1"
+
+static mozilla::LazyLogModule sSpellChecker("SpellChecker");
+
+NS_IMPL_CYCLE_COLLECTION(mozSpellChecker, mTextServicesDocument,
+ mPersonalDictionary)
+
+mozSpellChecker::mozSpellChecker() : mEngine(nullptr) {}
+
+mozSpellChecker::~mozSpellChecker() {
+ if (mPersonalDictionary) {
+ // mPersonalDictionary->Save();
+ mPersonalDictionary->EndSession();
+ }
+ mSpellCheckingEngine = nullptr;
+ mPersonalDictionary = nullptr;
+
+ if (mEngine) {
+ MOZ_ASSERT(XRE_IsContentProcess());
+ RemoteSpellcheckEngineChild::Send__delete__(mEngine);
+ MOZ_ASSERT(!mEngine);
+ }
+}
+
+nsresult mozSpellChecker::Init() {
+ mSpellCheckingEngine = nullptr;
+ if (XRE_IsContentProcess()) {
+ mozilla::dom::ContentChild* contentChild =
+ mozilla::dom::ContentChild::GetSingleton();
+ MOZ_ASSERT(contentChild);
+ mEngine = new RemoteSpellcheckEngineChild(this);
+ contentChild->SendPRemoteSpellcheckEngineConstructor(mEngine);
+ } else {
+ mPersonalDictionary =
+ do_GetService("@mozilla.org/spellchecker/personaldictionary;1");
+ }
+
+ return NS_OK;
+}
+
+TextServicesDocument* mozSpellChecker::GetTextServicesDocument() {
+ return mTextServicesDocument;
+}
+
+nsresult mozSpellChecker::SetDocument(
+ TextServicesDocument* aTextServicesDocument, bool aFromStartofDoc) {
+ MOZ_LOG(sSpellChecker, LogLevel::Debug, ("%s", __FUNCTION__));
+
+ mTextServicesDocument = aTextServicesDocument;
+ mFromStart = aFromStartofDoc;
+ return NS_OK;
+}
+
+nsresult mozSpellChecker::NextMisspelledWord(nsAString& aWord,
+ nsTArray<nsString>& aSuggestions) {
+ if (NS_WARN_IF(!mConverter)) {
+ return NS_ERROR_NOT_INITIALIZED;
+ }
+
+ int32_t selOffset;
+ nsresult result;
+ result = SetupDoc(&selOffset);
+ if (NS_FAILED(result)) return result;
+
+ bool done;
+ while (NS_SUCCEEDED(mTextServicesDocument->IsDone(&done)) && !done) {
+ int32_t begin, end;
+ nsAutoString str;
+ mTextServicesDocument->GetCurrentTextBlock(str);
+ while (mConverter->FindNextWord(str, selOffset, &begin, &end)) {
+ const nsDependentSubstring currWord(str, begin, end - begin);
+ bool isMisspelled;
+ result = CheckWord(currWord, &isMisspelled, &aSuggestions);
+ if (NS_WARN_IF(NS_FAILED(result))) {
+ return result;
+ }
+ if (isMisspelled) {
+ aWord = currWord;
+ MOZ_KnownLive(mTextServicesDocument)
+ ->SetSelection(AssertedCast<uint32_t>(begin),
+ AssertedCast<uint32_t>(end - begin));
+ // After ScrollSelectionIntoView(), the pending notifications might
+ // be flushed and PresShell/PresContext/Frames may be dead.
+ // See bug 418470.
+ mTextServicesDocument->ScrollSelectionIntoView();
+ return NS_OK;
+ }
+ selOffset = end;
+ }
+ mTextServicesDocument->NextBlock();
+ selOffset = 0;
+ }
+ return NS_OK;
+}
+
+RefPtr<mozilla::CheckWordPromise> mozSpellChecker::CheckWords(
+ const nsTArray<nsString>& aWords) {
+ if (XRE_IsContentProcess()) {
+ return mEngine->CheckWords(aWords);
+ }
+
+ nsTArray<bool> misspells;
+ misspells.SetCapacity(aWords.Length());
+ for (auto& word : aWords) {
+ bool misspelled;
+ nsresult rv = CheckWord(word, &misspelled, nullptr);
+ if (NS_WARN_IF(NS_FAILED(rv))) {
+ return mozilla::CheckWordPromise::CreateAndReject(rv, __func__);
+ }
+ misspells.AppendElement(misspelled);
+ }
+ return mozilla::CheckWordPromise::CreateAndResolve(std::move(misspells),
+ __func__);
+}
+
+nsresult mozSpellChecker::CheckWord(const nsAString& aWord, bool* aIsMisspelled,
+ nsTArray<nsString>* aSuggestions) {
+ if (XRE_IsContentProcess()) {
+ // Use async version (CheckWords or Suggest) on content process
+ return NS_ERROR_FAILURE;
+ }
+
+ nsresult result;
+ bool correct;
+
+ if (!mSpellCheckingEngine) {
+ return NS_ERROR_NULL_POINTER;
+ }
+ *aIsMisspelled = false;
+ result = mSpellCheckingEngine->Check(aWord, &correct);
+ NS_ENSURE_SUCCESS(result, result);
+ if (!correct) {
+ if (aSuggestions) {
+ result = mSpellCheckingEngine->Suggest(aWord, *aSuggestions);
+ NS_ENSURE_SUCCESS(result, result);
+ }
+ *aIsMisspelled = true;
+ }
+ return NS_OK;
+}
+
+RefPtr<mozilla::SuggestionsPromise> mozSpellChecker::Suggest(
+ const nsAString& aWord, uint32_t aMaxCount) {
+ if (XRE_IsContentProcess()) {
+ return mEngine->SendSuggest(aWord, aMaxCount)
+ ->Then(
+ mozilla::GetCurrentSerialEventTarget(), __func__,
+ [](nsTArray<nsString>&& aSuggestions) {
+ return mozilla::SuggestionsPromise::CreateAndResolve(
+ std::move(aSuggestions), __func__);
+ },
+ [](mozilla::ipc::ResponseRejectReason&& aReason) {
+ return mozilla::SuggestionsPromise::CreateAndReject(
+ NS_ERROR_NOT_AVAILABLE, __func__);
+ });
+ }
+
+ if (!mSpellCheckingEngine) {
+ return mozilla::SuggestionsPromise::CreateAndReject(NS_ERROR_NOT_AVAILABLE,
+ __func__);
+ }
+
+ bool correct;
+ nsresult rv = mSpellCheckingEngine->Check(aWord, &correct);
+ if (NS_FAILED(rv)) {
+ return mozilla::SuggestionsPromise::CreateAndReject(rv, __func__);
+ }
+ nsTArray<nsString> suggestions;
+ if (!correct) {
+ rv = mSpellCheckingEngine->Suggest(aWord, suggestions);
+ if (NS_FAILED(rv)) {
+ return mozilla::SuggestionsPromise::CreateAndReject(rv, __func__);
+ }
+ if (suggestions.Length() > aMaxCount) {
+ suggestions.TruncateLength(aMaxCount);
+ }
+ }
+ return mozilla::SuggestionsPromise::CreateAndResolve(std::move(suggestions),
+ __func__);
+}
+
+nsresult mozSpellChecker::Replace(const nsAString& aOldWord,
+ const nsAString& aNewWord,
+ bool aAllOccurrences) {
+ if (NS_WARN_IF(!mConverter)) {
+ return NS_ERROR_NOT_INITIALIZED;
+ }
+
+ if (!aAllOccurrences) {
+ MOZ_KnownLive(mTextServicesDocument)->InsertText(aNewWord);
+ return NS_OK;
+ }
+
+ int32_t selOffset;
+ int32_t startBlock;
+ int32_t begin, end;
+ bool done;
+ nsresult result;
+
+ // find out where we are
+ result = SetupDoc(&selOffset);
+ if (NS_WARN_IF(NS_FAILED(result))) {
+ return result;
+ }
+ result = GetCurrentBlockIndex(mTextServicesDocument, &startBlock);
+ if (NS_WARN_IF(NS_FAILED(result))) {
+ return result;
+ }
+
+ // start at the beginning
+ result = mTextServicesDocument->FirstBlock();
+ if (NS_WARN_IF(NS_FAILED(result))) {
+ return result;
+ }
+ int32_t currOffset = 0;
+ int32_t currentBlock = 0;
+ int32_t wordLengthDifference =
+ AssertedCast<int32_t>(static_cast<int64_t>(aNewWord.Length()) -
+ static_cast<int64_t>(aOldWord.Length()));
+ while (NS_SUCCEEDED(mTextServicesDocument->IsDone(&done)) && !done) {
+ nsAutoString str;
+ mTextServicesDocument->GetCurrentTextBlock(str);
+ while (mConverter->FindNextWord(str, currOffset, &begin, &end)) {
+ if (aOldWord.Equals(Substring(str, begin, end - begin))) {
+ // if we are before the current selection point but in the same
+ // block move the selection point forwards
+ if (currentBlock == startBlock && begin < selOffset) {
+ selOffset += wordLengthDifference;
+ if (selOffset < begin) {
+ selOffset = begin;
+ }
+ }
+ // Don't keep running if selecting or inserting text fails because
+ // it may cause infinite loop.
+ if (NS_WARN_IF(NS_FAILED(
+ MOZ_KnownLive(mTextServicesDocument)
+ ->SetSelection(AssertedCast<uint32_t>(begin),
+ AssertedCast<uint32_t>(end - begin))))) {
+ return NS_ERROR_FAILURE;
+ }
+ if (NS_WARN_IF(NS_FAILED(
+ MOZ_KnownLive(mTextServicesDocument)->InsertText(aNewWord)))) {
+ return NS_ERROR_FAILURE;
+ }
+ mTextServicesDocument->GetCurrentTextBlock(str);
+ end += wordLengthDifference; // recursion was cute in GEB, not here.
+ }
+ currOffset = end;
+ }
+ mTextServicesDocument->NextBlock();
+ currentBlock++;
+ currOffset = 0;
+ }
+
+ // We are done replacing. Put the selection point back where we found it
+ // (or equivalent);
+ result = mTextServicesDocument->FirstBlock();
+ if (NS_WARN_IF(NS_FAILED(result))) {
+ return result;
+ }
+ currentBlock = 0;
+ while (NS_SUCCEEDED(mTextServicesDocument->IsDone(&done)) && !done &&
+ currentBlock < startBlock) {
+ mTextServicesDocument->NextBlock();
+ }
+
+ // After we have moved to the block where the first occurrence of replace
+ // was done, put the selection to the next word following it. In case there
+ // is no word following it i.e if it happens to be the last word in that
+ // block, then move to the next block and put the selection to the first
+ // word in that block, otherwise when the Setupdoc() is called, it queries
+ // the LastSelectedBlock() and the selection offset of the last occurrence
+ // of the replaced word is taken instead of the first occurrence and things
+ // get messed up as reported in the bug 244969
+
+ if (NS_SUCCEEDED(mTextServicesDocument->IsDone(&done)) && !done) {
+ nsAutoString str;
+ mTextServicesDocument->GetCurrentTextBlock(str);
+ if (mConverter->FindNextWord(str, selOffset, &begin, &end)) {
+ MOZ_KnownLive(mTextServicesDocument)
+ ->SetSelection(AssertedCast<uint32_t>(begin), 0);
+ return NS_OK;
+ }
+ mTextServicesDocument->NextBlock();
+ mTextServicesDocument->GetCurrentTextBlock(str);
+ if (mConverter->FindNextWord(str, 0, &begin, &end)) {
+ MOZ_KnownLive(mTextServicesDocument)
+ ->SetSelection(AssertedCast<uint32_t>(begin), 0);
+ }
+ }
+ return NS_OK;
+}
+
+nsresult mozSpellChecker::IgnoreAll(const nsAString& aWord) {
+ if (mPersonalDictionary) {
+ mPersonalDictionary->IgnoreWord(aWord);
+ }
+ return NS_OK;
+}
+
+nsresult mozSpellChecker::AddWordToPersonalDictionary(const nsAString& aWord) {
+ nsresult res;
+ if (NS_WARN_IF(!mPersonalDictionary)) {
+ return NS_ERROR_NOT_INITIALIZED;
+ }
+ res = mPersonalDictionary->AddWord(aWord);
+ return res;
+}
+
+nsresult mozSpellChecker::RemoveWordFromPersonalDictionary(
+ const nsAString& aWord) {
+ nsresult res;
+ if (NS_WARN_IF(!mPersonalDictionary)) {
+ return NS_ERROR_NOT_INITIALIZED;
+ }
+ res = mPersonalDictionary->RemoveWord(aWord);
+ return res;
+}
+
+nsresult mozSpellChecker::GetPersonalDictionary(nsTArray<nsString>* aWordList) {
+ if (!aWordList || !mPersonalDictionary) return NS_ERROR_NULL_POINTER;
+
+ nsCOMPtr<nsIStringEnumerator> words;
+ mPersonalDictionary->GetWordList(getter_AddRefs(words));
+
+ bool hasMore;
+ nsAutoString word;
+ while (NS_SUCCEEDED(words->HasMore(&hasMore)) && hasMore) {
+ words->GetNext(word);
+ aWordList->AppendElement(word);
+ }
+ return NS_OK;
+}
+
+nsresult mozSpellChecker::GetDictionaryList(
+ nsTArray<nsCString>* aDictionaryList) {
+ MOZ_ASSERT(aDictionaryList->IsEmpty());
+ if (XRE_IsContentProcess()) {
+ ContentChild* child = ContentChild::GetSingleton();
+ child->GetAvailableDictionaries(*aDictionaryList);
+ return NS_OK;
+ }
+
+ nsresult rv;
+
+ // For catching duplicates
+ nsTHashSet<nsCString> dictionaries;
+
+ nsCOMArray<mozISpellCheckingEngine> spellCheckingEngines;
+ rv = GetEngineList(&spellCheckingEngines);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ for (int32_t i = 0; i < spellCheckingEngines.Count(); i++) {
+ nsCOMPtr<mozISpellCheckingEngine> engine = spellCheckingEngines[i];
+
+ nsTArray<nsCString> dictNames;
+ engine->GetDictionaryList(dictNames);
+ for (auto& dictName : dictNames) {
+ // Skip duplicate dictionaries. Only take the first one
+ // for each name.
+ if (!dictionaries.EnsureInserted(dictName)) continue;
+
+ aDictionaryList->AppendElement(dictName);
+ }
+ }
+
+ return NS_OK;
+}
+
+nsresult mozSpellChecker::GetCurrentDictionaries(
+ nsTArray<nsCString>& aDictionaries) {
+ if (XRE_IsContentProcess()) {
+ aDictionaries = mCurrentDictionaries.Clone();
+ return NS_OK;
+ }
+
+ if (!mSpellCheckingEngine) {
+ aDictionaries.Clear();
+ return NS_OK;
+ }
+
+ return mSpellCheckingEngine->GetDictionaries(aDictionaries);
+}
+
+nsresult mozSpellChecker::SetCurrentDictionary(const nsACString& aDictionary) {
+ if (XRE_IsContentProcess()) {
+ mCurrentDictionaries.Clear();
+ bool isSuccess;
+ mEngine->SendSetDictionary(aDictionary, &isSuccess);
+ if (!isSuccess) {
+ return NS_ERROR_NOT_AVAILABLE;
+ }
+
+ mCurrentDictionaries.AppendElement(aDictionary);
+ return NS_OK;
+ }
+
+ // Calls to mozISpellCheckingEngine::SetDictionary might destroy us
+ RefPtr<mozSpellChecker> kungFuDeathGrip = this;
+
+ mSpellCheckingEngine = nullptr;
+
+ if (aDictionary.IsEmpty()) {
+ return NS_OK;
+ }
+
+ nsresult rv;
+ nsCOMArray<mozISpellCheckingEngine> spellCheckingEngines;
+ rv = GetEngineList(&spellCheckingEngines);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ nsTArray<nsCString> dictionaries;
+ dictionaries.AppendElement(aDictionary);
+ for (int32_t i = 0; i < spellCheckingEngines.Count(); i++) {
+ // We must set mSpellCheckingEngine before we call SetDictionaries, since
+ // SetDictionaries calls back to this spell checker to check if the
+ // dictionary was set
+ mSpellCheckingEngine = spellCheckingEngines[i];
+ rv = mSpellCheckingEngine->SetDictionaries(dictionaries);
+
+ if (NS_SUCCEEDED(rv)) {
+ nsCOMPtr<mozIPersonalDictionary> personalDictionary =
+ do_GetService("@mozilla.org/spellchecker/personaldictionary;1");
+ mSpellCheckingEngine->SetPersonalDictionary(personalDictionary);
+
+ mConverter = new mozEnglishWordUtils;
+ return NS_OK;
+ }
+ }
+
+ mSpellCheckingEngine = nullptr;
+
+ // We could not find any engine with the requested dictionary
+ return NS_ERROR_NOT_AVAILABLE;
+}
+
+RefPtr<GenericPromise> mozSpellChecker::SetCurrentDictionaries(
+ const nsTArray<nsCString>& aDictionaries) {
+ if (XRE_IsContentProcess()) {
+ if (!mEngine) {
+ mCurrentDictionaries.Clear();
+ return GenericPromise::CreateAndReject(NS_ERROR_NOT_AVAILABLE, __func__);
+ }
+
+ // mCurrentDictionaries will be set by RemoteSpellCheckEngineChild
+ return mEngine->SetCurrentDictionaries(aDictionaries);
+ }
+
+ // Calls to mozISpellCheckingEngine::SetDictionary might destroy us
+ RefPtr<mozSpellChecker> kungFuDeathGrip = this;
+
+ mSpellCheckingEngine = nullptr;
+
+ if (aDictionaries.IsEmpty()) {
+ return GenericPromise::CreateAndResolve(true, __func__);
+ }
+
+ nsresult rv;
+ nsCOMArray<mozISpellCheckingEngine> spellCheckingEngines;
+ rv = GetEngineList(&spellCheckingEngines);
+ if (NS_FAILED(rv)) {
+ return GenericPromise::CreateAndReject(rv, __func__);
+ }
+
+ for (int32_t i = 0; i < spellCheckingEngines.Count(); i++) {
+ // We must set mSpellCheckingEngine before we call SetDictionaries, since
+ // SetDictionaries calls back to this spell checker to check if the
+ // dictionary was set
+ mSpellCheckingEngine = spellCheckingEngines[i];
+ rv = mSpellCheckingEngine->SetDictionaries(aDictionaries);
+
+ if (NS_SUCCEEDED(rv)) {
+ mCurrentDictionaries = aDictionaries.Clone();
+
+ nsCOMPtr<mozIPersonalDictionary> personalDictionary =
+ do_GetService("@mozilla.org/spellchecker/personaldictionary;1");
+ mSpellCheckingEngine->SetPersonalDictionary(personalDictionary);
+
+ mConverter = new mozEnglishWordUtils;
+ return GenericPromise::CreateAndResolve(true, __func__);
+ }
+ }
+
+ mSpellCheckingEngine = nullptr;
+
+ // We could not find any engine with the requested dictionary
+ return GenericPromise::CreateAndReject(NS_ERROR_NOT_AVAILABLE, __func__);
+}
+
+RefPtr<GenericPromise> mozSpellChecker::SetCurrentDictionaryFromList(
+ const nsTArray<nsCString>& aList) {
+ if (aList.IsEmpty()) {
+ return GenericPromise::CreateAndReject(NS_ERROR_INVALID_ARG, __func__);
+ }
+
+ if (XRE_IsContentProcess()) {
+ if (!mEngine) {
+ mCurrentDictionaries.Clear();
+ return GenericPromise::CreateAndReject(NS_ERROR_NOT_AVAILABLE, __func__);
+ }
+
+ // mCurrentDictionaries will be set by RemoteSpellCheckEngineChild
+ return mEngine->SetCurrentDictionaryFromList(aList);
+ }
+
+ for (auto& dictionary : aList) {
+ nsresult rv = SetCurrentDictionary(dictionary);
+ if (NS_SUCCEEDED(rv)) {
+ return GenericPromise::CreateAndResolve(true, __func__);
+ }
+ }
+ // We could not find any engine with the requested dictionary
+ return GenericPromise::CreateAndReject(NS_ERROR_NOT_AVAILABLE, __func__);
+}
+
+nsresult mozSpellChecker::SetupDoc(int32_t* outBlockOffset) {
+ nsresult rv;
+
+ TextServicesDocument::BlockSelectionStatus blockStatus;
+ *outBlockOffset = 0;
+
+ if (!mFromStart) {
+ uint32_t selOffset, selLength;
+ rv = MOZ_KnownLive(mTextServicesDocument)
+ ->LastSelectedBlock(&blockStatus, &selOffset, &selLength);
+ if (NS_SUCCEEDED(rv) &&
+ blockStatus !=
+ TextServicesDocument::BlockSelectionStatus::eBlockNotFound) {
+ switch (blockStatus) {
+ // No TB in S, but found one before/after S.
+ case TextServicesDocument::BlockSelectionStatus::eBlockOutside:
+ // S begins or ends in TB but extends outside of TB.
+ case TextServicesDocument::BlockSelectionStatus::eBlockPartial:
+ // the TS doc points to the block we want.
+ if (NS_WARN_IF(selOffset == UINT32_MAX) ||
+ NS_WARN_IF(selLength == UINT32_MAX)) {
+ rv = mTextServicesDocument->FirstBlock();
+ *outBlockOffset = 0;
+ break;
+ }
+ *outBlockOffset = AssertedCast<int32_t>(selOffset + selLength);
+ break;
+
+ // S extends beyond the start and end of TB.
+ case TextServicesDocument::BlockSelectionStatus::eBlockInside:
+ // we want the block after this one.
+ rv = mTextServicesDocument->NextBlock();
+ *outBlockOffset = 0;
+ break;
+
+ // TB contains entire S.
+ case TextServicesDocument::BlockSelectionStatus::eBlockContains:
+ if (NS_WARN_IF(selOffset == UINT32_MAX) ||
+ NS_WARN_IF(selLength == UINT32_MAX)) {
+ rv = mTextServicesDocument->FirstBlock();
+ *outBlockOffset = 0;
+ break;
+ }
+ *outBlockOffset = AssertedCast<int32_t>(selOffset + selLength);
+ break;
+
+ // There is no text block (TB) in or before the selection (S).
+ case TextServicesDocument::BlockSelectionStatus::eBlockNotFound:
+ default:
+ MOZ_ASSERT_UNREACHABLE("Shouldn't ever get this status");
+ }
+ }
+ // Failed to get last sel block. Just start at beginning
+ else {
+ rv = mTextServicesDocument->FirstBlock();
+ *outBlockOffset = 0;
+ }
+
+ }
+ // We want the first block
+ else {
+ rv = mTextServicesDocument->FirstBlock();
+ mFromStart = false;
+ }
+ return rv;
+}
+
+// utility method to discover which block we're in. The TSDoc interface doesn't
+// give us this, because it can't assume a read-only document. shamelessly
+// stolen from nsTextServicesDocument
+nsresult mozSpellChecker::GetCurrentBlockIndex(
+ TextServicesDocument* aTextServicesDocument, int32_t* aOutBlockIndex) {
+ int32_t blockIndex = 0;
+ bool isDone = false;
+ nsresult result = NS_OK;
+
+ do {
+ aTextServicesDocument->PrevBlock();
+ result = aTextServicesDocument->IsDone(&isDone);
+ if (!isDone) {
+ blockIndex++;
+ }
+ } while (NS_SUCCEEDED(result) && !isDone);
+
+ *aOutBlockIndex = blockIndex;
+
+ return result;
+}
+
+nsresult mozSpellChecker::GetEngineList(
+ nsCOMArray<mozISpellCheckingEngine>* aSpellCheckingEngines) {
+ MOZ_ASSERT(!XRE_IsContentProcess());
+
+ nsresult rv;
+ bool hasMoreEngines;
+
+ nsCOMPtr<nsICategoryManager> catMgr =
+ do_GetService(NS_CATEGORYMANAGER_CONTRACTID);
+ if (!catMgr) return NS_ERROR_NULL_POINTER;
+
+ nsCOMPtr<nsISimpleEnumerator> catEntries;
+
+ // Get contract IDs of registrated external spell-check engines and
+ // append one of HunSpell at the end.
+ rv = catMgr->EnumerateCategory("spell-check-engine",
+ getter_AddRefs(catEntries));
+ if (NS_FAILED(rv)) return rv;
+
+ while (NS_SUCCEEDED(catEntries->HasMoreElements(&hasMoreEngines)) &&
+ hasMoreEngines) {
+ nsCOMPtr<nsISupports> elem;
+ rv = catEntries->GetNext(getter_AddRefs(elem));
+
+ nsCOMPtr<nsISupportsCString> entry = do_QueryInterface(elem, &rv);
+ if (NS_FAILED(rv)) return rv;
+
+ nsCString contractId;
+ rv = entry->GetData(contractId);
+ if (NS_FAILED(rv)) return rv;
+
+ // Try to load spellchecker engine. Ignore errors silently
+ // except for the last one (HunSpell).
+ nsCOMPtr<mozISpellCheckingEngine> engine =
+ do_GetService(contractId.get(), &rv);
+ if (NS_SUCCEEDED(rv)) {
+ aSpellCheckingEngines->AppendObject(engine);
+ }
+ }
+
+ // Try to load HunSpell spellchecker engine.
+ nsCOMPtr<mozISpellCheckingEngine> engine =
+ do_GetService(DEFAULT_SPELL_CHECKER, &rv);
+ if (NS_FAILED(rv)) {
+ // Fail if not succeeded to load HunSpell. Ignore errors
+ // for external spellcheck engines.
+ return rv;
+ }
+ aSpellCheckingEngines->AppendObject(engine);
+
+ return NS_OK;
+}
diff --git a/extensions/spellcheck/src/mozSpellChecker.h b/extensions/spellcheck/src/mozSpellChecker.h
new file mode 100644
index 0000000000..aec4a95d65
--- /dev/null
+++ b/extensions/spellcheck/src/mozSpellChecker.h
@@ -0,0 +1,197 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef mozSpellChecker_h__
+#define mozSpellChecker_h__
+
+#include "mozilla/MozPromise.h"
+#include "nsCOMPtr.h"
+#include "nsCOMArray.h"
+#include "nsString.h"
+#include "mozIPersonalDictionary.h"
+#include "mozISpellCheckingEngine.h"
+#include "nsClassHashtable.h"
+#include "nsTArray.h"
+#include "nsCycleCollectionParticipant.h"
+
+class mozEnglishWordUtils;
+
+namespace mozilla {
+class RemoteSpellcheckEngineChild;
+class TextServicesDocument;
+typedef MozPromise<CopyableTArray<bool>, nsresult, false> CheckWordPromise;
+typedef MozPromise<CopyableTArray<nsString>, nsresult, false>
+ SuggestionsPromise;
+} // namespace mozilla
+
+class mozSpellChecker final {
+ public:
+ NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(mozSpellChecker)
+ NS_DECL_CYCLE_COLLECTION_NATIVE_CLASS(mozSpellChecker)
+
+ static already_AddRefed<mozSpellChecker> Create() {
+ RefPtr<mozSpellChecker> spellChecker = new mozSpellChecker();
+ nsresult rv = spellChecker->Init();
+ NS_ENSURE_SUCCESS(rv, nullptr);
+ return spellChecker.forget();
+ }
+
+ /**
+ * Tells the spellchecker what document to check.
+ * @param aDoc is the document to check.
+ * @param aFromStartOfDoc If true, start check from beginning of document,
+ * if false, start check from current cursor position.
+ */
+ nsresult SetDocument(mozilla::TextServicesDocument* aTextServicesDocument,
+ bool aFromStartofDoc);
+
+ /**
+ * Selects (hilites) the next misspelled word in the document.
+ * @param aWord will contain the misspelled word.
+ * @param aSuggestions is an array of nsStrings, that represent the
+ * suggested replacements for the misspelled word.
+ */
+ MOZ_CAN_RUN_SCRIPT
+ nsresult NextMisspelledWord(nsAString& aWord,
+ nsTArray<nsString>& aSuggestions);
+
+ /**
+ * Checks if a word is misspelled. No document is required to use this method.
+ * @param aWord is the word to check.
+ * @param aIsMisspelled will be set to true if the word is misspelled.
+ * @param aSuggestions is an array of nsStrings which represent the
+ * suggested replacements for the misspelled word. The array will be empty
+ * in chrome process if there aren't any suggestions. If suggestions is
+ * unnecessary, use CheckWords of async version.
+ */
+ nsresult CheckWord(const nsAString& aWord, bool* aIsMisspelled,
+ nsTArray<nsString>* aSuggestions);
+
+ /**
+ * This is a flavor of CheckWord, is async version of CheckWord.
+ * @Param aWords is array of words to check
+ */
+ RefPtr<mozilla::CheckWordPromise> CheckWords(
+ const nsTArray<nsString>& aWords);
+
+ /*
+ * Checks if a word is misspelled, then get suggestion words if existed.
+ */
+ RefPtr<mozilla::SuggestionsPromise> Suggest(const nsAString& aWord,
+ uint32_t aMaxCount);
+
+ /**
+ * Replaces the old word with the specified new word.
+ * @param aOldWord is the word to be replaced.
+ * @param aNewWord is the word that is to replace old word.
+ * @param aAllOccurrences will replace all occurrences of old
+ * word, in the document, with new word when it is true. If
+ * false, it will replace the 1st occurrence only!
+ */
+ MOZ_CAN_RUN_SCRIPT
+ nsresult Replace(const nsAString& aOldWord, const nsAString& aNewWord,
+ bool aAllOccurrences);
+
+ /**
+ * Ignores all occurrences of the specified word in the document.
+ * @param aWord is the word to ignore.
+ */
+ nsresult IgnoreAll(const nsAString& aWord);
+
+ /**
+ * Add a word to the user's personal dictionary.
+ * @param aWord is the word to add.
+ */
+ nsresult AddWordToPersonalDictionary(const nsAString& aWord);
+
+ /**
+ * Remove a word from the user's personal dictionary.
+ * @param aWord is the word to remove.
+ */
+ nsresult RemoveWordFromPersonalDictionary(const nsAString& aWord);
+
+ /**
+ * Returns the list of words in the user's personal dictionary.
+ * @param aWordList is an array of nsStrings that represent the
+ * list of words in the user's personal dictionary.
+ */
+ nsresult GetPersonalDictionary(nsTArray<nsString>* aWordList);
+
+ /**
+ * Returns the list of strings representing the dictionaries
+ * the spellchecker supports. It was suggested that the strings
+ * returned be in the RFC 1766 format. This format looks something
+ * like <ISO 639 language code>-<ISO 3166 country code>.
+ * For example: en-US
+ * @param aDictionaryList is an array of nsStrings that represent the
+ * dictionaries supported by the spellchecker.
+ */
+ nsresult GetDictionaryList(nsTArray<nsCString>* aDictionaryList);
+
+ /**
+ * Returns a string representing the current dictionaries.
+ * @param aDictionaries will contain the names of the dictionaries.
+ * This name is the same string that is in the list returned
+ * by GetDictionaryList().
+ */
+ nsresult GetCurrentDictionaries(nsTArray<nsCString>& aDictionaries);
+
+ /**
+ * Tells the spellchecker to use the specified dictionary.
+ * @param aDictionary a string that is in the list returned
+ * by GetDictionaryList() or an empty string . If aDictionary is
+ * an empty array, the spellchecker will be disabled.
+ */
+ nsresult SetCurrentDictionary(const nsACString& aDictionary);
+
+ /**
+ * Tells the spellchecker to use the specified dictionaries.
+ * @param aDictionaries an array of strings that is in the list returned
+ * by GetDictionaryList() or an empty array. If aDictionaries is
+ * an empty array, the spellchecker will be disabled.
+ */
+ RefPtr<mozilla::GenericPromise> SetCurrentDictionaries(
+ const nsTArray<nsCString>& aDictionaries);
+
+ /**
+ * Tells the spellchecker to use a specific dictionary from list.
+ * @param aList a preferred dictionary list
+ */
+ RefPtr<mozilla::GenericPromise> SetCurrentDictionaryFromList(
+ const nsTArray<nsCString>& aList);
+
+ void DeleteRemoteEngine() { mEngine = nullptr; }
+
+ mozilla::TextServicesDocument* GetTextServicesDocument();
+
+ protected:
+ mozSpellChecker();
+ virtual ~mozSpellChecker();
+
+ nsresult Init();
+
+ RefPtr<mozEnglishWordUtils> mConverter;
+ RefPtr<mozilla::TextServicesDocument> mTextServicesDocument;
+ nsCOMPtr<mozIPersonalDictionary> mPersonalDictionary;
+
+ nsCOMPtr<mozISpellCheckingEngine> mSpellCheckingEngine;
+ bool mFromStart;
+
+ nsTArray<nsCString> mCurrentDictionaries;
+
+ MOZ_CAN_RUN_SCRIPT
+ nsresult SetupDoc(int32_t* outBlockOffset);
+
+ nsresult GetCurrentBlockIndex(
+ mozilla::TextServicesDocument* aTextServicesDocument,
+ int32_t* aOutBlockIndex);
+
+ nsresult GetEngineList(nsCOMArray<mozISpellCheckingEngine>* aDictionaryList);
+
+ mozilla::RemoteSpellcheckEngineChild* mEngine;
+
+ friend class mozilla::RemoteSpellcheckEngineChild;
+};
+#endif // mozSpellChecker_h__
diff --git a/extensions/spellcheck/tests/chrome/base/base_utf.aff b/extensions/spellcheck/tests/chrome/base/base_utf.aff
new file mode 100644
index 0000000000..493157b301
--- /dev/null
+++ b/extensions/spellcheck/tests/chrome/base/base_utf.aff
@@ -0,0 +1,198 @@
+# OpenOffice.orgs en_US.aff file
+# with Unicode apostrophe:
+
+SET UTF-8
+TRY esianrtolcdugmphbyfvkwzESIANRTOLCDUGMPHBYFVKWZ'
+
+MAXNGRAMSUGS 1
+WORDCHARS .'
+
+PFX A Y 1
+PFX A 0 re .
+
+PFX I Y 1
+PFX I 0 in .
+
+PFX U Y 1
+PFX U 0 un .
+
+PFX C Y 1
+PFX C 0 de .
+
+PFX E Y 1
+PFX E 0 dis .
+
+PFX F Y 1
+PFX F 0 con .
+
+PFX K Y 1
+PFX K 0 pro .
+
+SFX V N 2
+SFX V e ive e
+SFX V 0 ive [^e]
+
+SFX N Y 3
+SFX N e ion e
+SFX N y ication y
+SFX N 0 en [^ey]
+
+SFX X Y 3
+SFX X e ions e
+SFX X y ications y
+SFX X 0 ens [^ey]
+
+SFX H N 2
+SFX H y ieth y
+SFX H 0 th [^y]
+
+SFX Y Y 1
+SFX Y 0 ly .
+
+SFX G Y 2
+SFX G e ing e
+SFX G 0 ing [^e]
+
+SFX J Y 2
+SFX J e ings e
+SFX J 0 ings [^e]
+
+SFX D Y 4
+SFX D 0 d e
+SFX D y ied [^aeiou]y
+SFX D 0 ed [^ey]
+SFX D 0 ed [aeiou]y
+
+SFX T N 4
+SFX T 0 st e
+SFX T y iest [^aeiou]y
+SFX T 0 est [aeiou]y
+SFX T 0 est [^ey]
+
+SFX R Y 4
+SFX R 0 r e
+SFX R y ier [^aeiou]y
+SFX R 0 er [aeiou]y
+SFX R 0 er [^ey]
+
+SFX Z Y 4
+SFX Z 0 rs e
+SFX Z y iers [^aeiou]y
+SFX Z 0 ers [aeiou]y
+SFX Z 0 ers [^ey]
+
+SFX S Y 4
+SFX S y ies [^aeiou]y
+SFX S 0 s [aeiou]y
+SFX S 0 es [sxzh]
+SFX S 0 s [^sxzhy]
+
+SFX P Y 3
+SFX P y iness [^aeiou]y
+SFX P 0 ness [aeiou]y
+SFX P 0 ness [^y]
+
+SFX M Y 1
+SFX M 0 's .
+
+SFX B Y 3
+SFX B 0 able [^aeiou]
+SFX B 0 able ee
+SFX B e able [^aeiou]e
+
+SFX L Y 1
+SFX L 0 ment .
+
+REP 88
+REP a ei
+REP ei a
+REP a ey
+REP ey a
+REP ai ie
+REP ie ai
+REP are air
+REP are ear
+REP are eir
+REP air are
+REP air ere
+REP ere air
+REP ere ear
+REP ere eir
+REP ear are
+REP ear air
+REP ear ere
+REP eir are
+REP eir ere
+REP ch te
+REP te ch
+REP ch ti
+REP ti ch
+REP ch tu
+REP tu ch
+REP ch s
+REP s ch
+REP ch k
+REP k ch
+REP f ph
+REP ph f
+REP gh f
+REP f gh
+REP i igh
+REP igh i
+REP i uy
+REP uy i
+REP i ee
+REP ee i
+REP j di
+REP di j
+REP j gg
+REP gg j
+REP j ge
+REP ge j
+REP s ti
+REP ti s
+REP s ci
+REP ci s
+REP k cc
+REP cc k
+REP k qu
+REP qu k
+REP kw qu
+REP o eau
+REP eau o
+REP o ew
+REP ew o
+REP oo ew
+REP ew oo
+REP ew ui
+REP ui ew
+REP oo ui
+REP ui oo
+REP ew u
+REP u ew
+REP oo u
+REP u oo
+REP u oe
+REP oe u
+REP u ieu
+REP ieu u
+REP ue ew
+REP ew ue
+REP uff ough
+REP oo ieu
+REP ieu oo
+REP ier ear
+REP ear ier
+REP ear air
+REP air ear
+REP w qu
+REP qu w
+REP z ss
+REP ss z
+REP shun tion
+REP shun sion
+REP shun cion
+McDonaldss叩/w
+McDonaldssz叩/g3) st:McDonald但s po:noun_prs is:TRANS
+McDonaldsszal/g4) st:McDonald但s po:noun_prs is:INSTR
+McDonaldssal/w
diff --git a/extensions/spellcheck/tests/chrome/base/base_utf.dic b/extensions/spellcheck/tests/chrome/base/base_utf.dic
new file mode 100644
index 0000000000..b2b536d285
--- /dev/null
+++ b/extensions/spellcheck/tests/chrome/base/base_utf.dic
@@ -0,0 +1,29 @@
+28
+created/U
+create/XKVNGADS
+imply/GNSDX
+natural/PUY
+like/USPBY
+convey/BDGS
+look/GZRDS
+text
+hello
+said
+sawyer
+NASA
+rotten
+day
+tomorrow
+seven
+FAQ/SM
+cant
+doesnt
+etc
+wont
+lip
+text
+horrifying
+speech
+suggest
+uncreate/V
+Hunspell
diff --git a/extensions/spellcheck/tests/chrome/chrome.ini b/extensions/spellcheck/tests/chrome/chrome.ini
new file mode 100644
index 0000000000..4aacb387c2
--- /dev/null
+++ b/extensions/spellcheck/tests/chrome/chrome.ini
@@ -0,0 +1,10 @@
+[DEFAULT]
+skip-if = os == 'android'
+
+[test_add_remove_dictionaries.xhtml]
+skip-if = verify
+support-files =
+ base/base_utf.dic
+ base/base_utf.aff
+ map/maputf.dic
+ map/maputf.aff
diff --git a/extensions/spellcheck/tests/chrome/map/maputf.aff b/extensions/spellcheck/tests/chrome/map/maputf.aff
new file mode 100644
index 0000000000..30edb2a785
--- /dev/null
+++ b/extensions/spellcheck/tests/chrome/map/maputf.aff
@@ -0,0 +1,11 @@
+# With MAP suggestion, Hunspell can add missing accents to a word.
+
+SET UTF-8
+
+# switch off ngram suggestion for testing
+MAXNGRAMSUGS 0
+
+MAP 3
+MAP u炭端
+MAP 旦坦o
+MAP (ss)
diff --git a/extensions/spellcheck/tests/chrome/map/maputf.dic b/extensions/spellcheck/tests/chrome/map/maputf.dic
new file mode 100644
index 0000000000..1c6fa8d058
--- /dev/null
+++ b/extensions/spellcheck/tests/chrome/map/maputf.dic
@@ -0,0 +1,4 @@
+3
+Fr端hst端ck
+t端k旦rf炭r坦
+gro
diff --git a/extensions/spellcheck/tests/chrome/test_add_remove_dictionaries.xhtml b/extensions/spellcheck/tests/chrome/test_add_remove_dictionaries.xhtml
new file mode 100644
index 0000000000..ae3f42aa67
--- /dev/null
+++ b/extensions/spellcheck/tests/chrome/test_add_remove_dictionaries.xhtml
@@ -0,0 +1,129 @@
+<?xml version="1.0"?>
+<?xml-stylesheet href="chrome://global/skin" type="text/css"?>
+
+<window title="Add and remove dictionaries test"
+ xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
+ xmlns:html="http://www.w3.org/1999/xhtml"
+ onload="RunTest();">
+
+ <script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"/>
+
+ <!-- test results are displayed in the html:body -->
+ <body xmlns="http://www.w3.org/1999/xhtml">
+ </body>
+
+ <script type="application/javascript">
+ <![CDATA[
+SimpleTest.waitForExplicitFinish();
+
+function getMisspelledWords(editor) {
+ return editor.selectionController.getSelection(Ci.nsISelectionController.SELECTION_SPELLCHECK).toString();
+}
+
+function getDictionaryList(editor) {
+ var spellchecker = editor.getInlineSpellChecker(true).spellChecker;
+ return spellchecker.GetDictionaryList();
+}
+
+function getCurrentDictionary(editor) {
+ var spellchecker = editor.getInlineSpellChecker(true).spellChecker;
+ return spellchecker.getCurrentDictionaries()[0];
+}
+
+function setCurrentDictionary(editor, dictionary) {
+ var spellchecker = editor.getInlineSpellChecker(true).spellChecker;
+ return spellchecker.setCurrentDictionaries([dictionary]);
+}
+
+function RunTest() {
+ var textbox = document.getElementById('textbox');
+ textbox.focus();
+ var editor = textbox.editor;
+
+ // eslint-disable-next-line mozilla/use-services
+ var dir = Cc["@mozilla.org/file/directory_service;1"].
+ getService(Ci.nsIProperties).
+ get("CurWorkD", Ci.nsIFile);
+ dir.append("chrome");
+ dir.append("extensions");
+ dir.append("spellcheck");
+ dir.append("tests");
+ dir.append("chrome");
+
+ var hunspell = Cc["@mozilla.org/spellchecker/engine;1"]
+ .getService(Ci.mozISpellCheckingEngine);
+
+ // install base dictionary
+ var base = dir.clone();
+ base.append("base");
+ ok(base.exists());
+ hunspell.addDirectory(base);
+
+ // install map dictionary
+ var map = dir.clone();
+ map.append("map");
+ ok(map.exists());
+ hunspell.addDirectory(map);
+
+ const {maybeOnSpellCheck} = ChromeUtils.import(
+ "resource://testing-common/AsyncSpellCheckTestHelper.jsm");
+ maybeOnSpellCheck(textbox, function () {
+
+ // test that base and map dictionaries are available
+ var dicts = getDictionaryList(editor);
+ isnot(dicts.indexOf("base-utf"), -1, "base is available");
+ isnot(dicts.indexOf("maputf"), -1, "map is available");
+
+ // select base dictionary
+ setCurrentDictionary(editor, "base-utf").then(() => {
+ /* eslint-disable no-useless-concat */
+ maybeOnSpellCheck(textbox, function () {
+ // test that base dictionary is in use
+ is(getMisspelledWords(editor), "Fr端hst端ck" + "qwertyu", "base misspellings");
+ is(getCurrentDictionary(editor), "base-utf", "current dictionary");
+
+ // select map dictionary
+ setCurrentDictionary(editor, "maputf").then(() => {
+ // Focus again, so the spelling gets updated.
+ textbox.blur();
+ textbox.focus();
+
+ maybeOnSpellCheck(textbox, function () {
+ // test that map dictionary is in use
+ is(getMisspelledWords(editor), "created" + "imply" + "tomorrow" + "qwertyu", "map misspellings (1)");
+ is(getCurrentDictionary(editor), "maputf", "current dictionary");
+
+ // uninstall map dictionary
+ hunspell.removeDirectory(map);
+
+ // Focus again, so the spelling gets updated.
+ textbox.blur();
+ textbox.focus();
+
+ maybeOnSpellCheck(textbox, function () {
+ // test that map dictionary is not in use
+ isnot(getMisspelledWords(editor), "created" + "imply" + "tomorrow" + "qwertyu", "map misspellings (2)");
+ isnot(getCurrentDictionary(editor), "maputf", "current dictionary");
+
+ // test that base dictionary is available and map dictionary is unavailable
+ var dicts = getDictionaryList(editor);
+ isnot(dicts.indexOf("base-utf"), -1, "base is available");
+ is(dicts.indexOf("maputf"), -1, "map is unavailable");
+
+ // uninstall base dictionary
+ hunspell.removeDirectory(base);
+
+ maybeOnSpellCheck(textbox, function () {
+ SimpleTest.finish();
+ });
+ });
+ });
+ });
+ });
+ });
+ });
+}
+ ]]>
+ </script>
+ <html:input id="textbox" spellcheck="true" value="created imply Fr端hst端ck tomorrow qwertyu"/>
+</window>
diff --git a/extensions/spellcheck/tests/mochitest/helper_bug1170484.js b/extensions/spellcheck/tests/mochitest/helper_bug1170484.js
new file mode 100644
index 0000000000..227e35e81a
--- /dev/null
+++ b/extensions/spellcheck/tests/mochitest/helper_bug1170484.js
@@ -0,0 +1,12 @@
+/* eslint-env mozilla/chrome-script */
+
+// Chrome scripts are run with synchronous messages, so make sure we're completely
+// decoupled from the content process before doing this work.
+Cu.dispatch(function () {
+ let chromeWin = Services.ww.activeWindow;
+ let contextMenu = chromeWin.document.getElementById("contentAreaContextMenu");
+ var suggestion = contextMenu.querySelector(".spell-suggestion");
+ suggestion.doCommand();
+ contextMenu.hidePopup();
+ sendAsyncMessage("spellingCorrected");
+});
diff --git a/extensions/spellcheck/tests/mochitest/mochitest.ini b/extensions/spellcheck/tests/mochitest/mochitest.ini
new file mode 100644
index 0000000000..3c7ae08f89
--- /dev/null
+++ b/extensions/spellcheck/tests/mochitest/mochitest.ini
@@ -0,0 +1,8 @@
+[DEFAULT]
+skip-if = os == 'android'
+
+[test_bug1170484.html]
+support-files = helper_bug1170484.js
+skip-if = os == 'linux' #Bug 1202570
+
+[test_bug1272623.html]
diff --git a/extensions/spellcheck/tests/mochitest/test_bug1170484.html b/extensions/spellcheck/tests/mochitest/test_bug1170484.html
new file mode 100644
index 0000000000..fa22998ada
--- /dev/null
+++ b/extensions/spellcheck/tests/mochitest/test_bug1170484.html
@@ -0,0 +1,59 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=1170484
+-->
+<head>
+ <meta charset="utf-8">
+ <title>Test for Bug 1170484</title>
+ <script src="/tests/SimpleTest/SimpleTest.js"></script>
+ <script src="/tests/SimpleTest/EventUtils.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+ <script type="application/javascript">
+
+ /** Test for Bug 1170484 */
+ SimpleTest.waitForExplicitFinish();
+
+ var { maybeOnSpellCheck } = SpecialPowers.ChromeUtils.import(
+ "resource://testing-common/AsyncSpellCheckTestHelper.jsm"
+ );
+
+ SimpleTest.waitForFocus(doTest, window);
+ function doTest() {
+ var mutations = 0;
+ var observer = new MutationObserver(() => { mutations++; });
+ observer.observe($('area'), { childList: true, characterData: true, characterDataOldValue: true, subtree: true });
+ var inputEvents = 0;
+ $('area').addEventListener('input', () => ++inputEvents);
+
+ // Clicking the contentEditable during onload doesn't seem to do anything.
+ // Not sure why, but postponing through the event loop seems to be enough.
+ SimpleTest.executeSoon(function() {
+ synthesizeMouseAtCenter($('misspelled'), {}, window);
+ maybeOnSpellCheck($('area'), function() {
+ synthesizeMouseAtCenter($('misspelled'), {type: 'contextmenu'}, window);
+ var mm = SpecialPowers.loadChromeScript(SimpleTest.getTestFileURL('helper_bug1170484.js'))
+ info("Loaded chrome script");
+ mm.addMessageListener('spellingCorrected', function() {
+ is($('area').textContent, 'testing spellcheck', "Spelling corrected properly");
+ is(mutations, 1, "Got correct number of mutations");
+ is(inputEvents, 1, "Got correct number of input events");
+ SimpleTest.finish();
+ });
+ });
+ });
+ }
+
+ </script>
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1170484">Mozilla Bug 1170484</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+
+</div>
+<pre id="test">
+ <div id="area" contenteditable="true">testing <span id="misspelled">spellechek</span></div>
+</pre>
+</body>
+</html>
diff --git a/extensions/spellcheck/tests/mochitest/test_bug1272623.html b/extensions/spellcheck/tests/mochitest/test_bug1272623.html
new file mode 100644
index 0000000000..677be4d9b5
--- /dev/null
+++ b/extensions/spellcheck/tests/mochitest/test_bug1272623.html
@@ -0,0 +1,83 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=1272623
+-->
+<head>
+ <meta charset="utf-8">
+ <title>Test for Bug 1272623</title>
+ <script src="/tests/SimpleTest/SimpleTest.js"></script>
+ <script src="/tests/SimpleTest/EventUtils.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1272623">Mozilla Bug 1272623</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+
+</div>
+<pre id="test">
+ <div id="area" contenteditable="true"><b style="font-weight:normal;">testing <span id="misspelled">spellechek</span></b></div>
+ <div id="area2" contenteditable="true">testing <span id="misspelled2" style="font-weight:bold;">spellechek</span></div>
+</pre>
+<script>
+
+/** Test for Bug 1272623 */
+
+ var maybeOnSpellCheck;
+
+ async function performCorrection(misspelled, area) {
+ synthesizeMouseAtCenter($(misspelled), {}, window);
+ await new Promise(resolve => maybeOnSpellCheck($(area), resolve));
+ synthesizeMouseAtCenter($(misspelled), {type: 'contextmenu'}, window);
+
+ // Perform the spelling correction
+ let mm = SpecialPowers.loadChromeScript(function() {
+ /* eslint-env mozilla/chrome-script */
+ const {BrowserTestUtils} = ChromeUtils.import("resource://testing-common/BrowserTestUtils.jsm");
+
+ // Chrome scripts are run with synchronous messages, so make sure we're completely
+ // decoupled from the content process before doing this work.
+ Cu.dispatch(async function() {
+ let chromeWin = Services.ww.activeWindow;
+ let contextMenu = chromeWin.document.getElementById("contentAreaContextMenu");
+ let suggestion = contextMenu.querySelector(".spell-suggestion");
+ if (!suggestion) {
+ await BrowserTestUtils.waitForMutationCondition(
+ contextMenu,
+ { childList: true },
+ () => contextMenu.querySelector(".spell-suggestion")
+ );
+ suggestion = contextMenu.querySelector(".spell-suggestion");
+ }
+ suggestion.doCommand();
+ contextMenu.hidePopup();
+ sendAsyncMessage("spellingCorrected");
+ });
+ });
+ info("Loaded chrome script");
+ await new Promise(resolve => mm.addMessageListener('spellingCorrected', resolve));
+ }
+
+ add_task(async function() {
+ maybeOnSpellCheck = SpecialPowers.ChromeUtils.import(
+ "resource://testing-common/AsyncSpellCheckTestHelper.jsm"
+ ).maybeOnSpellCheck;
+
+ // Wait for the page to be ready
+ await new Promise(resolve => SimpleTest.waitForFocus(() => SimpleTest.executeSoon(resolve), window));
+
+ // Check that <b> tags aren't inserted inside of other <b> tags when it would change the style
+ await performCorrection('misspelled', 'area');
+ is($('area').innerHTML, "<b style=\"font-weight:normal;\">testing <span id=\"misspelled\">spellcheck</span></b>");
+ is($('area').textContent, 'testing spellcheck', "Spelling corrected properly");
+
+ // Check that nodes aren't removed when the entire text inside of them is spelling-corrected
+ await performCorrection('misspelled2', 'area2');
+ is($('area2').innerHTML, "testing <span id=\"misspelled2\" style=\"font-weight:bold;\">spellcheck</span>");
+ is($('area2').textContent, 'testing spellcheck', "Spelling corrected properly");
+ });
+</script>
+</body>
+</html>
diff --git a/extensions/universalchardet/moz.build b/extensions/universalchardet/moz.build
new file mode 100644
index 0000000000..2d4b7badfc
--- /dev/null
+++ b/extensions/universalchardet/moz.build
@@ -0,0 +1,10 @@
+# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
+# vim: set filetype=python:
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+TEST_DIRS += ["tests"]
+
+with Files("**"):
+ BUG_COMPONENT = ("Core", "Internationalization")
diff --git a/extensions/universalchardet/tests/CharsetDetectionTests.js b/extensions/universalchardet/tests/CharsetDetectionTests.js
new file mode 100644
index 0000000000..8d6ebad964
--- /dev/null
+++ b/extensions/universalchardet/tests/CharsetDetectionTests.js
@@ -0,0 +1,48 @@
+/* -*- indent-tabs-mode: nil; js-indent-level: 4 -*- */
+/* vim: set ts=8 et sw=4 tw=80: */
+
+var gExpectedCharset;
+var gLocalDir;
+
+function CharsetDetectionTests(aTestFile, aExpectedCharset) {
+ gExpectedCharset = aExpectedCharset;
+
+ InitDetectorTests();
+
+ var fileURI = gLocalDir + aTestFile;
+ $("testframe").src = fileURI;
+
+ SimpleTest.waitForExplicitFinish();
+}
+
+function InitDetectorTests() {
+ var loader = Services.scriptloader;
+ var ioService = Services.io;
+ loader.loadSubScript("chrome://mochikit/content/chrome-harness.js");
+
+ $("testframe").onload = DoDetectionTest;
+
+ if (gExpectedCharset == "default") {
+ // No point trying to be generic here, because we have plenty of other
+ // unit tests that fail if run using a non-windows-1252 locale.
+ gExpectedCharset = "windows-1252";
+ }
+
+ // Get the local directory. This needs to be a file: URI because chrome:
+ // URIs are always UTF-8 (bug 617339) and we are testing decoding from other
+ // charsets.
+ var jar = getJar(getRootDirectory(window.location.href));
+ var dir = jar
+ ? extractJarToTmp(jar)
+ : getChromeDir(getResolvedURI(window.location.href));
+ gLocalDir = ioService.newFileURI(dir).spec;
+}
+
+function DoDetectionTest() {
+ var iframeDoc = $("testframe").contentDocument;
+ var charset = iframeDoc.characterSet;
+
+ is(charset, gExpectedCharset, "decoded as " + gExpectedCharset);
+
+ SimpleTest.finish();
+}
diff --git a/extensions/universalchardet/tests/bug1071816-1_text.html b/extensions/universalchardet/tests/bug1071816-1_text.html
new file mode 100644
index 0000000000..eae162afd5
--- /dev/null
+++ b/extensions/universalchardet/tests/bug1071816-1_text.html
@@ -0,0 +1,9 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <title>UTF-8</title>
+</head>
+<body>
+則
+</body>
+</html> \ No newline at end of file
diff --git a/extensions/universalchardet/tests/bug1071816-2_text.html b/extensions/universalchardet/tests/bug1071816-2_text.html
new file mode 100644
index 0000000000..489f383c2e
--- /dev/null
+++ b/extensions/universalchardet/tests/bug1071816-2_text.html
@@ -0,0 +1,9 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <title>windows-1252</title>
+</head>
+<body>
+
+</body>
+</html> \ No newline at end of file
diff --git a/extensions/universalchardet/tests/bug1071816-3_text.html b/extensions/universalchardet/tests/bug1071816-3_text.html
new file mode 100644
index 0000000000..c0bb397d0e
--- /dev/null
+++ b/extensions/universalchardet/tests/bug1071816-3_text.html
@@ -0,0 +1,536 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <title>UTF-8</title>
+<!-- More than 1024 bytes
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+-->
+</head>
+<body>
+則
+</body>
+</html> \ No newline at end of file
diff --git a/extensions/universalchardet/tests/bug1071816-4_text.html b/extensions/universalchardet/tests/bug1071816-4_text.html
new file mode 100644
index 0000000000..ee81cb1a50
--- /dev/null
+++ b/extensions/universalchardet/tests/bug1071816-4_text.html
@@ -0,0 +1,536 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <title>windows-1252</title>
+<!-- More than 1024 bytes
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+-->
+</head>
+<body>
+
+</body>
+</html> \ No newline at end of file
diff --git a/extensions/universalchardet/tests/bug306272_text.html b/extensions/universalchardet/tests/bug306272_text.html
new file mode 100644
index 0000000000..4a0c612834
--- /dev/null
+++ b/extensions/universalchardet/tests/bug306272_text.html
@@ -0,0 +1,9 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html><head>
+
+ <title>306272</title>
+
+
+</head><body>
+<a href="mailto:Antti.Nayha@somewhere.fi">Antti N辰yh辰 &lt;Antti.Nayha@somewhere.fi&gt;</a>
+</body></html> \ No newline at end of file
diff --git a/extensions/universalchardet/tests/bug426271_text-euc-jp.html b/extensions/universalchardet/tests/bug426271_text-euc-jp.html
new file mode 100644
index 0000000000..467d69c73e
--- /dev/null
+++ b/extensions/universalchardet/tests/bug426271_text-euc-jp.html
@@ -0,0 +1,11 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html lang="ja">
+<head>
+<title>日本語エンコードテスト</title>
+</head>
+<body>
+これはEUC-JPです昔々、ある所に子供のいない老夫婦が住んでいた。ある日、お婆さんが川で洗濯をしていると、大きな桃が流れて来たので、お爺さんと食べようと持ち帰った。二人で桃を割ると中から男の子が生まれたので、「桃太郎」と名付けて大事に育てた。
+
+成長した桃太郎は、鬼ヶ島の鬼が人々を苦しめていることを知り、鬼退治を決意する。両親から黍団子を餞別に貰い、道中にそれを分け与えてイヌ、サル、キジを家来に従える。鬼ヶ島で鬼と戦い、見事に勝利を収め、鬼が方々から奪っていった財宝を持ち帰り、お爺さん・お婆さんの元に返り、幸せに暮らしたという。出典: フリー百科事典『ウィキペディア(Wikipedia)』
+</body>
+</html>
diff --git a/extensions/universalchardet/tests/bug426271_text-utf-8.html b/extensions/universalchardet/tests/bug426271_text-utf-8.html
new file mode 100644
index 0000000000..7e38c27c35
--- /dev/null
+++ b/extensions/universalchardet/tests/bug426271_text-utf-8.html
@@ -0,0 +1,11 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html lang="ja">
+<head>
+<title>ユ茯潟潟若鴻</title>
+</head>
+<body>
+UTF-8с絖箴紊紿篏сャ紿綏ф羶紊с罅羌ャс冴蕋鴻≦鍵c篋篋冴ф蚊筝激絖障с罅紊篁紊т蚊
+
+激罅紊薔若九涯薔若篋冴ャ薔守羃祉羆堺筝∴Κ藥e蕕ャ莢違筝筝ゃ泣吾絎倶ャ緇薔若九涯ч若荀篋薔若鴻絅cc莢≦≦鍵冴祉紿菴綛吾阪: 主丞篋吾cc鐚Wikipedia鐚
+</body>
+</html>
diff --git a/extensions/universalchardet/tests/bug431054_text.html b/extensions/universalchardet/tests/bug431054_text.html
new file mode 100644
index 0000000000..aa88a4e1d2
--- /dev/null
+++ b/extensions/universalchardet/tests/bug431054_text.html
@@ -0,0 +1,5 @@
+<html>
+<body>
+ログイン
+</body>
+</html>
diff --git a/extensions/universalchardet/tests/bug620106_text.html b/extensions/universalchardet/tests/bug620106_text.html
new file mode 100644
index 0000000000..b7ca0aca33
--- /dev/null
+++ b/extensions/universalchardet/tests/bug620106_text.html
@@ -0,0 +1,1045 @@
+<!DOCTYPE html>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+テストのエンコーディングを検出。もう一度テスト。まだエンコードの検出をテストします。これが正しく検出されていますか?
+
diff --git a/extensions/universalchardet/tests/bug631751be_text.html b/extensions/universalchardet/tests/bug631751be_text.html
new file mode 100644
index 0000000000..104d503998
--- /dev/null
+++ b/extensions/universalchardet/tests/bug631751be_text.html
Binary files differ
diff --git a/extensions/universalchardet/tests/bug631751le_text.html b/extensions/universalchardet/tests/bug631751le_text.html
new file mode 100644
index 0000000000..a1e5f6bfbd
--- /dev/null
+++ b/extensions/universalchardet/tests/bug631751le_text.html
Binary files differ
diff --git a/extensions/universalchardet/tests/bug638318_text.html b/extensions/universalchardet/tests/bug638318_text.html
new file mode 100644
index 0000000000..3f2ff44212
--- /dev/null
+++ b/extensions/universalchardet/tests/bug638318_text.html
Binary files differ
diff --git a/extensions/universalchardet/tests/bug811363-1.text b/extensions/universalchardet/tests/bug811363-1.text
new file mode 100644
index 0000000000..a2952d62f7
--- /dev/null
+++ b/extensions/universalchardet/tests/bug811363-1.text
@@ -0,0 +1 @@
+Two-byte UTF-8 including the first and last characters in the range: 丿亠仍仂从濘
diff --git a/extensions/universalchardet/tests/bug811363-2.text b/extensions/universalchardet/tests/bug811363-2.text
new file mode 100644
index 0000000000..b3b672635d
--- /dev/null
+++ b/extensions/universalchardet/tests/bug811363-2.text
@@ -0,0 +1,3 @@
+Three byte UTF-8, first byte 0xE0, including first and last characters
+in the range: 爐謹ぐ爛爐迦狄
+
diff --git a/extensions/universalchardet/tests/bug811363-3.text b/extensions/universalchardet/tests/bug811363-3.text
new file mode 100644
index 0000000000..29b6d4c581
--- /dev/null
+++ b/extensions/universalchardet/tests/bug811363-3.text
@@ -0,0 +1,3 @@
+Three byte UTF-8, first byte 0xE1-EC, including first and last characters
+in the range: 激c若貎
+
diff --git a/extensions/universalchardet/tests/bug811363-4.text b/extensions/universalchardet/tests/bug811363-4.text
new file mode 100644
index 0000000000..f337d2e438
--- /dev/null
+++ b/extensions/universalchardet/tests/bug811363-4.text
@@ -0,0 +1,3 @@
+Three byte UTF-8, first byte 0xED, including first and last characters
+in the range:
+
diff --git a/extensions/universalchardet/tests/bug811363-5.text b/extensions/universalchardet/tests/bug811363-5.text
new file mode 100644
index 0000000000..2827c8030f
--- /dev/null
+++ b/extensions/universalchardet/tests/bug811363-5.text
@@ -0,0 +1,3 @@
+Three byte UTF-8, first byte 0xEE-EF, including first and last characters
+in the range: 鏨鏤鏤鏤鐃
+
diff --git a/extensions/universalchardet/tests/bug811363-6.text b/extensions/universalchardet/tests/bug811363-6.text
new file mode 100644
index 0000000000..c23e0077c4
--- /dev/null
+++ b/extensions/universalchardet/tests/bug811363-6.text
@@ -0,0 +1,3 @@
+Four byte UTF-8, first byte 0xF0, including first and last characters
+in the range: 介瑞告 霓真
+
diff --git a/extensions/universalchardet/tests/bug811363-7.text b/extensions/universalchardet/tests/bug811363-7.text
new file mode 100644
index 0000000000..8a2c209f18
--- /dev/null
+++ b/extensions/universalchardet/tests/bug811363-7.text
@@ -0,0 +1,3 @@
+Four byte UTF-8, first byte 0xF1-F3, including first and last characters
+in the range: 鷽真
+
diff --git a/extensions/universalchardet/tests/bug811363-8.text b/extensions/universalchardet/tests/bug811363-8.text
new file mode 100644
index 0000000000..b82f3da405
--- /dev/null
+++ b/extensions/universalchardet/tests/bug811363-8.text
@@ -0,0 +1,3 @@
+Four byte UTF-8, first byte 0xF4, including first and last characters
+in the range: 扤
+
diff --git a/extensions/universalchardet/tests/bug811363-9.text b/extensions/universalchardet/tests/bug811363-9.text
new file mode 100644
index 0000000000..50b232eafd
--- /dev/null
+++ b/extensions/universalchardet/tests/bug811363-9.text
@@ -0,0 +1,2 @@
+Four byte UTF-8, first byte 0xF0, including BMP only:
+
diff --git a/extensions/universalchardet/tests/bug811363-invalid-1.text b/extensions/universalchardet/tests/bug811363-invalid-1.text
new file mode 100644
index 0000000000..8718c36d73
--- /dev/null
+++ b/extensions/universalchardet/tests/bug811363-invalid-1.text
@@ -0,0 +1,4 @@
+Orphaned continuation bytes:
+
+、ぅΗ┤
+葦桶患況弦沙悉梢
diff --git a/extensions/universalchardet/tests/bug811363-invalid-5.text b/extensions/universalchardet/tests/bug811363-invalid-5.text
new file mode 100644
index 0000000000..fa76449c28
--- /dev/null
+++ b/extensions/universalchardet/tests/bug811363-invalid-5.text
@@ -0,0 +1,3 @@
+Isolated surrogates: 躾
+Surrogate pairs: 躇 躁錐真
+
diff --git a/extensions/universalchardet/tests/chrome.ini b/extensions/universalchardet/tests/chrome.ini
new file mode 100644
index 0000000000..a2b17a4dce
--- /dev/null
+++ b/extensions/universalchardet/tests/chrome.ini
@@ -0,0 +1,49 @@
+[DEFAULT]
+support-files =
+ CharsetDetectionTests.js
+ bug306272_text.html
+ bug426271_text-euc-jp.html
+ bug426271_text-utf-8.html
+ bug431054_text.html
+ bug631751be_text.html
+ bug631751le_text.html
+ bug638318_text.html
+ bug811363-1.text
+ bug811363-2.text
+ bug811363-3.text
+ bug811363-4.text
+ bug811363-5.text
+ bug811363-6.text
+ bug811363-7.text
+ bug811363-8.text
+ bug811363-9.text
+ bug811363-invalid-1.text
+ bug811363-invalid-5.text
+ bug1071816-1_text.html
+ bug1071816-2_text.html
+ bug1071816-3_text.html
+ bug1071816-4_text.html
+
+[test_bug306272.html]
+[test_bug426271-euc-jp.html]
+[test_bug426271-utf-8.html]
+[test_bug431054-japanese.html]
+[test_bug431054.html]
+[test_bug631751be.html]
+[test_bug631751le.html]
+[test_bug638318.html]
+[test_bug811363-1-1.html]
+[test_bug811363-1-5.html]
+[test_bug811363-2-1.html]
+[test_bug811363-2-2.html]
+[test_bug811363-2-3.html]
+[test_bug811363-2-4.html]
+[test_bug811363-2-5.html]
+[test_bug811363-2-6.html]
+[test_bug811363-2-7.html]
+[test_bug811363-2-8.html]
+[test_bug811363-2-9.html]
+[test_bug1071816-1.html]
+[test_bug1071816-2.html]
+[test_bug1071816-3.html]
+[test_bug1071816-4.html]
diff --git a/extensions/universalchardet/tests/moz.build b/extensions/universalchardet/tests/moz.build
new file mode 100644
index 0000000000..1a7d5281ea
--- /dev/null
+++ b/extensions/universalchardet/tests/moz.build
@@ -0,0 +1,7 @@
+# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
+# vim: set filetype=python:
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+MOCHITEST_CHROME_MANIFESTS += ["chrome.ini"]
diff --git a/extensions/universalchardet/tests/test_bug1071816-1.html b/extensions/universalchardet/tests/test_bug1071816-1.html
new file mode 100644
index 0000000000..9d9ea95dd6
--- /dev/null
+++ b/extensions/universalchardet/tests/test_bug1071816-1.html
@@ -0,0 +1,31 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=1071816
+-->
+<head>
+ <title>Test for Bug 1071816</title>
+ <script type="text/javascript"
+ src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js">
+ </script>
+ <script type="text/javascript" src="CharsetDetectionTests.js"></script>
+ <link rel="stylesheet" type="text/css"
+ href="chrome://mochikit/content/tests/SimpleTest/test.css" />
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1071816">Mozilla Bug 1071816</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+</div>
+<iframe id="testframe"></iframe>
+<pre id="test">
+<script class="testbody" type="text/javascript">
+/** Test for Bug 1071816 */
+/* Note! This test uses the chardet test harness but doesn't test chardet! */
+CharsetDetectionTests("bug1071816-1_text.html",
+ "UTF-8",
+ new Array(""));
+</script>
+</pre>
+</body>
+</html>
diff --git a/extensions/universalchardet/tests/test_bug1071816-2.html b/extensions/universalchardet/tests/test_bug1071816-2.html
new file mode 100644
index 0000000000..fde4e8d374
--- /dev/null
+++ b/extensions/universalchardet/tests/test_bug1071816-2.html
@@ -0,0 +1,31 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=1071816
+-->
+<head>
+ <title>Test for Bug 1071816</title>
+ <script type="text/javascript"
+ src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js">
+ </script>
+ <script type="text/javascript" src="CharsetDetectionTests.js"></script>
+ <link rel="stylesheet" type="text/css"
+ href="chrome://mochikit/content/tests/SimpleTest/test.css" />
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1071816">Mozilla Bug 1071816</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+</div>
+<iframe id="testframe"></iframe>
+<pre id="test">
+<script class="testbody" type="text/javascript">
+/** Test for Bug 1071816 */
+/* Note! This test uses the chardet test harness but doesn't test chardet! */
+CharsetDetectionTests("bug1071816-2_text.html",
+ "windows-1252",
+ new Array(""));
+</script>
+</pre>
+</body>
+</html>
diff --git a/extensions/universalchardet/tests/test_bug1071816-3.html b/extensions/universalchardet/tests/test_bug1071816-3.html
new file mode 100644
index 0000000000..adb8be46bb
--- /dev/null
+++ b/extensions/universalchardet/tests/test_bug1071816-3.html
@@ -0,0 +1,31 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=1071816
+-->
+<head>
+ <title>Test for Bug 1071816</title>
+ <script type="text/javascript"
+ src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js">
+ </script>
+ <script type="text/javascript" src="CharsetDetectionTests.js"></script>
+ <link rel="stylesheet" type="text/css"
+ href="chrome://mochikit/content/tests/SimpleTest/test.css" />
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1071816">Mozilla Bug 1071816</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+</div>
+<iframe id="testframe"></iframe>
+<pre id="test">
+<script class="testbody" type="text/javascript">
+/** Test for Bug 1071816 */
+/* Note! This test uses the chardet test harness but doesn't test chardet! */
+CharsetDetectionTests("bug1071816-3_text.html",
+ "UTF-8",
+ new Array(""));
+</script>
+</pre>
+</body>
+</html>
diff --git a/extensions/universalchardet/tests/test_bug1071816-4.html b/extensions/universalchardet/tests/test_bug1071816-4.html
new file mode 100644
index 0000000000..d5c99b3a66
--- /dev/null
+++ b/extensions/universalchardet/tests/test_bug1071816-4.html
@@ -0,0 +1,31 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=1071816
+-->
+<head>
+ <title>Test for Bug 1071816</title>
+ <script type="text/javascript"
+ src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js">
+ </script>
+ <script type="text/javascript" src="CharsetDetectionTests.js"></script>
+ <link rel="stylesheet" type="text/css"
+ href="chrome://mochikit/content/tests/SimpleTest/test.css" />
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1071816">Mozilla Bug 1071816</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+</div>
+<iframe id="testframe"></iframe>
+<pre id="test">
+<script class="testbody" type="text/javascript">
+/** Test for Bug 1071816 */
+/* Note! This test uses the chardet test harness but doesn't test chardet! */
+CharsetDetectionTests("bug1071816-4_text.html",
+ "windows-1252",
+ new Array(""));
+</script>
+</pre>
+</body>
+</html>
diff --git a/extensions/universalchardet/tests/test_bug306272.html b/extensions/universalchardet/tests/test_bug306272.html
new file mode 100644
index 0000000000..e1b99a0e51
--- /dev/null
+++ b/extensions/universalchardet/tests/test_bug306272.html
@@ -0,0 +1,31 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=306272
+-->
+<head>
+ <title>Test for Bug 306272</title>
+ <script type="text/javascript"
+ src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js">
+ </script>
+ <script type="text/javascript" src="CharsetDetectionTests.js"></script>
+ <link rel="stylesheet" type="text/css"
+ href="chrome://mochikit/content/tests/SimpleTest/test.css" />
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=306272">Mozilla Bug 306272</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+</div>
+<iframe id="testframe"></iframe>
+<pre id="test">
+<script class="testbody" type="text/javascript">
+/** Test for Bug 306272 */
+CharsetDetectionTests("bug306272_text.html",
+ "UTF-8",
+ new Array("ja_parallel_state_machine"));
+</script>
+</pre>
+</body>
+</html>
+
diff --git a/extensions/universalchardet/tests/test_bug426271-euc-jp.html b/extensions/universalchardet/tests/test_bug426271-euc-jp.html
new file mode 100644
index 0000000000..f1a2688298
--- /dev/null
+++ b/extensions/universalchardet/tests/test_bug426271-euc-jp.html
@@ -0,0 +1,31 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=426271
+-->
+<head>
+ <title>Test for Bug 426271</title>
+ <script type="text/javascript"
+ src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js">
+ </script>
+ <script type="text/javascript" src="CharsetDetectionTests.js"></script>
+ <link rel="stylesheet" type="text/css"
+ href="chrome://mochikit/content/tests/SimpleTest/test.css" />
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=426271">Mozilla Bug 426271</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+</div>
+<iframe id="testframe"></iframe>
+<pre id="test">
+<script class="testbody" type="text/javascript">
+/** Test for Bug 426271 */
+CharsetDetectionTests("bug426271_text-euc-jp.html",
+ "EUC-JP",
+ new Array("ja_parallel_state_machine"));
+</script>
+</pre>
+</body>
+</html>
+
diff --git a/extensions/universalchardet/tests/test_bug426271-utf-8.html b/extensions/universalchardet/tests/test_bug426271-utf-8.html
new file mode 100644
index 0000000000..70ad00d2cc
--- /dev/null
+++ b/extensions/universalchardet/tests/test_bug426271-utf-8.html
@@ -0,0 +1,31 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=426271
+-->
+<head>
+ <title>Test for Bug 426271</title>
+ <script type="text/javascript"
+ src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js">
+ </script>
+ <script type="text/javascript" src="CharsetDetectionTests.js"></script>
+ <link rel="stylesheet" type="text/css"
+ href="chrome://mochikit/content/tests/SimpleTest/test.css" />
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=426271">Mozilla Bug 426271</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+</div>
+<iframe id="testframe"></iframe>
+<pre id="test">
+<script class="testbody" type="text/javascript">
+/** Test for Bug 426271 */
+CharsetDetectionTests("bug426271_text-utf-8.html",
+ "UTF-8",
+ new Array("ja_parallel_state_machine"));
+</script>
+</pre>
+</body>
+</html>
+
diff --git a/extensions/universalchardet/tests/test_bug431054-japanese.html b/extensions/universalchardet/tests/test_bug431054-japanese.html
new file mode 100644
index 0000000000..21f76a759b
--- /dev/null
+++ b/extensions/universalchardet/tests/test_bug431054-japanese.html
@@ -0,0 +1,30 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=431054
+-->
+<head>
+ <title>Test for Bug 431054</title>
+ <script type="text/javascript"
+ src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js">
+ </script>
+ <script type="text/javascript" src="CharsetDetectionTests.js"></script>
+ <link rel="stylesheet" type="text/css"
+ href="chrome://mochikit/content/tests/SimpleTest/test.css" />
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=426271">Mozilla Bug 431054</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+</div>
+<iframe id="testframe"></iframe>
+<pre id="test">
+<script class="testbody" type="text/javascript">
+/** Test for Bug 431054 */
+CharsetDetectionTests("bug431054_text.html",
+ "EUC-JP",
+ new Array("ja_parallel_state_machine"));
+</script>
+</pre>
+</body>
+</html>
diff --git a/extensions/universalchardet/tests/test_bug431054.html b/extensions/universalchardet/tests/test_bug431054.html
new file mode 100644
index 0000000000..71a5ec7656
--- /dev/null
+++ b/extensions/universalchardet/tests/test_bug431054.html
@@ -0,0 +1,34 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=431054
+-->
+<head>
+ <title>Test for Bug 431054</title>
+ <script type="text/javascript"
+ src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js">
+ </script>
+ <script type="text/javascript" src="CharsetDetectionTests.js"></script>
+ <link rel="stylesheet" type="text/css"
+ href="chrome://mochikit/content/tests/SimpleTest/test.css" />
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=426271">Mozilla Bug 431054</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+</div>
+<iframe id="testframe"></iframe>
+<pre id="test">
+<script class="testbody" type="text/javascript">
+/** Test for Bug 431054 */
+CharsetDetectionTests("bug431054_text.html",
+ "EUC-JP",
+ ["zhtw_parallel_state_machine",
+ "zhcn_parallel_state_machine",
+ "zh_parallel_state_machine",
+ "cjk_parallel_state_machine",
+ "universal_charset_detector"]);
+</script>
+</pre>
+</body>
+</html>
diff --git a/extensions/universalchardet/tests/test_bug631751be.html b/extensions/universalchardet/tests/test_bug631751be.html
new file mode 100644
index 0000000000..9333050ae8
--- /dev/null
+++ b/extensions/universalchardet/tests/test_bug631751be.html
@@ -0,0 +1,31 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=631751
+-->
+<head>
+ <title>Test for Bug 631751</title>
+ <script type="text/javascript"
+ src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js">
+ </script>
+ <script type="text/javascript" src="CharsetDetectionTests.js"></script>
+ <link rel="stylesheet" type="text/css"
+ href="chrome://mochikit/content/tests/SimpleTest/test.css" />
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=631751">Mozilla Bug 631751</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+</div>
+<iframe id="testframe"></iframe>
+<pre id="test">
+<script class="testbody" type="text/javascript">
+/** Test for Bug 631751 */
+/* Note! This test uses the chardet test harness but doesn't test chardet! */
+CharsetDetectionTests("bug631751be_text.html",
+ "UTF-8", // Test runs from file: URL, so ASCII gets detected as UTF-8.
+ new Array(""));
+</script>
+</pre>
+</body>
+</html>
diff --git a/extensions/universalchardet/tests/test_bug631751le.html b/extensions/universalchardet/tests/test_bug631751le.html
new file mode 100644
index 0000000000..36725a3a91
--- /dev/null
+++ b/extensions/universalchardet/tests/test_bug631751le.html
@@ -0,0 +1,31 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=631751
+-->
+<head>
+ <title>Test for Bug 631751</title>
+ <script type="text/javascript"
+ src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js">
+ </script>
+ <script type="text/javascript" src="CharsetDetectionTests.js"></script>
+ <link rel="stylesheet" type="text/css"
+ href="chrome://mochikit/content/tests/SimpleTest/test.css" />
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=631751">Mozilla Bug 631751</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+</div>
+<iframe id="testframe"></iframe>
+<pre id="test">
+<script class="testbody" type="text/javascript">
+/** Test for Bug 631751 */
+/* Note! This test uses the chardet test harness but doesn't test chardet! */
+CharsetDetectionTests("bug631751le_text.html",
+ "UTF-8", // Test runs from file: URL, so ASCII gets detected as UTF-8.
+ new Array(""));
+</script>
+</pre>
+</body>
+</html>
diff --git a/extensions/universalchardet/tests/test_bug638318.html b/extensions/universalchardet/tests/test_bug638318.html
new file mode 100644
index 0000000000..ee49b5097c
--- /dev/null
+++ b/extensions/universalchardet/tests/test_bug638318.html
@@ -0,0 +1,31 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=638318
+-->
+<head>
+ <title>Test for Bug 638318</title>
+ <script type="text/javascript"
+ src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js">
+ </script>
+ <script type="text/javascript" src="CharsetDetectionTests.js"></script>
+ <link rel="stylesheet" type="text/css"
+ href="chrome://mochikit/content/tests/SimpleTest/test.css" />
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=638318">Mozilla Bug 638318</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+</div>
+<iframe id="testframe"></iframe>
+<pre id="test">
+<script class="testbody" type="text/javascript">
+/** Test for Bug 638318 */
+/* Note! This test uses the chardet test harness but doesn't test chardet! */
+CharsetDetectionTests("bug638318_text.html",
+ "UTF-8",
+ new Array(""));
+</script>
+</pre>
+</body>
+</html>
diff --git a/extensions/universalchardet/tests/test_bug811363-1-1.html b/extensions/universalchardet/tests/test_bug811363-1-1.html
new file mode 100644
index 0000000000..79a0d6d523
--- /dev/null
+++ b/extensions/universalchardet/tests/test_bug811363-1-1.html
@@ -0,0 +1,29 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=811363
+-->
+<head>
+ <title>Test for Bug 811363</title>
+ <script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js">
+ </script>
+ <script type="text/javascript" src="CharsetDetectionTests.js"></script>
+ <link rel="stylesheet" type="text/css"
+ href="chrome://mochikit/content/tests/SimpleTest/test.css" />
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=811363">Mozilla Bug 811363</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+</div>
+<iframe id="testframe"></iframe>
+<pre id="test">
+<script class="testbody" type="text/javascript">
+/** Test for Bug 811363 */
+CharsetDetectionTests("bug811363-invalid-1.text",
+ "windows-1252",
+ new Array("ja_parallel_state_machine"));
+</script>
+</pre>
+</body>
+</html>
diff --git a/extensions/universalchardet/tests/test_bug811363-1-5.html b/extensions/universalchardet/tests/test_bug811363-1-5.html
new file mode 100644
index 0000000000..70429f1c5f
--- /dev/null
+++ b/extensions/universalchardet/tests/test_bug811363-1-5.html
@@ -0,0 +1,29 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=811363
+-->
+<head>
+ <title>Test for Bug 811363</title>
+ <script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js">
+ </script>
+ <script type="text/javascript" src="CharsetDetectionTests.js"></script>
+ <link rel="stylesheet" type="text/css"
+ href="chrome://mochikit/content/tests/SimpleTest/test.css" />
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=811363">Mozilla Bug 811363</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+</div>
+<iframe id="testframe"></iframe>
+<pre id="test">
+<script class="testbody" type="text/javascript">
+/** Test for Bug 811363 */
+CharsetDetectionTests("bug811363-invalid-5.text",
+ "windows-1251",
+ new Array("ja_parallel_state_machine"));
+</script>
+</pre>
+</body>
+</html>
diff --git a/extensions/universalchardet/tests/test_bug811363-2-1.html b/extensions/universalchardet/tests/test_bug811363-2-1.html
new file mode 100644
index 0000000000..3325b1889d
--- /dev/null
+++ b/extensions/universalchardet/tests/test_bug811363-2-1.html
@@ -0,0 +1,29 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=811363
+-->
+<head>
+ <title>Test for Bug 811363</title>
+ <script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js">
+ </script>
+ <script type="text/javascript" src="CharsetDetectionTests.js"></script>
+ <link rel="stylesheet" type="text/css"
+ href="chrome://mochikit/content/tests/SimpleTest/test.css" />
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=811363">Mozilla Bug 811363</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+</div>
+<iframe id="testframe"></iframe>
+<pre id="test">
+<script class="testbody" type="text/javascript">
+/** Test for Bug 811363 */
+CharsetDetectionTests("bug811363-1.text",
+ "UTF-8",
+ new Array("ja_parallel_state_machine"));
+</script>
+</pre>
+</body>
+</html>
diff --git a/extensions/universalchardet/tests/test_bug811363-2-2.html b/extensions/universalchardet/tests/test_bug811363-2-2.html
new file mode 100644
index 0000000000..31bdde7297
--- /dev/null
+++ b/extensions/universalchardet/tests/test_bug811363-2-2.html
@@ -0,0 +1,29 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=811363
+-->
+<head>
+ <title>Test for Bug 811363</title>
+ <script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js">
+ </script>
+ <script type="text/javascript" src="CharsetDetectionTests.js"></script>
+ <link rel="stylesheet" type="text/css"
+ href="chrome://mochikit/content/tests/SimpleTest/test.css" />
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=811363">Mozilla Bug 811363</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+</div>
+<iframe id="testframe"></iframe>
+<pre id="test">
+<script class="testbody" type="text/javascript">
+/** Test for Bug 811363 */
+CharsetDetectionTests("bug811363-2.text",
+ "UTF-8",
+ new Array("ja_parallel_state_machine"));
+</script>
+</pre>
+</body>
+</html>
diff --git a/extensions/universalchardet/tests/test_bug811363-2-3.html b/extensions/universalchardet/tests/test_bug811363-2-3.html
new file mode 100644
index 0000000000..73efbe347f
--- /dev/null
+++ b/extensions/universalchardet/tests/test_bug811363-2-3.html
@@ -0,0 +1,29 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=811363
+-->
+<head>
+ <title>Test for Bug 811363</title>
+ <script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js">
+ </script>
+ <script type="text/javascript" src="CharsetDetectionTests.js"></script>
+ <link rel="stylesheet" type="text/css"
+ href="chrome://mochikit/content/tests/SimpleTest/test.css" />
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=811363">Mozilla Bug 811363</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+</div>
+<iframe id="testframe"></iframe>
+<pre id="test">
+<script class="testbody" type="text/javascript">
+/** Test for Bug 811363 */
+CharsetDetectionTests("bug811363-3.text",
+ "UTF-8",
+ new Array("ja_parallel_state_machine"));
+</script>
+</pre>
+</body>
+</html>
diff --git a/extensions/universalchardet/tests/test_bug811363-2-4.html b/extensions/universalchardet/tests/test_bug811363-2-4.html
new file mode 100644
index 0000000000..f9d90918d9
--- /dev/null
+++ b/extensions/universalchardet/tests/test_bug811363-2-4.html
@@ -0,0 +1,29 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=811363
+-->
+<head>
+ <title>Test for Bug 811363</title>
+ <script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js">
+ </script>
+ <script type="text/javascript" src="CharsetDetectionTests.js"></script>
+ <link rel="stylesheet" type="text/css"
+ href="chrome://mochikit/content/tests/SimpleTest/test.css" />
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=811363">Mozilla Bug 811363</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+</div>
+<iframe id="testframe"></iframe>
+<pre id="test">
+<script class="testbody" type="text/javascript">
+/** Test for Bug 811363 */
+CharsetDetectionTests("bug811363-4.text",
+ "UTF-8",
+ new Array("ja_parallel_state_machine"));
+</script>
+</pre>
+</body>
+</html>
diff --git a/extensions/universalchardet/tests/test_bug811363-2-5.html b/extensions/universalchardet/tests/test_bug811363-2-5.html
new file mode 100644
index 0000000000..a450ec0527
--- /dev/null
+++ b/extensions/universalchardet/tests/test_bug811363-2-5.html
@@ -0,0 +1,29 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=811363
+-->
+<head>
+ <title>Test for Bug 811363</title>
+ <script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js">
+ </script>
+ <script type="text/javascript" src="CharsetDetectionTests.js"></script>
+ <link rel="stylesheet" type="text/css"
+ href="chrome://mochikit/content/tests/SimpleTest/test.css" />
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=811363">Mozilla Bug 811363</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+</div>
+<iframe id="testframe"></iframe>
+<pre id="test">
+<script class="testbody" type="text/javascript">
+/** Test for Bug 811363 */
+CharsetDetectionTests("bug811363-5.text",
+ "UTF-8",
+ new Array("ja_parallel_state_machine"));
+</script>
+</pre>
+</body>
+</html>
diff --git a/extensions/universalchardet/tests/test_bug811363-2-6.html b/extensions/universalchardet/tests/test_bug811363-2-6.html
new file mode 100644
index 0000000000..18fb254043
--- /dev/null
+++ b/extensions/universalchardet/tests/test_bug811363-2-6.html
@@ -0,0 +1,29 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=811363
+-->
+<head>
+ <title>Test for Bug 811363</title>
+ <script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js">
+ </script>
+ <script type="text/javascript" src="CharsetDetectionTests.js"></script>
+ <link rel="stylesheet" type="text/css"
+ href="chrome://mochikit/content/tests/SimpleTest/test.css" />
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=811363">Mozilla Bug 811363</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+</div>
+<iframe id="testframe"></iframe>
+<pre id="test">
+<script class="testbody" type="text/javascript">
+/** Test for Bug 811363 */
+CharsetDetectionTests("bug811363-6.text",
+ "UTF-8",
+ new Array("ja_parallel_state_machine"));
+</script>
+</pre>
+</body>
+</html>
diff --git a/extensions/universalchardet/tests/test_bug811363-2-7.html b/extensions/universalchardet/tests/test_bug811363-2-7.html
new file mode 100644
index 0000000000..c7e571589a
--- /dev/null
+++ b/extensions/universalchardet/tests/test_bug811363-2-7.html
@@ -0,0 +1,29 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=811363
+-->
+<head>
+ <title>Test for Bug 811363</title>
+ <script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js">
+ </script>
+ <script type="text/javascript" src="CharsetDetectionTests.js"></script>
+ <link rel="stylesheet" type="text/css"
+ href="chrome://mochikit/content/tests/SimpleTest/test.css" />
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=811363">Mozilla Bug 811363</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+</div>
+<iframe id="testframe"></iframe>
+<pre id="test">
+<script class="testbody" type="text/javascript">
+/** Test for Bug 811363 */
+CharsetDetectionTests("bug811363-7.text",
+ "UTF-8",
+ new Array("ja_parallel_state_machine"));
+</script>
+</pre>
+</body>
+</html>
diff --git a/extensions/universalchardet/tests/test_bug811363-2-8.html b/extensions/universalchardet/tests/test_bug811363-2-8.html
new file mode 100644
index 0000000000..fb7951d7c0
--- /dev/null
+++ b/extensions/universalchardet/tests/test_bug811363-2-8.html
@@ -0,0 +1,29 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=811363
+-->
+<head>
+ <title>Test for Bug 811363</title>
+ <script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js">
+ </script>
+ <script type="text/javascript" src="CharsetDetectionTests.js"></script>
+ <link rel="stylesheet" type="text/css"
+ href="chrome://mochikit/content/tests/SimpleTest/test.css" />
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=811363">Mozilla Bug 811363</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+</div>
+<iframe id="testframe"></iframe>
+<pre id="test">
+<script class="testbody" type="text/javascript">
+/** Test for Bug 811363 */
+CharsetDetectionTests("bug811363-8.text",
+ "UTF-8",
+ new Array("ja_parallel_state_machine"));
+</script>
+</pre>
+</body>
+</html>
diff --git a/extensions/universalchardet/tests/test_bug811363-2-9.html b/extensions/universalchardet/tests/test_bug811363-2-9.html
new file mode 100644
index 0000000000..47156e4d54
--- /dev/null
+++ b/extensions/universalchardet/tests/test_bug811363-2-9.html
@@ -0,0 +1,29 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=811363
+-->
+<head>
+ <title>Test for Bug 811363</title>
+ <script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js">
+ </script>
+ <script type="text/javascript" src="CharsetDetectionTests.js"></script>
+ <link rel="stylesheet" type="text/css"
+ href="chrome://mochikit/content/tests/SimpleTest/test.css" />
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=811363">Mozilla Bug 811363</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+</div>
+<iframe id="testframe"></iframe>
+<pre id="test">
+<script class="testbody" type="text/javascript">
+/** Test for Bug 811363 */
+CharsetDetectionTests("bug811363-9.text",
+ "UTF-8",
+ new Array("ja_parallel_state_machine"));
+</script>
+</pre>
+</body>
+</html>