@willwade/aac-processors 0.0.6 → 0.0.8
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.
- package/README.md +2 -40
- package/dist/analytics/history.d.ts +57 -0
- package/dist/analytics/history.js +72 -0
- package/dist/core/analyze.d.ts +10 -0
- package/dist/core/analyze.js +10 -0
- package/dist/core/stringCasing.d.ts +11 -0
- package/dist/core/stringCasing.js +11 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +5 -0
- package/dist/processors/dotProcessor.js +31 -12
- package/dist/processors/gridset/colorUtils.d.ts +69 -0
- package/dist/processors/gridset/colorUtils.js +331 -0
- package/dist/processors/gridset/helpers.d.ts +125 -0
- package/dist/processors/gridset/helpers.js +354 -0
- package/dist/processors/gridset/styleHelpers.d.ts +3 -4
- package/dist/processors/gridset/styleHelpers.js +10 -44
- package/dist/processors/index.d.ts +6 -4
- package/dist/processors/index.js +51 -3
- package/dist/processors/obfProcessor.js +10 -2
- package/dist/processors/snap/helpers.d.ts +85 -0
- package/dist/processors/snap/helpers.js +259 -2
- package/dist/processors/snapProcessor.js +27 -5
- package/dist/processors/touchchat/helpers.d.ts +12 -0
- package/dist/processors/touchchat/helpers.js +12 -2
- package/dist/utils/dotnetTicks.d.ts +13 -0
- package/dist/utils/dotnetTicks.js +21 -0
- package/package.json +8 -6
- package/docs/.keep +0 -1
- package/docs/ApplePanels.md +0 -309
- package/docs/Grid3-Styling-Guide.md +0 -287
- package/docs/Grid3-XML-Format.md +0 -1788
- package/docs/TobiiDynavox-Snap-Details.md +0 -394
- package/docs/asterics-Grid-fileformat-details.md +0 -443
- package/docs/obf_.obz Open Board File Formats.md +0 -432
- package/docs/touchchat.md +0 -520
|
@@ -1,4 +1,27 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || function (mod) {
|
|
19
|
+
if (mod && mod.__esModule) return mod;
|
|
20
|
+
var result = {};
|
|
21
|
+
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
22
|
+
__setModuleDefault(result, mod);
|
|
23
|
+
return result;
|
|
24
|
+
};
|
|
2
25
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
26
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
27
|
};
|
|
@@ -6,7 +29,26 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
6
29
|
exports.getPageTokenImageMap = getPageTokenImageMap;
|
|
7
30
|
exports.getAllowedImageEntries = getAllowedImageEntries;
|
|
8
31
|
exports.openImage = openImage;
|
|
32
|
+
exports.generateGrid3Guid = generateGrid3Guid;
|
|
33
|
+
exports.createSettingsXml = createSettingsXml;
|
|
34
|
+
exports.createFileMapXml = createFileMapXml;
|
|
35
|
+
exports.getCommonDocumentsPath = getCommonDocumentsPath;
|
|
36
|
+
exports.findGrid3UserPaths = findGrid3UserPaths;
|
|
37
|
+
exports.findGrid3HistoryDatabases = findGrid3HistoryDatabases;
|
|
38
|
+
exports.findGrid3Users = findGrid3Users;
|
|
39
|
+
exports.findGrid3Vocabularies = findGrid3Vocabularies;
|
|
40
|
+
exports.findGrid3UserHistory = findGrid3UserHistory;
|
|
41
|
+
exports.isGrid3Installed = isGrid3Installed;
|
|
42
|
+
exports.readGrid3History = readGrid3History;
|
|
43
|
+
exports.readGrid3HistoryForUser = readGrid3HistoryForUser;
|
|
44
|
+
exports.readAllGrid3History = readAllGrid3History;
|
|
9
45
|
const adm_zip_1 = __importDefault(require("adm-zip"));
|
|
46
|
+
const fast_xml_parser_1 = require("fast-xml-parser");
|
|
47
|
+
const fs = __importStar(require("fs"));
|
|
48
|
+
const path = __importStar(require("path"));
|
|
49
|
+
const child_process_1 = require("child_process");
|
|
50
|
+
const better_sqlite3_1 = __importDefault(require("better-sqlite3"));
|
|
51
|
+
const dotnetTicks_1 = require("../../utils/dotnetTicks");
|
|
10
52
|
function normalizeZipPath(p) {
|
|
11
53
|
const unified = p.replace(/\\/g, '/');
|
|
12
54
|
try {
|
|
@@ -16,6 +58,10 @@ function normalizeZipPath(p) {
|
|
|
16
58
|
return unified;
|
|
17
59
|
}
|
|
18
60
|
}
|
|
61
|
+
/**
|
|
62
|
+
* Build a map of button IDs to resolved image entry paths for a specific page.
|
|
63
|
+
* Helpful when rewriting zip entry names or validating images referenced in a grid.
|
|
64
|
+
*/
|
|
19
65
|
function getPageTokenImageMap(tree, pageId) {
|
|
20
66
|
const map = new Map();
|
|
21
67
|
const page = tree.getPage(pageId);
|
|
@@ -28,6 +74,10 @@ function getPageTokenImageMap(tree, pageId) {
|
|
|
28
74
|
}
|
|
29
75
|
return map;
|
|
30
76
|
}
|
|
77
|
+
/**
|
|
78
|
+
* Collect all image entries referenced across every page in a tree.
|
|
79
|
+
* Returns normalized zip entry paths that should be preserved when pruning images.
|
|
80
|
+
*/
|
|
31
81
|
function getAllowedImageEntries(tree) {
|
|
32
82
|
const out = new Set();
|
|
33
83
|
Object.values(tree.pages).forEach((page) => {
|
|
@@ -38,6 +88,12 @@ function getAllowedImageEntries(tree) {
|
|
|
38
88
|
});
|
|
39
89
|
return out;
|
|
40
90
|
}
|
|
91
|
+
/**
|
|
92
|
+
* Read an image entry from a gridset zip by path.
|
|
93
|
+
* @param gridsetBuffer Gridset archive contents
|
|
94
|
+
* @param entryPath Entry name inside the zip
|
|
95
|
+
* @returns Image data buffer or null if not found
|
|
96
|
+
*/
|
|
41
97
|
function openImage(gridsetBuffer, entryPath) {
|
|
42
98
|
const zip = new adm_zip_1.default(gridsetBuffer);
|
|
43
99
|
const want = normalizeZipPath(entryPath);
|
|
@@ -46,3 +102,301 @@ function openImage(gridsetBuffer, entryPath) {
|
|
|
46
102
|
return null;
|
|
47
103
|
return entry.getData();
|
|
48
104
|
}
|
|
105
|
+
/**
|
|
106
|
+
* Generate a random GUID for Grid3 elements
|
|
107
|
+
* Grid3 uses GUIDs for grid identification
|
|
108
|
+
* @returns A UUID v4-like string in the format xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx
|
|
109
|
+
*/
|
|
110
|
+
function generateGrid3Guid() {
|
|
111
|
+
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
|
|
112
|
+
const r = (Math.random() * 16) | 0;
|
|
113
|
+
const v = c === 'x' ? r : (r & 0x3) | 0x8;
|
|
114
|
+
return v.toString(16);
|
|
115
|
+
});
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* Create Grid3 settings XML with start grid and common settings
|
|
119
|
+
* @param startGrid - Name of the grid to start on
|
|
120
|
+
* @param options - Optional settings (scan, hover, language, etc.)
|
|
121
|
+
* @returns XML string for Settings.xml
|
|
122
|
+
*/
|
|
123
|
+
function createSettingsXml(startGrid, options) {
|
|
124
|
+
const builder = new fast_xml_parser_1.XMLBuilder({
|
|
125
|
+
ignoreAttributes: false,
|
|
126
|
+
format: true,
|
|
127
|
+
indentBy: ' ',
|
|
128
|
+
});
|
|
129
|
+
const settingsData = {
|
|
130
|
+
GridSetSettings: {
|
|
131
|
+
'@_xmlns:xsi': 'http://www.w3.org/2001/XMLSchema-instance',
|
|
132
|
+
StartGrid: startGrid,
|
|
133
|
+
ScanEnabled: options?.scanEnabled?.toString() ?? 'false',
|
|
134
|
+
ScanTimeoutMs: options?.scanTimeoutMs?.toString() ?? '2000',
|
|
135
|
+
HoverEnabled: options?.hoverEnabled?.toString() ?? 'false',
|
|
136
|
+
HoverTimeoutMs: options?.hoverTimeoutMs?.toString() ?? '1000',
|
|
137
|
+
MouseclickEnabled: options?.mouseclickEnabled?.toString() ?? 'true',
|
|
138
|
+
Language: options?.language ?? 'en-US',
|
|
139
|
+
},
|
|
140
|
+
};
|
|
141
|
+
return builder.build(settingsData);
|
|
142
|
+
}
|
|
143
|
+
/**
|
|
144
|
+
* Create Grid3 FileMap.xml content
|
|
145
|
+
* @param grids - Array of grid configurations with name and path
|
|
146
|
+
* @returns XML string for FileMap.xml
|
|
147
|
+
*/
|
|
148
|
+
function createFileMapXml(grids) {
|
|
149
|
+
const builder = new fast_xml_parser_1.XMLBuilder({
|
|
150
|
+
ignoreAttributes: false,
|
|
151
|
+
format: true,
|
|
152
|
+
indentBy: ' ',
|
|
153
|
+
});
|
|
154
|
+
const entries = grids.map((grid) => ({
|
|
155
|
+
'@_StaticFile': grid.path,
|
|
156
|
+
...(grid.dynamicFiles && grid.dynamicFiles.length > 0
|
|
157
|
+
? { DynamicFiles: { File: grid.dynamicFiles } }
|
|
158
|
+
: {}),
|
|
159
|
+
}));
|
|
160
|
+
const fileMapData = {
|
|
161
|
+
FileMap: {
|
|
162
|
+
'@_xmlns:xsi': 'http://www.w3.org/2001/XMLSchema-instance',
|
|
163
|
+
Entries: {
|
|
164
|
+
Entry: entries,
|
|
165
|
+
},
|
|
166
|
+
},
|
|
167
|
+
};
|
|
168
|
+
return builder.build(fileMapData);
|
|
169
|
+
}
|
|
170
|
+
/**
|
|
171
|
+
* Get the Windows Common Documents folder path from registry
|
|
172
|
+
* Falls back to default path if registry access fails
|
|
173
|
+
* @returns Path to Common Documents folder
|
|
174
|
+
*/
|
|
175
|
+
function getCommonDocumentsPath() {
|
|
176
|
+
// Only works on Windows
|
|
177
|
+
if (process.platform !== 'win32') {
|
|
178
|
+
return '';
|
|
179
|
+
}
|
|
180
|
+
try {
|
|
181
|
+
// Query registry for Common Documents path
|
|
182
|
+
const command = 'REG.EXE QUERY "HKLM\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders" /V "Common Documents"';
|
|
183
|
+
const output = (0, child_process_1.execSync)(command, { encoding: 'utf-8', windowsHide: true });
|
|
184
|
+
// Parse the output to extract the path
|
|
185
|
+
const match = output.match(/Common Documents\s+REG_SZ\s+(.+)/);
|
|
186
|
+
if (match && match[1]) {
|
|
187
|
+
return match[1].trim();
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
catch (error) {
|
|
191
|
+
// Registry access failed, fall back to default
|
|
192
|
+
}
|
|
193
|
+
// Default fallback path
|
|
194
|
+
return 'C:\\Users\\Public\\Documents';
|
|
195
|
+
}
|
|
196
|
+
/**
|
|
197
|
+
* Find all Grid3 user data paths
|
|
198
|
+
* Searches for users and language codes in the Grid3 directory structure
|
|
199
|
+
* C:\Users\Public\Documents\Smartbox\Grid 3\Users\{UserName}\{langCode}\Phrases\history.sqlite
|
|
200
|
+
* @returns Array of Grid3 user path information
|
|
201
|
+
*/
|
|
202
|
+
function findGrid3UserPaths() {
|
|
203
|
+
const results = [];
|
|
204
|
+
// Only works on Windows
|
|
205
|
+
if (process.platform !== 'win32') {
|
|
206
|
+
return results;
|
|
207
|
+
}
|
|
208
|
+
try {
|
|
209
|
+
const commonDocs = getCommonDocumentsPath();
|
|
210
|
+
// Use Windows path joining so tests that mock a Windows platform stay consistent even on POSIX runners
|
|
211
|
+
const grid3BasePath = path.win32.join(commonDocs, 'Smartbox', 'Grid 3', 'Users');
|
|
212
|
+
// Check if Grid3 Users directory exists
|
|
213
|
+
if (!fs.existsSync(grid3BasePath)) {
|
|
214
|
+
return results;
|
|
215
|
+
}
|
|
216
|
+
// Enumerate users
|
|
217
|
+
const users = fs.readdirSync(grid3BasePath, { withFileTypes: true });
|
|
218
|
+
for (const userDir of users) {
|
|
219
|
+
if (!userDir.isDirectory())
|
|
220
|
+
continue;
|
|
221
|
+
const userName = userDir.name;
|
|
222
|
+
const userPath = path.win32.join(grid3BasePath, userName);
|
|
223
|
+
// Enumerate language codes
|
|
224
|
+
const langDirs = fs.readdirSync(userPath, { withFileTypes: true });
|
|
225
|
+
for (const langDir of langDirs) {
|
|
226
|
+
if (!langDir.isDirectory())
|
|
227
|
+
continue;
|
|
228
|
+
const langCode = langDir.name;
|
|
229
|
+
const basePath = path.win32.join(userPath, langCode);
|
|
230
|
+
const historyDbPath = path.win32.join(basePath, 'Phrases', 'history.sqlite');
|
|
231
|
+
// Only include if history database exists
|
|
232
|
+
if (fs.existsSync(historyDbPath)) {
|
|
233
|
+
results.push({
|
|
234
|
+
userName,
|
|
235
|
+
langCode,
|
|
236
|
+
basePath,
|
|
237
|
+
historyDbPath,
|
|
238
|
+
});
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
catch (error) {
|
|
244
|
+
// Silently fail if directory access fails
|
|
245
|
+
}
|
|
246
|
+
return results;
|
|
247
|
+
}
|
|
248
|
+
/**
|
|
249
|
+
* Find all Grid3 history database paths
|
|
250
|
+
* Convenience method that returns just the database file paths
|
|
251
|
+
* @returns Array of paths to history.sqlite files
|
|
252
|
+
*/
|
|
253
|
+
function findGrid3HistoryDatabases() {
|
|
254
|
+
return findGrid3UserPaths().map((userPath) => userPath.historyDbPath);
|
|
255
|
+
}
|
|
256
|
+
/**
|
|
257
|
+
* Get Grid 3 users (alias of findGrid3UserPaths for clarity)
|
|
258
|
+
*/
|
|
259
|
+
function findGrid3Users() {
|
|
260
|
+
return findGrid3UserPaths();
|
|
261
|
+
}
|
|
262
|
+
/**
|
|
263
|
+
* Find Grid 3 gridset/vocabulary files for each user
|
|
264
|
+
* @param userName Optional user filter; matches case-insensitively
|
|
265
|
+
* @returns Array of user/gridset path pairs
|
|
266
|
+
*/
|
|
267
|
+
function findGrid3Vocabularies(userName) {
|
|
268
|
+
const results = [];
|
|
269
|
+
if (process.platform !== 'win32') {
|
|
270
|
+
return results;
|
|
271
|
+
}
|
|
272
|
+
const commonDocs = getCommonDocumentsPath();
|
|
273
|
+
const grid3BasePath = path.win32.join(commonDocs, 'Smartbox', 'Grid 3', 'Users');
|
|
274
|
+
if (!fs.existsSync(grid3BasePath)) {
|
|
275
|
+
return results;
|
|
276
|
+
}
|
|
277
|
+
const normalizedUser = userName?.toLowerCase();
|
|
278
|
+
const users = fs.readdirSync(grid3BasePath, { withFileTypes: true });
|
|
279
|
+
for (const userDir of users) {
|
|
280
|
+
if (!userDir.isDirectory())
|
|
281
|
+
continue;
|
|
282
|
+
if (normalizedUser && userDir.name.toLowerCase() !== normalizedUser)
|
|
283
|
+
continue;
|
|
284
|
+
const userRoot = path.win32.join(grid3BasePath, userDir.name);
|
|
285
|
+
const gridSetsDir = path.win32.join(userRoot, 'Grid Sets');
|
|
286
|
+
if (!fs.existsSync(gridSetsDir))
|
|
287
|
+
continue;
|
|
288
|
+
const entries = fs.readdirSync(gridSetsDir, { withFileTypes: true });
|
|
289
|
+
for (const entry of entries) {
|
|
290
|
+
if (!entry.isFile())
|
|
291
|
+
continue;
|
|
292
|
+
const ext = path.extname(entry.name).toLowerCase();
|
|
293
|
+
if (ext === '.gridset' || ext === '.grd' || ext === '.grdl') {
|
|
294
|
+
results.push({
|
|
295
|
+
userName: userDir.name,
|
|
296
|
+
gridsetPath: path.win32.join(gridSetsDir, entry.name),
|
|
297
|
+
});
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
return results;
|
|
302
|
+
}
|
|
303
|
+
/**
|
|
304
|
+
* Find a specific user's Grid 3 history database
|
|
305
|
+
* @param userName User name to search for (case-insensitive)
|
|
306
|
+
* @param langCode Optional language code filter (case-insensitive)
|
|
307
|
+
* @returns Path to history.sqlite or null if not found
|
|
308
|
+
*/
|
|
309
|
+
function findGrid3UserHistory(userName, langCode) {
|
|
310
|
+
const normalizedUser = userName.toLowerCase();
|
|
311
|
+
const normalizedLang = langCode?.toLowerCase();
|
|
312
|
+
const match = findGrid3UserPaths().find((u) => u.userName.toLowerCase() === normalizedUser &&
|
|
313
|
+
(!normalizedLang || u.langCode.toLowerCase() === normalizedLang));
|
|
314
|
+
return match?.historyDbPath ?? null;
|
|
315
|
+
}
|
|
316
|
+
/**
|
|
317
|
+
* Check whether Grid 3 appears to be installed (Windows only)
|
|
318
|
+
*/
|
|
319
|
+
function isGrid3Installed() {
|
|
320
|
+
if (process.platform !== 'win32')
|
|
321
|
+
return false;
|
|
322
|
+
const commonDocs = getCommonDocumentsPath();
|
|
323
|
+
if (!commonDocs)
|
|
324
|
+
return false;
|
|
325
|
+
const grid3BasePath = path.win32.join(commonDocs, 'Smartbox', 'Grid 3', 'Users');
|
|
326
|
+
return fs.existsSync(grid3BasePath);
|
|
327
|
+
}
|
|
328
|
+
function parseGrid3ContentXml(xmlContent) {
|
|
329
|
+
const regex = /<r>(?:<!\[CDATA\[)?(.*?)(?:\]\]>)?<\/r>/gis;
|
|
330
|
+
const parts = [];
|
|
331
|
+
let match;
|
|
332
|
+
while ((match = regex.exec(xmlContent)) !== null) {
|
|
333
|
+
parts.push(match[1]);
|
|
334
|
+
}
|
|
335
|
+
if (parts.length > 0) {
|
|
336
|
+
return parts.join('');
|
|
337
|
+
}
|
|
338
|
+
return xmlContent.replace(/<[^>]+>/g, '').trim();
|
|
339
|
+
}
|
|
340
|
+
/**
|
|
341
|
+
* Read history events from a Grid 3 history.sqlite database.
|
|
342
|
+
* @param historyDbPath Absolute path to the history database
|
|
343
|
+
* @returns Parsed history entries grouped by phrase
|
|
344
|
+
*/
|
|
345
|
+
function readGrid3History(historyDbPath) {
|
|
346
|
+
if (!fs.existsSync(historyDbPath))
|
|
347
|
+
return [];
|
|
348
|
+
const db = new better_sqlite3_1.default(historyDbPath, { readonly: true });
|
|
349
|
+
const rows = db
|
|
350
|
+
.prepare(`
|
|
351
|
+
SELECT p.Id as PhraseId,
|
|
352
|
+
p.Text as TextValue,
|
|
353
|
+
p.Content as ContentXml,
|
|
354
|
+
ph.Timestamp as TickValue,
|
|
355
|
+
ph.Latitude as Latitude,
|
|
356
|
+
ph.Longitude as Longitude
|
|
357
|
+
FROM PhraseHistory ph
|
|
358
|
+
INNER JOIN Phrases p ON p.Id = ph.PhraseId
|
|
359
|
+
WHERE ph.Timestamp <> 0
|
|
360
|
+
ORDER BY ph.Timestamp ASC
|
|
361
|
+
`)
|
|
362
|
+
.all();
|
|
363
|
+
const events = new Map();
|
|
364
|
+
for (const row of rows) {
|
|
365
|
+
const phraseId = row.PhraseId;
|
|
366
|
+
const contentText = parseGrid3ContentXml(String(row.ContentXml ?? row.TextValue ?? ''));
|
|
367
|
+
const entry = events.get(phraseId) ??
|
|
368
|
+
{
|
|
369
|
+
id: `grid:${phraseId}`,
|
|
370
|
+
content: contentText,
|
|
371
|
+
occurrences: [],
|
|
372
|
+
rawXml: row.ContentXml,
|
|
373
|
+
};
|
|
374
|
+
entry.occurrences.push({
|
|
375
|
+
timestamp: (0, dotnetTicks_1.dotNetTicksToDate)(BigInt(row.TickValue ?? 0)),
|
|
376
|
+
latitude: row.Latitude ?? null,
|
|
377
|
+
longitude: row.Longitude ?? null,
|
|
378
|
+
});
|
|
379
|
+
events.set(phraseId, entry);
|
|
380
|
+
}
|
|
381
|
+
return Array.from(events.values());
|
|
382
|
+
}
|
|
383
|
+
/**
|
|
384
|
+
* Convenience wrapper to load history for a specific Grid 3 user/lang combination.
|
|
385
|
+
* @param userName Grid 3 user name (case-insensitive)
|
|
386
|
+
* @param langCode Optional language code to narrow selection (case-insensitive)
|
|
387
|
+
* @returns History entries for that user/language, or empty array if none
|
|
388
|
+
*/
|
|
389
|
+
function readGrid3HistoryForUser(userName, langCode) {
|
|
390
|
+
const dbPath = findGrid3UserHistory(userName, langCode);
|
|
391
|
+
if (!dbPath)
|
|
392
|
+
return [];
|
|
393
|
+
return readGrid3History(dbPath);
|
|
394
|
+
}
|
|
395
|
+
/**
|
|
396
|
+
* Load all available Grid 3 histories on the machine.
|
|
397
|
+
* @returns Combined history entries from every discovered history.sqlite
|
|
398
|
+
*/
|
|
399
|
+
function readAllGrid3History() {
|
|
400
|
+
const paths = findGrid3HistoryDatabases();
|
|
401
|
+
return paths.flatMap((p) => readGrid3History(p));
|
|
402
|
+
}
|
|
@@ -25,11 +25,10 @@ export declare const DEFAULT_GRID3_STYLES: Record<string, Grid3Style>;
|
|
|
25
25
|
*/
|
|
26
26
|
export declare const CATEGORY_STYLES: Record<string, Grid3Style>;
|
|
27
27
|
/**
|
|
28
|
-
*
|
|
29
|
-
* @
|
|
30
|
-
* @returns Color with alpha channel in format #AARRGGBBFF
|
|
28
|
+
* Re-export ensureAlphaChannel from colorUtils for backward compatibility
|
|
29
|
+
* @deprecated Use ensureAlphaChannel from colorUtils instead
|
|
31
30
|
*/
|
|
32
|
-
export
|
|
31
|
+
export { ensureAlphaChannel } from './colorUtils';
|
|
33
32
|
/**
|
|
34
33
|
* Create a Grid3 style XML string with default and category styles
|
|
35
34
|
* @param includeCategories - Whether to include category-specific styles (default: true)
|
|
@@ -6,11 +6,11 @@
|
|
|
6
6
|
* style XML generation, and style conversion utilities.
|
|
7
7
|
*/
|
|
8
8
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
-
exports.CATEGORY_STYLES = exports.DEFAULT_GRID3_STYLES = void 0;
|
|
10
|
-
exports.ensureAlphaChannel = ensureAlphaChannel;
|
|
9
|
+
exports.ensureAlphaChannel = exports.CATEGORY_STYLES = exports.DEFAULT_GRID3_STYLES = void 0;
|
|
11
10
|
exports.createDefaultStylesXml = createDefaultStylesXml;
|
|
12
11
|
exports.createCategoryStyle = createCategoryStyle;
|
|
13
12
|
const fast_xml_parser_1 = require("fast-xml-parser");
|
|
13
|
+
const colorUtils_1 = require("./colorUtils");
|
|
14
14
|
/**
|
|
15
15
|
* Default Grid3 styles for common use cases
|
|
16
16
|
* Colors are in 8-digit ARGB hex format (#AARRGGBBFF)
|
|
@@ -119,29 +119,11 @@ exports.CATEGORY_STYLES = {
|
|
|
119
119
|
},
|
|
120
120
|
};
|
|
121
121
|
/**
|
|
122
|
-
*
|
|
123
|
-
* @
|
|
124
|
-
* @returns Color with alpha channel in format #AARRGGBBFF
|
|
122
|
+
* Re-export ensureAlphaChannel from colorUtils for backward compatibility
|
|
123
|
+
* @deprecated Use ensureAlphaChannel from colorUtils instead
|
|
125
124
|
*/
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
return '#FFFFFFFF';
|
|
129
|
-
// If already 8 digits (with alpha), return as is
|
|
130
|
-
if (color.match(/^#[0-9A-Fa-f]{8}$/))
|
|
131
|
-
return color;
|
|
132
|
-
// If 6 digits (no alpha), add FF for fully opaque
|
|
133
|
-
if (color.match(/^#[0-9A-Fa-f]{6}$/))
|
|
134
|
-
return color + 'FF';
|
|
135
|
-
// If 3 digits (shorthand), expand to 8
|
|
136
|
-
if (color.match(/^#[0-9A-Fa-f]{3}$/)) {
|
|
137
|
-
const r = color[1];
|
|
138
|
-
const g = color[2];
|
|
139
|
-
const b = color[3];
|
|
140
|
-
return `#${r}${r}${g}${g}${b}${b}FF`;
|
|
141
|
-
}
|
|
142
|
-
// Invalid or unknown format, return white
|
|
143
|
-
return '#FFFFFFFF';
|
|
144
|
-
}
|
|
125
|
+
var colorUtils_2 = require("./colorUtils");
|
|
126
|
+
Object.defineProperty(exports, "ensureAlphaChannel", { enumerable: true, get: function () { return colorUtils_2.ensureAlphaChannel; } });
|
|
145
127
|
/**
|
|
146
128
|
* Create a Grid3 style XML string with default and category styles
|
|
147
129
|
* @param includeCategories - Whether to include category-specific styles (default: true)
|
|
@@ -185,27 +167,11 @@ function createDefaultStylesXml(includeCategories = true) {
|
|
|
185
167
|
*/
|
|
186
168
|
function createCategoryStyle(categoryName, backgroundColor, fontColor = '#FFFFFFFF') {
|
|
187
169
|
return {
|
|
188
|
-
BackColour: ensureAlphaChannel(backgroundColor),
|
|
189
|
-
TileColour: ensureAlphaChannel(backgroundColor),
|
|
190
|
-
BorderColour: ensureAlphaChannel(darkenColor(backgroundColor, 30)),
|
|
191
|
-
FontColour: ensureAlphaChannel(fontColor),
|
|
170
|
+
BackColour: (0, colorUtils_1.ensureAlphaChannel)(backgroundColor),
|
|
171
|
+
TileColour: (0, colorUtils_1.ensureAlphaChannel)(backgroundColor),
|
|
172
|
+
BorderColour: (0, colorUtils_1.ensureAlphaChannel)((0, colorUtils_1.darkenColor)(backgroundColor, 30)),
|
|
173
|
+
FontColour: (0, colorUtils_1.ensureAlphaChannel)(fontColor),
|
|
192
174
|
FontName: 'Arial',
|
|
193
175
|
FontSize: '16',
|
|
194
176
|
};
|
|
195
177
|
}
|
|
196
|
-
/**
|
|
197
|
-
* Darken a hex color by a given amount
|
|
198
|
-
* @param hexColor - Hex color string
|
|
199
|
-
* @param amount - Amount to darken (0-255)
|
|
200
|
-
* @returns Darkened hex color
|
|
201
|
-
*/
|
|
202
|
-
function darkenColor(hexColor, amount) {
|
|
203
|
-
const normalized = ensureAlphaChannel(hexColor);
|
|
204
|
-
const hex = normalized.slice(1, 7); // Extract RGB part (skip # and alpha)
|
|
205
|
-
const num = parseInt(hex, 16);
|
|
206
|
-
const clamp = (value) => Math.max(0, Math.min(255, value));
|
|
207
|
-
const r = clamp(((num >> 16) & 0xff) - amount);
|
|
208
|
-
const g = clamp(((num >> 8) & 0xff) - amount);
|
|
209
|
-
const b = clamp((num & 0xff) - amount);
|
|
210
|
-
return `#${((1 << 24) + (r << 16) + (g << 8) + b).toString(16).slice(1)}`;
|
|
211
|
-
}
|
|
@@ -7,10 +7,12 @@ export { OpmlProcessor } from './opmlProcessor';
|
|
|
7
7
|
export { SnapProcessor } from './snapProcessor';
|
|
8
8
|
export { TouchChatProcessor } from './touchchatProcessor';
|
|
9
9
|
export { AstericsGridProcessor } from './astericsGridProcessor';
|
|
10
|
-
export { getPageTokenImageMap, getAllowedImageEntries, openImage } from './gridset/helpers';
|
|
11
|
-
export { getPageTokenImageMap as getGridsetPageTokenImageMap, getAllowedImageEntries as getGridsetAllowedImageEntries, openImage as openGridsetImage, } from './gridset/helpers';
|
|
10
|
+
export { getPageTokenImageMap, getAllowedImageEntries, openImage, generateGrid3Guid, createSettingsXml, createFileMapXml, getCommonDocumentsPath, findGrid3UserPaths, findGrid3HistoryDatabases, findGrid3Users, findGrid3Vocabularies, findGrid3UserHistory, isGrid3Installed, readGrid3History, readGrid3HistoryForUser, readAllGrid3History, type Grid3UserPath, type Grid3VocabularyPath, type Grid3HistoryEntry, } from './gridset/helpers';
|
|
11
|
+
export { getPageTokenImageMap as getGridsetPageTokenImageMap, getAllowedImageEntries as getGridsetAllowedImageEntries, openImage as openGridsetImage, generateGrid3Guid as generateGridsetGuid, createSettingsXml as createGridsetSettingsXml, createFileMapXml as createGridsetFileMapXml, getCommonDocumentsPath as getGridsetCommonDocumentsPath, findGrid3UserPaths as findGridsetUserPaths, findGrid3HistoryDatabases as findGridsetHistoryDatabases, findGrid3Users as findGridsetUsers, findGrid3Vocabularies as findGridsetVocabularies, findGrid3UserHistory as findGridsetUserHistory, isGrid3Installed as isGridsetInstalled, readGrid3History as readGridsetHistory, readGrid3HistoryForUser as readGridsetHistoryForUser, readAllGrid3History as readAllGridsetHistory, } from './gridset/helpers';
|
|
12
12
|
export { resolveGrid3CellImage } from './gridset/resolver';
|
|
13
13
|
export { createWordlist, extractWordlists, updateWordlist, wordlistToXml, type WordList, type WordListItem, } from './gridset/wordlistHelpers';
|
|
14
|
-
export {
|
|
15
|
-
export {
|
|
14
|
+
export { getNamedColor, rgbaToHex, channelToHex, clampColorChannel, clampAlpha, toHexColor, darkenColor, normalizeColor, ensureAlphaChannel, } from './gridset/colorUtils';
|
|
15
|
+
export { DEFAULT_GRID3_STYLES, CATEGORY_STYLES, createDefaultStylesXml, createCategoryStyle, } from './gridset/styleHelpers';
|
|
16
|
+
export { ensureAlphaChannel as ensureAlphaChannelFromStyles } from './gridset/styleHelpers';
|
|
17
|
+
export { getPageTokenImageMap as getSnapPageTokenImageMap, getAllowedImageEntries as getSnapAllowedImageEntries, openImage as openSnapImage, findSnapPackages, findSnapPackagePath, findSnapUsers, findSnapUserVocabularies, findSnapUserHistory, isSnapInstalled, readSnapUsage, readSnapUsageForUser, type SnapPackagePath, type SnapUserInfo, type SnapUsageEntry, } from './snap/helpers';
|
|
16
18
|
export { getPageTokenImageMap as getTouchChatPageTokenImageMap, getAllowedImageEntries as getTouchChatAllowedImageEntries, openImage as openTouchChatImage, } from './touchchat/helpers';
|
package/dist/processors/index.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.
|
|
3
|
+
exports.clampColorChannel = exports.channelToHex = exports.rgbaToHex = exports.getNamedColor = exports.wordlistToXml = exports.updateWordlist = exports.extractWordlists = exports.createWordlist = exports.resolveGrid3CellImage = exports.readAllGridsetHistory = exports.readGridsetHistoryForUser = exports.readGridsetHistory = exports.isGridsetInstalled = exports.findGridsetUserHistory = exports.findGridsetVocabularies = exports.findGridsetUsers = exports.findGridsetHistoryDatabases = exports.findGridsetUserPaths = exports.getGridsetCommonDocumentsPath = exports.createGridsetFileMapXml = exports.createGridsetSettingsXml = exports.generateGridsetGuid = exports.openGridsetImage = exports.getGridsetAllowedImageEntries = exports.getGridsetPageTokenImageMap = exports.readAllGrid3History = exports.readGrid3HistoryForUser = exports.readGrid3History = exports.isGrid3Installed = exports.findGrid3UserHistory = exports.findGrid3Vocabularies = exports.findGrid3Users = exports.findGrid3HistoryDatabases = exports.findGrid3UserPaths = exports.getCommonDocumentsPath = exports.createFileMapXml = exports.createSettingsXml = exports.generateGrid3Guid = exports.openImage = exports.getAllowedImageEntries = exports.getPageTokenImageMap = exports.AstericsGridProcessor = exports.TouchChatProcessor = exports.SnapProcessor = exports.OpmlProcessor = exports.ObfProcessor = exports.GridsetProcessor = exports.ExcelProcessor = exports.DotProcessor = exports.ApplePanelsProcessor = void 0;
|
|
4
|
+
exports.openTouchChatImage = exports.getTouchChatAllowedImageEntries = exports.getTouchChatPageTokenImageMap = exports.readSnapUsageForUser = exports.readSnapUsage = exports.isSnapInstalled = exports.findSnapUserHistory = exports.findSnapUserVocabularies = exports.findSnapUsers = exports.findSnapPackagePath = exports.findSnapPackages = exports.openSnapImage = exports.getSnapAllowedImageEntries = exports.getSnapPageTokenImageMap = exports.ensureAlphaChannelFromStyles = exports.createCategoryStyle = exports.createDefaultStylesXml = exports.CATEGORY_STYLES = exports.DEFAULT_GRID3_STYLES = exports.ensureAlphaChannel = exports.normalizeColor = exports.darkenColor = exports.toHexColor = exports.clampAlpha = void 0;
|
|
4
5
|
var applePanelsProcessor_1 = require("./applePanelsProcessor");
|
|
5
6
|
Object.defineProperty(exports, "ApplePanelsProcessor", { enumerable: true, get: function () { return applePanelsProcessor_1.ApplePanelsProcessor; } });
|
|
6
7
|
var dotProcessor_1 = require("./dotProcessor");
|
|
@@ -24,10 +25,36 @@ var helpers_1 = require("./gridset/helpers");
|
|
|
24
25
|
Object.defineProperty(exports, "getPageTokenImageMap", { enumerable: true, get: function () { return helpers_1.getPageTokenImageMap; } });
|
|
25
26
|
Object.defineProperty(exports, "getAllowedImageEntries", { enumerable: true, get: function () { return helpers_1.getAllowedImageEntries; } });
|
|
26
27
|
Object.defineProperty(exports, "openImage", { enumerable: true, get: function () { return helpers_1.openImage; } });
|
|
28
|
+
Object.defineProperty(exports, "generateGrid3Guid", { enumerable: true, get: function () { return helpers_1.generateGrid3Guid; } });
|
|
29
|
+
Object.defineProperty(exports, "createSettingsXml", { enumerable: true, get: function () { return helpers_1.createSettingsXml; } });
|
|
30
|
+
Object.defineProperty(exports, "createFileMapXml", { enumerable: true, get: function () { return helpers_1.createFileMapXml; } });
|
|
31
|
+
Object.defineProperty(exports, "getCommonDocumentsPath", { enumerable: true, get: function () { return helpers_1.getCommonDocumentsPath; } });
|
|
32
|
+
Object.defineProperty(exports, "findGrid3UserPaths", { enumerable: true, get: function () { return helpers_1.findGrid3UserPaths; } });
|
|
33
|
+
Object.defineProperty(exports, "findGrid3HistoryDatabases", { enumerable: true, get: function () { return helpers_1.findGrid3HistoryDatabases; } });
|
|
34
|
+
Object.defineProperty(exports, "findGrid3Users", { enumerable: true, get: function () { return helpers_1.findGrid3Users; } });
|
|
35
|
+
Object.defineProperty(exports, "findGrid3Vocabularies", { enumerable: true, get: function () { return helpers_1.findGrid3Vocabularies; } });
|
|
36
|
+
Object.defineProperty(exports, "findGrid3UserHistory", { enumerable: true, get: function () { return helpers_1.findGrid3UserHistory; } });
|
|
37
|
+
Object.defineProperty(exports, "isGrid3Installed", { enumerable: true, get: function () { return helpers_1.isGrid3Installed; } });
|
|
38
|
+
Object.defineProperty(exports, "readGrid3History", { enumerable: true, get: function () { return helpers_1.readGrid3History; } });
|
|
39
|
+
Object.defineProperty(exports, "readGrid3HistoryForUser", { enumerable: true, get: function () { return helpers_1.readGrid3HistoryForUser; } });
|
|
40
|
+
Object.defineProperty(exports, "readAllGrid3History", { enumerable: true, get: function () { return helpers_1.readAllGrid3History; } });
|
|
27
41
|
var helpers_2 = require("./gridset/helpers");
|
|
28
42
|
Object.defineProperty(exports, "getGridsetPageTokenImageMap", { enumerable: true, get: function () { return helpers_2.getPageTokenImageMap; } });
|
|
29
43
|
Object.defineProperty(exports, "getGridsetAllowedImageEntries", { enumerable: true, get: function () { return helpers_2.getAllowedImageEntries; } });
|
|
30
44
|
Object.defineProperty(exports, "openGridsetImage", { enumerable: true, get: function () { return helpers_2.openImage; } });
|
|
45
|
+
Object.defineProperty(exports, "generateGridsetGuid", { enumerable: true, get: function () { return helpers_2.generateGrid3Guid; } });
|
|
46
|
+
Object.defineProperty(exports, "createGridsetSettingsXml", { enumerable: true, get: function () { return helpers_2.createSettingsXml; } });
|
|
47
|
+
Object.defineProperty(exports, "createGridsetFileMapXml", { enumerable: true, get: function () { return helpers_2.createFileMapXml; } });
|
|
48
|
+
Object.defineProperty(exports, "getGridsetCommonDocumentsPath", { enumerable: true, get: function () { return helpers_2.getCommonDocumentsPath; } });
|
|
49
|
+
Object.defineProperty(exports, "findGridsetUserPaths", { enumerable: true, get: function () { return helpers_2.findGrid3UserPaths; } });
|
|
50
|
+
Object.defineProperty(exports, "findGridsetHistoryDatabases", { enumerable: true, get: function () { return helpers_2.findGrid3HistoryDatabases; } });
|
|
51
|
+
Object.defineProperty(exports, "findGridsetUsers", { enumerable: true, get: function () { return helpers_2.findGrid3Users; } });
|
|
52
|
+
Object.defineProperty(exports, "findGridsetVocabularies", { enumerable: true, get: function () { return helpers_2.findGrid3Vocabularies; } });
|
|
53
|
+
Object.defineProperty(exports, "findGridsetUserHistory", { enumerable: true, get: function () { return helpers_2.findGrid3UserHistory; } });
|
|
54
|
+
Object.defineProperty(exports, "isGridsetInstalled", { enumerable: true, get: function () { return helpers_2.isGrid3Installed; } });
|
|
55
|
+
Object.defineProperty(exports, "readGridsetHistory", { enumerable: true, get: function () { return helpers_2.readGrid3History; } });
|
|
56
|
+
Object.defineProperty(exports, "readGridsetHistoryForUser", { enumerable: true, get: function () { return helpers_2.readGrid3HistoryForUser; } });
|
|
57
|
+
Object.defineProperty(exports, "readAllGridsetHistory", { enumerable: true, get: function () { return helpers_2.readAllGrid3History; } });
|
|
31
58
|
var resolver_1 = require("./gridset/resolver");
|
|
32
59
|
Object.defineProperty(exports, "resolveGrid3CellImage", { enumerable: true, get: function () { return resolver_1.resolveGrid3CellImage; } });
|
|
33
60
|
// Gridset (Grid 3) wordlist helpers
|
|
@@ -36,18 +63,39 @@ Object.defineProperty(exports, "createWordlist", { enumerable: true, get: functi
|
|
|
36
63
|
Object.defineProperty(exports, "extractWordlists", { enumerable: true, get: function () { return wordlistHelpers_1.extractWordlists; } });
|
|
37
64
|
Object.defineProperty(exports, "updateWordlist", { enumerable: true, get: function () { return wordlistHelpers_1.updateWordlist; } });
|
|
38
65
|
Object.defineProperty(exports, "wordlistToXml", { enumerable: true, get: function () { return wordlistHelpers_1.wordlistToXml; } });
|
|
66
|
+
// Gridset (Grid 3) color utilities
|
|
67
|
+
var colorUtils_1 = require("./gridset/colorUtils");
|
|
68
|
+
Object.defineProperty(exports, "getNamedColor", { enumerable: true, get: function () { return colorUtils_1.getNamedColor; } });
|
|
69
|
+
Object.defineProperty(exports, "rgbaToHex", { enumerable: true, get: function () { return colorUtils_1.rgbaToHex; } });
|
|
70
|
+
Object.defineProperty(exports, "channelToHex", { enumerable: true, get: function () { return colorUtils_1.channelToHex; } });
|
|
71
|
+
Object.defineProperty(exports, "clampColorChannel", { enumerable: true, get: function () { return colorUtils_1.clampColorChannel; } });
|
|
72
|
+
Object.defineProperty(exports, "clampAlpha", { enumerable: true, get: function () { return colorUtils_1.clampAlpha; } });
|
|
73
|
+
Object.defineProperty(exports, "toHexColor", { enumerable: true, get: function () { return colorUtils_1.toHexColor; } });
|
|
74
|
+
Object.defineProperty(exports, "darkenColor", { enumerable: true, get: function () { return colorUtils_1.darkenColor; } });
|
|
75
|
+
Object.defineProperty(exports, "normalizeColor", { enumerable: true, get: function () { return colorUtils_1.normalizeColor; } });
|
|
76
|
+
Object.defineProperty(exports, "ensureAlphaChannel", { enumerable: true, get: function () { return colorUtils_1.ensureAlphaChannel; } });
|
|
39
77
|
// Gridset (Grid 3) style helpers
|
|
40
78
|
var styleHelpers_1 = require("./gridset/styleHelpers");
|
|
41
79
|
Object.defineProperty(exports, "DEFAULT_GRID3_STYLES", { enumerable: true, get: function () { return styleHelpers_1.DEFAULT_GRID3_STYLES; } });
|
|
42
80
|
Object.defineProperty(exports, "CATEGORY_STYLES", { enumerable: true, get: function () { return styleHelpers_1.CATEGORY_STYLES; } });
|
|
43
|
-
Object.defineProperty(exports, "ensureAlphaChannel", { enumerable: true, get: function () { return styleHelpers_1.ensureAlphaChannel; } });
|
|
44
81
|
Object.defineProperty(exports, "createDefaultStylesXml", { enumerable: true, get: function () { return styleHelpers_1.createDefaultStylesXml; } });
|
|
45
82
|
Object.defineProperty(exports, "createCategoryStyle", { enumerable: true, get: function () { return styleHelpers_1.createCategoryStyle; } });
|
|
46
|
-
//
|
|
83
|
+
// Re-export ensureAlphaChannel from styleHelpers for backward compatibility
|
|
84
|
+
var styleHelpers_2 = require("./gridset/styleHelpers");
|
|
85
|
+
Object.defineProperty(exports, "ensureAlphaChannelFromStyles", { enumerable: true, get: function () { return styleHelpers_2.ensureAlphaChannel; } });
|
|
86
|
+
// Snap helpers
|
|
47
87
|
var helpers_3 = require("./snap/helpers");
|
|
48
88
|
Object.defineProperty(exports, "getSnapPageTokenImageMap", { enumerable: true, get: function () { return helpers_3.getPageTokenImageMap; } });
|
|
49
89
|
Object.defineProperty(exports, "getSnapAllowedImageEntries", { enumerable: true, get: function () { return helpers_3.getAllowedImageEntries; } });
|
|
50
90
|
Object.defineProperty(exports, "openSnapImage", { enumerable: true, get: function () { return helpers_3.openImage; } });
|
|
91
|
+
Object.defineProperty(exports, "findSnapPackages", { enumerable: true, get: function () { return helpers_3.findSnapPackages; } });
|
|
92
|
+
Object.defineProperty(exports, "findSnapPackagePath", { enumerable: true, get: function () { return helpers_3.findSnapPackagePath; } });
|
|
93
|
+
Object.defineProperty(exports, "findSnapUsers", { enumerable: true, get: function () { return helpers_3.findSnapUsers; } });
|
|
94
|
+
Object.defineProperty(exports, "findSnapUserVocabularies", { enumerable: true, get: function () { return helpers_3.findSnapUserVocabularies; } });
|
|
95
|
+
Object.defineProperty(exports, "findSnapUserHistory", { enumerable: true, get: function () { return helpers_3.findSnapUserHistory; } });
|
|
96
|
+
Object.defineProperty(exports, "isSnapInstalled", { enumerable: true, get: function () { return helpers_3.isSnapInstalled; } });
|
|
97
|
+
Object.defineProperty(exports, "readSnapUsage", { enumerable: true, get: function () { return helpers_3.readSnapUsage; } });
|
|
98
|
+
Object.defineProperty(exports, "readSnapUsageForUser", { enumerable: true, get: function () { return helpers_3.readSnapUsageForUser; } });
|
|
51
99
|
// TouchChat helpers (stubs)
|
|
52
100
|
var helpers_4 = require("./touchchat/helpers");
|
|
53
101
|
Object.defineProperty(exports, "getTouchChatPageTokenImageMap", { enumerable: true, get: function () { return helpers_4.getPageTokenImageMap; } });
|
|
@@ -144,12 +144,15 @@ class ObfProcessor extends baseProcessor_1.BaseProcessor {
|
|
|
144
144
|
}
|
|
145
145
|
const obj = JSON.parse(str);
|
|
146
146
|
if (obj && typeof obj === 'object' && 'id' in obj && 'buttons' in obj) {
|
|
147
|
+
// Validate buttons is an array
|
|
148
|
+
if (!Array.isArray(obj.buttons)) {
|
|
149
|
+
throw new Error('Invalid OBF: buttons must be an array');
|
|
150
|
+
}
|
|
147
151
|
return obj;
|
|
148
152
|
}
|
|
149
153
|
}
|
|
150
154
|
catch (error) {
|
|
151
155
|
// Log parsing errors for debugging but don't throw
|
|
152
|
-
console.warn(`Failed to parse OBF JSON: ${error.message}`);
|
|
153
156
|
}
|
|
154
157
|
return null;
|
|
155
158
|
}
|
|
@@ -232,7 +235,12 @@ class ObfProcessor extends baseProcessor_1.BaseProcessor {
|
|
|
232
235
|
buttonPositions.set(id, index);
|
|
233
236
|
return id;
|
|
234
237
|
});
|
|
235
|
-
return {
|
|
238
|
+
return {
|
|
239
|
+
rows: 1,
|
|
240
|
+
columns: fallbackRow.length,
|
|
241
|
+
order: [fallbackRow],
|
|
242
|
+
buttonPositions,
|
|
243
|
+
};
|
|
236
244
|
}
|
|
237
245
|
const order = [];
|
|
238
246
|
for (let rowIndex = 0; rowIndex < totalRows; rowIndex++) {
|