@coderyo/ui-shell 1.1.0 → 1.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +20 -2
- package/dist/index.js +44 -1
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/top-bar.ts","../src/logo-slot.ts","../src/user-preferences.ts","../src/settings-panel.ts","../src/symbol-search-dialog.ts","../src/symbol-search.ts","../src/theme-toggle.ts","../src/theme-provider.ts","../src/i18n-provider.ts","../src/chart-layout.ts","../src/context-menu.ts","../src/crosshair-legend.ts","../src/drawing-properties-panel.ts","../src/indicator-pane-host.ts","../src/layout-schema.ts","../src/layout-engine.ts","../src/layer/compositor-shell.ts","../src/layer/compositor-shell-sync.ts","../src/layout-features.ts","../src/status-bar.ts","../src/shortcuts-modal.ts","../src/layer/types.ts","../src/layer/overlay-mount.ts","../src/layer/chart-pane-mount.ts","../src/layer/normalize.ts","../src/layer/grid-to-preset.ts","../src/layer/default-presets.ts","../src/layer/preset-store.ts","../src/layer/group-utils.ts","../src/layer/layer-controller.ts","../src/layer/layer-editor.ts","../src/layer/compositor.ts","../src/layer/layer-panel.ts","../src/layer/page-navigator.ts","../src/layer/bind-layer-time-scale-sync.ts","../src/layer/merge-preset.ts","../src/layer/resolve-pane-layers.ts","../src/drawing-context-menu.ts","../src/code-snippet-panel.ts","../src/pine-editor-panel.ts","../src/pine-language.ts"],"sourcesContent":["import { DEFAULT_INTERVALS, type Interval, type SymbolSearchHit } from '@coderyo/data';\nimport type { I18nProvider } from './i18n-provider.js';\nimport { mountLogoSlot, type LogoSlotOptions } from './logo-slot.js';\nimport { mountSettingsMenu, type SettingsMenuOptions } from './settings-menu.js';\nimport {\n createSymbolSearchDialog,\n mountSymbolSearchDialogTrigger,\n} from './symbol-search-dialog.js';\nimport { mountSymbolSearch } from './symbol-search.js';\nimport { mountThemeToggle } from './theme-toggle.js';\nimport type { ThemeProvider } from './theme-provider.js';\n\nexport type SymbolInputMode = 'manual' | 'search' | 'dialog' | 'none';\n\nexport interface TopBarOptions {\n intervals?: Interval[];\n /** Highlighted interval button (defaults to first in `intervals`). */\n activeInterval?: Interval;\n initialSymbol?: string;\n onSymbolSearch?: (query: string) => Promise<SymbolSearchHit[]>;\n onSymbolSelect?: (symbol: string) => void;\n onIntervalChange?: (interval: Interval) => void;\n onThemeToggle?: () => void;\n onThemeChange?: (theme: 'dark' | 'light') => void;\n themeProvider?: ThemeProvider;\n i18n?: I18nProvider;\n logo?: LogoSlotOptions | false;\n onFullscreen?: () => void;\n onScreenshot?: () => void;\n settings?: SettingsMenuOptions;\n symbolInput?: SymbolInputMode;\n showSettings?: boolean;\n}\n\nfunction mountManualSymbolInput(\n parent: HTMLElement,\n opts: {\n initialSymbol?: string;\n onSymbolSelect?: (symbol: string) => void;\n i18n?: I18nProvider;\n },\n): void {\n const wrap = document.createElement('div');\n wrap.style.cssText = 'display:flex;align-items:center;gap:4px;margin-right:8px;';\n const input = document.createElement('input');\n input.type = 'text';\n input.placeholder = opts.i18n?.t('symbol.search', 'Symbol') ?? 'Symbol';\n input.value = opts.initialSymbol ?? '';\n input.style.cssText =\n 'width:140px;background:#0d1117;color:#e6edf3;border:1px solid #30363d;border-radius:4px;padding:4px 8px;font-size:12px;';\n const apply = () => {\n const v = input.value.trim();\n if (v) opts.onSymbolSelect?.(v);\n };\n input.addEventListener('keydown', (e) => {\n if (e.key === 'Enter') apply();\n });\n const btn = document.createElement('button');\n btn.type = 'button';\n btn.textContent = '↵';\n btn.title = 'Apply symbol';\n btn.style.cssText =\n 'background:#21262d;color:#e6edf3;border:1px solid #30363d;border-radius:4px;padding:4px 8px;cursor:pointer;font-size:12px;';\n btn.onclick = apply;\n wrap.append(input, btn);\n parent.appendChild(wrap);\n}\n\nexport function mountTopBar(\n parent: HTMLElement,\n opts: TopBarOptions = {},\n): { el: HTMLElement; setActiveInterval: (interval: Interval) => void } {\n const i18n = opts.i18n;\n const tKey = (key: string, fallback: string) => i18n?.t(key, fallback) ?? fallback;\n\n const bar = document.createElement('div');\n bar.className = 'tv-topbar';\n bar.style.cssText =\n 'display:flex;gap:8px;padding:8px 12px;align-items:center;border-bottom:1px solid var(--tv-border,#30363d);background:var(--tv-surface,#161b22);flex-shrink:0;box-sizing:border-box;width:100%;min-width:0;overflow-x:auto;overflow-y:visible;position:relative;';\n\n if (opts.logo !== false) {\n mountLogoSlot(bar, opts.logo ?? { label: 'TradView' });\n }\n\n const symbolMode = opts.symbolInput ?? 'manual';\n if (symbolMode === 'search' && opts.onSymbolSearch && opts.onSymbolSelect) {\n mountSymbolSearch(bar, {\n initialSymbol: opts.initialSymbol,\n onSearch: opts.onSymbolSearch,\n onSelect: opts.onSymbolSelect,\n });\n } else if (symbolMode === 'dialog' && opts.onSymbolSearch && opts.onSymbolSelect) {\n const dialog = createSymbolSearchDialog({\n initialSymbol: opts.initialSymbol,\n onSearch: opts.onSymbolSearch,\n onSelect: opts.onSymbolSelect,\n i18n,\n });\n mountSymbolSearchDialogTrigger(bar, dialog, {\n initialSymbol: opts.initialSymbol,\n i18n,\n });\n } else if (symbolMode === 'manual' && opts.onSymbolSelect) {\n mountManualSymbolInput(bar, {\n initialSymbol: opts.initialSymbol,\n onSymbolSelect: opts.onSymbolSelect,\n i18n,\n });\n }\n\n const intervals = opts.intervals ?? DEFAULT_INTERVALS;\n const btnStyle =\n 'background:#21262d;color:#e6edf3;border:1px solid #30363d;border-radius:4px;padding:4px 10px;cursor:pointer;font-size:12px;flex-shrink:0;';\n const btnActiveStyle = btnStyle.replace('#21262d', '#388bfd').replace('#e6edf3', '#fff');\n const intervalButtons = new Map<Interval, HTMLButtonElement>();\n let activeInterval = opts.activeInterval ?? intervals[0];\n\n const intervalRow = document.createElement('div');\n intervalRow.className = 'tv-topbar-intervals';\n intervalRow.style.cssText = 'display:flex;gap:8px;flex-wrap:nowrap;align-items:center;flex-shrink:0;';\n\n const paintIntervalButtons = () => {\n for (const [iv, btn] of intervalButtons) {\n btn.style.cssText = iv === activeInterval ? btnActiveStyle : btnStyle;\n }\n };\n\n for (const iv of intervals) {\n const btn = document.createElement('button');\n btn.type = 'button';\n btn.textContent = tKey(`interval.${iv}`, iv);\n btn.style.cssText = btnStyle;\n btn.onclick = () => {\n if (activeInterval === iv) return;\n activeInterval = iv;\n paintIntervalButtons();\n opts.onIntervalChange?.(iv);\n };\n intervalButtons.set(iv, btn);\n intervalRow.appendChild(btn);\n }\n paintIntervalButtons();\n bar.appendChild(intervalRow);\n\n const spacer = document.createElement('div');\n spacer.style.flex = '1';\n bar.appendChild(spacer);\n\n const mkBtn = (label: string, fn?: () => void) => {\n const b = document.createElement('button');\n b.type = 'button';\n b.textContent = label;\n b.style.cssText =\n 'background:#21262d;color:#e6edf3;border:1px solid #30363d;border-radius:4px;padding:4px 10px;cursor:pointer;font-size:12px;';\n b.onclick = () => fn?.();\n return b;\n };\n\n if (opts.themeProvider) {\n mountThemeToggle(bar, {\n themeProvider: opts.themeProvider,\n i18n,\n onThemeChange: opts.onThemeChange,\n });\n } else {\n bar.appendChild(mkBtn(tKey('theme.dark', '主題'), opts.onThemeToggle));\n }\n if (opts.showSettings && opts.settings) mountSettingsMenu(bar, opts.settings);\n bar.appendChild(mkBtn('⛶', opts.onFullscreen));\n bar.appendChild(mkBtn('📷', opts.onScreenshot));\n\n parent.appendChild(bar);\n return {\n el: bar,\n setActiveInterval: (interval) => {\n if (!intervalButtons.has(interval)) return;\n activeInterval = interval;\n paintIntervalButtons();\n },\n };\n}","export interface LogoSlotOptions {\n label?: string;\n href?: string;\n imageSrc?: string;\n}\n\nexport function mountLogoSlot(parent: HTMLElement, opts: LogoSlotOptions = {}): HTMLElement {\n const slot = document.createElement('div');\n slot.className = 'tv-logo-slot';\n slot.style.cssText =\n 'display:flex;align-items:center;gap:8px;margin-right:12px;flex-shrink:0;font-weight:600;font-size:13px;color:var(--tv-fg,#e6edf3);';\n\n const label = opts.label ?? 'TradView';\n const text = document.createElement('span');\n text.textContent = label;\n\n const children: HTMLElement[] = [];\n if (opts.imageSrc) {\n const img = document.createElement('img');\n img.src = opts.imageSrc;\n img.alt = label;\n img.style.cssText = 'height:22px;width:auto;display:block;';\n children.push(img);\n }\n children.push(text);\n\n if (opts.href) {\n const link = document.createElement('a');\n link.href = opts.href;\n link.style.cssText = 'color:inherit;text-decoration:none;display:flex;align-items:center;gap:8px;';\n link.append(...children);\n slot.appendChild(link);\n } else {\n slot.append(...children);\n }\n\n parent.appendChild(slot);\n return slot;\n}","import type { IndicatorConfig } from '@coderyo/indicators';\nimport {\n defaultChartStorage,\n loadIndicatorConfig as loadIndicatorConfigFromCore,\n saveIndicatorConfig as saveIndicatorConfigToCore,\n} from '@coderyo/core';\n\nexport const GRID_SETTING_KEY = 'tradview:settings:showGrid';\nexport const RETURN_CURSOR_KEY = 'tradview:settings:returnToCursorAfterDraw';\n\nexport function loadShowGridPreference(): boolean {\n try {\n return localStorage.getItem(GRID_SETTING_KEY) === '1';\n } catch {\n return false;\n }\n}\n\nexport function saveShowGridPreference(show: boolean): void {\n try {\n localStorage.setItem(GRID_SETTING_KEY, show ? '1' : '0');\n } catch {\n /* ignore */\n }\n}\n\nexport function loadReturnToCursorPreference(): boolean {\n try {\n return localStorage.getItem(RETURN_CURSOR_KEY) === '1';\n } catch {\n return false;\n }\n}\n\nexport function saveReturnToCursorPreference(v: boolean): void {\n try {\n localStorage.setItem(RETURN_CURSOR_KEY, v ? '1' : '0');\n } catch {\n /* ignore */\n }\n}\n\n/** @deprecated Prefer `@coderyo/core` `loadIndicatorConfig(storage, …)` when not using ui-shell. */\nexport function loadIndicatorConfig(symbol: string, interval: string): IndicatorConfig {\n return loadIndicatorConfigFromCore(defaultChartStorage, symbol, interval);\n}\n\n/** @deprecated Prefer `@coderyo/core` `saveIndicatorConfig(storage, …)` when not using ui-shell. */\nexport function saveIndicatorConfig(\n symbol: string,\n interval: string,\n config: IndicatorConfig,\n): void {\n saveIndicatorConfigToCore(defaultChartStorage, symbol, interval, config);\n}","import {\n DEFAULT_INDICATOR_CONFIG,\n disableIndicatorLayer,\n listActiveIndicatorLayers,\n type IndicatorConfig,\n type IndicatorLayerId,\n} from '@coderyo/indicators';\nimport { t } from '@coderyo/i18n';\nimport {\n loadReturnToCursorPreference,\n loadShowGridPreference,\n saveReturnToCursorPreference,\n saveShowGridPreference,\n} from './user-preferences.js';\n\nexport interface SettingsPanelOptions {\n showGrid?: boolean;\n onShowGridChange?: (show: boolean) => void;\n returnToCursorAfterDraw?: boolean;\n onReturnToCursorChange?: (v: boolean) => void;\n indicatorConfig?: IndicatorConfig;\n onIndicatorConfigChange?: (config: IndicatorConfig) => void;\n onClearAllIndicators?: () => void;\n onClearAllDrawings?: () => void;\n}\n\nexport function mountSettingsPanel(parent: HTMLElement, opts: SettingsPanelOptions = {}): HTMLElement {\n let open = false;\n let tab: 'chart' | 'drawing' | 'indicator' = 'chart';\n let showGrid = opts.showGrid ?? loadShowGridPreference();\n let returnToCursor = opts.returnToCursorAfterDraw ?? loadReturnToCursorPreference();\n let indicatorConfig = { ...(opts.indicatorConfig ?? DEFAULT_INDICATOR_CONFIG) };\n\n const wrap = document.createElement('div');\n wrap.style.cssText = 'position:relative;';\n\n const btn = document.createElement('button');\n btn.type = 'button';\n btn.title = t('settings.title', '設定');\n btn.textContent = '⚙';\n btn.style.cssText =\n 'background:#21262d;color:#e6edf3;border:1px solid #30363d;border-radius:4px;padding:4px 10px;cursor:pointer;font-size:14px;';\n\n const overlay = document.createElement('div');\n overlay.style.cssText =\n 'display:none;position:fixed;inset:0;z-index:2000;background:#01040999;align-items:center;justify-content:center;padding:16px;box-sizing:border-box;';\n\n const dialog = document.createElement('div');\n dialog.setAttribute('role', 'dialog');\n dialog.setAttribute('aria-modal', 'true');\n dialog.style.cssText =\n 'width:min(420px,100%);max-height:min(85vh,640px);display:flex;flex-direction:column;background:#161b22;border:1px solid #30363d;border-radius:8px;box-shadow:0 16px 48px #010409cc;overflow:hidden;';\n\n const header = document.createElement('div');\n header.style.cssText =\n 'display:flex;align-items:center;justify-content:space-between;padding:10px 12px;border-bottom:1px solid #30363d;';\n const title = document.createElement('span');\n title.textContent = t('settings.title', '設定');\n title.style.cssText = 'font-size:14px;font-weight:600;color:#e6edf3;';\n const closeBtn = document.createElement('button');\n closeBtn.type = 'button';\n closeBtn.textContent = '×';\n closeBtn.title = t('settings.close', '關閉');\n closeBtn.style.cssText =\n 'background:transparent;border:none;color:#8b949e;font-size:20px;line-height:1;cursor:pointer;padding:0 4px;';\n header.append(title, closeBtn);\n\n const tabs = document.createElement('div');\n tabs.style.cssText = 'display:flex;border-bottom:1px solid #30363d;flex-shrink:0;';\n const content = document.createElement('div');\n content.style.cssText = 'padding:10px 12px;font-size:12px;overflow:auto;flex:1;min-height:0;';\n\n const tabIds = [\n ['chart', t('settings.tab.chart', '圖表')],\n ['drawing', t('settings.tab.drawing', '繪圖')],\n ['indicator', t('settings.tab.indicator', '指標')],\n ] as const;\n\n const renderTabs = () => {\n tabs.replaceChildren();\n for (const [id, label] of tabIds) {\n const b = document.createElement('button');\n b.type = 'button';\n b.textContent = label;\n b.style.cssText = `flex:1;padding:8px;border:none;cursor:pointer;font-size:12px;${\n tab === id ? 'background:#21262d;color:#e6edf3;' : 'background:transparent;color:#8b949e;'\n }`;\n b.onclick = (e) => {\n e.stopPropagation();\n tab = id;\n renderTabs();\n renderContent();\n };\n tabs.appendChild(b);\n }\n };\n\n const checkbox = (label: string, checked: boolean, onChange: (v: boolean) => void) => {\n const row = document.createElement('label');\n row.style.cssText =\n 'display:flex;align-items:center;gap:8px;margin-bottom:8px;cursor:pointer;color:#e6edf3;';\n const input = document.createElement('input');\n input.type = 'checkbox';\n input.checked = checked;\n input.onchange = () => onChange(input.checked);\n row.append(input, document.createTextNode(label));\n return row;\n };\n\n const actionButton = (label: string, onClick: () => void, danger = true) => {\n const b = document.createElement('button');\n b.type = 'button';\n b.textContent = label;\n b.style.cssText = `display:block;width:100%;margin-top:10px;padding:6px 10px;border-radius:4px;border:1px solid ${\n danger ? '#f85149' : '#30363d'\n };background:#21262d;color:${danger ? '#f85149' : '#e6edf3'};cursor:pointer;font-size:12px;`;\n b.onclick = (e) => {\n e.stopPropagation();\n onClick();\n };\n return b;\n };\n\n const numberField = (label: string, value: number, onChange: (n: number) => void) => {\n const row = document.createElement('label');\n row.style.cssText = 'display:flex;justify-content:space-between;align-items:center;margin-bottom:6px;';\n row.innerHTML = `<span style=\"color:#8b949e\">${label}</span>`;\n const input = document.createElement('input');\n input.type = 'number';\n input.value = String(value);\n input.style.cssText =\n 'width:72px;padding:2px 6px;border-radius:4px;border:1px solid #30363d;background:#0d1117;color:#e6edf3;';\n input.onchange = () => onChange(Number(input.value) || value);\n row.appendChild(input);\n return row;\n };\n\n const renderLayerList = () => {\n const layers = listActiveIndicatorLayers(indicatorConfig);\n const section = document.createElement('div');\n section.style.marginBottom = '12px';\n const heading = document.createElement('div');\n heading.textContent = t('settings.ind.layers', '指標圖層');\n heading.style.cssText = 'font-weight:600;color:#e6edf3;margin-bottom:6px;font-size:12px;';\n section.appendChild(heading);\n if (layers.length === 0) {\n const empty = document.createElement('div');\n empty.textContent = t('settings.ind.layersEmpty', '目前沒有指標');\n empty.style.cssText = 'color:#8b949e;font-size:11px;';\n section.appendChild(empty);\n return section;\n }\n for (const layer of layers) {\n const row = document.createElement('div');\n row.style.cssText =\n 'display:flex;align-items:center;justify-content:space-between;gap:8px;padding:6px 8px;margin-bottom:4px;border-radius:4px;background:#0d1117;border:1px solid #30363d;';\n const meta = document.createElement('div');\n meta.style.cssText = 'min-width:0;';\n const name = document.createElement('div');\n name.textContent = layer.label;\n name.style.cssText = 'color:#e6edf3;font-size:12px;';\n const target = document.createElement('div');\n target.textContent =\n layer.target === 'main'\n ? t('settings.ind.layerMain', '主圖')\n : t('settings.ind.layerPane', '副圖');\n target.style.cssText = 'color:#8b949e;font-size:10px;margin-top:2px;';\n meta.append(name, target);\n const remove = document.createElement('button');\n remove.type = 'button';\n remove.textContent = t('settings.ind.layerRemove', '移除');\n remove.title = t('settings.ind.layerRemove', '移除');\n remove.style.cssText =\n 'flex-shrink:0;padding:2px 8px;border-radius:4px;border:1px solid #f85149;background:transparent;color:#f85149;cursor:pointer;font-size:11px;';\n remove.onclick = (e) => {\n e.stopPropagation();\n indicatorConfig = disableIndicatorLayer(indicatorConfig, layer.id as IndicatorLayerId);\n opts.onIndicatorConfigChange?.(indicatorConfig);\n renderContent();\n };\n row.append(meta, remove);\n section.appendChild(row);\n }\n return section;\n };\n\n const renderContent = () => {\n content.replaceChildren();\n if (tab === 'chart') {\n content.appendChild(\n checkbox(t('settings.showGrid', '顯示網格'), showGrid, (v) => {\n showGrid = v;\n saveShowGridPreference(v);\n opts.onShowGridChange?.(v);\n }),\n );\n } else if (tab === 'drawing') {\n content.appendChild(\n checkbox(t('settings.returnCursor', '畫完切回游標'), returnToCursor, (v) => {\n returnToCursor = v;\n saveReturnToCursorPreference(v);\n opts.onReturnToCursorChange?.(v);\n }),\n );\n content.appendChild(\n actionButton(t('settings.drawing.clearAll', '清除所有畫線'), () => {\n opts.onClearAllDrawings?.();\n renderContent();\n }),\n );\n } else {\n content.appendChild(renderLayerList());\n content.appendChild(\n checkbox(t('settings.ind.volume', '成交量副圖'), indicatorConfig.showVolume, (v) => {\n indicatorConfig = { ...indicatorConfig, showVolume: v };\n opts.onIndicatorConfigChange?.(indicatorConfig);\n renderContent();\n }),\n );\n const divider = document.createElement('div');\n divider.style.cssText = 'height:1px;background:#30363d;margin:10px 0;';\n content.appendChild(divider);\n content.appendChild(\n checkbox(t('settings.ind.macd', 'MACD 窗格'), indicatorConfig.showMacd, (v) => {\n indicatorConfig = { ...indicatorConfig, showMacd: v };\n opts.onIndicatorConfigChange?.(indicatorConfig);\n renderContent();\n }),\n );\n content.appendChild(\n checkbox(t('settings.ind.rsi', 'RSI 窗格'), indicatorConfig.showRsi, (v) => {\n indicatorConfig = { ...indicatorConfig, showRsi: v };\n opts.onIndicatorConfigChange?.(indicatorConfig);\n renderContent();\n }),\n );\n content.appendChild(\n checkbox(t('settings.ind.kdj', 'KDJ 窗格'), indicatorConfig.showKdj, (v) => {\n indicatorConfig = { ...indicatorConfig, showKdj: v };\n opts.onIndicatorConfigChange?.(indicatorConfig);\n renderContent();\n }),\n );\n const src = document.createElement('label');\n src.style.cssText = 'display:flex;justify-content:space-between;margin:8px 0 6px;';\n src.innerHTML = `<span style=\"color:#8b949e\">${t('settings.ind.source', '源')}</span>`;\n const sel = document.createElement('select');\n sel.style.cssText =\n 'background:#0d1117;color:#e6edf3;border:1px solid #30363d;border-radius:4px;padding:2px 6px;';\n for (const v of ['close', 'hlc3'] as const) {\n const o = document.createElement('option');\n o.value = v;\n o.textContent = v;\n sel.appendChild(o);\n }\n sel.value = indicatorConfig.source;\n sel.onchange = () => {\n indicatorConfig = { ...indicatorConfig, source: sel.value as IndicatorConfig['source'] };\n opts.onIndicatorConfigChange?.(indicatorConfig);\n };\n src.appendChild(sel);\n content.appendChild(src);\n content.appendChild(\n checkbox(t('settings.ind.ema', 'EMA 疊加'), indicatorConfig.showEma, (v) => {\n indicatorConfig = { ...indicatorConfig, showEma: v };\n opts.onIndicatorConfigChange?.(indicatorConfig);\n renderContent();\n }),\n );\n content.appendChild(\n numberField('EMA', indicatorConfig.emaPeriod, (n) => {\n indicatorConfig = { ...indicatorConfig, emaPeriod: n };\n opts.onIndicatorConfigChange?.(indicatorConfig);\n }),\n );\n content.appendChild(\n checkbox(t('settings.ind.boll', 'BOLL 通道'), indicatorConfig.showBoll, (v) => {\n indicatorConfig = { ...indicatorConfig, showBoll: v };\n opts.onIndicatorConfigChange?.(indicatorConfig);\n renderContent();\n }),\n );\n content.appendChild(\n numberField('BOLL', indicatorConfig.bollPeriod, (n) => {\n indicatorConfig = { ...indicatorConfig, bollPeriod: n };\n opts.onIndicatorConfigChange?.(indicatorConfig);\n }),\n );\n content.appendChild(\n numberField('MA', indicatorConfig.maPeriod, (n) => {\n indicatorConfig = { ...indicatorConfig, maPeriod: n };\n opts.onIndicatorConfigChange?.(indicatorConfig);\n }),\n );\n content.appendChild(\n numberField('MACD fast', indicatorConfig.macdFast, (n) => {\n indicatorConfig = { ...indicatorConfig, macdFast: n };\n opts.onIndicatorConfigChange?.(indicatorConfig);\n }),\n );\n content.appendChild(\n numberField('MACD slow', indicatorConfig.macdSlow, (n) => {\n indicatorConfig = { ...indicatorConfig, macdSlow: n };\n opts.onIndicatorConfigChange?.(indicatorConfig);\n }),\n );\n content.appendChild(\n numberField('RSI', indicatorConfig.rsiPeriod, (n) => {\n indicatorConfig = { ...indicatorConfig, rsiPeriod: n };\n opts.onIndicatorConfigChange?.(indicatorConfig);\n }),\n );\n content.appendChild(\n numberField('KDJ', indicatorConfig.kdjPeriod, (n) => {\n indicatorConfig = { ...indicatorConfig, kdjPeriod: n };\n opts.onIndicatorConfigChange?.(indicatorConfig);\n }),\n );\n content.appendChild(\n actionButton(t('settings.ind.clearAll', '清空所有指標'), () => {\n opts.onClearAllIndicators?.();\n if (opts.indicatorConfig) indicatorConfig = { ...opts.indicatorConfig };\n renderContent();\n }),\n );\n }\n };\n\n const setOpen = (next: boolean) => {\n open = next;\n overlay.style.display = open ? 'flex' : 'none';\n if (open) {\n if (opts.indicatorConfig) indicatorConfig = { ...opts.indicatorConfig };\n renderContent();\n }\n };\n\n renderTabs();\n renderContent();\n dialog.append(header, tabs, content);\n overlay.appendChild(dialog);\n document.body.appendChild(overlay);\n\n btn.onclick = (e) => {\n e.stopPropagation();\n setOpen(!open);\n };\n closeBtn.onclick = (e) => {\n e.stopPropagation();\n setOpen(false);\n };\n overlay.onclick = () => setOpen(false);\n dialog.onclick = (e) => e.stopPropagation();\n\n const onKey = (e: KeyboardEvent) => {\n if (e.key === 'Escape' && open) setOpen(false);\n };\n document.addEventListener('keydown', onKey);\n\n wrap.append(btn);\n parent.appendChild(wrap);\n\n const origRemove = wrap.remove.bind(wrap);\n wrap.remove = () => {\n document.removeEventListener('keydown', onKey);\n overlay.remove();\n origRemove();\n };\n\n return wrap;\n}","import type { SymbolSearchHit } from '@coderyo/data';\nimport type { I18nProvider } from './i18n-provider.js';\n\nexport interface SymbolSearchDialogOptions {\n onSearch: (query: string) => Promise<SymbolSearchHit[]>;\n onSelect: (symbol: string) => void;\n initialSymbol?: string;\n i18n?: I18nProvider;\n}\n\nexport interface SymbolSearchDialogHandle {\n open(): void;\n close(): void;\n destroy(): void;\n}\n\nexport function createSymbolSearchDialog(opts: SymbolSearchDialogOptions): SymbolSearchDialogHandle {\n const i18n = opts.i18n;\n const backdrop = document.createElement('div');\n backdrop.className = 'tv-symbol-dialog-backdrop';\n backdrop.style.cssText =\n 'display:none;position:fixed;inset:0;z-index:1000;background:rgba(0,0,0,0.55);align-items:flex-start;justify-content:center;padding:12vh 16px 16px;';\n\n const panel = document.createElement('div');\n panel.className = 'tv-symbol-dialog';\n panel.style.cssText =\n 'width:min(420px,100%);background:var(--tv-surface,#161b22);border:1px solid var(--tv-border,#30363d);border-radius:8px;padding:12px;box-shadow:0 8px 24px rgba(0,0,0,0.4);';\n\n const title = document.createElement('div');\n title.textContent = i18n?.t('symbol.search', '搜尋商品') ?? '搜尋商品';\n title.style.cssText = 'font-size:13px;font-weight:600;color:var(--tv-fg,#e6edf3);margin-bottom:8px;';\n\n const input = document.createElement('input');\n input.type = 'search';\n input.placeholder = i18n?.t('symbol.search', '搜尋商品') ?? '搜尋商品';\n input.value = opts.initialSymbol ?? '';\n input.style.cssText =\n 'width:100%;box-sizing:border-box;padding:8px 10px;border-radius:4px;border:1px solid var(--tv-border,#30363d);background:var(--tv-bg,#0d1117);color:var(--tv-fg,#e6edf3);font-size:13px;';\n\n const list = document.createElement('div');\n list.style.cssText = 'margin-top:8px;max-height:240px;overflow:auto;';\n\n panel.append(title, input, list);\n backdrop.appendChild(panel);\n\n let timer: ReturnType<typeof setTimeout> | undefined;\n let mounted = false;\n\n const renderHits = (hits: SymbolSearchHit[]) => {\n list.replaceChildren();\n if (hits.length === 0) {\n const empty = document.createElement('div');\n empty.textContent = '—';\n empty.style.cssText = 'padding:8px;color:var(--tv-muted,#8b949e);font-size:12px;';\n list.appendChild(empty);\n return;\n }\n for (const hit of hits) {\n const row = document.createElement('button');\n row.type = 'button';\n row.textContent = hit.exchange ? `${hit.symbol} · ${hit.exchange}` : hit.symbol;\n row.style.cssText =\n 'display:block;width:100%;text-align:left;padding:8px 10px;border:none;background:transparent;color:var(--tv-fg,#e6edf3);cursor:pointer;font-size:12px;border-radius:4px;';\n row.onmouseenter = () => {\n row.style.background = 'var(--tv-btn-bg,#21262d)';\n };\n row.onmouseleave = () => {\n row.style.background = 'transparent';\n };\n row.onclick = () => {\n opts.onSelect(hit.symbol);\n close();\n };\n list.appendChild(row);\n }\n };\n\n const runSearch = () => {\n const q = input.value.trim();\n if (q.length < 1) {\n list.replaceChildren();\n return;\n }\n void opts.onSearch(q).then(renderHits).catch(() => list.replaceChildren());\n };\n\n input.addEventListener('input', () => {\n clearTimeout(timer);\n timer = setTimeout(runSearch, 200);\n });\n\n input.addEventListener('keydown', (e) => {\n if (e.key === 'Escape') close();\n if (e.key === 'Enter') runSearch();\n });\n\n backdrop.addEventListener('click', (e) => {\n if (e.target === backdrop) close();\n });\n\n const open = () => {\n if (!mounted) {\n document.body.appendChild(backdrop);\n mounted = true;\n }\n backdrop.style.display = 'flex';\n input.focus();\n input.select();\n runSearch();\n };\n\n const close = () => {\n backdrop.style.display = 'none';\n };\n\n const destroy = () => {\n clearTimeout(timer);\n backdrop.remove();\n mounted = false;\n };\n\n return { open, close, destroy };\n}\n\n/** TopBar trigger: shows current symbol and opens the dialog. */\nexport function mountSymbolSearchDialogTrigger(\n parent: HTMLElement,\n dialog: SymbolSearchDialogHandle,\n opts: { initialSymbol?: string; i18n?: I18nProvider },\n): HTMLElement {\n const wrap = document.createElement('div');\n wrap.style.cssText = 'display:flex;align-items:center;margin-right:8px;flex-shrink:0;';\n\n const btn = document.createElement('button');\n btn.type = 'button';\n btn.textContent = opts.initialSymbol ?? (opts.i18n?.t('symbol.search', '搜尋商品') ?? '搜尋商品');\n btn.style.cssText =\n 'min-width:140px;text-align:left;background:var(--tv-bg,#0d1117);color:var(--tv-fg,#e6edf3);border:1px solid var(--tv-border,#30363d);border-radius:4px;padding:4px 10px;cursor:pointer;font-size:12px;';\n btn.onclick = () => dialog.open();\n\n wrap.appendChild(btn);\n parent.appendChild(wrap);\n return wrap;\n}","import type { SymbolSearchHit } from '@coderyo/data';\nimport { t } from '@coderyo/i18n';\n\nexport interface SymbolSearchOptions {\n onSearch: (query: string) => Promise<SymbolSearchHit[]>;\n onSelect: (symbol: string) => void;\n initialSymbol?: string;\n}\n\nexport function mountSymbolSearch(parent: HTMLElement, opts: SymbolSearchOptions): HTMLElement {\n const wrap = document.createElement('div');\n wrap.style.cssText = 'display:flex;align-items:center;gap:6px;margin-right:8px;';\n\n const input = document.createElement('input');\n input.type = 'search';\n input.placeholder = t('symbol.search', '搜尋商品');\n input.value = opts.initialSymbol ?? '';\n input.style.cssText =\n 'width:140px;padding:4px 8px;border-radius:4px;border:1px solid #30363d;background:#0d1117;color:#e6edf3;font-size:12px;';\n\n const list = document.createElement('div');\n list.style.cssText =\n 'display:none;position:absolute;top:100%;left:0;z-index:20;min-width:200px;max-height:200px;overflow:auto;background:#161b22;border:1px solid #30363d;border-radius:4px;';\n\n const box = document.createElement('div');\n box.style.position = 'relative';\n box.append(input, list);\n wrap.appendChild(box);\n\n let timer: ReturnType<typeof setTimeout> | undefined;\n\n const renderHits = (hits: SymbolSearchHit[]) => {\n list.replaceChildren();\n if (hits.length === 0) {\n list.style.display = 'none';\n return;\n }\n for (const hit of hits) {\n const row = document.createElement('button');\n row.type = 'button';\n row.textContent = hit.exchange ? `${hit.symbol} · ${hit.exchange}` : hit.symbol;\n row.style.cssText =\n 'display:block;width:100%;text-align:left;padding:6px 10px;border:none;background:transparent;color:#e6edf3;cursor:pointer;font-size:12px;';\n row.onmouseenter = () => {\n row.style.background = '#21262d';\n };\n row.onmouseleave = () => {\n row.style.background = 'transparent';\n };\n row.onclick = () => {\n input.value = hit.symbol;\n list.style.display = 'none';\n opts.onSelect(hit.symbol);\n };\n list.appendChild(row);\n }\n list.style.display = 'block';\n };\n\n input.addEventListener('input', () => {\n clearTimeout(timer);\n const q = input.value.trim();\n if (q.length < 1) {\n list.style.display = 'none';\n return;\n }\n timer = setTimeout(() => {\n void opts.onSearch(q).then(renderHits).catch(() => {\n list.style.display = 'none';\n });\n }, 200);\n });\n\n document.addEventListener('click', (e) => {\n if (!box.contains(e.target as Node)) list.style.display = 'none';\n });\n\n parent.appendChild(wrap);\n return wrap;\n}","import type { I18nProvider } from './i18n-provider.js';\nimport type { ThemeId, ThemeProvider } from './theme-provider.js';\n\nexport interface ThemeToggleOptions {\n themeProvider: ThemeProvider;\n i18n?: I18nProvider;\n onThemeChange?: (theme: ThemeId) => void;\n}\n\nexport function mountThemeToggle(parent: HTMLElement, opts: ThemeToggleOptions): HTMLButtonElement {\n const i18n = opts.i18n;\n const btn = document.createElement('button');\n btn.type = 'button';\n btn.className = 'tv-theme-toggle';\n btn.style.cssText =\n 'background:var(--tv-btn-bg,#21262d);color:var(--tv-fg,#e6edf3);border:1px solid var(--tv-border,#30363d);border-radius:4px;padding:4px 10px;cursor:pointer;font-size:12px;flex-shrink:0;';\n\n const paint = (theme: ThemeId) => {\n btn.textContent =\n theme === 'dark'\n ? (i18n?.t('theme.dark', '深色') ?? '深色')\n : (i18n?.t('theme.light', '淺色') ?? '淺色');\n };\n\n btn.onclick = () => {\n const next = opts.themeProvider.toggle();\n opts.onThemeChange?.(next);\n };\n\n opts.themeProvider.subscribe((theme) => paint(theme));\n parent.appendChild(btn);\n return btn;\n}","export type ThemeId = 'dark' | 'light';\n\nexport const THEME_STORAGE_KEY = 'tradview:theme';\n\nconst THEME_VARS: Record<ThemeId, Record<string, string>> = {\n dark: {\n '--tv-bg': '#0d1117',\n '--tv-surface': '#161b22',\n '--tv-border': '#30363d',\n '--tv-fg': '#e6edf3',\n '--tv-muted': '#8b949e',\n '--tv-accent': '#388bfd',\n '--tv-btn-bg': '#21262d',\n },\n light: {\n '--tv-bg': '#ffffff',\n '--tv-surface': '#f6f8fa',\n '--tv-border': '#d0d7de',\n '--tv-fg': '#24292f',\n '--tv-muted': '#656d76',\n '--tv-accent': '#0969da',\n '--tv-btn-bg': '#f6f8fa',\n },\n};\n\nexport function loadTheme(): ThemeId {\n try {\n const v = localStorage.getItem(THEME_STORAGE_KEY);\n return v === 'light' ? 'light' : 'dark';\n } catch {\n return 'dark';\n }\n}\n\nexport function saveTheme(theme: ThemeId): void {\n try {\n localStorage.setItem(THEME_STORAGE_KEY, theme);\n } catch {\n /* ignore */\n }\n}\n\nexport function applyThemeToDocument(theme: ThemeId, root: HTMLElement = document.documentElement): void {\n const vars = THEME_VARS[theme];\n for (const [k, v] of Object.entries(vars)) root.style.setProperty(k, v);\n root.dataset.tradviewTheme = theme;\n}\n\nexport interface ThemeProvider {\n getTheme(): ThemeId;\n setTheme(theme: ThemeId): void;\n toggle(): ThemeId;\n subscribe(listener: (theme: ThemeId) => void): () => void;\n}\n\nexport function createThemeProvider(initial?: ThemeId): ThemeProvider {\n let theme: ThemeId = initial ?? loadTheme();\n const listeners = new Set<(t: ThemeId) => void>();\n\n const notify = () => {\n applyThemeToDocument(theme);\n for (const l of listeners) l(theme);\n };\n\n applyThemeToDocument(theme);\n\n return {\n getTheme: () => theme,\n setTheme: (next) => {\n if (next === theme) return;\n theme = next;\n saveTheme(theme);\n notify();\n },\n toggle: () => {\n theme = theme === 'dark' ? 'light' : 'dark';\n saveTheme(theme);\n notify();\n return theme;\n },\n subscribe: (listener) => {\n listeners.add(listener);\n listener(theme);\n return () => listeners.delete(listener);\n },\n };\n}","import {\n getLocale,\n registerLocale,\n setLocale,\n t as i18nT,\n type I18nDictionary,\n type Locale,\n} from '@coderyo/i18n';\n\nexport interface I18nProvider {\n t(key: string, fallback?: string, params?: Record<string, string | number>): string;\n getLocale(): Locale;\n setLocale(locale: Locale): void;\n registerLocale(locale: Locale, dictionary: I18nDictionary): void;\n subscribe(listener: (locale: Locale) => void): () => void;\n}\n\nfunction interpolate(text: string, params?: Record<string, string | number>): string {\n if (!params) return text;\n return text.replace(/\\{(\\w+)\\}/g, (_, key: string) => String(params[key] ?? `{${key}}`));\n}\n\nexport function createI18nProvider(defaultLocale: Locale = 'zh-TW'): I18nProvider {\n setLocale(defaultLocale);\n const listeners = new Set<(locale: Locale) => void>();\n\n return {\n t(key, fallback, params) {\n return interpolate(i18nT(key, fallback), params);\n },\n getLocale,\n setLocale(locale) {\n setLocale(locale);\n for (const l of listeners) l(locale);\n },\n registerLocale(loc, dictionary) {\n registerLocale(loc, dictionary);\n if (getLocale() === loc) {\n for (const l of listeners) l(loc);\n }\n },\n subscribe(listener) {\n listeners.add(listener);\n listener(getLocale());\n return () => listeners.delete(listener);\n },\n };\n}","import { t } from '@coderyo/i18n';\nimport { attachChartContextMenu, type ContextMenuAction } from './context-menu.js';\nimport { mountCrosshairLegend } from './crosshair-legend.js';\nimport { mountDrawingPropertiesPanel } from './drawing-properties-panel.js';\nimport { mountIndicatorPaneHost } from './indicator-pane-host.js';\nimport { createLayoutGrid, type LayoutGridHandle } from './layout-engine.js';\nimport { createCompositorShell } from './layer/compositor-shell.js';\nimport { syncCompositorShellVisibilityFromFeatures } from './layer/compositor-shell-sync.js';\nimport { getWidgetPlacement } from './layout-schema.js';\nimport {\n mergeLayoutFeatures,\n resolveLayoutFeatures,\n type LayoutFeatures,\n type ResolvedLayoutFeatures,\n} from './layout-features.js';\nimport {\n loadLayoutSchema,\n resolveLayoutSchema,\n saveLayoutSchema,\n type LayoutSchema,\n} from './layout-schema.js';\nimport { mountStatusBar, type StatusBarOptions } from './status-bar.js';\nimport { mountTopBar, type TopBarOptions } from './top-bar.js';\nimport type { SettingsPanelOptions } from './settings-panel.js';\nimport { bindShortcutsModal } from './shortcuts-modal.js';\nimport { createI18nProvider, type I18nProvider } from './i18n-provider.js';\nimport { createThemeProvider, type ThemeProvider } from './theme-provider.js';\n\nexport type { LayoutFeatures, ResolvedLayoutFeatures } from './layout-features.js';\nexport { resolveLayoutFeatures, DEFAULT_LAYOUT_FEATURES, createDemoLayoutOptions } from './layout-features.js';\nexport type { LayoutSchema, LayoutWidgetId } from './layout-schema.js';\nexport {\n DEFAULT_LAYOUT_SCHEMA,\n resolveLayoutSchema,\n loadLayoutSchema,\n saveLayoutSchema,\n layoutStorageKey,\n} from './layout-schema.js';\n\nexport type DrawingToolId =\n | 'cursor'\n | 'trendline'\n | 'hline'\n | 'vline'\n | 'rectangle'\n | 'fibonacci'\n | 'text';\n\nconst DRAWING_TOOLS: Array<{ id: DrawingToolId; label: string }> = [\n { id: 'cursor', label: '↖' },\n { id: 'trendline', label: '╱' },\n { id: 'hline', label: '─' },\n { id: 'vline', label: '│' },\n { id: 'rectangle', label: '▭' },\n { id: 'fibonacci', label: 'φ' },\n { id: 'text', label: 'T' },\n];\n\nconst MOBILE_MQ = '(max-width: 768px)';\n\nexport interface ChartLayoutOptions extends TopBarOptions {\n themeProvider?: ThemeProvider;\n i18n?: I18nProvider;\n /** When false, do not auto-create theme provider / localStorage (default true). */\n autoThemeProvider?: boolean;\n /** When false, do not auto-create i18n provider (default true). */\n autoI18n?: boolean;\n /** Grid layout schema; omit to use {@link DEFAULT_LAYOUT_SCHEMA}. */\n layout?: LayoutSchema | null;\n /** Key for layout persistence (`layoutPersist`). Default `default`. */\n layoutId?: string;\n /** Persist layout schema to localStorage on change / saveLayout(). */\n layoutPersist?: boolean;\n /**\n * Enable drag/resize layout editor on mount.\n * @deprecated Ignored when `layerCompositorManaged` — use `mountLayerCompositor` + `enableLayerEditor`.\n */\n layoutEditor?: boolean;\n onLayoutChange?: (schema: LayoutSchema) => void;\n showTopBar?: boolean;\n showLeftToolbar?: boolean;\n showBottomToolbar?: boolean;\n activeDrawingTool?: DrawingToolId;\n onDrawingToolSelect?: (tool: DrawingToolId) => void;\n statusBar?: StatusBarOptions;\n contextMenuActions?: ContextMenuAction[];\n settings?: SettingsPanelOptions;\n showStatusBar?: boolean;\n showCrosshairLegend?: boolean;\n showPropertiesPanel?: boolean;\n showContextMenu?: boolean;\n showSettings?: boolean;\n showShortcuts?: boolean;\n symbolInput?: 'manual' | 'search' | 'dialog' | 'none';\n onDrawingStyleChange?: (patch: { color?: string; lineWidth?: number; text?: string }) => void;\n onDrawingSelectionBind?: (bind: (drawing: import('@coderyo/drawings').DrawingRecord | null) => void) => void;\n /**\n * When true, crosshair legend is not mounted under chartMain and visibility is driven by\n * LayerCompositor (not grid CSS / el.style.display here).\n */\n layerCompositorManaged?: boolean;\n}\n\nfunction mountToolButtons(\n parent: HTMLElement,\n activeTool: DrawingToolId,\n onSelect: (tool: DrawingToolId) => void,\n layout: 'column' | 'row',\n): { setActive: (tool: DrawingToolId) => void } {\n const btnStyle =\n layout === 'column'\n ? 'width:32px;height:28px;background:#21262d;color:#e6edf3;border:1px solid #30363d;border-radius:4px;cursor:pointer;font-size:13px;padding:0;'\n : 'min-width:36px;height:32px;background:#21262d;color:#e6edf3;border:1px solid #30363d;border-radius:4px;cursor:pointer;font-size:13px;padding:0 6px;';\n const activeStyle = btnStyle.replace('#21262d', '#388bfd').replace('#e6edf3', '#fff');\n\n const buttons = new Map<DrawingToolId, HTMLButtonElement>();\n for (const tool of DRAWING_TOOLS) {\n const btn = document.createElement('button');\n btn.type = 'button';\n btn.title = tool.id;\n btn.textContent = tool.label;\n btn.style.cssText = activeTool === tool.id ? activeStyle : btnStyle;\n btn.onclick = () => onSelect(tool.id);\n buttons.set(tool.id, btn);\n parent.appendChild(btn);\n }\n\n return {\n setActive: (tool) => {\n for (const [id, btn] of buttons) {\n btn.style.cssText = id === tool ? activeStyle : btnStyle;\n }\n },\n };\n}\n\nexport function mountChartLayout(root: HTMLElement, opts: ChartLayoutOptions = {}): {\n layoutRoot: HTMLElement;\n layoutGrid: HTMLElement;\n /** @deprecated Alias of chartMain — use chartMain for LWC mount. */\n chartHost: HTMLElement;\n chartMain: HTMLElement;\n chartVolume: HTMLElement;\n /** Drawing canvas host (same element as chartMain when compositor-managed). */\n drawingOverlay: HTMLElement;\n indicatorHost: HTMLElement;\n topBar: HTMLElement;\n setActiveInterval: (interval: import('@coderyo/data').Interval) => void;\n statusBar: ReturnType<typeof mountStatusBar>;\n crosshairLegend: ReturnType<typeof mountCrosshairLegend>;\n detachContextMenu: () => void;\n setActiveDrawingTool: (tool: DrawingToolId) => void;\n propertiesPanel: ReturnType<typeof mountDrawingPropertiesPanel>;\n /** Bind drawing + apply properties panel visibility (compositor-safe). */\n handleDrawingSelection: (drawing: import('@coderyo/drawings').DrawingRecord | null) => void;\n /** Sync showCrosshairLegend (etc.) to compositor layer.visible when layerCompositorManaged. */\n syncCompositorShellVisibility?: (\n controller: import('./layer/layer-controller.js').LayerController,\n ) => void;\n /**\n * Bind compositor controller so `setLayoutFeatures` keeps shell/legend layer.visible in sync.\n * Call once after `mountLayerCompositor` (Playground pattern).\n */\n bindLayerCompositorController?: (\n controller: import('./layer/layer-controller.js').LayerController,\n ) => void;\n setLayoutFeatures: (patch: LayoutFeatures) => void;\n getLayoutFeatures: () => ResolvedLayoutFeatures;\n getLayoutSchema: () => LayoutSchema;\n setLayoutSchema: (schema: LayoutSchema) => void;\n enableLayoutEditor: (enabled: boolean) => void;\n saveLayout: () => void;\n} {\n let layoutFeatures = resolveLayoutFeatures(opts);\n const layoutId = opts.layoutId ?? 'default';\n\n root.replaceChildren();\n root.style.display = 'flex';\n root.style.flexDirection = 'column';\n root.style.height = root.style.height || '100%';\n root.style.width = root.style.width || '100%';\n root.style.minWidth = '0';\n root.style.boxSizing = 'border-box';\n root.style.overflow = 'hidden';\n\n const useAutoTheme = opts.autoThemeProvider !== false;\n const useAutoI18n = opts.autoI18n !== false;\n const themeProvider =\n opts.themeProvider ?? (useAutoTheme ? createThemeProvider() : undefined);\n const i18nProvider = opts.i18n ?? (useAutoI18n ? createI18nProvider() : undefined);\n\n themeProvider?.subscribe((theme) => {\n root.style.background = theme === 'dark' ? '#0d1117' : '#f6f8fa';\n });\n\n let activeTool: DrawingToolId = opts.activeDrawingTool ?? 'cursor';\n let setActiveDesktop: ((t: DrawingToolId) => void) | null = null;\n let setActiveMobile: ((t: DrawingToolId) => void) | null = null;\n let lastSelectedDrawing: import('@coderyo/drawings').DrawingRecord | null = null;\n\n const setActiveDrawingTool = (tool: DrawingToolId) => {\n activeTool = tool;\n setActiveDesktop?.(tool);\n setActiveMobile?.(tool);\n };\n\n const onToolSelect = (tool: DrawingToolId) => {\n setActiveDrawingTool(tool);\n opts.onDrawingToolSelect?.(tool);\n };\n\n const topBarHost = document.createElement('div');\n topBarHost.className = 'tv-layout-header';\n topBarHost.style.cssText = 'width:100%;min-width:0;overflow:visible;position:relative;z-index:30;';\n\n const leftToolbar = document.createElement('aside');\n leftToolbar.style.cssText =\n 'width:100%;height:100%;max-width:44px;border-right:1px solid #30363d;background:#161b22;display:flex;flex-direction:column;align-items:center;padding:4px 2px;gap:4px;box-sizing:border-box;overflow:hidden;';\n\n const bottomToolbar = document.createElement('div');\n bottomToolbar.style.cssText =\n 'width:100%;height:100%;gap:6px;padding:6px 8px;border-top:1px solid #30363d;background:#161b22;overflow-x:auto;box-sizing:border-box;display:flex;flex-direction:row;';\n\n const chartMain = document.createElement('div');\n chartMain.className = 'tv-chart-main-mount';\n chartMain.style.cssText =\n 'width:100%;height:100%;min-height:120px;position:relative;overflow:hidden;box-sizing:border-box;';\n\n const chartVolume = document.createElement('div');\n chartVolume.className = 'tv-chart-volume-mount';\n chartVolume.style.cssText =\n 'width:100%;height:100%;min-height:48px;position:relative;overflow:hidden;box-sizing:border-box;';\n\n /** Legacy grid cell only; with LayerCompositor use chartMain/chartVolume mounts (not chartHost). */\n const chartHost = document.createElement('div');\n chartHost.className = 'tv-chart-grid-anchor';\n chartHost.style.cssText =\n 'width:100%;height:100%;min-height:0;position:relative;overflow:hidden;box-sizing:border-box;';\n\n const indicatorMount = document.createElement('div');\n indicatorMount.style.cssText = 'width:100%;height:100%;min-height:0;display:flex;flex-direction:column;';\n const indicatorHost = mountIndicatorPaneHost(indicatorMount);\n indicatorHost.style.flex = '1';\n\n const statusMount = document.createElement('div');\n statusMount.style.cssText = 'width:100%;height:100%;';\n const statusBar = mountStatusBar(statusMount, opts.statusBar ?? {});\n\n const propertiesMount = document.createElement('div');\n propertiesMount.style.cssText = 'width:100%;height:100%;min-height:0;';\n const propertiesPanel = mountDrawingPropertiesPanel(propertiesMount, {\n onStyleChange: opts.onDrawingStyleChange,\n });\n\n const layerCompositorManaged = opts.layerCompositorManaged === true;\n const drawingOverlay = chartMain;\n\n let loaded: LayoutSchema | null = null;\n let layoutSchema = resolveLayoutSchema(null);\n if (!layerCompositorManaged) {\n loaded =\n opts.layout !== undefined && opts.layout !== null\n ? resolveLayoutSchema(opts.layout)\n : opts.layoutPersist\n ? loadLayoutSchema(layoutId)\n : null;\n layoutSchema = resolveLayoutSchema(loaded);\n }\n\n const persistLayout = (schema: LayoutSchema) => {\n if (layerCompositorManaged) return;\n layoutSchema = resolveLayoutSchema(schema);\n if (opts.layoutPersist) saveLayoutSchema(layoutId, layoutSchema);\n opts.onLayoutChange?.(layoutSchema);\n };\n\n let layoutShell: LayoutGridHandle | ReturnType<typeof createCompositorShell>;\n if (layerCompositorManaged) {\n layoutShell = createCompositorShell({\n widgets: {\n topBar: topBarHost,\n leftToolbar,\n bottomToolbar,\n chartHost,\n indicatorHost: indicatorMount,\n statusBar: statusMount,\n propertiesPanel: propertiesMount,\n },\n });\n } else {\n layoutShell = createLayoutGrid({\n schema: layoutSchema,\n features: layoutFeatures,\n editor: opts.layoutEditor ?? false,\n onSchemaChange: persistLayout,\n widgets: {\n topBar: topBarHost,\n leftToolbar,\n bottomToolbar,\n chartHost,\n indicatorHost: indicatorMount,\n statusBar: statusMount,\n propertiesPanel: propertiesMount,\n },\n });\n }\n\n root.appendChild(layoutShell.root);\n\n let topBar: HTMLElement = topBarHost;\n let setActiveInterval: (interval: import('@coderyo/data').Interval) => void = () => {};\n const crosshairLegend = mountCrosshairLegend(\n layerCompositorManaged ? undefined : chartMain,\n { symbol: opts.initialSymbol },\n );\n\n let detachContextMenu = () => {};\n let shortcutsBound = false;\n let disposeMobileMq: (() => void) | null = null;\n\n const mountToolbarActions = (parent: HTMLElement, compact: boolean) => {\n const settings = opts.settings;\n if (!settings?.onClearAllDrawings && !settings?.onClearAllIndicators) return;\n const spacer = document.createElement('div');\n spacer.style.flex = compact ? '1' : '0';\n spacer.style.minHeight = compact ? '4px' : '0';\n parent.appendChild(spacer);\n const mk = (label: string, fn?: () => void) => {\n const b = document.createElement('button');\n b.type = 'button';\n b.title = label;\n b.textContent = compact\n ? label === t('toolbar.clearDrawings', '清除繪圖')\n ? '⌧'\n : '∅'\n : label;\n b.style.cssText = compact\n ? 'width:32px;height:24px;font-size:10px;background:#21262d;color:#f85149;border:1px solid #30363d;border-radius:4px;cursor:pointer;'\n : 'min-width:36px;height:28px;font-size:10px;background:#21262d;color:#f85149;border:1px solid #30363d;border-radius:4px;cursor:pointer;padding:0 4px;';\n b.onclick = () => fn?.();\n return b;\n };\n if (settings.onClearAllDrawings) {\n parent.appendChild(mk(t('toolbar.clearDrawings', '清除繪圖'), settings.onClearAllDrawings));\n }\n if (settings.onClearAllIndicators) {\n parent.appendChild(mk(t('toolbar.clearIndicators', '清除指標'), settings.onClearAllIndicators));\n }\n };\n\n const mountLeftToolbar = () => {\n leftToolbar.replaceChildren();\n const desktopTools = mountToolButtons(leftToolbar, activeTool, onToolSelect, 'column');\n setActiveDesktop = desktopTools.setActive;\n mountToolbarActions(leftToolbar, true);\n\n bottomToolbar.replaceChildren();\n const mobileTools = mountToolButtons(bottomToolbar, activeTool, onToolSelect, 'row');\n setActiveMobile = mobileTools.setActive;\n mountToolbarActions(bottomToolbar, false);\n };\n\n const chartAreaColStart = () => (layoutFeatures.showLeftToolbar ? 2 : 1);\n\n const applyPropertiesPanelLayout = (drawing: import('@coderyo/drawings').DrawingRecord | null) => {\n const showPanel = layoutFeatures.showPropertiesPanel && drawing != null;\n propertiesPanel.el.style.display = showPanel ? 'block' : 'none';\n if (layerCompositorManaged) return;\n\n const propsCell = layoutShell.cells.get('propertiesPanel');\n const chartCell = layoutShell.cells.get('chartHost');\n const indCell = layoutShell.cells.get('indicatorHost');\n const statusCell = layoutShell.cells.get('statusBar');\n if (!propsCell || !chartCell) return;\n\n const cw = getWidgetPlacement(layoutSchema, 'chartHost');\n const iw = getWidgetPlacement(layoutSchema, 'indicatorHost');\n const sw = getWidgetPlacement(layoutSchema, 'statusBar');\n const pw = getWidgetPlacement(layoutSchema, 'propertiesPanel');\n\n const applyPlacement = (cell: HTMLElement, p: { col: number; row: number; colSpan: number; rowSpan: number }) => {\n cell.style.gridColumn = `${p.col + 1} / span ${p.colSpan}`;\n cell.style.gridRow = `${p.row + 1} / span ${p.rowSpan}`;\n };\n\n if (showPanel) {\n propsCell.style.display = '';\n if (pw) applyPlacement(propsCell, pw);\n if (cw) applyPlacement(chartCell, cw);\n if (indCell && iw) {\n indCell.style.display = '';\n applyPlacement(indCell, iw);\n }\n if (statusCell && sw) applyPlacement(statusCell, sw);\n } else {\n propsCell.style.display = 'none';\n const end = layoutSchema.columns + 1;\n const start = chartAreaColStart();\n chartCell.style.gridColumn = `${start} / ${end}`;\n if (cw) chartCell.style.gridRow = `${cw.row + 1} / span ${cw.rowSpan}`;\n if (indCell && iw) {\n indCell.style.display = '';\n indCell.style.gridColumn = `${start} / ${end}`;\n indCell.style.gridRow = `${iw.row + 1} / span ${iw.rowSpan}`;\n }\n if (statusCell && sw) {\n statusCell.style.gridColumn = `${start} / ${end}`;\n statusCell.style.gridRow = `${sw.row + 1} / span ${sw.rowSpan}`;\n }\n }\n };\n\n const applyLayoutFeatures = () => {\n const f = layoutFeatures;\n\n if (f.showTopBar) {\n topBarHost.replaceChildren();\n const mounted = mountTopBar(\n topBarHost,\n Object.assign(opts, {\n symbolInput: f.symbolInput,\n showSettings: f.showSettings,\n themeProvider: opts.themeProvider ?? themeProvider,\n i18n: opts.i18n ?? i18nProvider,\n onThemeChange: (theme: 'dark' | 'light') => {\n opts.onThemeChange?.(theme);\n if (!opts.onThemeChange) opts.onThemeToggle?.();\n },\n }),\n );\n topBar = mounted.el;\n setActiveInterval = mounted.setActiveInterval;\n } else {\n topBarHost.replaceChildren();\n topBar = topBarHost;\n }\n\n if (f.showLeftToolbar || f.showBottomToolbar) mountLeftToolbar();\n else {\n leftToolbar.replaceChildren();\n bottomToolbar.replaceChildren();\n setActiveDesktop = null;\n setActiveMobile = null;\n }\n\n if (!layerCompositorManaged) {\n (layoutShell as LayoutGridHandle).applySchema(layoutSchema, f);\n }\n\n disposeMobileMq?.();\n const mq = window.matchMedia(MOBILE_MQ);\n const applyMobileTools = () => {\n const features = layoutFeatures;\n const mobile = mq.matches;\n if (features.showLeftToolbar) {\n leftToolbar.style.display = mobile ? 'none' : 'flex';\n }\n if (features.showBottomToolbar) {\n bottomToolbar.style.display = mobile ? 'flex' : 'none';\n const bottomCell = layoutShell.cells.get('bottomToolbar');\n if (bottomCell) {\n bottomCell.style.display = mobile && features.showBottomToolbar ? '' : 'none';\n }\n }\n };\n mq.addEventListener('change', applyMobileTools);\n disposeMobileMq = () => mq.removeEventListener('change', applyMobileTools);\n applyMobileTools();\n\n if (!layerCompositorManaged) {\n crosshairLegend.el.style.display = f.showCrosshairLegend ? '' : 'none';\n }\n\n detachContextMenu();\n if (f.showContextMenu) {\n detachContextMenu = attachChartContextMenu(chartMain, {\n actions: opts.contextMenuActions,\n });\n }\n\n if (f.showShortcuts && !shortcutsBound) {\n bindShortcutsModal();\n shortcutsBound = true;\n }\n\n applyPropertiesPanelLayout(lastSelectedDrawing);\n };\n\n const handleDrawingSelection = (drawing: import('@coderyo/drawings').DrawingRecord | null) => {\n lastSelectedDrawing = drawing;\n propertiesPanel.bind(drawing);\n applyPropertiesPanelLayout(drawing);\n };\n\n opts.onDrawingSelectionBind?.(propertiesPanel.bind);\n applyLayoutFeatures();\n applyPropertiesPanelLayout(null);\n\n let boundCompositorController: import('./layer/layer-controller.js').LayerController | null =\n null;\n\n const syncCompositorShellVisibility = layerCompositorManaged\n ? (controller: import('./layer/layer-controller.js').LayerController) => {\n syncCompositorShellVisibilityFromFeatures(controller, layoutFeatures);\n }\n : undefined;\n\n const syncCompositorShellVisibilityIfBound = () => {\n if (boundCompositorController) {\n syncCompositorShellVisibilityFromFeatures(boundCompositorController, layoutFeatures);\n }\n };\n\n const bindLayerCompositorController = layerCompositorManaged\n ? (controller: import('./layer/layer-controller.js').LayerController) => {\n boundCompositorController = controller;\n syncCompositorShellVisibilityFromFeatures(controller, layoutFeatures);\n }\n : undefined;\n\n return {\n layoutRoot: layoutShell.root,\n layoutGrid: layoutShell.grid,\n chartHost: chartMain,\n chartMain,\n chartVolume,\n drawingOverlay,\n indicatorHost,\n topBar,\n setActiveInterval,\n statusBar,\n crosshairLegend,\n detachContextMenu,\n setActiveDrawingTool,\n propertiesPanel,\n handleDrawingSelection,\n syncCompositorShellVisibility,\n bindLayerCompositorController,\n setLayoutFeatures: (patch) => {\n layoutFeatures = mergeLayoutFeatures(layoutFeatures, patch);\n applyLayoutFeatures();\n syncCompositorShellVisibilityIfBound();\n },\n getLayoutFeatures: () => ({ ...layoutFeatures }),\n getLayoutSchema: () =>\n layerCompositorManaged\n ? layoutSchema\n : (layoutShell as LayoutGridHandle).getSchema(),\n setLayoutSchema: (schema) => {\n if (layerCompositorManaged) return;\n layoutSchema = resolveLayoutSchema(schema);\n const grid = layoutShell as LayoutGridHandle;\n grid.setSchema(layoutSchema);\n grid.applySchema(layoutSchema, layoutFeatures);\n persistLayout(layoutSchema);\n },\n enableLayoutEditor: (enabled) => {\n if (layerCompositorManaged) return;\n (layoutShell as LayoutGridHandle).enableEditor(enabled);\n },\n saveLayout: () => {\n if (layerCompositorManaged) return;\n persistLayout((layoutShell as LayoutGridHandle).getSchema());\n },\n };\n}","import { t } from '@coderyo/i18n';\n\nexport interface ContextMenuAction {\n id: string;\n label: string;\n onClick: () => void;\n}\n\nexport interface ContextMenuOptions {\n actions?: ContextMenuAction[];\n}\n\nexport function attachChartContextMenu(\n chartHost: HTMLElement,\n opts: ContextMenuOptions = {},\n): () => void {\n let menu: HTMLDivElement | null = null;\n\n const close = () => {\n menu?.remove();\n menu = null;\n };\n\n const open = (x: number, y: number) => {\n close();\n menu = document.createElement('div');\n menu.style.cssText =\n 'position:fixed;z-index:50;min-width:160px;padding:4px 0;background:#161b22;border:1px solid #30363d;border-radius:6px;box-shadow:0 8px 24px #01040988;';\n\n const actions: ContextMenuAction[] = opts.actions ?? [\n {\n id: 'fit',\n label: t('context.fitContent', '適配畫面'),\n onClick: () => {},\n },\n ];\n\n for (const action of actions) {\n const row = document.createElement('button');\n row.type = 'button';\n row.textContent = action.label;\n row.style.cssText =\n 'display:block;width:100%;text-align:left;padding:8px 12px;border:none;background:transparent;color:#e6edf3;font-size:12px;cursor:pointer;';\n row.onmouseenter = () => {\n row.style.background = '#21262d';\n };\n row.onmouseleave = () => {\n row.style.background = 'transparent';\n };\n row.onclick = () => {\n action.onClick();\n close();\n };\n menu.appendChild(row);\n }\n\n menu.style.left = `${x}px`;\n menu.style.top = `${y}px`;\n document.body.appendChild(menu);\n };\n\n const onContext = (e: MouseEvent) => {\n e.preventDefault();\n open(e.clientX, e.clientY);\n };\n\n chartHost.addEventListener('contextmenu', onContext);\n document.addEventListener('click', close);\n document.addEventListener('scroll', close, true);\n\n return () => {\n chartHost.removeEventListener('contextmenu', onContext);\n document.removeEventListener('click', close);\n document.removeEventListener('scroll', close, true);\n close();\n };\n}","import type { OhlcvSnapshot } from './status-bar.js';\n\nexport interface CrosshairLegendOptions {\n symbol?: string;\n interval?: string;\n}\n\nexport function mountCrosshairLegend(\n chartHost?: HTMLElement,\n opts: CrosshairLegendOptions = {},\n): {\n el: HTMLElement;\n update: (payload: { time?: number; ohlcv?: OhlcvSnapshot | null }) => void;\n setMeta: (meta: CrosshairLegendOptions) => void;\n hide: () => void;\n} {\n const box = document.createElement('div');\n box.className = 'tv-crosshair-legend';\n box.style.cssText =\n 'display:none;position:absolute;top:8px;left:8px;z-index:10;padding:6px 10px;border-radius:6px;background:#161b22e6;border:1px solid #30363d;font-size:11px;color:#e6edf3;pointer-events:none;line-height:1.5;';\n\n const title = document.createElement('div');\n title.style.cssText = 'color:#8b949e;margin-bottom:2px;';\n const body = document.createElement('div');\n box.append(title, body);\n if (chartHost) chartHost.appendChild(box);\n\n const fmt = (n: number | undefined) =>\n n == null ? '—' : n.toLocaleString(undefined, { maximumFractionDigits: 2 });\n\n const render = (payload: { time?: number; ohlcv?: OhlcvSnapshot | null }) => {\n const parts = [opts.symbol, opts.interval].filter(Boolean);\n title.textContent = parts.length ? parts.join(' · ') : '';\n const o = payload.ohlcv;\n if (!o?.c && o?.o == null) {\n box.style.display = 'none';\n return;\n }\n const timeStr = payload.time != null ? new Date(payload.time).toLocaleString() : '';\n body.textContent = `${timeStr}\\nO ${fmt(o?.o)} H ${fmt(o?.h)} L ${fmt(o?.l)} C ${fmt(o?.c)}`;\n box.style.display = 'block';\n };\n\n return {\n el: box,\n update: render,\n setMeta: (meta) => {\n Object.assign(opts, meta);\n title.textContent = [opts.symbol, opts.interval].filter(Boolean).join(' · ');\n },\n hide: () => {\n box.style.display = 'none';\n },\n };\n}","import type { DrawingRecord } from '@coderyo/drawings';\nimport { t } from '@coderyo/i18n';\n\nexport interface DrawingPropertiesPanelOptions {\n onStyleChange?: (patch: { color?: string; lineWidth?: number; text?: string }) => void;\n}\n\nexport function mountDrawingPropertiesPanel(\n parent: HTMLElement,\n opts: DrawingPropertiesPanelOptions = {},\n): { el: HTMLElement; bind: (drawing: DrawingRecord | null) => void } {\n const panel = document.createElement('aside');\n panel.className = 'tv-drawing-props';\n panel.style.cssText =\n 'display:none;width:100%;max-width:200px;flex-shrink:0;border-left:1px solid #30363d;background:#161b22;padding:10px 12px;font-size:12px;color:#e6edf3;overflow:auto;box-sizing:border-box;';\n\n const title = document.createElement('div');\n title.textContent = t('drawing.props.title', '繪圖屬性');\n title.style.cssText = 'font-weight:600;margin-bottom:10px;';\n\n const typeEl = document.createElement('div');\n typeEl.style.color = '#8b949e';\n typeEl.style.marginBottom = '10px';\n\n const mkRow = (label: string) => {\n const row = document.createElement('label');\n row.style.cssText = 'display:flex;flex-direction:column;gap:4px;margin-bottom:8px;';\n const span = document.createElement('span');\n span.textContent = label;\n span.style.color = '#8b949e';\n row.appendChild(span);\n return row;\n };\n\n const colorRow = mkRow(t('drawing.props.color', '顏色'));\n const colorInput = document.createElement('input');\n colorInput.type = 'color';\n colorInput.style.cssText = 'width:100%;height:28px;border:none;background:transparent;cursor:pointer;';\n colorRow.appendChild(colorInput);\n\n const widthRow = mkRow(t('drawing.props.lineWidth', '線寬'));\n const widthInput = document.createElement('input');\n widthInput.type = 'range';\n widthInput.min = '1';\n widthInput.max = '6';\n widthInput.style.width = '100%';\n widthRow.appendChild(widthInput);\n\n const textRow = mkRow(t('drawing.props.text', '文字'));\n const textInput = document.createElement('input');\n textInput.type = 'text';\n textInput.style.cssText =\n 'padding:4px 8px;border-radius:4px;border:1px solid #30363d;background:#0d1117;color:#e6edf3;';\n textRow.appendChild(textInput);\n\n const lockedHint = document.createElement('div');\n lockedHint.style.cssText = 'color:#f78166;font-size:11px;margin-top:6px;display:none;';\n lockedHint.textContent = t('drawing.props.locked', '已鎖定 — 解鎖後可編輯');\n\n panel.append(title, typeEl, colorRow, widthRow, textRow, lockedHint);\n parent.appendChild(panel);\n\n const emit = () => {\n opts.onStyleChange?.({\n color: colorInput.value,\n lineWidth: Number(widthInput.value),\n text: textInput.value,\n });\n };\n colorInput.oninput = emit;\n widthInput.oninput = emit;\n textInput.oninput = emit;\n\n const bind = (drawing: DrawingRecord | null) => {\n if (!drawing) {\n panel.style.display = 'none';\n return;\n }\n panel.style.display = 'block';\n typeEl.textContent = `${t('drawing.props.type', '類型')}: ${drawing.type}`;\n const meta = drawing.meta ?? {};\n colorInput.value = String(meta.color ?? '#58a6ff');\n widthInput.value = String(meta.lineWidth ?? 2);\n textInput.value = String(meta.text ?? 'Note');\n textRow.style.display = drawing.type === 'text' ? 'flex' : 'none';\n const locked = Boolean(meta.locked);\n lockedHint.style.display = locked ? 'block' : 'none';\n colorInput.disabled = locked;\n widthInput.disabled = locked;\n textInput.disabled = locked;\n };\n\n return { el: panel, bind };\n}","/** Host for MACD / RSI / KDJ indicator panes (PR-11). */\nexport function mountIndicatorPaneHost(parent: HTMLElement): HTMLElement {\n const host = document.createElement('div');\n host.dataset.tradviewIndicatorHost = '1';\n host.style.cssText =\n 'display:flex;flex-direction:column;flex:2;min-height:120px;border-top:1px solid #30363d;background:#0d1117;overflow:hidden;';\n parent.appendChild(host);\n return host;\n}","/** Visual layout schema (grid-based composable shell). */\n\nexport type LayoutWidgetId =\n | 'topBar'\n | 'leftToolbar'\n | 'bottomToolbar'\n | 'chartHost'\n | 'indicatorHost'\n | 'statusBar'\n | 'propertiesPanel';\n\nexport interface LayoutWidgetPlacement {\n id: LayoutWidgetId;\n col: number;\n row: number;\n colSpan: number;\n rowSpan: number;\n}\n\nexport interface LayoutSchema {\n version: 1;\n columns: number;\n rows: number;\n widgets: LayoutWidgetPlacement[];\n}\n\nexport const LAYOUT_SCHEMA_VERSION = 1 as const;\n\n/** TV-style default when integrator omits `layout` (matches legacy mountChartLayout proportions). */\nexport const DEFAULT_LAYOUT_SCHEMA: LayoutSchema = {\n version: 1,\n columns: 12,\n rows: 12,\n widgets: [\n { id: 'topBar', col: 0, row: 0, colSpan: 12, rowSpan: 1 },\n { id: 'leftToolbar', col: 0, row: 1, colSpan: 1, rowSpan: 10 },\n { id: 'chartHost', col: 1, row: 1, colSpan: 9, rowSpan: 6 },\n { id: 'indicatorHost', col: 1, row: 7, colSpan: 9, rowSpan: 2 },\n { id: 'statusBar', col: 1, row: 9, colSpan: 9, rowSpan: 1 },\n { id: 'propertiesPanel', col: 10, row: 1, colSpan: 2, rowSpan: 9 },\n { id: 'bottomToolbar', col: 0, row: 11, colSpan: 12, rowSpan: 1 },\n ],\n};\n\nexport function layoutStorageKey(layoutId: string): string {\n return `tradview:layout:v${LAYOUT_SCHEMA_VERSION}:${layoutId}`;\n}\n\nexport function resolveLayoutSchema(\n partial?: LayoutSchema | null,\n): LayoutSchema {\n if (!partial) return cloneLayoutSchema(DEFAULT_LAYOUT_SCHEMA);\n return normalizeLayoutSchema(partial);\n}\n\nexport function cloneLayoutSchema(schema: LayoutSchema): LayoutSchema {\n return {\n version: 1,\n columns: schema.columns,\n rows: schema.rows,\n widgets: schema.widgets.map((w) => ({ ...w })),\n };\n}\n\nexport function normalizeLayoutSchema(input: LayoutSchema): LayoutSchema {\n const columns = Math.max(4, Math.min(24, input.columns || 12));\n const rows = Math.max(4, Math.min(24, input.rows || 12));\n const widgets: LayoutWidgetPlacement[] = [];\n const seen = new Set<LayoutWidgetId>();\n for (const w of input.widgets ?? []) {\n if (!isLayoutWidgetId(w.id) || seen.has(w.id)) continue;\n seen.add(w.id);\n widgets.push(clampPlacement(w, columns, rows));\n }\n for (const d of DEFAULT_LAYOUT_SCHEMA.widgets) {\n if (!seen.has(d.id)) widgets.push({ ...d });\n }\n return { version: 1, columns, rows, widgets };\n}\n\nfunction clampPlacement(\n w: LayoutWidgetPlacement,\n columns: number,\n rows: number,\n): LayoutWidgetPlacement {\n const colSpan = Math.max(1, Math.min(columns, w.colSpan || 1));\n const rowSpan = Math.max(1, Math.min(rows, w.rowSpan || 1));\n const col = Math.max(0, Math.min(columns - colSpan, w.col || 0));\n const row = Math.max(0, Math.min(rows - rowSpan, w.row || 0));\n return { id: w.id, col, row, colSpan, rowSpan };\n}\n\nfunction isLayoutWidgetId(id: string): id is LayoutWidgetId {\n return (\n id === 'topBar' ||\n id === 'leftToolbar' ||\n id === 'bottomToolbar' ||\n id === 'chartHost' ||\n id === 'indicatorHost' ||\n id === 'statusBar' ||\n id === 'propertiesPanel'\n );\n}\n\nexport function loadLayoutSchema(layoutId: string): LayoutSchema | null {\n try {\n const raw = localStorage.getItem(layoutStorageKey(layoutId));\n if (!raw) return null;\n return normalizeLayoutSchema(JSON.parse(raw) as LayoutSchema);\n } catch {\n return null;\n }\n}\n\nexport function saveLayoutSchema(layoutId: string, schema: LayoutSchema): void {\n try {\n localStorage.setItem(layoutStorageKey(layoutId), JSON.stringify(normalizeLayoutSchema(schema)));\n } catch {\n /* ignore */\n }\n}\n\nexport function getWidgetPlacement(\n schema: LayoutSchema,\n id: LayoutWidgetId,\n): LayoutWidgetPlacement | undefined {\n return schema.widgets.find((w) => w.id === id);\n}","import type { ResolvedLayoutFeatures } from './layout-features.js';\nimport {\n cloneLayoutSchema,\n type LayoutSchema,\n type LayoutWidgetId,\n type LayoutWidgetPlacement,\n} from './layout-schema.js';\n\nexport type LayoutWidgetElements = Partial<Record<LayoutWidgetId, HTMLElement>>;\n\nexport interface LayoutGridHandle {\n root: HTMLElement;\n grid: HTMLElement;\n cells: Map<LayoutWidgetId, HTMLElement>;\n applySchema: (schema: LayoutSchema, features: ResolvedLayoutFeatures) => void;\n enableEditor: (enabled: boolean) => void;\n getSchema: () => LayoutSchema;\n setSchema: (schema: LayoutSchema) => void;\n destroyEditor: () => void;\n}\n\nexport interface CreateLayoutGridOptions {\n schema: LayoutSchema;\n widgets: LayoutWidgetElements;\n features: ResolvedLayoutFeatures;\n editor?: boolean;\n onSchemaChange?: (schema: LayoutSchema) => void;\n}\n\nexport function createLayoutGrid(opts: CreateLayoutGridOptions): LayoutGridHandle {\n let schema = cloneLayoutSchema(opts.schema);\n const cells = new Map<LayoutWidgetId, HTMLElement>();\n\n const root = document.createElement('div');\n root.className = 'tv-layout-root';\n root.style.cssText =\n 'display:flex;flex-direction:column;flex:1;min-height:0;min-width:0;width:100%;height:100%;box-sizing:border-box;';\n\n const grid = document.createElement('div');\n grid.className = 'tv-layout-grid';\n grid.style.cssText =\n 'display:grid;flex:1;min-height:0;min-width:0;width:100%;position:relative;gap:0;';\n root.appendChild(grid);\n\n for (const w of schema.widgets) {\n const cell = document.createElement('div');\n cell.className = `tv-layout-cell tv-layout-cell--${w.id}`;\n cell.dataset.widgetId = w.id;\n cell.style.cssText =\n 'min-width:0;min-height:0;overflow:hidden;position:relative;box-sizing:border-box;';\n const el = opts.widgets[w.id];\n if (el) {\n el.style.width = '100%';\n el.style.height = '100%';\n el.style.minWidth = '0';\n el.style.minHeight = '0';\n if (w.id === 'chartHost') el.style.position = 'relative';\n cell.appendChild(el);\n }\n cells.set(w.id, cell);\n grid.appendChild(cell);\n }\n\n let editorCtl: LayoutEditorController | null = null;\n\n const applySchema = (next: LayoutSchema, features: ResolvedLayoutFeatures) => {\n schema = cloneLayoutSchema(next);\n applyGridTemplate(grid, schema, features);\n for (const w of schema.widgets) {\n const cell = cells.get(w.id);\n if (!cell) continue;\n applyPlacementStyle(cell, w);\n const visible = widgetVisible(w.id, features);\n cell.style.display = visible ? '' : 'none';\n cell.style.pointerEvents = visible ? '' : 'none';\n }\n editorCtl?.refresh(schema);\n };\n\n const enableEditor = (enabled: boolean) => {\n if (enabled) {\n if (!editorCtl) {\n editorCtl = new LayoutEditorController(grid, cells, schema, (s) => {\n schema = s;\n opts.onSchemaChange?.(s);\n });\n }\n editorCtl.enable(true);\n root.classList.add('tv-layout--edit');\n } else {\n editorCtl?.enable(false);\n root.classList.remove('tv-layout--edit');\n }\n };\n\n applySchema(schema, opts.features);\n if (opts.editor) enableEditor(true);\n\n return {\n root,\n grid,\n cells,\n applySchema,\n enableEditor,\n getSchema: () => cloneLayoutSchema(schema),\n setSchema: (s) => {\n schema = cloneLayoutSchema(s);\n applySchema(schema, opts.features);\n },\n destroyEditor: () => {\n editorCtl?.destroy();\n editorCtl = null;\n },\n };\n}\n\nfunction widgetVisible(id: LayoutWidgetId, f: ResolvedLayoutFeatures): boolean {\n switch (id) {\n case 'topBar':\n return f.showTopBar;\n case 'leftToolbar':\n return f.showLeftToolbar;\n case 'bottomToolbar':\n return f.showBottomToolbar;\n case 'statusBar':\n return f.showStatusBar;\n case 'propertiesPanel':\n return f.showPropertiesPanel;\n case 'chartHost':\n case 'indicatorHost':\n return true;\n default:\n return true;\n }\n}\n\nconst LEFT_TOOLBAR_COL_PX = 44;\n\nfunction applyGridTemplate(\n grid: HTMLElement,\n schema: LayoutSchema,\n features?: ResolvedLayoutFeatures,\n): void {\n const narrowToolbar = features?.showLeftToolbar ?? false;\n if (narrowToolbar && schema.columns >= 2) {\n grid.style.gridTemplateColumns = `${LEFT_TOOLBAR_COL_PX}px repeat(${schema.columns - 1}, minmax(0, 1fr))`;\n } else {\n grid.style.gridTemplateColumns = `repeat(${schema.columns}, minmax(0, 1fr))`;\n }\n grid.style.gridTemplateRows = `repeat(${schema.rows}, minmax(0, 1fr))`;\n}\n\nfunction applyPlacementStyle(cell: HTMLElement, w: LayoutWidgetPlacement): void {\n cell.style.gridColumn = `${w.col + 1} / span ${w.colSpan}`;\n cell.style.gridRow = `${w.row + 1} / span ${w.rowSpan}`;\n}\n\nclass LayoutEditorController {\n private enabled = false;\n private drag: {\n id: LayoutWidgetId;\n startX: number;\n startY: number;\n origin: LayoutWidgetPlacement;\n } | null = null;\n private resize: {\n id: LayoutWidgetId;\n startX: number;\n startY: number;\n origin: LayoutWidgetPlacement;\n } | null = null;\n private readonly cleanups: Array<() => void> = [];\n\n constructor(\n private readonly grid: HTMLElement,\n private readonly cells: Map<LayoutWidgetId, HTMLElement>,\n private schema: LayoutSchema,\n private readonly onChange: (schema: LayoutSchema) => void,\n ) {}\n\n refresh(schema: LayoutSchema): void {\n this.schema = cloneLayoutSchema(schema);\n for (const w of this.schema.widgets) {\n const cell = this.cells.get(w.id);\n if (cell) applyPlacementStyle(cell, w);\n }\n }\n\n enable(on: boolean): void {\n if (this.enabled === on) return;\n this.enabled = on;\n if (on) this.bind();\n else this.unbind();\n }\n\n destroy(): void {\n this.enable(false);\n }\n\n private bind(): void {\n for (const [id, cell] of this.cells) {\n const handle = document.createElement('div');\n handle.className = 'tv-layout-drag-handle';\n handle.title = `Drag ${id}`;\n handle.style.cssText =\n 'position:absolute;top:2px;left:2px;z-index:20;padding:2px 6px;font-size:10px;background:#388bfd;color:#fff;border-radius:3px;cursor:grab;user-select:none;opacity:0.85;';\n handle.textContent = id;\n\n const resize = document.createElement('div');\n resize.className = 'tv-layout-resize-handle';\n resize.title = 'Resize';\n resize.style.cssText =\n 'position:absolute;right:2px;bottom:2px;width:12px;height:12px;z-index:20;background:#388bfd;border-radius:2px;cursor:nwse-resize;opacity:0.85;';\n\n cell.style.outline = '1px dashed #388bfd';\n cell.appendChild(handle);\n cell.appendChild(resize);\n\n const onDragDown = (ev: PointerEvent) => {\n ev.preventDefault();\n const p = getPlacement(this.schema, id);\n if (!p) return;\n this.drag = { id, startX: ev.clientX, startY: ev.clientY, origin: { ...p } };\n handle.setPointerCapture(ev.pointerId);\n };\n const onDragMove = (ev: PointerEvent) => {\n if (!this.drag || this.drag.id !== id) return;\n const delta = pixelDeltaToGrid(this.grid, this.schema, ev.clientX - this.drag.startX, ev.clientY - this.drag.startY);\n const next = clampPlacement(\n {\n ...this.drag.origin,\n col: this.drag.origin.col + delta.dCol,\n row: this.drag.origin.row + delta.dRow,\n },\n this.schema,\n );\n updatePlacement(this.schema, next);\n applyPlacementStyle(cell, next);\n };\n const onDragUp = (ev: PointerEvent) => {\n if (!this.drag || this.drag.id !== id) return;\n this.drag = null;\n handle.releasePointerCapture(ev.pointerId);\n this.onChange(cloneLayoutSchema(this.schema));\n };\n\n const onResizeDown = (ev: PointerEvent) => {\n ev.preventDefault();\n ev.stopPropagation();\n const p = getPlacement(this.schema, id);\n if (!p) return;\n this.resize = { id, startX: ev.clientX, startY: ev.clientY, origin: { ...p } };\n resize.setPointerCapture(ev.pointerId);\n };\n const onResizeMove = (ev: PointerEvent) => {\n if (!this.resize || this.resize.id !== id) return;\n const delta = pixelDeltaToGrid(this.grid, this.schema, ev.clientX - this.resize.startX, ev.clientY - this.resize.startY);\n const next = clampPlacement(\n {\n ...this.resize.origin,\n colSpan: this.resize.origin.colSpan + delta.dCol,\n rowSpan: this.resize.origin.rowSpan + delta.dRow,\n },\n this.schema,\n );\n updatePlacement(this.schema, next);\n applyPlacementStyle(cell, next);\n };\n const onResizeUp = (ev: PointerEvent) => {\n if (!this.resize || this.resize.id !== id) return;\n this.resize = null;\n resize.releasePointerCapture(ev.pointerId);\n this.onChange(cloneLayoutSchema(this.schema));\n };\n\n handle.addEventListener('pointerdown', onDragDown);\n handle.addEventListener('pointermove', onDragMove);\n handle.addEventListener('pointerup', onDragUp);\n resize.addEventListener('pointerdown', onResizeDown);\n resize.addEventListener('pointermove', onResizeMove);\n resize.addEventListener('pointerup', onResizeUp);\n\n this.cleanups.push(() => {\n handle.remove();\n resize.remove();\n cell.style.outline = '';\n });\n }\n }\n\n private unbind(): void {\n for (const fn of this.cleanups) fn();\n this.cleanups.length = 0;\n this.drag = null;\n this.resize = null;\n }\n}\n\nfunction getPlacement(schema: LayoutSchema, id: LayoutWidgetId): LayoutWidgetPlacement | undefined {\n return schema.widgets.find((w) => w.id === id);\n}\n\nfunction updatePlacement(schema: LayoutSchema, p: LayoutWidgetPlacement): void {\n const i = schema.widgets.findIndex((w) => w.id === p.id);\n if (i >= 0) schema.widgets[i] = p;\n}\n\nfunction clampPlacement(p: LayoutWidgetPlacement, schema: LayoutSchema): LayoutWidgetPlacement {\n const colSpan = Math.max(1, Math.min(schema.columns - p.col, p.colSpan));\n const rowSpan = Math.max(1, Math.min(schema.rows - p.row, p.rowSpan));\n const col = Math.max(0, Math.min(schema.columns - colSpan, p.col));\n const row = Math.max(0, Math.min(schema.rows - rowSpan, p.row));\n return { ...p, col, row, colSpan, rowSpan };\n}\n\nfunction pixelDeltaToGrid(\n grid: HTMLElement,\n schema: LayoutSchema,\n dx: number,\n dy: number,\n): { dCol: number; dRow: number } {\n const rect = grid.getBoundingClientRect();\n const cellW = rect.width / schema.columns;\n const cellH = rect.height / schema.rows;\n return {\n dCol: cellW > 0 ? Math.round(dx / cellW) : 0,\n dRow: cellH > 0 ? Math.round(dy / cellH) : 0,\n };\n}","import type { ResolvedLayoutFeatures } from '../layout-features.js';\nimport type { LayoutWidgetId } from '../layout-schema.js';\n\nexport type CompositorShellWidgetId = LayoutWidgetId;\n\nexport interface CompositorShellHandle {\n root: HTMLElement;\n /** Hidden anchor grid (v2 compositor positions widgets; no 12×12 layout). */\n grid: HTMLElement;\n cells: Map<CompositorShellWidgetId, HTMLElement>;\n}\n\nexport interface CreateCompositorShellOptions {\n widgets: Partial<Record<CompositorShellWidgetId, HTMLElement>>;\n}\n\n/** Minimal DOM shell for LayoutPreset v2 — replaces legacy createLayoutGrid when compositor-managed. */\nexport function createCompositorShell(\n opts: CreateCompositorShellOptions,\n): CompositorShellHandle {\n const cells = new Map<CompositorShellWidgetId, HTMLElement>();\n\n const root = document.createElement('div');\n root.className = 'tv-layout-root tv-layout-root--compositor';\n root.style.cssText =\n 'display:flex;flex-direction:column;flex:1;min-height:0;min-width:0;width:100%;height:100%;box-sizing:border-box;position:relative;';\n\n const grid = document.createElement('div');\n grid.className = 'tv-compositor-shell-grid';\n grid.style.cssText =\n 'position:absolute;inset:0;overflow:hidden;visibility:hidden;pointer-events:none;z-index:0;';\n root.appendChild(grid);\n\n const widgetIds: CompositorShellWidgetId[] = [\n 'topBar',\n 'leftToolbar',\n 'bottomToolbar',\n 'chartHost',\n 'indicatorHost',\n 'statusBar',\n 'propertiesPanel',\n ];\n\n for (const id of widgetIds) {\n const cell = document.createElement('div');\n cell.className = `tv-layout-cell tv-layout-cell--${id}`;\n cell.dataset.widgetId = id;\n cell.style.cssText =\n 'position:absolute;left:0;top:0;width:100%;height:100%;min-width:0;min-height:0;overflow:hidden;box-sizing:border-box;';\n const el = opts.widgets[id];\n if (el) {\n el.style.width = '100%';\n el.style.height = '100%';\n el.style.minWidth = '0';\n el.style.minHeight = '0';\n if (id === 'chartHost') el.style.position = 'relative';\n cell.appendChild(el);\n }\n cells.set(id, cell);\n grid.appendChild(cell);\n }\n\n return { root, grid, cells };\n}\n\n/** No-op schema apply for compositor shell (features still drive widget mount in chart-layout). */\nexport function applyCompositorShellFeatures(\n _cells: Map<CompositorShellWidgetId, HTMLElement>,\n _features: ResolvedLayoutFeatures,\n): void {\n /* visibility driven by LayerCompositor + syncCompositorShellVisibility */\n}","import type { ResolvedLayoutFeatures } from '../layout-features.js';\nimport type { LayerController } from './layer-controller.js';\nimport type { LayerNode } from './types.js';\n\ntype ShellFeatureKey = keyof Pick<\n ResolvedLayoutFeatures,\n | 'showTopBar'\n | 'showLeftToolbar'\n | 'showBottomToolbar'\n | 'showStatusBar'\n | 'showPropertiesPanel'\n | 'showCrosshairLegend'\n>;\n\nconst SHELL_FEATURE_KEYS: ShellFeatureKey[] = [\n 'showTopBar',\n 'showLeftToolbar',\n 'showBottomToolbar',\n 'showStatusBar',\n 'showPropertiesPanel',\n 'showCrosshairLegend',\n];\n\nfunction shellLayerMatchesFeature(layer: LayerNode, feature: ShellFeatureKey): boolean {\n switch (feature) {\n case 'showTopBar':\n return layer.type === 'shell.topBar' || layer.widgetKey === 'topBar';\n case 'showLeftToolbar':\n return layer.type === 'shell.leftToolbar' || layer.widgetKey === 'leftToolbar';\n case 'showBottomToolbar':\n return layer.type === 'shell.bottomToolbar' || layer.widgetKey === 'bottomToolbar';\n case 'showStatusBar':\n return layer.type === 'shell.statusBar' || layer.widgetKey === 'statusBar';\n case 'showPropertiesPanel':\n return layer.type === 'shell.propertiesPanel' || layer.widgetKey === 'propertiesPanel';\n case 'showCrosshairLegend':\n return (\n layer.type === 'overlay.crosshairLegend' || layer.widgetKey === 'crosshairLegend'\n );\n default:\n return false;\n }\n}\n\n/** Map `LayoutFeatures` toggles to compositor layer.visible on the active page. */\nexport function syncCompositorShellVisibilityFromFeatures(\n controller: LayerController,\n features: ResolvedLayoutFeatures,\n): void {\n const pageLayers = controller.getLayersForActivePage();\n for (const feature of SHELL_FEATURE_KEYS) {\n const visible = features[feature];\n for (const layer of pageLayers) {\n if (shellLayerMatchesFeature(layer, feature)) {\n controller.setLayerVisible(layer.id, visible);\n }\n }\n }\n}","import type { ChartLayoutOptions } from './chart-layout.js';\n\nexport interface LayoutFeatures {\n showTopBar?: boolean;\n showLeftToolbar?: boolean;\n showBottomToolbar?: boolean;\n showCrosshairLegend?: boolean;\n showStatusBar?: boolean;\n showPropertiesPanel?: boolean;\n showContextMenu?: boolean;\n showSettings?: boolean;\n showShortcuts?: boolean;\n /** When TopBar is on and no search API: manual symbol input (default). */\n symbolInput?: 'manual' | 'search' | 'dialog' | 'none';\n}\n\nexport interface ResolvedLayoutFeatures {\n showTopBar: boolean;\n showLeftToolbar: boolean;\n showBottomToolbar: boolean;\n showCrosshairLegend: boolean;\n showStatusBar: boolean;\n showPropertiesPanel: boolean;\n showContextMenu: boolean;\n showSettings: boolean;\n showShortcuts: boolean;\n symbolInput: 'manual' | 'search' | 'dialog' | 'none';\n}\n\nexport const DEFAULT_LAYOUT_FEATURES: ResolvedLayoutFeatures = {\n showTopBar: false,\n showLeftToolbar: false,\n showBottomToolbar: false,\n showCrosshairLegend: false,\n showStatusBar: false,\n showPropertiesPanel: false,\n showContextMenu: false,\n showSettings: false,\n showShortcuts: false,\n symbolInput: 'manual',\n};\n\nexport function resolveLayoutFeatures(\n opts: ChartLayoutOptions = {},\n): ResolvedLayoutFeatures {\n const d = DEFAULT_LAYOUT_FEATURES;\n const top = opts.showTopBar ?? d.showTopBar;\n return {\n showTopBar: top,\n showLeftToolbar: opts.showLeftToolbar ?? d.showLeftToolbar,\n showBottomToolbar: opts.showBottomToolbar ?? d.showBottomToolbar,\n showCrosshairLegend: opts.showCrosshairLegend ?? d.showCrosshairLegend,\n showStatusBar: opts.showStatusBar ?? d.showStatusBar,\n showPropertiesPanel: opts.showPropertiesPanel ?? d.showPropertiesPanel,\n showContextMenu: opts.showContextMenu ?? d.showContextMenu,\n showSettings: opts.settings !== undefined ? (opts.showSettings ?? true) : (opts.showSettings ?? d.showSettings),\n showShortcuts: opts.showShortcuts ?? d.showShortcuts,\n symbolInput: opts.symbolInput ?? (opts.onSymbolSearch ? 'search' : d.symbolInput),\n };\n}\n\nexport function mergeLayoutFeatures(\n current: ResolvedLayoutFeatures,\n patch: LayoutFeatures,\n): ResolvedLayoutFeatures {\n return resolveLayoutFeatures({\n showTopBar: patch.showTopBar ?? current.showTopBar,\n showLeftToolbar: patch.showLeftToolbar ?? current.showLeftToolbar,\n showBottomToolbar: patch.showBottomToolbar ?? current.showBottomToolbar,\n showCrosshairLegend: patch.showCrosshairLegend ?? current.showCrosshairLegend,\n showStatusBar: patch.showStatusBar ?? current.showStatusBar,\n showPropertiesPanel: patch.showPropertiesPanel ?? current.showPropertiesPanel,\n showContextMenu: patch.showContextMenu ?? current.showContextMenu,\n showSettings: patch.showSettings ?? current.showSettings,\n showShortcuts: patch.showShortcuts ?? current.showShortcuts,\n symbolInput: patch.symbolInput ?? current.symbolInput,\n });\n}\n\n/** Playground: enable full TV shell. */\nexport function createDemoLayoutOptions(\n partial: ChartLayoutOptions = {},\n): ChartLayoutOptions {\n return {\n ...partial,\n showTopBar: partial.showTopBar ?? true,\n showLeftToolbar: partial.showLeftToolbar ?? true,\n showCrosshairLegend: partial.showCrosshairLegend ?? true,\n showStatusBar: partial.showStatusBar ?? true,\n showPropertiesPanel: partial.showPropertiesPanel ?? true,\n showContextMenu: partial.showContextMenu ?? true,\n showSettings: partial.showSettings ?? true,\n showShortcuts: partial.showShortcuts ?? true,\n showBottomToolbar: partial.showBottomToolbar ?? true,\n symbolInput: partial.symbolInput ?? (partial.onSymbolSearch ? 'search' : 'manual'),\n };\n}","import { getLocale, setLocale, t } from '@coderyo/i18n';\n\nexport interface OhlcvSnapshot {\n o?: number;\n h?: number;\n l?: number;\n c?: number;\n v?: number;\n}\n\nexport interface StatusBarOptions {\n connection?: string;\n symbol?: string;\n interval?: string;\n ohlcv?: OhlcvSnapshot | null;\n locale?: string;\n onLocaleChange?: (locale: string) => void;\n}\n\nfunction fmt(n: number | undefined, digits = 2): string {\n if (n == null || Number.isNaN(n)) return '—';\n return n.toLocaleString(undefined, { maximumFractionDigits: digits });\n}\n\nexport function mountStatusBar(parent: HTMLElement, opts: StatusBarOptions = {}): {\n el: HTMLElement;\n update: (patch: StatusBarOptions) => void;\n} {\n const bar = document.createElement('div');\n bar.className = 'tv-statusbar';\n bar.style.cssText =\n 'display:flex;align-items:center;gap:14px;padding:6px 12px;font-size:11px;color:#8b949e;border-top:1px solid #30363d;background:#161b22;flex-shrink:0;';\n\n const conn = document.createElement('span');\n const sym = document.createElement('span');\n const ohlcv = document.createElement('span');\n ohlcv.style.flex = '1';\n ohlcv.style.color = '#e6edf3';\n\n const localeWrap = document.createElement('label');\n localeWrap.style.cssText = 'display:flex;align-items:center;gap:4px;margin-left:auto;';\n const localeLabel = document.createElement('span');\n localeLabel.textContent = t('status.locale', '語系');\n const localeSelect = document.createElement('select');\n localeSelect.style.cssText =\n 'background:#0d1117;color:#e6edf3;border:1px solid #30363d;border-radius:4px;font-size:11px;padding:2px 4px;';\n for (const loc of ['zh-TW', 'en']) {\n const opt = document.createElement('option');\n opt.value = loc;\n opt.textContent = loc;\n localeSelect.appendChild(opt);\n }\n localeSelect.value = opts.locale ?? getLocale();\n localeSelect.onchange = () => {\n setLocale(localeSelect.value);\n opts.onLocaleChange?.(localeSelect.value);\n localeLabel.textContent = t('status.locale', '語系');\n render(opts);\n };\n localeWrap.append(localeLabel, localeSelect);\n\n bar.append(conn, sym, ohlcv, localeWrap);\n parent.appendChild(bar);\n\n const render = (state: StatusBarOptions) => {\n const merged = { ...opts, ...state };\n conn.textContent = `${t('status.connection', '連線')}:${merged.connection ?? '—'}`;\n const parts = [merged.symbol, merged.interval].filter(Boolean);\n sym.textContent = parts.length ? parts.join(' · ') : '';\n const o = merged.ohlcv;\n if (o && (o.o != null || o.c != null)) {\n ohlcv.textContent = `O ${fmt(o.o)} H ${fmt(o.h)} L ${fmt(o.l)} C ${fmt(o.c)} V ${fmt(o.v, 0)}`;\n } else {\n ohlcv.textContent = t('status.ohlcvHint', '移動十字線查看 OHLCV');\n }\n };\n\n render(opts);\n return {\n el: bar,\n update: (patch) => {\n Object.assign(opts, patch);\n render(opts);\n },\n };\n}","import { t } from '@coderyo/i18n';\n\nconst SHORTCUTS: Array<{ key: string; desc: string }> = [\n { key: '↖ / Esc', desc: '游標(選取/編輯繪圖)' },\n { key: 'Delete', desc: '刪除選中繪圖' },\n { key: 'R', desc: '適配畫面' },\n { key: 'End', desc: '跳到最新 K 線' },\n { key: 'F', desc: '全螢幕' },\n { key: 'S', desc: '截圖 PNG' },\n { key: 'L', desc: '對數價格軸' },\n { key: 'T', desc: '切換主題' },\n { key: '?', desc: '本說明' },\n];\n\nexport function bindShortcutsModal(): () => void {\n const handler = (e: KeyboardEvent) => {\n if (e.key !== '?' || e.ctrlKey || e.metaKey) return;\n const tag = (e.target as HTMLElement)?.tagName;\n if (tag === 'INPUT' || tag === 'TEXTAREA' || tag === 'SELECT') return;\n e.preventDefault();\n openShortcutsModal();\n };\n window.addEventListener('keydown', handler);\n return () => window.removeEventListener('keydown', handler);\n}\n\nexport function openShortcutsModal(): void {\n const backdrop = document.createElement('div');\n backdrop.style.cssText =\n 'position:fixed;inset:0;z-index:100;background:#01040999;display:flex;align-items:center;justify-content:center;';\n\n const box = document.createElement('div');\n box.style.cssText =\n 'min-width:320px;max-width:90vw;padding:16px 20px;background:#161b22;border:1px solid #30363d;border-radius:8px;color:#e6edf3;';\n\n const h = document.createElement('h2');\n h.textContent = t('shortcuts.title', '快捷鍵');\n h.style.cssText = 'font-size:16px;margin:0 0 12px;';\n\n const list = document.createElement('div');\n list.style.cssText = 'font-size:13px;line-height:1.8;';\n for (const s of SHORTCUTS) {\n const row = document.createElement('div');\n row.innerHTML = `<kbd style=\"background:#21262d;padding:2px 6px;border-radius:4px;margin-right:8px;\">${s.key}</kbd>${s.desc}`;\n list.appendChild(row);\n }\n\n const closeBtn = document.createElement('button');\n closeBtn.type = 'button';\n closeBtn.textContent = t('shortcuts.close', '關閉');\n closeBtn.style.cssText =\n 'margin-top:14px;padding:6px 14px;background:#21262d;color:#e6edf3;border:1px solid #30363d;border-radius:4px;cursor:pointer;';\n const close = () => backdrop.remove();\n closeBtn.onclick = close;\n backdrop.onclick = (e) => {\n if (e.target === backdrop) close();\n };\n\n box.append(h, list, closeBtn);\n backdrop.appendChild(box);\n document.body.appendChild(backdrop);\n}","/** LayoutPreset v2 — free-floating layer compositor (replaces layout-schema v1). */\n\nexport const LAYER_PRESET_VERSION = 2 as const;\n\nexport type LayerPresetAuthor = 'integrator' | 'user';\n\nexport type LayerType =\n | 'shell.topBar'\n | 'shell.leftToolbar'\n | 'shell.bottomToolbar'\n | 'shell.statusBar'\n | 'shell.propertiesPanel'\n | 'chart.host'\n | 'chart.main'\n | 'chart.volume'\n | 'chart.indicator'\n | 'chart.indicatorHost'\n | 'overlay.crosshairLegend'\n | 'overlay.drawing'\n | 'group';\n\n/** Normalized frame relative to page root (0..1). */\nexport interface LayerFrame {\n x: number;\n y: number;\n w: number;\n h: number;\n}\n\nexport interface LayoutPage {\n id: string;\n title: string;\n}\n\nexport interface LayerNode {\n id: string;\n pageId: string;\n type: LayerType;\n /** Maps to legacy widget id or chart role for mount. */\n widgetKey: string;\n frame: LayerFrame;\n zIndex: number;\n visible: boolean;\n locked: boolean;\n groupId?: string;\n /**\n * @public Time-scale sync group for chart panes. Same non-empty id → pan/zoom together;\n * omit or empty → pane is independent (own TimeScaleBus).\n */\n syncTimeScaleGroupId?: string;\n}\n\nexport interface BindGroup {\n id: string;\n name?: string;\n layerIds: string[];\n}\n\nexport interface LayoutPreset {\n version: typeof LAYER_PRESET_VERSION;\n /**\n * Monotonic revision for remote `host.layer.setPreset` merge/replace (integer ≥ 1).\n * @public Bridge schema 2 — stale host revision is rejected with `STALE_PRESET_REVISION`.\n */\n revision?: number;\n id: string;\n name: string;\n author: LayerPresetAuthor;\n readonly?: boolean;\n forkedFrom?: string;\n pages: LayoutPage[];\n layers: LayerNode[];\n groups: BindGroup[];\n}\n\nexport type LayerWidgetKey =\n | 'topBar'\n | 'leftToolbar'\n | 'bottomToolbar'\n | 'chartHost'\n | 'chartMain'\n | 'chartVolume'\n | 'chartIndicator'\n | 'indicatorHost'\n | 'statusBar'\n | 'propertiesPanel'\n | 'crosshairLegend'\n | 'drawingOverlay';","import type { LayerNode, LayerType } from './types.js';\n\nexport const OVERLAY_LAYER_TYPES: readonly LayerType[] = [\n 'overlay.crosshairLegend',\n 'overlay.drawing',\n] as const;\n\nexport function isOverlayLayerType(type: string): type is LayerType {\n return (OVERLAY_LAYER_TYPES as readonly string[]).includes(type);\n}\n\n/** Anchor crosshair legend + drawing overlay frames to chart.main on one page (P3). */\nexport function syncOverlayLayersToMain(layers: LayerNode[], pageId: string): void {\n const main = layers.find((l) => l.type === 'chart.main' && l.pageId === pageId);\n if (!main) return;\n\n const legend = layers.find(\n (l) => l.type === 'overlay.crosshairLegend' && l.pageId === pageId,\n );\n if (legend) {\n legend.frame = {\n x: main.frame.x,\n y: main.frame.y,\n w: Math.min(0.35, main.frame.w),\n h: Math.min(0.1, main.frame.h),\n };\n }\n\n const drawing = layers.find((l) => l.type === 'overlay.drawing' && l.pageId === pageId);\n if (drawing) {\n drawing.frame = {\n x: main.frame.x,\n y: main.frame.y,\n w: main.frame.w,\n h: main.frame.h,\n };\n if (drawing.zIndex <= main.zIndex) {\n drawing.zIndex = main.zIndex + 2;\n }\n }\n}\n\n/** Sync overlays for every page (normalize / bulk migrate). */\nexport function syncAllOverlayLayersToMain(layers: LayerNode[]): void {\n const pageIds = [...new Set(layers.map((l) => l.pageId))];\n for (const pageId of pageIds) {\n syncOverlayLayersToMain(layers, pageId);\n }\n}\n\n/** Active-page drawing overlay visibility (wire to `IChart.setFeatures({ drawings: { layer } })`). */\nexport function getDrawingOverlayVisible(\n controller: { getLayersForActivePage(): LayerNode[] },\n): boolean {\n const drawing = controller\n .getLayersForActivePage()\n .find((l) => l.type === 'overlay.drawing');\n return drawing?.visible ?? true;\n}\n\n/** Insert default overlay layers when chart.main exists (normalize). */\nexport function ensureOverlayLayers(\n layers: LayerNode[],\n pageId: string,\n): LayerNode[] {\n const main = layers.find((l) => l.type === 'chart.main' && l.pageId === pageId);\n if (!main) return layers;\n\n const out = [...layers];\n if (!out.some((l) => l.type === 'overlay.crosshairLegend' && l.pageId === pageId)) {\n out.push({\n id: `layer-crosshairLegend-${pageId}`,\n pageId,\n type: 'overlay.crosshairLegend',\n widgetKey: 'crosshairLegend',\n frame: { x: main.frame.x, y: main.frame.y, w: 0.2, h: 0.08 },\n zIndex: main.zIndex + 5,\n visible: true,\n locked: false,\n });\n }\n if (!out.some((l) => l.type === 'overlay.drawing' && l.pageId === pageId)) {\n out.push({\n id: `layer-drawingOverlay-${pageId}`,\n pageId,\n type: 'overlay.drawing',\n widgetKey: 'drawingOverlay',\n frame: { ...main.frame },\n zIndex: main.zIndex + 3,\n visible: true,\n locked: false,\n });\n }\n syncOverlayLayersToMain(out, pageId);\n return out;\n}","import type { LayerNode, LayerType } from './types.js';\nimport { syncAllOverlayLayersToMain } from './overlay-mount.js';\n\nexport const CHART_PANE_LAYER_TYPES: readonly LayerType[] = [\n 'chart.main',\n 'chart.volume',\n 'chart.indicator',\n 'chart.host',\n 'chart.indicatorHost',\n] as const;\n\nexport const DEFAULT_SYNC_TIME_SCALE_GROUP = 'chart-timescale';\n\nexport function isChartPaneLayerType(type: string): type is LayerType {\n return (CHART_PANE_LAYER_TYPES as readonly string[]).includes(type);\n}\n\nexport function widgetKeyForChartPaneType(type: LayerType): string | null {\n switch (type) {\n case 'chart.main':\n return 'chartMain';\n case 'chart.volume':\n return 'chartVolume';\n case 'chart.indicator':\n case 'chart.indicatorHost':\n return 'chartIndicator';\n case 'chart.host':\n return 'chartMain';\n default:\n return null;\n }\n}\n\nexport function paneIdFromWidgetKey(\n widgetKey: string,\n): 'main' | 'volume' | 'indicator' | null {\n switch (widgetKey) {\n case 'chartMain':\n case 'chartHost':\n return 'main';\n case 'chartVolume':\n return 'volume';\n case 'chartIndicator':\n case 'indicatorHost':\n return 'indicator';\n default:\n return null;\n }\n}\n\nexport interface HostSplitResult {\n layers: LayerNode[];\n /** Maps removed `chart.host` layer id → [mainId, volumeId]. */\n idRemap: Map<string, string[]>;\n}\n\n/** Split legacy `chart.host` into main + volume layers (vertical tile inside host frame). */\nexport function expandLegacyChartHostLayers(layers: LayerNode[]): LayerNode[] {\n return splitLegacyChartHost(layers).layers;\n}\n\nexport function splitLegacyChartHost(layers: LayerNode[]): HostSplitResult {\n const host = layers.find((l) => l.type === 'chart.host');\n if (!host || layers.some((l) => l.type === 'chart.main')) {\n return { layers, idRemap: new Map() };\n }\n\n const mainRatio = 0.65;\n const main: LayerNode = {\n ...host,\n id: `${host.id}-main`,\n type: 'chart.main',\n widgetKey: 'chartMain',\n frame: {\n x: host.frame.x,\n y: host.frame.y,\n w: host.frame.w,\n h: host.frame.h * mainRatio,\n },\n syncTimeScaleGroupId: host.syncTimeScaleGroupId,\n };\n const volume: LayerNode = {\n ...host,\n id: `${host.id}-volume`,\n type: 'chart.volume',\n widgetKey: 'chartVolume',\n frame: {\n x: host.frame.x,\n y: host.frame.y + host.frame.h * mainRatio,\n w: host.frame.w,\n h: host.frame.h * (1 - mainRatio),\n },\n zIndex: host.zIndex + 1,\n syncTimeScaleGroupId: host.syncTimeScaleGroupId,\n };\n\n const rest = layers.filter((l) => l.id !== host.id);\n const idRemap = new Map<string, string[]>([[host.id, [main.id, volume.id]]]);\n return { layers: [...rest, main, volume], idRemap };\n}\n\n/** @deprecated Use syncOverlayLayersToMain / syncAllOverlayLayersToMain */\nexport function syncCrosshairLegendToMain(layers: LayerNode[]): void {\n syncAllOverlayLayersToMain(layers);\n}\n\nexport function upgradeIndicatorHostType(layers: LayerNode[]): LayerNode[] {\n return layers.map((l) => {\n if (l.type !== 'chart.indicatorHost') return l;\n return {\n ...l,\n type: 'chart.indicator' as LayerType,\n widgetKey: l.widgetKey === 'indicatorHost' ? 'chartIndicator' : l.widgetKey,\n syncTimeScaleGroupId: l.syncTimeScaleGroupId,\n };\n });\n}","import {\n splitLegacyChartHost,\n upgradeIndicatorHostType,\n} from './chart-pane-mount.js';\nimport { ensureOverlayLayers, syncAllOverlayLayersToMain } from './overlay-mount.js';\nimport {\n LAYER_PRESET_VERSION,\n type BindGroup,\n type LayerFrame,\n type LayerNode,\n type LayerType,\n type LayoutPage,\n type LayoutPreset,\n} from './types.js';\n\nconst SHELL_TYPES: LayerType[] = [\n 'shell.topBar',\n 'shell.leftToolbar',\n 'shell.bottomToolbar',\n 'shell.statusBar',\n 'shell.propertiesPanel',\n];\n\nconst CHART_TYPES: LayerType[] = [\n 'chart.host',\n 'chart.main',\n 'chart.volume',\n 'chart.indicator',\n 'chart.indicatorHost',\n];\n\nconst OVERLAY_TYPES: LayerType[] = ['overlay.crosshairLegend', 'overlay.drawing'];\n\nfunction isLayerType(t: string): t is LayerType {\n return (\n SHELL_TYPES.includes(t as LayerType) ||\n CHART_TYPES.includes(t as LayerType) ||\n OVERLAY_TYPES.includes(t as LayerType) ||\n t === 'group'\n );\n}\n\nfunction clamp01(n: number): number {\n if (!Number.isFinite(n)) return 0;\n return Math.min(1, Math.max(0, n));\n}\n\nexport function clampFrame(frame: LayerFrame): LayerFrame {\n const w = Math.min(1, Math.max(0.02, clamp01(frame.w)));\n const h = Math.min(1, Math.max(0.02, clamp01(frame.h)));\n const x = clamp01(frame.x);\n const y = clamp01(frame.y);\n return {\n x: Math.min(x, 1 - w),\n y: Math.min(y, 1 - h),\n w,\n h,\n };\n}\n\nexport function normalizeLayoutPreset(input: LayoutPreset): LayoutPreset {\n const pages: LayoutPage[] =\n input.pages?.length > 0\n ? input.pages.map((p) => ({\n id: String(p.id || 'page-1'),\n title: String(p.title || 'Page 1'),\n }))\n : [{ id: 'page-1', title: '圖表' }];\n\n const pageIds = new Set(pages.map((p) => p.id));\n const defaultPageId = pages[0]!.id;\n\n const layers: LayerNode[] = [];\n const seenLayer = new Set<string>();\n\n for (const raw of input.layers ?? []) {\n if (!raw?.id || seenLayer.has(raw.id)) continue;\n if (!isLayerType(raw.type)) continue;\n seenLayer.add(raw.id);\n const pageId = pageIds.has(raw.pageId) ? raw.pageId : defaultPageId;\n layers.push({\n id: raw.id,\n pageId,\n type: raw.type,\n widgetKey: String(raw.widgetKey || raw.id),\n frame: clampFrame(raw.frame ?? { x: 0, y: 0, w: 1, h: 1 }),\n zIndex: Math.round(Number.isFinite(raw.zIndex) ? raw.zIndex : 0),\n visible: raw.visible !== false,\n locked: raw.locked === true,\n groupId: raw.groupId,\n syncTimeScaleGroupId: raw.syncTimeScaleGroupId,\n });\n }\n\n const { layers: splitLayers, idRemap } = splitLegacyChartHost(layers);\n let migrated = upgradeIndicatorHostType(splitLayers);\n for (const pageId of pageIds) {\n migrated = ensureOverlayLayers(migrated, pageId);\n }\n syncAllOverlayLayersToMain(migrated);\n\n migrated.sort((a, b) => a.zIndex - b.zIndex);\n migrated.forEach((l, i) => {\n l.zIndex = i;\n });\n\n const migratedIds = new Set(migrated.map((l) => l.id));\n\n const groups: BindGroup[] = [];\n const seenGroup = new Set<string>();\n for (const g of input.groups ?? []) {\n if (!g?.id || seenGroup.has(g.id)) continue;\n seenGroup.add(g.id);\n const layerIds = (g.layerIds ?? [])\n .flatMap((id) => idRemap.get(id) ?? [id])\n .filter((id) => migratedIds.has(id));\n if (layerIds.length === 0) continue;\n groups.push({\n id: g.id,\n name: g.name,\n layerIds,\n });\n }\n\n const revisionRaw = Number(input.revision);\n const revision =\n Number.isFinite(revisionRaw) && revisionRaw >= 1 ? Math.floor(revisionRaw) : 1;\n\n return {\n version: LAYER_PRESET_VERSION,\n revision,\n id: String(input.id || 'unnamed'),\n name: String(input.name || input.id || 'Untitled'),\n author: input.author === 'user' ? 'user' : 'integrator',\n readonly: input.readonly === true,\n forkedFrom: input.forkedFrom,\n pages,\n layers: migrated,\n groups,\n };\n}\n\nexport function cloneLayoutPreset(preset: LayoutPreset): LayoutPreset {\n return normalizeLayoutPreset({\n ...preset,\n pages: preset.pages.map((p) => ({ ...p })),\n layers: preset.layers.map((l) => ({ ...l, frame: { ...l.frame } })),\n groups: preset.groups.map((g) => ({ ...g, layerIds: [...g.layerIds] })),\n });\n}","import type { LayoutSchema, LayoutWidgetId } from '../layout-schema.js';\nimport { DEFAULT_LAYOUT_SCHEMA } from '../layout-schema.js';\nimport type { LayerNode, LayerType, LayoutPreset } from './types.js';\nimport { LAYER_PRESET_VERSION } from './types.js';\nimport { normalizeLayoutPreset } from './normalize.js';\n\nconst WIDGET_META: Partial<\n Record<LayoutWidgetId, { layerId: string; type: LayerType; widgetKey: string; z: number }>\n> = {\n topBar: { layerId: 'layer-topBar', type: 'shell.topBar', widgetKey: 'topBar', z: 10 },\n leftToolbar: { layerId: 'layer-leftToolbar', type: 'shell.leftToolbar', widgetKey: 'leftToolbar', z: 20 },\n indicatorHost: {\n layerId: 'layer-chartIndicator',\n type: 'chart.indicator',\n widgetKey: 'chartIndicator',\n z: 45,\n },\n statusBar: { layerId: 'layer-statusBar', type: 'shell.statusBar', widgetKey: 'statusBar', z: 50 },\n propertiesPanel: {\n layerId: 'layer-propertiesPanel',\n type: 'shell.propertiesPanel',\n widgetKey: 'propertiesPanel',\n z: 60,\n },\n bottomToolbar: { layerId: 'layer-bottomToolbar', type: 'shell.bottomToolbar', widgetKey: 'bottomToolbar', z: 70 },\n};\n\nconst MAIN_VOLUME_RATIO = 0.65;\n\nfunction chartHostLayers(\n w: LayoutSchema['widgets'][number],\n columns: number,\n rows: number,\n pageId: string,\n): LayerNode[] {\n const frame = {\n x: w.col / columns,\n y: w.row / rows,\n w: w.colSpan / columns,\n h: w.rowSpan / rows,\n };\n const mainH = frame.h * MAIN_VOLUME_RATIO;\n return [\n {\n id: 'layer-chartMain',\n pageId,\n type: 'chart.main',\n widgetKey: 'chartMain',\n frame: { x: frame.x, y: frame.y, w: frame.w, h: mainH },\n zIndex: 30,\n visible: true,\n locked: false,\n },\n {\n id: 'layer-chartVolume',\n pageId,\n type: 'chart.volume',\n widgetKey: 'chartVolume',\n frame: { x: frame.x, y: frame.y + mainH, w: frame.w, h: frame.h - mainH },\n zIndex: 35,\n visible: true,\n locked: false,\n },\n ];\n}\n\n/** Convert legacy 12×12 grid schema to normalized layer preset (single page). */\nexport function layoutSchemaToPreset(\n schema: LayoutSchema = DEFAULT_LAYOUT_SCHEMA,\n opts: { id?: string; name?: string } = {},\n): LayoutPreset {\n const columns = schema.columns || 12;\n const rows = schema.rows || 12;\n const pageId = 'page-1';\n\n const layers: LayerNode[] = [];\n for (const w of schema.widgets) {\n if (w.id === 'chartHost') {\n layers.push(...chartHostLayers(w, columns, rows, pageId));\n continue;\n }\n const meta = WIDGET_META[w.id];\n if (!meta) continue;\n layers.push({\n id: meta.layerId,\n pageId,\n type: meta.type,\n widgetKey: meta.widgetKey,\n frame: {\n x: w.col / columns,\n y: w.row / rows,\n w: w.colSpan / columns,\n h: w.rowSpan / rows,\n },\n zIndex: meta.z,\n visible: true,\n locked: false,\n\n });\n }\n\n const chartMain = layers.find((l) => l.widgetKey === 'chartMain');\n if (chartMain) {\n layers.push({\n id: 'layer-crosshairLegend',\n pageId,\n type: 'overlay.crosshairLegend',\n widgetKey: 'crosshairLegend',\n frame: {\n x: chartMain.frame.x,\n y: chartMain.frame.y,\n w: Math.min(0.35, chartMain.frame.w),\n h: Math.min(0.1, chartMain.frame.h),\n },\n zIndex: chartMain.zIndex + 5,\n visible: true,\n locked: false,\n });\n layers.push({\n id: 'layer-drawingOverlay',\n pageId,\n type: 'overlay.drawing',\n widgetKey: 'drawingOverlay',\n frame: { ...chartMain.frame },\n zIndex: chartMain.zIndex + 3,\n visible: true,\n locked: false,\n });\n }\n\n return normalizeLayoutPreset({\n version: LAYER_PRESET_VERSION,\n id: opts.id ?? 'vendor-default',\n name: opts.name ?? 'TradView 預設',\n author: 'integrator',\n readonly: false,\n pages: [{ id: pageId, title: '圖表' }],\n layers,\n groups: [],\n });\n}","import { layoutSchemaToPreset } from './grid-to-preset.js';\nimport type { LayoutPreset } from './types.js';\nimport { normalizeLayoutPreset } from './normalize.js';\n\n/** Built-in integrator preset — matches legacy DEFAULT_LAYOUT_SCHEMA proportions. */\nexport const VENDOR_DEFAULT_PRESET: LayoutPreset = layoutSchemaToPreset(undefined, {\n id: 'vendor-default',\n name: 'TradView 預設',\n});\n\n/** Compact: chart-focused, smaller chrome. */\nexport const VENDOR_COMPACT_PRESET: LayoutPreset = normalizeLayoutPreset({\n ...layoutSchemaToPreset(undefined, { id: 'vendor-compact', name: '精簡圖表' }),\n layers: layoutSchemaToPreset(undefined).layers.map((l) => {\n if (l.widgetKey === 'propertiesPanel') {\n return { ...l, visible: false, frame: { ...l.frame, w: 0.001, h: 0.001 } };\n }\n if (l.widgetKey === 'leftToolbar') {\n return { ...l, frame: { x: 0, y: 0.06, w: 0.04, h: 0.88 } };\n }\n if (l.widgetKey === 'chartMain') {\n return { ...l, frame: { x: 0.04, y: 0.06, w: 0.96, h: 0.4 } };\n }\n if (l.widgetKey === 'chartVolume') {\n return { ...l, frame: { x: 0.04, y: 0.46, w: 0.96, h: 0.16 } };\n }\n if (l.widgetKey === 'chartIndicator') {\n return { ...l, frame: { x: 0.04, y: 0.68, w: 0.96, h: 0.22 } };\n }\n return l;\n }),\n});\n\n/** Demo: main+volume share `prices`; indicator pane uses separate `osc` group. */\nexport const VENDOR_DUAL_SYNC_PRESET: LayoutPreset = normalizeLayoutPreset({\n ...layoutSchemaToPreset(undefined, { id: 'vendor-dual-sync', name: '雙時間軸分組' }),\n layers: layoutSchemaToPreset(undefined).layers.map((l) => {\n if (l.type === 'chart.main' || l.type === 'chart.volume') {\n return { ...l, syncTimeScaleGroupId: 'prices' };\n }\n if (l.type === 'chart.indicator') {\n return { ...l, syncTimeScaleGroupId: 'osc' };\n }\n return l;\n }),\n});\n\nexport const BUILTIN_PRESETS: LayoutPreset[] = [\n VENDOR_DEFAULT_PRESET,\n VENDOR_COMPACT_PRESET,\n VENDOR_DUAL_SYNC_PRESET,\n];\n\nexport function getBuiltinPreset(id: string): LayoutPreset | undefined {\n return BUILTIN_PRESETS.find((p) => p.id === id);\n}","import { getBuiltinPreset, BUILTIN_PRESETS } from './default-presets.js';\nimport { cloneLayoutPreset, normalizeLayoutPreset } from './normalize.js';\nimport type { LayoutPreset } from './types.js';\n\nconst INDEX_KEY = 'tradview:preset:v2:index';\n\nexport function presetStorageKey(id: string): string {\n return `tradview:preset:v2:${id}`;\n}\n\nexport interface PresetListEntry {\n id: string;\n name: string;\n author: LayoutPreset['author'];\n readonly?: boolean;\n builtin?: boolean;\n}\n\nfunction readIndex(): string[] {\n try {\n const raw = localStorage.getItem(INDEX_KEY);\n if (!raw) return [];\n const arr = JSON.parse(raw) as string[];\n return Array.isArray(arr) ? arr.filter((id) => typeof id === 'string') : [];\n } catch {\n return [];\n }\n}\n\nfunction writeIndex(ids: string[]): void {\n try {\n localStorage.setItem(INDEX_KEY, JSON.stringify([...new Set(ids)]));\n } catch {\n /* ignore */\n }\n}\n\nexport function listPresets(): PresetListEntry[] {\n const out: PresetListEntry[] = BUILTIN_PRESETS.map((p) => ({\n id: p.id,\n name: p.name,\n author: p.author,\n readonly: p.readonly,\n builtin: true,\n }));\n\n for (const id of readIndex()) {\n if (BUILTIN_PRESETS.some((p) => p.id === id)) continue;\n const loaded = loadPreset(id);\n if (loaded) {\n out.push({\n id: loaded.id,\n name: loaded.name,\n author: loaded.author,\n readonly: loaded.readonly,\n builtin: false,\n });\n }\n }\n return out;\n}\n\nexport function loadPreset(id: string): LayoutPreset | null {\n const builtin = getBuiltinPreset(id);\n if (builtin) return cloneLayoutPreset(builtin);\n\n try {\n const raw = localStorage.getItem(presetStorageKey(id));\n if (!raw) return null;\n return normalizeLayoutPreset(JSON.parse(raw) as LayoutPreset);\n } catch {\n return null;\n }\n}\n\nexport function savePreset(preset: LayoutPreset): void {\n const normalized = normalizeLayoutPreset(preset);\n if (getBuiltinPreset(normalized.id)) {\n throw new Error(`Cannot overwrite builtin preset: ${normalized.id}`);\n }\n try {\n localStorage.setItem(presetStorageKey(normalized.id), JSON.stringify(normalized));\n const ids = readIndex();\n if (!ids.includes(normalized.id)) {\n writeIndex([...ids, normalized.id]);\n }\n } catch {\n /* ignore */\n }\n}\n\nexport function deleteUserPreset(id: string): boolean {\n if (getBuiltinPreset(id)) return false;\n try {\n localStorage.removeItem(presetStorageKey(id));\n writeIndex(readIndex().filter((x) => x !== id));\n return true;\n } catch {\n return false;\n }\n}\n\nexport function forkPreset(\n sourceId: string,\n newId: string,\n newName: string,\n): LayoutPreset | null {\n const src = loadPreset(sourceId);\n if (!src) return null;\n const forked = normalizeLayoutPreset({\n ...cloneLayoutPreset(src),\n id: newId,\n name: newName,\n author: 'user',\n readonly: false,\n forkedFrom: sourceId,\n });\n savePreset(forked);\n return forked;\n}\n\nexport function resolvePreset(id: string | LayoutPreset | null | undefined): LayoutPreset {\n if (id && typeof id === 'object') return normalizeLayoutPreset(id);\n if (typeof id === 'string') {\n const loaded = loadPreset(id);\n if (loaded) return loaded;\n }\n return cloneLayoutPreset(getBuiltinPreset('vendor-default')!);\n}","import { clampFrame } from './normalize.js';\nimport type { LayerFrame, LayerNode } from './types.js';\n\n/** Union bounding box of layer frames (normalized 0..1). */\nexport function getLayersBoundingBox(layers: Pick<LayerNode, 'frame'>[]): LayerFrame | null {\n if (layers.length === 0) return null;\n let minX = 1;\n let minY = 1;\n let maxX = 0;\n let maxY = 0;\n for (const l of layers) {\n const f = l.frame;\n minX = Math.min(minX, f.x);\n minY = Math.min(minY, f.y);\n maxX = Math.max(maxX, f.x + f.w);\n maxY = Math.max(maxY, f.y + f.h);\n }\n const w = maxX - minX;\n const h = maxY - minY;\n if (w <= 0 || h <= 0) return null;\n return { x: minX, y: minY, w, h };\n}\n\n/** Move all frames by normalized delta; each frame is clamped independently. */\nexport function moveLayerFrames(\n frames: LayerFrame[],\n dx: number,\n dy: number,\n): LayerFrame[] {\n return frames.map((f) =>\n clampFrame({\n ...f,\n x: f.x + dx,\n y: f.y + dy,\n }),\n );\n}\n\n/**\n * Resize a group by mapping each member's relative position inside oldBbox into newBbox.\n */\nexport function resizeGroupFrames(\n members: Pick<LayerNode, 'frame'>[],\n oldBbox: LayerFrame,\n newBbox: LayerFrame,\n): LayerFrame[] {\n const ow = Math.max(oldBbox.w, 0.02);\n const oh = Math.max(oldBbox.h, 0.02);\n const nw = Math.max(newBbox.w, 0.02);\n const nh = Math.max(newBbox.h, 0.02);\n return members.map((m) => {\n const f = m.frame;\n const relX = (f.x - oldBbox.x) / ow;\n const relY = (f.y - oldBbox.y) / oh;\n const relW = f.w / ow;\n const relH = f.h / oh;\n return clampFrame({\n x: newBbox.x + relX * nw,\n y: newBbox.y + relY * nh,\n w: relW * nw,\n h: relH * nh,\n });\n });\n}\n\nexport function clampBBox(frame: LayerFrame): LayerFrame {\n return clampFrame(frame);\n}","import { isChartPaneLayerType, paneIdFromWidgetKey } from './chart-pane-mount.js';\nimport { syncOverlayLayersToMain } from './overlay-mount.js';\nimport { clampFrame, cloneLayoutPreset } from './normalize.js';\nimport {\n getLayersBoundingBox,\n moveLayerFrames,\n resizeGroupFrames,\n} from './group-utils.js';\nimport type { BindGroup, LayerFrame, LayoutPreset } from './types.js';\n\n/** @public Mutable controller for LayoutPreset v2 (layers, groups, pane focus). */\nexport class LayerController {\n private preset: LayoutPreset;\n private readonly listeners = new Set<() => void>();\n private readonly focusListeners = new Set<() => void>();\n private interactionDepth = 0;\n private pageIdSeq = 0;\n activePageId: string;\n /** P2: active chart pane layer (click-to-focus). */\n focusedPaneLayerId: string | null = null;\n /** Monotonic preset revision (Bridge `host.layer.setPreset`). */\n presetRevision: number;\n\n constructor(initial: LayoutPreset) {\n this.preset = cloneLayoutPreset(initial);\n this.presetRevision = this.preset.revision ?? 1;\n this.activePageId = this.preset.pages[0]?.id ?? 'page-1';\n }\n\n getPreset(): LayoutPreset {\n return cloneLayoutPreset(this.preset);\n }\n\n /** True while pointer drag/resize/marquee is active — blocks setPreset. */\n isInteracting(): boolean {\n return this.interactionDepth > 0;\n }\n\n beginInteraction(): void {\n this.interactionDepth++;\n }\n\n endInteraction(): void {\n this.interactionDepth = Math.max(0, this.interactionDepth - 1);\n }\n\n setPreset(next: LayoutPreset): boolean {\n if (this.isInteracting()) return false;\n this.preset = cloneLayoutPreset(next);\n this.presetRevision = this.preset.revision ?? 1;\n if (!this.preset.pages.some((p) => p.id === this.activePageId)) {\n this.activePageId = this.preset.pages[0]?.id ?? 'page-1';\n }\n this.emit();\n return true;\n }\n\n getLayersForActivePage(): LayoutPreset['layers'] {\n return this.preset.layers\n .filter((l) => l.pageId === this.activePageId)\n .sort((a, b) => a.zIndex - b.zIndex);\n }\n\n getFocusedPaneLayerId(): string | null {\n return this.focusedPaneLayerId;\n }\n\n getFocusedPaneId(): 'main' | 'volume' | 'indicator' | null {\n const layer = this.focusedPaneLayerId\n ? this.getLayer(this.focusedPaneLayerId)\n : undefined;\n return layer ? paneIdFromWidgetKey(layer.widgetKey) : null;\n }\n\n /** Raise z-index among chart panes only; does not rebuild compositor DOM. */\n focusChartPane(layerId: string): void {\n const layer = this.getLayer(layerId);\n if (!layer || layer.pageId !== this.activePageId || !isChartPaneLayerType(layer.type)) {\n return;\n }\n if (this.focusedPaneLayerId === layerId) return;\n this.focusedPaneLayerId = layerId;\n const chartLayers = this.getLayersForActivePage().filter((l) =>\n isChartPaneLayerType(l.type),\n );\n const maxZ = Math.max(...chartLayers.map((l) => l.zIndex), layer.zIndex);\n const FOCUS_Z_CAP = 500;\n if (layer.zIndex < maxZ) layer.zIndex = Math.min(maxZ + 1, FOCUS_Z_CAP);\n this.notifyFocus();\n }\n\n subscribeFocus(listener: () => void): () => void {\n this.focusListeners.add(listener);\n return () => this.focusListeners.delete(listener);\n }\n\n private notifyFocus(): void {\n for (const fn of this.focusListeners) fn();\n }\n\n private afterChartMainFrameChange(pageIds?: Iterable<string>): void {\n const ids = pageIds\n ? [...new Set(pageIds)]\n : [...new Set(this.preset.layers.map((l) => l.pageId))];\n for (const pageId of ids) {\n syncOverlayLayersToMain(this.preset.layers, pageId);\n }\n }\n\n setActivePage(pageId: string): boolean {\n if (!this.preset.pages.some((p) => p.id === pageId)) return false;\n if (this.activePageId === pageId) return false;\n this.activePageId = pageId;\n this.focusedPaneLayerId = null;\n this.emit();\n this.notifyFocus();\n return true;\n }\n\n addPage(title?: string): string {\n const suffix =\n typeof crypto !== 'undefined' && 'randomUUID' in crypto\n ? crypto.randomUUID()\n : `${Date.now()}-${++this.pageIdSeq}`;\n const id = `page-${suffix}`;\n const pageTitle = title?.trim() || `Page ${this.preset.pages.length + 1}`;\n this.preset.pages.push({ id, title: pageTitle });\n const templatePageId = this.activePageId;\n const templateLayers = this.preset.layers.filter((l) => l.pageId === templatePageId);\n const maxZ = Math.max(-1, ...this.preset.layers.map((l) => l.zIndex));\n let z = maxZ + 1;\n for (const tpl of templateLayers) {\n this.preset.layers.push({\n ...tpl,\n id: `${tpl.id}-${id}`,\n pageId: id,\n frame: { ...tpl.frame },\n zIndex: z++,\n groupId: undefined,\n });\n }\n this.activePageId = id;\n this.focusedPaneLayerId = null;\n this.emit();\n return id;\n }\n\n renamePage(pageId: string, title: string): boolean {\n const page = this.preset.pages.find((p) => p.id === pageId);\n if (!page) return false;\n const trimmed = title.trim();\n if (!trimmed) return false;\n page.title = trimmed;\n this.emit();\n return true;\n }\n\n removePage(pageId: string): boolean {\n if (this.preset.pages.length <= 1) return false;\n const idx = this.preset.pages.findIndex((p) => p.id === pageId);\n if (idx < 0) return false;\n this.preset.pages.splice(idx, 1);\n this.preset.layers = this.preset.layers.filter((l) => l.pageId !== pageId);\n for (const g of [...this.preset.groups]) {\n g.layerIds = g.layerIds.filter((lid) => this.getLayer(lid)?.pageId !== pageId);\n if (g.layerIds.length === 0) {\n this.preset.groups = this.preset.groups.filter((x) => x.id !== g.id);\n }\n }\n if (this.activePageId === pageId) {\n const nextPage = this.preset.pages[idx] ?? this.preset.pages[idx - 1];\n this.activePageId = nextPage?.id ?? this.preset.pages[0]!.id;\n this.focusedPaneLayerId = null;\n }\n this.emit();\n return true;\n }\n\n getLayer(layerId: string) {\n return this.preset.layers.find((l) => l.id === layerId);\n }\n\n /**\n * @public Set time-scale sync group for a chart pane layer (`''` clears → independent).\n */\n setLayerSyncGroup(layerId: string, groupId: string | null | undefined): boolean {\n const layer = this.getLayer(layerId);\n if (!layer || !isChartPaneLayerType(layer.type)) return false;\n const trimmed = groupId == null ? '' : String(groupId).trim();\n layer.syncTimeScaleGroupId = trimmed.length > 0 ? trimmed : undefined;\n this.emit();\n return true;\n }\n\n getGroup(groupId: string): BindGroup | undefined {\n return this.preset.groups.find((g) => g.id === groupId);\n }\n\n /** Layer ids that move/resize together (group members or singleton). */\n getTransformLayerIds(layerId: string): string[] {\n const layer = this.getLayer(layerId);\n if (!layer?.groupId) return [layerId];\n const group = this.getGroup(layer.groupId);\n if (!group || group.layerIds.length === 0) return [layerId];\n return group.layerIds.filter((id) => {\n const l = this.getLayer(id);\n return l && l.pageId === this.activePageId && !l.locked;\n });\n }\n\n getGroupMemberLayers(groupId: string): LayoutPreset['layers'] {\n const group = this.getGroup(groupId);\n if (!group) return [];\n return group.layerIds\n .map((id) => this.getLayer(id))\n .filter((l): l is NonNullable<typeof l> => !!l && l.pageId === this.activePageId);\n }\n\n setLayerFrame(layerId: string, frame: LayerFrame): void {\n const ids = this.getTransformLayerIds(layerId);\n if (ids.length === 1) {\n const layer = this.getLayer(layerId);\n if (!layer) return;\n layer.frame = clampFrame(frame);\n if (layer.type === 'overlay.drawing') {\n const main = this.preset.layers.find(\n (l) => l.type === 'chart.main' && l.pageId === layer.pageId,\n );\n if (main) main.frame = clampFrame(frame);\n }\n if (layer.type === 'chart.main' || layer.type === 'overlay.drawing') {\n this.afterChartMainFrameChange([layer.pageId]);\n }\n this.emit();\n return;\n }\n const members = ids.map((id) => this.getLayer(id)!).filter(Boolean);\n const oldBbox = getLayersBoundingBox(members);\n if (!oldBbox) return;\n const target = frame;\n const newFrames = resizeGroupFrames(members, oldBbox, target);\n members.forEach((m, i) => {\n m.frame = newFrames[i]!;\n });\n if (members.some((m) => m.type === 'chart.main' || m.type === 'overlay.drawing')) {\n this.afterChartMainFrameChange(members.map((m) => m.pageId));\n }\n this.emit();\n }\n\n private expandTransformIds(layerIds: string[]): string[] {\n const expanded = new Set<string>();\n for (const id of layerIds) {\n for (const tid of this.getTransformLayerIds(id)) expanded.add(tid);\n }\n return [...expanded];\n }\n\n moveLayers(layerIds: string[], dx: number, dy: number): void {\n const unique = this.expandTransformIds(layerIds);\n const layers = unique.map((id) => this.getLayer(id)).filter(Boolean) as LayoutPreset['layers'];\n if (layers.length === 0) return;\n const frames = moveLayerFrames(\n layers.map((l) => l.frame),\n dx,\n dy,\n );\n layers.forEach((l, i) => {\n l.frame = frames[i]!;\n });\n if (\n layers.some((l) => l.type === 'chart.main' || l.type === 'overlay.drawing')\n ) {\n this.afterChartMainFrameChange(layers.map((l) => l.pageId));\n }\n this.emit();\n }\n\n resizeLayersFromBbox(layerIds: string[], newBbox: LayerFrame): void {\n const unique = this.expandTransformIds(layerIds);\n const members = unique\n .map((id) => this.getLayer(id))\n .filter((l): l is NonNullable<typeof l> => !!l);\n if (members.length === 0) return;\n if (members.length === 1) {\n members[0]!.frame = clampFrame(newBbox);\n if (\n members[0]!.type === 'chart.main' ||\n members[0]!.type === 'overlay.drawing'\n ) {\n this.afterChartMainFrameChange([members[0]!.pageId]);\n }\n this.emit();\n return;\n }\n const oldBbox = getLayersBoundingBox(members);\n if (!oldBbox) return;\n const newFrames = resizeGroupFrames(members, oldBbox, newBbox);\n members.forEach((m, i) => {\n m.frame = newFrames[i]!;\n });\n if (members.some((m) => m.type === 'chart.main' || m.type === 'overlay.drawing')) {\n this.afterChartMainFrameChange(members.map((m) => m.pageId));\n }\n this.emit();\n }\n\n setLayerVisible(layerId: string, visible: boolean): void {\n const ids = this.syncGroupLayerIds(layerId);\n for (const id of ids) {\n const layer = this.getLayer(id);\n if (layer) layer.visible = visible;\n }\n this.emit();\n }\n\n setLayerLocked(layerId: string, locked: boolean): void {\n const ids = this.syncGroupLayerIds(layerId);\n for (const id of ids) {\n const layer = this.getLayer(id);\n if (layer) layer.locked = locked;\n }\n this.emit();\n }\n\n private syncGroupLayerIds(layerId: string): string[] {\n const layer = this.getLayer(layerId);\n if (!layer?.groupId) return [layerId];\n const group = this.getGroup(layer.groupId);\n if (!group?.layerIds.length) return [layerId];\n const onPage = group.layerIds.filter((id) => {\n const l = this.getLayer(id);\n return l && l.pageId === this.activePageId;\n });\n return onPage.length > 0 ? onPage : [layerId];\n }\n\n bumpZIndex(layerId: string, delta: 1 | -1): void {\n const ordered = this.getLayersForActivePage();\n const idx = ordered.findIndex((l) => l.id === layerId);\n if (idx < 0) return;\n const swap = idx + delta;\n if (swap < 0 || swap >= ordered.length) return;\n const a = ordered[idx]!;\n const b = ordered[swap]!;\n const tz = a.zIndex;\n a.zIndex = b.zIndex;\n b.zIndex = tz;\n this.preset.layers.sort((x, y) => x.zIndex - y.zIndex);\n this.preset.layers.forEach((l, i) => {\n l.zIndex = i;\n });\n this.emit();\n }\n\n reorderLayers(orderedIds: string[]): void {\n const pageLayers = this.preset.layers.filter((l) => l.pageId === this.activePageId);\n const byId = new Map(pageLayers.map((l) => [l.id, l]));\n let z = 0;\n for (const id of orderedIds) {\n const layer = byId.get(id);\n if (layer) layer.zIndex = z++;\n }\n for (const layer of pageLayers) {\n if (!orderedIds.includes(layer.id)) layer.zIndex = z++;\n }\n this.preset.layers.sort((a, b) => a.zIndex - b.zIndex);\n this.emit();\n }\n\n createBindGroup(layerIds: string[], name?: string): string | null {\n const unique = [...new Set(layerIds)].filter((id) => {\n const l = this.getLayer(id);\n return l && l.pageId === this.activePageId;\n });\n if (unique.length < 2) return null;\n\n for (const g of this.preset.groups) {\n for (const id of unique) {\n const idx = g.layerIds.indexOf(id);\n if (idx >= 0) g.layerIds.splice(idx, 1);\n }\n if (g.layerIds.length === 0) {\n this.preset.groups = this.preset.groups.filter((x) => x.id !== g.id);\n }\n }\n\n for (const id of unique) {\n const layer = this.getLayer(id);\n if (layer) delete layer.groupId;\n }\n\n const groupId = `group-${Date.now()}`;\n const group: BindGroup = { id: groupId, name, layerIds: unique };\n this.preset.groups.push(group);\n for (const id of unique) {\n const layer = this.getLayer(id);\n if (layer) layer.groupId = groupId;\n }\n this.emit();\n return groupId;\n }\n\n dissolveGroup(groupId: string): void {\n const group = this.getGroup(groupId);\n if (!group) return;\n for (const id of group.layerIds) {\n const layer = this.getLayer(id);\n if (layer?.groupId === groupId) delete layer.groupId;\n }\n this.preset.groups = this.preset.groups.filter((g) => g.id !== groupId);\n this.emit();\n }\n\n removeLayerFromGroup(layerId: string): void {\n const layer = this.getLayer(layerId);\n if (!layer?.groupId) return;\n const groupId = layer.groupId;\n delete layer.groupId;\n const group = this.getGroup(groupId);\n if (!group) return;\n group.layerIds = group.layerIds.filter((id) => id !== layerId);\n if (group.layerIds.length === 0) {\n this.preset.groups = this.preset.groups.filter((g) => g.id !== groupId);\n }\n this.emit();\n }\n\n subscribe(listener: () => void): () => void {\n this.listeners.add(listener);\n return () => this.listeners.delete(listener);\n }\n\n private emit(): void {\n for (const fn of this.listeners) fn();\n }\n}","import type { LayerController } from './layer-controller.js';\nimport { getLayersBoundingBox, resizeGroupFrames } from './group-utils.js';\nimport { clampFrame } from './normalize.js';\nimport type { LayerFrame } from './types.js';\n\nexport interface LayerEditorOptions {\n controller: LayerController;\n /** Called after drag/resize commits preset changes. */\n onPresetChange?: () => void;\n /** Shift+drag marquee selection on compositor root. */\n onMarqueeSelect?: (layerIds: string[]) => void;\n}\n\nexport interface LayerEditorHandle {\n setEnabled(enabled: boolean): void;\n isEnabled(): boolean;\n rebind(): void;\n destroy(): void;\n}\n\ntype ResizeHandle = 'nw' | 'ne' | 'sw' | 'se';\n\nconst HANDLE_CURSORS: Record<ResizeHandle, string> = {\n nw: 'nwse-resize',\n ne: 'nesw-resize',\n sw: 'nesw-resize',\n se: 'nwse-resize',\n};\n\nconst EPS = 1e-6;\n\nfunction framesEqual(a: LayerFrame, b: LayerFrame, eps = EPS): boolean {\n return (\n Math.abs(a.x - b.x) < eps &&\n Math.abs(a.y - b.y) < eps &&\n Math.abs(a.w - b.w) < eps &&\n Math.abs(a.h - b.h) < eps\n );\n}\n\nfunction frameIntersects(a: LayerFrame, b: LayerFrame): boolean {\n return a.x < b.x + b.w && a.x + a.w > b.x && a.y < b.y + b.h && a.y + a.h > b.y;\n}\n\n/** Let wrap receive drag/resize; LWC and buttons live inside children. */\nfunction setWrapContentPassthrough(wrap: HTMLElement, passthrough: boolean): void {\n for (const child of wrap.children) {\n if ((child as HTMLElement).classList.contains('tv-layer-handle')) continue;\n (child as HTMLElement).style.pointerEvents = passthrough ? 'none' : '';\n }\n}\n\nfunction clearWrapContentPassthrough(wrap: HTMLElement): void {\n for (const child of wrap.children) {\n if ((child as HTMLElement).classList.contains('tv-layer-handle')) continue;\n (child as HTMLElement).style.pointerEvents = '';\n }\n}\n\nexport function attachLayerEditor(\n compositorRoot: HTMLElement,\n opts: LayerEditorOptions,\n): LayerEditorHandle {\n const { controller, onPresetChange, onMarqueeSelect } = opts;\n let enabled = false;\n let abort: AbortController | null = null;\n let captureEl: HTMLElement | null = null;\n let capturePointerId: number | null = null;\n\n const releaseCapture = () => {\n if (captureEl && capturePointerId !== null) {\n try {\n captureEl.releasePointerCapture(capturePointerId);\n } catch {\n /* already released */\n }\n }\n if (capturePointerId !== null && controller.isInteracting()) {\n controller.endInteraction();\n }\n captureEl = null;\n capturePointerId = null;\n };\n\n const setCapture = (el: HTMLElement, pointerId: number) => {\n releaseCapture();\n captureEl = el;\n capturePointerId = pointerId;\n controller.beginInteraction();\n try {\n el.setPointerCapture(pointerId);\n } catch {\n controller.endInteraction();\n captureEl = null;\n capturePointerId = null;\n }\n };\n\n const normDelta = (dxPx: number, dyPx: number) => {\n const w = compositorRoot.clientWidth || 1;\n const h = compositorRoot.clientHeight || 1;\n return { dx: dxPx / w, dy: dyPx / h };\n };\n\n const applyWrapStyle = (wrap: HTMLElement, frame: LayerFrame) => {\n wrap.style.left = `${frame.x * 100}%`;\n wrap.style.top = `${frame.y * 100}%`;\n wrap.style.width = `${frame.w * 100}%`;\n wrap.style.height = `${frame.h * 100}%`;\n };\n\n const decorateWrap = (wrap: HTMLElement, layerId: string) => {\n wrap.querySelectorAll('.tv-layer-handle').forEach((el) => el.remove());\n const layer = controller.getLayer(layerId);\n if (!layer || layer.locked) {\n wrap.classList.remove('tv-layer-editable');\n wrap.style.cursor = '';\n wrap.style.outline = '';\n clearWrapContentPassthrough(wrap);\n return;\n }\n wrap.classList.add('tv-layer-editable');\n wrap.style.cursor = 'move';\n setWrapContentPassthrough(wrap, true);\n if (wrap.dataset.focused === '1') {\n wrap.style.outline = '2px solid #58a6ff';\n wrap.style.outlineOffset = '-2px';\n } else {\n wrap.style.outline = '1px dashed #58a6ff88';\n wrap.style.outlineOffset = '';\n }\n\n const handles: ResizeHandle[] = ['nw', 'ne', 'sw', 'se'];\n for (const h of handles) {\n const handle = document.createElement('div');\n handle.className = `tv-layer-handle tv-layer-handle-${h}`;\n handle.dataset.handle = h;\n handle.style.cssText = [\n 'position:absolute',\n 'width:8px',\n 'height:8px',\n 'background:#58a6ff',\n 'border:1px solid #0d1117',\n 'border-radius:2px',\n 'z-index:2',\n `cursor:${HANDLE_CURSORS[h]}`,\n h.includes('n') ? 'top:-4px' : 'bottom:-4px',\n h.includes('w') ? 'left:-4px' : 'right:-4px',\n ].join(';');\n wrap.appendChild(handle);\n }\n };\n\n const commitChange = () => {\n onPresetChange?.();\n };\n\n const computeResizeBbox = (\n startBbox: LayerFrame,\n corner: ResizeHandle,\n dx: number,\n dy: number,\n ): LayerFrame => {\n const newBbox = { ...startBbox };\n if (corner.includes('e')) newBbox.w = startBbox.w + dx;\n if (corner.includes('w')) {\n newBbox.x = startBbox.x + dx;\n newBbox.w = startBbox.w - dx;\n }\n if (corner.includes('s')) newBbox.h = startBbox.h + dy;\n if (corner.includes('n')) {\n newBbox.y = startBbox.y + dy;\n newBbox.h = startBbox.h - dy;\n }\n return clampFrame(newBbox);\n };\n\n const bindMarquee = (signal: AbortSignal) => {\n compositorRoot.addEventListener(\n 'pointerdown',\n (e) => {\n if (!e.shiftKey) return;\n if ((e.target as HTMLElement).closest('.tv-layer-wrap')) return;\n e.preventDefault();\n const rootRect = compositorRoot.getBoundingClientRect();\n const startX = e.clientX;\n const startY = e.clientY;\n const marquee = document.createElement('div');\n marquee.className = 'tv-layer-marquee';\n marquee.style.cssText =\n 'position:absolute;border:1px dashed #58a6ff;background:#58a6ff22;pointer-events:none;z-index:9999;';\n compositorRoot.appendChild(marquee);\n setCapture(compositorRoot, e.pointerId);\n\n const updateMarquee = (cx: number, cy: number) => {\n const x1 = Math.min(startX, cx) - rootRect.left;\n const y1 = Math.min(startY, cy) - rootRect.top;\n const x2 = Math.max(startX, cx) - rootRect.left;\n const y2 = Math.max(startY, cy) - rootRect.top;\n marquee.style.left = `${x1}px`;\n marquee.style.top = `${y1}px`;\n marquee.style.width = `${x2 - x1}px`;\n marquee.style.height = `${y2 - y1}px`;\n };\n\n const onMove = (ev: PointerEvent) => updateMarquee(ev.clientX, ev.clientY);\n\n const onUp = (ev: PointerEvent) => {\n releaseCapture();\n compositorRoot.removeEventListener('pointermove', onMove);\n compositorRoot.removeEventListener('pointerup', onUp);\n compositorRoot.removeEventListener('pointercancel', onUp);\n const w = compositorRoot.clientWidth || 1;\n const h = compositorRoot.clientHeight || 1;\n const sel: LayerFrame = clampFrame({\n x: (Math.min(startX, ev.clientX) - rootRect.left) / w,\n y: (Math.min(startY, ev.clientY) - rootRect.top) / h,\n w: Math.abs(ev.clientX - startX) / w,\n h: Math.abs(ev.clientY - startY) / h,\n });\n marquee.remove();\n if (sel.w < EPS && sel.h < EPS) return;\n const hits = controller\n .getLayersForActivePage()\n .filter((l) => frameIntersects(l.frame, sel))\n .map((l) => l.id);\n if (hits.length > 0) onMarqueeSelect?.(hits);\n };\n\n updateMarquee(startX, startY);\n compositorRoot.addEventListener('pointermove', onMove, { signal });\n compositorRoot.addEventListener('pointerup', onUp, { signal });\n compositorRoot.addEventListener('pointercancel', onUp, { signal });\n },\n { signal },\n );\n };\n\n const bindWrap = (wrap: HTMLElement, signal: AbortSignal) => {\n const layerId = wrap.dataset.layerId;\n if (!layerId) return;\n const layer = controller.getLayer(layerId);\n if (!layer || layer.locked) return;\n\n const transformIds = () => controller.getTransformLayerIds(layerId);\n\n const onPointerDownMove = (e: PointerEvent) => {\n if ((e.target as HTMLElement).classList.contains('tv-layer-handle')) return;\n e.preventDefault();\n e.stopPropagation();\n const ids = transformIds();\n const members = ids.map((id) => controller.getLayer(id)!).filter(Boolean);\n const startFrames = members.map((m) => ({ ...m.frame }));\n const startX = e.clientX;\n const startY = e.clientY;\n setCapture(wrap, e.pointerId);\n wrap.classList.add('tv-layer-dragging');\n\n const onMove = (ev: PointerEvent) => {\n const { dx, dy } = normDelta(ev.clientX - startX, ev.clientY - startY);\n const moved = startFrames.map((f) =>\n clampFrame({ ...f, x: f.x + dx, y: f.y + dy }),\n );\n compositorRoot.querySelectorAll('.tv-layer-wrap').forEach((el) => {\n const w = el as HTMLElement;\n const lid = w.dataset.layerId;\n if (!lid || !ids.includes(lid)) return;\n const idx = ids.indexOf(lid);\n if (idx >= 0) applyWrapStyle(w, moved[idx]!);\n });\n };\n\n const onUp = (ev: PointerEvent) => {\n releaseCapture();\n wrap.classList.remove('tv-layer-dragging');\n wrap.removeEventListener('pointermove', onMove);\n wrap.removeEventListener('pointerup', onUp);\n wrap.removeEventListener('pointercancel', onUp);\n const { dx, dy } = normDelta(ev.clientX - startX, ev.clientY - startY);\n if (Math.abs(dx) > EPS || Math.abs(dy) > EPS) {\n controller.moveLayers(ids, dx, dy);\n commitChange();\n }\n };\n\n wrap.addEventListener('pointermove', onMove, { signal });\n wrap.addEventListener('pointerup', onUp, { signal });\n wrap.addEventListener('pointercancel', onUp, { signal });\n };\n\n wrap.addEventListener('pointerdown', onPointerDownMove, { signal });\n\n wrap.querySelectorAll('.tv-layer-handle').forEach((handleEl) => {\n const handle = handleEl as HTMLElement;\n const corner = handle.dataset.handle as ResizeHandle;\n handle.addEventListener(\n 'pointerdown',\n (e) => {\n e.preventDefault();\n e.stopPropagation();\n const ids = transformIds();\n const members = ids.map((id) => controller.getLayer(id)!).filter(Boolean);\n let startBbox: LayerFrame | null;\n if (members.length === 1) {\n startBbox = { ...members[0]!.frame };\n } else {\n startBbox = getLayersBoundingBox(members);\n }\n if (!startBbox) return;\n const startX = e.clientX;\n const startY = e.clientY;\n setCapture(handle, e.pointerId);\n\n const onMove = (ev: PointerEvent) => {\n const { dx, dy } = normDelta(ev.clientX - startX, ev.clientY - startY);\n const newBbox = computeResizeBbox(startBbox!, corner, dx, dy);\n\n if (ids.length === 1) {\n applyWrapStyle(wrap, newBbox);\n } else {\n const resized = resizeGroupFrames(members, startBbox!, newBbox);\n compositorRoot.querySelectorAll('.tv-layer-wrap').forEach((el) => {\n const w = el as HTMLElement;\n const lid = w.dataset.layerId;\n if (!lid || !ids.includes(lid)) return;\n const idx = ids.indexOf(lid);\n if (idx >= 0) applyWrapStyle(w, resized[idx]!);\n });\n }\n };\n\n const onUp = (ev: PointerEvent) => {\n releaseCapture();\n handle.removeEventListener('pointermove', onMove);\n handle.removeEventListener('pointerup', onUp);\n handle.removeEventListener('pointercancel', onUp);\n const { dx, dy } = normDelta(ev.clientX - startX, ev.clientY - startY);\n const newBbox = computeResizeBbox(startBbox, corner, dx, dy);\n if (!framesEqual(newBbox, startBbox) && (Math.abs(dx) > EPS || Math.abs(dy) > EPS)) {\n controller.resizeLayersFromBbox(ids, newBbox);\n commitChange();\n }\n };\n\n handle.addEventListener('pointermove', onMove, { signal });\n handle.addEventListener('pointerup', onUp, { signal });\n handle.addEventListener('pointercancel', onUp, { signal });\n },\n { signal },\n );\n });\n };\n\n const cleanupEditChrome = () => {\n compositorRoot.classList.remove('tv-layer-edit-mode');\n compositorRoot.querySelectorAll('.tv-layer-marquee').forEach((el) => el.remove());\n compositorRoot.querySelectorAll('.tv-layer-wrap').forEach((w) => {\n const el = w as HTMLElement;\n el.classList.remove('tv-layer-editable', 'tv-layer-dragging');\n el.style.outline = '';\n el.style.cursor = '';\n el.querySelectorAll('.tv-layer-handle').forEach((h) => h.remove());\n clearWrapContentPassthrough(el);\n });\n compositorRoot.style.zIndex = '';\n };\n\n const rebind = () => {\n releaseCapture();\n abort?.abort();\n if (!enabled) {\n cleanupEditChrome();\n return;\n }\n compositorRoot.classList.add('tv-layer-edit-mode');\n compositorRoot.style.zIndex = '80';\n abort = new AbortController();\n const { signal } = abort;\n bindMarquee(signal);\n compositorRoot.querySelectorAll('.tv-layer-wrap').forEach((w) => {\n const wrap = w as HTMLElement;\n const layerId = wrap.dataset.layerId;\n if (!layerId) return;\n decorateWrap(wrap, layerId);\n bindWrap(wrap, signal);\n });\n };\n\n return {\n setEnabled(next: boolean) {\n enabled = next;\n rebind();\n },\n isEnabled: () => enabled,\n rebind,\n destroy: () => {\n enabled = false;\n releaseCapture();\n abort?.abort();\n cleanupEditChrome();\n },\n };\n}","import { isChartPaneLayerType } from './chart-pane-mount.js';\nimport { isOverlayLayerType } from './overlay-mount.js';\nimport type { LayerWidgetKey } from './types.js';\nimport { LayerController } from './layer-controller.js';\nimport type { LayerNode, LayoutPreset } from './types.js';\nimport { attachLayerEditor } from './layer-editor.js';\n\nexport type LayerWidgetElements = Partial<Record<LayerWidgetKey, HTMLElement>>;\n\nexport interface LayerCompositorOptions {\n preset: LayoutPreset;\n widgets: LayerWidgetElements;\n /** Hide legacy grid container when compositor positions widgets. */\n hideLegacyGrid?: HTMLElement;\n /** Fired after user drag/resize commits a preset change. */\n onPresetChange?: (preset: LayoutPreset) => void;\n /** Shift+drag marquee on compositor root (edit mode). */\n onMarqueeSelect?: (layerIds: string[]) => void;\n /** P2: chart pane focus changed (main / volume / indicator). */\n onChartPaneFocus?: (pane: 'main' | 'volume' | 'indicator' | null) => void;\n}\n\nexport interface LayerCompositorHandle {\n root: HTMLElement;\n controller: LayerController;\n apply(): void;\n enableLayerEditor(enabled: boolean): void;\n isLayerEditorEnabled(): boolean;\n destroy(): void;\n}\n\nfunction resolveWidgetEl(\n widgets: LayerWidgetElements,\n layer: LayerNode,\n): HTMLElement | undefined {\n const key = layer.widgetKey as LayerWidgetKey;\n if (layer.type === 'overlay.drawing') {\n return widgets.drawingOverlay ?? widgets.chartMain ?? widgets.chartHost;\n }\n return (\n widgets[key] ??\n (layer.widgetKey === 'chartMain' ? widgets.chartHost : undefined) ??\n (layer.widgetKey === 'chartIndicator' ? widgets.indicatorHost : undefined)\n );\n}\n\nfunction applyWrapFrame(wrap: HTMLElement, layer: LayerNode): void {\n wrap.style.left = `${layer.frame.x * 100}%`;\n wrap.style.top = `${layer.frame.y * 100}%`;\n wrap.style.width = `${layer.frame.w * 100}%`;\n wrap.style.height = `${layer.frame.h * 100}%`;\n wrap.style.zIndex = String(layer.zIndex + 1);\n}\n\nfunction layerStructureSignature(layers: LayerNode[], activePageId: string): string {\n return `${activePageId}|${layers\n .map((l) => `${l.id}:${l.type}:${l.widgetKey}:${l.visible}:${l.locked}`)\n .join('|')}`;\n}\n\nfunction wrapPointerEventsForLayer(layer: LayerNode, editorEnabled: boolean): string {\n if (layer.locked) return 'none';\n if (isOverlayLayerType(layer.type)) return 'none';\n if (isChartPaneLayerType(layer.type) && editorEnabled) return 'none';\n return 'auto';\n}\n\n/** @public Mount floating layer compositor (LayoutPreset v2) over shell widgets. */\nexport function mountLayerCompositor(\n parent: HTMLElement,\n opts: LayerCompositorOptions,\n): LayerCompositorHandle {\n const controller = new LayerController(opts.preset);\n const wrappers = new Map<string, HTMLElement>();\n let lastStructureSig = '';\n\n const root = document.createElement('div');\n root.className = 'tv-layer-compositor';\n root.style.cssText =\n 'position:absolute;inset:0;overflow:hidden;pointer-events:none;z-index:5;';\n parent.style.position = parent.style.position || 'relative';\n parent.appendChild(root);\n\n const editor = attachLayerEditor(root, {\n controller,\n onPresetChange: () => opts.onPresetChange?.(controller.getPreset()),\n onMarqueeSelect: opts.onMarqueeSelect,\n });\n\n const applyFocusStyles = () => {\n const focused = controller.focusedPaneLayerId;\n for (const [id, wrap] of wrappers) {\n const layer = controller.getLayer(id);\n if (!layer || !isChartPaneLayerType(layer.type)) continue;\n const active = id === focused;\n wrap.dataset.focused = active ? '1' : '0';\n wrap.style.outline = active ? '2px solid #58a6ff' : 'none';\n wrap.style.outlineOffset = active ? '-2px' : '';\n }\n };\n\n const patchFocusVisuals = (layers: LayerNode[]) => {\n for (const layer of layers) {\n const wrap = wrappers.get(layer.id);\n if (wrap) applyWrapFrame(wrap, layer);\n }\n applyFocusStyles();\n };\n\n const patchLayoutFrames = (layers: LayerNode[], patchOpts: { rebind?: boolean } = {}) => {\n patchFocusVisuals(layers);\n if (patchOpts.rebind !== false) editor.rebind();\n };\n\n const ensureDefaultChartFocus = (chartPaneIds: string[]) => {\n if (\n controller.focusedPaneLayerId &&\n !chartPaneIds.includes(controller.focusedPaneLayerId)\n ) {\n controller.focusedPaneLayerId = chartPaneIds[chartPaneIds.length - 1] ?? null;\n }\n if (!controller.focusedPaneLayerId && chartPaneIds.length > 0) {\n controller.focusedPaneLayerId = chartPaneIds[chartPaneIds.length - 1]!;\n }\n };\n\n const bindChartPanePointer = (wrap: HTMLElement, layer: LayerNode) => {\n wrap.addEventListener('pointerdown', (e) => {\n if (e.button !== 0 || controller.isInteracting()) return;\n const prev = controller.focusedPaneLayerId;\n if (prev === layer.id) return;\n queueMicrotask(() => {\n if (controller.isInteracting()) return;\n controller.focusChartPane(layer.id);\n opts.onChartPaneFocus?.(controller.getFocusedPaneId());\n });\n });\n };\n\n const syncRootPointerEvents = () => {\n root.style.pointerEvents = editor.isEnabled() ? 'auto' : 'none';\n };\n\n const apply = () => {\n syncRootPointerEvents();\n const preset = controller.getPreset();\n const layers = preset.layers\n .filter((l) => l.pageId === controller.activePageId && l.visible)\n .sort((a, b) => a.zIndex - b.zIndex);\n\n if (opts.hideLegacyGrid) opts.hideLegacyGrid.style.visibility = 'hidden';\n\n const chartPaneIds = layers.filter((l) => isChartPaneLayerType(l.type)).map((l) => l.id);\n ensureDefaultChartFocus(chartPaneIds);\n\n const structureSig = layerStructureSignature(layers, controller.activePageId);\n if (structureSig === lastStructureSig && wrappers.size > 0) {\n patchLayoutFrames(layers);\n return;\n }\n lastStructureSig = structureSig;\n\n root.replaceChildren();\n wrappers.clear();\n\n const editorOn = editor.isEnabled();\n\n for (const layer of layers) {\n if (layer.type === 'overlay.drawing') continue;\n\n const el = resolveWidgetEl(opts.widgets, layer);\n if (!el) continue;\n\n const wrap = document.createElement('div');\n wrap.className = 'tv-layer-wrap';\n if (isChartPaneLayerType(layer.type)) wrap.classList.add('tv-chart-pane-wrap');\n if (isOverlayLayerType(layer.type)) wrap.classList.add('tv-overlay-wrap');\n wrap.dataset.layerId = layer.id;\n wrap.dataset.widgetKey = layer.widgetKey;\n wrap.dataset.layerType = layer.type;\n if (layer.groupId) wrap.dataset.groupId = layer.groupId;\n\n const pe = wrapPointerEventsForLayer(layer, editorOn);\n wrap.style.cssText = [\n 'position:absolute',\n 'overflow:visible',\n 'box-sizing:border-box',\n `pointer-events:${pe}`,\n ].join(';');\n applyWrapFrame(wrap, layer);\n\n if (isChartPaneLayerType(layer.type) && !layer.locked && !editorOn) {\n bindChartPanePointer(wrap, layer);\n }\n\n if (layer.type === 'overlay.crosshairLegend') {\n el.style.pointerEvents = 'none';\n }\n\n el.style.width = '100%';\n el.style.height = '100%';\n el.style.minWidth = '0';\n el.style.minHeight = '0';\n el.style.overflow = layer.type === 'overlay.crosshairLegend' ? 'visible' : 'hidden';\n wrap.appendChild(el);\n root.appendChild(wrap);\n wrappers.set(layer.id, wrap);\n }\n\n applyFocusStyles();\n editor.rebind();\n };\n\n const unsubLayout = controller.subscribe(apply);\n const unsubFocus = controller.subscribeFocus(() => {\n const visible = controller\n .getLayersForActivePage()\n .filter((l) => l.visible);\n patchFocusVisuals(visible);\n });\n\n apply();\n\n return {\n root,\n controller,\n apply,\n enableLayerEditor: (enabled) => {\n editor.setEnabled(enabled);\n syncRootPointerEvents();\n apply();\n },\n isLayerEditorEnabled: () => editor.isEnabled(),\n destroy: () => {\n unsubLayout();\n unsubFocus();\n editor.destroy();\n root.remove();\n if (opts.hideLegacyGrid) opts.hideLegacyGrid.style.visibility = '';\n },\n };\n}","import { t } from '@coderyo/i18n';\nimport { isChartPaneLayerType } from './chart-pane-mount.js';\nimport type { LayerController } from './layer-controller.js';\n\nexport interface LayerPanelOptions {\n onSaveAsPreset?: (preset: ReturnType<LayerController['getPreset']>) => void;\n}\n\nexport interface LayerPanelHandle {\n el: HTMLElement;\n destroy: () => void;\n toggle: () => boolean;\n /** Replace panel checkbox selection (e.g. compositor shift+marquee). */\n selectLayers(layerIds: string[]): void;\n}\n\n/** @public Layer list UI bound to a LayerController. */\nexport function mountLayerPanel(\n parent: HTMLElement,\n controller: LayerController,\n opts: LayerPanelOptions = {},\n): LayerPanelHandle {\n const panel = document.createElement('aside');\n panel.className = 'tv-layer-panel';\n panel.style.cssText =\n 'display:none;position:fixed;right:12px;top:72px;width:240px;max-height:min(70vh,480px);z-index:2100;background:#161b22;border:1px solid #30363d;border-radius:8px;box-shadow:0 8px 24px #01040999;flex-direction:column;overflow:hidden;font-size:11px;color:#e6edf3;';\n\n const header = document.createElement('div');\n header.style.cssText =\n 'display:flex;align-items:center;justify-content:space-between;padding:8px 10px;border-bottom:1px solid #30363d;flex-shrink:0;';\n const title = document.createElement('span');\n title.textContent = t('layer.panel.title', '圖層');\n title.style.fontWeight = '600';\n const closeBtn = document.createElement('button');\n closeBtn.type = 'button';\n closeBtn.textContent = '×';\n closeBtn.style.cssText =\n 'background:transparent;border:none;color:#8b949e;font-size:18px;cursor:pointer;line-height:1;';\n header.append(title, closeBtn);\n\n const groupBar = document.createElement('div');\n groupBar.style.cssText =\n 'display:flex;gap:4px;padding:6px 8px;border-bottom:1px solid #30363d;flex-shrink:0;flex-wrap:wrap;';\n const createGroupBtn = document.createElement('button');\n createGroupBtn.type = 'button';\n createGroupBtn.textContent = t('layer.panel.createGroup', '建立群組');\n createGroupBtn.style.cssText =\n 'flex:1;min-width:0;padding:4px 6px;background:#21262d;color:#e6edf3;border:1px solid #30363d;border-radius:4px;cursor:pointer;font-size:10px;';\n const removeFromGroupBtn = document.createElement('button');\n removeFromGroupBtn.type = 'button';\n removeFromGroupBtn.textContent = t('layer.panel.removeFromGroup', '移出群組');\n removeFromGroupBtn.style.cssText = createGroupBtn.style.cssText;\n const ungroupBtn = document.createElement('button');\n ungroupBtn.type = 'button';\n ungroupBtn.textContent = t('layer.panel.ungroup', '解散群組');\n ungroupBtn.style.cssText = createGroupBtn.style.cssText;\n groupBar.append(createGroupBtn, removeFromGroupBtn, ungroupBtn);\n\n const list = document.createElement('div');\n list.style.cssText = 'overflow:auto;flex:1;min-height:0;padding:6px 4px;';\n\n const footer = document.createElement('div');\n footer.style.cssText = 'padding:8px;border-top:1px solid #30363d;flex-shrink:0;';\n const saveBtn = document.createElement('button');\n saveBtn.type = 'button';\n saveBtn.textContent = t('layer.panel.saveAs', '另存為我的範本');\n saveBtn.style.cssText =\n 'width:100%;padding:6px 8px;background:#21262d;color:#e6edf3;border:1px solid #30363d;border-radius:4px;cursor:pointer;font-size:11px;';\n footer.appendChild(saveBtn);\n\n panel.append(header, groupBar, list, footer);\n parent.appendChild(panel);\n\n let open = false;\n const selected = new Set<string>();\n let dragLayerId: string | null = null;\n\n const btnStyle =\n 'width:24px;height:22px;padding:0;border:1px solid #30363d;border-radius:3px;background:#21262d;cursor:pointer;font-size:10px;';\n\n const render = () => {\n list.replaceChildren();\n const layers = [...controller.getLayersForActivePage()].sort((a, b) => b.zIndex - a.zIndex);\n\n for (const id of [...selected]) {\n if (!layers.some((l) => l.id === id)) selected.delete(id);\n }\n\n createGroupBtn.disabled = selected.size < 2;\n const selectedWithGroup = layers.filter((l) => selected.has(l.id) && l.groupId);\n ungroupBtn.disabled = selectedWithGroup.length === 0;\n const singleInGroup =\n selected.size === 1 &&\n [...selected].some((id) => controller.getLayer(id)?.groupId);\n removeFromGroupBtn.disabled = !singleInGroup;\n\n for (const layer of layers) {\n const row = document.createElement('div');\n row.draggable = !layer.locked;\n row.dataset.layerId = layer.id;\n row.style.cssText =\n 'display:flex;align-items:center;gap:4px;padding:4px 6px;margin-bottom:2px;border-radius:4px;background:#0d1117;border:1px solid #21262d;cursor:grab;';\n\n row.ondragstart = (e) => {\n if (layer.locked) return;\n dragLayerId = layer.id;\n e.dataTransfer?.setData('text/plain', layer.id);\n if (e.dataTransfer) e.dataTransfer.effectAllowed = 'move';\n row.style.opacity = '0.55';\n };\n row.ondragend = () => {\n row.style.opacity = '';\n dragLayerId = null;\n };\n row.ondragover = (e) => {\n e.preventDefault();\n if (e.dataTransfer) e.dataTransfer.dropEffect = 'move';\n };\n row.ondrop = (e) => {\n e.preventDefault();\n if (!dragLayerId || dragLayerId === layer.id) return;\n const visual = [...controller.getLayersForActivePage()].sort(\n (a, b) => b.zIndex - a.zIndex,\n );\n const ids = visual.map((l) => l.id);\n const from = ids.indexOf(dragLayerId);\n const to = ids.indexOf(layer.id);\n if (from < 0 || to < 0) return;\n ids.splice(from, 1);\n ids.splice(to, 0, dragLayerId);\n controller.reorderLayers([...ids].reverse());\n dragLayerId = null;\n };\n\n const pick = document.createElement('input');\n pick.type = 'checkbox';\n pick.checked = selected.has(layer.id);\n pick.title = t('layer.panel.select', '選取');\n pick.style.cssText = 'width:14px;height:14px;cursor:pointer;flex-shrink:0;';\n pick.onchange = () => {\n if (pick.checked) selected.add(layer.id);\n else selected.delete(layer.id);\n render();\n };\n\n const eye = document.createElement('button');\n eye.type = 'button';\n eye.textContent = layer.visible ? '👁' : '—';\n eye.title = t('layer.panel.visibility', '顯示');\n eye.style.cssText = btnStyle;\n\n const lock = document.createElement('button');\n lock.type = 'button';\n lock.textContent = layer.locked ? '🔒' : '🔓';\n lock.title = t('layer.panel.lock', '鎖定');\n lock.style.cssText = btnStyle;\n\n const label = document.createElement('span');\n const groupTag = layer.groupId ? ` [${layer.groupId.slice(-4)}]` : '';\n label.textContent = `${layer.widgetKey}${groupTag}`;\n label.style.cssText = 'flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;';\n\n let syncIn: HTMLInputElement | null = null;\n if (isChartPaneLayerType(layer.type)) {\n syncIn = document.createElement('input');\n syncIn.type = 'text';\n syncIn.placeholder = t('layer.panel.syncGroup', '時間軸組');\n syncIn.value = layer.syncTimeScaleGroupId ?? '';\n syncIn.title = t(\n 'layer.panel.syncGroupHint',\n '相同組名同步縮放;留空則獨立',\n );\n syncIn.style.cssText =\n 'width:52px;flex-shrink:0;padding:2px 4px;font-size:10px;background:#21262d;color:#e6edf3;border:1px solid #30363d;border-radius:3px;';\n syncIn.onchange = () => {\n controller.setLayerSyncGroup(layer.id, syncIn!.value);\n };\n }\n\n const zUp = document.createElement('button');\n zUp.type = 'button';\n zUp.textContent = '▲';\n zUp.title = 'z+';\n zUp.style.cssText = btnStyle;\n const zDown = document.createElement('button');\n zDown.type = 'button';\n zDown.textContent = '▼';\n zDown.title = 'z-';\n zDown.style.cssText = btnStyle;\n\n eye.onclick = () => controller.setLayerVisible(layer.id, !layer.visible);\n lock.onclick = () => controller.setLayerLocked(layer.id, !layer.locked);\n zUp.onclick = () => controller.bumpZIndex(layer.id, 1);\n zDown.onclick = () => controller.bumpZIndex(layer.id, -1);\n\n if (syncIn) row.append(pick, eye, lock, label, syncIn, zUp, zDown);\n else row.append(pick, eye, lock, label, zUp, zDown);\n list.appendChild(row);\n }\n };\n\n createGroupBtn.onclick = () => {\n const ids = [...selected];\n if (ids.length < 2) return;\n controller.createBindGroup(ids);\n selected.clear();\n render();\n };\n\n removeFromGroupBtn.onclick = () => {\n const id = [...selected][0];\n if (!id) return;\n controller.removeLayerFromGroup(id);\n render();\n };\n\n ungroupBtn.onclick = () => {\n const groupIds = new Set<string>();\n for (const id of selected) {\n const layer = controller.getLayer(id);\n if (layer?.groupId) groupIds.add(layer.groupId);\n }\n for (const gid of groupIds) controller.dissolveGroup(gid);\n render();\n };\n\n const unsub = controller.subscribe(render);\n render();\n\n closeBtn.onclick = () => {\n open = false;\n panel.style.display = 'none';\n };\n\n saveBtn.onclick = () => opts.onSaveAsPreset?.(controller.getPreset());\n\n return {\n el: panel,\n destroy: () => {\n unsub();\n panel.remove();\n },\n toggle: () => {\n open = !open;\n panel.style.display = open ? 'flex' : 'none';\n return open;\n },\n selectLayers(layerIds: string[]) {\n selected.clear();\n for (const id of layerIds) selected.add(id);\n render();\n },\n };\n}","import { t } from '@coderyo/i18n';\nimport type { LayerController } from './layer-controller.js';\n\nexport interface PageNavigatorOptions {\n /** Show tab bar even on wide viewports (default: narrow only). */\n alwaysVisible?: boolean;\n narrowMq?: string;\n onPageChange?: (pageId: string) => void;\n}\n\nexport interface PageNavigatorHandle {\n el: HTMLElement;\n destroy: () => void;\n refresh: () => void;\n}\n\n/** @public Mobile-style page tabs for LayoutPreset v2 (P4). */\nexport function mountPageNavigator(\n parent: HTMLElement,\n controller: LayerController,\n opts: PageNavigatorOptions = {},\n): PageNavigatorHandle {\n const mq = opts.narrowMq ?? '(max-width: 768px)';\n const nav = document.createElement('nav');\n nav.className = 'tv-page-navigator';\n nav.style.cssText =\n 'display:none;align-items:center;gap:4px;padding:4px 8px;border-top:1px solid #30363d;background:#161b22;flex-shrink:0;flex-wrap:wrap;font-size:11px;color:#e6edf3;';\n\n const tabs = document.createElement('div');\n tabs.style.cssText = 'display:flex;gap:4px;flex-wrap:wrap;flex:1;min-width:0;';\n const actions = document.createElement('div');\n actions.style.cssText = 'display:flex;gap:4px;flex-shrink:0;';\n\n const addBtn = document.createElement('button');\n addBtn.type = 'button';\n addBtn.title = t('page.nav.add', '新增頁面');\n addBtn.textContent = '+';\n addBtn.style.cssText =\n 'width:28px;height:24px;background:#21262d;color:#e6edf3;border:1px solid #30363d;border-radius:4px;cursor:pointer;font-size:14px;line-height:1;';\n\n const renameBtn = document.createElement('button');\n renameBtn.type = 'button';\n renameBtn.title = t('page.nav.rename', '重新命名');\n renameBtn.textContent = '✎';\n renameBtn.style.cssText =\n 'width:28px;height:24px;background:#21262d;color:#e6edf3;border:1px solid #30363d;border-radius:4px;cursor:pointer;font-size:12px;';\n\n const delBtn = document.createElement('button');\n delBtn.type = 'button';\n delBtn.title = t('page.nav.delete', '刪除頁面');\n delBtn.textContent = '×';\n delBtn.style.cssText = renameBtn.style.cssText;\n\n actions.append(addBtn, renameBtn, delBtn);\n nav.append(tabs, actions);\n parent.appendChild(nav);\n\n const tabBtnStyle =\n 'padding:4px 10px;background:#21262d;color:#8b949e;border:1px solid #30363d;border-radius:4px;cursor:pointer;font-size:11px;max-width:120px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;';\n const tabBtnActiveStyle = tabBtnStyle.replace('#21262d', '#388bfd').replace('#8b949e', '#fff');\n\n const refresh = () => {\n tabs.replaceChildren();\n const preset = controller.getPreset();\n for (const page of preset.pages) {\n const btn = document.createElement('button');\n btn.type = 'button';\n btn.textContent = page.title;\n btn.title = page.title;\n btn.style.cssText =\n page.id === controller.activePageId ? tabBtnActiveStyle : tabBtnStyle;\n btn.onclick = () => {\n if (controller.setActivePage(page.id)) {\n opts.onPageChange?.(page.id);\n }\n };\n tabs.appendChild(btn);\n }\n delBtn.disabled = preset.pages.length <= 1;\n };\n\n addBtn.onclick = () => {\n const title = window.prompt(t('page.nav.addPrompt', '新頁面名稱'), '');\n const id = controller.addPage(title ?? undefined);\n opts.onPageChange?.(id);\n };\n\n renameBtn.onclick = () => {\n const page = controller.getPreset().pages.find((p) => p.id === controller.activePageId);\n if (!page) return;\n let title = window.prompt(t('page.nav.renamePrompt', '頁面名稱'), page.title);\n if (title == null) return;\n while (title !== null && !controller.renamePage(page.id, title)) {\n title = window.prompt(\n t('page.nav.renameEmpty', '名稱不可為空,請重新輸入'),\n title,\n );\n if (title == null) return;\n }\n };\n\n delBtn.onclick = () => {\n const page = controller.getPreset().pages.find((p) => p.id === controller.activePageId);\n if (!page || controller.getPreset().pages.length <= 1) return;\n if (!window.confirm(t('page.nav.deleteConfirm', `刪除「${page.title}」?`))) return;\n controller.removePage(page.id);\n opts.onPageChange?.(controller.activePageId);\n };\n\n const media = window.matchMedia(mq);\n const syncVisible = () => {\n nav.style.display = opts.alwaysVisible || media.matches ? 'flex' : 'none';\n };\n media.addEventListener('change', syncVisible);\n syncVisible();\n\n const unsub = controller.subscribe(refresh);\n refresh();\n\n return {\n el: nav,\n destroy: () => {\n unsub();\n media.removeEventListener('change', syncVisible);\n nav.remove();\n },\n refresh,\n };\n}","import type { LayerController } from './layer-controller.js';\n\n/** Minimal chart surface for layer time-scale sync (matches `IChart.applyTimeScaleSyncFromLayers`). */\nexport interface LayerTimeScaleSyncChart {\n applyTimeScaleSyncFromLayers(\n layers: Array<{ type: string; pageId?: string; syncTimeScaleGroupId?: string }>,\n pageId?: string,\n ): unknown;\n}\n\nexport interface BindLayerTimeScaleSyncOptions {\n /** Called after each sync apply (e.g. `requestAnimationFrame(chart.resize)`). */\n onSync?: () => void;\n}\n\n/**\n * @public Wire `IChart.applyTimeScaleSyncFromLayers` to `LayerController` preset mutations.\n * Applies immediately and on `controller.subscribe` (page switch, sync group, layer edits).\n * Returns unsubscribe — call after `mountLayerCompositor` + `createChart`.\n */\nexport function bindLayerTimeScaleSync(\n chart: LayerTimeScaleSyncChart,\n controller: LayerController,\n options?: BindLayerTimeScaleSyncOptions,\n): () => void {\n const apply = () => {\n chart.applyTimeScaleSyncFromLayers(\n controller.getPreset().layers,\n controller.activePageId,\n );\n options?.onSync?.();\n };\n apply();\n return controller.subscribe(apply);\n}","import { normalizeLayoutPreset } from './normalize.js';\nimport {\n LAYER_PRESET_VERSION,\n type BindGroup,\n type LayoutPage,\n type LayoutPreset,\n type LayerNode,\n} from './types.js';\n\nfunction upsertById<T extends { id: string }>(current: T[], incoming: T[] | undefined): T[] {\n if (!incoming?.length) return current.map((x) => ({ ...x }));\n const map = new Map(current.map((x) => [x.id, { ...x }]));\n for (const item of incoming) {\n if (!item?.id) continue;\n map.set(item.id, { ...item });\n }\n return [...map.values()];\n}\n\nfunction mergePages(current: LayoutPage[], incoming: LayoutPage[] | undefined): LayoutPage[] {\n return upsertById(current, incoming);\n}\n\nfunction mergeLayers(current: LayerNode[], incoming: LayerNode[] | undefined): LayerNode[] {\n if (!incoming?.length) return current.map((l) => ({ ...l, frame: { ...l.frame } }));\n const map = new Map(current.map((l) => [l.id, { ...l, frame: { ...l.frame } }]));\n for (const raw of incoming) {\n if (!raw?.id) continue;\n const prev = map.get(raw.id);\n map.set(raw.id, {\n ...(prev ?? raw),\n ...raw,\n frame: { ...(prev?.frame ?? raw.frame ?? { x: 0, y: 0, w: 1, h: 1 }) },\n });\n }\n return [...map.values()];\n}\n\nfunction mergeGroups(current: BindGroup[], incoming: BindGroup[] | undefined): BindGroup[] {\n if (!incoming?.length) {\n return current.map((g) => ({ ...g, layerIds: [...g.layerIds] }));\n }\n const map = new Map(current.map((g) => [g.id, { ...g, layerIds: [...g.layerIds] }]));\n for (const raw of incoming) {\n if (!raw?.id) continue;\n map.set(raw.id, {\n id: raw.id,\n name: raw.name ?? map.get(raw.id)?.name,\n layerIds: [...(raw.layerIds ?? map.get(raw.id)?.layerIds ?? [])],\n });\n }\n return [...map.values()];\n}\n\n/**\n * @public Merge partial LayoutPreset v2 into `current` (pages/layers/groups upsert by id).\n * Unmentioned entries are preserved. Result is normalized.\n */\nexport function mergeLayoutPreset(current: LayoutPreset, partial: LayoutPreset): LayoutPreset {\n return normalizeLayoutPreset({\n ...current,\n ...partial,\n version: LAYER_PRESET_VERSION,\n pages: mergePages(current.pages, partial.pages),\n layers: mergeLayers(current.layers, partial.layers),\n groups: mergeGroups(current.groups, partial.groups),\n });\n}","import type { BridgeLayerPane } from '@coderyo/bridge';\nimport {\n isValidLayerBridgePane,\n resolvePaneLayerIds as resolvePaneLayerIdsCore,\n} from '@coderyo/core';\nimport type { LayerType, LayoutPreset } from './types.js';\n\nconst PANE_TO_LAYER_TYPE: Record<BridgeLayerPane, LayerType> = {\n main: 'chart.main',\n volume: 'chart.volume',\n indicator: 'chart.indicator',\n};\n\nexport function layerTypeForBridgePane(pane: BridgeLayerPane): LayerType {\n return PANE_TO_LAYER_TYPE[pane];\n}\n\nexport { isValidLayerBridgePane as isValidBridgeLayerPane };\n\n/**\n * @public Resolve chart pane → layer ids for preset scope (supports `allPages`).\n */\nexport function resolvePaneLayerIds(\n preset: Pick<LayoutPreset, 'layers' | 'pages'>,\n pane: BridgeLayerPane,\n opts?: { allPages?: boolean; activePageId?: string },\n): string[] {\n return resolvePaneLayerIdsCore(preset, pane, opts);\n}","import type { DrawingRecord } from '@coderyo/drawings';\nimport { t } from '@coderyo/i18n';\n\nexport interface DrawingContextMenuHandlers {\n onDelete?: () => void;\n onCopy?: () => void;\n onToggleLock?: () => void;\n onDeselect?: () => void;\n onEditText?: () => void;\n}\n\nexport function openDrawingContextMenu(\n clientX: number,\n clientY: number,\n drawing: DrawingRecord | null,\n handlers: DrawingContextMenuHandlers,\n): () => void {\n const menu = document.createElement('div');\n menu.style.cssText =\n 'position:fixed;z-index:60;min-width:168px;padding:4px 0;background:#161b22;border:1px solid #30363d;border-radius:6px;box-shadow:0 8px 24px #01040988;';\n menu.style.left = `${clientX}px`;\n menu.style.top = `${clientY}px`;\n\n const add = (label: string, fn?: () => void, disabled = false) => {\n if (!fn) return;\n const btn = document.createElement('button');\n btn.type = 'button';\n btn.textContent = label;\n btn.disabled = disabled;\n btn.style.cssText =\n 'display:block;width:100%;text-align:left;padding:8px 12px;border:none;background:transparent;color:#e6edf3;font-size:12px;cursor:pointer;';\n if (disabled) btn.style.opacity = '0.45';\n btn.onclick = () => {\n fn();\n close();\n };\n menu.appendChild(btn);\n };\n\n if (drawing) {\n const locked = Boolean(drawing.meta?.locked);\n add(t('drawing.ctx.delete', '刪除'), handlers.onDelete);\n add(t('drawing.ctx.copy', '複製'), handlers.onCopy);\n add(\n locked ? t('drawing.ctx.unlock', '解鎖') : t('drawing.ctx.lock', '鎖定'),\n handlers.onToggleLock,\n );\n if (drawing.type === 'text') {\n add(t('drawing.ctx.editText', '編輯文字'), handlers.onEditText);\n }\n add(t('drawing.ctx.deselect', '取消選取'), handlers.onDeselect);\n }\n\n document.body.appendChild(menu);\n\n const close = () => {\n menu.remove();\n document.removeEventListener('click', close);\n };\n setTimeout(() => document.addEventListener('click', close), 0);\n return close;\n}","export function mountCodeSnippetPanel(parent: HTMLElement, getCode: () => string): HTMLElement {\n const wrap = document.createElement('details');\n wrap.style.cssText =\n 'flex-shrink:0;border-top:1px solid #30363d;background:#161b22;padding:6px 12px;font-size:11px;color:#8b949e;';\n\n const summary = document.createElement('summary');\n summary.textContent = '嵌入程式碼(整合方)';\n summary.style.cssText = 'cursor:pointer;color:#58a6ff;user-select:none;';\n\n const pre = document.createElement('pre');\n pre.style.cssText =\n 'margin:8px 0 0;padding:10px;background:#0d1117;border:1px solid #30363d;border-radius:6px;color:#e6edf3;font-size:11px;overflow:auto;max-height:160px;white-space:pre-wrap;';\n\n const copyBtn = document.createElement('button');\n copyBtn.type = 'button';\n copyBtn.textContent = '複製';\n copyBtn.style.cssText =\n 'margin-top:6px;padding:4px 10px;background:#21262d;color:#e6edf3;border:1px solid #30363d;border-radius:4px;cursor:pointer;font-size:11px;';\n copyBtn.onclick = () => {\n const code = getCode();\n pre.textContent = code;\n void navigator.clipboard.writeText(code);\n };\n\n wrap.ontoggle = () => {\n if (wrap.open) pre.textContent = getCode();\n };\n\n wrap.append(summary, pre, copyBtn);\n parent.appendChild(wrap);\n return wrap;\n}","import { compilePineLite } from '@coderyo/pine-lite';\n\ninterface PineDiagnostic {\n line: number;\n col: number;\n message: string;\n severity: 'error' | 'warning';\n endCol?: number;\n}\nimport { defaultKeymap, history, historyKeymap } from '@codemirror/commands';\nimport { syntaxHighlighting, defaultHighlightStyle, bracketMatching } from '@codemirror/language';\nimport { linter, type Diagnostic as CmDiagnostic } from '@codemirror/lint';\nimport { EditorState, type Extension } from '@codemirror/state';\nimport {\n EditorView,\n drawSelection,\n highlightActiveLine,\n highlightActiveLineGutter,\n keymap,\n lineNumbers,\n placeholder,\n} from '@codemirror/view';\nimport { t } from '@coderyo/i18n';\nimport { pineLanguage } from './pine-language.js';\n\nexport const PINE_SCRIPT_STORAGE_KEY = 'tradview:pine:script';\n\nexport function loadPineScriptPreference(): string | null {\n try {\n return localStorage.getItem(PINE_SCRIPT_STORAGE_KEY);\n } catch {\n return null;\n }\n}\n\nexport function savePineScriptPreference(script: string): void {\n try {\n localStorage.setItem(PINE_SCRIPT_STORAGE_KEY, script);\n } catch {\n /* ignore */\n }\n}\n\nfunction offsetAtLineCol(doc: string, line: number, col: number): number {\n const lines = doc.split('\\n');\n let off = 0;\n for (let i = 0; i < line - 1 && i < lines.length; i++) {\n off += lines[i]!.length + 1;\n }\n return off + Math.max(0, col - 1);\n}\n\nfunction pineDiagnosticsToCm(doc: string, diags: PineDiagnostic[]): CmDiagnostic[] {\n return diags.map((d) => {\n const from = offsetAtLineCol(doc, d.line, d.col);\n const to = d.endCol != null ? offsetAtLineCol(doc, d.line, d.endCol) : from + 1;\n return {\n from,\n to: Math.max(from + 1, to),\n severity: d.severity,\n message: d.message,\n };\n });\n}\n\nfunction createPineLinter(onStatus?: (msg: string, ok: boolean) => void) {\n return linter((view) => {\n const src = view.state.doc.toString();\n const result = compilePineLite(src);\n if (result.ok) {\n onStatus?.(t('pine.status.ok', '語法正確'), true);\n return [];\n }\n onStatus?.(result.errors[0] ?? t('pine.status.error', '語法錯誤'), false);\n return pineDiagnosticsToCm(src, result.diagnostics ?? []);\n });\n}\n\nconst darkTheme = EditorView.theme({\n '&': {\n backgroundColor: '#0d1117',\n color: '#e6edf3',\n fontSize: '12px',\n },\n '.cm-content': { caretColor: '#58a6ff', fontFamily: 'Consolas, \"Cascadia Code\", monospace' },\n '.cm-gutters': {\n backgroundColor: '#161b22',\n color: '#8b949e',\n borderRight: '1px solid #30363d',\n },\n '.cm-activeLine': { backgroundColor: '#161b22aa' },\n '.cm-activeLineGutter': { backgroundColor: '#21262d' },\n '.cm-selectionBackground, &.cm-focused .cm-selectionBackground': { backgroundColor: '#264f78' },\n '.cm-cursor': { borderLeftColor: '#58a6ff' },\n '.cm-lintRange-error': { backgroundImage: 'none', borderBottom: '2px wavy #f85149' },\n '.cm-lintRange-warning': { backgroundImage: 'none', borderBottom: '2px wavy #d29922' },\n});\n\nexport interface PineEditorPanelOptions {\n initialScript?: string;\n /** Debounced apply to chart (ms). Default 400. */\n debounceMs?: number;\n onApply?: (script: string, compileOk: boolean) => void;\n}\n\nexport function mountPineEditorPanel(\n parent: HTMLElement,\n opts: PineEditorPanelOptions = {},\n): {\n el: HTMLElement;\n getScript: () => string;\n setScript: (script: string) => void;\n applyNow: () => void;\n destroy: () => void;\n} {\n const wrap = document.createElement('details');\n wrap.className = 'tv-pine-editor';\n wrap.open = true;\n wrap.style.cssText =\n 'flex-shrink:0;border-top:1px solid #30363d;background:#161b22;max-height:220px;display:flex;flex-direction:column;';\n\n const summary = document.createElement('summary');\n summary.textContent = t('pine.editor.title', 'Pine 腳本編輯器');\n summary.style.cssText =\n 'cursor:pointer;color:#58a6ff;user-select:none;padding:6px 12px;font-size:12px;flex-shrink:0;';\n\n const toolbar = document.createElement('div');\n toolbar.style.cssText =\n 'display:flex;align-items:center;gap:8px;padding:0 12px 6px;flex-shrink:0;';\n\n const status = document.createElement('span');\n status.style.cssText = 'font-size:11px;color:#8b949e;flex:1;';\n status.textContent = t('pine.status.idle', '就緒');\n\n const applyBtn = document.createElement('button');\n applyBtn.type = 'button';\n applyBtn.textContent = t('pine.apply', '套用至圖表');\n applyBtn.style.cssText =\n 'padding:4px 10px;background:#238636;color:#fff;border:1px solid #2ea043;border-radius:4px;cursor:pointer;font-size:11px;';\n\n const host = document.createElement('div');\n host.style.cssText = 'flex:1;min-height:120px;max-height:160px;overflow:hidden;border-top:1px solid #30363d;';\n\n toolbar.append(status, applyBtn);\n wrap.append(summary, toolbar, host);\n parent.appendChild(wrap);\n\n let debounceTimer: ReturnType<typeof setTimeout> | null = null;\n const debounceMs = opts.debounceMs ?? 400;\n\n const runApply = (src: string) => {\n const r = compilePineLite(src);\n opts.onApply?.(src, r.ok);\n savePineScriptPreference(src);\n if (r.ok) {\n status.style.color = '#3fb950';\n status.textContent = t('pine.status.ok', '語法正確');\n } else {\n status.style.color = '#f85149';\n status.textContent = r.errors[0] ?? t('pine.status.error', '語法錯誤');\n }\n };\n\n const extensions: Extension[] = [\n lineNumbers(),\n highlightActiveLineGutter(),\n highlightActiveLine(),\n drawSelection(),\n bracketMatching(),\n history(),\n pineLanguage,\n syntaxHighlighting(defaultHighlightStyle, { fallback: true }),\n darkTheme,\n createPineLinter((msg, ok) => {\n status.style.color = ok ? '#8b949e' : '#f85149';\n status.textContent = msg;\n }),\n keymap.of([...defaultKeymap, ...historyKeymap]),\n placeholder(t('pine.placeholder', '// plot(sma(close, 20))')),\n EditorView.updateListener.of((u) => {\n if (!u.docChanged) return;\n if (debounceTimer) clearTimeout(debounceTimer);\n debounceTimer = setTimeout(() => runApply(u.state.doc.toString()), debounceMs);\n }),\n ];\n\n const state = EditorState.create({\n doc: opts.initialScript ?? '',\n extensions,\n });\n\n const view = new EditorView({ state, parent: host });\n\n applyBtn.onclick = () => runApply(view.state.doc.toString());\n\n return {\n el: wrap,\n getScript: () => view.state.doc.toString(),\n setScript: (script) => {\n view.dispatch({\n changes: { from: 0, to: view.state.doc.length, insert: script },\n });\n },\n applyNow: () => runApply(view.state.doc.toString()),\n destroy: () => {\n view.destroy();\n wrap.remove();\n },\n };\n}","import { StreamLanguage } from '@codemirror/language';\n\nexport const pineLanguage = StreamLanguage.define({\n name: 'pine-lite',\n startState: () => ({}),\n token(stream) {\n if (stream.eatSpace()) return null;\n if (stream.match(/\\/\\/.*/)) return 'comment';\n if (stream.match(/0x[\\da-fA-F]+|\\d+\\.?\\d*(?:[eE][+-]?\\d+)?/)) return 'number';\n if (stream.match(/\\b(?:var|plot|if|else|while|for|to|and|or|not|true|false)\\b/)) return 'keyword';\n if (stream.match(/\\b(?:sma|ema|rsi|close|open|high|low|volume|hl2|hlc3)\\b/)) return 'variableName';\n if (stream.match(/:=|==|!=|<=|>=|[+\\-*/<>=(){},]/)) return 'operator';\n if (stream.match(/[A-Za-z_]\\w*/)) return 'name';\n stream.next();\n return null;\n },\n});"],"mappings":"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","names":["t","t","t","fmt","t","clampPlacement","getLocale","setLocale","t","t","t","t","t","t","t","t","t","t"]}
|
|
1
|
+
{"version":3,"sources":["../src/top-bar.ts","../src/logo-slot.ts","../src/user-preferences.ts","../src/settings-panel.ts","../src/symbol-search-dialog.ts","../src/symbol-search.ts","../src/theme-toggle.ts","../src/theme-provider.ts","../src/i18n-provider.ts","../src/chart-layout.ts","../src/context-menu.ts","../src/crosshair-legend.ts","../src/drawing-properties-panel.ts","../src/indicator-pane-host.ts","../src/layout-schema.ts","../src/layout-engine.ts","../src/layer/compositor-shell.ts","../src/layer/compositor-shell-sync.ts","../src/layout-features.ts","../src/status-bar.ts","../src/shortcuts-modal.ts","../src/layer/types.ts","../src/layer/overlay-mount.ts","../src/layer/chart-pane-mount.ts","../src/layer/normalize.ts","../src/layer/grid-to-preset.ts","../src/layer/default-presets.ts","../src/layer/preset-store.ts","../src/layer/group-utils.ts","../src/layer/layer-controller.ts","../src/layer/layer-editor.ts","../src/layer/compositor.ts","../src/layer/layer-panel.ts","../src/layer/page-navigator.ts","../src/layer/bind-layer-time-scale-sync.ts","../src/layer/merge-preset.ts","../src/layer/layer-bridge-registration.ts","../src/layer/resolve-pane-layers.ts","../src/drawing-context-menu.ts","../src/code-snippet-panel.ts","../src/pine-editor-panel.ts","../src/pine-language.ts"],"sourcesContent":["import { DEFAULT_INTERVALS, type Interval, type SymbolSearchHit } from '@coderyo/data';\nimport type { I18nProvider } from './i18n-provider.js';\nimport { mountLogoSlot, type LogoSlotOptions } from './logo-slot.js';\nimport { mountSettingsMenu, type SettingsMenuOptions } from './settings-menu.js';\nimport {\n createSymbolSearchDialog,\n mountSymbolSearchDialogTrigger,\n} from './symbol-search-dialog.js';\nimport { mountSymbolSearch } from './symbol-search.js';\nimport { mountThemeToggle } from './theme-toggle.js';\nimport type { ThemeProvider } from './theme-provider.js';\n\nexport type SymbolInputMode = 'manual' | 'search' | 'dialog' | 'none';\n\nexport interface TopBarOptions {\n intervals?: Interval[];\n /** Highlighted interval button (defaults to first in `intervals`). */\n activeInterval?: Interval;\n initialSymbol?: string;\n onSymbolSearch?: (query: string) => Promise<SymbolSearchHit[]>;\n onSymbolSelect?: (symbol: string) => void;\n onIntervalChange?: (interval: Interval) => void;\n onThemeToggle?: () => void;\n onThemeChange?: (theme: 'dark' | 'light') => void;\n themeProvider?: ThemeProvider;\n i18n?: I18nProvider;\n logo?: LogoSlotOptions | false;\n onFullscreen?: () => void;\n onScreenshot?: () => void;\n settings?: SettingsMenuOptions;\n symbolInput?: SymbolInputMode;\n showSettings?: boolean;\n}\n\nfunction mountManualSymbolInput(\n parent: HTMLElement,\n opts: {\n initialSymbol?: string;\n onSymbolSelect?: (symbol: string) => void;\n i18n?: I18nProvider;\n },\n): void {\n const wrap = document.createElement('div');\n wrap.style.cssText = 'display:flex;align-items:center;gap:4px;margin-right:8px;';\n const input = document.createElement('input');\n input.type = 'text';\n input.placeholder = opts.i18n?.t('symbol.search', 'Symbol') ?? 'Symbol';\n input.value = opts.initialSymbol ?? '';\n input.style.cssText =\n 'width:140px;background:#0d1117;color:#e6edf3;border:1px solid #30363d;border-radius:4px;padding:4px 8px;font-size:12px;';\n const apply = () => {\n const v = input.value.trim();\n if (v) opts.onSymbolSelect?.(v);\n };\n input.addEventListener('keydown', (e) => {\n if (e.key === 'Enter') apply();\n });\n const btn = document.createElement('button');\n btn.type = 'button';\n btn.textContent = '↵';\n btn.title = 'Apply symbol';\n btn.style.cssText =\n 'background:#21262d;color:#e6edf3;border:1px solid #30363d;border-radius:4px;padding:4px 8px;cursor:pointer;font-size:12px;';\n btn.onclick = apply;\n wrap.append(input, btn);\n parent.appendChild(wrap);\n}\n\nexport function mountTopBar(\n parent: HTMLElement,\n opts: TopBarOptions = {},\n): { el: HTMLElement; setActiveInterval: (interval: Interval) => void } {\n const i18n = opts.i18n;\n const tKey = (key: string, fallback: string) => i18n?.t(key, fallback) ?? fallback;\n\n const bar = document.createElement('div');\n bar.className = 'tv-topbar';\n bar.style.cssText =\n 'display:flex;gap:8px;padding:8px 12px;align-items:center;border-bottom:1px solid var(--tv-border,#30363d);background:var(--tv-surface,#161b22);flex-shrink:0;box-sizing:border-box;width:100%;min-width:0;overflow-x:auto;overflow-y:visible;position:relative;';\n\n if (opts.logo !== false) {\n mountLogoSlot(bar, opts.logo ?? { label: 'TradView' });\n }\n\n const symbolMode = opts.symbolInput ?? 'manual';\n if (symbolMode === 'search' && opts.onSymbolSearch && opts.onSymbolSelect) {\n mountSymbolSearch(bar, {\n initialSymbol: opts.initialSymbol,\n onSearch: opts.onSymbolSearch,\n onSelect: opts.onSymbolSelect,\n });\n } else if (symbolMode === 'dialog' && opts.onSymbolSearch && opts.onSymbolSelect) {\n const dialog = createSymbolSearchDialog({\n initialSymbol: opts.initialSymbol,\n onSearch: opts.onSymbolSearch,\n onSelect: opts.onSymbolSelect,\n i18n,\n });\n mountSymbolSearchDialogTrigger(bar, dialog, {\n initialSymbol: opts.initialSymbol,\n i18n,\n });\n } else if (symbolMode === 'manual' && opts.onSymbolSelect) {\n mountManualSymbolInput(bar, {\n initialSymbol: opts.initialSymbol,\n onSymbolSelect: opts.onSymbolSelect,\n i18n,\n });\n }\n\n const intervals = opts.intervals ?? DEFAULT_INTERVALS;\n const btnStyle =\n 'background:#21262d;color:#e6edf3;border:1px solid #30363d;border-radius:4px;padding:4px 10px;cursor:pointer;font-size:12px;flex-shrink:0;';\n const btnActiveStyle = btnStyle.replace('#21262d', '#388bfd').replace('#e6edf3', '#fff');\n const intervalButtons = new Map<Interval, HTMLButtonElement>();\n let activeInterval = opts.activeInterval ?? intervals[0];\n\n const intervalRow = document.createElement('div');\n intervalRow.className = 'tv-topbar-intervals';\n intervalRow.style.cssText = 'display:flex;gap:8px;flex-wrap:nowrap;align-items:center;flex-shrink:0;';\n\n const paintIntervalButtons = () => {\n for (const [iv, btn] of intervalButtons) {\n btn.style.cssText = iv === activeInterval ? btnActiveStyle : btnStyle;\n }\n };\n\n for (const iv of intervals) {\n const btn = document.createElement('button');\n btn.type = 'button';\n btn.textContent = tKey(`interval.${iv}`, iv);\n btn.style.cssText = btnStyle;\n btn.onclick = () => {\n if (activeInterval === iv) return;\n activeInterval = iv;\n paintIntervalButtons();\n opts.onIntervalChange?.(iv);\n };\n intervalButtons.set(iv, btn);\n intervalRow.appendChild(btn);\n }\n paintIntervalButtons();\n bar.appendChild(intervalRow);\n\n const spacer = document.createElement('div');\n spacer.style.flex = '1';\n bar.appendChild(spacer);\n\n const mkBtn = (label: string, fn?: () => void) => {\n const b = document.createElement('button');\n b.type = 'button';\n b.textContent = label;\n b.style.cssText =\n 'background:#21262d;color:#e6edf3;border:1px solid #30363d;border-radius:4px;padding:4px 10px;cursor:pointer;font-size:12px;';\n b.onclick = () => fn?.();\n return b;\n };\n\n if (opts.themeProvider) {\n mountThemeToggle(bar, {\n themeProvider: opts.themeProvider,\n i18n,\n onThemeChange: opts.onThemeChange,\n });\n } else {\n bar.appendChild(mkBtn(tKey('theme.dark', '主題'), opts.onThemeToggle));\n }\n if (opts.showSettings && opts.settings) mountSettingsMenu(bar, opts.settings);\n bar.appendChild(mkBtn('⛶', opts.onFullscreen));\n bar.appendChild(mkBtn('📷', opts.onScreenshot));\n\n parent.appendChild(bar);\n return {\n el: bar,\n setActiveInterval: (interval) => {\n if (!intervalButtons.has(interval)) return;\n activeInterval = interval;\n paintIntervalButtons();\n },\n };\n}","export interface LogoSlotOptions {\n label?: string;\n href?: string;\n imageSrc?: string;\n}\n\nexport function mountLogoSlot(parent: HTMLElement, opts: LogoSlotOptions = {}): HTMLElement {\n const slot = document.createElement('div');\n slot.className = 'tv-logo-slot';\n slot.style.cssText =\n 'display:flex;align-items:center;gap:8px;margin-right:12px;flex-shrink:0;font-weight:600;font-size:13px;color:var(--tv-fg,#e6edf3);';\n\n const label = opts.label ?? 'TradView';\n const text = document.createElement('span');\n text.textContent = label;\n\n const children: HTMLElement[] = [];\n if (opts.imageSrc) {\n const img = document.createElement('img');\n img.src = opts.imageSrc;\n img.alt = label;\n img.style.cssText = 'height:22px;width:auto;display:block;';\n children.push(img);\n }\n children.push(text);\n\n if (opts.href) {\n const link = document.createElement('a');\n link.href = opts.href;\n link.style.cssText = 'color:inherit;text-decoration:none;display:flex;align-items:center;gap:8px;';\n link.append(...children);\n slot.appendChild(link);\n } else {\n slot.append(...children);\n }\n\n parent.appendChild(slot);\n return slot;\n}","import type { IndicatorConfig } from '@coderyo/indicators';\nimport {\n defaultChartStorage,\n loadIndicatorConfig as loadIndicatorConfigFromCore,\n saveIndicatorConfig as saveIndicatorConfigToCore,\n} from '@coderyo/core';\n\nexport const GRID_SETTING_KEY = 'tradview:settings:showGrid';\nexport const RETURN_CURSOR_KEY = 'tradview:settings:returnToCursorAfterDraw';\n\nexport function loadShowGridPreference(): boolean {\n try {\n return localStorage.getItem(GRID_SETTING_KEY) === '1';\n } catch {\n return false;\n }\n}\n\nexport function saveShowGridPreference(show: boolean): void {\n try {\n localStorage.setItem(GRID_SETTING_KEY, show ? '1' : '0');\n } catch {\n /* ignore */\n }\n}\n\nexport function loadReturnToCursorPreference(): boolean {\n try {\n return localStorage.getItem(RETURN_CURSOR_KEY) === '1';\n } catch {\n return false;\n }\n}\n\nexport function saveReturnToCursorPreference(v: boolean): void {\n try {\n localStorage.setItem(RETURN_CURSOR_KEY, v ? '1' : '0');\n } catch {\n /* ignore */\n }\n}\n\n/** @deprecated Prefer `@coderyo/core` `loadIndicatorConfig(storage, …)` when not using ui-shell. */\nexport function loadIndicatorConfig(symbol: string, interval: string): IndicatorConfig {\n return loadIndicatorConfigFromCore(defaultChartStorage, symbol, interval);\n}\n\n/** @deprecated Prefer `@coderyo/core` `saveIndicatorConfig(storage, …)` when not using ui-shell. */\nexport function saveIndicatorConfig(\n symbol: string,\n interval: string,\n config: IndicatorConfig,\n): void {\n saveIndicatorConfigToCore(defaultChartStorage, symbol, interval, config);\n}","import {\n DEFAULT_INDICATOR_CONFIG,\n disableIndicatorLayer,\n listActiveIndicatorLayers,\n type IndicatorConfig,\n type IndicatorLayerId,\n} from '@coderyo/indicators';\nimport { t } from '@coderyo/i18n';\nimport {\n loadReturnToCursorPreference,\n loadShowGridPreference,\n saveReturnToCursorPreference,\n saveShowGridPreference,\n} from './user-preferences.js';\n\nexport interface SettingsPanelOptions {\n showGrid?: boolean;\n onShowGridChange?: (show: boolean) => void;\n returnToCursorAfterDraw?: boolean;\n onReturnToCursorChange?: (v: boolean) => void;\n indicatorConfig?: IndicatorConfig;\n onIndicatorConfigChange?: (config: IndicatorConfig) => void;\n onClearAllIndicators?: () => void;\n onClearAllDrawings?: () => void;\n}\n\nexport function mountSettingsPanel(parent: HTMLElement, opts: SettingsPanelOptions = {}): HTMLElement {\n let open = false;\n let tab: 'chart' | 'drawing' | 'indicator' = 'chart';\n let showGrid = opts.showGrid ?? loadShowGridPreference();\n let returnToCursor = opts.returnToCursorAfterDraw ?? loadReturnToCursorPreference();\n let indicatorConfig = { ...(opts.indicatorConfig ?? DEFAULT_INDICATOR_CONFIG) };\n\n const wrap = document.createElement('div');\n wrap.style.cssText = 'position:relative;';\n\n const btn = document.createElement('button');\n btn.type = 'button';\n btn.title = t('settings.title', '設定');\n btn.textContent = '⚙';\n btn.style.cssText =\n 'background:#21262d;color:#e6edf3;border:1px solid #30363d;border-radius:4px;padding:4px 10px;cursor:pointer;font-size:14px;';\n\n const overlay = document.createElement('div');\n overlay.style.cssText =\n 'display:none;position:fixed;inset:0;z-index:2000;background:#01040999;align-items:center;justify-content:center;padding:16px;box-sizing:border-box;';\n\n const dialog = document.createElement('div');\n dialog.setAttribute('role', 'dialog');\n dialog.setAttribute('aria-modal', 'true');\n dialog.style.cssText =\n 'width:min(420px,100%);max-height:min(85vh,640px);display:flex;flex-direction:column;background:#161b22;border:1px solid #30363d;border-radius:8px;box-shadow:0 16px 48px #010409cc;overflow:hidden;';\n\n const header = document.createElement('div');\n header.style.cssText =\n 'display:flex;align-items:center;justify-content:space-between;padding:10px 12px;border-bottom:1px solid #30363d;';\n const title = document.createElement('span');\n title.textContent = t('settings.title', '設定');\n title.style.cssText = 'font-size:14px;font-weight:600;color:#e6edf3;';\n const closeBtn = document.createElement('button');\n closeBtn.type = 'button';\n closeBtn.textContent = '×';\n closeBtn.title = t('settings.close', '關閉');\n closeBtn.style.cssText =\n 'background:transparent;border:none;color:#8b949e;font-size:20px;line-height:1;cursor:pointer;padding:0 4px;';\n header.append(title, closeBtn);\n\n const tabs = document.createElement('div');\n tabs.style.cssText = 'display:flex;border-bottom:1px solid #30363d;flex-shrink:0;';\n const content = document.createElement('div');\n content.style.cssText = 'padding:10px 12px;font-size:12px;overflow:auto;flex:1;min-height:0;';\n\n const tabIds = [\n ['chart', t('settings.tab.chart', '圖表')],\n ['drawing', t('settings.tab.drawing', '繪圖')],\n ['indicator', t('settings.tab.indicator', '指標')],\n ] as const;\n\n const renderTabs = () => {\n tabs.replaceChildren();\n for (const [id, label] of tabIds) {\n const b = document.createElement('button');\n b.type = 'button';\n b.textContent = label;\n b.style.cssText = `flex:1;padding:8px;border:none;cursor:pointer;font-size:12px;${\n tab === id ? 'background:#21262d;color:#e6edf3;' : 'background:transparent;color:#8b949e;'\n }`;\n b.onclick = (e) => {\n e.stopPropagation();\n tab = id;\n renderTabs();\n renderContent();\n };\n tabs.appendChild(b);\n }\n };\n\n const checkbox = (label: string, checked: boolean, onChange: (v: boolean) => void) => {\n const row = document.createElement('label');\n row.style.cssText =\n 'display:flex;align-items:center;gap:8px;margin-bottom:8px;cursor:pointer;color:#e6edf3;';\n const input = document.createElement('input');\n input.type = 'checkbox';\n input.checked = checked;\n input.onchange = () => onChange(input.checked);\n row.append(input, document.createTextNode(label));\n return row;\n };\n\n const actionButton = (label: string, onClick: () => void, danger = true) => {\n const b = document.createElement('button');\n b.type = 'button';\n b.textContent = label;\n b.style.cssText = `display:block;width:100%;margin-top:10px;padding:6px 10px;border-radius:4px;border:1px solid ${\n danger ? '#f85149' : '#30363d'\n };background:#21262d;color:${danger ? '#f85149' : '#e6edf3'};cursor:pointer;font-size:12px;`;\n b.onclick = (e) => {\n e.stopPropagation();\n onClick();\n };\n return b;\n };\n\n const numberField = (label: string, value: number, onChange: (n: number) => void) => {\n const row = document.createElement('label');\n row.style.cssText = 'display:flex;justify-content:space-between;align-items:center;margin-bottom:6px;';\n row.innerHTML = `<span style=\"color:#8b949e\">${label}</span>`;\n const input = document.createElement('input');\n input.type = 'number';\n input.value = String(value);\n input.style.cssText =\n 'width:72px;padding:2px 6px;border-radius:4px;border:1px solid #30363d;background:#0d1117;color:#e6edf3;';\n input.onchange = () => onChange(Number(input.value) || value);\n row.appendChild(input);\n return row;\n };\n\n const renderLayerList = () => {\n const layers = listActiveIndicatorLayers(indicatorConfig);\n const section = document.createElement('div');\n section.style.marginBottom = '12px';\n const heading = document.createElement('div');\n heading.textContent = t('settings.ind.layers', '指標圖層');\n heading.style.cssText = 'font-weight:600;color:#e6edf3;margin-bottom:6px;font-size:12px;';\n section.appendChild(heading);\n if (layers.length === 0) {\n const empty = document.createElement('div');\n empty.textContent = t('settings.ind.layersEmpty', '目前沒有指標');\n empty.style.cssText = 'color:#8b949e;font-size:11px;';\n section.appendChild(empty);\n return section;\n }\n for (const layer of layers) {\n const row = document.createElement('div');\n row.style.cssText =\n 'display:flex;align-items:center;justify-content:space-between;gap:8px;padding:6px 8px;margin-bottom:4px;border-radius:4px;background:#0d1117;border:1px solid #30363d;';\n const meta = document.createElement('div');\n meta.style.cssText = 'min-width:0;';\n const name = document.createElement('div');\n name.textContent = layer.label;\n name.style.cssText = 'color:#e6edf3;font-size:12px;';\n const target = document.createElement('div');\n target.textContent =\n layer.target === 'main'\n ? t('settings.ind.layerMain', '主圖')\n : t('settings.ind.layerPane', '副圖');\n target.style.cssText = 'color:#8b949e;font-size:10px;margin-top:2px;';\n meta.append(name, target);\n const remove = document.createElement('button');\n remove.type = 'button';\n remove.textContent = t('settings.ind.layerRemove', '移除');\n remove.title = t('settings.ind.layerRemove', '移除');\n remove.style.cssText =\n 'flex-shrink:0;padding:2px 8px;border-radius:4px;border:1px solid #f85149;background:transparent;color:#f85149;cursor:pointer;font-size:11px;';\n remove.onclick = (e) => {\n e.stopPropagation();\n indicatorConfig = disableIndicatorLayer(indicatorConfig, layer.id as IndicatorLayerId);\n opts.onIndicatorConfigChange?.(indicatorConfig);\n renderContent();\n };\n row.append(meta, remove);\n section.appendChild(row);\n }\n return section;\n };\n\n const renderContent = () => {\n content.replaceChildren();\n if (tab === 'chart') {\n content.appendChild(\n checkbox(t('settings.showGrid', '顯示網格'), showGrid, (v) => {\n showGrid = v;\n saveShowGridPreference(v);\n opts.onShowGridChange?.(v);\n }),\n );\n } else if (tab === 'drawing') {\n content.appendChild(\n checkbox(t('settings.returnCursor', '畫完切回游標'), returnToCursor, (v) => {\n returnToCursor = v;\n saveReturnToCursorPreference(v);\n opts.onReturnToCursorChange?.(v);\n }),\n );\n content.appendChild(\n actionButton(t('settings.drawing.clearAll', '清除所有畫線'), () => {\n opts.onClearAllDrawings?.();\n renderContent();\n }),\n );\n } else {\n content.appendChild(renderLayerList());\n content.appendChild(\n checkbox(t('settings.ind.volume', '成交量副圖'), indicatorConfig.showVolume, (v) => {\n indicatorConfig = { ...indicatorConfig, showVolume: v };\n opts.onIndicatorConfigChange?.(indicatorConfig);\n renderContent();\n }),\n );\n const divider = document.createElement('div');\n divider.style.cssText = 'height:1px;background:#30363d;margin:10px 0;';\n content.appendChild(divider);\n content.appendChild(\n checkbox(t('settings.ind.macd', 'MACD 窗格'), indicatorConfig.showMacd, (v) => {\n indicatorConfig = { ...indicatorConfig, showMacd: v };\n opts.onIndicatorConfigChange?.(indicatorConfig);\n renderContent();\n }),\n );\n content.appendChild(\n checkbox(t('settings.ind.rsi', 'RSI 窗格'), indicatorConfig.showRsi, (v) => {\n indicatorConfig = { ...indicatorConfig, showRsi: v };\n opts.onIndicatorConfigChange?.(indicatorConfig);\n renderContent();\n }),\n );\n content.appendChild(\n checkbox(t('settings.ind.kdj', 'KDJ 窗格'), indicatorConfig.showKdj, (v) => {\n indicatorConfig = { ...indicatorConfig, showKdj: v };\n opts.onIndicatorConfigChange?.(indicatorConfig);\n renderContent();\n }),\n );\n const src = document.createElement('label');\n src.style.cssText = 'display:flex;justify-content:space-between;margin:8px 0 6px;';\n src.innerHTML = `<span style=\"color:#8b949e\">${t('settings.ind.source', '源')}</span>`;\n const sel = document.createElement('select');\n sel.style.cssText =\n 'background:#0d1117;color:#e6edf3;border:1px solid #30363d;border-radius:4px;padding:2px 6px;';\n for (const v of ['close', 'hlc3'] as const) {\n const o = document.createElement('option');\n o.value = v;\n o.textContent = v;\n sel.appendChild(o);\n }\n sel.value = indicatorConfig.source;\n sel.onchange = () => {\n indicatorConfig = { ...indicatorConfig, source: sel.value as IndicatorConfig['source'] };\n opts.onIndicatorConfigChange?.(indicatorConfig);\n };\n src.appendChild(sel);\n content.appendChild(src);\n content.appendChild(\n checkbox(t('settings.ind.ema', 'EMA 疊加'), indicatorConfig.showEma, (v) => {\n indicatorConfig = { ...indicatorConfig, showEma: v };\n opts.onIndicatorConfigChange?.(indicatorConfig);\n renderContent();\n }),\n );\n content.appendChild(\n numberField('EMA', indicatorConfig.emaPeriod, (n) => {\n indicatorConfig = { ...indicatorConfig, emaPeriod: n };\n opts.onIndicatorConfigChange?.(indicatorConfig);\n }),\n );\n content.appendChild(\n checkbox(t('settings.ind.boll', 'BOLL 通道'), indicatorConfig.showBoll, (v) => {\n indicatorConfig = { ...indicatorConfig, showBoll: v };\n opts.onIndicatorConfigChange?.(indicatorConfig);\n renderContent();\n }),\n );\n content.appendChild(\n numberField('BOLL', indicatorConfig.bollPeriod, (n) => {\n indicatorConfig = { ...indicatorConfig, bollPeriod: n };\n opts.onIndicatorConfigChange?.(indicatorConfig);\n }),\n );\n content.appendChild(\n numberField('MA', indicatorConfig.maPeriod, (n) => {\n indicatorConfig = { ...indicatorConfig, maPeriod: n };\n opts.onIndicatorConfigChange?.(indicatorConfig);\n }),\n );\n content.appendChild(\n numberField('MACD fast', indicatorConfig.macdFast, (n) => {\n indicatorConfig = { ...indicatorConfig, macdFast: n };\n opts.onIndicatorConfigChange?.(indicatorConfig);\n }),\n );\n content.appendChild(\n numberField('MACD slow', indicatorConfig.macdSlow, (n) => {\n indicatorConfig = { ...indicatorConfig, macdSlow: n };\n opts.onIndicatorConfigChange?.(indicatorConfig);\n }),\n );\n content.appendChild(\n numberField('RSI', indicatorConfig.rsiPeriod, (n) => {\n indicatorConfig = { ...indicatorConfig, rsiPeriod: n };\n opts.onIndicatorConfigChange?.(indicatorConfig);\n }),\n );\n content.appendChild(\n numberField('KDJ', indicatorConfig.kdjPeriod, (n) => {\n indicatorConfig = { ...indicatorConfig, kdjPeriod: n };\n opts.onIndicatorConfigChange?.(indicatorConfig);\n }),\n );\n content.appendChild(\n actionButton(t('settings.ind.clearAll', '清空所有指標'), () => {\n opts.onClearAllIndicators?.();\n if (opts.indicatorConfig) indicatorConfig = { ...opts.indicatorConfig };\n renderContent();\n }),\n );\n }\n };\n\n const setOpen = (next: boolean) => {\n open = next;\n overlay.style.display = open ? 'flex' : 'none';\n if (open) {\n if (opts.indicatorConfig) indicatorConfig = { ...opts.indicatorConfig };\n renderContent();\n }\n };\n\n renderTabs();\n renderContent();\n dialog.append(header, tabs, content);\n overlay.appendChild(dialog);\n document.body.appendChild(overlay);\n\n btn.onclick = (e) => {\n e.stopPropagation();\n setOpen(!open);\n };\n closeBtn.onclick = (e) => {\n e.stopPropagation();\n setOpen(false);\n };\n overlay.onclick = () => setOpen(false);\n dialog.onclick = (e) => e.stopPropagation();\n\n const onKey = (e: KeyboardEvent) => {\n if (e.key === 'Escape' && open) setOpen(false);\n };\n document.addEventListener('keydown', onKey);\n\n wrap.append(btn);\n parent.appendChild(wrap);\n\n const origRemove = wrap.remove.bind(wrap);\n wrap.remove = () => {\n document.removeEventListener('keydown', onKey);\n overlay.remove();\n origRemove();\n };\n\n return wrap;\n}","import type { SymbolSearchHit } from '@coderyo/data';\nimport type { I18nProvider } from './i18n-provider.js';\n\nexport interface SymbolSearchDialogOptions {\n onSearch: (query: string) => Promise<SymbolSearchHit[]>;\n onSelect: (symbol: string) => void;\n initialSymbol?: string;\n i18n?: I18nProvider;\n}\n\nexport interface SymbolSearchDialogHandle {\n open(): void;\n close(): void;\n destroy(): void;\n}\n\nexport function createSymbolSearchDialog(opts: SymbolSearchDialogOptions): SymbolSearchDialogHandle {\n const i18n = opts.i18n;\n const backdrop = document.createElement('div');\n backdrop.className = 'tv-symbol-dialog-backdrop';\n backdrop.style.cssText =\n 'display:none;position:fixed;inset:0;z-index:1000;background:rgba(0,0,0,0.55);align-items:flex-start;justify-content:center;padding:12vh 16px 16px;';\n\n const panel = document.createElement('div');\n panel.className = 'tv-symbol-dialog';\n panel.style.cssText =\n 'width:min(420px,100%);background:var(--tv-surface,#161b22);border:1px solid var(--tv-border,#30363d);border-radius:8px;padding:12px;box-shadow:0 8px 24px rgba(0,0,0,0.4);';\n\n const title = document.createElement('div');\n title.textContent = i18n?.t('symbol.search', '搜尋商品') ?? '搜尋商品';\n title.style.cssText = 'font-size:13px;font-weight:600;color:var(--tv-fg,#e6edf3);margin-bottom:8px;';\n\n const input = document.createElement('input');\n input.type = 'search';\n input.placeholder = i18n?.t('symbol.search', '搜尋商品') ?? '搜尋商品';\n input.value = opts.initialSymbol ?? '';\n input.style.cssText =\n 'width:100%;box-sizing:border-box;padding:8px 10px;border-radius:4px;border:1px solid var(--tv-border,#30363d);background:var(--tv-bg,#0d1117);color:var(--tv-fg,#e6edf3);font-size:13px;';\n\n const list = document.createElement('div');\n list.style.cssText = 'margin-top:8px;max-height:240px;overflow:auto;';\n\n panel.append(title, input, list);\n backdrop.appendChild(panel);\n\n let timer: ReturnType<typeof setTimeout> | undefined;\n let mounted = false;\n\n const renderHits = (hits: SymbolSearchHit[]) => {\n list.replaceChildren();\n if (hits.length === 0) {\n const empty = document.createElement('div');\n empty.textContent = '—';\n empty.style.cssText = 'padding:8px;color:var(--tv-muted,#8b949e);font-size:12px;';\n list.appendChild(empty);\n return;\n }\n for (const hit of hits) {\n const row = document.createElement('button');\n row.type = 'button';\n row.textContent = hit.exchange ? `${hit.symbol} · ${hit.exchange}` : hit.symbol;\n row.style.cssText =\n 'display:block;width:100%;text-align:left;padding:8px 10px;border:none;background:transparent;color:var(--tv-fg,#e6edf3);cursor:pointer;font-size:12px;border-radius:4px;';\n row.onmouseenter = () => {\n row.style.background = 'var(--tv-btn-bg,#21262d)';\n };\n row.onmouseleave = () => {\n row.style.background = 'transparent';\n };\n row.onclick = () => {\n opts.onSelect(hit.symbol);\n close();\n };\n list.appendChild(row);\n }\n };\n\n const runSearch = () => {\n const q = input.value.trim();\n if (q.length < 1) {\n list.replaceChildren();\n return;\n }\n void opts.onSearch(q).then(renderHits).catch(() => list.replaceChildren());\n };\n\n input.addEventListener('input', () => {\n clearTimeout(timer);\n timer = setTimeout(runSearch, 200);\n });\n\n input.addEventListener('keydown', (e) => {\n if (e.key === 'Escape') close();\n if (e.key === 'Enter') runSearch();\n });\n\n backdrop.addEventListener('click', (e) => {\n if (e.target === backdrop) close();\n });\n\n const open = () => {\n if (!mounted) {\n document.body.appendChild(backdrop);\n mounted = true;\n }\n backdrop.style.display = 'flex';\n input.focus();\n input.select();\n runSearch();\n };\n\n const close = () => {\n backdrop.style.display = 'none';\n };\n\n const destroy = () => {\n clearTimeout(timer);\n backdrop.remove();\n mounted = false;\n };\n\n return { open, close, destroy };\n}\n\n/** TopBar trigger: shows current symbol and opens the dialog. */\nexport function mountSymbolSearchDialogTrigger(\n parent: HTMLElement,\n dialog: SymbolSearchDialogHandle,\n opts: { initialSymbol?: string; i18n?: I18nProvider },\n): HTMLElement {\n const wrap = document.createElement('div');\n wrap.style.cssText = 'display:flex;align-items:center;margin-right:8px;flex-shrink:0;';\n\n const btn = document.createElement('button');\n btn.type = 'button';\n btn.textContent = opts.initialSymbol ?? (opts.i18n?.t('symbol.search', '搜尋商品') ?? '搜尋商品');\n btn.style.cssText =\n 'min-width:140px;text-align:left;background:var(--tv-bg,#0d1117);color:var(--tv-fg,#e6edf3);border:1px solid var(--tv-border,#30363d);border-radius:4px;padding:4px 10px;cursor:pointer;font-size:12px;';\n btn.onclick = () => dialog.open();\n\n wrap.appendChild(btn);\n parent.appendChild(wrap);\n return wrap;\n}","import type { SymbolSearchHit } from '@coderyo/data';\nimport { t } from '@coderyo/i18n';\n\nexport interface SymbolSearchOptions {\n onSearch: (query: string) => Promise<SymbolSearchHit[]>;\n onSelect: (symbol: string) => void;\n initialSymbol?: string;\n}\n\nexport function mountSymbolSearch(parent: HTMLElement, opts: SymbolSearchOptions): HTMLElement {\n const wrap = document.createElement('div');\n wrap.style.cssText = 'display:flex;align-items:center;gap:6px;margin-right:8px;';\n\n const input = document.createElement('input');\n input.type = 'search';\n input.placeholder = t('symbol.search', '搜尋商品');\n input.value = opts.initialSymbol ?? '';\n input.style.cssText =\n 'width:140px;padding:4px 8px;border-radius:4px;border:1px solid #30363d;background:#0d1117;color:#e6edf3;font-size:12px;';\n\n const list = document.createElement('div');\n list.style.cssText =\n 'display:none;position:absolute;top:100%;left:0;z-index:20;min-width:200px;max-height:200px;overflow:auto;background:#161b22;border:1px solid #30363d;border-radius:4px;';\n\n const box = document.createElement('div');\n box.style.position = 'relative';\n box.append(input, list);\n wrap.appendChild(box);\n\n let timer: ReturnType<typeof setTimeout> | undefined;\n\n const renderHits = (hits: SymbolSearchHit[]) => {\n list.replaceChildren();\n if (hits.length === 0) {\n list.style.display = 'none';\n return;\n }\n for (const hit of hits) {\n const row = document.createElement('button');\n row.type = 'button';\n row.textContent = hit.exchange ? `${hit.symbol} · ${hit.exchange}` : hit.symbol;\n row.style.cssText =\n 'display:block;width:100%;text-align:left;padding:6px 10px;border:none;background:transparent;color:#e6edf3;cursor:pointer;font-size:12px;';\n row.onmouseenter = () => {\n row.style.background = '#21262d';\n };\n row.onmouseleave = () => {\n row.style.background = 'transparent';\n };\n row.onclick = () => {\n input.value = hit.symbol;\n list.style.display = 'none';\n opts.onSelect(hit.symbol);\n };\n list.appendChild(row);\n }\n list.style.display = 'block';\n };\n\n input.addEventListener('input', () => {\n clearTimeout(timer);\n const q = input.value.trim();\n if (q.length < 1) {\n list.style.display = 'none';\n return;\n }\n timer = setTimeout(() => {\n void opts.onSearch(q).then(renderHits).catch(() => {\n list.style.display = 'none';\n });\n }, 200);\n });\n\n document.addEventListener('click', (e) => {\n if (!box.contains(e.target as Node)) list.style.display = 'none';\n });\n\n parent.appendChild(wrap);\n return wrap;\n}","import type { I18nProvider } from './i18n-provider.js';\nimport type { ThemeId, ThemeProvider } from './theme-provider.js';\n\nexport interface ThemeToggleOptions {\n themeProvider: ThemeProvider;\n i18n?: I18nProvider;\n onThemeChange?: (theme: ThemeId) => void;\n}\n\nexport function mountThemeToggle(parent: HTMLElement, opts: ThemeToggleOptions): HTMLButtonElement {\n const i18n = opts.i18n;\n const btn = document.createElement('button');\n btn.type = 'button';\n btn.className = 'tv-theme-toggle';\n btn.style.cssText =\n 'background:var(--tv-btn-bg,#21262d);color:var(--tv-fg,#e6edf3);border:1px solid var(--tv-border,#30363d);border-radius:4px;padding:4px 10px;cursor:pointer;font-size:12px;flex-shrink:0;';\n\n const paint = (theme: ThemeId) => {\n btn.textContent =\n theme === 'dark'\n ? (i18n?.t('theme.dark', '深色') ?? '深色')\n : (i18n?.t('theme.light', '淺色') ?? '淺色');\n };\n\n btn.onclick = () => {\n const next = opts.themeProvider.toggle();\n opts.onThemeChange?.(next);\n };\n\n opts.themeProvider.subscribe((theme) => paint(theme));\n parent.appendChild(btn);\n return btn;\n}","export type ThemeId = 'dark' | 'light';\n\nexport const THEME_STORAGE_KEY = 'tradview:theme';\n\nconst THEME_VARS: Record<ThemeId, Record<string, string>> = {\n dark: {\n '--tv-bg': '#0d1117',\n '--tv-surface': '#161b22',\n '--tv-border': '#30363d',\n '--tv-fg': '#e6edf3',\n '--tv-muted': '#8b949e',\n '--tv-accent': '#388bfd',\n '--tv-btn-bg': '#21262d',\n },\n light: {\n '--tv-bg': '#ffffff',\n '--tv-surface': '#f6f8fa',\n '--tv-border': '#d0d7de',\n '--tv-fg': '#24292f',\n '--tv-muted': '#656d76',\n '--tv-accent': '#0969da',\n '--tv-btn-bg': '#f6f8fa',\n },\n};\n\nexport function loadTheme(): ThemeId {\n try {\n const v = localStorage.getItem(THEME_STORAGE_KEY);\n return v === 'light' ? 'light' : 'dark';\n } catch {\n return 'dark';\n }\n}\n\nexport function saveTheme(theme: ThemeId): void {\n try {\n localStorage.setItem(THEME_STORAGE_KEY, theme);\n } catch {\n /* ignore */\n }\n}\n\nexport function applyThemeToDocument(theme: ThemeId, root: HTMLElement = document.documentElement): void {\n const vars = THEME_VARS[theme];\n for (const [k, v] of Object.entries(vars)) root.style.setProperty(k, v);\n root.dataset.tradviewTheme = theme;\n}\n\nexport interface ThemeProvider {\n getTheme(): ThemeId;\n setTheme(theme: ThemeId): void;\n toggle(): ThemeId;\n subscribe(listener: (theme: ThemeId) => void): () => void;\n}\n\nexport function createThemeProvider(initial?: ThemeId): ThemeProvider {\n let theme: ThemeId = initial ?? loadTheme();\n const listeners = new Set<(t: ThemeId) => void>();\n\n const notify = () => {\n applyThemeToDocument(theme);\n for (const l of listeners) l(theme);\n };\n\n applyThemeToDocument(theme);\n\n return {\n getTheme: () => theme,\n setTheme: (next) => {\n if (next === theme) return;\n theme = next;\n saveTheme(theme);\n notify();\n },\n toggle: () => {\n theme = theme === 'dark' ? 'light' : 'dark';\n saveTheme(theme);\n notify();\n return theme;\n },\n subscribe: (listener) => {\n listeners.add(listener);\n listener(theme);\n return () => listeners.delete(listener);\n },\n };\n}","import {\n getLocale,\n registerLocale,\n setLocale,\n t as i18nT,\n type I18nDictionary,\n type Locale,\n} from '@coderyo/i18n';\n\nexport interface I18nProvider {\n t(key: string, fallback?: string, params?: Record<string, string | number>): string;\n getLocale(): Locale;\n setLocale(locale: Locale): void;\n registerLocale(locale: Locale, dictionary: I18nDictionary): void;\n subscribe(listener: (locale: Locale) => void): () => void;\n}\n\nfunction interpolate(text: string, params?: Record<string, string | number>): string {\n if (!params) return text;\n return text.replace(/\\{(\\w+)\\}/g, (_, key: string) => String(params[key] ?? `{${key}}`));\n}\n\nexport function createI18nProvider(defaultLocale: Locale = 'zh-TW'): I18nProvider {\n setLocale(defaultLocale);\n const listeners = new Set<(locale: Locale) => void>();\n\n return {\n t(key, fallback, params) {\n return interpolate(i18nT(key, fallback), params);\n },\n getLocale,\n setLocale(locale) {\n setLocale(locale);\n for (const l of listeners) l(locale);\n },\n registerLocale(loc, dictionary) {\n registerLocale(loc, dictionary);\n if (getLocale() === loc) {\n for (const l of listeners) l(loc);\n }\n },\n subscribe(listener) {\n listeners.add(listener);\n listener(getLocale());\n return () => listeners.delete(listener);\n },\n };\n}","import { t } from '@coderyo/i18n';\nimport { attachChartContextMenu, type ContextMenuAction } from './context-menu.js';\nimport { mountCrosshairLegend } from './crosshair-legend.js';\nimport { mountDrawingPropertiesPanel } from './drawing-properties-panel.js';\nimport { mountIndicatorPaneHost } from './indicator-pane-host.js';\nimport { createLayoutGrid, type LayoutGridHandle } from './layout-engine.js';\nimport { createCompositorShell } from './layer/compositor-shell.js';\nimport { syncCompositorShellVisibilityFromFeatures } from './layer/compositor-shell-sync.js';\nimport { getWidgetPlacement } from './layout-schema.js';\nimport {\n mergeLayoutFeatures,\n resolveLayoutFeatures,\n type LayoutFeatures,\n type ResolvedLayoutFeatures,\n} from './layout-features.js';\nimport {\n loadLayoutSchema,\n resolveLayoutSchema,\n saveLayoutSchema,\n type LayoutSchema,\n} from './layout-schema.js';\nimport { mountStatusBar, type StatusBarOptions } from './status-bar.js';\nimport { mountTopBar, type TopBarOptions } from './top-bar.js';\nimport type { SettingsPanelOptions } from './settings-panel.js';\nimport { bindShortcutsModal } from './shortcuts-modal.js';\nimport { createI18nProvider, type I18nProvider } from './i18n-provider.js';\nimport { createThemeProvider, type ThemeProvider } from './theme-provider.js';\n\nexport type { LayoutFeatures, ResolvedLayoutFeatures } from './layout-features.js';\nexport { resolveLayoutFeatures, DEFAULT_LAYOUT_FEATURES, createDemoLayoutOptions } from './layout-features.js';\nexport type { LayoutSchema, LayoutWidgetId } from './layout-schema.js';\nexport {\n DEFAULT_LAYOUT_SCHEMA,\n resolveLayoutSchema,\n loadLayoutSchema,\n saveLayoutSchema,\n layoutStorageKey,\n} from './layout-schema.js';\n\nexport type DrawingToolId =\n | 'cursor'\n | 'trendline'\n | 'hline'\n | 'vline'\n | 'rectangle'\n | 'fibonacci'\n | 'text';\n\nconst DRAWING_TOOLS: Array<{ id: DrawingToolId; label: string }> = [\n { id: 'cursor', label: '↖' },\n { id: 'trendline', label: '╱' },\n { id: 'hline', label: '─' },\n { id: 'vline', label: '│' },\n { id: 'rectangle', label: '▭' },\n { id: 'fibonacci', label: 'φ' },\n { id: 'text', label: 'T' },\n];\n\nconst MOBILE_MQ = '(max-width: 768px)';\n\nexport interface ChartLayoutOptions extends TopBarOptions {\n themeProvider?: ThemeProvider;\n i18n?: I18nProvider;\n /** When false, do not auto-create theme provider / localStorage (default true). */\n autoThemeProvider?: boolean;\n /** When false, do not auto-create i18n provider (default true). */\n autoI18n?: boolean;\n /** Grid layout schema; omit to use {@link DEFAULT_LAYOUT_SCHEMA}. */\n layout?: LayoutSchema | null;\n /** Key for layout persistence (`layoutPersist`). Default `default`. */\n layoutId?: string;\n /** Persist layout schema to localStorage on change / saveLayout(). */\n layoutPersist?: boolean;\n /**\n * Enable drag/resize layout editor on mount.\n * @deprecated Ignored when `layerCompositorManaged` — use `mountLayerCompositor` + `enableLayerEditor`.\n */\n layoutEditor?: boolean;\n onLayoutChange?: (schema: LayoutSchema) => void;\n showTopBar?: boolean;\n showLeftToolbar?: boolean;\n showBottomToolbar?: boolean;\n activeDrawingTool?: DrawingToolId;\n onDrawingToolSelect?: (tool: DrawingToolId) => void;\n statusBar?: StatusBarOptions;\n contextMenuActions?: ContextMenuAction[];\n settings?: SettingsPanelOptions;\n showStatusBar?: boolean;\n showCrosshairLegend?: boolean;\n showPropertiesPanel?: boolean;\n showContextMenu?: boolean;\n showSettings?: boolean;\n showShortcuts?: boolean;\n symbolInput?: 'manual' | 'search' | 'dialog' | 'none';\n onDrawingStyleChange?: (patch: { color?: string; lineWidth?: number; text?: string }) => void;\n onDrawingSelectionBind?: (bind: (drawing: import('@coderyo/drawings').DrawingRecord | null) => void) => void;\n /**\n * When true, crosshair legend is not mounted under chartMain and visibility is driven by\n * LayerCompositor (not grid CSS / el.style.display here).\n */\n layerCompositorManaged?: boolean;\n}\n\nfunction mountToolButtons(\n parent: HTMLElement,\n activeTool: DrawingToolId,\n onSelect: (tool: DrawingToolId) => void,\n layout: 'column' | 'row',\n): { setActive: (tool: DrawingToolId) => void } {\n const btnStyle =\n layout === 'column'\n ? 'width:32px;height:28px;background:#21262d;color:#e6edf3;border:1px solid #30363d;border-radius:4px;cursor:pointer;font-size:13px;padding:0;'\n : 'min-width:36px;height:32px;background:#21262d;color:#e6edf3;border:1px solid #30363d;border-radius:4px;cursor:pointer;font-size:13px;padding:0 6px;';\n const activeStyle = btnStyle.replace('#21262d', '#388bfd').replace('#e6edf3', '#fff');\n\n const buttons = new Map<DrawingToolId, HTMLButtonElement>();\n for (const tool of DRAWING_TOOLS) {\n const btn = document.createElement('button');\n btn.type = 'button';\n btn.title = tool.id;\n btn.textContent = tool.label;\n btn.style.cssText = activeTool === tool.id ? activeStyle : btnStyle;\n btn.onclick = () => onSelect(tool.id);\n buttons.set(tool.id, btn);\n parent.appendChild(btn);\n }\n\n return {\n setActive: (tool) => {\n for (const [id, btn] of buttons) {\n btn.style.cssText = id === tool ? activeStyle : btnStyle;\n }\n },\n };\n}\n\nexport function mountChartLayout(root: HTMLElement, opts: ChartLayoutOptions = {}): {\n layoutRoot: HTMLElement;\n layoutGrid: HTMLElement;\n /** @deprecated Alias of chartMain — use chartMain for LWC mount. */\n chartHost: HTMLElement;\n chartMain: HTMLElement;\n chartVolume: HTMLElement;\n /** Drawing canvas host (same element as chartMain when compositor-managed). */\n drawingOverlay: HTMLElement;\n indicatorHost: HTMLElement;\n topBar: HTMLElement;\n setActiveInterval: (interval: import('@coderyo/data').Interval) => void;\n statusBar: ReturnType<typeof mountStatusBar>;\n crosshairLegend: ReturnType<typeof mountCrosshairLegend>;\n detachContextMenu: () => void;\n setActiveDrawingTool: (tool: DrawingToolId) => void;\n propertiesPanel: ReturnType<typeof mountDrawingPropertiesPanel>;\n /** Bind drawing + apply properties panel visibility (compositor-safe). */\n handleDrawingSelection: (drawing: import('@coderyo/drawings').DrawingRecord | null) => void;\n /** Sync showCrosshairLegend (etc.) to compositor layer.visible when layerCompositorManaged. */\n syncCompositorShellVisibility?: (\n controller: import('./layer/layer-controller.js').LayerController,\n ) => void;\n /**\n * Bind compositor controller so `setLayoutFeatures` keeps shell/legend layer.visible in sync.\n * Call once after `mountLayerCompositor` (Playground pattern).\n */\n bindLayerCompositorController?: (\n controller: import('./layer/layer-controller.js').LayerController,\n ) => void;\n setLayoutFeatures: (patch: LayoutFeatures) => void;\n getLayoutFeatures: () => ResolvedLayoutFeatures;\n getLayoutSchema: () => LayoutSchema;\n setLayoutSchema: (schema: LayoutSchema) => void;\n enableLayoutEditor: (enabled: boolean) => void;\n saveLayout: () => void;\n} {\n let layoutFeatures = resolveLayoutFeatures(opts);\n const layoutId = opts.layoutId ?? 'default';\n\n root.replaceChildren();\n root.style.display = 'flex';\n root.style.flexDirection = 'column';\n root.style.height = root.style.height || '100%';\n root.style.width = root.style.width || '100%';\n root.style.minWidth = '0';\n root.style.boxSizing = 'border-box';\n root.style.overflow = 'hidden';\n\n const useAutoTheme = opts.autoThemeProvider !== false;\n const useAutoI18n = opts.autoI18n !== false;\n const themeProvider =\n opts.themeProvider ?? (useAutoTheme ? createThemeProvider() : undefined);\n const i18nProvider = opts.i18n ?? (useAutoI18n ? createI18nProvider() : undefined);\n\n themeProvider?.subscribe((theme) => {\n root.style.background = theme === 'dark' ? '#0d1117' : '#f6f8fa';\n });\n\n let activeTool: DrawingToolId = opts.activeDrawingTool ?? 'cursor';\n let setActiveDesktop: ((t: DrawingToolId) => void) | null = null;\n let setActiveMobile: ((t: DrawingToolId) => void) | null = null;\n let lastSelectedDrawing: import('@coderyo/drawings').DrawingRecord | null = null;\n\n const setActiveDrawingTool = (tool: DrawingToolId) => {\n activeTool = tool;\n setActiveDesktop?.(tool);\n setActiveMobile?.(tool);\n };\n\n const onToolSelect = (tool: DrawingToolId) => {\n setActiveDrawingTool(tool);\n opts.onDrawingToolSelect?.(tool);\n };\n\n const topBarHost = document.createElement('div');\n topBarHost.className = 'tv-layout-header';\n topBarHost.style.cssText = 'width:100%;min-width:0;overflow:visible;position:relative;z-index:30;';\n\n const leftToolbar = document.createElement('aside');\n leftToolbar.style.cssText =\n 'width:100%;height:100%;max-width:44px;border-right:1px solid #30363d;background:#161b22;display:flex;flex-direction:column;align-items:center;padding:4px 2px;gap:4px;box-sizing:border-box;overflow:hidden;';\n\n const bottomToolbar = document.createElement('div');\n bottomToolbar.style.cssText =\n 'width:100%;height:100%;gap:6px;padding:6px 8px;border-top:1px solid #30363d;background:#161b22;overflow-x:auto;box-sizing:border-box;display:flex;flex-direction:row;';\n\n const chartMain = document.createElement('div');\n chartMain.className = 'tv-chart-main-mount';\n chartMain.style.cssText =\n 'width:100%;height:100%;min-height:120px;position:relative;overflow:hidden;box-sizing:border-box;';\n\n const chartVolume = document.createElement('div');\n chartVolume.className = 'tv-chart-volume-mount';\n chartVolume.style.cssText =\n 'width:100%;height:100%;min-height:48px;position:relative;overflow:hidden;box-sizing:border-box;';\n\n /** Legacy grid cell only; with LayerCompositor use chartMain/chartVolume mounts (not chartHost). */\n const chartHost = document.createElement('div');\n chartHost.className = 'tv-chart-grid-anchor';\n chartHost.style.cssText =\n 'width:100%;height:100%;min-height:0;position:relative;overflow:hidden;box-sizing:border-box;';\n\n const indicatorMount = document.createElement('div');\n indicatorMount.style.cssText = 'width:100%;height:100%;min-height:0;display:flex;flex-direction:column;';\n const indicatorHost = mountIndicatorPaneHost(indicatorMount);\n indicatorHost.style.flex = '1';\n\n const statusMount = document.createElement('div');\n statusMount.style.cssText = 'width:100%;height:100%;';\n const statusBar = mountStatusBar(statusMount, opts.statusBar ?? {});\n\n const propertiesMount = document.createElement('div');\n propertiesMount.style.cssText = 'width:100%;height:100%;min-height:0;';\n const propertiesPanel = mountDrawingPropertiesPanel(propertiesMount, {\n onStyleChange: opts.onDrawingStyleChange,\n });\n\n const layerCompositorManaged = opts.layerCompositorManaged === true;\n const drawingOverlay = chartMain;\n\n let loaded: LayoutSchema | null = null;\n let layoutSchema = resolveLayoutSchema(null);\n if (!layerCompositorManaged) {\n loaded =\n opts.layout !== undefined && opts.layout !== null\n ? resolveLayoutSchema(opts.layout)\n : opts.layoutPersist\n ? loadLayoutSchema(layoutId)\n : null;\n layoutSchema = resolveLayoutSchema(loaded);\n }\n\n const persistLayout = (schema: LayoutSchema) => {\n if (layerCompositorManaged) return;\n layoutSchema = resolveLayoutSchema(schema);\n if (opts.layoutPersist) saveLayoutSchema(layoutId, layoutSchema);\n opts.onLayoutChange?.(layoutSchema);\n };\n\n let layoutShell: LayoutGridHandle | ReturnType<typeof createCompositorShell>;\n if (layerCompositorManaged) {\n layoutShell = createCompositorShell({\n widgets: {\n topBar: topBarHost,\n leftToolbar,\n bottomToolbar,\n chartHost,\n indicatorHost: indicatorMount,\n statusBar: statusMount,\n propertiesPanel: propertiesMount,\n },\n });\n } else {\n layoutShell = createLayoutGrid({\n schema: layoutSchema,\n features: layoutFeatures,\n editor: opts.layoutEditor ?? false,\n onSchemaChange: persistLayout,\n widgets: {\n topBar: topBarHost,\n leftToolbar,\n bottomToolbar,\n chartHost,\n indicatorHost: indicatorMount,\n statusBar: statusMount,\n propertiesPanel: propertiesMount,\n },\n });\n }\n\n root.appendChild(layoutShell.root);\n\n let topBar: HTMLElement = topBarHost;\n let setActiveInterval: (interval: import('@coderyo/data').Interval) => void = () => {};\n const crosshairLegend = mountCrosshairLegend(\n layerCompositorManaged ? undefined : chartMain,\n { symbol: opts.initialSymbol },\n );\n\n let detachContextMenu = () => {};\n let shortcutsBound = false;\n let disposeMobileMq: (() => void) | null = null;\n\n const mountToolbarActions = (parent: HTMLElement, compact: boolean) => {\n const settings = opts.settings;\n if (!settings?.onClearAllDrawings && !settings?.onClearAllIndicators) return;\n const spacer = document.createElement('div');\n spacer.style.flex = compact ? '1' : '0';\n spacer.style.minHeight = compact ? '4px' : '0';\n parent.appendChild(spacer);\n const mk = (label: string, fn?: () => void) => {\n const b = document.createElement('button');\n b.type = 'button';\n b.title = label;\n b.textContent = compact\n ? label === t('toolbar.clearDrawings', '清除繪圖')\n ? '⌧'\n : '∅'\n : label;\n b.style.cssText = compact\n ? 'width:32px;height:24px;font-size:10px;background:#21262d;color:#f85149;border:1px solid #30363d;border-radius:4px;cursor:pointer;'\n : 'min-width:36px;height:28px;font-size:10px;background:#21262d;color:#f85149;border:1px solid #30363d;border-radius:4px;cursor:pointer;padding:0 4px;';\n b.onclick = () => fn?.();\n return b;\n };\n if (settings.onClearAllDrawings) {\n parent.appendChild(mk(t('toolbar.clearDrawings', '清除繪圖'), settings.onClearAllDrawings));\n }\n if (settings.onClearAllIndicators) {\n parent.appendChild(mk(t('toolbar.clearIndicators', '清除指標'), settings.onClearAllIndicators));\n }\n };\n\n const mountLeftToolbar = () => {\n leftToolbar.replaceChildren();\n const desktopTools = mountToolButtons(leftToolbar, activeTool, onToolSelect, 'column');\n setActiveDesktop = desktopTools.setActive;\n mountToolbarActions(leftToolbar, true);\n\n bottomToolbar.replaceChildren();\n const mobileTools = mountToolButtons(bottomToolbar, activeTool, onToolSelect, 'row');\n setActiveMobile = mobileTools.setActive;\n mountToolbarActions(bottomToolbar, false);\n };\n\n const chartAreaColStart = () => (layoutFeatures.showLeftToolbar ? 2 : 1);\n\n const applyPropertiesPanelLayout = (drawing: import('@coderyo/drawings').DrawingRecord | null) => {\n const showPanel = layoutFeatures.showPropertiesPanel && drawing != null;\n propertiesPanel.el.style.display = showPanel ? 'block' : 'none';\n if (layerCompositorManaged) return;\n\n const propsCell = layoutShell.cells.get('propertiesPanel');\n const chartCell = layoutShell.cells.get('chartHost');\n const indCell = layoutShell.cells.get('indicatorHost');\n const statusCell = layoutShell.cells.get('statusBar');\n if (!propsCell || !chartCell) return;\n\n const cw = getWidgetPlacement(layoutSchema, 'chartHost');\n const iw = getWidgetPlacement(layoutSchema, 'indicatorHost');\n const sw = getWidgetPlacement(layoutSchema, 'statusBar');\n const pw = getWidgetPlacement(layoutSchema, 'propertiesPanel');\n\n const applyPlacement = (cell: HTMLElement, p: { col: number; row: number; colSpan: number; rowSpan: number }) => {\n cell.style.gridColumn = `${p.col + 1} / span ${p.colSpan}`;\n cell.style.gridRow = `${p.row + 1} / span ${p.rowSpan}`;\n };\n\n if (showPanel) {\n propsCell.style.display = '';\n if (pw) applyPlacement(propsCell, pw);\n if (cw) applyPlacement(chartCell, cw);\n if (indCell && iw) {\n indCell.style.display = '';\n applyPlacement(indCell, iw);\n }\n if (statusCell && sw) applyPlacement(statusCell, sw);\n } else {\n propsCell.style.display = 'none';\n const end = layoutSchema.columns + 1;\n const start = chartAreaColStart();\n chartCell.style.gridColumn = `${start} / ${end}`;\n if (cw) chartCell.style.gridRow = `${cw.row + 1} / span ${cw.rowSpan}`;\n if (indCell && iw) {\n indCell.style.display = '';\n indCell.style.gridColumn = `${start} / ${end}`;\n indCell.style.gridRow = `${iw.row + 1} / span ${iw.rowSpan}`;\n }\n if (statusCell && sw) {\n statusCell.style.gridColumn = `${start} / ${end}`;\n statusCell.style.gridRow = `${sw.row + 1} / span ${sw.rowSpan}`;\n }\n }\n };\n\n const applyLayoutFeatures = () => {\n const f = layoutFeatures;\n\n if (f.showTopBar) {\n topBarHost.replaceChildren();\n const mounted = mountTopBar(\n topBarHost,\n Object.assign(opts, {\n symbolInput: f.symbolInput,\n showSettings: f.showSettings,\n themeProvider: opts.themeProvider ?? themeProvider,\n i18n: opts.i18n ?? i18nProvider,\n onThemeChange: (theme: 'dark' | 'light') => {\n opts.onThemeChange?.(theme);\n if (!opts.onThemeChange) opts.onThemeToggle?.();\n },\n }),\n );\n topBar = mounted.el;\n setActiveInterval = mounted.setActiveInterval;\n } else {\n topBarHost.replaceChildren();\n topBar = topBarHost;\n }\n\n if (f.showLeftToolbar || f.showBottomToolbar) mountLeftToolbar();\n else {\n leftToolbar.replaceChildren();\n bottomToolbar.replaceChildren();\n setActiveDesktop = null;\n setActiveMobile = null;\n }\n\n if (!layerCompositorManaged) {\n (layoutShell as LayoutGridHandle).applySchema(layoutSchema, f);\n }\n\n disposeMobileMq?.();\n const mq = window.matchMedia(MOBILE_MQ);\n const applyMobileTools = () => {\n const features = layoutFeatures;\n const mobile = mq.matches;\n if (features.showLeftToolbar) {\n leftToolbar.style.display = mobile ? 'none' : 'flex';\n }\n if (features.showBottomToolbar) {\n bottomToolbar.style.display = mobile ? 'flex' : 'none';\n const bottomCell = layoutShell.cells.get('bottomToolbar');\n if (bottomCell) {\n bottomCell.style.display = mobile && features.showBottomToolbar ? '' : 'none';\n }\n }\n };\n mq.addEventListener('change', applyMobileTools);\n disposeMobileMq = () => mq.removeEventListener('change', applyMobileTools);\n applyMobileTools();\n\n if (!layerCompositorManaged) {\n crosshairLegend.el.style.display = f.showCrosshairLegend ? '' : 'none';\n }\n\n detachContextMenu();\n if (f.showContextMenu) {\n detachContextMenu = attachChartContextMenu(chartMain, {\n actions: opts.contextMenuActions,\n });\n }\n\n if (f.showShortcuts && !shortcutsBound) {\n bindShortcutsModal();\n shortcutsBound = true;\n }\n\n applyPropertiesPanelLayout(lastSelectedDrawing);\n };\n\n const handleDrawingSelection = (drawing: import('@coderyo/drawings').DrawingRecord | null) => {\n lastSelectedDrawing = drawing;\n propertiesPanel.bind(drawing);\n applyPropertiesPanelLayout(drawing);\n };\n\n opts.onDrawingSelectionBind?.(propertiesPanel.bind);\n applyLayoutFeatures();\n applyPropertiesPanelLayout(null);\n\n let boundCompositorController: import('./layer/layer-controller.js').LayerController | null =\n null;\n\n const syncCompositorShellVisibility = layerCompositorManaged\n ? (controller: import('./layer/layer-controller.js').LayerController) => {\n syncCompositorShellVisibilityFromFeatures(controller, layoutFeatures);\n }\n : undefined;\n\n const syncCompositorShellVisibilityIfBound = () => {\n if (boundCompositorController) {\n syncCompositorShellVisibilityFromFeatures(boundCompositorController, layoutFeatures);\n }\n };\n\n const bindLayerCompositorController = layerCompositorManaged\n ? (controller: import('./layer/layer-controller.js').LayerController) => {\n boundCompositorController = controller;\n syncCompositorShellVisibilityFromFeatures(controller, layoutFeatures);\n }\n : undefined;\n\n return {\n layoutRoot: layoutShell.root,\n layoutGrid: layoutShell.grid,\n chartHost: chartMain,\n chartMain,\n chartVolume,\n drawingOverlay,\n indicatorHost,\n topBar,\n setActiveInterval,\n statusBar,\n crosshairLegend,\n detachContextMenu,\n setActiveDrawingTool,\n propertiesPanel,\n handleDrawingSelection,\n syncCompositorShellVisibility,\n bindLayerCompositorController,\n setLayoutFeatures: (patch) => {\n layoutFeatures = mergeLayoutFeatures(layoutFeatures, patch);\n applyLayoutFeatures();\n syncCompositorShellVisibilityIfBound();\n },\n getLayoutFeatures: () => ({ ...layoutFeatures }),\n getLayoutSchema: () =>\n layerCompositorManaged\n ? layoutSchema\n : (layoutShell as LayoutGridHandle).getSchema(),\n setLayoutSchema: (schema) => {\n if (layerCompositorManaged) return;\n layoutSchema = resolveLayoutSchema(schema);\n const grid = layoutShell as LayoutGridHandle;\n grid.setSchema(layoutSchema);\n grid.applySchema(layoutSchema, layoutFeatures);\n persistLayout(layoutSchema);\n },\n enableLayoutEditor: (enabled) => {\n if (layerCompositorManaged) return;\n (layoutShell as LayoutGridHandle).enableEditor(enabled);\n },\n saveLayout: () => {\n if (layerCompositorManaged) return;\n persistLayout((layoutShell as LayoutGridHandle).getSchema());\n },\n };\n}","import { t } from '@coderyo/i18n';\n\nexport interface ContextMenuAction {\n id: string;\n label: string;\n onClick: () => void;\n}\n\nexport interface ContextMenuOptions {\n actions?: ContextMenuAction[];\n}\n\nexport function attachChartContextMenu(\n chartHost: HTMLElement,\n opts: ContextMenuOptions = {},\n): () => void {\n let menu: HTMLDivElement | null = null;\n\n const close = () => {\n menu?.remove();\n menu = null;\n };\n\n const open = (x: number, y: number) => {\n close();\n menu = document.createElement('div');\n menu.style.cssText =\n 'position:fixed;z-index:50;min-width:160px;padding:4px 0;background:#161b22;border:1px solid #30363d;border-radius:6px;box-shadow:0 8px 24px #01040988;';\n\n const actions: ContextMenuAction[] = opts.actions ?? [\n {\n id: 'fit',\n label: t('context.fitContent', '適配畫面'),\n onClick: () => {},\n },\n ];\n\n for (const action of actions) {\n const row = document.createElement('button');\n row.type = 'button';\n row.textContent = action.label;\n row.style.cssText =\n 'display:block;width:100%;text-align:left;padding:8px 12px;border:none;background:transparent;color:#e6edf3;font-size:12px;cursor:pointer;';\n row.onmouseenter = () => {\n row.style.background = '#21262d';\n };\n row.onmouseleave = () => {\n row.style.background = 'transparent';\n };\n row.onclick = () => {\n action.onClick();\n close();\n };\n menu.appendChild(row);\n }\n\n menu.style.left = `${x}px`;\n menu.style.top = `${y}px`;\n document.body.appendChild(menu);\n };\n\n const onContext = (e: MouseEvent) => {\n e.preventDefault();\n open(e.clientX, e.clientY);\n };\n\n chartHost.addEventListener('contextmenu', onContext);\n document.addEventListener('click', close);\n document.addEventListener('scroll', close, true);\n\n return () => {\n chartHost.removeEventListener('contextmenu', onContext);\n document.removeEventListener('click', close);\n document.removeEventListener('scroll', close, true);\n close();\n };\n}","import type { OhlcvSnapshot } from './status-bar.js';\n\nexport interface CrosshairLegendOptions {\n symbol?: string;\n interval?: string;\n}\n\nexport function mountCrosshairLegend(\n chartHost?: HTMLElement,\n opts: CrosshairLegendOptions = {},\n): {\n el: HTMLElement;\n update: (payload: { time?: number; ohlcv?: OhlcvSnapshot | null }) => void;\n setMeta: (meta: CrosshairLegendOptions) => void;\n hide: () => void;\n} {\n const box = document.createElement('div');\n box.className = 'tv-crosshair-legend';\n box.style.cssText =\n 'display:none;position:absolute;top:8px;left:8px;z-index:10;padding:6px 10px;border-radius:6px;background:#161b22e6;border:1px solid #30363d;font-size:11px;color:#e6edf3;pointer-events:none;line-height:1.5;';\n\n const title = document.createElement('div');\n title.style.cssText = 'color:#8b949e;margin-bottom:2px;';\n const body = document.createElement('div');\n box.append(title, body);\n if (chartHost) chartHost.appendChild(box);\n\n const fmt = (n: number | undefined) =>\n n == null ? '—' : n.toLocaleString(undefined, { maximumFractionDigits: 2 });\n\n const render = (payload: { time?: number; ohlcv?: OhlcvSnapshot | null }) => {\n const parts = [opts.symbol, opts.interval].filter(Boolean);\n title.textContent = parts.length ? parts.join(' · ') : '';\n const o = payload.ohlcv;\n if (!o?.c && o?.o == null) {\n box.style.display = 'none';\n return;\n }\n const timeStr = payload.time != null ? new Date(payload.time).toLocaleString() : '';\n body.textContent = `${timeStr}\\nO ${fmt(o?.o)} H ${fmt(o?.h)} L ${fmt(o?.l)} C ${fmt(o?.c)}`;\n box.style.display = 'block';\n };\n\n return {\n el: box,\n update: render,\n setMeta: (meta) => {\n Object.assign(opts, meta);\n title.textContent = [opts.symbol, opts.interval].filter(Boolean).join(' · ');\n },\n hide: () => {\n box.style.display = 'none';\n },\n };\n}","import type { DrawingRecord } from '@coderyo/drawings';\nimport { t } from '@coderyo/i18n';\n\nexport interface DrawingPropertiesPanelOptions {\n onStyleChange?: (patch: { color?: string; lineWidth?: number; text?: string }) => void;\n}\n\nexport function mountDrawingPropertiesPanel(\n parent: HTMLElement,\n opts: DrawingPropertiesPanelOptions = {},\n): { el: HTMLElement; bind: (drawing: DrawingRecord | null) => void } {\n const panel = document.createElement('aside');\n panel.className = 'tv-drawing-props';\n panel.style.cssText =\n 'display:none;width:100%;max-width:200px;flex-shrink:0;border-left:1px solid #30363d;background:#161b22;padding:10px 12px;font-size:12px;color:#e6edf3;overflow:auto;box-sizing:border-box;';\n\n const title = document.createElement('div');\n title.textContent = t('drawing.props.title', '繪圖屬性');\n title.style.cssText = 'font-weight:600;margin-bottom:10px;';\n\n const typeEl = document.createElement('div');\n typeEl.style.color = '#8b949e';\n typeEl.style.marginBottom = '10px';\n\n const mkRow = (label: string) => {\n const row = document.createElement('label');\n row.style.cssText = 'display:flex;flex-direction:column;gap:4px;margin-bottom:8px;';\n const span = document.createElement('span');\n span.textContent = label;\n span.style.color = '#8b949e';\n row.appendChild(span);\n return row;\n };\n\n const colorRow = mkRow(t('drawing.props.color', '顏色'));\n const colorInput = document.createElement('input');\n colorInput.type = 'color';\n colorInput.style.cssText = 'width:100%;height:28px;border:none;background:transparent;cursor:pointer;';\n colorRow.appendChild(colorInput);\n\n const widthRow = mkRow(t('drawing.props.lineWidth', '線寬'));\n const widthInput = document.createElement('input');\n widthInput.type = 'range';\n widthInput.min = '1';\n widthInput.max = '6';\n widthInput.style.width = '100%';\n widthRow.appendChild(widthInput);\n\n const textRow = mkRow(t('drawing.props.text', '文字'));\n const textInput = document.createElement('input');\n textInput.type = 'text';\n textInput.style.cssText =\n 'padding:4px 8px;border-radius:4px;border:1px solid #30363d;background:#0d1117;color:#e6edf3;';\n textRow.appendChild(textInput);\n\n const lockedHint = document.createElement('div');\n lockedHint.style.cssText = 'color:#f78166;font-size:11px;margin-top:6px;display:none;';\n lockedHint.textContent = t('drawing.props.locked', '已鎖定 — 解鎖後可編輯');\n\n panel.append(title, typeEl, colorRow, widthRow, textRow, lockedHint);\n parent.appendChild(panel);\n\n const emit = () => {\n opts.onStyleChange?.({\n color: colorInput.value,\n lineWidth: Number(widthInput.value),\n text: textInput.value,\n });\n };\n colorInput.oninput = emit;\n widthInput.oninput = emit;\n textInput.oninput = emit;\n\n const bind = (drawing: DrawingRecord | null) => {\n if (!drawing) {\n panel.style.display = 'none';\n return;\n }\n panel.style.display = 'block';\n typeEl.textContent = `${t('drawing.props.type', '類型')}: ${drawing.type}`;\n const meta = drawing.meta ?? {};\n colorInput.value = String(meta.color ?? '#58a6ff');\n widthInput.value = String(meta.lineWidth ?? 2);\n textInput.value = String(meta.text ?? 'Note');\n textRow.style.display = drawing.type === 'text' ? 'flex' : 'none';\n const locked = Boolean(meta.locked);\n lockedHint.style.display = locked ? 'block' : 'none';\n colorInput.disabled = locked;\n widthInput.disabled = locked;\n textInput.disabled = locked;\n };\n\n return { el: panel, bind };\n}","/** Host for MACD / RSI / KDJ indicator panes (PR-11). */\nexport function mountIndicatorPaneHost(parent: HTMLElement): HTMLElement {\n const host = document.createElement('div');\n host.dataset.tradviewIndicatorHost = '1';\n host.style.cssText =\n 'display:flex;flex-direction:column;flex:2;min-height:120px;border-top:1px solid #30363d;background:#0d1117;overflow:hidden;';\n parent.appendChild(host);\n return host;\n}","/** Visual layout schema (grid-based composable shell). */\n\nexport type LayoutWidgetId =\n | 'topBar'\n | 'leftToolbar'\n | 'bottomToolbar'\n | 'chartHost'\n | 'indicatorHost'\n | 'statusBar'\n | 'propertiesPanel';\n\nexport interface LayoutWidgetPlacement {\n id: LayoutWidgetId;\n col: number;\n row: number;\n colSpan: number;\n rowSpan: number;\n}\n\nexport interface LayoutSchema {\n version: 1;\n columns: number;\n rows: number;\n widgets: LayoutWidgetPlacement[];\n}\n\nexport const LAYOUT_SCHEMA_VERSION = 1 as const;\n\n/** TV-style default when integrator omits `layout` (matches legacy mountChartLayout proportions). */\nexport const DEFAULT_LAYOUT_SCHEMA: LayoutSchema = {\n version: 1,\n columns: 12,\n rows: 12,\n widgets: [\n { id: 'topBar', col: 0, row: 0, colSpan: 12, rowSpan: 1 },\n { id: 'leftToolbar', col: 0, row: 1, colSpan: 1, rowSpan: 10 },\n { id: 'chartHost', col: 1, row: 1, colSpan: 9, rowSpan: 6 },\n { id: 'indicatorHost', col: 1, row: 7, colSpan: 9, rowSpan: 2 },\n { id: 'statusBar', col: 1, row: 9, colSpan: 9, rowSpan: 1 },\n { id: 'propertiesPanel', col: 10, row: 1, colSpan: 2, rowSpan: 9 },\n { id: 'bottomToolbar', col: 0, row: 11, colSpan: 12, rowSpan: 1 },\n ],\n};\n\nexport function layoutStorageKey(layoutId: string): string {\n return `tradview:layout:v${LAYOUT_SCHEMA_VERSION}:${layoutId}`;\n}\n\nexport function resolveLayoutSchema(\n partial?: LayoutSchema | null,\n): LayoutSchema {\n if (!partial) return cloneLayoutSchema(DEFAULT_LAYOUT_SCHEMA);\n return normalizeLayoutSchema(partial);\n}\n\nexport function cloneLayoutSchema(schema: LayoutSchema): LayoutSchema {\n return {\n version: 1,\n columns: schema.columns,\n rows: schema.rows,\n widgets: schema.widgets.map((w) => ({ ...w })),\n };\n}\n\nexport function normalizeLayoutSchema(input: LayoutSchema): LayoutSchema {\n const columns = Math.max(4, Math.min(24, input.columns || 12));\n const rows = Math.max(4, Math.min(24, input.rows || 12));\n const widgets: LayoutWidgetPlacement[] = [];\n const seen = new Set<LayoutWidgetId>();\n for (const w of input.widgets ?? []) {\n if (!isLayoutWidgetId(w.id) || seen.has(w.id)) continue;\n seen.add(w.id);\n widgets.push(clampPlacement(w, columns, rows));\n }\n for (const d of DEFAULT_LAYOUT_SCHEMA.widgets) {\n if (!seen.has(d.id)) widgets.push({ ...d });\n }\n return { version: 1, columns, rows, widgets };\n}\n\nfunction clampPlacement(\n w: LayoutWidgetPlacement,\n columns: number,\n rows: number,\n): LayoutWidgetPlacement {\n const colSpan = Math.max(1, Math.min(columns, w.colSpan || 1));\n const rowSpan = Math.max(1, Math.min(rows, w.rowSpan || 1));\n const col = Math.max(0, Math.min(columns - colSpan, w.col || 0));\n const row = Math.max(0, Math.min(rows - rowSpan, w.row || 0));\n return { id: w.id, col, row, colSpan, rowSpan };\n}\n\nfunction isLayoutWidgetId(id: string): id is LayoutWidgetId {\n return (\n id === 'topBar' ||\n id === 'leftToolbar' ||\n id === 'bottomToolbar' ||\n id === 'chartHost' ||\n id === 'indicatorHost' ||\n id === 'statusBar' ||\n id === 'propertiesPanel'\n );\n}\n\nexport function loadLayoutSchema(layoutId: string): LayoutSchema | null {\n try {\n const raw = localStorage.getItem(layoutStorageKey(layoutId));\n if (!raw) return null;\n return normalizeLayoutSchema(JSON.parse(raw) as LayoutSchema);\n } catch {\n return null;\n }\n}\n\nexport function saveLayoutSchema(layoutId: string, schema: LayoutSchema): void {\n try {\n localStorage.setItem(layoutStorageKey(layoutId), JSON.stringify(normalizeLayoutSchema(schema)));\n } catch {\n /* ignore */\n }\n}\n\nexport function getWidgetPlacement(\n schema: LayoutSchema,\n id: LayoutWidgetId,\n): LayoutWidgetPlacement | undefined {\n return schema.widgets.find((w) => w.id === id);\n}","import type { ResolvedLayoutFeatures } from './layout-features.js';\nimport {\n cloneLayoutSchema,\n type LayoutSchema,\n type LayoutWidgetId,\n type LayoutWidgetPlacement,\n} from './layout-schema.js';\n\nexport type LayoutWidgetElements = Partial<Record<LayoutWidgetId, HTMLElement>>;\n\nexport interface LayoutGridHandle {\n root: HTMLElement;\n grid: HTMLElement;\n cells: Map<LayoutWidgetId, HTMLElement>;\n applySchema: (schema: LayoutSchema, features: ResolvedLayoutFeatures) => void;\n enableEditor: (enabled: boolean) => void;\n getSchema: () => LayoutSchema;\n setSchema: (schema: LayoutSchema) => void;\n destroyEditor: () => void;\n}\n\nexport interface CreateLayoutGridOptions {\n schema: LayoutSchema;\n widgets: LayoutWidgetElements;\n features: ResolvedLayoutFeatures;\n editor?: boolean;\n onSchemaChange?: (schema: LayoutSchema) => void;\n}\n\nexport function createLayoutGrid(opts: CreateLayoutGridOptions): LayoutGridHandle {\n let schema = cloneLayoutSchema(opts.schema);\n const cells = new Map<LayoutWidgetId, HTMLElement>();\n\n const root = document.createElement('div');\n root.className = 'tv-layout-root';\n root.style.cssText =\n 'display:flex;flex-direction:column;flex:1;min-height:0;min-width:0;width:100%;height:100%;box-sizing:border-box;';\n\n const grid = document.createElement('div');\n grid.className = 'tv-layout-grid';\n grid.style.cssText =\n 'display:grid;flex:1;min-height:0;min-width:0;width:100%;position:relative;gap:0;';\n root.appendChild(grid);\n\n for (const w of schema.widgets) {\n const cell = document.createElement('div');\n cell.className = `tv-layout-cell tv-layout-cell--${w.id}`;\n cell.dataset.widgetId = w.id;\n cell.style.cssText =\n 'min-width:0;min-height:0;overflow:hidden;position:relative;box-sizing:border-box;';\n const el = opts.widgets[w.id];\n if (el) {\n el.style.width = '100%';\n el.style.height = '100%';\n el.style.minWidth = '0';\n el.style.minHeight = '0';\n if (w.id === 'chartHost') el.style.position = 'relative';\n cell.appendChild(el);\n }\n cells.set(w.id, cell);\n grid.appendChild(cell);\n }\n\n let editorCtl: LayoutEditorController | null = null;\n\n const applySchema = (next: LayoutSchema, features: ResolvedLayoutFeatures) => {\n schema = cloneLayoutSchema(next);\n applyGridTemplate(grid, schema, features);\n for (const w of schema.widgets) {\n const cell = cells.get(w.id);\n if (!cell) continue;\n applyPlacementStyle(cell, w);\n const visible = widgetVisible(w.id, features);\n cell.style.display = visible ? '' : 'none';\n cell.style.pointerEvents = visible ? '' : 'none';\n }\n editorCtl?.refresh(schema);\n };\n\n const enableEditor = (enabled: boolean) => {\n if (enabled) {\n if (!editorCtl) {\n editorCtl = new LayoutEditorController(grid, cells, schema, (s) => {\n schema = s;\n opts.onSchemaChange?.(s);\n });\n }\n editorCtl.enable(true);\n root.classList.add('tv-layout--edit');\n } else {\n editorCtl?.enable(false);\n root.classList.remove('tv-layout--edit');\n }\n };\n\n applySchema(schema, opts.features);\n if (opts.editor) enableEditor(true);\n\n return {\n root,\n grid,\n cells,\n applySchema,\n enableEditor,\n getSchema: () => cloneLayoutSchema(schema),\n setSchema: (s) => {\n schema = cloneLayoutSchema(s);\n applySchema(schema, opts.features);\n },\n destroyEditor: () => {\n editorCtl?.destroy();\n editorCtl = null;\n },\n };\n}\n\nfunction widgetVisible(id: LayoutWidgetId, f: ResolvedLayoutFeatures): boolean {\n switch (id) {\n case 'topBar':\n return f.showTopBar;\n case 'leftToolbar':\n return f.showLeftToolbar;\n case 'bottomToolbar':\n return f.showBottomToolbar;\n case 'statusBar':\n return f.showStatusBar;\n case 'propertiesPanel':\n return f.showPropertiesPanel;\n case 'chartHost':\n case 'indicatorHost':\n return true;\n default:\n return true;\n }\n}\n\nconst LEFT_TOOLBAR_COL_PX = 44;\n\nfunction applyGridTemplate(\n grid: HTMLElement,\n schema: LayoutSchema,\n features?: ResolvedLayoutFeatures,\n): void {\n const narrowToolbar = features?.showLeftToolbar ?? false;\n if (narrowToolbar && schema.columns >= 2) {\n grid.style.gridTemplateColumns = `${LEFT_TOOLBAR_COL_PX}px repeat(${schema.columns - 1}, minmax(0, 1fr))`;\n } else {\n grid.style.gridTemplateColumns = `repeat(${schema.columns}, minmax(0, 1fr))`;\n }\n grid.style.gridTemplateRows = `repeat(${schema.rows}, minmax(0, 1fr))`;\n}\n\nfunction applyPlacementStyle(cell: HTMLElement, w: LayoutWidgetPlacement): void {\n cell.style.gridColumn = `${w.col + 1} / span ${w.colSpan}`;\n cell.style.gridRow = `${w.row + 1} / span ${w.rowSpan}`;\n}\n\nclass LayoutEditorController {\n private enabled = false;\n private drag: {\n id: LayoutWidgetId;\n startX: number;\n startY: number;\n origin: LayoutWidgetPlacement;\n } | null = null;\n private resize: {\n id: LayoutWidgetId;\n startX: number;\n startY: number;\n origin: LayoutWidgetPlacement;\n } | null = null;\n private readonly cleanups: Array<() => void> = [];\n\n constructor(\n private readonly grid: HTMLElement,\n private readonly cells: Map<LayoutWidgetId, HTMLElement>,\n private schema: LayoutSchema,\n private readonly onChange: (schema: LayoutSchema) => void,\n ) {}\n\n refresh(schema: LayoutSchema): void {\n this.schema = cloneLayoutSchema(schema);\n for (const w of this.schema.widgets) {\n const cell = this.cells.get(w.id);\n if (cell) applyPlacementStyle(cell, w);\n }\n }\n\n enable(on: boolean): void {\n if (this.enabled === on) return;\n this.enabled = on;\n if (on) this.bind();\n else this.unbind();\n }\n\n destroy(): void {\n this.enable(false);\n }\n\n private bind(): void {\n for (const [id, cell] of this.cells) {\n const handle = document.createElement('div');\n handle.className = 'tv-layout-drag-handle';\n handle.title = `Drag ${id}`;\n handle.style.cssText =\n 'position:absolute;top:2px;left:2px;z-index:20;padding:2px 6px;font-size:10px;background:#388bfd;color:#fff;border-radius:3px;cursor:grab;user-select:none;opacity:0.85;';\n handle.textContent = id;\n\n const resize = document.createElement('div');\n resize.className = 'tv-layout-resize-handle';\n resize.title = 'Resize';\n resize.style.cssText =\n 'position:absolute;right:2px;bottom:2px;width:12px;height:12px;z-index:20;background:#388bfd;border-radius:2px;cursor:nwse-resize;opacity:0.85;';\n\n cell.style.outline = '1px dashed #388bfd';\n cell.appendChild(handle);\n cell.appendChild(resize);\n\n const onDragDown = (ev: PointerEvent) => {\n ev.preventDefault();\n const p = getPlacement(this.schema, id);\n if (!p) return;\n this.drag = { id, startX: ev.clientX, startY: ev.clientY, origin: { ...p } };\n handle.setPointerCapture(ev.pointerId);\n };\n const onDragMove = (ev: PointerEvent) => {\n if (!this.drag || this.drag.id !== id) return;\n const delta = pixelDeltaToGrid(this.grid, this.schema, ev.clientX - this.drag.startX, ev.clientY - this.drag.startY);\n const next = clampPlacement(\n {\n ...this.drag.origin,\n col: this.drag.origin.col + delta.dCol,\n row: this.drag.origin.row + delta.dRow,\n },\n this.schema,\n );\n updatePlacement(this.schema, next);\n applyPlacementStyle(cell, next);\n };\n const onDragUp = (ev: PointerEvent) => {\n if (!this.drag || this.drag.id !== id) return;\n this.drag = null;\n handle.releasePointerCapture(ev.pointerId);\n this.onChange(cloneLayoutSchema(this.schema));\n };\n\n const onResizeDown = (ev: PointerEvent) => {\n ev.preventDefault();\n ev.stopPropagation();\n const p = getPlacement(this.schema, id);\n if (!p) return;\n this.resize = { id, startX: ev.clientX, startY: ev.clientY, origin: { ...p } };\n resize.setPointerCapture(ev.pointerId);\n };\n const onResizeMove = (ev: PointerEvent) => {\n if (!this.resize || this.resize.id !== id) return;\n const delta = pixelDeltaToGrid(this.grid, this.schema, ev.clientX - this.resize.startX, ev.clientY - this.resize.startY);\n const next = clampPlacement(\n {\n ...this.resize.origin,\n colSpan: this.resize.origin.colSpan + delta.dCol,\n rowSpan: this.resize.origin.rowSpan + delta.dRow,\n },\n this.schema,\n );\n updatePlacement(this.schema, next);\n applyPlacementStyle(cell, next);\n };\n const onResizeUp = (ev: PointerEvent) => {\n if (!this.resize || this.resize.id !== id) return;\n this.resize = null;\n resize.releasePointerCapture(ev.pointerId);\n this.onChange(cloneLayoutSchema(this.schema));\n };\n\n handle.addEventListener('pointerdown', onDragDown);\n handle.addEventListener('pointermove', onDragMove);\n handle.addEventListener('pointerup', onDragUp);\n resize.addEventListener('pointerdown', onResizeDown);\n resize.addEventListener('pointermove', onResizeMove);\n resize.addEventListener('pointerup', onResizeUp);\n\n this.cleanups.push(() => {\n handle.remove();\n resize.remove();\n cell.style.outline = '';\n });\n }\n }\n\n private unbind(): void {\n for (const fn of this.cleanups) fn();\n this.cleanups.length = 0;\n this.drag = null;\n this.resize = null;\n }\n}\n\nfunction getPlacement(schema: LayoutSchema, id: LayoutWidgetId): LayoutWidgetPlacement | undefined {\n return schema.widgets.find((w) => w.id === id);\n}\n\nfunction updatePlacement(schema: LayoutSchema, p: LayoutWidgetPlacement): void {\n const i = schema.widgets.findIndex((w) => w.id === p.id);\n if (i >= 0) schema.widgets[i] = p;\n}\n\nfunction clampPlacement(p: LayoutWidgetPlacement, schema: LayoutSchema): LayoutWidgetPlacement {\n const colSpan = Math.max(1, Math.min(schema.columns - p.col, p.colSpan));\n const rowSpan = Math.max(1, Math.min(schema.rows - p.row, p.rowSpan));\n const col = Math.max(0, Math.min(schema.columns - colSpan, p.col));\n const row = Math.max(0, Math.min(schema.rows - rowSpan, p.row));\n return { ...p, col, row, colSpan, rowSpan };\n}\n\nfunction pixelDeltaToGrid(\n grid: HTMLElement,\n schema: LayoutSchema,\n dx: number,\n dy: number,\n): { dCol: number; dRow: number } {\n const rect = grid.getBoundingClientRect();\n const cellW = rect.width / schema.columns;\n const cellH = rect.height / schema.rows;\n return {\n dCol: cellW > 0 ? Math.round(dx / cellW) : 0,\n dRow: cellH > 0 ? Math.round(dy / cellH) : 0,\n };\n}","import type { ResolvedLayoutFeatures } from '../layout-features.js';\nimport type { LayoutWidgetId } from '../layout-schema.js';\n\nexport type CompositorShellWidgetId = LayoutWidgetId;\n\nexport interface CompositorShellHandle {\n root: HTMLElement;\n /** Hidden anchor grid (v2 compositor positions widgets; no 12×12 layout). */\n grid: HTMLElement;\n cells: Map<CompositorShellWidgetId, HTMLElement>;\n}\n\nexport interface CreateCompositorShellOptions {\n widgets: Partial<Record<CompositorShellWidgetId, HTMLElement>>;\n}\n\n/** Minimal DOM shell for LayoutPreset v2 — replaces legacy createLayoutGrid when compositor-managed. */\nexport function createCompositorShell(\n opts: CreateCompositorShellOptions,\n): CompositorShellHandle {\n const cells = new Map<CompositorShellWidgetId, HTMLElement>();\n\n const root = document.createElement('div');\n root.className = 'tv-layout-root tv-layout-root--compositor';\n root.style.cssText =\n 'display:flex;flex-direction:column;flex:1;min-height:0;min-width:0;width:100%;height:100%;box-sizing:border-box;position:relative;';\n\n const grid = document.createElement('div');\n grid.className = 'tv-compositor-shell-grid';\n grid.style.cssText =\n 'position:absolute;inset:0;overflow:hidden;visibility:hidden;pointer-events:none;z-index:0;';\n root.appendChild(grid);\n\n const widgetIds: CompositorShellWidgetId[] = [\n 'topBar',\n 'leftToolbar',\n 'bottomToolbar',\n 'chartHost',\n 'indicatorHost',\n 'statusBar',\n 'propertiesPanel',\n ];\n\n for (const id of widgetIds) {\n const cell = document.createElement('div');\n cell.className = `tv-layout-cell tv-layout-cell--${id}`;\n cell.dataset.widgetId = id;\n cell.style.cssText =\n 'position:absolute;left:0;top:0;width:100%;height:100%;min-width:0;min-height:0;overflow:hidden;box-sizing:border-box;';\n const el = opts.widgets[id];\n if (el) {\n el.style.width = '100%';\n el.style.height = '100%';\n el.style.minWidth = '0';\n el.style.minHeight = '0';\n if (id === 'chartHost') el.style.position = 'relative';\n cell.appendChild(el);\n }\n cells.set(id, cell);\n grid.appendChild(cell);\n }\n\n return { root, grid, cells };\n}\n\n/** No-op schema apply for compositor shell (features still drive widget mount in chart-layout). */\nexport function applyCompositorShellFeatures(\n _cells: Map<CompositorShellWidgetId, HTMLElement>,\n _features: ResolvedLayoutFeatures,\n): void {\n /* visibility driven by LayerCompositor + syncCompositorShellVisibility */\n}","import type { ResolvedLayoutFeatures } from '../layout-features.js';\nimport type { LayerController } from './layer-controller.js';\nimport type { LayerNode } from './types.js';\n\ntype ShellFeatureKey = keyof Pick<\n ResolvedLayoutFeatures,\n | 'showTopBar'\n | 'showLeftToolbar'\n | 'showBottomToolbar'\n | 'showStatusBar'\n | 'showPropertiesPanel'\n | 'showCrosshairLegend'\n>;\n\nconst SHELL_FEATURE_KEYS: ShellFeatureKey[] = [\n 'showTopBar',\n 'showLeftToolbar',\n 'showBottomToolbar',\n 'showStatusBar',\n 'showPropertiesPanel',\n 'showCrosshairLegend',\n];\n\nfunction shellLayerMatchesFeature(layer: LayerNode, feature: ShellFeatureKey): boolean {\n switch (feature) {\n case 'showTopBar':\n return layer.type === 'shell.topBar' || layer.widgetKey === 'topBar';\n case 'showLeftToolbar':\n return layer.type === 'shell.leftToolbar' || layer.widgetKey === 'leftToolbar';\n case 'showBottomToolbar':\n return layer.type === 'shell.bottomToolbar' || layer.widgetKey === 'bottomToolbar';\n case 'showStatusBar':\n return layer.type === 'shell.statusBar' || layer.widgetKey === 'statusBar';\n case 'showPropertiesPanel':\n return layer.type === 'shell.propertiesPanel' || layer.widgetKey === 'propertiesPanel';\n case 'showCrosshairLegend':\n return (\n layer.type === 'overlay.crosshairLegend' || layer.widgetKey === 'crosshairLegend'\n );\n default:\n return false;\n }\n}\n\n/** Map `LayoutFeatures` toggles to compositor layer.visible on the active page. */\nexport function syncCompositorShellVisibilityFromFeatures(\n controller: LayerController,\n features: ResolvedLayoutFeatures,\n): void {\n const pageLayers = controller.getLayersForActivePage();\n for (const feature of SHELL_FEATURE_KEYS) {\n const visible = features[feature];\n for (const layer of pageLayers) {\n if (shellLayerMatchesFeature(layer, feature)) {\n controller.setLayerVisible(layer.id, visible);\n }\n }\n }\n}","import type { ChartLayoutOptions } from './chart-layout.js';\n\nexport interface LayoutFeatures {\n showTopBar?: boolean;\n showLeftToolbar?: boolean;\n showBottomToolbar?: boolean;\n showCrosshairLegend?: boolean;\n showStatusBar?: boolean;\n showPropertiesPanel?: boolean;\n showContextMenu?: boolean;\n showSettings?: boolean;\n showShortcuts?: boolean;\n /** When TopBar is on and no search API: manual symbol input (default). */\n symbolInput?: 'manual' | 'search' | 'dialog' | 'none';\n}\n\nexport interface ResolvedLayoutFeatures {\n showTopBar: boolean;\n showLeftToolbar: boolean;\n showBottomToolbar: boolean;\n showCrosshairLegend: boolean;\n showStatusBar: boolean;\n showPropertiesPanel: boolean;\n showContextMenu: boolean;\n showSettings: boolean;\n showShortcuts: boolean;\n symbolInput: 'manual' | 'search' | 'dialog' | 'none';\n}\n\nexport const DEFAULT_LAYOUT_FEATURES: ResolvedLayoutFeatures = {\n showTopBar: false,\n showLeftToolbar: false,\n showBottomToolbar: false,\n showCrosshairLegend: false,\n showStatusBar: false,\n showPropertiesPanel: false,\n showContextMenu: false,\n showSettings: false,\n showShortcuts: false,\n symbolInput: 'manual',\n};\n\nexport function resolveLayoutFeatures(\n opts: ChartLayoutOptions = {},\n): ResolvedLayoutFeatures {\n const d = DEFAULT_LAYOUT_FEATURES;\n const top = opts.showTopBar ?? d.showTopBar;\n return {\n showTopBar: top,\n showLeftToolbar: opts.showLeftToolbar ?? d.showLeftToolbar,\n showBottomToolbar: opts.showBottomToolbar ?? d.showBottomToolbar,\n showCrosshairLegend: opts.showCrosshairLegend ?? d.showCrosshairLegend,\n showStatusBar: opts.showStatusBar ?? d.showStatusBar,\n showPropertiesPanel: opts.showPropertiesPanel ?? d.showPropertiesPanel,\n showContextMenu: opts.showContextMenu ?? d.showContextMenu,\n showSettings: opts.settings !== undefined ? (opts.showSettings ?? true) : (opts.showSettings ?? d.showSettings),\n showShortcuts: opts.showShortcuts ?? d.showShortcuts,\n symbolInput: opts.symbolInput ?? (opts.onSymbolSearch ? 'search' : d.symbolInput),\n };\n}\n\nexport function mergeLayoutFeatures(\n current: ResolvedLayoutFeatures,\n patch: LayoutFeatures,\n): ResolvedLayoutFeatures {\n return resolveLayoutFeatures({\n showTopBar: patch.showTopBar ?? current.showTopBar,\n showLeftToolbar: patch.showLeftToolbar ?? current.showLeftToolbar,\n showBottomToolbar: patch.showBottomToolbar ?? current.showBottomToolbar,\n showCrosshairLegend: patch.showCrosshairLegend ?? current.showCrosshairLegend,\n showStatusBar: patch.showStatusBar ?? current.showStatusBar,\n showPropertiesPanel: patch.showPropertiesPanel ?? current.showPropertiesPanel,\n showContextMenu: patch.showContextMenu ?? current.showContextMenu,\n showSettings: patch.showSettings ?? current.showSettings,\n showShortcuts: patch.showShortcuts ?? current.showShortcuts,\n symbolInput: patch.symbolInput ?? current.symbolInput,\n });\n}\n\n/** Playground: enable full TV shell. */\nexport function createDemoLayoutOptions(\n partial: ChartLayoutOptions = {},\n): ChartLayoutOptions {\n return {\n ...partial,\n showTopBar: partial.showTopBar ?? true,\n showLeftToolbar: partial.showLeftToolbar ?? true,\n showCrosshairLegend: partial.showCrosshairLegend ?? true,\n showStatusBar: partial.showStatusBar ?? true,\n showPropertiesPanel: partial.showPropertiesPanel ?? true,\n showContextMenu: partial.showContextMenu ?? true,\n showSettings: partial.showSettings ?? true,\n showShortcuts: partial.showShortcuts ?? true,\n showBottomToolbar: partial.showBottomToolbar ?? true,\n symbolInput: partial.symbolInput ?? (partial.onSymbolSearch ? 'search' : 'manual'),\n };\n}","import { getLocale, setLocale, t } from '@coderyo/i18n';\n\nexport interface OhlcvSnapshot {\n o?: number;\n h?: number;\n l?: number;\n c?: number;\n v?: number;\n}\n\nexport interface StatusBarOptions {\n connection?: string;\n symbol?: string;\n interval?: string;\n ohlcv?: OhlcvSnapshot | null;\n locale?: string;\n onLocaleChange?: (locale: string) => void;\n}\n\nfunction fmt(n: number | undefined, digits = 2): string {\n if (n == null || Number.isNaN(n)) return '—';\n return n.toLocaleString(undefined, { maximumFractionDigits: digits });\n}\n\nexport function mountStatusBar(parent: HTMLElement, opts: StatusBarOptions = {}): {\n el: HTMLElement;\n update: (patch: StatusBarOptions) => void;\n} {\n const bar = document.createElement('div');\n bar.className = 'tv-statusbar';\n bar.style.cssText =\n 'display:flex;align-items:center;gap:14px;padding:6px 12px;font-size:11px;color:#8b949e;border-top:1px solid #30363d;background:#161b22;flex-shrink:0;';\n\n const conn = document.createElement('span');\n const sym = document.createElement('span');\n const ohlcv = document.createElement('span');\n ohlcv.style.flex = '1';\n ohlcv.style.color = '#e6edf3';\n\n const localeWrap = document.createElement('label');\n localeWrap.style.cssText = 'display:flex;align-items:center;gap:4px;margin-left:auto;';\n const localeLabel = document.createElement('span');\n localeLabel.textContent = t('status.locale', '語系');\n const localeSelect = document.createElement('select');\n localeSelect.style.cssText =\n 'background:#0d1117;color:#e6edf3;border:1px solid #30363d;border-radius:4px;font-size:11px;padding:2px 4px;';\n for (const loc of ['zh-TW', 'en']) {\n const opt = document.createElement('option');\n opt.value = loc;\n opt.textContent = loc;\n localeSelect.appendChild(opt);\n }\n localeSelect.value = opts.locale ?? getLocale();\n localeSelect.onchange = () => {\n setLocale(localeSelect.value);\n opts.onLocaleChange?.(localeSelect.value);\n localeLabel.textContent = t('status.locale', '語系');\n render(opts);\n };\n localeWrap.append(localeLabel, localeSelect);\n\n bar.append(conn, sym, ohlcv, localeWrap);\n parent.appendChild(bar);\n\n const render = (state: StatusBarOptions) => {\n const merged = { ...opts, ...state };\n conn.textContent = `${t('status.connection', '連線')}:${merged.connection ?? '—'}`;\n const parts = [merged.symbol, merged.interval].filter(Boolean);\n sym.textContent = parts.length ? parts.join(' · ') : '';\n const o = merged.ohlcv;\n if (o && (o.o != null || o.c != null)) {\n ohlcv.textContent = `O ${fmt(o.o)} H ${fmt(o.h)} L ${fmt(o.l)} C ${fmt(o.c)} V ${fmt(o.v, 0)}`;\n } else {\n ohlcv.textContent = t('status.ohlcvHint', '移動十字線查看 OHLCV');\n }\n };\n\n render(opts);\n return {\n el: bar,\n update: (patch) => {\n Object.assign(opts, patch);\n render(opts);\n },\n };\n}","import { t } from '@coderyo/i18n';\n\nconst SHORTCUTS: Array<{ key: string; desc: string }> = [\n { key: '↖ / Esc', desc: '游標(選取/編輯繪圖)' },\n { key: 'Delete', desc: '刪除選中繪圖' },\n { key: 'R', desc: '適配畫面' },\n { key: 'End', desc: '跳到最新 K 線' },\n { key: 'F', desc: '全螢幕' },\n { key: 'S', desc: '截圖 PNG' },\n { key: 'L', desc: '對數價格軸' },\n { key: 'T', desc: '切換主題' },\n { key: '?', desc: '本說明' },\n];\n\nexport function bindShortcutsModal(): () => void {\n const handler = (e: KeyboardEvent) => {\n if (e.key !== '?' || e.ctrlKey || e.metaKey) return;\n const tag = (e.target as HTMLElement)?.tagName;\n if (tag === 'INPUT' || tag === 'TEXTAREA' || tag === 'SELECT') return;\n e.preventDefault();\n openShortcutsModal();\n };\n window.addEventListener('keydown', handler);\n return () => window.removeEventListener('keydown', handler);\n}\n\nexport function openShortcutsModal(): void {\n const backdrop = document.createElement('div');\n backdrop.style.cssText =\n 'position:fixed;inset:0;z-index:100;background:#01040999;display:flex;align-items:center;justify-content:center;';\n\n const box = document.createElement('div');\n box.style.cssText =\n 'min-width:320px;max-width:90vw;padding:16px 20px;background:#161b22;border:1px solid #30363d;border-radius:8px;color:#e6edf3;';\n\n const h = document.createElement('h2');\n h.textContent = t('shortcuts.title', '快捷鍵');\n h.style.cssText = 'font-size:16px;margin:0 0 12px;';\n\n const list = document.createElement('div');\n list.style.cssText = 'font-size:13px;line-height:1.8;';\n for (const s of SHORTCUTS) {\n const row = document.createElement('div');\n row.innerHTML = `<kbd style=\"background:#21262d;padding:2px 6px;border-radius:4px;margin-right:8px;\">${s.key}</kbd>${s.desc}`;\n list.appendChild(row);\n }\n\n const closeBtn = document.createElement('button');\n closeBtn.type = 'button';\n closeBtn.textContent = t('shortcuts.close', '關閉');\n closeBtn.style.cssText =\n 'margin-top:14px;padding:6px 14px;background:#21262d;color:#e6edf3;border:1px solid #30363d;border-radius:4px;cursor:pointer;';\n const close = () => backdrop.remove();\n closeBtn.onclick = close;\n backdrop.onclick = (e) => {\n if (e.target === backdrop) close();\n };\n\n box.append(h, list, closeBtn);\n backdrop.appendChild(box);\n document.body.appendChild(backdrop);\n}","/** LayoutPreset v2 — free-floating layer compositor (replaces layout-schema v1). */\n\nexport const LAYER_PRESET_VERSION = 2 as const;\n\nexport type LayerPresetAuthor = 'integrator' | 'user';\n\nexport type LayerType =\n | 'shell.topBar'\n | 'shell.leftToolbar'\n | 'shell.bottomToolbar'\n | 'shell.statusBar'\n | 'shell.propertiesPanel'\n | 'chart.host'\n | 'chart.main'\n | 'chart.volume'\n | 'chart.indicator'\n | 'chart.indicatorHost'\n | 'overlay.crosshairLegend'\n | 'overlay.drawing'\n | 'group';\n\n/** Normalized frame relative to page root (0..1). */\nexport interface LayerFrame {\n x: number;\n y: number;\n w: number;\n h: number;\n}\n\nexport interface LayoutPage {\n id: string;\n title: string;\n}\n\nexport interface LayerNode {\n id: string;\n pageId: string;\n type: LayerType;\n /** Maps to legacy widget id or chart role for mount. */\n widgetKey: string;\n frame: LayerFrame;\n zIndex: number;\n visible: boolean;\n locked: boolean;\n groupId?: string;\n /**\n * @public Time-scale sync group for chart panes. Same non-empty id → pan/zoom together;\n * omit or empty → pane is independent (own TimeScaleBus).\n */\n syncTimeScaleGroupId?: string;\n}\n\nexport interface BindGroup {\n id: string;\n name?: string;\n layerIds: string[];\n}\n\nexport interface LayoutPreset {\n version: typeof LAYER_PRESET_VERSION;\n /**\n * Monotonic revision for remote `host.layer.setPreset` merge/replace (integer ≥ 1).\n * @public Bridge schema 2 — stale host revision is rejected with `STALE_PRESET_REVISION`.\n */\n revision?: number;\n id: string;\n name: string;\n author: LayerPresetAuthor;\n readonly?: boolean;\n forkedFrom?: string;\n pages: LayoutPage[];\n layers: LayerNode[];\n groups: BindGroup[];\n}\n\nexport type LayerWidgetKey =\n | 'topBar'\n | 'leftToolbar'\n | 'bottomToolbar'\n | 'chartHost'\n | 'chartMain'\n | 'chartVolume'\n | 'chartIndicator'\n | 'indicatorHost'\n | 'statusBar'\n | 'propertiesPanel'\n | 'crosshairLegend'\n | 'drawingOverlay';","import type { LayerNode, LayerType } from './types.js';\n\nexport const OVERLAY_LAYER_TYPES: readonly LayerType[] = [\n 'overlay.crosshairLegend',\n 'overlay.drawing',\n] as const;\n\nexport function isOverlayLayerType(type: string): type is LayerType {\n return (OVERLAY_LAYER_TYPES as readonly string[]).includes(type);\n}\n\n/** Anchor crosshair legend + drawing overlay frames to chart.main on one page (P3). */\nexport function syncOverlayLayersToMain(layers: LayerNode[], pageId: string): void {\n const main = layers.find((l) => l.type === 'chart.main' && l.pageId === pageId);\n if (!main) return;\n\n const legend = layers.find(\n (l) => l.type === 'overlay.crosshairLegend' && l.pageId === pageId,\n );\n if (legend) {\n legend.frame = {\n x: main.frame.x,\n y: main.frame.y,\n w: Math.min(0.35, main.frame.w),\n h: Math.min(0.1, main.frame.h),\n };\n }\n\n const drawing = layers.find((l) => l.type === 'overlay.drawing' && l.pageId === pageId);\n if (drawing) {\n drawing.frame = {\n x: main.frame.x,\n y: main.frame.y,\n w: main.frame.w,\n h: main.frame.h,\n };\n if (drawing.zIndex <= main.zIndex) {\n drawing.zIndex = main.zIndex + 2;\n }\n }\n}\n\n/** Sync overlays for every page (normalize / bulk migrate). */\nexport function syncAllOverlayLayersToMain(layers: LayerNode[]): void {\n const pageIds = [...new Set(layers.map((l) => l.pageId))];\n for (const pageId of pageIds) {\n syncOverlayLayersToMain(layers, pageId);\n }\n}\n\n/** Active-page drawing overlay visibility (wire to `IChart.setFeatures({ drawings: { layer } })`). */\nexport function getDrawingOverlayVisible(\n controller: { getLayersForActivePage(): LayerNode[] },\n): boolean {\n const drawing = controller\n .getLayersForActivePage()\n .find((l) => l.type === 'overlay.drawing');\n return drawing?.visible ?? true;\n}\n\n/** Insert default overlay layers when chart.main exists (normalize). */\nexport function ensureOverlayLayers(\n layers: LayerNode[],\n pageId: string,\n): LayerNode[] {\n const main = layers.find((l) => l.type === 'chart.main' && l.pageId === pageId);\n if (!main) return layers;\n\n const out = [...layers];\n if (!out.some((l) => l.type === 'overlay.crosshairLegend' && l.pageId === pageId)) {\n out.push({\n id: `layer-crosshairLegend-${pageId}`,\n pageId,\n type: 'overlay.crosshairLegend',\n widgetKey: 'crosshairLegend',\n frame: { x: main.frame.x, y: main.frame.y, w: 0.2, h: 0.08 },\n zIndex: main.zIndex + 5,\n visible: true,\n locked: false,\n });\n }\n if (!out.some((l) => l.type === 'overlay.drawing' && l.pageId === pageId)) {\n out.push({\n id: `layer-drawingOverlay-${pageId}`,\n pageId,\n type: 'overlay.drawing',\n widgetKey: 'drawingOverlay',\n frame: { ...main.frame },\n zIndex: main.zIndex + 3,\n visible: true,\n locked: false,\n });\n }\n syncOverlayLayersToMain(out, pageId);\n return out;\n}","import type { LayerNode, LayerType } from './types.js';\nimport { syncAllOverlayLayersToMain } from './overlay-mount.js';\n\nexport const CHART_PANE_LAYER_TYPES: readonly LayerType[] = [\n 'chart.main',\n 'chart.volume',\n 'chart.indicator',\n 'chart.host',\n 'chart.indicatorHost',\n] as const;\n\nexport const DEFAULT_SYNC_TIME_SCALE_GROUP = 'chart-timescale';\n\nexport function isChartPaneLayerType(type: string): type is LayerType {\n return (CHART_PANE_LAYER_TYPES as readonly string[]).includes(type);\n}\n\nexport function widgetKeyForChartPaneType(type: LayerType): string | null {\n switch (type) {\n case 'chart.main':\n return 'chartMain';\n case 'chart.volume':\n return 'chartVolume';\n case 'chart.indicator':\n case 'chart.indicatorHost':\n return 'chartIndicator';\n case 'chart.host':\n return 'chartMain';\n default:\n return null;\n }\n}\n\nexport function paneIdFromWidgetKey(\n widgetKey: string,\n): 'main' | 'volume' | 'indicator' | null {\n switch (widgetKey) {\n case 'chartMain':\n case 'chartHost':\n return 'main';\n case 'chartVolume':\n return 'volume';\n case 'chartIndicator':\n case 'indicatorHost':\n return 'indicator';\n default:\n return null;\n }\n}\n\nexport interface HostSplitResult {\n layers: LayerNode[];\n /** Maps removed `chart.host` layer id → [mainId, volumeId]. */\n idRemap: Map<string, string[]>;\n}\n\n/** Split legacy `chart.host` into main + volume layers (vertical tile inside host frame). */\nexport function expandLegacyChartHostLayers(layers: LayerNode[]): LayerNode[] {\n return splitLegacyChartHost(layers).layers;\n}\n\nexport function splitLegacyChartHost(layers: LayerNode[]): HostSplitResult {\n const host = layers.find((l) => l.type === 'chart.host');\n if (!host || layers.some((l) => l.type === 'chart.main')) {\n return { layers, idRemap: new Map() };\n }\n\n const mainRatio = 0.65;\n const main: LayerNode = {\n ...host,\n id: `${host.id}-main`,\n type: 'chart.main',\n widgetKey: 'chartMain',\n frame: {\n x: host.frame.x,\n y: host.frame.y,\n w: host.frame.w,\n h: host.frame.h * mainRatio,\n },\n syncTimeScaleGroupId: host.syncTimeScaleGroupId,\n };\n const volume: LayerNode = {\n ...host,\n id: `${host.id}-volume`,\n type: 'chart.volume',\n widgetKey: 'chartVolume',\n frame: {\n x: host.frame.x,\n y: host.frame.y + host.frame.h * mainRatio,\n w: host.frame.w,\n h: host.frame.h * (1 - mainRatio),\n },\n zIndex: host.zIndex + 1,\n syncTimeScaleGroupId: host.syncTimeScaleGroupId,\n };\n\n const rest = layers.filter((l) => l.id !== host.id);\n const idRemap = new Map<string, string[]>([[host.id, [main.id, volume.id]]]);\n return { layers: [...rest, main, volume], idRemap };\n}\n\n/** @deprecated Use syncOverlayLayersToMain / syncAllOverlayLayersToMain */\nexport function syncCrosshairLegendToMain(layers: LayerNode[]): void {\n syncAllOverlayLayersToMain(layers);\n}\n\nexport function upgradeIndicatorHostType(layers: LayerNode[]): LayerNode[] {\n return layers.map((l) => {\n if (l.type !== 'chart.indicatorHost') return l;\n return {\n ...l,\n type: 'chart.indicator' as LayerType,\n widgetKey: l.widgetKey === 'indicatorHost' ? 'chartIndicator' : l.widgetKey,\n syncTimeScaleGroupId: l.syncTimeScaleGroupId,\n };\n });\n}","import {\n splitLegacyChartHost,\n upgradeIndicatorHostType,\n} from './chart-pane-mount.js';\nimport { ensureOverlayLayers, syncAllOverlayLayersToMain } from './overlay-mount.js';\nimport {\n LAYER_PRESET_VERSION,\n type BindGroup,\n type LayerFrame,\n type LayerNode,\n type LayerType,\n type LayoutPage,\n type LayoutPreset,\n} from './types.js';\n\nconst SHELL_TYPES: LayerType[] = [\n 'shell.topBar',\n 'shell.leftToolbar',\n 'shell.bottomToolbar',\n 'shell.statusBar',\n 'shell.propertiesPanel',\n];\n\nconst CHART_TYPES: LayerType[] = [\n 'chart.host',\n 'chart.main',\n 'chart.volume',\n 'chart.indicator',\n 'chart.indicatorHost',\n];\n\nconst OVERLAY_TYPES: LayerType[] = ['overlay.crosshairLegend', 'overlay.drawing'];\n\nfunction isLayerType(t: string): t is LayerType {\n return (\n SHELL_TYPES.includes(t as LayerType) ||\n CHART_TYPES.includes(t as LayerType) ||\n OVERLAY_TYPES.includes(t as LayerType) ||\n t === 'group'\n );\n}\n\nfunction clamp01(n: number): number {\n if (!Number.isFinite(n)) return 0;\n return Math.min(1, Math.max(0, n));\n}\n\nexport function clampFrame(frame: LayerFrame): LayerFrame {\n const w = Math.min(1, Math.max(0.02, clamp01(frame.w)));\n const h = Math.min(1, Math.max(0.02, clamp01(frame.h)));\n const x = clamp01(frame.x);\n const y = clamp01(frame.y);\n return {\n x: Math.min(x, 1 - w),\n y: Math.min(y, 1 - h),\n w,\n h,\n };\n}\n\nexport function normalizeLayoutPreset(input: LayoutPreset): LayoutPreset {\n const pages: LayoutPage[] =\n input.pages?.length > 0\n ? input.pages.map((p) => ({\n id: String(p.id || 'page-1'),\n title: String(p.title || 'Page 1'),\n }))\n : [{ id: 'page-1', title: '圖表' }];\n\n const pageIds = new Set(pages.map((p) => p.id));\n const defaultPageId = pages[0]!.id;\n\n const layers: LayerNode[] = [];\n const seenLayer = new Set<string>();\n\n for (const raw of input.layers ?? []) {\n if (!raw?.id || seenLayer.has(raw.id)) continue;\n if (!isLayerType(raw.type)) continue;\n seenLayer.add(raw.id);\n const pageId = pageIds.has(raw.pageId) ? raw.pageId : defaultPageId;\n layers.push({\n id: raw.id,\n pageId,\n type: raw.type,\n widgetKey: String(raw.widgetKey || raw.id),\n frame: clampFrame(raw.frame ?? { x: 0, y: 0, w: 1, h: 1 }),\n zIndex: Math.round(Number.isFinite(raw.zIndex) ? raw.zIndex : 0),\n visible: raw.visible !== false,\n locked: raw.locked === true,\n groupId: raw.groupId,\n syncTimeScaleGroupId: raw.syncTimeScaleGroupId,\n });\n }\n\n const { layers: splitLayers, idRemap } = splitLegacyChartHost(layers);\n let migrated = upgradeIndicatorHostType(splitLayers);\n for (const pageId of pageIds) {\n migrated = ensureOverlayLayers(migrated, pageId);\n }\n syncAllOverlayLayersToMain(migrated);\n\n migrated.sort((a, b) => a.zIndex - b.zIndex);\n migrated.forEach((l, i) => {\n l.zIndex = i;\n });\n\n const migratedIds = new Set(migrated.map((l) => l.id));\n\n const groups: BindGroup[] = [];\n const seenGroup = new Set<string>();\n for (const g of input.groups ?? []) {\n if (!g?.id || seenGroup.has(g.id)) continue;\n seenGroup.add(g.id);\n const layerIds = (g.layerIds ?? [])\n .flatMap((id) => idRemap.get(id) ?? [id])\n .filter((id) => migratedIds.has(id));\n if (layerIds.length === 0) continue;\n groups.push({\n id: g.id,\n name: g.name,\n layerIds,\n });\n }\n\n const revisionRaw = Number(input.revision);\n const revision =\n Number.isFinite(revisionRaw) && revisionRaw >= 1 ? Math.floor(revisionRaw) : 1;\n\n return {\n version: LAYER_PRESET_VERSION,\n revision,\n id: String(input.id || 'unnamed'),\n name: String(input.name || input.id || 'Untitled'),\n author: input.author === 'user' ? 'user' : 'integrator',\n readonly: input.readonly === true,\n forkedFrom: input.forkedFrom,\n pages,\n layers: migrated,\n groups,\n };\n}\n\nexport function cloneLayoutPreset(preset: LayoutPreset): LayoutPreset {\n return normalizeLayoutPreset({\n ...preset,\n pages: preset.pages.map((p) => ({ ...p })),\n layers: preset.layers.map((l) => ({ ...l, frame: { ...l.frame } })),\n groups: preset.groups.map((g) => ({ ...g, layerIds: [...g.layerIds] })),\n });\n}","import type { LayoutSchema, LayoutWidgetId } from '../layout-schema.js';\nimport { DEFAULT_LAYOUT_SCHEMA } from '../layout-schema.js';\nimport type { LayerNode, LayerType, LayoutPreset } from './types.js';\nimport { LAYER_PRESET_VERSION } from './types.js';\nimport { normalizeLayoutPreset } from './normalize.js';\n\nconst WIDGET_META: Partial<\n Record<LayoutWidgetId, { layerId: string; type: LayerType; widgetKey: string; z: number }>\n> = {\n topBar: { layerId: 'layer-topBar', type: 'shell.topBar', widgetKey: 'topBar', z: 10 },\n leftToolbar: { layerId: 'layer-leftToolbar', type: 'shell.leftToolbar', widgetKey: 'leftToolbar', z: 20 },\n indicatorHost: {\n layerId: 'layer-chartIndicator',\n type: 'chart.indicator',\n widgetKey: 'chartIndicator',\n z: 45,\n },\n statusBar: { layerId: 'layer-statusBar', type: 'shell.statusBar', widgetKey: 'statusBar', z: 50 },\n propertiesPanel: {\n layerId: 'layer-propertiesPanel',\n type: 'shell.propertiesPanel',\n widgetKey: 'propertiesPanel',\n z: 60,\n },\n bottomToolbar: { layerId: 'layer-bottomToolbar', type: 'shell.bottomToolbar', widgetKey: 'bottomToolbar', z: 70 },\n};\n\nconst MAIN_VOLUME_RATIO = 0.65;\n\nfunction chartHostLayers(\n w: LayoutSchema['widgets'][number],\n columns: number,\n rows: number,\n pageId: string,\n): LayerNode[] {\n const frame = {\n x: w.col / columns,\n y: w.row / rows,\n w: w.colSpan / columns,\n h: w.rowSpan / rows,\n };\n const mainH = frame.h * MAIN_VOLUME_RATIO;\n return [\n {\n id: 'layer-chartMain',\n pageId,\n type: 'chart.main',\n widgetKey: 'chartMain',\n frame: { x: frame.x, y: frame.y, w: frame.w, h: mainH },\n zIndex: 30,\n visible: true,\n locked: false,\n },\n {\n id: 'layer-chartVolume',\n pageId,\n type: 'chart.volume',\n widgetKey: 'chartVolume',\n frame: { x: frame.x, y: frame.y + mainH, w: frame.w, h: frame.h - mainH },\n zIndex: 35,\n visible: true,\n locked: false,\n },\n ];\n}\n\n/** Convert legacy 12×12 grid schema to normalized layer preset (single page). */\nexport function layoutSchemaToPreset(\n schema: LayoutSchema = DEFAULT_LAYOUT_SCHEMA,\n opts: { id?: string; name?: string } = {},\n): LayoutPreset {\n const columns = schema.columns || 12;\n const rows = schema.rows || 12;\n const pageId = 'page-1';\n\n const layers: LayerNode[] = [];\n for (const w of schema.widgets) {\n if (w.id === 'chartHost') {\n layers.push(...chartHostLayers(w, columns, rows, pageId));\n continue;\n }\n const meta = WIDGET_META[w.id];\n if (!meta) continue;\n layers.push({\n id: meta.layerId,\n pageId,\n type: meta.type,\n widgetKey: meta.widgetKey,\n frame: {\n x: w.col / columns,\n y: w.row / rows,\n w: w.colSpan / columns,\n h: w.rowSpan / rows,\n },\n zIndex: meta.z,\n visible: true,\n locked: false,\n\n });\n }\n\n const chartMain = layers.find((l) => l.widgetKey === 'chartMain');\n if (chartMain) {\n layers.push({\n id: 'layer-crosshairLegend',\n pageId,\n type: 'overlay.crosshairLegend',\n widgetKey: 'crosshairLegend',\n frame: {\n x: chartMain.frame.x,\n y: chartMain.frame.y,\n w: Math.min(0.35, chartMain.frame.w),\n h: Math.min(0.1, chartMain.frame.h),\n },\n zIndex: chartMain.zIndex + 5,\n visible: true,\n locked: false,\n });\n layers.push({\n id: 'layer-drawingOverlay',\n pageId,\n type: 'overlay.drawing',\n widgetKey: 'drawingOverlay',\n frame: { ...chartMain.frame },\n zIndex: chartMain.zIndex + 3,\n visible: true,\n locked: false,\n });\n }\n\n return normalizeLayoutPreset({\n version: LAYER_PRESET_VERSION,\n id: opts.id ?? 'vendor-default',\n name: opts.name ?? 'TradView 預設',\n author: 'integrator',\n readonly: false,\n pages: [{ id: pageId, title: '圖表' }],\n layers,\n groups: [],\n });\n}","import { layoutSchemaToPreset } from './grid-to-preset.js';\nimport type { LayoutPreset } from './types.js';\nimport { normalizeLayoutPreset } from './normalize.js';\n\n/** Built-in integrator preset — matches legacy DEFAULT_LAYOUT_SCHEMA proportions. */\nexport const VENDOR_DEFAULT_PRESET: LayoutPreset = layoutSchemaToPreset(undefined, {\n id: 'vendor-default',\n name: 'TradView 預設',\n});\n\n/** Compact: chart-focused, smaller chrome. */\nexport const VENDOR_COMPACT_PRESET: LayoutPreset = normalizeLayoutPreset({\n ...layoutSchemaToPreset(undefined, { id: 'vendor-compact', name: '精簡圖表' }),\n layers: layoutSchemaToPreset(undefined).layers.map((l) => {\n if (l.widgetKey === 'propertiesPanel') {\n return { ...l, visible: false, frame: { ...l.frame, w: 0.001, h: 0.001 } };\n }\n if (l.widgetKey === 'leftToolbar') {\n return { ...l, frame: { x: 0, y: 0.06, w: 0.04, h: 0.88 } };\n }\n if (l.widgetKey === 'chartMain') {\n return { ...l, frame: { x: 0.04, y: 0.06, w: 0.96, h: 0.4 } };\n }\n if (l.widgetKey === 'chartVolume') {\n return { ...l, frame: { x: 0.04, y: 0.46, w: 0.96, h: 0.16 } };\n }\n if (l.widgetKey === 'chartIndicator') {\n return { ...l, frame: { x: 0.04, y: 0.68, w: 0.96, h: 0.22 } };\n }\n return l;\n }),\n});\n\n/** Demo: main+volume share `prices`; indicator pane uses separate `osc` group. */\nexport const VENDOR_DUAL_SYNC_PRESET: LayoutPreset = normalizeLayoutPreset({\n ...layoutSchemaToPreset(undefined, { id: 'vendor-dual-sync', name: '雙時間軸分組' }),\n layers: layoutSchemaToPreset(undefined).layers.map((l) => {\n if (l.type === 'chart.main' || l.type === 'chart.volume') {\n return { ...l, syncTimeScaleGroupId: 'prices' };\n }\n if (l.type === 'chart.indicator') {\n return { ...l, syncTimeScaleGroupId: 'osc' };\n }\n return l;\n }),\n});\n\nexport const BUILTIN_PRESETS: LayoutPreset[] = [\n VENDOR_DEFAULT_PRESET,\n VENDOR_COMPACT_PRESET,\n VENDOR_DUAL_SYNC_PRESET,\n];\n\nexport function getBuiltinPreset(id: string): LayoutPreset | undefined {\n return BUILTIN_PRESETS.find((p) => p.id === id);\n}","import { getBuiltinPreset, BUILTIN_PRESETS } from './default-presets.js';\nimport { cloneLayoutPreset, normalizeLayoutPreset } from './normalize.js';\nimport type { LayoutPreset } from './types.js';\n\nconst INDEX_KEY = 'tradview:preset:v2:index';\n\nexport function presetStorageKey(id: string): string {\n return `tradview:preset:v2:${id}`;\n}\n\nexport interface PresetListEntry {\n id: string;\n name: string;\n author: LayoutPreset['author'];\n readonly?: boolean;\n builtin?: boolean;\n}\n\nfunction readIndex(): string[] {\n try {\n const raw = localStorage.getItem(INDEX_KEY);\n if (!raw) return [];\n const arr = JSON.parse(raw) as string[];\n return Array.isArray(arr) ? arr.filter((id) => typeof id === 'string') : [];\n } catch {\n return [];\n }\n}\n\nfunction writeIndex(ids: string[]): void {\n try {\n localStorage.setItem(INDEX_KEY, JSON.stringify([...new Set(ids)]));\n } catch {\n /* ignore */\n }\n}\n\nexport function listPresets(): PresetListEntry[] {\n const out: PresetListEntry[] = BUILTIN_PRESETS.map((p) => ({\n id: p.id,\n name: p.name,\n author: p.author,\n readonly: p.readonly,\n builtin: true,\n }));\n\n for (const id of readIndex()) {\n if (BUILTIN_PRESETS.some((p) => p.id === id)) continue;\n const loaded = loadPreset(id);\n if (loaded) {\n out.push({\n id: loaded.id,\n name: loaded.name,\n author: loaded.author,\n readonly: loaded.readonly,\n builtin: false,\n });\n }\n }\n return out;\n}\n\nexport function loadPreset(id: string): LayoutPreset | null {\n const builtin = getBuiltinPreset(id);\n if (builtin) return cloneLayoutPreset(builtin);\n\n try {\n const raw = localStorage.getItem(presetStorageKey(id));\n if (!raw) return null;\n return normalizeLayoutPreset(JSON.parse(raw) as LayoutPreset);\n } catch {\n return null;\n }\n}\n\nexport function savePreset(preset: LayoutPreset): void {\n const normalized = normalizeLayoutPreset(preset);\n if (getBuiltinPreset(normalized.id)) {\n throw new Error(`Cannot overwrite builtin preset: ${normalized.id}`);\n }\n try {\n localStorage.setItem(presetStorageKey(normalized.id), JSON.stringify(normalized));\n const ids = readIndex();\n if (!ids.includes(normalized.id)) {\n writeIndex([...ids, normalized.id]);\n }\n } catch {\n /* ignore */\n }\n}\n\nexport function deleteUserPreset(id: string): boolean {\n if (getBuiltinPreset(id)) return false;\n try {\n localStorage.removeItem(presetStorageKey(id));\n writeIndex(readIndex().filter((x) => x !== id));\n return true;\n } catch {\n return false;\n }\n}\n\nexport function forkPreset(\n sourceId: string,\n newId: string,\n newName: string,\n): LayoutPreset | null {\n const src = loadPreset(sourceId);\n if (!src) return null;\n const forked = normalizeLayoutPreset({\n ...cloneLayoutPreset(src),\n id: newId,\n name: newName,\n author: 'user',\n readonly: false,\n forkedFrom: sourceId,\n });\n savePreset(forked);\n return forked;\n}\n\nexport function resolvePreset(id: string | LayoutPreset | null | undefined): LayoutPreset {\n if (id && typeof id === 'object') return normalizeLayoutPreset(id);\n if (typeof id === 'string') {\n const loaded = loadPreset(id);\n if (loaded) return loaded;\n }\n return cloneLayoutPreset(getBuiltinPreset('vendor-default')!);\n}","import { clampFrame } from './normalize.js';\nimport type { LayerFrame, LayerNode } from './types.js';\n\n/** Union bounding box of layer frames (normalized 0..1). */\nexport function getLayersBoundingBox(layers: Pick<LayerNode, 'frame'>[]): LayerFrame | null {\n if (layers.length === 0) return null;\n let minX = 1;\n let minY = 1;\n let maxX = 0;\n let maxY = 0;\n for (const l of layers) {\n const f = l.frame;\n minX = Math.min(minX, f.x);\n minY = Math.min(minY, f.y);\n maxX = Math.max(maxX, f.x + f.w);\n maxY = Math.max(maxY, f.y + f.h);\n }\n const w = maxX - minX;\n const h = maxY - minY;\n if (w <= 0 || h <= 0) return null;\n return { x: minX, y: minY, w, h };\n}\n\n/** Move all frames by normalized delta; each frame is clamped independently. */\nexport function moveLayerFrames(\n frames: LayerFrame[],\n dx: number,\n dy: number,\n): LayerFrame[] {\n return frames.map((f) =>\n clampFrame({\n ...f,\n x: f.x + dx,\n y: f.y + dy,\n }),\n );\n}\n\n/**\n * Resize a group by mapping each member's relative position inside oldBbox into newBbox.\n */\nexport function resizeGroupFrames(\n members: Pick<LayerNode, 'frame'>[],\n oldBbox: LayerFrame,\n newBbox: LayerFrame,\n): LayerFrame[] {\n const ow = Math.max(oldBbox.w, 0.02);\n const oh = Math.max(oldBbox.h, 0.02);\n const nw = Math.max(newBbox.w, 0.02);\n const nh = Math.max(newBbox.h, 0.02);\n return members.map((m) => {\n const f = m.frame;\n const relX = (f.x - oldBbox.x) / ow;\n const relY = (f.y - oldBbox.y) / oh;\n const relW = f.w / ow;\n const relH = f.h / oh;\n return clampFrame({\n x: newBbox.x + relX * nw,\n y: newBbox.y + relY * nh,\n w: relW * nw,\n h: relH * nh,\n });\n });\n}\n\nexport function clampBBox(frame: LayerFrame): LayerFrame {\n return clampFrame(frame);\n}","import { isChartPaneLayerType, paneIdFromWidgetKey } from './chart-pane-mount.js';\nimport { syncOverlayLayersToMain } from './overlay-mount.js';\nimport { clampFrame, cloneLayoutPreset } from './normalize.js';\nimport {\n getLayersBoundingBox,\n moveLayerFrames,\n resizeGroupFrames,\n} from './group-utils.js';\nimport type { BindGroup, LayerFrame, LayoutPreset } from './types.js';\n\n/** @public Mutable controller for LayoutPreset v2 (layers, groups, pane focus). */\nexport class LayerController {\n private preset: LayoutPreset;\n private readonly listeners = new Set<() => void>();\n private readonly focusListeners = new Set<() => void>();\n private interactionDepth = 0;\n private pageIdSeq = 0;\n activePageId: string;\n /** P2: active chart pane layer (click-to-focus). */\n focusedPaneLayerId: string | null = null;\n /** Monotonic preset revision (Bridge `host.layer.setPreset`). */\n presetRevision: number;\n\n constructor(initial: LayoutPreset) {\n this.preset = cloneLayoutPreset(initial);\n this.presetRevision = this.preset.revision ?? 1;\n this.activePageId = this.preset.pages[0]?.id ?? 'page-1';\n }\n\n getPreset(): LayoutPreset {\n return cloneLayoutPreset(this.preset);\n }\n\n /** True while pointer drag/resize/marquee is active — blocks setPreset. */\n isInteracting(): boolean {\n return this.interactionDepth > 0;\n }\n\n beginInteraction(): void {\n this.interactionDepth++;\n }\n\n endInteraction(): void {\n this.interactionDepth = Math.max(0, this.interactionDepth - 1);\n }\n\n setPreset(next: LayoutPreset): boolean {\n if (this.isInteracting()) return false;\n this.preset = cloneLayoutPreset(next);\n this.presetRevision = this.preset.revision ?? 1;\n if (!this.preset.pages.some((p) => p.id === this.activePageId)) {\n this.activePageId = this.preset.pages[0]?.id ?? 'page-1';\n }\n this.emit();\n return true;\n }\n\n getLayersForActivePage(): LayoutPreset['layers'] {\n return this.preset.layers\n .filter((l) => l.pageId === this.activePageId)\n .sort((a, b) => a.zIndex - b.zIndex);\n }\n\n getFocusedPaneLayerId(): string | null {\n return this.focusedPaneLayerId;\n }\n\n getFocusedPaneId(): 'main' | 'volume' | 'indicator' | null {\n const layer = this.focusedPaneLayerId\n ? this.getLayer(this.focusedPaneLayerId)\n : undefined;\n return layer ? paneIdFromWidgetKey(layer.widgetKey) : null;\n }\n\n /** Raise z-index among chart panes only; does not rebuild compositor DOM. */\n focusChartPane(layerId: string): void {\n const layer = this.getLayer(layerId);\n if (!layer || layer.pageId !== this.activePageId || !isChartPaneLayerType(layer.type)) {\n return;\n }\n if (this.focusedPaneLayerId === layerId) return;\n this.focusedPaneLayerId = layerId;\n const chartLayers = this.getLayersForActivePage().filter((l) =>\n isChartPaneLayerType(l.type),\n );\n const maxZ = Math.max(...chartLayers.map((l) => l.zIndex), layer.zIndex);\n const FOCUS_Z_CAP = 500;\n if (layer.zIndex < maxZ) layer.zIndex = Math.min(maxZ + 1, FOCUS_Z_CAP);\n this.notifyFocus();\n }\n\n subscribeFocus(listener: () => void): () => void {\n this.focusListeners.add(listener);\n return () => this.focusListeners.delete(listener);\n }\n\n private notifyFocus(): void {\n for (const fn of this.focusListeners) fn();\n }\n\n private afterChartMainFrameChange(pageIds?: Iterable<string>): void {\n const ids = pageIds\n ? [...new Set(pageIds)]\n : [...new Set(this.preset.layers.map((l) => l.pageId))];\n for (const pageId of ids) {\n syncOverlayLayersToMain(this.preset.layers, pageId);\n }\n }\n\n setActivePage(pageId: string): boolean {\n if (!this.preset.pages.some((p) => p.id === pageId)) return false;\n if (this.activePageId === pageId) return false;\n this.activePageId = pageId;\n this.focusedPaneLayerId = null;\n this.emit();\n this.notifyFocus();\n return true;\n }\n\n addPage(title?: string): string {\n const suffix =\n typeof crypto !== 'undefined' && 'randomUUID' in crypto\n ? crypto.randomUUID()\n : `${Date.now()}-${++this.pageIdSeq}`;\n const id = `page-${suffix}`;\n const pageTitle = title?.trim() || `Page ${this.preset.pages.length + 1}`;\n this.preset.pages.push({ id, title: pageTitle });\n const templatePageId = this.activePageId;\n const templateLayers = this.preset.layers.filter((l) => l.pageId === templatePageId);\n const maxZ = Math.max(-1, ...this.preset.layers.map((l) => l.zIndex));\n let z = maxZ + 1;\n for (const tpl of templateLayers) {\n this.preset.layers.push({\n ...tpl,\n id: `${tpl.id}-${id}`,\n pageId: id,\n frame: { ...tpl.frame },\n zIndex: z++,\n groupId: undefined,\n });\n }\n this.activePageId = id;\n this.focusedPaneLayerId = null;\n this.emit();\n return id;\n }\n\n renamePage(pageId: string, title: string): boolean {\n const page = this.preset.pages.find((p) => p.id === pageId);\n if (!page) return false;\n const trimmed = title.trim();\n if (!trimmed) return false;\n page.title = trimmed;\n this.emit();\n return true;\n }\n\n removePage(pageId: string): boolean {\n if (this.preset.pages.length <= 1) return false;\n const idx = this.preset.pages.findIndex((p) => p.id === pageId);\n if (idx < 0) return false;\n this.preset.pages.splice(idx, 1);\n this.preset.layers = this.preset.layers.filter((l) => l.pageId !== pageId);\n for (const g of [...this.preset.groups]) {\n g.layerIds = g.layerIds.filter((lid) => this.getLayer(lid)?.pageId !== pageId);\n if (g.layerIds.length === 0) {\n this.preset.groups = this.preset.groups.filter((x) => x.id !== g.id);\n }\n }\n if (this.activePageId === pageId) {\n const nextPage = this.preset.pages[idx] ?? this.preset.pages[idx - 1];\n this.activePageId = nextPage?.id ?? this.preset.pages[0]!.id;\n this.focusedPaneLayerId = null;\n }\n this.emit();\n return true;\n }\n\n getLayer(layerId: string) {\n return this.preset.layers.find((l) => l.id === layerId);\n }\n\n /**\n * @public Set time-scale sync group for a chart pane layer (`''` clears → independent).\n */\n setLayerSyncGroup(layerId: string, groupId: string | null | undefined): boolean {\n const layer = this.getLayer(layerId);\n if (!layer || !isChartPaneLayerType(layer.type)) return false;\n const trimmed = groupId == null ? '' : String(groupId).trim();\n layer.syncTimeScaleGroupId = trimmed.length > 0 ? trimmed : undefined;\n this.emit();\n return true;\n }\n\n getGroup(groupId: string): BindGroup | undefined {\n return this.preset.groups.find((g) => g.id === groupId);\n }\n\n /** Layer ids that move/resize together (group members or singleton). */\n getTransformLayerIds(layerId: string): string[] {\n const layer = this.getLayer(layerId);\n if (!layer?.groupId) return [layerId];\n const group = this.getGroup(layer.groupId);\n if (!group || group.layerIds.length === 0) return [layerId];\n return group.layerIds.filter((id) => {\n const l = this.getLayer(id);\n return l && l.pageId === this.activePageId && !l.locked;\n });\n }\n\n getGroupMemberLayers(groupId: string): LayoutPreset['layers'] {\n const group = this.getGroup(groupId);\n if (!group) return [];\n return group.layerIds\n .map((id) => this.getLayer(id))\n .filter((l): l is NonNullable<typeof l> => !!l && l.pageId === this.activePageId);\n }\n\n setLayerFrame(layerId: string, frame: LayerFrame): void {\n const ids = this.getTransformLayerIds(layerId);\n if (ids.length === 1) {\n const layer = this.getLayer(layerId);\n if (!layer) return;\n layer.frame = clampFrame(frame);\n if (layer.type === 'overlay.drawing') {\n const main = this.preset.layers.find(\n (l) => l.type === 'chart.main' && l.pageId === layer.pageId,\n );\n if (main) main.frame = clampFrame(frame);\n }\n if (layer.type === 'chart.main' || layer.type === 'overlay.drawing') {\n this.afterChartMainFrameChange([layer.pageId]);\n }\n this.emit();\n return;\n }\n const members = ids.map((id) => this.getLayer(id)!).filter(Boolean);\n const oldBbox = getLayersBoundingBox(members);\n if (!oldBbox) return;\n const target = frame;\n const newFrames = resizeGroupFrames(members, oldBbox, target);\n members.forEach((m, i) => {\n m.frame = newFrames[i]!;\n });\n if (members.some((m) => m.type === 'chart.main' || m.type === 'overlay.drawing')) {\n this.afterChartMainFrameChange(members.map((m) => m.pageId));\n }\n this.emit();\n }\n\n private expandTransformIds(layerIds: string[]): string[] {\n const expanded = new Set<string>();\n for (const id of layerIds) {\n for (const tid of this.getTransformLayerIds(id)) expanded.add(tid);\n }\n return [...expanded];\n }\n\n moveLayers(layerIds: string[], dx: number, dy: number): void {\n const unique = this.expandTransformIds(layerIds);\n const layers = unique.map((id) => this.getLayer(id)).filter(Boolean) as LayoutPreset['layers'];\n if (layers.length === 0) return;\n const frames = moveLayerFrames(\n layers.map((l) => l.frame),\n dx,\n dy,\n );\n layers.forEach((l, i) => {\n l.frame = frames[i]!;\n });\n if (\n layers.some((l) => l.type === 'chart.main' || l.type === 'overlay.drawing')\n ) {\n this.afterChartMainFrameChange(layers.map((l) => l.pageId));\n }\n this.emit();\n }\n\n resizeLayersFromBbox(layerIds: string[], newBbox: LayerFrame): void {\n const unique = this.expandTransformIds(layerIds);\n const members = unique\n .map((id) => this.getLayer(id))\n .filter((l): l is NonNullable<typeof l> => !!l);\n if (members.length === 0) return;\n if (members.length === 1) {\n members[0]!.frame = clampFrame(newBbox);\n if (\n members[0]!.type === 'chart.main' ||\n members[0]!.type === 'overlay.drawing'\n ) {\n this.afterChartMainFrameChange([members[0]!.pageId]);\n }\n this.emit();\n return;\n }\n const oldBbox = getLayersBoundingBox(members);\n if (!oldBbox) return;\n const newFrames = resizeGroupFrames(members, oldBbox, newBbox);\n members.forEach((m, i) => {\n m.frame = newFrames[i]!;\n });\n if (members.some((m) => m.type === 'chart.main' || m.type === 'overlay.drawing')) {\n this.afterChartMainFrameChange(members.map((m) => m.pageId));\n }\n this.emit();\n }\n\n setLayerVisible(layerId: string, visible: boolean): void {\n const ids = this.syncGroupLayerIds(layerId);\n for (const id of ids) {\n const layer = this.getLayer(id);\n if (layer) layer.visible = visible;\n }\n this.emit();\n }\n\n setLayerLocked(layerId: string, locked: boolean): void {\n const ids = this.syncGroupLayerIds(layerId);\n for (const id of ids) {\n const layer = this.getLayer(id);\n if (layer) layer.locked = locked;\n }\n this.emit();\n }\n\n private syncGroupLayerIds(layerId: string): string[] {\n const layer = this.getLayer(layerId);\n if (!layer?.groupId) return [layerId];\n const group = this.getGroup(layer.groupId);\n if (!group?.layerIds.length) return [layerId];\n const onPage = group.layerIds.filter((id) => {\n const l = this.getLayer(id);\n return l && l.pageId === this.activePageId;\n });\n return onPage.length > 0 ? onPage : [layerId];\n }\n\n bumpZIndex(layerId: string, delta: 1 | -1): void {\n const ordered = this.getLayersForActivePage();\n const idx = ordered.findIndex((l) => l.id === layerId);\n if (idx < 0) return;\n const swap = idx + delta;\n if (swap < 0 || swap >= ordered.length) return;\n const a = ordered[idx]!;\n const b = ordered[swap]!;\n const tz = a.zIndex;\n a.zIndex = b.zIndex;\n b.zIndex = tz;\n this.preset.layers.sort((x, y) => x.zIndex - y.zIndex);\n this.preset.layers.forEach((l, i) => {\n l.zIndex = i;\n });\n this.emit();\n }\n\n reorderLayers(orderedIds: string[]): void {\n const pageLayers = this.preset.layers.filter((l) => l.pageId === this.activePageId);\n const byId = new Map(pageLayers.map((l) => [l.id, l]));\n let z = 0;\n for (const id of orderedIds) {\n const layer = byId.get(id);\n if (layer) layer.zIndex = z++;\n }\n for (const layer of pageLayers) {\n if (!orderedIds.includes(layer.id)) layer.zIndex = z++;\n }\n this.preset.layers.sort((a, b) => a.zIndex - b.zIndex);\n this.emit();\n }\n\n createBindGroup(layerIds: string[], name?: string): string | null {\n const unique = [...new Set(layerIds)].filter((id) => {\n const l = this.getLayer(id);\n return l && l.pageId === this.activePageId;\n });\n if (unique.length < 2) return null;\n\n for (const g of this.preset.groups) {\n for (const id of unique) {\n const idx = g.layerIds.indexOf(id);\n if (idx >= 0) g.layerIds.splice(idx, 1);\n }\n if (g.layerIds.length === 0) {\n this.preset.groups = this.preset.groups.filter((x) => x.id !== g.id);\n }\n }\n\n for (const id of unique) {\n const layer = this.getLayer(id);\n if (layer) delete layer.groupId;\n }\n\n const groupId = `group-${Date.now()}`;\n const group: BindGroup = { id: groupId, name, layerIds: unique };\n this.preset.groups.push(group);\n for (const id of unique) {\n const layer = this.getLayer(id);\n if (layer) layer.groupId = groupId;\n }\n this.emit();\n return groupId;\n }\n\n dissolveGroup(groupId: string): void {\n const group = this.getGroup(groupId);\n if (!group) return;\n for (const id of group.layerIds) {\n const layer = this.getLayer(id);\n if (layer?.groupId === groupId) delete layer.groupId;\n }\n this.preset.groups = this.preset.groups.filter((g) => g.id !== groupId);\n this.emit();\n }\n\n removeLayerFromGroup(layerId: string): void {\n const layer = this.getLayer(layerId);\n if (!layer?.groupId) return;\n const groupId = layer.groupId;\n delete layer.groupId;\n const group = this.getGroup(groupId);\n if (!group) return;\n group.layerIds = group.layerIds.filter((id) => id !== layerId);\n if (group.layerIds.length === 0) {\n this.preset.groups = this.preset.groups.filter((g) => g.id !== groupId);\n }\n this.emit();\n }\n\n subscribe(listener: () => void): () => void {\n this.listeners.add(listener);\n return () => this.listeners.delete(listener);\n }\n\n private emit(): void {\n for (const fn of this.listeners) fn();\n }\n}","import type { LayerController } from './layer-controller.js';\nimport { getLayersBoundingBox, resizeGroupFrames } from './group-utils.js';\nimport { clampFrame } from './normalize.js';\nimport type { LayerFrame } from './types.js';\n\nexport interface LayerEditorOptions {\n controller: LayerController;\n /** Called after drag/resize commits preset changes. */\n onPresetChange?: () => void;\n /** Shift+drag marquee selection on compositor root. */\n onMarqueeSelect?: (layerIds: string[]) => void;\n}\n\nexport interface LayerEditorHandle {\n setEnabled(enabled: boolean): void;\n isEnabled(): boolean;\n rebind(): void;\n destroy(): void;\n}\n\ntype ResizeHandle = 'nw' | 'ne' | 'sw' | 'se';\n\nconst HANDLE_CURSORS: Record<ResizeHandle, string> = {\n nw: 'nwse-resize',\n ne: 'nesw-resize',\n sw: 'nesw-resize',\n se: 'nwse-resize',\n};\n\nconst EPS = 1e-6;\n\nfunction framesEqual(a: LayerFrame, b: LayerFrame, eps = EPS): boolean {\n return (\n Math.abs(a.x - b.x) < eps &&\n Math.abs(a.y - b.y) < eps &&\n Math.abs(a.w - b.w) < eps &&\n Math.abs(a.h - b.h) < eps\n );\n}\n\nfunction frameIntersects(a: LayerFrame, b: LayerFrame): boolean {\n return a.x < b.x + b.w && a.x + a.w > b.x && a.y < b.y + b.h && a.y + a.h > b.y;\n}\n\n/** Let wrap receive drag/resize; LWC and buttons live inside children. */\nfunction setWrapContentPassthrough(wrap: HTMLElement, passthrough: boolean): void {\n for (const child of wrap.children) {\n if ((child as HTMLElement).classList.contains('tv-layer-handle')) continue;\n (child as HTMLElement).style.pointerEvents = passthrough ? 'none' : '';\n }\n}\n\nfunction clearWrapContentPassthrough(wrap: HTMLElement): void {\n for (const child of wrap.children) {\n if ((child as HTMLElement).classList.contains('tv-layer-handle')) continue;\n (child as HTMLElement).style.pointerEvents = '';\n }\n}\n\nexport function attachLayerEditor(\n compositorRoot: HTMLElement,\n opts: LayerEditorOptions,\n): LayerEditorHandle {\n const { controller, onPresetChange, onMarqueeSelect } = opts;\n let enabled = false;\n let abort: AbortController | null = null;\n let captureEl: HTMLElement | null = null;\n let capturePointerId: number | null = null;\n\n const releaseCapture = () => {\n if (captureEl && capturePointerId !== null) {\n try {\n captureEl.releasePointerCapture(capturePointerId);\n } catch {\n /* already released */\n }\n }\n if (capturePointerId !== null && controller.isInteracting()) {\n controller.endInteraction();\n }\n captureEl = null;\n capturePointerId = null;\n };\n\n const setCapture = (el: HTMLElement, pointerId: number) => {\n releaseCapture();\n captureEl = el;\n capturePointerId = pointerId;\n controller.beginInteraction();\n try {\n el.setPointerCapture(pointerId);\n } catch {\n controller.endInteraction();\n captureEl = null;\n capturePointerId = null;\n }\n };\n\n const normDelta = (dxPx: number, dyPx: number) => {\n const w = compositorRoot.clientWidth || 1;\n const h = compositorRoot.clientHeight || 1;\n return { dx: dxPx / w, dy: dyPx / h };\n };\n\n const applyWrapStyle = (wrap: HTMLElement, frame: LayerFrame) => {\n wrap.style.left = `${frame.x * 100}%`;\n wrap.style.top = `${frame.y * 100}%`;\n wrap.style.width = `${frame.w * 100}%`;\n wrap.style.height = `${frame.h * 100}%`;\n };\n\n const decorateWrap = (wrap: HTMLElement, layerId: string) => {\n wrap.querySelectorAll('.tv-layer-handle').forEach((el) => el.remove());\n const layer = controller.getLayer(layerId);\n if (!layer || layer.locked) {\n wrap.classList.remove('tv-layer-editable');\n wrap.style.cursor = '';\n wrap.style.outline = '';\n clearWrapContentPassthrough(wrap);\n return;\n }\n wrap.classList.add('tv-layer-editable');\n wrap.style.cursor = 'move';\n setWrapContentPassthrough(wrap, true);\n if (wrap.dataset.focused === '1') {\n wrap.style.outline = '2px solid #58a6ff';\n wrap.style.outlineOffset = '-2px';\n } else {\n wrap.style.outline = '1px dashed #58a6ff88';\n wrap.style.outlineOffset = '';\n }\n\n const handles: ResizeHandle[] = ['nw', 'ne', 'sw', 'se'];\n for (const h of handles) {\n const handle = document.createElement('div');\n handle.className = `tv-layer-handle tv-layer-handle-${h}`;\n handle.dataset.handle = h;\n handle.style.cssText = [\n 'position:absolute',\n 'width:8px',\n 'height:8px',\n 'background:#58a6ff',\n 'border:1px solid #0d1117',\n 'border-radius:2px',\n 'z-index:2',\n `cursor:${HANDLE_CURSORS[h]}`,\n h.includes('n') ? 'top:-4px' : 'bottom:-4px',\n h.includes('w') ? 'left:-4px' : 'right:-4px',\n ].join(';');\n wrap.appendChild(handle);\n }\n };\n\n const commitChange = () => {\n onPresetChange?.();\n };\n\n const computeResizeBbox = (\n startBbox: LayerFrame,\n corner: ResizeHandle,\n dx: number,\n dy: number,\n ): LayerFrame => {\n const newBbox = { ...startBbox };\n if (corner.includes('e')) newBbox.w = startBbox.w + dx;\n if (corner.includes('w')) {\n newBbox.x = startBbox.x + dx;\n newBbox.w = startBbox.w - dx;\n }\n if (corner.includes('s')) newBbox.h = startBbox.h + dy;\n if (corner.includes('n')) {\n newBbox.y = startBbox.y + dy;\n newBbox.h = startBbox.h - dy;\n }\n return clampFrame(newBbox);\n };\n\n const bindMarquee = (signal: AbortSignal) => {\n compositorRoot.addEventListener(\n 'pointerdown',\n (e) => {\n if (!e.shiftKey) return;\n if ((e.target as HTMLElement).closest('.tv-layer-wrap')) return;\n e.preventDefault();\n const rootRect = compositorRoot.getBoundingClientRect();\n const startX = e.clientX;\n const startY = e.clientY;\n const marquee = document.createElement('div');\n marquee.className = 'tv-layer-marquee';\n marquee.style.cssText =\n 'position:absolute;border:1px dashed #58a6ff;background:#58a6ff22;pointer-events:none;z-index:9999;';\n compositorRoot.appendChild(marquee);\n setCapture(compositorRoot, e.pointerId);\n\n const updateMarquee = (cx: number, cy: number) => {\n const x1 = Math.min(startX, cx) - rootRect.left;\n const y1 = Math.min(startY, cy) - rootRect.top;\n const x2 = Math.max(startX, cx) - rootRect.left;\n const y2 = Math.max(startY, cy) - rootRect.top;\n marquee.style.left = `${x1}px`;\n marquee.style.top = `${y1}px`;\n marquee.style.width = `${x2 - x1}px`;\n marquee.style.height = `${y2 - y1}px`;\n };\n\n const onMove = (ev: PointerEvent) => updateMarquee(ev.clientX, ev.clientY);\n\n const onUp = (ev: PointerEvent) => {\n releaseCapture();\n compositorRoot.removeEventListener('pointermove', onMove);\n compositorRoot.removeEventListener('pointerup', onUp);\n compositorRoot.removeEventListener('pointercancel', onUp);\n const w = compositorRoot.clientWidth || 1;\n const h = compositorRoot.clientHeight || 1;\n const sel: LayerFrame = clampFrame({\n x: (Math.min(startX, ev.clientX) - rootRect.left) / w,\n y: (Math.min(startY, ev.clientY) - rootRect.top) / h,\n w: Math.abs(ev.clientX - startX) / w,\n h: Math.abs(ev.clientY - startY) / h,\n });\n marquee.remove();\n if (sel.w < EPS && sel.h < EPS) return;\n const hits = controller\n .getLayersForActivePage()\n .filter((l) => frameIntersects(l.frame, sel))\n .map((l) => l.id);\n if (hits.length > 0) onMarqueeSelect?.(hits);\n };\n\n updateMarquee(startX, startY);\n compositorRoot.addEventListener('pointermove', onMove, { signal });\n compositorRoot.addEventListener('pointerup', onUp, { signal });\n compositorRoot.addEventListener('pointercancel', onUp, { signal });\n },\n { signal },\n );\n };\n\n const bindWrap = (wrap: HTMLElement, signal: AbortSignal) => {\n const layerId = wrap.dataset.layerId;\n if (!layerId) return;\n const layer = controller.getLayer(layerId);\n if (!layer || layer.locked) return;\n\n const transformIds = () => controller.getTransformLayerIds(layerId);\n\n const onPointerDownMove = (e: PointerEvent) => {\n if ((e.target as HTMLElement).classList.contains('tv-layer-handle')) return;\n e.preventDefault();\n e.stopPropagation();\n const ids = transformIds();\n const members = ids.map((id) => controller.getLayer(id)!).filter(Boolean);\n const startFrames = members.map((m) => ({ ...m.frame }));\n const startX = e.clientX;\n const startY = e.clientY;\n setCapture(wrap, e.pointerId);\n wrap.classList.add('tv-layer-dragging');\n\n const onMove = (ev: PointerEvent) => {\n const { dx, dy } = normDelta(ev.clientX - startX, ev.clientY - startY);\n const moved = startFrames.map((f) =>\n clampFrame({ ...f, x: f.x + dx, y: f.y + dy }),\n );\n compositorRoot.querySelectorAll('.tv-layer-wrap').forEach((el) => {\n const w = el as HTMLElement;\n const lid = w.dataset.layerId;\n if (!lid || !ids.includes(lid)) return;\n const idx = ids.indexOf(lid);\n if (idx >= 0) applyWrapStyle(w, moved[idx]!);\n });\n };\n\n const onUp = (ev: PointerEvent) => {\n releaseCapture();\n wrap.classList.remove('tv-layer-dragging');\n wrap.removeEventListener('pointermove', onMove);\n wrap.removeEventListener('pointerup', onUp);\n wrap.removeEventListener('pointercancel', onUp);\n const { dx, dy } = normDelta(ev.clientX - startX, ev.clientY - startY);\n if (Math.abs(dx) > EPS || Math.abs(dy) > EPS) {\n controller.moveLayers(ids, dx, dy);\n commitChange();\n }\n };\n\n wrap.addEventListener('pointermove', onMove, { signal });\n wrap.addEventListener('pointerup', onUp, { signal });\n wrap.addEventListener('pointercancel', onUp, { signal });\n };\n\n wrap.addEventListener('pointerdown', onPointerDownMove, { signal });\n\n wrap.querySelectorAll('.tv-layer-handle').forEach((handleEl) => {\n const handle = handleEl as HTMLElement;\n const corner = handle.dataset.handle as ResizeHandle;\n handle.addEventListener(\n 'pointerdown',\n (e) => {\n e.preventDefault();\n e.stopPropagation();\n const ids = transformIds();\n const members = ids.map((id) => controller.getLayer(id)!).filter(Boolean);\n let startBbox: LayerFrame | null;\n if (members.length === 1) {\n startBbox = { ...members[0]!.frame };\n } else {\n startBbox = getLayersBoundingBox(members);\n }\n if (!startBbox) return;\n const startX = e.clientX;\n const startY = e.clientY;\n setCapture(handle, e.pointerId);\n\n const onMove = (ev: PointerEvent) => {\n const { dx, dy } = normDelta(ev.clientX - startX, ev.clientY - startY);\n const newBbox = computeResizeBbox(startBbox!, corner, dx, dy);\n\n if (ids.length === 1) {\n applyWrapStyle(wrap, newBbox);\n } else {\n const resized = resizeGroupFrames(members, startBbox!, newBbox);\n compositorRoot.querySelectorAll('.tv-layer-wrap').forEach((el) => {\n const w = el as HTMLElement;\n const lid = w.dataset.layerId;\n if (!lid || !ids.includes(lid)) return;\n const idx = ids.indexOf(lid);\n if (idx >= 0) applyWrapStyle(w, resized[idx]!);\n });\n }\n };\n\n const onUp = (ev: PointerEvent) => {\n releaseCapture();\n handle.removeEventListener('pointermove', onMove);\n handle.removeEventListener('pointerup', onUp);\n handle.removeEventListener('pointercancel', onUp);\n const { dx, dy } = normDelta(ev.clientX - startX, ev.clientY - startY);\n const newBbox = computeResizeBbox(startBbox, corner, dx, dy);\n if (!framesEqual(newBbox, startBbox) && (Math.abs(dx) > EPS || Math.abs(dy) > EPS)) {\n controller.resizeLayersFromBbox(ids, newBbox);\n commitChange();\n }\n };\n\n handle.addEventListener('pointermove', onMove, { signal });\n handle.addEventListener('pointerup', onUp, { signal });\n handle.addEventListener('pointercancel', onUp, { signal });\n },\n { signal },\n );\n });\n };\n\n const cleanupEditChrome = () => {\n compositorRoot.classList.remove('tv-layer-edit-mode');\n compositorRoot.querySelectorAll('.tv-layer-marquee').forEach((el) => el.remove());\n compositorRoot.querySelectorAll('.tv-layer-wrap').forEach((w) => {\n const el = w as HTMLElement;\n el.classList.remove('tv-layer-editable', 'tv-layer-dragging');\n el.style.outline = '';\n el.style.cursor = '';\n el.querySelectorAll('.tv-layer-handle').forEach((h) => h.remove());\n clearWrapContentPassthrough(el);\n });\n compositorRoot.style.zIndex = '';\n };\n\n const rebind = () => {\n releaseCapture();\n abort?.abort();\n if (!enabled) {\n cleanupEditChrome();\n return;\n }\n compositorRoot.classList.add('tv-layer-edit-mode');\n compositorRoot.style.zIndex = '80';\n abort = new AbortController();\n const { signal } = abort;\n bindMarquee(signal);\n compositorRoot.querySelectorAll('.tv-layer-wrap').forEach((w) => {\n const wrap = w as HTMLElement;\n const layerId = wrap.dataset.layerId;\n if (!layerId) return;\n decorateWrap(wrap, layerId);\n bindWrap(wrap, signal);\n });\n };\n\n return {\n setEnabled(next: boolean) {\n enabled = next;\n rebind();\n },\n isEnabled: () => enabled,\n rebind,\n destroy: () => {\n enabled = false;\n releaseCapture();\n abort?.abort();\n cleanupEditChrome();\n },\n };\n}","import { isChartPaneLayerType } from './chart-pane-mount.js';\nimport { isOverlayLayerType } from './overlay-mount.js';\nimport type { LayerWidgetKey } from './types.js';\nimport { LayerController } from './layer-controller.js';\nimport type { LayerNode, LayoutPreset } from './types.js';\nimport { attachLayerEditor } from './layer-editor.js';\n\nexport type LayerWidgetElements = Partial<Record<LayerWidgetKey, HTMLElement>>;\n\nexport interface LayerCompositorOptions {\n preset: LayoutPreset;\n widgets: LayerWidgetElements;\n /** Hide legacy grid container when compositor positions widgets. */\n hideLegacyGrid?: HTMLElement;\n /** Fired after user drag/resize commits a preset change. */\n onPresetChange?: (preset: LayoutPreset) => void;\n /** Shift+drag marquee on compositor root (edit mode). */\n onMarqueeSelect?: (layerIds: string[]) => void;\n /** P2: chart pane focus changed (main / volume / indicator). */\n onChartPaneFocus?: (pane: 'main' | 'volume' | 'indicator' | null) => void;\n}\n\nexport interface LayerCompositorHandle {\n root: HTMLElement;\n controller: LayerController;\n apply(): void;\n enableLayerEditor(enabled: boolean): void;\n isLayerEditorEnabled(): boolean;\n destroy(): void;\n}\n\nfunction resolveWidgetEl(\n widgets: LayerWidgetElements,\n layer: LayerNode,\n): HTMLElement | undefined {\n const key = layer.widgetKey as LayerWidgetKey;\n if (layer.type === 'overlay.drawing') {\n return widgets.drawingOverlay ?? widgets.chartMain ?? widgets.chartHost;\n }\n return (\n widgets[key] ??\n (layer.widgetKey === 'chartMain' ? widgets.chartHost : undefined) ??\n (layer.widgetKey === 'chartIndicator' ? widgets.indicatorHost : undefined)\n );\n}\n\nfunction applyWrapFrame(wrap: HTMLElement, layer: LayerNode): void {\n wrap.style.left = `${layer.frame.x * 100}%`;\n wrap.style.top = `${layer.frame.y * 100}%`;\n wrap.style.width = `${layer.frame.w * 100}%`;\n wrap.style.height = `${layer.frame.h * 100}%`;\n wrap.style.zIndex = String(layer.zIndex + 1);\n}\n\nfunction layerStructureSignature(layers: LayerNode[], activePageId: string): string {\n return `${activePageId}|${layers\n .map((l) => `${l.id}:${l.type}:${l.widgetKey}:${l.visible}:${l.locked}`)\n .join('|')}`;\n}\n\nfunction wrapPointerEventsForLayer(layer: LayerNode, editorEnabled: boolean): string {\n if (layer.locked) return 'none';\n if (isOverlayLayerType(layer.type)) return 'none';\n if (isChartPaneLayerType(layer.type) && editorEnabled) return 'none';\n return 'auto';\n}\n\n/** @public Mount floating layer compositor (LayoutPreset v2) over shell widgets. */\nexport function mountLayerCompositor(\n parent: HTMLElement,\n opts: LayerCompositorOptions,\n): LayerCompositorHandle {\n const controller = new LayerController(opts.preset);\n const wrappers = new Map<string, HTMLElement>();\n let lastStructureSig = '';\n\n const root = document.createElement('div');\n root.className = 'tv-layer-compositor';\n root.style.cssText =\n 'position:absolute;inset:0;overflow:hidden;pointer-events:none;z-index:5;';\n parent.style.position = parent.style.position || 'relative';\n parent.appendChild(root);\n\n const editor = attachLayerEditor(root, {\n controller,\n onPresetChange: () => opts.onPresetChange?.(controller.getPreset()),\n onMarqueeSelect: opts.onMarqueeSelect,\n });\n\n const applyFocusStyles = () => {\n const focused = controller.focusedPaneLayerId;\n for (const [id, wrap] of wrappers) {\n const layer = controller.getLayer(id);\n if (!layer || !isChartPaneLayerType(layer.type)) continue;\n const active = id === focused;\n wrap.dataset.focused = active ? '1' : '0';\n wrap.style.outline = active ? '2px solid #58a6ff' : 'none';\n wrap.style.outlineOffset = active ? '-2px' : '';\n }\n };\n\n const patchFocusVisuals = (layers: LayerNode[]) => {\n for (const layer of layers) {\n const wrap = wrappers.get(layer.id);\n if (wrap) applyWrapFrame(wrap, layer);\n }\n applyFocusStyles();\n };\n\n const patchLayoutFrames = (layers: LayerNode[], patchOpts: { rebind?: boolean } = {}) => {\n patchFocusVisuals(layers);\n if (patchOpts.rebind !== false) editor.rebind();\n };\n\n const ensureDefaultChartFocus = (chartPaneIds: string[]) => {\n if (\n controller.focusedPaneLayerId &&\n !chartPaneIds.includes(controller.focusedPaneLayerId)\n ) {\n controller.focusedPaneLayerId = chartPaneIds[chartPaneIds.length - 1] ?? null;\n }\n if (!controller.focusedPaneLayerId && chartPaneIds.length > 0) {\n controller.focusedPaneLayerId = chartPaneIds[chartPaneIds.length - 1]!;\n }\n };\n\n const bindChartPanePointer = (wrap: HTMLElement, layer: LayerNode) => {\n wrap.addEventListener('pointerdown', (e) => {\n if (e.button !== 0 || controller.isInteracting()) return;\n const prev = controller.focusedPaneLayerId;\n if (prev === layer.id) return;\n queueMicrotask(() => {\n if (controller.isInteracting()) return;\n controller.focusChartPane(layer.id);\n opts.onChartPaneFocus?.(controller.getFocusedPaneId());\n });\n });\n };\n\n const syncRootPointerEvents = () => {\n root.style.pointerEvents = editor.isEnabled() ? 'auto' : 'none';\n };\n\n const apply = () => {\n syncRootPointerEvents();\n const preset = controller.getPreset();\n const layers = preset.layers\n .filter((l) => l.pageId === controller.activePageId && l.visible)\n .sort((a, b) => a.zIndex - b.zIndex);\n\n if (opts.hideLegacyGrid) opts.hideLegacyGrid.style.visibility = 'hidden';\n\n const chartPaneIds = layers.filter((l) => isChartPaneLayerType(l.type)).map((l) => l.id);\n ensureDefaultChartFocus(chartPaneIds);\n\n const structureSig = layerStructureSignature(layers, controller.activePageId);\n if (structureSig === lastStructureSig && wrappers.size > 0) {\n patchLayoutFrames(layers);\n return;\n }\n lastStructureSig = structureSig;\n\n root.replaceChildren();\n wrappers.clear();\n\n const editorOn = editor.isEnabled();\n\n for (const layer of layers) {\n if (layer.type === 'overlay.drawing') continue;\n\n const el = resolveWidgetEl(opts.widgets, layer);\n if (!el) continue;\n\n const wrap = document.createElement('div');\n wrap.className = 'tv-layer-wrap';\n if (isChartPaneLayerType(layer.type)) wrap.classList.add('tv-chart-pane-wrap');\n if (isOverlayLayerType(layer.type)) wrap.classList.add('tv-overlay-wrap');\n wrap.dataset.layerId = layer.id;\n wrap.dataset.widgetKey = layer.widgetKey;\n wrap.dataset.layerType = layer.type;\n if (layer.groupId) wrap.dataset.groupId = layer.groupId;\n\n const pe = wrapPointerEventsForLayer(layer, editorOn);\n wrap.style.cssText = [\n 'position:absolute',\n 'overflow:visible',\n 'box-sizing:border-box',\n `pointer-events:${pe}`,\n ].join(';');\n applyWrapFrame(wrap, layer);\n\n if (isChartPaneLayerType(layer.type) && !layer.locked && !editorOn) {\n bindChartPanePointer(wrap, layer);\n }\n\n if (layer.type === 'overlay.crosshairLegend') {\n el.style.pointerEvents = 'none';\n }\n\n el.style.width = '100%';\n el.style.height = '100%';\n el.style.minWidth = '0';\n el.style.minHeight = '0';\n el.style.overflow = layer.type === 'overlay.crosshairLegend' ? 'visible' : 'hidden';\n wrap.appendChild(el);\n root.appendChild(wrap);\n wrappers.set(layer.id, wrap);\n }\n\n applyFocusStyles();\n editor.rebind();\n };\n\n const unsubLayout = controller.subscribe(apply);\n const unsubFocus = controller.subscribeFocus(() => {\n const visible = controller\n .getLayersForActivePage()\n .filter((l) => l.visible);\n patchFocusVisuals(visible);\n });\n\n apply();\n\n return {\n root,\n controller,\n apply,\n enableLayerEditor: (enabled) => {\n editor.setEnabled(enabled);\n syncRootPointerEvents();\n apply();\n },\n isLayerEditorEnabled: () => editor.isEnabled(),\n destroy: () => {\n unsubLayout();\n unsubFocus();\n editor.destroy();\n root.remove();\n if (opts.hideLegacyGrid) opts.hideLegacyGrid.style.visibility = '';\n },\n };\n}","import { t } from '@coderyo/i18n';\nimport { isChartPaneLayerType } from './chart-pane-mount.js';\nimport type { LayerController } from './layer-controller.js';\n\nexport interface LayerPanelOptions {\n onSaveAsPreset?: (preset: ReturnType<LayerController['getPreset']>) => void;\n}\n\nexport interface LayerPanelHandle {\n el: HTMLElement;\n destroy: () => void;\n toggle: () => boolean;\n /** Replace panel checkbox selection (e.g. compositor shift+marquee). */\n selectLayers(layerIds: string[]): void;\n}\n\n/** @public Layer list UI bound to a LayerController. */\nexport function mountLayerPanel(\n parent: HTMLElement,\n controller: LayerController,\n opts: LayerPanelOptions = {},\n): LayerPanelHandle {\n const panel = document.createElement('aside');\n panel.className = 'tv-layer-panel';\n panel.style.cssText =\n 'display:none;position:fixed;right:12px;top:72px;width:240px;max-height:min(70vh,480px);z-index:2100;background:#161b22;border:1px solid #30363d;border-radius:8px;box-shadow:0 8px 24px #01040999;flex-direction:column;overflow:hidden;font-size:11px;color:#e6edf3;';\n\n const header = document.createElement('div');\n header.style.cssText =\n 'display:flex;align-items:center;justify-content:space-between;padding:8px 10px;border-bottom:1px solid #30363d;flex-shrink:0;';\n const title = document.createElement('span');\n title.textContent = t('layer.panel.title', '圖層');\n title.style.fontWeight = '600';\n const closeBtn = document.createElement('button');\n closeBtn.type = 'button';\n closeBtn.textContent = '×';\n closeBtn.style.cssText =\n 'background:transparent;border:none;color:#8b949e;font-size:18px;cursor:pointer;line-height:1;';\n header.append(title, closeBtn);\n\n const groupBar = document.createElement('div');\n groupBar.style.cssText =\n 'display:flex;gap:4px;padding:6px 8px;border-bottom:1px solid #30363d;flex-shrink:0;flex-wrap:wrap;';\n const createGroupBtn = document.createElement('button');\n createGroupBtn.type = 'button';\n createGroupBtn.textContent = t('layer.panel.createGroup', '建立群組');\n createGroupBtn.style.cssText =\n 'flex:1;min-width:0;padding:4px 6px;background:#21262d;color:#e6edf3;border:1px solid #30363d;border-radius:4px;cursor:pointer;font-size:10px;';\n const removeFromGroupBtn = document.createElement('button');\n removeFromGroupBtn.type = 'button';\n removeFromGroupBtn.textContent = t('layer.panel.removeFromGroup', '移出群組');\n removeFromGroupBtn.style.cssText = createGroupBtn.style.cssText;\n const ungroupBtn = document.createElement('button');\n ungroupBtn.type = 'button';\n ungroupBtn.textContent = t('layer.panel.ungroup', '解散群組');\n ungroupBtn.style.cssText = createGroupBtn.style.cssText;\n groupBar.append(createGroupBtn, removeFromGroupBtn, ungroupBtn);\n\n const list = document.createElement('div');\n list.style.cssText = 'overflow:auto;flex:1;min-height:0;padding:6px 4px;';\n\n const footer = document.createElement('div');\n footer.style.cssText = 'padding:8px;border-top:1px solid #30363d;flex-shrink:0;';\n const saveBtn = document.createElement('button');\n saveBtn.type = 'button';\n saveBtn.textContent = t('layer.panel.saveAs', '另存為我的範本');\n saveBtn.style.cssText =\n 'width:100%;padding:6px 8px;background:#21262d;color:#e6edf3;border:1px solid #30363d;border-radius:4px;cursor:pointer;font-size:11px;';\n footer.appendChild(saveBtn);\n\n panel.append(header, groupBar, list, footer);\n parent.appendChild(panel);\n\n let open = false;\n const selected = new Set<string>();\n let dragLayerId: string | null = null;\n\n const btnStyle =\n 'width:24px;height:22px;padding:0;border:1px solid #30363d;border-radius:3px;background:#21262d;cursor:pointer;font-size:10px;';\n\n const render = () => {\n list.replaceChildren();\n const layers = [...controller.getLayersForActivePage()].sort((a, b) => b.zIndex - a.zIndex);\n\n for (const id of [...selected]) {\n if (!layers.some((l) => l.id === id)) selected.delete(id);\n }\n\n createGroupBtn.disabled = selected.size < 2;\n const selectedWithGroup = layers.filter((l) => selected.has(l.id) && l.groupId);\n ungroupBtn.disabled = selectedWithGroup.length === 0;\n const singleInGroup =\n selected.size === 1 &&\n [...selected].some((id) => controller.getLayer(id)?.groupId);\n removeFromGroupBtn.disabled = !singleInGroup;\n\n for (const layer of layers) {\n const row = document.createElement('div');\n row.draggable = !layer.locked;\n row.dataset.layerId = layer.id;\n row.style.cssText =\n 'display:flex;align-items:center;gap:4px;padding:4px 6px;margin-bottom:2px;border-radius:4px;background:#0d1117;border:1px solid #21262d;cursor:grab;';\n\n row.ondragstart = (e) => {\n if (layer.locked) return;\n dragLayerId = layer.id;\n e.dataTransfer?.setData('text/plain', layer.id);\n if (e.dataTransfer) e.dataTransfer.effectAllowed = 'move';\n row.style.opacity = '0.55';\n };\n row.ondragend = () => {\n row.style.opacity = '';\n dragLayerId = null;\n };\n row.ondragover = (e) => {\n e.preventDefault();\n if (e.dataTransfer) e.dataTransfer.dropEffect = 'move';\n };\n row.ondrop = (e) => {\n e.preventDefault();\n if (!dragLayerId || dragLayerId === layer.id) return;\n const visual = [...controller.getLayersForActivePage()].sort(\n (a, b) => b.zIndex - a.zIndex,\n );\n const ids = visual.map((l) => l.id);\n const from = ids.indexOf(dragLayerId);\n const to = ids.indexOf(layer.id);\n if (from < 0 || to < 0) return;\n ids.splice(from, 1);\n ids.splice(to, 0, dragLayerId);\n controller.reorderLayers([...ids].reverse());\n dragLayerId = null;\n };\n\n const pick = document.createElement('input');\n pick.type = 'checkbox';\n pick.checked = selected.has(layer.id);\n pick.title = t('layer.panel.select', '選取');\n pick.style.cssText = 'width:14px;height:14px;cursor:pointer;flex-shrink:0;';\n pick.onchange = () => {\n if (pick.checked) selected.add(layer.id);\n else selected.delete(layer.id);\n render();\n };\n\n const eye = document.createElement('button');\n eye.type = 'button';\n eye.textContent = layer.visible ? '👁' : '—';\n eye.title = t('layer.panel.visibility', '顯示');\n eye.style.cssText = btnStyle;\n\n const lock = document.createElement('button');\n lock.type = 'button';\n lock.textContent = layer.locked ? '🔒' : '🔓';\n lock.title = t('layer.panel.lock', '鎖定');\n lock.style.cssText = btnStyle;\n\n const label = document.createElement('span');\n const groupTag = layer.groupId ? ` [${layer.groupId.slice(-4)}]` : '';\n label.textContent = `${layer.widgetKey}${groupTag}`;\n label.style.cssText = 'flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;';\n\n let syncIn: HTMLInputElement | null = null;\n if (isChartPaneLayerType(layer.type)) {\n syncIn = document.createElement('input');\n syncIn.type = 'text';\n syncIn.placeholder = t('layer.panel.syncGroup', '時間軸組');\n syncIn.value = layer.syncTimeScaleGroupId ?? '';\n syncIn.title = t(\n 'layer.panel.syncGroupHint',\n '相同組名同步縮放;留空則獨立',\n );\n syncIn.style.cssText =\n 'width:52px;flex-shrink:0;padding:2px 4px;font-size:10px;background:#21262d;color:#e6edf3;border:1px solid #30363d;border-radius:3px;';\n syncIn.onchange = () => {\n controller.setLayerSyncGroup(layer.id, syncIn!.value);\n };\n }\n\n const zUp = document.createElement('button');\n zUp.type = 'button';\n zUp.textContent = '▲';\n zUp.title = 'z+';\n zUp.style.cssText = btnStyle;\n const zDown = document.createElement('button');\n zDown.type = 'button';\n zDown.textContent = '▼';\n zDown.title = 'z-';\n zDown.style.cssText = btnStyle;\n\n eye.onclick = () => controller.setLayerVisible(layer.id, !layer.visible);\n lock.onclick = () => controller.setLayerLocked(layer.id, !layer.locked);\n zUp.onclick = () => controller.bumpZIndex(layer.id, 1);\n zDown.onclick = () => controller.bumpZIndex(layer.id, -1);\n\n if (syncIn) row.append(pick, eye, lock, label, syncIn, zUp, zDown);\n else row.append(pick, eye, lock, label, zUp, zDown);\n list.appendChild(row);\n }\n };\n\n createGroupBtn.onclick = () => {\n const ids = [...selected];\n if (ids.length < 2) return;\n controller.createBindGroup(ids);\n selected.clear();\n render();\n };\n\n removeFromGroupBtn.onclick = () => {\n const id = [...selected][0];\n if (!id) return;\n controller.removeLayerFromGroup(id);\n render();\n };\n\n ungroupBtn.onclick = () => {\n const groupIds = new Set<string>();\n for (const id of selected) {\n const layer = controller.getLayer(id);\n if (layer?.groupId) groupIds.add(layer.groupId);\n }\n for (const gid of groupIds) controller.dissolveGroup(gid);\n render();\n };\n\n const unsub = controller.subscribe(render);\n render();\n\n closeBtn.onclick = () => {\n open = false;\n panel.style.display = 'none';\n };\n\n saveBtn.onclick = () => opts.onSaveAsPreset?.(controller.getPreset());\n\n return {\n el: panel,\n destroy: () => {\n unsub();\n panel.remove();\n },\n toggle: () => {\n open = !open;\n panel.style.display = open ? 'flex' : 'none';\n return open;\n },\n selectLayers(layerIds: string[]) {\n selected.clear();\n for (const id of layerIds) selected.add(id);\n render();\n },\n };\n}","import { t } from '@coderyo/i18n';\nimport type { LayerController } from './layer-controller.js';\n\nexport interface PageNavigatorOptions {\n /** Show tab bar even on wide viewports (default: narrow only). */\n alwaysVisible?: boolean;\n narrowMq?: string;\n onPageChange?: (pageId: string) => void;\n}\n\nexport interface PageNavigatorHandle {\n el: HTMLElement;\n destroy: () => void;\n refresh: () => void;\n}\n\n/** @public Mobile-style page tabs for LayoutPreset v2 (P4). */\nexport function mountPageNavigator(\n parent: HTMLElement,\n controller: LayerController,\n opts: PageNavigatorOptions = {},\n): PageNavigatorHandle {\n const mq = opts.narrowMq ?? '(max-width: 768px)';\n const nav = document.createElement('nav');\n nav.className = 'tv-page-navigator';\n nav.style.cssText =\n 'display:none;align-items:center;gap:4px;padding:4px 8px;border-top:1px solid #30363d;background:#161b22;flex-shrink:0;flex-wrap:wrap;font-size:11px;color:#e6edf3;';\n\n const tabs = document.createElement('div');\n tabs.style.cssText = 'display:flex;gap:4px;flex-wrap:wrap;flex:1;min-width:0;';\n const actions = document.createElement('div');\n actions.style.cssText = 'display:flex;gap:4px;flex-shrink:0;';\n\n const addBtn = document.createElement('button');\n addBtn.type = 'button';\n addBtn.title = t('page.nav.add', '新增頁面');\n addBtn.textContent = '+';\n addBtn.style.cssText =\n 'width:28px;height:24px;background:#21262d;color:#e6edf3;border:1px solid #30363d;border-radius:4px;cursor:pointer;font-size:14px;line-height:1;';\n\n const renameBtn = document.createElement('button');\n renameBtn.type = 'button';\n renameBtn.title = t('page.nav.rename', '重新命名');\n renameBtn.textContent = '✎';\n renameBtn.style.cssText =\n 'width:28px;height:24px;background:#21262d;color:#e6edf3;border:1px solid #30363d;border-radius:4px;cursor:pointer;font-size:12px;';\n\n const delBtn = document.createElement('button');\n delBtn.type = 'button';\n delBtn.title = t('page.nav.delete', '刪除頁面');\n delBtn.textContent = '×';\n delBtn.style.cssText = renameBtn.style.cssText;\n\n actions.append(addBtn, renameBtn, delBtn);\n nav.append(tabs, actions);\n parent.appendChild(nav);\n\n const tabBtnStyle =\n 'padding:4px 10px;background:#21262d;color:#8b949e;border:1px solid #30363d;border-radius:4px;cursor:pointer;font-size:11px;max-width:120px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;';\n const tabBtnActiveStyle = tabBtnStyle.replace('#21262d', '#388bfd').replace('#8b949e', '#fff');\n\n const refresh = () => {\n tabs.replaceChildren();\n const preset = controller.getPreset();\n for (const page of preset.pages) {\n const btn = document.createElement('button');\n btn.type = 'button';\n btn.textContent = page.title;\n btn.title = page.title;\n btn.style.cssText =\n page.id === controller.activePageId ? tabBtnActiveStyle : tabBtnStyle;\n btn.onclick = () => {\n if (controller.setActivePage(page.id)) {\n opts.onPageChange?.(page.id);\n }\n };\n tabs.appendChild(btn);\n }\n delBtn.disabled = preset.pages.length <= 1;\n };\n\n addBtn.onclick = () => {\n const title = window.prompt(t('page.nav.addPrompt', '新頁面名稱'), '');\n const id = controller.addPage(title ?? undefined);\n opts.onPageChange?.(id);\n };\n\n renameBtn.onclick = () => {\n const page = controller.getPreset().pages.find((p) => p.id === controller.activePageId);\n if (!page) return;\n let title = window.prompt(t('page.nav.renamePrompt', '頁面名稱'), page.title);\n if (title == null) return;\n while (title !== null && !controller.renamePage(page.id, title)) {\n title = window.prompt(\n t('page.nav.renameEmpty', '名稱不可為空,請重新輸入'),\n title,\n );\n if (title == null) return;\n }\n };\n\n delBtn.onclick = () => {\n const page = controller.getPreset().pages.find((p) => p.id === controller.activePageId);\n if (!page || controller.getPreset().pages.length <= 1) return;\n if (!window.confirm(t('page.nav.deleteConfirm', `刪除「${page.title}」?`))) return;\n controller.removePage(page.id);\n opts.onPageChange?.(controller.activePageId);\n };\n\n const media = window.matchMedia(mq);\n const syncVisible = () => {\n nav.style.display = opts.alwaysVisible || media.matches ? 'flex' : 'none';\n };\n media.addEventListener('change', syncVisible);\n syncVisible();\n\n const unsub = controller.subscribe(refresh);\n refresh();\n\n return {\n el: nav,\n destroy: () => {\n unsub();\n media.removeEventListener('change', syncVisible);\n nav.remove();\n },\n refresh,\n };\n}","import type { LayerController } from './layer-controller.js';\n\n/** Minimal chart surface for layer time-scale sync (matches `IChart.applyTimeScaleSyncFromLayers`). */\nexport interface LayerTimeScaleSyncChart {\n applyTimeScaleSyncFromLayers(\n layers: Array<{ type: string; pageId?: string; syncTimeScaleGroupId?: string }>,\n pageId?: string,\n ): unknown;\n}\n\nexport interface BindLayerTimeScaleSyncOptions {\n /** Called after each sync apply (e.g. `requestAnimationFrame(chart.resize)`). */\n onSync?: () => void;\n}\n\n/**\n * @public Wire `IChart.applyTimeScaleSyncFromLayers` to `LayerController` preset mutations.\n * Applies immediately and on `controller.subscribe` (page switch, sync group, layer edits).\n * Returns unsubscribe — call after `mountLayerCompositor` + `createChart`.\n */\nexport function bindLayerTimeScaleSync(\n chart: LayerTimeScaleSyncChart,\n controller: LayerController,\n options?: BindLayerTimeScaleSyncOptions,\n): () => void {\n const apply = () => {\n chart.applyTimeScaleSyncFromLayers(\n controller.getPreset().layers,\n controller.activePageId,\n );\n options?.onSync?.();\n };\n apply();\n return controller.subscribe(apply);\n}","import { normalizeLayoutPreset } from './normalize.js';\nimport {\n LAYER_PRESET_VERSION,\n type BindGroup,\n type LayoutPage,\n type LayoutPreset,\n type LayerNode,\n} from './types.js';\n\nfunction upsertById<T extends { id: string }>(current: T[], incoming: T[] | undefined): T[] {\n if (!incoming?.length) return current.map((x) => ({ ...x }));\n const map = new Map(current.map((x) => [x.id, { ...x }]));\n for (const item of incoming) {\n if (!item?.id) continue;\n map.set(item.id, { ...item });\n }\n return [...map.values()];\n}\n\nfunction mergePages(current: LayoutPage[], incoming: LayoutPage[] | undefined): LayoutPage[] {\n return upsertById(current, incoming);\n}\n\nfunction mergeLayers(current: LayerNode[], incoming: LayerNode[] | undefined): LayerNode[] {\n if (!incoming?.length) return current.map((l) => ({ ...l, frame: { ...l.frame } }));\n const map = new Map(current.map((l) => [l.id, { ...l, frame: { ...l.frame } }]));\n for (const raw of incoming) {\n if (!raw?.id) continue;\n const prev = map.get(raw.id);\n map.set(raw.id, {\n ...(prev ?? raw),\n ...raw,\n frame: { ...(prev?.frame ?? raw.frame ?? { x: 0, y: 0, w: 1, h: 1 }) },\n });\n }\n return [...map.values()];\n}\n\nfunction mergeGroups(current: BindGroup[], incoming: BindGroup[] | undefined): BindGroup[] {\n if (!incoming?.length) {\n return current.map((g) => ({ ...g, layerIds: [...g.layerIds] }));\n }\n const map = new Map(current.map((g) => [g.id, { ...g, layerIds: [...g.layerIds] }]));\n for (const raw of incoming) {\n if (!raw?.id) continue;\n map.set(raw.id, {\n id: raw.id,\n name: raw.name ?? map.get(raw.id)?.name,\n layerIds: [...(raw.layerIds ?? map.get(raw.id)?.layerIds ?? [])],\n });\n }\n return [...map.values()];\n}\n\n/**\n * @public Merge partial LayoutPreset v2 into `current` (pages/layers/groups upsert by id).\n * Unmentioned entries are preserved. Result is normalized.\n */\nexport function mergeLayoutPreset(current: LayoutPreset, partial: LayoutPreset): LayoutPreset {\n return normalizeLayoutPreset({\n ...current,\n ...partial,\n version: LAYER_PRESET_VERSION,\n pages: mergePages(current.pages, partial.pages),\n layers: mergeLayers(current.layers, partial.layers),\n groups: mergeGroups(current.groups, partial.groups),\n });\n}","import type {\n ChartLayerBridgeRegistration,\n LayerBridgeController,\n LayerBridgePreset,\n LayerTimeScaleSyncChart,\n} from '@coderyo/core';\nimport type { LayerController } from './layer-controller.js';\nimport { mergeLayoutPreset } from './merge-preset.js';\nimport { normalizeLayoutPreset } from './normalize.js';\nimport type { LayoutPreset } from './types.js';\n\nexport type { ChartLayerBridgeRegistration } from '@coderyo/core';\n\nfunction asLayerBridgePreset(p: LayoutPreset): LayerBridgePreset {\n return p as unknown as LayerBridgePreset;\n}\n\n/** Wrap `LayerController` for `wireChartBridge` / `registerChartLayerBridge`. */\nexport function wrapLayerController(lc: LayerController): LayerBridgeController {\n return {\n get activePageId() {\n return lc.activePageId;\n },\n get presetRevision() {\n return lc.presetRevision;\n },\n set presetRevision(v: number) {\n lc.presetRevision = v;\n },\n getPreset: () => asLayerBridgePreset(lc.getPreset()),\n setLayerSyncGroup: (layerId, groupId) => lc.setLayerSyncGroup(layerId, groupId),\n setLayerVisible: (layerId, visible) => lc.setLayerVisible(layerId, visible),\n setActivePage: (pageId) => lc.setActivePage(pageId),\n setPreset: (next) => lc.setPreset(next as unknown as LayoutPreset),\n };\n}\n\nexport interface CreateLayerBridgeRegistrationOptions {\n chartId: string;\n chart: LayerTimeScaleSyncChart;\n layerController: LayerController;\n compositorApply?: () => void;\n syncCompositorShellVisibility?: () => void;\n normalizePreset?: (input: LayerBridgePreset) => LayerBridgePreset;\n mergePreset?: (current: LayerBridgePreset, partial: LayerBridgePreset) => LayerBridgePreset;\n}\n\n/**\n * @public Build `ChartLayerBridgeRegistration` for `wireChartBridge({ layerBridge })`.\n * Defaults `normalizePreset` / `mergePreset` to ui-shell layout helpers.\n */\nexport function createLayerBridgeRegistration(\n opts: CreateLayerBridgeRegistrationOptions,\n): ChartLayerBridgeRegistration {\n const normalizePreset =\n opts.normalizePreset ??\n ((p) => asLayerBridgePreset(normalizeLayoutPreset(p as unknown as LayoutPreset)));\n const mergePreset =\n opts.mergePreset ??\n ((current, partial) =>\n asLayerBridgePreset(\n mergeLayoutPreset(\n current as unknown as LayoutPreset,\n partial as unknown as LayoutPreset,\n ),\n ));\n\n return {\n chartId: opts.chartId,\n chart: opts.chart,\n layerController: wrapLayerController(opts.layerController),\n compositorApply: opts.compositorApply,\n syncCompositorShellVisibility: opts.syncCompositorShellVisibility,\n normalizePreset,\n mergePreset,\n };\n}","import type { BridgeLayerPane } from '@coderyo/bridge';\nimport {\n isValidLayerBridgePane,\n resolvePaneLayerIds as resolvePaneLayerIdsCore,\n} from '@coderyo/core';\nimport type { LayerType, LayoutPreset } from './types.js';\n\nconst PANE_TO_LAYER_TYPE: Record<BridgeLayerPane, LayerType> = {\n main: 'chart.main',\n volume: 'chart.volume',\n indicator: 'chart.indicator',\n};\n\nexport function layerTypeForBridgePane(pane: BridgeLayerPane): LayerType {\n return PANE_TO_LAYER_TYPE[pane];\n}\n\nexport { isValidLayerBridgePane as isValidBridgeLayerPane };\n\n/**\n * @public Resolve chart pane → layer ids for preset scope (supports `allPages`).\n */\nexport function resolvePaneLayerIds(\n preset: Pick<LayoutPreset, 'layers' | 'pages'>,\n pane: BridgeLayerPane,\n opts?: { allPages?: boolean; activePageId?: string },\n): string[] {\n return resolvePaneLayerIdsCore(preset, pane, opts);\n}","import type { DrawingRecord } from '@coderyo/drawings';\nimport { t } from '@coderyo/i18n';\n\nexport interface DrawingContextMenuHandlers {\n onDelete?: () => void;\n onCopy?: () => void;\n onToggleLock?: () => void;\n onDeselect?: () => void;\n onEditText?: () => void;\n}\n\nexport function openDrawingContextMenu(\n clientX: number,\n clientY: number,\n drawing: DrawingRecord | null,\n handlers: DrawingContextMenuHandlers,\n): () => void {\n const menu = document.createElement('div');\n menu.style.cssText =\n 'position:fixed;z-index:60;min-width:168px;padding:4px 0;background:#161b22;border:1px solid #30363d;border-radius:6px;box-shadow:0 8px 24px #01040988;';\n menu.style.left = `${clientX}px`;\n menu.style.top = `${clientY}px`;\n\n const add = (label: string, fn?: () => void, disabled = false) => {\n if (!fn) return;\n const btn = document.createElement('button');\n btn.type = 'button';\n btn.textContent = label;\n btn.disabled = disabled;\n btn.style.cssText =\n 'display:block;width:100%;text-align:left;padding:8px 12px;border:none;background:transparent;color:#e6edf3;font-size:12px;cursor:pointer;';\n if (disabled) btn.style.opacity = '0.45';\n btn.onclick = () => {\n fn();\n close();\n };\n menu.appendChild(btn);\n };\n\n if (drawing) {\n const locked = Boolean(drawing.meta?.locked);\n add(t('drawing.ctx.delete', '刪除'), handlers.onDelete);\n add(t('drawing.ctx.copy', '複製'), handlers.onCopy);\n add(\n locked ? t('drawing.ctx.unlock', '解鎖') : t('drawing.ctx.lock', '鎖定'),\n handlers.onToggleLock,\n );\n if (drawing.type === 'text') {\n add(t('drawing.ctx.editText', '編輯文字'), handlers.onEditText);\n }\n add(t('drawing.ctx.deselect', '取消選取'), handlers.onDeselect);\n }\n\n document.body.appendChild(menu);\n\n const close = () => {\n menu.remove();\n document.removeEventListener('click', close);\n };\n setTimeout(() => document.addEventListener('click', close), 0);\n return close;\n}","export function mountCodeSnippetPanel(parent: HTMLElement, getCode: () => string): HTMLElement {\n const wrap = document.createElement('details');\n wrap.style.cssText =\n 'flex-shrink:0;border-top:1px solid #30363d;background:#161b22;padding:6px 12px;font-size:11px;color:#8b949e;';\n\n const summary = document.createElement('summary');\n summary.textContent = '嵌入程式碼(整合方)';\n summary.style.cssText = 'cursor:pointer;color:#58a6ff;user-select:none;';\n\n const pre = document.createElement('pre');\n pre.style.cssText =\n 'margin:8px 0 0;padding:10px;background:#0d1117;border:1px solid #30363d;border-radius:6px;color:#e6edf3;font-size:11px;overflow:auto;max-height:160px;white-space:pre-wrap;';\n\n const copyBtn = document.createElement('button');\n copyBtn.type = 'button';\n copyBtn.textContent = '複製';\n copyBtn.style.cssText =\n 'margin-top:6px;padding:4px 10px;background:#21262d;color:#e6edf3;border:1px solid #30363d;border-radius:4px;cursor:pointer;font-size:11px;';\n copyBtn.onclick = () => {\n const code = getCode();\n pre.textContent = code;\n void navigator.clipboard.writeText(code);\n };\n\n wrap.ontoggle = () => {\n if (wrap.open) pre.textContent = getCode();\n };\n\n wrap.append(summary, pre, copyBtn);\n parent.appendChild(wrap);\n return wrap;\n}","import { compilePineLite } from '@coderyo/pine-lite';\n\ninterface PineDiagnostic {\n line: number;\n col: number;\n message: string;\n severity: 'error' | 'warning';\n endCol?: number;\n}\nimport { defaultKeymap, history, historyKeymap } from '@codemirror/commands';\nimport { syntaxHighlighting, defaultHighlightStyle, bracketMatching } from '@codemirror/language';\nimport { linter, type Diagnostic as CmDiagnostic } from '@codemirror/lint';\nimport { EditorState, type Extension } from '@codemirror/state';\nimport {\n EditorView,\n drawSelection,\n highlightActiveLine,\n highlightActiveLineGutter,\n keymap,\n lineNumbers,\n placeholder,\n} from '@codemirror/view';\nimport { t } from '@coderyo/i18n';\nimport { pineLanguage } from './pine-language.js';\n\nexport const PINE_SCRIPT_STORAGE_KEY = 'tradview:pine:script';\n\nexport function loadPineScriptPreference(): string | null {\n try {\n return localStorage.getItem(PINE_SCRIPT_STORAGE_KEY);\n } catch {\n return null;\n }\n}\n\nexport function savePineScriptPreference(script: string): void {\n try {\n localStorage.setItem(PINE_SCRIPT_STORAGE_KEY, script);\n } catch {\n /* ignore */\n }\n}\n\nfunction offsetAtLineCol(doc: string, line: number, col: number): number {\n const lines = doc.split('\\n');\n let off = 0;\n for (let i = 0; i < line - 1 && i < lines.length; i++) {\n off += lines[i]!.length + 1;\n }\n return off + Math.max(0, col - 1);\n}\n\nfunction pineDiagnosticsToCm(doc: string, diags: PineDiagnostic[]): CmDiagnostic[] {\n return diags.map((d) => {\n const from = offsetAtLineCol(doc, d.line, d.col);\n const to = d.endCol != null ? offsetAtLineCol(doc, d.line, d.endCol) : from + 1;\n return {\n from,\n to: Math.max(from + 1, to),\n severity: d.severity,\n message: d.message,\n };\n });\n}\n\nfunction createPineLinter(onStatus?: (msg: string, ok: boolean) => void) {\n return linter((view) => {\n const src = view.state.doc.toString();\n const result = compilePineLite(src);\n if (result.ok) {\n onStatus?.(t('pine.status.ok', '語法正確'), true);\n return [];\n }\n onStatus?.(result.errors[0] ?? t('pine.status.error', '語法錯誤'), false);\n return pineDiagnosticsToCm(src, result.diagnostics ?? []);\n });\n}\n\nconst darkTheme = EditorView.theme({\n '&': {\n backgroundColor: '#0d1117',\n color: '#e6edf3',\n fontSize: '12px',\n },\n '.cm-content': { caretColor: '#58a6ff', fontFamily: 'Consolas, \"Cascadia Code\", monospace' },\n '.cm-gutters': {\n backgroundColor: '#161b22',\n color: '#8b949e',\n borderRight: '1px solid #30363d',\n },\n '.cm-activeLine': { backgroundColor: '#161b22aa' },\n '.cm-activeLineGutter': { backgroundColor: '#21262d' },\n '.cm-selectionBackground, &.cm-focused .cm-selectionBackground': { backgroundColor: '#264f78' },\n '.cm-cursor': { borderLeftColor: '#58a6ff' },\n '.cm-lintRange-error': { backgroundImage: 'none', borderBottom: '2px wavy #f85149' },\n '.cm-lintRange-warning': { backgroundImage: 'none', borderBottom: '2px wavy #d29922' },\n});\n\nexport interface PineEditorPanelOptions {\n initialScript?: string;\n /** Debounced apply to chart (ms). Default 400. */\n debounceMs?: number;\n onApply?: (script: string, compileOk: boolean) => void;\n}\n\nexport function mountPineEditorPanel(\n parent: HTMLElement,\n opts: PineEditorPanelOptions = {},\n): {\n el: HTMLElement;\n getScript: () => string;\n setScript: (script: string) => void;\n applyNow: () => void;\n destroy: () => void;\n} {\n const wrap = document.createElement('details');\n wrap.className = 'tv-pine-editor';\n wrap.open = true;\n wrap.style.cssText =\n 'flex-shrink:0;border-top:1px solid #30363d;background:#161b22;max-height:220px;display:flex;flex-direction:column;';\n\n const summary = document.createElement('summary');\n summary.textContent = t('pine.editor.title', 'Pine 腳本編輯器');\n summary.style.cssText =\n 'cursor:pointer;color:#58a6ff;user-select:none;padding:6px 12px;font-size:12px;flex-shrink:0;';\n\n const toolbar = document.createElement('div');\n toolbar.style.cssText =\n 'display:flex;align-items:center;gap:8px;padding:0 12px 6px;flex-shrink:0;';\n\n const status = document.createElement('span');\n status.style.cssText = 'font-size:11px;color:#8b949e;flex:1;';\n status.textContent = t('pine.status.idle', '就緒');\n\n const applyBtn = document.createElement('button');\n applyBtn.type = 'button';\n applyBtn.textContent = t('pine.apply', '套用至圖表');\n applyBtn.style.cssText =\n 'padding:4px 10px;background:#238636;color:#fff;border:1px solid #2ea043;border-radius:4px;cursor:pointer;font-size:11px;';\n\n const host = document.createElement('div');\n host.style.cssText = 'flex:1;min-height:120px;max-height:160px;overflow:hidden;border-top:1px solid #30363d;';\n\n toolbar.append(status, applyBtn);\n wrap.append(summary, toolbar, host);\n parent.appendChild(wrap);\n\n let debounceTimer: ReturnType<typeof setTimeout> | null = null;\n const debounceMs = opts.debounceMs ?? 400;\n\n const runApply = (src: string) => {\n const r = compilePineLite(src);\n opts.onApply?.(src, r.ok);\n savePineScriptPreference(src);\n if (r.ok) {\n status.style.color = '#3fb950';\n status.textContent = t('pine.status.ok', '語法正確');\n } else {\n status.style.color = '#f85149';\n status.textContent = r.errors[0] ?? t('pine.status.error', '語法錯誤');\n }\n };\n\n const extensions: Extension[] = [\n lineNumbers(),\n highlightActiveLineGutter(),\n highlightActiveLine(),\n drawSelection(),\n bracketMatching(),\n history(),\n pineLanguage,\n syntaxHighlighting(defaultHighlightStyle, { fallback: true }),\n darkTheme,\n createPineLinter((msg, ok) => {\n status.style.color = ok ? '#8b949e' : '#f85149';\n status.textContent = msg;\n }),\n keymap.of([...defaultKeymap, ...historyKeymap]),\n placeholder(t('pine.placeholder', '// plot(sma(close, 20))')),\n EditorView.updateListener.of((u) => {\n if (!u.docChanged) return;\n if (debounceTimer) clearTimeout(debounceTimer);\n debounceTimer = setTimeout(() => runApply(u.state.doc.toString()), debounceMs);\n }),\n ];\n\n const state = EditorState.create({\n doc: opts.initialScript ?? '',\n extensions,\n });\n\n const view = new EditorView({ state, parent: host });\n\n applyBtn.onclick = () => runApply(view.state.doc.toString());\n\n return {\n el: wrap,\n getScript: () => view.state.doc.toString(),\n setScript: (script) => {\n view.dispatch({\n changes: { from: 0, to: view.state.doc.length, insert: script },\n });\n },\n applyNow: () => runApply(view.state.doc.toString()),\n destroy: () => {\n view.destroy();\n wrap.remove();\n },\n };\n}","import { StreamLanguage } from '@codemirror/language';\n\nexport const pineLanguage = StreamLanguage.define({\n name: 'pine-lite',\n startState: () => ({}),\n token(stream) {\n if (stream.eatSpace()) return null;\n if (stream.match(/\\/\\/.*/)) return 'comment';\n if (stream.match(/0x[\\da-fA-F]+|\\d+\\.?\\d*(?:[eE][+-]?\\d+)?/)) return 'number';\n if (stream.match(/\\b(?:var|plot|if|else|while|for|to|and|or|not|true|false)\\b/)) return 'keyword';\n if (stream.match(/\\b(?:sma|ema|rsi|close|open|high|low|volume|hl2|hlc3)\\b/)) return 'variableName';\n if (stream.match(/:=|==|!=|<=|>=|[+\\-*/<>=(){},]/)) return 'operator';\n if (stream.match(/[A-Za-z_]\\w*/)) return 'name';\n stream.next();\n return null;\n },\n});"],"mappings":"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","names":["t","t","t","fmt","t","clampPlacement","getLocale","setLocale","t","t","t","t","t","t","t","t","t","t"]}
|