@blue-soda/dsh-remote 0.4.32 → 0.5.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/client.js CHANGED
@@ -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;
@@ -1753,13 +131,13 @@ Minimum version required to store current data is: ` + bestVersion + `.
1753
131
  // src/defaults.ts
1754
132
  var DEFAULT_REMOTE_SERVER_URL = "https://sakakibara.ink:8443";
1755
133
 
134
+ // src/panel-authorization.ts
135
+ function authorizationStillNeeded(storedLocally, deviceCount) {
136
+ return deviceCount > 0 ? !1 : !storedLocally;
137
+ }
138
+
1756
139
  // 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";
140
+ 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
141
  function isEnabledQrProvider(provider) {
1764
142
  return ENABLED_QR_PROVIDERS.includes(provider);
1765
143
  }
@@ -1821,7 +199,8 @@ Minimum version required to store current data is: ` + bestVersion + `.
1821
199
  serverUrlHint: "HTTPS origin used for account authorization and encrypted relay.",
1822
200
  serverSaved: "Server address saved. Restart DSH to apply it.",
1823
201
  codexRemote: "Codex Remote",
1824
- codexRemoteHint: "Expose Codex projects through this Host. Restart DSH after changing this setting.",
202
+ codexStatusLine: "Current state: {state}",
203
+ codexControlAllow: "Allow other users to control Codex on this device",
1825
204
  codexSaved: "Codex Remote setting saved. Restart DSH to apply it.",
1826
205
  codexBinaryLabel: "Codex command or path",
1827
206
  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 +208,17 @@ Minimum version required to store current data is: ` + bestVersion + `.
1829
208
  codexBinaryAuto: "Use auto-discovery",
1830
209
  codexBinaryPlaceholder: 'Path to a Codex CLI that supports "codex app-server"',
1831
210
  codexBinaryPinned: "Set by hand. Clear the field and confirm to discover it automatically again.",
211
+ 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.",
212
+ codexUnavailableSignIn: "Codex is not signed in on this host. Sign in with the Codex app, then restart DSH.",
213
+ 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.",
214
+ codexUnavailableGeneric: "Codex is unavailable on this host ({code}).",
215
+ codexDisabled: "Codex is switched off on this device, so nobody can use it remotely.",
216
+ codexStarting: "Starting the Codex connection...",
217
+ codexUnavailableNoCode: "Codex is unavailable on this host.",
218
+ codexRecheck: "Re-check",
219
+ codexRemoteOff: "Codex is switched off on that device.",
220
+ codexRemoteNotProvided: "That device does not provide Codex.",
221
+ codexRemoteUnavailable: "Codex is currently unavailable on that device.",
1832
222
  authorizeFromRemote: "Sign in from the Remote entry in the sidebar, then return here to manage this device.",
1833
223
  authorizationMethod: "Authorization method",
1834
224
  accountPassword: "Account password",
@@ -1859,6 +249,9 @@ Minimum version required to store current data is: ` + bestVersion + `.
1859
249
  noRemoteHosts: "No authorized remote Host for this account.",
1860
250
  online: "Online",
1861
251
  offline: "Offline",
252
+ connectionControlDisabled: 'That device is not accepting control. Turn on "Allow control" on it.',
253
+ connectionHostOffline: "The selected Host is offline.",
254
+ hostRefusesControl: "Not accepting control",
1862
255
  thisMachineHost: "This machine as Remote Host",
1863
256
  connected: "Connected",
1864
257
  connectedAs: "Connected as {account}",
@@ -1871,10 +264,10 @@ Minimum version required to store current data is: ` + bestVersion + `.
1871
264
  reconnect: "Reconnect",
1872
265
  reconnectingAction: "Reconnecting\u2026",
1873
266
  reconnectStarted: "Reconnect requested.",
1874
- connectionAuthorizationExpired: "Authorization expired. Sign out and authorize this Host again.",
267
+ connectionAuthorizationExpired: "Authorization expired. Sign in again to authorize this device.",
1875
268
  connectionReplaced: "Another instance is using this Host identity. Stop it or use a separate DSH_HOME before reconnecting.",
1876
269
  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.",
270
+ connectionDeviceRevoked: "This device was removed on the Server. Sign in again to add it back.",
1878
271
  connectionOwnershipRequired: "The Server no longer recognizes this Host as an owned device.",
1879
272
  connectionRateLimited: "The Server is receiving too many requests. Automatic retry will continue.",
1880
273
  connectionVersionMismatch: "The Plugin and Server protocol versions are incompatible.",
@@ -1941,7 +334,8 @@ Minimum version required to store current data is: ` + bestVersion + `.
1941
334
  confirmAddWorkspace: "Add and open",
1942
335
  showAllWorkspaces: "Show all DSH workspaces",
1943
336
  showAllCodexWorkspaces: "Show all CodeX workspaces",
1944
- remoteModePrefix: "Remote mode \xB7 ",
337
+ remoteModeDsh: "Remote DSH \xB7 ",
338
+ remoteModeCodex: "Remote Codex \xB7 ",
1945
339
  remoteNetworkP2p: "P2P",
1946
340
  remoteNetworkTurn: "TURN",
1947
341
  remoteNetworkRelay: "Relay",
@@ -2020,6 +414,8 @@ Minimum version required to store current data is: ` + bestVersion + `.
2020
414
  noConnectedClients: "No devices are currently connected to this Host.",
2021
415
  unknownDevice: "Unknown device",
2022
416
  exitRemoteAccount: "Sign out",
417
+ revokeThisDevice: "Remove this device",
418
+ revokeDeviceImpact: "Removes this device from the account. Signing in again brings it back with the same device id.",
2023
419
  cancel: "Cancel",
2024
420
  signOutImpact: "Signing out disconnects this plugin and also signs DSH out of your DeepSeek account.",
2025
421
  wechatLogin: "WeChat QR",
@@ -2077,7 +473,8 @@ Minimum version required to store current data is: ` + bestVersion + `.
2077
473
  serverUrlHint: "\u7528\u4E8E\u8D26\u53F7\u6388\u6743\u548C\u52A0\u5BC6\u4E2D\u7EE7\u7684 HTTPS \u5730\u5740\u3002",
2078
474
  serverSaved: "Server \u5730\u5740\u5DF2\u4FDD\u5B58\uFF0C\u91CD\u542F DSH \u540E\u751F\u6548\u3002",
2079
475
  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",
476
+ codexStatusLine: "\u5F53\u524D\u72B6\u6001\uFF1A{state}",
477
+ codexControlAllow: "\u5141\u8BB8\u5176\u4ED6\u7528\u6237\u63A7\u5236\u672C\u8BBE\u5907Codex",
2081
478
  codexSaved: "Codex Remote \u8BBE\u7F6E\u5DF2\u4FDD\u5B58\uFF0C\u91CD\u542F DSH \u540E\u751F\u6548\u3002",
2082
479
  codexBinaryLabel: "Codex \u547D\u4EE4\u6216\u8DEF\u5F84",
2083
480
  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 +482,17 @@ Minimum version required to store current data is: ` + bestVersion + `.
2085
482
  codexBinaryAuto: "\u6062\u590D\u81EA\u52A8\u53D1\u73B0",
2086
483
  codexBinaryPlaceholder: '\u652F\u6301 "codex app-server" \u7684 Codex CLI \u8DEF\u5F84',
2087
484
  codexBinaryPinned: "\u5F53\u524D\u4E3A\u624B\u52A8\u6307\u5B9A\uFF1B\u6E05\u7A7A\u540E\u786E\u8BA4\u5373\u53EF\u6062\u590D\u81EA\u52A8\u53D1\u73B0\u3002",
485
+ 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",
486
+ 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",
487
+ 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",
488
+ codexUnavailableGeneric: "\u8FD9\u53F0 Host \u4E0A\u7684 Codex \u5F53\u524D\u4E0D\u53EF\u7528\uFF08{code}\uFF09\u3002",
489
+ codexDisabled: "\u672C\u8BBE\u5907\u7684 Codex \u5DF2\u5173\u95ED\uFF0C\u5176\u4ED6\u7528\u6237\u65E0\u6CD5\u8FDC\u7A0B\u4F7F\u7528\u3002",
490
+ codexStarting: "\u6B63\u5728\u542F\u52A8 Codex \u8FDE\u63A5\u2026",
491
+ codexUnavailableNoCode: "\u8FD9\u53F0 Host \u4E0A\u7684 Codex \u5F53\u524D\u4E0D\u53EF\u7528\u3002",
492
+ codexRecheck: "\u91CD\u65B0\u68C0\u67E5",
493
+ codexRemoteOff: "\u8BE5\u8BBE\u5907\u7684 Codex \u5DF2\u5173\u95ED\u3002",
494
+ codexRemoteNotProvided: "\u8BE5\u8BBE\u5907\u4E0D\u63D0\u4F9B Codex\u3002",
495
+ codexRemoteUnavailable: "\u8BE5\u8BBE\u5907\u7684 Codex \u5F53\u524D\u4E0D\u53EF\u7528\u3002",
2088
496
  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
497
  authorizationMethod: "\u6388\u6743\u65B9\u5F0F",
2090
498
  accountPassword: "\u8D26\u53F7\u5BC6\u7801",
@@ -2115,6 +523,9 @@ Minimum version required to store current data is: ` + bestVersion + `.
2115
523
  noRemoteHosts: "\u6B64\u8D26\u53F7\u6CA1\u6709\u5DF2\u6388\u6743\u7684\u8FDC\u7A0B Host\u3002",
2116
524
  online: "\u5728\u7EBF",
2117
525
  offline: "\u79BB\u7EBF",
526
+ 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",
527
+ connectionHostOffline: "\u6240\u9009 Host \u5F53\u524D\u79BB\u7EBF\u3002",
528
+ hostRefusesControl: "\u4E0D\u63A5\u53D7\u63A7\u5236",
2118
529
  thisMachineHost: "\u5C06\u6B64\u8BBE\u5907\u4F5C\u4E3A\u8FDC\u7A0B Host",
2119
530
  connected: "\u5DF2\u8FDE\u63A5",
2120
531
  connectedAs: "\u5DF2\u4F7F\u7528 {account} \u8FDE\u63A5",
@@ -2127,10 +538,10 @@ Minimum version required to store current data is: ` + bestVersion + `.
2127
538
  reconnect: "\u624B\u52A8\u91CD\u8FDE",
2128
539
  reconnectingAction: "\u6B63\u5728\u91CD\u8FDE\u2026",
2129
540
  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",
541
+ connectionAuthorizationExpired: "\u6388\u6743\u5DF2\u5931\u6548\uFF0C\u8BF7\u91CD\u65B0\u767B\u5F55\u4EE5\u91CD\u65B0\u6388\u6743\u6B64\u8BBE\u5907\u3002",
2131
542
  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
543
  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",
544
+ connectionDeviceRevoked: "\u6B64\u8BBE\u5907\u5DF2\u5728 Server \u4E0A\u88AB\u79FB\u9664\uFF0C\u8BF7\u91CD\u65B0\u767B\u5F55\u4EE5\u91CD\u65B0\u6DFB\u52A0\u3002",
2134
545
  connectionOwnershipRequired: "Server \u5DF2\u4E0D\u518D\u5C06\u6B64 Host \u8BC6\u522B\u4E3A\u5F53\u524D\u8D26\u53F7\u7684\u8BBE\u5907\u3002",
2135
546
  connectionRateLimited: "Server \u8BF7\u6C42\u8FC7\u591A\uFF0C\u63D2\u4EF6\u5C06\u7EE7\u7EED\u81EA\u52A8\u91CD\u8BD5\u3002",
2136
547
  connectionVersionMismatch: "Plugin \u4E0E Server \u7684\u534F\u8BAE\u7248\u672C\u4E0D\u517C\u5BB9\u3002",
@@ -2197,7 +608,8 @@ Minimum version required to store current data is: ` + bestVersion + `.
2197
608
  confirmAddWorkspace: "\u786E\u8BA4\u5E76\u6253\u5F00",
2198
609
  showAllWorkspaces: "\u663E\u793A\u5168\u90E8 DSH \u5DE5\u4F5C\u533A",
2199
610
  showAllCodexWorkspaces: "\u663E\u793A\u5168\u90E8 CodeX \u5DE5\u4F5C\u533A",
2200
- remoteModePrefix: "\u8FDC\u7A0B\u6A21\u5F0F \xB7 ",
611
+ remoteModeDsh: "\u8FDC\u7A0BDSH \xB7 ",
612
+ remoteModeCodex: "\u8FDC\u7A0BCodex \xB7 ",
2201
613
  remoteNetworkP2p: "P2P",
2202
614
  remoteNetworkTurn: "TURN",
2203
615
  remoteNetworkRelay: "\u4E2D\u7EE7",
@@ -2276,6 +688,8 @@ Minimum version required to store current data is: ` + bestVersion + `.
2276
688
  noConnectedClients: "\u76EE\u524D\u6CA1\u6709\u8BBE\u5907\u8FDE\u63A5\u5230\u8FD9\u53F0\u4E3B\u673A\u3002",
2277
689
  unknownDevice: "\u672A\u77E5\u8BBE\u5907",
2278
690
  exitRemoteAccount: "\u9000\u51FA\u8D26\u53F7",
691
+ revokeThisDevice: "\u6CE8\u9500\u672C\u8BBE\u5907",
692
+ 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
693
  cancel: "\u53D6\u6D88",
2280
694
  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
695
  wechatLogin: "\u5FAE\u4FE1\u626B\u7801",
@@ -2292,7 +706,11 @@ Minimum version required to store current data is: ` + bestVersion + `.
2292
706
  refreshQrCode: "\u5237\u65B0\u4E8C\u7EF4\u7801",
2293
707
  codexVirtualWorkspace: "CodeX \u5DE5\u4F5C\u533A",
2294
708
  codexVirtualSessions: "Sessions"
2295
- }, defaultPreferredTransports = ["lan", "p2p", "turn", "relay"], controlRouteBackoffStepsMs = [1e3, 2e3, 5e3, 1e4, 3e4], ControlRouteUnavailableError = class extends Error {
709
+ };
710
+ function codexUnavailableKey(code) {
711
+ return code === "CODEX_ACCOUNT_UNREACHABLE" ? "codexUnavailableAccount" : code === "CODEX_AUTH_REQUIRED" ? "codexUnavailableSignIn" : code === "CODEX_BINARY_UNAVAILABLE" || code === "CODEX_START_TIMEOUT" ? "codexUnavailableBinary" : "codexUnavailableGeneric";
712
+ }
713
+ var defaultPreferredTransports = ["lan", "p2p", "turn", "relay"], controlRouteBackoffStepsMs = [1e3, 2e3, 5e3, 1e4, 3e4], ControlRouteUnavailableError = class extends Error {
2296
714
  constructor(message) {
2297
715
  super(message), this.name = "ControlRouteUnavailableError";
2298
716
  }
@@ -2397,7 +815,44 @@ Minimum version required to store current data is: ` + bestVersion + `.
2397
815
  };
2398
816
  }
2399
817
  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");
818
+ 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");
819
+ }
820
+ var localisedRemoteCodes = /* @__PURE__ */ new Set([
821
+ "ACCOUNT_AUTH_REQUIRED",
822
+ "AUTH_INVALID",
823
+ "TOKEN_EXPIRED",
824
+ "MEMBERSHIP_REQUIRED",
825
+ "CONNECTION_REPLACED",
826
+ "CONTROL_DISABLED",
827
+ "HOST_OFFLINE",
828
+ "SERVER_CREDENTIALS_BUSY",
829
+ "DEVICE_REVOKED",
830
+ "DEVICE_OWNERSHIP_REQUIRED",
831
+ "RATE_LIMITED",
832
+ "UNSUPPORTED_VERSION",
833
+ "CONNECTION_FAILED",
834
+ "SERVER_NOT_CONFIGURED",
835
+ "CODEX_DISABLED",
836
+ "CODEX_NOT_PROVIDED",
837
+ "CODEX_UNAVAILABLE"
838
+ ]);
839
+ function controlFailure(error, t) {
840
+ let code = error?.details?.remoteCode;
841
+ return Object.assign(new Error(error?.message ?? t("remoteRequestFailed")), {
842
+ ...code === void 0 ? {} : { code },
843
+ retryable: error?.details?.retryable === !0
844
+ });
845
+ }
846
+ function remoteErrorMessage(reason, t) {
847
+ let code = reason instanceof Error && "code" in reason && typeof reason.code == "string" ? reason.code : void 0;
848
+ if (code !== void 0) {
849
+ if (code === "MEMBERSHIP_REQUIRED") return t("connectionOwnershipRequired");
850
+ if (code === "CODEX_DISABLED") return t("codexRemoteOff");
851
+ if (code === "CODEX_NOT_PROVIDED") return t("codexRemoteNotProvided");
852
+ if (code === "CODEX_UNAVAILABLE") return t("codexRemoteUnavailable");
853
+ if (localisedRemoteCodes.has(code)) return connectionErrorMessage(code, t);
854
+ }
855
+ return reason instanceof Error ? reason.message : String(reason);
2401
856
  }
2402
857
  async function setDeviceControl(control, enabled, authorized) {
2403
858
  return enabled && !authorized ? await control("host.authorization.set", { enabled: !0 }) : await control("host.connection.set", { connected: enabled });
@@ -2489,8 +944,8 @@ Minimum version required to store current data is: ` + bestVersion + `.
2489
944
  }
2490
945
  }
2491
946
  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) => {
2493
- 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);
947
+ 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) => {
948
+ setSettingsView(view), setServerUrl(view.config.serverUrl ?? DEFAULT_REMOTE_SERVER_URL), setCodexEnabled(view.config.codex?.enabled ?? !1), 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
949
  }, load = async () => {
2495
950
  let [view, status] = await Promise.all([
2496
951
  props.control("settings.get"),
@@ -2525,7 +980,7 @@ Minimum version required to store current data is: ` + bestVersion + `.
2525
980
  setBusy(!0), setError(void 0), setNotice(void 0);
2526
981
  try {
2527
982
  let view = await props.control("settings.logout");
2528
- applyView(view), setRegistrationCode(""), setNotice({ key: view.deepseekSignedOut === !0 ? "signedOutDeepseek" : "signedOut" });
983
+ applyView(view), setNotice({ key: view.deepseekSignedOut === !0 ? "signedOutDeepseek" : "signedOut" });
2529
984
  } catch (reason) {
2530
985
  setError(messageOf(reason));
2531
986
  } finally {
@@ -2633,7 +1088,7 @@ Minimum version required to store current data is: ` + bestVersion + `.
2633
1088
  setBusy(!1);
2634
1089
  }
2635
1090
  }, discard = () => {
2636
- settingsView !== void 0 && applyView(settingsView), setRegistrationCode(""), setNotice(void 0), setError(void 0);
1091
+ settingsView !== void 0 && applyView(settingsView), setNotice(void 0), setError(void 0);
2637
1092
  }, developmentSetting = React.createElement(
2638
1093
  "section",
2639
1094
  { className: "dshRemoteDevelopmentSettings" },
@@ -2678,62 +1133,25 @@ Minimum version required to store current data is: ` + bestVersion + `.
2678
1133
  ),
2679
1134
  React.createElement("small", null, t("previewPortsHint"))
2680
1135
  )
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(
1136
+ ), 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, {
1137
+ t,
1138
+ enabled: codexEnabled,
1139
+ onEnabledChange: (next) => void setCodexRemote(next),
1140
+ busy: busy || codexBusy,
1141
+ writable,
1142
+ unavailable: codexUnavailable,
1143
+ state: codexDomainStatus?.state,
1144
+ reasonCode: codexDomainStatus?.error,
1145
+ editable: codexBinaryEditable,
1146
+ pinned: codexBinaryPinned,
1147
+ discovered: codexBinaryDiscovered,
1148
+ value: codexBinary,
1149
+ onValueChange: (next) => setCodexBinary(next),
1150
+ onConfirm: () => void setCodexBinaryPath(codexBinary),
1151
+ onUseAuto: () => {
1152
+ setCodexBinary(""), setCodexBinaryPath("");
1153
+ }
1154
+ }), acpSetting = React.createElement(
2737
1155
  "details",
2738
1156
  { className: "dshRemoteAuthorizationSetting dshRemoteAcpSetting" },
2739
1157
  React.createElement(
@@ -2908,7 +1326,9 @@ Minimum version required to store current data is: ` + bestVersion + `.
2908
1326
  React.createElement("button", {
2909
1327
  type: "button",
2910
1328
  className: "dshRemoteReconnect",
2911
- disabled: reconnectBusy || hostStatus?.configured === !1,
1329
+ // A paused Host is not a broken one: there is nothing to reconnect, and the switch is the
1330
+ // only control that may turn reachability back on.
1331
+ disabled: reconnectBusy || hostStatus?.configured === !1 || hostStatus?.paused === !0,
2912
1332
  onClick: () => void reconnectHost()
2913
1333
  }, t(reconnectBusy ? "reconnectingAction" : "reconnect"))
2914
1334
  ),
@@ -2990,9 +1410,9 @@ Minimum version required to store current data is: ` + bestVersion + `.
2990
1410
  );
2991
1411
  }
2992
1412
  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(
1413
+ 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
1414
  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);
1415
+ ), [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
1416
  React.useEffect(() => {
2997
1417
  open || setDevicesOpen(!1);
2998
1418
  }, [open]), React.useEffect(() => {
@@ -3039,13 +1459,9 @@ Minimum version required to store current data is: ` + bestVersion + `.
3039
1459
  let run = ++qrFlowRun.current;
3040
1460
  setBusy(!0), setError(void 0), setQrExpired(!1);
3041
1461
  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
- });
1462
+ let session = await props.control("client.account.qr.start", { provider });
3047
1463
  if (run !== qrFlowRun.current) return;
3048
- setQrSession(session), setQrImage(image);
1464
+ setQrSession(session);
3049
1465
  } catch (reason) {
3050
1466
  run === qrFlowRun.current && setError(messageOf(reason));
3051
1467
  } finally {
@@ -3070,9 +1486,9 @@ Minimum version required to store current data is: ` + bestVersion + `.
3070
1486
  } catch (reason) {
3071
1487
  active && run === qrFlowRun.current && setError(messageOf(reason));
3072
1488
  } finally {
3073
- run === qrFlowRun.current && (setQrSession(void 0), setQrImage(void 0), setBusy(!1));
1489
+ run === qrFlowRun.current && (setQrSession(void 0), setBusy(!1));
3074
1490
  }
3075
- } else result.status === "expired" && (settled = !0, timer !== void 0 && window.clearInterval(timer), setQrExpired(!0), setQrSession(void 0), setQrImage(void 0));
1491
+ } else result.status === "expired" && (settled = !0, timer !== void 0 && window.clearInterval(timer), setQrExpired(!0), setQrSession(void 0));
3076
1492
  }).catch((reason) => {
3077
1493
  active && !settled && run === qrFlowRun.current && setError(messageOf(reason));
3078
1494
  }).finally(() => {
@@ -3082,23 +1498,9 @@ Minimum version required to store current data is: ` + bestVersion + `.
3082
1498
  return poll(), timer = window.setInterval(poll, 1500), () => {
3083
1499
  active = !1, timer !== void 0 && window.clearInterval(timer);
3084
1500
  };
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);
1501
+ }, [open, loginMethod, qrSession]);
1502
+ let selectHost = async (host) => {
1503
+ setBusy(!0), setError(void 0), setConnectingHost(host), setCodexWorkspaces([]), setCodexNotice(void 0), setShowAllWorkspaces(!1), setShowAllCodexWorkspaces(!1);
3102
1504
  try {
3103
1505
  let result = await runConnectHostProgress(
3104
1506
  status?.preferredTransports,
@@ -3110,21 +1512,38 @@ Minimum version required to store current data is: ` + bestVersion + `.
3110
1512
  async () => {
3111
1513
  let nextWorkspaces = await props.control("workspaces.list", {
3112
1514
  targetDeviceId: host.deviceId
3113
- }), nextCodexWorkspaces = await props.control("codex.workspaces.list", {
1515
+ }), codexReason, nextCodexWorkspaces = await props.control("codex.workspaces.list", {
3114
1516
  targetDeviceId: host.deviceId
3115
- }).catch(() => []), nextStatus = await props.control("status").catch(() => {
1517
+ }).catch((reason) => (codexReason = remoteErrorMessage(reason, t), [])), nextStatus = await props.control("status").catch(() => {
3116
1518
  });
3117
- return nextStatus !== void 0 && setStatus(nextStatus), { workspaces: nextWorkspaces, codexWorkspaces: nextCodexWorkspaces, status: nextStatus };
1519
+ return nextStatus !== void 0 && setStatus(nextStatus), setCodexNotice(codexReason), { workspaces: nextWorkspaces, codexWorkspaces: nextCodexWorkspaces, status: nextStatus };
3118
1520
  },
3119
1521
  (result2) => connectedProgress(result2.status)
3120
1522
  );
3121
- setWorkspaces(result.workspaces), setCodexWorkspaces(result.codexWorkspaces), setWorkspaceBackend("harness"), setCodexWorkspaceId(void 0), setSelectedHost(host), setPath(""), setAddingWorkspace(!1), setDirectory(void 0);
1523
+ 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
1524
  } catch (reason) {
3123
- setError(messageOf(reason));
1525
+ setError(remoteErrorMessage(reason, t));
3124
1526
  } finally {
3125
1527
  setConnectingHost(void 0), setBusy(!1);
3126
1528
  }
3127
- }, browseDirectory = async (nextPath) => {
1529
+ };
1530
+ async function loadHarnessWorkspaces(host) {
1531
+ try {
1532
+ setWorkspaces(await props.control("workspaces.list", { targetDeviceId: host.deviceId }));
1533
+ } catch (reason) {
1534
+ setError(remoteErrorMessage(reason, t));
1535
+ }
1536
+ }
1537
+ async function loadCodexWorkspaces(host) {
1538
+ try {
1539
+ setCodexWorkspaces(await props.control("codex.workspaces.list", {
1540
+ targetDeviceId: host.deviceId
1541
+ })), setCodexNotice(void 0), setCodexAvailable(!0);
1542
+ } catch (reason) {
1543
+ setCodexWorkspaces([]), setCodexNotice(remoteErrorMessage(reason, t)), setCodexAvailable(!1);
1544
+ }
1545
+ }
1546
+ let browseDirectory = async (nextPath) => {
3128
1547
  if (selectedHost !== void 0) {
3129
1548
  setBusy(!0), setError(void 0);
3130
1549
  try {
@@ -3134,7 +1553,7 @@ Minimum version required to store current data is: ` + bestVersion + `.
3134
1553
  });
3135
1554
  setDirectory(listing), setCodexWorkspaceId(void 0), setPath(listing.path);
3136
1555
  } catch (reason) {
3137
- setError(messageOf(reason));
1556
+ setError(remoteErrorMessage(reason, t));
3138
1557
  } finally {
3139
1558
  setBusy(!1);
3140
1559
  }
@@ -3144,16 +1563,19 @@ Minimum version required to store current data is: ` + bestVersion + `.
3144
1563
  }, cancelAddingWorkspace = () => {
3145
1564
  setAddingWorkspace(!1), setWorkspaceBackend("harness"), setCodexWorkspaceId(void 0), setDirectory(void 0), setPath("");
3146
1565
  }, refreshRemote = async () => {
3147
- setBusy(!0), setNotice(void 0), setError(void 0);
1566
+ setBusy(!0), setNotice(void 0), setError(void 0), props.control("settings.get").then(async (view) => {
1567
+ view.config.codex?.enabled !== !1 && view.codexStatus?.available !== !0 && await props.control("settings.codex.set", { enabled: !0 });
1568
+ }).catch(() => {
1569
+ });
3148
1570
  try {
3149
1571
  let nextStatus = await props.control("status");
3150
1572
  if (setStatus(nextStatus), !nextStatus.available) {
3151
1573
  setDevices([]), setNeedsAuthorization(!1), setAuthorizationResolved(!0), setSelectedHost(void 0), setWorkspaces([]), setCodexWorkspaces([]), setShowAllWorkspaces(!1), setShowAllCodexWorkspaces(!1), setWorkspaceBackend("harness"), setCodexWorkspaceId(void 0), setPath(""), setAddingWorkspace(!1), setDirectory(void 0);
3152
1574
  return;
3153
1575
  }
1576
+ let storedLocally;
3154
1577
  try {
3155
- let local = await props.control("authorization.local");
3156
- setNeedsAuthorization(local?.stored !== !0);
1578
+ storedLocally = (await props.control("authorization.local"))?.stored === !0, setNeedsAuthorization(!storedLocally);
3157
1579
  } catch {
3158
1580
  setNeedsAuthorization(!1);
3159
1581
  } finally {
@@ -3161,15 +1583,17 @@ Minimum version required to store current data is: ` + bestVersion + `.
3161
1583
  }
3162
1584
  try {
3163
1585
  let nextDevices = await props.control("devices");
3164
- if (setDevices(nextDevices), setNeedsAuthorization(!1), selectedHost !== void 0) {
1586
+ if (setDevices(nextDevices), storedLocally !== void 0 && setNeedsAuthorization(authorizationStillNeeded(storedLocally, nextDevices.length)), selectedHost !== void 0) {
3165
1587
  let nextSelectedHost = nextDevices.find((device) => device.deviceId === selectedHost.deviceId);
3166
1588
  nextSelectedHost === void 0 ? (setSelectedHost(void 0), setWorkspaces([]), setCodexWorkspaces([]), setShowAllWorkspaces(!1), setShowAllCodexWorkspaces(!1), setWorkspaceBackend("harness"), setCodexWorkspaceId(void 0), setPath(""), setAddingWorkspace(!1), setDirectory(void 0)) : setSelectedHost(nextSelectedHost);
3167
1589
  }
3168
1590
  } catch {
3169
1591
  setDevices([]), setNeedsAuthorization(!0), setSelectedHost(void 0), setWorkspaces([]), setCodexWorkspaces([]), setShowAllWorkspaces(!1), setShowAllCodexWorkspaces(!1), setWorkspaceBackend("harness"), setCodexWorkspaceId(void 0), setPath(""), setAddingWorkspace(!1), setDirectory(void 0);
3170
1592
  }
1593
+ selectedHost !== void 0 && (await props.control("remote.session.recover").then((next) => setStatus(next)).catch(() => {
1594
+ }), await Promise.all([loadHarnessWorkspaces(selectedHost), loadCodexWorkspaces(selectedHost)]));
3171
1595
  } catch (reason) {
3172
- setError(messageOf(reason)), setAuthorizationResolved(!0);
1596
+ setError(remoteErrorMessage(reason, t)), setAuthorizationResolved(!0);
3173
1597
  } finally {
3174
1598
  setBusy(!1);
3175
1599
  }
@@ -3179,12 +1603,31 @@ Minimum version required to store current data is: ` + bestVersion + `.
3179
1603
  React.useEffect(() => {
3180
1604
  if (!(!open || selectedHost !== void 0))
3181
1605
  return props.statusFeed.subscribe(setStatus);
1606
+ }, [open, selectedHost]), React.useEffect(() => {
1607
+ if (!open || selectedHost === void 0) return;
1608
+ let cancelled = !1, probe = async () => {
1609
+ let result = await props.control("remote.features.probe").catch(() => {
1610
+ });
1611
+ if (cancelled || result === void 0 || result.targetDeviceId !== void 0 && result.targetDeviceId !== selectedHost.deviceId) return;
1612
+ let nextStatus = await props.control("status").catch(() => {
1613
+ });
1614
+ if (cancelled) return;
1615
+ nextStatus !== void 0 && setStatus(nextStatus);
1616
+ let available = result.connected === !0 && result.features?.codex === !0;
1617
+ available !== codexProbeAvailable.current && await loadCodexWorkspaces(selectedHost), codexProbeAvailable.current = available;
1618
+ };
1619
+ probe();
1620
+ let timer = window.setInterval(() => void probe(), 5e3);
1621
+ return () => {
1622
+ cancelled = !0, window.clearInterval(timer);
1623
+ };
3182
1624
  }, [open, selectedHost]);
3183
1625
  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);
1626
+ 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
1627
  }, requestDeepSeekSignIn = async () => {
3186
1628
  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",
1629
+ // No `role`: a device has one identity, and the control writes only the Server address plus this
1630
+ // sign-in. Sending a role here was the last thing that made one look like a runtime switch.
3188
1631
  serverUrl: loginServerUrl.trim(),
3189
1632
  provider: "deepseek",
3190
1633
  callbackOrigin,
@@ -3219,9 +1662,9 @@ Minimum version required to store current data is: ` + bestVersion + `.
3219
1662
  if (state.pending) throw new Error(t("deepseekSignInTimeout"));
3220
1663
  } else
3221
1664
  tab?.close();
3222
- setDevices(await props.control("devices")), setStatus(await props.control("status")), setNeedsAuthorization(!1), setAuthorizationResolved(!0), setPassword(""), setNotice(void 0);
1665
+ setDevices(await props.control("devices")), setStatus(await props.control("status")), setNeedsAuthorization(!1), setAuthorizationResolved(!0), setNotice(void 0);
3223
1666
  } catch (reason) {
3224
- setError(messageOf(reason));
1667
+ setError(remoteErrorMessage(reason, t));
3225
1668
  } finally {
3226
1669
  setAwaitingDeepSeek(!1), setPendingAuthorizeUrl(void 0), setBusy(!1);
3227
1670
  }
@@ -3230,23 +1673,32 @@ Minimum version required to store current data is: ` + bestVersion + `.
3230
1673
  try {
3231
1674
  await props.control("mode.set", { mode: "local" }), window.location.reload();
3232
1675
  } catch (reason) {
3233
- setError(messageOf(reason)), setBusy(!1);
1676
+ setError(remoteErrorMessage(reason, t)), setBusy(!1);
3234
1677
  }
3235
1678
  }, setCurrentDeviceControl = async (enabled) => {
3236
1679
  setBusy(!0), setError(void 0);
3237
1680
  try {
3238
1681
  setStatus(await setDeviceControl(props.control, enabled, status?.host?.authorized === !0));
3239
1682
  } catch (reason) {
3240
- setError(messageOf(reason));
1683
+ setError(remoteErrorMessage(reason, t));
3241
1684
  } finally {
3242
1685
  setBusy(!1);
3243
1686
  }
1687
+ }, revokeRemote = async () => {
1688
+ setBusy(!0), setError(void 0), setNotice(void 0);
1689
+ try {
1690
+ await props.control("client.device.revoke"), setDevices([]), setNeedsAuthorization(!0), setStatus(await props.control("status"));
1691
+ } catch (reason) {
1692
+ setError(remoteErrorMessage(reason, t));
1693
+ } finally {
1694
+ setConfirmingRevoke(!1), setBusy(!1);
1695
+ }
3244
1696
  }, logoutRemote = async () => {
3245
1697
  setBusy(!0), setError(void 0), setNotice(void 0);
3246
1698
  try {
3247
- await props.control("settings.logout"), setDevices([]), setNeedsAuthorization(!0), setQrSession(void 0), setQrImage(void 0), setQrExpired(!1), setStatus(await props.control("status"));
1699
+ await props.control("settings.logout"), setDevices([]), setNeedsAuthorization(!0), setQrSession(void 0), setQrExpired(!1), setStatus(await props.control("status"));
3248
1700
  } catch (reason) {
3249
- setError(messageOf(reason));
1701
+ setError(remoteErrorMessage(reason, t));
3250
1702
  } finally {
3251
1703
  setConfirmingSignOut(!1), setBusy(!1);
3252
1704
  }
@@ -3267,10 +1719,10 @@ Minimum version required to store current data is: ` + bestVersion + `.
3267
1719
  }));
3268
1720
  setStatus(nextStatus), nextStatus.workspaceSelection !== void 0 && window.sessionStorage.setItem(pendingWorkspaceSelectionKey, JSON.stringify(nextStatus.workspaceSelection)), window.location.reload();
3269
1721
  } catch (reason) {
3270
- setError(messageOf(reason)), setBusy(!1);
1722
+ setError(remoteErrorMessage(reason, t)), setBusy(!1);
3271
1723
  }
3272
1724
  }
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 : [
1725
+ }, 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
1726
  formatPlatform(selectedHost.platform),
3275
1727
  selectedHost.harnessVersion === void 0 ? void 0 : t("harnessVersion", { version: selectedHost.harnessVersion }),
3276
1728
  selectedHost.clientVersion === void 0 ? void 0 : t("pluginVersion", { version: selectedHost.clientVersion })
@@ -3496,9 +1948,29 @@ Minimum version required to store current data is: ` + bestVersion + `.
3496
1948
  onChange: (event) => void setCurrentDeviceControl(event.target.checked)
3497
1949
  })
3498
1950
  ) : null,
1951
+ React.createElement(
1952
+ "div",
1953
+ { className: "dshRemotePageActions" },
1954
+ React.createElement("button", {
1955
+ type: "button",
1956
+ className: "dshRemotePageRefresh",
1957
+ disabled: busy,
1958
+ // Match the "allow control" label exactly: 12px/18px in the secondary label colour, so it
1959
+ // reads as the same kind of control instead of a page-level action.
1960
+ style: { fontWeight: "normal", fontSize: "12px", lineHeight: "18px", height: "auto", minWidth: "0", padding: "0 4px", color: "var(--dsw-alias-label-secondary)" },
1961
+ title: t("codexRemote"),
1962
+ "aria-label": t("codexRemote"),
1963
+ onClick: () => setCodexOpen(!0)
1964
+ }, t("codexRemote"))
1965
+ ),
3499
1966
  connectedMenu
3500
1967
  )
3501
1968
  ),
1969
+ codexOpen ? React.createElement(CodexConnectionDetails, {
1970
+ control: props.control,
1971
+ t,
1972
+ onClose: () => setCodexOpen(!1)
1973
+ }) : null,
3502
1974
  React.createElement("div", {
3503
1975
  className: `dshRemoteHostList${connectingHost === void 0 ? "" : " isCollapsed"}`,
3504
1976
  "aria-busy": connectingHost === void 0 ? void 0 : !0
@@ -3521,7 +1993,7 @@ Minimum version required to store current data is: ` + bestVersion + `.
3521
1993
  device.clientVersion === void 0 ? void 0 : t("pluginVersion", { version: device.clientVersion })
3522
1994
  ].filter(Boolean).join(" \xB7 "))
3523
1995
  ),
3524
- React.createElement("small", null, t(device.online ? "online" : "offline"))
1996
+ React.createElement("small", null, [t(device.online ? "online" : "offline"), device.hostControl === !1 ? t("hostRefusesControl") : void 0].filter(Boolean).join(" \xB7 "))
3525
1997
  )))
3526
1998
  ) : null,
3527
1999
  React.createElement(RemoteProgressView, { progress, t }),
@@ -3531,7 +2003,7 @@ Minimum version required to store current data is: ` + bestVersion + `.
3531
2003
  React.createElement(
3532
2004
  "p",
3533
2005
  { className: "dshRemoteHint" },
3534
- t(confirmingSignOut ? "signOutImpact" : "selectHostHint")
2006
+ t(confirmingRevoke ? "revokeDeviceImpact" : confirmingSignOut ? "signOutImpact" : "selectHostHint")
3535
2007
  ),
3536
2008
  React.createElement(
3537
2009
  "footer",
@@ -3555,6 +2027,27 @@ Minimum version required to store current data is: ` + bestVersion + `.
3555
2027
  React.Fragment,
3556
2028
  null,
3557
2029
  React.createElement("span", null, status?.host?.account ?? t("account")),
2030
+ confirmingRevoke ? React.createElement(
2031
+ React.Fragment,
2032
+ null,
2033
+ React.createElement("button", {
2034
+ type: "button",
2035
+ className: "dshRemoteDiscard",
2036
+ disabled: busy,
2037
+ onClick: () => setConfirmingRevoke(!1)
2038
+ }, t("cancel")),
2039
+ React.createElement("button", {
2040
+ type: "button",
2041
+ className: "dshRemoteAccountExit",
2042
+ disabled: busy,
2043
+ onClick: () => void revokeRemote()
2044
+ }, t("revokeThisDevice"))
2045
+ ) : React.createElement("button", {
2046
+ type: "button",
2047
+ className: "dshRemoteAccountExit",
2048
+ disabled: busy,
2049
+ onClick: () => setConfirmingRevoke(!0)
2050
+ }, t("revokeThisDevice")),
3558
2051
  React.createElement("button", {
3559
2052
  type: "button",
3560
2053
  className: "dshRemoteAccountExit",
@@ -3649,7 +2142,7 @@ Minimum version required to store current data is: ` + bestVersion + `.
3649
2142
  }, React.createElement("span", { "aria-hidden": !0 }, "\u2026"))
3650
2143
  )
3651
2144
  ),
3652
- !codexAvailable && codexWorkspaces.length === 0 ? null : React.createElement(
2145
+ React.createElement(
3653
2146
  "section",
3654
2147
  { className: "dshRemoteCodexWorkspaceGroup" },
3655
2148
  React.createElement(
@@ -3681,7 +2174,7 @@ Minimum version required to store current data is: ` + bestVersion + `.
3681
2174
  id: codexWorkspaceListId,
3682
2175
  className: "dshRemoteDirectoryList dshRemoteCodexWorkspaceList",
3683
2176
  "aria-labelledby": codexWorkspaceHeadingId
3684
- }, visibleCodexWorkspaces.length === 0 ? React.createElement("p", null, t("noCodexWorkspaces")) : visibleCodexWorkspaces.map((workspace) => React.createElement(
2177
+ }, visibleCodexWorkspaces.length === 0 ? React.createElement("p", null, codexNotice ?? t("noCodexWorkspaces")) : visibleCodexWorkspaces.map((workspace) => React.createElement(
3685
2178
  "button",
3686
2179
  {
3687
2180
  type: "button",
@@ -3731,153 +2224,162 @@ Minimum version required to store current data is: ` + bestVersion + `.
3731
2224
  )) : null
3732
2225
  );
3733
2226
  }
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
- };
2227
+ function CodexConnectionFields(props) {
2228
+ let { t, busy, writable, unavailable, editable, pinned, discovered, value } = props;
2229
+ return React.createElement(
2230
+ React.Fragment,
2231
+ null,
2232
+ React.createElement(
2233
+ "div",
2234
+ { className: "dshRemoteAuthorizationSetting" },
2235
+ React.createElement(
2236
+ "div",
2237
+ null,
2238
+ React.createElement("span", null, t("codexControlAllow"))
2239
+ ),
2240
+ React.createElement("input", {
2241
+ type: "checkbox",
2242
+ role: "switch",
2243
+ // Only greyed out while it is ON and the domain cannot run. A switched-off Codex also reports
2244
+ // available:false - that is the off state, not a failure - so treating it as "unavailable" locked the
2245
+ // switch and left no way to turn Codex back on.
2246
+ disabled: busy || !writable || unavailable && props.enabled,
2247
+ "aria-label": t("codexRemote"),
2248
+ checked: props.enabled,
2249
+ onChange: (event) => props.onEnabledChange(event.target.checked)
2250
+ })
2251
+ ),
2252
+ // A disabled Codex is a choice, not a fault, and neither is a launch in progress: available is false while the
2253
+ // domain starts, which used to paint a red line reading UNKNOWN for the couple of seconds every switch takes.
2254
+ // Red is for a real failure only, and a failure that carries no code says so in words instead of printing
2255
+ // UNKNOWN as if it were a code.
2256
+ 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")),
2257
+ React.createElement(
2258
+ "div",
2259
+ { className: "dshRemoteCodexBinary" },
2260
+ React.createElement("input", {
2261
+ type: "text",
2262
+ value: editable ? value : discovered ?? "",
2263
+ readOnly: !editable,
2264
+ // Never disabled for being unwritable: when the CLI cannot start, this field is the only way out, and a
2265
+ // failed save reports itself in the dialog instead of leaving the user with a dead control.
2266
+ disabled: busy,
2267
+ className: editable ? "" : "isDiscovered",
2268
+ placeholder: editable ? t("codexBinaryPlaceholder") : void 0,
2269
+ "aria-label": t("codexBinaryLabel"),
2270
+ onChange: (event) => props.onValueChange(event.target.value),
2271
+ onKeyDown: (event) => {
2272
+ event.key === "Enter" && editable && props.onConfirm();
2273
+ }
2274
+ }),
2275
+ editable ? React.createElement("button", {
2276
+ type: "button",
2277
+ className: "dshRemoteDiscard",
2278
+ disabled: busy,
2279
+ onClick: () => props.onConfirm()
2280
+ }, t("codexBinaryConfirm")) : null,
2281
+ pinned ? React.createElement("button", {
2282
+ type: "button",
2283
+ className: "dshRemoteDiscard",
2284
+ disabled: busy,
2285
+ onClick: () => props.onUseAuto()
2286
+ }, t("codexBinaryAuto")) : null,
2287
+ pinned || discovered === void 0 ? React.createElement("p", null, t(pinned ? "codexBinaryPinned" : "codexBinaryMissing")) : null
2288
+ )
2289
+ );
2290
+ }
2291
+ function CodexConnectionDetails(props) {
2292
+ 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
2293
  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);
2294
+ let cancelled = !1;
2295
+ return (async () => {
3772
2296
  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);
2297
+ let loaded = await control("settings.get");
2298
+ if (cancelled) return;
2299
+ setView(loaded), setEnabled(loaded.config.codex?.enabled ?? !1), setBinary(loaded.config.codex?.binary ?? "codex");
2300
+ } catch (cause) {
2301
+ cancelled || setError(cause instanceof Error ? cause.message : String(cause));
3789
2302
  }
2303
+ })(), () => {
2304
+ cancelled = !0;
2305
+ };
2306
+ }, [control]);
2307
+ let status = view?.codexStatus, unavailable = status !== void 0 && status.available === !1, settledState = status?.state;
2308
+ React.useEffect(() => {
2309
+ if (view === void 0 || busy || settledState === "ready" || settledState === "disabled") return;
2310
+ let timer = setInterval(() => {
2311
+ control("settings.get").then((next) => {
2312
+ setView(next), setEnabled(next.config.codex?.enabled ?? !1), setBinary(next.config.codex?.binary ?? "codex");
2313
+ }).catch(() => {
2314
+ });
2315
+ }, 2e3);
2316
+ return () => {
2317
+ clearInterval(timer);
2318
+ };
2319
+ }, [control, view, busy, settledState]);
2320
+ 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) => {
2321
+ setBusy(!0), setError(void 0);
2322
+ try {
2323
+ let updated = await control("settings.codex.set", {
2324
+ enabled: next.enabled ?? enabled,
2325
+ ...next.binary === void 0 ? {} : { binary: next.binary }
2326
+ });
2327
+ setView(updated), setEnabled(updated.config.codex?.enabled ?? enabled), setBinary(updated.config.codex?.binary ?? binary);
2328
+ } catch (cause) {
2329
+ setError(cause instanceof Error ? cause.message : String(cause));
2330
+ } finally {
2331
+ setBusy(!1);
3790
2332
  }
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" },
2333
+ };
2334
+ return React.createElement(
2335
+ "div",
2336
+ { className: "dshRemoteBackdrop", role: "presentation" },
2337
+ React.createElement(
2338
+ "section",
2339
+ {
2340
+ className: "dshRemoteDialog",
2341
+ role: "dialog",
2342
+ "aria-modal": !0,
2343
+ "aria-label": t("codexRemote")
2344
+ },
3805
2345
  React.createElement(
3806
- "section",
3807
- {
3808
- className: "dshRemoteDialog",
3809
- role: "dialog",
3810
- "aria-modal": !0,
3811
- "aria-label": t("harnessTarget")
3812
- },
2346
+ "div",
2347
+ { className: "dshRemoteHeader" },
2348
+ React.createElement("strong", null, t("codexRemote")),
2349
+ React.createElement("button", { type: "button", onClick: onClose, "aria-label": t("close") }, "\xD7")
2350
+ ),
2351
+ view === void 0 ? React.createElement("p", { className: "dshRemoteSettingsState" }, error ?? t("loadingSettings")) : React.createElement(
2352
+ React.Fragment,
2353
+ null,
2354
+ React.createElement("p", { className: "dshRemoteSettingsState" }, stateText),
2355
+ React.createElement(CodexConnectionFields, {
2356
+ t,
2357
+ enabled,
2358
+ onEnabledChange: (next) => void save({ enabled: next }),
2359
+ busy,
2360
+ writable,
2361
+ unavailable,
2362
+ state: status?.state,
2363
+ reasonCode: status?.error,
2364
+ editable,
2365
+ pinned,
2366
+ discovered,
2367
+ value: binary,
2368
+ onValueChange: (next) => setBinary(next),
2369
+ onConfirm: () => void save({ binary }),
2370
+ onUseAuto: () => void save({ binary: "" })
2371
+ }),
2372
+ // No confirm button: the switch and the command field save on their own, and a footer button could only
2373
+ // re-send the state the dialog captured when it opened - which is how pressing it turned a starting Codex
2374
+ // back off. The footer keeps the message line and nothing else.
3813
2375
  React.createElement(
3814
2376
  "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)
2377
+ { className: "dshRemoteSettingsFooter" },
2378
+ React.createElement("p", { className: error === void 0 ? "dshRemoteNotice" : "dshRemoteError" }, error ?? "")
2379
+ )
3878
2380
  )
3879
- ) : null
3880
- ) : null;
2381
+ )
2382
+ );
3881
2383
  }
3882
2384
  function RemoteSessionHeaderAction(props) {
3883
2385
  let { t } = props, status = React.useSyncExternalStore(
@@ -3916,7 +2418,14 @@ Minimum version required to store current data is: ` + bestVersion + `.
3916
2418
  strokeLinejoin: "round",
3917
2419
  "aria-hidden": !0
3918
2420
  }, 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")),
2421
+ // The label names the session being recovered when one is, because a Codex recovery has already
2422
+ // switched the carriers to the local shell by then; reading the kind off `backend` alone said
2423
+ // "remote DSH, reconnecting" for a Codex session.
2424
+ React.createElement(
2425
+ "span",
2426
+ { className: "dshRemoteModePrefix" },
2427
+ t((status.reconnecting?.kind ?? status.backend) === "codex" ? "remoteModeCodex" : "remoteModeDsh")
2428
+ ),
3920
2429
  React.createElement(
3921
2430
  "span",
3922
2431
  { className: "dshRemoteSessionTarget" },
@@ -4156,7 +2665,7 @@ Minimum version required to store current data is: ` + bestVersion + `.
4156
2665
  if (controlRouteBackoffIndex += 1, controlRouteRetryAfter = Date.now() + delayMs, endpoint === "status") return controlRouteUnavailableStatus();
4157
2666
  throw new ControlRouteUnavailableError(t("remoteControlUnavailable"));
4158
2667
  }
4159
- if (!result.ok) throw new Error(result.error?.message ?? t("remoteRequestFailed"));
2668
+ if (!result.ok) throw controlFailure(result.error, t);
4160
2669
  return result.value;
4161
2670
  }, statusFeed = createStatusFeed({
4162
2671
  url: STATUS_STREAM_PATH,