@keymanapp/common-types 17.0.300-beta → 17.0.301-beta

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 (142) hide show
  1. package/build/src/consts/virtual-key-constants.js +222 -221
  2. package/build/src/consts/virtual-key-constants.js.map +1 -1
  3. package/build/src/keyman-touch-layout/keyman-touch-layout-file-reader.js +73 -72
  4. package/build/src/keyman-touch-layout/keyman-touch-layout-file-reader.js.map +1 -1
  5. package/build/src/keyman-touch-layout/keyman-touch-layout-file-writer.js +121 -120
  6. package/build/src/keyman-touch-layout/keyman-touch-layout-file-writer.js.map +1 -1
  7. package/build/src/keyman-touch-layout/keyman-touch-layout-file.js +55 -54
  8. package/build/src/keyman-touch-layout/keyman-touch-layout-file.js.map +1 -1
  9. package/build/src/kmx/element-string.js +126 -125
  10. package/build/src/kmx/element-string.js.map +1 -1
  11. package/build/src/kmx/keyman-targets.js +80 -79
  12. package/build/src/kmx/keyman-targets.js.map +1 -1
  13. package/build/src/kmx/kmx-builder.js +190 -189
  14. package/build/src/kmx/kmx-builder.js.map +1 -1
  15. package/build/src/kmx/kmx-file-reader.js +135 -134
  16. package/build/src/kmx/kmx-file-reader.js.map +1 -1
  17. package/build/src/kmx/kmx-plus-builder/build-disp.js +28 -27
  18. package/build/src/kmx/kmx-plus-builder/build-disp.js.map +1 -1
  19. package/build/src/kmx/kmx-plus-builder/build-elem.js +90 -89
  20. package/build/src/kmx/kmx-plus-builder/build-elem.js.map +1 -1
  21. package/build/src/kmx/kmx-plus-builder/build-keys.js +108 -107
  22. package/build/src/kmx/kmx-plus-builder/build-keys.js.map +1 -1
  23. package/build/src/kmx/kmx-plus-builder/build-layr.js +102 -101
  24. package/build/src/kmx/kmx-plus-builder/build-layr.js.map +1 -1
  25. package/build/src/kmx/kmx-plus-builder/build-list.js +67 -66
  26. package/build/src/kmx/kmx-plus-builder/build-list.js.map +1 -1
  27. package/build/src/kmx/kmx-plus-builder/build-loca.js +22 -21
  28. package/build/src/kmx/kmx-plus-builder/build-loca.js.map +1 -1
  29. package/build/src/kmx/kmx-plus-builder/build-meta.js +23 -22
  30. package/build/src/kmx/kmx-plus-builder/build-meta.js.map +1 -1
  31. package/build/src/kmx/kmx-plus-builder/build-sect.js +16 -15
  32. package/build/src/kmx/kmx-plus-builder/build-sect.js.map +1 -1
  33. package/build/src/kmx/kmx-plus-builder/build-strs.js +47 -46
  34. package/build/src/kmx/kmx-plus-builder/build-strs.js.map +1 -1
  35. package/build/src/kmx/kmx-plus-builder/build-tran.js +70 -69
  36. package/build/src/kmx/kmx-plus-builder/build-tran.js.map +1 -1
  37. package/build/src/kmx/kmx-plus-builder/build-uset.js +61 -60
  38. package/build/src/kmx/kmx-plus-builder/build-uset.js.map +1 -1
  39. package/build/src/kmx/kmx-plus-builder/build-vars.js +49 -48
  40. package/build/src/kmx/kmx-plus-builder/build-vars.js.map +1 -1
  41. package/build/src/kmx/kmx-plus-builder/builder-section.js +5 -4
  42. package/build/src/kmx/kmx-plus-builder/builder-section.js.map +1 -1
  43. package/build/src/kmx/kmx-plus-builder/kmx-plus-builder.js +138 -137
  44. package/build/src/kmx/kmx-plus-builder/kmx-plus-builder.js.map +1 -1
  45. package/build/src/kmx/kmx-plus.js +831 -830
  46. package/build/src/kmx/kmx-plus.js.map +1 -1
  47. package/build/src/kmx/kmx.d.ts.map +1 -1
  48. package/build/src/kmx/kmx.js +303 -299
  49. package/build/src/kmx/kmx.js.map +1 -1
  50. package/build/src/kmx/string-list.js +89 -88
  51. package/build/src/kmx/string-list.js.map +1 -1
  52. package/build/src/kpj/keyman-developer-project.js +196 -195
  53. package/build/src/kpj/keyman-developer-project.js.map +1 -1
  54. package/build/src/kpj/kpj-file-reader.js +120 -119
  55. package/build/src/kpj/kpj-file-reader.js.map +1 -1
  56. package/build/src/kpj/kpj-file.js +13 -12
  57. package/build/src/kpj/kpj-file.js.map +1 -1
  58. package/build/src/kvk/kvk-file-reader.js +38 -37
  59. package/build/src/kvk/kvk-file-reader.js.map +1 -1
  60. package/build/src/kvk/kvk-file-writer.js +78 -77
  61. package/build/src/kvk/kvk-file-writer.js.map +1 -1
  62. package/build/src/kvk/kvk-file.js +91 -90
  63. package/build/src/kvk/kvk-file.js.map +1 -1
  64. package/build/src/kvk/kvks-file-reader.js +176 -175
  65. package/build/src/kvk/kvks-file-reader.js.map +1 -1
  66. package/build/src/kvk/kvks-file-writer.js +107 -106
  67. package/build/src/kvk/kvks-file-writer.js.map +1 -1
  68. package/build/src/kvk/kvks-file.js +12 -11
  69. package/build/src/kvk/kvks-file.js.map +1 -1
  70. package/build/src/kvk/visual-keyboard.js +76 -75
  71. package/build/src/kvk/visual-keyboard.js.map +1 -1
  72. package/build/src/ldml-keyboard/ldml-keyboard-testdata-xml.js +22 -21
  73. package/build/src/ldml-keyboard/ldml-keyboard-testdata-xml.js.map +1 -1
  74. package/build/src/ldml-keyboard/ldml-keyboard-xml-reader.js +410 -409
  75. package/build/src/ldml-keyboard/ldml-keyboard-xml-reader.js.map +1 -1
  76. package/build/src/ldml-keyboard/ldml-keyboard-xml.js +58 -57
  77. package/build/src/ldml-keyboard/ldml-keyboard-xml.js.map +1 -1
  78. package/build/src/ldml-keyboard/pattern-parser.js +491 -490
  79. package/build/src/ldml-keyboard/pattern-parser.js.map +1 -1
  80. package/build/src/ldml-keyboard/unicodeset-parser-api.js +30 -29
  81. package/build/src/ldml-keyboard/unicodeset-parser-api.js.map +1 -1
  82. package/build/src/main.js +35 -34
  83. package/build/src/main.js.map +1 -1
  84. package/build/src/package/kmp-json-file.js +4 -3
  85. package/build/src/package/kmp-json-file.js.map +1 -1
  86. package/build/src/package/kps-file.js +18 -17
  87. package/build/src/package/kps-file.js.map +1 -1
  88. package/build/src/schema-validators.js +28 -27
  89. package/build/src/schema-validators.js.map +1 -1
  90. package/build/src/schemas/displaymap.schema.js +38 -37
  91. package/build/src/schemas/displaymap.schema.js.map +1 -1
  92. package/build/src/schemas/displaymap.schema.validator.mjs +267 -266
  93. package/build/src/schemas/displaymap.schema.validator.mjs.map +1 -1
  94. package/build/src/schemas/keyboard_info.schema.js +101 -100
  95. package/build/src/schemas/keyboard_info.schema.js.map +1 -1
  96. package/build/src/schemas/keyboard_info.schema.validator.mjs +1161 -1160
  97. package/build/src/schemas/keyboard_info.schema.validator.mjs.map +1 -1
  98. package/build/src/schemas/keyman-touch-layout.clean.spec.js +154 -153
  99. package/build/src/schemas/keyman-touch-layout.clean.spec.js.map +1 -1
  100. package/build/src/schemas/keyman-touch-layout.clean.spec.validator.mjs +1095 -1094
  101. package/build/src/schemas/keyman-touch-layout.clean.spec.validator.mjs.map +1 -1
  102. package/build/src/schemas/keyman-touch-layout.spec.js +143 -142
  103. package/build/src/schemas/keyman-touch-layout.spec.js.map +1 -1
  104. package/build/src/schemas/keyman-touch-layout.spec.validator.mjs +1437 -1436
  105. package/build/src/schemas/keyman-touch-layout.spec.validator.mjs.map +1 -1
  106. package/build/src/schemas/kmp.schema.js +356 -355
  107. package/build/src/schemas/kmp.schema.js.map +1 -1
  108. package/build/src/schemas/kmp.schema.validator.mjs +1628 -1627
  109. package/build/src/schemas/kmp.schema.validator.mjs.map +1 -1
  110. package/build/src/schemas/kpj-9.0.schema.js +134 -133
  111. package/build/src/schemas/kpj-9.0.schema.js.map +1 -1
  112. package/build/src/schemas/kpj-9.0.schema.validator.mjs +656 -655
  113. package/build/src/schemas/kpj-9.0.schema.validator.mjs.map +1 -1
  114. package/build/src/schemas/kpj.schema.js +132 -131
  115. package/build/src/schemas/kpj.schema.js.map +1 -1
  116. package/build/src/schemas/kpj.schema.validator.mjs +516 -515
  117. package/build/src/schemas/kpj.schema.validator.mjs.map +1 -1
  118. package/build/src/schemas/kvks.schema.js +185 -184
  119. package/build/src/schemas/kvks.schema.js.map +1 -1
  120. package/build/src/schemas/kvks.schema.validator.mjs +626 -625
  121. package/build/src/schemas/kvks.schema.validator.mjs.map +1 -1
  122. package/build/src/schemas/ldml-keyboard3.schema.js +699 -698
  123. package/build/src/schemas/ldml-keyboard3.schema.js.map +1 -1
  124. package/build/src/schemas/ldml-keyboard3.schema.validator.mjs +3118 -3117
  125. package/build/src/schemas/ldml-keyboard3.schema.validator.mjs.map +1 -1
  126. package/build/src/schemas/ldml-keyboardtest3.schema.js +228 -227
  127. package/build/src/schemas/ldml-keyboardtest3.schema.js.map +1 -1
  128. package/build/src/schemas/ldml-keyboardtest3.schema.validator.mjs +745 -744
  129. package/build/src/schemas/ldml-keyboardtest3.schema.validator.mjs.map +1 -1
  130. package/build/src/schemas.js +26 -25
  131. package/build/src/schemas.js.map +1 -1
  132. package/build/src/util/common-events.js +29 -28
  133. package/build/src/util/common-events.js.map +1 -1
  134. package/build/src/util/compiler-interfaces.js +381 -380
  135. package/build/src/util/compiler-interfaces.js.map +1 -1
  136. package/build/src/util/errors.js +8 -7
  137. package/build/src/util/errors.js.map +1 -1
  138. package/build/src/util/file-types.js +143 -142
  139. package/build/src/util/file-types.js.map +1 -1
  140. package/build/src/util/util.js +369 -368
  141. package/build/src/util/util.js.map +1 -1
  142. package/package.json +2 -2
@@ -1,831 +1,832 @@
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]="25e2ea52-c73b-5f82-84c6-41530cb14d3a")}catch(e){}}();
2
- import { constants } from '@keymanapp/ldml-keyboard-constants';
3
- import * as r from 'restructure';
4
- import { ElementString } from './element-string.js';
5
- import { ListItem } from './string-list.js';
6
- import { isOneChar, toOneChar, unescapeString, escapeStringForRegex } from '../util/util.js';
7
- import { KMXFile } from './kmx.js';
8
- import { VariableParser } from '../ldml-keyboard/pattern-parser.js';
9
- import { MarkerParser } from '../ldml-keyboard/pattern-parser.js';
10
- // Implementation of file structures from /core/src/ldml/C7043_ldml.md
11
- // Writer in kmx-builder.ts
12
- // Reader in kmx-loader.ts
13
- export class Section {
14
- }
15
- // 'sect'
16
- export class Sect extends Section {
17
- }
18
- ;
19
- // 'bksp' -- see 'tran'
20
- // 'elem'
21
- export class Elem extends Section {
22
- strings = [];
23
- constructor(sections) {
24
- super();
25
- this.strings.push(ElementString.fromStrings(sections, '')); // C7043: null element string
26
- }
27
- /**
28
- * @param source if a string array, does not get reinterpreted as UnicodeSet. This is used with vars, etc. Or pass `["str"]` for an explicit 1-element elem.
29
- * If it is a string, will be interpreted per reorder element ruls.
30
- */
31
- allocElementString(sections, source, order, tertiary, tertiary_base, prebase) {
32
- let s = ElementString.fromStrings(sections, source, order, tertiary, tertiary_base, prebase);
33
- if (!s)
34
- return s;
35
- let result = this.strings.find(item => item.isEqual(s));
36
- if (result === undefined) {
37
- result = s;
38
- this.strings.push(result);
39
- }
40
- return result;
41
- }
42
- }
43
- ;
44
- // 'keys' is now `keys2.kmap`
45
- // 'loca'
46
- export class Loca extends Section {
47
- locales = [];
48
- }
49
- ;
50
- // 'meta'
51
- export var KeyboardSettings;
52
- (function (KeyboardSettings) {
53
- KeyboardSettings[KeyboardSettings["none"] = 0] = "none";
54
- KeyboardSettings[KeyboardSettings["normalizationDisabled"] = constants.meta_settings_normalization_disabled] = "normalizationDisabled";
55
- })(KeyboardSettings || (KeyboardSettings = {}));
56
- ;
57
- export class Meta extends Section {
58
- author;
59
- conform;
60
- layout;
61
- name;
62
- indicator;
63
- version; // semver version string, defaults to "0"
64
- settings;
65
- /** convenience for checking settings */
66
- get normalizationDisabled() {
67
- return this?.settings & KeyboardSettings.normalizationDisabled;
68
- }
69
- }
70
- ;
71
- // 'strs'
72
- /**
73
- * A string item in memory. This will be replaced with an index
74
- * into the string table at finalization.
75
- */
76
- export class StrsItem {
77
- /** string value */
78
- value;
79
- /** char value if this is a single-char placeholder item (CharStrsItem) */
80
- char;
81
- constructor(value, char) {
82
- if (char !== undefined) {
83
- if (!isOneChar(value)) {
84
- throw new Error(`StrsItem: ${value} is not a single char`);
85
- }
86
- if (char !== toOneChar(value)) {
87
- throw new Error(`StrsItem: ${char} is not the right codepoint for ${value}`);
88
- }
89
- }
90
- this.value = value;
91
- this.char = char;
92
- }
93
- compareTo(o) {
94
- return StrsItem.binaryStringCompare(this.value, o.value);
95
- }
96
- static binaryStringCompare(a, b) {
97
- // https://tc39.es/ecma262/multipage/abstract-operations.html#sec-islessthan
98
- if (typeof a != 'string' || typeof b != 'string') {
99
- throw new Error('binaryStringCompare: inputs must be strings');
100
- }
101
- if (a < b)
102
- return -1;
103
- if (a > b)
104
- return 1;
105
- return 0;
106
- }
107
- get isOneChar() {
108
- return this.char !== undefined;
109
- }
110
- }
111
- ;
112
- /**
113
- * A StrsItem for a single char. Used as a placeholder and hint to the builder
114
- */
115
- export class CharStrsItem extends StrsItem {
116
- constructor(value) {
117
- if (!isOneChar(value)) {
118
- throw RangeError(`not a 1-char string`);
119
- }
120
- super(value, toOneChar(value));
121
- }
122
- }
123
- ;
124
- ;
125
- export class Strs extends Section {
126
- /** the in-memory string table */
127
- strings = [new StrsItem('')]; // C7043: The null string is always required
128
- /** for validating */
129
- allProcessedStrings = new Set();
130
- /**
131
- * Allocate a StrsItem given the string, unescaping if necessary.
132
- * @param s escaped string
133
- * @param opts options for allocation
134
- * @param sections other sections, if needed
135
- * @returns StrsItem
136
- */
137
- allocString(s, opts, sections) {
138
- // Run the string processing pipeline
139
- s = Strs.processString(s, opts, sections);
140
- // add to the set, for testing
141
- if (s) {
142
- this.allProcessedStrings.add(s);
143
- }
144
- // if it's a single char, don't push it into the strs table
145
- if (opts?.singleOk && isOneChar(s)) {
146
- return new CharStrsItem(s);
147
- }
148
- // default: look to see if the string is already present
149
- let result = this.strings.find(item => item.value === s);
150
- if (result === undefined) {
151
- // only add if not already present
152
- result = new StrsItem(s);
153
- this.strings.push(result);
154
- }
155
- return result;
156
- }
157
- /** process everything according to opts */
158
- static processString(s, opts, sections) {
159
- s = s ?? '';
160
- // type check everything else
161
- if (typeof s !== 'string') {
162
- throw new Error('alloc_string: s must be a string, undefined, or null.');
163
- }
164
- // substitute variables
165
- if (opts?.stringVariables) {
166
- s = sections.vars.substituteStrings(s, sections);
167
- }
168
- // substitute markers
169
- if (opts?.markers) {
170
- s = sections.vars.substituteMarkerString(s);
171
- }
172
- // unescape \u{…}
173
- if (opts?.unescape) {
174
- s = unescapeString(s);
175
- }
176
- // nfd
177
- if (opts?.nfd) {
178
- if (!sections?.meta?.normalizationDisabled) {
179
- if (opts?.markers) {
180
- s = MarkerParser.nfd_markers(s, false);
181
- }
182
- else {
183
- s = s.normalize("NFD");
184
- }
185
- }
186
- }
187
- return s;
188
- }
189
- }
190
- ;
191
- /**
192
- * See LKVariables
193
- */
194
- export class Vars extends Section {
195
- totalCount() {
196
- return this.strings.length + this.sets.length + this.usets.length;
197
- }
198
- markers;
199
- strings = []; // ≠ StrsItem
200
- sets = [];
201
- usets = [];
202
- /**
203
- *
204
- * @returns false if any invalid variables
205
- */
206
- valid() {
207
- for (const t of [this.sets, this.strings, this.usets]) {
208
- for (const i of t) {
209
- if (!i.valid()) {
210
- return false;
211
- }
212
- }
213
- }
214
- return true;
215
- }
216
- // utilities for making use of Vars in other sections
217
- substituteSets(str, sections) {
218
- return str.replaceAll(VariableParser.SET_REFERENCE, (_entire, id) => {
219
- const val = Vars.findVariable(this.sets, id);
220
- if (val === null) {
221
- // Should have been caught during validation.
222
- throw Error(`Internal Error: reference to missing set variable ${id}`);
223
- }
224
- return val.value.value;
225
- });
226
- }
227
- substituteUnicodeSets(value, sections) {
228
- return value.replaceAll(VariableParser.SET_REFERENCE, (_entire, id) => {
229
- const v = Vars.findVariable(this.usets, id);
230
- if (v === null) {
231
- // Should have been caught during validation.
232
- throw Error(`Internal Error: reference to missing UnicodeSet variable ${id}`);
233
- }
234
- return v.value.value; // string value
235
- });
236
- }
237
- substituteStrings(str, sections, forMatch) {
238
- if (!str)
239
- return str;
240
- return str.replaceAll(VariableParser.STRING_REFERENCE, (_entire, id) => {
241
- const val = this.findStringVariableValue(id);
242
- if (val === null) {
243
- // Should have been caught during validation.
244
- throw Error(`Internal Error: reference to missing string variable ${id}`);
245
- }
246
- if (forMatch)
247
- return escapeStringForRegex(val);
248
- return val;
249
- });
250
- }
251
- findStringVariableValue(id) {
252
- return Vars.findVariable(this.strings, id)?.value?.value; // Unwrap: Variable, StrsItem
253
- }
254
- substituteSetRegex(str, sections) {
255
- return str.replaceAll(VariableParser.SET_REFERENCE, (_entire, id) => {
256
- // try as set
257
- const set = Vars.findVariable(this.sets, id);
258
- if (set !== null) {
259
- const { items } = set;
260
- const escapedStrings = items.map(v => escapeStringForRegex(v.value.value));
261
- const inner = escapedStrings.join('|');
262
- return `(?:${inner})`;
263
- }
264
- // try as unicodeset
265
- const uset = Vars.findVariable(this.usets, id);
266
- if (uset !== null) {
267
- const { unicodeSet } = uset;
268
- const inner = unicodeSet.ranges.map(([start, end]) => {
269
- const s = String.fromCodePoint(start);
270
- if (start === end) {
271
- return s;
272
- }
273
- else {
274
- const e = String.fromCodePoint(end);
275
- return `${s}-${e}`;
276
- }
277
- }).join('');
278
- return `[${inner}]`;
279
- }
280
- // else, missing
281
- throw Error(`Internal Error: reference to missing set variable ${id}`);
282
- });
283
- }
284
- /**
285
- * Variable locator facility
286
- * @param array
287
- * @param id
288
- * @returns
289
- */
290
- static findVariable(array, id) {
291
- const v = array.filter(e => e.id.value === id);
292
- if (v.length === 0) {
293
- return null;
294
- }
295
- else if (v.length !== 1) {
296
- // Should have been caught during validation
297
- throw Error(`Internal Error: Duplicate variable id ${id} crept into a variable list.`);
298
- }
299
- else {
300
- return v[0];
301
- }
302
- }
303
- substituteMarkerString(s, forMatch) {
304
- return MarkerParser.toSentinelString(s, this.markers, forMatch);
305
- }
306
- }
307
- ;
308
- /**
309
- * Common base for variable sections
310
- * See Variable
311
- */
312
- export class VarsItem extends Section {
313
- id;
314
- value;
315
- constructor(id, value, sections) {
316
- super();
317
- this.id = sections.strs.allocString(id);
318
- this.value = sections.strs.allocString(value, { unescape: true });
319
- }
320
- valid() {
321
- return true;
322
- }
323
- }
324
- ;
325
- export class UnicodeSetItem extends VarsItem {
326
- constructor(id, value, sections, usetparser) {
327
- super(id, value, sections);
328
- const needRanges = sections.usetparser.sizeUnicodeSet(value);
329
- if (needRanges >= 0) {
330
- this.unicodeSet = sections.usetparser.parseUnicodeSet(value, needRanges);
331
- } // otherwise: error (was recorded via callback)
332
- }
333
- unicodeSet;
334
- valid() {
335
- return !!this.unicodeSet;
336
- }
337
- }
338
- ;
339
- export class SetVarItem extends VarsItem {
340
- constructor(id, value, sections, rawItems) {
341
- super(id, value.join(' '), sections);
342
- this.items = sections.elem.allocElementString(sections, value);
343
- this.rawItems = rawItems;
344
- }
345
- // element string array
346
- items;
347
- // like items, but with unprocessed marker strings
348
- rawItems;
349
- valid() {
350
- return !!this.items;
351
- }
352
- }
353
- ;
354
- export class StringVarItem extends VarsItem {
355
- constructor(id, value, sections) {
356
- super(id, value, sections);
357
- }
358
- }
359
- ;
360
- // 'tran'
361
- export class TranTransform {
362
- from;
363
- to;
364
- mapFrom; // var name
365
- mapTo; // var name
366
- }
367
- export class TranGroup {
368
- type; // tran_group_type_transform | tran_group_type_reorder
369
- transforms = [];
370
- reorders = [];
371
- }
372
- export class TranReorder {
373
- elements;
374
- before;
375
- }
376
- ;
377
- export class Tran extends Section {
378
- groups = [];
379
- get id() {
380
- return constants.section.tran;
381
- }
382
- }
383
- ;
384
- export class UsetItem {
385
- uset;
386
- str;
387
- constructor(uset, str) {
388
- this.uset = uset;
389
- this.str = str;
390
- }
391
- compareTo(other) {
392
- return this.str.compareTo(other.str);
393
- }
394
- }
395
- ;
396
- export class Uset extends Section {
397
- usets = [];
398
- allocUset(set, sections) {
399
- // match the same pattern
400
- let result = this.usets.find(s => set.pattern == s.uset.pattern);
401
- if (result === undefined) {
402
- result = new UsetItem(set, sections.strs.allocString(set.pattern));
403
- this.usets.push(result);
404
- }
405
- return result;
406
- }
407
- }
408
- ;
409
- // alias type for 'bksp'
410
- export class Bksp extends Tran {
411
- get id() {
412
- return constants.section.bksp;
413
- }
414
- }
415
- ;
416
- // 'disp'
417
- export class DispItem {
418
- to;
419
- id;
420
- display;
421
- }
422
- ;
423
- export class Disp extends Section {
424
- baseCharacter;
425
- disps = [];
426
- }
427
- ;
428
- // 'layr'
429
- /**
430
- * In-memory `<layers>`
431
- */
432
- export class LayrList {
433
- hardware;
434
- layers = [];
435
- minDeviceWidth; // millimeters
436
- }
437
- ;
438
- /**
439
- * In-memory `<layer>`
440
- */
441
- export class LayrEntry {
442
- id;
443
- mod;
444
- rows = [];
445
- }
446
- ;
447
- /**
448
- * In-memory `<row>`
449
- */
450
- export class LayrRow {
451
- keys = [];
452
- }
453
- ;
454
- export class Layr extends Section {
455
- lists = [];
456
- }
457
- ;
458
- export class KeysKeys {
459
- flags;
460
- flicks; // for in-memory only
461
- id;
462
- longPress;
463
- longPressDefault;
464
- multiTap;
465
- switch;
466
- to;
467
- width;
468
- }
469
- ;
470
- export class KeysKmap {
471
- vkey;
472
- mod;
473
- key; // for in-memory only
474
- }
475
- ;
476
- export class KeysFlicks {
477
- flicks = [];
478
- id;
479
- compareTo(b) {
480
- return this.id.compareTo(b.id);
481
- }
482
- constructor(id) {
483
- this.id = id;
484
- }
485
- }
486
- ;
487
- export class KeysFlick {
488
- directions;
489
- keyId;
490
- }
491
- ;
492
- export class Keys extends Section {
493
- keys = [];
494
- flicks = [];
495
- kmap = [];
496
- constructor(strs) {
497
- super();
498
- let nullFlicks = new KeysFlicks(strs.allocString(''));
499
- this.flicks.push(nullFlicks); // C7043: null element string
500
- }
501
- }
502
- ;
503
- export class List extends Section {
504
- /**
505
- * Allocate a list from a space-separated list of items.
506
- * Note that passing undefined or null or `''` will
507
- * end up being the same as the empty list `[]`
508
- * @param s space-separated list of items
509
- * @param opts string options
510
- * @param sections sections
511
- * @returns a List object
512
- */
513
- allocListFromSpaces(s, opts, sections) {
514
- s = s ?? '';
515
- return this.allocList(s.split(' '), opts, sections);
516
- }
517
- /**
518
- * Return a List object referring to the string list.
519
- * Note that a falsy list, or a list containing only an empty string
520
- * `['']` will be stored as an empty list `[]`.
521
- * @param strs Strs section for allocation
522
- * @param s string list to allocate
523
- * @returns
524
- */
525
- allocList(s, opts, sections) {
526
- // Special case the 'null' list for [] or ['']
527
- if (!s || (s.length === 1 && s[0] === '')) {
528
- return this.lists[0];
529
- }
530
- let result = this.lists.find(item => item.isEqual(s));
531
- if (result === undefined) {
532
- // allocate a new ListItem
533
- result = ListItem.fromStrings(s, opts, sections);
534
- this.lists.push(result);
535
- }
536
- return result;
537
- }
538
- constructor(strs) {
539
- super();
540
- this.lists.push(ListItem.fromStrings([], {}, { strs })); // C7043: null element string
541
- }
542
- lists = [];
543
- }
544
- ;
545
- export { ListItem as ListItem };
546
- ;
547
- export class KMXPlusFile extends KMXFile {
548
- /* KMXPlus file structures */
549
- COMP_PLUS_SECT_ITEM;
550
- COMP_PLUS_SECT;
551
- // COMP_PLUS_BKSP == COMP_PLUS_TRAN
552
- COMP_PLUS_BKSP_ITEM;
553
- COMP_PLUS_BKSP;
554
- COMP_PLUS_DISP_ITEM;
555
- COMP_PLUS_DISP;
556
- COMP_PLUS_ELEM_ELEMENT;
557
- COMP_PLUS_ELEM_STRING;
558
- COMP_PLUS_ELEM;
559
- // COMP_PLUS_KEYS is now COMP_PLUS_KEYS_KMAP
560
- COMP_PLUS_LAYR_ENTRY;
561
- COMP_PLUS_LAYR_KEY;
562
- COMP_PLUS_LAYR_LIST;
563
- COMP_PLUS_LAYR_ROW;
564
- COMP_PLUS_LAYR;
565
- COMP_PLUS_KEYS_FLICK;
566
- COMP_PLUS_KEYS_FLICKS;
567
- COMP_PLUS_KEYS_KEY;
568
- COMP_PLUS_KEYS_KMAP;
569
- COMP_PLUS_KEYS;
570
- COMP_PLUS_LIST_LIST;
571
- COMP_PLUS_LIST_INDEX;
572
- COMP_PLUS_LIST;
573
- COMP_PLUS_LOCA_ITEM;
574
- COMP_PLUS_LOCA;
575
- COMP_PLUS_META;
576
- COMP_PLUS_STRS_ITEM;
577
- COMP_PLUS_STRS;
578
- COMP_PLUS_TRAN_GROUP;
579
- COMP_PLUS_TRAN_TRANSFORM;
580
- COMP_PLUS_TRAN_REORDER;
581
- COMP_PLUS_TRAN;
582
- COMP_PLUS_USET_USET;
583
- COMP_PLUS_USET_RANGE;
584
- COMP_PLUS_USET;
585
- COMP_PLUS_VKEY_ITEM;
586
- COMP_PLUS_VKEY;
587
- COMP_PLUS_VARS;
588
- COMP_PLUS_VARS_ITEM;
589
- /* File in-memory data */
590
- kmxplus = {};
591
- constructor() {
592
- super();
593
- // Binary-correct structures matching kmx_plus.h
594
- // helpers
595
- const STR_REF = r.uint32le;
596
- const ELEM_REF = r.uint32le;
597
- const LIST_REF = r.uint32le;
598
- const STR_OR_CHAR32 = r.uint32le;
599
- const CHAR32 = r.uint32le;
600
- const STR_OR_CHAR32_OR_USET = r.uint32le;
601
- const IDENT = r.uint32le;
602
- // 'sect'
603
- this.COMP_PLUS_SECT_ITEM = new r.Struct({
604
- sect: r.uint32le,
605
- offset: r.uint32le //? new r.VoidPointer(r.uint32le, {type: 'global'})
606
- });
607
- this.COMP_PLUS_SECT = new r.Struct({
608
- ident: IDENT,
609
- size: r.uint32le,
610
- total: r.uint32le,
611
- count: r.uint32le,
612
- items: new r.Array(this.COMP_PLUS_SECT_ITEM, 'count')
613
- });
614
- // 'bksp' - see 'tran'
615
- // 'disp'
616
- this.COMP_PLUS_DISP_ITEM = new r.Struct({
617
- to: STR_REF,
618
- id: STR_REF,
619
- display: STR_REF,
620
- });
621
- this.COMP_PLUS_DISP = new r.Struct({
622
- ident: IDENT,
623
- size: r.uint32le,
624
- count: r.uint32le,
625
- baseCharacter: CHAR32,
626
- items: new r.Array(this.COMP_PLUS_DISP_ITEM, 'count'),
627
- });
628
- // 'elem'
629
- this.COMP_PLUS_ELEM_ELEMENT = new r.Struct({
630
- element: STR_OR_CHAR32_OR_USET,
631
- flags: r.uint32le
632
- });
633
- this.COMP_PLUS_ELEM_STRING = new r.Struct({
634
- offset: r.uint32le,
635
- length: r.uint32le
636
- });
637
- this.COMP_PLUS_ELEM = new r.Struct({
638
- ident: IDENT,
639
- size: r.uint32le,
640
- count: r.uint32le,
641
- strings: new r.Array(this.COMP_PLUS_ELEM_STRING, 'count')
642
- // + variable subtable: Element data (see KMXPlusBuilder.emitElements())
643
- });
644
- // 'finl' - see 'tran'
645
- // 'keys' - see 'keys.kmap'
646
- // 'layr'
647
- this.COMP_PLUS_LAYR_ENTRY = new r.Struct({
648
- id: r.uint32le,
649
- mod: r.uint32le,
650
- row: r.uint32le,
651
- count: r.uint32le,
652
- });
653
- this.COMP_PLUS_LAYR_KEY = new r.Struct({
654
- key: r.uint32le, // str: key id
655
- });
656
- this.COMP_PLUS_LAYR_LIST = new r.Struct({
657
- hardware: STR_REF,
658
- layer: r.uint32le,
659
- count: r.uint32le,
660
- minDeviceWidth: r.uint32le, // integer: millimeters
661
- });
662
- this.COMP_PLUS_LAYR_ROW = new r.Struct({
663
- key: r.uint32le,
664
- count: r.uint32le,
665
- });
666
- this.COMP_PLUS_LAYR = new r.Struct({
667
- ident: IDENT,
668
- size: r.uint32le,
669
- listCount: r.uint32le,
670
- layerCount: r.uint32le,
671
- rowCount: r.uint32le,
672
- keyCount: r.uint32le,
673
- lists: new r.Array(this.COMP_PLUS_LAYR_LIST, 'listCount'),
674
- layers: new r.Array(this.COMP_PLUS_LAYR_ENTRY, 'layerCount'),
675
- rows: new r.Array(this.COMP_PLUS_LAYR_ROW, 'rowCount'),
676
- keys: new r.Array(this.COMP_PLUS_LAYR_KEY, 'keyCount'),
677
- });
678
- this.COMP_PLUS_KEYS_FLICK = new r.Struct({
679
- directions: LIST_REF,
680
- to: STR_OR_CHAR32, // str | codepoint
681
- });
682
- this.COMP_PLUS_KEYS_FLICKS = new r.Struct({
683
- count: r.uint32le,
684
- flick: r.uint32le,
685
- id: STR_REF, // str
686
- });
687
- this.COMP_PLUS_KEYS_KEY = new r.Struct({
688
- to: STR_OR_CHAR32,
689
- flags: r.uint32le,
690
- id: STR_REF,
691
- switch: STR_REF,
692
- width: r.uint32le,
693
- longPress: LIST_REF,
694
- longPressDefault: STR_REF,
695
- multiTap: LIST_REF,
696
- flicks: r.uint32le, // index into flicks table
697
- });
698
- this.COMP_PLUS_KEYS_KMAP = new r.Struct({
699
- vkey: r.uint32le,
700
- mod: r.uint32le,
701
- key: r.uint32le, // index into 'keys' subtable
702
- });
703
- this.COMP_PLUS_KEYS = new r.Struct({
704
- ident: IDENT,
705
- size: r.uint32le,
706
- keyCount: r.uint32le,
707
- flicksCount: r.uint32le,
708
- flickCount: r.uint32le,
709
- kmapCount: r.uint32le,
710
- keys: new r.Array(this.COMP_PLUS_KEYS_KEY, 'keyCount'),
711
- flicks: new r.Array(this.COMP_PLUS_KEYS_FLICKS, 'flicksCount'),
712
- flick: new r.Array(this.COMP_PLUS_KEYS_FLICK, 'flickCount'),
713
- kmap: new r.Array(this.COMP_PLUS_KEYS_KMAP, 'kmapCount'),
714
- });
715
- // 'list'
716
- this.COMP_PLUS_LIST_LIST = new r.Struct({
717
- index: r.uint32le,
718
- count: r.uint32le,
719
- });
720
- this.COMP_PLUS_LIST_INDEX = new r.Struct({
721
- str: STR_REF, // str
722
- });
723
- this.COMP_PLUS_LIST = new r.Struct({
724
- ident: IDENT,
725
- size: r.uint32le,
726
- listCount: r.uint32le,
727
- indexCount: r.uint32le,
728
- lists: new r.Array(this.COMP_PLUS_LIST_LIST, 'listCount'),
729
- indices: new r.Array(this.COMP_PLUS_LIST_INDEX, 'indexCount'),
730
- });
731
- // 'loca'
732
- this.COMP_PLUS_LOCA_ITEM = r.uint32le; //str
733
- this.COMP_PLUS_LOCA = new r.Struct({
734
- ident: IDENT,
735
- size: r.uint32le,
736
- count: r.uint32le,
737
- items: new r.Array(this.COMP_PLUS_LOCA_ITEM, 'count')
738
- });
739
- // 'meta'
740
- this.COMP_PLUS_META = new r.Struct({
741
- ident: IDENT,
742
- size: r.uint32le,
743
- author: STR_REF,
744
- conform: STR_REF,
745
- layout: STR_REF,
746
- name: STR_REF,
747
- indicator: STR_REF,
748
- version: STR_REF,
749
- settings: r.uint32le, //new r.Bitfield(r.uint32le, ['normalizationDisabled'])
750
- });
751
- // 'name' is gone
752
- // 'ordr' now part of 'tran'
753
- // 'strs'
754
- this.COMP_PLUS_STRS_ITEM = new r.Struct({
755
- // While we use length which is number of utf-16 code units excluding null terminator,
756
- // we always write a null terminator, so we can get restructure to do that for us here
757
- offset: r.uint32le,
758
- length: r.uint32le
759
- });
760
- this.COMP_PLUS_STRS = new r.Struct({
761
- ident: IDENT,
762
- size: r.uint32le,
763
- count: r.uint32le,
764
- items: new r.Array(this.COMP_PLUS_STRS_ITEM, 'count')
765
- // + variable subtable: String data (see KMXPlusBuilder.emitStrings())
766
- });
767
- // 'tran'
768
- this.COMP_PLUS_TRAN_GROUP = new r.Struct({
769
- type: r.uint32le,
770
- count: r.uint32le,
771
- index: r.uint32le, //index into subtable
772
- });
773
- this.COMP_PLUS_TRAN_TRANSFORM = new r.Struct({
774
- from: STR_REF,
775
- to: STR_REF,
776
- mapFrom: ELEM_REF,
777
- mapTo: ELEM_REF //elem
778
- });
779
- this.COMP_PLUS_TRAN_REORDER = new r.Struct({
780
- elements: ELEM_REF,
781
- before: ELEM_REF, //elem
782
- });
783
- this.COMP_PLUS_TRAN = new r.Struct({
784
- ident: IDENT,
785
- size: r.uint32le,
786
- groupCount: r.uint32le,
787
- transformCount: r.uint32le,
788
- reorderCount: r.uint32le,
789
- groups: new r.Array(this.COMP_PLUS_TRAN_GROUP, 'groupCount'),
790
- transforms: new r.Array(this.COMP_PLUS_TRAN_TRANSFORM, 'transformCount'),
791
- reorders: new r.Array(this.COMP_PLUS_TRAN_REORDER, 'reorderCount'),
792
- });
793
- // 'uset'
794
- this.COMP_PLUS_USET_USET = new r.Struct({
795
- range: r.uint32le,
796
- count: r.uint32le,
797
- pattern: STR_REF, // str
798
- });
799
- this.COMP_PLUS_USET_RANGE = new r.Struct({
800
- start: CHAR32,
801
- end: CHAR32,
802
- });
803
- this.COMP_PLUS_USET = new r.Struct({
804
- ident: IDENT,
805
- size: r.uint32le,
806
- usetCount: r.uint32le,
807
- rangeCount: r.uint32le,
808
- usets: new r.Array(this.COMP_PLUS_USET_USET, 'usetCount'),
809
- ranges: new r.Array(this.COMP_PLUS_USET_RANGE, 'rangeCount'),
810
- });
811
- // 'vars'
812
- this.COMP_PLUS_VARS_ITEM = new r.Struct({
813
- type: r.uint32le,
814
- id: STR_REF,
815
- value: STR_REF,
816
- elem: ELEM_REF,
817
- });
818
- this.COMP_PLUS_VARS = new r.Struct({
819
- ident: IDENT,
820
- size: r.uint32le,
821
- markers: LIST_REF,
822
- varCount: r.uint32le,
823
- varEntries: new r.Array(this.COMP_PLUS_VARS_ITEM, 'varCount'),
824
- });
825
- // 'vkey' is removed
826
- // Aliases
827
- this.COMP_PLUS_BKSP = this.COMP_PLUS_TRAN;
828
- }
829
- }
830
- //# debugId=25e2ea52-c73b-5f82-84c6-41530cb14d3a
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]="13f36df0-a89d-554b-8fe1-c2f2e8d02022")}catch(e){}}();
3
+ import { constants } from '@keymanapp/ldml-keyboard-constants';
4
+ import * as r from 'restructure';
5
+ import { ElementString } from './element-string.js';
6
+ import { ListItem } from './string-list.js';
7
+ import { isOneChar, toOneChar, unescapeString, escapeStringForRegex } from '../util/util.js';
8
+ import { KMXFile } from './kmx.js';
9
+ import { VariableParser } from '../ldml-keyboard/pattern-parser.js';
10
+ import { MarkerParser } from '../ldml-keyboard/pattern-parser.js';
11
+ // Implementation of file structures from /core/src/ldml/C7043_ldml.md
12
+ // Writer in kmx-builder.ts
13
+ // Reader in kmx-loader.ts
14
+ export class Section {
15
+ }
16
+ // 'sect'
17
+ export class Sect extends Section {
18
+ }
19
+ ;
20
+ // 'bksp' -- see 'tran'
21
+ // 'elem'
22
+ export class Elem extends Section {
23
+ strings = [];
24
+ constructor(sections) {
25
+ super();
26
+ this.strings.push(ElementString.fromStrings(sections, '')); // C7043: null element string
27
+ }
28
+ /**
29
+ * @param source if a string array, does not get reinterpreted as UnicodeSet. This is used with vars, etc. Or pass `["str"]` for an explicit 1-element elem.
30
+ * If it is a string, will be interpreted per reorder element ruls.
31
+ */
32
+ allocElementString(sections, source, order, tertiary, tertiary_base, prebase) {
33
+ let s = ElementString.fromStrings(sections, source, order, tertiary, tertiary_base, prebase);
34
+ if (!s)
35
+ return s;
36
+ let result = this.strings.find(item => item.isEqual(s));
37
+ if (result === undefined) {
38
+ result = s;
39
+ this.strings.push(result);
40
+ }
41
+ return result;
42
+ }
43
+ }
44
+ ;
45
+ // 'keys' is now `keys2.kmap`
46
+ // 'loca'
47
+ export class Loca extends Section {
48
+ locales = [];
49
+ }
50
+ ;
51
+ // 'meta'
52
+ export var KeyboardSettings;
53
+ (function (KeyboardSettings) {
54
+ KeyboardSettings[KeyboardSettings["none"] = 0] = "none";
55
+ KeyboardSettings[KeyboardSettings["normalizationDisabled"] = constants.meta_settings_normalization_disabled] = "normalizationDisabled";
56
+ })(KeyboardSettings || (KeyboardSettings = {}));
57
+ ;
58
+ export class Meta extends Section {
59
+ author;
60
+ conform;
61
+ layout;
62
+ name;
63
+ indicator;
64
+ version; // semver version string, defaults to "0"
65
+ settings;
66
+ /** convenience for checking settings */
67
+ get normalizationDisabled() {
68
+ return this?.settings & KeyboardSettings.normalizationDisabled;
69
+ }
70
+ }
71
+ ;
72
+ // 'strs'
73
+ /**
74
+ * A string item in memory. This will be replaced with an index
75
+ * into the string table at finalization.
76
+ */
77
+ export class StrsItem {
78
+ /** string value */
79
+ value;
80
+ /** char value if this is a single-char placeholder item (CharStrsItem) */
81
+ char;
82
+ constructor(value, char) {
83
+ if (char !== undefined) {
84
+ if (!isOneChar(value)) {
85
+ throw new Error(`StrsItem: ${value} is not a single char`);
86
+ }
87
+ if (char !== toOneChar(value)) {
88
+ throw new Error(`StrsItem: ${char} is not the right codepoint for ${value}`);
89
+ }
90
+ }
91
+ this.value = value;
92
+ this.char = char;
93
+ }
94
+ compareTo(o) {
95
+ return StrsItem.binaryStringCompare(this.value, o.value);
96
+ }
97
+ static binaryStringCompare(a, b) {
98
+ // https://tc39.es/ecma262/multipage/abstract-operations.html#sec-islessthan
99
+ if (typeof a != 'string' || typeof b != 'string') {
100
+ throw new Error('binaryStringCompare: inputs must be strings');
101
+ }
102
+ if (a < b)
103
+ return -1;
104
+ if (a > b)
105
+ return 1;
106
+ return 0;
107
+ }
108
+ get isOneChar() {
109
+ return this.char !== undefined;
110
+ }
111
+ }
112
+ ;
113
+ /**
114
+ * A StrsItem for a single char. Used as a placeholder and hint to the builder
115
+ */
116
+ export class CharStrsItem extends StrsItem {
117
+ constructor(value) {
118
+ if (!isOneChar(value)) {
119
+ throw RangeError(`not a 1-char string`);
120
+ }
121
+ super(value, toOneChar(value));
122
+ }
123
+ }
124
+ ;
125
+ ;
126
+ export class Strs extends Section {
127
+ /** the in-memory string table */
128
+ strings = [new StrsItem('')]; // C7043: The null string is always required
129
+ /** for validating */
130
+ allProcessedStrings = new Set();
131
+ /**
132
+ * Allocate a StrsItem given the string, unescaping if necessary.
133
+ * @param s escaped string
134
+ * @param opts options for allocation
135
+ * @param sections other sections, if needed
136
+ * @returns StrsItem
137
+ */
138
+ allocString(s, opts, sections) {
139
+ // Run the string processing pipeline
140
+ s = Strs.processString(s, opts, sections);
141
+ // add to the set, for testing
142
+ if (s) {
143
+ this.allProcessedStrings.add(s);
144
+ }
145
+ // if it's a single char, don't push it into the strs table
146
+ if (opts?.singleOk && isOneChar(s)) {
147
+ return new CharStrsItem(s);
148
+ }
149
+ // default: look to see if the string is already present
150
+ let result = this.strings.find(item => item.value === s);
151
+ if (result === undefined) {
152
+ // only add if not already present
153
+ result = new StrsItem(s);
154
+ this.strings.push(result);
155
+ }
156
+ return result;
157
+ }
158
+ /** process everything according to opts */
159
+ static processString(s, opts, sections) {
160
+ s = s ?? '';
161
+ // type check everything else
162
+ if (typeof s !== 'string') {
163
+ throw new Error('alloc_string: s must be a string, undefined, or null.');
164
+ }
165
+ // substitute variables
166
+ if (opts?.stringVariables) {
167
+ s = sections.vars.substituteStrings(s, sections);
168
+ }
169
+ // substitute markers
170
+ if (opts?.markers) {
171
+ s = sections.vars.substituteMarkerString(s);
172
+ }
173
+ // unescape \u{…}
174
+ if (opts?.unescape) {
175
+ s = unescapeString(s);
176
+ }
177
+ // nfd
178
+ if (opts?.nfd) {
179
+ if (!sections?.meta?.normalizationDisabled) {
180
+ if (opts?.markers) {
181
+ s = MarkerParser.nfd_markers(s, false);
182
+ }
183
+ else {
184
+ s = s.normalize("NFD");
185
+ }
186
+ }
187
+ }
188
+ return s;
189
+ }
190
+ }
191
+ ;
192
+ /**
193
+ * See LKVariables
194
+ */
195
+ export class Vars extends Section {
196
+ totalCount() {
197
+ return this.strings.length + this.sets.length + this.usets.length;
198
+ }
199
+ markers;
200
+ strings = []; // ≠ StrsItem
201
+ sets = [];
202
+ usets = [];
203
+ /**
204
+ *
205
+ * @returns false if any invalid variables
206
+ */
207
+ valid() {
208
+ for (const t of [this.sets, this.strings, this.usets]) {
209
+ for (const i of t) {
210
+ if (!i.valid()) {
211
+ return false;
212
+ }
213
+ }
214
+ }
215
+ return true;
216
+ }
217
+ // utilities for making use of Vars in other sections
218
+ substituteSets(str, sections) {
219
+ return str.replaceAll(VariableParser.SET_REFERENCE, (_entire, id) => {
220
+ const val = Vars.findVariable(this.sets, id);
221
+ if (val === null) {
222
+ // Should have been caught during validation.
223
+ throw Error(`Internal Error: reference to missing set variable ${id}`);
224
+ }
225
+ return val.value.value;
226
+ });
227
+ }
228
+ substituteUnicodeSets(value, sections) {
229
+ return value.replaceAll(VariableParser.SET_REFERENCE, (_entire, id) => {
230
+ const v = Vars.findVariable(this.usets, id);
231
+ if (v === null) {
232
+ // Should have been caught during validation.
233
+ throw Error(`Internal Error: reference to missing UnicodeSet variable ${id}`);
234
+ }
235
+ return v.value.value; // string value
236
+ });
237
+ }
238
+ substituteStrings(str, sections, forMatch) {
239
+ if (!str)
240
+ return str;
241
+ return str.replaceAll(VariableParser.STRING_REFERENCE, (_entire, id) => {
242
+ const val = this.findStringVariableValue(id);
243
+ if (val === null) {
244
+ // Should have been caught during validation.
245
+ throw Error(`Internal Error: reference to missing string variable ${id}`);
246
+ }
247
+ if (forMatch)
248
+ return escapeStringForRegex(val);
249
+ return val;
250
+ });
251
+ }
252
+ findStringVariableValue(id) {
253
+ return Vars.findVariable(this.strings, id)?.value?.value; // Unwrap: Variable, StrsItem
254
+ }
255
+ substituteSetRegex(str, sections) {
256
+ return str.replaceAll(VariableParser.SET_REFERENCE, (_entire, id) => {
257
+ // try as set
258
+ const set = Vars.findVariable(this.sets, id);
259
+ if (set !== null) {
260
+ const { items } = set;
261
+ const escapedStrings = items.map(v => escapeStringForRegex(v.value.value));
262
+ const inner = escapedStrings.join('|');
263
+ return `(?:${inner})`;
264
+ }
265
+ // try as unicodeset
266
+ const uset = Vars.findVariable(this.usets, id);
267
+ if (uset !== null) {
268
+ const { unicodeSet } = uset;
269
+ const inner = unicodeSet.ranges.map(([start, end]) => {
270
+ const s = String.fromCodePoint(start);
271
+ if (start === end) {
272
+ return s;
273
+ }
274
+ else {
275
+ const e = String.fromCodePoint(end);
276
+ return `${s}-${e}`;
277
+ }
278
+ }).join('');
279
+ return `[${inner}]`;
280
+ }
281
+ // else, missing
282
+ throw Error(`Internal Error: reference to missing set variable ${id}`);
283
+ });
284
+ }
285
+ /**
286
+ * Variable locator facility
287
+ * @param array
288
+ * @param id
289
+ * @returns
290
+ */
291
+ static findVariable(array, id) {
292
+ const v = array.filter(e => e.id.value === id);
293
+ if (v.length === 0) {
294
+ return null;
295
+ }
296
+ else if (v.length !== 1) {
297
+ // Should have been caught during validation
298
+ throw Error(`Internal Error: Duplicate variable id ${id} crept into a variable list.`);
299
+ }
300
+ else {
301
+ return v[0];
302
+ }
303
+ }
304
+ substituteMarkerString(s, forMatch) {
305
+ return MarkerParser.toSentinelString(s, this.markers, forMatch);
306
+ }
307
+ }
308
+ ;
309
+ /**
310
+ * Common base for variable sections
311
+ * See Variable
312
+ */
313
+ export class VarsItem extends Section {
314
+ id;
315
+ value;
316
+ constructor(id, value, sections) {
317
+ super();
318
+ this.id = sections.strs.allocString(id);
319
+ this.value = sections.strs.allocString(value, { unescape: true });
320
+ }
321
+ valid() {
322
+ return true;
323
+ }
324
+ }
325
+ ;
326
+ export class UnicodeSetItem extends VarsItem {
327
+ constructor(id, value, sections, usetparser) {
328
+ super(id, value, sections);
329
+ const needRanges = sections.usetparser.sizeUnicodeSet(value);
330
+ if (needRanges >= 0) {
331
+ this.unicodeSet = sections.usetparser.parseUnicodeSet(value, needRanges);
332
+ } // otherwise: error (was recorded via callback)
333
+ }
334
+ unicodeSet;
335
+ valid() {
336
+ return !!this.unicodeSet;
337
+ }
338
+ }
339
+ ;
340
+ export class SetVarItem extends VarsItem {
341
+ constructor(id, value, sections, rawItems) {
342
+ super(id, value.join(' '), sections);
343
+ this.items = sections.elem.allocElementString(sections, value);
344
+ this.rawItems = rawItems;
345
+ }
346
+ // element string array
347
+ items;
348
+ // like items, but with unprocessed marker strings
349
+ rawItems;
350
+ valid() {
351
+ return !!this.items;
352
+ }
353
+ }
354
+ ;
355
+ export class StringVarItem extends VarsItem {
356
+ constructor(id, value, sections) {
357
+ super(id, value, sections);
358
+ }
359
+ }
360
+ ;
361
+ // 'tran'
362
+ export class TranTransform {
363
+ from;
364
+ to;
365
+ mapFrom; // var name
366
+ mapTo; // var name
367
+ }
368
+ export class TranGroup {
369
+ type; // tran_group_type_transform | tran_group_type_reorder
370
+ transforms = [];
371
+ reorders = [];
372
+ }
373
+ export class TranReorder {
374
+ elements;
375
+ before;
376
+ }
377
+ ;
378
+ export class Tran extends Section {
379
+ groups = [];
380
+ get id() {
381
+ return constants.section.tran;
382
+ }
383
+ }
384
+ ;
385
+ export class UsetItem {
386
+ uset;
387
+ str;
388
+ constructor(uset, str) {
389
+ this.uset = uset;
390
+ this.str = str;
391
+ }
392
+ compareTo(other) {
393
+ return this.str.compareTo(other.str);
394
+ }
395
+ }
396
+ ;
397
+ export class Uset extends Section {
398
+ usets = [];
399
+ allocUset(set, sections) {
400
+ // match the same pattern
401
+ let result = this.usets.find(s => set.pattern == s.uset.pattern);
402
+ if (result === undefined) {
403
+ result = new UsetItem(set, sections.strs.allocString(set.pattern));
404
+ this.usets.push(result);
405
+ }
406
+ return result;
407
+ }
408
+ }
409
+ ;
410
+ // alias type for 'bksp'
411
+ export class Bksp extends Tran {
412
+ get id() {
413
+ return constants.section.bksp;
414
+ }
415
+ }
416
+ ;
417
+ // 'disp'
418
+ export class DispItem {
419
+ to;
420
+ id;
421
+ display;
422
+ }
423
+ ;
424
+ export class Disp extends Section {
425
+ baseCharacter;
426
+ disps = [];
427
+ }
428
+ ;
429
+ // 'layr'
430
+ /**
431
+ * In-memory `<layers>`
432
+ */
433
+ export class LayrList {
434
+ hardware;
435
+ layers = [];
436
+ minDeviceWidth; // millimeters
437
+ }
438
+ ;
439
+ /**
440
+ * In-memory `<layer>`
441
+ */
442
+ export class LayrEntry {
443
+ id;
444
+ mod;
445
+ rows = [];
446
+ }
447
+ ;
448
+ /**
449
+ * In-memory `<row>`
450
+ */
451
+ export class LayrRow {
452
+ keys = [];
453
+ }
454
+ ;
455
+ export class Layr extends Section {
456
+ lists = [];
457
+ }
458
+ ;
459
+ export class KeysKeys {
460
+ flags;
461
+ flicks; // for in-memory only
462
+ id;
463
+ longPress;
464
+ longPressDefault;
465
+ multiTap;
466
+ switch;
467
+ to;
468
+ width;
469
+ }
470
+ ;
471
+ export class KeysKmap {
472
+ vkey;
473
+ mod;
474
+ key; // for in-memory only
475
+ }
476
+ ;
477
+ export class KeysFlicks {
478
+ flicks = [];
479
+ id;
480
+ compareTo(b) {
481
+ return this.id.compareTo(b.id);
482
+ }
483
+ constructor(id) {
484
+ this.id = id;
485
+ }
486
+ }
487
+ ;
488
+ export class KeysFlick {
489
+ directions;
490
+ keyId;
491
+ }
492
+ ;
493
+ export class Keys extends Section {
494
+ keys = [];
495
+ flicks = [];
496
+ kmap = [];
497
+ constructor(strs) {
498
+ super();
499
+ let nullFlicks = new KeysFlicks(strs.allocString(''));
500
+ this.flicks.push(nullFlicks); // C7043: null element string
501
+ }
502
+ }
503
+ ;
504
+ export class List extends Section {
505
+ /**
506
+ * Allocate a list from a space-separated list of items.
507
+ * Note that passing undefined or null or `''` will
508
+ * end up being the same as the empty list `[]`
509
+ * @param s space-separated list of items
510
+ * @param opts string options
511
+ * @param sections sections
512
+ * @returns a List object
513
+ */
514
+ allocListFromSpaces(s, opts, sections) {
515
+ s = s ?? '';
516
+ return this.allocList(s.split(' '), opts, sections);
517
+ }
518
+ /**
519
+ * Return a List object referring to the string list.
520
+ * Note that a falsy list, or a list containing only an empty string
521
+ * `['']` will be stored as an empty list `[]`.
522
+ * @param strs Strs section for allocation
523
+ * @param s string list to allocate
524
+ * @returns
525
+ */
526
+ allocList(s, opts, sections) {
527
+ // Special case the 'null' list for [] or ['']
528
+ if (!s || (s.length === 1 && s[0] === '')) {
529
+ return this.lists[0];
530
+ }
531
+ let result = this.lists.find(item => item.isEqual(s));
532
+ if (result === undefined) {
533
+ // allocate a new ListItem
534
+ result = ListItem.fromStrings(s, opts, sections);
535
+ this.lists.push(result);
536
+ }
537
+ return result;
538
+ }
539
+ constructor(strs) {
540
+ super();
541
+ this.lists.push(ListItem.fromStrings([], {}, { strs })); // C7043: null element string
542
+ }
543
+ lists = [];
544
+ }
545
+ ;
546
+ export { ListItem as ListItem };
547
+ ;
548
+ export class KMXPlusFile extends KMXFile {
549
+ /* KMXPlus file structures */
550
+ COMP_PLUS_SECT_ITEM;
551
+ COMP_PLUS_SECT;
552
+ // COMP_PLUS_BKSP == COMP_PLUS_TRAN
553
+ COMP_PLUS_BKSP_ITEM;
554
+ COMP_PLUS_BKSP;
555
+ COMP_PLUS_DISP_ITEM;
556
+ COMP_PLUS_DISP;
557
+ COMP_PLUS_ELEM_ELEMENT;
558
+ COMP_PLUS_ELEM_STRING;
559
+ COMP_PLUS_ELEM;
560
+ // COMP_PLUS_KEYS is now COMP_PLUS_KEYS_KMAP
561
+ COMP_PLUS_LAYR_ENTRY;
562
+ COMP_PLUS_LAYR_KEY;
563
+ COMP_PLUS_LAYR_LIST;
564
+ COMP_PLUS_LAYR_ROW;
565
+ COMP_PLUS_LAYR;
566
+ COMP_PLUS_KEYS_FLICK;
567
+ COMP_PLUS_KEYS_FLICKS;
568
+ COMP_PLUS_KEYS_KEY;
569
+ COMP_PLUS_KEYS_KMAP;
570
+ COMP_PLUS_KEYS;
571
+ COMP_PLUS_LIST_LIST;
572
+ COMP_PLUS_LIST_INDEX;
573
+ COMP_PLUS_LIST;
574
+ COMP_PLUS_LOCA_ITEM;
575
+ COMP_PLUS_LOCA;
576
+ COMP_PLUS_META;
577
+ COMP_PLUS_STRS_ITEM;
578
+ COMP_PLUS_STRS;
579
+ COMP_PLUS_TRAN_GROUP;
580
+ COMP_PLUS_TRAN_TRANSFORM;
581
+ COMP_PLUS_TRAN_REORDER;
582
+ COMP_PLUS_TRAN;
583
+ COMP_PLUS_USET_USET;
584
+ COMP_PLUS_USET_RANGE;
585
+ COMP_PLUS_USET;
586
+ COMP_PLUS_VKEY_ITEM;
587
+ COMP_PLUS_VKEY;
588
+ COMP_PLUS_VARS;
589
+ COMP_PLUS_VARS_ITEM;
590
+ /* File in-memory data */
591
+ kmxplus = {};
592
+ constructor() {
593
+ super();
594
+ // Binary-correct structures matching kmx_plus.h
595
+ // helpers
596
+ const STR_REF = r.uint32le;
597
+ const ELEM_REF = r.uint32le;
598
+ const LIST_REF = r.uint32le;
599
+ const STR_OR_CHAR32 = r.uint32le;
600
+ const CHAR32 = r.uint32le;
601
+ const STR_OR_CHAR32_OR_USET = r.uint32le;
602
+ const IDENT = r.uint32le;
603
+ // 'sect'
604
+ this.COMP_PLUS_SECT_ITEM = new r.Struct({
605
+ sect: r.uint32le,
606
+ offset: r.uint32le //? new r.VoidPointer(r.uint32le, {type: 'global'})
607
+ });
608
+ this.COMP_PLUS_SECT = new r.Struct({
609
+ ident: IDENT,
610
+ size: r.uint32le,
611
+ total: r.uint32le,
612
+ count: r.uint32le,
613
+ items: new r.Array(this.COMP_PLUS_SECT_ITEM, 'count')
614
+ });
615
+ // 'bksp' - see 'tran'
616
+ // 'disp'
617
+ this.COMP_PLUS_DISP_ITEM = new r.Struct({
618
+ to: STR_REF,
619
+ id: STR_REF,
620
+ display: STR_REF,
621
+ });
622
+ this.COMP_PLUS_DISP = new r.Struct({
623
+ ident: IDENT,
624
+ size: r.uint32le,
625
+ count: r.uint32le,
626
+ baseCharacter: CHAR32,
627
+ items: new r.Array(this.COMP_PLUS_DISP_ITEM, 'count'),
628
+ });
629
+ // 'elem'
630
+ this.COMP_PLUS_ELEM_ELEMENT = new r.Struct({
631
+ element: STR_OR_CHAR32_OR_USET,
632
+ flags: r.uint32le
633
+ });
634
+ this.COMP_PLUS_ELEM_STRING = new r.Struct({
635
+ offset: r.uint32le,
636
+ length: r.uint32le
637
+ });
638
+ this.COMP_PLUS_ELEM = new r.Struct({
639
+ ident: IDENT,
640
+ size: r.uint32le,
641
+ count: r.uint32le,
642
+ strings: new r.Array(this.COMP_PLUS_ELEM_STRING, 'count')
643
+ // + variable subtable: Element data (see KMXPlusBuilder.emitElements())
644
+ });
645
+ // 'finl' - see 'tran'
646
+ // 'keys' - see 'keys.kmap'
647
+ // 'layr'
648
+ this.COMP_PLUS_LAYR_ENTRY = new r.Struct({
649
+ id: r.uint32le,
650
+ mod: r.uint32le,
651
+ row: r.uint32le,
652
+ count: r.uint32le,
653
+ });
654
+ this.COMP_PLUS_LAYR_KEY = new r.Struct({
655
+ key: r.uint32le, // str: key id
656
+ });
657
+ this.COMP_PLUS_LAYR_LIST = new r.Struct({
658
+ hardware: STR_REF,
659
+ layer: r.uint32le,
660
+ count: r.uint32le,
661
+ minDeviceWidth: r.uint32le, // integer: millimeters
662
+ });
663
+ this.COMP_PLUS_LAYR_ROW = new r.Struct({
664
+ key: r.uint32le,
665
+ count: r.uint32le,
666
+ });
667
+ this.COMP_PLUS_LAYR = new r.Struct({
668
+ ident: IDENT,
669
+ size: r.uint32le,
670
+ listCount: r.uint32le,
671
+ layerCount: r.uint32le,
672
+ rowCount: r.uint32le,
673
+ keyCount: r.uint32le,
674
+ lists: new r.Array(this.COMP_PLUS_LAYR_LIST, 'listCount'),
675
+ layers: new r.Array(this.COMP_PLUS_LAYR_ENTRY, 'layerCount'),
676
+ rows: new r.Array(this.COMP_PLUS_LAYR_ROW, 'rowCount'),
677
+ keys: new r.Array(this.COMP_PLUS_LAYR_KEY, 'keyCount'),
678
+ });
679
+ this.COMP_PLUS_KEYS_FLICK = new r.Struct({
680
+ directions: LIST_REF,
681
+ to: STR_OR_CHAR32, // str | codepoint
682
+ });
683
+ this.COMP_PLUS_KEYS_FLICKS = new r.Struct({
684
+ count: r.uint32le,
685
+ flick: r.uint32le,
686
+ id: STR_REF, // str
687
+ });
688
+ this.COMP_PLUS_KEYS_KEY = new r.Struct({
689
+ to: STR_OR_CHAR32,
690
+ flags: r.uint32le,
691
+ id: STR_REF,
692
+ switch: STR_REF,
693
+ width: r.uint32le,
694
+ longPress: LIST_REF,
695
+ longPressDefault: STR_REF,
696
+ multiTap: LIST_REF,
697
+ flicks: r.uint32le, // index into flicks table
698
+ });
699
+ this.COMP_PLUS_KEYS_KMAP = new r.Struct({
700
+ vkey: r.uint32le,
701
+ mod: r.uint32le,
702
+ key: r.uint32le, // index into 'keys' subtable
703
+ });
704
+ this.COMP_PLUS_KEYS = new r.Struct({
705
+ ident: IDENT,
706
+ size: r.uint32le,
707
+ keyCount: r.uint32le,
708
+ flicksCount: r.uint32le,
709
+ flickCount: r.uint32le,
710
+ kmapCount: r.uint32le,
711
+ keys: new r.Array(this.COMP_PLUS_KEYS_KEY, 'keyCount'),
712
+ flicks: new r.Array(this.COMP_PLUS_KEYS_FLICKS, 'flicksCount'),
713
+ flick: new r.Array(this.COMP_PLUS_KEYS_FLICK, 'flickCount'),
714
+ kmap: new r.Array(this.COMP_PLUS_KEYS_KMAP, 'kmapCount'),
715
+ });
716
+ // 'list'
717
+ this.COMP_PLUS_LIST_LIST = new r.Struct({
718
+ index: r.uint32le,
719
+ count: r.uint32le,
720
+ });
721
+ this.COMP_PLUS_LIST_INDEX = new r.Struct({
722
+ str: STR_REF, // str
723
+ });
724
+ this.COMP_PLUS_LIST = new r.Struct({
725
+ ident: IDENT,
726
+ size: r.uint32le,
727
+ listCount: r.uint32le,
728
+ indexCount: r.uint32le,
729
+ lists: new r.Array(this.COMP_PLUS_LIST_LIST, 'listCount'),
730
+ indices: new r.Array(this.COMP_PLUS_LIST_INDEX, 'indexCount'),
731
+ });
732
+ // 'loca'
733
+ this.COMP_PLUS_LOCA_ITEM = r.uint32le; //str
734
+ this.COMP_PLUS_LOCA = new r.Struct({
735
+ ident: IDENT,
736
+ size: r.uint32le,
737
+ count: r.uint32le,
738
+ items: new r.Array(this.COMP_PLUS_LOCA_ITEM, 'count')
739
+ });
740
+ // 'meta'
741
+ this.COMP_PLUS_META = new r.Struct({
742
+ ident: IDENT,
743
+ size: r.uint32le,
744
+ author: STR_REF,
745
+ conform: STR_REF,
746
+ layout: STR_REF,
747
+ name: STR_REF,
748
+ indicator: STR_REF,
749
+ version: STR_REF,
750
+ settings: r.uint32le, //new r.Bitfield(r.uint32le, ['normalizationDisabled'])
751
+ });
752
+ // 'name' is gone
753
+ // 'ordr' now part of 'tran'
754
+ // 'strs'
755
+ this.COMP_PLUS_STRS_ITEM = new r.Struct({
756
+ // While we use length which is number of utf-16 code units excluding null terminator,
757
+ // we always write a null terminator, so we can get restructure to do that for us here
758
+ offset: r.uint32le,
759
+ length: r.uint32le
760
+ });
761
+ this.COMP_PLUS_STRS = new r.Struct({
762
+ ident: IDENT,
763
+ size: r.uint32le,
764
+ count: r.uint32le,
765
+ items: new r.Array(this.COMP_PLUS_STRS_ITEM, 'count')
766
+ // + variable subtable: String data (see KMXPlusBuilder.emitStrings())
767
+ });
768
+ // 'tran'
769
+ this.COMP_PLUS_TRAN_GROUP = new r.Struct({
770
+ type: r.uint32le,
771
+ count: r.uint32le,
772
+ index: r.uint32le, //index into subtable
773
+ });
774
+ this.COMP_PLUS_TRAN_TRANSFORM = new r.Struct({
775
+ from: STR_REF,
776
+ to: STR_REF,
777
+ mapFrom: ELEM_REF,
778
+ mapTo: ELEM_REF //elem
779
+ });
780
+ this.COMP_PLUS_TRAN_REORDER = new r.Struct({
781
+ elements: ELEM_REF,
782
+ before: ELEM_REF, //elem
783
+ });
784
+ this.COMP_PLUS_TRAN = new r.Struct({
785
+ ident: IDENT,
786
+ size: r.uint32le,
787
+ groupCount: r.uint32le,
788
+ transformCount: r.uint32le,
789
+ reorderCount: r.uint32le,
790
+ groups: new r.Array(this.COMP_PLUS_TRAN_GROUP, 'groupCount'),
791
+ transforms: new r.Array(this.COMP_PLUS_TRAN_TRANSFORM, 'transformCount'),
792
+ reorders: new r.Array(this.COMP_PLUS_TRAN_REORDER, 'reorderCount'),
793
+ });
794
+ // 'uset'
795
+ this.COMP_PLUS_USET_USET = new r.Struct({
796
+ range: r.uint32le,
797
+ count: r.uint32le,
798
+ pattern: STR_REF, // str
799
+ });
800
+ this.COMP_PLUS_USET_RANGE = new r.Struct({
801
+ start: CHAR32,
802
+ end: CHAR32,
803
+ });
804
+ this.COMP_PLUS_USET = new r.Struct({
805
+ ident: IDENT,
806
+ size: r.uint32le,
807
+ usetCount: r.uint32le,
808
+ rangeCount: r.uint32le,
809
+ usets: new r.Array(this.COMP_PLUS_USET_USET, 'usetCount'),
810
+ ranges: new r.Array(this.COMP_PLUS_USET_RANGE, 'rangeCount'),
811
+ });
812
+ // 'vars'
813
+ this.COMP_PLUS_VARS_ITEM = new r.Struct({
814
+ type: r.uint32le,
815
+ id: STR_REF,
816
+ value: STR_REF,
817
+ elem: ELEM_REF,
818
+ });
819
+ this.COMP_PLUS_VARS = new r.Struct({
820
+ ident: IDENT,
821
+ size: r.uint32le,
822
+ markers: LIST_REF,
823
+ varCount: r.uint32le,
824
+ varEntries: new r.Array(this.COMP_PLUS_VARS_ITEM, 'varCount'),
825
+ });
826
+ // 'vkey' is removed
827
+ // Aliases
828
+ this.COMP_PLUS_BKSP = this.COMP_PLUS_TRAN;
829
+ }
830
+ }
831
831
  //# sourceMappingURL=kmx-plus.js.map
832
+ //# debugId=13f36df0-a89d-554b-8fe1-c2f2e8d02022