@linxin666/dsh-client-ui-skin-center 0.3.19 → 0.3.21
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/contracts/semantic-attrs-v1.md +11 -3
- package/lib/client.js +97 -33
- package/lib/client.js.map +1 -1
- package/lib/index.js +22 -16
- package/package.json +11 -11
- package/skins/blue-fantasy/patches.css +369 -0
package/lib/client.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.js","names":["css","useLiveValue","css","css","isRecord"],"sources":["../../../packages/skins/skin-center/src/client/CustomThemePanel.tsx","../../../packages/skins/skin-center/src/client/runtime/backdrop-scene.ts","../../../packages/skins/skin-center/src/client/wallpaper.ts","../../../packages/skins/skin-center/src/client/SliderControl.tsx","../../../packages/skins/skin-center/src/client/WallpaperPanel.tsx","../../../packages/skins/skin-center/src/client/SkinCenter.tsx","../../../packages/skins/skin-center/src/core/background.ts","../../../packages/skins/skin-center/src/client/background.ts","../../../packages/skins/skin-center/src/core/background-scope.ts","../../../packages/skins/skin-center/src/client/locales.ts","../../../packages/skins/skin-center/src/client/runtime/effect-ledger.ts","../../../packages/skins/skin-center/src/client/runtime/semantic-adapter.ts","../../../packages/skins/skin-center/src/client/runtime/shell-rendering.ts","../../../packages/skins/skin-center/src/client/runtime/decoration-layers.ts","../../../packages/skins/skin-center/src/client/runtime/skin-controller.ts","../../../packages/skins/skin-center/src/client/runtime/boot.ts","../../../packages/skins/skin-center/src/client/preview-coordinator.ts","../../../packages/skins/skin-center/src/core/custom-theme.ts","../../../packages/skins/skin-center/src/client/custom-theme-controller.ts","../../../packages/skins/skin-center/src/client/telemetry.ts","../../../packages/skins/skin-center/src/client/index.ts"],"sourcesContent":["import { useEffect, useState, useSyncExternalStore, type ReactNode } from 'react'\nimport type { PropsLocale } from '@deepseek-ai/dsh-client-ui-slots'\n\nimport type { CustomThemeController, CustomThemeScheme } from './custom-theme-controller.ts'\nimport css from './skin-center.module.css'\n\ntype ColorKey = 'accent' | 'background' | 'foreground'\n\nexport interface CustomThemeCardProps {\n t: PropsLocale<'skinCenter'>['t']\n customTheme: CustomThemeController\n scheme: CustomThemeScheme\n setScheme(scheme: CustomThemeScheme): void\n isActive: boolean\n isTrying: boolean\n busy: boolean\n disabled: boolean\n onTryOn(): void\n onExitTryOn(): void\n onApply(): void\n}\n\nexport function CustomThemeCard(props: CustomThemeCardProps): ReactNode {\n const {\n t, customTheme, scheme, setScheme, isActive, isTrying, busy, disabled,\n onTryOn, onExitTryOn, onApply,\n } = props\n const customThemeState = useSyncExternalStore(customTheme.subscribe, customTheme.getState)\n const profile = customTheme.profile(scheme)\n const [expanded, setExpanded] = useState(false)\n const [draftColors, setDraftColors] = useState<Record<ColorKey, string>>({\n accent: profile.accent,\n background: profile.background,\n foreground: profile.foreground,\n })\n\n useEffect(() => {\n setDraftColors({\n accent: profile.accent,\n background: profile.background,\n foreground: profile.foreground,\n })\n }, [scheme, profile.accent, profile.background, profile.foreground])\n\n const setDraft = (key: ColorKey, value: string): void => {\n setDraftColors(current => ({ ...current, [key]: value }))\n }\n const commitColor = (key: ColorKey): void => {\n const value = draftColors[key]\n if (/^#[0-9a-f]{6}$/i.test(value)) customTheme.setProfileValue(scheme, key, value)\n else setDraft(key, profile[key])\n }\n const colorField = (key: ColorKey, label: string): ReactNode => {\n const draft = draftColors[key]\n const pickerValue = /^#[0-9a-f]{6}$/i.test(draft) ? draft : profile[key]\n return (\n <label className={css.customThemeField} key={key}>\n <span className={css.customThemeFieldLabel}>{label}</span>\n <span className={css.customThemeInputRow}>\n <input\n className={css.customThemeColor}\n type=\"color\"\n value={pickerValue}\n aria-label={label}\n disabled={disabled}\n onChange={(event) => {\n const value = event.target.value\n setDraft(key, value)\n customTheme.setProfileValue(scheme, key, value)\n }}\n />\n <input\n className={css.customThemeHex}\n type=\"text\"\n value={draft}\n inputMode=\"text\"\n maxLength={7}\n spellCheck={false}\n aria-label={`${label} hex`}\n disabled={disabled}\n onChange={(event) => { setDraft(key, event.target.value) }}\n onBlur={() => { commitColor(key) }}\n onKeyDown={(event) => {\n if (event.key === 'Enter') event.currentTarget.blur()\n }}\n />\n </span>\n </label>\n )\n }\n\n return (\n <div className={`${css.card} ${css.customThemeCard}`} data-dsh-custom-theme-card=\"\">\n <div className={css.cardHead}>\n <span className={css.swatch} style={{ background: profile.accent }} aria-hidden=\"true\" />\n <span className={css.cardName}>{t('customThemeTitle')}</span>\n {(isActive || isTrying) && (\n <span className={`${css.badge} ${isActive ? css.badgeActive : css.badgeTrying}`}>\n {isActive ? t('active') : t('tryingOn')}\n </span>\n )}\n </div>\n <div className={css.cardTagline}>{t('customThemeTagline')}</div>\n {customThemeState.writeError !== null && (\n <div className={css.error} role=\"alert\">\n {t('customThemeSaveFailed')}\n </div>\n )}\n <div className={css.actions}>\n {isActive && !isTrying ? (\n <button type=\"button\" className={`${css.button} ${css.buttonGhost}`} disabled>{t('tryOn')}</button>\n ) : isTrying ? (\n <button type=\"button\" className={`${css.button} ${css.buttonPrimary}`} disabled={disabled} onClick={onExitTryOn}>\n {t('exitTryOn')}\n </button>\n ) : (\n <button type=\"button\" className={`${css.button} ${css.buttonPrimary}`} disabled={disabled} onClick={onTryOn}>\n {busy ? t('loading') : t('tryOn')}\n </button>\n )}\n <button type=\"button\" className={css.button} disabled={disabled} onClick={onApply}>\n {busy ? t('applying') : t('apply')}\n </button>\n <button\n type=\"button\"\n className={css.button}\n aria-expanded={expanded}\n disabled={disabled}\n onClick={() => { setExpanded(value => !value) }}\n >\n {expanded ? t('customThemeCloseEdit') : t('customThemeEdit')}\n </button>\n </div>\n\n {expanded && (\n <div className={css.customThemeEditor}>\n <div className={css.customThemeScheme} role=\"group\" aria-label={t('customThemeMode')}>\n <span className={css.themeLabel}>{t('customThemeMode')}</span>\n <button\n type=\"button\"\n aria-pressed={scheme === 'light'}\n className={`${css.themeButton} ${scheme === 'light' ? css.themeButtonActive : ''}`}\n disabled={disabled}\n onClick={() => { setScheme('light') }}\n >\n {t('customThemeLight')}\n </button>\n <button\n type=\"button\"\n aria-pressed={scheme === 'dark'}\n className={`${css.themeButton} ${scheme === 'dark' ? css.themeButtonActive : ''}`}\n disabled={disabled}\n onClick={() => { setScheme('dark') }}\n >\n {t('customThemeDark')}\n </button>\n </div>\n\n <div className={css.customThemeFields}>\n {colorField('accent', t('customThemeAccent'))}\n {colorField('background', t('customThemeBackground'))}\n {colorField('foreground', t('customThemeForeground'))}\n </div>\n\n <label className={css.customThemeContrast}>\n <span className={css.backgroundHead}>\n <span className={css.customThemeFieldLabel}>{t('customThemeContrast')}</span>\n <span className={css.backgroundValue} aria-hidden=\"true\">{profile.contrast}</span>\n </span>\n <input\n className={css.backgroundRange}\n type=\"range\"\n min=\"0\"\n max=\"100\"\n step=\"1\"\n value={profile.contrast}\n aria-label={t('customThemeContrast')}\n aria-valuetext={String(profile.contrast)}\n disabled={disabled}\n onChange={(event) => { customTheme.setProfileValue(scheme, 'contrast', Number(event.target.value)) }}\n />\n </label>\n\n <div className={css.customThemeFooter}>\n <span className={css.backgroundHintMuted}>{t('customThemeResetHint')}</span>\n <button type=\"button\" className={css.button} disabled={disabled} onClick={() => { customTheme.reset(scheme) }}>\n {t('customThemeReset')}\n </button>\n </div>\n </div>\n )}\n </div>\n )\n}\n","/**\n * Unified \"backdrop visible\" scene marker (issue #777).\n *\n * A skin with painted background media or a mounted Wallpaper Engine\n * wallpaper both put real backdrop art behind the app. The two runtime\n * controllers (skin-controller and wallpaper) report their mount state\n * through setSceneBackdropActive(); this module folds them into ONE body /\n * html marker `data-dsh-backdrop-active` and installs the shared composer\n * seat neutralizer that keys on it.\n *\n * The shell's active composer seat paints a bottom occlusion gradient under\n * the sticky input card (rc.8: a linear gradient to --dsw-alias-bg-base,\n * z-index 7). Backdrop scenes intentionally remove that seat-wide gradient in\n * both active and hero phases so wallpaper art remains unobstructed down to the\n * viewport edge. Skin-provided seat-wide ::before masks are neutralized too.\n * Composer task/statistics surfaces are styled by the shared shell adapter\n * from skin theme tokens, not by this scene layer.\n *\n * The input card itself ([data-composer-card], the official shell's stable card\n * anchor) keeps its translucent tint and gains the configurable backdrop blur\n * (default INPUT_FROST_BLUR_PX).\n *\n * The card rule is enabled only while the conversation actually has message\n * content (data-dsh-conversation-content): an empty conversation has no正文 to\n * occlude, so the input keeps its normal hero appearance without a frost flash.\n * The strength is provided by --dsh-input-card-blur and falls back to the\n * compatibility default when the setting has not loaded yet.\n *\n * The marker is body/html level (managed outside the surface/part/plugin\n * enum, see contracts/semantic-attrs-v1.md) and survives a neutralizer\n * teardown; the style is inert whenever the marker is absent.\n * @module @linxin666/dsh-client-ui-skin-center/runtime/backdrop-scene\n */\n\n/** Shared marker: set on html + body while a source reports backdrop art. */\nexport const BACKDROP_ACTIVE_ATTR = 'data-dsh-backdrop-active'\n\n/** The shared composer-seat neutralizer style's own attribute. */\nexport const SCENE_NEUTRALIZER_ATTR = 'data-dsh-scene-neutralizer'\n\n/** Conversation-content marker: set while the active conversation has rows. */\nexport const CONVERSATION_CONTENT_ATTR = 'data-dsh-conversation-content'\n\n/**\n * Stable shell scrollport scoped row selectors. Official builds emit the chat\n * anchor; the CSS-module suffix fallbacks retain compatibility with older\n * shells without returning to a body-wide topic/session query.\n */\nconst ACTIVE_CONVERSATION_CONTENT_SELECTOR = [\n '[data-conversation-scroll] [data-chat-anchor-key]',\n '[data-conversation-scroll] [class*=\"_userRow\"]',\n '[data-conversation-scroll] [class*=\"_compactionRow\"]',\n '[data-conversation-scroll] [class*=\"_contextRow\"]',\n '[data-conversation-scroll] [class*=\"_turnErrorRow\"]',\n].join(', ')\n\n/** One source that can make backdrop art visible. */\nexport type BackdropSource = 'skin' | 'wallpaper'\n\n/** Compatibility default for the input-card backdrop blur strength (px). */\nexport const INPUT_FROST_BLUR_PX = 10\n\nconst sourceSets = new WeakMap<Document, Set<BackdropSource>>()\nconst contentObservers = new WeakMap<Document, MutationObserver>()\n\n/**\n * Report one source's backdrop-art presence. The marker stays on while any\n * source is active, so the skin and wallpaper controllers never clobber each\n * other across their mount/unmount cycles.\n */\nexport function setSceneBackdropActive(doc: Document, source: BackdropSource, active: boolean): void {\n let sources = sourceSets.get(doc)\n if (sources === undefined) {\n sources = new Set()\n sourceSets.set(doc, sources)\n }\n if (active) sources.add(source)\n else sources.delete(source)\n syncMarker(doc, sources)\n}\n\n/** Reflect the source set onto html/body and ensure the neutralizer on use. */\nfunction syncMarker(doc: Document, sources: Set<BackdropSource>): void {\n const active = sources.size > 0\n if (active) {\n doc.body?.setAttribute(BACKDROP_ACTIVE_ATTR, 'true')\n doc.documentElement?.setAttribute(BACKDROP_ACTIVE_ATTR, 'true')\n ensureSceneNeutralizer(doc)\n startContentObserver(doc)\n } else {\n doc.body?.removeAttribute(BACKDROP_ACTIVE_ATTR)\n doc.documentElement?.removeAttribute(BACKDROP_ACTIVE_ATTR)\n stopContentObserver(doc)\n }\n}\n\n/**\n * Track whether the active conversation scrollport has message rows for the\n * frost gate. Topic pickers and outgoing session trees can retain their own\n * data-chat-anchor-key nodes during a switch; a body-wide query would count\n * those stale rows and flash the composer frost over the new empty topic.\n */\nfunction updateConversationContent(doc: Document): void {\n const has = doc.body !== null && doc.body.querySelector(ACTIVE_CONVERSATION_CONTENT_SELECTOR) !== null\n if (has) {\n doc.body?.setAttribute(CONVERSATION_CONTENT_ATTR, 'true')\n doc.documentElement?.setAttribute(CONVERSATION_CONTENT_ATTR, 'true')\n } else {\n doc.body?.removeAttribute(CONVERSATION_CONTENT_ATTR)\n doc.documentElement?.removeAttribute(CONVERSATION_CONTENT_ATTR)\n }\n}\n\n/** Observe the conversation tree while a backdrop is visible. */\nfunction startContentObserver(doc: Document): void {\n if (contentObservers.has(doc)) return\n updateConversationContent(doc)\n const win = doc.defaultView\n if (win === null || typeof win.MutationObserver !== 'function') return\n const observer = new win.MutationObserver(() => updateConversationContent(doc))\n observer.observe(doc.body ?? doc.documentElement, { childList: true, subtree: true })\n contentObservers.set(doc, observer)\n}\n\n/** Stop the content observer and drop the content marker. */\nfunction stopContentObserver(doc: Document): void {\n const observer = contentObservers.get(doc)\n if (observer !== undefined) {\n observer.disconnect()\n contentObservers.delete(doc)\n }\n doc.body?.removeAttribute(CONVERSATION_CONTENT_ATTR)\n doc.documentElement?.removeAttribute(CONVERSATION_CONTENT_ATTR)\n}\n\n/**\n * Install the shared composer-seat neutralizer, keyed by head presence so a\n * cleared head (tests) or a re-mount re-creates it. Without the marker the\n * rules are inert, so the style can outlive a single mount without changing\n * any other look.\n */\nexport function ensureSceneNeutralizer(doc: Document): void {\n if (doc.head === null) return\n if (doc.head.querySelector(`style[${SCENE_NEUTRALIZER_ATTR}]`) !== null) return\n const style = doc.createElement('style')\n style.setAttribute(SCENE_NEUTRALIZER_ATTR, '')\n style.textContent = `\n html[data-dsh-backdrop-active] [data-composer-seat],\n html[data-dsh-backdrop-active] [data-composer-seat]::before {\n background: none !important;\n backdrop-filter: none !important;\n -webkit-backdrop-filter: none !important;\n }\n html[data-dsh-backdrop-active][data-dsh-conversation-content] [data-composer-card] {\n backdrop-filter: blur(var(--dsh-input-card-blur, ${INPUT_FROST_BLUR_PX}px)) !important;\n -webkit-backdrop-filter: blur(var(--dsh-input-card-blur, ${INPUT_FROST_BLUR_PX}px)) !important;\n }\n `\n doc.head.appendChild(style)\n}\n","/**\n * Wallpaper layer controller for the skin center: renders the applied\n * Wallpaper Engine wallpaper behind the GUI and persists the selection\n * through the 'skin-wallpaper' settings namespace.\n *\n * Layers (fixed children of document.body, painted only while a wallpaper\n * is active):\n * - media layer z-index:-3 video / iframe / static frame image\n * - scrim layer z-index:-2 the dim veil (settings 'dim')\n * The skin-center backdrop blur element (z-index:-1, background.ts) sits\n * above both, so its backdrop-filter blurs the wallpaper together with the\n * skin backdrop. The 'wallpaperBlur' setting instead blurs the wallpaper\n * itself via a filter on the media layer.\n *\n * Mutual exclusion with skin backdrop art is paint-order only: the opaque\n * media layer covers the body's background, no skin writes are touched, and\n * unmounting restores the previous view for free.\n *\n * Render modes: 'live' mounts video/web directly; 'frame' pins a static\n * image (video: first frame captured to a canvas; scene: the host-decoded\n * PNG; web: the preview image) for a zero-animation-cost backdrop. When\n * 'pauseOnHidden' is set the video pauses while the window is hidden.\n * @module @linxin666/dsh-client-ui-skin-center/wallpaper\n */\nimport type { SettingsScope, SettingsScopeSnapshot } from '@deepseek-ai/dsh-client-ui-settings/client'\nimport { setSceneBackdropActive } from './runtime/backdrop-scene.ts'\n\n/** The namespace string the Host registers (mirrors src/index.ts). */\nexport const SKIN_WALLPAPER_NS = 'skin-wallpaper'\n\n/** One wallpaper's render contract, as delivered by the inventory route. */\nexport interface WallpaperDescriptor {\n id: string\n title: string\n /** 'image' is the macOS Desktop Pictures kind: a static host-converted JPEG. */\n type: 'video' | 'web' | 'scene' | 'application' | 'image'\n videoUrl: string | null\n webUrl: string | null\n frameUrl: string | null\n sceneUrl?: string | null\n /** Result of the lazy scene probe; retained for diagnostics and probe de-duping. */\n sceneCompatibility?: 'full' | 'partial' | 'static-only'\n unsupportedFeatures?: string[]\n /** Fullscreen authored layer placed beneath the live player when needed. */\n sceneBaseUrl?: string | null\n /** Hide the player only when an unsupported script makes a later opaque layer invalid. */\n preferSceneBase?: boolean\n /** Decoded fullscreen artwork discovered from the scene manifest. */\n previewUrl: string | null\n}\n\n/** The persisted wallpaper section shape. */\ninterface WallpaperSection {\n enabled?: boolean\n selection?: string\n mode?: 'live' | 'frame'\n fit?: 'cover' | 'contain' | 'fill'\n pauseOnHidden?: boolean\n dim?: number\n wallpaperBlur?: number\n /** Opacity of the wallpaper media layer itself, 0-100 percent. */\n wallpaperOpacity?: number\n /** Audible video wallpaper playback (default off = muted, #580). */\n sound?: boolean\n /** Wallpaper audio volume 0-100 (default 100). */\n volume?: number\n weLibraryDirs?: string[]\n}\n\n/** The face the skin-center card injects for the wallpaper feature. */\nexport interface WallpaperHandle {\n enabled(): boolean\n /** The persisted selection id ('' = none). */\n selection(): string\n mode(): 'live' | 'frame'\n fit(): 'cover' | 'contain' | 'fill'\n dim(): number\n wallpaperBlur(): number\n /** Opacity of the wallpaper media layer itself, 0-100. */\n wallpaperOpacity(): number\n pauseOnHidden(): boolean\n /** Audible playback for video wallpapers (default false = muted). */\n sound(): boolean\n /** Wallpaper audio volume 0-100. */\n volume(): number\n /** Manual library folders (settings field weLibraryDirs). */\n dirs(): string[]\n /** Add a manual library folder (trimmed, deduped) and persist. */\n addDir(dir: string): void\n /** Remove a manual library folder and persist. */\n removeDir(dir: string): void\n /**\n * Open the host's native directory picker (the SDK's loopback-only\n * host.pickDirectory: Finder on macOS, Explorer on Windows). Resolves to\n * the chosen absolute path, or null when the user cancelled. Rejects when\n * the native capability is unavailable (e.g. a paired remote client), in\n * which case the manual input remains the fallback. Optional: faces\n * without host access omit it and the panel hides the browse button.\n */\n pickDir?(): Promise<string | null>\n /** The currently mounted wallpaper id (try-on included), or null. */\n activeId(): string | null\n /** True while a try-on mount is up. */\n trying(): boolean\n subscribe(listener: () => void): () => void\n setEnabled(value: boolean): void\n setMode(mode: 'live' | 'frame'): void\n setFit(fit: 'cover' | 'contain' | 'fill'): void\n setDim(value: number): void\n setBlur(value: number): void\n setOpacity(value: number): void\n setPauseOnHidden(value: boolean): void\n setSound(value: boolean): void\n setVolume(value: number): void\n /** Persist + render a selection. */\n applySelection(descriptor: WallpaperDescriptor): void\n /** Unmount + clear the persisted selection. */\n clearSelection(): void\n /**\n * Reconcile the mounted layer with the persisted selection: the card\n * resolves the selection id against the inventory and calls this with the\n * descriptor (or null when the wallpaper is gone / none selected).\n */\n sync(descriptor: WallpaperDescriptor | null): void\n /** Mount a temporary preview (the applied selection is kept, not lost). */\n tryOn(descriptor: WallpaperDescriptor): void\n /** Drop the try-on mount and restore the applied selection, if any. */\n exitTryOn(): void\n /** Reconcile a live scene player after an external theme/compositor change. */\n recoverScenePlayer(): void\n dispose(): void\n}\n\nconst clamp = (value: number, min: number, max: number): number =>\n Math.max(min, Math.min(max, Math.round(value)))\n\n/** Style one fixed, non-interactive, under-everything wallpaper layer. */\nfunction styleLayer(element: HTMLElement, zIndex: number, layer: 'media' | 'scrim'): void {\n element.dataset.dshWallpaperLayer = layer\n element.style.position = 'fixed'\n element.style.inset = '0'\n element.style.zIndex = String(zIndex)\n element.style.pointerEvents = 'none'\n element.style.overflow = 'hidden'\n element.setAttribute('aria-hidden', 'true')\n}\n\n/** Style a full-bleed cover child (video / img / iframe). */\nfunction styleCover(element: HTMLElement, fit: 'cover' | 'contain' | 'fill' = 'cover'): void {\n element.style.width = '100%'\n element.style.height = '100%'\n element.style.objectFit = fit\n element.style.border = '0'\n element.style.display = 'block'\n}\n\n/** Max static-frame capture edge (the backdrop never needs more pixels). */\nconst FRAME_MAX_EDGE = 1920\n\nconst MIN_VIEWPORT_SURFACE_HEIGHT = 0.9\nconst MAX_SURFACE_OVERLAY_Z_INDEX = 100\n\n/** Any nontransparent background blocks some of the wallpaper. */\nfunction hasVisibleBackground(color: string): boolean {\n const normalized = color.trim().toLowerCase()\n if (normalized === '' || normalized === 'transparent') return false\n const match = normalized.match(/^[a-z-]+\\((.*)\\)$/)\n if (match === null) return true\n const args = match[1]\n const slash = args.lastIndexOf('/')\n if (slash >= 0) return hasVisibleAlpha(args.slice(slash + 1))\n const channels = args.split(',')\n return channels.length === 4 ? hasVisibleAlpha(channels[3] ?? '') : true\n}\n\nfunction hasVisibleAlpha(value: string): boolean {\n const alpha = Number.parseFloat(value)\n return Number.isFinite(alpha) && alpha > 0\n}\n\n/** Exclude owned layers plus modal/plugin/sidebar/details surfaces that must retain their paint. */\nfunction isExcludedWallpaperSurface(el: HTMLElement, zIndex: string): boolean {\n const semanticOverlay = typeof el.closest === 'function'\n && el.closest(\n '[data-dsh-wallpaper-layer], dialog, [role=\"dialog\"], [aria-modal=\"true\"], [data-shell-overlay], [data-slot=\"shell.overlay\"], [data-dsh-plugin], [data-slot=\"sidebar\"], [data-dsh-surface=\"sidebar\"], [data-slot=\"sidebar.workspaces\"], [data-pane=\"sidebar\"], aside, [data-slot=\"details\"], [data-dsh-surface=\"details\"], [data-pane=\"details\"], [class*=\"detailsCol\"], .aionui-root, [data-aionui-explorer-col], [data-aionui-preview-col], [data-dsh-better-sidebar], [data-dsh-panel-host]',\n ) !== null\n if (semanticOverlay) return true\n const numericZIndex = Number.parseFloat(zIndex)\n return Number.isFinite(numericZIndex) && numericZIndex > MAX_SURFACE_OVERLAY_Z_INDEX\n}\n\n/**\n * Default shell-surface detector for WE wallpaper neutralization (#712). A\n * target must cover most of the visible viewport and paint a nontransparent\n * background. It deliberately avoids equality against a theme token because\n * real shell surfaces can resolve a different or partially transparent color.\n * Modal and plugin overlays stay out of scope even when they fill the viewport.\n */\nexport function defaultWallpaperSurface(el: HTMLElement, doc: Document): boolean {\n const win = doc.defaultView\n if (win === null) return false\n let rectHeight = 0\n let viewportHeight = 0\n let background = ''\n let zIndex = ''\n try {\n rectHeight = el.getBoundingClientRect().height\n viewportHeight = doc.documentElement.clientHeight || win.innerHeight || 0\n const cs = win.getComputedStyle(el)\n background = cs.backgroundColor\n zIndex = cs.zIndex\n } catch {\n return false\n }\n // Only a rendered surface can obscure the wallpaper. In particular, avoid\n // tagging a hidden subtree before it has a real layout box. Upstream #712:\n // color-independent (any visible background) + min viewport coverage, so a\n // full-height shell surface no longer misses the mark on a token mismatch.\n const fillsViewport = viewportHeight > 0\n && rectHeight >= viewportHeight * MIN_VIEWPORT_SURFACE_HEIGHT\n return fillsViewport\n && hasVisibleBackground(background)\n && !isExcludedWallpaperSurface(el, zIndex)\n}\n\n/**\n * Workspace-list end-fade detector (#734): a gradient-background element inside\n * the sidebar workspaces slot. The official `data-slot=\"sidebar.workspaces\"`\n * anchor is stable; the fade element only carries hashed CSS-module classes, so\n * this selects it by computed style instead of class names.\n */\nexport function defaultWorkspaceFade(el: HTMLElement, doc: Document): boolean {\n const win = doc.defaultView\n if (win === null) return false\n try {\n return win.getComputedStyle(el).backgroundImage.includes('gradient')\n } catch {\n return false\n }\n}\n\nexport interface WallpaperControllerOptions {\n apiBase?: string\n fetchImpl?: typeof fetch\n doc?: Document\n /** Override the full-viewport-surface detector (tests); defaults to the\n * computed-style heuristic in defaultWallpaperSurface. */\n declareSurface?: (el: HTMLElement, doc: Document) => boolean\n /** Override the sidebar workspaces end-fade detector (tests); defaults to\n * defaultWorkspaceFade. */\n declareWorkspaceFade?: (el: HTMLElement, doc: Document) => boolean\n /** Trailing debounce for the surface re-scan (ms). Coalesces burst DOM\n * mutations (chat streaming) into one settled sweep; tests pass 0 to flush\n * right after rAF. Defaults to 150. */\n surfaceTrailMs?: number\n /** Override the light/dark theme detector (tests); defaults to\n * body[data-ds-dark-theme] presence. */\n themeGet?: () => 'light' | 'dark'\n}\n\n/**\n * Own the skin-wallpaper scope: keep the mounted layers in sync with the\n * persisted selection and the card-driven descriptor resolution.\n */\nexport class WallpaperController implements WallpaperHandle {\n private enabledValue = true\n private selectionValue = ''\n private modeValue: 'live' | 'frame' = 'live'\n private fitValue: 'cover' | 'contain' | 'fill' = 'cover'\n private pauseOnHiddenValue = true\n private soundValue = false\n private volumeValue = 100\n private dimValue = 25\n private blurValue = 0\n private opacityValue = 100\n private dirsValue: string[] = []\n private readonly listeners = new Set<() => void>()\n private readonly scope: SettingsScope<WallpaperSection>\n private readonly unsubscribe: () => void\n private readonly options: WallpaperControllerOptions\n private readonly doc: Document\n\n /** The descriptor of the applied selection, resolved by the card. */\n private applied: WallpaperDescriptor | null = null\n /** The try-on descriptor while a preview is up. */\n private previewing: WallpaperDescriptor | null = null\n\n private mediaLayer: HTMLDivElement | null = null\n private scrimLayer: HTMLDivElement | null = null\n private videoElement: HTMLVideoElement | null = null\n private rootNeutralizer: HTMLStyleElement | null = null\n /** Re-asserts the wallpaper layers if the shell tears the body subtree down. */\n private mountObserver: MutationObserver | null = null\n /** Re-tags full-viewport surfaces after navigation rebuilds #root (#805). */\n private surfaceObserver: MutationObserver | null = null\n /** Shell surfaces tagged with data-dsh-wallpaper-surface during this mount. */\n private taggedSurfaces = new Set<HTMLElement>()\n private disposed = false\n /** In-flight scene probes by wallpaper id; overlapping entry points\n * (applySelection / tryOn / sync / fetchAndSync) must not re-read the\n * same packed scene concurrently. */\n private probePending = new Map<string, Promise<void>>()\n /** Detached frame-capture video; released on error/abort/loadeddata and on\n * teardown so it never keeps buffering the source file. */\n private captureVideo: HTMLVideoElement | null = null\n /** Guard flag: suppresses readAll during applyThemeDefaults scope writes\n * to prevent mid-write listener cascades from resetting values. */\n private seeding = false\n\n constructor(scope: SettingsScope<WallpaperSection>, options: WallpaperControllerOptions = {}) {\n this.scope = scope\n this.options = options\n this.doc = options.doc ?? document\n this.readAll()\n this.unsubscribe = scope.subscribe(() => {\n if (this.disposed || this.seeding) return\n this.readAll()\n if (this.enabledValue && this.selectionValue && (!this.applied || this.applied.id !== this.selectionValue)) {\n this.fetchAndSync()\n } else {\n this.render()\n this.publish()\n }\n })\n // Pause-on-hidden wiring lives for the controller's whole life; it only\n // ever acts while a video is mounted.\n this.doc.addEventListener('visibilitychange', this.onVisibility)\n this.doc.defaultView?.addEventListener('message', this.onSceneMessage)\n // Audible autoplay stays blocked until the first user gesture; retry\n // play() on that gesture so an unmuted live wallpaper starts (#580).\n this.doc.addEventListener('pointerdown', this.onFirstGesture)\n this.doc.addEventListener('keydown', this.onFirstGesture)\n // Some DSH navigation (e.g. switching conversations) tears down the body\n // subtree, which removes the wallpaper layers while the selection is\n // still active. Re-mount them so the wallpaper does not disappear (#805).\n const win = this.doc.defaultView\n if (win !== null && typeof win.MutationObserver === 'function') {\n this.mountObserver = new win.MutationObserver(() => {\n if (this.disposed) return\n if ((this.previewing ?? this.applied) === null) return\n if (this.mediaLayer === null || !this.mediaLayer.isConnected) {\n this.render()\n }\n })\n this.mountObserver.observe(this.doc.body, { childList: true })\n }\n // Theme-aware defaults (#1051): when the scope has no explicit dim or\n // opacity (both sit at schema defaults), seed values tuned for the\n // current light/dark theme so text is readable out of the box.\n this.applyThemeDefaults()\n if (this.enabledValue && this.selectionValue) {\n this.fetchAndSync()\n }\n }\n\n private fetchAndSync(): void {\n if (!this.selectionValue || !this.doc) return\n const targetId = this.selectionValue\n const fetchFn = this.options.fetchImpl ?? (typeof fetch !== 'undefined' ? fetch.bind(this.doc.defaultView ?? globalThis) : undefined)\n if (!fetchFn) return\n const apiBase = this.options.apiBase ?? '/api/skin-center/we'\n fetchFn(`${apiBase}/inventory`)\n .then(async (response) => {\n if (this.disposed || !response.ok) return\n const payload = (await response.json().catch(() => null)) as {\n ok?: boolean\n wallpapers?: WallpaperDescriptor[]\n } | null\n if (payload?.ok === true && Array.isArray(payload.wallpapers)) {\n const item = payload.wallpapers.find((w) => w.id === targetId)\n if (item && this.selectionValue === targetId) {\n this.applied = item\n this.render()\n this.publish()\n this.probeSceneCapabilitiesIfNeeded(item)\n }\n }\n })\n .catch(() => {\n // Fail-silent on network errors\n })\n }\n\n /**\n * Lazily probe a scene's video/WebGL capabilities: the inventory never\n * reads packed scene payloads, so only the wallpaper the user actually\n * selects (apply, try-on or boot sync) asks the probe route. The response\n * is merged into every slot (previewing and applied) that holds the id.\n */\n private probeSceneCapabilitiesIfNeeded(descriptor: WallpaperDescriptor): void {\n if (this.disposed || descriptor.type !== 'scene' || descriptor.videoUrl !== null || descriptor.sceneUrl != null || descriptor.sceneCompatibility !== undefined) return\n const targetId = descriptor.id\n if (this.probePending.has(targetId)) return\n const fetchFn = this.options.fetchImpl ?? (typeof fetch !== 'undefined' ? fetch.bind(this.doc.defaultView ?? globalThis) : undefined)\n if (!fetchFn) return\n const apiBase = this.options.apiBase ?? '/api/skin-center/we'\n const pending = fetchFn(apiBase + '/scene-probe?id=' + encodeURIComponent(targetId))\n .then(async (response) => {\n if (this.disposed || !response.ok) return\n const payload = (await response.json().catch(() => null)) as {\n ok?: boolean\n videoUrl?: string | null\n sceneUrl?: string | null\n compatibility?: 'full' | 'partial' | 'static-only'\n unsupportedFeatures?: string[]\n } | null\n if (!payload || payload.ok !== true) return\n let sceneBaseUrl: string | null = null\n let preferSceneBase = false\n if (payload.sceneUrl && payload.compatibility === 'partial'\n && payload.unsupportedFeatures?.includes('embedded-script') === true) {\n try {\n const manifestResponse = await fetchFn(payload.sceneUrl.replace('/scene-runtime/', '/scene-manifest/'))\n const manifestPayload = manifestResponse.ok\n ? await manifestResponse.json().catch(() => null) as {\n ok?: boolean\n manifest?: {\n width?: number\n height?: number\n timeSchedule?: unknown\n layers?: Array<{ x?: number; y?: number; w?: number; h?: number; texUrl?: string; videoUrl?: string }>\n }\n } | null\n : null\n const manifest = manifestPayload?.ok === true ? manifestPayload.manifest : undefined\n // The renderer implements author-configured real-time switching;\n // do not replace that live player with one static base merely because\n // unrelated embedded scripts remain unsupported.\n if (manifest && manifest.timeSchedule === undefined && typeof manifest.width === 'number' && typeof manifest.height === 'number') {\n // Video-backed layers serve MP4 bytes: a CSS background cannot\n // paint them, so only still-image layers qualify as the base.\n const fullscreenIndex = manifest.layers?.findIndex(layer =>\n typeof layer.texUrl === 'string'\n && typeof layer.videoUrl !== 'string'\n && Math.abs((layer.w ?? 0) - manifest.width!) <= 1\n && Math.abs((layer.h ?? 0) - manifest.height!) <= 1\n && Math.abs((layer.x ?? 0) - manifest.width! / 2) <= 1\n && Math.abs((layer.y ?? 0) - manifest.height! / 2) <= 1\n ) ?? -1\n if (fullscreenIndex >= 0) {\n sceneBaseUrl = manifest.layers?.[fullscreenIndex]?.texUrl ?? null\n // A later oversized layer is generally a script-controlled\n // project/compose surface. It can cover the real artwork when\n // its script is unsupported; ordinary multi-layer scenes keep\n // the live player visible.\n preferSceneBase = manifest.layers?.slice(fullscreenIndex + 1).some(layer =>\n (layer.w ?? 0) > manifest.width! * 1.25\n || (layer.h ?? 0) > manifest.height! * 1.25\n ) === true\n }\n }\n } catch {\n // Keep the regular scene frame/player fallback.\n }\n }\n if (this.disposed) return\n // Compatibility metadata is retained for diagnostics and probe de-duping.\n // Partial scenes still use their actual scene runtime: unsupported scripts\n // may omit individual effects, but the decoded Wallpaper Engine layers and\n // supported particles must remain dynamic rather than becoming a cover.\n // Merge the capabilities into every slot holding the id: a probe\n // issued by try-on may land while sync/apply has already installed\n // the same wallpaper as applied, and exiting the try-on must not\n // fall back to a static frame without capabilities.\n let changed = false\n if (this.previewing?.id === targetId) {\n const merged: WallpaperDescriptor = {\n ...this.previewing,\n videoUrl: payload.videoUrl ?? this.previewing.videoUrl,\n sceneUrl: payload.sceneUrl ?? this.previewing.sceneUrl,\n sceneCompatibility: payload.compatibility,\n unsupportedFeatures: payload.unsupportedFeatures,\n sceneBaseUrl: sceneBaseUrl ?? this.previewing.sceneBaseUrl,\n preferSceneBase,\n }\n if (merged.videoUrl !== this.previewing.videoUrl\n || merged.sceneUrl !== this.previewing.sceneUrl\n || merged.sceneCompatibility !== this.previewing.sceneCompatibility\n || merged.sceneBaseUrl !== this.previewing.sceneBaseUrl\n || merged.preferSceneBase !== this.previewing.preferSceneBase) {\n this.previewing = merged\n changed = true\n }\n }\n if (this.applied?.id === targetId) {\n const merged: WallpaperDescriptor = {\n ...this.applied,\n videoUrl: payload.videoUrl ?? this.applied.videoUrl,\n sceneUrl: payload.sceneUrl ?? this.applied.sceneUrl,\n sceneCompatibility: payload.compatibility,\n unsupportedFeatures: payload.unsupportedFeatures,\n sceneBaseUrl: sceneBaseUrl ?? this.applied.sceneBaseUrl,\n preferSceneBase,\n }\n if (merged.videoUrl !== this.applied.videoUrl\n || merged.sceneUrl !== this.applied.sceneUrl\n || merged.sceneCompatibility !== this.applied.sceneCompatibility\n || merged.sceneBaseUrl !== this.applied.sceneBaseUrl\n || merged.preferSceneBase !== this.applied.preferSceneBase) {\n this.applied = merged\n changed = true\n }\n }\n if (!changed) return\n this.render()\n this.publish()\n })\n .catch(() => {\n // Fail-silent on network errors\n })\n .finally(() => {\n this.probePending.delete(targetId)\n })\n this.probePending.set(targetId, pending)\n }\n\n enabled = (): boolean => this.enabledValue\n selection = (): string => this.selectionValue\n mode = (): 'live' | 'frame' => this.modeValue\n fit = (): 'cover' | 'contain' | 'fill' => this.fitValue\n dim = (): number => this.dimValue\n wallpaperBlur = (): number => this.blurValue\n wallpaperOpacity = (): number => this.opacityValue\n pauseOnHidden = (): boolean => this.pauseOnHiddenValue\n sound = (): boolean => this.soundValue\n volume = (): number => this.volumeValue\n dirs = (): string[] => this.dirsValue\n\n addDir(dir: string): void {\n const trimmed = dir.trim()\n if (trimmed === '' || this.dirsValue.includes(trimmed)) return\n this.dirsValue = [...this.dirsValue, trimmed]\n this.publish()\n void this.scope.set('weLibraryDirs', this.dirsValue)\n }\n\n removeDir(dir: string): void {\n const next = this.dirsValue.filter(d => d !== dir)\n if (next.length === this.dirsValue.length) return\n this.dirsValue = next\n this.publish()\n void this.scope.set('weLibraryDirs', this.dirsValue)\n }\n\n private failedIds = new Set<string>()\n\n isDisplaying = (): boolean => {\n const id = this.activeId()\n return this.enabledValue && id !== null && !this.failedIds.has(id)\n }\n\n activeId = (): string | null => {\n const current = this.previewing ?? this.applied\n return this.mediaLayer !== null && current !== null ? current.id : null\n }\n trying = (): boolean => this.previewing !== null\n\n subscribe = (listener: () => void): (() => void) => {\n this.listeners.add(listener)\n return () => { this.listeners.delete(listener) }\n }\n\n setEnabled(value: boolean): void {\n this.enabledValue = value\n this.render()\n this.publish()\n void this.scope.set('enabled', value)\n }\n\n setMode(mode: 'live' | 'frame'): void {\n this.modeValue = mode\n this.render()\n this.publish()\n void this.scope.set('mode', mode)\n }\n\n setFit(fit: 'cover' | 'contain' | 'fill'): void {\n this.fitValue = fit\n this.render()\n this.publish()\n void this.scope.set('fit', fit)\n }\n\n setDim(value: number): void {\n this.dimValue = clamp(value, 0, 90)\n this.render()\n this.publish()\n void this.scope.set('dim', this.dimValue)\n }\n\n setBlur(value: number): void {\n this.blurValue = clamp(value, 0, 60)\n this.render()\n this.publish()\n void this.scope.set('wallpaperBlur', this.blurValue)\n }\n\n setOpacity(value: number): void {\n this.opacityValue = clamp(value, 0, 100)\n this.render()\n this.publish()\n void this.scope.set('wallpaperOpacity', this.opacityValue)\n }\n\n setPauseOnHidden(value: boolean): void {\n this.pauseOnHiddenValue = value\n this.publish()\n void this.scope.set('pauseOnHidden', value)\n }\n\n setSound(value: boolean): void {\n this.soundValue = value\n this.applySound()\n this.publish()\n void this.scope.set('sound', value)\n }\n\n setVolume(value: number): void {\n this.volumeValue = clamp(value, 0, 100)\n this.applySound()\n this.publish()\n void this.scope.set('volume', this.volumeValue)\n }\n\n applySelection(descriptor: WallpaperDescriptor): void {\n this.failedIds.delete(descriptor.id)\n this.applied = descriptor\n this.previewing = null\n this.selectionValue = descriptor.id\n this.render()\n this.publish()\n void this.scope.set('selection', descriptor.id)\n this.probeSceneCapabilitiesIfNeeded(descriptor)\n }\n\n clearSelection(): void {\n this.applied = null\n this.previewing = null\n this.selectionValue = ''\n this.render()\n this.publish()\n void this.scope.set('selection', '')\n }\n\n sync(descriptor: WallpaperDescriptor | null): void {\n // Inventory descriptors intentionally omit lazily probed scene capabilities.\n // Reopening Skin Center refreshes that inventory, so replacing an already\n // enriched descriptor verbatim would drop sceneUrl/videoUrl, rebuild the\n // media as a static frame, then probe and rebuild the live player again.\n // Preserve capabilities for the same id while still accepting every other\n // refreshed field from inventory.\n if (descriptor !== null && this.applied?.id === descriptor.id) {\n descriptor = {\n ...descriptor,\n videoUrl: descriptor.videoUrl ?? this.applied.videoUrl,\n sceneUrl: descriptor.sceneUrl ?? this.applied.sceneUrl,\n sceneCompatibility: descriptor.sceneCompatibility ?? this.applied.sceneCompatibility,\n unsupportedFeatures: descriptor.unsupportedFeatures ?? this.applied.unsupportedFeatures,\n sceneBaseUrl: descriptor.sceneBaseUrl ?? this.applied.sceneBaseUrl,\n preferSceneBase: descriptor.preferSceneBase ?? this.applied.preferSceneBase,\n }\n }\n this.applied = descriptor\n this.render()\n if (descriptor !== null) this.probeSceneCapabilitiesIfNeeded(descriptor)\n }\n\n tryOn(descriptor: WallpaperDescriptor): void {\n this.failedIds.delete(descriptor.id)\n this.previewing = descriptor\n this.render()\n this.publish()\n this.probeSceneCapabilitiesIfNeeded(descriptor)\n }\n\n exitTryOn(): void {\n if (this.previewing === null) return\n this.previewing = null\n this.render()\n this.publish()\n }\n\n recoverScenePlayer(): void {\n const scenePlayer = this.mediaLayer?.firstElementChild ?? null\n if (!(scenePlayer instanceof HTMLIFrameElement) || scenePlayer.dataset.dshScenePlayer !== '') return\n try {\n // The sandboxed player has an opaque origin, so a same-origin target\n // would never match it; '*' delivers to the single identified window.\n scenePlayer.contentWindow?.postMessage({ type: 'dsh-recover-renderer' }, '*')\n } catch {\n // A failed recovery message is harmless; the next render keeps the current frame.\n }\n }\n\n dispose(): void {\n if (this.disposed) return\n this.disposed = true\n this.unsubscribe()\n this.mountObserver?.disconnect()\n this.mountObserver = null\n this.doc.removeEventListener('visibilitychange', this.onVisibility)\n this.doc.defaultView?.removeEventListener('message', this.onSceneMessage)\n this.doc.removeEventListener('pointerdown', this.onFirstGesture)\n this.doc.removeEventListener('keydown', this.onFirstGesture)\n this.teardownLayers()\n }\n\n // --- internals -----------------------------------------------------------\n\n /**\n * Seed dim and opacity with theme-tuned values when neither has been\n * explicitly set (both are at schema defaults: dim=25, opacity=100).\n * This runs once at construction so a fresh wallpaper install gets\n * readable defaults for the active theme. Users who have already\n * adjusted either slider keep their values (#1051).\n */\n private applyThemeDefaults(): void {\n const snapshot = this.scope.getSnapshot()\n const value = snapshot.value ?? {}\n // Detect whether dim and opacity have never been written to the scope.\n // A value of undefined means the field was never persisted; any number\n // (even the schema default 25 for dim) means the user or a prior seed\n // already set it, so we must not overwrite.\n if (value.dim !== undefined || value.wallpaperOpacity !== undefined) return\n // The scope may not yet be writable during early initialization.\n if (snapshot.writable === false) return\n const theme = this.options.themeGet !== undefined\n ? this.options.themeGet()\n : (this.doc.body?.hasAttribute('data-ds-dark-theme') ? 'dark' : 'light')\n if (theme === 'light') {\n this.dimValue = 0\n this.opacityValue = 40\n } else {\n this.dimValue = 40\n this.opacityValue = 100\n }\n this.seeding = true\n try {\n void this.scope.set('dim', this.dimValue)\n void this.scope.set('wallpaperOpacity', this.opacityValue)\n } catch { /* scope not ready — values stay local until next readAll */ }\n this.seeding = false\n }\n\n private readAll(): void {\n const snapshot: SettingsScopeSnapshot<WallpaperSection> = this.scope.getSnapshot()\n const value = snapshot.value ?? {}\n this.enabledValue = typeof value.enabled === 'boolean' ? value.enabled : true\n this.selectionValue = typeof value.selection === 'string' ? value.selection : ''\n this.modeValue = value.mode === 'frame' ? 'frame' : 'live'\n const rawFit = value.fit\n this.fitValue = rawFit === 'contain' || rawFit === 'fill' ? rawFit : 'cover'\n this.pauseOnHiddenValue = typeof value.pauseOnHidden === 'boolean' ? value.pauseOnHidden : true\n this.soundValue = typeof value.sound === 'boolean' ? value.sound : false\n this.volumeValue = typeof value.volume === 'number' && Number.isFinite(value.volume)\n ? clamp(value.volume, 0, 100)\n : 100\n this.dimValue = typeof value.dim === 'number' && Number.isFinite(value.dim) ? clamp(value.dim, 0, 90) : 25\n this.blurValue = typeof value.wallpaperBlur === 'number' && Number.isFinite(value.wallpaperBlur)\n ? clamp(value.wallpaperBlur, 0, 60)\n : 0\n this.opacityValue = typeof value.wallpaperOpacity === 'number' && Number.isFinite(value.wallpaperOpacity)\n ? clamp(value.wallpaperOpacity, 0, 100)\n : 100\n this.dirsValue = Array.isArray(value.weLibraryDirs)\n ? value.weLibraryDirs.filter((d): d is string => typeof d === 'string' && d.trim() !== '')\n : []\n }\n\n /** Resume a policy-blocked video on the first user gesture (#580). */\n private readonly onFirstGesture = (): void => {\n if (this.videoElement === null || !this.videoElement.paused) return\n // jsdom (and older engines) return undefined, real browsers a promise.\n void this.videoElement.play()?.catch(() => { /* still blocked: retry on the next gesture */ })\n }\n\n private readonly onSceneMessage = (event: MessageEvent): void => {\n const scenePlayer = this.mediaLayer?.firstElementChild ?? null\n if (!(scenePlayer instanceof HTMLIFrameElement) || scenePlayer.dataset.dshScenePlayer !== '') return\n // The player is sandboxed without allow-same-origin, so its opaque origin\n // arrives as Origin \"null\"; only the identity of the sender (this exact\n // iframe window) proves the message came from the mounted player.\n if (event.source !== scenePlayer.contentWindow) return\n const message = event.data as { type?: unknown } | null\n if (message?.type !== 'dsh-scene-needs-reload') return\n // Context restoration invalidates every WebGL object. Reloading only the\n // isolated renderer keeps the wallpaper selection and shell state intact.\n scenePlayer.src = scenePlayer.src\n }\n\n private readonly onVisibility = (): void => {\n if (!this.pauseOnHiddenValue) return\n if (this.videoElement !== null) {\n if (this.doc.hidden) {\n this.videoElement.pause()\n } else {\n // jsdom (and older engines) return undefined, real browsers a promise.\n void this.videoElement.play()?.catch(() => { /* autoplay policy */ })\n }\n }\n const scenePlayer = this.mediaLayer?.firstElementChild ?? null\n if (scenePlayer instanceof HTMLIFrameElement && scenePlayer.dataset.dshScenePlayer === '') {\n try {\n // '*' reaches the opaque-origin sandboxed player (see applyFit).\n scenePlayer.contentWindow?.postMessage({ type: 'dsh-set-pause', paused: this.doc.hidden }, '*')\n } catch {\n // ignore\n }\n }\n }\n\n /** Reconcile the DOM with (enabled, previewing ?? applied, mode, dim, blur). */\n private render(): void {\n if (this.disposed) return\n const current = this.enabledValue ? (this.previewing ?? this.applied) : null\n if (current === null) {\n this.teardownLayers()\n return\n }\n this.ensureLayers(current)\n }\n\n private ensureLayers(descriptor: WallpaperDescriptor): void {\n // The stock shell paints opaque backgrounds on the app root and on the\n // composer seat, which fully cover the negative-z wallpaper layers\n // (issue #505, #632). Neutralize them ONLY while the own marker\n // data-dsh-wallpaper-active is present, so no skin or plugin style is\n // affected outside a mounted wallpaper (#506). The app-root rules mirror\n // the contract the v2 skin CSS pipeline appends for every skin\n // (`[id=\"root\"] { background: transparent }`); the id/attribute selectors\n // outrank the shell's class rules, and the --dsw-alias-bg-base token\n // itself is left untouched for every other consumer.\n if (this.rootNeutralizer === null) {\n this.rootNeutralizer = this.doc.createElement('style')\n this.rootNeutralizer.dataset.dshWallpaperRoot = ''\n this.rootNeutralizer.textContent = `\n [id=\"root\"] { background: transparent; }\n /* Wallpaper opacity backdrop (#1051): light-mode fades to white,\n dark-mode fades to black. :has() tracks theme switches live. */\n html[data-dsh-wallpaper-active] {\n background-color: white !important;\n background-image: none !important;\n }\n html[data-dsh-wallpaper-active]:has(body[data-ds-dark-theme]) {\n background-color: black !important;\n }\n body[data-dsh-wallpaper-active],\n html[data-dsh-skin][data-dsh-wallpaper-active] body,\n html[data-dsh-skin] body[data-dsh-wallpaper-active],\n body[data-dsh-wallpaper-active][data-ds-dark-theme],\n html[data-dsh-wallpaper-active] [id=\"root\"] {\n background-color: transparent !important;\n background-image: none !important;\n }\n /* Seat-wide skin pseudos would blur the whole footer. The shared dock\n row owns the compact rounded transcript mask instead (#777/#978). */\n html[data-dsh-wallpaper-active] [data-composer-seat]::before {\n background: none !important;\n backdrop-filter: none !important;\n }\n /* Full-viewport shell surfaces (AppFrame frame, conversation root,\n details root) paint the opaque app base background via hashed\n CSS-module classes. While a WE wallpaper is mounted the controller\n tags them with the own marker data-dsh-wallpaper-surface\n (markWallpaperSurfaces), and this rule neutralizes them with no\n class-name dependency (issue #734). */\n html[data-dsh-wallpaper-active] [data-dsh-wallpaper-surface] {\n background-color: transparent !important;\n background-image: none !important;\n }\n `\n this.doc.head.appendChild(this.rootNeutralizer)\n }\n this.doc.body.dataset.dshWallpaperActive = 'true'\n this.doc.documentElement.dataset.dshWallpaperActive = 'true'\n // Report the wallpaper into the unified \"backdrop visible\" marker so the\n // shared composer-seat neutralizer applies here too (issue #777).\n setSceneBackdropActive(this.doc, 'wallpaper', true)\n this.markSurfaces()\n this.ensureSurfaceObserver()\n // Connect-aware: navigation (e.g. switching conversations) can tear the\n // wallpaper layers out of the body subtree while the references survive.\n // Re-append the surviving layer instead of recreating it, so the media\n // child and its mediaKey survive and the video is not rebuilt / restarted\n // (#805). Only build a fresh layer when there is none at all.\n if (this.mediaLayer !== null && !this.mediaLayer.isConnected) {\n this.doc.body.appendChild(this.mediaLayer)\n }\n if (this.mediaLayer === null) {\n this.mediaLayer = this.doc.createElement('div')\n styleLayer(this.mediaLayer, -3, 'media')\n this.doc.body.appendChild(this.mediaLayer)\n }\n if (this.scrimLayer !== null && !this.scrimLayer.isConnected) {\n this.doc.body.appendChild(this.scrimLayer)\n }\n if (this.scrimLayer === null) {\n this.scrimLayer = this.doc.createElement('div')\n styleLayer(this.scrimLayer, -2, 'scrim')\n this.doc.body.appendChild(this.scrimLayer)\n }\n // Keep the inventory preview painted beneath live scene iframes. A WebGL\n // context can be temporarily lost (or its canvas can clear before the\n // isolated player reloads); without this backing frame the transparent\n // iframe exposes only the shell gradient and looks like the wallpaper was\n // removed. Video/web wallpapers paint their own opaque media, so they do\n // not need a duplicate backdrop.\n const sceneBackdrop = descriptor.type === 'scene'\n ? (descriptor.sceneBaseUrl ?? descriptor.frameUrl ?? descriptor.previewUrl)\n : null\n this.mediaLayer.style.backgroundImage = sceneBackdrop === null ? '' : `url(${JSON.stringify(sceneBackdrop)})`\n this.mediaLayer.style.backgroundPosition = sceneBackdrop === null ? '' : 'center'\n this.mediaLayer.style.backgroundRepeat = sceneBackdrop === null ? '' : 'no-repeat'\n this.mediaLayer.style.backgroundSize = sceneBackdrop === null\n ? ''\n : (this.fitValue === 'fill' ? '100% 100%' : this.fitValue)\n // Capabilities (videoUrl/sceneUrl) participate in the key: the lazy\n // scene probe merges them into the same descriptor id after the first\n // render, and the static frame must be rebuilt as live media.\n const mediaKey = descriptor.id + ':' + this.modeValue\n + ':' + (descriptor.videoUrl ?? '') + ':' + (descriptor.sceneUrl ?? '')\n + ':' + (descriptor.sceneCompatibility ?? '')\n + ':' + (descriptor.unsupportedFeatures?.join(',') ?? '')\n + ':' + (descriptor.sceneBaseUrl ?? '') + ':' + String(descriptor.preferSceneBase ?? false)\n if (this.mediaLayer.dataset.mediaKey !== mediaKey) {\n this.mediaLayer.dataset.mediaKey = mediaKey\n // A media transition (frame->live, mode switch) abandons the current\n // capture: release its src before replacing, otherwise the detached\n // video keeps buffering until teardown or the next capture.\n this.releaseCaptureVideo()\n this.mediaLayer.replaceChildren()\n this.videoElement = null\n const child = this.buildMedia(descriptor)\n if (child !== null) {\n this.mediaLayer.appendChild(child)\n // The initial play() in buildVideo ran while the element was detached\n // and may have been rejected; retry once mounted so large files start\n // streaming without a user gesture (#805 loading).\n if (child instanceof HTMLVideoElement && child.paused) {\n void child.play()?.catch(() => { /* retried on first gesture */ })\n }\n }\n } else {\n // Kept the surviving layer (mediaKey matched): some browsers pause a\n // <video> when it is torn out of the DOM, and the rebuild path above is\n // skipped, so its play retry never ran — resume playback explicitly.\n // Using the window-local constructor: jsdom (and isolated test envs)\n // may not surface the global HTMLVideoElement binding in every context.\n const child = this.mediaLayer.firstElementChild\n const VideoCtor = this.doc.defaultView?.HTMLVideoElement\n if (VideoCtor !== undefined && child instanceof VideoCtor && child.paused) {\n void child.play()?.catch(() => { /* autoplay policy: stays paused until gesture */ })\n }\n }\n // Sizing mode changes apply in place: rebuilding would restart video\n // playback and re-parse the scene on every click (#717 follow-up).\n this.applyFit()\n // Blur the wallpaper itself (the -1 backdrop-filter element stays the\n // skin-center blur control's business and blurs everything behind).\n const blur = this.blurValue > 0 ? 'blur(' + String(this.blurValue) + 'px)' : ''\n this.mediaLayer.style.filter = blur\n this.mediaLayer.style.transform = this.blurValue > 0 ? 'scale(1.05)' : ''\n // Wallpaper opacity (#1051): the html element's neutralizer background is\n // now black (not transparent) so reducing opacity fades toward black.\n this.mediaLayer.style.opacity = this.opacityValue < 100 ? String(this.opacityValue / 100) : ''\n this.scrimLayer.style.background = 'rgba(0, 0, 0, ' + String(this.dimValue / 100) + ')'\n }\n\n /** Push the current sizing mode onto the mounted media element. */\n private applyFit(): void {\n const child = this.mediaLayer?.firstElementChild ?? null\n if (child instanceof HTMLElement) {\n styleCover(child, this.fitValue)\n }\n if (child instanceof HTMLIFrameElement && child.dataset.dshScenePlayer === '') {\n try {\n // The player frame is sandboxed without allow-same-origin, so its\n // origin is opaque and a real-origin targetOrigin would drop the\n // message; '*' delivers to the identified contentWindow.\n child.contentWindow?.postMessage({ type: 'dsh-set-fit', fit: this.fitValue }, '*')\n } catch {\n // ignore: the player also receives the fit on its own load handler\n }\n }\n }\n\n /** Build the cover child for one descriptor + mode; null when unrenderable. */\n private buildMedia(descriptor: WallpaperDescriptor): HTMLElement | null {\n if (descriptor.type === 'video') {\n if (this.modeValue === 'live' && descriptor.videoUrl !== null) {\n return this.buildVideo(descriptor.videoUrl)\n }\n if (descriptor.videoUrl !== null) {\n return this.buildVideoFrame(descriptor.videoUrl, descriptor.previewUrl)\n }\n return this.buildImage(descriptor.previewUrl)\n }\n if (descriptor.type === 'web') {\n if (this.modeValue === 'live' && descriptor.webUrl !== null) {\n const iframe = this.doc.createElement('iframe')\n iframe.src = descriptor.webUrl\n // Web wallpapers are third-party HTML downloaded from the Workshop /\n // user directories and run with the host same-origin, so they must be\n // isolated: allow-scripts only gives an opaque origin (no parent DOM,\n // no host storage, no same-origin /api access). Script-only sandboxing\n // keeps textures/canvas/WebGL working; localStorage / cookies degrade.\n iframe.setAttribute('sandbox', 'allow-scripts')\n iframe.setAttribute('tabindex', '-1')\n styleCover(iframe, this.fitValue)\n return iframe\n }\n return this.buildImage(descriptor.previewUrl)\n }\n if (descriptor.type === 'scene') {\n if (this.modeValue === 'live' && descriptor.videoUrl !== null) {\n return this.buildVideo(descriptor.videoUrl, descriptor.frameUrl, descriptor.previewUrl)\n }\n if (this.modeValue === 'live' && descriptor.sceneUrl) {\n const iframe = this.doc.createElement('iframe')\n iframe.src = descriptor.sceneUrl\n // The scene player renders third-party scene data; same isolation as\n // web wallpapers (opaque origin, steering via postMessage).\n iframe.setAttribute('sandbox', 'allow-scripts')\n iframe.setAttribute('tabindex', '-1')\n iframe.dataset.dshScenePlayer = ''\n if (descriptor.preferSceneBase === true && descriptor.sceneBaseUrl) iframe.style.opacity = '0'\n styleCover(iframe, this.fitValue)\n iframe.addEventListener('load', () => {\n try {\n iframe.contentWindow?.postMessage({ type: 'dsh-set-fit', fit: this.fitValue }, '*')\n } catch {\n // ignore\n }\n })\n return iframe\n }\n if (this.modeValue === 'frame' && descriptor.videoUrl !== null && descriptor.frameUrl === null) {\n return this.buildVideoFrame(descriptor.videoUrl, descriptor.previewUrl)\n }\n // The host frame decode yields the native full-resolution texture (1080p/4K);\n // fall back to the preview image if the scene frame decode fails (422) (#521).\n return this.buildImage(descriptor.frameUrl ?? descriptor.previewUrl, descriptor.previewUrl)\n }\n return this.buildImage(descriptor.previewUrl)\n }\n\n /** Push the persisted sound/volume settings onto the mounted video. */\n private applySound(): void {\n if (this.videoElement === null) return\n this.videoElement.muted = !this.soundValue\n this.videoElement.volume = this.volumeValue / 100\n }\n\n private buildVideo(url: string, frameUrl: string | null = null, previewUrl: string | null = null): HTMLVideoElement {\n const video = this.doc.createElement('video')\n video.src = url\n video.muted = !this.soundValue\n video.volume = this.volumeValue / 100\n video.loop = true\n video.autoplay = true\n video.playsInline = true\n // Large local files may have the moov atom at the end: preload auto makes\n // Chromium fetch metadata eagerly instead of waiting for a gesture.\n video.preload = 'auto'\n video.setAttribute('aria-hidden', 'true')\n styleCover(video, this.fitValue)\n this.videoElement = video\n if (frameUrl !== null || previewUrl !== null) {\n video.addEventListener('error', () => {\n const nextUrl = frameUrl ?? previewUrl\n const nextFallback = frameUrl !== null ? previewUrl : null\n const img = this.buildImage(nextUrl, nextFallback)\n if (img && video.parentElement) {\n video.parentElement.replaceChild(img, video)\n } else {\n const currentId = this.previewing?.id ?? this.applied?.id\n if (currentId) {\n this.failedIds.add(currentId)\n this.render()\n this.publish()\n }\n }\n }, { once: true })\n } else {\n video.addEventListener('error', () => {\n const currentId = this.previewing?.id ?? this.applied?.id\n if (currentId) {\n this.failedIds.add(currentId)\n this.render()\n this.publish()\n }\n }, { once: true })\n }\n // jsdom (and older engines) return undefined, real browsers a promise.\n void video.play()?.catch(() => { /* autoplay policy: stays paused */ })\n return video\n }\n\n /** Static-frame mode for video: capture the first frame into an image. */\n private buildVideoFrame(url: string, previewUrl: string | null): HTMLElement {\n const image = this.doc.createElement('img')\n styleCover(image, this.fitValue)\n if (previewUrl !== null) image.src = previewUrl\n const video = this.doc.createElement('video')\n video.muted = true\n video.playsInline = true\n video.preload = 'auto'\n video.src = url\n // The capture video is owned by the controller: it is released on\n // error/abort, on a successful capture, and on teardown, so a decode\n // failure or an early mode switch cannot leave it buffering detached.\n this.releaseCaptureVideo()\n this.captureVideo = video\n const release = (): void => {\n video.removeAttribute('src')\n video.load()\n }\n video.addEventListener('error', release, { once: true })\n video.addEventListener('abort', release, { once: true })\n video.addEventListener('loadeddata', () => {\n try {\n const scale = Math.min(1, FRAME_MAX_EDGE / Math.max(video.videoWidth, video.videoHeight))\n const canvas = this.doc.createElement('canvas')\n canvas.width = Math.max(1, Math.round(video.videoWidth * scale))\n canvas.height = Math.max(1, Math.round(video.videoHeight * scale))\n const context = canvas.getContext('2d')\n if (context !== null) {\n context.drawImage(video, 0, 0, canvas.width, canvas.height)\n image.src = canvas.toDataURL('image/jpeg', 0.85)\n }\n } catch {\n // Capture failed (codec/format): the preview image stays.\n } finally {\n // Stop buffering whether the capture succeeded or not (a missing 2d\n // context or a decode failure must not leave the hidden video\n // streaming the file).\n release()\n }\n }, { once: true })\n return image\n }\n\n private releaseCaptureVideo(): void {\n if (this.captureVideo === null) return\n this.captureVideo.removeAttribute('src')\n this.captureVideo.load()\n this.captureVideo = null\n }\n\n private buildImage(url: string | null, fallbackUrl: string | null = null): HTMLElement | null {\n if (url === null) return null\n const image = this.doc.createElement('img')\n image.src = url\n image.alt = ''\n image.addEventListener('error', () => {\n if (fallbackUrl !== null && fallbackUrl !== url && image.src !== fallbackUrl) {\n image.src = fallbackUrl\n return\n }\n const currentId = this.previewing?.id ?? this.applied?.id\n if (currentId) {\n this.failedIds.add(currentId)\n this.render()\n this.publish()\n }\n })\n styleCover(image, this.fitValue)\n return image\n }\n\n /** Tag the official shell full-viewport background surfaces (AppFrame\n * frame, conversation root, details root) and the sidebar workspace-list\n * end fade with the own marker data-dsh-wallpaper-surface so the\n * neutralizer can target them without hashed class names (#734). Idempotent\n * across renders within one mount; untagged on teardown. */\n private markSurfaces(): void {\n const root = this.doc.getElementById('root')\n if (root !== null) {\n const custom = this.options.declareSurface\n // Upstream #712 detector is color-independent (any visible background +\n // min viewport coverage), so no per-sweep token resolution is needed.\n // Custom detectors keep their own (el, doc) signature.\n const isSurface = custom !== undefined\n ? (el: HTMLElement): boolean => custom(el, this.doc)\n : (el: HTMLElement): boolean => defaultWallpaperSurface(el, this.doc)\n const stack: Element[] = [root]\n while (stack.length > 0) {\n const node = stack.pop()\n if (node === undefined) continue\n if (node instanceof HTMLElement && !node.hasAttribute('data-dsh-wallpaper-surface') && isSurface(node)) {\n node.setAttribute('data-dsh-wallpaper-surface', '')\n this.taggedSurfaces.add(node)\n }\n for (const child of Array.from(node.children)) stack.push(child)\n }\n }\n this.markWorkspaceFades()\n }\n\n /** Tag the sidebar workspaces list-end fade with the same own marker (#734). */\n private markWorkspaceFades(): void {\n const slot = this.doc.querySelector('[data-slot=\"sidebar.workspaces\"]')\n if (slot === null) return\n const isFade = this.options.declareWorkspaceFade ?? defaultWorkspaceFade\n const stack: Element[] = [slot]\n while (stack.length > 0) {\n const node = stack.pop()\n if (node === undefined) continue\n if (node instanceof HTMLElement && !node.hasAttribute('data-dsh-wallpaper-surface') && isFade(node, this.doc)) {\n node.setAttribute('data-dsh-wallpaper-surface', '')\n this.taggedSurfaces.add(node)\n }\n for (const child of Array.from(node.children)) stack.push(child)\n }\n }\n\n /**\n * Watch document.body (subtree) while a wallpaper is active and re-tag only\n * the surfaces affected by each mutation. Navigation rebuilds #root by\n * replacing its children, so the added subtrees are scanned instead of the\n * whole tree; removed nodes are untagged immediately. This avoids repeated\n * full-tree scans and forced layout during chat streaming (#review).\n */\n private ensureSurfaceObserver(): void {\n if (this.disposed || this.surfaceObserver !== null) return\n const win = this.doc.defaultView\n if (win === null || typeof win.MutationObserver !== 'function') return\n this.surfaceObserver = new win.MutationObserver((records) => this.handleSurfaceMutations(records))\n this.surfaceObserver.observe(this.doc.body, { childList: true, subtree: true })\n }\n\n /** Incrementally tag added subtrees and untag removed subtrees. */\n private handleSurfaceMutations(records: MutationRecord[]): void {\n if (this.disposed || (this.previewing ?? this.applied) === null) return\n for (const record of records) {\n for (const node of record.addedNodes) {\n if (node instanceof HTMLElement) this.tagAddedSubtree(node)\n }\n for (const node of record.removedNodes) {\n if (node instanceof HTMLElement) this.untagRemovedSubtree(node)\n }\n }\n }\n\n /** Tag newly added elements that qualify as full-viewport surfaces or workspace fades. */\n private tagAddedSubtree(root: HTMLElement): void {\n const isSurface = this.options.declareSurface !== undefined\n ? (el: HTMLElement): boolean => this.options.declareSurface!(el, this.doc)\n : (el: HTMLElement): boolean => defaultWallpaperSurface(el, this.doc)\n const isFade = this.options.declareWorkspaceFade ?? defaultWorkspaceFade\n const stack: HTMLElement[] = [root]\n while (stack.length > 0) {\n const node = stack.pop()\n if (node === undefined) continue\n if (!node.hasAttribute('data-dsh-wallpaper-surface')) {\n const inWallpaperLayer = node.closest('[data-dsh-wallpaper-layer]') !== null\n const inWorkspaces = node.closest('[data-slot=\"sidebar.workspaces\"]') !== null\n if (!inWallpaperLayer && (isSurface(node) || (inWorkspaces && isFade(node, this.doc)))) {\n node.setAttribute('data-dsh-wallpaper-surface', '')\n this.taggedSurfaces.add(node)\n }\n }\n for (const child of Array.from(node.children)) {\n if (child instanceof HTMLElement) stack.push(child)\n }\n }\n }\n\n /** Remove tags from a removed subtree and drop its references. */\n private untagRemovedSubtree(root: HTMLElement): void {\n const stack: HTMLElement[] = [root]\n while (stack.length > 0) {\n const node = stack.pop()\n if (node === undefined) continue\n if (node.hasAttribute('data-dsh-wallpaper-surface')) {\n node.removeAttribute('data-dsh-wallpaper-surface')\n this.taggedSurfaces.delete(node)\n }\n for (const child of Array.from(node.children)) {\n if (child instanceof HTMLElement) stack.push(child)\n }\n }\n }\n\n private untagSurfaces(): void {\n for (const el of Array.from(this.taggedSurfaces)) el.removeAttribute('data-dsh-wallpaper-surface')\n this.taggedSurfaces.clear()\n }\n\n private teardownLayers(): void {\n this.releaseCaptureVideo()\n this.surfaceObserver?.disconnect()\n this.surfaceObserver = null\n this.untagSurfaces()\n delete this.doc.body.dataset.dshWallpaperActive\n delete this.doc.documentElement.dataset.dshWallpaperActive\n setSceneBackdropActive(this.doc, 'wallpaper', false)\n if (this.rootNeutralizer !== null) {\n this.rootNeutralizer.remove()\n this.rootNeutralizer = null\n }\n if (this.videoElement !== null) {\n this.videoElement.pause()\n this.videoElement = null\n }\n if (this.mediaLayer !== null) {\n this.mediaLayer.remove()\n this.mediaLayer = null\n }\n if (this.scrimLayer !== null) {\n this.scrimLayer.remove()\n this.scrimLayer = null\n }\n }\n\n private publish(): void {\n for (const listener of this.listeners) listener()\n }\n}\n\n/** Resolve a persisted selection id against an inventory list: exact id first, then the imported copy. */\nexport function resolveSelection(wallpapers: WallpaperDescriptor[], selection: string): WallpaperDescriptor | undefined {\n return wallpapers.find(w => w.id === selection)\n ?? wallpapers.find(w => w.id === 'imported/' + selection)\n}\n\n/**\n * Restore the persisted wallpaper selection at boot: resolve it against the\n * host inventory and mount it, without waiting for the skin-center panel to\n * open — the panel's mount effect is the only other sync() caller, so a page\n * load with a persisted selection otherwise renders nothing until the card\n * is opened. Best-effort and idempotent: the first non-empty selection wins;\n * the panel re-resolves on open if the inventory is still in flight or fails.\n */\nexport function installBootRestore(wallpaper: WallpaperHandle): void {\n let synced = false\n const restore = (): void => {\n if (synced) return\n const selected = wallpaper.selection()\n if (selected === '') return\n synced = true\n void (async () => {\n try {\n const response = await fetch('/api/skin-center/we/inventory')\n if (!response.ok) return\n const payload = await response.json().catch(() => null) as { ok?: boolean; wallpapers?: WallpaperDescriptor[] } | null\n if (payload?.ok !== true || !Array.isArray(payload.wallpapers)) return\n const match = resolveSelection(payload.wallpapers, selected)\n if (match !== undefined) wallpaper.sync(match)\n } catch {\n // Best-effort: the panel re-resolves on open.\n }\n })()\n }\n restore()\n wallpaper.subscribe(restore)\n}\n","/**\n * A drag-smooth range slider that decouples the visible value from the\n * external store while the user drags (issue #725).\n *\n * Binding <input type=\"range\"> directly to a useSyncExternalStore value\n * causes two defects during drag:\n * 1. Snapping back: the store subscription re-reads the scope snapshot while\n * the async scope.set() write is still in flight, resetting the thumb\n * to the old value mid-drag.\n * 2. Lag and stale labels: every onChange drives a full set -> publish ->\n * React render cycle, and the displayed number only updates once the\n * external store settles instead of following the thumb.\n *\n * This control keeps the input effectively uncontrolled: the browser moves\n * the thumb on the compositor thread with zero React involvement while\n * dragging, onInput reports the live value (one callback per animation\n * frame) so labels update in real time, and the final value is committed to\n * the external store through the native change event, which fires once per\n * completed pointer interaction (pointer release). Keyboard-only users get\n * an explicit commit path through onBlur and the Enter/Escape keydown\n * handlers, because not every engine fires the native change event for\n * range inputs on blur or Enter (jsdom does not; behavior varies by\n * browser). A pointer cancel aborts without committing, and the external\n * value is re-synced into the DOM only while the user is neither dragging\n * nor keyboard-focusing the input.\n * @module @linxin666/dsh-client-ui-skin-center/slider-control\n */\nimport { useCallback, useEffect, useRef, type ReactNode } from 'react'\n\n/** Props for the drag-smooth slider control. */\nexport interface SliderControlProps {\n /** External value from the store (initial value + sync target). */\n value: number\n min?: number\n max?: number\n step?: number\n /** Committed on drag end / keyboard change; callers persist to the store here. */\n onChange: (value: number) => void\n /** Live value during interaction, throttled to one callback per frame. */\n onChanging?: (value: number) => void\n className?: string\n id?: string\n ariaLabel?: string\n ariaValuetext?: string\n}\n\n/**\n * A range slider that stays smooth during drag (issue #725).\n *\n * @param props - slider props.\n * @returns the range input element.\n */\nexport function SliderControl({\n value: externalValue,\n min = 0,\n max = 100,\n step = 1,\n onChange,\n onChanging,\n className,\n id,\n ariaLabel,\n ariaValuetext,\n}: SliderControlProps): ReactNode {\n const inputRef = useRef<HTMLInputElement | null>(null)\n const draggingRef = useRef(false)\n const rafRef = useRef<number | null>(null)\n const liveRef = useRef(0)\n const lastCommittedRef = useRef<number | null>(null)\n const onChangingRef = useRef(onChanging)\n onChangingRef.current = onChanging\n\n // Commit through the NATIVE change event (React's onChange is synthesized\n // from 'input' for range inputs, which would commit on every move). The\n // native change event fires exactly once per completed pointer interaction.\n const commitRef = useRef(onChange)\n commitRef.current = onChange\n\n /**\n * Persist a value to the external store, de-duplicated against the last\n * committed value so the explicit keyboard/onBlur commit paths never\n * double-fire alongside the native change event (which real browsers also\n * emit on blur or Enter for range inputs).\n */\n const commit = useCallback((value: number): void => {\n if (lastCommittedRef.current === value) return\n lastCommittedRef.current = value\n commitRef.current(value)\n }, [])\n\n const commitCurrent = useCallback((): void => {\n const input = inputRef.current\n if (input === null) return\n draggingRef.current = false\n if (rafRef.current !== null) {\n cancelAnimationFrame(rafRef.current)\n rafRef.current = null\n }\n commit(Number(input.value))\n }, [commit])\n\n // Sync the external value into the DOM input, unless the user is dragging\n // or keyboard-focusing the input (the native change event already carries\n // the committed keyboard value; overwriting here would snap the thumb).\n useEffect(() => {\n const input = inputRef.current\n if (input !== null && !draggingRef.current && input !== input.ownerDocument.activeElement) {\n input.value = String(externalValue)\n }\n }, [externalValue])\n\n useEffect(() => {\n const input = inputRef.current\n if (input === null) return\n const listener = (): void => {\n draggingRef.current = false\n if (rafRef.current !== null) {\n cancelAnimationFrame(rafRef.current)\n rafRef.current = null\n }\n commit(Number(input.value))\n }\n input.addEventListener('change', listener)\n return (): void => {\n input.removeEventListener('change', listener)\n }\n }, [commit])\n\n // Release the pending frame on unmount.\n useEffect(() => {\n return (): void => {\n if (rafRef.current !== null) cancelAnimationFrame(rafRef.current)\n }\n }, [])\n\n /** Throttled live-value reporter: fires onChanging at most once per frame. */\n const reportLive = useCallback((value: number): void => {\n liveRef.current = value\n if (rafRef.current !== null) return\n rafRef.current = requestAnimationFrame(() => {\n rafRef.current = null\n onChangingRef.current?.(liveRef.current)\n })\n }, [])\n\n const startDrag = useCallback(() => {\n draggingRef.current = true\n }, [])\n\n /** Abort the interaction (pointer cancel): no value is committed. */\n const cancelDrag = useCallback(() => {\n draggingRef.current = false\n if (rafRef.current !== null) {\n cancelAnimationFrame(rafRef.current)\n rafRef.current = null\n }\n }, [])\n\n const onInput = useCallback((event: React.FormEvent<HTMLInputElement>) => {\n reportLive(Number(event.currentTarget.value))\n }, [reportLive])\n\n // Commit on blur so keyboard-only users persist the value even when the\n // engine never fires the native change event for range inputs on blur.\n const commitOnBlur = useCallback((): void => {\n if (draggingRef.current) return\n commitCurrent()\n }, [commitCurrent])\n\n // Enter/Escape are the explicit keyboard commit keys for range inputs.\n const onKeyDown = useCallback((event: React.KeyboardEvent<HTMLInputElement>): void => {\n if (event.key !== 'Enter' && event.key !== 'Escape') return\n if (draggingRef.current) return\n commitCurrent()\n }, [commitCurrent])\n\n return (\n <input\n ref={inputRef}\n id={id}\n className={className}\n type=\"range\"\n min={min}\n max={max}\n step={step}\n defaultValue={externalValue}\n aria-label={ariaLabel}\n aria-valuetext={ariaValuetext}\n onPointerDown={startDrag}\n onPointerCancel={cancelDrag}\n onInput={onInput}\n onBlur={commitOnBlur}\n onKeyDown={onKeyDown}\n />\n )\n}","/**\n * The wallpaper panel of the skin-center card: lists the user's local\n * Wallpaper Engine library (video / web / scene wallpapers) with live\n * try-on, one-click apply, local import, and render tuning. Rendering and\n * persistence ride the WallpaperController (wallpaper.ts); the library,\n * media, import and scene-frame bytes come from the host's /we routes.\n *\n * Compliance: wallpapers are the user's own local files (their Workshop\n * subscriptions or manual folders). The panel never downloads or shares\n * content; import only copies files within the user's machine.\n */\nimport { useCallback, useEffect, useRef, useState, useSyncExternalStore, type ReactNode } from 'react'\nimport type { PropsLocale } from '@deepseek-ai/dsh-client-ui-slots'\nimport { resolveSelection, type WallpaperDescriptor, type WallpaperHandle } from './wallpaper.ts'\nimport css from './skin-center.module.css'\nimport { SliderControl } from './SliderControl.tsx'\n\n/** Live-label helper: the shown value follows the in-drag thumb immediately,\n * and falls back to the store value once the store settles (issue #725). */\nfunction useLiveValue(value: number): [number, (v: number | null) => void] {\n const [live, setLive] = useState<number | null>(null)\n useEffect(() => {\n setLive(null)\n }, [value])\n return [live ?? value, setLive]\n}\n\n/** Host base path of the wallpaper API (mirrors src/we-routes.ts). */\nconst WE_API = '/api/skin-center/we'\n\n/** One wallpaper entry as served by the inventory route. */\ninterface WallpaperItem extends WallpaperDescriptor {\n source: 'workshop' | 'local' | 'imported' | 'system'\n playable: boolean\n updateAvailable: boolean\n rating?: 'g' | 'pg13' | 'r18'\n}\n\n/** Inventory payload shape. */\ninterface InventoryPayload {\n ok?: boolean\n installDir?: string | null\n total?: number\n portableCount?: number\n /** macOS-managed wallpapers (aerials + Desktop Pictures) in the list. */\n systemCount?: number\n wallpapers?: WallpaperItem[]\n error?: string\n}\n\n/** Post one wallpaper action and return whether it succeeded. */\nasync function postWe(path: string, id: string): Promise<string | null> {\n try {\n const response = await fetch(WE_API + path, {\n method: 'POST',\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify({ id }),\n })\n const payload = await response.json().catch(() => null) as { ok?: boolean; error?: string } | null\n if (!response.ok || payload?.ok !== true) return payload?.error ?? 'HTTP ' + String(response.status)\n return null\n } catch (error) {\n return error instanceof Error ? error.message : String(error)\n }\n}\n\n/** The type badge copy key of one wallpaper. */\nfunction typeKey(item: WallpaperItem): 'wallpaperTypeVideo' | 'wallpaperTypeWeb' | 'wallpaperTypeScene' | 'wallpaperTypeApp' | 'wallpaperTypeImage' {\n switch (item.type) {\n case 'video': return 'wallpaperTypeVideo'\n case 'web': return 'wallpaperTypeWeb'\n case 'scene': return 'wallpaperTypeScene'\n case 'image': return 'wallpaperTypeImage'\n default: return 'wallpaperTypeApp'\n }\n}\n\n/** Wallpaper grid page size (24 items per page). */\nconst PAGE_SIZE = 24\n\n/** Generate pagination page numbers with ellipses. */\nfunction paginationRange(current: number, total: number): (number | 'ellipsis')[] {\n if (total <= 7) {\n return Array.from({ length: total }, (_, i) => i + 1)\n }\n const pages: (number | 'ellipsis')[] = [1]\n let start = Math.max(2, current - 1)\n let end = Math.min(total - 1, current + 1)\n\n if (current <= 3) {\n start = 2\n end = 4\n } else if (current >= total - 2) {\n start = total - 3\n end = total - 1\n }\n\n if (start > 2) pages.push('ellipsis')\n for (let i = start; i <= end; i++) pages.push(i)\n if (end < total - 1) pages.push('ellipsis')\n pages.push(total)\n return pages\n}\n\n/** Render the Wallpaper Engine section of the skin-center card. */\nexport function WallpaperPanel({ t, wallpaper }: { t: PropsLocale<'skinCenter'>['t']; wallpaper: WallpaperHandle }): ReactNode {\n const enabled = useSyncExternalStore(wallpaper.subscribe, wallpaper.enabled)\n const selection = useSyncExternalStore(wallpaper.subscribe, wallpaper.selection)\n const mode = useSyncExternalStore(wallpaper.subscribe, wallpaper.mode)\n const fit = useSyncExternalStore(wallpaper.subscribe, wallpaper.fit)\n const dim = useSyncExternalStore(wallpaper.subscribe, wallpaper.dim)\n const blur = useSyncExternalStore(wallpaper.subscribe, wallpaper.wallpaperBlur)\n const opacity = useSyncExternalStore(wallpaper.subscribe, wallpaper.wallpaperOpacity)\n const pauseOnHidden = useSyncExternalStore(wallpaper.subscribe, wallpaper.pauseOnHidden)\n const sound = useSyncExternalStore(wallpaper.subscribe, wallpaper.sound)\n const volume = useSyncExternalStore(wallpaper.subscribe, wallpaper.volume)\n const activeId = useSyncExternalStore(wallpaper.subscribe, wallpaper.activeId)\n const trying = useSyncExternalStore(wallpaper.subscribe, wallpaper.trying)\n const dirs = useSyncExternalStore(wallpaper.subscribe, wallpaper.dirs)\n const [shownDim, setShownDim] = useLiveValue(dim)\n const [shownBlur, setShownBlur] = useLiveValue(blur)\n const [shownOpacity, setShownOpacity] = useLiveValue(opacity)\n const [shownVolume, setShownVolume] = useLiveValue(volume)\n const [dirInput, setDirInput] = useState('')\n const [picking, setPicking] = useState(false)\n const [page, setPage] = useState(1)\n const [ratingFilter, setRatingFilter] = useState<'g' | 'pg13' | 'r18'>('g')\n const [jumpInput, setJumpInput] = useState('')\n\n const [items, setItems] = useState<WallpaperItem[] | null>(null)\n const [installDir, setInstallDir] = useState<string | null>(null)\n const [systemCount, setSystemCount] = useState(0)\n const [loadError, setLoadError] = useState<string | null>(null)\n const [actionError, setActionError] = useState<string | null>(null)\n const [workingId, setWorkingId] = useState<string | null>(null)\n const mounted = useRef(false)\n useEffect(() => {\n mounted.current = true\n return () => { mounted.current = false }\n }, [])\n\n /** Fetch the inventory and reconcile the mounted layer with the selection. */\n const load = useCallback((): void => {\n void fetch(WE_API + '/inventory')\n .then(async response => {\n const payload = await response.json().catch(() => null) as InventoryPayload | null\n if (!mounted.current) return\n if (!response.ok || payload?.ok !== true || !Array.isArray(payload.wallpapers)) {\n setLoadError(payload?.error ?? 'HTTP ' + String(response.status))\n setItems([])\n return\n }\n setLoadError(null)\n setItems(payload.wallpapers)\n // A fresh inventory restarts the paged grid from the first page.\n setPage(1)\n setInstallDir(typeof payload.installDir === 'string' ? payload.installDir : null)\n setSystemCount(typeof payload.systemCount === 'number' ? payload.systemCount : 0)\n const selected = wallpaper.selection()\n wallpaper.sync(resolveSelection(payload.wallpapers, selected) ?? null)\n })\n .catch((error: unknown) => {\n if (!mounted.current) return\n setLoadError(error instanceof Error ? error.message : String(error))\n setItems([])\n })\n }, [wallpaper])\n\n useEffect(load, [load])\n\n /** Run one import/remove action with the shared busy + error state. */\n const runAction = (id: string, path: string, after?: () => void): void => {\n setActionError(null)\n setWorkingId(id)\n void postWe(path, id).then(error => {\n if (!mounted.current) return\n setWorkingId(null)\n if (error !== null) {\n setActionError(error)\n return\n }\n after?.()\n load()\n })\n }\n\n /** Open the host's native folder picker and add the chosen directory. */\n const browseDir = (): void => {\n const pick = wallpaper.pickDir\n if (pick === undefined) return\n setActionError(null)\n setPicking(true)\n void pick()\n .then(path => {\n if (!mounted.current) return\n setPicking(false)\n if (path === null || path.trim() === '') return // cancelled\n wallpaper.addDir(path)\n load()\n })\n .catch((error: unknown) => {\n // Non-loopback (paired remote) or a host without the native\n // capability: the manual input stays the fallback.\n if (!mounted.current) return\n setPicking(false)\n setActionError(t('wallpaperDirBrowseFailed') + ': ' + (error instanceof Error ? error.message : String(error)))\n })\n }\n\n const descriptorOf = (item: WallpaperItem): WallpaperDescriptor => ({\n id: item.id,\n title: item.title,\n type: item.type,\n videoUrl: item.videoUrl,\n webUrl: item.webUrl,\n frameUrl: item.frameUrl,\n sceneUrl: item.sceneUrl,\n previewUrl: item.previewUrl,\n })\n\n /** Whether one entry can be mounted at all in the current mode. */\n const renderable = (item: WallpaperItem): boolean =>\n item.playable || item.frameUrl !== null || item.previewUrl !== null\n\n const filteredItems = (items ?? []).filter(item => (item.rating ?? 'g') === ratingFilter)\n const totalPages = Math.max(1, Math.ceil(filteredItems.length / PAGE_SIZE))\n const currentPage = Math.min(Math.max(1, page), totalPages)\n const pagedItems = filteredItems.slice((currentPage - 1) * PAGE_SIZE, currentPage * PAGE_SIZE)\n\n const handleJump = (): void => {\n const target = parseInt(jumpInput.trim(), 10)\n if (!isNaN(target) && target >= 1 && target <= totalPages) {\n setPage(target)\n setJumpInput('')\n }\n }\n\n const onSelectRatingFilter = (filter: 'g' | 'pg13' | 'r18'): void => {\n setRatingFilter(filter)\n setPage(1)\n setJumpInput('')\n }\n\n const activeSelection = selection\n\n return (\n <div className={css.wallpaperSection}>\n <div className={css.enableRow}>\n <span className={css.enableLabel} title={t('wallpaperEnable')}>{t('wallpaperTitle')}</span>\n <button\n type=\"button\"\n role=\"switch\"\n aria-checked={enabled}\n aria-label={t('wallpaperEnable')}\n className={enabled ? css.switch + ' ' + css.switchOn : css.switch}\n onClick={() => { wallpaper.setEnabled(!enabled) }}\n >\n <span className={css.switchThumb} />\n </button>\n <p className={css.enableHint}>{t('wallpaperHint')}</p>\n </div>\n {enabled && (\n <>\n <div className={css.wallpaperStatus}>\n {loadError !== null\n ? <span className={css.wallpaperStatusError}>{t('wallpaperLoadError')}: {loadError}</span>\n : items === null\n ? <span>{t('loading')}</span>\n : installDir !== null\n ? <span>{t('wallpaperLibraryFound')} · {items.length}</span>\n : systemCount > 0\n ? <span>{t('wallpaperLibrarySystem')} · {items.length}</span>\n : <span>{t('wallpaperLibraryManual')} · {items.length}</span>}\n <button type=\"button\" className={css.button} onClick={load}>{t('wallpaperRefresh')}</button>\n </div>\n\n {activeSelection !== '' && (\n <div className={css.wallpaperControls}>\n <div className={css.themeRow}>\n <span className={css.themeLabel}>{t('wallpaperMode')}</span>\n <button\n type=\"button\"\n className={css.themeButton + (mode === 'live' ? ' ' + css.themeButtonActive : '')}\n onClick={() => { wallpaper.setMode('live') }}\n >\n {t('wallpaperModeLive')}\n </button>\n <button\n type=\"button\"\n className={css.themeButton + (mode === 'frame' ? ' ' + css.themeButtonActive : '')}\n onClick={() => { wallpaper.setMode('frame') }}\n >\n {t('wallpaperModeFrame')}\n </button>\n <button\n type=\"button\"\n className={css.button + ' ' + css.buttonGhost}\n onClick={() => { wallpaper.clearSelection() }}\n >\n {t('wallpaperClear')}\n </button>\n </div>\n <div className={css.themeRow}>\n <span className={css.themeLabel}>{t('wallpaperFit')}</span>\n <button\n type=\"button\"\n className={css.themeButton + (fit === 'cover' ? ' ' + css.themeButtonActive : '')}\n onClick={() => { wallpaper.setFit('cover') }}\n >\n {t('wallpaperFitCover')}\n </button>\n <button\n type=\"button\"\n className={css.themeButton + (fit === 'contain' ? ' ' + css.themeButtonActive : '')}\n onClick={() => { wallpaper.setFit('contain') }}\n >\n {t('wallpaperFitContain')}\n </button>\n <button\n type=\"button\"\n className={css.themeButton + (fit === 'fill' ? ' ' + css.themeButtonActive : '')}\n onClick={() => { wallpaper.setFit('fill') }}\n >\n {t('wallpaperFitFill')}\n </button>\n </div>\n <div className={css.backgroundRow}>\n <div className={css.backgroundHead}>\n <span className={css.backgroundLabel}>{t('wallpaperDim')}</span>\n <span className={css.backgroundValue} aria-hidden=\"true\">{shownDim}%</span>\n </div>\n <SliderControl\n className={css.backgroundRange}\n min={0}\n max={90}\n step={5}\n value={dim}\n ariaValuetext={shownDim + '%'}\n ariaLabel={t('wallpaperDim')}\n onChanging={setShownDim}\n onChange={(value) => { wallpaper.setDim(value) }}\n />\n <div className={css.backgroundHead}>\n <span className={css.backgroundLabel}>{t('wallpaperOpacity')}</span>\n <span className={css.backgroundValue} aria-hidden=\"true\">{shownOpacity}%</span>\n </div>\n <SliderControl\n className={css.backgroundRange}\n min={0}\n max={100}\n step={5}\n value={opacity}\n ariaValuetext={shownOpacity + '%'}\n ariaLabel={t('wallpaperOpacity')}\n onChanging={setShownOpacity}\n onChange={(value) => { wallpaper.setOpacity(value) }}\n />\n <div className={css.backgroundHead}>\n <span className={css.backgroundLabel}>{t('wallpaperBlur')}</span>\n <span className={css.backgroundValue} aria-hidden=\"true\">{shownBlur}px</span>\n </div>\n <SliderControl\n className={css.backgroundRange}\n min={0}\n max={60}\n step={1}\n value={blur}\n ariaValuetext={shownBlur + 'px'}\n ariaLabel={t('wallpaperBlur')}\n onChanging={setShownBlur}\n onChange={(value) => { wallpaper.setBlur(value) }}\n />\n </div>\n <div className={css.enableRow}>\n <span className={css.enableLabel}>{t('wallpaperPauseHidden')}</span>\n <button\n type=\"button\"\n role=\"switch\"\n aria-checked={pauseOnHidden}\n aria-label={t('wallpaperPauseHidden')}\n className={pauseOnHidden ? css.switch + ' ' + css.switchOn : css.switch}\n onClick={() => { wallpaper.setPauseOnHidden(!pauseOnHidden) }}\n >\n <span className={css.switchThumb} />\n </button>\n </div>\n <div className={css.enableRow}>\n <span className={css.enableLabel} title={t('wallpaperSoundHint')}>{t('wallpaperSound')}</span>\n <button\n type=\"button\"\n role=\"switch\"\n aria-checked={sound}\n aria-label={t('wallpaperSound')}\n className={sound ? css.switch + ' ' + css.switchOn : css.switch}\n onClick={() => { wallpaper.setSound(!sound) }}\n >\n <span className={css.switchThumb} />\n </button>\n </div>\n {sound && (\n <div className={css.backgroundRow}>\n <div className={css.backgroundHead}>\n <span className={css.backgroundLabel}>{t('wallpaperVolume')}</span>\n <span className={css.backgroundValue} aria-hidden=\"true\">{shownVolume}%</span>\n </div>\n <SliderControl\n className={css.backgroundRange}\n min={0}\n max={100}\n step={5}\n value={volume}\n ariaValuetext={shownVolume + '%'}\n ariaLabel={t('wallpaperVolume')}\n onChanging={setShownVolume}\n onChange={(value) => { wallpaper.setVolume(value) }}\n />\n </div>\n )}\n </div>\n )}\n\n <div className={css.wallpaperDirs}>\n <span className={css.themeLabel}>{t('wallpaperDirs')}</span>\n {dirs.length === 0 && <span className={css.backgroundHintMuted}>{t('wallpaperDirsEmpty')}</span>}\n {dirs.map(dir => (\n <span className={css.wallpaperDir} key={dir}>\n <span className={css.wallpaperDirPath} title={dir}>{dir}</span>\n <button\n type=\"button\"\n className={css.wallpaperDirRemove}\n aria-label={t('wallpaperRemove')}\n onClick={() => { wallpaper.removeDir(dir); load() }}\n >\n ×\n </button>\n </span>\n ))}\n <span className={css.wallpaperDirAdd}>\n <input\n className={css.wallpaperDirInput}\n type=\"text\"\n value={dirInput}\n placeholder={t('wallpaperDirPlaceholder')}\n onChange={(event) => { setDirInput(event.target.value) }}\n onKeyDown={(event) => {\n if (event.key === 'Enter' && dirInput.trim() !== '') {\n wallpaper.addDir(dirInput)\n setDirInput('')\n load()\n }\n }}\n />\n <button\n type=\"button\"\n className={css.button}\n disabled={dirInput.trim() === ''}\n onClick={() => { wallpaper.addDir(dirInput); setDirInput(''); load() }}\n >\n {t('wallpaperDirAdd')}\n </button>\n {wallpaper.pickDir !== undefined && (\n <button\n type=\"button\"\n className={css.button}\n disabled={picking}\n title={t('wallpaperDirBrowseHint')}\n onClick={browseDir}\n >\n {picking ? t('loading') : t('wallpaperDirBrowse')}\n </button>\n )}\n </span>\n <p className={css.backgroundHintMuted}>{t('wallpaperDirsHint')}</p>\n </div>\n\n {actionError !== null && <div className={css.error}>{actionError}</div>}\n\n {items !== null && items.length > 0 && (\n <div className={css.wallpaperToolbar}>\n <div className={css.ratingFilterGroup} role=\"tablist\" aria-label={t('wallpaperTitle')}>\n {(['g', 'pg13', 'r18'] as const).map(filter => {\n const active = ratingFilter === filter\n const key = filter === 'g'\n ? 'wallpaperRatingG'\n : filter === 'pg13'\n ? 'wallpaperRatingPg13'\n : 'wallpaperRatingR18'\n return (\n <button\n type=\"button\"\n key={filter}\n role=\"tab\"\n aria-selected={active}\n className={css.ratingFilterButton + (active ? ' ' + css.ratingFilterActive : '')}\n onClick={() => { onSelectRatingFilter(filter) }}\n >\n {t(key)}\n </button>\n )\n })}\n </div>\n <div className={css.pageTotalInfo}>\n {t('wallpaperPageTotal', { page: String(currentPage), total: String(totalPages) })}\n </div>\n </div>\n )}\n\n {items !== null && pagedItems.length > 0 && (\n <div className={css.wallpaperGrid}>\n {pagedItems.map(item => {\n const isApplied = item.id === activeSelection\n const isMounted = item.id === activeId\n const busy = workingId === item.id\n return (\n <div className={css.wallpaperCard} key={item.id}>\n <div className={css.wallpaperThumbWrap}>\n {item.previewUrl !== null\n ? <img className={css.wallpaperThumb} src={item.previewUrl} alt=\"\" loading=\"lazy\" />\n : item.videoUrl !== null\n // No preview image (bare .mp4 without project.json):\n // the video element's first frame is the cover.\n ? <video className={css.wallpaperThumb} src={item.videoUrl} preload=\"metadata\" muted playsInline aria-hidden=\"true\" />\n : <div className={css.wallpaperThumbEmpty} aria-hidden=\"true\" />}\n <span className={css.wallpaperType}>{t(typeKey(item))}</span>\n {item.rating === 'r18' ? (\n <span className={css.wallpaperRating + ' ' + css.ratingR18}>R18</span>\n ) : item.rating === 'pg13' ? (\n <span className={css.wallpaperRating + ' ' + css.ratingPg13}>PG-13</span>\n ) : (\n <span className={css.wallpaperRating + ' ' + css.ratingG}>G</span>\n )}\n {isMounted && (\n <span className={css.badge + ' ' + (trying ? css.badgeTrying : css.badgeActive)}>\n {trying ? t('tryingOn') : t('active')}\n </span>\n )}\n </div>\n <div className={css.wallpaperName} title={item.title}>{item.title}</div>\n <div className={css.wallpaperActions}>\n {isMounted && trying ? (\n <button type=\"button\" className={css.button + ' ' + css.buttonPrimary} onClick={() => { wallpaper.exitTryOn() }}>\n {t('exitTryOn')}\n </button>\n ) : (\n <button\n type=\"button\"\n className={css.button + ' ' + css.buttonPrimary}\n disabled={!renderable(item) || (isMounted && isApplied) || busy}\n onClick={() => { wallpaper.tryOn(descriptorOf(item)) }}\n >\n {t('tryOn')}\n </button>\n )}\n <button\n type=\"button\"\n className={css.button}\n disabled={!renderable(item) || isApplied || busy}\n onClick={() => { wallpaper.applySelection(descriptorOf(item)) }}\n >\n {isApplied ? t('active') : t('apply')}\n </button>\n {item.source === 'imported' ? (\n <>\n {item.updateAvailable && (\n <button\n type=\"button\"\n className={css.button}\n disabled={busy}\n title={t('wallpaperUpdateAvailable')}\n onClick={() => { runAction(item.id, '/reimport') }}\n >\n {busy ? t('loading') : t('wallpaperReimport')}\n </button>\n )}\n <button\n type=\"button\"\n className={css.button + ' ' + css.buttonGhost}\n disabled={busy}\n onClick={() => {\n runAction(item.id, '/remove', () => {\n if (wallpaper.selection() === item.id) wallpaper.clearSelection()\n })\n }}\n >\n {t('wallpaperRemove')}\n </button>\n </>\n ) : item.source === 'system' ? (\n // macOS-managed wallpapers are already local and\n // their folder is shared — nothing to import.\n <></>\n ) : (\n <button\n type=\"button\"\n className={css.button}\n disabled={busy}\n title={t('wallpaperImportHint')}\n onClick={() => { runAction(item.id, '/import') }}\n >\n {busy ? t('loading') : t('wallpaperImport')}\n </button>\n )}\n </div>\n </div>\n )\n })}\n </div>\n )}\n {totalPages > 1 && (\n <div className={css.wallpaperPagination} role=\"navigation\" aria-label={t('wallpaperTitle')}>\n <button\n type=\"button\"\n className={css.pageButton}\n disabled={currentPage <= 1}\n onClick={() => { setPage(p => Math.max(1, p - 1)) }}\n aria-label={t('wallpaperPagePrev')}\n >\n {t('wallpaperPagePrev')}\n </button>\n {paginationRange(currentPage, totalPages).map((p, idx) => {\n if (p === 'ellipsis') {\n return <span key={'ellipsis-' + String(idx)} className={css.pageEllipsis}>…</span>\n }\n const isActive = p === currentPage\n return (\n <button\n type=\"button\"\n key={p}\n className={css.pageButton + (isActive ? ' ' + css.pageButtonActive : '')}\n aria-current={isActive ? 'page' : undefined}\n onClick={() => { setPage(p) }}\n >\n {p}\n </button>\n )\n })}\n <button\n type=\"button\"\n className={css.pageButton}\n disabled={currentPage >= totalPages}\n onClick={() => { setPage(p => Math.min(totalPages, p + 1)) }}\n aria-label={t('wallpaperPageNext')}\n >\n {t('wallpaperPageNext')}\n </button>\n <form\n className={css.pageJumpForm}\n onSubmit={(e) => {\n e.preventDefault()\n handleJump()\n }}\n >\n <input\n type=\"text\"\n className={css.pageJumpInput}\n value={jumpInput}\n aria-label={t('wallpaperPageJump')}\n onChange={(e) => { setJumpInput(e.target.value) }}\n />\n <button type=\"submit\" className={css.pageButton} disabled={jumpInput.trim() === ''}>\n {t('wallpaperPageJump')}\n </button>\n </form>\n </div>\n )}\n {items !== null && (items.length === 0 || pagedItems.length === 0) && loadError === null && (\n <p className={css.backgroundHintMuted}>{t('wallpaperEmpty')}</p>\n )}\n </>\n )}\n </div>\n )\n}","/**\n * The skin-center card: rendered as the content of a first-level settings\n * section, listing the official stock look plus every installed skin in the\n * v2 catalog (package-shipped built-ins + user dirs under $DSH_HOME/skins).\n *\n * v2 architecture (issue #506): skins are pure asset directories loaded by\n * the skin-center runtime. Try-on and apply both go through the same atomic\n * switch engine (src/client/runtime/skin-controller.ts) — try-on simply\n * skips persistence, and apply is one click with NO page reload, no\n * cordis.patch.yml rewrite, no boot-graph regeneration. The \"trying on\"\n * badge tracks the controller's live state, so closing and reopening the\n * settings panel keeps showing the skin that is still being previewed.\n * Copy rides the standard `t` seat; the theme preview control drives the\n * official theme service (persisted, same as the Appearance row).\n */\nimport { useEffect, useRef, useState, useSyncExternalStore, type ReactNode } from 'react'\nimport type { PropsLocale, PropsRuntime } from '@deepseek-ai/dsh-client-ui-slots'\nimport type { ThemeSnapshot } from '@deepseek-ai/dsh-client-ui-theme/client'\nimport type { CatalogSkin, SkinRuntimeStore } from './runtime/boot.ts'\nimport type { SkinBackgroundHandle } from './background.ts'\nimport type { WallpaperHandle } from './wallpaper.ts'\nimport type { PreviewCoordinator } from './preview-coordinator.ts'\nimport type { CustomThemeController } from './custom-theme-controller.ts'\nimport { CustomThemeCard } from './CustomThemePanel.tsx'\nimport { WallpaperPanel } from './WallpaperPanel.tsx'\nimport { SliderControl } from './SliderControl.tsx'\nimport css from './skin-center.module.css'\n\n/** Business face the skin-center apply() injects into the card. */\nexport interface SkinCenterInjected {\n /** The v2 skin runtime store (controller + catalog). */\n runtime: SkinRuntimeStore\n theme: {\n getTheme(): ThemeSnapshot\n subscribe(listener: () => void): () => void\n setTheme(id: 'light' | 'dark'): void\n }\n /** Background occluder over the shared skin-background namespace. */\n background: SkinBackgroundHandle\n /** Wallpaper Engine bridge over the skin-wallpaper namespace. */\n wallpaper: WallpaperHandle\n /** One serialized preview session shared by skins and wallpapers. */\n preview: PreviewCoordinator\n /** User palette derived from the official stock theme. */\n customTheme: CustomThemeController\n}\n\n/** Plugin-card component props: locale seat + injected face. */\nexport type SkinCenterComponentProps =\n PropsLocale<'skinCenter'> & SkinCenterInjected\n\n/** The apply target of the official stock-look card. */\nconst OFFICIAL = 'official'\n\n/**\n * Live-label helper: the shown value follows the in-drag thumb immediately,\n * and falls back to the store value once the store settles (issue #725).\n */\nfunction useLiveValue(value: number): [number, (v: number | null) => void] {\n const [live, setLive] = useState<number | null>(null)\n useEffect(() => {\n setLive(null)\n }, [value])\n return [live ?? value, setLive]\n}\n\n/**\n * Render the skin-center card: a static header naming the plugin, with the\n * always-visible skin list (official default + every installed skin; try-on /\n * theme preview / one-click apply) rendered below it.\n * @param props - card props.\n * @returns the plugin card.\n */\nexport function SkinCenter({ t, runtime, theme, background, wallpaper, preview, customTheme }: SkinCenterComponentProps) {\n const snapshot = useSyncExternalStore((listener) => theme.subscribe(listener), () => theme.getTheme())\n const enabled = useSyncExternalStore(background.subscribe, background.enabled)\n const opacity = useSyncExternalStore(background.subscribe, background.opacity)\n const blurEmpty = useSyncExternalStore(background.subscribe, background.blurEmpty)\n const blurContent = useSyncExternalStore(background.subscribe, background.blurContent)\n const inputCardBlur = useSyncExternalStore(background.subscribe, background.inputCardBlur)\n const bubbleOpacity = useSyncExternalStore(background.subscribe, background.bubbleOpacity)\n const [shownOpacity, setShownOpacity] = useLiveValue(opacity)\n const [shownBlurEmpty, setShownBlurEmpty] = useLiveValue(blurEmpty)\n const [shownBlurContent, setShownBlurContent] = useLiveValue(blurContent)\n const [shownInputCardBlur, setShownInputCardBlur] = useLiveValue(inputCardBlur)\n const [shownBubbleOpacity, setShownBubbleOpacity] = useLiveValue(bubbleOpacity)\n const catalog = useSyncExternalStore(runtime.subscribe, runtime.catalog)\n const state = useSyncExternalStore(runtime.subscribe, runtime.controller.getState)\n const customThemeState = useSyncExternalStore(customTheme.subscribe, customTheme.getState)\n const activeId = state.active\n const previewing = state.previewing\n const tryingId = state.trying\n const activeEntry = activeId === null ? null : runtime.find(activeId)\n const backdropActive = activeEntry?.manifest.contributes.backgroundMedia !== undefined\n const [busyId, setBusyId] = useState<string | null>(null)\n const [error, setError] = useState<string | null>(null)\n const [verifying, setVerifying] = useState(false)\n const [verifySummary, setVerifySummary] = useState<{\n total: number\n valid: number\n issues: number\n repaired?: string[]\n repairFailed?: Array<{ id: string; error: string }>\n } | null>(null)\n const [verifyReports, setVerifyReports] = useState<Record<string, { status: string; hooksTrusted: boolean; mismatches: string[]; missing: string[] }>>({})\n const [confirmUninstallId, setConfirmUninstallId] = useState<string | null>(null)\n const [uninstallingId, setUninstallingId] = useState<string | null>(null)\n // Unmount guard: once the card is gone, pending async completions must not\n // setState (the controller itself owns the skin state and lives on).\n const mounted = useRef(false)\n // Latest-click-wins token; a newer click invalidates older completions.\n const requestSeq = useRef(0)\n useEffect(() => {\n mounted.current = true\n return () => { mounted.current = false }\n }, [])\n\n const run = (target: string, action: () => Promise<string | null>): void => {\n const seq = ++requestSeq.current\n setError(null)\n setBusyId(target)\n void action()\n .catch(() => {\n if (!mounted.current || seq !== requestSeq.current) return\n setError(t('applyFailed'))\n })\n .finally(() => {\n if (!mounted.current || seq !== requestSeq.current) return\n setBusyId(null)\n })\n }\n\n const tryOn = (entry: CatalogSkin): void => {\n run(entry.manifest.id, () => preview.runSkin(() => runtime.controller.tryOn(entry.manifest.id, entry)))\n }\n\n const tryOnOfficial = (): void => {\n run(OFFICIAL, () => preview.runSkin(() => runtime.controller.tryOn(null, null)))\n }\n\n const exitTryOn = (): void => {\n run(tryingId ?? OFFICIAL, () => preview.runSkin(() => runtime.controller.exitTryOn()))\n }\n\n const restoreCommittedSkin = async (state: { active: string | null }): Promise<void> => {\n const entry = state.active === null ? null : runtime.find(state.active)\n if (state.active !== null && entry === null) {\n throw new Error(`cannot restore skin ${state.active}`)\n }\n const restored = await runtime.controller.switchTo(state.active, entry)\n if (restored !== state.active) {\n throw new Error(`skin ${state.active ?? 'stock'} did not restore`)\n }\n }\n\n const switchAndDeactivateCustomTheme = async (\n target: string | null,\n entry: CatalogSkin | null,\n ): Promise<string | null> => {\n const previous = { ...runtime.controller.getState() }\n const active = await runtime.controller.switchTo(target, entry)\n if (active !== target) {\n throw new Error(`${target === null ? 'stock theme' : `skin ${target}`} did not activate`)\n }\n try {\n await customTheme.deactivate()\n return active\n } catch (error) {\n try {\n await restoreCommittedSkin(previous)\n } catch (rollbackError) {\n throw new AggregateError([error, rollbackError], 'skin switch cleanup and rollback failed')\n }\n throw error\n }\n }\n\n const restoreOfficialLook = async (): Promise<string | null> => {\n const active = await switchAndDeactivateCustomTheme(null, null)\n if (wallpaper.selection() !== '') wallpaper.clearSelection()\n return active\n }\n\n /**\n * One-click apply: atomic client-side switch + persisted selection. No\n * reload, no boot-graph wait — the tapIndex adapter makes the next page\n * load boot straight into this skin.\n * @param target - skin id, or `official` for the stock look.\n */\n const applySkin = (target: string): void => {\n if (target === OFFICIAL) {\n run(OFFICIAL, () => preview.runSkin(restoreOfficialLook))\n return\n }\n const entry = runtime.find(target)\n if (entry === null) {\n setError(t('applyFailed'))\n return\n }\n run(target, () => preview.runSkin(async () => {\n const active = await switchAndDeactivateCustomTheme(target, entry)\n if (wallpaper.selection() !== '') wallpaper.clearSelection()\n return active\n }))\n }\n\n const tryOnCustomTheme = (): void => {\n run('custom-theme', () => preview.runCustomTheme(async () => {\n const active = await runtime.controller.tryOn(null, null)\n if (active !== null) throw new Error('stock preview did not activate')\n customTheme.tryOn()\n return active\n }))\n }\n\n const exitCustomThemeTryOn = (): void => {\n run('custom-theme', () => preview.runCustomTheme(async () => {\n customTheme.exitTryOn()\n return await runtime.controller.exitTryOn()\n }))\n }\n\n const applyCustomTheme = (): void => {\n run('custom-theme', () => preview.runCustomTheme(async () => {\n await customTheme.apply()\n const active = await runtime.controller.switchTo(null, null)\n if (active !== null) {\n await customTheme.deactivate()\n throw new Error('stock theme did not activate')\n }\n return active\n }))\n }\n\n const handleVerify = async (): Promise<void> => {\n setVerifying(true)\n setError(null)\n try {\n const res = await fetch('/api/skin-center/v2/verify', {\n method: 'POST',\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify({ autoRepair: true }),\n })\n const json = (await res.json().catch(() => null)) as {\n ok?: boolean\n total?: number\n valid?: number\n issues?: number\n repaired?: string[]\n repairFailed?: Array<{ id: string; error: string }>\n details?: Array<{ id: string; status: string; hooksTrusted: boolean; mismatches: string[]; missing: string[] }>\n } | null\n if (!res.ok || json?.ok !== true) {\n throw new Error('verify failed')\n }\n if (!mounted.current) return\n setVerifySummary({\n total: json.total ?? 0,\n valid: json.valid ?? 0,\n issues: json.issues ?? 0,\n repaired: json.repaired ?? [],\n repairFailed: json.repairFailed ?? [],\n })\n const map: Record<string, { status: string; hooksTrusted: boolean; mismatches: string[]; missing: string[] }> = {}\n for (const item of json.details ?? []) {\n map[item.id] = item\n }\n setVerifyReports(map)\n if (json.repaired && json.repaired.length > 0) {\n await runtime.refreshCatalog()\n if (activeId && json.repaired.includes(activeId)) {\n const freshEntry = runtime.find(activeId)\n if (freshEntry) {\n await preview.runSkin(() => switchAndDeactivateCustomTheme(activeId, freshEntry))\n }\n }\n }\n } catch {\n if (mounted.current) setError(t('applyFailed'))\n } finally {\n if (mounted.current) setVerifying(false)\n }\n }\n\n const handleUninstall = async (entry: CatalogSkin): Promise<void> => {\n const id = entry.manifest.id\n setUninstallingId(id)\n setError(null)\n try {\n if (tryingId === id) {\n await preview.runSkin(() => runtime.controller.exitTryOn())\n }\n if (activeId === id) {\n await preview.runSkin(restoreOfficialLook)\n }\n const res = await fetch(`/api/skin-center/v2/skins/${encodeURIComponent(id)}/uninstall`, {\n method: 'POST',\n headers: { 'content-type': 'application/json' },\n })\n const json = (await res.json().catch(() => null)) as { ok?: boolean } | null\n if (!res.ok || json?.ok !== true) {\n throw new Error('uninstall failed')\n }\n await runtime.refreshCatalog()\n if (mounted.current) setConfirmUninstallId(null)\n } catch {\n if (mounted.current) setError(t('uninstallFailed'))\n } finally {\n if (mounted.current) setUninstallingId(null)\n }\n }\n\n const dark = document.body.hasAttribute('data-ds-dark-theme')\n\n /** One row: try-on control + apply button + optional uninstall. Shared by the official card and every skin card. */\n const actionButtons = (opts: {\n key: string\n entry?: CatalogSkin\n isActive: boolean\n isTrying: boolean\n onTryOn: () => void\n applyLabel: string\n }): ReactNode => {\n const isUser = opts.entry?.origin === 'user'\n const isConfirming = isUser && confirmUninstallId === opts.key\n return (\n <div className={css.actions}>\n {opts.isActive && !opts.isTrying ? (\n <button type=\"button\" className={`${css.button} ${css.buttonGhost}`} disabled>\n {t('tryOn')}\n </button>\n ) : opts.isTrying ? (\n <button type=\"button\" className={`${css.button} ${css.buttonPrimary}`} disabled={busyId !== null || uninstallingId !== null} onClick={exitTryOn}>\n {t('exitTryOn')}\n </button>\n ) : (\n <button\n type=\"button\"\n className={`${css.button} ${css.buttonPrimary}`}\n disabled={busyId !== null || uninstallingId !== null}\n onClick={opts.onTryOn}\n >\n {busyId === opts.key ? t('loading') : t('tryOn')}\n </button>\n )}\n <button\n type=\"button\"\n className={css.button}\n disabled={busyId !== null || uninstallingId !== null}\n onClick={() => { applySkin(opts.key) }}\n >\n {busyId === opts.key ? t('applying') : opts.applyLabel}\n </button>\n {isUser && (\n isConfirming ? (\n <>\n <button\n type=\"button\"\n className={`${css.button} ${css.buttonDangerConfirm}`}\n disabled={busyId !== null || uninstallingId !== null}\n onClick={() => { if (opts.entry) void handleUninstall(opts.entry) }}\n >\n {uninstallingId === opts.key ? t('uninstalling') : t('confirm')}\n </button>\n <button\n type=\"button\"\n className={css.button}\n disabled={uninstallingId !== null}\n onClick={() => { setConfirmUninstallId(null) }}\n >\n {t('cancel')}\n </button>\n </>\n ) : (\n <button\n type=\"button\"\n className={`${css.button} ${css.buttonDanger}`}\n disabled={busyId !== null || uninstallingId !== null}\n onClick={() => { setConfirmUninstallId(opts.key) }}\n >\n {t('uninstall')}\n </button>\n )\n )}\n </div>\n )\n }\n\n return (\n <li className={css.pluginCard}>\n <div className={css.cardHeaderStatic}>\n <span className={css.headText}>\n <span className={css.pluginName}>\n {t('title')}\n <span className={css.titleBadge}>{String(catalog?.length ?? 0)}</span>\n </span>\n <span className={css.cardDescription} title={t('cardDescription')}>{t('cardDescription')}</span>\n </span>\n </div>\n\n <div className={css.cardBody}>\n <div className={css.enableRow}>\n <span className={css.enableLabel} title={t('enabled')}>{t('enabled')}</span>\n <button\n type=\"button\"\n role=\"switch\"\n aria-checked={enabled}\n aria-label={t('enabled')}\n className={enabled ? css.switch + ' ' + css.switchOn : css.switch}\n onClick={() => { background.setEnabled(!enabled) }}\n >\n <span className={css.switchThumb} />\n </button>\n <p className={css.enableHint}>{t('enabledHint')}</p>\n </div>\n {enabled\n ? (\n <>\n <div className={css.head}>\n <div className={css.intro} title={t('intro')}>{t('intro')}</div>\n <div className={css.toolbar}>\n <div className={css.themeRow}>\n <span className={css.themeLabel}>{t('theme')}</span>\n <button\n type=\"button\"\n className={`${css.themeButton} ${dark ? '' : css.themeButtonActive}`}\n onClick={() => { theme.setTheme('light') }}\n >\n {t('themeLight')}\n </button>\n <button\n type=\"button\"\n className={`${css.themeButton} ${dark ? css.themeButtonActive : ''}`}\n onClick={() => { theme.setTheme('dark') }}\n >\n {t('themeDark')}\n </button>\n </div>\n <button\n type=\"button\"\n className={css.themeButton}\n disabled={verifying || busyId !== null || uninstallingId !== null}\n onClick={() => { void handleVerify() }}\n >\n {verifying ? t('verifyingIntegrity') : t('verifyIntegrity')}\n </button>\n </div>\n {verifySummary !== null && (\n <div className={`${css.verifySummary} ${verifySummary.issues === 0 ? css.verifySummarySuccess : css.verifySummaryWarning}`}>\n {verifySummary.repaired && verifySummary.repaired.length > 0 && verifySummary.issues === 0\n ? t('verifyRepaired', { count: verifySummary.repaired.length })\n : verifySummary.issues === 0\n ? t('verifyAllPassed', { count: verifySummary.total })\n : verifySummary.repaired && verifySummary.repaired.length > 0\n ? `${t('verifyRepaired', { count: verifySummary.repaired.length })}, ${t('verifyFoundIssues', { count: verifySummary.issues })}`\n : t('verifyFoundIssues', { count: verifySummary.issues })}\n </div>\n )}\n </div>\n\n <div className={css.backgroundRow}>\n <div className={css.backgroundHead}>\n <span className={css.backgroundLabel}>{t('backgroundOpacity')}</span>\n <span className={css.backgroundValue} aria-hidden=\"true\">{shownOpacity}%</span>\n </div>\n <SliderControl\n id=\"skin-center-background-opacity\"\n className={css.backgroundRange}\n min={0}\n max={100}\n step={5}\n value={opacity}\n ariaValuetext={shownOpacity + '%'}\n ariaLabel={t('backgroundOpacity')}\n onChanging={setShownOpacity}\n onChange={(value) => { background.set(value) }}\n />\n <p className={backdropActive ? css.backgroundHint : css.backgroundHintMuted}>\n {backdropActive ? t('backgroundHint') : t('backgroundHintInert')}\n </p>\n </div>\n <div className={css.backgroundRow}>\n <div className={css.backgroundHead}>\n <span className={css.backgroundLabel}>{t('backgroundBlurEmpty')}</span>\n <span className={css.backgroundValue} aria-hidden=\"true\">{shownBlurEmpty}px</span>\n </div>\n <SliderControl\n id=\"skin-center-background-blur-empty\"\n className={css.backgroundRange}\n min={0}\n max={20}\n step={1}\n value={blurEmpty}\n ariaValuetext={shownBlurEmpty + 'px'}\n ariaLabel={t('backgroundBlurEmpty')}\n onChanging={setShownBlurEmpty}\n onChange={(value) => { background.setBlurEmpty(value) }}\n />\n <div className={css.backgroundHead}>\n <span className={css.backgroundLabel}>{t('backgroundBlurContent')}</span>\n <span className={css.backgroundValue} aria-hidden=\"true\">{shownBlurContent}px</span>\n </div>\n <SliderControl\n id=\"skin-center-background-blur-content\"\n className={css.backgroundRange}\n min={0}\n max={20}\n step={1}\n value={blurContent}\n ariaValuetext={shownBlurContent + 'px'}\n ariaLabel={t('backgroundBlurContent')}\n onChanging={setShownBlurContent}\n onChange={(value) => { background.setBlurContent(value) }}\n />\n <p className={backdropActive ? css.backgroundHint : css.backgroundHintMuted}>\n {backdropActive ? t('backgroundBlurHint') : t('backgroundBlurInert')}\n </p>\n </div>\n\n\n <div className={css.backgroundRow}>\n <div className={css.backgroundHead}>\n <span className={css.backgroundLabel}>{t('inputCardBlur')}</span>\n <span className={css.backgroundValue} aria-hidden=\"true\">{shownInputCardBlur}px</span>\n </div>\n <SliderControl\n id=\"skin-center-input-card-blur\"\n className={css.backgroundRange}\n min={0}\n max={20}\n step={1}\n value={inputCardBlur}\n ariaValuetext={shownInputCardBlur + 'px'}\n ariaLabel={t('inputCardBlur')}\n onChanging={setShownInputCardBlur}\n onChange={(value) => { background.setInputCardBlur(value) }}\n />\n <p className={css.backgroundHint}>{t('inputCardBlurHint')}</p>\n </div>\n\n <div className={css.backgroundRow}>\n <div className={css.backgroundHead}>\n <span className={css.backgroundLabel}>{t('bubbleOpacity')}</span>\n <span className={css.backgroundValue} aria-hidden=\"true\">{shownBubbleOpacity}%</span>\n </div>\n <SliderControl\n id=\"skin-center-bubble-opacity\"\n className={css.backgroundRange}\n min={0}\n max={100}\n step={5}\n value={bubbleOpacity}\n ariaValuetext={shownBubbleOpacity + '%'}\n ariaLabel={t('bubbleOpacity')}\n onChanging={setShownBubbleOpacity}\n onChange={(value) => { background.setBubbleOpacity(value) }}\n />\n <p className={css.backgroundHint}>{t('bubbleOpacityHint')}</p>\n </div>\n\n <WallpaperPanel t={t} wallpaper={wallpaper} />\n\n {error !== null && <div className={css.error}>{error}</div>}\n\n <div className={css.list}>\n {(() => {\n const isActive = activeId === null && !previewing && !customThemeState.applied\n const isTrying = previewing && tryingId === null && !customThemeState.previewing\n const badge = isActive ? t('active') : isTrying ? t('tryingOn') : null\n return (\n <div className={css.card} key={OFFICIAL}>\n <div className={css.cardHead}>\n <span className={css.swatch} style={{ background: '#98a1ab' }} aria-hidden=\"true\" />\n <span className={css.cardName} title={t('official')}>{t('official')}</span>\n {badge !== null && (\n <span className={`${css.badge} ${isActive ? css.badgeActive : css.badgeTrying}`}>\n {badge}\n </span>\n )}\n </div>\n <div className={css.cardTagline} title={t('officialTagline')}>{t('officialTagline')}</div>\n {actionButtons({\n key: OFFICIAL,\n isActive,\n isTrying,\n onTryOn: tryOnOfficial,\n applyLabel: t('restore'),\n })}\n </div>\n )\n })()}\n\n {(catalog ?? []).map(entry => {\n const id = entry.manifest.id\n const isActive = id === activeId && !previewing\n const isTrying = previewing && id === tryingId\n const badge = isActive ? t('active') : isTrying ? t('tryingOn') : null\n const report = verifyReports[id]\n return (\n <div className={css.card} key={id}>\n <div className={css.cardHead}>\n <span\n className={css.swatch}\n style={{ background: entry.manifest.accent ?? '#98a1ab' }}\n aria-hidden=\"true\"\n />\n <span className={css.cardName} title={entry.manifest.nameEn}>{entry.manifest.nameEn}</span>\n {report && (\n <span\n className={`${css.badge} ${\n report.status === 'valid'\n ? css.badgeSuccess\n : report.status === 'tampered'\n ? css.badgeWarning\n : css.badgeDanger\n }`}\n title={\n report.status === 'valid'\n ? t('integrityValid')\n : [...report.mismatches, ...report.missing].join(', ') || report.status\n }\n >\n {report.status === 'valid'\n ? t('integrityValid')\n : report.status === 'tampered'\n ? t('integrityTampered')\n : report.status === 'missing-files'\n ? t('integrityMissing')\n : t('integrityHooksRefused')}\n </span>\n )}\n {badge !== null && (\n <span className={`${css.badge} ${isActive ? css.badgeActive : css.badgeTrying}`}>\n {badge}\n </span>\n )}\n </div>\n <div className={css.cardTagline} title={entry.manifest.tagline ?? ''}>\n {entry.manifest.tagline ?? ''}\n </div>\n {report && report.status !== 'valid' && (\n <div className={css.integrityNote}>\n {[\n report.mismatches.length > 0 ? `${t('integrityTampered')}: ${report.mismatches.join(', ')}` : null,\n report.missing.length > 0 ? `${t('integrityMissing')}: ${report.missing.join(', ')}` : null,\n ].filter(Boolean).join(' | ')}\n </div>\n )}\n {actionButtons({\n key: id,\n entry,\n isActive,\n isTrying,\n onTryOn: () => { tryOn(entry) },\n applyLabel: t('apply'),\n })}\n </div>\n )\n })}\n\n <CustomThemeCard\n t={t}\n customTheme={customTheme}\n scheme={dark ? 'dark' : 'light'}\n setScheme={scheme => { theme.setTheme(scheme) }}\n isActive={customThemeState.applied && activeId === null && !previewing}\n isTrying={customThemeState.previewing}\n busy={busyId === 'custom-theme'}\n disabled={busyId !== null}\n onTryOn={tryOnCustomTheme}\n onExitTryOn={exitCustomThemeTryOn}\n onApply={applyCustomTheme}\n />\n </div>\n </>\n )\n : (\n <p className={css.offNote} role=\"status\">{t('offNote')}</p>\n )}\n </div>\n </li>\n )\n}\n\n/** Props the settings section binds for the skin-center card page. */\nexport type SkinCenterSectionProps =\n PropsRuntime<'settings.section'>\n & PropsLocale<'skinCenter'>\n & SkinCenterInjected\n\n/** Render the skin-center card as a first-level settings page. */\nexport function SkinCenterSection(props: SkinCenterSectionProps): ReactNode {\n const { t, runtime, theme, background, wallpaper, preview, customTheme } = props\n return (\n <ul className={css.sectionList}>\n <SkinCenter\n t={t}\n runtime={runtime}\n theme={theme}\n background={background}\n wallpaper={wallpaper}\n preview={preview}\n customTheme={customTheme}\n />\n </ul>\n )\n}\n","/**\n * Shared skin-background preference contract (issue #996): the six values the\n * skin-center card edits — master switch, backdrop occlusion, per-state\n * backdrop blur, composer-card blur, and bubble opacity.\n *\n * These used to live only in the `skin-background` settings namespace, which\n * the remote pairing channel fences as loopback-only, so a paired remote\n * desktop always read defaults and silently dropped writes. They now persist\n * in the skin center's own v2 state (POST /api/skin-center/v2/active), which\n * rides the same allow-listed channel as skin switching. This module is the\n * dependency-free source of truth both halves (host routes / migration and\n * the browser controller) share.\n * @module @linxin666/dsh-client-ui-skin-center/core/background\n */\n\n/** Skin-background preference set persisted in the v2 active state file. */\nexport interface SkinBackgroundConfig {\n /** Master switch for the skin center. */\n enabled?: boolean\n /** Background occlusion 0-100 (0 = no extra veil, 100 = fully obscured). */\n backgroundOpacity?: number\n /** Empty-conversation backdrop blur, 0-20 px (0 disables). */\n backgroundBlurEmpty?: number\n /** With-content backdrop blur, 0-20 px (0 disables). */\n backgroundBlurContent?: number\n /** Composer-card backdrop blur, 0-20 px. */\n inputCardBlur?: number\n /** Message bubble opacity 0-100, for skins exposing bubble alpha. */\n bubbleOpacity?: number\n}\n\n/** Effective value of every field when the state carries none. */\nexport const SKIN_BACKGROUND_DEFAULTS: Readonly<Required<SkinBackgroundConfig>> = {\n enabled: true,\n backgroundOpacity: 0,\n backgroundBlurEmpty: 0,\n backgroundBlurContent: 0,\n inputCardBlur: 10,\n bubbleOpacity: 50,\n}\n\n/** The fields normalize/sanitize know about; unknown keys are dropped. */\nexport const SKIN_BACKGROUND_FIELDS = Object.keys(SKIN_BACKGROUND_DEFAULTS) as Array<keyof SkinBackgroundConfig>\n\nfunction clampInt(value: number, min: number, max: number): number {\n return Math.max(min, Math.min(max, Math.round(value)))\n}\n\nconst RANGES: Record<Exclude<keyof SkinBackgroundConfig, 'enabled'>, [number, number]> = {\n backgroundOpacity: [0, 100],\n backgroundBlurEmpty: [0, 20],\n backgroundBlurContent: [0, 20],\n inputCardBlur: [0, 20],\n bubbleOpacity: [0, 100],\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value)\n}\n\n/**\n * Lenient normalization for stored/legacy data: unknown keys and wrongly\n * typed fields are dropped, numeric fields are clamped into range. Never\n * fails; a non-object input yields an empty config.\n */\nexport function normalizeSkinBackground(value: unknown): SkinBackgroundConfig {\n if (!isRecord(value)) return {}\n const out: SkinBackgroundConfig = {}\n if (typeof value.enabled === 'boolean') out.enabled = value.enabled\n for (const field of Object.keys(RANGES) as Array<keyof typeof RANGES>) {\n const raw = value[field]\n if (typeof raw !== 'number' || !Number.isFinite(raw)) continue\n const [min, max] = RANGES[field]\n out[field] = clampInt(raw, min, max)\n }\n return out\n}\n\n/**\n * Strict validation for the POST /active write surface: a background value\n * must be an object whose known fields are correctly typed (numbers are then\n * clamped). Returns null for anything else so the route can answer 400.\n */\nexport function sanitizeSkinBackground(value: unknown): SkinBackgroundConfig | null {\n if (!isRecord(value)) return null\n if (value.enabled !== undefined && typeof value.enabled !== 'boolean') return null\n for (const field of Object.keys(RANGES) as Array<keyof typeof RANGES>) {\n const raw = value[field]\n if (raw !== undefined && (typeof raw !== 'number' || !Number.isFinite(raw))) return null\n }\n return normalizeSkinBackground(value)\n}\n\n/** Fill every absent field from {@link SKIN_BACKGROUND_DEFAULTS}. */\nexport function resolveSkinBackground(value: SkinBackgroundConfig | null | undefined): Required<SkinBackgroundConfig> {\n return { ...SKIN_BACKGROUND_DEFAULTS, ...(value ?? {}) }\n}\n\n/** True when at least one field departs from its default (customized data). */\nexport function hasCustomSkinBackground(value: SkinBackgroundConfig): boolean {\n return SKIN_BACKGROUND_FIELDS.some((field) => value[field] !== undefined && value[field] !== SKIN_BACKGROUND_DEFAULTS[field])\n}\n","/**\n * Background-scrim handle for the skin center: applies the chosen occlusion\n * to the page's backdrop, plus an optional per-state Gaussian blur of that\n * backdrop.\n *\n * Occlusion is a CSS variable on `document.body` (--dsw-skin-scrim), which\n * backdrop-painting skins (blue-fantasy / whale-song) read inside their\n * setBackdrop() so the veil stays in sync across theme flips and try-on\n * restores. The official stock look paints no backdrop, so the variable is\n * inert there — the value still persists so it is ready for the next backdrop\n * skin.\n *\n * The Gaussian blur targets the same painted backdrop through a fixed child\n * of `document.body` using backdrop-filter: it samples the body's own\n * background painted behind it. Separate strengths apply to the empty\n * conversation and the conversation-with-content states, detected from the\n * shell's stable message-row class suffixes (hash prefix varies, suffix is\n * stable). When the active blur is 0 no element exists, so there is no GPU\n * cost. Blur never changes the occlusion behavior above.\n *\n * Occlusion values are 0-100 (0 = no extra veil, 100 = fully obscured); they\n * are written through as a 0..1 alpha for the CSS variable. Blur values are\n * 0-20 px. Dragging the controls applies instantly (live).\n *\n * Persistence (issue #996): the controller owns no settings scope — the\n * remote pairing channel fences settings.* as loopback-only, which is what\n * stranded remote clients on defaults. The caller hands in the initial\n * values and a `persist` callback (the v2 /active channel); later external\n * edits (the official settings page locally, the refetched state remotely)\n * arrive through `init()`.\n */\nimport {\n resolveSkinBackground,\n SKIN_BACKGROUND_DEFAULTS,\n type SkinBackgroundConfig,\n} from '../core/background.ts'\n\n/** The namespace string the Host registers (mirrors src/index.ts). */\nexport const SKIN_BACKGROUND_NS = 'skin-background'\n\n/** Field of the background value inside the namespace section. */\nexport const OPACITY_FIELD = 'backgroundOpacity'\n\n/** Field of the empty-conversation backdrop blur inside the namespace section. */\nexport const BLUR_EMPTY_FIELD = 'backgroundBlurEmpty'\n\n/** Field of the with-content backdrop blur inside the namespace section. */\nexport const BLUR_CONTENT_FIELD = 'backgroundBlurContent'\n\n/** Field of the composer card backdrop blur inside the namespace section. */\nexport const INPUT_CARD_BLUR_FIELD = 'inputCardBlur'\n\n/** CSS custom property written to document.body and read by backdrop skins. */\nexport const SCRIM_VAR = '--dsw-skin-scrim'\n\n/** Field of the message bubble opacity inside the namespace section. */\nexport const BUBBLE_OPACITY_FIELD = 'bubbleOpacity'\n\n/** CSS custom property consumed by skins that expose translucent bubbles. */\nexport const BUBBLE_ALPHA_VAR = '--dsh-skin-bubble-alpha'\n\n/** CSS custom property consumed by the shared composer neutralizer. */\nexport const INPUT_CARD_BLUR_VAR = '--dsh-input-card-blur'\n\n/** Default occlusion (0 = no extra veil) when the section carries none. */\nexport const DEFAULT_OPACITY = SKIN_BACKGROUND_DEFAULTS.backgroundOpacity\n\n/** Default message bubble opacity percentage. */\nexport const DEFAULT_BUBBLE_OPACITY = SKIN_BACKGROUND_DEFAULTS.bubbleOpacity\n\n/** Default blur (0 = disabled) when the section carries none. */\nexport const DEFAULT_BLUR = SKIN_BACKGROUND_DEFAULTS.backgroundBlurEmpty\n\n/** The face the skin-center card injects for the background control. */\nexport interface SkinBackgroundHandle {\n /** Current master switch (true when the plugin is on). */\n enabled(): boolean\n /** Toggle + persist the master switch. */\n setEnabled(value: boolean): void\n /** Current occlusion 0-100 (also the getSnapshot seat for useSyncExternalStore). */\n opacity(): number\n /** Current empty-conversation backdrop blur 0-20 px. */\n blurEmpty(): number\n /** Current with-content backdrop blur 0-20 px. */\n blurContent(): number\n /** Current input-card backdrop blur 0-20 px. */\n inputCardBlur(): number\n /** Current message bubble opacity 0-100. */\n bubbleOpacity(): number\n /** Observe a change in the applied values. */\n subscribe(listener: () => void): () => void\n /** Apply + persist a new occlusion. */\n set(opacity: number): void\n /** Apply + persist a new empty-conversation backdrop blur (0-20 px). */\n setBlurEmpty(value: number): void\n /** Apply + persist a new with-content backdrop blur (0-20 px). */\n setBlurContent(value: number): void\n /** Apply + persist a new input-card backdrop blur (0-20 px). */\n setInputCardBlur(value: number): void\n /** Apply + persist a new message bubble opacity (0-100). */\n setBubbleOpacity(value: number): void\n /** Tear down the blur element and MutationObserver. */\n dispose(): void\n}\n\n/**\n * Selector for a conversation message row inside the shell's center column.\n * Official shell message rows carry `data-chat-anchor-key`; the\n * `data-pane=\"conversation\"` attribute is stamped by the dsh-web-all compat\n * shim on the center column, where the _userRow / _compactionRow /\n * _contextRow / _turnErrorRow suffixes are CSS-module message-row classes\n * (hash prefix varies, suffix is stable).\n */\nconst CONVERSATION_CONTENT_SELECTOR = [\n '[data-chat-anchor-key]',\n '[data-pane=\"conversation\"] [class*=\"_userRow\"]',\n '[data-pane=\"conversation\"] [class*=\"_compactionRow\"]',\n '[data-pane=\"conversation\"] [class*=\"_contextRow\"]',\n '[data-pane=\"conversation\"] [class*=\"_turnErrorRow\"]',\n].join(', ')\n\n/**\n * Own the background preference set: apply the values to the body instantly\n * and persist user edits through the caller-provided channel.\n */\nexport class BackgroundController implements SkinBackgroundHandle {\n private enabledValue = SKIN_BACKGROUND_DEFAULTS.enabled\n private opacityValue = SKIN_BACKGROUND_DEFAULTS.backgroundOpacity\n private blurEmptyValue = SKIN_BACKGROUND_DEFAULTS.backgroundBlurEmpty\n private blurContentValue = SKIN_BACKGROUND_DEFAULTS.backgroundBlurContent\n private inputCardBlurValue = SKIN_BACKGROUND_DEFAULTS.inputCardBlur\n private bubbleOpacityValue = SKIN_BACKGROUND_DEFAULTS.bubbleOpacity\n private readonly listeners = new Set<() => void>()\n private readonly persist: (next: SkinBackgroundConfig) => void\n /** The fixed backdrop-filter element, present only while active blur > 0. */\n private blurElement: HTMLDivElement | null = null\n /** The body MutationObserver, installed lazily once a blur is active. */\n private observer: MutationObserver | null = null\n /** Pending requestAnimationFrame id for a coalesced recheck. */\n private rafId: number | null = null\n /** Guard: after dispose no scheduled work may reinstall anything. */\n private disposed = false\n\n /**\n * @param initial - values known at construction (the local settings scope\n * snapshot on loopback); null starts from defaults until init() arrives.\n * @param persist - persistence channel for user edits (v2 /active POST).\n */\n constructor(initial: SkinBackgroundConfig | null, persist: (next: SkinBackgroundConfig) => void) {\n this.persist = persist\n if (initial !== null) this.assign(initial)\n this.applyOcclusion()\n this.applyInputCardBlur()\n this.applyBubbleOpacity()\n this.syncBlur()\n }\n\n /**\n * Replace the current values with externally sourced ones (the refetched\n * v2 state, or a live settings-scope publish). Never persists — the source\n * already owns the stored copy; the caller decides whether to forward the\n * change into the v2 store.\n */\n init(next: SkinBackgroundConfig | null): void {\n if (this.disposed) return\n this.assign(next ?? {})\n this.applyOcclusion()\n this.applyInputCardBlur()\n this.applyBubbleOpacity()\n this.syncBlur()\n this.publish()\n }\n\n /** The current values as a persistable config (every field concrete). */\n snapshot(): SkinBackgroundConfig {\n return {\n enabled: this.enabledValue,\n backgroundOpacity: this.opacityValue,\n backgroundBlurEmpty: this.blurEmptyValue,\n backgroundBlurContent: this.blurContentValue,\n inputCardBlur: this.inputCardBlurValue,\n bubbleOpacity: this.bubbleOpacityValue,\n }\n }\n\n enabled = (): boolean => this.enabledValue\n\n setEnabled(value: boolean): void {\n this.enabledValue = value\n this.applyOcclusion()\n this.applyInputCardBlur()\n this.applyBubbleOpacity()\n this.syncBlur()\n this.publish()\n this.persist(this.snapshot())\n }\n\n opacity = (): number => this.opacityValue\n\n blurEmpty = (): number => this.blurEmptyValue\n\n blurContent = (): number => this.blurContentValue\n\n inputCardBlur = (): number => this.inputCardBlurValue\n\n bubbleOpacity = (): number => this.bubbleOpacityValue\n\n subscribe = (listener: () => void): (() => void) => {\n this.listeners.add(listener)\n return () => { this.listeners.delete(listener) }\n }\n\n set(opacity: number): void {\n this.opacityValue = this.clampPercent(opacity)\n this.applyOcclusion()\n this.publish()\n this.persist(this.snapshot())\n }\n\n setBlurEmpty(value: number): void {\n this.blurEmptyValue = this.clampBlur(value)\n this.ensureObserver()\n this.syncBlur()\n this.publish()\n this.persist(this.snapshot())\n }\n\n setBlurContent(value: number): void {\n this.blurContentValue = this.clampBlur(value)\n this.ensureObserver()\n this.syncBlur()\n this.publish()\n this.persist(this.snapshot())\n }\n\n setInputCardBlur(value: number): void {\n this.inputCardBlurValue = this.clampBlur(value)\n this.applyInputCardBlur()\n this.publish()\n this.persist(this.snapshot())\n }\n\n setBubbleOpacity(value: number): void {\n this.bubbleOpacityValue = this.clampPercent(value)\n this.applyBubbleOpacity()\n this.publish()\n this.persist(this.snapshot())\n }\n\n dispose(): void {\n this.disposed = true\n if (this.rafId !== null) {\n cancelAnimationFrame(this.rafId)\n this.rafId = null\n }\n this.removeBlurElement()\n document.body.style.removeProperty(INPUT_CARD_BLUR_VAR)\n document.body.style.removeProperty(BUBBLE_ALPHA_VAR)\n if (this.observer !== null) {\n this.observer.disconnect()\n this.observer = null\n }\n }\n\n /** Copy one config into the live fields, defaults filling the gaps. */\n private assign(config: SkinBackgroundConfig): void {\n const resolved = resolveSkinBackground(config)\n this.enabledValue = resolved.enabled\n this.opacityValue = resolved.backgroundOpacity\n this.blurEmptyValue = resolved.backgroundBlurEmpty\n this.blurContentValue = resolved.backgroundBlurContent\n this.inputCardBlurValue = resolved.inputCardBlur\n this.bubbleOpacityValue = resolved.bubbleOpacity\n }\n\n private clampBlur(value: number): number {\n return Math.max(0, Math.min(20, Math.round(value)))\n }\n\n private clampPercent(value: number): number {\n return Math.max(0, Math.min(100, Math.round(value)))\n }\n\n private applyInputCardBlur(): void {\n if (!this.enabledValue) {\n document.body.style.removeProperty(INPUT_CARD_BLUR_VAR)\n return\n }\n document.body.style.setProperty(INPUT_CARD_BLUR_VAR, this.inputCardBlurValue + 'px')\n }\n\n private applyBubbleOpacity(): void {\n if (!this.enabledValue) {\n document.body.style.removeProperty(BUBBLE_ALPHA_VAR)\n return\n }\n document.body.style.setProperty(BUBBLE_ALPHA_VAR, String(this.bubbleOpacityValue / 100))\n }\n\n /** Write the current occlusion onto the body CSS variable (0..1 alpha). */\n private applyOcclusion(): void {\n if (!this.enabledValue) {\n document.body.style.removeProperty(SCRIM_VAR)\n return\n }\n document.body.style.setProperty(SCRIM_VAR, String(this.opacityValue / 100))\n }\n\n /**\n * Apply the active blur: empty or with-content strength depending on the\n * conversation state. A value > 0 ensures the fixed blur element exists\n * with the matching backdrop-filter; 0 removes it.\n */\n private syncBlur(): void {\n if (this.disposed) return\n if (this.hasWallpaper()) {\n // The wallpaper module owns its own blur (wallpaperBlur); the skin-center\n // background blur layer must stay off while a wallpaper is mounted so\n // the two settings remain independent (#777 decouple).\n this.removeBlurElement()\n return\n }\n if (!this.enabledValue) {\n this.removeBlurElement()\n return\n }\n this.ensureObserver()\n const active = this.hasConversationContent() ? this.blurContentValue : this.blurEmptyValue\n if (active > 0) this.ensureBlurElement(active)\n else this.removeBlurElement()\n }\n\n /** True when the conversation pane hosts at least one message row. */\n private hasConversationContent(): boolean {\n return document.querySelector(CONVERSATION_CONTENT_SELECTOR) !== null\n }\n\n /** True while a Wallpaper Engine wallpaper is mounted. */\n private hasWallpaper(): boolean {\n return document.documentElement.hasAttribute('data-dsh-wallpaper-active')\n }\n\n /** Create (if needed) and size the fixed backdrop-filter element. */\n private ensureBlurElement(active: number): void {\n if (this.blurElement === null) {\n const element = document.createElement('div')\n element.style.position = 'fixed'\n element.style.inset = '0'\n element.style.zIndex = '-1'\n element.style.pointerEvents = 'none'\n element.setAttribute('aria-hidden', 'true')\n this.blurElement = element\n document.body.appendChild(element)\n }\n const blur = 'blur(' + active + 'px)'\n this.blurElement.style.backdropFilter = blur\n // Safari: the vendor-prefixed form is only reachable via setProperty.\n this.blurElement.style.setProperty('-webkit-backdrop-filter', blur)\n }\n\n /** Remove the fixed blur element, if present. */\n private removeBlurElement(): void {\n if (this.blurElement === null) return\n this.blurElement.remove()\n this.blurElement = null\n }\n\n /**\n * Install the MutationObserver on document.body only when either blur\n * field is active, so a fully-disabled blur never pays the observation\n * cost. Runs lazily on the first non-zero set.\n */\n private ensureObserver(): void {\n if (this.disposed || this.observer !== null) return\n if (this.blurEmptyValue <= 0 && this.blurContentValue <= 0) return\n this.observer = new MutationObserver(() => this.scheduleRecheck())\n this.observer.observe(document.body, {\n childList: true,\n subtree: true,\n attributes: true,\n attributeFilter: ['class'],\n })\n // Also react to the wallpaper marker so the background blur layer is\n // removed/restored exactly when a wallpaper mounts/unmounts.\n this.observer.observe(document.documentElement, {\n attributes: true,\n attributeFilter: ['data-dsh-wallpaper-active'],\n })\n }\n\n /** Coalesce burst mutations into one rAF-delayed recheck. */\n private scheduleRecheck(): void {\n if (this.disposed || this.rafId !== null) return\n this.rafId = requestAnimationFrame(() => {\n this.rafId = null\n if (this.disposed) return\n this.syncBlur()\n })\n }\n\n private publish(): void {\n for (const listener of this.listeners) listener()\n }\n}\n","/**\n * Safe reconciliation helpers for the legacy skin-background settings scope.\n *\n * The scope's resolved value contains schema defaults, while its raw user layer\n * contains only fields explicitly stored by the user. The v2 active-state\n * document is authoritative, so a scope update may merge only those raw fields\n * into the live background values.\n */\nimport {\n normalizeSkinBackground,\n SKIN_BACKGROUND_FIELDS,\n type SkinBackgroundConfig,\n} from './background.ts'\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value)\n}\n\n/** Return the known, explicitly stored skin-background fields from a user layer. */\nexport function extractSkinBackgroundUserLayer(value: unknown): SkinBackgroundConfig | null {\n if (!isRecord(value)) return null\n const normalized = normalizeSkinBackground(value)\n const knownFields = Object.keys(normalized) as Array<keyof SkinBackgroundConfig>\n if (knownFields.length === 0) return null\n const owned: SkinBackgroundConfig = {}\n for (const field of knownFields) {\n ;(owned as Record<string, unknown>)[field] = normalized[field]\n }\n return owned\n}\n\n/**\n * Build a v2-safe patch from the raw user layer. Absent fields, including\n * schema-default fields absent from the user layer, never enter the patch.\n */\nexport function skinBackgroundUserPatch(current: SkinBackgroundConfig, user: unknown): SkinBackgroundConfig | null {\n const userConfig = extractSkinBackgroundUserLayer(user)\n if (userConfig === null) return null\n const patch: SkinBackgroundConfig = {}\n for (const field of SKIN_BACKGROUND_FIELDS) {\n if (!Object.hasOwn(userConfig, field)) continue\n const value = userConfig[field]\n if (value === undefined || value === current[field]) continue\n ;(patch as Record<string, unknown>)[field] = value\n }\n return Object.keys(patch).length === 0 ? null : patch\n}\n\nexport interface SkinBackgroundScopeSnapshot {\n revision: number | undefined\n user: unknown\n}\n\nexport interface SkinBackgroundScopeReconcileResult {\n accepted: boolean\n revision: number | undefined\n lastUserJson: string\n patch: SkinBackgroundConfig | null\n}\n\n/** Deterministic serialization of the user layer for content-based dedup. */\nexport function serializeSkinBackgroundUserLayer(user: unknown): string {\n const extracted = extractSkinBackgroundUserLayer(user)\n return extracted === null ? '' : JSON.stringify(extracted)\n}\n\n/**\n * Full reconciliation state the browser glue keeps across scope publications.\n * It adds boot ordering to the revision/content fence so the settings\n * document's initial sync can never be mistaken for a settings-page edit\n * (#1375): a legacy user layer carrying stale explicit values (zeros written\n * by the pre-#1107 bug family) would otherwise patch — and persist over — the\n * authoritative v2 state on every boot where the document and the v2 GET\n * finish in the unlucky order.\n */\nexport interface SkinBackgroundReconcileState {\n /** Whether the authoritative v2 GET has completed and applied its values. */\n v2Loaded: boolean\n /** Whether the one-shot boot document sync (first revisioned publication) was consumed. */\n bootSyncSeen: boolean\n /** Last namespace revision seen (published, or seeded at construction). */\n lastRevision: number | undefined\n /** Serialized user layer seen last, for content-based replay dedup. */\n lastUserJson: string\n}\n\n/** Seed the reconcile state from the scope snapshot visible at construction. */\nexport function initialSkinBackgroundReconcileState(\n snapshot: SkinBackgroundScopeSnapshot,\n): SkinBackgroundReconcileState {\n return {\n v2Loaded: false,\n bootSyncSeen: false,\n lastRevision: snapshot.revision,\n lastUserJson: serializeSkinBackgroundUserLayer(snapshot.user),\n }\n}\n\n/**\n * Fold one scope publication into the reconcile state and produce the v2-safe\n * patch to merge into the live background values (null = nothing to apply).\n *\n * The boot document never merges, whichever order it lands in:\n * - a publication seen before the v2 GET completes is only recorded, so the\n * post-load check reads it as the unchanged boot snapshot, not an edit;\n * - the first revisioned publication of the plugin's lifetime (the document\n * resync itself) is consumed as the boot sync even when it lands after the\n * GET, because a genuine settings-page edit can only follow the document.\n */\nexport function reconcileSkinBackgroundPublication(\n state: SkinBackgroundReconcileState,\n current: SkinBackgroundConfig,\n snapshot: SkinBackgroundScopeSnapshot,\n): { state: SkinBackgroundReconcileState; patch: SkinBackgroundConfig | null } {\n const seen: SkinBackgroundReconcileState = {\n ...state,\n lastRevision: snapshot.revision ?? state.lastRevision,\n lastUserJson: serializeSkinBackgroundUserLayer(snapshot.user),\n }\n if (!state.v2Loaded) return { state: seen, patch: null }\n if (!state.bootSyncSeen) {\n return {\n state: snapshot.revision === undefined ? seen : { ...seen, bootSyncSeen: true },\n patch: null,\n }\n }\n const result = reconcileSkinBackgroundScope(current, snapshot, state.lastRevision, state.lastUserJson)\n return { state: seen, patch: result.patch }\n}\n\n/**\n * Accept a scope publication only when its namespace revision is new AND the\n * user layer has actually changed. A revision bump with identical user-layer\n * content is a replay (settings-mirror resync, WS reconnect, or another\n * plugin writing to the global settings document) and must not overwrite the\n * authoritative v2 state.\n */\nexport function reconcileSkinBackgroundScope(\n current: SkinBackgroundConfig,\n snapshot: SkinBackgroundScopeSnapshot,\n lastRevision: number | undefined,\n lastUserJson: string | undefined,\n): SkinBackgroundScopeReconcileResult {\n const currentUserJson = serializeSkinBackgroundUserLayer(snapshot.user)\n if (\n snapshot.revision === undefined\n || snapshot.revision === lastRevision\n || currentUserJson === lastUserJson\n || currentUserJson === ''\n ) {\n return {\n accepted: false,\n revision: snapshot.revision ?? lastRevision,\n lastUserJson: currentUserJson,\n patch: null,\n }\n }\n return {\n accepted: true,\n revision: snapshot.revision,\n lastUserJson: currentUserJson,\n patch: skinBackgroundUserPatch(current, snapshot.user),\n }\n}\n","/**\n * Skin-center locale dictionaries. The plugin-card name, its description,\n * and every control of the in-GUI skin center is localized through the\n * standard `t` seat.\n */\n\n/** Copy keys owned by this plugin. */\nexport type SkinCenterKey =\n | 'title'\n | 'cardDescription'\n | 'enabled'\n | 'enabledHint'\n | 'offNote'\n | 'intro'\n | 'official'\n | 'officialTagline'\n | 'active'\n | 'tryingOn'\n | 'tryOn'\n | 'loading'\n | 'exitTryOn'\n | 'apply'\n | 'applying'\n | 'restore'\n | 'applyFailed'\n | 'appliedUnconfirmed'\n | 'appliedNeedRestart'\n | 'theme'\n | 'themeLight'\n | 'themeDark'\n | 'tryOnError'\n | 'backgroundOpacity'\n | 'backgroundBlurEmpty'\n | 'backgroundBlurContent'\n | 'inputCardBlur'\n | 'inputCardBlurHint'\n | 'bubbleOpacity'\n | 'bubbleOpacityHint'\n | 'backgroundBlurHint'\n | 'backgroundBlurInert'\n | 'backgroundHint'\n | 'backgroundHintInert'\n | 'wallpaperTitle'\n | 'wallpaperEnable'\n | 'wallpaperHint'\n | 'wallpaperLoadError'\n | 'wallpaperLibraryFound'\n | 'wallpaperLibraryManual'\n | 'wallpaperLibrarySystem'\n | 'wallpaperRefresh'\n | 'wallpaperMode'\n | 'wallpaperModeLive'\n | 'wallpaperModeFrame'\n | 'wallpaperFit'\n | 'wallpaperFitCover'\n | 'wallpaperFitContain'\n | 'wallpaperFitFill'\n | 'wallpaperClear'\n | 'wallpaperDim'\n | 'wallpaperOpacity'\n | 'wallpaperBlur'\n | 'wallpaperPauseHidden'\n | 'wallpaperSound'\n | 'wallpaperSoundHint'\n | 'wallpaperVolume'\n | 'wallpaperImport'\n | 'wallpaperImportHint'\n | 'wallpaperReimport'\n | 'wallpaperRemove'\n | 'wallpaperUpdateAvailable'\n | 'wallpaperEmpty'\n | 'wallpaperTypeVideo'\n | 'wallpaperTypeWeb'\n | 'wallpaperTypeScene'\n | 'wallpaperTypeApp'\n | 'wallpaperTypeImage'\n | 'wallpaperLoadMore'\n | 'wallpaperDirs'\n | 'wallpaperDirsEmpty'\n | 'wallpaperDirsHint'\n | 'wallpaperDirPlaceholder'\n | 'wallpaperDirAdd'\n | 'wallpaperDirBrowse'\n | 'wallpaperDirBrowseHint'\n | 'wallpaperDirBrowseFailed'\n | 'wallpaperRatingAll'\n | 'wallpaperRatingG'\n | 'wallpaperRatingPg13'\n | 'wallpaperRatingR18'\n | 'wallpaperPagePrev'\n | 'wallpaperPageNext'\n | 'wallpaperPageJump'\n | 'wallpaperPageTotal'\n | 'customThemeTitle'\n | 'customThemeTagline'\n | 'customThemeEdit'\n | 'customThemeCloseEdit'\n | 'customThemeMode'\n | 'customThemeLight'\n | 'customThemeDark'\n | 'customThemeAccent'\n | 'customThemeBackground'\n | 'customThemeForeground'\n | 'customThemeContrast'\n | 'customThemeReset'\n | 'customThemeResetHint'\n | 'customThemeSaveFailed'\n | 'uninstall'\n | 'uninstalling'\n | 'uninstallConfirm'\n | 'uninstallFailed'\n | 'verifyIntegrity'\n | 'verifyingIntegrity'\n | 'verifyAllPassed'\n | 'verifyFoundIssues'\n | 'integrityValid'\n | 'integrityTampered'\n | 'integrityMissing'\n | 'integrityHooksRefused'\n | 'cancel'\n | 'confirm'\n | 'verifyRepaired'\n | 'verifyRepairFailed'\n | 'repair'\n | 'repairing'\n | 'repaired'\n\nexport const en: Record<SkinCenterKey, string> = {\n title: 'Skin Center',\n cardDescription: 'Try on any installed skin live in the GUI — exit restores instantly, applying persists in one click.',\n enabled: 'Enable skin center',\n enabledHint: 'When off, try-on, apply and background controls are disabled; turn it back on to resume.',\n offNote: 'The skin center is turned off.',\n intro: 'Try on any skin live — it takes effect instantly, exit restores the current look. Apply persists it across restarts.',\n official: 'Official default',\n officialTagline: 'The stock DSH look with no skin applied.',\n active: 'Active',\n tryingOn: 'Trying on',\n tryOn: 'Try on',\n loading: 'Loading…',\n exitTryOn: 'Exit try-on',\n apply: 'Apply',\n applying: 'Applying…',\n restore: 'Restore',\n applyFailed: 'Apply failed',\n appliedUnconfirmed: 'Applied, but the change has not been confirmed — refresh the page in dev mode; packaged installs (DSH Desktop) need an app restart',\n appliedNeedRestart: 'Applied and confirmed, but the host did not hot-reload — restart dsh to take effect',\n theme: 'Theme preview',\n themeLight: 'Light',\n themeDark: 'Dark',\n tryOnError: 'Try-on failed — see console',\n backgroundOpacity: 'Background occlusion',\n backgroundBlurEmpty: 'Blur when empty',\n backgroundBlurContent: 'Blur with content',\n inputCardBlur: 'Input card blur',\n inputCardBlurHint: 'Blurs only the area behind the input card while backdrop art is visible; it does not blur the entire wallpaper.',\n bubbleOpacity: 'Bubble opacity',\n bubbleOpacityHint: 'Controls translucent message bubbles for skins that expose bubble alpha, such as Whale Mom.',\n backgroundBlurHint: 'Applies a separate Gaussian blur to the backdrop for the empty conversation and the conversation with content; 0 disables.',\n backgroundBlurInert: 'Visible only with skins that paint a backdrop; the official default has none.',\n backgroundHint: 'Instantly veils the backdrop behind the panels — higher values obscure the art to help you focus.',\n backgroundHintInert: 'Only applies to skins that paint a backdrop (Blue Fantasy / Whale Song). Applies to the official default automatically once such a skin is active.',\n wallpaperTitle: 'Wallpaper Engine',\n wallpaperEnable: 'Enable wallpapers',\n wallpaperHint: 'Use your local Wallpaper Engine library as the GUI backdrop: video, web, and scene wallpapers render live (scene wallpapers need WebGL).',\n wallpaperLoadError: 'Wallpaper library failed to load',\n wallpaperLibraryFound: 'Wallpaper Engine library detected',\n wallpaperLibraryManual: 'Manual folders only (no Wallpaper Engine install found; set folders in the skin-wallpaper settings)',\n wallpaperLibrarySystem: 'macOS wallpapers detected (aerials and Desktop Pictures)',\n wallpaperRefresh: 'Refresh',\n wallpaperMode: 'Render mode',\n wallpaperModeLive: 'Live',\n wallpaperModeFrame: 'Static frame',\n wallpaperFit: 'Sizing mode',\n wallpaperFitCover: 'Cover (fill)',\n wallpaperFitContain: 'Fit (entire image)',\n wallpaperFitFill: 'Stretch',\n wallpaperClear: 'Turn off wallpaper',\n wallpaperDim: 'Wallpaper dimming',\n wallpaperOpacity: 'Wallpaper opacity',\n wallpaperBlur: 'Wallpaper blur',\n wallpaperPauseHidden: 'Pause when window hidden',\n wallpaperSound: 'Wallpaper sound',\n wallpaperSoundHint: 'Play video wallpaper audio. The browser may keep it silent until you click or press a key once.',\n wallpaperVolume: 'Wallpaper volume',\n wallpaperImport: 'Import',\n wallpaperImportHint: 'Copy this wallpaper into local storage, so it keeps working even if the Steam library moves or changes',\n wallpaperReimport: 'Update',\n wallpaperRemove: 'Remove',\n wallpaperUpdateAvailable: 'The workshop original changed since import — update the local copy',\n wallpaperEmpty: 'No wallpapers found. Subscribe in the Wallpaper Engine workshop, or add manual folders to the skin-wallpaper settings.',\n wallpaperTypeVideo: 'Video',\n wallpaperTypeWeb: 'Web',\n wallpaperTypeScene: 'Scene (static)',\n wallpaperTypeApp: 'Unsupported',\n wallpaperTypeImage: 'Image',\n wallpaperLoadMore: 'Load more',\n wallpaperDirs: 'Manual folders',\n wallpaperDirsEmpty: 'No manual folders yet.',\n wallpaperDirsHint: 'No Wallpaper Engine (e.g. macOS)? Point a folder at any .mp4/.webm files, a wallpaper project folder, or a folder of projects — they become your wallpaper library.',\n wallpaperDirPlaceholder: '/path/to/wallpapers or ~/Movies/wallpapers',\n wallpaperDirAdd: 'Add',\n wallpaperDirBrowse: 'Browse…',\n wallpaperDirBrowseHint: 'Pick a folder with the system file manager (Finder / Explorer)',\n wallpaperDirBrowseFailed: 'Could not open the system folder picker — type the path manually instead',\n wallpaperRatingAll: 'All',\n wallpaperRatingG: 'G',\n wallpaperRatingPg13: 'PG-13',\n wallpaperRatingR18: 'R18',\n wallpaperPagePrev: 'Previous',\n wallpaperPageNext: 'Next',\n wallpaperPageJump: 'Go',\n wallpaperPageTotal: 'Page {page} / {total}',\n customThemeTitle: 'Custom theme',\n customThemeTagline: 'A separately saved palette derived from the official default theme.',\n customThemeEdit: 'Edit',\n customThemeCloseEdit: 'Collapse',\n customThemeMode: 'Editing mode',\n customThemeLight: 'Light',\n customThemeDark: 'Dark',\n customThemeAccent: 'Accent',\n customThemeBackground: 'Background',\n customThemeForeground: 'Foreground',\n customThemeContrast: 'Contrast',\n customThemeReset: 'Restore current mode default',\n customThemeResetHint: 'Only resets the selected light or dark profile.',\n customThemeSaveFailed: 'Could not save custom theme changes.',\n uninstall: 'Uninstall',\n uninstalling: 'Uninstalling…',\n uninstallConfirm: 'Are you sure you want to uninstall \"{name}\"? Local files will be deleted.',\n uninstallFailed: 'Uninstall failed',\n verifyIntegrity: 'Verify integrity',\n verifyingIntegrity: 'Verifying…',\n verifyAllPassed: 'All {count} installed skin(s) passed integrity verification',\n verifyFoundIssues: 'Found {count} skin(s) with integrity issues',\n integrityValid: 'Verified',\n integrityTampered: 'Modified',\n integrityMissing: 'Missing files',\n integrityHooksRefused: 'Hooks refused',\n cancel: 'Cancel',\n confirm: 'Confirm',\n verifyRepaired: 'Successfully repaired {count} skin(s) with integrity issues',\n verifyRepairFailed: 'Failed to repair {count} skin(s)',\n repair: 'Repair',\n repairing: 'Repairing…',\n repaired: 'Repaired',\n}\n\nexport const zh: Record<SkinCenterKey, string> = {\n title: '皮肤',\n cardDescription: '在 GUI 内即时试穿任意皮肤,退出即完全还原;应用一键完成并自动刷新。',\n enabled: '启用皮肤中心',\n enabledHint: '关闭后停用试穿、应用与背景控件,重新打开即恢复。',\n offNote: '皮肤中心已关闭。',\n intro: '任意皮肤可即时试穿,退出即完全还原;「应用」一键持久化,页面自动刷新生效。',\n official: '官方默认',\n officialTagline: '还原 DSH 官方默认外观,不应用任何皮肤。',\n active: '当前激活',\n tryingOn: '试穿中',\n tryOn: '试穿',\n loading: '加载中…',\n exitTryOn: '退出试穿',\n apply: '应用',\n applying: '应用中…',\n restore: '恢复默认',\n applyFailed: '应用失败',\n appliedUnconfirmed: '已写入配置但尚未确认生效——开发模式请刷新页面;打包版(DSH Desktop)需重启应用后生效',\n appliedNeedRestart: '已写入配置并确认生效,但宿主未热重载——请重启 dsh 后生效',\n theme: '主题预览',\n themeLight: '亮色',\n themeDark: '暗色',\n tryOnError: '试穿失败,详见控制台',\n backgroundOpacity: '背景遮挡',\n backgroundBlurEmpty: '空对话背景模糊',\n backgroundBlurContent: '有对话背景模糊',\n inputCardBlur: '输入卡模糊',\n inputCardBlurHint: '仅模糊输入卡背后的区域,不会让整张壁纸变糊。',\n bubbleOpacity: '气泡不透明度',\n bubbleOpacityHint: '调节支持气泡 alpha 的皮肤消息气泡,例如鲸鱼妈妈。',\n backgroundBlurHint: '对话为空与有内容时分别应用不同的背景高斯模糊强度,0 为关闭。',\n backgroundBlurInert: '仅对带背景图插画的皮肤可见;官方默认无背景图。',\n backgroundHint: '即时为面板背后的背景加遮罩——数值越高越能弱化插画,帮你集中注意力。',\n backgroundHintInert: '仅对带背景图插画的皮肤(蓝色幻想 / 鲸吟)生效;官方默认无背景图,该滑块对这些皮肤自动生效。',\n wallpaperTitle: 'Wallpaper Engine',\n wallpaperEnable: '启用动态壁纸',\n wallpaperHint: '把本机 Wallpaper Engine 壁纸库用作 GUI 背景:视频、网页与场景壁纸均动态渲染(场景壁纸需要 WebGL)。',\n wallpaperLoadError: '壁纸库加载失败',\n wallpaperLibraryFound: '已检测到 Wallpaper Engine 壁纸库',\n wallpaperLibraryManual: '仅手动目录(未检测到 Wallpaper Engine 安装,可在 skin-wallpaper 设置里添加目录)',\n wallpaperLibrarySystem: '已检测到 macOS 系统壁纸(航拍与桌面图片)',\n wallpaperRefresh: '刷新',\n wallpaperMode: '渲染模式',\n wallpaperModeLive: '动态',\n wallpaperModeFrame: '静态帧',\n wallpaperFit: '适应方式',\n wallpaperFitCover: '铺满裁剪',\n wallpaperFitContain: '完整缩放',\n wallpaperFitFill: '拉伸铺满',\n wallpaperClear: '关闭壁纸',\n wallpaperDim: '壁纸暗化',\n wallpaperOpacity: '壁纸不透明度',\n wallpaperBlur: '壁纸模糊',\n wallpaperPauseHidden: '窗口隐藏时暂停',\n wallpaperSound: '壁纸声音',\n wallpaperSoundHint: '播放视频壁纸的声音。浏览器可能在首次点击或按键前保持静音。',\n wallpaperVolume: '壁纸音量',\n wallpaperImport: '导入',\n wallpaperImportHint: '把该壁纸复制到本地存储,Steam 库迁移或变动后仍可继续使用',\n wallpaperReimport: '更新',\n wallpaperRemove: '移除',\n wallpaperUpdateAvailable: '工坊原件在导入后有更新——同步更新本地副本',\n wallpaperEmpty: '未发现壁纸。可先在 Wallpaper Engine 创意工坊订阅,或在 skin-wallpaper 设置里添加手动目录。',\n wallpaperTypeVideo: '视频',\n wallpaperTypeWeb: '网页',\n wallpaperTypeScene: '场景(静态)',\n wallpaperTypeApp: '不支持',\n wallpaperTypeImage: '静态图片',\n wallpaperLoadMore: '加载更多',\n wallpaperDirs: '手动目录',\n wallpaperDirsEmpty: '还没有手动目录。',\n wallpaperDirsHint: '没有 Wallpaper Engine(如 macOS)?把任意 .mp4/.webm 视频、单个壁纸项目文件夹或项目合集文件夹加进来,就是你的壁纸库。',\n wallpaperDirPlaceholder: '/path/to/wallpapers 或 ~/Movies/wallpapers',\n wallpaperDirAdd: '添加',\n wallpaperDirBrowse: '浏览…',\n wallpaperDirBrowseHint: '通过系统文件管理器(访达 / 资源管理器)选择文件夹',\n wallpaperDirBrowseFailed: '无法打开系统目录选择框——请手动输入路径',\n wallpaperRatingAll: '全部',\n wallpaperRatingG: 'G',\n wallpaperRatingPg13: 'PG-13',\n wallpaperRatingR18: 'R18',\n wallpaperPagePrev: '上一页',\n wallpaperPageNext: '下一页',\n wallpaperPageJump: '跳转',\n wallpaperPageTotal: '第 {page} / {total} 页',\n customThemeTitle: '自定义主题',\n customThemeTagline: '基于官方默认主题生成并独立保存的配色方案。',\n customThemeEdit: '编辑',\n customThemeCloseEdit: '收起',\n customThemeMode: '编辑模式',\n customThemeLight: '浅色',\n customThemeDark: '深色',\n customThemeAccent: '强调色',\n customThemeBackground: '背景色',\n customThemeForeground: '前景色',\n customThemeContrast: '对比度',\n customThemeReset: '恢复当前模式默认',\n customThemeResetHint: '只重置当前选择的浅色或深色配置。',\n customThemeSaveFailed: '自定义主题修改保存失败。',\n uninstall: '卸载',\n uninstalling: '卸载中…',\n uninstallConfirm: '确定要卸载皮肤「{name}」吗?本地文件将被永久删除。',\n uninstallFailed: '卸载失败',\n verifyIntegrity: '验证完整性',\n verifyingIntegrity: '正在验证…',\n verifyAllPassed: '所有 {count} 款已安装皮肤完整性正常',\n verifyFoundIssues: '发现 {count} 款皮肤存在完整性异常',\n verifyRepaired: '已自动修复 {count} 款皮肤的完整性异常',\n verifyRepairFailed: '{count} 款皮肤自动修复失败',\n repair: '修复',\n repairing: '修复中…',\n repaired: '已修复',\n integrityValid: '完整',\n integrityTampered: '文件已修改',\n integrityMissing: '缺少文件',\n integrityHooksRefused: 'Hooks 已拒绝',\n cancel: '取消',\n confirm: '确定',\n}\n","/**\n * Effect ledger (issue #506, contract section 6).\n *\n * Every runtime effect a skin activation creates — style tags, CSS variable\n * overrides, decoration-layer content, listeners, hook cleanups — is recorded\n * here as an append-only entry bound to its activation identity. Switching\n * skins releases the old activation's entries in reverse order; disposal is\n * idempotent and may run 0, 1 or N times.\n *\n * lifecycleScope split:\n * - \"activation\": everything injectable — released on every skin switch;\n * - \"component\": skin static assets and the user's selection — survive\n * switches, reloads and HMR. The ledger only tracks activation scope.\n *\n * Pure logic, no DOM types required (entries are opaque teardown closures).\n */\n\nexport type EffectKind = 'create' | 'bind' | 'replace' | 'release' | 'cleanup-failed'\n\nexport interface EffectLedgerEntry {\n /** Monotonic sequence number (append-only). */\n seq: number\n activationId: number\n kind: EffectKind\n /** Human-readable label for diagnostics (e.g. \"style:skin.css\"). */\n label: string\n /** For replace: the seq of the superseded entry. */\n replacesSeq?: number\n at: number\n}\n\ninterface LiveEffect {\n seq: number\n label: string\n teardown: () => void\n released: boolean\n}\n\nexport interface EffectLedger {\n /** Start a new activation identity. Returns its id. */\n beginActivation(): number\n /**\n * Record an effect under the activation. The teardown must be idempotent.\n * Throws if the activation was already disposed (fail-closed: no orphan\n * effects after a switch).\n */\n record(activationId: number, label: string, teardown: () => void): number\n /**\n * Record that `label` replaces a previous entry (e.g. decoration-layer\n * content swap). The replaced entry is released immediately.\n */\n replace(activationId: number, label: string, previousSeq: number | undefined, teardown: () => void): number\n /**\n * Release every live effect of the activation, newest first. Idempotent;\n * individual teardown failures are caught and logged as cleanup-failed\n * entries (one failing teardown never blocks the rest).\n */\n disposeActivation(activationId: number): void\n /** Whether disposeActivation has run for this activation. */\n isDisposed(activationId: number): boolean\n /** Read-only view of the append-only log (diagnostics / tests). */\n entries(): readonly EffectLedgerEntry[]\n}\n\nexport function createEffectLedger(now: () => number = () => Date.now()): EffectLedger {\n let seq = 0\n let nextActivation = 1\n const log: EffectLedgerEntry[] = []\n const live = new Map<number, LiveEffect[]>()\n const disposed = new Set<number>()\n\n function push(activationId: number, kind: EffectKind, label: string, replacesSeq?: number): number {\n seq += 1\n log.push({ seq, activationId, kind, label, replacesSeq, at: now() })\n return seq\n }\n\n function release(effect: LiveEffect, activationId: number): void {\n if (effect.released) return\n effect.released = true\n push(activationId, 'release', effect.label)\n try {\n effect.teardown()\n } catch {\n // A failing teardown must never block the remaining cleanup; the\n // failure itself is a ledger fact for diagnostics.\n push(activationId, 'cleanup-failed', effect.label)\n }\n }\n\n return {\n beginActivation() {\n const id = nextActivation++\n live.set(id, [])\n push(id, 'create', 'activation')\n return id\n },\n\n record(activationId, label, teardown) {\n const bucket = live.get(activationId)\n if (!bucket || disposed.has(activationId)) {\n throw new Error(`effect \"${label}\" recorded on disposed/unknown activation ${activationId}`)\n }\n const entrySeq = push(activationId, 'create', label)\n bucket.push({ seq: entrySeq, label, teardown, released: false })\n return entrySeq\n },\n\n replace(activationId, label, previousSeq, teardown) {\n const bucket = live.get(activationId)\n if (!bucket || disposed.has(activationId)) {\n throw new Error(`effect \"${label}\" replaced on disposed/unknown activation ${activationId}`)\n }\n if (previousSeq !== undefined) {\n const previous = bucket.find((e) => e.seq === previousSeq)\n if (previous) release(previous, activationId)\n }\n const entrySeq = push(activationId, 'replace', label, previousSeq)\n bucket.push({ seq: entrySeq, label, teardown, released: false })\n return entrySeq\n },\n\n disposeActivation(activationId) {\n if (disposed.has(activationId)) return\n disposed.add(activationId)\n const bucket = live.get(activationId) ?? []\n for (const effect of [...bucket].reverse()) release(effect, activationId)\n },\n\n isDisposed(activationId) {\n return disposed.has(activationId)\n },\n\n entries() {\n return log\n },\n }\n}\n","/**\n * Semantic adapter (issue #506, contract section 6, L2 compat adapter).\n *\n * One merged MutationObserver that stamps the semantic-attribute enumeration\n * (contracts/semantic-attrs-v1.md) onto the official shell DOM and onto\n * plugin roots that already expose stable anchors. This is explicitly a\n * COMPAT adapter — not a permanent public contract:\n * - official areas migrate to first-party attributes when the upstream\n * theme seam lands (then these rules are re-evaluated for deletion);\n * - third-party plugin areas stay here long-term (plugins that opt in\n * output the attributes themselves and the adapter becomes a no-op).\n *\n * Properties:\n * - merged: a single observer handles every rule;\n * - idempotent: re-tagging an already-correct element is a no-op, so React\n * re-renders simply get re-stamped when their nodes are re-added;\n * - fail-closed diagnostics: rules that match nothing and selectors the\n * engine rejects are reported, never thrown into the page;\n * - the adapter never REMOVES attributes it did not set; disposal only\n * disconnects the observer (stamping is cosmetic and scopes itself under\n * html[data-dsh-skin] consumers).\n * @module @linxin666/dsh-client-ui-skin-center/runtime/semantic-adapter\n */\n\nexport type SemanticAttr = 'data-dsh-surface' | 'data-dsh-part' | 'data-dsh-plugin'\n\nexport interface SemanticRule {\n /** CSS selector matched against added/existing elements. */\n selector: string\n /** Attribute(s) applied on match. */\n attrs: readonly (readonly [SemanticAttr, string])[]\n /** Why this rule exists / what it anchors (audit trail). */\n note: string\n}\n\n/**\n * The v1 rule table. Single ownership: only the skin-center edits this.\n * Anchors verified against @deepseek-ai rc.7 (see docs/archive survey).\n */\nexport const SEMANTIC_RULES_V1: readonly SemanticRule[] = [\n // ---- surfaces (official shell) ----\n { selector: '[data-slot=\"root\"]', attrs: [['data-dsh-surface', 'root']], note: 'ui-renderer root outlet' },\n { selector: '[data-slot=\"sidebar\"]', attrs: [['data-dsh-surface', 'sidebar']], note: 'layout sidebar outlet' },\n { selector: '[data-slot=\"conversation\"]', attrs: [['data-dsh-surface', 'conversation']], note: 'layout conversation outlet' },\n { selector: '[data-slot=\"conversation.session.header\"]', attrs: [['data-dsh-surface', 'session-header']], note: 'conversation header outlet' },\n { selector: '[data-slot=\"conversation.composer\"]', attrs: [['data-dsh-surface', 'composer']], note: 'composer chain outlet' },\n { selector: '[data-slot=\"details\"]', attrs: [['data-dsh-surface', 'details']], note: 'layout details outlet' },\n { selector: '[data-shell-overlay]', attrs: [['data-dsh-surface', 'overlay']], note: 'frame overlay attribute' },\n { selector: '[data-slot=\"shell.overlay\"]', attrs: [['data-dsh-surface', 'overlay']], note: 'shell overlay outlet' },\n {\n selector: '[role=\"dialog\"]:has([data-slot=\"settings.section\"])',\n attrs: [['data-dsh-surface', 'settings']],\n note: 'settings dialog (composite: dialog containing the section outlet)',\n },\n // ---- shell parts ----\n { selector: '[data-chat-flow-kind]', attrs: [['data-dsh-part', 'message-row']], note: 'chat flow item' },\n { selector: '[data-streaming]', attrs: [['data-dsh-part', 'message-body']], note: 'assistant markdown root' },\n { selector: '[data-conversation-scroll]', attrs: [['data-dsh-part', 'scrollport']], note: 'conversation scrollport' },\n { selector: 'textarea[data-phase]', attrs: [['data-dsh-part', 'composer-input']], note: 'composer textarea' },\n { selector: '[data-decoration=\"chip\"]', attrs: [['data-dsh-part', 'composer-chip']], note: 'composer reference chip' },\n { selector: '[data-queue-dock]', attrs: [['data-dsh-part', 'queue-dock']], note: 'queued turns dock' },\n { selector: '[data-turn-tail]', attrs: [['data-dsh-part', 'turn-tail']], note: 'turn tail row' },\n { selector: '[data-side]', attrs: [['data-dsh-part', 'resize-handle']], note: 'column resize handle' },\n {\n selector: 'button[class*=\"newSession\"]',\n attrs: [['data-dsh-part', 'new-session']],\n note: 'sidebar new-session action (compat seam shields skins from localized labels)',\n },\n // ---- plugin roots (plugins without stable anchors opt in via AGENTS.md) ----\n {\n selector: '[data-dsh-taskboard-view], [data-dsh-taskboard-board], [data-dsh-taskboard-entry]',\n attrs: [['data-dsh-plugin', 'task-board']],\n note: 'task-board panel/board/sidebar entry',\n },\n {\n selector: '[data-dsh-ssh-view], [data-dsh-ssh-entry]',\n attrs: [['data-dsh-plugin', 'ssh']],\n note: 'ssh panel/sidebar entry',\n },\n {\n selector: '[data-gitgraph-chip-anchor], [data-gitgraph-dialog]',\n attrs: [['data-dsh-plugin', 'git-graph']],\n note: 'git-graph chip/dialog',\n },\n {\n selector: '[data-dsh-pet-root]',\n attrs: [['data-dsh-plugin', 'pet']],\n note: 'pet global root',\n },\n // ---- family parts ----\n {\n selector: '[data-dsh-taskboard-entry], [data-dsh-ssh-entry]',\n attrs: [['data-dsh-part', 'sidebar-entry']],\n note: 'shared injected sidebar entry rows',\n },\n]\n\nexport interface SemanticAdapterDiagnostics {\n /** Rules whose selector the engine rejects (dropped, never retried). */\n invalidRules: string[]\n /** Rules that matched zero elements in the latest full pass. */\n unmatchedRules: string[]\n /** Total attributes stamped since start. */\n stamped: number\n}\n\nexport interface SemanticAdapter {\n start(): void\n stop(): void\n diagnostics(): SemanticAdapterDiagnostics\n readonly running: boolean\n}\n\ninterface LiveRule {\n rule: SemanticRule\n /** False once the engine rejected the selector. */\n usable: boolean\n /** Elements matched in the latest full pass. */\n matchedInPass: number\n}\n\nexport function createSemanticAdapter(doc: Document): SemanticAdapter {\n const rules: LiveRule[] = SEMANTIC_RULES_V1.map((rule) => ({ rule, usable: true, matchedInPass: 0 }))\n let observer: MutationObserver | null = null\n let stamped = 0\n let running = false\n\n const applyRule = (live: LiveRule, el: Element): void => {\n if (!live.usable) return\n let hit = false\n try {\n hit = el.matches(live.rule.selector)\n } catch {\n live.usable = false\n return\n }\n if (!hit) return\n live.matchedInPass += 1\n for (const [name, value] of live.rule.attrs) {\n if (el.getAttribute(name) !== value) {\n el.setAttribute(name, value)\n stamped += 1\n }\n }\n }\n\n const applyToTree = (rootEl: Element): void => {\n for (const live of rules) {\n if (!live.usable) continue\n applyRule(live, rootEl)\n let matches: Element[] = []\n try {\n matches = Array.from(rootEl.querySelectorAll(live.rule.selector))\n } catch {\n live.usable = false\n continue\n }\n for (const el of matches) applyRule(live, el)\n }\n }\n\n const fullPass = (): void => {\n for (const live of rules) live.matchedInPass = 0\n if (doc.documentElement) applyToTree(doc.documentElement)\n }\n\n return {\n get running() {\n return running\n },\n\n start() {\n if (running) return\n running = true\n fullPass()\n observer = new doc.defaultView!.MutationObserver((records) => {\n try {\n for (const record of records) {\n for (const node of Array.from(record.addedNodes)) {\n if (node.nodeType === 1) applyToTree(node as Element)\n }\n }\n } catch {\n // Fail-closed: a tagging error must never break the host page.\n }\n })\n observer.observe(doc.body ?? doc.documentElement, { childList: true, subtree: true })\n },\n\n stop() {\n running = false\n observer?.disconnect()\n observer = null\n },\n\n diagnostics() {\n return {\n invalidRules: rules.filter((r) => !r.usable).map((r) => r.rule.selector),\n unmatchedRules: rules.filter((r) => r.usable && r.matchedInPass === 0).map((r) => r.rule.selector),\n stamped,\n }\n },\n }\n}\n","/**\n * Shared shell rendering corrections for every visual mode owned by the skin\n * center (issue #954). The official shell exposes stable slot / composer\n * anchors, while the workspace-list fade itself is still a CSS-module class.\n * Keep that fallback scoped below sidebar.workspaces so an unrelated animation\n * or overlay whose class contains \"fade\" is never affected.\n *\n * The stylesheet is inert for the stock look: a catalog skin, custom theme or\n * wallpaper must be active. It is installed once per runtime and removed with\n * that runtime, so disabling the plugin restores the shell unchanged.\n * @module @linxin666/dsh-client-ui-skin-center/runtime/shell-rendering\n */\n\n/** Marker owned by the shared shell-rendering stylesheet. */\nexport const SHELL_RENDERING_STYLE_ATTR = 'data-dsh-shell-rendering'\n\n/** Fallback composer seat height for scrollport bottom clearance (px). */\nexport const DEFAULT_COMPOSER_CLEARANCE_PX = 100\n\nconst ACTIVE_VISUAL_SELECTOR = [\n 'html[data-dsh-skin]',\n 'html[data-dsh-custom-theme]:not([data-dsh-skin])',\n 'html[data-dsh-wallpaper-active]',\n].join(', ')\n\nconst COMPOSER_SEAT_SELECTORS = [\n '[data-slot=\"conversation.composer\"]',\n '[data-composer-seat]',\n '[data-dsh-surface=\"composer\"]',\n]\n\n/** Build the inert-by-default public rendering corrections. */\nexport function shellRenderingCss(): string {\n const scopes = ACTIVE_VISUAL_SELECTOR.split(', ')\n const scoped = (selector: string): string => scopes.map(scope => `${scope} ${selector}`).join(',\\n')\n return `\n /* Viewport lock: prevent outer page scrollbar and viewport\n displacement during element focus/scrollIntoView. */\n ${ACTIVE_VISUAL_SELECTOR},\n ${scoped('body')} {\n height: 100% !important;\n width: 100% !important;\n overflow: hidden !important;\n margin: 0 !important;\n padding: 0 !important;\n }\n ${scoped('[data-slot=\"sidebar.workspaces\"] [class*=\"_fade\"]')} {\n background: none !important;\n background-image: none !important;\n }\n ${scoped('[data-composer-card] textarea[data-phase]::placeholder')},\n ${scoped('textarea[data-dsh-part=\"composer-input\"]::placeholder')} {\n color: var(--dsw-alias-label-secondary, var(--dsw-alias-label-caption)) !important;\n -webkit-text-fill-color: var(--dsw-alias-label-secondary, var(--dsw-alias-label-caption)) !important;\n opacity: 1 !important;\n }\n ${scoped('[data-phase=\"active\"] [data-slot=\"conversation.input.dock\"] > *')},\n ${scoped('[data-phase=\"active\"] [data-slot=\"conversation.composer.dock\"] > *')} {\n /* One skin-driven accessory surface for task and statistics docks. Skins\n automatically follow their existing semantic theme tokens and may\n override the --dsh-composer-accessory-* variables for a stronger\n signature without coupling this adapter to a specific catalog skin. */\n background: var(--dsh-composer-accessory-bg, var(--dsw-specific-tip, var(--dsw-alias-bg-layer-1))) !important;\n color: var(--dsh-composer-accessory-color, var(--dsw-alias-label-tertiary)) !important;\n border: var(--dsh-composer-accessory-border, none) !important;\n border-radius: var(--dsh-composer-accessory-radius, 12px) !important;\n box-shadow: var(--dsh-composer-accessory-shadow, var(--dsw-shadow-lv1, 0 2px 10px rgba(7, 20, 38, 0.18)));\n backdrop-filter: blur(var(--dsh-composer-accessory-blur, var(--dsh-input-card-blur, 10px))) !important;\n -webkit-backdrop-filter: blur(var(--dsh-composer-accessory-blur, var(--dsh-input-card-blur, 10px))) !important;\n }\n ${scoped('[data-phase=\"active\"] [data-slot=\"conversation.composer.dock\"] > *')} {\n margin-top: var(--dsh-composer-accessory-gap, 4px);\n margin-bottom: var(--dsh-composer-accessory-gap, 4px);\n padding-top: 2px;\n padding-bottom: 2px;\n }\n ${scoped('[data-slot=\"conversation.input.dock\"] > [data-goal-bar=\"true\"][data-goal-bar=\"true\"][data-goal-bar=\"true\"]')} {\n /* The host goal dock spans the full composer seat and contains its own\n centered compact bar. Do not paint the outer dock as an accessory: that\n creates a viewport-wide veil behind the active-goal chip. The repeated\n stable marker deliberately raises specificity above catalog-skin dock\n selectors that load after this shared adapter. */\n background: transparent !important;\n border: 0 !important;\n border-radius: 0 !important;\n box-shadow: none !important;\n backdrop-filter: none !important;\n -webkit-backdrop-filter: none !important;\n }\n ${scoped('[data-conversation-scroll]')},\n ${scoped('[data-dsh-part=\"scrollport\"]')} {\n /* The composer is the scrollport's final in-flow child. Reserving physical\n padding after it lifts the active dock by one composer height and also\n shifts the hero above center. */\n padding-bottom: 0 !important;\n }\n /* #978 / #1133: Line-level scroll-margin retains scrollIntoView() clearance\n above the sticky composer without placing a scrollport-level scroll-padding\n that breaks browser caret-reveal geometry (which caused micro-scrolling on\n every keystroke while reading history). */\n ${scoped('[data-conversation-scroll] [data-chat-anchor-key]')},\n ${scoped('[data-conversation-scroll] [data-chat-flow-kind]')},\n ${scoped('[data-conversation-scroll] [data-dsh-part=\"message-row\"]')},\n ${scoped('[data-conversation-scroll] [data-turn-tail]')},\n ${scoped('[data-conversation-scroll] [class*=\"_userRow\"]')},\n ${scoped('[data-conversation-scroll] [class*=\"_compactionRow\"]')},\n ${scoped('[data-conversation-scroll] [class*=\"_contextRow\"]')},\n ${scoped('[data-conversation-scroll] [class*=\"_turnErrorRow\"]')} {\n scroll-margin-bottom: var(--dsh-composer-height, ${DEFAULT_COMPOSER_CLEARANCE_PX}px) !important;\n }\n /* #1117: The upstream recommended badge pairs two background-fill tokens\n as bg + text — in dark mode, skins like Blue Fantasy collapse them to\n near-identical dark navy values (contrast ~1:1). Override the text\n color to a readable foreground and tweak the background for contrast. */\n body[data-ds-dark-theme] ${scoped('[data-question-key] [class*=\"_badge\"]')},\n body[data-ds-dark-theme] ${scoped('[data-question-scroll] [class*=\"_badge\"]')} {\n color: var(--dsw-alias-label-primary, #ffffff) !important;\n background: var(--dsw-alias-interactive-bg-active, color-mix(in srgb, var(--dsw-alias-button-info-fill, #4a5fa8) 50%, transparent)) !important;\n }\n `\n}\n\n/** Install the shared corrections and return their idempotent teardown. */\nexport function installShellRenderingAdapter(doc: Document): () => void {\n if (doc.head === null) return () => {}\n const existing = doc.head.querySelector<HTMLStyleElement>(`style[${SHELL_RENDERING_STYLE_ATTR}]`)\n if (existing !== null) return () => {}\n\n const style = doc.createElement('style')\n style.setAttribute(SHELL_RENDERING_STYLE_ATTR, '')\n style.textContent = shellRenderingCss()\n doc.head.appendChild(style)\n\n const win = doc.defaultView\n try { win?.scrollTo?.(0, 0) } catch {}\n let resizeObserver: ResizeObserver | null = null\n let mutationObserver: MutationObserver | null = null\n let observedComposer: Element | null = null\n\n const syncHeight = (): void => {\n if (doc.body === null) return\n const composer = doc.body.querySelector(COMPOSER_SEAT_SELECTORS.join(', '))\n if (composer !== null) {\n if (observedComposer !== composer) {\n if (observedComposer !== null && resizeObserver !== null) {\n resizeObserver.unobserve(observedComposer)\n }\n observedComposer = composer\n if (resizeObserver !== null) {\n resizeObserver.observe(composer)\n }\n }\n const rect = composer.getBoundingClientRect()\n if (rect.height > 0) {\n doc.documentElement?.style.setProperty('--dsh-composer-height', `${Math.ceil(rect.height)}px`)\n }\n }\n }\n\n if (win !== null && typeof win.ResizeObserver === 'function') {\n resizeObserver = new win.ResizeObserver(() => syncHeight())\n }\n\n if (win !== null && typeof win.MutationObserver === 'function' && doc.body !== null) {\n mutationObserver = new win.MutationObserver(() => syncHeight())\n mutationObserver.observe(doc.body, { childList: true, subtree: true })\n }\n\n syncHeight()\n\n let disposed = false\n return () => {\n if (disposed) return\n disposed = true\n if (resizeObserver !== null) {\n resizeObserver.disconnect()\n resizeObserver = null\n }\n if (mutationObserver !== null) {\n mutationObserver.disconnect()\n mutationObserver = null\n }\n observedComposer = null\n doc.documentElement?.style.removeProperty('--dsh-composer-height')\n style.remove()\n }\n}\n","/**\n * Fixed decoration layers (issue #506, contract section 6).\n *\n * Six skin-center-owned, non-interactive containers mounted once per\n * document (component scope): background / ambient / top / bottom / sidebar /\n * foreground. Skins fill them per activation (background media, scrims,\n * strips); the CONTENT is activation scope — on every switch the controller\n * replaces it through the effect ledger.\n *\n * Guarantees:\n * - pointer-events: none always (decoration must never eat clicks);\n * - the layer elements themselves survive skin switches, reloads of the\n * skin runtime, and HMR (ensure* is idempotent);\n * - stacking stays below the official shell overlay: background/ambient sit\n * behind the app, the strip/foreground layers use moderate z-indices that\n * lose to dialogs/overlays (official overlay paints above 1000);\n * - the background layer carries its own compositor layer (will-change:\n * transform): a full-viewport skin background image is expensive to\n * re-rasterize, and without isolation Chromium re-rasterizes it in\n * horizontal bands whenever unrelated repaint bursts (streaming chat,\n * animated pets, overlay menus) invalidate the same area — visible as\n * vertical band flicker (issue #1013).\n * @module @linxin666/dsh-client-ui-skin-center/runtime/decoration-layers\n */\n\nexport const DECORATION_LAYER_NAMES = [\n 'background',\n 'ambient',\n 'top',\n 'bottom',\n 'sidebar',\n 'foreground',\n] as const\n\nexport type DecorationLayerName = (typeof DECORATION_LAYER_NAMES)[number]\n\nexport type DecorationLayers = Record<DecorationLayerName, HTMLElement>\n\nconst LAYER_ATTR = 'data-dsh-skin-layer'\n\n/**\n * Per-layer paint order. The background sits at -2: negative z-index\n * elements paint ABOVE the html/body backgrounds (so a skin's own opaque\n * root background-color renders BEHIND its art — the v1 layering) yet below\n * every panel surface. It shares -2 with the WE scrim, which never paints\n * at the same time (an active WE wallpaper suppresses skin media, enforced\n * by the controller). The skin-background blur veil (-1) still samples the\n * art above it. Ambient effects paint above the veils; the strip/foreground\n * layers stay below the official overlay band (>=1000).\n */\nconst LAYER_STYLE: Record<DecorationLayerName, string> = {\n // Explicit longhands only: the inset shorthand has burned us once (a\n // mid-session layer lost its bottom edge), longhands parse everywhere.\n background: 'position:fixed;top:0;right:0;bottom:0;left:0;z-index:-2;pointer-events:none;will-change:transform;',\n ambient: 'position:fixed;top:0;right:0;bottom:0;left:0;z-index:30;pointer-events:none;',\n top: 'position:fixed;top:0;left:0;right:0;z-index:40;pointer-events:none;',\n bottom: 'position:fixed;bottom:0;left:0;right:0;z-index:40;pointer-events:none;',\n sidebar: 'position:fixed;top:0;bottom:0;left:0;z-index:40;pointer-events:none;',\n foreground: 'position:fixed;top:0;right:0;bottom:0;left:0;z-index:41;pointer-events:none;',\n}\n\nfunction ensureOne(doc: Document, name: DecorationLayerName): HTMLElement {\n const existing = doc.querySelector<HTMLElement>(`[${LAYER_ATTR}=\"${name}\"]`)\n if (existing) {\n // Never trust a previous writer's styles: re-assert invariants.\n existing.style.cssText = LAYER_STYLE[name]\n return existing\n }\n const el = doc.createElement('div')\n el.setAttribute(LAYER_ATTR, name)\n el.setAttribute('aria-hidden', 'true')\n el.style.cssText = LAYER_STYLE[name]\n doc.body.appendChild(el)\n return el\n}\n\n/**\n * Ensure all six layers exist and return their handles. Idempotent; safe to\n * call on every activation.\n */\nexport function ensureDecorationLayers(doc: Document): DecorationLayers {\n return {\n background: ensureOne(doc, 'background'),\n ambient: ensureOne(doc, 'ambient'),\n top: ensureOne(doc, 'top'),\n bottom: ensureOne(doc, 'bottom'),\n sidebar: ensureOne(doc, 'sidebar'),\n foreground: ensureOne(doc, 'foreground'),\n }\n}\n\n/**\n * Replace one layer's content (activation scope). Returns a teardown that\n * removes exactly the nodes this call added — idempotent, ledger-ready.\n */\nexport function setLayerContent(\n layer: HTMLElement,\n nodes: Iterable<Node>,\n): () => void {\n const added = [...nodes]\n for (const node of added) layer.appendChild(node)\n let done = false\n return () => {\n if (done) return\n done = true\n for (const node of added) node.parentNode?.removeChild(node)\n }\n}\n\n/** Remove every node an activation left in a layer (used on dispose). */\nexport function clearLayer(layer: HTMLElement): void {\n while (layer.firstChild) layer.removeChild(layer.firstChild)\n}\n\n/**\n * Build the background media element for a manifest backgroundMedia layer.\n * Returns null when the theme variant has no media. The element fills the\n * background layer; the scrim (when declared) is a sibling overlay.\n */\nexport function buildBackgroundMedia(\n doc: Document,\n layer: { type: 'image' | 'video'; src: string; scrim?: string },\n assetBase: string,\n): HTMLElement[] {\n const nodes: HTMLElement[] = []\n const fullBleed = 'position:absolute;top:0;right:0;bottom:0;left:0;width:100%;height:100%;object-fit:cover;'\n if (layer.type === 'image') {\n const img = doc.createElement('img')\n img.src = `${assetBase}/${layer.src}`\n img.alt = ''\n img.setAttribute('aria-hidden', 'true')\n img.style.cssText = fullBleed\n nodes.push(img)\n } else {\n const video = doc.createElement('video')\n video.src = `${assetBase}/${layer.src}`\n video.muted = true\n video.loop = true\n video.autoplay = true\n video.playsInline = true\n video.setAttribute('aria-hidden', 'true')\n video.style.cssText = fullBleed\n nodes.push(video)\n }\n if (layer.scrim) {\n const scrim = doc.createElement('div')\n scrim.setAttribute('aria-hidden', 'true')\n scrim.style.cssText = `position:absolute;inset:0;background:${layer.scrim};`\n nodes.push(scrim)\n }\n return nodes\n}\n","/**\n * Skin runtime controller (issue #506, contract section 8) — the browser\n * switch engine. One switch is one NEW activation identity:\n *\n * switchTo(id):\n * 1. seq = ++latestRequest (latest-request-wins)\n * 2. activation = ledger.beginActivation()\n * 3. fetch stylesheet (+ patches) (already scoped + whitelisted host-side)\n * 4. install <style> tags, background media, hooks (all ledger-recorded)\n * 5. if seq is stale -> dispose this activation and bail\n * 6. flip html[data-dsh-skin] (the atomic visual cut)\n * 7. dispose the previous activation\n * 8. persist the selection\n *\n * Every step before the flip is discardable; a stale or failed switch leaves\n * the previous skin fully intact. hooks import/apply errors are caught: the\n * static part (stylesheet, media) stays active — the escape hatch can never\n * take the skin down with it.\n *\n * lifecycleScope split: the ledger tracks activation scope; the catalog\n * snapshot, the decoration layer elements and the persisted selection are\n * component scope and survive every switch.\n * @module @linxin666/dsh-client-ui-skin-center/runtime/skin-controller\n */\n\nimport type { EffectLedger } from './effect-ledger.ts'\nimport { buildBackgroundMedia, clearLayer, ensureDecorationLayers } from './decoration-layers.ts'\nimport type { DecorationLayers } from './decoration-layers.ts'\nimport { setSceneBackdropActive } from './backdrop-scene.ts'\n\n/** Catalog entry shape the controller needs (mirrors the v2 catalog route). */\nexport interface ControllerSkinEntry {\n manifest: {\n id: string\n contributes: {\n stylesheet: string\n patches?: string\n backgroundMedia?: {\n light?: { type: 'image' | 'video'; src: string; scrim?: string }\n dark?: { type: 'image' | 'video'; src: string; scrim?: string }\n }\n }\n facets?: { client?: { entry: string; apiVersion: string } }\n }\n}\n\nexport interface SkinControllerDeps {\n doc: Document\n ledger: EffectLedger\n /** Same-origin base of the v2 API (default /api/skin-center/v2). */\n apiBase?: string\n /** fetch injection for tests. */\n fetchImpl?: typeof fetch\n /** Persist the selection (POST /active by default). */\n persist?: (id: string | null) => Promise<void>\n /** Current light/dark theme (defaults to body[data-ds-dark-theme]). */\n themeGet?: () => 'light' | 'dark'\n /**\n * Theme-change subscription. The default observes the official\n * body[data-ds-dark-theme] attribute (the same ground truth v1 skins\n * used), so hooks get live theme flips out of the box.\n */\n themeSubscribe?: (listener: (theme: 'light' | 'dark') => void) => () => void\n /**\n * Stylesheet loader seam. Default installs a <link rel=\"stylesheet\"> and\n * awaits its load (relative url() inside the served CSS resolves against\n * the route URL — inlining into <style> would break asset resolution).\n */\n loadStylesheet?: (href: string) => Promise<void>\n /** hooks.mjs dynamic import seam for tests. */\n importHooks?: (url: string) => Promise<unknown>\n /**\n * Background-media priority (issue #506): when this returns true the\n * skin's manifest backgroundMedia is NOT painted — the Wallpaper Engine\n * wallpaper (and the user's manual background) outrank it. Re-evaluated\n * on every activation and on refresh().\n */\n suppressBackgroundMedia?: () => boolean\n /** Diagnostics sink (switch failures, hook errors). */\n onError?: (message: string, error: unknown) => void\n}\n\nexport interface SkinControllerState {\n /** The currently applied skin (null = stock look). */\n active: string | null\n /** The previewed skin id (null = the stock look is being previewed). */\n trying: string | null\n /** Whether a try-on preview is live (distinguishes previewing the stock\n * look from having no preview). */\n previewing: boolean\n}\n\nexport interface SkinController {\n /** Current applied skin id (null = stock look). */\n readonly active: string | null\n /** The fixed decoration layer handles (component scope). */\n readonly layers: DecorationLayers\n /**\n * Switch to a skin (or null for stock). Latest request wins; resolves to\n * the id that is actually active after this call settles (which may be a\n * newer one if a later switch superseded it).\n */\n switchTo(id: string | null, entry: ControllerSkinEntry | null): Promise<string | null>\n /**\n * Preview a skin without persisting it. The committed skin is remembered;\n * exitTryOn() restores it. Try-on of the stock look passes null.\n */\n tryOn(id: string | null, entry: ControllerSkinEntry | null): Promise<string | null>\n /** Leave the preview, restoring the committed skin. */\n exitTryOn(): Promise<string | null>\n /** React-friendly store: subscribe + snapshot of {active, trying}. */\n subscribe(listener: () => void): () => void\n getState(): SkinControllerState\n /**\n * Re-apply the current committed skin without persisting (e.g. the\n * wallpaper bridge just toggled, flipping background-media priority).\n * A full fresh activation — latest-request-wins keeps it race-safe.\n */\n refresh(): Promise<string | null>\n /** Dispose the current activation (e.g. on plugin teardown). */\n shutdown(): void\n}\n\ninterface HooksModule {\n default?: () => { apply(ctx: unknown): void; dispose?: () => void }\n}\n\nexport function createSkinController(deps: SkinControllerDeps): SkinController {\n const doc = deps.doc\n const ledger = deps.ledger\n const apiBase = deps.apiBase ?? '/api/skin-center/v2'\n const fetchImpl = deps.fetchImpl ?? fetch.bind(doc.defaultView)\n const layers = ensureDecorationLayers(doc)\n const onError = deps.onError ?? (() => {})\n\n const themeGet = deps.themeGet ?? (() =>\n (doc.body?.hasAttribute('data-ds-dark-theme') ? 'dark' : 'light'))\n const themeSubscribe = deps.themeSubscribe ?? ((listener) => {\n let last = themeGet()\n const observer = new doc.defaultView!.MutationObserver(() => {\n const next = themeGet()\n if (next !== last) {\n last = next\n listener(next)\n }\n })\n if (doc.body) observer.observe(doc.body, { attributes: true, attributeFilter: ['data-ds-dark-theme'] })\n return () => observer.disconnect()\n })\n /**\n * Re-paint the current activation's background media for the live\n * light/dark theme (the controller owns the layer, so a theme flip must\n * swap the variant the same way an activation does). No-op when there is\n * nothing painted or the manifest carries no backgroundMedia.\n */\n function repaintBackgroundForTheme(): void {\n if (active === null || currentActivation === null || lastEntry === null) return\n const media = lastEntry.manifest.contributes.backgroundMedia\n if (!media) return\n if (deps.suppressBackgroundMedia?.() === true) return\n const variant = themeGet() === 'dark' ? (media.dark ?? media.light) : (media.light ?? media.dark)\n if (!variant) return\n const assetBase = `${apiBase}/skins/${lastEntry.manifest.id}`\n setBackgroundLayer(currentActivation, buildBackgroundMedia(doc, variant, assetBase))\n }\n const unsubscribeTheme = themeSubscribe(() => repaintBackgroundForTheme())\n const loadStylesheet = deps.loadStylesheet ?? ((href: string) => new Promise<void>((resolveLink, rejectLink) => {\n const link = doc.createElement('link')\n link.rel = 'stylesheet'\n link.href = href\n const timer = setTimeout(() => rejectLink(new Error(`stylesheet load timeout: ${href}`)), 15000)\n link.onload = () => { clearTimeout(timer); resolveLink() }\n link.onerror = () => { clearTimeout(timer); rejectLink(new Error(`stylesheet load failed: ${href}`)) }\n doc.head.appendChild(link)\n }))\n\n let latestRequest = 0\n let currentActivation: number | null = null\n const initialSkinId = doc.documentElement?.getAttribute('data-dsh-skin') || null\n let active: string | null = initialSkinId\n /** The committed selection try-on restores (component scope). */\n let committed: { id: string | null; entry: ControllerSkinEntry | null } = { id: initialSkinId, entry: null }\n /** Last non-null applied entry, so refresh() can re-activate it. */\n let lastEntry: ControllerSkinEntry | null = null\n /** Last evaluated background-suppression verdict (refresh() skips no-ops). */\n let lastSuppressed: boolean | null = deps.suppressBackgroundMedia?.() === true\n let trying: string | null = null\n let previewing = false\n const listeners = new Set<() => void>()\n // React's useSyncExternalStore requires a CACHED snapshot: getSnapshot must\n // return the same reference until the state actually changes, or the store\n // consumer loops forever (and the settings card crashes blank).\n let stateSnapshot: SkinControllerState = { active: initialSkinId, trying: null, previewing: false }\n const emit = (): void => {\n stateSnapshot = { active, trying, previewing }\n for (const listener of listeners) listener()\n }\n\n /**\n * Install one stylesheet as a tracked <link> (the load itself happened in\n * loadStylesheet; here we only register the teardown). Links keep relative\n * url() resolution intact — a <style> tag would resolve them against the\n * document and 404 every skin asset.\n */\n function trackStylesheet(activation: number, label: string, href: string): void {\n const link = doc.head.querySelector<HTMLLinkElement>(`link[href=\"${href}\"]`)\n ledger.record(activation, `style:${label}`, () => link?.remove())\n }\n\n /**\n * Paint the skin background art into the `background` decoration layer\n * (z-index:-2) with a snapshot for the activation ledger. Only the CURRENT\n * activation may restore: when an older activation is disposed after a\n * newer one already re-painted the layer, restoring its snapshot would\n * clobber the newer paint.\n *\n * Two reasons the art lives in the layer, not on `document.body`:\n * - Chromium's backdrop-filter does not sample the canvas/body background,\n * so the skin-center blur layer (z-index:-1) could never blur body-painted\n * art (issue #732 defect A). A real fixed element IS sampled, so after\n * this change the same blur + scrim controls work on the skin backdrop\n * just like they already do on the Wallpaper Engine layers (issue #777).\n * - dragon-heir hooks expect the art in ctx.layers.background (they swap\n * the painted img and apply the v1 filter lift); the layer is the v2\n * contract and body painting was a leftover half-migration.\n * The body's own opaque background is forced transparent while art is\n * mounted, or the shell's static panels would cover the negative-z layer.\n */\n function setBackgroundLayer(activation: number, nodes: HTMLElement[]): void {\n const style = doc.body.style\n const previousBackgroundColor = style.getPropertyValue('background-color')\n const restore = (): void => {\n if (currentActivation !== activation) return\n clearLayer(layers.background)\n setSceneBackdropActive(doc, 'skin', false)\n if (previousBackgroundColor === '') style.removeProperty('background-color')\n else style.setProperty('background-color', previousBackgroundColor)\n }\n clearLayer(layers.background)\n if (nodes.length > 0) {\n for (const node of nodes) layers.background.appendChild(node)\n style.setProperty('background-color', 'transparent')\n setSceneBackdropActive(doc, 'skin', true)\n } else {\n setSceneBackdropActive(doc, 'skin', false)\n if (previousBackgroundColor === '') style.removeProperty('background-color')\n else style.setProperty('background-color', previousBackgroundColor)\n }\n ledger.record(activation, 'background:layer', restore)\n }\n\n function installBackground(\n activation: number,\n entry: ControllerSkinEntry,\n ): void {\n const media = entry.manifest.contributes.backgroundMedia\n if (!media) {\n setBackgroundLayer(activation, [])\n return\n }\n // WE wallpaper > user manual background > skin manifest background.\n if (deps.suppressBackgroundMedia?.() === true) {\n setBackgroundLayer(activation, [])\n return\n }\n const variant = themeGet() === 'dark' ? (media.dark ?? media.light) : (media.light ?? media.dark)\n if (!variant) {\n setBackgroundLayer(activation, [])\n return\n }\n const assetBase = `${apiBase}/skins/${entry.manifest.id}`\n setBackgroundLayer(activation, buildBackgroundMedia(doc, variant, assetBase))\n }\n\n async function installHooks(activation: number, entry: ControllerSkinEntry): Promise<void> {\n const facet = entry.manifest.facets?.client\n if (!facet) return\n const importHooks = deps.importHooks ?? ((url: string) => import(/* @vite-ignore */ url))\n try {\n const mod = (await importHooks(`${apiBase}/skins/${entry.manifest.id}/hooks.mjs`)) as HooksModule\n const factory = mod?.default\n if (typeof factory !== 'function') throw new Error('hooks.mjs must default-export defineSkinHooks()')\n const hooks = factory()\n if (typeof hooks?.apply !== 'function') throw new Error('defineSkinHooks() must return { apply }')\n const cleanups: Array<() => void> = []\n const ctx = {\n skinId: entry.manifest.id,\n scopeAttr: entry.manifest.id,\n assetBase: `${apiBase}/skins/${entry.manifest.id}`,\n layers,\n theme: {\n get: themeGet,\n subscribe: themeSubscribe,\n },\n onCleanup: (fn: () => void) => {\n cleanups.push(fn)\n },\n }\n hooks.apply(ctx)\n ledger.record(activation, 'hooks', () => {\n try {\n hooks.dispose?.()\n } catch (error) {\n onError(`hooks dispose failed for ${entry.manifest.id}`, error)\n }\n for (const cleanup of cleanups.reverse()) {\n try {\n cleanup()\n } catch (error) {\n onError(`hooks cleanup failed for ${entry.manifest.id}`, error)\n }\n }\n })\n } catch (error) {\n // The escape hatch never takes the static skin down with it.\n onError(`hooks failed for ${entry.manifest.id}; static skin stays active`, error)\n }\n }\n\n async function persist(id: string | null): Promise<void> {\n if (deps.persist) {\n await deps.persist(id)\n return\n }\n await fetchImpl(`${apiBase}/active`, {\n method: 'POST',\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify({ active: id }),\n })\n }\n\n async function switchInternal(\n id: string | null,\n entry: ControllerSkinEntry | null,\n shouldPersist: boolean,\n ): Promise<string | null> {\n const seq = ++latestRequest\n const activation = ledger.beginActivation()\n try {\n if (id !== null && entry !== null) {\n const stylesheetHref = `${apiBase}/skins/${id}/stylesheet`\n const patchesHref = entry.manifest.contributes.patches !== undefined\n ? `${apiBase}/skins/${id}/patches`\n : null\n await loadStylesheet(stylesheetHref)\n trackStylesheet(activation, 'stylesheet', stylesheetHref)\n if (patchesHref !== null) {\n await loadStylesheet(patchesHref).catch(() => {})\n trackStylesheet(activation, 'patches', patchesHref)\n }\n if (seq !== latestRequest) throw new StaleSwitch()\n installBackground(activation, entry)\n await installHooks(activation, entry)\n } else {\n // Stock / entryless switch owns the background layer too: it must\n // clear a previous skin's paint (the old activation's restore is\n // skipped as stale by the ownership gate).\n setBackgroundLayer(activation, [])\n }\n if (seq !== latestRequest) throw new StaleSwitch()\n\n // The atomic cut: attribute first, then retire the old activation.\n if (id === null) doc.documentElement.removeAttribute('data-dsh-skin')\n else doc.documentElement.setAttribute('data-dsh-skin', id)\n const previous = currentActivation\n currentActivation = activation\n active = id\n if (entry !== null) lastEntry = entry\n if (shouldPersist) {\n committed = { id, entry }\n trying = null\n previewing = false\n } else {\n previewing = id !== committed.id\n trying = previewing ? id : null\n }\n emit()\n if (previous !== null) ledger.disposeActivation(previous)\n if (shouldPersist) {\n await persist(id).catch((error) => onError('failed to persist the skin selection', error))\n }\n return active\n } catch (error) {\n ledger.disposeActivation(activation)\n if (error instanceof StaleSwitch) return active\n if (currentActivation === null) {\n active = null\n committed = { id: null, entry: null }\n doc.documentElement.removeAttribute('data-dsh-skin')\n emit()\n }\n onError(`switch to ${id ?? 'stock'} failed; previous skin intact`, error)\n return active\n }\n }\n\n return {\n get active() {\n return active\n },\n get layers() {\n return layers\n },\n\n async switchTo(id, entry) {\n return await switchInternal(id, entry, true)\n },\n\n async tryOn(id, entry) {\n return await switchInternal(id, entry, false)\n },\n\n async exitTryOn() {\n const result = await switchInternal(committed.id, committed.entry, false)\n return result\n },\n\n subscribe(listener) {\n listeners.add(listener)\n return () => listeners.delete(listener)\n },\n\n getState() {\n return stateSnapshot\n },\n\n async refresh() {\n const suppressed = deps.suppressBackgroundMedia?.() === true\n if (suppressed === lastSuppressed) return active\n lastSuppressed = suppressed\n const id = active\n if (id !== null && lastEntry === null) {\n return active\n }\n return await switchInternal(id, id === null ? null : lastEntry, false)\n },\n\n shutdown() {\n latestRequest += 1\n unsubscribeTheme()\n if (currentActivation !== null) {\n ledger.disposeActivation(currentActivation)\n currentActivation = null\n }\n active = null\n trying = null\n previewing = false\n committed = { id: null, entry: null }\n emit()\n doc.documentElement.removeAttribute('data-dsh-skin')\n },\n }\n}\n\nclass StaleSwitch extends Error {\n constructor() {\n super('superseded by a newer switch')\n }\n}\n","/**\n * Browser boot wiring for the v2 skin runtime (issue #506): one store per\n * document that owns the effect ledger, the skin controller, the semantic\n * adapter and the catalog snapshot. The settings card consumes the store;\n * the store outlives the card (settings panels unmount on close), so a\n * try-on preview survives closing and reopening the panel.\n *\n * Boot sequence: fetch the catalog snapshot once, read the persisted active\n * selection, and activate it (the tapIndex adapter already stamped the\n * attribute and preloaded the stylesheet for first paint; the controller\n * re-installs under ledger ownership so later switches stay atomic).\n * @module @linxin666/dsh-client-ui-skin-center/runtime/boot\n */\n\nimport { createEffectLedger } from './effect-ledger.ts'\nimport { createSemanticAdapter } from './semantic-adapter.ts'\nimport type { SemanticAdapter } from './semantic-adapter.ts'\nimport { installShellRenderingAdapter } from './shell-rendering.ts'\nimport { createSkinController } from './skin-controller.ts'\nimport type { ControllerSkinEntry, SkinController } from './skin-controller.ts'\n\n/** Display-ready catalog entry (manifest + origin), as served by /v2/catalog. */\nexport interface CatalogSkin {\n origin: 'builtin' | 'user'\n warnings: string[]\n manifest: ControllerSkinEntry['manifest'] & {\n name: string\n nameEn: string\n tagline?: string\n description?: string\n accent?: string\n order?: number\n author?: string\n license?: string\n attribution?: string\n preview?: { light: string; dark: string }\n tags?: string[]\n }\n}\n\nexport interface CatalogDiagnostic {\n subject: string\n origin: string\n errors: string[]\n}\n\nexport interface SkinRuntimeStore {\n readonly controller: SkinController\n readonly adapter: SemanticAdapter\n /** Loaded catalog snapshot (null until the first fetch resolves). */\n catalog(): CatalogSkin[] | null\n diagnostics(): CatalogDiagnostic[]\n /** Re-fetch the catalog (e.g. after the user drops a new skin directory). */\n refreshCatalog(): Promise<void>\n /** Find one entry in the current snapshot by id. */\n find(id: string): CatalogSkin | null\n /** Fires on catalog loads AND controller state transitions. */\n subscribe(listener: () => void): () => void\n /** Stop the semantic adapter and dispose the current activation. */\n shutdown(): void\n}\n\nexport interface BootOptions {\n doc?: Document\n apiBase?: string\n fetchImpl?: typeof fetch\n /** Background-media priority: true suppresses skin manifest media (WE wallpaper wins). */\n suppressBackgroundMedia?: () => boolean\n}\n\nexport function bootSkinRuntime(options: BootOptions = {}): SkinRuntimeStore {\n const doc = options.doc ?? document\n const apiBase = options.apiBase ?? '/api/skin-center/v2'\n const fetchImpl = options.fetchImpl ?? fetch.bind(doc.defaultView)\n\n const ledger = createEffectLedger()\n const controller = createSkinController({\n doc,\n ledger,\n apiBase,\n fetchImpl,\n suppressBackgroundMedia: options.suppressBackgroundMedia,\n // Switches fail closed to the previous skin; failures must still be\n // observable in the console (they are never thrown to the card).\n onError: (message, error) => {\n console.error(`[skin-center] ${message}`, error)\n },\n })\n const adapter = createSemanticAdapter(doc)\n adapter.start()\n const disposeShellRendering = installShellRenderingAdapter(doc)\n\n let catalog: CatalogSkin[] | null = null\n let diagnostics: CatalogDiagnostic[] = []\n const listeners = new Set<() => void>()\n const emit = (): void => {\n for (const listener of listeners) listener()\n }\n\n async function refreshCatalog(): Promise<void> {\n const res = await fetchImpl(`${apiBase}/catalog`)\n if (!res.ok) throw new Error(`catalog fetch -> ${res.status}`)\n const payload = (await res.json()) as {\n ok: boolean\n skins?: CatalogSkin[]\n diagnostics?: CatalogDiagnostic[]\n }\n catalog = payload.skins ?? []\n diagnostics = payload.diagnostics ?? []\n emit()\n }\n\n const store: SkinRuntimeStore = {\n controller,\n adapter,\n catalog: () => catalog,\n diagnostics: () => diagnostics,\n refreshCatalog,\n find(id) {\n return catalog?.find((s) => s.manifest.id === id) ?? null\n },\n subscribe(listener) {\n const off = controller.subscribe(listener)\n listeners.add(listener)\n return () => {\n off()\n listeners.delete(listener)\n }\n },\n shutdown() {\n adapter.stop()\n disposeShellRendering()\n controller.shutdown()\n },\n }\n\n // E2e/acceptance handle: exposes the boot store on the window for\n // scripted probes (see tests and the acceptance checklist).\n {\n const root = doc.defaultView as { __skinRuntime?: SkinRuntimeStore } & Window\n root.__skinRuntime = store\n }\n\n // Initial activation: apply the persisted selection from the snapshot.\n void (async () => {\n try {\n await refreshCatalog()\n let active = doc.documentElement?.getAttribute('data-dsh-skin') || null\n if (!active) {\n const res = await fetchImpl(`${apiBase}/active`)\n const payload = (await res.json()) as { ok: boolean; active?: string | null }\n active = payload.ok && typeof payload.active === 'string' ? payload.active : null\n }\n if (active === null) return\n let entry = store.find(active)\n if (entry === null) {\n const defaultEntry = store.find('blue-fantasy')\n if (defaultEntry !== null) {\n await controller.switchTo('blue-fantasy', defaultEntry as ControllerSkinEntry)\n } else {\n await controller.switchTo(null, null)\n }\n return\n }\n await controller.switchTo(active, entry as ControllerSkinEntry)\n } catch {\n // Fail-closed: boot into the stock look; the card surfaces catalog\n // errors through diagnostics().\n await controller.switchTo(null, null).catch(() => {})\n }\n })()\n\n if (typeof doc.defaultView !== 'undefined' && doc.defaultView !== null) {\n const win = doc.defaultView\n const onSkinApplied = (e: Event) => {\n const detail = (e as CustomEvent<{ id?: string }>).detail\n if (detail && typeof detail.id === 'string') {\n void refreshCatalog().then(async () => {\n const entry = store.find(detail.id!)\n if (entry !== null) {\n await controller.switchTo(detail.id!, entry as ControllerSkinEntry)\n }\n })\n }\n }\n win.addEventListener('dsh-skin-applied', onSkinApplied)\n listeners.add(() => win.removeEventListener('dsh-skin-applied', onSkinApplied))\n }\n\n return store\n}\n","/**\n * Serializes skin and wallpaper actions into one preview session.\n * A transition in one dimension fully retires the other dimension's preview\n * before it starts, so async skin switches cannot race wallpaper publishes.\n */\nexport interface PreviewSkinController {\n getState(): { previewing: boolean }\n exitTryOn(): Promise<string | null>\n}\n\nexport interface PreviewWallpaperController {\n trying(): boolean\n exitTryOn(): void\n}\n\nexport interface PreviewCustomThemeController {\n getState(): { previewing: boolean }\n exitTryOn(): void\n suspend(): void\n resume(): void\n}\n\nexport class PreviewCoordinator {\n private tail: Promise<void> = Promise.resolve()\n\n constructor(\n private readonly skin: PreviewSkinController,\n private readonly wallpaper: PreviewWallpaperController,\n private readonly customTheme?: PreviewCustomThemeController,\n ) {}\n\n runSkin<T>(action: () => Promise<T>): Promise<T> {\n return this.enqueue(async () => {\n if (this.wallpaper.trying()) this.wallpaper.exitTryOn()\n if (this.customTheme?.getState().previewing === true) this.customTheme.exitTryOn()\n this.customTheme?.suspend()\n try {\n return await action()\n } finally {\n if (!this.skin.getState().previewing) this.customTheme?.resume()\n }\n })\n }\n\n runWallpaper(action: () => void): Promise<void> {\n return this.enqueue(async () => {\n if (this.customTheme?.getState().previewing === true) this.customTheme.exitTryOn()\n if (this.skin.getState().previewing) await this.skin.exitTryOn()\n this.customTheme?.resume()\n action()\n })\n }\n\n runCustomTheme<T>(action: () => Promise<T>): Promise<T> {\n return this.enqueue(async () => {\n if (this.wallpaper.trying()) this.wallpaper.exitTryOn()\n const continuingCustomPreview = this.customTheme?.getState().previewing === true\n if (!continuingCustomPreview && this.skin.getState().previewing) await this.skin.exitTryOn()\n this.customTheme?.resume()\n return await action()\n })\n }\n\n private enqueue<T>(action: () => Promise<T>): Promise<T> {\n const run = this.tail.then(action, action)\n this.tail = run.then(() => undefined, () => undefined)\n return run\n }\n}\n","/** Versioned user theme derived from the official stock theme. */\n\nexport const SKIN_CUSTOM_THEME_NS = 'skin-custom-theme'\nexport const CUSTOM_THEME_VERSION = 1 as const\n\nexport interface CustomThemeProfile {\n accent: string\n background: string\n foreground: string\n contrast: number\n}\n\nexport interface CustomThemeConfig {\n version: number\n applied: boolean\n light: CustomThemeProfile\n dark: CustomThemeProfile\n}\n\nexport const CUSTOM_THEME_DEFAULTS: Readonly<CustomThemeConfig> = {\n version: CUSTOM_THEME_VERSION,\n applied: false,\n light: {\n accent: '#4d6bfe',\n background: '#f7f8fa',\n foreground: '#262626',\n contrast: 50,\n },\n dark: {\n accent: '#7c91ff',\n background: '#171719',\n foreground: '#f3f3f3',\n contrast: 50,\n },\n}\n\n/** The complete token surface this feature may emit. */\nexport const CUSTOM_THEME_ALLOWED_TOKENS = [\n '--dsw-alias-bg-base',\n '--dsw-alias-bg-layer-1',\n '--dsw-alias-bg-layer-2',\n '--dsw-alias-bg-layer-3',\n '--dsw-alias-bg-multi-select',\n '--dsw-alias-bg-overlay',\n '--dsw-alias-bg-skeleton',\n '--dsw-alias-border-l1',\n '--dsw-alias-border-l2',\n '--dsw-alias-border-l3',\n '--dsw-alias-border-l4',\n '--dsw-alias-brand-primary',\n '--dsw-alias-brand-primary-invert',\n '--dsw-alias-brand-text',\n '--dsw-alias-button-primary-dimmed',\n '--dsw-alias-button-primary-fill',\n '--dsw-alias-button-primary-hover',\n '--dsw-alias-interactive-bg-active',\n '--dsw-alias-interactive-bg-hover',\n '--dsw-alias-interactive-bg-hover-accent',\n '--dsw-alias-label-dimmed',\n '--dsw-alias-label-primary',\n '--dsw-alias-label-primary-foreground',\n '--dsw-alias-label-secondary',\n '--dsw-alias-label-tertiary',\n '--dsw-alias-markdown-code-block',\n '--dsw-alias-markdown-code-block-banner',\n '--dsw-alias-markdown-inline-code',\n '--dsw-alias-scrollbar-bg-l1',\n '--dsw-alias-scrollbar-hover-l1',\n '--dsw-alias-toast-bg',\n '--dsw-alias-tooltip-bg',\n '--dsw-specific-bubble',\n '--dsw-specific-bubble-highlight',\n '--dsw-specific-input-major',\n '--dsw-specific-menu',\n '--dsw-specific-selector',\n '--dsw-specific-sidebar-fill',\n '--dsw-specific-sidebar-nav-item-active',\n '--dsw-specific-sidebar-nav-item-active-accent',\n '--dsw-specific-sidebar-nav-item-hover',\n] as const\n\ntype UnknownRecord = Record<string, unknown>\n\nfunction record(value: unknown): UnknownRecord {\n return typeof value === 'object' && value !== null && !Array.isArray(value)\n ? value as UnknownRecord\n : {}\n}\n\nfunction color(value: unknown, fallback: string): string {\n return typeof value === 'string' && /^#[0-9a-f]{6}$/i.test(value)\n ? value.toLowerCase()\n : fallback\n}\n\nfunction contrast(value: unknown, fallback: number): number {\n if (typeof value !== 'number' || !Number.isFinite(value)) return fallback\n return Math.max(0, Math.min(100, Math.round(value)))\n}\n\nfunction normalizeProfile(value: unknown, fallback: Readonly<CustomThemeProfile>): CustomThemeProfile {\n const source = record(value)\n return {\n accent: color(source.accent, fallback.accent),\n background: color(source.background, fallback.background),\n foreground: color(source.foreground, fallback.foreground),\n contrast: contrast(source.contrast, fallback.contrast),\n }\n}\n\n/** Normalize untrusted settings data into the current contract version. */\nexport function normalizeCustomThemeConfig(value: unknown): CustomThemeConfig {\n const source = record(value)\n if (source.version !== undefined && source.version !== CUSTOM_THEME_VERSION) {\n return {\n version: CUSTOM_THEME_VERSION,\n applied: false,\n light: { ...CUSTOM_THEME_DEFAULTS.light },\n dark: { ...CUSTOM_THEME_DEFAULTS.dark },\n }\n }\n return {\n version: CUSTOM_THEME_VERSION,\n applied: source.applied === true,\n light: normalizeProfile(source.light, CUSTOM_THEME_DEFAULTS.light),\n dark: normalizeProfile(source.dark, CUSTOM_THEME_DEFAULTS.dark),\n }\n}\n\nfunction mix(a: string, aPercent: number, b: string): string {\n return `color-mix(in srgb, ${a} ${aPercent}%, ${b})`\n}\n\nfunction declarations(profile: CustomThemeProfile): Array<[typeof CUSTOM_THEME_ALLOWED_TOKENS[number], string]> {\n const { accent, background, foreground } = profile\n const depth1 = 2 + Math.round(profile.contrast * 0.12)\n const depth2 = depth1 + 4\n const depth3 = depth2 + 4\n const border = 12 + Math.round(profile.contrast * 0.18)\n const mutedText = 60 + Math.round(profile.contrast * 0.2)\n return [\n ['--dsw-alias-bg-base', background],\n ['--dsw-alias-bg-layer-1', mix(background, 100 - depth1, foreground)],\n ['--dsw-alias-bg-layer-2', mix(background, 100 - depth2, foreground)],\n ['--dsw-alias-bg-layer-3', mix(background, 100 - depth3, foreground)],\n ['--dsw-alias-bg-multi-select', mix(background, 84, accent)],\n ['--dsw-alias-bg-overlay', mix(background, 90 - Math.round(profile.contrast * 0.08), foreground)],\n ['--dsw-alias-bg-skeleton', mix(background, 82, foreground)],\n ['--dsw-alias-border-l1', mix(background, 100 - border, foreground)],\n ['--dsw-alias-border-l2', mix(background, 100 - Math.max(8, border - 5), foreground)],\n ['--dsw-alias-border-l3', mix(background, 100 - Math.max(5, border - 9), foreground)],\n ['--dsw-alias-border-l4', mix(background, 96, foreground)],\n ['--dsw-alias-brand-primary', accent],\n ['--dsw-alias-brand-primary-invert', background],\n ['--dsw-alias-brand-text', accent],\n ['--dsw-alias-button-primary-dimmed', mix(accent, 48, background)],\n ['--dsw-alias-button-primary-fill', accent],\n ['--dsw-alias-button-primary-hover', mix(accent, 82, foreground)],\n ['--dsw-alias-interactive-bg-active', mix(background, 78, accent)],\n ['--dsw-alias-interactive-bg-hover', mix(background, 100 - depth2, foreground)],\n ['--dsw-alias-interactive-bg-hover-accent', mix(background, 84, accent)],\n ['--dsw-alias-label-dimmed', mix(foreground, 42, background)],\n ['--dsw-alias-label-primary', foreground],\n ['--dsw-alias-label-primary-foreground', foreground],\n ['--dsw-alias-label-secondary', mix(foreground, mutedText, background)],\n ['--dsw-alias-label-tertiary', mix(foreground, Math.max(45, mutedText - 18), background)],\n ['--dsw-alias-markdown-code-block', mix(background, 100 - depth2, foreground)],\n ['--dsw-alias-markdown-code-block-banner', mix(background, 100 - depth3, foreground)],\n ['--dsw-alias-markdown-inline-code', mix(background, 86, accent)],\n ['--dsw-alias-scrollbar-bg-l1', mix(background, 94, foreground)],\n ['--dsw-alias-scrollbar-hover-l1', mix(background, 76, foreground)],\n ['--dsw-alias-toast-bg', mix(background, 100 - depth3, foreground)],\n ['--dsw-alias-tooltip-bg', mix(background, 28, foreground)],\n ['--dsw-specific-bubble', mix(background, 92, accent)],\n ['--dsw-specific-bubble-highlight', mix(background, 82, accent)],\n ['--dsw-specific-input-major', mix(background, 100 - depth1, foreground)],\n ['--dsw-specific-menu', mix(background, 100 - depth1, foreground)],\n ['--dsw-specific-selector', mix(background, 100 - depth2, foreground)],\n ['--dsw-specific-sidebar-fill', mix(background, 100 - depth1, foreground)],\n ['--dsw-specific-sidebar-nav-item-active', mix(background, 86, accent)],\n ['--dsw-specific-sidebar-nav-item-active-accent', accent],\n ['--dsw-specific-sidebar-nav-item-hover', mix(background, 100 - depth2, foreground)],\n ]\n}\n\nfunction block(selector: string, profile: CustomThemeProfile): string {\n const body = declarations(profile).map(([name, value]) => ` ${name}: ${value};`).join('\\n')\n return `${selector} {\\n${body}\\n}`\n}\n\n/** Build stock-only CSS from normalized, fixed token declarations. */\nexport function buildCustomThemeCss(value: unknown): string {\n const config = normalizeCustomThemeConfig(value)\n return [\n block('html[data-dsh-custom-theme]:not([data-dsh-skin]) body', config.light),\n block('html[data-dsh-custom-theme]:not([data-dsh-skin]) body[data-ds-dark-theme]', config.dark),\n ].join('\\n\\n')\n}\n","import type { SettingsScope } from '@deepseek-ai/dsh-client-ui-settings/client'\n\nimport {\n CUSTOM_THEME_DEFAULTS,\n buildCustomThemeCss,\n normalizeCustomThemeConfig,\n type CustomThemeConfig,\n type CustomThemeProfile,\n} from '../core/custom-theme.ts'\n\nexport type CustomThemeScheme = 'light' | 'dark'\n\nexport interface CustomThemeState {\n applied: boolean\n previewing: boolean\n visible: boolean\n writeError: string | null\n}\n\nexport interface CustomThemeControllerOptions {\n doc?: Document\n}\n\ntype CustomThemeField = keyof CustomThemeConfig & string\n\ninterface PendingWrite {\n field: CustomThemeField\n value: CustomThemeConfig[CustomThemeField]\n resolve(): void\n reject(error: unknown): void\n}\n\n/** Owns the custom-theme settings snapshot and its inert-by-default style. */\nexport class CustomThemeController {\n private readonly scope: SettingsScope<CustomThemeConfig>\n private readonly doc: Document\n private readonly style: HTMLStyleElement\n private readonly unsubscribe: () => void\n private readonly listeners = new Set<() => void>()\n private config: CustomThemeConfig\n private previewingValue = false\n private suspended = false\n private state: CustomThemeState\n private disposed = false\n private readonly writeQueue: PendingWrite[] = []\n private pendingWrites = 0\n private drainingWrites = false\n\n constructor(scope: SettingsScope<CustomThemeConfig>, options: CustomThemeControllerOptions = {}) {\n this.scope = scope\n this.doc = options.doc ?? document\n this.config = normalizeCustomThemeConfig(scope.getSnapshot().value)\n this.style = this.doc.createElement('style')\n this.style.dataset.dshCustomThemeStyle = ''\n this.doc.head.appendChild(this.style)\n this.state = { applied: this.config.applied, previewing: false, visible: false, writeError: null }\n this.syncDom()\n this.unsubscribe = scope.subscribe(() => {\n if (this.disposed || this.pendingWrites > 0) return\n this.syncFromScope()\n })\n }\n\n subscribe = (listener: () => void): (() => void) => {\n this.listeners.add(listener)\n return () => { this.listeners.delete(listener) }\n }\n\n getState = (): CustomThemeState => this.state\n\n profile(scheme: CustomThemeScheme): CustomThemeProfile {\n return { ...this.config[scheme] }\n }\n\n setProfileValue(\n scheme: CustomThemeScheme,\n key: keyof CustomThemeProfile,\n value: string | number,\n ): void {\n const next = normalizeCustomThemeConfig({\n ...this.config,\n [scheme]: { ...this.config[scheme], [key]: value },\n })\n this.config = next\n this.clearWriteError()\n this.syncDom()\n this.publish()\n void this.queueWrite(scheme, { ...next[scheme] }).catch(error => { this.setWriteError(error) })\n }\n\n reset(scheme: CustomThemeScheme): void {\n const profile = { ...CUSTOM_THEME_DEFAULTS[scheme] }\n this.config = { ...this.config, [scheme]: profile }\n this.clearWriteError()\n this.syncDom()\n this.publish()\n void this.queueWrite(scheme, profile).catch(error => { this.setWriteError(error) })\n }\n\n tryOn(): void {\n this.previewingValue = true\n this.suspended = false\n this.syncDom()\n this.publish()\n }\n\n exitTryOn(): void {\n this.previewingValue = false\n this.suspended = false\n this.syncDom()\n this.publish()\n }\n\n async apply(): Promise<void> {\n this.config = { ...this.config, applied: true }\n this.previewingValue = false\n this.suspended = false\n this.syncDom()\n this.publish()\n await this.queueWrite('applied', true)\n if (!this.config.applied) throw new Error('custom theme activation was not persisted')\n }\n\n async deactivate(): Promise<void> {\n this.config = { ...this.config, applied: false }\n this.previewingValue = false\n this.suspended = false\n this.syncDom()\n this.publish()\n await this.queueWrite('applied', false)\n if (this.config.applied) throw new Error('custom theme deactivation was not persisted')\n }\n\n suspend(): void {\n if (this.suspended) return\n this.suspended = true\n this.syncDom()\n this.publish()\n }\n\n resume(): void {\n if (!this.suspended) return\n this.suspended = false\n this.syncDom()\n this.publish()\n }\n\n dispose(): void {\n if (this.disposed) return\n this.disposed = true\n this.unsubscribe()\n this.listeners.clear()\n this.style.remove()\n this.doc.documentElement.removeAttribute('data-dsh-custom-theme')\n }\n\n private syncDom(): void {\n this.style.textContent = buildCustomThemeCss(this.config)\n const visible = (this.config.applied || this.previewingValue) && !this.suspended\n if (visible) this.doc.documentElement.setAttribute('data-dsh-custom-theme', 'true')\n else this.doc.documentElement.removeAttribute('data-dsh-custom-theme')\n this.state = {\n applied: this.config.applied,\n previewing: this.previewingValue,\n visible,\n writeError: this.state.writeError,\n }\n }\n\n private publish(): void {\n for (const listener of this.listeners) listener()\n }\n\n private syncFromScope(): void {\n this.config = normalizeCustomThemeConfig(this.scope.getSnapshot().value)\n this.syncDom()\n this.publish()\n }\n\n private clearWriteError(): void {\n if (this.state.writeError === null) return\n this.state = { ...this.state, writeError: null }\n }\n\n private setWriteError(error: unknown): void {\n this.state = {\n ...this.state,\n writeError: error instanceof Error ? error.message : String(error),\n }\n this.publish()\n }\n\n private queueWrite<K extends CustomThemeField>(field: K, value: CustomThemeConfig[K]): Promise<void> {\n this.pendingWrites += 1\n const pending = new Promise<void>((resolve, reject) => {\n this.writeQueue.push({\n field,\n value,\n resolve,\n reject,\n } as PendingWrite)\n })\n void this.drainWrites()\n return pending\n }\n\n private async drainWrites(): Promise<void> {\n if (this.drainingWrites) return\n this.drainingWrites = true\n const settled: Array<\n { write: PendingWrite; ok: true }\n | { write: PendingWrite; ok: false; error: unknown }\n > = []\n while (this.writeQueue.length > 0) {\n const write = this.writeQueue.shift()\n if (write === undefined) break\n try {\n await this.scope.set(write.field, write.value)\n } catch (error) {\n settled.push({ write, ok: false, error })\n continue\n } finally {\n this.pendingWrites -= 1\n }\n settled.push({ write, ok: true })\n }\n this.drainingWrites = false\n if (!this.disposed) this.syncFromScope()\n const failure = settled.find(result => !result.ok)\n if (!this.disposed && failure !== undefined && !failure.ok) {\n this.setWriteError(failure.error)\n }\n for (const result of settled) {\n if (result.ok) result.write.resolve()\n else result.write.reject(result.error)\n }\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 * In-GUI skin center, browser half: registers the Skin Center as a first-level\n * settings section (`settings.section`) and boots the v2 skin runtime\n * (effect ledger + atomic switch controller + semantic adapter + catalog\n * store). The section lists the installed skins (shipped built-ins +\n * $DSH_HOME/skins), tries them on live, and applies in one click — no reload,\n * no cordis.patch.yml rewrite (issue #506). The plugin writes only DOM and\n * the settings ledger — no services, no events, no model access.\n *\n * Background preferences persist through the v2 /active channel instead of\n * the settings scope (issue #996): the remote pairing channel fences\n * settings.* as loopback-only, so scope-backed writes never reached the\n * server from a paired desktop. The legacy skin-background scope is still\n * bound as a live input for the official settings page (loopback only);\n * card edits flow card -> POST /active, page edits flow scope -> POST\n * /active.\n */\nimport type { Context as ClientContext } from '@deepseek-ai/cordis'\nimport type { SettingsScope, SettingsScopeSpec } from '@deepseek-ai/dsh-client-ui-settings/client'\nimport type { ThemeRuntime } from '@deepseek-ai/dsh-client-ui-theme/client'\n// Type-only: pulls the locale plugin's Context merge (ctx.locale).\nimport type {} from '@deepseek-ai/dsh-client-locale/client'\n// Type-only: pulls the settings-surface Context merge (ctx.settingsScope).\nimport type {} from '@deepseek-ai/dsh-client-ui-settings/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'\n// Type-only: pulls the generated Remote namespace (ctx.remote), including directoryPicker.\nimport type {} from '@deepseek-ai/dsh-api-remotes/client'\nimport { SkinCenterSection, type SkinCenterInjected } from './SkinCenter.tsx'\nimport { BackgroundController, SKIN_BACKGROUND_NS } from './background.ts'\nimport type { SkinBackgroundConfig } from '../core/background.ts'\nimport { initialSkinBackgroundReconcileState, reconcileSkinBackgroundPublication } from '../core/background-scope.ts'\nimport { SKIN_WALLPAPER_NS, WallpaperController, installBootRestore } from './wallpaper.ts'\nimport { en, zh, type SkinCenterKey } from './locales.ts'\nimport { bootSkinRuntime } from './runtime/boot.ts'\nimport { PreviewCoordinator } from './preview-coordinator.ts'\nimport { CustomThemeController } from './custom-theme-controller.ts'\nimport { SKIN_CUSTOM_THEME_NS, type CustomThemeConfig } from '../core/custom-theme.ts'\nimport { reportDailyHeartbeat } from './telemetry.ts'\n\nexport type { SkinCenterComponentProps, SkinCenterInjected } from './SkinCenter.tsx'\nexport { bootSkinRuntime } from './runtime/boot.ts'\n\n/** Locale namespace owned by this plugin. */\nexport const NS = 'skinCenter'\n\ndeclare module '@deepseek-ai/dsh-client-ui-slots' {\n interface LocaleNamespaceMap {\n /** The skin-center card's copy. */\n skinCenter: SkinCenterKey\n }\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/** Required services: slots + locale (plugin card), theme (preview toggle), settingsScope + its transport (background scrim), and remote (wallpaper directory picker). */\nexport const inject = ['slots', 'locale', 'theme', 'settingsScope', 'connection', 'remote']\n\n/** Self-report item for the install heartbeat. */\nconst SELF_ITEM = [{ name: '@linxin666/dsh-client-ui-skin-center' }]\n\n/**\n * Beat the install heartbeat (docs/telemetry.md), enriching it with the\n * installed skin inventory (skin:<id> + version + channel) once the v2\n * catalog answers. Offline or pre-boot the beat stays package-only.\n */\nfunction beatHeartbeat(): void {\n reportDailyHeartbeat(SELF_ITEM)\n void fetch('/api/skin-center/v2/catalog')\n .then((res) => (res.ok ? res.json() : null))\n .then((catalog) => {\n if (!catalog || !Array.isArray(catalog.skins)) return\n const items = [...SELF_ITEM]\n for (const skin of catalog.skins) {\n const id = skin && skin.manifest && typeof skin.manifest.id === 'string' ? skin.manifest.id : ''\n if (!id) continue\n const item: { name: string; version?: string; channel?: 'market' | 'npm' | 'unknown' } = { name: 'skin:' + id }\n if (typeof skin.manifest.version === 'string') item.version = skin.manifest.version\n if (typeof skin.channel === 'string') item.channel = skin.channel\n items.push(item)\n }\n reportDailyHeartbeat(items.slice(0, 64))\n })\n .catch(() => { /* offline or fenced: the package-only beat already went out */ })\n}\n\n/**\n * Register the skin-center dictionaries, the body scope attribute, and the\n * Skin Center as a first-level settings section.\n * @param ctx - client root context.\n */\nexport function apply(ctx: ClientContext): void {\n // Anonymous install heartbeat (docs/telemetry.md): one beat per browser per\n // UTC day, package name plus installed-skin inventory, silent failure.\n beatHeartbeat()\n\n ctx.effect(() => {\n try {\n return ctx.locale.register(NS, { zh, en })\n } catch {\n return () => {}\n }\n }, 'ui-skin-center: dictionaries')\n\n // The card's own styles scope under this attribute so they keep applying\n // during try-on (when the active skin's attribute is retracted).\n ctx.effect(() => {\n document.body.dataset.dshSkinCenter = ''\n return () => { delete document.body.dataset.dshSkinCenter }\n }, 'ui-skin-center: body scope')\n\n const theme = ctx.get('theme') as ThemeRuntime\n const binder = ctx.get('webUiSettings') ?? ctx.settingsScope\n // The v2 state channel: GET backfills on boot, edits POST back debounced.\n // The remote proxy rewrites this path into the allow-listed channel, so it\n // works from paired desktops where the settings scope is fenced (#996).\n const V2_ACTIVE_URL = '/api/skin-center/v2/active'\n let persistTimer: ReturnType<typeof setTimeout> | null = null\n const postBackground = (next: SkinBackgroundConfig, keepalive = false): void => {\n void fetch(V2_ACTIVE_URL, {\n method: 'POST',\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify({ background: next }),\n keepalive,\n }).catch(() => { /* offline or pre-boot: the in-memory values stay applied */ })\n }\n // Coalesce slider drags into one write; dispose flushes the pending one.\n const persistBackground = (next: SkinBackgroundConfig): void => {\n if (persistTimer !== null) clearTimeout(persistTimer)\n persistTimer = setTimeout(() => {\n persistTimer = null\n postBackground(next)\n }, 250)\n }\n const flushBackground = (): void => {\n if (persistTimer === null) return\n clearTimeout(persistTimer)\n persistTimer = null\n postBackground(background.snapshot(), true)\n }\n // The legacy scope is an input face for the loopback settings page only.\n // Its resolved value contains schema defaults, so only the raw user layer may\n // be reconciled into the authoritative v2 state.\n const backgroundScope = binder.bind<SkinBackgroundConfig>({ namespace: SKIN_BACKGROUND_NS })\n const scopeConfig = (): SkinBackgroundConfig | null => {\n const value = backgroundScope.getSnapshot().value\n if (value === undefined || value === null) return null\n return value\n }\n const background = new BackgroundController(scopeConfig(), persistBackground)\n // Reconcile state for the legacy scope (revision + user-layer fence, plus\n // the boot-sync gate #1375): the settings document's initial sync must never\n // be mistaken for a settings-page edit, whichever order it and the v2 GET\n // land in — stale legacy user-layer fields (e.g. zeros left by the pre-#1107\n // bugs) would otherwise patch and persist over the authoritative v2 state.\n let reconcileState = initialSkinBackgroundReconcileState(backgroundScope.getSnapshot())\n const reconcileScope = (): void => {\n const result = reconcileSkinBackgroundPublication(\n reconcileState,\n background.snapshot(),\n backgroundScope.getSnapshot(),\n )\n reconcileState = result.state\n if (result.patch === null) return\n const currentSnapshot = background.snapshot()\n background.init({ ...currentSnapshot, ...result.patch })\n persistBackground(background.snapshot())\n }\n // Refetch the authoritative v2 state once booted; it wins over the scope\n // snapshot (the migration may only have run with this boot).\n void fetch(V2_ACTIVE_URL)\n .then((res) => (res.ok ? res.json() as Promise<{ background?: SkinBackgroundConfig | null }> : null))\n .then((body) => {\n reconcileState = { ...reconcileState, v2Loaded: true }\n if (body?.background) background.init(body.background)\n // Reconcile only a scope revision that changed while the v2 state was\n // loading; an unchanged revision is the legacy boot snapshot.\n reconcileScope()\n })\n .catch(() => {\n reconcileState = { ...reconcileState, v2Loaded: true }\n reconcileScope()\n })\n // Settings-page edits arrive through the scope publish. The settings mirror\n // may republish this namespace for an unrelated document change, so fence on\n // the namespace revision and use only explicitly stored user fields.\n ctx.effect(\n () => backgroundScope.subscribe(reconcileScope),\n 'ui-skin-center: background scope sync',\n )\n // Tear the blur element + observer down when this plugin's fiber goes away.\n ctx.effect(() => () => {\n flushBackground()\n background.dispose()\n }, 'ui-skin-center: background dispose')\n const customThemeScope = binder.bind<CustomThemeConfig>({ namespace: SKIN_CUSTOM_THEME_NS })\n const customTheme = new CustomThemeController(customThemeScope)\n ctx.effect(() => () => customTheme.dispose(), 'ui-skin-center: custom theme dispose')\n // The Wallpaper Engine bridge over the skin-wallpaper namespace.\n const wallpaperScope = binder.bind<{\n enabled?: boolean\n selection?: string\n mode?: 'live' | 'frame'\n pauseOnHidden?: boolean\n dim?: number\n wallpaperBlur?: number\n wallpaperOpacity?: number\n fit?: 'cover' | 'contain' | 'fill'\n }>({ namespace: SKIN_WALLPAPER_NS })\n const wallpaper = new WallpaperController(wallpaperScope)\n ctx.effect(() => () => wallpaper.dispose(), 'ui-skin-center: wallpaper dispose')\n // Mount the persisted wallpaper selection at boot (page load), so a\n // selection survives reloads without first opening the skin-center card.\n installBootRestore(wallpaper)\n\n // The v2 skin runtime store: outlives the settings card so a try-on\n // preview survives closing and reopening the panel. Background-media\n // priority: an active WE wallpaper suppresses skin manifest backgrounds;\n // toggling the wallpaper re-activates the current skin so the priority\n // flip paints immediately.\n const runtime = bootSkinRuntime({\n suppressBackgroundMedia: () => wallpaper.enabled() && wallpaper.isDisplaying(),\n })\n ctx.effect(() => () => runtime.shutdown(), 'ui-skin-center: runtime shutdown')\n ctx.effect(\n () => wallpaper.subscribe(() => { void runtime.controller.refresh() }),\n 'ui-skin-center: wallpaper priority refresh',\n )\n const preview = new PreviewCoordinator(runtime.controller, wallpaper, customTheme)\n ctx.effect(\n () => ctx.on('theme/change', () => wallpaper.recoverScenePlayer()),\n 'ui-skin-center: scene recovery after theme change',\n )\n const injected = (): SkinCenterInjected => ({\n runtime,\n preview,\n customTheme,\n theme: {\n getTheme: () => theme.getTheme(),\n subscribe: listener => ctx.on('theme/change', listener),\n setTheme: id => theme.setTheme(id),\n },\n background: {\n enabled: () => background.enabled(),\n setEnabled: value => background.setEnabled(value),\n opacity: () => background.opacity(),\n blurEmpty: () => background.blurEmpty(),\n blurContent: () => background.blurContent(),\n inputCardBlur: () => background.inputCardBlur(),\n bubbleOpacity: () => background.bubbleOpacity(),\n subscribe: listener => background.subscribe(listener),\n set: opacity => background.set(opacity),\n setBlurEmpty: value => background.setBlurEmpty(value),\n setBlurContent: value => background.setBlurContent(value),\n setInputCardBlur: value => background.setInputCardBlur(value),\n setBubbleOpacity: value => background.setBubbleOpacity(value),\n dispose: () => background.dispose(),\n },\n wallpaper: {\n enabled: () => wallpaper.enabled(),\n selection: () => wallpaper.selection(),\n mode: () => wallpaper.mode(),\n fit: () => wallpaper.fit(),\n dim: () => wallpaper.dim(),\n wallpaperBlur: () => wallpaper.wallpaperBlur(),\n wallpaperOpacity: () => wallpaper.wallpaperOpacity(),\n pauseOnHidden: () => wallpaper.pauseOnHidden(),\n sound: () => wallpaper.sound(),\n volume: () => wallpaper.volume(),\n dirs: () => wallpaper.dirs(),\n addDir: dir => wallpaper.addDir(dir),\n removeDir: dir => wallpaper.removeDir(dir),\n pickDir: async () => {\n const result = await ctx.remote.directoryPicker.pick()\n if (!result.ok) throw new Error(result.error.message)\n return result.value\n },\n activeId: () => wallpaper.activeId(),\n trying: () => wallpaper.trying(),\n subscribe: listener => wallpaper.subscribe(listener),\n setEnabled: value => wallpaper.setEnabled(value),\n setMode: value => wallpaper.setMode(value),\n setFit: fit => wallpaper.setFit(fit),\n setDim: value => wallpaper.setDim(value),\n setBlur: value => wallpaper.setBlur(value),\n setOpacity: value => wallpaper.setOpacity(value),\n setPauseOnHidden: value => wallpaper.setPauseOnHidden(value),\n setSound: value => wallpaper.setSound(value),\n setVolume: value => wallpaper.setVolume(value),\n applySelection: descriptor => { void preview.runWallpaper(() => wallpaper.applySelection(descriptor)) },\n clearSelection: () => wallpaper.clearSelection(),\n sync: descriptor => wallpaper.sync(descriptor),\n tryOn: descriptor => { void preview.runWallpaper(() => wallpaper.tryOn(descriptor)) },\n exitTryOn: () => wallpaper.exitTryOn(),\n recoverScenePlayer: () => wallpaper.recoverScenePlayer(),\n dispose: () => wallpaper.dispose(),\n },\n })\n\n // First-level settings section: the Skin Center card as its own top-level\n // settings page. Browsing and installing new skins happens in the DSH\n // Market store; this section manages the installed ones (try-on, apply,\n // wallpaper, custom theme).\n ctx.slots.inject('settings.section', () => {\n try {\n return ctx.slots.register({\n name: 'settings.section',\n id: 'skin-center',\n order: 120,\n label: () => ctx.locale.bind('skinCenter')('title'),\n locale: 'skinCenter',\n inject: injected,\n }, SkinCenterSection)\n } catch {\n return () => {}\n }\n })\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"client.js","names":["css","useLiveValue","css","css","isRecord"],"sources":["../../../packages/skins/skin-center/src/client/CustomThemePanel.tsx","../../../packages/skins/skin-center/src/client/runtime/backdrop-scene.ts","../../../packages/skins/skin-center/src/client/wallpaper.ts","../../../packages/skins/skin-center/src/client/SliderControl.tsx","../../../packages/skins/skin-center/src/client/WallpaperPanel.tsx","../../../packages/skins/skin-center/src/client/SkinCenter.tsx","../../../packages/skins/skin-center/src/core/background.ts","../../../packages/skins/skin-center/src/client/background.ts","../../../packages/skins/skin-center/src/core/background-scope.ts","../../../packages/skins/skin-center/src/client/locales.ts","../../../packages/skins/skin-center/src/client/runtime/effect-ledger.ts","../../../packages/skins/skin-center/src/client/runtime/semantic-adapter.ts","../../../packages/skins/skin-center/src/client/runtime/shell-rendering.ts","../../../packages/skins/skin-center/src/client/runtime/decoration-layers.ts","../../../packages/skins/skin-center/src/client/runtime/skin-controller.ts","../../../packages/skins/skin-center/src/client/runtime/boot.ts","../../../packages/skins/skin-center/src/client/preview-coordinator.ts","../../../packages/skins/skin-center/src/core/custom-theme.ts","../../../packages/skins/skin-center/src/client/custom-theme-controller.ts","../../../packages/skins/skin-center/src/client/telemetry.ts","../../../packages/skins/skin-center/src/client/index.ts"],"sourcesContent":["import { useEffect, useState, useSyncExternalStore, type ReactNode } from 'react'\nimport type { PropsLocale } from '@deepseek-ai/dsh-client-ui-slots'\n\nimport type { CustomThemeController, CustomThemeScheme } from './custom-theme-controller.ts'\nimport css from './skin-center.module.css'\n\ntype ColorKey = 'accent' | 'background' | 'foreground'\n\nexport interface CustomThemeCardProps {\n t: PropsLocale<'skinCenter'>['t']\n customTheme: CustomThemeController\n scheme: CustomThemeScheme\n setScheme(scheme: CustomThemeScheme): void\n isActive: boolean\n isTrying: boolean\n busy: boolean\n disabled: boolean\n onTryOn(): void\n onExitTryOn(): void\n onApply(): void\n}\n\nexport function CustomThemeCard(props: CustomThemeCardProps): ReactNode {\n const {\n t, customTheme, scheme, setScheme, isActive, isTrying, busy, disabled,\n onTryOn, onExitTryOn, onApply,\n } = props\n const customThemeState = useSyncExternalStore(customTheme.subscribe, customTheme.getState)\n const profile = customTheme.profile(scheme)\n const [expanded, setExpanded] = useState(false)\n const [draftColors, setDraftColors] = useState<Record<ColorKey, string>>({\n accent: profile.accent,\n background: profile.background,\n foreground: profile.foreground,\n })\n\n useEffect(() => {\n setDraftColors({\n accent: profile.accent,\n background: profile.background,\n foreground: profile.foreground,\n })\n }, [scheme, profile.accent, profile.background, profile.foreground])\n\n const setDraft = (key: ColorKey, value: string): void => {\n setDraftColors(current => ({ ...current, [key]: value }))\n }\n const commitColor = (key: ColorKey): void => {\n const value = draftColors[key]\n if (/^#[0-9a-f]{6}$/i.test(value)) customTheme.setProfileValue(scheme, key, value)\n else setDraft(key, profile[key])\n }\n const colorField = (key: ColorKey, label: string): ReactNode => {\n const draft = draftColors[key]\n const pickerValue = /^#[0-9a-f]{6}$/i.test(draft) ? draft : profile[key]\n return (\n <label className={css.customThemeField} key={key}>\n <span className={css.customThemeFieldLabel}>{label}</span>\n <span className={css.customThemeInputRow}>\n <input\n className={css.customThemeColor}\n type=\"color\"\n value={pickerValue}\n aria-label={label}\n disabled={disabled}\n onChange={(event) => {\n const value = event.target.value\n setDraft(key, value)\n customTheme.setProfileValue(scheme, key, value)\n }}\n />\n <input\n className={css.customThemeHex}\n type=\"text\"\n value={draft}\n inputMode=\"text\"\n maxLength={7}\n spellCheck={false}\n aria-label={`${label} hex`}\n disabled={disabled}\n onChange={(event) => { setDraft(key, event.target.value) }}\n onBlur={() => { commitColor(key) }}\n onKeyDown={(event) => {\n if (event.key === 'Enter') event.currentTarget.blur()\n }}\n />\n </span>\n </label>\n )\n }\n\n return (\n <div className={`${css.card} ${css.customThemeCard}`} data-dsh-custom-theme-card=\"\">\n <div className={css.cardHead}>\n <span className={css.swatch} style={{ background: profile.accent }} aria-hidden=\"true\" />\n <span className={css.cardName}>{t('customThemeTitle')}</span>\n {(isActive || isTrying) && (\n <span className={`${css.badge} ${isActive ? css.badgeActive : css.badgeTrying}`}>\n {isActive ? t('active') : t('tryingOn')}\n </span>\n )}\n </div>\n <div className={css.cardTagline}>{t('customThemeTagline')}</div>\n {customThemeState.writeError !== null && (\n <div className={css.error} role=\"alert\">\n {t('customThemeSaveFailed')}\n </div>\n )}\n <div className={css.actions}>\n {isActive && !isTrying ? (\n <button type=\"button\" className={`${css.button} ${css.buttonGhost}`} disabled>{t('tryOn')}</button>\n ) : isTrying ? (\n <button type=\"button\" className={`${css.button} ${css.buttonPrimary}`} disabled={disabled} onClick={onExitTryOn}>\n {t('exitTryOn')}\n </button>\n ) : (\n <button type=\"button\" className={`${css.button} ${css.buttonPrimary}`} disabled={disabled} onClick={onTryOn}>\n {busy ? t('loading') : t('tryOn')}\n </button>\n )}\n <button type=\"button\" className={css.button} disabled={disabled} onClick={onApply}>\n {busy ? t('applying') : t('apply')}\n </button>\n <button\n type=\"button\"\n className={css.button}\n aria-expanded={expanded}\n disabled={disabled}\n onClick={() => { setExpanded(value => !value) }}\n >\n {expanded ? t('customThemeCloseEdit') : t('customThemeEdit')}\n </button>\n </div>\n\n {expanded && (\n <div className={css.customThemeEditor}>\n <div className={css.customThemeScheme} role=\"group\" aria-label={t('customThemeMode')}>\n <span className={css.themeLabel}>{t('customThemeMode')}</span>\n <button\n type=\"button\"\n aria-pressed={scheme === 'light'}\n className={`${css.themeButton} ${scheme === 'light' ? css.themeButtonActive : ''}`}\n disabled={disabled}\n onClick={() => { setScheme('light') }}\n >\n {t('customThemeLight')}\n </button>\n <button\n type=\"button\"\n aria-pressed={scheme === 'dark'}\n className={`${css.themeButton} ${scheme === 'dark' ? css.themeButtonActive : ''}`}\n disabled={disabled}\n onClick={() => { setScheme('dark') }}\n >\n {t('customThemeDark')}\n </button>\n </div>\n\n <div className={css.customThemeFields}>\n {colorField('accent', t('customThemeAccent'))}\n {colorField('background', t('customThemeBackground'))}\n {colorField('foreground', t('customThemeForeground'))}\n </div>\n\n <label className={css.customThemeContrast}>\n <span className={css.backgroundHead}>\n <span className={css.customThemeFieldLabel}>{t('customThemeContrast')}</span>\n <span className={css.backgroundValue} aria-hidden=\"true\">{profile.contrast}</span>\n </span>\n <input\n className={css.backgroundRange}\n type=\"range\"\n min=\"0\"\n max=\"100\"\n step=\"1\"\n value={profile.contrast}\n aria-label={t('customThemeContrast')}\n aria-valuetext={String(profile.contrast)}\n disabled={disabled}\n onChange={(event) => { customTheme.setProfileValue(scheme, 'contrast', Number(event.target.value)) }}\n />\n </label>\n\n <div className={css.customThemeFooter}>\n <span className={css.backgroundHintMuted}>{t('customThemeResetHint')}</span>\n <button type=\"button\" className={css.button} disabled={disabled} onClick={() => { customTheme.reset(scheme) }}>\n {t('customThemeReset')}\n </button>\n </div>\n </div>\n )}\n </div>\n )\n}\n","/**\n * Unified \"backdrop visible\" scene marker (issue #777).\n *\n * A skin with painted background media or a mounted Wallpaper Engine\n * wallpaper both put real backdrop art behind the app. The two runtime\n * controllers (skin-controller and wallpaper) report their mount state\n * through setSceneBackdropActive(); this module folds them into ONE body /\n * html marker `data-dsh-backdrop-active` and installs the shared composer\n * seat neutralizer that keys on it.\n *\n * The shell's active composer seat paints a bottom occlusion gradient under\n * the sticky input card (rc.8: a linear gradient to --dsw-alias-bg-base,\n * z-index 7). Backdrop scenes intentionally remove that seat-wide gradient in\n * both active and hero phases so wallpaper art remains unobstructed down to the\n * viewport edge. Skin-provided seat-wide ::before masks are neutralized too.\n * Composer task/statistics surfaces are styled by the shared shell adapter\n * from skin theme tokens, not by this scene layer.\n *\n * The input card itself ([data-composer-card], the official shell's stable card\n * anchor) keeps its translucent tint and gains the configurable backdrop blur\n * (default INPUT_FROST_BLUR_PX).\n *\n * The card rule is enabled only while the conversation actually has message\n * content (data-dsh-conversation-content): an empty conversation has no正文 to\n * occlude, so the input keeps its normal hero appearance without a frost flash.\n * The strength is provided by --dsh-input-card-blur and falls back to the\n * compatibility default when the setting has not loaded yet.\n *\n * The marker is body/html level (managed outside the surface/part/plugin\n * enum, see contracts/semantic-attrs-v1.md) and survives a neutralizer\n * teardown; the style is inert whenever the marker is absent.\n * @module @linxin666/dsh-client-ui-skin-center/runtime/backdrop-scene\n */\n\n/** Shared marker: set on html + body while a source reports backdrop art. */\nexport const BACKDROP_ACTIVE_ATTR = 'data-dsh-backdrop-active'\n\n/** The shared composer-seat neutralizer style's own attribute. */\nexport const SCENE_NEUTRALIZER_ATTR = 'data-dsh-scene-neutralizer'\n\n/** Conversation-content marker: set while the active conversation has rows. */\nexport const CONVERSATION_CONTENT_ATTR = 'data-dsh-conversation-content'\n\n/**\n * Stable shell scrollport scoped row selectors. Official builds emit the chat\n * anchor; the CSS-module suffix fallbacks retain compatibility with older\n * shells without returning to a body-wide topic/session query.\n */\nconst ACTIVE_CONVERSATION_CONTENT_SELECTOR = [\n '[data-conversation-scroll] [data-chat-anchor-key]',\n '[data-conversation-scroll] [class*=\"_userRow\"]',\n '[data-conversation-scroll] [class*=\"_compactionRow\"]',\n '[data-conversation-scroll] [class*=\"_contextRow\"]',\n '[data-conversation-scroll] [class*=\"_turnErrorRow\"]',\n].join(', ')\n\n/** One source that can make backdrop art visible. */\nexport type BackdropSource = 'skin' | 'wallpaper'\n\n/** Compatibility default for the input-card backdrop blur strength (px). */\nexport const INPUT_FROST_BLUR_PX = 10\n\nconst sourceSets = new WeakMap<Document, Set<BackdropSource>>()\nconst contentObservers = new WeakMap<Document, MutationObserver>()\nconst contentFrames = new WeakMap<Document, number>()\n\n/** Write a marker attribute only when the desired state is not applied yet. */\nfunction applyMarker(el: Element | null, attr: string, active: boolean): void {\n if (el === null) return\n if (active) {\n if (el.getAttribute(attr) !== 'true') el.setAttribute(attr, 'true')\n return\n }\n if (el.hasAttribute(attr)) el.removeAttribute(attr)\n}\n\n/**\n * Report one source's backdrop-art presence. The marker stays on while any\n * source is active, so the skin and wallpaper controllers never clobber each\n * other across their mount/unmount cycles.\n */\nexport function setSceneBackdropActive(doc: Document, source: BackdropSource, active: boolean): void {\n let sources = sourceSets.get(doc)\n if (sources === undefined) {\n sources = new Set()\n sourceSets.set(doc, sources)\n }\n if (active) sources.add(source)\n else sources.delete(source)\n syncMarker(doc, sources)\n}\n\n/** Reflect the source set onto html/body and ensure the neutralizer on use. */\nfunction syncMarker(doc: Document, sources: Set<BackdropSource>): void {\n const active = sources.size > 0\n applyMarker(doc.body, BACKDROP_ACTIVE_ATTR, active)\n applyMarker(doc.documentElement, BACKDROP_ACTIVE_ATTR, active)\n if (active) {\n ensureSceneNeutralizer(doc)\n startContentObserver(doc)\n } else {\n stopContentObserver(doc)\n }\n}\n\n/**\n * Track whether the active conversation scrollport has message rows for the\n * frost gate. Topic pickers and outgoing session trees can retain their own\n * data-chat-anchor-key nodes during a switch; a body-wide query would count\n * those stale rows and flash the composer frost over the new empty topic.\n */\nfunction updateConversationContent(doc: Document): void {\n const has = doc.body !== null && doc.body.querySelector(ACTIVE_CONVERSATION_CONTENT_SELECTOR) !== null\n applyMarker(doc.body, CONVERSATION_CONTENT_ATTR, has)\n applyMarker(doc.documentElement, CONVERSATION_CONTENT_ATTR, has)\n}\n\n/**\n * Coalesce the mutation bursts of a streaming conversation into one content\n * check per frame; a check scheduled for a document that stopped observing is\n * dropped so a late frame can never re-add the marker after teardown.\n */\nfunction scheduleConversationContent(doc: Document): void {\n if (contentFrames.has(doc)) return\n const win = doc.defaultView\n if (win === null || typeof win.requestAnimationFrame !== 'function') {\n updateConversationContent(doc)\n return\n }\n contentFrames.set(doc, win.requestAnimationFrame(() => {\n contentFrames.delete(doc)\n if (!contentObservers.has(doc)) return\n updateConversationContent(doc)\n }))\n}\n\n/** Observe the conversation tree while a backdrop is visible. */\nfunction startContentObserver(doc: Document): void {\n if (contentObservers.has(doc)) return\n updateConversationContent(doc)\n const win = doc.defaultView\n if (win === null || typeof win.MutationObserver !== 'function') return\n const observer = new win.MutationObserver(() => scheduleConversationContent(doc))\n observer.observe(doc.body ?? doc.documentElement, { childList: true, subtree: true })\n contentObservers.set(doc, observer)\n}\n\n/** Stop the content observer, cancel pending work and drop the marker. */\nfunction stopContentObserver(doc: Document): void {\n const frame = contentFrames.get(doc)\n if (frame !== undefined) {\n const win = doc.defaultView\n if (win !== null && typeof win.cancelAnimationFrame === 'function') win.cancelAnimationFrame(frame)\n contentFrames.delete(doc)\n }\n const observer = contentObservers.get(doc)\n if (observer !== undefined) {\n observer.disconnect()\n contentObservers.delete(doc)\n }\n applyMarker(doc.body, CONVERSATION_CONTENT_ATTR, false)\n applyMarker(doc.documentElement, CONVERSATION_CONTENT_ATTR, false)\n}\n\n/**\n * Install the shared composer-seat neutralizer, keyed by head presence so a\n * cleared head (tests) or a re-mount re-creates it. Without the marker the\n * rules are inert, so the style can outlive a single mount without changing\n * any other look.\n */\nexport function ensureSceneNeutralizer(doc: Document): void {\n if (doc.head === null) return\n if (doc.head.querySelector(`style[${SCENE_NEUTRALIZER_ATTR}]`) !== null) return\n const style = doc.createElement('style')\n style.setAttribute(SCENE_NEUTRALIZER_ATTR, '')\n style.textContent = `\n html[data-dsh-backdrop-active] [data-composer-seat],\n html[data-dsh-backdrop-active] [data-composer-seat]::before {\n background: none !important;\n backdrop-filter: none !important;\n -webkit-backdrop-filter: none !important;\n }\n html[data-dsh-backdrop-active][data-dsh-conversation-content] [data-composer-card] {\n backdrop-filter: blur(var(--dsh-input-card-blur, ${INPUT_FROST_BLUR_PX}px)) !important;\n -webkit-backdrop-filter: blur(var(--dsh-input-card-blur, ${INPUT_FROST_BLUR_PX}px)) !important;\n }\n `\n doc.head.appendChild(style)\n}\n","/**\n * Wallpaper layer controller for the skin center: renders the applied\n * Wallpaper Engine wallpaper behind the GUI and persists the selection\n * through the 'skin-wallpaper' settings namespace.\n *\n * Layers (fixed children of document.body, painted only while a wallpaper\n * is active):\n * - media layer z-index:-3 video / iframe / static frame image\n * - scrim layer z-index:-2 the dim veil (settings 'dim')\n * The skin-center backdrop blur element (z-index:-1, background.ts) sits\n * above both, so its backdrop-filter blurs the wallpaper together with the\n * skin backdrop. The 'wallpaperBlur' setting instead blurs the wallpaper\n * itself via a filter on the media layer.\n *\n * Mutual exclusion with skin backdrop art is paint-order only: the opaque\n * media layer covers the body's background, no skin writes are touched, and\n * unmounting restores the previous view for free.\n *\n * Render modes: 'live' mounts video/web directly; 'frame' pins a static\n * image (video: first frame captured to a canvas; scene: the host-decoded\n * PNG; web: the preview image) for a zero-animation-cost backdrop. When\n * 'pauseOnHidden' is set the video pauses while the window is hidden.\n * @module @linxin666/dsh-client-ui-skin-center/wallpaper\n */\nimport type { SettingsScope, SettingsScopeSnapshot } from '@deepseek-ai/dsh-client-ui-settings/client'\nimport { setSceneBackdropActive } from './runtime/backdrop-scene.ts'\n\n/** The namespace string the Host registers (mirrors src/index.ts). */\nexport const SKIN_WALLPAPER_NS = 'skin-wallpaper'\n\n/** One wallpaper's render contract, as delivered by the inventory route. */\nexport interface WallpaperDescriptor {\n id: string\n title: string\n /** 'image' is the macOS Desktop Pictures kind: a static host-converted JPEG. */\n type: 'video' | 'web' | 'scene' | 'application' | 'image'\n videoUrl: string | null\n webUrl: string | null\n frameUrl: string | null\n sceneUrl?: string | null\n /** Result of the lazy scene probe; retained for diagnostics and probe de-duping. */\n sceneCompatibility?: 'full' | 'partial' | 'static-only'\n unsupportedFeatures?: string[]\n /** Fullscreen authored layer placed beneath the live player when needed. */\n sceneBaseUrl?: string | null\n /** Hide the player only when an unsupported script makes a later opaque layer invalid. */\n preferSceneBase?: boolean\n /** Decoded fullscreen artwork discovered from the scene manifest. */\n previewUrl: string | null\n}\n\n/** The persisted wallpaper section shape. */\ninterface WallpaperSection {\n enabled?: boolean\n selection?: string\n mode?: 'live' | 'frame'\n fit?: 'cover' | 'contain' | 'fill'\n pauseOnHidden?: boolean\n dim?: number\n wallpaperBlur?: number\n /** Opacity of the wallpaper media layer itself, 0-100 percent. */\n wallpaperOpacity?: number\n /** Audible video wallpaper playback (default off = muted, #580). */\n sound?: boolean\n /** Wallpaper audio volume 0-100 (default 100). */\n volume?: number\n weLibraryDirs?: string[]\n}\n\n/** The face the skin-center card injects for the wallpaper feature. */\nexport interface WallpaperHandle {\n enabled(): boolean\n /** The persisted selection id ('' = none). */\n selection(): string\n mode(): 'live' | 'frame'\n fit(): 'cover' | 'contain' | 'fill'\n dim(): number\n wallpaperBlur(): number\n /** Opacity of the wallpaper media layer itself, 0-100. */\n wallpaperOpacity(): number\n pauseOnHidden(): boolean\n /** Audible playback for video wallpapers (default false = muted). */\n sound(): boolean\n /** Wallpaper audio volume 0-100. */\n volume(): number\n /** Manual library folders (settings field weLibraryDirs). */\n dirs(): string[]\n /** Add a manual library folder (trimmed, deduped) and persist. */\n addDir(dir: string): void\n /** Remove a manual library folder and persist. */\n removeDir(dir: string): void\n /**\n * Open the host's native directory picker (the SDK's loopback-only\n * host.pickDirectory: Finder on macOS, Explorer on Windows). Resolves to\n * the chosen absolute path, or null when the user cancelled. Rejects when\n * the native capability is unavailable (e.g. a paired remote client), in\n * which case the manual input remains the fallback. Optional: faces\n * without host access omit it and the panel hides the browse button.\n */\n pickDir?(): Promise<string | null>\n /** The currently mounted wallpaper id (try-on included), or null. */\n activeId(): string | null\n /** True while a try-on mount is up. */\n trying(): boolean\n subscribe(listener: () => void): () => void\n setEnabled(value: boolean): void\n setMode(mode: 'live' | 'frame'): void\n setFit(fit: 'cover' | 'contain' | 'fill'): void\n setDim(value: number): void\n setBlur(value: number): void\n setOpacity(value: number): void\n setPauseOnHidden(value: boolean): void\n setSound(value: boolean): void\n setVolume(value: number): void\n /** Persist + render a selection. */\n applySelection(descriptor: WallpaperDescriptor): void\n /** Unmount + clear the persisted selection. */\n clearSelection(): void\n /**\n * Reconcile the mounted layer with the persisted selection: the card\n * resolves the selection id against the inventory and calls this with the\n * descriptor (or null when the wallpaper is gone / none selected).\n */\n sync(descriptor: WallpaperDescriptor | null): void\n /** Mount a temporary preview (the applied selection is kept, not lost). */\n tryOn(descriptor: WallpaperDescriptor): void\n /** Drop the try-on mount and restore the applied selection, if any. */\n exitTryOn(): void\n /** Reconcile a live scene player after an external theme/compositor change. */\n recoverScenePlayer(): void\n dispose(): void\n}\n\nconst clamp = (value: number, min: number, max: number): number =>\n Math.max(min, Math.min(max, Math.round(value)))\n\n/** Style one fixed, non-interactive, under-everything wallpaper layer. */\nfunction styleLayer(element: HTMLElement, zIndex: number, layer: 'media' | 'scrim'): void {\n element.dataset.dshWallpaperLayer = layer\n element.style.position = 'fixed'\n element.style.inset = '0'\n element.style.zIndex = String(zIndex)\n element.style.pointerEvents = 'none'\n element.style.overflow = 'hidden'\n element.setAttribute('aria-hidden', 'true')\n}\n\n/** Style a full-bleed cover child (video / img / iframe). */\nfunction styleCover(element: HTMLElement, fit: 'cover' | 'contain' | 'fill' = 'cover'): void {\n element.style.width = '100%'\n element.style.height = '100%'\n element.style.objectFit = fit\n element.style.border = '0'\n element.style.display = 'block'\n}\n\n/** Max static-frame capture edge (the backdrop never needs more pixels). */\nconst FRAME_MAX_EDGE = 1920\n\nconst MIN_VIEWPORT_SURFACE_HEIGHT = 0.9\nconst MAX_SURFACE_OVERLAY_Z_INDEX = 100\n\n/** Any nontransparent background blocks some of the wallpaper. */\nfunction hasVisibleBackground(color: string): boolean {\n const normalized = color.trim().toLowerCase()\n if (normalized === '' || normalized === 'transparent') return false\n const match = normalized.match(/^[a-z-]+\\((.*)\\)$/)\n if (match === null) return true\n const args = match[1]\n const slash = args.lastIndexOf('/')\n if (slash >= 0) return hasVisibleAlpha(args.slice(slash + 1))\n const channels = args.split(',')\n return channels.length === 4 ? hasVisibleAlpha(channels[3] ?? '') : true\n}\n\nfunction hasVisibleAlpha(value: string): boolean {\n const alpha = Number.parseFloat(value)\n return Number.isFinite(alpha) && alpha > 0\n}\n\n/** Exclude owned layers plus modal/plugin/sidebar/details surfaces that must retain their paint. */\nfunction isExcludedWallpaperSurface(el: HTMLElement, zIndex: string): boolean {\n const semanticOverlay = typeof el.closest === 'function'\n && el.closest(\n '[data-dsh-wallpaper-layer], dialog, [role=\"dialog\"], [aria-modal=\"true\"], [data-shell-overlay], [data-slot=\"shell.overlay\"], [data-dsh-plugin], [data-slot=\"sidebar\"], [data-dsh-surface=\"sidebar\"], [data-slot=\"sidebar.workspaces\"], [data-pane=\"sidebar\"], aside, [data-slot=\"details\"], [data-dsh-surface=\"details\"], [data-pane=\"details\"], [class*=\"detailsCol\"], .aionui-root, [data-aionui-explorer-col], [data-aionui-preview-col], [data-dsh-better-sidebar], [data-dsh-panel-host]',\n ) !== null\n if (semanticOverlay) return true\n const numericZIndex = Number.parseFloat(zIndex)\n return Number.isFinite(numericZIndex) && numericZIndex > MAX_SURFACE_OVERLAY_Z_INDEX\n}\n\n/**\n * Default shell-surface detector for WE wallpaper neutralization (#712). A\n * target must cover most of the visible viewport and paint a nontransparent\n * background. It deliberately avoids equality against a theme token because\n * real shell surfaces can resolve a different or partially transparent color.\n * Modal and plugin overlays stay out of scope even when they fill the viewport.\n */\nexport function defaultWallpaperSurface(el: HTMLElement, doc: Document): boolean {\n const win = doc.defaultView\n if (win === null) return false\n let rectHeight = 0\n let viewportHeight = 0\n let background = ''\n let zIndex = ''\n try {\n rectHeight = el.getBoundingClientRect().height\n viewportHeight = doc.documentElement.clientHeight || win.innerHeight || 0\n const cs = win.getComputedStyle(el)\n background = cs.backgroundColor\n zIndex = cs.zIndex\n } catch {\n return false\n }\n // Only a rendered surface can obscure the wallpaper. In particular, avoid\n // tagging a hidden subtree before it has a real layout box. Upstream #712:\n // color-independent (any visible background) + min viewport coverage, so a\n // full-height shell surface no longer misses the mark on a token mismatch.\n const fillsViewport = viewportHeight > 0\n && rectHeight >= viewportHeight * MIN_VIEWPORT_SURFACE_HEIGHT\n return fillsViewport\n && hasVisibleBackground(background)\n && !isExcludedWallpaperSurface(el, zIndex)\n}\n\n/**\n * Workspace-list end-fade detector (#734): a gradient-background element inside\n * the sidebar workspaces slot. The official `data-slot=\"sidebar.workspaces\"`\n * anchor is stable; the fade element only carries hashed CSS-module classes, so\n * this selects it by computed style instead of class names.\n */\nexport function defaultWorkspaceFade(el: HTMLElement, doc: Document): boolean {\n const win = doc.defaultView\n if (win === null) return false\n try {\n return win.getComputedStyle(el).backgroundImage.includes('gradient')\n } catch {\n return false\n }\n}\n\nexport interface WallpaperControllerOptions {\n apiBase?: string\n fetchImpl?: typeof fetch\n doc?: Document\n /** Override the full-viewport-surface detector (tests); defaults to the\n * computed-style heuristic in defaultWallpaperSurface. */\n declareSurface?: (el: HTMLElement, doc: Document) => boolean\n /** Override the sidebar workspaces end-fade detector (tests); defaults to\n * defaultWorkspaceFade. */\n declareWorkspaceFade?: (el: HTMLElement, doc: Document) => boolean\n /** Trailing debounce for the surface re-scan (ms). Coalesces burst DOM\n * mutations (chat streaming) into one settled sweep; tests pass 0 to flush\n * right after rAF. Defaults to 150. */\n surfaceTrailMs?: number\n /** Override the light/dark theme detector (tests); defaults to\n * body[data-ds-dark-theme] presence. */\n themeGet?: () => 'light' | 'dark'\n}\n\n/**\n * Own the skin-wallpaper scope: keep the mounted layers in sync with the\n * persisted selection and the card-driven descriptor resolution.\n */\nexport class WallpaperController implements WallpaperHandle {\n private enabledValue = true\n private selectionValue = ''\n private modeValue: 'live' | 'frame' = 'live'\n private fitValue: 'cover' | 'contain' | 'fill' = 'cover'\n private pauseOnHiddenValue = true\n private soundValue = false\n private volumeValue = 100\n private dimValue = 25\n private blurValue = 0\n private opacityValue = 100\n private dirsValue: string[] = []\n private readonly listeners = new Set<() => void>()\n private readonly scope: SettingsScope<WallpaperSection>\n private readonly unsubscribe: () => void\n private readonly options: WallpaperControllerOptions\n private readonly doc: Document\n\n /** The descriptor of the applied selection, resolved by the card. */\n private applied: WallpaperDescriptor | null = null\n /** The try-on descriptor while a preview is up. */\n private previewing: WallpaperDescriptor | null = null\n\n private mediaLayer: HTMLDivElement | null = null\n private scrimLayer: HTMLDivElement | null = null\n private videoElement: HTMLVideoElement | null = null\n private rootNeutralizer: HTMLStyleElement | null = null\n /** Re-asserts the wallpaper layers if the shell tears the body subtree down. */\n private mountObserver: MutationObserver | null = null\n /** Re-tags full-viewport surfaces after navigation rebuilds #root (#805). */\n private surfaceObserver: MutationObserver | null = null\n /** Shell surfaces tagged with data-dsh-wallpaper-surface during this mount. */\n private taggedSurfaces = new Set<HTMLElement>()\n private disposed = false\n /** In-flight scene probes by wallpaper id; overlapping entry points\n * (applySelection / tryOn / sync / fetchAndSync) must not re-read the\n * same packed scene concurrently. */\n private probePending = new Map<string, Promise<void>>()\n /** Detached frame-capture video; released on error/abort/loadeddata and on\n * teardown so it never keeps buffering the source file. */\n private captureVideo: HTMLVideoElement | null = null\n /** Guard flag: suppresses readAll during applyThemeDefaults scope writes\n * to prevent mid-write listener cascades from resetting values. */\n private seeding = false\n\n constructor(scope: SettingsScope<WallpaperSection>, options: WallpaperControllerOptions = {}) {\n this.scope = scope\n this.options = options\n this.doc = options.doc ?? document\n this.readAll()\n this.unsubscribe = scope.subscribe(() => {\n if (this.disposed || this.seeding) return\n this.readAll()\n if (this.enabledValue && this.selectionValue && (!this.applied || this.applied.id !== this.selectionValue)) {\n this.fetchAndSync()\n } else {\n this.render()\n this.publish()\n }\n })\n // Pause-on-hidden wiring lives for the controller's whole life; it only\n // ever acts while a video is mounted.\n this.doc.addEventListener('visibilitychange', this.onVisibility)\n this.doc.defaultView?.addEventListener('message', this.onSceneMessage)\n // Audible autoplay stays blocked until the first user gesture; retry\n // play() on that gesture so an unmuted live wallpaper starts (#580).\n this.doc.addEventListener('pointerdown', this.onFirstGesture)\n this.doc.addEventListener('keydown', this.onFirstGesture)\n // Some DSH navigation (e.g. switching conversations) tears down the body\n // subtree, which removes the wallpaper layers while the selection is\n // still active. Re-mount them so the wallpaper does not disappear (#805).\n const win = this.doc.defaultView\n if (win !== null && typeof win.MutationObserver === 'function') {\n this.mountObserver = new win.MutationObserver(() => {\n if (this.disposed) return\n if ((this.previewing ?? this.applied) === null) return\n if (this.mediaLayer === null || !this.mediaLayer.isConnected) {\n this.render()\n }\n })\n this.mountObserver.observe(this.doc.body, { childList: true })\n }\n // Theme-aware defaults (#1051): when the scope has no explicit dim or\n // opacity (both sit at schema defaults), seed values tuned for the\n // current light/dark theme so text is readable out of the box.\n this.applyThemeDefaults()\n if (this.enabledValue && this.selectionValue) {\n this.fetchAndSync()\n }\n }\n\n private fetchAndSync(): void {\n if (!this.selectionValue || !this.doc) return\n const targetId = this.selectionValue\n const fetchFn = this.options.fetchImpl ?? (typeof fetch !== 'undefined' ? fetch.bind(this.doc.defaultView ?? globalThis) : undefined)\n if (!fetchFn) return\n const apiBase = this.options.apiBase ?? '/api/skin-center/we'\n fetchFn(`${apiBase}/inventory`)\n .then(async (response) => {\n if (this.disposed || !response.ok) return\n const payload = (await response.json().catch(() => null)) as {\n ok?: boolean\n wallpapers?: WallpaperDescriptor[]\n } | null\n if (payload?.ok === true && Array.isArray(payload.wallpapers)) {\n const item = payload.wallpapers.find((w) => w.id === targetId)\n if (item && this.selectionValue === targetId) {\n this.applied = item\n this.render()\n this.publish()\n this.probeSceneCapabilitiesIfNeeded(item)\n }\n }\n })\n .catch(() => {\n // Fail-silent on network errors\n })\n }\n\n /**\n * Lazily probe a scene's video/WebGL capabilities: the inventory never\n * reads packed scene payloads, so only the wallpaper the user actually\n * selects (apply, try-on or boot sync) asks the probe route. The response\n * is merged into every slot (previewing and applied) that holds the id.\n */\n private probeSceneCapabilitiesIfNeeded(descriptor: WallpaperDescriptor): void {\n if (this.disposed || descriptor.type !== 'scene' || descriptor.videoUrl !== null || descriptor.sceneUrl != null || descriptor.sceneCompatibility !== undefined) return\n const targetId = descriptor.id\n if (this.probePending.has(targetId)) return\n const fetchFn = this.options.fetchImpl ?? (typeof fetch !== 'undefined' ? fetch.bind(this.doc.defaultView ?? globalThis) : undefined)\n if (!fetchFn) return\n const apiBase = this.options.apiBase ?? '/api/skin-center/we'\n const pending = fetchFn(apiBase + '/scene-probe?id=' + encodeURIComponent(targetId))\n .then(async (response) => {\n if (this.disposed || !response.ok) return\n const payload = (await response.json().catch(() => null)) as {\n ok?: boolean\n videoUrl?: string | null\n sceneUrl?: string | null\n compatibility?: 'full' | 'partial' | 'static-only'\n unsupportedFeatures?: string[]\n } | null\n if (!payload || payload.ok !== true) return\n let sceneBaseUrl: string | null = null\n let preferSceneBase = false\n if (payload.sceneUrl && payload.compatibility === 'partial'\n && payload.unsupportedFeatures?.includes('embedded-script') === true) {\n try {\n const manifestResponse = await fetchFn(payload.sceneUrl.replace('/scene-runtime/', '/scene-manifest/'))\n const manifestPayload = manifestResponse.ok\n ? await manifestResponse.json().catch(() => null) as {\n ok?: boolean\n manifest?: {\n width?: number\n height?: number\n timeSchedule?: unknown\n layers?: Array<{ x?: number; y?: number; w?: number; h?: number; texUrl?: string; videoUrl?: string }>\n }\n } | null\n : null\n const manifest = manifestPayload?.ok === true ? manifestPayload.manifest : undefined\n // The renderer implements author-configured real-time switching;\n // do not replace that live player with one static base merely because\n // unrelated embedded scripts remain unsupported.\n if (manifest && manifest.timeSchedule === undefined && typeof manifest.width === 'number' && typeof manifest.height === 'number') {\n // Video-backed layers serve MP4 bytes: a CSS background cannot\n // paint them, so only still-image layers qualify as the base.\n const fullscreenIndex = manifest.layers?.findIndex(layer =>\n typeof layer.texUrl === 'string'\n && typeof layer.videoUrl !== 'string'\n && Math.abs((layer.w ?? 0) - manifest.width!) <= 1\n && Math.abs((layer.h ?? 0) - manifest.height!) <= 1\n && Math.abs((layer.x ?? 0) - manifest.width! / 2) <= 1\n && Math.abs((layer.y ?? 0) - manifest.height! / 2) <= 1\n ) ?? -1\n if (fullscreenIndex >= 0) {\n sceneBaseUrl = manifest.layers?.[fullscreenIndex]?.texUrl ?? null\n // A later oversized layer is generally a script-controlled\n // project/compose surface. It can cover the real artwork when\n // its script is unsupported; ordinary multi-layer scenes keep\n // the live player visible.\n preferSceneBase = manifest.layers?.slice(fullscreenIndex + 1).some(layer =>\n (layer.w ?? 0) > manifest.width! * 1.25\n || (layer.h ?? 0) > manifest.height! * 1.25\n ) === true\n }\n }\n } catch {\n // Keep the regular scene frame/player fallback.\n }\n }\n if (this.disposed) return\n // Compatibility metadata is retained for diagnostics and probe de-duping.\n // Partial scenes still use their actual scene runtime: unsupported scripts\n // may omit individual effects, but the decoded Wallpaper Engine layers and\n // supported particles must remain dynamic rather than becoming a cover.\n // Merge the capabilities into every slot holding the id: a probe\n // issued by try-on may land while sync/apply has already installed\n // the same wallpaper as applied, and exiting the try-on must not\n // fall back to a static frame without capabilities.\n let changed = false\n if (this.previewing?.id === targetId) {\n const merged: WallpaperDescriptor = {\n ...this.previewing,\n videoUrl: payload.videoUrl ?? this.previewing.videoUrl,\n sceneUrl: payload.sceneUrl ?? this.previewing.sceneUrl,\n sceneCompatibility: payload.compatibility,\n unsupportedFeatures: payload.unsupportedFeatures,\n sceneBaseUrl: sceneBaseUrl ?? this.previewing.sceneBaseUrl,\n preferSceneBase,\n }\n if (merged.videoUrl !== this.previewing.videoUrl\n || merged.sceneUrl !== this.previewing.sceneUrl\n || merged.sceneCompatibility !== this.previewing.sceneCompatibility\n || merged.sceneBaseUrl !== this.previewing.sceneBaseUrl\n || merged.preferSceneBase !== this.previewing.preferSceneBase) {\n this.previewing = merged\n changed = true\n }\n }\n if (this.applied?.id === targetId) {\n const merged: WallpaperDescriptor = {\n ...this.applied,\n videoUrl: payload.videoUrl ?? this.applied.videoUrl,\n sceneUrl: payload.sceneUrl ?? this.applied.sceneUrl,\n sceneCompatibility: payload.compatibility,\n unsupportedFeatures: payload.unsupportedFeatures,\n sceneBaseUrl: sceneBaseUrl ?? this.applied.sceneBaseUrl,\n preferSceneBase,\n }\n if (merged.videoUrl !== this.applied.videoUrl\n || merged.sceneUrl !== this.applied.sceneUrl\n || merged.sceneCompatibility !== this.applied.sceneCompatibility\n || merged.sceneBaseUrl !== this.applied.sceneBaseUrl\n || merged.preferSceneBase !== this.applied.preferSceneBase) {\n this.applied = merged\n changed = true\n }\n }\n if (!changed) return\n this.render()\n this.publish()\n })\n .catch(() => {\n // Fail-silent on network errors\n })\n .finally(() => {\n this.probePending.delete(targetId)\n })\n this.probePending.set(targetId, pending)\n }\n\n enabled = (): boolean => this.enabledValue\n selection = (): string => this.selectionValue\n mode = (): 'live' | 'frame' => this.modeValue\n fit = (): 'cover' | 'contain' | 'fill' => this.fitValue\n dim = (): number => this.dimValue\n wallpaperBlur = (): number => this.blurValue\n wallpaperOpacity = (): number => this.opacityValue\n pauseOnHidden = (): boolean => this.pauseOnHiddenValue\n sound = (): boolean => this.soundValue\n volume = (): number => this.volumeValue\n dirs = (): string[] => this.dirsValue\n\n addDir(dir: string): void {\n const trimmed = dir.trim()\n if (trimmed === '' || this.dirsValue.includes(trimmed)) return\n this.dirsValue = [...this.dirsValue, trimmed]\n this.publish()\n void this.scope.set('weLibraryDirs', this.dirsValue)\n }\n\n removeDir(dir: string): void {\n const next = this.dirsValue.filter(d => d !== dir)\n if (next.length === this.dirsValue.length) return\n this.dirsValue = next\n this.publish()\n void this.scope.set('weLibraryDirs', this.dirsValue)\n }\n\n private failedIds = new Set<string>()\n\n isDisplaying = (): boolean => {\n const id = this.activeId()\n return this.enabledValue && id !== null && !this.failedIds.has(id)\n }\n\n activeId = (): string | null => {\n const current = this.previewing ?? this.applied\n return this.mediaLayer !== null && current !== null ? current.id : null\n }\n trying = (): boolean => this.previewing !== null\n\n subscribe = (listener: () => void): (() => void) => {\n this.listeners.add(listener)\n return () => { this.listeners.delete(listener) }\n }\n\n setEnabled(value: boolean): void {\n this.enabledValue = value\n this.render()\n this.publish()\n void this.scope.set('enabled', value)\n }\n\n setMode(mode: 'live' | 'frame'): void {\n this.modeValue = mode\n this.render()\n this.publish()\n void this.scope.set('mode', mode)\n }\n\n setFit(fit: 'cover' | 'contain' | 'fill'): void {\n this.fitValue = fit\n this.render()\n this.publish()\n void this.scope.set('fit', fit)\n }\n\n setDim(value: number): void {\n this.dimValue = clamp(value, 0, 90)\n this.render()\n this.publish()\n void this.scope.set('dim', this.dimValue)\n }\n\n setBlur(value: number): void {\n this.blurValue = clamp(value, 0, 60)\n this.render()\n this.publish()\n void this.scope.set('wallpaperBlur', this.blurValue)\n }\n\n setOpacity(value: number): void {\n this.opacityValue = clamp(value, 0, 100)\n this.render()\n this.publish()\n void this.scope.set('wallpaperOpacity', this.opacityValue)\n }\n\n setPauseOnHidden(value: boolean): void {\n this.pauseOnHiddenValue = value\n this.publish()\n void this.scope.set('pauseOnHidden', value)\n }\n\n setSound(value: boolean): void {\n this.soundValue = value\n this.applySound()\n this.publish()\n void this.scope.set('sound', value)\n }\n\n setVolume(value: number): void {\n this.volumeValue = clamp(value, 0, 100)\n this.applySound()\n this.publish()\n void this.scope.set('volume', this.volumeValue)\n }\n\n applySelection(descriptor: WallpaperDescriptor): void {\n this.failedIds.delete(descriptor.id)\n this.applied = descriptor\n this.previewing = null\n this.selectionValue = descriptor.id\n this.render()\n this.publish()\n void this.scope.set('selection', descriptor.id)\n this.probeSceneCapabilitiesIfNeeded(descriptor)\n }\n\n clearSelection(): void {\n this.applied = null\n this.previewing = null\n this.selectionValue = ''\n this.render()\n this.publish()\n void this.scope.set('selection', '')\n }\n\n sync(descriptor: WallpaperDescriptor | null): void {\n // Inventory descriptors intentionally omit lazily probed scene capabilities.\n // Reopening Skin Center refreshes that inventory, so replacing an already\n // enriched descriptor verbatim would drop sceneUrl/videoUrl, rebuild the\n // media as a static frame, then probe and rebuild the live player again.\n // Preserve capabilities for the same id while still accepting every other\n // refreshed field from inventory.\n if (descriptor !== null && this.applied?.id === descriptor.id) {\n descriptor = {\n ...descriptor,\n videoUrl: descriptor.videoUrl ?? this.applied.videoUrl,\n sceneUrl: descriptor.sceneUrl ?? this.applied.sceneUrl,\n sceneCompatibility: descriptor.sceneCompatibility ?? this.applied.sceneCompatibility,\n unsupportedFeatures: descriptor.unsupportedFeatures ?? this.applied.unsupportedFeatures,\n sceneBaseUrl: descriptor.sceneBaseUrl ?? this.applied.sceneBaseUrl,\n preferSceneBase: descriptor.preferSceneBase ?? this.applied.preferSceneBase,\n }\n }\n this.applied = descriptor\n this.render()\n if (descriptor !== null) this.probeSceneCapabilitiesIfNeeded(descriptor)\n }\n\n tryOn(descriptor: WallpaperDescriptor): void {\n this.failedIds.delete(descriptor.id)\n this.previewing = descriptor\n this.render()\n this.publish()\n this.probeSceneCapabilitiesIfNeeded(descriptor)\n }\n\n exitTryOn(): void {\n if (this.previewing === null) return\n this.previewing = null\n this.render()\n this.publish()\n }\n\n recoverScenePlayer(): void {\n const scenePlayer = this.mediaLayer?.firstElementChild ?? null\n if (!(scenePlayer instanceof HTMLIFrameElement) || scenePlayer.dataset.dshScenePlayer !== '') return\n try {\n // The sandboxed player has an opaque origin, so a same-origin target\n // would never match it; '*' delivers to the single identified window.\n scenePlayer.contentWindow?.postMessage({ type: 'dsh-recover-renderer' }, '*')\n } catch {\n // A failed recovery message is harmless; the next render keeps the current frame.\n }\n }\n\n dispose(): void {\n if (this.disposed) return\n this.disposed = true\n this.unsubscribe()\n this.mountObserver?.disconnect()\n this.mountObserver = null\n this.doc.removeEventListener('visibilitychange', this.onVisibility)\n this.doc.defaultView?.removeEventListener('message', this.onSceneMessage)\n this.doc.removeEventListener('pointerdown', this.onFirstGesture)\n this.doc.removeEventListener('keydown', this.onFirstGesture)\n this.teardownLayers()\n }\n\n // --- internals -----------------------------------------------------------\n\n /**\n * Seed dim and opacity with theme-tuned values when neither has been\n * explicitly set (both are at schema defaults: dim=25, opacity=100).\n * This runs once at construction so a fresh wallpaper install gets\n * readable defaults for the active theme. Users who have already\n * adjusted either slider keep their values (#1051).\n */\n private applyThemeDefaults(): void {\n const snapshot = this.scope.getSnapshot()\n const value = snapshot.value ?? {}\n // Detect whether dim and opacity have never been written to the scope.\n // A value of undefined means the field was never persisted; any number\n // (even the schema default 25 for dim) means the user or a prior seed\n // already set it, so we must not overwrite.\n if (value.dim !== undefined || value.wallpaperOpacity !== undefined) return\n // The scope may not yet be writable during early initialization.\n if (snapshot.writable === false) return\n const theme = this.options.themeGet !== undefined\n ? this.options.themeGet()\n : (this.doc.body?.hasAttribute('data-ds-dark-theme') ? 'dark' : 'light')\n if (theme === 'light') {\n this.dimValue = 0\n this.opacityValue = 40\n } else {\n this.dimValue = 40\n this.opacityValue = 100\n }\n this.seeding = true\n try {\n void this.scope.set('dim', this.dimValue)\n void this.scope.set('wallpaperOpacity', this.opacityValue)\n } catch { /* scope not ready — values stay local until next readAll */ }\n this.seeding = false\n }\n\n private readAll(): void {\n const snapshot: SettingsScopeSnapshot<WallpaperSection> = this.scope.getSnapshot()\n const value = snapshot.value ?? {}\n this.enabledValue = typeof value.enabled === 'boolean' ? value.enabled : true\n this.selectionValue = typeof value.selection === 'string' ? value.selection : ''\n this.modeValue = value.mode === 'frame' ? 'frame' : 'live'\n const rawFit = value.fit\n this.fitValue = rawFit === 'contain' || rawFit === 'fill' ? rawFit : 'cover'\n this.pauseOnHiddenValue = typeof value.pauseOnHidden === 'boolean' ? value.pauseOnHidden : true\n this.soundValue = typeof value.sound === 'boolean' ? value.sound : false\n this.volumeValue = typeof value.volume === 'number' && Number.isFinite(value.volume)\n ? clamp(value.volume, 0, 100)\n : 100\n this.dimValue = typeof value.dim === 'number' && Number.isFinite(value.dim) ? clamp(value.dim, 0, 90) : 25\n this.blurValue = typeof value.wallpaperBlur === 'number' && Number.isFinite(value.wallpaperBlur)\n ? clamp(value.wallpaperBlur, 0, 60)\n : 0\n this.opacityValue = typeof value.wallpaperOpacity === 'number' && Number.isFinite(value.wallpaperOpacity)\n ? clamp(value.wallpaperOpacity, 0, 100)\n : 100\n this.dirsValue = Array.isArray(value.weLibraryDirs)\n ? value.weLibraryDirs.filter((d): d is string => typeof d === 'string' && d.trim() !== '')\n : []\n }\n\n /** Resume a policy-blocked video on the first user gesture (#580). */\n private readonly onFirstGesture = (): void => {\n if (this.videoElement === null || !this.videoElement.paused) return\n // jsdom (and older engines) return undefined, real browsers a promise.\n void this.videoElement.play()?.catch(() => { /* still blocked: retry on the next gesture */ })\n }\n\n private readonly onSceneMessage = (event: MessageEvent): void => {\n const scenePlayer = this.mediaLayer?.firstElementChild ?? null\n if (!(scenePlayer instanceof HTMLIFrameElement) || scenePlayer.dataset.dshScenePlayer !== '') return\n // The player is sandboxed without allow-same-origin, so its opaque origin\n // arrives as Origin \"null\"; only the identity of the sender (this exact\n // iframe window) proves the message came from the mounted player.\n if (event.source !== scenePlayer.contentWindow) return\n const message = event.data as { type?: unknown } | null\n if (message?.type !== 'dsh-scene-needs-reload') return\n // Context restoration invalidates every WebGL object. Reloading only the\n // isolated renderer keeps the wallpaper selection and shell state intact.\n scenePlayer.src = scenePlayer.src\n }\n\n private readonly onVisibility = (): void => {\n if (!this.pauseOnHiddenValue) return\n if (this.videoElement !== null) {\n if (this.doc.hidden) {\n this.videoElement.pause()\n } else {\n // jsdom (and older engines) return undefined, real browsers a promise.\n void this.videoElement.play()?.catch(() => { /* autoplay policy */ })\n }\n }\n const scenePlayer = this.mediaLayer?.firstElementChild ?? null\n if (scenePlayer instanceof HTMLIFrameElement && scenePlayer.dataset.dshScenePlayer === '') {\n try {\n // '*' reaches the opaque-origin sandboxed player (see applyFit).\n scenePlayer.contentWindow?.postMessage({ type: 'dsh-set-pause', paused: this.doc.hidden }, '*')\n } catch {\n // ignore\n }\n }\n }\n\n /** Reconcile the DOM with (enabled, previewing ?? applied, mode, dim, blur). */\n private render(): void {\n if (this.disposed) return\n const current = this.enabledValue ? (this.previewing ?? this.applied) : null\n if (current === null) {\n this.teardownLayers()\n return\n }\n this.ensureLayers(current)\n }\n\n private ensureLayers(descriptor: WallpaperDescriptor): void {\n // The stock shell paints opaque backgrounds on the app root and on the\n // composer seat, which fully cover the negative-z wallpaper layers\n // (issue #505, #632). Neutralize them ONLY while the own marker\n // data-dsh-wallpaper-active is present, so no skin or plugin style is\n // affected outside a mounted wallpaper (#506). The app-root rules mirror\n // the contract the v2 skin CSS pipeline appends for every skin\n // (`[id=\"root\"] { background: transparent }`); the id/attribute selectors\n // outrank the shell's class rules, and the --dsw-alias-bg-base token\n // itself is left untouched for every other consumer.\n if (this.rootNeutralizer === null) {\n this.rootNeutralizer = this.doc.createElement('style')\n this.rootNeutralizer.dataset.dshWallpaperRoot = ''\n this.rootNeutralizer.textContent = `\n [id=\"root\"] { background: transparent; }\n /* Wallpaper opacity backdrop (#1051): light-mode fades to white,\n dark-mode fades to black. :has() tracks theme switches live. */\n html[data-dsh-wallpaper-active] {\n background-color: white !important;\n background-image: none !important;\n }\n html[data-dsh-wallpaper-active]:has(body[data-ds-dark-theme]) {\n background-color: black !important;\n }\n body[data-dsh-wallpaper-active],\n html[data-dsh-skin][data-dsh-wallpaper-active] body,\n html[data-dsh-skin] body[data-dsh-wallpaper-active],\n body[data-dsh-wallpaper-active][data-ds-dark-theme],\n html[data-dsh-wallpaper-active] [id=\"root\"] {\n background-color: transparent !important;\n background-image: none !important;\n }\n /* Seat-wide skin pseudos would blur the whole footer. The shared dock\n row owns the compact rounded transcript mask instead (#777/#978). */\n html[data-dsh-wallpaper-active] [data-composer-seat]::before {\n background: none !important;\n backdrop-filter: none !important;\n }\n /* Full-viewport shell surfaces (AppFrame frame, conversation root,\n details root) paint the opaque app base background via hashed\n CSS-module classes. While a WE wallpaper is mounted the controller\n tags them with the own marker data-dsh-wallpaper-surface\n (markWallpaperSurfaces), and this rule neutralizes them with no\n class-name dependency (issue #734). */\n html[data-dsh-wallpaper-active] [data-dsh-wallpaper-surface] {\n background-color: transparent !important;\n background-image: none !important;\n }\n `\n this.doc.head.appendChild(this.rootNeutralizer)\n }\n this.doc.body.dataset.dshWallpaperActive = 'true'\n this.doc.documentElement.dataset.dshWallpaperActive = 'true'\n // Report the wallpaper into the unified \"backdrop visible\" marker so the\n // shared composer-seat neutralizer applies here too (issue #777).\n setSceneBackdropActive(this.doc, 'wallpaper', true)\n this.markSurfaces()\n this.ensureSurfaceObserver()\n // Connect-aware: navigation (e.g. switching conversations) can tear the\n // wallpaper layers out of the body subtree while the references survive.\n // Re-append the surviving layer instead of recreating it, so the media\n // child and its mediaKey survive and the video is not rebuilt / restarted\n // (#805). Only build a fresh layer when there is none at all.\n if (this.mediaLayer !== null && !this.mediaLayer.isConnected) {\n this.doc.body.appendChild(this.mediaLayer)\n }\n if (this.mediaLayer === null) {\n this.mediaLayer = this.doc.createElement('div')\n styleLayer(this.mediaLayer, -3, 'media')\n this.doc.body.appendChild(this.mediaLayer)\n }\n if (this.scrimLayer !== null && !this.scrimLayer.isConnected) {\n this.doc.body.appendChild(this.scrimLayer)\n }\n if (this.scrimLayer === null) {\n this.scrimLayer = this.doc.createElement('div')\n styleLayer(this.scrimLayer, -2, 'scrim')\n this.doc.body.appendChild(this.scrimLayer)\n }\n // Keep the inventory preview painted beneath live scene iframes. A WebGL\n // context can be temporarily lost (or its canvas can clear before the\n // isolated player reloads); without this backing frame the transparent\n // iframe exposes only the shell gradient and looks like the wallpaper was\n // removed. Video/web wallpapers paint their own opaque media, so they do\n // not need a duplicate backdrop.\n const sceneBackdrop = descriptor.type === 'scene'\n ? (descriptor.sceneBaseUrl ?? descriptor.frameUrl ?? descriptor.previewUrl)\n : null\n this.mediaLayer.style.backgroundImage = sceneBackdrop === null ? '' : `url(${JSON.stringify(sceneBackdrop)})`\n this.mediaLayer.style.backgroundPosition = sceneBackdrop === null ? '' : 'center'\n this.mediaLayer.style.backgroundRepeat = sceneBackdrop === null ? '' : 'no-repeat'\n this.mediaLayer.style.backgroundSize = sceneBackdrop === null\n ? ''\n : (this.fitValue === 'fill' ? '100% 100%' : this.fitValue)\n // Capabilities (videoUrl/sceneUrl) participate in the key: the lazy\n // scene probe merges them into the same descriptor id after the first\n // render, and the static frame must be rebuilt as live media.\n const mediaKey = descriptor.id + ':' + this.modeValue\n + ':' + (descriptor.videoUrl ?? '') + ':' + (descriptor.sceneUrl ?? '')\n + ':' + (descriptor.sceneCompatibility ?? '')\n + ':' + (descriptor.unsupportedFeatures?.join(',') ?? '')\n + ':' + (descriptor.sceneBaseUrl ?? '') + ':' + String(descriptor.preferSceneBase ?? false)\n if (this.mediaLayer.dataset.mediaKey !== mediaKey) {\n this.mediaLayer.dataset.mediaKey = mediaKey\n // A media transition (frame->live, mode switch) abandons the current\n // capture: release its src before replacing, otherwise the detached\n // video keeps buffering until teardown or the next capture.\n this.releaseCaptureVideo()\n this.mediaLayer.replaceChildren()\n this.videoElement = null\n const child = this.buildMedia(descriptor)\n if (child !== null) {\n this.mediaLayer.appendChild(child)\n // The initial play() in buildVideo ran while the element was detached\n // and may have been rejected; retry once mounted so large files start\n // streaming without a user gesture (#805 loading).\n if (child instanceof HTMLVideoElement && child.paused) {\n void child.play()?.catch(() => { /* retried on first gesture */ })\n }\n }\n } else {\n // Kept the surviving layer (mediaKey matched): some browsers pause a\n // <video> when it is torn out of the DOM, and the rebuild path above is\n // skipped, so its play retry never ran — resume playback explicitly.\n // Using the window-local constructor: jsdom (and isolated test envs)\n // may not surface the global HTMLVideoElement binding in every context.\n const child = this.mediaLayer.firstElementChild\n const VideoCtor = this.doc.defaultView?.HTMLVideoElement\n if (VideoCtor !== undefined && child instanceof VideoCtor && child.paused) {\n void child.play()?.catch(() => { /* autoplay policy: stays paused until gesture */ })\n }\n }\n // Sizing mode changes apply in place: rebuilding would restart video\n // playback and re-parse the scene on every click (#717 follow-up).\n this.applyFit()\n // Blur the wallpaper itself (the -1 backdrop-filter element stays the\n // skin-center blur control's business and blurs everything behind).\n const blur = this.blurValue > 0 ? 'blur(' + String(this.blurValue) + 'px)' : ''\n this.mediaLayer.style.filter = blur\n this.mediaLayer.style.transform = this.blurValue > 0 ? 'scale(1.05)' : ''\n // Wallpaper opacity (#1051): the html element's neutralizer background is\n // now black (not transparent) so reducing opacity fades toward black.\n this.mediaLayer.style.opacity = this.opacityValue < 100 ? String(this.opacityValue / 100) : ''\n this.scrimLayer.style.background = 'rgba(0, 0, 0, ' + String(this.dimValue / 100) + ')'\n }\n\n /** Push the current sizing mode onto the mounted media element. */\n private applyFit(): void {\n const child = this.mediaLayer?.firstElementChild ?? null\n if (child instanceof HTMLElement) {\n styleCover(child, this.fitValue)\n }\n if (child instanceof HTMLIFrameElement && child.dataset.dshScenePlayer === '') {\n try {\n // The player frame is sandboxed without allow-same-origin, so its\n // origin is opaque and a real-origin targetOrigin would drop the\n // message; '*' delivers to the identified contentWindow.\n child.contentWindow?.postMessage({ type: 'dsh-set-fit', fit: this.fitValue }, '*')\n } catch {\n // ignore: the player also receives the fit on its own load handler\n }\n }\n }\n\n /** Build the cover child for one descriptor + mode; null when unrenderable. */\n private buildMedia(descriptor: WallpaperDescriptor): HTMLElement | null {\n if (descriptor.type === 'video') {\n if (this.modeValue === 'live' && descriptor.videoUrl !== null) {\n return this.buildVideo(descriptor.videoUrl)\n }\n if (descriptor.videoUrl !== null) {\n return this.buildVideoFrame(descriptor.videoUrl, descriptor.previewUrl)\n }\n return this.buildImage(descriptor.previewUrl)\n }\n if (descriptor.type === 'web') {\n if (this.modeValue === 'live' && descriptor.webUrl !== null) {\n const iframe = this.doc.createElement('iframe')\n iframe.src = descriptor.webUrl\n // Web wallpapers are third-party HTML downloaded from the Workshop /\n // user directories and run with the host same-origin, so they must be\n // isolated: allow-scripts only gives an opaque origin (no parent DOM,\n // no host storage, no same-origin /api access). Script-only sandboxing\n // keeps textures/canvas/WebGL working; localStorage / cookies degrade.\n iframe.setAttribute('sandbox', 'allow-scripts')\n iframe.setAttribute('tabindex', '-1')\n styleCover(iframe, this.fitValue)\n return iframe\n }\n return this.buildImage(descriptor.previewUrl)\n }\n if (descriptor.type === 'scene') {\n if (this.modeValue === 'live' && descriptor.videoUrl !== null) {\n return this.buildVideo(descriptor.videoUrl, descriptor.frameUrl, descriptor.previewUrl)\n }\n if (this.modeValue === 'live' && descriptor.sceneUrl) {\n const iframe = this.doc.createElement('iframe')\n iframe.src = descriptor.sceneUrl\n // The scene player renders third-party scene data; same isolation as\n // web wallpapers (opaque origin, steering via postMessage).\n iframe.setAttribute('sandbox', 'allow-scripts')\n iframe.setAttribute('tabindex', '-1')\n iframe.dataset.dshScenePlayer = ''\n if (descriptor.preferSceneBase === true && descriptor.sceneBaseUrl) iframe.style.opacity = '0'\n styleCover(iframe, this.fitValue)\n iframe.addEventListener('load', () => {\n try {\n iframe.contentWindow?.postMessage({ type: 'dsh-set-fit', fit: this.fitValue }, '*')\n } catch {\n // ignore\n }\n })\n return iframe\n }\n if (this.modeValue === 'frame' && descriptor.videoUrl !== null && descriptor.frameUrl === null) {\n return this.buildVideoFrame(descriptor.videoUrl, descriptor.previewUrl)\n }\n // The host frame decode yields the native full-resolution texture (1080p/4K);\n // fall back to the preview image if the scene frame decode fails (422) (#521).\n return this.buildImage(descriptor.frameUrl ?? descriptor.previewUrl, descriptor.previewUrl)\n }\n return this.buildImage(descriptor.previewUrl)\n }\n\n /** Push the persisted sound/volume settings onto the mounted video. */\n private applySound(): void {\n if (this.videoElement === null) return\n this.videoElement.muted = !this.soundValue\n this.videoElement.volume = this.volumeValue / 100\n }\n\n private buildVideo(url: string, frameUrl: string | null = null, previewUrl: string | null = null): HTMLVideoElement {\n const video = this.doc.createElement('video')\n video.src = url\n video.muted = !this.soundValue\n video.volume = this.volumeValue / 100\n video.loop = true\n video.autoplay = true\n video.playsInline = true\n // Large local files may have the moov atom at the end: preload auto makes\n // Chromium fetch metadata eagerly instead of waiting for a gesture.\n video.preload = 'auto'\n video.setAttribute('aria-hidden', 'true')\n styleCover(video, this.fitValue)\n this.videoElement = video\n if (frameUrl !== null || previewUrl !== null) {\n video.addEventListener('error', () => {\n const nextUrl = frameUrl ?? previewUrl\n const nextFallback = frameUrl !== null ? previewUrl : null\n const img = this.buildImage(nextUrl, nextFallback)\n if (img && video.parentElement) {\n video.parentElement.replaceChild(img, video)\n } else {\n const currentId = this.previewing?.id ?? this.applied?.id\n if (currentId) {\n this.failedIds.add(currentId)\n this.render()\n this.publish()\n }\n }\n }, { once: true })\n } else {\n video.addEventListener('error', () => {\n const currentId = this.previewing?.id ?? this.applied?.id\n if (currentId) {\n this.failedIds.add(currentId)\n this.render()\n this.publish()\n }\n }, { once: true })\n }\n // jsdom (and older engines) return undefined, real browsers a promise.\n void video.play()?.catch(() => { /* autoplay policy: stays paused */ })\n return video\n }\n\n /** Static-frame mode for video: capture the first frame into an image. */\n private buildVideoFrame(url: string, previewUrl: string | null): HTMLElement {\n const image = this.doc.createElement('img')\n styleCover(image, this.fitValue)\n if (previewUrl !== null) image.src = previewUrl\n const video = this.doc.createElement('video')\n video.muted = true\n video.playsInline = true\n video.preload = 'auto'\n video.src = url\n // The capture video is owned by the controller: it is released on\n // error/abort, on a successful capture, and on teardown, so a decode\n // failure or an early mode switch cannot leave it buffering detached.\n this.releaseCaptureVideo()\n this.captureVideo = video\n const release = (): void => {\n video.removeAttribute('src')\n video.load()\n }\n video.addEventListener('error', release, { once: true })\n video.addEventListener('abort', release, { once: true })\n video.addEventListener('loadeddata', () => {\n try {\n const scale = Math.min(1, FRAME_MAX_EDGE / Math.max(video.videoWidth, video.videoHeight))\n const canvas = this.doc.createElement('canvas')\n canvas.width = Math.max(1, Math.round(video.videoWidth * scale))\n canvas.height = Math.max(1, Math.round(video.videoHeight * scale))\n const context = canvas.getContext('2d')\n if (context !== null) {\n context.drawImage(video, 0, 0, canvas.width, canvas.height)\n image.src = canvas.toDataURL('image/jpeg', 0.85)\n }\n } catch {\n // Capture failed (codec/format): the preview image stays.\n } finally {\n // Stop buffering whether the capture succeeded or not (a missing 2d\n // context or a decode failure must not leave the hidden video\n // streaming the file).\n release()\n }\n }, { once: true })\n return image\n }\n\n private releaseCaptureVideo(): void {\n if (this.captureVideo === null) return\n this.captureVideo.removeAttribute('src')\n this.captureVideo.load()\n this.captureVideo = null\n }\n\n private buildImage(url: string | null, fallbackUrl: string | null = null): HTMLElement | null {\n if (url === null) return null\n const image = this.doc.createElement('img')\n image.src = url\n image.alt = ''\n image.addEventListener('error', () => {\n if (fallbackUrl !== null && fallbackUrl !== url && image.src !== fallbackUrl) {\n image.src = fallbackUrl\n return\n }\n const currentId = this.previewing?.id ?? this.applied?.id\n if (currentId) {\n this.failedIds.add(currentId)\n this.render()\n this.publish()\n }\n })\n styleCover(image, this.fitValue)\n return image\n }\n\n /** Tag the official shell full-viewport background surfaces (AppFrame\n * frame, conversation root, details root) and the sidebar workspace-list\n * end fade with the own marker data-dsh-wallpaper-surface so the\n * neutralizer can target them without hashed class names (#734). Idempotent\n * across renders within one mount; untagged on teardown. */\n private markSurfaces(): void {\n const root = this.doc.getElementById('root')\n if (root !== null) {\n const custom = this.options.declareSurface\n // Upstream #712 detector is color-independent (any visible background +\n // min viewport coverage), so no per-sweep token resolution is needed.\n // Custom detectors keep their own (el, doc) signature.\n const isSurface = custom !== undefined\n ? (el: HTMLElement): boolean => custom(el, this.doc)\n : (el: HTMLElement): boolean => defaultWallpaperSurface(el, this.doc)\n const stack: Element[] = [root]\n while (stack.length > 0) {\n const node = stack.pop()\n if (node === undefined) continue\n if (node instanceof HTMLElement && !node.hasAttribute('data-dsh-wallpaper-surface') && isSurface(node)) {\n node.setAttribute('data-dsh-wallpaper-surface', '')\n this.taggedSurfaces.add(node)\n }\n for (const child of Array.from(node.children)) stack.push(child)\n }\n }\n this.markWorkspaceFades()\n }\n\n /** Tag the sidebar workspaces list-end fade with the same own marker (#734). */\n private markWorkspaceFades(): void {\n const slot = this.doc.querySelector('[data-slot=\"sidebar.workspaces\"]')\n if (slot === null) return\n const isFade = this.options.declareWorkspaceFade ?? defaultWorkspaceFade\n const stack: Element[] = [slot]\n while (stack.length > 0) {\n const node = stack.pop()\n if (node === undefined) continue\n if (node instanceof HTMLElement && !node.hasAttribute('data-dsh-wallpaper-surface') && isFade(node, this.doc)) {\n node.setAttribute('data-dsh-wallpaper-surface', '')\n this.taggedSurfaces.add(node)\n }\n for (const child of Array.from(node.children)) stack.push(child)\n }\n }\n\n /**\n * Watch document.body (subtree) while a wallpaper is active and re-tag only\n * the surfaces affected by each mutation. Navigation rebuilds #root by\n * replacing its children, so the added subtrees are scanned instead of the\n * whole tree; removed nodes are untagged immediately. This avoids repeated\n * full-tree scans and forced layout during chat streaming (#review).\n */\n private ensureSurfaceObserver(): void {\n if (this.disposed || this.surfaceObserver !== null) return\n const win = this.doc.defaultView\n if (win === null || typeof win.MutationObserver !== 'function') return\n this.surfaceObserver = new win.MutationObserver((records) => this.handleSurfaceMutations(records))\n this.surfaceObserver.observe(this.doc.body, { childList: true, subtree: true })\n }\n\n /** Incrementally tag added subtrees and untag removed subtrees. */\n private handleSurfaceMutations(records: MutationRecord[]): void {\n if (this.disposed || (this.previewing ?? this.applied) === null) return\n for (const record of records) {\n for (const node of record.addedNodes) {\n if (node instanceof HTMLElement) this.tagAddedSubtree(node)\n }\n for (const node of record.removedNodes) {\n if (node instanceof HTMLElement) this.untagRemovedSubtree(node)\n }\n }\n }\n\n /** Tag newly added elements that qualify as full-viewport surfaces or workspace fades. */\n private tagAddedSubtree(root: HTMLElement): void {\n const isSurface = this.options.declareSurface !== undefined\n ? (el: HTMLElement): boolean => this.options.declareSurface!(el, this.doc)\n : (el: HTMLElement): boolean => defaultWallpaperSurface(el, this.doc)\n const isFade = this.options.declareWorkspaceFade ?? defaultWorkspaceFade\n const stack: HTMLElement[] = [root]\n while (stack.length > 0) {\n const node = stack.pop()\n if (node === undefined) continue\n if (!node.hasAttribute('data-dsh-wallpaper-surface')) {\n const inWallpaperLayer = node.closest('[data-dsh-wallpaper-layer]') !== null\n const inWorkspaces = node.closest('[data-slot=\"sidebar.workspaces\"]') !== null\n if (!inWallpaperLayer && (isSurface(node) || (inWorkspaces && isFade(node, this.doc)))) {\n node.setAttribute('data-dsh-wallpaper-surface', '')\n this.taggedSurfaces.add(node)\n }\n }\n for (const child of Array.from(node.children)) {\n if (child instanceof HTMLElement) stack.push(child)\n }\n }\n }\n\n /** Remove tags from a removed subtree and drop its references. */\n private untagRemovedSubtree(root: HTMLElement): void {\n const stack: HTMLElement[] = [root]\n while (stack.length > 0) {\n const node = stack.pop()\n if (node === undefined) continue\n if (node.hasAttribute('data-dsh-wallpaper-surface')) {\n node.removeAttribute('data-dsh-wallpaper-surface')\n this.taggedSurfaces.delete(node)\n }\n for (const child of Array.from(node.children)) {\n if (child instanceof HTMLElement) stack.push(child)\n }\n }\n }\n\n private untagSurfaces(): void {\n for (const el of Array.from(this.taggedSurfaces)) el.removeAttribute('data-dsh-wallpaper-surface')\n this.taggedSurfaces.clear()\n }\n\n private teardownLayers(): void {\n this.releaseCaptureVideo()\n this.surfaceObserver?.disconnect()\n this.surfaceObserver = null\n this.untagSurfaces()\n delete this.doc.body.dataset.dshWallpaperActive\n delete this.doc.documentElement.dataset.dshWallpaperActive\n setSceneBackdropActive(this.doc, 'wallpaper', false)\n if (this.rootNeutralizer !== null) {\n this.rootNeutralizer.remove()\n this.rootNeutralizer = null\n }\n if (this.videoElement !== null) {\n this.videoElement.pause()\n this.videoElement = null\n }\n if (this.mediaLayer !== null) {\n this.mediaLayer.remove()\n this.mediaLayer = null\n }\n if (this.scrimLayer !== null) {\n this.scrimLayer.remove()\n this.scrimLayer = null\n }\n }\n\n private publish(): void {\n for (const listener of this.listeners) listener()\n }\n}\n\n/** Resolve a persisted selection id against an inventory list: exact id first, then the imported copy. */\nexport function resolveSelection(wallpapers: WallpaperDescriptor[], selection: string): WallpaperDescriptor | undefined {\n return wallpapers.find(w => w.id === selection)\n ?? wallpapers.find(w => w.id === 'imported/' + selection)\n}\n\n/**\n * Restore the persisted wallpaper selection at boot: resolve it against the\n * host inventory and mount it, without waiting for the skin-center panel to\n * open — the panel's mount effect is the only other sync() caller, so a page\n * load with a persisted selection otherwise renders nothing until the card\n * is opened. Best-effort and idempotent: the first non-empty selection wins;\n * the panel re-resolves on open if the inventory is still in flight or fails.\n */\nexport function installBootRestore(wallpaper: WallpaperHandle): void {\n let synced = false\n const restore = (): void => {\n if (synced) return\n const selected = wallpaper.selection()\n if (selected === '') return\n synced = true\n void (async () => {\n try {\n const response = await fetch('/api/skin-center/we/inventory')\n if (!response.ok) return\n const payload = await response.json().catch(() => null) as { ok?: boolean; wallpapers?: WallpaperDescriptor[] } | null\n if (payload?.ok !== true || !Array.isArray(payload.wallpapers)) return\n const match = resolveSelection(payload.wallpapers, selected)\n if (match !== undefined) wallpaper.sync(match)\n } catch {\n // Best-effort: the panel re-resolves on open.\n }\n })()\n }\n restore()\n wallpaper.subscribe(restore)\n}\n","/**\n * A drag-smooth range slider that decouples the visible value from the\n * external store while the user drags (issue #725).\n *\n * Binding <input type=\"range\"> directly to a useSyncExternalStore value\n * causes two defects during drag:\n * 1. Snapping back: the store subscription re-reads the scope snapshot while\n * the async scope.set() write is still in flight, resetting the thumb\n * to the old value mid-drag.\n * 2. Lag and stale labels: every onChange drives a full set -> publish ->\n * React render cycle, and the displayed number only updates once the\n * external store settles instead of following the thumb.\n *\n * This control keeps the input effectively uncontrolled: the browser moves\n * the thumb on the compositor thread with zero React involvement while\n * dragging, onInput reports the live value (one callback per animation\n * frame) so labels update in real time, and the final value is committed to\n * the external store through the native change event, which fires once per\n * completed pointer interaction (pointer release). Keyboard-only users get\n * an explicit commit path through onBlur and the Enter/Escape keydown\n * handlers, because not every engine fires the native change event for\n * range inputs on blur or Enter (jsdom does not; behavior varies by\n * browser). A pointer cancel aborts without committing, and the external\n * value is re-synced into the DOM only while the user is neither dragging\n * nor keyboard-focusing the input.\n * @module @linxin666/dsh-client-ui-skin-center/slider-control\n */\nimport { useCallback, useEffect, useRef, type ReactNode } from 'react'\n\n/** Props for the drag-smooth slider control. */\nexport interface SliderControlProps {\n /** External value from the store (initial value + sync target). */\n value: number\n min?: number\n max?: number\n step?: number\n /** Committed on drag end / keyboard change; callers persist to the store here. */\n onChange: (value: number) => void\n /** Live value during interaction, throttled to one callback per frame. */\n onChanging?: (value: number) => void\n className?: string\n id?: string\n ariaLabel?: string\n ariaValuetext?: string\n}\n\n/**\n * A range slider that stays smooth during drag (issue #725).\n *\n * @param props - slider props.\n * @returns the range input element.\n */\nexport function SliderControl({\n value: externalValue,\n min = 0,\n max = 100,\n step = 1,\n onChange,\n onChanging,\n className,\n id,\n ariaLabel,\n ariaValuetext,\n}: SliderControlProps): ReactNode {\n const inputRef = useRef<HTMLInputElement | null>(null)\n const draggingRef = useRef(false)\n const rafRef = useRef<number | null>(null)\n const liveRef = useRef(0)\n const lastCommittedRef = useRef<number | null>(null)\n const onChangingRef = useRef(onChanging)\n onChangingRef.current = onChanging\n\n // Commit through the NATIVE change event (React's onChange is synthesized\n // from 'input' for range inputs, which would commit on every move). The\n // native change event fires exactly once per completed pointer interaction.\n const commitRef = useRef(onChange)\n commitRef.current = onChange\n\n /**\n * Persist a value to the external store, de-duplicated against the last\n * committed value so the explicit keyboard/onBlur commit paths never\n * double-fire alongside the native change event (which real browsers also\n * emit on blur or Enter for range inputs).\n */\n const commit = useCallback((value: number): void => {\n if (lastCommittedRef.current === value) return\n lastCommittedRef.current = value\n commitRef.current(value)\n }, [])\n\n const commitCurrent = useCallback((): void => {\n const input = inputRef.current\n if (input === null) return\n draggingRef.current = false\n if (rafRef.current !== null) {\n cancelAnimationFrame(rafRef.current)\n rafRef.current = null\n }\n commit(Number(input.value))\n }, [commit])\n\n // Sync the external value into the DOM input, unless the user is dragging\n // or keyboard-focusing the input (the native change event already carries\n // the committed keyboard value; overwriting here would snap the thumb).\n useEffect(() => {\n const input = inputRef.current\n if (input !== null && !draggingRef.current && input !== input.ownerDocument.activeElement) {\n input.value = String(externalValue)\n }\n }, [externalValue])\n\n useEffect(() => {\n const input = inputRef.current\n if (input === null) return\n const listener = (): void => {\n draggingRef.current = false\n if (rafRef.current !== null) {\n cancelAnimationFrame(rafRef.current)\n rafRef.current = null\n }\n commit(Number(input.value))\n }\n input.addEventListener('change', listener)\n return (): void => {\n input.removeEventListener('change', listener)\n }\n }, [commit])\n\n // Release the pending frame on unmount.\n useEffect(() => {\n return (): void => {\n if (rafRef.current !== null) cancelAnimationFrame(rafRef.current)\n }\n }, [])\n\n /** Throttled live-value reporter: fires onChanging at most once per frame. */\n const reportLive = useCallback((value: number): void => {\n liveRef.current = value\n if (rafRef.current !== null) return\n rafRef.current = requestAnimationFrame(() => {\n rafRef.current = null\n onChangingRef.current?.(liveRef.current)\n })\n }, [])\n\n const startDrag = useCallback(() => {\n draggingRef.current = true\n }, [])\n\n /** Abort the interaction (pointer cancel): no value is committed. */\n const cancelDrag = useCallback(() => {\n draggingRef.current = false\n if (rafRef.current !== null) {\n cancelAnimationFrame(rafRef.current)\n rafRef.current = null\n }\n }, [])\n\n const onInput = useCallback((event: React.FormEvent<HTMLInputElement>) => {\n reportLive(Number(event.currentTarget.value))\n }, [reportLive])\n\n // Commit on blur so keyboard-only users persist the value even when the\n // engine never fires the native change event for range inputs on blur.\n const commitOnBlur = useCallback((): void => {\n if (draggingRef.current) return\n commitCurrent()\n }, [commitCurrent])\n\n // Enter/Escape are the explicit keyboard commit keys for range inputs.\n const onKeyDown = useCallback((event: React.KeyboardEvent<HTMLInputElement>): void => {\n if (event.key !== 'Enter' && event.key !== 'Escape') return\n if (draggingRef.current) return\n commitCurrent()\n }, [commitCurrent])\n\n return (\n <input\n ref={inputRef}\n id={id}\n className={className}\n type=\"range\"\n min={min}\n max={max}\n step={step}\n defaultValue={externalValue}\n aria-label={ariaLabel}\n aria-valuetext={ariaValuetext}\n onPointerDown={startDrag}\n onPointerCancel={cancelDrag}\n onInput={onInput}\n onBlur={commitOnBlur}\n onKeyDown={onKeyDown}\n />\n )\n}","/**\n * The wallpaper panel of the skin-center card: lists the user's local\n * Wallpaper Engine library (video / web / scene wallpapers) with live\n * try-on, one-click apply, local import, and render tuning. Rendering and\n * persistence ride the WallpaperController (wallpaper.ts); the library,\n * media, import and scene-frame bytes come from the host's /we routes.\n *\n * Compliance: wallpapers are the user's own local files (their Workshop\n * subscriptions or manual folders). The panel never downloads or shares\n * content; import only copies files within the user's machine.\n */\nimport { useCallback, useEffect, useRef, useState, useSyncExternalStore, type ReactNode } from 'react'\nimport type { PropsLocale } from '@deepseek-ai/dsh-client-ui-slots'\nimport { resolveSelection, type WallpaperDescriptor, type WallpaperHandle } from './wallpaper.ts'\nimport css from './skin-center.module.css'\nimport { SliderControl } from './SliderControl.tsx'\n\n/** Live-label helper: the shown value follows the in-drag thumb immediately,\n * and falls back to the store value once the store settles (issue #725). */\nfunction useLiveValue(value: number): [number, (v: number | null) => void] {\n const [live, setLive] = useState<number | null>(null)\n useEffect(() => {\n setLive(null)\n }, [value])\n return [live ?? value, setLive]\n}\n\n/** Host base path of the wallpaper API (mirrors src/we-routes.ts). */\nconst WE_API = '/api/skin-center/we'\n\n/** One wallpaper entry as served by the inventory route. */\ninterface WallpaperItem extends WallpaperDescriptor {\n source: 'workshop' | 'local' | 'imported' | 'system'\n playable: boolean\n updateAvailable: boolean\n rating?: 'g' | 'pg13' | 'r18'\n}\n\n/** Inventory payload shape. */\ninterface InventoryPayload {\n ok?: boolean\n installDir?: string | null\n total?: number\n portableCount?: number\n /** macOS-managed wallpapers (aerials + Desktop Pictures) in the list. */\n systemCount?: number\n wallpapers?: WallpaperItem[]\n error?: string\n}\n\n/** Post one wallpaper action and return whether it succeeded. */\nasync function postWe(path: string, id: string): Promise<string | null> {\n try {\n const response = await fetch(WE_API + path, {\n method: 'POST',\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify({ id }),\n })\n const payload = await response.json().catch(() => null) as { ok?: boolean; error?: string } | null\n if (!response.ok || payload?.ok !== true) return payload?.error ?? 'HTTP ' + String(response.status)\n return null\n } catch (error) {\n return error instanceof Error ? error.message : String(error)\n }\n}\n\n/** The type badge copy key of one wallpaper. */\nfunction typeKey(item: WallpaperItem): 'wallpaperTypeVideo' | 'wallpaperTypeWeb' | 'wallpaperTypeScene' | 'wallpaperTypeApp' | 'wallpaperTypeImage' {\n switch (item.type) {\n case 'video': return 'wallpaperTypeVideo'\n case 'web': return 'wallpaperTypeWeb'\n case 'scene': return 'wallpaperTypeScene'\n case 'image': return 'wallpaperTypeImage'\n default: return 'wallpaperTypeApp'\n }\n}\n\n/** Wallpaper grid page size (24 items per page). */\nconst PAGE_SIZE = 24\n\n/** Generate pagination page numbers with ellipses. */\nfunction paginationRange(current: number, total: number): (number | 'ellipsis')[] {\n if (total <= 7) {\n return Array.from({ length: total }, (_, i) => i + 1)\n }\n const pages: (number | 'ellipsis')[] = [1]\n let start = Math.max(2, current - 1)\n let end = Math.min(total - 1, current + 1)\n\n if (current <= 3) {\n start = 2\n end = 4\n } else if (current >= total - 2) {\n start = total - 3\n end = total - 1\n }\n\n if (start > 2) pages.push('ellipsis')\n for (let i = start; i <= end; i++) pages.push(i)\n if (end < total - 1) pages.push('ellipsis')\n pages.push(total)\n return pages\n}\n\n/** Render the Wallpaper Engine section of the skin-center card. */\nexport function WallpaperPanel({ t, wallpaper }: { t: PropsLocale<'skinCenter'>['t']; wallpaper: WallpaperHandle }): ReactNode {\n const enabled = useSyncExternalStore(wallpaper.subscribe, wallpaper.enabled)\n const selection = useSyncExternalStore(wallpaper.subscribe, wallpaper.selection)\n const mode = useSyncExternalStore(wallpaper.subscribe, wallpaper.mode)\n const fit = useSyncExternalStore(wallpaper.subscribe, wallpaper.fit)\n const dim = useSyncExternalStore(wallpaper.subscribe, wallpaper.dim)\n const blur = useSyncExternalStore(wallpaper.subscribe, wallpaper.wallpaperBlur)\n const opacity = useSyncExternalStore(wallpaper.subscribe, wallpaper.wallpaperOpacity)\n const pauseOnHidden = useSyncExternalStore(wallpaper.subscribe, wallpaper.pauseOnHidden)\n const sound = useSyncExternalStore(wallpaper.subscribe, wallpaper.sound)\n const volume = useSyncExternalStore(wallpaper.subscribe, wallpaper.volume)\n const activeId = useSyncExternalStore(wallpaper.subscribe, wallpaper.activeId)\n const trying = useSyncExternalStore(wallpaper.subscribe, wallpaper.trying)\n const dirs = useSyncExternalStore(wallpaper.subscribe, wallpaper.dirs)\n const [shownDim, setShownDim] = useLiveValue(dim)\n const [shownBlur, setShownBlur] = useLiveValue(blur)\n const [shownOpacity, setShownOpacity] = useLiveValue(opacity)\n const [shownVolume, setShownVolume] = useLiveValue(volume)\n const [dirInput, setDirInput] = useState('')\n const [picking, setPicking] = useState(false)\n const [page, setPage] = useState(1)\n const [ratingFilter, setRatingFilter] = useState<'g' | 'pg13' | 'r18'>('g')\n const [jumpInput, setJumpInput] = useState('')\n\n const [items, setItems] = useState<WallpaperItem[] | null>(null)\n const [installDir, setInstallDir] = useState<string | null>(null)\n const [systemCount, setSystemCount] = useState(0)\n const [loadError, setLoadError] = useState<string | null>(null)\n const [actionError, setActionError] = useState<string | null>(null)\n const [workingId, setWorkingId] = useState<string | null>(null)\n const mounted = useRef(false)\n useEffect(() => {\n mounted.current = true\n return () => { mounted.current = false }\n }, [])\n\n /** Fetch the inventory and reconcile the mounted layer with the selection. */\n const load = useCallback((): void => {\n void fetch(WE_API + '/inventory')\n .then(async response => {\n const payload = await response.json().catch(() => null) as InventoryPayload | null\n if (!mounted.current) return\n if (!response.ok || payload?.ok !== true || !Array.isArray(payload.wallpapers)) {\n setLoadError(payload?.error ?? 'HTTP ' + String(response.status))\n setItems([])\n return\n }\n setLoadError(null)\n setItems(payload.wallpapers)\n // A fresh inventory restarts the paged grid from the first page.\n setPage(1)\n setInstallDir(typeof payload.installDir === 'string' ? payload.installDir : null)\n setSystemCount(typeof payload.systemCount === 'number' ? payload.systemCount : 0)\n const selected = wallpaper.selection()\n wallpaper.sync(resolveSelection(payload.wallpapers, selected) ?? null)\n })\n .catch((error: unknown) => {\n if (!mounted.current) return\n setLoadError(error instanceof Error ? error.message : String(error))\n setItems([])\n })\n }, [wallpaper])\n\n useEffect(load, [load])\n\n /** Run one import/remove action with the shared busy + error state. */\n const runAction = (id: string, path: string, after?: () => void): void => {\n setActionError(null)\n setWorkingId(id)\n void postWe(path, id).then(error => {\n if (!mounted.current) return\n setWorkingId(null)\n if (error !== null) {\n setActionError(error)\n return\n }\n after?.()\n load()\n })\n }\n\n /** Open the host's native folder picker and add the chosen directory. */\n const browseDir = (): void => {\n const pick = wallpaper.pickDir\n if (pick === undefined) return\n setActionError(null)\n setPicking(true)\n void pick()\n .then(path => {\n if (!mounted.current) return\n setPicking(false)\n if (path === null || path.trim() === '') return // cancelled\n wallpaper.addDir(path)\n load()\n })\n .catch((error: unknown) => {\n // Non-loopback (paired remote) or a host without the native\n // capability: the manual input stays the fallback.\n if (!mounted.current) return\n setPicking(false)\n setActionError(t('wallpaperDirBrowseFailed') + ': ' + (error instanceof Error ? error.message : String(error)))\n })\n }\n\n const descriptorOf = (item: WallpaperItem): WallpaperDescriptor => ({\n id: item.id,\n title: item.title,\n type: item.type,\n videoUrl: item.videoUrl,\n webUrl: item.webUrl,\n frameUrl: item.frameUrl,\n sceneUrl: item.sceneUrl,\n previewUrl: item.previewUrl,\n })\n\n /** Whether one entry can be mounted at all in the current mode. */\n const renderable = (item: WallpaperItem): boolean =>\n item.playable || item.frameUrl !== null || item.previewUrl !== null\n\n const filteredItems = (items ?? []).filter(item => (item.rating ?? 'g') === ratingFilter)\n const totalPages = Math.max(1, Math.ceil(filteredItems.length / PAGE_SIZE))\n const currentPage = Math.min(Math.max(1, page), totalPages)\n const pagedItems = filteredItems.slice((currentPage - 1) * PAGE_SIZE, currentPage * PAGE_SIZE)\n\n const handleJump = (): void => {\n const target = parseInt(jumpInput.trim(), 10)\n if (!isNaN(target) && target >= 1 && target <= totalPages) {\n setPage(target)\n setJumpInput('')\n }\n }\n\n const onSelectRatingFilter = (filter: 'g' | 'pg13' | 'r18'): void => {\n setRatingFilter(filter)\n setPage(1)\n setJumpInput('')\n }\n\n const activeSelection = selection\n\n return (\n <div className={css.wallpaperSection}>\n <div className={css.enableRow}>\n <span className={css.enableLabel} title={t('wallpaperEnable')}>{t('wallpaperTitle')}</span>\n <button\n type=\"button\"\n role=\"switch\"\n aria-checked={enabled}\n aria-label={t('wallpaperEnable')}\n className={enabled ? css.switch + ' ' + css.switchOn : css.switch}\n onClick={() => { wallpaper.setEnabled(!enabled) }}\n >\n <span className={css.switchThumb} />\n </button>\n <p className={css.enableHint}>{t('wallpaperHint')}</p>\n </div>\n {enabled && (\n <>\n <div className={css.wallpaperStatus}>\n {loadError !== null\n ? <span className={css.wallpaperStatusError}>{t('wallpaperLoadError')}: {loadError}</span>\n : items === null\n ? <span>{t('loading')}</span>\n : installDir !== null\n ? <span>{t('wallpaperLibraryFound')} · {items.length}</span>\n : systemCount > 0\n ? <span>{t('wallpaperLibrarySystem')} · {items.length}</span>\n : <span>{t('wallpaperLibraryManual')} · {items.length}</span>}\n <button type=\"button\" className={css.button} onClick={load}>{t('wallpaperRefresh')}</button>\n </div>\n\n {activeSelection !== '' && (\n <div className={css.wallpaperControls}>\n <div className={css.themeRow}>\n <span className={css.themeLabel}>{t('wallpaperMode')}</span>\n <button\n type=\"button\"\n className={css.themeButton + (mode === 'live' ? ' ' + css.themeButtonActive : '')}\n onClick={() => { wallpaper.setMode('live') }}\n >\n {t('wallpaperModeLive')}\n </button>\n <button\n type=\"button\"\n className={css.themeButton + (mode === 'frame' ? ' ' + css.themeButtonActive : '')}\n onClick={() => { wallpaper.setMode('frame') }}\n >\n {t('wallpaperModeFrame')}\n </button>\n <button\n type=\"button\"\n className={css.button + ' ' + css.buttonGhost}\n onClick={() => { wallpaper.clearSelection() }}\n >\n {t('wallpaperClear')}\n </button>\n </div>\n <div className={css.themeRow}>\n <span className={css.themeLabel}>{t('wallpaperFit')}</span>\n <button\n type=\"button\"\n className={css.themeButton + (fit === 'cover' ? ' ' + css.themeButtonActive : '')}\n onClick={() => { wallpaper.setFit('cover') }}\n >\n {t('wallpaperFitCover')}\n </button>\n <button\n type=\"button\"\n className={css.themeButton + (fit === 'contain' ? ' ' + css.themeButtonActive : '')}\n onClick={() => { wallpaper.setFit('contain') }}\n >\n {t('wallpaperFitContain')}\n </button>\n <button\n type=\"button\"\n className={css.themeButton + (fit === 'fill' ? ' ' + css.themeButtonActive : '')}\n onClick={() => { wallpaper.setFit('fill') }}\n >\n {t('wallpaperFitFill')}\n </button>\n </div>\n <div className={css.backgroundRow}>\n <div className={css.backgroundHead}>\n <span className={css.backgroundLabel}>{t('wallpaperDim')}</span>\n <span className={css.backgroundValue} aria-hidden=\"true\">{shownDim}%</span>\n </div>\n <SliderControl\n className={css.backgroundRange}\n min={0}\n max={90}\n step={5}\n value={dim}\n ariaValuetext={shownDim + '%'}\n ariaLabel={t('wallpaperDim')}\n onChanging={setShownDim}\n onChange={(value) => { wallpaper.setDim(value) }}\n />\n <div className={css.backgroundHead}>\n <span className={css.backgroundLabel}>{t('wallpaperOpacity')}</span>\n <span className={css.backgroundValue} aria-hidden=\"true\">{shownOpacity}%</span>\n </div>\n <SliderControl\n className={css.backgroundRange}\n min={0}\n max={100}\n step={5}\n value={opacity}\n ariaValuetext={shownOpacity + '%'}\n ariaLabel={t('wallpaperOpacity')}\n onChanging={setShownOpacity}\n onChange={(value) => { wallpaper.setOpacity(value) }}\n />\n <div className={css.backgroundHead}>\n <span className={css.backgroundLabel}>{t('wallpaperBlur')}</span>\n <span className={css.backgroundValue} aria-hidden=\"true\">{shownBlur}px</span>\n </div>\n <SliderControl\n className={css.backgroundRange}\n min={0}\n max={60}\n step={1}\n value={blur}\n ariaValuetext={shownBlur + 'px'}\n ariaLabel={t('wallpaperBlur')}\n onChanging={setShownBlur}\n onChange={(value) => { wallpaper.setBlur(value) }}\n />\n </div>\n <div className={css.enableRow}>\n <span className={css.enableLabel}>{t('wallpaperPauseHidden')}</span>\n <button\n type=\"button\"\n role=\"switch\"\n aria-checked={pauseOnHidden}\n aria-label={t('wallpaperPauseHidden')}\n className={pauseOnHidden ? css.switch + ' ' + css.switchOn : css.switch}\n onClick={() => { wallpaper.setPauseOnHidden(!pauseOnHidden) }}\n >\n <span className={css.switchThumb} />\n </button>\n </div>\n <div className={css.enableRow}>\n <span className={css.enableLabel} title={t('wallpaperSoundHint')}>{t('wallpaperSound')}</span>\n <button\n type=\"button\"\n role=\"switch\"\n aria-checked={sound}\n aria-label={t('wallpaperSound')}\n className={sound ? css.switch + ' ' + css.switchOn : css.switch}\n onClick={() => { wallpaper.setSound(!sound) }}\n >\n <span className={css.switchThumb} />\n </button>\n </div>\n {sound && (\n <div className={css.backgroundRow}>\n <div className={css.backgroundHead}>\n <span className={css.backgroundLabel}>{t('wallpaperVolume')}</span>\n <span className={css.backgroundValue} aria-hidden=\"true\">{shownVolume}%</span>\n </div>\n <SliderControl\n className={css.backgroundRange}\n min={0}\n max={100}\n step={5}\n value={volume}\n ariaValuetext={shownVolume + '%'}\n ariaLabel={t('wallpaperVolume')}\n onChanging={setShownVolume}\n onChange={(value) => { wallpaper.setVolume(value) }}\n />\n </div>\n )}\n </div>\n )}\n\n <div className={css.wallpaperDirs}>\n <span className={css.themeLabel}>{t('wallpaperDirs')}</span>\n {dirs.length === 0 && <span className={css.backgroundHintMuted}>{t('wallpaperDirsEmpty')}</span>}\n {dirs.map(dir => (\n <span className={css.wallpaperDir} key={dir}>\n <span className={css.wallpaperDirPath} title={dir}>{dir}</span>\n <button\n type=\"button\"\n className={css.wallpaperDirRemove}\n aria-label={t('wallpaperRemove')}\n onClick={() => { wallpaper.removeDir(dir); load() }}\n >\n ×\n </button>\n </span>\n ))}\n <span className={css.wallpaperDirAdd}>\n <input\n className={css.wallpaperDirInput}\n type=\"text\"\n value={dirInput}\n placeholder={t('wallpaperDirPlaceholder')}\n onChange={(event) => { setDirInput(event.target.value) }}\n onKeyDown={(event) => {\n if (event.key === 'Enter' && dirInput.trim() !== '') {\n wallpaper.addDir(dirInput)\n setDirInput('')\n load()\n }\n }}\n />\n <button\n type=\"button\"\n className={css.button}\n disabled={dirInput.trim() === ''}\n onClick={() => { wallpaper.addDir(dirInput); setDirInput(''); load() }}\n >\n {t('wallpaperDirAdd')}\n </button>\n {wallpaper.pickDir !== undefined && (\n <button\n type=\"button\"\n className={css.button}\n disabled={picking}\n title={t('wallpaperDirBrowseHint')}\n onClick={browseDir}\n >\n {picking ? t('loading') : t('wallpaperDirBrowse')}\n </button>\n )}\n </span>\n <p className={css.backgroundHintMuted}>{t('wallpaperDirsHint')}</p>\n </div>\n\n {actionError !== null && <div className={css.error}>{actionError}</div>}\n\n {items !== null && items.length > 0 && (\n <div className={css.wallpaperToolbar}>\n <div className={css.ratingFilterGroup} role=\"tablist\" aria-label={t('wallpaperTitle')}>\n {(['g', 'pg13', 'r18'] as const).map(filter => {\n const active = ratingFilter === filter\n const key = filter === 'g'\n ? 'wallpaperRatingG'\n : filter === 'pg13'\n ? 'wallpaperRatingPg13'\n : 'wallpaperRatingR18'\n return (\n <button\n type=\"button\"\n key={filter}\n role=\"tab\"\n aria-selected={active}\n className={css.ratingFilterButton + (active ? ' ' + css.ratingFilterActive : '')}\n onClick={() => { onSelectRatingFilter(filter) }}\n >\n {t(key)}\n </button>\n )\n })}\n </div>\n <div className={css.pageTotalInfo}>\n {t('wallpaperPageTotal', { page: String(currentPage), total: String(totalPages) })}\n </div>\n </div>\n )}\n\n {items !== null && pagedItems.length > 0 && (\n <div className={css.wallpaperGrid}>\n {pagedItems.map(item => {\n const isApplied = item.id === activeSelection\n const isMounted = item.id === activeId\n const busy = workingId === item.id\n return (\n <div className={css.wallpaperCard} key={item.id}>\n <div className={css.wallpaperThumbWrap}>\n {item.previewUrl !== null\n ? <img className={css.wallpaperThumb} src={item.previewUrl} alt=\"\" loading=\"lazy\" />\n : item.videoUrl !== null\n // No preview image (bare .mp4 without project.json):\n // the video element's first frame is the cover.\n ? <video className={css.wallpaperThumb} src={item.videoUrl} preload=\"metadata\" muted playsInline aria-hidden=\"true\" />\n : <div className={css.wallpaperThumbEmpty} aria-hidden=\"true\" />}\n <span className={css.wallpaperType}>{t(typeKey(item))}</span>\n {item.rating === 'r18' ? (\n <span className={css.wallpaperRating + ' ' + css.ratingR18}>R18</span>\n ) : item.rating === 'pg13' ? (\n <span className={css.wallpaperRating + ' ' + css.ratingPg13}>PG-13</span>\n ) : (\n <span className={css.wallpaperRating + ' ' + css.ratingG}>G</span>\n )}\n {isMounted && (\n <span className={css.badge + ' ' + (trying ? css.badgeTrying : css.badgeActive)}>\n {trying ? t('tryingOn') : t('active')}\n </span>\n )}\n </div>\n <div className={css.wallpaperName} title={item.title}>{item.title}</div>\n <div className={css.wallpaperActions}>\n {isMounted && trying ? (\n <button type=\"button\" className={css.button + ' ' + css.buttonPrimary} onClick={() => { wallpaper.exitTryOn() }}>\n {t('exitTryOn')}\n </button>\n ) : (\n <button\n type=\"button\"\n className={css.button + ' ' + css.buttonPrimary}\n disabled={!renderable(item) || (isMounted && isApplied) || busy}\n onClick={() => { wallpaper.tryOn(descriptorOf(item)) }}\n >\n {t('tryOn')}\n </button>\n )}\n <button\n type=\"button\"\n className={css.button}\n disabled={!renderable(item) || isApplied || busy}\n onClick={() => { wallpaper.applySelection(descriptorOf(item)) }}\n >\n {isApplied ? t('active') : t('apply')}\n </button>\n {item.source === 'imported' ? (\n <>\n {item.updateAvailable && (\n <button\n type=\"button\"\n className={css.button}\n disabled={busy}\n title={t('wallpaperUpdateAvailable')}\n onClick={() => { runAction(item.id, '/reimport') }}\n >\n {busy ? t('loading') : t('wallpaperReimport')}\n </button>\n )}\n <button\n type=\"button\"\n className={css.button + ' ' + css.buttonGhost}\n disabled={busy}\n onClick={() => {\n runAction(item.id, '/remove', () => {\n if (wallpaper.selection() === item.id) wallpaper.clearSelection()\n })\n }}\n >\n {t('wallpaperRemove')}\n </button>\n </>\n ) : item.source === 'system' ? (\n // macOS-managed wallpapers are already local and\n // their folder is shared — nothing to import.\n <></>\n ) : (\n <button\n type=\"button\"\n className={css.button}\n disabled={busy}\n title={t('wallpaperImportHint')}\n onClick={() => { runAction(item.id, '/import') }}\n >\n {busy ? t('loading') : t('wallpaperImport')}\n </button>\n )}\n </div>\n </div>\n )\n })}\n </div>\n )}\n {totalPages > 1 && (\n <div className={css.wallpaperPagination} role=\"navigation\" aria-label={t('wallpaperTitle')}>\n <button\n type=\"button\"\n className={css.pageButton}\n disabled={currentPage <= 1}\n onClick={() => { setPage(p => Math.max(1, p - 1)) }}\n aria-label={t('wallpaperPagePrev')}\n >\n {t('wallpaperPagePrev')}\n </button>\n {paginationRange(currentPage, totalPages).map((p, idx) => {\n if (p === 'ellipsis') {\n return <span key={'ellipsis-' + String(idx)} className={css.pageEllipsis}>…</span>\n }\n const isActive = p === currentPage\n return (\n <button\n type=\"button\"\n key={p}\n className={css.pageButton + (isActive ? ' ' + css.pageButtonActive : '')}\n aria-current={isActive ? 'page' : undefined}\n onClick={() => { setPage(p) }}\n >\n {p}\n </button>\n )\n })}\n <button\n type=\"button\"\n className={css.pageButton}\n disabled={currentPage >= totalPages}\n onClick={() => { setPage(p => Math.min(totalPages, p + 1)) }}\n aria-label={t('wallpaperPageNext')}\n >\n {t('wallpaperPageNext')}\n </button>\n <form\n className={css.pageJumpForm}\n onSubmit={(e) => {\n e.preventDefault()\n handleJump()\n }}\n >\n <input\n type=\"text\"\n className={css.pageJumpInput}\n value={jumpInput}\n aria-label={t('wallpaperPageJump')}\n onChange={(e) => { setJumpInput(e.target.value) }}\n />\n <button type=\"submit\" className={css.pageButton} disabled={jumpInput.trim() === ''}>\n {t('wallpaperPageJump')}\n </button>\n </form>\n </div>\n )}\n {items !== null && (items.length === 0 || pagedItems.length === 0) && loadError === null && (\n <p className={css.backgroundHintMuted}>{t('wallpaperEmpty')}</p>\n )}\n </>\n )}\n </div>\n )\n}","/**\n * The skin-center card: rendered as the content of a first-level settings\n * section, listing the official stock look plus every installed skin in the\n * v2 catalog (package-shipped built-ins + user dirs under $DSH_HOME/skins).\n *\n * v2 architecture (issue #506): skins are pure asset directories loaded by\n * the skin-center runtime. Try-on and apply both go through the same atomic\n * switch engine (src/client/runtime/skin-controller.ts) — try-on simply\n * skips persistence, and apply is one click with NO page reload, no\n * cordis.patch.yml rewrite, no boot-graph regeneration. The \"trying on\"\n * badge tracks the controller's live state, so closing and reopening the\n * settings panel keeps showing the skin that is still being previewed.\n * Copy rides the standard `t` seat; the theme preview control drives the\n * official theme service (persisted, same as the Appearance row).\n */\nimport { useEffect, useRef, useState, useSyncExternalStore, type ReactNode } from 'react'\nimport type { PropsLocale, PropsRuntime } from '@deepseek-ai/dsh-client-ui-slots'\nimport type { ThemeSnapshot } from '@deepseek-ai/dsh-client-ui-theme/client'\nimport type { CatalogSkin, SkinRuntimeStore } from './runtime/boot.ts'\nimport type { SkinBackgroundHandle } from './background.ts'\nimport type { WallpaperHandle } from './wallpaper.ts'\nimport type { PreviewCoordinator } from './preview-coordinator.ts'\nimport type { CustomThemeController } from './custom-theme-controller.ts'\nimport { CustomThemeCard } from './CustomThemePanel.tsx'\nimport { WallpaperPanel } from './WallpaperPanel.tsx'\nimport { SliderControl } from './SliderControl.tsx'\nimport css from './skin-center.module.css'\n\n/** Business face the skin-center apply() injects into the card. */\nexport interface SkinCenterInjected {\n /** The v2 skin runtime store (controller + catalog). */\n runtime: SkinRuntimeStore\n theme: {\n getTheme(): ThemeSnapshot\n subscribe(listener: () => void): () => void\n setTheme(id: 'light' | 'dark'): void\n }\n /** Background occluder over the shared skin-background namespace. */\n background: SkinBackgroundHandle\n /** Wallpaper Engine bridge over the skin-wallpaper namespace. */\n wallpaper: WallpaperHandle\n /** One serialized preview session shared by skins and wallpapers. */\n preview: PreviewCoordinator\n /** User palette derived from the official stock theme. */\n customTheme: CustomThemeController\n}\n\n/** Plugin-card component props: locale seat + injected face. */\nexport type SkinCenterComponentProps =\n PropsLocale<'skinCenter'> & SkinCenterInjected\n\n/** The apply target of the official stock-look card. */\nconst OFFICIAL = 'official'\n\n/**\n * Live-label helper: the shown value follows the in-drag thumb immediately,\n * and falls back to the store value once the store settles (issue #725).\n */\nfunction useLiveValue(value: number): [number, (v: number | null) => void] {\n const [live, setLive] = useState<number | null>(null)\n useEffect(() => {\n setLive(null)\n }, [value])\n return [live ?? value, setLive]\n}\n\n/**\n * Render the skin-center card: a static header naming the plugin, with the\n * always-visible skin list (official default + every installed skin; try-on /\n * theme preview / one-click apply) rendered below it.\n * @param props - card props.\n * @returns the plugin card.\n */\nexport function SkinCenter({ t, runtime, theme, background, wallpaper, preview, customTheme }: SkinCenterComponentProps) {\n const snapshot = useSyncExternalStore((listener) => theme.subscribe(listener), () => theme.getTheme())\n const enabled = useSyncExternalStore(background.subscribe, background.enabled)\n const opacity = useSyncExternalStore(background.subscribe, background.opacity)\n const blurEmpty = useSyncExternalStore(background.subscribe, background.blurEmpty)\n const blurContent = useSyncExternalStore(background.subscribe, background.blurContent)\n const inputCardBlur = useSyncExternalStore(background.subscribe, background.inputCardBlur)\n const bubbleOpacity = useSyncExternalStore(background.subscribe, background.bubbleOpacity)\n const [shownOpacity, setShownOpacity] = useLiveValue(opacity)\n const [shownBlurEmpty, setShownBlurEmpty] = useLiveValue(blurEmpty)\n const [shownBlurContent, setShownBlurContent] = useLiveValue(blurContent)\n const [shownInputCardBlur, setShownInputCardBlur] = useLiveValue(inputCardBlur)\n const [shownBubbleOpacity, setShownBubbleOpacity] = useLiveValue(bubbleOpacity)\n const catalog = useSyncExternalStore(runtime.subscribe, runtime.catalog)\n const state = useSyncExternalStore(runtime.subscribe, runtime.controller.getState)\n const customThemeState = useSyncExternalStore(customTheme.subscribe, customTheme.getState)\n const activeId = state.active\n const previewing = state.previewing\n const tryingId = state.trying\n const activeEntry = activeId === null ? null : runtime.find(activeId)\n const backdropActive = activeEntry?.manifest.contributes.backgroundMedia !== undefined\n const [busyId, setBusyId] = useState<string | null>(null)\n const [error, setError] = useState<string | null>(null)\n const [verifying, setVerifying] = useState(false)\n const [verifySummary, setVerifySummary] = useState<{\n total: number\n valid: number\n issues: number\n repaired?: string[]\n repairFailed?: Array<{ id: string; error: string }>\n } | null>(null)\n const [verifyReports, setVerifyReports] = useState<Record<string, { status: string; hooksTrusted: boolean; mismatches: string[]; missing: string[] }>>({})\n const [confirmUninstallId, setConfirmUninstallId] = useState<string | null>(null)\n const [uninstallingId, setUninstallingId] = useState<string | null>(null)\n // Unmount guard: once the card is gone, pending async completions must not\n // setState (the controller itself owns the skin state and lives on).\n const mounted = useRef(false)\n // Latest-click-wins token; a newer click invalidates older completions.\n const requestSeq = useRef(0)\n useEffect(() => {\n mounted.current = true\n return () => { mounted.current = false }\n }, [])\n\n const run = (target: string, action: () => Promise<string | null>): void => {\n const seq = ++requestSeq.current\n setError(null)\n setBusyId(target)\n void action()\n .catch(() => {\n if (!mounted.current || seq !== requestSeq.current) return\n setError(t('applyFailed'))\n })\n .finally(() => {\n if (!mounted.current || seq !== requestSeq.current) return\n setBusyId(null)\n })\n }\n\n const tryOn = (entry: CatalogSkin): void => {\n run(entry.manifest.id, () => preview.runSkin(() => runtime.controller.tryOn(entry.manifest.id, entry)))\n }\n\n const tryOnOfficial = (): void => {\n run(OFFICIAL, () => preview.runSkin(() => runtime.controller.tryOn(null, null)))\n }\n\n const exitTryOn = (): void => {\n run(tryingId ?? OFFICIAL, () => preview.runSkin(() => runtime.controller.exitTryOn()))\n }\n\n const restoreCommittedSkin = async (state: { active: string | null }): Promise<void> => {\n const entry = state.active === null ? null : runtime.find(state.active)\n if (state.active !== null && entry === null) {\n throw new Error(`cannot restore skin ${state.active}`)\n }\n const restored = await runtime.controller.switchTo(state.active, entry)\n if (restored !== state.active) {\n throw new Error(`skin ${state.active ?? 'stock'} did not restore`)\n }\n }\n\n const switchAndDeactivateCustomTheme = async (\n target: string | null,\n entry: CatalogSkin | null,\n ): Promise<string | null> => {\n const previous = { ...runtime.controller.getState() }\n const active = await runtime.controller.switchTo(target, entry)\n if (active !== target) {\n throw new Error(`${target === null ? 'stock theme' : `skin ${target}`} did not activate`)\n }\n try {\n await customTheme.deactivate()\n return active\n } catch (error) {\n try {\n await restoreCommittedSkin(previous)\n } catch (rollbackError) {\n throw new AggregateError([error, rollbackError], 'skin switch cleanup and rollback failed')\n }\n throw error\n }\n }\n\n const restoreOfficialLook = async (): Promise<string | null> => {\n const active = await switchAndDeactivateCustomTheme(null, null)\n if (wallpaper.selection() !== '') wallpaper.clearSelection()\n return active\n }\n\n /**\n * One-click apply: atomic client-side switch + persisted selection. No\n * reload, no boot-graph wait — the tapIndex adapter makes the next page\n * load boot straight into this skin.\n * @param target - skin id, or `official` for the stock look.\n */\n const applySkin = (target: string): void => {\n if (target === OFFICIAL) {\n run(OFFICIAL, () => preview.runSkin(restoreOfficialLook))\n return\n }\n const entry = runtime.find(target)\n if (entry === null) {\n setError(t('applyFailed'))\n return\n }\n run(target, () => preview.runSkin(async () => {\n const active = await switchAndDeactivateCustomTheme(target, entry)\n if (wallpaper.selection() !== '') wallpaper.clearSelection()\n return active\n }))\n }\n\n const tryOnCustomTheme = (): void => {\n run('custom-theme', () => preview.runCustomTheme(async () => {\n const active = await runtime.controller.tryOn(null, null)\n if (active !== null) throw new Error('stock preview did not activate')\n customTheme.tryOn()\n return active\n }))\n }\n\n const exitCustomThemeTryOn = (): void => {\n run('custom-theme', () => preview.runCustomTheme(async () => {\n customTheme.exitTryOn()\n return await runtime.controller.exitTryOn()\n }))\n }\n\n const applyCustomTheme = (): void => {\n run('custom-theme', () => preview.runCustomTheme(async () => {\n await customTheme.apply()\n const active = await runtime.controller.switchTo(null, null)\n if (active !== null) {\n await customTheme.deactivate()\n throw new Error('stock theme did not activate')\n }\n return active\n }))\n }\n\n const handleVerify = async (): Promise<void> => {\n setVerifying(true)\n setError(null)\n try {\n const res = await fetch('/api/skin-center/v2/verify', {\n method: 'POST',\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify({ autoRepair: true }),\n })\n const json = (await res.json().catch(() => null)) as {\n ok?: boolean\n total?: number\n valid?: number\n issues?: number\n repaired?: string[]\n repairFailed?: Array<{ id: string; error: string }>\n details?: Array<{ id: string; status: string; hooksTrusted: boolean; mismatches: string[]; missing: string[] }>\n } | null\n if (!res.ok || json?.ok !== true) {\n throw new Error('verify failed')\n }\n if (!mounted.current) return\n setVerifySummary({\n total: json.total ?? 0,\n valid: json.valid ?? 0,\n issues: json.issues ?? 0,\n repaired: json.repaired ?? [],\n repairFailed: json.repairFailed ?? [],\n })\n const map: Record<string, { status: string; hooksTrusted: boolean; mismatches: string[]; missing: string[] }> = {}\n for (const item of json.details ?? []) {\n map[item.id] = item\n }\n setVerifyReports(map)\n if (json.repaired && json.repaired.length > 0) {\n await runtime.refreshCatalog()\n if (activeId && json.repaired.includes(activeId)) {\n const freshEntry = runtime.find(activeId)\n if (freshEntry) {\n await preview.runSkin(() => switchAndDeactivateCustomTheme(activeId, freshEntry))\n }\n }\n }\n } catch {\n if (mounted.current) setError(t('applyFailed'))\n } finally {\n if (mounted.current) setVerifying(false)\n }\n }\n\n const handleUninstall = async (entry: CatalogSkin): Promise<void> => {\n const id = entry.manifest.id\n setUninstallingId(id)\n setError(null)\n try {\n if (tryingId === id) {\n await preview.runSkin(() => runtime.controller.exitTryOn())\n }\n if (activeId === id) {\n await preview.runSkin(restoreOfficialLook)\n }\n const res = await fetch(`/api/skin-center/v2/skins/${encodeURIComponent(id)}/uninstall`, {\n method: 'POST',\n headers: { 'content-type': 'application/json' },\n })\n const json = (await res.json().catch(() => null)) as { ok?: boolean } | null\n if (!res.ok || json?.ok !== true) {\n throw new Error('uninstall failed')\n }\n await runtime.refreshCatalog()\n if (mounted.current) setConfirmUninstallId(null)\n } catch {\n if (mounted.current) setError(t('uninstallFailed'))\n } finally {\n if (mounted.current) setUninstallingId(null)\n }\n }\n\n const dark = document.body.hasAttribute('data-ds-dark-theme')\n\n /** One row: try-on control + apply button + optional uninstall. Shared by the official card and every skin card. */\n const actionButtons = (opts: {\n key: string\n entry?: CatalogSkin\n isActive: boolean\n isTrying: boolean\n onTryOn: () => void\n applyLabel: string\n }): ReactNode => {\n const isUser = opts.entry?.origin === 'user'\n const isConfirming = isUser && confirmUninstallId === opts.key\n return (\n <div className={css.actions}>\n {opts.isActive && !opts.isTrying ? (\n <button type=\"button\" className={`${css.button} ${css.buttonGhost}`} disabled>\n {t('tryOn')}\n </button>\n ) : opts.isTrying ? (\n <button type=\"button\" className={`${css.button} ${css.buttonPrimary}`} disabled={busyId !== null || uninstallingId !== null} onClick={exitTryOn}>\n {t('exitTryOn')}\n </button>\n ) : (\n <button\n type=\"button\"\n className={`${css.button} ${css.buttonPrimary}`}\n disabled={busyId !== null || uninstallingId !== null}\n onClick={opts.onTryOn}\n >\n {busyId === opts.key ? t('loading') : t('tryOn')}\n </button>\n )}\n <button\n type=\"button\"\n className={css.button}\n disabled={busyId !== null || uninstallingId !== null}\n onClick={() => { applySkin(opts.key) }}\n >\n {busyId === opts.key ? t('applying') : opts.applyLabel}\n </button>\n {isUser && (\n isConfirming ? (\n <>\n <button\n type=\"button\"\n className={`${css.button} ${css.buttonDangerConfirm}`}\n disabled={busyId !== null || uninstallingId !== null}\n onClick={() => { if (opts.entry) void handleUninstall(opts.entry) }}\n >\n {uninstallingId === opts.key ? t('uninstalling') : t('confirm')}\n </button>\n <button\n type=\"button\"\n className={css.button}\n disabled={uninstallingId !== null}\n onClick={() => { setConfirmUninstallId(null) }}\n >\n {t('cancel')}\n </button>\n </>\n ) : (\n <button\n type=\"button\"\n className={`${css.button} ${css.buttonDanger}`}\n disabled={busyId !== null || uninstallingId !== null}\n onClick={() => { setConfirmUninstallId(opts.key) }}\n >\n {t('uninstall')}\n </button>\n )\n )}\n </div>\n )\n }\n\n return (\n <li className={css.pluginCard}>\n <div className={css.cardHeaderStatic}>\n <span className={css.headText}>\n <span className={css.pluginName}>\n {t('title')}\n <span className={css.titleBadge}>{String(catalog?.length ?? 0)}</span>\n </span>\n <span className={css.cardDescription} title={t('cardDescription')}>{t('cardDescription')}</span>\n </span>\n </div>\n\n <div className={css.cardBody}>\n <div className={css.enableRow}>\n <span className={css.enableLabel} title={t('enabled')}>{t('enabled')}</span>\n <button\n type=\"button\"\n role=\"switch\"\n aria-checked={enabled}\n aria-label={t('enabled')}\n className={enabled ? css.switch + ' ' + css.switchOn : css.switch}\n onClick={() => { background.setEnabled(!enabled) }}\n >\n <span className={css.switchThumb} />\n </button>\n <p className={css.enableHint}>{t('enabledHint')}</p>\n </div>\n {enabled\n ? (\n <>\n <div className={css.head}>\n <div className={css.intro} title={t('intro')}>{t('intro')}</div>\n <div className={css.toolbar}>\n <div className={css.themeRow}>\n <span className={css.themeLabel}>{t('theme')}</span>\n <button\n type=\"button\"\n className={`${css.themeButton} ${dark ? '' : css.themeButtonActive}`}\n onClick={() => { theme.setTheme('light') }}\n >\n {t('themeLight')}\n </button>\n <button\n type=\"button\"\n className={`${css.themeButton} ${dark ? css.themeButtonActive : ''}`}\n onClick={() => { theme.setTheme('dark') }}\n >\n {t('themeDark')}\n </button>\n </div>\n <button\n type=\"button\"\n className={css.themeButton}\n disabled={verifying || busyId !== null || uninstallingId !== null}\n onClick={() => { void handleVerify() }}\n >\n {verifying ? t('verifyingIntegrity') : t('verifyIntegrity')}\n </button>\n </div>\n {verifySummary !== null && (\n <div className={`${css.verifySummary} ${verifySummary.issues === 0 ? css.verifySummarySuccess : css.verifySummaryWarning}`}>\n {verifySummary.repaired && verifySummary.repaired.length > 0 && verifySummary.issues === 0\n ? t('verifyRepaired', { count: verifySummary.repaired.length })\n : verifySummary.issues === 0\n ? t('verifyAllPassed', { count: verifySummary.total })\n : verifySummary.repaired && verifySummary.repaired.length > 0\n ? `${t('verifyRepaired', { count: verifySummary.repaired.length })}, ${t('verifyFoundIssues', { count: verifySummary.issues })}`\n : t('verifyFoundIssues', { count: verifySummary.issues })}\n </div>\n )}\n </div>\n\n <div className={css.backgroundRow}>\n <div className={css.backgroundHead}>\n <span className={css.backgroundLabel}>{t('backgroundOpacity')}</span>\n <span className={css.backgroundValue} aria-hidden=\"true\">{shownOpacity}%</span>\n </div>\n <SliderControl\n id=\"skin-center-background-opacity\"\n className={css.backgroundRange}\n min={0}\n max={100}\n step={5}\n value={opacity}\n ariaValuetext={shownOpacity + '%'}\n ariaLabel={t('backgroundOpacity')}\n onChanging={setShownOpacity}\n onChange={(value) => { background.set(value) }}\n />\n <p className={backdropActive ? css.backgroundHint : css.backgroundHintMuted}>\n {backdropActive ? t('backgroundHint') : t('backgroundHintInert')}\n </p>\n </div>\n <div className={css.backgroundRow}>\n <div className={css.backgroundHead}>\n <span className={css.backgroundLabel}>{t('backgroundBlurEmpty')}</span>\n <span className={css.backgroundValue} aria-hidden=\"true\">{shownBlurEmpty}px</span>\n </div>\n <SliderControl\n id=\"skin-center-background-blur-empty\"\n className={css.backgroundRange}\n min={0}\n max={20}\n step={1}\n value={blurEmpty}\n ariaValuetext={shownBlurEmpty + 'px'}\n ariaLabel={t('backgroundBlurEmpty')}\n onChanging={setShownBlurEmpty}\n onChange={(value) => { background.setBlurEmpty(value) }}\n />\n <div className={css.backgroundHead}>\n <span className={css.backgroundLabel}>{t('backgroundBlurContent')}</span>\n <span className={css.backgroundValue} aria-hidden=\"true\">{shownBlurContent}px</span>\n </div>\n <SliderControl\n id=\"skin-center-background-blur-content\"\n className={css.backgroundRange}\n min={0}\n max={20}\n step={1}\n value={blurContent}\n ariaValuetext={shownBlurContent + 'px'}\n ariaLabel={t('backgroundBlurContent')}\n onChanging={setShownBlurContent}\n onChange={(value) => { background.setBlurContent(value) }}\n />\n <p className={backdropActive ? css.backgroundHint : css.backgroundHintMuted}>\n {backdropActive ? t('backgroundBlurHint') : t('backgroundBlurInert')}\n </p>\n </div>\n\n\n <div className={css.backgroundRow}>\n <div className={css.backgroundHead}>\n <span className={css.backgroundLabel}>{t('inputCardBlur')}</span>\n <span className={css.backgroundValue} aria-hidden=\"true\">{shownInputCardBlur}px</span>\n </div>\n <SliderControl\n id=\"skin-center-input-card-blur\"\n className={css.backgroundRange}\n min={0}\n max={20}\n step={1}\n value={inputCardBlur}\n ariaValuetext={shownInputCardBlur + 'px'}\n ariaLabel={t('inputCardBlur')}\n onChanging={setShownInputCardBlur}\n onChange={(value) => { background.setInputCardBlur(value) }}\n />\n <p className={css.backgroundHint}>{t('inputCardBlurHint')}</p>\n </div>\n\n <div className={css.backgroundRow}>\n <div className={css.backgroundHead}>\n <span className={css.backgroundLabel}>{t('bubbleOpacity')}</span>\n <span className={css.backgroundValue} aria-hidden=\"true\">{shownBubbleOpacity}%</span>\n </div>\n <SliderControl\n id=\"skin-center-bubble-opacity\"\n className={css.backgroundRange}\n min={0}\n max={100}\n step={5}\n value={bubbleOpacity}\n ariaValuetext={shownBubbleOpacity + '%'}\n ariaLabel={t('bubbleOpacity')}\n onChanging={setShownBubbleOpacity}\n onChange={(value) => { background.setBubbleOpacity(value) }}\n />\n <p className={css.backgroundHint}>{t('bubbleOpacityHint')}</p>\n </div>\n\n <WallpaperPanel t={t} wallpaper={wallpaper} />\n\n {error !== null && <div className={css.error}>{error}</div>}\n\n <div className={css.list}>\n {(() => {\n const isActive = activeId === null && !previewing && !customThemeState.applied\n const isTrying = previewing && tryingId === null && !customThemeState.previewing\n const badge = isActive ? t('active') : isTrying ? t('tryingOn') : null\n return (\n <div className={css.card} key={OFFICIAL}>\n <div className={css.cardHead}>\n <span className={css.swatch} style={{ background: '#98a1ab' }} aria-hidden=\"true\" />\n <span className={css.cardName} title={t('official')}>{t('official')}</span>\n {badge !== null && (\n <span className={`${css.badge} ${isActive ? css.badgeActive : css.badgeTrying}`}>\n {badge}\n </span>\n )}\n </div>\n <div className={css.cardTagline} title={t('officialTagline')}>{t('officialTagline')}</div>\n {actionButtons({\n key: OFFICIAL,\n isActive,\n isTrying,\n onTryOn: tryOnOfficial,\n applyLabel: t('restore'),\n })}\n </div>\n )\n })()}\n\n {(catalog ?? []).map(entry => {\n const id = entry.manifest.id\n const isActive = id === activeId && !previewing\n const isTrying = previewing && id === tryingId\n const badge = isActive ? t('active') : isTrying ? t('tryingOn') : null\n const report = verifyReports[id]\n return (\n <div className={css.card} key={id}>\n <div className={css.cardHead}>\n <span\n className={css.swatch}\n style={{ background: entry.manifest.accent ?? '#98a1ab' }}\n aria-hidden=\"true\"\n />\n <span className={css.cardName} title={entry.manifest.nameEn}>{entry.manifest.nameEn}</span>\n {report && (\n <span\n className={`${css.badge} ${\n report.status === 'valid'\n ? css.badgeSuccess\n : report.status === 'tampered'\n ? css.badgeWarning\n : css.badgeDanger\n }`}\n title={\n report.status === 'valid'\n ? t('integrityValid')\n : [...report.mismatches, ...report.missing].join(', ') || report.status\n }\n >\n {report.status === 'valid'\n ? t('integrityValid')\n : report.status === 'tampered'\n ? t('integrityTampered')\n : report.status === 'missing-files'\n ? t('integrityMissing')\n : t('integrityHooksRefused')}\n </span>\n )}\n {badge !== null && (\n <span className={`${css.badge} ${isActive ? css.badgeActive : css.badgeTrying}`}>\n {badge}\n </span>\n )}\n </div>\n <div className={css.cardTagline} title={entry.manifest.tagline ?? ''}>\n {entry.manifest.tagline ?? ''}\n </div>\n {report && report.status !== 'valid' && (\n <div className={css.integrityNote}>\n {[\n report.mismatches.length > 0 ? `${t('integrityTampered')}: ${report.mismatches.join(', ')}` : null,\n report.missing.length > 0 ? `${t('integrityMissing')}: ${report.missing.join(', ')}` : null,\n ].filter(Boolean).join(' | ')}\n </div>\n )}\n {actionButtons({\n key: id,\n entry,\n isActive,\n isTrying,\n onTryOn: () => { tryOn(entry) },\n applyLabel: t('apply'),\n })}\n </div>\n )\n })}\n\n <CustomThemeCard\n t={t}\n customTheme={customTheme}\n scheme={dark ? 'dark' : 'light'}\n setScheme={scheme => { theme.setTheme(scheme) }}\n isActive={customThemeState.applied && activeId === null && !previewing}\n isTrying={customThemeState.previewing}\n busy={busyId === 'custom-theme'}\n disabled={busyId !== null}\n onTryOn={tryOnCustomTheme}\n onExitTryOn={exitCustomThemeTryOn}\n onApply={applyCustomTheme}\n />\n </div>\n </>\n )\n : (\n <p className={css.offNote} role=\"status\">{t('offNote')}</p>\n )}\n </div>\n </li>\n )\n}\n\n/** Props the settings section binds for the skin-center card page. */\nexport type SkinCenterSectionProps =\n PropsRuntime<'settings.section'>\n & PropsLocale<'skinCenter'>\n & SkinCenterInjected\n\n/** Render the skin-center card as a first-level settings page. */\nexport function SkinCenterSection(props: SkinCenterSectionProps): ReactNode {\n const { t, runtime, theme, background, wallpaper, preview, customTheme } = props\n return (\n <ul className={css.sectionList}>\n <SkinCenter\n t={t}\n runtime={runtime}\n theme={theme}\n background={background}\n wallpaper={wallpaper}\n preview={preview}\n customTheme={customTheme}\n />\n </ul>\n )\n}\n","/**\n * Shared skin-background preference contract (issue #996): the six values the\n * skin-center card edits — master switch, backdrop occlusion, per-state\n * backdrop blur, composer-card blur, and bubble opacity.\n *\n * These used to live only in the `skin-background` settings namespace, which\n * the remote pairing channel fences as loopback-only, so a paired remote\n * desktop always read defaults and silently dropped writes. They now persist\n * in the skin center's own v2 state (POST /api/skin-center/v2/active), which\n * rides the same allow-listed channel as skin switching. This module is the\n * dependency-free source of truth both halves (host routes / migration and\n * the browser controller) share.\n * @module @linxin666/dsh-client-ui-skin-center/core/background\n */\n\n/** Skin-background preference set persisted in the v2 active state file. */\nexport interface SkinBackgroundConfig {\n /** Master switch for the skin center. */\n enabled?: boolean\n /** Background occlusion 0-100 (0 = no extra veil, 100 = fully obscured). */\n backgroundOpacity?: number\n /** Empty-conversation backdrop blur, 0-20 px (0 disables). */\n backgroundBlurEmpty?: number\n /** With-content backdrop blur, 0-20 px (0 disables). */\n backgroundBlurContent?: number\n /** Composer-card backdrop blur, 0-20 px. */\n inputCardBlur?: number\n /** Message bubble opacity 0-100, for skins exposing bubble alpha. */\n bubbleOpacity?: number\n}\n\n/** Effective value of every field when the state carries none. */\nexport const SKIN_BACKGROUND_DEFAULTS: Readonly<Required<SkinBackgroundConfig>> = {\n enabled: true,\n backgroundOpacity: 0,\n backgroundBlurEmpty: 0,\n backgroundBlurContent: 0,\n inputCardBlur: 10,\n bubbleOpacity: 50,\n}\n\n/** The fields normalize/sanitize know about; unknown keys are dropped. */\nexport const SKIN_BACKGROUND_FIELDS = Object.keys(SKIN_BACKGROUND_DEFAULTS) as Array<keyof SkinBackgroundConfig>\n\nfunction clampInt(value: number, min: number, max: number): number {\n return Math.max(min, Math.min(max, Math.round(value)))\n}\n\nconst RANGES: Record<Exclude<keyof SkinBackgroundConfig, 'enabled'>, [number, number]> = {\n backgroundOpacity: [0, 100],\n backgroundBlurEmpty: [0, 20],\n backgroundBlurContent: [0, 20],\n inputCardBlur: [0, 20],\n bubbleOpacity: [0, 100],\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value)\n}\n\n/**\n * Lenient normalization for stored/legacy data: unknown keys and wrongly\n * typed fields are dropped, numeric fields are clamped into range. Never\n * fails; a non-object input yields an empty config.\n */\nexport function normalizeSkinBackground(value: unknown): SkinBackgroundConfig {\n if (!isRecord(value)) return {}\n const out: SkinBackgroundConfig = {}\n if (typeof value.enabled === 'boolean') out.enabled = value.enabled\n for (const field of Object.keys(RANGES) as Array<keyof typeof RANGES>) {\n const raw = value[field]\n if (typeof raw !== 'number' || !Number.isFinite(raw)) continue\n const [min, max] = RANGES[field]\n out[field] = clampInt(raw, min, max)\n }\n return out\n}\n\n/**\n * Strict validation for the POST /active write surface: a background value\n * must be an object whose known fields are correctly typed (numbers are then\n * clamped). Returns null for anything else so the route can answer 400.\n */\nexport function sanitizeSkinBackground(value: unknown): SkinBackgroundConfig | null {\n if (!isRecord(value)) return null\n if (value.enabled !== undefined && typeof value.enabled !== 'boolean') return null\n for (const field of Object.keys(RANGES) as Array<keyof typeof RANGES>) {\n const raw = value[field]\n if (raw !== undefined && (typeof raw !== 'number' || !Number.isFinite(raw))) return null\n }\n return normalizeSkinBackground(value)\n}\n\n/** Fill every absent field from {@link SKIN_BACKGROUND_DEFAULTS}. */\nexport function resolveSkinBackground(value: SkinBackgroundConfig | null | undefined): Required<SkinBackgroundConfig> {\n return { ...SKIN_BACKGROUND_DEFAULTS, ...(value ?? {}) }\n}\n\n/** True when at least one field departs from its default (customized data). */\nexport function hasCustomSkinBackground(value: SkinBackgroundConfig): boolean {\n return SKIN_BACKGROUND_FIELDS.some((field) => value[field] !== undefined && value[field] !== SKIN_BACKGROUND_DEFAULTS[field])\n}\n","/**\n * Background-scrim handle for the skin center: applies the chosen occlusion\n * to the page's backdrop, plus an optional per-state Gaussian blur of that\n * backdrop.\n *\n * Occlusion is a CSS variable on `document.body` (--dsw-skin-scrim), which\n * backdrop-painting skins (blue-fantasy / whale-song) read inside their\n * setBackdrop() so the veil stays in sync across theme flips and try-on\n * restores. The official stock look paints no backdrop, so the variable is\n * inert there — the value still persists so it is ready for the next backdrop\n * skin.\n *\n * The Gaussian blur targets the same painted backdrop through a fixed child\n * of `document.body` using backdrop-filter: it samples the body's own\n * background painted behind it. Separate strengths apply to the empty\n * conversation and the conversation-with-content states, detected from the\n * shell's stable message-row class suffixes (hash prefix varies, suffix is\n * stable). When the active blur is 0 no element exists, so there is no GPU\n * cost. Blur never changes the occlusion behavior above.\n *\n * Occlusion values are 0-100 (0 = no extra veil, 100 = fully obscured); they\n * are written through as a 0..1 alpha for the CSS variable. Blur values are\n * 0-20 px. Dragging the controls applies instantly (live).\n *\n * Persistence (issue #996): the controller owns no settings scope — the\n * remote pairing channel fences settings.* as loopback-only, which is what\n * stranded remote clients on defaults. The caller hands in the initial\n * values and a `persist` callback (the v2 /active channel); later external\n * edits (the official settings page locally, the refetched state remotely)\n * arrive through `init()`.\n */\nimport {\n resolveSkinBackground,\n SKIN_BACKGROUND_DEFAULTS,\n type SkinBackgroundConfig,\n} from '../core/background.ts'\n\n/** The namespace string the Host registers (mirrors src/index.ts). */\nexport const SKIN_BACKGROUND_NS = 'skin-background'\n\n/** Field of the background value inside the namespace section. */\nexport const OPACITY_FIELD = 'backgroundOpacity'\n\n/** Field of the empty-conversation backdrop blur inside the namespace section. */\nexport const BLUR_EMPTY_FIELD = 'backgroundBlurEmpty'\n\n/** Field of the with-content backdrop blur inside the namespace section. */\nexport const BLUR_CONTENT_FIELD = 'backgroundBlurContent'\n\n/** Field of the composer card backdrop blur inside the namespace section. */\nexport const INPUT_CARD_BLUR_FIELD = 'inputCardBlur'\n\n/** CSS custom property written to document.body and read by backdrop skins. */\nexport const SCRIM_VAR = '--dsw-skin-scrim'\n\n/** Field of the message bubble opacity inside the namespace section. */\nexport const BUBBLE_OPACITY_FIELD = 'bubbleOpacity'\n\n/** CSS custom property consumed by skins that expose translucent bubbles. */\nexport const BUBBLE_ALPHA_VAR = '--dsh-skin-bubble-alpha'\n\n/** CSS custom property consumed by the shared composer neutralizer. */\nexport const INPUT_CARD_BLUR_VAR = '--dsh-input-card-blur'\n\n/** Default occlusion (0 = no extra veil) when the section carries none. */\nexport const DEFAULT_OPACITY = SKIN_BACKGROUND_DEFAULTS.backgroundOpacity\n\n/** Default message bubble opacity percentage. */\nexport const DEFAULT_BUBBLE_OPACITY = SKIN_BACKGROUND_DEFAULTS.bubbleOpacity\n\n/** Default blur (0 = disabled) when the section carries none. */\nexport const DEFAULT_BLUR = SKIN_BACKGROUND_DEFAULTS.backgroundBlurEmpty\n\n/** The face the skin-center card injects for the background control. */\nexport interface SkinBackgroundHandle {\n /** Current master switch (true when the plugin is on). */\n enabled(): boolean\n /** Toggle + persist the master switch. */\n setEnabled(value: boolean): void\n /** Current occlusion 0-100 (also the getSnapshot seat for useSyncExternalStore). */\n opacity(): number\n /** Current empty-conversation backdrop blur 0-20 px. */\n blurEmpty(): number\n /** Current with-content backdrop blur 0-20 px. */\n blurContent(): number\n /** Current input-card backdrop blur 0-20 px. */\n inputCardBlur(): number\n /** Current message bubble opacity 0-100. */\n bubbleOpacity(): number\n /** Observe a change in the applied values. */\n subscribe(listener: () => void): () => void\n /** Apply + persist a new occlusion. */\n set(opacity: number): void\n /** Apply + persist a new empty-conversation backdrop blur (0-20 px). */\n setBlurEmpty(value: number): void\n /** Apply + persist a new with-content backdrop blur (0-20 px). */\n setBlurContent(value: number): void\n /** Apply + persist a new input-card backdrop blur (0-20 px). */\n setInputCardBlur(value: number): void\n /** Apply + persist a new message bubble opacity (0-100). */\n setBubbleOpacity(value: number): void\n /** Tear down the blur element and MutationObserver. */\n dispose(): void\n}\n\n/**\n * Selector for a conversation message row inside the shell's center column.\n * Official shell message rows carry `data-chat-anchor-key`; the\n * `data-pane=\"conversation\"` attribute is stamped by the dsh-web-all compat\n * shim on the center column, where the _userRow / _compactionRow /\n * _contextRow / _turnErrorRow suffixes are CSS-module message-row classes\n * (hash prefix varies, suffix is stable).\n */\nconst CONVERSATION_CONTENT_SELECTOR = [\n '[data-chat-anchor-key]',\n '[data-pane=\"conversation\"] [class*=\"_userRow\"]',\n '[data-pane=\"conversation\"] [class*=\"_compactionRow\"]',\n '[data-pane=\"conversation\"] [class*=\"_contextRow\"]',\n '[data-pane=\"conversation\"] [class*=\"_turnErrorRow\"]',\n].join(', ')\n\n/**\n * Own the background preference set: apply the values to the body instantly\n * and persist user edits through the caller-provided channel.\n */\nexport class BackgroundController implements SkinBackgroundHandle {\n private enabledValue = SKIN_BACKGROUND_DEFAULTS.enabled\n private opacityValue = SKIN_BACKGROUND_DEFAULTS.backgroundOpacity\n private blurEmptyValue = SKIN_BACKGROUND_DEFAULTS.backgroundBlurEmpty\n private blurContentValue = SKIN_BACKGROUND_DEFAULTS.backgroundBlurContent\n private inputCardBlurValue = SKIN_BACKGROUND_DEFAULTS.inputCardBlur\n private bubbleOpacityValue = SKIN_BACKGROUND_DEFAULTS.bubbleOpacity\n private readonly listeners = new Set<() => void>()\n private readonly persist: (next: SkinBackgroundConfig) => void\n /** The fixed backdrop-filter element, present only while active blur > 0. */\n private blurElement: HTMLDivElement | null = null\n /** The body MutationObserver, installed lazily once a blur is active. */\n private observer: MutationObserver | null = null\n /** Pending requestAnimationFrame id for a coalesced recheck. */\n private rafId: number | null = null\n /** Guard: after dispose no scheduled work may reinstall anything. */\n private disposed = false\n\n /**\n * @param initial - values known at construction (the local settings scope\n * snapshot on loopback); null starts from defaults until init() arrives.\n * @param persist - persistence channel for user edits (v2 /active POST).\n */\n constructor(initial: SkinBackgroundConfig | null, persist: (next: SkinBackgroundConfig) => void) {\n this.persist = persist\n if (initial !== null) this.assign(initial)\n this.applyOcclusion()\n this.applyInputCardBlur()\n this.applyBubbleOpacity()\n this.syncBlur()\n }\n\n /**\n * Replace the current values with externally sourced ones (the refetched\n * v2 state, or a live settings-scope publish). Never persists — the source\n * already owns the stored copy; the caller decides whether to forward the\n * change into the v2 store.\n */\n init(next: SkinBackgroundConfig | null): void {\n if (this.disposed) return\n this.assign(next ?? {})\n this.applyOcclusion()\n this.applyInputCardBlur()\n this.applyBubbleOpacity()\n this.syncBlur()\n this.publish()\n }\n\n /** The current values as a persistable config (every field concrete). */\n snapshot(): SkinBackgroundConfig {\n return {\n enabled: this.enabledValue,\n backgroundOpacity: this.opacityValue,\n backgroundBlurEmpty: this.blurEmptyValue,\n backgroundBlurContent: this.blurContentValue,\n inputCardBlur: this.inputCardBlurValue,\n bubbleOpacity: this.bubbleOpacityValue,\n }\n }\n\n enabled = (): boolean => this.enabledValue\n\n setEnabled(value: boolean): void {\n this.enabledValue = value\n this.applyOcclusion()\n this.applyInputCardBlur()\n this.applyBubbleOpacity()\n this.syncBlur()\n this.publish()\n this.persist(this.snapshot())\n }\n\n opacity = (): number => this.opacityValue\n\n blurEmpty = (): number => this.blurEmptyValue\n\n blurContent = (): number => this.blurContentValue\n\n inputCardBlur = (): number => this.inputCardBlurValue\n\n bubbleOpacity = (): number => this.bubbleOpacityValue\n\n subscribe = (listener: () => void): (() => void) => {\n this.listeners.add(listener)\n return () => { this.listeners.delete(listener) }\n }\n\n set(opacity: number): void {\n this.opacityValue = this.clampPercent(opacity)\n this.applyOcclusion()\n this.publish()\n this.persist(this.snapshot())\n }\n\n setBlurEmpty(value: number): void {\n this.blurEmptyValue = this.clampBlur(value)\n this.ensureObserver()\n this.syncBlur()\n this.publish()\n this.persist(this.snapshot())\n }\n\n setBlurContent(value: number): void {\n this.blurContentValue = this.clampBlur(value)\n this.ensureObserver()\n this.syncBlur()\n this.publish()\n this.persist(this.snapshot())\n }\n\n setInputCardBlur(value: number): void {\n this.inputCardBlurValue = this.clampBlur(value)\n this.applyInputCardBlur()\n this.publish()\n this.persist(this.snapshot())\n }\n\n setBubbleOpacity(value: number): void {\n this.bubbleOpacityValue = this.clampPercent(value)\n this.applyBubbleOpacity()\n this.publish()\n this.persist(this.snapshot())\n }\n\n dispose(): void {\n this.disposed = true\n if (this.rafId !== null) {\n cancelAnimationFrame(this.rafId)\n this.rafId = null\n }\n this.removeBlurElement()\n document.body.style.removeProperty(INPUT_CARD_BLUR_VAR)\n document.body.style.removeProperty(BUBBLE_ALPHA_VAR)\n if (this.observer !== null) {\n this.observer.disconnect()\n this.observer = null\n }\n }\n\n /** Copy one config into the live fields, defaults filling the gaps. */\n private assign(config: SkinBackgroundConfig): void {\n const resolved = resolveSkinBackground(config)\n this.enabledValue = resolved.enabled\n this.opacityValue = resolved.backgroundOpacity\n this.blurEmptyValue = resolved.backgroundBlurEmpty\n this.blurContentValue = resolved.backgroundBlurContent\n this.inputCardBlurValue = resolved.inputCardBlur\n this.bubbleOpacityValue = resolved.bubbleOpacity\n }\n\n private clampBlur(value: number): number {\n return Math.max(0, Math.min(20, Math.round(value)))\n }\n\n private clampPercent(value: number): number {\n return Math.max(0, Math.min(100, Math.round(value)))\n }\n\n private applyInputCardBlur(): void {\n if (!this.enabledValue) {\n document.body.style.removeProperty(INPUT_CARD_BLUR_VAR)\n return\n }\n document.body.style.setProperty(INPUT_CARD_BLUR_VAR, this.inputCardBlurValue + 'px')\n }\n\n private applyBubbleOpacity(): void {\n if (!this.enabledValue) {\n document.body.style.removeProperty(BUBBLE_ALPHA_VAR)\n return\n }\n document.body.style.setProperty(BUBBLE_ALPHA_VAR, String(this.bubbleOpacityValue / 100))\n }\n\n /** Write the current occlusion onto the body CSS variable (0..1 alpha). */\n private applyOcclusion(): void {\n if (!this.enabledValue) {\n document.body.style.removeProperty(SCRIM_VAR)\n return\n }\n document.body.style.setProperty(SCRIM_VAR, String(this.opacityValue / 100))\n }\n\n /**\n * Apply the active blur: empty or with-content strength depending on the\n * conversation state. A value > 0 ensures the fixed blur element exists\n * with the matching backdrop-filter; 0 removes it.\n */\n private syncBlur(): void {\n if (this.disposed) return\n if (this.hasWallpaper()) {\n // The wallpaper module owns its own blur (wallpaperBlur); the skin-center\n // background blur layer must stay off while a wallpaper is mounted so\n // the two settings remain independent (#777 decouple).\n this.removeBlurElement()\n return\n }\n if (!this.enabledValue) {\n this.removeBlurElement()\n return\n }\n this.ensureObserver()\n const active = this.hasConversationContent() ? this.blurContentValue : this.blurEmptyValue\n if (active > 0) this.ensureBlurElement(active)\n else this.removeBlurElement()\n }\n\n /** True when the conversation pane hosts at least one message row. */\n private hasConversationContent(): boolean {\n return document.querySelector(CONVERSATION_CONTENT_SELECTOR) !== null\n }\n\n /** True while a Wallpaper Engine wallpaper is mounted. */\n private hasWallpaper(): boolean {\n return document.documentElement.hasAttribute('data-dsh-wallpaper-active')\n }\n\n /** Create (if needed) and size the fixed backdrop-filter element. */\n private ensureBlurElement(active: number): void {\n if (this.blurElement === null) {\n const element = document.createElement('div')\n element.style.position = 'fixed'\n element.style.inset = '0'\n element.style.zIndex = '-1'\n element.style.pointerEvents = 'none'\n element.setAttribute('aria-hidden', 'true')\n this.blurElement = element\n document.body.appendChild(element)\n }\n const blur = 'blur(' + active + 'px)'\n this.blurElement.style.backdropFilter = blur\n // Safari: the vendor-prefixed form is only reachable via setProperty.\n this.blurElement.style.setProperty('-webkit-backdrop-filter', blur)\n }\n\n /** Remove the fixed blur element, if present. */\n private removeBlurElement(): void {\n if (this.blurElement === null) return\n this.blurElement.remove()\n this.blurElement = null\n }\n\n /**\n * Install the MutationObserver on document.body only when either blur\n * field is active, so a fully-disabled blur never pays the observation\n * cost. Runs lazily on the first non-zero set.\n */\n private ensureObserver(): void {\n if (this.disposed || this.observer !== null) return\n if (this.blurEmptyValue <= 0 && this.blurContentValue <= 0) return\n this.observer = new MutationObserver(() => this.scheduleRecheck())\n this.observer.observe(document.body, {\n childList: true,\n subtree: true,\n attributes: true,\n attributeFilter: ['class'],\n })\n // Also react to the wallpaper marker so the background blur layer is\n // removed/restored exactly when a wallpaper mounts/unmounts.\n this.observer.observe(document.documentElement, {\n attributes: true,\n attributeFilter: ['data-dsh-wallpaper-active'],\n })\n }\n\n /** Coalesce burst mutations into one rAF-delayed recheck. */\n private scheduleRecheck(): void {\n if (this.disposed || this.rafId !== null) return\n this.rafId = requestAnimationFrame(() => {\n this.rafId = null\n if (this.disposed) return\n this.syncBlur()\n })\n }\n\n private publish(): void {\n for (const listener of this.listeners) listener()\n }\n}\n","/**\n * Safe reconciliation helpers for the legacy skin-background settings scope.\n *\n * The scope's resolved value contains schema defaults, while its raw user layer\n * contains only fields explicitly stored by the user. The v2 active-state\n * document is authoritative, so a scope update may merge only those raw fields\n * into the live background values.\n */\nimport {\n normalizeSkinBackground,\n SKIN_BACKGROUND_FIELDS,\n type SkinBackgroundConfig,\n} from './background.ts'\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value)\n}\n\n/** Return the known, explicitly stored skin-background fields from a user layer. */\nexport function extractSkinBackgroundUserLayer(value: unknown): SkinBackgroundConfig | null {\n if (!isRecord(value)) return null\n const normalized = normalizeSkinBackground(value)\n const knownFields = Object.keys(normalized) as Array<keyof SkinBackgroundConfig>\n if (knownFields.length === 0) return null\n const owned: SkinBackgroundConfig = {}\n for (const field of knownFields) {\n ;(owned as Record<string, unknown>)[field] = normalized[field]\n }\n return owned\n}\n\n/**\n * Build a v2-safe patch from the raw user layer. Absent fields, including\n * schema-default fields absent from the user layer, never enter the patch.\n */\nexport function skinBackgroundUserPatch(current: SkinBackgroundConfig, user: unknown): SkinBackgroundConfig | null {\n const userConfig = extractSkinBackgroundUserLayer(user)\n if (userConfig === null) return null\n const patch: SkinBackgroundConfig = {}\n for (const field of SKIN_BACKGROUND_FIELDS) {\n if (!Object.hasOwn(userConfig, field)) continue\n const value = userConfig[field]\n if (value === undefined || value === current[field]) continue\n ;(patch as Record<string, unknown>)[field] = value\n }\n return Object.keys(patch).length === 0 ? null : patch\n}\n\nexport interface SkinBackgroundScopeSnapshot {\n revision: number | undefined\n user: unknown\n}\n\nexport interface SkinBackgroundScopeReconcileResult {\n accepted: boolean\n revision: number | undefined\n lastUserJson: string\n patch: SkinBackgroundConfig | null\n}\n\n/** Deterministic serialization of the user layer for content-based dedup. */\nexport function serializeSkinBackgroundUserLayer(user: unknown): string {\n const extracted = extractSkinBackgroundUserLayer(user)\n return extracted === null ? '' : JSON.stringify(extracted)\n}\n\n/**\n * Full reconciliation state the browser glue keeps across scope publications.\n * It adds boot ordering to the revision/content fence so the settings\n * document's initial sync can never be mistaken for a settings-page edit\n * (#1375): a legacy user layer carrying stale explicit values (zeros written\n * by the pre-#1107 bug family) would otherwise patch — and persist over — the\n * authoritative v2 state on every boot where the document and the v2 GET\n * finish in the unlucky order.\n */\nexport interface SkinBackgroundReconcileState {\n /** Whether the authoritative v2 GET has completed and applied its values. */\n v2Loaded: boolean\n /** Whether the one-shot boot document sync (first revisioned publication) was consumed. */\n bootSyncSeen: boolean\n /** Last namespace revision seen (published, or seeded at construction). */\n lastRevision: number | undefined\n /** Serialized user layer seen last, for content-based replay dedup. */\n lastUserJson: string\n}\n\n/** Seed the reconcile state from the scope snapshot visible at construction. */\nexport function initialSkinBackgroundReconcileState(\n snapshot: SkinBackgroundScopeSnapshot,\n): SkinBackgroundReconcileState {\n return {\n v2Loaded: false,\n bootSyncSeen: false,\n lastRevision: snapshot.revision,\n lastUserJson: serializeSkinBackgroundUserLayer(snapshot.user),\n }\n}\n\n/**\n * Fold one scope publication into the reconcile state and produce the v2-safe\n * patch to merge into the live background values (null = nothing to apply).\n *\n * The boot document never merges, whichever order it lands in:\n * - a publication seen before the v2 GET completes is only recorded, so the\n * post-load check reads it as the unchanged boot snapshot, not an edit;\n * - the first revisioned publication of the plugin's lifetime (the document\n * resync itself) is consumed as the boot sync even when it lands after the\n * GET, because a genuine settings-page edit can only follow the document.\n */\nexport function reconcileSkinBackgroundPublication(\n state: SkinBackgroundReconcileState,\n current: SkinBackgroundConfig,\n snapshot: SkinBackgroundScopeSnapshot,\n): { state: SkinBackgroundReconcileState; patch: SkinBackgroundConfig | null } {\n const seen: SkinBackgroundReconcileState = {\n ...state,\n lastRevision: snapshot.revision ?? state.lastRevision,\n lastUserJson: serializeSkinBackgroundUserLayer(snapshot.user),\n }\n if (!state.v2Loaded) return { state: seen, patch: null }\n if (!state.bootSyncSeen) {\n return {\n state: snapshot.revision === undefined ? seen : { ...seen, bootSyncSeen: true },\n patch: null,\n }\n }\n const result = reconcileSkinBackgroundScope(current, snapshot, state.lastRevision, state.lastUserJson)\n return { state: seen, patch: result.patch }\n}\n\n/**\n * Accept a scope publication only when its namespace revision is new AND the\n * user layer has actually changed. A revision bump with identical user-layer\n * content is a replay (settings-mirror resync, WS reconnect, or another\n * plugin writing to the global settings document) and must not overwrite the\n * authoritative v2 state.\n */\nexport function reconcileSkinBackgroundScope(\n current: SkinBackgroundConfig,\n snapshot: SkinBackgroundScopeSnapshot,\n lastRevision: number | undefined,\n lastUserJson: string | undefined,\n): SkinBackgroundScopeReconcileResult {\n const currentUserJson = serializeSkinBackgroundUserLayer(snapshot.user)\n if (\n snapshot.revision === undefined\n || snapshot.revision === lastRevision\n || currentUserJson === lastUserJson\n || currentUserJson === ''\n ) {\n return {\n accepted: false,\n revision: snapshot.revision ?? lastRevision,\n lastUserJson: currentUserJson,\n patch: null,\n }\n }\n return {\n accepted: true,\n revision: snapshot.revision,\n lastUserJson: currentUserJson,\n patch: skinBackgroundUserPatch(current, snapshot.user),\n }\n}\n","/**\n * Skin-center locale dictionaries. The plugin-card name, its description,\n * and every control of the in-GUI skin center is localized through the\n * standard `t` seat.\n */\n\n/** Copy keys owned by this plugin. */\nexport type SkinCenterKey =\n | 'title'\n | 'cardDescription'\n | 'enabled'\n | 'enabledHint'\n | 'offNote'\n | 'intro'\n | 'official'\n | 'officialTagline'\n | 'active'\n | 'tryingOn'\n | 'tryOn'\n | 'loading'\n | 'exitTryOn'\n | 'apply'\n | 'applying'\n | 'restore'\n | 'applyFailed'\n | 'appliedUnconfirmed'\n | 'appliedNeedRestart'\n | 'theme'\n | 'themeLight'\n | 'themeDark'\n | 'tryOnError'\n | 'backgroundOpacity'\n | 'backgroundBlurEmpty'\n | 'backgroundBlurContent'\n | 'inputCardBlur'\n | 'inputCardBlurHint'\n | 'bubbleOpacity'\n | 'bubbleOpacityHint'\n | 'backgroundBlurHint'\n | 'backgroundBlurInert'\n | 'backgroundHint'\n | 'backgroundHintInert'\n | 'wallpaperTitle'\n | 'wallpaperEnable'\n | 'wallpaperHint'\n | 'wallpaperLoadError'\n | 'wallpaperLibraryFound'\n | 'wallpaperLibraryManual'\n | 'wallpaperLibrarySystem'\n | 'wallpaperRefresh'\n | 'wallpaperMode'\n | 'wallpaperModeLive'\n | 'wallpaperModeFrame'\n | 'wallpaperFit'\n | 'wallpaperFitCover'\n | 'wallpaperFitContain'\n | 'wallpaperFitFill'\n | 'wallpaperClear'\n | 'wallpaperDim'\n | 'wallpaperOpacity'\n | 'wallpaperBlur'\n | 'wallpaperPauseHidden'\n | 'wallpaperSound'\n | 'wallpaperSoundHint'\n | 'wallpaperVolume'\n | 'wallpaperImport'\n | 'wallpaperImportHint'\n | 'wallpaperReimport'\n | 'wallpaperRemove'\n | 'wallpaperUpdateAvailable'\n | 'wallpaperEmpty'\n | 'wallpaperTypeVideo'\n | 'wallpaperTypeWeb'\n | 'wallpaperTypeScene'\n | 'wallpaperTypeApp'\n | 'wallpaperTypeImage'\n | 'wallpaperLoadMore'\n | 'wallpaperDirs'\n | 'wallpaperDirsEmpty'\n | 'wallpaperDirsHint'\n | 'wallpaperDirPlaceholder'\n | 'wallpaperDirAdd'\n | 'wallpaperDirBrowse'\n | 'wallpaperDirBrowseHint'\n | 'wallpaperDirBrowseFailed'\n | 'wallpaperRatingAll'\n | 'wallpaperRatingG'\n | 'wallpaperRatingPg13'\n | 'wallpaperRatingR18'\n | 'wallpaperPagePrev'\n | 'wallpaperPageNext'\n | 'wallpaperPageJump'\n | 'wallpaperPageTotal'\n | 'customThemeTitle'\n | 'customThemeTagline'\n | 'customThemeEdit'\n | 'customThemeCloseEdit'\n | 'customThemeMode'\n | 'customThemeLight'\n | 'customThemeDark'\n | 'customThemeAccent'\n | 'customThemeBackground'\n | 'customThemeForeground'\n | 'customThemeContrast'\n | 'customThemeReset'\n | 'customThemeResetHint'\n | 'customThemeSaveFailed'\n | 'uninstall'\n | 'uninstalling'\n | 'uninstallConfirm'\n | 'uninstallFailed'\n | 'verifyIntegrity'\n | 'verifyingIntegrity'\n | 'verifyAllPassed'\n | 'verifyFoundIssues'\n | 'integrityValid'\n | 'integrityTampered'\n | 'integrityMissing'\n | 'integrityHooksRefused'\n | 'cancel'\n | 'confirm'\n | 'verifyRepaired'\n | 'verifyRepairFailed'\n | 'repair'\n | 'repairing'\n | 'repaired'\n\nexport const en: Record<SkinCenterKey, string> = {\n title: 'Skin Center',\n cardDescription: 'Try on any installed skin live in the GUI — exit restores instantly, applying persists in one click.',\n enabled: 'Enable skin center',\n enabledHint: 'When off, try-on, apply and background controls are disabled; turn it back on to resume.',\n offNote: 'The skin center is turned off.',\n intro: 'Try on any skin live — it takes effect instantly, exit restores the current look. Apply persists it across restarts.',\n official: 'Official default',\n officialTagline: 'The stock DSH look with no skin applied.',\n active: 'Active',\n tryingOn: 'Trying on',\n tryOn: 'Try on',\n loading: 'Loading…',\n exitTryOn: 'Exit try-on',\n apply: 'Apply',\n applying: 'Applying…',\n restore: 'Restore',\n applyFailed: 'Apply failed',\n appliedUnconfirmed: 'Applied, but the change has not been confirmed — refresh the page in dev mode; packaged installs (DSH Desktop) need an app restart',\n appliedNeedRestart: 'Applied and confirmed, but the host did not hot-reload — restart dsh to take effect',\n theme: 'Theme preview',\n themeLight: 'Light',\n themeDark: 'Dark',\n tryOnError: 'Try-on failed — see console',\n backgroundOpacity: 'Background occlusion',\n backgroundBlurEmpty: 'Blur when empty',\n backgroundBlurContent: 'Blur with content',\n inputCardBlur: 'Input card blur',\n inputCardBlurHint: 'Blurs only the area behind the input card while backdrop art is visible; it does not blur the entire wallpaper.',\n bubbleOpacity: 'Bubble opacity',\n bubbleOpacityHint: 'Controls translucent message bubbles for skins that expose bubble alpha, such as Whale Mom.',\n backgroundBlurHint: 'Applies a separate Gaussian blur to the backdrop for the empty conversation and the conversation with content; 0 disables.',\n backgroundBlurInert: 'Visible only with skins that paint a backdrop; the official default has none.',\n backgroundHint: 'Instantly veils the backdrop behind the panels — higher values obscure the art to help you focus.',\n backgroundHintInert: 'Only applies to skins that paint a backdrop (Blue Fantasy / Whale Song). Applies to the official default automatically once such a skin is active.',\n wallpaperTitle: 'Wallpaper Engine',\n wallpaperEnable: 'Enable wallpapers',\n wallpaperHint: 'Use your local Wallpaper Engine library as the GUI backdrop: video, web, and scene wallpapers render live (scene wallpapers need WebGL).',\n wallpaperLoadError: 'Wallpaper library failed to load',\n wallpaperLibraryFound: 'Wallpaper Engine library detected',\n wallpaperLibraryManual: 'Manual folders only (no Wallpaper Engine install found; set folders in the skin-wallpaper settings)',\n wallpaperLibrarySystem: 'macOS wallpapers detected (aerials and Desktop Pictures)',\n wallpaperRefresh: 'Refresh',\n wallpaperMode: 'Render mode',\n wallpaperModeLive: 'Live',\n wallpaperModeFrame: 'Static frame',\n wallpaperFit: 'Sizing mode',\n wallpaperFitCover: 'Cover (fill)',\n wallpaperFitContain: 'Fit (entire image)',\n wallpaperFitFill: 'Stretch',\n wallpaperClear: 'Turn off wallpaper',\n wallpaperDim: 'Wallpaper dimming',\n wallpaperOpacity: 'Wallpaper opacity',\n wallpaperBlur: 'Wallpaper blur',\n wallpaperPauseHidden: 'Pause when window hidden',\n wallpaperSound: 'Wallpaper sound',\n wallpaperSoundHint: 'Play video wallpaper audio. The browser may keep it silent until you click or press a key once.',\n wallpaperVolume: 'Wallpaper volume',\n wallpaperImport: 'Import',\n wallpaperImportHint: 'Copy this wallpaper into local storage, so it keeps working even if the Steam library moves or changes',\n wallpaperReimport: 'Update',\n wallpaperRemove: 'Remove',\n wallpaperUpdateAvailable: 'The workshop original changed since import — update the local copy',\n wallpaperEmpty: 'No wallpapers found. Subscribe in the Wallpaper Engine workshop, or add manual folders to the skin-wallpaper settings.',\n wallpaperTypeVideo: 'Video',\n wallpaperTypeWeb: 'Web',\n wallpaperTypeScene: 'Scene (static)',\n wallpaperTypeApp: 'Unsupported',\n wallpaperTypeImage: 'Image',\n wallpaperLoadMore: 'Load more',\n wallpaperDirs: 'Manual folders',\n wallpaperDirsEmpty: 'No manual folders yet.',\n wallpaperDirsHint: 'No Wallpaper Engine (e.g. macOS)? Point a folder at any .mp4/.webm files, a wallpaper project folder, or a folder of projects — they become your wallpaper library.',\n wallpaperDirPlaceholder: '/path/to/wallpapers or ~/Movies/wallpapers',\n wallpaperDirAdd: 'Add',\n wallpaperDirBrowse: 'Browse…',\n wallpaperDirBrowseHint: 'Pick a folder with the system file manager (Finder / Explorer)',\n wallpaperDirBrowseFailed: 'Could not open the system folder picker — type the path manually instead',\n wallpaperRatingAll: 'All',\n wallpaperRatingG: 'G',\n wallpaperRatingPg13: 'PG-13',\n wallpaperRatingR18: 'R18',\n wallpaperPagePrev: 'Previous',\n wallpaperPageNext: 'Next',\n wallpaperPageJump: 'Go',\n wallpaperPageTotal: 'Page {page} / {total}',\n customThemeTitle: 'Custom theme',\n customThemeTagline: 'A separately saved palette derived from the official default theme.',\n customThemeEdit: 'Edit',\n customThemeCloseEdit: 'Collapse',\n customThemeMode: 'Editing mode',\n customThemeLight: 'Light',\n customThemeDark: 'Dark',\n customThemeAccent: 'Accent',\n customThemeBackground: 'Background',\n customThemeForeground: 'Foreground',\n customThemeContrast: 'Contrast',\n customThemeReset: 'Restore current mode default',\n customThemeResetHint: 'Only resets the selected light or dark profile.',\n customThemeSaveFailed: 'Could not save custom theme changes.',\n uninstall: 'Uninstall',\n uninstalling: 'Uninstalling…',\n uninstallConfirm: 'Are you sure you want to uninstall \"{name}\"? Local files will be deleted.',\n uninstallFailed: 'Uninstall failed',\n verifyIntegrity: 'Verify integrity',\n verifyingIntegrity: 'Verifying…',\n verifyAllPassed: 'All {count} installed skin(s) passed integrity verification',\n verifyFoundIssues: 'Found {count} skin(s) with integrity issues',\n integrityValid: 'Verified',\n integrityTampered: 'Modified',\n integrityMissing: 'Missing files',\n integrityHooksRefused: 'Hooks refused',\n cancel: 'Cancel',\n confirm: 'Confirm',\n verifyRepaired: 'Successfully repaired {count} skin(s) with integrity issues',\n verifyRepairFailed: 'Failed to repair {count} skin(s)',\n repair: 'Repair',\n repairing: 'Repairing…',\n repaired: 'Repaired',\n}\n\nexport const zh: Record<SkinCenterKey, string> = {\n title: '皮肤',\n cardDescription: '在 GUI 内即时试穿任意皮肤,退出即完全还原;应用一键完成并自动刷新。',\n enabled: '启用皮肤中心',\n enabledHint: '关闭后停用试穿、应用与背景控件,重新打开即恢复。',\n offNote: '皮肤中心已关闭。',\n intro: '任意皮肤可即时试穿,退出即完全还原;「应用」一键持久化,页面自动刷新生效。',\n official: '官方默认',\n officialTagline: '还原 DSH 官方默认外观,不应用任何皮肤。',\n active: '当前激活',\n tryingOn: '试穿中',\n tryOn: '试穿',\n loading: '加载中…',\n exitTryOn: '退出试穿',\n apply: '应用',\n applying: '应用中…',\n restore: '恢复默认',\n applyFailed: '应用失败',\n appliedUnconfirmed: '已写入配置但尚未确认生效——开发模式请刷新页面;打包版(DSH Desktop)需重启应用后生效',\n appliedNeedRestart: '已写入配置并确认生效,但宿主未热重载——请重启 dsh 后生效',\n theme: '主题预览',\n themeLight: '亮色',\n themeDark: '暗色',\n tryOnError: '试穿失败,详见控制台',\n backgroundOpacity: '背景遮挡',\n backgroundBlurEmpty: '空对话背景模糊',\n backgroundBlurContent: '有对话背景模糊',\n inputCardBlur: '输入卡模糊',\n inputCardBlurHint: '仅模糊输入卡背后的区域,不会让整张壁纸变糊。',\n bubbleOpacity: '气泡不透明度',\n bubbleOpacityHint: '调节支持气泡 alpha 的皮肤消息气泡,例如鲸鱼妈妈。',\n backgroundBlurHint: '对话为空与有内容时分别应用不同的背景高斯模糊强度,0 为关闭。',\n backgroundBlurInert: '仅对带背景图插画的皮肤可见;官方默认无背景图。',\n backgroundHint: '即时为面板背后的背景加遮罩——数值越高越能弱化插画,帮你集中注意力。',\n backgroundHintInert: '仅对带背景图插画的皮肤(蓝色幻想 / 鲸吟)生效;官方默认无背景图,该滑块对这些皮肤自动生效。',\n wallpaperTitle: 'Wallpaper Engine',\n wallpaperEnable: '启用动态壁纸',\n wallpaperHint: '把本机 Wallpaper Engine 壁纸库用作 GUI 背景:视频、网页与场景壁纸均动态渲染(场景壁纸需要 WebGL)。',\n wallpaperLoadError: '壁纸库加载失败',\n wallpaperLibraryFound: '已检测到 Wallpaper Engine 壁纸库',\n wallpaperLibraryManual: '仅手动目录(未检测到 Wallpaper Engine 安装,可在 skin-wallpaper 设置里添加目录)',\n wallpaperLibrarySystem: '已检测到 macOS 系统壁纸(航拍与桌面图片)',\n wallpaperRefresh: '刷新',\n wallpaperMode: '渲染模式',\n wallpaperModeLive: '动态',\n wallpaperModeFrame: '静态帧',\n wallpaperFit: '适应方式',\n wallpaperFitCover: '铺满裁剪',\n wallpaperFitContain: '完整缩放',\n wallpaperFitFill: '拉伸铺满',\n wallpaperClear: '关闭壁纸',\n wallpaperDim: '壁纸暗化',\n wallpaperOpacity: '壁纸不透明度',\n wallpaperBlur: '壁纸模糊',\n wallpaperPauseHidden: '窗口隐藏时暂停',\n wallpaperSound: '壁纸声音',\n wallpaperSoundHint: '播放视频壁纸的声音。浏览器可能在首次点击或按键前保持静音。',\n wallpaperVolume: '壁纸音量',\n wallpaperImport: '导入',\n wallpaperImportHint: '把该壁纸复制到本地存储,Steam 库迁移或变动后仍可继续使用',\n wallpaperReimport: '更新',\n wallpaperRemove: '移除',\n wallpaperUpdateAvailable: '工坊原件在导入后有更新——同步更新本地副本',\n wallpaperEmpty: '未发现壁纸。可先在 Wallpaper Engine 创意工坊订阅,或在 skin-wallpaper 设置里添加手动目录。',\n wallpaperTypeVideo: '视频',\n wallpaperTypeWeb: '网页',\n wallpaperTypeScene: '场景(静态)',\n wallpaperTypeApp: '不支持',\n wallpaperTypeImage: '静态图片',\n wallpaperLoadMore: '加载更多',\n wallpaperDirs: '手动目录',\n wallpaperDirsEmpty: '还没有手动目录。',\n wallpaperDirsHint: '没有 Wallpaper Engine(如 macOS)?把任意 .mp4/.webm 视频、单个壁纸项目文件夹或项目合集文件夹加进来,就是你的壁纸库。',\n wallpaperDirPlaceholder: '/path/to/wallpapers 或 ~/Movies/wallpapers',\n wallpaperDirAdd: '添加',\n wallpaperDirBrowse: '浏览…',\n wallpaperDirBrowseHint: '通过系统文件管理器(访达 / 资源管理器)选择文件夹',\n wallpaperDirBrowseFailed: '无法打开系统目录选择框——请手动输入路径',\n wallpaperRatingAll: '全部',\n wallpaperRatingG: 'G',\n wallpaperRatingPg13: 'PG-13',\n wallpaperRatingR18: 'R18',\n wallpaperPagePrev: '上一页',\n wallpaperPageNext: '下一页',\n wallpaperPageJump: '跳转',\n wallpaperPageTotal: '第 {page} / {total} 页',\n customThemeTitle: '自定义主题',\n customThemeTagline: '基于官方默认主题生成并独立保存的配色方案。',\n customThemeEdit: '编辑',\n customThemeCloseEdit: '收起',\n customThemeMode: '编辑模式',\n customThemeLight: '浅色',\n customThemeDark: '深色',\n customThemeAccent: '强调色',\n customThemeBackground: '背景色',\n customThemeForeground: '前景色',\n customThemeContrast: '对比度',\n customThemeReset: '恢复当前模式默认',\n customThemeResetHint: '只重置当前选择的浅色或深色配置。',\n customThemeSaveFailed: '自定义主题修改保存失败。',\n uninstall: '卸载',\n uninstalling: '卸载中…',\n uninstallConfirm: '确定要卸载皮肤「{name}」吗?本地文件将被永久删除。',\n uninstallFailed: '卸载失败',\n verifyIntegrity: '验证完整性',\n verifyingIntegrity: '正在验证…',\n verifyAllPassed: '所有 {count} 款已安装皮肤完整性正常',\n verifyFoundIssues: '发现 {count} 款皮肤存在完整性异常',\n verifyRepaired: '已自动修复 {count} 款皮肤的完整性异常',\n verifyRepairFailed: '{count} 款皮肤自动修复失败',\n repair: '修复',\n repairing: '修复中…',\n repaired: '已修复',\n integrityValid: '完整',\n integrityTampered: '文件已修改',\n integrityMissing: '缺少文件',\n integrityHooksRefused: 'Hooks 已拒绝',\n cancel: '取消',\n confirm: '确定',\n}\n","/**\n * Effect ledger (issue #506, contract section 6).\n *\n * Every runtime effect a skin activation creates — style tags, CSS variable\n * overrides, decoration-layer content, listeners, hook cleanups — is recorded\n * here as an append-only entry bound to its activation identity. Switching\n * skins releases the old activation's entries in reverse order; disposal is\n * idempotent and may run 0, 1 or N times.\n *\n * lifecycleScope split:\n * - \"activation\": everything injectable — released on every skin switch;\n * - \"component\": skin static assets and the user's selection — survive\n * switches, reloads and HMR. The ledger only tracks activation scope.\n *\n * Pure logic, no DOM types required (entries are opaque teardown closures).\n */\n\nexport type EffectKind = 'create' | 'bind' | 'replace' | 'release' | 'cleanup-failed'\n\nexport interface EffectLedgerEntry {\n /** Monotonic sequence number (append-only). */\n seq: number\n activationId: number\n kind: EffectKind\n /** Human-readable label for diagnostics (e.g. \"style:skin.css\"). */\n label: string\n /** For replace: the seq of the superseded entry. */\n replacesSeq?: number\n at: number\n}\n\ninterface LiveEffect {\n seq: number\n label: string\n teardown: () => void\n released: boolean\n}\n\nexport interface EffectLedger {\n /** Start a new activation identity. Returns its id. */\n beginActivation(): number\n /**\n * Record an effect under the activation. The teardown must be idempotent.\n * Throws if the activation was already disposed (fail-closed: no orphan\n * effects after a switch).\n */\n record(activationId: number, label: string, teardown: () => void): number\n /**\n * Record that `label` replaces a previous entry (e.g. decoration-layer\n * content swap). The replaced entry is released immediately.\n */\n replace(activationId: number, label: string, previousSeq: number | undefined, teardown: () => void): number\n /**\n * Release every live effect of the activation, newest first. Idempotent;\n * individual teardown failures are caught and logged as cleanup-failed\n * entries (one failing teardown never blocks the rest).\n */\n disposeActivation(activationId: number): void\n /** Whether disposeActivation has run for this activation. */\n isDisposed(activationId: number): boolean\n /** Read-only view of the append-only log (diagnostics / tests). */\n entries(): readonly EffectLedgerEntry[]\n}\n\nexport function createEffectLedger(now: () => number = () => Date.now()): EffectLedger {\n let seq = 0\n let nextActivation = 1\n const log: EffectLedgerEntry[] = []\n const live = new Map<number, LiveEffect[]>()\n const disposed = new Set<number>()\n\n function push(activationId: number, kind: EffectKind, label: string, replacesSeq?: number): number {\n seq += 1\n log.push({ seq, activationId, kind, label, replacesSeq, at: now() })\n return seq\n }\n\n function release(effect: LiveEffect, activationId: number): void {\n if (effect.released) return\n effect.released = true\n push(activationId, 'release', effect.label)\n try {\n effect.teardown()\n } catch {\n // A failing teardown must never block the remaining cleanup; the\n // failure itself is a ledger fact for diagnostics.\n push(activationId, 'cleanup-failed', effect.label)\n }\n }\n\n return {\n beginActivation() {\n const id = nextActivation++\n live.set(id, [])\n push(id, 'create', 'activation')\n return id\n },\n\n record(activationId, label, teardown) {\n const bucket = live.get(activationId)\n if (!bucket || disposed.has(activationId)) {\n throw new Error(`effect \"${label}\" recorded on disposed/unknown activation ${activationId}`)\n }\n const entrySeq = push(activationId, 'create', label)\n bucket.push({ seq: entrySeq, label, teardown, released: false })\n return entrySeq\n },\n\n replace(activationId, label, previousSeq, teardown) {\n const bucket = live.get(activationId)\n if (!bucket || disposed.has(activationId)) {\n throw new Error(`effect \"${label}\" replaced on disposed/unknown activation ${activationId}`)\n }\n if (previousSeq !== undefined) {\n const previous = bucket.find((e) => e.seq === previousSeq)\n if (previous) release(previous, activationId)\n }\n const entrySeq = push(activationId, 'replace', label, previousSeq)\n bucket.push({ seq: entrySeq, label, teardown, released: false })\n return entrySeq\n },\n\n disposeActivation(activationId) {\n if (disposed.has(activationId)) return\n disposed.add(activationId)\n const bucket = live.get(activationId) ?? []\n for (const effect of [...bucket].reverse()) release(effect, activationId)\n },\n\n isDisposed(activationId) {\n return disposed.has(activationId)\n },\n\n entries() {\n return log\n },\n }\n}\n","/**\n * Semantic adapter (issue #506, contract section 6, L2 compat adapter).\n *\n * One merged MutationObserver that stamps the semantic-attribute enumeration\n * (contracts/semantic-attrs-v1.md) onto the official shell DOM and onto\n * plugin roots that already expose stable anchors. This is explicitly a\n * COMPAT adapter — not a permanent public contract:\n * - official areas migrate to first-party attributes when the upstream\n * theme seam lands (then these rules are re-evaluated for deletion);\n * - third-party plugin areas stay here long-term (plugins that opt in\n * output the attributes themselves and the adapter becomes a no-op).\n *\n * Properties:\n * - merged: a single observer handles every rule;\n * - idempotent: re-tagging an already-correct element is a no-op, so React\n * re-renders simply get re-stamped when their nodes are re-added;\n * - fail-closed diagnostics: rules that match nothing and selectors the\n * engine rejects are reported, never thrown into the page;\n * - the adapter never REMOVES attributes it did not set; disposal only\n * disconnects the observer (stamping is cosmetic and scopes itself under\n * html[data-dsh-skin] consumers).\n * @module @linxin666/dsh-client-ui-skin-center/runtime/semantic-adapter\n */\n\nexport type SemanticAttr = 'data-dsh-surface' | 'data-dsh-part' | 'data-dsh-plugin'\n\nexport interface SemanticRule {\n /** CSS selector matched against added/existing elements. */\n selector: string\n /** Attribute(s) applied on match. */\n attrs: readonly (readonly [SemanticAttr, string])[]\n /** Why this rule exists / what it anchors (audit trail). */\n note: string\n}\n\n/**\n * The v1 rule table. Single ownership: only the skin-center edits this.\n * Anchors verified against @deepseek-ai rc.7 (see docs/archive survey).\n */\nexport const SEMANTIC_RULES_V1: readonly SemanticRule[] = [\n // ---- surfaces (official shell) ----\n { selector: '[data-slot=\"root\"]', attrs: [['data-dsh-surface', 'root']], note: 'ui-renderer root outlet' },\n { selector: '[data-slot=\"sidebar\"]', attrs: [['data-dsh-surface', 'sidebar']], note: 'layout sidebar outlet' },\n { selector: '[data-slot=\"conversation\"]', attrs: [['data-dsh-surface', 'conversation']], note: 'layout conversation outlet' },\n { selector: '[data-slot=\"conversation.session.header\"]', attrs: [['data-dsh-surface', 'session-header']], note: 'conversation header outlet' },\n { selector: '[data-slot=\"conversation.composer\"]', attrs: [['data-dsh-surface', 'composer']], note: 'composer chain outlet' },\n { selector: '[data-slot=\"details\"]', attrs: [['data-dsh-surface', 'details']], note: 'layout details outlet' },\n { selector: '[data-shell-overlay]', attrs: [['data-dsh-surface', 'overlay']], note: 'frame overlay attribute' },\n { selector: '[data-slot=\"shell.overlay\"]', attrs: [['data-dsh-surface', 'overlay']], note: 'shell overlay outlet' },\n {\n selector: '[role=\"dialog\"]:has([data-slot=\"settings.section\"])',\n attrs: [['data-dsh-surface', 'settings']],\n note: 'settings dialog (composite: dialog containing the section outlet)',\n },\n // ---- shell parts ----\n { selector: '[data-chat-flow-kind]', attrs: [['data-dsh-part', 'message-row']], note: 'chat flow item' },\n { selector: '[data-streaming]', attrs: [['data-dsh-part', 'message-body']], note: 'assistant markdown root' },\n { selector: '[data-conversation-scroll]', attrs: [['data-dsh-part', 'scrollport']], note: 'conversation scrollport' },\n { selector: 'textarea[data-phase]', attrs: [['data-dsh-part', 'composer-input']], note: 'composer textarea' },\n { selector: '[data-decoration=\"chip\"]', attrs: [['data-dsh-part', 'composer-chip']], note: 'composer reference chip' },\n { selector: '[data-queue-dock]', attrs: [['data-dsh-part', 'queue-dock']], note: 'queued turns dock' },\n { selector: '[data-turn-tail]', attrs: [['data-dsh-part', 'turn-tail']], note: 'turn tail row' },\n { selector: '[data-side]', attrs: [['data-dsh-part', 'resize-handle']], note: 'column resize handle' },\n {\n selector: 'button[class*=\"newSession\"]',\n attrs: [['data-dsh-part', 'new-session']],\n note: 'sidebar new-session action (compat seam shields skins from localized labels)',\n },\n // ---- plugin roots (plugins without stable anchors opt in via AGENTS.md) ----\n {\n selector: '[data-dsh-taskboard-view], [data-dsh-taskboard-board], [data-dsh-taskboard-entry]',\n attrs: [['data-dsh-plugin', 'task-board']],\n note: 'task-board panel/board/sidebar entry',\n },\n {\n selector: '[data-dsh-ssh-view], [data-dsh-ssh-entry]',\n attrs: [['data-dsh-plugin', 'ssh']],\n note: 'ssh panel/sidebar entry',\n },\n {\n selector: '[data-gitgraph-chip-anchor], [data-gitgraph-dialog]',\n attrs: [['data-dsh-plugin', 'git-graph']],\n note: 'git-graph chip/dialog',\n },\n {\n selector: '[data-dsh-pet-root]',\n attrs: [['data-dsh-plugin', 'pet']],\n note: 'pet global root',\n },\n // ---- family parts ----\n {\n selector: '[data-dsh-taskboard-entry], [data-dsh-ssh-entry]',\n attrs: [['data-dsh-part', 'sidebar-entry']],\n note: 'shared injected sidebar entry rows',\n },\n]\n\nexport interface SemanticAdapterDiagnostics {\n /** Rules whose selector the engine rejects (dropped, never retried). */\n invalidRules: string[]\n /** Rules that matched zero elements in the latest full pass. */\n unmatchedRules: string[]\n /** Total attributes stamped since start. */\n stamped: number\n}\n\nexport interface SemanticAdapter {\n start(): void\n stop(): void\n diagnostics(): SemanticAdapterDiagnostics\n readonly running: boolean\n}\n\ninterface LiveRule {\n rule: SemanticRule\n /** False once the engine rejected the selector. */\n usable: boolean\n /** Elements matched in the latest full pass. */\n matchedInPass: number\n}\n\nexport function createSemanticAdapter(doc: Document): SemanticAdapter {\n const rules: LiveRule[] = SEMANTIC_RULES_V1.map((rule) => ({ rule, usable: true, matchedInPass: 0 }))\n let observer: MutationObserver | null = null\n let stamped = 0\n let running = false\n\n const applyRule = (live: LiveRule, el: Element): void => {\n if (!live.usable) return\n let hit = false\n try {\n hit = el.matches(live.rule.selector)\n } catch {\n live.usable = false\n return\n }\n if (!hit) return\n live.matchedInPass += 1\n for (const [name, value] of live.rule.attrs) {\n if (el.getAttribute(name) !== value) {\n el.setAttribute(name, value)\n stamped += 1\n }\n }\n }\n\n const applyToTree = (rootEl: Element): void => {\n for (const live of rules) {\n if (!live.usable) continue\n applyRule(live, rootEl)\n let matches: Element[] = []\n try {\n matches = Array.from(rootEl.querySelectorAll(live.rule.selector))\n } catch {\n live.usable = false\n continue\n }\n for (const el of matches) applyRule(live, el)\n }\n }\n\n const fullPass = (): void => {\n for (const live of rules) live.matchedInPass = 0\n if (doc.documentElement) applyToTree(doc.documentElement)\n }\n\n return {\n get running() {\n return running\n },\n\n start() {\n if (running) return\n running = true\n fullPass()\n observer = new doc.defaultView!.MutationObserver((records) => {\n try {\n for (const record of records) {\n for (const node of Array.from(record.addedNodes)) {\n if (node.nodeType === 1) applyToTree(node as Element)\n }\n }\n } catch {\n // Fail-closed: a tagging error must never break the host page.\n }\n })\n observer.observe(doc.body ?? doc.documentElement, { childList: true, subtree: true })\n },\n\n stop() {\n running = false\n observer?.disconnect()\n observer = null\n },\n\n diagnostics() {\n return {\n invalidRules: rules.filter((r) => !r.usable).map((r) => r.rule.selector),\n unmatchedRules: rules.filter((r) => r.usable && r.matchedInPass === 0).map((r) => r.rule.selector),\n stamped,\n }\n },\n }\n}\n","/**\n * Shared shell rendering corrections for every visual mode owned by the skin\n * center (issue #954). The official shell exposes stable slot / composer\n * anchors, while the workspace-list fade itself is still a CSS-module class.\n * Keep that fallback scoped below sidebar.workspaces so an unrelated animation\n * or overlay whose class contains \"fade\" is never affected.\n *\n * The stylesheet is inert for the stock look: a catalog skin, custom theme or\n * wallpaper must be active. It is installed once per runtime and removed with\n * that runtime, so disabling the plugin restores the shell unchanged.\n * @module @linxin666/dsh-client-ui-skin-center/runtime/shell-rendering\n */\n\n/** Marker owned by the shared shell-rendering stylesheet. */\nexport const SHELL_RENDERING_STYLE_ATTR = 'data-dsh-shell-rendering'\n\n/** Fallback composer seat height for scrollport bottom clearance (px). */\nexport const DEFAULT_COMPOSER_CLEARANCE_PX = 100\n\nconst ACTIVE_VISUAL_SELECTOR = [\n 'html[data-dsh-skin]',\n 'html[data-dsh-custom-theme]:not([data-dsh-skin])',\n 'html[data-dsh-wallpaper-active]',\n].join(', ')\n\nconst COMPOSER_SEAT_SELECTORS = [\n '[data-slot=\"conversation.composer\"]',\n '[data-composer-seat]',\n '[data-dsh-surface=\"composer\"]',\n]\n\n/** Build the inert-by-default public rendering corrections. */\nexport function shellRenderingCss(): string {\n const scopes = ACTIVE_VISUAL_SELECTOR.split(', ')\n const scoped = (selector: string): string => scopes.map(scope => `${scope} ${selector}`).join(',\\n')\n return `\n /* Viewport lock: prevent outer page scrollbar and viewport\n displacement during element focus/scrollIntoView. */\n ${ACTIVE_VISUAL_SELECTOR},\n ${scoped('body')} {\n height: 100% !important;\n width: 100% !important;\n overflow: hidden !important;\n margin: 0 !important;\n padding: 0 !important;\n }\n ${scoped('[data-slot=\"sidebar.workspaces\"] [class*=\"_fade\"]')} {\n background: none !important;\n background-image: none !important;\n }\n ${scoped('[data-composer-card] textarea[data-phase]::placeholder')},\n ${scoped('textarea[data-dsh-part=\"composer-input\"]::placeholder')} {\n color: var(--dsw-alias-label-secondary, var(--dsw-alias-label-caption)) !important;\n -webkit-text-fill-color: var(--dsw-alias-label-secondary, var(--dsw-alias-label-caption)) !important;\n opacity: 1 !important;\n }\n ${scoped('[data-phase=\"active\"] [data-slot=\"conversation.input.dock\"] > *')},\n ${scoped('[data-phase=\"active\"] [data-slot=\"conversation.composer.dock\"] > *')} {\n /* One skin-driven accessory surface for task and statistics docks. Skins\n automatically follow their existing semantic theme tokens and may\n override the --dsh-composer-accessory-* variables for a stronger\n signature without coupling this adapter to a specific catalog skin. */\n background: var(--dsh-composer-accessory-bg, var(--dsw-specific-tip, var(--dsw-alias-bg-layer-1))) !important;\n color: var(--dsh-composer-accessory-color, var(--dsw-alias-label-tertiary)) !important;\n border: var(--dsh-composer-accessory-border, none) !important;\n border-radius: var(--dsh-composer-accessory-radius, 12px) !important;\n box-shadow: var(--dsh-composer-accessory-shadow, var(--dsw-shadow-lv1, 0 2px 10px rgba(7, 20, 38, 0.18)));\n backdrop-filter: blur(var(--dsh-composer-accessory-blur, var(--dsh-input-card-blur, 10px))) !important;\n -webkit-backdrop-filter: blur(var(--dsh-composer-accessory-blur, var(--dsh-input-card-blur, 10px))) !important;\n }\n ${scoped('[data-phase=\"active\"] [data-slot=\"conversation.composer.dock\"] > *')} {\n margin-top: var(--dsh-composer-accessory-gap, 4px);\n margin-bottom: var(--dsh-composer-accessory-gap, 4px);\n padding-top: 2px;\n padding-bottom: 2px;\n }\n ${scoped('[data-slot=\"conversation.input.dock\"] > [data-goal-bar=\"true\"][data-goal-bar=\"true\"][data-goal-bar=\"true\"]')} {\n /* The host goal dock spans the full composer seat and contains its own\n centered compact bar. Do not paint the outer dock as an accessory: that\n creates a viewport-wide veil behind the active-goal chip. The repeated\n stable marker deliberately raises specificity above catalog-skin dock\n selectors that load after this shared adapter. */\n background: transparent !important;\n border: 0 !important;\n border-radius: 0 !important;\n box-shadow: none !important;\n backdrop-filter: none !important;\n -webkit-backdrop-filter: none !important;\n }\n ${scoped('[data-conversation-scroll]')},\n ${scoped('[data-dsh-part=\"scrollport\"]')} {\n /* The composer is the scrollport's final in-flow child. Reserving physical\n padding after it lifts the active dock by one composer height and also\n shifts the hero above center. */\n padding-bottom: 0 !important;\n }\n /* #978 / #1133: Line-level scroll-margin retains scrollIntoView() clearance\n above the sticky composer without placing a scrollport-level scroll-padding\n that breaks browser caret-reveal geometry (which caused micro-scrolling on\n every keystroke while reading history). */\n ${scoped('[data-conversation-scroll] [data-chat-anchor-key]')},\n ${scoped('[data-conversation-scroll] [data-chat-flow-kind]')},\n ${scoped('[data-conversation-scroll] [data-dsh-part=\"message-row\"]')},\n ${scoped('[data-conversation-scroll] [data-turn-tail]')},\n ${scoped('[data-conversation-scroll] [class*=\"_userRow\"]')},\n ${scoped('[data-conversation-scroll] [class*=\"_compactionRow\"]')},\n ${scoped('[data-conversation-scroll] [class*=\"_contextRow\"]')},\n ${scoped('[data-conversation-scroll] [class*=\"_turnErrorRow\"]')} {\n scroll-margin-bottom: var(--dsh-composer-height, ${DEFAULT_COMPOSER_CLEARANCE_PX}px) !important;\n }\n /* #1117: The upstream recommended badge pairs two background-fill tokens\n as bg + text — in dark mode, skins like Blue Fantasy collapse them to\n near-identical dark navy values (contrast ~1:1). Override the text\n color to a readable foreground and tweak the background for contrast.\n The dark-theme attribute lives on <body>, so it belongs inside the\n scoped selector: prefixing the already-scoped list produced\n \"body ... html ...\", a descendant chain that can never match (#1490). */\n ${scoped('body[data-ds-dark-theme] [data-question-key] [class*=\"_badge\"]')},\n ${scoped('body[data-ds-dark-theme] [data-question-scroll] [class*=\"_badge\"]')} {\n color: var(--dsw-alias-label-primary, #ffffff) !important;\n background: var(--dsw-alias-interactive-bg-active, color-mix(in srgb, var(--dsw-alias-button-info-fill, #4a5fa8) 50%, transparent)) !important;\n }\n `\n}\n\n/** Install the shared corrections and return their idempotent teardown. */\nexport function installShellRenderingAdapter(doc: Document): () => void {\n if (doc.head === null) return () => {}\n const existing = doc.head.querySelector<HTMLStyleElement>(`style[${SHELL_RENDERING_STYLE_ATTR}]`)\n if (existing !== null) return () => {}\n\n const style = doc.createElement('style')\n style.setAttribute(SHELL_RENDERING_STYLE_ATTR, '')\n style.textContent = shellRenderingCss()\n doc.head.appendChild(style)\n\n const win = doc.defaultView\n try { win?.scrollTo?.(0, 0) } catch {}\n const composerSelector = COMPOSER_SEAT_SELECTORS.join(', ')\n let resizeObserver: ResizeObserver | null = null\n let mutationObserver: MutationObserver | null = null\n let observedComposer: Element | null = null\n let appliedHeight = ''\n let scheduledFrame: number | null = null\n let disposed = false\n\n // The shell mounts one composer seat per conversation; keep the resolved\n // element while it stays connected instead of re-querying the body for every\n // mutation batch (issue #954 follow-up: streaming produced many queries/s).\n const resolveComposer = (): Element | null => {\n if (observedComposer !== null && observedComposer.isConnected) return observedComposer\n return doc.body === null ? null : doc.body.querySelector(composerSelector)\n }\n\n const syncHeight = (): void => {\n if (doc.body === null) return\n const composer = resolveComposer()\n if (composer === null) return\n if (observedComposer !== composer) {\n if (observedComposer !== null && resizeObserver !== null) {\n resizeObserver.unobserve(observedComposer)\n }\n observedComposer = composer\n if (resizeObserver !== null) {\n resizeObserver.observe(composer)\n }\n }\n const rect = composer.getBoundingClientRect()\n if (rect.height <= 0) return\n const root = doc.documentElement\n const next = `${Math.ceil(rect.height)}px`\n // Skip the custom-property write (and its forced style invalidation) while\n // the measured height still matches what is already applied.\n if (next === appliedHeight || root === null) return\n appliedHeight = next\n root.style.setProperty('--dsh-composer-height', next)\n }\n\n // Coalesce mutation bursts into at most one measure/write per frame; the\n // disposer cancels whatever is still scheduled.\n const scheduleSync = (): void => {\n if (scheduledFrame !== null || disposed) return\n if (win === null || typeof win.requestAnimationFrame !== 'function') {\n syncHeight()\n return\n }\n scheduledFrame = win.requestAnimationFrame(() => {\n scheduledFrame = null\n if (disposed) return\n syncHeight()\n })\n }\n\n if (win !== null && typeof win.ResizeObserver === 'function') {\n resizeObserver = new win.ResizeObserver(() => syncHeight())\n }\n\n if (win !== null && typeof win.MutationObserver === 'function' && doc.body !== null) {\n mutationObserver = new win.MutationObserver(() => scheduleSync())\n mutationObserver.observe(doc.body, { childList: true, subtree: true })\n }\n\n syncHeight()\n\n return () => {\n if (disposed) return\n disposed = true\n if (scheduledFrame !== null) {\n if (win !== null && typeof win.cancelAnimationFrame === 'function') win.cancelAnimationFrame(scheduledFrame)\n scheduledFrame = null\n }\n if (resizeObserver !== null) {\n resizeObserver.disconnect()\n resizeObserver = null\n }\n if (mutationObserver !== null) {\n mutationObserver.disconnect()\n mutationObserver = null\n }\n observedComposer = null\n appliedHeight = ''\n doc.documentElement?.style.removeProperty('--dsh-composer-height')\n style.remove()\n }\n}\n","/**\n * Fixed decoration layers (issue #506, contract section 6).\n *\n * Six skin-center-owned, non-interactive containers mounted once per\n * document (component scope): background / ambient / top / bottom / sidebar /\n * foreground. Skins fill them per activation (background media, scrims,\n * strips); the CONTENT is activation scope — on every switch the controller\n * replaces it through the effect ledger.\n *\n * Guarantees:\n * - pointer-events: none always (decoration must never eat clicks);\n * - the layer elements themselves survive skin switches, reloads of the\n * skin runtime, and HMR (ensure* is idempotent);\n * - stacking stays below the official shell overlay: background/ambient sit\n * behind the app, the strip/foreground layers use moderate z-indices that\n * lose to dialogs/overlays (official overlay paints above 1000);\n * - the background layer carries its own compositor layer (will-change:\n * transform): a full-viewport skin background image is expensive to\n * re-rasterize, and without isolation Chromium re-rasterizes it in\n * horizontal bands whenever unrelated repaint bursts (streaming chat,\n * animated pets, overlay menus) invalidate the same area — visible as\n * vertical band flicker (issue #1013).\n * @module @linxin666/dsh-client-ui-skin-center/runtime/decoration-layers\n */\n\nexport const DECORATION_LAYER_NAMES = [\n 'background',\n 'ambient',\n 'top',\n 'bottom',\n 'sidebar',\n 'foreground',\n] as const\n\nexport type DecorationLayerName = (typeof DECORATION_LAYER_NAMES)[number]\n\nexport type DecorationLayers = Record<DecorationLayerName, HTMLElement>\n\nconst LAYER_ATTR = 'data-dsh-skin-layer'\n\n/**\n * Per-layer paint order. The background sits at -2: negative z-index\n * elements paint ABOVE the html/body backgrounds (so a skin's own opaque\n * root background-color renders BEHIND its art — the v1 layering) yet below\n * every panel surface. It shares -2 with the WE scrim, which never paints\n * at the same time (an active WE wallpaper suppresses skin media, enforced\n * by the controller). The skin-background blur veil (-1) still samples the\n * art above it. Ambient effects paint above the veils; the strip/foreground\n * layers stay below the official overlay band (>=1000).\n */\nconst LAYER_STYLE: Record<DecorationLayerName, string> = {\n // Explicit longhands only: the inset shorthand has burned us once (a\n // mid-session layer lost its bottom edge), longhands parse everywhere.\n background: 'position:fixed;top:0;right:0;bottom:0;left:0;z-index:-2;pointer-events:none;will-change:transform;',\n ambient: 'position:fixed;top:0;right:0;bottom:0;left:0;z-index:30;pointer-events:none;',\n top: 'position:fixed;top:0;left:0;right:0;z-index:40;pointer-events:none;',\n bottom: 'position:fixed;bottom:0;left:0;right:0;z-index:40;pointer-events:none;',\n sidebar: 'position:fixed;top:0;bottom:0;left:0;z-index:40;pointer-events:none;',\n foreground: 'position:fixed;top:0;right:0;bottom:0;left:0;z-index:41;pointer-events:none;',\n}\n\nfunction ensureOne(doc: Document, name: DecorationLayerName): HTMLElement {\n const existing = doc.querySelector<HTMLElement>(`[${LAYER_ATTR}=\"${name}\"]`)\n if (existing) {\n // Never trust a previous writer's styles: re-assert invariants.\n existing.style.cssText = LAYER_STYLE[name]\n return existing\n }\n const el = doc.createElement('div')\n el.setAttribute(LAYER_ATTR, name)\n el.setAttribute('aria-hidden', 'true')\n el.style.cssText = LAYER_STYLE[name]\n doc.body.appendChild(el)\n return el\n}\n\n/**\n * Ensure all six layers exist and return their handles. Idempotent; safe to\n * call on every activation.\n */\nexport function ensureDecorationLayers(doc: Document): DecorationLayers {\n return {\n background: ensureOne(doc, 'background'),\n ambient: ensureOne(doc, 'ambient'),\n top: ensureOne(doc, 'top'),\n bottom: ensureOne(doc, 'bottom'),\n sidebar: ensureOne(doc, 'sidebar'),\n foreground: ensureOne(doc, 'foreground'),\n }\n}\n\n/**\n * Replace one layer's content (activation scope). Returns a teardown that\n * removes exactly the nodes this call added — idempotent, ledger-ready.\n */\nexport function setLayerContent(\n layer: HTMLElement,\n nodes: Iterable<Node>,\n): () => void {\n const added = [...nodes]\n for (const node of added) layer.appendChild(node)\n let done = false\n return () => {\n if (done) return\n done = true\n for (const node of added) node.parentNode?.removeChild(node)\n }\n}\n\n/** Remove every node an activation left in a layer (used on dispose). */\nexport function clearLayer(layer: HTMLElement): void {\n while (layer.firstChild) layer.removeChild(layer.firstChild)\n}\n\n/**\n * Build the background media element for a manifest backgroundMedia layer.\n * Returns null when the theme variant has no media. The element fills the\n * background layer; the scrim (when declared) is a sibling overlay.\n */\nexport function buildBackgroundMedia(\n doc: Document,\n layer: { type: 'image' | 'video'; src: string; scrim?: string },\n assetBase: string,\n): HTMLElement[] {\n const nodes: HTMLElement[] = []\n const fullBleed = 'position:absolute;top:0;right:0;bottom:0;left:0;width:100%;height:100%;object-fit:cover;'\n if (layer.type === 'image') {\n const img = doc.createElement('img')\n img.src = `${assetBase}/${layer.src}`\n img.alt = ''\n img.setAttribute('aria-hidden', 'true')\n img.style.cssText = fullBleed\n nodes.push(img)\n } else {\n const video = doc.createElement('video')\n video.src = `${assetBase}/${layer.src}`\n video.muted = true\n video.loop = true\n video.autoplay = true\n video.playsInline = true\n video.setAttribute('aria-hidden', 'true')\n video.style.cssText = fullBleed\n nodes.push(video)\n }\n if (layer.scrim) {\n const scrim = doc.createElement('div')\n scrim.setAttribute('aria-hidden', 'true')\n scrim.style.cssText = `position:absolute;inset:0;background:${layer.scrim};`\n nodes.push(scrim)\n }\n return nodes\n}\n","/**\n * Skin runtime controller (issue #506, contract section 8) — the browser\n * switch engine. One switch is one NEW activation identity:\n *\n * switchTo(id):\n * 1. seq = ++latestRequest (latest-request-wins)\n * 2. activation = ledger.beginActivation()\n * 3. fetch stylesheet (+ patches) (already scoped + whitelisted host-side)\n * 4. install <style> tags, background media, hooks (all ledger-recorded)\n * 5. if seq is stale -> dispose this activation and bail\n * 6. flip html[data-dsh-skin] (the atomic visual cut)\n * 7. dispose the previous activation\n * 8. persist the selection\n *\n * Every step before the flip is discardable; a stale or failed switch leaves\n * the previous skin fully intact. hooks import/apply errors are caught: the\n * static part (stylesheet, media) stays active — the escape hatch can never\n * take the skin down with it.\n *\n * lifecycleScope split: the ledger tracks activation scope; the catalog\n * snapshot, the decoration layer elements and the persisted selection are\n * component scope and survive every switch.\n * @module @linxin666/dsh-client-ui-skin-center/runtime/skin-controller\n */\n\nimport type { EffectLedger } from './effect-ledger.ts'\nimport { buildBackgroundMedia, clearLayer, ensureDecorationLayers } from './decoration-layers.ts'\nimport type { DecorationLayers } from './decoration-layers.ts'\nimport { setSceneBackdropActive } from './backdrop-scene.ts'\n\n/** Catalog entry shape the controller needs (mirrors the v2 catalog route). */\nexport interface ControllerSkinEntry {\n manifest: {\n id: string\n contributes: {\n stylesheet: string\n patches?: string\n backgroundMedia?: {\n light?: { type: 'image' | 'video'; src: string; scrim?: string }\n dark?: { type: 'image' | 'video'; src: string; scrim?: string }\n }\n }\n facets?: { client?: { entry: string; apiVersion: string } }\n }\n}\n\nexport interface SkinControllerDeps {\n doc: Document\n ledger: EffectLedger\n /** Same-origin base of the v2 API (default /api/skin-center/v2). */\n apiBase?: string\n /** fetch injection for tests. */\n fetchImpl?: typeof fetch\n /** Persist the selection (POST /active by default). */\n persist?: (id: string | null) => Promise<void>\n /** Current light/dark theme (defaults to body[data-ds-dark-theme]). */\n themeGet?: () => 'light' | 'dark'\n /**\n * Theme-change subscription. The default observes the official\n * body[data-ds-dark-theme] attribute (the same ground truth v1 skins\n * used), so hooks get live theme flips out of the box.\n */\n themeSubscribe?: (listener: (theme: 'light' | 'dark') => void) => () => void\n /**\n * Stylesheet loader seam. Default installs a <link rel=\"stylesheet\"> and\n * awaits its load (relative url() inside the served CSS resolves against\n * the route URL — inlining into <style> would break asset resolution).\n */\n loadStylesheet?: (href: string) => Promise<void>\n /** hooks.mjs dynamic import seam for tests. */\n importHooks?: (url: string) => Promise<unknown>\n /**\n * Background-media priority (issue #506): when this returns true the\n * skin's manifest backgroundMedia is NOT painted — the Wallpaper Engine\n * wallpaper (and the user's manual background) outrank it. Re-evaluated\n * on every activation and on refresh().\n */\n suppressBackgroundMedia?: () => boolean\n /** Diagnostics sink (switch failures, hook errors). */\n onError?: (message: string, error: unknown) => void\n}\n\nexport interface SkinControllerState {\n /** The currently applied skin (null = stock look). */\n active: string | null\n /** The previewed skin id (null = the stock look is being previewed). */\n trying: string | null\n /** Whether a try-on preview is live (distinguishes previewing the stock\n * look from having no preview). */\n previewing: boolean\n}\n\nexport interface SkinController {\n /** Current applied skin id (null = stock look). */\n readonly active: string | null\n /** The fixed decoration layer handles (component scope). */\n readonly layers: DecorationLayers\n /**\n * Switch to a skin (or null for stock). Latest request wins; resolves to\n * the id that is actually active after this call settles (which may be a\n * newer one if a later switch superseded it).\n */\n switchTo(id: string | null, entry: ControllerSkinEntry | null): Promise<string | null>\n /**\n * Preview a skin without persisting it. The committed skin is remembered;\n * exitTryOn() restores it. Try-on of the stock look passes null.\n */\n tryOn(id: string | null, entry: ControllerSkinEntry | null): Promise<string | null>\n /** Leave the preview, restoring the committed skin. */\n exitTryOn(): Promise<string | null>\n /** React-friendly store: subscribe + snapshot of {active, trying}. */\n subscribe(listener: () => void): () => void\n getState(): SkinControllerState\n /**\n * Re-apply the current committed skin without persisting (e.g. the\n * wallpaper bridge just toggled, flipping background-media priority).\n * A full fresh activation — latest-request-wins keeps it race-safe.\n */\n refresh(): Promise<string | null>\n /** Dispose the current activation (e.g. on plugin teardown). */\n shutdown(): void\n}\n\ninterface HooksModule {\n default?: () => { apply(ctx: unknown): void; dispose?: () => void }\n}\n\nexport function createSkinController(deps: SkinControllerDeps): SkinController {\n const doc = deps.doc\n const ledger = deps.ledger\n const apiBase = deps.apiBase ?? '/api/skin-center/v2'\n const fetchImpl = deps.fetchImpl ?? fetch.bind(doc.defaultView)\n const layers = ensureDecorationLayers(doc)\n const onError = deps.onError ?? (() => {})\n\n const themeGet = deps.themeGet ?? (() =>\n (doc.body?.hasAttribute('data-ds-dark-theme') ? 'dark' : 'light'))\n const themeSubscribe = deps.themeSubscribe ?? ((listener) => {\n let last = themeGet()\n const observer = new doc.defaultView!.MutationObserver(() => {\n const next = themeGet()\n if (next !== last) {\n last = next\n listener(next)\n }\n })\n if (doc.body) observer.observe(doc.body, { attributes: true, attributeFilter: ['data-ds-dark-theme'] })\n return () => observer.disconnect()\n })\n /**\n * Re-paint the current activation's background media for the live\n * light/dark theme (the controller owns the layer, so a theme flip must\n * swap the variant the same way an activation does). No-op when there is\n * nothing painted or the manifest carries no backgroundMedia.\n */\n function repaintBackgroundForTheme(): void {\n if (active === null || currentActivation === null || lastEntry === null) return\n const media = lastEntry.manifest.contributes.backgroundMedia\n if (!media) return\n if (deps.suppressBackgroundMedia?.() === true) return\n const variant = themeGet() === 'dark' ? (media.dark ?? media.light) : (media.light ?? media.dark)\n if (!variant) return\n const assetBase = `${apiBase}/skins/${lastEntry.manifest.id}`\n setBackgroundLayer(currentActivation, buildBackgroundMedia(doc, variant, assetBase))\n }\n const unsubscribeTheme = themeSubscribe(() => repaintBackgroundForTheme())\n const loadStylesheet = deps.loadStylesheet ?? ((href: string) => new Promise<void>((resolveLink, rejectLink) => {\n const link = doc.createElement('link')\n link.rel = 'stylesheet'\n link.href = href\n const timer = setTimeout(() => rejectLink(new Error(`stylesheet load timeout: ${href}`)), 15000)\n link.onload = () => { clearTimeout(timer); resolveLink() }\n link.onerror = () => { clearTimeout(timer); rejectLink(new Error(`stylesheet load failed: ${href}`)) }\n doc.head.appendChild(link)\n }))\n\n let latestRequest = 0\n let currentActivation: number | null = null\n const initialSkinId = doc.documentElement?.getAttribute('data-dsh-skin') || null\n let active: string | null = initialSkinId\n /** The committed selection try-on restores (component scope). */\n let committed: { id: string | null; entry: ControllerSkinEntry | null } = { id: initialSkinId, entry: null }\n /** Last non-null applied entry, so refresh() can re-activate it. */\n let lastEntry: ControllerSkinEntry | null = null\n /** Last evaluated background-suppression verdict (refresh() skips no-ops). */\n let lastSuppressed: boolean | null = deps.suppressBackgroundMedia?.() === true\n let trying: string | null = null\n let previewing = false\n const listeners = new Set<() => void>()\n // React's useSyncExternalStore requires a CACHED snapshot: getSnapshot must\n // return the same reference until the state actually changes, or the store\n // consumer loops forever (and the settings card crashes blank).\n let stateSnapshot: SkinControllerState = { active: initialSkinId, trying: null, previewing: false }\n const emit = (): void => {\n stateSnapshot = { active, trying, previewing }\n for (const listener of listeners) listener()\n }\n\n /**\n * Install one stylesheet as a tracked <link> (the load itself happened in\n * loadStylesheet; here we only register the teardown). Links keep relative\n * url() resolution intact — a <style> tag would resolve them against the\n * document and 404 every skin asset.\n */\n function trackStylesheet(activation: number, label: string, href: string): void {\n const link = doc.head.querySelector<HTMLLinkElement>(`link[href=\"${href}\"]`)\n ledger.record(activation, `style:${label}`, () => link?.remove())\n }\n\n /**\n * Paint the skin background art into the `background` decoration layer\n * (z-index:-2) with a snapshot for the activation ledger. Only the CURRENT\n * activation may restore: when an older activation is disposed after a\n * newer one already re-painted the layer, restoring its snapshot would\n * clobber the newer paint.\n *\n * Two reasons the art lives in the layer, not on `document.body`:\n * - Chromium's backdrop-filter does not sample the canvas/body background,\n * so the skin-center blur layer (z-index:-1) could never blur body-painted\n * art (issue #732 defect A). A real fixed element IS sampled, so after\n * this change the same blur + scrim controls work on the skin backdrop\n * just like they already do on the Wallpaper Engine layers (issue #777).\n * - dragon-heir hooks expect the art in ctx.layers.background (they swap\n * the painted img and apply the v1 filter lift); the layer is the v2\n * contract and body painting was a leftover half-migration.\n * The body's own opaque background is forced transparent while art is\n * mounted, or the shell's static panels would cover the negative-z layer.\n */\n function setBackgroundLayer(activation: number, nodes: HTMLElement[]): void {\n const style = doc.body.style\n const previousBackgroundColor = style.getPropertyValue('background-color')\n const previousBackgroundImage = style.getPropertyValue('background-image')\n const restore = (): void => {\n if (currentActivation !== activation) return\n clearLayer(layers.background)\n setSceneBackdropActive(doc, 'skin', false)\n if (previousBackgroundColor === '') style.removeProperty('background-color')\n else style.setProperty('background-color', previousBackgroundColor)\n if (previousBackgroundImage === '') style.removeProperty('background-image')\n else style.setProperty('background-image', previousBackgroundImage)\n }\n clearLayer(layers.background)\n if (nodes.length > 0) {\n for (const node of nodes) layers.background.appendChild(node)\n style.setProperty('background-color', 'transparent')\n style.setProperty('background-image', 'none')\n setSceneBackdropActive(doc, 'skin', true)\n } else {\n setSceneBackdropActive(doc, 'skin', false)\n if (previousBackgroundColor === '') style.removeProperty('background-color')\n else style.setProperty('background-color', previousBackgroundColor)\n if (previousBackgroundImage === '') style.removeProperty('background-image')\n else style.setProperty('background-image', previousBackgroundImage)\n }\n ledger.record(activation, 'background:layer', restore)\n }\n\n function installBackground(\n activation: number,\n entry: ControllerSkinEntry,\n ): void {\n const media = entry.manifest.contributes.backgroundMedia\n if (!media) {\n setBackgroundLayer(activation, [])\n return\n }\n // WE wallpaper > user manual background > skin manifest background.\n if (deps.suppressBackgroundMedia?.() === true) {\n setBackgroundLayer(activation, [])\n return\n }\n const variant = themeGet() === 'dark' ? (media.dark ?? media.light) : (media.light ?? media.dark)\n if (!variant) {\n setBackgroundLayer(activation, [])\n return\n }\n const assetBase = `${apiBase}/skins/${entry.manifest.id}`\n setBackgroundLayer(activation, buildBackgroundMedia(doc, variant, assetBase))\n }\n\n async function installHooks(activation: number, entry: ControllerSkinEntry): Promise<void> {\n const facet = entry.manifest.facets?.client\n if (!facet) return\n const importHooks = deps.importHooks ?? ((url: string) => import(/* @vite-ignore */ url))\n try {\n const mod = (await importHooks(`${apiBase}/skins/${entry.manifest.id}/hooks.mjs`)) as HooksModule\n const factory = mod?.default\n if (typeof factory !== 'function') throw new Error('hooks.mjs must default-export defineSkinHooks()')\n const hooks = factory()\n if (typeof hooks?.apply !== 'function') throw new Error('defineSkinHooks() must return { apply }')\n const cleanups: Array<() => void> = []\n const ctx = {\n skinId: entry.manifest.id,\n scopeAttr: entry.manifest.id,\n assetBase: `${apiBase}/skins/${entry.manifest.id}`,\n layers,\n theme: {\n get: themeGet,\n subscribe: themeSubscribe,\n },\n onCleanup: (fn: () => void) => {\n cleanups.push(fn)\n },\n }\n hooks.apply(ctx)\n ledger.record(activation, 'hooks', () => {\n try {\n hooks.dispose?.()\n } catch (error) {\n onError(`hooks dispose failed for ${entry.manifest.id}`, error)\n }\n for (const cleanup of cleanups.reverse()) {\n try {\n cleanup()\n } catch (error) {\n onError(`hooks cleanup failed for ${entry.manifest.id}`, error)\n }\n }\n })\n } catch (error) {\n // The escape hatch never takes the static skin down with it.\n onError(`hooks failed for ${entry.manifest.id}; static skin stays active`, error)\n }\n }\n\n async function persist(id: string | null): Promise<void> {\n if (deps.persist) {\n await deps.persist(id)\n return\n }\n await fetchImpl(`${apiBase}/active`, {\n method: 'POST',\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify({ active: id }),\n })\n }\n\n async function switchInternal(\n id: string | null,\n entry: ControllerSkinEntry | null,\n shouldPersist: boolean,\n ): Promise<string | null> {\n const seq = ++latestRequest\n const activation = ledger.beginActivation()\n try {\n if (id !== null && entry !== null) {\n const stylesheetHref = `${apiBase}/skins/${id}/stylesheet`\n const patchesHref = entry.manifest.contributes.patches !== undefined\n ? `${apiBase}/skins/${id}/patches`\n : null\n await loadStylesheet(stylesheetHref)\n trackStylesheet(activation, 'stylesheet', stylesheetHref)\n if (patchesHref !== null) {\n await loadStylesheet(patchesHref).catch(() => {})\n trackStylesheet(activation, 'patches', patchesHref)\n }\n if (seq !== latestRequest) throw new StaleSwitch()\n installBackground(activation, entry)\n await installHooks(activation, entry)\n } else {\n // Stock / entryless switch owns the background layer too: it must\n // clear a previous skin's paint (the old activation's restore is\n // skipped as stale by the ownership gate).\n setBackgroundLayer(activation, [])\n }\n if (seq !== latestRequest) throw new StaleSwitch()\n\n // The atomic cut: attribute first, then retire the old activation.\n if (id === null) doc.documentElement.removeAttribute('data-dsh-skin')\n else doc.documentElement.setAttribute('data-dsh-skin', id)\n const previous = currentActivation\n currentActivation = activation\n active = id\n if (entry !== null) lastEntry = entry\n if (shouldPersist) {\n committed = { id, entry }\n trying = null\n previewing = false\n } else {\n previewing = id !== committed.id\n trying = previewing ? id : null\n }\n emit()\n if (previous !== null) ledger.disposeActivation(previous)\n if (shouldPersist) {\n await persist(id).catch((error) => onError('failed to persist the skin selection', error))\n }\n return active\n } catch (error) {\n ledger.disposeActivation(activation)\n if (error instanceof StaleSwitch) return active\n if (currentActivation === null) {\n active = null\n committed = { id: null, entry: null }\n doc.documentElement.removeAttribute('data-dsh-skin')\n emit()\n }\n onError(`switch to ${id ?? 'stock'} failed; previous skin intact`, error)\n return active\n }\n }\n\n return {\n get active() {\n return active\n },\n get layers() {\n return layers\n },\n\n async switchTo(id, entry) {\n return await switchInternal(id, entry, true)\n },\n\n async tryOn(id, entry) {\n return await switchInternal(id, entry, false)\n },\n\n async exitTryOn() {\n const result = await switchInternal(committed.id, committed.entry, false)\n return result\n },\n\n subscribe(listener) {\n listeners.add(listener)\n return () => listeners.delete(listener)\n },\n\n getState() {\n return stateSnapshot\n },\n\n async refresh() {\n const suppressed = deps.suppressBackgroundMedia?.() === true\n if (suppressed === lastSuppressed) return active\n lastSuppressed = suppressed\n const id = active\n if (id !== null && lastEntry === null) {\n return active\n }\n return await switchInternal(id, id === null ? null : lastEntry, false)\n },\n\n shutdown() {\n latestRequest += 1\n unsubscribeTheme()\n if (currentActivation !== null) {\n ledger.disposeActivation(currentActivation)\n currentActivation = null\n }\n active = null\n trying = null\n previewing = false\n committed = { id: null, entry: null }\n emit()\n doc.documentElement.removeAttribute('data-dsh-skin')\n },\n }\n}\n\nclass StaleSwitch extends Error {\n constructor() {\n super('superseded by a newer switch')\n }\n}\n","/**\n * Browser boot wiring for the v2 skin runtime (issue #506): one store per\n * document that owns the effect ledger, the skin controller, the semantic\n * adapter and the catalog snapshot. The settings card consumes the store;\n * the store outlives the card (settings panels unmount on close), so a\n * try-on preview survives closing and reopening the panel.\n *\n * Boot sequence: fetch the catalog snapshot once, read the persisted active\n * selection, and activate it (the tapIndex adapter already stamped the\n * attribute and preloaded the stylesheet for first paint; the controller\n * re-installs under ledger ownership so later switches stay atomic).\n * @module @linxin666/dsh-client-ui-skin-center/runtime/boot\n */\n\nimport { createEffectLedger } from './effect-ledger.ts'\nimport { createSemanticAdapter } from './semantic-adapter.ts'\nimport type { SemanticAdapter } from './semantic-adapter.ts'\nimport { installShellRenderingAdapter } from './shell-rendering.ts'\nimport { createSkinController } from './skin-controller.ts'\nimport type { ControllerSkinEntry, SkinController } from './skin-controller.ts'\n\n/** Display-ready catalog entry (manifest + origin), as served by /v2/catalog. */\nexport interface CatalogSkin {\n origin: 'builtin' | 'user'\n warnings: string[]\n manifest: ControllerSkinEntry['manifest'] & {\n name: string\n nameEn: string\n tagline?: string\n description?: string\n accent?: string\n order?: number\n author?: string\n license?: string\n attribution?: string\n preview?: { light: string; dark: string }\n tags?: string[]\n }\n}\n\nexport interface CatalogDiagnostic {\n subject: string\n origin: string\n errors: string[]\n}\n\nexport interface SkinRuntimeStore {\n readonly controller: SkinController\n readonly adapter: SemanticAdapter\n /** Loaded catalog snapshot (null until the first fetch resolves). */\n catalog(): CatalogSkin[] | null\n diagnostics(): CatalogDiagnostic[]\n /** Re-fetch the catalog (e.g. after the user drops a new skin directory). */\n refreshCatalog(): Promise<void>\n /** Find one entry in the current snapshot by id. */\n find(id: string): CatalogSkin | null\n /** Fires on catalog loads AND controller state transitions. */\n subscribe(listener: () => void): () => void\n /** Stop the semantic adapter and dispose the current activation. */\n shutdown(): void\n}\n\nexport interface BootOptions {\n doc?: Document\n apiBase?: string\n fetchImpl?: typeof fetch\n /** Background-media priority: true suppresses skin manifest media (WE wallpaper wins). */\n suppressBackgroundMedia?: () => boolean\n}\n\nexport function bootSkinRuntime(options: BootOptions = {}): SkinRuntimeStore {\n const doc = options.doc ?? document\n const apiBase = options.apiBase ?? '/api/skin-center/v2'\n const fetchImpl = options.fetchImpl ?? fetch.bind(doc.defaultView)\n\n const ledger = createEffectLedger()\n const controller = createSkinController({\n doc,\n ledger,\n apiBase,\n fetchImpl,\n suppressBackgroundMedia: options.suppressBackgroundMedia,\n // Switches fail closed to the previous skin; failures must still be\n // observable in the console (they are never thrown to the card).\n onError: (message, error) => {\n console.error(`[skin-center] ${message}`, error)\n },\n })\n const adapter = createSemanticAdapter(doc)\n adapter.start()\n const disposeShellRendering = installShellRenderingAdapter(doc)\n\n let catalog: CatalogSkin[] | null = null\n let diagnostics: CatalogDiagnostic[] = []\n const listeners = new Set<() => void>()\n const emit = (): void => {\n for (const listener of listeners) listener()\n }\n\n async function refreshCatalog(): Promise<void> {\n const res = await fetchImpl(`${apiBase}/catalog`)\n if (!res.ok) throw new Error(`catalog fetch -> ${res.status}`)\n const payload = (await res.json()) as {\n ok: boolean\n skins?: CatalogSkin[]\n diagnostics?: CatalogDiagnostic[]\n }\n catalog = payload.skins ?? []\n diagnostics = payload.diagnostics ?? []\n emit()\n }\n\n const store: SkinRuntimeStore = {\n controller,\n adapter,\n catalog: () => catalog,\n diagnostics: () => diagnostics,\n refreshCatalog,\n find(id) {\n return catalog?.find((s) => s.manifest.id === id) ?? null\n },\n subscribe(listener) {\n const off = controller.subscribe(listener)\n listeners.add(listener)\n return () => {\n off()\n listeners.delete(listener)\n }\n },\n shutdown() {\n adapter.stop()\n disposeShellRendering()\n controller.shutdown()\n },\n }\n\n // E2e/acceptance handle: exposes the boot store on the window for\n // scripted probes (see tests and the acceptance checklist).\n {\n const root = doc.defaultView as { __skinRuntime?: SkinRuntimeStore } & Window\n root.__skinRuntime = store\n }\n\n // Initial activation: apply the persisted selection from the snapshot.\n void (async () => {\n try {\n await refreshCatalog()\n let active = doc.documentElement?.getAttribute('data-dsh-skin') || null\n if (!active) {\n const res = await fetchImpl(`${apiBase}/active`)\n const payload = (await res.json()) as { ok: boolean; active?: string | null }\n active = payload.ok && typeof payload.active === 'string' ? payload.active : null\n }\n if (active === null) return\n let entry = store.find(active)\n if (entry === null) {\n const defaultEntry = store.find('blue-fantasy')\n if (defaultEntry !== null) {\n await controller.switchTo('blue-fantasy', defaultEntry as ControllerSkinEntry)\n } else {\n await controller.switchTo(null, null)\n }\n return\n }\n await controller.switchTo(active, entry as ControllerSkinEntry)\n } catch {\n // Fail-closed: boot into the stock look; the card surfaces catalog\n // errors through diagnostics().\n await controller.switchTo(null, null).catch(() => {})\n }\n })()\n\n if (typeof doc.defaultView !== 'undefined' && doc.defaultView !== null) {\n const win = doc.defaultView\n const onSkinApplied = (e: Event) => {\n const detail = (e as CustomEvent<{ id?: string }>).detail\n if (detail && typeof detail.id === 'string') {\n void refreshCatalog().then(async () => {\n const entry = store.find(detail.id!)\n if (entry !== null) {\n await controller.switchTo(detail.id!, entry as ControllerSkinEntry)\n }\n })\n }\n }\n win.addEventListener('dsh-skin-applied', onSkinApplied)\n listeners.add(() => win.removeEventListener('dsh-skin-applied', onSkinApplied))\n }\n\n return store\n}\n","/**\n * Serializes skin and wallpaper actions into one preview session.\n * A transition in one dimension fully retires the other dimension's preview\n * before it starts, so async skin switches cannot race wallpaper publishes.\n */\nexport interface PreviewSkinController {\n getState(): { previewing: boolean }\n exitTryOn(): Promise<string | null>\n}\n\nexport interface PreviewWallpaperController {\n trying(): boolean\n exitTryOn(): void\n}\n\nexport interface PreviewCustomThemeController {\n getState(): { previewing: boolean }\n exitTryOn(): void\n suspend(): void\n resume(): void\n}\n\nexport class PreviewCoordinator {\n private tail: Promise<void> = Promise.resolve()\n\n constructor(\n private readonly skin: PreviewSkinController,\n private readonly wallpaper: PreviewWallpaperController,\n private readonly customTheme?: PreviewCustomThemeController,\n ) {}\n\n runSkin<T>(action: () => Promise<T>): Promise<T> {\n return this.enqueue(async () => {\n if (this.wallpaper.trying()) this.wallpaper.exitTryOn()\n if (this.customTheme?.getState().previewing === true) this.customTheme.exitTryOn()\n this.customTheme?.suspend()\n try {\n return await action()\n } finally {\n if (!this.skin.getState().previewing) this.customTheme?.resume()\n }\n })\n }\n\n runWallpaper(action: () => void): Promise<void> {\n return this.enqueue(async () => {\n if (this.customTheme?.getState().previewing === true) this.customTheme.exitTryOn()\n if (this.skin.getState().previewing) await this.skin.exitTryOn()\n this.customTheme?.resume()\n action()\n })\n }\n\n runCustomTheme<T>(action: () => Promise<T>): Promise<T> {\n return this.enqueue(async () => {\n if (this.wallpaper.trying()) this.wallpaper.exitTryOn()\n const continuingCustomPreview = this.customTheme?.getState().previewing === true\n if (!continuingCustomPreview && this.skin.getState().previewing) await this.skin.exitTryOn()\n this.customTheme?.resume()\n return await action()\n })\n }\n\n private enqueue<T>(action: () => Promise<T>): Promise<T> {\n const run = this.tail.then(action, action)\n this.tail = run.then(() => undefined, () => undefined)\n return run\n }\n}\n","/** Versioned user theme derived from the official stock theme. */\n\nexport const SKIN_CUSTOM_THEME_NS = 'skin-custom-theme'\nexport const CUSTOM_THEME_VERSION = 1 as const\n\nexport interface CustomThemeProfile {\n accent: string\n background: string\n foreground: string\n contrast: number\n}\n\nexport interface CustomThemeConfig {\n version: number\n applied: boolean\n light: CustomThemeProfile\n dark: CustomThemeProfile\n}\n\nexport const CUSTOM_THEME_DEFAULTS: Readonly<CustomThemeConfig> = {\n version: CUSTOM_THEME_VERSION,\n applied: false,\n light: {\n accent: '#4d6bfe',\n background: '#f7f8fa',\n foreground: '#262626',\n contrast: 50,\n },\n dark: {\n accent: '#7c91ff',\n background: '#171719',\n foreground: '#f3f3f3',\n contrast: 50,\n },\n}\n\n/** The complete token surface this feature may emit. */\nexport const CUSTOM_THEME_ALLOWED_TOKENS = [\n '--dsw-alias-bg-base',\n '--dsw-alias-bg-layer-1',\n '--dsw-alias-bg-layer-2',\n '--dsw-alias-bg-layer-3',\n '--dsw-alias-bg-multi-select',\n '--dsw-alias-bg-overlay',\n '--dsw-alias-bg-skeleton',\n '--dsw-alias-border-l1',\n '--dsw-alias-border-l2',\n '--dsw-alias-border-l3',\n '--dsw-alias-border-l4',\n '--dsw-alias-brand-primary',\n '--dsw-alias-brand-primary-invert',\n '--dsw-alias-brand-text',\n '--dsw-alias-button-primary-dimmed',\n '--dsw-alias-button-primary-fill',\n '--dsw-alias-button-primary-hover',\n '--dsw-alias-interactive-bg-active',\n '--dsw-alias-interactive-bg-hover',\n '--dsw-alias-interactive-bg-hover-accent',\n '--dsw-alias-label-dimmed',\n '--dsw-alias-label-primary',\n '--dsw-alias-label-primary-foreground',\n '--dsw-alias-label-secondary',\n '--dsw-alias-label-tertiary',\n '--dsw-alias-markdown-code-block',\n '--dsw-alias-markdown-code-block-banner',\n '--dsw-alias-markdown-inline-code',\n '--dsw-alias-scrollbar-bg-l1',\n '--dsw-alias-scrollbar-hover-l1',\n '--dsw-alias-toast-bg',\n '--dsw-alias-tooltip-bg',\n '--dsw-specific-bubble',\n '--dsw-specific-bubble-highlight',\n '--dsw-specific-input-major',\n '--dsw-specific-menu',\n '--dsw-specific-selector',\n '--dsw-specific-sidebar-fill',\n '--dsw-specific-sidebar-nav-item-active',\n '--dsw-specific-sidebar-nav-item-active-accent',\n '--dsw-specific-sidebar-nav-item-hover',\n] as const\n\ntype UnknownRecord = Record<string, unknown>\n\nfunction record(value: unknown): UnknownRecord {\n return typeof value === 'object' && value !== null && !Array.isArray(value)\n ? value as UnknownRecord\n : {}\n}\n\nfunction color(value: unknown, fallback: string): string {\n return typeof value === 'string' && /^#[0-9a-f]{6}$/i.test(value)\n ? value.toLowerCase()\n : fallback\n}\n\nfunction contrast(value: unknown, fallback: number): number {\n if (typeof value !== 'number' || !Number.isFinite(value)) return fallback\n return Math.max(0, Math.min(100, Math.round(value)))\n}\n\nfunction normalizeProfile(value: unknown, fallback: Readonly<CustomThemeProfile>): CustomThemeProfile {\n const source = record(value)\n return {\n accent: color(source.accent, fallback.accent),\n background: color(source.background, fallback.background),\n foreground: color(source.foreground, fallback.foreground),\n contrast: contrast(source.contrast, fallback.contrast),\n }\n}\n\n/** Normalize untrusted settings data into the current contract version. */\nexport function normalizeCustomThemeConfig(value: unknown): CustomThemeConfig {\n const source = record(value)\n if (source.version !== undefined && source.version !== CUSTOM_THEME_VERSION) {\n return {\n version: CUSTOM_THEME_VERSION,\n applied: false,\n light: { ...CUSTOM_THEME_DEFAULTS.light },\n dark: { ...CUSTOM_THEME_DEFAULTS.dark },\n }\n }\n return {\n version: CUSTOM_THEME_VERSION,\n applied: source.applied === true,\n light: normalizeProfile(source.light, CUSTOM_THEME_DEFAULTS.light),\n dark: normalizeProfile(source.dark, CUSTOM_THEME_DEFAULTS.dark),\n }\n}\n\nfunction mix(a: string, aPercent: number, b: string): string {\n return `color-mix(in srgb, ${a} ${aPercent}%, ${b})`\n}\n\nfunction declarations(profile: CustomThemeProfile): Array<[typeof CUSTOM_THEME_ALLOWED_TOKENS[number], string]> {\n const { accent, background, foreground } = profile\n const depth1 = 2 + Math.round(profile.contrast * 0.12)\n const depth2 = depth1 + 4\n const depth3 = depth2 + 4\n const border = 12 + Math.round(profile.contrast * 0.18)\n const mutedText = 60 + Math.round(profile.contrast * 0.2)\n return [\n ['--dsw-alias-bg-base', background],\n ['--dsw-alias-bg-layer-1', mix(background, 100 - depth1, foreground)],\n ['--dsw-alias-bg-layer-2', mix(background, 100 - depth2, foreground)],\n ['--dsw-alias-bg-layer-3', mix(background, 100 - depth3, foreground)],\n ['--dsw-alias-bg-multi-select', mix(background, 84, accent)],\n ['--dsw-alias-bg-overlay', mix(background, 90 - Math.round(profile.contrast * 0.08), foreground)],\n ['--dsw-alias-bg-skeleton', mix(background, 82, foreground)],\n ['--dsw-alias-border-l1', mix(background, 100 - border, foreground)],\n ['--dsw-alias-border-l2', mix(background, 100 - Math.max(8, border - 5), foreground)],\n ['--dsw-alias-border-l3', mix(background, 100 - Math.max(5, border - 9), foreground)],\n ['--dsw-alias-border-l4', mix(background, 96, foreground)],\n ['--dsw-alias-brand-primary', accent],\n ['--dsw-alias-brand-primary-invert', background],\n ['--dsw-alias-brand-text', accent],\n ['--dsw-alias-button-primary-dimmed', mix(accent, 48, background)],\n ['--dsw-alias-button-primary-fill', accent],\n ['--dsw-alias-button-primary-hover', mix(accent, 82, foreground)],\n ['--dsw-alias-interactive-bg-active', mix(background, 78, accent)],\n ['--dsw-alias-interactive-bg-hover', mix(background, 100 - depth2, foreground)],\n ['--dsw-alias-interactive-bg-hover-accent', mix(background, 84, accent)],\n ['--dsw-alias-label-dimmed', mix(foreground, 42, background)],\n ['--dsw-alias-label-primary', foreground],\n ['--dsw-alias-label-primary-foreground', foreground],\n ['--dsw-alias-label-secondary', mix(foreground, mutedText, background)],\n ['--dsw-alias-label-tertiary', mix(foreground, Math.max(45, mutedText - 18), background)],\n ['--dsw-alias-markdown-code-block', mix(background, 100 - depth2, foreground)],\n ['--dsw-alias-markdown-code-block-banner', mix(background, 100 - depth3, foreground)],\n ['--dsw-alias-markdown-inline-code', mix(background, 86, accent)],\n ['--dsw-alias-scrollbar-bg-l1', mix(background, 94, foreground)],\n ['--dsw-alias-scrollbar-hover-l1', mix(background, 76, foreground)],\n ['--dsw-alias-toast-bg', mix(background, 100 - depth3, foreground)],\n ['--dsw-alias-tooltip-bg', mix(background, 28, foreground)],\n ['--dsw-specific-bubble', mix(background, 92, accent)],\n ['--dsw-specific-bubble-highlight', mix(background, 82, accent)],\n ['--dsw-specific-input-major', mix(background, 100 - depth1, foreground)],\n ['--dsw-specific-menu', mix(background, 100 - depth1, foreground)],\n ['--dsw-specific-selector', mix(background, 100 - depth2, foreground)],\n ['--dsw-specific-sidebar-fill', mix(background, 100 - depth1, foreground)],\n ['--dsw-specific-sidebar-nav-item-active', mix(background, 86, accent)],\n ['--dsw-specific-sidebar-nav-item-active-accent', accent],\n ['--dsw-specific-sidebar-nav-item-hover', mix(background, 100 - depth2, foreground)],\n ]\n}\n\nfunction block(selector: string, profile: CustomThemeProfile): string {\n const body = declarations(profile).map(([name, value]) => ` ${name}: ${value};`).join('\\n')\n return `${selector} {\\n${body}\\n}`\n}\n\n/** Build stock-only CSS from normalized, fixed token declarations. */\nexport function buildCustomThemeCss(value: unknown): string {\n const config = normalizeCustomThemeConfig(value)\n return [\n block('html[data-dsh-custom-theme]:not([data-dsh-skin]) body', config.light),\n block('html[data-dsh-custom-theme]:not([data-dsh-skin]) body[data-ds-dark-theme]', config.dark),\n ].join('\\n\\n')\n}\n","import type { SettingsScope } from '@deepseek-ai/dsh-client-ui-settings/client'\n\nimport {\n CUSTOM_THEME_DEFAULTS,\n buildCustomThemeCss,\n normalizeCustomThemeConfig,\n type CustomThemeConfig,\n type CustomThemeProfile,\n} from '../core/custom-theme.ts'\n\nexport type CustomThemeScheme = 'light' | 'dark'\n\nexport interface CustomThemeState {\n applied: boolean\n previewing: boolean\n visible: boolean\n writeError: string | null\n}\n\nexport interface CustomThemeControllerOptions {\n doc?: Document\n}\n\ntype CustomThemeField = keyof CustomThemeConfig & string\n\ninterface PendingWrite {\n field: CustomThemeField\n value: CustomThemeConfig[CustomThemeField]\n resolve(): void\n reject(error: unknown): void\n}\n\n/** Owns the custom-theme settings snapshot and its inert-by-default style. */\nexport class CustomThemeController {\n private readonly scope: SettingsScope<CustomThemeConfig>\n private readonly doc: Document\n private readonly style: HTMLStyleElement\n private readonly unsubscribe: () => void\n private readonly listeners = new Set<() => void>()\n private config: CustomThemeConfig\n private previewingValue = false\n private suspended = false\n private state: CustomThemeState\n private disposed = false\n private readonly writeQueue: PendingWrite[] = []\n private pendingWrites = 0\n private drainingWrites = false\n\n constructor(scope: SettingsScope<CustomThemeConfig>, options: CustomThemeControllerOptions = {}) {\n this.scope = scope\n this.doc = options.doc ?? document\n this.config = normalizeCustomThemeConfig(scope.getSnapshot().value)\n this.style = this.doc.createElement('style')\n this.style.dataset.dshCustomThemeStyle = ''\n this.doc.head.appendChild(this.style)\n this.state = { applied: this.config.applied, previewing: false, visible: false, writeError: null }\n this.syncDom()\n this.unsubscribe = scope.subscribe(() => {\n if (this.disposed || this.pendingWrites > 0) return\n this.syncFromScope()\n })\n }\n\n subscribe = (listener: () => void): (() => void) => {\n this.listeners.add(listener)\n return () => { this.listeners.delete(listener) }\n }\n\n getState = (): CustomThemeState => this.state\n\n profile(scheme: CustomThemeScheme): CustomThemeProfile {\n return { ...this.config[scheme] }\n }\n\n setProfileValue(\n scheme: CustomThemeScheme,\n key: keyof CustomThemeProfile,\n value: string | number,\n ): void {\n const next = normalizeCustomThemeConfig({\n ...this.config,\n [scheme]: { ...this.config[scheme], [key]: value },\n })\n this.config = next\n this.clearWriteError()\n this.syncDom()\n this.publish()\n void this.queueWrite(scheme, { ...next[scheme] }).catch(error => { this.setWriteError(error) })\n }\n\n reset(scheme: CustomThemeScheme): void {\n const profile = { ...CUSTOM_THEME_DEFAULTS[scheme] }\n this.config = { ...this.config, [scheme]: profile }\n this.clearWriteError()\n this.syncDom()\n this.publish()\n void this.queueWrite(scheme, profile).catch(error => { this.setWriteError(error) })\n }\n\n tryOn(): void {\n this.previewingValue = true\n this.suspended = false\n this.syncDom()\n this.publish()\n }\n\n exitTryOn(): void {\n this.previewingValue = false\n this.suspended = false\n this.syncDom()\n this.publish()\n }\n\n async apply(): Promise<void> {\n this.config = { ...this.config, applied: true }\n this.previewingValue = false\n this.suspended = false\n this.syncDom()\n this.publish()\n await this.queueWrite('applied', true)\n if (!this.config.applied) throw new Error('custom theme activation was not persisted')\n }\n\n async deactivate(): Promise<void> {\n this.config = { ...this.config, applied: false }\n this.previewingValue = false\n this.suspended = false\n this.syncDom()\n this.publish()\n await this.queueWrite('applied', false)\n if (this.config.applied) throw new Error('custom theme deactivation was not persisted')\n }\n\n suspend(): void {\n if (this.suspended) return\n this.suspended = true\n this.syncDom()\n this.publish()\n }\n\n resume(): void {\n if (!this.suspended) return\n this.suspended = false\n this.syncDom()\n this.publish()\n }\n\n dispose(): void {\n if (this.disposed) return\n this.disposed = true\n this.unsubscribe()\n this.listeners.clear()\n this.style.remove()\n this.doc.documentElement.removeAttribute('data-dsh-custom-theme')\n }\n\n private syncDom(): void {\n this.style.textContent = buildCustomThemeCss(this.config)\n const visible = (this.config.applied || this.previewingValue) && !this.suspended\n if (visible) this.doc.documentElement.setAttribute('data-dsh-custom-theme', 'true')\n else this.doc.documentElement.removeAttribute('data-dsh-custom-theme')\n this.state = {\n applied: this.config.applied,\n previewing: this.previewingValue,\n visible,\n writeError: this.state.writeError,\n }\n }\n\n private publish(): void {\n for (const listener of this.listeners) listener()\n }\n\n private syncFromScope(): void {\n this.config = normalizeCustomThemeConfig(this.scope.getSnapshot().value)\n this.syncDom()\n this.publish()\n }\n\n private clearWriteError(): void {\n if (this.state.writeError === null) return\n this.state = { ...this.state, writeError: null }\n }\n\n private setWriteError(error: unknown): void {\n this.state = {\n ...this.state,\n writeError: error instanceof Error ? error.message : String(error),\n }\n this.publish()\n }\n\n private queueWrite<K extends CustomThemeField>(field: K, value: CustomThemeConfig[K]): Promise<void> {\n this.pendingWrites += 1\n const pending = new Promise<void>((resolve, reject) => {\n this.writeQueue.push({\n field,\n value,\n resolve,\n reject,\n } as PendingWrite)\n })\n void this.drainWrites()\n return pending\n }\n\n private async drainWrites(): Promise<void> {\n if (this.drainingWrites) return\n this.drainingWrites = true\n const settled: Array<\n { write: PendingWrite; ok: true }\n | { write: PendingWrite; ok: false; error: unknown }\n > = []\n while (this.writeQueue.length > 0) {\n const write = this.writeQueue.shift()\n if (write === undefined) break\n try {\n await this.scope.set(write.field, write.value)\n } catch (error) {\n settled.push({ write, ok: false, error })\n continue\n } finally {\n this.pendingWrites -= 1\n }\n settled.push({ write, ok: true })\n }\n this.drainingWrites = false\n if (!this.disposed) this.syncFromScope()\n const failure = settled.find(result => !result.ok)\n if (!this.disposed && failure !== undefined && !failure.ok) {\n this.setWriteError(failure.error)\n }\n for (const result of settled) {\n if (result.ok) result.write.resolve()\n else result.write.reject(result.error)\n }\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 * In-GUI skin center, browser half: registers the Skin Center as a first-level\n * settings section (`settings.section`) and boots the v2 skin runtime\n * (effect ledger + atomic switch controller + semantic adapter + catalog\n * store). The section lists the installed skins (shipped built-ins +\n * $DSH_HOME/skins), tries them on live, and applies in one click — no reload,\n * no cordis.patch.yml rewrite (issue #506). The plugin writes only DOM and\n * the settings ledger — no services, no events, no model access.\n *\n * Background preferences persist through the v2 /active channel instead of\n * the settings scope (issue #996): the remote pairing channel fences\n * settings.* as loopback-only, so scope-backed writes never reached the\n * server from a paired desktop. The legacy skin-background scope is still\n * bound as a live input for the official settings page (loopback only);\n * card edits flow card -> POST /active, page edits flow scope -> POST\n * /active.\n */\nimport type { Context as ClientContext } from '@deepseek-ai/cordis'\nimport type { SettingsScope, SettingsScopeSpec } from '@deepseek-ai/dsh-client-ui-settings/client'\nimport type { ThemeRuntime } from '@deepseek-ai/dsh-client-ui-theme/client'\n// Type-only: pulls the locale plugin's Context merge (ctx.locale).\nimport type {} from '@deepseek-ai/dsh-client-locale/client'\n// Type-only: pulls the settings-surface Context merge (ctx.settingsScope).\nimport type {} from '@deepseek-ai/dsh-client-ui-settings/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'\n// Type-only: pulls the generated Remote namespace (ctx.remote), including directoryPicker.\nimport type {} from '@deepseek-ai/dsh-api-remotes/client'\nimport { SkinCenterSection, type SkinCenterInjected } from './SkinCenter.tsx'\nimport { BackgroundController, SKIN_BACKGROUND_NS } from './background.ts'\nimport type { SkinBackgroundConfig } from '../core/background.ts'\nimport { initialSkinBackgroundReconcileState, reconcileSkinBackgroundPublication } from '../core/background-scope.ts'\nimport { SKIN_WALLPAPER_NS, WallpaperController, installBootRestore } from './wallpaper.ts'\nimport { en, zh, type SkinCenterKey } from './locales.ts'\nimport { bootSkinRuntime } from './runtime/boot.ts'\nimport { PreviewCoordinator } from './preview-coordinator.ts'\nimport { CustomThemeController } from './custom-theme-controller.ts'\nimport { SKIN_CUSTOM_THEME_NS, type CustomThemeConfig } from '../core/custom-theme.ts'\nimport { reportDailyHeartbeat } from './telemetry.ts'\n\nexport type { SkinCenterComponentProps, SkinCenterInjected } from './SkinCenter.tsx'\nexport { bootSkinRuntime } from './runtime/boot.ts'\n\n/** Locale namespace owned by this plugin. */\nexport const NS = 'skinCenter'\n\ndeclare module '@deepseek-ai/dsh-client-ui-slots' {\n interface LocaleNamespaceMap {\n /** The skin-center card's copy. */\n skinCenter: SkinCenterKey\n }\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/** Required services: slots + locale (plugin card), theme (preview toggle), settingsScope + its transport (background scrim), and remote (wallpaper directory picker). */\nexport const inject = ['slots', 'locale', 'theme', 'settingsScope', 'connection', 'remote']\n\n/** Self-report item for the install heartbeat. */\nconst SELF_ITEM = [{ name: '@linxin666/dsh-client-ui-skin-center' }]\n\n/**\n * Beat the install heartbeat (docs/telemetry.md), enriching it with the\n * installed skin inventory (skin:<id> + version + channel) once the v2\n * catalog answers. Offline or pre-boot the beat stays package-only.\n */\nfunction beatHeartbeat(): void {\n reportDailyHeartbeat(SELF_ITEM)\n void fetch('/api/skin-center/v2/catalog')\n .then((res) => (res.ok ? res.json() : null))\n .then((catalog) => {\n if (!catalog || !Array.isArray(catalog.skins)) return\n const items = [...SELF_ITEM]\n for (const skin of catalog.skins) {\n const id = skin && skin.manifest && typeof skin.manifest.id === 'string' ? skin.manifest.id : ''\n if (!id) continue\n const item: { name: string; version?: string; channel?: 'market' | 'npm' | 'unknown' } = { name: 'skin:' + id }\n if (typeof skin.manifest.version === 'string') item.version = skin.manifest.version\n if (typeof skin.channel === 'string') item.channel = skin.channel\n items.push(item)\n }\n reportDailyHeartbeat(items.slice(0, 64))\n })\n .catch(() => { /* offline or fenced: the package-only beat already went out */ })\n}\n\n/**\n * Register the skin-center dictionaries, the body scope attribute, and the\n * Skin Center as a first-level settings section.\n * @param ctx - client root context.\n */\nexport function apply(ctx: ClientContext): void {\n // Anonymous install heartbeat (docs/telemetry.md): one beat per browser per\n // UTC day, package name plus installed-skin inventory, silent failure.\n beatHeartbeat()\n\n ctx.effect(() => {\n try {\n return ctx.locale.register(NS, { zh, en })\n } catch {\n return () => {}\n }\n }, 'ui-skin-center: dictionaries')\n\n // The card's own styles scope under this attribute so they keep applying\n // during try-on (when the active skin's attribute is retracted).\n ctx.effect(() => {\n document.body.dataset.dshSkinCenter = ''\n return () => { delete document.body.dataset.dshSkinCenter }\n }, 'ui-skin-center: body scope')\n\n const theme = ctx.get('theme') as ThemeRuntime\n const binder = ctx.get('webUiSettings') ?? ctx.settingsScope\n // The v2 state channel: GET backfills on boot, edits POST back debounced.\n // The remote proxy rewrites this path into the allow-listed channel, so it\n // works from paired desktops where the settings scope is fenced (#996).\n const V2_ACTIVE_URL = '/api/skin-center/v2/active'\n let persistTimer: ReturnType<typeof setTimeout> | null = null\n const postBackground = (next: SkinBackgroundConfig, keepalive = false): void => {\n void fetch(V2_ACTIVE_URL, {\n method: 'POST',\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify({ background: next }),\n keepalive,\n }).catch(() => { /* offline or pre-boot: the in-memory values stay applied */ })\n }\n // Coalesce slider drags into one write; dispose flushes the pending one.\n const persistBackground = (next: SkinBackgroundConfig): void => {\n if (persistTimer !== null) clearTimeout(persistTimer)\n persistTimer = setTimeout(() => {\n persistTimer = null\n postBackground(next)\n }, 250)\n }\n const flushBackground = (): void => {\n if (persistTimer === null) return\n clearTimeout(persistTimer)\n persistTimer = null\n postBackground(background.snapshot(), true)\n }\n // The legacy scope is an input face for the loopback settings page only.\n // Its resolved value contains schema defaults, so only the raw user layer may\n // be reconciled into the authoritative v2 state.\n const backgroundScope = binder.bind<SkinBackgroundConfig>({ namespace: SKIN_BACKGROUND_NS })\n const scopeConfig = (): SkinBackgroundConfig | null => {\n const value = backgroundScope.getSnapshot().value\n if (value === undefined || value === null) return null\n return value\n }\n const background = new BackgroundController(scopeConfig(), persistBackground)\n // Reconcile state for the legacy scope (revision + user-layer fence, plus\n // the boot-sync gate #1375): the settings document's initial sync must never\n // be mistaken for a settings-page edit, whichever order it and the v2 GET\n // land in — stale legacy user-layer fields (e.g. zeros left by the pre-#1107\n // bugs) would otherwise patch and persist over the authoritative v2 state.\n let reconcileState = initialSkinBackgroundReconcileState(backgroundScope.getSnapshot())\n const reconcileScope = (): void => {\n const result = reconcileSkinBackgroundPublication(\n reconcileState,\n background.snapshot(),\n backgroundScope.getSnapshot(),\n )\n reconcileState = result.state\n if (result.patch === null) return\n const currentSnapshot = background.snapshot()\n background.init({ ...currentSnapshot, ...result.patch })\n persistBackground(background.snapshot())\n }\n // Refetch the authoritative v2 state once booted; it wins over the scope\n // snapshot (the migration may only have run with this boot).\n void fetch(V2_ACTIVE_URL)\n .then((res) => (res.ok ? res.json() as Promise<{ background?: SkinBackgroundConfig | null }> : null))\n .then((body) => {\n reconcileState = { ...reconcileState, v2Loaded: true }\n if (body?.background) background.init(body.background)\n // Reconcile only a scope revision that changed while the v2 state was\n // loading; an unchanged revision is the legacy boot snapshot.\n reconcileScope()\n })\n .catch(() => {\n reconcileState = { ...reconcileState, v2Loaded: true }\n reconcileScope()\n })\n // Settings-page edits arrive through the scope publish. The settings mirror\n // may republish this namespace for an unrelated document change, so fence on\n // the namespace revision and use only explicitly stored user fields.\n ctx.effect(\n () => backgroundScope.subscribe(reconcileScope),\n 'ui-skin-center: background scope sync',\n )\n // Tear the blur element + observer down when this plugin's fiber goes away.\n ctx.effect(() => () => {\n flushBackground()\n background.dispose()\n }, 'ui-skin-center: background dispose')\n const customThemeScope = binder.bind<CustomThemeConfig>({ namespace: SKIN_CUSTOM_THEME_NS })\n const customTheme = new CustomThemeController(customThemeScope)\n ctx.effect(() => () => customTheme.dispose(), 'ui-skin-center: custom theme dispose')\n // The Wallpaper Engine bridge over the skin-wallpaper namespace.\n const wallpaperScope = binder.bind<{\n enabled?: boolean\n selection?: string\n mode?: 'live' | 'frame'\n pauseOnHidden?: boolean\n dim?: number\n wallpaperBlur?: number\n wallpaperOpacity?: number\n fit?: 'cover' | 'contain' | 'fill'\n }>({ namespace: SKIN_WALLPAPER_NS })\n const wallpaper = new WallpaperController(wallpaperScope)\n ctx.effect(() => () => wallpaper.dispose(), 'ui-skin-center: wallpaper dispose')\n // Mount the persisted wallpaper selection at boot (page load), so a\n // selection survives reloads without first opening the skin-center card.\n installBootRestore(wallpaper)\n\n // The v2 skin runtime store: outlives the settings card so a try-on\n // preview survives closing and reopening the panel. Background-media\n // priority: an active WE wallpaper suppresses skin manifest backgrounds;\n // toggling the wallpaper re-activates the current skin so the priority\n // flip paints immediately.\n const runtime = bootSkinRuntime({\n suppressBackgroundMedia: () => wallpaper.enabled() && wallpaper.isDisplaying(),\n })\n ctx.effect(() => () => runtime.shutdown(), 'ui-skin-center: runtime shutdown')\n ctx.effect(\n () => wallpaper.subscribe(() => { void runtime.controller.refresh() }),\n 'ui-skin-center: wallpaper priority refresh',\n )\n const preview = new PreviewCoordinator(runtime.controller, wallpaper, customTheme)\n ctx.effect(\n () => ctx.on('theme/change', () => wallpaper.recoverScenePlayer()),\n 'ui-skin-center: scene recovery after theme change',\n )\n const injected = (): SkinCenterInjected => ({\n runtime,\n preview,\n customTheme,\n theme: {\n getTheme: () => theme.getTheme(),\n subscribe: listener => ctx.on('theme/change', listener),\n setTheme: id => theme.setTheme(id),\n },\n background: {\n enabled: () => background.enabled(),\n setEnabled: value => background.setEnabled(value),\n opacity: () => background.opacity(),\n blurEmpty: () => background.blurEmpty(),\n blurContent: () => background.blurContent(),\n inputCardBlur: () => background.inputCardBlur(),\n bubbleOpacity: () => background.bubbleOpacity(),\n subscribe: listener => background.subscribe(listener),\n set: opacity => background.set(opacity),\n setBlurEmpty: value => background.setBlurEmpty(value),\n setBlurContent: value => background.setBlurContent(value),\n setInputCardBlur: value => background.setInputCardBlur(value),\n setBubbleOpacity: value => background.setBubbleOpacity(value),\n dispose: () => background.dispose(),\n },\n wallpaper: {\n enabled: () => wallpaper.enabled(),\n selection: () => wallpaper.selection(),\n mode: () => wallpaper.mode(),\n fit: () => wallpaper.fit(),\n dim: () => wallpaper.dim(),\n wallpaperBlur: () => wallpaper.wallpaperBlur(),\n wallpaperOpacity: () => wallpaper.wallpaperOpacity(),\n pauseOnHidden: () => wallpaper.pauseOnHidden(),\n sound: () => wallpaper.sound(),\n volume: () => wallpaper.volume(),\n dirs: () => wallpaper.dirs(),\n addDir: dir => wallpaper.addDir(dir),\n removeDir: dir => wallpaper.removeDir(dir),\n pickDir: async () => {\n const result = await ctx.remote.directoryPicker.pick()\n if (!result.ok) throw new Error(result.error.message)\n return result.value\n },\n activeId: () => wallpaper.activeId(),\n trying: () => wallpaper.trying(),\n subscribe: listener => wallpaper.subscribe(listener),\n setEnabled: value => wallpaper.setEnabled(value),\n setMode: value => wallpaper.setMode(value),\n setFit: fit => wallpaper.setFit(fit),\n setDim: value => wallpaper.setDim(value),\n setBlur: value => wallpaper.setBlur(value),\n setOpacity: value => wallpaper.setOpacity(value),\n setPauseOnHidden: value => wallpaper.setPauseOnHidden(value),\n setSound: value => wallpaper.setSound(value),\n setVolume: value => wallpaper.setVolume(value),\n applySelection: descriptor => { void preview.runWallpaper(() => wallpaper.applySelection(descriptor)) },\n clearSelection: () => wallpaper.clearSelection(),\n sync: descriptor => wallpaper.sync(descriptor),\n tryOn: descriptor => { void preview.runWallpaper(() => wallpaper.tryOn(descriptor)) },\n exitTryOn: () => wallpaper.exitTryOn(),\n recoverScenePlayer: () => wallpaper.recoverScenePlayer(),\n dispose: () => wallpaper.dispose(),\n },\n })\n\n // First-level settings section: the Skin Center card as its own top-level\n // settings page. Browsing and installing new skins happens in the DSH\n // Market store; this section manages the installed ones (try-on, apply,\n // wallpaper, custom theme).\n ctx.slots.inject('settings.section', () => {\n try {\n return ctx.slots.register({\n name: 'settings.section',\n id: 'skin-center',\n order: 120,\n label: () => ctx.locale.bind('skinCenter')('title'),\n locale: 'skinCenter',\n inject: injected,\n }, SkinCenterSection)\n } catch {\n return () => {}\n }\n })\n}\n"],"mappings":"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"}
|