@blue-soda/dsh-remote 0.4.32 → 0.5.0

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.
@@ -1,1627 +1,5 @@
1
1
  "use strict";
2
2
  (() => {
3
- var __create = Object.create;
4
- var __defProp = Object.defineProperty;
5
- var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
6
- var __getOwnPropNames = Object.getOwnPropertyNames;
7
- var __getProtoOf = Object.getPrototypeOf, __hasOwnProp = Object.prototype.hasOwnProperty;
8
- var __commonJS = (cb, mod) => function() {
9
- return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
10
- };
11
- var __copyProps = (to, from, except, desc) => {
12
- if (from && typeof from == "object" || typeof from == "function")
13
- for (let key of __getOwnPropNames(from))
14
- !__hasOwnProp.call(to, key) && key !== except && __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
- return to;
16
- };
17
- var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
18
- // If the importer is in node compatibility mode or this is not an ESM
19
- // file that has been converted to a CommonJS file using a Babel-
20
- // compatible transform (i.e. "__esModule" has not been set), then set
21
- // "default" to the CommonJS "module.exports" for node compatibility.
22
- isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: !0 }) : target,
23
- mod
24
- ));
25
-
26
- // ../../node_modules/qrcode/lib/can-promise.js
27
- var require_can_promise = __commonJS({
28
- "../../node_modules/qrcode/lib/can-promise.js"(exports, module) {
29
- module.exports = function() {
30
- return typeof Promise == "function" && Promise.prototype && Promise.prototype.then;
31
- };
32
- }
33
- });
34
-
35
- // ../../node_modules/qrcode/lib/core/utils.js
36
- var require_utils = __commonJS({
37
- "../../node_modules/qrcode/lib/core/utils.js"(exports) {
38
- var toSJISFunction, CODEWORDS_COUNT = [
39
- 0,
40
- // Not used
41
- 26,
42
- 44,
43
- 70,
44
- 100,
45
- 134,
46
- 172,
47
- 196,
48
- 242,
49
- 292,
50
- 346,
51
- 404,
52
- 466,
53
- 532,
54
- 581,
55
- 655,
56
- 733,
57
- 815,
58
- 901,
59
- 991,
60
- 1085,
61
- 1156,
62
- 1258,
63
- 1364,
64
- 1474,
65
- 1588,
66
- 1706,
67
- 1828,
68
- 1921,
69
- 2051,
70
- 2185,
71
- 2323,
72
- 2465,
73
- 2611,
74
- 2761,
75
- 2876,
76
- 3034,
77
- 3196,
78
- 3362,
79
- 3532,
80
- 3706
81
- ];
82
- exports.getSymbolSize = function(version) {
83
- if (!version) throw new Error('"version" cannot be null or undefined');
84
- if (version < 1 || version > 40) throw new Error('"version" should be in range from 1 to 40');
85
- return version * 4 + 17;
86
- };
87
- exports.getSymbolTotalCodewords = function(version) {
88
- return CODEWORDS_COUNT[version];
89
- };
90
- exports.getBCHDigit = function(data) {
91
- let digit = 0;
92
- for (; data !== 0; )
93
- digit++, data >>>= 1;
94
- return digit;
95
- };
96
- exports.setToSJISFunction = function(f) {
97
- if (typeof f != "function")
98
- throw new Error('"toSJISFunc" is not a valid function.');
99
- toSJISFunction = f;
100
- };
101
- exports.isKanjiModeEnabled = function() {
102
- return typeof toSJISFunction < "u";
103
- };
104
- exports.toSJIS = function(kanji) {
105
- return toSJISFunction(kanji);
106
- };
107
- }
108
- });
109
-
110
- // ../../node_modules/qrcode/lib/core/error-correction-level.js
111
- var require_error_correction_level = __commonJS({
112
- "../../node_modules/qrcode/lib/core/error-correction-level.js"(exports) {
113
- exports.L = { bit: 1 };
114
- exports.M = { bit: 0 };
115
- exports.Q = { bit: 3 };
116
- exports.H = { bit: 2 };
117
- function fromString(string) {
118
- if (typeof string != "string")
119
- throw new Error("Param is not a string");
120
- switch (string.toLowerCase()) {
121
- case "l":
122
- case "low":
123
- return exports.L;
124
- case "m":
125
- case "medium":
126
- return exports.M;
127
- case "q":
128
- case "quartile":
129
- return exports.Q;
130
- case "h":
131
- case "high":
132
- return exports.H;
133
- default:
134
- throw new Error("Unknown EC Level: " + string);
135
- }
136
- }
137
- exports.isValid = function(level) {
138
- return level && typeof level.bit < "u" && level.bit >= 0 && level.bit < 4;
139
- };
140
- exports.from = function(value, defaultValue) {
141
- if (exports.isValid(value))
142
- return value;
143
- try {
144
- return fromString(value);
145
- } catch {
146
- return defaultValue;
147
- }
148
- };
149
- }
150
- });
151
-
152
- // ../../node_modules/qrcode/lib/core/bit-buffer.js
153
- var require_bit_buffer = __commonJS({
154
- "../../node_modules/qrcode/lib/core/bit-buffer.js"(exports, module) {
155
- function BitBuffer() {
156
- this.buffer = [], this.length = 0;
157
- }
158
- BitBuffer.prototype = {
159
- get: function(index) {
160
- let bufIndex = Math.floor(index / 8);
161
- return (this.buffer[bufIndex] >>> 7 - index % 8 & 1) === 1;
162
- },
163
- put: function(num, length) {
164
- for (let i = 0; i < length; i++)
165
- this.putBit((num >>> length - i - 1 & 1) === 1);
166
- },
167
- getLengthInBits: function() {
168
- return this.length;
169
- },
170
- putBit: function(bit) {
171
- let bufIndex = Math.floor(this.length / 8);
172
- this.buffer.length <= bufIndex && this.buffer.push(0), bit && (this.buffer[bufIndex] |= 128 >>> this.length % 8), this.length++;
173
- }
174
- };
175
- module.exports = BitBuffer;
176
- }
177
- });
178
-
179
- // ../../node_modules/qrcode/lib/core/bit-matrix.js
180
- var require_bit_matrix = __commonJS({
181
- "../../node_modules/qrcode/lib/core/bit-matrix.js"(exports, module) {
182
- function BitMatrix(size) {
183
- if (!size || size < 1)
184
- throw new Error("BitMatrix size must be defined and greater than 0");
185
- this.size = size, this.data = new Uint8Array(size * size), this.reservedBit = new Uint8Array(size * size);
186
- }
187
- BitMatrix.prototype.set = function(row, col, value, reserved) {
188
- let index = row * this.size + col;
189
- this.data[index] = value, reserved && (this.reservedBit[index] = !0);
190
- };
191
- BitMatrix.prototype.get = function(row, col) {
192
- return this.data[row * this.size + col];
193
- };
194
- BitMatrix.prototype.xor = function(row, col, value) {
195
- this.data[row * this.size + col] ^= value;
196
- };
197
- BitMatrix.prototype.isReserved = function(row, col) {
198
- return this.reservedBit[row * this.size + col];
199
- };
200
- module.exports = BitMatrix;
201
- }
202
- });
203
-
204
- // ../../node_modules/qrcode/lib/core/alignment-pattern.js
205
- var require_alignment_pattern = __commonJS({
206
- "../../node_modules/qrcode/lib/core/alignment-pattern.js"(exports) {
207
- var getSymbolSize = require_utils().getSymbolSize;
208
- exports.getRowColCoords = function(version) {
209
- if (version === 1) return [];
210
- let posCount = Math.floor(version / 7) + 2, size = getSymbolSize(version), intervals = size === 145 ? 26 : Math.ceil((size - 13) / (2 * posCount - 2)) * 2, positions = [size - 7];
211
- for (let i = 1; i < posCount - 1; i++)
212
- positions[i] = positions[i - 1] - intervals;
213
- return positions.push(6), positions.reverse();
214
- };
215
- exports.getPositions = function(version) {
216
- let coords = [], pos = exports.getRowColCoords(version), posLength = pos.length;
217
- for (let i = 0; i < posLength; i++)
218
- for (let j = 0; j < posLength; j++)
219
- i === 0 && j === 0 || // top-left
220
- i === 0 && j === posLength - 1 || // bottom-left
221
- i === posLength - 1 && j === 0 || coords.push([pos[i], pos[j]]);
222
- return coords;
223
- };
224
- }
225
- });
226
-
227
- // ../../node_modules/qrcode/lib/core/finder-pattern.js
228
- var require_finder_pattern = __commonJS({
229
- "../../node_modules/qrcode/lib/core/finder-pattern.js"(exports) {
230
- var getSymbolSize = require_utils().getSymbolSize, FINDER_PATTERN_SIZE = 7;
231
- exports.getPositions = function(version) {
232
- let size = getSymbolSize(version);
233
- return [
234
- // top-left
235
- [0, 0],
236
- // top-right
237
- [size - FINDER_PATTERN_SIZE, 0],
238
- // bottom-left
239
- [0, size - FINDER_PATTERN_SIZE]
240
- ];
241
- };
242
- }
243
- });
244
-
245
- // ../../node_modules/qrcode/lib/core/mask-pattern.js
246
- var require_mask_pattern = __commonJS({
247
- "../../node_modules/qrcode/lib/core/mask-pattern.js"(exports) {
248
- exports.Patterns = {
249
- PATTERN000: 0,
250
- PATTERN001: 1,
251
- PATTERN010: 2,
252
- PATTERN011: 3,
253
- PATTERN100: 4,
254
- PATTERN101: 5,
255
- PATTERN110: 6,
256
- PATTERN111: 7
257
- };
258
- var PenaltyScores = {
259
- N1: 3,
260
- N2: 3,
261
- N3: 40,
262
- N4: 10
263
- };
264
- exports.isValid = function(mask) {
265
- return mask != null && mask !== "" && !isNaN(mask) && mask >= 0 && mask <= 7;
266
- };
267
- exports.from = function(value) {
268
- return exports.isValid(value) ? parseInt(value, 10) : void 0;
269
- };
270
- exports.getPenaltyN1 = function(data) {
271
- let size = data.size, points = 0, sameCountCol = 0, sameCountRow = 0, lastCol = null, lastRow = null;
272
- for (let row = 0; row < size; row++) {
273
- sameCountCol = sameCountRow = 0, lastCol = lastRow = null;
274
- for (let col = 0; col < size; col++) {
275
- let module2 = data.get(row, col);
276
- module2 === lastCol ? sameCountCol++ : (sameCountCol >= 5 && (points += PenaltyScores.N1 + (sameCountCol - 5)), lastCol = module2, sameCountCol = 1), module2 = data.get(col, row), module2 === lastRow ? sameCountRow++ : (sameCountRow >= 5 && (points += PenaltyScores.N1 + (sameCountRow - 5)), lastRow = module2, sameCountRow = 1);
277
- }
278
- sameCountCol >= 5 && (points += PenaltyScores.N1 + (sameCountCol - 5)), sameCountRow >= 5 && (points += PenaltyScores.N1 + (sameCountRow - 5));
279
- }
280
- return points;
281
- };
282
- exports.getPenaltyN2 = function(data) {
283
- let size = data.size, points = 0;
284
- for (let row = 0; row < size - 1; row++)
285
- for (let col = 0; col < size - 1; col++) {
286
- let last = data.get(row, col) + data.get(row, col + 1) + data.get(row + 1, col) + data.get(row + 1, col + 1);
287
- (last === 4 || last === 0) && points++;
288
- }
289
- return points * PenaltyScores.N2;
290
- };
291
- exports.getPenaltyN3 = function(data) {
292
- let size = data.size, points = 0, bitsCol = 0, bitsRow = 0;
293
- for (let row = 0; row < size; row++) {
294
- bitsCol = bitsRow = 0;
295
- for (let col = 0; col < size; col++)
296
- bitsCol = bitsCol << 1 & 2047 | data.get(row, col), col >= 10 && (bitsCol === 1488 || bitsCol === 93) && points++, bitsRow = bitsRow << 1 & 2047 | data.get(col, row), col >= 10 && (bitsRow === 1488 || bitsRow === 93) && points++;
297
- }
298
- return points * PenaltyScores.N3;
299
- };
300
- exports.getPenaltyN4 = function(data) {
301
- let darkCount = 0, modulesCount = data.data.length;
302
- for (let i = 0; i < modulesCount; i++) darkCount += data.data[i];
303
- return Math.abs(Math.ceil(darkCount * 100 / modulesCount / 5) - 10) * PenaltyScores.N4;
304
- };
305
- function getMaskAt(maskPattern, i, j) {
306
- switch (maskPattern) {
307
- case exports.Patterns.PATTERN000:
308
- return (i + j) % 2 === 0;
309
- case exports.Patterns.PATTERN001:
310
- return i % 2 === 0;
311
- case exports.Patterns.PATTERN010:
312
- return j % 3 === 0;
313
- case exports.Patterns.PATTERN011:
314
- return (i + j) % 3 === 0;
315
- case exports.Patterns.PATTERN100:
316
- return (Math.floor(i / 2) + Math.floor(j / 3)) % 2 === 0;
317
- case exports.Patterns.PATTERN101:
318
- return i * j % 2 + i * j % 3 === 0;
319
- case exports.Patterns.PATTERN110:
320
- return (i * j % 2 + i * j % 3) % 2 === 0;
321
- case exports.Patterns.PATTERN111:
322
- return (i * j % 3 + (i + j) % 2) % 2 === 0;
323
- default:
324
- throw new Error("bad maskPattern:" + maskPattern);
325
- }
326
- }
327
- exports.applyMask = function(pattern, data) {
328
- let size = data.size;
329
- for (let col = 0; col < size; col++)
330
- for (let row = 0; row < size; row++)
331
- data.isReserved(row, col) || data.xor(row, col, getMaskAt(pattern, row, col));
332
- };
333
- exports.getBestMask = function(data, setupFormatFunc) {
334
- let numPatterns = Object.keys(exports.Patterns).length, bestPattern = 0, lowerPenalty = 1 / 0;
335
- for (let p = 0; p < numPatterns; p++) {
336
- setupFormatFunc(p), exports.applyMask(p, data);
337
- let penalty = exports.getPenaltyN1(data) + exports.getPenaltyN2(data) + exports.getPenaltyN3(data) + exports.getPenaltyN4(data);
338
- exports.applyMask(p, data), penalty < lowerPenalty && (lowerPenalty = penalty, bestPattern = p);
339
- }
340
- return bestPattern;
341
- };
342
- }
343
- });
344
-
345
- // ../../node_modules/qrcode/lib/core/error-correction-code.js
346
- var require_error_correction_code = __commonJS({
347
- "../../node_modules/qrcode/lib/core/error-correction-code.js"(exports) {
348
- var ECLevel = require_error_correction_level(), EC_BLOCKS_TABLE = [
349
- // L M Q H
350
- 1,
351
- 1,
352
- 1,
353
- 1,
354
- 1,
355
- 1,
356
- 1,
357
- 1,
358
- 1,
359
- 1,
360
- 2,
361
- 2,
362
- 1,
363
- 2,
364
- 2,
365
- 4,
366
- 1,
367
- 2,
368
- 4,
369
- 4,
370
- 2,
371
- 4,
372
- 4,
373
- 4,
374
- 2,
375
- 4,
376
- 6,
377
- 5,
378
- 2,
379
- 4,
380
- 6,
381
- 6,
382
- 2,
383
- 5,
384
- 8,
385
- 8,
386
- 4,
387
- 5,
388
- 8,
389
- 8,
390
- 4,
391
- 5,
392
- 8,
393
- 11,
394
- 4,
395
- 8,
396
- 10,
397
- 11,
398
- 4,
399
- 9,
400
- 12,
401
- 16,
402
- 4,
403
- 9,
404
- 16,
405
- 16,
406
- 6,
407
- 10,
408
- 12,
409
- 18,
410
- 6,
411
- 10,
412
- 17,
413
- 16,
414
- 6,
415
- 11,
416
- 16,
417
- 19,
418
- 6,
419
- 13,
420
- 18,
421
- 21,
422
- 7,
423
- 14,
424
- 21,
425
- 25,
426
- 8,
427
- 16,
428
- 20,
429
- 25,
430
- 8,
431
- 17,
432
- 23,
433
- 25,
434
- 9,
435
- 17,
436
- 23,
437
- 34,
438
- 9,
439
- 18,
440
- 25,
441
- 30,
442
- 10,
443
- 20,
444
- 27,
445
- 32,
446
- 12,
447
- 21,
448
- 29,
449
- 35,
450
- 12,
451
- 23,
452
- 34,
453
- 37,
454
- 12,
455
- 25,
456
- 34,
457
- 40,
458
- 13,
459
- 26,
460
- 35,
461
- 42,
462
- 14,
463
- 28,
464
- 38,
465
- 45,
466
- 15,
467
- 29,
468
- 40,
469
- 48,
470
- 16,
471
- 31,
472
- 43,
473
- 51,
474
- 17,
475
- 33,
476
- 45,
477
- 54,
478
- 18,
479
- 35,
480
- 48,
481
- 57,
482
- 19,
483
- 37,
484
- 51,
485
- 60,
486
- 19,
487
- 38,
488
- 53,
489
- 63,
490
- 20,
491
- 40,
492
- 56,
493
- 66,
494
- 21,
495
- 43,
496
- 59,
497
- 70,
498
- 22,
499
- 45,
500
- 62,
501
- 74,
502
- 24,
503
- 47,
504
- 65,
505
- 77,
506
- 25,
507
- 49,
508
- 68,
509
- 81
510
- ], EC_CODEWORDS_TABLE = [
511
- // L M Q H
512
- 7,
513
- 10,
514
- 13,
515
- 17,
516
- 10,
517
- 16,
518
- 22,
519
- 28,
520
- 15,
521
- 26,
522
- 36,
523
- 44,
524
- 20,
525
- 36,
526
- 52,
527
- 64,
528
- 26,
529
- 48,
530
- 72,
531
- 88,
532
- 36,
533
- 64,
534
- 96,
535
- 112,
536
- 40,
537
- 72,
538
- 108,
539
- 130,
540
- 48,
541
- 88,
542
- 132,
543
- 156,
544
- 60,
545
- 110,
546
- 160,
547
- 192,
548
- 72,
549
- 130,
550
- 192,
551
- 224,
552
- 80,
553
- 150,
554
- 224,
555
- 264,
556
- 96,
557
- 176,
558
- 260,
559
- 308,
560
- 104,
561
- 198,
562
- 288,
563
- 352,
564
- 120,
565
- 216,
566
- 320,
567
- 384,
568
- 132,
569
- 240,
570
- 360,
571
- 432,
572
- 144,
573
- 280,
574
- 408,
575
- 480,
576
- 168,
577
- 308,
578
- 448,
579
- 532,
580
- 180,
581
- 338,
582
- 504,
583
- 588,
584
- 196,
585
- 364,
586
- 546,
587
- 650,
588
- 224,
589
- 416,
590
- 600,
591
- 700,
592
- 224,
593
- 442,
594
- 644,
595
- 750,
596
- 252,
597
- 476,
598
- 690,
599
- 816,
600
- 270,
601
- 504,
602
- 750,
603
- 900,
604
- 300,
605
- 560,
606
- 810,
607
- 960,
608
- 312,
609
- 588,
610
- 870,
611
- 1050,
612
- 336,
613
- 644,
614
- 952,
615
- 1110,
616
- 360,
617
- 700,
618
- 1020,
619
- 1200,
620
- 390,
621
- 728,
622
- 1050,
623
- 1260,
624
- 420,
625
- 784,
626
- 1140,
627
- 1350,
628
- 450,
629
- 812,
630
- 1200,
631
- 1440,
632
- 480,
633
- 868,
634
- 1290,
635
- 1530,
636
- 510,
637
- 924,
638
- 1350,
639
- 1620,
640
- 540,
641
- 980,
642
- 1440,
643
- 1710,
644
- 570,
645
- 1036,
646
- 1530,
647
- 1800,
648
- 570,
649
- 1064,
650
- 1590,
651
- 1890,
652
- 600,
653
- 1120,
654
- 1680,
655
- 1980,
656
- 630,
657
- 1204,
658
- 1770,
659
- 2100,
660
- 660,
661
- 1260,
662
- 1860,
663
- 2220,
664
- 720,
665
- 1316,
666
- 1950,
667
- 2310,
668
- 750,
669
- 1372,
670
- 2040,
671
- 2430
672
- ];
673
- exports.getBlocksCount = function(version, errorCorrectionLevel) {
674
- switch (errorCorrectionLevel) {
675
- case ECLevel.L:
676
- return EC_BLOCKS_TABLE[(version - 1) * 4 + 0];
677
- case ECLevel.M:
678
- return EC_BLOCKS_TABLE[(version - 1) * 4 + 1];
679
- case ECLevel.Q:
680
- return EC_BLOCKS_TABLE[(version - 1) * 4 + 2];
681
- case ECLevel.H:
682
- return EC_BLOCKS_TABLE[(version - 1) * 4 + 3];
683
- default:
684
- return;
685
- }
686
- };
687
- exports.getTotalCodewordsCount = function(version, errorCorrectionLevel) {
688
- switch (errorCorrectionLevel) {
689
- case ECLevel.L:
690
- return EC_CODEWORDS_TABLE[(version - 1) * 4 + 0];
691
- case ECLevel.M:
692
- return EC_CODEWORDS_TABLE[(version - 1) * 4 + 1];
693
- case ECLevel.Q:
694
- return EC_CODEWORDS_TABLE[(version - 1) * 4 + 2];
695
- case ECLevel.H:
696
- return EC_CODEWORDS_TABLE[(version - 1) * 4 + 3];
697
- default:
698
- return;
699
- }
700
- };
701
- }
702
- });
703
-
704
- // ../../node_modules/qrcode/lib/core/galois-field.js
705
- var require_galois_field = __commonJS({
706
- "../../node_modules/qrcode/lib/core/galois-field.js"(exports) {
707
- var EXP_TABLE = new Uint8Array(512), LOG_TABLE = new Uint8Array(256);
708
- (function() {
709
- let x = 1;
710
- for (let i = 0; i < 255; i++)
711
- EXP_TABLE[i] = x, LOG_TABLE[x] = i, x <<= 1, x & 256 && (x ^= 285);
712
- for (let i = 255; i < 512; i++)
713
- EXP_TABLE[i] = EXP_TABLE[i - 255];
714
- })();
715
- exports.log = function(n) {
716
- if (n < 1) throw new Error("log(" + n + ")");
717
- return LOG_TABLE[n];
718
- };
719
- exports.exp = function(n) {
720
- return EXP_TABLE[n];
721
- };
722
- exports.mul = function(x, y) {
723
- return x === 0 || y === 0 ? 0 : EXP_TABLE[LOG_TABLE[x] + LOG_TABLE[y]];
724
- };
725
- }
726
- });
727
-
728
- // ../../node_modules/qrcode/lib/core/polynomial.js
729
- var require_polynomial = __commonJS({
730
- "../../node_modules/qrcode/lib/core/polynomial.js"(exports) {
731
- var GF = require_galois_field();
732
- exports.mul = function(p1, p2) {
733
- let coeff = new Uint8Array(p1.length + p2.length - 1);
734
- for (let i = 0; i < p1.length; i++)
735
- for (let j = 0; j < p2.length; j++)
736
- coeff[i + j] ^= GF.mul(p1[i], p2[j]);
737
- return coeff;
738
- };
739
- exports.mod = function(divident, divisor) {
740
- let result = new Uint8Array(divident);
741
- for (; result.length - divisor.length >= 0; ) {
742
- let coeff = result[0];
743
- for (let i = 0; i < divisor.length; i++)
744
- result[i] ^= GF.mul(divisor[i], coeff);
745
- let offset = 0;
746
- for (; offset < result.length && result[offset] === 0; ) offset++;
747
- result = result.slice(offset);
748
- }
749
- return result;
750
- };
751
- exports.generateECPolynomial = function(degree) {
752
- let poly = new Uint8Array([1]);
753
- for (let i = 0; i < degree; i++)
754
- poly = exports.mul(poly, new Uint8Array([1, GF.exp(i)]));
755
- return poly;
756
- };
757
- }
758
- });
759
-
760
- // ../../node_modules/qrcode/lib/core/reed-solomon-encoder.js
761
- var require_reed_solomon_encoder = __commonJS({
762
- "../../node_modules/qrcode/lib/core/reed-solomon-encoder.js"(exports, module) {
763
- var Polynomial = require_polynomial();
764
- function ReedSolomonEncoder(degree) {
765
- this.genPoly = void 0, this.degree = degree, this.degree && this.initialize(this.degree);
766
- }
767
- ReedSolomonEncoder.prototype.initialize = function(degree) {
768
- this.degree = degree, this.genPoly = Polynomial.generateECPolynomial(this.degree);
769
- };
770
- ReedSolomonEncoder.prototype.encode = function(data) {
771
- if (!this.genPoly)
772
- throw new Error("Encoder not initialized");
773
- let paddedData = new Uint8Array(data.length + this.degree);
774
- paddedData.set(data);
775
- let remainder = Polynomial.mod(paddedData, this.genPoly), start = this.degree - remainder.length;
776
- if (start > 0) {
777
- let buff = new Uint8Array(this.degree);
778
- return buff.set(remainder, start), buff;
779
- }
780
- return remainder;
781
- };
782
- module.exports = ReedSolomonEncoder;
783
- }
784
- });
785
-
786
- // ../../node_modules/qrcode/lib/core/version-check.js
787
- var require_version_check = __commonJS({
788
- "../../node_modules/qrcode/lib/core/version-check.js"(exports) {
789
- exports.isValid = function(version) {
790
- return !isNaN(version) && version >= 1 && version <= 40;
791
- };
792
- }
793
- });
794
-
795
- // ../../node_modules/qrcode/lib/core/regex.js
796
- var require_regex = __commonJS({
797
- "../../node_modules/qrcode/lib/core/regex.js"(exports) {
798
- var numeric = "[0-9]+", alphanumeric = "[A-Z $%*+\\-./:]+", kanji = "(?:[u3000-u303F]|[u3040-u309F]|[u30A0-u30FF]|[uFF00-uFFEF]|[u4E00-u9FAF]|[u2605-u2606]|[u2190-u2195]|u203B|[u2010u2015u2018u2019u2025u2026u201Cu201Du2225u2260]|[u0391-u0451]|[u00A7u00A8u00B1u00B4u00D7u00F7])+";
799
- kanji = kanji.replace(/u/g, "\\u");
800
- var byte = "(?:(?![A-Z0-9 $%*+\\-./:]|" + kanji + `)(?:.|[\r
801
- ]))+`;
802
- exports.KANJI = new RegExp(kanji, "g");
803
- exports.BYTE_KANJI = new RegExp("[^A-Z0-9 $%*+\\-./:]+", "g");
804
- exports.BYTE = new RegExp(byte, "g");
805
- exports.NUMERIC = new RegExp(numeric, "g");
806
- exports.ALPHANUMERIC = new RegExp(alphanumeric, "g");
807
- var TEST_KANJI = new RegExp("^" + kanji + "$"), TEST_NUMERIC = new RegExp("^" + numeric + "$"), TEST_ALPHANUMERIC = new RegExp("^[A-Z0-9 $%*+\\-./:]+$");
808
- exports.testKanji = function(str) {
809
- return TEST_KANJI.test(str);
810
- };
811
- exports.testNumeric = function(str) {
812
- return TEST_NUMERIC.test(str);
813
- };
814
- exports.testAlphanumeric = function(str) {
815
- return TEST_ALPHANUMERIC.test(str);
816
- };
817
- }
818
- });
819
-
820
- // ../../node_modules/qrcode/lib/core/mode.js
821
- var require_mode = __commonJS({
822
- "../../node_modules/qrcode/lib/core/mode.js"(exports) {
823
- var VersionCheck = require_version_check(), Regex = require_regex();
824
- exports.NUMERIC = {
825
- id: "Numeric",
826
- bit: 1,
827
- ccBits: [10, 12, 14]
828
- };
829
- exports.ALPHANUMERIC = {
830
- id: "Alphanumeric",
831
- bit: 2,
832
- ccBits: [9, 11, 13]
833
- };
834
- exports.BYTE = {
835
- id: "Byte",
836
- bit: 4,
837
- ccBits: [8, 16, 16]
838
- };
839
- exports.KANJI = {
840
- id: "Kanji",
841
- bit: 8,
842
- ccBits: [8, 10, 12]
843
- };
844
- exports.MIXED = {
845
- bit: -1
846
- };
847
- exports.getCharCountIndicator = function(mode, version) {
848
- if (!mode.ccBits) throw new Error("Invalid mode: " + mode);
849
- if (!VersionCheck.isValid(version))
850
- throw new Error("Invalid version: " + version);
851
- return version >= 1 && version < 10 ? mode.ccBits[0] : version < 27 ? mode.ccBits[1] : mode.ccBits[2];
852
- };
853
- exports.getBestModeForData = function(dataStr) {
854
- return Regex.testNumeric(dataStr) ? exports.NUMERIC : Regex.testAlphanumeric(dataStr) ? exports.ALPHANUMERIC : Regex.testKanji(dataStr) ? exports.KANJI : exports.BYTE;
855
- };
856
- exports.toString = function(mode) {
857
- if (mode && mode.id) return mode.id;
858
- throw new Error("Invalid mode");
859
- };
860
- exports.isValid = function(mode) {
861
- return mode && mode.bit && mode.ccBits;
862
- };
863
- function fromString(string) {
864
- if (typeof string != "string")
865
- throw new Error("Param is not a string");
866
- switch (string.toLowerCase()) {
867
- case "numeric":
868
- return exports.NUMERIC;
869
- case "alphanumeric":
870
- return exports.ALPHANUMERIC;
871
- case "kanji":
872
- return exports.KANJI;
873
- case "byte":
874
- return exports.BYTE;
875
- default:
876
- throw new Error("Unknown mode: " + string);
877
- }
878
- }
879
- exports.from = function(value, defaultValue) {
880
- if (exports.isValid(value))
881
- return value;
882
- try {
883
- return fromString(value);
884
- } catch {
885
- return defaultValue;
886
- }
887
- };
888
- }
889
- });
890
-
891
- // ../../node_modules/qrcode/lib/core/version.js
892
- var require_version = __commonJS({
893
- "../../node_modules/qrcode/lib/core/version.js"(exports) {
894
- var Utils = require_utils(), ECCode = require_error_correction_code(), ECLevel = require_error_correction_level(), Mode = require_mode(), VersionCheck = require_version_check(), G18 = 7973, G18_BCH = Utils.getBCHDigit(G18);
895
- function getBestVersionForDataLength(mode, length, errorCorrectionLevel) {
896
- for (let currentVersion = 1; currentVersion <= 40; currentVersion++)
897
- if (length <= exports.getCapacity(currentVersion, errorCorrectionLevel, mode))
898
- return currentVersion;
899
- }
900
- function getReservedBitsCount(mode, version) {
901
- return Mode.getCharCountIndicator(mode, version) + 4;
902
- }
903
- function getTotalBitsFromDataArray(segments, version) {
904
- let totalBits = 0;
905
- return segments.forEach(function(data) {
906
- let reservedBits = getReservedBitsCount(data.mode, version);
907
- totalBits += reservedBits + data.getBitsLength();
908
- }), totalBits;
909
- }
910
- function getBestVersionForMixedData(segments, errorCorrectionLevel) {
911
- for (let currentVersion = 1; currentVersion <= 40; currentVersion++)
912
- if (getTotalBitsFromDataArray(segments, currentVersion) <= exports.getCapacity(currentVersion, errorCorrectionLevel, Mode.MIXED))
913
- return currentVersion;
914
- }
915
- exports.from = function(value, defaultValue) {
916
- return VersionCheck.isValid(value) ? parseInt(value, 10) : defaultValue;
917
- };
918
- exports.getCapacity = function(version, errorCorrectionLevel, mode) {
919
- if (!VersionCheck.isValid(version))
920
- throw new Error("Invalid QR Code version");
921
- typeof mode > "u" && (mode = Mode.BYTE);
922
- let totalCodewords = Utils.getSymbolTotalCodewords(version), ecTotalCodewords = ECCode.getTotalCodewordsCount(version, errorCorrectionLevel), dataTotalCodewordsBits = (totalCodewords - ecTotalCodewords) * 8;
923
- if (mode === Mode.MIXED) return dataTotalCodewordsBits;
924
- let usableBits = dataTotalCodewordsBits - getReservedBitsCount(mode, version);
925
- switch (mode) {
926
- case Mode.NUMERIC:
927
- return Math.floor(usableBits / 10 * 3);
928
- case Mode.ALPHANUMERIC:
929
- return Math.floor(usableBits / 11 * 2);
930
- case Mode.KANJI:
931
- return Math.floor(usableBits / 13);
932
- case Mode.BYTE:
933
- default:
934
- return Math.floor(usableBits / 8);
935
- }
936
- };
937
- exports.getBestVersionForData = function(data, errorCorrectionLevel) {
938
- let seg, ecl = ECLevel.from(errorCorrectionLevel, ECLevel.M);
939
- if (Array.isArray(data)) {
940
- if (data.length > 1)
941
- return getBestVersionForMixedData(data, ecl);
942
- if (data.length === 0)
943
- return 1;
944
- seg = data[0];
945
- } else
946
- seg = data;
947
- return getBestVersionForDataLength(seg.mode, seg.getLength(), ecl);
948
- };
949
- exports.getEncodedBits = function(version) {
950
- if (!VersionCheck.isValid(version) || version < 7)
951
- throw new Error("Invalid QR Code version");
952
- let d = version << 12;
953
- for (; Utils.getBCHDigit(d) - G18_BCH >= 0; )
954
- d ^= G18 << Utils.getBCHDigit(d) - G18_BCH;
955
- return version << 12 | d;
956
- };
957
- }
958
- });
959
-
960
- // ../../node_modules/qrcode/lib/core/format-info.js
961
- var require_format_info = __commonJS({
962
- "../../node_modules/qrcode/lib/core/format-info.js"(exports) {
963
- var Utils = require_utils(), G15 = 1335, G15_MASK = 21522, G15_BCH = Utils.getBCHDigit(G15);
964
- exports.getEncodedBits = function(errorCorrectionLevel, mask) {
965
- let data = errorCorrectionLevel.bit << 3 | mask, d = data << 10;
966
- for (; Utils.getBCHDigit(d) - G15_BCH >= 0; )
967
- d ^= G15 << Utils.getBCHDigit(d) - G15_BCH;
968
- return (data << 10 | d) ^ G15_MASK;
969
- };
970
- }
971
- });
972
-
973
- // ../../node_modules/qrcode/lib/core/numeric-data.js
974
- var require_numeric_data = __commonJS({
975
- "../../node_modules/qrcode/lib/core/numeric-data.js"(exports, module) {
976
- var Mode = require_mode();
977
- function NumericData(data) {
978
- this.mode = Mode.NUMERIC, this.data = data.toString();
979
- }
980
- NumericData.getBitsLength = function(length) {
981
- return 10 * Math.floor(length / 3) + (length % 3 ? length % 3 * 3 + 1 : 0);
982
- };
983
- NumericData.prototype.getLength = function() {
984
- return this.data.length;
985
- };
986
- NumericData.prototype.getBitsLength = function() {
987
- return NumericData.getBitsLength(this.data.length);
988
- };
989
- NumericData.prototype.write = function(bitBuffer) {
990
- let i, group, value;
991
- for (i = 0; i + 3 <= this.data.length; i += 3)
992
- group = this.data.substr(i, 3), value = parseInt(group, 10), bitBuffer.put(value, 10);
993
- let remainingNum = this.data.length - i;
994
- remainingNum > 0 && (group = this.data.substr(i), value = parseInt(group, 10), bitBuffer.put(value, remainingNum * 3 + 1));
995
- };
996
- module.exports = NumericData;
997
- }
998
- });
999
-
1000
- // ../../node_modules/qrcode/lib/core/alphanumeric-data.js
1001
- var require_alphanumeric_data = __commonJS({
1002
- "../../node_modules/qrcode/lib/core/alphanumeric-data.js"(exports, module) {
1003
- var Mode = require_mode(), ALPHA_NUM_CHARS = [
1004
- "0",
1005
- "1",
1006
- "2",
1007
- "3",
1008
- "4",
1009
- "5",
1010
- "6",
1011
- "7",
1012
- "8",
1013
- "9",
1014
- "A",
1015
- "B",
1016
- "C",
1017
- "D",
1018
- "E",
1019
- "F",
1020
- "G",
1021
- "H",
1022
- "I",
1023
- "J",
1024
- "K",
1025
- "L",
1026
- "M",
1027
- "N",
1028
- "O",
1029
- "P",
1030
- "Q",
1031
- "R",
1032
- "S",
1033
- "T",
1034
- "U",
1035
- "V",
1036
- "W",
1037
- "X",
1038
- "Y",
1039
- "Z",
1040
- " ",
1041
- "$",
1042
- "%",
1043
- "*",
1044
- "+",
1045
- "-",
1046
- ".",
1047
- "/",
1048
- ":"
1049
- ];
1050
- function AlphanumericData(data) {
1051
- this.mode = Mode.ALPHANUMERIC, this.data = data;
1052
- }
1053
- AlphanumericData.getBitsLength = function(length) {
1054
- return 11 * Math.floor(length / 2) + 6 * (length % 2);
1055
- };
1056
- AlphanumericData.prototype.getLength = function() {
1057
- return this.data.length;
1058
- };
1059
- AlphanumericData.prototype.getBitsLength = function() {
1060
- return AlphanumericData.getBitsLength(this.data.length);
1061
- };
1062
- AlphanumericData.prototype.write = function(bitBuffer) {
1063
- let i;
1064
- for (i = 0; i + 2 <= this.data.length; i += 2) {
1065
- let value = ALPHA_NUM_CHARS.indexOf(this.data[i]) * 45;
1066
- value += ALPHA_NUM_CHARS.indexOf(this.data[i + 1]), bitBuffer.put(value, 11);
1067
- }
1068
- this.data.length % 2 && bitBuffer.put(ALPHA_NUM_CHARS.indexOf(this.data[i]), 6);
1069
- };
1070
- module.exports = AlphanumericData;
1071
- }
1072
- });
1073
-
1074
- // ../../node_modules/qrcode/lib/core/byte-data.js
1075
- var require_byte_data = __commonJS({
1076
- "../../node_modules/qrcode/lib/core/byte-data.js"(exports, module) {
1077
- var Mode = require_mode();
1078
- function ByteData(data) {
1079
- this.mode = Mode.BYTE, typeof data == "string" ? this.data = new TextEncoder().encode(data) : this.data = new Uint8Array(data);
1080
- }
1081
- ByteData.getBitsLength = function(length) {
1082
- return length * 8;
1083
- };
1084
- ByteData.prototype.getLength = function() {
1085
- return this.data.length;
1086
- };
1087
- ByteData.prototype.getBitsLength = function() {
1088
- return ByteData.getBitsLength(this.data.length);
1089
- };
1090
- ByteData.prototype.write = function(bitBuffer) {
1091
- for (let i = 0, l = this.data.length; i < l; i++)
1092
- bitBuffer.put(this.data[i], 8);
1093
- };
1094
- module.exports = ByteData;
1095
- }
1096
- });
1097
-
1098
- // ../../node_modules/qrcode/lib/core/kanji-data.js
1099
- var require_kanji_data = __commonJS({
1100
- "../../node_modules/qrcode/lib/core/kanji-data.js"(exports, module) {
1101
- var Mode = require_mode(), Utils = require_utils();
1102
- function KanjiData(data) {
1103
- this.mode = Mode.KANJI, this.data = data;
1104
- }
1105
- KanjiData.getBitsLength = function(length) {
1106
- return length * 13;
1107
- };
1108
- KanjiData.prototype.getLength = function() {
1109
- return this.data.length;
1110
- };
1111
- KanjiData.prototype.getBitsLength = function() {
1112
- return KanjiData.getBitsLength(this.data.length);
1113
- };
1114
- KanjiData.prototype.write = function(bitBuffer) {
1115
- let i;
1116
- for (i = 0; i < this.data.length; i++) {
1117
- let value = Utils.toSJIS(this.data[i]);
1118
- if (value >= 33088 && value <= 40956)
1119
- value -= 33088;
1120
- else if (value >= 57408 && value <= 60351)
1121
- value -= 49472;
1122
- else
1123
- throw new Error(
1124
- "Invalid SJIS character: " + this.data[i] + `
1125
- Make sure your charset is UTF-8`
1126
- );
1127
- value = (value >>> 8 & 255) * 192 + (value & 255), bitBuffer.put(value, 13);
1128
- }
1129
- };
1130
- module.exports = KanjiData;
1131
- }
1132
- });
1133
-
1134
- // ../../node_modules/dijkstrajs/dijkstra.js
1135
- var require_dijkstra = __commonJS({
1136
- "../../node_modules/dijkstrajs/dijkstra.js"(exports, module) {
1137
- "use strict";
1138
- var dijkstra = {
1139
- single_source_shortest_paths: function(graph, s, d) {
1140
- var predecessors = {}, costs = {};
1141
- costs[s] = 0;
1142
- var open = dijkstra.PriorityQueue.make();
1143
- open.push(s, 0);
1144
- for (var closest, u, v, cost_of_s_to_u, adjacent_nodes, cost_of_e, cost_of_s_to_u_plus_cost_of_e, cost_of_s_to_v, first_visit; !open.empty(); ) {
1145
- closest = open.pop(), u = closest.value, cost_of_s_to_u = closest.cost, adjacent_nodes = graph[u] || {};
1146
- for (v in adjacent_nodes)
1147
- adjacent_nodes.hasOwnProperty(v) && (cost_of_e = adjacent_nodes[v], cost_of_s_to_u_plus_cost_of_e = cost_of_s_to_u + cost_of_e, cost_of_s_to_v = costs[v], first_visit = typeof costs[v] > "u", (first_visit || cost_of_s_to_v > cost_of_s_to_u_plus_cost_of_e) && (costs[v] = cost_of_s_to_u_plus_cost_of_e, open.push(v, cost_of_s_to_u_plus_cost_of_e), predecessors[v] = u));
1148
- }
1149
- if (typeof d < "u" && typeof costs[d] > "u") {
1150
- var msg = ["Could not find a path from ", s, " to ", d, "."].join("");
1151
- throw new Error(msg);
1152
- }
1153
- return predecessors;
1154
- },
1155
- extract_shortest_path_from_predecessor_list: function(predecessors, d) {
1156
- for (var nodes = [], u = d, predecessor; u; )
1157
- nodes.push(u), predecessor = predecessors[u], u = predecessors[u];
1158
- return nodes.reverse(), nodes;
1159
- },
1160
- find_path: function(graph, s, d) {
1161
- var predecessors = dijkstra.single_source_shortest_paths(graph, s, d);
1162
- return dijkstra.extract_shortest_path_from_predecessor_list(
1163
- predecessors,
1164
- d
1165
- );
1166
- },
1167
- /**
1168
- * A very naive priority queue implementation.
1169
- */
1170
- PriorityQueue: {
1171
- make: function(opts) {
1172
- var T = dijkstra.PriorityQueue, t = {}, key;
1173
- opts = opts || {};
1174
- for (key in T)
1175
- T.hasOwnProperty(key) && (t[key] = T[key]);
1176
- return t.queue = [], t.sorter = opts.sorter || T.default_sorter, t;
1177
- },
1178
- default_sorter: function(a, b) {
1179
- return a.cost - b.cost;
1180
- },
1181
- /**
1182
- * Add a new item to the queue and ensure the highest priority element
1183
- * is at the front of the queue.
1184
- */
1185
- push: function(value, cost) {
1186
- var item = { value, cost };
1187
- this.queue.push(item), this.queue.sort(this.sorter);
1188
- },
1189
- /**
1190
- * Return the highest priority element in the queue.
1191
- */
1192
- pop: function() {
1193
- return this.queue.shift();
1194
- },
1195
- empty: function() {
1196
- return this.queue.length === 0;
1197
- }
1198
- }
1199
- };
1200
- typeof module < "u" && (module.exports = dijkstra);
1201
- }
1202
- });
1203
-
1204
- // ../../node_modules/qrcode/lib/core/segments.js
1205
- var require_segments = __commonJS({
1206
- "../../node_modules/qrcode/lib/core/segments.js"(exports) {
1207
- var Mode = require_mode(), NumericData = require_numeric_data(), AlphanumericData = require_alphanumeric_data(), ByteData = require_byte_data(), KanjiData = require_kanji_data(), Regex = require_regex(), Utils = require_utils(), dijkstra = require_dijkstra();
1208
- function getStringByteLength(str) {
1209
- return unescape(encodeURIComponent(str)).length;
1210
- }
1211
- function getSegments(regex, mode, str) {
1212
- let segments = [], result;
1213
- for (; (result = regex.exec(str)) !== null; )
1214
- segments.push({
1215
- data: result[0],
1216
- index: result.index,
1217
- mode,
1218
- length: result[0].length
1219
- });
1220
- return segments;
1221
- }
1222
- function getSegmentsFromString(dataStr) {
1223
- let numSegs = getSegments(Regex.NUMERIC, Mode.NUMERIC, dataStr), alphaNumSegs = getSegments(Regex.ALPHANUMERIC, Mode.ALPHANUMERIC, dataStr), byteSegs, kanjiSegs;
1224
- return Utils.isKanjiModeEnabled() ? (byteSegs = getSegments(Regex.BYTE, Mode.BYTE, dataStr), kanjiSegs = getSegments(Regex.KANJI, Mode.KANJI, dataStr)) : (byteSegs = getSegments(Regex.BYTE_KANJI, Mode.BYTE, dataStr), kanjiSegs = []), numSegs.concat(alphaNumSegs, byteSegs, kanjiSegs).sort(function(s1, s2) {
1225
- return s1.index - s2.index;
1226
- }).map(function(obj) {
1227
- return {
1228
- data: obj.data,
1229
- mode: obj.mode,
1230
- length: obj.length
1231
- };
1232
- });
1233
- }
1234
- function getSegmentBitsLength(length, mode) {
1235
- switch (mode) {
1236
- case Mode.NUMERIC:
1237
- return NumericData.getBitsLength(length);
1238
- case Mode.ALPHANUMERIC:
1239
- return AlphanumericData.getBitsLength(length);
1240
- case Mode.KANJI:
1241
- return KanjiData.getBitsLength(length);
1242
- case Mode.BYTE:
1243
- return ByteData.getBitsLength(length);
1244
- }
1245
- }
1246
- function mergeSegments(segs) {
1247
- return segs.reduce(function(acc, curr) {
1248
- let prevSeg = acc.length - 1 >= 0 ? acc[acc.length - 1] : null;
1249
- return prevSeg && prevSeg.mode === curr.mode ? (acc[acc.length - 1].data += curr.data, acc) : (acc.push(curr), acc);
1250
- }, []);
1251
- }
1252
- function buildNodes(segs) {
1253
- let nodes = [];
1254
- for (let i = 0; i < segs.length; i++) {
1255
- let seg = segs[i];
1256
- switch (seg.mode) {
1257
- case Mode.NUMERIC:
1258
- nodes.push([
1259
- seg,
1260
- { data: seg.data, mode: Mode.ALPHANUMERIC, length: seg.length },
1261
- { data: seg.data, mode: Mode.BYTE, length: seg.length }
1262
- ]);
1263
- break;
1264
- case Mode.ALPHANUMERIC:
1265
- nodes.push([
1266
- seg,
1267
- { data: seg.data, mode: Mode.BYTE, length: seg.length }
1268
- ]);
1269
- break;
1270
- case Mode.KANJI:
1271
- nodes.push([
1272
- seg,
1273
- { data: seg.data, mode: Mode.BYTE, length: getStringByteLength(seg.data) }
1274
- ]);
1275
- break;
1276
- case Mode.BYTE:
1277
- nodes.push([
1278
- { data: seg.data, mode: Mode.BYTE, length: getStringByteLength(seg.data) }
1279
- ]);
1280
- }
1281
- }
1282
- return nodes;
1283
- }
1284
- function buildGraph(nodes, version) {
1285
- let table = {}, graph = { start: {} }, prevNodeIds = ["start"];
1286
- for (let i = 0; i < nodes.length; i++) {
1287
- let nodeGroup = nodes[i], currentNodeIds = [];
1288
- for (let j = 0; j < nodeGroup.length; j++) {
1289
- let node = nodeGroup[j], key = "" + i + j;
1290
- currentNodeIds.push(key), table[key] = { node, lastCount: 0 }, graph[key] = {};
1291
- for (let n = 0; n < prevNodeIds.length; n++) {
1292
- let prevNodeId = prevNodeIds[n];
1293
- table[prevNodeId] && table[prevNodeId].node.mode === node.mode ? (graph[prevNodeId][key] = getSegmentBitsLength(table[prevNodeId].lastCount + node.length, node.mode) - getSegmentBitsLength(table[prevNodeId].lastCount, node.mode), table[prevNodeId].lastCount += node.length) : (table[prevNodeId] && (table[prevNodeId].lastCount = node.length), graph[prevNodeId][key] = getSegmentBitsLength(node.length, node.mode) + 4 + Mode.getCharCountIndicator(node.mode, version));
1294
- }
1295
- }
1296
- prevNodeIds = currentNodeIds;
1297
- }
1298
- for (let n = 0; n < prevNodeIds.length; n++)
1299
- graph[prevNodeIds[n]].end = 0;
1300
- return { map: graph, table };
1301
- }
1302
- function buildSingleSegment(data, modesHint) {
1303
- let mode, bestMode = Mode.getBestModeForData(data);
1304
- if (mode = Mode.from(modesHint, bestMode), mode !== Mode.BYTE && mode.bit < bestMode.bit)
1305
- throw new Error('"' + data + '" cannot be encoded with mode ' + Mode.toString(mode) + `.
1306
- Suggested mode is: ` + Mode.toString(bestMode));
1307
- switch (mode === Mode.KANJI && !Utils.isKanjiModeEnabled() && (mode = Mode.BYTE), mode) {
1308
- case Mode.NUMERIC:
1309
- return new NumericData(data);
1310
- case Mode.ALPHANUMERIC:
1311
- return new AlphanumericData(data);
1312
- case Mode.KANJI:
1313
- return new KanjiData(data);
1314
- case Mode.BYTE:
1315
- return new ByteData(data);
1316
- }
1317
- }
1318
- exports.fromArray = function(array) {
1319
- return array.reduce(function(acc, seg) {
1320
- return typeof seg == "string" ? acc.push(buildSingleSegment(seg, null)) : seg.data && acc.push(buildSingleSegment(seg.data, seg.mode)), acc;
1321
- }, []);
1322
- };
1323
- exports.fromString = function(data, version) {
1324
- let segs = getSegmentsFromString(data, Utils.isKanjiModeEnabled()), nodes = buildNodes(segs), graph = buildGraph(nodes, version), path = dijkstra.find_path(graph.map, "start", "end"), optimizedSegs = [];
1325
- for (let i = 1; i < path.length - 1; i++)
1326
- optimizedSegs.push(graph.table[path[i]].node);
1327
- return exports.fromArray(mergeSegments(optimizedSegs));
1328
- };
1329
- exports.rawSplit = function(data) {
1330
- return exports.fromArray(
1331
- getSegmentsFromString(data, Utils.isKanjiModeEnabled())
1332
- );
1333
- };
1334
- }
1335
- });
1336
-
1337
- // ../../node_modules/qrcode/lib/core/qrcode.js
1338
- var require_qrcode = __commonJS({
1339
- "../../node_modules/qrcode/lib/core/qrcode.js"(exports) {
1340
- var Utils = require_utils(), ECLevel = require_error_correction_level(), BitBuffer = require_bit_buffer(), BitMatrix = require_bit_matrix(), AlignmentPattern = require_alignment_pattern(), FinderPattern = require_finder_pattern(), MaskPattern = require_mask_pattern(), ECCode = require_error_correction_code(), ReedSolomonEncoder = require_reed_solomon_encoder(), Version = require_version(), FormatInfo = require_format_info(), Mode = require_mode(), Segments = require_segments();
1341
- function setupFinderPattern(matrix, version) {
1342
- let size = matrix.size, pos = FinderPattern.getPositions(version);
1343
- for (let i = 0; i < pos.length; i++) {
1344
- let row = pos[i][0], col = pos[i][1];
1345
- for (let r = -1; r <= 7; r++)
1346
- if (!(row + r <= -1 || size <= row + r))
1347
- for (let c = -1; c <= 7; c++)
1348
- col + c <= -1 || size <= col + c || (r >= 0 && r <= 6 && (c === 0 || c === 6) || c >= 0 && c <= 6 && (r === 0 || r === 6) || r >= 2 && r <= 4 && c >= 2 && c <= 4 ? matrix.set(row + r, col + c, !0, !0) : matrix.set(row + r, col + c, !1, !0));
1349
- }
1350
- }
1351
- function setupTimingPattern(matrix) {
1352
- let size = matrix.size;
1353
- for (let r = 8; r < size - 8; r++) {
1354
- let value = r % 2 === 0;
1355
- matrix.set(r, 6, value, !0), matrix.set(6, r, value, !0);
1356
- }
1357
- }
1358
- function setupAlignmentPattern(matrix, version) {
1359
- let pos = AlignmentPattern.getPositions(version);
1360
- for (let i = 0; i < pos.length; i++) {
1361
- let row = pos[i][0], col = pos[i][1];
1362
- for (let r = -2; r <= 2; r++)
1363
- for (let c = -2; c <= 2; c++)
1364
- r === -2 || r === 2 || c === -2 || c === 2 || r === 0 && c === 0 ? matrix.set(row + r, col + c, !0, !0) : matrix.set(row + r, col + c, !1, !0);
1365
- }
1366
- }
1367
- function setupVersionInfo(matrix, version) {
1368
- let size = matrix.size, bits = Version.getEncodedBits(version), row, col, mod;
1369
- for (let i = 0; i < 18; i++)
1370
- row = Math.floor(i / 3), col = i % 3 + size - 8 - 3, mod = (bits >> i & 1) === 1, matrix.set(row, col, mod, !0), matrix.set(col, row, mod, !0);
1371
- }
1372
- function setupFormatInfo(matrix, errorCorrectionLevel, maskPattern) {
1373
- let size = matrix.size, bits = FormatInfo.getEncodedBits(errorCorrectionLevel, maskPattern), i, mod;
1374
- for (i = 0; i < 15; i++)
1375
- mod = (bits >> i & 1) === 1, i < 6 ? matrix.set(i, 8, mod, !0) : i < 8 ? matrix.set(i + 1, 8, mod, !0) : matrix.set(size - 15 + i, 8, mod, !0), i < 8 ? matrix.set(8, size - i - 1, mod, !0) : i < 9 ? matrix.set(8, 15 - i - 1 + 1, mod, !0) : matrix.set(8, 15 - i - 1, mod, !0);
1376
- matrix.set(size - 8, 8, 1, !0);
1377
- }
1378
- function setupData(matrix, data) {
1379
- let size = matrix.size, inc = -1, row = size - 1, bitIndex = 7, byteIndex = 0;
1380
- for (let col = size - 1; col > 0; col -= 2)
1381
- for (col === 6 && col--; ; ) {
1382
- for (let c = 0; c < 2; c++)
1383
- if (!matrix.isReserved(row, col - c)) {
1384
- let dark = !1;
1385
- byteIndex < data.length && (dark = (data[byteIndex] >>> bitIndex & 1) === 1), matrix.set(row, col - c, dark), bitIndex--, bitIndex === -1 && (byteIndex++, bitIndex = 7);
1386
- }
1387
- if (row += inc, row < 0 || size <= row) {
1388
- row -= inc, inc = -inc;
1389
- break;
1390
- }
1391
- }
1392
- }
1393
- function createData(version, errorCorrectionLevel, segments) {
1394
- let buffer = new BitBuffer();
1395
- segments.forEach(function(data) {
1396
- buffer.put(data.mode.bit, 4), buffer.put(data.getLength(), Mode.getCharCountIndicator(data.mode, version)), data.write(buffer);
1397
- });
1398
- let totalCodewords = Utils.getSymbolTotalCodewords(version), ecTotalCodewords = ECCode.getTotalCodewordsCount(version, errorCorrectionLevel), dataTotalCodewordsBits = (totalCodewords - ecTotalCodewords) * 8;
1399
- for (buffer.getLengthInBits() + 4 <= dataTotalCodewordsBits && buffer.put(0, 4); buffer.getLengthInBits() % 8 !== 0; )
1400
- buffer.putBit(0);
1401
- let remainingByte = (dataTotalCodewordsBits - buffer.getLengthInBits()) / 8;
1402
- for (let i = 0; i < remainingByte; i++)
1403
- buffer.put(i % 2 ? 17 : 236, 8);
1404
- return createCodewords(buffer, version, errorCorrectionLevel);
1405
- }
1406
- function createCodewords(bitBuffer, version, errorCorrectionLevel) {
1407
- let totalCodewords = Utils.getSymbolTotalCodewords(version), ecTotalCodewords = ECCode.getTotalCodewordsCount(version, errorCorrectionLevel), dataTotalCodewords = totalCodewords - ecTotalCodewords, ecTotalBlocks = ECCode.getBlocksCount(version, errorCorrectionLevel), blocksInGroup2 = totalCodewords % ecTotalBlocks, blocksInGroup1 = ecTotalBlocks - blocksInGroup2, totalCodewordsInGroup1 = Math.floor(totalCodewords / ecTotalBlocks), dataCodewordsInGroup1 = Math.floor(dataTotalCodewords / ecTotalBlocks), dataCodewordsInGroup2 = dataCodewordsInGroup1 + 1, ecCount = totalCodewordsInGroup1 - dataCodewordsInGroup1, rs = new ReedSolomonEncoder(ecCount), offset = 0, dcData = new Array(ecTotalBlocks), ecData = new Array(ecTotalBlocks), maxDataSize = 0, buffer = new Uint8Array(bitBuffer.buffer);
1408
- for (let b = 0; b < ecTotalBlocks; b++) {
1409
- let dataSize = b < blocksInGroup1 ? dataCodewordsInGroup1 : dataCodewordsInGroup2;
1410
- dcData[b] = buffer.slice(offset, offset + dataSize), ecData[b] = rs.encode(dcData[b]), offset += dataSize, maxDataSize = Math.max(maxDataSize, dataSize);
1411
- }
1412
- let data = new Uint8Array(totalCodewords), index = 0, i, r;
1413
- for (i = 0; i < maxDataSize; i++)
1414
- for (r = 0; r < ecTotalBlocks; r++)
1415
- i < dcData[r].length && (data[index++] = dcData[r][i]);
1416
- for (i = 0; i < ecCount; i++)
1417
- for (r = 0; r < ecTotalBlocks; r++)
1418
- data[index++] = ecData[r][i];
1419
- return data;
1420
- }
1421
- function createSymbol(data, version, errorCorrectionLevel, maskPattern) {
1422
- let segments;
1423
- if (Array.isArray(data))
1424
- segments = Segments.fromArray(data);
1425
- else if (typeof data == "string") {
1426
- let estimatedVersion = version;
1427
- if (!estimatedVersion) {
1428
- let rawSegments = Segments.rawSplit(data);
1429
- estimatedVersion = Version.getBestVersionForData(rawSegments, errorCorrectionLevel);
1430
- }
1431
- segments = Segments.fromString(data, estimatedVersion || 40);
1432
- } else
1433
- throw new Error("Invalid data");
1434
- let bestVersion = Version.getBestVersionForData(segments, errorCorrectionLevel);
1435
- if (!bestVersion)
1436
- throw new Error("The amount of data is too big to be stored in a QR Code");
1437
- if (!version)
1438
- version = bestVersion;
1439
- else if (version < bestVersion)
1440
- throw new Error(
1441
- `
1442
- The chosen QR Code version cannot contain this amount of data.
1443
- Minimum version required to store current data is: ` + bestVersion + `.
1444
- `
1445
- );
1446
- let dataBits = createData(version, errorCorrectionLevel, segments), moduleCount = Utils.getSymbolSize(version), modules = new BitMatrix(moduleCount);
1447
- return setupFinderPattern(modules, version), setupTimingPattern(modules), setupAlignmentPattern(modules, version), setupFormatInfo(modules, errorCorrectionLevel, 0), version >= 7 && setupVersionInfo(modules, version), setupData(modules, dataBits), isNaN(maskPattern) && (maskPattern = MaskPattern.getBestMask(
1448
- modules,
1449
- setupFormatInfo.bind(null, modules, errorCorrectionLevel)
1450
- )), MaskPattern.applyMask(maskPattern, modules), setupFormatInfo(modules, errorCorrectionLevel, maskPattern), {
1451
- modules,
1452
- version,
1453
- errorCorrectionLevel,
1454
- maskPattern,
1455
- segments
1456
- };
1457
- }
1458
- exports.create = function(data, options) {
1459
- if (typeof data > "u" || data === "")
1460
- throw new Error("No input text");
1461
- let errorCorrectionLevel = ECLevel.M, version, mask;
1462
- return typeof options < "u" && (errorCorrectionLevel = ECLevel.from(options.errorCorrectionLevel, ECLevel.M), version = Version.from(options.version), mask = MaskPattern.from(options.maskPattern), options.toSJISFunc && Utils.setToSJISFunction(options.toSJISFunc)), createSymbol(data, version, errorCorrectionLevel, mask);
1463
- };
1464
- }
1465
- });
1466
-
1467
- // ../../node_modules/qrcode/lib/renderer/utils.js
1468
- var require_utils2 = __commonJS({
1469
- "../../node_modules/qrcode/lib/renderer/utils.js"(exports) {
1470
- function hex2rgba(hex) {
1471
- if (typeof hex == "number" && (hex = hex.toString()), typeof hex != "string")
1472
- throw new Error("Color should be defined as hex string");
1473
- let hexCode = hex.slice().replace("#", "").split("");
1474
- if (hexCode.length < 3 || hexCode.length === 5 || hexCode.length > 8)
1475
- throw new Error("Invalid hex color: " + hex);
1476
- (hexCode.length === 3 || hexCode.length === 4) && (hexCode = Array.prototype.concat.apply([], hexCode.map(function(c) {
1477
- return [c, c];
1478
- }))), hexCode.length === 6 && hexCode.push("F", "F");
1479
- let hexValue = parseInt(hexCode.join(""), 16);
1480
- return {
1481
- r: hexValue >> 24 & 255,
1482
- g: hexValue >> 16 & 255,
1483
- b: hexValue >> 8 & 255,
1484
- a: hexValue & 255,
1485
- hex: "#" + hexCode.slice(0, 6).join("")
1486
- };
1487
- }
1488
- exports.getOptions = function(options) {
1489
- options || (options = {}), options.color || (options.color = {});
1490
- let margin = typeof options.margin > "u" || options.margin === null || options.margin < 0 ? 4 : options.margin, width = options.width && options.width >= 21 ? options.width : void 0, scale = options.scale || 4;
1491
- return {
1492
- width,
1493
- scale: width ? 4 : scale,
1494
- margin,
1495
- color: {
1496
- dark: hex2rgba(options.color.dark || "#000000ff"),
1497
- light: hex2rgba(options.color.light || "#ffffffff")
1498
- },
1499
- type: options.type,
1500
- rendererOpts: options.rendererOpts || {}
1501
- };
1502
- };
1503
- exports.getScale = function(qrSize, opts) {
1504
- return opts.width && opts.width >= qrSize + opts.margin * 2 ? opts.width / (qrSize + opts.margin * 2) : opts.scale;
1505
- };
1506
- exports.getImageWidth = function(qrSize, opts) {
1507
- let scale = exports.getScale(qrSize, opts);
1508
- return Math.floor((qrSize + opts.margin * 2) * scale);
1509
- };
1510
- exports.qrToImageData = function(imgData, qr, opts) {
1511
- let size = qr.modules.size, data = qr.modules.data, scale = exports.getScale(size, opts), symbolSize = Math.floor((size + opts.margin * 2) * scale), scaledMargin = opts.margin * scale, palette = [opts.color.light, opts.color.dark];
1512
- for (let i = 0; i < symbolSize; i++)
1513
- for (let j = 0; j < symbolSize; j++) {
1514
- let posDst = (i * symbolSize + j) * 4, pxColor = opts.color.light;
1515
- if (i >= scaledMargin && j >= scaledMargin && i < symbolSize - scaledMargin && j < symbolSize - scaledMargin) {
1516
- let iSrc = Math.floor((i - scaledMargin) / scale), jSrc = Math.floor((j - scaledMargin) / scale);
1517
- pxColor = palette[data[iSrc * size + jSrc] ? 1 : 0];
1518
- }
1519
- imgData[posDst++] = pxColor.r, imgData[posDst++] = pxColor.g, imgData[posDst++] = pxColor.b, imgData[posDst] = pxColor.a;
1520
- }
1521
- };
1522
- }
1523
- });
1524
-
1525
- // ../../node_modules/qrcode/lib/renderer/canvas.js
1526
- var require_canvas = __commonJS({
1527
- "../../node_modules/qrcode/lib/renderer/canvas.js"(exports) {
1528
- var Utils = require_utils2();
1529
- function clearCanvas(ctx, canvas, size) {
1530
- ctx.clearRect(0, 0, canvas.width, canvas.height), canvas.style || (canvas.style = {}), canvas.height = size, canvas.width = size, canvas.style.height = size + "px", canvas.style.width = size + "px";
1531
- }
1532
- function getCanvasElement() {
1533
- try {
1534
- return document.createElement("canvas");
1535
- } catch {
1536
- throw new Error("You need to specify a canvas element");
1537
- }
1538
- }
1539
- exports.render = function(qrData, canvas, options) {
1540
- let opts = options, canvasEl = canvas;
1541
- typeof opts > "u" && (!canvas || !canvas.getContext) && (opts = canvas, canvas = void 0), canvas || (canvasEl = getCanvasElement()), opts = Utils.getOptions(opts);
1542
- let size = Utils.getImageWidth(qrData.modules.size, opts), ctx = canvasEl.getContext("2d"), image = ctx.createImageData(size, size);
1543
- return Utils.qrToImageData(image.data, qrData, opts), clearCanvas(ctx, canvasEl, size), ctx.putImageData(image, 0, 0), canvasEl;
1544
- };
1545
- exports.renderToDataURL = function(qrData, canvas, options) {
1546
- let opts = options;
1547
- typeof opts > "u" && (!canvas || !canvas.getContext) && (opts = canvas, canvas = void 0), opts || (opts = {});
1548
- let canvasEl = exports.render(qrData, canvas, opts), type = opts.type || "image/png", rendererOpts = opts.rendererOpts || {};
1549
- return canvasEl.toDataURL(type, rendererOpts.quality);
1550
- };
1551
- }
1552
- });
1553
-
1554
- // ../../node_modules/qrcode/lib/renderer/svg-tag.js
1555
- var require_svg_tag = __commonJS({
1556
- "../../node_modules/qrcode/lib/renderer/svg-tag.js"(exports) {
1557
- var Utils = require_utils2();
1558
- function getColorAttrib(color, attrib) {
1559
- let alpha = color.a / 255, str = attrib + '="' + color.hex + '"';
1560
- return alpha < 1 ? str + " " + attrib + '-opacity="' + alpha.toFixed(2).slice(1) + '"' : str;
1561
- }
1562
- function svgCmd(cmd, x, y) {
1563
- let str = cmd + x;
1564
- return typeof y < "u" && (str += " " + y), str;
1565
- }
1566
- function qrToPath(data, size, margin) {
1567
- let path = "", moveBy = 0, newRow = !1, lineLength = 0;
1568
- for (let i = 0; i < data.length; i++) {
1569
- let col = Math.floor(i % size), row = Math.floor(i / size);
1570
- !col && !newRow && (newRow = !0), data[i] ? (lineLength++, i > 0 && col > 0 && data[i - 1] || (path += newRow ? svgCmd("M", col + margin, 0.5 + row + margin) : svgCmd("m", moveBy, 0), moveBy = 0, newRow = !1), col + 1 < size && data[i + 1] || (path += svgCmd("h", lineLength), lineLength = 0)) : moveBy++;
1571
- }
1572
- return path;
1573
- }
1574
- exports.render = function(qrData, options, cb) {
1575
- let opts = Utils.getOptions(options), size = qrData.modules.size, data = qrData.modules.data, qrcodesize = size + opts.margin * 2, bg = opts.color.light.a ? "<path " + getColorAttrib(opts.color.light, "fill") + ' d="M0 0h' + qrcodesize + "v" + qrcodesize + 'H0z"/>' : "", path = "<path " + getColorAttrib(opts.color.dark, "stroke") + ' d="' + qrToPath(data, size, opts.margin) + '"/>', viewBox = 'viewBox="0 0 ' + qrcodesize + " " + qrcodesize + '"', svgTag = '<svg xmlns="http://www.w3.org/2000/svg" ' + (opts.width ? 'width="' + opts.width + '" height="' + opts.width + '" ' : "") + viewBox + ' shape-rendering="crispEdges">' + bg + path + `</svg>
1576
- `;
1577
- return typeof cb == "function" && cb(null, svgTag), svgTag;
1578
- };
1579
- }
1580
- });
1581
-
1582
- // ../../node_modules/qrcode/lib/browser.js
1583
- var require_browser = __commonJS({
1584
- "../../node_modules/qrcode/lib/browser.js"(exports) {
1585
- var canPromise = require_can_promise(), QRCode2 = require_qrcode(), CanvasRenderer = require_canvas(), SvgRenderer = require_svg_tag();
1586
- function renderCanvas(renderFunc, canvas, text, opts, cb) {
1587
- let args = [].slice.call(arguments, 1), argsNum = args.length, isLastArgCb = typeof args[argsNum - 1] == "function";
1588
- if (!isLastArgCb && !canPromise())
1589
- throw new Error("Callback required as last argument");
1590
- if (isLastArgCb) {
1591
- if (argsNum < 2)
1592
- throw new Error("Too few arguments provided");
1593
- argsNum === 2 ? (cb = text, text = canvas, canvas = opts = void 0) : argsNum === 3 && (canvas.getContext && typeof cb > "u" ? (cb = opts, opts = void 0) : (cb = opts, opts = text, text = canvas, canvas = void 0));
1594
- } else {
1595
- if (argsNum < 1)
1596
- throw new Error("Too few arguments provided");
1597
- return argsNum === 1 ? (text = canvas, canvas = opts = void 0) : argsNum === 2 && !canvas.getContext && (opts = text, text = canvas, canvas = void 0), new Promise(function(resolve, reject) {
1598
- try {
1599
- let data = QRCode2.create(text, opts);
1600
- resolve(renderFunc(data, canvas, opts));
1601
- } catch (e) {
1602
- reject(e);
1603
- }
1604
- });
1605
- }
1606
- try {
1607
- let data = QRCode2.create(text, opts);
1608
- cb(null, renderFunc(data, canvas, opts));
1609
- } catch (e) {
1610
- cb(e);
1611
- }
1612
- }
1613
- exports.create = QRCode2.create;
1614
- exports.toCanvas = renderCanvas.bind(null, CanvasRenderer.render);
1615
- exports.toDataURL = renderCanvas.bind(null, CanvasRenderer.renderToDataURL);
1616
- exports.toString = renderCanvas.bind(null, function(data, _, opts) {
1617
- return SvgRenderer.render(data, opts);
1618
- });
1619
- }
1620
- });
1621
-
1622
- // src/client.ts
1623
- var import_qrcode = __toESM(require_browser(), 1);
1624
-
1625
3
  // src/remote-file-content-provider.ts
1626
4
  function shouldUseRemoteFileViewer(status) {
1627
5
  return status.mode === "remote" && status.remoteFeatures?.fileViewer === !0;
@@ -1754,12 +132,7 @@ Minimum version required to store current data is: ` + bestVersion + `.
1754
132
  var DEFAULT_REMOTE_SERVER_URL = "https://sakakibara.ink:8443";
1755
133
 
1756
134
  // src/client.ts
1757
- var clientModuleId = "@blue-soda/dsh-remote", pendingWorkspaceSelectionKey = "dsh-remote:pending-workspace-selection", deepSeekWorkspaceIcon = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEAAAABACAMAAACdt4HsAAAACVBMVEUAAADy8vXx8fUsA3vyAAAAAXRSTlMAQObYZgAAAOxJREFUWMPtlsEOwyAMQxP+/6OnTZMGxHGcot3wDYgfhkJbs6urprzveGtu9d1NgEdto8w93GuA7zPS2RFg7ynsCOAokbtAmLr2YaeKgJ6fxpT8jCAC0qSqPyNoO5DXdvyouj4ClFAdYaDxK09uiBDCIYBf6CxLesnR0uF2pG+JmhCqrUb0AOvjjoQaYDTCEAAgMg5grhAeAQIB+/M15IcKlnUIp4CkTCd0AKb4zVsRSJVGYEVzT0agK107IMGMEurvromEpaX4wzk/IKw378kq4LafED6Oowxfk7AP2q8W16EdM3p29Eyvrv6vF0WIBfBziKyCAAAAAElFTkSuQmCC", gptWorkspaceIcon = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEAAAABACAMAAACdt4HsAAAAclBMVEX////v7+++wMf////s7O3k5OTExcrX2Ny6vMTv8PPW19yXmqRqboJmaHd3eoaqrLPs7fGMjpfb3eKlpq1eYXOxs7pWWWd+gY5HSVdRVGVub3k+QU74+Pg4OkcvMT1ISlUoKjUiIy4fICueoKkaGyUSFB21Bp+qAAAAAXRSTlMAQObYZgAABChJREFUWMPtl916qjoQhlsdEwIECEgMYCBxx/u/xT1DrFUL1LO1DtY8LSLJvPnmB4gfH//sr7TPDfvdebf/xXZbkE/4zZ0MVhGHd9zJDsv+7F3//Z69tT5wljAu3tXw+TIlzXKJlhflYmJ+5uF5WpWhb54X+C/zZCmT2wJA4dJZwus0UYjIGqWyMhVbEp4yKNRRqlv0opW5PJLJ4rFJXvP4JKDRMqturBZjkMVJFYjR6iHQDQDI4+k2k51wZbWrqwp4mR/1CVYATyko9TFGxBUqL5IvMbXSWt0T8bkGgFLqgqZBI/Uxbx5UAxLaNcCNLBpttM7wbCc1pmJOpWAsDtey68UaQMyrFgb9uxLPjqg3+nGluyKN0XUdWw0BJ0NvTFFqgzpr9J+Dh4w0Ga1qkqBNswagxdRgFPAbgHRQG5jumGWyMxrTIaRRa4AzFs0YrNMXgI4MJWnsKYFhGNMnIh/mBOPsV8CZBFjN9w8ArowxnZzDr5IcvxTaKpxJCVsoI3SWysz1UM4AqQdzlCgho1IKrK+x1mKFzisANtgEU8E7GwHDgOqxe4w9tnM166wbaA2xBMBLrTWcAGYGdCiYVUJUrMCF+7l6gklrW1RwPi8ByjuActANqhKzVWoYrFGcCFzbDgNaBrTWpncFQMcI2DfWoAiDqRCiHcYM/ZdCEKkZqfR8spj4F0CiJjv2gHL6URNoCQDaYacL6O1oFDO2eQDUFP7AKdCRdC4CRDZaNifbjA41l/uYb/SZMAFNTBGzY7sG4J2jTsJgToOzIzXF3HZqBpSOAGduXbkGEKV1OqVGqRJpRxtvwbSw5IqAiUJItwBCOT9R32FCGo3nCkAN3t0UTBRC6zDONcBeOee9pr4T+ASbnDOdc5OmtREwEEB5w8Wqgt4bOV5c7Lt9iiK8zdP/IsBbutUGX4gNwEVCqd3FUt/xYnRWt7BvPBYQjwjAGXa3ASguHVAZ/WXKlA3eZDX1wRegFsr7E2wAlB9xFbx/7MV70kFT8aqNgLL3F8nFBmA3hrn/IJHjKJOK2oj1WI4Z4FzwN/81AOhgYD6v2xbIvaZIurLC9AfvB1WLTYAoXejF1xeBL5cpBIyEbmxkZymIXwDQh1BAfOrhI1lfwtgz8tozF5T4ttf3+32AyxC6klwAgw/YVTHpoK82xYt3wLP/Bw4AAI4D7/01TLKXBj9NEz2wEuGiKpoy68S/FwCLMQAZ3gXhihaCa25vQo6RyToOz9PE6wYjJgGi1YnqZX8qMIK+TDlnargGzSv4NvFjlwXf/nfLLMrAB4O/Xl3BH0d+RIASFgDA8IYMIXgr2+cBsbDdPSwAAHjSZFmb3txETCKIxc0uWwI8rxsLJcTiVndNwyMgKljbbNN2/zcEAja2+4RgIDYN2Bu/WtAOaEodnu2dnzz/7I/Y/w/LaEcX/MdfAAAAAElFTkSuQmCC", ENABLED_QR_PROVIDERS = ["github"], QR_LOGIN_ENABLED = !1, QR_PROVIDER_LABELS = {
1758
- wechat: "wechatLogin",
1759
- github: "githubLogin",
1760
- zhihu: "zhihuLogin"
1761
- };
1762
- var defaultQrProvider = ENABLED_QR_PROVIDERS[0] ?? "wechat";
135
+ var clientModuleId = "@blue-soda/dsh-remote", pendingWorkspaceSelectionKey = "dsh-remote:pending-workspace-selection", deepSeekWorkspaceIcon = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEAAAABACAMAAACdt4HsAAAACVBMVEUAAADy8vXx8fUsA3vyAAAAAXRSTlMAQObYZgAAAOxJREFUWMPtlsEOwyAMQxP+/6OnTZMGxHGcot3wDYgfhkJbs6urprzveGtu9d1NgEdto8w93GuA7zPS2RFg7ynsCOAokbtAmLr2YaeKgJ6fxpT8jCAC0qSqPyNoO5DXdvyouj4ClFAdYaDxK09uiBDCIYBf6CxLesnR0uF2pG+JmhCqrUb0AOvjjoQaYDTCEAAgMg5grhAeAQIB+/M15IcKlnUIp4CkTCd0AKb4zVsRSJVGYEVzT0agK107IMGMEurvromEpaX4wzk/IKw378kq4LafED6Oowxfk7AP2q8W16EdM3p29Eyvrv6vF0WIBfBziKyCAAAAAElFTkSuQmCC", gptWorkspaceIcon = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEAAAABACAMAAACdt4HsAAAAclBMVEX////v7+++wMf////s7O3k5OTExcrX2Ny6vMTv8PPW19yXmqRqboJmaHd3eoaqrLPs7fGMjpfb3eKlpq1eYXOxs7pWWWd+gY5HSVdRVGVub3k+QU74+Pg4OkcvMT1ISlUoKjUiIy4fICueoKkaGyUSFB21Bp+qAAAAAXRSTlMAQObYZgAABChJREFUWMPtl916qjoQhlsdEwIECEgMYCBxx/u/xT1DrFUL1LO1DtY8LSLJvPnmB4gfH//sr7TPDfvdebf/xXZbkE/4zZ0MVhGHd9zJDsv+7F3//Z69tT5wljAu3tXw+TIlzXKJlhflYmJ+5uF5WpWhb54X+C/zZCmT2wJA4dJZwus0UYjIGqWyMhVbEp4yKNRRqlv0opW5PJLJ4rFJXvP4JKDRMqturBZjkMVJFYjR6iHQDQDI4+k2k51wZbWrqwp4mR/1CVYATyko9TFGxBUqL5IvMbXSWt0T8bkGgFLqgqZBI/Uxbx5UAxLaNcCNLBpttM7wbCc1pmJOpWAsDtey68UaQMyrFgb9uxLPjqg3+nGluyKN0XUdWw0BJ0NvTFFqgzpr9J+Dh4w0Ga1qkqBNswagxdRgFPAbgHRQG5jumGWyMxrTIaRRa4AzFs0YrNMXgI4MJWnsKYFhGNMnIh/mBOPsV8CZBFjN9w8ArowxnZzDr5IcvxTaKpxJCVsoI3SWysz1UM4AqQdzlCgho1IKrK+x1mKFzisANtgEU8E7GwHDgOqxe4w9tnM166wbaA2xBMBLrTWcAGYGdCiYVUJUrMCF+7l6gklrW1RwPi8ByjuActANqhKzVWoYrFGcCFzbDgNaBrTWpncFQMcI2DfWoAiDqRCiHcYM/ZdCEKkZqfR8spj4F0CiJjv2gHL6URNoCQDaYacL6O1oFDO2eQDUFP7AKdCRdC4CRDZaNifbjA41l/uYb/SZMAFNTBGzY7sG4J2jTsJgToOzIzXF3HZqBpSOAGduXbkGEKV1OqVGqRJpRxtvwbSw5IqAiUJItwBCOT9R32FCGo3nCkAN3t0UTBRC6zDONcBeOee9pr4T+ASbnDOdc5OmtREwEEB5w8Wqgt4bOV5c7Lt9iiK8zdP/IsBbutUGX4gNwEVCqd3FUt/xYnRWt7BvPBYQjwjAGXa3ASguHVAZ/WXKlA3eZDX1wRegFsr7E2wAlB9xFbx/7MV70kFT8aqNgLL3F8nFBmA3hrn/IJHjKJOK2oj1WI4Z4FzwN/81AOhgYD6v2xbIvaZIurLC9AfvB1WLTYAoXejF1xeBL5cpBIyEbmxkZymIXwDQh1BAfOrhI1lfwtgz8tozF5T4ttf3+32AyxC6klwAgw/YVTHpoK82xYt3wLP/Bw4AAI4D7/01TLKXBj9NEz2wEuGiKpoy68S/FwCLMQAZ3gXhihaCa25vQo6RyToOz9PE6wYjJgGi1YnqZX8qMIK+TDlnargGzSv4NvFjlwXf/nfLLMrAB4O/Xl3BH0d+RIASFgDA8IYMIXgr2+cBsbDdPSwAAHjSZFmb3txETCKIxc0uWwI8rxsLJcTiVndNwyMgKljbbNN2/zcEAja2+4RgIDYN2Bu/WtAOaEodnu2dnzz/7I/Y/w/LaEcX/MdfAAAAAElFTkSuQmCC", ENABLED_QR_PROVIDERS = ["github"], QR_LOGIN_ENABLED = !1, defaultQrProvider = ENABLED_QR_PROVIDERS[0] ?? "wechat";
1763
136
  function isEnabledQrProvider(provider) {
1764
137
  return ENABLED_QR_PROVIDERS.includes(provider);
1765
138
  }
@@ -1821,7 +194,8 @@ Minimum version required to store current data is: ` + bestVersion + `.
1821
194
  serverUrlHint: "HTTPS origin used for account authorization and encrypted relay.",
1822
195
  serverSaved: "Server address saved. Restart DSH to apply it.",
1823
196
  codexRemote: "Codex Remote",
1824
- codexRemoteHint: "Expose Codex projects through this Host. Restart DSH after changing this setting.",
197
+ codexStatusLine: "Current state: {state}",
198
+ codexControlAllow: "Allow other users to control Codex on this device",
1825
199
  codexSaved: "Codex Remote setting saved. Restart DSH to apply it.",
1826
200
  codexBinaryLabel: "Codex command or path",
1827
201
  codexBinaryMissing: 'No Codex found automatically. Install the Codex desktop app, or enter the path to a Codex CLI that supports "codex app-server".',
@@ -1829,6 +203,17 @@ Minimum version required to store current data is: ` + bestVersion + `.
1829
203
  codexBinaryAuto: "Use auto-discovery",
1830
204
  codexBinaryPlaceholder: 'Path to a Codex CLI that supports "codex app-server"',
1831
205
  codexBinaryPinned: "Set by hand. Clear the field and confirm to discover it automatically again.",
206
+ codexUnavailableAccount: "Codex cannot reach your account from this network (region not supported, or the sign-in expired). It returns as soon as the account can be refreshed.",
207
+ codexUnavailableSignIn: "Codex is not signed in on this host. Sign in with the Codex app, then restart DSH.",
208
+ codexUnavailableBinary: "The Codex CLI could not be started here. Install the Codex desktop app, or set the command or full path in the field below.",
209
+ codexUnavailableGeneric: "Codex is unavailable on this host ({code}).",
210
+ codexDisabled: "Codex is switched off on this device, so nobody can use it remotely.",
211
+ codexStarting: "Starting the Codex connection...",
212
+ codexUnavailableNoCode: "Codex is unavailable on this host.",
213
+ codexRecheck: "Re-check",
214
+ codexRemoteOff: "Codex is switched off on that device.",
215
+ codexRemoteNotProvided: "That device does not provide Codex.",
216
+ codexRemoteUnavailable: "Codex is currently unavailable on that device.",
1832
217
  authorizeFromRemote: "Sign in from the Remote entry in the sidebar, then return here to manage this device.",
1833
218
  authorizationMethod: "Authorization method",
1834
219
  accountPassword: "Account password",
@@ -1859,6 +244,9 @@ Minimum version required to store current data is: ` + bestVersion + `.
1859
244
  noRemoteHosts: "No authorized remote Host for this account.",
1860
245
  online: "Online",
1861
246
  offline: "Offline",
247
+ connectionControlDisabled: 'That device is not accepting control. Turn on "Allow control" on it.',
248
+ connectionHostOffline: "The selected Host is offline.",
249
+ hostRefusesControl: "Not accepting control",
1862
250
  thisMachineHost: "This machine as Remote Host",
1863
251
  connected: "Connected",
1864
252
  connectedAs: "Connected as {account}",
@@ -1871,10 +259,10 @@ Minimum version required to store current data is: ` + bestVersion + `.
1871
259
  reconnect: "Reconnect",
1872
260
  reconnectingAction: "Reconnecting\u2026",
1873
261
  reconnectStarted: "Reconnect requested.",
1874
- connectionAuthorizationExpired: "Authorization expired. Sign out and authorize this Host again.",
262
+ connectionAuthorizationExpired: "Authorization expired. Sign in again to authorize this device.",
1875
263
  connectionReplaced: "Another instance is using this Host identity. Stop it or use a separate DSH_HOME before reconnecting.",
1876
264
  connectionCredentialsBusy: "Credential refresh is locked. Stop other instances. After a crash, stop all instances before removing server-credentials.json.refresh-lock and authorizing again.",
1877
- connectionDeviceRevoked: "This Host was revoked on the Server. Sign out and authorize it again.",
265
+ connectionDeviceRevoked: "This device was removed on the Server. Sign in again to add it back.",
1878
266
  connectionOwnershipRequired: "The Server no longer recognizes this Host as an owned device.",
1879
267
  connectionRateLimited: "The Server is receiving too many requests. Automatic retry will continue.",
1880
268
  connectionVersionMismatch: "The Plugin and Server protocol versions are incompatible.",
@@ -1941,7 +329,8 @@ Minimum version required to store current data is: ` + bestVersion + `.
1941
329
  confirmAddWorkspace: "Add and open",
1942
330
  showAllWorkspaces: "Show all DSH workspaces",
1943
331
  showAllCodexWorkspaces: "Show all CodeX workspaces",
1944
- remoteModePrefix: "Remote mode \xB7 ",
332
+ remoteModeDsh: "Remote DSH \xB7 ",
333
+ remoteModeCodex: "Remote Codex \xB7 ",
1945
334
  remoteNetworkP2p: "P2P",
1946
335
  remoteNetworkTurn: "TURN",
1947
336
  remoteNetworkRelay: "Relay",
@@ -2020,6 +409,8 @@ Minimum version required to store current data is: ` + bestVersion + `.
2020
409
  noConnectedClients: "No devices are currently connected to this Host.",
2021
410
  unknownDevice: "Unknown device",
2022
411
  exitRemoteAccount: "Sign out",
412
+ revokeThisDevice: "Remove this device",
413
+ revokeDeviceImpact: "Removes this device from the account. Signing in again brings it back with the same device id.",
2023
414
  cancel: "Cancel",
2024
415
  signOutImpact: "Signing out disconnects this plugin and also signs DSH out of your DeepSeek account.",
2025
416
  wechatLogin: "WeChat QR",
@@ -2077,7 +468,8 @@ Minimum version required to store current data is: ` + bestVersion + `.
2077
468
  serverUrlHint: "\u7528\u4E8E\u8D26\u53F7\u6388\u6743\u548C\u52A0\u5BC6\u4E2D\u7EE7\u7684 HTTPS \u5730\u5740\u3002",
2078
469
  serverSaved: "Server \u5730\u5740\u5DF2\u4FDD\u5B58\uFF0C\u91CD\u542F DSH \u540E\u751F\u6548\u3002",
2079
470
  codexRemote: "Codex Remote",
2080
- codexRemoteHint: "\u901A\u8FC7\u8FD9\u53F0 Host \u63D0\u4F9B Codex \u9879\u76EE\uFF1B\u4FEE\u6539\u540E\u9700\u91CD\u542F DSH \u751F\u6548\u3002",
471
+ codexStatusLine: "\u5F53\u524D\u72B6\u6001\uFF1A{state}",
472
+ codexControlAllow: "\u5141\u8BB8\u5176\u4ED6\u7528\u6237\u63A7\u5236\u672C\u8BBE\u5907Codex",
2081
473
  codexSaved: "Codex Remote \u8BBE\u7F6E\u5DF2\u4FDD\u5B58\uFF0C\u91CD\u542F DSH \u540E\u751F\u6548\u3002",
2082
474
  codexBinaryLabel: "Codex \u547D\u4EE4\u6216\u8DEF\u5F84",
2083
475
  codexBinaryMissing: '\u672A\u81EA\u52A8\u53D1\u73B0 Codex\u3002\u8BF7\u5B89\u88C5 Codex \u684C\u9762\u5E94\u7528\uFF0C\u6216\u586B\u5199\u652F\u6301 "codex app-server" \u7684 Codex CLI \u8DEF\u5F84\u3002',
@@ -2085,6 +477,17 @@ Minimum version required to store current data is: ` + bestVersion + `.
2085
477
  codexBinaryAuto: "\u6062\u590D\u81EA\u52A8\u53D1\u73B0",
2086
478
  codexBinaryPlaceholder: '\u652F\u6301 "codex app-server" \u7684 Codex CLI \u8DEF\u5F84',
2087
479
  codexBinaryPinned: "\u5F53\u524D\u4E3A\u624B\u52A8\u6307\u5B9A\uFF1B\u6E05\u7A7A\u540E\u786E\u8BA4\u5373\u53EF\u6062\u590D\u81EA\u52A8\u53D1\u73B0\u3002",
480
+ codexUnavailableAccount: "Codex \u65E0\u6CD5\u4ECE\u5F53\u524D\u7F51\u7EDC\u8BBF\u95EE\u4F60\u7684\u8D26\u53F7\uFF08\u533A\u57DF\u4E0D\u53D7\u652F\u6301\uFF0C\u6216\u767B\u5F55\u5DF2\u8FC7\u671F\uFF09\u3002\u8D26\u53F7\u6062\u590D\u53EF\u8FBE\u540E Codex \u5373\u56DE\u6765\u3002",
481
+ codexUnavailableSignIn: "\u8FD9\u53F0 Host \u4E0A\u7684 Codex \u5C1A\u672A\u767B\u5F55\u3002\u8BF7\u5148\u7528 Codex \u5E94\u7528\u767B\u5F55\uFF0C\u7136\u540E\u91CD\u542F DSH\u3002",
482
+ codexUnavailableBinary: "\u8FD9\u91CC\u7684 Codex CLI \u65E0\u6CD5\u542F\u52A8\u3002\u8BF7\u5B89\u88C5 Codex \u684C\u9762\u5E94\u7528\uFF0C\u6216\u5728\u4E0B\u65B9\u586B\u5199\u53EF\u7528\u7684\u547D\u4EE4\u6216\u5B8C\u6574\u8DEF\u5F84\u3002",
483
+ codexUnavailableGeneric: "\u8FD9\u53F0 Host \u4E0A\u7684 Codex \u5F53\u524D\u4E0D\u53EF\u7528\uFF08{code}\uFF09\u3002",
484
+ codexDisabled: "\u672C\u8BBE\u5907\u7684 Codex \u5DF2\u5173\u95ED\uFF0C\u5176\u4ED6\u7528\u6237\u65E0\u6CD5\u8FDC\u7A0B\u4F7F\u7528\u3002",
485
+ codexStarting: "\u6B63\u5728\u542F\u52A8 Codex \u8FDE\u63A5\u2026",
486
+ codexUnavailableNoCode: "\u8FD9\u53F0 Host \u4E0A\u7684 Codex \u5F53\u524D\u4E0D\u53EF\u7528\u3002",
487
+ codexRecheck: "\u91CD\u65B0\u68C0\u67E5",
488
+ codexRemoteOff: "\u8BE5\u8BBE\u5907\u7684 Codex \u5DF2\u5173\u95ED\u3002",
489
+ codexRemoteNotProvided: "\u8BE5\u8BBE\u5907\u4E0D\u63D0\u4F9B Codex\u3002",
490
+ codexRemoteUnavailable: "\u8BE5\u8BBE\u5907\u7684 Codex \u5F53\u524D\u4E0D\u53EF\u7528\u3002",
2088
491
  authorizeFromRemote: "\u8BF7\u4ECE\u4FA7\u680F Remote \u5165\u53E3\u767B\u5F55\uFF0C\u767B\u5F55\u540E\u53EF\u5728\u8FD9\u91CC\u7BA1\u7406\u5F53\u524D\u8BBE\u5907\u3002",
2089
492
  authorizationMethod: "\u6388\u6743\u65B9\u5F0F",
2090
493
  accountPassword: "\u8D26\u53F7\u5BC6\u7801",
@@ -2115,6 +518,9 @@ Minimum version required to store current data is: ` + bestVersion + `.
2115
518
  noRemoteHosts: "\u6B64\u8D26\u53F7\u6CA1\u6709\u5DF2\u6388\u6743\u7684\u8FDC\u7A0B Host\u3002",
2116
519
  online: "\u5728\u7EBF",
2117
520
  offline: "\u79BB\u7EBF",
521
+ connectionControlDisabled: "\u8BE5\u8BBE\u5907\u5F53\u524D\u4E0D\u63A5\u53D7\u63A7\u5236\uFF0C\u8BF7\u5728\u5B83\u4E0A\u9762\u6253\u5F00\u300C\u5141\u8BB8\u63A7\u5236\u300D\u3002",
522
+ connectionHostOffline: "\u6240\u9009 Host \u5F53\u524D\u79BB\u7EBF\u3002",
523
+ hostRefusesControl: "\u4E0D\u63A5\u53D7\u63A7\u5236",
2118
524
  thisMachineHost: "\u5C06\u6B64\u8BBE\u5907\u4F5C\u4E3A\u8FDC\u7A0B Host",
2119
525
  connected: "\u5DF2\u8FDE\u63A5",
2120
526
  connectedAs: "\u5DF2\u4F7F\u7528 {account} \u8FDE\u63A5",
@@ -2127,10 +533,10 @@ Minimum version required to store current data is: ` + bestVersion + `.
2127
533
  reconnect: "\u624B\u52A8\u91CD\u8FDE",
2128
534
  reconnectingAction: "\u6B63\u5728\u91CD\u8FDE\u2026",
2129
535
  reconnectStarted: "\u5DF2\u53D1\u8D77\u91CD\u8FDE\u3002",
2130
- connectionAuthorizationExpired: "\u6388\u6743\u5DF2\u5931\u6548\uFF0C\u8BF7\u9000\u51FA\u6388\u6743\u540E\u91CD\u65B0\u8FDE\u63A5\u6B64 Host\u3002",
536
+ connectionAuthorizationExpired: "\u6388\u6743\u5DF2\u5931\u6548\uFF0C\u8BF7\u91CD\u65B0\u767B\u5F55\u4EE5\u91CD\u65B0\u6388\u6743\u6B64\u8BBE\u5907\u3002",
2131
537
  connectionReplaced: "\u53E6\u4E00\u5B9E\u4F8B\u6B63\u5728\u4F7F\u7528\u6B64 Host \u8EAB\u4EFD\u3002\u8BF7\u505C\u6B62\u8BE5\u5B9E\u4F8B\uFF0C\u6216\u4F7F\u7528\u72EC\u7ACB\u7684 DSH_HOME \u540E\u91CD\u65B0\u8FDE\u63A5\u3002",
2132
538
  connectionCredentialsBusy: "\u51ED\u636E\u5237\u65B0\u88AB\u9501\u5B9A\uFF0C\u8BF7\u505C\u6B62\u5176\u4ED6\u5B9E\u4F8B\u3002\u82E5\u6B64\u524D\u5F02\u5E38\u9000\u51FA\uFF0C\u8BF7\u505C\u6B62\u6240\u6709\u5B9E\u4F8B\u540E\u79FB\u9664 server-credentials.json.refresh-lock \u5E76\u91CD\u65B0\u6388\u6743\u3002",
2133
- connectionDeviceRevoked: "\u6B64 Host \u5DF2\u5728 Server \u4E0A\u88AB\u64A4\u9500\uFF0C\u8BF7\u9000\u51FA\u6388\u6743\u540E\u91CD\u65B0\u8FDE\u63A5\u3002",
539
+ connectionDeviceRevoked: "\u6B64\u8BBE\u5907\u5DF2\u5728 Server \u4E0A\u88AB\u79FB\u9664\uFF0C\u8BF7\u91CD\u65B0\u767B\u5F55\u4EE5\u91CD\u65B0\u6DFB\u52A0\u3002",
2134
540
  connectionOwnershipRequired: "Server \u5DF2\u4E0D\u518D\u5C06\u6B64 Host \u8BC6\u522B\u4E3A\u5F53\u524D\u8D26\u53F7\u7684\u8BBE\u5907\u3002",
2135
541
  connectionRateLimited: "Server \u8BF7\u6C42\u8FC7\u591A\uFF0C\u63D2\u4EF6\u5C06\u7EE7\u7EED\u81EA\u52A8\u91CD\u8BD5\u3002",
2136
542
  connectionVersionMismatch: "Plugin \u4E0E Server \u7684\u534F\u8BAE\u7248\u672C\u4E0D\u517C\u5BB9\u3002",
@@ -2197,7 +603,8 @@ Minimum version required to store current data is: ` + bestVersion + `.
2197
603
  confirmAddWorkspace: "\u786E\u8BA4\u5E76\u6253\u5F00",
2198
604
  showAllWorkspaces: "\u663E\u793A\u5168\u90E8 DSH \u5DE5\u4F5C\u533A",
2199
605
  showAllCodexWorkspaces: "\u663E\u793A\u5168\u90E8 CodeX \u5DE5\u4F5C\u533A",
2200
- remoteModePrefix: "\u8FDC\u7A0B\u6A21\u5F0F \xB7 ",
606
+ remoteModeDsh: "\u8FDC\u7A0BDSH \xB7 ",
607
+ remoteModeCodex: "\u8FDC\u7A0BCodex \xB7 ",
2201
608
  remoteNetworkP2p: "P2P",
2202
609
  remoteNetworkTurn: "TURN",
2203
610
  remoteNetworkRelay: "\u4E2D\u7EE7",
@@ -2276,6 +683,8 @@ Minimum version required to store current data is: ` + bestVersion + `.
2276
683
  noConnectedClients: "\u76EE\u524D\u6CA1\u6709\u8BBE\u5907\u8FDE\u63A5\u5230\u8FD9\u53F0\u4E3B\u673A\u3002",
2277
684
  unknownDevice: "\u672A\u77E5\u8BBE\u5907",
2278
685
  exitRemoteAccount: "\u9000\u51FA\u8D26\u53F7",
686
+ revokeThisDevice: "\u6CE8\u9500\u672C\u8BBE\u5907",
687
+ revokeDeviceImpact: "\u5C06\u4ECE\u8D26\u53F7\u4E2D\u79FB\u9664\u672C\u8BBE\u5907\uFF1B\u91CD\u65B0\u767B\u5F55\u4F1A\u4EE5\u540C\u4E00\u4E2A\u8BBE\u5907 ID \u56DE\u6765\u3002",
2279
688
  cancel: "\u53D6\u6D88",
2280
689
  signOutImpact: "\u9000\u51FA\u540E\u4F1A\u65AD\u5F00\u672C\u63D2\u4EF6\u7684\u8FDE\u63A5\uFF0C\u5E76\u4E14\u4F1A\u4E00\u5E76\u9000\u51FA DSH \u7684 DeepSeek \u8D26\u53F7\u767B\u5F55\u3002",
2281
690
  wechatLogin: "\u5FAE\u4FE1\u626B\u7801",
@@ -2292,7 +701,11 @@ Minimum version required to store current data is: ` + bestVersion + `.
2292
701
  refreshQrCode: "\u5237\u65B0\u4E8C\u7EF4\u7801",
2293
702
  codexVirtualWorkspace: "CodeX \u5DE5\u4F5C\u533A",
2294
703
  codexVirtualSessions: "Sessions"
2295
- }, defaultPreferredTransports = ["lan", "p2p", "turn", "relay"], controlRouteBackoffStepsMs = [1e3, 2e3, 5e3, 1e4, 3e4], ControlRouteUnavailableError = class extends Error {
704
+ };
705
+ function codexUnavailableKey(code) {
706
+ return code === "CODEX_ACCOUNT_UNREACHABLE" ? "codexUnavailableAccount" : code === "CODEX_AUTH_REQUIRED" ? "codexUnavailableSignIn" : code === "CODEX_BINARY_UNAVAILABLE" || code === "CODEX_START_TIMEOUT" ? "codexUnavailableBinary" : "codexUnavailableGeneric";
707
+ }
708
+ var defaultPreferredTransports = ["lan", "p2p", "turn", "relay"], controlRouteBackoffStepsMs = [1e3, 2e3, 5e3, 1e4, 3e4], ControlRouteUnavailableError = class extends Error {
2296
709
  constructor(message) {
2297
710
  super(message), this.name = "ControlRouteUnavailableError";
2298
711
  }
@@ -2397,7 +810,44 @@ Minimum version required to store current data is: ` + bestVersion + `.
2397
810
  };
2398
811
  }
2399
812
  function connectionErrorMessage(code, t) {
2400
- return t(code === "ACCOUNT_AUTH_REQUIRED" || code === "AUTH_INVALID" || code === "TOKEN_EXPIRED" ? "connectionAuthorizationExpired" : code === "CONNECTION_REPLACED" ? "connectionReplaced" : code === "SERVER_CREDENTIALS_BUSY" ? "connectionCredentialsBusy" : code === "DEVICE_REVOKED" ? "connectionDeviceRevoked" : code === "DEVICE_OWNERSHIP_REQUIRED" ? "connectionOwnershipRequired" : code === "RATE_LIMITED" ? "connectionRateLimited" : code === "UNSUPPORTED_VERSION" ? "connectionVersionMismatch" : code === "INVALID_MESSAGE" ? "connectionInvalidResponse" : code === "CONNECTION_FAILED" || code === "SERVER_NOT_CONFIGURED" ? "connectionReachability" : "connectionUnexpected");
813
+ return t(code === "ACCOUNT_AUTH_REQUIRED" || code === "AUTH_INVALID" || code === "TOKEN_EXPIRED" ? "connectionAuthorizationExpired" : code === "CONNECTION_REPLACED" ? "connectionReplaced" : code === "CONTROL_DISABLED" ? "connectionControlDisabled" : code === "HOST_OFFLINE" ? "connectionHostOffline" : code === "SERVER_CREDENTIALS_BUSY" ? "connectionCredentialsBusy" : code === "DEVICE_REVOKED" ? "connectionDeviceRevoked" : code === "DEVICE_OWNERSHIP_REQUIRED" ? "connectionOwnershipRequired" : code === "RATE_LIMITED" ? "connectionRateLimited" : code === "UNSUPPORTED_VERSION" ? "connectionVersionMismatch" : code === "INVALID_MESSAGE" ? "connectionInvalidResponse" : code === "CONNECTION_FAILED" || code === "SERVER_NOT_CONFIGURED" ? "connectionReachability" : "connectionUnexpected");
814
+ }
815
+ var localisedRemoteCodes = /* @__PURE__ */ new Set([
816
+ "ACCOUNT_AUTH_REQUIRED",
817
+ "AUTH_INVALID",
818
+ "TOKEN_EXPIRED",
819
+ "MEMBERSHIP_REQUIRED",
820
+ "CONNECTION_REPLACED",
821
+ "CONTROL_DISABLED",
822
+ "HOST_OFFLINE",
823
+ "SERVER_CREDENTIALS_BUSY",
824
+ "DEVICE_REVOKED",
825
+ "DEVICE_OWNERSHIP_REQUIRED",
826
+ "RATE_LIMITED",
827
+ "UNSUPPORTED_VERSION",
828
+ "CONNECTION_FAILED",
829
+ "SERVER_NOT_CONFIGURED",
830
+ "CODEX_DISABLED",
831
+ "CODEX_NOT_PROVIDED",
832
+ "CODEX_UNAVAILABLE"
833
+ ]);
834
+ function controlFailure(error, t) {
835
+ let code = error?.details?.remoteCode;
836
+ return Object.assign(new Error(error?.message ?? t("remoteRequestFailed")), {
837
+ ...code === void 0 ? {} : { code },
838
+ retryable: error?.details?.retryable === !0
839
+ });
840
+ }
841
+ function remoteErrorMessage(reason, t) {
842
+ let code = reason instanceof Error && "code" in reason && typeof reason.code == "string" ? reason.code : void 0;
843
+ if (code !== void 0) {
844
+ if (code === "MEMBERSHIP_REQUIRED") return t("connectionOwnershipRequired");
845
+ if (code === "CODEX_DISABLED") return t("codexRemoteOff");
846
+ if (code === "CODEX_NOT_PROVIDED") return t("codexRemoteNotProvided");
847
+ if (code === "CODEX_UNAVAILABLE") return t("codexRemoteUnavailable");
848
+ if (localisedRemoteCodes.has(code)) return connectionErrorMessage(code, t);
849
+ }
850
+ return reason instanceof Error ? reason.message : String(reason);
2401
851
  }
2402
852
  async function setDeviceControl(control, enabled, authorized) {
2403
853
  return enabled && !authorized ? await control("host.authorization.set", { enabled: !0 }) : await control("host.connection.set", { connected: enabled });
@@ -2489,7 +939,7 @@ Minimum version required to store current data is: ` + bestVersion + `.
2489
939
  }
2490
940
  }
2491
941
  function RemotePluginOptions(props) {
2492
- let { t } = props, [open, setOpen] = React.useState(props.view === "page"), [serverUrl, setServerUrl] = React.useState(""), [codexEnabled, setCodexEnabled] = React.useState(!0), [codexBinary, setCodexBinary] = React.useState("codex"), [portsBusy, setPortsBusy] = React.useState(!1), [previewPorts, setPreviewPorts] = React.useState(""), role = "host", [registrationCode, setRegistrationCode] = React.useState(""), [associations, setAssociations] = React.useState({}), [loaded, setLoaded] = React.useState(!1), [writable, setWritable] = React.useState(!1), [busy, setBusy] = React.useState(!1), [terminalEnabled, setTerminalEnabled] = React.useState(!1), [terminalBusy, setTerminalBusy] = React.useState(!1), [codexBusy, setCodexBusy] = React.useState(!1), [acpBackends, setAcpBackends] = React.useState([]), [acpAvailability, setAcpAvailability] = React.useState({}), [acpChecking, setAcpChecking] = React.useState({}), [acpCheckResults, setAcpCheckResults] = React.useState({}), [addingAcp, setAddingAcp] = React.useState(!1), [acpName, setAcpName] = React.useState(""), [acpCommand, setAcpCommand] = React.useState(""), [acpArguments, setAcpArguments] = React.useState("acp"), [reconnectBusy, setReconnectBusy] = React.useState(!1), [hostStatus, setHostStatus] = React.useState(void 0), [hostName, setHostName] = React.useState(""), [hostDeviceId, setHostDeviceId] = React.useState(""), [notice, setNotice] = React.useState(void 0), [error, setError] = React.useState(void 0), [settingsView, setSettingsView] = React.useState(void 0), persistedServerUrl = settingsView?.config.serverUrl ?? DEFAULT_REMOTE_SERVER_URL, association = associations.client ?? associations.host, serverDirty = settingsView !== void 0 && serverUrl !== persistedServerUrl, draftDirty = serverDirty, applyView = (view) => {
942
+ let { t } = props, [open, setOpen] = React.useState(props.view === "page"), [serverUrl, setServerUrl] = React.useState(""), [codexEnabled, setCodexEnabled] = React.useState(!0), [codexBinary, setCodexBinary] = React.useState("codex"), [portsBusy, setPortsBusy] = React.useState(!1), [previewPorts, setPreviewPorts] = React.useState(""), [associations, setAssociations] = React.useState({}), [loaded, setLoaded] = React.useState(!1), [writable, setWritable] = React.useState(!1), [busy, setBusy] = React.useState(!1), [terminalEnabled, setTerminalEnabled] = React.useState(!1), [terminalBusy, setTerminalBusy] = React.useState(!1), [codexBusy, setCodexBusy] = React.useState(!1), [acpBackends, setAcpBackends] = React.useState([]), [acpAvailability, setAcpAvailability] = React.useState({}), [acpChecking, setAcpChecking] = React.useState({}), [acpCheckResults, setAcpCheckResults] = React.useState({}), [addingAcp, setAddingAcp] = React.useState(!1), [acpName, setAcpName] = React.useState(""), [acpCommand, setAcpCommand] = React.useState(""), [acpArguments, setAcpArguments] = React.useState("acp"), [reconnectBusy, setReconnectBusy] = React.useState(!1), [hostStatus, setHostStatus] = React.useState(void 0), [hostName, setHostName] = React.useState(""), [hostDeviceId, setHostDeviceId] = React.useState(""), [notice, setNotice] = React.useState(void 0), [error, setError] = React.useState(void 0), [settingsView, setSettingsView] = React.useState(void 0), persistedServerUrl = settingsView?.config.serverUrl ?? DEFAULT_REMOTE_SERVER_URL, association = associations.client ?? associations.host, serverDirty = settingsView !== void 0 && serverUrl !== persistedServerUrl, draftDirty = serverDirty, applyView = (view) => {
2493
943
  setSettingsView(view), setServerUrl(view.config.serverUrl ?? DEFAULT_REMOTE_SERVER_URL), setCodexEnabled(view.config.codex?.enabled ?? !0), setCodexBinary(view.config.codex?.binary ?? "codex"), setTerminalEnabled(view.config.terminal?.enabled ?? !0), setPreviewPorts((view.config.loopback?.ports ?? []).join(", ")), setAcpBackends((view.config.acp?.backends ?? []).map((item) => ({ id: item.id, enabled: item.enabled !== !1 }))), setAcpAvailability(view.acpAvailability ?? {}), setAssociations(view.associations ?? (view.association === void 0 ? {} : { host: view.association })), setWritable(view.writable), setLoaded(!0);
2494
944
  }, load = async () => {
2495
945
  let [view, status] = await Promise.all([
@@ -2525,7 +975,7 @@ Minimum version required to store current data is: ` + bestVersion + `.
2525
975
  setBusy(!0), setError(void 0), setNotice(void 0);
2526
976
  try {
2527
977
  let view = await props.control("settings.logout");
2528
- applyView(view), setRegistrationCode(""), setNotice({ key: view.deepseekSignedOut === !0 ? "signedOutDeepseek" : "signedOut" });
978
+ applyView(view), setNotice({ key: view.deepseekSignedOut === !0 ? "signedOutDeepseek" : "signedOut" });
2529
979
  } catch (reason) {
2530
980
  setError(messageOf(reason));
2531
981
  } finally {
@@ -2633,7 +1083,7 @@ Minimum version required to store current data is: ` + bestVersion + `.
2633
1083
  setBusy(!1);
2634
1084
  }
2635
1085
  }, discard = () => {
2636
- settingsView !== void 0 && applyView(settingsView), setRegistrationCode(""), setNotice(void 0), setError(void 0);
1086
+ settingsView !== void 0 && applyView(settingsView), setNotice(void 0), setError(void 0);
2637
1087
  }, developmentSetting = React.createElement(
2638
1088
  "section",
2639
1089
  { className: "dshRemoteDevelopmentSettings" },
@@ -2678,62 +1128,25 @@ Minimum version required to store current data is: ` + bestVersion + `.
2678
1128
  ),
2679
1129
  React.createElement("small", null, t("previewPortsHint"))
2680
1130
  )
2681
- ), codexBinaryConfigured = settingsView?.config.codex?.binary ?? "codex", codexBinaryDiscovered = settingsView?.discoveredCodexBinary, codexBinaryPinned = codexBinaryConfigured !== "codex", codexBinaryEditable = codexBinaryPinned || codexBinaryDiscovered === void 0, codexSetting = React.createElement(
2682
- React.Fragment,
2683
- null,
2684
- React.createElement(
2685
- "div",
2686
- { className: "dshRemoteAuthorizationSetting" },
2687
- React.createElement(
2688
- "div",
2689
- null,
2690
- React.createElement("strong", null, t("codexRemote")),
2691
- React.createElement("p", null, t("codexRemoteHint"))
2692
- ),
2693
- React.createElement("input", {
2694
- type: "checkbox",
2695
- role: "switch",
2696
- disabled: busy || codexBusy || !writable,
2697
- "aria-label": t("codexRemote"),
2698
- checked: codexEnabled,
2699
- onChange: (event) => void setCodexRemote(event.target.checked)
2700
- })
2701
- ),
2702
- React.createElement(
2703
- "div",
2704
- { className: "dshRemoteCodexBinary" },
2705
- React.createElement("input", {
2706
- type: "text",
2707
- value: codexBinaryEditable ? codexBinary : codexBinaryDiscovered ?? "",
2708
- readOnly: !codexBinaryEditable,
2709
- disabled: busy || codexBusy || !writable,
2710
- className: codexBinaryEditable ? "" : "isDiscovered",
2711
- placeholder: codexBinaryEditable ? t("codexBinaryPlaceholder") : void 0,
2712
- "aria-label": t("codexBinaryLabel"),
2713
- onChange: (event) => setCodexBinary(event.target.value),
2714
- onKeyDown: (event) => {
2715
- event.key === "Enter" && codexBinaryEditable && setCodexBinaryPath(codexBinary);
2716
- }
2717
- }),
2718
- codexBinaryEditable ? React.createElement("button", {
2719
- type: "button",
2720
- className: "dshRemoteDiscard",
2721
- disabled: busy || codexBusy || !writable,
2722
- onClick: () => void setCodexBinaryPath(codexBinary)
2723
- }, t("codexBinaryConfirm")) : null,
2724
- codexBinaryPinned ? React.createElement("button", {
2725
- type: "button",
2726
- className: "dshRemoteDiscard",
2727
- disabled: busy || codexBusy || !writable,
2728
- onClick: () => {
2729
- setCodexBinary(""), setCodexBinaryPath("");
2730
- }
2731
- }, t("codexBinaryAuto")) : null,
2732
- // The greyed field already shows the discovered path, so the only line
2733
- // worth printing is the one that asks the user for something.
2734
- codexBinaryPinned || codexBinaryDiscovered === void 0 ? React.createElement("p", null, t(codexBinaryPinned ? "codexBinaryPinned" : "codexBinaryMissing")) : null
2735
- )
2736
- ), acpSetting = React.createElement(
1131
+ ), codexBinaryConfigured = settingsView?.config.codex?.binary ?? "codex", codexBinaryDiscovered = settingsView?.discoveredCodexBinary, codexBinaryPinned = codexBinaryConfigured !== "codex", codexBinaryEditable = codexBinaryPinned || codexBinaryDiscovered === void 0, codexDomainStatus = settingsView?.codexStatus, codexUnavailable = codexDomainStatus !== void 0 && codexDomainStatus.available === !1, codexSetting = React.createElement(CodexConnectionFields, {
1132
+ t,
1133
+ enabled: codexEnabled,
1134
+ onEnabledChange: (next) => void setCodexRemote(next),
1135
+ busy: busy || codexBusy,
1136
+ writable,
1137
+ unavailable: codexUnavailable,
1138
+ state: codexDomainStatus?.state,
1139
+ reasonCode: codexDomainStatus?.error,
1140
+ editable: codexBinaryEditable,
1141
+ pinned: codexBinaryPinned,
1142
+ discovered: codexBinaryDiscovered,
1143
+ value: codexBinary,
1144
+ onValueChange: (next) => setCodexBinary(next),
1145
+ onConfirm: () => void setCodexBinaryPath(codexBinary),
1146
+ onUseAuto: () => {
1147
+ setCodexBinary(""), setCodexBinaryPath("");
1148
+ }
1149
+ }), acpSetting = React.createElement(
2737
1150
  "details",
2738
1151
  { className: "dshRemoteAuthorizationSetting dshRemoteAcpSetting" },
2739
1152
  React.createElement(
@@ -2908,7 +1321,9 @@ Minimum version required to store current data is: ` + bestVersion + `.
2908
1321
  React.createElement("button", {
2909
1322
  type: "button",
2910
1323
  className: "dshRemoteReconnect",
2911
- disabled: reconnectBusy || hostStatus?.configured === !1,
1324
+ // A paused Host is not a broken one: there is nothing to reconnect, and the switch is the
1325
+ // only control that may turn reachability back on.
1326
+ disabled: reconnectBusy || hostStatus?.configured === !1 || hostStatus?.paused === !0,
2912
1327
  onClick: () => void reconnectHost()
2913
1328
  }, t(reconnectBusy ? "reconnectingAction" : "reconnect"))
2914
1329
  ),
@@ -2990,9 +1405,9 @@ Minimum version required to store current data is: ` + bestVersion + `.
2990
1405
  );
2991
1406
  }
2992
1407
  function RemoteWorkspaceAction(props) {
2993
- let { t } = props, [open, setOpen] = React.useState(!1), [status, setStatus] = React.useState(void 0), [devices, setDevices] = React.useState([]), [selectedHost, setSelectedHost] = React.useState(void 0), [connectingHost, setConnectingHost] = React.useState(void 0), [workspaces, setWorkspaces] = React.useState([]), [codexWorkspaces, setCodexWorkspaces] = React.useState([]), [workspaceBackend, setWorkspaceBackend] = React.useState("harness"), [codexWorkspaceId, setCodexWorkspaceId] = React.useState(void 0), [directory, setDirectory] = React.useState(void 0), [path, setPath] = React.useState(""), [addingWorkspace, setAddingWorkspace] = React.useState(!1), [showAllWorkspaces, setShowAllWorkspaces] = React.useState(!1), [showAllCodexWorkspaces, setShowAllCodexWorkspaces] = React.useState(!1), [devicesOpen, setDevicesOpen] = React.useState(!1), workspaceListId = "dsh-remote-workspace-list", codexWorkspaceHeadingId = "dsh-remote-codex-workspace-heading", codexWorkspaceListId = "dsh-remote-codex-workspace-list", [busy, setBusy] = React.useState(!1), [needsAuthorization, setNeedsAuthorization] = React.useState(!1), [authorizationResolved, setAuthorizationResolved] = React.useState(!1), [email, setEmail] = React.useState(""), [password, setPassword] = React.useState(""), [loginServerUrl, setLoginServerUrl] = React.useState(DEFAULT_REMOTE_SERVER_URL), [editingServerUrl, setEditingServerUrl] = React.useState(!1), [awaitingDeepSeek, setAwaitingDeepSeek] = React.useState(!1), [pendingAuthorizeUrl, setPendingAuthorizeUrl] = React.useState(void 0), [loginMethod, setLoginMethod] = React.useState(
1408
+ let { t } = props, [open, setOpen] = React.useState(!1), [status, setStatus] = React.useState(void 0), [devices, setDevices] = React.useState([]), [selectedHost, setSelectedHost] = React.useState(void 0), [connectingHost, setConnectingHost] = React.useState(void 0), [workspaces, setWorkspaces] = React.useState([]), [codexWorkspaces, setCodexWorkspaces] = React.useState([]), [codexNotice, setCodexNotice] = React.useState(void 0), [codexAvailable, setCodexAvailable] = React.useState(!1), codexProbeAvailable = React.useRef(!1), [codexOpen, setCodexOpen] = React.useState(!1), [workspaceBackend, setWorkspaceBackend] = React.useState("harness"), [codexWorkspaceId, setCodexWorkspaceId] = React.useState(void 0), [directory, setDirectory] = React.useState(void 0), [path, setPath] = React.useState(""), [addingWorkspace, setAddingWorkspace] = React.useState(!1), [showAllWorkspaces, setShowAllWorkspaces] = React.useState(!1), [showAllCodexWorkspaces, setShowAllCodexWorkspaces] = React.useState(!1), [devicesOpen, setDevicesOpen] = React.useState(!1), workspaceListId = "dsh-remote-workspace-list", codexWorkspaceHeadingId = "dsh-remote-codex-workspace-heading", codexWorkspaceListId = "dsh-remote-codex-workspace-list", [busy, setBusy] = React.useState(!1), [needsAuthorization, setNeedsAuthorization] = React.useState(!1), [authorizationResolved, setAuthorizationResolved] = React.useState(!1), [loginServerUrl, setLoginServerUrl] = React.useState(DEFAULT_REMOTE_SERVER_URL), [editingServerUrl, setEditingServerUrl] = React.useState(!1), [awaitingDeepSeek, setAwaitingDeepSeek] = React.useState(!1), [pendingAuthorizeUrl, setPendingAuthorizeUrl] = React.useState(void 0), [loginMethod] = React.useState(
2994
1409
  isEnabledQrProvider(props.preferredQrProvider) ? props.preferredQrProvider : defaultQrProvider
2995
- ), [loginMethodManuallySelected, setLoginMethodManuallySelected] = React.useState(!1), [qrSession, setQrSession] = React.useState(void 0), [qrImage, setQrImage] = React.useState(void 0), [qrExpired, setQrExpired] = React.useState(!1), [progress, setProgress] = React.useState(void 0), progressRun = React.useRef(0), qrFlowRun = React.useRef(0), [notice, setNotice] = React.useState(void 0), [confirmingSignOut, setConfirmingSignOut] = React.useState(!1), [error, setError] = React.useState(void 0);
1410
+ ), [qrSession, setQrSession] = React.useState(void 0), [qrExpired, setQrExpired] = React.useState(!1), [progress, setProgress] = React.useState(void 0), progressRun = React.useRef(0), qrFlowRun = React.useRef(0), [notice, setNotice] = React.useState(void 0), [confirmingSignOut, setConfirmingSignOut] = React.useState(!1), [confirmingRevoke, setConfirmingRevoke] = React.useState(!1), [error, setError] = React.useState(void 0);
2996
1411
  React.useEffect(() => {
2997
1412
  open || setDevicesOpen(!1);
2998
1413
  }, [open]), React.useEffect(() => {
@@ -3039,13 +1454,9 @@ Minimum version required to store current data is: ` + bestVersion + `.
3039
1454
  let run = ++qrFlowRun.current;
3040
1455
  setBusy(!0), setError(void 0), setQrExpired(!1);
3041
1456
  try {
3042
- let session = await props.control("client.account.qr.start", { provider }), image = await import_qrcode.default.toDataURL(session.scanUrl, {
3043
- width: 184,
3044
- margin: 1,
3045
- errorCorrectionLevel: "L"
3046
- });
1457
+ let session = await props.control("client.account.qr.start", { provider });
3047
1458
  if (run !== qrFlowRun.current) return;
3048
- setQrSession(session), setQrImage(image);
1459
+ setQrSession(session);
3049
1460
  } catch (reason) {
3050
1461
  run === qrFlowRun.current && setError(messageOf(reason));
3051
1462
  } finally {
@@ -3070,9 +1481,9 @@ Minimum version required to store current data is: ` + bestVersion + `.
3070
1481
  } catch (reason) {
3071
1482
  active && run === qrFlowRun.current && setError(messageOf(reason));
3072
1483
  } finally {
3073
- run === qrFlowRun.current && (setQrSession(void 0), setQrImage(void 0), setBusy(!1));
1484
+ run === qrFlowRun.current && (setQrSession(void 0), setBusy(!1));
3074
1485
  }
3075
- } else result.status === "expired" && (settled = !0, timer !== void 0 && window.clearInterval(timer), setQrExpired(!0), setQrSession(void 0), setQrImage(void 0));
1486
+ } else result.status === "expired" && (settled = !0, timer !== void 0 && window.clearInterval(timer), setQrExpired(!0), setQrSession(void 0));
3076
1487
  }).catch((reason) => {
3077
1488
  active && !settled && run === qrFlowRun.current && setError(messageOf(reason));
3078
1489
  }).finally(() => {
@@ -3082,23 +1493,9 @@ Minimum version required to store current data is: ` + bestVersion + `.
3082
1493
  return poll(), timer = window.setInterval(poll, 1500), () => {
3083
1494
  active = !1, timer !== void 0 && window.clearInterval(timer);
3084
1495
  };
3085
- }, [open, loginMethod, qrSession]), React.useEffect(() => {
3086
- loginMethodManuallySelected || loginMethod === props.preferredQrProvider || (qrFlowRun.current += 1, setLoginMethod(props.preferredQrProvider), setQrSession(void 0), setQrImage(void 0), setQrExpired(!1), setError(void 0));
3087
- }, [props.preferredQrProvider, loginMethodManuallySelected]);
3088
- let selectLoginMethod = (method) => {
3089
- setLoginMethodManuallySelected(!0), method !== loginMethod && (qrFlowRun.current += 1, setLoginMethod(method), setQrSession(void 0), setQrImage(void 0), setQrExpired(!1), setError(void 0));
3090
- }, orderedQrProviders = ENABLED_QR_PROVIDERS, qrLoginTab = (provider) => React.createElement("button", {
3091
- key: provider,
3092
- type: "button",
3093
- role: "tab",
3094
- id: `dsh-remote-${provider}-tab`,
3095
- "aria-selected": loginMethod === provider,
3096
- "aria-controls": `dsh-remote-${provider}-panel`,
3097
- className: loginMethod === provider ? "isActive" : "",
3098
- disabled: busy,
3099
- onClick: () => selectLoginMethod(provider)
3100
- }, t(QR_PROVIDER_LABELS[provider])), selectHost = async (host) => {
3101
- setBusy(!0), setError(void 0), setConnectingHost(host), setCodexWorkspaces([]), setShowAllWorkspaces(!1), setShowAllCodexWorkspaces(!1);
1496
+ }, [open, loginMethod, qrSession]);
1497
+ let selectHost = async (host) => {
1498
+ setBusy(!0), setError(void 0), setConnectingHost(host), setCodexWorkspaces([]), setCodexNotice(void 0), setShowAllWorkspaces(!1), setShowAllCodexWorkspaces(!1);
3102
1499
  try {
3103
1500
  let result = await runConnectHostProgress(
3104
1501
  status?.preferredTransports,
@@ -3110,21 +1507,38 @@ Minimum version required to store current data is: ` + bestVersion + `.
3110
1507
  async () => {
3111
1508
  let nextWorkspaces = await props.control("workspaces.list", {
3112
1509
  targetDeviceId: host.deviceId
3113
- }), nextCodexWorkspaces = await props.control("codex.workspaces.list", {
1510
+ }), codexReason, nextCodexWorkspaces = await props.control("codex.workspaces.list", {
3114
1511
  targetDeviceId: host.deviceId
3115
- }).catch(() => []), nextStatus = await props.control("status").catch(() => {
1512
+ }).catch((reason) => (codexReason = remoteErrorMessage(reason, t), [])), nextStatus = await props.control("status").catch(() => {
3116
1513
  });
3117
- return nextStatus !== void 0 && setStatus(nextStatus), { workspaces: nextWorkspaces, codexWorkspaces: nextCodexWorkspaces, status: nextStatus };
1514
+ return nextStatus !== void 0 && setStatus(nextStatus), setCodexNotice(codexReason), { workspaces: nextWorkspaces, codexWorkspaces: nextCodexWorkspaces, status: nextStatus };
3118
1515
  },
3119
1516
  (result2) => connectedProgress(result2.status)
3120
1517
  );
3121
- setWorkspaces(result.workspaces), setCodexWorkspaces(result.codexWorkspaces), setWorkspaceBackend("harness"), setCodexWorkspaceId(void 0), setSelectedHost(host), setPath(""), setAddingWorkspace(!1), setDirectory(void 0);
1518
+ setWorkspaces(result.workspaces), setCodexWorkspaces(result.codexWorkspaces), setCodexAvailable(result.status?.remoteFeatures?.codex === !0), codexProbeAvailable.current = result.status?.remoteFeatures?.codex === !0, setWorkspaceBackend("harness"), setCodexWorkspaceId(void 0), setSelectedHost(host), setPath(""), setAddingWorkspace(!1), setDirectory(void 0);
3122
1519
  } catch (reason) {
3123
- setError(messageOf(reason));
1520
+ setError(remoteErrorMessage(reason, t));
3124
1521
  } finally {
3125
1522
  setConnectingHost(void 0), setBusy(!1);
3126
1523
  }
3127
- }, browseDirectory = async (nextPath) => {
1524
+ };
1525
+ async function loadHarnessWorkspaces(host) {
1526
+ try {
1527
+ setWorkspaces(await props.control("workspaces.list", { targetDeviceId: host.deviceId }));
1528
+ } catch (reason) {
1529
+ setError(remoteErrorMessage(reason, t));
1530
+ }
1531
+ }
1532
+ async function loadCodexWorkspaces(host) {
1533
+ try {
1534
+ setCodexWorkspaces(await props.control("codex.workspaces.list", {
1535
+ targetDeviceId: host.deviceId
1536
+ })), setCodexNotice(void 0), setCodexAvailable(!0);
1537
+ } catch (reason) {
1538
+ setCodexWorkspaces([]), setCodexNotice(remoteErrorMessage(reason, t)), setCodexAvailable(!1);
1539
+ }
1540
+ }
1541
+ let browseDirectory = async (nextPath) => {
3128
1542
  if (selectedHost !== void 0) {
3129
1543
  setBusy(!0), setError(void 0);
3130
1544
  try {
@@ -3134,7 +1548,7 @@ Minimum version required to store current data is: ` + bestVersion + `.
3134
1548
  });
3135
1549
  setDirectory(listing), setCodexWorkspaceId(void 0), setPath(listing.path);
3136
1550
  } catch (reason) {
3137
- setError(messageOf(reason));
1551
+ setError(remoteErrorMessage(reason, t));
3138
1552
  } finally {
3139
1553
  setBusy(!1);
3140
1554
  }
@@ -3144,7 +1558,10 @@ Minimum version required to store current data is: ` + bestVersion + `.
3144
1558
  }, cancelAddingWorkspace = () => {
3145
1559
  setAddingWorkspace(!1), setWorkspaceBackend("harness"), setCodexWorkspaceId(void 0), setDirectory(void 0), setPath("");
3146
1560
  }, refreshRemote = async () => {
3147
- setBusy(!0), setNotice(void 0), setError(void 0);
1561
+ setBusy(!0), setNotice(void 0), setError(void 0), props.control("settings.get").then(async (view) => {
1562
+ view.config.codex?.enabled !== !1 && view.codexStatus?.available !== !0 && await props.control("settings.codex.set", { enabled: !0 });
1563
+ }).catch(() => {
1564
+ });
3148
1565
  try {
3149
1566
  let nextStatus = await props.control("status");
3150
1567
  if (setStatus(nextStatus), !nextStatus.available) {
@@ -3168,8 +1585,10 @@ Minimum version required to store current data is: ` + bestVersion + `.
3168
1585
  } catch {
3169
1586
  setDevices([]), setNeedsAuthorization(!0), setSelectedHost(void 0), setWorkspaces([]), setCodexWorkspaces([]), setShowAllWorkspaces(!1), setShowAllCodexWorkspaces(!1), setWorkspaceBackend("harness"), setCodexWorkspaceId(void 0), setPath(""), setAddingWorkspace(!1), setDirectory(void 0);
3170
1587
  }
1588
+ selectedHost !== void 0 && (await props.control("remote.session.recover").then((next) => setStatus(next)).catch(() => {
1589
+ }), await Promise.all([loadHarnessWorkspaces(selectedHost), loadCodexWorkspaces(selectedHost)]));
3171
1590
  } catch (reason) {
3172
- setError(messageOf(reason)), setAuthorizationResolved(!0);
1591
+ setError(remoteErrorMessage(reason, t)), setAuthorizationResolved(!0);
3173
1592
  } finally {
3174
1593
  setBusy(!1);
3175
1594
  }
@@ -3179,12 +1598,31 @@ Minimum version required to store current data is: ` + bestVersion + `.
3179
1598
  React.useEffect(() => {
3180
1599
  if (!(!open || selectedHost !== void 0))
3181
1600
  return props.statusFeed.subscribe(setStatus);
1601
+ }, [open, selectedHost]), React.useEffect(() => {
1602
+ if (!open || selectedHost === void 0) return;
1603
+ let cancelled = !1, probe = async () => {
1604
+ let result = await props.control("remote.features.probe").catch(() => {
1605
+ });
1606
+ if (cancelled || result === void 0 || result.targetDeviceId !== void 0 && result.targetDeviceId !== selectedHost.deviceId) return;
1607
+ let nextStatus = await props.control("status").catch(() => {
1608
+ });
1609
+ if (cancelled) return;
1610
+ nextStatus !== void 0 && setStatus(nextStatus);
1611
+ let available = result.connected === !0 && result.features?.codex === !0;
1612
+ available !== codexProbeAvailable.current && await loadCodexWorkspaces(selectedHost), codexProbeAvailable.current = available;
1613
+ };
1614
+ probe();
1615
+ let timer = window.setInterval(() => void probe(), 5e3);
1616
+ return () => {
1617
+ cancelled = !0, window.clearInterval(timer);
1618
+ };
3182
1619
  }, [open, selectedHost]);
3183
1620
  let chooseAnotherHost = () => {
3184
- setSelectedHost(void 0), setWorkspaces([]), setCodexWorkspaces([]), setShowAllWorkspaces(!1), setShowAllCodexWorkspaces(!1), setWorkspaceBackend("harness"), setCodexWorkspaceId(void 0), setDirectory(void 0), setPath(""), setAddingWorkspace(!1), setError(void 0);
1621
+ setSelectedHost(void 0), setWorkspaces([]), setCodexWorkspaces([]), setCodexNotice(void 0), setCodexAvailable(!1), codexProbeAvailable.current = !1, setShowAllWorkspaces(!1), setShowAllCodexWorkspaces(!1), setWorkspaceBackend("harness"), setCodexWorkspaceId(void 0), setDirectory(void 0), setPath(""), setAddingWorkspace(!1), setError(void 0);
3185
1622
  }, requestDeepSeekSignIn = async () => {
3186
1623
  let transport = globalThis.__DSH_TRANSPORT__, callbackOrigin = transport?.streamBaseUrl !== void 0 ? new URL(transport.streamBaseUrl).origin : window.location.origin, result = await props.control("settings.configure", {
3187
- role: "client",
1624
+ // No `role`: a device has one identity, and the control writes only the Server address plus this
1625
+ // sign-in. Sending a role here was the last thing that made one look like a runtime switch.
3188
1626
  serverUrl: loginServerUrl.trim(),
3189
1627
  provider: "deepseek",
3190
1628
  callbackOrigin,
@@ -3219,9 +1657,9 @@ Minimum version required to store current data is: ` + bestVersion + `.
3219
1657
  if (state.pending) throw new Error(t("deepseekSignInTimeout"));
3220
1658
  } else
3221
1659
  tab?.close();
3222
- setDevices(await props.control("devices")), setStatus(await props.control("status")), setNeedsAuthorization(!1), setAuthorizationResolved(!0), setPassword(""), setNotice(void 0);
1660
+ setDevices(await props.control("devices")), setStatus(await props.control("status")), setNeedsAuthorization(!1), setAuthorizationResolved(!0), setNotice(void 0);
3223
1661
  } catch (reason) {
3224
- setError(messageOf(reason));
1662
+ setError(remoteErrorMessage(reason, t));
3225
1663
  } finally {
3226
1664
  setAwaitingDeepSeek(!1), setPendingAuthorizeUrl(void 0), setBusy(!1);
3227
1665
  }
@@ -3230,23 +1668,32 @@ Minimum version required to store current data is: ` + bestVersion + `.
3230
1668
  try {
3231
1669
  await props.control("mode.set", { mode: "local" }), window.location.reload();
3232
1670
  } catch (reason) {
3233
- setError(messageOf(reason)), setBusy(!1);
1671
+ setError(remoteErrorMessage(reason, t)), setBusy(!1);
3234
1672
  }
3235
1673
  }, setCurrentDeviceControl = async (enabled) => {
3236
1674
  setBusy(!0), setError(void 0);
3237
1675
  try {
3238
1676
  setStatus(await setDeviceControl(props.control, enabled, status?.host?.authorized === !0));
3239
1677
  } catch (reason) {
3240
- setError(messageOf(reason));
1678
+ setError(remoteErrorMessage(reason, t));
3241
1679
  } finally {
3242
1680
  setBusy(!1);
3243
1681
  }
1682
+ }, revokeRemote = async () => {
1683
+ setBusy(!0), setError(void 0), setNotice(void 0);
1684
+ try {
1685
+ await props.control("client.device.revoke"), setDevices([]), setNeedsAuthorization(!0), setStatus(await props.control("status"));
1686
+ } catch (reason) {
1687
+ setError(remoteErrorMessage(reason, t));
1688
+ } finally {
1689
+ setConfirmingRevoke(!1), setBusy(!1);
1690
+ }
3244
1691
  }, logoutRemote = async () => {
3245
1692
  setBusy(!0), setError(void 0), setNotice(void 0);
3246
1693
  try {
3247
- await props.control("settings.logout"), setDevices([]), setNeedsAuthorization(!0), setQrSession(void 0), setQrImage(void 0), setQrExpired(!1), setStatus(await props.control("status"));
1694
+ await props.control("settings.logout"), setDevices([]), setNeedsAuthorization(!0), setQrSession(void 0), setQrExpired(!1), setStatus(await props.control("status"));
3248
1695
  } catch (reason) {
3249
- setError(messageOf(reason));
1696
+ setError(remoteErrorMessage(reason, t));
3250
1697
  } finally {
3251
1698
  setConfirmingSignOut(!1), setBusy(!1);
3252
1699
  }
@@ -3267,10 +1714,10 @@ Minimum version required to store current data is: ` + bestVersion + `.
3267
1714
  }));
3268
1715
  setStatus(nextStatus), nextStatus.workspaceSelection !== void 0 && window.sessionStorage.setItem(pendingWorkspaceSelectionKey, JSON.stringify(nextStatus.workspaceSelection)), window.location.reload();
3269
1716
  } catch (reason) {
3270
- setError(messageOf(reason)), setBusy(!1);
1717
+ setError(remoteErrorMessage(reason, t)), setBusy(!1);
3271
1718
  }
3272
1719
  }
3273
- }, remoteLabel = status?.mode === "remote" ? t("activeRemote", { name: status.target?.name ?? t("host") }) : t("remoteEntry"), visibleWorkspaces = showAllWorkspaces ? workspaces : workspaces.slice(0, 3), visibleCodexWorkspaces = showAllCodexWorkspaces ? codexWorkspaces : codexWorkspaces.slice(0, 3), codexAvailable = status?.remoteFeatures?.codex === !0, selectedHostDetails = selectedHost === void 0 ? void 0 : [
1720
+ }, remoteLabel = status?.mode === "remote" ? t("activeRemote", { name: status.target?.name ?? t("host") }) : t("remoteEntry"), visibleWorkspaces = showAllWorkspaces ? workspaces : workspaces.slice(0, 3), visibleCodexWorkspaces = showAllCodexWorkspaces ? codexWorkspaces : codexWorkspaces.slice(0, 3), selectedHostDetails = selectedHost === void 0 ? void 0 : [
3274
1721
  formatPlatform(selectedHost.platform),
3275
1722
  selectedHost.harnessVersion === void 0 ? void 0 : t("harnessVersion", { version: selectedHost.harnessVersion }),
3276
1723
  selectedHost.clientVersion === void 0 ? void 0 : t("pluginVersion", { version: selectedHost.clientVersion })
@@ -3496,9 +1943,29 @@ Minimum version required to store current data is: ` + bestVersion + `.
3496
1943
  onChange: (event) => void setCurrentDeviceControl(event.target.checked)
3497
1944
  })
3498
1945
  ) : null,
1946
+ React.createElement(
1947
+ "div",
1948
+ { className: "dshRemotePageActions" },
1949
+ React.createElement("button", {
1950
+ type: "button",
1951
+ className: "dshRemotePageRefresh",
1952
+ disabled: busy,
1953
+ // Match the "allow control" label exactly: 12px/18px in the secondary label colour, so it
1954
+ // reads as the same kind of control instead of a page-level action.
1955
+ style: { fontWeight: "normal", fontSize: "12px", lineHeight: "18px", height: "auto", minWidth: "0", padding: "0 4px", color: "var(--dsw-alias-label-secondary)" },
1956
+ title: t("codexRemote"),
1957
+ "aria-label": t("codexRemote"),
1958
+ onClick: () => setCodexOpen(!0)
1959
+ }, t("codexRemote"))
1960
+ ),
3499
1961
  connectedMenu
3500
1962
  )
3501
1963
  ),
1964
+ codexOpen ? React.createElement(CodexConnectionDetails, {
1965
+ control: props.control,
1966
+ t,
1967
+ onClose: () => setCodexOpen(!1)
1968
+ }) : null,
3502
1969
  React.createElement("div", {
3503
1970
  className: `dshRemoteHostList${connectingHost === void 0 ? "" : " isCollapsed"}`,
3504
1971
  "aria-busy": connectingHost === void 0 ? void 0 : !0
@@ -3521,7 +1988,7 @@ Minimum version required to store current data is: ` + bestVersion + `.
3521
1988
  device.clientVersion === void 0 ? void 0 : t("pluginVersion", { version: device.clientVersion })
3522
1989
  ].filter(Boolean).join(" \xB7 "))
3523
1990
  ),
3524
- React.createElement("small", null, t(device.online ? "online" : "offline"))
1991
+ React.createElement("small", null, [t(device.online ? "online" : "offline"), device.hostControl === !1 ? t("hostRefusesControl") : void 0].filter(Boolean).join(" \xB7 "))
3525
1992
  )))
3526
1993
  ) : null,
3527
1994
  React.createElement(RemoteProgressView, { progress, t }),
@@ -3531,7 +1998,7 @@ Minimum version required to store current data is: ` + bestVersion + `.
3531
1998
  React.createElement(
3532
1999
  "p",
3533
2000
  { className: "dshRemoteHint" },
3534
- t(confirmingSignOut ? "signOutImpact" : "selectHostHint")
2001
+ t(confirmingRevoke ? "revokeDeviceImpact" : confirmingSignOut ? "signOutImpact" : "selectHostHint")
3535
2002
  ),
3536
2003
  React.createElement(
3537
2004
  "footer",
@@ -3555,6 +2022,27 @@ Minimum version required to store current data is: ` + bestVersion + `.
3555
2022
  React.Fragment,
3556
2023
  null,
3557
2024
  React.createElement("span", null, status?.host?.account ?? t("account")),
2025
+ confirmingRevoke ? React.createElement(
2026
+ React.Fragment,
2027
+ null,
2028
+ React.createElement("button", {
2029
+ type: "button",
2030
+ className: "dshRemoteDiscard",
2031
+ disabled: busy,
2032
+ onClick: () => setConfirmingRevoke(!1)
2033
+ }, t("cancel")),
2034
+ React.createElement("button", {
2035
+ type: "button",
2036
+ className: "dshRemoteAccountExit",
2037
+ disabled: busy,
2038
+ onClick: () => void revokeRemote()
2039
+ }, t("revokeThisDevice"))
2040
+ ) : React.createElement("button", {
2041
+ type: "button",
2042
+ className: "dshRemoteAccountExit",
2043
+ disabled: busy,
2044
+ onClick: () => setConfirmingRevoke(!0)
2045
+ }, t("revokeThisDevice")),
3558
2046
  React.createElement("button", {
3559
2047
  type: "button",
3560
2048
  className: "dshRemoteAccountExit",
@@ -3649,7 +2137,7 @@ Minimum version required to store current data is: ` + bestVersion + `.
3649
2137
  }, React.createElement("span", { "aria-hidden": !0 }, "\u2026"))
3650
2138
  )
3651
2139
  ),
3652
- !codexAvailable && codexWorkspaces.length === 0 ? null : React.createElement(
2140
+ React.createElement(
3653
2141
  "section",
3654
2142
  { className: "dshRemoteCodexWorkspaceGroup" },
3655
2143
  React.createElement(
@@ -3681,7 +2169,7 @@ Minimum version required to store current data is: ` + bestVersion + `.
3681
2169
  id: codexWorkspaceListId,
3682
2170
  className: "dshRemoteDirectoryList dshRemoteCodexWorkspaceList",
3683
2171
  "aria-labelledby": codexWorkspaceHeadingId
3684
- }, visibleCodexWorkspaces.length === 0 ? React.createElement("p", null, t("noCodexWorkspaces")) : visibleCodexWorkspaces.map((workspace) => React.createElement(
2172
+ }, visibleCodexWorkspaces.length === 0 ? React.createElement("p", null, codexNotice ?? t("noCodexWorkspaces")) : visibleCodexWorkspaces.map((workspace) => React.createElement(
3685
2173
  "button",
3686
2174
  {
3687
2175
  type: "button",
@@ -3731,153 +2219,162 @@ Minimum version required to store current data is: ` + bestVersion + `.
3731
2219
  )) : null
3732
2220
  );
3733
2221
  }
3734
- function RemoteModeAction(props) {
3735
- let { t } = props, [open, setOpen] = React.useState(!1), [status, setStatus] = React.useState(void 0), [devices, setDevices] = React.useState([]), [hostRegistrationCode, setHostRegistrationCode] = React.useState(""), [email, setEmail] = React.useState(""), [password, setPassword] = React.useState(""), [busy, setBusy] = React.useState(!1), [progress, setProgress] = React.useState(void 0), progressRun = React.useRef(0), [error, setError] = React.useState(void 0), [supported, setSupported] = React.useState(!0), refresh = async () => {
3736
- let [nextStatus, nextDevices] = await Promise.all([
3737
- props.control("status"),
3738
- props.control("devices").catch(() => [])
3739
- ]);
3740
- setStatus(nextStatus), setDevices(nextDevices);
3741
- }, refreshStatus = async () => {
3742
- setStatus(await props.control("status"));
3743
- };
2222
+ function CodexConnectionFields(props) {
2223
+ let { t, busy, writable, unavailable, editable, pinned, discovered, value } = props;
2224
+ return React.createElement(
2225
+ React.Fragment,
2226
+ null,
2227
+ React.createElement(
2228
+ "div",
2229
+ { className: "dshRemoteAuthorizationSetting" },
2230
+ React.createElement(
2231
+ "div",
2232
+ null,
2233
+ React.createElement("span", null, t("codexControlAllow"))
2234
+ ),
2235
+ React.createElement("input", {
2236
+ type: "checkbox",
2237
+ role: "switch",
2238
+ // Only greyed out while it is ON and the domain cannot run. A switched-off Codex also reports
2239
+ // available:false - that is the off state, not a failure - so treating it as "unavailable" locked the
2240
+ // switch and left no way to turn Codex back on.
2241
+ disabled: busy || !writable || unavailable && props.enabled,
2242
+ "aria-label": t("codexRemote"),
2243
+ checked: props.enabled,
2244
+ onChange: (event) => props.onEnabledChange(event.target.checked)
2245
+ })
2246
+ ),
2247
+ // A disabled Codex is a choice, not a fault, and neither is a launch in progress: available is false while the
2248
+ // domain starts, which used to paint a red line reading UNKNOWN for the couple of seconds every switch takes.
2249
+ // Red is for a real failure only, and a failure that carries no code says so in words instead of printing
2250
+ // UNKNOWN as if it were a code.
2251
+ props.enabled ? props.state === "starting" || props.state === "restarting" ? React.createElement("p", { className: "dshRemoteSettingsState" }, t("codexStarting")) : unavailable && props.state === "unavailable" ? React.createElement("p", { className: "dshRemoteError" }, props.reasonCode === void 0 ? t("codexUnavailableNoCode") : t(codexUnavailableKey(props.reasonCode), { code: props.reasonCode })) : null : React.createElement("p", { className: "dshRemoteSettingsState" }, t("codexDisabled")),
2252
+ React.createElement(
2253
+ "div",
2254
+ { className: "dshRemoteCodexBinary" },
2255
+ React.createElement("input", {
2256
+ type: "text",
2257
+ value: editable ? value : discovered ?? "",
2258
+ readOnly: !editable,
2259
+ // Never disabled for being unwritable: when the CLI cannot start, this field is the only way out, and a
2260
+ // failed save reports itself in the dialog instead of leaving the user with a dead control.
2261
+ disabled: busy,
2262
+ className: editable ? "" : "isDiscovered",
2263
+ placeholder: editable ? t("codexBinaryPlaceholder") : void 0,
2264
+ "aria-label": t("codexBinaryLabel"),
2265
+ onChange: (event) => props.onValueChange(event.target.value),
2266
+ onKeyDown: (event) => {
2267
+ event.key === "Enter" && editable && props.onConfirm();
2268
+ }
2269
+ }),
2270
+ editable ? React.createElement("button", {
2271
+ type: "button",
2272
+ className: "dshRemoteDiscard",
2273
+ disabled: busy,
2274
+ onClick: () => props.onConfirm()
2275
+ }, t("codexBinaryConfirm")) : null,
2276
+ pinned ? React.createElement("button", {
2277
+ type: "button",
2278
+ className: "dshRemoteDiscard",
2279
+ disabled: busy,
2280
+ onClick: () => props.onUseAuto()
2281
+ }, t("codexBinaryAuto")) : null,
2282
+ pinned || discovered === void 0 ? React.createElement("p", null, t(pinned ? "codexBinaryPinned" : "codexBinaryMissing")) : null
2283
+ )
2284
+ );
2285
+ }
2286
+ function CodexConnectionDetails(props) {
2287
+ let { control, t, onClose } = props, [view, setView] = React.useState(void 0), [enabled, setEnabled] = React.useState(!0), [binary, setBinary] = React.useState("codex"), [busy, setBusy] = React.useState(!1), [error, setError] = React.useState(void 0);
3744
2288
  React.useEffect(() => {
3745
- refresh().catch((reason) => {
3746
- setError(messageOf(reason)), setSupported(!1);
3747
- });
3748
- }, []), React.useEffect(() => {
3749
- if (open)
3750
- return props.statusFeed.subscribe(setStatus);
3751
- }, [open]);
3752
- let switchMode = async (mode, targetDeviceId) => {
3753
- setBusy(!0), setError(void 0);
3754
- try {
3755
- let action = () => props.control("mode.set", { mode, ...targetDeviceId === void 0 ? {} : { targetDeviceId } });
3756
- setStatus(mode === "remote" && targetDeviceId !== void 0 ? await runConnectHostProgress(
3757
- status?.preferredTransports,
3758
- targetDeviceId,
3759
- props.control,
3760
- { label: "remoteProgressSwitchingWorkspace", detail: "remoteProgressSwitchingWorkspaceDetail" },
3761
- setProgress,
3762
- progressRun,
3763
- action,
3764
- connectedProgress
3765
- ) : await action()), window.location.reload();
3766
- } catch (reason) {
3767
- setError(messageOf(reason)), setBusy(!1);
3768
- }
3769
- }, loginHost = async () => {
3770
- if (!(email.trim() === "" || password === "")) {
3771
- setBusy(!0), setError(void 0);
2289
+ let cancelled = !1;
2290
+ return (async () => {
3772
2291
  try {
3773
- await props.control("host.account.login", { email: email.trim(), password }), await refreshStatus();
3774
- } catch (reason) {
3775
- setError(messageOf(reason));
3776
- } finally {
3777
- setPassword(""), setBusy(!1);
3778
- }
3779
- }
3780
- }, registerHostWithCode = async () => {
3781
- if (hostRegistrationCode.trim() !== "") {
3782
- setBusy(!0), setError(void 0);
3783
- try {
3784
- await props.control("host.registration-code.submit", { code: hostRegistrationCode.trim() }), setHostRegistrationCode(""), await refreshStatus();
3785
- } catch (reason) {
3786
- setError(messageOf(reason));
3787
- } finally {
3788
- setBusy(!1);
2292
+ let loaded = await control("settings.get");
2293
+ if (cancelled) return;
2294
+ setView(loaded), setEnabled(loaded.config.codex?.enabled ?? !0), setBinary(loaded.config.codex?.binary ?? "codex");
2295
+ } catch (cause) {
2296
+ cancelled || setError(cause instanceof Error ? cause.message : String(cause));
3789
2297
  }
2298
+ })(), () => {
2299
+ cancelled = !0;
2300
+ };
2301
+ }, [control]);
2302
+ let status = view?.codexStatus, unavailable = status !== void 0 && status.available === !1, settledState = status?.state;
2303
+ React.useEffect(() => {
2304
+ if (view === void 0 || busy || settledState === "ready" || settledState === "disabled") return;
2305
+ let timer = setInterval(() => {
2306
+ control("settings.get").then((next) => {
2307
+ setView(next), setEnabled(next.config.codex?.enabled ?? !0), setBinary(next.config.codex?.binary ?? "codex");
2308
+ }).catch(() => {
2309
+ });
2310
+ }, 2e3);
2311
+ return () => {
2312
+ clearInterval(timer);
2313
+ };
2314
+ }, [control, view, busy, settledState]);
2315
+ let writable = view?.writable === !0, discovered = view?.discoveredCodexBinary, pinned = (view?.config.codex?.binary ?? "codex") !== "codex", editable = pinned || discovered === void 0, stateName = status === void 0 ? void 0 : `${(status.state ?? "unknown").slice(0, 1).toUpperCase()}${(status.state ?? "unknown").slice(1)}`, stateText = stateName === void 0 ? t("loadingSettings") : t("codexStatusLine", { state: `${stateName}${status?.error === void 0 ? "" : ` \xB7 ${status.error}`}` }), save = async (next) => {
2316
+ setBusy(!0), setError(void 0);
2317
+ try {
2318
+ let updated = await control("settings.codex.set", {
2319
+ enabled: next.enabled ?? enabled,
2320
+ ...next.binary === void 0 ? {} : { binary: next.binary }
2321
+ });
2322
+ setView(updated), setEnabled(updated.config.codex?.enabled ?? enabled), setBinary(updated.config.codex?.binary ?? binary);
2323
+ } catch (cause) {
2324
+ setError(cause instanceof Error ? cause.message : String(cause));
2325
+ } finally {
2326
+ setBusy(!1);
3790
2327
  }
3791
- }, label = status?.mode === "remote" ? t("remoteTarget", { name: status.target?.name ?? t("host") }) : t("local");
3792
- return supported ? React.createElement(
3793
- React.Fragment,
3794
- null,
3795
- React.createElement("button", {
3796
- type: "button",
3797
- className: "dshRemoteModeButton",
3798
- title: t("switchTarget"),
3799
- "aria-label": t("switchTarget"),
3800
- onClick: () => setOpen(!0)
3801
- }, React.createElement("span", { "aria-hidden": !0 }, "\u25CE"), props.wide ? React.createElement("span", null, label) : null),
3802
- open ? React.createElement(
3803
- "div",
3804
- { className: "dshRemoteBackdrop", role: "presentation" },
2328
+ };
2329
+ return React.createElement(
2330
+ "div",
2331
+ { className: "dshRemoteBackdrop", role: "presentation" },
2332
+ React.createElement(
2333
+ "section",
2334
+ {
2335
+ className: "dshRemoteDialog",
2336
+ role: "dialog",
2337
+ "aria-modal": !0,
2338
+ "aria-label": t("codexRemote")
2339
+ },
3805
2340
  React.createElement(
3806
- "section",
3807
- {
3808
- className: "dshRemoteDialog",
3809
- role: "dialog",
3810
- "aria-modal": !0,
3811
- "aria-label": t("harnessTarget")
3812
- },
2341
+ "div",
2342
+ { className: "dshRemoteHeader" },
2343
+ React.createElement("strong", null, t("codexRemote")),
2344
+ React.createElement("button", { type: "button", onClick: onClose, "aria-label": t("close") }, "\xD7")
2345
+ ),
2346
+ view === void 0 ? React.createElement("p", { className: "dshRemoteSettingsState" }, error ?? t("loadingSettings")) : React.createElement(
2347
+ React.Fragment,
2348
+ null,
2349
+ React.createElement("p", { className: "dshRemoteSettingsState" }, stateText),
2350
+ React.createElement(CodexConnectionFields, {
2351
+ t,
2352
+ enabled,
2353
+ onEnabledChange: (next) => void save({ enabled: next }),
2354
+ busy,
2355
+ writable,
2356
+ unavailable,
2357
+ state: status?.state,
2358
+ reasonCode: status?.error,
2359
+ editable,
2360
+ pinned,
2361
+ discovered,
2362
+ value: binary,
2363
+ onValueChange: (next) => setBinary(next),
2364
+ onConfirm: () => void save({ binary }),
2365
+ onUseAuto: () => void save({ binary: "" })
2366
+ }),
2367
+ // No confirm button: the switch and the command field save on their own, and a footer button could only
2368
+ // re-send the state the dialog captured when it opened - which is how pressing it turned a starting Codex
2369
+ // back off. The footer keeps the message line and nothing else.
3813
2370
  React.createElement(
3814
2371
  "div",
3815
- { className: "dshRemoteHeader" },
3816
- React.createElement("strong", null, t("harnessTarget")),
3817
- React.createElement("button", { type: "button", onClick: () => setOpen(!1), "aria-label": t("close") }, "\xD7")
3818
- ),
3819
- React.createElement("button", {
3820
- type: "button",
3821
- disabled: busy || status?.mode === "local",
3822
- onClick: () => void switchMode("local")
3823
- }, t("thisMachineLocal")),
3824
- React.createElement("div", { className: "dshRemoteDevices" }, devices.length === 0 ? React.createElement("p", null, t("noRemoteHosts")) : devices.map((device) => React.createElement("button", {
3825
- type: "button",
3826
- key: device.deviceId,
3827
- disabled: busy || !device.online || status?.target?.deviceId === device.deviceId,
3828
- onClick: () => void switchMode("remote", device.deviceId)
3829
- }, `${device.name} \xB7 ${t(device.online ? "online" : "offline")}`))),
3830
- React.createElement(RemoteProgressView, { progress, t }),
3831
- status?.hostAuthorizationAvailable && status.host !== void 0 ? React.createElement(
3832
- "div",
3833
- { className: "dshRemoteHostAccount" },
3834
- React.createElement("strong", null, t("thisMachineHost")),
3835
- React.createElement("p", null, status.host.online ? status.host.account === void 0 ? t("connected") : t("connectedAs", { account: status.host.account }) : status.host.accountRequired ? t("hostSignInHint") : status.host.error === void 0 ? t("checkingHost") : t("hostUnavailable", { error: connectionErrorMessage(status.host.error, t) })),
3836
- status.host.accountRequired ? React.createElement(
3837
- "div",
3838
- { className: "dshRemoteLogin" },
3839
- React.createElement("input", {
3840
- type: "email",
3841
- value: email,
3842
- disabled: busy,
3843
- autoComplete: "username",
3844
- placeholder: t("serverAccountEmail"),
3845
- "aria-label": t("serverAccountEmail"),
3846
- onChange: (event) => setEmail(event.target.value)
3847
- }),
3848
- React.createElement("input", {
3849
- type: "password",
3850
- value: password,
3851
- disabled: busy,
3852
- autoComplete: "current-password",
3853
- placeholder: t("password"),
3854
- "aria-label": t("serverAccountPassword"),
3855
- onChange: (event) => setPassword(event.target.value)
3856
- }),
3857
- React.createElement("button", {
3858
- type: "button",
3859
- disabled: busy || email.trim() === "" || password === "",
3860
- onClick: () => void loginHost()
3861
- }, t(busy ? "signingIn" : "signInRegisterHost")),
3862
- React.createElement("input", {
3863
- value: hostRegistrationCode,
3864
- disabled: busy,
3865
- autoComplete: "one-time-code",
3866
- placeholder: t("hostRegistrationCode"),
3867
- "aria-label": t("hostRegistrationCode"),
3868
- onChange: (event) => setHostRegistrationCode(event.target.value)
3869
- }),
3870
- React.createElement("button", {
3871
- type: "button",
3872
- disabled: busy || hostRegistrationCode.trim() === "",
3873
- onClick: () => void registerHostWithCode()
3874
- }, t(busy ? "registering" : "useRegistrationCode"))
3875
- ) : null
3876
- ) : null,
3877
- error === void 0 ? null : React.createElement("p", { className: "dshRemoteError", role: "alert" }, error)
2372
+ { className: "dshRemoteSettingsFooter" },
2373
+ React.createElement("p", { className: error === void 0 ? "dshRemoteNotice" : "dshRemoteError" }, error ?? "")
2374
+ )
3878
2375
  )
3879
- ) : null
3880
- ) : null;
2376
+ )
2377
+ );
3881
2378
  }
3882
2379
  function RemoteSessionHeaderAction(props) {
3883
2380
  let { t } = props, status = React.useSyncExternalStore(
@@ -3916,7 +2413,14 @@ Minimum version required to store current data is: ` + bestVersion + `.
3916
2413
  strokeLinejoin: "round",
3917
2414
  "aria-hidden": !0
3918
2415
  }, React.createElement("rect", { x: 3, y: 4, width: 18, height: 13, rx: 2 }), React.createElement("path", { d: "M8 21h8M12 17v4" })),
3919
- React.createElement("span", { className: "dshRemoteModePrefix" }, t("remoteModePrefix")),
2416
+ // The label names the session being recovered when one is, because a Codex recovery has already
2417
+ // switched the carriers to the local shell by then; reading the kind off `backend` alone said
2418
+ // "remote DSH, reconnecting" for a Codex session.
2419
+ React.createElement(
2420
+ "span",
2421
+ { className: "dshRemoteModePrefix" },
2422
+ t((status.reconnecting?.kind ?? status.backend) === "codex" ? "remoteModeCodex" : "remoteModeDsh")
2423
+ ),
3920
2424
  React.createElement(
3921
2425
  "span",
3922
2426
  { className: "dshRemoteSessionTarget" },
@@ -4156,7 +2660,7 @@ Minimum version required to store current data is: ` + bestVersion + `.
4156
2660
  if (controlRouteBackoffIndex += 1, controlRouteRetryAfter = Date.now() + delayMs, endpoint === "status") return controlRouteUnavailableStatus();
4157
2661
  throw new ControlRouteUnavailableError(t("remoteControlUnavailable"));
4158
2662
  }
4159
- if (!result.ok) throw new Error(result.error?.message ?? t("remoteRequestFailed"));
2663
+ if (!result.ok) throw controlFailure(result.error, t);
4160
2664
  return result.value;
4161
2665
  }, statusFeed = createStatusFeed({
4162
2666
  url: STATUS_STREAM_PATH,