@keymanapp/kmc-kmn 18.0.16-alpha → 18.0.18-alpha

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (33) hide show
  1. package/build/src/compiler/compiler.d.ts.map +1 -1
  2. package/build/src/compiler/compiler.js +495 -487
  3. package/build/src/compiler/compiler.js.map +1 -1
  4. package/build/src/compiler/kmn-compiler-messages.d.ts +8 -0
  5. package/build/src/compiler/kmn-compiler-messages.d.ts.map +1 -1
  6. package/build/src/compiler/kmn-compiler-messages.js +497 -488
  7. package/build/src/compiler/kmn-compiler-messages.js.map +1 -1
  8. package/build/src/compiler/osk.js +86 -85
  9. package/build/src/compiler/osk.js.map +1 -1
  10. package/build/src/import/kmcmplib/wasm-host.js +3264 -3263
  11. package/build/src/import/kmcmplib/wasm-host.js.map +1 -1
  12. package/build/src/import/kmcmplib/wasm-host.wasm +0 -0
  13. package/build/src/kmw-compiler/compiler-globals.js +40 -39
  14. package/build/src/kmw-compiler/compiler-globals.js.map +1 -1
  15. package/build/src/kmw-compiler/constants.js +81 -80
  16. package/build/src/kmw-compiler/constants.js.map +1 -1
  17. package/build/src/kmw-compiler/javascript-strings.js +854 -853
  18. package/build/src/kmw-compiler/javascript-strings.js.map +1 -1
  19. package/build/src/kmw-compiler/keymanweb-key-codes.js +821 -820
  20. package/build/src/kmw-compiler/keymanweb-key-codes.js.map +1 -1
  21. package/build/src/kmw-compiler/kmw-compiler-messages.js +42 -41
  22. package/build/src/kmw-compiler/kmw-compiler-messages.js.map +1 -1
  23. package/build/src/kmw-compiler/kmw-compiler.js +549 -548
  24. package/build/src/kmw-compiler/kmw-compiler.js.map +1 -1
  25. package/build/src/kmw-compiler/util.js +249 -248
  26. package/build/src/kmw-compiler/util.js.map +1 -1
  27. package/build/src/kmw-compiler/validate-layout-file.js +278 -277
  28. package/build/src/kmw-compiler/validate-layout-file.js.map +1 -1
  29. package/build/src/kmw-compiler/visual-keyboard-compiler.js +121 -120
  30. package/build/src/kmw-compiler/visual-keyboard-compiler.js.map +1 -1
  31. package/build/src/main.js +12 -11
  32. package/build/src/main.js.map +1 -1
  33. package/package.json +5 -5
@@ -1,278 +1,279 @@
1
- !function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:{},n=(new Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="55766aad-9de8-587f-9fb1-1978f7fa4c8a")}catch(e){}}();
2
- import { TouchLayoutFileReader, TouchLayoutFileWriter } from "@keymanapp/common-types";
3
- import { callbacks, fk, IsKeyboardVersion14OrLater, IsKeyboardVersion15OrLater, IsKeyboardVersion17OrLater } from "./compiler-globals.js";
4
- import { JavaScript_Key } from "./javascript-strings.js";
5
- import { TRequiredKey, CRequiredKeys, CSpecialText, CSpecialText14Map, CSpecialText17Map, CSpecialTextMinVer, CSpecialTextMaxVer } from "./constants.js";
6
- import { KeymanWebTouchStandardKeyNames, KMWAdditionalKeyNames, VKeyNames } from "./keymanweb-key-codes.js";
7
- import { KmwCompilerMessages } from "./kmw-compiler-messages.js";
8
- import * as Osk from '../compiler/osk.js';
9
- ;
10
- function IsValidUnicodeValue(ch) {
11
- return ((ch >= 0x0020) && (ch <= 0x007F)) ||
12
- ((ch >= 0x00A0) && (ch <= 0x10FFFF));
13
- }
14
- var TKeyIdType;
15
- (function (TKeyIdType) {
16
- TKeyIdType[TKeyIdType["Key_Invalid"] = 0] = "Key_Invalid";
17
- TKeyIdType[TKeyIdType["Key_Constant"] = 1] = "Key_Constant";
18
- TKeyIdType[TKeyIdType["Key_Touch"] = 2] = "Key_Touch";
19
- TKeyIdType[TKeyIdType["Key_Unicode"] = 3] = "Key_Unicode";
20
- TKeyIdType[TKeyIdType["Key_Unicode_Multi"] = 4] = "Key_Unicode_Multi";
21
- })(TKeyIdType || (TKeyIdType = {}));
22
- ; // I4142
23
- function GetKeyIdUnicodeType(value) {
24
- let values = value.split('_');
25
- for (let v of values) {
26
- if (!IsValidUnicodeValue(parseInt(v, 16))) {
27
- return TKeyIdType.Key_Invalid;
28
- }
29
- }
30
- if (values.length > 1) {
31
- return TKeyIdType.Key_Unicode_Multi;
32
- }
33
- return TKeyIdType.Key_Unicode;
34
- }
35
- function KeyIdType(FId) {
36
- FId = FId.toUpperCase();
37
- switch (FId.charAt(0)) {
38
- case 'T':
39
- return TKeyIdType.Key_Touch;
40
- case 'U':
41
- if (FId.startsWith('U_')) {
42
- return GetKeyIdUnicodeType(FId.substring(2));
43
- }
44
- default:
45
- // Note: can't use indexOf because some VKeyNames are mixed case, e.g. K_oE2
46
- if (VKeyNames.find(key => key.toUpperCase() == FId)) {
47
- return TKeyIdType.Key_Constant;
48
- }
49
- if (KeymanWebTouchStandardKeyNames.indexOf(FId) >= 0) {
50
- return TKeyIdType.Key_Constant;
51
- }
52
- if (KMWAdditionalKeyNames.indexOf(FId) >= 0) {
53
- return TKeyIdType.Key_Constant;
54
- }
55
- }
56
- return TKeyIdType.Key_Invalid;
57
- }
58
- function CheckKey(platformId, FPlatform, layer, FId, FText, FNextLayer, FKeyType, FRequiredKeys, FDictionary) {
59
- //
60
- // Coerce missing ID and Text to empty strings for additional tests
61
- //
62
- FId = FId ?? '';
63
- FText = FText ?? '';
64
- //
65
- // Check that each touch layer has K_LOPT, [K_ROPT,] K_BKSP, K_ENTER
66
- //
67
- for (let key of CRequiredKeys) {
68
- if (TRequiredKey[key].toLowerCase() == FId.toLowerCase()) {
69
- if (FRequiredKeys.indexOf(key) < 0) {
70
- FRequiredKeys.push(key);
71
- }
72
- break;
73
- }
74
- }
75
- //
76
- // Check that each layer referenced exists
77
- //
78
- if (typeof FNextLayer == 'string' && FNextLayer.length > 0) {
79
- if (FPlatform.layer.find(l => l.id.toLowerCase() == FNextLayer.toLowerCase()) == undefined) {
80
- callbacks.reportMessage(KmwCompilerMessages.Warn_TouchLayoutMissingLayer({
81
- keyId: FId,
82
- layerId: layer.id,
83
- nextLayer: FNextLayer,
84
- platformName: platformId
85
- }));
86
- }
87
- }
88
- //
89
- // Check that the key has a valid id // I4142
90
- //
91
- if (FId.trim() == '') {
92
- if (!([9 /* TouchLayout.TouchLayoutKeySp.blank */, 10 /* TouchLayout.TouchLayoutKeySp.spacer */].includes(FKeyType))) {
93
- callbacks.reportMessage(KmwCompilerMessages.Warn_TouchLayoutUnidentifiedKey({ layerId: layer.id }));
94
- }
95
- return true;
96
- }
97
- let FValid = KeyIdType(FId);
98
- if (FValid == TKeyIdType.Key_Invalid) {
99
- callbacks.reportMessage(KmwCompilerMessages.Error_TouchLayoutInvalidIdentifier({ keyId: FId, platformName: platformId, layerId: layer.id }));
100
- return false;
101
- }
102
- else if (FValid == TKeyIdType.Key_Unicode_Multi && !IsKeyboardVersion15OrLater()) {
103
- callbacks.reportMessage(KmwCompilerMessages.Error_TouchLayoutIdentifierRequires15({ keyId: FId, platformName: platformId, layerId: layer.id }));
104
- return false;
105
- }
106
- //
107
- // Check that each custom key code has at least *a* rule associated with it
108
- //
109
- if (FValid == TKeyIdType.Key_Touch && FNextLayer == '' && [0 /* TouchLayout.TouchLayoutKeySp.normal */, 8 /* TouchLayout.TouchLayoutKeySp.deadkey */].includes(FKeyType)) {
110
- // Search for the key in the key dictionary - ignore K_LOPT, K_ROPT...
111
- if (FDictionary.indexOf(FId) < 0) {
112
- callbacks.reportMessage(KmwCompilerMessages.Warn_TouchLayoutCustomKeyNotDefined({ keyId: FId, platformName: platformId, layerId: layer.id }));
113
- }
114
- }
115
- //
116
- // Check that if the key has a *special* label, it is available in the target version
117
- //
118
- if (FText.startsWith('*') && FText.endsWith('*') && FText.length > 2) {
119
- // Keyman versions before 14 do not support '*special*' labels on non-special keys.
120
- // ZWNJ use, however, is safe because it will be transformed in function
121
- // TransformSpecialKeys14 to '<|>', which does not require the custom OSK font.
122
- const mapVersion = Math.max(Math.min(fk.fileVersion, CSpecialTextMaxVer), CSpecialTextMinVer);
123
- const specialText = CSpecialText.get(mapVersion);
124
- if (specialText.includes(FText) &&
125
- !IsKeyboardVersion14OrLater() &&
126
- !([1 /* TouchLayout.TouchLayoutKeySp.special */, 2 /* TouchLayout.TouchLayoutKeySp.specialActive */].includes(FKeyType))) {
127
- callbacks.reportMessage(KmwCompilerMessages.Warn_TouchLayoutSpecialLabelOnNormalKey({
128
- keyId: FId,
129
- platformName: platformId,
130
- layerId: layer.id,
131
- label: FText
132
- }));
133
- }
134
- }
135
- return true;
136
- }
137
- function CheckDictionaryKeyValidity(fk, FDictionary) {
138
- // TODO: O(eeek) performance here
139
- for (let i = 0; i < FDictionary.length; i++) {
140
- if (FDictionary[i] == '') {
141
- continue;
142
- }
143
- if ([TKeyIdType.Key_Invalid, TKeyIdType.Key_Constant].includes(KeyIdType(FDictionary[i]))) {
144
- for (let fgp of fk.groups) {
145
- if (fgp.fUsingKeys) {
146
- for (let fkp of fgp.keys) {
147
- if (JavaScript_Key(fkp, fk.isMnemonic) == i + 256) {
148
- callbacks.reportMessage(KmwCompilerMessages.Error_InvalidKeyCode({ keyId: FDictionary[i] }));
149
- }
150
- }
151
- }
152
- }
153
- }
154
- }
155
- }
156
- function TransformSpecialKeys14(FDebug, sLayoutFile) {
157
- // Rewrite Special key labels that are only supported in Keyman 14+
158
- // This code is a little ugly but effective.
159
- if (!IsKeyboardVersion14OrLater()) {
160
- for (let i = 0; i < CSpecialText14Map.length; i++) {
161
- // Assumes the JSON output format will not change
162
- if (FDebug) {
163
- sLayoutFile = sLayoutFile.replaceAll('"text": "' + CSpecialText14Map[i][0] + '"', '"text": this._v>13 ? "' + CSpecialText14Map[i][0] + '" : "' + CSpecialText14Map[i][1] + '"');
164
- }
165
- else {
166
- sLayoutFile = sLayoutFile.replaceAll('"text":"' + CSpecialText14Map[i][0] + '"', '"text":this._v>13?"' + CSpecialText14Map[i][0] + '":"' + CSpecialText14Map[i][1] + '"');
167
- }
168
- }
169
- }
170
- return sLayoutFile;
171
- }
172
- function TransformSpecialKeys17(FDebug, sLayoutFile) {
173
- // Rewrite Special key labels that are only supported in Keyman 17+
174
- // This code is a little ugly but effective.
175
- if (!IsKeyboardVersion17OrLater()) {
176
- for (let i = 0; i < CSpecialText17Map.length; i++) {
177
- // Assumes the JSON output format will not change
178
- if (FDebug) {
179
- sLayoutFile = sLayoutFile.replaceAll('"text": "' + CSpecialText17Map[i][0] + '"', '"text": this._v>16 ? "' + CSpecialText17Map[i][0] + '" : "' + CSpecialText17Map[i][1] + '"');
180
- }
181
- else {
182
- sLayoutFile = sLayoutFile.replaceAll('"text":"' + CSpecialText17Map[i][0] + '"', '"text":this._v>16?"' + CSpecialText17Map[i][0] + '":"' + CSpecialText17Map[i][1] + '"');
183
- }
184
- }
185
- }
186
- return sLayoutFile;
187
- }
188
- export function ValidateLayoutFile(fk, FDebug, sLayoutFile, sVKDictionary, displayMap) {
189
- let FDictionary = sVKDictionary.split(/\s+/);
190
- CheckDictionaryKeyValidity(fk, FDictionary); // I4142
191
- let reader = new TouchLayoutFileReader();
192
- let data;
193
- try {
194
- if (!callbacks.fs.existsSync(sLayoutFile)) {
195
- callbacks.reportMessage(KmwCompilerMessages.Error_TouchLayoutFileDoesNotExist({ filename: sLayoutFile }));
196
- return null;
197
- }
198
- data = reader.read(callbacks.loadFile(sLayoutFile));
199
- if (!data) {
200
- throw new Error('Unknown error reading touch layout file');
201
- }
202
- }
203
- catch (e) {
204
- callbacks.reportMessage(KmwCompilerMessages.Error_InvalidTouchLayoutFileFormat({ msg: (e ?? 'Unspecified error').toString() }));
205
- return null;
206
- }
207
- let hasWarnedOfGestureUseDownlevel = false;
208
- const warnGesturesIfNeeded = function (keyId) {
209
- if (!hasWarnedOfGestureUseDownlevel && !IsKeyboardVersion17OrLater()) {
210
- hasWarnedOfGestureUseDownlevel = true;
211
- callbacks.reportMessage(KmwCompilerMessages.Hint_TouchLayoutUsesUnsupportedGesturesDownlevel({ keyId }));
212
- }
213
- };
214
- let result = true;
215
- let FTouchLayoutFont = ''; // I4872
216
- let pid;
217
- for (pid in data) {
218
- let platform = data[pid];
219
- // Test that the font matches on all platforms // I4872
220
- if (FTouchLayoutFont == '') {
221
- FTouchLayoutFont = platform.font?.toLowerCase() ?? '';
222
- }
223
- else if ((platform.font?.toLowerCase() ?? '') != FTouchLayoutFont) {
224
- callbacks.reportMessage(KmwCompilerMessages.Warn_TouchLayoutFontShouldBeSameForAllPlatforms());
225
- // TODO: why support multiple font values if it has to be the same across all platforms?!
226
- }
227
- // Test that all required keys are present
228
- for (let layer of platform.layer) {
229
- let FRequiredKeys = [];
230
- for (let row of layer.row) {
231
- for (let key of row.key) {
232
- result = CheckKey(pid, platform, layer, key.id, key.text, key.nextlayer, key.sp, FRequiredKeys, FDictionary) && result; // I4119
233
- if (key.sk) {
234
- for (let subkey of key.sk) {
235
- result = CheckKey(pid, platform, layer, subkey.id, subkey.text, subkey.nextlayer, subkey.sp, FRequiredKeys, FDictionary) && result;
236
- }
237
- }
238
- let direction;
239
- if (key.flick) {
240
- for (direction in key.flick) {
241
- warnGesturesIfNeeded(key.id);
242
- result = CheckKey(pid, platform, layer, key.flick[direction].id, key.flick[direction].text, key.flick[direction].nextlayer, key.flick[direction].sp, FRequiredKeys, FDictionary) && result;
243
- }
244
- }
245
- if (key.multitap) {
246
- for (let subkey of key.multitap) {
247
- warnGesturesIfNeeded(key.id);
248
- result = CheckKey(pid, platform, layer, subkey.id, subkey.text, subkey.nextlayer, subkey.sp, FRequiredKeys, FDictionary) && result;
249
- }
250
- }
251
- }
252
- }
253
- if (FRequiredKeys.length != CRequiredKeys.length) {
254
- callbacks.reportMessage(KmwCompilerMessages.Warn_TouchLayoutMissingRequiredKeys({
255
- layerId: layer.id,
256
- platformName: pid,
257
- missingKeys: CRequiredKeys.filter(x => !FRequiredKeys.includes(x)).join(', ')
258
- }));
259
- }
260
- }
261
- }
262
- // Transform the layout keys with displayMap
263
- if (displayMap) {
264
- Osk.remapTouchLayout(data, displayMap);
265
- }
266
- // If not debugging, then this strips out formatting for a big saving in file size
267
- // This also normalises any values such as Pad or Width which should be strings
268
- let writer = new TouchLayoutFileWriter({ formatted: FDebug });
269
- sLayoutFile = writer.compile(data);
270
- sLayoutFile = TransformSpecialKeys14(FDebug, sLayoutFile);
271
- sLayoutFile = TransformSpecialKeys17(FDebug, sLayoutFile);
272
- return {
273
- output: sLayoutFile,
274
- result
275
- };
276
- }
277
- //# debugId=55766aad-9de8-587f-9fb1-1978f7fa4c8a
1
+
2
+ !function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:{},n=(new Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="8528f1d8-5ec7-5e50-bde3-a3c955ca5a2b")}catch(e){}}();
3
+ import { TouchLayoutFileReader, TouchLayoutFileWriter } from "@keymanapp/common-types";
4
+ import { callbacks, fk, IsKeyboardVersion14OrLater, IsKeyboardVersion15OrLater, IsKeyboardVersion17OrLater } from "./compiler-globals.js";
5
+ import { JavaScript_Key } from "./javascript-strings.js";
6
+ import { TRequiredKey, CRequiredKeys, CSpecialText, CSpecialText14Map, CSpecialText17Map, CSpecialTextMinVer, CSpecialTextMaxVer } from "./constants.js";
7
+ import { KeymanWebTouchStandardKeyNames, KMWAdditionalKeyNames, VKeyNames } from "./keymanweb-key-codes.js";
8
+ import { KmwCompilerMessages } from "./kmw-compiler-messages.js";
9
+ import * as Osk from '../compiler/osk.js';
10
+ ;
11
+ function IsValidUnicodeValue(ch) {
12
+ return ((ch >= 0x0020) && (ch <= 0x007F)) ||
13
+ ((ch >= 0x00A0) && (ch <= 0x10FFFF));
14
+ }
15
+ var TKeyIdType;
16
+ (function (TKeyIdType) {
17
+ TKeyIdType[TKeyIdType["Key_Invalid"] = 0] = "Key_Invalid";
18
+ TKeyIdType[TKeyIdType["Key_Constant"] = 1] = "Key_Constant";
19
+ TKeyIdType[TKeyIdType["Key_Touch"] = 2] = "Key_Touch";
20
+ TKeyIdType[TKeyIdType["Key_Unicode"] = 3] = "Key_Unicode";
21
+ TKeyIdType[TKeyIdType["Key_Unicode_Multi"] = 4] = "Key_Unicode_Multi";
22
+ })(TKeyIdType || (TKeyIdType = {}));
23
+ ; // I4142
24
+ function GetKeyIdUnicodeType(value) {
25
+ let values = value.split('_');
26
+ for (let v of values) {
27
+ if (!IsValidUnicodeValue(parseInt(v, 16))) {
28
+ return TKeyIdType.Key_Invalid;
29
+ }
30
+ }
31
+ if (values.length > 1) {
32
+ return TKeyIdType.Key_Unicode_Multi;
33
+ }
34
+ return TKeyIdType.Key_Unicode;
35
+ }
36
+ function KeyIdType(FId) {
37
+ FId = FId.toUpperCase();
38
+ switch (FId.charAt(0)) {
39
+ case 'T':
40
+ return TKeyIdType.Key_Touch;
41
+ case 'U':
42
+ if (FId.startsWith('U_')) {
43
+ return GetKeyIdUnicodeType(FId.substring(2));
44
+ }
45
+ default:
46
+ // Note: can't use indexOf because some VKeyNames are mixed case, e.g. K_oE2
47
+ if (VKeyNames.find(key => key.toUpperCase() == FId)) {
48
+ return TKeyIdType.Key_Constant;
49
+ }
50
+ if (KeymanWebTouchStandardKeyNames.indexOf(FId) >= 0) {
51
+ return TKeyIdType.Key_Constant;
52
+ }
53
+ if (KMWAdditionalKeyNames.indexOf(FId) >= 0) {
54
+ return TKeyIdType.Key_Constant;
55
+ }
56
+ }
57
+ return TKeyIdType.Key_Invalid;
58
+ }
59
+ function CheckKey(platformId, FPlatform, layer, FId, FText, FNextLayer, FKeyType, FRequiredKeys, FDictionary) {
60
+ //
61
+ // Coerce missing ID and Text to empty strings for additional tests
62
+ //
63
+ FId = FId ?? '';
64
+ FText = FText ?? '';
65
+ //
66
+ // Check that each touch layer has K_LOPT, [K_ROPT,] K_BKSP, K_ENTER
67
+ //
68
+ for (let key of CRequiredKeys) {
69
+ if (TRequiredKey[key].toLowerCase() == FId.toLowerCase()) {
70
+ if (FRequiredKeys.indexOf(key) < 0) {
71
+ FRequiredKeys.push(key);
72
+ }
73
+ break;
74
+ }
75
+ }
76
+ //
77
+ // Check that each layer referenced exists
78
+ //
79
+ if (typeof FNextLayer == 'string' && FNextLayer.length > 0) {
80
+ if (FPlatform.layer.find(l => l.id.toLowerCase() == FNextLayer.toLowerCase()) == undefined) {
81
+ callbacks.reportMessage(KmwCompilerMessages.Warn_TouchLayoutMissingLayer({
82
+ keyId: FId,
83
+ layerId: layer.id,
84
+ nextLayer: FNextLayer,
85
+ platformName: platformId
86
+ }));
87
+ }
88
+ }
89
+ //
90
+ // Check that the key has a valid id // I4142
91
+ //
92
+ if (FId.trim() == '') {
93
+ if (!([9 /* TouchLayout.TouchLayoutKeySp.blank */, 10 /* TouchLayout.TouchLayoutKeySp.spacer */].includes(FKeyType))) {
94
+ callbacks.reportMessage(KmwCompilerMessages.Warn_TouchLayoutUnidentifiedKey({ layerId: layer.id }));
95
+ }
96
+ return true;
97
+ }
98
+ let FValid = KeyIdType(FId);
99
+ if (FValid == TKeyIdType.Key_Invalid) {
100
+ callbacks.reportMessage(KmwCompilerMessages.Error_TouchLayoutInvalidIdentifier({ keyId: FId, platformName: platformId, layerId: layer.id }));
101
+ return false;
102
+ }
103
+ else if (FValid == TKeyIdType.Key_Unicode_Multi && !IsKeyboardVersion15OrLater()) {
104
+ callbacks.reportMessage(KmwCompilerMessages.Error_TouchLayoutIdentifierRequires15({ keyId: FId, platformName: platformId, layerId: layer.id }));
105
+ return false;
106
+ }
107
+ //
108
+ // Check that each custom key code has at least *a* rule associated with it
109
+ //
110
+ if (FValid == TKeyIdType.Key_Touch && FNextLayer == '' && [0 /* TouchLayout.TouchLayoutKeySp.normal */, 8 /* TouchLayout.TouchLayoutKeySp.deadkey */].includes(FKeyType)) {
111
+ // Search for the key in the key dictionary - ignore K_LOPT, K_ROPT...
112
+ if (FDictionary.indexOf(FId) < 0) {
113
+ callbacks.reportMessage(KmwCompilerMessages.Warn_TouchLayoutCustomKeyNotDefined({ keyId: FId, platformName: platformId, layerId: layer.id }));
114
+ }
115
+ }
116
+ //
117
+ // Check that if the key has a *special* label, it is available in the target version
118
+ //
119
+ if (FText.startsWith('*') && FText.endsWith('*') && FText.length > 2) {
120
+ // Keyman versions before 14 do not support '*special*' labels on non-special keys.
121
+ // ZWNJ use, however, is safe because it will be transformed in function
122
+ // TransformSpecialKeys14 to '<|>', which does not require the custom OSK font.
123
+ const mapVersion = Math.max(Math.min(fk.fileVersion, CSpecialTextMaxVer), CSpecialTextMinVer);
124
+ const specialText = CSpecialText.get(mapVersion);
125
+ if (specialText.includes(FText) &&
126
+ !IsKeyboardVersion14OrLater() &&
127
+ !([1 /* TouchLayout.TouchLayoutKeySp.special */, 2 /* TouchLayout.TouchLayoutKeySp.specialActive */].includes(FKeyType))) {
128
+ callbacks.reportMessage(KmwCompilerMessages.Warn_TouchLayoutSpecialLabelOnNormalKey({
129
+ keyId: FId,
130
+ platformName: platformId,
131
+ layerId: layer.id,
132
+ label: FText
133
+ }));
134
+ }
135
+ }
136
+ return true;
137
+ }
138
+ function CheckDictionaryKeyValidity(fk, FDictionary) {
139
+ // TODO: O(eeek) performance here
140
+ for (let i = 0; i < FDictionary.length; i++) {
141
+ if (FDictionary[i] == '') {
142
+ continue;
143
+ }
144
+ if ([TKeyIdType.Key_Invalid, TKeyIdType.Key_Constant].includes(KeyIdType(FDictionary[i]))) {
145
+ for (let fgp of fk.groups) {
146
+ if (fgp.fUsingKeys) {
147
+ for (let fkp of fgp.keys) {
148
+ if (JavaScript_Key(fkp, fk.isMnemonic) == i + 256) {
149
+ callbacks.reportMessage(KmwCompilerMessages.Error_InvalidKeyCode({ keyId: FDictionary[i] }));
150
+ }
151
+ }
152
+ }
153
+ }
154
+ }
155
+ }
156
+ }
157
+ function TransformSpecialKeys14(FDebug, sLayoutFile) {
158
+ // Rewrite Special key labels that are only supported in Keyman 14+
159
+ // This code is a little ugly but effective.
160
+ if (!IsKeyboardVersion14OrLater()) {
161
+ for (let i = 0; i < CSpecialText14Map.length; i++) {
162
+ // Assumes the JSON output format will not change
163
+ if (FDebug) {
164
+ sLayoutFile = sLayoutFile.replaceAll('"text": "' + CSpecialText14Map[i][0] + '"', '"text": this._v>13 ? "' + CSpecialText14Map[i][0] + '" : "' + CSpecialText14Map[i][1] + '"');
165
+ }
166
+ else {
167
+ sLayoutFile = sLayoutFile.replaceAll('"text":"' + CSpecialText14Map[i][0] + '"', '"text":this._v>13?"' + CSpecialText14Map[i][0] + '":"' + CSpecialText14Map[i][1] + '"');
168
+ }
169
+ }
170
+ }
171
+ return sLayoutFile;
172
+ }
173
+ function TransformSpecialKeys17(FDebug, sLayoutFile) {
174
+ // Rewrite Special key labels that are only supported in Keyman 17+
175
+ // This code is a little ugly but effective.
176
+ if (!IsKeyboardVersion17OrLater()) {
177
+ for (let i = 0; i < CSpecialText17Map.length; i++) {
178
+ // Assumes the JSON output format will not change
179
+ if (FDebug) {
180
+ sLayoutFile = sLayoutFile.replaceAll('"text": "' + CSpecialText17Map[i][0] + '"', '"text": this._v>16 ? "' + CSpecialText17Map[i][0] + '" : "' + CSpecialText17Map[i][1] + '"');
181
+ }
182
+ else {
183
+ sLayoutFile = sLayoutFile.replaceAll('"text":"' + CSpecialText17Map[i][0] + '"', '"text":this._v>16?"' + CSpecialText17Map[i][0] + '":"' + CSpecialText17Map[i][1] + '"');
184
+ }
185
+ }
186
+ }
187
+ return sLayoutFile;
188
+ }
189
+ export function ValidateLayoutFile(fk, FDebug, sLayoutFile, sVKDictionary, displayMap) {
190
+ let FDictionary = sVKDictionary.split(/\s+/);
191
+ CheckDictionaryKeyValidity(fk, FDictionary); // I4142
192
+ let reader = new TouchLayoutFileReader();
193
+ let data;
194
+ try {
195
+ if (!callbacks.fs.existsSync(sLayoutFile)) {
196
+ callbacks.reportMessage(KmwCompilerMessages.Error_TouchLayoutFileDoesNotExist({ filename: sLayoutFile }));
197
+ return null;
198
+ }
199
+ data = reader.read(callbacks.loadFile(sLayoutFile));
200
+ if (!data) {
201
+ throw new Error('Unknown error reading touch layout file');
202
+ }
203
+ }
204
+ catch (e) {
205
+ callbacks.reportMessage(KmwCompilerMessages.Error_InvalidTouchLayoutFileFormat({ msg: (e ?? 'Unspecified error').toString() }));
206
+ return null;
207
+ }
208
+ let hasWarnedOfGestureUseDownlevel = false;
209
+ const warnGesturesIfNeeded = function (keyId) {
210
+ if (!hasWarnedOfGestureUseDownlevel && !IsKeyboardVersion17OrLater()) {
211
+ hasWarnedOfGestureUseDownlevel = true;
212
+ callbacks.reportMessage(KmwCompilerMessages.Hint_TouchLayoutUsesUnsupportedGesturesDownlevel({ keyId }));
213
+ }
214
+ };
215
+ let result = true;
216
+ let FTouchLayoutFont = ''; // I4872
217
+ let pid;
218
+ for (pid in data) {
219
+ let platform = data[pid];
220
+ // Test that the font matches on all platforms // I4872
221
+ if (FTouchLayoutFont == '') {
222
+ FTouchLayoutFont = platform.font?.toLowerCase() ?? '';
223
+ }
224
+ else if ((platform.font?.toLowerCase() ?? '') != FTouchLayoutFont) {
225
+ callbacks.reportMessage(KmwCompilerMessages.Warn_TouchLayoutFontShouldBeSameForAllPlatforms());
226
+ // TODO: why support multiple font values if it has to be the same across all platforms?!
227
+ }
228
+ // Test that all required keys are present
229
+ for (let layer of platform.layer) {
230
+ let FRequiredKeys = [];
231
+ for (let row of layer.row) {
232
+ for (let key of row.key) {
233
+ result = CheckKey(pid, platform, layer, key.id, key.text, key.nextlayer, key.sp, FRequiredKeys, FDictionary) && result; // I4119
234
+ if (key.sk) {
235
+ for (let subkey of key.sk) {
236
+ result = CheckKey(pid, platform, layer, subkey.id, subkey.text, subkey.nextlayer, subkey.sp, FRequiredKeys, FDictionary) && result;
237
+ }
238
+ }
239
+ let direction;
240
+ if (key.flick) {
241
+ for (direction in key.flick) {
242
+ warnGesturesIfNeeded(key.id);
243
+ result = CheckKey(pid, platform, layer, key.flick[direction].id, key.flick[direction].text, key.flick[direction].nextlayer, key.flick[direction].sp, FRequiredKeys, FDictionary) && result;
244
+ }
245
+ }
246
+ if (key.multitap) {
247
+ for (let subkey of key.multitap) {
248
+ warnGesturesIfNeeded(key.id);
249
+ result = CheckKey(pid, platform, layer, subkey.id, subkey.text, subkey.nextlayer, subkey.sp, FRequiredKeys, FDictionary) && result;
250
+ }
251
+ }
252
+ }
253
+ }
254
+ if (FRequiredKeys.length != CRequiredKeys.length) {
255
+ callbacks.reportMessage(KmwCompilerMessages.Warn_TouchLayoutMissingRequiredKeys({
256
+ layerId: layer.id,
257
+ platformName: pid,
258
+ missingKeys: CRequiredKeys.filter(x => !FRequiredKeys.includes(x)).join(', ')
259
+ }));
260
+ }
261
+ }
262
+ }
263
+ // Transform the layout keys with displayMap
264
+ if (displayMap) {
265
+ Osk.remapTouchLayout(data, displayMap);
266
+ }
267
+ // If not debugging, then this strips out formatting for a big saving in file size
268
+ // This also normalises any values such as Pad or Width which should be strings
269
+ let writer = new TouchLayoutFileWriter({ formatted: FDebug });
270
+ sLayoutFile = writer.compile(data);
271
+ sLayoutFile = TransformSpecialKeys14(FDebug, sLayoutFile);
272
+ sLayoutFile = TransformSpecialKeys17(FDebug, sLayoutFile);
273
+ return {
274
+ output: sLayoutFile,
275
+ result
276
+ };
277
+ }
278
278
  //# sourceMappingURL=validate-layout-file.js.map
279
+ //# debugId=8528f1d8-5ec7-5e50-bde3-a3c955ca5a2b