@jian-ai/remote-control 0.8.3 → 0.8.4
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/bin/jian-remote.mjs +353 -11
- package/macos/computer-helper +0 -0
- package/macos/computer-helper.swift +195 -121
- package/macos/jian-pointer.png +0 -0
- package/package.json +1 -1
package/bin/jian-remote.mjs
CHANGED
|
@@ -4,15 +4,26 @@ import { createHash } from 'node:crypto';
|
|
|
4
4
|
import {
|
|
5
5
|
existsSync,
|
|
6
6
|
mkdtempSync,
|
|
7
|
+
readdirSync,
|
|
7
8
|
readFileSync,
|
|
8
9
|
realpathSync,
|
|
9
10
|
rmSync,
|
|
10
11
|
statSync,
|
|
11
12
|
writeFileSync,
|
|
12
13
|
} from 'node:fs';
|
|
13
|
-
import {
|
|
14
|
+
import {
|
|
15
|
+
chmod,
|
|
16
|
+
copyFile,
|
|
17
|
+
mkdir,
|
|
18
|
+
readdir,
|
|
19
|
+
readFile,
|
|
20
|
+
rename,
|
|
21
|
+
rm,
|
|
22
|
+
unlink,
|
|
23
|
+
writeFile,
|
|
24
|
+
} from 'node:fs/promises';
|
|
14
25
|
import { homedir, tmpdir } from 'node:os';
|
|
15
|
-
import { dirname, join, resolve } from 'node:path';
|
|
26
|
+
import { basename, dirname, join, resolve } from 'node:path';
|
|
16
27
|
import { fileURLToPath, pathToFileURL } from 'node:url';
|
|
17
28
|
|
|
18
29
|
const configDir = join(homedir(), '.config', 'jian-remote');
|
|
@@ -53,7 +64,7 @@ export function parseCliInvocation(argv = args) {
|
|
|
53
64
|
* Stamped to the release tag on npm publish and when the gateway serves this script.
|
|
54
65
|
* Compatibility with the gateway requires the same major.minor (see versionsCompatible).
|
|
55
66
|
*/
|
|
56
|
-
export const PACKAGE_VERSION = '0.8.
|
|
67
|
+
export const PACKAGE_VERSION = '0.8.4';
|
|
57
68
|
|
|
58
69
|
/** Soft stdout/stderr caps while capturing a command (chars). Gateway schema matches these. */
|
|
59
70
|
const STDOUT_CAP = 400_000;
|
|
@@ -142,12 +153,291 @@ export function macosAppBundlePaths(home = homedir()) {
|
|
|
142
153
|
appRoot,
|
|
143
154
|
contents: join(appRoot, 'Contents'),
|
|
144
155
|
macosDir: join(appRoot, 'Contents', 'MacOS'),
|
|
156
|
+
/** Homebrew / official Node often load `@rpath/libnode.*.dylib` from here. */
|
|
157
|
+
libDir: join(appRoot, 'Contents', 'lib'),
|
|
145
158
|
executable: join(appRoot, 'Contents', 'MacOS', MACOS_APP_NAME),
|
|
146
159
|
infoPlist: join(appRoot, 'Contents', 'Info.plist'),
|
|
147
160
|
bundleId: MACOS_BUNDLE_ID,
|
|
148
161
|
};
|
|
149
162
|
}
|
|
150
163
|
|
|
164
|
+
/** dyld system locations — leave these on the host; do not copy into the app. */
|
|
165
|
+
export function isMacSystemLibrary(depPath) {
|
|
166
|
+
if (typeof depPath !== 'string' || !depPath) return true;
|
|
167
|
+
if (depPath.startsWith('/usr/lib/')) return true;
|
|
168
|
+
if (depPath.startsWith('/System/')) return true;
|
|
169
|
+
if (depPath.startsWith('/Library/Apple/')) return true;
|
|
170
|
+
if (depPath.startsWith('/usr/local/lib/libSystem')) return true;
|
|
171
|
+
return false;
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
/**
|
|
175
|
+
* Parse `otool -L` lines into load-command paths (skips the header "path:" line).
|
|
176
|
+
* Example line: `\t@rpath/libnode.147.dylib (compatibility version 147.0.0, current version …)`
|
|
177
|
+
*/
|
|
178
|
+
export function parseOtoolDependencies(stdout) {
|
|
179
|
+
const deps = [];
|
|
180
|
+
for (const line of String(stdout || '').split('\n')) {
|
|
181
|
+
const trimmed = line.trim();
|
|
182
|
+
if (!trimmed || trimmed.endsWith(':')) continue;
|
|
183
|
+
const match = /^(.+?)\s+\(compatibility version\b/.exec(trimmed);
|
|
184
|
+
if (!match) continue;
|
|
185
|
+
const dep = match[1].trim();
|
|
186
|
+
if (dep) deps.push(dep);
|
|
187
|
+
}
|
|
188
|
+
return deps;
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
/**
|
|
192
|
+
* Parse LC_RPATH entries from `otool -l` (or `otool -l -v`) output.
|
|
193
|
+
* Looks for: `cmd LC_RPATH` … `path <value> (offset …)`
|
|
194
|
+
*/
|
|
195
|
+
export function parseOtoolRpaths(stdout) {
|
|
196
|
+
const rpaths = [];
|
|
197
|
+
const lines = String(stdout || '').split('\n');
|
|
198
|
+
for (let i = 0; i < lines.length; i += 1) {
|
|
199
|
+
if (!/\bLC_RPATH\b/.test(lines[i])) continue;
|
|
200
|
+
for (let j = i + 1; j < Math.min(i + 6, lines.length); j += 1) {
|
|
201
|
+
const match = /^\s*path\s+(.+?)(?:\s+\(offset\s+\d+\))?\s*$/.exec(lines[j]);
|
|
202
|
+
if (match) {
|
|
203
|
+
rpaths.push(match[1].trim());
|
|
204
|
+
break;
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
return rpaths;
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
/**
|
|
212
|
+
* Expand @executable_path / @loader_path / @rpath against the source Node layout.
|
|
213
|
+
* Absolute paths pass through. Unresolvable @rpath names return null.
|
|
214
|
+
*/
|
|
215
|
+
export function resolveMachODependency(
|
|
216
|
+
dep,
|
|
217
|
+
{ binaryPath, executablePath, rpaths = [], exists = existsSync } = {},
|
|
218
|
+
) {
|
|
219
|
+
if (typeof dep !== 'string' || !dep) return null;
|
|
220
|
+
const loaderDir = dirname(binaryPath);
|
|
221
|
+
const execDir = dirname(executablePath || binaryPath);
|
|
222
|
+
|
|
223
|
+
const expandPrefix = (value) => {
|
|
224
|
+
if (value.startsWith('@loader_path')) {
|
|
225
|
+
return join(loaderDir, value.slice('@loader_path'.length).replace(/^\//, '') || '.');
|
|
226
|
+
}
|
|
227
|
+
if (value.startsWith('@executable_path')) {
|
|
228
|
+
return join(execDir, value.slice('@executable_path'.length).replace(/^\//, '') || '.');
|
|
229
|
+
}
|
|
230
|
+
return value;
|
|
231
|
+
};
|
|
232
|
+
|
|
233
|
+
if (dep.startsWith('@rpath/')) {
|
|
234
|
+
const rest = dep.slice('@rpath/'.length);
|
|
235
|
+
for (const rpath of rpaths) {
|
|
236
|
+
const base = expandPrefix(rpath);
|
|
237
|
+
const candidate = join(base, rest);
|
|
238
|
+
if (exists(candidate)) return candidate;
|
|
239
|
+
}
|
|
240
|
+
// Common Node layouts when LC_RPATH is missing from a stub parse: bin/ + ../lib/.
|
|
241
|
+
for (const candidate of [
|
|
242
|
+
join(loaderDir, rest),
|
|
243
|
+
join(loaderDir, '..', 'lib', rest),
|
|
244
|
+
join(execDir, rest),
|
|
245
|
+
join(execDir, '..', 'lib', rest),
|
|
246
|
+
]) {
|
|
247
|
+
if (exists(candidate)) return candidate;
|
|
248
|
+
}
|
|
249
|
+
return null;
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
if (dep.startsWith('@loader_path') || dep.startsWith('@executable_path')) {
|
|
253
|
+
const candidate = expandPrefix(dep);
|
|
254
|
+
return exists(candidate) ? candidate : null;
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
if (dep.startsWith('/')) {
|
|
258
|
+
return exists(dep) ? dep : null;
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
return null;
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
const SIBLING_DYLIB_PREFIXES = [
|
|
265
|
+
'libnode.',
|
|
266
|
+
'libuv.',
|
|
267
|
+
'libbrotli',
|
|
268
|
+
'libcares.',
|
|
269
|
+
'libnghttp',
|
|
270
|
+
'libopenssl.',
|
|
271
|
+
'libssl.',
|
|
272
|
+
'libcrypto.',
|
|
273
|
+
'libicu',
|
|
274
|
+
];
|
|
275
|
+
|
|
276
|
+
/**
|
|
277
|
+
* Sibling search when otool is unavailable or incomplete — Homebrew Cellar and
|
|
278
|
+
* official tarballs keep libnode next to bin/ or under ../lib/.
|
|
279
|
+
*/
|
|
280
|
+
export function discoverSiblingNodeLibraries(nodePath, { exists = existsSync, listDir } = {}) {
|
|
281
|
+
const dir = dirname(nodePath);
|
|
282
|
+
const searchDirs = [dir, join(dir, 'lib'), join(dir, '..', 'lib')];
|
|
283
|
+
const found = [];
|
|
284
|
+
const list =
|
|
285
|
+
listDir ||
|
|
286
|
+
((path) => {
|
|
287
|
+
try {
|
|
288
|
+
return readdirSync(path);
|
|
289
|
+
} catch {
|
|
290
|
+
return [];
|
|
291
|
+
}
|
|
292
|
+
});
|
|
293
|
+
for (const searchDir of searchDirs) {
|
|
294
|
+
if (!exists(searchDir)) continue;
|
|
295
|
+
for (const name of list(searchDir)) {
|
|
296
|
+
if (!name.endsWith('.dylib')) continue;
|
|
297
|
+
if (!SIBLING_DYLIB_PREFIXES.some((prefix) => name.startsWith(prefix))) continue;
|
|
298
|
+
const full = join(searchDir, name);
|
|
299
|
+
if (exists(full)) found.push(full);
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
return found;
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
/**
|
|
306
|
+
* BFS: every non-system Mach-O dependency of `nodePath` that must live inside the .app.
|
|
307
|
+
* Returns absolute source paths (deduped, stable order).
|
|
308
|
+
*/
|
|
309
|
+
export function collectNodeRuntimeLibraries(
|
|
310
|
+
nodePath,
|
|
311
|
+
{
|
|
312
|
+
exists = existsSync,
|
|
313
|
+
readDeps = defaultReadOtoolDeps,
|
|
314
|
+
readRpaths = defaultReadOtoolRpaths,
|
|
315
|
+
listDir,
|
|
316
|
+
} = {},
|
|
317
|
+
) {
|
|
318
|
+
const realNode = (() => {
|
|
319
|
+
try {
|
|
320
|
+
return realpathSync(nodePath);
|
|
321
|
+
} catch {
|
|
322
|
+
return nodePath;
|
|
323
|
+
}
|
|
324
|
+
})();
|
|
325
|
+
|
|
326
|
+
const queue = [realNode];
|
|
327
|
+
const seenBinaries = new Set();
|
|
328
|
+
const libraries = [];
|
|
329
|
+
const seenLibs = new Set();
|
|
330
|
+
|
|
331
|
+
const enqueueLib = (source) => {
|
|
332
|
+
let real = source;
|
|
333
|
+
try {
|
|
334
|
+
real = realpathSync(source);
|
|
335
|
+
} catch {
|
|
336
|
+
// keep source
|
|
337
|
+
}
|
|
338
|
+
if (seenLibs.has(real)) return;
|
|
339
|
+
seenLibs.add(real);
|
|
340
|
+
libraries.push(real);
|
|
341
|
+
queue.push(real);
|
|
342
|
+
};
|
|
343
|
+
|
|
344
|
+
// Seed Cellar/tarball siblings first so a missing otool still walks transitive deps.
|
|
345
|
+
for (const sibling of discoverSiblingNodeLibraries(realNode, { exists, listDir })) {
|
|
346
|
+
enqueueLib(sibling);
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
while (queue.length > 0) {
|
|
350
|
+
const current = queue.shift();
|
|
351
|
+
if (!current || seenBinaries.has(current)) continue;
|
|
352
|
+
seenBinaries.add(current);
|
|
353
|
+
|
|
354
|
+
const rpaths = readRpaths(current);
|
|
355
|
+
const deps = readDeps(current);
|
|
356
|
+
for (const dep of deps) {
|
|
357
|
+
if (isMacSystemLibrary(dep)) continue;
|
|
358
|
+
// Self-id lines sometimes appear as the dylib's install name — skip when it resolves to self.
|
|
359
|
+
const resolved = resolveMachODependency(dep, {
|
|
360
|
+
binaryPath: current,
|
|
361
|
+
executablePath: realNode,
|
|
362
|
+
rpaths,
|
|
363
|
+
exists,
|
|
364
|
+
});
|
|
365
|
+
if (!resolved) continue;
|
|
366
|
+
let realResolved = resolved;
|
|
367
|
+
try {
|
|
368
|
+
realResolved = realpathSync(resolved);
|
|
369
|
+
} catch {
|
|
370
|
+
// keep
|
|
371
|
+
}
|
|
372
|
+
if (realResolved === realNode || realResolved === current) continue;
|
|
373
|
+
if (isMacSystemLibrary(realResolved)) continue;
|
|
374
|
+
enqueueLib(realResolved);
|
|
375
|
+
}
|
|
376
|
+
}
|
|
377
|
+
|
|
378
|
+
return libraries;
|
|
379
|
+
}
|
|
380
|
+
|
|
381
|
+
function defaultReadOtoolDeps(binaryPath) {
|
|
382
|
+
const result = spawnSync('otool', ['-L', binaryPath], { encoding: 'utf8' });
|
|
383
|
+
if (result.status !== 0) return [];
|
|
384
|
+
return parseOtoolDependencies(result.stdout || '');
|
|
385
|
+
}
|
|
386
|
+
|
|
387
|
+
function defaultReadOtoolRpaths(binaryPath) {
|
|
388
|
+
const result = spawnSync('otool', ['-l', binaryPath], { encoding: 'utf8' });
|
|
389
|
+
if (result.status !== 0) return [];
|
|
390
|
+
return parseOtoolRpaths(result.stdout || '');
|
|
391
|
+
}
|
|
392
|
+
|
|
393
|
+
/** Drop Gatekeeper quarantine on a path (best-effort; missing xattr is fine). */
|
|
394
|
+
export function clearMacQuarantine(targetPath) {
|
|
395
|
+
spawnSync('xattr', ['-dr', 'com.apple.quarantine', targetPath], { encoding: 'utf8' });
|
|
396
|
+
}
|
|
397
|
+
|
|
398
|
+
function runInstallNameTool(argv, run) {
|
|
399
|
+
// -add_rpath fails (status 1) when the rpath already exists — that is fine.
|
|
400
|
+
return run('install_name_tool', argv);
|
|
401
|
+
}
|
|
402
|
+
|
|
403
|
+
/**
|
|
404
|
+
* Rewrite load commands so bundled libs resolve via `@rpath/<basename>` inside Contents/lib.
|
|
405
|
+
* Best-effort: missing install_name_tool still leaves copies under Contents/lib for @rpath.
|
|
406
|
+
*/
|
|
407
|
+
export function rewriteBundledMachOLinks({
|
|
408
|
+
executablePath,
|
|
409
|
+
libDir,
|
|
410
|
+
libraryBasenames,
|
|
411
|
+
readDeps = defaultReadOtoolDeps,
|
|
412
|
+
run = (cmd, argv) => spawnSync(cmd, argv, { encoding: 'utf8' }),
|
|
413
|
+
}) {
|
|
414
|
+
const names = new Set(libraryBasenames);
|
|
415
|
+
|
|
416
|
+
runInstallNameTool(['-add_rpath', '@executable_path/../lib', executablePath], run);
|
|
417
|
+
runInstallNameTool(['-add_rpath', '@executable_path', executablePath], run);
|
|
418
|
+
|
|
419
|
+
for (const name of names) {
|
|
420
|
+
runInstallNameTool(['-id', `@rpath/${name}`, join(libDir, name)], run);
|
|
421
|
+
}
|
|
422
|
+
|
|
423
|
+
const consumers = [executablePath, ...[...names].map((name) => join(libDir, name))];
|
|
424
|
+
for (const consumer of consumers) {
|
|
425
|
+
for (const dep of readDeps(consumer)) {
|
|
426
|
+
if (isMacSystemLibrary(dep)) continue;
|
|
427
|
+
const depBase = basename(
|
|
428
|
+
dep
|
|
429
|
+
.replace(/^@rpath\//, '')
|
|
430
|
+
.replace(/^@loader_path\//, '')
|
|
431
|
+
.replace(/^@executable_path\//, ''),
|
|
432
|
+
);
|
|
433
|
+
if (!names.has(depBase)) continue;
|
|
434
|
+
const desired = `@rpath/${depBase}`;
|
|
435
|
+
if (dep === desired) continue;
|
|
436
|
+
runInstallNameTool(['-change', dep, desired, consumer], run);
|
|
437
|
+
}
|
|
438
|
+
}
|
|
439
|
+
}
|
|
440
|
+
|
|
151
441
|
export function buildMacosAppInfoPlist() {
|
|
152
442
|
return `<?xml version="1.0" encoding="UTF-8"?>
|
|
153
443
|
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
|
@@ -214,26 +504,78 @@ export function buildLaunchAgentPlist({
|
|
|
214
504
|
}
|
|
215
505
|
|
|
216
506
|
/**
|
|
217
|
-
* Copy the current Node binary
|
|
218
|
-
*
|
|
507
|
+
* Copy the current Node binary *and* its @rpath shared libs (libnode, ICU, …) into
|
|
508
|
+
* Jian Remote.app, then ad-hoc sign so Login Items / TCC attach to Jian — not system node.
|
|
509
|
+
* Homebrew / nvm / fnm / official pkg layouts resolve via Contents/lib (@executable_path/../lib).
|
|
219
510
|
*/
|
|
220
|
-
async function materializeMacosAppRuntime(
|
|
221
|
-
|
|
511
|
+
export async function materializeMacosAppRuntime({
|
|
512
|
+
sourceNode = process.execPath,
|
|
513
|
+
home = homedir(),
|
|
514
|
+
collectLibraries = collectNodeRuntimeLibraries,
|
|
515
|
+
} = {}) {
|
|
516
|
+
const paths = macosAppBundlePaths(home);
|
|
222
517
|
await mkdir(paths.macosDir, { recursive: true, mode: 0o755 });
|
|
518
|
+
await mkdir(paths.libDir, { recursive: true, mode: 0o755 });
|
|
223
519
|
await writeFile(paths.infoPlist, buildMacosAppInfoPlist(), { mode: 0o644 });
|
|
224
|
-
|
|
520
|
+
|
|
521
|
+
let realSource = sourceNode;
|
|
522
|
+
try {
|
|
523
|
+
realSource = realpathSync(sourceNode);
|
|
524
|
+
} catch {
|
|
525
|
+
// keep sourceNode
|
|
526
|
+
}
|
|
527
|
+
|
|
225
528
|
const temp = `${paths.executable}.${process.pid}.tmp`;
|
|
226
|
-
await copyFile(
|
|
529
|
+
await copyFile(realSource, temp);
|
|
227
530
|
await chmod(temp, 0o755);
|
|
228
531
|
await rename(temp, paths.executable);
|
|
229
|
-
|
|
532
|
+
|
|
533
|
+
// Drop stale dylibs from a previous Node major so @rpath cannot pick an old libnode.
|
|
534
|
+
try {
|
|
535
|
+
for (const name of await readdir(paths.libDir)) {
|
|
536
|
+
if (!name.endsWith('.dylib')) continue;
|
|
537
|
+
await rm(join(paths.libDir, name), { force: true });
|
|
538
|
+
}
|
|
539
|
+
} catch {
|
|
540
|
+
// lib dir may be brand new
|
|
541
|
+
}
|
|
542
|
+
|
|
543
|
+
const librarySources = collectLibraries(realSource);
|
|
544
|
+
const libraryBasenames = [];
|
|
545
|
+
for (const libSource of librarySources) {
|
|
546
|
+
const name = basename(libSource);
|
|
547
|
+
if (!name.endsWith('.dylib')) continue;
|
|
548
|
+
const dest = join(paths.libDir, name);
|
|
549
|
+
await copyFile(libSource, dest);
|
|
550
|
+
await chmod(dest, 0o755);
|
|
551
|
+
libraryBasenames.push(name);
|
|
552
|
+
}
|
|
553
|
+
|
|
554
|
+
if (libraryBasenames.length > 0) {
|
|
555
|
+
rewriteBundledMachOLinks({
|
|
556
|
+
executablePath: paths.executable,
|
|
557
|
+
libDir: paths.libDir,
|
|
558
|
+
libraryBasenames,
|
|
559
|
+
});
|
|
560
|
+
}
|
|
561
|
+
|
|
562
|
+
clearMacQuarantine(paths.appRoot);
|
|
563
|
+
|
|
564
|
+
// Sign nested dylibs first, then the executable, then the bundle (ad-hoc / unsigned path).
|
|
565
|
+
for (const name of libraryBasenames) {
|
|
566
|
+
spawnSync(
|
|
567
|
+
'codesign',
|
|
568
|
+
['--force', '-s', '-', '--identifier', MACOS_BUNDLE_ID, join(paths.libDir, name)],
|
|
569
|
+
{ stdio: 'ignore' },
|
|
570
|
+
);
|
|
571
|
+
}
|
|
230
572
|
spawnSync('codesign', ['--force', '-s', '-', '--identifier', MACOS_BUNDLE_ID, paths.executable], {
|
|
231
573
|
stdio: 'ignore',
|
|
232
574
|
});
|
|
233
575
|
spawnSync('codesign', ['--force', '-s', '-', '--identifier', MACOS_BUNDLE_ID, paths.appRoot], {
|
|
234
576
|
stdio: 'ignore',
|
|
235
577
|
});
|
|
236
|
-
return paths;
|
|
578
|
+
return { ...paths, bundledLibraries: libraryBasenames };
|
|
237
579
|
}
|
|
238
580
|
|
|
239
581
|
export function parseRelease(version) {
|
package/macos/computer-helper
CHANGED
|
Binary file
|
|
@@ -94,127 +94,201 @@ private let hotspot = CGPoint(x: 12, y: 12)
|
|
|
94
94
|
|
|
95
95
|
/// Ship asset `macos/jian-pointer.png` (@3x master) as base64 — single-file helper stays
|
|
96
96
|
/// reliable when only the binary is copied into Application Support (no sidecar PNG).
|
|
97
|
-
private let jianPointerPngBase64 =
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
97
|
+
private let jianPointerPngBase64 = """
|
|
98
|
+
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
|
|
291
|
+
"""
|
|
218
292
|
|
|
219
293
|
private let jianPointerImage: NSImage? = {
|
|
220
294
|
guard let data = Data(base64Encoded: jianPointerPngBase64, options: .ignoreUnknownCharacters)
|
package/macos/jian-pointer.png
CHANGED
|
Binary file
|