@linxin666/dsh-remote-web-ui 0.3.22 → 0.3.24
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.i18n.yaml +2 -2
- package/README.md +4 -0
- package/README.zh.md +4 -0
- package/lib/client.js +193 -20
- package/lib/client.js.map +1 -1
- package/lib/index.js +181 -34
- package/lib/types/client/index.d.ts.map +1 -1
- package/lib/types/client/index.js +13 -18
- package/lib/types/client/mobile-adapt.d.ts.map +1 -1
- package/lib/types/client/mobile-adapt.js +40 -6
- package/lib/types/client/plugin-card-seat.d.ts +97 -0
- package/lib/types/client/plugin-card-seat.d.ts.map +1 -0
- package/lib/types/client/plugin-card-seat.js +141 -0
- package/lib/types/client/remote-channel.d.ts +35 -0
- package/lib/types/client/remote-channel.d.ts.map +1 -1
- package/lib/types/client/remote-channel.js +55 -0
- package/lib/types/console-output.d.ts +41 -0
- package/lib/types/console-output.d.ts.map +1 -0
- package/lib/types/console-output.js +89 -0
- package/lib/types/index.d.ts.map +1 -1
- package/lib/types/index.js +26 -22
- package/lib/types/public-base.d.ts +67 -0
- package/lib/types/public-base.d.ts.map +1 -0
- package/lib/types/public-base.js +110 -0
- package/lib/types/remote-channel-boot.d.ts +5 -2
- package/lib/types/remote-channel-boot.d.ts.map +1 -1
- package/lib/types/remote-channel-boot.js +28 -2
- package/lib/types/remote-channel-rules.d.ts +4 -0
- package/lib/types/remote-channel-rules.d.ts.map +1 -1
- package/lib/types/remote-channel-rules.js +2 -0
- package/lib/types/update.d.ts.map +1 -1
- package/lib/types/update.js +5 -12
- package/package.json +1 -1
- package/src/client/index.ts +13 -17
- package/src/client/mobile-adapt.ts +39 -5
- package/src/client/plugin-card-seat.ts +185 -0
- package/src/client/remote-channel.ts +64 -0
- package/src/console-output.ts +97 -0
- package/src/index.ts +26 -22
- package/src/public-base.ts +122 -0
- package/src/remote-channel-boot.ts +28 -2
- package/src/remote-channel-rules.ts +6 -0
- package/src/update.ts +5 -10
package/lib/client.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.js","names":["React","css","IconCloseOutline16","IconCopyOutline16","IconStopFill16","IconRefreshOutline16","css","IconCloseOutline16","IconRefreshOutline16","css","IconDownloadOutline16","css","css","css","REMOTE_PREFIX","REMOTE_API_PREFIX","css"],"sources":["../../../node_modules/.pnpm/clsx@2.1.1/node_modules/clsx/dist/clsx.mjs","../../../node_modules/.pnpm/qrcode.react@4.2.0_react@18.3.1/node_modules/qrcode.react/lib/esm/index.js","../../../packages/dsh-remote-web-ui/src/client/pair-api.ts","../../../packages/dsh-remote-web-ui/src/client/device-name.ts","../../../packages/dsh-remote-web-ui/src/client/RemotePanel.tsx","../../../packages/dsh-remote-web-ui/src/client/PhoneIcon.tsx","../../../packages/dsh-remote-web-ui/src/client/update-api.ts","../../../packages/dsh-remote-web-ui/src/client/UpdatePanel.tsx","../../../packages/dsh-remote-web-ui/src/client/UpdateEntry.tsx","../../../packages/dsh-remote-web-ui/src/client/RemoteEntry.tsx","../../../packages/dsh-remote-web-ui/src/client/FooterRemoteEntry.tsx","../../../packages/dsh-remote-web-ui/src/client/PairFailedNotice.tsx","../../../packages/dsh-remote-web-ui/src/client/PluginSettingsCard.tsx","../../../packages/dsh-remote-web-ui/src/client/settings-form.ts","../../../packages/dsh-remote-web-ui/src/client/RemoteSettingsCard.tsx","../../../packages/dsh-remote-web-ui/src/client/locales.ts","../../../packages/dsh-remote-web-ui/src/client/deep-link.ts","../../../packages/dsh-remote-web-ui/src/remote-methods.ts","../../../packages/dsh-remote-web-ui/src/remote-channel-rules.ts","../../../packages/dsh-remote-web-ui/src/client/remote-channel.ts","../../../packages/dsh-remote-web-ui/src/client/FenceNotice.tsx","../../../packages/dsh-remote-web-ui/src/client/telemetry.ts","../../../packages/dsh-remote-web-ui/src/client/mobile-adapt.ts","../../../packages/dsh-remote-web-ui/src/client/index.ts"],"sourcesContent":["function r(e){var t,f,n=\"\";if(\"string\"==typeof e||\"number\"==typeof e)n+=e;else if(\"object\"==typeof e)if(Array.isArray(e)){var o=e.length;for(t=0;t<o;t++)e[t]&&(f=r(e[t]))&&(n&&(n+=\" \"),n+=f)}else for(f in e)e[f]&&(n&&(n+=\" \"),n+=f);return n}export function clsx(){for(var e,t,f=0,n=\"\",o=arguments.length;f<o;f++)(e=arguments[f])&&(t=r(e))&&(n&&(n+=\" \"),n+=t);return n}export default clsx;","var __defProp = Object.defineProperty;\nvar __getOwnPropSymbols = Object.getOwnPropertySymbols;\nvar __hasOwnProp = Object.prototype.hasOwnProperty;\nvar __propIsEnum = Object.prototype.propertyIsEnumerable;\nvar __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;\nvar __spreadValues = (a, b) => {\n for (var prop in b || (b = {}))\n if (__hasOwnProp.call(b, prop))\n __defNormalProp(a, prop, b[prop]);\n if (__getOwnPropSymbols)\n for (var prop of __getOwnPropSymbols(b)) {\n if (__propIsEnum.call(b, prop))\n __defNormalProp(a, prop, b[prop]);\n }\n return a;\n};\nvar __objRest = (source, exclude) => {\n var target = {};\n for (var prop in source)\n if (__hasOwnProp.call(source, prop) && exclude.indexOf(prop) < 0)\n target[prop] = source[prop];\n if (source != null && __getOwnPropSymbols)\n for (var prop of __getOwnPropSymbols(source)) {\n if (exclude.indexOf(prop) < 0 && __propIsEnum.call(source, prop))\n target[prop] = source[prop];\n }\n return target;\n};\n\n// src/index.tsx\nimport React from \"react\";\n\n// src/third-party/qrcodegen/index.ts\n/**\n * @license QR Code generator library (TypeScript)\n * Copyright (c) Project Nayuki.\n * SPDX-License-Identifier: MIT\n */\nvar qrcodegen;\n((qrcodegen2) => {\n const _QrCode = class _QrCode {\n /*-- Constructor (low level) and fields --*/\n // Creates a new QR Code with the given version number,\n // error correction level, data codeword bytes, and mask number.\n // This is a low-level API that most users should not use directly.\n // A mid-level API is the encodeSegments() function.\n constructor(version, errorCorrectionLevel, dataCodewords, msk) {\n this.version = version;\n this.errorCorrectionLevel = errorCorrectionLevel;\n // The modules of this QR Code (false = light, true = dark).\n // Immutable after constructor finishes. Accessed through getModule().\n this.modules = [];\n // Indicates function modules that are not subjected to masking. Discarded when constructor finishes.\n this.isFunction = [];\n if (version < _QrCode.MIN_VERSION || version > _QrCode.MAX_VERSION)\n throw new RangeError(\"Version value out of range\");\n if (msk < -1 || msk > 7)\n throw new RangeError(\"Mask value out of range\");\n this.size = version * 4 + 17;\n let row = [];\n for (let i = 0; i < this.size; i++)\n row.push(false);\n for (let i = 0; i < this.size; i++) {\n this.modules.push(row.slice());\n this.isFunction.push(row.slice());\n }\n this.drawFunctionPatterns();\n const allCodewords = this.addEccAndInterleave(dataCodewords);\n this.drawCodewords(allCodewords);\n if (msk == -1) {\n let minPenalty = 1e9;\n for (let i = 0; i < 8; i++) {\n this.applyMask(i);\n this.drawFormatBits(i);\n const penalty = this.getPenaltyScore();\n if (penalty < minPenalty) {\n msk = i;\n minPenalty = penalty;\n }\n this.applyMask(i);\n }\n }\n assert(0 <= msk && msk <= 7);\n this.mask = msk;\n this.applyMask(msk);\n this.drawFormatBits(msk);\n this.isFunction = [];\n }\n /*-- Static factory functions (high level) --*/\n // Returns a QR Code representing the given Unicode text string at the given error correction level.\n // As a conservative upper bound, this function is guaranteed to succeed for strings that have 738 or fewer\n // Unicode code points (not UTF-16 code units) if the low error correction level is used. The smallest possible\n // QR Code version is automatically chosen for the output. The ECC level of the result may be higher than the\n // ecl argument if it can be done without increasing the version.\n static encodeText(text, ecl) {\n const segs = qrcodegen2.QrSegment.makeSegments(text);\n return _QrCode.encodeSegments(segs, ecl);\n }\n // Returns a QR Code representing the given binary data at the given error correction level.\n // This function always encodes using the binary segment mode, not any text mode. The maximum number of\n // bytes allowed is 2953. The smallest possible QR Code version is automatically chosen for the output.\n // The ECC level of the result may be higher than the ecl argument if it can be done without increasing the version.\n static encodeBinary(data, ecl) {\n const seg = qrcodegen2.QrSegment.makeBytes(data);\n return _QrCode.encodeSegments([seg], ecl);\n }\n /*-- Static factory functions (mid level) --*/\n // Returns a QR Code representing the given segments with the given encoding parameters.\n // The smallest possible QR Code version within the given range is automatically\n // chosen for the output. Iff boostEcl is true, then the ECC level of the result\n // may be higher than the ecl argument if it can be done without increasing the\n // version. The mask number is either between 0 to 7 (inclusive) to force that\n // mask, or -1 to automatically choose an appropriate mask (which may be slow).\n // This function allows the user to create a custom sequence of segments that switches\n // between modes (such as alphanumeric and byte) to encode text in less space.\n // This is a mid-level API; the high-level API is encodeText() and encodeBinary().\n static encodeSegments(segs, ecl, minVersion = 1, maxVersion = 40, mask = -1, boostEcl = true) {\n if (!(_QrCode.MIN_VERSION <= minVersion && minVersion <= maxVersion && maxVersion <= _QrCode.MAX_VERSION) || mask < -1 || mask > 7)\n throw new RangeError(\"Invalid value\");\n let version;\n let dataUsedBits;\n for (version = minVersion; ; version++) {\n const dataCapacityBits2 = _QrCode.getNumDataCodewords(version, ecl) * 8;\n const usedBits = QrSegment.getTotalBits(segs, version);\n if (usedBits <= dataCapacityBits2) {\n dataUsedBits = usedBits;\n break;\n }\n if (version >= maxVersion)\n throw new RangeError(\"Data too long\");\n }\n for (const newEcl of [_QrCode.Ecc.MEDIUM, _QrCode.Ecc.QUARTILE, _QrCode.Ecc.HIGH]) {\n if (boostEcl && dataUsedBits <= _QrCode.getNumDataCodewords(version, newEcl) * 8)\n ecl = newEcl;\n }\n let bb = [];\n for (const seg of segs) {\n appendBits(seg.mode.modeBits, 4, bb);\n appendBits(seg.numChars, seg.mode.numCharCountBits(version), bb);\n for (const b of seg.getData())\n bb.push(b);\n }\n assert(bb.length == dataUsedBits);\n const dataCapacityBits = _QrCode.getNumDataCodewords(version, ecl) * 8;\n assert(bb.length <= dataCapacityBits);\n appendBits(0, Math.min(4, dataCapacityBits - bb.length), bb);\n appendBits(0, (8 - bb.length % 8) % 8, bb);\n assert(bb.length % 8 == 0);\n for (let padByte = 236; bb.length < dataCapacityBits; padByte ^= 236 ^ 17)\n appendBits(padByte, 8, bb);\n let dataCodewords = [];\n while (dataCodewords.length * 8 < bb.length)\n dataCodewords.push(0);\n bb.forEach((b, i) => dataCodewords[i >>> 3] |= b << 7 - (i & 7));\n return new _QrCode(version, ecl, dataCodewords, mask);\n }\n /*-- Accessor methods --*/\n // Returns the color of the module (pixel) at the given coordinates, which is false\n // for light or true for dark. The top left corner has the coordinates (x=0, y=0).\n // If the given coordinates are out of bounds, then false (light) is returned.\n getModule(x, y) {\n return 0 <= x && x < this.size && 0 <= y && y < this.size && this.modules[y][x];\n }\n // Modified to expose modules for easy access\n getModules() {\n return this.modules;\n }\n /*-- Private helper methods for constructor: Drawing function modules --*/\n // Reads this object's version field, and draws and marks all function modules.\n drawFunctionPatterns() {\n for (let i = 0; i < this.size; i++) {\n this.setFunctionModule(6, i, i % 2 == 0);\n this.setFunctionModule(i, 6, i % 2 == 0);\n }\n this.drawFinderPattern(3, 3);\n this.drawFinderPattern(this.size - 4, 3);\n this.drawFinderPattern(3, this.size - 4);\n const alignPatPos = this.getAlignmentPatternPositions();\n const numAlign = alignPatPos.length;\n for (let i = 0; i < numAlign; i++) {\n for (let j = 0; j < numAlign; j++) {\n if (!(i == 0 && j == 0 || i == 0 && j == numAlign - 1 || i == numAlign - 1 && j == 0))\n this.drawAlignmentPattern(alignPatPos[i], alignPatPos[j]);\n }\n }\n this.drawFormatBits(0);\n this.drawVersion();\n }\n // Draws two copies of the format bits (with its own error correction code)\n // based on the given mask and this object's error correction level field.\n drawFormatBits(mask) {\n const data = this.errorCorrectionLevel.formatBits << 3 | mask;\n let rem = data;\n for (let i = 0; i < 10; i++)\n rem = rem << 1 ^ (rem >>> 9) * 1335;\n const bits = (data << 10 | rem) ^ 21522;\n assert(bits >>> 15 == 0);\n for (let i = 0; i <= 5; i++)\n this.setFunctionModule(8, i, getBit(bits, i));\n this.setFunctionModule(8, 7, getBit(bits, 6));\n this.setFunctionModule(8, 8, getBit(bits, 7));\n this.setFunctionModule(7, 8, getBit(bits, 8));\n for (let i = 9; i < 15; i++)\n this.setFunctionModule(14 - i, 8, getBit(bits, i));\n for (let i = 0; i < 8; i++)\n this.setFunctionModule(this.size - 1 - i, 8, getBit(bits, i));\n for (let i = 8; i < 15; i++)\n this.setFunctionModule(8, this.size - 15 + i, getBit(bits, i));\n this.setFunctionModule(8, this.size - 8, true);\n }\n // Draws two copies of the version bits (with its own error correction code),\n // based on this object's version field, iff 7 <= version <= 40.\n drawVersion() {\n if (this.version < 7)\n return;\n let rem = this.version;\n for (let i = 0; i < 12; i++)\n rem = rem << 1 ^ (rem >>> 11) * 7973;\n const bits = this.version << 12 | rem;\n assert(bits >>> 18 == 0);\n for (let i = 0; i < 18; i++) {\n const color = getBit(bits, i);\n const a = this.size - 11 + i % 3;\n const b = Math.floor(i / 3);\n this.setFunctionModule(a, b, color);\n this.setFunctionModule(b, a, color);\n }\n }\n // Draws a 9*9 finder pattern including the border separator,\n // with the center module at (x, y). Modules can be out of bounds.\n drawFinderPattern(x, y) {\n for (let dy = -4; dy <= 4; dy++) {\n for (let dx = -4; dx <= 4; dx++) {\n const dist = Math.max(Math.abs(dx), Math.abs(dy));\n const xx = x + dx;\n const yy = y + dy;\n if (0 <= xx && xx < this.size && 0 <= yy && yy < this.size)\n this.setFunctionModule(xx, yy, dist != 2 && dist != 4);\n }\n }\n }\n // Draws a 5*5 alignment pattern, with the center module\n // at (x, y). All modules must be in bounds.\n drawAlignmentPattern(x, y) {\n for (let dy = -2; dy <= 2; dy++) {\n for (let dx = -2; dx <= 2; dx++)\n this.setFunctionModule(x + dx, y + dy, Math.max(Math.abs(dx), Math.abs(dy)) != 1);\n }\n }\n // Sets the color of a module and marks it as a function module.\n // Only used by the constructor. Coordinates must be in bounds.\n setFunctionModule(x, y, isDark) {\n this.modules[y][x] = isDark;\n this.isFunction[y][x] = true;\n }\n /*-- Private helper methods for constructor: Codewords and masking --*/\n // Returns a new byte string representing the given data with the appropriate error correction\n // codewords appended to it, based on this object's version and error correction level.\n addEccAndInterleave(data) {\n const ver = this.version;\n const ecl = this.errorCorrectionLevel;\n if (data.length != _QrCode.getNumDataCodewords(ver, ecl))\n throw new RangeError(\"Invalid argument\");\n const numBlocks = _QrCode.NUM_ERROR_CORRECTION_BLOCKS[ecl.ordinal][ver];\n const blockEccLen = _QrCode.ECC_CODEWORDS_PER_BLOCK[ecl.ordinal][ver];\n const rawCodewords = Math.floor(_QrCode.getNumRawDataModules(ver) / 8);\n const numShortBlocks = numBlocks - rawCodewords % numBlocks;\n const shortBlockLen = Math.floor(rawCodewords / numBlocks);\n let blocks = [];\n const rsDiv = _QrCode.reedSolomonComputeDivisor(blockEccLen);\n for (let i = 0, k = 0; i < numBlocks; i++) {\n let dat = data.slice(k, k + shortBlockLen - blockEccLen + (i < numShortBlocks ? 0 : 1));\n k += dat.length;\n const ecc = _QrCode.reedSolomonComputeRemainder(dat, rsDiv);\n if (i < numShortBlocks)\n dat.push(0);\n blocks.push(dat.concat(ecc));\n }\n let result = [];\n for (let i = 0; i < blocks[0].length; i++) {\n blocks.forEach((block, j) => {\n if (i != shortBlockLen - blockEccLen || j >= numShortBlocks)\n result.push(block[i]);\n });\n }\n assert(result.length == rawCodewords);\n return result;\n }\n // Draws the given sequence of 8-bit codewords (data and error correction) onto the entire\n // data area of this QR Code. Function modules need to be marked off before this is called.\n drawCodewords(data) {\n if (data.length != Math.floor(_QrCode.getNumRawDataModules(this.version) / 8))\n throw new RangeError(\"Invalid argument\");\n let i = 0;\n for (let right = this.size - 1; right >= 1; right -= 2) {\n if (right == 6)\n right = 5;\n for (let vert = 0; vert < this.size; vert++) {\n for (let j = 0; j < 2; j++) {\n const x = right - j;\n const upward = (right + 1 & 2) == 0;\n const y = upward ? this.size - 1 - vert : vert;\n if (!this.isFunction[y][x] && i < data.length * 8) {\n this.modules[y][x] = getBit(data[i >>> 3], 7 - (i & 7));\n i++;\n }\n }\n }\n }\n assert(i == data.length * 8);\n }\n // XORs the codeword modules in this QR Code with the given mask pattern.\n // The function modules must be marked and the codeword bits must be drawn\n // before masking. Due to the arithmetic of XOR, calling applyMask() with\n // the same mask value a second time will undo the mask. A final well-formed\n // QR Code needs exactly one (not zero, two, etc.) mask applied.\n applyMask(mask) {\n if (mask < 0 || mask > 7)\n throw new RangeError(\"Mask value out of range\");\n for (let y = 0; y < this.size; y++) {\n for (let x = 0; x < this.size; x++) {\n let invert;\n switch (mask) {\n case 0:\n invert = (x + y) % 2 == 0;\n break;\n case 1:\n invert = y % 2 == 0;\n break;\n case 2:\n invert = x % 3 == 0;\n break;\n case 3:\n invert = (x + y) % 3 == 0;\n break;\n case 4:\n invert = (Math.floor(x / 3) + Math.floor(y / 2)) % 2 == 0;\n break;\n case 5:\n invert = x * y % 2 + x * y % 3 == 0;\n break;\n case 6:\n invert = (x * y % 2 + x * y % 3) % 2 == 0;\n break;\n case 7:\n invert = ((x + y) % 2 + x * y % 3) % 2 == 0;\n break;\n default:\n throw new Error(\"Unreachable\");\n }\n if (!this.isFunction[y][x] && invert)\n this.modules[y][x] = !this.modules[y][x];\n }\n }\n }\n // Calculates and returns the penalty score based on state of this QR Code's current modules.\n // This is used by the automatic mask choice algorithm to find the mask pattern that yields the lowest score.\n getPenaltyScore() {\n let result = 0;\n for (let y = 0; y < this.size; y++) {\n let runColor = false;\n let runX = 0;\n let runHistory = [0, 0, 0, 0, 0, 0, 0];\n for (let x = 0; x < this.size; x++) {\n if (this.modules[y][x] == runColor) {\n runX++;\n if (runX == 5)\n result += _QrCode.PENALTY_N1;\n else if (runX > 5)\n result++;\n } else {\n this.finderPenaltyAddHistory(runX, runHistory);\n if (!runColor)\n result += this.finderPenaltyCountPatterns(runHistory) * _QrCode.PENALTY_N3;\n runColor = this.modules[y][x];\n runX = 1;\n }\n }\n result += this.finderPenaltyTerminateAndCount(runColor, runX, runHistory) * _QrCode.PENALTY_N3;\n }\n for (let x = 0; x < this.size; x++) {\n let runColor = false;\n let runY = 0;\n let runHistory = [0, 0, 0, 0, 0, 0, 0];\n for (let y = 0; y < this.size; y++) {\n if (this.modules[y][x] == runColor) {\n runY++;\n if (runY == 5)\n result += _QrCode.PENALTY_N1;\n else if (runY > 5)\n result++;\n } else {\n this.finderPenaltyAddHistory(runY, runHistory);\n if (!runColor)\n result += this.finderPenaltyCountPatterns(runHistory) * _QrCode.PENALTY_N3;\n runColor = this.modules[y][x];\n runY = 1;\n }\n }\n result += this.finderPenaltyTerminateAndCount(runColor, runY, runHistory) * _QrCode.PENALTY_N3;\n }\n for (let y = 0; y < this.size - 1; y++) {\n for (let x = 0; x < this.size - 1; x++) {\n const color = this.modules[y][x];\n if (color == this.modules[y][x + 1] && color == this.modules[y + 1][x] && color == this.modules[y + 1][x + 1])\n result += _QrCode.PENALTY_N2;\n }\n }\n let dark = 0;\n for (const row of this.modules)\n dark = row.reduce((sum, color) => sum + (color ? 1 : 0), dark);\n const total = this.size * this.size;\n const k = Math.ceil(Math.abs(dark * 20 - total * 10) / total) - 1;\n assert(0 <= k && k <= 9);\n result += k * _QrCode.PENALTY_N4;\n assert(0 <= result && result <= 2568888);\n return result;\n }\n /*-- Private helper functions --*/\n // Returns an ascending list of positions of alignment patterns for this version number.\n // Each position is in the range [0,177), and are used on both the x and y axes.\n // This could be implemented as lookup table of 40 variable-length lists of integers.\n getAlignmentPatternPositions() {\n if (this.version == 1)\n return [];\n else {\n const numAlign = Math.floor(this.version / 7) + 2;\n const step = this.version == 32 ? 26 : Math.ceil((this.version * 4 + 4) / (numAlign * 2 - 2)) * 2;\n let result = [6];\n for (let pos = this.size - 7; result.length < numAlign; pos -= step)\n result.splice(1, 0, pos);\n return result;\n }\n }\n // Returns the number of data bits that can be stored in a QR Code of the given version number, after\n // all function modules are excluded. This includes remainder bits, so it might not be a multiple of 8.\n // The result is in the range [208, 29648]. This could be implemented as a 40-entry lookup table.\n static getNumRawDataModules(ver) {\n if (ver < _QrCode.MIN_VERSION || ver > _QrCode.MAX_VERSION)\n throw new RangeError(\"Version number out of range\");\n let result = (16 * ver + 128) * ver + 64;\n if (ver >= 2) {\n const numAlign = Math.floor(ver / 7) + 2;\n result -= (25 * numAlign - 10) * numAlign - 55;\n if (ver >= 7)\n result -= 36;\n }\n assert(208 <= result && result <= 29648);\n return result;\n }\n // Returns the number of 8-bit data (i.e. not error correction) codewords contained in any\n // QR Code of the given version number and error correction level, with remainder bits discarded.\n // This stateless pure function could be implemented as a (40*4)-cell lookup table.\n static getNumDataCodewords(ver, ecl) {\n return Math.floor(_QrCode.getNumRawDataModules(ver) / 8) - _QrCode.ECC_CODEWORDS_PER_BLOCK[ecl.ordinal][ver] * _QrCode.NUM_ERROR_CORRECTION_BLOCKS[ecl.ordinal][ver];\n }\n // Returns a Reed-Solomon ECC generator polynomial for the given degree. This could be\n // implemented as a lookup table over all possible parameter values, instead of as an algorithm.\n static reedSolomonComputeDivisor(degree) {\n if (degree < 1 || degree > 255)\n throw new RangeError(\"Degree out of range\");\n let result = [];\n for (let i = 0; i < degree - 1; i++)\n result.push(0);\n result.push(1);\n let root = 1;\n for (let i = 0; i < degree; i++) {\n for (let j = 0; j < result.length; j++) {\n result[j] = _QrCode.reedSolomonMultiply(result[j], root);\n if (j + 1 < result.length)\n result[j] ^= result[j + 1];\n }\n root = _QrCode.reedSolomonMultiply(root, 2);\n }\n return result;\n }\n // Returns the Reed-Solomon error correction codeword for the given data and divisor polynomials.\n static reedSolomonComputeRemainder(data, divisor) {\n let result = divisor.map((_) => 0);\n for (const b of data) {\n const factor = b ^ result.shift();\n result.push(0);\n divisor.forEach((coef, i) => result[i] ^= _QrCode.reedSolomonMultiply(coef, factor));\n }\n return result;\n }\n // Returns the product of the two given field elements modulo GF(2^8/0x11D). The arguments and result\n // are unsigned 8-bit integers. This could be implemented as a lookup table of 256*256 entries of uint8.\n static reedSolomonMultiply(x, y) {\n if (x >>> 8 != 0 || y >>> 8 != 0)\n throw new RangeError(\"Byte out of range\");\n let z = 0;\n for (let i = 7; i >= 0; i--) {\n z = z << 1 ^ (z >>> 7) * 285;\n z ^= (y >>> i & 1) * x;\n }\n assert(z >>> 8 == 0);\n return z;\n }\n // Can only be called immediately after a light run is added, and\n // returns either 0, 1, or 2. A helper function for getPenaltyScore().\n finderPenaltyCountPatterns(runHistory) {\n const n = runHistory[1];\n assert(n <= this.size * 3);\n const core = n > 0 && runHistory[2] == n && runHistory[3] == n * 3 && runHistory[4] == n && runHistory[5] == n;\n return (core && runHistory[0] >= n * 4 && runHistory[6] >= n ? 1 : 0) + (core && runHistory[6] >= n * 4 && runHistory[0] >= n ? 1 : 0);\n }\n // Must be called at the end of a line (row or column) of modules. A helper function for getPenaltyScore().\n finderPenaltyTerminateAndCount(currentRunColor, currentRunLength, runHistory) {\n if (currentRunColor) {\n this.finderPenaltyAddHistory(currentRunLength, runHistory);\n currentRunLength = 0;\n }\n currentRunLength += this.size;\n this.finderPenaltyAddHistory(currentRunLength, runHistory);\n return this.finderPenaltyCountPatterns(runHistory);\n }\n // Pushes the given value to the front and drops the last value. A helper function for getPenaltyScore().\n finderPenaltyAddHistory(currentRunLength, runHistory) {\n if (runHistory[0] == 0)\n currentRunLength += this.size;\n runHistory.pop();\n runHistory.unshift(currentRunLength);\n }\n };\n /*-- Constants and tables --*/\n // The minimum version number supported in the QR Code Model 2 standard.\n _QrCode.MIN_VERSION = 1;\n // The maximum version number supported in the QR Code Model 2 standard.\n _QrCode.MAX_VERSION = 40;\n // For use in getPenaltyScore(), when evaluating which mask is best.\n _QrCode.PENALTY_N1 = 3;\n _QrCode.PENALTY_N2 = 3;\n _QrCode.PENALTY_N3 = 40;\n _QrCode.PENALTY_N4 = 10;\n _QrCode.ECC_CODEWORDS_PER_BLOCK = [\n // Version: (note that index 0 is for padding, and is set to an illegal value)\n //0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40 Error correction level\n [-1, 7, 10, 15, 20, 26, 18, 20, 24, 30, 18, 20, 24, 26, 30, 22, 24, 28, 30, 28, 28, 28, 28, 30, 30, 26, 28, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30],\n // Low\n [-1, 10, 16, 26, 18, 24, 16, 18, 22, 22, 26, 30, 22, 22, 24, 24, 28, 28, 26, 26, 26, 26, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28],\n // Medium\n [-1, 13, 22, 18, 26, 18, 24, 18, 22, 20, 24, 28, 26, 24, 20, 30, 24, 28, 28, 26, 30, 28, 30, 30, 30, 30, 28, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30],\n // Quartile\n [-1, 17, 28, 22, 16, 22, 28, 26, 26, 24, 28, 24, 28, 22, 24, 24, 30, 28, 28, 26, 28, 30, 24, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30]\n // High\n ];\n _QrCode.NUM_ERROR_CORRECTION_BLOCKS = [\n // Version: (note that index 0 is for padding, and is set to an illegal value)\n //0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40 Error correction level\n [-1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 4, 4, 4, 4, 4, 6, 6, 6, 6, 7, 8, 8, 9, 9, 10, 12, 12, 12, 13, 14, 15, 16, 17, 18, 19, 19, 20, 21, 22, 24, 25],\n // Low\n [-1, 1, 1, 1, 2, 2, 4, 4, 4, 5, 5, 5, 8, 9, 9, 10, 10, 11, 13, 14, 16, 17, 17, 18, 20, 21, 23, 25, 26, 28, 29, 31, 33, 35, 37, 38, 40, 43, 45, 47, 49],\n // Medium\n [-1, 1, 1, 2, 2, 4, 4, 6, 6, 8, 8, 8, 10, 12, 16, 12, 17, 16, 18, 21, 20, 23, 23, 25, 27, 29, 34, 34, 35, 38, 40, 43, 45, 48, 51, 53, 56, 59, 62, 65, 68],\n // Quartile\n [-1, 1, 1, 2, 4, 4, 4, 5, 6, 8, 8, 11, 11, 16, 16, 18, 16, 19, 21, 25, 25, 25, 34, 30, 32, 35, 37, 40, 42, 45, 48, 51, 54, 57, 60, 63, 66, 70, 74, 77, 81]\n // High\n ];\n let QrCode = _QrCode;\n qrcodegen2.QrCode = _QrCode;\n function appendBits(val, len, bb) {\n if (len < 0 || len > 31 || val >>> len != 0)\n throw new RangeError(\"Value out of range\");\n for (let i = len - 1; i >= 0; i--)\n bb.push(val >>> i & 1);\n }\n function getBit(x, i) {\n return (x >>> i & 1) != 0;\n }\n function assert(cond) {\n if (!cond)\n throw new Error(\"Assertion error\");\n }\n const _QrSegment = class _QrSegment {\n /*-- Constructor (low level) and fields --*/\n // Creates a new QR Code segment with the given attributes and data.\n // The character count (numChars) must agree with the mode and the bit buffer length,\n // but the constraint isn't checked. The given bit buffer is cloned and stored.\n constructor(mode, numChars, bitData) {\n this.mode = mode;\n this.numChars = numChars;\n this.bitData = bitData;\n if (numChars < 0)\n throw new RangeError(\"Invalid argument\");\n this.bitData = bitData.slice();\n }\n /*-- Static factory functions (mid level) --*/\n // Returns a segment representing the given binary data encoded in\n // byte mode. All input byte arrays are acceptable. Any text string\n // can be converted to UTF-8 bytes and encoded as a byte mode segment.\n static makeBytes(data) {\n let bb = [];\n for (const b of data)\n appendBits(b, 8, bb);\n return new _QrSegment(_QrSegment.Mode.BYTE, data.length, bb);\n }\n // Returns a segment representing the given string of decimal digits encoded in numeric mode.\n static makeNumeric(digits) {\n if (!_QrSegment.isNumeric(digits))\n throw new RangeError(\"String contains non-numeric characters\");\n let bb = [];\n for (let i = 0; i < digits.length; ) {\n const n = Math.min(digits.length - i, 3);\n appendBits(parseInt(digits.substring(i, i + n), 10), n * 3 + 1, bb);\n i += n;\n }\n return new _QrSegment(_QrSegment.Mode.NUMERIC, digits.length, bb);\n }\n // Returns a segment representing the given text string encoded in alphanumeric mode.\n // The characters allowed are: 0 to 9, A to Z (uppercase only), space,\n // dollar, percent, asterisk, plus, hyphen, period, slash, colon.\n static makeAlphanumeric(text) {\n if (!_QrSegment.isAlphanumeric(text))\n throw new RangeError(\"String contains unencodable characters in alphanumeric mode\");\n let bb = [];\n let i;\n for (i = 0; i + 2 <= text.length; i += 2) {\n let temp = _QrSegment.ALPHANUMERIC_CHARSET.indexOf(text.charAt(i)) * 45;\n temp += _QrSegment.ALPHANUMERIC_CHARSET.indexOf(text.charAt(i + 1));\n appendBits(temp, 11, bb);\n }\n if (i < text.length)\n appendBits(_QrSegment.ALPHANUMERIC_CHARSET.indexOf(text.charAt(i)), 6, bb);\n return new _QrSegment(_QrSegment.Mode.ALPHANUMERIC, text.length, bb);\n }\n // Returns a new mutable list of zero or more segments to represent the given Unicode text string.\n // The result may use various segment modes and switch modes to optimize the length of the bit stream.\n static makeSegments(text) {\n if (text == \"\")\n return [];\n else if (_QrSegment.isNumeric(text))\n return [_QrSegment.makeNumeric(text)];\n else if (_QrSegment.isAlphanumeric(text))\n return [_QrSegment.makeAlphanumeric(text)];\n else\n return [_QrSegment.makeBytes(_QrSegment.toUtf8ByteArray(text))];\n }\n // Returns a segment representing an Extended Channel Interpretation\n // (ECI) designator with the given assignment value.\n static makeEci(assignVal) {\n let bb = [];\n if (assignVal < 0)\n throw new RangeError(\"ECI assignment value out of range\");\n else if (assignVal < 1 << 7)\n appendBits(assignVal, 8, bb);\n else if (assignVal < 1 << 14) {\n appendBits(2, 2, bb);\n appendBits(assignVal, 14, bb);\n } else if (assignVal < 1e6) {\n appendBits(6, 3, bb);\n appendBits(assignVal, 21, bb);\n } else\n throw new RangeError(\"ECI assignment value out of range\");\n return new _QrSegment(_QrSegment.Mode.ECI, 0, bb);\n }\n // Tests whether the given string can be encoded as a segment in numeric mode.\n // A string is encodable iff each character is in the range 0 to 9.\n static isNumeric(text) {\n return _QrSegment.NUMERIC_REGEX.test(text);\n }\n // Tests whether the given string can be encoded as a segment in alphanumeric mode.\n // A string is encodable iff each character is in the following set: 0 to 9, A to Z\n // (uppercase only), space, dollar, percent, asterisk, plus, hyphen, period, slash, colon.\n static isAlphanumeric(text) {\n return _QrSegment.ALPHANUMERIC_REGEX.test(text);\n }\n /*-- Methods --*/\n // Returns a new copy of the data bits of this segment.\n getData() {\n return this.bitData.slice();\n }\n // (Package-private) Calculates and returns the number of bits needed to encode the given segments at\n // the given version. The result is infinity if a segment has too many characters to fit its length field.\n static getTotalBits(segs, version) {\n let result = 0;\n for (const seg of segs) {\n const ccbits = seg.mode.numCharCountBits(version);\n if (seg.numChars >= 1 << ccbits)\n return Infinity;\n result += 4 + ccbits + seg.bitData.length;\n }\n return result;\n }\n // Returns a new array of bytes representing the given string encoded in UTF-8.\n static toUtf8ByteArray(str) {\n str = encodeURI(str);\n let result = [];\n for (let i = 0; i < str.length; i++) {\n if (str.charAt(i) != \"%\")\n result.push(str.charCodeAt(i));\n else {\n result.push(parseInt(str.substring(i + 1, i + 3), 16));\n i += 2;\n }\n }\n return result;\n }\n };\n /*-- Constants --*/\n // Describes precisely all strings that are encodable in numeric mode.\n _QrSegment.NUMERIC_REGEX = /^[0-9]*$/;\n // Describes precisely all strings that are encodable in alphanumeric mode.\n _QrSegment.ALPHANUMERIC_REGEX = /^[A-Z0-9 $%*+.\\/:-]*$/;\n // The set of all legal characters in alphanumeric mode,\n // where each character value maps to the index in the string.\n _QrSegment.ALPHANUMERIC_CHARSET = \"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ $%*+-./:\";\n let QrSegment = _QrSegment;\n qrcodegen2.QrSegment = _QrSegment;\n})(qrcodegen || (qrcodegen = {}));\n((qrcodegen2) => {\n let QrCode;\n ((QrCode2) => {\n const _Ecc = class _Ecc {\n // The QR Code can tolerate about 30% erroneous codewords\n /*-- Constructor and fields --*/\n constructor(ordinal, formatBits) {\n this.ordinal = ordinal;\n this.formatBits = formatBits;\n }\n };\n /*-- Constants --*/\n _Ecc.LOW = new _Ecc(0, 1);\n // The QR Code can tolerate about 7% erroneous codewords\n _Ecc.MEDIUM = new _Ecc(1, 0);\n // The QR Code can tolerate about 15% erroneous codewords\n _Ecc.QUARTILE = new _Ecc(2, 3);\n // The QR Code can tolerate about 25% erroneous codewords\n _Ecc.HIGH = new _Ecc(3, 2);\n let Ecc = _Ecc;\n QrCode2.Ecc = _Ecc;\n })(QrCode = qrcodegen2.QrCode || (qrcodegen2.QrCode = {}));\n})(qrcodegen || (qrcodegen = {}));\n((qrcodegen2) => {\n let QrSegment;\n ((QrSegment2) => {\n const _Mode = class _Mode {\n /*-- Constructor and fields --*/\n constructor(modeBits, numBitsCharCount) {\n this.modeBits = modeBits;\n this.numBitsCharCount = numBitsCharCount;\n }\n /*-- Method --*/\n // (Package-private) Returns the bit width of the character count field for a segment in\n // this mode in a QR Code at the given version number. The result is in the range [0, 16].\n numCharCountBits(ver) {\n return this.numBitsCharCount[Math.floor((ver + 7) / 17)];\n }\n };\n /*-- Constants --*/\n _Mode.NUMERIC = new _Mode(1, [10, 12, 14]);\n _Mode.ALPHANUMERIC = new _Mode(2, [9, 11, 13]);\n _Mode.BYTE = new _Mode(4, [8, 16, 16]);\n _Mode.KANJI = new _Mode(8, [8, 10, 12]);\n _Mode.ECI = new _Mode(7, [0, 0, 0]);\n let Mode = _Mode;\n QrSegment2.Mode = _Mode;\n })(QrSegment = qrcodegen2.QrSegment || (qrcodegen2.QrSegment = {}));\n})(qrcodegen || (qrcodegen = {}));\nvar qrcodegen_default = qrcodegen;\n\n// src/index.tsx\n/**\n * @license qrcode.react\n * Copyright (c) Paul O'Shannessy\n * SPDX-License-Identifier: ISC\n */\nvar ERROR_LEVEL_MAP = {\n L: qrcodegen_default.QrCode.Ecc.LOW,\n M: qrcodegen_default.QrCode.Ecc.MEDIUM,\n Q: qrcodegen_default.QrCode.Ecc.QUARTILE,\n H: qrcodegen_default.QrCode.Ecc.HIGH\n};\nvar DEFAULT_SIZE = 128;\nvar DEFAULT_LEVEL = \"L\";\nvar DEFAULT_BGCOLOR = \"#FFFFFF\";\nvar DEFAULT_FGCOLOR = \"#000000\";\nvar DEFAULT_INCLUDEMARGIN = false;\nvar DEFAULT_MINVERSION = 1;\nvar SPEC_MARGIN_SIZE = 4;\nvar DEFAULT_MARGIN_SIZE = 0;\nvar DEFAULT_IMG_SCALE = 0.1;\nfunction generatePath(modules, margin = 0) {\n const ops = [];\n modules.forEach(function(row, y) {\n let start = null;\n row.forEach(function(cell, x) {\n if (!cell && start !== null) {\n ops.push(\n `M${start + margin} ${y + margin}h${x - start}v1H${start + margin}z`\n );\n start = null;\n return;\n }\n if (x === row.length - 1) {\n if (!cell) {\n return;\n }\n if (start === null) {\n ops.push(`M${x + margin},${y + margin} h1v1H${x + margin}z`);\n } else {\n ops.push(\n `M${start + margin},${y + margin} h${x + 1 - start}v1H${start + margin}z`\n );\n }\n return;\n }\n if (cell && start === null) {\n start = x;\n }\n });\n });\n return ops.join(\"\");\n}\nfunction excavateModules(modules, excavation) {\n return modules.slice().map((row, y) => {\n if (y < excavation.y || y >= excavation.y + excavation.h) {\n return row;\n }\n return row.map((cell, x) => {\n if (x < excavation.x || x >= excavation.x + excavation.w) {\n return cell;\n }\n return false;\n });\n });\n}\nfunction getImageSettings(cells, size, margin, imageSettings) {\n if (imageSettings == null) {\n return null;\n }\n const numCells = cells.length + margin * 2;\n const defaultSize = Math.floor(size * DEFAULT_IMG_SCALE);\n const scale = numCells / size;\n const w = (imageSettings.width || defaultSize) * scale;\n const h = (imageSettings.height || defaultSize) * scale;\n const x = imageSettings.x == null ? cells.length / 2 - w / 2 : imageSettings.x * scale;\n const y = imageSettings.y == null ? cells.length / 2 - h / 2 : imageSettings.y * scale;\n const opacity = imageSettings.opacity == null ? 1 : imageSettings.opacity;\n let excavation = null;\n if (imageSettings.excavate) {\n let floorX = Math.floor(x);\n let floorY = Math.floor(y);\n let ceilW = Math.ceil(w + x - floorX);\n let ceilH = Math.ceil(h + y - floorY);\n excavation = { x: floorX, y: floorY, w: ceilW, h: ceilH };\n }\n const crossOrigin = imageSettings.crossOrigin;\n return { x, y, h, w, excavation, opacity, crossOrigin };\n}\nfunction getMarginSize(includeMargin, marginSize) {\n if (marginSize != null) {\n return Math.max(Math.floor(marginSize), 0);\n }\n return includeMargin ? SPEC_MARGIN_SIZE : DEFAULT_MARGIN_SIZE;\n}\nfunction useQRCode({\n value,\n level,\n minVersion,\n includeMargin,\n marginSize,\n imageSettings,\n size,\n boostLevel\n}) {\n let qrcode = React.useMemo(() => {\n const values = Array.isArray(value) ? value : [value];\n const segments = values.reduce((accum, v) => {\n accum.push(...qrcodegen_default.QrSegment.makeSegments(v));\n return accum;\n }, []);\n return qrcodegen_default.QrCode.encodeSegments(\n segments,\n ERROR_LEVEL_MAP[level],\n minVersion,\n void 0,\n void 0,\n boostLevel\n );\n }, [value, level, minVersion, boostLevel]);\n const { cells, margin, numCells, calculatedImageSettings } = React.useMemo(() => {\n let cells2 = qrcode.getModules();\n const margin2 = getMarginSize(includeMargin, marginSize);\n const numCells2 = cells2.length + margin2 * 2;\n const calculatedImageSettings2 = getImageSettings(\n cells2,\n size,\n margin2,\n imageSettings\n );\n return {\n cells: cells2,\n margin: margin2,\n numCells: numCells2,\n calculatedImageSettings: calculatedImageSettings2\n };\n }, [qrcode, size, imageSettings, includeMargin, marginSize]);\n return {\n qrcode,\n margin,\n cells,\n numCells,\n calculatedImageSettings\n };\n}\nvar SUPPORTS_PATH2D = function() {\n try {\n new Path2D().addPath(new Path2D());\n } catch (e) {\n return false;\n }\n return true;\n}();\nvar QRCodeCanvas = React.forwardRef(\n function QRCodeCanvas2(props, forwardedRef) {\n const _a = props, {\n value,\n size = DEFAULT_SIZE,\n level = DEFAULT_LEVEL,\n bgColor = DEFAULT_BGCOLOR,\n fgColor = DEFAULT_FGCOLOR,\n includeMargin = DEFAULT_INCLUDEMARGIN,\n minVersion = DEFAULT_MINVERSION,\n boostLevel,\n marginSize,\n imageSettings\n } = _a, extraProps = __objRest(_a, [\n \"value\",\n \"size\",\n \"level\",\n \"bgColor\",\n \"fgColor\",\n \"includeMargin\",\n \"minVersion\",\n \"boostLevel\",\n \"marginSize\",\n \"imageSettings\"\n ]);\n const _b = extraProps, { style } = _b, otherProps = __objRest(_b, [\"style\"]);\n const imgSrc = imageSettings == null ? void 0 : imageSettings.src;\n const _canvas = React.useRef(null);\n const _image = React.useRef(null);\n const setCanvasRef = React.useCallback(\n (node) => {\n _canvas.current = node;\n if (typeof forwardedRef === \"function\") {\n forwardedRef(node);\n } else if (forwardedRef) {\n forwardedRef.current = node;\n }\n },\n [forwardedRef]\n );\n const [isImgLoaded, setIsImageLoaded] = React.useState(false);\n const { margin, cells, numCells, calculatedImageSettings } = useQRCode({\n value,\n level,\n minVersion,\n boostLevel,\n includeMargin,\n marginSize,\n imageSettings,\n size\n });\n React.useEffect(() => {\n if (_canvas.current != null) {\n const canvas = _canvas.current;\n const ctx = canvas.getContext(\"2d\");\n if (!ctx) {\n return;\n }\n let cellsToDraw = cells;\n const image = _image.current;\n const haveImageToRender = calculatedImageSettings != null && image !== null && image.complete && image.naturalHeight !== 0 && image.naturalWidth !== 0;\n if (haveImageToRender) {\n if (calculatedImageSettings.excavation != null) {\n cellsToDraw = excavateModules(\n cells,\n calculatedImageSettings.excavation\n );\n }\n }\n const pixelRatio = window.devicePixelRatio || 1;\n canvas.height = canvas.width = size * pixelRatio;\n const scale = size / numCells * pixelRatio;\n ctx.scale(scale, scale);\n ctx.fillStyle = bgColor;\n ctx.fillRect(0, 0, numCells, numCells);\n ctx.fillStyle = fgColor;\n if (SUPPORTS_PATH2D) {\n ctx.fill(new Path2D(generatePath(cellsToDraw, margin)));\n } else {\n cells.forEach(function(row, rdx) {\n row.forEach(function(cell, cdx) {\n if (cell) {\n ctx.fillRect(cdx + margin, rdx + margin, 1, 1);\n }\n });\n });\n }\n if (calculatedImageSettings) {\n ctx.globalAlpha = calculatedImageSettings.opacity;\n }\n if (haveImageToRender) {\n ctx.drawImage(\n image,\n calculatedImageSettings.x + margin,\n calculatedImageSettings.y + margin,\n calculatedImageSettings.w,\n calculatedImageSettings.h\n );\n }\n }\n });\n React.useEffect(() => {\n setIsImageLoaded(false);\n }, [imgSrc]);\n const canvasStyle = __spreadValues({ height: size, width: size }, style);\n let img = null;\n if (imgSrc != null) {\n img = /* @__PURE__ */ React.createElement(\n \"img\",\n {\n src: imgSrc,\n key: imgSrc,\n style: { display: \"none\" },\n onLoad: () => {\n setIsImageLoaded(true);\n },\n ref: _image,\n crossOrigin: calculatedImageSettings == null ? void 0 : calculatedImageSettings.crossOrigin\n }\n );\n }\n return /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement(\n \"canvas\",\n __spreadValues({\n style: canvasStyle,\n height: size,\n width: size,\n ref: setCanvasRef,\n role: \"img\"\n }, otherProps)\n ), img);\n }\n);\nQRCodeCanvas.displayName = \"QRCodeCanvas\";\nvar QRCodeSVG = React.forwardRef(\n function QRCodeSVG2(props, forwardedRef) {\n const _a = props, {\n value,\n size = DEFAULT_SIZE,\n level = DEFAULT_LEVEL,\n bgColor = DEFAULT_BGCOLOR,\n fgColor = DEFAULT_FGCOLOR,\n includeMargin = DEFAULT_INCLUDEMARGIN,\n minVersion = DEFAULT_MINVERSION,\n boostLevel,\n title,\n marginSize,\n imageSettings\n } = _a, otherProps = __objRest(_a, [\n \"value\",\n \"size\",\n \"level\",\n \"bgColor\",\n \"fgColor\",\n \"includeMargin\",\n \"minVersion\",\n \"boostLevel\",\n \"title\",\n \"marginSize\",\n \"imageSettings\"\n ]);\n const { margin, cells, numCells, calculatedImageSettings } = useQRCode({\n value,\n level,\n minVersion,\n boostLevel,\n includeMargin,\n marginSize,\n imageSettings,\n size\n });\n let cellsToDraw = cells;\n let image = null;\n if (imageSettings != null && calculatedImageSettings != null) {\n if (calculatedImageSettings.excavation != null) {\n cellsToDraw = excavateModules(\n cells,\n calculatedImageSettings.excavation\n );\n }\n image = /* @__PURE__ */ React.createElement(\n \"image\",\n {\n href: imageSettings.src,\n height: calculatedImageSettings.h,\n width: calculatedImageSettings.w,\n x: calculatedImageSettings.x + margin,\n y: calculatedImageSettings.y + margin,\n preserveAspectRatio: \"none\",\n opacity: calculatedImageSettings.opacity,\n crossOrigin: calculatedImageSettings.crossOrigin\n }\n );\n }\n const fgPath = generatePath(cellsToDraw, margin);\n return /* @__PURE__ */ React.createElement(\n \"svg\",\n __spreadValues({\n height: size,\n width: size,\n viewBox: `0 0 ${numCells} ${numCells}`,\n ref: forwardedRef,\n role: \"img\"\n }, otherProps),\n !!title && /* @__PURE__ */ React.createElement(\"title\", null, title),\n /* @__PURE__ */ React.createElement(\n \"path\",\n {\n fill: bgColor,\n d: `M0,0 h${numCells}v${numCells}H0z`,\n shapeRendering: \"crispEdges\"\n }\n ),\n /* @__PURE__ */ React.createElement(\"path\", { fill: fgColor, d: fgPath, shapeRendering: \"crispEdges\" }),\n image\n );\n }\n);\nQRCodeSVG.displayName = \"QRCodeSVG\";\nexport {\n QRCodeCanvas,\n QRCodeSVG\n};\n","/**\n * Browser-side wire helpers for the /api/pair surface. Plain fetch over\n * same-origin /api (like the connection client); JSON bodies, string\n * responses for the error codes.\n */\n\n/** issue() response. */\nexport interface IssueResult {\n ok: true\n url: string\n token: string\n expiresAt: number\n /** Every constructible LAN base address (interface order). */\n lanAddresses: string[]\n /** The configured public (tunneled) base URL, when present. */\n publicBaseUrl?: string\n}\n\n/** issue() refusal: the server is not LAN-reachable. */\nexport interface IssueLanRequired {\n ok: false\n code: 'lan-required'\n}\n\n/** issue() refusal: the requested LAN address is not constructible. */\nexport interface IssueUnknownAddress {\n ok: false\n code: 'unknown-address'\n}\n\n/** issue() refusal: the loopback-only fence rejected this origin. */\nexport interface IssueLoopbackRequired {\n ok: false\n code: 'forbidden'\n}\n\nexport type IssueResponse = IssueResult | IssueLanRequired | IssueUnknownAddress | IssueLoopbackRequired\n\n/** Public policy fields returned by the pairing status endpoint. */\nexport interface PairGatePolicy {\n requirePairingForLan: boolean\n}\n\n/** Read the host-authoritative desktop pairing policy. */\nexport async function readPairGatePolicy(): Promise<PairGatePolicy> {\n const response = await fetch('/api/pair/status')\n if (!response.ok) throw new Error(`remote-web-ui: status failed with ${String(response.status)}`)\n const value = await response.json() as { requirePairingForLan?: unknown }\n if (typeof value.requirePairingForLan !== 'boolean') {\n throw new Error('remote-web-ui: status omitted requirePairingForLan')\n }\n return { requirePairingForLan: value.requirePairingForLan }\n}\n\n/** accept() refusal codes. */\nexport type AcceptFailure = { ok: false; code: 'invalid' | 'used' | 'forbidden' }\n\n/** One auto-tunnel status frame (absent while the feature is off). */\nexport interface TunnelStatusFrame {\n state: 'starting' | 'running' | 'failed'\n url?: string\n error?: string\n}\n\n/** One relay-registry status frame (absent while the relay is not in play). */\nexport interface RelayStatusFrame {\n state: 'off' | 'registering' | 'running' | 'failed'\n /** The stable relay origin, once registered. */\n url?: string\n /** Human-readable failure detail of the last sync attempt. */\n error?: string\n}\n\n/** One /api posture frame (host half probe; see src/posture.ts). */\nexport interface PostureFrame {\n checkedAt: number\n hosts: { host: string; exposed: boolean }[]\n}\n\n/** One /api/pair/events frame. */\nexport interface PairStateFrame {\n type: 'state'\n phase: 'lan-required' | 'stopped' | 'waiting' | 'connected' | 'disconnected'\n lanAvailable: boolean\n tokenId?: string\n tokenExpiresAt?: number\n deviceCount: number\n onlineCount: number\n /** Per-device roster (loopback events only). */\n devices?: DeviceFrame[]\n /** Auto-tunnel status, while the auto-tunnel feature is active. */\n tunnel?: TunnelStatusFrame\n /** Relay-registry status, while the stable-origin relay is in play. */\n relay?: RelayStatusFrame\n /** Latest /api fence posture probe, once a round has completed. */\n posture?: PostureFrame\n}\n\n/** One authorized-device row from the loopback status stream. */\nexport interface DeviceFrame {\n id: string\n createdAt: number\n lastSeenAt: number\n online: boolean\n userAgent?: string\n}\n\n/**\n * Mint a fresh pairing token (one active token at a time — this invalidates\n * any previous link).\n * @param address - optional LAN IP literal the QR must be built from (the\n * default is the first interface); unknown literals refuse with\n * 'unknown-address'.\n * @returns the issued link, the lan-required refusal (server never bound\n * 0.0.0.0), or the forbidden refusal (the loopback-only fence rejected this\n * origin — the panel is a desktop control endpoint).\n */\nexport async function issuePair(address?: string): Promise<IssueResponse> {\n const response = await fetch('/api/pair/issue', {\n method: 'POST',\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify({\n ...(address !== undefined ? { address } : {}),\n }),\n })\n if (!response.ok) {\n if (response.status === 409) return { ok: false, code: 'lan-required' }\n if (response.status === 403) return { ok: false, code: 'forbidden' }\n if (response.status === 400) return { ok: false, code: 'unknown-address' }\n throw new Error(`remote-web-ui: issue failed with ${String(response.status)}`)\n }\n return await response.json() as IssueResult\n}\n\n/**\n * Accept a pairing token (the phone's first open of the QR link). Success\n * sets the device cookie; the page then reloads to boot with it.\n * @param token - the token from the URL.\n * @returns the wire result.\n */\nexport async function acceptPair(token: string): Promise<{ ok: true } | AcceptFailure> {\n const response = await fetch('/api/pair/accept', {\n method: 'POST',\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify({ token }),\n })\n if (response.ok) return { ok: true }\n if (response.status === 404) return { ok: false, code: 'invalid' }\n if (response.status === 409) return { ok: false, code: 'used' }\n return { ok: false, code: 'forbidden' }\n}\n\n/** Revoke mobile access (paired devices + the current token). */\nexport async function stopPair(): Promise<void> {\n const response = await fetch('/api/pair/stop', { method: 'POST' })\n if (!response.ok) throw new Error(`remote-web-ui: stop failed with ${String(response.status)}`)\n}\n\n/**\n * Revoke one paired device from the loopback panel.\n * @param deviceId - the session id of the row to drop.\n */\nexport async function revokePair(deviceId: string): Promise<void> {\n const response = await fetch('/api/pair/revoke', {\n method: 'POST',\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify({ deviceId }),\n })\n if (response.status === 404) return\n if (!response.ok) throw new Error(`remote-web-ui: revoke failed with ${String(response.status)}`)\n}\n\n/** Presence heartbeat from a paired phone (unpaired heartbeats 401 harmlessly). */\nexport async function sendHeartbeat(): Promise<void> {\n await fetch('/api/pair/heartbeat', { method: 'POST' })\n}\n\n/** Whether the current page URL carries a pairing token. */\nexport function readPairParams(search: string): { pair?: string } {\n const params = new URLSearchParams(search)\n const pair = params.get('pair')\n return pair !== null && pair !== '' ? { pair } : {}\n}\n\n/**\n * Strip one query parameter from the current URL without reloading.\n * @param name - the parameter to remove.\n * @returns the new search string ('' when empty).\n */\nexport function stripParam(name: string): string {\n const url = new URL(window.location.href)\n url.searchParams.delete(name)\n return url.search\n}\n\n/** LAN-bind status frame from the loopback-only card endpoint. */\nexport interface LanBindFrame {\n profile: string\n /** The config toggle: true/false once flipped, null while untouched. */\n setting: boolean | null\n /** The bind default the managed patch block currently pins. */\n blockHost: string | null\n /** The live bind of the running web server. */\n bindHost: string\n port: number\n lanUrls: string[]\n firewall: { ok: boolean; managed: boolean; note?: string }\n platform: string\n /** true when the running bind has not caught up with the toggle yet. */\n pendingRestart?: boolean\n}\n\n/** Read the LAN-bind facts (loopback-only endpoint). */\nexport async function readLanBindStatus(): Promise<LanBindFrame> {\n const response = await fetch('/api/pair/lan-bind')\n if (!response.ok) throw new Error(`remote-web-ui: lan-bind status failed with ${String(response.status)}`)\n return await response.json() as LanBindFrame\n}\n\n/** Human-readable expiry clock, e.g. \"10:35\". */\nexport function formatClock(epochMs: number): string {\n const date = new Date(epochMs)\n const hours = String(date.getHours()).padStart(2, '0')\n const minutes = String(date.getMinutes()).padStart(2, '0')\n return `${hours}:${minutes}`\n}\n\n/** Calendar + clock for last-seen timestamps, e.g. \"2026-08-19 10:35\". */\nexport function formatLastSeen(epochMs: number): string {\n const date = new Date(epochMs)\n const year = String(date.getFullYear())\n const month = String(date.getMonth() + 1).padStart(2, '0')\n const day = String(date.getDate()).padStart(2, '0')\n return `${year}-${month}-${day} ${formatClock(epochMs)}`\n}\n\n/**\n * Copy text to the clipboard with a fallback for insecure contexts\n * (plain-HTTP LAN origins lack navigator.clipboard).\n * @param text - the text to copy.\n * @returns whether the copy succeeded.\n */\nexport async function copyText(text: string): Promise<boolean> {\n if (typeof navigator !== 'undefined' && navigator.clipboard !== undefined) {\n try {\n await navigator.clipboard.writeText(text)\n return true\n } catch {\n // fall through to the execCommand path\n }\n }\n try {\n const area = document.createElement('textarea')\n area.value = text\n area.style.position = 'fixed'\n area.style.opacity = '0'\n document.body.appendChild(area)\n area.select()\n const ok = document.execCommand('copy')\n area.remove()\n return ok\n } catch {\n return false\n }\n}\n","/** Derive a short, non-sensitive device label from a browser User-Agent. */\nexport function deviceNameFromUserAgent(userAgent?: string): string | undefined {\n if (userAgent === undefined || userAgent.trim() === '') return undefined\n\n const os = /Windows NT/i.test(userAgent)\n ? 'Windows'\n : /Android/i.test(userAgent)\n ? 'Android'\n : /iPhone|iPad|iPod/i.test(userAgent)\n ? 'iOS'\n : /Macintosh|Mac OS X/i.test(userAgent)\n ? 'macOS'\n : /Linux/i.test(userAgent)\n ? 'Linux'\n : undefined\n\n const browser = /Edg(?:A|iOS)?\\//i.test(userAgent)\n ? 'Edge'\n : /(?:OPR|Opera)\\//i.test(userAgent)\n ? 'Opera'\n : /(?:Chrome|CriOS)\\//i.test(userAgent)\n ? 'Chrome'\n : /(?:Firefox|FxiOS)\\//i.test(userAgent)\n ? 'Firefox'\n : /Safari\\//i.test(userAgent) && /Version\\//i.test(userAgent)\n ? 'Safari'\n : undefined\n\n if (os !== undefined && browser !== undefined) return `${os} · ${browser}`\n return os ?? browser\n}\n","/**\n * The mobile remote-control panel body: status card (state text + badge),\n * the QR code, the open-on-phone hint with the link text, and the three\n * actions (stop / refresh / copy). Pure presentation — all state and\n * actions arrive through props from the entry's behavior component.\n */\nimport clsx from 'clsx'\nimport { QRCodeSVG } from 'qrcode.react'\nimport {\n IconCloseOutline16, IconCopyOutline16, IconRefreshOutline16, IconStopFill16,\n} from '@deepseek-ai/dsh-client-ui-primitives'\nimport type { TranslateNS } from '@deepseek-ai/dsh-client-ui-slots'\nimport type { PairingPhase } from '../pairing.ts'\nimport {\n formatClock,\n formatLastSeen,\n type DeviceFrame,\n type PostureFrame,\n type RelayStatusFrame,\n type TunnelStatusFrame,\n} from './pair-api.ts'\nimport { deviceNameFromUserAgent } from './device-name.ts'\nimport css from './remote.module.css'\n\n/** The panel's view state, owned by the entry component. */\nexport type PanelState =\n | { kind: 'lan-required'; tunnel?: TunnelStatusFrame }\n | { kind: 'loopback-required' }\n | { kind: 'unreachable' }\n | {\n kind: 'ready'\n url: string\n expiresAt: number\n expired: boolean\n phase: PairingPhase\n deviceCount: number\n onlineCount: number\n /** Authorized devices for the roster under the QR card. */\n devices: DeviceFrame[]\n /** The LAN literal the current QR was built from. */\n address: string\n /** Every constructible LAN literal (interface order). */\n lanAddresses: string[]\n /** The active pairing token itself (useful in Docker/reverse proxy topologies). */\n token?: string\n /** Whether this QR is built on the configured public (tunneled) base. */\n public: boolean\n /** The configured public (tunneled) base URL, when present. */\n publicBaseUrl?: string\n /** Auto-tunnel status, while the auto-tunnel feature is active. */\n tunnel?: TunnelStatusFrame\n /** Relay-registry status, while the stable-origin relay is in play. */\n relay?: RelayStatusFrame\n /** Latest /api posture probe, once a round has completed. */\n posture?: PostureFrame\n }\n\n/** Full panel props: copy + view state + actions. */\nexport interface RemotePanelProps {\n t: TranslateNS<'remote'>\n state: PanelState\n copied: boolean\n copiedToken?: boolean\n onClose(): void\n onStop(): void\n onRefresh(): void\n onCopy(url: string): void\n onCopyToken?(token: string): void\n /** Re-mint the QR against a different LAN address. */\n onPickAddress(address: string): void\n /** Re-mint the QR against the configured public (tunneled) base. */\n onPickPublic(): void\n /** Revoke one paired device. */\n onRevoke(deviceId: string): void\n}\n\n/** Badge text + tone per phase (ready states only). */\nfunction statusOf(\n t: TranslateNS<'remote'>,\n state: Extract<PanelState, { kind: 'ready' }>,\n): { text: string; tone: 'waiting' | 'connected' | 'disconnected' | 'stopped' } {\n switch (state.phase) {\n case 'connected': return { text: t('status.connected', { n: state.onlineCount }), tone: 'connected' }\n case 'disconnected': return { text: t('status.disconnected'), tone: 'disconnected' }\n case 'stopped': return { text: t('status.stopped'), tone: 'stopped' }\n case 'lan-required': return { text: t('status.lanRequired'), tone: 'stopped' }\n case 'waiting': return { text: t('status.waiting'), tone: 'waiting' }\n }\n}\n\n/**\n * Render the pairing panel.\n * @param props - copy, state, and actions.\n * @returns the panel element tree.\n */\nexport function RemotePanel({\n t,\n state,\n copied,\n copiedToken,\n onClose,\n onStop,\n onRefresh,\n onCopy,\n onCopyToken,\n onPickAddress,\n onPickPublic,\n onRevoke,\n}: RemotePanelProps) {\n return (\n <div className={css.panel} role=\"dialog\" aria-modal=\"true\" aria-label={t('title')}>\n <div className={css.header}>\n <div className={css.heading}>\n <h2 className={css.title}>{t('title')}</h2>\n <p className={css.subtitle}>{t('subtitle')}</p>\n </div>\n <button type=\"button\" className={css.close} aria-label={t('close.label')} onClick={onClose}>\n <IconCloseOutline16 size={14} />\n </button>\n </div>\n\n {state.kind === 'lan-required' ? (\n <div className={css.banner} role=\"alert\">\n <p className={css.bannerTitle}>{t('status.lanRequired')}</p>\n <p className={css.bannerHint}>{t('status.lanRequiredHint')}</p>\n </div>\n ) : state.kind === 'loopback-required' ? (\n <div className={css.banner} role=\"alert\">\n <p className={css.bannerTitle}>{t('status.loopbackRequired')}</p>\n <p className={css.bannerHint}>{t('status.loopbackRequiredHint')}</p>\n </div>\n ) : state.kind === 'unreachable' ? (\n <div className={css.banner} role=\"alert\">\n <p className={css.bannerTitle}>{t('status.unreachable')}</p>\n <p className={css.bannerHint}>{t('status.unreachableHint')}</p>\n </div>\n ) : (\n <>\n {state.posture !== undefined && state.posture.hosts.some(host => host.exposed) && (\n <div className={css.banner} role=\"alert\">\n <p className={css.bannerTitle}>{t('posture.exposed')}</p>\n <p className={css.bannerHint}>\n {t('posture.exposedHint', { hosts: state.posture.hosts.filter(host => host.exposed).map(host => host.host).join(', ') })}\n </p>\n </div>\n )}\n <div className={css.card}>\n <div className={css.cardHeader}>\n <span className={css.cardTitle}>{t('card.title')}</span>\n <span className={css.badges}>\n {state.public && <span className={clsx(css.badge, css.badgePublic)}>{t('public.badge')}</span>}\n <span className={clsx(css.badge, css[`badge-${statusOf(t, state).tone}`])}>\n {statusOf(t, state).text}\n </span>\n </span>\n </div>\n <div className={css.qrWrap} data-testid=\"remote-qr\">\n <QRCodeSVG value={state.url} size={184} level=\"M\" marginSize={1} className={css.qr} />\n </div>\n {state.expired\n ? <p className={css.expired}>{t('pair.expired')}</p>\n : <p className={css.expiry}>{t('pair.expires', { time: formatClock(state.expiresAt) })}</p>}\n </div>\n\n <p className={css.hint}>{state.public ? t('pair.publicHint') : t('pair.hint')}</p>\n <div className={css.pairLinks}>\n <div className={css.pairLinkRow}>\n <div className={css.pairLinkText}>\n <span className={css.pairLinkLabel}>{t('pair.linkLabel')}</span>\n <code className={css.link} title={state.url}>{state.url}</code>\n </div>\n <button type=\"button\" className={css.copyLink} onClick={() => onCopy(state.url)}>\n <IconCopyOutline16 size={14} />\n {copied ? t('action.copied') : t('action.copyLink')}\n </button>\n </div>\n {state.token !== undefined && state.token !== '' && (\n <div className={css.pairLinkRow}>\n <div className={css.pairLinkText}>\n <span className={css.pairLinkLabel}>{t('pair.tokenLabel')}</span>\n <code className={css.link} title={state.token}>{state.token}</code>\n </div>\n <button\n type=\"button\"\n className={css.copyLink}\n onClick={() => onCopyToken ? onCopyToken(state.token!) : onCopy(state.token!)}\n >\n <IconCopyOutline16 size={14} />\n {copiedToken ? t('action.copiedToken') : t('action.copyToken')}\n </button>\n </div>\n )}\n </div>\n <p className={css.oneTimeHint}>\n {t('pair.oneTimeHint')} {t('pair.dockerHint')}\n </p>\n {state.phase === 'stopped' && <p className={css.stoppedHint}>{t('stopped.hint')}</p>}\n {state.tunnel !== undefined && state.tunnel.state !== 'running' && (\n <p className={state.tunnel.state === 'failed' ? css.tunnelFailed : css.tunnelNote} role=\"status\">\n {state.tunnel.state === 'failed'\n ? t('tunnel.failed', { error: state.tunnel.error ?? t('tunnel.unknownError') })\n : t('tunnel.starting')}\n </p>\n )}\n {state.relay?.state === 'registering' && (\n <p className={css.tunnelNote} role=\"status\">{t('relay.registering')}</p>\n )}\n {state.relay?.state === 'failed' && (\n <p className={css.tunnelFailed} role=\"status\">\n {t('relay.failed', { error: state.relay.error ?? t('tunnel.unknownError') })}\n </p>\n )}\n\n {(state.publicBaseUrl !== undefined || state.lanAddresses.length > 1) && (\n <fieldset className={css.addresses}>\n <legend>{t('address.label')}</legend>\n {state.publicBaseUrl !== undefined && (\n <label key=\"public\" className={css.address}>\n <input\n type=\"radio\"\n name=\"lan-address\"\n aria-label={t('address.public')}\n checked={state.public}\n onChange={onPickPublic}\n />\n <span>{t('address.public')}</span>\n <code className={css.addressValue}>{state.publicBaseUrl}</code>\n </label>\n )}\n {state.lanAddresses.map(address => (\n <label key={address} className={css.address}>\n <input\n type=\"radio\"\n name=\"lan-address\"\n aria-label={address}\n checked={!state.public && address === state.address}\n onChange={() => onPickAddress(address)}\n />\n <span>{t('address.lan')}</span>\n <code className={css.addressValue}>{address}</code>\n </label>\n ))}\n <p className={css.addressHint}>{t('address.hint')}</p>\n </fieldset>\n )}\n\n <div className={css.actions}>\n <button type=\"button\" className={css.action} onClick={onStop}>\n <IconStopFill16 size={14} />\n {t('action.stop')}\n </button>\n <button type=\"button\" className={css.action} onClick={onRefresh}>\n <IconRefreshOutline16 size={14} />\n {t('action.refresh')}\n </button>\n </div>\n\n <section className={css.devices} data-testid=\"remote-devices\" aria-label={t('devices.title')}>\n <h3 className={css.devicesTitle}>{t('devices.title')}</h3>\n {state.devices.length === 0 ? (\n <p className={css.devicesEmpty}>{t('devices.empty')}</p>\n ) : (\n <ul className={css.deviceList}>\n {state.devices.map(device => (\n <li key={device.id} className={css.deviceRow}>\n <div className={css.deviceMeta}>\n <span className={css.deviceName}>\n {deviceNameFromUserAgent(device.userAgent) ?? t('devices.unknown')}\n </span>\n <span className={clsx(css.devicePresence, device.online ? css.deviceOnline : css.deviceOffline)}>\n {device.online ? t('devices.online') : t('devices.offline')}\n </span>\n <span className={css.deviceSeen}>\n {t('devices.lastSeen', { time: formatLastSeen(device.lastSeenAt) })}\n </span>\n </div>\n <button\n type=\"button\"\n className={css.deviceRevoke}\n aria-label={t('devices.revoke.label')}\n onClick={() => { onRevoke(device.id) }}\n >\n {t('devices.revoke')}\n </button>\n </li>\n ))}\n </ul>\n )}\n </section>\n </>\n )}\n </div>\n )\n}\n","/**\n * Phone glyph for the sidebar remote-control trigger. Not part of the\n * shared icon set (ui-primitives has no phone icon); matches the outline\n * style with currentColor strokes.\n */\n\n/** Icon props mirroring ui-primitives' IconProps. */\nexport interface PhoneIconProps {\n /** Glyph size in px (default 16). */\n size?: number\n /** Extra class for layout placement. */\n className?: string\n}\n\n/**\n * Render the phone icon.\n * @param props - size and optional class.\n * @returns the svg element.\n */\nexport function PhoneIcon({ size = 16, className }: PhoneIconProps) {\n return (\n <svg width={size} height={size} className={className} viewBox=\"0 0 16 16\" fill=\"none\" aria-hidden=\"true\">\n <path\n d=\"M4.2 1.8h2.4l.9 2.4-1.5 1.1a7.4 7.4 0 0 0 4.7 4.7l1.1-1.5 2.4.9v2.4a.9.9 0 0 1-1 .9A11.4 11.4 0 0 1 3.3 2.8a.9.9 0 0 1 .9-1Z\"\n stroke=\"currentColor\"\n strokeWidth=\"1.3\"\n strokeLinejoin=\"round\"\n />\n </svg>\n )\n}\n","/**\n * Browser-side wire helpers for the /api/update surface. Plain fetch over\n * same-origin /api like the pairing client; the host half enforces the\n * loopback-only fence and owns the pnpm run.\n */\n\nimport type { UpdateRunResult, UpdateStatus } from '../update.ts'\n\n/**\n * Error thrown when the update status probe fails: carries the HTTP status\n * so the panel can tell \"the update route is not mounted\" (404 — the host\n * process runs an older plugin build) apart from real network failures.\n */\nexport class UpdateStatusError extends Error {\n /** HTTP status of the failed response (0 when the fetch never returned). */\n readonly status: number\n constructor(status: number) {\n super('update status unavailable (HTTP ' + String(status) + ')')\n this.status = status\n }\n}\n\n/**\n * Probe the update status: install mode, owning profile, and the\n * current-vs-latest comparison for every family package.\n * @returns the status snapshot.\n */\nexport async function fetchUpdateStatus(): Promise<UpdateStatus> {\n let response: Response\n try {\n response = await fetch('/api/update/status')\n } catch {\n // Network-level failure: nothing came back at all.\n throw new UpdateStatusError(0)\n }\n if (!response.ok) throw new UpdateStatusError(response.status)\n return await response.json() as UpdateStatus\n}\n\n/**\n * Run the update (pnpm update in the owning profile). Blocks until pnpm\n * exits — the panel shows an in-flight state meanwhile.\n * @returns the run outcome.\n */\nexport async function runUpdate(): Promise<UpdateRunResult> {\n const response = await fetch('/api/update/run', { method: 'POST' })\n if (!response.ok) throw new Error('update run unavailable')\n return await response.json() as UpdateRunResult\n}\n","/**\n * The update panel body: check progress, version comparison, the\n * auto-update in-flight state, and the outcome (restart hint on success,\n * translated failure on error). Pure presentation — all state arrives\n * through props from the entry behavior component.\n */\nimport type { TranslateNS } from '@deepseek-ai/dsh-client-ui-slots'\nimport { IconCloseOutline16, IconRefreshOutline16 } from '@deepseek-ai/dsh-client-ui-primitives'\nimport type { UpdateReleaseNotes, UpdateRunResult, UpdateStatus } from '../update.ts'\nimport css from \"./remote.module.css\"\n\n/** The panel view state, owned by the entry component. */\nexport type UpdateView =\n | { kind: 'checking' }\n | { kind: 'result'; status: UpdateStatus }\n | { kind: 'updating'; status: UpdateStatus }\n | { kind: 'done'; result: UpdateRunResult }\n | { kind: 'error'; message: string; detail?: string }\n\n/** Full panel props: copy + view state + actions. */\nexport interface UpdatePanelProps {\n t: TranslateNS<'remote'>\n view: UpdateView\n onClose(): void\n /** Re-run the check from a terminal state. */\n onRecheck(): void\n /** Start the update from the result view (the confirmation step, #507). */\n onStartUpdate(status: UpdateStatus): void\n}\n\n/** The anchor package name (aggregate first) for copy purposes. */\nfunction anchorName(status: UpdateStatus | undefined): string | undefined {\n return status?.anchor ?? status?.packages[0]?.name\n}\n\n/** The latest npm release of the anchor, for reference copy. */\nfunction anchorLatest(status: UpdateStatus | undefined): string | undefined {\n return status?.packages[0]?.latest\n}\n\n/**\n * Render the update panel.\n * @param props - copy, view state, and actions.\n * @returns the panel element tree.\n */\nexport function UpdatePanel({ t, view, onClose, onRecheck, onStartUpdate }: UpdatePanelProps) {\n const status = view.kind === \"result\" || view.kind === \"updating\" ? view.status : undefined\n const title = view.kind === \"done\" && view.result.ok ? t(\"update.done\") : t(\"update.title\")\n const subtitle = subtitleOf(t, view)\n return (\n <div className={css.panel} role=\"dialog\" aria-modal=\"true\" aria-label={title}>\n <div className={css.header}>\n <div className={css.heading}>\n <h2 className={css.title}>{title}</h2>\n {subtitle !== undefined && <p className={css.subtitle}>{subtitle}</p>}\n </div>\n <button type=\"button\" className={css.close} aria-label={t(\"update.close\")} onClick={onClose}>\n <IconCloseOutline16 />\n </button>\n </div>\n {view.kind === \"checking\" && <p className={css.updateStatus}>{t(\"update.checking\")}</p>}\n {view.kind === \"result\" && status !== undefined && <ResultBody t={t} status={status} />}\n {view.kind === \"result\" && status !== undefined && status.mode === \"npm\" && status.outdated && status.error === undefined && (\n <div className={css.updateActions}>\n <button type=\"button\" className={css.updateRetry} onClick={() => onStartUpdate(status)}>\n {t(\"update.start\")}\n </button>\n </div>\n )}\n {view.kind === \"updating\" && status !== undefined && (\n <div>\n <p className={css.updateStatus}>\n {t(\"update.updating\", { name: anchorName(status) ?? \"\", version: anchorLatest(status) ?? \"\" })}\n </p>\n <p className={css.updateDetail}>{t(\"update.cooldownNotice\")}</p>\n <PackageSummary t={t} status={status} />\n </div>\n )}\n {view.kind === \"done\" && <DoneBody t={t} result={view.result} />}\n {view.kind === \"error\" && (\n <div>\n <p className={css.updateError}>{view.message}</p>\n {view.detail !== undefined && <pre className={css.updateOutput}>{view.detail}</pre>}\n </div>\n )}\n {(view.kind === \"done\" || view.kind === \"error\") && (\n <div className={css.updateActions}>\n <button type=\"button\" className={css.updateRetry} onClick={onRecheck}>\n <IconRefreshOutline16 /> {t(\"update.retry\")}\n </button>\n </div>\n )}\n </div>\n )\n}\n\n/** The subtitle copy per view state (absent on plain results). */\nfunction subtitleOf(t: TranslateNS<\"remote\">, view: UpdateView): string | undefined {\n switch (view.kind) {\n case \"checking\":\n return t(\"update.checking\")\n case \"updating\":\n return t(\"update.updatingTitle\")\n case \"result\":\n return undefined\n case \"done\":\n return view.result.ok ? t(\"update.doneDetail\") : t(\"update.error\")\n case \"error\":\n // The error body below carries the message; no subtitle duplication.\n return undefined\n }\n}\n\n/** The checked result body: mode banner + version list. */\nfunction ResultBody({ t, status }: { t: TranslateNS<\"remote\">; status: UpdateStatus }) {\n const anchor = anchorName(status)\n const latest = anchorLatest(status)\n if (status.mode === \"link\") {\n return (\n <div>\n <p className={css.updateStatus}>{t(\"update.linkMode\")}</p>\n <p className={css.updateDetail}>{t(\"update.linkModeDetail\", { version: latest ?? \"-\" })}</p>\n </div>\n )\n }\n if (status.mode === \"missing\") {\n return (\n <div>\n <p className={css.updateStatus}>{t(\"update.missing\")}</p>\n <p className={css.updateDetail}>{t(\"update.missingDetail\")}</p>\n </div>\n )\n }\n if (status.error === \"registry-unreachable\") {\n return (\n <div>\n <p className={css.updateStatus}>{t(\"update.offline\")}</p>\n <p className={css.updateDetail}>{t(\"update.offlineDetail\")}</p>\n </div>\n )\n }\n if (status.outdated) {\n return (\n <div>\n <p className={css.updateStatus}>{t(\"update.found\")}</p>\n <p className={css.updateDetail}>\n {anchor !== undefined ? t(\"update.foundDetail\", { name: anchor, version: latest ?? \"\" }) : \"\"}\n </p>\n <p className={css.updateDetail}>{t(\"update.cooldownNotice\")}</p>\n <PackageSummary t={t} status={status} />\n </div>\n )\n }\n return (\n <div>\n <p className={css.updateStatus}>{t(\"update.upToDate\")}</p>\n {anchor !== undefined && latest !== undefined && (\n <p className={css.updateDetail}>{t(\"update.upToDateDetail\", { name: anchor, version: latest })}</p>\n )}\n <PackageSummary t={t} status={status} />\n </div>\n )\n}\n\n/** Release-note summary when available; otherwise fall back to the package list. */\nfunction PackageSummary({ t, status }: { t: TranslateNS<'remote'>; status: UpdateStatus }) {\n if (status.notes === undefined) return <PackageList status={status} />\n return (\n <div>\n <ReleaseNotes t={t} notes={status.notes} />\n <details className={css.updateVersions}>\n <summary className={css.updateVersionsSummary}>{t(\"update.componentVersions\")}</summary>\n <PackageList status={status} />\n </details>\n </div>\n )\n}\n\n/** Render GitHub Release sections as a compact three-group list. */\nfunction ReleaseNotes({ t, notes }: { t: TranslateNS<'remote'>; notes: UpdateReleaseNotes }) {\n const sections = [\n { key: 'features', title: t(\"update.releaseFeatures\"), items: notes.features },\n { key: 'fixes', title: t(\"update.releaseFixes\"), items: notes.fixes },\n { key: 'other', title: t(\"update.releaseOther\"), items: notes.other },\n ].filter(section => section.items.length > 0)\n if (sections.length === 0) return <p className={css.updateDetail}>{t(\"update.releaseUnavailable\")}</p>\n return (\n <div className={css.updateNotes}>\n <h3 className={css.updateNotesTitle}>{t(\"update.releaseNotes\", { version: notes.version })}</h3>\n {sections.map(section => (\n <section key={section.key} className={css.updateNoteSection}>\n <h4 className={css.updateNoteHeading}>{section.title}</h4>\n <ul className={css.updateNoteList}>\n {section.items.map((item, index) => (\n <li key={index} className={css.updateNoteItem}>{item}</li>\n ))}\n </ul>\n </section>\n ))}\n </div>\n )\n}\n\n/** The per-package current → latest comparison list. */\nfunction PackageList({ status }: { status: UpdateStatus }) {\n if (status.packages.length === 0) return null\n return (\n <ul className={css.updateList}>\n {status.packages.map(packageStatus => (\n <li key={packageStatus.name} className={css.updateListItem}>\n <span className={css.updateListName}>{packageStatus.name}</span>\n <span className={css.updateListVersions}>\n {packageStatus.current}\n {packageStatus.latest !== undefined && packageStatus.latest !== packageStatus.current && (\n <> → {packageStatus.latest}</>\n )}\n </span>\n </li>\n ))}\n </ul>\n )\n}\n\n/** The outcome body: success + restart hint, or the translated failure. */\nfunction DoneBody({ t, result }: { t: TranslateNS<\"remote\">; result: UpdateRunResult }) {\n if (result.ok) {\n // The title already reads \"Update complete\"; the body carries the details.\n return (\n <div>\n <p className={css.updateDetail}>{t(\"update.doneDetail\")}</p>\n <p className={css.updateDetail}>{t(\"update.restartHint\")}</p>\n </div>\n )\n }\n const message = errorMessageOf(t, result)\n return (\n <div>\n <p className={css.updateError}>{message}</p>\n {result.output.trim() !== \"\" && <pre className={css.updateOutput}>{result.output.trim()}</pre>}\n </div>\n )\n}\n\n/** Translate a structured failure code; fall back to the raw message. */\nfunction errorMessageOf(t: TranslateNS<\"remote\">, result: UpdateRunResult): string {\n switch (result.errorCode) {\n case \"pnpm-missing\": return t(\"update.error.pnpmMissing\")\n case \"timeout\": return t(\"update.error.timeout\")\n case \"not-found\": return t(\"update.error.notFound\")\n case \"link\": return t(\"update.error.link\")\n case \"pnpm-failed\": return t(\"update.error.pnpmFailed\", { code: String(result.exitCode ?? \"?\") })\n case \"stale\": return t(\"update.error.stale\")\n case \"verify-failed\": return t(\"update.error.verifyFailed\")\n default: return result.error ?? t(\"update.error.unknown\")\n }\n}\n","/**\n * The sidebar update seat: the download trigger beside the remote-control\n * trigger plus the update panel modal. Owns the flow — probe the registry\n * on open, show the result, and let the user start the update from the\n * result view (#507), then report the outcome (restart hint on success,\n * translated failure on error).\n * Component-local state per the client stack rules.\n */\nimport { useCallback, useEffect, useRef, useState } from \"react\"\nimport { createPortal } from \"react-dom\"\nimport type { TranslateNS } from '@deepseek-ai/dsh-client-ui-slots'\nimport { IconDownloadOutline16 } from '@deepseek-ai/dsh-client-ui-primitives'\nimport type { UpdateStatus } from '../update.ts'\nimport { fetchUpdateStatus, runUpdate, UpdateStatusError } from \"./update-api.ts\"\nimport { UpdatePanel, type UpdateView } from \"./UpdatePanel.tsx\"\nimport css from \"./remote.module.css\"\n\n/** Entry props: the sidebar column state + the standard locale seat. */\nexport interface UpdateEntryProps {\n /** Whether the sidebar renders wide content (false = 56px rail). */\n wide: boolean\n t: TranslateNS<'remote'>\n}\n\n/**\n * Render the update trigger and panel.\n * @param props - column state and locale seat.\n * @returns the entry element tree.\n */\nexport function UpdateEntry({ wide, t }: UpdateEntryProps) {\n const [open, setOpen] = useState(false)\n const [view, setView] = useState<UpdateView>({ kind: \"checking\" })\n const [updateAvailable, setUpdateAvailable] = useState(false)\n const runToken = useRef(0)\n const availabilityToken = useRef(0)\n const mounted = useRef(false)\n\n const probeAvailability = useCallback(async (): Promise<void> => {\n const token = ++availabilityToken.current\n try {\n const status = await fetchUpdateStatus()\n if (token === availabilityToken.current) {\n setUpdateAvailable(status.mode === \"npm\" && status.outdated)\n }\n } catch {\n if (token === availabilityToken.current) setUpdateAvailable(false)\n }\n }, [])\n\n const check = useCallback(async (): Promise<void> => {\n const availabilityCheck = ++availabilityToken.current\n setView({ kind: \"checking\" })\n let status: UpdateStatus\n try {\n status = await fetchUpdateStatus()\n } catch (error) {\n if (availabilityCheck === availabilityToken.current) setUpdateAvailable(false)\n // HTTP 404: the update route is not mounted — the host process runs an\n // older plugin build (client refreshed, host did not). Restarting dsh\n // web loads the new plugin; a plain network failure gets the generic\n // offline copy instead of a misleading \"cannot reach update source\".\n if (error instanceof UpdateStatusError && error.status === 404) {\n setView({ kind: \"error\", message: t(\"update.unmounted\"), detail: t(\"update.unmountedDetail\") })\n return\n }\n setView({ kind: \"error\", message: t(\"update.offline\"), detail: t(\"update.offlineDetail\") })\n return\n }\n if (availabilityCheck === availabilityToken.current) {\n setUpdateAvailable(status.mode === \"npm\" && status.outdated)\n }\n if (status.error === \"registry-unreachable\") {\n setView({ kind: \"result\", status })\n return\n }\n // Checking never starts an update by itself (#507): the result view\n // carries the confirmation button that calls startUpdate.\n setView({ kind: \"result\", status })\n }, [t])\n\n const startUpdate = useCallback(async (status: UpdateStatus): Promise<void> => {\n if (status.mode !== \"npm\" || !status.outdated) return\n setView({ kind: \"updating\", status })\n const token = ++runToken.current\n try {\n const result = await runUpdate()\n if (result.ok && mounted.current) setUpdateAvailable(false)\n if (token !== runToken.current) return\n setView({ kind: \"done\", result })\n } catch {\n if (token !== runToken.current) return\n setView({ kind: \"error\", message: t(\"update.error\"), detail: t(\"update.offlineDetail\") })\n }\n }, [t])\n\n const openPanel = useCallback((): void => {\n setOpen(true)\n void check()\n }, [check])\n\n const closePanel = useCallback((): void => {\n runToken.current++\n setOpen(false)\n }, [])\n\n // Check once after mount without opening the panel or starting an update.\n useEffect(() => {\n mounted.current = true\n void probeAvailability()\n return () => {\n mounted.current = false\n runToken.current++\n availabilityToken.current++\n }\n }, [probeAvailability])\n\n const updateLabel = updateAvailable ? t(\"update.availableLabel\") : t(\"update.label\")\n\n return (\n <>\n <button\n type=\"button\"\n className={css.trigger}\n data-wide={wide ? (updateAvailable ? \"wide\" : undefined) : \"rail\"}\n data-update-available={updateAvailable ? \"true\" : undefined}\n aria-label={updateLabel}\n aria-expanded={open}\n title={updateLabel}\n onClick={openPanel}\n >\n <IconDownloadOutline16 size={wide ? 16 : 18} />\n {updateAvailable && wide && (\n <span className={css.updateBadgeText}>{t(\"update.badge\")}</span>\n )}\n </button>\n {open && createPortal((\n <div className={css.overlay} role=\"presentation\">\n <div className={css.mask} aria-hidden=\"true\" onClick={closePanel} />\n <UpdatePanel t={t} view={view} onClose={closePanel} onRecheck={() => { void check() }} onStartUpdate={(status) => { void startUpdate(status) }} />\n </div>\n ), document.body)}\n </>\n )\n}\n","/**\n * The sidebar remote-control seat: the update trigger plus the phone-icon\n * trigger beside the settings button, and the pairing panel modal. Owns the\n * panel behavior — token minting on open, the status SSE subscription,\n * stop/refresh/copy — and renders the pure {@link RemotePanel} body. The\n * update seat (the dsh-web self-update flow) rides the same footer row,\n * rendered by {@link UpdateEntry}. Component-local state per the client\n * stack rules: nothing here survives remounts or crosses entries.\n */\nimport { useCallback, useEffect, useRef, useState } from 'react'\nimport { createPortal } from 'react-dom'\nimport type { PropsLocale } from '@deepseek-ai/dsh-client-ui-slots'\nimport type { PairingPhase } from '../pairing.ts'\nimport { RemotePanel, type PanelState } from './RemotePanel.tsx'\nimport { copyText, issuePair, revokePair, stopPair, type DeviceFrame, type IssueResponse, type PairStateFrame, type RelayStatusFrame, type TunnelStatusFrame } from './pair-api.ts'\nimport { PhoneIcon } from './PhoneIcon.tsx'\nimport { UpdateEntry } from './UpdateEntry.tsx'\nimport css from './remote.module.css'\n\n/** Entry props: the sidebar column state and the standard locale seat. */\nexport type RemoteEntryProps = PropsLocale<'remote'> & {\n /** Whether the sidebar renders wide content (false = 56px rail). */\n wide: boolean\n}\n\n/**\n * Apply one status frame onto the current state: the ready state mirrors\n * the full phase/device picture, while the lan-required banner only keeps\n * the auto-tunnel frame (the signal for the running re-issue).\n */\nfunction mergeFrame(state: PanelState, frame: PairStateFrame): PanelState {\n if (state.kind === 'lan-required') {\n return {\n ...state,\n ...(frame.tunnel !== undefined ? { tunnel: frame.tunnel } : {}),\n }\n }\n if (state.kind !== 'ready') return state\n return {\n ...state,\n phase: frame.phase,\n deviceCount: frame.deviceCount,\n onlineCount: frame.onlineCount,\n devices: frame.devices ?? [],\n ...(frame.tunnel !== undefined ? { tunnel: frame.tunnel as TunnelStatusFrame } : {}),\n ...(frame.relay !== undefined ? { relay: frame.relay } : {}),\n ...(frame.posture !== undefined ? { posture: frame.posture } : {}),\n }\n}\n\n/**\n * Render the remote-control trigger and panel.\n * @param props - composed slot props (contract in this package).\n * @returns the entry element tree.\n */\nexport function RemoteEntry({ wide, t }: RemoteEntryProps) {\n const [open, setOpen] = useState(false)\n const [state, setState] = useState<PanelState>({ kind: 'lan-required' })\n // Latest-state mirror for the EventSource callback: transition detection\n // must live outside setState updaters (updaters may run twice and must be\n // pure), so mint decisions read this ref instead.\n const stateRef = useRef(state)\n useEffect(() => { stateRef.current = state }, [state])\n const [copied, setCopied] = useState<boolean>(false)\n const [copiedToken, setCopiedToken] = useState<boolean>(false)\n const eventSource = useRef<EventSource | undefined>(undefined)\n // Generation counter for the open flow: closing (or re-opening) the panel\n // bumps it, so an in-flight issue() that resolves after a close does not\n // spawn a stray EventSource.\n const openSeq = useRef(0)\n\n const closeEventSource = useCallback(() => {\n eventSource.current?.close()\n eventSource.current = undefined\n }, [])\n\n const mint = useCallback(async (address?: string): Promise<PanelState> => {\n let result: IssueResponse\n try {\n result = await issuePair(address)\n } catch {\n // Fetch/network failure: show an explicit state instead of silently\n // leaving the panel on its initial banner.\n return { kind: 'unreachable' }\n }\n if (!result.ok) {\n // 403 is the loopback-only fence refusing a LAN origin (the panel is a\n // desktop control endpoint); 409 means the server never bound 0.0.0.0;\n // 400 means the requested LAN literal is no longer constructible.\n if (result.code === 'forbidden') return { kind: 'loopback-required' }\n if (result.code === 'unknown-address') return { kind: 'unreachable' }\n return { kind: 'lan-required' }\n }\n const publicBaseUrl = result.publicBaseUrl\n return {\n kind: 'ready',\n url: result.url,\n token: result.token,\n expiresAt: result.expiresAt,\n expired: Date.now() > result.expiresAt,\n phase: 'waiting',\n deviceCount: 0,\n onlineCount: 0,\n devices: [] as DeviceFrame[],\n // Whether this QR is built on the configured public (tunneled) base.\n public: publicBaseUrl !== undefined && result.url.startsWith(publicBaseUrl),\n ...(publicBaseUrl !== undefined ? { publicBaseUrl } : {}),\n // The issued URL names the requested (or default first) literal; the\n // public link has no LAN literal, so no radio row is selected then.\n address: address ?? result.lanAddresses[0] ?? '',\n lanAddresses: result.lanAddresses,\n }\n }, [])\n\n const openPanel = useCallback(async (): Promise<void> => {\n const seq = ++openSeq.current\n setOpen(true)\n const next = await mint()\n // A close (or re-open) during the await invalidates this issue: skip the\n // state write and the stream so a panel closed mid-mint neither leaks an\n // EventSource nor resurrects a stale QR.\n if (seq !== openSeq.current) return\n setState(next)\n // Live status: the desktop panel mirrors the pairing service state. The\n // stream makes sense in the ready state and on the lan-required banner —\n // there the auto-tunnel may still be starting, and following its frames\n // lets the panel re-issue once it runs. The loopback-required and\n // unreachable origins are fenced out of the events endpoint, so opening\n // it there would just start a doomed reconnect loop.\n if (next.kind !== 'ready' && next.kind !== 'lan-required') return\n const source = new EventSource('/api/pair/events')\n eventSource.current = source\n source.onmessage = (event) => {\n try {\n const frame = JSON.parse(event.data as string) as PairStateFrame\n if (frame.type !== 'state') return\n // The auto-tunnel crossed into running while the panel sat on the\n // lan-required banner: re-issue so the server hands back a ready QR\n // built on the public base (only on the transition into running, to\n // avoid mint storms). Detected on the ref, outside the updater: an\n // updater may be invoked twice and must stay pure, so mint() cannot\n // run inside it.\n const previous = stateRef.current\n if (\n previous.kind === 'lan-required'\n && frame.tunnel?.state === 'running'\n && previous.tunnel?.state !== 'running'\n ) {\n void mint().then(setState)\n return\n }\n setState(current => mergeFrame(current, frame))\n } catch {\n // Malformed frames are dropped; the snapshot on open is authoritative.\n }\n }\n }, [mint])\n\n const closePanel = useCallback(() => {\n openSeq.current += 1\n closeEventSource()\n setOpen(false)\n }, [closeEventSource])\n\n // Expiry flip: one timeout per token lifetime (reset by refresh).\n useEffect(() => {\n if (state.kind !== 'ready') return\n if (state.expired) return\n const delay = state.expiresAt - Date.now()\n if (delay <= 0) {\n setState(previous => previous.kind === 'ready' ? { ...previous, expired: true } : previous)\n return\n }\n const timer = window.setTimeout(() => {\n setState(previous => previous.kind === 'ready' ? { ...previous, expired: true } : previous)\n }, delay)\n return () => { window.clearTimeout(timer) }\n }, [state])\n\n // Unmount safety: never leave the stream open.\n useEffect(() => closeEventSource, [closeEventSource])\n\n const handleStop = useCallback(() => {\n // A failed stop request is harmless: the optimistic phase flip below\n // keeps the UI honest, and the status stream confirms the stopped phase.\n void stopPair().catch(() => {})\n // Optimistic fallback; the status stream confirms with the stopped phase.\n setState(previous => previous.kind === 'ready' ? { ...previous, phase: 'stopped' as PairingPhase, devices: [] } : previous)\n }, [])\n\n const handleRevoke = useCallback((deviceId: string) => {\n void revokePair(deviceId).catch(() => {})\n setState(previous => previous.kind === 'ready'\n ? { ...previous, devices: previous.devices.filter(device => device.id !== deviceId) }\n : previous)\n }, [])\n\n const handleRefresh = useCallback(() => {\n void mint().then(setState)\n }, [mint])\n\n /** Re-mint against another LAN literal (multi-homed machines). */\n const handlePickAddress = useCallback((address: string) => {\n void mint(address).then(setState)\n }, [mint])\n\n /** Re-mint against the configured public (tunneled) base. */\n const handlePickPublic = useCallback(() => {\n void mint().then(setState)\n }, [mint])\n\n const handleCopy = useCallback((url: string) => {\n void copyText(url).then((ok) => {\n if (!ok) return\n setCopied(true)\n window.setTimeout(() => { setCopied(false) }, 1500)\n })\n }, [])\n\n const handleCopyToken = useCallback((token: string) => {\n void copyText(token).then((ok) => {\n if (!ok) return\n setCopiedToken(true)\n window.setTimeout(() => { setCopiedToken(false) }, 1500)\n })\n }, [])\n\n return (\n <>\n <div className={css.entryRow} data-rail={wide ? undefined : 'rail'}>\n <UpdateEntry wide={wide} t={t} />\n <TooltipAnchor wide={wide} label={t('entry.label')} onClick={openPanel} expanded={open} />\n </div>\n {open && createPortal((\n <div className={css.overlay} role=\"presentation\">\n <div className={css.mask} aria-hidden=\"true\" onClick={closePanel} />\n <RemotePanel\n t={t}\n state={state}\n copied={copied}\n copiedToken={copiedToken}\n onClose={closePanel}\n onStop={handleStop}\n onRefresh={handleRefresh}\n onCopy={handleCopy}\n onCopyToken={handleCopyToken}\n onPickAddress={handlePickAddress}\n onPickPublic={handlePickPublic}\n onRevoke={handleRevoke}\n />\n </div>\n ), document.body)}\n </>\n )\n}\n\n/** The trigger: an icon-only control with a persistent accessible label. */\nfunction TooltipAnchor({ wide, label, onClick, expanded }: { wide: boolean; label: string; onClick: () => void; expanded: boolean }) {\n return (\n <button\n type=\"button\"\n className={css.trigger}\n data-wide={wide ? 'wide' : 'rail'}\n aria-label={label}\n aria-expanded={expanded}\n title={label}\n onClick={onClick}\n >\n <PhoneIcon size={wide ? 16 : 18} />\n </button>\n )\n}\n","/**\n * Sidebar footer-seat wrapper for the remote-control entry.\n *\n * Current dsh web shells declare `sidebar.footer.action` (the seat beside\n * the settings trigger) instead of the legacy `sidebar.remote` seat this\n * plugin was written against. The footer seat supplies `{ wide }`; the\n * pairing link is origin-agnostic, so no workspace source is involved.\n */\nimport type { PropsLocale } from '@deepseek-ai/dsh-client-ui-slots'\nimport { RemoteEntry } from './RemoteEntry.tsx'\n\n/** Entry props: the footer seat's column state and the standard locale seat. */\nexport type FooterRemoteEntryProps = PropsLocale<'remote'> & {\n /** Whether the sidebar renders wide content (false = 56px rail). */\n wide: boolean\n}\n\n/**\n * Render the remote-control trigger + pairing panel from the footer seat.\n * @param props - composed slot props (footer seat subset).\n * @returns the entry element tree.\n */\nexport function FooterRemoteEntry(props: FooterRemoteEntryProps) {\n return (\n <RemoteEntry\n wide={props.wide}\n t={props.t}\n />\n )\n}\n","/**\n * One-time failed-pairing notice: a fixed toast rendered on the phone after\n * a QR accept failed (invalid/used token or a network error). Mounted by\n * the client apply with a plain React root — no slot machinery for a\n * transient diagnostic.\n */\nimport { useEffect, useState } from 'react'\nimport type { TranslateNS } from '@deepseek-ai/dsh-client-ui-slots'\nimport css from './remote.module.css'\n\n/** Notice props: localized copy. */\nexport interface PairFailedNoticeProps {\n t: TranslateNS<'remote'>\n}\n\n/**\n * Render the failed-pair toast (auto-dismisses).\n * @param props - localized copy.\n * @returns the toast element.\n */\nexport function PairFailedNotice({ t }: PairFailedNoticeProps) { const [visible, setVisible] = useState(true)\n useEffect(() => {\n const timer = window.setTimeout(() => { setVisible(false) }, 8000)\n return () => { window.clearTimeout(timer) }\n }, [])\n if (!visible) return null\n return (\n <div className={css.notice} role=\"alert\">\n <p className={css.noticeTitle}>{t('pair.failed.title')}</p>\n <p className={css.noticeDetail}>{t('pair.failed.detail')}</p>\n </div>\n )\n}\n","// Generated by scripts/sync-shared.mjs from shared/client/settings/PluginSettingsCard.tsx. Do not edit this copy; edit the shared source and run \"node scripts/sync-shared.mjs\".\n/**\n * Family-shared chrome for plugin settings cards: a disclosure header naming\n * the plugin and what its settings govern, the controls inside, and the save\n * that writes them. Renders nothing while the namespace is unavailable — a\n * deployment that does not compose the owning plugin should show no trace of\n * it. Inlined into each consumer's client bundle; mirrors the official\n * ui-plugin-config PluginCard in a self-contained slice.\n */\n\nimport { useCallback, useEffect, useLayoutEffect, useRef, useState, type KeyboardEvent, type ReactNode } from 'react'\nimport type { CardShell } from './settings-form.ts'\nimport css from './settings-card.module.css'\n\n/** Copy keys the card chrome itself reads; every consumer locale carries this shared vocabulary. */\nexport const CARD_COPY_KEYS = [\n 'settings.collapse',\n 'settings.expand',\n 'settings.notExposed',\n 'settings.unsaved',\n 'settings.readOnly',\n 'settings.saveFailed',\n 'settings.discard',\n 'settings.save',\n 'settings.saving',\n] as const\n\n/** Copy key the card chrome itself reads. */\nexport type CardCopyKey = (typeof CARD_COPY_KEYS)[number]\n\n/** Key domain for the plugin's own copy (inferred per consumer). */\nexport type SettingsCardKey<TKey extends string = string> = TKey | CardCopyKey\n\n/** Card chrome shared by every plugin settings card. */\nexport interface PluginSettingsCardProps<TKey extends string = string> {\n /** Locale reader for this card's copy. */\n t: (key: SettingsCardKey<TKey>, params?: Record<string, string | number>) => string\n /** Locale key of the plugin's name. */\n titleKey: TKey\n /** Locale key of the line describing what this plugin's settings govern. */\n descriptionKey: TKey\n /** Optional rich header description rendered instead of the plain t(descriptionKey) text (the plain text stays as the tooltip). */\n descriptionNode?: ReactNode\n /** The card's form state: availability, writability, and what a save would do. */\n state: CardShell\n /** Write every staged edit. */\n onSave: () => void\n /** Drop every staged edit. */\n onDiscard: () => void\n /**\n * Render the controls expanded on arrival (still collapsible). Defaults to\n * true: promoted first-level sections show their settings immediately.\n */\n defaultOpen?: boolean\n /**\n * Render without the collapse affordance: a static header and an always\n * visible body. Used by first-level settings sections whose nav entry\n * already provides the selection.\n */\n alwaysOpen?: boolean\n /**\n * Hide the save/discard footer: cards whose body applies its own changes\n * immediately (an embedded external settings section) have no staged\n * edits, so the footer would sit there permanently disabled.\n */\n hideFooter?: boolean\n /** The plugin's controls. */\n children: ReactNode\n}\n\n/**\n * Render one plugin settings card.\n * @param props - the plugin's copy keys, its form state, and its controls.\n * @returns the card, or nothing while the namespace is still loading.\n */\nexport function PluginSettingsCard<TKey extends string = string>(props: PluginSettingsCardProps<TKey>) {\n const [open, setOpen] = useState(props.defaultOpen ?? true)\n const { state, alwaysOpen } = props\n if (!state.available) return null\n const title = props.t(props.titleKey)\n const description = props.t(props.descriptionKey)\n const blocked = !state.dirty || state.invalid || state.saving\n const expanded = alwaysOpen === true || open\n const cardClass = expanded ? `${css.cardOpen} ${css.card}` : css.card\n // With alwaysOpen the nav entry already provides the selection, so the\n // header is a static title row instead of a disclosure button.\n const header = alwaysOpen === true\n ? (\n <div className={css.headerStatic}>\n <span className={css.headText}>\n <span className={css.name} title={title}>{title}</span>\n <span className={css.description} title={description}>{props.descriptionNode ?? description}</span>\n </span>\n {state.dirty ? <span className={css.pending} title={props.t('settings.unsaved')}>{props.t('settings.unsaved')}</span> : null}\n </div>\n )\n : (\n <button\n type=\"button\"\n className={css.header}\n aria-expanded={open}\n aria-label={`${props.t(open ? 'settings.collapse' : 'settings.expand')}: ${title}`}\n onClick={() => { setOpen(!open) }}\n >\n <span className={css.headText}>\n <span className={css.name} title={title}>{title}</span>\n <span className={css.description} title={description}>{props.descriptionNode ?? description}</span>\n </span>\n {state.dirty ? <span className={css.pending} title={props.t('settings.unsaved')}>{props.t('settings.unsaved')}</span> : null}\n <svg\n width=\"14\"\n height=\"14\"\n viewBox=\"0 0 14 14\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n className={open ? `${css.chevron} ${css.chevronOpen}` : css.chevron}\n >\n <path\n d=\"M11.8486 5.5L11.4238 5.92383L8.69727 8.65137C8.44157 8.90706 8.21562 9.13382 8.01172 9.29785C7.79912 9.46883 7.55595 9.61756 7.25 9.66602C7.08435 9.69222 6.91565 9.69222 6.75 9.66602C6.44405 9.61756 6.20088 9.46883 5.98828 9.29785C5.78438 9.13382 5.55843 8.90706 5.30273 8.65137L2.57617 5.92383L2.15137 5.5L3 4.65137L3.42383 5.07617L6.15137 7.80273C6.42595 8.07732 6.59876 8.24849 6.74023 8.3623C6.87291 8.46904 6.92272 8.47813 6.9375 8.48047C6.97895 8.48703 7.02105 8.48703 7.0625 8.48047C7.07728 8.47813 7.12709 8.46904 7.25977 8.3623C7.40124 8.24849 7.57405 8.07732 7.84863 7.80273L10.5762 5.07617L11 4.65137L11.8486 5.5Z\"\n fill=\"currentColor\"\n />\n </svg>\n </button>\n )\n // The namespace exists but the Host does not serve it to this client (the\n // official settings allowlist omits third-party namespaces): show a card\n // that explains the gap instead of vanishing, so a missing card never\n // reads as a missing plugin.\n if (!state.exposed) {\n return (\n <li className={cardClass}>\n {header}\n {expanded\n ? (\n <div className={css.body}>\n <p className={css.notExposed} role=\"status\">{props.t('settings.notExposed')}</p>\n </div>\n )\n : null}\n </li>\n )\n }\n return (\n <li className={cardClass}>\n {header}\n {expanded\n ? (\n <div className={css.body}>\n {!state.writable ? <p className={css.readOnly} role=\"status\">{props.t('settings.readOnly')}</p> : null}\n {props.children}\n {props.hideFooter === true\n ? null\n : (\n <div className={css.footer}>\n {state.failed\n ? (\n <p className={css.failed} role=\"status\">\n {props.t('settings.saveFailed')}{state.failedReason ? ' - ' + state.failedReason : ''}\n </p>\n )\n : null}\n <button\n type=\"button\"\n className={css.discard}\n disabled={!state.dirty || state.saving}\n onClick={props.onDiscard}\n >\n {props.t('settings.discard')}\n </button>\n <button\n type=\"button\"\n className={css.save}\n disabled={blocked}\n onClick={props.onSave}\n >\n {props.t(!state.saving ? 'settings.save' : 'settings.saving')}\n </button>\n </div>\n )}\n </div>\n )\n : null}\n </li>\n )\n}\n\n/** Props every field control needs regardless of its value type. */\nexport interface FieldProps {\n /** Stable id associating the label with its control. */\n id: string\n /** Visible label. */\n label: string\n /** One-line explanation rendered under the control. */\n hint: string\n /** Draft text this control renders. */\n text: string\n /** True when saving would leave a user-layer entry for this field. */\n overridden: boolean\n /** True when the draft is not a value this field accepts. */\n invalid: boolean\n /** Copy for the overridden badge. */\n overriddenLabel: string\n /** Copy for the reset control. */\n resetLabel: string\n /** Copy shown in place of the hint while the draft is invalid. */\n invalidLabel: string\n /** Disables every control (read-only document, or an unavailable namespace). */\n disabled: boolean\n /** Stage draft text. */\n onEdit: (text: string) => void\n /** Stage a clear so the field re-inherits the composition layer. */\n onReset: () => void\n}\n\n/** A staged value field. `numeric` only hints the keypad: which drafts a field accepts is decided by its spec. */\nexport function ValueField(props: FieldProps & {\n /** Hints a numeric keypad without narrowing what the control accepts. */\n numeric?: boolean\n /** Placeholder shown while the draft is empty. */\n placeholder?: string\n}) {\n return (\n <div className={css.field}>\n <div className={css.head}>\n <label className={css.label} htmlFor={props.id}>{props.label}</label>\n {props.overridden\n ? (\n <span className={css.badges}>\n <span className={css.badge}>{props.overriddenLabel}</span>\n <button\n type=\"button\"\n className={css.reset}\n disabled={props.disabled}\n onClick={props.onReset}\n >\n {props.resetLabel}\n </button>\n </span>\n )\n : null}\n </div>\n <input\n id={props.id}\n className={props.invalid ? css.inputInvalid : css.input}\n type=\"text\"\n {...props.numeric === true ? { inputMode: 'numeric' as const } : {}}\n {...props.invalid ? { 'aria-invalid': true } : {}}\n value={props.text}\n placeholder={props.placeholder ?? ''}\n disabled={props.disabled}\n onChange={(event) => { props.onEdit(event.target.value) }}\n />\n <p className={props.invalid ? css.invalid : css.hint}>\n {props.invalid ? props.invalidLabel : props.hint}\n </p>\n </div>\n )\n}\n\nconst NON_SKIN_BODY_MARKERS = new Set(['dshSkinCenter', 'dshSidebarCollapsed'])\n// 检测使用使用皮肤,用了皮肤退回原生select样式,防止样式冲突。默认外观下使用优化后的select样式。\nfunction isSkinActive(): boolean {\n const datasetList = Object.keys(document.body.dataset)\n const isActive = datasetList.some(key => key.startsWith('dsh') && !NON_SKIN_BODY_MARKERS.has(key))\n return isActive\n}\n\ninterface SelectOption {\n value: string\n label: string\n}\n\nconst SELECT_CLOSE_MS = 100\n\n/**\n * The shared dual-mode select control. While an appearance skin is active it\n * renders the legacy native `<select>` untouched, so element-level skin\n * selectors keep working; under the default appearance it renders a\n * self-drawn `role=\"listbox\"` popup whose open/close is transition-animated.\n * Staged cards reach it through BooleanField/ChoiceField; immediate-apply\n * editors (the side-card prefs) bind it directly through onEdit.\n * 双模式下拉框:皮肤激活时用原生 select,默认外观用自绘动画弹层。\n */\nexport function SelectField(props: {\n id: string\n options: ReadonlyArray<SelectOption>\n value: string\n disabled: boolean\n invalid: boolean\n onEdit: (text: string) => void\n}) {\n const { id, options, value } = props\n const [open, setOpen] = useState(false)\n const [closing, setClosing] = useState(false)\n const [phase, setPhase] = useState<'initial' | 'open'>('initial')\n const [activeIndex, setActiveIndex] = useState(0)\n const closeTimer = useRef<ReturnType<typeof setTimeout> | undefined>(undefined)\n const wrapRef = useRef<HTMLDivElement | null>(null)\n const popupRef = useRef<HTMLDivElement | null>(null)\n\n const currentIndex = () => {\n const index = options.findIndex(option => option.value === value)\n return index >= 0 ? index : 0\n }\n\n const close = useCallback(() => {\n if (closeTimer.current !== undefined) clearTimeout(closeTimer.current)\n setClosing(true)\n closeTimer.current = setTimeout(() => {\n setClosing(false)\n setOpen(false)\n }, SELECT_CLOSE_MS)\n }, [])\n\n const openPopup = () => {\n if (closeTimer.current !== undefined) clearTimeout(closeTimer.current)\n setActiveIndex(currentIndex())\n setPhase('initial')\n setClosing(false)\n setOpen(true)\n }\n\n const commit = (index: number) => {\n const option = options[index]\n if (option) props.onEdit(option.value)\n close()\n }\n\n const onTriggerClick = () => {\n if (props.disabled) return\n if (open && !closing) close()\n else openPopup()\n }\n\n const onKeyDown = (event: KeyboardEvent<HTMLButtonElement>) => {\n if (props.disabled) return\n const count = options.length\n switch (event.key) {\n case 'ArrowDown':\n case 'ArrowUp':\n case 'Enter':\n case ' ':\n event.preventDefault()\n if (!open) {\n openPopup()\n } else if (!closing) {\n if (event.key === 'ArrowDown') setActiveIndex(index => (index + 1) % count)\n else if (event.key === 'ArrowUp') setActiveIndex(index => (index - 1 + count) % count)\n else commit(activeIndex)\n }\n break\n case 'Escape':\n if (open) {\n event.preventDefault()\n event.stopPropagation()\n close()\n }\n break\n case 'Tab':\n if (open) close()\n break\n }\n }\n\n useEffect(() => () => {\n if (closeTimer.current !== undefined) clearTimeout(closeTimer.current)\n }, [])\n useLayoutEffect(() => {\n if (open && !closing && phase === 'initial') {\n void popupRef.current?.offsetHeight\n setPhase('open')\n }\n }, [open, closing, phase])\n\n useEffect(() => {\n if (!open) return\n const onPointerDown = (event: PointerEvent) => {\n const target = event.target\n if (target instanceof Node && !wrapRef.current?.contains(target)) close()\n }\n document.addEventListener('pointerdown', onPointerDown)\n return () => document.removeEventListener('pointerdown', onPointerDown)\n }, [open, close])\n\n useEffect(() => {\n if (props.disabled && open) close()\n }, [props.disabled, open, close])\n\n // 使用了皮肤则退回原生select样式防止样式冲突。\n if (isSkinActive()) {\n return (\n <select\n id={id}\n className={css.select}\n value={value}\n disabled={props.disabled}\n onChange={(event) => { props.onEdit(event.target.value) }}\n >\n {options.map(option => (\n <option key={option.value} value={option.value}>{option.label}</option>\n ))}\n </select>\n )\n }\n\n const label = options.find(option => option.value === value)?.label ?? ''\n const popupClass = closing\n ? `${css.selectPopup} ${css.selectPopupClose}`\n : phase === 'open'\n ? `${css.selectPopup} ${css.selectPopupOpen}`\n : css.selectPopup\n return (\n <div className={css.selectWrap} ref={wrapRef}>\n <button\n type=\"button\"\n id={id}\n className={`${css.select} ${css.selectButton}`}\n disabled={props.disabled}\n aria-haspopup=\"listbox\"\n aria-expanded={open}\n aria-activedescendant={open ? `${id}-o${activeIndex}` : undefined}\n aria-invalid={props.invalid || undefined}\n onClick={onTriggerClick}\n onKeyDown={onKeyDown}\n >\n <span className={css.selectLabel}>{label}</span>\n <svg\n width=\"14\"\n height=\"14\"\n viewBox=\"0 0 14 14\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n className={open ? `${css.selectChevron} ${css.selectChevronOpen}` : css.selectChevron}\n aria-hidden=\"true\"\n >\n <path\n d=\"M11.8486 5.5L11.4238 5.92383L8.69727 8.65137C8.44157 8.90706 8.21562 9.13382 8.01172 9.29785C7.79912 9.46883 7.55595 9.61756 7.25 9.66602C7.08435 9.69222 6.91565 9.69222 6.75 9.66602C6.44405 9.61756 6.20088 9.46883 5.98828 9.29785C5.78438 9.13382 5.55843 8.90706 5.30273 8.65137L2.57617 5.92383L2.15137 5.5L3 4.65137L3.42383 5.07617L6.15137 7.80273C6.42595 8.07732 6.59876 8.24849 6.74023 8.3623C6.87291 8.46904 6.92272 8.47813 6.9375 8.48047C6.97895 8.48703 7.02105 8.48703 7.0625 8.48047C7.07728 8.47813 7.12709 8.46904 7.25977 8.3623C7.40124 8.24849 7.57405 8.07732 7.84863 7.80273L10.5762 5.07617L11 4.65137L11.8486 5.5Z\"\n fill=\"currentColor\"\n />\n </svg>\n </button>\n {open\n ? (\n <div className={popupClass} role=\"listbox\" ref={popupRef}>\n {options.map((option, index) => (\n <div\n key={option.value}\n id={`${id}-o${index}`}\n role=\"option\"\n aria-selected={option.value === value}\n className={`${css.selectOption}${option.value === value ? ` ${css.selectOptionSelected}` : ''}${index === activeIndex && !closing ? ` ${css.selectOptionActive}` : ''}`}\n onClick={() => { commit(index) }}\n >\n {option.label}\n </div>\n ))}\n </div>\n )\n : null}\n </div>\n )\n}\n\n/** A staged boolean field: 继承 / 开 / 关. */\nexport function BooleanField(props: FieldProps & {\n /** Copy for the inherit option. */\n inheritLabel: string\n /** Copy for the on option. */\n onLabel: string\n /** Copy for the off option. */\n offLabel: string\n}) {\n return (\n <div className={css.field}>\n <div className={css.head}>\n <label className={css.label} htmlFor={props.id}>{props.label}</label>\n {props.overridden\n ? (\n <span className={css.badges}>\n <span className={css.badge}>{props.overriddenLabel}</span>\n <button\n type=\"button\"\n className={css.reset}\n disabled={props.disabled}\n onClick={props.onReset}\n >\n {props.resetLabel}\n </button>\n </span>\n )\n : null}\n </div>\n <SelectField\n id={props.id}\n options={[\n { value: '', label: props.inheritLabel },\n { value: 'true', label: props.onLabel },\n { value: 'false', label: props.offLabel },\n ]}\n value={props.text}\n disabled={props.disabled}\n invalid={props.invalid}\n onEdit={props.onEdit}\n />\n <p className={css.hint}>{props.hint}</p>\n </div>\n )\n}\n\n/** A staged enumerated field rendered as a select. */\nexport function ChoiceField(props: FieldProps & {\n /** Copy for the inherit option (draft text is the empty string). */\n inheritLabel: string\n /** Choices rendered in order; `value` is the draft/stored text. */\n choices: ReadonlyArray<{ value: string; label: string }>\n}) {\n return (\n <div className={css.field}>\n <div className={css.head}>\n <label className={css.label} htmlFor={props.id}>{props.label}</label>\n {props.overridden\n ? (\n <span className={css.badges}>\n <span className={css.badge}>{props.overriddenLabel}</span>\n <button\n type=\"button\"\n className={css.reset}\n disabled={props.disabled}\n onClick={props.onReset}\n >\n {props.resetLabel}\n </button>\n </span>\n )\n : null}\n </div>\n <SelectField\n id={props.id}\n options={[{ value: '', label: props.inheritLabel }, ...props.choices]}\n value={props.text}\n disabled={props.disabled}\n invalid={props.invalid}\n onEdit={props.onEdit}\n />\n <p className={props.invalid ? css.invalid : css.hint}>\n {props.invalid ? props.invalidLabel : props.hint}\n </p>\n </div>\n )\n}\n","// Generated by scripts/sync-shared.mjs from shared/client/settings/settings-form.ts. Do not edit this copy; edit the shared source and run \"node scripts/sync-shared.mjs\".\n/**\n * Staged form model behind the plugin settings card. A card stages what the\n * user types and writes it only when they save — the settings write is a\n * durable, revision-fenced document mutation, so staging keeps what is on\n * screen exactly what a save would store. Family-shared slice inlined into\n * each plugin's client bundle; mirrors the official ui-plugin-config\n * card-store pattern.\n */\n\nimport type { SettingsScope, SettingsScopeSnapshot } from '@deepseek-ai/dsh-client-ui-settings/client'\nimport type { SnapshotStore } from '@deepseek-ai/dsh-client-store'\nimport { createSnapshotStore } from '@deepseek-ai/dsh-client-store'\n\n/** The write one field's staged text performs when the card is saved. */\nexport type FieldWrite =\n | { kind: 'set'; value: unknown }\n | { kind: 'clear' }\n\n/** How one field converts between its stored value and its draft text. */\nexport interface FieldSpec {\n /** Field name inside the namespace section. */\n field: string\n /**\n * Whether the Host treats this field as a secret and redacts its value from\n * the read-back (role('secret') in the section schema). Redacted secrets are\n * never compared against the draft on save: the Host strips them from every\n * wire view layer, so the settled snapshot carries nothing to read back. A\n * staged secret set is judged by the mutation settling; the rest of its\n * batch, when one exists, is still judged by read-back, and the atomic\n * mutation lands every write or none.\n */\n secret?: boolean\n /** Render a stored value as draft text; the empty string when the section carries none. */\n format: (value: unknown) => string\n /**\n * The write this draft text stages, or undefined when the text is not a\n * value this field accepts — which blocks the save rather than discarding it.\n */\n parse: (text: string) => FieldWrite | undefined\n}\n\n/** One field as the card renders it. */\nexport interface FieldState {\n /** Draft text the control renders. */\n text: string\n /** Whether saving would leave a user-layer entry for this field. */\n overridden: boolean\n /** Whether the draft is not a value this field accepts, which blocks saving. */\n invalid: boolean\n}\n\n/** Form state every plugin settings card shares. */\nexport interface CardShell {\n /** False while the namespace is still loading; the card renders nothing. */\n available: boolean\n /**\n * Whether the namespace is actually served to this client. False when the\n * Host deployment does not expose it (e.g. the owning plugin's settings\n * domain is not mounted): the card renders an explanation\n * instead of its form, so a missing namespace never looks like a missing\n * plugin.\n */\n exposed: boolean\n /** Whether the Host document accepts writes. */\n writable: boolean\n /** Whether the form holds edits that a save would write. */\n dirty: boolean\n /** Whether any staged draft is invalid, which blocks the save. */\n invalid: boolean\n /** Whether a save is crossing the wire. */\n saving: boolean\n /** Whether the last save did not land as staged; cleared by the next edit or save. */\n failed: boolean\n /**\n * The rejection code/message the Host returned for the last failed save,\n * surfaced next to the generic failure text. Undefined while no save has\n * failed (or the failure carried no server reason).\n */\n failedReason?: string\n}\n\n/** The write actions the card's slot entry injects. */\nexport interface CardActions {\n /** Stage draft text for one field. */\n edit: (field: string, text: string) => void\n /** Stage a clear, so saving lets the field re-inherit the composition layer. */\n resetField: (field: string) => void\n /** Write every staged edit, then re-seed from what the Host accepted. */\n save: () => void\n /** Drop every staged edit. */\n discard: () => void\n}\n\n/** One field's staged edit. */\ninterface StagedEdit {\n /** Draft text the control renders. */\n text: string\n /** True when this edit clears the field whatever text it shows. */\n clear: boolean\n}\n\n/** One staged edit resolved into the write a save performs. */\ninterface PlannedWrite {\n /** Field this entry writes. */\n field: string\n /** The durable write this entry performs, inside the save's one atomic mutation. */\n op: BatchedWrite\n /**\n * Read the settled snapshot back and report whether the Host holds this\n * write's effect. Undefined when the draft is not a value the field\n * accepts: there is nothing to write, and the entry blocks the save.\n */\n judge: (() => boolean) | undefined\n}\n\n/** One durable write inside the save's atomic scope mutation. */\nexport interface BatchedWrite {\n /** Field this entry writes. */\n field: string\n /** set stores a value; unset drops the leaf. */\n op: 'set' | 'unset'\n /** Value for op set (absent for unset). */\n value?: unknown\n}\n\n/** Constraints a numeric field's accepted drafts must satisfy, mirroring the host schema. */\nexport interface NumberConstraints {\n /** The accepted value must be a whole number. */\n integer?: boolean\n /** The accepted value must be at least this. */\n min?: number\n}\n\n/** A whole- or decimal-number field. An empty draft clears the field; any other draft that is not a finite number within the constraints blocks the save. */\nexport function numberField(field: string, constraints: NumberConstraints = {}): FieldSpec {\n const { integer = false, min } = constraints\n return {\n field,\n format: value => typeof value === 'number' ? String(value) : '',\n parse: (text) => {\n const trimmed = text.trim()\n if (trimmed === '') return { kind: 'clear' }\n const parsed = Number(trimmed)\n if (!Number.isFinite(parsed)) return undefined\n if (integer && !Number.isInteger(parsed)) return undefined\n if (min !== undefined && parsed < min) return undefined\n return { kind: 'set', value: parsed }\n },\n }\n}\n\n/** A free-text field. An empty draft clears the field. */\nexport function textField(field: string): FieldSpec {\n return {\n field,\n format: value => typeof value === 'string' ? value : '',\n parse: (text) => {\n const trimmed = text.trim()\n return trimmed === '' ? { kind: 'clear' } : { kind: 'set', value: trimmed }\n },\n }\n}\n\n/**\n * A free-text field the Host treats as a secret and redacts from the read-back\n * (role('secret') in the section schema). The card still edits it like text,\n * but a save never compares the redacted value back: the staged set is judged\n * by the mutation settling (see {@link FieldSpec.secret}).\n */\nexport function secretField(field: string): FieldSpec {\n return { ...textField(field), secret: true }\n}\n\n/** A boolean field, edited through true/false draft text. */\nexport function booleanField(field: string): FieldSpec {\n return {\n field,\n format: value => typeof value === 'boolean' ? String(value) : '',\n parse: (text) => {\n const trimmed = text.trim()\n if (trimmed === '') return { kind: 'clear' }\n if (trimmed === 'true') return { kind: 'set', value: true }\n if (trimmed === 'false') return { kind: 'set', value: false }\n return undefined\n },\n }\n}\n\n/** An enumerated string field; only the listed choices are accepted. An empty draft clears the field. */\nexport function choiceField(field: string, choices: readonly string[]): FieldSpec {\n return {\n field,\n format: value => typeof value === 'string' && choices.includes(value) ? value : '',\n parse: (text) => {\n if (text === '') return { kind: 'clear' }\n return choices.includes(text) ? { kind: 'set', value: text } : undefined\n },\n }\n}\n\n/**\n * Stages one card's edits over one settings namespace and writes them on save.\n *\n * The Host is the only authority on whether a value was accepted — its\n * validators own the constraints no schema can express — so the outcome is\n * read back from the section rather than predicted here. A save that did not\n * land keeps its drafts, so the user can correct them instead of retyping.\n */\nexport class CardForm<T> {\n private readonly specs: Map<string, FieldSpec>\n private readonly staged = new Map<string, StagedEdit>()\n private readonly listeners = new Set<() => void>()\n /** The scope subscription installed in the constructor; released by dispose(). */\n private readonly disposeScope: () => void\n private disposed = false\n private saving = false\n private failed = false\n private failedReason: string | undefined\n\n /** @param scope - the bound settings scope for this card's namespace. */\n constructor(\n private readonly scope: SettingsScope<T>,\n specs: FieldSpec[],\n ) {\n this.specs = new Map(specs.map(spec => [spec.field, spec]))\n this.disposeScope = scope.subscribe(() => { this.publish() })\n }\n\n /**\n * Release the scope subscription and every bound store listener. The card\n * must call this on teardown; later calls are no-ops.\n */\n dispose(): void {\n if (this.disposed) return\n this.disposed = true\n this.disposeScope()\n this.listeners.clear()\n }\n\n /** Publish a projection of this form, rebuilt whenever the scope or a draft changes. */\n bind<S>(project: () => S): SnapshotStore<S> {\n const store = createSnapshotStore(project())\n this.listeners.add(() => { store.set(project()) })\n return store\n }\n\n /** Read the card-level state: what the Host serves, and what a save would do. */\n shell(): CardShell {\n const snapshot = this.scope.getSnapshot()\n const plan = this.plan()\n return {\n available: snapshot.status !== 'loading',\n exposed: snapshot.status === 'ready',\n writable: snapshot.writable,\n dirty: plan.length > 0,\n invalid: plan.some(item => item.judge === undefined),\n saving: this.saving,\n failed: this.failed,\n ...this.failedReason === undefined ? {} : { failedReason: this.failedReason },\n }\n }\n\n /** Read one field's state from the effective section and its staged draft. */\n field(field: string): FieldState {\n const spec = this.specOf(field)\n const staged = this.staged.get(field)\n if (staged === undefined) {\n return { text: spec.format(this.sectionValue(field)), overridden: this.stored(field), invalid: false }\n }\n const write = staged.clear ? { kind: 'clear' as const } : spec.parse(staged.text)\n return {\n text: staged.text,\n overridden: write?.kind === 'set',\n invalid: write === undefined,\n }\n }\n\n /** The actions the card's slot registration injects. */\n actions(): CardActions {\n return {\n edit: (field, text) => { this.stage(field, { text, clear: false }) },\n resetField: (field) => {\n this.stage(field, { text: this.specOf(field).format(this.baseValue(field)), clear: true })\n },\n save: () => { void this.save() },\n discard: () => {\n if (this.staged.size === 0 && !this.failed) return\n this.staged.clear()\n this.failed = false\n this.failedReason = undefined\n this.publish()\n },\n }\n }\n\n /**\n * Write every staged edit in one atomic scope mutation, then re-seed from\n * what the Host accepted.\n *\n * The whole batch rides one mutate, so cross-field validate hooks\n * (baseURL+model) judge it as a unit: the Host either applies every write\n * or refuses the batch. The 0.1.2 scope contract never rejects a refused\n * mutation — the scope recovers with a fresh Host view and resolves — so\n * resolution alone proves nothing: the outcome is judged by reading the\n * settled snapshot back, one planned write at a time, and one missed write\n * fails the whole save. A scope that still rejects on refusal (the dsh-web\n * bridge scope) reports through the same failure path with its rejection\n * message. A save that did not land keeps its drafts, so the user can\n * correct them instead of retyping.\n * @returns settlement after the mutation and the read-back.\n */\n async save(): Promise<void> {\n const plan = this.plan()\n const valid = plan.filter((item): item is PlannedWrite & { judge: () => boolean } => item.judge !== undefined)\n if (plan.length === 0 || this.saving || valid.length !== plan.length) return\n // Snapshot the staged entries this save writes, so an edit staged while it\n // is in flight (which replaces the same key) survives: only delete the key\n // when the entry is still the one this save started from.\n const pending = new Map<string, StagedEdit | undefined>()\n for (const item of plan) pending.set(item.field, this.staged.get(item.field))\n this.saving = true\n this.failed = false\n this.failedReason = undefined\n this.publish()\n // One atomic namespace mutation: the 0.1.2 scope contract takes ordered\n // path operations, so the whole staged batch is validated, persisted, and\n // recovered together — either every write lands or none does.\n const ops: Array<{ op: 'set'; path: string[]; value: string | number | boolean } | { op: 'unset'; path: string[] }> = valid.map(item => item.op.op === 'set'\n ? { op: 'set', path: [item.field], value: (item.op as { value: string | number | boolean }).value }\n : { op: 'unset', path: [item.field] })\n let failedReason: string | undefined\n try {\n await this.scope.mutate(ops)\n } catch (error) {\n failedReason = error instanceof Error ? error.message : String(error)\n }\n // The 0.1.2 scope resolves even a refused mutation (it recovers with a\n // fresh view instead of throwing), so resolution alone proves nothing:\n // judge every planned write against the settled snapshot. The mutation is\n // atomic, so one missed write fails the whole save and keeps the drafts.\n const landed = failedReason === undefined && valid.every(item => item.judge())\n for (const [field, before] of pending) {\n if (landed && this.staged.get(field) === before) this.staged.delete(field)\n }\n this.saving = false\n this.failed = !landed\n // A read-back failure carries no server reason: the card surfaces its\n // generic failure copy; a rejecting scope (the bridge) adds its message.\n this.failedReason = failedReason\n this.publish()\n }\n\n /**\n * Every staged edit a save would write. An entry whose draft is not a value\n * its field accepts carries no write: the form is still dirty, and the save\n * refuses rather than dropping the edit. A staged edit that matches the\n * effective section is not a write at all.\n * @returns the planned writes, in the order the fields were staged.\n */\n private plan(): PlannedWrite[] {\n const plan: PlannedWrite[] = []\n for (const [field, staged] of this.staged) {\n const spec = this.specOf(field)\n if (staged.clear) {\n if (this.stored(field)) plan.push({ field, op: { field, op: 'unset' }, judge: () => this.landedUnset(field) })\n continue\n }\n if (staged.text === spec.format(this.sectionValue(field))) continue\n const write = spec.parse(staged.text)\n if (write === undefined) plan.push({ field, op: { field, op: 'unset' }, judge: undefined })\n else if (write.kind === 'clear') plan.push({ field, op: { field, op: 'unset' }, judge: () => this.landedUnset(field) })\n else plan.push({ field, op: { field, op: 'set', value: write.value }, judge: () => this.landedSet(field, write.value) })\n }\n return plan\n }\n\n /**\n * Read-back judgment for a planned set: the user layer must hold the\n * intended value once the mutation has settled.\n */\n private landedSet(field: string, value: unknown): boolean {\n // A redacted secret never appears in any wire view layer: the Host strips\n // role('secret') fields and reports them through a sidecar the scope\n // snapshot does not expose, so there is nothing to compare the draft\n // against. Settling is the only signal the form has; the rest of the\n // batch, when one exists, still carries the atomic verdict by read-back.\n if (this.specOf(field).secret) return true\n return this.userLayer()?.[field] === value\n }\n\n /**\n * Read-back judgment for a planned unset: the field must be gone from the\n * user layer once the mutation has settled.\n */\n private landedUnset(field: string): boolean {\n return !this.stored(field)\n }\n\n private stage(field: string, edit: StagedEdit): void {\n this.staged.set(field, edit)\n this.failed = false\n this.failedReason = undefined\n this.publish()\n }\n\n private specOf(field: string): FieldSpec {\n const spec = this.specs.get(field)\n // Every call site names a field this card declared; a missing one is a\n // wiring mistake that must not degrade into a silently inert control.\n if (spec === undefined) throw new Error(`settings card has no field ${field}`)\n return spec\n }\n\n private snapshotOf(): SettingsScopeSnapshot<T> {\n return this.scope.getSnapshot()\n }\n\n private sectionValue(field: string): unknown {\n return (this.snapshotOf().value as Record<string, unknown> | undefined)?.[field]\n }\n\n private baseValue(field: string): unknown {\n return (this.snapshotOf().base as Record<string, unknown> | undefined)?.[field]\n }\n\n private userLayer(): Record<string, unknown> | undefined {\n return this.snapshotOf().user as Record<string, unknown> | undefined\n }\n\n private stored(field: string): boolean {\n const user = this.userLayer()\n return user !== undefined && Object.hasOwn(user, field)\n }\n\n private publish(): void {\n for (const listener of this.listeners) listener()\n }\n}\n","/**\n * The remote-control settings card: pairing security and device limits.\n * Registers into the `web-ui.plugin.item` child slot the Web UI plugin group\n * renders, bound to the `remote-web-ui` settings namespace.\n */\n\nimport { useEffect, useState } from 'react'\nimport type { InjectFace, PropsLocale, PropsRuntime } from '@deepseek-ai/dsh-client-ui-slots'\nimport type { SettingsScope } from '@deepseek-ai/dsh-client-ui-settings/client'\nimport type { SnapshotStore } from '@deepseek-ai/dsh-client-store'\nimport { PluginSettingsCard, ValueField, BooleanField } from './PluginSettingsCard.tsx'\nimport { CardForm, booleanField, numberField, secretField, textField, type CardActions, type CardShell, type FieldState as CardFieldState } from './settings-form.ts'\nimport { readLanBindStatus, type LanBindFrame } from './pair-api.ts'\nimport type { TranslateNS } from '@deepseek-ai/dsh-client-ui-slots'\n\n/** The remote-control fields this card edits (the namespace's full schema). */\nexport interface RemoteSettings {\n /** Master switch for the plugin. */\n enabled?: boolean\n /** Token lifetime in ms; the QR link dies after this. */\n tokenTtlMs?: number\n /** A device is \"online\" while its lastSeenAt is newer than this (ms). */\n offlineAfterMs?: number\n /** Hard cap on paired device sessions (oldest evicted when full). */\n maxDevices?: number\n /** Idle sessions older than this (ms) are deleted. */\n idleExpireMs?: number\n /** Cookie name carrying the paired device id. */\n cookieName?: string\n /** Fence flag: whether non-loopback /api requests must carry a live paired-device cookie. */\n requirePairingForLan?: boolean\n /** Public (tunneled) base URL the QR link is built from when set. */\n publicBaseUrl?: string\n /** When on, the plugin runs its own Cloudflare quick tunnel automatically. */\n autoTunnel?: boolean\n /**\n * Cloudflare named-tunnel token: when set (and autoTunnel is off), the\n * plugin runs the named tunnel toward the fixed public hostname — a phone\n * paired once keeps its session across restarts.\n */\n tunnelToken?: string\n /**\n * Stable-origin relay: when on (default), the quick tunnel is fronted by a\n * fixed `<id>.dsh-market.com` subdomain so the phone's bookmark and\n * pairing cookie survive restarts without any setup.\n */\n relay?: boolean\n /**\n * LAN bind toggle: once flipped, the plugin manages the profile patch's\n * webserver block (0.0.0.0 / 127.0.0.1) and the host firewall rule.\n */\n lanBind?: boolean\n}\n\n/** What the remote-control card renders. */\nexport interface RemoteSettingsCardState extends CardShell {\n /** Master switch. */\n enabled: CardFieldState\n /** Token lifetime. */\n tokenTtlMs: CardFieldState\n /** Device offline threshold. */\n offlineAfterMs: CardFieldState\n /** Paired-device cap. */\n maxDevices: CardFieldState\n /** Idle-expiry window. */\n idleExpireMs: CardFieldState\n /** Device cookie name. */\n cookieName: CardFieldState\n /** LAN fence flag. */\n requirePairingForLan: CardFieldState\n /** Public (tunneled) base URL. */\n publicBaseUrl: CardFieldState\n /** Auto public tunnel switch. */\n autoTunnel: CardFieldState\n /** Named-tunnel token (stored redacted by the Host). */\n tunnelToken: CardFieldState\n /** Stable-origin relay switch. */\n relay: CardFieldState\n /** LAN bind toggle. */\n lanBind: CardFieldState\n}\n\n/** The registration-side face the card's slot entry injects. */\nexport interface RemoteSettingsCardFace extends CardActions {\n hooks: {\n /** Card snapshot bound by the renderer as useRemoteSettingsCard. */\n remoteSettingsCard: SnapshotStore<RemoteSettingsCardState>\n }\n}\n\n/** Bridges the `remote-web-ui` scope onto the card's staged form. */\nexport class RemoteSettingsCardController {\n private readonly form: CardForm<RemoteSettings>\n private readonly store: SnapshotStore<RemoteSettingsCardState>\n\n /** @param scope - the bound settings scope for the `remote-web-ui` namespace. */\n constructor(scope: SettingsScope<RemoteSettings>) {\n this.form = new CardForm(scope, [\n booleanField('enabled'),\n numberField('tokenTtlMs'),\n numberField('offlineAfterMs'),\n numberField('maxDevices'),\n numberField('idleExpireMs'),\n textField('cookieName'),\n booleanField('requirePairingForLan'),\n textField('publicBaseUrl'),\n booleanField('autoTunnel'),\n secretField('tunnelToken'),\n booleanField('relay'),\n booleanField('lanBind'),\n ])\n this.store = this.form.bind(() => this.projection())\n }\n\n private projection(): RemoteSettingsCardState {\n return {\n ...this.form.shell(),\n enabled: this.form.field('enabled'),\n tokenTtlMs: this.form.field('tokenTtlMs'),\n offlineAfterMs: this.form.field('offlineAfterMs'),\n maxDevices: this.form.field('maxDevices'),\n idleExpireMs: this.form.field('idleExpireMs'),\n cookieName: this.form.field('cookieName'),\n requirePairingForLan: this.form.field('requirePairingForLan'),\n publicBaseUrl: this.form.field('publicBaseUrl'),\n autoTunnel: this.form.field('autoTunnel'),\n tunnelToken: this.form.field('tunnelToken'),\n relay: this.form.field('relay'),\n lanBind: this.form.field('lanBind'),\n }\n }\n\n /**\n * Build the face the card's slot registration injects.\n * @returns the card's snapshot and its form actions.\n */\n inject(): RemoteSettingsCardFace {\n return { hooks: { remoteSettingsCard: this.store }, ...this.form.actions() }\n }\n\n /**\n * Release the card's scope subscription and bound stores; the slot\n * disposer calls this on teardown.\n */\n dispose(): void {\n this.form.dispose()\n }\n}\n\n/** Props the renderer binds for the remote-control card. */\nexport type RemoteSettingsCardProps =\n PropsRuntime<'web-ui.plugin.item'>\n & PropsLocale<'remote'>\n & InjectFace<RemoteSettingsCardFace>\n\n/**\n * Render the remote-control card.\n * @param props - locale copy, the card snapshot, and its form actions.\n * @returns the card.\n */\nexport function RemoteSettingsCard(props: RemoteSettingsCardProps) {\n const { t } = props\n const state = props.useRemoteSettingsCard(snapshot => snapshot)\n const disabled = !state.writable\n const fieldProps = {\n overriddenLabel: t('settings.overridden'),\n resetLabel: t('settings.reset'),\n invalidLabel: t('settings.invalidNumber'),\n disabled,\n }\n return (\n <PluginSettingsCard\n t={t}\n titleKey=\"settings.title\"\n descriptionKey=\"settings.description\"\n defaultOpen={false}\n state={state}\n onSave={props.save}\n onDiscard={props.discard}\n >\n <BooleanField\n id=\"settings-remote-enabled\"\n label={t('settings.enabled')}\n hint={t('settings.enabledHint')}\n inheritLabel={t('settings.inherit')}\n onLabel={t('settings.on')}\n offLabel={t('settings.off')}\n {...fieldProps}\n {...state.enabled}\n onEdit={(text) => { props.edit('enabled', text) }}\n onReset={() => { props.resetField('enabled') }}\n />\n <ValueField\n id=\"settings-remote-token-ttl\"\n label={t('settings.tokenTtlMs')}\n hint={t('settings.tokenTtlMsHint')}\n numeric\n {...fieldProps}\n {...state.tokenTtlMs}\n onEdit={(text) => { props.edit('tokenTtlMs', text) }}\n onReset={() => { props.resetField('tokenTtlMs') }}\n />\n <ValueField\n id=\"settings-remote-offline\"\n label={t('settings.offlineAfterMs')}\n hint={t('settings.offlineAfterMsHint')}\n numeric\n {...fieldProps}\n {...state.offlineAfterMs}\n onEdit={(text) => { props.edit('offlineAfterMs', text) }}\n onReset={() => { props.resetField('offlineAfterMs') }}\n />\n <ValueField\n id=\"settings-remote-max-devices\"\n label={t('settings.maxDevices')}\n hint={t('settings.maxDevicesHint')}\n numeric\n {...fieldProps}\n {...state.maxDevices}\n onEdit={(text) => { props.edit('maxDevices', text) }}\n onReset={() => { props.resetField('maxDevices') }}\n />\n <ValueField\n id=\"settings-remote-idle-expire\"\n label={t('settings.idleExpireMs')}\n hint={t('settings.idleExpireMsHint')}\n numeric\n {...fieldProps}\n {...state.idleExpireMs}\n onEdit={(text) => { props.edit('idleExpireMs', text) }}\n onReset={() => { props.resetField('idleExpireMs') }}\n />\n <ValueField\n id=\"settings-remote-cookie\"\n label={t('settings.cookieName')}\n hint={t('settings.cookieNameHint')}\n {...fieldProps}\n {...state.cookieName}\n onEdit={(text) => { props.edit('cookieName', text) }}\n onReset={() => { props.resetField('cookieName') }}\n />\n <BooleanField\n id=\"settings-remote-fence\"\n label={t('settings.requirePairingForLan')}\n hint={t('settings.requirePairingForLanHint')}\n inheritLabel={t('settings.inherit')}\n onLabel={t('settings.on')}\n offLabel={t('settings.off')}\n {...fieldProps}\n {...state.requirePairingForLan}\n onEdit={(text) => { props.edit('requirePairingForLan', text) }}\n onReset={() => { props.resetField('requirePairingForLan') }}\n />\n <ValueField\n id=\"settings-remote-public-base\"\n label={t('settings.publicBaseUrl')}\n hint={t('settings.publicBaseUrlHint')}\n placeholder=\"https://example.trycloudflare.com\"\n {...fieldProps}\n {...state.publicBaseUrl}\n onEdit={(text) => { props.edit('publicBaseUrl', text) }}\n onReset={() => { props.resetField('publicBaseUrl') }}\n />\n <BooleanField\n id=\"settings-remote-auto-tunnel\"\n label={t('settings.autoTunnel')}\n hint={t('settings.autoTunnelHint')}\n inheritLabel={t('settings.inherit')}\n onLabel={t('settings.on')}\n offLabel={t('settings.off')}\n {...fieldProps}\n {...state.autoTunnel}\n onEdit={(text) => { props.edit('autoTunnel', text) }}\n onReset={() => { props.resetField('autoTunnel') }}\n />\n <ValueField\n id=\"settings-remote-tunnel-token\"\n label={t('settings.tunnelToken')}\n hint={t('settings.tunnelTokenHint')}\n placeholder=\"eyJ...\"\n {...fieldProps}\n {...state.tunnelToken}\n onEdit={(text) => { props.edit('tunnelToken', text) }}\n onReset={() => { props.resetField('tunnelToken') }}\n />\n <BooleanField\n id=\"settings-remote-relay\"\n label={t('settings.relay')}\n hint={t('settings.relayHint')}\n inheritLabel={t('settings.inherit')}\n onLabel={t('settings.on')}\n offLabel={t('settings.off')}\n {...fieldProps}\n {...state.relay}\n onEdit={(text) => { props.edit('relay', text) }}\n onReset={() => { props.resetField('relay') }}\n />\n <LanBindStatus t={t} />\n <BooleanField\n id=\"settings-remote-lan-bind\"\n label={t('settings.lanBind')}\n hint={t('settings.lanBindHint')}\n inheritLabel={t('settings.inherit')}\n onLabel={t('settings.on')}\n offLabel={t('settings.off')}\n {...fieldProps}\n {...state.lanBind}\n onEdit={(text) => { props.edit('lanBind', text) }}\n onReset={() => { props.resetField('lanBind') }}\n />\n </PluginSettingsCard>\n )\n}\n\n/**\n * Live LAN-bind facts above the toggle: the managed block's host, the live\n * bind, the firewall summary, and the reachable LAN URLs. Polls the\n * loopback-only status endpoint; a failure (non-loopback origin) renders\n * nothing — the pairing panel carries the loopback banner instead.\n */\nfunction LanBindStatus({ t }: { t: TranslateNS<'remote'> }) {\n const [frame, setFrame] = useState<LanBindFrame | undefined>(undefined)\n useEffect(() => {\n let alive = true\n const read = (): void => {\n void readLanBindStatus().then((value) => {\n if (alive) setFrame(value)\n }).catch(() => {})\n }\n read()\n const timer = window.setInterval(read, 10_000)\n return () => {\n alive = false\n window.clearInterval(timer)\n }\n }, [])\n if (frame === undefined) return null\n const lanOn = frame.blockHost === '0.0.0.0'\n const firewallText = frame.firewall.managed\n ? t(frame.firewall.ok ? 'lan.firewall.ok' : 'lan.firewall.bad')\n : t('lan.firewall.unmanaged')\n const lines: string[] = [\n t('lan.bind', { host: frame.bindHost, port: String(frame.port) }) + ' · ' + firewallText,\n ]\n if (lanOn && frame.lanUrls.length > 0) {\n lines.push(t('lan.urls', { urls: frame.lanUrls.join(' ') }))\n }\n if (!lanOn) {\n lines.push(t('lan.off'))\n }\n if (frame.setting === null) {\n lines.push(t('lan.untouched'))\n }\n if (frame.pendingRestart === true) {\n lines.push(t('lan.pendingRestart'))\n }\n return (\n <div style={{ display: 'flex', flexDirection: 'column', gap: 2, fontSize: 12, lineHeight: '18px', opacity: 0.85 }}>\n {lines.map((line, index) => (\n <div key={index} style={{ wordBreak: 'break-all' }}>{line}</div>\n ))}\n </div>\n )\n}\n","/** `remote` namespace dictionaries: the remote-access surface copy. */\n\n/** Simplified Chinese dictionary (the key-set source of truth). */\nexport const zh = {\n 'entry.label': '远程访问',\n 'mobile.whale.open': '打开侧边栏',\n 'mobile.composer.pickModel': '选择模型',\n 'mobile.composer.pickEffort': '选择推理等级',\n 'title': '远程访问',\n 'subtitle': '通过手机或另一台电脑配对,远程使用同一份 Web 界面(官方界面 + 移动端适配)',\n 'card.title': '设备配对',\n 'public.badge': '公网',\n 'status.waiting': '等待设备连接',\n 'status.connected': '已连接 {n} 台设备',\n 'status.disconnected': '已配对设备离线',\n 'status.stopped': '已停止远程访问',\n 'status.lanRequired': '此功能需要局域网绑定或公网地址才能使用',\n 'status.lanRequiredHint': '当前服务仅绑定在 127.0.0.1 且未配置公网地址,手机无法访问。请在「设置 → Web 插件 → 远程访问设置」卡片中打开“局域网访问”,或用 dsh web --host 0.0.0.0 重新启动,或填写内网穿透的公网地址。',\n 'status.loopbackRequired': '配对面板仅限本机使用',\n 'status.loopbackRequiredHint': '请通过 http://127.0.0.1 打开此页面后重试;手机请使用配对链接访问。',\n 'status.unreachable': '无法连接配对服务',\n 'status.unreachableHint': '请刷新页面后重试。',\n 'pair.hint': '无法扫码?可直接打开下方配对链接',\n 'pair.publicHint': '公网链接:设备无需与本机处于同一网络',\n 'address.label': '选择二维码指向的网络',\n 'address.public': '公网地址',\n 'address.lan': '局域网',\n 'address.hint': '远程设备不在同一网络时请使用公网地址;局域网地址仅限同一网络内使用。',\n 'pair.expires': '二维码有效至 {time}',\n 'pair.expired': '二维码已过期,请刷新',\n 'pair.linkLabel': '配对链接',\n 'pair.tokenLabel': '配对令牌',\n 'pair.dockerHint': 'Docker 或反向代理环境下,可直接复制此令牌并在目标设备配对页面输入。',\n 'pair.oneTimeHint': '链接含一次性令牌;任一设备配对成功后立即失效,配对下一台设备请刷新二维码。',\n 'pair.failed.title': '配对失败',\n 'pair.failed.detail': '链接无效或已使用,请回到电脑端刷新二维码后重新扫码。',\n 'fence.unpaired.title': '此设备未配对,无法访问工作区数据',\n 'fence.unpaired.eyebrow': '需要设备配对',\n 'fence.unpaired.hint': '为保护工作区、会话与插件数据,远程电脑必须先通过主电脑授权。',\n 'fence.unpaired.stepDesktop': '在主电脑打开 http://127.0.0.1:3080,进入“远程访问”。',\n 'fence.unpaired.stepLink': '在“设备配对”中复制电脑配对链接。',\n 'fence.unpaired.stepOpen': '在当前浏览器打开该链接,完成授权后即可进入。',\n 'fence.unpaired.retry': '重新检测',\n 'fence.unpaired.tokenPlaceholder': '或在此直接粘贴配对链接 / Token',\n 'fence.unpaired.pairAction': '立即配对',\n 'fence.unpaired.pairing': '配对中…',\n 'fence.unpaired.tokenInvalid': '配对链接或 Token 无效已过期',\n 'fence.unpaired.tokenUsed': '该配对链接已被使用',\n 'fence.unpaired.tokenFailed': '配对失败,请检查网络或重新获取链接',\n 'fence.unpaired.footnote': '请勿使用他人提供的配对链接;管理员可随时取消此设备的授权。',\n 'posture.exposed': '/api 通道对未配对设备敞开',\n 'posture.exposedHint': '以下来源的请求未经配对即可访问完整桌面 API:{hosts}。请移除对应来源的 --trusted-host(配对机制已覆盖远程访问),或改为仅绑定 127.0.0.1 并使用隧道。',\n 'action.stop': '停止',\n 'action.refresh': '刷新二维码',\n 'action.copy': '复制链接',\n 'action.copyLink': '复制链接',\n 'action.copyToken': '复制令牌',\n 'action.copied': '已复制',\n 'action.copiedToken': '已复制令牌',\n 'devices.title': '已授权设备',\n 'devices.empty': '还没有已配对的设备。扫码或打开链接后会出现在这里。',\n 'devices.unknown': '未知设备',\n 'devices.online': '在线',\n 'devices.offline': '离线',\n 'devices.lastSeen': '最近活动 {time}',\n 'devices.revoke': '取消配对',\n 'devices.revoke.label': '取消配对此设备',\n 'stopped.hint': '已停止远程访问。点击\"刷新二维码\"重新开启。',\n 'tunnel.starting': '公网隧道启动中,二维码将自动变为公网链接…',\n 'tunnel.failed': '公网隧道启动失败:{error}',\n 'tunnel.unknownError': '未知错误',\n 'relay.registering': '正在把临时隧道同步到固定域名(<id>.dsh-market.com)…',\n 'relay.failed': '固定域名同步失败:{error}。正在自动重试,期间二维码可能使用临时地址。',\n 'close.label': '关闭远程访问面板',\n // 插件设置卡片(settings.plugin.item 席位)。\n 'settings.title': '远程访问设置',\n 'settings.description': '配对安全与设备限额。',\n 'settings.enabled': '启用远程访问',\n 'settings.enabledHint': '关闭后移除侧边栏入口并停用配对路由与局域网栅栏。',\n 'settings.tokenTtlMs': '配对令牌有效期(毫秒)',\n 'settings.tokenTtlMsHint': '新生成的二维码链接在此时间后失效。',\n 'settings.offlineAfterMs': '设备离线判定(毫秒)',\n 'settings.offlineAfterMsHint': '配对设备超过该时长未上报心跳即视为离线。',\n 'settings.maxDevices': '已配对设备上限',\n 'settings.maxDevicesHint': '超过上限时淘汰最旧的设备会话。',\n 'settings.idleExpireMs': '空闲过期(毫秒)',\n 'settings.idleExpireMsHint': '超过该时长没有任何心跳或请求的已配对设备会被删除,必须重新扫码。默认 7 天。',\n 'settings.cookieName': '设备 Cookie 名',\n 'settings.cookieNameHint': '携带已配对设备标识的 Cookie 名称。',\n 'settings.requirePairingForLan': '局域网访问要求配对',\n 'settings.requirePairingForLanHint': '开启:非本机回环的桌面 Web GUI 改走门控的 /remote,必须携带有效配对 Cookie;关闭:桌面继续走普通路径(仅在该来源已被 SDK 信任时有意义),配对只管理令牌与状态。',\n 'settings.publicBaseUrl': '公网地址(可选)',\n 'settings.publicBaseUrlHint': '内网穿透的公网地址,如 Cloudflare Tunnel:https://xxx.trycloudflare.com;固定域名隧道(下方令牌)也填这里。填写后二维码将生成公网链接,手机不在同一网络也能配对;留空则仅局域网可用。',\n 'settings.autoTunnel': '自动公网隧道',\n 'settings.autoTunnelHint': '开启后插件自动启动 Cloudflare quick tunnel(无需安装任何工具),并自动更新公网地址与信任配置,手机随时可用公网配对;注意临时域名每次重启都会变化,手机需重新扫码。开启时忽略下方固定隧道令牌与上方手动公网地址。',\n 'settings.tunnelToken': '固定域名隧道令牌(Cloudflare Tunnel)',\n 'settings.tunnelTokenHint': '填入 Cloudflare 命名隧道的 Token(即 cloudflared tunnel run --token 的值),插件会自动运行该隧道:公共主机名固定不变,手机配对一次后重启也无需重新配对。需先在 Cloudflare 控制台把公共主机名映射到 http://127.0.0.1:<端口>,并在上方\"公网地址\"填写同一域名。优先级低于\"自动公网隧道\"。',\n 'settings.relay': '固定域名中继(推荐开启)',\n 'settings.relayHint': '开启后自动隧道会额外注册一个固定不变的公网子域名(<id>.dsh-market.com,由 dsh-market 边缘中继到你的临时隧道),手机配对一次后重启无需重新扫码,二维码与书签地址永远不变。流量经由 dsh-market 边缘转发(与临时隧道相同的信任面);关闭则回退为纯临时地址,每次重启需重新配对。仅对\"自动公网隧道\"生效。',\n 'settings.lanBind': '局域网访问(绑定 0.0.0.0)',\n 'settings.lanBindHint': '开启后插件把绑定默认改写为 0.0.0.0 并写入 profile 补丁(显式 --host 仍优先),同时维护主机防火墙放行(Windows/Linux;macOS 无需管理);关闭回退 127.0.0.1。绑定变化通常在重启 dsh web 后生效。',\n 'lan.cardTitle': '局域网访问',\n 'lan.bind': '绑定:{host}:{port}',\n 'lan.off': '当前仅本机可访问。',\n 'lan.urls': '局域网地址:{urls}',\n 'lan.firewall.ok': '防火墙已放行',\n 'lan.firewall.bad': '防火墙未放行(需管理员权限)',\n 'lan.firewall.unmanaged': '防火墙不由插件管理(未检测到受支持的防火墙)',\n 'lan.untouched': '开关尚未使用:打开后插件才会改写 profile 补丁。',\n 'lan.pendingRestart': '绑定将在重启 dsh web 后生效。',\n 'settings.inherit': '继承',\n 'settings.on': '开',\n 'settings.off': '关',\n 'settings.overridden': '已覆盖',\n 'settings.reset': '恢复默认',\n 'settings.notExposed': '当前 DSH 版本未向设置页暴露本插件的配置命名空间,表单不可用。可编辑 $DSH_HOME/settings.yaml 直接配置,或确认提供该命名空间的插件已挂载其设置域并重启。',\n 'settings.readOnly': '当前部署的设置只读。',\n 'settings.expand': '展开设置',\n 'settings.collapse': '收起设置',\n 'settings.save': '保存',\n 'settings.saving': '保存中…',\n 'settings.discard': '放弃',\n 'settings.unsaved': '未保存',\n 'settings.saveFailed': '部署未接受这些值,已保留供你修改。',\n 'settings.invalidNumber': '请输入数字,留空则使用默认值。',\n // 更新面板(侧边栏更新按钮)。\n 'update.label': '检查更新',\n 'update.badge': '有更新',\n 'update.availableLabel': '发现新版本,检查更新',\n 'update.title': '检查更新',\n 'update.checking': '正在检查远程仓库中的新版本…',\n 'update.upToDate': '当前已是最新版本',\n 'update.upToDateDetail': '{name} 已是最新版本 v{version}。',\n 'update.found': '发现新版本',\n 'update.foundDetail': '{name} 有新版本 v{version}。确认后开始更新。',\n 'update.start': '开始更新',\n 'update.updating': '正在更新 {name} 至 v{version},可能需要 1-2 分钟…',\n 'update.cooldownNotice': '本次更新由你主动触发,将跳过 pnpm 的 24 小时发布冷却期(供应链保护)直接安装所选版本。',\n 'update.updatingTitle': '正在更新…',\n 'update.done': '更新完成',\n 'update.doneDetail': '所有组件已更新到最新版本。',\n 'update.restartHint': '请重启 dsh web 使新版本生效:在终端按 Ctrl+C 停止后重新运行 dsh web。',\n 'update.linkMode': '当前为本地开发模式',\n 'update.linkModeDetail': 'dsh-web 或其组件通过本地链接安装(开发模式),无法自动更新。npm 上最新版本:{version}。请同步本地仓库,或移除与全家桶重复的独立链接。',\n 'update.missing': '未找到 dsh-web 安装',\n 'update.missingDetail': '无法定位已安装的 dsh-web 聚合包。请先运行 dsh plugin --profile <profile> add @linxin666/dsh-web-all。',\n 'update.offline': '无法连接更新源',\n 'update.offlineDetail': '网络不可用或更新服务异常,请稍后重试。',\n 'update.unmounted': '更新服务未加载',\n 'update.unmountedDetail': '当前 dsh web 进程运行的插件版本不含更新服务,请重启 dsh web(Ctrl+C 后重新运行)后再试。',\n 'update.error': '更新失败',\n 'update.packages': '组件版本',\n 'update.releaseNotes': 'v{version} 更新说明',\n 'update.releaseFeatures': '新增功能',\n 'update.releaseFixes': '修复',\n 'update.releaseOther': '其他变动',\n 'update.releaseUnavailable': '本次发布说明暂不可用,可前往 GitHub Release 查看。',\n 'update.componentVersions': '查看组件版本',\n 'update.retry': '重新检查',\n 'update.close': '关闭更新面板',\n 'update.error.pnpmMissing': '未找到 pnpm,已尝试 pnpm / corepack / npx 仍不可用。请安装 pnpm 后重启应用(Windows: npm install -g pnpm 或 corepack enable;macOS: brew install pnpm 或 corepack enable)。',\n 'update.error.timeout': '更新超时,已终止安装进程,请重试。',\n 'update.error.notFound': '未找到 dsh-web 聚合包安装,无法更新。',\n 'update.error.link': 'dsh-web 或其组件使用本地链接,无法自动更新;请同步本地仓库,或移除与全家桶重复的独立链接。',\n 'update.error.pnpmFailed': '更新执行失败(pnpm 退出码 {code}),详见下方输出。',\n 'update.error.stale': '更新命令已执行,但安装版本未变化。常见原因:pnpm 11 的 minimumReleaseAge 门禁会静默跳过发布不足 24 小时的新版本。请在 profile 目录(~/.dsh/profiles/<profile>)的 pnpm-workspace.yaml 中配置 minimumReleaseAgeExclude(例如 \"@linxin666/*\")或 minimumReleaseAge: 0 后重新点击更新。',\n 'update.error.verifyFailed': '更新命令已执行,但无法核对安装后的版本(可能是 registry 探测失败或安装路径变化)。请查看下方输出,或稍后重试。',\n 'update.error.unknown': '更新失败,请重试。',\n} satisfies Record<string, string>\n\n/** The remote namespace key union. */\nexport type RemoteKey = keyof typeof zh\n\n/** The settings-card slice of the remote dictionary. */\nexport type SettingsCardKey = RemoteKey\n\n/** English dictionary, checked complete against the zh key set. */\nexport const en = {\n 'entry.label': 'Remote access',\n 'mobile.whale.open': 'Open sidebar',\n 'mobile.composer.pickModel': 'Pick model',\n 'mobile.composer.pickEffort': 'Pick reasoning effort',\n 'title': 'Remote access',\n 'subtitle': 'Pair a phone or another computer to share the same Web GUI (official UI + mobile adaptation)',\n 'card.title': 'Pair a device',\n 'public.badge': 'Public',\n 'status.waiting': 'Waiting for a device',\n 'status.connected': '{n} device(s) connected',\n 'status.disconnected': 'Paired devices offline',\n 'status.stopped': 'Remote access stopped',\n 'status.lanRequired': 'This feature needs a LAN bind or a public address',\n 'status.lanRequiredHint': 'The server is bound to 127.0.0.1 and no public address is configured, so a phone cannot reach it. Turn on LAN access in the settings card under Settings → Web Plugins → Remote access, or restart with dsh web --host 0.0.0.0, or set the tunneled public address.',\n 'status.loopbackRequired': 'The pairing panel works on this machine only',\n 'status.loopbackRequiredHint': 'Open this page at http://127.0.0.1 to mint a QR code; phones use the paired link.',\n 'status.unreachable': 'Cannot reach the pairing service',\n 'status.unreachableHint': 'Refresh the page and try again.',\n 'pair.hint': 'Cannot scan? Open one of the pairing links below',\n 'pair.publicHint': 'Public links work when the device is not on the same network',\n 'address.label': 'Network the QR code points to',\n 'address.public': 'Public',\n 'address.lan': 'LAN',\n 'address.hint': 'Use the public address when the remote device is on another network; LAN addresses only work on the same network.',\n 'pair.expires': 'QR code valid until {time}',\n 'pair.expired': 'QR code expired — refresh it',\n 'pair.linkLabel': 'Pairing link',\n 'pair.tokenLabel': 'Pairing token',\n 'pair.dockerHint': 'In Docker or reverse proxy environments, copy this token to pair directly on the target device.',\n 'pair.oneTimeHint': 'The link carries one single-use token; it dies as soon as any device pairs. Refresh the QR to pair the next device.',\n 'pair.failed.title': 'Pairing failed',\n 'pair.failed.detail': 'The link is invalid or was already used. Refresh the QR code on your computer and scan again.',\n 'fence.unpaired.title': 'This device is not paired and cannot reach workspace data',\n 'fence.unpaired.eyebrow': 'Device pairing required',\n 'fence.unpaired.hint': 'To protect workspace, session, and plugin data, a remote computer must first be authorized by the primary computer.',\n 'fence.unpaired.stepDesktop': 'On the primary computer, open http://127.0.0.1:3080 and go to Remote access.',\n 'fence.unpaired.stepLink': 'Copy the computer pairing link under Pair a device.',\n 'fence.unpaired.stepOpen': 'Open that link in this browser. After authorization, the workspace will become available.',\n 'fence.unpaired.retry': 'Check again',\n 'fence.unpaired.tokenPlaceholder': 'Or paste pairing link / token here',\n 'fence.unpaired.pairAction': 'Pair Now',\n 'fence.unpaired.pairing': 'Pairing…',\n 'fence.unpaired.tokenInvalid': 'Pairing link or token is invalid or expired',\n 'fence.unpaired.tokenUsed': 'This pairing link has already been used',\n 'fence.unpaired.tokenFailed': 'Pairing failed, please check network or issue a new link',\n 'fence.unpaired.footnote': 'Do not use pairing links from people you do not trust. An administrator can revoke this device at any time.',\n 'posture.exposed': 'The /api channel is open to unpaired devices',\n 'posture.exposedHint': 'Requests from {hosts} reach the full desktop API without pairing. Remove --trusted-host for them (pairing already covers remote access), or bind loopback only and use the tunnel.',\n 'action.stop': 'Stop',\n 'action.refresh': 'Refresh QR',\n 'action.copy': 'Copy link',\n 'action.copyLink': 'Copy link',\n 'action.copyToken': 'Copy token',\n 'action.copied': 'Copied',\n 'action.copiedToken': 'Token copied',\n 'devices.title': 'Authorized devices',\n 'devices.empty': 'No paired devices yet. Scan the QR or open the link to add one.',\n 'devices.unknown': 'Unknown device',\n 'devices.online': 'Online',\n 'devices.offline': 'Offline',\n 'devices.lastSeen': 'Last active {time}',\n 'devices.revoke': 'Unpair',\n 'devices.revoke.label': 'Unpair this device',\n 'stopped.hint': 'Remote access is stopped. Click \"Refresh QR\" to re-enable it.',\n 'tunnel.starting': 'The public tunnel is starting; the QR code will switch to a public link shortly…',\n 'tunnel.failed': 'The public tunnel failed to start: {error}',\n 'tunnel.unknownError': 'unknown error',\n 'relay.registering': 'Syncing the ephemeral tunnel to the stable hostname (<id>.dsh-market.com)…',\n 'relay.failed': 'Stable-hostname sync failed: {error}. Retrying automatically; the QR may use the ephemeral address meanwhile.',\n 'close.label': 'Close remote access panel',\n // Plugin settings card (the `settings.plugin.item` seat).\n 'settings.title': 'Remote access settings',\n 'settings.description': 'Pairing security and device limits.',\n 'settings.enabled': 'Enable remote access',\n 'settings.enabledHint': 'When off, the sidebar entry is removed and pairing routes plus the LAN fence stop.',\n 'settings.tokenTtlMs': 'Pairing token lifetime (ms)',\n 'settings.tokenTtlMsHint': 'How long a minted QR link stays valid before it dies.',\n 'settings.offlineAfterMs': 'Device offline threshold (ms)',\n 'settings.offlineAfterMsHint': 'A paired device flips to offline when it has not been seen for this long.',\n 'settings.maxDevices': 'Paired device cap',\n 'settings.maxDevicesHint': 'Hard cap on paired device sessions; the oldest is evicted when full.',\n 'settings.idleExpireMs': 'Idle expiry (ms)',\n 'settings.idleExpireMsHint': 'A paired device with no heartbeat or request for this long is deleted and must scan again. Default is 7 days.',\n 'settings.cookieName': 'Device cookie name',\n 'settings.cookieNameHint': 'Cookie that carries the paired device id.',\n 'settings.requirePairingForLan': 'Require pairing for LAN access',\n 'settings.requirePairingForLanHint': 'On: a desktop Web GUI at a non-loopback origin rides the gated /remote channel and must carry a live paired-device cookie. Off: the desktop stays on its original paths (only useful when that origin is already trusted) and pairing only manages tokens/status.',\n 'settings.publicBaseUrl': 'Public address (optional)',\n 'settings.publicBaseUrlHint': 'The public URL of a tunnel in front of this server, e.g. a Cloudflare Tunnel: https://xxx.trycloudflare.com; a fixed-hostname tunnel (token below) also goes here. When set, the QR link is built from it so a phone anywhere can pair; leave blank for LAN-only usage.',\n 'settings.autoTunnel': 'Auto public tunnel',\n 'settings.autoTunnelHint': 'When on, the plugin runs its own Cloudflare quick tunnel (no tool installation needed) and keeps the public address and trust config in sync automatically, so a phone anywhere can pair at any time; note the ephemeral hostname changes on every restart, so phones must scan again. The named-tunnel token below and the manual public address above are ignored while this is on.',\n 'settings.tunnelToken': 'Fixed-hostname tunnel token (Cloudflare Tunnel)',\n 'settings.tunnelTokenHint': 'Paste a Cloudflare named-tunnel token (the value of cloudflared tunnel run --token) and the plugin runs the tunnel itself: the public hostname stays fixed, so a phone pairs once and never again across restarts. First map the public hostname to http://127.0.0.1:<port> in the Cloudflare dashboard and enter the same hostname as the public address above. Lower precedence than the auto quick tunnel.',\n 'settings.relay': 'Stable-hostname relay (recommended)',\n 'settings.relayHint': 'When on, the auto tunnel additionally registers a never-changing public subdomain (<id>.dsh-market.com, relayed by the dsh-market edge to your ephemeral tunnel), so a phone pairs once and the QR and bookmark stay valid across restarts. Traffic transits the dsh-market edge (the same trust point as the ephemeral tunnel); turn off to fall back to the raw ephemeral address, which needs re-pairing after every restart. Applies to the auto public tunnel only.',\n 'settings.lanBind': 'LAN access (bind 0.0.0.0)',\n 'settings.lanBindHint': 'When on, the plugin writes a managed block into the profile patch defaulting the bind to 0.0.0.0 (an explicit --host flag still wins), and maintains the matching host firewall rule (Windows/Linux; other platforms need none). When off, the block pins 127.0.0.1. The bind change usually takes effect after dsh web restarts.',\n 'lan.cardTitle': 'LAN access',\n 'lan.bind': 'Bind: {host}:{port}',\n 'lan.off': 'Currently localhost-only.',\n 'lan.urls': 'LAN URLs: {urls}',\n 'lan.firewall.ok': 'firewall open',\n 'lan.firewall.bad': 'firewall blocked (needs admin)',\n 'lan.firewall.unmanaged': 'firewall not managed (no supported firewall detected)',\n 'lan.untouched': 'The toggle has never been used; the profile patch is only written once you flip it.',\n 'lan.pendingRestart': 'The bind change takes effect after dsh web restarts.',\n 'settings.inherit': 'Inherit',\n 'settings.on': 'On',\n 'settings.off': 'Off',\n 'settings.overridden': 'Overridden',\n 'settings.reset': 'Reset to default',\n 'settings.notExposed': 'This DSH version does not expose this plugin\\'s settings namespace to the configuration page, so the form is unavailable. Edit $DSH_HOME/settings.yaml directly, or confirm that the plugin owning the namespace is mounted with its settings domain and restart.',\n 'settings.readOnly': 'This deployment stores settings read-only.',\n 'settings.expand': 'Show settings',\n 'settings.collapse': 'Hide settings',\n 'settings.save': 'Save',\n 'settings.saving': 'Saving…',\n 'settings.discard': 'Discard',\n 'settings.unsaved': 'Unsaved',\n 'settings.saveFailed': 'The deployment did not accept these values; they were left for you to correct.',\n 'settings.invalidNumber': 'Enter a number, or leave blank to use the default.',\n // Update panel (the sidebar update trigger).\n 'update.label': 'Check for updates',\n 'update.badge': 'Update available',\n 'update.availableLabel': 'New version available. Check for updates',\n 'update.title': 'Check for updates',\n 'update.checking': 'Checking the remote repository for newer releases…',\n 'update.upToDate': 'Everything is up to date',\n 'update.upToDateDetail': '{name} is at the latest version v{version}.',\n 'update.found': 'A new version is available',\n 'update.foundDetail': '{name} has a newer release v{version}. Confirm to start the update.',\n 'update.start': 'Update now',\n 'update.updating': 'Updating {name} to v{version}; this may take 1-2 minutes…',\n 'update.cooldownNotice': 'This user-initiated update bypasses pnpm\\'s 24-hour release cooldown (supply-chain protection) and installs the selected version immediately.',\n 'update.updatingTitle': 'Updating…',\n 'update.done': 'Update complete',\n 'update.doneDetail': 'All components are up to date.',\n 'update.restartHint': 'Restart dsh web for the new version to take effect: stop it with Ctrl+C in the terminal, then run dsh web again.',\n 'update.linkMode': 'Local development mode',\n 'update.linkModeDetail': 'dsh-web or one of its components is installed via a local link and cannot be updated remotely. Latest npm release: {version}. Sync the local checkout, or remove a standalone link duplicated by the aggregate.',\n 'update.missing': 'dsh-web not found',\n 'update.missingDetail': 'Could not locate the installed dsh-web aggregate package. Install it with: dsh plugin --profile <profile> add @linxin666/dsh-web-all',\n 'update.offline': 'Cannot reach the update source',\n 'update.offlineDetail': 'The network is unavailable or the update service is failing; try again later.',\n 'update.unmounted': 'The update service is not loaded',\n 'update.unmountedDetail': 'The running dsh web process loads a plugin build without the update service; restart dsh web (Ctrl+C, then run dsh web again) and retry.',\n 'update.error': 'Update failed',\n 'update.packages': 'Component versions',\n 'update.releaseNotes': 'v{version} release notes',\n 'update.releaseFeatures': 'New Features',\n 'update.releaseFixes': 'Bug Fixes',\n 'update.releaseOther': 'Other Changes',\n 'update.releaseUnavailable': 'Release notes are unavailable for this version; see the GitHub release instead.',\n 'update.componentVersions': 'View component versions',\n 'update.retry': 'Check again',\n 'update.close': 'Close update panel',\n 'update.error.pnpmMissing': 'pnpm was not found (tried pnpm / corepack / npx). Install pnpm and restart the app (Windows: npm install -g pnpm or corepack enable; macOS: brew install pnpm or corepack enable).',\n 'update.error.timeout': 'The update timed out and the install process was killed; try again.',\n 'update.error.notFound': 'The dsh-web aggregate package is not installed; nothing to update.',\n 'update.error.link': 'dsh-web or one of its components uses a local link. Sync the checkout, or remove a standalone link duplicated by the aggregate.',\n 'update.error.pnpmFailed': 'The update failed (pnpm exited with code {code}); see the output below.',\n 'update.error.stale': 'The update command ran but the installed versions did not change. Likely cause: the pnpm 11 minimumReleaseAge gate silently skips releases published less than 24 hours ago. Add minimumReleaseAgeExclude (e.g. \"@linxin666/*\") or set minimumReleaseAge: 0 in pnpm-workspace.yaml under the profile directory (~/.dsh/profiles/<profile>), then run the update again.',\n 'update.error.verifyFailed': 'The update command ran but the installed versions could not be verified afterwards (registry probe failed or the install path changed). Inspect the output below, or retry later.',\n 'update.error.unknown': 'Update failed; try again.',\n} satisfies Record<RemoteKey, string>\n","/**\n * Pair boot flow: the QR link's `pair` parameter. Runs from the client\n * apply on every page load, on any device: `pair` present → accept the\n * token, then reload so the whole SPA boots with the device cookie (the\n * accept endpoint is exempt from the pairing gate; every other /api request\n * needs the cookie). Every device — phone or PC — lands on the same official\n * Web GUI; phones get the injected portrait adaptation. Failure of accept\n * leaves a sessionStorage marker the entry renders as a one-time notice.\n */\n\nimport type { Context } from '@deepseek-ai/cordis'\nimport { acceptPair, readPairParams } from './pair-api.ts'\n\n/** sessionStorage key for the failed-pair notice. */\nexport const PAIR_FAILED_MARKER = 'dsh-remote-pair-failed'\n\n/**\n * The page-navigation surface the boot flow drives. Browser pages use the\n * default (window.location/history); tests inject a fake.\n */\nexport interface PageSurface {\n /** The current page URL (read fresh on each access). */\n href: string\n /** Replace the URL without reloading. */\n replaceState(url: string): void\n /** Navigate to a URL (a fresh page load). */\n navigate(url: string): void\n /** Reload the page. */\n reload(): void\n}\n\n/** The browser implementation of {@link PageSurface}. */\nexport const browserPage: PageSurface = {\n get href(): string {\n return window.location.href\n },\n replaceState(url: string): void {\n window.history.replaceState(null, '', url)\n },\n navigate(url: string): void {\n window.location.assign(url)\n },\n reload(): void {\n window.location.reload()\n },\n}\n\n/**\n * Run the pair boot flow for this page load.\n * @param ctx - client root context (unused since the deep-link retirement;\n * kept for call-site stability).\n * @param search - the current location.search.\n * @param page - the page surface (defaults to the browser).\n */\nexport function runPairBootFlow(ctx: Context, search: string, page: PageSurface = browserPage): void {\n void ctx\n const params = readPairParams(search)\n if (params.pair !== undefined) {\n void runAccept(params.pair, page)\n }\n}\n\n/** Accept the token, then reload into the paired official UI. */\nasync function runAccept(token: string, page: PageSurface): Promise<void> {\n let ok = false\n try {\n const result = await acceptPair(token)\n ok = result.ok\n if (!ok) sessionStorage.setItem(PAIR_FAILED_MARKER, 'failed')\n } catch {\n sessionStorage.setItem(PAIR_FAILED_MARKER, 'failed')\n }\n // Drop the token from the URL either way: an accepted token is consumed\n // (a re-scan would 409), and a failed one must not loop.\n const url = new URL(page.href)\n url.searchParams.delete('pair')\n page.replaceState(`${url.pathname}${url.search}${url.hash}`)\n if (ok) {\n // Every device reloads into the same official Web GUI at this origin.\n page.reload()\n }\n}\n","/**\n * Remote desktop channel constants — SDK-independent so tests and the\n * client half can pin them without importing the host SDK graph.\n *\n * Access model on the 0.1.2-alpha.2 line: the host /api surface has no\n * per-method privilege pin — the \"configuration plane is local\" behavior\n * lives in the browser (client plugins branch on connection.isLoopback), and\n * the paired remote desktop flips into host mode via the transport hook\n * (ownsHost) while every call rides this gated channel as a loopback-shaped\n * request. A paired device is therefore a full-control credential by\n * design; the only paths that stay physically local are the control planes\n * below (pairing control, self-update, plugin install/remove, host power).\n */\n\n/** Gated mirror of same-origin fenced paths (`/remote` + original pathname). */\nexport const REMOTE_PREFIX = '/remote'\n\n/** Connection-plugin method prefix under the gated channel. */\nexport const REMOTE_API_PREFIX = `${REMOTE_PREFIX}/api`\n\n/**\n * The gated mirrors of the official client WebSocket paths. On the pinned\n * 0.1.2-alpha.2 line the client opens ONE persistent stream socket — the\n * Typert gateway mux at `/api/remote.mux` — and every Remote stream\n * (workspace follow, session feed, ...) rides it. If that socket is not\n * rewritten onto the gated channel the phone's streams die at the connection\n * fence and the UI shows an empty workspace/session mirror, so the mux is\n * the one path that must never be missing here.\n */\nexport const REMOTE_API_PATHS = {\n mux: `${REMOTE_API_PREFIX}/remote.mux`,\n} as const\n\n/**\n * Exact upgrade paths registered on webServer (the SDK matches upgrades by\n * exact path, not prefix). Query strings ride on the request URL.\n */\nexport const REMOTE_UPGRADE_PATHS = [\n REMOTE_API_PATHS.mux,\n `${REMOTE_PREFIX}/sidebar/ws/terminal`,\n `${REMOTE_PREFIX}/sidebar/ws/agent-terminals`,\n `${REMOTE_API_PREFIX}/dsh-ssh/terminal`,\n] as const\n\n/** Plugin-manager HTTP prefix: install/remove stay physically local. */\nexport const PLUGIN_MANAGER_PATH = '/api/plugin-manager'\n\n/** Family settings-bridge HTTP prefix — re-exposed to paired devices (plain settings parity). */\nexport const WEB_UI_SETTINGS_BRIDGE_PATH = '/api/dsh-web-ui-settings'\n\n/**\n * The cookieless device credential: the boot patch reads the device id from\n * the /pair-app URL, keeps it in sessionStorage, and attaches it to every\n * gated HTTP call as this header (and to WebSocket upgrades as the `device`\n * query parameter - WS handshakes cannot carry headers from the Web API).\n * The channel gate accepts it exactly like the device cookie, so the mobile\n * flow works even with browser cookies fully blocked; the cookie remains the\n * primary credential on normal browsers.\n */\nexport const REMOTE_DEVICE_HEADER = 'x-dsh-remote-device'\nexport const REMOTE_DEVICE_QUERY = 'device'\n\n/**\n * Path prefixes that stay physically local even for a paired device. A\n * paired remote desktop may use the full host API (chat, sessions,\n * settings, credentials, presets — it is a full-control credential), but it\n * must not reach the machine-control planes: pairing control itself, the\n * dsh-web self-update installer, and plugin install/remove.\n */\nexport const LOCAL_ONLY_PREFIXES: readonly string[] = [\n '/api/pair',\n '/api/update',\n PLUGIN_MANAGER_PATH,\n] as const\n\n/**\n * Whether a paired inner path must stay physically local.\n * @param innerPath - the rewritten inner path (e.g. `/api/session.list`).\n * @returns a denial message, or undefined when the path may be proxied.\n */\nexport function localOnlyDenial(innerPath: string): string | undefined {\n for (const prefix of LOCAL_ONLY_PREFIXES) {\n if (innerPath === prefix || innerPath.startsWith(`${prefix}/`)) {\n return `${prefix.slice(1)} stays physically local and stays unreachable from a paired remote desktop`\n }\n }\n return undefined\n}\n","/**\n * The remote-channel rewrite contract as pure data (issue #987): both the\n * browser patch (client/remote-channel.ts) and the parse-time boot patch\n * (remote-channel-boot.ts, inlined into index.html by the host) decide from\n * these tables, so the two can never drift apart.\n * @module @linxin666/dsh-remote-web-ui/remote-channel-rules\n */\n\n/** The gated mirror prefix (must match src/remote-methods.ts). */\nexport const REMOTE_PREFIX = '/remote'\n\nimport { REMOTE_DEVICE_HEADER, REMOTE_DEVICE_QUERY } from './remote-methods.ts'\n\nexport { REMOTE_DEVICE_HEADER, REMOTE_DEVICE_QUERY }\n\n/** Connection-plugin method prefix under the gated channel. */\nexport const REMOTE_API_PREFIX = `${REMOTE_PREFIX}/api`\n\n/** Every decision input of the remote-channel rewrite, JSON-serializable. */\nexport interface RemoteChannelRules {\n readonly remotePrefix: string\n readonly apiPrefix: string\n readonly pairPrefix: string\n readonly updatePrefix: string\n readonly settingsBridgePrefix: string\n readonly sidebarPrefix: string\n readonly gitPrefix: string\n readonly petPrefix: string\n readonly wsPaths: readonly string[]\n /** Header carrying the cookieless device credential on gated fetches. */\n readonly deviceHeader: string\n /** sessionStorage key holding the device credential (set by /pair-app). */\n readonly deviceKey: string\n /** Query parameter carrying it on WebSocket upgrades. */\n readonly deviceQuery: string\n}\n\n/** The live rule set. */\nexport const REMOTE_CHANNEL_RULES: RemoteChannelRules = {\n remotePrefix: REMOTE_PREFIX,\n apiPrefix: '/api/',\n pairPrefix: '/api/pair/',\n updatePrefix: '/api/update/',\n settingsBridgePrefix: '/api/dsh-web-ui-settings',\n sidebarPrefix: '/sidebar/',\n gitPrefix: '/git/',\n petPrefix: '/pet/',\n // The official 0.1.2-alpha.2 line opens exactly one stream socket (the\n // Typert gateway mux, /api/remote.mux); the legacy /api/events.* paths\n // were removed by the SDK and stay absent here.\n wsPaths: [\n '/api/remote.mux',\n '/sidebar/ws/terminal',\n '/sidebar/ws/agent-terminals',\n '/api/dsh-ssh/terminal',\n ],\n deviceHeader: REMOTE_DEVICE_HEADER,\n deviceKey: 'dsh-remote-device',\n deviceQuery: REMOTE_DEVICE_QUERY,\n}\n\n/** The window global the boot patch publishes its seat under. */\nexport const REMOTE_CHANNEL_BOOT_GLOBAL = '__DSH_REMOTE_CHANNEL_BOOT__'\n\n/**\n * The seat the parse-time boot patch installs: hook seats the plugin's\n * client apply adopts, a pending-unpaired flag for signals raised before\n * adoption, and restore() retiring the patch (also removes the global).\n */\nexport interface RemoteChannelBootSeat {\n onUnpaired: (() => void) | null\n onPaired: (() => void) | null\n pendingUnpaired: boolean\n restore(): void\n}\n","/**\n * The remote desktop channel — browser half. On a non-loopback origin (LAN\n * address or public tunnel) fenced host routes refuse the request, and\n * pairing is the real access control — so same-origin traffic the desktop\n * issues is rewritten onto this plugin's gated `/remote` prefix (host half\n * in src/remote-api.ts). The host then re-issues the call to 127.0.0.1 so\n * plugin loopback fences pass.\n *\n * The rewrite is deliberately narrow:\n * - loopback origins are untouched (the desktop at 127.0.0.1 keeps original paths);\n * - the pairing routes (`/api/pair/*`) stay where they are — accept must\n * work BEFORE a device is paired;\n * - the update endpoints (`/api/update/*`) stay loopback-only;\n * - the family settings bridge (`/api/dsh-web-ui-settings/*`) stays\n * loopback-only (same plane as SDK settings.*);\n * - `/api/*` (SDK methods and `/api/<plugin>/...` plugin namespaces),\n * `/sidebar/*`, `/git/*`, and `/pet/*` ride the channel;\n * - fetch, EventSource, WebSocket, and img/script/iframe `src` are patched;\n * everything else calls the original unchanged.\n *\n * Pure helpers are exported for unit tests; `installRemoteChannel` patches\n * the given window and returns their restore.\n */\n\nimport {\n REMOTE_API_PREFIX,\n REMOTE_CHANNEL_RULES,\n REMOTE_PREFIX,\n} from '../remote-channel-rules.ts'\n\nexport { REMOTE_API_PREFIX, REMOTE_PREFIX }\nexport type { RemoteChannelBootSeat } from '../remote-channel-rules.ts'\nexport { REMOTE_CHANNEL_BOOT_GLOBAL } from '../remote-channel-rules.ts'\n\nconst RULES = REMOTE_CHANNEL_RULES\n\n/** Minimal settings snapshot used by the remote channel decision. */\nexport interface RemoteChannelSettingsSnapshot {\n status: 'ready' | 'loading' | 'unavailable' | string\n value?: { enabled?: boolean; requirePairingForLan?: boolean }\n}\n\n/** Decide whether a remote desktop channel is required from local or host policy. */\nexport function remoteChannelRequired(\n hostname: string,\n snapshot: RemoteChannelSettingsSnapshot,\n hostPairingPolicy: boolean | undefined,\n): boolean {\n if (isLoopbackHostname(hostname)) return false\n if (snapshot.status === 'ready') {\n return (snapshot.value?.enabled ?? true) && (snapshot.value?.requirePairingForLan ?? true)\n }\n // Install provisionally while the host probe is pending so early SDK calls\n // cannot escape onto the plain remote origin. A confirmed false retires it.\n return hostPairingPolicy !== false\n}\n\n/**\n * Browser-safe loopback classification for the page origin (the SDK client\n * exports its own; this copy keeps the module dependency-free).\n * @param hostname - a location hostname (IPv6 without brackets).\n * @returns true for localhost, IPv6 loopback, or any 127/8 literal.\n */\nexport function isLoopbackHostname(hostname: string): boolean {\n if (hostname === 'localhost' || hostname === '::1') return true\n const parts = hostname.split('.')\n return parts.length === 4 && parts[0] === '127' && parts.every(part => /^\\d{1,3}$/.test(part) && Number(part) <= 255)\n}\n\n/**\n * Whether one same-origin path must ride the gated channel (fetch, EventSource,\n * img/script/iframe src).\n * @param pathname - the request URL pathname.\n */\nexport function shouldRewriteFetchPath(pathname: string): boolean {\n if (pathname.startsWith(RULES.pairPrefix)) return false\n if (pathname.startsWith(RULES.updatePrefix)) return false\n if (pathname === RULES.settingsBridgePrefix || pathname.startsWith(`${RULES.settingsBridgePrefix}/`)) return false\n if (pathname.startsWith(RULES.apiPrefix)) return true\n if (pathname.startsWith(RULES.sidebarPrefix) || pathname === '/sidebar') return true\n if (pathname.startsWith(RULES.gitPrefix) || pathname === '/git') return true\n if (pathname.startsWith(RULES.petPrefix) || pathname === '/pet') return true\n return false\n}\n\n/**\n * Whether one WebSocket path must ride the gated channel.\n * @param pathname - the WebSocket URL pathname.\n */\nexport function shouldRewriteWsPath(pathname: string): boolean {\n return RULES.wsPaths.includes(pathname)\n}\n\n/** The gated twin of one fenced path (`/remote` + original pathname). */\nexport function rewritePath(pathname: string): string {\n return `${REMOTE_PREFIX}${pathname}`\n}\n\n/**\n * Rewrite one raw URL string when it is same-origin and fenced. Relative\n * inputs stay relative so resource loaders do not unexpectedly absolutize.\n */\nexport function rewriteRawUrl(raw: string, baseHref: string, origin: string): string {\n let url: URL\n try {\n url = new URL(raw, baseHref)\n } catch {\n return raw\n }\n if (url.origin !== origin) return raw\n if (!shouldRewriteFetchPath(url.pathname)) return raw\n url.pathname = rewritePath(url.pathname)\n if (raw.startsWith('/') && !raw.startsWith('//')) {\n return `${url.pathname}${url.search}${url.hash}`\n }\n return url.href\n}\n\n/** A constructor that exposes a configurable `src` on its prototype. */\ninterface SrcConstructor {\n prototype: object\n}\n\n/** The subset of window the channel needs (injectable for tests). */\nexport interface ChannelWindow {\n fetch: typeof globalThis.fetch\n WebSocket: typeof WebSocket\n EventSource?: typeof EventSource\n HTMLImageElement?: SrcConstructor\n HTMLScriptElement?: SrcConstructor\n HTMLIFrameElement?: SrcConstructor\n location: { origin: string; href: string }\n sessionStorage?: { getItem(key: string): string | null }\n}\n\n/** Options for {@link installRemoteChannel}. */\nexport interface RemoteChannelOptions {\n /** Called when a gated call came back unpaired (code `unpaired`). */\n onUnpaired?: () => void\n /** Called when a gated call succeeded (an unpaired banner can retire). */\n onPaired?: () => void\n}\n\n/** Read an unpaired code from either the SDK envelope or a plugin JSON body. */\nfunction unpairedCodeOf(value: unknown): string | undefined {\n if (typeof value !== 'object' || value === null) return undefined\n const record = value as { result?: unknown; error?: unknown }\n const nested = record.result\n if (typeof nested === 'object' && nested !== null) {\n const error = (nested as { error?: unknown }).error\n if (typeof error === 'object' && error !== null && typeof (error as { code?: unknown }).code === 'string') {\n return (error as { code: string }).code\n }\n }\n const error = record.error\n if (typeof error === 'object' && error !== null && typeof (error as { code?: unknown }).code === 'string') {\n return (error as { code: string }).code\n }\n return undefined\n}\n\n/**\n * Whether a gated 403 is the unpaired-device fence (not a loopback-only\n * method denial, which uses the same status with code `forbidden`).\n */\nexport async function isUnpairedDenied(response: Response): Promise<boolean> {\n if (response.status !== 403) return false\n try {\n return unpairedCodeOf(await response.json()) === 'unpaired'\n } catch {\n return false\n }\n}\n\n/**\n * Wrap a prototype `src` setter so fenced same-origin URLs ride `/remote`.\n * No-ops when the constructor is missing or `src` is not configurable.\n */\nfunction patchSrcAccessor(ctor: SrcConstructor | undefined, rewrite: (value: string) => string): () => void {\n if (ctor === undefined) return () => {}\n const descriptor = Object.getOwnPropertyDescriptor(ctor.prototype, 'src')\n if (descriptor === undefined || descriptor.configurable === false) return () => {}\n if (descriptor.set === undefined) return () => {}\n const originalSet = descriptor.set\n const originalGet = descriptor.get\n Object.defineProperty(ctor.prototype, 'src', {\n configurable: true,\n enumerable: descriptor.enumerable ?? true,\n get: originalGet,\n set(this: unknown, value: unknown) {\n originalSet.call(this, rewrite(String(value)))\n },\n })\n return () => {\n Object.defineProperty(ctor.prototype, 'src', descriptor)\n }\n}\n\n/**\n * Patch `fetch`, `EventSource`, `WebSocket`, and resource `src` accessors on\n * one window to route fenced traffic through the gated channel.\n * @param window - the browser window (or a test double).\n * @param options - the unpaired callback.\n * @returns a function restoring the originals.\n */\nexport function installRemoteChannel(window: ChannelWindow, options: RemoteChannelOptions = {}): () => void {\n const originalFetch = window.fetch\n const OriginalWebSocket = window.WebSocket\n const OriginalEventSource = window.EventSource\n\n const sameOrigin = (url: URL): boolean => url.origin === window.location.origin\n const rewrite = (raw: string): string => rewriteRawUrl(raw, window.location.href, window.location.origin)\n\n // The cookieless device credential (set by the /pair-app capture script):\n // attaches as a header on gated fetches and as the device query on WS and\n // EventSource handshakes, mirroring the boot patch exactly.\n const device = (() => {\n try {\n return window.sessionStorage?.getItem(RULES.deviceKey) ?? null\n } catch {\n return null\n }\n })()\n const attach = (init?: RequestInit): RequestInit | undefined => {\n if (device === null) return init\n const headers = init?.headers\n if (typeof Headers !== 'undefined' && headers instanceof Headers) {\n try { headers.set(RULES.deviceHeader, device) } catch { /* ignore */ }\n return init\n }\n if (typeof headers === 'object' && headers !== null) {\n return { ...init, headers: { ...(headers as Record<string, string>), [RULES.deviceHeader]: device } } as RequestInit\n }\n return init\n }\n const withDeviceQuery = (url: URL): URL => {\n if (device !== null) url.searchParams.set(RULES.deviceQuery, device)\n return url\n }\n\n const patchedFetch: typeof globalThis.fetch = (input, init) => {\n const url = new URL(\n typeof input === 'string' || input instanceof URL ? input.toString() : input.url,\n window.location.href,\n )\n if (sameOrigin(url) && shouldRewriteFetchPath(url.pathname)) {\n const rewritten = new URL(url)\n rewritten.pathname = rewritePath(url.pathname)\n const next: RequestInfo | URL = typeof input === 'string' || input instanceof URL\n ? rewritten.toString()\n : new Request(rewritten, input)\n return Promise.resolve(originalFetch.call(window, next, attach(init))).then(async (response) => {\n if (await isUnpairedDenied(response.clone())) options.onUnpaired?.()\n else options.onPaired?.()\n return response\n })\n }\n return originalFetch.call(window, input, init)\n }\n\n class PatchedWebSocket extends OriginalWebSocket {\n constructor(url: string | URL, protocols?: string | string[]) {\n const parsed = new URL(url.toString(), window.location.href)\n const wsOrigin = parsed.protocol === 'wss:' ? `https://${parsed.host}` : parsed.protocol === 'ws:' ? `http://${parsed.host}` : ''\n if (wsOrigin !== '' && wsOrigin === window.location.origin && shouldRewriteWsPath(parsed.pathname)) {\n const rewritten = new URL(parsed)\n rewritten.pathname = rewritePath(parsed.pathname)\n super(withDeviceQuery(rewritten), protocols)\n return\n }\n super(url, protocols)\n }\n }\n\n const restoreSrc = [\n patchSrcAccessor(window.HTMLImageElement, rewrite),\n patchSrcAccessor(window.HTMLScriptElement, rewrite),\n patchSrcAccessor(window.HTMLIFrameElement, rewrite),\n ]\n\n window.fetch = patchedFetch\n window.WebSocket = PatchedWebSocket as typeof WebSocket\n if (OriginalEventSource !== undefined) {\n class PatchedEventSource extends OriginalEventSource {\n constructor(url: string | URL, eventSourceInitDict?: EventSourceInit) {\n const parsed = new URL(url.toString(), window.location.href)\n if (sameOrigin(parsed) && shouldRewriteFetchPath(parsed.pathname)) {\n const rewritten = new URL(parsed)\n rewritten.pathname = rewritePath(parsed.pathname)\n super(withDeviceQuery(rewritten), eventSourceInitDict)\n return\n }\n super(url, eventSourceInitDict)\n }\n }\n window.EventSource = PatchedEventSource\n }\n\n return () => {\n window.fetch = originalFetch\n window.WebSocket = OriginalWebSocket\n if (OriginalEventSource !== undefined) window.EventSource = OriginalEventSource\n for (const restore of restoreSrc) restore()\n }\n}\n\n/**\n * The remote-channel lifecycle transition between two steady states:\n * running (active + installed) and retired (inactive + not installed).\n * The client apply drives the channel with this decision and retires the\n * unpaired fence notice together with the channel itself — a notice raised\n * while the channel was briefly active must not outlive it (issue #808).\n */\nexport type ChannelTransition = 'install' | 'retire' | 'none'\n\n/**\n * Decide what the channel lifecycle must do next.\n * @param active - whether the gated remote channel should be running now.\n * @param installed - whether it currently is (disposer !== undefined).\n * @returns the transition to apply.\n */\nexport function channelTransition(active: boolean, installed: boolean): ChannelTransition {\n if (active && !installed) return 'install'\n if (!active && installed) return 'retire'\n return 'none'\n}\n","/**\n * Unpaired-desktop notice: a full-page blocking surface rendered when the remote channel\n * (see remote-channel.ts) refuses a call because this desktop browser has no\n * live paired-device cookie. Retires automatically once a gated call\n * succeeds (the channel reports pairing) or when the channel itself is\n * torn down (requirePairingForLan off / plugin disabled), so it never\n * outlives the unpaired state it describes.\n */\nimport { useState, type FormEvent } from 'react'\nimport type { TranslateNS } from '@deepseek-ai/dsh-client-ui-slots'\nimport { acceptPair } from './pair-api.ts'\nimport css from './remote.module.css'\n\n/** Notice props: localized copy. */\nexport interface FenceNoticeProps {\n t: TranslateNS<'remote'>\n /** Retry after the user has opened a freshly issued computer pairing link. */\n onRetry: () => void\n /** Optional custom pairing acceptor for testing / dependency injection. */\n onAccept?: (token: string) => Promise<{ ok: true } | { ok: false; code: 'invalid' | 'used' | 'forbidden' }>\n}\n\n/**\n * Extract a pairing token from either a raw token string or a copied pairing link URL.\n */\nexport function extractPairToken(input: string): string | undefined {\n const trimmed = input.trim()\n if (trimmed === '') return undefined\n try {\n const url = new URL(trimmed)\n const token = url.searchParams.get('pair')\n if (token !== null && token !== '') return token\n } catch {\n // Plain token string\n }\n return trimmed\n}\n\n/**\n * Render the unpaired blocking page.\n * @param props - localized copy.\n * @returns the notice element.\n */\nexport function FenceNotice({ t, onRetry, onAccept = acceptPair }: FenceNoticeProps) {\n const [tokenInput, setTokenInput] = useState('')\n const [submitting, setSubmitting] = useState(false)\n const [errorMsg, setErrorMsg] = useState<string | undefined>(undefined)\n\n const handleSubmit = async (event: FormEvent<HTMLFormElement>) => {\n event.preventDefault()\n const token = extractPairToken(tokenInput)\n if (!token) return\n\n setSubmitting(true)\n setErrorMsg(undefined)\n\n try {\n const result = await onAccept(token)\n if (result.ok) {\n onRetry()\n return\n }\n if (result.code === 'invalid') {\n setErrorMsg(t('fence.unpaired.tokenInvalid'))\n } else if (result.code === 'used') {\n setErrorMsg(t('fence.unpaired.tokenUsed'))\n } else {\n setErrorMsg(t('fence.unpaired.tokenFailed'))\n }\n } catch {\n setErrorMsg(t('fence.unpaired.tokenFailed'))\n } finally {\n setSubmitting(false)\n }\n }\n\n return (\n <div className={css.fencePage} role=\"dialog\" aria-modal=\"true\" aria-labelledby=\"remote-fence-title\">\n <main className={css.fenceCard} data-dsh-plugin=\"remote-web-ui\">\n <div className={css.fenceMark} aria-hidden=\"true\">×</div>\n <p className={css.fenceEyebrow}>{t('fence.unpaired.eyebrow')}</p>\n <h1 id=\"remote-fence-title\" className={css.fenceTitle}>{t('fence.unpaired.title')}</h1>\n <p className={css.fenceDetail}>{t('fence.unpaired.hint')}</p>\n <ol className={css.fenceSteps}>\n <li>{t('fence.unpaired.stepDesktop')}</li>\n <li>{t('fence.unpaired.stepLink')}</li>\n <li>{t('fence.unpaired.stepOpen')}</li>\n </ol>\n\n <form className={css.fenceForm} onSubmit={handleSubmit}>\n <div className={css.fenceInputRow}>\n <input\n type=\"text\"\n className={css.fenceInput}\n placeholder={t('fence.unpaired.tokenPlaceholder')}\n value={tokenInput}\n onChange={event => {\n setTokenInput(event.target.value)\n if (errorMsg !== undefined) setErrorMsg(undefined)\n }}\n disabled={submitting}\n aria-label={t('fence.unpaired.tokenPlaceholder')}\n />\n <button\n className={css.fencePairButton}\n type=\"submit\"\n disabled={submitting || tokenInput.trim() === ''}\n >\n {submitting ? t('fence.unpaired.pairing') : t('fence.unpaired.pairAction')}\n </button>\n </div>\n {errorMsg !== undefined && (\n <p className={css.fenceError} role=\"alert\">{errorMsg}</p>\n )}\n </form>\n\n <button className={css.fenceRetry} type=\"button\" onClick={onRetry}>\n {t('fence.unpaired.retry')}\n </button>\n <p className={css.fenceFootnote}>{t('fence.unpaired.footnote')}</p>\n </main>\n </div>\n )\n}\n","// Generated by scripts/sync-shared.mjs from shared/client/telemetry.ts. Do not edit this copy; edit the shared source and run \"node scripts/sync-shared.mjs\".\n/**\n * Anonymous install telemetry shared by the DSH Web UI family plugins.\n *\n * Once per UTC day per browser, each wired plugin sends one heartbeat to\n * the dsh-market edge API listing its package name (and version when known).\n * The payload carries no conversation data and no identifiers beyond a random\n * UUID generated in localStorage; the server hashes it with a deployment salt\n * before storage and never persists IP addresses. Sends are fire-and-forget:\n * failures stay silent and simply retry on a later mount or day. The system\n * is documented in docs/telemetry.md.\n */\n\nexport type TelemetryChannel = 'market' | 'npm' | 'unknown'\n\nexport interface TelemetryItem {\n /** npm package name or asset id, e.g. \"@linxin666/dsh-pet\" or \"skin:harbor\". */\n name: string\n /** Installed version when known; omitted otherwise. */\n version?: string\n /** Install channel when determinable (market = Workshop install). */\n channel?: TelemetryChannel\n}\n\nconst VISITOR_KEY = 'dsh-web-ui-telemetry-visitor'\nconst DAY_KEY_PREFIX = 'dsh-web-ui-telemetry-day:'\nconst ENDPOINT = 'https://dsh-market.com/api/telemetry/event'\n\n// Baked into each client bundle by shared/tsdown.client.ts (the package's own\n// package.json version at build time). Undefined in dev/test builds.\ndeclare const __DSH_PKG_VERSION__: string | undefined\n\n/** The building package's version, when the bundle carries it. */\nfunction bakedVersion(): string | undefined {\n try {\n return typeof __DSH_PKG_VERSION__ === 'string' && __DSH_PKG_VERSION__ !== ''\n ? __DSH_PKG_VERSION__\n : undefined\n } catch {\n return undefined\n }\n}\n\n/** Read or lazily create the anonymous visitor id; null when storage is unavailable. */\nfunction visitorId(): string | null {\n try {\n const existing = localStorage.getItem(VISITOR_KEY)\n if (existing && /^[A-Za-z0-9_-]{16,64}$/.test(existing)) return existing\n const fresh = crypto.randomUUID().replaceAll('-', '')\n localStorage.setItem(VISITOR_KEY, fresh)\n return fresh\n } catch {\n // Storage unavailable (privacy mode, sandboxed frame): report nothing.\n return null\n }\n}\n\n/** Drop stale per-day dedup keys so localStorage does not grow forever. */\nfunction pruneDayKeys(today: string): void {\n try {\n for (let index = localStorage.length - 1; index >= 0; index -= 1) {\n const key = localStorage.key(index)\n if (key !== null && key.startsWith(DAY_KEY_PREFIX) && key !== DAY_KEY_PREFIX + today) {\n localStorage.removeItem(key)\n }\n }\n } catch { /* best effort */ }\n}\n\n/**\n * Fire the daily heartbeat for the given items at most once per UTC day per\n * browser. Never throws and never blocks the caller. Items without an explicit\n * version inherit the bundle's baked build version.\n */\nexport function reportDailyHeartbeat(items: readonly TelemetryItem[]): void {\n try {\n if (items.length === 0) return\n const today = new Date().toISOString().slice(0, 10)\n // Automation contexts (CDP-driven QA browsers, fresh isolated profiles)\n // mint a new visitor id per run and would inflate instance counts.\n if (navigator.webdriver) return\n if (localStorage.getItem(DAY_KEY_PREFIX + today) !== null) return\n const visitor = visitorId()\n if (visitor === null) return\n pruneDayKeys(today)\n const payloadItems = items.map((item) => {\n const out: Record<string, string> = { name: item.name }\n const version = item.version ?? bakedVersion()\n if (version !== undefined) out.version = version\n if (item.channel !== undefined) out.channel = item.channel\n return out\n })\n const body = JSON.stringify({ kind: 'heartbeat', visitor, items: payloadItems })\n void fetch(ENDPOINT, {\n method: 'POST',\n headers: { 'content-type': 'application/json' },\n body,\n keepalive: true,\n }).then((response) => {\n // Mark the day only after an accepted send, so offline browsers retry\n // on a later mount instead of going dark until tomorrow.\n if (response.ok) localStorage.setItem(DAY_KEY_PREFIX + today, '1')\n }).catch(() => { /* unreachable endpoint: stay silent */ })\n } catch { /* never break the host UI over telemetry */ }\n}\n","/**\n * Portrait-touch adaptation of the OFFICIAL desktop Web GUI (the dsh-LAN\n * approach): while a touch device is in portrait, inject a CSS + gesture\n * layer on top of the running SPA instead of maintaining a second UI. The\n * official layout already auto-collapses the sidebar below 1024px; this\n * layer adds touch-target sizing, 16px inputs (iOS focus zoom), safe-area\n * padding, a floating whale button as the collapsed-sidebar entry (with a\n * verified toggle fallback for cohorts whose layout face mounts inert),\n * swipe gestures, long-press session menus, a bottom-sheet composer picker\n * (model / effort / permission menus), desktop-surface suppression, and\n * composer/header compaction.\n * Landscape, desktop, and wide viewports stay untouched; a manual\n * sessionStorage opt-out (dsh-remote-force-desktop=1) disables the layer.\n *\n * Selector strategy: CSS Modules class names are hash-prefixed with the\n * semantic name as a stable suffix (`pI_x6G_centerCol`), so attribute\n * suffix selectors survive official rebuilds that only change the hash. The\n * semantic names were read off the 0.1.2-alpha.1 official client build and\n * are re-verified on every GUI QA round; rules borrowed from the dsh-LAN\n * reference (MIT, v47-v78) keep their version comments.\n * @module @linxin666/dsh-remote-web-ui/client/mobile-adapt\n */\n\nimport type { RemoteKey } from './locales.ts'\n\n/** The window global the plugin apply() wires the layout service into. */\nexport interface RemoteAdaptGlobal {\n evaluate: () => void\n /** Wired by the plugin apply once ctx.layout is live. */\n toggleSidebar: (() => void) | null\n /** Wired by the plugin apply once ctx.layout is live. */\n closeDetails: (() => void) | null\n /**\n * Wired by the plugin apply once the `remote` locale namespace is bound:\n * the translate seat the injected surfaces (whale, compact picker) read\n * their labels from. Null until then; label reads fall back to English\n * (the SDK's universal fallback) and the 600ms sync tick re-renders the\n * labels once the seat is wired.\n */\n translate: ((key: RemoteKey) => string) | null\n /** Plugin master switch: false reverts the layer, true re-evaluates. */\n setEnabled(on: boolean): void\n /** Replays a pending closeDetails once the layout face is wired (the first apply ran before the wiring). */\n flushCloseDetails(): void\n}\n\n/** Storage key for the manual desktop opt-out. */\nconst FORCE_DESKTOP_KEY = 'dsh-remote-force-desktop'\n/** Storage key for the dragged whale position. */\nconst WHALE_POS_KEY = 'dsh-remote-whale-pos'\n/** Injected stylesheet identity. */\nconst ADAPT_CSS_ID = 'dsh-remote-web-ui/mobile-adapt.css'\n/** Body class while the adaptation is active. */\nconst ACTIVE_CLASS = 'dsh-remote-portrait'\n/** Body class while the collapsed rail is hidden behind the whale. */\nconst RAIL_HIDDEN_CLASS = 'dsh-remote-rail-hidden'\n/** Whale button id. */\nconst WHALE_ID = 'dshRemoteWhale'\n/** Compact picker: synthesized model button id. */\nconst MODEL_BTN_ID = 'dshRemoteModelPick'\n/** Compact picker: synthesized effort button id. */\nconst EFFORT_BTN_ID = 'dshRemoteEffortPick'\n/** Body class while the compact picker buttons are wired. */\nconst COMPACT_CLASS = 'dsh-remote-compact-picker'\n/** Body class while the header actions are seated in the tabs row. */\nconst HEADER_SEATED_CLASS = 'dsh-remote-header-seated'\n/** The two composer picker entries the compact buttons drill into. */\ntype PickerKind = 'model' | 'effort'\n/** Locale-dependent fast path for the official picker cells (zh/en). */\nconst PICKER_CELL_PATTERN: Record<PickerKind, RegExp> = {\n model: /模型|Model/, // i18n-allow: matches official picker cell text, not plugin copy\n effort: /推理等级|Reasoning|Effort/i, // i18n-allow: matches official picker cell text, not plugin copy\n}\n/** Position of each drill cell among the sheet's chevron cells. */\nconst DRILL_INDEX: Record<PickerKind, number> = { model: 0, effort: 1 }\n/**\n * The official application frame. The layout column classes are the anchor:\n * `_frame` is shared by unrelated official components (the chat turn rail,\n * message-image thumbnails, the subagent pill, PlanReviewPanel), so a bare\n * suffix match would restyle and hit-block those. `data-dsh-frame` is the\n * aggregate compat stamp, kept as the fast path.\n */\nconst APP_FRAME_SELECTOR = '[data-dsh-frame], [class*=\"_frame\"]:has([class*=\"_centerCol\"])'\n\n/**\n * The official composer surface. `_composerSeat` is the plugin's historical\n * anchor; the official `data-dsh-surface=\"composer\"` part attribute is the\n * stable alternative if the class ever gains a modifier.\n */\nconst COMPOSER_SELECTOR = '[class$=\"_composerSeat\"], [data-dsh-surface=\"composer\"]'\n\n/** Resolve the official application frame (never a nested `_frame` surface). */\nfunction appFrame(): HTMLElement | null {\n const frame = document.querySelector(APP_FRAME_SELECTOR)\n return frame instanceof HTMLElement ? frame : null\n}\n\n/**\n * Whether the current viewport is a portrait touch device small enough to\n * need the adaptation.\n */\nfunction isMobilePortrait(): boolean {\n if (typeof window === 'undefined') return false\n if (typeof window.matchMedia !== 'function') return false\n if (!window.matchMedia('(orientation: portrait)').matches) return false\n if (!window.matchMedia('(pointer: coarse)').matches) return false\n if (window.innerWidth >= 1100) return false\n if (window.sessionStorage.getItem(FORCE_DESKTOP_KEY) === '1') return false\n return true\n}\n\n/**\n * The injected rules. Grouped by surface; version comments trace rules back\n * to the dsh-LAN reference they were ported from.\n */\nconst ADAPT_CSS: readonly string[] = [\n 'html,body{height:100%}',\n // The app frame fills the dynamic viewport (browser chrome collapse).\n // Scoped to the application frame: a bare [class$=\"_frame\"] also matches the\n // chat turn rail, message thumbnails, the subagent pill and PlanReviewPanel,\n // stretching each to a full-width 100dvh pointer-events:auto block.\n '[class*=\"_frame\"]:has([class*=\"_centerCol\"]){width:100%;height:100dvh}',\n // Collapsed rail: bigger touch targets.\n '[class$=\"_railFish\"] button,[class$=\"_panelIcon\"],[class$=\"_newSession\"]{min-width:44px;min-height:44px}',\n // Message list padding on narrow screens.\n '[class$=\"_scroll\"]{padding:8px 10px}',\n // 16px inputs prevent iOS focus zoom; keep the send button touchy.\n '[class$=\"_input\"],textarea,input{font-size:16px}',\n '[class$=\"_composer\"]{padding-bottom:calc(4px + env(safe-area-inset-bottom))}',\n // v50: slightly smaller type on portrait phones.\n '[class$=\"_scrollBody\"] [class$=\"_root\"]{font-size:14.5px}',\n '[class$=\"_scrollBody\"] [class$=\"_bubble\"]{font-size:14.5px}',\n '[class$=\"_titleRow\"] *{font-size:13px}',\n '[class*=\"_sidebarCol\"] [class$=\"_root\"],[class*=\"_sidebarCol\"] [class$=\"_newSession\"],[class*=\"_sidebarCol\"] [class$=\"_trigger\"],[class*=\"_sidebarCol\"] [class$=\"_title\"]{font-size:13px}',\n '[class*=\"_sidebarCol\"] [class$=\"_meta\"],[class*=\"_sidebarCol\"] [class$=\"_time\"]{font-size:11.5px}',\n // v50: collapsed rail hidden; the whale button is the entry. The frame's\n // grid is inline-styled (56px rail track when collapsed); pin the first\n // track to 0 so content uses the full width. On portrait phones the\n // details track is always 0 (computeColumns drops it when there is no\n // room), so the three-track override is safe here.\n '[class$=\"_frame\"][data-sidebar-collapsed]{grid-template-columns:0 minmax(0,1fr) 0 !important}',\n // The official collapsed sidebar is an absolutely-positioned overlay rail\n // (it leaves the grid flow), so the in-flow centerCol would auto-place\n // into the now-0px FIRST track and collapse the conversation to zero width\n // on an intermittent basis (the rail flips relative <-> absolute as the\n // host overlay mounts). Pin every column to an explicit track so the\n // center always lands on the 1fr track regardless of the sidebar's\n // computed position.\n '[class$=\"_frame\"][data-sidebar-collapsed] [class*=\"_sidebarCol\"]{grid-column:1/2}',\n '[class$=\"_frame\"][data-sidebar-collapsed] [class$=\"_centerCol\"]{grid-column:2/3}',\n '[class$=\"_frame\"][data-sidebar-collapsed] [class$=\"_detailsCol\"]{grid-column:3/4}',\n // Keep the chat header title clear of the floating whale.\n `body.${RAIL_HIDDEN_CLASS} [class$=\"_titleRow\"]{padding-left:52px}`,\n // The whale button itself.\n `#${WHALE_ID}{position:fixed;top:calc(4px + env(safe-area-inset-top));left:calc(8px + env(safe-area-inset-left));z-index:2147482999;width:34px;height:34px;min-width:34px;padding:0;border-radius:10px;background:var(--dsw-alias-bg-module-platform);border:1px solid var(--dsw-alias-border-l2);color:var(--dsw-alias-label-primary);display:flex;align-items:center;justify-content:center;cursor:pointer;box-shadow:0 1px 6px rgba(0,0,0,.25)}`,\n `#${WHALE_ID} svg{width:20px;height:15px;display:block}`,\n `#${WHALE_ID}:active{opacity:.72}`,\n `#${WHALE_ID}{touch-action:none}`,\n // v51/v52: smaller collapse toggle in the expanded sidebar (the toggle\n // carries two classes, so match by containment); v47's panelIcon touch\n // rule forces a 44px min on the icon itself — zero it out so the 13px\n // glyph fits the 18px button.\n '[class*=\"_sidebarCol\"] [class$=\"_logoRow\"] [class*=\"_iconButton\"]{width:18px;height:18px}',\n '[class*=\"_sidebarCol\"] [class$=\"_logoRow\"] [class*=\"_iconButton\"] svg{width:13px;height:13px;min-width:0;min-height:0}',\n // v77: workspace rows' right-side actions (menu + new session) are\n // hover-only on desktop; always show them on mobile touch.\n '[class*=\"_sidebarCol\"] [class*=\"_projectRow\"] [class*=\"_rowActions\"]{display:inline-flex}',\n // v78: mobile long-press on a row must not start native drag.\n '[class*=\"_sidebarCol\"] [class*=\"_sessionRow\"],[class*=\"_sidebarCol\"] [class*=\"_projectRow\"]{-webkit-user-drag:none;user-select:none}',\n // Hide the header Session-log download button (no space on phones).\n '[class$=\"_headerUtilities\"]{display:none}',\n // v52 composer: the two lines (permission / model) stay stacked with zero\n // row gap; the command, context-meter and send/stop buttons float at the\n // left/right edges vertically centered over both lines.\n '[class$=\"_composerSeat\"] [class$=\"_card\"]{margin-bottom:1px}',\n '[class$=\"_composerSeat\"] [class$=\"_row\"]{flex-wrap:wrap;row-gap:0;padding:2px 8px 1px;position:relative}',\n '[class$=\"_composerSeat\"] [class$=\"_add\"]{position:absolute;left:8px;top:50%;transform:translateY(-50%)}',\n '[class$=\"_composerSeat\"] [class$=\"_modes\"]{min-width:0;padding-left:38px}',\n // Model line left-aligned with the permission line (same command-button\n // clearance), rows stay tightly stacked.\n '[class$=\"_composerSeat\"] [class$=\"_trailing\"]{flex-basis:100%;position:relative;min-height:32px;justify-content:flex-start;padding-left:38px;padding-right:78px}',\n '[class$=\"_composerSeat\"] [class$=\"_trailing\"] *{font-size:12px}',\n // v54: smaller permission/model buttons (font + height). v79: the\n // permission trigger collapses to its shield icon on phones — the label\n // text is the first thing a narrow row drops (the icon color carries the\n // state), matching the dsh-LAN compact composer.\n '[class$=\"_composerSeat\"] [class$=\"_modes\"] [class$=\"_trigger\"]{height:24px;min-height:24px;font-size:12px}',\n '[class$=\"_composerSeat\"] [class$=\"_trailing\"] [class$=\"_trigger\"]{height:24px;min-height:24px;font-size:11px}',\n // Context meter + send/stop float at the right edge, vertically centered\n // over both lines (the meter's root contains the track).\n '[class$=\"_composerSeat\"] [class$=\"_trailing\"] > [class$=\"_root\"]:has([class$=\"_track\"]){position:absolute;right:52px;top:50%;transform:translateY(-50%)}',\n '[class$=\"_composerSeat\"] [class$=\"_primary\"]{position:absolute;right:8px;top:50%;transform:translateY(-50%)}',\n // v79: the model picker menu anchors right:0 to its narrow trigger, so on\n // a phone both the picker menu and the model list fly past the left\n // viewport edge (model names unreadably cut). Turn the picker into a\n // bottom sheet: the composer seat carries an identity transform, which\n // would still become the containing block for fixed children, so free it\n // first; then pin every seat menu to the viewport bottom with real touch\n // targets. Covers the picker, the model list, and the other composer\n // popovers (permission presets, attachments) alike.\n '[class$=\"_composerSeat\"]{transform:none !important}',\n '[class$=\"_composerSeat\"] [class$=\"_menu\"]{position:fixed !important;left:8px !important;right:8px !important;top:auto !important;bottom:calc(8px + env(safe-area-inset-bottom)) !important;width:auto !important;max-width:none !important;max-height:70dvh !important;overflow-y:auto !important;z-index:2147482000}',\n '[class$=\"_composerSeat\"] [class$=\"_menu\"] [class$=\"_cell\"]{height:44px;min-height:44px;font-size:13px}',\n // v79 (compact picker): when the row is too narrow for the desktop text\n // triggers, the phone falls back to icon entries — the context ring stays\n // official, and two synthesized buttons open the picker sheet straight on\n // the model list and the effort list (drill-through, so one tap lands on\n // the same list the user's mock shows). The original text trigger hides\n // only while the wired buttons exist (body class): a failed wiring\n // degrades back to the usable text trigger instead of no picker.\n `body.${COMPACT_CLASS} [class$=\"_composerSeat\"] [class$=\"_trailing\"] [class$=\"_trigger\"]:has([class$=\"_triggerEffort\"]){display:none}`,\n // The icon buttons sit inline in the tools row (parallel to the\n // permission trigger), so the trailing line collapses to zero and the\n // context ring + send re-anchor to the row itself. The ring shifts a\n // few px right: at its desktop offset its hit box kisses the effort\n // button.\n `body.${COMPACT_CLASS} [class$=\"_composerSeat\"] [class$=\"_trailing\"]{flex-basis:auto;position:static;min-height:0;padding:0;width:0}`,\n `body.${COMPACT_CLASS} [class$=\"_composerSeat\"] [class$=\"_trailing\"] > [class$=\"_root\"]:has([class$=\"_track\"]){right:44px}`,\n `#${MODEL_BTN_ID},#${EFFORT_BTN_ID}{width:26px;height:32px;min-width:26px;padding:0;border-radius:9px;background:var(--dsw-alias-bg-module-platform);border:1px solid var(--dsw-alias-border-l2);color:var(--dsw-alias-label-primary);display:flex;align-items:center;justify-content:center;cursor:pointer;flex:none;margin-left:4px}`,\n\n\n `#${MODEL_BTN_ID} svg,#${EFFORT_BTN_ID} svg{width:16px;height:16px;display:block}`,\n `#${MODEL_BTN_ID}:active,#${EFFORT_BTN_ID}:active{opacity:.7}`,\n // Bottom stats line (N rounds / M steps) two sizes below the tabs; v55\n // wraps freely but clamps at two lines (the official rule is nowrap +\n // single-line ellipsis); v60 drops the official 32px right padding.\n '[class$=\"_composerSeat\"] [data-slot=\"conversation.composer.dock\"] [class$=\"_root\"]{font-size:10px;white-space:normal;word-break:break-word;overflow-wrap:anywhere;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden;text-align:left;line-height:13px;letter-spacing:-0.2px;padding-left:0;padding-right:0}',\n // (user bubbles keep the v50 14.5px via the _bubble rule.)\n '[class$=\"_scrollBody\"] [class$=\"_root\"]{font-size:13px}',\n // v58/v65 port note: the dsh-LAN `_body` gap:6px compaction is deliberately\n // NOT ported. The official message row is a shrinkable flex column whose\n // bottom-anchored body then measures shorter than its text (13px root font\n // on a fixed 24px line box), and the extra gap pushed the first text line\n // above the row box — every assistant message clipped its top half on the\n // phone (verified on the real GUI; the removal restores natural heights).\n // v58/v65: on touch, taps leave :hover/:focus stuck, so official Tooltip\n // bubbles stay visible on mobile. The bubble class hash sits AFTER the\n // name, so match by containment, still scoped by role=tooltip so user\n // message bubbles (no tooltip role) stay visible.\n '[class*=\"_bubble\"][role=\"tooltip\"]{display:none}',\n // v65: PlanReviewPanel shares the _frame/_card suffixes and overflows a\n // narrow phone; pin it to the viewport with border-box and cap its height\n // so the card sits fully on screen.\n '[class$=\"_composerSeat\"] [class$=\"_frame\"]{box-sizing:border-box;width:100%;max-width:100%;padding-left:12px;padding-right:12px;height:auto;max-height:calc(100dvh - 96px);align-items:flex-start;overflow-y:auto}',\n '[class$=\"_composerSeat\"] [class$=\"_frame\"] [class$=\"_card\"]{max-width:none;width:100%}',\n // v67: header actions (agent-preset mode label + background-task badge)\n // are re-seated from the title row into the tabs row; hidden in the\n // original spot so React re-renders do not flicker them back.\n // Only while the layer has taken the actions over: out of flow (so the\n // title row keeps its own layout and React keeps owning the node) and\n // painted over the tabs row by the transform alignActionsText computes.\n `body.${HEADER_SEATED_CLASS} [class$=\"_header\"] [class$=\"_titleCluster\"] [class$=\"_headerActions\"]{position:absolute;left:0;top:0;margin:0;display:flex;align-items:center;gap:6px;flex:none;z-index:2}`,\n // v70: match the tab text size with the seated mode label (12px); NB\n // [class$=\"_tab\"] misses the active tab (its class ends in \"_tabActive\")\n // — containment so BOTH tabs match.\n '[class$=\"_header\"] [class$=\"_tabs\"] [class*=\"_tab\"]{font-size:12px;white-space:nowrap}',\n // Mobile scope: hide the plugin surfaces that do not fit a phone — the\n // right-hand details column and every desktop-oriented tool surface. The\n // list keys on the L2 semantic roots (data-dsh-plugin, ownership stays\n // with the declaring plugin), so official class churn cannot resurrect\n // them. These are render suppressions: the client bundles still load.\n // The pet is part of the hidden set by design: the mobile remote mirror\n // carries the desktop-less phone surface, and a floating pet would only\n // cover the small viewport. The suppression is the requirement, not a bug.\n `body.${ACTIVE_CLASS} [class$=\\\"_detailsCol\\\"]{display:none !important}`,\n `body.${ACTIVE_CLASS} [data-dsh-plugin=\\\"ssh\\\"],`,\n `body.${ACTIVE_CLASS} [data-dsh-plugin=\\\"skill-explorer\\\"],`,\n `body.${ACTIVE_CLASS} [data-dsh-plugin=\\\"task-board\\\"],`,\n `body.${ACTIVE_CLASS} [data-dsh-plugin=\\\"git-graph\\\"],`,\n `body.${ACTIVE_CLASS} [data-dsh-plugin=\\\"pet\\\"],`,\n `body.${ACTIVE_CLASS} [data-dsh-plugin=\\\"usage\\\"]{display:none !important}`,\n // The official workbench (Files / source control) mounts into a\n // full-viewport portal layer with no data-dsh-plugin root, so the plugin\n // list above cannot key on it; its open state persists across page loads,\n // and on a phone it covers the entire conversation with no visible close\n // control — the remote-opens-to-an-empty-screen report. Hide the\n // workbench panel only: the same portal layer also hosts the settings\n // modal, which must stay reachable (verified in the GUI QA round).\n `body.${ACTIVE_CLASS} [class$=\\\"_overlayLayer\\\"] [class$=\\\"_workbench\\\"]{display:none !important}`,\n // v68: settings modal on mobile — the official panel is a fixed 800px\n // two-column layout (nav + content); switch to a column layout: the\n // section nav becomes a horizontal scrollable row on top.\n '[class$=\"_overlay\"] [class$=\"_panel\"]{flex-direction:column;max-height:calc(100dvh - 32px)}',\n '[class$=\"_overlay\"] [class$=\"_panel\"] [class$=\"_nav\"]{flex-direction:row;gap:4px;width:100%;padding:12px 12px 0;overflow-x:auto;overflow-y:hidden}',\n '[class$=\"_overlay\"] [class$=\"_panel\"] [class$=\"_navTitle\"]{display:none}',\n '[class$=\"_overlay\"] [class$=\"_panel\"] [class$=\"_navList\"]{flex-direction:row;gap:4px}',\n '[class$=\"_overlay\"] [class$=\"_panel\"] [class$=\"_navCell\"]{height:34px;padding:0 12px;gap:6px;flex:none;border-radius:10px}',\n '[class$=\"_overlay\"] [class$=\"_panel\"] [class$=\"_navLabel\"]{font-size:13px}',\n '[class$=\"_overlay\"] [class$=\"_panel\"] [class$=\"_content\"]{flex:1;min-height:0}',\n]\n\n/** Cube glyph for the compact model button (a plain box outline). */\nconst CUBE_ICON = '<path d=\"M21 8a2 2 0 0 0-1-1.73l-7-4a2 2 0 0 0-2 0l-7 4A2 2 0 0 0 3 8v8a2 2 0 0 0 1 1.73l7 4a2 2 0 0 0 2 0l7-4A2 2 0 0 0 21 16Z\"/><path d=\"m3.3 7 8.7 5 8.7-5\"/><path d=\"M12 22V12\"/>'\n/** Level glyph for the compact effort button (three rising bars). */\nconst LEVELS_ICON = '<path d=\"M4 6h16\"/><path d=\"M7 12h10\"/><path d=\"M10 18h4\"/>'\n\n/** The DeepSeek fish glyph (the official brand mark path). */\nconst FISH_PATH = 'M22.9168 1.43018C22.6713 1.31018 22.5658 1.53918 22.4223 1.65519C22.3733 1.69269 22.3318 1.74169 22.2903 1.78669C21.9317 2.1697 21.5127 2.42121 20.9657 2.39121C20.1657 2.34621 19.4827 2.59771 18.8787 3.20973C18.7502 2.45521 18.3236 2.0047 17.6746 1.71569C17.3351 1.56568 16.9916 1.41518 16.7536 1.08867C16.5876 0.856163 16.5421 0.597155 16.4591 0.341647C16.4061 0.187643 16.3536 0.0301382 16.1761 0.00363739C15.9836 -0.0263635 15.9081 0.135141 15.8326 0.270145C15.5306 0.822162 15.4136 1.43018 15.4251 2.0462C15.4516 3.43174 16.0366 4.53527 17.1991 5.3203C17.3311 5.4103 17.3651 5.5003 17.3236 5.63181C17.2441 5.90231 17.1501 6.16482 17.0671 6.43533C17.0141 6.60784 16.9351 6.64584 16.7501 6.57033C16.1121 6.30383 15.5611 5.90931 15.074 5.4328C14.2475 4.63328 13.5 3.75075 12.568 3.05973C12.349 2.89822 12.13 2.74822 11.9034 2.60522C10.9524 1.68169 12.028 0.923165 12.277 0.833162C12.5375 0.739159 12.3675 0.41615 11.5259 0.42015C10.6844 0.42365 9.91439 0.705658 8.93286 1.08117C8.78935 1.13767 8.63835 1.17867 8.48384 1.21267C7.59332 1.04367 6.66829 1.00617 5.70226 1.11517C3.88321 1.31768 2.43016 2.1777 1.36213 3.64575C0.0790928 5.4103 -0.222916 7.41536 0.146595 9.50642C0.535106 11.7105 1.66014 13.535 3.38869 14.9616C5.18125 16.4406 7.24581 17.1657 9.60138 17.0266C11.0319 16.9441 12.6245 16.7526 14.421 15.2321C14.874 15.4576 15.3496 15.5476 16.1381 15.6151C16.7456 15.6716 17.3306 15.5851 17.7836 15.4911C18.4931 15.3411 18.4441 14.6841 18.1876 14.5636C16.1081 13.595 16.5646 13.9891 16.1496 13.67C17.2061 12.42 18.8202 10.1979 19.3182 7.17235C19.3672 6.83834 19.4297 6.36783 19.4222 6.09732C19.4182 5.93231 19.4562 5.86831 19.6447 5.84931C20.1657 5.78931 20.6712 5.64681 21.1357 5.3913C22.4833 4.65528 23.0268 3.44624 23.1548 1.9972C23.1738 1.77569 23.1508 1.54668 22.9168 1.43018Z'\n\n/**\n * Install the adaptation layer. Runs once per page (idempotent); the\n * evaluate loop re-applies on orientation/resize and reverts off-portrait.\n */\nexport function startMobileAdapt(): void {\n if (typeof window === 'undefined' || typeof document === 'undefined') return\n if ((window as unknown as { __dshRemoteAdaptInstalled?: boolean }).__dshRemoteAdaptInstalled === true) return\n ;(window as unknown as { __dshRemoteAdaptInstalled?: boolean }).__dshRemoteAdaptInstalled = true\n\n const w = window as unknown as { __dshRemoteAdapt?: RemoteAdaptGlobal } & Record<string, unknown>\n /**\n * Label lookup for the injected surfaces: the `remote` namespace seat wired\n * by the plugin apply, else the English fallback (the SDK's universal\n * fallback; the sync tick re-renders the labels once the seat is live).\n */\n const surfaceText = (key: RemoteKey, fallback: string): string => {\n try {\n const out = w.__dshRemoteAdapt?.translate?.(key)\n return typeof out === 'string' && out.length > 0 ? out : fallback\n } catch {\n return fallback\n }\n }\n let active = false\n let savedViewportContent: string | null = null\n let whaleEl: HTMLButtonElement | null = null\n let whaleObserver: MutationObserver | null = null\n /** Header subtree observer: marks the geometry measurement dirty on re-render. */\n let headerObserver: MutationObserver | null = null\n let observedHeader: Element | null = null\n /** Whether the seated-actions geometry needs re-measuring (see alignActionsText). */\n let headerGeometryDirty = true\n let whaleTimer: number | null = null\n let whaleSuppressClick = false\n let whaleShown = false\n let drag: { x: number; y: number; left: number; top: number; moved: boolean } | null = null\n let swipeTouch: { x: number; y: number; id: number } | null = null\n let lastComposerTap = 0\n // Plugin master switch: the module-scope layer installs before any config\n // is readable, so the plugin apply() flips this through setEnabled() once\n // the settings snapshot settles (disabled plugin = no injected surface).\n let adaptEnabled = true\n\n /**\n * Idempotently (re-)install the adaptation stylesheet. The rules live in\n * one <style> tag keyed by data-plugin-css; the sync tick re-runs this so\n * a tag lost to any external DOM cleanup is restored within one tick\n * instead of silently dropping the suppressions (portrait pet hiding,\n * rail compaction) while the body class stays.\n */\n function ensureAdaptStyle(): void {\n if (document.querySelector(`style[data-plugin-css=\"${ADAPT_CSS_ID}\"]`) !== null) return\n const tag = document.createElement('style')\n tag.dataset.plugin = 'remote-web-ui'\n tag.dataset.pluginCss = ADAPT_CSS_ID\n tag.textContent = ADAPT_CSS.join('')\n document.head.appendChild(tag)\n }\n\n function apply(): void {\n if (active) return\n active = true\n document.body.classList.add(ACTIVE_CLASS)\n // A details panel opened before the viewport rotated into portrait (or\n // restored across reloads) would sit behind the display:none above;\n // closing it through the official face unmounts the surface entirely.\n // The layout face throws by design when the root entry has not mounted\n // yet (boot-order), which is a tolerated no-op here — the plugin apply\n // replays it through flushCloseDetails once the wiring is live.\n try {\n w.__dshRemoteAdapt?.closeDetails?.()\n } catch {}\n ensureAdaptStyle()\n // viewport-fit=cover enables env(safe-area-inset-*); restore on revert.\n const meta = document.querySelector('meta[name=viewport]')\n if (meta instanceof HTMLMetaElement && meta.getAttribute('content') !== null && !(meta.getAttribute('content') ?? '').includes('viewport-fit')) {\n savedViewportContent = meta.getAttribute('content')\n meta.setAttribute('content', `${savedViewportContent}, viewport-fit=cover`)\n }\n ensureWhale()\n syncWhale()\n // React builds nodes with attributes before inserting them, so\n // attribute observers miss the initial collapsed state — a light\n // interval is the reliable sync.\n setWhaleTimer(true)\n seatHeaderActions()\n }\n\n function revert(): void {\n if (!active) return\n active = false\n unseatHeaderActions()\n restoreRowDrag()\n removeCompactPicker()\n document.body.classList.remove(ACTIVE_CLASS)\n document.body.classList.remove(RAIL_HIDDEN_CLASS)\n const tag = document.querySelector(`style[data-plugin-css=\"${ADAPT_CSS_ID}\"]`)\n tag?.remove()\n const meta = document.querySelector('meta[name=viewport]')\n if (meta instanceof HTMLMetaElement && savedViewportContent !== null) {\n meta.setAttribute('content', savedViewportContent)\n savedViewportContent = null\n }\n if (whaleEl !== null) whaleEl.style.display = 'none'\n setWhaleTimer(false)\n if (whaleObserver !== null) {\n whaleObserver.disconnect()\n whaleObserver = null\n }\n }\n\n /** Start/stop the 600ms sync tick; a no-op when already in the asked state. */\n function setWhaleTimer(on: boolean): void {\n if (on && whaleTimer === null && active) {\n whaleTimer = window.setInterval(syncWhale, 600)\n } else if (!on && whaleTimer !== null) {\n window.clearInterval(whaleTimer)\n whaleTimer = null\n }\n }\n\n /**\n * Compact picker (v79): a phone row cannot fit the desktop text triggers,\n * so the model/effort entries become two icon buttons in the trailing\n * row. Both forward to the official picker trigger (its menu renders as\n * the bottom sheet) and then drill straight into the asked cell — model\n * list or effort list — so one tap lands on the list, matching the\n * cube-model / brain-effort mapping. The official context ring next to\n * the send button keeps its own semantics untouched.\n */\n function removeCompactPicker(): void {\n document.body.classList.remove(COMPACT_CLASS)\n document.getElementById(MODEL_BTN_ID)?.remove()\n document.getElementById(EFFORT_BTN_ID)?.remove()\n }\n\n function drillIntoPicker(kind: PickerKind): void {\n const trigger = document.querySelector('[class$=\"_composerSeat\"] [class$=\"_trailing\"] [class$=\"_trigger\"]:has([class$=\"_triggerEffort\"])') as HTMLElement | null\n if (trigger === null) return\n trigger.click()\n // The sheet mount takes a beat (observed ~0.2-0.6s on a cold phone\n // mirror); poll until the asked cell exists instead of a fixed delay.\n let tries = 0\n const tapCell = (): void => {\n tries += 1\n const cells = Array.from(document.querySelectorAll('[class$=\"_composerSeat\"] [class$=\"_menu\"] [class$=\"_cell\"]'))\n // The official cell copy is localized (zh/en/ru), so the label match is\n // only the fast path; the sheet's drill cells (label + value + chevron)\n // are the structural anchor: model first, effort second, on every locale.\n const byLabel = cells.find((c) => PICKER_CELL_PATTERN[kind].test(c.textContent ?? ''))\n const drillable = cells.filter((c) => c.querySelector('[class*=\"_cellChevron\"], [class*=\"_chevron\"]'))\n const cell = byLabel ?? drillable[DRILL_INDEX[kind]]\n if (cell !== undefined) {\n ;(cell as HTMLElement).click()\n return\n }\n if (tries < 8) window.setTimeout(tapCell, 150)\n }\n window.setTimeout(tapCell, 150)\n }\n\n function makeCompactButton(id: string, title: string, icon: string, kind: PickerKind): HTMLButtonElement {\n const btn = document.createElement('button')\n btn.id = id\n btn.type = 'button'\n btn.dataset.dshPlugin = 'remote-web-ui'\n btn.title = title\n btn.setAttribute('aria-label', title)\n btn.innerHTML = `<svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\">${icon}</svg>`\n btn.addEventListener('click', () => { drillIntoPicker(kind) })\n return btn\n }\n\n function syncCompactPicker(): void {\n if (!active) return\n const tools = document.querySelector('[class$=\"_composerSeat\"] [class$=\"_tools\"]')\n const trigger = tools?.parentElement?.querySelector('[class$=\"_triggerEffort\"]')?.parentElement\n if (tools === null || trigger === null) {\n removeCompactPicker()\n return\n }\n if (document.getElementById(MODEL_BTN_ID) === null) {\n // The cell pattern matches the OFFICIAL picker cell text (the official\n // client's own zh/en copy), not plugin-owned text.\n tools.appendChild(makeCompactButton(MODEL_BTN_ID, surfaceText('mobile.composer.pickModel', 'Pick model'), CUBE_ICON, 'model'))\n }\n if (document.getElementById(EFFORT_BTN_ID) === null) {\n tools.appendChild(makeCompactButton(EFFORT_BTN_ID, surfaceText('mobile.composer.pickEffort', 'Pick reasoning effort'), LEVELS_ICON, 'effort'))\n }\n // Titles re-read every tick so a locale switch (or the translate seat\n // arriving after this layer installed) is picked up without a reload.\n for (const [id, key, fallback] of [\n [MODEL_BTN_ID, 'mobile.composer.pickModel', 'Pick model'],\n [EFFORT_BTN_ID, 'mobile.composer.pickEffort', 'Pick reasoning effort'],\n ] as const) {\n const btn = document.getElementById(id)\n if (btn === null) continue\n const label = surfaceText(key, fallback)\n btn.title = label\n btn.setAttribute('aria-label', label)\n }\n document.body.classList.add(COMPACT_CLASS)\n }\n /**\n * The official sidebar toggle in the logo row. The row's own `_toggle` class\n * is the precise anchor; the row's last button is the fallback for cohorts\n * that only expose the generic icon-button class (the first button is the\n * brand, which navigates home — never click that one). `_railFish` is kept\n * for older compositions that carried a rail fish button.\n */\n function officialSidebarToggle(): HTMLElement | null {\n const rail = document.querySelector('[class$=\"_railFish\"] button')\n if (rail instanceof HTMLElement) return rail\n const row = document.querySelector('[class$=\"_logoRow\"]')\n if (row === null) return null\n const toggles = row.querySelectorAll('button[class*=\"_toggle\"]')\n const last = toggles.length > 0 ? toggles[toggles.length - 1] : row.querySelectorAll('button')[row.querySelectorAll('button').length - 1]\n return last instanceof HTMLElement ? last : null\n }\n /**\n * Toggle the sidebar through the official rail/logo toggle first, then\n * verify the flip and fall back to the wired layout face.\n *\n * The order is evidence-driven: the official toggle owns its own store\n * actions and flips the state on every cohort we support, while the wired\n * LayoutController is mounted yet inert on the installed cohort — calling it\n * left `data-sidebar-collapsed` untouched for the whole 800ms observation\n * window, so face-first made every whale tap wait out the verification\n * delay before anything moved. The face stays the fallback for compositions\n * that render no logo-row toggle, and it is only called after the toggle\n * demonstrably failed, so the two can never cancel each other out.\n */\n function toggleSidebarVerified(): void {\n const frame = appFrame()\n const collapsedBefore = frame !== null ? frame.hasAttribute('data-sidebar-collapsed') : null\n const face = w.__dshRemoteAdapt?.toggleSidebar\n const callFace = (): void => {\n if (typeof face !== 'function') return\n try { face() } catch {}\n }\n const toggle = officialSidebarToggle()\n if (collapsedBefore === null || toggle === null) {\n // No frame to verify against, or no official toggle: the face is the\n // only available control.\n if (toggle !== null) toggle.click()\n else callFace()\n return\n }\n toggle.click()\n let tries = 0\n const verify = (): void => {\n if (!active) return\n const frameNow = appFrame()\n if (frameNow === null) return\n if (frameNow.hasAttribute('data-sidebar-collapsed') !== collapsedBefore) return\n tries += 1\n if (tries < 2) {\n window.setTimeout(verify, 120)\n return\n }\n callFace()\n }\n window.setTimeout(verify, 120)\n }\n function ensureWhale(): void {\n if (whaleEl !== null || !document.body) return\n const whale = document.createElement('button')\n whale.id = WHALE_ID\n whale.type = 'button'\n whale.dataset.dshPlugin = 'remote-web-ui'\n // The label reads the `remote` namespace (wired by the plugin apply);\n // before wiring it falls back to English and the sync tick re-renders it.\n const whaleLabel = surfaceText('mobile.whale.open', 'Open sidebar')\n whale.title = whaleLabel\n whale.setAttribute('aria-label', whaleLabel)\n whale.innerHTML = `<svg viewBox=\"0 0 23.16 17.04\" fill=\"none\" aria-hidden=\"true\"><path d=\"${FISH_PATH}\" fill=\"currentColor\"/></svg>`\n whale.addEventListener('click', () => {\n if (whaleSuppressClick) {\n whaleSuppressClick = false\n return\n }\n toggleSidebarVerified()\n })\n // v51: the whale floats — pointer-drag repositions it (persisted).\n whale.addEventListener('pointerdown', (e) => {\n if (whaleEl === null) return\n if (e.button !== 0 && e.pointerType === 'mouse') return\n // v61: opening the sidebar must not leave a focused composer input\n // behind — on phones a still-focused input makes the first tap re-pop\n // the keyboard (iOS) or keeps it open. Blur at pointerdown (before the\n // tap completes; click is too late for iOS) and block pending\n // programmatic refocus.\n if (active && isComposerField(document.activeElement)) {\n // The composer field is a contenteditable div (the official client\n // renders no textarea), so the old textarea/input lookup never matched\n // it while a bare `input` branch could blur an unrelated field.\n document.activeElement.blur()\n lastComposerTap = 0\n }\n drag = { x: e.clientX, y: e.clientY, left: whale.offsetLeft, top: whale.offsetTop, moved: false }\n try { whale.setPointerCapture(e.pointerId) } catch {}\n e.preventDefault()\n e.stopPropagation()\n })\n whale.addEventListener('pointermove', (e) => {\n if (whaleEl === null || drag === null) return\n const dx = e.clientX - drag.x\n const dy = e.clientY - drag.y\n drag.moved = drag.moved || Math.abs(dx) > 3 || Math.abs(dy) > 3\n whaleEl.style.left = `${Math.min(Math.max(4, drag.left + dx), window.innerWidth - 38)}px`\n whaleEl.style.top = `${Math.min(Math.max(4, drag.top + dy), window.innerHeight - 38)}px`\n e.preventDefault()\n e.stopPropagation()\n })\n const endWhaleDrag = (): void => {\n if (whaleEl === null || drag === null) return\n const moved = drag.moved\n drag = null\n whaleSuppressClick = moved\n try {\n window.localStorage.setItem(WHALE_POS_KEY, JSON.stringify({ x: whaleEl.offsetLeft, y: whaleEl.offsetTop }))\n } catch {}\n }\n whale.addEventListener('pointerup', endWhaleDrag)\n // A cancelled pointer (system gesture, incoming call) is not a drag end:\n // keep the click un-suppressed so the next real tap still toggles.\n whale.addEventListener('pointercancel', () => {\n drag = null\n whaleSuppressClick = false\n })\n whaleEl = whale\n document.body.appendChild(whale)\n }\n\n /**\n * Restore the official draggable state this layer overrode while active.\n * Rows are React-owned and may have been re-created meanwhile, so only the\n * tracked elements are touched; a detached element is skipped.\n */\n function restoreRowDrag(): void {\n if (dragOverridden.size === 0) return\n for (const [row, original] of dragOverridden) {\n if (!row.isConnected) continue\n if (original === null) row.removeAttribute('draggable')\n else row.setAttribute('draggable', original)\n }\n dragOverridden.clear()\n }\n\n /** Restore a dragged position when the whale becomes visible again. */\n function applyWhalePos(): void {\n if (whaleEl === null) return\n let pos: { x?: unknown; y?: unknown } | null = null\n try {\n pos = JSON.parse(window.localStorage.getItem(WHALE_POS_KEY) ?? 'null') as { x?: unknown; y?: unknown } | null\n } catch {}\n if (pos !== null && typeof pos.x === 'number' && typeof pos.y === 'number') {\n // Clamp to the current viewport: a position saved on a larger screen\n // (resize, split-screen, rotation) must not park the whale — the only\n // portrait sidebar entry — out of reach.\n const x = Math.min(Math.max(4, pos.x), window.innerWidth - 38)\n const y = Math.min(Math.max(4, pos.y), window.innerHeight - 38)\n whaleEl.style.left = `${x}px`\n whaleEl.style.top = `${y}px`\n }\n }\n\n // v78: on touch, official session/project rows are draggable for\n // reordering; a long-press would start native drag instead of our action\n // menu. Force them non-draggable while the adapt is active (React may\n // re-create rows, so re-apply on the sync tick).\n /** Rows whose official draggable state this layer overrode (restored on revert). */\n const dragOverridden = new Map<Element, string | null>()\n function disableRowDrag(): void {\n if (!active) return\n const rows = document.querySelectorAll('[class*=\"_sidebarCol\"] [class*=\"_sessionRow\"], [class*=\"_sidebarCol\"] [class*=\"_projectRow\"]')\n for (const row of rows) {\n if (row.getAttribute('draggable') !== 'false') {\n if (!dragOverridden.has(row)) dragOverridden.set(row, row.getAttribute('draggable'))\n row.setAttribute('draggable', 'false')\n }\n }\n }\n\n function syncWhale(): void {\n // Keep the stylesheet present while the layer is active (the tick runs\n // every 600ms; see ensureAdaptStyle for why the tag can need a re-assert).\n if (active) ensureAdaptStyle()\n if (whaleEl === null) return\n if (!active) {\n whaleEl.style.display = 'none'\n return\n }\n const collapsed = appFrame()?.hasAttribute('data-sidebar-collapsed') === true\n const overlayUp = document.querySelector('[class$=\"_overlay\"]') !== null\n const show = collapsed && !overlayUp\n // Restore on every hidden-to-shown transition — including the very\n // first show on a fresh page load, where the inline display is still\n // '' and a CSS-read guard would never fire.\n if (show && !whaleShown) applyWhalePos()\n whaleEl.style.display = show ? '' : 'none'\n whaleShown = show\n // Re-read the label every tick so a locale switch is picked up live.\n const whaleLabel = surfaceText('mobile.whale.open', 'Open sidebar')\n if (whaleEl.title !== whaleLabel) whaleEl.title = whaleLabel\n if (whaleEl.getAttribute('aria-label') !== whaleLabel) whaleEl.setAttribute('aria-label', whaleLabel)\n document.body.classList.toggle(RAIL_HIDDEN_CLASS, collapsed)\n disableRowDrag()\n seatHeaderActions()\n alignActionsText()\n syncCompactPicker()\n }\n\n // v67: on mobile the header actions (agent-preset mode label + background\n // task badge) move from the title row into the tabs row. React re-creates\n // the node in its original spot on re-render, so the interval re-seats it;\n // stale seated copies are removed first. The original spot is only hidden\n // while a seat actually exists: the tabs row renders only for multi-tab\n // sessions, and hiding the actions without a seat target made them vanish.\n function seatHeaderActions(): void {\n if (!active) return\n const header = document.querySelector('[class$=\"_header\"]')\n const tabs = header !== null ? header.querySelector('[class$=\"_tabs\"]') : null\n const actions = header !== null ? header.querySelector('[class$=\"_titleCluster\"] [class$=\"_headerActions\"]') : null\n // The actions node is NOT moved: it is a React-owned host node whose badge\n // button carries live handlers, and re-parenting it makes React's later\n // insertBefore/removeChild anchors point at a node that is no longer a\n // child of the recorded parent (a NotFoundError in the commit phase). The\n // injected CSS takes it out of flow and the transform below paints it over\n // the tabs row instead.\n const seated = header !== null && tabs !== null && actions !== null\n document.body.classList.toggle(HEADER_SEATED_CLASS, seated)\n ensureHeaderObserver(seated ? header : null)\n }\n\n // Paint the mode/badge over the tabs row: the actions keep their DOM slot in\n // the title cluster (out of flow via CSS) and are moved with a transform, so\n // the tabs row reserves room with padding instead of the node being moved.\n // The tabs row height is not stable (a background task badge grows it) and\n // the official right padding differs per cohort, so both axes are measured\n // and converged each time the header geometry is dirty.\n function alignActionsText(): void {\n if (!active) return\n const header = document.querySelector('[class$=\"_header\"]')\n if (header === null) return\n const tabs = header.querySelector('[class$=\"_tabs\"]')\n const actions = header.querySelector('[class$=\"_titleCluster\"] [class$=\"_headerActions\"]')\n if (tabs === null || actions === null || !(tabs instanceof HTMLElement) || !(actions instanceof HTMLElement)) return\n if (!headerGeometryDirty) return\n headerGeometryDirty = false\n const tabBtn = tabs.querySelector(':scope > [class*=\"_tab\"]')\n const textBottom = (el: Element | null): number | null => {\n if (el === null) return null\n const text = Array.from(el.childNodes).find((n) => n.nodeType === 3 && n.textContent !== null && n.textContent.trim() !== '')\n if (text === undefined) return null\n try {\n const range = document.createRange()\n range.selectNode(text)\n return range.getBoundingClientRect().bottom\n } catch {\n return null\n }\n }\n const translate = /translate\\((-?[\\d.]+)px,\\s*(-?[\\d.]+)px\\)/.exec(actions.style.transform ?? '')\n let dx = translate !== null ? parseFloat(translate[1] ?? '0') : 0\n let dy = translate !== null ? parseFloat(translate[2] ?? '0') : 0\n const actionsRect = actions.getBoundingClientRect()\n const tabsRect = tabs.getBoundingClientRect()\n // Horizontal: the actions' right edge lands on the tabs row's right edge.\n const rightDiff = tabsRect.right - actionsRect.right\n if (Math.abs(rightDiff) >= 0.5) dx = Math.round((dx + rightDiff) * 10) / 10\n // Vertical: the actions' text bottom lands on the tab text bottom.\n const tabBottom = textBottom(tabBtn)\n if (tabBottom !== null) {\n let maxBottom: number | null = null\n for (const sel of ['[class$=\"_label\"]', '[class$=\"_count\"]']) {\n const b = textBottom(actions.querySelector(sel))\n if (b !== null && (maxBottom === null || b > maxBottom)) maxBottom = b\n }\n if (maxBottom !== null) {\n const bottomDiff = tabBottom - maxBottom\n if (Math.abs(bottomDiff) >= 0.5) dy = Math.round((dy + bottomDiff) * 10) / 10\n }\n }\n const next = `translate(${dx}px, ${dy}px)`\n if (actions.style.transform !== next) actions.style.transform = next\n // Reserve the painted width so the tab labels never slide under it.\n const reserve = `${Math.ceil(actionsRect.width) + 8}px`\n if (tabs.style.paddingRight !== reserve) tabs.style.paddingRight = reserve\n }\n\n function unseatHeaderActions(): void {\n document.body.classList.remove(HEADER_SEATED_CLASS)\n const header = document.querySelector('[class$=\"_header\"]')\n const tabs = header !== null ? header.querySelector('[class$=\"_tabs\"]') : null\n const actions = header !== null ? header.querySelector('[class$=\"_titleCluster\"] [class$=\"_headerActions\"]') : null\n if (actions instanceof HTMLElement) actions.style.transform = ''\n if (tabs instanceof HTMLElement) tabs.style.paddingRight = ''\n if (headerObserver !== null) {\n headerObserver.disconnect()\n headerObserver = null\n observedHeader = null\n }\n }\n\n function ensureWhaleObserver(): void {\n if (whaleObserver !== null || typeof MutationObserver === 'undefined' || !document.body) return\n whaleObserver = new MutationObserver(() => { syncWhale() })\n whaleObserver.observe(document.body, { attributes: true, attributeFilter: ['data-sidebar-collapsed'], subtree: true })\n }\n\n /**\n * Observe the conversation header subtree and mark its geometry dirty on any\n * re-render (label text, badge count, node replacement). The per-tick\n * alignment then reads layout only when the header actually changed instead\n * of on every tick while a message streams. The observer is swapped when the\n * header node is replaced and disconnected with the layer.\n */\n function ensureHeaderObserver(header: Element | null): void {\n if (typeof MutationObserver === 'undefined') return\n if (observedHeader === header && headerObserver !== null) return\n headerObserver?.disconnect()\n headerObserver = null\n observedHeader = null\n if (header === null) return\n headerObserver = new MutationObserver(() => { headerGeometryDirty = true })\n headerObserver.observe(header, { childList: true, subtree: true, characterData: true, attributes: true, attributeFilter: ['class'] })\n observedHeader = header\n headerGeometryDirty = true\n }\n\n function evaluate(): void {\n // A viewport change invalidates every measured position.\n headerGeometryDirty = true\n if (!adaptEnabled) {\n revert()\n return\n }\n if (isMobilePortrait()) {\n apply()\n ensureWhaleObserver()\n } else {\n revert()\n }\n }\n evaluate()\n window.addEventListener('orientationchange', evaluate)\n window.addEventListener('resize', evaluate)\n // The 600ms tick is a page-lifetime wake source; pause it while the page\n // is hidden (backgrounded phone tab) and resume on return.\n document.addEventListener('visibilitychange', () => { setWhaleTimer(document.visibilityState !== 'hidden') })\n\n // v51: Enter only inserts a newline on mobile (send goes through the send\n // button). Captured at document level so the official Enter-to-send\n // handler never sees the event. The rewrite is scoped to the composer:\n // `_input` is also the class of the settings, plugin and agent-preset text\n // fields, where swallowing Enter and inserting a newline into a single-line\n // input left the key dead.\n function onKeydownCapture(e: KeyboardEvent): void {\n if (!active) return\n if (e.key !== 'Enter' || e.shiftKey || e.ctrlKey || e.metaKey || e.altKey) return\n const t = e.target\n if (!(t instanceof HTMLElement)) return\n if (composerFieldOf(t) === null) return\n // keyCode 229 is the classic IME-confirm signal (Safari fires\n // compositionend before the Enter keydown) — never treat it as a\n // plain newline.\n if (e.isComposing || e.keyCode === 229) return\n e.preventDefault()\n e.stopPropagation()\n try { document.execCommand('insertText', false, '\\n') } catch {}\n }\n document.addEventListener('keydown', onKeydownCapture, true)\n\n function collapseSidebar(): void {\n toggleSidebarVerified()\n }\n\n // Auto-collapse the expanded sidebar on mobile: after clicking a session\n // row, or when tapping anywhere outside the sidebar (overlays/dialogs and\n // the whale excluded).\n function onClickCapture(e: MouseEvent): void {\n if (!active) return\n const frame = appFrame()\n if (frame === null || frame.hasAttribute('data-sidebar-collapsed')) return\n const t = e.target\n if (!(t instanceof Element)) return\n if (t.closest('[class*=\"_sidebarCol\"]') !== null) {\n // v68: opening settings also folds the sidebar so the modal closes\n // back into a clean conversation view. Clicks on the session\n // row-actions ellipsis (or its opened menu anchor) must NOT collapse\n // the sidebar — they open the action menu. v76: clicking the top-level\n // New Session also folds. v77: clicking a workspace row's new-session\n // button also folds.\n const topNewSessionClicked = t.closest('[class$=\"_newSession\"], [class$=\"_brand\"]') !== null\n let projectNewSessionClicked = false\n const projectActions = t.closest('[class*=\"_projectRow\"] [class*=\"_rowActions\"]')\n if (projectActions !== null) {\n const btn = t.closest('button')\n const btns = projectActions.querySelectorAll('button')\n projectNewSessionClicked = btn !== null && btns.length > 0 && btn === btns[btns.length - 1]\n }\n let shouldCollapse = false\n if (t.closest('[class*=\"_sessionRow\"]') !== null) {\n shouldCollapse = t.closest('[class*=\"_rowActions\"]') === null\n } else if (t.closest('[class$=\"_settingsArea\"]') !== null || topNewSessionClicked || projectNewSessionClicked) {\n shouldCollapse = true\n }\n if (shouldCollapse) collapseSidebar()\n return\n }\n if (t.closest('[class$=\"_overlay\"], [class$=\"_dialog\"], [class$=\"_menu\"], [class*=\"_portal\"], [id=\"dshRemoteWhale\"], [id=\"dshLanGate\"]') !== null) return\n collapseSidebar()\n }\n document.addEventListener('click', onClickCapture, true)\n\n // v65/v66: swipe gestures. Swiping LEFT while the sidebar is expanded\n // collapses it; swiping RIGHT in the conversation view opens it. Vertical\n // swipes (list scrolling), swipes starting on inputs, on the whale, or\n // inside horizontally scrollable containers are ignored.\n function insideHScrollable(el: Element): boolean {\n let n: Element | null = el\n while (n !== null && n !== document.body) {\n const cs = getComputedStyle(n)\n if ((cs.overflowX === 'auto' || cs.overflowX === 'scroll') && n.scrollWidth > n.clientWidth + 4) return true\n n = n.parentElement\n }\n return false\n }\n document.addEventListener('touchstart', (e) => {\n if (!active) return\n // Multi-finger touches are never a swipe: a pinch that happens to end with\n // >60px of horizontal finger travel would otherwise toggle the sidebar.\n if (e.touches.length > 1) {\n swipeTouch = null\n return\n }\n const t = e.target\n const editable = t instanceof HTMLElement && t.isContentEditable\n if (t instanceof Element && (t.tagName === 'TEXTAREA' || t.tagName === 'INPUT' || editable || t.closest(`#${WHALE_ID}`) !== null || insideHScrollable(t) || t.closest('table, [class$=\"_table\"], [class$=\"_tablePane\"]') !== null)) {\n swipeTouch = null\n return\n }\n const ct = e.changedTouches[0]\n if (ct === undefined) return\n swipeTouch = { x: ct.clientX, y: ct.clientY, id: ct.identifier }\n }, { capture: true, passive: true })\n document.addEventListener('touchend', (e) => {\n if (swipeTouch === null) return\n // Still more than one finger down: a pinch is in progress, not a swipe.\n if (e.touches.length > 0) return\n const ct = e.changedTouches[0]\n if (ct === undefined || ct.identifier !== swipeTouch.id) return\n const dx = ct.clientX - swipeTouch.x\n const dy = ct.clientY - swipeTouch.y\n swipeTouch = null\n if (!active) return\n if (Math.abs(dx) < 60 || Math.abs(dx) < Math.abs(dy) * 1.5) return\n const frame = appFrame()\n if (frame === null) return\n if (document.querySelector('[class$=\"_overlay\"], [class$=\"_dialog\"], [class$=\"_menu\"], [class*=\"_portal\"]') !== null) return\n const collapsed = frame.hasAttribute('data-sidebar-collapsed')\n if (dx < 0 && !collapsed) collapseSidebar()\n else if (dx > 0 && collapsed) toggleSidebarVerified()\n }, { capture: true, passive: true })\n document.addEventListener('touchcancel', () => {\n swipeTouch = null\n }, true)\n\n // Long-press a session row opens the same action menu as the desktop's\n // right-side ellipsis button (rename / fork / archive). On touch the\n // row-actions button is hover-only, so a long press reveals + clicks it.\n const LONG_PRESS_MS = 500\n const LONG_PRESS_MOVE = 10\n let longPress: { row: Element; x: number; y: number; timer: number | null; triggered: boolean } | null = null\n let suppressSessionClickUntil = 0\n let suppressSessionClickRow: Element | null = null\n let longPressMenuGuardUntil = 0\n\n function clearLongPress(): void {\n if (longPress !== null) {\n if (longPress.timer !== null) window.clearTimeout(longPress.timer)\n longPress = null\n }\n }\n\n function openSessionMenu(row: Element): void {\n const actions = row.querySelector('[class*=\"_rowActions\"]')\n const btn = actions?.querySelector('button')\n if (actions === null || btn === null) return\n // The official row hides actions until hover/menuOpen; force the anchor\n // visible just long enough for .click() to be accepted.\n longPressMenuGuardUntil = Date.now() + 1200\n ;(actions as HTMLElement).style.display = 'inline-flex'\n try {\n (btn as HTMLElement).click()\n } finally {\n window.setTimeout(() => { (actions as HTMLElement).style.display = '' }, 50)\n }\n }\n document.addEventListener('touchstart', (e) => {\n if (!active) return\n const t = e.target\n if (!(t instanceof Element)) {\n clearLongPress()\n return\n }\n const row = t.closest('[class*=\"_sessionRow\"]')\n if (row === null || t.closest('[class*=\"_rowActions\"]') !== null) {\n clearLongPress()\n return\n }\n const ct = e.changedTouches[0]\n if (ct === undefined) return\n clearLongPress()\n const lp = { row, x: ct.clientX, y: ct.clientY, timer: null as number | null, triggered: false }\n lp.timer = window.setTimeout(() => {\n if (longPress !== lp) return\n lp.triggered = true\n openSessionMenu(lp.row)\n try { navigator.vibrate?.(10) } catch {}\n }, LONG_PRESS_MS)\n longPress = lp\n }, { capture: true, passive: true })\n document.addEventListener('touchmove', (e) => {\n if (!active || longPress === null) return\n const ct = e.changedTouches[0]\n if (ct === undefined) return\n if (Math.abs(ct.clientX - longPress.x) > LONG_PRESS_MOVE || Math.abs(ct.clientY - longPress.y) > LONG_PRESS_MOVE) {\n clearLongPress()\n }\n }, { capture: true, passive: true })\n document.addEventListener('touchend', (e) => {\n if (!active || longPress === null) return\n const ct = e.changedTouches[0]\n if (ct === undefined) return\n const lp = longPress\n clearLongPress()\n if (lp.triggered) {\n // Stop the finger-lift from also opening the session; the menu is\n // already open and the sidebar should stay put.\n e.preventDefault()\n suppressSessionClickUntil = Date.now() + 800\n suppressSessionClickRow = lp.row\n }\n }, { capture: true, passive: false })\n document.addEventListener('touchcancel', () => {\n clearLongPress()\n }, true)\n // A long press ends with a synthetic click; swallow that one click so it\n // neither opens the conversation nor collapses the sidebar.\n window.addEventListener('click', (e) => {\n if (!active || Date.now() > suppressSessionClickUntil) return\n const t = e.target\n if (t instanceof Element && suppressSessionClickRow !== null && (t === suppressSessionClickRow || suppressSessionClickRow.contains(t))) {\n e.stopPropagation()\n e.preventDefault()\n suppressSessionClickUntil = 0\n suppressSessionClickRow = null\n }\n }, true)\n // Some Android browsers fire a native context menu after a long press.\n document.addEventListener('contextmenu', (e) => {\n if (!active) return\n const t = e.target\n if (!(t instanceof Element)) return\n if (t.closest('[class*=\"_sessionRow\"]') !== null && ((longPress !== null && longPress.triggered) || Date.now() <= suppressSessionClickUntil)) {\n e.preventDefault()\n }\n }, true)\n // Keep the long-press menu open across the finger-lift: the official\n // Menu closes on pointerleave of its root, which fires on touch end.\n document.addEventListener('pointerleave', (e) => {\n if (!active || Date.now() > longPressMenuGuardUntil) return\n const t = e.target\n if (t instanceof Element && (t.closest('[class*=\"_rowActions\"]') !== null || t.closest('[class*=\"_sessionRow\"]') !== null || t.closest('[class*=\"_projectRow\"]') !== null)) {\n e.stopPropagation()\n }\n }, true)\n\n // Intercept programmatic .focus() on the composer field: the official\n // conversation component focuses it on mount and on session changes; user\n // taps focus it through the browser's own pipeline. Only allow composer\n // focus that follows a real tap on the field itself. The composer field is\n // the official contenteditable input root (`data-composer-input`) on this\n // cohort — matching only textarea/input missed it entirely, so every session\n // open popped the phone keyboard. The queue-row editor input is deliberately\n // NOT a composer field: its autoFocus must keep working.\n const isComposerField = (el: Element | null): el is HTMLElement => {\n if (!(el instanceof HTMLElement)) return false\n if (el.closest(COMPOSER_SELECTOR) === null) return false\n if (el.matches('[data-composer-input]')) return true\n if (el.tagName === 'TEXTAREA') return true\n return el.tagName === 'INPUT' && el.matches('[class*=\"_input\"]')\n }\n /** The composer field that owns an event target, if any. */\n const composerFieldOf = (target: EventTarget | null): HTMLElement | null => {\n const el = target instanceof Element ? target.closest('[data-composer-input], [class*=\"_input\"], textarea') : null\n return isComposerField(el) ? el : null\n }\n const lanOrigFocus = HTMLElement.prototype.focus\n HTMLElement.prototype.focus = function (this: HTMLElement, options?: FocusOptions): void {\n if (active && isComposerField(this) && Date.now() - lastComposerTap >= 800) return\n lanOrigFocus.call(this, options)\n }\n document.addEventListener('pointerdown', (e) => {\n if (!active) return\n if (composerFieldOf(e.target) !== null) lastComposerTap = Date.now()\n }, true)\n\n // The plugin apply() wires toggleSidebar/closeDetails to ctx.layout once\n // it is live, and flips the master switch when the settings snapshot\n // settles.\n w.__dshRemoteAdapt = {\n evaluate,\n toggleSidebar: null,\n closeDetails: null,\n translate: null,\n setEnabled(on: boolean): void {\n adaptEnabled = on\n if (on) evaluate()\n else revert()\n },\n flushCloseDetails(): void {\n // The first apply() ran before any wiring existed, so its\n // closeDetails call was a no-op; replay it once the layout face is\n // live so a restored details panel cannot sit hidden-uncloseable.\n if (active) w.__dshRemoteAdapt?.closeDetails?.()\n },\n }\n}\n","/**\n * Remote control — browser half. Registers the `remote` dictionaries, the\n * sidebar-foot entry (phone trigger + pairing panel + update trigger), and\n * the pair boot flow (accept + presence heartbeats) plus the one-time\n * failed-pair notice. The portrait-touch adaptation of the official UI\n * starts under the plugin lifecycle (startMobileAdapt inside apply) and reverts\n * on dispose, so disabled plugin entries stay inert. Export discipline: packages/client/AGENTS.md — the\n * /client surface carries only what cordis loading needs plus types.\n */\nimport { createElement } from 'react'\nimport { createRoot } from 'react-dom/client'\nimport type { Context as ClientContext } from '@deepseek-ai/cordis'\nimport type { SettingsScope, SettingsScopeSpec } from '@deepseek-ai/dsh-client-ui-settings/client'\n// Type-only: pulls the locale plugin's Context merge (ctx.locale) and the\n// ui-sidebar SlotMap merge (the 'sidebar.footer.action' hole).\nimport type {} from '@deepseek-ai/dsh-client-locale/client'\n// Type-only: pulls the settings-surface SlotMap merge (the 'settings.section'\n// entry) and the ctx.settingsScope Context merge.\nimport type {} from '@deepseek-ai/dsh-client-ui-settings/client'\nimport type {} from '@deepseek-ai/dsh-client-ui-sidebar/client'\n// Type-only: pulls the ctx.slots merge (the renderer owns the slot registry since 0.1.2).\nimport type {} from '@deepseek-ai/dsh-client-ui-renderer/client'\nimport type { ConnectionHandle } from '@deepseek-ai/dsh-client-connection/client'\nimport { FooterRemoteEntry } from './FooterRemoteEntry.tsx'\nimport { RemoteEntry } from './RemoteEntry.tsx'\nimport { PairFailedNotice } from './PairFailedNotice.tsx'\nimport { RemoteSettingsCard, RemoteSettingsCardController, type RemoteSettings } from './RemoteSettingsCard.tsx'\nimport { en, zh, type RemoteKey } from './locales.ts'\nimport { PAIR_FAILED_MARKER, runPairBootFlow } from './deep-link.ts'\nimport { readPairGatePolicy, sendHeartbeat } from './pair-api.ts'\nimport {\n channelTransition,\n installRemoteChannel,\n isLoopbackHostname,\n remoteChannelRequired,\n REMOTE_CHANNEL_BOOT_GLOBAL,\n type RemoteChannelBootSeat,\n} from './remote-channel.ts'\nimport { FenceNotice } from './FenceNotice.tsx'\nimport { reportDailyHeartbeat } from './telemetry.ts'\nimport { startMobileAdapt, type RemoteAdaptGlobal } from './mobile-adapt.ts'\n\n// Portrait-touch adaptation of the official UI: installed under the plugin\n// lifecycle (apply) so disabling the plugin in cordis patch (disabled: true)\n// leaves the DOM untouched.\n\nexport type { RemoteEntryProps } from './RemoteEntry.tsx'\nexport type { PanelState, RemotePanelProps } from './RemotePanel.tsx'\nexport type { PairFailedNoticeProps } from './PairFailedNotice.tsx'\nexport type { RemoteKey } from './locales.ts'\nexport type { RemoteSettingsCardFace, RemoteSettingsCardState } from './RemoteSettingsCard.tsx'\nexport type { UpdateEntryProps } from './UpdateEntry.tsx'\nexport type { UpdatePanelProps, UpdateView } from './UpdatePanel.tsx'\n\ndeclare module '@deepseek-ai/dsh-client-ui-slots' {\n interface LocaleNamespaceMap {\n /** Mobile remote-control surface copy. */\n remote: RemoteKey\n }\n\n interface SlotMap {\n /**\n * The sidebar foot seat beside the settings trigger, declared by the\n * sidebar shell on deployments that carry the feature seat; the shell\n * passes only its column display state.\n */\n /**\n * The child slot the Web UI plugin group declares; this card registers\n * into the group instead of the top-level `settings.plugin.item` list.\n * Spelled here with the same shape so this package can register without\n * depending on the sibling UI package.\n */\n 'web-ui.plugin.item': { kind: 'list'; scope: 'root'; owner: SettingsPluginItemOwnerProps }\n }\n}\n\n/** Owner share of the sidebar remote-control seat: the column display state the trigger renders against. */\nexport interface SidebarRemoteOwnerProps {\n /** Whether the sidebar renders wide content (false = 56px rail). */\n wide: boolean\n}\n\n/** Owner share of a plugin card (the section supplies nothing). */\nexport interface SettingsPluginItemOwnerProps {\n /** Marker field: card owner props are intentionally empty. */\n children?: never\n}\n\ndeclare module '@deepseek-ai/cordis' {\n interface Context {\n /**\n * Optional rc.6 compatibility binder provided by dsh-web-settings;\n * absent when that group plugin is not installed, so callers fall back to\n * the official settings scope.\n */\n webUiSettings?: { bind<S>(spec: SettingsScopeSpec<S>): SettingsScope<S> }\n }\n}\n\n\n/** Dictionary namespace owned by this plugin. */\nconst NS = 'remote'\n\n/** Settings namespace the remote-control card edits (the Host plugin registers it). */\nconst REMOTE_WEB_UI_NS = 'remote-web-ui'\n\n/** Heartbeat cadence from a paired phone (presence + revocation liveness). */\nconst HEARTBEAT_INTERVAL_MS = 10_000\n\n/** Services required by this plugin. */\nexport const inject = ['slots', 'locale', 'connection', 'settingsScope', 'remote']\n\n/**\n * Register the remote-control surface.\n * @param ctx - client root context.\n */\nexport function apply(ctx: ClientContext): void {\n // Portrait-touch adaptation of the official UI: installed under the plugin\n // lifecycle so disabling the plugin in cordis patch (disabled: true) never\n // injects mobile CSS, gesture hooks, or the whale floating button.\n startMobileAdapt()\n ctx.effect(() => () => {\n ;(window as unknown as { __dshRemoteAdapt?: RemoteAdaptGlobal }).__dshRemoteAdapt?.setEnabled?.(false)\n }, 'remote-web-ui: mobile-adapt')\n\n // Anonymous install heartbeat (docs/telemetry.md): one beat per browser per\n // UTC day, package name only, silent failure.\n reportDailyHeartbeat([{ name: '@linxin666/dsh-remote-web-ui' }])\n\n ctx.effect(() => {\n try {\n return ctx.locale.register(NS, { zh, en })\n } catch {\n return () => {}\n }\n }, 'remote-web-ui: dictionaries')\n\n // The mobile adapt's whale button expands the collapsed sidebar and the\n // activation closes the details panel — both through the official layout\n // service (ctx.layout.toggleSidebar / closeDetails flip the panel state;\n // the narrow-viewport semantics open the drawer).\n const layout = ctx.get('layout') as { toggleSidebar?: () => void; closeDetails?: () => void } | undefined\n const adapt = (window as unknown as { __dshRemoteAdapt?: RemoteAdaptGlobal }).__dshRemoteAdapt\n // The official layout face throws (by contract) when the root entry has\n // not mounted yet; these closures also fire from gestures racing that\n // first mount, so they tolerate the throw instead of surfacing it.\n const layoutCall = (call: (() => void) | undefined): void => {\n try {\n call?.()\n } catch {\n // Boot-order throw: the panel action is a no-op before the root entry.\n }\n }\n if (layout !== undefined && adapt !== undefined) {\n if (typeof layout.toggleSidebar === 'function') {\n adapt.toggleSidebar = () => {\n layoutCall(layout.toggleSidebar)\n }\n }\n if (typeof layout.closeDetails === 'function') {\n adapt.closeDetails = () => {\n layoutCall(layout.closeDetails)\n }\n }\n }\n if (adapt !== undefined && adapt.toggleSidebar === null) {\n // Layout face unavailable (older composition): fall back to clicking the\n // official rail toggle when it exists.\n adapt.toggleSidebar = () => {\n (document.querySelector('[class$=\"_railFish\"] button, [class$=\"_logoRow\"] [class*=\"_iconButton\"]') as HTMLElement | null)?.click()\n }\n }\n\n const t = ctx.locale.bind(NS)\n // Hand the `remote` translate seat to the module-scope adaptation layer:\n // the whale/compact-picker labels were rendered with the English fallback\n // before any dictionary existed; the wiring plus the layer's own sync tick\n // re-render them in the active locale.\n if (adapt !== undefined) adapt.translate = t\n const binder = ctx.get('webUiSettings') ?? ctx.settingsScope\n const settingsScope = binder.bind<RemoteSettings>({ namespace: REMOTE_WEB_UI_NS })\n const enabled = (): boolean => {\n const snapshot = settingsScope.getSnapshot()\n return snapshot.status === 'ready'\n ? snapshot.value?.enabled ?? true\n : snapshot.status === 'unavailable'\n }\n\n // Master switch for the adaptation layer: the module-scope install runs\n // before any config is readable, so flip it once the settings snapshot is\n // bound and on every later change (disabled plugin = no injected surface).\n // Also replay the pending closeDetails: the first portrait apply ran\n // before the layout face was wired, so its closeDetails was a no-op and a\n // restored details panel would otherwise sit hidden until landscape.\n const syncAdaptEnabled = (): void => {\n ;(window as unknown as { __dshRemoteAdapt?: RemoteAdaptGlobal }).__dshRemoteAdapt?.setEnabled?.(enabled())\n }\n settingsScope.subscribe(syncAdaptEnabled)\n syncAdaptEnabled()\n // The replay closes a details panel restored before the wiring; the\n // layout face throws while the root entry has not mounted yet (a real\n // boot-order race on slow remote loads), and the plugin's apply world\n // must survive it — the replay is a best-effort no-op then.\n try {\n adapt?.flushCloseDetails?.()\n } catch {}\n\n // Sidebar foot entry: the sidebar foot seat is `sidebar.footer.action` in\n // the 0.1.2 shell composition (the legacy `sidebar.remote` seat is gone\n // upstream). The pairing link is origin-agnostic, so the entry needs no\n // workspace source.\n ctx.slots.inject('sidebar.footer.action', () => {\n let disposeEntry: (() => void) | undefined\n const syncEntry = (): void => {\n if (enabled() && disposeEntry === undefined) {\n try {\n disposeEntry = ctx.slots.register({ name: 'sidebar.footer.action', id: 'remote-web-ui', locale: NS }, FooterRemoteEntry)\n } catch {\n // ignore registration collision\n }\n } else if (!enabled() && disposeEntry !== undefined) {\n disposeEntry()\n disposeEntry = undefined\n }\n }\n const unsubscribe = settingsScope.subscribe(syncEntry)\n syncEntry()\n return () => {\n unsubscribe()\n disposeEntry?.()\n }\n })\n\n // Plugin configuration card: one staged form over the `remote-web-ui`\n // settings namespace, contributed to the Web UI plugin group.\n const remoteSettings = new RemoteSettingsCardController(settingsScope)\n ctx.slots.inject('web-ui.plugin.item', () => {\n try {\n const unregister = ctx.slots.register({\n name: 'web-ui.plugin.item',\n id: 'remote-web-ui',\n order: 90,\n locale: NS,\n inject: () => remoteSettings.inject(),\n }, RemoteSettingsCard)\n return () => {\n remoteSettings.dispose()\n unregister()\n }\n } catch {\n return () => {}\n }\n })\n\n // Phone-side boot flow + heartbeats. Loopback pages (the desktop) never\n // heartbeat; the server ignores unpaired heartbeats anyway. Both run only\n // while the plugin is enabled.\n let disposeRuntime: (() => void) | undefined\n const syncRuntime = (): void => {\n if (enabled() && disposeRuntime === undefined) {\n disposeRuntime = ctx.effect(() => {\n const connection = ctx.get('connection') as ConnectionHandle | undefined\n const loopback = connection?.isLoopback ?? true\n runPairBootFlow(ctx, window.location.search)\n if (loopback) return () => {}\n const timer = window.setInterval(() => { void sendHeartbeat().catch(() => {}) }, HEARTBEAT_INTERVAL_MS)\n return () => { window.clearInterval(timer) }\n }, 'remote-web-ui: pair flow + heartbeats')\n } else if (!enabled() && disposeRuntime !== undefined) {\n disposeRuntime()\n disposeRuntime = undefined\n }\n }\n settingsScope.subscribe(syncRuntime)\n syncRuntime()\n\n // Remote desktop channel: on a non-loopback origin (LAN address or public\n // tunnel) the connection plugin's /api fence refuses this desktop Web GUI,\n // and pairing is the access control — so the SDK client's /api traffic is\n // rewritten onto this plugin's gated /remote/api prefix (remote-channel.ts)\n // while the fence setting demands it. Loopback origins are untouched.\n let disposeChannel: (() => void) | undefined\n let hostPairingPolicy: boolean | undefined\n let unpairedWhilePolicyPending = false\n let fenceNotice: { unmount: () => void; node: HTMLElement } | undefined\n const showFenceNotice = (): void => {\n if (fenceNotice !== undefined) return\n const node = document.createElement('div')\n document.body.appendChild(node)\n const root = createRoot(node)\n root.render(createElement(FenceNotice, { t, onRetry: () => { window.location.reload() } }))\n fenceNotice = { unmount: () => { root.unmount(); node.remove() }, node }\n }\n const hideFenceNotice = (): void => {\n fenceNotice?.unmount()\n fenceNotice = undefined\n }\n const handleUnpaired = (): void => {\n if (settingsScope.getSnapshot().status !== 'ready' && hostPairingPolicy === undefined) {\n unpairedWhilePolicyPending = true\n return\n }\n showFenceNotice()\n }\n const channelActive = (): boolean => remoteChannelRequired(\n window.location.hostname,\n settingsScope.getSnapshot(),\n hostPairingPolicy,\n )\n // The parse-time boot patch (issue #987), when the served index carried\n // it: already installed before any boot entry ran, so adopting its seat\n // beats patching a second time (which would double-rewrite onto\n // /remote/remote/...).\n const bootSeat = (): RemoteChannelBootSeat | undefined =>\n (window as unknown as Record<string, RemoteChannelBootSeat | undefined>)[REMOTE_CHANNEL_BOOT_GLOBAL]\n const syncChannel = (): void => {\n const transition = channelTransition(channelActive(), disposeChannel !== undefined)\n if (transition === 'install') {\n const seat = bootSeat()\n if (seat !== undefined) {\n seat.onUnpaired = handleUnpaired\n seat.onPaired = hideFenceNotice\n // Replay a signal raised before adoption (early unpaired responses).\n if (seat.pendingUnpaired) {\n seat.pendingUnpaired = false\n handleUnpaired()\n }\n disposeChannel = ctx.effect(() => () => {\n seat.onUnpaired = null\n seat.onPaired = null\n }, 'remote-web-ui: remote desktop channel (boot patch)')\n } else {\n disposeChannel = ctx.effect(() => {\n const restore = installRemoteChannel(window, { onUnpaired: handleUnpaired, onPaired: hideFenceNotice })\n return restore\n }, 'remote-web-ui: remote desktop channel')\n }\n } else if (transition === 'retire' && disposeChannel !== undefined) {\n disposeChannel()\n disposeChannel = undefined\n // Retire the provisional parse-time install with the channel: the\n // desktop now rides plain /api, so the rewrite must go (its seat\n // removes the global; a later re-activation patches afresh).\n bootSeat()?.restore()\n // Retire the notice with the channel: once requirePairingForLan turns\n // off (or the plugin is disabled) the desktop rides plain /api again,\n // so an unpaired notice raised while the channel was briefly active\n // (the settings snapshot loads after boot) must not outlive it. The\n // installed channel is the only path that raises the notice, so with\n // the channel gone nothing can re-raise it (issue #808).\n hideFenceNotice()\n } else if (transition === 'none' && !channelActive()) {\n // The channel was never adopted (policy settled to off before apply\n // ran): the provisional boot patch still retires.\n bootSeat()?.restore()\n }\n }\n settingsScope.subscribe(syncChannel)\n syncChannel()\n if (!isLoopbackHostname(window.location.hostname) && settingsScope.getSnapshot().status !== 'ready') {\n void readPairGatePolicy().then((policy) => {\n hostPairingPolicy = policy.requirePairingForLan\n syncChannel()\n if (hostPairingPolicy && unpairedWhilePolicyPending) showFenceNotice()\n unpairedWhilePolicyPending = false\n }).catch(() => {\n // Fail closed when the policy endpoint is unavailable or malformed.\n hostPairingPolicy = true\n syncChannel()\n if (unpairedWhilePolicyPending) showFenceNotice()\n unpairedWhilePolicyPending = false\n })\n }\n\n // One-time failed-pair toast. The accept result lands asynchronously, so\n // the marker check is deferred past the accept round trip.\n ctx.effect(() => {\n const timer = window.setTimeout(() => {\n if (sessionStorage.getItem(PAIR_FAILED_MARKER) === null) return\n sessionStorage.removeItem(PAIR_FAILED_MARKER)\n const mount = document.createElement('div')\n document.body.appendChild(mount)\n const root = createRoot(mount)\n root.render(createElement(PairFailedNotice, { t }))\n // The toast owns its dismissal; the root lives for the page lifetime.\n void root\n }, 1500)\n return () => { window.clearTimeout(timer) }\n }, 'remote-web-ui: failed-pair notice')\n}\n"],"x_google_ignoreList":[0,1],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"client.js","names":["React","css","IconCloseOutline16","IconCopyOutline16","IconStopFill16","IconRefreshOutline16","css","IconCloseOutline16","IconRefreshOutline16","css","IconDownloadOutline16","css","css","css","REMOTE_PREFIX","REMOTE_API_PREFIX","css"],"sources":["../../../node_modules/.pnpm/clsx@2.1.1/node_modules/clsx/dist/clsx.mjs","../../../node_modules/.pnpm/qrcode.react@4.2.0_react@18.3.1/node_modules/qrcode.react/lib/esm/index.js","../../../packages/dsh-remote-web-ui/src/client/pair-api.ts","../../../packages/dsh-remote-web-ui/src/client/device-name.ts","../../../packages/dsh-remote-web-ui/src/client/RemotePanel.tsx","../../../packages/dsh-remote-web-ui/src/client/PhoneIcon.tsx","../../../packages/dsh-remote-web-ui/src/client/update-api.ts","../../../packages/dsh-remote-web-ui/src/client/UpdatePanel.tsx","../../../packages/dsh-remote-web-ui/src/client/UpdateEntry.tsx","../../../packages/dsh-remote-web-ui/src/client/RemoteEntry.tsx","../../../packages/dsh-remote-web-ui/src/client/FooterRemoteEntry.tsx","../../../packages/dsh-remote-web-ui/src/client/PairFailedNotice.tsx","../../../packages/dsh-remote-web-ui/src/client/PluginSettingsCard.tsx","../../../packages/dsh-remote-web-ui/src/client/settings-form.ts","../../../packages/dsh-remote-web-ui/src/client/RemoteSettingsCard.tsx","../../../packages/dsh-remote-web-ui/src/client/locales.ts","../../../packages/dsh-remote-web-ui/src/client/deep-link.ts","../../../packages/dsh-remote-web-ui/src/remote-methods.ts","../../../packages/dsh-remote-web-ui/src/remote-channel-rules.ts","../../../packages/dsh-remote-web-ui/src/client/remote-channel.ts","../../../packages/dsh-remote-web-ui/src/client/FenceNotice.tsx","../../../packages/dsh-remote-web-ui/src/client/telemetry.ts","../../../packages/dsh-remote-web-ui/src/client/mobile-adapt.ts","../../../packages/dsh-remote-web-ui/src/client/plugin-card-seat.ts","../../../packages/dsh-remote-web-ui/src/client/index.ts"],"sourcesContent":["function r(e){var t,f,n=\"\";if(\"string\"==typeof e||\"number\"==typeof e)n+=e;else if(\"object\"==typeof e)if(Array.isArray(e)){var o=e.length;for(t=0;t<o;t++)e[t]&&(f=r(e[t]))&&(n&&(n+=\" \"),n+=f)}else for(f in e)e[f]&&(n&&(n+=\" \"),n+=f);return n}export function clsx(){for(var e,t,f=0,n=\"\",o=arguments.length;f<o;f++)(e=arguments[f])&&(t=r(e))&&(n&&(n+=\" \"),n+=t);return n}export default clsx;","var __defProp = Object.defineProperty;\nvar __getOwnPropSymbols = Object.getOwnPropertySymbols;\nvar __hasOwnProp = Object.prototype.hasOwnProperty;\nvar __propIsEnum = Object.prototype.propertyIsEnumerable;\nvar __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;\nvar __spreadValues = (a, b) => {\n for (var prop in b || (b = {}))\n if (__hasOwnProp.call(b, prop))\n __defNormalProp(a, prop, b[prop]);\n if (__getOwnPropSymbols)\n for (var prop of __getOwnPropSymbols(b)) {\n if (__propIsEnum.call(b, prop))\n __defNormalProp(a, prop, b[prop]);\n }\n return a;\n};\nvar __objRest = (source, exclude) => {\n var target = {};\n for (var prop in source)\n if (__hasOwnProp.call(source, prop) && exclude.indexOf(prop) < 0)\n target[prop] = source[prop];\n if (source != null && __getOwnPropSymbols)\n for (var prop of __getOwnPropSymbols(source)) {\n if (exclude.indexOf(prop) < 0 && __propIsEnum.call(source, prop))\n target[prop] = source[prop];\n }\n return target;\n};\n\n// src/index.tsx\nimport React from \"react\";\n\n// src/third-party/qrcodegen/index.ts\n/**\n * @license QR Code generator library (TypeScript)\n * Copyright (c) Project Nayuki.\n * SPDX-License-Identifier: MIT\n */\nvar qrcodegen;\n((qrcodegen2) => {\n const _QrCode = class _QrCode {\n /*-- Constructor (low level) and fields --*/\n // Creates a new QR Code with the given version number,\n // error correction level, data codeword bytes, and mask number.\n // This is a low-level API that most users should not use directly.\n // A mid-level API is the encodeSegments() function.\n constructor(version, errorCorrectionLevel, dataCodewords, msk) {\n this.version = version;\n this.errorCorrectionLevel = errorCorrectionLevel;\n // The modules of this QR Code (false = light, true = dark).\n // Immutable after constructor finishes. Accessed through getModule().\n this.modules = [];\n // Indicates function modules that are not subjected to masking. Discarded when constructor finishes.\n this.isFunction = [];\n if (version < _QrCode.MIN_VERSION || version > _QrCode.MAX_VERSION)\n throw new RangeError(\"Version value out of range\");\n if (msk < -1 || msk > 7)\n throw new RangeError(\"Mask value out of range\");\n this.size = version * 4 + 17;\n let row = [];\n for (let i = 0; i < this.size; i++)\n row.push(false);\n for (let i = 0; i < this.size; i++) {\n this.modules.push(row.slice());\n this.isFunction.push(row.slice());\n }\n this.drawFunctionPatterns();\n const allCodewords = this.addEccAndInterleave(dataCodewords);\n this.drawCodewords(allCodewords);\n if (msk == -1) {\n let minPenalty = 1e9;\n for (let i = 0; i < 8; i++) {\n this.applyMask(i);\n this.drawFormatBits(i);\n const penalty = this.getPenaltyScore();\n if (penalty < minPenalty) {\n msk = i;\n minPenalty = penalty;\n }\n this.applyMask(i);\n }\n }\n assert(0 <= msk && msk <= 7);\n this.mask = msk;\n this.applyMask(msk);\n this.drawFormatBits(msk);\n this.isFunction = [];\n }\n /*-- Static factory functions (high level) --*/\n // Returns a QR Code representing the given Unicode text string at the given error correction level.\n // As a conservative upper bound, this function is guaranteed to succeed for strings that have 738 or fewer\n // Unicode code points (not UTF-16 code units) if the low error correction level is used. The smallest possible\n // QR Code version is automatically chosen for the output. The ECC level of the result may be higher than the\n // ecl argument if it can be done without increasing the version.\n static encodeText(text, ecl) {\n const segs = qrcodegen2.QrSegment.makeSegments(text);\n return _QrCode.encodeSegments(segs, ecl);\n }\n // Returns a QR Code representing the given binary data at the given error correction level.\n // This function always encodes using the binary segment mode, not any text mode. The maximum number of\n // bytes allowed is 2953. The smallest possible QR Code version is automatically chosen for the output.\n // The ECC level of the result may be higher than the ecl argument if it can be done without increasing the version.\n static encodeBinary(data, ecl) {\n const seg = qrcodegen2.QrSegment.makeBytes(data);\n return _QrCode.encodeSegments([seg], ecl);\n }\n /*-- Static factory functions (mid level) --*/\n // Returns a QR Code representing the given segments with the given encoding parameters.\n // The smallest possible QR Code version within the given range is automatically\n // chosen for the output. Iff boostEcl is true, then the ECC level of the result\n // may be higher than the ecl argument if it can be done without increasing the\n // version. The mask number is either between 0 to 7 (inclusive) to force that\n // mask, or -1 to automatically choose an appropriate mask (which may be slow).\n // This function allows the user to create a custom sequence of segments that switches\n // between modes (such as alphanumeric and byte) to encode text in less space.\n // This is a mid-level API; the high-level API is encodeText() and encodeBinary().\n static encodeSegments(segs, ecl, minVersion = 1, maxVersion = 40, mask = -1, boostEcl = true) {\n if (!(_QrCode.MIN_VERSION <= minVersion && minVersion <= maxVersion && maxVersion <= _QrCode.MAX_VERSION) || mask < -1 || mask > 7)\n throw new RangeError(\"Invalid value\");\n let version;\n let dataUsedBits;\n for (version = minVersion; ; version++) {\n const dataCapacityBits2 = _QrCode.getNumDataCodewords(version, ecl) * 8;\n const usedBits = QrSegment.getTotalBits(segs, version);\n if (usedBits <= dataCapacityBits2) {\n dataUsedBits = usedBits;\n break;\n }\n if (version >= maxVersion)\n throw new RangeError(\"Data too long\");\n }\n for (const newEcl of [_QrCode.Ecc.MEDIUM, _QrCode.Ecc.QUARTILE, _QrCode.Ecc.HIGH]) {\n if (boostEcl && dataUsedBits <= _QrCode.getNumDataCodewords(version, newEcl) * 8)\n ecl = newEcl;\n }\n let bb = [];\n for (const seg of segs) {\n appendBits(seg.mode.modeBits, 4, bb);\n appendBits(seg.numChars, seg.mode.numCharCountBits(version), bb);\n for (const b of seg.getData())\n bb.push(b);\n }\n assert(bb.length == dataUsedBits);\n const dataCapacityBits = _QrCode.getNumDataCodewords(version, ecl) * 8;\n assert(bb.length <= dataCapacityBits);\n appendBits(0, Math.min(4, dataCapacityBits - bb.length), bb);\n appendBits(0, (8 - bb.length % 8) % 8, bb);\n assert(bb.length % 8 == 0);\n for (let padByte = 236; bb.length < dataCapacityBits; padByte ^= 236 ^ 17)\n appendBits(padByte, 8, bb);\n let dataCodewords = [];\n while (dataCodewords.length * 8 < bb.length)\n dataCodewords.push(0);\n bb.forEach((b, i) => dataCodewords[i >>> 3] |= b << 7 - (i & 7));\n return new _QrCode(version, ecl, dataCodewords, mask);\n }\n /*-- Accessor methods --*/\n // Returns the color of the module (pixel) at the given coordinates, which is false\n // for light or true for dark. The top left corner has the coordinates (x=0, y=0).\n // If the given coordinates are out of bounds, then false (light) is returned.\n getModule(x, y) {\n return 0 <= x && x < this.size && 0 <= y && y < this.size && this.modules[y][x];\n }\n // Modified to expose modules for easy access\n getModules() {\n return this.modules;\n }\n /*-- Private helper methods for constructor: Drawing function modules --*/\n // Reads this object's version field, and draws and marks all function modules.\n drawFunctionPatterns() {\n for (let i = 0; i < this.size; i++) {\n this.setFunctionModule(6, i, i % 2 == 0);\n this.setFunctionModule(i, 6, i % 2 == 0);\n }\n this.drawFinderPattern(3, 3);\n this.drawFinderPattern(this.size - 4, 3);\n this.drawFinderPattern(3, this.size - 4);\n const alignPatPos = this.getAlignmentPatternPositions();\n const numAlign = alignPatPos.length;\n for (let i = 0; i < numAlign; i++) {\n for (let j = 0; j < numAlign; j++) {\n if (!(i == 0 && j == 0 || i == 0 && j == numAlign - 1 || i == numAlign - 1 && j == 0))\n this.drawAlignmentPattern(alignPatPos[i], alignPatPos[j]);\n }\n }\n this.drawFormatBits(0);\n this.drawVersion();\n }\n // Draws two copies of the format bits (with its own error correction code)\n // based on the given mask and this object's error correction level field.\n drawFormatBits(mask) {\n const data = this.errorCorrectionLevel.formatBits << 3 | mask;\n let rem = data;\n for (let i = 0; i < 10; i++)\n rem = rem << 1 ^ (rem >>> 9) * 1335;\n const bits = (data << 10 | rem) ^ 21522;\n assert(bits >>> 15 == 0);\n for (let i = 0; i <= 5; i++)\n this.setFunctionModule(8, i, getBit(bits, i));\n this.setFunctionModule(8, 7, getBit(bits, 6));\n this.setFunctionModule(8, 8, getBit(bits, 7));\n this.setFunctionModule(7, 8, getBit(bits, 8));\n for (let i = 9; i < 15; i++)\n this.setFunctionModule(14 - i, 8, getBit(bits, i));\n for (let i = 0; i < 8; i++)\n this.setFunctionModule(this.size - 1 - i, 8, getBit(bits, i));\n for (let i = 8; i < 15; i++)\n this.setFunctionModule(8, this.size - 15 + i, getBit(bits, i));\n this.setFunctionModule(8, this.size - 8, true);\n }\n // Draws two copies of the version bits (with its own error correction code),\n // based on this object's version field, iff 7 <= version <= 40.\n drawVersion() {\n if (this.version < 7)\n return;\n let rem = this.version;\n for (let i = 0; i < 12; i++)\n rem = rem << 1 ^ (rem >>> 11) * 7973;\n const bits = this.version << 12 | rem;\n assert(bits >>> 18 == 0);\n for (let i = 0; i < 18; i++) {\n const color = getBit(bits, i);\n const a = this.size - 11 + i % 3;\n const b = Math.floor(i / 3);\n this.setFunctionModule(a, b, color);\n this.setFunctionModule(b, a, color);\n }\n }\n // Draws a 9*9 finder pattern including the border separator,\n // with the center module at (x, y). Modules can be out of bounds.\n drawFinderPattern(x, y) {\n for (let dy = -4; dy <= 4; dy++) {\n for (let dx = -4; dx <= 4; dx++) {\n const dist = Math.max(Math.abs(dx), Math.abs(dy));\n const xx = x + dx;\n const yy = y + dy;\n if (0 <= xx && xx < this.size && 0 <= yy && yy < this.size)\n this.setFunctionModule(xx, yy, dist != 2 && dist != 4);\n }\n }\n }\n // Draws a 5*5 alignment pattern, with the center module\n // at (x, y). All modules must be in bounds.\n drawAlignmentPattern(x, y) {\n for (let dy = -2; dy <= 2; dy++) {\n for (let dx = -2; dx <= 2; dx++)\n this.setFunctionModule(x + dx, y + dy, Math.max(Math.abs(dx), Math.abs(dy)) != 1);\n }\n }\n // Sets the color of a module and marks it as a function module.\n // Only used by the constructor. Coordinates must be in bounds.\n setFunctionModule(x, y, isDark) {\n this.modules[y][x] = isDark;\n this.isFunction[y][x] = true;\n }\n /*-- Private helper methods for constructor: Codewords and masking --*/\n // Returns a new byte string representing the given data with the appropriate error correction\n // codewords appended to it, based on this object's version and error correction level.\n addEccAndInterleave(data) {\n const ver = this.version;\n const ecl = this.errorCorrectionLevel;\n if (data.length != _QrCode.getNumDataCodewords(ver, ecl))\n throw new RangeError(\"Invalid argument\");\n const numBlocks = _QrCode.NUM_ERROR_CORRECTION_BLOCKS[ecl.ordinal][ver];\n const blockEccLen = _QrCode.ECC_CODEWORDS_PER_BLOCK[ecl.ordinal][ver];\n const rawCodewords = Math.floor(_QrCode.getNumRawDataModules(ver) / 8);\n const numShortBlocks = numBlocks - rawCodewords % numBlocks;\n const shortBlockLen = Math.floor(rawCodewords / numBlocks);\n let blocks = [];\n const rsDiv = _QrCode.reedSolomonComputeDivisor(blockEccLen);\n for (let i = 0, k = 0; i < numBlocks; i++) {\n let dat = data.slice(k, k + shortBlockLen - blockEccLen + (i < numShortBlocks ? 0 : 1));\n k += dat.length;\n const ecc = _QrCode.reedSolomonComputeRemainder(dat, rsDiv);\n if (i < numShortBlocks)\n dat.push(0);\n blocks.push(dat.concat(ecc));\n }\n let result = [];\n for (let i = 0; i < blocks[0].length; i++) {\n blocks.forEach((block, j) => {\n if (i != shortBlockLen - blockEccLen || j >= numShortBlocks)\n result.push(block[i]);\n });\n }\n assert(result.length == rawCodewords);\n return result;\n }\n // Draws the given sequence of 8-bit codewords (data and error correction) onto the entire\n // data area of this QR Code. Function modules need to be marked off before this is called.\n drawCodewords(data) {\n if (data.length != Math.floor(_QrCode.getNumRawDataModules(this.version) / 8))\n throw new RangeError(\"Invalid argument\");\n let i = 0;\n for (let right = this.size - 1; right >= 1; right -= 2) {\n if (right == 6)\n right = 5;\n for (let vert = 0; vert < this.size; vert++) {\n for (let j = 0; j < 2; j++) {\n const x = right - j;\n const upward = (right + 1 & 2) == 0;\n const y = upward ? this.size - 1 - vert : vert;\n if (!this.isFunction[y][x] && i < data.length * 8) {\n this.modules[y][x] = getBit(data[i >>> 3], 7 - (i & 7));\n i++;\n }\n }\n }\n }\n assert(i == data.length * 8);\n }\n // XORs the codeword modules in this QR Code with the given mask pattern.\n // The function modules must be marked and the codeword bits must be drawn\n // before masking. Due to the arithmetic of XOR, calling applyMask() with\n // the same mask value a second time will undo the mask. A final well-formed\n // QR Code needs exactly one (not zero, two, etc.) mask applied.\n applyMask(mask) {\n if (mask < 0 || mask > 7)\n throw new RangeError(\"Mask value out of range\");\n for (let y = 0; y < this.size; y++) {\n for (let x = 0; x < this.size; x++) {\n let invert;\n switch (mask) {\n case 0:\n invert = (x + y) % 2 == 0;\n break;\n case 1:\n invert = y % 2 == 0;\n break;\n case 2:\n invert = x % 3 == 0;\n break;\n case 3:\n invert = (x + y) % 3 == 0;\n break;\n case 4:\n invert = (Math.floor(x / 3) + Math.floor(y / 2)) % 2 == 0;\n break;\n case 5:\n invert = x * y % 2 + x * y % 3 == 0;\n break;\n case 6:\n invert = (x * y % 2 + x * y % 3) % 2 == 0;\n break;\n case 7:\n invert = ((x + y) % 2 + x * y % 3) % 2 == 0;\n break;\n default:\n throw new Error(\"Unreachable\");\n }\n if (!this.isFunction[y][x] && invert)\n this.modules[y][x] = !this.modules[y][x];\n }\n }\n }\n // Calculates and returns the penalty score based on state of this QR Code's current modules.\n // This is used by the automatic mask choice algorithm to find the mask pattern that yields the lowest score.\n getPenaltyScore() {\n let result = 0;\n for (let y = 0; y < this.size; y++) {\n let runColor = false;\n let runX = 0;\n let runHistory = [0, 0, 0, 0, 0, 0, 0];\n for (let x = 0; x < this.size; x++) {\n if (this.modules[y][x] == runColor) {\n runX++;\n if (runX == 5)\n result += _QrCode.PENALTY_N1;\n else if (runX > 5)\n result++;\n } else {\n this.finderPenaltyAddHistory(runX, runHistory);\n if (!runColor)\n result += this.finderPenaltyCountPatterns(runHistory) * _QrCode.PENALTY_N3;\n runColor = this.modules[y][x];\n runX = 1;\n }\n }\n result += this.finderPenaltyTerminateAndCount(runColor, runX, runHistory) * _QrCode.PENALTY_N3;\n }\n for (let x = 0; x < this.size; x++) {\n let runColor = false;\n let runY = 0;\n let runHistory = [0, 0, 0, 0, 0, 0, 0];\n for (let y = 0; y < this.size; y++) {\n if (this.modules[y][x] == runColor) {\n runY++;\n if (runY == 5)\n result += _QrCode.PENALTY_N1;\n else if (runY > 5)\n result++;\n } else {\n this.finderPenaltyAddHistory(runY, runHistory);\n if (!runColor)\n result += this.finderPenaltyCountPatterns(runHistory) * _QrCode.PENALTY_N3;\n runColor = this.modules[y][x];\n runY = 1;\n }\n }\n result += this.finderPenaltyTerminateAndCount(runColor, runY, runHistory) * _QrCode.PENALTY_N3;\n }\n for (let y = 0; y < this.size - 1; y++) {\n for (let x = 0; x < this.size - 1; x++) {\n const color = this.modules[y][x];\n if (color == this.modules[y][x + 1] && color == this.modules[y + 1][x] && color == this.modules[y + 1][x + 1])\n result += _QrCode.PENALTY_N2;\n }\n }\n let dark = 0;\n for (const row of this.modules)\n dark = row.reduce((sum, color) => sum + (color ? 1 : 0), dark);\n const total = this.size * this.size;\n const k = Math.ceil(Math.abs(dark * 20 - total * 10) / total) - 1;\n assert(0 <= k && k <= 9);\n result += k * _QrCode.PENALTY_N4;\n assert(0 <= result && result <= 2568888);\n return result;\n }\n /*-- Private helper functions --*/\n // Returns an ascending list of positions of alignment patterns for this version number.\n // Each position is in the range [0,177), and are used on both the x and y axes.\n // This could be implemented as lookup table of 40 variable-length lists of integers.\n getAlignmentPatternPositions() {\n if (this.version == 1)\n return [];\n else {\n const numAlign = Math.floor(this.version / 7) + 2;\n const step = this.version == 32 ? 26 : Math.ceil((this.version * 4 + 4) / (numAlign * 2 - 2)) * 2;\n let result = [6];\n for (let pos = this.size - 7; result.length < numAlign; pos -= step)\n result.splice(1, 0, pos);\n return result;\n }\n }\n // Returns the number of data bits that can be stored in a QR Code of the given version number, after\n // all function modules are excluded. This includes remainder bits, so it might not be a multiple of 8.\n // The result is in the range [208, 29648]. This could be implemented as a 40-entry lookup table.\n static getNumRawDataModules(ver) {\n if (ver < _QrCode.MIN_VERSION || ver > _QrCode.MAX_VERSION)\n throw new RangeError(\"Version number out of range\");\n let result = (16 * ver + 128) * ver + 64;\n if (ver >= 2) {\n const numAlign = Math.floor(ver / 7) + 2;\n result -= (25 * numAlign - 10) * numAlign - 55;\n if (ver >= 7)\n result -= 36;\n }\n assert(208 <= result && result <= 29648);\n return result;\n }\n // Returns the number of 8-bit data (i.e. not error correction) codewords contained in any\n // QR Code of the given version number and error correction level, with remainder bits discarded.\n // This stateless pure function could be implemented as a (40*4)-cell lookup table.\n static getNumDataCodewords(ver, ecl) {\n return Math.floor(_QrCode.getNumRawDataModules(ver) / 8) - _QrCode.ECC_CODEWORDS_PER_BLOCK[ecl.ordinal][ver] * _QrCode.NUM_ERROR_CORRECTION_BLOCKS[ecl.ordinal][ver];\n }\n // Returns a Reed-Solomon ECC generator polynomial for the given degree. This could be\n // implemented as a lookup table over all possible parameter values, instead of as an algorithm.\n static reedSolomonComputeDivisor(degree) {\n if (degree < 1 || degree > 255)\n throw new RangeError(\"Degree out of range\");\n let result = [];\n for (let i = 0; i < degree - 1; i++)\n result.push(0);\n result.push(1);\n let root = 1;\n for (let i = 0; i < degree; i++) {\n for (let j = 0; j < result.length; j++) {\n result[j] = _QrCode.reedSolomonMultiply(result[j], root);\n if (j + 1 < result.length)\n result[j] ^= result[j + 1];\n }\n root = _QrCode.reedSolomonMultiply(root, 2);\n }\n return result;\n }\n // Returns the Reed-Solomon error correction codeword for the given data and divisor polynomials.\n static reedSolomonComputeRemainder(data, divisor) {\n let result = divisor.map((_) => 0);\n for (const b of data) {\n const factor = b ^ result.shift();\n result.push(0);\n divisor.forEach((coef, i) => result[i] ^= _QrCode.reedSolomonMultiply(coef, factor));\n }\n return result;\n }\n // Returns the product of the two given field elements modulo GF(2^8/0x11D). The arguments and result\n // are unsigned 8-bit integers. This could be implemented as a lookup table of 256*256 entries of uint8.\n static reedSolomonMultiply(x, y) {\n if (x >>> 8 != 0 || y >>> 8 != 0)\n throw new RangeError(\"Byte out of range\");\n let z = 0;\n for (let i = 7; i >= 0; i--) {\n z = z << 1 ^ (z >>> 7) * 285;\n z ^= (y >>> i & 1) * x;\n }\n assert(z >>> 8 == 0);\n return z;\n }\n // Can only be called immediately after a light run is added, and\n // returns either 0, 1, or 2. A helper function for getPenaltyScore().\n finderPenaltyCountPatterns(runHistory) {\n const n = runHistory[1];\n assert(n <= this.size * 3);\n const core = n > 0 && runHistory[2] == n && runHistory[3] == n * 3 && runHistory[4] == n && runHistory[5] == n;\n return (core && runHistory[0] >= n * 4 && runHistory[6] >= n ? 1 : 0) + (core && runHistory[6] >= n * 4 && runHistory[0] >= n ? 1 : 0);\n }\n // Must be called at the end of a line (row or column) of modules. A helper function for getPenaltyScore().\n finderPenaltyTerminateAndCount(currentRunColor, currentRunLength, runHistory) {\n if (currentRunColor) {\n this.finderPenaltyAddHistory(currentRunLength, runHistory);\n currentRunLength = 0;\n }\n currentRunLength += this.size;\n this.finderPenaltyAddHistory(currentRunLength, runHistory);\n return this.finderPenaltyCountPatterns(runHistory);\n }\n // Pushes the given value to the front and drops the last value. A helper function for getPenaltyScore().\n finderPenaltyAddHistory(currentRunLength, runHistory) {\n if (runHistory[0] == 0)\n currentRunLength += this.size;\n runHistory.pop();\n runHistory.unshift(currentRunLength);\n }\n };\n /*-- Constants and tables --*/\n // The minimum version number supported in the QR Code Model 2 standard.\n _QrCode.MIN_VERSION = 1;\n // The maximum version number supported in the QR Code Model 2 standard.\n _QrCode.MAX_VERSION = 40;\n // For use in getPenaltyScore(), when evaluating which mask is best.\n _QrCode.PENALTY_N1 = 3;\n _QrCode.PENALTY_N2 = 3;\n _QrCode.PENALTY_N3 = 40;\n _QrCode.PENALTY_N4 = 10;\n _QrCode.ECC_CODEWORDS_PER_BLOCK = [\n // Version: (note that index 0 is for padding, and is set to an illegal value)\n //0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40 Error correction level\n [-1, 7, 10, 15, 20, 26, 18, 20, 24, 30, 18, 20, 24, 26, 30, 22, 24, 28, 30, 28, 28, 28, 28, 30, 30, 26, 28, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30],\n // Low\n [-1, 10, 16, 26, 18, 24, 16, 18, 22, 22, 26, 30, 22, 22, 24, 24, 28, 28, 26, 26, 26, 26, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28],\n // Medium\n [-1, 13, 22, 18, 26, 18, 24, 18, 22, 20, 24, 28, 26, 24, 20, 30, 24, 28, 28, 26, 30, 28, 30, 30, 30, 30, 28, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30],\n // Quartile\n [-1, 17, 28, 22, 16, 22, 28, 26, 26, 24, 28, 24, 28, 22, 24, 24, 30, 28, 28, 26, 28, 30, 24, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30]\n // High\n ];\n _QrCode.NUM_ERROR_CORRECTION_BLOCKS = [\n // Version: (note that index 0 is for padding, and is set to an illegal value)\n //0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40 Error correction level\n [-1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 4, 4, 4, 4, 4, 6, 6, 6, 6, 7, 8, 8, 9, 9, 10, 12, 12, 12, 13, 14, 15, 16, 17, 18, 19, 19, 20, 21, 22, 24, 25],\n // Low\n [-1, 1, 1, 1, 2, 2, 4, 4, 4, 5, 5, 5, 8, 9, 9, 10, 10, 11, 13, 14, 16, 17, 17, 18, 20, 21, 23, 25, 26, 28, 29, 31, 33, 35, 37, 38, 40, 43, 45, 47, 49],\n // Medium\n [-1, 1, 1, 2, 2, 4, 4, 6, 6, 8, 8, 8, 10, 12, 16, 12, 17, 16, 18, 21, 20, 23, 23, 25, 27, 29, 34, 34, 35, 38, 40, 43, 45, 48, 51, 53, 56, 59, 62, 65, 68],\n // Quartile\n [-1, 1, 1, 2, 4, 4, 4, 5, 6, 8, 8, 11, 11, 16, 16, 18, 16, 19, 21, 25, 25, 25, 34, 30, 32, 35, 37, 40, 42, 45, 48, 51, 54, 57, 60, 63, 66, 70, 74, 77, 81]\n // High\n ];\n let QrCode = _QrCode;\n qrcodegen2.QrCode = _QrCode;\n function appendBits(val, len, bb) {\n if (len < 0 || len > 31 || val >>> len != 0)\n throw new RangeError(\"Value out of range\");\n for (let i = len - 1; i >= 0; i--)\n bb.push(val >>> i & 1);\n }\n function getBit(x, i) {\n return (x >>> i & 1) != 0;\n }\n function assert(cond) {\n if (!cond)\n throw new Error(\"Assertion error\");\n }\n const _QrSegment = class _QrSegment {\n /*-- Constructor (low level) and fields --*/\n // Creates a new QR Code segment with the given attributes and data.\n // The character count (numChars) must agree with the mode and the bit buffer length,\n // but the constraint isn't checked. The given bit buffer is cloned and stored.\n constructor(mode, numChars, bitData) {\n this.mode = mode;\n this.numChars = numChars;\n this.bitData = bitData;\n if (numChars < 0)\n throw new RangeError(\"Invalid argument\");\n this.bitData = bitData.slice();\n }\n /*-- Static factory functions (mid level) --*/\n // Returns a segment representing the given binary data encoded in\n // byte mode. All input byte arrays are acceptable. Any text string\n // can be converted to UTF-8 bytes and encoded as a byte mode segment.\n static makeBytes(data) {\n let bb = [];\n for (const b of data)\n appendBits(b, 8, bb);\n return new _QrSegment(_QrSegment.Mode.BYTE, data.length, bb);\n }\n // Returns a segment representing the given string of decimal digits encoded in numeric mode.\n static makeNumeric(digits) {\n if (!_QrSegment.isNumeric(digits))\n throw new RangeError(\"String contains non-numeric characters\");\n let bb = [];\n for (let i = 0; i < digits.length; ) {\n const n = Math.min(digits.length - i, 3);\n appendBits(parseInt(digits.substring(i, i + n), 10), n * 3 + 1, bb);\n i += n;\n }\n return new _QrSegment(_QrSegment.Mode.NUMERIC, digits.length, bb);\n }\n // Returns a segment representing the given text string encoded in alphanumeric mode.\n // The characters allowed are: 0 to 9, A to Z (uppercase only), space,\n // dollar, percent, asterisk, plus, hyphen, period, slash, colon.\n static makeAlphanumeric(text) {\n if (!_QrSegment.isAlphanumeric(text))\n throw new RangeError(\"String contains unencodable characters in alphanumeric mode\");\n let bb = [];\n let i;\n for (i = 0; i + 2 <= text.length; i += 2) {\n let temp = _QrSegment.ALPHANUMERIC_CHARSET.indexOf(text.charAt(i)) * 45;\n temp += _QrSegment.ALPHANUMERIC_CHARSET.indexOf(text.charAt(i + 1));\n appendBits(temp, 11, bb);\n }\n if (i < text.length)\n appendBits(_QrSegment.ALPHANUMERIC_CHARSET.indexOf(text.charAt(i)), 6, bb);\n return new _QrSegment(_QrSegment.Mode.ALPHANUMERIC, text.length, bb);\n }\n // Returns a new mutable list of zero or more segments to represent the given Unicode text string.\n // The result may use various segment modes and switch modes to optimize the length of the bit stream.\n static makeSegments(text) {\n if (text == \"\")\n return [];\n else if (_QrSegment.isNumeric(text))\n return [_QrSegment.makeNumeric(text)];\n else if (_QrSegment.isAlphanumeric(text))\n return [_QrSegment.makeAlphanumeric(text)];\n else\n return [_QrSegment.makeBytes(_QrSegment.toUtf8ByteArray(text))];\n }\n // Returns a segment representing an Extended Channel Interpretation\n // (ECI) designator with the given assignment value.\n static makeEci(assignVal) {\n let bb = [];\n if (assignVal < 0)\n throw new RangeError(\"ECI assignment value out of range\");\n else if (assignVal < 1 << 7)\n appendBits(assignVal, 8, bb);\n else if (assignVal < 1 << 14) {\n appendBits(2, 2, bb);\n appendBits(assignVal, 14, bb);\n } else if (assignVal < 1e6) {\n appendBits(6, 3, bb);\n appendBits(assignVal, 21, bb);\n } else\n throw new RangeError(\"ECI assignment value out of range\");\n return new _QrSegment(_QrSegment.Mode.ECI, 0, bb);\n }\n // Tests whether the given string can be encoded as a segment in numeric mode.\n // A string is encodable iff each character is in the range 0 to 9.\n static isNumeric(text) {\n return _QrSegment.NUMERIC_REGEX.test(text);\n }\n // Tests whether the given string can be encoded as a segment in alphanumeric mode.\n // A string is encodable iff each character is in the following set: 0 to 9, A to Z\n // (uppercase only), space, dollar, percent, asterisk, plus, hyphen, period, slash, colon.\n static isAlphanumeric(text) {\n return _QrSegment.ALPHANUMERIC_REGEX.test(text);\n }\n /*-- Methods --*/\n // Returns a new copy of the data bits of this segment.\n getData() {\n return this.bitData.slice();\n }\n // (Package-private) Calculates and returns the number of bits needed to encode the given segments at\n // the given version. The result is infinity if a segment has too many characters to fit its length field.\n static getTotalBits(segs, version) {\n let result = 0;\n for (const seg of segs) {\n const ccbits = seg.mode.numCharCountBits(version);\n if (seg.numChars >= 1 << ccbits)\n return Infinity;\n result += 4 + ccbits + seg.bitData.length;\n }\n return result;\n }\n // Returns a new array of bytes representing the given string encoded in UTF-8.\n static toUtf8ByteArray(str) {\n str = encodeURI(str);\n let result = [];\n for (let i = 0; i < str.length; i++) {\n if (str.charAt(i) != \"%\")\n result.push(str.charCodeAt(i));\n else {\n result.push(parseInt(str.substring(i + 1, i + 3), 16));\n i += 2;\n }\n }\n return result;\n }\n };\n /*-- Constants --*/\n // Describes precisely all strings that are encodable in numeric mode.\n _QrSegment.NUMERIC_REGEX = /^[0-9]*$/;\n // Describes precisely all strings that are encodable in alphanumeric mode.\n _QrSegment.ALPHANUMERIC_REGEX = /^[A-Z0-9 $%*+.\\/:-]*$/;\n // The set of all legal characters in alphanumeric mode,\n // where each character value maps to the index in the string.\n _QrSegment.ALPHANUMERIC_CHARSET = \"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ $%*+-./:\";\n let QrSegment = _QrSegment;\n qrcodegen2.QrSegment = _QrSegment;\n})(qrcodegen || (qrcodegen = {}));\n((qrcodegen2) => {\n let QrCode;\n ((QrCode2) => {\n const _Ecc = class _Ecc {\n // The QR Code can tolerate about 30% erroneous codewords\n /*-- Constructor and fields --*/\n constructor(ordinal, formatBits) {\n this.ordinal = ordinal;\n this.formatBits = formatBits;\n }\n };\n /*-- Constants --*/\n _Ecc.LOW = new _Ecc(0, 1);\n // The QR Code can tolerate about 7% erroneous codewords\n _Ecc.MEDIUM = new _Ecc(1, 0);\n // The QR Code can tolerate about 15% erroneous codewords\n _Ecc.QUARTILE = new _Ecc(2, 3);\n // The QR Code can tolerate about 25% erroneous codewords\n _Ecc.HIGH = new _Ecc(3, 2);\n let Ecc = _Ecc;\n QrCode2.Ecc = _Ecc;\n })(QrCode = qrcodegen2.QrCode || (qrcodegen2.QrCode = {}));\n})(qrcodegen || (qrcodegen = {}));\n((qrcodegen2) => {\n let QrSegment;\n ((QrSegment2) => {\n const _Mode = class _Mode {\n /*-- Constructor and fields --*/\n constructor(modeBits, numBitsCharCount) {\n this.modeBits = modeBits;\n this.numBitsCharCount = numBitsCharCount;\n }\n /*-- Method --*/\n // (Package-private) Returns the bit width of the character count field for a segment in\n // this mode in a QR Code at the given version number. The result is in the range [0, 16].\n numCharCountBits(ver) {\n return this.numBitsCharCount[Math.floor((ver + 7) / 17)];\n }\n };\n /*-- Constants --*/\n _Mode.NUMERIC = new _Mode(1, [10, 12, 14]);\n _Mode.ALPHANUMERIC = new _Mode(2, [9, 11, 13]);\n _Mode.BYTE = new _Mode(4, [8, 16, 16]);\n _Mode.KANJI = new _Mode(8, [8, 10, 12]);\n _Mode.ECI = new _Mode(7, [0, 0, 0]);\n let Mode = _Mode;\n QrSegment2.Mode = _Mode;\n })(QrSegment = qrcodegen2.QrSegment || (qrcodegen2.QrSegment = {}));\n})(qrcodegen || (qrcodegen = {}));\nvar qrcodegen_default = qrcodegen;\n\n// src/index.tsx\n/**\n * @license qrcode.react\n * Copyright (c) Paul O'Shannessy\n * SPDX-License-Identifier: ISC\n */\nvar ERROR_LEVEL_MAP = {\n L: qrcodegen_default.QrCode.Ecc.LOW,\n M: qrcodegen_default.QrCode.Ecc.MEDIUM,\n Q: qrcodegen_default.QrCode.Ecc.QUARTILE,\n H: qrcodegen_default.QrCode.Ecc.HIGH\n};\nvar DEFAULT_SIZE = 128;\nvar DEFAULT_LEVEL = \"L\";\nvar DEFAULT_BGCOLOR = \"#FFFFFF\";\nvar DEFAULT_FGCOLOR = \"#000000\";\nvar DEFAULT_INCLUDEMARGIN = false;\nvar DEFAULT_MINVERSION = 1;\nvar SPEC_MARGIN_SIZE = 4;\nvar DEFAULT_MARGIN_SIZE = 0;\nvar DEFAULT_IMG_SCALE = 0.1;\nfunction generatePath(modules, margin = 0) {\n const ops = [];\n modules.forEach(function(row, y) {\n let start = null;\n row.forEach(function(cell, x) {\n if (!cell && start !== null) {\n ops.push(\n `M${start + margin} ${y + margin}h${x - start}v1H${start + margin}z`\n );\n start = null;\n return;\n }\n if (x === row.length - 1) {\n if (!cell) {\n return;\n }\n if (start === null) {\n ops.push(`M${x + margin},${y + margin} h1v1H${x + margin}z`);\n } else {\n ops.push(\n `M${start + margin},${y + margin} h${x + 1 - start}v1H${start + margin}z`\n );\n }\n return;\n }\n if (cell && start === null) {\n start = x;\n }\n });\n });\n return ops.join(\"\");\n}\nfunction excavateModules(modules, excavation) {\n return modules.slice().map((row, y) => {\n if (y < excavation.y || y >= excavation.y + excavation.h) {\n return row;\n }\n return row.map((cell, x) => {\n if (x < excavation.x || x >= excavation.x + excavation.w) {\n return cell;\n }\n return false;\n });\n });\n}\nfunction getImageSettings(cells, size, margin, imageSettings) {\n if (imageSettings == null) {\n return null;\n }\n const numCells = cells.length + margin * 2;\n const defaultSize = Math.floor(size * DEFAULT_IMG_SCALE);\n const scale = numCells / size;\n const w = (imageSettings.width || defaultSize) * scale;\n const h = (imageSettings.height || defaultSize) * scale;\n const x = imageSettings.x == null ? cells.length / 2 - w / 2 : imageSettings.x * scale;\n const y = imageSettings.y == null ? cells.length / 2 - h / 2 : imageSettings.y * scale;\n const opacity = imageSettings.opacity == null ? 1 : imageSettings.opacity;\n let excavation = null;\n if (imageSettings.excavate) {\n let floorX = Math.floor(x);\n let floorY = Math.floor(y);\n let ceilW = Math.ceil(w + x - floorX);\n let ceilH = Math.ceil(h + y - floorY);\n excavation = { x: floorX, y: floorY, w: ceilW, h: ceilH };\n }\n const crossOrigin = imageSettings.crossOrigin;\n return { x, y, h, w, excavation, opacity, crossOrigin };\n}\nfunction getMarginSize(includeMargin, marginSize) {\n if (marginSize != null) {\n return Math.max(Math.floor(marginSize), 0);\n }\n return includeMargin ? SPEC_MARGIN_SIZE : DEFAULT_MARGIN_SIZE;\n}\nfunction useQRCode({\n value,\n level,\n minVersion,\n includeMargin,\n marginSize,\n imageSettings,\n size,\n boostLevel\n}) {\n let qrcode = React.useMemo(() => {\n const values = Array.isArray(value) ? value : [value];\n const segments = values.reduce((accum, v) => {\n accum.push(...qrcodegen_default.QrSegment.makeSegments(v));\n return accum;\n }, []);\n return qrcodegen_default.QrCode.encodeSegments(\n segments,\n ERROR_LEVEL_MAP[level],\n minVersion,\n void 0,\n void 0,\n boostLevel\n );\n }, [value, level, minVersion, boostLevel]);\n const { cells, margin, numCells, calculatedImageSettings } = React.useMemo(() => {\n let cells2 = qrcode.getModules();\n const margin2 = getMarginSize(includeMargin, marginSize);\n const numCells2 = cells2.length + margin2 * 2;\n const calculatedImageSettings2 = getImageSettings(\n cells2,\n size,\n margin2,\n imageSettings\n );\n return {\n cells: cells2,\n margin: margin2,\n numCells: numCells2,\n calculatedImageSettings: calculatedImageSettings2\n };\n }, [qrcode, size, imageSettings, includeMargin, marginSize]);\n return {\n qrcode,\n margin,\n cells,\n numCells,\n calculatedImageSettings\n };\n}\nvar SUPPORTS_PATH2D = function() {\n try {\n new Path2D().addPath(new Path2D());\n } catch (e) {\n return false;\n }\n return true;\n}();\nvar QRCodeCanvas = React.forwardRef(\n function QRCodeCanvas2(props, forwardedRef) {\n const _a = props, {\n value,\n size = DEFAULT_SIZE,\n level = DEFAULT_LEVEL,\n bgColor = DEFAULT_BGCOLOR,\n fgColor = DEFAULT_FGCOLOR,\n includeMargin = DEFAULT_INCLUDEMARGIN,\n minVersion = DEFAULT_MINVERSION,\n boostLevel,\n marginSize,\n imageSettings\n } = _a, extraProps = __objRest(_a, [\n \"value\",\n \"size\",\n \"level\",\n \"bgColor\",\n \"fgColor\",\n \"includeMargin\",\n \"minVersion\",\n \"boostLevel\",\n \"marginSize\",\n \"imageSettings\"\n ]);\n const _b = extraProps, { style } = _b, otherProps = __objRest(_b, [\"style\"]);\n const imgSrc = imageSettings == null ? void 0 : imageSettings.src;\n const _canvas = React.useRef(null);\n const _image = React.useRef(null);\n const setCanvasRef = React.useCallback(\n (node) => {\n _canvas.current = node;\n if (typeof forwardedRef === \"function\") {\n forwardedRef(node);\n } else if (forwardedRef) {\n forwardedRef.current = node;\n }\n },\n [forwardedRef]\n );\n const [isImgLoaded, setIsImageLoaded] = React.useState(false);\n const { margin, cells, numCells, calculatedImageSettings } = useQRCode({\n value,\n level,\n minVersion,\n boostLevel,\n includeMargin,\n marginSize,\n imageSettings,\n size\n });\n React.useEffect(() => {\n if (_canvas.current != null) {\n const canvas = _canvas.current;\n const ctx = canvas.getContext(\"2d\");\n if (!ctx) {\n return;\n }\n let cellsToDraw = cells;\n const image = _image.current;\n const haveImageToRender = calculatedImageSettings != null && image !== null && image.complete && image.naturalHeight !== 0 && image.naturalWidth !== 0;\n if (haveImageToRender) {\n if (calculatedImageSettings.excavation != null) {\n cellsToDraw = excavateModules(\n cells,\n calculatedImageSettings.excavation\n );\n }\n }\n const pixelRatio = window.devicePixelRatio || 1;\n canvas.height = canvas.width = size * pixelRatio;\n const scale = size / numCells * pixelRatio;\n ctx.scale(scale, scale);\n ctx.fillStyle = bgColor;\n ctx.fillRect(0, 0, numCells, numCells);\n ctx.fillStyle = fgColor;\n if (SUPPORTS_PATH2D) {\n ctx.fill(new Path2D(generatePath(cellsToDraw, margin)));\n } else {\n cells.forEach(function(row, rdx) {\n row.forEach(function(cell, cdx) {\n if (cell) {\n ctx.fillRect(cdx + margin, rdx + margin, 1, 1);\n }\n });\n });\n }\n if (calculatedImageSettings) {\n ctx.globalAlpha = calculatedImageSettings.opacity;\n }\n if (haveImageToRender) {\n ctx.drawImage(\n image,\n calculatedImageSettings.x + margin,\n calculatedImageSettings.y + margin,\n calculatedImageSettings.w,\n calculatedImageSettings.h\n );\n }\n }\n });\n React.useEffect(() => {\n setIsImageLoaded(false);\n }, [imgSrc]);\n const canvasStyle = __spreadValues({ height: size, width: size }, style);\n let img = null;\n if (imgSrc != null) {\n img = /* @__PURE__ */ React.createElement(\n \"img\",\n {\n src: imgSrc,\n key: imgSrc,\n style: { display: \"none\" },\n onLoad: () => {\n setIsImageLoaded(true);\n },\n ref: _image,\n crossOrigin: calculatedImageSettings == null ? void 0 : calculatedImageSettings.crossOrigin\n }\n );\n }\n return /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement(\n \"canvas\",\n __spreadValues({\n style: canvasStyle,\n height: size,\n width: size,\n ref: setCanvasRef,\n role: \"img\"\n }, otherProps)\n ), img);\n }\n);\nQRCodeCanvas.displayName = \"QRCodeCanvas\";\nvar QRCodeSVG = React.forwardRef(\n function QRCodeSVG2(props, forwardedRef) {\n const _a = props, {\n value,\n size = DEFAULT_SIZE,\n level = DEFAULT_LEVEL,\n bgColor = DEFAULT_BGCOLOR,\n fgColor = DEFAULT_FGCOLOR,\n includeMargin = DEFAULT_INCLUDEMARGIN,\n minVersion = DEFAULT_MINVERSION,\n boostLevel,\n title,\n marginSize,\n imageSettings\n } = _a, otherProps = __objRest(_a, [\n \"value\",\n \"size\",\n \"level\",\n \"bgColor\",\n \"fgColor\",\n \"includeMargin\",\n \"minVersion\",\n \"boostLevel\",\n \"title\",\n \"marginSize\",\n \"imageSettings\"\n ]);\n const { margin, cells, numCells, calculatedImageSettings } = useQRCode({\n value,\n level,\n minVersion,\n boostLevel,\n includeMargin,\n marginSize,\n imageSettings,\n size\n });\n let cellsToDraw = cells;\n let image = null;\n if (imageSettings != null && calculatedImageSettings != null) {\n if (calculatedImageSettings.excavation != null) {\n cellsToDraw = excavateModules(\n cells,\n calculatedImageSettings.excavation\n );\n }\n image = /* @__PURE__ */ React.createElement(\n \"image\",\n {\n href: imageSettings.src,\n height: calculatedImageSettings.h,\n width: calculatedImageSettings.w,\n x: calculatedImageSettings.x + margin,\n y: calculatedImageSettings.y + margin,\n preserveAspectRatio: \"none\",\n opacity: calculatedImageSettings.opacity,\n crossOrigin: calculatedImageSettings.crossOrigin\n }\n );\n }\n const fgPath = generatePath(cellsToDraw, margin);\n return /* @__PURE__ */ React.createElement(\n \"svg\",\n __spreadValues({\n height: size,\n width: size,\n viewBox: `0 0 ${numCells} ${numCells}`,\n ref: forwardedRef,\n role: \"img\"\n }, otherProps),\n !!title && /* @__PURE__ */ React.createElement(\"title\", null, title),\n /* @__PURE__ */ React.createElement(\n \"path\",\n {\n fill: bgColor,\n d: `M0,0 h${numCells}v${numCells}H0z`,\n shapeRendering: \"crispEdges\"\n }\n ),\n /* @__PURE__ */ React.createElement(\"path\", { fill: fgColor, d: fgPath, shapeRendering: \"crispEdges\" }),\n image\n );\n }\n);\nQRCodeSVG.displayName = \"QRCodeSVG\";\nexport {\n QRCodeCanvas,\n QRCodeSVG\n};\n","/**\n * Browser-side wire helpers for the /api/pair surface. Plain fetch over\n * same-origin /api (like the connection client); JSON bodies, string\n * responses for the error codes.\n */\n\n/** issue() response. */\nexport interface IssueResult {\n ok: true\n url: string\n token: string\n expiresAt: number\n /** Every constructible LAN base address (interface order). */\n lanAddresses: string[]\n /** The configured public (tunneled) base URL, when present. */\n publicBaseUrl?: string\n}\n\n/** issue() refusal: the server is not LAN-reachable. */\nexport interface IssueLanRequired {\n ok: false\n code: 'lan-required'\n}\n\n/** issue() refusal: the requested LAN address is not constructible. */\nexport interface IssueUnknownAddress {\n ok: false\n code: 'unknown-address'\n}\n\n/** issue() refusal: the loopback-only fence rejected this origin. */\nexport interface IssueLoopbackRequired {\n ok: false\n code: 'forbidden'\n}\n\nexport type IssueResponse = IssueResult | IssueLanRequired | IssueUnknownAddress | IssueLoopbackRequired\n\n/** Public policy fields returned by the pairing status endpoint. */\nexport interface PairGatePolicy {\n requirePairingForLan: boolean\n}\n\n/** Read the host-authoritative desktop pairing policy. */\nexport async function readPairGatePolicy(): Promise<PairGatePolicy> {\n const response = await fetch('/api/pair/status')\n if (!response.ok) throw new Error(`remote-web-ui: status failed with ${String(response.status)}`)\n const value = await response.json() as { requirePairingForLan?: unknown }\n if (typeof value.requirePairingForLan !== 'boolean') {\n throw new Error('remote-web-ui: status omitted requirePairingForLan')\n }\n return { requirePairingForLan: value.requirePairingForLan }\n}\n\n/** accept() refusal codes. */\nexport type AcceptFailure = { ok: false; code: 'invalid' | 'used' | 'forbidden' }\n\n/** One auto-tunnel status frame (absent while the feature is off). */\nexport interface TunnelStatusFrame {\n state: 'starting' | 'running' | 'failed'\n url?: string\n error?: string\n}\n\n/** One relay-registry status frame (absent while the relay is not in play). */\nexport interface RelayStatusFrame {\n state: 'off' | 'registering' | 'running' | 'failed'\n /** The stable relay origin, once registered. */\n url?: string\n /** Human-readable failure detail of the last sync attempt. */\n error?: string\n}\n\n/** One /api posture frame (host half probe; see src/posture.ts). */\nexport interface PostureFrame {\n checkedAt: number\n hosts: { host: string; exposed: boolean }[]\n}\n\n/** One /api/pair/events frame. */\nexport interface PairStateFrame {\n type: 'state'\n phase: 'lan-required' | 'stopped' | 'waiting' | 'connected' | 'disconnected'\n lanAvailable: boolean\n tokenId?: string\n tokenExpiresAt?: number\n deviceCount: number\n onlineCount: number\n /** Per-device roster (loopback events only). */\n devices?: DeviceFrame[]\n /** Auto-tunnel status, while the auto-tunnel feature is active. */\n tunnel?: TunnelStatusFrame\n /** Relay-registry status, while the stable-origin relay is in play. */\n relay?: RelayStatusFrame\n /** Latest /api fence posture probe, once a round has completed. */\n posture?: PostureFrame\n}\n\n/** One authorized-device row from the loopback status stream. */\nexport interface DeviceFrame {\n id: string\n createdAt: number\n lastSeenAt: number\n online: boolean\n userAgent?: string\n}\n\n/**\n * Mint a fresh pairing token (one active token at a time — this invalidates\n * any previous link).\n * @param address - optional LAN IP literal the QR must be built from (the\n * default is the first interface); unknown literals refuse with\n * 'unknown-address'.\n * @returns the issued link, the lan-required refusal (server never bound\n * 0.0.0.0), or the forbidden refusal (the loopback-only fence rejected this\n * origin — the panel is a desktop control endpoint).\n */\nexport async function issuePair(address?: string): Promise<IssueResponse> {\n const response = await fetch('/api/pair/issue', {\n method: 'POST',\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify({\n ...(address !== undefined ? { address } : {}),\n }),\n })\n if (!response.ok) {\n if (response.status === 409) return { ok: false, code: 'lan-required' }\n if (response.status === 403) return { ok: false, code: 'forbidden' }\n if (response.status === 400) return { ok: false, code: 'unknown-address' }\n throw new Error(`remote-web-ui: issue failed with ${String(response.status)}`)\n }\n return await response.json() as IssueResult\n}\n\n/**\n * Accept a pairing token (the phone's first open of the QR link). Success\n * sets the device cookie; the page then reloads to boot with it.\n * @param token - the token from the URL.\n * @returns the wire result.\n */\nexport async function acceptPair(token: string): Promise<{ ok: true } | AcceptFailure> {\n const response = await fetch('/api/pair/accept', {\n method: 'POST',\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify({ token }),\n })\n if (response.ok) return { ok: true }\n if (response.status === 404) return { ok: false, code: 'invalid' }\n if (response.status === 409) return { ok: false, code: 'used' }\n return { ok: false, code: 'forbidden' }\n}\n\n/** Revoke mobile access (paired devices + the current token). */\nexport async function stopPair(): Promise<void> {\n const response = await fetch('/api/pair/stop', { method: 'POST' })\n if (!response.ok) throw new Error(`remote-web-ui: stop failed with ${String(response.status)}`)\n}\n\n/**\n * Revoke one paired device from the loopback panel.\n * @param deviceId - the session id of the row to drop.\n */\nexport async function revokePair(deviceId: string): Promise<void> {\n const response = await fetch('/api/pair/revoke', {\n method: 'POST',\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify({ deviceId }),\n })\n if (response.status === 404) return\n if (!response.ok) throw new Error(`remote-web-ui: revoke failed with ${String(response.status)}`)\n}\n\n/** Presence heartbeat from a paired phone (unpaired heartbeats 401 harmlessly). */\nexport async function sendHeartbeat(): Promise<void> {\n await fetch('/api/pair/heartbeat', { method: 'POST' })\n}\n\n/** Whether the current page URL carries a pairing token. */\nexport function readPairParams(search: string): { pair?: string } {\n const params = new URLSearchParams(search)\n const pair = params.get('pair')\n return pair !== null && pair !== '' ? { pair } : {}\n}\n\n/**\n * Strip one query parameter from the current URL without reloading.\n * @param name - the parameter to remove.\n * @returns the new search string ('' when empty).\n */\nexport function stripParam(name: string): string {\n const url = new URL(window.location.href)\n url.searchParams.delete(name)\n return url.search\n}\n\n/** LAN-bind status frame from the loopback-only card endpoint. */\nexport interface LanBindFrame {\n profile: string\n /** The config toggle: true/false once flipped, null while untouched. */\n setting: boolean | null\n /** The bind default the managed patch block currently pins. */\n blockHost: string | null\n /** The live bind of the running web server. */\n bindHost: string\n port: number\n lanUrls: string[]\n firewall: { ok: boolean; managed: boolean; note?: string }\n platform: string\n /** true when the running bind has not caught up with the toggle yet. */\n pendingRestart?: boolean\n}\n\n/** Read the LAN-bind facts (loopback-only endpoint). */\nexport async function readLanBindStatus(): Promise<LanBindFrame> {\n const response = await fetch('/api/pair/lan-bind')\n if (!response.ok) throw new Error(`remote-web-ui: lan-bind status failed with ${String(response.status)}`)\n return await response.json() as LanBindFrame\n}\n\n/** Human-readable expiry clock, e.g. \"10:35\". */\nexport function formatClock(epochMs: number): string {\n const date = new Date(epochMs)\n const hours = String(date.getHours()).padStart(2, '0')\n const minutes = String(date.getMinutes()).padStart(2, '0')\n return `${hours}:${minutes}`\n}\n\n/** Calendar + clock for last-seen timestamps, e.g. \"2026-08-19 10:35\". */\nexport function formatLastSeen(epochMs: number): string {\n const date = new Date(epochMs)\n const year = String(date.getFullYear())\n const month = String(date.getMonth() + 1).padStart(2, '0')\n const day = String(date.getDate()).padStart(2, '0')\n return `${year}-${month}-${day} ${formatClock(epochMs)}`\n}\n\n/**\n * Copy text to the clipboard with a fallback for insecure contexts\n * (plain-HTTP LAN origins lack navigator.clipboard).\n * @param text - the text to copy.\n * @returns whether the copy succeeded.\n */\nexport async function copyText(text: string): Promise<boolean> {\n if (typeof navigator !== 'undefined' && navigator.clipboard !== undefined) {\n try {\n await navigator.clipboard.writeText(text)\n return true\n } catch {\n // fall through to the execCommand path\n }\n }\n try {\n const area = document.createElement('textarea')\n area.value = text\n area.style.position = 'fixed'\n area.style.opacity = '0'\n document.body.appendChild(area)\n area.select()\n const ok = document.execCommand('copy')\n area.remove()\n return ok\n } catch {\n return false\n }\n}\n","/** Derive a short, non-sensitive device label from a browser User-Agent. */\nexport function deviceNameFromUserAgent(userAgent?: string): string | undefined {\n if (userAgent === undefined || userAgent.trim() === '') return undefined\n\n const os = /Windows NT/i.test(userAgent)\n ? 'Windows'\n : /Android/i.test(userAgent)\n ? 'Android'\n : /iPhone|iPad|iPod/i.test(userAgent)\n ? 'iOS'\n : /Macintosh|Mac OS X/i.test(userAgent)\n ? 'macOS'\n : /Linux/i.test(userAgent)\n ? 'Linux'\n : undefined\n\n const browser = /Edg(?:A|iOS)?\\//i.test(userAgent)\n ? 'Edge'\n : /(?:OPR|Opera)\\//i.test(userAgent)\n ? 'Opera'\n : /(?:Chrome|CriOS)\\//i.test(userAgent)\n ? 'Chrome'\n : /(?:Firefox|FxiOS)\\//i.test(userAgent)\n ? 'Firefox'\n : /Safari\\//i.test(userAgent) && /Version\\//i.test(userAgent)\n ? 'Safari'\n : undefined\n\n if (os !== undefined && browser !== undefined) return `${os} · ${browser}`\n return os ?? browser\n}\n","/**\n * The mobile remote-control panel body: status card (state text + badge),\n * the QR code, the open-on-phone hint with the link text, and the three\n * actions (stop / refresh / copy). Pure presentation — all state and\n * actions arrive through props from the entry's behavior component.\n */\nimport clsx from 'clsx'\nimport { QRCodeSVG } from 'qrcode.react'\nimport {\n IconCloseOutline16, IconCopyOutline16, IconRefreshOutline16, IconStopFill16,\n} from '@deepseek-ai/dsh-client-ui-primitives'\nimport type { TranslateNS } from '@deepseek-ai/dsh-client-ui-slots'\nimport type { PairingPhase } from '../pairing.ts'\nimport {\n formatClock,\n formatLastSeen,\n type DeviceFrame,\n type PostureFrame,\n type RelayStatusFrame,\n type TunnelStatusFrame,\n} from './pair-api.ts'\nimport { deviceNameFromUserAgent } from './device-name.ts'\nimport css from './remote.module.css'\n\n/** The panel's view state, owned by the entry component. */\nexport type PanelState =\n | { kind: 'lan-required'; tunnel?: TunnelStatusFrame }\n | { kind: 'loopback-required' }\n | { kind: 'unreachable' }\n | {\n kind: 'ready'\n url: string\n expiresAt: number\n expired: boolean\n phase: PairingPhase\n deviceCount: number\n onlineCount: number\n /** Authorized devices for the roster under the QR card. */\n devices: DeviceFrame[]\n /** The LAN literal the current QR was built from. */\n address: string\n /** Every constructible LAN literal (interface order). */\n lanAddresses: string[]\n /** The active pairing token itself (useful in Docker/reverse proxy topologies). */\n token?: string\n /** Whether this QR is built on the configured public (tunneled) base. */\n public: boolean\n /** The configured public (tunneled) base URL, when present. */\n publicBaseUrl?: string\n /** Auto-tunnel status, while the auto-tunnel feature is active. */\n tunnel?: TunnelStatusFrame\n /** Relay-registry status, while the stable-origin relay is in play. */\n relay?: RelayStatusFrame\n /** Latest /api posture probe, once a round has completed. */\n posture?: PostureFrame\n }\n\n/** Full panel props: copy + view state + actions. */\nexport interface RemotePanelProps {\n t: TranslateNS<'remote'>\n state: PanelState\n copied: boolean\n copiedToken?: boolean\n onClose(): void\n onStop(): void\n onRefresh(): void\n onCopy(url: string): void\n onCopyToken?(token: string): void\n /** Re-mint the QR against a different LAN address. */\n onPickAddress(address: string): void\n /** Re-mint the QR against the configured public (tunneled) base. */\n onPickPublic(): void\n /** Revoke one paired device. */\n onRevoke(deviceId: string): void\n}\n\n/** Badge text + tone per phase (ready states only). */\nfunction statusOf(\n t: TranslateNS<'remote'>,\n state: Extract<PanelState, { kind: 'ready' }>,\n): { text: string; tone: 'waiting' | 'connected' | 'disconnected' | 'stopped' } {\n switch (state.phase) {\n case 'connected': return { text: t('status.connected', { n: state.onlineCount }), tone: 'connected' }\n case 'disconnected': return { text: t('status.disconnected'), tone: 'disconnected' }\n case 'stopped': return { text: t('status.stopped'), tone: 'stopped' }\n case 'lan-required': return { text: t('status.lanRequired'), tone: 'stopped' }\n case 'waiting': return { text: t('status.waiting'), tone: 'waiting' }\n }\n}\n\n/**\n * Render the pairing panel.\n * @param props - copy, state, and actions.\n * @returns the panel element tree.\n */\nexport function RemotePanel({\n t,\n state,\n copied,\n copiedToken,\n onClose,\n onStop,\n onRefresh,\n onCopy,\n onCopyToken,\n onPickAddress,\n onPickPublic,\n onRevoke,\n}: RemotePanelProps) {\n return (\n <div className={css.panel} role=\"dialog\" aria-modal=\"true\" aria-label={t('title')}>\n <div className={css.header}>\n <div className={css.heading}>\n <h2 className={css.title}>{t('title')}</h2>\n <p className={css.subtitle}>{t('subtitle')}</p>\n </div>\n <button type=\"button\" className={css.close} aria-label={t('close.label')} onClick={onClose}>\n <IconCloseOutline16 size={14} />\n </button>\n </div>\n\n {state.kind === 'lan-required' ? (\n <div className={css.banner} role=\"alert\">\n <p className={css.bannerTitle}>{t('status.lanRequired')}</p>\n <p className={css.bannerHint}>{t('status.lanRequiredHint')}</p>\n </div>\n ) : state.kind === 'loopback-required' ? (\n <div className={css.banner} role=\"alert\">\n <p className={css.bannerTitle}>{t('status.loopbackRequired')}</p>\n <p className={css.bannerHint}>{t('status.loopbackRequiredHint')}</p>\n </div>\n ) : state.kind === 'unreachable' ? (\n <div className={css.banner} role=\"alert\">\n <p className={css.bannerTitle}>{t('status.unreachable')}</p>\n <p className={css.bannerHint}>{t('status.unreachableHint')}</p>\n </div>\n ) : (\n <>\n {state.posture !== undefined && state.posture.hosts.some(host => host.exposed) && (\n <div className={css.banner} role=\"alert\">\n <p className={css.bannerTitle}>{t('posture.exposed')}</p>\n <p className={css.bannerHint}>\n {t('posture.exposedHint', { hosts: state.posture.hosts.filter(host => host.exposed).map(host => host.host).join(', ') })}\n </p>\n </div>\n )}\n <div className={css.card}>\n <div className={css.cardHeader}>\n <span className={css.cardTitle}>{t('card.title')}</span>\n <span className={css.badges}>\n {state.public && <span className={clsx(css.badge, css.badgePublic)}>{t('public.badge')}</span>}\n <span className={clsx(css.badge, css[`badge-${statusOf(t, state).tone}`])}>\n {statusOf(t, state).text}\n </span>\n </span>\n </div>\n <div className={css.qrWrap} data-testid=\"remote-qr\">\n <QRCodeSVG value={state.url} size={184} level=\"M\" marginSize={1} className={css.qr} />\n </div>\n {state.expired\n ? <p className={css.expired}>{t('pair.expired')}</p>\n : <p className={css.expiry}>{t('pair.expires', { time: formatClock(state.expiresAt) })}</p>}\n </div>\n\n <p className={css.hint}>{state.public ? t('pair.publicHint') : t('pair.hint')}</p>\n <div className={css.pairLinks}>\n <div className={css.pairLinkRow}>\n <div className={css.pairLinkText}>\n <span className={css.pairLinkLabel}>{t('pair.linkLabel')}</span>\n <code className={css.link} title={state.url}>{state.url}</code>\n </div>\n <button type=\"button\" className={css.copyLink} onClick={() => onCopy(state.url)}>\n <IconCopyOutline16 size={14} />\n {copied ? t('action.copied') : t('action.copyLink')}\n </button>\n </div>\n {state.token !== undefined && state.token !== '' && (\n <div className={css.pairLinkRow}>\n <div className={css.pairLinkText}>\n <span className={css.pairLinkLabel}>{t('pair.tokenLabel')}</span>\n <code className={css.link} title={state.token}>{state.token}</code>\n </div>\n <button\n type=\"button\"\n className={css.copyLink}\n onClick={() => onCopyToken ? onCopyToken(state.token!) : onCopy(state.token!)}\n >\n <IconCopyOutline16 size={14} />\n {copiedToken ? t('action.copiedToken') : t('action.copyToken')}\n </button>\n </div>\n )}\n </div>\n <p className={css.oneTimeHint}>\n {t('pair.oneTimeHint')} {t('pair.dockerHint')}\n </p>\n {state.phase === 'stopped' && <p className={css.stoppedHint}>{t('stopped.hint')}</p>}\n {state.tunnel !== undefined && state.tunnel.state !== 'running' && (\n <p className={state.tunnel.state === 'failed' ? css.tunnelFailed : css.tunnelNote} role=\"status\">\n {state.tunnel.state === 'failed'\n ? t('tunnel.failed', { error: state.tunnel.error ?? t('tunnel.unknownError') })\n : t('tunnel.starting')}\n </p>\n )}\n {state.relay?.state === 'registering' && (\n <p className={css.tunnelNote} role=\"status\">{t('relay.registering')}</p>\n )}\n {state.relay?.state === 'failed' && (\n <p className={css.tunnelFailed} role=\"status\">\n {t('relay.failed', { error: state.relay.error ?? t('tunnel.unknownError') })}\n </p>\n )}\n\n {(state.publicBaseUrl !== undefined || state.lanAddresses.length > 1) && (\n <fieldset className={css.addresses}>\n <legend>{t('address.label')}</legend>\n {state.publicBaseUrl !== undefined && (\n <label key=\"public\" className={css.address}>\n <input\n type=\"radio\"\n name=\"lan-address\"\n aria-label={t('address.public')}\n checked={state.public}\n onChange={onPickPublic}\n />\n <span>{t('address.public')}</span>\n <code className={css.addressValue}>{state.publicBaseUrl}</code>\n </label>\n )}\n {state.lanAddresses.map(address => (\n <label key={address} className={css.address}>\n <input\n type=\"radio\"\n name=\"lan-address\"\n aria-label={address}\n checked={!state.public && address === state.address}\n onChange={() => onPickAddress(address)}\n />\n <span>{t('address.lan')}</span>\n <code className={css.addressValue}>{address}</code>\n </label>\n ))}\n <p className={css.addressHint}>{t('address.hint')}</p>\n </fieldset>\n )}\n\n <div className={css.actions}>\n <button type=\"button\" className={css.action} onClick={onStop}>\n <IconStopFill16 size={14} />\n {t('action.stop')}\n </button>\n <button type=\"button\" className={css.action} onClick={onRefresh}>\n <IconRefreshOutline16 size={14} />\n {t('action.refresh')}\n </button>\n </div>\n\n <section className={css.devices} data-testid=\"remote-devices\" aria-label={t('devices.title')}>\n <h3 className={css.devicesTitle}>{t('devices.title')}</h3>\n {state.devices.length === 0 ? (\n <p className={css.devicesEmpty}>{t('devices.empty')}</p>\n ) : (\n <ul className={css.deviceList}>\n {state.devices.map(device => (\n <li key={device.id} className={css.deviceRow}>\n <div className={css.deviceMeta}>\n <span className={css.deviceName}>\n {deviceNameFromUserAgent(device.userAgent) ?? t('devices.unknown')}\n </span>\n <span className={clsx(css.devicePresence, device.online ? css.deviceOnline : css.deviceOffline)}>\n {device.online ? t('devices.online') : t('devices.offline')}\n </span>\n <span className={css.deviceSeen}>\n {t('devices.lastSeen', { time: formatLastSeen(device.lastSeenAt) })}\n </span>\n </div>\n <button\n type=\"button\"\n className={css.deviceRevoke}\n aria-label={t('devices.revoke.label')}\n onClick={() => { onRevoke(device.id) }}\n >\n {t('devices.revoke')}\n </button>\n </li>\n ))}\n </ul>\n )}\n </section>\n </>\n )}\n </div>\n )\n}\n","/**\n * Phone glyph for the sidebar remote-control trigger. Not part of the\n * shared icon set (ui-primitives has no phone icon); matches the outline\n * style with currentColor strokes.\n */\n\n/** Icon props mirroring ui-primitives' IconProps. */\nexport interface PhoneIconProps {\n /** Glyph size in px (default 16). */\n size?: number\n /** Extra class for layout placement. */\n className?: string\n}\n\n/**\n * Render the phone icon.\n * @param props - size and optional class.\n * @returns the svg element.\n */\nexport function PhoneIcon({ size = 16, className }: PhoneIconProps) {\n return (\n <svg width={size} height={size} className={className} viewBox=\"0 0 16 16\" fill=\"none\" aria-hidden=\"true\">\n <path\n d=\"M4.2 1.8h2.4l.9 2.4-1.5 1.1a7.4 7.4 0 0 0 4.7 4.7l1.1-1.5 2.4.9v2.4a.9.9 0 0 1-1 .9A11.4 11.4 0 0 1 3.3 2.8a.9.9 0 0 1 .9-1Z\"\n stroke=\"currentColor\"\n strokeWidth=\"1.3\"\n strokeLinejoin=\"round\"\n />\n </svg>\n )\n}\n","/**\n * Browser-side wire helpers for the /api/update surface. Plain fetch over\n * same-origin /api like the pairing client; the host half enforces the\n * loopback-only fence and owns the pnpm run.\n */\n\nimport type { UpdateRunResult, UpdateStatus } from '../update.ts'\n\n/**\n * Error thrown when the update status probe fails: carries the HTTP status\n * so the panel can tell \"the update route is not mounted\" (404 — the host\n * process runs an older plugin build) apart from real network failures.\n */\nexport class UpdateStatusError extends Error {\n /** HTTP status of the failed response (0 when the fetch never returned). */\n readonly status: number\n constructor(status: number) {\n super('update status unavailable (HTTP ' + String(status) + ')')\n this.status = status\n }\n}\n\n/**\n * Probe the update status: install mode, owning profile, and the\n * current-vs-latest comparison for every family package.\n * @returns the status snapshot.\n */\nexport async function fetchUpdateStatus(): Promise<UpdateStatus> {\n let response: Response\n try {\n response = await fetch('/api/update/status')\n } catch {\n // Network-level failure: nothing came back at all.\n throw new UpdateStatusError(0)\n }\n if (!response.ok) throw new UpdateStatusError(response.status)\n return await response.json() as UpdateStatus\n}\n\n/**\n * Run the update (pnpm update in the owning profile). Blocks until pnpm\n * exits — the panel shows an in-flight state meanwhile.\n * @returns the run outcome.\n */\nexport async function runUpdate(): Promise<UpdateRunResult> {\n const response = await fetch('/api/update/run', { method: 'POST' })\n if (!response.ok) throw new Error('update run unavailable')\n return await response.json() as UpdateRunResult\n}\n","/**\n * The update panel body: check progress, version comparison, the\n * auto-update in-flight state, and the outcome (restart hint on success,\n * translated failure on error). Pure presentation — all state arrives\n * through props from the entry behavior component.\n */\nimport type { TranslateNS } from '@deepseek-ai/dsh-client-ui-slots'\nimport { IconCloseOutline16, IconRefreshOutline16 } from '@deepseek-ai/dsh-client-ui-primitives'\nimport type { UpdateReleaseNotes, UpdateRunResult, UpdateStatus } from '../update.ts'\nimport css from \"./remote.module.css\"\n\n/** The panel view state, owned by the entry component. */\nexport type UpdateView =\n | { kind: 'checking' }\n | { kind: 'result'; status: UpdateStatus }\n | { kind: 'updating'; status: UpdateStatus }\n | { kind: 'done'; result: UpdateRunResult }\n | { kind: 'error'; message: string; detail?: string }\n\n/** Full panel props: copy + view state + actions. */\nexport interface UpdatePanelProps {\n t: TranslateNS<'remote'>\n view: UpdateView\n onClose(): void\n /** Re-run the check from a terminal state. */\n onRecheck(): void\n /** Start the update from the result view (the confirmation step, #507). */\n onStartUpdate(status: UpdateStatus): void\n}\n\n/** The anchor package name (aggregate first) for copy purposes. */\nfunction anchorName(status: UpdateStatus | undefined): string | undefined {\n return status?.anchor ?? status?.packages[0]?.name\n}\n\n/** The latest npm release of the anchor, for reference copy. */\nfunction anchorLatest(status: UpdateStatus | undefined): string | undefined {\n return status?.packages[0]?.latest\n}\n\n/**\n * Render the update panel.\n * @param props - copy, view state, and actions.\n * @returns the panel element tree.\n */\nexport function UpdatePanel({ t, view, onClose, onRecheck, onStartUpdate }: UpdatePanelProps) {\n const status = view.kind === \"result\" || view.kind === \"updating\" ? view.status : undefined\n const title = view.kind === \"done\" && view.result.ok ? t(\"update.done\") : t(\"update.title\")\n const subtitle = subtitleOf(t, view)\n return (\n <div className={css.panel} role=\"dialog\" aria-modal=\"true\" aria-label={title}>\n <div className={css.header}>\n <div className={css.heading}>\n <h2 className={css.title}>{title}</h2>\n {subtitle !== undefined && <p className={css.subtitle}>{subtitle}</p>}\n </div>\n <button type=\"button\" className={css.close} aria-label={t(\"update.close\")} onClick={onClose}>\n <IconCloseOutline16 />\n </button>\n </div>\n {view.kind === \"checking\" && <p className={css.updateStatus}>{t(\"update.checking\")}</p>}\n {view.kind === \"result\" && status !== undefined && <ResultBody t={t} status={status} />}\n {view.kind === \"result\" && status !== undefined && status.mode === \"npm\" && status.outdated && status.error === undefined && (\n <div className={css.updateActions}>\n <button type=\"button\" className={css.updateRetry} onClick={() => onStartUpdate(status)}>\n {t(\"update.start\")}\n </button>\n </div>\n )}\n {view.kind === \"updating\" && status !== undefined && (\n <div>\n <p className={css.updateStatus}>\n {t(\"update.updating\", { name: anchorName(status) ?? \"\", version: anchorLatest(status) ?? \"\" })}\n </p>\n <p className={css.updateDetail}>{t(\"update.cooldownNotice\")}</p>\n <PackageSummary t={t} status={status} />\n </div>\n )}\n {view.kind === \"done\" && <DoneBody t={t} result={view.result} />}\n {view.kind === \"error\" && (\n <div>\n <p className={css.updateError}>{view.message}</p>\n {view.detail !== undefined && <pre className={css.updateOutput}>{view.detail}</pre>}\n </div>\n )}\n {(view.kind === \"done\" || view.kind === \"error\") && (\n <div className={css.updateActions}>\n <button type=\"button\" className={css.updateRetry} onClick={onRecheck}>\n <IconRefreshOutline16 /> {t(\"update.retry\")}\n </button>\n </div>\n )}\n </div>\n )\n}\n\n/** The subtitle copy per view state (absent on plain results). */\nfunction subtitleOf(t: TranslateNS<\"remote\">, view: UpdateView): string | undefined {\n switch (view.kind) {\n case \"checking\":\n return t(\"update.checking\")\n case \"updating\":\n return t(\"update.updatingTitle\")\n case \"result\":\n return undefined\n case \"done\":\n return view.result.ok ? t(\"update.doneDetail\") : t(\"update.error\")\n case \"error\":\n // The error body below carries the message; no subtitle duplication.\n return undefined\n }\n}\n\n/** The checked result body: mode banner + version list. */\nfunction ResultBody({ t, status }: { t: TranslateNS<\"remote\">; status: UpdateStatus }) {\n const anchor = anchorName(status)\n const latest = anchorLatest(status)\n if (status.mode === \"link\") {\n return (\n <div>\n <p className={css.updateStatus}>{t(\"update.linkMode\")}</p>\n <p className={css.updateDetail}>{t(\"update.linkModeDetail\", { version: latest ?? \"-\" })}</p>\n </div>\n )\n }\n if (status.mode === \"missing\") {\n return (\n <div>\n <p className={css.updateStatus}>{t(\"update.missing\")}</p>\n <p className={css.updateDetail}>{t(\"update.missingDetail\")}</p>\n </div>\n )\n }\n if (status.error === \"registry-unreachable\") {\n return (\n <div>\n <p className={css.updateStatus}>{t(\"update.offline\")}</p>\n <p className={css.updateDetail}>{t(\"update.offlineDetail\")}</p>\n </div>\n )\n }\n if (status.outdated) {\n return (\n <div>\n <p className={css.updateStatus}>{t(\"update.found\")}</p>\n <p className={css.updateDetail}>\n {anchor !== undefined ? t(\"update.foundDetail\", { name: anchor, version: latest ?? \"\" }) : \"\"}\n </p>\n <p className={css.updateDetail}>{t(\"update.cooldownNotice\")}</p>\n <PackageSummary t={t} status={status} />\n </div>\n )\n }\n return (\n <div>\n <p className={css.updateStatus}>{t(\"update.upToDate\")}</p>\n {anchor !== undefined && latest !== undefined && (\n <p className={css.updateDetail}>{t(\"update.upToDateDetail\", { name: anchor, version: latest })}</p>\n )}\n <PackageSummary t={t} status={status} />\n </div>\n )\n}\n\n/** Release-note summary when available; otherwise fall back to the package list. */\nfunction PackageSummary({ t, status }: { t: TranslateNS<'remote'>; status: UpdateStatus }) {\n if (status.notes === undefined) return <PackageList status={status} />\n return (\n <div>\n <ReleaseNotes t={t} notes={status.notes} />\n <details className={css.updateVersions}>\n <summary className={css.updateVersionsSummary}>{t(\"update.componentVersions\")}</summary>\n <PackageList status={status} />\n </details>\n </div>\n )\n}\n\n/** Render GitHub Release sections as a compact three-group list. */\nfunction ReleaseNotes({ t, notes }: { t: TranslateNS<'remote'>; notes: UpdateReleaseNotes }) {\n const sections = [\n { key: 'features', title: t(\"update.releaseFeatures\"), items: notes.features },\n { key: 'fixes', title: t(\"update.releaseFixes\"), items: notes.fixes },\n { key: 'other', title: t(\"update.releaseOther\"), items: notes.other },\n ].filter(section => section.items.length > 0)\n if (sections.length === 0) return <p className={css.updateDetail}>{t(\"update.releaseUnavailable\")}</p>\n return (\n <div className={css.updateNotes}>\n <h3 className={css.updateNotesTitle}>{t(\"update.releaseNotes\", { version: notes.version })}</h3>\n {sections.map(section => (\n <section key={section.key} className={css.updateNoteSection}>\n <h4 className={css.updateNoteHeading}>{section.title}</h4>\n <ul className={css.updateNoteList}>\n {section.items.map((item, index) => (\n <li key={index} className={css.updateNoteItem}>{item}</li>\n ))}\n </ul>\n </section>\n ))}\n </div>\n )\n}\n\n/** The per-package current → latest comparison list. */\nfunction PackageList({ status }: { status: UpdateStatus }) {\n if (status.packages.length === 0) return null\n return (\n <ul className={css.updateList}>\n {status.packages.map(packageStatus => (\n <li key={packageStatus.name} className={css.updateListItem}>\n <span className={css.updateListName}>{packageStatus.name}</span>\n <span className={css.updateListVersions}>\n {packageStatus.current}\n {packageStatus.latest !== undefined && packageStatus.latest !== packageStatus.current && (\n <> → {packageStatus.latest}</>\n )}\n </span>\n </li>\n ))}\n </ul>\n )\n}\n\n/** The outcome body: success + restart hint, or the translated failure. */\nfunction DoneBody({ t, result }: { t: TranslateNS<\"remote\">; result: UpdateRunResult }) {\n if (result.ok) {\n // The title already reads \"Update complete\"; the body carries the details.\n return (\n <div>\n <p className={css.updateDetail}>{t(\"update.doneDetail\")}</p>\n <p className={css.updateDetail}>{t(\"update.restartHint\")}</p>\n </div>\n )\n }\n const message = errorMessageOf(t, result)\n return (\n <div>\n <p className={css.updateError}>{message}</p>\n {result.output.trim() !== \"\" && <pre className={css.updateOutput}>{result.output.trim()}</pre>}\n </div>\n )\n}\n\n/** Translate a structured failure code; fall back to the raw message. */\nfunction errorMessageOf(t: TranslateNS<\"remote\">, result: UpdateRunResult): string {\n switch (result.errorCode) {\n case \"pnpm-missing\": return t(\"update.error.pnpmMissing\")\n case \"timeout\": return t(\"update.error.timeout\")\n case \"not-found\": return t(\"update.error.notFound\")\n case \"link\": return t(\"update.error.link\")\n case \"pnpm-failed\": return t(\"update.error.pnpmFailed\", { code: String(result.exitCode ?? \"?\") })\n case \"stale\": return t(\"update.error.stale\")\n case \"verify-failed\": return t(\"update.error.verifyFailed\")\n default: return result.error ?? t(\"update.error.unknown\")\n }\n}\n","/**\n * The sidebar update seat: the download trigger beside the remote-control\n * trigger plus the update panel modal. Owns the flow — probe the registry\n * on open, show the result, and let the user start the update from the\n * result view (#507), then report the outcome (restart hint on success,\n * translated failure on error).\n * Component-local state per the client stack rules.\n */\nimport { useCallback, useEffect, useRef, useState } from \"react\"\nimport { createPortal } from \"react-dom\"\nimport type { TranslateNS } from '@deepseek-ai/dsh-client-ui-slots'\nimport { IconDownloadOutline16 } from '@deepseek-ai/dsh-client-ui-primitives'\nimport type { UpdateStatus } from '../update.ts'\nimport { fetchUpdateStatus, runUpdate, UpdateStatusError } from \"./update-api.ts\"\nimport { UpdatePanel, type UpdateView } from \"./UpdatePanel.tsx\"\nimport css from \"./remote.module.css\"\n\n/** Entry props: the sidebar column state + the standard locale seat. */\nexport interface UpdateEntryProps {\n /** Whether the sidebar renders wide content (false = 56px rail). */\n wide: boolean\n t: TranslateNS<'remote'>\n}\n\n/**\n * Render the update trigger and panel.\n * @param props - column state and locale seat.\n * @returns the entry element tree.\n */\nexport function UpdateEntry({ wide, t }: UpdateEntryProps) {\n const [open, setOpen] = useState(false)\n const [view, setView] = useState<UpdateView>({ kind: \"checking\" })\n const [updateAvailable, setUpdateAvailable] = useState(false)\n const runToken = useRef(0)\n const availabilityToken = useRef(0)\n const mounted = useRef(false)\n\n const probeAvailability = useCallback(async (): Promise<void> => {\n const token = ++availabilityToken.current\n try {\n const status = await fetchUpdateStatus()\n if (token === availabilityToken.current) {\n setUpdateAvailable(status.mode === \"npm\" && status.outdated)\n }\n } catch {\n if (token === availabilityToken.current) setUpdateAvailable(false)\n }\n }, [])\n\n const check = useCallback(async (): Promise<void> => {\n const availabilityCheck = ++availabilityToken.current\n setView({ kind: \"checking\" })\n let status: UpdateStatus\n try {\n status = await fetchUpdateStatus()\n } catch (error) {\n if (availabilityCheck === availabilityToken.current) setUpdateAvailable(false)\n // HTTP 404: the update route is not mounted — the host process runs an\n // older plugin build (client refreshed, host did not). Restarting dsh\n // web loads the new plugin; a plain network failure gets the generic\n // offline copy instead of a misleading \"cannot reach update source\".\n if (error instanceof UpdateStatusError && error.status === 404) {\n setView({ kind: \"error\", message: t(\"update.unmounted\"), detail: t(\"update.unmountedDetail\") })\n return\n }\n setView({ kind: \"error\", message: t(\"update.offline\"), detail: t(\"update.offlineDetail\") })\n return\n }\n if (availabilityCheck === availabilityToken.current) {\n setUpdateAvailable(status.mode === \"npm\" && status.outdated)\n }\n if (status.error === \"registry-unreachable\") {\n setView({ kind: \"result\", status })\n return\n }\n // Checking never starts an update by itself (#507): the result view\n // carries the confirmation button that calls startUpdate.\n setView({ kind: \"result\", status })\n }, [t])\n\n const startUpdate = useCallback(async (status: UpdateStatus): Promise<void> => {\n if (status.mode !== \"npm\" || !status.outdated) return\n setView({ kind: \"updating\", status })\n const token = ++runToken.current\n try {\n const result = await runUpdate()\n if (result.ok && mounted.current) setUpdateAvailable(false)\n if (token !== runToken.current) return\n setView({ kind: \"done\", result })\n } catch {\n if (token !== runToken.current) return\n setView({ kind: \"error\", message: t(\"update.error\"), detail: t(\"update.offlineDetail\") })\n }\n }, [t])\n\n const openPanel = useCallback((): void => {\n setOpen(true)\n void check()\n }, [check])\n\n const closePanel = useCallback((): void => {\n runToken.current++\n setOpen(false)\n }, [])\n\n // Check once after mount without opening the panel or starting an update.\n useEffect(() => {\n mounted.current = true\n void probeAvailability()\n return () => {\n mounted.current = false\n runToken.current++\n availabilityToken.current++\n }\n }, [probeAvailability])\n\n const updateLabel = updateAvailable ? t(\"update.availableLabel\") : t(\"update.label\")\n\n return (\n <>\n <button\n type=\"button\"\n className={css.trigger}\n data-wide={wide ? (updateAvailable ? \"wide\" : undefined) : \"rail\"}\n data-update-available={updateAvailable ? \"true\" : undefined}\n aria-label={updateLabel}\n aria-expanded={open}\n title={updateLabel}\n onClick={openPanel}\n >\n <IconDownloadOutline16 size={wide ? 16 : 18} />\n {updateAvailable && wide && (\n <span className={css.updateBadgeText}>{t(\"update.badge\")}</span>\n )}\n </button>\n {open && createPortal((\n <div className={css.overlay} role=\"presentation\">\n <div className={css.mask} aria-hidden=\"true\" onClick={closePanel} />\n <UpdatePanel t={t} view={view} onClose={closePanel} onRecheck={() => { void check() }} onStartUpdate={(status) => { void startUpdate(status) }} />\n </div>\n ), document.body)}\n </>\n )\n}\n","/**\n * The sidebar remote-control seat: the update trigger plus the phone-icon\n * trigger beside the settings button, and the pairing panel modal. Owns the\n * panel behavior — token minting on open, the status SSE subscription,\n * stop/refresh/copy — and renders the pure {@link RemotePanel} body. The\n * update seat (the dsh-web self-update flow) rides the same footer row,\n * rendered by {@link UpdateEntry}. Component-local state per the client\n * stack rules: nothing here survives remounts or crosses entries.\n */\nimport { useCallback, useEffect, useRef, useState } from 'react'\nimport { createPortal } from 'react-dom'\nimport type { PropsLocale } from '@deepseek-ai/dsh-client-ui-slots'\nimport type { PairingPhase } from '../pairing.ts'\nimport { RemotePanel, type PanelState } from './RemotePanel.tsx'\nimport { copyText, issuePair, revokePair, stopPair, type DeviceFrame, type IssueResponse, type PairStateFrame, type RelayStatusFrame, type TunnelStatusFrame } from './pair-api.ts'\nimport { PhoneIcon } from './PhoneIcon.tsx'\nimport { UpdateEntry } from './UpdateEntry.tsx'\nimport css from './remote.module.css'\n\n/** Entry props: the sidebar column state and the standard locale seat. */\nexport type RemoteEntryProps = PropsLocale<'remote'> & {\n /** Whether the sidebar renders wide content (false = 56px rail). */\n wide: boolean\n}\n\n/**\n * Apply one status frame onto the current state: the ready state mirrors\n * the full phase/device picture, while the lan-required banner only keeps\n * the auto-tunnel frame (the signal for the running re-issue).\n */\nfunction mergeFrame(state: PanelState, frame: PairStateFrame): PanelState {\n if (state.kind === 'lan-required') {\n return {\n ...state,\n ...(frame.tunnel !== undefined ? { tunnel: frame.tunnel } : {}),\n }\n }\n if (state.kind !== 'ready') return state\n return {\n ...state,\n phase: frame.phase,\n deviceCount: frame.deviceCount,\n onlineCount: frame.onlineCount,\n devices: frame.devices ?? [],\n ...(frame.tunnel !== undefined ? { tunnel: frame.tunnel as TunnelStatusFrame } : {}),\n ...(frame.relay !== undefined ? { relay: frame.relay } : {}),\n ...(frame.posture !== undefined ? { posture: frame.posture } : {}),\n }\n}\n\n/**\n * Render the remote-control trigger and panel.\n * @param props - composed slot props (contract in this package).\n * @returns the entry element tree.\n */\nexport function RemoteEntry({ wide, t }: RemoteEntryProps) {\n const [open, setOpen] = useState(false)\n const [state, setState] = useState<PanelState>({ kind: 'lan-required' })\n // Latest-state mirror for the EventSource callback: transition detection\n // must live outside setState updaters (updaters may run twice and must be\n // pure), so mint decisions read this ref instead.\n const stateRef = useRef(state)\n useEffect(() => { stateRef.current = state }, [state])\n const [copied, setCopied] = useState<boolean>(false)\n const [copiedToken, setCopiedToken] = useState<boolean>(false)\n const eventSource = useRef<EventSource | undefined>(undefined)\n // Generation counter for the open flow: closing (or re-opening) the panel\n // bumps it, so an in-flight issue() that resolves after a close does not\n // spawn a stray EventSource.\n const openSeq = useRef(0)\n\n const closeEventSource = useCallback(() => {\n eventSource.current?.close()\n eventSource.current = undefined\n }, [])\n\n const mint = useCallback(async (address?: string): Promise<PanelState> => {\n let result: IssueResponse\n try {\n result = await issuePair(address)\n } catch {\n // Fetch/network failure: show an explicit state instead of silently\n // leaving the panel on its initial banner.\n return { kind: 'unreachable' }\n }\n if (!result.ok) {\n // 403 is the loopback-only fence refusing a LAN origin (the panel is a\n // desktop control endpoint); 409 means the server never bound 0.0.0.0;\n // 400 means the requested LAN literal is no longer constructible.\n if (result.code === 'forbidden') return { kind: 'loopback-required' }\n if (result.code === 'unknown-address') return { kind: 'unreachable' }\n return { kind: 'lan-required' }\n }\n const publicBaseUrl = result.publicBaseUrl\n return {\n kind: 'ready',\n url: result.url,\n token: result.token,\n expiresAt: result.expiresAt,\n expired: Date.now() > result.expiresAt,\n phase: 'waiting',\n deviceCount: 0,\n onlineCount: 0,\n devices: [] as DeviceFrame[],\n // Whether this QR is built on the configured public (tunneled) base.\n public: publicBaseUrl !== undefined && result.url.startsWith(publicBaseUrl),\n ...(publicBaseUrl !== undefined ? { publicBaseUrl } : {}),\n // The issued URL names the requested (or default first) literal; the\n // public link has no LAN literal, so no radio row is selected then.\n address: address ?? result.lanAddresses[0] ?? '',\n lanAddresses: result.lanAddresses,\n }\n }, [])\n\n const openPanel = useCallback(async (): Promise<void> => {\n const seq = ++openSeq.current\n setOpen(true)\n const next = await mint()\n // A close (or re-open) during the await invalidates this issue: skip the\n // state write and the stream so a panel closed mid-mint neither leaks an\n // EventSource nor resurrects a stale QR.\n if (seq !== openSeq.current) return\n setState(next)\n // Live status: the desktop panel mirrors the pairing service state. The\n // stream makes sense in the ready state and on the lan-required banner —\n // there the auto-tunnel may still be starting, and following its frames\n // lets the panel re-issue once it runs. The loopback-required and\n // unreachable origins are fenced out of the events endpoint, so opening\n // it there would just start a doomed reconnect loop.\n if (next.kind !== 'ready' && next.kind !== 'lan-required') return\n const source = new EventSource('/api/pair/events')\n eventSource.current = source\n source.onmessage = (event) => {\n try {\n const frame = JSON.parse(event.data as string) as PairStateFrame\n if (frame.type !== 'state') return\n // The auto-tunnel crossed into running while the panel sat on the\n // lan-required banner: re-issue so the server hands back a ready QR\n // built on the public base (only on the transition into running, to\n // avoid mint storms). Detected on the ref, outside the updater: an\n // updater may be invoked twice and must stay pure, so mint() cannot\n // run inside it.\n const previous = stateRef.current\n if (\n previous.kind === 'lan-required'\n && frame.tunnel?.state === 'running'\n && previous.tunnel?.state !== 'running'\n ) {\n void mint().then(setState)\n return\n }\n setState(current => mergeFrame(current, frame))\n } catch {\n // Malformed frames are dropped; the snapshot on open is authoritative.\n }\n }\n }, [mint])\n\n const closePanel = useCallback(() => {\n openSeq.current += 1\n closeEventSource()\n setOpen(false)\n }, [closeEventSource])\n\n // Expiry flip: one timeout per token lifetime (reset by refresh).\n useEffect(() => {\n if (state.kind !== 'ready') return\n if (state.expired) return\n const delay = state.expiresAt - Date.now()\n if (delay <= 0) {\n setState(previous => previous.kind === 'ready' ? { ...previous, expired: true } : previous)\n return\n }\n const timer = window.setTimeout(() => {\n setState(previous => previous.kind === 'ready' ? { ...previous, expired: true } : previous)\n }, delay)\n return () => { window.clearTimeout(timer) }\n }, [state])\n\n // Unmount safety: never leave the stream open.\n useEffect(() => closeEventSource, [closeEventSource])\n\n const handleStop = useCallback(() => {\n // A failed stop request is harmless: the optimistic phase flip below\n // keeps the UI honest, and the status stream confirms the stopped phase.\n void stopPair().catch(() => {})\n // Optimistic fallback; the status stream confirms with the stopped phase.\n setState(previous => previous.kind === 'ready' ? { ...previous, phase: 'stopped' as PairingPhase, devices: [] } : previous)\n }, [])\n\n const handleRevoke = useCallback((deviceId: string) => {\n void revokePair(deviceId).catch(() => {})\n setState(previous => previous.kind === 'ready'\n ? { ...previous, devices: previous.devices.filter(device => device.id !== deviceId) }\n : previous)\n }, [])\n\n const handleRefresh = useCallback(() => {\n void mint().then(setState)\n }, [mint])\n\n /** Re-mint against another LAN literal (multi-homed machines). */\n const handlePickAddress = useCallback((address: string) => {\n void mint(address).then(setState)\n }, [mint])\n\n /** Re-mint against the configured public (tunneled) base. */\n const handlePickPublic = useCallback(() => {\n void mint().then(setState)\n }, [mint])\n\n const handleCopy = useCallback((url: string) => {\n void copyText(url).then((ok) => {\n if (!ok) return\n setCopied(true)\n window.setTimeout(() => { setCopied(false) }, 1500)\n })\n }, [])\n\n const handleCopyToken = useCallback((token: string) => {\n void copyText(token).then((ok) => {\n if (!ok) return\n setCopiedToken(true)\n window.setTimeout(() => { setCopiedToken(false) }, 1500)\n })\n }, [])\n\n return (\n <>\n <div className={css.entryRow} data-rail={wide ? undefined : 'rail'}>\n <UpdateEntry wide={wide} t={t} />\n <TooltipAnchor wide={wide} label={t('entry.label')} onClick={openPanel} expanded={open} />\n </div>\n {open && createPortal((\n <div className={css.overlay} role=\"presentation\">\n <div className={css.mask} aria-hidden=\"true\" onClick={closePanel} />\n <RemotePanel\n t={t}\n state={state}\n copied={copied}\n copiedToken={copiedToken}\n onClose={closePanel}\n onStop={handleStop}\n onRefresh={handleRefresh}\n onCopy={handleCopy}\n onCopyToken={handleCopyToken}\n onPickAddress={handlePickAddress}\n onPickPublic={handlePickPublic}\n onRevoke={handleRevoke}\n />\n </div>\n ), document.body)}\n </>\n )\n}\n\n/** The trigger: an icon-only control with a persistent accessible label. */\nfunction TooltipAnchor({ wide, label, onClick, expanded }: { wide: boolean; label: string; onClick: () => void; expanded: boolean }) {\n return (\n <button\n type=\"button\"\n className={css.trigger}\n data-wide={wide ? 'wide' : 'rail'}\n aria-label={label}\n aria-expanded={expanded}\n title={label}\n onClick={onClick}\n >\n <PhoneIcon size={wide ? 16 : 18} />\n </button>\n )\n}\n","/**\n * Sidebar footer-seat wrapper for the remote-control entry.\n *\n * Current dsh web shells declare `sidebar.footer.action` (the seat beside\n * the settings trigger) instead of the legacy `sidebar.remote` seat this\n * plugin was written against. The footer seat supplies `{ wide }`; the\n * pairing link is origin-agnostic, so no workspace source is involved.\n */\nimport type { PropsLocale } from '@deepseek-ai/dsh-client-ui-slots'\nimport { RemoteEntry } from './RemoteEntry.tsx'\n\n/** Entry props: the footer seat's column state and the standard locale seat. */\nexport type FooterRemoteEntryProps = PropsLocale<'remote'> & {\n /** Whether the sidebar renders wide content (false = 56px rail). */\n wide: boolean\n}\n\n/**\n * Render the remote-control trigger + pairing panel from the footer seat.\n * @param props - composed slot props (footer seat subset).\n * @returns the entry element tree.\n */\nexport function FooterRemoteEntry(props: FooterRemoteEntryProps) {\n return (\n <RemoteEntry\n wide={props.wide}\n t={props.t}\n />\n )\n}\n","/**\n * One-time failed-pairing notice: a fixed toast rendered on the phone after\n * a QR accept failed (invalid/used token or a network error). Mounted by\n * the client apply with a plain React root — no slot machinery for a\n * transient diagnostic.\n */\nimport { useEffect, useState } from 'react'\nimport type { TranslateNS } from '@deepseek-ai/dsh-client-ui-slots'\nimport css from './remote.module.css'\n\n/** Notice props: localized copy. */\nexport interface PairFailedNoticeProps {\n t: TranslateNS<'remote'>\n}\n\n/**\n * Render the failed-pair toast (auto-dismisses).\n * @param props - localized copy.\n * @returns the toast element.\n */\nexport function PairFailedNotice({ t }: PairFailedNoticeProps) { const [visible, setVisible] = useState(true)\n useEffect(() => {\n const timer = window.setTimeout(() => { setVisible(false) }, 8000)\n return () => { window.clearTimeout(timer) }\n }, [])\n if (!visible) return null\n return (\n <div className={css.notice} role=\"alert\">\n <p className={css.noticeTitle}>{t('pair.failed.title')}</p>\n <p className={css.noticeDetail}>{t('pair.failed.detail')}</p>\n </div>\n )\n}\n","// Generated by scripts/sync-shared.mjs from shared/client/settings/PluginSettingsCard.tsx. Do not edit this copy; edit the shared source and run \"node scripts/sync-shared.mjs\".\n/**\n * Family-shared chrome for plugin settings cards: a disclosure header naming\n * the plugin and what its settings govern, the controls inside, and the save\n * that writes them. Renders nothing while the namespace is unavailable — a\n * deployment that does not compose the owning plugin should show no trace of\n * it. Inlined into each consumer's client bundle; mirrors the official\n * ui-plugin-config PluginCard in a self-contained slice.\n */\n\nimport { useCallback, useEffect, useLayoutEffect, useRef, useState, type KeyboardEvent, type ReactNode } from 'react'\nimport type { CardShell } from './settings-form.ts'\nimport css from './settings-card.module.css'\n\n/** Copy keys the card chrome itself reads; every consumer locale carries this shared vocabulary. */\nexport const CARD_COPY_KEYS = [\n 'settings.collapse',\n 'settings.expand',\n 'settings.notExposed',\n 'settings.unsaved',\n 'settings.readOnly',\n 'settings.saveFailed',\n 'settings.discard',\n 'settings.save',\n 'settings.saving',\n] as const\n\n/** Copy key the card chrome itself reads. */\nexport type CardCopyKey = (typeof CARD_COPY_KEYS)[number]\n\n/** Key domain for the plugin's own copy (inferred per consumer). */\nexport type SettingsCardKey<TKey extends string = string> = TKey | CardCopyKey\n\n/** Card chrome shared by every plugin settings card. */\nexport interface PluginSettingsCardProps<TKey extends string = string> {\n /** Locale reader for this card's copy. */\n t: (key: SettingsCardKey<TKey>, params?: Record<string, string | number>) => string\n /** Locale key of the plugin's name. */\n titleKey: TKey\n /** Locale key of the line describing what this plugin's settings govern. */\n descriptionKey: TKey\n /** Optional rich header description rendered instead of the plain t(descriptionKey) text (the plain text stays as the tooltip). */\n descriptionNode?: ReactNode\n /** The card's form state: availability, writability, and what a save would do. */\n state: CardShell\n /** Write every staged edit. */\n onSave: () => void\n /** Drop every staged edit. */\n onDiscard: () => void\n /**\n * Render the controls expanded on arrival (still collapsible). Defaults to\n * true: promoted first-level sections show their settings immediately.\n */\n defaultOpen?: boolean\n /**\n * Render without the collapse affordance: a static header and an always\n * visible body. Used by first-level settings sections whose nav entry\n * already provides the selection.\n */\n alwaysOpen?: boolean\n /**\n * Hide the save/discard footer: cards whose body applies its own changes\n * immediately (an embedded external settings section) have no staged\n * edits, so the footer would sit there permanently disabled.\n */\n hideFooter?: boolean\n /** The plugin's controls. */\n children: ReactNode\n}\n\n/**\n * Render one plugin settings card.\n * @param props - the plugin's copy keys, its form state, and its controls.\n * @returns the card, or nothing while the namespace is still loading.\n */\nexport function PluginSettingsCard<TKey extends string = string>(props: PluginSettingsCardProps<TKey>) {\n const [open, setOpen] = useState(props.defaultOpen ?? true)\n const { state, alwaysOpen } = props\n if (!state.available) return null\n const title = props.t(props.titleKey)\n const description = props.t(props.descriptionKey)\n const blocked = !state.dirty || state.invalid || state.saving\n const expanded = alwaysOpen === true || open\n const cardClass = expanded ? `${css.cardOpen} ${css.card}` : css.card\n // With alwaysOpen the nav entry already provides the selection, so the\n // header is a static title row instead of a disclosure button.\n const header = alwaysOpen === true\n ? (\n <div className={css.headerStatic}>\n <span className={css.headText}>\n <span className={css.name} title={title}>{title}</span>\n <span className={css.description} title={description}>{props.descriptionNode ?? description}</span>\n </span>\n {state.dirty ? <span className={css.pending} title={props.t('settings.unsaved')}>{props.t('settings.unsaved')}</span> : null}\n </div>\n )\n : (\n <button\n type=\"button\"\n className={css.header}\n aria-expanded={open}\n aria-label={`${props.t(open ? 'settings.collapse' : 'settings.expand')}: ${title}`}\n onClick={() => { setOpen(!open) }}\n >\n <span className={css.headText}>\n <span className={css.name} title={title}>{title}</span>\n <span className={css.description} title={description}>{props.descriptionNode ?? description}</span>\n </span>\n {state.dirty ? <span className={css.pending} title={props.t('settings.unsaved')}>{props.t('settings.unsaved')}</span> : null}\n <svg\n width=\"14\"\n height=\"14\"\n viewBox=\"0 0 14 14\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n className={open ? `${css.chevron} ${css.chevronOpen}` : css.chevron}\n >\n <path\n d=\"M11.8486 5.5L11.4238 5.92383L8.69727 8.65137C8.44157 8.90706 8.21562 9.13382 8.01172 9.29785C7.79912 9.46883 7.55595 9.61756 7.25 9.66602C7.08435 9.69222 6.91565 9.69222 6.75 9.66602C6.44405 9.61756 6.20088 9.46883 5.98828 9.29785C5.78438 9.13382 5.55843 8.90706 5.30273 8.65137L2.57617 5.92383L2.15137 5.5L3 4.65137L3.42383 5.07617L6.15137 7.80273C6.42595 8.07732 6.59876 8.24849 6.74023 8.3623C6.87291 8.46904 6.92272 8.47813 6.9375 8.48047C6.97895 8.48703 7.02105 8.48703 7.0625 8.48047C7.07728 8.47813 7.12709 8.46904 7.25977 8.3623C7.40124 8.24849 7.57405 8.07732 7.84863 7.80273L10.5762 5.07617L11 4.65137L11.8486 5.5Z\"\n fill=\"currentColor\"\n />\n </svg>\n </button>\n )\n // The namespace exists but the Host does not serve it to this client (the\n // official settings allowlist omits third-party namespaces): show a card\n // that explains the gap instead of vanishing, so a missing card never\n // reads as a missing plugin.\n if (!state.exposed) {\n return (\n <li className={cardClass}>\n {header}\n {expanded\n ? (\n <div className={css.body}>\n <p className={css.notExposed} role=\"status\">{props.t('settings.notExposed')}</p>\n </div>\n )\n : null}\n </li>\n )\n }\n return (\n <li className={cardClass}>\n {header}\n {expanded\n ? (\n <div className={css.body}>\n {!state.writable ? <p className={css.readOnly} role=\"status\">{props.t('settings.readOnly')}</p> : null}\n {props.children}\n {props.hideFooter === true\n ? null\n : (\n <div className={css.footer}>\n {state.failed\n ? (\n <p className={css.failed} role=\"status\">\n {props.t('settings.saveFailed')}{state.failedReason ? ' - ' + state.failedReason : ''}\n </p>\n )\n : null}\n <button\n type=\"button\"\n className={css.discard}\n disabled={!state.dirty || state.saving}\n onClick={props.onDiscard}\n >\n {props.t('settings.discard')}\n </button>\n <button\n type=\"button\"\n className={css.save}\n disabled={blocked}\n onClick={props.onSave}\n >\n {props.t(!state.saving ? 'settings.save' : 'settings.saving')}\n </button>\n </div>\n )}\n </div>\n )\n : null}\n </li>\n )\n}\n\n/** Props every field control needs regardless of its value type. */\nexport interface FieldProps {\n /** Stable id associating the label with its control. */\n id: string\n /** Visible label. */\n label: string\n /** One-line explanation rendered under the control. */\n hint: string\n /** Draft text this control renders. */\n text: string\n /** True when saving would leave a user-layer entry for this field. */\n overridden: boolean\n /** True when the draft is not a value this field accepts. */\n invalid: boolean\n /** Copy for the overridden badge. */\n overriddenLabel: string\n /** Copy for the reset control. */\n resetLabel: string\n /** Copy shown in place of the hint while the draft is invalid. */\n invalidLabel: string\n /** Disables every control (read-only document, or an unavailable namespace). */\n disabled: boolean\n /** Stage draft text. */\n onEdit: (text: string) => void\n /** Stage a clear so the field re-inherits the composition layer. */\n onReset: () => void\n}\n\n/** A staged value field. `numeric` only hints the keypad: which drafts a field accepts is decided by its spec. */\nexport function ValueField(props: FieldProps & {\n /** Hints a numeric keypad without narrowing what the control accepts. */\n numeric?: boolean\n /** Placeholder shown while the draft is empty. */\n placeholder?: string\n}) {\n return (\n <div className={css.field}>\n <div className={css.head}>\n <label className={css.label} htmlFor={props.id}>{props.label}</label>\n {props.overridden\n ? (\n <span className={css.badges}>\n <span className={css.badge}>{props.overriddenLabel}</span>\n <button\n type=\"button\"\n className={css.reset}\n disabled={props.disabled}\n onClick={props.onReset}\n >\n {props.resetLabel}\n </button>\n </span>\n )\n : null}\n </div>\n <input\n id={props.id}\n className={props.invalid ? css.inputInvalid : css.input}\n type=\"text\"\n {...props.numeric === true ? { inputMode: 'numeric' as const } : {}}\n {...props.invalid ? { 'aria-invalid': true } : {}}\n value={props.text}\n placeholder={props.placeholder ?? ''}\n disabled={props.disabled}\n onChange={(event) => { props.onEdit(event.target.value) }}\n />\n <p className={props.invalid ? css.invalid : css.hint}>\n {props.invalid ? props.invalidLabel : props.hint}\n </p>\n </div>\n )\n}\n\nconst NON_SKIN_BODY_MARKERS = new Set(['dshSkinCenter', 'dshSidebarCollapsed'])\n// 检测使用使用皮肤,用了皮肤退回原生select样式,防止样式冲突。默认外观下使用优化后的select样式。\nfunction isSkinActive(): boolean {\n const datasetList = Object.keys(document.body.dataset)\n const isActive = datasetList.some(key => key.startsWith('dsh') && !NON_SKIN_BODY_MARKERS.has(key))\n return isActive\n}\n\ninterface SelectOption {\n value: string\n label: string\n}\n\nconst SELECT_CLOSE_MS = 100\n\n/**\n * The shared dual-mode select control. While an appearance skin is active it\n * renders the legacy native `<select>` untouched, so element-level skin\n * selectors keep working; under the default appearance it renders a\n * self-drawn `role=\"listbox\"` popup whose open/close is transition-animated.\n * Staged cards reach it through BooleanField/ChoiceField; immediate-apply\n * editors (the side-card prefs) bind it directly through onEdit.\n * 双模式下拉框:皮肤激活时用原生 select,默认外观用自绘动画弹层。\n */\nexport function SelectField(props: {\n id: string\n options: ReadonlyArray<SelectOption>\n value: string\n disabled: boolean\n invalid: boolean\n onEdit: (text: string) => void\n}) {\n const { id, options, value } = props\n const [open, setOpen] = useState(false)\n const [closing, setClosing] = useState(false)\n const [phase, setPhase] = useState<'initial' | 'open'>('initial')\n const [activeIndex, setActiveIndex] = useState(0)\n const closeTimer = useRef<ReturnType<typeof setTimeout> | undefined>(undefined)\n const wrapRef = useRef<HTMLDivElement | null>(null)\n const popupRef = useRef<HTMLDivElement | null>(null)\n\n const currentIndex = () => {\n const index = options.findIndex(option => option.value === value)\n return index >= 0 ? index : 0\n }\n\n const close = useCallback(() => {\n if (closeTimer.current !== undefined) clearTimeout(closeTimer.current)\n setClosing(true)\n closeTimer.current = setTimeout(() => {\n setClosing(false)\n setOpen(false)\n }, SELECT_CLOSE_MS)\n }, [])\n\n const openPopup = () => {\n if (closeTimer.current !== undefined) clearTimeout(closeTimer.current)\n setActiveIndex(currentIndex())\n setPhase('initial')\n setClosing(false)\n setOpen(true)\n }\n\n const commit = (index: number) => {\n const option = options[index]\n if (option) props.onEdit(option.value)\n close()\n }\n\n const onTriggerClick = () => {\n if (props.disabled) return\n if (open && !closing) close()\n else openPopup()\n }\n\n const onKeyDown = (event: KeyboardEvent<HTMLButtonElement>) => {\n if (props.disabled) return\n const count = options.length\n switch (event.key) {\n case 'ArrowDown':\n case 'ArrowUp':\n case 'Enter':\n case ' ':\n event.preventDefault()\n if (!open) {\n openPopup()\n } else if (!closing) {\n if (event.key === 'ArrowDown') setActiveIndex(index => (index + 1) % count)\n else if (event.key === 'ArrowUp') setActiveIndex(index => (index - 1 + count) % count)\n else commit(activeIndex)\n }\n break\n case 'Escape':\n if (open) {\n event.preventDefault()\n event.stopPropagation()\n close()\n }\n break\n case 'Tab':\n if (open) close()\n break\n }\n }\n\n useEffect(() => () => {\n if (closeTimer.current !== undefined) clearTimeout(closeTimer.current)\n }, [])\n useLayoutEffect(() => {\n if (open && !closing && phase === 'initial') {\n void popupRef.current?.offsetHeight\n setPhase('open')\n }\n }, [open, closing, phase])\n\n useEffect(() => {\n if (!open) return\n const onPointerDown = (event: PointerEvent) => {\n const target = event.target\n if (target instanceof Node && !wrapRef.current?.contains(target)) close()\n }\n document.addEventListener('pointerdown', onPointerDown)\n return () => document.removeEventListener('pointerdown', onPointerDown)\n }, [open, close])\n\n useEffect(() => {\n if (props.disabled && open) close()\n }, [props.disabled, open, close])\n\n // 使用了皮肤则退回原生select样式防止样式冲突。\n if (isSkinActive()) {\n return (\n <select\n id={id}\n className={css.select}\n value={value}\n disabled={props.disabled}\n onChange={(event) => { props.onEdit(event.target.value) }}\n >\n {options.map(option => (\n <option key={option.value} value={option.value}>{option.label}</option>\n ))}\n </select>\n )\n }\n\n const label = options.find(option => option.value === value)?.label ?? ''\n const popupClass = closing\n ? `${css.selectPopup} ${css.selectPopupClose}`\n : phase === 'open'\n ? `${css.selectPopup} ${css.selectPopupOpen}`\n : css.selectPopup\n return (\n <div className={css.selectWrap} ref={wrapRef}>\n <button\n type=\"button\"\n id={id}\n className={`${css.select} ${css.selectButton}`}\n disabled={props.disabled}\n aria-haspopup=\"listbox\"\n aria-expanded={open}\n aria-activedescendant={open ? `${id}-o${activeIndex}` : undefined}\n aria-invalid={props.invalid || undefined}\n onClick={onTriggerClick}\n onKeyDown={onKeyDown}\n >\n <span className={css.selectLabel}>{label}</span>\n <svg\n width=\"14\"\n height=\"14\"\n viewBox=\"0 0 14 14\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n className={open ? `${css.selectChevron} ${css.selectChevronOpen}` : css.selectChevron}\n aria-hidden=\"true\"\n >\n <path\n d=\"M11.8486 5.5L11.4238 5.92383L8.69727 8.65137C8.44157 8.90706 8.21562 9.13382 8.01172 9.29785C7.79912 9.46883 7.55595 9.61756 7.25 9.66602C7.08435 9.69222 6.91565 9.69222 6.75 9.66602C6.44405 9.61756 6.20088 9.46883 5.98828 9.29785C5.78438 9.13382 5.55843 8.90706 5.30273 8.65137L2.57617 5.92383L2.15137 5.5L3 4.65137L3.42383 5.07617L6.15137 7.80273C6.42595 8.07732 6.59876 8.24849 6.74023 8.3623C6.87291 8.46904 6.92272 8.47813 6.9375 8.48047C6.97895 8.48703 7.02105 8.48703 7.0625 8.48047C7.07728 8.47813 7.12709 8.46904 7.25977 8.3623C7.40124 8.24849 7.57405 8.07732 7.84863 7.80273L10.5762 5.07617L11 4.65137L11.8486 5.5Z\"\n fill=\"currentColor\"\n />\n </svg>\n </button>\n {open\n ? (\n <div className={popupClass} role=\"listbox\" ref={popupRef}>\n {options.map((option, index) => (\n <div\n key={option.value}\n id={`${id}-o${index}`}\n role=\"option\"\n aria-selected={option.value === value}\n className={`${css.selectOption}${option.value === value ? ` ${css.selectOptionSelected}` : ''}${index === activeIndex && !closing ? ` ${css.selectOptionActive}` : ''}`}\n onClick={() => { commit(index) }}\n >\n {option.label}\n </div>\n ))}\n </div>\n )\n : null}\n </div>\n )\n}\n\n/** A staged boolean field: 继承 / 开 / 关. */\nexport function BooleanField(props: FieldProps & {\n /** Copy for the inherit option. */\n inheritLabel: string\n /** Copy for the on option. */\n onLabel: string\n /** Copy for the off option. */\n offLabel: string\n}) {\n return (\n <div className={css.field}>\n <div className={css.head}>\n <label className={css.label} htmlFor={props.id}>{props.label}</label>\n {props.overridden\n ? (\n <span className={css.badges}>\n <span className={css.badge}>{props.overriddenLabel}</span>\n <button\n type=\"button\"\n className={css.reset}\n disabled={props.disabled}\n onClick={props.onReset}\n >\n {props.resetLabel}\n </button>\n </span>\n )\n : null}\n </div>\n <SelectField\n id={props.id}\n options={[\n { value: '', label: props.inheritLabel },\n { value: 'true', label: props.onLabel },\n { value: 'false', label: props.offLabel },\n ]}\n value={props.text}\n disabled={props.disabled}\n invalid={props.invalid}\n onEdit={props.onEdit}\n />\n <p className={css.hint}>{props.hint}</p>\n </div>\n )\n}\n\n/** A staged enumerated field rendered as a select. */\nexport function ChoiceField(props: FieldProps & {\n /** Copy for the inherit option (draft text is the empty string). */\n inheritLabel: string\n /** Choices rendered in order; `value` is the draft/stored text. */\n choices: ReadonlyArray<{ value: string; label: string }>\n}) {\n return (\n <div className={css.field}>\n <div className={css.head}>\n <label className={css.label} htmlFor={props.id}>{props.label}</label>\n {props.overridden\n ? (\n <span className={css.badges}>\n <span className={css.badge}>{props.overriddenLabel}</span>\n <button\n type=\"button\"\n className={css.reset}\n disabled={props.disabled}\n onClick={props.onReset}\n >\n {props.resetLabel}\n </button>\n </span>\n )\n : null}\n </div>\n <SelectField\n id={props.id}\n options={[{ value: '', label: props.inheritLabel }, ...props.choices]}\n value={props.text}\n disabled={props.disabled}\n invalid={props.invalid}\n onEdit={props.onEdit}\n />\n <p className={props.invalid ? css.invalid : css.hint}>\n {props.invalid ? props.invalidLabel : props.hint}\n </p>\n </div>\n )\n}\n","// Generated by scripts/sync-shared.mjs from shared/client/settings/settings-form.ts. Do not edit this copy; edit the shared source and run \"node scripts/sync-shared.mjs\".\n/**\n * Staged form model behind the plugin settings card. A card stages what the\n * user types and writes it only when they save — the settings write is a\n * durable, revision-fenced document mutation, so staging keeps what is on\n * screen exactly what a save would store. Family-shared slice inlined into\n * each plugin's client bundle; mirrors the official ui-plugin-config\n * card-store pattern.\n */\n\nimport type { SettingsScope, SettingsScopeSnapshot } from '@deepseek-ai/dsh-client-ui-settings/client'\nimport type { SnapshotStore } from '@deepseek-ai/dsh-client-store'\nimport { createSnapshotStore } from '@deepseek-ai/dsh-client-store'\n\n/** The write one field's staged text performs when the card is saved. */\nexport type FieldWrite =\n | { kind: 'set'; value: unknown }\n | { kind: 'clear' }\n\n/** How one field converts between its stored value and its draft text. */\nexport interface FieldSpec {\n /** Field name inside the namespace section. */\n field: string\n /**\n * Whether the Host treats this field as a secret and redacts its value from\n * the read-back (role('secret') in the section schema). Redacted secrets are\n * never compared against the draft on save: the Host strips them from every\n * wire view layer, so the settled snapshot carries nothing to read back. A\n * staged secret set is judged by the mutation settling; the rest of its\n * batch, when one exists, is still judged by read-back, and the atomic\n * mutation lands every write or none.\n */\n secret?: boolean\n /** Render a stored value as draft text; the empty string when the section carries none. */\n format: (value: unknown) => string\n /**\n * The write this draft text stages, or undefined when the text is not a\n * value this field accepts — which blocks the save rather than discarding it.\n */\n parse: (text: string) => FieldWrite | undefined\n}\n\n/** One field as the card renders it. */\nexport interface FieldState {\n /** Draft text the control renders. */\n text: string\n /** Whether saving would leave a user-layer entry for this field. */\n overridden: boolean\n /** Whether the draft is not a value this field accepts, which blocks saving. */\n invalid: boolean\n}\n\n/** Form state every plugin settings card shares. */\nexport interface CardShell {\n /** False while the namespace is still loading; the card renders nothing. */\n available: boolean\n /**\n * Whether the namespace is actually served to this client. False when the\n * Host deployment does not expose it (e.g. the owning plugin's settings\n * domain is not mounted): the card renders an explanation\n * instead of its form, so a missing namespace never looks like a missing\n * plugin.\n */\n exposed: boolean\n /** Whether the Host document accepts writes. */\n writable: boolean\n /** Whether the form holds edits that a save would write. */\n dirty: boolean\n /** Whether any staged draft is invalid, which blocks the save. */\n invalid: boolean\n /** Whether a save is crossing the wire. */\n saving: boolean\n /** Whether the last save did not land as staged; cleared by the next edit or save. */\n failed: boolean\n /**\n * The rejection code/message the Host returned for the last failed save,\n * surfaced next to the generic failure text. Undefined while no save has\n * failed (or the failure carried no server reason).\n */\n failedReason?: string\n}\n\n/** The write actions the card's slot entry injects. */\nexport interface CardActions {\n /** Stage draft text for one field. */\n edit: (field: string, text: string) => void\n /** Stage a clear, so saving lets the field re-inherit the composition layer. */\n resetField: (field: string) => void\n /** Write every staged edit, then re-seed from what the Host accepted. */\n save: () => void\n /** Drop every staged edit. */\n discard: () => void\n}\n\n/** One field's staged edit. */\ninterface StagedEdit {\n /** Draft text the control renders. */\n text: string\n /** True when this edit clears the field whatever text it shows. */\n clear: boolean\n}\n\n/** One staged edit resolved into the write a save performs. */\ninterface PlannedWrite {\n /** Field this entry writes. */\n field: string\n /** The durable write this entry performs, inside the save's one atomic mutation. */\n op: BatchedWrite\n /**\n * Read the settled snapshot back and report whether the Host holds this\n * write's effect. Undefined when the draft is not a value the field\n * accepts: there is nothing to write, and the entry blocks the save.\n */\n judge: (() => boolean) | undefined\n}\n\n/** One durable write inside the save's atomic scope mutation. */\nexport interface BatchedWrite {\n /** Field this entry writes. */\n field: string\n /** set stores a value; unset drops the leaf. */\n op: 'set' | 'unset'\n /** Value for op set (absent for unset). */\n value?: unknown\n}\n\n/** Constraints a numeric field's accepted drafts must satisfy, mirroring the host schema. */\nexport interface NumberConstraints {\n /** The accepted value must be a whole number. */\n integer?: boolean\n /** The accepted value must be at least this. */\n min?: number\n}\n\n/** A whole- or decimal-number field. An empty draft clears the field; any other draft that is not a finite number within the constraints blocks the save. */\nexport function numberField(field: string, constraints: NumberConstraints = {}): FieldSpec {\n const { integer = false, min } = constraints\n return {\n field,\n format: value => typeof value === 'number' ? String(value) : '',\n parse: (text) => {\n const trimmed = text.trim()\n if (trimmed === '') return { kind: 'clear' }\n const parsed = Number(trimmed)\n if (!Number.isFinite(parsed)) return undefined\n if (integer && !Number.isInteger(parsed)) return undefined\n if (min !== undefined && parsed < min) return undefined\n return { kind: 'set', value: parsed }\n },\n }\n}\n\n/** A free-text field. An empty draft clears the field. */\nexport function textField(field: string): FieldSpec {\n return {\n field,\n format: value => typeof value === 'string' ? value : '',\n parse: (text) => {\n const trimmed = text.trim()\n return trimmed === '' ? { kind: 'clear' } : { kind: 'set', value: trimmed }\n },\n }\n}\n\n/**\n * A free-text field the Host treats as a secret and redacts from the read-back\n * (role('secret') in the section schema). The card still edits it like text,\n * but a save never compares the redacted value back: the staged set is judged\n * by the mutation settling (see {@link FieldSpec.secret}).\n */\nexport function secretField(field: string): FieldSpec {\n return { ...textField(field), secret: true }\n}\n\n/** A boolean field, edited through true/false draft text. */\nexport function booleanField(field: string): FieldSpec {\n return {\n field,\n format: value => typeof value === 'boolean' ? String(value) : '',\n parse: (text) => {\n const trimmed = text.trim()\n if (trimmed === '') return { kind: 'clear' }\n if (trimmed === 'true') return { kind: 'set', value: true }\n if (trimmed === 'false') return { kind: 'set', value: false }\n return undefined\n },\n }\n}\n\n/** An enumerated string field; only the listed choices are accepted. An empty draft clears the field. */\nexport function choiceField(field: string, choices: readonly string[]): FieldSpec {\n return {\n field,\n format: value => typeof value === 'string' && choices.includes(value) ? value : '',\n parse: (text) => {\n if (text === '') return { kind: 'clear' }\n return choices.includes(text) ? { kind: 'set', value: text } : undefined\n },\n }\n}\n\n/**\n * Stages one card's edits over one settings namespace and writes them on save.\n *\n * The Host is the only authority on whether a value was accepted — its\n * validators own the constraints no schema can express — so the outcome is\n * read back from the section rather than predicted here. A save that did not\n * land keeps its drafts, so the user can correct them instead of retyping.\n */\nexport class CardForm<T> {\n private readonly specs: Map<string, FieldSpec>\n private readonly staged = new Map<string, StagedEdit>()\n private readonly listeners = new Set<() => void>()\n /** The scope subscription installed in the constructor; released by dispose(). */\n private readonly disposeScope: () => void\n private disposed = false\n private saving = false\n private failed = false\n private failedReason: string | undefined\n\n /** @param scope - the bound settings scope for this card's namespace. */\n constructor(\n private readonly scope: SettingsScope<T>,\n specs: FieldSpec[],\n ) {\n this.specs = new Map(specs.map(spec => [spec.field, spec]))\n this.disposeScope = scope.subscribe(() => { this.publish() })\n }\n\n /**\n * Release the scope subscription and every bound store listener. The card\n * must call this on teardown; later calls are no-ops.\n */\n dispose(): void {\n if (this.disposed) return\n this.disposed = true\n this.disposeScope()\n this.listeners.clear()\n }\n\n /** Publish a projection of this form, rebuilt whenever the scope or a draft changes. */\n bind<S>(project: () => S): SnapshotStore<S> {\n const store = createSnapshotStore(project())\n this.listeners.add(() => { store.set(project()) })\n return store\n }\n\n /** Read the card-level state: what the Host serves, and what a save would do. */\n shell(): CardShell {\n const snapshot = this.scope.getSnapshot()\n const plan = this.plan()\n return {\n available: snapshot.status !== 'loading',\n exposed: snapshot.status === 'ready',\n writable: snapshot.writable,\n dirty: plan.length > 0,\n invalid: plan.some(item => item.judge === undefined),\n saving: this.saving,\n failed: this.failed,\n ...this.failedReason === undefined ? {} : { failedReason: this.failedReason },\n }\n }\n\n /** Read one field's state from the effective section and its staged draft. */\n field(field: string): FieldState {\n const spec = this.specOf(field)\n const staged = this.staged.get(field)\n if (staged === undefined) {\n return { text: spec.format(this.sectionValue(field)), overridden: this.stored(field), invalid: false }\n }\n const write = staged.clear ? { kind: 'clear' as const } : spec.parse(staged.text)\n return {\n text: staged.text,\n overridden: write?.kind === 'set',\n invalid: write === undefined,\n }\n }\n\n /** The actions the card's slot registration injects. */\n actions(): CardActions {\n return {\n edit: (field, text) => { this.stage(field, { text, clear: false }) },\n resetField: (field) => {\n this.stage(field, { text: this.specOf(field).format(this.baseValue(field)), clear: true })\n },\n save: () => { void this.save() },\n discard: () => {\n if (this.staged.size === 0 && !this.failed) return\n this.staged.clear()\n this.failed = false\n this.failedReason = undefined\n this.publish()\n },\n }\n }\n\n /**\n * Write every staged edit in one atomic scope mutation, then re-seed from\n * what the Host accepted.\n *\n * The whole batch rides one mutate, so cross-field validate hooks\n * (baseURL+model) judge it as a unit: the Host either applies every write\n * or refuses the batch. The 0.1.2 scope contract never rejects a refused\n * mutation — the scope recovers with a fresh Host view and resolves — so\n * resolution alone proves nothing: the outcome is judged by reading the\n * settled snapshot back, one planned write at a time, and one missed write\n * fails the whole save. A scope that still rejects on refusal (the dsh-web\n * bridge scope) reports through the same failure path with its rejection\n * message. A save that did not land keeps its drafts, so the user can\n * correct them instead of retyping.\n * @returns settlement after the mutation and the read-back.\n */\n async save(): Promise<void> {\n const plan = this.plan()\n const valid = plan.filter((item): item is PlannedWrite & { judge: () => boolean } => item.judge !== undefined)\n if (plan.length === 0 || this.saving || valid.length !== plan.length) return\n // Snapshot the staged entries this save writes, so an edit staged while it\n // is in flight (which replaces the same key) survives: only delete the key\n // when the entry is still the one this save started from.\n const pending = new Map<string, StagedEdit | undefined>()\n for (const item of plan) pending.set(item.field, this.staged.get(item.field))\n this.saving = true\n this.failed = false\n this.failedReason = undefined\n this.publish()\n // One atomic namespace mutation: the 0.1.2 scope contract takes ordered\n // path operations, so the whole staged batch is validated, persisted, and\n // recovered together — either every write lands or none does.\n const ops: Array<{ op: 'set'; path: string[]; value: string | number | boolean } | { op: 'unset'; path: string[] }> = valid.map(item => item.op.op === 'set'\n ? { op: 'set', path: [item.field], value: (item.op as { value: string | number | boolean }).value }\n : { op: 'unset', path: [item.field] })\n let failedReason: string | undefined\n try {\n await this.scope.mutate(ops)\n } catch (error) {\n failedReason = error instanceof Error ? error.message : String(error)\n }\n // The 0.1.2 scope resolves even a refused mutation (it recovers with a\n // fresh view instead of throwing), so resolution alone proves nothing:\n // judge every planned write against the settled snapshot. The mutation is\n // atomic, so one missed write fails the whole save and keeps the drafts.\n const landed = failedReason === undefined && valid.every(item => item.judge())\n for (const [field, before] of pending) {\n if (landed && this.staged.get(field) === before) this.staged.delete(field)\n }\n this.saving = false\n this.failed = !landed\n // A read-back failure carries no server reason: the card surfaces its\n // generic failure copy; a rejecting scope (the bridge) adds its message.\n this.failedReason = failedReason\n this.publish()\n }\n\n /**\n * Every staged edit a save would write. An entry whose draft is not a value\n * its field accepts carries no write: the form is still dirty, and the save\n * refuses rather than dropping the edit. A staged edit that matches the\n * effective section is not a write at all.\n * @returns the planned writes, in the order the fields were staged.\n */\n private plan(): PlannedWrite[] {\n const plan: PlannedWrite[] = []\n for (const [field, staged] of this.staged) {\n const spec = this.specOf(field)\n if (staged.clear) {\n if (this.stored(field)) plan.push({ field, op: { field, op: 'unset' }, judge: () => this.landedUnset(field) })\n continue\n }\n if (staged.text === spec.format(this.sectionValue(field))) continue\n const write = spec.parse(staged.text)\n if (write === undefined) plan.push({ field, op: { field, op: 'unset' }, judge: undefined })\n else if (write.kind === 'clear') plan.push({ field, op: { field, op: 'unset' }, judge: () => this.landedUnset(field) })\n else plan.push({ field, op: { field, op: 'set', value: write.value }, judge: () => this.landedSet(field, write.value) })\n }\n return plan\n }\n\n /**\n * Read-back judgment for a planned set: the user layer must hold the\n * intended value once the mutation has settled.\n */\n private landedSet(field: string, value: unknown): boolean {\n // A redacted secret never appears in any wire view layer: the Host strips\n // role('secret') fields and reports them through a sidecar the scope\n // snapshot does not expose, so there is nothing to compare the draft\n // against. Settling is the only signal the form has; the rest of the\n // batch, when one exists, still carries the atomic verdict by read-back.\n if (this.specOf(field).secret) return true\n return this.userLayer()?.[field] === value\n }\n\n /**\n * Read-back judgment for a planned unset: the field must be gone from the\n * user layer once the mutation has settled.\n */\n private landedUnset(field: string): boolean {\n return !this.stored(field)\n }\n\n private stage(field: string, edit: StagedEdit): void {\n this.staged.set(field, edit)\n this.failed = false\n this.failedReason = undefined\n this.publish()\n }\n\n private specOf(field: string): FieldSpec {\n const spec = this.specs.get(field)\n // Every call site names a field this card declared; a missing one is a\n // wiring mistake that must not degrade into a silently inert control.\n if (spec === undefined) throw new Error(`settings card has no field ${field}`)\n return spec\n }\n\n private snapshotOf(): SettingsScopeSnapshot<T> {\n return this.scope.getSnapshot()\n }\n\n private sectionValue(field: string): unknown {\n return (this.snapshotOf().value as Record<string, unknown> | undefined)?.[field]\n }\n\n private baseValue(field: string): unknown {\n return (this.snapshotOf().base as Record<string, unknown> | undefined)?.[field]\n }\n\n private userLayer(): Record<string, unknown> | undefined {\n return this.snapshotOf().user as Record<string, unknown> | undefined\n }\n\n private stored(field: string): boolean {\n const user = this.userLayer()\n return user !== undefined && Object.hasOwn(user, field)\n }\n\n private publish(): void {\n for (const listener of this.listeners) listener()\n }\n}\n","/**\n * The remote-control settings card: pairing security and device limits.\n * Registers into the `web-ui.plugin.item` child slot the Web UI plugin group\n * renders, bound to the `remote-web-ui` settings namespace.\n */\n\nimport { useEffect, useState } from 'react'\nimport type { InjectFace, PropsLocale, PropsRuntime } from '@deepseek-ai/dsh-client-ui-slots'\nimport type { SettingsScope } from '@deepseek-ai/dsh-client-ui-settings/client'\nimport type { SnapshotStore } from '@deepseek-ai/dsh-client-store'\nimport { PluginSettingsCard, ValueField, BooleanField } from './PluginSettingsCard.tsx'\nimport { CardForm, booleanField, numberField, secretField, textField, type CardActions, type CardShell, type FieldState as CardFieldState } from './settings-form.ts'\nimport { readLanBindStatus, type LanBindFrame } from './pair-api.ts'\nimport type { TranslateNS } from '@deepseek-ai/dsh-client-ui-slots'\n\n/** The remote-control fields this card edits (the namespace's full schema). */\nexport interface RemoteSettings {\n /** Master switch for the plugin. */\n enabled?: boolean\n /** Token lifetime in ms; the QR link dies after this. */\n tokenTtlMs?: number\n /** A device is \"online\" while its lastSeenAt is newer than this (ms). */\n offlineAfterMs?: number\n /** Hard cap on paired device sessions (oldest evicted when full). */\n maxDevices?: number\n /** Idle sessions older than this (ms) are deleted. */\n idleExpireMs?: number\n /** Cookie name carrying the paired device id. */\n cookieName?: string\n /** Fence flag: whether non-loopback /api requests must carry a live paired-device cookie. */\n requirePairingForLan?: boolean\n /** Public (tunneled) base URL the QR link is built from when set. */\n publicBaseUrl?: string\n /** When on, the plugin runs its own Cloudflare quick tunnel automatically. */\n autoTunnel?: boolean\n /**\n * Cloudflare named-tunnel token: when set (and autoTunnel is off), the\n * plugin runs the named tunnel toward the fixed public hostname — a phone\n * paired once keeps its session across restarts.\n */\n tunnelToken?: string\n /**\n * Stable-origin relay: when on (default), the quick tunnel is fronted by a\n * fixed `<id>.dsh-market.com` subdomain so the phone's bookmark and\n * pairing cookie survive restarts without any setup.\n */\n relay?: boolean\n /**\n * LAN bind toggle: once flipped, the plugin manages the profile patch's\n * webserver block (0.0.0.0 / 127.0.0.1) and the host firewall rule.\n */\n lanBind?: boolean\n}\n\n/** What the remote-control card renders. */\nexport interface RemoteSettingsCardState extends CardShell {\n /** Master switch. */\n enabled: CardFieldState\n /** Token lifetime. */\n tokenTtlMs: CardFieldState\n /** Device offline threshold. */\n offlineAfterMs: CardFieldState\n /** Paired-device cap. */\n maxDevices: CardFieldState\n /** Idle-expiry window. */\n idleExpireMs: CardFieldState\n /** Device cookie name. */\n cookieName: CardFieldState\n /** LAN fence flag. */\n requirePairingForLan: CardFieldState\n /** Public (tunneled) base URL. */\n publicBaseUrl: CardFieldState\n /** Auto public tunnel switch. */\n autoTunnel: CardFieldState\n /** Named-tunnel token (stored redacted by the Host). */\n tunnelToken: CardFieldState\n /** Stable-origin relay switch. */\n relay: CardFieldState\n /** LAN bind toggle. */\n lanBind: CardFieldState\n}\n\n/** The registration-side face the card's slot entry injects. */\nexport interface RemoteSettingsCardFace extends CardActions {\n hooks: {\n /** Card snapshot bound by the renderer as useRemoteSettingsCard. */\n remoteSettingsCard: SnapshotStore<RemoteSettingsCardState>\n }\n}\n\n/** Bridges the `remote-web-ui` scope onto the card's staged form. */\nexport class RemoteSettingsCardController {\n private readonly form: CardForm<RemoteSettings>\n private readonly store: SnapshotStore<RemoteSettingsCardState>\n\n /** @param scope - the bound settings scope for the `remote-web-ui` namespace. */\n constructor(scope: SettingsScope<RemoteSettings>) {\n this.form = new CardForm(scope, [\n booleanField('enabled'),\n numberField('tokenTtlMs'),\n numberField('offlineAfterMs'),\n numberField('maxDevices'),\n numberField('idleExpireMs'),\n textField('cookieName'),\n booleanField('requirePairingForLan'),\n textField('publicBaseUrl'),\n booleanField('autoTunnel'),\n secretField('tunnelToken'),\n booleanField('relay'),\n booleanField('lanBind'),\n ])\n this.store = this.form.bind(() => this.projection())\n }\n\n private projection(): RemoteSettingsCardState {\n return {\n ...this.form.shell(),\n enabled: this.form.field('enabled'),\n tokenTtlMs: this.form.field('tokenTtlMs'),\n offlineAfterMs: this.form.field('offlineAfterMs'),\n maxDevices: this.form.field('maxDevices'),\n idleExpireMs: this.form.field('idleExpireMs'),\n cookieName: this.form.field('cookieName'),\n requirePairingForLan: this.form.field('requirePairingForLan'),\n publicBaseUrl: this.form.field('publicBaseUrl'),\n autoTunnel: this.form.field('autoTunnel'),\n tunnelToken: this.form.field('tunnelToken'),\n relay: this.form.field('relay'),\n lanBind: this.form.field('lanBind'),\n }\n }\n\n /**\n * Build the face the card's slot registration injects.\n * @returns the card's snapshot and its form actions.\n */\n inject(): RemoteSettingsCardFace {\n return { hooks: { remoteSettingsCard: this.store }, ...this.form.actions() }\n }\n\n /**\n * Release the card's scope subscription and bound stores; the slot\n * disposer calls this on teardown.\n */\n dispose(): void {\n this.form.dispose()\n }\n}\n\n/** Props the renderer binds for the remote-control card. */\nexport type RemoteSettingsCardProps =\n PropsRuntime<'web-ui.plugin.item'>\n & PropsLocale<'remote'>\n & InjectFace<RemoteSettingsCardFace>\n\n/**\n * Render the remote-control card.\n * @param props - locale copy, the card snapshot, and its form actions.\n * @returns the card.\n */\nexport function RemoteSettingsCard(props: RemoteSettingsCardProps) {\n const { t } = props\n const state = props.useRemoteSettingsCard(snapshot => snapshot)\n const disabled = !state.writable\n const fieldProps = {\n overriddenLabel: t('settings.overridden'),\n resetLabel: t('settings.reset'),\n invalidLabel: t('settings.invalidNumber'),\n disabled,\n }\n return (\n <PluginSettingsCard\n t={t}\n titleKey=\"settings.title\"\n descriptionKey=\"settings.description\"\n defaultOpen={false}\n state={state}\n onSave={props.save}\n onDiscard={props.discard}\n >\n <BooleanField\n id=\"settings-remote-enabled\"\n label={t('settings.enabled')}\n hint={t('settings.enabledHint')}\n inheritLabel={t('settings.inherit')}\n onLabel={t('settings.on')}\n offLabel={t('settings.off')}\n {...fieldProps}\n {...state.enabled}\n onEdit={(text) => { props.edit('enabled', text) }}\n onReset={() => { props.resetField('enabled') }}\n />\n <ValueField\n id=\"settings-remote-token-ttl\"\n label={t('settings.tokenTtlMs')}\n hint={t('settings.tokenTtlMsHint')}\n numeric\n {...fieldProps}\n {...state.tokenTtlMs}\n onEdit={(text) => { props.edit('tokenTtlMs', text) }}\n onReset={() => { props.resetField('tokenTtlMs') }}\n />\n <ValueField\n id=\"settings-remote-offline\"\n label={t('settings.offlineAfterMs')}\n hint={t('settings.offlineAfterMsHint')}\n numeric\n {...fieldProps}\n {...state.offlineAfterMs}\n onEdit={(text) => { props.edit('offlineAfterMs', text) }}\n onReset={() => { props.resetField('offlineAfterMs') }}\n />\n <ValueField\n id=\"settings-remote-max-devices\"\n label={t('settings.maxDevices')}\n hint={t('settings.maxDevicesHint')}\n numeric\n {...fieldProps}\n {...state.maxDevices}\n onEdit={(text) => { props.edit('maxDevices', text) }}\n onReset={() => { props.resetField('maxDevices') }}\n />\n <ValueField\n id=\"settings-remote-idle-expire\"\n label={t('settings.idleExpireMs')}\n hint={t('settings.idleExpireMsHint')}\n numeric\n {...fieldProps}\n {...state.idleExpireMs}\n onEdit={(text) => { props.edit('idleExpireMs', text) }}\n onReset={() => { props.resetField('idleExpireMs') }}\n />\n <ValueField\n id=\"settings-remote-cookie\"\n label={t('settings.cookieName')}\n hint={t('settings.cookieNameHint')}\n {...fieldProps}\n {...state.cookieName}\n onEdit={(text) => { props.edit('cookieName', text) }}\n onReset={() => { props.resetField('cookieName') }}\n />\n <BooleanField\n id=\"settings-remote-fence\"\n label={t('settings.requirePairingForLan')}\n hint={t('settings.requirePairingForLanHint')}\n inheritLabel={t('settings.inherit')}\n onLabel={t('settings.on')}\n offLabel={t('settings.off')}\n {...fieldProps}\n {...state.requirePairingForLan}\n onEdit={(text) => { props.edit('requirePairingForLan', text) }}\n onReset={() => { props.resetField('requirePairingForLan') }}\n />\n <ValueField\n id=\"settings-remote-public-base\"\n label={t('settings.publicBaseUrl')}\n hint={t('settings.publicBaseUrlHint')}\n placeholder=\"https://example.trycloudflare.com\"\n {...fieldProps}\n {...state.publicBaseUrl}\n onEdit={(text) => { props.edit('publicBaseUrl', text) }}\n onReset={() => { props.resetField('publicBaseUrl') }}\n />\n <BooleanField\n id=\"settings-remote-auto-tunnel\"\n label={t('settings.autoTunnel')}\n hint={t('settings.autoTunnelHint')}\n inheritLabel={t('settings.inherit')}\n onLabel={t('settings.on')}\n offLabel={t('settings.off')}\n {...fieldProps}\n {...state.autoTunnel}\n onEdit={(text) => { props.edit('autoTunnel', text) }}\n onReset={() => { props.resetField('autoTunnel') }}\n />\n <ValueField\n id=\"settings-remote-tunnel-token\"\n label={t('settings.tunnelToken')}\n hint={t('settings.tunnelTokenHint')}\n placeholder=\"eyJ...\"\n {...fieldProps}\n {...state.tunnelToken}\n onEdit={(text) => { props.edit('tunnelToken', text) }}\n onReset={() => { props.resetField('tunnelToken') }}\n />\n <BooleanField\n id=\"settings-remote-relay\"\n label={t('settings.relay')}\n hint={t('settings.relayHint')}\n inheritLabel={t('settings.inherit')}\n onLabel={t('settings.on')}\n offLabel={t('settings.off')}\n {...fieldProps}\n {...state.relay}\n onEdit={(text) => { props.edit('relay', text) }}\n onReset={() => { props.resetField('relay') }}\n />\n <LanBindStatus t={t} />\n <BooleanField\n id=\"settings-remote-lan-bind\"\n label={t('settings.lanBind')}\n hint={t('settings.lanBindHint')}\n inheritLabel={t('settings.inherit')}\n onLabel={t('settings.on')}\n offLabel={t('settings.off')}\n {...fieldProps}\n {...state.lanBind}\n onEdit={(text) => { props.edit('lanBind', text) }}\n onReset={() => { props.resetField('lanBind') }}\n />\n </PluginSettingsCard>\n )\n}\n\n/**\n * Live LAN-bind facts above the toggle: the managed block's host, the live\n * bind, the firewall summary, and the reachable LAN URLs. Polls the\n * loopback-only status endpoint; a failure (non-loopback origin) renders\n * nothing — the pairing panel carries the loopback banner instead.\n */\nfunction LanBindStatus({ t }: { t: TranslateNS<'remote'> }) {\n const [frame, setFrame] = useState<LanBindFrame | undefined>(undefined)\n useEffect(() => {\n let alive = true\n const read = (): void => {\n void readLanBindStatus().then((value) => {\n if (alive) setFrame(value)\n }).catch(() => {})\n }\n read()\n const timer = window.setInterval(read, 10_000)\n return () => {\n alive = false\n window.clearInterval(timer)\n }\n }, [])\n if (frame === undefined) return null\n const lanOn = frame.blockHost === '0.0.0.0'\n const firewallText = frame.firewall.managed\n ? t(frame.firewall.ok ? 'lan.firewall.ok' : 'lan.firewall.bad')\n : t('lan.firewall.unmanaged')\n const lines: string[] = [\n t('lan.bind', { host: frame.bindHost, port: String(frame.port) }) + ' · ' + firewallText,\n ]\n if (lanOn && frame.lanUrls.length > 0) {\n lines.push(t('lan.urls', { urls: frame.lanUrls.join(' ') }))\n }\n if (!lanOn) {\n lines.push(t('lan.off'))\n }\n if (frame.setting === null) {\n lines.push(t('lan.untouched'))\n }\n if (frame.pendingRestart === true) {\n lines.push(t('lan.pendingRestart'))\n }\n return (\n <div style={{ display: 'flex', flexDirection: 'column', gap: 2, fontSize: 12, lineHeight: '18px', opacity: 0.85 }}>\n {lines.map((line, index) => (\n <div key={index} style={{ wordBreak: 'break-all' }}>{line}</div>\n ))}\n </div>\n )\n}\n","/** `remote` namespace dictionaries: the remote-access surface copy. */\n\n/** Simplified Chinese dictionary (the key-set source of truth). */\nexport const zh = {\n 'entry.label': '远程访问',\n 'mobile.whale.open': '打开侧边栏',\n 'mobile.composer.pickModel': '选择模型',\n 'mobile.composer.pickEffort': '选择推理等级',\n 'title': '远程访问',\n 'subtitle': '通过手机或另一台电脑配对,远程使用同一份 Web 界面(官方界面 + 移动端适配)',\n 'card.title': '设备配对',\n 'public.badge': '公网',\n 'status.waiting': '等待设备连接',\n 'status.connected': '已连接 {n} 台设备',\n 'status.disconnected': '已配对设备离线',\n 'status.stopped': '已停止远程访问',\n 'status.lanRequired': '此功能需要局域网绑定或公网地址才能使用',\n 'status.lanRequiredHint': '当前服务仅绑定在 127.0.0.1 且未配置公网地址,手机无法访问。请在「设置 → Web 插件 → 远程访问设置」卡片中打开“局域网访问”,或用 dsh web --host 0.0.0.0 重新启动,或填写内网穿透的公网地址。',\n 'status.loopbackRequired': '配对面板仅限本机使用',\n 'status.loopbackRequiredHint': '请通过 http://127.0.0.1 打开此页面后重试;手机请使用配对链接访问。',\n 'status.unreachable': '无法连接配对服务',\n 'status.unreachableHint': '请刷新页面后重试。',\n 'pair.hint': '无法扫码?可直接打开下方配对链接',\n 'pair.publicHint': '公网链接:设备无需与本机处于同一网络',\n 'address.label': '选择二维码指向的网络',\n 'address.public': '公网地址',\n 'address.lan': '局域网',\n 'address.hint': '远程设备不在同一网络时请使用公网地址;局域网地址仅限同一网络内使用。',\n 'pair.expires': '二维码有效至 {time}',\n 'pair.expired': '二维码已过期,请刷新',\n 'pair.linkLabel': '配对链接',\n 'pair.tokenLabel': '配对令牌',\n 'pair.dockerHint': 'Docker 或反向代理环境下,可直接复制此令牌并在目标设备配对页面输入。',\n 'pair.oneTimeHint': '链接含一次性令牌;任一设备配对成功后立即失效,配对下一台设备请刷新二维码。',\n 'pair.failed.title': '配对失败',\n 'pair.failed.detail': '链接无效或已使用,请回到电脑端刷新二维码后重新扫码。',\n 'fence.unpaired.title': '此设备未配对,无法访问工作区数据',\n 'fence.unpaired.eyebrow': '需要设备配对',\n 'fence.unpaired.hint': '为保护工作区、会话与插件数据,远程电脑必须先通过主电脑授权。',\n 'fence.unpaired.stepDesktop': '在主电脑打开 http://127.0.0.1:3080,进入“远程访问”。',\n 'fence.unpaired.stepLink': '在“设备配对”中复制电脑配对链接。',\n 'fence.unpaired.stepOpen': '在当前浏览器打开该链接,完成授权后即可进入。',\n 'fence.unpaired.retry': '重新检测',\n 'fence.unpaired.tokenPlaceholder': '或在此直接粘贴配对链接 / Token',\n 'fence.unpaired.pairAction': '立即配对',\n 'fence.unpaired.pairing': '配对中…',\n 'fence.unpaired.tokenInvalid': '配对链接或 Token 无效已过期',\n 'fence.unpaired.tokenUsed': '该配对链接已被使用',\n 'fence.unpaired.tokenFailed': '配对失败,请检查网络或重新获取链接',\n 'fence.unpaired.footnote': '请勿使用他人提供的配对链接;管理员可随时取消此设备的授权。',\n 'posture.exposed': '/api 通道对未配对设备敞开',\n 'posture.exposedHint': '以下来源的请求未经配对即可访问完整桌面 API:{hosts}。请移除对应来源的 --trusted-host(配对机制已覆盖远程访问),或改为仅绑定 127.0.0.1 并使用隧道。',\n 'action.stop': '停止',\n 'action.refresh': '刷新二维码',\n 'action.copy': '复制链接',\n 'action.copyLink': '复制链接',\n 'action.copyToken': '复制令牌',\n 'action.copied': '已复制',\n 'action.copiedToken': '已复制令牌',\n 'devices.title': '已授权设备',\n 'devices.empty': '还没有已配对的设备。扫码或打开链接后会出现在这里。',\n 'devices.unknown': '未知设备',\n 'devices.online': '在线',\n 'devices.offline': '离线',\n 'devices.lastSeen': '最近活动 {time}',\n 'devices.revoke': '取消配对',\n 'devices.revoke.label': '取消配对此设备',\n 'stopped.hint': '已停止远程访问。点击\"刷新二维码\"重新开启。',\n 'tunnel.starting': '公网隧道启动中,二维码将自动变为公网链接…',\n 'tunnel.failed': '公网隧道启动失败:{error}',\n 'tunnel.unknownError': '未知错误',\n 'relay.registering': '正在把临时隧道同步到固定域名(<id>.dsh-market.com)…',\n 'relay.failed': '固定域名同步失败:{error}。正在自动重试,期间二维码可能使用临时地址。',\n 'close.label': '关闭远程访问面板',\n // 插件设置卡片(settings.plugin.item 席位)。\n 'settings.title': '远程访问设置',\n 'settings.description': '配对安全与设备限额。',\n 'settings.enabled': '启用远程访问',\n 'settings.enabledHint': '关闭后移除侧边栏入口并停用配对路由与局域网栅栏。',\n 'settings.tokenTtlMs': '配对令牌有效期(毫秒)',\n 'settings.tokenTtlMsHint': '新生成的二维码链接在此时间后失效。',\n 'settings.offlineAfterMs': '设备离线判定(毫秒)',\n 'settings.offlineAfterMsHint': '配对设备超过该时长未上报心跳即视为离线。',\n 'settings.maxDevices': '已配对设备上限',\n 'settings.maxDevicesHint': '超过上限时淘汰最旧的设备会话。',\n 'settings.idleExpireMs': '空闲过期(毫秒)',\n 'settings.idleExpireMsHint': '超过该时长没有任何心跳或请求的已配对设备会被删除,必须重新扫码。默认 7 天。',\n 'settings.cookieName': '设备 Cookie 名',\n 'settings.cookieNameHint': '携带已配对设备标识的 Cookie 名称。',\n 'settings.requirePairingForLan': '局域网访问要求配对',\n 'settings.requirePairingForLanHint': '开启:非本机回环的桌面 Web GUI 改走门控的 /remote,必须携带有效配对 Cookie;关闭:桌面继续走普通路径(仅在该来源已被 SDK 信任时有意义),配对只管理令牌与状态。',\n 'settings.publicBaseUrl': '公网地址(可选)',\n 'settings.publicBaseUrlHint': '内网穿透的公网地址,如 Cloudflare Tunnel:https://xxx.trycloudflare.com;固定域名隧道(下方令牌)也填这里。填写后二维码将生成公网链接,手机不在同一网络也能配对;留空则仅局域网可用。',\n 'settings.autoTunnel': '自动公网隧道',\n 'settings.autoTunnelHint': '开启后插件自动启动 Cloudflare quick tunnel(无需安装任何工具),并自动更新公网地址与信任配置,手机随时可用公网配对;注意临时域名每次重启都会变化,手机需重新扫码。开启时忽略下方固定隧道令牌与上方手动公网地址。',\n 'settings.tunnelToken': '固定域名隧道令牌(Cloudflare Tunnel)',\n 'settings.tunnelTokenHint': '填入 Cloudflare 命名隧道的 Token(即 cloudflared tunnel run --token 的值),插件会自动运行该隧道:公共主机名固定不变,手机配对一次后重启也无需重新配对。需先在 Cloudflare 控制台把公共主机名映射到 http://127.0.0.1:<端口>,并在上方\"公网地址\"填写同一域名。优先级低于\"自动公网隧道\"。',\n 'settings.relay': '固定域名中继(推荐开启)',\n 'settings.relayHint': '开启后自动隧道会额外注册一个固定不变的公网子域名(<id>.dsh-market.com,由 dsh-market 边缘中继到你的临时隧道),手机配对一次后重启无需重新扫码,二维码与书签地址永远不变。流量经由 dsh-market 边缘转发(与临时隧道相同的信任面);关闭则回退为纯临时地址,每次重启需重新配对。仅对\"自动公网隧道\"生效。',\n 'settings.lanBind': '局域网访问(绑定 0.0.0.0)',\n 'settings.lanBindHint': '开启后插件把绑定默认改写为 0.0.0.0 并写入 profile 补丁(显式 --host 仍优先),同时维护主机防火墙放行(Windows/Linux;macOS 无需管理);关闭回退 127.0.0.1。绑定变化通常在重启 dsh web 后生效。',\n 'lan.cardTitle': '局域网访问',\n 'lan.bind': '绑定:{host}:{port}',\n 'lan.off': '当前仅本机可访问。',\n 'lan.urls': '局域网地址:{urls}',\n 'lan.firewall.ok': '防火墙已放行',\n 'lan.firewall.bad': '防火墙未放行(需管理员权限)',\n 'lan.firewall.unmanaged': '防火墙不由插件管理(未检测到受支持的防火墙)',\n 'lan.untouched': '开关尚未使用:打开后插件才会改写 profile 补丁。',\n 'lan.pendingRestart': '绑定将在重启 dsh web 后生效。',\n 'settings.inherit': '继承',\n 'settings.on': '开',\n 'settings.off': '关',\n 'settings.overridden': '已覆盖',\n 'settings.reset': '恢复默认',\n 'settings.notExposed': '当前 DSH 版本未向设置页暴露本插件的配置命名空间,表单不可用。可编辑 $DSH_HOME/settings.yaml 直接配置,或确认提供该命名空间的插件已挂载其设置域并重启。',\n 'settings.readOnly': '当前部署的设置只读。',\n 'settings.expand': '展开设置',\n 'settings.collapse': '收起设置',\n 'settings.save': '保存',\n 'settings.saving': '保存中…',\n 'settings.discard': '放弃',\n 'settings.unsaved': '未保存',\n 'settings.saveFailed': '部署未接受这些值,已保留供你修改。',\n 'settings.invalidNumber': '请输入数字,留空则使用默认值。',\n // 更新面板(侧边栏更新按钮)。\n 'update.label': '检查更新',\n 'update.badge': '有更新',\n 'update.availableLabel': '发现新版本,检查更新',\n 'update.title': '检查更新',\n 'update.checking': '正在检查远程仓库中的新版本…',\n 'update.upToDate': '当前已是最新版本',\n 'update.upToDateDetail': '{name} 已是最新版本 v{version}。',\n 'update.found': '发现新版本',\n 'update.foundDetail': '{name} 有新版本 v{version}。确认后开始更新。',\n 'update.start': '开始更新',\n 'update.updating': '正在更新 {name} 至 v{version},可能需要 1-2 分钟…',\n 'update.cooldownNotice': '本次更新由你主动触发,将跳过 pnpm 的 24 小时发布冷却期(供应链保护)直接安装所选版本。',\n 'update.updatingTitle': '正在更新…',\n 'update.done': '更新完成',\n 'update.doneDetail': '所有组件已更新到最新版本。',\n 'update.restartHint': '请重启 dsh web 使新版本生效:在终端按 Ctrl+C 停止后重新运行 dsh web。',\n 'update.linkMode': '当前为本地开发模式',\n 'update.linkModeDetail': 'dsh-web 或其组件通过本地链接安装(开发模式),无法自动更新。npm 上最新版本:{version}。请同步本地仓库,或移除与全家桶重复的独立链接。',\n 'update.missing': '未找到 dsh-web 安装',\n 'update.missingDetail': '无法定位已安装的 dsh-web 聚合包。请先运行 dsh plugin --profile <profile> add @linxin666/dsh-web-all。',\n 'update.offline': '无法连接更新源',\n 'update.offlineDetail': '网络不可用或更新服务异常,请稍后重试。',\n 'update.unmounted': '更新服务未加载',\n 'update.unmountedDetail': '当前 dsh web 进程运行的插件版本不含更新服务,请重启 dsh web(Ctrl+C 后重新运行)后再试。',\n 'update.error': '更新失败',\n 'update.packages': '组件版本',\n 'update.releaseNotes': 'v{version} 更新说明',\n 'update.releaseFeatures': '新增功能',\n 'update.releaseFixes': '修复',\n 'update.releaseOther': '其他变动',\n 'update.releaseUnavailable': '本次发布说明暂不可用,可前往 GitHub Release 查看。',\n 'update.componentVersions': '查看组件版本',\n 'update.retry': '重新检查',\n 'update.close': '关闭更新面板',\n 'update.error.pnpmMissing': '未找到 pnpm,已尝试 pnpm / corepack / npx 仍不可用。请安装 pnpm 后重启应用(Windows: npm install -g pnpm 或 corepack enable;macOS: brew install pnpm 或 corepack enable)。',\n 'update.error.timeout': '更新超时,已终止安装进程,请重试。',\n 'update.error.notFound': '未找到 dsh-web 聚合包安装,无法更新。',\n 'update.error.link': 'dsh-web 或其组件使用本地链接,无法自动更新;请同步本地仓库,或移除与全家桶重复的独立链接。',\n 'update.error.pnpmFailed': '更新执行失败(pnpm 退出码 {code}),详见下方输出。',\n 'update.error.stale': '更新命令已执行,但安装版本未变化。常见原因:pnpm 11 的 minimumReleaseAge 门禁会静默跳过发布不足 24 小时的新版本。请在 profile 目录(~/.dsh/profiles/<profile>)的 pnpm-workspace.yaml 中配置 minimumReleaseAgeExclude(例如 \"@linxin666/*\")或 minimumReleaseAge: 0 后重新点击更新。',\n 'update.error.verifyFailed': '更新命令已执行,但无法核对安装后的版本(可能是 registry 探测失败或安装路径变化)。请查看下方输出,或稍后重试。',\n 'update.error.unknown': '更新失败,请重试。',\n} satisfies Record<string, string>\n\n/** The remote namespace key union. */\nexport type RemoteKey = keyof typeof zh\n\n/** The settings-card slice of the remote dictionary. */\nexport type SettingsCardKey = RemoteKey\n\n/** English dictionary, checked complete against the zh key set. */\nexport const en = {\n 'entry.label': 'Remote access',\n 'mobile.whale.open': 'Open sidebar',\n 'mobile.composer.pickModel': 'Pick model',\n 'mobile.composer.pickEffort': 'Pick reasoning effort',\n 'title': 'Remote access',\n 'subtitle': 'Pair a phone or another computer to share the same Web GUI (official UI + mobile adaptation)',\n 'card.title': 'Pair a device',\n 'public.badge': 'Public',\n 'status.waiting': 'Waiting for a device',\n 'status.connected': '{n} device(s) connected',\n 'status.disconnected': 'Paired devices offline',\n 'status.stopped': 'Remote access stopped',\n 'status.lanRequired': 'This feature needs a LAN bind or a public address',\n 'status.lanRequiredHint': 'The server is bound to 127.0.0.1 and no public address is configured, so a phone cannot reach it. Turn on LAN access in the settings card under Settings → Web Plugins → Remote access, or restart with dsh web --host 0.0.0.0, or set the tunneled public address.',\n 'status.loopbackRequired': 'The pairing panel works on this machine only',\n 'status.loopbackRequiredHint': 'Open this page at http://127.0.0.1 to mint a QR code; phones use the paired link.',\n 'status.unreachable': 'Cannot reach the pairing service',\n 'status.unreachableHint': 'Refresh the page and try again.',\n 'pair.hint': 'Cannot scan? Open one of the pairing links below',\n 'pair.publicHint': 'Public links work when the device is not on the same network',\n 'address.label': 'Network the QR code points to',\n 'address.public': 'Public',\n 'address.lan': 'LAN',\n 'address.hint': 'Use the public address when the remote device is on another network; LAN addresses only work on the same network.',\n 'pair.expires': 'QR code valid until {time}',\n 'pair.expired': 'QR code expired — refresh it',\n 'pair.linkLabel': 'Pairing link',\n 'pair.tokenLabel': 'Pairing token',\n 'pair.dockerHint': 'In Docker or reverse proxy environments, copy this token to pair directly on the target device.',\n 'pair.oneTimeHint': 'The link carries one single-use token; it dies as soon as any device pairs. Refresh the QR to pair the next device.',\n 'pair.failed.title': 'Pairing failed',\n 'pair.failed.detail': 'The link is invalid or was already used. Refresh the QR code on your computer and scan again.',\n 'fence.unpaired.title': 'This device is not paired and cannot reach workspace data',\n 'fence.unpaired.eyebrow': 'Device pairing required',\n 'fence.unpaired.hint': 'To protect workspace, session, and plugin data, a remote computer must first be authorized by the primary computer.',\n 'fence.unpaired.stepDesktop': 'On the primary computer, open http://127.0.0.1:3080 and go to Remote access.',\n 'fence.unpaired.stepLink': 'Copy the computer pairing link under Pair a device.',\n 'fence.unpaired.stepOpen': 'Open that link in this browser. After authorization, the workspace will become available.',\n 'fence.unpaired.retry': 'Check again',\n 'fence.unpaired.tokenPlaceholder': 'Or paste pairing link / token here',\n 'fence.unpaired.pairAction': 'Pair Now',\n 'fence.unpaired.pairing': 'Pairing…',\n 'fence.unpaired.tokenInvalid': 'Pairing link or token is invalid or expired',\n 'fence.unpaired.tokenUsed': 'This pairing link has already been used',\n 'fence.unpaired.tokenFailed': 'Pairing failed, please check network or issue a new link',\n 'fence.unpaired.footnote': 'Do not use pairing links from people you do not trust. An administrator can revoke this device at any time.',\n 'posture.exposed': 'The /api channel is open to unpaired devices',\n 'posture.exposedHint': 'Requests from {hosts} reach the full desktop API without pairing. Remove --trusted-host for them (pairing already covers remote access), or bind loopback only and use the tunnel.',\n 'action.stop': 'Stop',\n 'action.refresh': 'Refresh QR',\n 'action.copy': 'Copy link',\n 'action.copyLink': 'Copy link',\n 'action.copyToken': 'Copy token',\n 'action.copied': 'Copied',\n 'action.copiedToken': 'Token copied',\n 'devices.title': 'Authorized devices',\n 'devices.empty': 'No paired devices yet. Scan the QR or open the link to add one.',\n 'devices.unknown': 'Unknown device',\n 'devices.online': 'Online',\n 'devices.offline': 'Offline',\n 'devices.lastSeen': 'Last active {time}',\n 'devices.revoke': 'Unpair',\n 'devices.revoke.label': 'Unpair this device',\n 'stopped.hint': 'Remote access is stopped. Click \"Refresh QR\" to re-enable it.',\n 'tunnel.starting': 'The public tunnel is starting; the QR code will switch to a public link shortly…',\n 'tunnel.failed': 'The public tunnel failed to start: {error}',\n 'tunnel.unknownError': 'unknown error',\n 'relay.registering': 'Syncing the ephemeral tunnel to the stable hostname (<id>.dsh-market.com)…',\n 'relay.failed': 'Stable-hostname sync failed: {error}. Retrying automatically; the QR may use the ephemeral address meanwhile.',\n 'close.label': 'Close remote access panel',\n // Plugin settings card (the `settings.plugin.item` seat).\n 'settings.title': 'Remote access settings',\n 'settings.description': 'Pairing security and device limits.',\n 'settings.enabled': 'Enable remote access',\n 'settings.enabledHint': 'When off, the sidebar entry is removed and pairing routes plus the LAN fence stop.',\n 'settings.tokenTtlMs': 'Pairing token lifetime (ms)',\n 'settings.tokenTtlMsHint': 'How long a minted QR link stays valid before it dies.',\n 'settings.offlineAfterMs': 'Device offline threshold (ms)',\n 'settings.offlineAfterMsHint': 'A paired device flips to offline when it has not been seen for this long.',\n 'settings.maxDevices': 'Paired device cap',\n 'settings.maxDevicesHint': 'Hard cap on paired device sessions; the oldest is evicted when full.',\n 'settings.idleExpireMs': 'Idle expiry (ms)',\n 'settings.idleExpireMsHint': 'A paired device with no heartbeat or request for this long is deleted and must scan again. Default is 7 days.',\n 'settings.cookieName': 'Device cookie name',\n 'settings.cookieNameHint': 'Cookie that carries the paired device id.',\n 'settings.requirePairingForLan': 'Require pairing for LAN access',\n 'settings.requirePairingForLanHint': 'On: a desktop Web GUI at a non-loopback origin rides the gated /remote channel and must carry a live paired-device cookie. Off: the desktop stays on its original paths (only useful when that origin is already trusted) and pairing only manages tokens/status.',\n 'settings.publicBaseUrl': 'Public address (optional)',\n 'settings.publicBaseUrlHint': 'The public URL of a tunnel in front of this server, e.g. a Cloudflare Tunnel: https://xxx.trycloudflare.com; a fixed-hostname tunnel (token below) also goes here. When set, the QR link is built from it so a phone anywhere can pair; leave blank for LAN-only usage.',\n 'settings.autoTunnel': 'Auto public tunnel',\n 'settings.autoTunnelHint': 'When on, the plugin runs its own Cloudflare quick tunnel (no tool installation needed) and keeps the public address and trust config in sync automatically, so a phone anywhere can pair at any time; note the ephemeral hostname changes on every restart, so phones must scan again. The named-tunnel token below and the manual public address above are ignored while this is on.',\n 'settings.tunnelToken': 'Fixed-hostname tunnel token (Cloudflare Tunnel)',\n 'settings.tunnelTokenHint': 'Paste a Cloudflare named-tunnel token (the value of cloudflared tunnel run --token) and the plugin runs the tunnel itself: the public hostname stays fixed, so a phone pairs once and never again across restarts. First map the public hostname to http://127.0.0.1:<port> in the Cloudflare dashboard and enter the same hostname as the public address above. Lower precedence than the auto quick tunnel.',\n 'settings.relay': 'Stable-hostname relay (recommended)',\n 'settings.relayHint': 'When on, the auto tunnel additionally registers a never-changing public subdomain (<id>.dsh-market.com, relayed by the dsh-market edge to your ephemeral tunnel), so a phone pairs once and the QR and bookmark stay valid across restarts. Traffic transits the dsh-market edge (the same trust point as the ephemeral tunnel); turn off to fall back to the raw ephemeral address, which needs re-pairing after every restart. Applies to the auto public tunnel only.',\n 'settings.lanBind': 'LAN access (bind 0.0.0.0)',\n 'settings.lanBindHint': 'When on, the plugin writes a managed block into the profile patch defaulting the bind to 0.0.0.0 (an explicit --host flag still wins), and maintains the matching host firewall rule (Windows/Linux; other platforms need none). When off, the block pins 127.0.0.1. The bind change usually takes effect after dsh web restarts.',\n 'lan.cardTitle': 'LAN access',\n 'lan.bind': 'Bind: {host}:{port}',\n 'lan.off': 'Currently localhost-only.',\n 'lan.urls': 'LAN URLs: {urls}',\n 'lan.firewall.ok': 'firewall open',\n 'lan.firewall.bad': 'firewall blocked (needs admin)',\n 'lan.firewall.unmanaged': 'firewall not managed (no supported firewall detected)',\n 'lan.untouched': 'The toggle has never been used; the profile patch is only written once you flip it.',\n 'lan.pendingRestart': 'The bind change takes effect after dsh web restarts.',\n 'settings.inherit': 'Inherit',\n 'settings.on': 'On',\n 'settings.off': 'Off',\n 'settings.overridden': 'Overridden',\n 'settings.reset': 'Reset to default',\n 'settings.notExposed': 'This DSH version does not expose this plugin\\'s settings namespace to the configuration page, so the form is unavailable. Edit $DSH_HOME/settings.yaml directly, or confirm that the plugin owning the namespace is mounted with its settings domain and restart.',\n 'settings.readOnly': 'This deployment stores settings read-only.',\n 'settings.expand': 'Show settings',\n 'settings.collapse': 'Hide settings',\n 'settings.save': 'Save',\n 'settings.saving': 'Saving…',\n 'settings.discard': 'Discard',\n 'settings.unsaved': 'Unsaved',\n 'settings.saveFailed': 'The deployment did not accept these values; they were left for you to correct.',\n 'settings.invalidNumber': 'Enter a number, or leave blank to use the default.',\n // Update panel (the sidebar update trigger).\n 'update.label': 'Check for updates',\n 'update.badge': 'Update available',\n 'update.availableLabel': 'New version available. Check for updates',\n 'update.title': 'Check for updates',\n 'update.checking': 'Checking the remote repository for newer releases…',\n 'update.upToDate': 'Everything is up to date',\n 'update.upToDateDetail': '{name} is at the latest version v{version}.',\n 'update.found': 'A new version is available',\n 'update.foundDetail': '{name} has a newer release v{version}. Confirm to start the update.',\n 'update.start': 'Update now',\n 'update.updating': 'Updating {name} to v{version}; this may take 1-2 minutes…',\n 'update.cooldownNotice': 'This user-initiated update bypasses pnpm\\'s 24-hour release cooldown (supply-chain protection) and installs the selected version immediately.',\n 'update.updatingTitle': 'Updating…',\n 'update.done': 'Update complete',\n 'update.doneDetail': 'All components are up to date.',\n 'update.restartHint': 'Restart dsh web for the new version to take effect: stop it with Ctrl+C in the terminal, then run dsh web again.',\n 'update.linkMode': 'Local development mode',\n 'update.linkModeDetail': 'dsh-web or one of its components is installed via a local link and cannot be updated remotely. Latest npm release: {version}. Sync the local checkout, or remove a standalone link duplicated by the aggregate.',\n 'update.missing': 'dsh-web not found',\n 'update.missingDetail': 'Could not locate the installed dsh-web aggregate package. Install it with: dsh plugin --profile <profile> add @linxin666/dsh-web-all',\n 'update.offline': 'Cannot reach the update source',\n 'update.offlineDetail': 'The network is unavailable or the update service is failing; try again later.',\n 'update.unmounted': 'The update service is not loaded',\n 'update.unmountedDetail': 'The running dsh web process loads a plugin build without the update service; restart dsh web (Ctrl+C, then run dsh web again) and retry.',\n 'update.error': 'Update failed',\n 'update.packages': 'Component versions',\n 'update.releaseNotes': 'v{version} release notes',\n 'update.releaseFeatures': 'New Features',\n 'update.releaseFixes': 'Bug Fixes',\n 'update.releaseOther': 'Other Changes',\n 'update.releaseUnavailable': 'Release notes are unavailable for this version; see the GitHub release instead.',\n 'update.componentVersions': 'View component versions',\n 'update.retry': 'Check again',\n 'update.close': 'Close update panel',\n 'update.error.pnpmMissing': 'pnpm was not found (tried pnpm / corepack / npx). Install pnpm and restart the app (Windows: npm install -g pnpm or corepack enable; macOS: brew install pnpm or corepack enable).',\n 'update.error.timeout': 'The update timed out and the install process was killed; try again.',\n 'update.error.notFound': 'The dsh-web aggregate package is not installed; nothing to update.',\n 'update.error.link': 'dsh-web or one of its components uses a local link. Sync the checkout, or remove a standalone link duplicated by the aggregate.',\n 'update.error.pnpmFailed': 'The update failed (pnpm exited with code {code}); see the output below.',\n 'update.error.stale': 'The update command ran but the installed versions did not change. Likely cause: the pnpm 11 minimumReleaseAge gate silently skips releases published less than 24 hours ago. Add minimumReleaseAgeExclude (e.g. \"@linxin666/*\") or set minimumReleaseAge: 0 in pnpm-workspace.yaml under the profile directory (~/.dsh/profiles/<profile>), then run the update again.',\n 'update.error.verifyFailed': 'The update command ran but the installed versions could not be verified afterwards (registry probe failed or the install path changed). Inspect the output below, or retry later.',\n 'update.error.unknown': 'Update failed; try again.',\n} satisfies Record<RemoteKey, string>\n","/**\n * Pair boot flow: the QR link's `pair` parameter. Runs from the client\n * apply on every page load, on any device: `pair` present → accept the\n * token, then reload so the whole SPA boots with the device cookie (the\n * accept endpoint is exempt from the pairing gate; every other /api request\n * needs the cookie). Every device — phone or PC — lands on the same official\n * Web GUI; phones get the injected portrait adaptation. Failure of accept\n * leaves a sessionStorage marker the entry renders as a one-time notice.\n */\n\nimport type { Context } from '@deepseek-ai/cordis'\nimport { acceptPair, readPairParams } from './pair-api.ts'\n\n/** sessionStorage key for the failed-pair notice. */\nexport const PAIR_FAILED_MARKER = 'dsh-remote-pair-failed'\n\n/**\n * The page-navigation surface the boot flow drives. Browser pages use the\n * default (window.location/history); tests inject a fake.\n */\nexport interface PageSurface {\n /** The current page URL (read fresh on each access). */\n href: string\n /** Replace the URL without reloading. */\n replaceState(url: string): void\n /** Navigate to a URL (a fresh page load). */\n navigate(url: string): void\n /** Reload the page. */\n reload(): void\n}\n\n/** The browser implementation of {@link PageSurface}. */\nexport const browserPage: PageSurface = {\n get href(): string {\n return window.location.href\n },\n replaceState(url: string): void {\n window.history.replaceState(null, '', url)\n },\n navigate(url: string): void {\n window.location.assign(url)\n },\n reload(): void {\n window.location.reload()\n },\n}\n\n/**\n * Run the pair boot flow for this page load.\n * @param ctx - client root context (unused since the deep-link retirement;\n * kept for call-site stability).\n * @param search - the current location.search.\n * @param page - the page surface (defaults to the browser).\n */\nexport function runPairBootFlow(ctx: Context, search: string, page: PageSurface = browserPage): void {\n void ctx\n const params = readPairParams(search)\n if (params.pair !== undefined) {\n void runAccept(params.pair, page)\n }\n}\n\n/** Accept the token, then reload into the paired official UI. */\nasync function runAccept(token: string, page: PageSurface): Promise<void> {\n let ok = false\n try {\n const result = await acceptPair(token)\n ok = result.ok\n if (!ok) sessionStorage.setItem(PAIR_FAILED_MARKER, 'failed')\n } catch {\n sessionStorage.setItem(PAIR_FAILED_MARKER, 'failed')\n }\n // Drop the token from the URL either way: an accepted token is consumed\n // (a re-scan would 409), and a failed one must not loop.\n const url = new URL(page.href)\n url.searchParams.delete('pair')\n page.replaceState(`${url.pathname}${url.search}${url.hash}`)\n if (ok) {\n // Every device reloads into the same official Web GUI at this origin.\n page.reload()\n }\n}\n","/**\n * Remote desktop channel constants — SDK-independent so tests and the\n * client half can pin them without importing the host SDK graph.\n *\n * Access model on the 0.1.2-alpha.2 line: the host /api surface has no\n * per-method privilege pin — the \"configuration plane is local\" behavior\n * lives in the browser (client plugins branch on connection.isLoopback), and\n * the paired remote desktop flips into host mode via the transport hook\n * (ownsHost) while every call rides this gated channel as a loopback-shaped\n * request. A paired device is therefore a full-control credential by\n * design; the only paths that stay physically local are the control planes\n * below (pairing control, self-update, plugin install/remove, host power).\n */\n\n/** Gated mirror of same-origin fenced paths (`/remote` + original pathname). */\nexport const REMOTE_PREFIX = '/remote'\n\n/** Connection-plugin method prefix under the gated channel. */\nexport const REMOTE_API_PREFIX = `${REMOTE_PREFIX}/api`\n\n/**\n * The gated mirrors of the official client WebSocket paths. On the pinned\n * 0.1.2-alpha.2 line the client opens ONE persistent stream socket — the\n * Typert gateway mux at `/api/remote.mux` — and every Remote stream\n * (workspace follow, session feed, ...) rides it. If that socket is not\n * rewritten onto the gated channel the phone's streams die at the connection\n * fence and the UI shows an empty workspace/session mirror, so the mux is\n * the one path that must never be missing here.\n */\nexport const REMOTE_API_PATHS = {\n mux: `${REMOTE_API_PREFIX}/remote.mux`,\n} as const\n\n/**\n * Exact upgrade paths registered on webServer (the SDK matches upgrades by\n * exact path, not prefix). Query strings ride on the request URL.\n */\nexport const REMOTE_UPGRADE_PATHS = [\n REMOTE_API_PATHS.mux,\n `${REMOTE_PREFIX}/sidebar/ws/terminal`,\n `${REMOTE_PREFIX}/sidebar/ws/agent-terminals`,\n `${REMOTE_API_PREFIX}/dsh-ssh/terminal`,\n] as const\n\n/** Plugin-manager HTTP prefix: install/remove stay physically local. */\nexport const PLUGIN_MANAGER_PATH = '/api/plugin-manager'\n\n/** Family settings-bridge HTTP prefix — re-exposed to paired devices (plain settings parity). */\nexport const WEB_UI_SETTINGS_BRIDGE_PATH = '/api/dsh-web-ui-settings'\n\n/**\n * The cookieless device credential: the boot patch reads the device id from\n * the /pair-app URL, keeps it in sessionStorage, and attaches it to every\n * gated HTTP call as this header (and to WebSocket upgrades as the `device`\n * query parameter - WS handshakes cannot carry headers from the Web API).\n * The channel gate accepts it exactly like the device cookie, so the mobile\n * flow works even with browser cookies fully blocked; the cookie remains the\n * primary credential on normal browsers.\n */\nexport const REMOTE_DEVICE_HEADER = 'x-dsh-remote-device'\nexport const REMOTE_DEVICE_QUERY = 'device'\n\n/**\n * Path prefixes that stay physically local even for a paired device. A\n * paired remote desktop may use the full host API (chat, sessions,\n * settings, credentials, presets — it is a full-control credential), but it\n * must not reach the machine-control planes: pairing control itself, the\n * dsh-web self-update installer, and plugin install/remove.\n */\nexport const LOCAL_ONLY_PREFIXES: readonly string[] = [\n '/api/pair',\n '/api/update',\n PLUGIN_MANAGER_PATH,\n] as const\n\n/**\n * Whether a paired inner path must stay physically local.\n * @param innerPath - the rewritten inner path (e.g. `/api/session.list`).\n * @returns a denial message, or undefined when the path may be proxied.\n */\nexport function localOnlyDenial(innerPath: string): string | undefined {\n for (const prefix of LOCAL_ONLY_PREFIXES) {\n if (innerPath === prefix || innerPath.startsWith(`${prefix}/`)) {\n return `${prefix.slice(1)} stays physically local and stays unreachable from a paired remote desktop`\n }\n }\n return undefined\n}\n","/**\n * The remote-channel rewrite contract as pure data (issue #987): both the\n * browser patch (client/remote-channel.ts) and the parse-time boot patch\n * (remote-channel-boot.ts, inlined into index.html by the host) decide from\n * these tables, so the two can never drift apart.\n * @module @linxin666/dsh-remote-web-ui/remote-channel-rules\n */\n\n/** The gated mirror prefix (must match src/remote-methods.ts). */\nexport const REMOTE_PREFIX = '/remote'\n\nimport { REMOTE_DEVICE_HEADER, REMOTE_DEVICE_QUERY } from './remote-methods.ts'\n\nexport { REMOTE_DEVICE_HEADER, REMOTE_DEVICE_QUERY }\n\n/** Connection-plugin method prefix under the gated channel. */\nexport const REMOTE_API_PREFIX = `${REMOTE_PREFIX}/api`\n\n/** Every decision input of the remote-channel rewrite, JSON-serializable. */\nexport interface RemoteChannelRules {\n readonly remotePrefix: string\n readonly apiPrefix: string\n readonly pairPrefix: string\n readonly updatePrefix: string\n readonly settingsBridgePrefix: string\n readonly sidebarPrefix: string\n readonly gitPrefix: string\n readonly petPrefix: string\n readonly wsPaths: readonly string[]\n /** Header carrying the cookieless device credential on gated fetches. */\n readonly deviceHeader: string\n /** sessionStorage key holding the device credential (set by /pair-app). */\n readonly deviceKey: string\n /** Query parameter carrying it on WebSocket upgrades. */\n readonly deviceQuery: string\n /** Raw upload route the boot hook keeps on the gated channel. */\n readonly uploadPath: string\n /** Page global the pre-Cordis upload hook is published under. */\n readonly uploadHookGlobal: string\n}\n\n/** The live rule set. */\nexport const REMOTE_CHANNEL_RULES: RemoteChannelRules = {\n remotePrefix: REMOTE_PREFIX,\n apiPrefix: '/api/',\n pairPrefix: '/api/pair/',\n updatePrefix: '/api/update/',\n settingsBridgePrefix: '/api/dsh-web-ui-settings',\n sidebarPrefix: '/sidebar/',\n gitPrefix: '/git/',\n petPrefix: '/pet/',\n // The official 0.1.2-alpha.2 line opens exactly one stream socket (the\n // Typert gateway mux, /api/remote.mux); the legacy /api/events.* paths\n // were removed by the SDK and stay absent here.\n wsPaths: [\n '/api/remote.mux',\n '/sidebar/ws/terminal',\n '/sidebar/ws/agent-terminals',\n '/api/dsh-ssh/terminal',\n ],\n deviceHeader: REMOTE_DEVICE_HEADER,\n deviceKey: 'dsh-remote-device',\n deviceQuery: REMOTE_DEVICE_QUERY,\n uploadPath: '/api/session/uploadFileBinary',\n uploadHookGlobal: '__DSH_FILE_UPLOAD__',\n}\n\n/** The window global the boot patch publishes its seat under. */\nexport const REMOTE_CHANNEL_BOOT_GLOBAL = '__DSH_REMOTE_CHANNEL_BOOT__'\n\n/**\n * The seat the parse-time boot patch installs: hook seats the plugin's\n * client apply adopts, a pending-unpaired flag for signals raised before\n * adoption, and restore() retiring the patch (also removes the global).\n */\nexport interface RemoteChannelBootSeat {\n onUnpaired: (() => void) | null\n onPaired: (() => void) | null\n pendingUnpaired: boolean\n restore(): void\n}\n","/**\n * The remote desktop channel — browser half. On a non-loopback origin (LAN\n * address or public tunnel) fenced host routes refuse the request, and\n * pairing is the real access control — so same-origin traffic the desktop\n * issues is rewritten onto this plugin's gated `/remote` prefix (host half\n * in src/remote-api.ts). The host then re-issues the call to 127.0.0.1 so\n * plugin loopback fences pass.\n *\n * The rewrite is deliberately narrow:\n * - loopback origins are untouched (the desktop at 127.0.0.1 keeps original paths);\n * - the pairing routes (`/api/pair/*`) stay where they are — accept must\n * work BEFORE a device is paired;\n * - the update endpoints (`/api/update/*`) stay loopback-only;\n * - the family settings bridge (`/api/dsh-web-ui-settings/*`) stays\n * loopback-only (same plane as SDK settings.*);\n * - `/api/*` (SDK methods and `/api/<plugin>/...` plugin namespaces),\n * `/sidebar/*`, `/git/*`, and `/pet/*` ride the channel;\n * - fetch, EventSource, WebSocket, and img/script/iframe `src` are patched;\n * everything else calls the original unchanged.\n *\n * Pure helpers are exported for unit tests; `installRemoteChannel` patches\n * the given window and returns their restore.\n */\n\nimport {\n REMOTE_API_PREFIX,\n REMOTE_CHANNEL_RULES,\n REMOTE_PREFIX,\n} from '../remote-channel-rules.ts'\n\nexport { REMOTE_API_PREFIX, REMOTE_PREFIX }\nexport type { RemoteChannelBootSeat } from '../remote-channel-rules.ts'\nexport { REMOTE_CHANNEL_BOOT_GLOBAL } from '../remote-channel-rules.ts'\n\nconst RULES = REMOTE_CHANNEL_RULES\n\n/** Minimal settings snapshot used by the remote channel decision. */\nexport interface RemoteChannelSettingsSnapshot {\n status: 'ready' | 'loading' | 'unavailable' | string\n value?: { enabled?: boolean; requirePairingForLan?: boolean }\n}\n\n/** Decide whether a remote desktop channel is required from local or host policy. */\nexport function remoteChannelRequired(\n hostname: string,\n snapshot: RemoteChannelSettingsSnapshot,\n hostPairingPolicy: boolean | undefined,\n): boolean {\n if (isLoopbackHostname(hostname)) return false\n if (snapshot.status === 'ready') {\n return (snapshot.value?.enabled ?? true) && (snapshot.value?.requirePairingForLan ?? true)\n }\n // Install provisionally while the host probe is pending so early SDK calls\n // cannot escape onto the plain remote origin. A confirmed false retires it.\n return hostPairingPolicy !== false\n}\n\n/**\n * Browser-safe loopback classification for the page origin (the SDK client\n * exports its own; this copy keeps the module dependency-free).\n * @param hostname - a location hostname (IPv6 without brackets).\n * @returns true for localhost, IPv6 loopback, or any 127/8 literal.\n */\nexport function isLoopbackHostname(hostname: string): boolean {\n if (hostname === 'localhost' || hostname === '::1') return true\n const parts = hostname.split('.')\n return parts.length === 4 && parts[0] === '127' && parts.every(part => /^\\d{1,3}$/.test(part) && Number(part) <= 255)\n}\n\n/**\n * Whether one same-origin path must ride the gated channel (fetch, EventSource,\n * img/script/iframe src).\n * @param pathname - the request URL pathname.\n */\nexport function shouldRewriteFetchPath(pathname: string): boolean {\n if (pathname.startsWith(RULES.pairPrefix)) return false\n if (pathname.startsWith(RULES.updatePrefix)) return false\n if (pathname === RULES.settingsBridgePrefix || pathname.startsWith(`${RULES.settingsBridgePrefix}/`)) return false\n if (pathname.startsWith(RULES.apiPrefix)) return true\n if (pathname.startsWith(RULES.sidebarPrefix) || pathname === '/sidebar') return true\n if (pathname.startsWith(RULES.gitPrefix) || pathname === '/git') return true\n if (pathname.startsWith(RULES.petPrefix) || pathname === '/pet') return true\n return false\n}\n\n/**\n * Whether one WebSocket path must ride the gated channel.\n * @param pathname - the WebSocket URL pathname.\n */\nexport function shouldRewriteWsPath(pathname: string): boolean {\n return RULES.wsPaths.includes(pathname)\n}\n\n/** The gated twin of one fenced path (`/remote` + original pathname). */\nexport function rewritePath(pathname: string): string {\n return `${REMOTE_PREFIX}${pathname}`\n}\n\n/**\n * Rewrite one raw URL string when it is same-origin and fenced. Relative\n * inputs stay relative so resource loaders do not unexpectedly absolutize.\n */\nexport function rewriteRawUrl(raw: string, baseHref: string, origin: string): string {\n let url: URL\n try {\n url = new URL(raw, baseHref)\n } catch {\n return raw\n }\n if (url.origin !== origin) return raw\n if (!shouldRewriteFetchPath(url.pathname)) return raw\n url.pathname = rewritePath(url.pathname)\n if (raw.startsWith('/') && !raw.startsWith('//')) {\n return `${url.pathname}${url.search}${url.hash}`\n }\n return url.href\n}\n\n/** A constructor that exposes a configurable `src` on its prototype. */\ninterface SrcConstructor {\n prototype: object\n}\n\n/** The subset of window the channel needs (injectable for tests). */\nexport interface ChannelWindow {\n fetch: typeof globalThis.fetch\n WebSocket: typeof WebSocket\n EventSource?: typeof EventSource\n HTMLImageElement?: SrcConstructor\n HTMLScriptElement?: SrcConstructor\n HTMLIFrameElement?: SrcConstructor\n location: { origin: string; href: string }\n sessionStorage?: { getItem(key: string): string | null }\n}\n\n/** Options for {@link installRemoteChannel}. */\nexport interface RemoteChannelOptions {\n /** Called when a gated call came back unpaired (code `unpaired`). */\n onUnpaired?: () => void\n /** Called when a gated call succeeded (an unpaired banner can retire). */\n onPaired?: () => void\n}\n\n/** Read an unpaired code from either the SDK envelope or a plugin JSON body. */\nfunction unpairedCodeOf(value: unknown): string | undefined {\n if (typeof value !== 'object' || value === null) return undefined\n const record = value as { result?: unknown; error?: unknown }\n const nested = record.result\n if (typeof nested === 'object' && nested !== null) {\n const error = (nested as { error?: unknown }).error\n if (typeof error === 'object' && error !== null && typeof (error as { code?: unknown }).code === 'string') {\n return (error as { code: string }).code\n }\n }\n const error = record.error\n if (typeof error === 'object' && error !== null && typeof (error as { code?: unknown }).code === 'string') {\n return (error as { code: string }).code\n }\n return undefined\n}\n\n/**\n * Whether a gated 403 is the unpaired-device fence (not a loopback-only\n * method denial, which uses the same status with code `forbidden`).\n */\nexport async function isUnpairedDenied(response: Response): Promise<boolean> {\n if (response.status !== 403) return false\n try {\n return unpairedCodeOf(await response.json()) === 'unpaired'\n } catch {\n return false\n }\n}\n\n/**\n * Wrap a prototype `src` setter so fenced same-origin URLs ride `/remote`.\n * No-ops when the constructor is missing or `src` is not configurable.\n */\nfunction patchSrcAccessor(ctor: SrcConstructor | undefined, rewrite: (value: string) => string): () => void {\n if (ctor === undefined) return () => {}\n const descriptor = Object.getOwnPropertyDescriptor(ctor.prototype, 'src')\n if (descriptor === undefined || descriptor.configurable === false) return () => {}\n if (descriptor.set === undefined) return () => {}\n const originalSet = descriptor.set\n const originalGet = descriptor.get\n Object.defineProperty(ctor.prototype, 'src', {\n configurable: true,\n enumerable: descriptor.enumerable ?? true,\n get: originalGet,\n set(this: unknown, value: unknown) {\n originalSet.call(this, rewrite(String(value)))\n },\n })\n return () => {\n Object.defineProperty(ctor.prototype, 'src', descriptor)\n }\n}\n\n/**\n * Patch `fetch`, `EventSource`, `WebSocket`, and resource `src` accessors on\n * one window to route fenced traffic through the gated channel.\n * @param window - the browser window (or a test double).\n * @param options - the unpaired callback.\n * @returns a function restoring the originals.\n */\nexport function installRemoteChannel(window: ChannelWindow, options: RemoteChannelOptions = {}): () => void {\n const originalFetch = window.fetch\n const OriginalWebSocket = window.WebSocket\n const OriginalEventSource = window.EventSource\n // Publish the official upload hook before the file-upload service reads it\n // (issue #1580); removed again by the restore below.\n const restoreUploadHook = installFileUploadHook(window as unknown as UploadHookWindow)\n\n const sameOrigin = (url: URL): boolean => url.origin === window.location.origin\n const rewrite = (raw: string): string => rewriteRawUrl(raw, window.location.href, window.location.origin)\n\n // The cookieless device credential (set by the /pair-app capture script):\n // attaches as a header on gated fetches and as the device query on WS and\n // EventSource handshakes, mirroring the boot patch exactly.\n const device = (() => {\n try {\n return window.sessionStorage?.getItem(RULES.deviceKey) ?? null\n } catch {\n return null\n }\n })()\n const attach = (init?: RequestInit): RequestInit | undefined => {\n if (device === null) return init\n const headers = init?.headers\n if (typeof Headers !== 'undefined' && headers instanceof Headers) {\n try { headers.set(RULES.deviceHeader, device) } catch { /* ignore */ }\n return init\n }\n if (typeof headers === 'object' && headers !== null) {\n return { ...init, headers: { ...(headers as Record<string, string>), [RULES.deviceHeader]: device } } as RequestInit\n }\n return init\n }\n const withDeviceQuery = (url: URL): URL => {\n if (device !== null) url.searchParams.set(RULES.deviceQuery, device)\n return url\n }\n\n const patchedFetch: typeof globalThis.fetch = (input, init) => {\n const url = new URL(\n typeof input === 'string' || input instanceof URL ? input.toString() : input.url,\n window.location.href,\n )\n if (sameOrigin(url) && shouldRewriteFetchPath(url.pathname)) {\n const rewritten = new URL(url)\n rewritten.pathname = rewritePath(url.pathname)\n const next: RequestInfo | URL = typeof input === 'string' || input instanceof URL\n ? rewritten.toString()\n : new Request(rewritten, input)\n return Promise.resolve(originalFetch.call(window, next, attach(init))).then(async (response) => {\n if (await isUnpairedDenied(response.clone())) options.onUnpaired?.()\n else options.onPaired?.()\n return response\n })\n }\n return originalFetch.call(window, input, init)\n }\n\n class PatchedWebSocket extends OriginalWebSocket {\n constructor(url: string | URL, protocols?: string | string[]) {\n const parsed = new URL(url.toString(), window.location.href)\n const wsOrigin = parsed.protocol === 'wss:' ? `https://${parsed.host}` : parsed.protocol === 'ws:' ? `http://${parsed.host}` : ''\n if (wsOrigin !== '' && wsOrigin === window.location.origin && shouldRewriteWsPath(parsed.pathname)) {\n const rewritten = new URL(parsed)\n rewritten.pathname = rewritePath(parsed.pathname)\n super(withDeviceQuery(rewritten), protocols)\n return\n }\n super(url, protocols)\n }\n }\n\n const restoreSrc = [\n patchSrcAccessor(window.HTMLImageElement, rewrite),\n patchSrcAccessor(window.HTMLScriptElement, rewrite),\n patchSrcAccessor(window.HTMLIFrameElement, rewrite),\n ]\n\n window.fetch = patchedFetch\n window.WebSocket = PatchedWebSocket as typeof WebSocket\n if (OriginalEventSource !== undefined) {\n class PatchedEventSource extends OriginalEventSource {\n constructor(url: string | URL, eventSourceInitDict?: EventSourceInit) {\n const parsed = new URL(url.toString(), window.location.href)\n if (sameOrigin(parsed) && shouldRewriteFetchPath(parsed.pathname)) {\n const rewritten = new URL(parsed)\n rewritten.pathname = rewritePath(parsed.pathname)\n super(withDeviceQuery(rewritten), eventSourceInitDict)\n return\n }\n super(url, eventSourceInitDict)\n }\n }\n window.EventSource = PatchedEventSource\n }\n\n return () => {\n window.fetch = originalFetch\n window.WebSocket = OriginalWebSocket\n if (OriginalEventSource !== undefined) window.EventSource = OriginalEventSource\n for (const restore of restoreSrc) restore()\n restoreUploadHook()\n }\n}\n\n/** Page global the official pre-Cordis upload hook is published under. */\nexport const FILE_UPLOAD_HOOK_GLOBAL = '__DSH_FILE_UPLOAD__'\n\n/** The subset of window the upload hook needs (injectable for tests). */\nexport interface UploadHookWindow {\n fetch: typeof globalThis.fetch\n location: { href: string; origin: string }\n /** Pre-existing hook owner; left untouched when present. */\n __DSH_FILE_UPLOAD__?: {\n fetch: (input: string | URL, init?: RequestInit) => Promise<Response>\n }\n}\n\n/**\n * Publish the official pre-Cordis upload hook so background uploads keep\n * riding the patched main-thread fetch (issue #1580).\n *\n * `@deepseek-ai/dsh-client-file-upload` reads `globalThis.__DSH_FILE_UPLOAD__`\n * once when its runtime is constructed; without it the carrier is a Web\n * Worker, whose own globals no main-thread patch reaches. That worker's XHR\n * goes straight to `<origin>/api/session/uploadFileBinary` with neither the\n * `/remote` rewrite nor the cookieless device credential, so the harness\n * browser-auth fence answers 401 and every upload from a paired browser\n * fails. Rewriting the worker URL cannot fix it: a worker context carries\n * neither the pairing cookie nor the device header.\n *\n * The hook hands the runtime the same transport the rest of the page uses -\n * the boot script publishes an identical one (remote-channel-boot.ts), and\n * this is the fallback for pages served without it.\n *\n * @param window - the browser window (or a test double), BEFORE the channel patch.\n * @returns a function retiring the hook (a pre-existing one is left alone).\n */\nexport function installFileUploadHook(window: UploadHookWindow): () => void {\n if (window.__DSH_FILE_UPLOAD__ !== undefined) return () => {}\n const originalFetch = window.fetch\n const hook = {\n fetch: (input: string | URL, init?: RequestInit): Promise<Response> => {\n const raw = typeof input === 'string' ? input : input.href\n let url: URL\n try {\n url = new URL(raw, window.location.href)\n } catch {\n return originalFetch.call(window, input, init)\n }\n // Delegate the whole decision to the patched fetch: rewriting the path\n // here first would make it skip its own rewrite branch and drop the\n // device credential the fence requires.\n if (url.origin === window.location.origin && url.pathname === RULES.uploadPath) {\n return window.fetch.call(window, raw, init)\n }\n return originalFetch.call(window, input, init)\n },\n }\n window.__DSH_FILE_UPLOAD__ = hook\n return () => {\n if (window.__DSH_FILE_UPLOAD__ === hook) delete window.__DSH_FILE_UPLOAD__\n }\n}\n\n/**\n * The remote-channel lifecycle transition between two steady states:\n * running (active + installed) and retired (inactive + not installed).\n * The client apply drives the channel with this decision and retires the\n * unpaired fence notice together with the channel itself — a notice raised\n * while the channel was briefly active must not outlive it (issue #808).\n */\nexport type ChannelTransition = 'install' | 'retire' | 'none'\n\n/**\n * Decide what the channel lifecycle must do next.\n * @param active - whether the gated remote channel should be running now.\n * @param installed - whether it currently is (disposer !== undefined).\n * @returns the transition to apply.\n */\nexport function channelTransition(active: boolean, installed: boolean): ChannelTransition {\n if (active && !installed) return 'install'\n if (!active && installed) return 'retire'\n return 'none'\n}\n","/**\n * Unpaired-desktop notice: a full-page blocking surface rendered when the remote channel\n * (see remote-channel.ts) refuses a call because this desktop browser has no\n * live paired-device cookie. Retires automatically once a gated call\n * succeeds (the channel reports pairing) or when the channel itself is\n * torn down (requirePairingForLan off / plugin disabled), so it never\n * outlives the unpaired state it describes.\n */\nimport { useState, type FormEvent } from 'react'\nimport type { TranslateNS } from '@deepseek-ai/dsh-client-ui-slots'\nimport { acceptPair } from './pair-api.ts'\nimport css from './remote.module.css'\n\n/** Notice props: localized copy. */\nexport interface FenceNoticeProps {\n t: TranslateNS<'remote'>\n /** Retry after the user has opened a freshly issued computer pairing link. */\n onRetry: () => void\n /** Optional custom pairing acceptor for testing / dependency injection. */\n onAccept?: (token: string) => Promise<{ ok: true } | { ok: false; code: 'invalid' | 'used' | 'forbidden' }>\n}\n\n/**\n * Extract a pairing token from either a raw token string or a copied pairing link URL.\n */\nexport function extractPairToken(input: string): string | undefined {\n const trimmed = input.trim()\n if (trimmed === '') return undefined\n try {\n const url = new URL(trimmed)\n const token = url.searchParams.get('pair')\n if (token !== null && token !== '') return token\n } catch {\n // Plain token string\n }\n return trimmed\n}\n\n/**\n * Render the unpaired blocking page.\n * @param props - localized copy.\n * @returns the notice element.\n */\nexport function FenceNotice({ t, onRetry, onAccept = acceptPair }: FenceNoticeProps) {\n const [tokenInput, setTokenInput] = useState('')\n const [submitting, setSubmitting] = useState(false)\n const [errorMsg, setErrorMsg] = useState<string | undefined>(undefined)\n\n const handleSubmit = async (event: FormEvent<HTMLFormElement>) => {\n event.preventDefault()\n const token = extractPairToken(tokenInput)\n if (!token) return\n\n setSubmitting(true)\n setErrorMsg(undefined)\n\n try {\n const result = await onAccept(token)\n if (result.ok) {\n onRetry()\n return\n }\n if (result.code === 'invalid') {\n setErrorMsg(t('fence.unpaired.tokenInvalid'))\n } else if (result.code === 'used') {\n setErrorMsg(t('fence.unpaired.tokenUsed'))\n } else {\n setErrorMsg(t('fence.unpaired.tokenFailed'))\n }\n } catch {\n setErrorMsg(t('fence.unpaired.tokenFailed'))\n } finally {\n setSubmitting(false)\n }\n }\n\n return (\n <div className={css.fencePage} role=\"dialog\" aria-modal=\"true\" aria-labelledby=\"remote-fence-title\">\n <main className={css.fenceCard} data-dsh-plugin=\"remote-web-ui\">\n <div className={css.fenceMark} aria-hidden=\"true\">×</div>\n <p className={css.fenceEyebrow}>{t('fence.unpaired.eyebrow')}</p>\n <h1 id=\"remote-fence-title\" className={css.fenceTitle}>{t('fence.unpaired.title')}</h1>\n <p className={css.fenceDetail}>{t('fence.unpaired.hint')}</p>\n <ol className={css.fenceSteps}>\n <li>{t('fence.unpaired.stepDesktop')}</li>\n <li>{t('fence.unpaired.stepLink')}</li>\n <li>{t('fence.unpaired.stepOpen')}</li>\n </ol>\n\n <form className={css.fenceForm} onSubmit={handleSubmit}>\n <div className={css.fenceInputRow}>\n <input\n type=\"text\"\n className={css.fenceInput}\n placeholder={t('fence.unpaired.tokenPlaceholder')}\n value={tokenInput}\n onChange={event => {\n setTokenInput(event.target.value)\n if (errorMsg !== undefined) setErrorMsg(undefined)\n }}\n disabled={submitting}\n aria-label={t('fence.unpaired.tokenPlaceholder')}\n />\n <button\n className={css.fencePairButton}\n type=\"submit\"\n disabled={submitting || tokenInput.trim() === ''}\n >\n {submitting ? t('fence.unpaired.pairing') : t('fence.unpaired.pairAction')}\n </button>\n </div>\n {errorMsg !== undefined && (\n <p className={css.fenceError} role=\"alert\">{errorMsg}</p>\n )}\n </form>\n\n <button className={css.fenceRetry} type=\"button\" onClick={onRetry}>\n {t('fence.unpaired.retry')}\n </button>\n <p className={css.fenceFootnote}>{t('fence.unpaired.footnote')}</p>\n </main>\n </div>\n )\n}\n","// Generated by scripts/sync-shared.mjs from shared/client/telemetry.ts. Do not edit this copy; edit the shared source and run \"node scripts/sync-shared.mjs\".\n/**\n * Anonymous install telemetry shared by the DSH Web UI family plugins.\n *\n * Once per UTC day per browser, each wired plugin sends one heartbeat to\n * the dsh-market edge API listing its package name (and version when known).\n * The payload carries no conversation data and no identifiers beyond a random\n * UUID generated in localStorage; the server hashes it with a deployment salt\n * before storage and never persists IP addresses. Sends are fire-and-forget:\n * failures stay silent and simply retry on a later mount or day. The system\n * is documented in docs/telemetry.md.\n */\n\nexport type TelemetryChannel = 'market' | 'npm' | 'unknown'\n\nexport interface TelemetryItem {\n /** npm package name or asset id, e.g. \"@linxin666/dsh-pet\" or \"skin:harbor\". */\n name: string\n /** Installed version when known; omitted otherwise. */\n version?: string\n /** Install channel when determinable (market = Workshop install). */\n channel?: TelemetryChannel\n}\n\nconst VISITOR_KEY = 'dsh-web-ui-telemetry-visitor'\nconst DAY_KEY_PREFIX = 'dsh-web-ui-telemetry-day:'\nconst ENDPOINT = 'https://dsh-market.com/api/telemetry/event'\n\n// Baked into each client bundle by shared/tsdown.client.ts (the package's own\n// package.json version at build time). Undefined in dev/test builds.\ndeclare const __DSH_PKG_VERSION__: string | undefined\n\n/** The building package's version, when the bundle carries it. */\nfunction bakedVersion(): string | undefined {\n try {\n return typeof __DSH_PKG_VERSION__ === 'string' && __DSH_PKG_VERSION__ !== ''\n ? __DSH_PKG_VERSION__\n : undefined\n } catch {\n return undefined\n }\n}\n\n/** Read or lazily create the anonymous visitor id; null when storage is unavailable. */\nfunction visitorId(): string | null {\n try {\n const existing = localStorage.getItem(VISITOR_KEY)\n if (existing && /^[A-Za-z0-9_-]{16,64}$/.test(existing)) return existing\n const fresh = crypto.randomUUID().replaceAll('-', '')\n localStorage.setItem(VISITOR_KEY, fresh)\n return fresh\n } catch {\n // Storage unavailable (privacy mode, sandboxed frame): report nothing.\n return null\n }\n}\n\n/** Drop stale per-day dedup keys so localStorage does not grow forever. */\nfunction pruneDayKeys(today: string): void {\n try {\n for (let index = localStorage.length - 1; index >= 0; index -= 1) {\n const key = localStorage.key(index)\n if (key !== null && key.startsWith(DAY_KEY_PREFIX) && key !== DAY_KEY_PREFIX + today) {\n localStorage.removeItem(key)\n }\n }\n } catch { /* best effort */ }\n}\n\n/**\n * Fire the daily heartbeat for the given items at most once per UTC day per\n * browser. Never throws and never blocks the caller. Items without an explicit\n * version inherit the bundle's baked build version.\n */\nexport function reportDailyHeartbeat(items: readonly TelemetryItem[]): void {\n try {\n if (items.length === 0) return\n const today = new Date().toISOString().slice(0, 10)\n // Automation contexts (CDP-driven QA browsers, fresh isolated profiles)\n // mint a new visitor id per run and would inflate instance counts.\n if (navigator.webdriver) return\n if (localStorage.getItem(DAY_KEY_PREFIX + today) !== null) return\n const visitor = visitorId()\n if (visitor === null) return\n pruneDayKeys(today)\n const payloadItems = items.map((item) => {\n const out: Record<string, string> = { name: item.name }\n const version = item.version ?? bakedVersion()\n if (version !== undefined) out.version = version\n if (item.channel !== undefined) out.channel = item.channel\n return out\n })\n const body = JSON.stringify({ kind: 'heartbeat', visitor, items: payloadItems })\n void fetch(ENDPOINT, {\n method: 'POST',\n headers: { 'content-type': 'application/json' },\n body,\n keepalive: true,\n }).then((response) => {\n // Mark the day only after an accepted send, so offline browsers retry\n // on a later mount instead of going dark until tomorrow.\n if (response.ok) localStorage.setItem(DAY_KEY_PREFIX + today, '1')\n }).catch(() => { /* unreachable endpoint: stay silent */ })\n } catch { /* never break the host UI over telemetry */ }\n}\n","/**\n * Portrait-touch adaptation of the OFFICIAL desktop Web GUI (the dsh-LAN\n * approach): while a touch device is in portrait, inject a CSS + gesture\n * layer on top of the running SPA instead of maintaining a second UI. The\n * official layout already auto-collapses the sidebar below 1024px; this\n * layer adds touch-target sizing, 16px inputs (iOS focus zoom), safe-area\n * padding, a floating whale button as the collapsed-sidebar entry (with a\n * verified toggle fallback for cohorts whose layout face mounts inert),\n * swipe gestures, long-press session menus, a bottom-sheet composer picker\n * (model / effort / permission menus), desktop-surface suppression, and\n * composer/header compaction.\n * Landscape, desktop, and wide viewports stay untouched; a manual\n * sessionStorage opt-out (dsh-remote-force-desktop=1) disables the layer.\n *\n * Selector strategy: CSS Modules class names are hash-prefixed with the\n * semantic name as a stable suffix (`pI_x6G_centerCol`), so attribute\n * suffix selectors survive official rebuilds that only change the hash. The\n * semantic names were read off the 0.1.2-alpha.1 official client build and\n * are re-verified on every GUI QA round; rules borrowed from the dsh-LAN\n * reference (MIT, v47-v78) keep their version comments.\n * @module @linxin666/dsh-remote-web-ui/client/mobile-adapt\n */\n\nimport type { RemoteKey } from './locales.ts'\n\n/** The window global the plugin apply() wires the layout service into. */\nexport interface RemoteAdaptGlobal {\n evaluate: () => void\n /** Wired by the plugin apply once ctx.layout is live. */\n toggleSidebar: (() => void) | null\n /** Wired by the plugin apply once ctx.layout is live. */\n closeDetails: (() => void) | null\n /**\n * Wired by the plugin apply once the `remote` locale namespace is bound:\n * the translate seat the injected surfaces (whale, compact picker) read\n * their labels from. Null until then; label reads fall back to English\n * (the SDK's universal fallback) and the 600ms sync tick re-renders the\n * labels once the seat is wired.\n */\n translate: ((key: RemoteKey) => string) | null\n /** Plugin master switch: false reverts the layer, true re-evaluates. */\n setEnabled(on: boolean): void\n /** Replays a pending closeDetails once the layout face is wired (the first apply ran before the wiring). */\n flushCloseDetails(): void\n}\n\n/** Storage key for the manual desktop opt-out. */\nconst FORCE_DESKTOP_KEY = 'dsh-remote-force-desktop'\n/** Storage key for the dragged whale position. */\nconst WHALE_POS_KEY = 'dsh-remote-whale-pos'\n/** Injected stylesheet identity. */\nconst ADAPT_CSS_ID = 'dsh-remote-web-ui/mobile-adapt.css'\n/** Body class while the adaptation is active. */\nconst ACTIVE_CLASS = 'dsh-remote-portrait'\n/** Body class while the collapsed rail is hidden behind the whale. */\nconst RAIL_HIDDEN_CLASS = 'dsh-remote-rail-hidden'\n/** Whale button id. */\nconst WHALE_ID = 'dshRemoteWhale'\n/** Compact picker: synthesized model button id. */\nconst MODEL_BTN_ID = 'dshRemoteModelPick'\n/** Compact picker: synthesized effort button id. */\nconst EFFORT_BTN_ID = 'dshRemoteEffortPick'\n/** Body class while the compact picker buttons are wired. */\nconst COMPACT_CLASS = 'dsh-remote-compact-picker'\n/** Body class while the header actions are seated in the tabs row. */\nconst HEADER_SEATED_CLASS = 'dsh-remote-header-seated'\n/**\n * Width the seated header actions paint over the tabs row, as a CSS variable\n * on <html>. The row caps its own width with it (see the v80 rules) instead of\n * reserving the space with padding.\n */\nconst HEADER_RESERVE_VAR = '--dsh-remote-header-actions-reserve'\n/** The two composer picker entries the compact buttons drill into. */\ntype PickerKind = 'model' | 'effort'\n/** Locale-dependent fast path for the official picker cells (zh/en). */\nconst PICKER_CELL_PATTERN: Record<PickerKind, RegExp> = {\n model: /模型|Model/, // i18n-allow: matches official picker cell text, not plugin copy\n effort: /推理等级|Reasoning|Effort/i, // i18n-allow: matches official picker cell text, not plugin copy\n}\n/** Position of each drill cell among the sheet's chevron cells. */\nconst DRILL_INDEX: Record<PickerKind, number> = { model: 0, effort: 1 }\n/**\n * The official application frame. The layout column classes are the anchor:\n * `_frame` is shared by unrelated official components (the chat turn rail,\n * message-image thumbnails, the subagent pill, PlanReviewPanel), so a bare\n * suffix match would restyle and hit-block those. `data-dsh-frame` is the\n * aggregate compat stamp, kept as the fast path.\n */\nconst APP_FRAME_SELECTOR = '[data-dsh-frame], [class*=\"_frame\"]:has([class*=\"_centerCol\"])'\n\n/**\n * The official composer surface. `_composerSeat` is the plugin's historical\n * anchor; the official `data-dsh-surface=\"composer\"` part attribute is the\n * stable alternative if the class ever gains a modifier.\n */\nconst COMPOSER_SELECTOR = '[class$=\"_composerSeat\"], [data-dsh-surface=\"composer\"]'\n\n/** Resolve the official application frame (never a nested `_frame` surface). */\nfunction appFrame(): HTMLElement | null {\n const frame = document.querySelector(APP_FRAME_SELECTOR)\n return frame instanceof HTMLElement ? frame : null\n}\n\n/**\n * Whether the current viewport is a portrait touch device small enough to\n * need the adaptation.\n */\nfunction isMobilePortrait(): boolean {\n if (typeof window === 'undefined') return false\n if (typeof window.matchMedia !== 'function') return false\n if (!window.matchMedia('(orientation: portrait)').matches) return false\n if (!window.matchMedia('(pointer: coarse)').matches) return false\n if (window.innerWidth >= 1100) return false\n if (window.sessionStorage.getItem(FORCE_DESKTOP_KEY) === '1') return false\n return true\n}\n\n/**\n * The injected rules. Grouped by surface; version comments trace rules back\n * to the dsh-LAN reference they were ported from.\n */\nconst ADAPT_CSS: readonly string[] = [\n 'html,body{height:100%}',\n // The app frame fills the dynamic viewport (browser chrome collapse).\n // Scoped to the application frame: a bare [class$=\"_frame\"] also matches the\n // chat turn rail, message thumbnails, the subagent pill and PlanReviewPanel,\n // stretching each to a full-width 100dvh pointer-events:auto block.\n '[class*=\"_frame\"]:has([class*=\"_centerCol\"]){width:100%;height:100dvh}',\n // Collapsed rail: bigger touch targets.\n '[class$=\"_railFish\"] button,[class$=\"_panelIcon\"],[class$=\"_newSession\"]{min-width:44px;min-height:44px}',\n // Message list padding on narrow screens.\n '[class$=\"_scroll\"]{padding:8px 10px}',\n // 16px inputs prevent iOS focus zoom; keep the send button touchy.\n '[class$=\"_input\"],textarea,input{font-size:16px}',\n '[class$=\"_composer\"]{padding-bottom:calc(4px + env(safe-area-inset-bottom))}',\n // v50: slightly smaller type on portrait phones.\n '[class$=\"_scrollBody\"] [class$=\"_root\"]{font-size:14.5px}',\n '[class$=\"_scrollBody\"] [class$=\"_bubble\"]{font-size:14.5px}',\n '[class$=\"_titleRow\"] *{font-size:13px}',\n '[class*=\"_sidebarCol\"] [class$=\"_root\"],[class*=\"_sidebarCol\"] [class$=\"_newSession\"],[class*=\"_sidebarCol\"] [class$=\"_trigger\"],[class*=\"_sidebarCol\"] [class$=\"_title\"]{font-size:13px}',\n '[class*=\"_sidebarCol\"] [class$=\"_meta\"],[class*=\"_sidebarCol\"] [class$=\"_time\"]{font-size:11.5px}',\n // v50: collapsed rail hidden; the whale button is the entry. The frame's\n // grid is inline-styled (56px rail track when collapsed); pin the first\n // track to 0 so content uses the full width. On portrait phones the\n // details track is always 0 (computeColumns drops it when there is no\n // room), so the three-track override is safe here.\n '[class$=\"_frame\"][data-sidebar-collapsed]{grid-template-columns:0 minmax(0,1fr) 0 !important}',\n // The official collapsed sidebar is an absolutely-positioned overlay rail\n // (it leaves the grid flow), so the in-flow centerCol would auto-place\n // into the now-0px FIRST track and collapse the conversation to zero width\n // on an intermittent basis (the rail flips relative <-> absolute as the\n // host overlay mounts). Pin every column to an explicit track so the\n // center always lands on the 1fr track regardless of the sidebar's\n // computed position.\n '[class$=\"_frame\"][data-sidebar-collapsed] [class*=\"_sidebarCol\"]{grid-column:1/2}',\n '[class$=\"_frame\"][data-sidebar-collapsed] [class$=\"_centerCol\"]{grid-column:2/3}',\n '[class$=\"_frame\"][data-sidebar-collapsed] [class$=\"_detailsCol\"]{grid-column:3/4}',\n // Keep the chat header title clear of the floating whale.\n `body.${RAIL_HIDDEN_CLASS} [class$=\"_titleRow\"]{padding-left:52px}`,\n // The whale button itself.\n `#${WHALE_ID}{position:fixed;top:calc(4px + env(safe-area-inset-top));left:calc(8px + env(safe-area-inset-left));z-index:2147482999;width:34px;height:34px;min-width:34px;padding:0;border-radius:10px;background:var(--dsw-alias-bg-module-platform);border:1px solid var(--dsw-alias-border-l2);color:var(--dsw-alias-label-primary);display:flex;align-items:center;justify-content:center;cursor:pointer;box-shadow:0 1px 6px rgba(0,0,0,.25)}`,\n `#${WHALE_ID} svg{width:20px;height:15px;display:block}`,\n `#${WHALE_ID}:active{opacity:.72}`,\n `#${WHALE_ID}{touch-action:none}`,\n // v51/v52: smaller collapse toggle in the expanded sidebar (the toggle\n // carries two classes, so match by containment); v47's panelIcon touch\n // rule forces a 44px min on the icon itself — zero it out so the 13px\n // glyph fits the 18px button.\n '[class*=\"_sidebarCol\"] [class$=\"_logoRow\"] [class*=\"_iconButton\"]{width:18px;height:18px}',\n '[class*=\"_sidebarCol\"] [class$=\"_logoRow\"] [class*=\"_iconButton\"] svg{width:13px;height:13px;min-width:0;min-height:0}',\n // v77: workspace rows' right-side actions (menu + new session) are\n // hover-only on desktop; always show them on mobile touch.\n '[class*=\"_sidebarCol\"] [class*=\"_projectRow\"] [class*=\"_rowActions\"]{display:inline-flex}',\n // v78: mobile long-press on a row must not start native drag.\n '[class*=\"_sidebarCol\"] [class*=\"_sessionRow\"],[class*=\"_sidebarCol\"] [class*=\"_projectRow\"]{-webkit-user-drag:none;user-select:none}',\n // Hide the header Session-log download button (no space on phones).\n '[class$=\"_headerUtilities\"]{display:none}',\n // v52 composer: the two lines (permission / model) stay stacked with zero\n // row gap; the command, context-meter and send/stop buttons float at the\n // left/right edges vertically centered over both lines.\n '[class$=\"_composerSeat\"] [class$=\"_card\"]{margin-bottom:1px}',\n '[class$=\"_composerSeat\"] [class$=\"_row\"]{flex-wrap:wrap;row-gap:0;padding:2px 8px 1px;position:relative}',\n '[class$=\"_composerSeat\"] [class$=\"_add\"]{position:absolute;left:8px;top:50%;transform:translateY(-50%)}',\n '[class$=\"_composerSeat\"] [class$=\"_modes\"]{min-width:0;padding-left:38px}',\n // Model line left-aligned with the permission line (same command-button\n // clearance), rows stay tightly stacked.\n '[class$=\"_composerSeat\"] [class$=\"_trailing\"]{flex-basis:100%;position:relative;min-height:32px;justify-content:flex-start;padding-left:38px;padding-right:78px}',\n '[class$=\"_composerSeat\"] [class$=\"_trailing\"] *{font-size:12px}',\n // v54: smaller permission/model buttons (font + height). v79: the\n // permission trigger collapses to its shield icon on phones — the label\n // text is the first thing a narrow row drops (the icon color carries the\n // state), matching the dsh-LAN compact composer.\n '[class$=\"_composerSeat\"] [class$=\"_modes\"] [class$=\"_trigger\"]{height:24px;min-height:24px;font-size:12px}',\n '[class$=\"_composerSeat\"] [class$=\"_trailing\"] [class$=\"_trigger\"]{height:24px;min-height:24px;font-size:11px}',\n // Context meter + send/stop float at the right edge, vertically centered\n // over both lines (the meter's root contains the track).\n '[class$=\"_composerSeat\"] [class$=\"_trailing\"] > [class$=\"_root\"]:has([class$=\"_track\"]){position:absolute;right:52px;top:50%;transform:translateY(-50%)}',\n '[class$=\"_composerSeat\"] [class$=\"_primary\"]{position:absolute;right:8px;top:50%;transform:translateY(-50%)}',\n // v79: the model picker menu anchors right:0 to its narrow trigger, so on\n // a phone both the picker menu and the model list fly past the left\n // viewport edge (model names unreadably cut). Turn the picker into a\n // bottom sheet: the composer seat carries an identity transform, which\n // would still become the containing block for fixed children, so free it\n // first; then pin every seat menu to the viewport bottom with real touch\n // targets. Covers the picker, the model list, and the other composer\n // popovers (permission presets, attachments) alike.\n '[class$=\"_composerSeat\"]{transform:none !important}',\n '[class$=\"_composerSeat\"] [class$=\"_menu\"]{position:fixed !important;left:8px !important;right:8px !important;top:auto !important;bottom:calc(8px + env(safe-area-inset-bottom)) !important;width:auto !important;max-width:none !important;max-height:70dvh !important;overflow-y:auto !important;z-index:2147482000}',\n '[class$=\"_composerSeat\"] [class$=\"_menu\"] [class$=\"_cell\"]{height:44px;min-height:44px;font-size:13px}',\n // v79 (compact picker): when the row is too narrow for the desktop text\n // triggers, the phone falls back to icon entries — the context ring stays\n // official, and two synthesized buttons open the picker sheet straight on\n // the model list and the effort list (drill-through, so one tap lands on\n // the same list the user's mock shows). The original text trigger hides\n // only while the wired buttons exist (body class): a failed wiring\n // degrades back to the usable text trigger instead of no picker.\n `body.${COMPACT_CLASS} [class$=\"_composerSeat\"] [class$=\"_trailing\"] [class$=\"_trigger\"]:has([class$=\"_triggerEffort\"]){display:none}`,\n // The icon buttons sit inline in the tools row (parallel to the\n // permission trigger), so the trailing line collapses to zero and the\n // context ring + send re-anchor to the row itself. The ring shifts a\n // few px right: at its desktop offset its hit box kisses the effort\n // button.\n `body.${COMPACT_CLASS} [class$=\"_composerSeat\"] [class$=\"_trailing\"]{flex-basis:auto;position:static;min-height:0;padding:0;width:0}`,\n `body.${COMPACT_CLASS} [class$=\"_composerSeat\"] [class$=\"_trailing\"] > [class$=\"_root\"]:has([class$=\"_track\"]){right:44px}`,\n `#${MODEL_BTN_ID},#${EFFORT_BTN_ID}{width:26px;height:32px;min-width:26px;padding:0;border-radius:9px;background:var(--dsw-alias-bg-module-platform);border:1px solid var(--dsw-alias-border-l2);color:var(--dsw-alias-label-primary);display:flex;align-items:center;justify-content:center;cursor:pointer;flex:none;margin-left:4px}`,\n\n\n `#${MODEL_BTN_ID} svg,#${EFFORT_BTN_ID} svg{width:16px;height:16px;display:block}`,\n `#${MODEL_BTN_ID}:active,#${EFFORT_BTN_ID}:active{opacity:.7}`,\n // Bottom stats line (N rounds / M steps) two sizes below the tabs; v55\n // wraps freely but clamps at two lines (the official rule is nowrap +\n // single-line ellipsis); v60 drops the official 32px right padding.\n '[class$=\"_composerSeat\"] [data-slot=\"conversation.composer.dock\"] [class$=\"_root\"]{font-size:10px;white-space:normal;word-break:break-word;overflow-wrap:anywhere;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden;text-align:left;line-height:13px;letter-spacing:-0.2px;padding-left:0;padding-right:0}',\n // (user bubbles keep the v50 14.5px via the _bubble rule.)\n '[class$=\"_scrollBody\"] [class$=\"_root\"]{font-size:13px}',\n // v58/v65 port note: the dsh-LAN `_body` gap:6px compaction is deliberately\n // NOT ported. The official message row is a shrinkable flex column whose\n // bottom-anchored body then measures shorter than its text (13px root font\n // on a fixed 24px line box), and the extra gap pushed the first text line\n // above the row box — every assistant message clipped its top half on the\n // phone (verified on the real GUI; the removal restores natural heights).\n // v58/v65: on touch, taps leave :hover/:focus stuck, so official Tooltip\n // bubbles stay visible on mobile. The bubble class hash sits AFTER the\n // name, so match by containment, still scoped by role=tooltip so user\n // message bubbles (no tooltip role) stay visible.\n '[class*=\"_bubble\"][role=\"tooltip\"]{display:none}',\n // v65: PlanReviewPanel shares the _frame/_card suffixes and overflows a\n // narrow phone; pin it to the viewport with border-box and cap its height\n // so the card sits fully on screen.\n '[class$=\"_composerSeat\"] [class$=\"_frame\"]{box-sizing:border-box;width:100%;max-width:100%;padding-left:12px;padding-right:12px;height:auto;max-height:calc(100dvh - 96px);align-items:flex-start;overflow-y:auto}',\n '[class$=\"_composerSeat\"] [class$=\"_frame\"] [class$=\"_card\"]{max-width:none;width:100%}',\n // v67: header actions (agent-preset mode label + background-task badge)\n // are re-seated from the title row into the tabs row; hidden in the\n // original spot so React re-renders do not flicker them back.\n // Only while the layer has taken the actions over: out of flow (so the\n // title row keeps its own layout and React keeps owning the node) and\n // painted over the tabs row by the transform alignActionsText computes.\n `body.${HEADER_SEATED_CLASS} [class$=\"_header\"] [class$=\"_titleCluster\"] [class$=\"_headerActions\"]{position:absolute;left:0;top:0;margin:0;display:flex;align-items:center;gap:6px;flex:none;z-index:2}`,\n // v70: match the tab text size with the seated mode label (12px); NB\n // [class$=\"_tab\"] misses the active tab (its class ends in \"_tabActive\")\n // — containment so BOTH tabs match.\n '[class$=\"_header\"] [class$=\"_tabs\"] [class*=\"_tab\"]{font-size:12px;white-space:nowrap}',\n // v80: the tabs row must give the painted actions their width up on its own.\n // The v67 padding reservation could not do it: the row is a nowrap flex\n // container, and once the tab labels plus their gaps overflow the reduced\n // content box the flex items spill over the padding box, so the trailing\n // tabs render underneath the actions (reported on a phone: a long agent\n // preset label covered the last tabs). Cap the row against the reserve and\n // let the labels scroll instead. The value rides a CSS variable on <html>\n // because the update lands before React re-creates the row node, and an\n // inline reservation on that node is dropped until the next sync tick.\n // The 2px bottom padding keeps the active-tab underline inside the clipping\n // box; the matching negative margin keeps the header height official.\n `body.${HEADER_SEATED_CLASS} [class$=\"_header\"] [class$=\"_tabs\"]{max-width:max(0px,calc(100% - var(${HEADER_RESERVE_VAR},0px)));overflow-x:auto;overflow-y:hidden;scrollbar-width:none;-webkit-overflow-scrolling:touch;padding-bottom:2px;margin-bottom:-2px}`,\n `body.${HEADER_SEATED_CLASS} [class$=\"_header\"] [class$=\"_tabs\"]::-webkit-scrollbar{display:none}`,\n `body.${HEADER_SEATED_CLASS} [class$=\"_header\"] [class$=\"_tabs\"] > [class*=\"_tab\"]{flex:0 0 auto}`,\n // Mobile scope: hide the plugin surfaces that do not fit a phone — the\n // right-hand details column and every desktop-oriented tool surface. The\n // list keys on the L2 semantic roots (data-dsh-plugin, ownership stays\n // with the declaring plugin), so official class churn cannot resurrect\n // them. These are render suppressions: the client bundles still load.\n // The pet is part of the hidden set by design: the mobile remote mirror\n // carries the desktop-less phone surface, and a floating pet would only\n // cover the small viewport. The suppression is the requirement, not a bug.\n `body.${ACTIVE_CLASS} [class$=\\\"_detailsCol\\\"]{display:none !important}`,\n `body.${ACTIVE_CLASS} [data-dsh-plugin=\\\"ssh\\\"],`,\n `body.${ACTIVE_CLASS} [data-dsh-plugin=\\\"skill-explorer\\\"],`,\n `body.${ACTIVE_CLASS} [data-dsh-plugin=\\\"task-board\\\"],`,\n `body.${ACTIVE_CLASS} [data-dsh-plugin=\\\"git-graph\\\"],`,\n `body.${ACTIVE_CLASS} [data-dsh-plugin=\\\"pet\\\"],`,\n `body.${ACTIVE_CLASS} [data-dsh-plugin=\\\"usage\\\"]{display:none !important}`,\n // The official workbench (Files / source control) mounts into a\n // full-viewport portal layer with no data-dsh-plugin root, so the plugin\n // list above cannot key on it; its open state persists across page loads,\n // and on a phone it covers the entire conversation with no visible close\n // control — the remote-opens-to-an-empty-screen report. Hide the\n // workbench panel only: the same portal layer also hosts the settings\n // modal, which must stay reachable (verified in the GUI QA round).\n `body.${ACTIVE_CLASS} [class$=\\\"_overlayLayer\\\"] [class$=\\\"_workbench\\\"]{display:none !important}`,\n // v68: settings modal on mobile — the official panel is a fixed 800px\n // two-column layout (nav + content); switch to a column layout: the\n // section nav becomes a horizontal scrollable row on top.\n '[class$=\"_overlay\"] [class$=\"_panel\"]{flex-direction:column;max-height:calc(100dvh - 32px)}',\n '[class$=\"_overlay\"] [class$=\"_panel\"] [class$=\"_nav\"]{flex-direction:row;gap:4px;width:100%;padding:12px 12px 0;overflow-x:auto;overflow-y:hidden}',\n '[class$=\"_overlay\"] [class$=\"_panel\"] [class$=\"_navTitle\"]{display:none}',\n '[class$=\"_overlay\"] [class$=\"_panel\"] [class$=\"_navList\"]{flex-direction:row;gap:4px}',\n '[class$=\"_overlay\"] [class$=\"_panel\"] [class$=\"_navCell\"]{height:34px;padding:0 12px;gap:6px;flex:none;border-radius:10px}',\n '[class$=\"_overlay\"] [class$=\"_panel\"] [class$=\"_navLabel\"]{font-size:13px}',\n '[class$=\"_overlay\"] [class$=\"_panel\"] [class$=\"_content\"]{flex:1;min-height:0}',\n]\n\n/** Cube glyph for the compact model button (a plain box outline). */\nconst CUBE_ICON = '<path d=\"M21 8a2 2 0 0 0-1-1.73l-7-4a2 2 0 0 0-2 0l-7 4A2 2 0 0 0 3 8v8a2 2 0 0 0 1 1.73l7 4a2 2 0 0 0 2 0l7-4A2 2 0 0 0 21 16Z\"/><path d=\"m3.3 7 8.7 5 8.7-5\"/><path d=\"M12 22V12\"/>'\n/** Level glyph for the compact effort button (three rising bars). */\nconst LEVELS_ICON = '<path d=\"M4 6h16\"/><path d=\"M7 12h10\"/><path d=\"M10 18h4\"/>'\n\n/** The DeepSeek fish glyph (the official brand mark path). */\nconst FISH_PATH = 'M22.9168 1.43018C22.6713 1.31018 22.5658 1.53918 22.4223 1.65519C22.3733 1.69269 22.3318 1.74169 22.2903 1.78669C21.9317 2.1697 21.5127 2.42121 20.9657 2.39121C20.1657 2.34621 19.4827 2.59771 18.8787 3.20973C18.7502 2.45521 18.3236 2.0047 17.6746 1.71569C17.3351 1.56568 16.9916 1.41518 16.7536 1.08867C16.5876 0.856163 16.5421 0.597155 16.4591 0.341647C16.4061 0.187643 16.3536 0.0301382 16.1761 0.00363739C15.9836 -0.0263635 15.9081 0.135141 15.8326 0.270145C15.5306 0.822162 15.4136 1.43018 15.4251 2.0462C15.4516 3.43174 16.0366 4.53527 17.1991 5.3203C17.3311 5.4103 17.3651 5.5003 17.3236 5.63181C17.2441 5.90231 17.1501 6.16482 17.0671 6.43533C17.0141 6.60784 16.9351 6.64584 16.7501 6.57033C16.1121 6.30383 15.5611 5.90931 15.074 5.4328C14.2475 4.63328 13.5 3.75075 12.568 3.05973C12.349 2.89822 12.13 2.74822 11.9034 2.60522C10.9524 1.68169 12.028 0.923165 12.277 0.833162C12.5375 0.739159 12.3675 0.41615 11.5259 0.42015C10.6844 0.42365 9.91439 0.705658 8.93286 1.08117C8.78935 1.13767 8.63835 1.17867 8.48384 1.21267C7.59332 1.04367 6.66829 1.00617 5.70226 1.11517C3.88321 1.31768 2.43016 2.1777 1.36213 3.64575C0.0790928 5.4103 -0.222916 7.41536 0.146595 9.50642C0.535106 11.7105 1.66014 13.535 3.38869 14.9616C5.18125 16.4406 7.24581 17.1657 9.60138 17.0266C11.0319 16.9441 12.6245 16.7526 14.421 15.2321C14.874 15.4576 15.3496 15.5476 16.1381 15.6151C16.7456 15.6716 17.3306 15.5851 17.7836 15.4911C18.4931 15.3411 18.4441 14.6841 18.1876 14.5636C16.1081 13.595 16.5646 13.9891 16.1496 13.67C17.2061 12.42 18.8202 10.1979 19.3182 7.17235C19.3672 6.83834 19.4297 6.36783 19.4222 6.09732C19.4182 5.93231 19.4562 5.86831 19.6447 5.84931C20.1657 5.78931 20.6712 5.64681 21.1357 5.3913C22.4833 4.65528 23.0268 3.44624 23.1548 1.9972C23.1738 1.77569 23.1508 1.54668 22.9168 1.43018Z'\n\n/**\n * Install the adaptation layer. Runs once per page (idempotent); the\n * evaluate loop re-applies on orientation/resize and reverts off-portrait.\n */\nexport function startMobileAdapt(): void {\n if (typeof window === 'undefined' || typeof document === 'undefined') return\n if ((window as unknown as { __dshRemoteAdaptInstalled?: boolean }).__dshRemoteAdaptInstalled === true) return\n ;(window as unknown as { __dshRemoteAdaptInstalled?: boolean }).__dshRemoteAdaptInstalled = true\n\n const w = window as unknown as { __dshRemoteAdapt?: RemoteAdaptGlobal } & Record<string, unknown>\n /**\n * Label lookup for the injected surfaces: the `remote` namespace seat wired\n * by the plugin apply, else the English fallback (the SDK's universal\n * fallback; the sync tick re-renders the labels once the seat is live).\n */\n const surfaceText = (key: RemoteKey, fallback: string): string => {\n try {\n const out = w.__dshRemoteAdapt?.translate?.(key)\n return typeof out === 'string' && out.length > 0 ? out : fallback\n } catch {\n return fallback\n }\n }\n let active = false\n let savedViewportContent: string | null = null\n let whaleEl: HTMLButtonElement | null = null\n let whaleObserver: MutationObserver | null = null\n /** Header subtree observer: marks the geometry measurement dirty on re-render. */\n let headerObserver: MutationObserver | null = null\n let observedHeader: Element | null = null\n /** Whether the seated-actions geometry needs re-measuring (see alignActionsText). */\n let headerGeometryDirty = true\n let whaleTimer: number | null = null\n let whaleSuppressClick = false\n let whaleShown = false\n let drag: { x: number; y: number; left: number; top: number; moved: boolean } | null = null\n let swipeTouch: { x: number; y: number; id: number } | null = null\n let lastComposerTap = 0\n // Plugin master switch: the module-scope layer installs before any config\n // is readable, so the plugin apply() flips this through setEnabled() once\n // the settings snapshot settles (disabled plugin = no injected surface).\n let adaptEnabled = true\n\n /**\n * Idempotently (re-)install the adaptation stylesheet. The rules live in\n * one <style> tag keyed by data-plugin-css; the sync tick re-runs this so\n * a tag lost to any external DOM cleanup is restored within one tick\n * instead of silently dropping the suppressions (portrait pet hiding,\n * rail compaction) while the body class stays.\n */\n function ensureAdaptStyle(): void {\n if (document.querySelector(`style[data-plugin-css=\"${ADAPT_CSS_ID}\"]`) !== null) return\n const tag = document.createElement('style')\n tag.dataset.plugin = 'remote-web-ui'\n tag.dataset.pluginCss = ADAPT_CSS_ID\n tag.textContent = ADAPT_CSS.join('')\n document.head.appendChild(tag)\n }\n\n function apply(): void {\n if (active) return\n active = true\n document.body.classList.add(ACTIVE_CLASS)\n // A details panel opened before the viewport rotated into portrait (or\n // restored across reloads) would sit behind the display:none above;\n // closing it through the official face unmounts the surface entirely.\n // The layout face throws by design when the root entry has not mounted\n // yet (boot-order), which is a tolerated no-op here — the plugin apply\n // replays it through flushCloseDetails once the wiring is live.\n try {\n w.__dshRemoteAdapt?.closeDetails?.()\n } catch {}\n ensureAdaptStyle()\n // viewport-fit=cover enables env(safe-area-inset-*); restore on revert.\n const meta = document.querySelector('meta[name=viewport]')\n if (meta instanceof HTMLMetaElement && meta.getAttribute('content') !== null && !(meta.getAttribute('content') ?? '').includes('viewport-fit')) {\n savedViewportContent = meta.getAttribute('content')\n meta.setAttribute('content', `${savedViewportContent}, viewport-fit=cover`)\n }\n ensureWhale()\n syncWhale()\n // React builds nodes with attributes before inserting them, so\n // attribute observers miss the initial collapsed state — a light\n // interval is the reliable sync.\n setWhaleTimer(true)\n seatHeaderActions()\n }\n\n function revert(): void {\n if (!active) return\n active = false\n unseatHeaderActions()\n restoreRowDrag()\n removeCompactPicker()\n document.body.classList.remove(ACTIVE_CLASS)\n document.body.classList.remove(RAIL_HIDDEN_CLASS)\n const tag = document.querySelector(`style[data-plugin-css=\"${ADAPT_CSS_ID}\"]`)\n tag?.remove()\n const meta = document.querySelector('meta[name=viewport]')\n if (meta instanceof HTMLMetaElement && savedViewportContent !== null) {\n meta.setAttribute('content', savedViewportContent)\n savedViewportContent = null\n }\n if (whaleEl !== null) whaleEl.style.display = 'none'\n setWhaleTimer(false)\n if (whaleObserver !== null) {\n whaleObserver.disconnect()\n whaleObserver = null\n }\n }\n\n /** Start/stop the 600ms sync tick; a no-op when already in the asked state. */\n function setWhaleTimer(on: boolean): void {\n if (on && whaleTimer === null && active) {\n whaleTimer = window.setInterval(syncWhale, 600)\n } else if (!on && whaleTimer !== null) {\n window.clearInterval(whaleTimer)\n whaleTimer = null\n }\n }\n\n /**\n * Compact picker (v79): a phone row cannot fit the desktop text triggers,\n * so the model/effort entries become two icon buttons in the trailing\n * row. Both forward to the official picker trigger (its menu renders as\n * the bottom sheet) and then drill straight into the asked cell — model\n * list or effort list — so one tap lands on the list, matching the\n * cube-model / brain-effort mapping. The official context ring next to\n * the send button keeps its own semantics untouched.\n */\n function removeCompactPicker(): void {\n document.body.classList.remove(COMPACT_CLASS)\n document.getElementById(MODEL_BTN_ID)?.remove()\n document.getElementById(EFFORT_BTN_ID)?.remove()\n }\n\n function drillIntoPicker(kind: PickerKind): void {\n const trigger = document.querySelector('[class$=\"_composerSeat\"] [class$=\"_trailing\"] [class$=\"_trigger\"]:has([class$=\"_triggerEffort\"])') as HTMLElement | null\n if (trigger === null) return\n trigger.click()\n // The sheet mount takes a beat (observed ~0.2-0.6s on a cold phone\n // mirror); poll until the asked cell exists instead of a fixed delay.\n let tries = 0\n const tapCell = (): void => {\n tries += 1\n const cells = Array.from(document.querySelectorAll('[class$=\"_composerSeat\"] [class$=\"_menu\"] [class$=\"_cell\"]'))\n // The official cell copy is localized (zh/en/ru), so the label match is\n // only the fast path; the sheet's drill cells (label + value + chevron)\n // are the structural anchor: model first, effort second, on every locale.\n const byLabel = cells.find((c) => PICKER_CELL_PATTERN[kind].test(c.textContent ?? ''))\n const drillable = cells.filter((c) => c.querySelector('[class*=\"_cellChevron\"], [class*=\"_chevron\"]'))\n const cell = byLabel ?? drillable[DRILL_INDEX[kind]]\n if (cell !== undefined) {\n ;(cell as HTMLElement).click()\n return\n }\n if (tries < 8) window.setTimeout(tapCell, 150)\n }\n window.setTimeout(tapCell, 150)\n }\n\n function makeCompactButton(id: string, title: string, icon: string, kind: PickerKind): HTMLButtonElement {\n const btn = document.createElement('button')\n btn.id = id\n btn.type = 'button'\n btn.dataset.dshPlugin = 'remote-web-ui'\n btn.title = title\n btn.setAttribute('aria-label', title)\n btn.innerHTML = `<svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\">${icon}</svg>`\n btn.addEventListener('click', () => { drillIntoPicker(kind) })\n return btn\n }\n\n function syncCompactPicker(): void {\n if (!active) return\n const tools = document.querySelector('[class$=\"_composerSeat\"] [class$=\"_tools\"]')\n const trigger = tools?.parentElement?.querySelector('[class$=\"_triggerEffort\"]')?.parentElement\n if (tools === null || trigger === null) {\n removeCompactPicker()\n return\n }\n if (document.getElementById(MODEL_BTN_ID) === null) {\n // The cell pattern matches the OFFICIAL picker cell text (the official\n // client's own zh/en copy), not plugin-owned text.\n tools.appendChild(makeCompactButton(MODEL_BTN_ID, surfaceText('mobile.composer.pickModel', 'Pick model'), CUBE_ICON, 'model'))\n }\n if (document.getElementById(EFFORT_BTN_ID) === null) {\n tools.appendChild(makeCompactButton(EFFORT_BTN_ID, surfaceText('mobile.composer.pickEffort', 'Pick reasoning effort'), LEVELS_ICON, 'effort'))\n }\n // Titles re-read every tick so a locale switch (or the translate seat\n // arriving after this layer installed) is picked up without a reload.\n for (const [id, key, fallback] of [\n [MODEL_BTN_ID, 'mobile.composer.pickModel', 'Pick model'],\n [EFFORT_BTN_ID, 'mobile.composer.pickEffort', 'Pick reasoning effort'],\n ] as const) {\n const btn = document.getElementById(id)\n if (btn === null) continue\n const label = surfaceText(key, fallback)\n btn.title = label\n btn.setAttribute('aria-label', label)\n }\n document.body.classList.add(COMPACT_CLASS)\n }\n /**\n * The official sidebar toggle in the logo row. The row's own `_toggle` class\n * is the precise anchor; the row's last button is the fallback for cohorts\n * that only expose the generic icon-button class (the first button is the\n * brand, which navigates home — never click that one). `_railFish` is kept\n * for older compositions that carried a rail fish button.\n */\n function officialSidebarToggle(): HTMLElement | null {\n const rail = document.querySelector('[class$=\"_railFish\"] button')\n if (rail instanceof HTMLElement) return rail\n const row = document.querySelector('[class$=\"_logoRow\"]')\n if (row === null) return null\n const toggles = row.querySelectorAll('button[class*=\"_toggle\"]')\n const last = toggles.length > 0 ? toggles[toggles.length - 1] : row.querySelectorAll('button')[row.querySelectorAll('button').length - 1]\n return last instanceof HTMLElement ? last : null\n }\n /**\n * Toggle the sidebar through the official rail/logo toggle first, then\n * verify the flip and fall back to the wired layout face.\n *\n * The order is evidence-driven: the official toggle owns its own store\n * actions and flips the state on every cohort we support, while the wired\n * LayoutController is mounted yet inert on the installed cohort — calling it\n * left `data-sidebar-collapsed` untouched for the whole 800ms observation\n * window, so face-first made every whale tap wait out the verification\n * delay before anything moved. The face stays the fallback for compositions\n * that render no logo-row toggle, and it is only called after the toggle\n * demonstrably failed, so the two can never cancel each other out.\n */\n function toggleSidebarVerified(): void {\n const frame = appFrame()\n const collapsedBefore = frame !== null ? frame.hasAttribute('data-sidebar-collapsed') : null\n const face = w.__dshRemoteAdapt?.toggleSidebar\n const callFace = (): void => {\n if (typeof face !== 'function') return\n try { face() } catch {}\n }\n const toggle = officialSidebarToggle()\n if (collapsedBefore === null || toggle === null) {\n // No frame to verify against, or no official toggle: the face is the\n // only available control.\n if (toggle !== null) toggle.click()\n else callFace()\n return\n }\n toggle.click()\n let tries = 0\n const verify = (): void => {\n if (!active) return\n const frameNow = appFrame()\n if (frameNow === null) return\n if (frameNow.hasAttribute('data-sidebar-collapsed') !== collapsedBefore) return\n tries += 1\n if (tries < 2) {\n window.setTimeout(verify, 120)\n return\n }\n callFace()\n }\n window.setTimeout(verify, 120)\n }\n function ensureWhale(): void {\n if (whaleEl !== null || !document.body) return\n const whale = document.createElement('button')\n whale.id = WHALE_ID\n whale.type = 'button'\n whale.dataset.dshPlugin = 'remote-web-ui'\n // The label reads the `remote` namespace (wired by the plugin apply);\n // before wiring it falls back to English and the sync tick re-renders it.\n const whaleLabel = surfaceText('mobile.whale.open', 'Open sidebar')\n whale.title = whaleLabel\n whale.setAttribute('aria-label', whaleLabel)\n whale.innerHTML = `<svg viewBox=\"0 0 23.16 17.04\" fill=\"none\" aria-hidden=\"true\"><path d=\"${FISH_PATH}\" fill=\"currentColor\"/></svg>`\n whale.addEventListener('click', () => {\n if (whaleSuppressClick) {\n whaleSuppressClick = false\n return\n }\n toggleSidebarVerified()\n })\n // v51: the whale floats — pointer-drag repositions it (persisted).\n whale.addEventListener('pointerdown', (e) => {\n if (whaleEl === null) return\n if (e.button !== 0 && e.pointerType === 'mouse') return\n // v61: opening the sidebar must not leave a focused composer input\n // behind — on phones a still-focused input makes the first tap re-pop\n // the keyboard (iOS) or keeps it open. Blur at pointerdown (before the\n // tap completes; click is too late for iOS) and block pending\n // programmatic refocus.\n if (active && isComposerField(document.activeElement)) {\n // The composer field is a contenteditable div (the official client\n // renders no textarea), so the old textarea/input lookup never matched\n // it while a bare `input` branch could blur an unrelated field.\n document.activeElement.blur()\n lastComposerTap = 0\n }\n drag = { x: e.clientX, y: e.clientY, left: whale.offsetLeft, top: whale.offsetTop, moved: false }\n try { whale.setPointerCapture(e.pointerId) } catch {}\n e.preventDefault()\n e.stopPropagation()\n })\n whale.addEventListener('pointermove', (e) => {\n if (whaleEl === null || drag === null) return\n const dx = e.clientX - drag.x\n const dy = e.clientY - drag.y\n drag.moved = drag.moved || Math.abs(dx) > 3 || Math.abs(dy) > 3\n whaleEl.style.left = `${Math.min(Math.max(4, drag.left + dx), window.innerWidth - 38)}px`\n whaleEl.style.top = `${Math.min(Math.max(4, drag.top + dy), window.innerHeight - 38)}px`\n e.preventDefault()\n e.stopPropagation()\n })\n const endWhaleDrag = (): void => {\n if (whaleEl === null || drag === null) return\n const moved = drag.moved\n drag = null\n whaleSuppressClick = moved\n try {\n window.localStorage.setItem(WHALE_POS_KEY, JSON.stringify({ x: whaleEl.offsetLeft, y: whaleEl.offsetTop }))\n } catch {}\n }\n whale.addEventListener('pointerup', endWhaleDrag)\n // A cancelled pointer (system gesture, incoming call) is not a drag end:\n // keep the click un-suppressed so the next real tap still toggles.\n whale.addEventListener('pointercancel', () => {\n drag = null\n whaleSuppressClick = false\n })\n whaleEl = whale\n document.body.appendChild(whale)\n }\n\n /**\n * Restore the official draggable state this layer overrode while active.\n * Rows are React-owned and may have been re-created meanwhile, so only the\n * tracked elements are touched; a detached element is skipped.\n */\n function restoreRowDrag(): void {\n if (dragOverridden.size === 0) return\n for (const [row, original] of dragOverridden) {\n if (!row.isConnected) continue\n if (original === null) row.removeAttribute('draggable')\n else row.setAttribute('draggable', original)\n }\n dragOverridden.clear()\n }\n\n /** Restore a dragged position when the whale becomes visible again. */\n function applyWhalePos(): void {\n if (whaleEl === null) return\n let pos: { x?: unknown; y?: unknown } | null = null\n try {\n pos = JSON.parse(window.localStorage.getItem(WHALE_POS_KEY) ?? 'null') as { x?: unknown; y?: unknown } | null\n } catch {}\n if (pos !== null && typeof pos.x === 'number' && typeof pos.y === 'number') {\n // Clamp to the current viewport: a position saved on a larger screen\n // (resize, split-screen, rotation) must not park the whale — the only\n // portrait sidebar entry — out of reach.\n const x = Math.min(Math.max(4, pos.x), window.innerWidth - 38)\n const y = Math.min(Math.max(4, pos.y), window.innerHeight - 38)\n whaleEl.style.left = `${x}px`\n whaleEl.style.top = `${y}px`\n }\n }\n\n // v78: on touch, official session/project rows are draggable for\n // reordering; a long-press would start native drag instead of our action\n // menu. Force them non-draggable while the adapt is active (React may\n // re-create rows, so re-apply on the sync tick).\n /** Rows whose official draggable state this layer overrode (restored on revert). */\n const dragOverridden = new Map<Element, string | null>()\n function disableRowDrag(): void {\n if (!active) return\n const rows = document.querySelectorAll('[class*=\"_sidebarCol\"] [class*=\"_sessionRow\"], [class*=\"_sidebarCol\"] [class*=\"_projectRow\"]')\n for (const row of rows) {\n if (row.getAttribute('draggable') !== 'false') {\n if (!dragOverridden.has(row)) dragOverridden.set(row, row.getAttribute('draggable'))\n row.setAttribute('draggable', 'false')\n }\n }\n }\n\n function syncWhale(): void {\n // Keep the stylesheet present while the layer is active (the tick runs\n // every 600ms; see ensureAdaptStyle for why the tag can need a re-assert).\n if (active) ensureAdaptStyle()\n if (whaleEl === null) return\n if (!active) {\n whaleEl.style.display = 'none'\n return\n }\n const collapsed = appFrame()?.hasAttribute('data-sidebar-collapsed') === true\n const overlayUp = document.querySelector('[class$=\"_overlay\"]') !== null\n const show = collapsed && !overlayUp\n // Restore on every hidden-to-shown transition — including the very\n // first show on a fresh page load, where the inline display is still\n // '' and a CSS-read guard would never fire.\n if (show && !whaleShown) applyWhalePos()\n whaleEl.style.display = show ? '' : 'none'\n whaleShown = show\n // Re-read the label every tick so a locale switch is picked up live.\n const whaleLabel = surfaceText('mobile.whale.open', 'Open sidebar')\n if (whaleEl.title !== whaleLabel) whaleEl.title = whaleLabel\n if (whaleEl.getAttribute('aria-label') !== whaleLabel) whaleEl.setAttribute('aria-label', whaleLabel)\n document.body.classList.toggle(RAIL_HIDDEN_CLASS, collapsed)\n disableRowDrag()\n seatHeaderActions()\n alignActionsText()\n syncCompactPicker()\n }\n\n // v67: on mobile the header actions (agent-preset mode label + background\n // task badge) move from the title row into the tabs row. React re-creates\n // the node in its original spot on re-render, so the interval re-seats it;\n // stale seated copies are removed first. The original spot is only hidden\n // while a seat actually exists: the tabs row renders only for multi-tab\n // sessions, and hiding the actions without a seat target made them vanish.\n function seatHeaderActions(): void {\n if (!active) return\n const header = document.querySelector('[class$=\"_header\"]')\n const tabs = header !== null ? header.querySelector('[class$=\"_tabs\"]') : null\n const actions = header !== null ? header.querySelector('[class$=\"_titleCluster\"] [class$=\"_headerActions\"]') : null\n // The actions node is NOT moved: it is a React-owned host node whose badge\n // button carries live handlers, and re-parenting it makes React's later\n // insertBefore/removeChild anchors point at a node that is no longer a\n // child of the recorded parent (a NotFoundError in the commit phase). The\n // injected CSS takes it out of flow and the transform below paints it over\n // the tabs row instead.\n const seated = header !== null && tabs !== null && actions !== null\n document.body.classList.toggle(HEADER_SEATED_CLASS, seated)\n ensureHeaderObserver(seated ? header : null)\n }\n\n // Paint the mode/badge over the tabs row: the actions keep their DOM slot in\n // the title cluster (out of flow via CSS) and are moved with a transform, so\n // the tabs row reserves room with padding instead of the node being moved.\n // The tabs row height is not stable (a background task badge grows it) and\n // the official right padding differs per cohort, so both axes are measured\n // and converged each time the header geometry is dirty.\n function alignActionsText(): void {\n if (!active) return\n const header = document.querySelector('[class$=\"_header\"]')\n if (header === null) return\n const tabs = header.querySelector('[class$=\"_tabs\"]')\n const actions = header.querySelector('[class$=\"_titleCluster\"] [class$=\"_headerActions\"]')\n if (tabs === null || actions === null || !(tabs instanceof HTMLElement) || !(actions instanceof HTMLElement)) return\n if (!headerGeometryDirty) return\n headerGeometryDirty = false\n const tabBtn = tabs.querySelector(':scope > [class*=\"_tab\"]')\n const textBottom = (el: Element | null): number | null => {\n if (el === null) return null\n const text = Array.from(el.childNodes).find((n) => n.nodeType === 3 && n.textContent !== null && n.textContent.trim() !== '')\n if (text === undefined) return null\n try {\n const range = document.createRange()\n range.selectNode(text)\n return range.getBoundingClientRect().bottom\n } catch {\n return null\n }\n }\n const translate = /translate\\((-?[\\d.]+)px,\\s*(-?[\\d.]+)px\\)/.exec(actions.style.transform ?? '')\n let dx = translate !== null ? parseFloat(translate[1] ?? '0') : 0\n let dy = translate !== null ? parseFloat(translate[2] ?? '0') : 0\n const actionsRect = actions.getBoundingClientRect()\n // Horizontal: the actions' right edge lands on the header's content edge,\n // NOT on the tabs row's right edge. The row caps its own width against the\n // reserve below (v80), so anchoring to the row would let the pair walk\n // leftwards on every measurement.\n const headerRect = header.getBoundingClientRect()\n const headerStyle = getComputedStyle(header)\n const contentRight = headerRect.right - (parseFloat(headerStyle.paddingRight) || 0) - (parseFloat(headerStyle.borderRightWidth) || 0)\n const rightDiff = contentRight - actionsRect.right\n if (Math.abs(rightDiff) >= 0.5) dx = Math.round((dx + rightDiff) * 10) / 10\n // Vertical: the actions' text bottom lands on the tab text bottom.\n const tabBottom = textBottom(tabBtn)\n if (tabBottom !== null) {\n let maxBottom: number | null = null\n for (const sel of ['[class$=\"_label\"]', '[class$=\"_count\"]']) {\n const b = textBottom(actions.querySelector(sel))\n if (b !== null && (maxBottom === null || b > maxBottom)) maxBottom = b\n }\n if (maxBottom !== null) {\n const bottomDiff = tabBottom - maxBottom\n if (Math.abs(bottomDiff) >= 0.5) dy = Math.round((dy + bottomDiff) * 10) / 10\n }\n }\n const next = `translate(${dx}px, ${dy}px)`\n if (actions.style.transform !== next) actions.style.transform = next\n // Reserve the painted width on the row itself, so the tab labels never\n // slide under it. The value rides a CSS variable on <html>: React\n // recreates the row node on re-render, which would drop an inline\n // reservation until the next sync tick, and until then the labels render\n // underneath the painted actions.\n const reserve = `${Math.ceil(actionsRect.width) + 8}px`\n const rootStyle = document.documentElement.style\n if (rootStyle.getPropertyValue(HEADER_RESERVE_VAR) !== reserve) rootStyle.setProperty(HEADER_RESERVE_VAR, reserve)\n }\n\n function unseatHeaderActions(): void {\n document.body.classList.remove(HEADER_SEATED_CLASS)\n document.documentElement.style.removeProperty(HEADER_RESERVE_VAR)\n const header = document.querySelector('[class$=\"_header\"]')\n const tabs = header !== null ? header.querySelector('[class$=\"_tabs\"]') : null\n const actions = header !== null ? header.querySelector('[class$=\"_titleCluster\"] [class$=\"_headerActions\"]') : null\n if (actions instanceof HTMLElement) actions.style.transform = ''\n // The v67 padding reservation is gone with the v80 cap; clearing it keeps a\n // profile that hot-updated from an older build from keeping a stale inline\n // width on the row.\n if (tabs instanceof HTMLElement) tabs.style.paddingRight = ''\n if (headerObserver !== null) {\n headerObserver.disconnect()\n headerObserver = null\n observedHeader = null\n }\n }\n\n function ensureWhaleObserver(): void {\n if (whaleObserver !== null || typeof MutationObserver === 'undefined' || !document.body) return\n whaleObserver = new MutationObserver(() => { syncWhale() })\n whaleObserver.observe(document.body, { attributes: true, attributeFilter: ['data-sidebar-collapsed'], subtree: true })\n }\n\n /**\n * Observe the conversation header subtree and mark its geometry dirty on any\n * re-render (label text, badge count, node replacement). The per-tick\n * alignment then reads layout only when the header actually changed instead\n * of on every tick while a message streams. The observer is swapped when the\n * header node is replaced and disconnected with the layer.\n */\n function ensureHeaderObserver(header: Element | null): void {\n if (typeof MutationObserver === 'undefined') return\n if (observedHeader === header && headerObserver !== null) return\n headerObserver?.disconnect()\n headerObserver = null\n observedHeader = null\n if (header === null) return\n headerObserver = new MutationObserver(() => { headerGeometryDirty = true })\n headerObserver.observe(header, { childList: true, subtree: true, characterData: true, attributes: true, attributeFilter: ['class'] })\n observedHeader = header\n headerGeometryDirty = true\n }\n\n function evaluate(): void {\n // A viewport change invalidates every measured position.\n headerGeometryDirty = true\n if (!adaptEnabled) {\n revert()\n return\n }\n if (isMobilePortrait()) {\n apply()\n ensureWhaleObserver()\n } else {\n revert()\n }\n }\n evaluate()\n window.addEventListener('orientationchange', evaluate)\n window.addEventListener('resize', evaluate)\n // The 600ms tick is a page-lifetime wake source; pause it while the page\n // is hidden (backgrounded phone tab) and resume on return.\n document.addEventListener('visibilitychange', () => { setWhaleTimer(document.visibilityState !== 'hidden') })\n\n // v51: Enter only inserts a newline on mobile (send goes through the send\n // button). Captured at document level so the official Enter-to-send\n // handler never sees the event. The rewrite is scoped to the composer:\n // `_input` is also the class of the settings, plugin and agent-preset text\n // fields, where swallowing Enter and inserting a newline into a single-line\n // input left the key dead.\n function onKeydownCapture(e: KeyboardEvent): void {\n if (!active) return\n if (e.key !== 'Enter' || e.shiftKey || e.ctrlKey || e.metaKey || e.altKey) return\n const t = e.target\n if (!(t instanceof HTMLElement)) return\n if (composerFieldOf(t) === null) return\n // keyCode 229 is the classic IME-confirm signal (Safari fires\n // compositionend before the Enter keydown) — never treat it as a\n // plain newline.\n if (e.isComposing || e.keyCode === 229) return\n e.preventDefault()\n e.stopPropagation()\n try { document.execCommand('insertText', false, '\\n') } catch {}\n }\n document.addEventListener('keydown', onKeydownCapture, true)\n\n function collapseSidebar(): void {\n toggleSidebarVerified()\n }\n\n // Auto-collapse the expanded sidebar on mobile: after clicking a session\n // row, or when tapping anywhere outside the sidebar (overlays/dialogs and\n // the whale excluded).\n function onClickCapture(e: MouseEvent): void {\n if (!active) return\n const frame = appFrame()\n if (frame === null || frame.hasAttribute('data-sidebar-collapsed')) return\n const t = e.target\n if (!(t instanceof Element)) return\n if (t.closest('[class*=\"_sidebarCol\"]') !== null) {\n // v68: opening settings also folds the sidebar so the modal closes\n // back into a clean conversation view. Clicks on the session\n // row-actions ellipsis (or its opened menu anchor) must NOT collapse\n // the sidebar — they open the action menu. v76: clicking the top-level\n // New Session also folds. v77: clicking a workspace row's new-session\n // button also folds.\n const topNewSessionClicked = t.closest('[class$=\"_newSession\"], [class$=\"_brand\"]') !== null\n let projectNewSessionClicked = false\n const projectActions = t.closest('[class*=\"_projectRow\"] [class*=\"_rowActions\"]')\n if (projectActions !== null) {\n const btn = t.closest('button')\n const btns = projectActions.querySelectorAll('button')\n projectNewSessionClicked = btn !== null && btns.length > 0 && btn === btns[btns.length - 1]\n }\n let shouldCollapse = false\n if (t.closest('[class*=\"_sessionRow\"]') !== null) {\n shouldCollapse = t.closest('[class*=\"_rowActions\"]') === null\n } else if (t.closest('[class$=\"_settingsArea\"]') !== null || topNewSessionClicked || projectNewSessionClicked) {\n shouldCollapse = true\n }\n if (shouldCollapse) collapseSidebar()\n return\n }\n if (t.closest('[class$=\"_overlay\"], [class$=\"_dialog\"], [class$=\"_menu\"], [class*=\"_portal\"], [id=\"dshRemoteWhale\"], [id=\"dshLanGate\"]') !== null) return\n collapseSidebar()\n }\n document.addEventListener('click', onClickCapture, true)\n\n // v65/v66: swipe gestures. Swiping LEFT while the sidebar is expanded\n // collapses it; swiping RIGHT in the conversation view opens it. Vertical\n // swipes (list scrolling), swipes starting on inputs, on the whale, or\n // inside horizontally scrollable containers are ignored.\n function insideHScrollable(el: Element): boolean {\n let n: Element | null = el\n while (n !== null && n !== document.body) {\n const cs = getComputedStyle(n)\n if ((cs.overflowX === 'auto' || cs.overflowX === 'scroll') && n.scrollWidth > n.clientWidth + 4) return true\n n = n.parentElement\n }\n return false\n }\n document.addEventListener('touchstart', (e) => {\n if (!active) return\n // Multi-finger touches are never a swipe: a pinch that happens to end with\n // >60px of horizontal finger travel would otherwise toggle the sidebar.\n if (e.touches.length > 1) {\n swipeTouch = null\n return\n }\n const t = e.target\n const editable = t instanceof HTMLElement && t.isContentEditable\n if (t instanceof Element && (t.tagName === 'TEXTAREA' || t.tagName === 'INPUT' || editable || t.closest(`#${WHALE_ID}`) !== null || insideHScrollable(t) || t.closest('table, [class$=\"_table\"], [class$=\"_tablePane\"]') !== null)) {\n swipeTouch = null\n return\n }\n const ct = e.changedTouches[0]\n if (ct === undefined) return\n swipeTouch = { x: ct.clientX, y: ct.clientY, id: ct.identifier }\n }, { capture: true, passive: true })\n document.addEventListener('touchend', (e) => {\n if (swipeTouch === null) return\n // Still more than one finger down: a pinch is in progress, not a swipe.\n if (e.touches.length > 0) return\n const ct = e.changedTouches[0]\n if (ct === undefined || ct.identifier !== swipeTouch.id) return\n const dx = ct.clientX - swipeTouch.x\n const dy = ct.clientY - swipeTouch.y\n swipeTouch = null\n if (!active) return\n if (Math.abs(dx) < 60 || Math.abs(dx) < Math.abs(dy) * 1.5) return\n const frame = appFrame()\n if (frame === null) return\n if (document.querySelector('[class$=\"_overlay\"], [class$=\"_dialog\"], [class$=\"_menu\"], [class*=\"_portal\"]') !== null) return\n const collapsed = frame.hasAttribute('data-sidebar-collapsed')\n if (dx < 0 && !collapsed) collapseSidebar()\n else if (dx > 0 && collapsed) toggleSidebarVerified()\n }, { capture: true, passive: true })\n document.addEventListener('touchcancel', () => {\n swipeTouch = null\n }, true)\n\n // Long-press a session row opens the same action menu as the desktop's\n // right-side ellipsis button (rename / fork / archive). On touch the\n // row-actions button is hover-only, so a long press reveals + clicks it.\n const LONG_PRESS_MS = 500\n const LONG_PRESS_MOVE = 10\n let longPress: { row: Element; x: number; y: number; timer: number | null; triggered: boolean } | null = null\n let suppressSessionClickUntil = 0\n let suppressSessionClickRow: Element | null = null\n let longPressMenuGuardUntil = 0\n\n function clearLongPress(): void {\n if (longPress !== null) {\n if (longPress.timer !== null) window.clearTimeout(longPress.timer)\n longPress = null\n }\n }\n\n function openSessionMenu(row: Element): void {\n const actions = row.querySelector('[class*=\"_rowActions\"]')\n const btn = actions?.querySelector('button')\n if (actions === null || btn === null) return\n // The official row hides actions until hover/menuOpen; force the anchor\n // visible just long enough for .click() to be accepted.\n longPressMenuGuardUntil = Date.now() + 1200\n ;(actions as HTMLElement).style.display = 'inline-flex'\n try {\n (btn as HTMLElement).click()\n } finally {\n window.setTimeout(() => { (actions as HTMLElement).style.display = '' }, 50)\n }\n }\n document.addEventListener('touchstart', (e) => {\n if (!active) return\n const t = e.target\n if (!(t instanceof Element)) {\n clearLongPress()\n return\n }\n const row = t.closest('[class*=\"_sessionRow\"]')\n if (row === null || t.closest('[class*=\"_rowActions\"]') !== null) {\n clearLongPress()\n return\n }\n const ct = e.changedTouches[0]\n if (ct === undefined) return\n clearLongPress()\n const lp = { row, x: ct.clientX, y: ct.clientY, timer: null as number | null, triggered: false }\n lp.timer = window.setTimeout(() => {\n if (longPress !== lp) return\n lp.triggered = true\n openSessionMenu(lp.row)\n try { navigator.vibrate?.(10) } catch {}\n }, LONG_PRESS_MS)\n longPress = lp\n }, { capture: true, passive: true })\n document.addEventListener('touchmove', (e) => {\n if (!active || longPress === null) return\n const ct = e.changedTouches[0]\n if (ct === undefined) return\n if (Math.abs(ct.clientX - longPress.x) > LONG_PRESS_MOVE || Math.abs(ct.clientY - longPress.y) > LONG_PRESS_MOVE) {\n clearLongPress()\n }\n }, { capture: true, passive: true })\n document.addEventListener('touchend', (e) => {\n if (!active || longPress === null) return\n const ct = e.changedTouches[0]\n if (ct === undefined) return\n const lp = longPress\n clearLongPress()\n if (lp.triggered) {\n // Stop the finger-lift from also opening the session; the menu is\n // already open and the sidebar should stay put.\n e.preventDefault()\n suppressSessionClickUntil = Date.now() + 800\n suppressSessionClickRow = lp.row\n }\n }, { capture: true, passive: false })\n document.addEventListener('touchcancel', () => {\n clearLongPress()\n }, true)\n // A long press ends with a synthetic click; swallow that one click so it\n // neither opens the conversation nor collapses the sidebar.\n window.addEventListener('click', (e) => {\n if (!active || Date.now() > suppressSessionClickUntil) return\n const t = e.target\n if (t instanceof Element && suppressSessionClickRow !== null && (t === suppressSessionClickRow || suppressSessionClickRow.contains(t))) {\n e.stopPropagation()\n e.preventDefault()\n suppressSessionClickUntil = 0\n suppressSessionClickRow = null\n }\n }, true)\n // Some Android browsers fire a native context menu after a long press.\n document.addEventListener('contextmenu', (e) => {\n if (!active) return\n const t = e.target\n if (!(t instanceof Element)) return\n if (t.closest('[class*=\"_sessionRow\"]') !== null && ((longPress !== null && longPress.triggered) || Date.now() <= suppressSessionClickUntil)) {\n e.preventDefault()\n }\n }, true)\n // Keep the long-press menu open across the finger-lift: the official\n // Menu closes on pointerleave of its root, which fires on touch end.\n document.addEventListener('pointerleave', (e) => {\n if (!active || Date.now() > longPressMenuGuardUntil) return\n const t = e.target\n if (t instanceof Element && (t.closest('[class*=\"_rowActions\"]') !== null || t.closest('[class*=\"_sessionRow\"]') !== null || t.closest('[class*=\"_projectRow\"]') !== null)) {\n e.stopPropagation()\n }\n }, true)\n\n // Intercept programmatic .focus() on the composer field: the official\n // conversation component focuses it on mount and on session changes; user\n // taps focus it through the browser's own pipeline. Only allow composer\n // focus that follows a real tap on the field itself. The composer field is\n // the official contenteditable input root (`data-composer-input`) on this\n // cohort — matching only textarea/input missed it entirely, so every session\n // open popped the phone keyboard. The queue-row editor input is deliberately\n // NOT a composer field: its autoFocus must keep working.\n const isComposerField = (el: Element | null): el is HTMLElement => {\n if (!(el instanceof HTMLElement)) return false\n if (el.closest(COMPOSER_SELECTOR) === null) return false\n if (el.matches('[data-composer-input]')) return true\n if (el.tagName === 'TEXTAREA') return true\n return el.tagName === 'INPUT' && el.matches('[class*=\"_input\"]')\n }\n /** The composer field that owns an event target, if any. */\n const composerFieldOf = (target: EventTarget | null): HTMLElement | null => {\n const el = target instanceof Element ? target.closest('[data-composer-input], [class*=\"_input\"], textarea') : null\n return isComposerField(el) ? el : null\n }\n const lanOrigFocus = HTMLElement.prototype.focus\n HTMLElement.prototype.focus = function (this: HTMLElement, options?: FocusOptions): void {\n if (active && isComposerField(this) && Date.now() - lastComposerTap >= 800) return\n lanOrigFocus.call(this, options)\n }\n document.addEventListener('pointerdown', (e) => {\n if (!active) return\n if (composerFieldOf(e.target) !== null) lastComposerTap = Date.now()\n }, true)\n\n // The plugin apply() wires toggleSidebar/closeDetails to ctx.layout once\n // it is live, and flips the master switch when the settings snapshot\n // settles.\n w.__dshRemoteAdapt = {\n evaluate,\n toggleSidebar: null,\n closeDetails: null,\n translate: null,\n setEnabled(on: boolean): void {\n adaptEnabled = on\n if (on) evaluate()\n else revert()\n },\n flushCloseDetails(): void {\n // The first apply() ran before any wiring existed, so its\n // closeDetails call was a no-op; replay it once the layout face is\n // live so a restored details panel cannot sit hidden-uncloseable.\n if (active) w.__dshRemoteAdapt?.closeDetails?.()\n },\n }\n}\n","// Generated by scripts/sync-shared.mjs from shared/client/settings/plugin-card-seat.ts. Do not edit this copy; edit the shared source and run \"node scripts/sync-shared.mjs\".\n/**\n * Family plugin-card seat.\n *\n * A family plugin contributes its settings card to whichever plugin-card seat\n * the running host actually renders:\n *\n * - `web-ui.plugin.item` — the list seat declared by the dsh-web-settings\n * group section (this family's own first-level \"Web UI plugins\" section);\n * - `settings.plugin.item` — the official keyed seat of the harness's\n * `ui-settings-plugins` tab, keyed by the settings namespace the card edits.\n *\n * SEAT SELECTION IS NOT A DECLARATION PROBE. The official `ui-settings-plugins`\n * row belongs to the harness bundle and its `configurable` tab always declares\n * `settings.plugin.item` before any external plugin's `apply()` runs, so\n * \"is the official seat declared?\" answers yes even in the deployment whose\n * whole point is the family group. Choosing on that probe sends every family\n * card to the official Plugins tab and leaves the group's own section\n * permanently empty — the family of reports where the section renders its\n * heading and zero cards.\n *\n * The signal that actually distinguishes the two deployments is whether\n * dsh-web-settings is loaded: it is the package that owns the group section and\n * it publishes the `webUiSettings` service during `apply()`, which every\n * family plugin already reads for its settings scope. Group loaded -> the family\n * seat; group absent -> the official seat.\n *\n * The decision is re-evaluated on every `slots/changed` because the group may\n * apply after this plugin (the family aggregate orders it first, a profile that\n * installs the group separately need not): the initial contribution goes to the\n * official seat, then moves to the family seat the moment the group's section\n * registers. The entry is disposed before the replacement is registered, so a\n * card is never in two seats at once.\n *\n * The shared tree has no client-SDK dependency, so this module reads its\n * context through the structural shape below; callers pass the plugin's own\n * `ctx`.\n */\n\n/** The family list seat key. */\nexport const FAMILY_PLUGIN_CARD_SEAT = 'web-ui.plugin.item'\n\n/** The official keyed plugin-card seat key. */\nexport const OFFICIAL_PLUGIN_CARD_SEAT = 'settings.plugin.item'\n\n/** The service dsh-web-settings publishes while it is loaded. */\nexport const FAMILY_GROUP_SERVICE = 'webUiSettings'\n\n/** The slot-registry member this helper uses (structurally satisfied by ctx.slots). */\nexport interface PluginCardSlots {\n /** Contribution of one card entry. */\n register(options: never, component: never): unknown\n}\n\n/** The slice of the client context a card contribution needs. */\nexport interface PluginCardContext {\n slots: PluginCardSlots\n /** Service lookup; absent on a context double that only models the slots. */\n get?(name: string): unknown\n /** Event subscription seat; absent on an event-less test double. */\n on?(event: string, listener: (...args: never[]) => void): unknown\n}\n\n/** Owner share of a plugin card (both seats supply nothing). */\nexport interface SettingsPluginItemOwnerProps {\n /** Marker field: card owner props are intentionally empty. */\n children?: never\n}\n\n/** One family plugin's card contribution. */\nexport interface PluginCardSeat {\n /** Settings namespace the card edits (the official seat's dispatch key). */\n namespace: string\n /** Family list-seat entry id. */\n id: string\n /** Family list-seat sort order. */\n order?: number\n /** Family list-seat display label; the official keyed seat carries none. */\n label?: () => string\n /** Locale namespace the card renders with. */\n locale: string\n /** Business-face factory of the registration. */\n inject?: () => object\n /**\n * The card component. Its props type is the seat's composed shape, which is\n * chosen at runtime, so the helper takes it erased; the registrant keeps its\n * own precise typing at the call site.\n */\n component: unknown\n}\n\n/**\n * Whether the family group (dsh-web-settings) is loaded in this page. The\n * service is the group package's own contract, so the probe cannot be fooled\n * by a harness release that starts declaring the official seat differently.\n */\nexport function familyGroupLoaded(ctx: PluginCardContext): boolean {\n const get = ctx.get\n if (typeof get !== 'function') return false\n try {\n return get.call(ctx, FAMILY_GROUP_SERVICE) !== undefined\n } catch {\n // A context that refuses the lookup: treat the group as absent, which\n // falls back to the official seat the harness declares.\n return false\n }\n}\n\n/** Report a refused registration instead of leaving the user with no card. */\nfunction warnRefusedSeat(seat: string, error: unknown): void {\n try {\n console.warn(`[dsh-web] plugin card registration into \"${seat}\" was refused; the card will not render`, error)\n } catch {\n // Best-effort console write; a failed warning must not break the plugin.\n }\n}\n\n/**\n * Contribute one family plugin card to the seat this host renders, following\n * the group if it loads later. The entry is disposed and re-registered on a\n * seat change, never duplicated.\n * @param ctx - client context (its slot registry decides the seat).\n * @param seat - the card contribution.\n */\nexport function installPluginCard(ctx: PluginCardContext, seat: PluginCardSeat): void {\n const slots = ctx.slots\n const component = seat.component as never\n const inject = seat.inject as never\n\n let dispose: (() => void) | undefined\n let current: string | undefined\n /**\n * Re-entrancy latch. The registry emits a change event synchronously from\n * inside both `register` and the previous entry's disposer, so an unguarded\n * reconcile would re-enter itself mid-move and register the card twice into\n * the seat it is leaving (\"already has an entry for key ...\").\n */\n let reconciling = false\n\n /** Reconcile the contribution with the currently live seat (no-op when unchanged). */\n const reconcile = (): void => {\n if (reconciling) return\n const target = familyGroupLoaded(ctx) ? FAMILY_PLUGIN_CARD_SEAT : OFFICIAL_PLUGIN_CARD_SEAT\n if (current === target) return\n reconciling = true\n const previous = dispose\n dispose = undefined\n current = undefined\n previous?.()\n try {\n dispose = slots.register((target === FAMILY_PLUGIN_CARD_SEAT\n ? {\n name: FAMILY_PLUGIN_CARD_SEAT,\n id: seat.id,\n ...(seat.order === undefined ? {} : { order: seat.order }),\n ...(seat.label === undefined ? {} : { label: seat.label }),\n locale: seat.locale,\n ...(seat.inject === undefined ? {} : { inject }),\n }\n : {\n name: OFFICIAL_PLUGIN_CARD_SEAT,\n key: seat.namespace,\n locale: seat.locale,\n ...(seat.inject === undefined ? {} : { inject }),\n }) as never, component) as () => void\n current = target\n } catch (error) {\n warnRefusedSeat(target, error)\n } finally {\n reconciling = false\n }\n }\n\n if (typeof ctx.on === 'function') {\n try {\n ctx.on('slots/changed', () => { reconcile() })\n } catch {\n // An event seat that refuses the subscription leaves the initial\n // decision in place; the card still renders in the seat chosen below.\n }\n }\n // The initial decision: the group, when it is already loaded (the aggregate\n // order), otherwise the official seat the harness declares.\n reconcile()\n}\n","/**\n * Remote control — browser half. Registers the `remote` dictionaries, the\n * sidebar-foot entry (phone trigger + pairing panel + update trigger), and\n * the pair boot flow (accept + presence heartbeats) plus the one-time\n * failed-pair notice. The portrait-touch adaptation of the official UI\n * starts under the plugin lifecycle (startMobileAdapt inside apply) and reverts\n * on dispose, so disabled plugin entries stay inert. Export discipline: packages/client/AGENTS.md — the\n * /client surface carries only what cordis loading needs plus types.\n */\nimport { createElement } from 'react'\nimport { createRoot } from 'react-dom/client'\nimport type { Context as ClientContext } from '@deepseek-ai/cordis'\nimport type { SettingsScope, SettingsScopeSpec } from '@deepseek-ai/dsh-client-ui-settings/client'\n// Type-only: pulls the locale plugin's Context merge (ctx.locale) and the\n// ui-sidebar SlotMap merge (the 'sidebar.footer.action' hole).\nimport type {} from '@deepseek-ai/dsh-client-locale/client'\n// Type-only: pulls the settings-surface SlotMap merge (the 'settings.section'\n// entry) and the ctx.settingsScope Context merge.\nimport type {} from '@deepseek-ai/dsh-client-ui-settings/client'\nimport type {} from '@deepseek-ai/dsh-client-ui-sidebar/client'\n// Type-only: pulls the ctx.slots merge (the renderer owns the slot registry since 0.1.2).\nimport type {} from '@deepseek-ai/dsh-client-ui-renderer/client'\nimport type { ConnectionHandle } from '@deepseek-ai/dsh-client-connection/client'\nimport { FooterRemoteEntry } from './FooterRemoteEntry.tsx'\nimport { RemoteEntry } from './RemoteEntry.tsx'\nimport { PairFailedNotice } from './PairFailedNotice.tsx'\nimport { RemoteSettingsCard, RemoteSettingsCardController, type RemoteSettings } from './RemoteSettingsCard.tsx'\nimport { en, zh, type RemoteKey } from './locales.ts'\nimport { PAIR_FAILED_MARKER, runPairBootFlow } from './deep-link.ts'\nimport { readPairGatePolicy, sendHeartbeat } from './pair-api.ts'\nimport {\n channelTransition,\n installRemoteChannel,\n isLoopbackHostname,\n remoteChannelRequired,\n REMOTE_CHANNEL_BOOT_GLOBAL,\n type RemoteChannelBootSeat,\n} from './remote-channel.ts'\nimport { FenceNotice } from './FenceNotice.tsx'\nimport { reportDailyHeartbeat } from './telemetry.ts'\nimport { startMobileAdapt, type RemoteAdaptGlobal } from './mobile-adapt.ts'\nimport { installPluginCard } from './plugin-card-seat.ts'\n\n// Portrait-touch adaptation of the official UI: installed under the plugin\n// lifecycle (apply) so disabling the plugin in cordis patch (disabled: true)\n// leaves the DOM untouched.\n\nexport type { RemoteEntryProps } from './RemoteEntry.tsx'\nexport type { PanelState, RemotePanelProps } from './RemotePanel.tsx'\nexport type { PairFailedNoticeProps } from './PairFailedNotice.tsx'\nexport type { RemoteKey } from './locales.ts'\nexport type { RemoteSettingsCardFace, RemoteSettingsCardState } from './RemoteSettingsCard.tsx'\nexport type { UpdateEntryProps } from './UpdateEntry.tsx'\nexport type { UpdatePanelProps, UpdateView } from './UpdatePanel.tsx'\n\ndeclare module '@deepseek-ai/dsh-client-ui-slots' {\n interface LocaleNamespaceMap {\n /** Mobile remote-control surface copy. */\n remote: RemoteKey\n }\n\n interface SlotMap {\n /**\n * The sidebar foot seat beside the settings trigger, declared by the\n * sidebar shell on deployments that carry the feature seat; the shell\n * passes only its column display state.\n */\n /**\n * The child slot the Web UI plugin group declares; this card registers\n * into the group instead of the top-level `settings.plugin.item` list.\n * Spelled here with the same shape so this package can register without\n * depending on the sibling UI package.\n */\n 'web-ui.plugin.item': { kind: 'list'; scope: 'root'; owner: SettingsPluginItemOwnerProps }\n }\n}\n\n/** Owner share of the sidebar remote-control seat: the column display state the trigger renders against. */\nexport interface SidebarRemoteOwnerProps {\n /** Whether the sidebar renders wide content (false = 56px rail). */\n wide: boolean\n}\n\n/** Owner share of a plugin card (the section supplies nothing). */\nexport interface SettingsPluginItemOwnerProps {\n /** Marker field: card owner props are intentionally empty. */\n children?: never\n}\n\ndeclare module '@deepseek-ai/cordis' {\n interface Context {\n /**\n * Optional rc.6 compatibility binder provided by dsh-web-settings;\n * absent when that group plugin is not installed, so callers fall back to\n * the official settings scope.\n */\n webUiSettings?: { bind<S>(spec: SettingsScopeSpec<S>): SettingsScope<S> }\n }\n}\n\n\n/** Dictionary namespace owned by this plugin. */\nconst NS = 'remote'\n\n/** Settings namespace the remote-control card edits (the Host plugin registers it). */\nconst REMOTE_WEB_UI_NS = 'remote-web-ui'\n\n/** Heartbeat cadence from a paired phone (presence + revocation liveness). */\nconst HEARTBEAT_INTERVAL_MS = 10_000\n\n/** Services required by this plugin. */\nexport const inject = ['slots', 'locale', 'connection', 'settingsScope', 'remote']\n\n/**\n * Register the remote-control surface.\n * @param ctx - client root context.\n */\nexport function apply(ctx: ClientContext): void {\n // Portrait-touch adaptation of the official UI: installed under the plugin\n // lifecycle so disabling the plugin in cordis patch (disabled: true) never\n // injects mobile CSS, gesture hooks, or the whale floating button.\n startMobileAdapt()\n ctx.effect(() => () => {\n ;(window as unknown as { __dshRemoteAdapt?: RemoteAdaptGlobal }).__dshRemoteAdapt?.setEnabled?.(false)\n }, 'remote-web-ui: mobile-adapt')\n\n // Anonymous install heartbeat (docs/telemetry.md): one beat per browser per\n // UTC day, package name only, silent failure.\n reportDailyHeartbeat([{ name: '@linxin666/dsh-remote-web-ui' }])\n\n ctx.effect(() => {\n try {\n return ctx.locale.register(NS, { zh, en })\n } catch {\n return () => {}\n }\n }, 'remote-web-ui: dictionaries')\n\n // The mobile adapt's whale button expands the collapsed sidebar and the\n // activation closes the details panel — both through the official layout\n // service (ctx.layout.toggleSidebar / closeDetails flip the panel state;\n // the narrow-viewport semantics open the drawer).\n const layout = ctx.get('layout') as { toggleSidebar?: () => void; closeDetails?: () => void } | undefined\n const adapt = (window as unknown as { __dshRemoteAdapt?: RemoteAdaptGlobal }).__dshRemoteAdapt\n // The official layout face throws (by contract) when the root entry has\n // not mounted yet; these closures also fire from gestures racing that\n // first mount, so they tolerate the throw instead of surfacing it.\n const layoutCall = (call: (() => void) | undefined): void => {\n try {\n call?.()\n } catch {\n // Boot-order throw: the panel action is a no-op before the root entry.\n }\n }\n if (layout !== undefined && adapt !== undefined) {\n if (typeof layout.toggleSidebar === 'function') {\n adapt.toggleSidebar = () => {\n layoutCall(layout.toggleSidebar)\n }\n }\n if (typeof layout.closeDetails === 'function') {\n adapt.closeDetails = () => {\n layoutCall(layout.closeDetails)\n }\n }\n }\n if (adapt !== undefined && adapt.toggleSidebar === null) {\n // Layout face unavailable (older composition): fall back to clicking the\n // official rail toggle when it exists.\n adapt.toggleSidebar = () => {\n (document.querySelector('[class$=\"_railFish\"] button, [class$=\"_logoRow\"] [class*=\"_iconButton\"]') as HTMLElement | null)?.click()\n }\n }\n\n const t = ctx.locale.bind(NS)\n // Hand the `remote` translate seat to the module-scope adaptation layer:\n // the whale/compact-picker labels were rendered with the English fallback\n // before any dictionary existed; the wiring plus the layer's own sync tick\n // re-render them in the active locale.\n if (adapt !== undefined) adapt.translate = t\n const binder = ctx.get('webUiSettings') ?? ctx.settingsScope\n const settingsScope = binder.bind<RemoteSettings>({ namespace: REMOTE_WEB_UI_NS })\n const enabled = (): boolean => {\n const snapshot = settingsScope.getSnapshot()\n return snapshot.status === 'ready'\n ? snapshot.value?.enabled ?? true\n : snapshot.status === 'unavailable'\n }\n\n // Master switch for the adaptation layer: the module-scope install runs\n // before any config is readable, so flip it once the settings snapshot is\n // bound and on every later change (disabled plugin = no injected surface).\n // Also replay the pending closeDetails: the first portrait apply ran\n // before the layout face was wired, so its closeDetails was a no-op and a\n // restored details panel would otherwise sit hidden until landscape.\n const syncAdaptEnabled = (): void => {\n ;(window as unknown as { __dshRemoteAdapt?: RemoteAdaptGlobal }).__dshRemoteAdapt?.setEnabled?.(enabled())\n }\n settingsScope.subscribe(syncAdaptEnabled)\n syncAdaptEnabled()\n // The replay closes a details panel restored before the wiring; the\n // layout face throws while the root entry has not mounted yet (a real\n // boot-order race on slow remote loads), and the plugin's apply world\n // must survive it — the replay is a best-effort no-op then.\n try {\n adapt?.flushCloseDetails?.()\n } catch {}\n\n // Sidebar foot entry: the sidebar foot seat is `sidebar.footer.action` in\n // the 0.1.2 shell composition (the legacy `sidebar.remote` seat is gone\n // upstream). The pairing link is origin-agnostic, so the entry needs no\n // workspace source.\n ctx.slots.inject('sidebar.footer.action', () => {\n let disposeEntry: (() => void) | undefined\n const syncEntry = (): void => {\n if (enabled() && disposeEntry === undefined) {\n try {\n disposeEntry = ctx.slots.register({ name: 'sidebar.footer.action', id: 'remote-web-ui', locale: NS }, FooterRemoteEntry)\n } catch {\n // ignore registration collision\n }\n } else if (!enabled() && disposeEntry !== undefined) {\n disposeEntry()\n disposeEntry = undefined\n }\n }\n const unsubscribe = settingsScope.subscribe(syncEntry)\n syncEntry()\n return () => {\n unsubscribe()\n disposeEntry?.()\n }\n })\n\n // Plugin configuration card: one staged form over the `remote-web-ui`\n // settings namespace, contributed to whichever plugin-card seat the running\n // host declares (the family group's list seat, or the official keyed seat of\n // the plugin-configuration tab when dsh-web-settings is not installed —\n // issue #1589).\n const remoteSettings = new RemoteSettingsCardController(settingsScope)\n installPluginCard(ctx, {\n namespace: REMOTE_WEB_UI_NS,\n id: 'remote-web-ui',\n order: 90,\n locale: NS,\n inject: () => remoteSettings.inject(),\n component: RemoteSettingsCard,\n })\n ctx.effect(() => () => { remoteSettings.dispose() }, 'remote-web-ui: settings card')\n\n // Phone-side boot flow + heartbeats. Loopback pages (the desktop) never\n // heartbeat; the server ignores unpaired heartbeats anyway. Both run only\n // while the plugin is enabled.\n let disposeRuntime: (() => void) | undefined\n const syncRuntime = (): void => {\n if (enabled() && disposeRuntime === undefined) {\n disposeRuntime = ctx.effect(() => {\n const connection = ctx.get('connection') as ConnectionHandle | undefined\n const loopback = connection?.isLoopback ?? true\n runPairBootFlow(ctx, window.location.search)\n if (loopback) return () => {}\n const timer = window.setInterval(() => { void sendHeartbeat().catch(() => {}) }, HEARTBEAT_INTERVAL_MS)\n return () => { window.clearInterval(timer) }\n }, 'remote-web-ui: pair flow + heartbeats')\n } else if (!enabled() && disposeRuntime !== undefined) {\n disposeRuntime()\n disposeRuntime = undefined\n }\n }\n settingsScope.subscribe(syncRuntime)\n syncRuntime()\n\n // Remote desktop channel: on a non-loopback origin (LAN address or public\n // tunnel) the connection plugin's /api fence refuses this desktop Web GUI,\n // and pairing is the access control — so the SDK client's /api traffic is\n // rewritten onto this plugin's gated /remote/api prefix (remote-channel.ts)\n // while the fence setting demands it. Loopback origins are untouched.\n let disposeChannel: (() => void) | undefined\n let hostPairingPolicy: boolean | undefined\n let unpairedWhilePolicyPending = false\n let fenceNotice: { unmount: () => void; node: HTMLElement } | undefined\n const showFenceNotice = (): void => {\n if (fenceNotice !== undefined) return\n const node = document.createElement('div')\n document.body.appendChild(node)\n const root = createRoot(node)\n root.render(createElement(FenceNotice, { t, onRetry: () => { window.location.reload() } }))\n fenceNotice = { unmount: () => { root.unmount(); node.remove() }, node }\n }\n const hideFenceNotice = (): void => {\n fenceNotice?.unmount()\n fenceNotice = undefined\n }\n const handleUnpaired = (): void => {\n if (settingsScope.getSnapshot().status !== 'ready' && hostPairingPolicy === undefined) {\n unpairedWhilePolicyPending = true\n return\n }\n showFenceNotice()\n }\n const channelActive = (): boolean => remoteChannelRequired(\n window.location.hostname,\n settingsScope.getSnapshot(),\n hostPairingPolicy,\n )\n // The parse-time boot patch (issue #987), when the served index carried\n // it: already installed before any boot entry ran, so adopting its seat\n // beats patching a second time (which would double-rewrite onto\n // /remote/remote/...).\n const bootSeat = (): RemoteChannelBootSeat | undefined =>\n (window as unknown as Record<string, RemoteChannelBootSeat | undefined>)[REMOTE_CHANNEL_BOOT_GLOBAL]\n const syncChannel = (): void => {\n const transition = channelTransition(channelActive(), disposeChannel !== undefined)\n if (transition === 'install') {\n const seat = bootSeat()\n if (seat !== undefined) {\n seat.onUnpaired = handleUnpaired\n seat.onPaired = hideFenceNotice\n // Replay a signal raised before adoption (early unpaired responses).\n if (seat.pendingUnpaired) {\n seat.pendingUnpaired = false\n handleUnpaired()\n }\n disposeChannel = ctx.effect(() => () => {\n seat.onUnpaired = null\n seat.onPaired = null\n }, 'remote-web-ui: remote desktop channel (boot patch)')\n } else {\n disposeChannel = ctx.effect(() => {\n const restore = installRemoteChannel(window, { onUnpaired: handleUnpaired, onPaired: hideFenceNotice })\n return restore\n }, 'remote-web-ui: remote desktop channel')\n }\n } else if (transition === 'retire' && disposeChannel !== undefined) {\n disposeChannel()\n disposeChannel = undefined\n // Retire the provisional parse-time install with the channel: the\n // desktop now rides plain /api, so the rewrite must go (its seat\n // removes the global; a later re-activation patches afresh).\n bootSeat()?.restore()\n // Retire the notice with the channel: once requirePairingForLan turns\n // off (or the plugin is disabled) the desktop rides plain /api again,\n // so an unpaired notice raised while the channel was briefly active\n // (the settings snapshot loads after boot) must not outlive it. The\n // installed channel is the only path that raises the notice, so with\n // the channel gone nothing can re-raise it (issue #808).\n hideFenceNotice()\n } else if (transition === 'none' && !channelActive()) {\n // The channel was never adopted (policy settled to off before apply\n // ran): the provisional boot patch still retires.\n bootSeat()?.restore()\n }\n }\n settingsScope.subscribe(syncChannel)\n syncChannel()\n if (!isLoopbackHostname(window.location.hostname) && settingsScope.getSnapshot().status !== 'ready') {\n void readPairGatePolicy().then((policy) => {\n hostPairingPolicy = policy.requirePairingForLan\n syncChannel()\n if (hostPairingPolicy && unpairedWhilePolicyPending) showFenceNotice()\n unpairedWhilePolicyPending = false\n }).catch(() => {\n // Fail closed when the policy endpoint is unavailable or malformed.\n hostPairingPolicy = true\n syncChannel()\n if (unpairedWhilePolicyPending) showFenceNotice()\n unpairedWhilePolicyPending = false\n })\n }\n\n // One-time failed-pair toast. The accept result lands asynchronously, so\n // the marker check is deferred past the accept round trip.\n ctx.effect(() => {\n const timer = window.setTimeout(() => {\n if (sessionStorage.getItem(PAIR_FAILED_MARKER) === null) return\n sessionStorage.removeItem(PAIR_FAILED_MARKER)\n const mount = document.createElement('div')\n document.body.appendChild(mount)\n const root = createRoot(mount)\n root.render(createElement(PairFailedNotice, { t }))\n // The toast owns its dismissal; the root lives for the page lifetime.\n void root\n }, 1500)\n return () => { window.clearTimeout(timer) }\n }, 'remote-web-ui: failed-pair notice')\n}\n"],"x_google_ignoreList":[0,1],"mappings":"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"}
|