diff --git a/resources/build/help-keyman-com.sh b/resources/build/help-keyman-com.sh index ce68df0a85..f335ee7e6b 100755 --- a/resources/build/help-keyman-com.sh +++ b/resources/build/help-keyman-com.sh @@ -90,6 +90,9 @@ function upload_keyman_help { mac) upload mac/docs/help products/mac/$VERSION_RELEASE ;; + web) + upload web/docs/engine developer/engine/web/$VERSION_RELEASE + ;; windows) # Note: `/windows/src/desktop/help/build.sh web` must be run first upload windows/bin/help/md/desktop products/windows/$VERSION_RELEASE @@ -120,7 +123,7 @@ while [[ $# -gt 0 ]] ; do display_usage exit 0 ;; - android | ios | linux | mac | windows | developer) + android | ios | linux | mac | windows | developer | web) platform=$key ;; *) diff --git a/web/build.sh b/web/build.sh index be1227cdee..6f1846dc6a 100755 --- a/web/build.sh +++ b/web/build.sh @@ -14,6 +14,9 @@ THIS_SCRIPT="$(readlink -f "${BASH_SOURCE[0]}")" builder_set_child_base src builder_describe "Builds engine modules for Keyman Engine for Web (KMW)." \ + \ + "@/resources/tools/check-markdown test:help" \ + \ "clean" \ "configure" \ "build" \ @@ -33,9 +36,11 @@ builder_describe "Builds engine modules for Keyman Engine for Web (KMW)." \ ":engine/main Builds all common code used by KMW's app/-level targets" \ ":engine/osk Builds the Web OSK module" \ ":engine/predictive-text=src/engine/predictive-text/worker-main Builds KMW's predictive text module" \ + ":help Online documentation" \ ":samples Builds all needed resources for the KMW sample-page set" \ ":tools Builds engine-related development resources" \ ":test-pages=src/test/manual Builds resources needed for the KMW manual testing pages" \ + ":_all (Meta build target used when targets are not specified)" \ "--ci+ Set to utilize CI-based test configurations & reporting." # Possible TODO? @@ -182,11 +187,17 @@ builder_run_child_actions build:tools builder_run_child_actions build:test-pages # Build tests -builder_run_action build build_action +builder_run_action build:_all build_action # Run tests -builder_run_child_actions test -builder_run_action test test_action +# builder_run_child_actions test +builder_run_action test:_all test_action + +function do_test_help() { + check-markdown "$KEYMAN_ROOT/web/docs/engine" +} + +builder_run_action test:help do_test_help # Create coverage report -builder_run_action coverage coverage_action +builder_run_action coverage:_all coverage_action diff --git a/web/docs/engine/developer_images/guide_lang_options.gif b/web/docs/engine/developer_images/guide_lang_options.gif new file mode 100644 index 0000000000..8974465ac8 Binary files /dev/null and b/web/docs/engine/developer_images/guide_lang_options.gif differ diff --git a/web/docs/engine/developer_images/kmw20_osk_kbd1.png b/web/docs/engine/developer_images/kmw20_osk_kbd1.png new file mode 100644 index 0000000000..0975eb1cd8 Binary files /dev/null and b/web/docs/engine/developer_images/kmw20_osk_kbd1.png differ diff --git a/web/docs/engine/developer_images/kmw20_osk_kbd2.png b/web/docs/engine/developer_images/kmw20_osk_kbd2.png new file mode 100644 index 0000000000..38452e84a1 Binary files /dev/null and b/web/docs/engine/developer_images/kmw20_osk_kbd2.png differ diff --git a/web/docs/engine/developer_images/kmw_automatic_control.png b/web/docs/engine/developer_images/kmw_automatic_control.png new file mode 100644 index 0000000000..cc5dae53d5 Binary files /dev/null and b/web/docs/engine/developer_images/kmw_automatic_control.png differ diff --git a/web/docs/engine/developer_images/kmw_control_by_control_1.png b/web/docs/engine/developer_images/kmw_control_by_control_1.png new file mode 100644 index 0000000000..21f042bcf8 Binary files /dev/null and b/web/docs/engine/developer_images/kmw_control_by_control_1.png differ diff --git a/web/docs/engine/developer_images/kmw_control_by_control_2.png b/web/docs/engine/developer_images/kmw_control_by_control_2.png new file mode 100644 index 0000000000..a98b384ab2 Binary files /dev/null and b/web/docs/engine/developer_images/kmw_control_by_control_2.png differ diff --git a/web/docs/engine/developer_images/kmw_control_by_control_3.png b/web/docs/engine/developer_images/kmw_control_by_control_3.png new file mode 100644 index 0000000000..4fbbed06be Binary files /dev/null and b/web/docs/engine/developer_images/kmw_control_by_control_3.png differ diff --git a/web/docs/engine/developer_images/kmw_defaults.png b/web/docs/engine/developer_images/kmw_defaults.png new file mode 100644 index 0000000000..e9146bf5ae Binary files /dev/null and b/web/docs/engine/developer_images/kmw_defaults.png differ diff --git a/web/docs/engine/developer_images/kmw_full_manual_control.png b/web/docs/engine/developer_images/kmw_full_manual_control.png new file mode 100644 index 0000000000..0007fa8f10 Binary files /dev/null and b/web/docs/engine/developer_images/kmw_full_manual_control.png differ diff --git a/web/docs/engine/developer_images/kmw_manual_control.png b/web/docs/engine/developer_images/kmw_manual_control.png new file mode 100644 index 0000000000..cc5dae53d5 Binary files /dev/null and b/web/docs/engine/developer_images/kmw_manual_control.png differ diff --git a/web/docs/engine/developer_images/tutorial_crm_step0-createcrm-confirm.png b/web/docs/engine/developer_images/tutorial_crm_step0-createcrm-confirm.png new file mode 100644 index 0000000000..070d43f174 Binary files /dev/null and b/web/docs/engine/developer_images/tutorial_crm_step0-createcrm-confirm.png differ diff --git a/web/docs/engine/developer_images/tutorial_crm_step0-createcrm.png b/web/docs/engine/developer_images/tutorial_crm_step0-createcrm.png new file mode 100644 index 0000000000..c0a5786c7c Binary files /dev/null and b/web/docs/engine/developer_images/tutorial_crm_step0-createcrm.png differ diff --git a/web/docs/engine/developer_images/tutorial_crm_step0-tools-opencrm.png b/web/docs/engine/developer_images/tutorial_crm_step0-tools-opencrm.png new file mode 100644 index 0000000000..ad77918ede Binary files /dev/null and b/web/docs/engine/developer_images/tutorial_crm_step0-tools-opencrm.png differ diff --git a/web/docs/engine/developer_images/tutorial_crm_step1-login.png b/web/docs/engine/developer_images/tutorial_crm_step1-login.png new file mode 100644 index 0000000000..afec71e35f Binary files /dev/null and b/web/docs/engine/developer_images/tutorial_crm_step1-login.png differ diff --git a/web/docs/engine/developer_images/tutorial_crm_step1-status-filled.png b/web/docs/engine/developer_images/tutorial_crm_step1-status-filled.png new file mode 100644 index 0000000000..a67bdd529b Binary files /dev/null and b/web/docs/engine/developer_images/tutorial_crm_step1-status-filled.png differ diff --git a/web/docs/engine/developer_images/tutorial_crm_step1-status.png b/web/docs/engine/developer_images/tutorial_crm_step1-status.png new file mode 100644 index 0000000000..f2d5f65d81 Binary files /dev/null and b/web/docs/engine/developer_images/tutorial_crm_step1-status.png differ diff --git a/web/docs/engine/developer_images/tutorial_crm_step2-createcustomer.png b/web/docs/engine/developer_images/tutorial_crm_step2-createcustomer.png new file mode 100644 index 0000000000..27fdf87669 Binary files /dev/null and b/web/docs/engine/developer_images/tutorial_crm_step2-createcustomer.png differ diff --git a/web/docs/engine/developer_images/tutorial_crm_step2-createpurchase-licence.png b/web/docs/engine/developer_images/tutorial_crm_step2-createpurchase-licence.png new file mode 100644 index 0000000000..ef47db2d56 Binary files /dev/null and b/web/docs/engine/developer_images/tutorial_crm_step2-createpurchase-licence.png differ diff --git a/web/docs/engine/developer_images/tutorial_crm_step2-createpurchase.png b/web/docs/engine/developer_images/tutorial_crm_step2-createpurchase.png new file mode 100644 index 0000000000..e5d1eb0f3e Binary files /dev/null and b/web/docs/engine/developer_images/tutorial_crm_step2-createpurchase.png differ diff --git a/web/docs/engine/developer_images/tutorial_crm_step2-customerdetails.png b/web/docs/engine/developer_images/tutorial_crm_step2-customerdetails.png new file mode 100644 index 0000000000..0a968a884e Binary files /dev/null and b/web/docs/engine/developer_images/tutorial_crm_step2-customerdetails.png differ diff --git a/web/docs/engine/developer_images/tutorial_crm_step2-customers.png b/web/docs/engine/developer_images/tutorial_crm_step2-customers.png new file mode 100644 index 0000000000..93d2d93d52 Binary files /dev/null and b/web/docs/engine/developer_images/tutorial_crm_step2-customers.png differ diff --git a/web/docs/engine/developer_images/tutorial_keyboard_qfrench.gif b/web/docs/engine/developer_images/tutorial_keyboard_qfrench.gif new file mode 100644 index 0000000000..99e274b454 Binary files /dev/null and b/web/docs/engine/developer_images/tutorial_keyboard_qfrench.gif differ diff --git a/web/docs/engine/developer_images/tutorial_package_includesdocs.gif b/web/docs/engine/developer_images/tutorial_package_includesdocs.gif new file mode 100644 index 0000000000..6eebbb9fc0 Binary files /dev/null and b/web/docs/engine/developer_images/tutorial_package_includesdocs.gif differ diff --git a/web/docs/engine/developer_images/tutorial_package_includesfonts.gif b/web/docs/engine/developer_images/tutorial_package_includesfonts.gif new file mode 100644 index 0000000000..cbeca7bd53 Binary files /dev/null and b/web/docs/engine/developer_images/tutorial_package_includesfonts.gif differ diff --git a/web/docs/engine/developer_images/tutorial_package_includesosk.gif b/web/docs/engine/developer_images/tutorial_package_includesosk.gif new file mode 100644 index 0000000000..5db43bf1b9 Binary files /dev/null and b/web/docs/engine/developer_images/tutorial_package_includesosk.gif differ diff --git a/web/docs/engine/developer_images/tutorial_package_includeswelcome.gif b/web/docs/engine/developer_images/tutorial_package_includeswelcome.gif new file mode 100644 index 0000000000..9313bd0481 Binary files /dev/null and b/web/docs/engine/developer_images/tutorial_package_includeswelcome.gif differ diff --git a/web/docs/engine/guide/adding-keyboards.md b/web/docs/engine/guide/adding-keyboards.md new file mode 100644 index 0000000000..93e65d1442 --- /dev/null +++ b/web/docs/engine/guide/adding-keyboards.md @@ -0,0 +1,59 @@ +--- +title: Adding Keyboards +--- + +There are multiple ways to add and install keyboards into your KeymanWeb installation. + +In the examples that follow, please note the use of variable `kmw` as shorthand for the `keyman` object. + +## Directly linking a local copy + +The most efficient way to utilize a keyboard is to obtain a local copy of it and place this copy in a static location on your website. Once this is done, it can be directly linked into KeymanWeb as follows. + +```c +keyman.addKeyboards({ + id:'us', // The keyboard's unique identification code. + name:'English', // The keyboard's user-readable name. + language:{ + id:'en', // A BCP 47 code uniquely identifying the language. + name:'English (US)' // The language's name. + }, + filename:'./us-1.0.js' // A valid path to the compiled *.js file representing the keyboard. +}); +``` +Custom fonts may also be utilized via the `language.font` property. For example: + +```c +font:{ + family:'LaoWeb', + source:['../font/saysettha_web.ttf','../font/saysettha_web.woff','../font/saysettha_web.eot'] +} +``` + +## Requested from the CDN by language name + +To obtain the default Keyman keyboard for a given language, call the following function. + +```c +keyman.addKeyboardsForLanguage('Dzongkha'); +``` + +This example would find the default keyboard for the Dzongkha language. This method will fail if the name doesn't perfectly match any language found in the CDN's repository. + +Alternatively, languages may be looked up via their BCP 47 language code as follows: + +```c +keyman.addKeyboards('@he') +``` + +The `@` prefix indicates the use of the BCP 47 language code, which in this case corresponds with Hebrew. + +## Requested from the CDN by keyboard name + +To obtain a specific keyboard by name or by keyboard name and language code as a pair, see the following: + +```c +keyman.addKeyboards('french','european2@sv','european2@no') +``` + +This will install three keyboards - one for French (named, quite simply, "French") and two copies of the EuroLatin2 keyboard - one for Swedish and one for Norwegian. diff --git a/web/docs/engine/guide/examples/__auto-control.html b/web/docs/engine/guide/examples/__auto-control.html new file mode 100644 index 0000000000..9e1786c6d7 --- /dev/null +++ b/web/docs/engine/guide/examples/__auto-control.html @@ -0,0 +1,28 @@ + + + + + + + + +
+

+

+
+ + \ No newline at end of file diff --git a/web/docs/engine/guide/examples/__control-by-control.html b/web/docs/engine/guide/examples/__control-by-control.html new file mode 100644 index 0000000000..b1f7ac5e42 --- /dev/null +++ b/web/docs/engine/guide/examples/__control-by-control.html @@ -0,0 +1,47 @@ + + + + + + + + + + + + +
+ +

Email to (KeymanWeb not enabled)

+ +

Subject (Defaults to 'English' or 'off' unless on a touch-based device)

+ +

Message body (Defaults to 'LaoKeys')

+ +
+ + + \ No newline at end of file diff --git a/web/docs/engine/guide/examples/__first-example.html b/web/docs/engine/guide/examples/__first-example.html new file mode 100644 index 0000000000..3b46160f65 --- /dev/null +++ b/web/docs/engine/guide/examples/__first-example.html @@ -0,0 +1,23 @@ + + + + + KeymanWeb - A First Example + + + + + + + + +

Click me and type:

+ + \ No newline at end of file diff --git a/web/docs/engine/guide/examples/__full-manual-control.html b/web/docs/engine/guide/examples/__full-manual-control.html new file mode 100644 index 0000000000..c9d76d90fb --- /dev/null +++ b/web/docs/engine/guide/examples/__full-manual-control.html @@ -0,0 +1,55 @@ + + + + + + + + + + + +
+ +

Keyboard:

+ +

+
+ + + diff --git a/web/docs/engine/guide/examples/__manual-control.html b/web/docs/engine/guide/examples/__manual-control.html new file mode 100644 index 0000000000..37776a7850 --- /dev/null +++ b/web/docs/engine/guide/examples/__manual-control.html @@ -0,0 +1,45 @@ + + + + + + + + + + + +
+ +

KeymanWeb

+ +

+

+ +
+ + \ No newline at end of file diff --git a/web/docs/engine/guide/examples/automatic-control.md b/web/docs/engine/guide/examples/automatic-control.md new file mode 100644 index 0000000000..c804556e18 --- /dev/null +++ b/web/docs/engine/guide/examples/automatic-control.md @@ -0,0 +1,44 @@ +--- +title: Automatic Mode Example +--- + +This page shows how to include a local keyboard from an arbitrary location in your website's file structure. + +In this example, we use only the LaoKey keyboard. Please click [this link](./__auto-control.html) to open the test page. + +## Code Walkthrough + +```html + + + + + + +``` + +As you can see above, the second line in the code snippet above references the LaoKey keyboard loader JavaScript file. This is a small stub file, typically less than 200 bytes, that defines the name and actual location of the real keyboard file (in this case, **laokeys.js**). When a page may reference many keyboards, this saves downloading potentially hundreds of kilobytes of unused Javascript keyboards - the keyboard is downloaded when it is first selected by the user. + +## API References + +On initialization: [`keyman.init()`](../../reference/core/init). + +On including keyboards: [`keyman.addKeyboards()`](../../reference/core/addKeyboards). + +------------------------------------------------------------------------ + +[On to Manual Control Example](manual-control) diff --git a/web/docs/engine/guide/examples/control-by-control.md b/web/docs/engine/guide/examples/control-by-control.md new file mode 100644 index 0000000000..da8ee9acca --- /dev/null +++ b/web/docs/engine/guide/examples/control-by-control.md @@ -0,0 +1,71 @@ +--- +title: Control-by-Control Example +--- + +In this example, a simulated webmail form, the default and permissible keyboard for each control is managed by the web page. We use the automatic mode for simplicity of demonstration. We also link to the CDN for KeymanWeb in this example. Please click [this link](__control-by-control.html) to open the test page. + +## Code Walkthrough + +Include the following script in the HEAD of your page: + +```js + +``` + +Also include the following HTML code: + +```html + + + + + + + + + + +``` +--- +**Note:** In this example we disabled the first element (`document.f.address`) by API call. A later API call can re-enable KeymanWeb for this control should it fit the page's design. Alternatively, this can be done by instead adding the class `'kmw-disabled'` to the control. This will permanently block KeymanWeb from handling its input. + +--- + +The `loadKeyboards()` function used by this page may be found +[here](js/unified_loader.js). + +## API References + +On disabling controls: +- [`keyman.disableControl()`](../../reference/core/disableControl). + +On setting the keyboard for a single control: +- [`keyman.setKeyboardForControl()`](../../reference/core/setKeyboardForControl). + +------------------------------------------------------------------------ + +[Return to Example index](./) diff --git a/web/docs/engine/guide/examples/form_help.jpg b/web/docs/engine/guide/examples/form_help.jpg new file mode 100644 index 0000000000..8db9f1712d Binary files /dev/null and b/web/docs/engine/guide/examples/form_help.jpg differ diff --git a/web/docs/engine/guide/examples/full-manual-control.md b/web/docs/engine/guide/examples/full-manual-control.md new file mode 100644 index 0000000000..e9e8d2908a --- /dev/null +++ b/web/docs/engine/guide/examples/full-manual-control.md @@ -0,0 +1,82 @@ +--- +title: Manual Control - Custom Interface +--- + +In this example, the web page designer has opted for their own user interface instead of the KeymanWeb interface. The keyboards in the selector are populated from the KeymanWeb list of keyboards. Please click [this link](__full-manual-control.html) to open the test page. + +## Code Walkthrough + +Include the following script in the HEAD of your page: + +```js + +``` + +Also include the following HTML code: + +```html + + + + + + + + + + +``` + +- File: [unified_loader.js](js/unified_loader.js) + +And finally, include the keyboard SELECT and the clickable help img: + +```html + +

Keyboard: +``` + +On programmatically setting the keyboard: +- [`keyman.setActiveKeyboard()`](../../reference/core/setActiveKeyboard). + +On getting KeymanWeb's managed list of keyboards: +- [`keyman.getKeyboards()`](../../reference/core/getKeyboards). + +------------------------------------------------------------------------ + +[On to Control by Control Example](control-by-control) diff --git a/web/docs/engine/guide/examples/index.md b/web/docs/engine/guide/examples/index.md new file mode 100644 index 0000000000..477ac911af --- /dev/null +++ b/web/docs/engine/guide/examples/index.md @@ -0,0 +1,26 @@ +--- +title: Additional KeymanWeb Usage Examples +--- + +This set of examples displays basic use of the API to demonstrate customization possibilities for use of KeymanWeb. + +- [Automatic Control Example](automatic-control) + + Demonstrates the simplest way to get up and running with KeymanWeb. + +- [Manual On-Screen Keyboard Control](manual-control) + + Demonstrates some basic API allowing for custom control of the on-screen keyboard's display. + +- [Manual Language Control Example](full-manual-control) + + Demonstrates API allowing for custom controls to manage the active keyboard. + +- [Control by Control Example](control-by-control) + + Demonstrates how to set different languages for different controls and how to disable controls via API call. + +--- +**Note:** in the actual source for these examples, we link to the most current version of KeymanWeb instead of a local copy, though the first three are written to demonstrate working with a local copy of KeymanWeb and will work accordingly. + +--- diff --git a/web/docs/engine/guide/examples/js/devanagari_inscript.js b/web/docs/engine/guide/examples/js/devanagari_inscript.js new file mode 100644 index 0000000000..1089b51dd7 --- /dev/null +++ b/web/docs/engine/guide/examples/js/devanagari_inscript.js @@ -0,0 +1,2 @@ +/*(C) Copyright 1994-2006 Tavultesoft Pty Ltd. All Rights Reserved. Details: keymanweb.com*/ +KeymanWeb.KR(new Keyboard_devanagari_inscript()); function Keyboard_devanagari_inscript() {this.KI="Keyboard_devanagari_inscript";this.KM=0;this.KN="Devanagari (INSCRIPT)";this.KV={F:' 1em "Arial"',K102:0,BK:new Array("ॊ","1","2","3","4","5","6","7","8","9","0","-","ृ","","","","ौ","ै","ा","ी","ू","ब","ह","ग","द","ज","ड","़","ॉ","","","","ो","े","्","ि","ु","प","र","क","त","च","ट","","","","","","ॉ","ॆ","ं","म","न","व","ल","स",",",".","य","","","","",""," ","ऒ","ऍ","ॅ","्र","र्","ज्ञ","त्र","क्ष","श्र","(",")","ः","ऋ","","","","औ","ऐ","आ","ई","ऊ","भ","ङ","घ","ध","झ","ढ","ञ","ऑ","","","","ओ","ए","अ","इ","उ","फ","ऱ","ख","थ","छ","ठ","","","","","","ऑ","ऎ","ँ","ण","ऩ","ऴ","ळ","श","ष","।","य़","","","","",""," ","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","ॊ","1","2","3","4","5","6","7","8","9","0","-","ृ","","","","ौ","ै","ा","ी","ू","ब","ह","ग","द","ज","ड","़","ॉ","","","","ो","े","्","ि","ु","प","र","क","त","च","ट","","","","","","ॉ","ॆ","ं","म","न","व","ल","स",",",".","य","","","","",""," ","ऒ","ऍ","ॅ","्र","र्","ज्ञ","त्र","क्ष","श्र","(",")","ः","ऋ","","","","औ","ऐ","आ","ई","ऊ","भ","ङ","घ","ध","झ","ढ","ञ","ऑ","","","","ओ","ए","अ","इ","उ","फ","ऱ","ख","थ","छ","ठ","","","","","","ऑ","ऎ","ँ","ण","ऩ","ऴ","ळ","श","ष","।","य़","","","","",""," ","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","१","२","३","४","५","६","७","८","९","०","","ॄ","","","","","","","ॣ","","","","ग़","","ज़","ड़","","","","","","","","","ॢ","","","","क़","","॒","","","","","","","","॓","","॔","","","","","॰","॥","","","","","","","","","","","","","","","","","","","","ॠ","","","","","","","ॡ","","","","","","","ढ़","","","","","","","","","ऌ","","फ़","","ख़","","","॑","","","","","","","","ॐ","","","","","","","ऽ","","","","","","","")};this.KH="Help for this keyboard";this.s4="devanagari_inscript.kvk";this.s5="Help for this keyboard";this.gs=function(t,e){return this.g0(t,e);};this.g0=function(t,e){var k=KeymanWeb,m=0;if(k.KKM(e,16384,32)){m=1;k.KO(0,t," ");}else if(k.KKM(e,16400,32)){m=1;k.KO(0,t," ");}else if(k.KKM(e,16384,32)){m=1;k.KO(0,t," ");}else if(k.KKM(e,16384,32)){m=1;k.KO(0,t," ");}else if(k.KKM(e,16384,48)){m=1;k.KO(0,t,"0");}else if(k.KKM(e,16400,48)){m=1;k.KO(0,t,")");}else if(k.KKM(e,16384,48)){m=1;k.KO(0,t,"०");}else if(k.KKM(e,16384,49)){m=1;k.KO(0,t,"1");}else if(k.KKM(e,16400,49)){m=1;k.KO(0,t,"ऍ");}else if(k.KKM(e,16400,49)){m=1;k.KO(0,t,"‍");}else if(k.KKM(e,16384,49)){m=1;k.KO(0,t,"१");}else if(k.KKM(e,16400,49)){m=1;k.KO(0,t,"‍");}else if(k.KKM(e,16384,50)){m=1;k.KO(0,t,"2");}else if(k.KKM(e,16400,50)){m=1;k.KO(0,t,"ॅ");}else if(k.KKM(e,16400,50)){m=1;k.KO(0,t,"‌");}else if(k.KKM(e,16384,50)){m=1;k.KO(0,t,"२");}else if(k.KKM(e,16400,50)){m=1;k.KO(0,t,"‌");}else if(k.KKM(e,16384,51)){m=1;k.KO(0,t,"3");}else if(k.KKM(e,16400,51)){m=1;k.KO(0,t,"्र");}else if(k.KKM(e,16384,51)){m=1;k.KO(0,t,"३");}else if(k.KKM(e,16384,52)){m=1;k.KO(0,t,"4");}else if(k.KKM(e,16400,52)){m=1;k.KO(0,t,"र्");}else if(k.KKM(e,16384,52)){m=1;k.KO(0,t,"४");}else if(k.KKM(e,16384,53)){m=1;k.KO(0,t,"5");}else if(k.KKM(e,16400,53)){m=1;k.KO(0,t,"ज्ञ");}else if(k.KKM(e,16384,53)){m=1;k.KO(0,t,"५");}else if(k.KKM(e,16384,54)){m=1;k.KO(0,t,"6");}else if(k.KKM(e,16400,54)){m=1;k.KO(0,t,"त्र");}else if(k.KKM(e,16384,54)){m=1;k.KO(0,t,"६");}else if(k.KKM(e,16384,55)){m=1;k.KO(0,t,"7");}else if(k.KKM(e,16400,55)){m=1;k.KO(0,t,"क्ष");}else if(k.KKM(e,16384,55)){m=1;k.KO(0,t,"७");}else if(k.KKM(e,16384,56)){m=1;k.KO(0,t,"8");}else if(k.KKM(e,16400,56)){m=1;k.KO(0,t,"श्र");}else if(k.KKM(e,16384,56)){m=1;k.KO(0,t,"८");}else if(k.KKM(e,16384,57)){m=1;k.KO(0,t,"9");}else if(k.KKM(e,16400,57)){m=1;k.KO(0,t,"(");}else if(k.KKM(e,16384,57)){m=1;k.KO(0,t,"९");}else if(k.KKM(e,16384,65)){m=1;k.KO(0,t,"ो");}else if(k.KKM(e,16400,65)){m=1;k.KO(0,t,"ओ");}else if(k.KKM(e,16384,66)){m=1;k.KO(0,t,"व");}else if(k.KKM(e,16400,66)){m=1;k.KO(0,t,"ऴ");}else if(k.KKM(e,16384,67)){m=1;k.KO(0,t,"म");}else if(k.KKM(e,16400,67)){m=1;k.KO(0,t,"ण");}else if(k.KKM(e,16384,67)){m=1;k.KO(0,t,"॔");}else if(k.KKM(e,16384,68)){m=1;k.KO(0,t,"्");}else if(k.KKM(e,16400,68)){m=1;k.KO(0,t,"अ");}else if(k.KKM(e,16384,69)){m=1;k.KO(0,t,"ा");}else if(k.KKM(e,16400,69)){m=1;k.KO(0,t,"आ");}else if(k.KKM(e,16384,70)){m=1;k.KO(0,t,"ि");}else if(k.KKM(e,16400,70)){m=1;k.KO(0,t,"इ");}else if(k.KKM(e,16384,70)){m=1;k.KO(0,t,"ॢ");}else if(k.KKM(e,16400,70)){m=1;k.KO(0,t,"ऌ");}else if(k.KKM(e,16384,71)){m=1;k.KO(0,t,"ु");}else if(k.KKM(e,16400,71)){m=1;k.KO(0,t,"उ");}else if(k.KKM(e,16384,72)){m=1;k.KO(0,t,"प");}else if(k.KKM(e,16400,72)){m=1;k.KO(0,t,"फ");}else if(k.KKM(e,16400,72)){m=1;k.KO(0,t,"फ़");}else if(k.KKM(e,16384,73)){m=1;k.KO(0,t,"ग");}else if(k.KKM(e,16400,73)){m=1;k.KO(0,t,"घ");}else if(k.KKM(e,16384,73)){m=1;k.KO(0,t,"ग़");}else if(k.KKM(e,16384,74)){m=1;k.KO(0,t,"र");}else if(k.KKM(e,16400,74)){m=1;k.KO(0,t,"ऱ");}else if(k.KKM(e,16384,75)){m=1;k.KO(0,t,"क");}else if(k.KKM(e,16400,75)){m=1;k.KO(0,t,"ख");}else if(k.KKM(e,16384,75)){m=1;k.KO(0,t,"क़");}else if(k.KKM(e,16400,75)){m=1;k.KO(0,t,"ख़");}else if(k.KKM(e,16384,76)){m=1;k.KO(0,t,"त");}else if(k.KKM(e,16400,76)){m=1;k.KO(0,t,"थ");}else if(k.KKM(e,16384,77)){m=1;k.KO(0,t,"स");}else if(k.KKM(e,16400,77)){m=1;k.KO(0,t,"श");}else if(k.KKM(e,16384,78)){m=1;k.KO(0,t,"ल");}else if(k.KKM(e,16400,78)){m=1;k.KO(0,t,"ळ");}else if(k.KKM(e,16384,79)){m=1;k.KO(0,t,"द");}else if(k.KKM(e,16400,79)){m=1;k.KO(0,t,"ध");}else if(k.KKM(e,16384,80)){m=1;k.KO(0,t,"ज");}else if(k.KKM(e,16400,80)){m=1;k.KO(0,t,"झ");}else if(k.KKM(e,16384,80)){m=1;k.KO(0,t,"ज़");}else if(k.KKM(e,16384,81)){m=1;k.KO(0,t,"ौ");}else if(k.KKM(e,16400,81)){m=1;k.KO(0,t,"औ");}else if(k.KKM(e,16384,82)){m=1;k.KO(0,t,"ी");}else if(k.KKM(e,16400,82)){m=1;k.KO(0,t,"ई");}else if(k.KKM(e,16384,82)){m=1;k.KO(0,t,"ॣ");}else if(k.KKM(e,16400,82)){m=1;k.KO(0,t,"ॡ");}else if(k.KKM(e,16384,83)){m=1;k.KO(0,t,"े");}else if(k.KKM(e,16400,83)){m=1;k.KO(0,t,"ए");}else if(k.KKM(e,16384,84)){m=1;k.KO(0,t,"ू");}else if(k.KKM(e,16400,84)){m=1;k.KO(0,t,"ऊ");}else if(k.KKM(e,16384,85)){m=1;k.KO(0,t,"ह");}else if(k.KKM(e,16400,85)){m=1;k.KO(0,t,"ङ");}else if(k.KKM(e,16384,86)){m=1;k.KO(0,t,"न");}else if(k.KKM(e,16400,86)){m=1;k.KO(0,t,"ऩ");}else if(k.KKM(e,16384,87)){m=1;k.KO(0,t,"ै");}else if(k.KKM(e,16400,87)){m=1;k.KO(0,t,"ऐ");}else if(k.KKM(e,16384,88)){m=1;k.KO(0,t,"ं");}else if(k.KKM(e,16400,88)){m=1;k.KO(0,t,"ँ");}else if(k.KKM(e,16400,88)){m=1;k.KO(0,t,"ॐ");}else if(k.KKM(e,16384,89)){m=1;k.KO(0,t,"ब");}else if(k.KKM(e,16400,89)){m=1;k.KO(0,t,"भ");}else if(k.KKM(e,16384,90)){m=1;k.KO(0,t,"ॆ");}else if(k.KKM(e,16400,90)){m=1;k.KO(0,t,"ऎ");}else if(k.KKM(e,16384,90)){m=1;k.KO(0,t,"॓");}else if(k.KKM(e,16384,106)){m=1;k.KO(0,t,"*");}else if(k.KKM(e,16400,106)){m=1;k.KO(0,t,"*");}else if(k.KKM(e,16384,107)){m=1;k.KO(0,t,"+");}else if(k.KKM(e,16400,107)){m=1;k.KO(0,t,"+");}else if(k.KKM(e,16384,109)){m=1;k.KO(0,t,"-");}else if(k.KKM(e,16400,109)){m=1;k.KO(0,t,"-");}else if(k.KKM(e,16384,186)){m=1;k.KO(0,t,"च");}else if(k.KKM(e,16400,186)){m=1;k.KO(0,t,"छ");}else if(k.KKM(e,16384,186)){m=1;k.KO(0,t,"॒");}else if(k.KKM(e,16384,187)){m=1;k.KO(0,t,"ृ");}else if(k.KKM(e,16400,187)){m=1;k.KO(0,t,"ऋ");}else if(k.KKM(e,16384,187)){m=1;k.KO(0,t,"ॄ");}else if(k.KKM(e,16400,187)){m=1;k.KO(0,t,"ॠ");}else if(k.KKM(e,16384,188)){m=1;k.KO(0,t,",");}else if(k.KKM(e,16400,188)){m=1;k.KO(0,t,"ष");}else if(k.KKM(e,16384,188)){m=1;k.KO(0,t,"॰");}else if(k.KKM(e,16384,189)){m=1;k.KO(0,t,"-");}else if(k.KKM(e,16400,189)){m=1;k.KO(0,t,"ः");}else if(k.KKM(e,16384,190)){m=1;k.KO(0,t,".");}else if(k.KKM(e,16400,190)){m=1;k.KO(0,t,"।");}else if(k.KKM(e,16384,190)){m=1;k.KO(0,t,"॥");}else if(k.KKM(e,16400,190)){m=1;k.KO(0,t,"ऽ");}else if(k.KKM(e,16384,191)){m=1;k.KO(0,t,"य");}else if(k.KKM(e,16400,191)){m=1;k.KO(0,t,"य़");}else if(k.KKM(e,16384,192)){m=1;k.KO(0,t,"ॊ");}else if(k.KKM(e,16400,192)){m=1;k.KO(0,t,"ऒ");}else if(k.KKM(e,16384,219)){m=1;k.KO(0,t,"ड");}else if(k.KKM(e,16400,219)){m=1;k.KO(0,t,"ढ");}else if(k.KKM(e,16384,219)){m=1;k.KO(0,t,"ड़");}else if(k.KKM(e,16400,219)){m=1;k.KO(0,t,"ढ़");}else if(k.KKM(e,16384,220)){m=1;k.KO(0,t,"ॉ");}else if(k.KKM(e,16400,220)){m=1;k.KO(0,t,"ऑ");}else if(k.KKM(e,16384,221)){m=1;k.KO(0,t,"़");}else if(k.KKM(e,16400,221)){m=1;k.KO(0,t,"ञ");}else if(k.KKM(e,16384,222)){m=1;k.KO(0,t,"ट");}else if(k.KKM(e,16400,222)){m=1;k.KO(0,t,"ठ");}else if(k.KKM(e,16400,222)){m=1;k.KO(0,t,"॑");}else if(k.KKM(e,16384,226)){m=1;k.KO(0,t,"ॉ");}else if(k.KKM(e,16400,226)){m=1;k.KO(0,t,"ऑ");}return m;};} diff --git a/web/docs/engine/guide/examples/js/devanagari_inscript_load.js b/web/docs/engine/guide/examples/js/devanagari_inscript_load.js new file mode 100644 index 0000000000..c2fd4d90fe --- /dev/null +++ b/web/docs/engine/guide/examples/js/devanagari_inscript_load.js @@ -0,0 +1,2 @@ +/*(C) Copyright 1994-2006 Tavultesoft Pty Ltd. All Rights Reserved. Details: keymanweb.com*/ +KeymanWeb.KRS(new Stub_Keyboard_devanagari_inscript()); function Stub_Keyboard_devanagari_inscript() {this.KF="devanagari_inscript.js";this.KI="Keyboard_devanagari_inscript";this.KN="Devanagari (INSCRIPT)";} diff --git a/web/docs/engine/guide/examples/js/european2.js b/web/docs/engine/guide/examples/js/european2.js new file mode 100644 index 0000000000..bc658b528e --- /dev/null +++ b/web/docs/engine/guide/examples/js/european2.js @@ -0,0 +1,110 @@ +KeymanWeb.KR(new Keyboard_european2());function Keyboard_european2(){this.KI="Keyboard_european2";this.KN="EuroLatin2 Keyboard";this.KV=null;this.KH='

More help

Letters
Symbols
Accent
Marks
Type`#\'"^%&*~-_:@.|,
Result `  ̏ ´ ˝ ˆ ˇ  ̑ ˘ ˜ ˉ  ̱ ¨ ˚ ˙ . ¸
Other
Letters
Type = thencegjnostyz\'
Result ɔ ə ɂ ɲ ŋ ɵ ß þ ȝ ʒ
Ɔ Ə Ɂ Ɲ Ŋ Ɵ Þ Ȝ Ʒ

Type \\ thendegknos
Result ð ɛ ǥ ĸ ʼn ø ſ
Ð Ɛ Ǥ Ø
Digraphs Typea\\ed\\zf\\if\\li\\jl\\jn\\jo\\eo\\i
Result æ dž ij lj nj œ ƣ
Æ Dž DŽ IJ Lj LJ Nj NJ Œ Ƣ
Punctuation
and Symbols
Type\\?\\!<<>>\\f\\m\\P\\S\\T\\t\\|\\c\\p\\rt\\m
Result¿¡«»ªº§¦©®

Type\\:\\\'\\,\\_\\M\\N\\-\\~\\...\\.\\>
Result¨´¸¯­¬·
Numbers
and Fractions
Type\\+\\x\\/\\*\\%\\u
Result±×÷°µ

Typen\\o\\1\\2\\3\\4\\5\\6\\7\\8\\9\\0
Result¹²³

Type1//21//32//31//43//41//52//53//54//51//65//61//83//85//87//8
Result½¼¾
Currency
Symbols
Type $ thencefhlnNpPrRwy
Result¢£¥

Type $ thenCdDFgGkKt
Result¤
';this.KM=0;this.KBVER="1.6";this.KVKL={"tablet":{"font":"Tahoma","layer":[{"id":"default","row":[{"id":1,"key":[{"id":"K_Q","text":"q","sk":[{"id":"U_A78C"}]},{"id":"K_W","text":"w","sk":[{"id":"U_1E81"},{"id":"U_1E83"},{"id":"U_0175"},{"id":"U_1E85"},{"id":"U_1E98"},{"id":"U_1E87"},{"id":"U_1E89"}]},{"id":"K_E","text":"e","sk":[{"text":"\u00E8","id":"U_00E8"},{"text":"\u0205","id":"U_0205"},{"text":"\u00E9","id":"U_00E9"},{"text":"\u00EA","id":"U_00EA"},{"text":"\u011B","id":"U_011B"},{"text":"\u0207","id":"U_0207"},{"text":"\u0115","id":"U_0115"},{"text":"\u1EBD","id":"U_1EBD"},{"text":"\u0113","id":"U_0113"},{"text":"\u00EB","id":"U_00EB"},{"text":"\u0117","id":"U_0117"},{"text":"\u1EB9","id":"U_1EB9"},{"text":"\u0119","id":"U_0119"},{"text":"\u0259","id":"U_0259"},{"text":"\u025B","id":"U_025B"}]},{"id":"K_R","text":"r","sk":[{"id":"U_0211"},{"id":"U_0155"},{"id":"U_0159"},{"id":"U_0213"},{"id":"U_024D"},{"id":"U_1E5F"},{"id":"U_1E59"},{"id":"U_1E5B"},{"id":"U_0157"}]},{"id":"K_T","text":"t","sk":[{"text":"\u0165","id":"U_0165"},{"text":"\u0167","id":"U_0167"},{"text":"\u1E6F","id":"U_1E6F"},{"text":"\u1E97","id":"U_1E97"},{"text":"\u1E6B","id":"U_1E6B"},{"text":"\u1E6D","id":"U_1E6D"},{"text":"\u0163","id":"U_0163"},{"text":"\u021B","id":"U_021B"},{"text":"\u00FE","id":"U_00FE"}]},{"id":"K_Y","text":"y","sk":[{"id":"U_1EF3"},{"id":"U_00FD"},{"id":"U_0177"},{"id":"U_1EF9"},{"id":"U_0233"},{"id":"U_00FF"},{"id":"U_1E99"},{"id":"U_1E8F"},{"id":"U_1EF5"}]},{"id":"K_U","text":"u","sk":[{"id":"U_00F9"},{"id":"U_0215"},{"id":"U_00FA"},{"id":"U_0171"},{"id":"U_00FB"},{"id":"U_01D4"},{"id":"U_0217"},{"id":"U_016D"},{"id":"U_0169"},{"id":"U_016B"},{"id":"U_00FC"},{"id":"U_016F"},{"id":"U_1EE5"},{"id":"U_0173"}]},{"id":"K_I","text":"i","sk":[{"id":"U_00EC"},{"id":"U_0209"},{"id":"U_00ED"},{"id":"U_00EE"},{"id":"U_01D0"},{"id":"U_020B"},{"id":"U_012D"},{"id":"U_0129"},{"id":"U_012B"},{"id":"U_00EF"},{"id":"U_0131"},{"id":"U_1ECB"},{"id":"U_012F"},{"id":"U_0272"},{"id":"U_0133"}]},{"id":"K_O","text":"o","sk":[{"id":"U_00F2"},{"id":"U_020D"},{"id":"U_00F3"},{"id":"U_0151"},{"id":"U_00F4"},{"id":"U_01D2"},{"id":"U_020F"},{"id":"U_014F"},{"id":"U_00F5"},{"id":"U_014D"},{"id":"U_00F6"},{"id":"U_022F"},{"id":"U_1ECD"},{"id":"U_01EB"},{"id":"U_0275"},{"id":"U_00F8"},{"id":"U_0254"},{"id":"U_0153"},{"id":"U_01A3"}]},{"id":"K_P","text":"p","sk":[{"id":"U_1E55"},{"id":"U_0070"},{"id":"U_1E57"}]}]},{"id":2,"key":[{"id":"K_A","text":"a","pad":"40","sk":[{"id":"U_00E0"},{"id":"U_0201"},{"id":"U_00E1"},{"id":"U_00E2"},{"id":"U_01CE"},{"id":"U_0203"},{"id":"U_0103"},{"id":"U_00E3"},{"id":"U_0101"},{"id":"U_00E4"},{"id":"U_00E5"},{"id":"U_0227"},{"id":"U_1EA1"},{"id":"U_0105"},{"id":"U_00E6"}]},{"id":"K_S","text":"s","sk":[{"text":"\u015B","id":"U_015B"},{"text":"\u015D","id":"U_015D"},{"text":"\u0161","id":"U_0161"},{"text":"\u1E61","id":"U_1E61"},{"text":"\u1E63","id":"U_1E63"},{"text":"\u015F","id":"U_015F"},{"text":"\u0219","id":"U_0219"},{"text":"\u00DF","id":"U_00DF"},{"text":"\u017F","id":"U_017F"}]},{"id":"K_D","text":"d","sk":[{"id":"U_010F"},{"id":"U_0111"},{"id":"U_1E0F"},{"id":"U_1E0B"},{"id":"U_1E0D"},{"id":"U_1E11"},{"id":"U_00F0"},{"id":"U_01C6"}]},{"id":"K_F","text":"f","sk":[{"id":"U_1E1F"},{"id":"U_FB01"},{"id":"U_FB02"}]},{"id":"K_G","text":"g","sk":[{"id":"U_01F5"},{"id":"U_011D"},{"id":"U_01E7"},{"id":"U_011F"},{"id":"U_0067"},{"id":"U_1E21"},{"id":"U_0121"},{"id":"U_0123"},{"id":"U_0242"},{"id":"U_01E5"}]},{"id":"K_H","text":"h","sk":[{"id":"U_0125"},{"id":"U_021F"},{"id":"U_1E2B"},{"id":"U_0127"},{"id":"U_1E96"},{"id":"U_1E27"},{"id":"U_1E23"},{"id":"U_1E25"},{"id":"U_1E29"}]},{"id":"K_J","text":"j","sk":[{"id":"U_0135"},{"id":"U_01F0"},{"id":"U_0249"},{"id":"U_0237"}]},{"id":"K_K","text":"k","sk":[{"id":"U_1E31"},{"id":"U_01E9"},{"id":"U_1E35"},{"id":"U_1E33"},{"id":"U_0137"},{"id":"U_0138"}]},{"id":"K_L","text":"l","sk":[{"id":"U_013A"},{"id":"U_013E"},{"id":"U_026B"},{"id":"U_0142"},{"id":"U_1E3B"},{"id":"U_0140"},{"id":"U_1E37"},{"id":"U_013C"},{"id":"U_01C9"}]},{"id":"T_new_20","text":"","width":"10","sp":"10"}]},{"id":3,"key":[{"id":"K_SHIFT","text":"*Shift*","width":"100","sp":"1","nextlayer":"shift"},{"id":"K_Z","text":"z","sk":[{"id":"U_017A"},{"id":"U_1E91"},{"id":"U_017E"},{"id":"U_01B6"},{"id":"U_1E95"},{"id":"U_017C"},{"id":"U_1E93"},{"id":"U_2C6C"},{"id":"U_0292"},{"id":"U_01EF"}]},{"id":"K_X","text":"x","sk":[{"id":"U_1E8D"},{"id":"U_1E8B"}]},{"id":"K_C","text":"c","sk":[{"id":"U_0107"},{"id":"U_0109"},{"id":"U_010D"},{"id":"U_010B"},{"id":"U_00E7"}]},{"id":"K_V","text":"v","sk":[{"id":"U_1E7D"},{"id":"U_1E7F"}]},{"id":"K_B","text":"b","sk":[{"id":"U_0180"},{"id":"U_1E07"},{"id":"U_1E03"},{"id":"U_1E05"}]},{"id":"K_N","text":"n","sk":[{"id":"U_014B"},{"id":"U_01F9"},{"id":"U_0144"},{"id":"U_0148"},{"id":"U_00F1"},{"id":"U_1E49"},{"id":"U_1E45"},{"id":"U_1E47"},{"id":"U_0146"},{"id":"U_0149"},{"id":"U_01CC"}]},{"id":"K_M","text":"m","sk":[{"id":"U_1E3F"},{"id":"U_1E41"},{"id":"U_1E43"}]},{"id":"K_PERIOD","text":".","sk":[{"id":"K_COMMA","text":","},{"id":"U_0021"},{"id":"U_003F"},{"id":"U_0027"},{"id":"U_0022"},{"id":"U_005C"},{"id":"U_003A"},{"id":"U_003B"}]},{"id":"K_BKSP","text":"*BkSp*","width":"100","sp":"1"}]},{"id":4,"key":[{"id":"K_NUMERALS","text":"*123*","width":"150","sp":"1","nextlayer":"numeric"},{"id":"K_LOPT","text":"*Menu*","width":"100","sp":"1"},{"id":"T_new_34","text":"","width":"10","sp":"10"},{"id":"K_SPACE","text":"","width":"610","sp":"0"},{"id":"T_new_36","text":"","width":"10","sp":"10"},{"id":"K_ENTER","text":"*Enter*","width":"140","sp":"1"}]}]},{"id":"shift","row":[{"id":1,"key":[{"id":"K_Q","text":"Q","sk":[{"id":"U_A78B"}]},{"id":"K_W","text":"W","sk":[{"id":"U_1E80"},{"id":"U_1E82"},{"id":"U_0174"},{"id":"U_1E84"},{"id":"U_1E86"},{"id":"U_1E88"}]},{"id":"K_E","text":"E","sk":[{"id":"U_00C8"},{"id":"U_0204"},{"id":"U_00C9"},{"id":"U_00CA"},{"id":"U_011A"},{"id":"U_0206"},{"id":"U_0114"},{"id":"U_1EBC"},{"id":"U_0112"},{"id":"U_00CB"},{"id":"U_0116"},{"id":"U_1EB8"},{"id":"U_0118"},{"id":"U_018F"},{"id":"U_0190"}]},{"id":"K_R","text":"R","sk":[{"id":"U_0210"},{"id":"U_0154"},{"id":"U_0158"},{"id":"U_0212"},{"id":"U_024C"},{"id":"U_1E5E"},{"id":"U_1E58"},{"id":"U_1E5A"},{"id":"U_0156"}]},{"id":"K_T","text":"T","sk":[{"text":"\u0164","id":"U_0164"},{"text":"\u0166","id":"U_0166"},{"text":"\u1E6E","id":"U_1E6E"},{"text":"\u1E6A","id":"U_1E6A"},{"text":"\u1E6C","id":"U_1E6C"},{"text":"\u0162","id":"U_0162"},{"text":"\u021A","id":"U_021A"},{"text":"\u00DE","id":"U_00DE"}]},{"id":"K_Y","text":"Y","sk":[{"id":"U_1EF2"},{"id":"U_00DD"},{"id":"U_0176"},{"id":"U_1EF8"},{"id":"U_0232"},{"id":"U_0178"},{"id":"U_1E8E"},{"id":"U_1EF4"}]},{"id":"K_U","text":"U","sk":[{"id":"U_00D9"},{"id":"U_0214"},{"id":"U_00DA"},{"id":"U_0170"},{"id":"U_00DB"},{"id":"U_01D3"},{"id":"U_0216"},{"id":"U_016C"},{"id":"U_0168"},{"id":"U_016A"},{"id":"U_00DC"},{"id":"U_016E"},{"id":"U_1EE4"},{"id":"U_0172"}]},{"id":"K_I","text":"I","sk":[{"id":"U_00CC"},{"id":"U_0208"},{"id":"U_00CD"},{"id":"U_00CE"},{"id":"U_01CF"},{"id":"U_020A"},{"id":"U_012C"},{"id":"U_0128"},{"id":"U_012A"},{"id":"U_00CF"},{"id":"U_0130"},{"id":"U_1ECA"},{"id":"U_012E"},{"id":"U_019D"}]},{"id":"K_O","text":"O","sk":[{"id":"U_00D2"},{"id":"U_020C"},{"id":"U_00D3"},{"id":"U_0150"},{"id":"U_00D4"},{"id":"U_01D1"},{"id":"U_020E"},{"id":"U_014E"},{"id":"U_00D5"},{"id":"U_014C"},{"id":"U_00D6"},{"id":"U_022E"},{"id":"U_1ECC"},{"id":"U_01EA"},{"id":"U_019F"},{"id":"U_00D8"},{"id":"U_0186"},{"id":"U_0152"},{"id":"U_01A2"}]},{"id":"K_P","text":"P","sk":[{"id":"U_1E54"},{"id":"U_0050"},{"id":"U_1E56"}]}]},{"id":2,"key":[{"id":"K_A","text":"A","pad":"40","sk":[{"id":"U_00C0"},{"id":"U_0200"},{"id":"U_00C1"},{"id":"U_00C2"},{"id":"U_01CD"},{"id":"U_0202"},{"id":"U_0102"},{"id":"U_00C3"},{"id":"U_0100"},{"id":"U_00C4"},{"id":"U_00C5"},{"id":"U_0226"},{"id":"U_1EA0"},{"id":"U_0104"},{"id":"U_00C6"}]},{"id":"K_S","text":"S","sk":[{"text":"\u015A","id":"U_015A"},{"text":"\u015C","id":"U_015C"},{"text":"\u0160","id":"U_0160"},{"text":"\u1E60","id":"U_1E60"},{"text":"\u1E62","id":"U_1E62"},{"text":"\u015E","id":"U_015E"},{"text":"\u0218","id":"U_0218"},{"text":"\u1E9E","id":"U_1E9E"}]},{"id":"K_D","text":"D","sk":[{"id":"U_010E"},{"id":"U_0110"},{"id":"U_1E0E"},{"id":"U_1E0A"},{"id":"U_1E0C"},{"id":"U_1E10"},{"id":"U_00D0"},{"id":"U_01C5"},{"id":"U_01C4"}]},{"id":"K_F","text":"F","sk":[{"id":"U_1E1E"}]},{"id":"K_G","text":"G","sk":[{"id":"U_01F4"},{"id":"U_011C"},{"id":"U_01E6"},{"id":"U_011E"},{"id":"U_0047"},{"id":"U_1E20"},{"id":"U_0120"},{"id":"U_0122"},{"id":"U_0241"},{"id":"U_01E4"}]},{"id":"K_H","text":"H","sk":[{"id":"U_0124"},{"id":"U_021E"},{"id":"U_1E2A"},{"id":"U_0126"},{"id":"U_1E26"},{"id":"U_1E22"},{"id":"U_1E24"},{"id":"U_1E28"}]},{"id":"K_J","text":"J","sk":[{"id":"U_0134"},{"id":"U_0248"}]},{"id":"K_K","text":"K","sk":[{"id":"U_1E30"},{"id":"U_01E8"},{"id":"U_1E34"},{"id":"U_1E32"},{"id":"U_0136"}]},{"id":"K_L","text":"L","sk":[{"id":"U_0139"},{"id":"U_013D"},{"id":"U_2C62"},{"id":"U_0141"},{"id":"U_1E3A"},{"id":"U_013F"},{"id":"U_1E36"},{"id":"U_013B"},{"id":"U_01C8"},{"id":"U_01C7"}]},{"id":"T_new_60","text":"","width":"10","sp":"10"}]},{"id":3,"key":[{"id":"K_SHIFT","text":"*Shift*","width":"100","sp":"2","nextlayer":"default"},{"id":"K_Z","text":"Z","sk":[{"id":"U_021C"},{"id":"U_0179"},{"id":"U_1E90"},{"id":"U_017D"},{"id":"U_01B5"},{"id":"U_1E94"},{"id":"U_017B"},{"id":"U_1E92"},{"id":"U_2C6B"},{"id":"U_01B7"},{"id":"U_01EE"}]},{"id":"K_X","text":"X","sk":[{"id":"U_1E8C"},{"id":"U_1E8A"}]},{"id":"K_C","text":"C","sk":[{"id":"U_0106"},{"id":"U_0108"},{"id":"U_010C"},{"id":"U_010A"},{"id":"U_00C7"}]},{"id":"K_V","text":"V","sk":[{"id":"U_1E7C"},{"id":"U_1E7E"}]},{"id":"K_B","text":"B","sk":[{"id":"U_0243"},{"id":"U_1E06"},{"id":"U_1E02"},{"id":"U_1E04"}]},{"id":"K_N","text":"N","sk":[{"id":"U_014A"},{"id":"U_01F8"},{"id":"U_0143"},{"id":"U_0147"},{"id":"U_00D1"},{"id":"U_1E48"},{"id":"U_1E44"},{"id":"U_1E46"},{"id":"U_0145"},{"id":"U_01CB"},{"id":"U_01CA"}]},{"id":"K_M","text":"M","sk":[{"id":"U_1E3E"},{"id":"U_1E40"},{"id":"U_1E42"}]},{"id":"K_PERIOD","text":".","layer":"default","sk":[{"text":",","id":"K_COMMA"},{"text":"!","id":"U_0021","layer":"default"},{"text":"?","id":"U_003F","layer":"default"},{"text":"'","id":"U_0027","layer":"default"},{"text":"\"","id":"U_0022","layer":"default"},{"text":"\\","id":"U_005C","layer":"default"},{"text":":","id":"U_003A","layer":"default"},{"text":";","id":"U_003B","layer":"default"}]},{"id":"K_BKSP","text":"*BkSp*","width":"100","sp":"1"}]},{"id":4,"key":[{"id":"K_NUMERALS","text":"*123*","width":"150","sp":"1","nextlayer":"numeric"},{"id":"K_LOPT","text":"*Menu*","width":"100","sp":"1"},{"id":"T_new_74","text":"","width":"10","sp":"10"},{"id":"K_SPACE","text":"","width":"610","sp":"0"},{"id":"T_new_76","text":"","width":"10","sp":"10"},{"id":"K_ENTER","text":"*Enter*","width":"140","sp":"1"}]}]},{"id":"numeric","row":[{"id":1,"key":[{"id":"K_1","text":"1","sp":"0","sk":[{"id":"U_00B9"},{"id":"U_00BD"},{"id":"U_2153"},{"id":"U_00BC"},{"id":"U_2155"},{"id":"U_2159"},{"id":"U_215B"}]},{"id":"K_2","text":"2","sp":"0","sk":[{"id":"U_00B2"},{"id":"U_2154"},{"id":"U_2156"}]},{"id":"K_3","text":"3","sp":"0","sk":[{"id":"U_00B3"},{"id":"U_00BE"},{"id":"U_2157"},{"id":"U_215C"}]},{"id":"K_4","text":"4","sp":"0","sk":[{"id":"U_2074"},{"id":"U_2158"}]},{"id":"K_5","text":"5","sp":"0","sk":[{"id":"U_2075"},{"id":"U_215A"},{"id":"U_215D"}]},{"id":"K_6","text":"6","sp":"0","sk":[{"id":"U_2076"}]},{"id":"K_7","text":"7","sp":"0","sk":[{"id":"U_2077"},{"id":"U_215E"}]},{"id":"K_8","text":"8","sp":"0","sk":[{"id":"U_2078"}]},{"id":"K_9","text":"9","sp":"0","sk":[{"id":"U_2079"}]},{"id":"K_0","text":"0","sp":"0","sk":[{"id":"U_2070"}]}]},{"id":2,"key":[{"id":"U_0024","text":"$","pad":"40"},{"id":"U_0040","text":"@"},{"id":"U_0023","text":"#"},{"id":"U_0025","text":"%","sk":[{"id":"U_2030"},{"id":"U_2031"}]},{"id":"U_0026","text":"&"},{"id":"U_005F","text":"_"},{"id":"U_003D","text":"="},{"id":"U_007C","text":"|"},{"id":"U_002F","text":"\/","sk":[{"text":"\\","id":"U_005C"}]},{"id":"T_new_164","text":"","width":"10","sp":"10"}]},{"id":3,"key":[{"id":"K_LOWER","text":"*abc*","width":"100","sp":"1","nextlayer":"default"},{"id":"U_005B","text":"[","sk":[{"id":"U_007B"},{"id":"U_00AB"},{"id":"U_003C"}]},{"id":"U_0028","text":"("},{"id":"U_0029","text":")"},{"id":"U_005D","text":"]","sk":[{"id":"U_007D"},{"id":"U_00BB"},{"id":"U_003E"}]},{"id":"U_002B","text":"+"},{"id":"U_002D","text":"-"},{"id":"U_002A","text":"*"},{"id":"K_PERIOD","text":".","sk":[{"id":"K_COMMA","text":","},{"id":"U_0021"},{"id":"U_003F"},{"id":"U_0027"},{"id":"U_0022"},{"id":"U_005C"},{"id":"U_003A"},{"id":"U_003B"}]},{"id":"K_BKSP","text":"*BkSp*","width":"100","sp":"1"}]},{"id":4,"key":[{"id":"K_CURRENCIES","text":"*Currency*","width":"150","sp":"1","nextlayer":"currency"},{"id":"K_LOPT","text":"*Menu*","width":"100","sp":"1"},{"id":"T_new_178","text":"","width":"10","sp":"10"},{"id":"K_SPACE","text":"","width":"610","sp":"0"},{"id":"T_new_180","text":"","width":"10","sp":"10"},{"id":"K_ENTER","text":"*Enter*","width":"140","sp":"1"}]}]},{"id":"symbol","row":[{"id":1,"key":[{"id":"U_0060","text":"`"},{"id":"U_007E","text":"~"},{"id":"U_005E","text":"^"},{"id":"U_00A8","text":"\u00A8"},{"id":"U_00B4","text":"\u00B4"},{"id":"U_00B8","text":"\u00B8"},{"id":"U_00AF","text":"\u00AF"},{"id":"U_00BF","text":"\u00BF"},{"id":"U_00A1","text":"\u00A1"},{"id":"U_00AC","text":"\u00AC"}]},{"id":2,"key":[{"id":"U_00AA","text":"\u00AA","pad":"40"},{"id":"U_00BA","text":"\u00BA"},{"id":"U_00B6","text":"\u00B6"},{"id":"U_00A7","text":"\u00A7"},{"id":"U_2021","text":"\u2021"},{"id":"U_2020","text":"\u2020"},{"id":"U_00A6","text":"\u00A6"},{"id":"U_2122","text":"\u2122"},{"id":"U_2116","text":"\u2116"},{"id":"T_new_336","text":"","width":"10","sp":"10"}]},{"id":3,"key":[{"id":"K_LOWER","text":"*abc*","width":"100","sp":"1","nextlayer":"default"},{"id":"U_00A9","text":"\u00A9"},{"id":"U_2117","text":"\u2117"},{"id":"U_00AE","text":"\u00AE"},{"id":"U_2014","text":"\u2014"},{"id":"U_2013","text":"\u2013"},{"id":"U_2022","text":"\u2022"},{"id":"U_00B7","text":"\u00B7"},{"id":"U_2026","text":"\u2026","sk":[{"id":"U_00B1"},{"id":"U_00D7"},{"id":"U_00F7"},{"id":"U_00B5"},{"id":"U_00B0"},{"id":"U_2031"}]},{"id":"K_BKSP","text":"*BkSp*","width":"100","sp":"1"}]},{"id":4,"key":[{"id":"K_CURRENCIES","text":"*Currency*","width":"150","sp":"1","nextlayer":"numeric"},{"id":"K_LOPT","text":"*Menu*","width":"100","sp":"1"},{"id":"T_new_350","text":"","width":"10","sp":"10"},{"id":"K_SPACE","text":"","width":"610","sp":"0"},{"id":"T_new_352","text":"","width":"10","sp":"10"},{"id":"K_ENTER","text":"*Enter*","width":"140","sp":"1"}]}]},{"id":"currency","row":[{"id":1,"key":[{"id":"U_00A2","text":"\u00A2","nextlayer":"numeric"},{"id":"U_20AC","text":"\u20AC","nextlayer":"numeric"},{"id":"U_20A4","text":"\u20A4","nextlayer":"numeric"},{"id":"U_00A3","text":"\u00A3","nextlayer":"numeric"},{"id":"U_20AA","text":"\u20AA","nextlayer":"numeric"},{"id":"U_20A8","text":"\u20A8","nextlayer":"numeric"},{"id":"U_20B9","text":"\u20B9","nextlayer":"numeric"},{"id":"U_20A9","text":"\u20A9","nextlayer":"numeric"},{"id":"U_00A5","text":"\u00A5","nextlayer":"numeric"},{"id":"U_00A4","text":"\u00A4","nextlayer":"numeric"}]},{"id":2,"key":[{"id":"U_20AB","text":"\u20AB","pad":"40"},{"id":"U_20AF","text":"\u20AF"},{"id":"U_20B1","text":"\u20B1"},{"id":"U_20A3","text":"\u20A3"},{"id":"U_20B0","text":"\u20B0"},{"id":"U_20B2","text":"\u20B2"},{"id":"U_20B4","text":"\u20B4"},{"id":"U_20A1","text":"\u20A1"},{"id":"U_20AD","text":"\u20AD"},{"id":"T_new_2717","text":"","width":"10","sp":"10"}]},{"id":3,"key":[{"id":"K_LOWER","text":"*abc*","width":"100","sp":"1","nextlayer":"default"},{"id":"U_20A6","text":"\u20A6"},{"id":"U_20A7","text":"\u20A7"},{"id":"U_20AE","text":"\u20AE"},{"id":"U_0BF9","text":"\u0BF9"},{"id":"U_09F3","text":"\u09F3"},{"id":"U_0E3F","text":"\u0E3F"},{"id":"T_new_2725","text":"","sp":"9"},{"id":"T_new_2726","text":"","sp":"9"},{"id":"K_BKSP","text":"*BkSp*","width":"100","sp":"1"}]},{"id":4,"key":[{"id":"K_SYMBOLS","text":"*Symbol*","width":"150","sp":"1","nextlayer":"symbol"},{"id":"K_LOPT","text":"*Menu*","width":"100","sp":"1"},{"id":"T_new_2731","text":"","width":"10","sp":"10"},{"id":"K_SPACE","text":"","width":"610","sp":"0"},{"id":"T_new_2733","text":"","width":"10","sp":"10"},{"id":"K_ENTER","text":"*Enter*","width":"140","sp":"1"}]}]}]}};this.s15="`#'\"^%&*~-_:@.|,=\\$";this.s16="àèìǹòùẁỳÀÈÌǸÒÙẀỲ";this.s17="aeinouwyAEINOUWY";this.s18="ȁȅȉȍȑȕȀȄȈȌȐȔ";this.s19="aeioruAEIORU";this.s20="áćéǵíḱĺḿńóṕŕśúẃýźÁĆÉǴÍḰĹḾŃÓṔŔŚÚẂÝŹ";this.s21="acegiklmnoprsuwyzACEGIKLMNOPRSUWYZ";this.s22="őűŐŰ";this.s23="ouOU";this.s24="âĉêĝĥîĵôŝûŵŷẑÂĈÊĜĤÎĴÔŜÛŴŶẐ";this.s25="aceghijosuwyzACEGHIJOSUWYZ";this.s26="ǎǍčČďĎěĚǧǦȟȞǐǏǰǩǨľĽňŇǒǑřŘšŠťŤǔǓǯǮžŽ";this.s27="aAcCdDeEgGhHiIjkKlLnNoOrRsStTuUxXzZ";this.s28="ȂȃȆȇȊȋȎȏȒȓȖȗ";this.s29="AaEeIiOoRrUu";this.s30="ăĂĕĔğĞḫḪĭĬŏŎŭŬ";this.s31="aAeEgGhHiIoOuU";this.s32="ãÃẽẼĩĨɫⱢñÑõÕũŨṽṼỹỸ";this.s33="aAeEiIlLnNoOuUvVyY";this.s34="ĀāɃƀĐđĒēḠḡĦħĪīɈɉŁłŌōɌɍŦŧŪūȲȳƵƶ";this.s35="AaBbDdEeGgHhIiJjLlOoRrTtUuYyZz";this.s36="ḆḇḎḏẖḴḵḺḻṈṉṞṟṮṯẔẕ";this.s37="BbDdhKkLlNnRrTtZz";this.s38="äëḧïöẗüẅẍÿÄËḦÏÖÜẄẌŸ";this.s39="aehiotuwxyAEHIOUWXY";this.s40="åÅůŮẘẙșȘțȚ";this.s41="aAuUwysStT";this.s42="ȧȦḃḂċĊḋḊėĖḟḞġĠḣḢıİȷŀĿṁṀṅṄȯȮṗṖṙṘṡṠṫṪẇẆẋẊẏẎżŻ";this.s43="aAbBcCdDeEfFgGhHiIjlLmMnNoOpPrRsStTwWxXyYzZ";this.s44="ẠạḄḅḌḍẸẹḤḥỊịḲḳḶḷṂṃṆṇỌọṚṛṢṣṬṭỤụṾṿẈẉỴỵẒẓ";this.s45="AaBbDdEeHhIiKkLlMmNnOoRrSsTtUuVvWwYyZz";this.s46="ąĄçÇḑḐęĘģĢḩḨįĮķĶļĻņŅǫǪŗŖşŞţŢųŲⱬⱫ";this.s47="aAcCdDeEgGhHiIkKlLnNoOrRsStTuUzZ";this.s48="ƆɔƏəɁɂƝɲŊŋƟɵẞßÞþȜȝƷʒ";this.s49="CcEeGgJjNnOoSsTtYyZz";this.s50="©ÐðƐɛªǤǥĸ—º–ʼnØø¶℗®§ſ‡†µ×¡¦¨¬­¯°±´·¸¿÷‰•¹²³⁴⁵⁶⁷⁸⁹⁰";this.s51="cDdEefGgkMmNnOoPprSsTtux!|:~-_*+'.,?/%>1234567890";this.s52="¤¢₯₫€€₱₣₲₰₴₡₭₤₦₪₧£₹₨₮₩¥";this.s53="CcDdEefFGghkKlNnPpRrtwy";this.s56="tablet";this.s57="phone";this.KVER="9.0.487.0";this.gs=function(t,e) {return this.g0(t,e);};this.g0=function(t,e) {var k=KeymanWeb,r=0,m=0;if(k.KKM(e,16400,49)&&k.KCM(1,t,"\\",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"¡");}else if(k.KKM(e,16400,222)&&k.KCM(1,t,"=",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"Ꞌ");}else if(k.KKM(e,16400,222)&&k.KCM(1,t,"\"",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"\"");}else if(k.KKM(e,16400,222)&&k.KIFS(31,this.s56,t)) {r=m=1;r=this.g1(t,e);}else if(k.KKM(e,16400,222)&&k.KIFS(31,this.s57,t)) {r=m=1;r=this.g1(t,e);}else if(k.KKM(e,16400,222)) {r=m=1;k.KO(0,t,"\"");k.KDO(-1,t,0);}else if(k.KKM(e,16400,51)&&k.KCM(1,t,"#",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"#");}else if(k.KKM(e,16400,51)&&k.KIFS(31,this.s56,t)) {r=m=1;r=this.g1(t,e);}else if(k.KKM(e,16400,51)&&k.KIFS(31,this.s57,t)) {r=m=1;r=this.g1(t,e);}else if(k.KKM(e,16400,51)) {r=m=1;k.KO(0,t,"#");k.KDO(-1,t,0);}else if(k.KKM(e,16400,52)&&k.KCM(1,t,"$",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"$");}else if(k.KKM(e,16400,52)&&k.KIFS(31,this.s56,t)) {r=m=1;r=this.g1(t,e);}else if(k.KKM(e,16400,52)&&k.KIFS(31,this.s57,t)) {r=m=1;r=this.g1(t,e);}else if(k.KKM(e,16400,52)) {r=m=1;k.KO(0,t,"$");k.KDO(-1,t,0);}else if(k.KKM(e,16400,53)&&k.KCM(1,t,"\\",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"‰");}else if(k.KKM(e,16400,53)&&k.KCM(1,t,"%",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"%");}else if(k.KKM(e,16400,53)&&k.KIFS(31,this.s56,t)) {r=m=1;r=this.g1(t,e);}else if(k.KKM(e,16400,53)&&k.KIFS(31,this.s57,t)) {r=m=1;r=this.g1(t,e);}else if(k.KKM(e,16400,53)) {r=m=1;k.KO(0,t,"%");k.KDO(-1,t,0);}else if(k.KKM(e,16400,55)&&k.KCM(1,t,"&",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"&");}else if(k.KKM(e,16400,55)&&k.KIFS(31,this.s56,t)) {r=m=1;r=this.g1(t,e);}else if(k.KKM(e,16400,55)&&k.KIFS(31,this.s57,t)) {r=m=1;r=this.g1(t,e);}else if(k.KKM(e,16400,55)) {r=m=1;k.KO(0,t,"&");k.KDO(-1,t,0);}else if(k.KKM(e,16384,222)&&k.KCM(1,t,"=",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"ꞌ");}else if(k.KKM(e,16384,222)&&k.KCM(1,t,"\\",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"´");}else if(k.KKM(e,16384,222)&&k.KCM(1,t,"'",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"'");}else if(k.KKM(e,16384,222)&&k.KIFS(31,this.s56,t)) {r=m=1;r=this.g1(t,e);}else if(k.KKM(e,16384,222)&&k.KIFS(31,this.s57,t)) {r=m=1;r=this.g1(t,e);}else if(k.KKM(e,16384,222)) {r=m=1;k.KO(0,t,"'");k.KDO(-1,t,0);}else if(k.KKM(e,16400,56)&&k.KCM(1,t,"\\",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"°");}else if(k.KKM(e,16400,56)&&k.KCM(1,t,"*",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"*");}else if(k.KKM(e,16400,56)&&k.KIFS(31,this.s56,t)) {r=m=1;r=this.g1(t,e);}else if(k.KKM(e,16400,56)&&k.KIFS(31,this.s57,t)) {r=m=1;r=this.g1(t,e);}else if(k.KKM(e,16400,56)) {r=m=1;k.KO(0,t,"*");k.KDO(-1,t,0);}else if(k.KKM(e,16400,187)&&k.KCM(1,t,"\\",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"±");}else if(k.KKM(e,16384,188)&&k.KCM(1,t,"\\",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"¸");}else if(k.KKM(e,16384,188)&&k.KCM(1,t,",",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,",");}else if(k.KKM(e,16384,188)&&k.KIFS(31,this.s56,t)) {r=m=1;r=this.g1(t,e);}else if(k.KKM(e,16384,188)&&k.KIFS(31,this.s57,t)) {r=m=1;r=this.g1(t,e);}else if(k.KKM(e,16384,188)) {r=m=1;k.KO(0,t,",");k.KDO(-1,t,0);}else if(k.KKM(e,16384,189)&&k.KCM(1,t,"\\",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"­");}else if(k.KKM(e,16384,189)&&k.KCM(1,t,"-",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"-");}else if(k.KKM(e,16384,189)&&k.KIFS(31,this.s56,t)) {r=m=1;r=this.g1(t,e);}else if(k.KKM(e,16384,189)&&k.KIFS(31,this.s57,t)) {r=m=1;r=this.g1(t,e);}else if(k.KKM(e,16384,189)) {r=m=1;k.KO(0,t,"-");k.KDO(-1,t,0);}else if(k.KKM(e,16384,190)&&k.KCM(1,t,"\\",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"·");}else if(k.KKM(e,16384,190)&&k.KCM(2,t,"·.",2)) {r=m=1;k.KO(2,t,"…");}else if(k.KKM(e,16384,190)&&k.KCM(1,t,".",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,".");}else if(k.KKM(e,16384,190)&&k.KIFS(31,this.s56,t)) {r=m=1;r=this.g1(t,e);}else if(k.KKM(e,16384,190)&&k.KIFS(31,this.s57,t)) {r=m=1;r=this.g1(t,e);}else if(k.KKM(e,16384,190)) {r=m=1;k.KO(0,t,".");k.KDO(-1,t,0);}else if(k.KKM(e,16384,191)&&k.KCM(1,t,"\\",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"÷");}else if(k.KKM(e,16384,48)&&k.KCM(1,t,"\\",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"⁰");}else if(k.KKM(e,16384,49)&&k.KCM(1,t,"\\",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"¹");}else if(k.KKM(e,16384,50)&&k.KCM(3,t,"1//",3)) {r=m=1;k.KO(3,t,"½");}else if(k.KKM(e,16384,50)&&k.KCM(1,t,"\\",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"²");}else if(k.KKM(e,16384,50)&&k.KCM(2,t,"¹/",2)) {r=m=1;k.KO(2,t,"½");}else if(k.KKM(e,16384,51)&&k.KCM(3,t,"1//",3)) {r=m=1;k.KO(3,t,"⅓");}else if(k.KKM(e,16384,51)&&k.KCM(3,t,"2//",3)) {r=m=1;k.KO(3,t,"⅔");}else if(k.KKM(e,16384,51)&&k.KCM(1,t,"\\",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"³");}else if(k.KKM(e,16384,51)&&k.KCM(2,t,"¹/",2)) {r=m=1;k.KO(2,t,"⅓");}else if(k.KKM(e,16384,51)&&k.KCM(2,t,"²/",2)) {r=m=1;k.KO(2,t,"⅔");}else if(k.KKM(e,16384,52)&&k.KCM(3,t,"1//",3)) {r=m=1;k.KO(3,t,"¼");}else if(k.KKM(e,16384,52)&&k.KCM(3,t,"3//",3)) {r=m=1;k.KO(3,t,"¾");}else if(k.KKM(e,16384,52)&&k.KCM(1,t,"\\",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"⁴");}else if(k.KKM(e,16384,52)&&k.KCM(2,t,"¹/",2)) {r=m=1;k.KO(2,t,"¼");}else if(k.KKM(e,16384,52)&&k.KCM(2,t,"³/",2)) {r=m=1;k.KO(2,t,"¾");}else if(k.KKM(e,16384,53)&&k.KCM(3,t,"1//",3)) {r=m=1;k.KO(3,t,"⅕");}else if(k.KKM(e,16384,53)&&k.KCM(3,t,"2//",3)) {r=m=1;k.KO(3,t,"⅖");}else if(k.KKM(e,16384,53)&&k.KCM(3,t,"3//",3)) {r=m=1;k.KO(3,t,"⅗");}else if(k.KKM(e,16384,53)&&k.KCM(3,t,"4//",3)) {r=m=1;k.KO(3,t,"⅘");}else if(k.KKM(e,16384,53)&&k.KCM(1,t,"\\",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"⁵");}else if(k.KKM(e,16384,54)&&k.KCM(3,t,"1//",3)) {r=m=1;k.KO(3,t,"⅙");}else if(k.KKM(e,16384,54)&&k.KCM(3,t,"5//",3)) {r=m=1;k.KO(3,t,"⅚");}else if(k.KKM(e,16384,54)&&k.KCM(1,t,"\\",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"⁶");}else if(k.KKM(e,16384,55)&&k.KCM(1,t,"\\",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"⁷");}else if(k.KKM(e,16384,56)&&k.KCM(3,t,"1//",3)) {r=m=1;k.KO(3,t,"⅛");}else if(k.KKM(e,16384,56)&&k.KCM(3,t,"3//",3)) {r=m=1;k.KO(3,t,"⅜");}else if(k.KKM(e,16384,56)&&k.KCM(3,t,"5//",3)) {r=m=1;k.KO(3,t,"⅝");}else if(k.KKM(e,16384,56)&&k.KCM(3,t,"7//",3)) {r=m=1;k.KO(3,t,"⅞");}else if(k.KKM(e,16384,56)&&k.KCM(1,t,"\\",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"⁸");}else if(k.KKM(e,16384,56)&&k.KCM(2,t,"¹/",2)) {r=m=1;k.KO(2,t,"⅛");}else if(k.KKM(e,16384,56)&&k.KCM(2,t,"³/",2)) {r=m=1;k.KO(2,t,"⅜");}else if(k.KKM(e,16384,56)&&k.KCM(2,t,"⁵/",2)) {r=m=1;k.KO(2,t,"⅝");}else if(k.KKM(e,16384,56)&&k.KCM(2,t,"⁷/",2)) {r=m=1;k.KO(2,t,"⅞");}else if(k.KKM(e,16384,57)&&k.KCM(1,t,"\\",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"⁹");}else if(k.KKM(e,16400,186)&&k.KCM(1,t,"\\",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"¨");}else if(k.KKM(e,16400,186)&&k.KCM(1,t,":",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,":");}else if(k.KKM(e,16400,186)&&k.KIFS(31,this.s56,t)) {r=m=1;r=this.g1(t,e);}else if(k.KKM(e,16400,186)&&k.KIFS(31,this.s57,t)) {r=m=1;r=this.g1(t,e);}else if(k.KKM(e,16400,186)) {r=m=1;k.KO(0,t,":");k.KDO(-1,t,0);}else if(k.KKM(e,16400,188)&&k.KCM(1,t,"<",1)&&k.KDM(0,t,1)) {r=m=1;k.KO(1,t,"<<");k.KDO(-1,t,1);}else if(k.KKM(e,16400,188)&&k.KCM(1,t,"<",1)) {r=m=1;k.KO(1,t,"«");}else if(k.KKM(e,16400,188)&&k.KCM(1,t,"«",1)) {r=m=1;k.KO(1,t,"<<");k.KDO(-1,t,1);}else if(k.KKM(e,16384,187)&&k.KCM(1,t,"=",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"=");}else if(k.KKM(e,16384,187)&&k.KIFS(31,this.s56,t)) {r=m=1;r=this.g1(t,e);}else if(k.KKM(e,16384,187)&&k.KIFS(31,this.s57,t)) {r=m=1;r=this.g1(t,e);}else if(k.KKM(e,16384,187)) {r=m=1;k.KO(0,t,"=");k.KDO(-1,t,0);}else if(k.KKM(e,16400,190)&&k.KCM(1,t,"\\",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"•");}else if(k.KKM(e,16400,190)&&k.KCM(1,t,">",1)&&k.KDM(0,t,1)) {r=m=1;k.KO(1,t,">>");k.KDO(-1,t,1);}else if(k.KKM(e,16400,190)&&k.KCM(1,t,">",1)) {r=m=1;k.KO(1,t,"»");}else if(k.KKM(e,16400,190)&&k.KCM(1,t,"»",1)) {r=m=1;k.KO(1,t,">>");k.KDO(-1,t,1);}else if(k.KKM(e,16400,191)&&k.KCM(1,t,"\\",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"¿");}else if(k.KKM(e,16400,50)&&k.KCM(1,t,"@",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"@");}else if(k.KKM(e,16400,50)&&k.KIFS(31,this.s56,t)) {r=m=1;r=this.g1(t,e);}else if(k.KKM(e,16400,50)&&k.KIFS(31,this.s57,t)) {r=m=1;r=this.g1(t,e);}else if(k.KKM(e,16400,50)) {r=m=1;k.KO(0,t,"@");k.KDO(-1,t,0);}else if(k.KKM(e,16400,65)&&k.KCM(1,t,"`",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"À");}else if(k.KKM(e,16400,65)&&k.KCM(1,t,"#",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"Ȁ");}else if(k.KKM(e,16400,65)&&k.KCM(1,t,"'",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"Á");}else if(k.KKM(e,16400,65)&&k.KCM(1,t,"^",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"Â");}else if(k.KKM(e,16400,65)&&k.KCM(1,t,"%",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"Ǎ");}else if(k.KKM(e,16400,65)&&k.KCM(1,t,"&",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"Ȃ");}else if(k.KKM(e,16400,65)&&k.KCM(1,t,"*",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"Ă");}else if(k.KKM(e,16400,65)&&k.KCM(1,t,"~",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"Ã");}else if(k.KKM(e,16400,65)&&k.KCM(1,t,"-",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"Ā");}else if(k.KKM(e,16400,65)&&k.KCM(1,t,":",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"Ä");}else if(k.KKM(e,16400,65)&&k.KCM(1,t,"@",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"Å");}else if(k.KKM(e,16400,65)&&k.KCM(1,t,".",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"Ȧ");}else if(k.KKM(e,16400,65)&&k.KCM(1,t,"|",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"Ạ");}else if(k.KKM(e,16400,65)&&k.KCM(1,t,",",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"Ą");}else if(k.KKM(e,16400,66)&&k.KCM(1,t,"-",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"Ƀ");}else if(k.KKM(e,16400,66)&&k.KCM(1,t,"_",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"Ḇ");}else if(k.KKM(e,16400,66)&&k.KCM(1,t,".",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"Ḃ");}else if(k.KKM(e,16400,66)&&k.KCM(1,t,"|",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"Ḅ");}else if(k.KKM(e,16400,67)&&k.KCM(1,t,"'",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"Ć");}else if(k.KKM(e,16400,67)&&k.KCM(1,t,"^",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"Ĉ");}else if(k.KKM(e,16400,67)&&k.KCM(1,t,"%",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"Č");}else if(k.KKM(e,16400,67)&&k.KCM(1,t,".",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"Ċ");}else if(k.KKM(e,16400,67)&&k.KCM(1,t,",",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"Ç");}else if(k.KKM(e,16400,67)&&k.KCM(1,t,"=",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"Ɔ");}else if(k.KKM(e,16400,67)&&k.KCM(1,t,"$",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"¤");}else if(k.KKM(e,16400,68)&&k.KCM(1,t,"%",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"Ď");}else if(k.KKM(e,16400,68)&&k.KCM(1,t,"-",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"Đ");}else if(k.KKM(e,16400,68)&&k.KCM(1,t,"_",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"Ḏ");}else if(k.KKM(e,16400,68)&&k.KCM(1,t,".",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"Ḋ");}else if(k.KKM(e,16400,68)&&k.KCM(1,t,"|",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"Ḍ");}else if(k.KKM(e,16400,68)&&k.KCM(1,t,",",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"Ḑ");}else if(k.KKM(e,16400,68)&&k.KCM(1,t,"\\",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"Ð");}else if(k.KKM(e,16400,68)&&k.KCM(1,t,"$",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"₯");}else if(k.KKM(e,16400,69)&&k.KCM(2,t,"A\\",2)&&k.KDM(0,t,0)) {r=m=1;k.KO(2,t,"Æ");}else if(k.KKM(e,16400,69)&&k.KCM(2,t,"O\\",2)&&k.KDM(0,t,0)) {r=m=1;k.KO(2,t,"Œ");}else if(k.KKM(e,16400,69)&&k.KCM(1,t,"`",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"È");}else if(k.KKM(e,16400,69)&&k.KCM(1,t,"#",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"Ȅ");}else if(k.KKM(e,16400,69)&&k.KCM(1,t,"'",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"É");}else if(k.KKM(e,16400,69)&&k.KCM(1,t,"^",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"Ê");}else if(k.KKM(e,16400,69)&&k.KCM(1,t,"%",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"Ě");}else if(k.KKM(e,16400,69)&&k.KCM(1,t,"&",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"Ȇ");}else if(k.KKM(e,16400,69)&&k.KCM(1,t,"*",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"Ĕ");}else if(k.KKM(e,16400,69)&&k.KCM(1,t,"~",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"Ẽ");}else if(k.KKM(e,16400,69)&&k.KCM(1,t,"-",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"Ē");}else if(k.KKM(e,16400,69)&&k.KCM(1,t,":",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"Ë");}else if(k.KKM(e,16400,69)&&k.KCM(1,t,".",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"Ė");}else if(k.KKM(e,16400,69)&&k.KCM(1,t,"|",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"Ẹ");}else if(k.KKM(e,16400,69)&&k.KCM(1,t,",",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"Ę");}else if(k.KKM(e,16400,69)&&k.KCM(1,t,"=",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"Ə");}else if(k.KKM(e,16400,69)&&k.KCM(1,t,"\\",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"Ɛ");}else if(k.KKM(e,16400,69)&&k.KCM(1,t,"$",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"€");}else if(k.KKM(e,16400,70)&&k.KCM(1,t,".",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"Ḟ");}else if(k.KKM(e,16400,70)&&k.KCM(1,t,"$",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"₣");}else if(k.KKM(e,16400,71)&&k.KCM(2,t,"N\\",2)&&k.KDM(0,t,0)) {r=m=1;k.KO(2,t,"Ŋ");}else if(k.KKM(e,16400,71)&&k.KCM(1,t,"~",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"G̃");}else if(k.KKM(e,16400,71)&&k.KCM(1,t,"'",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"Ǵ");}else if(k.KKM(e,16400,71)&&k.KCM(1,t,"^",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"Ĝ");}else if(k.KKM(e,16400,71)&&k.KCM(1,t,"%",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"Ǧ");}else if(k.KKM(e,16400,71)&&k.KCM(1,t,"*",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"Ğ");}else if(k.KKM(e,16400,71)&&k.KCM(1,t,"-",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"Ḡ");}else if(k.KKM(e,16400,71)&&k.KCM(1,t,".",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"Ġ");}else if(k.KKM(e,16400,71)&&k.KCM(1,t,",",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"Ģ");}else if(k.KKM(e,16400,71)&&k.KCM(1,t,"=",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"Ɂ");}else if(k.KKM(e,16400,71)&&k.KCM(1,t,"\\",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"Ǥ");}else if(k.KKM(e,16400,71)&&k.KCM(1,t,"$",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"₲");}else if(k.KKM(e,16400,72)&&k.KCM(2,t,"T\\",2)&&k.KDM(0,t,0)) {r=m=1;k.KO(2,t,"Þ");}else if(k.KKM(e,16400,72)&&k.KCM(1,t,"^",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"Ĥ");}else if(k.KKM(e,16400,72)&&k.KCM(1,t,"%",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"Ȟ");}else if(k.KKM(e,16400,72)&&k.KCM(1,t,"*",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"Ḫ");}else if(k.KKM(e,16400,72)&&k.KCM(1,t,"-",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"Ħ");}else if(k.KKM(e,16400,72)&&k.KCM(1,t,":",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"Ḧ");}else if(k.KKM(e,16400,72)&&k.KCM(1,t,".",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"Ḣ");}else if(k.KKM(e,16400,72)&&k.KCM(1,t,"|",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"Ḥ");}else if(k.KKM(e,16400,72)&&k.KCM(1,t,",",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"Ḩ");}else if(k.KKM(e,16400,73)&&k.KCM(2,t,"O\\",2)&&k.KDM(0,t,0)) {r=m=1;k.KO(2,t,"Ƣ");}else if(k.KKM(e,16400,73)&&k.KCM(1,t,"`",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"Ì");}else if(k.KKM(e,16400,73)&&k.KCM(1,t,"#",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"Ȉ");}else if(k.KKM(e,16400,73)&&k.KCM(1,t,"'",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"Í");}else if(k.KKM(e,16400,73)&&k.KCM(1,t,"^",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"Î");}else if(k.KKM(e,16400,73)&&k.KCM(1,t,"%",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"Ǐ");}else if(k.KKM(e,16400,73)&&k.KCM(1,t,"&",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"Ȋ");}else if(k.KKM(e,16400,73)&&k.KCM(1,t,"*",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"Ĭ");}else if(k.KKM(e,16400,73)&&k.KCM(1,t,"~",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"Ĩ");}else if(k.KKM(e,16400,73)&&k.KCM(1,t,"-",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"Ī");}else if(k.KKM(e,16400,73)&&k.KCM(1,t,":",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"Ï");}else if(k.KKM(e,16400,73)&&k.KCM(1,t,".",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"İ");}else if(k.KKM(e,16400,73)&&k.KCM(1,t,"|",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"Ị");}else if(k.KKM(e,16400,73)&&k.KCM(1,t,",",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"Į");}else if(k.KKM(e,16400,74)&&k.KCM(2,t,"I\\",2)&&k.KDM(0,t,0)) {r=m=1;k.KO(2,t,"IJ");}else if(k.KKM(e,16400,74)&&k.KCM(2,t,"L\\",2)&&k.KDM(0,t,0)) {r=m=1;k.KO(2,t,"LJ");}else if(k.KKM(e,16400,74)&&k.KCM(2,t,"N\\",2)&&k.KDM(0,t,0)) {r=m=1;k.KO(2,t,"NJ");}else if(k.KKM(e,16400,74)&&k.KCM(1,t,"^",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"Ĵ");}else if(k.KKM(e,16400,74)&&k.KCM(1,t,"-",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"Ɉ");}else if(k.KKM(e,16400,74)&&k.KCM(1,t,"=",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"Ɲ");}else if(k.KKM(e,16400,75)&&k.KCM(1,t,"'",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"Ḱ");}else if(k.KKM(e,16400,75)&&k.KCM(1,t,"%",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"Ǩ");}else if(k.KKM(e,16400,75)&&k.KCM(1,t,"_",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"Ḵ");}else if(k.KKM(e,16400,75)&&k.KCM(1,t,"|",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"Ḳ");}else if(k.KKM(e,16400,75)&&k.KCM(1,t,",",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"Ķ");}else if(k.KKM(e,16400,75)&&k.KCM(1,t,"$",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"₭");}else if(k.KKM(e,16400,76)&&k.KCM(1,t,"'",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"Ĺ");}else if(k.KKM(e,16400,76)&&k.KCM(1,t,"%",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"Ľ");}else if(k.KKM(e,16400,76)&&k.KCM(1,t,"~",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"Ɫ");}else if(k.KKM(e,16400,76)&&k.KCM(1,t,"-",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"Ł");}else if(k.KKM(e,16400,76)&&k.KCM(1,t,"_",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"Ḻ");}else if(k.KKM(e,16400,76)&&k.KCM(1,t,".",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"Ŀ");}else if(k.KKM(e,16400,76)&&k.KCM(1,t,"|",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"Ḷ");}else if(k.KKM(e,16400,76)&&k.KCM(1,t,",",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"Ļ");}else if(k.KKM(e,16400,77)&&k.KCM(2,t,"T\\",2)&&k.KDM(0,t,0)) {r=m=1;k.KO(2,t,"™");}else if(k.KKM(e,16400,77)&&k.KCM(1,t,"'",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"Ḿ");}else if(k.KKM(e,16400,77)&&k.KCM(1,t,".",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"Ṁ");}else if(k.KKM(e,16400,77)&&k.KCM(1,t,"|",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"Ṃ");}else if(k.KKM(e,16400,77)&&k.KCM(1,t,"\\",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"—");}else if(k.KKM(e,16400,78)&&k.KCM(1,t,"`",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"Ǹ");}else if(k.KKM(e,16400,78)&&k.KCM(1,t,"'",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"Ń");}else if(k.KKM(e,16400,78)&&k.KCM(1,t,"%",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"Ň");}else if(k.KKM(e,16400,78)&&k.KCM(1,t,"~",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"Ñ");}else if(k.KKM(e,16400,78)&&k.KCM(1,t,"_",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"Ṉ");}else if(k.KKM(e,16400,78)&&k.KCM(1,t,".",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"Ṅ");}else if(k.KKM(e,16400,78)&&k.KCM(1,t,"|",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"Ṇ");}else if(k.KKM(e,16400,78)&&k.KCM(1,t,",",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"Ņ");}else if(k.KKM(e,16400,78)&&k.KCM(1,t,"=",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"Ŋ");}else if(k.KKM(e,16400,78)&&k.KCM(1,t,"\\",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"–");}else if(k.KKM(e,16400,78)&&k.KCM(1,t,"$",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"₦");}else if(k.KKM(e,16400,79)&&k.KCM(2,t,"N\\",2)&&k.KDM(0,t,0)) {r=m=1;k.KO(2,t,"№");}else if(k.KKM(e,16400,79)&&k.KCM(1,t,"`",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"Ò");}else if(k.KKM(e,16400,79)&&k.KCM(1,t,"#",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"Ȍ");}else if(k.KKM(e,16400,79)&&k.KCM(1,t,"'",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"Ó");}else if(k.KKM(e,16400,79)&&k.KCM(1,t,"\"",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"Ő");}else if(k.KKM(e,16400,79)&&k.KCM(1,t,"^",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"Ô");}else if(k.KKM(e,16400,79)&&k.KCM(1,t,"%",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"Ǒ");}else if(k.KKM(e,16400,79)&&k.KCM(1,t,"&",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"Ȏ");}else if(k.KKM(e,16400,79)&&k.KCM(1,t,"*",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"Ŏ");}else if(k.KKM(e,16400,79)&&k.KCM(1,t,"~",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"Õ");}else if(k.KKM(e,16400,79)&&k.KCM(1,t,"-",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"Ō");}else if(k.KKM(e,16400,79)&&k.KCM(1,t,":",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"Ö");}else if(k.KKM(e,16400,79)&&k.KCM(1,t,".",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"Ȯ");}else if(k.KKM(e,16400,79)&&k.KCM(1,t,"|",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"Ọ");}else if(k.KKM(e,16400,79)&&k.KCM(1,t,",",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"Ǫ");}else if(k.KKM(e,16400,79)&&k.KCM(1,t,"=",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"Ɵ");}else if(k.KKM(e,16400,79)&&k.KCM(1,t,"\\",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"Ø");}else if(k.KKM(e,16400,80)&&k.KCM(1,t,":",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"P̈");}else if(k.KKM(e,16400,80)&&k.KCM(1,t,"'",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"Ṕ");}else if(k.KKM(e,16400,80)&&k.KCM(1,t,".",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"Ṗ");}else if(k.KKM(e,16400,80)&&k.KCM(1,t,"\\",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"¶");}else if(k.KKM(e,16400,80)&&k.KCM(1,t,"$",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"₧");}else if(k.KKM(e,16400,82)&&k.KCM(1,t,"#",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"Ȑ");}else if(k.KKM(e,16400,82)&&k.KCM(1,t,"'",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"Ŕ");}else if(k.KKM(e,16400,82)&&k.KCM(1,t,"%",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"Ř");}else if(k.KKM(e,16400,82)&&k.KCM(1,t,"&",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"Ȓ");}else if(k.KKM(e,16400,82)&&k.KCM(1,t,"-",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"Ɍ");}else if(k.KKM(e,16400,82)&&k.KCM(1,t,"_",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"Ṟ");}else if(k.KKM(e,16400,82)&&k.KCM(1,t,".",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"Ṙ");}else if(k.KKM(e,16400,82)&&k.KCM(1,t,"|",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"Ṛ");}else if(k.KKM(e,16400,82)&&k.KCM(1,t,",",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"Ŗ");}else if(k.KKM(e,16400,82)&&k.KCM(1,t,"$",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"₹");}else if(k.KKM(e,16400,83)&&k.KCM(2,t,"S\\",2)&&k.KDM(0,t,0)) {r=m=1;k.KO(2,t,"ẞ");}else if(k.KKM(e,16400,83)&&k.KCM(1,t,"'",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"Ś");}else if(k.KKM(e,16400,83)&&k.KCM(1,t,"^",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"Ŝ");}else if(k.KKM(e,16400,83)&&k.KCM(1,t,"%",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"Š");}else if(k.KKM(e,16400,83)&&k.KCM(1,t,"@",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"Ș");}else if(k.KKM(e,16400,83)&&k.KCM(1,t,".",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"Ṡ");}else if(k.KKM(e,16400,83)&&k.KCM(1,t,"|",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"Ṣ");}else if(k.KKM(e,16400,83)&&k.KCM(1,t,",",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"Ş");}else if(k.KKM(e,16400,83)&&k.KCM(1,t,"=",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"ẞ");}else if(k.KKM(e,16400,83)&&k.KCM(1,t,"\\",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"§");}else if(k.KKM(e,16400,84)&&k.KCM(1,t,"%",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"Ť");}else if(k.KKM(e,16400,84)&&k.KCM(1,t,"-",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"Ŧ");}else if(k.KKM(e,16400,84)&&k.KCM(1,t,"_",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"Ṯ");}else if(k.KKM(e,16400,84)&&k.KCM(1,t,"@",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"Ț");}else if(k.KKM(e,16400,84)&&k.KCM(1,t,".",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"Ṫ");}else if(k.KKM(e,16400,84)&&k.KCM(1,t,"|",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"Ṭ");}else if(k.KKM(e,16400,84)&&k.KCM(1,t,",",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"Ţ");}else if(k.KKM(e,16400,84)&&k.KCM(1,t,"=",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"Þ");}else if(k.KKM(e,16400,84)&&k.KCM(1,t,"\\",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"‡");}else if(k.KKM(e,16400,85)&&k.KCM(1,t,"`",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"Ù");}else if(k.KKM(e,16400,85)&&k.KCM(1,t,"#",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"Ȕ");}else if(k.KKM(e,16400,85)&&k.KCM(1,t,"'",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"Ú");}else if(k.KKM(e,16400,85)&&k.KCM(1,t,"\"",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"Ű");}else if(k.KKM(e,16400,85)&&k.KCM(1,t,"^",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"Û");}else if(k.KKM(e,16400,85)&&k.KCM(1,t,"%",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"Ǔ");}else if(k.KKM(e,16400,85)&&k.KCM(1,t,"&",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"Ȗ");}else if(k.KKM(e,16400,85)&&k.KCM(1,t,"*",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"Ŭ");}else if(k.KKM(e,16400,85)&&k.KCM(1,t,"~",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"Ũ");}else if(k.KKM(e,16400,85)&&k.KCM(1,t,"-",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"Ū");}else if(k.KKM(e,16400,85)&&k.KCM(1,t,":",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"Ü");}else if(k.KKM(e,16400,85)&&k.KCM(1,t,"@",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"Ů");}else if(k.KKM(e,16400,85)&&k.KCM(1,t,"|",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"Ụ");}else if(k.KKM(e,16400,85)&&k.KCM(1,t,",",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"Ų");}else if(k.KKM(e,16400,86)&&k.KCM(1,t,"~",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"Ṽ");}else if(k.KKM(e,16400,86)&&k.KCM(1,t,"|",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"Ṿ");}else if(k.KKM(e,16400,87)&&k.KCM(1,t,"`",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"Ẁ");}else if(k.KKM(e,16400,87)&&k.KCM(1,t,"'",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"Ẃ");}else if(k.KKM(e,16400,87)&&k.KCM(1,t,"^",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"Ŵ");}else if(k.KKM(e,16400,87)&&k.KCM(1,t,":",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"Ẅ");}else if(k.KKM(e,16400,87)&&k.KCM(1,t,".",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"Ẇ");}else if(k.KKM(e,16400,87)&&k.KCM(1,t,"|",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"Ẉ");}else if(k.KKM(e,16400,88)&&k.KCM(1,t,"%",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"Ǯ");}else if(k.KKM(e,16400,88)&&k.KCM(1,t,":",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"Ẍ");}else if(k.KKM(e,16400,88)&&k.KCM(1,t,".",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"Ẋ");}else if(k.KKM(e,16400,89)&&k.KCM(1,t,"`",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"Ỳ");}else if(k.KKM(e,16400,89)&&k.KCM(1,t,"'",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"Ý");}else if(k.KKM(e,16400,89)&&k.KCM(1,t,"^",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"Ŷ");}else if(k.KKM(e,16400,89)&&k.KCM(1,t,"~",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"Ỹ");}else if(k.KKM(e,16400,89)&&k.KCM(1,t,"-",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"Ȳ");}else if(k.KKM(e,16400,89)&&k.KCM(1,t,":",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"Ÿ");}else if(k.KKM(e,16400,89)&&k.KCM(1,t,".",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"Ẏ");}else if(k.KKM(e,16400,89)&&k.KCM(1,t,"|",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"Ỵ");}else if(k.KKM(e,16400,89)&&k.KCM(1,t,"=",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"Ȝ");}else if(k.KKM(e,16400,90)&&k.KCM(2,t,"D\\",2)&&k.KDM(0,t,0)) {r=m=1;k.KO(2,t,"DŽ");}else if(k.KKM(e,16400,90)&&k.KCM(1,t,"'",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"Ź");}else if(k.KKM(e,16400,90)&&k.KCM(1,t,"^",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"Ẑ");}else if(k.KKM(e,16400,90)&&k.KCM(1,t,"%",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"Ž");}else if(k.KKM(e,16400,90)&&k.KCM(1,t,"-",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"Ƶ");}else if(k.KKM(e,16400,90)&&k.KCM(1,t,"_",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"Ẕ");}else if(k.KKM(e,16400,90)&&k.KCM(1,t,".",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"Ż");}else if(k.KKM(e,16400,90)&&k.KCM(1,t,"|",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"Ẓ");}else if(k.KKM(e,16400,90)&&k.KCM(1,t,",",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"Ⱬ");}else if(k.KKM(e,16400,90)&&k.KCM(1,t,"=",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"Ʒ");}else if(k.KKM(e,16384,220)&&k.KCM(1,t,"\\",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"\\");}else if(k.KKM(e,16384,220)&&k.KIFS(31,this.s56,t)) {r=m=1;r=this.g1(t,e);}else if(k.KKM(e,16384,220)&&k.KIFS(31,this.s57,t)) {r=m=1;r=this.g1(t,e);}else if(k.KKM(e,16384,220)) {r=m=1;k.KO(0,t,"\\");k.KDO(-1,t,0);}else if(k.KKM(e,16400,54)&&k.KCM(1,t,"^",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"^");}else if(k.KKM(e,16400,54)&&k.KIFS(31,this.s56,t)) {r=m=1;r=this.g1(t,e);}else if(k.KKM(e,16400,54)&&k.KIFS(31,this.s57,t)) {r=m=1;r=this.g1(t,e);}else if(k.KKM(e,16400,54)) {r=m=1;k.KO(0,t,"^");k.KDO(-1,t,0);}else if(k.KKM(e,16400,189)&&k.KCM(1,t,"\\",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"¯");}else if(k.KKM(e,16400,189)&&k.KCM(1,t,"_",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"_");}else if(k.KKM(e,16400,189)&&k.KIFS(31,this.s56,t)) {r=m=1;r=this.g1(t,e);}else if(k.KKM(e,16400,189)&&k.KIFS(31,this.s57,t)) {r=m=1;r=this.g1(t,e);}else if(k.KKM(e,16400,189)) {r=m=1;k.KO(0,t,"_");k.KDO(-1,t,0);}else if(k.KKM(e,16384,192)&&k.KCM(1,t,"`",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"`");}else if(k.KKM(e,16384,192)&&k.KIFS(31,this.s56,t)) {r=m=1;r=this.g1(t,e);}else if(k.KKM(e,16384,192)&&k.KIFS(31,this.s57,t)) {r=m=1;r=this.g1(t,e);}else if(k.KKM(e,16384,192)) {r=m=1;k.KO(0,t,"`");k.KDO(-1,t,0);}else if(k.KKM(e,16384,65)&&k.KCM(1,t,"`",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"à");}else if(k.KKM(e,16384,65)&&k.KCM(1,t,"#",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"ȁ");}else if(k.KKM(e,16384,65)&&k.KCM(1,t,"'",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"á");}else if(k.KKM(e,16384,65)&&k.KCM(1,t,"^",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"â");}else if(k.KKM(e,16384,65)&&k.KCM(1,t,"%",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"ǎ");}else if(k.KKM(e,16384,65)&&k.KCM(1,t,"&",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"ȃ");}else if(k.KKM(e,16384,65)&&k.KCM(1,t,"*",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"ă");}else if(k.KKM(e,16384,65)&&k.KCM(1,t,"~",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"ã");}else if(k.KKM(e,16384,65)&&k.KCM(1,t,"-",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"ā");}else if(k.KKM(e,16384,65)&&k.KCM(1,t,":",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"ä");}else if(k.KKM(e,16384,65)&&k.KCM(1,t,"@",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"å");}else if(k.KKM(e,16384,65)&&k.KCM(1,t,".",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"ȧ");}else if(k.KKM(e,16384,65)&&k.KCM(1,t,"|",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"ạ");}else if(k.KKM(e,16384,65)&&k.KCM(1,t,",",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"ą");}else if(k.KKM(e,16384,66)&&k.KCM(1,t,"-",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"ƀ");}else if(k.KKM(e,16384,66)&&k.KCM(1,t,"_",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"ḇ");}else if(k.KKM(e,16384,66)&&k.KCM(1,t,".",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"ḃ");}else if(k.KKM(e,16384,66)&&k.KCM(1,t,"|",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"ḅ");}else if(k.KKM(e,16384,67)&&k.KCM(1,t,"'",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"ć");}else if(k.KKM(e,16384,67)&&k.KCM(1,t,"^",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"ĉ");}else if(k.KKM(e,16384,67)&&k.KCM(1,t,"%",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"č");}else if(k.KKM(e,16384,67)&&k.KCM(1,t,".",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"ċ");}else if(k.KKM(e,16384,67)&&k.KCM(1,t,",",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"ç");}else if(k.KKM(e,16384,67)&&k.KCM(1,t,"=",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"ɔ");}else if(k.KKM(e,16384,67)&&k.KCM(1,t,"\\",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"©");}else if(k.KKM(e,16384,67)&&k.KCM(1,t,"$",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"¢");}else if(k.KKM(e,16384,68)&&k.KCM(1,t,"%",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"ď");}else if(k.KKM(e,16384,68)&&k.KCM(1,t,"-",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"đ");}else if(k.KKM(e,16384,68)&&k.KCM(1,t,"_",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"ḏ");}else if(k.KKM(e,16384,68)&&k.KCM(1,t,".",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"ḋ");}else if(k.KKM(e,16384,68)&&k.KCM(1,t,"|",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"ḍ");}else if(k.KKM(e,16384,68)&&k.KCM(1,t,",",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"ḑ");}else if(k.KKM(e,16384,68)&&k.KCM(1,t,"\\",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"ð");}else if(k.KKM(e,16384,68)&&k.KCM(1,t,"$",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"₫");}else if(k.KKM(e,16384,69)&&k.KCM(2,t,"a\\",2)&&k.KDM(0,t,0)) {r=m=1;k.KO(2,t,"æ");}else if(k.KKM(e,16384,69)&&k.KCM(2,t,"o\\",2)&&k.KDM(0,t,0)) {r=m=1;k.KO(2,t,"œ");}else if(k.KKM(e,16384,69)&&k.KCM(1,t,"`",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"è");}else if(k.KKM(e,16384,69)&&k.KCM(1,t,"#",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"ȅ");}else if(k.KKM(e,16384,69)&&k.KCM(1,t,"'",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"é");}else if(k.KKM(e,16384,69)&&k.KCM(1,t,"^",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"ê");}else if(k.KKM(e,16384,69)&&k.KCM(1,t,"%",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"ě");}else if(k.KKM(e,16384,69)&&k.KCM(1,t,"&",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"ȇ");}else if(k.KKM(e,16384,69)&&k.KCM(1,t,"*",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"ĕ");}else if(k.KKM(e,16384,69)&&k.KCM(1,t,"~",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"ẽ");}else if(k.KKM(e,16384,69)&&k.KCM(1,t,"-",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"ē");}else if(k.KKM(e,16384,69)&&k.KCM(1,t,":",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"ë");}else if(k.KKM(e,16384,69)&&k.KCM(1,t,".",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"ė");}else if(k.KKM(e,16384,69)&&k.KCM(1,t,"|",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"ẹ");}else if(k.KKM(e,16384,69)&&k.KCM(1,t,",",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"ę");}else if(k.KKM(e,16384,69)&&k.KCM(1,t,"=",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"ə");}else if(k.KKM(e,16384,69)&&k.KCM(1,t,"\\",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"ɛ");}else if(k.KKM(e,16384,69)&&k.KCM(1,t,"$",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"€");}else if(k.KKM(e,16384,70)&&k.KCM(1,t,".",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"ḟ");}else if(k.KKM(e,16384,70)&&k.KCM(1,t,"\\",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"ª");}else if(k.KKM(e,16384,70)&&k.KCM(1,t,"$",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"₱");}else if(k.KKM(e,16384,71)&&k.KCM(2,t,"n\\",2)&&k.KDM(0,t,0)) {r=m=1;k.KO(2,t,"ŋ");}else if(k.KKM(e,16384,71)&&k.KCM(1,t,"~",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"g̃");}else if(k.KKM(e,16384,71)&&k.KCM(1,t,"'",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"ǵ");}else if(k.KKM(e,16384,71)&&k.KCM(1,t,"^",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"ĝ");}else if(k.KKM(e,16384,71)&&k.KCM(1,t,"%",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"ǧ");}else if(k.KKM(e,16384,71)&&k.KCM(1,t,"*",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"ğ");}else if(k.KKM(e,16384,71)&&k.KCM(1,t,"-",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"ḡ");}else if(k.KKM(e,16384,71)&&k.KCM(1,t,".",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"ġ");}else if(k.KKM(e,16384,71)&&k.KCM(1,t,",",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"ģ");}else if(k.KKM(e,16384,71)&&k.KCM(1,t,"=",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"ɂ");}else if(k.KKM(e,16384,71)&&k.KCM(1,t,"\\",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"ǥ");}else if(k.KKM(e,16384,71)&&k.KCM(1,t,"$",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"₰");}else if(k.KKM(e,16384,72)&&k.KCM(2,t,"t\\",2)&&k.KDM(0,t,0)) {r=m=1;k.KO(2,t,"þ");}else if(k.KKM(e,16384,72)&&k.KCM(1,t,"^",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"ĥ");}else if(k.KKM(e,16384,72)&&k.KCM(1,t,"%",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"ȟ");}else if(k.KKM(e,16384,72)&&k.KCM(1,t,"*",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"ḫ");}else if(k.KKM(e,16384,72)&&k.KCM(1,t,"-",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"ħ");}else if(k.KKM(e,16384,72)&&k.KCM(1,t,"_",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"ẖ");}else if(k.KKM(e,16384,72)&&k.KCM(1,t,":",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"ḧ");}else if(k.KKM(e,16384,72)&&k.KCM(1,t,".",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"ḣ");}else if(k.KKM(e,16384,72)&&k.KCM(1,t,"|",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"ḥ");}else if(k.KKM(e,16384,72)&&k.KCM(1,t,",",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"ḩ");}else if(k.KKM(e,16384,72)&&k.KCM(1,t,"$",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"₴");}else if(k.KKM(e,16384,73)&&k.KCM(2,t,"f\\",2)&&k.KDM(0,t,0)) {r=m=1;k.KO(2,t,"fi");}else if(k.KKM(e,16384,73)&&k.KCM(2,t,"o\\",2)&&k.KDM(0,t,0)) {r=m=1;k.KO(2,t,"ƣ");}else if(k.KKM(e,16384,73)&&k.KCM(1,t,"`",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"ì");}else if(k.KKM(e,16384,73)&&k.KCM(1,t,"#",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"ȉ");}else if(k.KKM(e,16384,73)&&k.KCM(1,t,"'",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"í");}else if(k.KKM(e,16384,73)&&k.KCM(1,t,"^",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"î");}else if(k.KKM(e,16384,73)&&k.KCM(1,t,"%",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"ǐ");}else if(k.KKM(e,16384,73)&&k.KCM(1,t,"&",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"ȋ");}else if(k.KKM(e,16384,73)&&k.KCM(1,t,"*",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"ĭ");}else if(k.KKM(e,16384,73)&&k.KCM(1,t,"~",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"ĩ");}else if(k.KKM(e,16384,73)&&k.KCM(1,t,"-",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"ī");}else if(k.KKM(e,16384,73)&&k.KCM(1,t,":",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"ï");}else if(k.KKM(e,16384,73)&&k.KCM(1,t,".",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"ı");}else if(k.KKM(e,16384,73)&&k.KCM(1,t,"|",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"ị");}else if(k.KKM(e,16384,73)&&k.KCM(1,t,",",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"į");}else if(k.KKM(e,16384,74)&&k.KCM(2,t,"i\\",2)&&k.KDM(0,t,0)) {r=m=1;k.KO(2,t,"ij");}else if(k.KKM(e,16384,74)&&k.KCM(2,t,"L\\",2)&&k.KDM(0,t,0)) {r=m=1;k.KO(2,t,"Lj");}else if(k.KKM(e,16384,74)&&k.KCM(2,t,"l\\",2)&&k.KDM(0,t,0)) {r=m=1;k.KO(2,t,"lj");}else if(k.KKM(e,16384,74)&&k.KCM(2,t,"N\\",2)&&k.KDM(0,t,0)) {r=m=1;k.KO(2,t,"Nj");}else if(k.KKM(e,16384,74)&&k.KCM(2,t,"n\\",2)&&k.KDM(0,t,0)) {r=m=1;k.KO(2,t,"nj");}else if(k.KKM(e,16384,74)&&k.KCM(1,t,"^",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"ĵ");}else if(k.KKM(e,16384,74)&&k.KCM(1,t,"%",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"ǰ");}else if(k.KKM(e,16384,74)&&k.KCM(1,t,"-",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"ɉ");}else if(k.KKM(e,16384,74)&&k.KCM(1,t,".",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"ȷ");}else if(k.KKM(e,16384,74)&&k.KCM(1,t,"=",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"ɲ");}else if(k.KKM(e,16384,75)&&k.KCM(1,t,"'",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"ḱ");}else if(k.KKM(e,16384,75)&&k.KCM(1,t,"%",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"ǩ");}else if(k.KKM(e,16384,75)&&k.KCM(1,t,"_",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"ḵ");}else if(k.KKM(e,16384,75)&&k.KCM(1,t,"|",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"ḳ");}else if(k.KKM(e,16384,75)&&k.KCM(1,t,",",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"ķ");}else if(k.KKM(e,16384,75)&&k.KCM(1,t,"\\",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"ĸ");}else if(k.KKM(e,16384,75)&&k.KCM(1,t,"$",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"₡");}else if(k.KKM(e,16384,76)&&k.KCM(2,t,"f\\",2)&&k.KDM(0,t,0)) {r=m=1;k.KO(2,t,"fl");}else if(k.KKM(e,16384,76)&&k.KCM(1,t,"'",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"ĺ");}else if(k.KKM(e,16384,76)&&k.KCM(1,t,"%",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"ľ");}else if(k.KKM(e,16384,76)&&k.KCM(1,t,"~",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"ɫ");}else if(k.KKM(e,16384,76)&&k.KCM(1,t,"-",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"ł");}else if(k.KKM(e,16384,76)&&k.KCM(1,t,"_",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"ḻ");}else if(k.KKM(e,16384,76)&&k.KCM(1,t,".",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"ŀ");}else if(k.KKM(e,16384,76)&&k.KCM(1,t,"|",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"ḷ");}else if(k.KKM(e,16384,76)&&k.KCM(1,t,",",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"ļ");}else if(k.KKM(e,16384,76)&&k.KCM(1,t,"$",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"₤");}else if(k.KKM(e,16384,77)&&k.KCM(2,t,"t\\",2)&&k.KDM(0,t,0)) {r=m=1;k.KO(2,t,"™");}else if(k.KKM(e,16384,77)&&k.KCM(1,t,"'",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"ḿ");}else if(k.KKM(e,16384,77)&&k.KCM(1,t,".",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"ṁ");}else if(k.KKM(e,16384,77)&&k.KCM(1,t,"|",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"ṃ");}else if(k.KKM(e,16384,77)&&k.KCM(1,t,"\\",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"º");}else if(k.KKM(e,16384,78)&&k.KCM(1,t,"`",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"ǹ");}else if(k.KKM(e,16384,78)&&k.KCM(1,t,"'",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"ń");}else if(k.KKM(e,16384,78)&&k.KCM(1,t,"%",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"ň");}else if(k.KKM(e,16384,78)&&k.KCM(1,t,"~",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"ñ");}else if(k.KKM(e,16384,78)&&k.KCM(1,t,"_",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"ṉ");}else if(k.KKM(e,16384,78)&&k.KCM(1,t,".",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"ṅ");}else if(k.KKM(e,16384,78)&&k.KCM(1,t,"|",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"ṇ");}else if(k.KKM(e,16384,78)&&k.KCM(1,t,",",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"ņ");}else if(k.KKM(e,16384,78)&&k.KCM(1,t,"=",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"ŋ");}else if(k.KKM(e,16384,78)&&k.KCM(1,t,"\\",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"ʼn");}else if(k.KKM(e,16384,78)&&k.KCM(1,t,"$",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"₪");}else if(k.KKM(e,16384,79)&&k.KCM(2,t,"n\\",2)&&k.KDM(0,t,0)) {r=m=1;k.KO(2,t,"№");}else if(k.KKM(e,16384,79)&&k.KCM(1,t,"`",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"ò");}else if(k.KKM(e,16384,79)&&k.KCM(1,t,"#",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"ȍ");}else if(k.KKM(e,16384,79)&&k.KCM(1,t,"'",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"ó");}else if(k.KKM(e,16384,79)&&k.KCM(1,t,"\"",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"ő");}else if(k.KKM(e,16384,79)&&k.KCM(1,t,"^",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"ô");}else if(k.KKM(e,16384,79)&&k.KCM(1,t,"%",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"ǒ");}else if(k.KKM(e,16384,79)&&k.KCM(1,t,"&",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"ȏ");}else if(k.KKM(e,16384,79)&&k.KCM(1,t,"*",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"ŏ");}else if(k.KKM(e,16384,79)&&k.KCM(1,t,"~",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"õ");}else if(k.KKM(e,16384,79)&&k.KCM(1,t,"-",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"ō");}else if(k.KKM(e,16384,79)&&k.KCM(1,t,":",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"ö");}else if(k.KKM(e,16384,79)&&k.KCM(1,t,".",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"ȯ");}else if(k.KKM(e,16384,79)&&k.KCM(1,t,"|",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"ọ");}else if(k.KKM(e,16384,79)&&k.KCM(1,t,",",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"ǫ");}else if(k.KKM(e,16384,79)&&k.KCM(1,t,"=",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"ɵ");}else if(k.KKM(e,16384,79)&&k.KCM(1,t,"\\",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"ø");}else if(k.KKM(e,16384,80)&&k.KCM(1,t,":",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"p̈");}else if(k.KKM(e,16384,80)&&k.KCM(1,t,"'",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"ṕ");}else if(k.KKM(e,16384,80)&&k.KCM(1,t,".",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"ṗ");}else if(k.KKM(e,16384,80)&&k.KCM(1,t,"\\",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"℗");}else if(k.KKM(e,16384,80)&&k.KCM(1,t,"$",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"£");}else if(k.KKM(e,16384,82)&&k.KCM(1,t,"#",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"ȑ");}else if(k.KKM(e,16384,82)&&k.KCM(1,t,"'",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"ŕ");}else if(k.KKM(e,16384,82)&&k.KCM(1,t,"%",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"ř");}else if(k.KKM(e,16384,82)&&k.KCM(1,t,"&",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"ȓ");}else if(k.KKM(e,16384,82)&&k.KCM(1,t,"-",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"ɍ");}else if(k.KKM(e,16384,82)&&k.KCM(1,t,"_",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"ṟ");}else if(k.KKM(e,16384,82)&&k.KCM(1,t,".",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"ṙ");}else if(k.KKM(e,16384,82)&&k.KCM(1,t,"|",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"ṛ");}else if(k.KKM(e,16384,82)&&k.KCM(1,t,",",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"ŗ");}else if(k.KKM(e,16384,82)&&k.KCM(1,t,"\\",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"®");}else if(k.KKM(e,16384,82)&&k.KCM(1,t,"$",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"₨");}else if(k.KKM(e,16384,83)&&k.KCM(2,t,"s\\",2)&&k.KDM(0,t,0)) {r=m=1;k.KO(2,t,"ß");}else if(k.KKM(e,16384,83)&&k.KCM(1,t,"'",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"ś");}else if(k.KKM(e,16384,83)&&k.KCM(1,t,"^",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"ŝ");}else if(k.KKM(e,16384,83)&&k.KCM(1,t,"%",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"š");}else if(k.KKM(e,16384,83)&&k.KCM(1,t,"@",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"ș");}else if(k.KKM(e,16384,83)&&k.KCM(1,t,".",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"ṡ");}else if(k.KKM(e,16384,83)&&k.KCM(1,t,"|",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"ṣ");}else if(k.KKM(e,16384,83)&&k.KCM(1,t,",",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"ş");}else if(k.KKM(e,16384,83)&&k.KCM(1,t,"=",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"ß");}else if(k.KKM(e,16384,83)&&k.KCM(1,t,"\\",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"ſ");}else if(k.KKM(e,16384,84)&&k.KCM(1,t,"%",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"ť");}else if(k.KKM(e,16384,84)&&k.KCM(1,t,"-",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"ŧ");}else if(k.KKM(e,16384,84)&&k.KCM(1,t,"_",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"ṯ");}else if(k.KKM(e,16384,84)&&k.KCM(1,t,":",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"ẗ");}else if(k.KKM(e,16384,84)&&k.KCM(1,t,"@",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"ț");}else if(k.KKM(e,16384,84)&&k.KCM(1,t,".",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"ṫ");}else if(k.KKM(e,16384,84)&&k.KCM(1,t,"|",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"ṭ");}else if(k.KKM(e,16384,84)&&k.KCM(1,t,",",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"ţ");}else if(k.KKM(e,16384,84)&&k.KCM(1,t,"=",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"þ");}else if(k.KKM(e,16384,84)&&k.KCM(1,t,"\\",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"†");}else if(k.KKM(e,16384,84)&&k.KCM(1,t,"$",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"₮");}else if(k.KKM(e,16384,85)&&k.KCM(1,t,"`",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"ù");}else if(k.KKM(e,16384,85)&&k.KCM(1,t,"#",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"ȕ");}else if(k.KKM(e,16384,85)&&k.KCM(1,t,"'",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"ú");}else if(k.KKM(e,16384,85)&&k.KCM(1,t,"\"",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"ű");}else if(k.KKM(e,16384,85)&&k.KCM(1,t,"^",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"û");}else if(k.KKM(e,16384,85)&&k.KCM(1,t,"%",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"ǔ");}else if(k.KKM(e,16384,85)&&k.KCM(1,t,"&",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"ȗ");}else if(k.KKM(e,16384,85)&&k.KCM(1,t,"*",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"ŭ");}else if(k.KKM(e,16384,85)&&k.KCM(1,t,"~",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"ũ");}else if(k.KKM(e,16384,85)&&k.KCM(1,t,"-",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"ū");}else if(k.KKM(e,16384,85)&&k.KCM(1,t,":",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"ü");}else if(k.KKM(e,16384,85)&&k.KCM(1,t,"@",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"ů");}else if(k.KKM(e,16384,85)&&k.KCM(1,t,"|",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"ụ");}else if(k.KKM(e,16384,85)&&k.KCM(1,t,",",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"ų");}else if(k.KKM(e,16384,85)&&k.KCM(1,t,"\\",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"µ");}else if(k.KKM(e,16384,86)&&k.KCM(1,t,"~",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"ṽ");}else if(k.KKM(e,16384,86)&&k.KCM(1,t,"|",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"ṿ");}else if(k.KKM(e,16384,87)&&k.KCM(1,t,"`",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"ẁ");}else if(k.KKM(e,16384,87)&&k.KCM(1,t,"'",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"ẃ");}else if(k.KKM(e,16384,87)&&k.KCM(1,t,"^",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"ŵ");}else if(k.KKM(e,16384,87)&&k.KCM(1,t,":",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"ẅ");}else if(k.KKM(e,16384,87)&&k.KCM(1,t,"@",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"ẘ");}else if(k.KKM(e,16384,87)&&k.KCM(1,t,".",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"ẇ");}else if(k.KKM(e,16384,87)&&k.KCM(1,t,"|",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"ẉ");}else if(k.KKM(e,16384,87)&&k.KCM(1,t,"$",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"₩");}else if(k.KKM(e,16384,88)&&k.KCM(1,t,"%",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"ǯ");}else if(k.KKM(e,16384,88)&&k.KCM(1,t,":",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"ẍ");}else if(k.KKM(e,16384,88)&&k.KCM(1,t,".",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"ẋ");}else if(k.KKM(e,16384,88)&&k.KCM(1,t,"\\",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"×");}else if(k.KKM(e,16384,89)&&k.KCM(1,t,"`",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"ỳ");}else if(k.KKM(e,16384,89)&&k.KCM(1,t,"'",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"ý");}else if(k.KKM(e,16384,89)&&k.KCM(1,t,"^",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"ŷ");}else if(k.KKM(e,16384,89)&&k.KCM(1,t,"~",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"ỹ");}else if(k.KKM(e,16384,89)&&k.KCM(1,t,"-",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"ȳ");}else if(k.KKM(e,16384,89)&&k.KCM(1,t,":",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"ÿ");}else if(k.KKM(e,16384,89)&&k.KCM(1,t,"@",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"ẙ");}else if(k.KKM(e,16384,89)&&k.KCM(1,t,".",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"ẏ");}else if(k.KKM(e,16384,89)&&k.KCM(1,t,"|",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"ỵ");}else if(k.KKM(e,16384,89)&&k.KCM(1,t,"=",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"ȝ");}else if(k.KKM(e,16384,89)&&k.KCM(1,t,"$",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"¥");}else if(k.KKM(e,16384,90)&&k.KCM(2,t,"D\\",2)&&k.KDM(0,t,0)) {r=m=1;k.KO(2,t,"Dž");}else if(k.KKM(e,16384,90)&&k.KCM(2,t,"d\\",2)&&k.KDM(0,t,0)) {r=m=1;k.KO(2,t,"dž");}else if(k.KKM(e,16384,90)&&k.KCM(1,t,"'",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"ź");}else if(k.KKM(e,16384,90)&&k.KCM(1,t,"^",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"ẑ");}else if(k.KKM(e,16384,90)&&k.KCM(1,t,"%",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"ž");}else if(k.KKM(e,16384,90)&&k.KCM(1,t,"-",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"ƶ");}else if(k.KKM(e,16384,90)&&k.KCM(1,t,"_",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"ẕ");}else if(k.KKM(e,16384,90)&&k.KCM(1,t,".",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"ż");}else if(k.KKM(e,16384,90)&&k.KCM(1,t,"|",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"ẓ");}else if(k.KKM(e,16384,90)&&k.KCM(1,t,",",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"ⱬ");}else if(k.KKM(e,16384,90)&&k.KCM(1,t,"=",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"ʒ");}else if(k.KKM(e,16400,220)&&k.KCM(1,t,"\\",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"¦");}else if(k.KKM(e,16400,220)&&k.KCM(1,t,"|",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"|");}else if(k.KKM(e,16400,220)&&k.KIFS(31,this.s56,t)) {r=m=1;r=this.g1(t,e);}else if(k.KKM(e,16400,220)&&k.KIFS(31,this.s57,t)) {r=m=1;r=this.g1(t,e);}else if(k.KKM(e,16400,220)) {r=m=1;k.KO(0,t,"|");k.KDO(-1,t,0);}else if(k.KKM(e,16400,192)&&k.KCM(1,t,"\\",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"¬");}else if(k.KKM(e,16400,192)&&k.KCM(1,t,"~",1)&&k.KDM(0,t,0)) {r=m=1;k.KO(1,t,"~");}else if(k.KKM(e,16400,192)&&k.KIFS(31,this.s56,t)) {r=m=1;r=this.g1(t,e);}else if(k.KKM(e,16400,192)&&k.KIFS(31,this.s57,t)) {r=m=1;r=this.g1(t,e);}else if(k.KKM(e,16400,192)) {r=m=1;k.KO(0,t,"~");k.KDO(-1,t,0);}return r;};this.g1=function(t,e) {var k=KeymanWeb,r=0,m=0;return r;};this.KHF=function(e) { + var h = document.getElementsByTagName('head'); + var stext = + "#keyboard_europeanlatin_help { text-align: left; padding: 0; background: #f5e3de; font-size: 8pt; font-family: Tahoma; cursor: default; padding: 4px; }"+ + "#keyboard_europeanlatin_help table { margin-top: 0; }"+ + "#keyboard_europeanlatin_help tr.out td { padding: 4px; border: solid 1px #ad4a28; font-size: 10pt; font-family: Cambria, Tahoma; font-weight: bold; text-align: center; background: white; }"+ + "#keyboard_europeanlatin_help th { padding: 2px 2px; font-size: 8pt; font-family: Tahoma; }"+ + "#keyboard_europeanlatin_help span.elkey { font-weight: normal; background: #e0e0e0; border: outset 1px; padding: 2px 6px; }"+ + "#keyboard_europeanlatin_help th.prompt { text-align: left; white-space: nowrap; }"+ + "#keyboard_europeanlatin_help tr.key th.prompt { background: white; border: none; font-weight: normal; text-align: right; }"+ + "#keyboard_europeanlatin_help tr.key th.title { background: white; border: none; font-weight: bold; vertical-align: middle; text-align: left; padding: 1px; }"+ + "#keyboard_europeanlatin_help tr.key th { min-width: 14px; margin: 2px; font-weight: normal; text-align: center; background: #e0e0e0; border: outset 1px; padding: 2px 2px; }"+ + "#keyboard_europeanlatin_help tr.out th.prompt { background: white; border: none; font-weight: normal; text-align: right; }"+ + "#keyboard_europeanlatin_help tr.gap th { background: white; border: none; height: 7px; }"+ + "#keyboard_europeanlatin_help p { font-weight: bold; }"+ + "#keyboard_eurolatin_tabsheets { color: black; border: solid 1px #ad4a28; margin: 0 4px 4px 4px; background: white; z-index: 101; }"+ + ".keyboard_eurolatin_tabsheet_selected { display: block; padding: 6px 6px 0 6px; }"+ + ".keyboard_eurolatin_tabsheet { display: none; }"+ + "#keyboard_eurolatin_tabs { margin: 4px 4px 0 4px; z-index: 100; }"+ + ".keyboard_eurolatin_tab { background: white; color: #ad4a28; border: solid 1px #ad4a28; display: inline; padding: 1px 4px 0px 4px; height: 16px; }"+ + ".keyboard_eurolatin_tab_selected { background: white; color: #ad4a28; border: solid 1px #ad4a28; display: inline; padding: 1px 4px; border-bottom: none; margin-top: -1px; height: 18px;}"; + + var style = document.createElement("style"); + style.setAttribute("type", "text/css"); + if(style.styleSheet){// IE + style.styleSheet.cssText = stext; + } else {// w3c + var cssText = document.createTextNode(stext); + style.appendChild(cssText); + } + if(h && h.length > 0) + h[0].appendChild(style); + + e=document.getElementById('keyboard_europeanlatin_help'); + if (typeof e.onselectstart!="undefined") //IE route + e.onselectstart=function(){return false;}; + else + { + e.style.MozUserSelect="none"; + e.style.KhtmlUserSelect="none"; + e.style.UserSelect="none"; + } + var ch = e.getElementsByTagName('td'); + + for(var i = 0; i < ch.length; i++) + { + if(ch[i].attributes['o']) + { + var sxv = ch[i].attributes['x'].value, so = ch[i].attributes['o'].value, sc = ch[i].attributes['c'].value; + if(ch[i].attributes['p']) var sp = ch[i].attributes['p'].value; else var sp = ''; + // ch[i].title = 'The following combinations are available: '+so; + var ce = function(tag){return document.createElement(tag);} + var sx = '', sy = '', sz = (sp == '' ? '' : sy); + var e2 = ce('div'); + for(var j = 0; j < sc.length; j++) + { + var chvo = so.charAt(j), chvc = sc.charAt(j), chvp = sp.charAt(j); + /* Special case for characters p umlaut, g tilde because they aren't precomposed */ + if(sxv == ':' && chvo == 'p') { chvo = 'p̈'; chvp = 'P̈'; } + if(sxv == '~' && chvo == 'g') { chvo = 'g̃'; chvp = 'G̃'; } + sx += ''; + sy += ''; + if(sp != '') sz += ''; + } + e2.innerHTML = sx+''+sy+''+sz+(sz == '' ? '' : '')+'
'+sxv+chvc+''+chvo+''+chvp+'
'; + + var es = e2.style; + es.background = '#f3ffdf'; + es.border = 'solid 1px #ad4a28'; + es.padding = '2px'; + es.display = 'none'; + es.position = 'absolute'; + es.left = (ch[i].offsetLeft+4)+'px'; + es.top = '24px'; + e2.onclick = function() { KeymanWeb.KT(); window.event.cancelBubble=true; return false; } + + ch[i].kmw_subitems = e2; + ch[i].appendChild(e2); + ch[i].onmouseover = function() { this.style.background = KeymanWeb_KeyHoverColor; this.kmw_subitems.style.left=this.offsetLeft+4+'px'; this.kmw_subitems.style.top=(this.offsetParent.offsetTop+this.offsetTop+this.offsetHeight-2)+'px'; this.kmw_subitems.style.display = 'block'; return false; } + ch[i].onmouseout = function() { this.style.background = ''; this.kmw_subitems.style.display = 'none'; return false; } + } + else + { + ch[i].onmouseover = function() { this.style.background = KeymanWeb_KeyHoverColor; return false; } + ch[i].onmouseout = function() { this.style.background = ''; return false; } + } + + ch[i].onclick = function(e) { with(this) { if(attributes['x']) KeymanWeb.KT(attributes['x'].value,0); else if(innerHTML != ' ') KeymanWeb.KT(innerHTML); else KeymanWeb.KT(''); } if(!e)e=window.event;if(e) e.cancelBubble=true;} + ch[i].onmousedown = function(e) { KeymanWeb.KSF(); if(!e)e=window.event;if(e) e.cancelBubble=true; } + } + + e.onclick=function() { KeymanWeb.KT(''); return false; } + e.onmousedown=function() { KeymanWeb.KSF(); return false; } + + e = document.getElementById('keyboard_eurolatin_tabs'); + e2 = document.getElementById('keyboard_eurolatin_tabsheets'); + var ch = [document.getElementById('keyboard_eurolatin_letters_tab'), document.getElementById('keyboard_eurolatin_symbols_tab')]; + var ch2 = [document.getElementById('keyboard_eurolatin_letters_tabsheet'), document.getElementById('keyboard_eurolatin_symbols_tabsheet')]; + for(var i = 0; i < ch.length; i++) + ch[i].onclick = (function(i) { return function(e) + { + for(var j = 0; j < ch.length; j++) + { + ch[j].className = "keyboard_eurolatin_tab" + (i == j ? "_selected" : ""); + ch2[j].className = "keyboard_eurolatin_tabsheet" + (i == j ? "_selected" : ""); + } + } + })(i); +} +} \ No newline at end of file diff --git a/web/docs/engine/guide/examples/js/european2_load.js b/web/docs/engine/guide/examples/js/european2_load.js new file mode 100644 index 0000000000..96ecc9a9be --- /dev/null +++ b/web/docs/engine/guide/examples/js/european2_load.js @@ -0,0 +1 @@ +KeymanWeb.KRS(new Stub_Keyboard_european2()); function Stub_Keyboard_european2() {this.KF="european2-1.6.js";this.KI="Keyboard_european2";this.KN="EuroLatin2 Keyboard";} \ No newline at end of file diff --git a/web/docs/engine/guide/examples/js/hebrew.js b/web/docs/engine/guide/examples/js/hebrew.js new file mode 100644 index 0000000000..4fc1c0287b --- /dev/null +++ b/web/docs/engine/guide/examples/js/hebrew.js @@ -0,0 +1,4 @@ +/*(C) Copyright 1994-2006 Tavultesoft Pty Ltd. All Rights Reserved. Details: keymanweb.com*/ +KeymanWeb.KR(new Keyboard_hebrew()); function Keyboard_hebrew() +{this.KI="Keyboard_hebrew";this.KN="Hebrew";this.KM=0;this.KV={F:' 1em "Arial"',K102:0,BK:new Array(";","1","2","3","4","5","6","7","8","9","0","-","=","","","","/","'","ק","ר","א","ט","ו","ן","ם","פ","]","[","\\","","","","ש","ד","ג","כ","ע","י","ח","ל","ך","ף",",","","","","","","\\","ז","ס","ב","ה","נ","מ","צ","ת","ץ",".","","","","",""," ","~","!","@","#","$","%","^","&","*",")","(","_","+","","","","Q","W","E","R","T","Y","U","I","O","P","}","{","|","","","","A","S","D","F","G","H","J","K","L",":","\"","","","","","","|","Z","X","C","V","B","N","M",">","<","?","","","","",""," ","","","","","₪","","","","","","","","","","","","","","","","","","","","","","‎","‏","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""," ","","","","‎","‏","","","","","","","ֿ","","","","","","","€","","","","װ","","","","","","","","","","","","","","","ײ","ױ","","","","","","","","","","","","","","","","","","","","","","","","","","")};this.KH='';this.KRTL=1;this.s4="hebrew.kvk";this.s5="1";this.gs=function(t,e){return this.g0(t,e);} +;this.g0=function(t,e){var k=KeymanWeb,m=0;if(k.KKM(e,16384,32)){m=1;k.KO(0,t," ");}else if(k.KKM(e,16400,32)){m=1;k.KO(0,t," ");}else if(k.KKM(e,16416,32)){m=1;k.KO(0,t," ");}else if(k.KKM(e,16384,48)){m=1;k.KO(0,t,"0");}else if(k.KKM(e,16400,48)){m=1;k.KO(0,t,"(");}else if(k.KKM(e,16384,49)){m=1;k.KO(0,t,"1");}else if(k.KKM(e,16400,49)){m=1;k.KO(0,t,"!");}else if(k.KKM(e,16384,50)){m=1;k.KO(0,t,"2");}else if(k.KKM(e,16400,50)){m=1;k.KO(0,t,"@");}else if(k.KKM(e,16384,51)){m=1;k.KO(0,t,"3");}else if(k.KKM(e,16400,51)){m=1;k.KO(0,t,"#");}else if(k.KKM(e,16432,51)){m=1;k.KO(0,t,"‎");}else if(k.KKM(e,16384,52)){m=1;k.KO(0,t,"4");}else if(k.KKM(e,16400,52)){m=1;k.KO(0,t,"$");}else if(k.KKM(e,16432,52)){m=1;k.KO(0,t,"‏");}else if(k.KKM(e,16416,52)){m=1;k.KO(0,t,"₪");}else if(k.KKM(e,16384,53)){m=1;k.KO(0,t,"5");}else if(k.KKM(e,16400,53)){m=1;k.KO(0,t,"%");}else if(k.KKM(e,16384,54)){m=1;k.KO(0,t,"6");}else if(k.KKM(e,16400,54)){m=1;k.KO(0,t,"^");}else if(k.KKM(e,16384,55)){m=1;k.KO(0,t,"7");}else if(k.KKM(e,16400,55)){m=1;k.KO(0,t,"&");}else if(k.KKM(e,16384,56)){m=1;k.KO(0,t,"8");}else if(k.KKM(e,16400,56)){m=1;k.KO(0,t,"*");}else if(k.KKM(e,16384,57)){m=1;k.KO(0,t,"9");}else if(k.KKM(e,16400,57)){m=1;k.KO(0,t,")");}else if(k.KKM(e,16384,65)){m=1;k.KO(0,t,"ש");}else if(k.KKM(e,16400,65)){m=1;k.KO(0,t,"A");}else if(k.KKM(e,16384,66)){m=1;k.KO(0,t,"נ");}else if(k.KKM(e,16400,66)){m=1;k.KO(0,t,"B");}else if(k.KKM(e,16384,67)){m=1;k.KO(0,t,"ב");}else if(k.KKM(e,16400,67)){m=1;k.KO(0,t,"C");}else if(k.KKM(e,16384,68)){m=1;k.KO(0,t,"ג");}else if(k.KKM(e,16400,68)){m=1;k.KO(0,t,"D");}else if(k.KKM(e,16384,69)){m=1;k.KO(0,t,"ק");}else if(k.KKM(e,16400,69)){m=1;k.KO(0,t,"E");}else if(k.KKM(e,16432,69)){m=1;k.KO(0,t,"€");}else if(k.KKM(e,16384,70)){m=1;k.KO(0,t,"כ");}else if(k.KKM(e,16400,70)){m=1;k.KO(0,t,"F");}else if(k.KKM(e,16384,71)){m=1;k.KO(0,t,"ע");}else if(k.KKM(e,16400,71)){m=1;k.KO(0,t,"G");}else if(k.KKM(e,16384,72)){m=1;k.KO(0,t,"י");}else if(k.KKM(e,16400,72)){m=1;k.KO(0,t,"H");}else if(k.KKM(e,16432,72)){m=1;k.KO(0,t,"ײ");}else if(k.KKM(e,16384,73)){m=1;k.KO(0,t,"ן");}else if(k.KKM(e,16400,73)){m=1;k.KO(0,t,"I");}else if(k.KKM(e,16384,74)){m=1;k.KO(0,t,"ח");}else if(k.KKM(e,16400,74)){m=1;k.KO(0,t,"J");}else if(k.KKM(e,16432,74)){m=1;k.KO(0,t,"ױ");}else if(k.KKM(e,16384,75)){m=1;k.KO(0,t,"ל");}else if(k.KKM(e,16400,75)){m=1;k.KO(0,t,"K");}else if(k.KKM(e,16384,76)){m=1;k.KO(0,t,"ך");}else if(k.KKM(e,16400,76)){m=1;k.KO(0,t,"L");}else if(k.KKM(e,16384,77)){m=1;k.KO(0,t,"צ");}else if(k.KKM(e,16400,77)){m=1;k.KO(0,t,"M");}else if(k.KKM(e,16384,78)){m=1;k.KO(0,t,"מ");}else if(k.KKM(e,16400,78)){m=1;k.KO(0,t,"N");}else if(k.KKM(e,16384,79)){m=1;k.KO(0,t,"ם");}else if(k.KKM(e,16400,79)){m=1;k.KO(0,t,"O");}else if(k.KKM(e,16384,80)){m=1;k.KO(0,t,"פ");}else if(k.KKM(e,16400,80)){m=1;k.KO(0,t,"P");}else if(k.KKM(e,16384,81)){m=1;k.KO(0,t,"/");}else if(k.KKM(e,16400,81)){m=1;k.KO(0,t,"Q");}else if(k.KKM(e,16384,82)){m=1;k.KO(0,t,"ר");}else if(k.KKM(e,16400,82)){m=1;k.KO(0,t,"R");}else if(k.KKM(e,16384,83)){m=1;k.KO(0,t,"ד");}else if(k.KKM(e,16400,83)){m=1;k.KO(0,t,"S");}else if(k.KKM(e,16384,84)){m=1;k.KO(0,t,"א");}else if(k.KKM(e,16400,84)){m=1;k.KO(0,t,"T");}else if(k.KKM(e,16384,85)){m=1;k.KO(0,t,"ו");}else if(k.KKM(e,16400,85)){m=1;k.KO(0,t,"U");}else if(k.KKM(e,16432,85)){m=1;k.KO(0,t,"װ");}else if(k.KKM(e,16384,86)){m=1;k.KO(0,t,"ה");}else if(k.KKM(e,16400,86)){m=1;k.KO(0,t,"V");}else if(k.KKM(e,16384,87)){m=1;k.KO(0,t,"'");}else if(k.KKM(e,16400,87)){m=1;k.KO(0,t,"W");}else if(k.KKM(e,16384,88)){m=1;k.KO(0,t,"ס");}else if(k.KKM(e,16400,88)){m=1;k.KO(0,t,"X");}else if(k.KKM(e,16384,89)){m=1;k.KO(0,t,"ט");}else if(k.KKM(e,16400,89)){m=1;k.KO(0,t,"Y");}else if(k.KKM(e,16384,90)){m=1;k.KO(0,t,"ז");}else if(k.KKM(e,16400,90)){m=1;k.KO(0,t,"Z");}else if(k.KKM(e,16384,106)){m=1;k.KO(0,t,"*");}else if(k.KKM(e,16400,106)){m=1;k.KO(0,t,"*");}else if(k.KKM(e,16384,107)){m=1;k.KO(0,t,"+");}else if(k.KKM(e,16400,107)){m=1;k.KO(0,t,"+");}else if(k.KKM(e,16384,109)){m=1;k.KO(0,t,"-");}else if(k.KKM(e,16400,109)){m=1;k.KO(0,t,"-");}else if(k.KKM(e,16384,186)){m=1;k.KO(0,t,"ף");}else if(k.KKM(e,16400,186)){m=1;k.KO(0,t,":");}else if(k.KKM(e,16384,187)){m=1;k.KO(0,t,"=");}else if(k.KKM(e,16400,187)){m=1;k.KO(0,t,"+");}else if(k.KKM(e,16384,188)){m=1;k.KO(0,t,"ת");}else if(k.KKM(e,16400,188)){m=1;k.KO(0,t,">");}else if(k.KKM(e,16384,189)){m=1;k.KO(0,t,"-");}else if(k.KKM(e,16400,189)){m=1;k.KO(0,t,"_");}else if(k.KKM(e,16432,189)){m=1;k.KO(0,t,"ֿ");}else if(k.KKM(e,16384,190)){m=1;k.KO(0,t,"ץ");}else if(k.KKM(e,16400,190)){m=1;k.KO(0,t,"<");}else if(k.KKM(e,16384,191)){m=1;k.KO(0,t,".");}else if(k.KKM(e,16400,191)){m=1;k.KO(0,t,"?");}else if(k.KKM(e,16384,192)){m=1;k.KO(0,t,";");}else if(k.KKM(e,16400,192)){m=1;k.KO(0,t,"~");}else if(k.KKM(e,16384,219)){m=1;k.KO(0,t,"]");}else if(k.KKM(e,16400,219)){m=1;k.KO(0,t,"}");}else if(k.KKM(e,16416,219)){m=1;k.KO(0,t,"‎");}else if(k.KKM(e,16384,220)){m=1;k.KO(0,t,"\\");}else if(k.KKM(e,16400,220)){m=1;k.KO(0,t,"|");}else if(k.KKM(e,16384,221)){m=1;k.KO(0,t,"[");}else if(k.KKM(e,16400,221)){m=1;k.KO(0,t,"{");}else if(k.KKM(e,16416,221)){m=1;k.KO(0,t,"‏");}else if(k.KKM(e,16384,222)){m=1;k.KO(0,t,",");}else if(k.KKM(e,16400,222)){m=1;k.KO(0,t,"\"");}else if(k.KKM(e,16384,226)){m=1;k.KO(0,t,"\\");}else if(k.KKM(e,16400,226)){m=1;k.KO(0,t,"|");}return m;};} diff --git a/web/docs/engine/guide/examples/js/hebrew_load.js b/web/docs/engine/guide/examples/js/hebrew_load.js new file mode 100644 index 0000000000..ebcd50e4d0 --- /dev/null +++ b/web/docs/engine/guide/examples/js/hebrew_load.js @@ -0,0 +1,2 @@ +/*(C) Copyright 1994-2006 Tavultesoft Pty Ltd. All Rights Reserved. Details: keymanweb.com*/ +KeymanWeb.KRS(new Stub_Keyboard_hebrew()); function Stub_Keyboard_hebrew() {this.KF="hebrew.js";this.KI="Keyboard_hebrew";this.KN="Hebrew";} diff --git a/web/docs/engine/guide/examples/js/kbdicon.gif b/web/docs/engine/guide/examples/js/kbdicon.gif new file mode 100644 index 0000000000..e37bec2d68 Binary files /dev/null and b/web/docs/engine/guide/examples/js/kbdicon.gif differ diff --git a/web/docs/engine/guide/examples/js/keymanweb.js b/web/docs/engine/guide/examples/js/keymanweb.js new file mode 100644 index 0000000000..cd335869e0 --- /dev/null +++ b/web/docs/engine/guide/examples/js/keymanweb.js @@ -0,0 +1,440 @@ +var $jscomp=$jscomp||{};$jscomp.scope={};$jscomp.ASSUME_ES5=!1;$jscomp.ASSUME_NO_NATIVE_MAP=!1;$jscomp.ASSUME_NO_NATIVE_SET=!1;$jscomp.defineProperty=$jscomp.ASSUME_ES5||"function"==typeof Object.defineProperties?Object.defineProperty:function(b,a,g){b!=Array.prototype&&b!=Object.prototype&&(b[a]=g.value)};$jscomp.getGlobal=function(b){return"undefined"!=typeof window&&window===b?b:"undefined"!=typeof global&&null!=global?global:b};$jscomp.global=$jscomp.getGlobal(this); +$jscomp.polyfill=function(b,a,g,k){if(a){g=$jscomp.global;b=b.split(".");for(k=0;kb&&(b=Math.max(0,e+b));if(null==k||k>e)k=e;k=Number(k);0>k&&(k=Math.max(0,e+k));for(b=Number(b||0);bc.className.indexOf("keymanweb-input")))return!0;c.nodeName.toLowerCase();if(c.ownerDocument&&c instanceof c.ownerDocument.defaultView.HTMLInputElement){var b=c.type.toLowerCase();if("text"!=b&&"search"!=b)return!0}else if(!(!d.touchable&&c.isContentEditable||c.ownerDocument&&c instanceof c.ownerDocument.defaultView.HTMLTextAreaElement))return!0; +e.states.activeElement=c;3==c.nodeType&&(c=c.parentNode);b=c;(null==c.className||0>c.className.indexOf("keymanweb-input"))&&this instanceof e&&this.scrollBody(c);c.ownerDocument&&c instanceof c.ownerDocument.defaultView.HTMLIFrameElement&&(this.keyman.domManager._AttachToIframe(c),c=c.contentWindow.document);var h=a.states.lastActiveElement;a.states.lastActiveElement=c;this.keyman.uiManager.justActivated?this._BlurKeyboardSettings():this._FocusKeyboardSettings(h?!1:!0);if(this._CommonFocusHelper(c))return!0; +c._KeymanWebSelectionStart=c._KeymanWebSelectionEnd=null;c.ownerDocument&&c instanceof c.ownerDocument.defaultView.HTMLElement&&this.keyman.domManager._SetTargDir(c);this.doControlFocused(b,a.states.lastActiveElement);d.touchable?f._Enabled=1:f.ready&&(this.keyman.keyboardManager.isCJK()&&(f._Enabled=1),f._Enabled?f._Show():f._Hide(!1));return!0}.bind(this);this._ControlBlur=function(c){c=this.keyman._GetEventObject(c);var d=this.keyman.util.eventTarget(c);if(null==d)return!0;a.states.activeElement= +null;this instanceof e&&this.hideCaret();3==d.nodeType&&(d=d.parentNode);d.ownerDocument&&(d instanceof d.ownerDocument.defaultView.HTMLIFrameElement&&(d=d.contentWindow.document),d instanceof d.ownerDocument.defaultView.HTMLInputElement||d instanceof d.ownerDocument.defaultView.HTMLTextAreaElement)&&(d._KeymanWebSelectionStart=d.value._kmwCodeUnitToCodePoint(d.selectionStart),d._KeymanWebSelectionEnd=d.value._kmwCodeUnitToCodePoint(d.selectionEnd));this._BlurKeyboardSettings();a.states.lastActiveElement= +d;this.keyman.uiManager.justActivated=!1;var f=this.keyman.uiManager.isActivating;f||this.keyman.keyboardManager.notifyKeyboard(0,d,0);this.doControlBlurred(d,c,f);this.keyman.osk.ready&&!f&&this.keyman.osk._Hide(!1);this.doChangeEvent(d);this.keyman.interface.resetContext();return!0}.bind(this);this._SelectionChange=function(){a.states._IgnoreNextSelChange&&a.states._IgnoreNextSelChange--;return!0}.bind(this);this._KeyDown=function(c){var d=this.keyman.keyboardManager.activeKeyboard,f=this.keyman.osk, +b=this.keyman.util,h=this.keyman["interface"];a.states._KeyPressToSwallow=0;if(a.states._DisableInput||null==d)return!0;var e=b.eventTarget(c);if(b.device.touchable){if(e&&"undefined"!=typeof e.kmwInput&&0==e.kmwInput)return!0}else if(e&&0<=e.className.indexOf("kmw-disabled"))return!0;if(!f.ready)return!0;e=this._GetKeyEventProperties(c,!0);if(null==e)return!0;switch(e.Lcode){case 8:h.clearDeadkeys();break;case 16:case 17:case 18:case 20:case 144:case 145:return this.keyman.keyboardManager.notifyKeyboard(e.Lcode, +e.Ltarg,1),b.device.touchable?!0:f._UpdateVKShift(e,e.Lcode-15,1)}e.LmodifierChange&&(this.keyman.keyboardManager.notifyKeyboard(0,e.Ltarg,1),f._UpdateVKShift(e,0,1));!window.event&&this.keyman.keyMapManager.browserMap.FF["k"+e.Lcode]&&(e.Lcode=this.keyman.keyMapManager.browserMap.FF["k"+e.Lcode]);if(d.KM){if(8==e.Lcode)return a.states._KeyPressToSwallow=1,h.processKeystroke(b.physicalDevice,e.Ltarg,e)||this.keyman.interface.defaultBackspace(),!1;a.states._KeyPressToSwallow=0;l=l||h.processKeystroke(b.physicalDevice, +e.Ltarg,e)}else{var l=0,g=this.keyman.keyMapManager.languageMap[f._BaseLayout];g&&g["k"+e.Lcode]&&(e.Lcode=g["k"+e.Lcode]);"undefined"!=typeof d.KM||e.Lmodifiers&96||(g={Lcode:this.keyman.keyMapManager._USKeyCodeToCharCode(e),Ltarg:e.Ltarg,Lmodifiers:0,LisVirtualKey:0},h.processKeystroke(b.physicalDevice,g.Ltarg,g)&&(l=1));l=l||h.processKeystroke(b.physicalDevice,e.Ltarg,e);8==e.Lcode&&!l&&null!=e.Ltarg.className&&0<=e.Ltarg.className.indexOf("keymanweb-input")&&this.keyman.interface.defaultBackspace()}!l&& +96<=e.Lcode&&111>=e.Lcode&&!d.KM&&(h.output(0,e.Ltarg,String._kmwFromCharCode(106>e.Lcode?e.Lcode-48:e.Lcode-64)),l=1);if(l)return c&&c.preventDefault&&(c.preventDefault(),c.stopPropagation()),a.states._KeyPressToSwallow=c?this._GetEventKeyCode(c):0,!1;a.states._KeyPressToSwallow=0;return 8==e.Lcode&&null!=e.Ltarg.className&&0<=e.Ltarg.className.indexOf("keymanweb-input")?!1:"undefined"!=typeof e.Ltarg.base&&(c=f.defaultKeyOutput("",e.Lcode,e.Lmodifiers,!1,e.Ltarg))?(h.output(0,e.Ltarg,c),!1):!0}.bind(this); +this._KeyPress=function(c){if(a.states._DisableInput||null==this.keyman.keyboardManager.activeKeyboard)return!0;var d=this._GetKeyEventProperties(c);if(null==d||d.LisVirtualKey)return!0;if(!this.keyman.keyboardManager.activeKeyboard.KM){if(!a.states._KeyPressToSwallow||32>d.Lcode||this.keyman._BrowserIsSafari&&63232d.Lcode)return!0;if(c=this.keyman._GetEventObject(c))c.returnValue=!1;return!1}if(a.states._KeyPressToSwallow||this.keyman["interface"].processKeystroke(this.keyman.util.physicalDevice, +d.Ltarg,d))return a.states._KeyPressToSwallow=0,c&&c.preventDefault&&(c.preventDefault(),c.stopPropagation()),!1;a.states._KeyPressToSwallow=0;return!0}.bind(this);this._KeyUp=function(c){var a=this.keyman.keyboardManager,f=this.keyman.osk;c=this._GetKeyEventProperties(c,!1);if(null==c||!f.ready)return!0;switch(c.Lcode){case 13:if(c.Ltarg instanceof c.Ltarg.ownerDocument.defaultView.HTMLTextAreaElement)break;if(c.Ltarg.base&&c.Ltarg.base instanceof c.Ltarg.base.ownerDocument.defaultView.HTMLTextAreaElement)break; +c.Ltarg instanceof c.Ltarg.ownerDocument.defaultView.HTMLInputElement&&(a=c.Ltarg,"search"==a.type||"submit"==a.type?a.form.submit():this.keyman.domManager.moveToNext(!1));return!0;case 16:case 17:case 18:case 20:case 144:case 145:return a.notifyKeyboard(c.Lcode,c.Ltarg,0),this.keyman.util.device.touchable?!0:f._UpdateVKShift(c,c.Lcode-15,1)}c.LmodifierChange&&(a.notifyKeyboard(0,c.Ltarg,0),f._UpdateVKShift(c,0,1));return!1}.bind(this);this.keyman=b}a.prototype.getText=function(a){return""};a.prototype.setText= +function(a,c,d){};a.prototype.getTextBeforeCaret=function(a){return""};a.prototype.setTextBeforeCaret=function(a,c){};a.prototype.getTextCaret=function(a){return 0};a.prototype.setTextCaret=function(a,c){};a.prototype.hideCaret=function(){};a.prototype.updateInput=function(a){};a.prototype.doControlFocused=function(a,c){var d={};d.target=a;d.activeControl=c;return this.keyman.util.callEvent("kmw.controlfocused",d)};a.prototype.doControlBlurred=function(a,c,d){var f={};f.target=a;f.event=c;f.isActivating= +d;return this.keyman.util.callEvent("kmw.controlblurred",f)};a.prototype._BlurKeyboardSettings=function(b,c){var d=this.keyman.keyboardManager.activeKeyboard?this.keyman.keyboardManager.activeKeyboard.KI:"",f=this.keyman.keyboardManager.getActiveLanguage();void 0!==b&&void 0!==c&&(d=b,f=c);(b=a.states.lastActiveElement)&&null!=b._kmwAttachment.keyboard?(b._kmwAttachment.keyboard=d,b._kmwAttachment.languageCode=f):(this.keyman.globalKeyboard=d,this.keyman.globalLanguageCode=f)};a.prototype._FocusKeyboardSettings= +function(b){var c=a.states.lastActiveElement;c&&null!=c._kmwAttachment.keyboard?this.keyman.keyboardManager.setActiveKeyboard(c._kmwAttachment.keyboard,c._kmwAttachment.languageCode):b||this.keyman.keyboardManager.setActiveKeyboard(this.keyman.globalKeyboard,this.keyman.globalLanguageCode)};a.prototype._CommonFocusHelper=function(b){var c=this.keyman.uiManager;if(b.ownerDocument&&b instanceof b.ownerDocument.defaultView.HTMLIFrameElement&&(!this.keyman.domManager._IsIEEditableIframe(b,1)||!this.keyman.domManager._IsMozillaEditableIframe(b, +1)))return a.states._DisableInput=!0;a.states._DisableInput=!1;c.justActivated||(this.keyman["interface"]._DeadKeys=[],this.keyman.keyboardManager.notifyKeyboard(0,b,1));c.justActivated||a.states._SelectionControl==b||(c.isActivating=!1);c.justActivated=!1;a.states._SelectionControl=b;return!1};a.prototype._GetEventKeyCode=function(a){return a.keyCode?a.keyCode:a.which?a.which:null};a.prototype._GetKeyEventProperties=function(h,c){c=new b.keyman.KeyEvent;h=this.keyman._GetEventObject(h);c.Ltarg=this.keyman.util.eventTarget(h); +if(null==c.Ltarg||!0===h.cancelBubble)return null;3==c.Ltarg.nodeType&&(c.Ltarg=c.Ltarg.parentNode);c.Lcode=this._GetEventKeyCode(h);if(null==c.Lcode)return null;var d=this.keyman.osk,f=this.keyman.keyboardManager.activeKeyboard;if(f&&f.KM&&c.Lcode!=d.keyCodes.K_SPACE){var e=d.defaultKeyOutput("K_xxxx",c.Lcode,h.getModifierState("Shift")?16:0,!1,null);e&&(c.Lcode=e.charCodeAt(0))}e=a.states.modStateFlags;var m=!1,l=!1;switch(c.Lcode){case d.keyCodes.K_CTRL:case d.keyCodes.K_LCTRL:case d.keyCodes.K_RCTRL:case d.keyCodes.K_CONTROL:case d.keyCodes.K_LCONTROL:case d.keyCodes.K_RCONTROL:m= +!0;break;case d.keyCodes.K_LMENU:case d.keyCodes.K_RMENU:case d.keyCodes.K_ALT:case d.keyCodes.K_LALT:case d.keyCodes.K_RALT:l=!0}var g=0|(h.getModifierState("Shift")?16:0);h.getModifierState("Control")&&(g|=0!=h.location&&m?1==h.location?d.modifierCodes.LCTRL:d.modifierCodes.RCTRL:e&3);h.getModifierState("Alt")&&(g|=0!=h.location&&l?1==h.location?d.modifierCodes.LALT:d.modifierCodes.RALT:e&12);c.Lstates=0;h.getModifierState("CapsLock")?c.Lstates=d.modifierCodes.CAPS:c.Lstates=d.modifierCodes.NO_CAPS; +h.getModifierState("NumLock")?c.Lstates|=d.modifierCodes.NUM_LOCK:c.Lstates|=d.modifierCodes.NO_NUM_LOCK;h.getModifierState("ScrollLock")||h.getModifierState("Scroll")?c.Lstates|=d.modifierCodes.SCROLL_LOCK:c.Lstates|=d.modifierCodes.NO_SCROLL_LOCK;g|=c.Lstates;c.LmodifierChange=a.states.modStateFlags!=g;a.states.modStateFlags=g;f&&f.KM&&h.getModifierState("CapsLock")&&(65<=c.Lcode&&90>=c.Lcode||97<=c.Lcode&&122>=c.Lcode)&&(g^=16,c.Lcode^=32);f=d.modifierCodes.RALT|d.modifierCodes.LCTRL;(e&f)==f&& +(g&f)!=f&&(g&=~f);g&d.modifierCodes.RALT&&(g&=~d.modifierCodes.LCTRL);this.keyman.keyboardManager.isChiral()?(c.Lmodifiers=g&d.modifierBitmasks.CHIRAL,d.emulatesAltGr()&&(c.Lmodifiers&d.modifierBitmasks.ALT_GR_SIM)==d.modifierBitmasks.ALT_GR_SIM&&(c.Lmodifiers^=d.modifierBitmasks.ALT_GR_SIM,c.Lmodifiers|=d.modifierCodes.RALT)):c.Lmodifiers=g&16|(g&(d.modifierCodes.LCTRL|d.modifierCodes.RCTRL)?32:0)|(g&(d.modifierCodes.LALT|d.modifierCodes.RALT)?64:0);c.LisVirtualKeyCode="undefined"!=typeof h.charCode&& +null!=h.charCode&&(0==h.charCode||0!=(c.Lmodifiers&111));c.LisVirtualKey=c.LisVirtualKeyCode||"keypress"!=h.type;return c};a.prototype.doChangeEvent=function(b){if(a.states.changed){if("function"==typeof Event)var c=new Event("change",{bubbles:!0,cancelable:!1});else c=document.createEvent("HTMLEvents"),c.initEvent("change",!0,!1);b.base&&b.base.kmw_ip&&(b=b.base);b.dispatchEvent(c)}a.states.changed=!1};a.states=new g;return a}();a.DOMEventHandlers=k;var e=function(b){function h(c){c=b.call(this, +c)||this;c.setFocus=function(c){var d=this.keyman.osk,b=this.keyman.util;k.states.setFocusTimer();if(a.Util.instanceof(c,"TouchEvent"))var h=c.touches[0];else h={clientX:0,clientY:0},h.target=k.states.lastActiveElement?k.states.lastActiveElement.kmw_ip:this.keyman.domManager.sortedInputs[0].kmw_ip;c=h.clientX;var e=h.clientY,l=h.target;var g=a.Util.instanceof(l,"HTMLSpanElement")?l.parentNode:null!=l.className&&0<=l.className.indexOf("keymanweb-input")?l.firstChild:l;h=g.parentNode;k.states.activeElement!= +h&&(this.hideCaret(),k.states.activeElement=h,h.focus());this.keyman.domManager._SetTargDir(h);d.ready&&!d._Visible&&d._Show();if(a.Util.instanceof(l,"HTMLDivElement"))e=b._GetAbsoluteX(g.firstChild),"rtl"==h.dir?(e+=g.firstChild.offsetWidth,d=c>e?0:1E5):d=cv;v++){var x=b._GetAbsoluteY(g)-t;if(x>e&&d>l&&d!=n)n=d,d=Math.round((d+l)/2);else if(xe&&d>l;)this.setTextCaret(h,--d);for(;b._GetAbsoluteY(g)-ta};for(v=0;16>v;v++){e=b._GetAbsoluteX(g);if(x(e,c)&&d>l&&d!=n)n=d,d=Math.round((d+l)/2);else if(!x(e, +c)&&dl;)this.setTextCaret(h,--d);for(;!x(b._GetAbsoluteX(g),c)&&dd.className.indexOf("keymanweb-input"))d=d.parentNode; +if(null==d.className||0>d.className.indexOf("keymanweb-input"))d=d.parentNode;if(!(null==d.className||0>d.className.indexOf("keymanweb-input"))){if(a.Util.instanceof(c,"TouchEvent")){var b=c.touches[0].screenX;var h=c.touches[0].screenY}else b=c.screenX,h=c.screenY;if("undefined"==typeof this.firstTouch||null==this.firstTouch)this.firstTouch={x:b,y:h};else{var e=this.firstTouch.x,l=this.firstTouch.y;c=d.firstChild;if("TEXTAREA"==d.base.nodeName){if(b=parseInt(c.style.top,10),isNaN(b)&&(b=0),e=l-h, +-4>e||4g||4e&&(h=e),hf&&(f=0);b=a._kmwLength();if(null=== +f||f>b)f=b;e=a._kmwSubstr(0,f);a=a._kmwSubstr(f);h.textContent=e;d.textContent=a}}this.updateBaseElement(c,b)};h.prototype.getTextBeforeCaret=function(c){return c&&1c.firstChild.childNodes.length)){var a=c.firstChild,f=this.caret.style,b=a.childNodes[1];this.caret.parentNode!=a&&a.appendChild(this.caret); +f.left=b.offsetLeft+"px";f.top=b.offsetTop+"px";f.height=b.offsetHeight-1+"px";f.visibility="hidden";this.scrollBody(c);this.setScrollBar(c)}};h.prototype.updateInput=function(c){var a=this.keyman.util,f=c.style,b=c.base,h=window.getComputedStyle(b,null),e=parseInt(h.marginLeft,10),l=parseInt(h.marginTop,10),g=a._GetAbsoluteX(b),k=a._GetAbsoluteY(b),n=c.offsetParent;n&&(g-=a._GetAbsoluteX(n),k-=a._GetAbsoluteY(n));isNaN(e)&&(e=0);isNaN(l)&&(l=0);f.left=g-e+"px";f.top=k-l+"px";"undefined"!=typeof h.MozBoxSizing&& +(f.left=g+"px",f.top=k+"px");e=b.offsetWidth;b=b.offsetHeight;l=parseInt(h.paddingLeft,10);g=parseInt(h.paddingRight,10);k=parseInt(h.paddingTop,10);n=parseInt(h.paddingBottom,10);var t=parseInt(h.borderLeft,10),z=parseInt(h.borderRight,10),x=parseInt(h.borderTop,10),B=parseInt(h.borderBottom,10),u="undefined";"undefined"!=typeof h.boxSizing?u=h.boxSizing:"undefined"!=typeof h.MozBoxSizing&&(u=h.MozBoxSizing);"content-box"==u&&(isNaN(l)||(e-=l),isNaN(g)||(e-=g),isNaN(t)||(e-=t),isNaN(z)||(e-=z),isNaN(k)|| +(b-=k),isNaN(n)||(b-=n),isNaN(x)||(b-=x),isNaN(B)||(b-=B));"Android"==a.device.OS&&("undefined"!=typeof h.MozBoxSizing?(f.paddingTop=k+1+"px",f.paddingLeft=l+"px","TEXTAREA"==c.base.nodeName?f.marginTop="1px":f.marginLeft="1px",e--,b--):(e++,b++));f.width=e+"px";f.height=b+"px"};h.prototype.updateBaseElement=function(c,a){var d=c.base.ownerDocument.defaultView;c.base instanceof d.HTMLInputElement||c.base instanceof d.HTMLTextAreaElement?c.base.value=this.getText(c):c.base.textContent=this.getText(c); +c.style.backgroundColor=0==a?"transparent":window.getComputedStyle(c.base,null).backgroundColor;"iOS"==this.keyman.util.device.OS&&(c.base.style.visibility=0==a?"visible":"hidden")};h.prototype.cancelInput=function(){k.states.activeElement=null;this.hideCaret();this.keyman.osk.hideNow()};h.prototype.setScrollBar=function(c){var a=c.childNodes[0],f=c.childNodes[1].style;(a.offsetWidth>c.offsetWidth||0>a.offsetLeft)&&"TEXTAREA"!=c.base.nodeName?(f.height="4px",f.width=c.offsetWidth/a.offsetWidth*100+ +"%",f.left=-a.offsetLeft/a.offsetWidth*100+"%",f.top="0",f.visibility="visible"):a.offsetHeight>c.offsetHeight||0>a.offsetTop?(f.width="4px",f.height=c.offsetHeight/a.offsetHeight*100+"%",f.top=-a.offsetTop/a.offsetHeight*100+"%",f.left="0",f.visibility="visible"):f.visibility="hidden"};h.prototype.scrollInput=function(a){if(a&&a.firstChild&&null!=a.className&&!(0>a.className.indexOf("keymanweb-input"))){var c=a.firstChild;if(!(3>c.childNodes.length)){var f=this.keyman.util,b=c.childNodes[1],h=f._GetAbsoluteX(b); +b=f._GetAbsoluteY(b);var e=f._GetAbsoluteX(a);f=f._GetAbsoluteY(a);var l=parseInt(c.style.left,10),g=parseInt(c.style.top,10),k=0,n=0;isNaN(l)&&(l=0);isNaN(g)&&(g=0);a.base instanceof a.base.ownerDocument.defaultView.HTMLTextAreaElement?(h=Math.round(a.offsetHeight/a.base.rows),bf+a.offsetHeight-h&&(n=b-f-a.offsetHeight+h),0!=n&&(c.style.top=(ge+a.offsetWidth-12&&(k=h-e-a.offsetWidth+12),0!=k&&(c.style.left=(la.className.indexOf("keymanweb-input"))&&c.ready){a=a.firstChild.childNodes[1];f=f._GetAbsoluteY(a);var b=window.pageYOffset;fc&&(c=0));0!=c&&window.scrollTo(0,c+window.pageYOffset)}};return h}(k);a.DOMTouchHandlers=e})(b.keyman||(b.keyman={}))})(com||(com={})); +String.kmwFromCharCode=function(b){var a=[],g;for(g=0;gk||1114111k?a.push(k):(k-=65536,a.push((k>>10)+55296),a.push(k%1024+56320))}return String.fromCharCode.apply(void 0,a)}; +String.prototype.kmwCharCodeAt=function(b){var a=String(this),g=0;if(0>b||b>=a.length)return NaN;for(var k=0;k=b&&a.length>g+1&&(a=a.charCodeAt(g+1),56320<=a&&57343>=a)?(b-55296<<10)+(a-56320)+65536:b};String.prototype.kmwIndexOf=function(b,a){var g=String(this);b=g.indexOf(b,a);if(0>b)return b;for(var k=a=0;null!==k&&kb)return b;for(var k=a=0;null!==k&&kb&&(b=g.kmwLength()+b);0>b&&(b=0);var k=g.kmwCodePointToCodeUnit(b),e=k;if(null===k)return"";if(2>arguments.length)e=g.length;else for(var h=0;ha){var k=b;b=a;a=k}b=g.kmwCodePointToCodeUnit(b);a=g.kmwCodePointToCodeUnit(a)}if(isNaN(b)||null===b)b=0;if(isNaN(a)||null===a)a=g.length;return g.substring(b,a)}; +String.prototype.kmwNextChar=function(b){var a=String(this);if(null===b||0>b||b>=a.length-1)return null;var g=a.charCodeAt(b);return 55296<=g&&56319>=g&&a.length>b+1&&(g=a.charCodeAt(b+1),56320<=g&&57343>=g)?b==a.length-2?null:b+2:b+1};String.prototype.kmwPrevChar=function(b){var a=String(this);if(null==b||0>=b||b>a.length)return null;var g=a.charCodeAt(b-1);return 56320<=g&&57343>=g&&1=a)?b-2:b-1}; +String.prototype.kmwCodePointToCodeUnit=function(b){if(null===b)return null;var a=String(this),g=0;if(0>b){g=a.length;for(var k=0;k>b;k--)g=a.kmwPrevChar(g);return g}if(b==a.kmwLength())return a.length;for(k=0;kb?a.substr(b).kmwLength():a.substr(0,b).kmwLength()};String.prototype.kmwCharAt=function(b){var a=String(this);return 0<=b?a.kmwSubstr(b,1):""}; +String.prototype.kmwBMPNextChar=function(b){var a=String(this);return 0>b||b>=a.length-1?null:b+1};String.prototype.kmwBMPPrevChar=function(b){var a=String(this);return 0>=b||b>a.length?null:b-1};String.prototype.kmwBMPCodePointToCodeUnit=function(b){return b};String.prototype.kmwBMPCodeUnitToCodePoint=function(b){return b};String.prototype.kmwBMPLength=function(){return String(this).length}; +String.prototype.kmwBMPSubstr=function(b,a){var g=String(this);return-1c-a)g.hideOnRelease=!1},this.keyman.util.attachDOMEvent(document.body,"touchstart",this.keyman.hideOskIfOnBody,!1),this.keyman.util.attachDOMEvent(document.body,"touchmove",this.keyman.cancelHideIfScrolling,!1),this.keyman.util.attachDOMEvent(document.body,"touchend",this.keyman.conditionallyHideOsk,!1)));this.keyman.keyboardManager.restoreCurrentKeyboard();MutationObserver? +(f=document.querySelector("body"),"manual"!=this.keyman.options.attachType&&(d={childList:!0,subtree:!0},this.attachmentObserver=new MutationObserver(this._AutoAttachObserverCore),this.attachmentObserver.observe(f,d)),d={subtree:!0,attributes:!0,attributeOldValue:!0,attributeFilter:["class","readonly"]},this.enablementObserver=new MutationObserver(this._EnablementMutationObserverCore),this.enablementObserver.observe(f,d)):console.warn("Your browser is outdated and does not support MutationObservers, a web feature needed by KeymanWeb to support dynamically-added elements."); +this.keyman.setInitialized(2);return Promise.resolve()}.bind(this);this.keyman=b;b.util.device.touchable&&(this.touchHandlers=new a.DOMTouchHandlers(b));this.nonTouchHandlers=new a.DOMEventHandlers(b)}b.prototype.shutdown=function(){this.enablementObserver&&this.enablementObserver.disconnect();this.attachmentObserver&&this.attachmentObserver.disconnect();for(var a=0,b=this.inputList;ab.base.rows+1&&(b.base.rows=c)),e.width=a.width,e.minHeight=a.height): +(e.minWidth=a.width,e.height=a.height);b.base.style.visibility="hidden";(function(a){a._kmwResizeHandler=function(c){window.setTimeout(function(){k.updateInput(a)},1)};a.base.addEventListener("resize",a._kmwResizeHandler,!1);a.base.addEventListener("orientationchange",a._kmwResizeHandler,!1)})(b);k.setText(b,b.base instanceof b.base.ownerDocument.defaultView.HTMLTextAreaElement||b.base instanceof b.base.ownerDocument.defaultView.HTMLInputElement?b.base.value:b.base.textContent,null);return!0};b.prototype.disableTouchElement= +function(a){if("iframe"!=a.tagName.toLowerCase()){if(a.kmw_ip){var b=this.inputList.indexOf(a.kmw_ip);-1!=b&&this.inputList.splice(b,1);a.style.visibility="visible";a.disabled=!1;a.removeEventListener("resize",a.kmw_ip._kmwResizeHandler);this.disableInputElement(a.kmw_ip);a.parentNode&&a.parentNode.removeChild(a.kmw_ip);delete a.kmw_ip}this.setupNonKMWTouchElement(a)}};b.prototype.setupNonKMWTouchElement=function(a){this.keyman.util.attachDOMEvent(a,"touchstart",this.nonKMWTouchHandler,!1);this.isAttached(a)&& +(a._kmwAttachment.touchEnabled=!1)};b.prototype.enableInputElement=function(a,b){b=b?a.base:a;this.isKMWDisabled(b)||(a instanceof a.ownerDocument.defaultView.HTMLIFrameElement?this._AttachToIframe(a):(b.className=b.className?b.className+" keymanweb-font":"keymanweb-font",this.inputList.push(a),this.keyman.util.attachDOMEvent(b,"focus",this.getHandlers(a)._ControlFocus),this.keyman.util.attachDOMEvent(b,"blur",this.getHandlers(a)._ControlBlur),a.onkeypress=this.getHandlers(a)._KeyPress,a.onkeydown= +this.getHandlers(a)._KeyDown,a.onkeyup=this.getHandlers(a)._KeyUp))};b.prototype.disableInputElement=function(a,b){var h=b?a.base:a;if(a instanceof a.ownerDocument.defaultView.HTMLIFrameElement)this._DetachFromIframe(a);else{0l[a].className.indexOf("kmw-disabled")&& +b.push({ip:l[a],x:d._GetAbsoluteX(l[a]),y:d._GetAbsoluteY(l[a])})}for(a=0;ac[a].className.indexOf("kmw-disabled")&&b.push({ip:c[a],x:d._GetAbsoluteX(c[a]),y:d._GetAbsoluteY(c[a])});b.sort(function(a,c){return a.y!=c.y?a.y-c.y:a.x-c.x});l=[];for(a=0;ab.indexOf("kmw-disabled")&&(a.className=b?b+" kmw-disabled": +"kmw-disabled")};b.prototype.setKeyboardForControl=function(a,b,l){null!==b&&void 0!==b?0>b.indexOf("Keyboard_")&&""!=b&&(b="Keyboard_"+b):l=null;if(a instanceof a.ownerDocument.defaultView.HTMLIFrameElement)console.warn("'keymanweb.setKeyboardForControl' cannot set keyboard on iframes.");else if(this.isAttached(a)){a._kmwAttachment.keyboard=b;a._kmwAttachment.languageCode=l;var c=this.getLastActiveElement();!c||c!=a&&c!=a.kmw_ip||(null!=b&&null!=l?this.keyman.keyboardManager.setActiveKeyboard(b, +l):this.keyman.keyboardManager.setActiveKeyboard(this.keyman.globalKeyboard,this.keyman.globalLanguageCode))}else console.error("KeymanWeb is not attached to element "+a)};b.prototype.getKeyboardForControl=function(a){if(this.isAttached(a))return a._kmwAttachment.keyboard;console.error("KeymanWeb is not attached to element "+a);return null};b.prototype.getLanguageForControl=function(a){if(this.isAttached(a))return a._kmwAttachment.languageCode;console.error("KeymanWeb is not attached to element "+ +a);return null};b.prototype.focusLastActiveElement=function(){var a=this.getLastActiveElement();a&&(this.keyman.uiManager.justActivated=!0,a.ownerDocument&&a instanceof a.ownerDocument.defaultView.HTMLIFrameElement&&this.keyman.domManager._IsMozillaEditableIframe(a,0)?a.ownerDocument.defaultView.focus():a.focus&&a.focus())};b.prototype.getLastActiveElement=function(){return a.DOMEventHandlers.states.lastActiveElement};b.prototype.clearLastActiveElement=function(){a.DOMEventHandlers.states.lastActiveElement= +null};b.prototype.getActiveElement=function(){return a.DOMEventHandlers.states.activeElement};b.prototype._setActiveElement=function(b){a.DOMEventHandlers.states.activeElement=b};b.prototype.setActiveElement=function(b,h){"string"==typeof b&&(b=document.getElementById(b));this.isAttached(b)||this.keyman.isEmbedded?(b=b.kmw_ip?b.kmw_ip:b,this.keyman.isEmbedded||this.keyman.touchAliasing._BlurKeyboardSettings(),a.DOMEventHandlers.states.activeElement!=b&&this.keyman.interface.resetContext(),a.DOMEventHandlers.states.activeElement= +a.DOMEventHandlers.states.lastActiveElement=b,this.keyman.isEmbedded||this.keyman.touchAliasing._FocusKeyboardSettings(!1),1=e.length?h-e.length:h;h=0>h?h+e.length:h;d?(a.DOMEventHandlers.states.focusing=!0,b=e[h].kmw_ip,"undefined"==typeof b?e[h].focus():(this.keyman.domManager.setActiveElement(b),this.touchHandlers.setTextCaret(b,1E4),this.touchHandlers.scrollInput(b),b.focus())):e[h].focus()}};b.prototype.moveToElement=function(a){"string"==typeof a&&(a=document.getElementById(a)); +this.keyman.util.device.touchable&&a.kmw_ip?a.kmw_ip.focus():a.focus()};b.prototype._IsIEEditableIframe=function(a,b){var h,c=a&&(h=a.tagName)&&"body"==h.toLowerCase()&&(h=a.ownerDocument)&&h.parentWindow;return!b&&c||b&&(!c||a.isContentEditable)};b.prototype._IsMozillaEditableIframe=function(a,b){var h;a=a&&(h=a.defaultView)&&h.frameElement;return!b&&a||b&&(!a||"on"==h.document.designMode.toLowerCase())};b.prototype.getBaseFont=function(){var a=this.keyman.util,b=document.getElementsByTagName("input"), +g=document.getElementsByTagName("textarea"),c=0;if(0==b.length&&0==g.length)c=0;else if(0f.offsetTop?c=2:d.offsetLeftf.offsetLeft&&(c=2)}switch(c){case 0:case 1:a.getStyleValue(b[0],"font-family");case 2:var q=a.getStyleValue(g[0],"font-family")}if("undefined"==typeof q||"monospace"==q)q="Arial,sans-serif";return q};b.prototype.initializeUI=function(){this.keyman.ui&& +this.keyman.ui.initialize instanceof Function?(this.keyman.ui.initialize(),this.keyman.osk._Show()):window.setTimeout(this.initializeUI.bind(this),1E3)};return b}();a.DOMManager=b})(b.keyman||(b.keyman={}))})(com||(com={})); +(function(b){(function(a){var b=function(){function a(){this.touchable=!!("ontouchstart"in window);this.OS="";this.formFactor="desktop";this.dyLandscape=this.dyPortrait=0;this.version="0";this.orientation=window.orientation;this.browser=""}a.prototype.getDPI=function(){var a=document.createElement("DIV"),b=a.style,g=96;if("complete"!==document.readyState)return g;a.id="calculateDPI";b.position="absolute";b.display="block";b.visibility="hidden";b.left="10px";b.top="10px";b.width="1in";b.height="10px"; +document.body.appendChild(a);g="undefined"==typeof window.devicePixelRatio?a.offsetWidth:a.offsetWidth*window.devicePixelRatio;document.body.removeChild(a);return g};a.prototype.detect=function(){var b=a._GetIEVersion();if(navigator&&navigator.userAgent){var h=navigator.userAgent;if(0<=h.indexOf("iPad"))this.OS="iOS",this.formFactor="tablet",this.dyPortrait=this.dyLandscape=0;else if(0<=h.indexOf("iPhone"))this.OS="iOS",this.formFactor="phone",this.dyPortrait=this.dyLandscape=25;else if(0<=h.indexOf("Android")){this.OS= +"Android";this.formFactor="phone";this.dyPortrait=75;this.dyLandscape=25;try{this.version=h.match(/(?:Android\s+)(\d+\.\d+\.\d+)/)[1]}catch(l){}}else 0<=h.indexOf("Linux")?this.OS="Linux":0<=h.indexOf("Macintosh")?this.OS="MacOSX":0<=h.indexOf("Windows NT")&&(this.OS="Windows",0<=h.indexOf("Touch")&&(this.formFactor="phone"),"number"==typeof navigator.msMaxTouchPoints&&0Math.min(screen.width,screen.height)&&(this.formFactor= +"phone");"phone"==this.formFactor&&720b)this.browser="ie";else{if("iOS"==this.OS||"macosx"==this.OS.toLowerCase())this.browser="safari";/Firefox|Chrome|OPR|Safari|Edge/.test(navigator.userAgent)&&(0<=navigator.userAgent.indexOf("Firefox")&&"onmozorientationchange"in screen?this.browser="firefox":0<=navigator.userAgent.indexOf("OPR")? +this.browser="opera":0<=navigator.userAgent.indexOf(" Edge/")?this.browser="edge":0<=navigator.userAgent.indexOf("Chrome")?this.browser="chrome":0<=navigator.userAgent.indexOf("Safari")&&(this.browser="safari"))}};a._GetIEVersion=function(){var a="";"userAgent"in navigator&&(a=navigator.userAgent);if("selection"in document){var b=navigator.appVersion;var g=b.indexOf("MSIE ");if(0<=g){if("BackCompat"==document.compatMode)return 6;b=b.substr(g+5);g=b.indexOf(".");if(0g)return 999;a=a.substr(g+8);g=a.indexOf(".");return 0document.documentElement.clientWidth)return 1;var a=screen.width;this.landscapeView()?screen.widthscreen.height&&(a=screen.height);return Math.round(100*a/window.innerWidth)/100}catch(l){return 1}};e.prototype.barHeight=function(){var a=0;"phone"==this.device.formFactor&& +(a=screen.height/2-window.innerHeight-(this.landscapeView()?this.device.dyLandscape:this.device.dyPortrait));return a};e.prototype._EncodeEntities=function(a){return a.replace("&","&").replace("<","<").replace(">",">")};e.prototype.createShim=function(){console.warn("The util.createShim function is deprecated, as its old functionality is no longer needed. It and references to its previously-produced shims may be safely removed.")};e.prototype.showShim=function(a,b,c){console.warn("The util.showShim function is deprecated, as its old functionality is no longer needed. It may be safely removed.")}; +e.prototype.hideShim=function(a){console.warn("The util.hideShim function is deprecated, as its old functionality is no longer needed. It may be safely removed.")};e.prototype.rgba=function(a,b,c,d,f){a="transparent";try{a="rgba("+b+","+c+","+d+","+f+")"}catch(q){a="rgb("+b+","+c+","+d+")"}return a};e.prototype.addStyleSheet=function(a){var b=document.createElement("style");b.type="text/css";b.appendChild(document.createTextNode(a));a=document.getElementsByTagName("HEAD");0c.indexOf("/")&& +(c=this.keyman.options.fonts+c);""!=d&&0>d.indexOf("/")&&(d=this.keyman.options.fonts+d);""!=f&&0>f.indexOf("/")&&(f=this.keyman.options.fonts+f);""!=q&&0>q.indexOf("/")&&(q=this.keyman.options.fonts+q);h="@font-face {\nfont-family:"+b.family+";\nfont-style:normal;\nfont-weight:normal;\n";if(9<=a.Device._GetIEVersion())if("iOS"==this.device.OS)if(""!=c)c=this.unCached(c),h=h+"src:url('"+c+"') format('truetype');";else return;else{f=[];"Android"==this.device.OS?(""!=q&&f.push("url('"+q+"') format('svg')"), +""!=d&&f.push("url('"+d+"') format('woff')"),""!=c&&f.push("url('"+c+"') format('truetype')")):(""!=d&&f.push("url('"+d+"') format('woff')"),""!=c&&f.push("url('"+c+"') format('truetype')"),""!=q&&f.push("url('"+q+"') format('svg')"));if(0==f.length)return;h+="src:"+f.join(",")+";"}else if(""!=f)h=h+"src:url('"+f+"');";else return;this.addStyleSheet(h+"\n}\n");this.embeddedFonts.push(b.family)}};e.prototype.unCached=function(a){return a};e.prototype.loadCookie=function(a){var b={};if(0c?(b.value=b.value._kmwSubstring(0,f)+e+b.value._kmwSubstring(d),c=0):b.value=fa&&(f.p+=c)}};c.prototype.doInputEvent=function(a){var c;"function"==typeof window.InputEvent&&(c=new window.InputEvent("input",{bubbles:!0,cancelable:!1}));a.base&&a.base.kmw_ip&& +(a=a.base);a&&c&&a.dispatchEvent(c)};c.prototype.defaultBackspace=function(a){a||(a=this.keymanweb.domManager.getLastActiveElement());this.output(1,a,"");this.doInputEvent(a)};c.prototype.processKeystroke=function(a,c,b){this.keymanweb._CachedSelectionStart=null;this._DeadkeyResetMatched();this.resetContextCache();this.keymanweb.util.activeDevice=a;(a=this.keymanweb.keyboardManager.activeKeyboard.gs(c,b))&&this.doInputEvent(c);return a};c.prototype.getLastActiveElement=function(){return this.keymanweb.domManager.getLastActiveElement()}; +c.prototype.focusLastActiveElement=function(){this.keymanweb.domManager.focusLastActiveElement()};c.prototype.hideHelp=function(){this.keymanweb.osk._Hide(!0)};c.prototype.showHelp=function(a,c){this.keymanweb.osk._Show(a,c)};c.prototype.showPinnedHelp=function(){this.keymanweb.osk.userPositioned=!0;this.keymanweb.osk._Show(-1,-1)};c.prototype.resetContext=function(){this.keymanweb.osk.layerId="default";this.clearDeadkeys();this.resetContextCache();this.resetVKShift();this.keymanweb.osk._Show()}; +c.prototype.setNumericLayer=function(){var a;for(a=0;ah||9arguments.length||!c)c="---"; +for(d=0;d=this.keyboardStubs.length)&&0!=this.keyboardStubs.length&&(a=this.keyboardStubs[0].KI,c=this.keyboardStubs[0].KLC);2"+q);var l=this;h.asyncLoader.promise=new Promise(function(a,c){window.setTimeout(function(){l.installKeyboard(a,c,h)},0)})}this.activeStub=this.keyboardStubs[f];return this.keyboardStubs[f].asyncLoader.promise}this.keymanweb.domManager._SetTargDir(this.keymanweb.domManager.getLastActiveElement())}d=this.activeKeyboard;null!==d&&String.kmwEnableSupplementaryPlane(d&&(d.KS&&1==d.KS||"Hieroglyphic"==d.KN));g._Load();return Promise.resolve()};c.prototype.installKeyboard= +function(a,c,b){var d=this.keymanweb.util,f=this.keymanweb.osk,e=d._CreateElement("script");e.charset="UTF-8";e.type="text/javascript";this.keymanweb.isEmbedded&&(e.id=b.KI);var g=b.KF,h=b.KL,q=b.KN,k=this;e.addEventListener("error",function(){null!==b.asyncLoader.timer&&(window.clearTimeout(b.asyncLoader.timer),b.asyncLoader.timer=null);b.asyncLoader.callback("Cannot find the "+q+" keyboard for "+h+".","warn");b.asyncLoader=null;c()},!1);e.addEventListener("load",function(){null!==b.asyncLoader.timer&& +(window.clearTimeout(b.asyncLoader.timer),b.asyncLoader.timer=null);var e=k.getKeyboardByID(b.KI);e?(b==k.activeStub&&(k.doBeforeKeyboardChange(e.KI,b.KLC),k.activeKeyboard=e,null!=k.keymanweb.domManager.getLastActiveElement()&&(k.keymanweb.uiManager.justActivated=!0,k.keymanweb.domManager._SetTargDir(k.keymanweb.domManager.getLastActiveElement())),String.kmwEnableSupplementaryPlane(e&&(e.KS&&1==e.KS||"Hieroglyphic"==e.KN)),k.saveCurrentKeyboard(e.KI,b.KLC),f._Load()),k.keymanweb.isEmbedded||d.wait(!1), +b.asyncLoader=null,a()):(b.asyncLoader.callback("Error registering the "+q+" keyboard for "+h+".","error"),b.asyncLoader=null,c())},!1);e.src=this.keymanweb.getKeyboardPath(g);try{document.body.appendChild(e),this.linkedScripts.push(e)}catch(z){try{document.getElementsByTagName("head")[0].appendChild(e)}catch(x){c()}}};c.prototype.saveCurrentKeyboard=function(a,c){this.keymanweb.util.saveCookie("KeymanWeb_Keyboard",{current:a+":"+c});this.keymanweb.isEmbedded||this.keymanweb.touchAliasing._BlurKeyboardSettings(a, +c)};c.prototype.restoreCurrentKeyboard=function(){var a=this.keyboardStubs,c=a.length;if(!(1>a.length)){var b=this.getSavedKeyboard();b.split(":");var e=b.split(":");2>e.length&&(e[1]="");for(b=0;bb&&(d=!1)}e&&(0arguments.length||d.LanguageCode==b)return d}return null};b.prototype.getKeyboards=function(){return this.keyboardManager.getDetailedKeyboards()};b.prototype.getSavedKeyboard=function(){return this.keyboardManager.getSavedKeyboard()};b.prototype.init=function(a){return this.domManager.init(a)};b.prototype.resetContext=function(){this.interface.resetContext()};b.prototype.setNumericLayer=function(){this.interface.setNumericLayer()};b.prototype.disableControl=function(a){this.domManager.disableControl(a)}; +b.prototype.enableControl=function(a){this.domManager.enableControl(a)};b.prototype.setKeyboardForControl=function(a,b,g){this.domManager.setKeyboardForControl(a,b,g)};b.prototype.getKeyboardForControl=function(a){this.domManager.getKeyboardForControl(a)};b.prototype.getLanguageForControl=function(a){this.domManager.getLanguageForControl(a)};b.prototype.focusLastActiveElement=function(){this.domManager.focusLastActiveElement()};b.prototype.getLastActiveElement=function(){return this.domManager.getLastActiveElement()}; +b.prototype.setActiveElement=function(a,b){return this.domManager.setActiveElement(a,b)};b.prototype.moveToElement=function(a){this.domManager.moveToElement(a)};b.prototype.addHotKey=function(a,b,g){this.hotkeyManager.addHotKey(a,b,g)};b.prototype.removeHotKey=function(a,b){this.hotkeyManager.removeHotkey(a,b)};b.prototype.getUIState=function(){return this.uiManager.getUIState()};b.prototype.activatingUI=function(a){this.uiManager.setActivatingUI(a)};return b}();a.KeymanBase=b})(b.keyman||(b.keyman= +{}))})(com||(com={}));var scripts=document.getElementsByTagName("script"),ss=scripts[scripts.length-1].src,sPath=ss.substr(0,ss.lastIndexOf("/")+1),KeymanBase=com.keyman.KeymanBase;KeymanBase._srcPath=sPath;KeymanBase._rootPath=sPath.replace(/(https?:\/\/)([^\/]*)(.*)/,"$1$2/");KeymanBase._protocol=sPath.replace(/(.{3,5}:)(.*)/,"$1");KeymanBase.__BUILD__=203; +window.keyman&&window.keyman.loaded||function(){var b=window.keyman=new KeymanBase,a=b.osk;b.ui={};a.highlightSubKeys=function(a,b,e){};a.createKeyTip=function(){};a.optionKey=function(a,b,e){};a.showKeyTip=function(a,b){};a.waitForFonts=function(a,b){return!0}}(); +window.keyman.initialized||function(){var b=window.keyman,a=b.osk,g=b.util;b.debug=b.debug=function(a){if(null==b.debugElement){var e=document.createElement("DIV");var g=e.style;g.position="absolute";g.width="30%";g.maxHeight="50%";g.top="0";g.right="0";g.minHeight="50px";g.border="1px solid blue";g.whiteSpace="pre-line";g.overflowY="scroll";g=document.createElement("P");g.id="debug_output";g.style.margin="2px";e.appendChild(g);document.body.appendChild(e);b.debugElement=g}if(null!=(g=document.getElementById("debug_output")))if(0== +arguments.length)"undefined"!=typeof g.textContent?g.textContent="":g.innerHTML="";else{e=(new Date).toTimeString().substr(3,5)+" ";var k,c;for(k=0;k"+g.innerHTML}};b.debugElement=null;b.delayedInit();a._BaseLayout="undefined"!==typeof window.KeymanWeb_BaseLayout?window.KeymanWeb_BaseLayout:"us";b._BrowserIsSafari=0<=navigator.userAgent.indexOf("AppleWebKit");g.attachDOMEvent(window,"load",b.domManager._WindowLoad,!1);g.attachDOMEvent(window,"unload",b.domManager._WindowUnload,!1);g.attachDOMEvent(document,"keyup",b.hotkeyManager._Process, +!1);g.attachDOMEvent(window,"focus",b.interface.resetVKShift.bind(b.interface),!1);g.attachDOMEvent(window,"blur",b.interface.resetVKShift.bind(b.interface),!1);String.kmwEnableSupplementaryPlane(!1)}(); +(function(b){(function(a){var b=function(){return function(a,b,g,c,d,f){this.id=a;this.text=b;this.width=g?g:"50";this.sp=c;this.nextlayer=d;this.pad=f}}();a.OSKKeySpec=b;b=function(){function a(a){this.spec=a}a.getTextWidth=function(b,e){e.fontFamily||(e.fontFamily=getComputedStyle(document.body).fontFamily);e.fontSize&&""!=e.fontSize||(e.fontSize="1em");var c=e.fontFamily,d=window.keyman.osk.getKeyEmFontSize();e=window.keyman.util.getFontSizeStyle(e.fontSize);d=e.absolute?e.val+"px":e.val*d+"px"; +e=(a.getTextWidth.canvas||(a.getTextWidth.canvas=document.createElement("canvas"))).getContext("2d");e.font=d+" "+c;return e.measureText(b).width};a.prototype.getKeyWidth=function(){var a=this.objectUnits();if("px"==a)return this.spec.widthpc;if("%"==a)return a=window.keyman.osk.getWidthFromCookie(),Math.floor(a*this.spec.widthpc/100)};a.prototype.objectUnits=function(){return"desktop"==window.keyman.util.device.formFactor?"%":"px"};a.prototype.renameSpecialKey=function(a){var b=window.keyman.osk.specialCharacters; +return b[a]?String.fromCharCode(57344+b[a]):a};a.prototype.generateKeyText=function(){var b=window.keyman.util,e=this.spec,c=b._CreateElement("span"),d=c.style;if(null==e.text||""==e.text){var f="\u00a0";"string"==typeof e.id&&/^U_[0-9A-F]{4}$/i.test(e.id)&&(f=String.fromCharCode(parseInt(e.id.substr(2),16)))}else f=e.text;c.className="kmw-key-text";if("1"==e.sp||"2"==e.sp)f=this.renameSpecialKey("*Tab*"==e.text&&"shift"==e.layer?"*TabLeft*":e.text);var g=window.keyman.osk;d.fontSize=g.fontSize;"string"== +typeof e.font&&""!=e.font&&(d.fontFamily=e.font);"string"==typeof e.fontsize&&0!=e.fontsize&&(d.fontSize=e.fontsize);e=window.keyman.keyboardManager;var m={fontSize:d.fontSize};m.fontFamily=d.fontFamily?d.fontFamily:g.fontFamily;g=a.getTextWidth(f,m);0==g&&""!=f&&"\u00a0"!=f&&(f="\u25cc"+f,e.isRTL()&&(f="\u200f"+f),g=a.getTextWidth(f,m));b=b.getFontSizeStyle(d.fontSize);g=.9*this.getKeyWidth()/g;1>g&&(d.fontSize=b.absolute?g*b.val+"px":g*b.val+"em");c.innerHTML=f;return c};return a}();a.OSKKey=b; +var k=function(a){function b(b){return a.call(this,b)||this}__extends(b,a);b.prototype.getId=function(){return this.spec.layer+"-"+this.spec.id};b.prototype.generateKeyCapLabel=function(){var a=window.keyman.osk.keyCodes[this.spec.id];switch(a){case 186:a=59;break;case 187:a=61;break;case 188:a=44;break;case 189:a=45;break;case 190:a=46;break;case 191:a=47;break;case 192:a=96;break;case 219:a=91;break;case 220:a=92;break;case 221:a=93;break;case 222:a=39;break;default:if(48>a||90?~",'{|}"']],l="K_BKQUOTE K_1 K_2 K_3 K_4 K_5 K_6 K_7 K_8 K_9 K_0 K_HYPHEN K_EQUAL K_* K_* K_* K_Q K_W K_E K_R K_T K_Y K_U K_I K_O K_P K_LBRKT K_RBRKT K_BKSLASH K_* K_* K_* K_A K_S K_D K_F K_G K_H K_J K_K K_L K_COLON K_QUOTE K_* K_* K_* K_* K_* K_oE2 K_Z K_X K_C K_V K_B K_N K_M K_COMMA K_PERIOD K_SLASH K_* K_* K_* K_* K_* K_SPACE".split(" "); +a._Box=null;a._DivVKbd=null;a._DivVKbdHelp=null;a._Visible=0;a._Enabled=1;a._VShift=[];a._VKeySpans=[];a._VKeyDown=null;a._VKbdContainer=null;a._VOriginalWidth=1;a._BaseLayout="us";a._BaseLayoutEuro={};a._BaseLayoutEuro.se="\u00a71234567890+\u00b4~~~QWERTYUIOP\u00c5\u00a8'~~~ASDFGHJKL\u00d6\u00c4~~~~~.9*screen.width&&(h=.9*screen.width);f.width=h+"px";a.width=h}"height"in c&&(b=c.height-(b.offsetHeight-e.offsetHeight), +b<.1*screen.height&&(b=.1*screen.height),b>.5*screen.height&&(b=.5*screen.height),f.height=b+"px",f.fontSize=b/8+"px",a.height=b);"nosize"in c&&a.resizeIcon&&(a.resizeIcon.style.display=c.nosize?"none":"block")}"nomove"in c&&(a.noDrag=c.nomove,a.pinImg&&(a.pinImg.style.display=c.nomove||!a.userPositioned?"none":"block"));a.saveCookie()}};a.getKeyEmFontSize=function(){if("desktop"==g.device.formFactor)return.8*a.getFontSizeFromCookie();var c=getComputedStyle(document.body).fontSize;c=g.getFontSizeStyle(c).val; +var b=g.getFontSizeStyle(a._Box).val;return c*b};a.getPos=function(){var c=a._Box;return{left:a._Visible?c.offsetLeft:a.x,top:a._Visible?c.offsetTop:a.y}};a.setPos=a.setPos=function(c){if("undefined"!=typeof a._Box&&!k.touchable){if(a.userPositioned){var b=c.left;c=c.top;"undefined"!=typeof b&&(b<-.8*a._Box.offsetWidth&&(b=-.8*a._Box.offsetWidth),a.userPositioned&&(a._Box.style.left=b+"px",a.x=b));"undefined"!=typeof c&&(0>c&&(c=0),a.userPositioned&&(a._Box.style.top=c+"px",a.y=c))}a.pinImg&&(a.pinImg.style.display= +a.userPositioned?"block":"none")}};a._VKeyGetTarget=function(a){a=b._GetEventObject(a);a=g.eventTarget(a);if(null==a)return null;3==a.nodeType&&(a=a.parentNode);"SPAN"==a.tagName&&(a=a.parentNode);return a};a.highlightKey=function(c,b){if(c&&""!=c.className&&!(0<=c.className.indexOf("kmw-key-row"))){var d=c.className;null!=a.keytip&&0>d.indexOf("kmw-key-shift")&&0>d.indexOf("kmw-spacebar")&&0>c.id.indexOf("popup")?a.showKeyTip(c,b):b&&0>d.indexOf(" kmw-key-touched")?(c.className=d+" kmw-key-touched", +a.showKeyTip(null,!1)):c.className=d.replace(" kmw-key-touched","")}};a.showSubKeys=function(c){if(null!=a.keyPending){var b=document.createElement("DIV");a.getDefaultKeyObject();b.id="kmw-popup-keys";a.popupBaseKey=c;"phone"==k.formFactor&&a.prependBaseKey(c);var f=c.id.split("-");var e=f[f.length-1];if("phone"==k.formFactor&&c.subKeys[0].id!=e){e={id:e,layer:""};1h&&(e=h);0>e&&(e=0);f.left=e+"px";a.popupCallout=a.addCallout(c);f.visibility="visible";b.shim=document.createElement("DIV");b.shim.id="kmw-popup-shim";a._Box.appendChild(b.shim);"phone"==k.formFactor&&(c=b.childNodes[0].firstChild,a.keyPending=c,a.highlightKey(c,!0))}};a.prependBaseKey=function(c){if(c&&"undefined"!=typeof c.id){var b=c.id.split("-");var f=b[b.length-1]; +b=c.key&&c.key.layer?c.key.layer:1arguments.length?null:d,e=b.keyboardManager.isChiral();"number"==typeof f&&(f=a.getLayerId(16*f));if(!f)switch(c){case "K_LSHIFT":case "K_RSHIFT":case "K_SHIFT":f="shift";break;case "K_LCONTROL":case "K_LCTRL":if(e){f="leftctrl";break}case "K_RCONTROL":case "K_RCTRL":if(e){f= +"rightctrl";break}case "K_CTRL":f="ctrl";break;case "K_LMENU":case "K_LALT":if(e){f="leftalt";break}case "K_RMENU":case "K_RALT":if(e){f="rightalt";break}case "K_ALT":f="alt";break;case "K_ALTGR":f=e?"leftctrl-rightalt":"ctrl-alt";break;case "K_CURRENCIES":case "K_NUMERALS":case "K_SHIFTED":case "K_UPPER":case "K_LOWER":case "K_SYMBOLS":f="default"}if(!f||f==a.layerId&&"desktop"!=k.formFactor)return!1;a.updateLayer(f);a._Show();return!0};a.defaultKeyOutput=function(c,d,f,g,k){var m="",q=!1,l=k&&"undefined"!= +typeof k.base;0==f?q=!0:f==a.modifierCodes.SHIFT?(q=!0,f=1):console.warn("KMW only defines default key output for the 'default' and 'shift' layers!");if(l||g)switch((l=a.keyCodes[c])||(l=d),l){case a.keyCodes.K_BKSP:e.defaultBackspace();break;case a.keyCodes.K_TAB:b.domManager.moveToNext(f);break;case a.keyCodes.K_TABBACK:b.domManager.moveToNext(!0);break;case a.keyCodes.K_TABFWD:b.domManager.moveToNext(!1);break;case a.keyCodes.K_ENTER:if("TEXTAREA"==k.nodeName||"undefined"!=typeof k.base&&"TEXTAREA"== +k.base.nodeName)return"\n";g&&("INPUT"!=k.nodeName||"search"!=k.type&&"submit"!=k.type?"undefined"==typeof k.base||"search"!=k.base.type&&"submit"!=k.base.type?b.domManager.moveToNext(!1):(k.base.disabled=!1,k.base.form.submit()):k.form.submit());break;case a.keyCodes.K_SPACE:return" "}if("U_"==c.substr(0,2))c=parseInt(c.substr(2,6),16),0<=c&&31>=c||128<=c&&159>=c?console.log("Suppressing Unicode control code: U_00"+c.toString(16)):m=String.kmwFromCharCode(c);else if(q)try{d>=a.keyCodes.K_0&&d<=a.keyCodes.K_9? +m=h[f][0][d-a.keyCodes.K_0]:d>=a.keyCodes.K_A&&d<=a.keyCodes.K_Z?m=String.fromCharCode(d+(f?0:32)):d>=a.keyCodes.K_COLON&&d<=a.keyCodes.K_BKQUOTE?m=h[f][1][d-a.keyCodes.K_COLON]:d>=a.keyCodes.K_LBRKT&&d<=a.keyCodes.K_QUOTE&&(m=h[f][2][d-a.keyCodes.K_LBRKT])}catch(v){console.error("Error detected with default mapping for key: code = "+d+", shift state = "+(1==f?"shift":"default"))}return m};a.clickKey=function(c){var d=b.domManager.getLastActiveElement(),f,h=b.keyboardManager.activeKeyboard;var m= +c.id.split("-");if(2>m.length)return!0;"popup"==m[0]&&m.splice(0,1);if(null!=d){var l=m[0],p=m[m.length-1].toUpperCase(),r=f=a.getModifierState(a.layerId);for(f=1;f=m.Lcode||97<=m.Lcode&&122>=m.Lcode)&&(m.Lmodifiers^=16,m.Lcode^=32)}"undefined"==typeof h.KM&&(m.Lcode=b.keyMapManager._USKeyCodeToCharCode(m),m.LisVirtualKey=!1);if(!h||0!=m.Lcode&&!e.processKeystroke(g.device,d,m))switch(m.Lcode=m.vkCode,p){case "K_CAPS":case "K_NUMLOCK":case "K_SCROLL":a._stateKeys[p]= +!a._stateKeys[p];a._Show();break;default:(h=a.defaultKeyOutput(p,m.Lcode,f,!0,d))&&e.output(0,d,h)}"undefined"!=typeof c.key&&null!==c.key.nextlayer&&(a.nextLayer=c.key.nextlayer);a.selectLayer(p,r);d._KeymanWebSelectionStart=null;d._KeymanWebSelectionEnd=null}b.uiManager.setActivatingUI(!1);return!0};a.getLayerId=function(b){var c="";if(0==b)return"default";b&a.modifierCodes.LCTRL&&(c=(0c.length)){var d=a.lgList=g._CreateElement("DIV");a.lgList.id="kmw-language-menu";d.shim=g._CreateElement("DIV");d.shim.id="kmw-language-menu-background";d.shim.addEventListener("touchstart",function(b){b.preventDefault();a.hideLanguageList();if(2a.spaceBar.offsetLeft&&ca.spaceBar.offsetTop&&b=l;l++){var p= +g._CreateElement("P");p.innerHTML=String.fromCharCode(l+64);e.appendChild(p)}e.addEventListener("touchstart",function(b){a.scrollToLanguage(b,f,h)},!1);e.addEventListener("touchend",function(a){a.stopPropagation();a.preventDefault()},!1);d.appendChild(e);d.addEventListener("scroll",function(b){a.lgList.scrolling=!0},!1);f.addEventListener("scroll",function(a){1>f.scrollTop&&(f.scrollTop=1);f.scrollTop>f.scrollHeight-f.offsetHeight-1&&(f.scrollTop=f.scrollHeight-f.offsetHeight-1)},!1);a.lgList.activeLgNo= +a.addLanguagesToMenu(h,c);a.lgList.visibility="hidden";document.body.appendChild(a.lgList);"Android"==k.OS&&"devicePixelRatio"in window&&(a.lgList.style.fontSize=2/window.devicePixelRatio+"em");"Android"==k.OS&&"tablet"==k.formFactor&&"devicePixelRatio"in window&&(l=parseInt(g.getStyleValue(d,"width"),10),c=d.style,isNaN(l)||(c.width=c.maxWidth=2*l/window.devicePixelRatio+"px"),l=parseInt(g.getStyleValue(f,"width"),10),c=f.style,isNaN(l)||(c.width=c.maxWidth=2*l/window.devicePixelRatio+"px"),l=parseInt(g.getStyleValue(h, +"width"),10),c=h.style,isNaN(l)||(c.width=c.maxWidth=2*l/window.devicePixelRatio+"px"));a.adjustLanguageMenu(0);c=Math.floor(d.offsetHeight/26);p=Math.round(100*c/(e.childNodes[1].offsetTop-e.childNodes[0].offsetTop))/100;var r=.6l;l++){var v=e.childNodes[l].style;2==r&&1==l%2?v.display="none":(v.fontSize=p*r+"em",v.lineHeight=c*r+"px")}l=f.offsetWidth;f.scrollHeight>f.offsetHeight+3?l+=e.offsetWidth:e.style.display="none";d.style.width=l+"px";a.lgList.visibility= +"";d=h.firstChild.offsetHeight*a.lgList.activeLgNo+1;f.scrollTop=d;f.scrollTopf.scrollHeight-f.offsetHeight-1&&(f.scrollTop=f.scrollHeight-f.offsetHeight-1)}};a.adjustLanguageMenu=function(b){var c=a.lgList,f=c.firstChild,e=f.firstChild,h=c.style;c=c.childNodes[1];var l=window.innerHeight-a.lgKey.offsetHeight-16;e=(e.childNodes.length+b-1)*e.firstChild.firstChild.offsetHeight;"iOS"==k.OS&&("phone"==k.formFactor?(b=g.landscapeView()?36:0, +l=(window.innerHeight-b-16)*g.getViewportScale()):"tablet"==k.formFactor&&(b=g.landscapeView()?16:0,l-=b));h.left=g._GetAbsoluteX(a.lgKey)+"px";e>l&&(e=l);h.height=e+"px";h.top=g._GetAbsoluteY(a._Box)+a._Box.offsetHeight-e+window.pageYOffset-6+"px";h.bottom="auto";c.style.height=f.style.height=h.height};a.scrollToLanguage=function(a,b,f){a.stopImmediatePropagation();a.stopPropagation();a.preventDefault();if("P"==a.touches[0].target.nodeName){var c,d=0;a=a.touches[0].target.innerHTML.charCodeAt(0); +var e=f.childNodes;try{for(c=0;c=a)break}}catch(r){}try{d=f.firstChild.offsetHeight*c+1,b.scrollTop=d}catch(r){d=0}try{b.scrollTopb.scrollHeight-b.offsetHeight-1&&(b.scrollTop=b.scrollHeight-b.offsetHeight-1)}catch(r){}}};a.addLanguagesToMenu=function(c,d){var f=d.length,e,h,l=[];for(h=0;h=this.className.indexOf("selected")&&(this.className+=" selected");a.lgList.scrolling=!1;a.lgList.y0=b.touches[0].pageY;return!0};f=function(b){b.stopImmediatePropagation();var c=a.lgList.childNodes[0],d=c.scrollHeight-c.offsetHeight;if("undefined"!=typeof b.pageY)var f=b.pageY;else if("undefined"!=typeof b.touches)f=b.touches[0].pageY;else return;var e=f-a.lgList.y0;if(0>e)c.scrollTop>=d-1&&(b.preventDefault(),a.lgList.y0=f);else if(0c.scrollTop&&(b.preventDefault(),a.lgList.y0=f);else return; +if(-5>e||5u&&(u=F)}u="desktop"==d?u+5:u+15;for(l=0;lparseInt(A[0].pad,10)?(w=Math.round(parseInt(A[0].width,10)*x/u),A[0].widthpc=w,D+=w,A[0].padpc=x-D):0f.id.indexOf("popup")&&f.id!=a.popupBaseKey.id)a.highlightKey(a.keyPending,!1),a.clearPopup(),a.keyPending=null}f&&f.id&&a.optionKey(b,f.id,!1);f=b.changedTouches[0].pageX; +f=2>f&&5window.innerWidth-2&&a.touchXa.keyPending.className.indexOf("hidden")&&0h.id.indexOf("BKSP")&&(a.deleting&&window.clearTimeout(a.deleting),a.deleting=0);if(a.popupVisible)null==h?(g&&a.highlightKey(g,!1),a.keyPending=null):h==a.popupBaseKey?(a.hasClass(h,"kmw-key-touched")||a.highlightKey(h,!0),a.keyPending=h):(g&&a.highlightKey(g,!1),a.keyPending=null);else{(e=document.getElementById("kmw-popup-keys"))&&"visible"==e.style.visibility&&"phone"==k.formFactor&&h==a.popupBaseKey&&(h=e.childNodes[0].firstChild);a.currentTarget=h;g&&h&&h.id!=g.id&&a.highlightKey(g, +!1);a.highlightSubKeys(h,c,f);if(e&&"visible"==e.style.visibility){if(h&&0>h.id.indexOf("popup")&&h!=a.popupBaseKey)return;h&&h==a.popupBaseKey&&0>h.className.indexOf("kmw-key-touched")&&a.highlightKey(h,!0)}else g&&b.touches[0].pageYh.className.indexOf("kmw-key-touched"))&&a.highlightKey(h,!0);g&&h&&h!=g&&""!=h.id&&a.touchHold(h)}}}; +a.hasClass=function(a,b){b=" "+b+" ";return 0<=(" "+a.className+" ").replace(/[\n\t\r\f]/g," ").indexOf(b)};a.keyTarget=function(b){try{if(b){if(a.hasClass(b,"kmw-key"))return b;if(b.parentNode&&a.hasClass(b.parentNode,"kmw-key"))return b.parentNode;if(b.firstChild&&a.hasClass(b.firstChild,"kmw-key"))return b.firstChild}}catch(d){}return null};a.findNearestKey=function(a,b){if(!a||"undefined"==typeof a.changedTouches||0==a.changedTouches.length)return null;for(a=a.changedTouches[0].pageX;b&&0>b.className.indexOf("key-row");)b= +b.parentNode;if(!b)return null;var c,d=0,e=24,g=1E5;for(c=0;cg&&(b=b.childNodes[d],h=b.offsetLeft,k=h+b.offsetWidth,40c||10r;r++){var v=r+65*e;h.push(b[v]);vC+65*A&&(u.text="`1234567890-=\u00a7~~qwertyuiop[]\\~~~asdfghjkl;'~~~~~?zxcvbnm,./~~~~~ ~!@#$%^&*()_+\u00a7~~QWERTYUIOP{}\\~~~ASDFGHJKL:\"~~~~~?ZXCVBNM<>?~~~~~ "[C+65*A]);"undefined"==typeof u.text&&(u.text="");switch(u.id){case "K_SHIFT":d=u;break;case "K_CAPS":z=u;break;case "K_NUMLOCK":B=u;break;case "K_SCROLL":F=u}if(null!=u.sk){for(C=0;C";h.style.border="1px solid #ccc";return h};a.adjustHeights=function(){if(a._Box&&a._Box.firstChild&&a._Box.firstChild.firstChild&&a._Box.firstChild.firstChild.childNodes){var b=a._Box.firstChild.firstChild.childNodes,d=b[0].childNodes.length,f=a.getHeight(),e=Math.floor(f/(0==d?1:d)),h,l,p;var r=1;"Android"==k.OS&& +"devicePixelRatio"in window&&(e/=window.devicePixelRatio);f=d*e;d=a._Box;e=d.style;e.height=e.maxHeight=f+3+"px";d=d.firstChild.firstChild;e=d.style;e.height=e.maxHeight=f+3+"px";"iOS"==k.OS&&(r/=g.getViewportScale());e.fontSize=r+"em";var v="iOS"==k.OS&&"phone"==k.formFactor&&g.landscapeView();for(r=0;r
Copyright © 2017 SIL International')};a.resizeBar=function(){var b=g._CreateElement("DIV");b.className="kmw-footer";b.onmousedown=a._CancelMouse; +var d=g._CreateElement("DIV");d.className="kmw-footer-caption";d.innerHTML='KeymanWeb';d.id="keymanweb-osk-footer-caption";g.attachDOMEvent(d,"dblclick",function(b){b&&b.shiftKey&&a.showBuild()},!1);"onselectstart"in d&&(d.onselectstart=g.selectStartHandler);b.appendChild(d);d=g._CreateElement("DIV");d.className="kmw-footer-resize";d.onmousedown=a._VResizeMouseDown;d.onmouseover=d.onmouseout=a._VResizeMouseOut;b.appendChild(d);a.resizeIcon=d;return b}; +a._VKbdMouseOver=function(a){b.uiManager.setActivatingUI(!0)};a._VKbdMouseOut=function(a){b.uiManager.setActivatingUI(!1)};a._VResizeMouseOver=a._VResizeMouseOut=function(c){c=b._GetEventObject(c);if(!c)return!1;c&&c.preventDefault&&c.preventDefault();var d=a.getRect();a.width=d.width;a.height=d.height;c.cancelBubble=!0;return!1};a._VResizeMouseDown=function(c){b.uiManager.justActivated=!0;c=b._GetEventObject(c);if(!c)return!0;a.resizing=1;if(c.pageX){var d=c.pageX;var f=c.pageY}else c.clientX&&(d= +c.clientX+document.body.scrollLeft,f=c.clientY+document.body.scrollTop);a._ResizeMouseX=d;a._ResizeMouseY=f;document.onmousemove!=a._VResizeMouseMove&&document.onmousemove!=a._VMoveMouseMove&&(a._VPreviousMouseMove=document.onmousemove,a._VPreviousMouseUp=document.onmouseup);a._VPreviousCursor=document.body.style.cursor;a._VPreviousMouseButton="undefined"==typeof c.which?c.button:c.which;a._VOriginalWidth=a._DivVKbd.offsetWidth;a._VOriginalHeight=a._DivVKbd.offsetHeight;document.onmousemove=a._VResizeMouseMove; +document.onmouseup=a._VResizeMoveMouseUp;document.body.style.cursor&&(document.body.style.cursor="se-resize");c&&c.preventDefault&&c.preventDefault();c.cancelBubble=!0;return!1};a._VResizeMouseMove=function(c){c=b._GetEventObject(c);if(!c)return!0;a.resizing=1;if(a._VPreviousMouseButton!=("undefined"==typeof c.which?c.button:c.which))return a._VResizeMoveMouseUp(c);if(c.pageX){var d=c.pageX;var f=c.pageY}else c.clientX&&(d=c.clientX+document.body.scrollLeft,f=c.clientY+document.body.scrollTop);d= +a._VOriginalWidth+d-a._ResizeMouseX;f=a._VOriginalHeight+f-a._ResizeMouseY;d<.2*screen.width&&(d=.2*screen.width);f<.1*screen.height&&(f=.1*screen.height);d>.9*screen.width&&(d=.9*screen.width);f>.5*screen.height&&(d=.5*screen.height);a._DivVKbd.style.width=d+"px";a._DivVKbd.style.height=f+"px";a._DivVKbd.style.fontSize=f/8+"px";c&&c.preventDefault&&c.preventDefault();c.cancelBubble=!0;return!1};a._VMoveMouseDown=function(c){b.uiManager.justActivated=!0;c=b._GetEventObject(c);if(!c)return!0;a.resizing= +1;if(c.pageX){var d=c.pageX;var f=c.pageY}else c.clientX&&(d=c.clientX+document.body.scrollLeft,f=c.clientY+document.body.scrollTop);document.onmousemove!=a._VResizeMouseMove&&document.onmousemove!=a._VMoveMouseMove&&(a._VPreviousMouseMove=document.onmousemove,a._VPreviousMouseUp=document.onmouseup);a._VPreviousCursor=document.body.style.cursor;a._VPreviousMouseButton="undefined"==typeof c.which?c.button:c.which;a._VMoveX=d-a._Box.offsetLeft;a._VMoveY=f-a._Box.offsetTop;b.keyboardManager.isCJK()&& +(a.pinImg.style.left="15px");document.onmousemove=a._VMoveMouseMove;document.onmouseup=a._VResizeMoveMouseUp;document.body.style.cursor&&(document.body.style.cursor="move");c&&c.preventDefault&&c.preventDefault();c.cancelBubble=!0;return!1};a._VMoveMouseMove=function(c){c=b._GetEventObject(c);if(!c||a.noDrag)return!0;a.resizing=1;a.userPositioned=!0;a.pinImg.style.display="block";if(a._VPreviousMouseButton!=("undefined"==typeof c.which?c.button:c.which))return a._VResizeMoveMouseUp(c);if(c.pageX){var d= +c.pageX;var f=c.pageY}else c.clientX&&(d=c.clientX+document.body.scrollLeft,f=c.clientY+document.body.scrollTop);a._Box.style.left=d-a._VMoveX+"px";a._Box.style.top=f-a._VMoveY+"px";c&&c.preventDefault&&c.preventDefault();d=a.getRect();a.width=d.width;a.height=d.height;c.cancelBubble=!0;return!1};a._VResizeMoveMouseUp=function(c){c=b._GetEventObject(c);if(!c)return!0;a.resizing=0;a.currentKey=null;document.onmousemove=a._VPreviousMouseMove;document.onmouseup=a._VPreviousMouseUp;document.body.style.cursor&& +(document.body.style.cursor=a._VPreviousCursor);b.domManager.focusLastActiveElement();c&&c.preventDefault&&c.preventDefault();b.uiManager.justActivated=!1;b.uiManager.setActivatingUI(!1);a._DivVKbd&&(a._VOriginalWidth=a._DivVKbd.offsetWidth,a._VOriginalHeight=a._DivVKbd.offsetHeight);a.doResizeMove();c.cancelBubble=!0;a.saveCookie();return!1};a.userLocated=function(){return a.userPositioned};a.show=function(b){0 +b||b>=c.length||c[b].aligned)&&"block"==c[b].style.display){var f=a._DivVKbd.childNodes[0].offsetWidth-6;"Windows"==k.OS&&(f-=g.landscapeView()?4:40);var e,h=c[b].childNodes;for(e=0;e?~~~~~ "}),a._GenerateVisualKeyboard(e,d,h,b.keyboardManager.getKeyboardModifierBitmask())):(a.ddOSK=!1,e=g._CreateElement("DIV"), +e.className="kmw-title-bar",e.appendChild(a._TitleBarInterior()),e.onmousedown=a._VMoveMouseDown,a._Box.appendChild(e),e=g._CreateElement("DIV"),e.className="kmw-osk-static",e.innerHTML=d,a._Box.appendChild(e),c.KHF&&c.KHF(a._Box));b._TitleElement&&(b._TitleElement.innerHTML=""+c.KN+" - "+b._TitleElement.innerHTML,b._TitleElement.className="",b._TitleElement.style.color="#fff")}else e=g._CreateElement("DIV"),e.className="kmw-title-bar",e.appendChild(a._TitleBarInterior()), +e.onmousedown=a._VMoveMouseDown,a._Box.appendChild(e),e=g._CreateElement("DIV"),e.className="kmw-osk-none",a._Box.appendChild(e);a.createKeyTip();d=a._Box.firstChild;c=" kmw-keyboard-"+(c?c.KI.replace("Keyboard_",""):"");"keymanweb_title_bar"==d.id&&(d=d.nextSibling);d.className="kmw-osk-inner-frame"+c;a.appendStyleSheet();a._Enabled&&a._Show()}};a.appendStyleSheet=function(){var c=b.keyboardManager.activeKeyboard,d=b.keyboardManager.activeStub;if(null!=d){a.styleSheet&&g.removeStyleSheet(a.styleSheet); +var e=d.KFont;d=d.KOskFont;g.addFontFaceStyleSheet(e);g.addFontFaceStyleSheet(d);b.hideInputs();var h=a.addFontStyle(e,d);null!=c&&"string"==typeof c.KCSS&&(h+=c.KCSS);a.styleSheet=g.addStyleSheet(h);a.waitForFonts(e,d)&&b.alignInputs()}};a.addFontStyle=function(a,d){var c=b.baseFont;"undefined"!=typeof a&&"undefined"!=typeof a.family&&(c=a.family);c=c.replace(/\u0022/g,"");var e=new RegExp("\\s?"+c+",?"),g=b.appliedFont.replace(/\u0022/g,"");g=g.replace(e,"");g=g.replace(/,$/,"");g='"'+(""==g?c: +c+","+g).replace(/,\s?/g,'","')+'"';c=".keymanweb-font{\nfont-family:"+g+" !important;\n}\n";"undefined"!=typeof d?c=c+'.kmw-key-text{\nfont-family:"'+d.family.replace(/\u0022/g,"").replace(/,/g,'","')+'";\n}\n':"undefined"!=typeof a&&(c=c+'.kmw-key-text{\nfont-family:"'+a.family.replace(/\u0022/g,"").replace(/,/g,'","')+'";\n}\n');b.appliedFont=g;return c};a._Unload=function(){a._VShift=a._DivVKbd=a._VKeySpans=a._Box=0};a.saveCookie=function(){var b=g.loadCookie("KeymanWeb_OnScreenKeyboard"),d=a.getPos(); +b.visible=a._Enabled?1:0;b.userSet=a.userPositioned?1:0;b.left=d.left;b.top=d.top;a._DivVKbd&&(b.width=a.width,b.height=a.height);g.saveCookie("KeymanWeb_OnScreenKeyboard",b)};a.loadCookie=function(){var b=g.loadCookie("KeymanWeb_OnScreenKeyboard");if("undefined"==typeof b||null==b)return a.userPositioned=!1;a._Enabled=g.toNumber(b.visible,!0);a.userPositioned=g.toNumber(b.userSet,!1);a.x=g.toNumber(b.left,-1);a.y=g.toNumber(b.top,-1);var d=g.toNumber(b.width,.3*screen.width);b=g.toNumber(b.height, +.15*screen.height);d<.2*screen.width&&(d=.2*screen.width);b<.1*screen.height&&(b=.1*screen.height);d>.9*screen.width&&(d=.9*screen.width);b>.5*screen.height&&(b=.5*screen.height);a._DivVKbd&&(a._DivVKbd.style.width=d+"px",a._DivVKbd.style.height=b+"px",a._DivVKbd.style.fontSize=b/8+"px");-1!=a.x&&-1!=a.y&&a._Box||(a.userPositioned=!1);a.xa.y&&(a.x=-1,a.y=-1,a.userPositioned=!1);a.userPositioned&&a._Box&&a.setPos({left:a.x,top:a.y});return!0}; +a.getWidthFromCookie=function(){var a=g.loadCookie("KeymanWeb_OnScreenKeyboard");if("undefined"==typeof a||null==a)return.3*screen.width;a=g.toNumber(a.width,.3*screen.width);a<.2*screen.width?a=.2*screen.width:a>.9*screen.width&&(a=.9*screen.width);return a};a.getFontSizeFromCookie=function(){var a=g.loadCookie("KeymanWeb_OnScreenKeyboard");if("undefined"==typeof a||null==a)return 16;a=g.toNumber(a.height,.15*screen.height);a>.5*screen.height&&(a=.5*screen.height);return a/8}}(); +(function(b){(function(a){var b=function(){function a(){this.innerWidth=window.innerWidth;this.innerHeight=window.innerHeight}a.prototype.equals=function(a){return this.innerWidth==a.innerWidth&&this.innerHeight==a.innerHeight};return a}(),k=function(){function a(b){this.idlePermutationCounter=a.IDLE_PERMUTATION_CAP;this.keyman=b}a.prototype.resolve=function(){this.keyman.alignInputs();var a=this.keyman.osk;a.hideLanguageList();a._Load();this.oskVisible&&a._Show();this.isActive=!1;this.updateTimer&& +(window.clearInterval(this.updateTimer),this.rotState=null)};a.prototype.initNewRotation=function(){this.oskVisible=this.keyman.osk.isVisible();this.keyman.osk.hideNow();this.isActive=!0};a.prototype.init=function(){if(!this.keyman.isEmbedded){var a=this.keyman.util.device.OS,b=this.keyman.util,c=this;"iOS"==a?(b.attachDOMEvent(window,"orientationchange",function(){c.iOSEventHandler();return!1}),b.attachDOMEvent(window,"resize",function(){c.iOSEventHandler();return!1})):"Android"==a&&("onmozorientationchange"in +screen?b.attachDOMEvent(screen,"mozorientationchange",function(){c.initNewRotation();return!1}):b.attachDOMEvent(window,"orientationchange",function(){c.initNewRotation();return!1}),b.attachDOMEvent(window,"resize",function(){c.resolve();return!1}))}};a.prototype.iOSEventHandler=function(){this.isActive||(this.initNewRotation(),this.rotState=new b,this.updateTimer=window.setInterval(this.iOSEventUpdate.bind(this),a.UPDATE_INTERVAL));this.idlePermutationCounter=0};a.prototype.iOSEventUpdate=function(){var e= +new b;this.rotState.equals(e)?++this.idlePermutationCounter==a.IDLE_PERMUTATION_CAP&&this.resolve():(this.rotState=e,this.idlePermutationCounter=0)};a.IDLE_PERMUTATION_CAP=15;a.UPDATE_INTERVAL=20;return a}();a.RotationManager=k})(b.keyman||(b.keyman={}))})(com||(com={})); +window.keyman.initialized||function(){var b=window.keyman,a=b.osk,g=b.util,k=g.device;b.isEmbedded=!1;b.setDefaultDeviceOptions=function(a){""==a.attachType&&(a.attachType=k.touchable?"manual":"auto")};g.wait=function(a){var e=this.waiting;if("undefined"!=typeof e&&null!=e&&!b.warned){var g=e.firstChild.childNodes;a?(e.pending=!0,window.setTimeout(function(){e.pending&&(window.scrollTo(0,0),g[0].style.display="none",g[1].className="kmw-wait-text",g[1].innerHTML=a,g[2].style.display="block",e.style.display= +"block")},1E3)):e.pending&&(g[1].innerHTML="",e.pending=!1,e.style.display="none")}};b.getStyleSheetPath=function(a){return g.getOption("resources")+"osk/"+a};b.getKeyboardPath=function(a){return(/^(([\.]\/)|([\.][\.]\/)|(\/))|(:)/.test(a)?"":b.options.keyboards)+a};b.KC_=function(a,g,l){var c,d="",e=l.body?l:l.ownerDocument;if(k.touchable)d=b.touchAliasing.getTextBeforeCaret(l);else if(e&&(c=e.defaultView)&&c.getSelection&&("on"==e.designMode.toLowerCase()||"true"==l.contentEditable||"plaintext-only"== +l.contentEditable||""===l.contentEditable))l=c.getSelection(),3==l.focusNode.nodeType&&(d=l.focusNode.substringData(0,l.focusOffset));else if(l.setSelectionRange){if(l._KeymanWebSelectionStart)d=l._KeymanWebSelectionStart;else{if(null===b._CachedSelectionStart||l.selectionStart!==b._LastCachedSelection)b._LastCachedSelection=l.selectionStart,b._CachedSelectionStart=l.value._kmwCodeUnitToCodePoint(l.selectionStart),b._CachedSelectionEnd=l.value._kmwCodeUnitToCodePoint(l.selectionEnd);d=b._CachedSelectionStart}d= +l.value._kmwSubstr(0,d)}d._kmwLength()l&&hm&&kf&&(r.fontSize=d*f+"px"));v.textContent=p.textContent;n.display="block";n.position="absolute";n.textAlign="center";n.width="100%";n.top="2%";n.bottom="auto";p=(z.width-m)/2;cwindow.innerWidth-m-p&&(t=1,c-=p);a.drawPreview(z,m,E,t);r.left=c-p+"px";r.display="block"}else e.style.display="none";e.key=b;e.state=h}};a.drawPreview=function(a,b,g,c){g=a.getContext("2d");var d=(a.width-b)/2,e=a.height,h=d,l=b+d;b+=2*d;var E=.5*e,p=.6*e,r=8;"Android"==k.OS&&(r=3);switch(c){case -1:h-= +d;l-=d;break;case 1:h+=d,l+=d}g.clearRect(0,0,a.width,a.height);"Android"==k.OS?(h=l=(h+l)/2,g.fillStyle="#999"):g.fillStyle="#ffffff";g.lineWidth="1";g.strokeStyle="#cccccc";g.save();g.beginPath();g.moveTo(0+r,0);g.arcTo(b,0,b,r,r);"Android"==k.OS?(g.arcTo(b,E,l,p,r),g.arcTo(l,p,h,p,r)):(g.arcTo(b,E,l,p,r),g.arcTo(l,p,l-r,e,r),g.arcTo(l,e,h,e,r),g.arcTo(h,e,h,p-r,r));g.arcTo(h,p,0,E-r,r);g.arcTo(0,E,0,r,r);g.arcTo(0,0,0+r,0,r);g.fill();g.stroke();g.restore()};a.addCallout=function(b){if("phone"!= +k.formFactor||"iOS"!=k.OS)return null;var e=g._CreateElement("div"),l=e.style;e.id="kmw-popup-callout";a._Box.appendChild(e);var c=b.offsetLeft,d=b.offsetWidth,f=b.offsetHeight;l.top=b.offsetTop-6+"px";l.left=c+"px";l.width=d+"px";l.height=f+6+"px";return e};a.touchHold=function(b){a.subkeyDelayTimer&&(window.clearTimeout(a.subkeyDelayTimer),a.subkeyDelayTimer=null);"undefined"!=typeof b.subKeys&&null!=b.subKeys&&(a.subkeyDelayTimer=window.setTimeout(function(){a.clearPopup();a.showSubKeys(b)},a.popupDelay))}; +b.handleRotationEvents=function(){(new com.keyman.RotationManager(b)).init()};a.waitForFonts=function(a,h){if("undefined"==typeof a&&"undefined"==typeof h||"undefined"==typeof a.files&&"undefined"==typeof h.files)return!0;var e=g.checkFontDescriptor(a),c=g.checkFontDescriptor(h);if(e&&c)return!0;b.fontCheckTimer=window.setInterval(function(){g.checkFontDescriptor(a)&&g.checkFontDescriptor(h)&&(window.clearInterval(b.fontCheckTimer),b.fontCheckTimer=null,b.alignInputs())},100);window.setTimeout(function(){b.fontCheckTimer&& +(window.clearInterval(b.fontCheckTimer),b.fontCheckTimer=null,b.alignInputs())},5E3);return!1}}(); +window.keyman.initialized||(window.keyman.dfltLayout={desktop:{font:"Tahoma,Helvetica",layer:[{id:"default",row:[{id:"1",key:[{id:"K_BKQUOTE"},{id:"K_1"},{id:"K_2"},{id:"K_3"},{id:"K_4"},{id:"K_5"},{id:"K_6"},{id:"K_7"},{id:"K_8"},{id:"K_9"},{id:"K_0"},{id:"K_HYPHEN"},{id:"K_EQUAL"},{id:"K_BKSP",text:"*BkSp*",sp:"1",width:"130"}]},{id:"2",key:[{id:"K_TAB",text:"*Tab*",sp:"1",width:"130"},{id:"K_Q"},{id:"K_W"},{id:"K_E"},{id:"K_R"},{id:"K_T"},{id:"K_Y"},{id:"K_U"},{id:"K_I"},{id:"K_O"},{id:"K_P"}, +{id:"K_LBRKT"},{id:"K_RBRKT"},{id:"K_BKSLASH"}]},{id:"3",key:[{id:"K_CAPS",text:"*Caps*",sp:"1",width:"165"},{id:"K_A"},{id:"K_S"},{id:"K_D"},{id:"K_F"},{id:"K_G"},{id:"K_H"},{id:"K_J"},{id:"K_K"},{id:"K_L"},{id:"K_COLON"},{id:"K_QUOTE"},{id:"K_ENTER",text:"*Enter*",sp:"1",width:"165"}]},{id:"4",key:[{id:"K_SHIFT",text:"*Shift*",sp:"1",width:"130"},{id:"K_oE2"},{id:"K_Z"},{id:"K_X"},{id:"K_C"},{id:"K_V"},{id:"K_B"},{id:"K_N"},{id:"K_M"},{id:"K_COMMA"},{id:"K_PERIOD"},{id:"K_SLASH"},{id:"K_RSHIFT", +text:"*Shift*",sp:"1",width:"130"}]},{id:"5",key:[{id:"K_LCONTROL",text:"*Ctrl*",sp:"1",width:"170"},{id:"K_LALT",text:"*Alt*",sp:"1",width:"160"},{id:"K_SPACE",text:"",width:"770"},{id:"K_RALT",text:"*Alt*",sp:"1",width:"160"},{id:"K_RCONTROL",text:"*Ctrl*",sp:"1",width:"170"}]}]}]},tablet:{font:"Tahoma,Helvetica",layer:[{id:"default",row:[{id:"0",key:[{id:"K_1"},{id:"K_2"},{id:"K_3"},{id:"K_4"},{id:"K_5"},{id:"K_6"},{id:"K_7"},{id:"K_8"},{id:"K_9"},{id:"K_0"},{id:"K_HYPHEN"},{id:"K_EQUAL"},{sp:"10", +width:"1"}]},{id:"1",key:[{id:"K_Q",pad:"25"},{id:"K_W"},{id:"K_E"},{id:"K_R"},{id:"K_T"},{id:"K_Y"},{id:"K_U"},{id:"K_I"},{id:"K_O"},{id:"K_P"},{id:"K_LBRKT"},{id:"K_RBRKT"},{sp:"10",width:"1"}]},{id:"2",key:[{id:"K_A",pad:"50"},{id:"K_S"},{id:"K_D"},{id:"K_F"},{id:"K_G"},{id:"K_H"},{id:"K_J"},{id:"K_K"},{id:"K_L"},{id:"K_COLON"},{id:"K_QUOTE"},{id:"K_BKSLASH",width:"90"}]},{id:"3",key:[{id:"K_oE2",width:"90"},{id:"K_Z"},{id:"K_X"},{id:"K_C"},{id:"K_V"},{id:"K_B"},{id:"K_N"},{id:"K_M"},{id:"K_COMMA"}, +{id:"K_PERIOD"},{id:"K_SLASH"},{id:"K_BKQUOTE"},{sp:"10",width:"1"}]},{id:"4",key:[{id:"K_SHIFT",text:"*Shift*",sp:"1",width:"200",sk:[{id:"K_LCONTROL",text:"*Ctrl*",sp:"1",width:"50",nextlayer:"ctrl"},{id:"K_LCONTROL",text:"*LCtrl*",sp:"1",width:"50",nextlayer:"leftctrl"},{id:"K_RCONTROL",text:"*RCtrl*",sp:"1",width:"50",nextlayer:"rightctrl"},{id:"K_LALT",text:"*Alt*",sp:"1",width:"50",nextlayer:"alt"},{id:"K_LALT",text:"*LAlt*",sp:"1",width:"50",nextlayer:"leftalt"},{id:"K_RALT",text:"*RAlt*", +sp:"1",width:"50",nextlayer:"rightalt"},{id:"K_ALTGR",text:"*AltGr*",sp:"1",width:"50",nextlayer:"ctrl-alt"}]},{id:"K_LOPT",text:"*Menu*",sp:"1",width:"150"},{id:"K_SPACE",text:"",width:"570"},{id:"K_BKSP",text:"*BkSp*",sp:"1",width:"150"},{id:"K_ENTER",text:"*Enter*",sp:"1",width:"200"}]}]}]},phone:{font:"Tahoma,Helvetica",layer:[{id:"default",row:[{id:"0",key:[{id:"K_1"},{id:"K_2"},{id:"K_3"},{id:"K_4"},{id:"K_5"},{id:"K_6"},{id:"K_7"},{id:"K_8"},{id:"K_9"},{id:"K_0"},{id:"K_HYPHEN"},{id:"K_EQUAL"}, +{sp:"10",width:"1"}]},{id:"1",key:[{id:"K_Q",pad:"25"},{id:"K_W"},{id:"K_E"},{id:"K_R"},{id:"K_T"},{id:"K_Y"},{id:"K_U"},{id:"K_I"},{id:"K_O"},{id:"K_P"},{id:"K_LBRKT"},{id:"K_RBRKT"},{sp:"10",width:"1"}]},{id:"2",key:[{id:"K_A",pad:"50"},{id:"K_S"},{id:"K_D"},{id:"K_F"},{id:"K_G"},{id:"K_H"},{id:"K_J"},{id:"K_K"},{id:"K_L"},{id:"K_COLON"},{id:"K_QUOTE"},{id:"K_BKSLASH",width:"90"}]},{id:"3",key:[{id:"K_oE2",width:"90"},{id:"K_Z"},{id:"K_X"},{id:"K_C"},{id:"K_V"},{id:"K_B"},{id:"K_N"},{id:"K_M"}, +{id:"K_COMMA"},{id:"K_PERIOD"},{id:"K_SLASH"},{id:"K_BKQUOTE"},{sp:"10",width:"1"}]},{id:"4",key:[{id:"K_SHIFT",text:"*Shift*",sp:"1",width:"200",sk:[{id:"K_LCONTROL",text:"*Ctrl*",sp:"1",width:"50",nextlayer:"ctrl"},{id:"K_LCONTROL",text:"*LCtrl*",sp:"1",width:"50",nextlayer:"leftctrl"},{id:"K_RCONTROL",text:"*RCtrl*",sp:"1",width:"50",nextlayer:"rightctrl"},{id:"K_LALT",text:"*Alt*",sp:"1",width:"50",nextlayer:"alt"},{id:"K_LALT",text:"*LAlt*",sp:"1",width:"50",nextlayer:"leftalt"},{id:"K_RALT", +text:"*RAlt*",sp:"1",width:"50",nextlayer:"rightalt"},{id:"K_ALTGR",text:"*AltGr*",sp:"1",width:"50",nextlayer:"ctrl-alt"}]},{id:"K_LOPT",text:"*Menu*",width:"150",sp:"1"},{id:"K_SPACE",width:"570",text:""},{id:"K_BKSP",text:"*BkSp*",width:"150",sp:"1"},{id:"K_ENTER",text:"*Enter*",width:"200",sp:"1"}]}]}]}});(function(){var b=window.keyman,a=window.setInterval(function(){"complete"===document.readyState&&(window.clearInterval(a),b.init(null))},10)})(); +var CLOSURE_NO_DEPS=!0,COMPILED=!0,goog=goog||{};goog.global=this;goog.isDef=function(b){return void 0!==b};goog.isString=function(b){return"string"==typeof b};goog.isBoolean=function(b){return"boolean"==typeof b};goog.isNumber=function(b){return"number"==typeof b};goog.exportPath_=function(b,a,g){b=b.split(".");g=g||goog.global;b[0]in g||!g.execScript||g.execScript("var "+b[0]);for(var k;b.length&&(k=b.shift());)!b.length&&goog.isDef(a)?g[k]=a:g=g[k]&&g[k]!==Object.prototype[k]?g[k]:g[k]={}}; +goog.define=function(b,a){COMPILED||(goog.global.CLOSURE_UNCOMPILED_DEFINES&&void 0===goog.global.CLOSURE_UNCOMPILED_DEFINES.nodeType&&Object.prototype.hasOwnProperty.call(goog.global.CLOSURE_UNCOMPILED_DEFINES,b)?a=goog.global.CLOSURE_UNCOMPILED_DEFINES[b]:goog.global.CLOSURE_DEFINES&&void 0===goog.global.CLOSURE_DEFINES.nodeType&&Object.prototype.hasOwnProperty.call(goog.global.CLOSURE_DEFINES,b)&&(a=goog.global.CLOSURE_DEFINES[b]));goog.exportPath_(b,a)};goog.DEBUG=!0;goog.LOCALE="en"; +goog.TRUSTED_SITE=!0;goog.STRICT_MODE_COMPATIBLE=!1;goog.DISALLOW_TEST_ONLY_CODE=COMPILED&&!goog.DEBUG;goog.ENABLE_CHROME_APP_SAFE_SCRIPT_LOADING=!1;goog.provide=function(b){if(goog.isInModuleLoader_())throw Error("goog.provide can not be used within a goog.module.");if(!COMPILED&&goog.isProvided_(b))throw Error('Namespace "'+b+'" already declared.');goog.constructNamespace_(b)}; +goog.constructNamespace_=function(b,a){if(!COMPILED){delete goog.implicitNamespaces_[b];for(var g=b;(g=g.substring(0,g.lastIndexOf(".")))&&!goog.getObjectByName(g);)goog.implicitNamespaces_[g]=!0}goog.exportPath_(b,a)};goog.VALID_MODULE_RE_=/^[a-zA-Z_$][a-zA-Z0-9._$]*$/; +goog.module=function(b){if(!goog.isString(b)||!b||-1==b.search(goog.VALID_MODULE_RE_))throw Error("Invalid module identifier");if(!goog.isInModuleLoader_())throw Error("Module "+b+" has been loaded incorrectly. Note, modules cannot be loaded as normal scripts. They require some kind of pre-processing step. You're likely trying to load a module via a script tag or as a part of a concatenated bundle without rewriting the module. For more info see: https://github.com/google/closure-library/wiki/goog.module:-an-ES6-module-like-alternative-to-goog.provide.");if(goog.moduleLoaderState_.moduleName)throw Error("goog.module may only be called once per module."); +goog.moduleLoaderState_.moduleName=b;if(!COMPILED){if(goog.isProvided_(b))throw Error('Namespace "'+b+'" already declared.');delete goog.implicitNamespaces_[b]}};goog.module.get=function(b){return goog.module.getInternal_(b)};goog.module.getInternal_=function(b){if(!COMPILED){if(b in goog.loadedModules_)return goog.loadedModules_[b];if(!goog.implicitNamespaces_[b])return b=goog.getObjectByName(b),null!=b?b:null}return null};goog.moduleLoaderState_=null; +goog.isInModuleLoader_=function(){return null!=goog.moduleLoaderState_};goog.module.declareLegacyNamespace=function(){if(!COMPILED&&!goog.isInModuleLoader_())throw Error("goog.module.declareLegacyNamespace must be called from within a goog.module");if(!COMPILED&&!goog.moduleLoaderState_.moduleName)throw Error("goog.module must be called prior to goog.module.declareLegacyNamespace.");goog.moduleLoaderState_.declareLegacyNamespace=!0}; +goog.setTestOnly=function(b){if(goog.DISALLOW_TEST_ONLY_CODE)throw b=b||"",Error("Importing test-only code into non-debug environment"+(b?": "+b:"."));};goog.forwardDeclare=function(b){};COMPILED||(goog.isProvided_=function(b){return b in goog.loadedModules_||!goog.implicitNamespaces_[b]&&goog.isDefAndNotNull(goog.getObjectByName(b))},goog.implicitNamespaces_={"goog.module":!0}); +goog.getObjectByName=function(b,a){b=b.split(".");a=a||goog.global;for(var g=0;g>>0);goog.uidCounter_=0;goog.getHashCode=goog.getUid; +goog.removeHashCode=goog.removeUid;goog.cloneObject=function(b){var a=goog.typeOf(b);if("object"==a||"array"==a){if(b.clone)return b.clone();a="array"==a?[]:{};for(var g in b)a[g]=goog.cloneObject(b[g]);return a}return b};goog.bindNative_=function(b,a,g){return b.call.apply(b.bind,arguments)}; +goog.bindJs_=function(b,a,g){if(!b)throw Error();if(2Number(b[1])?!1:a('(()=>{"use strict";class X{constructor(){if(new.target!=String)throw 1;this.x=42}}let q=Reflect.construct(X,[],String);if(q.x!=42||!(q instanceof String))throw 1;for(const a of[2,3]){if(a==2)continue;function f(z={a}){let a=0;return z.a}{function f(){return 0;}}return f()==3}})()')});b("es6-impl",function(){return!0});b("es7",function(){return a("2 ** 2 == 4")});b("es8",function(){return a("async () => 1, true")});return g},goog.Transpiler.prototype.needsTranspile= +function(b){if("always"==goog.TRANSPILE)return!0;if("never"==goog.TRANSPILE)return!1;this.requiresTranspilation_||(this.requiresTranspilation_=this.createRequiresTranspilation_());if(b in this.requiresTranspilation_)return this.requiresTranspilation_[b];throw Error("Unknown language mode: "+b);},goog.Transpiler.prototype.transpile=function(b,a){return goog.transpile_(b,a)},goog.transpiler_=new goog.Transpiler,goog.DebugLoader=function(){this.dependencies_={loadFlags:{},nameToPath:{},requires:{},visited:{}, +written:{},deferred:{}};this.oldIeWaiting_=!1;this.queuedModules_=[];this.lastNonModuleScriptIndex_=0},goog.DebugLoader.IS_OLD_IE_=!(goog.global.atob||!goog.global.document||!goog.global.document.all),goog.DebugLoader.prototype.earlyProcessLoad=function(b){goog.DebugLoader.IS_OLD_IE_&&this.maybeProcessDeferredDep_(b)},goog.DebugLoader.prototype.load=function(b){var a=this.getPathFromDeps_(b);if(a){var g=function(a){if(!(a in h.written||a in h.visited)){h.visited[a]=!0;if(a in h.requires)for(var b in h.requires[a])if(!l.isProvided(b))if(b in +h.nameToPath)g(h.nameToPath[b]);else throw Error("Undefined nameToPath for "+b);a in e||(e[a]=!0,k.push(a))}},k=[],e={},h=this.dependencies_,l=this;g(a);for(b=0;b\x3c/script>')},goog.DebugLoader.prototype.appendScriptSrcNode_=function(b){var a=goog.global.document,g=a.createElement("script");g.type="text/javascript";g.src=b;g.defer=!1;g.async=!1;a.head.appendChild(g)},goog.DebugLoader.prototype.writeScriptTag_=function(b,a){if(this.inHtmlDocument()){var g=goog.global.document;if(!goog.ENABLE_CHROME_APP_SAFE_SCRIPT_LOADING&& +"complete"==g.readyState){if(/\bdeps.js$/.test(b))return!1;throw Error('Cannot write "'+b+'" after document load');}void 0===a?goog.DebugLoader.IS_OLD_IE_?(this.oldIeWaiting_=!0,a=" onreadystatechange='goog.debugLoader_.onScriptLoad_(this, "+ ++this.lastNonModuleScriptIndex_+")' ",g.write(' +``` + +Also include the following HTML code: + +```html + + + + + + + + + +``` + +- File: [laokeys_load.js](js/laokeys_load.js) + +And finally, include the control img for KeymanWeb: + +```html + +KeymanWeb +``` + +## API References + +On programmatically setting the keyboard: +- [`keyman.setActiveKeyboard()`](../../reference/core/setActiveKeyboard). + +On managing the visibility of the OSK: +- [`keyman.osk.hide()`](../../reference/osk/hide) +- [`keyman.osk.show()`](../../reference/osk/show). + +------------------------------------------------------------------------ + +[On to Full Manual Control Example](full-manual-control) diff --git a/web/docs/engine/guide/get-started.md b/web/docs/engine/guide/get-started.md new file mode 100644 index 0000000000..4089f6712d --- /dev/null +++ b/web/docs/engine/guide/get-started.md @@ -0,0 +1,53 @@ +--- +title: Getting Started With KeymanWeb +--- + +## Prerequisite + +- First, if you have not yet obtained a copy of KeymanWeb, please visit [the KeymanWeb Developer Home](https://keyman.com/developer/keymanweb/). A link to the "https minified" version of the code will be used here. + +## Demo + +To setup a basic first page with KeymanWeb, only two lines of code are necessary, but a few more lines will be shown here. Open [an example page](examples/__first-example.html). + +The source code for the page may be seen below. + +```html + + + + + KeymanWeb - A First Example + + + + + + +

Click me and type:

+ + +``` + +## The Breakdown + +- The `` loads the Keyman Engine for Web script for the page. + +- `(function() { keyman.init(); });` serves to initialize the web engine with default settings. By adding the object `{attachType:'auto'}` as a parameter to our `keyman.init()` call, the KeymanWeb engine will then link into any detected input elements automatically, regardless of browser or device, as part of its initialization. + +- The other ``, creates the language menu seen on non-mobile devices and the on-screen keyboard toggle button. For other options, see our [User Interface Design](user-interface-design) page. + +- The calls to `keyman.addKeyboards()` in the source above link in the two example Keyman keyboards used in this demo from our CDN server. For more info on how to include keyboards in your KeymanWeb installation, check the [Adding Keyboards](adding-keyboards) page. + +## API References + +- On initialization: [`keyman.init()`](../reference/core/init). + +- On including keyboards: [`keyman.addKeyboards()`](../reference/core/addKeyboards). diff --git a/web/docs/engine/guide/index.md b/web/docs/engine/guide/index.md new file mode 100644 index 0000000000..26e2e42b47 --- /dev/null +++ b/web/docs/engine/guide/index.md @@ -0,0 +1,13 @@ +--- +title: KeymanWeb 18.0 - The Guide +--- + +Welcome to the guide for using KeymanWeb 18.0. + +- [Getting Started with Keyman Web](get-started) +- [User Interface Design](user-interface-design) +- [What is a Keyboard?](what-is-a-keyboard) +- [Installing Keyboards](adding-keyboards) +- [Additional Examples](examples/) + +[Return to the main KeymanWeb 18.0 page](../) \ No newline at end of file diff --git a/web/docs/engine/guide/user-interface-design.md b/web/docs/engine/guide/user-interface-design.md new file mode 100644 index 0000000000..9f56ac214e --- /dev/null +++ b/web/docs/engine/guide/user-interface-design.md @@ -0,0 +1,103 @@ +--- +title: User Interface Design +--- + +This page displays all the different KeymanWeb user interface options +available for non-mobile consumption. Use whichever one best complements +your website. Depending on the number of keyboards you are using and the +way your website is designed, the various interfaces will be more or +less suitable. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

The Button Interface

+

+ +
Button Interface

+
+

Display: Fixed Element

+

No of Keyboards: up to 20

+

HTML: Header & Control

+
+
+

For an interface which fits unobtrusively into your website while maintaining full functionality, try the Button Interface. All KeymanWeb's functions are displayed in a menu appearing whenever the user hovers over the button, which can be placed anywhere on the website.

+

To keep this interface as compact as possible, it is controlled through a single menu. While there is technically no limit to the number of keyboards that can be used, the Button interface works best on sites using up to 20 different keyboards, which are listed alphabetically.

+

The include for this interface is <script src="kmwuibutton.js">.

+

To select where the interface will be displayed on your page, add the following element where desired: <div id="KeymanWebControl" display="block"></div>

+

The property display may take two values: block and none, the latter of which temporarily hides the element.

+

For information on how your site users will interact with the Button Interface, click here.

+

The Floating Interface

+

+ +
Floating Interface

+
+

Display: Floating Element

+

No of Keyboards: up to 20

+

HTML: Header Only

+
+
+

The Floating Interface provides a clear, menu-based approach to selecting from a list of keyboards. This interface can be incorporated without changing the layout of your existing site, as it automatically appears when users click in a a supported control (such as a textbox) and disappears again when they click outside. You can choose to have the interface float below (DefaultBelow) or to the right of (DefaultRight) the active control.

+

This interface is simple to use, and with its single alphabetical list of keyboards, works most effectively on sites supporting up to around 20 keyboards.

+

The include for this interface is <script src="kmwuifloat.js">.

+

For information on how your site users will interact with the Floating Interface, click here.

+

The Toggle Interface

+

+ +
Toggle Interface

+
+

Display: Floating Element

+

No of Keyboards: 1

+

HTML: Header Only

+
+
+

For a website incorporating KeymanWeb to support a single keyboard, the Toggle is the ideal solution. The interface floats at the right of the active control, and is hidden when the mouse is clicked outside, which means that no changes have to be made to your site design. A simple on-off interface makes it easy for users to switch between their default language and the supported keyboard.

+

The include for this interface is <script src="kmwuitoggle.js">.

+

For information on how your site users will interact with the Toggle Interface, click here.

+

The Toolbar Interface

+

+ +
Toolbar Interface

+
+

Display: Fixed Element

+

No of Keyboards: unlimited

+

HTML: Header & Control

+
+
+

The standard interface for many sites incorporating KeymanWeb is the Toolbar. This interface, which can be positioned anywhere on a website by inserting the HTML code provided, provides an instant visual indication that the site allows users to type in a range of languages.

+

The Toolbar's map-based menu, displayed whenever a user clicks on the Keyboards button, works particularly well with multilingual sites integrating languages from all over the world. The most recently-used keyboard is remembered in a cookie, making it as easy to switch between English and another language as the Toggle interface, while maintaining full functionality and support for an essentially unlimited number of keyboards.

+

The include for this interface is <script src="kmwuitoolbar.js">.

+

To select where the interface will be displayed on your page, add the following element where desired: <div id="KeymanWebControl" display="block"></div>, as with the Button Interface above.

+

A live example of the KeymanWeb Toolbar Interface is available on the KeymanWeb Demo Site. For information on how your site users will interact with the Toolbar Interface, click here.

+ +
diff --git a/web/docs/engine/guide/what-is-a-keyboard.md b/web/docs/engine/guide/what-is-a-keyboard.md new file mode 100644 index 0000000000..204e26bfb7 --- /dev/null +++ b/web/docs/engine/guide/what-is-a-keyboard.md @@ -0,0 +1,13 @@ +--- +title: What is a Keyboard? +--- + +When using KeymanWeb, the term *keyboard* refers specifically to the way the keys are arranged for a specific language (i.e. which letter or character appears when a given key is pressed). While many languages use a keyboard based on the English-language QWERTY layout, those that have a different writing system altogether usually have a completely unrelated keyboard. Some languages also have more than one keyboard layout; a typewriter-based layout and a phonetic layout, for example. + +The keyboards available for use with KeymanWeb have been developed by a wide range of people all over the world. Some keyboards adhere to published standards while others have been developed to meet a specific requirement. [Keyman Developer](/developer/current-version/) has been used to develop the keyboards. + +## Information on Specific Keyboards + +KeymanWeb supports a very wide range of languages, and many keyboards available for use with KeymanWeb include features specific to particular languages. Because of this, each keyboard has its own documentation, which is included with the On-Screen Keyboard. Although the level of detail in this documentation does vary somewhat, depending on the designer and the requirements of each keyboard, this is the first place to look for information on using a particular language with KeymanWeb. + +[Index of help for KeymanWeb keyboard layouts](/keyboard) diff --git a/web/docs/engine/images/Image15.png b/web/docs/engine/images/Image15.png new file mode 100644 index 0000000000..eb3086fdd0 Binary files /dev/null and b/web/docs/engine/images/Image15.png differ diff --git a/web/docs/engine/images/agreement - Copy.psp b/web/docs/engine/images/agreement - Copy.psp new file mode 100644 index 0000000000..8e51b89156 Binary files /dev/null and b/web/docs/engine/images/agreement - Copy.psp differ diff --git a/web/docs/engine/images/agreement.png b/web/docs/engine/images/agreement.png new file mode 100644 index 0000000000..c8339793c4 Binary files /dev/null and b/web/docs/engine/images/agreement.png differ diff --git a/web/docs/engine/images/agreement.psp b/web/docs/engine/images/agreement.psp new file mode 100644 index 0000000000..c21894b887 Binary files /dev/null and b/web/docs/engine/images/agreement.psp differ diff --git a/web/docs/engine/images/console0.png b/web/docs/engine/images/console0.png new file mode 100644 index 0000000000..d69b2aa60e Binary files /dev/null and b/web/docs/engine/images/console0.png differ diff --git a/web/docs/engine/images/console0.psp b/web/docs/engine/images/console0.psp new file mode 100644 index 0000000000..3be39b8528 Binary files /dev/null and b/web/docs/engine/images/console0.psp differ diff --git a/web/docs/engine/images/console1.png b/web/docs/engine/images/console1.png new file mode 100644 index 0000000000..565a954d32 Binary files /dev/null and b/web/docs/engine/images/console1.png differ diff --git a/web/docs/engine/images/console1.psp b/web/docs/engine/images/console1.psp new file mode 100644 index 0000000000..987d71079c Binary files /dev/null and b/web/docs/engine/images/console1.psp differ diff --git a/web/docs/engine/images/dashboard1.png b/web/docs/engine/images/dashboard1.png new file mode 100644 index 0000000000..44d0196d9f Binary files /dev/null and b/web/docs/engine/images/dashboard1.png differ diff --git a/web/docs/engine/images/dashboard1.psp b/web/docs/engine/images/dashboard1.psp new file mode 100644 index 0000000000..b56315629b Binary files /dev/null and b/web/docs/engine/images/dashboard1.psp differ diff --git a/web/docs/engine/images/dashboard2.png b/web/docs/engine/images/dashboard2.png new file mode 100644 index 0000000000..d2112bfdf4 Binary files /dev/null and b/web/docs/engine/images/dashboard2.png differ diff --git a/web/docs/engine/images/dashboard2.psp b/web/docs/engine/images/dashboard2.psp new file mode 100644 index 0000000000..a85162917f Binary files /dev/null and b/web/docs/engine/images/dashboard2.psp differ diff --git a/web/docs/engine/images/demo1.png b/web/docs/engine/images/demo1.png new file mode 100644 index 0000000000..96a1e2fe7c Binary files /dev/null and b/web/docs/engine/images/demo1.png differ diff --git a/web/docs/engine/images/demo1.psp b/web/docs/engine/images/demo1.psp new file mode 100644 index 0000000000..4ea2ccd7d6 Binary files /dev/null and b/web/docs/engine/images/demo1.psp differ diff --git a/web/docs/engine/images/demo2.png b/web/docs/engine/images/demo2.png new file mode 100644 index 0000000000..32beb2e721 Binary files /dev/null and b/web/docs/engine/images/demo2.png differ diff --git a/web/docs/engine/images/demo2.psp b/web/docs/engine/images/demo2.psp new file mode 100644 index 0000000000..8806e71210 Binary files /dev/null and b/web/docs/engine/images/demo2.psp differ diff --git a/web/docs/engine/images/dev-manage.gif b/web/docs/engine/images/dev-manage.gif new file mode 100644 index 0000000000..5752b00236 Binary files /dev/null and b/web/docs/engine/images/dev-manage.gif differ diff --git a/web/docs/engine/images/domains.png b/web/docs/engine/images/domains.png new file mode 100644 index 0000000000..cdad1feaea Binary files /dev/null and b/web/docs/engine/images/domains.png differ diff --git a/web/docs/engine/images/domains.psp b/web/docs/engine/images/domains.psp new file mode 100644 index 0000000000..cdb77bdc7e Binary files /dev/null and b/web/docs/engine/images/domains.psp differ diff --git a/web/docs/engine/images/edit.gif b/web/docs/engine/images/edit.gif new file mode 100644 index 0000000000..dc771073a3 Binary files /dev/null and b/web/docs/engine/images/edit.gif differ diff --git a/web/docs/engine/images/integrate.png b/web/docs/engine/images/integrate.png new file mode 100644 index 0000000000..e807dac32d Binary files /dev/null and b/web/docs/engine/images/integrate.png differ diff --git a/web/docs/engine/images/integrate.psp b/web/docs/engine/images/integrate.psp new file mode 100644 index 0000000000..8c6b64051d Binary files /dev/null and b/web/docs/engine/images/integrate.psp differ diff --git a/web/docs/engine/images/keyboards0.png b/web/docs/engine/images/keyboards0.png new file mode 100644 index 0000000000..d20a459290 Binary files /dev/null and b/web/docs/engine/images/keyboards0.png differ diff --git a/web/docs/engine/images/keyboards0.psp b/web/docs/engine/images/keyboards0.psp new file mode 100644 index 0000000000..25cac75cc8 Binary files /dev/null and b/web/docs/engine/images/keyboards0.psp differ diff --git a/web/docs/engine/images/keyboards1.png b/web/docs/engine/images/keyboards1.png new file mode 100644 index 0000000000..f600f71039 Binary files /dev/null and b/web/docs/engine/images/keyboards1.png differ diff --git a/web/docs/engine/images/keyboards1.psp b/web/docs/engine/images/keyboards1.psp new file mode 100644 index 0000000000..5c48601886 Binary files /dev/null and b/web/docs/engine/images/keyboards1.psp differ diff --git a/web/docs/engine/images/kmwlogo.gif b/web/docs/engine/images/kmwlogo.gif new file mode 100644 index 0000000000..5fea3b95a3 Binary files /dev/null and b/web/docs/engine/images/kmwlogo.gif differ diff --git a/web/docs/engine/images/login.gif b/web/docs/engine/images/login.gif new file mode 100644 index 0000000000..22555bc6b1 Binary files /dev/null and b/web/docs/engine/images/login.gif differ diff --git a/web/docs/engine/images/login.png b/web/docs/engine/images/login.png new file mode 100644 index 0000000000..daac1de128 Binary files /dev/null and b/web/docs/engine/images/login.png differ diff --git a/web/docs/engine/images/login.psp b/web/docs/engine/images/login.psp new file mode 100644 index 0000000000..2623dafa46 Binary files /dev/null and b/web/docs/engine/images/login.psp differ diff --git a/web/docs/engine/images/plans.png b/web/docs/engine/images/plans.png new file mode 100644 index 0000000000..7e92828c07 Binary files /dev/null and b/web/docs/engine/images/plans.png differ diff --git a/web/docs/engine/images/plans.psp b/web/docs/engine/images/plans.psp new file mode 100644 index 0000000000..3ac30faa66 Binary files /dev/null and b/web/docs/engine/images/plans.psp differ diff --git a/web/docs/engine/images/sshot1.gif b/web/docs/engine/images/sshot1.gif new file mode 100644 index 0000000000..ae5ccef6ba Binary files /dev/null and b/web/docs/engine/images/sshot1.gif differ diff --git a/web/docs/engine/images/sshot2.gif b/web/docs/engine/images/sshot2.gif new file mode 100644 index 0000000000..90dff8581f Binary files /dev/null and b/web/docs/engine/images/sshot2.gif differ diff --git a/web/docs/engine/images/sshot4.gif b/web/docs/engine/images/sshot4.gif new file mode 100644 index 0000000000..c8c33038ff Binary files /dev/null and b/web/docs/engine/images/sshot4.gif differ diff --git a/web/docs/engine/images/sshot5.gif b/web/docs/engine/images/sshot5.gif new file mode 100644 index 0000000000..e7ea8aec74 Binary files /dev/null and b/web/docs/engine/images/sshot5.gif differ diff --git a/web/docs/engine/images/ssx1.gif b/web/docs/engine/images/ssx1.gif new file mode 100644 index 0000000000..e6eff7f0e1 Binary files /dev/null and b/web/docs/engine/images/ssx1.gif differ diff --git a/web/docs/engine/images/ssx2.gif b/web/docs/engine/images/ssx2.gif new file mode 100644 index 0000000000..edca2c9569 Binary files /dev/null and b/web/docs/engine/images/ssx2.gif differ diff --git a/web/docs/engine/images/ssx3.gif b/web/docs/engine/images/ssx3.gif new file mode 100644 index 0000000000..ac8901dd5d Binary files /dev/null and b/web/docs/engine/images/ssx3.gif differ diff --git a/web/docs/engine/images/ssx4.gif b/web/docs/engine/images/ssx4.gif new file mode 100644 index 0000000000..579829c596 Binary files /dev/null and b/web/docs/engine/images/ssx4.gif differ diff --git a/web/docs/engine/images/ssx5.gif b/web/docs/engine/images/ssx5.gif new file mode 100644 index 0000000000..e819fe04eb Binary files /dev/null and b/web/docs/engine/images/ssx5.gif differ diff --git a/web/docs/engine/images/ssx6.gif b/web/docs/engine/images/ssx6.gif new file mode 100644 index 0000000000..04608b67c1 Binary files /dev/null and b/web/docs/engine/images/ssx6.gif differ diff --git a/web/docs/engine/images/ssx7.gif b/web/docs/engine/images/ssx7.gif new file mode 100644 index 0000000000..f9ecacff76 Binary files /dev/null and b/web/docs/engine/images/ssx7.gif differ diff --git a/web/docs/engine/images/ui-button.gif b/web/docs/engine/images/ui-button.gif new file mode 100644 index 0000000000..1762f77fc6 Binary files /dev/null and b/web/docs/engine/images/ui-button.gif differ diff --git a/web/docs/engine/images/ui-floating.gif b/web/docs/engine/images/ui-floating.gif new file mode 100644 index 0000000000..e961ab8416 Binary files /dev/null and b/web/docs/engine/images/ui-floating.gif differ diff --git a/web/docs/engine/images/ui-toggle.gif b/web/docs/engine/images/ui-toggle.gif new file mode 100644 index 0000000000..f468c54b2e Binary files /dev/null and b/web/docs/engine/images/ui-toggle.gif differ diff --git a/web/docs/engine/images/ui-toolbar.gif b/web/docs/engine/images/ui-toolbar.gif new file mode 100644 index 0000000000..b27d559356 Binary files /dev/null and b/web/docs/engine/images/ui-toolbar.gif differ diff --git a/web/docs/engine/index.md b/web/docs/engine/index.md new file mode 100644 index 0000000000..63d14e2fd1 --- /dev/null +++ b/web/docs/engine/index.md @@ -0,0 +1,39 @@ +--- +title: Keyman Engine for Web 18.0 Developer Help +--- +Keyman Engine for Web 18.0 is the current version of KeymanWeb and +supports touch devices with custom touch-layouts as well as desktop +computer browsers. + +[Download](https://keyman.com/developer/keymanweb/) +: Downloading Keyman Engine for Web 18.0 + + + +[Guide](guide/) +: Keyman Engine for Web 18.0 Guide + + + +[Reference](reference) +: Keyman Engine for Web 18.0 Developer Reference + + + +[What's New](whats-new) +: What's new in Keyman Engine for Web 18.0 + + + +[Cloud Services API](../../../cloud/) +: Keyman Engine for Web - Cloud Services API + +### For More Information... + +- [Keyman Community](https://community.software.sil.org/c/keyman) +- [Stack Overflow](https://stackoverflow.com/search?q=%5Bkeyman%5D) - + for support on creating keyboard layouts with Keyman Developer ([ask + a + question](https://stackoverflow.com/questions/ask?tags=keyman,keyman-developer,keyboard,unicode)) +- [Keyman Engine for Web - Version History](../history) + diff --git a/web/docs/engine/reference/compatibility/FocusLastActiveElement.md b/web/docs/engine/reference/compatibility/FocusLastActiveElement.md new file mode 100644 index 0000000000..49cb6dfed4 --- /dev/null +++ b/web/docs/engine/reference/compatibility/FocusLastActiveElement.md @@ -0,0 +1,26 @@ +--- +title: FocusLastActiveElement +--- + +## Summary + +Restore the focus to the element active before input was moved to +KeymanWeb. + +## Syntax + +``` +keyman.FocusLastActiveElement() +``` + +### Parameters + +None. + +### Return Value + +`undefined` + +### Replaced By + +[`keyman.focusLastActiveElement()`](../core/focusLastActiveElement) diff --git a/web/docs/engine/reference/compatibility/GetLastActiveElement.md b/web/docs/engine/reference/compatibility/GetLastActiveElement.md new file mode 100644 index 0000000000..32ca21c103 --- /dev/null +++ b/web/docs/engine/reference/compatibility/GetLastActiveElement.md @@ -0,0 +1,26 @@ +--- +title: GetLastActiveElement +--- + +## Summary + +Returns the last active target element before the current KMW operation. + +## Syntax + +``` +keyman.GetLastActiveElement(); +``` + +### Parameters + +None. + +### Return Value + +`Element` +: The requested element. + +### Replaced By + +[`keyman.getLastActiveElement()`](../core/getLastActiveElement) diff --git a/web/docs/engine/reference/compatibility/HideHelp.md b/web/docs/engine/reference/compatibility/HideHelp.md new file mode 100644 index 0000000000..4c916c02a0 --- /dev/null +++ b/web/docs/engine/reference/compatibility/HideHelp.md @@ -0,0 +1,25 @@ +--- +title: HideHelp +--- + +## Summary + +Hides the OSK (visual help). + +## Syntax + +``` +keyman.HideHelp(); +``` + +### Parameters + +None. + +### Return Value + +`undefined` + +### Replaced By + +[`keyman.osk.hide()`](../osk/hide) diff --git a/web/docs/engine/reference/compatibility/ShowHelp.md b/web/docs/engine/reference/compatibility/ShowHelp.md new file mode 100644 index 0000000000..9647ec6b16 --- /dev/null +++ b/web/docs/engine/reference/compatibility/ShowHelp.md @@ -0,0 +1,32 @@ +--- +title: ShowHelp +--- + +## Summary + +Shows the on-screen keyboard at the requested (x, y) coordinates. + +## Syntax + +``` +keyman.ShowHelp(x, y); +``` + +### Parameters + +`x` +: Type: `number` +: x-coordinate for display of the OSK. + +`y` +: Type: `number` +: y-coordinate for display of the OSK. + +### Return Value + +`undefined` + +### Replaced by + +[`keyman.osk.setPos()`](../osk/setPos), +[`keyman.osk.show()`](../osk/show) diff --git a/web/docs/engine/reference/compatibility/ShowPinnedHelp.md b/web/docs/engine/reference/compatibility/ShowPinnedHelp.md new file mode 100644 index 0000000000..43b3e40946 --- /dev/null +++ b/web/docs/engine/reference/compatibility/ShowPinnedHelp.md @@ -0,0 +1,26 @@ +--- +title: ShowPinnedHelp +--- + +## Summary + +Shows the on-screen keyboard and locks it at the resulting location. + +## Syntax + +``` +keyman.ShowPinnedHelp(x, y); +``` + +### Parameters + +None. + +### Return Value + +`undefined` + +### Replaced by + +[`keyman.osk.setRect()`](../osk/setRect), +[`keyman.osk.show()`](../osk/show) diff --git a/web/docs/engine/reference/compatibility/index.md b/web/docs/engine/reference/compatibility/index.md new file mode 100644 index 0000000000..98f4e37813 --- /dev/null +++ b/web/docs/engine/reference/compatibility/index.md @@ -0,0 +1,33 @@ +--- +title: Compatibility Functions +--- + +The following *KeymanWeb* core functions +have been retained for compatibility with existing custom keyboards, but +should not be used in any new keyboards or user interfaces. Equivalent +new function calls are indicated. + +[`GetLastActiveElement` Function](GetLastActiveElement) +: [`keyman.getLastActiveElement()`](../core/getLastActiveElement) + + + +[`FocusLastActiveElement` Function](FocusLastActiveElement) +: [`keyman.focusLastActiveElement()`](../core/focusLastActiveElement) + + + +[`HideHelp` Function](HideHelp) +: [`keyman.osk.hide()`](../osk/hide) + + + +[`ShowHelp` Function](ShowHelp) +: [`keyman.osk.setPos()`](../osk/setPos), + [`keyman.osk.show()`](../osk/show) + + + +[`ShowPinnedHelp` Function](ShowPinnedHelp) +: [`keyman.osk.setRect()`](../osk/setRect), + [`keyman.osk.show()`](../osk/show) diff --git a/web/docs/engine/reference/core/BuildVisualKeyboard.md b/web/docs/engine/reference/core/BuildVisualKeyboard.md new file mode 100644 index 0000000000..4a258dfa01 --- /dev/null +++ b/web/docs/engine/reference/core/BuildVisualKeyboard.md @@ -0,0 +1,48 @@ +--- +title: BuildVisualKeyboard +--- + +## Summary + +Create a copy of the OSK for embedding in documentation or help page. + +## Syntax + +```c +keyman.BuildVisualKeyboard(keyboardID, staticFlag, layoutFormFactor, layerID) +``` + +### Parameters + +`keyboardID` +: Type: `string` +: Identifying name of the keyboard. + +`staticFlag` +: Type: `number` +: Deprecated parameter; should be set to 1. + +`layoutFormFactor` +: Type: `string` *optional* +: A string describing the layout to use for the generated keyboard. Should be one of the following: + + - `'desktop'` + - `'phone'` + - `'tablet'` + + Defaults to `'desktop'`. + +`layerID` +: Type: `string|number` *optional* +: Name or index of the layer to be shown. If not specified, defaults to 'default', the base layer. + +### Return Value + +`Element` +: A non-interactive DIV object will filled keyboard layer content. + +## Description + +Generates a non-interactive `
` element with the complete structure +of the specified layer of an on-screen keyboard (OSK) that the user can +then utilize for documentation or other purposes. diff --git a/web/docs/engine/reference/core/activatingUI.md b/web/docs/engine/reference/core/activatingUI.md new file mode 100644 index 0000000000..a5837f6b48 --- /dev/null +++ b/web/docs/engine/reference/core/activatingUI.md @@ -0,0 +1,29 @@ +--- +title: activatingUI +--- + +## Summary + +Sets an internal flag to notify KeymanWeb of change in UI activation state. + +## Syntax + +```c +keyman.activatingUI(state); +``` + +### Parameters + +`state` +: Type: `boolean|number` +: Used to signify if the user is interacting with KeymanWeb UI elements. + +### Return Value + +`undefined` + +## Description + +This function is used by the various non-mobile UI implementations to aid the KeymanWeb engine with internal bookkeeping. In particular, it is necessary for accurately tracking effects related to the active control when interacting with UI elements. + +As a result, this function should only ever be utilized within custom UI code. diff --git a/web/docs/engine/reference/core/addEventListener.md b/web/docs/engine/reference/core/addEventListener.md new file mode 100644 index 0000000000..10a7318260 --- /dev/null +++ b/web/docs/engine/reference/core/addEventListener.md @@ -0,0 +1,46 @@ +--- +title: addEventListener +--- + +## Summary + +Adds an event listener for user-handling of KeymanWeb events. + +## Syntax + +```c +keyman.addEventListener(event, func); +``` + +### Parameters + +`event` +: Type: `string` +: The name of an event to be generated by the `keyman` object. Please see the [Events section](../events) for more details and examples. + +`func` +: Type: `function` +: A function to be called when the event is raised. This function should expect a single parameter, which will be set to the originally-generated event object. + +### Return Value + +`boolean` +: Returns `true` if successful, otherwise `false`. + +## Description + +--- +**Note:** Standard HTML element events for the KeymanWeb element (focus, +blur, keydown, keypress, etc.) may be intercepted and used to modify the +user interface as necessary. User-defined event handlers should normally +return true to allow other event handling to be processed normally. + +--- + +## Example + +```c +keyman.addEventListener('focus', function(e) { + console.log("Now handling input for control " + e.target "!"); +}); +``` diff --git a/web/docs/engine/reference/core/addHotKey.md b/web/docs/engine/reference/core/addHotKey.md new file mode 100644 index 0000000000..67be15c65c --- /dev/null +++ b/web/docs/engine/reference/core/addHotKey.md @@ -0,0 +1,35 @@ +--- +title: addHotKey +--- + +## Summary + +Add hot key handler to array of document-level hotkeys triggered by key-up event. + +## Syntax + +```c +keyman.addHotKey(keyCode, shiftState, handler); +``` + +### Parameters + +`keyCode` +: Type: `number` +: The base key of the hotkey + +`shiftState` +: Type: `number` +: `shiftState` is a bitwise combination of SHIFT (0x10), CTRL (0x20) and ALT (0x40). + +`handler` +: Type: `function` +: The function to be called when the hotkey is triggered. It should not expect any parameters. + +### Return Value + +`undefined` + +## Description + +Used to support custom hotkeys within a web document. Only one handler function may exist per hotkey combination. diff --git a/web/docs/engine/reference/core/addKeyboards.md b/web/docs/engine/reference/core/addKeyboards.md new file mode 100644 index 0000000000..4a2dc77f5d --- /dev/null +++ b/web/docs/engine/reference/core/addKeyboards.md @@ -0,0 +1,179 @@ +--- +title: addKeyboards function +--- + +## Summary + +Adds keyboards to KeymanWeb. + +## Syntax + +```js +keyman.addKeyboards(spec[, spec...]) +``` + +### Parameters + +`spec` + +: Type: `string|Object` + + keyboard name string or keyboard metadata JSON object + +### Return Value + +`Promise`: A [JavaScript Promise](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) +fulfilled upon adding keyboards. + +The promise is an array containing a combination of the following: +* successfully registered keyboard objects which define some or all of these [properties](../keyboard_properties) +* [ErrorStub](../keyboard_registration_errors) objects for keyboards that failed to register + +## Description + +The keyboard spec can be a string or an object. Multiple keyboard specs can be +specified in a single call, which can reduce the round-trip cost of multiple +calls to Keyman Cloud servers (when using Keyman Cloud). + +For general information and example uses of this method, please see the [Adding Keyboards](../../guide/adding-keyboards) page from the guide section. + +### Using a `string` + +When keyboard spec is a string, the Keyman Cloud is used to source the keyboard +file. Keymanweb will load webfonts and keyboard file automatically on demand. +The string format is one of the following: + +* `'keyboardID'`: Adds a specific keyboard, linking it to the default language for the keyboard +* `'@languageID'`: Adds the default keyboard for the specified BCP 47 language code +* `'keyboardID@languageID'`: Loads a specific keyboard + language combination + +The keyboard catalogue is online at +[http://keyman.com/developer/keymanweb/keyboards](http://keyman.com/developer/keymanweb/keyboards). + +### Using an `object` + +When keyboard spec is an object, then more parameters can be specified, +including sourcing the keyboard from locations other than the Keyman Cloud. The +specification of the object is related to the Keyman Cloud JSON API (formerly +known as KeymanWeb Server Data API): + +The `spec` object contains the following members: + + +`name` + +: `string` + + Name of the keyboard. + +`id` + +: `string` + + ID (internal name) of keyboard, together with version always matches the + filename of the keyboard + +`filename` + +: `string` + + url of keyboard *.js file, relative (to page) or absolute + +`languages` + +: `array|object` + + An array of objects (see definition below) or single object linked to the + keyboard. + +`rtl` + +: `boolean` optional + + `true` if the keyboard targets a right-to-left script. May be set to `false` + or left `undefined` otherwise. + +`version` + +: `string` optional + + Version of keyboard *.js file + +`displayName` + +: `string` optional + + A name to display in the spacebar of the keyboard; if omitted, use the + default [`spacebarText` option](init#init_options). + +--- + +The `spec.languages` object contains the following members: + +`name` + +: `string` + + Name of the language. + +`id` + +: `string` + + BCP 47 language code. + +`region` + +: `string` optional + + _Required_ when using the Toolbar UI. May be set with one of the following + region names: + + * `'World'` (`'un'`) + * `'Africa'` (`'af'`) + * `'Asia'` (`'as'`) + * `'Europe'` (`'eu'`) + * `'South America'` (`'sa'`) + * `'North America'` (`'na'`) + * `'Oceania'` (`'oc'`) + * `'Central America'` (`'ca'`) + * `'Middle East'` (`'me'`) + +`font` + +: `array|object` optional + + An array of Font objects (see definition below) or single object describing + fonts for input fields and the OSK (if `oskFont` is not present.) + +`oskFont` + +: `array|object` optional + + An array of Font objects (see `font` definition below) or single object + describing fonts for the OSK. + +--- + +The `spec.languages.font` object contains the following members: + +`family` + +: `string` + + Font family that KeymanWeb will provide for this font. + +`filename` + +: `array` + + Array of URLs where font resources can be accessed, relative to the [`fonts` + initialization property](init). Multiple font resources can be specified as + platform font format support varies and KeymanWeb will pick the most + appropriate for the platform. + +`size` + +: `string` optional + + Font size (in CSS dimensions). If not specified, then `1em` is used. diff --git a/web/docs/engine/reference/core/addKeyboardsForLanguage.md b/web/docs/engine/reference/core/addKeyboardsForLanguage.md new file mode 100644 index 0000000000..d06ce2ede2 --- /dev/null +++ b/web/docs/engine/reference/core/addKeyboardsForLanguage.md @@ -0,0 +1,44 @@ +--- +title: addKeyboardsForLanguage function +--- + +## Summary + +Add default or all keyboards for a given language to KeymanWeb. + +## Syntax + +```js +keyman.addKeyboardsForLanguage(spec[, spec...]) +``` + +### Parameters + +`spec` + +: Type: `string` + + Language name string. Appending `$` to the language name will cause all available keyboards for that language to be loaded rather than the default keyboard. + +### Return Value + +`Promise`: A [JavaScript Promise](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) +fulfilled upon adding keyboards. + +The promise is an array containing the following: +* successfully registered keyboard objects which define some or all of these [properties](../keyboard_properties) + +## Description + +The language spec is a string. Multiple language specs can also be +specified in a single call, which can reduce the round-trip cost of multiple +calls to Keyman Cloud servers (when using Keyman Cloud). + +The first call to `addKeyboardsForLanguage()` makes an additional call to the Keyman API to load the current list of keyboard/language associations. This determines the default keyboards that are added for the language. + +For general information and example uses of this method, please see the [Adding Keyboards](../../guide/adding-keyboards) page from the guide section. + +### Using a `string` + +For the given language specs, the Keyman Cloud is used to source the keyboard +file. diff --git a/web/docs/engine/reference/core/attachToControl.md b/web/docs/engine/reference/core/attachToControl.md new file mode 100644 index 0000000000..30f6a57a82 --- /dev/null +++ b/web/docs/engine/reference/core/attachToControl.md @@ -0,0 +1,48 @@ +--- +title: attachToControl +--- + +## Summary + +Attach KeymanWeb to HTML element (or IFrame). + +## Syntax + +```c +keyman.attachToControl(Pelem) +``` + +### Parameters + +`Pelem` +: Type: `Element` +: Element to which KeymanWeb will be attached. + +### Return Value + +`undefined` + +## Description + +There are two steps involved in enabling input handling with KeymanWeb +for any given control: *attachment* and *enablement*. The attachment +process validates a control's compatibility with KeymanWeb and +establishes special metadata within the system. This data is released if +the control is ever detached. The control will not receive special input +handling until the control is enabled within KeymanWeb. + +If `attachToControl()` is called on an element with the `'kmw-disabled'` +class property, it will only establish KeymanWeb's metadata for the +control and initialize the control in a disabled state. A later call to +`enableControl()` may be used to initialize input handling for it. +Otherwise, the control will be both attached and enabled. + +When the [initialization property `attachType`](init) is set to +`'auto'`, this function is called automatically for every control on the +page, even those dynamically added. However, when `attachType` is set to +`'manual'`, `attachToControl` must be explicitly called for each control +in need of KeymanWeb's input handling. + +## See also: +- [`keyman.detachFromControl()`](detachFromControl) +- [`keyman.enableControl()`](enableControl) diff --git a/web/docs/engine/reference/core/build.md b/web/docs/engine/reference/core/build.md new file mode 100644 index 0000000000..75824dd48d --- /dev/null +++ b/web/docs/engine/reference/core/build.md @@ -0,0 +1,29 @@ +--- +title: build +--- + +## Summary + +Denotes the release-version .patch component for the loaded KeymanWeb instance. + +## Syntax + +```c +keyman.build +``` + +## Type + +string + +### Access + +Read only + +### Return Value + +(for example) `14.0.1` + +## Description + +... diff --git a/web/docs/engine/reference/core/detachFromControl.md b/web/docs/engine/reference/core/detachFromControl.md new file mode 100644 index 0000000000..fbb50299c7 --- /dev/null +++ b/web/docs/engine/reference/core/detachFromControl.md @@ -0,0 +1,34 @@ +--- +title: detachFromControl +--- + +## Summary + +Detach KeymanWeb from HTML element (or IFrame). + +## Syntax + +```c +keyman.detachFromControl(Pelem); +``` + +### Parameters + +`Pelem` +: Type: `Element` +: Element for KeymanWeb to detach from, no longer handling input. + +### Return Value + +`undefined` + +## Description + +This function entirely detaches KeymanWeb from the specified control, +removing all specialized input handling and data tracking for the +element. As such, detaching effectively 'resets' the control's state +entirely, save for any previously-input text. + +For more information about attachment, see [`keyman.attachToControl()`](attachToControl). + +Contrast with [`keyman.disableControl()`](disableControl). diff --git a/web/docs/engine/reference/core/disableControl.md b/web/docs/engine/reference/core/disableControl.md new file mode 100644 index 0000000000..0be0d43649 --- /dev/null +++ b/web/docs/engine/reference/core/disableControl.md @@ -0,0 +1,41 @@ +--- +title: disableControl +--- + +## Summary + +Disables KeymanWeb input handling for the specified control. + +## Syntax + +```c +keyman.disableControl(Pelem) +``` + +### Parameters + +`Pelem` +: Type: `Element` +: Element to become KeymanWeb-disabled. + +### Return Value + +`undefined` + +## Description + +This function is used to explicitly disable KeymanWeb input handling for +a previously-attached control, adding the class `'kmw-disabled'` +property to the element as necessary. It will not, however, detach +KeymanWeb from the control, and any KeymanWeb-specific metadata will +persist until KeymanWeb is explicitly detached from the element. + +If `'kmw-disabled'` is added to the control via other means, +`disableControl()` will be called upon it automatically and +non-recursively. + +If called on an element in an unattached state, the `'kmw-disabled'` tag will be added to the element. + +## See also: +- [`keyman.detachFromControl()`](detachFromControl) +- [`keyman.enableControl()`](enableControl) diff --git a/web/docs/engine/reference/core/enableControl.md b/web/docs/engine/reference/core/enableControl.md new file mode 100644 index 0000000000..2ca4664462 --- /dev/null +++ b/web/docs/engine/reference/core/enableControl.md @@ -0,0 +1,45 @@ +--- +title: enableControl +--- + +## Summary + +Enables KeymanWeb input handling for the specified control. + +## Syntax + +```c +keyman.enableControl(Pelem) +``` + +### Parameters + +`Pelem` +: Type: `Element` +: Element to become KeymanWeb-enabled. + +### Return Value + +`undefined` + +## Description + +There are two steps involved in enabling input handling with KeymanWeb +for any given control: *attachment* and *enablement*. The attachment +process validates a control's compatibility with KeymanWeb and +establishes special metadata within the system. This data is released if +the control is ever detached. The control will not receive special input +handling unless the control is enabled within KeymanWeb. + +This function is used to explicitly enable KeymanWeb input handling for +a previously-attached control, removing the class `'kmw-disabled'` +property from the element as necessary. It will not, however, attach +KeymanWeb to the control. + +If `'kmw-disabled'` is removed from the control via other means, `enableControl()` will be called upon it automatically and non-recursively. + +If called on an element in an unattached state, the `'kmw-disabled'` tag will be removed from the element. + +## See also +- [`keyman.attachToControl()`](attachToControl) +- [`keyman.disableControl()`](disableControl) diff --git a/web/docs/engine/reference/core/focusLastActiveElement.md b/web/docs/engine/reference/core/focusLastActiveElement.md new file mode 100644 index 0000000000..54deb07f10 --- /dev/null +++ b/web/docs/engine/reference/core/focusLastActiveElement.md @@ -0,0 +1,25 @@ +--- +title: focusLastActiveElement +--- + +## Summary + +Restore the focus to the element active before input was moved to KeymanWeb. + +## Syntax + +```c +keyman.focusLastActiveElement() +``` + +### Parameters + +None. + +### Return Value + +`undefined` + +## Description + +... diff --git a/web/docs/engine/reference/core/getActiveKeyboard.md b/web/docs/engine/reference/core/getActiveKeyboard.md new file mode 100644 index 0000000000..900aa09f47 --- /dev/null +++ b/web/docs/engine/reference/core/getActiveKeyboard.md @@ -0,0 +1,22 @@ +--- +title: getActiveKeyboard +--- + +## Summary + +Get the internal name of the currently active keyboard. + +## Syntax + +```c +keyman.getActiveKeyboard() +``` + +### Parameters + +None. + +### Return Value + +`string` +: The ID (internal name) of the currently-active keyboard. diff --git a/web/docs/engine/reference/core/getActiveLanguage.md b/web/docs/engine/reference/core/getActiveLanguage.md new file mode 100644 index 0000000000..588ce805dd --- /dev/null +++ b/web/docs/engine/reference/core/getActiveLanguage.md @@ -0,0 +1,26 @@ +--- +title: getActiveLanguage +--- + +## Summary + +Get the language code for the currently selected language. + +## Syntax + +```c +keyman.getActiveLanguage() +``` + +### Parameters + +None. + +### Return Value + +`string` +: The active language's BCP 47 language code. + +## Description + +... diff --git a/web/docs/engine/reference/core/getKeyboard.md b/web/docs/engine/reference/core/getKeyboard.md new file mode 100644 index 0000000000..0d6f8eb52e --- /dev/null +++ b/web/docs/engine/reference/core/getKeyboard.md @@ -0,0 +1,79 @@ +--- +title: getKeyboard +--- + +## Summary + +Get keyboard meta data for the selected keyboard and language. + +## Syntax + +```c +keyman.getKeyboard(keyboardName, languageCode) +``` + +### Parameters + +`keyboardName` +: Type: `string` +: The ID (internal name) of the keyboard. + +`languageCode` +: Type: `string` *optional* +: The BCP 47 language code. + +### Return Value + +`Object` +: An object with metadata corresponding to the requested keyboard. + +## Description + +The `keyboard` object contains the following members: + +`Name` +: `string` +: User-friendly name of the keyboard. + +`InternalName` +: `string` +: Internal name of the keyboard. + +`LanguageName` +: `string` +: User-friendly name of the language actively tied to the keyboard. + +`LanguageCode` +: `string` +: The three-letter code used to internally represent the language. + +`RegionName` +: `string` +: The user-friendly name of the region of the world within which the language is predominantly found. + +`RegionCode` +: `string` +: The three-letter code representing the region. + +`CountryName` +: `string` *optional* +: The user-friendly name of the country in which the language is spoken. + +`CountryCode` +: `string` *optional* +: A three-letter code corresponding to the country. + +`KeyboardID` +: `string` *optional* +: *Deprecated.* A unique identifier for the keyboard. (Use 'InternalName' instead.) + +`Font` +: `string` *optional* +: The font packaged with the keyboard to support its use. + +`OskFont` +: `string` *optional* +: The font packaged with the keyboard to properly display specialized OSK characters. + +## See also +- [keyman.addKeyboards()](addKeyboards) and its documentation about keyboard specification objects. diff --git a/web/docs/engine/reference/core/getKeyboardForControl.md b/web/docs/engine/reference/core/getKeyboardForControl.md new file mode 100644 index 0000000000..e2b2049e5b --- /dev/null +++ b/web/docs/engine/reference/core/getKeyboardForControl.md @@ -0,0 +1,34 @@ +--- +title: getKeyboardForControl +--- + +## Summary + +Obtain the keyboard set for a specific control, if it exists. + +## Syntax + +```c +keyman.getKeyboardForControl(Pelem); +``` + +### Parameters + +`Pelem` +: Type: `Element` +: An HTML input control. + +### Return Value + +`string|null` +: If the control has independent keyboard settings, returns the ID (internal name) of a keyboard. Otherwise, returns `null`. + +## Description + +This function is useful for determining when a control has +independently-managed keyboard settings within KeymanWeb. **Note** that it +will return `null` otherwise, even if there is an active keyboard within +KeymanWeb. + +## See also +- [`keyman.setKeyboardForControl()`](setKeyboardForControl) contrast with [`keyman.getActiveKeyboard()`](getActiveKeyboard) diff --git a/web/docs/engine/reference/core/getKeyboards.md b/web/docs/engine/reference/core/getKeyboards.md new file mode 100644 index 0000000000..8d84521b31 --- /dev/null +++ b/web/docs/engine/reference/core/getKeyboards.md @@ -0,0 +1,29 @@ +--- +title: getKeyboards +--- + +## Summary + +Get details of currently installed keyboards. + +## Syntax + +```c +keyman.getKeyboards() +``` + +### Parameters + +None. + +### Return Value + +`Array` +: An array of specifications for the currently-installed keyboards. + +## Description + +See [keyman.getKeyboard()](getKeyboard) for detail on the returned keyboard specification objects. + +## See also +- [keyman.addKeyboards()](addKeyboards) diff --git a/web/docs/engine/reference/core/getLastActiveElement.md b/web/docs/engine/reference/core/getLastActiveElement.md new file mode 100644 index 0000000000..d34fc7ffa5 --- /dev/null +++ b/web/docs/engine/reference/core/getLastActiveElement.md @@ -0,0 +1,26 @@ +--- +title: getLastActiveElement +--- + +## Summary + +Return the last element activated before input was moved to KeymanWeb. + +## Syntax + +```c +keyman.getLastActiveElement(); +``` + +### Parameters + +None. + +### Return Value + +`Element` +: The last element activated before KeymanWeb activated. + +## Description + +... diff --git a/web/docs/engine/reference/core/getSavedKeyboard.md b/web/docs/engine/reference/core/getSavedKeyboard.md new file mode 100644 index 0000000000..dfffe2121b --- /dev/null +++ b/web/docs/engine/reference/core/getSavedKeyboard.md @@ -0,0 +1,26 @@ +--- +title: getSavedKeyboard +--- + +## Summary + +Get the (internal) keyboard name and language code of the most recently active keyboard, as stored in KeymanWeb's cookie management system. + +## Syntax + +```c +keyman.getSavedKeyboard(); +``` + +### Parameters + +None. + +### Return Value + +`string` +: Format: `Internal-Name:Language-Code` + +## Description + +This function is used to automatically restore the last keyboard selected by a user in order to restore it upon a new visit to the page KeymanWeb is embedded within. diff --git a/web/docs/engine/reference/core/getUIState.md b/web/docs/engine/reference/core/getUIState.md new file mode 100644 index 0000000000..402e482413 --- /dev/null +++ b/web/docs/engine/reference/core/getUIState.md @@ -0,0 +1,34 @@ +--- +title: getUIState +--- + +## Summary + +Get the KeymanWeb user interface activation state. + +## Syntax + +```c +keyman.getUIState() +``` + +### Parameters + +None. + +### Return Value + +`Object` +: A '`ui_state`' object specifying the UI's current activation state. Please see below for more details. + +## Description + +The `ui_state` object contains the following members: + +`activationPending` +: `boolean` +: Indicates that the KeymanWeb UI is being activated. + +`activated` +: `boolean` +: Indicates that the KeymanUI is presently active. diff --git a/web/docs/engine/reference/core/helpURL.md b/web/docs/engine/reference/core/helpURL.md new file mode 100644 index 0000000000..16f86eb3ca --- /dev/null +++ b/web/docs/engine/reference/core/helpURL.md @@ -0,0 +1,29 @@ +--- +title: helpURL +--- + +## Summary + +URL for keyboard help site (set by site developer). + +## Syntax + +```keyman +keyman.helpURL +``` + +### Type + +`string` + +### Access + +Read only + +### Return Value + +Presently set to [`"http://help.keymanweb.com/go"`](). + +## Description + +... diff --git a/web/docs/engine/reference/core/index.md b/web/docs/engine/reference/core/index.md new file mode 100644 index 0000000000..8ce45877fd --- /dev/null +++ b/web/docs/engine/reference/core/index.md @@ -0,0 +1,133 @@ +--- +title: Core Module +--- + +The KeymanWeb core module is exposed to the developer as `window.keyman`. + +[`build` Property](build) +: The release build of KeymanWeb. + + +[`version` Property](version) +: The version of KeymanWeb. + + +[`initialized` Property](initialized) +: Keymanweb core module initialization state. + + +[`activatingUI` Function](activatingUI) +: Set an internal flag to notify KeymanWeb of change in UI activation state. + + +[`addEventListener` Function](addEventListener) +: Adds an event listener for user-handling of keymanweb events. + + +[`addHotKey` Function](addHotKey) +: Add hot key handler to array of document-level hotkeys triggered by key-up event. + + +[`addKeyboards` Function](addKeyboards) +: Adds keyboards to keymanweb. + + +[`addKeyboardsForLanguage` Function](addKeyboardsForLanguage) +: Adds default or all keyboards for a given language to keymanweb. + + +[`attachToControl` Function](attachToControl) +: Attach KeymanWeb to HTML element (or IFrame). + + +[ `BuildVisualKeyboard` Function](BuildVisualKeyboard) +: Create a copy of the OSK for embedding in documentation or help page. + + +[`detachFromControl` Function](detachFromControl) +: Detach KeymanWeb from HTML element (or IFrame). + + +[`disableControl` Function](disableControl) +: Disables KeymanWeb input handling for the specified control. + + +[`enableControl` Function](enableControl) +: Enables KeymanWeb input handling for the specified control. + + +[`focusLastActiveElement` Function](focusLastActiveElement) +: Restore the focus to the element active before input was moved to KeymanWeb. + + +[`getActiveKeyboard` Function](getActiveKeyboard) +: Get the ID (internal name) of the currently active keyboard. + + +[`getActiveLanguage` Function](getActiveLanguage) +: Get the language code for the currently selected language. + + +[`getKeyboard` Function](getKeyboard) +: Get keyboard meta data for the selected keyboard and language. + + +[`getKeyboardForControl` Function](getKeyboardForControl) +: Obtain the keyboard set for a specific control, if it exists. + + +[`getKeyboards` Function](getKeyboards) +: Get details of currently installed keyboards. + + +[`getLastActiveElement` Function](getLastActiveElement) +: Return the last element activated before input was moved to KeymanWeb. + + +[`getSavedKeyboard` Function](getSavedKeyboard) +: Get the (internal) keyboard name and language code of the most recently active + keyboard. + + +[`getUIState` Function](getUIState) +: Get the KeymanWeb user interface activation state. + + +[`init` Function](init) +: Sets license key, selects user interface, and other KeymanWeb Options. + + +[`isChiral` Function](isChiral) +: Test if a given keyboard recognizes chiral modifier data, such as left-control vs right-control. + + +[`isCJK` Function](isCJK) +: Test if a given keyboard or keyboard stub (or the current keyboard) is for Chinese, Japanese, or Korean. + + +[`moveToElement` Function](moveToElement) +: Move input focus to user specified element. + + +[`removeEventListener` Function](removeEventListener) +: Removes a user-defined event handler. + + +[`removeHotKey` Function](removeHotKey) +: Remove hotkey handler from document's list of hotkey handlers. + + +[`removeKeyboards` Function](removeKeyboards) +: Removes keyboards (by ID) from KeymanWeb. + + +[`resetContext` Function](resetContext) +: Revert OSK to default layer and clear any deadkeys and modifiers + + +[`setActiveKeyboard` Function](setActiveKeyboard) +: Change the currently active keyboard. + + +[`setKeyboardForControl` Function](setKeyboardForControl) +: Associate control with independent keyboard settings initialized to a specific keyboard. diff --git a/web/docs/engine/reference/core/init.md b/web/docs/engine/reference/core/init.md new file mode 100644 index 0000000000..9f18301f8c --- /dev/null +++ b/web/docs/engine/reference/core/init.md @@ -0,0 +1,146 @@ +--- +title: init function +--- + +## Summary + +Initializes KeymanWeb and configures KeymanWeb Options. + +Note that this is an asynchronous operation. + +`keyman.init()` is automatically called after the page loads, with default +options, if it has not already been called by scripts on the page. It is safe to +call `keyman.init()` once more in this situation, in order to set additional +options. + +The [`keyman.initialized` property](initialized) may be checked to determine the +current initialization state of Keyman Engine for Web. + +You should not call functions other than `keyman.init()` until Keyman +initialization is complete. As `keyman.init()` returns a Promise, the Promise +fulfilment callback is the appropriate place to perform post-init steps. + +## Syntax + +```js +keyman.init(initOptions); +``` + +### Parameters + +`initOptions` + +: Type: `Object`. + + See the Description section below for the necessary object specification. + +### Return Value + +`Promise`: A [JavaScript Promise](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) +fulfilled upon full initialization. + +## Initialization Options + +The `initOptions` object may contain the following members: + +`ui` + +: `string|object` optional + + The user interface to be used on desktop devices. Default value: `'float'`. + Please see below for the specification of this parameter if using an object + value. + +`root` + +: `string` optional + + The folder KeymanWeb should consider root. Default value: `undefined`, which + sets `root` to the base folder where keymanweb.js is located. + +`resources` + +: `string` optional + + The image folder URL for UI resources. Default value: `[root]/resources`. + +`keyboards` + +: `string` optional + + The folder containing local keyboard resources if utilized. Default value: + `[root]/keyboards`. + +`fonts` + +: `string` optional + + Folder containing any embedded fonts required for keyboards or the OSK. + Default value: `[root]`. + +`attachType` + +: `string` optional + + Must be `undefined`, `'auto'`, or `'manual'`. Specifies the default behavior + for attaching KeymanWeb to any input elements on the webpage. + + * If `undefined`, KeymanWeb will default to 'manual' for mobile devices and + 'auto' for other devices. + * If `'auto'`, KeymanWeb will automatically attach to every non-disabled + control, even those added after page initialization. + * If `'manual'`, KeymanWeb must be instructed to attached manually to each + control it should handle input for. + +`setActiveOnRegister` + +: `boolean` optional + + Specifies whether KeymanWeb will set the newly registered keyboard as active. Default value `true`. + + * If `true`, KeymanWeb will automatically activate a keyboard when registered. + * If `false`, KeymanWeb will not activate a keyboard when registered. + + **Note:** Changed from `string` type to `boolean` type in KeymanWeb 17.0 ([#8458](https://github.com/keymanapp/keyman/pull/8458)). + +`useAlerts` + +: `boolean` optional + + Specifies whether KeymanWeb's alert feedback should be enabled. Default value `true`. + + * If `true`, KeymanWeb will display its default alerts. + * If `false`, KeymanWeb will not display its default alerts. Choose this if you wish to disable them or would prefer to customize your site's error feedback. + * In either case, any calls your page makes to `keyman.util.alert()` will not be blocked. This only affects calls built into KeymanWeb itself. + +`spacebarText` + +: `com.keyman.SpacebarText` optional + + If present, must be one of the following four constants: + * `KEYBOARD /*'keyboard'*/` - show the keyboard name in the spacebar + * `LANGUAGE /*'language'*/` - show the language name in the spacebar + * `LANGUAGE_KEYBOARD /*'languageKeyboard'*/` - show both language and + keyboard name in the spacebar, separated by hyphen + * `BLANK /*'blank'*/` - keep the spacebar blank + + Note that this may be overridden on a per-keyboard basis with the registration + property `displayName`. + + Default value: `LANGUAGE_KEYBOARD`. + +--- + +If setting `initOptions.ui` with an object value, it should be specified as +follows: + +`name` + +: `string` +: The name of the ui to utilize for non-mobile devices. + + +`right` + +: `boolean` optional +: A Float-UI-only option. Sets right-alignment of the UI. Defaults to false. diff --git a/web/docs/engine/reference/core/initialized.md b/web/docs/engine/reference/core/initialized.md new file mode 100644 index 0000000000..dd4dc8214b --- /dev/null +++ b/web/docs/engine/reference/core/initialized.md @@ -0,0 +1,40 @@ +--- +title: keyman.initialized +--- + +### Summary + +Keymanweb core module initialization state flag. + +### Syntax + +```js + keyman.initialized +``` + +### Type + +Integer + +### Access + +Read only + +### Return Value + +* `0`, if Keyman Engine for Web is not initialized +* `1`, if Keyman Engine for Web has started initialization +* `2`, if Keyman Engine for Web is completely initialized + +### Description + +The [`keyman.init()` function](init) is used to initialize Keyman. You can check +this flag to see what the current initialization status is. You should not call +functions other than `keyman.init()` until Keyman initialization is complete. As +`keyman.init()` returns a Promise, the Promise fulfilment callback is the +appropriate place to perform post-init steps. + +### History + +* 2.0: Keyman Engine for Web supports values `0`, `1`, or `2`. +* 16.0: Documentation updated to match implementation. diff --git a/web/docs/engine/reference/core/isCJK.md b/web/docs/engine/reference/core/isCJK.md new file mode 100644 index 0000000000..820bdcc135 --- /dev/null +++ b/web/docs/engine/reference/core/isCJK.md @@ -0,0 +1,28 @@ +--- +title: isCJK +--- + +## Summary + +Test if a given keyboard or keyboard stub (or the current keyboard) is for Chinese, Japanese, or Korean. + +## Syntax + +```c +keyman.isCJK(keyboard); +``` + +### Parameters + +`keyboard` +: Type: `object` *optional* +: A loaded keyboard. Defaults to the currently-active keyboard if not specified. + +### Return Value + +`boolean` +: `true` if the keyboard uses a pick list, as with the keyboards mentioned before, `false` if not. + +## Description + +East Asian keyboards (and some others) may use an IME with a "pick list" of characters, requiring special handling. diff --git a/web/docs/engine/reference/core/isChiral.md b/web/docs/engine/reference/core/isChiral.md new file mode 100644 index 0000000000..9605a0f9bd --- /dev/null +++ b/web/docs/engine/reference/core/isChiral.md @@ -0,0 +1,41 @@ +--- +title: isChiral +--- + +## Summary + +Test if a given keyboard recognizes chiral modifier data, such as +left-control vs right-control. + +## Syntax + +```c +keyman.isChiral(keyboard); +``` + +### Parameters + +`keyboard` +: Type: `string` *optional* +: The id (identifying name) of a keyboard. Defaults to the currently-active keyboard if not specified. + +### Return Value + +`boolean` +: `true` if the keyboard accepts chiral (left-vs-right) variants of CTRL and ALT, `false` if not. + +## Description + +The specified keyboard must have been fully loaded at some point for +this information to be accessible; otherwise it will return `false` +(non-chiral). It is always accurate for the currently-active keyboard. + +With the present system architecture, this is a bit complicated in that +a keyboard is only set to 'active' after the +[`keyboardloaded`](../events/keyman/keyboardloaded) event completes and +after the [`keyboardchange`](../events/keyman/keyboardchange) event has +completed for the first activation of a keyboard. However, both events +return the name of the keyboard involved in the event, and this can be +passed as an argument to `isChiral` from the +[`keyboardloaded`](../events/keyman/keyboardloaded) event's handler to +obtain the correct keyboard chirality information. diff --git a/web/docs/engine/reference/core/moveToElement.md b/web/docs/engine/reference/core/moveToElement.md new file mode 100644 index 0000000000..f850c03401 --- /dev/null +++ b/web/docs/engine/reference/core/moveToElement.md @@ -0,0 +1,30 @@ +--- +title: moveToElement +--- + +## Summary + +Move input focus to user specified element. + +## Syntax + +```c +keyman.moveToElement(Pelem); +``` + +### Parameters + +`Pelem` +: Type: `string|Element` +: Moves focus to the user-specified element, finding it by element id if necessary. + +### Return Value + +`undefined` + +## Description + +Touch-based input works through simulated input fields in KeymanWeb +rather than the original controls of the page. As a result, this +function should be used in place of the default `Pelem.focus()` method. +It is used internally to allow OSK-based iteration through controls. diff --git a/web/docs/engine/reference/core/removeEventListener.md b/web/docs/engine/reference/core/removeEventListener.md new file mode 100644 index 0000000000..a7e37a7b70 --- /dev/null +++ b/web/docs/engine/reference/core/removeEventListener.md @@ -0,0 +1,33 @@ +--- +title: removeEventListener +--- + +## Summary + +Removes a user-defined event handler. + +## Syntax + +```c +keyman.removeEventListener(event, func); +``` + +### Parameters + +`event` +: Type: `string` +: The name of an event generated by the `keyman` object. + +`func` +: Type: `function` +: A function currently set to handle that event when it is raised. + +### Return Value + +`undefined` + +## Description + +See also [`keyman.addEventListener()`](addEventListener). + +To be implemented. \ No newline at end of file diff --git a/web/docs/engine/reference/core/removeHotKey.md b/web/docs/engine/reference/core/removeHotKey.md new file mode 100644 index 0000000000..3c0a9d0afa --- /dev/null +++ b/web/docs/engine/reference/core/removeHotKey.md @@ -0,0 +1,31 @@ +--- +title: removeHotKey +--- + +## Summary + +Remove the hotkey handler from document's list of hotkey handlers. + +## Syntax + +```c +keyman.removeHotkey(keyCode, shiftState); +``` + +### Parameters + +`keyCode` +: Type: `number` +: The base key code for the hotkey. + +`shiftState` +: Type: `number` +: The modifier values corresponding to ALT, CTRL, and SHIFT for the hotkey. + +### Return Value + +`undefined` + +## Description + +See also [`keyman.addHotKey()`](addHotKey). diff --git a/web/docs/engine/reference/core/removeKeyboards.md b/web/docs/engine/reference/core/removeKeyboards.md new file mode 100644 index 0000000000..03a14d5e24 --- /dev/null +++ b/web/docs/engine/reference/core/removeKeyboards.md @@ -0,0 +1,30 @@ +--- +title: removeKeyboards +--- + +## Summary + +Removes keyboards (by ID) from KeymanWeb. + +## Syntax + +```c +keyman.removeKeyboards(id[, id2, ...]) +``` + +### Parameters + +`id` +: Type: `string` +: keyboard name string + +### Return Value + +`boolean` +: `true` if all keyboards were successfully removed, otherwise `false`. + +## Description + +Allows a web page designer to dynamically remove keyboards from KeymanWeb by their ID(s). + +If the value `false` is returned, it is most likely that at least one specified keyboard was not actively loaded in KeymanWeb at the time of the call. diff --git a/web/docs/engine/reference/core/resetContext.md b/web/docs/engine/reference/core/resetContext.md new file mode 100644 index 0000000000..4d81dbd0db --- /dev/null +++ b/web/docs/engine/reference/core/resetContext.md @@ -0,0 +1,25 @@ +--- +title: resetContext +--- + +## Summary + +Revert OSK to default layer and clear any deadkeys and modifiers. + +## Syntax + +```c +keyman.resetContext(); +``` + +### Parameters + +None. + +### Return Value + +`undefined` + +## Description + +... diff --git a/web/docs/engine/reference/core/setActiveKeyboard.md b/web/docs/engine/reference/core/setActiveKeyboard.md new file mode 100644 index 0000000000..bdd33b0509 --- /dev/null +++ b/web/docs/engine/reference/core/setActiveKeyboard.md @@ -0,0 +1,34 @@ +--- +title: setActiveKeyboard +--- + +## Summary + +Change the currently active keyboard. + +## Syntax + +```c +keyman.setActiveKeyboard(keyboardName, languageCode); +``` + +### Parameters + +`keyboardName` +: Type: `string` +: The ID (internal name) of the keyboard to be set as active. + +`languageCode` +: Type: `string` *optional* +: The BCP 47 code for the keyboard's language. + +### Return Value + +`Promise` +: A [JavaScript Promise](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) fulfilled upon successfully linking and activating the keyboard. + +## Description + +Calls to `setActiveKeyboard` are asynchronous for keyboards not previously set as active. + +Use the `internalName` and `languageCode` keyboard variables. If `languageCode` is defaulted, `setActiveKeyboard` will select the language code for the first matching keyboard stub. diff --git a/web/docs/engine/reference/core/setKeyboardForControl.md b/web/docs/engine/reference/core/setKeyboardForControl.md new file mode 100644 index 0000000000..e1243d97cd --- /dev/null +++ b/web/docs/engine/reference/core/setKeyboardForControl.md @@ -0,0 +1,47 @@ +--- +title: setKeyboardForControl +--- + +## Summary + +Associate control with independent keyboard settings initialized to a specific keyboard. + +## Syntax + +```c +keyman.setDefaultKeyboardForControl(Pelem, keyboard, languageCode); +``` + +### Parameters + +`Pelem` +: Type: `Element` +: The control element to be managed manually. + +`keyboard` +: Type: `string` *optional* +: The ID (internal name) of a keyboard. + +`languageCode` +: Type: `string` *optional* +: The three-letter language code for the keyboard. + +### Return Value + +`undefined` + +## Description + +This function establishes the control with separately-managed keyboard +settings from other, non-specialized controls on the page. This may be +undone by setting both `keyboard` and `languageCode` to null, reverting +the control back to default keyboard-management behavior. + +Note that either **both** parameters should be set or **neither**. In +particular, if `languageCode` is specified but not `keyboard`, this +method will not automatically select an appropriate keyboard, even if +one has previously been registered with that language code. + +Due to system limitations, this function will fail if called on an IFRAME element. + +See also [Control-by-Control Example (guide)](../../guide/examples/control-by-control) diff --git a/web/docs/engine/reference/core/version.md b/web/docs/engine/reference/core/version.md new file mode 100644 index 0000000000..7df0978ac8 --- /dev/null +++ b/web/docs/engine/reference/core/version.md @@ -0,0 +1,29 @@ +--- +title: version +--- + +## Summary + +The version number of the loaded KeymanWeb instance. + +## Syntax + +```c +keyman.version +``` + +### Type + +string + +### Access + +Read only + +### Return Value + +`'18.0'` (for KeymanWeb 18.0) + +## Description + +... diff --git a/web/docs/engine/reference/events/index.md b/web/docs/engine/reference/events/index.md new file mode 100644 index 0000000000..df7538c2c1 --- /dev/null +++ b/web/docs/engine/reference/events/index.md @@ -0,0 +1,110 @@ +--- +title: Events - Keyman Engine for Web +--- + +A number of events are exposed to allow the designer of a user +interface to control the appearance and behavior of user interface +elements. Standard event-processing requires all arguments to be passed +as an array (object) with named member variables. + +Two components of Keyman Engine for Web specify events: +* `keyman` object -- the main component +* `keyman.osk` object -- the on-screen keyboard component + +Object events are handled in user code by passing the handler entry to +the object, using *addEventListener()*. + +--- + +### `keyman` events + +[`beforekeyboardchange`](keyman/beforekeyboardchange) +: Called when keyboard input language about to change. + + + +[`controlblurred`](keyman/controlblurred) +: Called when input element loses focus. + + + +[`controlfocused`](keyman/controlfocused) +: Called when input element receives focus. + + + +[`keyboardchange`](keyman/keyboardchange) +: Called when keyboard input language changed. + + + +[`keyboardloaded`](keyman/keyboardloaded) +: Called when keyboard code loaded. + + +[`keyboardregistered`](keyman/keyboardregistered) +: Called when keyboard 'stub' processed (for listing as available + keyboard). + + + +[`loaduserinterface`](keyman/loaduserinterface) +: Called when allow ui initialization. + + + +[`unloaduserinterface`](keyman/unloaduserinterface) +: Called when allow ui clean-up. + +For example, to define a user function to handle the KeymanWeb +`keyboardchange` event, include: + +``` typescript +keyman.addEventListener('keyboardchange', + function(p) + { + ui.updateMenu(p.internalName,p.languageCode); + }); + +``` + +--- + +### `keyman.osk` On Screen Keyboard events + +[`configclick`](osk/configclick) +: Called when allows the UI to present KeymanWeb configuration + options. + + + +[`helpclick`](osk/helpclick) +: Called when allows the UI to present a help page. + + + +[`hide`](osk/hide) +: Called when OSK hidden. + + + +[`resizemove`](osk/resizemove) +: Called when OSK resized or moved on desktop. + + + +[`show`](osk/show) +: Called when OSK displayed. + + +For example, to add an event handler that modifies the user interface when the on-screen +keyboard is displayed: + +``` typescript +keyman.osk.addEventListener('show', + function(p) + { + ui.updateUI(p.x, p.y, p.userLocated); + }); + +``` diff --git a/web/docs/engine/reference/events/keyman/beforekeyboardchange.md b/web/docs/engine/reference/events/keyman/beforekeyboardchange.md new file mode 100644 index 0000000000..6fad014400 --- /dev/null +++ b/web/docs/engine/reference/events/keyman/beforekeyboardchange.md @@ -0,0 +1,36 @@ +--- +title: keyman.beforekeyboardchange Event +--- + +## Summary + +Called when keyboard input language is about to change. + +## Syntax + +``` +keyman.addEventListener('beforekeyboardchange', function(keyboardProperties) { + ... +}); +``` + +### Parameters + +`keyboardProperties` +: Type: `object` +: An object with the following properties: + +: - `internalName` - the keyboard's name + +: - `languageCode` - its BCP 47 language code. + +### Return Value + +`boolean` +: `true` if the event should continue processing, `false` if it should + not. Your event handler should return `true` aside from exceptional + circumstances. + +## Description + +This event is designed to be used with UI modules. diff --git a/web/docs/engine/reference/events/keyman/controlblurred.md b/web/docs/engine/reference/events/keyman/controlblurred.md new file mode 100644 index 0000000000..bb42a2b548 --- /dev/null +++ b/web/docs/engine/reference/events/keyman/controlblurred.md @@ -0,0 +1,38 @@ +--- +title: keyman.controlblurred Event +--- + +## Summary + +Called when an input element loses focus. + +## Syntax + +``` +keyman.addEventListener('controlblurred', function(eventProperties) { + ... +}); +``` + +### Parameters + +`eventProperties` +: Type: `object` +: An object with the following properties: + +: - `target` - the element losing focus + +: - `event` - the original event object generated by the web page. + +: - `isActivating` - the activation state of the UI element(s). + +### Return Value + +`boolean` +: `true` if the event should continue processing, `false` if it should + not. Your event handler should return `true` aside from exceptional + circumstances. + +## Description + +This event is used by various KeymanWeb UI elements. diff --git a/web/docs/engine/reference/events/keyman/controlfocused.md b/web/docs/engine/reference/events/keyman/controlfocused.md new file mode 100644 index 0000000000..34525f0fed --- /dev/null +++ b/web/docs/engine/reference/events/keyman/controlfocused.md @@ -0,0 +1,36 @@ +--- +title: keyman.controlfocused Event +--- + +## Summary + +Called when an input element receives focus. + +## Syntax + +``` +keyman.addEventListener('controlfocused', function(eventProperties) { + ... +}); +``` + +### Parameters + +`eventProperties` +: Type: `object` +: An object with the following properties: + +: - `target` - the element gaining focus + +: - `event` - the currently active control. + +### Return Value + +`boolean` +: `true` if the event should continue processing, `false` if it should + not. Your event handler should return `true` aside from exceptional + circumstances. + +## Description + +This event is used by various KeymanWeb UI elements. diff --git a/web/docs/engine/reference/events/keyman/index.md b/web/docs/engine/reference/events/keyman/index.md new file mode 100644 index 0000000000..953956f130 --- /dev/null +++ b/web/docs/engine/reference/events/keyman/index.md @@ -0,0 +1,43 @@ +--- +title: keyman events +--- + +[`beforekeyboardchange`](beforekeyboardchange) +: Called when keyboard input language about to change. + + + +[`controlblurred`](controlblurred) +: Called when input element loses focus. + + + +[`controlfocused`](controlfocused) +: Called when input element receives focus. + + + +[`keyboardchange`](keyboardchange) +: Called when keyboard input language changed. + + + +[`keyboardloaded`](keyboardloaded) +: Called when keyboard code loaded. + + +[`keyboardregistered`](keyboardregistered) +: Called when keyboard 'stub' processed (for listing as available + keyboard). + + + +[`loaduserinterface`](loaduserinterface) +: Called when allow ui initialization. + + + +[`unloaduserinterface`](unloaduserinterface) +: Called when allow ui clean-up. + +[Return to main `events` index](..) \ No newline at end of file diff --git a/web/docs/engine/reference/events/keyman/keyboardchange.md b/web/docs/engine/reference/events/keyman/keyboardchange.md new file mode 100644 index 0000000000..0d4570257f --- /dev/null +++ b/web/docs/engine/reference/events/keyman/keyboardchange.md @@ -0,0 +1,37 @@ +--- +title: keyman.keyboardchange Event +--- + +## Summary + +Called when keyboard input language changed. + +## Syntax + +``` +keyman.addEventListener('keyboardchange', function(keyboardProperties) { + ... +}); +``` + +### Parameters + +`keyboardProperties` +: Type: `object` +: An object with the following properties: + +: - `internalName` - the keyboard's name + +: - `languageCode` - its BCP 47 language code. + +### Return Value + +`boolean` +: `true` if the event should continue processing, `false` if it should + not. Your event handler should return `true` aside from exceptional + circumstances. + +## Description + +This event is utilized by the various non-mobile UI elements included +with KeymanWeb. diff --git a/web/docs/engine/reference/events/keyman/keyboardloaded.md b/web/docs/engine/reference/events/keyman/keyboardloaded.md new file mode 100644 index 0000000000..7b0a65b882 --- /dev/null +++ b/web/docs/engine/reference/events/keyman/keyboardloaded.md @@ -0,0 +1,35 @@ +--- +title: keyman.keyboardloaded Event +--- + +## Summary + +Called when keyboard code loaded. + +## Syntax + +``` +keyman.addEventListener('keyboardloaded', function(keyboardProperties) { + ... +}); +``` + +### Parameters + +`keyboardProperties` +: Type: `object` +: An object with the following property: + +: - `keyboardName` - the keyboard's name. + +### Return Value + +`boolean` +: `true` if the event should continue processing, `false` if it should + not. Your event handler should return `true` aside from exceptional + circumstances. + +## Description + +This event is only raised once a keyboard has been fully loaded and +processed, ready for active use. diff --git a/web/docs/engine/reference/events/keyman/keyboardregistered.md b/web/docs/engine/reference/events/keyman/keyboardregistered.md new file mode 100644 index 0000000000..b92ca767d9 --- /dev/null +++ b/web/docs/engine/reference/events/keyman/keyboardregistered.md @@ -0,0 +1,43 @@ +--- +title: keyman.keyboardregistered Event +--- + +## Summary + +Called when a keyboard 'stub' is processed (for listing as available +keyboard). + +## Syntax + +``` +keyman.addEventListener('keyboardregistered', function(keyboardProperties) { + ... +}); +``` + +### Parameters + +`keyboardProperties` +: Type: `object` +: An object with the following properties: + +: - `internalName` - the keyboard's id + +: - `language` - its corresponding language. + +: - `keyboardName` - the keyboard's name + +: - `languageCode` - its BCP 47 language code. + +### Return Value + +`boolean` +: `true` if the event should continue processing, `false` if it should + not. Your event handler should return `true` aside from exceptional + circumstances. + +## Description + +This event is used by all the UI elements in order to update the list of +available keyboards as soon as a new keyboard stub has been registered, +before any attempt to load it has been made. diff --git a/web/docs/engine/reference/events/keyman/loaduserinterface.md b/web/docs/engine/reference/events/keyman/loaduserinterface.md new file mode 100644 index 0000000000..094df102e5 --- /dev/null +++ b/web/docs/engine/reference/events/keyman/loaduserinterface.md @@ -0,0 +1,30 @@ +--- +title: keyman.loaduserinterface Event +--- + +## Summary + +Called to initiate the ui initialization process. + +## Syntax + +``` +keyman.addEventListener('loaduserinterface', function() { + ... +}); +``` + +### Parameters + +None. + +### Return Value + +`boolean` +: `true` if the event should continue processing, `false` if it should + not. Your event handler should return `true` aside from exceptional + circumstances. + +## Description + +... diff --git a/web/docs/engine/reference/events/keyman/unloaduserinterface.md b/web/docs/engine/reference/events/keyman/unloaduserinterface.md new file mode 100644 index 0000000000..db44244b5b --- /dev/null +++ b/web/docs/engine/reference/events/keyman/unloaduserinterface.md @@ -0,0 +1,31 @@ +--- +title: keyman.unloaduserinterface Event +--- + +## Summary + +Called when allow ui clean-up. + +## Syntax + +``` +keyman.addEventListener('unloaduserinterface', function() { + ... +}); +``` + +### Parameters + +None. + +### Return Value + +`boolean` +: `true` if the event should continue processing, `false` if it should + not. Your event handler should return `true` aside from exceptional + circumstances. + +## Description + +Called when the ui is to be unloaded, allowing cleanup of resources if +necessary. diff --git a/web/docs/engine/reference/events/osk/configclick.md b/web/docs/engine/reference/events/osk/configclick.md new file mode 100644 index 0000000000..a4ccba9446 --- /dev/null +++ b/web/docs/engine/reference/events/osk/configclick.md @@ -0,0 +1,32 @@ +--- +title: osk.configclick Event +--- + +## Summary + +Called upon user request for the UI to present KeymanWeb configuration +options. + +## Syntax + +``` +keyman.osk.addEventListener('configclick', function() { + ... +}); +``` + +### Parameters + +None. + +### Return Value + +`boolean` +: `true` if the event should continue processing, `false` if it should + not. Your event handler should return `true` aside from exceptional + circumstances. + +## Description + +This event is raised when the user wishes to access configuration +options. diff --git a/web/docs/engine/reference/events/osk/helpclick.md b/web/docs/engine/reference/events/osk/helpclick.md new file mode 100644 index 0000000000..7e7a27d242 --- /dev/null +++ b/web/docs/engine/reference/events/osk/helpclick.md @@ -0,0 +1,31 @@ +--- +title: osk.helpclick Event +--- + +## Summary + +Called upon user request for the UI to present a help page. + +## Syntax + +``` +keyman.osk.addEventListener('helpclick', function() { + ... +}); +``` + +### Parameters + +None. + +### Return Value + +`boolean` +: `true` if the event should continue processing, `false` if it should + not. Your event handler should return `true` aside from exceptional + circumstances. + +## Description + +This event is raised whenever the user wishes to access help +information. diff --git a/web/docs/engine/reference/events/osk/hide.md b/web/docs/engine/reference/events/osk/hide.md new file mode 100644 index 0000000000..77af0b65d1 --- /dev/null +++ b/web/docs/engine/reference/events/osk/hide.md @@ -0,0 +1,33 @@ +--- +title: osk.hide Event +--- + +## Summary + +Called when the OSK is hidden. + +## Syntax + +``` +keyman.osk.addEventListener('hide', function(param) { + ... +}); +``` + +### Parameters + +`param` +: Type: `Object` +: An object with field HiddenByUser, a `boolean` which indicates if + the OSK was hidden directly by the user's actions. + +### Return Value + +`boolean` +: `true` if the event should continue processing, `false` if it should + not. Your event handler should return `true` aside from exceptional + circumstances. + +## Description + +... diff --git a/web/docs/engine/reference/events/osk/index.md b/web/docs/engine/reference/events/osk/index.md new file mode 100644 index 0000000000..7edeef819d --- /dev/null +++ b/web/docs/engine/reference/events/osk/index.md @@ -0,0 +1,29 @@ +--- +title: OSK events +--- + +[`configclick`](configclick) +: Called when allows the UI to present KeymanWeb configuration + options. + + + +[`helpclick`](helpclick) +: Called when allows the UI to present a help page. + + + +[`hide`](hide) +: Called when OSK hidden. + + + +[`resizemove`](resizemove) +: Called when OSK resized or moved on desktop. + + + +[`show`](show) +: Called when OSK displayed. + +[Return to main `events` index](..) \ No newline at end of file diff --git a/web/docs/engine/reference/events/osk/resizemove.md b/web/docs/engine/reference/events/osk/resizemove.md new file mode 100644 index 0000000000..c6211a3200 --- /dev/null +++ b/web/docs/engine/reference/events/osk/resizemove.md @@ -0,0 +1,30 @@ +--- +title: osk.resizemove Event +--- + +## Summary + +Called when OSK resized or moved on desktop. + +## Syntax + +``` +keyman.osk.addEventListener('resizemove', function() { + ... +}); +``` + +### Parameters + +None. + +### Return Value + +`boolean` +: `true` if the event should continue processing, `false` if it should + not. Your event handler should return `true` aside from exceptional + circumstances. + +## Description + +This event is raised whenever the OSK is moved. diff --git a/web/docs/engine/reference/events/osk/show.md b/web/docs/engine/reference/events/osk/show.md new file mode 100644 index 0000000000..3d2e67b4f3 --- /dev/null +++ b/web/docs/engine/reference/events/osk/show.md @@ -0,0 +1,50 @@ +--- +title: osk.show Event +--- + +## Summary + +Called when the OSK is displayed. + +## Syntax + +``` +keyman.osk.addEventListener('show', function(obj) { + ... +}); +``` + +### Parameters + +`obj` +: Type: `object` +: An object specifying the osk's display state information. + +Available display state information: + + + +`obj.x` +: `Number` +: The x-coordinate of the left side of the OSK. + +`obj.y` +: `Number` +: The y-coordinate of the top of the OSK. + +`obj.userLocated` +: `boolean` +: `true` if the OSK has been directly placed by the user. + + + +### Return Value + +`boolean` +: `true` if the event should continue processing, `false` if it should + not. Your event handler should return `true` aside from exceptional + circumstances. + +## Description + +... diff --git a/web/docs/engine/reference/index.md b/web/docs/engine/reference/index.md new file mode 100644 index 0000000000..74d83c3931 --- /dev/null +++ b/web/docs/engine/reference/index.md @@ -0,0 +1,42 @@ +--- +title: KeymanWeb 18.0 Reference +--- + +[KeymanWeb Overview](overview) +: KeymanWeb is a cross-browser JavaScript input method solution. + +[KeymanWeb Core Module](core) +: The KeymanWeb core module is exposed to the developer as `window.keyman`. + +[On-Screen Keyboard Module](osk) +: The On-Screen Keyboard module is exposed to the developer as `window.keyman.osk`. + +[KeymanWeb Utility Module](util) +: The KeymanWeb Utility Function module is exposed to the developer as `window.keyman.util`. + +[KeymanWeb Output Functions](interface) +: KeymanWeb exposes its keyboard interface object through `window.keyman.interface`, providing a number of functions for low-level processing of input, context and output. + +[KeymanWeb Compatibility Functions](compatibility) +: The following KeymanWeb core functions have been retained for compatibility with existing custom keyboards, but should not be used in any new keyboards or user interfaces. Equivalent new function calls are indicated. + +[Desktop User Interfaces](ui) +: Four different KeymanWeb user interfaces for desktop browsers are included, allowing users to select and enable keyboard mapping from a list of installed keyboards, and to control the visibility of the On-Screen Keyboard. + +[KeymanWeb Initialization Options](core/init#init_options) +: The following options can be defined by the site designer in the initialization call to KeymanWeb. + +[KeymanWeb Events](events) +: A number of KeymanWeb events are exposed to allow the designer of a user interface to control the appearance and behavior of user interface elements. Standard event-processing requires all arguments to be passed as an array (object) with named member variables. + +[KeymanWeb Keyboard Properties](keyboard_properties) +: Most keyboards are generated automatically from the Keyman keyboard source by Keyman Developer and contain properties used by KeymanWeb during keyboard mapping. + +[KeymanWeb Layout Designer](layouts) +: One of the main features of KeymanWeb is its ability to support distinct, user-customizable layouts for touch-screen keyboards on phones and tablets. + +[KeymanWeb Layout Specifications](layoutspec) +: Touch-screen layouts for KeymanWeb are specified as JSON objects containing a member object for each specified device type. + +[KeymanWeb Keyboard Development Reference](/developer/language/guide/multi-platform) +: Information on how to explicitly support KeymanWeb in custom keyboards. diff --git a/web/docs/engine/reference/interface/_nul.md b/web/docs/engine/reference/interface/_nul.md new file mode 100644 index 0000000000..4d20af049c --- /dev/null +++ b/web/docs/engine/reference/interface/_nul.md @@ -0,0 +1,42 @@ +--- +title: nul (KN) +--- + +## Summary + +[`nul`](/developer/language/reference/nul) context check: Returns `true` if the length of the [`context`](/developer/language/reference/context) is less than or equal to `n` characters. + +## Syntax + +```c +keyman.interface.nul(n, Pelem); +``` + +or + +```c +KeymanWeb.KN(n, Pelem); // Shorthand +``` + +### Parameters + +`n` +: Type: `number` +: The length of `context` to check. + +`Pelem` +: Type: `Element` +: The element whose `context` is being examined. + +### Return Value + +`boolean` +: `true` if the context is not longer than `n` characters, otherwise `false`. + +## Description + +This is of particular use in handling the [Developer rule `nul`](/developer/language/reference/nul) and is subject to the caveats listed therein. + +## See also + +- [`keyman.interface.context()`](context) diff --git a/web/docs/engine/reference/interface/any.md b/web/docs/engine/reference/interface/any.md new file mode 100644 index 0000000000..1bcc704046 --- /dev/null +++ b/web/docs/engine/reference/interface/any.md @@ -0,0 +1,62 @@ +--- +title: any (KA) (Deprecated) +--- + +## Summary + +(Deprecated) Returns whether or not the char `ch` is found within the [`any`](/developer/language/reference/any)([`store`](/developer/language/reference/store)) string, setting the internally-tracked index 'n' accordingly. + +## Syntax + +```c +keyman.interface.any(index, ch, storeText); +``` + +or + +```c +KeymanWeb.KA(index, ch, storeText); // Shorthand +``` + +### Parameters + +`index` +: Type: `number` +: The index id (starting from zero) at which the detected character will be internally tracked. + +`ch` +: Type: `string` +: The input character to find in the text store. + +`storeText` +: Type: `string` +: The contents of the specified text `store`. + +### Return Value + +`boolean` +: `true` if the input character has a match in the text store, otherwise `false`. + +## Description + +This function corresponds most directly to the keyboard language command [`any`](/developer/language/reference/any), which operates upon text [`store`](/developer/language/reference/store)s to allow for array-based input-output text matching. For example, + +```keyman +store(keys) 'abcde' +store(output) 'αβγδε' ++ any(keys) > index(output,1) +``` + +facilitates mapping the characters `'abcde'` to their respective entry in the output store `'αβγδε'`. `keyman.interface.any()`'s role in this process is usually optimized out into individual mappings for performance reasons, though it is often involved when `any` is involved as part of a rule's `context`, rather than upon the triggering keystroke itself. + +In order to check if the character `'a'` has a match in the `keys` store above, the code + +```c +keyman.interface.any(0, 'a', 'abcde') +``` + +would suffice, setting an internally-tracked index (id=0) to hold the index value 0. Note that the internally-tracked index (id=0) is decremented relative to the index appearing in the `index` call in the keyboard source above; the corresponding [`keyman.interface.indexOutput()`](indexOutput) call increments the id by 1 due to Keyman's keyboard language rules. + +## See also + +- [`keyman.interface.indexOutput()`](indexOutput) diff --git a/web/docs/engine/reference/interface/beep.md b/web/docs/engine/reference/interface/beep.md new file mode 100644 index 0000000000..b5f067c30f --- /dev/null +++ b/web/docs/engine/reference/interface/beep.md @@ -0,0 +1,33 @@ +--- +title: beep (KB) +--- + +## Summary + +Flash body or element as substitute for an audible feedback [`beep`](/developer/language/reference/beep). + +## Syntax + +```c +keyman.interface.beep(Pelem); +``` + +or + +```c +KeymanWeb.KB(Pelem); // Shorthand +``` + +### Parameters + +`Pelem` +: Type: `Element` +: The page element to be temporarily set flashing. + +### Return Value + +`undefined` + +## Description + +This function is designed to implement feedback for erroneous input sequences, as with the keyboard language [`beep`](/developer/language/reference/beep) command. The flashing feedback should last approximately 1/20 of a second. diff --git a/web/docs/engine/reference/interface/beepReset.md b/web/docs/engine/reference/interface/beepReset.md new file mode 100644 index 0000000000..dd840ce8e5 --- /dev/null +++ b/web/docs/engine/reference/interface/beepReset.md @@ -0,0 +1,31 @@ +--- +title: beepReset (KBR) +--- + +## Summary + +Cancels previous feedback [`beep`](/developer/language/reference/beep) operations across the page. + +## Syntax + +```c +keyman.interface.beepReset(); +``` + +or + +```c +KeymanWeb.KBR(); // Shorthand +``` + +### Parameters + +None. + +### Return Value + +`undefined` + +## Description + +The `keyman.interface.beepReset()` function is automatically called by [`keyman.interface.beep()`](beep) after a short interval (approximately 1/20 of a second) and should not need to be called manually. diff --git a/web/docs/engine/reference/interface/context.md b/web/docs/engine/reference/interface/context.md new file mode 100644 index 0000000000..982d19d538 --- /dev/null +++ b/web/docs/engine/reference/interface/context.md @@ -0,0 +1,60 @@ +--- +title: context (KC) (Deprecated) +--- + +## Summary + +(Deprecated) Gets [`context`](/developer/language/reference/context) for an ongoing keyboard operation relative to the caret's present position. + +## Syntax + +```c +keyman.interface.context(n, ln, Pelem); +``` + +or + +```c +KeymanWeb.KC(n, ln, Pelem); // Shorthand +``` + +### Parameters + +`n` +: Type: `number` +: Relative position of the caret for the context retrieval operation. + +`ln` +: Type: `number` +: Number of characters of text context to retrieve. + +`Pelem` +: Type: `Element` +: The element being operated upon. + +### Return Value + +`string` +: The requested [`context`](/developer/language/reference/context) text. + +## Description + +For an example from [Developer 'rules'](/developer/language/guide/rules), a keyboard might implement the following rule + +```keyman +"abc" + "d" > context(2) "D" +``` + +by first checking that the initial context (`"abc"`) matches and then using the following to fulfill the rule: + +```keyman +keyman.interface.output(3, Pelem, keyman.interface.context(2, 1, Pelem)); +keyman.interface.output(0, Pelem, "D"); +``` + +This operates by first replacing the original context `"abc"` with the requested subset of `context(2)`, then outputting the character (`"D"`) corresponding to the new keystroke. + +## See also + +- [`keyman.interface.contextMatch()`](contextMatch) +- [`keyman.interface.output()`](output) diff --git a/web/docs/engine/reference/interface/contextExOutput.md b/web/docs/engine/reference/interface/contextExOutput.md new file mode 100644 index 0000000000..35a1801088 --- /dev/null +++ b/web/docs/engine/reference/interface/contextExOutput.md @@ -0,0 +1,52 @@ +--- +title: contextExOutput (KCXO) +--- + +## Summary + +`contextExOutput` function emits the character or object at `contextOffset` from the +current matched rule's context. Introduced in Keyman 14.0, in order to resolve a +gap between desktop and web core functionality for `context(n)` matching on `notany()`. + +## Syntax + +```js + keyman.interface.contextExOutput(dn, outputTarget, contextLength, contextOffset); +``` + +or + +```js + KeymanWeb.KCXO(dn, outputTarget, contextLength, contextOffset); // Shorthand +``` + +## Parameters + +`dn` +: Type: `number` +: number of characters to delete left of cursor + +`outputTarget` +: Type: `OutputTarget` +: target to output to + +`contextLength` +: Type: `number` +: length of current rule context to retrieve + +`contextOffset` +: Type: `number` +: offset from start of current rule context, 1-based + +## Returns + +`void` + +## See also + +* [`keyman.interface.output()`](output) +* [`keyman.interface.indexOutput()`](indexOutput) + +## History + +* Introduced in Keyman 14.0 diff --git a/web/docs/engine/reference/interface/contextMatch.md b/web/docs/engine/reference/interface/contextMatch.md new file mode 100644 index 0000000000..84a5641864 --- /dev/null +++ b/web/docs/engine/reference/interface/contextMatch.md @@ -0,0 +1,67 @@ +--- +title: contextMatch (KCM) (Deprecated) +--- + +## Summary + +(Deprecated) Context matching: Returns `true` if `context(n,ln,elem) == val`. + +## Syntax + +```keyman +keyman.interface.contextMatch(n, Pelem, val, ln); +``` + +or + +```keyman +KeymanWeb.KCM(n, Pelem, val, ln); // Shorthand +``` + +### Parameters + +`n` +: Type: `number` +: Relative position of the caret for the context match attempt. + +`Pelem` +: Type: `Element` +: The element being operated upon. + +`val` +: Type: `string` +: The desired text value for context to match. + +`ln` +: Type: `number` +: Number of characters of text context to match. + +### Return Value + +`boolean` +: `true` if the context matches the specified value `val`, otherwise `false`. + +## Description + +This is a core element of keyboard input management within KeymanWeb in versions prior to 10.0, typically called automatically during keystroke processing events. For comparison with [Developer 'rules'](/developer/language/guide/rules) from keyboard source code, in the rule + +```keyman +"a" + "'" > "á" +``` + +a keyboard would check that the initial context (`"a"`) matches by using + +```keyman +keyman.interface.contextMatch(1, Pelem, "a", 1) +``` + +which checks, starting at the first character to the left of the caret, a single character to see if it matches the value "a". + +For versions 10.0 and later, please consider use of [`fullContextMatch()`](fullContextMatch) instead. + +## See also + +- [`fullContextMatch()`](fullContextMatch) +- [`keyman.interface.context()`](context) +- [`keyman.interface.output()`](output) +- [`keyman.interface.keyMatch()`](keyMatch) diff --git a/web/docs/engine/reference/interface/deadkeyMatch.md b/web/docs/engine/reference/interface/deadkeyMatch.md new file mode 100644 index 0000000000..1307a82e96 --- /dev/null +++ b/web/docs/engine/reference/interface/deadkeyMatch.md @@ -0,0 +1,71 @@ +--- +title: deadkeyMatch (KDM) (Deprecated) +--- + +## Summary + +(Deprecated)Deadkey matching: Seeks to match the [`deadkey`](/developer/language/reference/deadkey) state `dk` at the relative caret position `n`. + +## Syntax + +```c +keyman.interface.deadkeyMatch(n, Pelem, dk); +``` + +or + +```c +KeymanWeb.KDM(n, Pelem, dk); // Shorthand +``` + +### Parameters + +`n` +: Type: `number` +: The position to match, relative to the caret's present position. + +`Pelem` +: Type: `Element` +: The HTML element receiving input. + +`dk` +: Type: `number` +: The deadkey id. + +### Return Value + +`boolean` +: `true` if the specified deadkey exists at the specified input location, otherwise `false`. + +## Description + +Deadkeys are useful for tracking hidden state information used to modify future keystrokes. For example, rather than using + +```keyman +"`" + "a" = "à" +``` + +to combine two visible characters, certain applications may desire to keep the `` "`" `` character hidden with a rule such as + +```keyman ++ '`' > dk(backquote) + +... + +dk(backquote) + "a" > "à" +``` + +The Developer compiler then generates a unique id for the deadkey state - say, `0`, and in order to detect the deadkey associated with the `` '`' `` character, compiles the `dk(backquote)` check to + +```c +keyman.interface.deadkeyMatch(0, Pelem, 0) +``` + +which detects the existing deadkey (the second zero above) at the caret's present position (the first zero above). + +For versions 10.0 and later, please consider use of [`fullContextMatch()`](fullContextMatch) instead. + +## See also + +- [`keyman.interface.deadkeyOutput()`](deadkeyOutput) +- [Wikipedia article on deadkeys](https://en.wikipedia.org/wiki/Dead_key) diff --git a/web/docs/engine/reference/interface/deadkeyOutput.md b/web/docs/engine/reference/interface/deadkeyOutput.md new file mode 100644 index 0000000000..36c6de624d --- /dev/null +++ b/web/docs/engine/reference/interface/deadkeyOutput.md @@ -0,0 +1,66 @@ +--- +title: deadkeyOutput (KDO) +--- + +## Summary + +Deadkey output: Associates the [`deadkey`](/developer/language/reference/deadkey) state `dk` with the element at the current caret position, after overwriting `nd` characters. + +## Syntax + +```c +keyman.interface.deadkeyOutput(nd, Pelem, dk); +``` + +or + +```c +KeymanWeb.KDO(nd, Pelem, dk); // Shorthand +``` + +### Parameters + +`nd` +: Type: `number` +: The number of characters to overwrite (delete). May be set to `-1` or `0` to prevent overwrites. + +`Pelem` +: Type: `Element` +: The element receiving output. + +`dk` +: Type: `number` +: The deadkey id. + +### Return Value + +`undefined` + +## Description + +Deadkeys are useful for tracking hidden state information used to modify future keystrokes. For example, rather than using + +```keyman +"`" + "a" = "à" +``` + +to combine two visible characters, certain applications may desire to keep the `` "`" `` character hidden with a rule such as + +```keyman ++ '`' > dk(backquote) + +... + +dk(backquote) + "a" > "à" +``` + +The Developer compiler then generates a unique id for the deadkey state - say, `0`, and upon detecting input of the `` '`' `` character with the [`keyman.interface.deadkeyMatch()`](deadkeyMatch) function, compiles the deadkey generation to + +```c +keyman.interface.deadkeyOutput(0, Pelem, 0); +``` + +## See also + +- [`keyman.interface.deadkeyMatch()`](deadkeyMatch) +- [Wikipedia article on deadkeys](https://en.wikipedia.org/wiki/Dead_key) diff --git a/web/docs/engine/reference/interface/deleteContext.md b/web/docs/engine/reference/interface/deleteContext.md new file mode 100644 index 0000000000..28b6a0432f --- /dev/null +++ b/web/docs/engine/reference/interface/deleteContext.md @@ -0,0 +1,57 @@ +--- +title: deleteContext (KDC) +--- + +## Summary + +Context deletion - removes the specified number of deadkeys and characters from before the caret. + +## Syntax + +```c +keyman.interface.deleteContext(dn, Pelem); +``` + +or + +```c +KeymanWeb.KDC(n, Pelem); // Shorthand +``` + +### Parameters + +`dn` +: Type: `number` +: The number of entries (deadkeys, characters) to be deleted from the current context. + +`Pelem` +: Type: `Element` +: The element being operated upon. + +### Return Value + +`undefined` + +## Description + +This is a core element of keyboard input management within KeymanWeb introduced with version 10. It is utilized to manage the deletion of context in a deadkey-aware manner, in parallel to [`keyman.interface.fullContextMatch`](fullContextMatch). For comparison with [Developer 'rules'](/developer/language/guide/rules) from keyboard source code... + +```keyman +store(pair_1) 'uU' +store(pair_2) 'lL' + +c Lots of keyboard rules... + +'nul' dk(nothing) + '.' > nul +``` + +would have a rule output as follows: + +```c +// Context is length four (three characters + one deadkey), so we delete all four. +keyman.interface.deleteContext(4, element); +``` + +## See also + +- [`keyman.interface.fullContextMatch()`](fullContextMatch) diff --git a/web/docs/engine/reference/interface/fullContextMatch.md b/web/docs/engine/reference/interface/fullContextMatch.md new file mode 100644 index 0000000000..d6afed737f --- /dev/null +++ b/web/docs/engine/reference/interface/fullContextMatch.md @@ -0,0 +1,137 @@ +--- +title: fullContextMatch (KFCM) +--- + +## Summary + +Context matching: Returns `true` if the current context matches the specified rule context specification. + +## Syntax + +```c +keyman.interface.fullContextMatch(n, Pelem, rule); +``` + +or + +```c +KeymanWeb.KFCM(n, Pelem, rule); // Shorthand +``` + +### Parameters + +`n` +: Type: `number` +: Relative position of the caret for the context match attempt. + +`Pelem` +: Type: `Element` +: The element being operated upon. + +`rule` +: Type: `Array(ContextEntry)` +: The rule context specification to be matched. + +### Return Value + +`boolean` +: `true` if the context matches the rule specification `rule`, otherwise `false`. + +## Rule specification + +Each `ContextEntry` in the `rule` array must be one of the following six types: + +- A plain string with one character +- A `DeadkeyEntry` object with the following members: + + `t` + : `'d'` + : Indicates to expect a [`deadkey`](/developer/language/reference/deadkey) entry. + + `d` + : `number` + : The integer ID of the deadkey to match. + +- An `AnyEntry` object with the following members: + + `t` + : `'a'` + : Indicates the use of an [`any`](/developer/language/reference/any) statement. + + `a` + : `string` + : The store string to be searched for a context match + + `n` + : `boolean` *optional* + : `true` signals to negate the match, as with a [`notany`](/developer/language/reference/notany) statement. + +- An `IndexEntry` object with the following members: + + `t` + : `'i'` + : Indicates the use of an [`index`](/developer/language/reference/index) statement. + + `i` + : `string` + : the store string to be indexed for output corresponding to a previous `any` + + `o` + : `number` + : the index of the corresponding `any` in the rule's context, starting from 1. + +- A `ContextEx` object with the following members: + + `t` + : `'c'` + : Indicates the use of a [`context`](/developer/language/reference/context) statement. + + `c` + : `number` + : The position in context to be matched by the current context location. + +- A `NulEntry` object with the following member: + + `t` + : `'n'` + : Indicates the use of a context-based [`nul`](/developer/language/reference/nul) rule. + +The rule will be interpreted left to right, starting at the specified relative position to the caret. + +## Description + +This is a core element of keyboard input management within KeymanWeb introduced with version 10.0, typically called automatically during keystroke processing events. For comparison with [Developer 'rules'](/developer/language/guide/rules) from keyboard source code... + +```keyman +store(pair_1) 'aA' +store(pair_2) 'bB' + +c Lots of keyboard rules... + +dk(money) 'c' any(pair_1) index(pair_2, 3) + '.' > 'taxi' +``` + +would have Javascript roughly as follows: + +```c +// In the keyboard store definitions: +this.s_pair_1 = 'aA'; // store(pair_1) 'aA' +this.s_pair_2 = 'bB'; // store(pair_2) 'bB' + +// For the deadkey: +this.d_money = 0; // dk(money)'s internal id + +// Within the keyboard rule-matching function: +var matched = keyman.interface.fullContextMatch(4, element, { + {t:'d', d:this.d_money}, // dk(money) + 'c', // 'c' + {t:'a', a:this.s_pair_1}, // 'any(pair_1)' + {t:'i', i:this.s_pair_2, o:3} // 'index(pair_2, 3)' +}); +``` + +## See also + +- [The Keyman Keyboard Language Reference](/developer/language/reference) +- [`keyman.interface.contextMatch()`](contextMatch) +- [`keyman.interface.deleteContext()`](deleteContext) diff --git a/web/docs/engine/reference/interface/ifStore.md b/web/docs/engine/reference/interface/ifStore.md new file mode 100644 index 0000000000..64252cffc1 --- /dev/null +++ b/web/docs/engine/reference/interface/ifStore.md @@ -0,0 +1,62 @@ +--- +title: ifStore (KIFS) +--- + +## Summary + +`ifStore` compares the content of a [system `store`](/developer/language/guide/stores#toc-system-stores) with a string value. + +## Syntax + +```c +keyman.interface.ifStore(systemId, strValue, Pelem); +``` + +or + +```c +KeymanWeb.KIFS(systemId, strValue, Pelem); +``` + +### Parameters + +`systemId` +: Type: `number` +: The ID of the system store to test. + +`strValue` +: Type: `string` +: The string value to be used for comparison. + +`Pelem` +: Type: `Element` +: The page element currently active. (This parameter exists for use by possible future extensions.) + +### Return Value + +`boolean` +: `true` if the value matches that of the system store, otherwise `false`. + +## Description + +Only system IDs `31` (`platform`) and `33` (`layer`) are currently supported. + +For `platform`, any combination of the following may be tested against the current device and browser: + +- Input method: +: `['touch', 'hardware']` + +- any combination of OS: +: `['windows', 'android', 'ios', 'macosx', 'linux']` + +- form factor: +: `['desktop', 'tablet', 'phone']` + +- browser: +: `['native', 'web', 'ie', 'chrome', 'firefox', 'safari', 'opera']` + +Only one of each category may be matched at a time. + +## See also + +- [`keyman.interface.setStore()`](setStore) diff --git a/web/docs/engine/reference/interface/index.md b/web/docs/engine/reference/interface/index.md new file mode 100644 index 0000000000..d257b7e3e3 --- /dev/null +++ b/web/docs/engine/reference/interface/index.md @@ -0,0 +1,107 @@ +--- +title: Output Functions - the Keyboard API +--- + +The KeymanWeb core object `window.keyman.interface` (with legacy-oriented, deprecated alias `KeymanWeb`) exposes a number of functions for low-level processing of input, context and output. These functions are designed for use by keyboards compiled through Keyman Developer in order to facilitate input text processing and will also work for custom-coded KeymanWeb keyboards. As such, most of these functions should only be called by keyboard code, and a good understanding of the [Keyman Keyboard Language](/developer/language) will prove extremely beneficial toward understanding the keyboard API functions enumerated in this section. + +Custom user interfaces would not normally use these functions, but they are described here as some custom keyboards, such as IME-style keyboards, may need to interact with the user interface. + +[`any` Function (Deprecated)](any) +: Returns whether or not the char `ch` is found within the [`any`](/developer/language/reference/any)([`store`](/developer/language/reference/store)) string, setting an internally-tracked index for use in the `indexOutput` function. +: Shorthand name: `KeymanWeb.KA` + +[`beep` Function](beep) +: Flash body or element as substitute for an audible feedback [`beep`](/developer/language/reference/beep). +: Shorthand name: `KeymanWeb.KB` + +[`beepReset` Function](beepReset) +: Cancels a previous feedback [`beep`](/developer/language/reference/beep) operation on a page element. +: Shorthand name: `KeymanWeb.KBR` + +[`context` Function (Deprecated)](context) +: Gets [`context`](/developer/language/reference/context) for an ongoing keyboard operation relative to the caret's present position. +: Shorthand name: `KeymanWeb.KC` + +[`contextExOutput` Function](contextExOutput) +: Emits the character or object at `contextOffset` from the current matched rule's context. +: Shorthand name: `KeymanWeb.KCXO` + +[`contextMatch` Function (Deprecated)](contextMatch) +: Context matching: Returns `true` if the specified `context` call matches a provided string. +: Shorthand name: `KeymanWeb.KCM` + +[`deadkeyMatch` Function (Deprecated)](deadkeyMatch) +: Deadkey matching: Seeks to match the [`deadkey`](/developer/language/reference/deadkey) state `dk` at the relative caret position `n`. +: Shorthand name: `KeymanWeb.KDM` + +[`deadkeyOutput` Function](deadkeyOutput) +: Deadkey output: Associates the [`deadkey`](/developer/language/reference/deadkey) state `dk` with the element at the current caret position, after overwriting `nd` characters. +: Shorthand name: `KeymanWeb.KDO` + +[`deleteContext` Function](deleteContext) +: Context deletion - removes the specified number of deadkeys and characters from the left of the caret. +: Shorthand name: `KeymanWeb.KDC` + +[`fullContextMatch` Function](fullContextMatch) +: Context matching: Returns `true` if the current context matches the specified rule context specification. +: Shorthand name: `KeymanWeb.KFCM` + +[`ifStore` Function](ifStore) +: `ifStore` compares the content of a [system `store`](/developer/language/guide/stores#toc-system-stores) with a string value. +: Shorthand name: `KeymanWeb.KIFS` + +[`indexOutput` Function](indexOutput) +: Index-based output: Outputs a mapped character according to a previous selection from a `keyman.interface.any()` call upon a [`store`](/developer/language/reference/store) string, after deleting `nd` characters. +: Shorthand name: `KeymanWeb.KIO` + +[`insertText` Function](insertText) +: Inserts a text string and optional [`deadkey`](/developer/language/reference/deadkey) into the active output element. +: Shorthand name: `KeymanWeb.KT` + +[`isKeypress` Function](isKeypress) +: Returns `true` if the input event corresponds to a keypress event resulting in character output. +: Shorthand name: `KeymanWeb.KIK` + +[`keyInformation` Function](keyInformation) +: Returns an object with extended information about a specified keystroke event. +: Shorthand name: `KeymanWeb.KKI` + +[`keyMatch` Function](keyMatch) +: Keystroke matching: Returns `true` if the event matches the rule's shift mask and key code. +: Shorthand name: `KeymanWeb.KKM` + +[`loadStore` Function](loadStore) +: Load an option [`store`](/developer/language/guide/stores) value from a cookie or default value if no prior stored value exists. +: Shorthand name: `KeymanWeb.KLOAD` + +[`nul` Function](_nul) +: [`nul`](/developer/language/reference/nul) context check: Returns `true` if the length of the [`context`](/developer/language/reference/context) is less than or equal to `n` characters. +: Shorthand name: `KeymanWeb.KN` + +[`output` Function](output) +: Outputs the specified string to an element, overwriting characters before the caret if specified. +: Shorthand name: `KeymanWeb.KO` + +[`registerKeyboard` Function](registerKeyboard) +: Register the keyboard stub and load the keyboard. +: Shorthand name: `KeymanWeb.KR` + +[`registerStub` Function](registerStub) +: Register the keyboard stub, return true if already registered. +: Shorthand name: `KeymanWeb.KRS` + +[`saveFocus` Function](saveFocus) +: Save focus: Temporarily saves keyboard processing data for the currently-focused control. +: Shorthand name: `KeymanWeb.KSF` + +[`saveStore` Function](saveStore) +: Save an option [`store`](/developer/language/guide/stores) value to a cookie for the active keyboard. +: Shorthand name: `KeymanWeb.KSAVE` + +[`setStore` Function](setStore) +: `setStore` sets the value of a [system `store`](/developer/language/guide/stores#toc-system-stores) to a string. +: Shorthand name: `KeymanWeb.KSETS` + +[`stateMatch` Function](stateMatch) +: State-key matching: Returns `true` if the event matches the rule's state-key requirements. +: Shorthand name: `KeymanWeb.KSM` diff --git a/web/docs/engine/reference/interface/indexOutput.md b/web/docs/engine/reference/interface/indexOutput.md new file mode 100644 index 0000000000..2654f37147 --- /dev/null +++ b/web/docs/engine/reference/interface/indexOutput.md @@ -0,0 +1,61 @@ +--- +title: indexOutput (KIO) +--- + +## Summary + +Index-based output: Outputs a mapped character according to a previous selection from a `keyman.interface.any()` call upon a [`store`](/developer/language/reference/store) string, after deleting `nd` characters. + +## Syntax + +```c +keyman.interface.indexOutput(nd, store, index, Pelem); +``` + +or + +```c +KeymanWeb.KIO(nd, store, index, Pelem); +``` + +### Parameters + +`nd` +: Type: `number` +: The number of characters to be overwritten. + +`store` +: Type: `string` +: The store string to be used for mapping a character previously detected via `keyman.interface.any()`, which itself maps to a [`any`](/developer/language/reference/any) call. + +`index` +: Type: `number` +: The index id to which the detected character's index in the original matching array was saved. The index id should be incremented by 1 relative to the value specified in `keyman.interface.any()`. + +`Pelem` +: Type: `Element` +: The HTML element receiving the output. + +## Description + +This function corresponds most directly to the keyboard language command [`index`](/developer/language/reference/index), which operates upon text [`store`](/developer/language/reference/store)s to allow for array-based input-output text matching. For example, + +```keyman +store(keys) 'abcde' +store(output) 'αβγδε' ++ any(keys) > index(output,1) +``` + +facilitates mapping the characters `'abcde'` to their respective entry in the output store `'αβγδε'`. `keyman.interface.indexOutput()`'s role in this process is usually optimized out into individual mappings for performance reasons, though it is often involved when `any` is involved as part of a rule's `context`, rather than upon the triggering keystroke itself. + +In order to output the desired character corresponding to `'a'` in the `output` store above, the code + +```c +keyman.interface.indexOutput(0, 'αβγδε', 1, Pelem) +``` + +would suffice, overwriting no characters and using the previously-matched index (id = 0 + 1). Note that the `keyman.interface.indexOutput()` call must increment the id by 1 due to Keyman's keyboard language rules, which corresponds directly to the `index` call in the keyboard source above. + +## See also + +- [`keyman.interface.any()`](any) diff --git a/web/docs/engine/reference/interface/insertText.md b/web/docs/engine/reference/interface/insertText.md new file mode 100644 index 0000000000..313ae07f8d --- /dev/null +++ b/web/docs/engine/reference/interface/insertText.md @@ -0,0 +1,38 @@ +--- +title: insertText (KT) +--- + +## Summary + +Inserts a text string and optional [`deadkey`](/developer/language/reference/deadkey) into the active output element. + +## Syntax + +```c +keyman.interface.insertText(text, dk); +``` + +or + +```c +KeymanWeb.KT(text, dk); // Shorthand +``` + +### Parameters + +`text` +: Type: `string` +: The text to insert. + +`dk` +: Type: `number` *optional* +: The deadkey's id, if one is to be inserted. + +### Return Value + +`boolean` +: `true` if the operation is successful, otherwise `false`. + +## Description + +This function is designed to allow custom UI elements or custom OSK displays (as for the [EuroLatin keyboard](https://keymanweb.com/#aae,Keyboard_sil_euro_latin)) to directly insert input into a control without losing the current input state due to loss of focus for the control. It is safe for use outside of keyboard code. diff --git a/web/docs/engine/reference/interface/isKeypress.md b/web/docs/engine/reference/interface/isKeypress.md new file mode 100644 index 0000000000..c5edbcf913 --- /dev/null +++ b/web/docs/engine/reference/interface/isKeypress.md @@ -0,0 +1,36 @@ +--- +title: isKeypress (KIK) +--- + +## Summary + +Returns `true` if the input event corresponds to a keypress event resulting in character output. + +## Syntax + +```c +keyman.interface.isKeypress(e); +``` + +or + +```c +KeymanWeb.KIK(e); // Shorthand +``` + +### Parameters + +`e` +: Type: `Object` +: The event object to be evaluated. + +### Return Value + +`boolean` +: `true` if the event would produce text output, otherwise `false`. + +## Description + +This function is designed to facilitate filtering of keystrokes, allowing custom-coded keyboards to ignore function-oriented keystroke events that should never be used for text generation, such as for F1-F12. + +The logic corresponds to that for the keyboard language [`nomatch`](/developer/language/reference/nomatch) rule. diff --git a/web/docs/engine/reference/interface/keyInformation.md b/web/docs/engine/reference/interface/keyInformation.md new file mode 100644 index 0000000000..3d64bff3f0 --- /dev/null +++ b/web/docs/engine/reference/interface/keyInformation.md @@ -0,0 +1,62 @@ +--- +title: keyInformation (KKI) +--- + +## Summary + +Returns an object with extended information about a specified keystroke event. + +## Syntax + +```c +keyman.interface.keyInformation(e); +``` + +or + +```c +KeymanWeb.KKI(e); // Shorthand +``` + +### Parameters + +`e` +: Type: `Object` +: The event object to be evaluated. + +### Return Value + +`Object` +: An object with extended key event information. + +## Description + +--- +**Note:** This function will not succeed if it is called from outside of a keyboard's standard text-processing operations. + +--- + +The `key_event` object contains the following members: + +`vk` +: `boolean` +: A flag indicating whether or not the event corresponds to a virtual key. + +`code` +: `number` +: The underlying keycode for the event. + +`modifiers` +: `number` +: A set of bit-flags corresponding to the SHIFT, CTRL, and ALT state of the keyboard. + +The bit masks for each modifier are as follows: + +- SHIFT +: `0x10` + +- CTRL +: `0x20` + +- ALT +: `0x40` diff --git a/web/docs/engine/reference/interface/keyMatch.md b/web/docs/engine/reference/interface/keyMatch.md new file mode 100644 index 0000000000..52fe8f368d --- /dev/null +++ b/web/docs/engine/reference/interface/keyMatch.md @@ -0,0 +1,61 @@ +--- +title: keyMatch (KKM) +--- + +## Summary + +Keystroke matching: Returns `true` if the event matches the rule's shift mask and key code. + +## Syntax + +```c +keyman.interface.keyMatch(e, shiftCode, keyCode); +``` + +or + +```c +KeymanWeb.KKM(e, shiftCode, keyCode); // Shorthand +``` + +### Parameters + +`e` +: Type: `Object` +: A keystroke-related event object to match. + +`shiftCode` +: Type: `number` +: The shift-state code the event object should match. + +`keyCode` +: Type: `number` +: The key code the event object should match. + +### Return Value + +`boolean` +: `true` if the keystroke matches the desired values, otherwise `false`. + +## Description + +This is a core element of keyboard input management within KeymanWeb, typically called automatically during keystroke processing events. For comparison with [Developer 'rules'](/developer/language/guide/rules) from keyboard source code, in the rule + +```keyman +"a" + "'" > "á" +``` + +a keyboard would check that the triggering keystroke (`"'"`) matches by using + +```keyman +keyman.interface.keyMatch(e, 0, 39) +``` + +from within a raised keystroke event with object `e`, which checks that the keystroke represented by `e` is unshifted and matches the underlying keycode value for `"'"`, which is `39` in ASCII and Unicode. + +As `keyman.interface.keyMatch()` receives an event object as one of its parameters, it does not need a direct link to the element receiving input. + +## See also + +- [`keyman.interface.contextMatch()`](contextMatch) +- [`keyman.interface.stateMatch()`](stateMatch) diff --git a/web/docs/engine/reference/interface/loadStore.md b/web/docs/engine/reference/interface/loadStore.md new file mode 100644 index 0000000000..c8ccee5616 --- /dev/null +++ b/web/docs/engine/reference/interface/loadStore.md @@ -0,0 +1,46 @@ +--- +title: loadStore (KLOAD) +--- + +## Summary + +Load an option [`store`](/developer/language/guide/stores) value from a cookie or default value if no prior stored value exists. + +## Syntax + +```c +keyman.interface.loadStore(kbdName, storeName, value); +``` + +or + +```c +KeymanWeb.KLOAD(kbdName, storeName, value); // Shorthand +``` + +### Parameters + +`kbdName` +: Type: `string` +: The keyboard's identifying internal name. + +`storeName` +: Type: `string` +: The option `store` name that is embedded in the cookie's name. + +`value` +: Type: `string` +: A value for the store to use as default if no prior value exists. + +### Return Value + +`string` +: The current value of the store, or the default `value` provided if the store's value is `undefined`. + +## Description + +`keyman.interface.loadStore()` and [`keyman.interface.saveStore()`](saveStore) provide API-based functionality similar to that of the keyboard language's option `store`. Values will persist across multiple visits to the site by use of cookies. However, these functions cannot interact with `store`s from existing compiled keyboards due to compilation optimizations. As such, they are most useful for custom-coded web-oriented keyboards. + +## See also + +- [`keyman.interface.saveStore();`](saveStore) diff --git a/web/docs/engine/reference/interface/output.md b/web/docs/engine/reference/interface/output.md new file mode 100644 index 0000000000..81e53ff1ce --- /dev/null +++ b/web/docs/engine/reference/interface/output.md @@ -0,0 +1,57 @@ +--- +title: output (KO) +--- + +## Summary + +Outputs the specified string to an element, overwriting `nd` characters before the caret. + +## Syntax + +```c +keyman.interface.output(nd, Pelem, str); +``` + +or + +```c +KeymanWeb.KO(nd, Pelem, str); // Shorthand +``` + +### Parameters + +`nd` +: Type: `number` +: The number of characters to overwrite. Passively ignores values less than zero. + +`Pelem` +: Type: `Element` +: The input element to receive the output text. + +`str` +: Type: `string` +: The output text to write to the input element. + +### Return Value + +`undefined` + +## Description + +This is a core element of keyboard input management within KeymanWeb, typically called automatically during keystroke processing events. For comparison with [Developer 'rules'](/developer/language/guide/rules) from keyboard source code, in the rule + +```keyman +"a" + "'" > "á" +``` + +a keyboard would, after checking that the initial context (`"a"`) matches, use + +```c +keyman.interface.output(1, Pelem, "á"); +``` + +to erase one character `"a"` and output one character `"á"`, effectively performing the desired replacement. + +## See also + +- [`keyman.interface.contextMatch()`](contextMatch) diff --git a/web/docs/engine/reference/interface/registerKeyboard.md b/web/docs/engine/reference/interface/registerKeyboard.md new file mode 100644 index 0000000000..ea2917f3b9 --- /dev/null +++ b/web/docs/engine/reference/interface/registerKeyboard.md @@ -0,0 +1,37 @@ +--- +title: registerKeyboard (KR) +--- + +## Summary + +Registers and loads the keyboard. + +## Syntax + +```c +keyman.interface.registerKeyboard(Pk); +``` + +or + +```c +KeymanWeb.KR(Pk); // Shorthand +``` + +### Parameters + +`Pk` +: Type: `Object` +: The keyboard object to be loaded and registered. + +### Return Value + +`undefined` + +## Description + +--- +**Note:** Any calls made to this function before KeymanWeb has initialized will be deferred until initialization occurs. Furthermore, an existing keyboard stub must exist for KeymanWeb to fully link with the keyboard. + +--- +This keyboard object is typically provided directly by the keyboard-loading process employed within KeymanWeb and its keyboard source files. diff --git a/web/docs/engine/reference/interface/registerStub.md b/web/docs/engine/reference/interface/registerStub.md new file mode 100644 index 0000000000..2d9c8ef5a8 --- /dev/null +++ b/web/docs/engine/reference/interface/registerStub.md @@ -0,0 +1,39 @@ +--- +title: registerStub (KRS) +--- + +## Summary + +Registers the keyboard stub or returns true if already registered. + +## Syntax + +```c +keyman.interface.registerStub(Pstub); +``` + +or + +```c +KeymanWeb.KRS(Pstub); // Shorthand +``` + +### Parameters + +`Pstub` +: Type: `Object` +: A keyboard stub object representing the keyboard's basic lookup parameters. + +### Return Value + +`optional number` +: `1` if the keyboard is preregistered, otherwise `null`. + +## Description + +--- +**Note:** This only registers the stub with KeymanWeb, allowing it to later request the keyboard from the server or filesystem upon demand in order to complete the linking process. + +--- + +The `keyman.interface.registerStub` function is typically called on the user's behalf by the [`keyman.addKeyboards()`](../core/addKeyboards) function. diff --git a/web/docs/engine/reference/interface/saveFocus.md b/web/docs/engine/reference/interface/saveFocus.md new file mode 100644 index 0000000000..417761c066 --- /dev/null +++ b/web/docs/engine/reference/interface/saveFocus.md @@ -0,0 +1,35 @@ +--- +title: saveFocus (KSF) +--- + +## Summary + +Save focus: Temporarily saves keyboard processing data for the currently-focused control. + +## Syntax + +```c +keyman.interface.saveFocus() +``` + +or + +```c +KeymanWeb.KSF() // Shorthand +``` + +### Parameters + +None. + +### Return Value + +`undefined` + +## Description + +Use this function to temporarily preserve all keyboard processing information during a single change-of-focus event. + +This function is designed to allow custom UI elements, custom OSK displays (as for the [EuroLatin keyboard](https://keymanweb.com/#aae,Keyboard_sil_euro_latin)), or keyboards with picker-style functionality (such as the [Japanese keyboard](https://keymanweb.com/#jpn,Keyboard_japanese)) to operate without losing the current input state due to loss of focus for the active control. + +A good example of when to call this function would be for `onmousedown` events for visual elements not intended to change the element of focus within KeymanWeb. It is safe for use outside of keyboard code. diff --git a/web/docs/engine/reference/interface/saveStore.md b/web/docs/engine/reference/interface/saveStore.md new file mode 100644 index 0000000000..7855b9bf5f --- /dev/null +++ b/web/docs/engine/reference/interface/saveStore.md @@ -0,0 +1,42 @@ +--- +title: saveStore (KSAVE) +--- + +## Summary + +Save an option [`store`](/developer/language/guide/stores) value to a cookie for the active keyboard. + +## Syntax + +```c +keyman.interface.saveStore(storeName, value); +``` + +or + +```c +KeymanWeb.KSAVE(storeName, value); // Shorthand +``` + +### Parameters + +`storeName` +: Type: `string` +: The option `store` name, which will be embedded in the cookie's name. + +`value` +: Type: `string` +: The option value to save. + +### Return Value + +`boolean` +: `true` if the operation is successful, otherwise `false`. + +## Description + +[`keyman.interface.loadStore()`](loadStore) and `keyman.interface.saveStore()`provide API-based functionality similar to that of the keyboard language's option `store`. Values will persist across multiple visits to the site by use of cookies. However, these functions cannot interact with `store`s from existing compiled keyboards due to compilation optimizations. As such, they are most useful for custom-coded web-oriented keyboards. + +## See also + +- [`keyman.interface.loadStore();`](loadStore) diff --git a/web/docs/engine/reference/interface/setStore.md b/web/docs/engine/reference/interface/setStore.md new file mode 100644 index 0000000000..1244e51c51 --- /dev/null +++ b/web/docs/engine/reference/interface/setStore.md @@ -0,0 +1,48 @@ +--- +title: setStore (KSETS) +--- + +## Summary + +`setStore` sets the value of a [system `store`](/developer/language/guide/stores#toc-system-stores) to a string. + +## Syntax + +```c +keyman.interface.setStore(systemId, strValue, Pelem); +``` + +or + +```c +KeymanWeb.KSETS(systemId, strValue, Pelem); // Shorthand +``` + +### Parameters + +`systemId` +: Type: `number` +: The ID of the system store to set. Only system ID `33` (`layer`) is currently supported. + +`strValue` +: Type: `string` +: The string value to set as the system store's content. + +`Pelem` +: Type: `Element` +: The page element currently active. (This parameter exists for use by possible future extensions.) + +### Return Value + +`boolean` +: `true` if the operation succeeds, otherwise `false`. + +## Description + +This function is used to set the value of writeable system stores. Many system stores are readonly, containing metadata about an individual keyboard, so `keyman.interface.ifStore()` will fail upon attempts to modify their values. + +This function cannot modify standard keyboard [`stores`](/developer/language/guide/stores) and is limited to system `stores` only, as standard keyboard stores are optimized into Javascript string literals set directly in code with automatically-generated names. + +## See also + +- [`keyman.interface.ifStore()`](ifStore) diff --git a/web/docs/engine/reference/interface/stateMatch.md b/web/docs/engine/reference/interface/stateMatch.md new file mode 100644 index 0000000000..5dbc4f3612 --- /dev/null +++ b/web/docs/engine/reference/interface/stateMatch.md @@ -0,0 +1,61 @@ +--- +title: stateMatch (KSM) +--- + +## Summary + +State-key matching: Returns `true` if the event matches the rule's state-key requirements. + +## Syntax + +```c +keyman.interface.stateMatch(e, shiftCode); +``` + +or + +```c +KeymanWeb.KSM(e, shiftCode); // Shorthand +``` + +### Parameters + +`e` +: Type: `Object` +: A keystroke-related event object to match. + +`state` +: Type: `number` +: The state-key bitflags the event should match. + +### Return Value + +`boolean` +: `true` if the keystroke matches the desired states, otherwise `false`. + +## Description + +As of KeymanWeb 10.0, KeymanWeb now supports keyboard rules conditioned upon 'state keys' like Caps Lock [if specified by keyboard developers](/developer/language/guide/virtual-keys#toc-caps-lock). + +The `stateMatch` function examines the bit-flags to determine the state keys being tested and compares the keyboard event against them as appropriate. As such, it is designed to be a condition check alongside [`keyman.interface.keyMatch()`](keyMatch) and [`keyman.interface.contextMatch()`](contextMatch). + +For comparison with [Developer 'rules'](/developer/language/guide/virtual-keys#toc-caps-lock) from keyboard source code, in the rule + +```keyman ++ [CAPS K_A] > 'BIG A' ++ [NCAPS K_A] > 'small a' +``` + +a keyboard would check which rule the triggering keystroke (`"a"`) matches by using + +```c +keyman.interface.stateMatch(e, 0x100) +``` + +from within a raised keystroke event with object `e`, which checks that the keystroke represented by `e` has an activated Caps Lock state as represented by the code 0x0100. The NCAPS rule would instead compare against 0x0200. + +As `keyman.interface.stateMatch()` receives an event object as one of its parameters, it does not need a direct link to the element receiving input. + +## See also + +- [`keyman.interface.keyMatch()`](keyMatch) diff --git a/web/docs/engine/reference/keyboard_properties.md b/web/docs/engine/reference/keyboard_properties.md new file mode 100644 index 0000000000..a5c5ac6b2e --- /dev/null +++ b/web/docs/engine/reference/keyboard_properties.md @@ -0,0 +1,97 @@ +--- +title: Keyboard Properties +--- + +Most keyboards are generated automatically from the Keyman keyboard source by +_Keyman Developer_ and contain properties used by _KeymanWeb_ during keyboard +mapping. Keyboards implement mapping by invoking functions within _KeymanWeb_, +but do not interact directly with the user interface. However, user interfaces +may need to interact with custom developed keyboards if, for example, they use a +"pick list" or have other IME-like behavior. + +Each registered keyboard object defines some or all of the following exposed +string properties: + +`KN` + +: `string`, (`name`) visible name of the keyboard, required. + +`KI` + +: `string`, (`internalName`) identifier of the keyboard, starting with `Keyboard_`, required. + +`KMINVER` + +: `string`, minimum version that the keyboard will run on, `2.0` if not present, optional. + +`KV` + +: `object`, on screen keyboard definition, optional. + +`KDU` + +: `number`, `1` to display underlying characters on On Screen Keyboard, `0` or omitted to hide them, optional + +`KH` + +: `string`, Keyboard help, in HTML; if present replaces `KV` in the On Screen Keyboard, optional + +`KM` + +: `number`, `1` to use mnemonic layout, `0` or omitted for positional, optional + +`KBVER` + +: `string`, version of the keyboard (should be dotted decimal format), optional + +`KMBM` + +: `number`, bitmask denoting modifiers used in the keyboard, if not present defaults to 0x0070, optional + +`KVKL` + +: `object`, touch layout definition, optional. + +`KVER` + +: `string`, version of Keyman Developer used to compile the keyboard, optional + +`KVS` + +: `string[]`, array of all variable store names found in the keyboard (15.0 and later), optional + +`KS` + +: `number`, `1` means Unicode characters U+10000-U+10FFFF, including the Supplementary Multilingual Plane (SMP), are used in the keyboard, optional + +`KVKD` + +: `object`, Virtual key dictionary listing custom touch keys used in the keyboard, optional + +`KCSS` + +: `string`, Custom CSS defined by the keyboard, optional + +`KFont` + +: `object`, Embedded font specification for mapped input elements and on-screen keyboard, optional + +`KOskFont` + +: `object`, Embedded font specification for on-screen keyboard, optional + +For most keyboards which require an embedded font, the same font will be used +for mapped elements and the on-screen keyboard, and only the `KFont` property +wil be defined. The additional property `KOskFont` property would only be used +where it may be helpful to use a different embedded font for the on-screen +keyboard. + +The `KFont` and `KOskFont` members are objects with the following members: + +`family` + +: `string`, font-family name for embedded font, e.g. `'LatinWeb'` + +`files` + +: `string` or `string[]`, Font file name or names, e.g. `['DejaVuSans.ttf','DejaVuSans.woff','DejaVuSans.eot']` diff --git a/web/docs/engine/reference/keyboard_registration_errors.md b/web/docs/engine/reference/keyboard_registration_errors.md new file mode 100644 index 0000000000..9ff4214bc9 --- /dev/null +++ b/web/docs/engine/reference/keyboard_registration_errors.md @@ -0,0 +1,55 @@ +--- +title: Keyboard Registration Errors +--- + +If KeymanWeb has an error while adding/registering a keyboard, the `ErrorStub` object containing the following members is returned: + +`keyboard` + +: `object` optional + + Information on the keyboard + +`language` + +: `object` optional + + Information on the language associated with the keyboard + +`error` + +: `Error` + + Javascript error that occurred during keyboard registration + +--- + +The `ErrorStub.keyboard` object contains the following members: + +`id` + +: `string` + +ID (internal name) of keyboard + +`name` + +: `string` + +Name of the keyboard + +--- + +The `ErrorStub.language` object contains the following members: + +`id` + +: `string` + +BCP 47 code for supported keyboard language. If a keyboard supports multiple languages, an array of ErrorStubs is returned. + +`name` + +: `string` + +Name of the language diff --git a/web/docs/engine/reference/layouts.md b/web/docs/engine/reference/layouts.md new file mode 100644 index 0000000000..df3e3b50c7 --- /dev/null +++ b/web/docs/engine/reference/layouts.md @@ -0,0 +1,5 @@ +--- +title: Layout Designer +--- + +One of the main features of *KeymanWeb 17* is its ability to support distinct, user-customizable layouts for touch-screen keyboards on phones and tablets. *Keyman Developer 17* includes a layout designer to simplify the process of creating custom layouts for any keyboard. diff --git a/web/docs/engine/reference/layoutspec.md b/web/docs/engine/reference/layoutspec.md new file mode 100644 index 0000000000..2cdaec1fff --- /dev/null +++ b/web/docs/engine/reference/layoutspec.md @@ -0,0 +1,402 @@ +--- +title: Layout Specifications +--- + +Touch-screen layouts for *KeymanWeb 17* are specified as JSON objects containing a member object for each specified device type. Currently supported device types are *tablet* and *phone*. Layouts for *desktop* computers may also be specified but desktop on-screen keyboard design is normally managed by the +standard *Keyman Developer* on-screen keyboard tool rather than the keyboard layout designer. If the same +layout is appropriate for both *tablet* and *phone* devices only one need be specified, and will be used for either type of device. + +File encoding for manually-created layout files may use either UTF-8 or 7-bit ANSI coding, but must not include a BOM. For easier editing and management without requiring special fonts, embedded Unicode characters with values above 127 may use the *\uXXXX* notation. + +For details of the JSON specification, see [The JSON Data Interchange Format(ECMA-404)](http://www.ecma-international.org/publications/files/ECMA-ST/ECMA-404.pdf). + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Object name or descriptionObject or array element members
(container object) + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescriptionRequired
tabletObjectTablet layout specificationNo
phoneObjectPhone layout specificationNo
desktopObjectDesktop OSK layout specificationNo
+
(layout specification) + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescriptionRequired
fontstringKey label default fontNo
fontsizestringKey label default font size (in em)No
layerObject arrayArray of layer specificationsYes
+
layer + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescriptionRequired
idstringLayer nameYes
rowObject arrayArray of keyboard row specificationsYes
nextlayerstringKeyboard layer to display after processing keystrokeNo
+
row + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescriptionRequired
idstringRow numberYes
keyObject arrayArray of keyboard key specificationsYes
+
key + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescriptionRequired
idstringKey identifierYes*
textstringText on keyNo
fontstringFont name if different from default key label fontNo
fontsizestringFont size if different from default key label font sizeNo
spnumberKey styleNo
widthnumberKey widthNo
padnumberSpace before keyNo
dknumberDeadkey (1) or normal key (0 or omitted)No
layerstringModifier key or keys assumed applied when + mapping this keyNo
nextlayerstringName of keyboard layer to be displayed after this key is processedNo
skObject arrayArray of pop-up key specificationsNo
+
+ +Details of key member specifications are given below: + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Member nameDetails
idEach key id must start with >K_ , for keys mapped to standard Keyman virtual key names, e.g. K_HYPHEN , or either U_ or T_ for user-defined names. Keys identified as U_xxxx[_xxxx...] specify one or more Unicode characters in hex format, e.g. U_1363 for the Ethiopic Comma character, and will insert those characters if the key id is not matched by a rule. Other user-defined keys, such as T_ZZZ , will be ignored unless matched by a rule. The key id is required except for key styles 9 or 10 (blank or spacer keys).
textWhere a key id is of the form K_XXXX , the text on the key will be the indicated Unicode character if this member is omitted. However, what the keystroke output will depend on any rules that process the keystroke, and may or may not be the same as the key text.
sp + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ValueKey style
0Normal key (default)
1Shift key
2Active shift key
8Deadkey
9Blank key
10Spacer
+
fontThe font for the key label may be specified if it is necessary to use a different font for that key.
fontsizeThe font size for the key label may be specified (in em units) if necessary.
widthBy default, each key has a width of 100 + units, with rows then scaled to make the widest row fit on the screen. + Set the width value if a key should be narrower or wider than the + standard width.
padSpace before key, in same units as width (default key width=100 units).
layerOverride the default layer type for processing key rules. For example, use 'layer':'shift' in any layer to process a key rule as if it were the shift layer, i.e. as if the Shift key was down.
nextlayerSelect the key layer to be displayed after processing the current keystroke. This will usually be used to implement custom layer selection, but can also be used to select a different layer after a deadkey or normal key, and will override any nextlayer value specifed for the entire layer. The layer to be displayed may also be specified using the setlayer() statement in a rule in the keyboard source.
skPop-up key specifications are identical to normal key specifications except that they cannot be nested. (Key size and spacing members width and pad are ignored for pop-up keys.)
+ +For many keyboards, it is helpful to associate some keyboard layers with physical keyboard modifier states. This is reflected in the layer name, where a layer name of *shift* means that when a key in that layer is touched, the keystroke will be processed as if the keyboard Shift key is held. + +The special layer names of: +  *leftalt* , + *rightalt* , + *alt* , +  *leftctrl* , + *rightctrl* , + *ctrl* , + *ctrlalt* , +  *leftctrl-leftalt* , + *rightctrl-rightalt* , + *leftctrl-leftalt-shift* , + *rightctrl-rightalt-shift* , +  *shift* , + *shift-alt* , + *shift-ctrl* , + *shift-ctrl-alt* , +  *leftalt-shift* , + *rightalt-shift* , + *leftctrl-shift* , and + *rightctrl-shift* +each apply the appropriate modifier keys when processing rules unless overridden by a *layer* value in the key specification. The layer names *default* , *numeric* , *symbol* and *currency* are also recognized, but no modifier key is applied for keys in these layers. + +The following special key identifiers have been added to simplify layer selection: + +| Identifier | Value | +|:-------------|:------| +| K_NUMERALS | 261 | +| K_SYMBOLS | 262 | +| K_CURRENCIES | 263 | +| K_SHIFTED | 264 | +| K_ALTGR | 265 | + +A special font is used to provide easily recognizable key graphics for various special purpose keys. The following key text strings will be recognized and cause the appropriate graphic to be used for the key cap instead of the actual text: + +| Text string | Key purpose | +|:------------------|:--------------------------------------------------------| +| \*Shift\* | Shift key image (inactive) | +| \*Enter\* | Return | +| \*Tab\* | Move to next input element in tab order | +| \*BkSp\* | Backspace | +| \*Menu\* | Display the language menu | +| \*Hide\* | Hide the virtual keyboard | +| \*Alt\* | Alt key caption | +| \*Ctrl\* | Control key caption | +| \*Caps\* | Caps Lock caption | +| \*ABC\* | Select the upper case alphabetic layer | +| \*abc\* | Return to the default (alphabetic) keyboard layer | +| \*123\* | Select a numeric keyboard layer | +| \*Symbol\* | Select a layer with various non-letter symbols | +| \*Currency\* | Select a layer with currency symbols | +| \*Shifted\* | Active Shift key image | +| \*AltGr\* | Select Control + Alt (AltGr) modifier state | +| \*TabLeft\* | Go back to previous input element in tab order | +| \*LAlt\* | Select left Alt modifier state | +| \*RAlt\* | Select right Alt modifier state | +| \*LCtrl\* | Select left Control modifier state | +| \*RCtrl\* | Select right Control modifier state | +| \*LAltCtrl\* | Select left Alt + left Control modifier state | +| \*RAltCtrl\* | Select right Alt + right Control modifier state | +| \*LAltCtrlShift\* | Select left Alt + left Control + Shift modifier state | +| \*RAltCtrlShift\* | Select right Alt + right Control + Shift modifier state | +| \*AltShift\* | Select Alt + Shift modifier state | +| \*CtrlShift\* | Select Control + Shift modifier state | +| \*AltCtrlShift\* | Select Alt + Control + Shift modifier state | +| \*LAltShift\* | Select left Alt + Shift modifier state | +| \*RAltShift\* | Select right Alt + Shift modifier state | +| \*LCtrlShift\* | Select left Control + Shift modifier state | +| \*RCtrlShift\* | Select right Control + Shift modifier state | diff --git a/web/docs/engine/reference/osk/addEventListener.md b/web/docs/engine/reference/osk/addEventListener.md new file mode 100644 index 0000000000..8f36d96e5e --- /dev/null +++ b/web/docs/engine/reference/osk/addEventListener.md @@ -0,0 +1,31 @@ +--- +title: addEventListener +--- + +## Summary + +Adds an event listener for user-handling of On-Screen keyboard events. + +## Syntax + +```c +keyman.osk.addEventListener(eventName, func) +``` + +### Parameters + +`eventName` +: Type: `string` +: The name of an event generated by the `keyman.osk` object. See [the Events section](../events) for details and examples. + +`func` +: Type: `function(Object)` +: A function to be called when the event is raised. + +### Return Value + +`boolean` + +## Description + +Standard HTML element events for the On-Screen Keyboard element may also be intercepted and used to modify the user interface if necessary. diff --git a/web/docs/engine/reference/osk/classes.md b/web/docs/engine/reference/osk/classes.md new file mode 100644 index 0000000000..ea82b0bcf3 --- /dev/null +++ b/web/docs/engine/reference/osk/classes.md @@ -0,0 +1,154 @@ +--- +title: Class Names and Identifiers for On-Screen Keyboard and Other KeymanWeb Elements +--- + +The appearance of the _KeymanWeb_ on-screen keyboard, menu amd other elements can be customized +by a web designer by redefining (or adding to) the default styles. Styles and named elements +all have the class name (or id) prefix `kmw-` joined to the object and item names, +for example `kmw-key-text`, to set the basic style for the keycap text on each on-screen keyboard key. +Multiple classes are applied to many objects, with top-level classes of `tablet`, +`phone` and `desktop` used to set different element styles according to the device type. +Unique elements, such as the menu and pop-up key frame, are named rather than referred to by class. + +Most visual attributes such as text size and colour, background colour, shading, margins, etc. can be varied +according to preference but developers should avoid changing positional attributes. + +### Class names applied to on-screen keyboard elements: + +| Class name | Keyboard element | +| ----------------------- | ----------------------------------- | +| `kmw-osk-frame` | Outer keyboard frame | +| `kmw-osk-inner-frame` | Inner keyboard frame | +| `kmw-key-layer-group` | Keyboard layers container element | +| `kmw-key-layer` | Keyboard layer element | +| `kmw-key-row` | Keyboard row container element | +| `kmw-key-square` | Keyboard key container element | +| `kmw-key-square-ex` | Pop-up key container element | +| `kmw-key` | Key element | +| `kmw-key-label` | Key label (desktop OSK and phonetic layouts) | +| `kmw-key-text` | Keycap text | +| `kmw-key-popup-icon` | Text or graphic to indicate that a keyboard key has associated popup keys | +| `kmw-spacebar-caption` | Style applied to caption on spacebar | + +### Class names applied to different types of keys: + +| Class name | Key style | +| ----------------------- | ------------------------------- | +| `kmw-key-default` | Default | +| `kmw-key-shift` | Shift key, layer-switching keys | +| `kmw-key-shift-on` | Active shift key | +| `kmw-key-deadkey` | [Dead key](/developer/language/reference/deadkey) | +| `kmw-key-blank` | Blank, unmapped key | +| `kmw-key-hidden` | Hidden spacer key | +| `kmw-key-touched` | Active (touched) key | + +### Element identifiers for keys: + +Useful reference: [Keys, Virtual Keys, and Virtual Character Keys](/developer/language/guide/virtual-keys#toc-key-codes) + +Each key element (`kmw-key`) has an ID based on the key code used for it within Keyman Developer. Each ID is based on +two or three pieces: +- The key's layer +- The key's code +- _If_ it differs from the key's actual layer, the "modifier" setting for the key as set within the Touch Layout editor. + +The format: +- ``-`` +- ``-``+`` (if different from ``) + +Some example IDs: +- `default-K_K` - the `K_K` key on the `default` layer +- `currency-U_20B2` - the `U_20B2` key (₲) on the `currency` layer +- `numeric-K_0+default` - the `K_0` key displayed on the `numeric` layer, using the same modifiers as the `default` layer. + +For keys reached by longpress, the form of the ID is the same, just with one extra piece: it is prepended with `popup-`. +- `popup-default-U_1E0F` - the `U_1E0F` subkey (ḏ) on the `default` layer + - This is one of the subkeys of the 'd' key on the `default` layer on the EuroLatin (SIL) keyboard. + +You can set styles for specific keys by using CSS selectors against specific key IDs. + +The following selector will find the key element for all keys with the key code `K_RBRKT` of the keyboard's phone layout. + +```css +.phone div.kmw-key.kmw-key-default[id*='K_RBRKT'] +``` + +Note the `[id*='K_RBRKT']` part. There can be a few variations here: +- `*=` - "contains" +- `^=` - "starts with" +- `$=` - "ends with" + +So, to match all keys reached by longpress, you could use: + +```css +div.kmw-key.kmw-key-default[id^='popup-'] +``` + +Also, `:not(...)` can be used to invert a selector. The following selector will match all base keys, but not +any longpress keys. + +```css +div.kmw-key.kmw-key-default:not([id^='popup-']) +``` + +### Element identifiers and class names for desktop on-screen keyboard elements: + +| Class name or id | Desktop OSK element | +| ----------------------- | ------------------------------- | +| `kmw-title-bar` | OSK title bar | +| `kmw-title-bar-caption` | OSK title bar caption (keyboard name) | +| `kmw-title-bar-actions` | Container for image elements in OSK title bar | +| `kmw-title-bar-image` | Active image element (button) in OSK title bar | +| `kmw-footer` | Desktop OSK footer element | +| `kmw-footer-caption` | Caption in desktop OSK footer | +| `kmw-footer-resize` | Style for the footer's resizing icon | +| `kmw-osk-static` | Container style for non-sizable keyboards | +| `kmw-osk-none` | Empty keyboard container style | +| `#kmw-pin-image` | Style of icon to return OSK to default position | +| `#kmw-config-image` | Style of icon to open configuration options window | +| `#kmw-help-image` | Style of icon to open keymanweb help window | +| `#kmw-close-button` | Style of close button image | + +### Element identifiers and class names applied to pop-up key container elements: + +| Class name | Element | +| ----------------------- | ------------------------------- | +| `#kmw-popup-keys` | Pop-up key container | +| `arrow-border` | Style setting callout arrow border | +| `arrow-content` | Style setting callout arrow background | + +### Element identifiers and class names applied to language menu elements: + +| Class name | Menu element | +| --------------------------- | ------------------------------- | +| `#kmw-language-menu` | Language menu container element | +| `#kmw-language-menu-background` | Hidden background layer preventing unwanted action while selecting a language or keyboard | +| `#kmw-menu-scroll-container` | Container for language list scroller | +| `#kmw-menu-scroller` | Langauge list scroller | +| `#kmw-menu-index` | Container for language index | +| `#kmw-menu-footer` | Placeholder at bottom of scroller | +| `kbd-list` | Style for language-list element | +| `kmw-list-open` | Style for list element when expanded | +| `kmw-list-closed` | Style for list element when not expanded | +| `kmw-list-entry` | Language entry in language list | +| `kmw-single-entry` | Single keyboard entry in language list | +| `current` | Active keyboard entry in language list | +| `selected` | Touched entry in language list | + +### Message box class names: + +| Class name | Element | +| ----------------------- | ------------------------------- | +| `kmw-wait-box` | Message box | +| `kmw-wait-background` | Message box background | +| `kmw-wait-text` | Message box wait text | +| `kmw-wait-graphic` | Message box wait icon | +| `kmw-alert-text` | Message box alert text | +| `kmw-alert-close` | Message box close icon | + +The default styles for _KeymanWeb_ can be found online at +https://github.com/keymanapp/keyman/blob/master/web/src/resources/osk/kmwosk.css. + +For the styles for specific released versions, they can also be found through +s.keyman.com, such as https://s.keyman.com/kmw/engine/17.0.326/osk/kmwosk.css +for version 17.0.326. \ No newline at end of file diff --git a/web/docs/engine/reference/osk/getRect.md b/web/docs/engine/reference/osk/getRect.md new file mode 100644 index 0000000000..a4eab65927 --- /dev/null +++ b/web/docs/engine/reference/osk/getRect.md @@ -0,0 +1,42 @@ +--- +title: getRect +--- + +## Summary + +Get absolute position and size of OSK window. + +## Syntax + +```c +keyman.osk.getRect() +``` + +### Parameters + +None. + +### Return Value + +`Object` +: The position and size of the OSK's container element. + +## Description + +The returned `getRect` object contains the following members: + +`left` +: `number` +: The x-coordinate corresponding to the left side of the OSK. + +`top` +: `number` +: The y-coordinate corresponding to the top of the OSK. + +`width` +: `number` +: The width (in pixels) of the OSK. + +`height` +: `number` +: The height (in pixels) of the OSK. diff --git a/web/docs/engine/reference/osk/hide.md b/web/docs/engine/reference/osk/hide.md new file mode 100644 index 0000000000..8d5d4e91a5 --- /dev/null +++ b/web/docs/engine/reference/osk/hide.md @@ -0,0 +1,25 @@ +--- +title: hide +--- + +## Summary + +Hides the OSK. + +## Syntax + +```c +keyman.osk.hide() +``` + +### Parameters + +None. + +### Return Value + +`undefined` + +## Description + +Hides the On-Screen Keyboard. diff --git a/web/docs/engine/reference/osk/index.md b/web/docs/engine/reference/osk/index.md new file mode 100644 index 0000000000..6f2018178b --- /dev/null +++ b/web/docs/engine/reference/osk/index.md @@ -0,0 +1,41 @@ +--- +title: On-Screen Keyboard Module +--- + +The On-Screen Keyboard module is exposed to the developer as `window.keyman.osk`. + +[`addEventListener` Function](addEventListener) +: Adds an event listener for user-handling of On-Screen keyboard events. + +[`getRect` Function](getRect) +: Get absolute position and size of OSK window. + +[`hide` Function](hide) +: Hide the OSK. + +[`isEnabled` Function](isEnabled) +: Return the user-defined OSK visibility as set by prior calls to show or hide. + +[`isVisible` Function](isVisible) +: Return the actual visibility of the On-Screen Keyboard. + +[`removeEventListener` Function](removeEventListener) +: Removes a user-defined event handler. + +[`restorePosition` Function](restorePosition) +: Move OSK back to default position, floating under active input element. + +[`setPos` Function](setPos) +: Set absolute position and size of desktop OSK window, limited to screen. + +[`setRect` Function](setRect) +: Set absolute position and size of desktop OSK window. + +[`show` Function](show) +: Display, hide or toggle OSK visibility. + +[`userLocated` Function](userLocated) +: Determine whether or not the OSK has been moved from its default position by the user. + +[Class Names and Identifiers for On-Screen Keyboard and Other KeymanWeb Elements](classes) +: The appearance of the KeymanWeb on-screen keyboard, menu amd other elements can be customized by a web designer by redefining (or adding to) the default styles. diff --git a/web/docs/engine/reference/osk/isEnabled.md b/web/docs/engine/reference/osk/isEnabled.md new file mode 100644 index 0000000000..18811bc157 --- /dev/null +++ b/web/docs/engine/reference/osk/isEnabled.md @@ -0,0 +1,26 @@ +--- +title: isEnabled +--- + +## Summary + +Return the user-defined OSK visibility as set by prior calls to [`show`](show) or [`hide`](hide). + +## Syntax + +```c +keyman.osk.isEnabled(); +``` + +### Parameters + +None. + +### Return Value + +`boolean` +: `true` if the OSK is enabled, else `false`. + +## Description + +Actual OSK visibility will also depend on whether or not the target is focused (see isVisible) diff --git a/web/docs/engine/reference/osk/isVisible.md b/web/docs/engine/reference/osk/isVisible.md new file mode 100644 index 0000000000..436436568a --- /dev/null +++ b/web/docs/engine/reference/osk/isVisible.md @@ -0,0 +1,22 @@ +--- +title: isVisible +--- + +## Summary + +Return the actual visibility of the On-Screen Keyboard. + +## Syntax + +```c +keyman.osk.isVisible(); +``` + +### Parameters + +None. + +### Return Value + +`boolean` +: `true` if the OSK is actually visible, else `false`. Note that this will usually return `false` after any UI event that results in (temporary) loss of focus. diff --git a/web/docs/engine/reference/osk/removeEventListener.md b/web/docs/engine/reference/osk/removeEventListener.md new file mode 100644 index 0000000000..19823c525f --- /dev/null +++ b/web/docs/engine/reference/osk/removeEventListener.md @@ -0,0 +1,33 @@ +--- +title: removeEventListener +--- + +## Summary + +Removes a user-defined event handler. + +## Syntax + +```c +keyman.osk.removeEventListener(eventName, func); +``` + +### Parameters + +`eventName` +: Type: `string` +: The name of an event generated by the `keyman.osk` object. + +`func` +: Type: `Function` +: A function currently set to handle that event when it is raised. + +### Return Value + +`undefined` + +## Description + +To be implemented. + +Will be the OSK's analogue of the to-be-implemented core function [`removeEventListener`](../core/removeEventListener). diff --git a/web/docs/engine/reference/osk/restorePosition.md b/web/docs/engine/reference/osk/restorePosition.md new file mode 100644 index 0000000000..ea84208a36 --- /dev/null +++ b/web/docs/engine/reference/osk/restorePosition.md @@ -0,0 +1,40 @@ +--- +title: restorePosition +--- + +## Summary + +Move OSK back to default position, floating under active input element, for +desktop OSK. + +## Syntax + +```js +keyman.osk.restorePosition(keepDefaultPosition); +``` + +## Parameters + +`keepDefaultPosition` +: `boolean` optional +: If `true` does not reset the default `left`, `top` set by [`setRect()`](setRect). +: If `false` or omitted, resets the default `left`, `top` as well. + +## Return Value + +`undefined` + +## Description + +This is the equivalent of pressing the pin in the title bar of the desktop OSK. +The user may move the OSK, after which point the OSK stays where the user has +placed it. Similarly, calling [`setPos()`](setPos) will fix the position of the +OSK. Calling `restorePosition()` resets the position of the OSK and re-attaches +it to the bottom of the active input element. + +Note that if the user clicks the pin it does not reset the default `left`, `top` +as set by `setRect()`. + +## History + +* Published as public API in 14.0.272 \ No newline at end of file diff --git a/web/docs/engine/reference/osk/setPos.md b/web/docs/engine/reference/osk/setPos.md new file mode 100644 index 0000000000..7e6c53f93a --- /dev/null +++ b/web/docs/engine/reference/osk/setPos.md @@ -0,0 +1,23 @@ +--- +title: setPos +--- + +## Summary + +Set absolute position and size of desktop OSK window, limited to screen. + +## Syntax + +```c +keyman.osk.setPos(pt) +``` + +### Parameters + +`pt` +: Type: `Object` +: An object with the two properties `left` and `top`, used to set the position of the OSK. + +### Return Value + +`undefined` diff --git a/web/docs/engine/reference/osk/setRect.md b/web/docs/engine/reference/osk/setRect.md new file mode 100644 index 0000000000..e90ed0d836 --- /dev/null +++ b/web/docs/engine/reference/osk/setRect.md @@ -0,0 +1,55 @@ +--- +title: setRect +--- + +## Summary + +Set absolute position and size of desktop OSK window. + +## Syntax + +```c +keyman.osk.setRect(p); +``` + +### Parameters + +`p` +: Type: `Object` +: An object specifying location and/or user permissions for altering the OSK's display. + +### Return Value + +`undefined` + +## Description + +The `setRect` object contains the following members: + +`left` +: `number` *optional* +: Sets the x-coordinate of the OSK's left side. + +`top` +: `number` *optional* +: Sets the y-coordinate of the OSK's top side. + +`width` +: `number` *optional* +: Sets the width of the OSK. + +`height` +: `number` *optional* +: Sets the height of the OSK. + +`nosize` +: `boolean` *optional* +: If set to `true`, prevents the user from altering the OSK's size. If set to `false`, allows the user to resize the OSK. If omitted, does not change the existing state. + +`nomove` +: `boolean` *optional* +: If set to `true`, prevents the user from relocating the OSK manually. If set to `false`, allows the user to move the OSK. If omitted, does not change the existing state. + +The values and states of omitted object members will not be changed. + +This differs from [`setPos()`](setPos) in that it allows resizing the keyboard and controlling the user's ability to move/size the keyboard. Furthermore, when `left` and `top` members are included, they override the default position of the keyboard rather than setting the position temporarily. diff --git a/web/docs/engine/reference/osk/show.md b/web/docs/engine/reference/osk/show.md new file mode 100644 index 0000000000..a2e73b6c77 --- /dev/null +++ b/web/docs/engine/reference/osk/show.md @@ -0,0 +1,27 @@ +--- +title: show +--- + +## Summary + +Display, hide or toggle OSK visibility. + +## Syntax + +```c +keyman.osk.show(mode); +``` + +### Parameters + +`mode` +: Type: `boolean` *optional* +: `true` to display, `false` to hide, omitted to toggle. + +### Return Value + +`undefined` + +## Description + +Visibility will be toggled on or off if the argument is omitted. diff --git a/web/docs/engine/reference/osk/userLocated.md b/web/docs/engine/reference/osk/userLocated.md new file mode 100644 index 0000000000..ed85dde233 --- /dev/null +++ b/web/docs/engine/reference/osk/userLocated.md @@ -0,0 +1,22 @@ +--- +title: userLocated +--- + +## Summary + +Determine whether or not the OSK has been moved from its default position by the user. + +## Syntax + +```c +keyman.osk.userLocated(); +``` + +### Parameters + +None. + +### Return Value + +`boolean` +: `true` if location is specified by the user, else `false`. diff --git a/web/docs/engine/reference/overview.md b/web/docs/engine/reference/overview.md new file mode 100644 index 0000000000..574e704abf --- /dev/null +++ b/web/docs/engine/reference/overview.md @@ -0,0 +1,25 @@ +--- +title: Overview +--- + +*KeymanWeb* is a cross-browser JavaScript input method solution. + +The *KeymanWeb 17 API* provides JavaScript functions to allow a website developer to integrate the use of +*KeymanWeb* multi-lingual keyboard mapping into a website, using either a standard or a custom-designed user-interface. The functions are exposed as API calls to the *KeymanWeb* core, the +*On-Screen Keyboard* module, a *Utility function* library, or one of the standard *User Interface* modules. + +A *KeymanWeb* instance is automatically constructed when you include the compiled KeymanWeb script (kmw-release.js) in your web page source. + +The *KeymanWeb API* comprises the following objects: + +- *Core* +: Exposed as [`keyman`](core). + +- *On-Screen Keyboard* +: Exposed as [`keyman.osk`](osk). + +- *Utility Functions* +: Exposed as [`keyman.util`](util). + +- *User Interface* +: Exposed as [`keyman.ui`](ui). diff --git a/web/docs/engine/reference/ui/button.md b/web/docs/engine/reference/ui/button.md new file mode 100644 index 0000000000..6c90d518e7 --- /dev/null +++ b/web/docs/engine/reference/ui/button.md @@ -0,0 +1,15 @@ +--- +title: "Button" Interface +--- + +The simplest user interface is the "button" UI, which appears at a fixed +position on the web page, and is attached to an empty 'Div' element with +id='KeymanWebControl' added to the page where appropriate. + +When the mouse is hovered over the 'button' UI, a menu of supported +input languages and keyboards is shown: + +![](images/ui_button.png) + +In this example, a Japanese keyboard with an Input Method Editor (IME) +has been selected. diff --git a/web/docs/engine/reference/ui/float.md b/web/docs/engine/reference/ui/float.md new file mode 100644 index 0000000000..bf97c556d5 --- /dev/null +++ b/web/docs/engine/reference/ui/float.md @@ -0,0 +1,13 @@ +--- +title: "Float" Interface +--- + +The "float" user interface (the original +*KeymanWeb* user interface) appears as a +drop-down list of available keyboards below the currently focused +element: + +![](images/ui_float.png) + +An initialization option allows the interface element to be aligned at +the right of the focused element if preferred. diff --git a/web/docs/engine/reference/ui/images/ui_button.png b/web/docs/engine/reference/ui/images/ui_button.png new file mode 100644 index 0000000000..c4225ee83a Binary files /dev/null and b/web/docs/engine/reference/ui/images/ui_button.png differ diff --git a/web/docs/engine/reference/ui/images/ui_float.png b/web/docs/engine/reference/ui/images/ui_float.png new file mode 100644 index 0000000000..5ed6a977cc Binary files /dev/null and b/web/docs/engine/reference/ui/images/ui_float.png differ diff --git a/web/docs/engine/reference/ui/images/ui_toggle.png b/web/docs/engine/reference/ui/images/ui_toggle.png new file mode 100644 index 0000000000..88c55f7b54 Binary files /dev/null and b/web/docs/engine/reference/ui/images/ui_toggle.png differ diff --git a/web/docs/engine/reference/ui/images/ui_toolbar.png b/web/docs/engine/reference/ui/images/ui_toolbar.png new file mode 100644 index 0000000000..428ec2b2e6 Binary files /dev/null and b/web/docs/engine/reference/ui/images/ui_toolbar.png differ diff --git a/web/docs/engine/reference/ui/index.md b/web/docs/engine/reference/ui/index.md new file mode 100644 index 0000000000..74788baf51 --- /dev/null +++ b/web/docs/engine/reference/ui/index.md @@ -0,0 +1,43 @@ +--- +title: Desktop User Interfaces +--- + +Four different KeymanWeb user interfaces for desktop browsers are +included, allowing users to select and enable keyboard mapping from a +list of installed keyboards, and to control the visibility of the +On-Screen Keyboard. + +["Button" Interface](button) +: The simplest user interface is the "button" UI, which appears at a + fixed position on the web page, and is attached to an empty 'Div' + element with id='KeymanWebControl' added to the page where + appropriate. + + + +["Toggle" Interface](toggle) +: The "toggle" user interface provides a drop-down list of supported + input languages and keyboards, and moves with the focus to appear at + the right hand side of the focused element. + + + +["Float" Interface](float) +: The "float" user interface (the original KeymanWeb user interface) + appears as a drop-down list of available keyboards below the + currently focused element + + + +["Toolbar" Interface](toolbar) +: For pages which must support a large number of languages from many + regions, we recommend using our "toolbar" user interface, which + displays a drop-down map allowing users to first choose the region + from the map or by name, then select input language by country. + +Alternatively, developers may implement a custom interface for desktop +browsers with appropriate corporate branding, using the various API +functions to manage keyboard selection and display. + +For touch-screen devices, the user-interface is integrated into the +On-Screen Keyboard, and cannot be overridden by the developer. diff --git a/web/docs/engine/reference/ui/toggle.md b/web/docs/engine/reference/ui/toggle.md new file mode 100644 index 0000000000..dc5ed97d4d --- /dev/null +++ b/web/docs/engine/reference/ui/toggle.md @@ -0,0 +1,20 @@ +--- +title: "Toggle" Interface +--- + +The "toggle" user interface provides a drop-down list of supported input +languages and keyboards, and moves with the focus to appear at the right +hand side of the focused element: + +![](images/ui_toggle.png) + +The "toggle" interface also supports the use of "hot keys" to simplify +keyboard use: + +| Hot key | Action | +|:---------------------------------------------|:----------------------------------------| +| *Ctrl /* | enable/disable currently selected keyboard | +| *Ctrl Shift /* | select next listed keyboard | +| *Alt /* | enable/disable OSK display | + + diff --git a/web/docs/engine/reference/ui/toolbar.md b/web/docs/engine/reference/ui/toolbar.md new file mode 100644 index 0000000000..23dc943ee3 --- /dev/null +++ b/web/docs/engine/reference/ui/toolbar.md @@ -0,0 +1,19 @@ +--- +title: "Toolbar" Interface +--- + +For pages which must support a large number of languages from many +regions, we recommend using our "toolbar" user interface, which displays +a drop-down map allowing users to first choose the region from the map +or by name, then select input language by country. A second drop-down +list is displayed (as shown here) if more than one keyboard is available +for the selected language. + +The "toolbar" user interface is attached to any DIV element on the page +(by giving that element the +*id='KeymanWebControl'*), and remains +fixed in position with respect to that element, but the On-Screen +Keyboard moves to each focused input element, unless fixed in position +by the user. + +![](images/ui_toolbar.png) diff --git a/web/docs/engine/reference/util/addStyleSheet.md b/web/docs/engine/reference/util/addStyleSheet.md new file mode 100644 index 0000000000..004bcacdc3 --- /dev/null +++ b/web/docs/engine/reference/util/addStyleSheet.md @@ -0,0 +1,32 @@ +--- +title: addStyleSheet +--- + +## Summary + +Generates a style sheet element for use in adding or overriding default On-Screen Keyboard styles. + +## Syntax + +```c +keyman.util.addStyleSheet(sheet) +``` + +### Parameters + +`sheet` +: Type: `string` +: A string representing a CSS style sheet. + +### Return Value + +`Object` +: A page element representing the newly-embedded style sheet. + +## Description + +See our list of [standard OSK style names](../osk/classes) as a reference if implementing your own stylesheets. + +See also: +- [`keyman.util.linkStyleSheet()`](linkStyleSheet) +- [`keyman.util.removeStyleSheet()`](removeStyleSheet) diff --git a/web/docs/engine/reference/util/alert.md b/web/docs/engine/reference/util/alert.md new file mode 100644 index 0000000000..65cb3922e1 --- /dev/null +++ b/web/docs/engine/reference/util/alert.md @@ -0,0 +1,32 @@ +--- +title: alert +--- + +## Summary + +Generates a KeymanWeb alert window. + +## Syntax + +```c +keyman.util.alert(msg, fn) +``` + +### Parameters + +`msg` +: Type: `string` +: Alert message text. + +`fn` +: Type: `function()` *optional* +: Function to be called upon alert dismissal. + +### Return Value + +`undefined` + +## Description + +The optional second parameter specifies a function to be called when the +window is dismissed. \ No newline at end of file diff --git a/web/docs/engine/reference/util/attachDOMEvent.md b/web/docs/engine/reference/util/attachDOMEvent.md new file mode 100644 index 0000000000..41540e70bd --- /dev/null +++ b/web/docs/engine/reference/util/attachDOMEvent.md @@ -0,0 +1,43 @@ +--- +title: attachDOMEvent +--- + +## Summary + +Attach user-defined event handler for any DOM event for an element. + +## Syntax + +```c +keyman.util.attachDOMEvent(Pelem, eventName, handler, useCapture); +``` + +### Parameters + +`Pelem` +: Type: `Element` +: Element to which the event is being attached. + +`eventName` +: Type: `string` +: The name of the event, without an 'on' prefix. + +`handler` +: Type: `function(Object)` +: The event handler being attached. + +`useCapture` +: Type: `boolean` *optional* +: Set this to `true` if the event should be captured in the bubbling phase; otherwise, use `false` or leave this parameter empty. + +### Return Value + +`undefined` + +## Description + +The event name should be specified without the 'on' prefix. The fourth argument, useCapture, is optional and will default to false. + +The method exists for legacy reasons that arise when dealing with old versions of IE, simplifying event-handling code. + +See also: [`keyman.util.detachDOMEvent`](detachDOMEvent) diff --git a/web/docs/engine/reference/util/createElement.md b/web/docs/engine/reference/util/createElement.md new file mode 100644 index 0000000000..198ba7117b --- /dev/null +++ b/web/docs/engine/reference/util/createElement.md @@ -0,0 +1,28 @@ +--- +title: createElement +--- + +## Summary + +Create an unselectable HTML element for the *KeymanWeb* On-Screen keyboard and User Interfaces. + +## Syntax + +```c +keyman.util.createElement(nodeName); +``` + +### Parameters + +`nodeName` +: Type: `string` +: Name for the newly-created element. + +### Return Value + +`Element` +: The new, requested user-unselectable HTML element. + +## Description + +Elements created with this function do not capture the focus. Use `document.createElement` to create normally selectable elements. diff --git a/web/docs/engine/reference/util/detachDOMEvent.md b/web/docs/engine/reference/util/detachDOMEvent.md new file mode 100644 index 0000000000..8227ed8ebe --- /dev/null +++ b/web/docs/engine/reference/util/detachDOMEvent.md @@ -0,0 +1,41 @@ +--- +title: detachDOMEvent +--- + +## Summary + +Detach DOM event handler from element to prevent memory leaks. + +## Syntax + +```c +keyman.util.detachDOMEvent(); +``` + +### Parameters + +`Pelem` +: Type: `Element` +: Element from which the event is being detached. + +`eventName` +: Type: `string` +: The name of the event, without an 'on' prefix. + +`handler` +: Type: `function(Object)` +: The event handler being detached. + +`useCapture` +: Type: `boolean` *optional* +: Set this to `true` if the event was being captured in the bubbling phase; otherwise, use `false` or leave this parameter empty. + +### Return Value + +`undefined` + +## Description + +The fourth argument, useCapture, is optional and will default to false. + +See also: [`keyman.util.attachDOMEvent`](attachDOMEvent) diff --git a/web/docs/engine/reference/util/getAbsolute.md b/web/docs/engine/reference/util/getAbsolute.md new file mode 100644 index 0000000000..d1a5f12680 --- /dev/null +++ b/web/docs/engine/reference/util/getAbsolute.md @@ -0,0 +1,30 @@ +--- +title: getAbsolute +--- + +## Summary + +Get the absolute position of an element. + +## Syntax + +```c +keyman.util.getAbsolute(Pelem); +``` + +### Parameters + +`Pelem` +: Type: `Element` +: An HTML element. + +### Return Value + +`Object` +: An object with two `number` properties (`x` and `y`) corresponding to the specified element's absolute position on the page. + +## Description + +See also: +- [`keyman.util.getAbsoluteX()`](getAbsoluteX) +- [`keyman.util.getAbsoluteY()`](getAbsoluteY) diff --git a/web/docs/engine/reference/util/getAbsoluteX.md b/web/docs/engine/reference/util/getAbsoluteX.md new file mode 100644 index 0000000000..3b9e57a3ca --- /dev/null +++ b/web/docs/engine/reference/util/getAbsoluteX.md @@ -0,0 +1,30 @@ +--- +title: getAbsoluteX +--- + +## Summary + +Get the absolute x-coordinate of an element. + +## Syntax + +```c +keyman.util.getAbsoluteX(Pelem); +``` + +### Parameters + +`Pelem` +: Type: `Element` +: An HTML element. + +### Return Value + +`number` +: The specified element's absolute x-coordinate on the page. + +## Description + +See also: +- [`keyman.util.getAbsolute()`](getAbsolute) +- [`keyman.util.getAbsoluteY()`](getAbsoluteY) diff --git a/web/docs/engine/reference/util/getAbsoluteY.md b/web/docs/engine/reference/util/getAbsoluteY.md new file mode 100644 index 0000000000..c41d75c2fd --- /dev/null +++ b/web/docs/engine/reference/util/getAbsoluteY.md @@ -0,0 +1,30 @@ +--- +title: getAbsoluteY +--- + +## Summary + +Get the absolute y-coordinate of an element. + +## Syntax + +```c +keyman.util.getAbsoluteY(Pelem); +``` + +### Parameters + +`Pelem` +: Type: `Element` +: An HTML element. + +### Return Value + +`number` +: The specified element's absolute y-coordinate on the page. + +## Description + +See also: +- [`keyman.util.getAbsolute()`](getAbsolute) +- [`keyman.util.getAbsoluteX()`](getAbsoluteX) diff --git a/web/docs/engine/reference/util/getOption.md b/web/docs/engine/reference/util/getOption.md new file mode 100644 index 0000000000..5e182abeb0 --- /dev/null +++ b/web/docs/engine/reference/util/getOption.md @@ -0,0 +1,32 @@ +--- +title: getOption +--- + +## Summary + +Get a KeymanWeb, On-Screen Keyboard or User Interface option value. + +## Syntax + +```c +keyman.util.getOption(optionName, dflt); +``` + +### Parameters + +`optionName` +: Type: `string` +: The named initialization option. + +`dflt` +: Type: `string|Object` *optional* +: The value to return if the option is not set. + +### Return Value + +`string|Object` +: The value of the option (if set). If not set and no value is provided for `dflt`, returns the empty string. + +## Description + +See also [`keyman.util.setOption()`](setOption). diff --git a/web/docs/engine/reference/util/index.md b/web/docs/engine/reference/util/index.md new file mode 100644 index 0000000000..f599e3d5d6 --- /dev/null +++ b/web/docs/engine/reference/util/index.md @@ -0,0 +1,65 @@ +--- +title: Utility Module +--- + +The KeymanWeb Utility Function module is exposed to the developer as `window.keyman.util`. + +[`addStyleSheet` Function](addStyleSheet) +: Add or override default On-Screen Keyboard styles. + +[`alert` Function](alert) +: Customized alert window. + +[`attachDOMEvent` Function](attachDOMEvent) +: Attach user-defined event handler for any DOM event for an element. + +[`createElement` Function](createElement) +: Create an unselectable HTML element for the KeymanWeb On-Screen + keyboard and User Interfaces. + +[`detachDOMEvent` Function](detachDOMEvent) +: Detach DOM event handler from element to prevent memory leaks. + +[`getAbsolute` Function](getAbsolute) +: Get the absolute position of an element. + +[`getAbsoluteX` Function](getAbsoluteX) +: Get the absolute y-coordinate of an element. + +[`getAbsoluteY` Function](getAbsoluteY) +: Get the absolute y-coordinate of an element. + +[`getOption` Function](getOption) +: Get a KeymanWeb, On-Screen Keyboard or User Interface option value. + +[`isTouchDevice` Function](isTouchDevice) +: Allow external callers (such as UIs) to detect if the active device + is touch sensitive. + +[`linkStyleSheet` Function](linkStyleSheet) +: Add a reference to an external stylesheet file. + +[`loadCookie` Function](loadCookie) +: Get a document cookie, or an array of all document cookies. + +[`removeStyleSheet` Function](removeStyleSheet) +: Remove user-defined style sheet. + +[`rgba` Function](rgba) +: Browser-independent alpha-channel management. + +[`saveCookie` Function](saveCookie) +: Save document variables as a cookie. + +[`setOption` Function](setOption) +: Set a KeymanWeb, On-Screen Keyboard or User Interface option value. + +[`toFloat` Function](toFloat) +: Floating conversion with default. + +[`toNumber` Function](toNumber) +: Integer conversion with default. + +[`toNzString` Function](toNzString) +: Returns default string value if argument is null, false, an empty + string, or undefined. diff --git a/web/docs/engine/reference/util/isTouchDevice.md b/web/docs/engine/reference/util/isTouchDevice.md new file mode 100644 index 0000000000..2531aca196 --- /dev/null +++ b/web/docs/engine/reference/util/isTouchDevice.md @@ -0,0 +1,29 @@ +--- +title: isTouchDevice +--- + +## Summary + +Allow external callers (such as UIs) to detect if the active device is considered touch sensitive by KeymanWeb. + +## Syntax + +```c +keyman.util.isTouchDevice(); +``` + +### Parameters + +None. + +### Return Value + +`boolean` +: `true` if KMW is targetting touch-sensitivity for the device, otherwise `false`. + +``` +isTouchDevice ... +``` + +> [!Note] +> In current versions of KeymanWeb this function will return `false` for touchscreen laptops; current touch support is specialized for mobile phones and tablets. diff --git a/web/docs/engine/reference/util/linkStyleSheet.md b/web/docs/engine/reference/util/linkStyleSheet.md new file mode 100644 index 0000000000..c163a411e7 --- /dev/null +++ b/web/docs/engine/reference/util/linkStyleSheet.md @@ -0,0 +1,29 @@ +--- +title: linkStyleSheet +--- + +## Summary + +Add a reference to an external stylesheet file. + +## Syntax + +```c +keyman.util.linkStyleSheet(s); +``` + +### Parameters + +`s` +: Type: `string` +: Path to a pre-existing stylesheet file. + +### Return Value + +`undefined` + +## Description + +See also: +- [`keyman.util.addStyleSheet()`](addStyleSheet) +- [`keyman.util.removeStyleSheet()`](removeStyleSheet). diff --git a/web/docs/engine/reference/util/loadCookie.md b/web/docs/engine/reference/util/loadCookie.md new file mode 100644 index 0000000000..e9215a8854 --- /dev/null +++ b/web/docs/engine/reference/util/loadCookie.md @@ -0,0 +1,28 @@ +--- +title: loadCookie +--- + +## Summary + +Get a document cookie, or an array of all document cookies. + +## Syntax + +```c +keyman.util.loadCookie(cn); +``` + +### Parameters + +`cn` +: Type: `string` **optional** +: Name of the cookie to be loaded if not loading the default cookie. + +### Return Value + +`Object` +: An array of names and strings or an array of variables and values. + +## Description + +... diff --git a/web/docs/engine/reference/util/removeStyleSheet.md b/web/docs/engine/reference/util/removeStyleSheet.md new file mode 100644 index 0000000000..2e0c097726 --- /dev/null +++ b/web/docs/engine/reference/util/removeStyleSheet.md @@ -0,0 +1,32 @@ +--- +title: removeStyleSheet +--- + +## Summary + +Remove user-defined style sheet. + +## Syntax + +```c +keyman.util.removeStyleSheet(Pelem); +``` + +### Parameters + +`Pelem` +: Type: `Element` +: Element representing the style sheet to be removed. + +### Return Value + +`boolean` +: `true` if the style sheet element was successfully removed, otherwise `false`. + +## Description + +If the element does not represent a style sheet, this function will not remove the element and will simply return `false`. + +See also: +- [`keyman.util.addStyleSheet()`](addStyleSheet) +- [`keyman.util.linkStyleSheet()`](linkStyleSheet) diff --git a/web/docs/engine/reference/util/rgba.md b/web/docs/engine/reference/util/rgba.md new file mode 100644 index 0000000000..6107034b48 --- /dev/null +++ b/web/docs/engine/reference/util/rgba.md @@ -0,0 +1,44 @@ +--- +title: rgba +--- + +## Summary + +Browser-independent alpha-channel management. + +## Syntax + +```c +keyman.util.rgba(s, r, g, b, a); +``` + +### Parameters + +`s` +: Type: `Element` +: Element style object + +`r` +: Type: `number` +: Value for red (0-255) + +`g` +: Type: `number` +: Value for green (0-255) + +`b` +: Type: `number` +: Value for blue (0-255) + +`a` +: Type: `number` +: Value for alpha/opacity (0-1.0) + +### Return Value + +`string` +: Background color CSS value. + +## Description + +This function returns the required string value for setting background transparency, and applies an appropriate `a` filter to the element for IE versions before IE9. diff --git a/web/docs/engine/reference/util/saveCookie.md b/web/docs/engine/reference/util/saveCookie.md new file mode 100644 index 0000000000..66c97a29ef --- /dev/null +++ b/web/docs/engine/reference/util/saveCookie.md @@ -0,0 +1,31 @@ +--- +title: saveCookie +--- + +## Summary + +Save document variables as a cookie. + +## Syntax + +```c +keyman.util.saveCookie(cn, cv); +``` + +### Parameters + +`cn` +: Type: `string` +: Name of the cookie to save. + +`cv` +: Type: `Object` +: An array of named arguments and values. + +### Return Value + +`undefined` + +## Description + +... diff --git a/web/docs/engine/reference/util/setOption.md b/web/docs/engine/reference/util/setOption.md new file mode 100644 index 0000000000..0596bf0e11 --- /dev/null +++ b/web/docs/engine/reference/util/setOption.md @@ -0,0 +1,31 @@ +--- +title: setOption +--- + +## Summary + +Set a KeymanWeb, On-Screen Keyboard or User Interface option value. + +## Syntax + +```c +keyman.util.setOption(optionName, value); +``` + +### Parameters + +`optionName` +: Type: `string` +: The named initialization option. + +`value` +: Type: `string|Object` *optional* +: The value the option will be set to. Clears the option's current value if left blank. + +### Return Value + +`undefined` + +## Description + +See also [`keyman.util.getOption()`](getOption). diff --git a/web/docs/engine/reference/util/toFloat.md b/web/docs/engine/reference/util/toFloat.md new file mode 100644 index 0000000000..549af81e07 --- /dev/null +++ b/web/docs/engine/reference/util/toFloat.md @@ -0,0 +1,32 @@ +--- +title: toFloat +--- + +## Summary + +Floating conversion with default. + +## Syntax + +```c +keyman.util.toFloat(s, dflt); +``` + +### Parameters + +`s` +: Type: `string` +: Numeric string. + +`dflt` +: Type: `number` +: Default value if parse is unsuccessful. + +### Return Value + +`number` +: The string's conversion to a numeric value, or the default value if unsuccessful. + +## Description + +... diff --git a/web/docs/engine/reference/util/toNumber.md b/web/docs/engine/reference/util/toNumber.md new file mode 100644 index 0000000000..a71950ec5a --- /dev/null +++ b/web/docs/engine/reference/util/toNumber.md @@ -0,0 +1,32 @@ +--- +title: toNumber +--- + +## Summary + +String -> number conversion, with default. + +## Syntax + +```c +keyman.util.toNumber(s, dflt); +``` + +### Parameters + +`s` +: Type: `string` +: Numeric string. + +`dflt` +: Type: `number` +: Default value if parse is unsuccessful. + +### Return Value + +`number` +: The string's conversion to a whole-number numeric value, or the default value if unsuccessful. + +## Description + +... diff --git a/web/docs/engine/reference/util/toNzString.md b/web/docs/engine/reference/util/toNzString.md new file mode 100644 index 0000000000..b1b98af6f1 --- /dev/null +++ b/web/docs/engine/reference/util/toNzString.md @@ -0,0 +1,32 @@ +--- +title: toNzString +--- + +## Summary + +Returns string value for the item, or the default string value if the argument is null, false, an empty string, or undefined. + +## Syntax + +```c +keyman.util.toNzString(item, dflt); +``` + +### Parameters + +`item` +: Type: `*` +: Variable to convert. + +`dflt` +: Type: `*` *optional* +: Value to use of the converted variable is null, false, the empty string, or undefined. + +### Return Value + +`string` +: The string equivalent value for the item being converted. + +## Description + +... diff --git a/web/docs/engine/troubleshooting/embedded_fonts.md b/web/docs/engine/troubleshooting/embedded_fonts.md new file mode 100644 index 0000000000..81215add20 --- /dev/null +++ b/web/docs/engine/troubleshooting/embedded_fonts.md @@ -0,0 +1,53 @@ +--- +title: Embedded Font Troubleshooting +--- + +KeymanWeb allows users to display and enter text that may require a font +not normally installed with your operating system, by including +(embedding) a special copy of a suitable font in the web page. + +However, many older browsers do not support the use of embedded fonts. +This test page will help you to find out whether or not your browser +supports the use of embedded fonts for a number of languages which may +not be fully supported by your operating system. + +In the table below, the left column has an image showing how the sample +text should appear, the center column displays the sample text using a +font installed on your system, if available, and the right column shows +the same sample text displayed using an embedded font downloaded +automatically with this web page. + +--- +**Note:** This page may take a minute or more to load all of the fonts +needed to display correctly. + +--- + +| Language | Sample text - image | Sample text - installed font | Sample text - embedded font\* | +|----------|---------------------|------------------------------|-------------------------------| +| Amharic | ![](images/GeezSample.png) | ኢትዮጵያ | ኢትዮጵያ | +| Burmese | ![](images/BurmeseSample.png) | မြန်မာအက္ခရာ | မြန်မာအက္ခရာ | +| Dinka | ![](images/DinkaSample.png) | Thuɔŋjäŋ | Thuɔŋjäŋ | +| Khmer | ![](images/KhmerSample.png) | ភាសាខ្មែរ | ភាសាខ្មែរ | +| Lao | ![](images/LaoSample.png) | ພາສາລາວກໍໄດ້ | ພາສາລາວກໍໄດ້ | +| Oriya | ![](images/OriyaSample.png) | ଓଡ଼ିଆ | ଓଡ଼ିଆ | +| Sinhala | ![](images/SinhalaSample.png) | සිංහල | සිංහල | +| Tamil | ![](images/TamilSample.png) | தமிழ் | தமிழ் | +| Tibetan | ![](images/TibetanSample.png) | བོད་ཡུལ། | བོད་ཡུལ། | + +--- +**If the embedded font display for a language is not exactly the same as in the corresponding image,** +for example, with script characters shown +but incorrectly positioned or ordered, you will need to install the +Keyman Desktop package for your language onto your computer. You can +download the Keyman Desktop package by clicking the "Help on this +keyboard" link in the On Screen Keyboard. This is likely to be observed +with scripts such as Burmese, Khmer or Tibetan if your operating system +does not fully support the display of the font used for those scripts. + +--- + +## More Help + +If you are experiencing continued difficulty in using KeymanWeb and have not been able to find a solution on this site, [please contact us](/contact). + diff --git a/web/docs/engine/troubleshooting/images/BurmeseSample.png b/web/docs/engine/troubleshooting/images/BurmeseSample.png new file mode 100644 index 0000000000..5a5d2707f2 Binary files /dev/null and b/web/docs/engine/troubleshooting/images/BurmeseSample.png differ diff --git a/web/docs/engine/troubleshooting/images/DinkaSample.png b/web/docs/engine/troubleshooting/images/DinkaSample.png new file mode 100644 index 0000000000..b26e5a92f6 Binary files /dev/null and b/web/docs/engine/troubleshooting/images/DinkaSample.png differ diff --git a/web/docs/engine/troubleshooting/images/GeezSample.png b/web/docs/engine/troubleshooting/images/GeezSample.png new file mode 100644 index 0000000000..230ea58b93 Binary files /dev/null and b/web/docs/engine/troubleshooting/images/GeezSample.png differ diff --git a/web/docs/engine/troubleshooting/images/KhmerSample.png b/web/docs/engine/troubleshooting/images/KhmerSample.png new file mode 100644 index 0000000000..e00a40b10b Binary files /dev/null and b/web/docs/engine/troubleshooting/images/KhmerSample.png differ diff --git a/web/docs/engine/troubleshooting/images/LaoSample.png b/web/docs/engine/troubleshooting/images/LaoSample.png new file mode 100644 index 0000000000..a2179bcc9e Binary files /dev/null and b/web/docs/engine/troubleshooting/images/LaoSample.png differ diff --git a/web/docs/engine/troubleshooting/images/OriyaSample.png b/web/docs/engine/troubleshooting/images/OriyaSample.png new file mode 100644 index 0000000000..e2aef1c7e1 Binary files /dev/null and b/web/docs/engine/troubleshooting/images/OriyaSample.png differ diff --git a/web/docs/engine/troubleshooting/images/SinhalaSample.png b/web/docs/engine/troubleshooting/images/SinhalaSample.png new file mode 100644 index 0000000000..bb9cd40522 Binary files /dev/null and b/web/docs/engine/troubleshooting/images/SinhalaSample.png differ diff --git a/web/docs/engine/troubleshooting/images/TamilSample.png b/web/docs/engine/troubleshooting/images/TamilSample.png new file mode 100644 index 0000000000..20c7812aa4 Binary files /dev/null and b/web/docs/engine/troubleshooting/images/TamilSample.png differ diff --git a/web/docs/engine/troubleshooting/images/TibetanSample.png b/web/docs/engine/troubleshooting/images/TibetanSample.png new file mode 100644 index 0000000000..cd1c10e125 Binary files /dev/null and b/web/docs/engine/troubleshooting/images/TibetanSample.png differ diff --git a/web/docs/engine/troubleshooting/images/bigone.bmp b/web/docs/engine/troubleshooting/images/bigone.bmp new file mode 100644 index 0000000000..2b875ab02f Binary files /dev/null and b/web/docs/engine/troubleshooting/images/bigone.bmp differ diff --git a/web/docs/engine/troubleshooting/images/boxes.gif b/web/docs/engine/troubleshooting/images/boxes.gif new file mode 100644 index 0000000000..5cb8151a7a Binary files /dev/null and b/web/docs/engine/troubleshooting/images/boxes.gif differ diff --git a/web/docs/engine/troubleshooting/images/ctrlkey.gif b/web/docs/engine/troubleshooting/images/ctrlkey.gif new file mode 100644 index 0000000000..13054987c3 Binary files /dev/null and b/web/docs/engine/troubleshooting/images/ctrlkey.gif differ diff --git a/web/docs/engine/troubleshooting/images/incorrect-tibetan1.gif b/web/docs/engine/troubleshooting/images/incorrect-tibetan1.gif new file mode 100644 index 0000000000..1f4b48525c Binary files /dev/null and b/web/docs/engine/troubleshooting/images/incorrect-tibetan1.gif differ diff --git a/web/docs/engine/troubleshooting/images/incorrect-tibetan2.gif b/web/docs/engine/troubleshooting/images/incorrect-tibetan2.gif new file mode 100644 index 0000000000..8d91858f88 Binary files /dev/null and b/web/docs/engine/troubleshooting/images/incorrect-tibetan2.gif differ diff --git a/web/docs/engine/troubleshooting/images/oskeyboard.gif b/web/docs/engine/troubleshooting/images/oskeyboard.gif new file mode 100644 index 0000000000..4f03d41a4e Binary files /dev/null and b/web/docs/engine/troubleshooting/images/oskeyboard.gif differ diff --git a/web/docs/engine/troubleshooting/images/pin.gif b/web/docs/engine/troubleshooting/images/pin.gif new file mode 100644 index 0000000000..5e6f0997d6 Binary files /dev/null and b/web/docs/engine/troubleshooting/images/pin.gif differ diff --git a/web/docs/engine/troubleshooting/images/ui-bt-hidekb.gif b/web/docs/engine/troubleshooting/images/ui-bt-hidekb.gif new file mode 100644 index 0000000000..a22745688d Binary files /dev/null and b/web/docs/engine/troubleshooting/images/ui-bt-hidekb.gif differ diff --git a/web/docs/engine/troubleshooting/images/ui-tb-control6.gif b/web/docs/engine/troubleshooting/images/ui-tb-control6.gif new file mode 100644 index 0000000000..e24085f61d Binary files /dev/null and b/web/docs/engine/troubleshooting/images/ui-tb-control6.gif differ diff --git a/web/docs/engine/troubleshooting/index.md b/web/docs/engine/troubleshooting/index.md new file mode 100644 index 0000000000..019401f8ee --- /dev/null +++ b/web/docs/engine/troubleshooting/index.md @@ -0,0 +1,92 @@ +--- +title: Troubleshooting +--- + +Listed below are some difficulties occasionally experienced when using +KeymanWeb. The information on this page is continually reviewed and +updated, and other questions are addressed in the [Keyman Community](https://community.software.sil.org/c/keyman). + +- [Why are boxes appearing when I type?](#boxes) +- [Why isn't my language appearing correctly?](#one) +- [Why can't I see the On-Screen Keyboard?](#two) +- [Why can I only type in English?](#three) + + + +#### Boxes (Characters do not Appear) + + + +If empty boxes, or boxes containing Unicode character codes, appear in +your text box when you type (and/or on the On-Screen Keyboard), as in +the images on the right, please check the following: + +- Confirm that your browser supports embedded fonts and is up to date, + as some earlier versions of browsers do not include this feature. In + this case, to enable KeymanWeb to function properly, you will need + to update your browser or download the specific font required for + your keyboard. +- If you copy and paste text that you have typed in KeymanWeb into + another application such as Microsoft Word, you may find that it + does not display. In this case, you will need to installing the + Keyman Desktop package for the keyboard onto your computer. You can + download the Keyman Desktop package by clicking the "Help on this + keyboard" link in the On Screen Keyboard. +- An [embedded font test page](embedded_fonts) is available for further testing of embedded font support on your computer. + + + +#### Characters are not Displayed Correctly + + + +If you find that you can see the characters for a language on screen, +but they don't display quite right, you may be experiencing a limitation +in your operating system. An example of this is visible in the Tibetan +script on the right. Installing Keyman Desktop or Keyman for Mac may +help resolve these issues. + + + +#### Disappearing On-Screen Keyboard + +If the [On-Screen Keyboard](osk) does not appear, or disappears as soon +as you move it, please check the following: + +- Make sure KeymanWeb is activated by clicking in the text area. +- Confirm that the [On-Screen Keyboard](osk) is turned on. In the + **Button** interface, the first item in the Keyboard Menu should be + ![Hide Keyboard](images/ui-bt-hidekb.gif), while in the other user + interface designs, the On-Screen Keyboard icon ![On-Screen Keyboard](images/ui-tb-control6.gif) should have a box around it. +- Ensure that a keyboard has been actively selected. The On-Screen + Keyboard will not display for the default operating system keyboard, + which is generally available as the first selectable keyboard on + KeymanWeb desktop user interfaces. +- Scroll up and down (and across if necessary) the website to see if + the On-Screen Keyboard is actually being displayed, but is in a + different position. +- For more information on using the On-Screen Keyboard, [click + here](osk). + + + +#### English Letters + +If English letters appear when you type, rather than your language, +please check the following: + +- Confirm that KeymanWeb is activated for the textbox or text area you + are typing into. +- Make sure you have selected the correct keyboard for the language + you wish to use. Some languages use more than one writing system, + and these are often available as different keyboards. +- For more information on the KeymanWeb user interfaces, [click + here](../ui). + + + +#### More Help + +If you are experiencing continued difficulty in using KeymanWeb and have not been able to find a solution on this page, [click here](/contact). + + diff --git a/web/docs/engine/troubleshooting/osk.md b/web/docs/engine/troubleshooting/osk.md new file mode 100644 index 0000000000..7adc06bba0 --- /dev/null +++ b/web/docs/engine/troubleshooting/osk.md @@ -0,0 +1,83 @@ +--- +title: What is a Keyboard? +--- + +When using KeymanWeb, the term *keyboard* refers specifically to +the way the keys are arranged for a specific language (i.e. which letter +or character appears when a given key is pressed). Some languages have +more than one keyboard layout; a typewriter-based layout and a phonetic +layout, for example. + +This page gives information about KeymanWeb's On-Screen Keyboard: the +map of the keyboard which appears on a website when KeymanWeb is in use. + +#### On-Screen Keyboard + +![On-Screen Keyboard Image](images/oskeyboard.gif) + +The **On-Screen Keyboard** *(left)* displays the layout of the keyboard +you are currently using. When you press any key, the blue character or +letter marked on the On-Screen Keyboard will appear in the textbox. Many +keyboards also use combinations of **Shift**, **Ctrl** or **Alt** and +letter keys to include more characters. When Shift, Ctrl or Alt is +pressed, the On-Screen Keyboard display will change to show these +characters. + +You can also use the On-Screen Keyboard to enter text directly, without +pressing any keys on your physical keyboard. Click once on any character +displayed on the On-Screen-Keyboard, and it will be entered into the +textbox. Shift-, Ctrl- and Alt- combinations also work with this method: +click once on Shift, for example, and it will stay 'pressed' until it is +clicked again or the physical Shift key is pressed. Although text entry +using this method can be less efficient, it can be useful when a +non-English physical keyboard is attached to the computer in use. + +#### **Moving and Hiding the On-Screen Keyboard** + +The On-Screen Keyboard can be moved to any area of the website which is +being displayed. It can be placed in a more convenient position for +referring to when typing, or moved out of the way if it is obscuring +part of the textbox or another part of the screen. To move the On-Screen +Keyboard, move the mouse pointer over the On-Screen Keyboard's title bar +(where the title 'Tavultesoft Keyman' is displayed), and the pointer +will change to a four-way arrow. Hold down the left mouse button, drag +the Keyboard to your desired posistion and release the mouse button. The +On-Screen Keyboard will remain in the new position until it is moved +again. + +When you move the On-Screen Keyboard, a drawing pin icon ![](images/pin.gif) will appear in the title bar. Clicking on the drawing pin icon will return the On-Screen Keyboard to its original position near the KeymanWeb Control. + +If you are familiar with the layout of the keyboard in use and do not +need to refer to the On-Screen Keyboard, it can be hidden (and displayed +again if necessary) using the KeymanWeb Control. The method for hiding +and displaying the On-Screen Keyboard varies slightly (it is done +through either a menu item or a button) depending on which User +Interface is configured on your website. Please refer to the specific +[User Interface pages](../ui) for more details. + +#### **Resizing the On-Screen Keyboard** + +You can also change the size of the On-Screen Keyboard. For example, you +may choose to make the On-Screen Keyboard smaller, instead of moving it, +to better fit it on your screen; or you might like to enlarge the +On-Screen Keyboard to make it clearer and easier to refer to. + +![Ctrl Key Image](images/ctrlkey.gif) + +To resize the On-Screen Keyboard, move the mouse pointer over the shaded +corner of the 'Ctrl' Key at its bottom right. When the pointer changes +to a diagonal two-way arrow, hold down the left mouse button and drag +the mouse to make the On-Screen Keyboard larger or smaller. Releasing +the mouse button will set the size, and the On-Screen Keyboard will +remain the new size until it is resized again. + +#### Information on Specific Keyboards + +KeymanWeb supports a very wide range of languages, and many keyboards +available for use with KeymanWeb include features specific to particular +languages. Because of this, each keyboard has its own documentation, +which can be accessed by clicking on the Help on this Keyboard +link at the bottom of the On-Screen Keyboard. Although the level of +detail in this documentation does vary somewhat, depending on the +designer and the requirements of each keyboard, this is the first place +to look for information on using a particular language with KeymanWeb. diff --git a/web/docs/engine/ui/images/ctrlkey.gif b/web/docs/engine/ui/images/ctrlkey.gif new file mode 100644 index 0000000000..13054987c3 Binary files /dev/null and b/web/docs/engine/ui/images/ctrlkey.gif differ diff --git a/web/docs/engine/ui/images/oskeyboard.gif b/web/docs/engine/ui/images/oskeyboard.gif new file mode 100644 index 0000000000..4f03d41a4e Binary files /dev/null and b/web/docs/engine/ui/images/oskeyboard.gif differ diff --git a/web/docs/engine/ui/images/pin.gif b/web/docs/engine/ui/images/pin.gif new file mode 100644 index 0000000000..5e6f0997d6 Binary files /dev/null and b/web/docs/engine/ui/images/pin.gif differ diff --git a/web/docs/engine/ui/images/squareboxes.gif b/web/docs/engine/ui/images/squareboxes.gif new file mode 100644 index 0000000000..8b25becc2b Binary files /dev/null and b/web/docs/engine/ui/images/squareboxes.gif differ diff --git a/web/docs/engine/ui/images/ui-123.gif b/web/docs/engine/ui/images/ui-123.gif new file mode 100644 index 0000000000..837ff66536 Binary files /dev/null and b/web/docs/engine/ui/images/ui-123.gif differ diff --git a/web/docs/engine/ui/images/ui-b-123.gif b/web/docs/engine/ui/images/ui-b-123.gif new file mode 100644 index 0000000000..c23f0a36a3 Binary files /dev/null and b/web/docs/engine/ui/images/ui-b-123.gif differ diff --git a/web/docs/engine/ui/images/ui-bt-control.gif b/web/docs/engine/ui/images/ui-bt-control.gif new file mode 100644 index 0000000000..413ccc6b34 Binary files /dev/null and b/web/docs/engine/ui/images/ui-bt-control.gif differ diff --git a/web/docs/engine/ui/images/ui-bt-hidekb.gif b/web/docs/engine/ui/images/ui-bt-hidekb.gif new file mode 100644 index 0000000000..a22745688d Binary files /dev/null and b/web/docs/engine/ui/images/ui-bt-hidekb.gif differ diff --git a/web/docs/engine/ui/images/ui-bt-menu.gif b/web/docs/engine/ui/images/ui-bt-menu.gif new file mode 100644 index 0000000000..7ce3113cc7 Binary files /dev/null and b/web/docs/engine/ui/images/ui-bt-menu.gif differ diff --git a/web/docs/engine/ui/images/ui-bt-showkb.gif b/web/docs/engine/ui/images/ui-bt-showkb.gif new file mode 100644 index 0000000000..2533bb05b0 Binary files /dev/null and b/web/docs/engine/ui/images/ui-bt-showkb.gif differ diff --git a/web/docs/engine/ui/images/ui-bt-step123.gif b/web/docs/engine/ui/images/ui-bt-step123.gif new file mode 100644 index 0000000000..3dacf0b51d Binary files /dev/null and b/web/docs/engine/ui/images/ui-bt-step123.gif differ diff --git a/web/docs/engine/ui/images/ui-button.gif b/web/docs/engine/ui/images/ui-button.gif new file mode 100644 index 0000000000..1762f77fc6 Binary files /dev/null and b/web/docs/engine/ui/images/ui-button.gif differ diff --git a/web/docs/engine/ui/images/ui-fl-control.gif b/web/docs/engine/ui/images/ui-fl-control.gif new file mode 100644 index 0000000000..bc0e2c1a11 Binary files /dev/null and b/web/docs/engine/ui/images/ui-fl-control.gif differ diff --git a/web/docs/engine/ui/images/ui-fl-control2.gif b/web/docs/engine/ui/images/ui-fl-control2.gif new file mode 100644 index 0000000000..f4b17e0a5c Binary files /dev/null and b/web/docs/engine/ui/images/ui-fl-control2.gif differ diff --git a/web/docs/engine/ui/images/ui-fl-control3.gif b/web/docs/engine/ui/images/ui-fl-control3.gif new file mode 100644 index 0000000000..b4731a1f01 Binary files /dev/null and b/web/docs/engine/ui/images/ui-fl-control3.gif differ diff --git a/web/docs/engine/ui/images/ui-fl-step123.gif b/web/docs/engine/ui/images/ui-fl-step123.gif new file mode 100644 index 0000000000..d52d64338d Binary files /dev/null and b/web/docs/engine/ui/images/ui-fl-step123.gif differ diff --git a/web/docs/engine/ui/images/ui-floating.gif b/web/docs/engine/ui/images/ui-floating.gif new file mode 100644 index 0000000000..e961ab8416 Binary files /dev/null and b/web/docs/engine/ui/images/ui-floating.gif differ diff --git a/web/docs/engine/ui/images/ui-osk.gif b/web/docs/engine/ui/images/ui-osk.gif new file mode 100644 index 0000000000..910ef3f62d Binary files /dev/null and b/web/docs/engine/ui/images/ui-osk.gif differ diff --git a/web/docs/engine/ui/images/ui-tb-control.gif b/web/docs/engine/ui/images/ui-tb-control.gif new file mode 100644 index 0000000000..b27d559356 Binary files /dev/null and b/web/docs/engine/ui/images/ui-tb-control.gif differ diff --git a/web/docs/engine/ui/images/ui-tb-control2.gif b/web/docs/engine/ui/images/ui-tb-control2.gif new file mode 100644 index 0000000000..11448648be Binary files /dev/null and b/web/docs/engine/ui/images/ui-tb-control2.gif differ diff --git a/web/docs/engine/ui/images/ui-tb-control3.gif b/web/docs/engine/ui/images/ui-tb-control3.gif new file mode 100644 index 0000000000..2fa52fb79b Binary files /dev/null and b/web/docs/engine/ui/images/ui-tb-control3.gif differ diff --git a/web/docs/engine/ui/images/ui-tb-control4.gif b/web/docs/engine/ui/images/ui-tb-control4.gif new file mode 100644 index 0000000000..ba960a3c99 Binary files /dev/null and b/web/docs/engine/ui/images/ui-tb-control4.gif differ diff --git a/web/docs/engine/ui/images/ui-tb-control5.gif b/web/docs/engine/ui/images/ui-tb-control5.gif new file mode 100644 index 0000000000..302b0d9eb2 Binary files /dev/null and b/web/docs/engine/ui/images/ui-tb-control5.gif differ diff --git a/web/docs/engine/ui/images/ui-tb-control6.gif b/web/docs/engine/ui/images/ui-tb-control6.gif new file mode 100644 index 0000000000..e24085f61d Binary files /dev/null and b/web/docs/engine/ui/images/ui-tb-control6.gif differ diff --git a/web/docs/engine/ui/images/ui-tb-step123.gif b/web/docs/engine/ui/images/ui-tb-step123.gif new file mode 100644 index 0000000000..c88da5812a Binary files /dev/null and b/web/docs/engine/ui/images/ui-tb-step123.gif differ diff --git a/web/docs/engine/ui/images/ui-tg-control.gif b/web/docs/engine/ui/images/ui-tg-control.gif new file mode 100644 index 0000000000..e3410b5f9a Binary files /dev/null and b/web/docs/engine/ui/images/ui-tg-control.gif differ diff --git a/web/docs/engine/ui/images/ui-tg-control2.gif b/web/docs/engine/ui/images/ui-tg-control2.gif new file mode 100644 index 0000000000..19a655964f Binary files /dev/null and b/web/docs/engine/ui/images/ui-tg-control2.gif differ diff --git a/web/docs/engine/ui/images/ui-tg-control3.gif b/web/docs/engine/ui/images/ui-tg-control3.gif new file mode 100644 index 0000000000..57dd52706e Binary files /dev/null and b/web/docs/engine/ui/images/ui-tg-control3.gif differ diff --git a/web/docs/engine/ui/images/ui-tg-controlz2.gif b/web/docs/engine/ui/images/ui-tg-controlz2.gif new file mode 100644 index 0000000000..4127d4ca40 Binary files /dev/null and b/web/docs/engine/ui/images/ui-tg-controlz2.gif differ diff --git a/web/docs/engine/ui/images/ui-tg-step123.gif b/web/docs/engine/ui/images/ui-tg-step123.gif new file mode 100644 index 0000000000..695cf110cc Binary files /dev/null and b/web/docs/engine/ui/images/ui-tg-step123.gif differ diff --git a/web/docs/engine/ui/images/ui-toggle.gif b/web/docs/engine/ui/images/ui-toggle.gif new file mode 100644 index 0000000000..f468c54b2e Binary files /dev/null and b/web/docs/engine/ui/images/ui-toggle.gif differ diff --git a/web/docs/engine/ui/images/ui-toolbar.gif b/web/docs/engine/ui/images/ui-toolbar.gif new file mode 100644 index 0000000000..b27d559356 Binary files /dev/null and b/web/docs/engine/ui/images/ui-toolbar.gif differ diff --git a/web/docs/engine/ui/images/white.gif b/web/docs/engine/ui/images/white.gif new file mode 100644 index 0000000000..714cf142c1 Binary files /dev/null and b/web/docs/engine/ui/images/white.gif differ diff --git a/web/docs/engine/ui/index.md b/web/docs/engine/ui/index.md new file mode 100644 index 0000000000..04d74d8bee --- /dev/null +++ b/web/docs/engine/ui/index.md @@ -0,0 +1,67 @@ +--- +title: Using KeymanWeb +--- +## User Interface options + +As a web-based language solution, KeymanWeb can be used for an extremely +wide variety of applications. A range of standard User Interface designs +have been included to provide flexibility in incorporating KeymanWeb +into a website. This allows developers to select an interface which best +complements their website design. Customised designs can be developed to +suit specific site requirements. Please [contact support](/contact/) +for more information. + +Using the various interfaces is largely similar, but because the +appearance of each is quite distinct, they are dealt with in different +sections of this help documentation. Please click on the links below for +more information on the interface you are using. + +
+ +++++ + + + + + + + + + + + + + + + + + + +

+Button +Interface

+Floating +Interface

+Toggle +Interface

+Toolbar +Interface
More information is also +available on how to use the On Screen Keyboard.

+On Screen +Keyboard
+ +
diff --git a/web/docs/engine/ui/osk.md b/web/docs/engine/ui/osk.md new file mode 100644 index 0000000000..9d13cc9a85 --- /dev/null +++ b/web/docs/engine/ui/osk.md @@ -0,0 +1,90 @@ +--- +title: On Screen Keyboard +--- + +### What is a Keyboard? + +When using KeymanWeb, the term *keyboard* refers specifically to +the way the keys are arranged for a specific language (i.e. which letter +or character appears when a given key is pressed). Some languages have +more than one keyboard layout; a typewriter-based layout and a phonetic +layout, for example. + +This page gives information about KeymanWeb's On-Screen Keyboard: the +map of the keyboard which appears on a website when KeymanWeb is in use. + +[More about KeymanWeb keyboards](../../current-version/guide/what-is-a-keyboard) + +### On-Screen Keyboard + +![On-Screen Keyboard Image](images/oskeyboard.gif) + +The **On-Screen Keyboard** *(above)* displays the layout of the keyboard +you are currently using. When you press any key, the blue character or +letter marked on the On-Screen Keyboard will appear in the textbox. Many +keyboards also use combinations of **Shift**, **Ctrl** or **Alt** and +letter keys to include more characters. When Shift, Ctrl or Alt is +pressed, the On-Screen Keyboard display will change to show these +characters. + +You can also use the On-Screen Keyboard to enter text directly, without +pressing any keys on your physical keyboard. Click once on any character +displayed on the On-Screen-Keyboard, and it will be entered into the +textbox. Shift-, Ctrl- and Alt- combinations also work with this method: +click once on Shift, for example, and it will stay 'pressed' until it is +clicked again or the physical Shift key is pressed. Although text entry +using this method can be less efficient, it can be useful when a +non-English physical keyboard is attached to the computer in use. + +### Moving and Hiding the On-Screen Keyboard + +The On-Screen Keyboard can be moved to any area of the website which is +being displayed. It can be placed in a more convenient position for +referring to when typing, or moved out of the way if it is obscuring +part of the textbox or another part of the screen. To move the On-Screen +Keyboard, move the mouse pointer over the On-Screen Keyboard's title bar +(where the title 'Tavultesoft Keyman' is displayed), and the pointer +will change to a four-way arrow. Hold down the left mouse button, drag +the Keyboard to your desired posistion and release the mouse button. The +On-Screen Keyboard will remain in the new position until it is moved +again. + +When you move the On-Screen Keyboard, a drawing pin icon +![](images/pin.gif) will appear in the title bar. Clicking on the +drawing pin icon will return the On-Screen Keyboard to its original +position near the KeymanWeb Control. + +If you are familiar with the layout of the keyboard in use and do not +need to refer to the On-Screen Keyboard, it can be hidden (and displayed +again if necessary) using the KeymanWeb Control. The method for hiding +and displaying the On-Screen Keyboard varies slightly (it is done +through either a menu item or a button) depending on which User +Interface is configured on your website. Please refer to the specific +[User Interface pages](../ui) for more details. + +### Resizing the On-Screen Keyboard + +You can also change the size of the On-Screen Keyboard. For example, you +may choose to make the On-Screen Keyboard smaller, instead of moving it, +to better fit it on your screen; or you might like to enlarge the +On-Screen Keyboard to make it clearer and easier to refer to. + +![Ctrl Key Image](images/ctrlkey.gif) + +To resize the On-Screen Keyboard, move the mouse pointer over the shaded +corner of the 'Ctrl' Key at its bottom right. When the pointer changes +to a diagonal two-way arrow, hold down the left mouse button and drag +the mouse to make the On-Screen Keyboard larger or smaller. Releasing +the mouse button will set the size, and the On-Screen Keyboard will +remain the new size until it is resized again. + +### Information on Specific Keyboards + +KeymanWeb supports a very wide range of languages, and many keyboards +available for use with KeymanWeb include features specific to particular +languages. Because of this, each keyboard has its own documentation, +which can be accessed by clicking on the Help on this Keyboard +link at the bottom of the On-Screen Keyboard. Although the level of +detail in this documentation does vary somewhat, depending on the +designer and the requirements of each keyboard, this is the first place +to look for information on using a particular language with KeymanWeb. diff --git a/web/docs/engine/ui/ui-button.md b/web/docs/engine/ui/ui-button.md new file mode 100644 index 0000000000..1a9331689b --- /dev/null +++ b/web/docs/engine/ui/ui-button.md @@ -0,0 +1,60 @@ +--- +title: Using the KeymanWeb Button Interface +--- +KeymanWeb's Button user interface allows multiple keyboards to be +integrated into a website and controlled through a single button +control. This button is visible all the time, and so can be incorporated +into the site's overall design. + +### Using the Button Interface to Type in Your Language + +![](images/ui-bt-step123.gif) + +### Button Control + +![](images/ui-bt-control.gif) If the **Button Control** *(left)* is visible on a website, this is an +indication that KeymanWeb has been set up to allow typing in one or more +languages. The Button Control is usually located above, beside or close +to a text box or text area, though this will vary depending on the +design and layout of the site. + + + +Moving the mouse point over the Menu Button will display the **Keyboard +Menu** *(left)*. This is a list of all the keyboards which have been +integrated for use with KeymanWeb on this particular website. + +### Selecting a Keyboard + +To choose the keyboard or language in which to type, click once on that +keyboard's name in the Keyboard Menu. The name will then be marked in +**bold** text on the menu. On many sites, you can start typing +immediately, while in other cases, you will need to click once inside +the text box or text area before beginning to type. + +If a website incorporates several keyboards, it is possible to type in +more than one language inside a single text box by returning to the +Keyboard Menu and selecting a different keyboard. To return to typing in +English or your default language, simply choose 'English' from the +Keyboard Menu. + +KeymanWeb will only affect the keyboard used in the text box to which it +is attached. If you type text into any other text box or text area, it +will continue to appear in your normal language. + +### On-Screen Keyboard + + + +The [On-Screen Keyboard](osk) *(left)* is a dynamic display showing the +layout of the keyboard you are using. At the top of the Keyboard Menu +(assuming the On-Screen Keyboard is not already visible) is the item +![Show Keyboard](images/ui-bt-showkb.gif). Clicking on this once will +cause the On-Screen Keyboard to appear and change the menu item to +![Hide Keyboard](images/ui-bt-hidekb.gif). This works in reverse if the +On-Screen Keyboard is already displayed. + +To avoid obscuring the display, the On-Screen Keyboard will not actually +be displayed unless you have clicked in a text box which incorporates +KeymanWeb. For more information about using the On-Screen Keyboard, +[click here](osk). diff --git a/web/docs/engine/ui/ui-floating.md b/web/docs/engine/ui/ui-floating.md new file mode 100644 index 0000000000..46658acf9b --- /dev/null +++ b/web/docs/engine/ui/ui-floating.md @@ -0,0 +1,57 @@ +--- +title: Using the KeymanWeb Floating Interface +--- +KeymanWeb's Floating user interface provides a straightforward and +unobtrusive method of incorporating a range of languages and keyboards +into a website. + +### Using the Floating Interface to Type in Your Language + +![](images/ui-fl-step123.gif) + +### Control Bar + + + +On a website which uses this KeymanWeb interface to allow typing in one +or more languages, the **Control Bar** *(left)* will appear when you +click in a text box or text area. + +The Control Bar will be located either to the right of or below the text +box, depending on how the website has been set up, and will disappear +when you click on a different part of the website. + +### Selecting a Keyboard + + + +In the centre of the Control Bar is a menu which displays a list of all +the keyboards that have been integrated into the website. To choose the +keyboard or language in which to type, click once on that keyboard's +name in the Keyboard Menu. The name will then be highlighted on the +menu, and you can start typing immediately. + +If a website incorporates several keyboards, it is possible to type in +more than one language inside a single text box by returning to this +menu and selecting a different keyboard. To return to typing in English +or your default language, simply choose 'English' from the menu. + +KeymanWeb will only affect the keyboard used in the text box to which it +is attached. If you type text into any other text box or text area, it +will continue to appear in your normal language. + +### On-Screen Keyboard + + + +The [On-Screen Keyboard](osk) *(left)* is a dynamic display showing the +layout of the keyboard you are using. Clicking on the On-Screen Keyboard +icon ![](images/ui-fl-control3.gif) on the right side of the Control Bar +turns the On-Screen Keyboard on and off. When the On-Screen keyboard is +activated, this icon will have a border around it, as shown. However, to +avoid obscuring the display, the On-Screen Keyboard will not actually be +displayed unless you have clicked in a text box which incorporates +KeymanWeb. For more information about using the On-Screen Keyboard, +[click here](osk). + + diff --git a/web/docs/engine/ui/ui-toggle.md b/web/docs/engine/ui/ui-toggle.md new file mode 100644 index 0000000000..83e3335b59 --- /dev/null +++ b/web/docs/engine/ui/ui-toggle.md @@ -0,0 +1,42 @@ +--- +title: Using the KeymanWeb Toggle Interface +--- +KeymanWeb's Toggle user interface is designed to provide a simple and +unobtrusive way of incorporating a single keyboard into a website. + +### Using the Toggle Interface to Type in Your Language + +![](images/ui-tg-step123.gif) + +### Toggle Control + +![](images/ui-tg-control.gif) When you click in a text box (or text area) on the website, the **Toggle +Control** *(left)* appears on the right of the box, indicating that it +is possible to type in another language. + +![](images/ui-tg-controlz2.gif) Hovering the mouse pointer over the KeymanWeb icon on the left-hand side +of the Toggle control *(left)* will display the name of the language and +keyboard which has been enabled for this site. Clicking on the icon will +turn KeymanWeb on and enable you to type in this language. When +KeymanWeb is active, there will be a solid border around the KeymanWeb +icon (as in the image). To turn KeymanWeb off and return to typing in +your default language, simply click on the icon once again. + +--- +**Note:** Clicking in a different text box or text area will not necessarily turn KeymanWeb off; this depends on how the website has been configured. + +--- + +### On-Screen Keyboard + + + +The [On-Screen Keyboard](osk) *(left)* is a dynamic display showing the +layout of the keyboard you are using. Clicking on the On-Screen Keyboard +icon ![](images/ui-tg-control3.gif) on the right side of the Toggle +Control turns the On-Screen Keyboard on and off. When the On-Screen +keyboard is activated, this icon will have a solid border around it. +However, to avoid obscuring the display, the On-Screen Keyboard will not +actually be displayed unless you have clicked in a text box which +incorporates KeymanWeb. For more information about using the On-Screen +Keyboard, [click here](osk). diff --git a/web/docs/engine/ui/ui-toolbar.md b/web/docs/engine/ui/ui-toolbar.md new file mode 100644 index 0000000000..ad6787b15c --- /dev/null +++ b/web/docs/engine/ui/ui-toolbar.md @@ -0,0 +1,68 @@ +--- +title: Using the KeymanWeb Toolbar Interface +--- +## Toolbar Interface + +KeymanWeb's Toolbar user interface provides a very clear and visible +method of incorporating a range of international languages and keyboards +into a website. The toolbar is visible all the time, which makes it +suitable for incorporating into a site's overall design. + +### Using the Toolbar Interface to Type in Your Language + +![](images/ui-tb-step123.gif) + +### Toolbar + +![](images/ui-tb-control.gif) If the **Toolbar** *(left)* is visible on a website, this is an +indication that KeymanWeb has been set up to allow typing in one or more +languages. The Toolbar is usually located above, inside or close to a +text box or text area, though this will vary, depending on the site. + +### Selecting a Keyboard + + + +To begin typing in a different language, in which to type, click on the +**Keyboards** dropdown menu on the Toolbar. A world map, divided into +regions, will be displayed, with a list of available languages below +*(right)*. Clicking on each region of the world will update the list so +show which languages from that region can be used to type. Simply click +on the name of the language you wish to use. + +For languages which have only a single keyboard available, a label +giving the name of the selected language will be added to the Toolbar, +and you can click in a suitable text box or text area and begin typing +with that keyboard. To return to typing in English or your default +language, click on the ![Off](images/ui-tb-control5.gif) icon near the +centre of the Toolbar. + + + +For many languages, however, a variety of keyboard layouts is available, +and more than one of these may have been incorporated into a website. In +this case, beside the language name on the Toolbar, another dropdown +menu will appear, with a list of keyboards to choose from (left). Click +on the desired keyboard and then in the text box to begin typing using +this keyboard. + +If a website incorporates several keyboards, it is possible to type in +more than one language inside a single text box by returning to the +menus on the Toolbar and selecting a different language and/or keyboard. +As mentioned above, clicking on the ![Off](images/ui-tb-control5.gif) +icon near the centre of the Toolbar will return you to typing in English +or your default language. + +### On-Screen Keyboard + + + +The [On-Screen Keyboard](osk) *(left)* is a dynamic display showing the +layout of the keyboard you are using. Clicking on the On-Screen Keyboard +icon ![](images/ui-tb-control6.gif) on the right side of the Toolbar +turns the On-Screen Keyboard on and off. When the On-Screen keyboard is +activated, this icon will have a border around it, as shown. However, to +avoid obscuring the display, the On-Screen Keyboard will not actually be +displayed unless you have clicked in a text box which incorporates +KeymanWeb. For more information about using the On-Screen Keyboard, +[click here](osk). diff --git a/web/docs/engine/whats-new.md b/web/docs/engine/whats-new.md new file mode 100644 index 0000000000..49fa337fe0 --- /dev/null +++ b/web/docs/engine/whats-new.md @@ -0,0 +1,3 @@ +--- +title: What's New in KeymanWeb 18.0 +---