@keymanapp/kmc-package 17.0.85-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 (79) hide show
  1. package/.nyc_output/coverage-4892-1681239251006-0.json +1 -0
  2. package/Makefile +38 -0
  3. package/build/src/kmp-compiler.d.ts +18 -0
  4. package/build/src/kmp-compiler.d.ts.map +1 -0
  5. package/build/src/kmp-compiler.js +232 -0
  6. package/build/src/kmp-compiler.js.map +1 -0
  7. package/build/src/kmp-json-file.d.ts +68 -0
  8. package/build/src/kmp-json-file.d.ts.map +1 -0
  9. package/build/src/kmp-json-file.js +2 -0
  10. package/build/src/kmp-json-file.js.map +1 -0
  11. package/build/src/kps-file.d.ts +98 -0
  12. package/build/src/kps-file.d.ts.map +1 -0
  13. package/build/src/kps-file.js +16 -0
  14. package/build/src/kps-file.js.map +1 -0
  15. package/build/test/helpers/index.d.ts +10 -0
  16. package/build/test/helpers/index.d.ts.map +1 -0
  17. package/build/test/helpers/index.js +17 -0
  18. package/build/test/helpers/index.js.map +1 -0
  19. package/build/test/test-package-compiler.d.ts +2 -0
  20. package/build/test/test-package-compiler.d.ts.map +1 -0
  21. package/build/test/test-package-compiler.js +97 -0
  22. package/build/test/test-package-compiler.js.map +1 -0
  23. package/build/test/tsconfig.tsbuildinfo +1 -0
  24. package/build/tsconfig.tsbuildinfo +1 -0
  25. package/build.sh +66 -0
  26. package/coverage/lcov-report/base.css +224 -0
  27. package/coverage/lcov-report/block-navigation.js +87 -0
  28. package/coverage/lcov-report/favicon.png +0 -0
  29. package/coverage/lcov-report/index.html +146 -0
  30. package/coverage/lcov-report/prettify.css +1 -0
  31. package/coverage/lcov-report/prettify.js +2 -0
  32. package/coverage/lcov-report/sort-arrow-sprite.png +0 -0
  33. package/coverage/lcov-report/sorter.js +196 -0
  34. package/coverage/lcov-report/src/index.html +116 -0
  35. package/coverage/lcov-report/src/kmp-compiler.ts.html +904 -0
  36. package/coverage/lcov-report/test/helpers/index.html +116 -0
  37. package/coverage/lcov-report/test/helpers/index.ts.html +136 -0
  38. package/coverage/lcov-report/test/index.html +116 -0
  39. package/coverage/lcov-report/test/test-package-compiler.ts.html +445 -0
  40. package/coverage/lcov.info +518 -0
  41. package/package.json +54 -0
  42. package/src/kmp-compiler.ts +273 -0
  43. package/src/kmp-json-file.ts +77 -0
  44. package/src/kps-file.ts +126 -0
  45. package/test/fixtures/example.qaa.sencoten/example.qaa.sencoten.model.js +55 -0
  46. package/test/fixtures/example.qaa.sencoten/example.qaa.sencoten.model.kmp.intermediate.json +48 -0
  47. package/test/fixtures/example.qaa.sencoten/example.qaa.sencoten.model.kmp.json +48 -0
  48. package/test/fixtures/example.qaa.sencoten/example.qaa.sencoten.model.kmp.zipped.json +45 -0
  49. package/test/fixtures/example.qaa.sencoten/example.qaa.sencoten.model.kps +35 -0
  50. package/test/fixtures/example.qaa.sencoten/example.qaa.sencoten.model.ts +6 -0
  51. package/test/fixtures/example.qaa.sencoten/wordlist.tsv +10 -0
  52. package/test/fixtures/khmer_angkor/build/khmer_angkor.js +1 -0
  53. package/test/fixtures/khmer_angkor/build/khmer_angkor.kmx +0 -0
  54. package/test/fixtures/khmer_angkor/build/khmer_angkor.kvk +0 -0
  55. package/test/fixtures/khmer_angkor/ref/kmp.json +110 -0
  56. package/test/fixtures/khmer_angkor/shared/fonts/khmer/busrakbd/khmer_busra_kbd.ttf +0 -0
  57. package/test/fixtures/khmer_angkor/shared/fonts/khmer/mondulkiri/FONTLOG.txt +123 -0
  58. package/test/fixtures/khmer_angkor/shared/fonts/khmer/mondulkiri/Mondulkiri-R.ttf +0 -0
  59. package/test/fixtures/khmer_angkor/shared/fonts/khmer/mondulkiri/OFL-FAQ.txt +425 -0
  60. package/test/fixtures/khmer_angkor/shared/fonts/khmer/mondulkiri/OFL.txt +95 -0
  61. package/test/fixtures/khmer_angkor/source/khmer_angkor.kps +131 -0
  62. package/test/fixtures/khmer_angkor/source/readme.htm +23 -0
  63. package/test/fixtures/khmer_angkor/source/splash.gif +0 -0
  64. package/test/fixtures/khmer_angkor/source/welcome/KAK_Documentation_EN.pdf +0 -0
  65. package/test/fixtures/khmer_angkor/source/welcome/KAK_Documentation_KH.pdf +0 -0
  66. package/test/fixtures/khmer_angkor/source/welcome/image002.png +0 -0
  67. package/test/fixtures/khmer_angkor/source/welcome/keyboard_layout.png +0 -0
  68. package/test/fixtures/khmer_angkor/source/welcome/welcome.htm +54 -0
  69. package/test/fixtures/withfolders.qaa.sencoten/build/withfolders.qaa.sencoten.model.js +55 -0
  70. package/test/fixtures/withfolders.qaa.sencoten/source/welcome.htm +1 -0
  71. package/test/fixtures/withfolders.qaa.sencoten/source/withfolders.qaa.sencoten.model.kps +41 -0
  72. package/test/fixtures/withfolders.qaa.sencoten/source/withfolders.qaa.sencoten.model.ts +6 -0
  73. package/test/fixtures/withfolders.qaa.sencoten/source/wordlist.tsv +10 -0
  74. package/test/fixtures/withfolders.qaa.sencoten/withfolders.qaa.sencoten.model.kmp.intermediate.json +52 -0
  75. package/test/fixtures/withfolders.qaa.sencoten/withfolders.qaa.sencoten.model.kmp.zipped.json +50 -0
  76. package/test/helpers/index.ts +17 -0
  77. package/test/test-package-compiler.ts +120 -0
  78. package/test/tsconfig.json +19 -0
  79. package/tsconfig.json +15 -0
@@ -0,0 +1,273 @@
1
+ import * as fs from 'fs';
2
+ import * as path from 'path';
3
+ import * as xml2js from 'xml2js';
4
+ import JSZip from 'jszip';
5
+ import KEYMAN_VERSION from "@keymanapp/keyman-version";
6
+
7
+ import type { KpsFile, KpsFileContentFile, KpsFileInfo, KpsFileKeyboard, KpsFileLanguage, KpsFileLexicalModel, KpsFileOptions, KpsPackage } from './kps-file.js';
8
+ import type { KmpJsonFile, KmpJsonFileInfo, KmpJsonFileLanguage, KmpJsonFileOptions } from './kmp-json-file.js';
9
+
10
+ export { type KmpJsonFile } from './kmp-json-file.js';
11
+
12
+ const FILEVERSION_KMP_JSON = '12.0';
13
+
14
+ export default class KmpCompiler {
15
+
16
+ public transformKpsToKmpObject(kpsString: string, kpsPath: string): KmpJsonFile {
17
+
18
+ // Load the KPS data from XML as JS structured data.
19
+
20
+ let kpsPackage = (() => {
21
+ let a: KpsPackage;
22
+ let parser = new xml2js.Parser({
23
+ tagNameProcessors: [xml2js.processors.firstCharLowerCase],
24
+ explicitArray: false
25
+ });
26
+ parser.parseString(kpsString, (e: unknown, r: unknown) => { a = r as KpsPackage });
27
+ return a;
28
+ })();
29
+
30
+ let kps: KpsFile = kpsPackage.package;
31
+
32
+ //
33
+ // To convert to kmp.json, we need to:
34
+ //
35
+ // 1. Unwrap arrays (and convert to array where single object)
36
+ // 2. Fix casing on `iD`
37
+ // 3. Rewrap info, keyboard.languages, lexicalModel.languages, startMenu.items elements
38
+ // 4. Remove options.followKeyboardVersion, file.fileType
39
+ // 5. Convert file.copyLocation to a Number
40
+ // 6. Filenames need to be basenames (but this comes after processing)
41
+ //
42
+
43
+ // Start to construct the kmp.json file from the .kps file
44
+
45
+ let kmp: KmpJsonFile = {
46
+ system: {
47
+ fileVersion: FILEVERSION_KMP_JSON,
48
+ keymanDeveloperVersion: KEYMAN_VERSION.VERSION
49
+ },
50
+ options: {}
51
+ };
52
+
53
+ //
54
+ // Fill in additional fields
55
+ //
56
+
57
+ let keys: [keyof KpsFileOptions, keyof KmpJsonFileOptions][] = [
58
+ ['executeProgram','executeProgram'],
59
+ ['graphicFile', 'graphicFile'],
60
+ ['msiFileName','msiFilename'],
61
+ ['msiOptions', 'msiOptions'],
62
+ ['readMeFile', 'readmeFile']
63
+ ];
64
+ for (let [src,dst] of keys) {
65
+ if (kps.options[src]) {
66
+ kmp.options[dst] = kps.options[src];
67
+ }
68
+ }
69
+
70
+ //
71
+ // Add basic metadata
72
+ //
73
+
74
+ if(kps.info) {
75
+ kmp.info = this.kpsInfoToKmpInfo(kps.info);
76
+ }
77
+
78
+ // FollowKeyboardVersion support
79
+
80
+ if(kps.options?.followKeyboardVersion !== undefined) {
81
+ kmp.info.version = {
82
+ description: this.extractKeyboardVersionFromKmx(kpsPath, kps)
83
+ };
84
+ }
85
+
86
+ //
87
+ // Add file metadata
88
+ //
89
+
90
+ if(kps.files && kps.files.file) {
91
+ kmp.files = this.arrayWrap(kps.files.file).map((file: KpsFileContentFile) => {
92
+ return {
93
+ name: file.name,
94
+ description: file.description,
95
+ copyLocation: parseInt(file.copyLocation, 10) || undefined
96
+ // note: we don't emit fileType as that is not permitted in kmp.json
97
+ };
98
+ });
99
+ }
100
+ kmp.files = kmp.files ?? [];
101
+
102
+ // Add the standard kmp.json self-referential to match existing implementations
103
+ kmp.files.push({
104
+ name: "kmp.json",
105
+ description: "Package information (JSON)"
106
+ });
107
+
108
+ //
109
+ // Add keyboard metadata
110
+ //
111
+
112
+ if(kps.keyboards && kps.keyboards.keyboard) {
113
+ kmp.keyboards = this.arrayWrap(kps.keyboards.keyboard).map((keyboard: KpsFileKeyboard) => {
114
+ return {
115
+ displayFont: keyboard.displayFont ? path.basename(keyboard.displayFont.replaceAll('\\', '/')) : undefined,
116
+ oskFont: keyboard.oSKFont ? path.basename(keyboard.oSKFont.replaceAll('\\', '/')) : undefined,
117
+ name:keyboard.name,
118
+ id:keyboard.iD,
119
+ version:keyboard.version,
120
+ languages: this.kpsLanguagesToKmpLanguages(this.arrayWrap(keyboard.languages.language) as KpsFileLanguage[])
121
+ };
122
+ });
123
+ }
124
+
125
+ //
126
+ // Add lexical-model metadata
127
+ //
128
+
129
+ if(kps.lexicalModels && kps.lexicalModels.lexicalModel) {
130
+ kmp.lexicalModels = this.arrayWrap(kps.lexicalModels.lexicalModel).map((model: KpsFileLexicalModel) => {
131
+ return { name:model.name, id:model.iD, languages: this.kpsLanguagesToKmpLanguages(this.arrayWrap(model.languages.language) as KpsFileLanguage[]) }
132
+ });
133
+ }
134
+
135
+ //
136
+ // Add Windows Start Menu metadata
137
+ //
138
+
139
+ if(kps.startMenu && kps.startMenu.items) {
140
+ kmp.startMenu = {};
141
+ if(kps.startMenu.addUninstallEntry) kmp.startMenu.addUninstallEntry = kps.startMenu.addUninstallEntry === '';
142
+ if(kps.startMenu.folder) kmp.startMenu.folder = kps.startMenu.folder;
143
+ if(kps.startMenu.items && kps.startMenu.items.item) kmp.startMenu.items = this.arrayWrap(kps.startMenu.items.item);
144
+ }
145
+
146
+ //
147
+ // Add translation strings
148
+ //
149
+
150
+ if(kps.strings && kps.strings.string) {
151
+ kmp.strings = this.arrayWrap(kps.strings.string);
152
+ }
153
+
154
+ kmp = this.stripUndefined(kmp) as KmpJsonFile;
155
+
156
+ return kmp;
157
+ }
158
+
159
+ // Helper functions
160
+
161
+ private kpsInfoToKmpInfo(info: KpsFileInfo): KmpJsonFileInfo {
162
+ let ni: KmpJsonFileInfo = {};
163
+
164
+ const keys: [(keyof KpsFileInfo), (keyof KmpJsonFileInfo)][] = [
165
+ ['author','author'],
166
+ ['copyright','copyright'],
167
+ ['name','name'],
168
+ ['version','version'],
169
+ ['webSite','website']
170
+ ];
171
+
172
+ for (let [src,dst] of keys) {
173
+ if (info[src]) {
174
+ ni[dst] = {description: info[src]._ ?? (typeof info[src] == 'string' ? info[src].toString() : '')};
175
+ if(info[src].$ && info[src].$.URL) ni[dst].url = info[src].$.URL;
176
+ }
177
+ }
178
+
179
+ return ni;
180
+ };
181
+
182
+ private arrayWrap(a: unknown) {
183
+ if (Array.isArray(a)) {
184
+ return a;
185
+ }
186
+ return [a];
187
+ };
188
+
189
+ private kpsLanguagesToKmpLanguages(language: KpsFileLanguage[]): KmpJsonFileLanguage[] {
190
+ return language.map((element) => { return { name: element._, id: element.$.ID } });
191
+ };
192
+
193
+ private extractKeyboardVersionFromKmx(kpsPath: string, kps: KpsFile) {
194
+ // TODO-LDML: #7340 this is incomplete; we need to read from first .kmx
195
+ // When we do this, we'll need to update fixtures to have the correct
196
+ // version string also
197
+ if(!kps.keyboards || !kps.keyboards.keyboard) {
198
+ // We don't read from the kps metadata because we want the keyboard
199
+ // version data here;
200
+ // TODO: currently model files don't support follow-version?
201
+ return '0.0.0';
202
+ }
203
+ let k: KpsFileKeyboard[] = this.arrayWrap(kps.keyboards.keyboard);
204
+ return k?.[0]?.version ?? '0.0.0';
205
+ }
206
+
207
+ private stripUndefined(o: any) {
208
+ for(const key in o) {
209
+ if(o[key] === undefined) {
210
+ delete o[key];
211
+ } else if(typeof o[key] == 'object') {
212
+ o[key] = this.stripUndefined(o[key]);
213
+ }
214
+ }
215
+ return o;
216
+ }
217
+
218
+ /**
219
+ * Returns a Promise to the serialized data which can then be written to a .kmp file.
220
+ *
221
+ * @param kpsFilename - Filename of the kps, not read, used only for calculating relative paths
222
+ * @param kmpJsonData - The kmp.json Object
223
+ */
224
+ public buildKmpFile(kpsFilename: string, kmpJsonData: KmpJsonFile): Promise<string> {
225
+ const zip = JSZip();
226
+
227
+ const kmpJsonFileName = 'kmp.json';
228
+
229
+ const basePath = path.dirname(kpsFilename);
230
+
231
+ // Make a copy of kmpJsonData, as we mutate paths for writing
232
+ const data: KmpJsonFile = JSON.parse(JSON.stringify(kmpJsonData));
233
+ if(!data.files) {
234
+ data.files = [];
235
+ }
236
+
237
+ data.files.forEach(function(value) {
238
+ // Get the path of the file
239
+ let filename = value.name;
240
+
241
+ // We add this separately after zipping all other files
242
+ if(filename == 'kmp.json') {
243
+ return;
244
+ }
245
+
246
+ if(path.isAbsolute(value.name)) {
247
+ // absolute paths are not very cross-platform compatible -- we are going to have trouble
248
+ // with path separators and roots
249
+ // TODO: emit a warning
250
+ } else {
251
+ // Transform separators to platform separators -- kps files may use
252
+ // either / or \, although older kps files were always \.
253
+ if(path.sep == '/') {
254
+ filename = filename.replace(/\\/g, '/');
255
+ } else {
256
+ filename = filename.replace(/\//g, '\\');
257
+ }
258
+ filename = path.resolve(basePath, filename);
259
+ }
260
+ const basename = path.basename(filename);
261
+ let data = fs.readFileSync(filename);
262
+ zip.file(basename, data);
263
+
264
+ // Remove path data from files before JSON save
265
+ value.name = basename;
266
+ });
267
+
268
+ zip.file(kmpJsonFileName, JSON.stringify(data, null, 2));
269
+
270
+ // Generate kmp file
271
+ return zip.generateAsync({type: 'binarystring', compression:'DEFLATE'});
272
+ }
273
+ }
@@ -0,0 +1,77 @@
1
+ export interface KmpJsonFile {
2
+ system: KmpJsonFileSystem;
3
+ options: KmpJsonFileOptions;
4
+ info?: KmpJsonFileInfo;
5
+ files?: KmpJsonFileContentFile[];
6
+ lexicalModels?: KmpJsonFileLexicalModel[];
7
+ startMenu?: KmpJsonFileStartMenu;
8
+ keyboards?: KmpJsonFileKeyboard[];
9
+ strings?: string[];
10
+ }
11
+
12
+ export interface KmpJsonFileSystem {
13
+ keymanDeveloperVersion: string;
14
+ fileVersion: string;
15
+ }
16
+
17
+ export interface KmpJsonFileOptions {
18
+ readmeFile?: string;
19
+ graphicFile?: string;
20
+ executeProgram?: string;
21
+ msiFilename?: string;
22
+ msiOptions?: string;
23
+ }
24
+
25
+ export interface KmpJsonFileInfo {
26
+ website?: KmpJsonFileInfoItem;
27
+ version?: KmpJsonFileInfoItem;
28
+ name?: KmpJsonFileInfoItem;
29
+ copyright?: KmpJsonFileInfoItem;
30
+ author?: KmpJsonFileInfoItem;
31
+ }
32
+
33
+ export interface KmpJsonFileInfoItem {
34
+ description: string;
35
+ url?: string;
36
+ }
37
+
38
+ export interface KmpJsonFileContentFile {
39
+ name: string;
40
+ description: string;
41
+ copyLocation?: number;
42
+ }
43
+
44
+ export interface KmpJsonFileLexicalModel {
45
+ name: string;
46
+ id: string;
47
+ languages: KmpJsonFileLanguage[];
48
+ }
49
+
50
+ export interface KmpJsonFileLanguage {
51
+ name: string;
52
+ id: string;
53
+ }
54
+
55
+ export interface KmpJsonFileKeyboard {
56
+ name: string;
57
+ id: string;
58
+ version: string;
59
+ oskFont?: string;
60
+ displayFont?: string;
61
+ rtl?: boolean;
62
+ languages?: KmpJsonFileLanguage[];
63
+ }
64
+
65
+ export interface KmpJsonFileStartMenu {
66
+ folder?: string;
67
+ addUninstallEntry?: boolean;
68
+ items?: KmpJsonFileStartMenuItem[];
69
+ }
70
+
71
+ export interface KmpJsonFileStartMenuItem {
72
+ name: string;
73
+ filename: string;
74
+ arguments?: string;
75
+ icon?: string;
76
+ location?: string;
77
+ }
@@ -0,0 +1,126 @@
1
+ //
2
+ // The interfaces in this file are designed with reference to the
3
+ // mapped structures produced by xml2js when passed a .kps file.
4
+ //
5
+ // A few notes:
6
+ //
7
+ // * Casing is updated to camelCase during load (leaving `iD` as a
8
+ // mixed up beastie).
9
+ // * Arrays are buried a layer too deep (e.g. <Files><File/><File/></Files>
10
+ // leads to KpsFiles.KpsFile[]
11
+ // * Properties such as used in Info Items use `_` and `$` and must be
12
+ // extracted.
13
+ // * Strings element is not yet checked to be correct
14
+ //
15
+
16
+ export interface KpsPackage {
17
+ /**
18
+ * <Package> -- the root element.
19
+ */
20
+ package: KpsFile;
21
+ }
22
+
23
+ export interface KpsFile {
24
+ system: KpsFileSystem;
25
+ options: KpsFileOptions;
26
+ info?: KpsFileInfo;
27
+ files?: KpsFileContentFiles;
28
+ keyboards?: KpsFileKeyboards;
29
+ lexicalModels?: KpsFileLexicalModels;
30
+ startMenu?: KpsFileStartMenu;
31
+ strings?: KpsFileStrings;
32
+ }
33
+
34
+ export interface KpsFileSystem {
35
+ keymanDeveloperVersion: string;
36
+ fileVersion: string;
37
+ }
38
+
39
+ export interface KpsFileOptions {
40
+ followKeyboardVersion?: string;
41
+ readMeFile?: string;
42
+ graphicFile?: string;
43
+ executeProgram?: string;
44
+ msiFileName?: string;
45
+ msiOptions?: string;
46
+ }
47
+
48
+ export interface KpsFileInfo {
49
+ name?: KpsFileInfoItem;
50
+ copyright?: KpsFileInfoItem;
51
+ author?: KpsFileInfoItem;
52
+ webSite?: KpsFileInfoItem;
53
+ version?: KpsFileInfoItem;
54
+ }
55
+
56
+ export interface KpsFileInfoItem {
57
+ _: string;
58
+ $: { URL: string };
59
+ }
60
+
61
+ export interface KpsFileContentFiles {
62
+ file: KpsFileContentFile[] | KpsFileContentFile;
63
+ }
64
+
65
+ export interface KpsFileContentFile {
66
+ name: string;
67
+ description: string;
68
+ copyLocation: string;
69
+ fileType: string;
70
+ }
71
+
72
+ export interface KpsFileLexicalModel {
73
+ name: string;
74
+ iD: string;
75
+ languages: KpsFileLanguages;
76
+ }
77
+
78
+ export interface KpsFileLexicalModels {
79
+ lexicalModel: KpsFileLexicalModel[] | KpsFileLexicalModel;
80
+ }
81
+
82
+ export interface KpsFileLanguages {
83
+ language: KpsFileLanguage[] | KpsFileLanguage;
84
+ }
85
+
86
+ export interface KpsFileLanguage {
87
+ _: string;
88
+ $: { ID: string }
89
+ }
90
+
91
+ export interface KpsFileKeyboard {
92
+ name: string;
93
+ iD: string;
94
+ version: string;
95
+ oSKFont?: string;
96
+ displayFont?: string;
97
+ rtl?: boolean;
98
+ languages?: KpsFileLanguages;
99
+ }
100
+
101
+ export interface KpsFileKeyboards {
102
+ keyboard: KpsFileKeyboard[] | KpsFileKeyboard;
103
+ }
104
+
105
+ export interface KpsFileStartMenu {
106
+ folder?: string;
107
+ addUninstallEntry?: string;
108
+ items?: KpsFileStartMenuItems;
109
+ }
110
+
111
+ export interface KpsFileStartMenuItem {
112
+ name: string;
113
+ filename: string;
114
+ arguments?: string;
115
+ icon?: string;
116
+ location?: string;
117
+ }
118
+
119
+ export interface KpsFileStartMenuItems {
120
+ item: KpsFileStartMenuItem[] | KpsFileStartMenuItem;
121
+ }
122
+
123
+ export interface KpsFileStrings {
124
+ //TODO: validate this structure
125
+ string: string[] | string;
126
+ }
@@ -0,0 +1,55 @@
1
+ (function() {
2
+ 'use strict';
3
+ var definitions = {
4
+ defaults: {
5
+ version: "16.0.60-alpha",
6
+ applyCasing: function defaultApplyCasing(casing, text) {
7
+ switch (casing) {
8
+ case 'lower':
9
+ return text.toLowerCase();
10
+ case 'upper':
11
+ return text.toUpperCase();
12
+ case 'initial':
13
+ var headCode = text.charCodeAt(0);
14
+ // The length of the first code unit, as measured in code points.
15
+ var headUnitLength = 1;
16
+ // Is the first character a high surrogate, indicating possible use of UTF-16
17
+ // surrogate pairs? Also, is the string long enough for there to BE a pair?
18
+ if (text.length > 1 && headCode >= 0xD800 && headCode <= 0xDBFF) {
19
+ // It's possible, so now we check for low surrogates.
20
+ var lowSurrogateCode = text.charCodeAt(1);
21
+ if (lowSurrogateCode >= 0xDC00 && lowSurrogateCode <= 0xDFFF) {
22
+ // We have a surrogate pair; this pair is the 'first' character.
23
+ headUnitLength++;
24
+ }
25
+ }
26
+ // Capitalizes the first code unit of the string, leaving the rest intact.
27
+ return text.substring(0, headUnitLength).toUpperCase() // head - uppercased
28
+ .concat(text.substring(headUnitLength)); // tail - lowercased
29
+ }
30
+ }
31
+ }, model: {
32
+ searchTermToKey: function defaultCasedSearchTermToKey(wordform, applyCasing) {
33
+ // While this is a bit WET, as the basic `defaultSearchTermToKey` exists and performs some of
34
+ // the same functions, repetition is the easiest way to allow the function to be safely compiled
35
+ // with ease by use of `.toString()`.
36
+ return Array.from(wordform
37
+ .normalize('NFKD')
38
+ // Remove any combining diacritics (if input is in NFKD)
39
+ .replace(/[\u0300-\u036F]/g, '')) // end of `Array.from`
40
+ .map(function (c) { return applyCasing('lower', c); })
41
+ .join('');
42
+ }
43
+ },
44
+ applyCasing: function(caseToApply, text) {
45
+ return definitions.defaults.applyCasing(caseToApply, text);
46
+ },
47
+ searchTermToKey: function(text) {
48
+ return definitions.model.searchTermToKey(text, definitions.applyCasing);
49
+ }
50
+ };
51
+ LMLayerWorker.loadModel(new models.TrieModel({"totalWeight":44103,"root":{"type":"internal","weight":13644,"values":["t","e","s","ȼ","n","u","i"],"children":{"t":{"type":"leaf","weight":13644,"entries":[{"key":"tŧe","weight":13644,"content":"TŦE"}]},"e":{"type":"leaf","weight":9134,"entries":[{"key":"e","weight":9134,"content":"E"}]},"s":{"type":"internal","weight":4816,"values":["e","w"],"children":{"e":{"type":"leaf","weight":4816,"entries":[{"key":"sen","weight":4816,"content":"SEN"}]},"w":{"type":"leaf","weight":2621,"entries":[{"key":"sw","weight":2621,"content":"SW̱"}]}}},"ȼ":{"type":"internal","weight":3479,"values":["﷐","s"],"children":{"﷐":{"type":"leaf","weight":3479,"entries":[{"key":"ȼ","weight":3479,"content":"Ȼ"}]},"s":{"type":"leaf","weight":1925,"entries":[{"key":"ȼse","weight":1925,"content":"ȻSE"}]}}},"n":{"type":"leaf","weight":2314,"entries":[{"key":"niƚ","weight":2314,"content":"NIȽ"}]},"u":{"type":"leaf","weight":2298,"entries":[{"key":"u ","weight":2298,"content":"U¸"}]},"i":{"type":"leaf","weight":1988,"entries":[{"key":"i ","weight":1988,"content":"I¸"},{"key":"i","weight":1884,"content":"I"}]}}}}, {
52
+ wordBreaker: wordBreakers['default'],
53
+ searchTermToKey: definitions.searchTermToKey,
54
+ }));
55
+ })();
@@ -0,0 +1,48 @@
1
+ {
2
+ "system": {
3
+ "keymanDeveloperVersion": "12.0.1500.0",
4
+ "fileVersion": "12.0"
5
+ },
6
+ "options": {},
7
+ "info": {
8
+ "author": {
9
+ "description": "Eddie Antonio Santos",
10
+ "url": "mailto:Eddie.Santos@nrc-cnrc.gc.ca"
11
+ },
12
+ "copyright": {
13
+ "description": "© 2019 National Research Council Canada"
14
+ },
15
+ "name": {
16
+ "description": "SENĆOŦEN (Saanich Dialect) Lexical Model"
17
+ },
18
+ "version": {
19
+ "description": "0.0.0"
20
+ }
21
+ },
22
+ "files": [
23
+ {
24
+ "name": "example.qaa.sencoten.model.js",
25
+ "description": "Lexical model example.qaa.sencoten.model.js"
26
+ },
27
+ {
28
+ "description": "Package information (JSON)",
29
+ "name": "kmp.json"
30
+ }
31
+ ],
32
+ "lexicalModels": [
33
+ {
34
+ "name": "SENĆOŦEN dictionary",
35
+ "id": "example.qaa.sencoten",
36
+ "languages": [
37
+ {
38
+ "name": "North Straits Salish",
39
+ "id": "qaa"
40
+ },
41
+ {
42
+ "name": "SENĆOŦEN",
43
+ "id": "qaa-Latn"
44
+ }
45
+ ]
46
+ }
47
+ ]
48
+ }
@@ -0,0 +1,48 @@
1
+ {
2
+ "system": {
3
+ "keymanDeveloperVersion": "12.0.1500.0",
4
+ "fileVersion": "12.0"
5
+ },
6
+ "options": {},
7
+ "info": {
8
+ "author": {
9
+ "description": "Eddie Antonio Santos",
10
+ "url": "mailto:Eddie.Santos@nrc-cnrc.gc.ca"
11
+ },
12
+ "copyright": {
13
+ "description": "© 2019 National Research Council Canada"
14
+ },
15
+ "name": {
16
+ "description": "SENĆOŦEN (Saanich Dialect) Lexical Model"
17
+ },
18
+ "version": {
19
+ "description": "0.0.0"
20
+ }
21
+ },
22
+ "files": [
23
+ {
24
+ "name": "..\\build\\example.qaa.sencoten.model.js",
25
+ "description": "Lexical model example.qaa.sencoten.model.js"
26
+ },
27
+ {
28
+ "name": "kmp.json",
29
+ "description": "Package information (JSON)"
30
+ }
31
+ ],
32
+ "lexicalModels": [
33
+ {
34
+ "name": "SENĆOŦEN dictionary",
35
+ "id": "example.qaa.sencoten",
36
+ "languages": [
37
+ {
38
+ "name": "North Straits Salish",
39
+ "id": "qaa"
40
+ },
41
+ {
42
+ "name": "SENĆOŦEN",
43
+ "id": "qaa-Latn"
44
+ }
45
+ ]
46
+ }
47
+ ]
48
+ }
@@ -0,0 +1,45 @@
1
+ {
2
+ "system": {
3
+ "keymanDeveloperVersion": "12.0.1500.0",
4
+ "fileVersion": "12.0"
5
+ },
6
+ "options": {},
7
+ "info": {
8
+ "author": {
9
+ "description": "Eddie Antonio Santos",
10
+ "url": "mailto:Eddie.Santos@nrc-cnrc.gc.ca"
11
+ },
12
+ "copyright": {
13
+ "description": "© 2019 National Research Council Canada"
14
+ },
15
+ "name": {
16
+ "description": "SENĆOŦEN (Saanich Dialect) Lexical Model"
17
+ },
18
+ "version": {
19
+ "description": "1.0.3"
20
+ }
21
+ },
22
+ "files": [
23
+ {
24
+ "name": "example.qaa.sencoten.model.js",
25
+ "description": "Lexical model example.qaa.sencoten.model.js",
26
+ "copyLocation": 0
27
+ }
28
+ ],
29
+ "lexicalModels": [
30
+ {
31
+ "name": "SENĆOŦEN dictionary",
32
+ "id": "example.qaa.sencoten",
33
+ "languages": [
34
+ {
35
+ "name": "North Straits Salish",
36
+ "id": "qaa"
37
+ },
38
+ {
39
+ "name": "SENĆOŦEN",
40
+ "id": "qaa-Latn"
41
+ }
42
+ ]
43
+ }
44
+ ]
45
+ }