diff --git a/dea/bode.py b/dea/bode.py index e888b25..dea37c1 100755 --- a/dea/bode.py +++ b/dea/bode.py @@ -1,26 +1,49 @@ import numpy as np +from fastapi import HTTPException from scipy import signal from .config import BODE_MAX_MULTIPLIER, BODE_POINTS -from .schemas import BodeParams +from .schemas import BodeCompareParams, BodeParams from .validation import require_finite, validate_coefficients -def calculate_bode_response(params: BodeParams): - fs_val = require_finite(params.fs, "fs") - b_vals = validate_coefficients(params.b, "b") - a_vals = validate_coefficients(params.a, "a") - f_min = params.fs / 50000.0 - f_max = params.fs * BODE_MAX_MULTIPLIER - f_eval = np.logspace(np.log10(f_min), np.log10(f_max), BODE_POINTS) - +def _bode_series(b_values, a_values, f_eval, fs_val): + b_vals = validate_coefficients(b_values, "b") + a_vals = validate_coefficients(a_values, "a") _, h = signal.freqz(b_vals, a_vals, worN=f_eval, fs=fs_val) - mag = 20 * np.log10(np.abs(h) + 1e-12) - phase = np.angle(h, deg=True) - return { - "freq": f_eval.tolist(), - "mag": mag.tolist(), - "phase": phase.tolist(), + "mag": (20 * np.log10(np.abs(h) + 1e-12)).tolist(), + "phase": np.angle(h, deg=True).tolist(), } + +def _frequency_axis(fs): + fs_val = require_finite(fs, "fs") + f_min = fs_val / 50000.0 + f_max = fs_val * BODE_MAX_MULTIPLIER + return fs_val, np.logspace(np.log10(f_min), np.log10(f_max), BODE_POINTS) + + +def calculate_bode_response(params: BodeParams): + fs_val, f_eval = _frequency_axis(params.fs) + series = _bode_series(params.b, params.a, f_eval, fs_val) + return { + "freq": f_eval.tolist(), + "mag": series["mag"], + "phase": series["phase"], + } + + +def calculate_bode_compare_response(params: BodeCompareParams): + fs_val, f_eval = _frequency_axis(params.ideal.fs) + fixed_fs_val = require_finite(params.fixed.fs, "fixed.fs") + if not np.isclose(fixed_fs_val, fs_val): + raise HTTPException(status_code=400, detail="ideal 與 fixed 的 fs 必須相同") + + ideal = _bode_series(params.ideal.b, params.ideal.a, f_eval, fs_val) + fixed = _bode_series(params.fixed.b, params.fixed.a, f_eval, fs_val) + return { + "freq": f_eval.tolist(), + "ideal": ideal, + "fixed": fixed, + } diff --git a/dea/schemas.py b/dea/schemas.py index 5977015..61e2ba2 100755 --- a/dea/schemas.py +++ b/dea/schemas.py @@ -38,3 +38,7 @@ class BodeParams(BaseModel): a: List[float] = Field(min_length=1, max_length=MAX_COEFFICIENTS) fs: float = Field(gt=0) + +class BodeCompareParams(BaseModel): + ideal: BodeParams + fixed: BodeParams diff --git a/dea_api.py b/dea_api.py index 560f733..0d5fabd 100755 --- a/dea_api.py +++ b/dea_api.py @@ -2,7 +2,7 @@ from fastapi import FastAPI, File, Form, HTTPException, Request, UploadFile from fastapi.responses import RedirectResponse, StreamingResponse from fastapi.staticfiles import StaticFiles -from dea.bode import calculate_bode_response +from dea.bode import calculate_bode_compare_response, calculate_bode_response from dea.config import ( BODE_MAX_MULTIPLIER, BODE_POINTS, @@ -19,7 +19,7 @@ from dea.csv_processing import ( read_csv_upload, ) from dea.filter_design import design_response -from dea.schemas import BodeParams, DesignParams +from dea.schemas import BodeCompareParams, BodeParams, DesignParams from dea.security import ( SECURITY_HEADERS, add_security_headers, @@ -75,6 +75,16 @@ def calculate_bode(params: BodeParams): raise HTTPException(status_code=400, detail=str(e)) +@app.post("/api/bode/compare") +def calculate_bode_compare(params: BodeCompareParams): + try: + return calculate_bode_compare_response(params) + except HTTPException: + raise + except Exception as e: + raise HTTPException(status_code=400, detail=str(e)) + + @app.post("/api/filter") async def filter_csv( file: UploadFile = File(...), diff --git a/src/App.vue b/src/App.vue index fd84c8e..c56c167 100644 --- a/src/App.vue +++ b/src/App.vue @@ -73,7 +73,7 @@ 濾波器設計 重設設計 + class="text-[10px] font-bold role-bg-secondary-soft role-border-secondary-soft role-text-secondary role-hover-secondary-soft border px-2 py-1 rounded transition-colors uppercase">重設設計 @@ -267,7 +267,7 @@ 濾波器係數設定 重設 + class="text-[10px] font-bold role-bg-secondary-soft role-border-secondary-soft role-text-secondary role-hover-secondary-soft border px-2 py-1 rounded transition-colors uppercase mr-1">重設 @@ -475,7 +475,7 @@ 重設 + class="text-[10px] font-bold role-bg-secondary-soft role-border-secondary-soft role-text-secondary role-hover-secondary-soft border px-2 py-1 rounded transition-colors uppercase mr-1">重設 diff --git a/src/app-options.js b/src/app-options.js old mode 100644 new mode 100755 index d2ffa3f..f74dc62 --- a/src/app-options.js +++ b/src/app-options.js @@ -1,1119 +1,1107 @@ -const DEFAULT_FILTER_TYPE = "Lowpass (低通)"; -const MANUAL_FILTER_TYPE = "(無) 手動自訂"; -const DEFAULT_FS = 100000.0; -const DEFAULT_B_STR = "0.5, 0.5, 0.0, 0.0"; -const DEFAULT_A_STR = "1.0, 0.0, 0.0, 0.0"; -const DEFAULT_SHIFT_BITS = 14; -const ZERO_7 = [0, 0, 0, 0, 0, 0, 0]; -const DEFAULT_PARAMS = { - fc: 1000.0, order: 1, - bp_f_low: 500.0, bp_f_high: 2000.0, bp_order: 1, - notch_f0: 120.0, notch_q: 1.0, - opoz_fz: 15000.0, opoz_fp: 10.0, - tp1z_fz: 200.0, tp1z_fp1: 10.0, tp1z_fp2: 5000.0, - tptz_fz1: 200.0, tptz_fz2: 25000.0, tptz_fp1: 10.0, tptz_fp2: 5000.0, - kp: 0.003, ki: 10.0, kd: 0.000016, - sogi_f0: 60.0, sogi_k: 1.414, -}; +const DEFAULT_FILTER_TYPE = "Lowpass (低通)"; +const MANUAL_FILTER_TYPE = "(無) 手動自訂"; +const DEFAULT_FS = 100000.0; +const DEFAULT_B_STR = "0.5, 0.5, 0.0, 0.0"; +const DEFAULT_A_STR = "1.0, 0.0, 0.0, 0.0"; +const DEFAULT_SHIFT_BITS = 14; +const ZERO_7 = [0, 0, 0, 0, 0, 0, 0]; +const DEFAULT_PARAMS = { + fc: 1000.0, order: 1, + bp_f_low: 500.0, bp_f_high: 2000.0, bp_order: 1, + notch_f0: 120.0, notch_q: 1.0, + opoz_fz: 15000.0, opoz_fp: 10.0, + tp1z_fz: 200.0, tp1z_fp1: 10.0, tp1z_fp2: 5000.0, + tptz_fz1: 200.0, tptz_fz2: 25000.0, tptz_fp1: 10.0, tptz_fp2: 5000.0, + kp: 0.003, ki: 10.0, kd: 0.000016, + sogi_f0: 60.0, sogi_k: 1.414, +}; + +const cloneDefaultParams = () => ({ ...DEFAULT_PARAMS }); +const zero7 = () => [...ZERO_7]; + +export default { + data() { + return { + fs: DEFAULT_FS, + b_str: DEFAULT_B_STR, + a_str: DEFAULT_A_STR, + filterType: DEFAULT_FILTER_TYPE, + filterOptions: [ + "Lowpass (低通)", "Highpass (高通)", "Bandpass (帶通)", + "Notch (陷波器)", "1P1Z (一極一零)", "2P1Z (二極一零)", "2P2Z (二極二零)", + "PID 控制器", "SOGI-Alpha (帶通)", "SOGI-Beta (低通)", "(無) 手動自訂" + ], + systemGain: 1.0, + params: cloneDefaultParams(), + // 模式切換 + isDarkMode: true, + // 係數倍率微調 + baseB: [0.5, 0.5, 0, 0, 0, 0, 0], + baseA: [1, 0, 0, 0, 0, 0, 0], + bSliders: zero7(), + aSliders: zero7(), // a1~a6 (index 0 unused for display but maps to a[1]~a[6]) + sense_b: '2x', sense_a: '2x', + + loadingBode: false, bodeTimeout: null, globalError: null, + csvFile: null, csvColumns: [], csvPreview: [], csvInfo: null, csvParseError: null, + selectedColumn: 0, loadingFilter: false, filterDone: false, timePlotData: null, + mobileTab: 'settings', // 手機版頁籤:'settings' | 'chart' + shiftBitsB: DEFAULT_SHIFT_BITS, + shiftBitsA: DEFAULT_SHIFT_BITS, + fixedOverrides: { a: {}, b: {} }, + outOfRangeB: [false, false, false, false, false, false, false], + outOfRangeA: [false, false, false, false, false, false, false], + aFineStep: 0.01, + aFineRepeatDelayTimer: null, + aFineRepeatTimer: null, + aFineDrag: null, + shiftBitRepeatDelayTimer: null, + shiftBitRepeatTimer: null, + shiftBitDrag: null, + fixedAFineStep: 1, + fixedAFineDrag: null, + fixedAFineRepeatDelayTimer: null, + fixedAFineRepeatTimer: null, + isTouchInput: false, + activeCoeffAdjustment: null, + } + }, + + computed: { + maxLogB() { + if (this.sense_b === '1%') return Math.log10(1.01); + if (this.sense_b === '2x') return Math.log10(2.0); + return 1.0; + }, + maxLogA() { + if (this.sense_a === '1%') return Math.log10(1.01); + if (this.sense_a === '2x') return Math.log10(2.0); + if (this.sense_a === '10x') return Math.log10(10.0); + return Math.log10(2.0); + }, + b_int_str: { + get() { + return this.fixedPointCoeffs.b.map(item => item.val).join(', '); + }, + set(val) { + const cleaned = val.replace(/[^0-9,\-\s]/g, ''); + const nums = this.parseCoeffs(cleaned); + nums.forEach((n, i) => { + this.fixedOverrides.b[i] = Math.round(n); + }); + this.debouncedUpdateBode(); + } + }, + a_int_str: { + get() { + return this.fixedPointCoeffs.a.map(item => item.val).join(', '); + }, + set(val) { + const cleaned = val.replace(/[^0-9,\-\s]/g, ''); + const nums = this.parseCoeffs(cleaned); + nums.forEach((n, i) => { + this.fixedOverrides.a[i] = Math.round(n); + }); + this.debouncedUpdateBode(); + } + }, + fixedPointCoeffs() { + const scaleB = Math.pow(2, this.shiftBitsB); + const scaleA = Math.pow(2, this.shiftBitsA); + const b_raw = this.parseCoeffs(this.b_str); + const a_raw = this.parseCoeffs(this.a_str); + + const b = b_raw.map((x, i) => { + const autoVal = Math.round(x * scaleB); + const val = (this.fixedOverrides.b[i] !== undefined) ? this.fixedOverrides.b[i] : autoVal; + return { label: `b${i}`, val, isOverridden: this.fixedOverrides.b[i] !== undefined }; + }); + const a = a_raw.map((x, i) => { + const autoVal = Math.round(x * scaleA); + const val = (this.fixedOverrides.a[i] !== undefined) ? this.fixedOverrides.a[i] : autoVal; + return { label: `a${i}`, val, isOverridden: this.fixedOverrides.a[i] !== undefined }; + }); + + return { b, a }; + }, + floatingCoeffs() { + const b = this.parseCoeffs(this.b_str).map((x, i) => ({ label: `b${i}`, val: parseFloat(x.toPrecision(6)) })); + const a = this.parseCoeffs(this.a_str).map((x, i) => ({ label: `a${i}`, val: parseFloat(x.toPrecision(6)) })); + return { b, a }; + }, + isManualDirty() { + if (this.bSliders.some(v => v !== 0) || this.aSliders.some(v => v !== 0)) return true; + const currentB = this.padTo7(this.parseCoeffs(this.b_str)); + const currentA = this.padTo7(this.parseCoeffs(this.a_str)); + const targetB = this.baseB.map(x => x * (this.systemGain || 1.0)); + const targetA = this.baseA; + + for (let i = 0; i < 7; i++) { + const bVal = currentB[i] || 0; + const bTarget = targetB[i] || 0; + // 使用相對誤差,避免數值較大時 (如 K > 10000) 產生的精確度誤判 + const epsB = Math.max(1e-8, Math.abs(bTarget) * 1e-10); + if (Math.abs(bVal - bTarget) > epsB) return true; + + const aVal = currentA[i] || 0; + const aTarget = targetA[i] || 0; + const epsA = Math.max(1e-8, Math.abs(aTarget) * 1e-10); + if (Math.abs(aVal - aTarget) > epsA) return true; + } + return false; + }, + isFixedPointDirty() { + return this.shiftBitsB !== DEFAULT_SHIFT_BITS + || this.shiftBitsA !== DEFAULT_SHIFT_BITS + || Object.keys(this.fixedOverrides.b).length > 0 + || Object.keys(this.fixedOverrides.a).length > 0; + }, + currentA1() { + const a = this.parseCoeffs(this.a_str); + return a[1] || 0; + }, + currentA2() { + const a = this.parseCoeffs(this.a_str); + return a[2] || 0; + }, + currentDelta() { + return (this.currentA1 + this.currentA2 + 1) / 2; + }, + currentR() { + return (this.currentA2 - this.currentA1 - 1) / 2; + }, + currentA1A2Diff() { + return this.currentA1 - this.currentA2; + }, + currentA1A2Sum() { + return this.currentA1 + this.currentA2; + }, + fixedA0Int() { + return Math.pow(2, this.shiftBitsA); + }, + fixedCurrentA1() { + return this.fixedPointCoeffs.a[1]?.val || 0; + }, + fixedCurrentA2() { + return this.fixedPointCoeffs.a[2]?.val || 0; + }, + fixedCurrentDelta() { + return (this.fixedCurrentA1 + this.fixedCurrentA2 + this.fixedA0Int) / 2; + }, + fixedCurrentR() { + return (this.fixedCurrentA2 - this.fixedCurrentA1 - this.fixedA0Int) / 2; + }, + fixedCurrentA1A2Diff() { + return this.fixedCurrentA1 - this.fixedCurrentA2; + }, + fixedCurrentA1A2Sum() { + return this.fixedCurrentA1 + this.fixedCurrentA2; + } + }, + mounted() { + this.isTouchInput = window.matchMedia?.('(pointer: coarse)').matches || false; + window.addEventListener('pointerdown', this.rememberPointerType); + + const savedTheme = localStorage.getItem('theme'); + this.isDarkMode = savedTheme ? savedTheme === 'dark' : true; + if (this.isDarkMode) { + document.documentElement.classList.add('dark'); + } else { + document.documentElement.classList.remove('dark'); + } + this.applyFilterDesign(); + }, + beforeUnmount() { + window.removeEventListener('pointerdown', this.rememberPointerType); + this.stopA1A2Repeat(); + this.stopAFineDrag(); + this.stopShiftBitRepeat(); + this.stopShiftBitDrag(); + this.stopFixedA1A2Repeat(); + this.stopFixedAFineDrag(); + }, + methods: { + rememberPointerType(event) { + if (event.pointerType === 'touch') { + this.isTouchInput = true; + } else if (event.pointerType === 'mouse' || event.pointerType === 'pen') { + this.isTouchInput = false; + } + }, + toggleDarkMode() { + this.isDarkMode = !this.isDarkMode; + localStorage.setItem('theme', this.isDarkMode ? 'dark' : 'light'); + if (this.isDarkMode) { + document.documentElement.classList.add('dark'); + } else { + document.documentElement.classList.remove('dark'); + } + this.updateBodePlot({ switchToChart: false }); + if (this.timePlotData) { + this.drawTimePlot(this.timePlotData); + } + }, + formatK(val) { + if (val >= 1000000) return `(~${(val / 1000000).toFixed(1).replace('.0', '')}M)`; + if (val >= 1000) return `(~${(val / 1000).toFixed(1).replace('.0', '')}k)`; + return ""; + }, + parseCoeffs(str) { + if (!str) return []; + // 支援逗號、空格、換行等分隔符號 + return str.split(/[,\s]+/).map(x => parseFloat(x.trim())).filter(x => !isNaN(x)); + }, + padTo7(arr) { + const r = arr.slice(0, 7); + while (r.length < 7) r.push(0); + return r; + }, + syncBaseFromText() { + const gain = this.systemGain || 1.0; + this.baseB = this.padTo7(this.parseCoeffs(this.b_str)).map(x => x / gain); + this.baseA = this.padTo7(this.parseCoeffs(this.a_str)); + this.baseA[0] = 1.0; + this.fixedOverrides = { a: {}, b: {} }; + this.bSliders = [0, 0, 0, 0, 0, 0, 0]; + this.aSliders = [0, 0, 0, 0, 0, 0, 0]; + this.outOfRangeB = [false, false, false, false, false, false, false]; + this.outOfRangeA = [false, false, false, false, false, false, false]; + }, + resetSlidersB() { + this.bSliders = [0, 0, 0, 0, 0, 0, 0]; + this.b_str = this.baseB.map(x => parseFloat(x.toPrecision(10))).join(', '); + this.debouncedUpdateBode(); + }, + resetSlidersA() { + this.aSliders = [0, 0, 0, 0, 0, 0]; + this.a_str = this.baseA.map(x => parseFloat(x.toPrecision(10))).join(', '); + this.debouncedUpdateBode(); + }, + clearManualAdjustments() { + this.bSliders = [0, 0, 0, 0, 0, 0, 0]; + this.aSliders = [0, 0, 0, 0, 0, 0, 0]; + const gain = this.systemGain || 1.0; + this.b_str = this.baseB.map(x => parseFloat((x * gain).toPrecision(10))).join(', '); + this.a_str = this.baseA.map(x => parseFloat(x.toPrecision(10))).join(', '); + this.activeCoeffAdjustment = null; + this.calcSlidersFromText(); + this.updateBodePlot({ switchToChart: false }); + }, + updateFromControls({ updateBode = true } = {}) { + const currentB = this.baseB.map((base, i) => base * (this.systemGain || 1.0) * Math.pow(10, this.bSliders[i] || 0)); + const currentA = [1.0]; + for (let i = 1; i < 7; i++) { + currentA.push(this.baseA[i] * Math.pow(10, this.aSliders[i] || 0)); + } + this.b_str = currentB.map(x => parseFloat(x.toPrecision(10))).join(', '); + this.a_str = currentA.map(x => parseFloat(x.toPrecision(10))).join(', '); + if (updateBode) this.debouncedUpdateBode(); + }, + stepDecimals(step) { + const text = String(step); + if (text.includes('e-')) return Number(text.split('e-')[1]); + return text.includes('.') ? text.split('.')[1].length : 0; + }, + roundToStep(value, step = this.aFineStep) { + const scale = 1 / step; + return Math.round(value * scale) / scale; + }, + formatFineCoeff(value) { + if (!Number.isFinite(value)) return '0'; + return Number(value).toString(); + }, + formatAFineDelta(step = this.aFineStep) { + return this.roundToStep(step, step).toFixed(this.stepDecimals(step)); + }, + formatFixedFineCoeff(value) { + if (!Number.isFinite(value)) return '0'; + return Number.isInteger(value) ? String(value) : String(value); + }, + formatFixedAFineDelta(step = this.fixedAFineStep) { + return String(step); + }, + adjustAFineStep(direction) { + const nextStep = this.aFineStep * (direction > 0 ? 0.1 : 10); + const clampedStep = Math.min(1, Math.max(1e-9, nextStep)); + this.aFineStep = Number(clampedStep.toPrecision(12)); + }, + adjustFixedAFineStep(direction) { + const nextStep = this.fixedAFineStep * (direction > 0 ? 0.1 : 10); + this.fixedAFineStep = Math.max(1, Math.min(1000000000, Math.round(nextStep))); + }, + setDeltaR(delta, r) { + const nextDelta = Number(delta); + const nextR = Number(r); + if (!Number.isFinite(nextDelta) || !Number.isFinite(nextR)) return; + this.setA1A2(-1 - nextR + nextDelta, nextR + nextDelta); + }, + setAFineDirect(target, rawValue) { + const nextValue = parseFloat(rawValue); + if (!Number.isFinite(nextValue)) return; + if (target === 'delta') { + this.setDeltaR(nextValue, this.currentR); + } else if (target === 'r') { + this.setDeltaR(this.currentDelta, nextValue); + } + }, + adjustAFineValue(target, steps) { + const delta = steps * this.aFineStep; + if (target === 'delta') { + this.setDeltaR(this.currentDelta + delta, this.currentR); + } else if (target === 'r') { + this.setDeltaR(this.currentDelta, this.currentR + delta); + } + }, + handleAFineWheel(target, event) { + if (!event.shiftKey) { + event.currentTarget?.blur?.(); + return; + } + event.preventDefault(); + const direction = event.deltaY < 0 ? 1 : -1; + const steps = Math.max(1, Math.round(Math.abs(event.deltaY) / 80)); + this.adjustAFineValue(target, direction * steps); + }, + startAFineDrag(target, event) { + if (event.pointerType !== 'touch') return; + event.preventDefault(); + this.aFineDrag = { target, lastY: event.clientY, remainder: 0 }; + window.addEventListener('pointermove', this.moveAFineDrag, { passive: false }); + window.addEventListener('pointerup', this.stopAFineDrag); + window.addEventListener('pointercancel', this.stopAFineDrag); + }, + moveAFineDrag(event) { + if (!this.aFineDrag) return; + event.preventDefault(); + const delta = this.aFineDrag.lastY - event.clientY; + this.aFineDrag.lastY = event.clientY; + this.aFineDrag.remainder += delta; + const steps = Math.trunc(this.aFineDrag.remainder / 18); + if (steps === 0) return; + this.aFineDrag.remainder -= steps * 18; + this.adjustAFineValue(this.aFineDrag.target, steps); + }, + stopAFineDrag() { + this.aFineDrag = null; + window.removeEventListener('pointermove', this.moveAFineDrag); + window.removeEventListener('pointerup', this.stopAFineDrag); + window.removeEventListener('pointercancel', this.stopAFineDrag); + }, + setFixedDeltaR(delta, r) { + const nextDelta = Number(delta); + const nextR = Number(r); + if (!Number.isFinite(nextDelta) || !Number.isFinite(nextR)) return; + this.fixedOverrides.a[1] = Math.round(-this.fixedA0Int - nextR + nextDelta); + this.fixedOverrides.a[2] = Math.round(nextR + nextDelta); + this.debouncedUpdateBode(); + }, + setFixedAFineDirect(target, rawValue) { + const nextValue = parseFloat(rawValue); + if (!Number.isFinite(nextValue)) return; + if (target === 'delta') { + this.setFixedDeltaR(nextValue, this.fixedCurrentR); + } else if (target === 'r') { + this.setFixedDeltaR(this.fixedCurrentDelta, nextValue); + } + }, + adjustFixedAFineValue(target, steps) { + const delta = steps * this.fixedAFineStep; + if (target === 'delta') { + this.setFixedDeltaR(this.fixedCurrentDelta + delta, this.fixedCurrentR); + } else if (target === 'r') { + this.setFixedDeltaR(this.fixedCurrentDelta, this.fixedCurrentR + delta); + } + }, + handleFixedAFineWheel(target, event) { + if (!event.shiftKey) { + event.currentTarget?.blur?.(); + return; + } + event.preventDefault(); + const direction = event.deltaY < 0 ? 1 : -1; + const steps = Math.max(1, Math.round(Math.abs(event.deltaY) / 80)); + this.adjustFixedAFineValue(target, direction * steps); + }, + startFixedA1A2Repeat(target, direction) { + this.stopFixedA1A2Repeat(); + this.adjustFixedAFineValue(target, direction); + this.fixedAFineRepeatDelayTimer = setTimeout(() => { + this.fixedAFineRepeatTimer = setInterval(() => { + this.adjustFixedAFineValue(target, direction); + }, 80); + }, 350); + }, + stopFixedA1A2Repeat() { + clearTimeout(this.fixedAFineRepeatDelayTimer); + clearInterval(this.fixedAFineRepeatTimer); + this.fixedAFineRepeatDelayTimer = null; + this.fixedAFineRepeatTimer = null; + }, + startFixedAFineDrag(target, event) { + if (event.pointerType !== 'touch') return; + event.preventDefault(); + this.fixedAFineDrag = { target, lastY: event.clientY, remainder: 0 }; + window.addEventListener('pointermove', this.moveFixedAFineDrag, { passive: false }); + window.addEventListener('pointerup', this.stopFixedAFineDrag); + window.addEventListener('pointercancel', this.stopFixedAFineDrag); + }, + moveFixedAFineDrag(event) { + if (!this.fixedAFineDrag) return; + event.preventDefault(); + const delta = this.fixedAFineDrag.lastY - event.clientY; + this.fixedAFineDrag.lastY = event.clientY; + this.fixedAFineDrag.remainder += delta; + const steps = Math.trunc(this.fixedAFineDrag.remainder / 18); + if (steps === 0) return; + this.fixedAFineDrag.remainder -= steps * 18; + this.adjustFixedAFineValue(this.fixedAFineDrag.target, steps); + }, + stopFixedAFineDrag() { + this.fixedAFineDrag = null; + window.removeEventListener('pointermove', this.moveFixedAFineDrag); + window.removeEventListener('pointerup', this.stopFixedAFineDrag); + window.removeEventListener('pointercancel', this.stopFixedAFineDrag); + }, + normalizeShiftBits(rawValue) { + const nextValue = parseInt(rawValue, 10); + if (!Number.isFinite(nextValue)) return 0; + return Math.max(0, nextValue); + }, + setShiftBits(type, rawValue) { + const nextValue = this.normalizeShiftBits(rawValue); + if (type === 'b') { + this.shiftBitsB = nextValue; + } else { + this.shiftBitsA = nextValue; + } + this.clearFixedOverrides(type); + this.debouncedUpdateBode(); + }, + adjustShiftBits(type, steps) { + const current = type === 'b' ? this.shiftBitsB : this.shiftBitsA; + this.setShiftBits(type, current + steps); + }, + handleShiftBitWheel(type, event) { + if (!event.shiftKey) { + event.currentTarget?.blur?.(); + return; + } + event.preventDefault(); + const direction = event.deltaY < 0 ? 1 : -1; + const steps = Math.max(1, Math.round(Math.abs(event.deltaY) / 80)); + this.adjustShiftBits(type, direction * steps); + }, + startShiftBitRepeat(type, direction) { + this.stopShiftBitRepeat(); + this.adjustShiftBits(type, direction); + this.shiftBitRepeatDelayTimer = setTimeout(() => { + this.shiftBitRepeatTimer = setInterval(() => { + this.adjustShiftBits(type, direction); + }, 80); + }, 350); + }, + stopShiftBitRepeat() { + clearTimeout(this.shiftBitRepeatDelayTimer); + clearInterval(this.shiftBitRepeatTimer); + this.shiftBitRepeatDelayTimer = null; + this.shiftBitRepeatTimer = null; + }, + startShiftBitDrag(type, event) { + if (event.pointerType !== 'touch') return; + event.preventDefault(); + this.shiftBitDrag = { type, lastY: event.clientY, remainder: 0 }; + window.addEventListener('pointermove', this.moveShiftBitDrag, { passive: false }); + window.addEventListener('pointerup', this.stopShiftBitDrag); + window.addEventListener('pointercancel', this.stopShiftBitDrag); + }, + moveShiftBitDrag(event) { + if (!this.shiftBitDrag) return; + event.preventDefault(); + const delta = this.shiftBitDrag.lastY - event.clientY; + this.shiftBitDrag.lastY = event.clientY; + this.shiftBitDrag.remainder += delta; + const steps = Math.trunc(this.shiftBitDrag.remainder / 18); + if (steps === 0) return; + this.shiftBitDrag.remainder -= steps * 18; + this.adjustShiftBits(this.shiftBitDrag.type, steps); + }, + stopShiftBitDrag() { + this.shiftBitDrag = null; + window.removeEventListener('pointermove', this.moveShiftBitDrag); + window.removeEventListener('pointerup', this.stopShiftBitDrag); + window.removeEventListener('pointercancel', this.stopShiftBitDrag); + }, + setA1A2(a1, a2) { + const a = this.padTo7(this.parseCoeffs(this.a_str)); + a[0] = 1.0; + a[1] = Number(a1); + a[2] = Number(a2); + this.a_str = a.map(x => Number.isFinite(x) ? Number(x).toString() : '0').join(', '); + this.calcSlidersFromText(); + this.debouncedUpdateBode(); + }, + adjustA1A2(mode, direction) { + const step = this.aFineStep * direction; + + if (mode === 'delta') { + this.setDeltaR(this.currentDelta + step, this.currentR); + } else if (mode === 'r') { + this.setDeltaR(this.currentDelta, this.currentR + step); + } + }, + startA1A2Repeat(mode, direction) { + this.stopA1A2Repeat(); + this.adjustA1A2(mode, direction); + this.aFineRepeatDelayTimer = setTimeout(() => { + this.aFineRepeatTimer = setInterval(() => { + this.adjustA1A2(mode, direction); + }, 80); + }, 350); + }, + stopA1A2Repeat() { + clearTimeout(this.aFineRepeatDelayTimer); + clearInterval(this.aFineRepeatTimer); + this.aFineRepeatDelayTimer = null; + this.aFineRepeatTimer = null; + }, + toggleCoeffAdjustment(panel) { + if (this.activeCoeffAdjustment === panel) { + this.activeCoeffAdjustment = null; + return; + } + this.activeCoeffAdjustment = panel; + if (panel === 'a1a2') { + this.calcSlidersFromText(); + } + }, + calcSlidersFromText() { + const gain = this.systemGain || 1.0; + const currentB = this.parseCoeffs(this.b_str); + const currentA = this.parseCoeffs(this.a_str); + + // 計算 b 係數滑桿 + for (let i = 0; i < 7; i++) { + const val = currentB[i] || 0; + const base = this.baseB[i] || 0; + this.outOfRangeB[i] = false; + if (base !== 0 && val !== 0 && (val / (base * gain)) > 0) { + let logVal = Math.log10(val / (base * gain)); + if (Math.abs(logVal) < 1e-12) logVal = 0; // 消除浮點數微小誤差 + if (Math.abs(logVal) > this.maxLogB) this.outOfRangeB[i] = true; + this.bSliders[i] = Math.max(-this.maxLogB, Math.min(this.maxLogB, logVal)); + } else { + this.bSliders[i] = 0; + if (val !== 0 && base !== 0) this.outOfRangeB[i] = true; // 符號不同或極端 + } + } + // 計算 a 係數滑桿 (a0 恆為 1, 從 a1 開始) + for (let i = 1; i < 7; i++) { + const val = currentA[i] || 0; + const base = this.baseA[i] || 0; + this.outOfRangeA[i] = false; + if (base !== 0 && val !== 0 && (val / base) > 0) { + let logVal = Math.log10(val / base); + if (Math.abs(logVal) < 1e-12) logVal = 0; // 消除浮點數微小誤差 + if (Math.abs(logVal) > this.maxLogA) this.outOfRangeA[i] = true; + this.aSliders[i] = Math.max(-this.maxLogA, Math.min(this.maxLogA, logVal)); + } else { + this.aSliders[i] = 0; + if (val !== 0 && base !== 0) this.outOfRangeA[i] = true; + } + } + }, + debouncedUpdateFromText(type) { + if (type === 'b') this.b_str = this.b_str.replace(/[^0-9,.\-\s]/g, ''); + if (type === 'a') this.a_str = this.a_str.replace(/[^0-9,.\-\s]/g, ''); + + // 當文字改變時,反向計算滑桿位置 + this.calcSlidersFromText(); + this.debouncedUpdateBode(); + }, + onlyNumberKey(e, allowDot = true) { + // 允許的控制鍵 + const allowedKeys = ['Backspace', 'Delete', 'ArrowLeft', 'ArrowRight', 'Tab', 'Enter', 'Home', 'End']; + if (allowedKeys.includes(e.key) || e.ctrlKey || e.metaKey) return; + + // 檢查字元是否合法 + const charRegex = allowDot ? /[0-9,.\-\s]/ : /[0-9,\-\s]/; + if (!charRegex.test(e.key)) { + e.preventDefault(); + } + }, + clearFixedOverrides(type = null) { + if (type === 'a' || type === 'b') { + this.fixedOverrides[type] = {}; + return; + } + this.fixedOverrides = { a: {}, b: {} }; + }, + resetFixedPointSettings() { + this.shiftBitsB = DEFAULT_SHIFT_BITS; + this.shiftBitsA = DEFAULT_SHIFT_BITS; + this.fixedAFineStep = 1; + this.clearFixedOverrides(); + this.updateBodePlot({ switchToChart: false }); + }, + debouncedApply() { + clearTimeout(this.bodeTimeout); + this.bodeTimeout = setTimeout(() => { + if (this.filterType !== MANUAL_FILTER_TYPE) this.applyFilterDesign(); + else this.updateBodePlot({ switchToChart: false }); + }, 300); + }, + debouncedUpdateBode() { + clearTimeout(this.bodeTimeout); + this.bodeTimeout = setTimeout(() => this.updateBodePlot({ switchToChart: false }), 150); + }, + onGainChange() { + this.updateFromControls(); + }, + onFilterTypeChange() { + this.systemGain = 1.0; + // 這裡可以選擇是否重設所有設計參數 (fc, Q 等) + // 根據使用者要求「載入預設值」,我們呼叫重設邏輯 + this.clearFixedOverrides(); + this.bSliders = zero7(); + this.aSliders = zero7(); + this.outOfRangeB = [false, false, false, false, false, false, false]; + this.outOfRangeA = [false, false, false, false, false, false, false]; + this.activeCoeffAdjustment = null; + if (this.filterType !== MANUAL_FILTER_TYPE) { + this.params = cloneDefaultParams(); + } + this.applyFilterDesign(); + }, + resetFilterParams() { + clearTimeout(this.bodeTimeout); + this.fs = DEFAULT_FS; + this.filterType = DEFAULT_FILTER_TYPE; + this.systemGain = 1.0; + this.params = cloneDefaultParams(); + this.b_str = DEFAULT_B_STR; + this.a_str = DEFAULT_A_STR; + this.baseB = this.padTo7(this.parseCoeffs(DEFAULT_B_STR)); + this.baseA = this.padTo7(this.parseCoeffs(DEFAULT_A_STR)); + this.clearFixedOverrides(); + this.bSliders = zero7(); + this.aSliders = zero7(); + this.outOfRangeB = [false, false, false, false, false, false, false]; + this.outOfRangeA = [false, false, false, false, false, false, false]; + this.sense_b = '2x'; + this.sense_a = '2x'; + this.shiftBitsB = DEFAULT_SHIFT_BITS; + this.shiftBitsA = DEFAULT_SHIFT_BITS; + this.aFineStep = 0.01; + this.fixedAFineStep = 1; + this.stopA1A2Repeat(); + this.stopAFineDrag(); + this.stopFixedA1A2Repeat(); + this.stopFixedAFineDrag(); + this.stopShiftBitRepeat(); + this.stopShiftBitDrag(); + this.activeCoeffAdjustment = null; + this.globalError = null; + this.applyFilterDesign(); + }, + async applyFilterDesign() { + if (this.filterType === MANUAL_FILTER_TYPE) return; + this.globalError = null; + try { + const payload = { + filter_type: this.filterType, fs: this.fs, + lp_fc: this.params.fc, lp_order: this.params.order, + hp_fc: this.params.fc, hp_order: this.params.order, + bp_f_low: this.params.bp_f_low, bp_f_high: this.params.bp_f_high, bp_order: this.params.bp_order, + notch_f0: this.params.notch_f0, notch_q: this.params.notch_q, + opoz_fz: this.params.opoz_fz, opoz_fp: this.params.opoz_fp, + tp1z_fz: this.params.tp1z_fz, tp1z_fp1: this.params.tp1z_fp1, tp1z_fp2: this.params.tp1z_fp2, + tptz_fz1: this.params.tptz_fz1, tptz_fz2: this.params.tptz_fz2, + tptz_fp1: this.params.tptz_fp1, tptz_fp2: this.params.tptz_fp2, + pid_kp: this.params.kp, pid_ki: this.params.ki, pid_kd: this.params.kd, + sogi_f0: this.params.sogi_f0, sogi_k: this.params.sogi_k + }; + const res = await fetch('/api/design', { + method: 'POST', headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify(payload) + }); + if (!res.ok) { const err = await res.json(); throw new Error(err.detail || '設計濾波器失敗'); } + const data = await res.json(); + // 1. 將後端傳回的單位增益係數存入 baseB + this.baseB = this.padTo7(data.b); + this.baseA = this.padTo7(data.a); + this.baseA[0] = 1.0; + + // 2. 重新計算含增益的文字框顯示與滑桿位置 + this.bSliders = [0, 0, 0, 0, 0, 0, 0]; + this.aSliders = [0, 0, 0, 0, 0, 0, 0]; + this.activeCoeffAdjustment = null; + this.updateFromControls({ updateBode: false }); + + // 3. 更新圖表 + await this.updateBodePlot({ switchToChart: false }); + } catch (e) { this.globalError = e.message; } + }, + async updateBodePlot({ switchToChart = true } = {}) { + this.loadingBode = true; + this.globalError = null; + try { + let b_ideal = this.parseCoeffs(this.b_str); + let a_ideal = this.parseCoeffs(this.a_str); + if (b_ideal.length === 0) b_ideal = [1.0]; + if (a_ideal.length === 0) a_ideal = [1.0]; + + const scaleB = Math.pow(2, this.shiftBitsB); + const scaleA = Math.pow(2, this.shiftBitsA); + const b_fixed = b_ideal.map((x, i) => { + const intVal = (this.fixedOverrides.b[i] !== undefined) ? this.fixedOverrides.b[i] : Math.round(x * scaleB); + return intVal / scaleB; + }); + const a_fixed = a_ideal.map((x, i) => { + const intVal = (this.fixedOverrides.a[i] !== undefined) ? this.fixedOverrides.a[i] : Math.round(x * scaleA); + return intVal / scaleA; + }); + + const res = await fetch('/api/bode/compare', { + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify({ + ideal: { b: b_ideal, a: a_ideal, fs: this.fs }, + fixed: { b: b_fixed, a: a_fixed, fs: this.fs } + }) + }); + + let data; + if (res.status === 404) { + const [resIdeal, resFixed] = await Promise.all([ + fetch('/api/bode', { + method: 'POST', headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify({ b: b_ideal, a: a_ideal, fs: this.fs }) + }), + fetch('/api/bode', { + method: 'POST', headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify({ b: b_fixed, a: a_fixed, fs: this.fs }) + }) + ]); + + if (!resIdeal.ok || !resFixed.ok) throw new Error('無法計算頻率響應'); + const dataIdeal = await resIdeal.json(); + const dataFixed = await resFixed.json(); + data = { + freq: dataIdeal.freq, + ideal: { mag: dataIdeal.mag, phase: dataIdeal.phase }, + fixed: { mag: dataFixed.mag, phase: dataFixed.phase } + }; + } else if (!res.ok) { + const err = await res.json(); + throw new Error(err.detail || '無法計算頻率響應'); + } else { + data = await res.json(); + } + + this.drawBodePlot(data.freq, data.ideal.mag, data.ideal.phase, data.fixed.mag, data.fixed.phase); + // 手機版:計算完成後自動切換到圖表頁籤 + if (switchToChart && window.innerWidth < 1024) this.mobileTab = 'chart'; + } catch (e) { this.globalError = e.message; } + finally { this.loadingBode = false; } + }, + drawBodePlot(freq, magIdeal, phaseIdeal, magFixed, phaseFixed) { + const fs = this.fs; + const fMin = freq[0], fMax = freq[freq.length - 1]; + const isDark = this.isDarkMode; + const isSmallScreen = window.innerWidth < 768; + + // 產生 1-2-5 刻度 + const xTicks = [], xTexts = []; + const pStart = Math.floor(Math.log10(fMin)); + const pEnd = Math.ceil(Math.log10(fMax)); + for (let p = pStart; p <= pEnd; p++) { + for (const m of [1, 2, 5]) { + const val = m * Math.pow(10, p); + if (val < fMin || val > fMax) continue; + xTicks.push(val); + if (val < 1) xTexts.push(val.toPrecision(3)); + else if (val < 1000) xTexts.push(String(val)); + else if (val < 1000000) xTexts.push((val / 1000) + 'k'); + else xTexts.push((val / 1000000) + 'M'); + } + } + + // Nyquist & fs 標線 (shapes) + const shapes = []; + const annotations = []; + const addVLine = (xVal, text, row) => { + const yref = row === 1 ? 'y' : 'y2'; + shapes.push({ + type: 'line', x0: xVal, x1: xVal, y0: 0, y1: 1, + xref: row === 1 ? 'x' : 'x2', yref: yref + ' domain', + line: { color: isDark ? 'rgba(242,184,181,0.72)' : 'rgba(179,38,30,0.68)', width: 1.4, dash: 'dash' } + }); + if (text) { + annotations.push({ + x: Math.log10(xVal), y: 1, text: text, + xref: row === 1 ? 'x' : 'x2', yref: yref + ' domain', + showarrow: false, font: { color: isDark ? '#f2b8b5' : '#b3261e', size: isSmallScreen ? 10 : 12 }, + yshift: isSmallScreen ? 15 : 12, + xanchor: 'center', + yanchor: isSmallScreen ? 'middle' : 'bottom', + textangle: isSmallScreen ? -90 : 0 + }); + } + }; + addVLine(fs / 2, 'Nyquist', 1); + addVLine(fs, 'fs', 1); + addVLine(fs / 2, null, 2); + addVLine(fs, null, 2); + + // 10 的倍數強化線 + for (let p = pStart; p <= pEnd; p++) { + const v = Math.pow(10, p); + if (v >= fMin && v <= fMax) { + const gridColor = isDark ? 'rgba(200,206,224,0.24)' : 'rgba(86,96,117,0.16)'; + shapes.push( + { type: 'line', x0: v, x1: v, y0: 0, y1: 1, xref: 'x', yref: 'y domain', line: { color: gridColor, width: 1.5 } }, + { type: 'line', x0: v, x1: v, y0: 0, y1: 1, xref: 'x2', yref: 'y2 domain', line: { color: gridColor, width: 1.5 } } + ); + } + } + + const gridColor = isDark ? 'rgba(200,206,224,0.14)' : 'rgba(86,96,117,0.09)'; + const zeroLineColor = isDark ? 'rgba(200,206,224,0.24)' : 'rgba(82,86,99,0.20)'; + const textColor = isDark ? '#b4b4bd' : '#525663'; + const titleColor = isDark ? '#f1f1f4' : '#17191f'; + const plotBgColor = isDark ? '#090a0d' : '#ffffff'; + + const xAxisCommon = { + type: 'log', title: { text: 'Freq (Hz)', font: { size: isSmallScreen ? 12 : 14 } }, + range: [Math.log10(fMin), Math.log10(fMax)], + tickvals: xTicks, ticktext: xTexts, + showgrid: true, gridcolor: gridColor, + tickfont: { color: textColor, size: isSmallScreen ? 11 : 12 }, + nticks: isSmallScreen ? 6 : 10 + }; + + const layout = { + paper_bgcolor: plotBgColor, plot_bgcolor: plotBgColor, + margin: isSmallScreen ? { t: 80, b: 120, l: 55, r: 15 } : { t: 70, b: 120, l: 70, r: 30 }, + showlegend: false, + grid: { rows: 2, columns: 1, pattern: 'independent', roworder: 'top to bottom', ygap: isSmallScreen ? 0.35 : 0.3 }, + font: { color: textColor, family: 'Google Sans, Roboto, sans-serif' }, + annotations: [ + { text: 'Magnitude Response (dB)', xref: 'x domain', yref: 'y domain', x: 0.5, y: isSmallScreen ? 1.25 : 1.15, showarrow: false, font: { size: isSmallScreen ? 14 : 16, color: titleColor, weight: 'normal' } }, + { text: 'Phase Response (Deg)', xref: 'x2 domain', yref: 'y2 domain', x: 0.5, y: isSmallScreen ? 1.25 : 1.15, showarrow: false, font: { size: isSmallScreen ? 14 : 16, color: titleColor, weight: 'normal' } }, + + // 手動 Magnitude 圖例 (位於上方圖表下方) + { xref: 'paper', yref: 'paper', x: 0.35, y: isSmallScreen ? 0.52 : 0.54, text: '一一一', font: { color: isDark ? '#c8cee0' : '#566075', size: 10 }, showarrow: false }, + { xref: 'paper', yref: 'paper', x: 0.42, y: isSmallScreen ? 0.52 : 0.54, text: 'Ideal (Float)', font: { color: textColor, size: 11 }, showarrow: false, xanchor: 'left' }, + { xref: 'paper', yref: 'paper', x: 0.58, y: isSmallScreen ? 0.52 : 0.54, text: '· · · ·', font: { color: isDark ? '#b9b2ff' : '#7a6689', size: 14 }, showarrow: false }, + { xref: 'paper', yref: 'paper', x: 0.63, y: isSmallScreen ? 0.52 : 0.54, text: `Fixed (b Q${this.shiftBitsB}, a Q${this.shiftBitsA})`, font: { color: textColor, size: 11 }, showarrow: false, xanchor: 'left' }, + + // 手動 Phase 圖例 (位於下方圖表下方) + { xref: 'paper', yref: 'paper', x: 0.35, y: -0.15, text: '一一一', font: { color: isDark ? '#64d2ff' : '#2d6f8f', size: 10 }, showarrow: false }, + { xref: 'paper', yref: 'paper', x: 0.42, y: -0.15, text: 'Ideal Phase', font: { color: textColor, size: 11 }, showarrow: false, xanchor: 'left' }, + { xref: 'paper', yref: 'paper', x: 0.58, y: -0.15, text: '· · · ·', font: { color: isDark ? '#ff9bd8' : '#96527b', size: 14 }, showarrow: false }, + { xref: 'paper', yref: 'paper', x: 0.63, y: -0.15, text: 'Fixed Phase', font: { color: textColor, size: 11 }, showarrow: false, xanchor: 'left' }, + + ...annotations + ], + xaxis: { ...xAxisCommon }, + yaxis: { title: { text: 'Mag (dB)', font: { size: isSmallScreen ? 12 : 14 } }, range: [-60, 0], gridcolor: gridColor, zerolinecolor: zeroLineColor, tickfont: { color: textColor, size: isSmallScreen ? 11 : 12 } }, + xaxis2: { ...xAxisCommon }, + yaxis2: { title: { text: 'Phase (°)', font: { size: isSmallScreen ? 12 : 14 } }, range: [-180, 180], tickvals: [-180, -90, 0, 90, 180], gridcolor: gridColor, zerolinecolor: zeroLineColor, tickfont: { color: textColor, size: isSmallScreen ? 11 : 12 } }, + shapes: shapes + }; + + const traceMagIdeal = { x: freq, y: magIdeal, name: 'Ideal (Float)', type: 'scatter', line: { color: isDark ? '#c8cee0' : '#566075', width: 2.8 } }; + const traceMagFixed = { x: freq, y: magFixed, name: `Fixed (b Q${this.shiftBitsB}, a Q${this.shiftBitsA})`, type: 'scatter', line: { color: isDark ? '#b9b2ff' : '#7a6689', width: 2.4, dash: 'dot' } }; -const cloneDefaultParams = () => ({ ...DEFAULT_PARAMS }); -const zero7 = () => [...ZERO_7]; - -export default { - data() { - return { - fs: DEFAULT_FS, - b_str: DEFAULT_B_STR, - a_str: DEFAULT_A_STR, - filterType: DEFAULT_FILTER_TYPE, - filterOptions: [ - "Lowpass (低通)", "Highpass (高通)", "Bandpass (帶通)", - "Notch (陷波器)", "1P1Z (一極一零)", "2P1Z (二極一零)", "2P2Z (二極二零)", - "PID 控制器", "SOGI-Alpha (帶通)", "SOGI-Beta (低通)", "(無) 手動自訂" - ], - systemGain: 1.0, - params: cloneDefaultParams(), - // 模式切換 - isDarkMode: false, - // 係數倍率微調 - baseB: [0.5, 0.5, 0, 0, 0, 0, 0], - baseA: [1, 0, 0, 0, 0, 0, 0], - bSliders: zero7(), - aSliders: zero7(), // a1~a6 (index 0 unused for display but maps to a[1]~a[6]) - sense_b: '2x', sense_a: '2x', - - loadingBode: false, bodeTimeout: null, globalError: null, - csvFile: null, csvColumns: [], csvPreview: [], csvInfo: null, csvParseError: null, - selectedColumn: 0, loadingFilter: false, filterDone: false, timePlotData: null, - mobileTab: 'settings', // 手機版頁籤:'settings' | 'chart' - shiftBitsB: DEFAULT_SHIFT_BITS, - shiftBitsA: DEFAULT_SHIFT_BITS, - fixedOverrides: { a: {}, b: {} }, - outOfRangeB: [false, false, false, false, false, false, false], - outOfRangeA: [false, false, false, false, false, false, false], - aFineStep: 0.01, - aFineRepeatDelayTimer: null, - aFineRepeatTimer: null, - aFineDrag: null, - shiftBitRepeatDelayTimer: null, - shiftBitRepeatTimer: null, - shiftBitDrag: null, - fixedAFineStep: 1, - fixedAFineDrag: null, - fixedAFineRepeatDelayTimer: null, - fixedAFineRepeatTimer: null, - isTouchInput: false, - showAdvancedAdjustment: false, - activeCoeffAdjustment: null, - } - }, - - computed: { - maxLogB() { - if (this.sense_b === '1%') return Math.log10(1.01); - if (this.sense_b === '2x') return Math.log10(2.0); - return 1.0; - }, - maxLogA() { - if (this.sense_a === '1%') return Math.log10(1.01); - if (this.sense_a === '2x') return Math.log10(2.0); - if (this.sense_a === '10x') return Math.log10(10.0); - return Math.log10(2.0); - }, - b_int_str: { - get() { - return this.fixedPointCoeffs.b.map(item => item.val).join(', '); - }, - set(val) { - const cleaned = val.replace(/[^0-9,\-\s]/g, ''); - const nums = this.parseCoeffs(cleaned); - nums.forEach((n, i) => { - this.fixedOverrides.b[i] = Math.round(n); - }); - this.debouncedUpdateBode(); - } - }, - a_int_str: { - get() { - return this.fixedPointCoeffs.a.map(item => item.val).join(', '); - }, - set(val) { - const cleaned = val.replace(/[^0-9,\-\s]/g, ''); - const nums = this.parseCoeffs(cleaned); - nums.forEach((n, i) => { - this.fixedOverrides.a[i] = Math.round(n); - }); - this.debouncedUpdateBode(); - } - }, - fixedPointCoeffs() { - const scaleB = Math.pow(2, this.shiftBitsB); - const scaleA = Math.pow(2, this.shiftBitsA); - const b_raw = this.parseCoeffs(this.b_str); - const a_raw = this.parseCoeffs(this.a_str); - - const b = b_raw.map((x, i) => { - const autoVal = Math.round(x * scaleB); - const val = (this.fixedOverrides.b[i] !== undefined) ? this.fixedOverrides.b[i] : autoVal; - return { label: `b${i}`, val, isOverridden: this.fixedOverrides.b[i] !== undefined }; - }); - const a = a_raw.map((x, i) => { - const autoVal = Math.round(x * scaleA); - const val = (this.fixedOverrides.a[i] !== undefined) ? this.fixedOverrides.a[i] : autoVal; - return { label: `a${i}`, val, isOverridden: this.fixedOverrides.a[i] !== undefined }; - }); - - return { b, a }; - }, - floatingCoeffs() { - const b = this.parseCoeffs(this.b_str).map((x, i) => ({ label: `b${i}`, val: parseFloat(x.toPrecision(6)) })); - const a = this.parseCoeffs(this.a_str).map((x, i) => ({ label: `a${i}`, val: parseFloat(x.toPrecision(6)) })); - return { b, a }; - }, - isManualDirty() { - if (this.bSliders.some(v => v !== 0) || this.aSliders.some(v => v !== 0)) return true; - const currentB = this.padTo7(this.parseCoeffs(this.b_str)); - const currentA = this.padTo7(this.parseCoeffs(this.a_str)); - const targetB = this.baseB.map(x => x * (this.systemGain || 1.0)); - const targetA = this.baseA; - - for (let i = 0; i < 7; i++) { - const bVal = currentB[i] || 0; - const bTarget = targetB[i] || 0; - // 使用相對誤差,避免數值較大時 (如 K > 10000) 產生的精確度誤判 - const epsB = Math.max(1e-8, Math.abs(bTarget) * 1e-10); - if (Math.abs(bVal - bTarget) > epsB) return true; - - const aVal = currentA[i] || 0; - const aTarget = targetA[i] || 0; - const epsA = Math.max(1e-8, Math.abs(aTarget) * 1e-10); - if (Math.abs(aVal - aTarget) > epsA) return true; - } - return false; - }, - isFixedPointDirty() { - return this.shiftBitsB !== DEFAULT_SHIFT_BITS - || this.shiftBitsA !== DEFAULT_SHIFT_BITS - || Object.keys(this.fixedOverrides.b).length > 0 - || Object.keys(this.fixedOverrides.a).length > 0; - }, - currentA1() { - const a = this.parseCoeffs(this.a_str); - return a[1] || 0; - }, - currentA2() { - const a = this.parseCoeffs(this.a_str); - return a[2] || 0; - }, - currentDelta() { - return (this.currentA1 + this.currentA2 + 1) / 2; - }, - currentR() { - return (this.currentA2 - this.currentA1 - 1) / 2; - }, - currentA1A2Diff() { - return this.currentA1 - this.currentA2; - }, - currentA1A2Sum() { - return this.currentA1 + this.currentA2; - }, - fixedA0Int() { - return Math.pow(2, this.shiftBitsA); - }, - fixedCurrentA1() { - return this.fixedPointCoeffs.a[1]?.val || 0; - }, - fixedCurrentA2() { - return this.fixedPointCoeffs.a[2]?.val || 0; - }, - fixedCurrentDelta() { - return (this.fixedCurrentA1 + this.fixedCurrentA2 + this.fixedA0Int) / 2; - }, - fixedCurrentR() { - return (this.fixedCurrentA2 - this.fixedCurrentA1 - this.fixedA0Int) / 2; - }, - fixedCurrentA1A2Diff() { - return this.fixedCurrentA1 - this.fixedCurrentA2; - }, - fixedCurrentA1A2Sum() { - return this.fixedCurrentA1 + this.fixedCurrentA2; - } - }, - mounted() { - this.isTouchInput = window.matchMedia?.('(pointer: coarse)').matches || false; - window.addEventListener('pointerdown', this.rememberPointerType); - - const savedTheme = localStorage.getItem('theme'); - if (savedTheme) { - this.isDarkMode = savedTheme === 'dark'; - } - if (this.isDarkMode) { - document.documentElement.classList.add('dark'); - } else { - document.documentElement.classList.remove('dark'); - } - this.applyFilterDesign(); - }, - beforeUnmount() { - window.removeEventListener('pointerdown', this.rememberPointerType); - this.stopA1A2Repeat(); - this.stopAFineDrag(); - this.stopShiftBitRepeat(); - this.stopShiftBitDrag(); - this.stopFixedA1A2Repeat(); - this.stopFixedAFineDrag(); - }, - methods: { - rememberPointerType(event) { - if (event.pointerType === 'touch') { - this.isTouchInput = true; - } else if (event.pointerType === 'mouse' || event.pointerType === 'pen') { - this.isTouchInput = false; - } - }, - toggleDarkMode() { - this.isDarkMode = !this.isDarkMode; - localStorage.setItem('theme', this.isDarkMode ? 'dark' : 'light'); - if (this.isDarkMode) { - document.documentElement.classList.add('dark'); - } else { - document.documentElement.classList.remove('dark'); - } - this.updateBodePlot({ switchToChart: false }); - if (this.timePlotData) { - this.drawTimePlot(this.timePlotData); - } - }, - formatK(val) { - if (val >= 1000000) return `(~${(val / 1000000).toFixed(1).replace('.0', '')}M)`; - if (val >= 1000) return `(~${(val / 1000).toFixed(1).replace('.0', '')}k)`; - return ""; - }, - parseCoeffs(str) { - if (!str) return []; - // 支援逗號、空格、換行等分隔符號 - return str.split(/[,\s]+/).map(x => parseFloat(x.trim())).filter(x => !isNaN(x)); - }, - padTo7(arr) { - const r = arr.slice(0, 7); - while (r.length < 7) r.push(0); - return r; - }, - syncBaseFromText() { - const gain = this.systemGain || 1.0; - this.baseB = this.padTo7(this.parseCoeffs(this.b_str)).map(x => x / gain); - this.baseA = this.padTo7(this.parseCoeffs(this.a_str)); - this.baseA[0] = 1.0; - this.fixedOverrides = { a: {}, b: {} }; - this.bSliders = [0, 0, 0, 0, 0, 0, 0]; - this.aSliders = [0, 0, 0, 0, 0, 0, 0]; - this.outOfRangeB = [false, false, false, false, false, false, false]; - this.outOfRangeA = [false, false, false, false, false, false, false]; - }, - resetSlidersB() { - this.bSliders = [0, 0, 0, 0, 0, 0, 0]; - this.b_str = this.baseB.map(x => parseFloat(x.toPrecision(10))).join(', '); - this.debouncedUpdateBode(); - }, - resetSlidersA() { - this.aSliders = [0, 0, 0, 0, 0, 0]; - this.a_str = this.baseA.map(x => parseFloat(x.toPrecision(10))).join(', '); - this.debouncedUpdateBode(); - }, - clearManualAdjustments() { - this.bSliders = [0, 0, 0, 0, 0, 0, 0]; - this.aSliders = [0, 0, 0, 0, 0, 0, 0]; - const gain = this.systemGain || 1.0; - this.b_str = this.baseB.map(x => parseFloat((x * gain).toPrecision(10))).join(', '); - this.a_str = this.baseA.map(x => parseFloat(x.toPrecision(10))).join(', '); - this.showAdvancedAdjustment = false; - this.activeCoeffAdjustment = null; - this.calcSlidersFromText(); - this.updateBodePlot({ switchToChart: false }); - }, - updateFromControls() { - const currentB = this.baseB.map((base, i) => base * (this.systemGain || 1.0) * Math.pow(10, this.bSliders[i] || 0)); - const currentA = [1.0]; - for (let i = 1; i < 7; i++) { - currentA.push(this.baseA[i] * Math.pow(10, this.aSliders[i] || 0)); - } - this.b_str = currentB.map(x => parseFloat(x.toPrecision(10))).join(', '); - this.a_str = currentA.map(x => parseFloat(x.toPrecision(10))).join(', '); - this.debouncedUpdateBode(); - }, - updateFromText() { - // 不再呼叫 syncBaseFromText(),保留基礎設計 (baseB/baseA) 作為參考點 - // 只更新圖表,讓滑桿維持在相對應的偏差位置 - this.updateBodePlot({ switchToChart: false }); - }, - stepDecimals(step) { - const text = String(step); - if (text.includes('e-')) return Number(text.split('e-')[1]); - return text.includes('.') ? text.split('.')[1].length : 0; - }, - roundToStep(value, step = this.aFineStep) { - const scale = 1 / step; - return Math.round(value * scale) / scale; - }, - formatFineCoeff(value) { - if (!Number.isFinite(value)) return '0'; - return Number(value).toString(); - }, - formatAFineDelta(step = this.aFineStep) { - return this.roundToStep(step, step).toFixed(this.stepDecimals(step)); - }, - formatFixedFineCoeff(value) { - if (!Number.isFinite(value)) return '0'; - return Number.isInteger(value) ? String(value) : String(value); - }, - formatFixedAFineDelta(step = this.fixedAFineStep) { - return String(step); - }, - adjustAFineStep(direction) { - const nextStep = this.aFineStep * (direction > 0 ? 0.1 : 10); - const clampedStep = Math.min(1, Math.max(1e-9, nextStep)); - this.aFineStep = Number(clampedStep.toPrecision(12)); - }, - adjustFixedAFineStep(direction) { - const nextStep = this.fixedAFineStep * (direction > 0 ? 0.1 : 10); - this.fixedAFineStep = Math.max(1, Math.min(1000000000, Math.round(nextStep))); - }, - setDeltaR(delta, r) { - const nextDelta = Number(delta); - const nextR = Number(r); - if (!Number.isFinite(nextDelta) || !Number.isFinite(nextR)) return; - this.setA1A2(-1 - nextR + nextDelta, nextR + nextDelta); - }, - setAFineDirect(target, rawValue) { - const nextValue = parseFloat(rawValue); - if (!Number.isFinite(nextValue)) return; - if (target === 'delta') { - this.setDeltaR(nextValue, this.currentR); - } else if (target === 'r') { - this.setDeltaR(this.currentDelta, nextValue); - } - }, - adjustAFineValue(target, steps) { - const delta = steps * this.aFineStep; - if (target === 'delta') { - this.setDeltaR(this.currentDelta + delta, this.currentR); - } else if (target === 'r') { - this.setDeltaR(this.currentDelta, this.currentR + delta); - } - }, - handleAFineWheel(target, event) { - if (!event.shiftKey) { - event.currentTarget?.blur?.(); - return; - } - event.preventDefault(); - const direction = event.deltaY < 0 ? 1 : -1; - const steps = Math.max(1, Math.round(Math.abs(event.deltaY) / 80)); - this.adjustAFineValue(target, direction * steps); - }, - startAFineDrag(target, event) { - if (event.pointerType !== 'touch') return; - event.preventDefault(); - this.aFineDrag = { target, lastY: event.clientY, remainder: 0 }; - window.addEventListener('pointermove', this.moveAFineDrag, { passive: false }); - window.addEventListener('pointerup', this.stopAFineDrag); - window.addEventListener('pointercancel', this.stopAFineDrag); - }, - moveAFineDrag(event) { - if (!this.aFineDrag) return; - event.preventDefault(); - const delta = this.aFineDrag.lastY - event.clientY; - this.aFineDrag.lastY = event.clientY; - this.aFineDrag.remainder += delta; - const steps = Math.trunc(this.aFineDrag.remainder / 18); - if (steps === 0) return; - this.aFineDrag.remainder -= steps * 18; - this.adjustAFineValue(this.aFineDrag.target, steps); - }, - stopAFineDrag() { - this.aFineDrag = null; - window.removeEventListener('pointermove', this.moveAFineDrag); - window.removeEventListener('pointerup', this.stopAFineDrag); - window.removeEventListener('pointercancel', this.stopAFineDrag); - }, - setFixedDeltaR(delta, r) { - const nextDelta = Number(delta); - const nextR = Number(r); - if (!Number.isFinite(nextDelta) || !Number.isFinite(nextR)) return; - this.fixedOverrides.a[1] = Math.round(-this.fixedA0Int - nextR + nextDelta); - this.fixedOverrides.a[2] = Math.round(nextR + nextDelta); - this.debouncedUpdateBode(); - }, - setFixedAFineDirect(target, rawValue) { - const nextValue = parseFloat(rawValue); - if (!Number.isFinite(nextValue)) return; - if (target === 'delta') { - this.setFixedDeltaR(nextValue, this.fixedCurrentR); - } else if (target === 'r') { - this.setFixedDeltaR(this.fixedCurrentDelta, nextValue); - } - }, - adjustFixedAFineValue(target, steps) { - const delta = steps * this.fixedAFineStep; - if (target === 'delta') { - this.setFixedDeltaR(this.fixedCurrentDelta + delta, this.fixedCurrentR); - } else if (target === 'r') { - this.setFixedDeltaR(this.fixedCurrentDelta, this.fixedCurrentR + delta); - } - }, - handleFixedAFineWheel(target, event) { - if (!event.shiftKey) { - event.currentTarget?.blur?.(); - return; - } - event.preventDefault(); - const direction = event.deltaY < 0 ? 1 : -1; - const steps = Math.max(1, Math.round(Math.abs(event.deltaY) / 80)); - this.adjustFixedAFineValue(target, direction * steps); - }, - startFixedA1A2Repeat(target, direction) { - this.stopFixedA1A2Repeat(); - this.adjustFixedAFineValue(target, direction); - this.fixedAFineRepeatDelayTimer = setTimeout(() => { - this.fixedAFineRepeatTimer = setInterval(() => { - this.adjustFixedAFineValue(target, direction); - }, 80); - }, 350); - }, - stopFixedA1A2Repeat() { - clearTimeout(this.fixedAFineRepeatDelayTimer); - clearInterval(this.fixedAFineRepeatTimer); - this.fixedAFineRepeatDelayTimer = null; - this.fixedAFineRepeatTimer = null; - }, - startFixedAFineDrag(target, event) { - if (event.pointerType !== 'touch') return; - event.preventDefault(); - this.fixedAFineDrag = { target, lastY: event.clientY, remainder: 0 }; - window.addEventListener('pointermove', this.moveFixedAFineDrag, { passive: false }); - window.addEventListener('pointerup', this.stopFixedAFineDrag); - window.addEventListener('pointercancel', this.stopFixedAFineDrag); - }, - moveFixedAFineDrag(event) { - if (!this.fixedAFineDrag) return; - event.preventDefault(); - const delta = this.fixedAFineDrag.lastY - event.clientY; - this.fixedAFineDrag.lastY = event.clientY; - this.fixedAFineDrag.remainder += delta; - const steps = Math.trunc(this.fixedAFineDrag.remainder / 18); - if (steps === 0) return; - this.fixedAFineDrag.remainder -= steps * 18; - this.adjustFixedAFineValue(this.fixedAFineDrag.target, steps); - }, - stopFixedAFineDrag() { - this.fixedAFineDrag = null; - window.removeEventListener('pointermove', this.moveFixedAFineDrag); - window.removeEventListener('pointerup', this.stopFixedAFineDrag); - window.removeEventListener('pointercancel', this.stopFixedAFineDrag); - }, - normalizeShiftBits(rawValue) { - const nextValue = parseInt(rawValue, 10); - if (!Number.isFinite(nextValue)) return 0; - return Math.max(0, nextValue); - }, - setShiftBits(type, rawValue) { - const nextValue = this.normalizeShiftBits(rawValue); - if (type === 'b') { - this.shiftBitsB = nextValue; - } else { - this.shiftBitsA = nextValue; - } - this.clearFixedOverrides(type); - this.debouncedUpdateBode(); - }, - adjustShiftBits(type, steps) { - const current = type === 'b' ? this.shiftBitsB : this.shiftBitsA; - this.setShiftBits(type, current + steps); - }, - handleShiftBitWheel(type, event) { - if (!event.shiftKey) { - event.currentTarget?.blur?.(); - return; - } - event.preventDefault(); - const direction = event.deltaY < 0 ? 1 : -1; - const steps = Math.max(1, Math.round(Math.abs(event.deltaY) / 80)); - this.adjustShiftBits(type, direction * steps); - }, - startShiftBitRepeat(type, direction) { - this.stopShiftBitRepeat(); - this.adjustShiftBits(type, direction); - this.shiftBitRepeatDelayTimer = setTimeout(() => { - this.shiftBitRepeatTimer = setInterval(() => { - this.adjustShiftBits(type, direction); - }, 80); - }, 350); - }, - stopShiftBitRepeat() { - clearTimeout(this.shiftBitRepeatDelayTimer); - clearInterval(this.shiftBitRepeatTimer); - this.shiftBitRepeatDelayTimer = null; - this.shiftBitRepeatTimer = null; - }, - startShiftBitDrag(type, event) { - if (event.pointerType !== 'touch') return; - event.preventDefault(); - this.shiftBitDrag = { type, lastY: event.clientY, remainder: 0 }; - window.addEventListener('pointermove', this.moveShiftBitDrag, { passive: false }); - window.addEventListener('pointerup', this.stopShiftBitDrag); - window.addEventListener('pointercancel', this.stopShiftBitDrag); - }, - moveShiftBitDrag(event) { - if (!this.shiftBitDrag) return; - event.preventDefault(); - const delta = this.shiftBitDrag.lastY - event.clientY; - this.shiftBitDrag.lastY = event.clientY; - this.shiftBitDrag.remainder += delta; - const steps = Math.trunc(this.shiftBitDrag.remainder / 18); - if (steps === 0) return; - this.shiftBitDrag.remainder -= steps * 18; - this.adjustShiftBits(this.shiftBitDrag.type, steps); - }, - stopShiftBitDrag() { - this.shiftBitDrag = null; - window.removeEventListener('pointermove', this.moveShiftBitDrag); - window.removeEventListener('pointerup', this.stopShiftBitDrag); - window.removeEventListener('pointercancel', this.stopShiftBitDrag); - }, - setA1A2(a1, a2) { - const a = this.padTo7(this.parseCoeffs(this.a_str)); - a[0] = 1.0; - a[1] = Number(a1); - a[2] = Number(a2); - this.a_str = a.map(x => Number.isFinite(x) ? Number(x).toString() : '0').join(', '); - this.calcSlidersFromText(); - this.debouncedUpdateBode(); - }, - adjustA1A2(mode, direction) { - const step = this.aFineStep * direction; - - if (mode === 'delta') { - this.setDeltaR(this.currentDelta + step, this.currentR); - } else if (mode === 'r') { - this.setDeltaR(this.currentDelta, this.currentR + step); - } - }, - startA1A2Repeat(mode, direction) { - this.stopA1A2Repeat(); - this.adjustA1A2(mode, direction); - this.aFineRepeatDelayTimer = setTimeout(() => { - this.aFineRepeatTimer = setInterval(() => { - this.adjustA1A2(mode, direction); - }, 80); - }, 350); - }, - stopA1A2Repeat() { - clearTimeout(this.aFineRepeatDelayTimer); - clearInterval(this.aFineRepeatTimer); - this.aFineRepeatDelayTimer = null; - this.aFineRepeatTimer = null; - }, - enableAdvancedAdjustment() { - this.calcSlidersFromText(); - this.showAdvancedAdjustment = true; - this.activeCoeffAdjustment = 'a1a2'; - }, - toggleCoeffAdjustment(panel) { - if (this.activeCoeffAdjustment === panel) { - this.activeCoeffAdjustment = null; - this.showAdvancedAdjustment = false; - return; - } - this.activeCoeffAdjustment = panel; - this.showAdvancedAdjustment = panel === 'a1a2'; - if (panel === 'a1a2') { - this.calcSlidersFromText(); - } - }, - calcSlidersFromText() { - const gain = this.systemGain || 1.0; - const currentB = this.parseCoeffs(this.b_str); - const currentA = this.parseCoeffs(this.a_str); - - // 計算 b 係數滑桿 - for (let i = 0; i < 7; i++) { - const val = currentB[i] || 0; - const base = this.baseB[i] || 0; - this.outOfRangeB[i] = false; - if (base !== 0 && val !== 0 && (val / (base * gain)) > 0) { - let logVal = Math.log10(val / (base * gain)); - if (Math.abs(logVal) < 1e-12) logVal = 0; // 消除浮點數微小誤差 - if (Math.abs(logVal) > this.maxLogB) this.outOfRangeB[i] = true; - this.bSliders[i] = Math.max(-this.maxLogB, Math.min(this.maxLogB, logVal)); - } else { - this.bSliders[i] = 0; - if (val !== 0 && base !== 0) this.outOfRangeB[i] = true; // 符號不同或極端 - } - } - // 計算 a 係數滑桿 (a0 恆為 1, 從 a1 開始) - for (let i = 1; i < 7; i++) { - const val = currentA[i] || 0; - const base = this.baseA[i] || 0; - this.outOfRangeA[i] = false; - if (base !== 0 && val !== 0 && (val / base) > 0) { - let logVal = Math.log10(val / base); - if (Math.abs(logVal) < 1e-12) logVal = 0; // 消除浮點數微小誤差 - if (Math.abs(logVal) > this.maxLogA) this.outOfRangeA[i] = true; - this.aSliders[i] = Math.max(-this.maxLogA, Math.min(this.maxLogA, logVal)); - } else { - this.aSliders[i] = 0; - if (val !== 0 && base !== 0) this.outOfRangeA[i] = true; - } - } - }, - debouncedUpdateFromText(type) { - if (type === 'b') this.b_str = this.b_str.replace(/[^0-9,.\-\s]/g, ''); - if (type === 'a') this.a_str = this.a_str.replace(/[^0-9,.\-\s]/g, ''); - - // 當文字改變時,反向計算滑桿位置 - this.calcSlidersFromText(); - this.debouncedUpdateBode(); - }, - onlyNumberKey(e, allowDot = true) { - // 允許的控制鍵 - const allowedKeys = ['Backspace', 'Delete', 'ArrowLeft', 'ArrowRight', 'Tab', 'Enter', 'Home', 'End']; - if (allowedKeys.includes(e.key) || e.ctrlKey || e.metaKey) return; - - // 檢查字元是否合法 - const charRegex = allowDot ? /[0-9,.\-\s]/ : /[0-9,\-\s]/; - if (!charRegex.test(e.key)) { - e.preventDefault(); - } - }, - updateFromFixed(idx, type, val) { - const intVal = parseInt(val); - if (isNaN(intVal)) return; - this.fixedOverrides[type][idx] = intVal; - this.updateBodePlot({ switchToChart: false }); - }, - clearFixedOverrides(type = null) { - if (type === 'a' || type === 'b') { - this.fixedOverrides[type] = {}; - return; - } - this.fixedOverrides = { a: {}, b: {} }; - }, - resetFixedPointSettings() { - this.shiftBitsB = DEFAULT_SHIFT_BITS; - this.shiftBitsA = DEFAULT_SHIFT_BITS; - this.fixedAFineStep = 1; - this.clearFixedOverrides(); - this.updateBodePlot({ switchToChart: false }); - }, - onFsChange() { - if (this.filterType !== MANUAL_FILTER_TYPE) { - this.applyFilterDesign(); - } else { - this.updateBodePlot({ switchToChart: false }); - } - }, - debouncedApply() { - clearTimeout(this.bodeTimeout); - this.bodeTimeout = setTimeout(() => { - if (this.filterType !== MANUAL_FILTER_TYPE) this.applyFilterDesign(); - else this.updateBodePlot({ switchToChart: false }); - }, 300); - }, - debouncedUpdateBode() { - clearTimeout(this.bodeTimeout); - this.bodeTimeout = setTimeout(() => this.updateBodePlot({ switchToChart: false }), 150); - }, - onGainChange() { - this.updateFromControls(); - this.debouncedUpdateBode(); - }, - onFilterTypeChange() { - this.systemGain = 1.0; - // 這裡可以選擇是否重設所有設計參數 (fc, Q 等) - // 根據使用者要求「載入預設值」,我們呼叫重設邏輯 - this.clearFixedOverrides(); - this.bSliders = zero7(); - this.aSliders = zero7(); - this.outOfRangeB = [false, false, false, false, false, false, false]; - this.outOfRangeA = [false, false, false, false, false, false, false]; - this.showAdvancedAdjustment = false; - this.activeCoeffAdjustment = null; - if (this.filterType !== MANUAL_FILTER_TYPE) { - this.params = cloneDefaultParams(); - } - this.applyFilterDesign(); - }, - resetFilterParams() { - clearTimeout(this.bodeTimeout); - this.fs = DEFAULT_FS; - this.filterType = DEFAULT_FILTER_TYPE; - this.systemGain = 1.0; - this.params = cloneDefaultParams(); - this.b_str = DEFAULT_B_STR; - this.a_str = DEFAULT_A_STR; - this.baseB = this.padTo7(this.parseCoeffs(DEFAULT_B_STR)); - this.baseA = this.padTo7(this.parseCoeffs(DEFAULT_A_STR)); - this.clearFixedOverrides(); - this.bSliders = zero7(); - this.aSliders = zero7(); - this.outOfRangeB = [false, false, false, false, false, false, false]; - this.outOfRangeA = [false, false, false, false, false, false, false]; - this.sense_b = '2x'; - this.sense_a = '2x'; - this.shiftBitsB = DEFAULT_SHIFT_BITS; - this.shiftBitsA = DEFAULT_SHIFT_BITS; - this.aFineStep = 0.01; - this.fixedAFineStep = 1; - this.stopA1A2Repeat(); - this.stopAFineDrag(); - this.stopFixedA1A2Repeat(); - this.stopFixedAFineDrag(); - this.stopShiftBitRepeat(); - this.stopShiftBitDrag(); - this.showAdvancedAdjustment = false; - this.activeCoeffAdjustment = null; - this.globalError = null; - this.applyFilterDesign(); - }, - async applyFilterDesign() { - if (this.filterType === MANUAL_FILTER_TYPE) return; - this.globalError = null; - try { - const payload = { - filter_type: this.filterType, fs: this.fs, - lp_fc: this.params.fc, lp_order: this.params.order, - hp_fc: this.params.fc, hp_order: this.params.order, - bp_f_low: this.params.bp_f_low, bp_f_high: this.params.bp_f_high, bp_order: this.params.bp_order, - notch_f0: this.params.notch_f0, notch_q: this.params.notch_q, - opoz_fz: this.params.opoz_fz, opoz_fp: this.params.opoz_fp, - tp1z_fz: this.params.tp1z_fz, tp1z_fp1: this.params.tp1z_fp1, tp1z_fp2: this.params.tp1z_fp2, - tptz_fz1: this.params.tptz_fz1, tptz_fz2: this.params.tptz_fz2, - tptz_fp1: this.params.tptz_fp1, tptz_fp2: this.params.tptz_fp2, - pid_kp: this.params.kp, pid_ki: this.params.ki, pid_kd: this.params.kd, - sogi_f0: this.params.sogi_f0, sogi_k: this.params.sogi_k - }; - const res = await fetch('/api/design', { - method: 'POST', headers: { 'Content-Type': 'application/json' }, - body: JSON.stringify(payload) - }); - if (!res.ok) { const err = await res.json(); throw new Error(err.detail || '設計濾波器失敗'); } - const data = await res.json(); - // 1. 將後端傳回的單位增益係數存入 baseB - this.baseB = this.padTo7(data.b); - this.baseA = this.padTo7(data.a); - this.baseA[0] = 1.0; - - // 2. 重新計算含增益的文字框顯示與滑桿位置 - this.bSliders = [0, 0, 0, 0, 0, 0, 0]; - this.aSliders = [0, 0, 0, 0, 0, 0, 0]; - this.showAdvancedAdjustment = false; - this.activeCoeffAdjustment = null; - this.updateFromControls(); - - // 3. 更新圖表 - this.updateBodePlot({ switchToChart: false }); - } catch (e) { this.globalError = e.message; } - }, - async updateBodePlot({ switchToChart = true } = {}) { - this.loadingBode = true; - this.globalError = null; - try { - let b_ideal = this.parseCoeffs(this.b_str); - let a_ideal = this.parseCoeffs(this.a_str); - if (b_ideal.length === 0) b_ideal = [1.0]; - if (a_ideal.length === 0) a_ideal = [1.0]; - - const scaleB = Math.pow(2, this.shiftBitsB); - const scaleA = Math.pow(2, this.shiftBitsA); - const b_fixed = b_ideal.map((x, i) => { - const intVal = (this.fixedOverrides.b[i] !== undefined) ? this.fixedOverrides.b[i] : Math.round(x * scaleB); - return intVal / scaleB; - }); - const a_fixed = a_ideal.map((x, i) => { - const intVal = (this.fixedOverrides.a[i] !== undefined) ? this.fixedOverrides.a[i] : Math.round(x * scaleA); - return intVal / scaleA; - }); - - const [resIdeal, resFixed] = await Promise.all([ - fetch('/api/bode', { - method: 'POST', headers: { 'Content-Type': 'application/json' }, - body: JSON.stringify({ b: b_ideal, a: a_ideal, fs: this.fs }) - }), - fetch('/api/bode', { - method: 'POST', headers: { 'Content-Type': 'application/json' }, - body: JSON.stringify({ b: b_fixed, a: a_fixed, fs: this.fs }) - }) - ]); - - if (!resIdeal.ok || !resFixed.ok) throw new Error('無法計算頻率響應'); - - const dataIdeal = await resIdeal.json(); - const dataFixed = await resFixed.json(); - - this.drawBodePlot(dataIdeal.freq, dataIdeal.mag, dataIdeal.phase, dataFixed.mag, dataFixed.phase); - // 手機版:計算完成後自動切換到圖表頁籤 - if (switchToChart && window.innerWidth < 1024) this.mobileTab = 'chart'; - } catch (e) { this.globalError = e.message; } - finally { this.loadingBode = false; } - }, - drawBodePlot(freq, magIdeal, phaseIdeal, magFixed, phaseFixed) { - const fs = this.fs; - const fMin = freq[0], fMax = freq[freq.length - 1]; - const isDark = this.isDarkMode; - const isSmallScreen = window.innerWidth < 768; - - // 產生 1-2-5 刻度 - const xTicks = [], xTexts = []; - const pStart = Math.floor(Math.log10(fMin)); - const pEnd = Math.ceil(Math.log10(fMax)); - for (let p = pStart; p <= pEnd; p++) { - for (const m of [1, 2, 5]) { - const val = m * Math.pow(10, p); - if (val < fMin || val > fMax) continue; - xTicks.push(val); - if (val < 1) xTexts.push(val.toPrecision(3)); - else if (val < 1000) xTexts.push(String(val)); - else if (val < 1000000) xTexts.push((val / 1000) + 'k'); - else xTexts.push((val / 1000000) + 'M'); - } - } - - // Nyquist & fs 標線 (shapes) - const shapes = []; - const annotations = []; - const addVLine = (xVal, text, row) => { - const yref = row === 1 ? 'y' : 'y2'; - shapes.push({ - type: 'line', x0: xVal, x1: xVal, y0: 0, y1: 1, - xref: row === 1 ? 'x' : 'x2', yref: yref + ' domain', - line: { color: isDark ? 'rgba(230,184,180,0.72)' : 'rgba(162,95,91,0.72)', width: 1.4, dash: 'dash' } - }); - if (text) { - annotations.push({ - x: Math.log10(xVal), y: 1, text: text, - xref: row === 1 ? 'x' : 'x2', yref: yref + ' domain', - showarrow: false, font: { color: isDark ? '#e6b8b4' : '#a25f5b', size: isSmallScreen ? 10 : 12 }, - yshift: isSmallScreen ? 15 : 12, - xanchor: 'center', - yanchor: isSmallScreen ? 'middle' : 'bottom', - textangle: isSmallScreen ? -90 : 0 - }); - } - }; - addVLine(fs / 2, 'Nyquist', 1); - addVLine(fs, 'fs', 1); - addVLine(fs / 2, null, 2); - addVLine(fs, null, 2); - - // 10 的倍數強化線 - for (let p = pStart; p <= pEnd; p++) { - const v = Math.pow(10, p); - if (v >= fMin && v <= fMax) { - const gridColor = isDark ? 'rgba(199,206,193,0.24)' : 'rgba(101,120,104,0.16)'; - shapes.push( - { type: 'line', x0: v, x1: v, y0: 0, y1: 1, xref: 'x', yref: 'y domain', line: { color: gridColor, width: 1.5 } }, - { type: 'line', x0: v, x1: v, y0: 0, y1: 1, xref: 'x2', yref: 'y2 domain', line: { color: gridColor, width: 1.5 } } - ); - } - } - - const gridColor = isDark ? 'rgba(199,206,193,0.14)' : 'rgba(101,120,104,0.09)'; - const zeroLineColor = isDark ? 'rgba(199,206,193,0.24)' : 'rgba(70,75,67,0.20)'; - const textColor = isDark ? '#c7cec1' : '#42483f'; - const titleColor = isDark ? '#e5e9df' : '#1b1d19'; - const plotBgColor = isDark ? '#0b0e0a' : '#ffffff'; - - const xAxisCommon = { - type: 'log', title: { text: 'Freq (Hz)', font: { size: isSmallScreen ? 12 : 14 } }, - range: [Math.log10(fMin), Math.log10(fMax)], - tickvals: xTicks, ticktext: xTexts, - showgrid: true, gridcolor: gridColor, - tickfont: { color: textColor, size: isSmallScreen ? 11 : 12 }, - nticks: isSmallScreen ? 6 : 10 - }; - - const layout = { - paper_bgcolor: plotBgColor, plot_bgcolor: plotBgColor, - margin: isSmallScreen ? { t: 80, b: 120, l: 55, r: 15 } : { t: 70, b: 120, l: 70, r: 30 }, - showlegend: false, - grid: { rows: 2, columns: 1, pattern: 'independent', roworder: 'top to bottom', ygap: isSmallScreen ? 0.35 : 0.3 }, - font: { color: textColor, family: 'Google Sans, Roboto, sans-serif' }, - annotations: [ - { text: 'Magnitude Response (dB)', xref: 'x domain', yref: 'y domain', x: 0.5, y: isSmallScreen ? 1.25 : 1.15, showarrow: false, font: { size: isSmallScreen ? 14 : 16, color: titleColor, weight: 'bold' } }, - { text: 'Phase Response (Deg)', xref: 'x2 domain', yref: 'y2 domain', x: 0.5, y: isSmallScreen ? 1.25 : 1.15, showarrow: false, font: { size: isSmallScreen ? 14 : 16, color: titleColor, weight: 'bold' } }, - - // 手動 Magnitude 圖例 (位於上方圖表下方) - { xref: 'paper', yref: 'paper', x: 0.35, y: isSmallScreen ? 0.52 : 0.54, text: '一一一', font: { color: isDark ? '#b7c9b8' : '#657868', size: 10 }, showarrow: false }, - { xref: 'paper', yref: 'paper', x: 0.42, y: isSmallScreen ? 0.52 : 0.54, text: 'Ideal (Float)', font: { color: textColor, size: 11 }, showarrow: false, xanchor: 'left' }, - { xref: 'paper', yref: 'paper', x: 0.58, y: isSmallScreen ? 0.52 : 0.54, text: '· · · ·', font: { color: isDark ? '#c6cbbf' : '#73786f', size: 14 }, showarrow: false }, - { xref: 'paper', yref: 'paper', x: 0.63, y: isSmallScreen ? 0.52 : 0.54, text: `Fixed (b Q${this.shiftBitsB}, a Q${this.shiftBitsA})`, font: { color: textColor, size: 11 }, showarrow: false, xanchor: 'left' }, - - // 手動 Phase 圖例 (位於下方圖表下方) - { xref: 'paper', yref: 'paper', x: 0.35, y: -0.15, text: '一一一', font: { color: isDark ? '#d4c5aa' : '#877b68', size: 10 }, showarrow: false }, - { xref: 'paper', yref: 'paper', x: 0.42, y: -0.15, text: 'Ideal Phase', font: { color: textColor, size: 11 }, showarrow: false, xanchor: 'left' }, - { xref: 'paper', yref: 'paper', x: 0.58, y: -0.15, text: '· · · ·', font: { color: isDark ? '#e6b8b4' : '#a25f5b', size: 14 }, showarrow: false }, - { xref: 'paper', yref: 'paper', x: 0.63, y: -0.15, text: 'Fixed Phase', font: { color: textColor, size: 11 }, showarrow: false, xanchor: 'left' }, - - ...annotations - ], - xaxis: { ...xAxisCommon }, - yaxis: { title: { text: 'Mag (dB)', font: { size: isSmallScreen ? 12 : 14 } }, range: [-60, 0], gridcolor: gridColor, zerolinecolor: zeroLineColor, tickfont: { color: textColor, size: isSmallScreen ? 11 : 12 } }, - xaxis2: { ...xAxisCommon }, - yaxis2: { title: { text: 'Phase (°)', font: { size: isSmallScreen ? 12 : 14 } }, range: [-180, 180], tickvals: [-180, -90, 0, 90, 180], gridcolor: gridColor, zerolinecolor: zeroLineColor, tickfont: { color: textColor, size: isSmallScreen ? 11 : 12 } }, - shapes: shapes - }; - - const traceMagIdeal = { x: freq, y: magIdeal, name: 'Ideal (Float)', type: 'scatter', line: { color: isDark ? '#b7c9b8' : '#657868', width: 2.8 } }; - const traceMagFixed = { x: freq, y: magFixed, name: `Fixed (b Q${this.shiftBitsB}, a Q${this.shiftBitsA})`, type: 'scatter', line: { color: isDark ? '#c6cbbf' : '#73786f', width: 2.4, dash: 'dot' } }; - - const tracePhaseIdeal = { x: freq, y: phaseIdeal, name: 'Ideal Phase', type: 'scatter', line: { color: isDark ? '#d4c5aa' : '#877b68', width: 2.8 }, xaxis: 'x2', yaxis: 'y2' }; - const tracePhaseFixed = { x: freq, y: phaseFixed, name: 'Fixed Phase', type: 'scatter', line: { color: isDark ? '#e6b8b4' : '#a25f5b', width: 2.4, dash: 'dot' }, xaxis: 'x2', yaxis: 'y2' }; - - Plotly.react('bodePlot', [traceMagIdeal, traceMagFixed, tracePhaseIdeal, tracePhaseFixed], layout, { responsive: true }); - }, - - parseCsvText(text, maxRows = Infinity) { - const rows = []; - let row = []; - let field = ''; - let inQuotes = false; - let totalRows = 0; - - const finishRow = () => { - row.push(field); - if (row.some(value => value.trim() !== '')) { - totalRows++; - if (rows.length < maxRows) rows.push(row); - } - row = []; - field = ''; - }; - - for (let i = 0; i < text.length; i++) { - const char = text[i]; - const next = text[i + 1]; - - if (char === '"') { - if (inQuotes && next === '"') { - field += '"'; - i++; - } else { - inQuotes = !inQuotes; - } - } else if (char === ',' && !inQuotes) { - row.push(field); - field = ''; - } else if ((char === '\n' || char === '\r') && !inQuotes) { - if (char === '\r' && next === '\n') i++; - finishRow(); - } else { - field += char; - } - } - - if (inQuotes) throw new Error('CSV 引號未正確結束'); - finishRow(); - return { rows, totalRows }; - }, - - resetCsvState() { - this.csvFile = null; - this.csvColumns = []; - this.csvPreview = []; - this.csvInfo = null; - this.csvParseError = null; - this.selectedColumn = 0; - this.filterDone = false; - this.timePlotData = null; - }, - - handleFileUpload(event) { - const file = event.target.files[0]; - this.resetCsvState(); - if (!file) return; - - const maxBytes = 32 * 1024 * 1024; - const fileName = file.name || ''; - if (!fileName.toLowerCase().endsWith('.csv')) { - this.csvParseError = '請選擇 .csv 檔案'; - event.target.value = ''; - return; - } - if (file.size > maxBytes) { - this.csvParseError = 'CSV 檔案不可超過 32MB'; - event.target.value = ''; - return; - } - - const reader = new FileReader(); - reader.onload = (e) => { - try { - const text = String(e.target.result || '').replace(/^\uFEFF/, ''); - const { rows, totalRows } = this.parseCsvText(text, 6); - if (totalRows < 2 || rows.length < 2) throw new Error('CSV 需包含標題列與至少一筆資料'); - - const columns = rows[0].map((value, index) => { - const label = value.trim(); - return label || `Column ${index + 1}`; - }); - if (columns.length === 0) throw new Error('CSV 標題列不可為空'); - - this.csvFile = file; - this.csvColumns = columns; - this.csvPreview = rows.slice(1, 6).map(row => { - const padded = row.slice(0, columns.length); - while (padded.length < columns.length) padded.push(''); - return padded.map(value => value.trim()); - }); - this.csvInfo = { - rows: Math.max(totalRows - 1, 0), - columns: columns.length, - size: file.size, - }; - this.selectedColumn = 0; - if (columns.length > 1) { - const first = columns[0].toLowerCase(); - if (['time', 't', 'sec', 'x', 'index', 'unnamed'].some(kw => first.includes(kw))) { - this.selectedColumn = 1; - } - } - } catch (err) { - this.csvParseError = err.message || 'CSV 解析失敗'; - this.csvColumns = []; - this.csvPreview = []; - this.csvInfo = null; - event.target.value = ''; - } - }; - reader.onerror = () => { - this.csvParseError = 'CSV 讀取失敗'; - event.target.value = ''; - }; - reader.readAsText(file); - }, - - async processFilter() { - if (!this.csvFile) return; - this.loadingFilter = true; - this.globalError = null; - const formData = new FormData(); - formData.append('file', this.csvFile); - formData.append('b', this.b_str); - formData.append('a', this.a_str); - formData.append('col_idx', this.selectedColumn); - try { - const res = await fetch('/api/filter', { method: 'POST', body: formData }); - if (!res.ok) { const err = await res.json(); throw new Error(err.detail || '濾波處理失敗'); } - const data = await res.json(); - this.timePlotData = data; - this.filterDone = true; - // 確保在可見狀態下繪圖,避免 Plotly 計算尺寸錯誤 - this.$nextTick(() => { - this.drawTimePlot(data); - }); - } catch (e) { this.globalError = e.message; } - finally { this.loadingFilter = false; } - }, - - drawTimePlot(data) { - const isDark = this.isDarkMode; - const isSmallScreen = window.innerWidth < 768; - const gridColor = isDark ? 'rgba(199,206,193,0.14)' : 'rgba(101,120,104,0.09)'; - const zeroLineColor = isDark ? 'rgba(199,206,193,0.24)' : 'rgba(70,75,67,0.20)'; - const textColor = isDark ? '#c7cec1' : '#42483f'; - const plotBgColor = isDark ? '#0b0e0a' : '#ffffff'; - - const layout = { - paper_bgcolor: plotBgColor, plot_bgcolor: plotBgColor, - margin: isSmallScreen ? { t: 60, b: 60, l: 45, r: 15 } : { t: 40, b: 55, l: 60, r: 20 }, - font: { color: textColor, family: 'Google Sans, Roboto, sans-serif' }, - xaxis: { title: { text: 'Sample Index', font: { size: isSmallScreen ? 10 : 11 } }, gridcolor: gridColor, zerolinecolor: zeroLineColor, tickfont: { color: textColor, size: isSmallScreen ? 9 : 11 } }, - yaxis: { title: { text: 'Amplitude', font: { size: isSmallScreen ? 10 : 11 } }, gridcolor: gridColor, zerolinecolor: zeroLineColor, tickfont: { color: textColor, size: isSmallScreen ? 9 : 11 } }, - legend: { orientation: 'h', y: 1.02, yanchor: 'bottom', x: 1, xanchor: 'right', font: { color: textColor, size: isSmallScreen ? 9 : 10 } } - }; - Plotly.react('timePlot', [ - { x: data.index, y: data.original, name: '原始輸入訊號 (Input)', type: 'scatter', line: { color: isDark ? '#b7c9b8' : '#657868', width: 2.4 }, opacity: 0.9 }, - { x: data.index, y: data.filtered, name: '濾波後輸出 (Output)', type: 'scatter', line: { color: isDark ? '#c6cbbf' : '#73786f', width: 2.4 }, opacity: 0.95 } - ], layout, { responsive: true }); - }, - - async downloadCsv() { - if (!this.csvFile) return; - const formData = new FormData(); - formData.append('file', this.csvFile); - formData.append('b', this.b_str); - formData.append('a', this.a_str); - formData.append('col_idx', this.selectedColumn); - try { - const res = await fetch('/api/filter/download', { method: 'POST', body: formData }); - if (!res.ok) throw new Error('下載失敗'); - const blob = await res.blob(); - const url = window.URL.createObjectURL(blob); - const a = document.createElement('a'); - a.href = url; a.download = 'filtered_output.csv'; - document.body.appendChild(a); a.click(); - window.URL.revokeObjectURL(url); - } catch (e) { this.globalError = e.message; } - } - } -} + const tracePhaseIdeal = { x: freq, y: phaseIdeal, name: 'Ideal Phase', type: 'scatter', line: { color: isDark ? '#64d2ff' : '#2d6f8f', width: 2.8 }, xaxis: 'x2', yaxis: 'y2' }; + const tracePhaseFixed = { x: freq, y: phaseFixed, name: 'Fixed Phase', type: 'scatter', line: { color: isDark ? '#ff9bd8' : '#96527b', width: 2.4, dash: 'dot' }, xaxis: 'x2', yaxis: 'y2' }; + + Plotly.react('bodePlot', [traceMagIdeal, traceMagFixed, tracePhaseIdeal, tracePhaseFixed], layout, { responsive: true }); + }, + + parseCsvText(text, maxRows = Infinity) { + const rows = []; + let row = []; + let field = ''; + let inQuotes = false; + let totalRows = 0; + + const finishRow = () => { + row.push(field); + if (row.some(value => value.trim() !== '')) { + totalRows++; + if (rows.length < maxRows) rows.push(row); + } + row = []; + field = ''; + }; + + for (let i = 0; i < text.length; i++) { + const char = text[i]; + const next = text[i + 1]; + + if (char === '"') { + if (inQuotes && next === '"') { + field += '"'; + i++; + } else { + inQuotes = !inQuotes; + } + } else if (char === ',' && !inQuotes) { + row.push(field); + field = ''; + } else if ((char === '\n' || char === '\r') && !inQuotes) { + if (char === '\r' && next === '\n') i++; + finishRow(); + } else { + field += char; + } + } + + if (inQuotes) throw new Error('CSV 引號未正確結束'); + finishRow(); + return { rows, totalRows }; + }, + + resetCsvState() { + this.csvFile = null; + this.csvColumns = []; + this.csvPreview = []; + this.csvInfo = null; + this.csvParseError = null; + this.selectedColumn = 0; + this.filterDone = false; + this.timePlotData = null; + }, + + handleFileUpload(event) { + const file = event.target.files[0]; + this.resetCsvState(); + if (!file) return; + + const maxBytes = 32 * 1024 * 1024; + const fileName = file.name || ''; + if (!fileName.toLowerCase().endsWith('.csv')) { + this.csvParseError = '請選擇 .csv 檔案'; + event.target.value = ''; + return; + } + if (file.size > maxBytes) { + this.csvParseError = 'CSV 檔案不可超過 32MB'; + event.target.value = ''; + return; + } + + const reader = new FileReader(); + reader.onload = (e) => { + try { + const text = String(e.target.result || '').replace(/^\uFEFF/, ''); + const { rows, totalRows } = this.parseCsvText(text, 6); + if (totalRows < 2 || rows.length < 2) throw new Error('CSV 需包含標題列與至少一筆資料'); + + const columns = rows[0].map((value, index) => { + const label = value.trim(); + return label || `Column ${index + 1}`; + }); + if (columns.length === 0) throw new Error('CSV 標題列不可為空'); + + this.csvFile = file; + this.csvColumns = columns; + this.csvPreview = rows.slice(1, 6).map(row => { + const padded = row.slice(0, columns.length); + while (padded.length < columns.length) padded.push(''); + return padded.map(value => value.trim()); + }); + this.csvInfo = { + rows: Math.max(totalRows - 1, 0), + columns: columns.length, + size: file.size, + }; + this.selectedColumn = 0; + if (columns.length > 1) { + const first = columns[0].toLowerCase(); + if (['time', 't', 'sec', 'x', 'index', 'unnamed'].some(kw => first.includes(kw))) { + this.selectedColumn = 1; + } + } + } catch (err) { + this.csvParseError = err.message || 'CSV 解析失敗'; + this.csvColumns = []; + this.csvPreview = []; + this.csvInfo = null; + event.target.value = ''; + } + }; + reader.onerror = () => { + this.csvParseError = 'CSV 讀取失敗'; + event.target.value = ''; + }; + reader.readAsText(file); + }, + + async processFilter() { + if (!this.csvFile) return; + this.loadingFilter = true; + this.globalError = null; + const formData = new FormData(); + formData.append('file', this.csvFile); + formData.append('b', this.b_str); + formData.append('a', this.a_str); + formData.append('col_idx', this.selectedColumn); + try { + const res = await fetch('/api/filter', { method: 'POST', body: formData }); + if (!res.ok) { const err = await res.json(); throw new Error(err.detail || '濾波處理失敗'); } + const data = await res.json(); + this.timePlotData = data; + this.filterDone = true; + // 確保在可見狀態下繪圖,避免 Plotly 計算尺寸錯誤 + this.$nextTick(() => { + this.drawTimePlot(data); + }); + } catch (e) { this.globalError = e.message; } + finally { this.loadingFilter = false; } + }, + + drawTimePlot(data) { + const isDark = this.isDarkMode; + const isSmallScreen = window.innerWidth < 768; + const gridColor = isDark ? 'rgba(200,206,224,0.14)' : 'rgba(86,96,117,0.09)'; + const zeroLineColor = isDark ? 'rgba(200,206,224,0.24)' : 'rgba(82,86,99,0.20)'; + const textColor = isDark ? '#b4b4bd' : '#525663'; + const plotBgColor = isDark ? '#090a0d' : '#ffffff'; + + const layout = { + paper_bgcolor: plotBgColor, plot_bgcolor: plotBgColor, + margin: isSmallScreen ? { t: 60, b: 60, l: 45, r: 15 } : { t: 40, b: 55, l: 60, r: 20 }, + font: { color: textColor, family: 'Google Sans, Roboto, sans-serif' }, + xaxis: { title: { text: 'Sample Index', font: { size: isSmallScreen ? 10 : 11 } }, gridcolor: gridColor, zerolinecolor: zeroLineColor, tickfont: { color: textColor, size: isSmallScreen ? 9 : 11 } }, + yaxis: { title: { text: 'Amplitude', font: { size: isSmallScreen ? 10 : 11 } }, gridcolor: gridColor, zerolinecolor: zeroLineColor, tickfont: { color: textColor, size: isSmallScreen ? 9 : 11 } }, + legend: { orientation: 'h', y: 1.02, yanchor: 'bottom', x: 1, xanchor: 'right', font: { color: textColor, size: isSmallScreen ? 9 : 10 } } + }; + Plotly.react('timePlot', [ + { x: data.index, y: data.original, name: '原始輸入訊號 (Input)', type: 'scatter', line: { color: isDark ? '#c8cee0' : '#566075', width: 2.4 }, opacity: 0.9 }, + { x: data.index, y: data.filtered, name: '濾波後輸出 (Output)', type: 'scatter', line: { color: isDark ? '#64d2ff' : '#2d6f8f', width: 2.4 }, opacity: 0.95 } + ], layout, { responsive: true }); + }, + + async downloadCsv() { + if (!this.csvFile) return; + const formData = new FormData(); + formData.append('file', this.csvFile); + formData.append('b', this.b_str); + formData.append('a', this.a_str); + formData.append('col_idx', this.selectedColumn); + try { + const res = await fetch('/api/filter/download', { method: 'POST', body: formData }); + if (!res.ok) throw new Error('下載失敗'); + const blob = await res.blob(); + const url = window.URL.createObjectURL(blob); + const a = document.createElement('a'); + a.href = url; a.download = 'filtered_output.csv'; + document.body.appendChild(a); a.click(); + window.URL.revokeObjectURL(url); + } catch (e) { this.globalError = e.message; } + } + } +} diff --git a/src/style.css b/src/style.css index 8498e5e..cbd0f79 100755 --- a/src/style.css +++ b/src/style.css @@ -4,36 +4,42 @@ @tailwind components; @tailwind utilities; -/* Morandi green hierarchy. Feature colors are expressed through role classes only. */ +/* Pixel M3E hierarchy. Feature colors are expressed through role classes only. */ :root { - --m3-primary: #657868; + --m3-primary: #566075; --m3-on-primary: #ffffff; - --m3-primary-container: #dce7dc; - --m3-on-primary-container: #1b2a1f; - --m3-secondary: #73786f; + --m3-primary-container: #d8deef; + --m3-on-primary-container: #202637; + --m3-secondary: #5e6472; --m3-on-secondary: #ffffff; - --m3-secondary-container: #e2e6dc; - --m3-on-secondary-container: #20251f; - --m3-tertiary: #877b68; + --m3-secondary-container: #e1e5f0; + --m3-on-secondary-container: #242832; + --m3-tertiary: #7a6689; --m3-on-tertiary: #ffffff; - --m3-tertiary-container: #ece2d2; - --m3-on-tertiary-container: #2d261a; - --m3-error: #a25f5b; + --m3-tertiary-container: #f0dcff; + --m3-on-tertiary-container: #30203d; + --m3-error: #b3261e; --m3-on-error: #ffffff; - --m3-error-container: #f2ddda; - --m3-warning: #806b43; - --m3-warning-container: #f0e4c7; - --m3-background: #fbfcf8; - --m3-surface: #fbfcf8; + --m3-error-container: #f9dedc; + --m3-success: #2e7d61; + --m3-success-container: #cceede; + --m3-warning: #8c6d1f; + --m3-warning-container: #f5e4b2; + --m3-accent-cyan: #64d2ff; + --m3-accent-pink: #ff9bd8; + --m3-accent-orange: #ffb879; + --m3-accent-lavender: #b9b2ff; + --m3-background: #f6f7fb; + --m3-surface: #f6f7fb; --m3-surface-container-lowest: #ffffff; - --m3-surface-container-low: #f4f7ef; - --m3-surface-container: #edf1e8; - --m3-surface-container-high: #e4e9de; - --m3-surface-container-highest: #dbe2d5; - --m3-on-surface: #1b1d19; - --m3-on-surface-variant: #464b43; - --m3-outline: #747b70; - --m3-outline-variant: #c9d0c3; + --m3-surface-container-low: #eff1f7; + --m3-surface-container: #e7e9f1; + --m3-surface-container-high: #dde1ec; + --m3-surface-container-highest: #d1d7e6; + --m3-on-surface: #17191f; + --m3-on-surface-variant: #525663; + --m3-outline: #747987; + --m3-outline-variant: #c3c8d4; --m3-divider: color-mix(in srgb, var(--m3-outline-variant) 78%, transparent); --m3-soft-outline: color-mix(in srgb, var(--m3-outline-variant) 88%, transparent); --m3-input-outline: color-mix(in srgb, var(--m3-outline) 82%, transparent); @@ -41,41 +47,58 @@ --m3-secondary-state: color-mix(in srgb, var(--m3-secondary) 12%, transparent); --m3-tertiary-state: color-mix(in srgb, var(--m3-tertiary) 12%, transparent); --m3-warning-state: color-mix(in srgb, var(--m3-warning) 12%, transparent); - --m3-shadow: 0 1px 2px rgba(29, 27, 32, 0.14), 0 2px 6px rgba(29, 27, 32, 0.10); - --m3-elevated-shadow: 0 3px 8px rgba(29, 27, 32, 0.13), 0 12px 24px rgba(29, 27, 32, 0.08); + --m3-shadow: 0 1px 2px rgba(15, 18, 26, 0.10), 0 8px 18px rgba(15, 18, 26, 0.08); + --m3-elevated-shadow: 0 8px 22px rgba(15, 18, 26, 0.12), 0 18px 36px rgba(15, 18, 26, 0.10); + --background: var(--m3-background); + --surface: var(--m3-surface-container); + --surfaceHigh: var(--m3-surface-container-high); + --primary: var(--m3-primary); + --onPrimary: var(--m3-on-primary); + --textPrimary: var(--m3-on-surface); + --textSecondary: var(--m3-on-surface-variant); + --border: var(--m3-outline-variant); + --danger: var(--m3-error); + --success: var(--m3-success); + --warning: var(--m3-warning); } .dark { - --m3-primary: #b7c9b8; - --m3-on-primary: #243429; - --m3-primary-container: #3f5745; - --m3-on-primary-container: #dce7dc; - --m3-secondary: #c6cbbf; - --m3-on-secondary: #2e332b; - --m3-secondary-container: #454b40; - --m3-on-secondary-container: #e2e6dc; - --m3-tertiary: #d4c5aa; - --m3-on-tertiary: #3b2f20; - --m3-tertiary-container: #5d503e; - --m3-on-tertiary-container: #f1e4cf; - --m3-error: #e6b8b4; - --m3-on-error: #5f1715; - --m3-error-container: #7c3430; - --m3-warning: #dcc48e; - --m3-warning-container: #5a4828; - --m3-background: #111510; - --m3-surface: #111510; - --m3-surface-container-lowest: #0b0e0a; - --m3-surface-container-low: #1a1f18; - --m3-surface-container: #20261e; - --m3-surface-container-high: #2a3128; - --m3-surface-container-highest: #343d31; - --m3-on-surface: #e5e9df; - --m3-on-surface-variant: #c7cec1; - --m3-outline: #92998e; - --m3-outline-variant: #464d43; - --m3-shadow: 0 1px 2px rgba(0, 0, 0, 0.36), 0 4px 12px rgba(0, 0, 0, 0.28); - --m3-elevated-shadow: 0 4px 12px rgba(0, 0, 0, 0.45), 0 16px 32px rgba(0, 0, 0, 0.32); + --m3-primary: #c8cee0; + --m3-on-primary: #202431; + --m3-primary-container: #3f4453; + --m3-on-primary-container: #eef1ff; + --m3-secondary: #aeb6c9; + --m3-on-secondary: #242832; + --m3-secondary-container: #343842; + --m3-on-secondary-container: #e4e8f6; + --m3-tertiary: #d6b7f0; + --m3-on-tertiary: #382047; + --m3-tertiary-container: #4b3b59; + --m3-on-tertiary-container: #f4dcff; + --m3-error: #f2b8b5; + --m3-on-error: #601410; + --m3-error-container: #7d2e29; + --m3-success: #9bd7bd; + --m3-success-container: #254c3a; + --m3-warning: #e6cb7f; + --m3-warning-container: #55451f; + --m3-accent-cyan: #5fd4ff; + --m3-accent-pink: #ff9bd8; + --m3-accent-orange: #ffb879; + --m3-accent-lavender: #b9b2ff; + --m3-background: #111216; + --m3-surface: #111216; + --m3-surface-container-lowest: #090a0d; + --m3-surface-container-low: #1a1b20; + --m3-surface-container: #2a2a2e; + --m3-surface-container-high: #34353b; + --m3-surface-container-highest: #41434b; + --m3-on-surface: #f1f1f4; + --m3-on-surface-variant: #b4b4bd; + --m3-outline: #8b8d98; + --m3-outline-variant: #4b4d56; + --m3-shadow: 0 1px 2px rgba(0, 0, 0, 0.42), 0 8px 24px rgba(0, 0, 0, 0.34); + --m3-elevated-shadow: 0 8px 24px rgba(0, 0, 0, 0.48), 0 24px 48px rgba(0, 0, 0, 0.36); } html, @@ -87,7 +110,16 @@ body, body { font-family: "Google Sans", Roboto, "Noto Sans TC", system-ui, -apple-system, sans-serif; + font-size: 16px; + line-height: 1.55; letter-spacing: 0; + text-rendering: optimizeLegibility; +} + +#app { + background: + radial-gradient(circle at 50% 0%, color-mix(in srgb, var(--m3-primary) 10%, transparent), transparent 30rem), + var(--m3-background); } header, @@ -106,11 +138,26 @@ header.bg-white, header.dark\:bg-dark, footer.bg-white, footer.dark\:bg-dark { - background: var(--m3-surface-container-low) !important; + background: color-mix(in srgb, var(--m3-background) 82%, var(--m3-surface-container) 18%) !important; border-color: var(--m3-divider) !important; box-shadow: none !important; } +header { + min-height: 72px; + padding-inline: clamp(1rem, 2vw, 1.75rem) !important; +} + +header img { + background: var(--m3-surface-container-high); + border-radius: 18px !important; +} + +header h1 { + font-size: clamp(1.35rem, 1.8vw, 2rem) !important; + line-height: 1.15; +} + aside.bg-white, aside.dark\:bg-dark, main.bg-slate-50, @@ -133,7 +180,23 @@ header h1 { background: none !important; color: var(--m3-on-surface) !important; -webkit-text-fill-color: var(--m3-on-surface); - font-weight: 700; + font-weight: 500; + letter-spacing: 0; +} + +h2 { + font-size: 0.95rem !important; + font-weight: 500 !important; + letter-spacing: 0.01em !important; + text-transform: none !important; +} + +h3.font-bold { + font-size: clamp(1.15rem, 1.35vw, 1.45rem) !important; +} + +h4.font-bold { + font-size: 1.05rem !important; } hr { @@ -168,6 +231,22 @@ main > div, box-shadow: none !important; } +aside section { + background: var(--m3-surface-container) !important; + border: 1px solid var(--m3-soft-outline); + border-radius: 28px; + padding: 1.15rem; +} + +main > div { + border-radius: 30px !important; + overflow: hidden; +} + +main > div > div:first-child { + border-radius: 30px 30px 0 0; +} + .border, .border-2 { border-color: var(--m3-outline-variant) !important; @@ -222,7 +301,7 @@ input[type="number"], textarea { background: var(--m3-surface-container-lowest) !important; border-color: var(--m3-input-outline) !important; - border-radius: 12px !important; + border-radius: 22px !important; color: var(--m3-on-surface) !important; box-shadow: none; } @@ -248,10 +327,17 @@ label.cursor-pointer { border-color: transparent !important; border-radius: 999px !important; box-shadow: none !important; - font-weight: 650; + font-weight: 500; transition: background-color 140ms ease, color 140ms ease, box-shadow 140ms ease, transform 120ms ease; } +button:focus-visible, +[role="button"]:focus-visible, +label.cursor-pointer:focus-visible { + outline: 3px solid color-mix(in srgb, var(--m3-primary) 42%, transparent); + outline-offset: 2px; +} + button:hover, [role="button"]:hover, label.cursor-pointer:hover { @@ -297,7 +383,7 @@ details, select, textarea, input[type="number"] { - border-radius: 16px !important; + border-radius: 22px !important; } .rounded-full { @@ -305,15 +391,17 @@ input[type="number"] { } input[type=range] { - background: color-mix(in srgb, var(--m3-primary) 22%, var(--m3-surface-container-high)) !important; + background: color-mix(in srgb, var(--m3-primary) 28%, var(--m3-surface-container-high)) !important; border-radius: 999px; - height: 6px; + height: 10px; } input[type=range]::-webkit-slider-thumb { background: var(--m3-primary); - border: 3px solid var(--m3-surface-container-lowest); + border: 4px solid var(--m3-surface-container-lowest); box-shadow: var(--m3-shadow); + height: 28px; + width: 28px; } .dark input[type=range]::-webkit-slider-thumb { @@ -529,3 +617,138 @@ details .grid.grid-cols-\[2rem_1fr_2rem\] button { background: var(--m3-secondary-container) !important; color: var(--m3-on-secondary-container) !important; } + +details .grid.grid-cols-\[3\.25rem_1fr_3\.25rem\] > button, +details .grid.grid-cols-\[2rem_1fr_2rem\] > button, +details button.touch-none { + background: var(--m3-secondary-container) !important; + border: 1px solid color-mix(in srgb, var(--m3-secondary) 28%, var(--m3-outline-variant)) !important; + color: var(--m3-on-secondary-container) !important; + border-radius: 999px !important; + min-height: 42px; +} + +details .grid.grid-cols-\[3\.25rem_1fr_3\.25rem\] > button:hover, +details .grid.grid-cols-\[2rem_1fr_2rem\] > button:hover, +details button.touch-none:hover { + background: color-mix(in srgb, var(--m3-secondary-container) 82%, var(--m3-primary) 18%) !important; + color: var(--m3-on-secondary-container) !important; +} + +details .grid.grid-cols-\[3\.25rem_1fr_3\.25rem\] > div, +details .grid.grid-cols-\[2rem_1fr_2rem\] input, +details button.touch-none, +details .grid.grid-cols-2.gap-2 > div { + background: var(--m3-surface-container-lowest) !important; + border-color: var(--m3-soft-outline) !important; +} + +details .grid.grid-cols-\[2rem_1fr_2rem\] input, +details button.touch-none span.font-mono, +details .grid.grid-cols-2.gap-2 > div span.font-mono { + color: var(--m3-on-surface) !important; + -webkit-text-fill-color: var(--m3-on-surface); +} + +details .grid.grid-cols-\[3\.25rem_1fr_3\.25rem\] > div span.font-mono { + color: var(--m3-on-secondary-container) !important; + -webkit-text-fill-color: var(--m3-on-secondary-container); +} + +details .grid.grid-cols-\[2rem_1fr_2rem\] input:focus { + border-color: var(--m3-primary) !important; + box-shadow: 0 0 0 3px var(--m3-primary-state) !important; +} + +.grid.grid-cols-\[3\.25rem_1fr_3\.25rem\] > button, +.grid.grid-cols-\[2rem_1fr_2rem\] > button, +button.touch-none { + background: var(--m3-secondary-container) !important; + border: 1px solid color-mix(in srgb, var(--m3-secondary) 28%, var(--m3-outline-variant)) !important; + color: var(--m3-on-secondary-container) !important; + border-radius: 999px !important; + font-size: 0.875rem !important; + font-weight: 500 !important; + letter-spacing: 0 !important; + min-height: 42px; +} + +.grid.grid-cols-\[3\.25rem_1fr_3\.25rem\] > button:hover, +.grid.grid-cols-\[2rem_1fr_2rem\] > button:hover, +button.touch-none:hover { + background: color-mix(in srgb, var(--m3-secondary-container) 82%, var(--m3-primary) 18%) !important; + color: var(--m3-on-secondary-container) !important; +} + +.grid.grid-cols-\[2rem_1fr_2rem\] > input, +button.touch-none, +.grid.grid-cols-\[3\.25rem_1fr_3\.25rem\] > div { + background: var(--m3-surface-container-lowest) !important; + border-color: var(--m3-soft-outline) !important; +} + +.grid.grid-cols-\[2rem_1fr_2rem\] > input, +button.touch-none span.font-mono, +.grid.grid-cols-\[3\.25rem_1fr_3\.25rem\] span.font-mono, +.grid.grid-cols-2.gap-2 span.font-mono { + color: var(--m3-on-surface) !important; + -webkit-text-fill-color: var(--m3-on-surface); + font-weight: 500 !important; +} + +.grid.grid-cols-\[3\.25rem_1fr_3\.25rem\] span:not(.font-mono), +.grid.grid-cols-2.gap-2 span:not(.font-mono) { + font-weight: 400 !important; +} + +.grid.grid-cols-\[2rem_1fr_2rem\] > input { + text-align: center; + font-size: 0.95rem !important; + min-height: 42px; +} + +.grid.grid-cols-\[2rem_1fr_2rem\] > input:focus { + border-color: var(--m3-primary) !important; + box-shadow: 0 0 0 3px var(--m3-primary-state) !important; +} + +#app .font-bold, +#app .font-semibold, +#app strong, +#app b { + font-weight: 500 !important; +} + +#app label, +#app summary, +#app p, +#app span { + letter-spacing: 0 !important; +} + +#app section .flex.flex-wrap.gap-1.mb-2 > div, +#app section .grid.grid-cols-2.gap-2 > div, +#app section .grid.grid-cols-\[3\.25rem_1fr_3\.25rem\] > div, +#app section button.touch-none { + background: var(--m3-surface-container-lowest) !important; + border-color: var(--m3-soft-outline) !important; + color: var(--m3-on-surface) !important; +} + +#app section .flex.flex-wrap.gap-1.mb-2 > div span, +#app section .grid.grid-cols-2.gap-2 > div span, +#app section .grid.grid-cols-\[3\.25rem_1fr_3\.25rem\] > div span, +#app section button.touch-none span { + color: var(--m3-on-surface) !important; + -webkit-text-fill-color: var(--m3-on-surface); + font-weight: 500 !important; +} + +#app section .flex.flex-wrap.gap-1.mb-2 > div span:first-child, +#app section .grid.grid-cols-2.gap-2 > div span:first-child, +#app section .grid.grid-cols-\[3\.25rem_1fr_3\.25rem\] > div span:first-child, +#app section button.touch-none span:first-child { + color: var(--m3-on-surface-variant) !important; + -webkit-text-fill-color: var(--m3-on-surface-variant); + font-weight: 400 !important; +} diff --git a/static/build/app.css b/static/build/app.css index adecc6e..087b73f 100644 --- a/static/build/app.css +++ b/static/build/app.css @@ -1 +1 @@ -.custom-scrollbar::-webkit-scrollbar{width:6px;height:6px}.custom-scrollbar::-webkit-scrollbar-track{background:0 0}.custom-scrollbar::-webkit-scrollbar-thumb{background:#cbd5e1;border-radius:3px}.dark .custom-scrollbar::-webkit-scrollbar-thumb{background:#374151}.custom-scrollbar::-webkit-scrollbar-thumb:hover{background:#94a3b8}.dark .custom-scrollbar::-webkit-scrollbar-thumb:hover{background:#4b5563}body{font-family:Inter,system-ui,-apple-system,sans-serif;font-size:16px;line-height:1.6}input[type=range]{appearance:none;cursor:pointer;background:#e2e8f0;border-radius:4px;height:8px;transition:background .3s}.dark input[type=range]{background:#374151}input[type=range]::-webkit-slider-thumb{-webkit-appearance:none;cursor:pointer;background:#3b82f6;border:2px solid #fff;border-radius:50%;width:24px;height:24px;transition:background .15s ease-in-out,transform .1s;box-shadow:0 2px 5px #0003}.dark input[type=range]::-webkit-slider-thumb{border:2px solid #1f2937}input[type=range]::-webkit-slider-thumb:hover{background:#2563eb;transform:scale(1.1)}button,select,input[type=number],textarea{min-height:44px}.btn-small{min-height:unset}input[type=number]::-webkit-inner-spin-button{appearance:none;margin:0}input[type=number]::-webkit-outer-spin-button{appearance:none;margin:0}input[type=number]{appearance:textfield}.js-plotly-plot .plotly .modebar-container{width:100%!important;display:block!important;top:-45px!important;left:0!important;right:0!important}.js-plotly-plot .plotly .modebar{padding-right:10px;background:0 0!important;flex-flow:row!important;justify-content:flex-end!important;display:flex!important;position:static!important}.js-plotly-plot .plotly .modebar-group{flex-direction:row!important;display:flex!important}#bodePlot,#timePlot{margin-top:50px}@media (width<=1024px){.js-plotly-plot .plotly .modebar-container{top:-40px!important}}details>summary{-webkit-user-select:none;user-select:none;list-style:none}details>summary::-webkit-details-marker{display:none}details>div{animation:.2s ease-out slideDown;overflow:hidden}@keyframes slideDown{0%{opacity:0;transform:translateY(-6px)}to{opacity:1;transform:translateY(0)}}*,:before,:after,::backdrop{--tw-border-spacing-x:0;--tw-border-spacing-y:0;--tw-translate-x:0;--tw-translate-y:0;--tw-rotate:0;--tw-skew-x:0;--tw-skew-y:0;--tw-scale-x:1;--tw-scale-y:1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness:proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-color:#3b82f680;--tw-ring-offset-shadow:0 0 #0000;--tw-ring-shadow:0 0 #0000;--tw-shadow:0 0 #0000;--tw-shadow-colored:0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: ;--tw-contain-size: ;--tw-contain-layout: ;--tw-contain-paint: ;--tw-contain-style: }*,:before,:after{box-sizing:border-box;border:0 solid #e5e7eb}:before,:after{--tw-content:""}html,:host{-webkit-text-size-adjust:100%;tab-size:4;font-feature-settings:normal;font-variation-settings:normal;-webkit-tap-highlight-color:transparent;font-family:ui-sans-serif,system-ui,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol,Noto Color Emoji;line-height:1.5}body{line-height:inherit;margin:0}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;-webkit-text-decoration:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,samp,pre{font-feature-settings:normal;font-variation-settings:normal;font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace;font-size:1em}small{font-size:80%}sub,sup{vertical-align:baseline;font-size:75%;line-height:0;position:relative}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}button,input,optgroup,select,textarea{font-feature-settings:inherit;font-variation-settings:inherit;font-family:inherit;font-size:100%;font-weight:inherit;line-height:inherit;letter-spacing:inherit;color:inherit;margin:0;padding:0}button,select{text-transform:none}button,input:where([type=button]),input:where([type=reset]),input:where([type=submit]){-webkit-appearance:button;background-color:#0000;background-image:none}:-moz-focusring{outline:auto}:-moz-ui-invalid{box-shadow:none}progress{vertical-align:baseline}::-webkit-inner-spin-button{height:auto}::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}summary{display:list-item}blockquote,dl,dd,h1,h2,h3,h4,h5,h6,hr,figure,p,pre{margin:0}fieldset{margin:0;padding:0}legend{padding:0}ol,ul,menu{margin:0;padding:0;list-style:none}dialog{padding:0}textarea{resize:vertical}input::-moz-placeholder{opacity:1;color:#9ca3af}textarea::-moz-placeholder{opacity:1;color:#9ca3af}input::placeholder,textarea::placeholder{opacity:1;color:#9ca3af}button,[role=button]{cursor:pointer}:disabled{cursor:default}img,svg,video,canvas,audio,iframe,embed,object{vertical-align:middle;display:block}img,video{max-width:100%;height:auto}[hidden]:where(:not([hidden=until-found])){display:none}.pointer-events-none{pointer-events:none}.absolute{position:absolute}.relative{position:relative}.inset-0{inset:0}.right-6{right:1.5rem}.top-4{top:1rem}.z-10{z-index:10}.z-20{z-index:20}.z-50{z-index:50}.mx-2{margin-left:.5rem;margin-right:.5rem}.mx-auto{margin-left:auto;margin-right:auto}.mb-1{margin-bottom:.25rem}.mb-2{margin-bottom:.5rem}.mb-3{margin-bottom:.75rem}.mb-4{margin-bottom:1rem}.mb-6{margin-bottom:1.5rem}.ml-2{margin-left:.5rem}.ml-auto{margin-left:auto}.mr-1{margin-right:.25rem}.mt-1{margin-top:.25rem}.mt-2{margin-top:.5rem}.mt-3{margin-top:.75rem}.block{display:block}.flex{display:flex}.table{display:table}.grid{display:grid}.hidden{display:none}.h-10{height:2.5rem}.h-12{height:3rem}.h-2{height:.5rem}.h-4{height:1rem}.h-5{height:1.25rem}.h-8{height:2rem}.h-\[300px\]{height:300px}.h-\[400px\]{height:400px}.h-\[800px\]{height:800px}.h-full{height:100%}.h-screen{height:100vh}.min-h-screen{min-height:100vh}.w-10{width:2.5rem}.w-12{width:3rem}.w-2{width:.5rem}.w-24{width:6rem}.w-28{width:7rem}.w-4{width:1rem}.w-5{width:1.25rem}.w-full{width:100%}.min-w-0{min-width:0}.min-w-\[580px\]{min-width:580px}.max-w-full{max-width:100%}.flex-1{flex:1}.flex-shrink-0{flex-shrink:0}.transform{transform:translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}@keyframes ping{75%,to{opacity:0;transform:scale(2)}}.animate-ping{animation:1s cubic-bezier(0,0,.2,1) infinite ping}@keyframes pulse{50%{opacity:.5}}.animate-pulse{animation:2s cubic-bezier(.4,0,.6,1) infinite pulse}.cursor-pointer{cursor:pointer}.touch-none{touch-action:none}.select-none{-webkit-user-select:none;user-select:none}.resize-none{resize:none}.grid-cols-1{grid-template-columns:repeat(1,minmax(0,1fr))}.grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.grid-cols-\[2rem_1fr_2rem\]{grid-template-columns:2rem 1fr 2rem}.grid-cols-\[3\.25rem_1fr_3\.25rem\]{grid-template-columns:3.25rem 1fr 3.25rem}.flex-col{flex-direction:column}.flex-wrap{flex-wrap:wrap}.items-center{align-items:center}.justify-center{justify-content:center}.justify-between{justify-content:space-between}.gap-0{gap:0}.gap-1{gap:.25rem}.gap-2{gap:.5rem}.gap-3{gap:.75rem}.gap-4{gap:1rem}.gap-5{gap:1.25rem}.space-y-3>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-top:calc(.75rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.75rem * var(--tw-space-y-reverse))}.space-y-4>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-top:calc(1rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(1rem * var(--tw-space-y-reverse))}.divide-y>:not([hidden])~:not([hidden]){--tw-divide-y-reverse:0;border-top-width:calc(1px * calc(1 - var(--tw-divide-y-reverse)));border-bottom-width:calc(1px * var(--tw-divide-y-reverse))}.divide-slate-100>:not([hidden])~:not([hidden]){--tw-divide-opacity:1;border-color:rgb(241 245 249/var(--tw-divide-opacity,1))}.overflow-hidden{overflow:hidden}.overflow-x-auto{overflow-x:auto}.overflow-y-auto{overflow-y:auto}.truncate{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.rounded{border-radius:.25rem}.rounded-lg{border-radius:.5rem}.rounded-xl{border-radius:.75rem}.border{border-width:1px}.border-2{border-width:2px}.border-b{border-bottom-width:1px}.border-b-2{border-bottom-width:2px}.border-l{border-left-width:1px}.border-t{border-top-width:1px}.border-dashed{border-style:dashed}.border-slate-100{--tw-border-opacity:1;border-color:rgb(241 245 249/var(--tw-border-opacity,1))}.border-slate-200{--tw-border-opacity:1;border-color:rgb(226 232 240/var(--tw-border-opacity,1))}.border-slate-300{--tw-border-opacity:1;border-color:rgb(203 213 225/var(--tw-border-opacity,1))}.bg-slate-100{--tw-bg-opacity:1;background-color:rgb(241 245 249/var(--tw-bg-opacity,1))}.bg-slate-200{--tw-bg-opacity:1;background-color:rgb(226 232 240/var(--tw-bg-opacity,1))}.bg-slate-50{--tw-bg-opacity:1;background-color:rgb(248 250 252/var(--tw-bg-opacity,1))}.bg-slate-50\/50{background-color:#f8fafc80}.bg-slate-700{--tw-bg-opacity:1;background-color:rgb(51 65 85/var(--tw-bg-opacity,1))}.bg-white{--tw-bg-opacity:1;background-color:rgb(255 255 255/var(--tw-bg-opacity,1))}.bg-gradient-to-br{background-image:linear-gradient(to bottom right, var(--tw-gradient-stops))}.object-contain{-o-object-fit:contain;object-fit:contain}.\!p-0{padding:0!important}.p-0{padding:0}.p-2{padding:.5rem}.p-3{padding:.75rem}.p-4{padding:1rem}.p-5{padding:1.25rem}.p-6{padding:1.5rem}.px-1\.5{padding-left:.375rem;padding-right:.375rem}.px-2{padding-left:.5rem;padding-right:.5rem}.px-3{padding-left:.75rem;padding-right:.75rem}.px-4{padding-left:1rem;padding-right:1rem}.px-5{padding-left:1.25rem;padding-right:1.25rem}.px-6{padding-left:1.5rem;padding-right:1.5rem}.py-0\.5{padding-top:.125rem;padding-bottom:.125rem}.py-1{padding-top:.25rem;padding-bottom:.25rem}.py-1\.5{padding-top:.375rem;padding-bottom:.375rem}.py-2{padding-top:.5rem;padding-bottom:.5rem}.py-2\.5{padding-top:.625rem;padding-bottom:.625rem}.py-3{padding-top:.75rem;padding-bottom:.75rem}.py-4{padding-top:1rem;padding-bottom:1rem}.pb-3{padding-bottom:.75rem}.text-left{text-align:left}.text-center{text-align:center}.font-mono{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace}.text-\[10px\]{font-size:10px}.text-\[11px\]{font-size:11px}.text-\[9px\]{font-size:9px}.text-base{font-size:1rem;line-height:1.5rem}.text-lg{font-size:1.125rem;line-height:1.75rem}.text-sm{font-size:.875rem;line-height:1.25rem}.text-xl{font-size:1.25rem;line-height:1.75rem}.text-xs{font-size:.75rem;line-height:1rem}.font-bold{font-weight:700}.font-medium{font-weight:500}.font-semibold{font-weight:600}.uppercase{text-transform:uppercase}.italic{font-style:italic}.leading-relaxed{line-height:1.625}.tracking-tight{letter-spacing:-.025em}.tracking-wide{letter-spacing:.025em}.tracking-wider{letter-spacing:.05em}.text-gray-500{--tw-text-opacity:1;color:rgb(107 114 128/var(--tw-text-opacity,1))}.text-slate-400{--tw-text-opacity:1;color:rgb(148 163 184/var(--tw-text-opacity,1))}.text-slate-500{--tw-text-opacity:1;color:rgb(100 116 139/var(--tw-text-opacity,1))}.text-slate-600{--tw-text-opacity:1;color:rgb(71 85 105/var(--tw-text-opacity,1))}.text-slate-700{--tw-text-opacity:1;color:rgb(51 65 85/var(--tw-text-opacity,1))}.text-slate-800{--tw-text-opacity:1;color:rgb(30 41 59/var(--tw-text-opacity,1))}.text-slate-900{--tw-text-opacity:1;color:rgb(15 23 42/var(--tw-text-opacity,1))}.opacity-50{opacity:.5}.shadow-inner{--tw-shadow:inset 0 2px 4px 0 #0000000d;--tw-shadow-colored:inset 0 2px 4px 0 var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow,0 0 #0000), var(--tw-ring-shadow,0 0 #0000), var(--tw-shadow)}.shadow-lg{--tw-shadow:0 10px 15px -3px #0000001a, 0 4px 6px -4px #0000001a;--tw-shadow-colored:0 10px 15px -3px var(--tw-shadow-color), 0 4px 6px -4px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow,0 0 #0000), var(--tw-ring-shadow,0 0 #0000), var(--tw-shadow)}.shadow-md{--tw-shadow:0 4px 6px -1px #0000001a, 0 2px 4px -2px #0000001a;--tw-shadow-colored:0 4px 6px -1px var(--tw-shadow-color), 0 2px 4px -2px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow,0 0 #0000), var(--tw-ring-shadow,0 0 #0000), var(--tw-shadow)}.shadow-sm{--tw-shadow:0 1px 2px 0 #0000000d;--tw-shadow-colored:0 1px 2px 0 var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow,0 0 #0000), var(--tw-ring-shadow,0 0 #0000), var(--tw-shadow)}.outline-none{outline-offset:2px;outline:2px solid #0000}.ring-1{--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow,0 0 #0000)}.blur{--tw-blur:blur(8px);filter:var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow)}.filter{filter:var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow)}.backdrop-blur-sm{--tw-backdrop-blur:blur(4px);-webkit-backdrop-filter:var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia);backdrop-filter:var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia)}.transition-all{transition-property:all;transition-duration:.15s;transition-timing-function:cubic-bezier(.4,0,.2,1)}.transition-colors{transition-property:color,background-color,border-color,text-decoration-color,fill,stroke;transition-duration:.15s;transition-timing-function:cubic-bezier(.4,0,.2,1)}.duration-300{transition-duration:.3s}:root{--m3-primary:#657868;--m3-on-primary:#fff;--m3-primary-container:#dce7dc;--m3-on-primary-container:#1b2a1f;--m3-secondary:#73786f;--m3-on-secondary:#fff;--m3-secondary-container:#e2e6dc;--m3-on-secondary-container:#20251f;--m3-tertiary:#877b68;--m3-on-tertiary:#fff;--m3-tertiary-container:#ece2d2;--m3-on-tertiary-container:#2d261a;--m3-error:#a25f5b;--m3-on-error:#fff;--m3-error-container:#f2ddda;--m3-warning:#806b43;--m3-warning-container:#f0e4c7;--m3-background:#fbfcf8;--m3-surface:#fbfcf8;--m3-surface-container-lowest:#fff;--m3-surface-container-low:#f4f7ef;--m3-surface-container:#edf1e8;--m3-surface-container-high:#e4e9de;--m3-surface-container-highest:#dbe2d5;--m3-on-surface:#1b1d19;--m3-on-surface-variant:#464b43;--m3-outline:#747b70;--m3-outline-variant:#c9d0c3;--m3-divider:color-mix(in srgb, var(--m3-outline-variant) 78%, transparent);--m3-soft-outline:color-mix(in srgb, var(--m3-outline-variant) 88%, transparent);--m3-input-outline:color-mix(in srgb, var(--m3-outline) 82%, transparent);--m3-primary-state:color-mix(in srgb, var(--m3-primary) 14%, transparent);--m3-secondary-state:color-mix(in srgb, var(--m3-secondary) 12%, transparent);--m3-tertiary-state:color-mix(in srgb, var(--m3-tertiary) 12%, transparent);--m3-warning-state:color-mix(in srgb, var(--m3-warning) 12%, transparent);--m3-shadow:0 1px 2px #1d1b2024, 0 2px 6px #1d1b201a;--m3-elevated-shadow:0 3px 8px #1d1b2021, 0 12px 24px #1d1b2014}.dark{--m3-primary:#b7c9b8;--m3-on-primary:#243429;--m3-primary-container:#3f5745;--m3-on-primary-container:#dce7dc;--m3-secondary:#c6cbbf;--m3-on-secondary:#2e332b;--m3-secondary-container:#454b40;--m3-on-secondary-container:#e2e6dc;--m3-tertiary:#d4c5aa;--m3-on-tertiary:#3b2f20;--m3-tertiary-container:#5d503e;--m3-on-tertiary-container:#f1e4cf;--m3-error:#e6b8b4;--m3-on-error:#5f1715;--m3-error-container:#7c3430;--m3-warning:#dcc48e;--m3-warning-container:#5a4828;--m3-background:#111510;--m3-surface:#111510;--m3-surface-container-lowest:#0b0e0a;--m3-surface-container-low:#1a1f18;--m3-surface-container:#20261e;--m3-surface-container-high:#2a3128;--m3-surface-container-highest:#343d31;--m3-on-surface:#e5e9df;--m3-on-surface-variant:#c7cec1;--m3-outline:#92998e;--m3-outline-variant:#464d43;--m3-shadow:0 1px 2px #0000005c, 0 4px 12px #00000047;--m3-elevated-shadow:0 4px 12px #00000073, 0 16px 32px #00000052}html,body,#dea-root{background:var(--m3-background);color:var(--m3-on-surface)}body{letter-spacing:0;font-family:Google Sans,Roboto,Noto Sans TC,system-ui,-apple-system,sans-serif}header,aside,footer,main>div,section,details,.js-plotly-plot,#bodePlot,#timePlot{color:var(--m3-on-surface)}header.bg-white,header.dark\:bg-dark,footer.bg-white,footer.dark\:bg-dark{background:var(--m3-surface-container-low)!important;border-color:var(--m3-divider)!important;box-shadow:none!important}aside.bg-white,aside.dark\:bg-dark,main.bg-slate-50,main.dark\:bg-\[\#0f0f0f\]{background:var(--m3-background)!important;border-color:var(--m3-divider)!important}h2,h3,h4,label,summary{color:var(--m3-on-surface-variant)!important}h3.font-bold,h4.font-bold,header h1{-webkit-text-fill-color:var(--m3-on-surface);font-weight:700;color:var(--m3-on-surface)!important;background:0 0!important}hr{border-color:var(--m3-divider)!important}.bg-white,.dark .dark\:bg-dark,.dark .lg\:dark\:bg-dark,.bg-slate-50,.dark .dark\:bg-gray-900,.dark .dark\:bg-gray-900\/50,.dark .dark\:bg-gray-900\/30{background-color:var(--m3-surface-container-low)!important}.bg-slate-50\/50,.bg-slate-100,.dark .dark\:bg-gray-800,.dark .dark\:bg-gray-800\/50,.dark .dark\:bg-gray-800\/30{background-color:var(--m3-surface-container)!important}details,main>div,.overflow-x-auto.rounded-xl,.space-y-3.bg-slate-100,.flex.items-center.flex-wrap.gap-4{background-color:var(--m3-surface-container)!important;border-color:var(--m3-soft-outline)!important;box-shadow:none!important}.border,.border-2{border-color:var(--m3-outline-variant)!important}.border-b,.border-t,.border-l,.border-r,.lg\:border,.divide-y>:not([hidden])~:not([hidden]){border-color:var(--m3-divider)!important}.shadow-md,.shadow-lg,.lg\:shadow-md,.shadow-inner{box-shadow:var(--m3-shadow)!important}#bodePlot,#timePlot,.js-plotly-plot,:is(.overflow-x-auto:has(#bodePlot),.overflow-x-auto:has(#timePlot)){background-color:var(--m3-surface-container-lowest)!important}.text-slate-900,.text-slate-800,.dark .dark\:text-gray-100,.dark .dark\:text-gray-200{color:var(--m3-on-surface)!important}.text-slate-700,.text-slate-600,.text-slate-500,.text-slate-400,.dark .dark\:text-gray-300,.dark .dark\:text-gray-400,.dark .dark\:text-gray-500{color:var(--m3-on-surface-variant)!important}select,input[type=number],textarea{box-shadow:none;background:var(--m3-surface-container-lowest)!important;border-color:var(--m3-input-outline)!important;color:var(--m3-on-surface)!important;border-radius:12px!important}select:hover,input[type=number]:hover,textarea:hover{border-color:var(--m3-outline)!important}select:focus,input[type=number]:focus,textarea:focus,.role-focus-primary:focus,.role-focus-primary:focus-visible{border-color:var(--m3-primary)!important;box-shadow:0 0 0 3px var(--m3-primary-state)!important}button,[role=button],label.cursor-pointer{font-weight:650;transition:background-color .14s,color .14s,box-shadow .14s,transform .12s;box-shadow:none!important;border-color:#0000!important;border-radius:999px!important}button:hover,[role=button]:hover,label.cursor-pointer:hover{transform:translateY(-1px)}button:active,[role=button]:active,label.cursor-pointer:active{transform:translateY(0)}button.bg-slate-200,button.dark\:bg-gray-800{background:var(--m3-secondary-container)!important;color:var(--m3-on-secondary-container)!important}button.bg-slate-200:hover,button.dark\:bg-gray-800:hover,.hover\:bg-slate-600:hover,.hover\:bg-slate-300:hover,.dark .dark\:hover\:bg-gray-700:hover{background:color-mix(in srgb, var(--m3-secondary-container) 82%, var(--m3-primary) 18%)!important}button.border.bg-white,button.border.bg-slate-200,button.border.dark\:bg-gray-800,label.border.bg-white{border-color:var(--m3-soft-outline)!important}.bg-slate-700{background:var(--m3-secondary)!important;color:var(--m3-on-secondary)!important}.rounded,.rounded-lg,.rounded-xl,details,select,textarea,input[type=number]{border-radius:16px!important}.rounded-full{border-radius:999px!important}input[type=range]{border-radius:999px;height:6px;background:color-mix(in srgb, var(--m3-primary) 22%, var(--m3-surface-container-high))!important}input[type=range]::-webkit-slider-thumb{background:var(--m3-primary);border:3px solid var(--m3-surface-container-lowest);box-shadow:var(--m3-shadow)}.dark input[type=range]::-webkit-slider-thumb{background:var(--m3-primary);border-color:var(--m3-surface-container-lowest)}.custom-scrollbar::-webkit-scrollbar-thumb{background:color-mix(in srgb, var(--m3-outline) 52%, transparent)}tr.bg-slate-50,.hover\:bg-slate-50\/50:hover,.dark .dark\:hover\:bg-gray-800\/30:hover{background-color:var(--m3-surface-container-high)!important}.role-theme-icon{color:var(--m3-tertiary)!important}.role-text-on-fill{color:var(--m3-on-primary)!important}.role-text-primary{color:var(--m3-primary)!important}.role-text-primary-muted{color:color-mix(in srgb, var(--m3-primary) 78%, var(--m3-on-surface-variant))!important}.role-text-secondary{color:var(--m3-secondary)!important}.role-text-secondary-muted{color:color-mix(in srgb, var(--m3-secondary) 76%, var(--m3-on-surface-variant))!important}.role-text-tertiary{color:var(--m3-tertiary)!important}.role-text-tertiary-muted{color:color-mix(in srgb, var(--m3-tertiary) 76%, var(--m3-on-surface-variant))!important}.role-text-warning{color:var(--m3-warning)!important}.role-text-error{color:var(--m3-error)!important}.role-bg-primary,button.role-bg-primary,label.role-bg-primary{background:var(--m3-primary)!important;color:var(--m3-on-primary)!important;box-shadow:var(--m3-shadow)!important}.role-bg-primary:hover,.role-hover-primary:hover{background:color-mix(in srgb, var(--m3-primary) 88%, var(--m3-on-primary) 12%)!important;box-shadow:var(--m3-elevated-shadow)!important}.role-bg-primary-soft{background-color:color-mix(in srgb, var(--m3-primary-container) 76%, var(--m3-surface-container-lowest))!important;border-color:color-mix(in srgb, var(--m3-primary) 28%, var(--m3-outline-variant))!important;color:var(--m3-on-primary-container)!important}.role-hover-primary-soft:hover{background-color:color-mix(in srgb, var(--m3-primary-container) 82%, var(--m3-primary) 18%)!important}.role-bg-secondary-soft{background-color:color-mix(in srgb, var(--m3-secondary-container) 76%, var(--m3-surface-container-lowest))!important;border-color:color-mix(in srgb, var(--m3-secondary) 28%, var(--m3-outline-variant))!important;color:var(--m3-on-secondary-container)!important}.role-hover-secondary-soft:hover{background-color:color-mix(in srgb, var(--m3-secondary-container) 82%, var(--m3-secondary) 18%)!important}.role-bg-tertiary-soft{background-color:color-mix(in srgb, var(--m3-tertiary-container) 76%, var(--m3-surface-container-lowest))!important;border-color:color-mix(in srgb, var(--m3-tertiary) 28%, var(--m3-outline-variant))!important;color:var(--m3-on-tertiary-container)!important}.role-hover-tertiary-soft:hover{background-color:color-mix(in srgb, var(--m3-tertiary-container) 82%, var(--m3-tertiary) 18%)!important}.role-bg-warning-soft{background-color:color-mix(in srgb, var(--m3-warning-container) 66%, var(--m3-surface-container-lowest))!important;border-color:color-mix(in srgb, var(--m3-warning) 30%, var(--m3-outline-variant))!important;color:var(--m3-warning)!important}.role-hover-warning-soft:hover{background-color:color-mix(in srgb, var(--m3-warning-container) 78%, var(--m3-warning) 14%)!important}.role-bg-error-soft{background-color:var(--m3-error-container)!important;color:var(--m3-error)!important}.role-dot-primary{background-color:var(--m3-primary)!important}.role-border-primary,.role-active-border-primary:active{border-color:var(--m3-primary)!important}.role-border-primary-soft{border-color:color-mix(in srgb, var(--m3-primary) 24%, transparent)!important}.role-border-secondary,.role-active-border-secondary:active{border-color:var(--m3-secondary)!important}.role-border-secondary-soft{border-color:color-mix(in srgb, var(--m3-secondary) 24%, transparent)!important}.role-border-tertiary,.role-active-border-tertiary:active{border-color:var(--m3-tertiary)!important}.role-border-tertiary-soft{border-color:color-mix(in srgb, var(--m3-tertiary) 24%, transparent)!important}.role-border-warning-soft{border-color:color-mix(in srgb, var(--m3-warning) 24%, transparent)!important}.role-border-error{border-color:color-mix(in srgb, var(--m3-error) 34%, transparent)!important}.role-ring-primary,.role-active-ring-primary:active,.role-focus-ring-primary{--tw-ring-color:var(--m3-primary-state)!important}.role-ring-secondary,.role-active-ring-secondary:active{--tw-ring-color:var(--m3-secondary-state)!important}.role-active-ring-tertiary:active{--tw-ring-color:var(--m3-tertiary-state)!important}.ring-1{box-shadow:0 0 0 1px var(--m3-primary-state)!important}.role-range-primary{accent-color:var(--m3-primary)}.role-range-secondary{accent-color:var(--m3-secondary)}.role-shadow-primary:hover{box-shadow:var(--m3-elevated-shadow)!important}.role-hover-error:hover{color:color-mix(in srgb, var(--m3-error) 78%, var(--m3-on-surface))!important}.role-surface-gradient{background-image:linear-gradient(135deg, color-mix(in srgb, var(--m3-primary) 7%, transparent), color-mix(in srgb, var(--m3-tertiary) 6%, transparent))!important}details .grid.grid-cols-\[3\.25rem_1fr_3\.25rem\]>div,details .grid.grid-cols-\[2rem_1fr_2rem\] input,details button.touch-none{border-color:var(--m3-soft-outline)!important;background:#fff!important}.dark details .grid.grid-cols-\[3\.25rem_1fr_3\.25rem\]>div,.dark details .grid.grid-cols-\[2rem_1fr_2rem\] input,.dark details button.touch-none{background:var(--m3-surface-container-lowest)!important}details .grid.grid-cols-\[2rem_1fr_2rem\] button{background:var(--m3-secondary-container)!important;color:var(--m3-on-secondary-container)!important}.hover\:bg-slate-100:hover{--tw-bg-opacity:1;background-color:rgb(241 245 249/var(--tw-bg-opacity,1))}.hover\:bg-slate-200:hover{--tw-bg-opacity:1;background-color:rgb(226 232 240/var(--tw-bg-opacity,1))}.hover\:bg-slate-300:hover{--tw-bg-opacity:1;background-color:rgb(203 213 225/var(--tw-bg-opacity,1))}.hover\:bg-slate-50\/50:hover{background-color:#f8fafc80}.hover\:bg-slate-600:hover{--tw-bg-opacity:1;background-color:rgb(71 85 105/var(--tw-bg-opacity,1))}.hover\:text-slate-600:hover{--tw-text-opacity:1;color:rgb(71 85 105/var(--tw-text-opacity,1))}.hover\:text-slate-700:hover{--tw-text-opacity:1;color:rgb(51 65 85/var(--tw-text-opacity,1))}.focus\:ring-1:focus{--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow,0 0 #0000)}.active\:border-slate-400:active{--tw-border-opacity:1;border-color:rgb(148 163 184/var(--tw-border-opacity,1))}.active\:ring-2:active{--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow,0 0 #0000)}.active\:ring-slate-400\/20:active{--tw-ring-color:#94a3b833}.disabled\:cursor-not-allowed:disabled{cursor:not-allowed}.disabled\:opacity-50:disabled{opacity:.5}.dark\:divide-gray-800:is(.dark *)>:not([hidden])~:not([hidden]){--tw-divide-opacity:1;border-color:rgb(31 41 55/var(--tw-divide-opacity,1))}.dark\:border-gray-100:is(.dark *){--tw-border-opacity:1;border-color:rgb(243 244 246/var(--tw-border-opacity,1))}.dark\:border-gray-700:is(.dark *){--tw-border-opacity:1;border-color:rgb(55 65 81/var(--tw-border-opacity,1))}.dark\:border-gray-800:is(.dark *){--tw-border-opacity:1;border-color:rgb(31 41 55/var(--tw-border-opacity,1))}.dark\:bg-\[\#0f0f0f\]:is(.dark *){--tw-bg-opacity:1;background-color:rgb(15 15 15/var(--tw-bg-opacity,1))}.dark\:bg-dark:is(.dark *){--tw-bg-opacity:1;background-color:rgb(18 18 18/var(--tw-bg-opacity,1))}.dark\:bg-darker:is(.dark *){--tw-bg-opacity:1;background-color:rgb(10 10 10/var(--tw-bg-opacity,1))}.dark\:bg-gray-800:is(.dark *){--tw-bg-opacity:1;background-color:rgb(31 41 55/var(--tw-bg-opacity,1))}.dark\:bg-gray-800\/50:is(.dark *){background-color:#1f293780}.dark\:bg-gray-900:is(.dark *){--tw-bg-opacity:1;background-color:rgb(17 24 39/var(--tw-bg-opacity,1))}.dark\:bg-gray-900\/30:is(.dark *){background-color:#1118274d}.dark\:bg-gray-900\/50:is(.dark *){background-color:#11182780}.dark\:bg-white:is(.dark *){--tw-bg-opacity:1;background-color:rgb(255 255 255/var(--tw-bg-opacity,1))}.dark\:text-gray-100:is(.dark *){--tw-text-opacity:1;color:rgb(243 244 246/var(--tw-text-opacity,1))}.dark\:text-gray-200:is(.dark *){--tw-text-opacity:1;color:rgb(229 231 235/var(--tw-text-opacity,1))}.dark\:text-gray-300:is(.dark *){--tw-text-opacity:1;color:rgb(209 213 219/var(--tw-text-opacity,1))}.dark\:text-gray-400:is(.dark *){--tw-text-opacity:1;color:rgb(156 163 175/var(--tw-text-opacity,1))}.dark\:text-gray-500:is(.dark *){--tw-text-opacity:1;color:rgb(107 114 128/var(--tw-text-opacity,1))}.dark\:text-gray-600:is(.dark *){--tw-text-opacity:1;color:rgb(75 85 99/var(--tw-text-opacity,1))}.dark\:hover\:bg-gray-700:hover:is(.dark *){--tw-bg-opacity:1;background-color:rgb(55 65 81/var(--tw-bg-opacity,1))}.dark\:hover\:bg-gray-800\/30:hover:is(.dark *){background-color:#1f29374d}.dark\:hover\:text-gray-200:hover:is(.dark *){--tw-text-opacity:1;color:rgb(229 231 235/var(--tw-text-opacity,1))}.dark\:hover\:text-gray-300:hover:is(.dark *){--tw-text-opacity:1;color:rgb(209 213 219/var(--tw-text-opacity,1))}@media (width>=640px){.sm\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}}@media (width>=1024px){.lg\:block{display:block}.lg\:flex{display:flex}.lg\:hidden{display:none}.lg\:w-96{width:24rem}.lg\:flex-row{flex-direction:row}.lg\:gap-6{gap:1.5rem}.lg\:rounded-xl{border-radius:.75rem}.lg\:border{border-width:1px}.lg\:border-b-0{border-bottom-width:0}.lg\:border-r{border-right-width:1px}.lg\:border-slate-200{--tw-border-opacity:1;border-color:rgb(226 232 240/var(--tw-border-opacity,1))}.lg\:p-1{padding:.25rem}.lg\:p-6{padding:1.5rem}.lg\:shadow-md{--tw-shadow:0 4px 6px -1px #0000001a, 0 2px 4px -2px #0000001a;--tw-shadow-colored:0 4px 6px -1px var(--tw-shadow-color), 0 2px 4px -2px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow,0 0 #0000), var(--tw-ring-shadow,0 0 #0000), var(--tw-shadow)}.lg\:dark\:border-gray-800:is(.dark *){--tw-border-opacity:1;border-color:rgb(31 41 55/var(--tw-border-opacity,1))}.lg\:dark\:bg-dark:is(.dark *){--tw-bg-opacity:1;background-color:rgb(18 18 18/var(--tw-bg-opacity,1))}} +.custom-scrollbar::-webkit-scrollbar{width:6px;height:6px}.custom-scrollbar::-webkit-scrollbar-track{background:0 0}.custom-scrollbar::-webkit-scrollbar-thumb{background:#cbd5e1;border-radius:3px}.dark .custom-scrollbar::-webkit-scrollbar-thumb{background:#374151}.custom-scrollbar::-webkit-scrollbar-thumb:hover{background:#94a3b8}.dark .custom-scrollbar::-webkit-scrollbar-thumb:hover{background:#4b5563}body{font-family:Inter,system-ui,-apple-system,sans-serif;font-size:16px;line-height:1.6}input[type=range]{appearance:none;cursor:pointer;background:#e2e8f0;border-radius:4px;height:8px;transition:background .3s}.dark input[type=range]{background:#374151}input[type=range]::-webkit-slider-thumb{-webkit-appearance:none;cursor:pointer;background:#3b82f6;border:2px solid #fff;border-radius:50%;width:24px;height:24px;transition:background .15s ease-in-out,transform .1s;box-shadow:0 2px 5px #0003}.dark input[type=range]::-webkit-slider-thumb{border:2px solid #1f2937}input[type=range]::-webkit-slider-thumb:hover{background:#2563eb;transform:scale(1.1)}button,select,input[type=number],textarea{min-height:44px}.btn-small{min-height:unset}input[type=number]::-webkit-inner-spin-button{appearance:none;margin:0}input[type=number]::-webkit-outer-spin-button{appearance:none;margin:0}input[type=number]{appearance:textfield}.js-plotly-plot .plotly .modebar-container{width:100%!important;display:block!important;top:-45px!important;left:0!important;right:0!important}.js-plotly-plot .plotly .modebar{padding-right:10px;background:0 0!important;flex-flow:row!important;justify-content:flex-end!important;display:flex!important;position:static!important}.js-plotly-plot .plotly .modebar-group{flex-direction:row!important;display:flex!important}#bodePlot,#timePlot{margin-top:50px}@media (width<=1024px){.js-plotly-plot .plotly .modebar-container{top:-40px!important}}details>summary{-webkit-user-select:none;user-select:none;list-style:none}details>summary::-webkit-details-marker{display:none}details>div{animation:.2s ease-out slideDown;overflow:hidden}@keyframes slideDown{0%{opacity:0;transform:translateY(-6px)}to{opacity:1;transform:translateY(0)}}*,:before,:after,::backdrop{--tw-border-spacing-x:0;--tw-border-spacing-y:0;--tw-translate-x:0;--tw-translate-y:0;--tw-rotate:0;--tw-skew-x:0;--tw-skew-y:0;--tw-scale-x:1;--tw-scale-y:1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness:proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-color:#3b82f680;--tw-ring-offset-shadow:0 0 #0000;--tw-ring-shadow:0 0 #0000;--tw-shadow:0 0 #0000;--tw-shadow-colored:0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: ;--tw-contain-size: ;--tw-contain-layout: ;--tw-contain-paint: ;--tw-contain-style: }*,:before,:after{box-sizing:border-box;border:0 solid #e5e7eb}:before,:after{--tw-content:""}html,:host{-webkit-text-size-adjust:100%;tab-size:4;font-feature-settings:normal;font-variation-settings:normal;-webkit-tap-highlight-color:transparent;font-family:ui-sans-serif,system-ui,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol,Noto Color Emoji;line-height:1.5}body{line-height:inherit;margin:0}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;-webkit-text-decoration:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,samp,pre{font-feature-settings:normal;font-variation-settings:normal;font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace;font-size:1em}small{font-size:80%}sub,sup{vertical-align:baseline;font-size:75%;line-height:0;position:relative}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}button,input,optgroup,select,textarea{font-feature-settings:inherit;font-variation-settings:inherit;font-family:inherit;font-size:100%;font-weight:inherit;line-height:inherit;letter-spacing:inherit;color:inherit;margin:0;padding:0}button,select{text-transform:none}button,input:where([type=button]),input:where([type=reset]),input:where([type=submit]){-webkit-appearance:button;background-color:#0000;background-image:none}:-moz-focusring{outline:auto}:-moz-ui-invalid{box-shadow:none}progress{vertical-align:baseline}::-webkit-inner-spin-button{height:auto}::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}summary{display:list-item}blockquote,dl,dd,h1,h2,h3,h4,h5,h6,hr,figure,p,pre{margin:0}fieldset{margin:0;padding:0}legend{padding:0}ol,ul,menu{margin:0;padding:0;list-style:none}dialog{padding:0}textarea{resize:vertical}input::-moz-placeholder{opacity:1;color:#9ca3af}textarea::-moz-placeholder{opacity:1;color:#9ca3af}input::placeholder,textarea::placeholder{opacity:1;color:#9ca3af}button,[role=button]{cursor:pointer}:disabled{cursor:default}img,svg,video,canvas,audio,iframe,embed,object{vertical-align:middle;display:block}img,video{max-width:100%;height:auto}[hidden]:where(:not([hidden=until-found])){display:none}.pointer-events-none{pointer-events:none}.fixed{position:fixed}.absolute{position:absolute}.relative{position:relative}.inset-0{inset:0}.right-6{right:1.5rem}.top-4{top:1rem}.z-10{z-index:10}.z-20{z-index:20}.z-50{z-index:50}.mx-2{margin-left:.5rem;margin-right:.5rem}.mx-auto{margin-left:auto;margin-right:auto}.mb-1{margin-bottom:.25rem}.mb-2{margin-bottom:.5rem}.mb-3{margin-bottom:.75rem}.mb-4{margin-bottom:1rem}.mb-6{margin-bottom:1.5rem}.ml-2{margin-left:.5rem}.ml-auto{margin-left:auto}.mr-1{margin-right:.25rem}.mt-1{margin-top:.25rem}.mt-2{margin-top:.5rem}.mt-3{margin-top:.75rem}.block{display:block}.flex{display:flex}.table{display:table}.grid{display:grid}.hidden{display:none}.h-10{height:2.5rem}.h-12{height:3rem}.h-2{height:.5rem}.h-4{height:1rem}.h-5{height:1.25rem}.h-8{height:2rem}.h-\[300px\]{height:300px}.h-\[400px\]{height:400px}.h-\[800px\]{height:800px}.h-full{height:100%}.h-screen{height:100vh}.min-h-screen{min-height:100vh}.w-10{width:2.5rem}.w-12{width:3rem}.w-2{width:.5rem}.w-24{width:6rem}.w-28{width:7rem}.w-4{width:1rem}.w-5{width:1.25rem}.w-full{width:100%}.min-w-0{min-width:0}.min-w-\[580px\]{min-width:580px}.max-w-full{max-width:100%}.flex-1{flex:1}.flex-shrink-0{flex-shrink:0}.transform{transform:translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}@keyframes ping{75%,to{opacity:0;transform:scale(2)}}.animate-ping{animation:1s cubic-bezier(0,0,.2,1) infinite ping}@keyframes pulse{50%{opacity:.5}}.animate-pulse{animation:2s cubic-bezier(.4,0,.6,1) infinite pulse}.cursor-pointer{cursor:pointer}.touch-none{touch-action:none}.select-none{-webkit-user-select:none;user-select:none}.resize-none{resize:none}.grid-cols-1{grid-template-columns:repeat(1,minmax(0,1fr))}.grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.grid-cols-\[2rem_1fr_2rem\]{grid-template-columns:2rem 1fr 2rem}.grid-cols-\[3\.25rem_1fr_3\.25rem\]{grid-template-columns:3.25rem 1fr 3.25rem}.flex-col{flex-direction:column}.flex-wrap{flex-wrap:wrap}.items-center{align-items:center}.justify-center{justify-content:center}.justify-between{justify-content:space-between}.gap-0{gap:0}.gap-1{gap:.25rem}.gap-2{gap:.5rem}.gap-3{gap:.75rem}.gap-4{gap:1rem}.gap-5{gap:1.25rem}.space-y-3>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-top:calc(.75rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.75rem * var(--tw-space-y-reverse))}.space-y-4>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-top:calc(1rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(1rem * var(--tw-space-y-reverse))}.divide-y>:not([hidden])~:not([hidden]){--tw-divide-y-reverse:0;border-top-width:calc(1px * calc(1 - var(--tw-divide-y-reverse)));border-bottom-width:calc(1px * var(--tw-divide-y-reverse))}.divide-slate-100>:not([hidden])~:not([hidden]){--tw-divide-opacity:1;border-color:rgb(241 245 249/var(--tw-divide-opacity,1))}.overflow-hidden{overflow:hidden}.overflow-x-auto{overflow-x:auto}.overflow-y-auto{overflow-y:auto}.truncate{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.rounded{border-radius:.25rem}.rounded-lg{border-radius:.5rem}.rounded-xl{border-radius:.75rem}.border{border-width:1px}.border-2{border-width:2px}.border-b{border-bottom-width:1px}.border-b-2{border-bottom-width:2px}.border-l{border-left-width:1px}.border-t{border-top-width:1px}.border-dashed{border-style:dashed}.border-slate-100{--tw-border-opacity:1;border-color:rgb(241 245 249/var(--tw-border-opacity,1))}.border-slate-200{--tw-border-opacity:1;border-color:rgb(226 232 240/var(--tw-border-opacity,1))}.border-slate-300{--tw-border-opacity:1;border-color:rgb(203 213 225/var(--tw-border-opacity,1))}.bg-slate-100{--tw-bg-opacity:1;background-color:rgb(241 245 249/var(--tw-bg-opacity,1))}.bg-slate-200{--tw-bg-opacity:1;background-color:rgb(226 232 240/var(--tw-bg-opacity,1))}.bg-slate-50{--tw-bg-opacity:1;background-color:rgb(248 250 252/var(--tw-bg-opacity,1))}.bg-slate-50\/50{background-color:#f8fafc80}.bg-slate-700{--tw-bg-opacity:1;background-color:rgb(51 65 85/var(--tw-bg-opacity,1))}.bg-white{--tw-bg-opacity:1;background-color:rgb(255 255 255/var(--tw-bg-opacity,1))}.bg-gradient-to-br{background-image:linear-gradient(to bottom right, var(--tw-gradient-stops))}.object-contain{-o-object-fit:contain;object-fit:contain}.\!p-0{padding:0!important}.p-0{padding:0}.p-2{padding:.5rem}.p-3{padding:.75rem}.p-4{padding:1rem}.p-5{padding:1.25rem}.p-6{padding:1.5rem}.px-1\.5{padding-left:.375rem;padding-right:.375rem}.px-2{padding-left:.5rem;padding-right:.5rem}.px-3{padding-left:.75rem;padding-right:.75rem}.px-4{padding-left:1rem;padding-right:1rem}.px-5{padding-left:1.25rem;padding-right:1.25rem}.px-6{padding-left:1.5rem;padding-right:1.5rem}.py-0\.5{padding-top:.125rem;padding-bottom:.125rem}.py-1{padding-top:.25rem;padding-bottom:.25rem}.py-1\.5{padding-top:.375rem;padding-bottom:.375rem}.py-2{padding-top:.5rem;padding-bottom:.5rem}.py-2\.5{padding-top:.625rem;padding-bottom:.625rem}.py-3{padding-top:.75rem;padding-bottom:.75rem}.py-4{padding-top:1rem;padding-bottom:1rem}.pb-3{padding-bottom:.75rem}.text-left{text-align:left}.text-center{text-align:center}.font-mono{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace}.text-\[10px\]{font-size:10px}.text-\[11px\]{font-size:11px}.text-\[9px\]{font-size:9px}.text-base{font-size:1rem;line-height:1.5rem}.text-lg{font-size:1.125rem;line-height:1.75rem}.text-sm{font-size:.875rem;line-height:1.25rem}.text-xl{font-size:1.25rem;line-height:1.75rem}.text-xs{font-size:.75rem;line-height:1rem}.font-bold{font-weight:700}.font-medium{font-weight:500}.font-semibold{font-weight:600}.uppercase{text-transform:uppercase}.italic{font-style:italic}.leading-relaxed{line-height:1.625}.tracking-tight{letter-spacing:-.025em}.tracking-wide{letter-spacing:.025em}.tracking-wider{letter-spacing:.05em}.text-gray-500{--tw-text-opacity:1;color:rgb(107 114 128/var(--tw-text-opacity,1))}.text-slate-400{--tw-text-opacity:1;color:rgb(148 163 184/var(--tw-text-opacity,1))}.text-slate-500{--tw-text-opacity:1;color:rgb(100 116 139/var(--tw-text-opacity,1))}.text-slate-600{--tw-text-opacity:1;color:rgb(71 85 105/var(--tw-text-opacity,1))}.text-slate-700{--tw-text-opacity:1;color:rgb(51 65 85/var(--tw-text-opacity,1))}.text-slate-800{--tw-text-opacity:1;color:rgb(30 41 59/var(--tw-text-opacity,1))}.text-slate-900{--tw-text-opacity:1;color:rgb(15 23 42/var(--tw-text-opacity,1))}.opacity-50{opacity:.5}.shadow-inner{--tw-shadow:inset 0 2px 4px 0 #0000000d;--tw-shadow-colored:inset 0 2px 4px 0 var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow,0 0 #0000), var(--tw-ring-shadow,0 0 #0000), var(--tw-shadow)}.shadow-lg{--tw-shadow:0 10px 15px -3px #0000001a, 0 4px 6px -4px #0000001a;--tw-shadow-colored:0 10px 15px -3px var(--tw-shadow-color), 0 4px 6px -4px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow,0 0 #0000), var(--tw-ring-shadow,0 0 #0000), var(--tw-shadow)}.shadow-md{--tw-shadow:0 4px 6px -1px #0000001a, 0 2px 4px -2px #0000001a;--tw-shadow-colored:0 4px 6px -1px var(--tw-shadow-color), 0 2px 4px -2px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow,0 0 #0000), var(--tw-ring-shadow,0 0 #0000), var(--tw-shadow)}.shadow-sm{--tw-shadow:0 1px 2px 0 #0000000d;--tw-shadow-colored:0 1px 2px 0 var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow,0 0 #0000), var(--tw-ring-shadow,0 0 #0000), var(--tw-shadow)}.outline-none{outline-offset:2px;outline:2px solid #0000}.ring-1{--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow,0 0 #0000)}.blur{--tw-blur:blur(8px);filter:var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow)}.filter{filter:var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow)}.backdrop-blur-sm{--tw-backdrop-blur:blur(4px);-webkit-backdrop-filter:var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia);backdrop-filter:var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia)}.transition-all{transition-property:all;transition-duration:.15s;transition-timing-function:cubic-bezier(.4,0,.2,1)}.transition-colors{transition-property:color,background-color,border-color,text-decoration-color,fill,stroke;transition-duration:.15s;transition-timing-function:cubic-bezier(.4,0,.2,1)}.duration-300{transition-duration:.3s}:root{--m3-primary:#566075;--m3-on-primary:#fff;--m3-primary-container:#d8deef;--m3-on-primary-container:#202637;--m3-secondary:#5e6472;--m3-on-secondary:#fff;--m3-secondary-container:#e1e5f0;--m3-on-secondary-container:#242832;--m3-tertiary:#7a6689;--m3-on-tertiary:#fff;--m3-tertiary-container:#f0dcff;--m3-on-tertiary-container:#30203d;--m3-error:#b3261e;--m3-on-error:#fff;--m3-error-container:#f9dedc;--m3-success:#2e7d61;--m3-success-container:#cceede;--m3-warning:#8c6d1f;--m3-warning-container:#f5e4b2;--m3-accent-cyan:#64d2ff;--m3-accent-pink:#ff9bd8;--m3-accent-orange:#ffb879;--m3-accent-lavender:#b9b2ff;--m3-background:#f6f7fb;--m3-surface:#f6f7fb;--m3-surface-container-lowest:#fff;--m3-surface-container-low:#eff1f7;--m3-surface-container:#e7e9f1;--m3-surface-container-high:#dde1ec;--m3-surface-container-highest:#d1d7e6;--m3-on-surface:#17191f;--m3-on-surface-variant:#525663;--m3-outline:#747987;--m3-outline-variant:#c3c8d4;--m3-divider:color-mix(in srgb, var(--m3-outline-variant) 78%, transparent);--m3-soft-outline:color-mix(in srgb, var(--m3-outline-variant) 88%, transparent);--m3-input-outline:color-mix(in srgb, var(--m3-outline) 82%, transparent);--m3-primary-state:color-mix(in srgb, var(--m3-primary) 14%, transparent);--m3-secondary-state:color-mix(in srgb, var(--m3-secondary) 12%, transparent);--m3-tertiary-state:color-mix(in srgb, var(--m3-tertiary) 12%, transparent);--m3-warning-state:color-mix(in srgb, var(--m3-warning) 12%, transparent);--m3-shadow:0 1px 2px #0f121a1a, 0 8px 18px #0f121a14;--m3-elevated-shadow:0 8px 22px #0f121a1f, 0 18px 36px #0f121a1a;--background:var(--m3-background);--surface:var(--m3-surface-container);--surfaceHigh:var(--m3-surface-container-high);--primary:var(--m3-primary);--onPrimary:var(--m3-on-primary);--textPrimary:var(--m3-on-surface);--textSecondary:var(--m3-on-surface-variant);--border:var(--m3-outline-variant);--danger:var(--m3-error);--success:var(--m3-success);--warning:var(--m3-warning)}.dark{--m3-primary:#c8cee0;--m3-on-primary:#202431;--m3-primary-container:#3f4453;--m3-on-primary-container:#eef1ff;--m3-secondary:#aeb6c9;--m3-on-secondary:#242832;--m3-secondary-container:#343842;--m3-on-secondary-container:#e4e8f6;--m3-tertiary:#d6b7f0;--m3-on-tertiary:#382047;--m3-tertiary-container:#4b3b59;--m3-on-tertiary-container:#f4dcff;--m3-error:#f2b8b5;--m3-on-error:#601410;--m3-error-container:#7d2e29;--m3-success:#9bd7bd;--m3-success-container:#254c3a;--m3-warning:#e6cb7f;--m3-warning-container:#55451f;--m3-accent-cyan:#5fd4ff;--m3-accent-pink:#ff9bd8;--m3-accent-orange:#ffb879;--m3-accent-lavender:#b9b2ff;--m3-background:#111216;--m3-surface:#111216;--m3-surface-container-lowest:#090a0d;--m3-surface-container-low:#1a1b20;--m3-surface-container:#2a2a2e;--m3-surface-container-high:#34353b;--m3-surface-container-highest:#41434b;--m3-on-surface:#f1f1f4;--m3-on-surface-variant:#b4b4bd;--m3-outline:#8b8d98;--m3-outline-variant:#4b4d56;--m3-shadow:0 1px 2px #0000006b, 0 8px 24px #00000057;--m3-elevated-shadow:0 8px 24px #0000007a, 0 24px 48px #0000005c}html,body,#dea-root{background:var(--m3-background);color:var(--m3-on-surface)}body{letter-spacing:0;text-rendering:optimizelegibility;font-family:Google Sans,Roboto,Noto Sans TC,system-ui,-apple-system,sans-serif;font-size:16px;line-height:1.55}#app{background:radial-gradient(circle at 50% 0%, color-mix(in srgb, var(--m3-primary) 10%, transparent), transparent 30rem), var(--m3-background)}header,aside,footer,main>div,section,details,.js-plotly-plot,#bodePlot,#timePlot{color:var(--m3-on-surface)}header.bg-white,header.dark\:bg-dark,footer.bg-white,footer.dark\:bg-dark{background:color-mix(in srgb, var(--m3-background) 82%, var(--m3-surface-container) 18%)!important;border-color:var(--m3-divider)!important;box-shadow:none!important}header{min-height:72px;padding-inline:clamp(1rem,2vw,1.75rem)!important}header img{background:var(--m3-surface-container-high);border-radius:18px!important}header h1{line-height:1.15;font-size:clamp(1.35rem,1.8vw,2rem)!important}aside.bg-white,aside.dark\:bg-dark,main.bg-slate-50,main.dark\:bg-\[\#0f0f0f\]{background:var(--m3-background)!important;border-color:var(--m3-divider)!important}h2,h3,h4,label,summary{color:var(--m3-on-surface-variant)!important}h3.font-bold,h4.font-bold,header h1{-webkit-text-fill-color:var(--m3-on-surface);letter-spacing:0;font-weight:500;color:var(--m3-on-surface)!important;background:0 0!important}h2{letter-spacing:.01em!important;text-transform:none!important;font-size:.95rem!important;font-weight:500!important}h3.font-bold{font-size:clamp(1.15rem,1.35vw,1.45rem)!important}h4.font-bold{font-size:1.05rem!important}hr{border-color:var(--m3-divider)!important}.bg-white,.dark .dark\:bg-dark,.dark .lg\:dark\:bg-dark,.bg-slate-50,.dark .dark\:bg-gray-900,.dark .dark\:bg-gray-900\/50,.dark .dark\:bg-gray-900\/30{background-color:var(--m3-surface-container-low)!important}.bg-slate-50\/50,.bg-slate-100,.dark .dark\:bg-gray-800,.dark .dark\:bg-gray-800\/50,.dark .dark\:bg-gray-800\/30{background-color:var(--m3-surface-container)!important}details,main>div,.overflow-x-auto.rounded-xl,.space-y-3.bg-slate-100,.flex.items-center.flex-wrap.gap-4{background-color:var(--m3-surface-container)!important;border-color:var(--m3-soft-outline)!important;box-shadow:none!important}aside section{border:1px solid var(--m3-soft-outline);border-radius:28px;padding:1.15rem;background:var(--m3-surface-container)!important}main>div{overflow:hidden;border-radius:30px!important}main>div>div:first-child{border-radius:30px 30px 0 0}.border,.border-2{border-color:var(--m3-outline-variant)!important}.border-b,.border-t,.border-l,.border-r,.lg\:border,.divide-y>:not([hidden])~:not([hidden]){border-color:var(--m3-divider)!important}.shadow-md,.shadow-lg,.lg\:shadow-md,.shadow-inner{box-shadow:var(--m3-shadow)!important}#bodePlot,#timePlot,.js-plotly-plot,:is(.overflow-x-auto:has(#bodePlot),.overflow-x-auto:has(#timePlot)){background-color:var(--m3-surface-container-lowest)!important}.text-slate-900,.text-slate-800,.dark .dark\:text-gray-100,.dark .dark\:text-gray-200{color:var(--m3-on-surface)!important}.text-slate-700,.text-slate-600,.text-slate-500,.text-slate-400,.dark .dark\:text-gray-300,.dark .dark\:text-gray-400,.dark .dark\:text-gray-500{color:var(--m3-on-surface-variant)!important}select,input[type=number],textarea{box-shadow:none;background:var(--m3-surface-container-lowest)!important;border-color:var(--m3-input-outline)!important;color:var(--m3-on-surface)!important;border-radius:22px!important}select:hover,input[type=number]:hover,textarea:hover{border-color:var(--m3-outline)!important}select:focus,input[type=number]:focus,textarea:focus,.role-focus-primary:focus,.role-focus-primary:focus-visible{border-color:var(--m3-primary)!important;box-shadow:0 0 0 3px var(--m3-primary-state)!important}button,[role=button],label.cursor-pointer{font-weight:500;transition:background-color .14s,color .14s,box-shadow .14s,transform .12s;box-shadow:none!important;border-color:#0000!important;border-radius:999px!important}button:focus-visible,[role=button]:focus-visible,label.cursor-pointer:focus-visible{outline:3px solid color-mix(in srgb, var(--m3-primary) 42%, transparent);outline-offset:2px}button:hover,[role=button]:hover,label.cursor-pointer:hover{transform:translateY(-1px)}button:active,[role=button]:active,label.cursor-pointer:active{transform:translateY(0)}button.bg-slate-200,button.dark\:bg-gray-800{background:var(--m3-secondary-container)!important;color:var(--m3-on-secondary-container)!important}button.bg-slate-200:hover,button.dark\:bg-gray-800:hover,.hover\:bg-slate-600:hover,.hover\:bg-slate-300:hover,.dark .dark\:hover\:bg-gray-700:hover{background:color-mix(in srgb, var(--m3-secondary-container) 82%, var(--m3-primary) 18%)!important}button.border.bg-white,button.border.bg-slate-200,button.border.dark\:bg-gray-800,label.border.bg-white{border-color:var(--m3-soft-outline)!important}.bg-slate-700{background:var(--m3-secondary)!important;color:var(--m3-on-secondary)!important}.rounded,.rounded-lg,.rounded-xl,details,select,textarea,input[type=number]{border-radius:22px!important}.rounded-full{border-radius:999px!important}input[type=range]{border-radius:999px;height:10px;background:color-mix(in srgb, var(--m3-primary) 28%, var(--m3-surface-container-high))!important}input[type=range]::-webkit-slider-thumb{background:var(--m3-primary);border:4px solid var(--m3-surface-container-lowest);box-shadow:var(--m3-shadow);width:28px;height:28px}.dark input[type=range]::-webkit-slider-thumb{background:var(--m3-primary);border-color:var(--m3-surface-container-lowest)}.custom-scrollbar::-webkit-scrollbar-thumb{background:color-mix(in srgb, var(--m3-outline) 52%, transparent)}tr.bg-slate-50,.hover\:bg-slate-50\/50:hover,.dark .dark\:hover\:bg-gray-800\/30:hover{background-color:var(--m3-surface-container-high)!important}.role-theme-icon{color:var(--m3-tertiary)!important}.role-text-on-fill{color:var(--m3-on-primary)!important}.role-text-primary{color:var(--m3-primary)!important}.role-text-primary-muted{color:color-mix(in srgb, var(--m3-primary) 78%, var(--m3-on-surface-variant))!important}.role-text-secondary{color:var(--m3-secondary)!important}.role-text-secondary-muted{color:color-mix(in srgb, var(--m3-secondary) 76%, var(--m3-on-surface-variant))!important}.role-text-tertiary{color:var(--m3-tertiary)!important}.role-text-tertiary-muted{color:color-mix(in srgb, var(--m3-tertiary) 76%, var(--m3-on-surface-variant))!important}.role-text-warning{color:var(--m3-warning)!important}.role-text-error{color:var(--m3-error)!important}.role-bg-primary,button.role-bg-primary,label.role-bg-primary{background:var(--m3-primary)!important;color:var(--m3-on-primary)!important;box-shadow:var(--m3-shadow)!important}.role-bg-primary:hover,.role-hover-primary:hover{background:color-mix(in srgb, var(--m3-primary) 88%, var(--m3-on-primary) 12%)!important;box-shadow:var(--m3-elevated-shadow)!important}.role-bg-primary-soft{background-color:color-mix(in srgb, var(--m3-primary-container) 76%, var(--m3-surface-container-lowest))!important;border-color:color-mix(in srgb, var(--m3-primary) 28%, var(--m3-outline-variant))!important;color:var(--m3-on-primary-container)!important}.role-hover-primary-soft:hover{background-color:color-mix(in srgb, var(--m3-primary-container) 82%, var(--m3-primary) 18%)!important}.role-bg-secondary-soft{background-color:color-mix(in srgb, var(--m3-secondary-container) 76%, var(--m3-surface-container-lowest))!important;border-color:color-mix(in srgb, var(--m3-secondary) 28%, var(--m3-outline-variant))!important;color:var(--m3-on-secondary-container)!important}.role-hover-secondary-soft:hover{background-color:color-mix(in srgb, var(--m3-secondary-container) 82%, var(--m3-secondary) 18%)!important}.role-bg-tertiary-soft{background-color:color-mix(in srgb, var(--m3-tertiary-container) 76%, var(--m3-surface-container-lowest))!important;border-color:color-mix(in srgb, var(--m3-tertiary) 28%, var(--m3-outline-variant))!important;color:var(--m3-on-tertiary-container)!important}.role-hover-tertiary-soft:hover{background-color:color-mix(in srgb, var(--m3-tertiary-container) 82%, var(--m3-tertiary) 18%)!important}.role-bg-warning-soft{background-color:color-mix(in srgb, var(--m3-warning-container) 66%, var(--m3-surface-container-lowest))!important;border-color:color-mix(in srgb, var(--m3-warning) 30%, var(--m3-outline-variant))!important;color:var(--m3-warning)!important}.role-hover-warning-soft:hover{background-color:color-mix(in srgb, var(--m3-warning-container) 78%, var(--m3-warning) 14%)!important}.role-bg-error-soft{background-color:var(--m3-error-container)!important;color:var(--m3-error)!important}.role-dot-primary{background-color:var(--m3-primary)!important}.role-border-primary,.role-active-border-primary:active{border-color:var(--m3-primary)!important}.role-border-primary-soft{border-color:color-mix(in srgb, var(--m3-primary) 24%, transparent)!important}.role-border-secondary,.role-active-border-secondary:active{border-color:var(--m3-secondary)!important}.role-border-secondary-soft{border-color:color-mix(in srgb, var(--m3-secondary) 24%, transparent)!important}.role-border-tertiary,.role-active-border-tertiary:active{border-color:var(--m3-tertiary)!important}.role-border-tertiary-soft{border-color:color-mix(in srgb, var(--m3-tertiary) 24%, transparent)!important}.role-border-warning-soft{border-color:color-mix(in srgb, var(--m3-warning) 24%, transparent)!important}.role-border-error{border-color:color-mix(in srgb, var(--m3-error) 34%, transparent)!important}.role-ring-primary,.role-active-ring-primary:active,.role-focus-ring-primary{--tw-ring-color:var(--m3-primary-state)!important}.role-ring-secondary,.role-active-ring-secondary:active{--tw-ring-color:var(--m3-secondary-state)!important}.role-active-ring-tertiary:active{--tw-ring-color:var(--m3-tertiary-state)!important}.ring-1{box-shadow:0 0 0 1px var(--m3-primary-state)!important}.role-range-primary{accent-color:var(--m3-primary)}.role-range-secondary{accent-color:var(--m3-secondary)}.role-shadow-primary:hover{box-shadow:var(--m3-elevated-shadow)!important}.role-hover-error:hover{color:color-mix(in srgb, var(--m3-error) 78%, var(--m3-on-surface))!important}.role-surface-gradient{background-image:linear-gradient(135deg, color-mix(in srgb, var(--m3-primary) 7%, transparent), color-mix(in srgb, var(--m3-tertiary) 6%, transparent))!important}details .grid.grid-cols-\[3\.25rem_1fr_3\.25rem\]>div,details .grid.grid-cols-\[2rem_1fr_2rem\] input,details button.touch-none{border-color:var(--m3-soft-outline)!important;background:#fff!important}.dark details .grid.grid-cols-\[3\.25rem_1fr_3\.25rem\]>div,.dark details .grid.grid-cols-\[2rem_1fr_2rem\] input,.dark details button.touch-none{background:var(--m3-surface-container-lowest)!important}details .grid.grid-cols-\[2rem_1fr_2rem\] button{background:var(--m3-secondary-container)!important;color:var(--m3-on-secondary-container)!important}details .grid.grid-cols-\[3\.25rem_1fr_3\.25rem\]>button,details .grid.grid-cols-\[2rem_1fr_2rem\]>button,details button.touch-none{min-height:42px;background:var(--m3-secondary-container)!important;border:1px solid color-mix(in srgb, var(--m3-secondary) 28%, var(--m3-outline-variant))!important;color:var(--m3-on-secondary-container)!important;border-radius:999px!important}details .grid.grid-cols-\[3\.25rem_1fr_3\.25rem\]>button:hover,details .grid.grid-cols-\[2rem_1fr_2rem\]>button:hover,details button.touch-none:hover{background:color-mix(in srgb, var(--m3-secondary-container) 82%, var(--m3-primary) 18%)!important;color:var(--m3-on-secondary-container)!important}details .grid.grid-cols-\[3\.25rem_1fr_3\.25rem\]>div,details .grid.grid-cols-\[2rem_1fr_2rem\] input,details button.touch-none,details .grid.grid-cols-2.gap-2>div{background:var(--m3-surface-container-lowest)!important;border-color:var(--m3-soft-outline)!important}details .grid.grid-cols-\[2rem_1fr_2rem\] input,details button.touch-none span.font-mono,details .grid.grid-cols-2.gap-2>div span.font-mono{-webkit-text-fill-color:var(--m3-on-surface);color:var(--m3-on-surface)!important}details .grid.grid-cols-\[3\.25rem_1fr_3\.25rem\]>div span.font-mono{-webkit-text-fill-color:var(--m3-on-secondary-container);color:var(--m3-on-secondary-container)!important}details .grid.grid-cols-\[2rem_1fr_2rem\] input:focus{border-color:var(--m3-primary)!important;box-shadow:0 0 0 3px var(--m3-primary-state)!important}.grid.grid-cols-\[3\.25rem_1fr_3\.25rem\]>button,.grid.grid-cols-\[2rem_1fr_2rem\]>button,button.touch-none{min-height:42px;background:var(--m3-secondary-container)!important;border:1px solid color-mix(in srgb, var(--m3-secondary) 28%, var(--m3-outline-variant))!important;color:var(--m3-on-secondary-container)!important;letter-spacing:0!important;border-radius:999px!important;font-size:.875rem!important;font-weight:500!important}.grid.grid-cols-\[3\.25rem_1fr_3\.25rem\]>button:hover,.grid.grid-cols-\[2rem_1fr_2rem\]>button:hover,button.touch-none:hover{background:color-mix(in srgb, var(--m3-secondary-container) 82%, var(--m3-primary) 18%)!important;color:var(--m3-on-secondary-container)!important}.grid.grid-cols-\[2rem_1fr_2rem\]>input,button.touch-none,.grid.grid-cols-\[3\.25rem_1fr_3\.25rem\]>div{background:var(--m3-surface-container-lowest)!important;border-color:var(--m3-soft-outline)!important}.grid.grid-cols-\[2rem_1fr_2rem\]>input,button.touch-none span.font-mono,.grid.grid-cols-\[3\.25rem_1fr_3\.25rem\] span.font-mono,.grid.grid-cols-2.gap-2 span.font-mono{-webkit-text-fill-color:var(--m3-on-surface);color:var(--m3-on-surface)!important;font-weight:500!important}.grid.grid-cols-\[3\.25rem_1fr_3\.25rem\] span:not(.font-mono),.grid.grid-cols-2.gap-2 span:not(.font-mono){font-weight:400!important}.grid.grid-cols-\[2rem_1fr_2rem\]>input{text-align:center;min-height:42px;font-size:.95rem!important}.grid.grid-cols-\[2rem_1fr_2rem\]>input:focus{border-color:var(--m3-primary)!important;box-shadow:0 0 0 3px var(--m3-primary-state)!important}#app .font-bold,#app .font-semibold,#app strong,#app b{font-weight:500!important}#app label,#app summary,#app p,#app span{letter-spacing:0!important}#app section .flex.flex-wrap.gap-1.mb-2>div,#app section .grid.grid-cols-2.gap-2>div,#app section .grid.grid-cols-\[3\.25rem_1fr_3\.25rem\]>div,#app section button.touch-none{background:var(--m3-surface-container-lowest)!important;border-color:var(--m3-soft-outline)!important;color:var(--m3-on-surface)!important}#app section .flex.flex-wrap.gap-1.mb-2>div span,#app section .grid.grid-cols-2.gap-2>div span,#app section .grid.grid-cols-\[3\.25rem_1fr_3\.25rem\]>div span,#app section button.touch-none span{-webkit-text-fill-color:var(--m3-on-surface);color:var(--m3-on-surface)!important;font-weight:500!important}#app section .flex.flex-wrap.gap-1.mb-2>div span:first-child,#app section .grid.grid-cols-2.gap-2>div span:first-child,#app section .grid.grid-cols-\[3\.25rem_1fr_3\.25rem\]>div span:first-child,#app section button.touch-none span:first-child{-webkit-text-fill-color:var(--m3-on-surface-variant);color:var(--m3-on-surface-variant)!important;font-weight:400!important}.hover\:bg-slate-100:hover{--tw-bg-opacity:1;background-color:rgb(241 245 249/var(--tw-bg-opacity,1))}.hover\:bg-slate-200:hover{--tw-bg-opacity:1;background-color:rgb(226 232 240/var(--tw-bg-opacity,1))}.hover\:bg-slate-300:hover{--tw-bg-opacity:1;background-color:rgb(203 213 225/var(--tw-bg-opacity,1))}.hover\:bg-slate-50\/50:hover{background-color:#f8fafc80}.hover\:bg-slate-600:hover{--tw-bg-opacity:1;background-color:rgb(71 85 105/var(--tw-bg-opacity,1))}.hover\:text-slate-600:hover{--tw-text-opacity:1;color:rgb(71 85 105/var(--tw-text-opacity,1))}.hover\:text-slate-700:hover{--tw-text-opacity:1;color:rgb(51 65 85/var(--tw-text-opacity,1))}.focus\:ring-1:focus{--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow,0 0 #0000)}.active\:border-slate-400:active{--tw-border-opacity:1;border-color:rgb(148 163 184/var(--tw-border-opacity,1))}.active\:ring-2:active{--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow,0 0 #0000)}.active\:ring-slate-400\/20:active{--tw-ring-color:#94a3b833}.disabled\:cursor-not-allowed:disabled{cursor:not-allowed}.disabled\:opacity-50:disabled{opacity:.5}.dark\:divide-gray-800:is(.dark *)>:not([hidden])~:not([hidden]){--tw-divide-opacity:1;border-color:rgb(31 41 55/var(--tw-divide-opacity,1))}.dark\:border-gray-100:is(.dark *){--tw-border-opacity:1;border-color:rgb(243 244 246/var(--tw-border-opacity,1))}.dark\:border-gray-700:is(.dark *){--tw-border-opacity:1;border-color:rgb(55 65 81/var(--tw-border-opacity,1))}.dark\:border-gray-800:is(.dark *){--tw-border-opacity:1;border-color:rgb(31 41 55/var(--tw-border-opacity,1))}.dark\:bg-\[\#0f0f0f\]:is(.dark *){--tw-bg-opacity:1;background-color:rgb(15 15 15/var(--tw-bg-opacity,1))}.dark\:bg-dark:is(.dark *){--tw-bg-opacity:1;background-color:rgb(18 18 18/var(--tw-bg-opacity,1))}.dark\:bg-darker:is(.dark *){--tw-bg-opacity:1;background-color:rgb(10 10 10/var(--tw-bg-opacity,1))}.dark\:bg-gray-800:is(.dark *){--tw-bg-opacity:1;background-color:rgb(31 41 55/var(--tw-bg-opacity,1))}.dark\:bg-gray-800\/50:is(.dark *){background-color:#1f293780}.dark\:bg-gray-900:is(.dark *){--tw-bg-opacity:1;background-color:rgb(17 24 39/var(--tw-bg-opacity,1))}.dark\:bg-gray-900\/30:is(.dark *){background-color:#1118274d}.dark\:bg-gray-900\/50:is(.dark *){background-color:#11182780}.dark\:bg-white:is(.dark *){--tw-bg-opacity:1;background-color:rgb(255 255 255/var(--tw-bg-opacity,1))}.dark\:text-gray-100:is(.dark *){--tw-text-opacity:1;color:rgb(243 244 246/var(--tw-text-opacity,1))}.dark\:text-gray-200:is(.dark *){--tw-text-opacity:1;color:rgb(229 231 235/var(--tw-text-opacity,1))}.dark\:text-gray-300:is(.dark *){--tw-text-opacity:1;color:rgb(209 213 219/var(--tw-text-opacity,1))}.dark\:text-gray-400:is(.dark *){--tw-text-opacity:1;color:rgb(156 163 175/var(--tw-text-opacity,1))}.dark\:text-gray-500:is(.dark *){--tw-text-opacity:1;color:rgb(107 114 128/var(--tw-text-opacity,1))}.dark\:text-gray-600:is(.dark *){--tw-text-opacity:1;color:rgb(75 85 99/var(--tw-text-opacity,1))}.dark\:hover\:bg-gray-700:hover:is(.dark *){--tw-bg-opacity:1;background-color:rgb(55 65 81/var(--tw-bg-opacity,1))}.dark\:hover\:bg-gray-800\/30:hover:is(.dark *){background-color:#1f29374d}.dark\:hover\:text-gray-200:hover:is(.dark *){--tw-text-opacity:1;color:rgb(229 231 235/var(--tw-text-opacity,1))}.dark\:hover\:text-gray-300:hover:is(.dark *){--tw-text-opacity:1;color:rgb(209 213 219/var(--tw-text-opacity,1))}@media (width>=640px){.sm\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}}@media (width>=1024px){.lg\:block{display:block}.lg\:flex{display:flex}.lg\:hidden{display:none}.lg\:w-96{width:24rem}.lg\:flex-row{flex-direction:row}.lg\:gap-6{gap:1.5rem}.lg\:rounded-xl{border-radius:.75rem}.lg\:border{border-width:1px}.lg\:border-b-0{border-bottom-width:0}.lg\:border-r{border-right-width:1px}.lg\:border-slate-200{--tw-border-opacity:1;border-color:rgb(226 232 240/var(--tw-border-opacity,1))}.lg\:p-1{padding:.25rem}.lg\:p-6{padding:1.5rem}.lg\:shadow-md{--tw-shadow:0 4px 6px -1px #0000001a, 0 2px 4px -2px #0000001a;--tw-shadow-colored:0 4px 6px -1px var(--tw-shadow-color), 0 2px 4px -2px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow,0 0 #0000), var(--tw-ring-shadow,0 0 #0000), var(--tw-shadow)}.lg\:dark\:border-gray-800:is(.dark *){--tw-border-opacity:1;border-color:rgb(31 41 55/var(--tw-border-opacity,1))}.lg\:dark\:bg-dark:is(.dark *){--tw-bg-opacity:1;background-color:rgb(18 18 18/var(--tw-bg-opacity,1))}} diff --git a/static/build/app.js b/static/build/app.js index 7b5b676..cb0b964 100644 --- a/static/build/app.js +++ b/static/build/app.js @@ -1,3 +1,3 @@ -(function(){let e=document.createElement(`link`).relList;if(e&&e.supports&&e.supports(`modulepreload`))return;for(let e of document.querySelectorAll(`link[rel="modulepreload"]`))n(e);new MutationObserver(e=>{for(let t of e)if(t.type===`childList`)for(let e of t.addedNodes)e.tagName===`LINK`&&e.rel===`modulepreload`&&n(e)}).observe(document,{childList:!0,subtree:!0});function t(e){let t={};return e.integrity&&(t.integrity=e.integrity),e.referrerPolicy&&(t.referrerPolicy=e.referrerPolicy),e.crossOrigin===`use-credentials`?t.credentials=`include`:e.crossOrigin===`anonymous`?t.credentials=`omit`:t.credentials=`same-origin`,t}function n(e){if(e.ep)return;e.ep=!0;let n=t(e);fetch(e.href,n)}})();function e(e){let t=Object.create(null);for(let n of e.split(`,`))t[n]=1;return e=>e in t}var t={},n=[],r=()=>{},i=()=>!1,a=e=>e.charCodeAt(0)===111&&e.charCodeAt(1)===110&&(e.charCodeAt(2)>122||e.charCodeAt(2)<97),o=e=>e.startsWith(`onUpdate:`),s=Object.assign,c=(e,t)=>{let n=e.indexOf(t);n>-1&&e.splice(n,1)},l=Object.prototype.hasOwnProperty,u=(e,t)=>l.call(e,t),d=Array.isArray,f=e=>x(e)===`[object Map]`,p=e=>x(e)===`[object Set]`,m=e=>x(e)===`[object Date]`,h=e=>typeof e==`function`,g=e=>typeof e==`string`,_=e=>typeof e==`symbol`,v=e=>typeof e==`object`&&!!e,y=e=>(v(e)||h(e))&&h(e.then)&&h(e.catch),b=Object.prototype.toString,x=e=>b.call(e),S=e=>x(e).slice(8,-1),C=e=>x(e)===`[object Object]`,w=e=>g(e)&&e!==`NaN`&&e[0]!==`-`&&``+parseInt(e,10)===e,ee=e(`,key,ref,ref_for,ref_key,onVnodeBeforeMount,onVnodeMounted,onVnodeBeforeUpdate,onVnodeUpdated,onVnodeBeforeUnmount,onVnodeUnmounted`),te=e=>{let t=Object.create(null);return(n=>t[n]||(t[n]=e(n)))},ne=/-\w/g,T=te(e=>e.replace(ne,e=>e.slice(1).toUpperCase())),re=/\B([A-Z])/g,E=te(e=>e.replace(re,`-$1`).toLowerCase()),ie=te(e=>e.charAt(0).toUpperCase()+e.slice(1)),ae=te(e=>e?`on${ie(e)}`:``),D=(e,t)=>!Object.is(e,t),oe=(e,...t)=>{for(let n=0;n{Object.defineProperty(e,t,{configurable:!0,enumerable:!1,writable:r,value:n})},se=e=>{let t=parseFloat(e);return isNaN(t)?e:t},ce,le=()=>ce||=typeof globalThis<`u`?globalThis:typeof self<`u`?self:typeof window<`u`?window:typeof global<`u`?global:{};function ue(e){if(d(e)){let t={};for(let n=0;n{if(e){let n=e.split(fe);n.length>1&&(t[n[0].trim()]=n[1].trim())}}),t}function k(e){let t=``;if(g(e))t=e;else if(d(e))for(let n=0;nye(e,t))}var xe=e=>!!(e&&e.__v_isRef===!0),A=e=>g(e)?e:e==null?``:d(e)||v(e)&&(e.toString===b||!h(e.toString))?xe(e)?A(e.value):JSON.stringify(e,Se,2):String(e),Se=(e,t)=>xe(t)?Se(e,t.value):f(t)?{[`Map(${t.size})`]:[...t.entries()].reduce((e,[t,n],r)=>(e[Ce(t,r)+` =>`]=n,e),{})}:p(t)?{[`Set(${t.size})`]:[...t.values()].map(e=>Ce(e))}:_(t)?Ce(t):v(t)&&!d(t)&&!C(t)?String(t):t,Ce=(e,t=``)=>_(e)?`Symbol(${e.description??t})`:e,j,we=class{constructor(e=!1){this.detached=e,this._active=!0,this._on=0,this.effects=[],this.cleanups=[],this._isPaused=!1,this._warnOnRun=!0,this.__v_skip=!0,!e&&j&&(j.active?(this.parent=j,this.index=(j.scopes||=[]).push(this)-1):(this._active=!1,this._warnOnRun=!1))}get active(){return this._active}pause(){if(this._active){this._isPaused=!0;let e,t;if(this.scopes)for(e=0,t=this.scopes.length;e0&&--this._on===0){if(j===this)j=this.prevScope;else{let e=j;for(;e;){if(e.prevScope===this){e.prevScope=this.prevScope;break}e=e.prevScope}}this.prevScope=void 0}}stop(e){if(this._active){this._active=!1;let t,n;for(t=0,n=this.effects.length;t0)return;if(Ae){let e=Ae;for(Ae=void 0;e;){let t=e.next;e.next=void 0,e.flags&=-9,e=t}}let e;for(;ke;){let t=ke;for(ke=void 0;t;){let n=t.next;if(t.next=void 0,t.flags&=-9,t.flags&1)try{t.trigger()}catch(t){e||=t}t=n}}if(e)throw e}function Pe(e){for(let t=e.deps;t;t=t.nextDep)t.version=-1,t.prevActiveLink=t.dep.activeLink,t.dep.activeLink=t}function Fe(e){let t,n=e.depsTail,r=n;for(;r;){let e=r.prevDep;r.version===-1?(r===n&&(n=e),Re(r),ze(r)):t=r,r.dep.activeLink=r.prevActiveLink,r.prevActiveLink=void 0,r=e}e.deps=t,e.depsTail=n}function Ie(e){for(let t=e.deps;t;t=t.nextDep)if(t.dep.version!==t.version||t.dep.computed&&(Le(t.dep.computed)||t.dep.version!==t.version))return!0;return!!e._dirty}function Le(e){if(e.flags&4&&!(e.flags&16)||(e.flags&=-17,e.globalVersion===We)||(e.globalVersion=We,!e.isSSR&&e.flags&128&&(!e.deps&&!e._dirty||!Ie(e))))return;e.flags|=2;let t=e.dep,n=M,r=N;M=e,N=!0;try{Pe(e);let n=e.fn(e._value);(t.version===0||D(n,e._value))&&(e.flags|=128,e._value=n,t.version++)}catch(e){throw t.version++,e}finally{M=n,N=r,Fe(e),e.flags&=-3}}function Re(e,t=!1){let{dep:n,prevSub:r,nextSub:i}=e;if(r&&(r.nextSub=i,e.prevSub=void 0),i&&(i.prevSub=r,e.nextSub=void 0),n.subs===e&&(n.subs=r,!r&&n.computed)){n.computed.flags&=-5;for(let e=n.computed.deps;e;e=e.nextDep)Re(e,!0)}!t&&!--n.sc&&n.map&&n.map.delete(n.key)}function ze(e){let{prevDep:t,nextDep:n}=e;t&&(t.nextDep=n,e.prevDep=void 0),n&&(n.prevDep=t,e.nextDep=void 0)}var N=!0,Be=[];function Ve(){Be.push(N),N=!1}function He(){let e=Be.pop();N=e===void 0?!0:e}function Ue(e){let{cleanup:t}=e;if(e.cleanup=void 0,t){let e=M;M=void 0;try{t()}finally{M=e}}}var We=0,Ge=class{constructor(e,t){this.sub=e,this.dep=t,this.version=t.version,this.nextDep=this.prevDep=this.nextSub=this.prevSub=this.prevActiveLink=void 0}},Ke=class{constructor(e){this.computed=e,this.version=0,this.activeLink=void 0,this.subs=void 0,this.map=void 0,this.key=void 0,this.sc=0,this.__v_skip=!0}track(e){if(!M||!N||M===this.computed)return;let t=this.activeLink;if(t===void 0||t.sub!==M)t=this.activeLink=new Ge(M,this),M.deps?(t.prevDep=M.depsTail,M.depsTail.nextDep=t,M.depsTail=t):M.deps=M.depsTail=t,qe(t);else if(t.version===-1&&(t.version=this.version,t.nextDep)){let e=t.nextDep;e.prevDep=t.prevDep,t.prevDep&&(t.prevDep.nextDep=e),t.prevDep=M.depsTail,t.nextDep=void 0,M.depsTail.nextDep=t,M.depsTail=t,M.deps===t&&(M.deps=e)}return t}trigger(e){this.version++,We++,this.notify(e)}notify(e){Me();try{for(let e=this.subs;e;e=e.prevSub)e.sub.notify()&&e.sub.dep.notify()}finally{Ne()}}};function qe(e){if(e.dep.sc++,e.sub.flags&4){let t=e.dep.computed;if(t&&!e.dep.subs){t.flags|=20;for(let e=t.deps;e;e=e.nextDep)qe(e)}let n=e.dep.subs;n!==e&&(e.prevSub=n,n&&(n.nextSub=e)),e.dep.subs=e}}var Je=new WeakMap,Ye=Symbol(``),Xe=Symbol(``),Ze=Symbol(``);function P(e,t,n){if(N&&M){let t=Je.get(e);t||Je.set(e,t=new Map);let r=t.get(n);r||(t.set(n,r=new Ke),r.map=t,r.key=n),r.track()}}function Qe(e,t,n,r,i,a){let o=Je.get(e);if(!o){We++;return}let s=e=>{e&&e.trigger()};if(Me(),t===`clear`)o.forEach(s);else{let i=d(e),a=i&&w(n);if(i&&n===`length`){let e=Number(r);o.forEach((t,n)=>{(n===`length`||n===Ze||!_(n)&&n>=e)&&s(t)})}else switch((n!==void 0||o.has(void 0))&&s(o.get(n)),a&&s(o.get(Ze)),t){case`add`:i?a&&s(o.get(`length`)):(s(o.get(Ye)),f(e)&&s(o.get(Xe)));break;case`delete`:i||(s(o.get(Ye)),f(e)&&s(o.get(Xe)));break;case`set`:f(e)&&s(o.get(Ye));break}}Ne()}function $e(e){let t=I(e);return t===e?t:(P(t,`iterate`,Ze),F(e)?t:t.map(Vt))}function et(e){return P(e=I(e),`iterate`,Ze),e}function tt(e,t){return Rt(e)?Ht(Lt(e)?Vt(t):t):Vt(t)}var nt={__proto__:null,[Symbol.iterator](){return rt(this,Symbol.iterator,e=>tt(this,e))},concat(...e){return $e(this).concat(...e.map(e=>d(e)?$e(e):e))},entries(){return rt(this,`entries`,e=>(e[1]=tt(this,e[1]),e))},every(e,t){return at(this,`every`,e,t,void 0,arguments)},filter(e,t){return at(this,`filter`,e,t,e=>e.map(e=>tt(this,e)),arguments)},find(e,t){return at(this,`find`,e,t,e=>tt(this,e),arguments)},findIndex(e,t){return at(this,`findIndex`,e,t,void 0,arguments)},findLast(e,t){return at(this,`findLast`,e,t,e=>tt(this,e),arguments)},findLastIndex(e,t){return at(this,`findLastIndex`,e,t,void 0,arguments)},forEach(e,t){return at(this,`forEach`,e,t,void 0,arguments)},includes(...e){return st(this,`includes`,e)},indexOf(...e){return st(this,`indexOf`,e)},join(e){return $e(this).join(e)},lastIndexOf(...e){return st(this,`lastIndexOf`,e)},map(e,t){return at(this,`map`,e,t,void 0,arguments)},pop(){return ct(this,`pop`)},push(...e){return ct(this,`push`,e)},reduce(e,...t){return ot(this,`reduce`,e,t)},reduceRight(e,...t){return ot(this,`reduceRight`,e,t)},shift(){return ct(this,`shift`)},some(e,t){return at(this,`some`,e,t,void 0,arguments)},splice(...e){return ct(this,`splice`,e)},toReversed(){return $e(this).toReversed()},toSorted(e){return $e(this).toSorted(e)},toSpliced(...e){return $e(this).toSpliced(...e)},unshift(...e){return ct(this,`unshift`,e)},values(){return rt(this,`values`,e=>tt(this,e))}};function rt(e,t,n){let r=et(e),i=r[t]();return r!==e&&!F(e)&&(i._next=i.next,i.next=()=>{let e=i._next();return e.done||(e.value=n(e.value)),e}),i}var it=Array.prototype;function at(e,t,n,r,i,a){let o=et(e),s=o!==e&&!F(e),c=o[t];if(c!==it[t]){let t=c.apply(e,a);return s?Vt(t):t}let l=n;o!==e&&(s?l=function(t,r){return n.call(this,tt(e,t),r,e)}:n.length>2&&(l=function(t,r){return n.call(this,t,r,e)}));let u=c.call(o,l,r);return s&&i?i(u):u}function ot(e,t,n,r){let i=et(e),a=i!==e&&!F(e),o=n,s=!1;i!==e&&(a?(s=r.length===0,o=function(t,r,i){return s&&(s=!1,t=tt(e,t)),n.call(this,t,tt(e,r),i,e)}):n.length>3&&(o=function(t,r,i){return n.call(this,t,r,i,e)}));let c=i[t](o,...r);return s?tt(e,c):c}function st(e,t,n){let r=I(e);P(r,`iterate`,Ze);let i=r[t](...n);return(i===-1||i===!1)&&zt(n[0])?(n[0]=I(n[0]),r[t](...n)):i}function ct(e,t,n=[]){Ve(),Me();let r=I(e)[t].apply(e,n);return Ne(),He(),r}var lt=e(`__proto__,__v_isRef,__isVue`),ut=new Set(Object.getOwnPropertyNames(Symbol).filter(e=>e!==`arguments`&&e!==`caller`).map(e=>Symbol[e]).filter(_));function dt(e){_(e)||(e=String(e));let t=I(this);return P(t,`has`,e),t.hasOwnProperty(e)}var ft=class{constructor(e=!1,t=!1){this._isReadonly=e,this._isShallow=t}get(e,t,n){if(t===`__v_skip`)return e.__v_skip;let r=this._isReadonly,i=this._isShallow;if(t===`__v_isReactive`)return!r;if(t===`__v_isReadonly`)return r;if(t===`__v_isShallow`)return i;if(t===`__v_raw`)return n===(r?i?At:kt:i?Ot:Dt).get(e)||Object.getPrototypeOf(e)===Object.getPrototypeOf(n)?e:void 0;let a=d(e);if(!r){let e;if(a&&(e=nt[t]))return e;if(t===`hasOwnProperty`)return dt}let o=Reflect.get(e,t,L(e)?e:n);if((_(t)?ut.has(t):lt(t))||(r||P(e,`get`,t),i))return o;if(L(o)){let e=a&&w(t)?o:o.value;return r&&v(e)?Ft(e):e}return v(o)?r?Ft(o):Nt(o):o}},pt=class extends ft{constructor(e=!1){super(!1,e)}set(e,t,n,r){let i=e[t],a=d(e)&&w(t);if(!this._isShallow){let e=Rt(i);if(!F(n)&&!Rt(n)&&(i=I(i),n=I(n)),!a&&L(i)&&!L(n))return e||(i.value=n),!0}let o=a?Number(t)e,yt=e=>Reflect.getPrototypeOf(e);function bt(e,t,n){return function(...r){let i=this.__v_raw,a=I(i),o=f(a),c=e===`entries`||e===Symbol.iterator&&o,l=e===`keys`&&o,u=i[e](...r),d=n?vt:t?Ht:Vt;return!t&&P(a,`iterate`,l?Xe:Ye),s(Object.create(u),{next(){let{value:e,done:t}=u.next();return t?{value:e,done:t}:{value:c?[d(e[0]),d(e[1])]:d(e),done:t}}})}}function xt(e){return function(...t){return e===`delete`?!1:e===`clear`?void 0:this}}function St(e,t){let n={get(n){let r=this.__v_raw,i=I(r),a=I(n);e||(D(n,a)&&P(i,`get`,n),P(i,`get`,a));let{has:o}=yt(i),s=t?vt:e?Ht:Vt;if(o.call(i,n))return s(r.get(n));if(o.call(i,a))return s(r.get(a));r!==i&&r.get(n)},get size(){let t=this.__v_raw;return!e&&P(I(t),`iterate`,Ye),t.size},has(t){let n=this.__v_raw,r=I(n),i=I(t);return e||(D(t,i)&&P(r,`has`,t),P(r,`has`,i)),t===i?n.has(t):n.has(t)||n.has(i)},forEach(n,r){let i=this,a=i.__v_raw,o=I(a),s=t?vt:e?Ht:Vt;return!e&&P(o,`iterate`,Ye),a.forEach((e,t)=>n.call(r,s(e),s(t),i))}};return s(n,e?{add:xt(`add`),set:xt(`set`),delete:xt(`delete`),clear:xt(`clear`)}:{add(e){let n=I(this),r=yt(n),i=I(e),a=!t&&!F(e)&&!Rt(e)?i:e;return r.has.call(n,a)||D(e,a)&&r.has.call(n,e)||D(i,a)&&r.has.call(n,i)||(n.add(a),Qe(n,`add`,a,a)),this},set(e,n){!t&&!F(n)&&!Rt(n)&&(n=I(n));let r=I(this),{has:i,get:a}=yt(r),o=i.call(r,e);o||=(e=I(e),i.call(r,e));let s=a.call(r,e);return r.set(e,n),o?D(n,s)&&Qe(r,`set`,e,n,s):Qe(r,`add`,e,n),this},delete(e){let t=I(this),{has:n,get:r}=yt(t),i=n.call(t,e);i||=(e=I(e),n.call(t,e));let a=r?r.call(t,e):void 0,o=t.delete(e);return i&&Qe(t,`delete`,e,void 0,a),o},clear(){let e=I(this),t=e.size!==0,n=e.clear();return t&&Qe(e,`clear`,void 0,void 0,void 0),n}}),[`keys`,`values`,`entries`,Symbol.iterator].forEach(r=>{n[r]=bt(r,e,t)}),n}function Ct(e,t){let n=St(e,t);return(t,r,i)=>r===`__v_isReactive`?!e:r===`__v_isReadonly`?e:r===`__v_raw`?t:Reflect.get(u(n,r)&&r in t?n:t,r,i)}var wt={get:Ct(!1,!1)},Tt={get:Ct(!1,!0)},Et={get:Ct(!0,!1)},Dt=new WeakMap,Ot=new WeakMap,kt=new WeakMap,At=new WeakMap;function jt(e){switch(e){case`Object`:case`Array`:return 1;case`Map`:case`Set`:case`WeakMap`:case`WeakSet`:return 2;default:return 0}}function Mt(e){return e.__v_skip||!Object.isExtensible(e)?0:jt(S(e))}function Nt(e){return Rt(e)?e:It(e,!1,ht,wt,Dt)}function Pt(e){return It(e,!1,_t,Tt,Ot)}function Ft(e){return It(e,!0,gt,Et,kt)}function It(e,t,n,r,i){if(!v(e)||e.__v_raw&&!(t&&e.__v_isReactive))return e;let a=Mt(e);if(a===0)return e;let o=i.get(e);if(o)return o;let s=new Proxy(e,a===2?r:n);return i.set(e,s),s}function Lt(e){return Rt(e)?Lt(e.__v_raw):!!(e&&e.__v_isReactive)}function Rt(e){return!!(e&&e.__v_isReadonly)}function F(e){return!!(e&&e.__v_isShallow)}function zt(e){return e?!!e.__v_raw:!1}function I(e){let t=e&&e.__v_raw;return t?I(t):e}function Bt(e){return!u(e,`__v_skip`)&&Object.isExtensible(e)&&O(e,`__v_skip`,!0),e}var Vt=e=>v(e)?Nt(e):e,Ht=e=>v(e)?Ft(e):e;function L(e){return e?e.__v_isRef===!0:!1}function Ut(e){return L(e)?e.value:e}var Wt={get:(e,t,n)=>t===`__v_raw`?e:Ut(Reflect.get(e,t,n)),set:(e,t,n,r)=>{let i=e[t];return L(i)&&!L(n)?(i.value=n,!0):Reflect.set(e,t,n,r)}};function Gt(e){return Lt(e)?e:new Proxy(e,Wt)}var Kt=class{constructor(e,t,n){this.fn=e,this.setter=t,this._value=void 0,this.dep=new Ke(this),this.__v_isRef=!0,this.deps=void 0,this.depsTail=void 0,this.flags=16,this.globalVersion=We-1,this.next=void 0,this.effect=this,this.__v_isReadonly=!t,this.isSSR=n}notify(){if(this.flags|=16,!(this.flags&8)&&M!==this)return je(this,!0),!0}get value(){let e=this.dep.track();return Le(this),e&&(e.version=this.dep.version),this._value}set value(e){this.setter&&this.setter(e)}};function qt(e,t,n=!1){let r,i;return h(e)?r=e:(r=e.get,i=e.set),new Kt(r,i,n)}var Jt={},Yt=new WeakMap,Xt=void 0;function Zt(e,t=!1,n=Xt){if(n){let t=Yt.get(n);t||Yt.set(n,t=[]),t.push(e)}}function Qt(e,n,i=t){let{immediate:a,deep:o,once:s,scheduler:l,augmentJob:u,call:f}=i,p=e=>o?e:F(e)||o===!1||o===0?$t(e,1):$t(e),m,g,_,v,y=!1,b=!1;if(L(e)?(g=()=>e.value,y=F(e)):Lt(e)?(g=()=>p(e),y=!0):d(e)?(b=!0,y=e.some(e=>Lt(e)||F(e)),g=()=>e.map(e=>{if(L(e))return e.value;if(Lt(e))return p(e);if(h(e))return f?f(e,2):e()})):g=h(e)?n?f?()=>f(e,2):e:()=>{if(_){Ve();try{_()}finally{He()}}let t=Xt;Xt=m;try{return f?f(e,3,[v]):e(v)}finally{Xt=t}}:r,n&&o){let e=g,t=o===!0?1/0:o;g=()=>$t(e(),t)}let x=Te(),S=()=>{m.stop(),x&&x.active&&c(x.effects,m)};if(s&&n){let e=n;n=(...t)=>{e(...t),S()}}let C=b?Array(e.length).fill(Jt):Jt,w=e=>{if(!(!(m.flags&1)||!m.dirty&&!e))if(n){let e=m.run();if(o||y||(b?e.some((e,t)=>D(e,C[t])):D(e,C))){_&&_();let t=Xt;Xt=m;try{let t=[e,C===Jt?void 0:b&&C[0]===Jt?[]:C,v];C=e,f?f(n,3,t):n(...t)}finally{Xt=t}}}else m.run()};return u&&u(w),m=new De(g),m.scheduler=l?()=>l(w,!1):w,v=e=>Zt(e,!1,m),_=m.onStop=()=>{let e=Yt.get(m);if(e){if(f)f(e,4);else for(let t of e)t();Yt.delete(m)}},n?a?w(!0):C=m.run():l?l(w.bind(null,!0),!0):m.run(),S.pause=m.pause.bind(m),S.resume=m.resume.bind(m),S.stop=S,S}function $t(e,t=1/0,n){if(t<=0||!v(e)||e.__v_skip||(n||=new Map,(n.get(e)||0)>=t))return e;if(n.set(e,t),t--,L(e))$t(e.value,t,n);else if(d(e))for(let r=0;r{$t(e,t,n)});else if(C(e)){for(let r in e)$t(e[r],t,n);for(let r of Object.getOwnPropertySymbols(e))Object.prototype.propertyIsEnumerable.call(e,r)&&$t(e[r],t,n)}return e}function en(e,t,n,r){try{return r?e(...r):e()}catch(e){nn(e,t,n)}}function tn(e,t,n,r){if(h(e)){let i=en(e,t,n,r);return i&&y(i)&&i.catch(e=>{nn(e,t,n)}),i}if(d(e)){let i=[];for(let a=0;a>>1,i=R[r],a=vn(i);a=vn(n)?R.push(e):R.splice(fn(t),0,e),e.flags|=1,mn()}}function mn(){un||=ln.then(yn)}function hn(e){d(e)?on.push(...e):sn&&e.id===-1?sn.splice(cn+1,0,e):e.flags&1||(on.push(e),e.flags|=1),mn()}function gn(e,t,n=an+1){for(;nvn(e)-vn(t));if(on.length=0,sn){sn.push(...e);return}for(sn=e,cn=0;cne.id==null?e.flags&2?-1:1/0:e.id;function yn(e){try{for(an=0;an{r._d&&Ci(-1);let i=xn(t),a;try{a=e(...n)}finally{xn(i),r._d&&Ci(1)}return a};return r._n=!0,r._c=!0,r._d=!0,r}function B(e,n){if(z===null)return e;let r=ra(z),i=e.dirs||=[];for(let e=0;e1)return n&&h(t)?t.call(r&&r.proxy):t}}var En=Symbol.for(`v-scx`),Dn=()=>Tn(En);function On(e,t,n){return kn(e,t,n)}function kn(e,n,i=t){let{immediate:a,deep:o,flush:c,once:l}=i,u=s({},i),d=n&&a||!n&&c!==`post`,f;if(Ji){if(c===`sync`){let e=Dn();f=e.__watcherHandles||=[]}else if(!d){let e=()=>{};return e.stop=r,e.resume=r,e.pause=r,e}}let p=Z;u.call=(e,t,n)=>tn(e,p,t,n);let m=!1;c===`post`?u.scheduler=e=>{U(e,p&&p.suspense)}:c!==`sync`&&(m=!0,u.scheduler=(e,t)=>{t?e():pn(e)}),u.augmentJob=e=>{n&&(e.flags|=4),m&&(e.flags|=2,p&&(e.id=p.uid,e.i=p))};let h=Qt(e,n,u);return Ji&&(f?f.push(h):d&&h()),h}function An(e,t,n){let r=this.proxy,i=g(e)?e.includes(`.`)?jn(r,e):()=>r[e]:e.bind(r,r),a;h(t)?a=t:(a=t.handler,n=t);let o=Gi(this),s=kn(i,a.bind(r),n);return o(),s}function jn(e,t){let n=t.split(`.`);return()=>{let t=e;for(let e=0;ee.__isTeleport,Pn=Symbol(`_leaveCb`);function Fn(e,t){e.shapeFlag&6&&e.component?(e.transition=t,Fn(e.component.subTree,t)):e.shapeFlag&128?(e.ssContent.transition=t.clone(e.ssContent),e.ssFallback.transition=t.clone(e.ssFallback)):e.transition=t}function In(e){e.ids=[e.ids[0]+ e.ids[2]+++`-`,0,0]}function Ln(e,t){let n;return!!((n=Object.getOwnPropertyDescriptor(e,t))&&!n.configurable)}var Rn=new WeakMap;function zn(e,n,r,a,o=!1){if(d(e)){e.forEach((e,t)=>zn(e,n&&(d(n)?n[t]:n),r,a,o));return}if(Vn(a)&&!o){a.shapeFlag&512&&a.type.__asyncResolved&&a.component.subTree.component&&zn(e,n,r,a.component.subTree);return}let s=a.shapeFlag&4?ra(a.component):a.el,l=o?null:s,{i:f,r:p}=e,m=n&&n.r,_=f.refs===t?f.refs={}:f.refs,v=f.setupState,y=I(v),b=v===t?i:e=>Ln(_,e)?!1:u(y,e),x=(e,t)=>!(t&&Ln(_,t));if(m!=null&&m!==p){if(Bn(n),g(m))_[m]=null,b(m)&&(v[m]=null);else if(L(m)){let e=n;x(m,e.k)&&(m.value=null),e.k&&(_[e.k]=null)}}if(h(p))en(p,f,12,[l,_]);else{let t=g(p),n=L(p);if(t||n){let i=()=>{if(e.f){let n=t?b(p)?v[p]:_[p]:x(p)||!e.k?p.value:_[e.k];if(o)d(n)&&c(n,s);else if(d(n))n.includes(s)||n.push(s);else if(t)_[p]=[s],b(p)&&(v[p]=_[p]);else{let t=[s];x(p,e.k)&&(p.value=t),e.k&&(_[e.k]=t)}}else t?(_[p]=l,b(p)&&(v[p]=l)):n&&(x(p,e.k)&&(p.value=l),e.k&&(_[e.k]=l))};if(l){let t=()=>{i(),Rn.delete(e)};t.id=-1,Rn.set(e,t),U(t,r)}else Bn(e),i()}}}function Bn(e){let t=Rn.get(e);t&&(t.flags|=8,Rn.delete(e))}le().requestIdleCallback,le().cancelIdleCallback;var Vn=e=>!!e.type.__asyncLoader,Hn=e=>e.type.__isKeepAlive;function Un(e,t){Gn(e,`a`,t)}function Wn(e,t){Gn(e,`da`,t)}function Gn(e,t,n=Z){let r=e.__wdc||=()=>{let t=n;for(;t;){if(t.isDeactivated)return;t=t.parent}return e()};if(qn(t,r,n),n){let e=n.parent;for(;e&&e.parent;)Hn(e.parent.vnode)&&Kn(r,t,n,e),e=e.parent}}function Kn(e,t,n,r){let i=qn(t,e,r,!0);er(()=>{c(r[t],i)},n)}function qn(e,t,n=Z,r=!1){if(n){let i=n[e]||(n[e]=[]),a=t.__weh||=(...r)=>{Ve();let i=Gi(n),a=tn(t,n,e,r);return i(),He(),a};return r?i.unshift(a):i.push(a),a}}var Jn=e=>(t,n=Z)=>{(!Ji||e===`sp`)&&qn(e,(...e)=>t(...e),n)},Yn=Jn(`bm`),Xn=Jn(`m`),Zn=Jn(`bu`),Qn=Jn(`u`),$n=Jn(`bum`),er=Jn(`um`),tr=Jn(`sp`),nr=Jn(`rtg`),rr=Jn(`rtc`);function ir(e,t=Z){qn(`ec`,e,t)}var ar=Symbol.for(`v-ndc`);function V(e,t,n,r){let i,a=n&&n[r],o=d(e);if(o||g(e)){let n=o&&Lt(e),r=!1,s=!1;n&&(r=!F(e),s=Rt(e),e=et(e)),i=Array(e.length);for(let n=0,o=e.length;nt(e,n,void 0,a&&a[n]));else{let n=Object.keys(e);i=Array(n.length);for(let r=0,o=n.length;re?qi(e)?ra(e):or(e.parent):null,sr=s(Object.create(null),{$:e=>e,$el:e=>e.vnode.el,$data:e=>e.data,$props:e=>e.props,$attrs:e=>e.attrs,$slots:e=>e.slots,$refs:e=>e.refs,$parent:e=>or(e.parent),$root:e=>or(e.root),$host:e=>e.ce,$emit:e=>e.emit,$options:e=>gr(e),$forceUpdate:e=>e.f||=()=>{pn(e.update)},$nextTick:e=>e.n||=dn.bind(e.proxy),$watch:e=>An.bind(e)}),cr=(e,n)=>e!==t&&!e.__isScriptSetup&&u(e,n),lr={get({_:e},n){if(n===`__v_skip`)return!0;let{ctx:r,setupState:i,data:a,props:o,accessCache:s,type:c,appContext:l}=e;if(n[0]!==`$`){let e=s[n];if(e!==void 0)switch(e){case 1:return i[n];case 2:return a[n];case 4:return r[n];case 3:return o[n]}else if(cr(i,n))return s[n]=1,i[n];else if(a!==t&&u(a,n))return s[n]=2,a[n];else if(u(o,n))return s[n]=3,o[n];else if(r!==t&&u(r,n))return s[n]=4,r[n];else dr&&(s[n]=0)}let d=sr[n],f,p;if(d)return n===`$attrs`&&P(e.attrs,`get`,``),d(e);if((f=c.__cssModules)&&(f=f[n]))return f;if(r!==t&&u(r,n))return s[n]=4,r[n];if(p=l.config.globalProperties,u(p,n))return p[n]},set({_:e},n,r){let{data:i,setupState:a,ctx:o}=e;return cr(a,n)?(a[n]=r,!0):i!==t&&u(i,n)?(i[n]=r,!0):u(e.props,n)||n[0]===`$`&&n.slice(1)in e?!1:(o[n]=r,!0)},has({_:{data:e,setupState:n,accessCache:r,ctx:i,appContext:a,props:o,type:s}},c){let l;return!!(r[c]||e!==t&&c[0]!==`$`&&u(e,c)||cr(n,c)||u(o,c)||u(i,c)||u(sr,c)||u(a.config.globalProperties,c)||(l=s.__cssModules)&&l[c])},defineProperty(e,t,n){return n.get==null?u(n,`value`)&&this.set(e,t,n.value,null):e._.accessCache[t]=0,Reflect.defineProperty(e,t,n)}};function ur(e){return d(e)?e.reduce((e,t)=>(e[t]=null,e),{}):e}var dr=!0;function fr(e){let t=gr(e),n=e.proxy,i=e.ctx;dr=!1,t.beforeCreate&&mr(t.beforeCreate,e,`bc`);let{data:a,computed:o,methods:s,watch:c,provide:l,inject:u,created:f,beforeMount:p,mounted:m,beforeUpdate:g,updated:_,activated:y,deactivated:b,beforeDestroy:x,beforeUnmount:S,destroyed:C,unmounted:w,render:ee,renderTracked:te,renderTriggered:ne,errorCaptured:T,serverPrefetch:re,expose:E,inheritAttrs:ie,components:ae,directives:D,filters:oe}=t;if(u&&pr(u,i,null),s)for(let e in s){let t=s[e];h(t)&&(i[e]=t.bind(n))}if(a){let t=a.call(n,n);v(t)&&(e.data=Nt(t))}if(dr=!0,o)for(let e in o){let t=o[e],a=aa({get:h(t)?t.bind(n,n):h(t.get)?t.get.bind(n,n):r,set:!h(t)&&h(t.set)?t.set.bind(n):r});Object.defineProperty(i,e,{enumerable:!0,configurable:!0,get:()=>a.value,set:e=>a.value=e})}if(c)for(let e in c)hr(c[e],i,n,e);if(l){let e=h(l)?l.call(n):l;Reflect.ownKeys(e).forEach(t=>{wn(t,e[t])})}f&&mr(f,e,`c`);function O(e,t){d(t)?t.forEach(t=>e(t.bind(n))):t&&e(t.bind(n))}if(O(Yn,p),O(Xn,m),O(Zn,g),O(Qn,_),O(Un,y),O(Wn,b),O(ir,T),O(rr,te),O(nr,ne),O($n,S),O(er,w),O(tr,re),d(E))if(E.length){let t=e.exposed||={};E.forEach(e=>{Object.defineProperty(t,e,{get:()=>n[e],set:t=>n[e]=t,enumerable:!0})})}else e.exposed||={};ee&&e.render===r&&(e.render=ee),ie!=null&&(e.inheritAttrs=ie),ae&&(e.components=ae),D&&(e.directives=D),re&&In(e)}function pr(e,t,n=r){d(e)&&(e=xr(e));for(let n in e){let r=e[n],i;i=v(r)?`default`in r?Tn(r.from||n,r.default,!0):Tn(r.from||n):Tn(r),L(i)?Object.defineProperty(t,n,{enumerable:!0,configurable:!0,get:()=>i.value,set:e=>i.value=e}):t[n]=i}}function mr(e,t,n){tn(d(e)?e.map(e=>e.bind(t.proxy)):e.bind(t.proxy),t,n)}function hr(e,t,n,r){let i=r.includes(`.`)?jn(n,r):()=>n[r];if(g(e)){let n=t[e];h(n)&&On(i,n)}else if(h(e))On(i,e.bind(n));else if(v(e))if(d(e))e.forEach(e=>hr(e,t,n,r));else{let r=h(e.handler)?e.handler.bind(n):t[e.handler];h(r)&&On(i,r,e)}}function gr(e){let t=e.type,{mixins:n,extends:r}=t,{mixins:i,optionsCache:a,config:{optionMergeStrategies:o}}=e.appContext,s=a.get(t),c;return s?c=s:!i.length&&!n&&!r?c=t:(c={},i.length&&i.forEach(e=>_r(c,e,o,!0)),_r(c,t,o)),v(t)&&a.set(t,c),c}function _r(e,t,n,r=!1){let{mixins:i,extends:a}=t;a&&_r(e,a,n,!0),i&&i.forEach(t=>_r(e,t,n,!0));for(let i in t)if(!(r&&i===`expose`)){let r=vr[i]||n&&n[i];e[i]=r?r(e[i],t[i]):t[i]}return e}var vr={data:yr,props:Cr,emits:Cr,methods:Sr,computed:Sr,beforeCreate:H,created:H,beforeMount:H,mounted:H,beforeUpdate:H,updated:H,beforeDestroy:H,beforeUnmount:H,destroyed:H,unmounted:H,activated:H,deactivated:H,errorCaptured:H,serverPrefetch:H,components:Sr,directives:Sr,watch:wr,provide:yr,inject:br};function yr(e,t){return t?e?function(){return s(h(e)?e.call(this,this):e,h(t)?t.call(this,this):t)}:t:e}function br(e,t){return Sr(xr(e),xr(t))}function xr(e){if(d(e)){let t={};for(let n=0;nt===`modelValue`||t===`model-value`?e.modelModifiers:e[`${t}Modifiers`]||e[`${T(t)}Modifiers`]||e[`${E(t)}Modifiers`];function Ar(e,n,...r){if(e.isUnmounted)return;let i=e.vnode.props||t,a=r,o=n.startsWith(`update:`),s=o&&kr(i,n.slice(7));s&&(s.trim&&(a=r.map(e=>g(e)?e.trim():e)),s.number&&(a=r.map(se)));let c,l=i[c=ae(n)]||i[c=ae(T(n))];!l&&o&&(l=i[c=ae(E(n))]),l&&tn(l,e,6,a);let u=i[c+`Once`];if(u){if(!e.emitted)e.emitted={};else if(e.emitted[c])return;e.emitted[c]=!0,tn(u,e,6,a)}}var jr=new WeakMap;function Mr(e,t,n=!1){let r=n?jr:t.emitsCache,i=r.get(e);if(i!==void 0)return i;let a=e.emits,o={},c=!1;if(!h(e)){let r=e=>{let n=Mr(e,t,!0);n&&(c=!0,s(o,n))};!n&&t.mixins.length&&t.mixins.forEach(r),e.extends&&r(e.extends),e.mixins&&e.mixins.forEach(r)}return!a&&!c?(v(e)&&r.set(e,null),null):(d(a)?a.forEach(e=>o[e]=null):s(o,a),v(e)&&r.set(e,o),o)}function Nr(e,t){return!e||!a(t)?!1:(t=t.slice(2).replace(/Once$/,``),u(e,t[0].toLowerCase()+t.slice(1))||u(e,E(t))||u(e,t))}function Pr(e){let{type:t,vnode:n,proxy:r,withProxy:i,propsOptions:[a],slots:s,attrs:c,emit:l,render:u,renderCache:d,props:f,data:p,setupState:m,ctx:h,inheritAttrs:g}=e,_=xn(e),v,y;try{if(n.shapeFlag&4){let e=i||r,t=e;v=Pi(u.call(t,e,d,f,m,p,h)),y=c}else{let e=t;v=Pi(e.length>1?e(f,{attrs:c,slots:s,emit:l}):e(f,null)),y=t.props?c:Fr(c)}}catch(t){bi.length=0,nn(t,e,1),v=Ai(vi)}let b=v;if(y&&g!==!1){let e=Object.keys(y),{shapeFlag:t}=b;e.length&&t&7&&(a&&e.some(o)&&(y=Ir(y,a)),b=Ni(b,y,!1,!0))}return n.dirs&&(b=Ni(b,null,!1,!0),b.dirs=b.dirs?b.dirs.concat(n.dirs):n.dirs),n.transition&&Fn(b,n.transition),v=b,xn(_),v}var Fr=e=>{let t;for(let n in e)(n===`class`||n===`style`||a(n))&&((t||={})[n]=e[n]);return t},Ir=(e,t)=>{let n={};for(let r in e)(!o(r)||!(r.slice(9)in t))&&(n[r]=e[r]);return n};function Lr(e,t,n){let{props:r,children:i,component:a}=e,{props:o,children:s,patchFlag:c}=t,l=a.emitsOptions;if(t.dirs||t.transition)return!0;if(n&&c>=0){if(c&1024)return!0;if(c&16)return r?Rr(r,o,l):!!o;if(c&8){let e=t.dynamicProps;for(let t=0;tObject.create(Vr),Ur=e=>Object.getPrototypeOf(e)===Vr;function Wr(e,t,n,r=!1){let i={},a=Hr();e.propsDefaults=Object.create(null),Kr(e,t,i,a);for(let t in e.propsOptions[0])t in i||(i[t]=void 0);n?e.props=r?i:Pt(i):e.type.props?e.props=i:e.props=a,e.attrs=a}function Gr(e,t,n,r){let{props:i,attrs:a,vnode:{patchFlag:o}}=e,s=I(i),[c]=e.propsOptions,l=!1;if((r||o>0)&&!(o&16)){if(o&8){let n=e.vnode.dynamicProps;for(let r=0;r{p=!0;let[t,n]=Yr(e,r,!0);s(l,t),n&&f.push(...n)};!i&&r.mixins.length&&r.mixins.forEach(t),e.extends&&t(e.extends),e.mixins&&e.mixins.forEach(t)}if(!c&&!p)return v(e)&&a.set(e,n),n;if(d(c))for(let e=0;ee===`_`||e===`_ctx`||e===`$stable`,Qr=e=>d(e)?e.map(Pi):[Pi(e)],$r=(e,t,n)=>{if(t._n)return t;let r=Sn((...e)=>Qr(t(...e)),n);return r._c=!1,r},ei=(e,t,n)=>{let r=e._ctx;for(let n in e){if(Zr(n))continue;let i=e[n];if(h(i))t[n]=$r(n,i,r);else if(i!=null){let e=Qr(i);t[n]=()=>e}}},ti=(e,t)=>{let n=Qr(t);e.slots.default=()=>n},ni=(e,t,n)=>{for(let r in t)(n||!Zr(r))&&(e[r]=t[r])},ri=(e,t,n)=>{let r=e.slots=Hr();if(e.vnode.shapeFlag&32){let e=t._;e?(ni(r,t,n),n&&O(r,`_`,e,!0)):ei(t,r)}else t&&ti(e,t)},ii=(e,n,r)=>{let{vnode:i,slots:a}=e,o=!0,s=t;if(i.shapeFlag&32){let e=n._;e?r&&e===1?o=!1:ni(a,n,r):(o=!n.$stable,ei(n,a)),s=n}else n&&(ti(e,n),s={default:1});if(o)for(let e in a)!Zr(e)&&s[e]==null&&delete a[e]},U=gi;function ai(e){return oi(e)}function oi(e,i){let a=le();a.__VUE__=!0;let{insert:o,remove:s,patchProp:c,createElement:l,createText:u,createComment:d,setText:f,setElementText:p,parentNode:m,nextSibling:h,setScopeId:g=r,insertStaticContent:_}=e,v=(e,t,n,r=null,i=null,a=null,o=void 0,s=null,c=!!t.dynamicChildren)=>{if(e===t)return;e&&!Di(e,t)&&(r=ye(e),k(e,i,a,!0),e=null),t.patchFlag===-2&&(c=!1,t.dynamicChildren=null);let{type:l,ref:u,shapeFlag:d}=t;switch(l){case _i:y(e,t,n,r);break;case vi:b(e,t,n,r);break;case yi:e??x(t,n,r,o);break;case W:ae(e,t,n,r,i,a,o,s,c);break;default:d&1?w(e,t,n,r,i,a,o,s,c):d&6?D(e,t,n,r,i,a,o,s,c):(d&64||d&128)&&l.process(e,t,n,r,i,a,o,s,c,A)}u!=null&&i?zn(u,e&&e.ref,a,t||e,!t):u==null&&e&&e.ref!=null&&zn(e.ref,null,a,e,!0)},y=(e,t,n,r)=>{if(e==null)o(t.el=u(t.children),n,r);else{let n=t.el=e.el;t.children!==e.children&&f(n,t.children)}},b=(e,t,n,r)=>{e==null?o(t.el=d(t.children||``),n,r):t.el=e.el},x=(e,t,n,r)=>{[e.el,e.anchor]=_(e.children,t,n,r,e.el,e.anchor)},S=({el:e,anchor:t},n,r)=>{let i;for(;e&&e!==t;)i=h(e),o(e,n,r),e=i;o(t,n,r)},C=({el:e,anchor:t})=>{let n;for(;e&&e!==t;)n=h(e),s(e),e=n;s(t)},w=(e,t,n,r,i,a,o,s,c)=>{if(t.type===`svg`?o=`svg`:t.type===`math`&&(o=`mathml`),e==null)te(t,n,r,i,a,o,s,c);else{let n=e.el&&e.el._isVueCE?e.el:null;try{n&&n._beginPatch(),re(e,t,i,a,o,s,c)}finally{n&&n._endPatch()}}},te=(e,t,n,r,i,a,s,u)=>{let d,f,{props:m,shapeFlag:h,transition:g,dirs:_}=e;if(d=e.el=l(e.type,a,m&&m.is,m),h&8?p(d,e.children):h&16&&T(e.children,d,null,r,i,si(e,a),s,u),_&&Cn(e,null,r,`created`),ne(d,e,e.scopeId,s,r),m){for(let e in m)e!==`value`&&!ee(e)&&c(d,e,null,m[e],a,r);`value`in m&&c(d,`value`,null,m.value,a),(f=m.onVnodeBeforeMount)&&Ri(f,r,e)}_&&Cn(e,null,r,`beforeMount`);let v=li(i,g);v&&g.beforeEnter(d),o(d,t,n),((f=m&&m.onVnodeMounted)||v||_)&&U(()=>{try{f&&Ri(f,r,e),v&&g.enter(d),_&&Cn(e,null,r,`mounted`)}finally{}},i)},ne=(e,t,n,r,i)=>{if(n&&g(e,n),r)for(let t=0;t{for(let l=c;l{let l=n.el=e.el,{patchFlag:u,dynamicChildren:d,dirs:f}=n;u|=e.patchFlag&16;let m=e.props||t,h=n.props||t,g;if(r&&ci(r,!1),(g=h.onVnodeBeforeUpdate)&&Ri(g,r,n,e),f&&Cn(n,e,r,`beforeUpdate`),r&&ci(r,!0),(m.innerHTML&&h.innerHTML==null||m.textContent&&h.textContent==null)&&p(l,``),d?E(e.dynamicChildren,d,l,r,i,si(n,a),o):s||de(e,n,l,null,r,i,si(n,a),o,!1),u>0){if(u&16)ie(l,m,h,r,a);else if(u&2&&m.class!==h.class&&c(l,`class`,null,h.class,a),u&4&&c(l,`style`,m.style,h.style,a),u&8){let e=n.dynamicProps;for(let t=0;t{g&&Ri(g,r,n,e),f&&Cn(n,e,r,`updated`)},i)},E=(e,t,n,r,i,a,o)=>{for(let s=0;s{if(n!==r){if(n!==t)for(let t in n)!ee(t)&&!(t in r)&&c(e,t,n[t],null,a,i);for(let t in r){if(ee(t))continue;let o=r[t],s=n[t];o!==s&&t!==`value`&&c(e,t,s,o,a,i)}`value`in r&&c(e,`value`,n.value,r.value,a)}},ae=(e,t,n,r,i,a,s,c,l)=>{let d=t.el=e?e.el:u(``),f=t.anchor=e?e.anchor:u(``),{patchFlag:p,dynamicChildren:m,slotScopeIds:h}=t;h&&(c=c?c.concat(h):h),e==null?(o(d,n,r),o(f,n,r),T(t.children||[],n,f,i,a,s,c,l)):p>0&&p&64&&m&&e.dynamicChildren&&e.dynamicChildren.length===m.length?(E(e.dynamicChildren,m,n,i,a,s,c),(t.key!=null||i&&t===i.subTree)&&ui(e,t,!0)):de(e,t,n,f,i,a,s,c,l)},D=(e,t,n,r,i,a,o,s,c)=>{t.slotScopeIds=s,e==null?t.shapeFlag&512?i.ctx.activate(t,n,r,o,c):O(t,n,r,i,a,o,c):se(e,t,c)},O=(e,t,n,r,i,a,o)=>{let s=e.component=Vi(e,r,i);if(Hn(e)&&(s.ctx.renderer=A),Yi(s,!1,o),s.asyncDep){if(i&&i.registerDep(s,ce,o),!e.el){let r=s.subTree=Ai(vi);b(null,r,t,n),e.placeholder=r.el}}else ce(s,e,t,n,i,a,o)},se=(e,t,n)=>{let r=t.component=e.component;if(Lr(e,t,n))if(r.asyncDep&&!r.asyncResolved){ue(r,t,n);return}else r.next=t,r.update();else t.el=e.el,r.vnode=t},ce=(e,t,n,r,i,a,o)=>{let s=()=>{if(e.isMounted){let{next:t,bu:n,u:r,parent:s,vnode:c}=e;{let n=fi(e);if(n){t&&(t.el=c.el,ue(e,t,o)),n.asyncDep.then(()=>{U(()=>{e.isUnmounted||l()},i)});return}}let u=t,d;ci(e,!1),t?(t.el=c.el,ue(e,t,o)):t=c,n&&oe(n),(d=t.props&&t.props.onVnodeBeforeUpdate)&&Ri(d,s,t,c),ci(e,!0);let f=Pr(e),p=e.subTree;e.subTree=f,v(p,f,m(p.el),ye(p),e,i,a),t.el=f.el,u===null&&Br(e,f.el),r&&U(r,i),(d=t.props&&t.props.onVnodeUpdated)&&U(()=>Ri(d,s,t,c),i)}else{let o,{el:s,props:c}=t,{bm:l,m:u,parent:d,root:f,type:p}=e,m=Vn(t);if(ci(e,!1),l&&oe(l),!m&&(o=c&&c.onVnodeBeforeMount)&&Ri(o,d,t),ci(e,!0),s&&Ce){let t=()=>{e.subTree=Pr(e),Ce(s,e.subTree,e,i,null)};m&&p.__asyncHydrate?p.__asyncHydrate(s,e,t):t()}else{f.ce&&f.ce._hasShadowRoot()&&f.ce._injectChildStyle(p,e.parent?e.parent.type:void 0);let o=e.subTree=Pr(e);v(null,o,n,r,e,i,a),t.el=o.el}if(u&&U(u,i),!m&&(o=c&&c.onVnodeMounted)){let e=t;U(()=>Ri(o,d,e),i)}(t.shapeFlag&256||d&&Vn(d.vnode)&&d.vnode.shapeFlag&256)&&e.a&&U(e.a,i),e.isMounted=!0,t=n=r=null}};e.scope.on();let c=e.effect=new De(s);e.scope.off();let l=e.update=c.run.bind(c),u=e.job=c.runIfDirty.bind(c);u.i=e,u.id=e.uid,c.scheduler=()=>pn(u),ci(e,!0),l()},ue=(e,t,n)=>{t.component=e;let r=e.vnode.props;e.vnode=t,e.next=null,Gr(e,t.props,r,n),ii(e,t.children,n),Ve(),gn(e),He()},de=(e,t,n,r,i,a,o,s,c=!1)=>{let l=e&&e.children,u=e?e.shapeFlag:0,d=t.children,{patchFlag:f,shapeFlag:m}=t;if(f>0){if(f&128){pe(l,d,n,r,i,a,o,s,c);return}else if(f&256){fe(l,d,n,r,i,a,o,s,c);return}}m&8?(u&16&&ve(l,i,a),d!==l&&p(n,d)):u&16?m&16?pe(l,d,n,r,i,a,o,s,c):ve(l,i,a,!0):(u&8&&p(n,``),m&16&&T(d,n,r,i,a,o,s,c))},fe=(e,t,r,i,a,o,s,c,l)=>{e||=n,t||=n;let u=e.length,d=t.length,f=Math.min(u,d),p;for(p=0;pd?ve(e,a,o,!0,!1,f):T(t,r,i,a,o,s,c,l,f)},pe=(e,t,r,i,a,o,s,c,l)=>{let u=0,d=t.length,f=e.length-1,p=d-1;for(;u<=f&&u<=p;){let n=e[u],i=t[u]=l?Fi(t[u]):Pi(t[u]);if(Di(n,i))v(n,i,r,null,a,o,s,c,l);else break;u++}for(;u<=f&&u<=p;){let n=e[f],i=t[p]=l?Fi(t[p]):Pi(t[p]);if(Di(n,i))v(n,i,r,null,a,o,s,c,l);else break;f--,p--}if(u>f){if(u<=p){let e=p+1,n=ep)for(;u<=f;)k(e[u],a,o,!0),u++;else{let m=u,h=u,g=new Map;for(u=h;u<=p;u++){let e=t[u]=l?Fi(t[u]):Pi(t[u]);e.key!=null&&g.set(e.key,u)}let _,y=0,b=p-h+1,x=!1,S=0,C=Array(b);for(u=0;u=b){k(n,a,o,!0);continue}let i;if(n.key!=null)i=g.get(n.key);else for(_=h;_<=p;_++)if(C[_-h]===0&&Di(n,t[_])){i=_;break}i===void 0?k(n,a,o,!0):(C[i-h]=u+1,i>=S?S=i:x=!0,v(n,t[i],r,null,a,o,s,c,l),y++)}let w=x?di(C):n;for(_=w.length-1,u=b-1;u>=0;u--){let e=h+u,n=t[e],f=t[e+1],p=e+1{let{el:a,type:c,transition:l,children:u,shapeFlag:d}=e;if(d&6){me(e.component.subTree,t,n,r);return}if(d&128){e.suspense.move(t,n,r);return}if(d&64){c.move(e,t,n,A);return}if(c===W){o(a,t,n);for(let e=0;el.enter(a),i);else{let{leave:r,delayLeave:i,afterLeave:c}=l,u=()=>{e.ctx.isUnmounted?s(a):o(a,t,n)},d=()=>{a._isLeaving&&a[Pn](!0),r(a,()=>{u(),c&&c()})};i?i(a,u,d):d()}else o(a,t,n)},k=(e,t,n,r=!1,i=!1)=>{let{type:a,props:o,ref:s,children:c,dynamicChildren:l,shapeFlag:u,patchFlag:d,dirs:f,cacheIndex:p,memo:m}=e;if(d===-2&&(i=!1),s!=null&&(Ve(),zn(s,null,n,e,!0),He()),p!=null&&(t.renderCache[p]=void 0),u&256){t.ctx.deactivate(e);return}let h=u&1&&f,g=!Vn(e),_;if(g&&(_=o&&o.onVnodeBeforeUnmount)&&Ri(_,t,e),u&6)_e(e.component,n,r);else{if(u&128){e.suspense.unmount(n,r);return}h&&Cn(e,null,t,`beforeUnmount`),u&64?e.type.remove(e,t,n,A,r):l&&!l.hasOnce&&(a!==W||d>0&&d&64)?ve(l,t,n,!1,!0):(a===W&&d&384||!i&&u&16)&&ve(c,t,n),r&&he(e)}let v=m!=null&&p==null;(g&&(_=o&&o.onVnodeUnmounted)||h||v)&&U(()=>{_&&Ri(_,t,e),h&&Cn(e,null,t,`unmounted`),v&&(e.el=null)},n)},he=e=>{let{type:t,el:n,anchor:r,transition:i}=e;if(t===W){ge(n,r);return}if(t===yi){C(e);return}let a=()=>{s(n),i&&!i.persisted&&i.afterLeave&&i.afterLeave()};if(e.shapeFlag&1&&i&&!i.persisted){let{leave:t,delayLeave:r}=i,o=()=>t(n,a);r?r(e.el,a,o):o()}else a()},ge=(e,t)=>{let n;for(;e!==t;)n=h(e),s(e),e=n;s(t)},_e=(e,t,n)=>{let{bum:r,scope:i,job:a,subTree:o,um:s,m:c,a:l}=e;pi(c),pi(l),r&&oe(r),i.stop(),a&&(a.flags|=8,k(o,e,t,n)),s&&U(s,t),U(()=>{e.isUnmounted=!0},t)},ve=(e,t,n,r=!1,i=!1,a=0)=>{for(let o=a;o{if(e.shapeFlag&6)return ye(e.component.subTree);if(e.shapeFlag&128)return e.suspense.next();let t=h(e.anchor||e.el),n=t&&t[Mn];return n?h(n):t},be=!1,xe=(e,t,n)=>{let r;e==null?t._vnode&&(k(t._vnode,null,null,!0),r=t._vnode.component):v(t._vnode||null,e,t,null,null,null,n),t._vnode=e,be||=(be=!0,gn(r),_n(),!1)},A={p:v,um:k,m:me,r:he,mt:O,mc:T,pc:de,pbc:E,n:ye,o:e},Se,Ce;return i&&([Se,Ce]=i(A)),{render:xe,hydrate:Se,createApp:Dr(xe,Se)}}function si({type:e,props:t},n){return n===`svg`&&e===`foreignObject`||n===`mathml`&&e===`annotation-xml`&&t&&t.encoding&&t.encoding.includes(`html`)?void 0:n}function ci({effect:e,job:t},n){n?(e.flags|=32,t.flags|=4):(e.flags&=-33,t.flags&=-5)}function li(e,t){return(!e||e&&!e.pendingBranch)&&t&&!t.persisted}function ui(e,t,n=!1){let r=e.children,i=t.children;if(d(r)&&d(i))for(let e=0;e>1,e[n[s]]0&&(t[r]=n[a-1]),n[a]=r)}}for(a=n.length,o=n[a-1];a-- >0;)n[a]=o,o=t[o];return n}function fi(e){let t=e.subTree.component;if(t)return t.asyncDep&&!t.asyncResolved?t:fi(t)}function pi(e){if(e)for(let t=0;te.__isSuspense;function gi(e,t){t&&t.pendingBranch?d(e)?t.effects.push(...e):t.effects.push(e):hn(e)}var W=Symbol.for(`v-fgt`),_i=Symbol.for(`v-txt`),vi=Symbol.for(`v-cmt`),yi=Symbol.for(`v-stc`),bi=[],G=null;function K(e=!1){bi.push(G=e?null:[])}function xi(){bi.pop(),G=bi[bi.length-1]||null}var Si=1;function Ci(e,t=!1){Si+=e,e<0&&G&&t&&(G.hasOnce=!0)}function wi(e){return e.dynamicChildren=Si>0?G||n:null,xi(),Si>0&&G&&G.push(e),e}function q(e,t,n,r,i,a){return wi(J(e,t,n,r,i,a,!0))}function Ti(e,t,n,r,i){return wi(Ai(e,t,n,r,i,!0))}function Ei(e){return e?e.__v_isVNode===!0:!1}function Di(e,t){return e.type===t.type&&e.key===t.key}var Oi=({key:e})=>e??null,ki=({ref:e,ref_key:t,ref_for:n})=>(typeof e==`number`&&(e=``+e),e==null?null:g(e)||L(e)||h(e)?{i:z,r:e,k:t,f:!!n}:e);function J(e,t=null,n=null,r=0,i=null,a=e===W?0:1,o=!1,s=!1){let c={__v_isVNode:!0,__v_skip:!0,type:e,props:t,key:t&&Oi(t),ref:t&&ki(t),scopeId:bn,slotScopeIds:null,children:n,component:null,suspense:null,ssContent:null,ssFallback:null,dirs:null,transition:null,el:null,anchor:null,target:null,targetStart:null,targetAnchor:null,staticCount:0,shapeFlag:a,patchFlag:r,dynamicProps:i,dynamicChildren:null,appContext:null,ctx:z};return s?(Ii(c,n),a&128&&e.normalize(c)):n&&(c.shapeFlag|=g(n)?8:16),Si>0&&!o&&G&&(c.patchFlag>0||a&6)&&c.patchFlag!==32&&G.push(c),c}var Ai=ji;function ji(e,t=null,n=null,r=0,i=null,a=!1){if((!e||e===ar)&&(e=vi),Ei(e)){let r=Ni(e,t,!0);return n&&Ii(r,n),Si>0&&!a&&G&&(r.shapeFlag&6?G[G.indexOf(e)]=r:G.push(r)),r.patchFlag=-2,r}if(ia(e)&&(e=e.__vccOpts),t){t=Mi(t);let{class:e,style:n}=t;e&&!g(e)&&(t.class=k(e)),v(n)&&(zt(n)&&!d(n)&&(n=s({},n)),t.style=ue(n))}let o=g(e)?1:hi(e)?128:Nn(e)?64:v(e)?4:h(e)?2:0;return J(e,t,n,r,i,o,a,!0)}function Mi(e){return e?zt(e)||Ur(e)?s({},e):e:null}function Ni(e,t,n=!1,r=!1){let{props:i,ref:a,patchFlag:o,children:s,transition:c}=e,l=t?Li(i||{},t):i,u={__v_isVNode:!0,__v_skip:!0,type:e.type,props:l,key:l&&Oi(l),ref:t&&t.ref?n&&a?d(a)?a.concat(ki(t)):[a,ki(t)]:ki(t):a,scopeId:e.scopeId,slotScopeIds:e.slotScopeIds,children:s,target:e.target,targetStart:e.targetStart,targetAnchor:e.targetAnchor,staticCount:e.staticCount,shapeFlag:e.shapeFlag,patchFlag:t&&e.type!==W?o===-1?16:o|16:o,dynamicProps:e.dynamicProps,dynamicChildren:e.dynamicChildren,appContext:e.appContext,dirs:e.dirs,transition:c,component:e.component,suspense:e.suspense,ssContent:e.ssContent&&Ni(e.ssContent),ssFallback:e.ssFallback&&Ni(e.ssFallback),placeholder:e.placeholder,el:e.el,anchor:e.anchor,ctx:e.ctx,ce:e.ce};return c&&r&&Fn(u,c.clone(u)),u}function Y(e=` `,t=0){return Ai(_i,null,e,t)}function X(e=``,t=!1){return t?(K(),Ti(vi,null,e)):Ai(vi,null,e)}function Pi(e){return e==null||typeof e==`boolean`?Ai(vi):d(e)?Ai(W,null,e.slice()):Ei(e)?Fi(e):Ai(_i,null,String(e))}function Fi(e){return e.el===null&&e.patchFlag!==-1||e.memo?e:Ni(e)}function Ii(e,t){let n=0,{shapeFlag:r}=e;if(t==null)t=null;else if(d(t))n=16;else if(typeof t==`object`)if(r&65){let n=t.default;n&&(n._c&&(n._d=!1),Ii(e,n()),n._c&&(n._d=!0));return}else{n=32;let r=t._;!r&&!Ur(t)?t._ctx=z:r===3&&z&&(z.slots._===1?t._=1:(t._=2,e.patchFlag|=1024))}else h(t)?(t={default:t,_ctx:z},n=32):(t=String(t),r&64?(n=16,t=[Y(t)]):n=8);e.children=t,e.shapeFlag|=n}function Li(...e){let t={};for(let n=0;nZ||z,Ui,Wi;{let e=le(),t=(t,n)=>{let r;return(r=e[t])||(r=e[t]=[]),r.push(n),e=>{r.length>1?r.forEach(t=>t(e)):r[0](e)}};Ui=t(`__VUE_INSTANCE_SETTERS__`,e=>Z=e),Wi=t(`__VUE_SSR_SETTERS__`,e=>Ji=e)}var Gi=e=>{let t=Z;return Ui(e),e.scope.on(),()=>{e.scope.off(),Ui(t)}},Ki=()=>{Z&&Z.scope.off(),Ui(null)};function qi(e){return e.vnode.shapeFlag&4}var Ji=!1;function Yi(e,t=!1,n=!1){t&&Wi(t);let{props:r,children:i}=e.vnode,a=qi(e);Wr(e,r,a,t),ri(e,i,n||t);let o=a?Xi(e,t):void 0;return t&&Wi(!1),o}function Xi(e,t){let n=e.type;e.accessCache=Object.create(null),e.proxy=new Proxy(e.ctx,lr);let{setup:r}=n;if(r){Ve();let n=e.setupContext=r.length>1?na(e):null,i=Gi(e),a=en(r,e,0,[e.props,n]),o=y(a);if(He(),i(),(o||e.sp)&&!Vn(e)&&In(e),o){if(a.then(Ki,Ki),t)return a.then(n=>{Zi(e,n,t)}).catch(t=>{nn(t,e,0)});e.asyncDep=a}else Zi(e,a,t)}else ea(e,t)}function Zi(e,t,n){h(t)?e.type.__ssrInlineRender?e.ssrRender=t:e.render=t:v(t)&&(e.setupState=Gt(t)),ea(e,n)}var Qi,$i;function ea(e,t,n){let i=e.type;if(!e.render){if(!t&&Qi&&!i.render){let t=i.template||gr(e).template;if(t){let{isCustomElement:n,compilerOptions:r}=e.appContext.config,{delimiters:a,compilerOptions:o}=i;i.render=Qi(t,s(s({isCustomElement:n,delimiters:a},r),o))}}e.render=i.render||r,$i&&$i(e)}{let t=Gi(e);Ve();try{fr(e)}finally{He(),t()}}}var ta={get(e,t){return P(e,`get`,``),e[t]}};function na(e){return{attrs:new Proxy(e.attrs,ta),slots:e.slots,emit:e.emit,expose:t=>{e.exposed=t||{}}}}function ra(e){return e.exposed?e.exposeProxy||=new Proxy(Gt(Bt(e.exposed)),{get(t,n){if(n in t)return t[n];if(n in sr)return sr[n](e)},has(e,t){return t in e||t in sr}}):e.proxy}function ia(e){return h(e)&&`__vccOpts`in e}var aa=(e,t)=>qt(e,t,Ji),oa=`3.5.34`,sa=void 0,ca=typeof window<`u`&&window.trustedTypes;if(ca)try{sa=ca.createPolicy(`vue`,{createHTML:e=>e})}catch{}var la=sa?e=>sa.createHTML(e):e=>e,ua=`http://www.w3.org/2000/svg`,da=`http://www.w3.org/1998/Math/MathML`,fa=typeof document<`u`?document:null,pa=fa&&fa.createElement(`template`),ma={insert:(e,t,n)=>{t.insertBefore(e,n||null)},remove:e=>{let t=e.parentNode;t&&t.removeChild(e)},createElement:(e,t,n,r)=>{let i=t===`svg`?fa.createElementNS(ua,e):t===`mathml`?fa.createElementNS(da,e):n?fa.createElement(e,{is:n}):fa.createElement(e);return e===`select`&&r&&r.multiple!=null&&i.setAttribute(`multiple`,r.multiple),i},createText:e=>fa.createTextNode(e),createComment:e=>fa.createComment(e),setText:(e,t)=>{e.nodeValue=t},setElementText:(e,t)=>{e.textContent=t},parentNode:e=>e.parentNode,nextSibling:e=>e.nextSibling,querySelector:e=>fa.querySelector(e),setScopeId(e,t){e.setAttribute(t,``)},insertStaticContent(e,t,n,r,i,a){let o=n?n.previousSibling:t.lastChild;if(i&&(i===a||i.nextSibling))for(;t.insertBefore(i.cloneNode(!0),n),!(i===a||!(i=i.nextSibling)););else{pa.innerHTML=la(r===`svg`?`${e}`:r===`mathml`?`${e}`:e);let i=pa.content;if(r===`svg`||r===`mathml`){let e=i.firstChild;for(;e.firstChild;)i.appendChild(e.firstChild);i.removeChild(e)}t.insertBefore(i,n)}return[o?o.nextSibling:t.firstChild,n?n.previousSibling:t.lastChild]}},ha=Symbol(`_vtc`);function ga(e,t,n){let r=e[ha];r&&(t=(t?[t,...r]:[...r]).join(` `)),t==null?e.removeAttribute(`class`):n?e.setAttribute(`class`,t):e.className=t}var _a=Symbol(`_vod`),va=Symbol(`_vsh`),ya={name:`show`,beforeMount(e,{value:t},{transition:n}){e[_a]=e.style.display===`none`?``:e.style.display,n&&t?n.beforeEnter(e):ba(e,t)},mounted(e,{value:t},{transition:n}){n&&t&&n.enter(e)},updated(e,{value:t,oldValue:n},{transition:r}){!t!=!n&&(r?t?(r.beforeEnter(e),ba(e,!0),r.enter(e)):r.leave(e,()=>{ba(e,!1)}):ba(e,t))},beforeUnmount(e,{value:t}){ba(e,t)}};function ba(e,t){e.style.display=t?e[_a]:`none`,e[va]=!t}var xa=Symbol(``),Sa=/(?:^|;)\s*display\s*:/;function Ca(e,t,n){let r=e.style,i=g(n),a=!1;if(n&&!i){if(t)if(g(t))for(let e of t.split(`;`)){let t=e.slice(0,e.indexOf(`:`)).trim();n[t]??Ta(r,t,``)}else for(let e in t)n[e]??Ta(r,e,``);for(let i in n){i===`display`&&(a=!0);let o=n[i];o==null?Ta(r,i,``):ka(e,i,!g(t)&&t?t[i]:void 0,o)||Ta(r,i,o)}}else if(i){if(t!==n){let e=r[xa];e&&(n+=`;`+e),r.cssText=n,a=Sa.test(n)}}else t&&e.removeAttribute(`style`);_a in e&&(e[_a]=a?r.display:``,e[va]&&(r.display=`none`))}var wa=/\s*!important$/;function Ta(e,t,n){if(d(n))n.forEach(n=>Ta(e,t,n));else if(n??=``,t.startsWith(`--`))e.setProperty(t,n);else{let r=Oa(e,t);wa.test(n)?e.setProperty(E(r),n.replace(wa,``),`important`):e[r]=n}}var Ea=[`Webkit`,`Moz`,`ms`],Da={};function Oa(e,t){let n=Da[t];if(n)return n;let r=T(t);if(r!==`filter`&&r in e)return Da[t]=r;r=ie(r);for(let n=0;nza||=(Ba.then(()=>za=0),Date.now());function Ha(e,t){let n=e=>{if(!e._vts)e._vts=Date.now();else if(e._vts<=n.attached)return;tn(Ua(e,n.value),t,5,[e])};return n.value=e,n.attached=Va(),n}function Ua(e,t){if(d(t)){let n=e.stopImmediatePropagation;return e.stopImmediatePropagation=()=>{n.call(e),e._stopped=!0},t.map(e=>t=>!t._stopped&&e&&e(t))}else return t}var Wa=e=>e.charCodeAt(0)===111&&e.charCodeAt(1)===110&&e.charCodeAt(2)>96&&e.charCodeAt(2)<123,Ga=(e,t,n,r,i,s)=>{let c=i===`svg`;t===`class`?ga(e,r,c):t===`style`?Ca(e,n,r):a(t)?o(t)||Ia(e,t,n,r,s):(t[0]===`.`?(t=t.slice(1),!0):t[0]===`^`?(t=t.slice(1),!1):Ka(e,t,r,c))?(Ma(e,t,r),!e.tagName.includes(`-`)&&(t===`value`||t===`checked`||t===`selected`)&&ja(e,t,r,c,s,t!==`value`)):e._isVueCE&&(qa(e,t)||e._def.__asyncLoader&&(/[A-Z]/.test(t)||!g(r)))?Ma(e,T(t),r,s,t):(t===`true-value`?e._trueValue=r:t===`false-value`&&(e._falseValue=r),ja(e,t,r,c))};function Ka(e,t,n,r){if(r)return!!(t===`innerHTML`||t===`textContent`||t in e&&Wa(t)&&h(n));if(t===`spellcheck`||t===`draggable`||t===`translate`||t===`autocorrect`||t===`sandbox`&&e.tagName===`IFRAME`||t===`form`||t===`list`&&e.tagName===`INPUT`||t===`type`&&e.tagName===`TEXTAREA`)return!1;if(t===`width`||t===`height`){let t=e.tagName;if(t===`IMG`||t===`VIDEO`||t===`CANVAS`||t===`SOURCE`)return!1}return Wa(t)&&g(n)?!1:t in e}function qa(e,t){let n=e._def.props;if(!n)return!1;let r=T(t);return Array.isArray(n)?n.some(e=>T(e)===r):Object.keys(n).some(e=>T(e)===r)}var Ja=e=>{let t=e.props[`onUpdate:modelValue`]||!1;return d(t)?e=>oe(t,e):t};function Ya(e){e.target.composing=!0}function Xa(e){let t=e.target;t.composing&&(t.composing=!1,t.dispatchEvent(new Event(`input`)))}var Za=Symbol(`_assign`);function Qa(e,t,n){return t&&(e=e.trim()),n&&(e=se(e)),e}var Q={created(e,{modifiers:{lazy:t,trim:n,number:r}},i){e[Za]=Ja(i);let a=r||i.props&&i.props.type===`number`;Na(e,t?`change`:`input`,t=>{t.target.composing||e[Za](Qa(e.value,n,a))}),(n||a)&&Na(e,`change`,()=>{e.value=Qa(e.value,n,a)}),t||(Na(e,`compositionstart`,Ya),Na(e,`compositionend`,Xa),Na(e,`change`,Xa))},mounted(e,{value:t}){e.value=t??``},beforeUpdate(e,{value:t,oldValue:n,modifiers:{lazy:r,trim:i,number:a}},o){if(e[Za]=Ja(o),e.composing)return;let s=(a||e.type===`number`)&&!/^0\d/.test(e.value)?se(e.value):e.value,c=t??``;if(s===c)return;let l=e.getRootNode();(l instanceof Document||l instanceof ShadowRoot)&&l.activeElement===e&&e.type!==`range`&&(r&&t===n||i&&e.value.trim()===c)||(e.value=c)}},$a={deep:!0,created(e,{value:t,modifiers:{number:n}},r){let i=p(t);Na(e,`change`,()=>{let t=Array.prototype.filter.call(e.options,e=>e.selected).map(e=>n?se(to(e)):to(e));e[Za](e.multiple?i?new Set(t):t:t[0]),e._assigning=!0,dn(()=>{e._assigning=!1})}),e[Za]=Ja(r)},mounted(e,{value:t}){eo(e,t)},beforeUpdate(e,t,n){e[Za]=Ja(n)},updated(e,{value:t}){e._assigning||eo(e,t)}};function eo(e,t){let n=e.multiple,r=d(t);if(!(n&&!r&&!p(t))){for(let i=0,a=e.options.length;iString(e)===String(o)):a.selected=be(t,o)>-1}else a.selected=t.has(o);else if(ye(to(a),t)){e.selectedIndex!==i&&(e.selectedIndex=i);return}}!n&&e.selectedIndex!==-1&&(e.selectedIndex=-1)}}function to(e){return`_value`in e?e._value:e.value}var no=[`ctrl`,`shift`,`alt`,`meta`],ro={stop:e=>e.stopPropagation(),prevent:e=>e.preventDefault(),self:e=>e.target!==e.currentTarget,ctrl:e=>!e.ctrlKey,shift:e=>!e.shiftKey,alt:e=>!e.altKey,meta:e=>!e.metaKey,left:e=>`button`in e&&e.button!==0,middle:e=>`button`in e&&e.button!==1,right:e=>`button`in e&&e.button!==2,exact:(e,t)=>no.some(n=>e[`${n}Key`]&&!t.includes(n))},$=(e,t)=>{if(!e)return e;let n=e._withMods||={},r=t.join(`.`);return n[r]||(n[r]=((n,...r)=>{for(let e=0;e{let t=oo().createApp(...e),{mount:n}=t;return t.mount=e=>{let r=lo(e);if(!r)return;let i=t._component;!h(i)&&!i.render&&!i.template&&(i.template=r.innerHTML),r.nodeType===1&&(r.textContent=``);let a=n(r,!1,co(r));return r instanceof Element&&(r.removeAttribute(`v-cloak`),r.setAttribute(`data-v-app`,``)),a},t});function co(e){if(e instanceof SVGElement)return`svg`;if(typeof MathMLElement==`function`&&e instanceof MathMLElement)return`mathml`}function lo(e){return g(e)?document.querySelector(e):e}var uo=`Lowpass (低通)`,fo=`(無) 手動自訂`,po=1e5,mo=`0.5, 0.5, 0.0, 0.0`,ho=`1.0, 0.0, 0.0, 0.0`,go=14,_o=[0,0,0,0,0,0,0],vo={fc:1e3,order:1,bp_f_low:500,bp_f_high:2e3,bp_order:1,notch_f0:120,notch_q:1,opoz_fz:15e3,opoz_fp:10,tp1z_fz:200,tp1z_fp1:10,tp1z_fp2:5e3,tptz_fz1:200,tptz_fz2:25e3,tptz_fp1:10,tptz_fp2:5e3,kp:.003,ki:10,kd:16e-6,sogi_f0:60,sogi_k:1.414},yo=()=>({...vo}),bo=()=>[..._o],xo={data(){return{fs:po,b_str:mo,a_str:ho,filterType:uo,filterOptions:[`Lowpass (低通)`,`Highpass (高通)`,`Bandpass (帶通)`,`Notch (陷波器)`,`1P1Z (一極一零)`,`2P1Z (二極一零)`,`2P2Z (二極二零)`,`PID 控制器`,`SOGI-Alpha (帶通)`,`SOGI-Beta (低通)`,`(無) 手動自訂`],systemGain:1,params:yo(),isDarkMode:!1,baseB:[.5,.5,0,0,0,0,0],baseA:[1,0,0,0,0,0,0],bSliders:bo(),aSliders:bo(),sense_b:`2x`,sense_a:`2x`,loadingBode:!1,bodeTimeout:null,globalError:null,csvFile:null,csvColumns:[],csvPreview:[],csvInfo:null,csvParseError:null,selectedColumn:0,loadingFilter:!1,filterDone:!1,timePlotData:null,mobileTab:`settings`,shiftBitsB:go,shiftBitsA:go,fixedOverrides:{a:{},b:{}},outOfRangeB:[!1,!1,!1,!1,!1,!1,!1],outOfRangeA:[!1,!1,!1,!1,!1,!1,!1],aFineStep:.01,aFineRepeatDelayTimer:null,aFineRepeatTimer:null,aFineDrag:null,shiftBitRepeatDelayTimer:null,shiftBitRepeatTimer:null,shiftBitDrag:null,fixedAFineStep:1,fixedAFineDrag:null,fixedAFineRepeatDelayTimer:null,fixedAFineRepeatTimer:null,isTouchInput:!1,showAdvancedAdjustment:!1,activeCoeffAdjustment:null}},computed:{maxLogB(){return this.sense_b===`1%`?Math.log10(1.01):this.sense_b===`2x`?Math.log10(2):1},maxLogA(){return this.sense_a===`1%`?Math.log10(1.01):this.sense_a===`2x`?Math.log10(2):this.sense_a===`10x`?Math.log10(10):Math.log10(2)},b_int_str:{get(){return this.fixedPointCoeffs.b.map(e=>e.val).join(`, `)},set(e){let t=e.replace(/[^0-9,\-\s]/g,``);this.parseCoeffs(t).forEach((e,t)=>{this.fixedOverrides.b[t]=Math.round(e)}),this.debouncedUpdateBode()}},a_int_str:{get(){return this.fixedPointCoeffs.a.map(e=>e.val).join(`, `)},set(e){let t=e.replace(/[^0-9,\-\s]/g,``);this.parseCoeffs(t).forEach((e,t)=>{this.fixedOverrides.a[t]=Math.round(e)}),this.debouncedUpdateBode()}},fixedPointCoeffs(){let e=2**this.shiftBitsB,t=2**this.shiftBitsA,n=this.parseCoeffs(this.b_str),r=this.parseCoeffs(this.a_str);return{b:n.map((t,n)=>{let r=Math.round(t*e),i=this.fixedOverrides.b[n]===void 0?r:this.fixedOverrides.b[n];return{label:`b${n}`,val:i,isOverridden:this.fixedOverrides.b[n]!==void 0}}),a:r.map((e,n)=>{let r=Math.round(e*t),i=this.fixedOverrides.a[n]===void 0?r:this.fixedOverrides.a[n];return{label:`a${n}`,val:i,isOverridden:this.fixedOverrides.a[n]!==void 0}})}},floatingCoeffs(){return{b:this.parseCoeffs(this.b_str).map((e,t)=>({label:`b${t}`,val:parseFloat(e.toPrecision(6))})),a:this.parseCoeffs(this.a_str).map((e,t)=>({label:`a${t}`,val:parseFloat(e.toPrecision(6))}))}},isManualDirty(){if(this.bSliders.some(e=>e!==0)||this.aSliders.some(e=>e!==0))return!0;let e=this.padTo7(this.parseCoeffs(this.b_str)),t=this.padTo7(this.parseCoeffs(this.a_str)),n=this.baseB.map(e=>e*(this.systemGain||1)),r=this.baseA;for(let i=0;i<7;i++){let a=e[i]||0,o=n[i]||0,s=Math.max(1e-8,Math.abs(o)*1e-10);if(Math.abs(a-o)>s)return!0;let c=t[i]||0,l=r[i]||0,u=Math.max(1e-8,Math.abs(l)*1e-10);if(Math.abs(c-l)>u)return!0}return!1},isFixedPointDirty(){return this.shiftBitsB!==go||this.shiftBitsA!==go||Object.keys(this.fixedOverrides.b).length>0||Object.keys(this.fixedOverrides.a).length>0},currentA1(){return this.parseCoeffs(this.a_str)[1]||0},currentA2(){return this.parseCoeffs(this.a_str)[2]||0},currentDelta(){return(this.currentA1+this.currentA2+1)/2},currentR(){return(this.currentA2-this.currentA1-1)/2},currentA1A2Diff(){return this.currentA1-this.currentA2},currentA1A2Sum(){return this.currentA1+this.currentA2},fixedA0Int(){return 2**this.shiftBitsA},fixedCurrentA1(){return this.fixedPointCoeffs.a[1]?.val||0},fixedCurrentA2(){return this.fixedPointCoeffs.a[2]?.val||0},fixedCurrentDelta(){return(this.fixedCurrentA1+this.fixedCurrentA2+this.fixedA0Int)/2},fixedCurrentR(){return(this.fixedCurrentA2-this.fixedCurrentA1-this.fixedA0Int)/2},fixedCurrentA1A2Diff(){return this.fixedCurrentA1-this.fixedCurrentA2},fixedCurrentA1A2Sum(){return this.fixedCurrentA1+this.fixedCurrentA2}},mounted(){this.isTouchInput=window.matchMedia?.(`(pointer: coarse)`).matches||!1,window.addEventListener(`pointerdown`,this.rememberPointerType);let e=localStorage.getItem(`theme`);e&&(this.isDarkMode=e===`dark`),this.isDarkMode?document.documentElement.classList.add(`dark`):document.documentElement.classList.remove(`dark`),this.applyFilterDesign()},beforeUnmount(){window.removeEventListener(`pointerdown`,this.rememberPointerType),this.stopA1A2Repeat(),this.stopAFineDrag(),this.stopShiftBitRepeat(),this.stopShiftBitDrag(),this.stopFixedA1A2Repeat(),this.stopFixedAFineDrag()},methods:{rememberPointerType(e){e.pointerType===`touch`?this.isTouchInput=!0:(e.pointerType===`mouse`||e.pointerType===`pen`)&&(this.isTouchInput=!1)},toggleDarkMode(){this.isDarkMode=!this.isDarkMode,localStorage.setItem(`theme`,this.isDarkMode?`dark`:`light`),this.isDarkMode?document.documentElement.classList.add(`dark`):document.documentElement.classList.remove(`dark`),this.updateBodePlot({switchToChart:!1}),this.timePlotData&&this.drawTimePlot(this.timePlotData)},formatK(e){return e>=1e6?`(~${(e/1e6).toFixed(1).replace(`.0`,``)}M)`:e>=1e3?`(~${(e/1e3).toFixed(1).replace(`.0`,``)}k)`:``},parseCoeffs(e){return e?e.split(/[,\s]+/).map(e=>parseFloat(e.trim())).filter(e=>!isNaN(e)):[]},padTo7(e){let t=e.slice(0,7);for(;t.length<7;)t.push(0);return t},syncBaseFromText(){let e=this.systemGain||1;this.baseB=this.padTo7(this.parseCoeffs(this.b_str)).map(t=>t/e),this.baseA=this.padTo7(this.parseCoeffs(this.a_str)),this.baseA[0]=1,this.fixedOverrides={a:{},b:{}},this.bSliders=[0,0,0,0,0,0,0],this.aSliders=[0,0,0,0,0,0,0],this.outOfRangeB=[!1,!1,!1,!1,!1,!1,!1],this.outOfRangeA=[!1,!1,!1,!1,!1,!1,!1]},resetSlidersB(){this.bSliders=[0,0,0,0,0,0,0],this.b_str=this.baseB.map(e=>parseFloat(e.toPrecision(10))).join(`, `),this.debouncedUpdateBode()},resetSlidersA(){this.aSliders=[0,0,0,0,0,0],this.a_str=this.baseA.map(e=>parseFloat(e.toPrecision(10))).join(`, `),this.debouncedUpdateBode()},clearManualAdjustments(){this.bSliders=[0,0,0,0,0,0,0],this.aSliders=[0,0,0,0,0,0,0];let e=this.systemGain||1;this.b_str=this.baseB.map(t=>parseFloat((t*e).toPrecision(10))).join(`, `),this.a_str=this.baseA.map(e=>parseFloat(e.toPrecision(10))).join(`, `),this.showAdvancedAdjustment=!1,this.activeCoeffAdjustment=null,this.calcSlidersFromText(),this.updateBodePlot({switchToChart:!1})},updateFromControls(){let e=this.baseB.map((e,t)=>e*(this.systemGain||1)*10**(this.bSliders[t]||0)),t=[1];for(let e=1;e<7;e++)t.push(this.baseA[e]*10**(this.aSliders[e]||0));this.b_str=e.map(e=>parseFloat(e.toPrecision(10))).join(`, `),this.a_str=t.map(e=>parseFloat(e.toPrecision(10))).join(`, `),this.debouncedUpdateBode()},updateFromText(){this.updateBodePlot({switchToChart:!1})},stepDecimals(e){let t=String(e);return t.includes(`e-`)?Number(t.split(`e-`)[1]):t.includes(`.`)?t.split(`.`)[1].length:0},roundToStep(e,t=this.aFineStep){let n=1/t;return Math.round(e*n)/n},formatFineCoeff(e){return Number.isFinite(e)?Number(e).toString():`0`},formatAFineDelta(e=this.aFineStep){return this.roundToStep(e,e).toFixed(this.stepDecimals(e))},formatFixedFineCoeff(e){return Number.isFinite(e)?String(e):`0`},formatFixedAFineDelta(e=this.fixedAFineStep){return String(e)},adjustAFineStep(e){let t=this.aFineStep*(e>0?.1:10),n=Math.min(1,Math.max(1e-9,t));this.aFineStep=Number(n.toPrecision(12))},adjustFixedAFineStep(e){let t=this.fixedAFineStep*(e>0?.1:10);this.fixedAFineStep=Math.max(1,Math.min(1e9,Math.round(t)))},setDeltaR(e,t){let n=Number(e),r=Number(t);!Number.isFinite(n)||!Number.isFinite(r)||this.setA1A2(-1-r+n,r+n)},setAFineDirect(e,t){let n=parseFloat(t);Number.isFinite(n)&&(e===`delta`?this.setDeltaR(n,this.currentR):e===`r`&&this.setDeltaR(this.currentDelta,n))},adjustAFineValue(e,t){let n=t*this.aFineStep;e===`delta`?this.setDeltaR(this.currentDelta+n,this.currentR):e===`r`&&this.setDeltaR(this.currentDelta,this.currentR+n)},handleAFineWheel(e,t){if(!t.shiftKey){t.currentTarget?.blur?.();return}t.preventDefault();let n=t.deltaY<0?1:-1,r=Math.max(1,Math.round(Math.abs(t.deltaY)/80));this.adjustAFineValue(e,n*r)},startAFineDrag(e,t){t.pointerType===`touch`&&(t.preventDefault(),this.aFineDrag={target:e,lastY:t.clientY,remainder:0},window.addEventListener(`pointermove`,this.moveAFineDrag,{passive:!1}),window.addEventListener(`pointerup`,this.stopAFineDrag),window.addEventListener(`pointercancel`,this.stopAFineDrag))},moveAFineDrag(e){if(!this.aFineDrag)return;e.preventDefault();let t=this.aFineDrag.lastY-e.clientY;this.aFineDrag.lastY=e.clientY,this.aFineDrag.remainder+=t;let n=Math.trunc(this.aFineDrag.remainder/18);n!==0&&(this.aFineDrag.remainder-=n*18,this.adjustAFineValue(this.aFineDrag.target,n))},stopAFineDrag(){this.aFineDrag=null,window.removeEventListener(`pointermove`,this.moveAFineDrag),window.removeEventListener(`pointerup`,this.stopAFineDrag),window.removeEventListener(`pointercancel`,this.stopAFineDrag)},setFixedDeltaR(e,t){let n=Number(e),r=Number(t);!Number.isFinite(n)||!Number.isFinite(r)||(this.fixedOverrides.a[1]=Math.round(-this.fixedA0Int-r+n),this.fixedOverrides.a[2]=Math.round(r+n),this.debouncedUpdateBode())},setFixedAFineDirect(e,t){let n=parseFloat(t);Number.isFinite(n)&&(e===`delta`?this.setFixedDeltaR(n,this.fixedCurrentR):e===`r`&&this.setFixedDeltaR(this.fixedCurrentDelta,n))},adjustFixedAFineValue(e,t){let n=t*this.fixedAFineStep;e===`delta`?this.setFixedDeltaR(this.fixedCurrentDelta+n,this.fixedCurrentR):e===`r`&&this.setFixedDeltaR(this.fixedCurrentDelta,this.fixedCurrentR+n)},handleFixedAFineWheel(e,t){if(!t.shiftKey){t.currentTarget?.blur?.();return}t.preventDefault();let n=t.deltaY<0?1:-1,r=Math.max(1,Math.round(Math.abs(t.deltaY)/80));this.adjustFixedAFineValue(e,n*r)},startFixedA1A2Repeat(e,t){this.stopFixedA1A2Repeat(),this.adjustFixedAFineValue(e,t),this.fixedAFineRepeatDelayTimer=setTimeout(()=>{this.fixedAFineRepeatTimer=setInterval(()=>{this.adjustFixedAFineValue(e,t)},80)},350)},stopFixedA1A2Repeat(){clearTimeout(this.fixedAFineRepeatDelayTimer),clearInterval(this.fixedAFineRepeatTimer),this.fixedAFineRepeatDelayTimer=null,this.fixedAFineRepeatTimer=null},startFixedAFineDrag(e,t){t.pointerType===`touch`&&(t.preventDefault(),this.fixedAFineDrag={target:e,lastY:t.clientY,remainder:0},window.addEventListener(`pointermove`,this.moveFixedAFineDrag,{passive:!1}),window.addEventListener(`pointerup`,this.stopFixedAFineDrag),window.addEventListener(`pointercancel`,this.stopFixedAFineDrag))},moveFixedAFineDrag(e){if(!this.fixedAFineDrag)return;e.preventDefault();let t=this.fixedAFineDrag.lastY-e.clientY;this.fixedAFineDrag.lastY=e.clientY,this.fixedAFineDrag.remainder+=t;let n=Math.trunc(this.fixedAFineDrag.remainder/18);n!==0&&(this.fixedAFineDrag.remainder-=n*18,this.adjustFixedAFineValue(this.fixedAFineDrag.target,n))},stopFixedAFineDrag(){this.fixedAFineDrag=null,window.removeEventListener(`pointermove`,this.moveFixedAFineDrag),window.removeEventListener(`pointerup`,this.stopFixedAFineDrag),window.removeEventListener(`pointercancel`,this.stopFixedAFineDrag)},normalizeShiftBits(e){let t=parseInt(e,10);return Number.isFinite(t)?Math.max(0,t):0},setShiftBits(e,t){let n=this.normalizeShiftBits(t);e===`b`?this.shiftBitsB=n:this.shiftBitsA=n,this.clearFixedOverrides(e),this.debouncedUpdateBode()},adjustShiftBits(e,t){let n=e===`b`?this.shiftBitsB:this.shiftBitsA;this.setShiftBits(e,n+t)},handleShiftBitWheel(e,t){if(!t.shiftKey){t.currentTarget?.blur?.();return}t.preventDefault();let n=t.deltaY<0?1:-1,r=Math.max(1,Math.round(Math.abs(t.deltaY)/80));this.adjustShiftBits(e,n*r)},startShiftBitRepeat(e,t){this.stopShiftBitRepeat(),this.adjustShiftBits(e,t),this.shiftBitRepeatDelayTimer=setTimeout(()=>{this.shiftBitRepeatTimer=setInterval(()=>{this.adjustShiftBits(e,t)},80)},350)},stopShiftBitRepeat(){clearTimeout(this.shiftBitRepeatDelayTimer),clearInterval(this.shiftBitRepeatTimer),this.shiftBitRepeatDelayTimer=null,this.shiftBitRepeatTimer=null},startShiftBitDrag(e,t){t.pointerType===`touch`&&(t.preventDefault(),this.shiftBitDrag={type:e,lastY:t.clientY,remainder:0},window.addEventListener(`pointermove`,this.moveShiftBitDrag,{passive:!1}),window.addEventListener(`pointerup`,this.stopShiftBitDrag),window.addEventListener(`pointercancel`,this.stopShiftBitDrag))},moveShiftBitDrag(e){if(!this.shiftBitDrag)return;e.preventDefault();let t=this.shiftBitDrag.lastY-e.clientY;this.shiftBitDrag.lastY=e.clientY,this.shiftBitDrag.remainder+=t;let n=Math.trunc(this.shiftBitDrag.remainder/18);n!==0&&(this.shiftBitDrag.remainder-=n*18,this.adjustShiftBits(this.shiftBitDrag.type,n))},stopShiftBitDrag(){this.shiftBitDrag=null,window.removeEventListener(`pointermove`,this.moveShiftBitDrag),window.removeEventListener(`pointerup`,this.stopShiftBitDrag),window.removeEventListener(`pointercancel`,this.stopShiftBitDrag)},setA1A2(e,t){let n=this.padTo7(this.parseCoeffs(this.a_str));n[0]=1,n[1]=Number(e),n[2]=Number(t),this.a_str=n.map(e=>Number.isFinite(e)?Number(e).toString():`0`).join(`, `),this.calcSlidersFromText(),this.debouncedUpdateBode()},adjustA1A2(e,t){let n=this.aFineStep*t;e===`delta`?this.setDeltaR(this.currentDelta+n,this.currentR):e===`r`&&this.setDeltaR(this.currentDelta,this.currentR+n)},startA1A2Repeat(e,t){this.stopA1A2Repeat(),this.adjustA1A2(e,t),this.aFineRepeatDelayTimer=setTimeout(()=>{this.aFineRepeatTimer=setInterval(()=>{this.adjustA1A2(e,t)},80)},350)},stopA1A2Repeat(){clearTimeout(this.aFineRepeatDelayTimer),clearInterval(this.aFineRepeatTimer),this.aFineRepeatDelayTimer=null,this.aFineRepeatTimer=null},enableAdvancedAdjustment(){this.calcSlidersFromText(),this.showAdvancedAdjustment=!0,this.activeCoeffAdjustment=`a1a2`},toggleCoeffAdjustment(e){if(this.activeCoeffAdjustment===e){this.activeCoeffAdjustment=null,this.showAdvancedAdjustment=!1;return}this.activeCoeffAdjustment=e,this.showAdvancedAdjustment=e===`a1a2`,e===`a1a2`&&this.calcSlidersFromText()},calcSlidersFromText(){let e=this.systemGain||1,t=this.parseCoeffs(this.b_str),n=this.parseCoeffs(this.a_str);for(let n=0;n<7;n++){let r=t[n]||0,i=this.baseB[n]||0;if(this.outOfRangeB[n]=!1,i!==0&&r!==0&&r/(i*e)>0){let t=Math.log10(r/(i*e));Math.abs(t)<1e-12&&(t=0),Math.abs(t)>this.maxLogB&&(this.outOfRangeB[n]=!0),this.bSliders[n]=Math.max(-this.maxLogB,Math.min(this.maxLogB,t))}else this.bSliders[n]=0,r!==0&&i!==0&&(this.outOfRangeB[n]=!0)}for(let e=1;e<7;e++){let t=n[e]||0,r=this.baseA[e]||0;if(this.outOfRangeA[e]=!1,r!==0&&t!==0&&t/r>0){let n=Math.log10(t/r);Math.abs(n)<1e-12&&(n=0),Math.abs(n)>this.maxLogA&&(this.outOfRangeA[e]=!0),this.aSliders[e]=Math.max(-this.maxLogA,Math.min(this.maxLogA,n))}else this.aSliders[e]=0,t!==0&&r!==0&&(this.outOfRangeA[e]=!0)}},debouncedUpdateFromText(e){e===`b`&&(this.b_str=this.b_str.replace(/[^0-9,.\-\s]/g,``)),e===`a`&&(this.a_str=this.a_str.replace(/[^0-9,.\-\s]/g,``)),this.calcSlidersFromText(),this.debouncedUpdateBode()},onlyNumberKey(e,t=!0){[`Backspace`,`Delete`,`ArrowLeft`,`ArrowRight`,`Tab`,`Enter`,`Home`,`End`].includes(e.key)||e.ctrlKey||e.metaKey||(t?/[0-9,.\-\s]/:/[0-9,\-\s]/).test(e.key)||e.preventDefault()},updateFromFixed(e,t,n){let r=parseInt(n);isNaN(r)||(this.fixedOverrides[t][e]=r,this.updateBodePlot({switchToChart:!1}))},clearFixedOverrides(e=null){if(e===`a`||e===`b`){this.fixedOverrides[e]={};return}this.fixedOverrides={a:{},b:{}}},resetFixedPointSettings(){this.shiftBitsB=go,this.shiftBitsA=go,this.fixedAFineStep=1,this.clearFixedOverrides(),this.updateBodePlot({switchToChart:!1})},onFsChange(){this.filterType===fo?this.updateBodePlot({switchToChart:!1}):this.applyFilterDesign()},debouncedApply(){clearTimeout(this.bodeTimeout),this.bodeTimeout=setTimeout(()=>{this.filterType===fo?this.updateBodePlot({switchToChart:!1}):this.applyFilterDesign()},300)},debouncedUpdateBode(){clearTimeout(this.bodeTimeout),this.bodeTimeout=setTimeout(()=>this.updateBodePlot({switchToChart:!1}),150)},onGainChange(){this.updateFromControls(),this.debouncedUpdateBode()},onFilterTypeChange(){this.systemGain=1,this.clearFixedOverrides(),this.bSliders=bo(),this.aSliders=bo(),this.outOfRangeB=[!1,!1,!1,!1,!1,!1,!1],this.outOfRangeA=[!1,!1,!1,!1,!1,!1,!1],this.showAdvancedAdjustment=!1,this.activeCoeffAdjustment=null,this.filterType!==fo&&(this.params=yo()),this.applyFilterDesign()},resetFilterParams(){clearTimeout(this.bodeTimeout),this.fs=po,this.filterType=uo,this.systemGain=1,this.params=yo(),this.b_str=mo,this.a_str=ho,this.baseB=this.padTo7(this.parseCoeffs(mo)),this.baseA=this.padTo7(this.parseCoeffs(ho)),this.clearFixedOverrides(),this.bSliders=bo(),this.aSliders=bo(),this.outOfRangeB=[!1,!1,!1,!1,!1,!1,!1],this.outOfRangeA=[!1,!1,!1,!1,!1,!1,!1],this.sense_b=`2x`,this.sense_a=`2x`,this.shiftBitsB=go,this.shiftBitsA=go,this.aFineStep=.01,this.fixedAFineStep=1,this.stopA1A2Repeat(),this.stopAFineDrag(),this.stopFixedA1A2Repeat(),this.stopFixedAFineDrag(),this.stopShiftBitRepeat(),this.stopShiftBitDrag(),this.showAdvancedAdjustment=!1,this.activeCoeffAdjustment=null,this.globalError=null,this.applyFilterDesign()},async applyFilterDesign(){if(this.filterType!==fo){this.globalError=null;try{let e={filter_type:this.filterType,fs:this.fs,lp_fc:this.params.fc,lp_order:this.params.order,hp_fc:this.params.fc,hp_order:this.params.order,bp_f_low:this.params.bp_f_low,bp_f_high:this.params.bp_f_high,bp_order:this.params.bp_order,notch_f0:this.params.notch_f0,notch_q:this.params.notch_q,opoz_fz:this.params.opoz_fz,opoz_fp:this.params.opoz_fp,tp1z_fz:this.params.tp1z_fz,tp1z_fp1:this.params.tp1z_fp1,tp1z_fp2:this.params.tp1z_fp2,tptz_fz1:this.params.tptz_fz1,tptz_fz2:this.params.tptz_fz2,tptz_fp1:this.params.tptz_fp1,tptz_fp2:this.params.tptz_fp2,pid_kp:this.params.kp,pid_ki:this.params.ki,pid_kd:this.params.kd,sogi_f0:this.params.sogi_f0,sogi_k:this.params.sogi_k},t=await fetch(`/api/design`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify(e)});if(!t.ok){let e=await t.json();throw Error(e.detail||`設計濾波器失敗`)}let n=await t.json();this.baseB=this.padTo7(n.b),this.baseA=this.padTo7(n.a),this.baseA[0]=1,this.bSliders=[0,0,0,0,0,0,0],this.aSliders=[0,0,0,0,0,0,0],this.showAdvancedAdjustment=!1,this.activeCoeffAdjustment=null,this.updateFromControls(),this.updateBodePlot({switchToChart:!1})}catch(e){this.globalError=e.message}}},async updateBodePlot({switchToChart:e=!0}={}){this.loadingBode=!0,this.globalError=null;try{let t=this.parseCoeffs(this.b_str),n=this.parseCoeffs(this.a_str);t.length===0&&(t=[1]),n.length===0&&(n=[1]);let r=2**this.shiftBitsB,i=2**this.shiftBitsA,a=t.map((e,t)=>(this.fixedOverrides.b[t]===void 0?Math.round(e*r):this.fixedOverrides.b[t])/r),o=n.map((e,t)=>(this.fixedOverrides.a[t]===void 0?Math.round(e*i):this.fixedOverrides.a[t])/i),[s,c]=await Promise.all([fetch(`/api/bode`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({b:t,a:n,fs:this.fs})}),fetch(`/api/bode`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({b:a,a:o,fs:this.fs})})]);if(!s.ok||!c.ok)throw Error(`無法計算頻率響應`);let l=await s.json(),u=await c.json();this.drawBodePlot(l.freq,l.mag,l.phase,u.mag,u.phase),e&&window.innerWidth<1024&&(this.mobileTab=`chart`)}catch(e){this.globalError=e.message}finally{this.loadingBode=!1}},drawBodePlot(e,t,n,r,i){let a=this.fs,o=e[0],s=e[e.length-1],c=this.isDarkMode,l=window.innerWidth<768,u=[],d=[],f=Math.floor(Math.log10(o)),p=Math.ceil(Math.log10(s));for(let e=f;e<=p;e++)for(let t of[1,2,5]){let n=t*10**e;ns||(u.push(n),n<1?d.push(n.toPrecision(3)):n<1e3?d.push(String(n)):n<1e6?d.push(n/1e3+`k`):d.push(n/1e6+`M`))}let m=[],h=[],g=(e,t,n)=>{let r=n===1?`y`:`y2`;m.push({type:`line`,x0:e,x1:e,y0:0,y1:1,xref:n===1?`x`:`x2`,yref:r+` domain`,line:{color:c?`rgba(230,184,180,0.72)`:`rgba(162,95,91,0.72)`,width:1.4,dash:`dash`}}),t&&h.push({x:Math.log10(e),y:1,text:t,xref:n===1?`x`:`x2`,yref:r+` domain`,showarrow:!1,font:{color:c?`#e6b8b4`:`#a25f5b`,size:l?10:12},yshift:l?15:12,xanchor:`center`,yanchor:l?`middle`:`bottom`,textangle:l?-90:0})};g(a/2,`Nyquist`,1),g(a,`fs`,1),g(a/2,null,2),g(a,null,2);for(let e=f;e<=p;e++){let t=10**e;if(t>=o&&t<=s){let e=c?`rgba(199,206,193,0.24)`:`rgba(101,120,104,0.16)`;m.push({type:`line`,x0:t,x1:t,y0:0,y1:1,xref:`x`,yref:`y domain`,line:{color:e,width:1.5}},{type:`line`,x0:t,x1:t,y0:0,y1:1,xref:`x2`,yref:`y2 domain`,line:{color:e,width:1.5}})}}let _=c?`rgba(199,206,193,0.14)`:`rgba(101,120,104,0.09)`,v=c?`rgba(199,206,193,0.24)`:`rgba(70,75,67,0.20)`,y=c?`#c7cec1`:`#42483f`,b=c?`#e5e9df`:`#1b1d19`,x=c?`#0b0e0a`:`#ffffff`,S={type:`log`,title:{text:`Freq (Hz)`,font:{size:l?12:14}},range:[Math.log10(o),Math.log10(s)],tickvals:u,ticktext:d,showgrid:!0,gridcolor:_,tickfont:{color:y,size:l?11:12},nticks:l?6:10},C={paper_bgcolor:x,plot_bgcolor:x,margin:l?{t:80,b:120,l:55,r:15}:{t:70,b:120,l:70,r:30},showlegend:!1,grid:{rows:2,columns:1,pattern:`independent`,roworder:`top to bottom`,ygap:l?.35:.3},font:{color:y,family:`Google Sans, Roboto, sans-serif`},annotations:[{text:`Magnitude Response (dB)`,xref:`x domain`,yref:`y domain`,x:.5,y:l?1.25:1.15,showarrow:!1,font:{size:l?14:16,color:b,weight:`bold`}},{text:`Phase Response (Deg)`,xref:`x2 domain`,yref:`y2 domain`,x:.5,y:l?1.25:1.15,showarrow:!1,font:{size:l?14:16,color:b,weight:`bold`}},{xref:`paper`,yref:`paper`,x:.35,y:l?.52:.54,text:`一一一`,font:{color:c?`#b7c9b8`:`#657868`,size:10},showarrow:!1},{xref:`paper`,yref:`paper`,x:.42,y:l?.52:.54,text:`Ideal (Float)`,font:{color:y,size:11},showarrow:!1,xanchor:`left`},{xref:`paper`,yref:`paper`,x:.58,y:l?.52:.54,text:`· · · ·`,font:{color:c?`#c6cbbf`:`#73786f`,size:14},showarrow:!1},{xref:`paper`,yref:`paper`,x:.63,y:l?.52:.54,text:`Fixed (b Q${this.shiftBitsB}, a Q${this.shiftBitsA})`,font:{color:y,size:11},showarrow:!1,xanchor:`left`},{xref:`paper`,yref:`paper`,x:.35,y:-.15,text:`一一一`,font:{color:c?`#d4c5aa`:`#877b68`,size:10},showarrow:!1},{xref:`paper`,yref:`paper`,x:.42,y:-.15,text:`Ideal Phase`,font:{color:y,size:11},showarrow:!1,xanchor:`left`},{xref:`paper`,yref:`paper`,x:.58,y:-.15,text:`· · · ·`,font:{color:c?`#e6b8b4`:`#a25f5b`,size:14},showarrow:!1},{xref:`paper`,yref:`paper`,x:.63,y:-.15,text:`Fixed Phase`,font:{color:y,size:11},showarrow:!1,xanchor:`left`},...h],xaxis:{...S},yaxis:{title:{text:`Mag (dB)`,font:{size:l?12:14}},range:[-60,0],gridcolor:_,zerolinecolor:v,tickfont:{color:y,size:l?11:12}},xaxis2:{...S},yaxis2:{title:{text:`Phase (°)`,font:{size:l?12:14}},range:[-180,180],tickvals:[-180,-90,0,90,180],gridcolor:_,zerolinecolor:v,tickfont:{color:y,size:l?11:12}},shapes:m},w={x:e,y:t,name:`Ideal (Float)`,type:`scatter`,line:{color:c?`#b7c9b8`:`#657868`,width:2.8}},ee={x:e,y:r,name:`Fixed (b Q${this.shiftBitsB}, a Q${this.shiftBitsA})`,type:`scatter`,line:{color:c?`#c6cbbf`:`#73786f`,width:2.4,dash:`dot`}},te={x:e,y:n,name:`Ideal Phase`,type:`scatter`,line:{color:c?`#d4c5aa`:`#877b68`,width:2.8},xaxis:`x2`,yaxis:`y2`},ne={x:e,y:i,name:`Fixed Phase`,type:`scatter`,line:{color:c?`#e6b8b4`:`#a25f5b`,width:2.4,dash:`dot`},xaxis:`x2`,yaxis:`y2`};Plotly.react(`bodePlot`,[w,ee,te,ne],C,{responsive:!0})},parseCsvText(e,t=1/0){let n=[],r=[],i=``,a=!1,o=0,s=()=>{r.push(i),r.some(e=>e.trim()!==``)&&(o++,n.length{for(let t of e)if(t.type===`childList`)for(let e of t.addedNodes)e.tagName===`LINK`&&e.rel===`modulepreload`&&n(e)}).observe(document,{childList:!0,subtree:!0});function t(e){let t={};return e.integrity&&(t.integrity=e.integrity),e.referrerPolicy&&(t.referrerPolicy=e.referrerPolicy),e.crossOrigin===`use-credentials`?t.credentials=`include`:e.crossOrigin===`anonymous`?t.credentials=`omit`:t.credentials=`same-origin`,t}function n(e){if(e.ep)return;e.ep=!0;let n=t(e);fetch(e.href,n)}})();function e(e){let t=Object.create(null);for(let n of e.split(`,`))t[n]=1;return e=>e in t}var t={},n=[],r=()=>{},i=()=>!1,a=e=>e.charCodeAt(0)===111&&e.charCodeAt(1)===110&&(e.charCodeAt(2)>122||e.charCodeAt(2)<97),o=e=>e.startsWith(`onUpdate:`),s=Object.assign,c=(e,t)=>{let n=e.indexOf(t);n>-1&&e.splice(n,1)},l=Object.prototype.hasOwnProperty,u=(e,t)=>l.call(e,t),d=Array.isArray,f=e=>x(e)===`[object Map]`,p=e=>x(e)===`[object Set]`,m=e=>x(e)===`[object Date]`,h=e=>typeof e==`function`,g=e=>typeof e==`string`,_=e=>typeof e==`symbol`,v=e=>typeof e==`object`&&!!e,y=e=>(v(e)||h(e))&&h(e.then)&&h(e.catch),b=Object.prototype.toString,x=e=>b.call(e),S=e=>x(e).slice(8,-1),C=e=>x(e)===`[object Object]`,w=e=>g(e)&&e!==`NaN`&&e[0]!==`-`&&``+parseInt(e,10)===e,ee=e(`,key,ref,ref_for,ref_key,onVnodeBeforeMount,onVnodeMounted,onVnodeBeforeUpdate,onVnodeUpdated,onVnodeBeforeUnmount,onVnodeUnmounted`),te=e=>{let t=Object.create(null);return(n=>t[n]||(t[n]=e(n)))},ne=/-\w/g,T=te(e=>e.replace(ne,e=>e.slice(1).toUpperCase())),re=/\B([A-Z])/g,E=te(e=>e.replace(re,`-$1`).toLowerCase()),ie=te(e=>e.charAt(0).toUpperCase()+e.slice(1)),ae=te(e=>e?`on${ie(e)}`:``),D=(e,t)=>!Object.is(e,t),oe=(e,...t)=>{for(let n=0;n{Object.defineProperty(e,t,{configurable:!0,enumerable:!1,writable:r,value:n})},se=e=>{let t=parseFloat(e);return isNaN(t)?e:t},ce,le=()=>ce||=typeof globalThis<`u`?globalThis:typeof self<`u`?self:typeof window<`u`?window:typeof global<`u`?global:{};function ue(e){if(d(e)){let t={};for(let n=0;n{if(e){let n=e.split(fe);n.length>1&&(t[n[0].trim()]=n[1].trim())}}),t}function k(e){let t=``;if(g(e))t=e;else if(d(e))for(let n=0;nye(e,t))}var xe=e=>!!(e&&e.__v_isRef===!0),A=e=>g(e)?e:e==null?``:d(e)||v(e)&&(e.toString===b||!h(e.toString))?xe(e)?A(e.value):JSON.stringify(e,Se,2):String(e),Se=(e,t)=>xe(t)?Se(e,t.value):f(t)?{[`Map(${t.size})`]:[...t.entries()].reduce((e,[t,n],r)=>(e[Ce(t,r)+` =>`]=n,e),{})}:p(t)?{[`Set(${t.size})`]:[...t.values()].map(e=>Ce(e))}:_(t)?Ce(t):v(t)&&!d(t)&&!C(t)?String(t):t,Ce=(e,t=``)=>_(e)?`Symbol(${e.description??t})`:e,j,we=class{constructor(e=!1){this.detached=e,this._active=!0,this._on=0,this.effects=[],this.cleanups=[],this._isPaused=!1,this._warnOnRun=!0,this.__v_skip=!0,!e&&j&&(j.active?(this.parent=j,this.index=(j.scopes||=[]).push(this)-1):(this._active=!1,this._warnOnRun=!1))}get active(){return this._active}pause(){if(this._active){this._isPaused=!0;let e,t;if(this.scopes)for(e=0,t=this.scopes.length;e0&&--this._on===0){if(j===this)j=this.prevScope;else{let e=j;for(;e;){if(e.prevScope===this){e.prevScope=this.prevScope;break}e=e.prevScope}}this.prevScope=void 0}}stop(e){if(this._active){this._active=!1;let t,n;for(t=0,n=this.effects.length;t0)return;if(Ae){let e=Ae;for(Ae=void 0;e;){let t=e.next;e.next=void 0,e.flags&=-9,e=t}}let e;for(;ke;){let t=ke;for(ke=void 0;t;){let n=t.next;if(t.next=void 0,t.flags&=-9,t.flags&1)try{t.trigger()}catch(t){e||=t}t=n}}if(e)throw e}function Pe(e){for(let t=e.deps;t;t=t.nextDep)t.version=-1,t.prevActiveLink=t.dep.activeLink,t.dep.activeLink=t}function Fe(e){let t,n=e.depsTail,r=n;for(;r;){let e=r.prevDep;r.version===-1?(r===n&&(n=e),Re(r),ze(r)):t=r,r.dep.activeLink=r.prevActiveLink,r.prevActiveLink=void 0,r=e}e.deps=t,e.depsTail=n}function Ie(e){for(let t=e.deps;t;t=t.nextDep)if(t.dep.version!==t.version||t.dep.computed&&(Le(t.dep.computed)||t.dep.version!==t.version))return!0;return!!e._dirty}function Le(e){if(e.flags&4&&!(e.flags&16)||(e.flags&=-17,e.globalVersion===We)||(e.globalVersion=We,!e.isSSR&&e.flags&128&&(!e.deps&&!e._dirty||!Ie(e))))return;e.flags|=2;let t=e.dep,n=M,r=N;M=e,N=!0;try{Pe(e);let n=e.fn(e._value);(t.version===0||D(n,e._value))&&(e.flags|=128,e._value=n,t.version++)}catch(e){throw t.version++,e}finally{M=n,N=r,Fe(e),e.flags&=-3}}function Re(e,t=!1){let{dep:n,prevSub:r,nextSub:i}=e;if(r&&(r.nextSub=i,e.prevSub=void 0),i&&(i.prevSub=r,e.nextSub=void 0),n.subs===e&&(n.subs=r,!r&&n.computed)){n.computed.flags&=-5;for(let e=n.computed.deps;e;e=e.nextDep)Re(e,!0)}!t&&!--n.sc&&n.map&&n.map.delete(n.key)}function ze(e){let{prevDep:t,nextDep:n}=e;t&&(t.nextDep=n,e.prevDep=void 0),n&&(n.prevDep=t,e.nextDep=void 0)}var N=!0,Be=[];function Ve(){Be.push(N),N=!1}function He(){let e=Be.pop();N=e===void 0?!0:e}function Ue(e){let{cleanup:t}=e;if(e.cleanup=void 0,t){let e=M;M=void 0;try{t()}finally{M=e}}}var We=0,Ge=class{constructor(e,t){this.sub=e,this.dep=t,this.version=t.version,this.nextDep=this.prevDep=this.nextSub=this.prevSub=this.prevActiveLink=void 0}},Ke=class{constructor(e){this.computed=e,this.version=0,this.activeLink=void 0,this.subs=void 0,this.map=void 0,this.key=void 0,this.sc=0,this.__v_skip=!0}track(e){if(!M||!N||M===this.computed)return;let t=this.activeLink;if(t===void 0||t.sub!==M)t=this.activeLink=new Ge(M,this),M.deps?(t.prevDep=M.depsTail,M.depsTail.nextDep=t,M.depsTail=t):M.deps=M.depsTail=t,qe(t);else if(t.version===-1&&(t.version=this.version,t.nextDep)){let e=t.nextDep;e.prevDep=t.prevDep,t.prevDep&&(t.prevDep.nextDep=e),t.prevDep=M.depsTail,t.nextDep=void 0,M.depsTail.nextDep=t,M.depsTail=t,M.deps===t&&(M.deps=e)}return t}trigger(e){this.version++,We++,this.notify(e)}notify(e){Me();try{for(let e=this.subs;e;e=e.prevSub)e.sub.notify()&&e.sub.dep.notify()}finally{Ne()}}};function qe(e){if(e.dep.sc++,e.sub.flags&4){let t=e.dep.computed;if(t&&!e.dep.subs){t.flags|=20;for(let e=t.deps;e;e=e.nextDep)qe(e)}let n=e.dep.subs;n!==e&&(e.prevSub=n,n&&(n.nextSub=e)),e.dep.subs=e}}var Je=new WeakMap,Ye=Symbol(``),Xe=Symbol(``),Ze=Symbol(``);function P(e,t,n){if(N&&M){let t=Je.get(e);t||Je.set(e,t=new Map);let r=t.get(n);r||(t.set(n,r=new Ke),r.map=t,r.key=n),r.track()}}function Qe(e,t,n,r,i,a){let o=Je.get(e);if(!o){We++;return}let s=e=>{e&&e.trigger()};if(Me(),t===`clear`)o.forEach(s);else{let i=d(e),a=i&&w(n);if(i&&n===`length`){let e=Number(r);o.forEach((t,n)=>{(n===`length`||n===Ze||!_(n)&&n>=e)&&s(t)})}else switch((n!==void 0||o.has(void 0))&&s(o.get(n)),a&&s(o.get(Ze)),t){case`add`:i?a&&s(o.get(`length`)):(s(o.get(Ye)),f(e)&&s(o.get(Xe)));break;case`delete`:i||(s(o.get(Ye)),f(e)&&s(o.get(Xe)));break;case`set`:f(e)&&s(o.get(Ye));break}}Ne()}function $e(e){let t=I(e);return t===e?t:(P(t,`iterate`,Ze),F(e)?t:t.map(Vt))}function et(e){return P(e=I(e),`iterate`,Ze),e}function tt(e,t){return Rt(e)?Ht(Lt(e)?Vt(t):t):Vt(t)}var nt={__proto__:null,[Symbol.iterator](){return rt(this,Symbol.iterator,e=>tt(this,e))},concat(...e){return $e(this).concat(...e.map(e=>d(e)?$e(e):e))},entries(){return rt(this,`entries`,e=>(e[1]=tt(this,e[1]),e))},every(e,t){return at(this,`every`,e,t,void 0,arguments)},filter(e,t){return at(this,`filter`,e,t,e=>e.map(e=>tt(this,e)),arguments)},find(e,t){return at(this,`find`,e,t,e=>tt(this,e),arguments)},findIndex(e,t){return at(this,`findIndex`,e,t,void 0,arguments)},findLast(e,t){return at(this,`findLast`,e,t,e=>tt(this,e),arguments)},findLastIndex(e,t){return at(this,`findLastIndex`,e,t,void 0,arguments)},forEach(e,t){return at(this,`forEach`,e,t,void 0,arguments)},includes(...e){return st(this,`includes`,e)},indexOf(...e){return st(this,`indexOf`,e)},join(e){return $e(this).join(e)},lastIndexOf(...e){return st(this,`lastIndexOf`,e)},map(e,t){return at(this,`map`,e,t,void 0,arguments)},pop(){return ct(this,`pop`)},push(...e){return ct(this,`push`,e)},reduce(e,...t){return ot(this,`reduce`,e,t)},reduceRight(e,...t){return ot(this,`reduceRight`,e,t)},shift(){return ct(this,`shift`)},some(e,t){return at(this,`some`,e,t,void 0,arguments)},splice(...e){return ct(this,`splice`,e)},toReversed(){return $e(this).toReversed()},toSorted(e){return $e(this).toSorted(e)},toSpliced(...e){return $e(this).toSpliced(...e)},unshift(...e){return ct(this,`unshift`,e)},values(){return rt(this,`values`,e=>tt(this,e))}};function rt(e,t,n){let r=et(e),i=r[t]();return r!==e&&!F(e)&&(i._next=i.next,i.next=()=>{let e=i._next();return e.done||(e.value=n(e.value)),e}),i}var it=Array.prototype;function at(e,t,n,r,i,a){let o=et(e),s=o!==e&&!F(e),c=o[t];if(c!==it[t]){let t=c.apply(e,a);return s?Vt(t):t}let l=n;o!==e&&(s?l=function(t,r){return n.call(this,tt(e,t),r,e)}:n.length>2&&(l=function(t,r){return n.call(this,t,r,e)}));let u=c.call(o,l,r);return s&&i?i(u):u}function ot(e,t,n,r){let i=et(e),a=i!==e&&!F(e),o=n,s=!1;i!==e&&(a?(s=r.length===0,o=function(t,r,i){return s&&(s=!1,t=tt(e,t)),n.call(this,t,tt(e,r),i,e)}):n.length>3&&(o=function(t,r,i){return n.call(this,t,r,i,e)}));let c=i[t](o,...r);return s?tt(e,c):c}function st(e,t,n){let r=I(e);P(r,`iterate`,Ze);let i=r[t](...n);return(i===-1||i===!1)&&zt(n[0])?(n[0]=I(n[0]),r[t](...n)):i}function ct(e,t,n=[]){Ve(),Me();let r=I(e)[t].apply(e,n);return Ne(),He(),r}var lt=e(`__proto__,__v_isRef,__isVue`),ut=new Set(Object.getOwnPropertyNames(Symbol).filter(e=>e!==`arguments`&&e!==`caller`).map(e=>Symbol[e]).filter(_));function dt(e){_(e)||(e=String(e));let t=I(this);return P(t,`has`,e),t.hasOwnProperty(e)}var ft=class{constructor(e=!1,t=!1){this._isReadonly=e,this._isShallow=t}get(e,t,n){if(t===`__v_skip`)return e.__v_skip;let r=this._isReadonly,i=this._isShallow;if(t===`__v_isReactive`)return!r;if(t===`__v_isReadonly`)return r;if(t===`__v_isShallow`)return i;if(t===`__v_raw`)return n===(r?i?At:kt:i?Ot:Dt).get(e)||Object.getPrototypeOf(e)===Object.getPrototypeOf(n)?e:void 0;let a=d(e);if(!r){let e;if(a&&(e=nt[t]))return e;if(t===`hasOwnProperty`)return dt}let o=Reflect.get(e,t,L(e)?e:n);if((_(t)?ut.has(t):lt(t))||(r||P(e,`get`,t),i))return o;if(L(o)){let e=a&&w(t)?o:o.value;return r&&v(e)?Ft(e):e}return v(o)?r?Ft(o):Nt(o):o}},pt=class extends ft{constructor(e=!1){super(!1,e)}set(e,t,n,r){let i=e[t],a=d(e)&&w(t);if(!this._isShallow){let e=Rt(i);if(!F(n)&&!Rt(n)&&(i=I(i),n=I(n)),!a&&L(i)&&!L(n))return e||(i.value=n),!0}let o=a?Number(t)e,yt=e=>Reflect.getPrototypeOf(e);function bt(e,t,n){return function(...r){let i=this.__v_raw,a=I(i),o=f(a),c=e===`entries`||e===Symbol.iterator&&o,l=e===`keys`&&o,u=i[e](...r),d=n?vt:t?Ht:Vt;return!t&&P(a,`iterate`,l?Xe:Ye),s(Object.create(u),{next(){let{value:e,done:t}=u.next();return t?{value:e,done:t}:{value:c?[d(e[0]),d(e[1])]:d(e),done:t}}})}}function xt(e){return function(...t){return e===`delete`?!1:e===`clear`?void 0:this}}function St(e,t){let n={get(n){let r=this.__v_raw,i=I(r),a=I(n);e||(D(n,a)&&P(i,`get`,n),P(i,`get`,a));let{has:o}=yt(i),s=t?vt:e?Ht:Vt;if(o.call(i,n))return s(r.get(n));if(o.call(i,a))return s(r.get(a));r!==i&&r.get(n)},get size(){let t=this.__v_raw;return!e&&P(I(t),`iterate`,Ye),t.size},has(t){let n=this.__v_raw,r=I(n),i=I(t);return e||(D(t,i)&&P(r,`has`,t),P(r,`has`,i)),t===i?n.has(t):n.has(t)||n.has(i)},forEach(n,r){let i=this,a=i.__v_raw,o=I(a),s=t?vt:e?Ht:Vt;return!e&&P(o,`iterate`,Ye),a.forEach((e,t)=>n.call(r,s(e),s(t),i))}};return s(n,e?{add:xt(`add`),set:xt(`set`),delete:xt(`delete`),clear:xt(`clear`)}:{add(e){let n=I(this),r=yt(n),i=I(e),a=!t&&!F(e)&&!Rt(e)?i:e;return r.has.call(n,a)||D(e,a)&&r.has.call(n,e)||D(i,a)&&r.has.call(n,i)||(n.add(a),Qe(n,`add`,a,a)),this},set(e,n){!t&&!F(n)&&!Rt(n)&&(n=I(n));let r=I(this),{has:i,get:a}=yt(r),o=i.call(r,e);o||=(e=I(e),i.call(r,e));let s=a.call(r,e);return r.set(e,n),o?D(n,s)&&Qe(r,`set`,e,n,s):Qe(r,`add`,e,n),this},delete(e){let t=I(this),{has:n,get:r}=yt(t),i=n.call(t,e);i||=(e=I(e),n.call(t,e));let a=r?r.call(t,e):void 0,o=t.delete(e);return i&&Qe(t,`delete`,e,void 0,a),o},clear(){let e=I(this),t=e.size!==0,n=e.clear();return t&&Qe(e,`clear`,void 0,void 0,void 0),n}}),[`keys`,`values`,`entries`,Symbol.iterator].forEach(r=>{n[r]=bt(r,e,t)}),n}function Ct(e,t){let n=St(e,t);return(t,r,i)=>r===`__v_isReactive`?!e:r===`__v_isReadonly`?e:r===`__v_raw`?t:Reflect.get(u(n,r)&&r in t?n:t,r,i)}var wt={get:Ct(!1,!1)},Tt={get:Ct(!1,!0)},Et={get:Ct(!0,!1)},Dt=new WeakMap,Ot=new WeakMap,kt=new WeakMap,At=new WeakMap;function jt(e){switch(e){case`Object`:case`Array`:return 1;case`Map`:case`Set`:case`WeakMap`:case`WeakSet`:return 2;default:return 0}}function Mt(e){return e.__v_skip||!Object.isExtensible(e)?0:jt(S(e))}function Nt(e){return Rt(e)?e:It(e,!1,ht,wt,Dt)}function Pt(e){return It(e,!1,_t,Tt,Ot)}function Ft(e){return It(e,!0,gt,Et,kt)}function It(e,t,n,r,i){if(!v(e)||e.__v_raw&&!(t&&e.__v_isReactive))return e;let a=Mt(e);if(a===0)return e;let o=i.get(e);if(o)return o;let s=new Proxy(e,a===2?r:n);return i.set(e,s),s}function Lt(e){return Rt(e)?Lt(e.__v_raw):!!(e&&e.__v_isReactive)}function Rt(e){return!!(e&&e.__v_isReadonly)}function F(e){return!!(e&&e.__v_isShallow)}function zt(e){return e?!!e.__v_raw:!1}function I(e){let t=e&&e.__v_raw;return t?I(t):e}function Bt(e){return!u(e,`__v_skip`)&&Object.isExtensible(e)&&O(e,`__v_skip`,!0),e}var Vt=e=>v(e)?Nt(e):e,Ht=e=>v(e)?Ft(e):e;function L(e){return e?e.__v_isRef===!0:!1}function Ut(e){return L(e)?e.value:e}var Wt={get:(e,t,n)=>t===`__v_raw`?e:Ut(Reflect.get(e,t,n)),set:(e,t,n,r)=>{let i=e[t];return L(i)&&!L(n)?(i.value=n,!0):Reflect.set(e,t,n,r)}};function Gt(e){return Lt(e)?e:new Proxy(e,Wt)}var Kt=class{constructor(e,t,n){this.fn=e,this.setter=t,this._value=void 0,this.dep=new Ke(this),this.__v_isRef=!0,this.deps=void 0,this.depsTail=void 0,this.flags=16,this.globalVersion=We-1,this.next=void 0,this.effect=this,this.__v_isReadonly=!t,this.isSSR=n}notify(){if(this.flags|=16,!(this.flags&8)&&M!==this)return je(this,!0),!0}get value(){let e=this.dep.track();return Le(this),e&&(e.version=this.dep.version),this._value}set value(e){this.setter&&this.setter(e)}};function qt(e,t,n=!1){let r,i;return h(e)?r=e:(r=e.get,i=e.set),new Kt(r,i,n)}var Jt={},Yt=new WeakMap,Xt=void 0;function Zt(e,t=!1,n=Xt){if(n){let t=Yt.get(n);t||Yt.set(n,t=[]),t.push(e)}}function Qt(e,n,i=t){let{immediate:a,deep:o,once:s,scheduler:l,augmentJob:u,call:f}=i,p=e=>o?e:F(e)||o===!1||o===0?$t(e,1):$t(e),m,g,_,v,y=!1,b=!1;if(L(e)?(g=()=>e.value,y=F(e)):Lt(e)?(g=()=>p(e),y=!0):d(e)?(b=!0,y=e.some(e=>Lt(e)||F(e)),g=()=>e.map(e=>{if(L(e))return e.value;if(Lt(e))return p(e);if(h(e))return f?f(e,2):e()})):g=h(e)?n?f?()=>f(e,2):e:()=>{if(_){Ve();try{_()}finally{He()}}let t=Xt;Xt=m;try{return f?f(e,3,[v]):e(v)}finally{Xt=t}}:r,n&&o){let e=g,t=o===!0?1/0:o;g=()=>$t(e(),t)}let x=Te(),S=()=>{m.stop(),x&&x.active&&c(x.effects,m)};if(s&&n){let e=n;n=(...t)=>{e(...t),S()}}let C=b?Array(e.length).fill(Jt):Jt,w=e=>{if(!(!(m.flags&1)||!m.dirty&&!e))if(n){let e=m.run();if(o||y||(b?e.some((e,t)=>D(e,C[t])):D(e,C))){_&&_();let t=Xt;Xt=m;try{let t=[e,C===Jt?void 0:b&&C[0]===Jt?[]:C,v];C=e,f?f(n,3,t):n(...t)}finally{Xt=t}}}else m.run()};return u&&u(w),m=new De(g),m.scheduler=l?()=>l(w,!1):w,v=e=>Zt(e,!1,m),_=m.onStop=()=>{let e=Yt.get(m);if(e){if(f)f(e,4);else for(let t of e)t();Yt.delete(m)}},n?a?w(!0):C=m.run():l?l(w.bind(null,!0),!0):m.run(),S.pause=m.pause.bind(m),S.resume=m.resume.bind(m),S.stop=S,S}function $t(e,t=1/0,n){if(t<=0||!v(e)||e.__v_skip||(n||=new Map,(n.get(e)||0)>=t))return e;if(n.set(e,t),t--,L(e))$t(e.value,t,n);else if(d(e))for(let r=0;r{$t(e,t,n)});else if(C(e)){for(let r in e)$t(e[r],t,n);for(let r of Object.getOwnPropertySymbols(e))Object.prototype.propertyIsEnumerable.call(e,r)&&$t(e[r],t,n)}return e}function en(e,t,n,r){try{return r?e(...r):e()}catch(e){nn(e,t,n)}}function tn(e,t,n,r){if(h(e)){let i=en(e,t,n,r);return i&&y(i)&&i.catch(e=>{nn(e,t,n)}),i}if(d(e)){let i=[];for(let a=0;a>>1,i=R[r],a=vn(i);a=vn(n)?R.push(e):R.splice(fn(t),0,e),e.flags|=1,mn()}}function mn(){un||=ln.then(yn)}function hn(e){d(e)?on.push(...e):sn&&e.id===-1?sn.splice(cn+1,0,e):e.flags&1||(on.push(e),e.flags|=1),mn()}function gn(e,t,n=an+1){for(;nvn(e)-vn(t));if(on.length=0,sn){sn.push(...e);return}for(sn=e,cn=0;cne.id==null?e.flags&2?-1:1/0:e.id;function yn(e){try{for(an=0;an{r._d&&Ci(-1);let i=xn(t),a;try{a=e(...n)}finally{xn(i),r._d&&Ci(1)}return a};return r._n=!0,r._c=!0,r._d=!0,r}function B(e,n){if(z===null)return e;let r=ra(z),i=e.dirs||=[];for(let e=0;e1)return n&&h(t)?t.call(r&&r.proxy):t}}var En=Symbol.for(`v-scx`),Dn=()=>Tn(En);function On(e,t,n){return kn(e,t,n)}function kn(e,n,i=t){let{immediate:a,deep:o,flush:c,once:l}=i,u=s({},i),d=n&&a||!n&&c!==`post`,f;if(Ji){if(c===`sync`){let e=Dn();f=e.__watcherHandles||=[]}else if(!d){let e=()=>{};return e.stop=r,e.resume=r,e.pause=r,e}}let p=Z;u.call=(e,t,n)=>tn(e,p,t,n);let m=!1;c===`post`?u.scheduler=e=>{U(e,p&&p.suspense)}:c!==`sync`&&(m=!0,u.scheduler=(e,t)=>{t?e():pn(e)}),u.augmentJob=e=>{n&&(e.flags|=4),m&&(e.flags|=2,p&&(e.id=p.uid,e.i=p))};let h=Qt(e,n,u);return Ji&&(f?f.push(h):d&&h()),h}function An(e,t,n){let r=this.proxy,i=g(e)?e.includes(`.`)?jn(r,e):()=>r[e]:e.bind(r,r),a;h(t)?a=t:(a=t.handler,n=t);let o=Gi(this),s=kn(i,a.bind(r),n);return o(),s}function jn(e,t){let n=t.split(`.`);return()=>{let t=e;for(let e=0;ee.__isTeleport,Pn=Symbol(`_leaveCb`);function Fn(e,t){e.shapeFlag&6&&e.component?(e.transition=t,Fn(e.component.subTree,t)):e.shapeFlag&128?(e.ssContent.transition=t.clone(e.ssContent),e.ssFallback.transition=t.clone(e.ssFallback)):e.transition=t}function In(e){e.ids=[e.ids[0]+ e.ids[2]+++`-`,0,0]}function Ln(e,t){let n;return!!((n=Object.getOwnPropertyDescriptor(e,t))&&!n.configurable)}var Rn=new WeakMap;function zn(e,n,r,a,o=!1){if(d(e)){e.forEach((e,t)=>zn(e,n&&(d(n)?n[t]:n),r,a,o));return}if(Vn(a)&&!o){a.shapeFlag&512&&a.type.__asyncResolved&&a.component.subTree.component&&zn(e,n,r,a.component.subTree);return}let s=a.shapeFlag&4?ra(a.component):a.el,l=o?null:s,{i:f,r:p}=e,m=n&&n.r,_=f.refs===t?f.refs={}:f.refs,v=f.setupState,y=I(v),b=v===t?i:e=>Ln(_,e)?!1:u(y,e),x=(e,t)=>!(t&&Ln(_,t));if(m!=null&&m!==p){if(Bn(n),g(m))_[m]=null,b(m)&&(v[m]=null);else if(L(m)){let e=n;x(m,e.k)&&(m.value=null),e.k&&(_[e.k]=null)}}if(h(p))en(p,f,12,[l,_]);else{let t=g(p),n=L(p);if(t||n){let i=()=>{if(e.f){let n=t?b(p)?v[p]:_[p]:x(p)||!e.k?p.value:_[e.k];if(o)d(n)&&c(n,s);else if(d(n))n.includes(s)||n.push(s);else if(t)_[p]=[s],b(p)&&(v[p]=_[p]);else{let t=[s];x(p,e.k)&&(p.value=t),e.k&&(_[e.k]=t)}}else t?(_[p]=l,b(p)&&(v[p]=l)):n&&(x(p,e.k)&&(p.value=l),e.k&&(_[e.k]=l))};if(l){let t=()=>{i(),Rn.delete(e)};t.id=-1,Rn.set(e,t),U(t,r)}else Bn(e),i()}}}function Bn(e){let t=Rn.get(e);t&&(t.flags|=8,Rn.delete(e))}le().requestIdleCallback,le().cancelIdleCallback;var Vn=e=>!!e.type.__asyncLoader,Hn=e=>e.type.__isKeepAlive;function Un(e,t){Gn(e,`a`,t)}function Wn(e,t){Gn(e,`da`,t)}function Gn(e,t,n=Z){let r=e.__wdc||=()=>{let t=n;for(;t;){if(t.isDeactivated)return;t=t.parent}return e()};if(qn(t,r,n),n){let e=n.parent;for(;e&&e.parent;)Hn(e.parent.vnode)&&Kn(r,t,n,e),e=e.parent}}function Kn(e,t,n,r){let i=qn(t,e,r,!0);er(()=>{c(r[t],i)},n)}function qn(e,t,n=Z,r=!1){if(n){let i=n[e]||(n[e]=[]),a=t.__weh||=(...r)=>{Ve();let i=Gi(n),a=tn(t,n,e,r);return i(),He(),a};return r?i.unshift(a):i.push(a),a}}var Jn=e=>(t,n=Z)=>{(!Ji||e===`sp`)&&qn(e,(...e)=>t(...e),n)},Yn=Jn(`bm`),Xn=Jn(`m`),Zn=Jn(`bu`),Qn=Jn(`u`),$n=Jn(`bum`),er=Jn(`um`),tr=Jn(`sp`),nr=Jn(`rtg`),rr=Jn(`rtc`);function ir(e,t=Z){qn(`ec`,e,t)}var ar=Symbol.for(`v-ndc`);function V(e,t,n,r){let i,a=n&&n[r],o=d(e);if(o||g(e)){let n=o&&Lt(e),r=!1,s=!1;n&&(r=!F(e),s=Rt(e),e=et(e)),i=Array(e.length);for(let n=0,o=e.length;nt(e,n,void 0,a&&a[n]));else{let n=Object.keys(e);i=Array(n.length);for(let r=0,o=n.length;re?qi(e)?ra(e):or(e.parent):null,sr=s(Object.create(null),{$:e=>e,$el:e=>e.vnode.el,$data:e=>e.data,$props:e=>e.props,$attrs:e=>e.attrs,$slots:e=>e.slots,$refs:e=>e.refs,$parent:e=>or(e.parent),$root:e=>or(e.root),$host:e=>e.ce,$emit:e=>e.emit,$options:e=>gr(e),$forceUpdate:e=>e.f||=()=>{pn(e.update)},$nextTick:e=>e.n||=dn.bind(e.proxy),$watch:e=>An.bind(e)}),cr=(e,n)=>e!==t&&!e.__isScriptSetup&&u(e,n),lr={get({_:e},n){if(n===`__v_skip`)return!0;let{ctx:r,setupState:i,data:a,props:o,accessCache:s,type:c,appContext:l}=e;if(n[0]!==`$`){let e=s[n];if(e!==void 0)switch(e){case 1:return i[n];case 2:return a[n];case 4:return r[n];case 3:return o[n]}else if(cr(i,n))return s[n]=1,i[n];else if(a!==t&&u(a,n))return s[n]=2,a[n];else if(u(o,n))return s[n]=3,o[n];else if(r!==t&&u(r,n))return s[n]=4,r[n];else dr&&(s[n]=0)}let d=sr[n],f,p;if(d)return n===`$attrs`&&P(e.attrs,`get`,``),d(e);if((f=c.__cssModules)&&(f=f[n]))return f;if(r!==t&&u(r,n))return s[n]=4,r[n];if(p=l.config.globalProperties,u(p,n))return p[n]},set({_:e},n,r){let{data:i,setupState:a,ctx:o}=e;return cr(a,n)?(a[n]=r,!0):i!==t&&u(i,n)?(i[n]=r,!0):u(e.props,n)||n[0]===`$`&&n.slice(1)in e?!1:(o[n]=r,!0)},has({_:{data:e,setupState:n,accessCache:r,ctx:i,appContext:a,props:o,type:s}},c){let l;return!!(r[c]||e!==t&&c[0]!==`$`&&u(e,c)||cr(n,c)||u(o,c)||u(i,c)||u(sr,c)||u(a.config.globalProperties,c)||(l=s.__cssModules)&&l[c])},defineProperty(e,t,n){return n.get==null?u(n,`value`)&&this.set(e,t,n.value,null):e._.accessCache[t]=0,Reflect.defineProperty(e,t,n)}};function ur(e){return d(e)?e.reduce((e,t)=>(e[t]=null,e),{}):e}var dr=!0;function fr(e){let t=gr(e),n=e.proxy,i=e.ctx;dr=!1,t.beforeCreate&&mr(t.beforeCreate,e,`bc`);let{data:a,computed:o,methods:s,watch:c,provide:l,inject:u,created:f,beforeMount:p,mounted:m,beforeUpdate:g,updated:_,activated:y,deactivated:b,beforeDestroy:x,beforeUnmount:S,destroyed:C,unmounted:w,render:ee,renderTracked:te,renderTriggered:ne,errorCaptured:T,serverPrefetch:re,expose:E,inheritAttrs:ie,components:ae,directives:D,filters:oe}=t;if(u&&pr(u,i,null),s)for(let e in s){let t=s[e];h(t)&&(i[e]=t.bind(n))}if(a){let t=a.call(n,n);v(t)&&(e.data=Nt(t))}if(dr=!0,o)for(let e in o){let t=o[e],a=aa({get:h(t)?t.bind(n,n):h(t.get)?t.get.bind(n,n):r,set:!h(t)&&h(t.set)?t.set.bind(n):r});Object.defineProperty(i,e,{enumerable:!0,configurable:!0,get:()=>a.value,set:e=>a.value=e})}if(c)for(let e in c)hr(c[e],i,n,e);if(l){let e=h(l)?l.call(n):l;Reflect.ownKeys(e).forEach(t=>{wn(t,e[t])})}f&&mr(f,e,`c`);function O(e,t){d(t)?t.forEach(t=>e(t.bind(n))):t&&e(t.bind(n))}if(O(Yn,p),O(Xn,m),O(Zn,g),O(Qn,_),O(Un,y),O(Wn,b),O(ir,T),O(rr,te),O(nr,ne),O($n,S),O(er,w),O(tr,re),d(E))if(E.length){let t=e.exposed||={};E.forEach(e=>{Object.defineProperty(t,e,{get:()=>n[e],set:t=>n[e]=t,enumerable:!0})})}else e.exposed||={};ee&&e.render===r&&(e.render=ee),ie!=null&&(e.inheritAttrs=ie),ae&&(e.components=ae),D&&(e.directives=D),re&&In(e)}function pr(e,t,n=r){d(e)&&(e=xr(e));for(let n in e){let r=e[n],i;i=v(r)?`default`in r?Tn(r.from||n,r.default,!0):Tn(r.from||n):Tn(r),L(i)?Object.defineProperty(t,n,{enumerable:!0,configurable:!0,get:()=>i.value,set:e=>i.value=e}):t[n]=i}}function mr(e,t,n){tn(d(e)?e.map(e=>e.bind(t.proxy)):e.bind(t.proxy),t,n)}function hr(e,t,n,r){let i=r.includes(`.`)?jn(n,r):()=>n[r];if(g(e)){let n=t[e];h(n)&&On(i,n)}else if(h(e))On(i,e.bind(n));else if(v(e))if(d(e))e.forEach(e=>hr(e,t,n,r));else{let r=h(e.handler)?e.handler.bind(n):t[e.handler];h(r)&&On(i,r,e)}}function gr(e){let t=e.type,{mixins:n,extends:r}=t,{mixins:i,optionsCache:a,config:{optionMergeStrategies:o}}=e.appContext,s=a.get(t),c;return s?c=s:!i.length&&!n&&!r?c=t:(c={},i.length&&i.forEach(e=>_r(c,e,o,!0)),_r(c,t,o)),v(t)&&a.set(t,c),c}function _r(e,t,n,r=!1){let{mixins:i,extends:a}=t;a&&_r(e,a,n,!0),i&&i.forEach(t=>_r(e,t,n,!0));for(let i in t)if(!(r&&i===`expose`)){let r=vr[i]||n&&n[i];e[i]=r?r(e[i],t[i]):t[i]}return e}var vr={data:yr,props:Cr,emits:Cr,methods:Sr,computed:Sr,beforeCreate:H,created:H,beforeMount:H,mounted:H,beforeUpdate:H,updated:H,beforeDestroy:H,beforeUnmount:H,destroyed:H,unmounted:H,activated:H,deactivated:H,errorCaptured:H,serverPrefetch:H,components:Sr,directives:Sr,watch:wr,provide:yr,inject:br};function yr(e,t){return t?e?function(){return s(h(e)?e.call(this,this):e,h(t)?t.call(this,this):t)}:t:e}function br(e,t){return Sr(xr(e),xr(t))}function xr(e){if(d(e)){let t={};for(let n=0;nt===`modelValue`||t===`model-value`?e.modelModifiers:e[`${t}Modifiers`]||e[`${T(t)}Modifiers`]||e[`${E(t)}Modifiers`];function Ar(e,n,...r){if(e.isUnmounted)return;let i=e.vnode.props||t,a=r,o=n.startsWith(`update:`),s=o&&kr(i,n.slice(7));s&&(s.trim&&(a=r.map(e=>g(e)?e.trim():e)),s.number&&(a=r.map(se)));let c,l=i[c=ae(n)]||i[c=ae(T(n))];!l&&o&&(l=i[c=ae(E(n))]),l&&tn(l,e,6,a);let u=i[c+`Once`];if(u){if(!e.emitted)e.emitted={};else if(e.emitted[c])return;e.emitted[c]=!0,tn(u,e,6,a)}}var jr=new WeakMap;function Mr(e,t,n=!1){let r=n?jr:t.emitsCache,i=r.get(e);if(i!==void 0)return i;let a=e.emits,o={},c=!1;if(!h(e)){let r=e=>{let n=Mr(e,t,!0);n&&(c=!0,s(o,n))};!n&&t.mixins.length&&t.mixins.forEach(r),e.extends&&r(e.extends),e.mixins&&e.mixins.forEach(r)}return!a&&!c?(v(e)&&r.set(e,null),null):(d(a)?a.forEach(e=>o[e]=null):s(o,a),v(e)&&r.set(e,o),o)}function Nr(e,t){return!e||!a(t)?!1:(t=t.slice(2).replace(/Once$/,``),u(e,t[0].toLowerCase()+t.slice(1))||u(e,E(t))||u(e,t))}function Pr(e){let{type:t,vnode:n,proxy:r,withProxy:i,propsOptions:[a],slots:s,attrs:c,emit:l,render:u,renderCache:d,props:f,data:p,setupState:m,ctx:h,inheritAttrs:g}=e,_=xn(e),v,y;try{if(n.shapeFlag&4){let e=i||r,t=e;v=Pi(u.call(t,e,d,f,m,p,h)),y=c}else{let e=t;v=Pi(e.length>1?e(f,{attrs:c,slots:s,emit:l}):e(f,null)),y=t.props?c:Fr(c)}}catch(t){bi.length=0,nn(t,e,1),v=Ai(vi)}let b=v;if(y&&g!==!1){let e=Object.keys(y),{shapeFlag:t}=b;e.length&&t&7&&(a&&e.some(o)&&(y=Ir(y,a)),b=Ni(b,y,!1,!0))}return n.dirs&&(b=Ni(b,null,!1,!0),b.dirs=b.dirs?b.dirs.concat(n.dirs):n.dirs),n.transition&&Fn(b,n.transition),v=b,xn(_),v}var Fr=e=>{let t;for(let n in e)(n===`class`||n===`style`||a(n))&&((t||={})[n]=e[n]);return t},Ir=(e,t)=>{let n={};for(let r in e)(!o(r)||!(r.slice(9)in t))&&(n[r]=e[r]);return n};function Lr(e,t,n){let{props:r,children:i,component:a}=e,{props:o,children:s,patchFlag:c}=t,l=a.emitsOptions;if(t.dirs||t.transition)return!0;if(n&&c>=0){if(c&1024)return!0;if(c&16)return r?Rr(r,o,l):!!o;if(c&8){let e=t.dynamicProps;for(let t=0;tObject.create(Vr),Ur=e=>Object.getPrototypeOf(e)===Vr;function Wr(e,t,n,r=!1){let i={},a=Hr();e.propsDefaults=Object.create(null),Kr(e,t,i,a);for(let t in e.propsOptions[0])t in i||(i[t]=void 0);n?e.props=r?i:Pt(i):e.type.props?e.props=i:e.props=a,e.attrs=a}function Gr(e,t,n,r){let{props:i,attrs:a,vnode:{patchFlag:o}}=e,s=I(i),[c]=e.propsOptions,l=!1;if((r||o>0)&&!(o&16)){if(o&8){let n=e.vnode.dynamicProps;for(let r=0;r{p=!0;let[t,n]=Yr(e,r,!0);s(l,t),n&&f.push(...n)};!i&&r.mixins.length&&r.mixins.forEach(t),e.extends&&t(e.extends),e.mixins&&e.mixins.forEach(t)}if(!c&&!p)return v(e)&&a.set(e,n),n;if(d(c))for(let e=0;ee===`_`||e===`_ctx`||e===`$stable`,Qr=e=>d(e)?e.map(Pi):[Pi(e)],$r=(e,t,n)=>{if(t._n)return t;let r=Sn((...e)=>Qr(t(...e)),n);return r._c=!1,r},ei=(e,t,n)=>{let r=e._ctx;for(let n in e){if(Zr(n))continue;let i=e[n];if(h(i))t[n]=$r(n,i,r);else if(i!=null){let e=Qr(i);t[n]=()=>e}}},ti=(e,t)=>{let n=Qr(t);e.slots.default=()=>n},ni=(e,t,n)=>{for(let r in t)(n||!Zr(r))&&(e[r]=t[r])},ri=(e,t,n)=>{let r=e.slots=Hr();if(e.vnode.shapeFlag&32){let e=t._;e?(ni(r,t,n),n&&O(r,`_`,e,!0)):ei(t,r)}else t&&ti(e,t)},ii=(e,n,r)=>{let{vnode:i,slots:a}=e,o=!0,s=t;if(i.shapeFlag&32){let e=n._;e?r&&e===1?o=!1:ni(a,n,r):(o=!n.$stable,ei(n,a)),s=n}else n&&(ti(e,n),s={default:1});if(o)for(let e in a)!Zr(e)&&s[e]==null&&delete a[e]},U=gi;function ai(e){return oi(e)}function oi(e,i){let a=le();a.__VUE__=!0;let{insert:o,remove:s,patchProp:c,createElement:l,createText:u,createComment:d,setText:f,setElementText:p,parentNode:m,nextSibling:h,setScopeId:g=r,insertStaticContent:_}=e,v=(e,t,n,r=null,i=null,a=null,o=void 0,s=null,c=!!t.dynamicChildren)=>{if(e===t)return;e&&!Di(e,t)&&(r=ye(e),k(e,i,a,!0),e=null),t.patchFlag===-2&&(c=!1,t.dynamicChildren=null);let{type:l,ref:u,shapeFlag:d}=t;switch(l){case _i:y(e,t,n,r);break;case vi:b(e,t,n,r);break;case yi:e??x(t,n,r,o);break;case W:ae(e,t,n,r,i,a,o,s,c);break;default:d&1?w(e,t,n,r,i,a,o,s,c):d&6?D(e,t,n,r,i,a,o,s,c):(d&64||d&128)&&l.process(e,t,n,r,i,a,o,s,c,A)}u!=null&&i?zn(u,e&&e.ref,a,t||e,!t):u==null&&e&&e.ref!=null&&zn(e.ref,null,a,e,!0)},y=(e,t,n,r)=>{if(e==null)o(t.el=u(t.children),n,r);else{let n=t.el=e.el;t.children!==e.children&&f(n,t.children)}},b=(e,t,n,r)=>{e==null?o(t.el=d(t.children||``),n,r):t.el=e.el},x=(e,t,n,r)=>{[e.el,e.anchor]=_(e.children,t,n,r,e.el,e.anchor)},S=({el:e,anchor:t},n,r)=>{let i;for(;e&&e!==t;)i=h(e),o(e,n,r),e=i;o(t,n,r)},C=({el:e,anchor:t})=>{let n;for(;e&&e!==t;)n=h(e),s(e),e=n;s(t)},w=(e,t,n,r,i,a,o,s,c)=>{if(t.type===`svg`?o=`svg`:t.type===`math`&&(o=`mathml`),e==null)te(t,n,r,i,a,o,s,c);else{let n=e.el&&e.el._isVueCE?e.el:null;try{n&&n._beginPatch(),re(e,t,i,a,o,s,c)}finally{n&&n._endPatch()}}},te=(e,t,n,r,i,a,s,u)=>{let d,f,{props:m,shapeFlag:h,transition:g,dirs:_}=e;if(d=e.el=l(e.type,a,m&&m.is,m),h&8?p(d,e.children):h&16&&T(e.children,d,null,r,i,si(e,a),s,u),_&&Cn(e,null,r,`created`),ne(d,e,e.scopeId,s,r),m){for(let e in m)e!==`value`&&!ee(e)&&c(d,e,null,m[e],a,r);`value`in m&&c(d,`value`,null,m.value,a),(f=m.onVnodeBeforeMount)&&Ri(f,r,e)}_&&Cn(e,null,r,`beforeMount`);let v=li(i,g);v&&g.beforeEnter(d),o(d,t,n),((f=m&&m.onVnodeMounted)||v||_)&&U(()=>{try{f&&Ri(f,r,e),v&&g.enter(d),_&&Cn(e,null,r,`mounted`)}finally{}},i)},ne=(e,t,n,r,i)=>{if(n&&g(e,n),r)for(let t=0;t{for(let l=c;l{let l=n.el=e.el,{patchFlag:u,dynamicChildren:d,dirs:f}=n;u|=e.patchFlag&16;let m=e.props||t,h=n.props||t,g;if(r&&ci(r,!1),(g=h.onVnodeBeforeUpdate)&&Ri(g,r,n,e),f&&Cn(n,e,r,`beforeUpdate`),r&&ci(r,!0),(m.innerHTML&&h.innerHTML==null||m.textContent&&h.textContent==null)&&p(l,``),d?E(e.dynamicChildren,d,l,r,i,si(n,a),o):s||de(e,n,l,null,r,i,si(n,a),o,!1),u>0){if(u&16)ie(l,m,h,r,a);else if(u&2&&m.class!==h.class&&c(l,`class`,null,h.class,a),u&4&&c(l,`style`,m.style,h.style,a),u&8){let e=n.dynamicProps;for(let t=0;t{g&&Ri(g,r,n,e),f&&Cn(n,e,r,`updated`)},i)},E=(e,t,n,r,i,a,o)=>{for(let s=0;s{if(n!==r){if(n!==t)for(let t in n)!ee(t)&&!(t in r)&&c(e,t,n[t],null,a,i);for(let t in r){if(ee(t))continue;let o=r[t],s=n[t];o!==s&&t!==`value`&&c(e,t,s,o,a,i)}`value`in r&&c(e,`value`,n.value,r.value,a)}},ae=(e,t,n,r,i,a,s,c,l)=>{let d=t.el=e?e.el:u(``),f=t.anchor=e?e.anchor:u(``),{patchFlag:p,dynamicChildren:m,slotScopeIds:h}=t;h&&(c=c?c.concat(h):h),e==null?(o(d,n,r),o(f,n,r),T(t.children||[],n,f,i,a,s,c,l)):p>0&&p&64&&m&&e.dynamicChildren&&e.dynamicChildren.length===m.length?(E(e.dynamicChildren,m,n,i,a,s,c),(t.key!=null||i&&t===i.subTree)&&ui(e,t,!0)):de(e,t,n,f,i,a,s,c,l)},D=(e,t,n,r,i,a,o,s,c)=>{t.slotScopeIds=s,e==null?t.shapeFlag&512?i.ctx.activate(t,n,r,o,c):O(t,n,r,i,a,o,c):se(e,t,c)},O=(e,t,n,r,i,a,o)=>{let s=e.component=Vi(e,r,i);if(Hn(e)&&(s.ctx.renderer=A),Yi(s,!1,o),s.asyncDep){if(i&&i.registerDep(s,ce,o),!e.el){let r=s.subTree=Ai(vi);b(null,r,t,n),e.placeholder=r.el}}else ce(s,e,t,n,i,a,o)},se=(e,t,n)=>{let r=t.component=e.component;if(Lr(e,t,n))if(r.asyncDep&&!r.asyncResolved){ue(r,t,n);return}else r.next=t,r.update();else t.el=e.el,r.vnode=t},ce=(e,t,n,r,i,a,o)=>{let s=()=>{if(e.isMounted){let{next:t,bu:n,u:r,parent:s,vnode:c}=e;{let n=fi(e);if(n){t&&(t.el=c.el,ue(e,t,o)),n.asyncDep.then(()=>{U(()=>{e.isUnmounted||l()},i)});return}}let u=t,d;ci(e,!1),t?(t.el=c.el,ue(e,t,o)):t=c,n&&oe(n),(d=t.props&&t.props.onVnodeBeforeUpdate)&&Ri(d,s,t,c),ci(e,!0);let f=Pr(e),p=e.subTree;e.subTree=f,v(p,f,m(p.el),ye(p),e,i,a),t.el=f.el,u===null&&Br(e,f.el),r&&U(r,i),(d=t.props&&t.props.onVnodeUpdated)&&U(()=>Ri(d,s,t,c),i)}else{let o,{el:s,props:c}=t,{bm:l,m:u,parent:d,root:f,type:p}=e,m=Vn(t);if(ci(e,!1),l&&oe(l),!m&&(o=c&&c.onVnodeBeforeMount)&&Ri(o,d,t),ci(e,!0),s&&Ce){let t=()=>{e.subTree=Pr(e),Ce(s,e.subTree,e,i,null)};m&&p.__asyncHydrate?p.__asyncHydrate(s,e,t):t()}else{f.ce&&f.ce._hasShadowRoot()&&f.ce._injectChildStyle(p,e.parent?e.parent.type:void 0);let o=e.subTree=Pr(e);v(null,o,n,r,e,i,a),t.el=o.el}if(u&&U(u,i),!m&&(o=c&&c.onVnodeMounted)){let e=t;U(()=>Ri(o,d,e),i)}(t.shapeFlag&256||d&&Vn(d.vnode)&&d.vnode.shapeFlag&256)&&e.a&&U(e.a,i),e.isMounted=!0,t=n=r=null}};e.scope.on();let c=e.effect=new De(s);e.scope.off();let l=e.update=c.run.bind(c),u=e.job=c.runIfDirty.bind(c);u.i=e,u.id=e.uid,c.scheduler=()=>pn(u),ci(e,!0),l()},ue=(e,t,n)=>{t.component=e;let r=e.vnode.props;e.vnode=t,e.next=null,Gr(e,t.props,r,n),ii(e,t.children,n),Ve(),gn(e),He()},de=(e,t,n,r,i,a,o,s,c=!1)=>{let l=e&&e.children,u=e?e.shapeFlag:0,d=t.children,{patchFlag:f,shapeFlag:m}=t;if(f>0){if(f&128){pe(l,d,n,r,i,a,o,s,c);return}else if(f&256){fe(l,d,n,r,i,a,o,s,c);return}}m&8?(u&16&&ve(l,i,a),d!==l&&p(n,d)):u&16?m&16?pe(l,d,n,r,i,a,o,s,c):ve(l,i,a,!0):(u&8&&p(n,``),m&16&&T(d,n,r,i,a,o,s,c))},fe=(e,t,r,i,a,o,s,c,l)=>{e||=n,t||=n;let u=e.length,d=t.length,f=Math.min(u,d),p;for(p=0;pd?ve(e,a,o,!0,!1,f):T(t,r,i,a,o,s,c,l,f)},pe=(e,t,r,i,a,o,s,c,l)=>{let u=0,d=t.length,f=e.length-1,p=d-1;for(;u<=f&&u<=p;){let n=e[u],i=t[u]=l?Fi(t[u]):Pi(t[u]);if(Di(n,i))v(n,i,r,null,a,o,s,c,l);else break;u++}for(;u<=f&&u<=p;){let n=e[f],i=t[p]=l?Fi(t[p]):Pi(t[p]);if(Di(n,i))v(n,i,r,null,a,o,s,c,l);else break;f--,p--}if(u>f){if(u<=p){let e=p+1,n=ep)for(;u<=f;)k(e[u],a,o,!0),u++;else{let m=u,h=u,g=new Map;for(u=h;u<=p;u++){let e=t[u]=l?Fi(t[u]):Pi(t[u]);e.key!=null&&g.set(e.key,u)}let _,y=0,b=p-h+1,x=!1,S=0,C=Array(b);for(u=0;u=b){k(n,a,o,!0);continue}let i;if(n.key!=null)i=g.get(n.key);else for(_=h;_<=p;_++)if(C[_-h]===0&&Di(n,t[_])){i=_;break}i===void 0?k(n,a,o,!0):(C[i-h]=u+1,i>=S?S=i:x=!0,v(n,t[i],r,null,a,o,s,c,l),y++)}let w=x?di(C):n;for(_=w.length-1,u=b-1;u>=0;u--){let e=h+u,n=t[e],f=t[e+1],p=e+1{let{el:a,type:c,transition:l,children:u,shapeFlag:d}=e;if(d&6){me(e.component.subTree,t,n,r);return}if(d&128){e.suspense.move(t,n,r);return}if(d&64){c.move(e,t,n,A);return}if(c===W){o(a,t,n);for(let e=0;el.enter(a),i);else{let{leave:r,delayLeave:i,afterLeave:c}=l,u=()=>{e.ctx.isUnmounted?s(a):o(a,t,n)},d=()=>{a._isLeaving&&a[Pn](!0),r(a,()=>{u(),c&&c()})};i?i(a,u,d):d()}else o(a,t,n)},k=(e,t,n,r=!1,i=!1)=>{let{type:a,props:o,ref:s,children:c,dynamicChildren:l,shapeFlag:u,patchFlag:d,dirs:f,cacheIndex:p,memo:m}=e;if(d===-2&&(i=!1),s!=null&&(Ve(),zn(s,null,n,e,!0),He()),p!=null&&(t.renderCache[p]=void 0),u&256){t.ctx.deactivate(e);return}let h=u&1&&f,g=!Vn(e),_;if(g&&(_=o&&o.onVnodeBeforeUnmount)&&Ri(_,t,e),u&6)_e(e.component,n,r);else{if(u&128){e.suspense.unmount(n,r);return}h&&Cn(e,null,t,`beforeUnmount`),u&64?e.type.remove(e,t,n,A,r):l&&!l.hasOnce&&(a!==W||d>0&&d&64)?ve(l,t,n,!1,!0):(a===W&&d&384||!i&&u&16)&&ve(c,t,n),r&&he(e)}let v=m!=null&&p==null;(g&&(_=o&&o.onVnodeUnmounted)||h||v)&&U(()=>{_&&Ri(_,t,e),h&&Cn(e,null,t,`unmounted`),v&&(e.el=null)},n)},he=e=>{let{type:t,el:n,anchor:r,transition:i}=e;if(t===W){ge(n,r);return}if(t===yi){C(e);return}let a=()=>{s(n),i&&!i.persisted&&i.afterLeave&&i.afterLeave()};if(e.shapeFlag&1&&i&&!i.persisted){let{leave:t,delayLeave:r}=i,o=()=>t(n,a);r?r(e.el,a,o):o()}else a()},ge=(e,t)=>{let n;for(;e!==t;)n=h(e),s(e),e=n;s(t)},_e=(e,t,n)=>{let{bum:r,scope:i,job:a,subTree:o,um:s,m:c,a:l}=e;pi(c),pi(l),r&&oe(r),i.stop(),a&&(a.flags|=8,k(o,e,t,n)),s&&U(s,t),U(()=>{e.isUnmounted=!0},t)},ve=(e,t,n,r=!1,i=!1,a=0)=>{for(let o=a;o{if(e.shapeFlag&6)return ye(e.component.subTree);if(e.shapeFlag&128)return e.suspense.next();let t=h(e.anchor||e.el),n=t&&t[Mn];return n?h(n):t},be=!1,xe=(e,t,n)=>{let r;e==null?t._vnode&&(k(t._vnode,null,null,!0),r=t._vnode.component):v(t._vnode||null,e,t,null,null,null,n),t._vnode=e,be||=(be=!0,gn(r),_n(),!1)},A={p:v,um:k,m:me,r:he,mt:O,mc:T,pc:de,pbc:E,n:ye,o:e},Se,Ce;return i&&([Se,Ce]=i(A)),{render:xe,hydrate:Se,createApp:Dr(xe,Se)}}function si({type:e,props:t},n){return n===`svg`&&e===`foreignObject`||n===`mathml`&&e===`annotation-xml`&&t&&t.encoding&&t.encoding.includes(`html`)?void 0:n}function ci({effect:e,job:t},n){n?(e.flags|=32,t.flags|=4):(e.flags&=-33,t.flags&=-5)}function li(e,t){return(!e||e&&!e.pendingBranch)&&t&&!t.persisted}function ui(e,t,n=!1){let r=e.children,i=t.children;if(d(r)&&d(i))for(let e=0;e>1,e[n[s]]0&&(t[r]=n[a-1]),n[a]=r)}}for(a=n.length,o=n[a-1];a-- >0;)n[a]=o,o=t[o];return n}function fi(e){let t=e.subTree.component;if(t)return t.asyncDep&&!t.asyncResolved?t:fi(t)}function pi(e){if(e)for(let t=0;te.__isSuspense;function gi(e,t){t&&t.pendingBranch?d(e)?t.effects.push(...e):t.effects.push(e):hn(e)}var W=Symbol.for(`v-fgt`),_i=Symbol.for(`v-txt`),vi=Symbol.for(`v-cmt`),yi=Symbol.for(`v-stc`),bi=[],G=null;function K(e=!1){bi.push(G=e?null:[])}function xi(){bi.pop(),G=bi[bi.length-1]||null}var Si=1;function Ci(e,t=!1){Si+=e,e<0&&G&&t&&(G.hasOnce=!0)}function wi(e){return e.dynamicChildren=Si>0?G||n:null,xi(),Si>0&&G&&G.push(e),e}function q(e,t,n,r,i,a){return wi(J(e,t,n,r,i,a,!0))}function Ti(e,t,n,r,i){return wi(Ai(e,t,n,r,i,!0))}function Ei(e){return e?e.__v_isVNode===!0:!1}function Di(e,t){return e.type===t.type&&e.key===t.key}var Oi=({key:e})=>e??null,ki=({ref:e,ref_key:t,ref_for:n})=>(typeof e==`number`&&(e=``+e),e==null?null:g(e)||L(e)||h(e)?{i:z,r:e,k:t,f:!!n}:e);function J(e,t=null,n=null,r=0,i=null,a=e===W?0:1,o=!1,s=!1){let c={__v_isVNode:!0,__v_skip:!0,type:e,props:t,key:t&&Oi(t),ref:t&&ki(t),scopeId:bn,slotScopeIds:null,children:n,component:null,suspense:null,ssContent:null,ssFallback:null,dirs:null,transition:null,el:null,anchor:null,target:null,targetStart:null,targetAnchor:null,staticCount:0,shapeFlag:a,patchFlag:r,dynamicProps:i,dynamicChildren:null,appContext:null,ctx:z};return s?(Ii(c,n),a&128&&e.normalize(c)):n&&(c.shapeFlag|=g(n)?8:16),Si>0&&!o&&G&&(c.patchFlag>0||a&6)&&c.patchFlag!==32&&G.push(c),c}var Ai=ji;function ji(e,t=null,n=null,r=0,i=null,a=!1){if((!e||e===ar)&&(e=vi),Ei(e)){let r=Ni(e,t,!0);return n&&Ii(r,n),Si>0&&!a&&G&&(r.shapeFlag&6?G[G.indexOf(e)]=r:G.push(r)),r.patchFlag=-2,r}if(ia(e)&&(e=e.__vccOpts),t){t=Mi(t);let{class:e,style:n}=t;e&&!g(e)&&(t.class=k(e)),v(n)&&(zt(n)&&!d(n)&&(n=s({},n)),t.style=ue(n))}let o=g(e)?1:hi(e)?128:Nn(e)?64:v(e)?4:h(e)?2:0;return J(e,t,n,r,i,o,a,!0)}function Mi(e){return e?zt(e)||Ur(e)?s({},e):e:null}function Ni(e,t,n=!1,r=!1){let{props:i,ref:a,patchFlag:o,children:s,transition:c}=e,l=t?Li(i||{},t):i,u={__v_isVNode:!0,__v_skip:!0,type:e.type,props:l,key:l&&Oi(l),ref:t&&t.ref?n&&a?d(a)?a.concat(ki(t)):[a,ki(t)]:ki(t):a,scopeId:e.scopeId,slotScopeIds:e.slotScopeIds,children:s,target:e.target,targetStart:e.targetStart,targetAnchor:e.targetAnchor,staticCount:e.staticCount,shapeFlag:e.shapeFlag,patchFlag:t&&e.type!==W?o===-1?16:o|16:o,dynamicProps:e.dynamicProps,dynamicChildren:e.dynamicChildren,appContext:e.appContext,dirs:e.dirs,transition:c,component:e.component,suspense:e.suspense,ssContent:e.ssContent&&Ni(e.ssContent),ssFallback:e.ssFallback&&Ni(e.ssFallback),placeholder:e.placeholder,el:e.el,anchor:e.anchor,ctx:e.ctx,ce:e.ce};return c&&r&&Fn(u,c.clone(u)),u}function Y(e=` `,t=0){return Ai(_i,null,e,t)}function X(e=``,t=!1){return t?(K(),Ti(vi,null,e)):Ai(vi,null,e)}function Pi(e){return e==null||typeof e==`boolean`?Ai(vi):d(e)?Ai(W,null,e.slice()):Ei(e)?Fi(e):Ai(_i,null,String(e))}function Fi(e){return e.el===null&&e.patchFlag!==-1||e.memo?e:Ni(e)}function Ii(e,t){let n=0,{shapeFlag:r}=e;if(t==null)t=null;else if(d(t))n=16;else if(typeof t==`object`)if(r&65){let n=t.default;n&&(n._c&&(n._d=!1),Ii(e,n()),n._c&&(n._d=!0));return}else{n=32;let r=t._;!r&&!Ur(t)?t._ctx=z:r===3&&z&&(z.slots._===1?t._=1:(t._=2,e.patchFlag|=1024))}else h(t)?(t={default:t,_ctx:z},n=32):(t=String(t),r&64?(n=16,t=[Y(t)]):n=8);e.children=t,e.shapeFlag|=n}function Li(...e){let t={};for(let n=0;nZ||z,Ui,Wi;{let e=le(),t=(t,n)=>{let r;return(r=e[t])||(r=e[t]=[]),r.push(n),e=>{r.length>1?r.forEach(t=>t(e)):r[0](e)}};Ui=t(`__VUE_INSTANCE_SETTERS__`,e=>Z=e),Wi=t(`__VUE_SSR_SETTERS__`,e=>Ji=e)}var Gi=e=>{let t=Z;return Ui(e),e.scope.on(),()=>{e.scope.off(),Ui(t)}},Ki=()=>{Z&&Z.scope.off(),Ui(null)};function qi(e){return e.vnode.shapeFlag&4}var Ji=!1;function Yi(e,t=!1,n=!1){t&&Wi(t);let{props:r,children:i}=e.vnode,a=qi(e);Wr(e,r,a,t),ri(e,i,n||t);let o=a?Xi(e,t):void 0;return t&&Wi(!1),o}function Xi(e,t){let n=e.type;e.accessCache=Object.create(null),e.proxy=new Proxy(e.ctx,lr);let{setup:r}=n;if(r){Ve();let n=e.setupContext=r.length>1?na(e):null,i=Gi(e),a=en(r,e,0,[e.props,n]),o=y(a);if(He(),i(),(o||e.sp)&&!Vn(e)&&In(e),o){if(a.then(Ki,Ki),t)return a.then(n=>{Zi(e,n,t)}).catch(t=>{nn(t,e,0)});e.asyncDep=a}else Zi(e,a,t)}else ea(e,t)}function Zi(e,t,n){h(t)?e.type.__ssrInlineRender?e.ssrRender=t:e.render=t:v(t)&&(e.setupState=Gt(t)),ea(e,n)}var Qi,$i;function ea(e,t,n){let i=e.type;if(!e.render){if(!t&&Qi&&!i.render){let t=i.template||gr(e).template;if(t){let{isCustomElement:n,compilerOptions:r}=e.appContext.config,{delimiters:a,compilerOptions:o}=i;i.render=Qi(t,s(s({isCustomElement:n,delimiters:a},r),o))}}e.render=i.render||r,$i&&$i(e)}{let t=Gi(e);Ve();try{fr(e)}finally{He(),t()}}}var ta={get(e,t){return P(e,`get`,``),e[t]}};function na(e){return{attrs:new Proxy(e.attrs,ta),slots:e.slots,emit:e.emit,expose:t=>{e.exposed=t||{}}}}function ra(e){return e.exposed?e.exposeProxy||=new Proxy(Gt(Bt(e.exposed)),{get(t,n){if(n in t)return t[n];if(n in sr)return sr[n](e)},has(e,t){return t in e||t in sr}}):e.proxy}function ia(e){return h(e)&&`__vccOpts`in e}var aa=(e,t)=>qt(e,t,Ji),oa=`3.5.34`,sa=void 0,ca=typeof window<`u`&&window.trustedTypes;if(ca)try{sa=ca.createPolicy(`vue`,{createHTML:e=>e})}catch{}var la=sa?e=>sa.createHTML(e):e=>e,ua=`http://www.w3.org/2000/svg`,da=`http://www.w3.org/1998/Math/MathML`,fa=typeof document<`u`?document:null,pa=fa&&fa.createElement(`template`),ma={insert:(e,t,n)=>{t.insertBefore(e,n||null)},remove:e=>{let t=e.parentNode;t&&t.removeChild(e)},createElement:(e,t,n,r)=>{let i=t===`svg`?fa.createElementNS(ua,e):t===`mathml`?fa.createElementNS(da,e):n?fa.createElement(e,{is:n}):fa.createElement(e);return e===`select`&&r&&r.multiple!=null&&i.setAttribute(`multiple`,r.multiple),i},createText:e=>fa.createTextNode(e),createComment:e=>fa.createComment(e),setText:(e,t)=>{e.nodeValue=t},setElementText:(e,t)=>{e.textContent=t},parentNode:e=>e.parentNode,nextSibling:e=>e.nextSibling,querySelector:e=>fa.querySelector(e),setScopeId(e,t){e.setAttribute(t,``)},insertStaticContent(e,t,n,r,i,a){let o=n?n.previousSibling:t.lastChild;if(i&&(i===a||i.nextSibling))for(;t.insertBefore(i.cloneNode(!0),n),!(i===a||!(i=i.nextSibling)););else{pa.innerHTML=la(r===`svg`?`${e}`:r===`mathml`?`${e}`:e);let i=pa.content;if(r===`svg`||r===`mathml`){let e=i.firstChild;for(;e.firstChild;)i.appendChild(e.firstChild);i.removeChild(e)}t.insertBefore(i,n)}return[o?o.nextSibling:t.firstChild,n?n.previousSibling:t.lastChild]}},ha=Symbol(`_vtc`);function ga(e,t,n){let r=e[ha];r&&(t=(t?[t,...r]:[...r]).join(` `)),t==null?e.removeAttribute(`class`):n?e.setAttribute(`class`,t):e.className=t}var _a=Symbol(`_vod`),va=Symbol(`_vsh`),ya={name:`show`,beforeMount(e,{value:t},{transition:n}){e[_a]=e.style.display===`none`?``:e.style.display,n&&t?n.beforeEnter(e):ba(e,t)},mounted(e,{value:t},{transition:n}){n&&t&&n.enter(e)},updated(e,{value:t,oldValue:n},{transition:r}){!t!=!n&&(r?t?(r.beforeEnter(e),ba(e,!0),r.enter(e)):r.leave(e,()=>{ba(e,!1)}):ba(e,t))},beforeUnmount(e,{value:t}){ba(e,t)}};function ba(e,t){e.style.display=t?e[_a]:`none`,e[va]=!t}var xa=Symbol(``),Sa=/(?:^|;)\s*display\s*:/;function Ca(e,t,n){let r=e.style,i=g(n),a=!1;if(n&&!i){if(t)if(g(t))for(let e of t.split(`;`)){let t=e.slice(0,e.indexOf(`:`)).trim();n[t]??Ta(r,t,``)}else for(let e in t)n[e]??Ta(r,e,``);for(let i in n){i===`display`&&(a=!0);let o=n[i];o==null?Ta(r,i,``):ka(e,i,!g(t)&&t?t[i]:void 0,o)||Ta(r,i,o)}}else if(i){if(t!==n){let e=r[xa];e&&(n+=`;`+e),r.cssText=n,a=Sa.test(n)}}else t&&e.removeAttribute(`style`);_a in e&&(e[_a]=a?r.display:``,e[va]&&(r.display=`none`))}var wa=/\s*!important$/;function Ta(e,t,n){if(d(n))n.forEach(n=>Ta(e,t,n));else if(n??=``,t.startsWith(`--`))e.setProperty(t,n);else{let r=Oa(e,t);wa.test(n)?e.setProperty(E(r),n.replace(wa,``),`important`):e[r]=n}}var Ea=[`Webkit`,`Moz`,`ms`],Da={};function Oa(e,t){let n=Da[t];if(n)return n;let r=T(t);if(r!==`filter`&&r in e)return Da[t]=r;r=ie(r);for(let n=0;nza||=(Ba.then(()=>za=0),Date.now());function Ha(e,t){let n=e=>{if(!e._vts)e._vts=Date.now();else if(e._vts<=n.attached)return;tn(Ua(e,n.value),t,5,[e])};return n.value=e,n.attached=Va(),n}function Ua(e,t){if(d(t)){let n=e.stopImmediatePropagation;return e.stopImmediatePropagation=()=>{n.call(e),e._stopped=!0},t.map(e=>t=>!t._stopped&&e&&e(t))}else return t}var Wa=e=>e.charCodeAt(0)===111&&e.charCodeAt(1)===110&&e.charCodeAt(2)>96&&e.charCodeAt(2)<123,Ga=(e,t,n,r,i,s)=>{let c=i===`svg`;t===`class`?ga(e,r,c):t===`style`?Ca(e,n,r):a(t)?o(t)||Ia(e,t,n,r,s):(t[0]===`.`?(t=t.slice(1),!0):t[0]===`^`?(t=t.slice(1),!1):Ka(e,t,r,c))?(Ma(e,t,r),!e.tagName.includes(`-`)&&(t===`value`||t===`checked`||t===`selected`)&&ja(e,t,r,c,s,t!==`value`)):e._isVueCE&&(qa(e,t)||e._def.__asyncLoader&&(/[A-Z]/.test(t)||!g(r)))?Ma(e,T(t),r,s,t):(t===`true-value`?e._trueValue=r:t===`false-value`&&(e._falseValue=r),ja(e,t,r,c))};function Ka(e,t,n,r){if(r)return!!(t===`innerHTML`||t===`textContent`||t in e&&Wa(t)&&h(n));if(t===`spellcheck`||t===`draggable`||t===`translate`||t===`autocorrect`||t===`sandbox`&&e.tagName===`IFRAME`||t===`form`||t===`list`&&e.tagName===`INPUT`||t===`type`&&e.tagName===`TEXTAREA`)return!1;if(t===`width`||t===`height`){let t=e.tagName;if(t===`IMG`||t===`VIDEO`||t===`CANVAS`||t===`SOURCE`)return!1}return Wa(t)&&g(n)?!1:t in e}function qa(e,t){let n=e._def.props;if(!n)return!1;let r=T(t);return Array.isArray(n)?n.some(e=>T(e)===r):Object.keys(n).some(e=>T(e)===r)}var Ja=e=>{let t=e.props[`onUpdate:modelValue`]||!1;return d(t)?e=>oe(t,e):t};function Ya(e){e.target.composing=!0}function Xa(e){let t=e.target;t.composing&&(t.composing=!1,t.dispatchEvent(new Event(`input`)))}var Za=Symbol(`_assign`);function Qa(e,t,n){return t&&(e=e.trim()),n&&(e=se(e)),e}var Q={created(e,{modifiers:{lazy:t,trim:n,number:r}},i){e[Za]=Ja(i);let a=r||i.props&&i.props.type===`number`;Na(e,t?`change`:`input`,t=>{t.target.composing||e[Za](Qa(e.value,n,a))}),(n||a)&&Na(e,`change`,()=>{e.value=Qa(e.value,n,a)}),t||(Na(e,`compositionstart`,Ya),Na(e,`compositionend`,Xa),Na(e,`change`,Xa))},mounted(e,{value:t}){e.value=t??``},beforeUpdate(e,{value:t,oldValue:n,modifiers:{lazy:r,trim:i,number:a}},o){if(e[Za]=Ja(o),e.composing)return;let s=(a||e.type===`number`)&&!/^0\d/.test(e.value)?se(e.value):e.value,c=t??``;if(s===c)return;let l=e.getRootNode();(l instanceof Document||l instanceof ShadowRoot)&&l.activeElement===e&&e.type!==`range`&&(r&&t===n||i&&e.value.trim()===c)||(e.value=c)}},$a={deep:!0,created(e,{value:t,modifiers:{number:n}},r){let i=p(t);Na(e,`change`,()=>{let t=Array.prototype.filter.call(e.options,e=>e.selected).map(e=>n?se(to(e)):to(e));e[Za](e.multiple?i?new Set(t):t:t[0]),e._assigning=!0,dn(()=>{e._assigning=!1})}),e[Za]=Ja(r)},mounted(e,{value:t}){eo(e,t)},beforeUpdate(e,t,n){e[Za]=Ja(n)},updated(e,{value:t}){e._assigning||eo(e,t)}};function eo(e,t){let n=e.multiple,r=d(t);if(!(n&&!r&&!p(t))){for(let i=0,a=e.options.length;iString(e)===String(o)):a.selected=be(t,o)>-1}else a.selected=t.has(o);else if(ye(to(a),t)){e.selectedIndex!==i&&(e.selectedIndex=i);return}}!n&&e.selectedIndex!==-1&&(e.selectedIndex=-1)}}function to(e){return`_value`in e?e._value:e.value}var no=[`ctrl`,`shift`,`alt`,`meta`],ro={stop:e=>e.stopPropagation(),prevent:e=>e.preventDefault(),self:e=>e.target!==e.currentTarget,ctrl:e=>!e.ctrlKey,shift:e=>!e.shiftKey,alt:e=>!e.altKey,meta:e=>!e.metaKey,left:e=>`button`in e&&e.button!==0,middle:e=>`button`in e&&e.button!==1,right:e=>`button`in e&&e.button!==2,exact:(e,t)=>no.some(n=>e[`${n}Key`]&&!t.includes(n))},$=(e,t)=>{if(!e)return e;let n=e._withMods||={},r=t.join(`.`);return n[r]||(n[r]=((n,...r)=>{for(let e=0;e{let t=oo().createApp(...e),{mount:n}=t;return t.mount=e=>{let r=lo(e);if(!r)return;let i=t._component;!h(i)&&!i.render&&!i.template&&(i.template=r.innerHTML),r.nodeType===1&&(r.textContent=``);let a=n(r,!1,co(r));return r instanceof Element&&(r.removeAttribute(`v-cloak`),r.setAttribute(`data-v-app`,``)),a},t});function co(e){if(e instanceof SVGElement)return`svg`;if(typeof MathMLElement==`function`&&e instanceof MathMLElement)return`mathml`}function lo(e){return g(e)?document.querySelector(e):e}var uo=`Lowpass (低通)`,fo=`(無) 手動自訂`,po=1e5,mo=`0.5, 0.5, 0.0, 0.0`,ho=`1.0, 0.0, 0.0, 0.0`,go=14,_o=[0,0,0,0,0,0,0],vo={fc:1e3,order:1,bp_f_low:500,bp_f_high:2e3,bp_order:1,notch_f0:120,notch_q:1,opoz_fz:15e3,opoz_fp:10,tp1z_fz:200,tp1z_fp1:10,tp1z_fp2:5e3,tptz_fz1:200,tptz_fz2:25e3,tptz_fp1:10,tptz_fp2:5e3,kp:.003,ki:10,kd:16e-6,sogi_f0:60,sogi_k:1.414},yo=()=>({...vo}),bo=()=>[..._o],xo={data(){return{fs:po,b_str:mo,a_str:ho,filterType:uo,filterOptions:[`Lowpass (低通)`,`Highpass (高通)`,`Bandpass (帶通)`,`Notch (陷波器)`,`1P1Z (一極一零)`,`2P1Z (二極一零)`,`2P2Z (二極二零)`,`PID 控制器`,`SOGI-Alpha (帶通)`,`SOGI-Beta (低通)`,`(無) 手動自訂`],systemGain:1,params:yo(),isDarkMode:!0,baseB:[.5,.5,0,0,0,0,0],baseA:[1,0,0,0,0,0,0],bSliders:bo(),aSliders:bo(),sense_b:`2x`,sense_a:`2x`,loadingBode:!1,bodeTimeout:null,globalError:null,csvFile:null,csvColumns:[],csvPreview:[],csvInfo:null,csvParseError:null,selectedColumn:0,loadingFilter:!1,filterDone:!1,timePlotData:null,mobileTab:`settings`,shiftBitsB:go,shiftBitsA:go,fixedOverrides:{a:{},b:{}},outOfRangeB:[!1,!1,!1,!1,!1,!1,!1],outOfRangeA:[!1,!1,!1,!1,!1,!1,!1],aFineStep:.01,aFineRepeatDelayTimer:null,aFineRepeatTimer:null,aFineDrag:null,shiftBitRepeatDelayTimer:null,shiftBitRepeatTimer:null,shiftBitDrag:null,fixedAFineStep:1,fixedAFineDrag:null,fixedAFineRepeatDelayTimer:null,fixedAFineRepeatTimer:null,isTouchInput:!1,activeCoeffAdjustment:null}},computed:{maxLogB(){return this.sense_b===`1%`?Math.log10(1.01):this.sense_b===`2x`?Math.log10(2):1},maxLogA(){return this.sense_a===`1%`?Math.log10(1.01):this.sense_a===`2x`?Math.log10(2):this.sense_a===`10x`?Math.log10(10):Math.log10(2)},b_int_str:{get(){return this.fixedPointCoeffs.b.map(e=>e.val).join(`, `)},set(e){let t=e.replace(/[^0-9,\-\s]/g,``);this.parseCoeffs(t).forEach((e,t)=>{this.fixedOverrides.b[t]=Math.round(e)}),this.debouncedUpdateBode()}},a_int_str:{get(){return this.fixedPointCoeffs.a.map(e=>e.val).join(`, `)},set(e){let t=e.replace(/[^0-9,\-\s]/g,``);this.parseCoeffs(t).forEach((e,t)=>{this.fixedOverrides.a[t]=Math.round(e)}),this.debouncedUpdateBode()}},fixedPointCoeffs(){let e=2**this.shiftBitsB,t=2**this.shiftBitsA,n=this.parseCoeffs(this.b_str),r=this.parseCoeffs(this.a_str);return{b:n.map((t,n)=>{let r=Math.round(t*e),i=this.fixedOverrides.b[n]===void 0?r:this.fixedOverrides.b[n];return{label:`b${n}`,val:i,isOverridden:this.fixedOverrides.b[n]!==void 0}}),a:r.map((e,n)=>{let r=Math.round(e*t),i=this.fixedOverrides.a[n]===void 0?r:this.fixedOverrides.a[n];return{label:`a${n}`,val:i,isOverridden:this.fixedOverrides.a[n]!==void 0}})}},floatingCoeffs(){return{b:this.parseCoeffs(this.b_str).map((e,t)=>({label:`b${t}`,val:parseFloat(e.toPrecision(6))})),a:this.parseCoeffs(this.a_str).map((e,t)=>({label:`a${t}`,val:parseFloat(e.toPrecision(6))}))}},isManualDirty(){if(this.bSliders.some(e=>e!==0)||this.aSliders.some(e=>e!==0))return!0;let e=this.padTo7(this.parseCoeffs(this.b_str)),t=this.padTo7(this.parseCoeffs(this.a_str)),n=this.baseB.map(e=>e*(this.systemGain||1)),r=this.baseA;for(let i=0;i<7;i++){let a=e[i]||0,o=n[i]||0,s=Math.max(1e-8,Math.abs(o)*1e-10);if(Math.abs(a-o)>s)return!0;let c=t[i]||0,l=r[i]||0,u=Math.max(1e-8,Math.abs(l)*1e-10);if(Math.abs(c-l)>u)return!0}return!1},isFixedPointDirty(){return this.shiftBitsB!==go||this.shiftBitsA!==go||Object.keys(this.fixedOverrides.b).length>0||Object.keys(this.fixedOverrides.a).length>0},currentA1(){return this.parseCoeffs(this.a_str)[1]||0},currentA2(){return this.parseCoeffs(this.a_str)[2]||0},currentDelta(){return(this.currentA1+this.currentA2+1)/2},currentR(){return(this.currentA2-this.currentA1-1)/2},currentA1A2Diff(){return this.currentA1-this.currentA2},currentA1A2Sum(){return this.currentA1+this.currentA2},fixedA0Int(){return 2**this.shiftBitsA},fixedCurrentA1(){return this.fixedPointCoeffs.a[1]?.val||0},fixedCurrentA2(){return this.fixedPointCoeffs.a[2]?.val||0},fixedCurrentDelta(){return(this.fixedCurrentA1+this.fixedCurrentA2+this.fixedA0Int)/2},fixedCurrentR(){return(this.fixedCurrentA2-this.fixedCurrentA1-this.fixedA0Int)/2},fixedCurrentA1A2Diff(){return this.fixedCurrentA1-this.fixedCurrentA2},fixedCurrentA1A2Sum(){return this.fixedCurrentA1+this.fixedCurrentA2}},mounted(){this.isTouchInput=window.matchMedia?.(`(pointer: coarse)`).matches||!1,window.addEventListener(`pointerdown`,this.rememberPointerType);let e=localStorage.getItem(`theme`);this.isDarkMode=e?e===`dark`:!0,this.isDarkMode?document.documentElement.classList.add(`dark`):document.documentElement.classList.remove(`dark`),this.applyFilterDesign()},beforeUnmount(){window.removeEventListener(`pointerdown`,this.rememberPointerType),this.stopA1A2Repeat(),this.stopAFineDrag(),this.stopShiftBitRepeat(),this.stopShiftBitDrag(),this.stopFixedA1A2Repeat(),this.stopFixedAFineDrag()},methods:{rememberPointerType(e){e.pointerType===`touch`?this.isTouchInput=!0:(e.pointerType===`mouse`||e.pointerType===`pen`)&&(this.isTouchInput=!1)},toggleDarkMode(){this.isDarkMode=!this.isDarkMode,localStorage.setItem(`theme`,this.isDarkMode?`dark`:`light`),this.isDarkMode?document.documentElement.classList.add(`dark`):document.documentElement.classList.remove(`dark`),this.updateBodePlot({switchToChart:!1}),this.timePlotData&&this.drawTimePlot(this.timePlotData)},formatK(e){return e>=1e6?`(~${(e/1e6).toFixed(1).replace(`.0`,``)}M)`:e>=1e3?`(~${(e/1e3).toFixed(1).replace(`.0`,``)}k)`:``},parseCoeffs(e){return e?e.split(/[,\s]+/).map(e=>parseFloat(e.trim())).filter(e=>!isNaN(e)):[]},padTo7(e){let t=e.slice(0,7);for(;t.length<7;)t.push(0);return t},syncBaseFromText(){let e=this.systemGain||1;this.baseB=this.padTo7(this.parseCoeffs(this.b_str)).map(t=>t/e),this.baseA=this.padTo7(this.parseCoeffs(this.a_str)),this.baseA[0]=1,this.fixedOverrides={a:{},b:{}},this.bSliders=[0,0,0,0,0,0,0],this.aSliders=[0,0,0,0,0,0,0],this.outOfRangeB=[!1,!1,!1,!1,!1,!1,!1],this.outOfRangeA=[!1,!1,!1,!1,!1,!1,!1]},resetSlidersB(){this.bSliders=[0,0,0,0,0,0,0],this.b_str=this.baseB.map(e=>parseFloat(e.toPrecision(10))).join(`, `),this.debouncedUpdateBode()},resetSlidersA(){this.aSliders=[0,0,0,0,0,0],this.a_str=this.baseA.map(e=>parseFloat(e.toPrecision(10))).join(`, `),this.debouncedUpdateBode()},clearManualAdjustments(){this.bSliders=[0,0,0,0,0,0,0],this.aSliders=[0,0,0,0,0,0,0];let e=this.systemGain||1;this.b_str=this.baseB.map(t=>parseFloat((t*e).toPrecision(10))).join(`, `),this.a_str=this.baseA.map(e=>parseFloat(e.toPrecision(10))).join(`, `),this.activeCoeffAdjustment=null,this.calcSlidersFromText(),this.updateBodePlot({switchToChart:!1})},updateFromControls({updateBode:e=!0}={}){let t=this.baseB.map((e,t)=>e*(this.systemGain||1)*10**(this.bSliders[t]||0)),n=[1];for(let e=1;e<7;e++)n.push(this.baseA[e]*10**(this.aSliders[e]||0));this.b_str=t.map(e=>parseFloat(e.toPrecision(10))).join(`, `),this.a_str=n.map(e=>parseFloat(e.toPrecision(10))).join(`, `),e&&this.debouncedUpdateBode()},stepDecimals(e){let t=String(e);return t.includes(`e-`)?Number(t.split(`e-`)[1]):t.includes(`.`)?t.split(`.`)[1].length:0},roundToStep(e,t=this.aFineStep){let n=1/t;return Math.round(e*n)/n},formatFineCoeff(e){return Number.isFinite(e)?Number(e).toString():`0`},formatAFineDelta(e=this.aFineStep){return this.roundToStep(e,e).toFixed(this.stepDecimals(e))},formatFixedFineCoeff(e){return Number.isFinite(e)?String(e):`0`},formatFixedAFineDelta(e=this.fixedAFineStep){return String(e)},adjustAFineStep(e){let t=this.aFineStep*(e>0?.1:10),n=Math.min(1,Math.max(1e-9,t));this.aFineStep=Number(n.toPrecision(12))},adjustFixedAFineStep(e){let t=this.fixedAFineStep*(e>0?.1:10);this.fixedAFineStep=Math.max(1,Math.min(1e9,Math.round(t)))},setDeltaR(e,t){let n=Number(e),r=Number(t);!Number.isFinite(n)||!Number.isFinite(r)||this.setA1A2(-1-r+n,r+n)},setAFineDirect(e,t){let n=parseFloat(t);Number.isFinite(n)&&(e===`delta`?this.setDeltaR(n,this.currentR):e===`r`&&this.setDeltaR(this.currentDelta,n))},adjustAFineValue(e,t){let n=t*this.aFineStep;e===`delta`?this.setDeltaR(this.currentDelta+n,this.currentR):e===`r`&&this.setDeltaR(this.currentDelta,this.currentR+n)},handleAFineWheel(e,t){if(!t.shiftKey){t.currentTarget?.blur?.();return}t.preventDefault();let n=t.deltaY<0?1:-1,r=Math.max(1,Math.round(Math.abs(t.deltaY)/80));this.adjustAFineValue(e,n*r)},startAFineDrag(e,t){t.pointerType===`touch`&&(t.preventDefault(),this.aFineDrag={target:e,lastY:t.clientY,remainder:0},window.addEventListener(`pointermove`,this.moveAFineDrag,{passive:!1}),window.addEventListener(`pointerup`,this.stopAFineDrag),window.addEventListener(`pointercancel`,this.stopAFineDrag))},moveAFineDrag(e){if(!this.aFineDrag)return;e.preventDefault();let t=this.aFineDrag.lastY-e.clientY;this.aFineDrag.lastY=e.clientY,this.aFineDrag.remainder+=t;let n=Math.trunc(this.aFineDrag.remainder/18);n!==0&&(this.aFineDrag.remainder-=n*18,this.adjustAFineValue(this.aFineDrag.target,n))},stopAFineDrag(){this.aFineDrag=null,window.removeEventListener(`pointermove`,this.moveAFineDrag),window.removeEventListener(`pointerup`,this.stopAFineDrag),window.removeEventListener(`pointercancel`,this.stopAFineDrag)},setFixedDeltaR(e,t){let n=Number(e),r=Number(t);!Number.isFinite(n)||!Number.isFinite(r)||(this.fixedOverrides.a[1]=Math.round(-this.fixedA0Int-r+n),this.fixedOverrides.a[2]=Math.round(r+n),this.debouncedUpdateBode())},setFixedAFineDirect(e,t){let n=parseFloat(t);Number.isFinite(n)&&(e===`delta`?this.setFixedDeltaR(n,this.fixedCurrentR):e===`r`&&this.setFixedDeltaR(this.fixedCurrentDelta,n))},adjustFixedAFineValue(e,t){let n=t*this.fixedAFineStep;e===`delta`?this.setFixedDeltaR(this.fixedCurrentDelta+n,this.fixedCurrentR):e===`r`&&this.setFixedDeltaR(this.fixedCurrentDelta,this.fixedCurrentR+n)},handleFixedAFineWheel(e,t){if(!t.shiftKey){t.currentTarget?.blur?.();return}t.preventDefault();let n=t.deltaY<0?1:-1,r=Math.max(1,Math.round(Math.abs(t.deltaY)/80));this.adjustFixedAFineValue(e,n*r)},startFixedA1A2Repeat(e,t){this.stopFixedA1A2Repeat(),this.adjustFixedAFineValue(e,t),this.fixedAFineRepeatDelayTimer=setTimeout(()=>{this.fixedAFineRepeatTimer=setInterval(()=>{this.adjustFixedAFineValue(e,t)},80)},350)},stopFixedA1A2Repeat(){clearTimeout(this.fixedAFineRepeatDelayTimer),clearInterval(this.fixedAFineRepeatTimer),this.fixedAFineRepeatDelayTimer=null,this.fixedAFineRepeatTimer=null},startFixedAFineDrag(e,t){t.pointerType===`touch`&&(t.preventDefault(),this.fixedAFineDrag={target:e,lastY:t.clientY,remainder:0},window.addEventListener(`pointermove`,this.moveFixedAFineDrag,{passive:!1}),window.addEventListener(`pointerup`,this.stopFixedAFineDrag),window.addEventListener(`pointercancel`,this.stopFixedAFineDrag))},moveFixedAFineDrag(e){if(!this.fixedAFineDrag)return;e.preventDefault();let t=this.fixedAFineDrag.lastY-e.clientY;this.fixedAFineDrag.lastY=e.clientY,this.fixedAFineDrag.remainder+=t;let n=Math.trunc(this.fixedAFineDrag.remainder/18);n!==0&&(this.fixedAFineDrag.remainder-=n*18,this.adjustFixedAFineValue(this.fixedAFineDrag.target,n))},stopFixedAFineDrag(){this.fixedAFineDrag=null,window.removeEventListener(`pointermove`,this.moveFixedAFineDrag),window.removeEventListener(`pointerup`,this.stopFixedAFineDrag),window.removeEventListener(`pointercancel`,this.stopFixedAFineDrag)},normalizeShiftBits(e){let t=parseInt(e,10);return Number.isFinite(t)?Math.max(0,t):0},setShiftBits(e,t){let n=this.normalizeShiftBits(t);e===`b`?this.shiftBitsB=n:this.shiftBitsA=n,this.clearFixedOverrides(e),this.debouncedUpdateBode()},adjustShiftBits(e,t){let n=e===`b`?this.shiftBitsB:this.shiftBitsA;this.setShiftBits(e,n+t)},handleShiftBitWheel(e,t){if(!t.shiftKey){t.currentTarget?.blur?.();return}t.preventDefault();let n=t.deltaY<0?1:-1,r=Math.max(1,Math.round(Math.abs(t.deltaY)/80));this.adjustShiftBits(e,n*r)},startShiftBitRepeat(e,t){this.stopShiftBitRepeat(),this.adjustShiftBits(e,t),this.shiftBitRepeatDelayTimer=setTimeout(()=>{this.shiftBitRepeatTimer=setInterval(()=>{this.adjustShiftBits(e,t)},80)},350)},stopShiftBitRepeat(){clearTimeout(this.shiftBitRepeatDelayTimer),clearInterval(this.shiftBitRepeatTimer),this.shiftBitRepeatDelayTimer=null,this.shiftBitRepeatTimer=null},startShiftBitDrag(e,t){t.pointerType===`touch`&&(t.preventDefault(),this.shiftBitDrag={type:e,lastY:t.clientY,remainder:0},window.addEventListener(`pointermove`,this.moveShiftBitDrag,{passive:!1}),window.addEventListener(`pointerup`,this.stopShiftBitDrag),window.addEventListener(`pointercancel`,this.stopShiftBitDrag))},moveShiftBitDrag(e){if(!this.shiftBitDrag)return;e.preventDefault();let t=this.shiftBitDrag.lastY-e.clientY;this.shiftBitDrag.lastY=e.clientY,this.shiftBitDrag.remainder+=t;let n=Math.trunc(this.shiftBitDrag.remainder/18);n!==0&&(this.shiftBitDrag.remainder-=n*18,this.adjustShiftBits(this.shiftBitDrag.type,n))},stopShiftBitDrag(){this.shiftBitDrag=null,window.removeEventListener(`pointermove`,this.moveShiftBitDrag),window.removeEventListener(`pointerup`,this.stopShiftBitDrag),window.removeEventListener(`pointercancel`,this.stopShiftBitDrag)},setA1A2(e,t){let n=this.padTo7(this.parseCoeffs(this.a_str));n[0]=1,n[1]=Number(e),n[2]=Number(t),this.a_str=n.map(e=>Number.isFinite(e)?Number(e).toString():`0`).join(`, `),this.calcSlidersFromText(),this.debouncedUpdateBode()},adjustA1A2(e,t){let n=this.aFineStep*t;e===`delta`?this.setDeltaR(this.currentDelta+n,this.currentR):e===`r`&&this.setDeltaR(this.currentDelta,this.currentR+n)},startA1A2Repeat(e,t){this.stopA1A2Repeat(),this.adjustA1A2(e,t),this.aFineRepeatDelayTimer=setTimeout(()=>{this.aFineRepeatTimer=setInterval(()=>{this.adjustA1A2(e,t)},80)},350)},stopA1A2Repeat(){clearTimeout(this.aFineRepeatDelayTimer),clearInterval(this.aFineRepeatTimer),this.aFineRepeatDelayTimer=null,this.aFineRepeatTimer=null},toggleCoeffAdjustment(e){if(this.activeCoeffAdjustment===e){this.activeCoeffAdjustment=null;return}this.activeCoeffAdjustment=e,e===`a1a2`&&this.calcSlidersFromText()},calcSlidersFromText(){let e=this.systemGain||1,t=this.parseCoeffs(this.b_str),n=this.parseCoeffs(this.a_str);for(let n=0;n<7;n++){let r=t[n]||0,i=this.baseB[n]||0;if(this.outOfRangeB[n]=!1,i!==0&&r!==0&&r/(i*e)>0){let t=Math.log10(r/(i*e));Math.abs(t)<1e-12&&(t=0),Math.abs(t)>this.maxLogB&&(this.outOfRangeB[n]=!0),this.bSliders[n]=Math.max(-this.maxLogB,Math.min(this.maxLogB,t))}else this.bSliders[n]=0,r!==0&&i!==0&&(this.outOfRangeB[n]=!0)}for(let e=1;e<7;e++){let t=n[e]||0,r=this.baseA[e]||0;if(this.outOfRangeA[e]=!1,r!==0&&t!==0&&t/r>0){let n=Math.log10(t/r);Math.abs(n)<1e-12&&(n=0),Math.abs(n)>this.maxLogA&&(this.outOfRangeA[e]=!0),this.aSliders[e]=Math.max(-this.maxLogA,Math.min(this.maxLogA,n))}else this.aSliders[e]=0,t!==0&&r!==0&&(this.outOfRangeA[e]=!0)}},debouncedUpdateFromText(e){e===`b`&&(this.b_str=this.b_str.replace(/[^0-9,.\-\s]/g,``)),e===`a`&&(this.a_str=this.a_str.replace(/[^0-9,.\-\s]/g,``)),this.calcSlidersFromText(),this.debouncedUpdateBode()},onlyNumberKey(e,t=!0){[`Backspace`,`Delete`,`ArrowLeft`,`ArrowRight`,`Tab`,`Enter`,`Home`,`End`].includes(e.key)||e.ctrlKey||e.metaKey||(t?/[0-9,.\-\s]/:/[0-9,\-\s]/).test(e.key)||e.preventDefault()},clearFixedOverrides(e=null){if(e===`a`||e===`b`){this.fixedOverrides[e]={};return}this.fixedOverrides={a:{},b:{}}},resetFixedPointSettings(){this.shiftBitsB=go,this.shiftBitsA=go,this.fixedAFineStep=1,this.clearFixedOverrides(),this.updateBodePlot({switchToChart:!1})},debouncedApply(){clearTimeout(this.bodeTimeout),this.bodeTimeout=setTimeout(()=>{this.filterType===fo?this.updateBodePlot({switchToChart:!1}):this.applyFilterDesign()},300)},debouncedUpdateBode(){clearTimeout(this.bodeTimeout),this.bodeTimeout=setTimeout(()=>this.updateBodePlot({switchToChart:!1}),150)},onGainChange(){this.updateFromControls()},onFilterTypeChange(){this.systemGain=1,this.clearFixedOverrides(),this.bSliders=bo(),this.aSliders=bo(),this.outOfRangeB=[!1,!1,!1,!1,!1,!1,!1],this.outOfRangeA=[!1,!1,!1,!1,!1,!1,!1],this.activeCoeffAdjustment=null,this.filterType!==fo&&(this.params=yo()),this.applyFilterDesign()},resetFilterParams(){clearTimeout(this.bodeTimeout),this.fs=po,this.filterType=uo,this.systemGain=1,this.params=yo(),this.b_str=mo,this.a_str=ho,this.baseB=this.padTo7(this.parseCoeffs(mo)),this.baseA=this.padTo7(this.parseCoeffs(ho)),this.clearFixedOverrides(),this.bSliders=bo(),this.aSliders=bo(),this.outOfRangeB=[!1,!1,!1,!1,!1,!1,!1],this.outOfRangeA=[!1,!1,!1,!1,!1,!1,!1],this.sense_b=`2x`,this.sense_a=`2x`,this.shiftBitsB=go,this.shiftBitsA=go,this.aFineStep=.01,this.fixedAFineStep=1,this.stopA1A2Repeat(),this.stopAFineDrag(),this.stopFixedA1A2Repeat(),this.stopFixedAFineDrag(),this.stopShiftBitRepeat(),this.stopShiftBitDrag(),this.activeCoeffAdjustment=null,this.globalError=null,this.applyFilterDesign()},async applyFilterDesign(){if(this.filterType!==fo){this.globalError=null;try{let e={filter_type:this.filterType,fs:this.fs,lp_fc:this.params.fc,lp_order:this.params.order,hp_fc:this.params.fc,hp_order:this.params.order,bp_f_low:this.params.bp_f_low,bp_f_high:this.params.bp_f_high,bp_order:this.params.bp_order,notch_f0:this.params.notch_f0,notch_q:this.params.notch_q,opoz_fz:this.params.opoz_fz,opoz_fp:this.params.opoz_fp,tp1z_fz:this.params.tp1z_fz,tp1z_fp1:this.params.tp1z_fp1,tp1z_fp2:this.params.tp1z_fp2,tptz_fz1:this.params.tptz_fz1,tptz_fz2:this.params.tptz_fz2,tptz_fp1:this.params.tptz_fp1,tptz_fp2:this.params.tptz_fp2,pid_kp:this.params.kp,pid_ki:this.params.ki,pid_kd:this.params.kd,sogi_f0:this.params.sogi_f0,sogi_k:this.params.sogi_k},t=await fetch(`/api/design`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify(e)});if(!t.ok){let e=await t.json();throw Error(e.detail||`設計濾波器失敗`)}let n=await t.json();this.baseB=this.padTo7(n.b),this.baseA=this.padTo7(n.a),this.baseA[0]=1,this.bSliders=[0,0,0,0,0,0,0],this.aSliders=[0,0,0,0,0,0,0],this.activeCoeffAdjustment=null,this.updateFromControls({updateBode:!1}),await this.updateBodePlot({switchToChart:!1})}catch(e){this.globalError=e.message}}},async updateBodePlot({switchToChart:e=!0}={}){this.loadingBode=!0,this.globalError=null;try{let t=this.parseCoeffs(this.b_str),n=this.parseCoeffs(this.a_str);t.length===0&&(t=[1]),n.length===0&&(n=[1]);let r=2**this.shiftBitsB,i=2**this.shiftBitsA,a=t.map((e,t)=>(this.fixedOverrides.b[t]===void 0?Math.round(e*r):this.fixedOverrides.b[t])/r),o=n.map((e,t)=>(this.fixedOverrides.a[t]===void 0?Math.round(e*i):this.fixedOverrides.a[t])/i),s=await fetch(`/api/bode/compare`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({ideal:{b:t,a:n,fs:this.fs},fixed:{b:a,a:o,fs:this.fs}})}),c;if(s.status===404){let[e,r]=await Promise.all([fetch(`/api/bode`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({b:t,a:n,fs:this.fs})}),fetch(`/api/bode`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({b:a,a:o,fs:this.fs})})]);if(!e.ok||!r.ok)throw Error(`無法計算頻率響應`);let i=await e.json(),s=await r.json();c={freq:i.freq,ideal:{mag:i.mag,phase:i.phase},fixed:{mag:s.mag,phase:s.phase}}}else if(s.ok)c=await s.json();else{let e=await s.json();throw Error(e.detail||`無法計算頻率響應`)}this.drawBodePlot(c.freq,c.ideal.mag,c.ideal.phase,c.fixed.mag,c.fixed.phase),e&&window.innerWidth<1024&&(this.mobileTab=`chart`)}catch(e){this.globalError=e.message}finally{this.loadingBode=!1}},drawBodePlot(e,t,n,r,i){let a=this.fs,o=e[0],s=e[e.length-1],c=this.isDarkMode,l=window.innerWidth<768,u=[],d=[],f=Math.floor(Math.log10(o)),p=Math.ceil(Math.log10(s));for(let e=f;e<=p;e++)for(let t of[1,2,5]){let n=t*10**e;ns||(u.push(n),n<1?d.push(n.toPrecision(3)):n<1e3?d.push(String(n)):n<1e6?d.push(n/1e3+`k`):d.push(n/1e6+`M`))}let m=[],h=[],g=(e,t,n)=>{let r=n===1?`y`:`y2`;m.push({type:`line`,x0:e,x1:e,y0:0,y1:1,xref:n===1?`x`:`x2`,yref:r+` domain`,line:{color:c?`rgba(242,184,181,0.72)`:`rgba(179,38,30,0.68)`,width:1.4,dash:`dash`}}),t&&h.push({x:Math.log10(e),y:1,text:t,xref:n===1?`x`:`x2`,yref:r+` domain`,showarrow:!1,font:{color:c?`#f2b8b5`:`#b3261e`,size:l?10:12},yshift:l?15:12,xanchor:`center`,yanchor:l?`middle`:`bottom`,textangle:l?-90:0})};g(a/2,`Nyquist`,1),g(a,`fs`,1),g(a/2,null,2),g(a,null,2);for(let e=f;e<=p;e++){let t=10**e;if(t>=o&&t<=s){let e=c?`rgba(200,206,224,0.24)`:`rgba(86,96,117,0.16)`;m.push({type:`line`,x0:t,x1:t,y0:0,y1:1,xref:`x`,yref:`y domain`,line:{color:e,width:1.5}},{type:`line`,x0:t,x1:t,y0:0,y1:1,xref:`x2`,yref:`y2 domain`,line:{color:e,width:1.5}})}}let _=c?`rgba(200,206,224,0.14)`:`rgba(86,96,117,0.09)`,v=c?`rgba(200,206,224,0.24)`:`rgba(82,86,99,0.20)`,y=c?`#b4b4bd`:`#525663`,b=c?`#f1f1f4`:`#17191f`,x=c?`#090a0d`:`#ffffff`,S={type:`log`,title:{text:`Freq (Hz)`,font:{size:l?12:14}},range:[Math.log10(o),Math.log10(s)],tickvals:u,ticktext:d,showgrid:!0,gridcolor:_,tickfont:{color:y,size:l?11:12},nticks:l?6:10},C={paper_bgcolor:x,plot_bgcolor:x,margin:l?{t:80,b:120,l:55,r:15}:{t:70,b:120,l:70,r:30},showlegend:!1,grid:{rows:2,columns:1,pattern:`independent`,roworder:`top to bottom`,ygap:l?.35:.3},font:{color:y,family:`Google Sans, Roboto, sans-serif`},annotations:[{text:`Magnitude Response (dB)`,xref:`x domain`,yref:`y domain`,x:.5,y:l?1.25:1.15,showarrow:!1,font:{size:l?14:16,color:b,weight:`normal`}},{text:`Phase Response (Deg)`,xref:`x2 domain`,yref:`y2 domain`,x:.5,y:l?1.25:1.15,showarrow:!1,font:{size:l?14:16,color:b,weight:`normal`}},{xref:`paper`,yref:`paper`,x:.35,y:l?.52:.54,text:`一一一`,font:{color:c?`#c8cee0`:`#566075`,size:10},showarrow:!1},{xref:`paper`,yref:`paper`,x:.42,y:l?.52:.54,text:`Ideal (Float)`,font:{color:y,size:11},showarrow:!1,xanchor:`left`},{xref:`paper`,yref:`paper`,x:.58,y:l?.52:.54,text:`· · · ·`,font:{color:c?`#b9b2ff`:`#7a6689`,size:14},showarrow:!1},{xref:`paper`,yref:`paper`,x:.63,y:l?.52:.54,text:`Fixed (b Q${this.shiftBitsB}, a Q${this.shiftBitsA})`,font:{color:y,size:11},showarrow:!1,xanchor:`left`},{xref:`paper`,yref:`paper`,x:.35,y:-.15,text:`一一一`,font:{color:c?`#64d2ff`:`#2d6f8f`,size:10},showarrow:!1},{xref:`paper`,yref:`paper`,x:.42,y:-.15,text:`Ideal Phase`,font:{color:y,size:11},showarrow:!1,xanchor:`left`},{xref:`paper`,yref:`paper`,x:.58,y:-.15,text:`· · · ·`,font:{color:c?`#ff9bd8`:`#96527b`,size:14},showarrow:!1},{xref:`paper`,yref:`paper`,x:.63,y:-.15,text:`Fixed Phase`,font:{color:y,size:11},showarrow:!1,xanchor:`left`},...h],xaxis:{...S},yaxis:{title:{text:`Mag (dB)`,font:{size:l?12:14}},range:[-60,0],gridcolor:_,zerolinecolor:v,tickfont:{color:y,size:l?11:12}},xaxis2:{...S},yaxis2:{title:{text:`Phase (°)`,font:{size:l?12:14}},range:[-180,180],tickvals:[-180,-90,0,90,180],gridcolor:_,zerolinecolor:v,tickfont:{color:y,size:l?11:12}},shapes:m},w={x:e,y:t,name:`Ideal (Float)`,type:`scatter`,line:{color:c?`#c8cee0`:`#566075`,width:2.8}},ee={x:e,y:r,name:`Fixed (b Q${this.shiftBitsB}, a Q${this.shiftBitsA})`,type:`scatter`,line:{color:c?`#b9b2ff`:`#7a6689`,width:2.4,dash:`dot`}},te={x:e,y:n,name:`Ideal Phase`,type:`scatter`,line:{color:c?`#64d2ff`:`#2d6f8f`,width:2.8},xaxis:`x2`,yaxis:`y2`},ne={x:e,y:i,name:`Fixed Phase`,type:`scatter`,line:{color:c?`#ff9bd8`:`#96527b`,width:2.4,dash:`dot`},xaxis:`x2`,yaxis:`y2`};Plotly.react(`bodePlot`,[w,ee,te,ne],C,{responsive:!0})},parseCsvText(e,t=1/0){let n=[],r=[],i=``,a=!1,o=0,s=()=>{r.push(i),r.some(e=>e.trim()!==``)&&(o++,n.length33554432){this.csvParseError=`CSV 檔案不可超過 32MB`,e.target.value=``;return}let n=new FileReader;n.onload=n=>{try{let e=String(n.target.result||``).replace(/^\uFEFF/,``),{rows:r,totalRows:i}=this.parseCsvText(e,6);if(i<2||r.length<2)throw Error(`CSV 需包含標題列與至少一筆資料`);let a=r[0].map((e,t)=>e.trim()||`Column ${t+1}`);if(a.length===0)throw Error(`CSV 標題列不可為空`);if(this.csvFile=t,this.csvColumns=a,this.csvPreview=r.slice(1,6).map(e=>{let t=e.slice(0,a.length);for(;t.lengthe.trim())}),this.csvInfo={rows:Math.max(i-1,0),columns:a.length,size:t.size},this.selectedColumn=0,a.length>1){let e=a[0].toLowerCase();[`time`,`t`,`sec`,`x`,`index`,`unnamed`].some(t=>e.includes(t))&&(this.selectedColumn=1)}}catch(t){this.csvParseError=t.message||`CSV 解析失敗`,this.csvColumns=[],this.csvPreview=[],this.csvInfo=null,e.target.value=``}},n.onerror=()=>{this.csvParseError=`CSV 讀取失敗`,e.target.value=``},n.readAsText(t)},async processFilter(){if(!this.csvFile)return;this.loadingFilter=!0,this.globalError=null;let e=new FormData;e.append(`file`,this.csvFile),e.append(`b`,this.b_str),e.append(`a`,this.a_str),e.append(`col_idx`,this.selectedColumn);try{let t=await fetch(`/api/filter`,{method:`POST`,body:e});if(!t.ok){let e=await t.json();throw Error(e.detail||`濾波處理失敗`)}let n=await t.json();this.timePlotData=n,this.filterDone=!0,this.$nextTick(()=>{this.drawTimePlot(n)})}catch(e){this.globalError=e.message}finally{this.loadingFilter=!1}},drawTimePlot(e){let t=this.isDarkMode,n=window.innerWidth<768,r=t?`rgba(199,206,193,0.14)`:`rgba(101,120,104,0.09)`,i=t?`rgba(199,206,193,0.24)`:`rgba(70,75,67,0.20)`,a=t?`#c7cec1`:`#42483f`,o=t?`#0b0e0a`:`#ffffff`,s={paper_bgcolor:o,plot_bgcolor:o,margin:n?{t:60,b:60,l:45,r:15}:{t:40,b:55,l:60,r:20},font:{color:a,family:`Google Sans, Roboto, sans-serif`},xaxis:{title:{text:`Sample Index`,font:{size:n?10:11}},gridcolor:r,zerolinecolor:i,tickfont:{color:a,size:n?9:11}},yaxis:{title:{text:`Amplitude`,font:{size:n?10:11}},gridcolor:r,zerolinecolor:i,tickfont:{color:a,size:n?9:11}},legend:{orientation:`h`,y:1.02,yanchor:`bottom`,x:1,xanchor:`right`,font:{color:a,size:n?9:10}}};Plotly.react(`timePlot`,[{x:e.index,y:e.original,name:`原始輸入訊號 (Input)`,type:`scatter`,line:{color:t?`#b7c9b8`:`#657868`,width:2.4},opacity:.9},{x:e.index,y:e.filtered,name:`濾波後輸出 (Output)`,type:`scatter`,line:{color:t?`#c6cbbf`:`#73786f`,width:2.4},opacity:.95}],s,{responsive:!0})},async downloadCsv(){if(!this.csvFile)return;let e=new FormData;e.append(`file`,this.csvFile),e.append(`b`,this.b_str),e.append(`a`,this.a_str),e.append(`col_idx`,this.selectedColumn);try{let t=await fetch(`/api/filter/download`,{method:`POST`,body:e});if(!t.ok)throw Error(`下載失敗`);let n=await t.blob(),r=window.URL.createObjectURL(n),i=document.createElement(`a`);i.href=r,i.download=`filtered_output.csv`,document.body.appendChild(i),i.click(),window.URL.revokeObjectURL(r)}catch(e){this.globalError=e.message}}}},So=(e,t)=>{let n=e.__vccOpts||e;for(let[e,r]of t)n[e]=r;return n},Co={id:`app`,class:`flex flex-col h-screen overflow-hidden`},wo={class:`bg-white dark:bg-dark border-b border-slate-200 dark:border-gray-800 p-4 shadow-md flex justify-between items-center z-10`},To={class:`flex items-center gap-4`},Eo={key:0,class:`w-5 h-5 role-theme-icon`,fill:`currentColor`,viewBox:`0 0 20 20`},Do={key:1,class:`w-5 h-5 text-slate-700`,fill:`currentColor`,viewBox:`0 0 20 20`},Oo={class:`lg:hidden flex border-b border-slate-200 dark:border-gray-800 bg-white dark:bg-dark z-10 flex-shrink-0`},ko={key:0,class:`w-2 h-2 rounded-full role-dot-primary animate-ping`},Ao={class:`flex flex-col lg:flex-row flex-1 overflow-hidden`},jo={class:`text-sm font-semibold text-slate-500 dark:text-gray-400 uppercase tracking-wider mb-3 flex items-center justify-between`},Mo=[`value`],No={key:0,class:`space-y-3 bg-slate-100 dark:bg-gray-900 p-4 rounded-lg border border-slate-200 dark:border-gray-800 shadow-inner`},Po={key:0},Fo={class:`text-sm text-slate-500 dark:text-gray-400 flex justify-between mb-1`},Io={class:`role-text-primary`},Lo=[`max`],Ro={class:`flex gap-2`},zo=[`onClick`],Bo={key:1},Vo={class:`text-sm text-slate-500 dark:text-gray-400 flex justify-between mb-1`},Ho={class:`role-text-primary`},Uo={class:`text-sm text-slate-500 dark:text-gray-400 flex justify-between mb-1`},Wo={class:`role-text-primary`},Go={class:`flex gap-2`},Ko=[`onClick`],qo={key:2,class:`space-y-3`},Jo={key:3,class:`space-y-3`},Yo={key:4,class:`space-y-3`},Xo={key:5,class:`space-y-3`},Zo={key:6,class:`space-y-3`},Qo={class:`text-sm font-medium text-slate-500 dark:text-gray-400 mb-1 block`},$o=[`onUpdate:modelValue`],es={key:7,class:`space-y-3`},ts={class:`space-y-3`},ns={class:`text-sm text-slate-500 dark:text-gray-400 flex justify-between mb-1`},rs={class:`role-text-primary`},is={class:`text-sm text-slate-500 dark:text-gray-400 flex justify-between mb-1`},as={class:`role-text-primary`},os={class:`text-sm font-semibold text-slate-500 dark:text-gray-400 uppercase tracking-wider mb-3 flex justify-between items-center`},ss={class:`flex items-center gap-2`},cs={class:`mb-3`},ls={class:`flex flex-wrap gap-1 mb-2`},us={class:`text-[9px] role-text-primary-muted font-bold`},ds={class:`text-[10px] font-mono role-text-primary`},fs=[`open`],ps={class:`px-3 pb-3`},ms={class:`flex items-center gap-2 mb-2 mt-1`},hs=[`onClick`],gs={key:0},_s={class:`text-xs text-slate-400 dark:text-gray-500 flex justify-between mt-1`},vs={key:0,class:`role-text-warning font-bold animate-pulse`},ys=[`onUpdate:modelValue`,`min`,`max`,`step`],bs={class:`mb-3`},xs={class:`flex flex-wrap gap-1 mb-2`},Ss={class:`text-[9px] role-text-secondary-muted font-bold`},Cs={class:`text-[10px] font-mono role-text-secondary`},ws=[`open`],Ts={class:`px-3 pb-3`},Es={class:`flex items-center gap-2 mb-2 mt-1`},Ds=[`onClick`],Os={key:0},ks={class:`text-xs text-slate-400 dark:text-gray-500 flex justify-between mt-1`},As={key:0,class:`role-text-warning font-bold animate-pulse`},js=[`onUpdate:modelValue`,`min`,`max`,`step`],Ms=[`open`],Ns={class:`px-3 pb-3`},Ps={class:`mb-4`},Fs={class:`grid grid-cols-[3.25rem_1fr_3.25rem] gap-2 mb-3`},Is={class:`min-w-0 rounded-lg border role-border-tertiary-soft role-bg-tertiary-soft px-3 py-2 text-center`},Ls=[`title`],Rs={class:`text-[11px] font-semibold text-slate-400 dark:text-gray-500 mb-2`},zs={class:`grid grid-cols-2 gap-2`},Bs={key:0,class:`block`},Vs={class:`grid grid-cols-[2rem_1fr_2rem] gap-1`},Hs=[`value`,`step`],Us=[`title`],Ws={key:2,class:`block`},Gs={class:`grid grid-cols-[2rem_1fr_2rem] gap-1`},Ks=[`value`,`step`],qs=[`title`],Js={class:`grid grid-cols-2 gap-2 mb-4`},Ys={class:`min-w-0 bg-white dark:bg-gray-800 border border-slate-100 dark:border-gray-700 rounded-lg p-2 text-center shadow-sm`},Xs=[`title`],Zs={class:`min-w-0 bg-white dark:bg-gray-800 border border-slate-100 dark:border-gray-700 rounded-lg p-2 text-center shadow-sm`},Qs=[`title`],$s={class:`min-w-0 bg-white dark:bg-gray-800 border border-slate-100 dark:border-gray-700 rounded-lg p-2 text-center shadow-sm`},ec=[`title`],tc={class:`min-w-0 bg-white dark:bg-gray-800 border border-slate-100 dark:border-gray-700 rounded-lg p-2 text-center shadow-sm`},nc=[`title`],rc={class:`text-sm font-semibold text-slate-500 dark:text-gray-400 uppercase tracking-wider mb-3 flex justify-between items-center`},ic={class:`flex items-center gap-2`},ac={class:`text-xs role-bg-primary-soft role-text-primary px-2 py-1 rounded`},oc={class:`text-xs role-bg-secondary-soft role-text-secondary px-2 py-1 rounded`},sc={class:`flex items-center gap-2`},cc={class:`mb-4 grid grid-cols-1 sm:grid-cols-2 gap-3`},lc={key:0,class:`grid grid-cols-[2rem_1fr_2rem] gap-1`},uc=[`value`],dc={class:`text-lg font-mono font-bold role-text-primary`},fc={class:`text-[10px] text-slate-400 mt-1`},pc={key:0,class:`grid grid-cols-[2rem_1fr_2rem] gap-1`},mc=[`value`],hc={class:`text-lg font-mono font-bold role-text-secondary`},gc={class:`text-[10px] text-slate-400 mt-1`},_c={class:`space-y-4`},vc={class:`flex flex-wrap gap-1 mb-2`},yc={class:`text-[9px] role-text-primary font-bold`},bc={class:`flex flex-wrap gap-1 mb-2`},xc={class:`text-[9px] role-text-secondary-muted font-bold`},Sc={class:`mt-3 bg-slate-50 dark:bg-gray-900 border border-slate-200 dark:border-gray-800 rounded-lg`},Cc={class:`px-3 pb-3`},wc={class:`mb-4`},Tc={class:`grid grid-cols-[3.25rem_1fr_3.25rem] gap-2 mb-3`},Ec={class:`min-w-0 rounded-lg border role-border-secondary-soft role-bg-secondary-soft px-3 py-2 text-center`},Dc=[`title`],Oc={class:`text-[11px] font-semibold text-slate-400 dark:text-gray-500 mb-2`},kc={class:`grid grid-cols-2 gap-2`},Ac={key:0,class:`block`},jc={class:`grid grid-cols-[2rem_1fr_2rem] gap-1`},Mc=[`value`,`step`],Nc=[`title`],Pc={key:2,class:`block`},Fc={class:`grid grid-cols-[2rem_1fr_2rem] gap-1`},Ic=[`value`,`step`],Lc=[`title`],Rc={class:`grid grid-cols-2 gap-2 mb-4`},zc={class:`min-w-0 bg-white dark:bg-gray-800 border border-slate-100 dark:border-gray-700 rounded-lg p-2 text-center shadow-sm`},Bc=[`title`],Vc={class:`min-w-0 bg-white dark:bg-gray-800 border border-slate-100 dark:border-gray-700 rounded-lg p-2 text-center shadow-sm`},Hc=[`title`],Uc={class:`min-w-0 bg-white dark:bg-gray-800 border border-slate-100 dark:border-gray-700 rounded-lg p-2 text-center shadow-sm`},Wc=[`title`],Gc={class:`min-w-0 bg-white dark:bg-gray-800 border border-slate-100 dark:border-gray-700 rounded-lg p-2 text-center shadow-sm`},Kc=[`title`],qc={class:`role-bg-warning-soft border role-border-warning-soft rounded-lg p-3`},Jc={class:`text-[10px] role-text-warning leading-relaxed`},Yc={class:`text-[10px] text-slate-400 dark:text-gray-500 mt-3 italic`},Xc={key:0,class:`absolute top-4 right-6 role-bg-error-soft border role-border-error role-text-error role-text-on-fill px-4 py-3 rounded-lg shadow-lg text-base z-50 flex items-center gap-2`},Zc={class:`bg-white dark:bg-dark lg:rounded-xl border-b lg:border border-slate-100 lg:border-slate-200 dark:border-gray-800 lg:dark:border-gray-800 lg:shadow-md p-0 lg:p-1 flex-shrink-0 relative transition-colors duration-300`},Qc={class:`px-5 py-4 border-b border-slate-100 dark:border-gray-800 flex justify-between items-center bg-white dark:bg-dark backdrop-blur-sm z-10 relative`},$c={key:0,class:`text-sm role-text-primary role-bg-primary-soft px-3 py-1.5 rounded border role-border-primary-soft flex items-center gap-2`},el={class:`bg-white dark:bg-white lg:dark:bg-dark lg:rounded-xl border-b lg:border border-slate-100 lg:border-slate-200 dark:border-gray-100 lg:dark:border-gray-800 lg:shadow-md p-0 lg:p-1 flex-shrink-0 relative transition-colors duration-300`},tl={class:`p-6 z-10 relative bg-white dark:bg-dark transition-colors duration-300`},nl={class:`flex items-center flex-wrap gap-4 mb-6 p-4 bg-slate-50 dark:bg-gray-900/50 rounded-lg border border-slate-100 dark:border-gray-800`},rl={class:`cursor-pointer role-bg-primary role-hover-primary role-text-on-fill px-5 py-3 rounded-lg text-base font-semibold transition-all shadow-md role-shadow-primary flex items-center gap-2`},il={key:0,class:`text-base role-text-primary font-mono`},al={key:1,class:`text-sm text-slate-500 dark:text-gray-400 font-mono`},ol={key:2,class:`text-sm role-text-error font-semibold`},sl={key:3,class:`h-8 border-l border-slate-200 dark:border-gray-700 mx-2`},cl={key:4,class:`flex items-center gap-2`},ll=[`value`],ul=[`disabled`],dl={key:0,class:`mb-6`},fl={class:`overflow-x-auto rounded-xl border border-slate-100 dark:border-gray-800 shadow-inner`},pl={class:`w-full text-sm text-left`},ml={class:`bg-slate-50 dark:bg-gray-800/50`},hl={class:`divide-y divide-slate-100 dark:divide-gray-800`},gl={key:1,class:`text-base font-bold text-slate-800 dark:text-gray-200 mb-3`},_l={class:`overflow-x-auto bg-white dark:bg-dark`},vl={id:`timePlot`,class:`min-w-[580px] w-full h-[400px] bg-white dark:bg-dark`},yl={key:2,class:`h-[300px] flex flex-col items-center justify-center text-slate-400 dark:text-gray-500 border-2 border-dashed border-slate-200 dark:border-gray-800 rounded-xl bg-slate-50/50 dark:bg-gray-900/30`};function bl(e,t,n,r,i,a){return K(),q(`div`,Co,[J(`header`,wo,[t[147]||=J(`div`,{class:`flex items-center gap-3`},[J(`img`,{src:`/ui/logo.png`,alt:`Logo`,class:`h-10 w-10 object-contain rounded-lg shadow-sm`}),J(`h1`,{class:`text-xl font-bold text-slate-900 dark:text-gray-100`},` 差分方程式分析 (Difference Equation Analyzer)`)],-1),J(`div`,To,[J(`button`,{onClick:t[0]||=(...t)=>e.toggleDarkMode&&e.toggleDarkMode(...t),class:`p-2 rounded-lg bg-slate-100 dark:bg-gray-800 hover:bg-slate-200 dark:hover:bg-gray-700 transition-colors shadow-sm`},[e.isDarkMode?(K(),q(`svg`,Eo,[...t[145]||=[J(`path`,{d:`M10 12a2 2 0 100-4 2 2 0 000 4z`},null,-1),J(`path`,{"fill-rule":`evenodd`,d:`M10 18a8 8 0 100-16 8 8 0 000 16zm1-13a1 1 0 10-2 0 1 1 0 002 0zM2 10a1 1 0 011-1h1a1 1 0 110 2H3a1 1 0 01-1-1zm14 0a1 1 0 011-1h1a1 1 0 110 2h-1a1 1 0 01-1-1zM5.05 5.05a1 1 0 011.414 0l.707.707a1 1 0 11-1.414 1.414l-.707-.707a1 1 0 010-1.414zm9.9 9.9a1 1 0 011.414 0l.707.707a1 1 0 11-1.414 1.414l-.707-.707a1 1 0 010-1.414zM5.05 14.95a1 1 0 010-1.414l.707-.707a1 1 0 011.414 1.414l-.707.707a1 1 0 01-1.414 0zm9.9-9.9a1 1 0 010-1.414l.707-.707a1 1 0 011.414 1.414l-.707.707a1 1 0 01-1.414 0z`,"clip-rule":`evenodd`},null,-1)]])):(K(),q(`svg`,Do,[...t[146]||=[J(`path`,{d:`M17.293 13.293A8 8 0 016.707 2.707a8.001 8.001 0 1010.586 10.586z`},null,-1)]]))])])]),J(`div`,Oo,[J(`button`,{onClick:t[1]||=t=>e.mobileTab=`settings`,class:k([e.mobileTab===`settings`?`border-b-2 role-border-primary role-text-primary role-bg-primary-soft`:`text-slate-500 dark:text-gray-400 hover:text-slate-700 dark:hover:text-gray-200`,`flex-1 flex items-center justify-center gap-2 py-3 text-sm font-semibold transition-colors`])},[...t[148]||=[J(`svg`,{class:`w-4 h-4`,fill:`none`,stroke:`currentColor`,viewBox:`0 0 24 24`},[J(`path`,{"stroke-linecap":`round`,"stroke-linejoin":`round`,"stroke-width":`2`,d:`M9.594 3.94c.09-.542.56-.94 1.11-.94h2.592c.55 0 1.02.398 1.11.94l.213 1.281c.063.374.313.686.655.85.11.052.218.108.324.168.325.183.72.177 1.039-.019l1.09-.67a1.125 1.125 0 011.45.12l1.833 1.833c.39.39.439.999.12 1.45l-.67 1.09c-.196.319-.202.714-.019 1.039.06.106.116.214.168.324.164.342.476.592.85.655l1.281.213c.542.09.94.56.94 1.11v2.592c0 .55-.398 1.02-.94 1.11l-1.281.213c-.374.063-.686.313-.85.655a6.47 6.47 0 01-.168.324c-.183.325-.177.72.019 1.039l.67 1.09c.319.451.27 1.06-.12 1.45l-1.833 1.833a1.125 1.125 0 01-1.45.12l-1.09-.67c-.319-.196-.714-.202-1.039-.019a6.47 6.47 0 01-.324.168c-.342.164-.592.476-.655.85l-.213 1.281c-.09.542-.56.94-1.11.94h-2.592c-.55 0-1.02-.398-1.11-.94l-.213-1.281c-.063-.374-.313-.686-.655-.85a6.47 6.47 0 01-.324-.168c-.325-.183-.72-.177-1.039.019l-1.09.67a1.125 1.125 0 01-1.45-.12L2.99 18.157a1.125 1.125 0 01-.12-1.45l.67-1.09c.196-.319.202-.714.019-1.039a6.47 6.47 0 01-.168-.324c-.164-.342-.476-.592-.85-.655l-1.281-.213A1.125 1.125 0 01.32 12.276V9.684c0-.55.398-1.02.94-1.11l1.281-.213c.374-.063.686-.313.85-.655.052-.11.108-.218.168-.324.183-.325.177-.72-.019-1.039l-.67-1.09a1.125 1.125 0 01.12-1.45L4.823 1.97a1.125 1.125 0 011.45-.12l1.09.67c.319.196.714.202 1.039.019.106-.06.214-.116.324-.168.342-.164.592-.476.655-.85l.213-1.281z`,transform:`translate(0.32 0.5) scale(0.97)`}),J(`path`,{"stroke-linecap":`round`,"stroke-linejoin":`round`,"stroke-width":`2`,d:`M15 12a3 3 0 11-6 0 3 3 0 016 0z`})],-1),Y(` 設定 `,-1)]],2),J(`button`,{onClick:t[2]||=t=>e.mobileTab=`chart`,class:k([e.mobileTab===`chart`?`border-b-2 role-border-primary role-text-primary role-bg-primary-soft`:`text-slate-500 dark:text-gray-400 hover:text-slate-700 dark:hover:text-gray-200`,`flex-1 flex items-center justify-center gap-2 py-3 text-sm font-semibold transition-colors`])},[t[149]||=J(`svg`,{class:`w-4 h-4`,fill:`none`,stroke:`currentColor`,viewBox:`0 0 24 24`},[J(`path`,{"stroke-linecap":`round`,"stroke-linejoin":`round`,"stroke-width":`2`,d:`M9 19v-6a2 2 0 00-2-2H5a2 2 0 00-2 2v6a2 2 0 002 2h2a2 2 0 002-2zm0 0V9a2 2 0 012-2h2a2 2 0 012 2v10m-6 0a2 2 0 002 2h2a2 2 0 002-2m0 0V5a2 2 0 012-2h2a2 2 0 012 2v14a2 2 0 01-2 2h-2a2 2 0 01-2-2z`})],-1),t[150]||=Y(` 圖表 `,-1),e.loadingBode?(K(),q(`span`,ko)):X(``,!0)],2)]),J(`div`,Ao,[J(`aside`,{class:k([e.mobileTab===`settings`?`flex`:`hidden`,`lg:flex flex-col w-full lg:w-96 h-full bg-white dark:bg-dark border-b lg:border-b-0 lg:border-r border-slate-200 dark:border-gray-800 overflow-y-auto p-5 gap-5 custom-scrollbar transition-colors duration-300`])},[J(`section`,null,[J(`h2`,jo,[t[151]||=J(`div`,{class:`flex items-center gap-2`},[J(`svg`,{class:`w-5 h-5`,fill:`none`,stroke:`currentColor`,viewBox:`0 0 24 24`},[J(`path`,{"stroke-linecap":`round`,"stroke-linejoin":`round`,"stroke-width":`2`,d:`M10.325 4.317c.426-1.756 2.924-1.756 3.35 0a1.724 1.724 0 002.573 1.066c1.543-.94 3.31.826 2.37 2.37a1.724 1.724 0 001.065 2.572c1.756.426 1.756 2.924 0 3.35a1.724 1.724 0 00-1.066 2.573c.94 1.543-.826 3.31-2.37 2.37a1.724 1.724 0 00-2.572 1.065c-.426 1.756-2.924 1.756-3.35 0a1.724 1.724 0 00-2.573-1.066c-1.543.94-3.31-.826-2.37-2.37a1.724 1.724 0 00-1.065-2.572c-1.756-.426-1.756-2.924 0-3.35a1.724 1.724 0 001.066-2.573c-.94-1.543.826-3.31 2.37-2.37.996.608 2.296.07 2.572-1.065z`}),J(`path`,{"stroke-linecap":`round`,"stroke-linejoin":`round`,"stroke-width":`2`,d:`M15 12a3 3 0 11-6 0 3 3 0 016 0z`})]),Y(` 濾波器設計 `)],-1),J(`button`,{onClick:t[3]||=(...t)=>e.resetFilterParams&&e.resetFilterParams(...t),class:`text-[10px] font-bold role-bg-warning-soft role-text-warning role-hover-warning-soft px-2 py-1 rounded transition-colors uppercase`},`重設設計`)]),B(J(`select`,{"onUpdate:modelValue":t[4]||=t=>e.filterType=t,onChange:t[5]||=(...t)=>e.onFilterTypeChange&&e.onFilterTypeChange(...t),class:`w-full bg-slate-50 dark:bg-gray-800 border border-slate-200 dark:border-gray-700 rounded-lg p-3 text-base role-focus-primary focus:ring-1 role-focus-ring-primary outline-none transition-all mb-3 text-slate-900 dark:text-gray-100 truncate`},[(K(!0),q(W,null,V(e.filterOptions,e=>(K(),q(`option`,{key:e,value:e},A(e),9,Mo))),128))],544),[[$a,e.filterType]]),e.filterType===`(無) 手動自訂`?X(``,!0):(K(),q(`div`,No,[[`Lowpass (低通)`,`Highpass (高通)`].includes(e.filterType)?(K(),q(`div`,Po,[J(`label`,Fo,[t[152]||=J(`span`,null,`截止頻率 f_c (Hz)`,-1),J(`span`,Io,A(e.formatK(e.params.fc)),1)]),B(J(`input`,{type:`range`,"onUpdate:modelValue":t[6]||=t=>e.params.fc=t,onInput:t[7]||=(...t)=>e.debouncedApply&&e.debouncedApply(...t),min:1,max:e.fs/2,class:`w-full role-range-primary mb-2`},null,40,Lo),[[Q,e.params.fc,void 0,{number:!0}]]),B(J(`input`,{type:`number`,"onUpdate:modelValue":t[8]||=t=>e.params.fc=t,onChange:t[9]||=(...t)=>e.applyFilterDesign&&e.applyFilterDesign(...t),class:`w-full bg-white dark:bg-gray-800 border border-slate-200 dark:border-gray-700 rounded p-3 text-base role-focus-primary outline-none text-slate-900 dark:text-gray-100`},null,544),[[Q,e.params.fc,void 0,{number:!0}]]),t[153]||=J(`label`,{class:`text-sm text-slate-500 dark:text-gray-400 mt-3 mb-2 block`},`階數 Order`,-1),J(`div`,Ro,[(K(),q(W,null,V([1,2,3],t=>J(`button`,{key:t,onClick:n=>{e.params.order=t,e.applyFilterDesign()},class:k([e.params.order===t?`role-bg-primary role-text-on-fill role-border-primary`:`bg-slate-200 dark:bg-gray-800 text-slate-600 dark:text-gray-400 border-slate-300 dark:border-gray-700`,`flex-1 rounded py-2.5 text-base font-medium border transition-colors`])},A(t),11,zo)),64))])])):X(``,!0),e.filterType===`Bandpass (帶通)`?(K(),q(`div`,Bo,[J(`label`,Vo,[t[154]||=J(`span`,null,`下截止頻率 f_low (Hz)`,-1),J(`span`,Ho,A(e.formatK(e.params.bp_f_low)),1)]),B(J(`input`,{type:`number`,"onUpdate:modelValue":t[10]||=t=>e.params.bp_f_low=t,onChange:t[11]||=(...t)=>e.applyFilterDesign&&e.applyFilterDesign(...t),class:`w-full bg-white dark:bg-gray-800 border border-slate-200 dark:border-gray-700 rounded p-3 text-base mb-2 text-slate-900 dark:text-gray-100`},null,544),[[Q,e.params.bp_f_low,void 0,{number:!0}]]),J(`label`,Uo,[t[155]||=J(`span`,null,`上截止頻率 f_high (Hz)`,-1),J(`span`,Wo,A(e.formatK(e.params.bp_f_high)),1)]),B(J(`input`,{type:`number`,"onUpdate:modelValue":t[12]||=t=>e.params.bp_f_high=t,onChange:t[13]||=(...t)=>e.applyFilterDesign&&e.applyFilterDesign(...t),class:`w-full bg-white dark:bg-gray-800 border border-slate-200 dark:border-gray-700 rounded p-3 text-base mb-2 text-slate-900 dark:text-gray-100`},null,544),[[Q,e.params.bp_f_high,void 0,{number:!0}]]),t[156]||=J(`label`,{class:`text-sm text-slate-500 dark:text-gray-400 mt-2 mb-2 block`},`階數 Order`,-1),J(`div`,Go,[(K(),q(W,null,V([1,2,3],t=>J(`button`,{key:t,onClick:n=>{e.params.bp_order=t,e.applyFilterDesign()},class:k([e.params.bp_order===t?`role-bg-primary role-text-on-fill role-border-primary`:`bg-slate-200 dark:bg-gray-800 text-slate-600 dark:text-gray-400 border-slate-300 dark:border-gray-700`,`flex-1 rounded py-1.5 text-sm border transition-colors`])},A(t),11,Ko)),64))])])):X(``,!0),e.filterType===`Notch (陷波器)`?(K(),q(`div`,qo,[J(`div`,null,[t[157]||=J(`label`,{class:`text-sm text-slate-500 dark:text-gray-400 mb-2 block`},`中心頻率 f_0 (Hz)`,-1),B(J(`input`,{type:`number`,"onUpdate:modelValue":t[14]||=t=>e.params.notch_f0=t,onChange:t[15]||=(...t)=>e.applyFilterDesign&&e.applyFilterDesign(...t),class:`w-full bg-white dark:bg-gray-800 border border-slate-200 dark:border-gray-700 rounded p-3 text-base text-slate-900 dark:text-gray-100`},null,544),[[Q,e.params.notch_f0,void 0,{number:!0}]])]),J(`div`,null,[t[158]||=J(`label`,{class:`text-sm text-slate-500 dark:text-gray-400 mb-2 block`},`品質因數 Q`,-1),B(J(`input`,{type:`number`,"onUpdate:modelValue":t[16]||=t=>e.params.notch_q=t,onChange:t[17]||=(...t)=>e.applyFilterDesign&&e.applyFilterDesign(...t),step:`0.1`,class:`w-full bg-white dark:bg-gray-800 border border-slate-200 dark:border-gray-700 rounded p-3 text-base text-slate-900 dark:text-gray-100`},null,544),[[Q,e.params.notch_q,void 0,{number:!0}]])])])):X(``,!0),e.filterType===`1P1Z (一極一零)`?(K(),q(`div`,Jo,[J(`div`,null,[t[159]||=J(`label`,{class:`text-sm text-slate-500 dark:text-gray-400 mb-2 block`},`零點頻率 Freq_z (Hz)`,-1),B(J(`input`,{type:`number`,"onUpdate:modelValue":t[18]||=t=>e.params.opoz_fz=t,onChange:t[19]||=(...t)=>e.applyFilterDesign&&e.applyFilterDesign(...t),class:`w-full bg-white dark:bg-gray-800 border border-slate-200 dark:border-gray-700 rounded p-3 text-base text-slate-900 dark:text-gray-100`},null,544),[[Q,e.params.opoz_fz,void 0,{number:!0}]])]),J(`div`,null,[t[160]||=J(`label`,{class:`text-sm text-slate-500 dark:text-gray-400 mb-2 block`},`極點頻率 Freq_p (Hz)`,-1),B(J(`input`,{type:`number`,"onUpdate:modelValue":t[20]||=t=>e.params.opoz_fp=t,onChange:t[21]||=(...t)=>e.applyFilterDesign&&e.applyFilterDesign(...t),class:`w-full bg-white dark:bg-gray-800 border border-slate-200 dark:border-gray-700 rounded p-3 text-base text-slate-900 dark:text-gray-100`},null,544),[[Q,e.params.opoz_fp,void 0,{number:!0}]])])])):X(``,!0),e.filterType===`2P1Z (二極一零)`?(K(),q(`div`,Yo,[J(`div`,null,[t[161]||=J(`label`,{class:`text-sm text-slate-500 dark:text-gray-400 mb-2 block`},`零點頻率 Freq_z (Hz)`,-1),B(J(`input`,{type:`number`,"onUpdate:modelValue":t[22]||=t=>e.params.tp1z_fz=t,onChange:t[23]||=(...t)=>e.applyFilterDesign&&e.applyFilterDesign(...t),class:`w-full bg-white dark:bg-gray-800 border border-slate-200 dark:border-gray-700 rounded p-3 text-base text-slate-900 dark:text-gray-100`},null,544),[[Q,e.params.tp1z_fz,void 0,{number:!0}]])]),J(`div`,null,[t[162]||=J(`label`,{class:`text-sm text-slate-500 dark:text-gray-400 mb-2 block`},`極點頻率 1 Freq_p1 (Hz)`,-1),B(J(`input`,{type:`number`,"onUpdate:modelValue":t[24]||=t=>e.params.tp1z_fp1=t,onChange:t[25]||=(...t)=>e.applyFilterDesign&&e.applyFilterDesign(...t),class:`w-full bg-white dark:bg-gray-800 border border-slate-200 dark:border-gray-700 rounded p-3 text-base text-slate-900 dark:text-gray-100`},null,544),[[Q,e.params.tp1z_fp1,void 0,{number:!0}]])]),J(`div`,null,[t[163]||=J(`label`,{class:`text-sm text-slate-500 dark:text-gray-400 mb-2 block`},`極點頻率 2 Freq_p2 (Hz)`,-1),B(J(`input`,{type:`number`,"onUpdate:modelValue":t[26]||=t=>e.params.tp1z_fp2=t,onChange:t[27]||=(...t)=>e.applyFilterDesign&&e.applyFilterDesign(...t),class:`w-full bg-white dark:bg-gray-800 border border-slate-200 dark:border-gray-700 rounded p-3 text-base text-slate-900 dark:text-gray-100`},null,544),[[Q,e.params.tp1z_fp2,void 0,{number:!0}]])])])):X(``,!0),e.filterType===`2P2Z (二極二零)`?(K(),q(`div`,Xo,[J(`div`,null,[t[164]||=J(`label`,{class:`text-sm text-slate-500 dark:text-gray-400 mb-2 block`},`零點頻率 1 Freq_z1 (Hz)`,-1),B(J(`input`,{type:`number`,"onUpdate:modelValue":t[28]||=t=>e.params.tptz_fz1=t,onChange:t[29]||=(...t)=>e.applyFilterDesign&&e.applyFilterDesign(...t),class:`w-full bg-white dark:bg-gray-800 border border-slate-200 dark:border-gray-700 rounded p-3 text-base text-slate-900 dark:text-gray-100`},null,544),[[Q,e.params.tptz_fz1,void 0,{number:!0}]])]),J(`div`,null,[t[165]||=J(`label`,{class:`text-sm text-slate-500 dark:text-gray-400 mb-2 block`},`零點頻率 2 Freq_z2 (Hz)`,-1),B(J(`input`,{type:`number`,"onUpdate:modelValue":t[30]||=t=>e.params.tptz_fz2=t,onChange:t[31]||=(...t)=>e.applyFilterDesign&&e.applyFilterDesign(...t),class:`w-full bg-white dark:bg-gray-800 border border-slate-200 dark:border-gray-700 rounded p-3 text-base text-slate-900 dark:text-gray-100`},null,544),[[Q,e.params.tptz_fz2,void 0,{number:!0}]])]),J(`div`,null,[t[166]||=J(`label`,{class:`text-sm text-slate-500 dark:text-gray-400 mb-2 block`},`極點頻率 1 Freq_p1 (Hz)`,-1),B(J(`input`,{type:`number`,"onUpdate:modelValue":t[32]||=t=>e.params.tptz_fp1=t,onChange:t[33]||=(...t)=>e.applyFilterDesign&&e.applyFilterDesign(...t),class:`w-full bg-white dark:bg-gray-800 border border-slate-200 dark:border-gray-700 rounded p-3 text-base text-slate-900 dark:text-gray-100`},null,544),[[Q,e.params.tptz_fp1,void 0,{number:!0}]])]),J(`div`,null,[t[167]||=J(`label`,{class:`text-sm text-slate-500 dark:text-gray-400 mb-2 block`},`極點頻率 2 Freq_p2 (Hz)`,-1),B(J(`input`,{type:`number`,"onUpdate:modelValue":t[34]||=t=>e.params.tptz_fp2=t,onChange:t[35]||=(...t)=>e.applyFilterDesign&&e.applyFilterDesign(...t),class:`w-full bg-white dark:bg-gray-800 border border-slate-200 dark:border-gray-700 rounded p-3 text-base text-slate-900 dark:text-gray-100`},null,544),[[Q,e.params.tptz_fp2,void 0,{number:!0}]])])])):X(``,!0),e.filterType===`PID 控制器`?(K(),q(`div`,Zo,[(K(),q(W,null,V([{key:`kp`,label:`比例增益 Kp`},{key:`ki`,label:`積分增益 Ki`},{key:`kd`,label:`微分增益 Kd`}],n=>J(`div`,{key:n.key},[J(`label`,Qo,A(n.label),1),B(J(`input`,{type:`number`,"onUpdate:modelValue":t=>e.params[n.key]=t,onChange:t[36]||=(...t)=>e.applyFilterDesign&&e.applyFilterDesign(...t),step:`0.0001`,class:`w-full bg-white dark:bg-gray-800 border border-slate-200 dark:border-gray-700 rounded p-3 text-base role-focus-primary outline-none text-slate-900 dark:text-gray-100`},null,40,$o),[[Q,e.params[n.key],void 0,{number:!0}]])])),64))])):X(``,!0),e.filterType===`SOGI-Alpha (帶通)`||e.filterType===`SOGI-Beta (低通)`?(K(),q(`div`,es,[J(`div`,null,[t[168]||=J(`label`,{class:`text-xs text-slate-500 dark:text-gray-400 mb-1 block`},`中心頻率 f_0 (Hz)`,-1),B(J(`input`,{type:`number`,"onUpdate:modelValue":t[37]||=t=>e.params.sogi_f0=t,onChange:t[38]||=(...t)=>e.applyFilterDesign&&e.applyFilterDesign(...t),class:`w-full bg-white dark:bg-gray-800 border border-slate-200 dark:border-gray-700 rounded p-2 text-sm text-slate-900 dark:text-gray-100`},null,544),[[Q,e.params.sogi_f0,void 0,{number:!0}]])]),J(`div`,null,[t[169]||=J(`label`,{class:`text-xs text-slate-500 dark:text-gray-400 mb-1 block`},`阻尼因數 k`,-1),B(J(`input`,{type:`number`,"onUpdate:modelValue":t[39]||=t=>e.params.sogi_k=t,onChange:t[40]||=(...t)=>e.applyFilterDesign&&e.applyFilterDesign(...t),step:`0.001`,class:`w-full bg-white dark:bg-gray-800 border border-slate-200 dark:border-gray-700 rounded p-2 text-sm text-slate-900 dark:text-gray-100`},null,544),[[Q,e.params.sogi_k,void 0,{number:!0}]])])])):X(``,!0),t[170]||=J(`div`,{class:`role-bg-primary-soft border role-border-primary-soft rounded-lg p-3 text-sm role-text-primary mt-2`},` 調整上方參數會自動覆寫 a, b 係數。你也可以隨時手動修改下方係數進行微調。 `,-1)]))]),t[207]||=J(`hr`,{class:`border-slate-200 dark:border-gray-800`},null,-1),J(`section`,null,[t[173]||=J(`h2`,{class:`text-sm font-semibold text-slate-500 dark:text-gray-400 uppercase tracking-wider mb-3 flex items-center gap-2`},[J(`svg`,{class:`w-5 h-5`,fill:`none`,stroke:`currentColor`,viewBox:`0 0 24 24`},[J(`path`,{"stroke-linecap":`round`,"stroke-linejoin":`round`,"stroke-width":`2`,d:`M10.325 4.317c.426-1.756 2.924-1.756 3.35 0a1.724 1.724 0 002.573 1.066c1.543-.94 3.31.826 2.37 2.37a1.724 1.724 0 001.065 2.572c1.756.426 1.756 2.924 0 3.35a1.724 1.724 0 00-1.066 2.573c.94 1.543-.826 3.31-2.37 2.37a1.724 1.724 0 00-2.572 1.065c-.426 1.756-2.924 1.756-3.35 0a1.724 1.724 0 00-2.573-1.066c-1.543.94-3.31-.826-2.37-2.37a1.724 1.724 0 00-1.065-2.572c-1.756-.426-1.756-2.924 0-3.35a1.724 1.724 0 001.066-2.573c-.94-1.543.826-3.31 2.37-2.37.996.608 2.296.07 2.572-1.065z`}),J(`path`,{"stroke-linecap":`round`,"stroke-linejoin":`round`,"stroke-width":`2`,d:`M15 12a3 3 0 11-6 0 3 3 0 016 0z`})]),Y(` 系統參數`)],-1),J(`div`,ts,[J(`div`,null,[J(`label`,ns,[t[171]||=J(`span`,null,`取樣頻率 fs (Hz)`,-1),J(`span`,rs,A(e.formatK(e.fs)),1)]),B(J(`input`,{type:`number`,"onUpdate:modelValue":t[41]||=t=>e.fs=t,onInput:t[42]||=(...t)=>e.debouncedApply&&e.debouncedApply(...t),onKeydown:t[43]||=(...t)=>e.onlyNumberKey&&e.onlyNumberKey(...t),class:`w-full bg-white dark:bg-gray-800 border border-slate-200 dark:border-gray-700 rounded-lg p-3 text-base role-focus-primary outline-none transition-all text-slate-900 dark:text-gray-100`},null,544),[[Q,e.fs,void 0,{number:!0}]])]),J(`div`,null,[J(`label`,is,[t[172]||=J(`span`,null,`系統增益 K (System Gain)`,-1),J(`span`,as,A(e.systemGain)+`x`,1)]),B(J(`input`,{type:`number`,"onUpdate:modelValue":t[44]||=t=>e.systemGain=t,onInput:t[45]||=(...t)=>e.onGainChange&&e.onGainChange(...t),step:`0.1`,onKeydown:t[46]||=(...t)=>e.onlyNumberKey&&e.onlyNumberKey(...t),class:`w-full bg-white dark:bg-gray-800 border border-slate-200 dark:border-gray-700 rounded-lg p-3 text-base role-focus-primary outline-none transition-all text-slate-900 dark:text-gray-100`},null,544),[[Q,e.systemGain,void 0,{number:!0}]])])])]),t[208]||=J(`hr`,{class:`border-slate-200 dark:border-gray-800`},null,-1),J(`section`,null,[J(`h2`,os,[t[174]||=J(`span`,{class:`flex items-center gap-2`},[J(`svg`,{class:`w-5 h-5`,fill:`none`,stroke:`currentColor`,viewBox:`0 0 24 24`},[J(`path`,{"stroke-linecap":`round`,"stroke-linejoin":`round`,"stroke-width":`2`,d:`M4 7h16M4 12h16M4 17h16M8 7v10M16 7v10`})]),Y(` 濾波器係數設定`)],-1),J(`div`,ss,[e.isManualDirty?(K(),q(`button`,{key:0,onClick:t[47]||=(...t)=>e.clearManualAdjustments&&e.clearManualAdjustments(...t),class:`text-[10px] font-bold bg-slate-200 dark:bg-gray-800 hover:bg-slate-300 dark:hover:bg-gray-700 px-2 py-1 rounded text-slate-500 transition-colors uppercase mr-1`},`重設`)):X(``,!0)])]),J(`div`,cs,[t[175]||=J(`label`,{class:`text-sm text-slate-500 dark:text-gray-400 mb-1 block`},`前饋分子係數 b (b0 ~ b6)`,-1),J(`div`,ls,[(K(!0),q(W,null,V(e.floatingCoeffs.b,e=>(K(),q(`div`,{key:e.label,class:`role-bg-primary-soft px-1.5 py-0.5 rounded border role-border-primary-soft flex gap-1 items-center`},[J(`span`,us,A(e.label)+`:`,1),J(`span`,ds,A(e.val),1)]))),128))]),B(J(`textarea`,{"onUpdate:modelValue":t[48]||=t=>e.b_str=t,onInput:t[49]||=t=>e.debouncedUpdateFromText(`b`),onKeydown:t[50]||=(...t)=>e.onlyNumberKey&&e.onlyNumberKey(...t),rows:`2`,class:`w-full bg-slate-50 dark:bg-gray-900 border border-slate-200 dark:border-gray-700 rounded-lg p-3 text-sm role-focus-primary outline-none font-mono resize-none leading-relaxed role-text-primary`},null,544),[[Q,e.b_str]])]),J(`details`,{open:e.activeCoeffAdjustment===`bScale`,class:`mb-3 bg-slate-50 dark:bg-gray-900 border border-slate-200 dark:border-gray-800 rounded-lg`},[J(`summary`,{onClick:t[51]||=$(t=>e.toggleCoeffAdjustment(`bScale`),[`prevent`]),class:`text-sm text-slate-500 dark:text-gray-400 px-3 py-3 cursor-pointer hover:text-slate-600 dark:hover:text-gray-300`},` b 係數倍率微調`),J(`div`,ps,[J(`div`,ms,[t[176]||=J(`span`,{class:`text-xs text-slate-400 dark:text-gray-500`},`靈敏度:`,-1),(K(),q(W,null,V([`1%`,`2x`,`10x`],t=>J(`button`,{key:t,onClick:n=>e.sense_b=t,class:k([e.sense_b===t?`role-bg-primary role-text-on-fill`:`bg-slate-200 dark:bg-gray-800 text-slate-500 dark:text-gray-400`,`btn-small px-3 py-1.5 rounded text-xs font-medium border border-slate-300 dark:border-gray-700`])},A(t),11,hs)),64))]),(K(),q(W,null,V(7,n=>(K(),q(W,{key:`bs`+n},[e.baseB[n-1]===0?X(``,!0):(K(),q(`div`,gs,[J(`label`,_s,[J(`span`,null,`b`+A(n-1)+` (基準: `+A((e.baseB[n-1]*(e.systemGain||1)).toPrecision(6))+`)`,1),e.outOfRangeB[n-1]?(K(),q(`span`,vs,`超出滑桿範圍`)):X(``,!0)]),B(J(`input`,{type:`range`,"onUpdate:modelValue":t=>e.bSliders[n-1]=t,onInput:t[52]||=(...t)=>e.updateFromControls&&e.updateFromControls(...t),min:-e.maxLogB,max:e.maxLogB,step:e.maxLogB/100,class:`w-full role-range-primary`},null,40,ys),[[Q,e.bSliders[n-1],void 0,{number:!0}]])]))],64))),64))])],8,fs),J(`div`,bs,[t[177]||=J(`label`,{class:`text-sm text-slate-500 dark:text-gray-400 mb-1 block`},`回饋分母係數 a (a0=1, a1 ~ a6)`,-1),J(`div`,xs,[(K(!0),q(W,null,V(e.floatingCoeffs.a,e=>(K(),q(`div`,{key:e.label,class:`role-bg-secondary-soft px-1.5 py-0.5 rounded border role-border-secondary-soft flex gap-1 items-center`},[J(`span`,Ss,A(e.label)+`:`,1),J(`span`,Cs,A(e.val),1)]))),128))]),B(J(`textarea`,{"onUpdate:modelValue":t[53]||=t=>e.a_str=t,onInput:t[54]||=t=>e.debouncedUpdateFromText(`a`),onKeydown:t[55]||=(...t)=>e.onlyNumberKey&&e.onlyNumberKey(...t),rows:`2`,class:`w-full bg-slate-50 dark:bg-gray-900 border border-slate-200 dark:border-gray-700 rounded-lg p-3 text-sm role-focus-primary outline-none font-mono resize-none leading-relaxed role-text-secondary`},null,544),[[Q,e.a_str]])]),J(`details`,{open:e.activeCoeffAdjustment===`aScale`,class:`bg-slate-50 dark:bg-gray-900 border border-slate-200 dark:border-gray-800 rounded-lg`},[J(`summary`,{onClick:t[56]||=$(t=>e.toggleCoeffAdjustment(`aScale`),[`prevent`]),class:`text-sm text-slate-500 dark:text-gray-400 px-3 py-3 cursor-pointer hover:text-slate-600 dark:hover:text-gray-300`},` a 係數倍率微調`),J(`div`,Ts,[J(`div`,Es,[t[178]||=J(`span`,{class:`text-xs text-slate-400 dark:text-gray-500`},`靈敏度:`,-1),(K(),q(W,null,V([`1%`,`2x`,`10x`],t=>J(`button`,{key:t,onClick:n=>e.sense_a=t,class:k([e.sense_a===t?`role-bg-primary role-text-on-fill`:`bg-slate-200 dark:bg-gray-800 text-slate-500 dark:text-gray-400`,`px-3 py-1.5 rounded text-xs font-medium border border-slate-300 dark:border-gray-700`])},A(t),11,Ds)),64))]),(K(),q(W,null,V(6,n=>(K(),q(W,{key:`as`+n},[e.baseA[n]===0?X(``,!0):(K(),q(`div`,Os,[J(`label`,ks,[J(`span`,null,`a`+A(n)+` (基準: `+A(e.baseA[n].toPrecision(6))+`)`,1),e.outOfRangeA[n]?(K(),q(`span`,As,`超出滑桿範圍`)):X(``,!0)]),B(J(`input`,{type:`range`,"onUpdate:modelValue":t=>e.aSliders[n]=t,onInput:t[57]||=(...t)=>e.updateFromControls&&e.updateFromControls(...t),min:-e.maxLogA,max:e.maxLogA,step:e.maxLogA/100,class:`w-full role-range-secondary`},null,40,js),[[Q,e.aSliders[n],void 0,{number:!0}]])]))],64))),64))])],8,ws),J(`details`,{open:e.activeCoeffAdjustment===`a1a2`,class:`mt-3 bg-slate-50 dark:bg-gray-900 border border-slate-200 dark:border-gray-800 rounded-lg`},[J(`summary`,{onClick:t[58]||=$(t=>e.toggleCoeffAdjustment(`a1a2`),[`prevent`]),class:`text-sm text-slate-500 dark:text-gray-400 px-3 py-3 cursor-pointer hover:text-slate-600 dark:hover:text-gray-300`},` a1/a2 步階微調`),J(`div`,Ns,[J(`div`,Ps,[J(`div`,Fs,[J(`button`,{type:`button`,onClick:t[59]||=t=>e.adjustAFineStep(-1),title:`調粗`,class:`rounded-lg border border-slate-200 dark:border-gray-700 bg-white dark:bg-gray-800 text-slate-600 dark:text-gray-300 py-2 text-xs font-bold transition-colors hover:bg-slate-100 dark:hover:bg-gray-700`},` 粗 `),J(`div`,Is,[t[179]||=J(`span`,{class:`block text-[9px] role-text-tertiary-muted role-text-tertiary font-bold`},`微調量`,-1),J(`span`,{class:`block truncate font-mono text-sm font-bold role-text-tertiary`,title:e.formatAFineDelta()},` +/-`+A(e.formatAFineDelta()),9,Ls)]),J(`button`,{type:`button`,onClick:t[60]||=t=>e.adjustAFineStep(1),title:`調細`,class:`rounded-lg border border-slate-200 dark:border-gray-700 bg-white dark:bg-gray-800 text-slate-600 dark:text-gray-300 py-2 text-xs font-bold transition-colors hover:bg-slate-100 dark:hover:bg-gray-700`},` 細 `)]),J(`div`,Rs,A(e.isTouchInput?`觸控拖曳微調`:`直接輸入 / shift + 滾輪微調`),1),J(`div`,zs,[e.isTouchInput?(K(),q(`button`,{key:1,type:`button`,onPointerdown:t[72]||=$(t=>e.startAFineDrag(`delta`,t),[`prevent`]),class:`touch-none select-none w-28 mx-auto bg-white dark:bg-gray-800 border border-slate-200 dark:border-gray-700 rounded-lg p-3 text-center role-active-border-tertiary active:ring-2 role-active-ring-tertiary`},[t[181]||=J(`span`,{class:`text-[9px] text-slate-400 block font-bold mb-1`},`δ`,-1),J(`span`,{class:`block max-w-full truncate text-base font-mono font-bold role-text-tertiary`,title:e.formatFineCoeff(e.currentDelta)},A(e.formatFineCoeff(e.currentDelta)),9,Us)],32)):(K(),q(`label`,Bs,[t[180]||=J(`span`,{class:`text-[9px] text-slate-400 block font-bold mb-1`},`δ`,-1),J(`div`,Vs,[J(`button`,{type:`button`,onPointerdown:t[61]||=$(t=>e.startA1A2Repeat(`delta`,-1),[`prevent`]),onPointerup:t[62]||=(...t)=>e.stopA1A2Repeat&&e.stopA1A2Repeat(...t),onPointerleave:t[63]||=(...t)=>e.stopA1A2Repeat&&e.stopA1A2Repeat(...t),onPointercancel:t[64]||=(...t)=>e.stopA1A2Repeat&&e.stopA1A2Repeat(...t),class:`rounded-lg bg-slate-200 dark:bg-gray-800 hover:bg-slate-300 dark:hover:bg-gray-700 text-slate-700 dark:text-gray-300 text-sm font-bold transition-colors`},`-`,32),J(`input`,{type:`number`,value:e.formatFineCoeff(e.currentDelta),step:e.aFineStep,onChange:t[65]||=t=>e.setAFineDirect(`delta`,t.target.value),onKeydown:t[66]||=(...t)=>e.onlyNumberKey&&e.onlyNumberKey(...t),onWheel:t[67]||=t=>e.handleAFineWheel(`delta`,t),class:`min-w-0 w-full bg-white dark:bg-gray-800 border border-slate-200 dark:border-gray-700 rounded-lg p-3 text-xs font-mono text-center role-text-tertiary`},null,40,Hs),J(`button`,{type:`button`,onPointerdown:t[68]||=$(t=>e.startA1A2Repeat(`delta`,1),[`prevent`]),onPointerup:t[69]||=(...t)=>e.stopA1A2Repeat&&e.stopA1A2Repeat(...t),onPointerleave:t[70]||=(...t)=>e.stopA1A2Repeat&&e.stopA1A2Repeat(...t),onPointercancel:t[71]||=(...t)=>e.stopA1A2Repeat&&e.stopA1A2Repeat(...t),class:`rounded-lg bg-slate-200 dark:bg-gray-800 hover:bg-slate-300 dark:hover:bg-gray-700 text-slate-700 dark:text-gray-300 text-sm font-bold transition-colors`},`+`,32)])])),e.isTouchInput?(K(),q(`button`,{key:3,type:`button`,onPointerdown:t[84]||=$(t=>e.startAFineDrag(`r`,t),[`prevent`]),class:`touch-none select-none w-28 mx-auto bg-white dark:bg-gray-800 border border-slate-200 dark:border-gray-700 rounded-lg p-3 text-center role-active-border-primary active:ring-2 role-active-ring-primary`},[t[183]||=J(`span`,{class:`text-[9px] text-slate-400 block font-bold mb-1`},`r`,-1),J(`span`,{class:`block max-w-full truncate text-base font-mono font-bold role-text-primary`,title:e.formatFineCoeff(e.currentR)},A(e.formatFineCoeff(e.currentR)),9,qs)],32)):(K(),q(`label`,Ws,[t[182]||=J(`span`,{class:`text-[9px] text-slate-400 block font-bold mb-1`},`r`,-1),J(`div`,Gs,[J(`button`,{type:`button`,onPointerdown:t[73]||=$(t=>e.startA1A2Repeat(`r`,-1),[`prevent`]),onPointerup:t[74]||=(...t)=>e.stopA1A2Repeat&&e.stopA1A2Repeat(...t),onPointerleave:t[75]||=(...t)=>e.stopA1A2Repeat&&e.stopA1A2Repeat(...t),onPointercancel:t[76]||=(...t)=>e.stopA1A2Repeat&&e.stopA1A2Repeat(...t),class:`rounded-lg role-bg-tertiary-soft role-hover-tertiary-soft role-text-tertiary text-sm font-bold transition-colors`},`-`,32),J(`input`,{type:`number`,value:e.formatFineCoeff(e.currentR),step:e.aFineStep,onChange:t[77]||=t=>e.setAFineDirect(`r`,t.target.value),onKeydown:t[78]||=(...t)=>e.onlyNumberKey&&e.onlyNumberKey(...t),onWheel:t[79]||=t=>e.handleAFineWheel(`r`,t),class:`min-w-0 w-full bg-white dark:bg-gray-800 border border-slate-200 dark:border-gray-700 rounded-lg p-3 text-xs font-mono text-center role-text-primary`},null,40,Ks),J(`button`,{type:`button`,onPointerdown:t[80]||=$(t=>e.startA1A2Repeat(`r`,1),[`prevent`]),onPointerup:t[81]||=(...t)=>e.stopA1A2Repeat&&e.stopA1A2Repeat(...t),onPointerleave:t[82]||=(...t)=>e.stopA1A2Repeat&&e.stopA1A2Repeat(...t),onPointercancel:t[83]||=(...t)=>e.stopA1A2Repeat&&e.stopA1A2Repeat(...t),class:`rounded-lg role-bg-primary-soft role-hover-primary-soft role-text-primary text-sm font-bold transition-colors`},`+`,32)])]))])]),J(`div`,Js,[J(`div`,Ys,[t[184]||=J(`span`,{class:`text-[9px] text-slate-400 block font-bold mb-1`},`a1 = -1 - r + δ`,-1),J(`span`,{class:`block max-w-full truncate text-sm font-mono font-bold role-text-tertiary`,title:e.formatFineCoeff(e.currentA1)},A(e.formatFineCoeff(e.currentA1)),9,Xs)]),J(`div`,Zs,[t[185]||=J(`span`,{class:`text-[9px] text-slate-400 block font-bold mb-1`},`a2 = r + δ`,-1),J(`span`,{class:`block max-w-full truncate text-sm font-mono font-bold role-text-primary`,title:e.formatFineCoeff(e.currentA2)},A(e.formatFineCoeff(e.currentA2)),9,Qs)]),J(`div`,$s,[t[186]||=J(`span`,{class:`text-[9px] text-slate-400 block font-bold mb-1`},`差值 a1-a2`,-1),J(`span`,{class:`block max-w-full truncate text-xs font-mono text-slate-600 dark:text-gray-300`,title:e.formatFineCoeff(e.currentA1A2Diff)},A(e.formatFineCoeff(e.currentA1A2Diff)),9,ec)]),J(`div`,tc,[t[187]||=J(`span`,{class:`text-[9px] text-slate-400 block font-bold mb-1`},`總和 a1+a2`,-1),J(`span`,{class:`block max-w-full truncate text-xs font-mono text-slate-600 dark:text-gray-300`,title:e.formatFineCoeff(e.currentA1A2Sum)},A(e.formatFineCoeff(e.currentA1A2Sum)),9,nc)])]),t[188]||=J(`div`,{class:`role-bg-warning-soft border role-border-warning-soft rounded-lg p-3`},[J(`p`,{class:`text-[10px] role-text-warning leading-relaxed`},[J(`span`,{class:`font-bold`},`運算說明:`),J(`br`),Y(` δ = (a1 + a2 + 1) / 2,r = (a2 - a1 - 1) / 2。更改數值會自動更新圖表;桌機可用 +/- 或 shift + 滾輪,觸控時按住數值面板上下拖曳。 `)])],-1)])],8,Ms)]),t[209]||=J(`hr`,{class:`border-slate-200 dark:border-gray-800`},null,-1),J(`section`,null,[J(`h2`,rc,[J(`div`,ic,[t[189]||=J(`svg`,{class:`w-5 h-5`,fill:`none`,stroke:`currentColor`,viewBox:`0 0 24 24`},[J(`path`,{"stroke-linecap":`round`,"stroke-linejoin":`round`,"stroke-width":`2`,d:`M9 7h6M9 12h6M9 17h3M5 5a2 2 0 012-2h7l5 5v11a2 2 0 01-2 2H7a2 2 0 01-2-2V5z`})],-1),t[190]||=J(`span`,null,`定點數係數轉換`,-1),J(`span`,ac,`b Q`+A(e.shiftBitsB),1),J(`span`,oc,`a Q`+A(e.shiftBitsA),1)]),J(`div`,sc,[e.isFixedPointDirty?(K(),q(`button`,{key:0,onClick:t[85]||=(...t)=>e.resetFixedPointSettings&&e.resetFixedPointSettings(...t),class:`text-[10px] font-bold bg-slate-200 dark:bg-gray-800 hover:bg-slate-300 dark:hover:bg-gray-700 px-2 py-1 rounded text-slate-500 transition-colors uppercase mr-1`},`重設`)):X(``,!0)])]),J(`div`,cc,[J(`div`,null,[t[191]||=J(`label`,{class:`text-sm text-slate-500 dark:text-gray-400 mb-1 block`},`b 左移位元數 (Shift Bits)`,-1),e.isTouchInput?(K(),q(`button`,{key:1,type:`button`,onPointerdown:t[97]||=$(t=>e.startShiftBitDrag(`b`,t),[`prevent`]),class:`touch-none select-none block w-24 mx-auto bg-white dark:bg-gray-800 border border-slate-200 dark:border-gray-700 rounded-lg p-3 text-center role-active-border-primary active:ring-2 role-active-ring-primary`},[J(`span`,dc,A(e.shiftBitsB),1)],32)):(K(),q(`div`,lc,[J(`button`,{type:`button`,onPointerdown:t[86]||=$(t=>e.startShiftBitRepeat(`b`,-1),[`prevent`]),onPointerup:t[87]||=(...t)=>e.stopShiftBitRepeat&&e.stopShiftBitRepeat(...t),onPointerleave:t[88]||=(...t)=>e.stopShiftBitRepeat&&e.stopShiftBitRepeat(...t),onPointercancel:t[89]||=(...t)=>e.stopShiftBitRepeat&&e.stopShiftBitRepeat(...t),class:`rounded-lg role-bg-primary-soft role-hover-primary-soft role-text-primary text-sm font-bold transition-colors`},`-`,32),J(`input`,{type:`number`,value:e.shiftBitsB,min:`0`,onChange:t[90]||=t=>e.setShiftBits(`b`,t.target.value),onKeydown:t[91]||=(...t)=>e.onlyNumberKey&&e.onlyNumberKey(...t),onWheel:t[92]||=t=>e.handleShiftBitWheel(`b`,t),class:`min-w-0 w-full bg-white dark:bg-gray-800 border border-slate-200 dark:border-gray-700 rounded-lg p-3 text-base role-focus-primary outline-none transition-all text-slate-900 dark:text-gray-100`},null,40,uc),J(`button`,{type:`button`,onPointerdown:t[93]||=$(t=>e.startShiftBitRepeat(`b`,1),[`prevent`]),onPointerup:t[94]||=(...t)=>e.stopShiftBitRepeat&&e.stopShiftBitRepeat(...t),onPointerleave:t[95]||=(...t)=>e.stopShiftBitRepeat&&e.stopShiftBitRepeat(...t),onPointercancel:t[96]||=(...t)=>e.stopShiftBitRepeat&&e.stopShiftBitRepeat(...t),class:`rounded-lg role-bg-primary-soft role-hover-primary-soft role-text-primary text-sm font-bold transition-colors`},`+`,32)])),J(`p`,fc,`b scaling: 2^`+A(e.shiftBitsB)+` (`+A(2**e.shiftBitsB)+`)`,1)]),J(`div`,null,[t[192]||=J(`label`,{class:`text-sm text-slate-500 dark:text-gray-400 mb-1 block`},`a 左移位元數 (Shift Bits)`,-1),e.isTouchInput?(K(),q(`button`,{key:1,type:`button`,onPointerdown:t[109]||=$(t=>e.startShiftBitDrag(`a`,t),[`prevent`]),class:`touch-none select-none block w-24 mx-auto bg-white dark:bg-gray-800 border border-slate-200 dark:border-gray-700 rounded-lg p-3 text-center role-active-border-secondary active:ring-2 role-active-ring-secondary`},[J(`span`,hc,A(e.shiftBitsA),1)],32)):(K(),q(`div`,pc,[J(`button`,{type:`button`,onPointerdown:t[98]||=$(t=>e.startShiftBitRepeat(`a`,-1),[`prevent`]),onPointerup:t[99]||=(...t)=>e.stopShiftBitRepeat&&e.stopShiftBitRepeat(...t),onPointerleave:t[100]||=(...t)=>e.stopShiftBitRepeat&&e.stopShiftBitRepeat(...t),onPointercancel:t[101]||=(...t)=>e.stopShiftBitRepeat&&e.stopShiftBitRepeat(...t),class:`rounded-lg role-bg-secondary-soft role-hover-secondary-soft role-text-secondary text-sm font-bold transition-colors`},`-`,32),J(`input`,{type:`number`,value:e.shiftBitsA,min:`0`,onChange:t[102]||=t=>e.setShiftBits(`a`,t.target.value),onKeydown:t[103]||=(...t)=>e.onlyNumberKey&&e.onlyNumberKey(...t),onWheel:t[104]||=t=>e.handleShiftBitWheel(`a`,t),class:`min-w-0 w-full bg-white dark:bg-gray-800 border border-slate-200 dark:border-gray-700 rounded-lg p-3 text-base role-focus-primary outline-none transition-all text-slate-900 dark:text-gray-100`},null,40,mc),J(`button`,{type:`button`,onPointerdown:t[105]||=$(t=>e.startShiftBitRepeat(`a`,1),[`prevent`]),onPointerup:t[106]||=(...t)=>e.stopShiftBitRepeat&&e.stopShiftBitRepeat(...t),onPointerleave:t[107]||=(...t)=>e.stopShiftBitRepeat&&e.stopShiftBitRepeat(...t),onPointercancel:t[108]||=(...t)=>e.stopShiftBitRepeat&&e.stopShiftBitRepeat(...t),class:`rounded-lg role-bg-secondary-soft role-hover-secondary-soft role-text-secondary text-sm font-bold transition-colors`},`+`,32)])),J(`p`,gc,`a scaling: 2^`+A(e.shiftBitsA)+` (`+A(2**e.shiftBitsA)+`)`,1)])]),J(`div`,_c,[J(`div`,null,[t[193]||=J(`label`,{class:`text-sm text-slate-500 dark:text-gray-400 mb-1 block`},`定點分子係數 b (Integers)`,-1),J(`div`,vc,[(K(!0),q(W,null,V(e.fixedPointCoeffs.b,(e,t)=>(K(),q(`div`,{key:e.label,class:k([e.isOverridden?`role-border-primary ring-1 role-ring-primary`:`role-border-primary-soft`,`role-bg-primary-soft px-1.5 py-0.5 rounded border flex items-center gap-1 transition-all`])},[J(`span`,yc,A(e.label)+`:`,1),J(`span`,{class:k([`text-[10px] font-mono role-text-primary font-bold`,{italic:!e.isOverridden}])},A(e.val),3)],2))),128))]),B(J(`textarea`,{"onUpdate:modelValue":t[110]||=t=>e.b_int_str=t,onKeydown:t[111]||=t=>e.onlyNumberKey(t,!1),rows:`2`,class:`w-full bg-slate-50 dark:bg-gray-900 border border-slate-200 dark:border-gray-700 rounded-lg p-3 text-sm role-focus-primary outline-none font-mono resize-none leading-relaxed role-text-primary`},null,544),[[Q,e.b_int_str]])]),J(`div`,null,[t[206]||=J(`label`,{class:`text-sm text-slate-500 dark:text-gray-400 mb-1 block`},`定點分母係數 a (Integers)`,-1),J(`div`,bc,[(K(!0),q(W,null,V(e.fixedPointCoeffs.a,(e,t)=>(K(),q(`div`,{key:e.label,class:k([e.isOverridden?`role-border-secondary ring-1 role-ring-secondary`:`role-border-secondary-soft`,`role-bg-secondary-soft px-1.5 py-0.5 rounded border flex items-center gap-1 transition-all`])},[J(`span`,xc,A(e.label)+`:`,1),J(`span`,{class:k([`text-[10px] font-mono role-text-secondary font-bold`,{italic:!e.isOverridden}])},A(e.val),3)],2))),128))]),B(J(`textarea`,{"onUpdate:modelValue":t[112]||=t=>e.a_int_str=t,onKeydown:t[113]||=t=>e.onlyNumberKey(t,!1),rows:`2`,class:`w-full bg-slate-50 dark:bg-gray-900 border border-slate-200 dark:border-gray-700 rounded-lg p-3 text-sm role-focus-primary outline-none font-mono resize-none leading-relaxed role-text-secondary`},null,544),[[Q,e.a_int_str]]),J(`details`,Sc,[t[205]||=J(`summary`,{class:`text-sm text-slate-500 dark:text-gray-400 px-3 py-3 cursor-pointer hover:text-slate-600 dark:hover:text-gray-300`},` a1/a2 步階微調`,-1),J(`div`,Cc,[J(`div`,wc,[J(`div`,Tc,[J(`button`,{type:`button`,onClick:t[114]||=t=>e.adjustFixedAFineStep(-1),title:`調粗`,class:`rounded-lg border border-slate-200 dark:border-gray-700 bg-white dark:bg-gray-800 text-slate-600 dark:text-gray-300 py-2 text-xs font-bold transition-colors hover:bg-slate-100 dark:hover:bg-gray-700`},`粗`),J(`div`,Ec,[t[194]||=J(`span`,{class:`block text-[9px] role-text-secondary-muted role-text-secondary font-bold`},`微調量`,-1),J(`span`,{class:`block truncate font-mono text-sm font-bold role-text-secondary`,title:e.formatFixedAFineDelta()},`+/-`+A(e.formatFixedAFineDelta()),9,Dc)]),J(`button`,{type:`button`,onClick:t[115]||=t=>e.adjustFixedAFineStep(1),title:`調細`,class:`rounded-lg border border-slate-200 dark:border-gray-700 bg-white dark:bg-gray-800 text-slate-600 dark:text-gray-300 py-2 text-xs font-bold transition-colors hover:bg-slate-100 dark:hover:bg-gray-700`},`細`)]),J(`div`,Oc,A(e.isTouchInput?`觸控拖曳微調`:`直接輸入 / shift + 滾輪微調`),1),J(`div`,kc,[e.isTouchInput?(K(),q(`button`,{key:1,type:`button`,onPointerdown:t[127]||=$(t=>e.startFixedAFineDrag(`delta`,t),[`prevent`]),class:`touch-none select-none w-28 mx-auto bg-white dark:bg-gray-800 border border-slate-200 dark:border-gray-700 rounded-lg p-3 text-center role-active-border-secondary active:ring-2 role-active-ring-secondary`},[t[196]||=J(`span`,{class:`text-[9px] text-slate-400 block font-bold mb-1`},`δ`,-1),J(`span`,{class:`block max-w-full truncate text-base font-mono font-bold role-text-secondary`,title:e.formatFixedFineCoeff(e.fixedCurrentDelta)},A(e.formatFixedFineCoeff(e.fixedCurrentDelta)),9,Nc)],32)):(K(),q(`label`,Ac,[t[195]||=J(`span`,{class:`text-[9px] text-slate-400 block font-bold mb-1`},`δ`,-1),J(`div`,jc,[J(`button`,{type:`button`,onPointerdown:t[116]||=$(t=>e.startFixedA1A2Repeat(`delta`,-1),[`prevent`]),onPointerup:t[117]||=(...t)=>e.stopFixedA1A2Repeat&&e.stopFixedA1A2Repeat(...t),onPointerleave:t[118]||=(...t)=>e.stopFixedA1A2Repeat&&e.stopFixedA1A2Repeat(...t),onPointercancel:t[119]||=(...t)=>e.stopFixedA1A2Repeat&&e.stopFixedA1A2Repeat(...t),class:`rounded-lg role-bg-secondary-soft role-hover-secondary-soft role-text-secondary text-sm font-bold transition-colors`},`-`,32),J(`input`,{type:`number`,value:e.formatFixedFineCoeff(e.fixedCurrentDelta),step:e.fixedAFineStep,onChange:t[120]||=t=>e.setFixedAFineDirect(`delta`,t.target.value),onKeydown:t[121]||=(...t)=>e.onlyNumberKey&&e.onlyNumberKey(...t),onWheel:t[122]||=t=>e.handleFixedAFineWheel(`delta`,t),class:`min-w-0 w-full bg-white dark:bg-gray-800 border border-slate-200 dark:border-gray-700 rounded-lg p-3 text-xs font-mono text-center role-text-secondary`},null,40,Mc),J(`button`,{type:`button`,onPointerdown:t[123]||=$(t=>e.startFixedA1A2Repeat(`delta`,1),[`prevent`]),onPointerup:t[124]||=(...t)=>e.stopFixedA1A2Repeat&&e.stopFixedA1A2Repeat(...t),onPointerleave:t[125]||=(...t)=>e.stopFixedA1A2Repeat&&e.stopFixedA1A2Repeat(...t),onPointercancel:t[126]||=(...t)=>e.stopFixedA1A2Repeat&&e.stopFixedA1A2Repeat(...t),class:`rounded-lg role-bg-secondary-soft role-hover-secondary-soft role-text-secondary text-sm font-bold transition-colors`},`+`,32)])])),e.isTouchInput?(K(),q(`button`,{key:3,type:`button`,onPointerdown:t[139]||=$(t=>e.startFixedAFineDrag(`r`,t),[`prevent`]),class:`touch-none select-none w-28 mx-auto bg-white dark:bg-gray-800 border border-slate-200 dark:border-gray-700 rounded-lg p-3 text-center active:border-slate-400 active:ring-2 active:ring-slate-400/20`},[t[198]||=J(`span`,{class:`text-[9px] text-slate-400 block font-bold mb-1`},`r`,-1),J(`span`,{class:`block max-w-full truncate text-base font-mono font-bold text-slate-700 dark:text-gray-300`,title:e.formatFixedFineCoeff(e.fixedCurrentR)},A(e.formatFixedFineCoeff(e.fixedCurrentR)),9,Lc)],32)):(K(),q(`label`,Pc,[t[197]||=J(`span`,{class:`text-[9px] text-slate-400 block font-bold mb-1`},`r`,-1),J(`div`,Fc,[J(`button`,{type:`button`,onPointerdown:t[128]||=$(t=>e.startFixedA1A2Repeat(`r`,-1),[`prevent`]),onPointerup:t[129]||=(...t)=>e.stopFixedA1A2Repeat&&e.stopFixedA1A2Repeat(...t),onPointerleave:t[130]||=(...t)=>e.stopFixedA1A2Repeat&&e.stopFixedA1A2Repeat(...t),onPointercancel:t[131]||=(...t)=>e.stopFixedA1A2Repeat&&e.stopFixedA1A2Repeat(...t),class:`rounded-lg bg-slate-200 dark:bg-gray-800 hover:bg-slate-300 dark:hover:bg-gray-700 text-slate-700 dark:text-gray-300 text-sm font-bold transition-colors`},`-`,32),J(`input`,{type:`number`,value:e.formatFixedFineCoeff(e.fixedCurrentR),step:e.fixedAFineStep,onChange:t[132]||=t=>e.setFixedAFineDirect(`r`,t.target.value),onKeydown:t[133]||=(...t)=>e.onlyNumberKey&&e.onlyNumberKey(...t),onWheel:t[134]||=t=>e.handleFixedAFineWheel(`r`,t),class:`min-w-0 w-full bg-white dark:bg-gray-800 border border-slate-200 dark:border-gray-700 rounded-lg p-3 text-xs font-mono text-center text-slate-700 dark:text-gray-300`},null,40,Ic),J(`button`,{type:`button`,onPointerdown:t[135]||=$(t=>e.startFixedA1A2Repeat(`r`,1),[`prevent`]),onPointerup:t[136]||=(...t)=>e.stopFixedA1A2Repeat&&e.stopFixedA1A2Repeat(...t),onPointerleave:t[137]||=(...t)=>e.stopFixedA1A2Repeat&&e.stopFixedA1A2Repeat(...t),onPointercancel:t[138]||=(...t)=>e.stopFixedA1A2Repeat&&e.stopFixedA1A2Repeat(...t),class:`rounded-lg bg-slate-200 dark:bg-gray-800 hover:bg-slate-300 dark:hover:bg-gray-700 text-slate-700 dark:text-gray-300 text-sm font-bold transition-colors`},`+`,32)])]))])]),J(`div`,Rc,[J(`div`,zc,[t[199]||=J(`span`,{class:`text-[9px] text-slate-400 block font-bold mb-1`},`a1 = -a0 - r + δ`,-1),J(`span`,{class:`block max-w-full truncate text-sm font-mono font-bold role-text-secondary-muted`,title:e.formatFixedFineCoeff(e.fixedCurrentA1)},A(e.formatFixedFineCoeff(e.fixedCurrentA1)),9,Bc)]),J(`div`,Vc,[t[200]||=J(`span`,{class:`text-[9px] text-slate-400 block font-bold mb-1`},`a2 = r + δ`,-1),J(`span`,{class:`block max-w-full truncate text-sm font-mono font-bold role-text-secondary-muted`,title:e.formatFixedFineCoeff(e.fixedCurrentA2)},A(e.formatFixedFineCoeff(e.fixedCurrentA2)),9,Hc)]),J(`div`,Uc,[t[201]||=J(`span`,{class:`text-[9px] text-slate-400 block font-bold mb-1`},`差值 a1-a2`,-1),J(`span`,{class:`block max-w-full truncate text-xs font-mono text-slate-600 dark:text-gray-300`,title:e.formatFixedFineCoeff(e.fixedCurrentA1A2Diff)},A(e.formatFixedFineCoeff(e.fixedCurrentA1A2Diff)),9,Wc)]),J(`div`,Gc,[t[202]||=J(`span`,{class:`text-[9px] text-slate-400 block font-bold mb-1`},`總和 a1+a2`,-1),J(`span`,{class:`block max-w-full truncate text-xs font-mono text-slate-600 dark:text-gray-300`,title:e.formatFixedFineCoeff(e.fixedCurrentA1A2Sum)},A(e.formatFixedFineCoeff(e.fixedCurrentA1A2Sum)),9,Kc)])]),J(`div`,qc,[J(`p`,Jc,[t[203]||=J(`span`,{class:`font-bold`},`運算說明:`,-1),t[204]||=J(`br`,null,null,-1),Y(` a0 = 2^`+A(e.shiftBitsA)+`,δ = (a1 + a2 + a0) / 2,r = (a2 - a1 - a0) / 2。 `,1)])])])])])]),J(`p`,Yc,`註:b 係數乘以 2^`+A(e.shiftBitsB)+`,a 係數乘以 2^`+A(e.shiftBitsA)+` 後四捨五入,可用於定點數 DSP 實作。`,1)])],2),J(`main`,{class:k([e.mobileTab===`chart`?`flex bg-white dark:bg-[#0f0f0f] !p-0`:`hidden`,`lg:flex flex-1 flex-col overflow-y-auto bg-slate-50 dark:bg-[#0f0f0f] lg:p-6 gap-0 lg:gap-6 custom-scrollbar relative transition-colors duration-300`])},[e.globalError?(K(),q(`div`,Xc,[t[210]||=J(`svg`,{class:`w-4 h-4`,fill:`none`,stroke:`currentColor`,viewBox:`0 0 24 24`},[J(`path`,{"stroke-linecap":`round`,"stroke-linejoin":`round`,"stroke-width":`2`,d:`M12 8v4m0 4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z`})],-1),Y(` `+A(e.globalError)+` `,1),J(`button`,{onClick:t[140]||=t=>e.globalError=null,class:`ml-2 role-hover-error`},`×`)])):X(``,!0),J(`div`,Zc,[t[213]||=J(`div`,{class:`hidden lg:block absolute inset-0 bg-gradient-to-br role-surface-gradient pointer-events-none`},null,-1),J(`div`,Qc,[t[212]||=J(`h3`,{class:`font-bold text-slate-800 dark:text-gray-200 tracking-wide flex items-center gap-2`},[J(`svg`,{class:`w-5 h-5 role-text-primary`,fill:`none`,stroke:`currentColor`,viewBox:`0 0 24 24`},[J(`path`,{"stroke-linecap":`round`,"stroke-linejoin":`round`,"stroke-width":`2`,d:`M4 19V5m0 14h16M7 16l3-4 3 2 4-7`})]),Y(` 頻率響應 (Frequency Response)`)],-1),e.loadingBode?(K(),q(`div`,$c,[...t[211]||=[J(`span`,{class:`w-2 h-2 rounded-full role-dot-primary animate-ping`},null,-1),Y(` 重新計算中... `,-1)]])):X(``,!0)]),t[214]||=J(`div`,{class:`overflow-x-auto bg-white dark:bg-dark`},[J(`div`,{id:`bodePlot`,class:`min-w-[580px] w-full h-[800px] z-10 relative bg-white dark:bg-dark`})],-1)]),J(`div`,el,[t[222]||=J(`div`,{class:`px-5 py-4 border-b border-slate-100 dark:border-gray-800 bg-white dark:bg-dark backdrop-blur-sm z-10 relative`},[J(`h3`,{class:`font-bold text-slate-800 dark:text-gray-200 tracking-wide flex items-center gap-2`},[J(`svg`,{class:`w-5 h-5 role-text-primary`,fill:`none`,stroke:`currentColor`,viewBox:`0 0 24 24`},[J(`path`,{"stroke-linecap":`round`,"stroke-linejoin":`round`,"stroke-width":`2`,d:`M4 12h4l2-6 4 12 2-6h4`})]),Y(` 時域訊號探討`)])],-1),J(`div`,tl,[t[221]||=J(`p`,{class:`text-base text-slate-500 dark:text-gray-400 mb-4`},`請上傳包含時域訊號的 CSV 檔案,系統會使用上述設定的差分濾波器。 `,-1),J(`div`,nl,[J(`label`,rl,[t[215]||=J(`svg`,{class:`w-5 h-5`,fill:`none`,stroke:`currentColor`,viewBox:`0 0 24 24`},[J(`path`,{"stroke-linecap":`round`,"stroke-linejoin":`round`,"stroke-width":`2`,d:`M4 16v1a3 3 0 003 3h10a3 3 0 003-3v-1m-4-8l-4-4m0 0L8 8m4-4v12`})],-1),t[216]||=Y(` 上傳輸入訊號 (CSV) `,-1),J(`input`,{type:`file`,ref:`fileInput`,accept:`.csv`,onChange:t[141]||=(...t)=>e.handleFileUpload&&e.handleFileUpload(...t),class:`hidden`},null,544)]),e.csvFile?(K(),q(`span`,il,A(e.csvFile.name),1)):X(``,!0),e.csvInfo?(K(),q(`span`,al,A(e.csvInfo.rows)+` 筆 / `+A(e.csvInfo.columns)+` 欄 `,1)):X(``,!0),e.csvParseError?(K(),q(`span`,ol,A(e.csvParseError),1)):X(``,!0),e.csvColumns.length>0?(K(),q(`div`,sl)):X(``,!0),e.csvColumns.length>0?(K(),q(`div`,cl,[t[217]||=J(`span`,{class:`text-sm text-slate-400`},`訊號欄位:`,-1),B(J(`select`,{"onUpdate:modelValue":t[142]||=t=>e.selectedColumn=t,class:`bg-white dark:bg-gray-800 border border-slate-200 dark:border-gray-700 rounded-lg p-3 text-base role-focus-primary outline-none text-slate-900 dark:text-gray-100`},[(K(!0),q(W,null,V(e.csvColumns,(e,t)=>(K(),q(`option`,{key:t,value:t},A(e),9,ll))),128))],512),[[$a,e.selectedColumn]])])):X(``,!0),e.csvFile?(K(),q(`button`,{key:5,onClick:t[143]||=(...t)=>e.processFilter&&e.processFilter(...t),class:`role-bg-primary role-hover-primary role-text-on-fill px-6 py-3 rounded-lg text-base font-semibold transition-all shadow-md role-shadow-primary disabled:opacity-50 disabled:cursor-not-allowed`,disabled:e.loadingFilter||e.csvColumns.length===0},A(e.loadingFilter?`處理中...`:`執行當前濾波器`),9,ul)):X(``,!0),e.filterDone?(K(),q(`button`,{key:6,onClick:t[144]||=(...t)=>e.downloadCsv&&e.downloadCsv(...t),class:`ml-auto bg-slate-700 hover:bg-slate-600 role-text-on-fill px-5 py-3 rounded-lg text-base font-semibold transition-all flex items-center gap-2`},[...t[218]||=[J(`svg`,{class:`w-5 h-5`,fill:`none`,stroke:`currentColor`,viewBox:`0 0 24 24`},[J(`path`,{"stroke-linecap":`round`,"stroke-linejoin":`round`,"stroke-width":`2`,d:`M4 16v1a3 3 0 003 3h10a3 3 0 003-3v-1m-4-4l-4 4m0 0l-4-4m4 4V4`})],-1),Y(` 匯出結果 `,-1)]])):X(``,!0)]),e.csvPreview.length>0?(K(),q(`div`,dl,[t[219]||=J(`h4`,{class:`text-sm font-semibold text-slate-500 dark:text-gray-400 mb-2 uppercase tracking-tight`},` 資料預覽 (前五筆):`,-1),J(`div`,fl,[J(`table`,pl,[J(`thead`,null,[J(`tr`,ml,[(K(!0),q(W,null,V(e.csvColumns,e=>(K(),q(`th`,{key:e,class:`px-4 py-3 font-semibold text-slate-700 dark:text-gray-300`},A(e),1))),128))])]),J(`tbody`,hl,[(K(!0),q(W,null,V(e.csvPreview,(e,t)=>(K(),q(`tr`,{key:t,class:`hover:bg-slate-50/50 dark:hover:bg-gray-800/30 transition-colors`},[(K(!0),q(W,null,V(e,(e,t)=>(K(),q(`td`,{key:t,class:`px-4 py-2 font-mono text-slate-600 dark:text-gray-400`},A(e),1))),128))]))),128))])])])])):X(``,!0),e.filterDone?(K(),q(`h4`,gl,`波形比較圖 `)):X(``,!0),J(`div`,_l,[B(J(`div`,vl,null,512),[[ya,e.filterDone]])]),!e.filterDone&&!e.loadingFilter&&e.csvPreview.length===0?(K(),q(`div`,yl,[...t[220]||=[J(`svg`,{class:`w-12 h-12 mb-3 opacity-50`,fill:`none`,stroke:`currentColor`,viewBox:`0 0 24 24`},[J(`path`,{"stroke-linecap":`round`,"stroke-linejoin":`round`,"stroke-width":`1.5`,d:`M9 19v-6a2 2 0 00-2-2H5a2 2 0 00-2 2v6a2 2 0 002 2h2a2 2 0 002-2zm0 0V9a2 2 0 012-2h2a2 2 0 012 2v10m-6 0a2 2 0 002 2h2a2 2 0 002-2m0 0V5a2 2 0 012-2h2a2 2 0 012 2v14a2 2 0 01-2 2h-2a2 2 0 01-2-2z`})],-1),J(`p`,null,`請上傳包含時間序列的 CSV 檔案進行測試`,-1)]])):X(``,!0)])])],2)]),t[223]||=J(`footer`,{class:`bg-white dark:bg-dark border-t border-slate-200 dark:border-gray-800 py-2 text-center z-20 transition-colors duration-300`},[J(`p`,{class:`text-xs text-slate-400 dark:text-gray-600`},`© 2026 喆富創新科技股份有限公司. All rights reserved.`)],-1)])}so(So(xo,[[`render`,bl]])).mount(`#dea-root`); \ No newline at end of file +`&&t++,s()):i+=n}if(a)throw Error(`CSV 引號未正確結束`);return s(),{rows:n,totalRows:o}},resetCsvState(){this.csvFile=null,this.csvColumns=[],this.csvPreview=[],this.csvInfo=null,this.csvParseError=null,this.selectedColumn=0,this.filterDone=!1,this.timePlotData=null},handleFileUpload(e){let t=e.target.files[0];if(this.resetCsvState(),!t)return;if(!(t.name||``).toLowerCase().endsWith(`.csv`)){this.csvParseError=`請選擇 .csv 檔案`,e.target.value=``;return}if(t.size>33554432){this.csvParseError=`CSV 檔案不可超過 32MB`,e.target.value=``;return}let n=new FileReader;n.onload=n=>{try{let e=String(n.target.result||``).replace(/^\uFEFF/,``),{rows:r,totalRows:i}=this.parseCsvText(e,6);if(i<2||r.length<2)throw Error(`CSV 需包含標題列與至少一筆資料`);let a=r[0].map((e,t)=>e.trim()||`Column ${t+1}`);if(a.length===0)throw Error(`CSV 標題列不可為空`);if(this.csvFile=t,this.csvColumns=a,this.csvPreview=r.slice(1,6).map(e=>{let t=e.slice(0,a.length);for(;t.lengthe.trim())}),this.csvInfo={rows:Math.max(i-1,0),columns:a.length,size:t.size},this.selectedColumn=0,a.length>1){let e=a[0].toLowerCase();[`time`,`t`,`sec`,`x`,`index`,`unnamed`].some(t=>e.includes(t))&&(this.selectedColumn=1)}}catch(t){this.csvParseError=t.message||`CSV 解析失敗`,this.csvColumns=[],this.csvPreview=[],this.csvInfo=null,e.target.value=``}},n.onerror=()=>{this.csvParseError=`CSV 讀取失敗`,e.target.value=``},n.readAsText(t)},async processFilter(){if(!this.csvFile)return;this.loadingFilter=!0,this.globalError=null;let e=new FormData;e.append(`file`,this.csvFile),e.append(`b`,this.b_str),e.append(`a`,this.a_str),e.append(`col_idx`,this.selectedColumn);try{let t=await fetch(`/api/filter`,{method:`POST`,body:e});if(!t.ok){let e=await t.json();throw Error(e.detail||`濾波處理失敗`)}let n=await t.json();this.timePlotData=n,this.filterDone=!0,this.$nextTick(()=>{this.drawTimePlot(n)})}catch(e){this.globalError=e.message}finally{this.loadingFilter=!1}},drawTimePlot(e){let t=this.isDarkMode,n=window.innerWidth<768,r=t?`rgba(200,206,224,0.14)`:`rgba(86,96,117,0.09)`,i=t?`rgba(200,206,224,0.24)`:`rgba(82,86,99,0.20)`,a=t?`#b4b4bd`:`#525663`,o=t?`#090a0d`:`#ffffff`,s={paper_bgcolor:o,plot_bgcolor:o,margin:n?{t:60,b:60,l:45,r:15}:{t:40,b:55,l:60,r:20},font:{color:a,family:`Google Sans, Roboto, sans-serif`},xaxis:{title:{text:`Sample Index`,font:{size:n?10:11}},gridcolor:r,zerolinecolor:i,tickfont:{color:a,size:n?9:11}},yaxis:{title:{text:`Amplitude`,font:{size:n?10:11}},gridcolor:r,zerolinecolor:i,tickfont:{color:a,size:n?9:11}},legend:{orientation:`h`,y:1.02,yanchor:`bottom`,x:1,xanchor:`right`,font:{color:a,size:n?9:10}}};Plotly.react(`timePlot`,[{x:e.index,y:e.original,name:`原始輸入訊號 (Input)`,type:`scatter`,line:{color:t?`#c8cee0`:`#566075`,width:2.4},opacity:.9},{x:e.index,y:e.filtered,name:`濾波後輸出 (Output)`,type:`scatter`,line:{color:t?`#64d2ff`:`#2d6f8f`,width:2.4},opacity:.95}],s,{responsive:!0})},async downloadCsv(){if(!this.csvFile)return;let e=new FormData;e.append(`file`,this.csvFile),e.append(`b`,this.b_str),e.append(`a`,this.a_str),e.append(`col_idx`,this.selectedColumn);try{let t=await fetch(`/api/filter/download`,{method:`POST`,body:e});if(!t.ok)throw Error(`下載失敗`);let n=await t.blob(),r=window.URL.createObjectURL(n),i=document.createElement(`a`);i.href=r,i.download=`filtered_output.csv`,document.body.appendChild(i),i.click(),window.URL.revokeObjectURL(r)}catch(e){this.globalError=e.message}}}},So=(e,t)=>{let n=e.__vccOpts||e;for(let[e,r]of t)n[e]=r;return n},Co={id:`app`,class:`flex flex-col h-screen overflow-hidden`},wo={class:`bg-white dark:bg-dark border-b border-slate-200 dark:border-gray-800 p-4 shadow-md flex justify-between items-center z-10`},To={class:`flex items-center gap-4`},Eo={key:0,class:`w-5 h-5 role-theme-icon`,fill:`currentColor`,viewBox:`0 0 20 20`},Do={key:1,class:`w-5 h-5 text-slate-700`,fill:`currentColor`,viewBox:`0 0 20 20`},Oo={class:`lg:hidden flex border-b border-slate-200 dark:border-gray-800 bg-white dark:bg-dark z-10 flex-shrink-0`},ko={key:0,class:`w-2 h-2 rounded-full role-dot-primary animate-ping`},Ao={class:`flex flex-col lg:flex-row flex-1 overflow-hidden`},jo={class:`text-sm font-semibold text-slate-500 dark:text-gray-400 uppercase tracking-wider mb-3 flex items-center justify-between`},Mo=[`value`],No={key:0,class:`space-y-3 bg-slate-100 dark:bg-gray-900 p-4 rounded-lg border border-slate-200 dark:border-gray-800 shadow-inner`},Po={key:0},Fo={class:`text-sm text-slate-500 dark:text-gray-400 flex justify-between mb-1`},Io={class:`role-text-primary`},Lo=[`max`],Ro={class:`flex gap-2`},zo=[`onClick`],Bo={key:1},Vo={class:`text-sm text-slate-500 dark:text-gray-400 flex justify-between mb-1`},Ho={class:`role-text-primary`},Uo={class:`text-sm text-slate-500 dark:text-gray-400 flex justify-between mb-1`},Wo={class:`role-text-primary`},Go={class:`flex gap-2`},Ko=[`onClick`],qo={key:2,class:`space-y-3`},Jo={key:3,class:`space-y-3`},Yo={key:4,class:`space-y-3`},Xo={key:5,class:`space-y-3`},Zo={key:6,class:`space-y-3`},Qo={class:`text-sm font-medium text-slate-500 dark:text-gray-400 mb-1 block`},$o=[`onUpdate:modelValue`],es={key:7,class:`space-y-3`},ts={class:`space-y-3`},ns={class:`text-sm text-slate-500 dark:text-gray-400 flex justify-between mb-1`},rs={class:`role-text-primary`},is={class:`text-sm text-slate-500 dark:text-gray-400 flex justify-between mb-1`},as={class:`role-text-primary`},os={class:`text-sm font-semibold text-slate-500 dark:text-gray-400 uppercase tracking-wider mb-3 flex justify-between items-center`},ss={class:`flex items-center gap-2`},cs={class:`mb-3`},ls={class:`flex flex-wrap gap-1 mb-2`},us={class:`text-[9px] role-text-primary-muted font-bold`},ds={class:`text-[10px] font-mono role-text-primary`},fs=[`open`],ps={class:`px-3 pb-3`},ms={class:`flex items-center gap-2 mb-2 mt-1`},hs=[`onClick`],gs={key:0},_s={class:`text-xs text-slate-400 dark:text-gray-500 flex justify-between mt-1`},vs={key:0,class:`role-text-warning font-bold animate-pulse`},ys=[`onUpdate:modelValue`,`min`,`max`,`step`],bs={class:`mb-3`},xs={class:`flex flex-wrap gap-1 mb-2`},Ss={class:`text-[9px] role-text-secondary-muted font-bold`},Cs={class:`text-[10px] font-mono role-text-secondary`},ws=[`open`],Ts={class:`px-3 pb-3`},Es={class:`flex items-center gap-2 mb-2 mt-1`},Ds=[`onClick`],Os={key:0},ks={class:`text-xs text-slate-400 dark:text-gray-500 flex justify-between mt-1`},As={key:0,class:`role-text-warning font-bold animate-pulse`},js=[`onUpdate:modelValue`,`min`,`max`,`step`],Ms=[`open`],Ns={class:`px-3 pb-3`},Ps={class:`mb-4`},Fs={class:`grid grid-cols-[3.25rem_1fr_3.25rem] gap-2 mb-3`},Is={class:`min-w-0 rounded-lg border role-border-tertiary-soft role-bg-tertiary-soft px-3 py-2 text-center`},Ls=[`title`],Rs={class:`text-[11px] font-semibold text-slate-400 dark:text-gray-500 mb-2`},zs={class:`grid grid-cols-2 gap-2`},Bs={key:0,class:`block`},Vs={class:`grid grid-cols-[2rem_1fr_2rem] gap-1`},Hs=[`value`,`step`],Us=[`title`],Ws={key:2,class:`block`},Gs={class:`grid grid-cols-[2rem_1fr_2rem] gap-1`},Ks=[`value`,`step`],qs=[`title`],Js={class:`grid grid-cols-2 gap-2 mb-4`},Ys={class:`min-w-0 bg-white dark:bg-gray-800 border border-slate-100 dark:border-gray-700 rounded-lg p-2 text-center shadow-sm`},Xs=[`title`],Zs={class:`min-w-0 bg-white dark:bg-gray-800 border border-slate-100 dark:border-gray-700 rounded-lg p-2 text-center shadow-sm`},Qs=[`title`],$s={class:`min-w-0 bg-white dark:bg-gray-800 border border-slate-100 dark:border-gray-700 rounded-lg p-2 text-center shadow-sm`},ec=[`title`],tc={class:`min-w-0 bg-white dark:bg-gray-800 border border-slate-100 dark:border-gray-700 rounded-lg p-2 text-center shadow-sm`},nc=[`title`],rc={class:`text-sm font-semibold text-slate-500 dark:text-gray-400 uppercase tracking-wider mb-3 flex justify-between items-center`},ic={class:`flex items-center gap-2`},ac={class:`text-xs role-bg-primary-soft role-text-primary px-2 py-1 rounded`},oc={class:`text-xs role-bg-secondary-soft role-text-secondary px-2 py-1 rounded`},sc={class:`flex items-center gap-2`},cc={class:`mb-4 grid grid-cols-1 sm:grid-cols-2 gap-3`},lc={key:0,class:`grid grid-cols-[2rem_1fr_2rem] gap-1`},uc=[`value`],dc={class:`text-lg font-mono font-bold role-text-primary`},fc={class:`text-[10px] text-slate-400 mt-1`},pc={key:0,class:`grid grid-cols-[2rem_1fr_2rem] gap-1`},mc=[`value`],hc={class:`text-lg font-mono font-bold role-text-secondary`},gc={class:`text-[10px] text-slate-400 mt-1`},_c={class:`space-y-4`},vc={class:`flex flex-wrap gap-1 mb-2`},yc={class:`text-[9px] role-text-primary font-bold`},bc={class:`flex flex-wrap gap-1 mb-2`},xc={class:`text-[9px] role-text-secondary-muted font-bold`},Sc={class:`mt-3 bg-slate-50 dark:bg-gray-900 border border-slate-200 dark:border-gray-800 rounded-lg`},Cc={class:`px-3 pb-3`},wc={class:`mb-4`},Tc={class:`grid grid-cols-[3.25rem_1fr_3.25rem] gap-2 mb-3`},Ec={class:`min-w-0 rounded-lg border role-border-secondary-soft role-bg-secondary-soft px-3 py-2 text-center`},Dc=[`title`],Oc={class:`text-[11px] font-semibold text-slate-400 dark:text-gray-500 mb-2`},kc={class:`grid grid-cols-2 gap-2`},Ac={key:0,class:`block`},jc={class:`grid grid-cols-[2rem_1fr_2rem] gap-1`},Mc=[`value`,`step`],Nc=[`title`],Pc={key:2,class:`block`},Fc={class:`grid grid-cols-[2rem_1fr_2rem] gap-1`},Ic=[`value`,`step`],Lc=[`title`],Rc={class:`grid grid-cols-2 gap-2 mb-4`},zc={class:`min-w-0 bg-white dark:bg-gray-800 border border-slate-100 dark:border-gray-700 rounded-lg p-2 text-center shadow-sm`},Bc=[`title`],Vc={class:`min-w-0 bg-white dark:bg-gray-800 border border-slate-100 dark:border-gray-700 rounded-lg p-2 text-center shadow-sm`},Hc=[`title`],Uc={class:`min-w-0 bg-white dark:bg-gray-800 border border-slate-100 dark:border-gray-700 rounded-lg p-2 text-center shadow-sm`},Wc=[`title`],Gc={class:`min-w-0 bg-white dark:bg-gray-800 border border-slate-100 dark:border-gray-700 rounded-lg p-2 text-center shadow-sm`},Kc=[`title`],qc={class:`role-bg-warning-soft border role-border-warning-soft rounded-lg p-3`},Jc={class:`text-[10px] role-text-warning leading-relaxed`},Yc={class:`text-[10px] text-slate-400 dark:text-gray-500 mt-3 italic`},Xc={key:0,class:`absolute top-4 right-6 role-bg-error-soft border role-border-error role-text-error role-text-on-fill px-4 py-3 rounded-lg shadow-lg text-base z-50 flex items-center gap-2`},Zc={class:`bg-white dark:bg-dark lg:rounded-xl border-b lg:border border-slate-100 lg:border-slate-200 dark:border-gray-800 lg:dark:border-gray-800 lg:shadow-md p-0 lg:p-1 flex-shrink-0 relative transition-colors duration-300`},Qc={class:`px-5 py-4 border-b border-slate-100 dark:border-gray-800 flex justify-between items-center bg-white dark:bg-dark backdrop-blur-sm z-10 relative`},$c={key:0,class:`text-sm role-text-primary role-bg-primary-soft px-3 py-1.5 rounded border role-border-primary-soft flex items-center gap-2`},el={class:`bg-white dark:bg-white lg:dark:bg-dark lg:rounded-xl border-b lg:border border-slate-100 lg:border-slate-200 dark:border-gray-100 lg:dark:border-gray-800 lg:shadow-md p-0 lg:p-1 flex-shrink-0 relative transition-colors duration-300`},tl={class:`p-6 z-10 relative bg-white dark:bg-dark transition-colors duration-300`},nl={class:`flex items-center flex-wrap gap-4 mb-6 p-4 bg-slate-50 dark:bg-gray-900/50 rounded-lg border border-slate-100 dark:border-gray-800`},rl={class:`cursor-pointer role-bg-primary role-hover-primary role-text-on-fill px-5 py-3 rounded-lg text-base font-semibold transition-all shadow-md role-shadow-primary flex items-center gap-2`},il={key:0,class:`text-base role-text-primary font-mono`},al={key:1,class:`text-sm text-slate-500 dark:text-gray-400 font-mono`},ol={key:2,class:`text-sm role-text-error font-semibold`},sl={key:3,class:`h-8 border-l border-slate-200 dark:border-gray-700 mx-2`},cl={key:4,class:`flex items-center gap-2`},ll=[`value`],ul=[`disabled`],dl={key:0,class:`mb-6`},fl={class:`overflow-x-auto rounded-xl border border-slate-100 dark:border-gray-800 shadow-inner`},pl={class:`w-full text-sm text-left`},ml={class:`bg-slate-50 dark:bg-gray-800/50`},hl={class:`divide-y divide-slate-100 dark:divide-gray-800`},gl={key:1,class:`text-base font-bold text-slate-800 dark:text-gray-200 mb-3`},_l={class:`overflow-x-auto bg-white dark:bg-dark`},vl={id:`timePlot`,class:`min-w-[580px] w-full h-[400px] bg-white dark:bg-dark`},yl={key:2,class:`h-[300px] flex flex-col items-center justify-center text-slate-400 dark:text-gray-500 border-2 border-dashed border-slate-200 dark:border-gray-800 rounded-xl bg-slate-50/50 dark:bg-gray-900/30`};function bl(e,t,n,r,i,a){return K(),q(`div`,Co,[J(`header`,wo,[t[147]||=J(`div`,{class:`flex items-center gap-3`},[J(`img`,{src:`/ui/logo.png`,alt:`Logo`,class:`h-10 w-10 object-contain rounded-lg shadow-sm`}),J(`h1`,{class:`text-xl font-bold text-slate-900 dark:text-gray-100`},` 差分方程式分析 (Difference Equation Analyzer)`)],-1),J(`div`,To,[J(`button`,{onClick:t[0]||=(...t)=>e.toggleDarkMode&&e.toggleDarkMode(...t),class:`p-2 rounded-lg bg-slate-100 dark:bg-gray-800 hover:bg-slate-200 dark:hover:bg-gray-700 transition-colors shadow-sm`},[e.isDarkMode?(K(),q(`svg`,Eo,[...t[145]||=[J(`path`,{d:`M10 12a2 2 0 100-4 2 2 0 000 4z`},null,-1),J(`path`,{"fill-rule":`evenodd`,d:`M10 18a8 8 0 100-16 8 8 0 000 16zm1-13a1 1 0 10-2 0 1 1 0 002 0zM2 10a1 1 0 011-1h1a1 1 0 110 2H3a1 1 0 01-1-1zm14 0a1 1 0 011-1h1a1 1 0 110 2h-1a1 1 0 01-1-1zM5.05 5.05a1 1 0 011.414 0l.707.707a1 1 0 11-1.414 1.414l-.707-.707a1 1 0 010-1.414zm9.9 9.9a1 1 0 011.414 0l.707.707a1 1 0 11-1.414 1.414l-.707-.707a1 1 0 010-1.414zM5.05 14.95a1 1 0 010-1.414l.707-.707a1 1 0 011.414 1.414l-.707.707a1 1 0 01-1.414 0zm9.9-9.9a1 1 0 010-1.414l.707-.707a1 1 0 011.414 1.414l-.707.707a1 1 0 01-1.414 0z`,"clip-rule":`evenodd`},null,-1)]])):(K(),q(`svg`,Do,[...t[146]||=[J(`path`,{d:`M17.293 13.293A8 8 0 016.707 2.707a8.001 8.001 0 1010.586 10.586z`},null,-1)]]))])])]),J(`div`,Oo,[J(`button`,{onClick:t[1]||=t=>e.mobileTab=`settings`,class:k([e.mobileTab===`settings`?`border-b-2 role-border-primary role-text-primary role-bg-primary-soft`:`text-slate-500 dark:text-gray-400 hover:text-slate-700 dark:hover:text-gray-200`,`flex-1 flex items-center justify-center gap-2 py-3 text-sm font-semibold transition-colors`])},[...t[148]||=[J(`svg`,{class:`w-4 h-4`,fill:`none`,stroke:`currentColor`,viewBox:`0 0 24 24`},[J(`path`,{"stroke-linecap":`round`,"stroke-linejoin":`round`,"stroke-width":`2`,d:`M9.594 3.94c.09-.542.56-.94 1.11-.94h2.592c.55 0 1.02.398 1.11.94l.213 1.281c.063.374.313.686.655.85.11.052.218.108.324.168.325.183.72.177 1.039-.019l1.09-.67a1.125 1.125 0 011.45.12l1.833 1.833c.39.39.439.999.12 1.45l-.67 1.09c-.196.319-.202.714-.019 1.039.06.106.116.214.168.324.164.342.476.592.85.655l1.281.213c.542.09.94.56.94 1.11v2.592c0 .55-.398 1.02-.94 1.11l-1.281.213c-.374.063-.686.313-.85.655a6.47 6.47 0 01-.168.324c-.183.325-.177.72.019 1.039l.67 1.09c.319.451.27 1.06-.12 1.45l-1.833 1.833a1.125 1.125 0 01-1.45.12l-1.09-.67c-.319-.196-.714-.202-1.039-.019a6.47 6.47 0 01-.324.168c-.342.164-.592.476-.655.85l-.213 1.281c-.09.542-.56.94-1.11.94h-2.592c-.55 0-1.02-.398-1.11-.94l-.213-1.281c-.063-.374-.313-.686-.655-.85a6.47 6.47 0 01-.324-.168c-.325-.183-.72-.177-1.039.019l-1.09.67a1.125 1.125 0 01-1.45-.12L2.99 18.157a1.125 1.125 0 01-.12-1.45l.67-1.09c.196-.319.202-.714.019-1.039a6.47 6.47 0 01-.168-.324c-.164-.342-.476-.592-.85-.655l-1.281-.213A1.125 1.125 0 01.32 12.276V9.684c0-.55.398-1.02.94-1.11l1.281-.213c.374-.063.686-.313.85-.655.052-.11.108-.218.168-.324.183-.325.177-.72-.019-1.039l-.67-1.09a1.125 1.125 0 01.12-1.45L4.823 1.97a1.125 1.125 0 011.45-.12l1.09.67c.319.196.714.202 1.039.019.106-.06.214-.116.324-.168.342-.164.592-.476.655-.85l.213-1.281z`,transform:`translate(0.32 0.5) scale(0.97)`}),J(`path`,{"stroke-linecap":`round`,"stroke-linejoin":`round`,"stroke-width":`2`,d:`M15 12a3 3 0 11-6 0 3 3 0 016 0z`})],-1),Y(` 設定 `,-1)]],2),J(`button`,{onClick:t[2]||=t=>e.mobileTab=`chart`,class:k([e.mobileTab===`chart`?`border-b-2 role-border-primary role-text-primary role-bg-primary-soft`:`text-slate-500 dark:text-gray-400 hover:text-slate-700 dark:hover:text-gray-200`,`flex-1 flex items-center justify-center gap-2 py-3 text-sm font-semibold transition-colors`])},[t[149]||=J(`svg`,{class:`w-4 h-4`,fill:`none`,stroke:`currentColor`,viewBox:`0 0 24 24`},[J(`path`,{"stroke-linecap":`round`,"stroke-linejoin":`round`,"stroke-width":`2`,d:`M9 19v-6a2 2 0 00-2-2H5a2 2 0 00-2 2v6a2 2 0 002 2h2a2 2 0 002-2zm0 0V9a2 2 0 012-2h2a2 2 0 012 2v10m-6 0a2 2 0 002 2h2a2 2 0 002-2m0 0V5a2 2 0 012-2h2a2 2 0 012 2v14a2 2 0 01-2 2h-2a2 2 0 01-2-2z`})],-1),t[150]||=Y(` 圖表 `,-1),e.loadingBode?(K(),q(`span`,ko)):X(``,!0)],2)]),J(`div`,Ao,[J(`aside`,{class:k([e.mobileTab===`settings`?`flex`:`hidden`,`lg:flex flex-col w-full lg:w-96 h-full bg-white dark:bg-dark border-b lg:border-b-0 lg:border-r border-slate-200 dark:border-gray-800 overflow-y-auto p-5 gap-5 custom-scrollbar transition-colors duration-300`])},[J(`section`,null,[J(`h2`,jo,[t[151]||=J(`div`,{class:`flex items-center gap-2`},[J(`svg`,{class:`w-5 h-5`,fill:`none`,stroke:`currentColor`,viewBox:`0 0 24 24`},[J(`path`,{"stroke-linecap":`round`,"stroke-linejoin":`round`,"stroke-width":`2`,d:`M10.325 4.317c.426-1.756 2.924-1.756 3.35 0a1.724 1.724 0 002.573 1.066c1.543-.94 3.31.826 2.37 2.37a1.724 1.724 0 001.065 2.572c1.756.426 1.756 2.924 0 3.35a1.724 1.724 0 00-1.066 2.573c.94 1.543-.826 3.31-2.37 2.37a1.724 1.724 0 00-2.572 1.065c-.426 1.756-2.924 1.756-3.35 0a1.724 1.724 0 00-2.573-1.066c-1.543.94-3.31-.826-2.37-2.37a1.724 1.724 0 00-1.065-2.572c-1.756-.426-1.756-2.924 0-3.35a1.724 1.724 0 001.066-2.573c-.94-1.543.826-3.31 2.37-2.37.996.608 2.296.07 2.572-1.065z`}),J(`path`,{"stroke-linecap":`round`,"stroke-linejoin":`round`,"stroke-width":`2`,d:`M15 12a3 3 0 11-6 0 3 3 0 016 0z`})]),Y(` 濾波器設計 `)],-1),J(`button`,{onClick:t[3]||=(...t)=>e.resetFilterParams&&e.resetFilterParams(...t),class:`text-[10px] font-bold role-bg-secondary-soft role-border-secondary-soft role-text-secondary role-hover-secondary-soft border px-2 py-1 rounded transition-colors uppercase`},`重設設計`)]),B(J(`select`,{"onUpdate:modelValue":t[4]||=t=>e.filterType=t,onChange:t[5]||=(...t)=>e.onFilterTypeChange&&e.onFilterTypeChange(...t),class:`w-full bg-slate-50 dark:bg-gray-800 border border-slate-200 dark:border-gray-700 rounded-lg p-3 text-base role-focus-primary focus:ring-1 role-focus-ring-primary outline-none transition-all mb-3 text-slate-900 dark:text-gray-100 truncate`},[(K(!0),q(W,null,V(e.filterOptions,e=>(K(),q(`option`,{key:e,value:e},A(e),9,Mo))),128))],544),[[$a,e.filterType]]),e.filterType===`(無) 手動自訂`?X(``,!0):(K(),q(`div`,No,[[`Lowpass (低通)`,`Highpass (高通)`].includes(e.filterType)?(K(),q(`div`,Po,[J(`label`,Fo,[t[152]||=J(`span`,null,`截止頻率 f_c (Hz)`,-1),J(`span`,Io,A(e.formatK(e.params.fc)),1)]),B(J(`input`,{type:`range`,"onUpdate:modelValue":t[6]||=t=>e.params.fc=t,onInput:t[7]||=(...t)=>e.debouncedApply&&e.debouncedApply(...t),min:1,max:e.fs/2,class:`w-full role-range-primary mb-2`},null,40,Lo),[[Q,e.params.fc,void 0,{number:!0}]]),B(J(`input`,{type:`number`,"onUpdate:modelValue":t[8]||=t=>e.params.fc=t,onChange:t[9]||=(...t)=>e.applyFilterDesign&&e.applyFilterDesign(...t),class:`w-full bg-white dark:bg-gray-800 border border-slate-200 dark:border-gray-700 rounded p-3 text-base role-focus-primary outline-none text-slate-900 dark:text-gray-100`},null,544),[[Q,e.params.fc,void 0,{number:!0}]]),t[153]||=J(`label`,{class:`text-sm text-slate-500 dark:text-gray-400 mt-3 mb-2 block`},`階數 Order`,-1),J(`div`,Ro,[(K(),q(W,null,V([1,2,3],t=>J(`button`,{key:t,onClick:n=>{e.params.order=t,e.applyFilterDesign()},class:k([e.params.order===t?`role-bg-primary role-text-on-fill role-border-primary`:`bg-slate-200 dark:bg-gray-800 text-slate-600 dark:text-gray-400 border-slate-300 dark:border-gray-700`,`flex-1 rounded py-2.5 text-base font-medium border transition-colors`])},A(t),11,zo)),64))])])):X(``,!0),e.filterType===`Bandpass (帶通)`?(K(),q(`div`,Bo,[J(`label`,Vo,[t[154]||=J(`span`,null,`下截止頻率 f_low (Hz)`,-1),J(`span`,Ho,A(e.formatK(e.params.bp_f_low)),1)]),B(J(`input`,{type:`number`,"onUpdate:modelValue":t[10]||=t=>e.params.bp_f_low=t,onChange:t[11]||=(...t)=>e.applyFilterDesign&&e.applyFilterDesign(...t),class:`w-full bg-white dark:bg-gray-800 border border-slate-200 dark:border-gray-700 rounded p-3 text-base mb-2 text-slate-900 dark:text-gray-100`},null,544),[[Q,e.params.bp_f_low,void 0,{number:!0}]]),J(`label`,Uo,[t[155]||=J(`span`,null,`上截止頻率 f_high (Hz)`,-1),J(`span`,Wo,A(e.formatK(e.params.bp_f_high)),1)]),B(J(`input`,{type:`number`,"onUpdate:modelValue":t[12]||=t=>e.params.bp_f_high=t,onChange:t[13]||=(...t)=>e.applyFilterDesign&&e.applyFilterDesign(...t),class:`w-full bg-white dark:bg-gray-800 border border-slate-200 dark:border-gray-700 rounded p-3 text-base mb-2 text-slate-900 dark:text-gray-100`},null,544),[[Q,e.params.bp_f_high,void 0,{number:!0}]]),t[156]||=J(`label`,{class:`text-sm text-slate-500 dark:text-gray-400 mt-2 mb-2 block`},`階數 Order`,-1),J(`div`,Go,[(K(),q(W,null,V([1,2,3],t=>J(`button`,{key:t,onClick:n=>{e.params.bp_order=t,e.applyFilterDesign()},class:k([e.params.bp_order===t?`role-bg-primary role-text-on-fill role-border-primary`:`bg-slate-200 dark:bg-gray-800 text-slate-600 dark:text-gray-400 border-slate-300 dark:border-gray-700`,`flex-1 rounded py-1.5 text-sm border transition-colors`])},A(t),11,Ko)),64))])])):X(``,!0),e.filterType===`Notch (陷波器)`?(K(),q(`div`,qo,[J(`div`,null,[t[157]||=J(`label`,{class:`text-sm text-slate-500 dark:text-gray-400 mb-2 block`},`中心頻率 f_0 (Hz)`,-1),B(J(`input`,{type:`number`,"onUpdate:modelValue":t[14]||=t=>e.params.notch_f0=t,onChange:t[15]||=(...t)=>e.applyFilterDesign&&e.applyFilterDesign(...t),class:`w-full bg-white dark:bg-gray-800 border border-slate-200 dark:border-gray-700 rounded p-3 text-base text-slate-900 dark:text-gray-100`},null,544),[[Q,e.params.notch_f0,void 0,{number:!0}]])]),J(`div`,null,[t[158]||=J(`label`,{class:`text-sm text-slate-500 dark:text-gray-400 mb-2 block`},`品質因數 Q`,-1),B(J(`input`,{type:`number`,"onUpdate:modelValue":t[16]||=t=>e.params.notch_q=t,onChange:t[17]||=(...t)=>e.applyFilterDesign&&e.applyFilterDesign(...t),step:`0.1`,class:`w-full bg-white dark:bg-gray-800 border border-slate-200 dark:border-gray-700 rounded p-3 text-base text-slate-900 dark:text-gray-100`},null,544),[[Q,e.params.notch_q,void 0,{number:!0}]])])])):X(``,!0),e.filterType===`1P1Z (一極一零)`?(K(),q(`div`,Jo,[J(`div`,null,[t[159]||=J(`label`,{class:`text-sm text-slate-500 dark:text-gray-400 mb-2 block`},`零點頻率 Freq_z (Hz)`,-1),B(J(`input`,{type:`number`,"onUpdate:modelValue":t[18]||=t=>e.params.opoz_fz=t,onChange:t[19]||=(...t)=>e.applyFilterDesign&&e.applyFilterDesign(...t),class:`w-full bg-white dark:bg-gray-800 border border-slate-200 dark:border-gray-700 rounded p-3 text-base text-slate-900 dark:text-gray-100`},null,544),[[Q,e.params.opoz_fz,void 0,{number:!0}]])]),J(`div`,null,[t[160]||=J(`label`,{class:`text-sm text-slate-500 dark:text-gray-400 mb-2 block`},`極點頻率 Freq_p (Hz)`,-1),B(J(`input`,{type:`number`,"onUpdate:modelValue":t[20]||=t=>e.params.opoz_fp=t,onChange:t[21]||=(...t)=>e.applyFilterDesign&&e.applyFilterDesign(...t),class:`w-full bg-white dark:bg-gray-800 border border-slate-200 dark:border-gray-700 rounded p-3 text-base text-slate-900 dark:text-gray-100`},null,544),[[Q,e.params.opoz_fp,void 0,{number:!0}]])])])):X(``,!0),e.filterType===`2P1Z (二極一零)`?(K(),q(`div`,Yo,[J(`div`,null,[t[161]||=J(`label`,{class:`text-sm text-slate-500 dark:text-gray-400 mb-2 block`},`零點頻率 Freq_z (Hz)`,-1),B(J(`input`,{type:`number`,"onUpdate:modelValue":t[22]||=t=>e.params.tp1z_fz=t,onChange:t[23]||=(...t)=>e.applyFilterDesign&&e.applyFilterDesign(...t),class:`w-full bg-white dark:bg-gray-800 border border-slate-200 dark:border-gray-700 rounded p-3 text-base text-slate-900 dark:text-gray-100`},null,544),[[Q,e.params.tp1z_fz,void 0,{number:!0}]])]),J(`div`,null,[t[162]||=J(`label`,{class:`text-sm text-slate-500 dark:text-gray-400 mb-2 block`},`極點頻率 1 Freq_p1 (Hz)`,-1),B(J(`input`,{type:`number`,"onUpdate:modelValue":t[24]||=t=>e.params.tp1z_fp1=t,onChange:t[25]||=(...t)=>e.applyFilterDesign&&e.applyFilterDesign(...t),class:`w-full bg-white dark:bg-gray-800 border border-slate-200 dark:border-gray-700 rounded p-3 text-base text-slate-900 dark:text-gray-100`},null,544),[[Q,e.params.tp1z_fp1,void 0,{number:!0}]])]),J(`div`,null,[t[163]||=J(`label`,{class:`text-sm text-slate-500 dark:text-gray-400 mb-2 block`},`極點頻率 2 Freq_p2 (Hz)`,-1),B(J(`input`,{type:`number`,"onUpdate:modelValue":t[26]||=t=>e.params.tp1z_fp2=t,onChange:t[27]||=(...t)=>e.applyFilterDesign&&e.applyFilterDesign(...t),class:`w-full bg-white dark:bg-gray-800 border border-slate-200 dark:border-gray-700 rounded p-3 text-base text-slate-900 dark:text-gray-100`},null,544),[[Q,e.params.tp1z_fp2,void 0,{number:!0}]])])])):X(``,!0),e.filterType===`2P2Z (二極二零)`?(K(),q(`div`,Xo,[J(`div`,null,[t[164]||=J(`label`,{class:`text-sm text-slate-500 dark:text-gray-400 mb-2 block`},`零點頻率 1 Freq_z1 (Hz)`,-1),B(J(`input`,{type:`number`,"onUpdate:modelValue":t[28]||=t=>e.params.tptz_fz1=t,onChange:t[29]||=(...t)=>e.applyFilterDesign&&e.applyFilterDesign(...t),class:`w-full bg-white dark:bg-gray-800 border border-slate-200 dark:border-gray-700 rounded p-3 text-base text-slate-900 dark:text-gray-100`},null,544),[[Q,e.params.tptz_fz1,void 0,{number:!0}]])]),J(`div`,null,[t[165]||=J(`label`,{class:`text-sm text-slate-500 dark:text-gray-400 mb-2 block`},`零點頻率 2 Freq_z2 (Hz)`,-1),B(J(`input`,{type:`number`,"onUpdate:modelValue":t[30]||=t=>e.params.tptz_fz2=t,onChange:t[31]||=(...t)=>e.applyFilterDesign&&e.applyFilterDesign(...t),class:`w-full bg-white dark:bg-gray-800 border border-slate-200 dark:border-gray-700 rounded p-3 text-base text-slate-900 dark:text-gray-100`},null,544),[[Q,e.params.tptz_fz2,void 0,{number:!0}]])]),J(`div`,null,[t[166]||=J(`label`,{class:`text-sm text-slate-500 dark:text-gray-400 mb-2 block`},`極點頻率 1 Freq_p1 (Hz)`,-1),B(J(`input`,{type:`number`,"onUpdate:modelValue":t[32]||=t=>e.params.tptz_fp1=t,onChange:t[33]||=(...t)=>e.applyFilterDesign&&e.applyFilterDesign(...t),class:`w-full bg-white dark:bg-gray-800 border border-slate-200 dark:border-gray-700 rounded p-3 text-base text-slate-900 dark:text-gray-100`},null,544),[[Q,e.params.tptz_fp1,void 0,{number:!0}]])]),J(`div`,null,[t[167]||=J(`label`,{class:`text-sm text-slate-500 dark:text-gray-400 mb-2 block`},`極點頻率 2 Freq_p2 (Hz)`,-1),B(J(`input`,{type:`number`,"onUpdate:modelValue":t[34]||=t=>e.params.tptz_fp2=t,onChange:t[35]||=(...t)=>e.applyFilterDesign&&e.applyFilterDesign(...t),class:`w-full bg-white dark:bg-gray-800 border border-slate-200 dark:border-gray-700 rounded p-3 text-base text-slate-900 dark:text-gray-100`},null,544),[[Q,e.params.tptz_fp2,void 0,{number:!0}]])])])):X(``,!0),e.filterType===`PID 控制器`?(K(),q(`div`,Zo,[(K(),q(W,null,V([{key:`kp`,label:`比例增益 Kp`},{key:`ki`,label:`積分增益 Ki`},{key:`kd`,label:`微分增益 Kd`}],n=>J(`div`,{key:n.key},[J(`label`,Qo,A(n.label),1),B(J(`input`,{type:`number`,"onUpdate:modelValue":t=>e.params[n.key]=t,onChange:t[36]||=(...t)=>e.applyFilterDesign&&e.applyFilterDesign(...t),step:`0.0001`,class:`w-full bg-white dark:bg-gray-800 border border-slate-200 dark:border-gray-700 rounded p-3 text-base role-focus-primary outline-none text-slate-900 dark:text-gray-100`},null,40,$o),[[Q,e.params[n.key],void 0,{number:!0}]])])),64))])):X(``,!0),e.filterType===`SOGI-Alpha (帶通)`||e.filterType===`SOGI-Beta (低通)`?(K(),q(`div`,es,[J(`div`,null,[t[168]||=J(`label`,{class:`text-xs text-slate-500 dark:text-gray-400 mb-1 block`},`中心頻率 f_0 (Hz)`,-1),B(J(`input`,{type:`number`,"onUpdate:modelValue":t[37]||=t=>e.params.sogi_f0=t,onChange:t[38]||=(...t)=>e.applyFilterDesign&&e.applyFilterDesign(...t),class:`w-full bg-white dark:bg-gray-800 border border-slate-200 dark:border-gray-700 rounded p-2 text-sm text-slate-900 dark:text-gray-100`},null,544),[[Q,e.params.sogi_f0,void 0,{number:!0}]])]),J(`div`,null,[t[169]||=J(`label`,{class:`text-xs text-slate-500 dark:text-gray-400 mb-1 block`},`阻尼因數 k`,-1),B(J(`input`,{type:`number`,"onUpdate:modelValue":t[39]||=t=>e.params.sogi_k=t,onChange:t[40]||=(...t)=>e.applyFilterDesign&&e.applyFilterDesign(...t),step:`0.001`,class:`w-full bg-white dark:bg-gray-800 border border-slate-200 dark:border-gray-700 rounded p-2 text-sm text-slate-900 dark:text-gray-100`},null,544),[[Q,e.params.sogi_k,void 0,{number:!0}]])])])):X(``,!0),t[170]||=J(`div`,{class:`role-bg-primary-soft border role-border-primary-soft rounded-lg p-3 text-sm role-text-primary mt-2`},` 調整上方參數會自動覆寫 a, b 係數。你也可以隨時手動修改下方係數進行微調。 `,-1)]))]),t[207]||=J(`hr`,{class:`border-slate-200 dark:border-gray-800`},null,-1),J(`section`,null,[t[173]||=J(`h2`,{class:`text-sm font-semibold text-slate-500 dark:text-gray-400 uppercase tracking-wider mb-3 flex items-center gap-2`},[J(`svg`,{class:`w-5 h-5`,fill:`none`,stroke:`currentColor`,viewBox:`0 0 24 24`},[J(`path`,{"stroke-linecap":`round`,"stroke-linejoin":`round`,"stroke-width":`2`,d:`M10.325 4.317c.426-1.756 2.924-1.756 3.35 0a1.724 1.724 0 002.573 1.066c1.543-.94 3.31.826 2.37 2.37a1.724 1.724 0 001.065 2.572c1.756.426 1.756 2.924 0 3.35a1.724 1.724 0 00-1.066 2.573c.94 1.543-.826 3.31-2.37 2.37a1.724 1.724 0 00-2.572 1.065c-.426 1.756-2.924 1.756-3.35 0a1.724 1.724 0 00-2.573-1.066c-1.543.94-3.31-.826-2.37-2.37a1.724 1.724 0 00-1.065-2.572c-1.756-.426-1.756-2.924 0-3.35a1.724 1.724 0 001.066-2.573c-.94-1.543.826-3.31 2.37-2.37.996.608 2.296.07 2.572-1.065z`}),J(`path`,{"stroke-linecap":`round`,"stroke-linejoin":`round`,"stroke-width":`2`,d:`M15 12a3 3 0 11-6 0 3 3 0 016 0z`})]),Y(` 系統參數`)],-1),J(`div`,ts,[J(`div`,null,[J(`label`,ns,[t[171]||=J(`span`,null,`取樣頻率 fs (Hz)`,-1),J(`span`,rs,A(e.formatK(e.fs)),1)]),B(J(`input`,{type:`number`,"onUpdate:modelValue":t[41]||=t=>e.fs=t,onInput:t[42]||=(...t)=>e.debouncedApply&&e.debouncedApply(...t),onKeydown:t[43]||=(...t)=>e.onlyNumberKey&&e.onlyNumberKey(...t),class:`w-full bg-white dark:bg-gray-800 border border-slate-200 dark:border-gray-700 rounded-lg p-3 text-base role-focus-primary outline-none transition-all text-slate-900 dark:text-gray-100`},null,544),[[Q,e.fs,void 0,{number:!0}]])]),J(`div`,null,[J(`label`,is,[t[172]||=J(`span`,null,`系統增益 K (System Gain)`,-1),J(`span`,as,A(e.systemGain)+`x`,1)]),B(J(`input`,{type:`number`,"onUpdate:modelValue":t[44]||=t=>e.systemGain=t,onInput:t[45]||=(...t)=>e.onGainChange&&e.onGainChange(...t),step:`0.1`,onKeydown:t[46]||=(...t)=>e.onlyNumberKey&&e.onlyNumberKey(...t),class:`w-full bg-white dark:bg-gray-800 border border-slate-200 dark:border-gray-700 rounded-lg p-3 text-base role-focus-primary outline-none transition-all text-slate-900 dark:text-gray-100`},null,544),[[Q,e.systemGain,void 0,{number:!0}]])])])]),t[208]||=J(`hr`,{class:`border-slate-200 dark:border-gray-800`},null,-1),J(`section`,null,[J(`h2`,os,[t[174]||=J(`span`,{class:`flex items-center gap-2`},[J(`svg`,{class:`w-5 h-5`,fill:`none`,stroke:`currentColor`,viewBox:`0 0 24 24`},[J(`path`,{"stroke-linecap":`round`,"stroke-linejoin":`round`,"stroke-width":`2`,d:`M4 7h16M4 12h16M4 17h16M8 7v10M16 7v10`})]),Y(` 濾波器係數設定`)],-1),J(`div`,ss,[e.isManualDirty?(K(),q(`button`,{key:0,onClick:t[47]||=(...t)=>e.clearManualAdjustments&&e.clearManualAdjustments(...t),class:`text-[10px] font-bold role-bg-secondary-soft role-border-secondary-soft role-text-secondary role-hover-secondary-soft border px-2 py-1 rounded transition-colors uppercase mr-1`},`重設`)):X(``,!0)])]),J(`div`,cs,[t[175]||=J(`label`,{class:`text-sm text-slate-500 dark:text-gray-400 mb-1 block`},`前饋分子係數 b (b0 ~ b6)`,-1),J(`div`,ls,[(K(!0),q(W,null,V(e.floatingCoeffs.b,e=>(K(),q(`div`,{key:e.label,class:`role-bg-primary-soft px-1.5 py-0.5 rounded border role-border-primary-soft flex gap-1 items-center`},[J(`span`,us,A(e.label)+`:`,1),J(`span`,ds,A(e.val),1)]))),128))]),B(J(`textarea`,{"onUpdate:modelValue":t[48]||=t=>e.b_str=t,onInput:t[49]||=t=>e.debouncedUpdateFromText(`b`),onKeydown:t[50]||=(...t)=>e.onlyNumberKey&&e.onlyNumberKey(...t),rows:`2`,class:`w-full bg-slate-50 dark:bg-gray-900 border border-slate-200 dark:border-gray-700 rounded-lg p-3 text-sm role-focus-primary outline-none font-mono resize-none leading-relaxed role-text-primary`},null,544),[[Q,e.b_str]])]),J(`details`,{open:e.activeCoeffAdjustment===`bScale`,class:`mb-3 bg-slate-50 dark:bg-gray-900 border border-slate-200 dark:border-gray-800 rounded-lg`},[J(`summary`,{onClick:t[51]||=$(t=>e.toggleCoeffAdjustment(`bScale`),[`prevent`]),class:`text-sm text-slate-500 dark:text-gray-400 px-3 py-3 cursor-pointer hover:text-slate-600 dark:hover:text-gray-300`},` b 係數倍率微調`),J(`div`,ps,[J(`div`,ms,[t[176]||=J(`span`,{class:`text-xs text-slate-400 dark:text-gray-500`},`靈敏度:`,-1),(K(),q(W,null,V([`1%`,`2x`,`10x`],t=>J(`button`,{key:t,onClick:n=>e.sense_b=t,class:k([e.sense_b===t?`role-bg-primary role-text-on-fill`:`bg-slate-200 dark:bg-gray-800 text-slate-500 dark:text-gray-400`,`btn-small px-3 py-1.5 rounded text-xs font-medium border border-slate-300 dark:border-gray-700`])},A(t),11,hs)),64))]),(K(),q(W,null,V(7,n=>(K(),q(W,{key:`bs`+n},[e.baseB[n-1]===0?X(``,!0):(K(),q(`div`,gs,[J(`label`,_s,[J(`span`,null,`b`+A(n-1)+` (基準: `+A((e.baseB[n-1]*(e.systemGain||1)).toPrecision(6))+`)`,1),e.outOfRangeB[n-1]?(K(),q(`span`,vs,`超出滑桿範圍`)):X(``,!0)]),B(J(`input`,{type:`range`,"onUpdate:modelValue":t=>e.bSliders[n-1]=t,onInput:t[52]||=(...t)=>e.updateFromControls&&e.updateFromControls(...t),min:-e.maxLogB,max:e.maxLogB,step:e.maxLogB/100,class:`w-full role-range-primary`},null,40,ys),[[Q,e.bSliders[n-1],void 0,{number:!0}]])]))],64))),64))])],8,fs),J(`div`,bs,[t[177]||=J(`label`,{class:`text-sm text-slate-500 dark:text-gray-400 mb-1 block`},`回饋分母係數 a (a0=1, a1 ~ a6)`,-1),J(`div`,xs,[(K(!0),q(W,null,V(e.floatingCoeffs.a,e=>(K(),q(`div`,{key:e.label,class:`role-bg-secondary-soft px-1.5 py-0.5 rounded border role-border-secondary-soft flex gap-1 items-center`},[J(`span`,Ss,A(e.label)+`:`,1),J(`span`,Cs,A(e.val),1)]))),128))]),B(J(`textarea`,{"onUpdate:modelValue":t[53]||=t=>e.a_str=t,onInput:t[54]||=t=>e.debouncedUpdateFromText(`a`),onKeydown:t[55]||=(...t)=>e.onlyNumberKey&&e.onlyNumberKey(...t),rows:`2`,class:`w-full bg-slate-50 dark:bg-gray-900 border border-slate-200 dark:border-gray-700 rounded-lg p-3 text-sm role-focus-primary outline-none font-mono resize-none leading-relaxed role-text-secondary`},null,544),[[Q,e.a_str]])]),J(`details`,{open:e.activeCoeffAdjustment===`aScale`,class:`bg-slate-50 dark:bg-gray-900 border border-slate-200 dark:border-gray-800 rounded-lg`},[J(`summary`,{onClick:t[56]||=$(t=>e.toggleCoeffAdjustment(`aScale`),[`prevent`]),class:`text-sm text-slate-500 dark:text-gray-400 px-3 py-3 cursor-pointer hover:text-slate-600 dark:hover:text-gray-300`},` a 係數倍率微調`),J(`div`,Ts,[J(`div`,Es,[t[178]||=J(`span`,{class:`text-xs text-slate-400 dark:text-gray-500`},`靈敏度:`,-1),(K(),q(W,null,V([`1%`,`2x`,`10x`],t=>J(`button`,{key:t,onClick:n=>e.sense_a=t,class:k([e.sense_a===t?`role-bg-primary role-text-on-fill`:`bg-slate-200 dark:bg-gray-800 text-slate-500 dark:text-gray-400`,`px-3 py-1.5 rounded text-xs font-medium border border-slate-300 dark:border-gray-700`])},A(t),11,Ds)),64))]),(K(),q(W,null,V(6,n=>(K(),q(W,{key:`as`+n},[e.baseA[n]===0?X(``,!0):(K(),q(`div`,Os,[J(`label`,ks,[J(`span`,null,`a`+A(n)+` (基準: `+A(e.baseA[n].toPrecision(6))+`)`,1),e.outOfRangeA[n]?(K(),q(`span`,As,`超出滑桿範圍`)):X(``,!0)]),B(J(`input`,{type:`range`,"onUpdate:modelValue":t=>e.aSliders[n]=t,onInput:t[57]||=(...t)=>e.updateFromControls&&e.updateFromControls(...t),min:-e.maxLogA,max:e.maxLogA,step:e.maxLogA/100,class:`w-full role-range-secondary`},null,40,js),[[Q,e.aSliders[n],void 0,{number:!0}]])]))],64))),64))])],8,ws),J(`details`,{open:e.activeCoeffAdjustment===`a1a2`,class:`mt-3 bg-slate-50 dark:bg-gray-900 border border-slate-200 dark:border-gray-800 rounded-lg`},[J(`summary`,{onClick:t[58]||=$(t=>e.toggleCoeffAdjustment(`a1a2`),[`prevent`]),class:`text-sm text-slate-500 dark:text-gray-400 px-3 py-3 cursor-pointer hover:text-slate-600 dark:hover:text-gray-300`},` a1/a2 步階微調`),J(`div`,Ns,[J(`div`,Ps,[J(`div`,Fs,[J(`button`,{type:`button`,onClick:t[59]||=t=>e.adjustAFineStep(-1),title:`調粗`,class:`rounded-lg border border-slate-200 dark:border-gray-700 bg-white dark:bg-gray-800 text-slate-600 dark:text-gray-300 py-2 text-xs font-bold transition-colors hover:bg-slate-100 dark:hover:bg-gray-700`},` 粗 `),J(`div`,Is,[t[179]||=J(`span`,{class:`block text-[9px] role-text-tertiary-muted role-text-tertiary font-bold`},`微調量`,-1),J(`span`,{class:`block truncate font-mono text-sm font-bold role-text-tertiary`,title:e.formatAFineDelta()},` +/-`+A(e.formatAFineDelta()),9,Ls)]),J(`button`,{type:`button`,onClick:t[60]||=t=>e.adjustAFineStep(1),title:`調細`,class:`rounded-lg border border-slate-200 dark:border-gray-700 bg-white dark:bg-gray-800 text-slate-600 dark:text-gray-300 py-2 text-xs font-bold transition-colors hover:bg-slate-100 dark:hover:bg-gray-700`},` 細 `)]),J(`div`,Rs,A(e.isTouchInput?`觸控拖曳微調`:`直接輸入 / shift + 滾輪微調`),1),J(`div`,zs,[e.isTouchInput?(K(),q(`button`,{key:1,type:`button`,onPointerdown:t[72]||=$(t=>e.startAFineDrag(`delta`,t),[`prevent`]),class:`touch-none select-none w-28 mx-auto bg-white dark:bg-gray-800 border border-slate-200 dark:border-gray-700 rounded-lg p-3 text-center role-active-border-tertiary active:ring-2 role-active-ring-tertiary`},[t[181]||=J(`span`,{class:`text-[9px] text-slate-400 block font-bold mb-1`},`δ`,-1),J(`span`,{class:`block max-w-full truncate text-base font-mono font-bold role-text-tertiary`,title:e.formatFineCoeff(e.currentDelta)},A(e.formatFineCoeff(e.currentDelta)),9,Us)],32)):(K(),q(`label`,Bs,[t[180]||=J(`span`,{class:`text-[9px] text-slate-400 block font-bold mb-1`},`δ`,-1),J(`div`,Vs,[J(`button`,{type:`button`,onPointerdown:t[61]||=$(t=>e.startA1A2Repeat(`delta`,-1),[`prevent`]),onPointerup:t[62]||=(...t)=>e.stopA1A2Repeat&&e.stopA1A2Repeat(...t),onPointerleave:t[63]||=(...t)=>e.stopA1A2Repeat&&e.stopA1A2Repeat(...t),onPointercancel:t[64]||=(...t)=>e.stopA1A2Repeat&&e.stopA1A2Repeat(...t),class:`rounded-lg bg-slate-200 dark:bg-gray-800 hover:bg-slate-300 dark:hover:bg-gray-700 text-slate-700 dark:text-gray-300 text-sm font-bold transition-colors`},`-`,32),J(`input`,{type:`number`,value:e.formatFineCoeff(e.currentDelta),step:e.aFineStep,onChange:t[65]||=t=>e.setAFineDirect(`delta`,t.target.value),onKeydown:t[66]||=(...t)=>e.onlyNumberKey&&e.onlyNumberKey(...t),onWheel:t[67]||=t=>e.handleAFineWheel(`delta`,t),class:`min-w-0 w-full bg-white dark:bg-gray-800 border border-slate-200 dark:border-gray-700 rounded-lg p-3 text-xs font-mono text-center role-text-tertiary`},null,40,Hs),J(`button`,{type:`button`,onPointerdown:t[68]||=$(t=>e.startA1A2Repeat(`delta`,1),[`prevent`]),onPointerup:t[69]||=(...t)=>e.stopA1A2Repeat&&e.stopA1A2Repeat(...t),onPointerleave:t[70]||=(...t)=>e.stopA1A2Repeat&&e.stopA1A2Repeat(...t),onPointercancel:t[71]||=(...t)=>e.stopA1A2Repeat&&e.stopA1A2Repeat(...t),class:`rounded-lg bg-slate-200 dark:bg-gray-800 hover:bg-slate-300 dark:hover:bg-gray-700 text-slate-700 dark:text-gray-300 text-sm font-bold transition-colors`},`+`,32)])])),e.isTouchInput?(K(),q(`button`,{key:3,type:`button`,onPointerdown:t[84]||=$(t=>e.startAFineDrag(`r`,t),[`prevent`]),class:`touch-none select-none w-28 mx-auto bg-white dark:bg-gray-800 border border-slate-200 dark:border-gray-700 rounded-lg p-3 text-center role-active-border-primary active:ring-2 role-active-ring-primary`},[t[183]||=J(`span`,{class:`text-[9px] text-slate-400 block font-bold mb-1`},`r`,-1),J(`span`,{class:`block max-w-full truncate text-base font-mono font-bold role-text-primary`,title:e.formatFineCoeff(e.currentR)},A(e.formatFineCoeff(e.currentR)),9,qs)],32)):(K(),q(`label`,Ws,[t[182]||=J(`span`,{class:`text-[9px] text-slate-400 block font-bold mb-1`},`r`,-1),J(`div`,Gs,[J(`button`,{type:`button`,onPointerdown:t[73]||=$(t=>e.startA1A2Repeat(`r`,-1),[`prevent`]),onPointerup:t[74]||=(...t)=>e.stopA1A2Repeat&&e.stopA1A2Repeat(...t),onPointerleave:t[75]||=(...t)=>e.stopA1A2Repeat&&e.stopA1A2Repeat(...t),onPointercancel:t[76]||=(...t)=>e.stopA1A2Repeat&&e.stopA1A2Repeat(...t),class:`rounded-lg role-bg-tertiary-soft role-hover-tertiary-soft role-text-tertiary text-sm font-bold transition-colors`},`-`,32),J(`input`,{type:`number`,value:e.formatFineCoeff(e.currentR),step:e.aFineStep,onChange:t[77]||=t=>e.setAFineDirect(`r`,t.target.value),onKeydown:t[78]||=(...t)=>e.onlyNumberKey&&e.onlyNumberKey(...t),onWheel:t[79]||=t=>e.handleAFineWheel(`r`,t),class:`min-w-0 w-full bg-white dark:bg-gray-800 border border-slate-200 dark:border-gray-700 rounded-lg p-3 text-xs font-mono text-center role-text-primary`},null,40,Ks),J(`button`,{type:`button`,onPointerdown:t[80]||=$(t=>e.startA1A2Repeat(`r`,1),[`prevent`]),onPointerup:t[81]||=(...t)=>e.stopA1A2Repeat&&e.stopA1A2Repeat(...t),onPointerleave:t[82]||=(...t)=>e.stopA1A2Repeat&&e.stopA1A2Repeat(...t),onPointercancel:t[83]||=(...t)=>e.stopA1A2Repeat&&e.stopA1A2Repeat(...t),class:`rounded-lg role-bg-primary-soft role-hover-primary-soft role-text-primary text-sm font-bold transition-colors`},`+`,32)])]))])]),J(`div`,Js,[J(`div`,Ys,[t[184]||=J(`span`,{class:`text-[9px] text-slate-400 block font-bold mb-1`},`a1 = -1 - r + δ`,-1),J(`span`,{class:`block max-w-full truncate text-sm font-mono font-bold role-text-tertiary`,title:e.formatFineCoeff(e.currentA1)},A(e.formatFineCoeff(e.currentA1)),9,Xs)]),J(`div`,Zs,[t[185]||=J(`span`,{class:`text-[9px] text-slate-400 block font-bold mb-1`},`a2 = r + δ`,-1),J(`span`,{class:`block max-w-full truncate text-sm font-mono font-bold role-text-primary`,title:e.formatFineCoeff(e.currentA2)},A(e.formatFineCoeff(e.currentA2)),9,Qs)]),J(`div`,$s,[t[186]||=J(`span`,{class:`text-[9px] text-slate-400 block font-bold mb-1`},`差值 a1-a2`,-1),J(`span`,{class:`block max-w-full truncate text-xs font-mono text-slate-600 dark:text-gray-300`,title:e.formatFineCoeff(e.currentA1A2Diff)},A(e.formatFineCoeff(e.currentA1A2Diff)),9,ec)]),J(`div`,tc,[t[187]||=J(`span`,{class:`text-[9px] text-slate-400 block font-bold mb-1`},`總和 a1+a2`,-1),J(`span`,{class:`block max-w-full truncate text-xs font-mono text-slate-600 dark:text-gray-300`,title:e.formatFineCoeff(e.currentA1A2Sum)},A(e.formatFineCoeff(e.currentA1A2Sum)),9,nc)])]),t[188]||=J(`div`,{class:`role-bg-warning-soft border role-border-warning-soft rounded-lg p-3`},[J(`p`,{class:`text-[10px] role-text-warning leading-relaxed`},[J(`span`,{class:`font-bold`},`運算說明:`),J(`br`),Y(` δ = (a1 + a2 + 1) / 2,r = (a2 - a1 - 1) / 2。更改數值會自動更新圖表;桌機可用 +/- 或 shift + 滾輪,觸控時按住數值面板上下拖曳。 `)])],-1)])],8,Ms)]),t[209]||=J(`hr`,{class:`border-slate-200 dark:border-gray-800`},null,-1),J(`section`,null,[J(`h2`,rc,[J(`div`,ic,[t[189]||=J(`svg`,{class:`w-5 h-5`,fill:`none`,stroke:`currentColor`,viewBox:`0 0 24 24`},[J(`path`,{"stroke-linecap":`round`,"stroke-linejoin":`round`,"stroke-width":`2`,d:`M9 7h6M9 12h6M9 17h3M5 5a2 2 0 012-2h7l5 5v11a2 2 0 01-2 2H7a2 2 0 01-2-2V5z`})],-1),t[190]||=J(`span`,null,`定點數係數轉換`,-1),J(`span`,ac,`b Q`+A(e.shiftBitsB),1),J(`span`,oc,`a Q`+A(e.shiftBitsA),1)]),J(`div`,sc,[e.isFixedPointDirty?(K(),q(`button`,{key:0,onClick:t[85]||=(...t)=>e.resetFixedPointSettings&&e.resetFixedPointSettings(...t),class:`text-[10px] font-bold role-bg-secondary-soft role-border-secondary-soft role-text-secondary role-hover-secondary-soft border px-2 py-1 rounded transition-colors uppercase mr-1`},`重設`)):X(``,!0)])]),J(`div`,cc,[J(`div`,null,[t[191]||=J(`label`,{class:`text-sm text-slate-500 dark:text-gray-400 mb-1 block`},`b 左移位元數 (Shift Bits)`,-1),e.isTouchInput?(K(),q(`button`,{key:1,type:`button`,onPointerdown:t[97]||=$(t=>e.startShiftBitDrag(`b`,t),[`prevent`]),class:`touch-none select-none block w-24 mx-auto bg-white dark:bg-gray-800 border border-slate-200 dark:border-gray-700 rounded-lg p-3 text-center role-active-border-primary active:ring-2 role-active-ring-primary`},[J(`span`,dc,A(e.shiftBitsB),1)],32)):(K(),q(`div`,lc,[J(`button`,{type:`button`,onPointerdown:t[86]||=$(t=>e.startShiftBitRepeat(`b`,-1),[`prevent`]),onPointerup:t[87]||=(...t)=>e.stopShiftBitRepeat&&e.stopShiftBitRepeat(...t),onPointerleave:t[88]||=(...t)=>e.stopShiftBitRepeat&&e.stopShiftBitRepeat(...t),onPointercancel:t[89]||=(...t)=>e.stopShiftBitRepeat&&e.stopShiftBitRepeat(...t),class:`rounded-lg role-bg-primary-soft role-hover-primary-soft role-text-primary text-sm font-bold transition-colors`},`-`,32),J(`input`,{type:`number`,value:e.shiftBitsB,min:`0`,onChange:t[90]||=t=>e.setShiftBits(`b`,t.target.value),onKeydown:t[91]||=(...t)=>e.onlyNumberKey&&e.onlyNumberKey(...t),onWheel:t[92]||=t=>e.handleShiftBitWheel(`b`,t),class:`min-w-0 w-full bg-white dark:bg-gray-800 border border-slate-200 dark:border-gray-700 rounded-lg p-3 text-base role-focus-primary outline-none transition-all text-slate-900 dark:text-gray-100`},null,40,uc),J(`button`,{type:`button`,onPointerdown:t[93]||=$(t=>e.startShiftBitRepeat(`b`,1),[`prevent`]),onPointerup:t[94]||=(...t)=>e.stopShiftBitRepeat&&e.stopShiftBitRepeat(...t),onPointerleave:t[95]||=(...t)=>e.stopShiftBitRepeat&&e.stopShiftBitRepeat(...t),onPointercancel:t[96]||=(...t)=>e.stopShiftBitRepeat&&e.stopShiftBitRepeat(...t),class:`rounded-lg role-bg-primary-soft role-hover-primary-soft role-text-primary text-sm font-bold transition-colors`},`+`,32)])),J(`p`,fc,`b scaling: 2^`+A(e.shiftBitsB)+` (`+A(2**e.shiftBitsB)+`)`,1)]),J(`div`,null,[t[192]||=J(`label`,{class:`text-sm text-slate-500 dark:text-gray-400 mb-1 block`},`a 左移位元數 (Shift Bits)`,-1),e.isTouchInput?(K(),q(`button`,{key:1,type:`button`,onPointerdown:t[109]||=$(t=>e.startShiftBitDrag(`a`,t),[`prevent`]),class:`touch-none select-none block w-24 mx-auto bg-white dark:bg-gray-800 border border-slate-200 dark:border-gray-700 rounded-lg p-3 text-center role-active-border-secondary active:ring-2 role-active-ring-secondary`},[J(`span`,hc,A(e.shiftBitsA),1)],32)):(K(),q(`div`,pc,[J(`button`,{type:`button`,onPointerdown:t[98]||=$(t=>e.startShiftBitRepeat(`a`,-1),[`prevent`]),onPointerup:t[99]||=(...t)=>e.stopShiftBitRepeat&&e.stopShiftBitRepeat(...t),onPointerleave:t[100]||=(...t)=>e.stopShiftBitRepeat&&e.stopShiftBitRepeat(...t),onPointercancel:t[101]||=(...t)=>e.stopShiftBitRepeat&&e.stopShiftBitRepeat(...t),class:`rounded-lg role-bg-secondary-soft role-hover-secondary-soft role-text-secondary text-sm font-bold transition-colors`},`-`,32),J(`input`,{type:`number`,value:e.shiftBitsA,min:`0`,onChange:t[102]||=t=>e.setShiftBits(`a`,t.target.value),onKeydown:t[103]||=(...t)=>e.onlyNumberKey&&e.onlyNumberKey(...t),onWheel:t[104]||=t=>e.handleShiftBitWheel(`a`,t),class:`min-w-0 w-full bg-white dark:bg-gray-800 border border-slate-200 dark:border-gray-700 rounded-lg p-3 text-base role-focus-primary outline-none transition-all text-slate-900 dark:text-gray-100`},null,40,mc),J(`button`,{type:`button`,onPointerdown:t[105]||=$(t=>e.startShiftBitRepeat(`a`,1),[`prevent`]),onPointerup:t[106]||=(...t)=>e.stopShiftBitRepeat&&e.stopShiftBitRepeat(...t),onPointerleave:t[107]||=(...t)=>e.stopShiftBitRepeat&&e.stopShiftBitRepeat(...t),onPointercancel:t[108]||=(...t)=>e.stopShiftBitRepeat&&e.stopShiftBitRepeat(...t),class:`rounded-lg role-bg-secondary-soft role-hover-secondary-soft role-text-secondary text-sm font-bold transition-colors`},`+`,32)])),J(`p`,gc,`a scaling: 2^`+A(e.shiftBitsA)+` (`+A(2**e.shiftBitsA)+`)`,1)])]),J(`div`,_c,[J(`div`,null,[t[193]||=J(`label`,{class:`text-sm text-slate-500 dark:text-gray-400 mb-1 block`},`定點分子係數 b (Integers)`,-1),J(`div`,vc,[(K(!0),q(W,null,V(e.fixedPointCoeffs.b,(e,t)=>(K(),q(`div`,{key:e.label,class:k([e.isOverridden?`role-border-primary ring-1 role-ring-primary`:`role-border-primary-soft`,`role-bg-primary-soft px-1.5 py-0.5 rounded border flex items-center gap-1 transition-all`])},[J(`span`,yc,A(e.label)+`:`,1),J(`span`,{class:k([`text-[10px] font-mono role-text-primary font-bold`,{italic:!e.isOverridden}])},A(e.val),3)],2))),128))]),B(J(`textarea`,{"onUpdate:modelValue":t[110]||=t=>e.b_int_str=t,onKeydown:t[111]||=t=>e.onlyNumberKey(t,!1),rows:`2`,class:`w-full bg-slate-50 dark:bg-gray-900 border border-slate-200 dark:border-gray-700 rounded-lg p-3 text-sm role-focus-primary outline-none font-mono resize-none leading-relaxed role-text-primary`},null,544),[[Q,e.b_int_str]])]),J(`div`,null,[t[206]||=J(`label`,{class:`text-sm text-slate-500 dark:text-gray-400 mb-1 block`},`定點分母係數 a (Integers)`,-1),J(`div`,bc,[(K(!0),q(W,null,V(e.fixedPointCoeffs.a,(e,t)=>(K(),q(`div`,{key:e.label,class:k([e.isOverridden?`role-border-secondary ring-1 role-ring-secondary`:`role-border-secondary-soft`,`role-bg-secondary-soft px-1.5 py-0.5 rounded border flex items-center gap-1 transition-all`])},[J(`span`,xc,A(e.label)+`:`,1),J(`span`,{class:k([`text-[10px] font-mono role-text-secondary font-bold`,{italic:!e.isOverridden}])},A(e.val),3)],2))),128))]),B(J(`textarea`,{"onUpdate:modelValue":t[112]||=t=>e.a_int_str=t,onKeydown:t[113]||=t=>e.onlyNumberKey(t,!1),rows:`2`,class:`w-full bg-slate-50 dark:bg-gray-900 border border-slate-200 dark:border-gray-700 rounded-lg p-3 text-sm role-focus-primary outline-none font-mono resize-none leading-relaxed role-text-secondary`},null,544),[[Q,e.a_int_str]]),J(`details`,Sc,[t[205]||=J(`summary`,{class:`text-sm text-slate-500 dark:text-gray-400 px-3 py-3 cursor-pointer hover:text-slate-600 dark:hover:text-gray-300`},` a1/a2 步階微調`,-1),J(`div`,Cc,[J(`div`,wc,[J(`div`,Tc,[J(`button`,{type:`button`,onClick:t[114]||=t=>e.adjustFixedAFineStep(-1),title:`調粗`,class:`rounded-lg border border-slate-200 dark:border-gray-700 bg-white dark:bg-gray-800 text-slate-600 dark:text-gray-300 py-2 text-xs font-bold transition-colors hover:bg-slate-100 dark:hover:bg-gray-700`},`粗`),J(`div`,Ec,[t[194]||=J(`span`,{class:`block text-[9px] role-text-secondary-muted role-text-secondary font-bold`},`微調量`,-1),J(`span`,{class:`block truncate font-mono text-sm font-bold role-text-secondary`,title:e.formatFixedAFineDelta()},`+/-`+A(e.formatFixedAFineDelta()),9,Dc)]),J(`button`,{type:`button`,onClick:t[115]||=t=>e.adjustFixedAFineStep(1),title:`調細`,class:`rounded-lg border border-slate-200 dark:border-gray-700 bg-white dark:bg-gray-800 text-slate-600 dark:text-gray-300 py-2 text-xs font-bold transition-colors hover:bg-slate-100 dark:hover:bg-gray-700`},`細`)]),J(`div`,Oc,A(e.isTouchInput?`觸控拖曳微調`:`直接輸入 / shift + 滾輪微調`),1),J(`div`,kc,[e.isTouchInput?(K(),q(`button`,{key:1,type:`button`,onPointerdown:t[127]||=$(t=>e.startFixedAFineDrag(`delta`,t),[`prevent`]),class:`touch-none select-none w-28 mx-auto bg-white dark:bg-gray-800 border border-slate-200 dark:border-gray-700 rounded-lg p-3 text-center role-active-border-secondary active:ring-2 role-active-ring-secondary`},[t[196]||=J(`span`,{class:`text-[9px] text-slate-400 block font-bold mb-1`},`δ`,-1),J(`span`,{class:`block max-w-full truncate text-base font-mono font-bold role-text-secondary`,title:e.formatFixedFineCoeff(e.fixedCurrentDelta)},A(e.formatFixedFineCoeff(e.fixedCurrentDelta)),9,Nc)],32)):(K(),q(`label`,Ac,[t[195]||=J(`span`,{class:`text-[9px] text-slate-400 block font-bold mb-1`},`δ`,-1),J(`div`,jc,[J(`button`,{type:`button`,onPointerdown:t[116]||=$(t=>e.startFixedA1A2Repeat(`delta`,-1),[`prevent`]),onPointerup:t[117]||=(...t)=>e.stopFixedA1A2Repeat&&e.stopFixedA1A2Repeat(...t),onPointerleave:t[118]||=(...t)=>e.stopFixedA1A2Repeat&&e.stopFixedA1A2Repeat(...t),onPointercancel:t[119]||=(...t)=>e.stopFixedA1A2Repeat&&e.stopFixedA1A2Repeat(...t),class:`rounded-lg role-bg-secondary-soft role-hover-secondary-soft role-text-secondary text-sm font-bold transition-colors`},`-`,32),J(`input`,{type:`number`,value:e.formatFixedFineCoeff(e.fixedCurrentDelta),step:e.fixedAFineStep,onChange:t[120]||=t=>e.setFixedAFineDirect(`delta`,t.target.value),onKeydown:t[121]||=(...t)=>e.onlyNumberKey&&e.onlyNumberKey(...t),onWheel:t[122]||=t=>e.handleFixedAFineWheel(`delta`,t),class:`min-w-0 w-full bg-white dark:bg-gray-800 border border-slate-200 dark:border-gray-700 rounded-lg p-3 text-xs font-mono text-center role-text-secondary`},null,40,Mc),J(`button`,{type:`button`,onPointerdown:t[123]||=$(t=>e.startFixedA1A2Repeat(`delta`,1),[`prevent`]),onPointerup:t[124]||=(...t)=>e.stopFixedA1A2Repeat&&e.stopFixedA1A2Repeat(...t),onPointerleave:t[125]||=(...t)=>e.stopFixedA1A2Repeat&&e.stopFixedA1A2Repeat(...t),onPointercancel:t[126]||=(...t)=>e.stopFixedA1A2Repeat&&e.stopFixedA1A2Repeat(...t),class:`rounded-lg role-bg-secondary-soft role-hover-secondary-soft role-text-secondary text-sm font-bold transition-colors`},`+`,32)])])),e.isTouchInput?(K(),q(`button`,{key:3,type:`button`,onPointerdown:t[139]||=$(t=>e.startFixedAFineDrag(`r`,t),[`prevent`]),class:`touch-none select-none w-28 mx-auto bg-white dark:bg-gray-800 border border-slate-200 dark:border-gray-700 rounded-lg p-3 text-center active:border-slate-400 active:ring-2 active:ring-slate-400/20`},[t[198]||=J(`span`,{class:`text-[9px] text-slate-400 block font-bold mb-1`},`r`,-1),J(`span`,{class:`block max-w-full truncate text-base font-mono font-bold text-slate-700 dark:text-gray-300`,title:e.formatFixedFineCoeff(e.fixedCurrentR)},A(e.formatFixedFineCoeff(e.fixedCurrentR)),9,Lc)],32)):(K(),q(`label`,Pc,[t[197]||=J(`span`,{class:`text-[9px] text-slate-400 block font-bold mb-1`},`r`,-1),J(`div`,Fc,[J(`button`,{type:`button`,onPointerdown:t[128]||=$(t=>e.startFixedA1A2Repeat(`r`,-1),[`prevent`]),onPointerup:t[129]||=(...t)=>e.stopFixedA1A2Repeat&&e.stopFixedA1A2Repeat(...t),onPointerleave:t[130]||=(...t)=>e.stopFixedA1A2Repeat&&e.stopFixedA1A2Repeat(...t),onPointercancel:t[131]||=(...t)=>e.stopFixedA1A2Repeat&&e.stopFixedA1A2Repeat(...t),class:`rounded-lg bg-slate-200 dark:bg-gray-800 hover:bg-slate-300 dark:hover:bg-gray-700 text-slate-700 dark:text-gray-300 text-sm font-bold transition-colors`},`-`,32),J(`input`,{type:`number`,value:e.formatFixedFineCoeff(e.fixedCurrentR),step:e.fixedAFineStep,onChange:t[132]||=t=>e.setFixedAFineDirect(`r`,t.target.value),onKeydown:t[133]||=(...t)=>e.onlyNumberKey&&e.onlyNumberKey(...t),onWheel:t[134]||=t=>e.handleFixedAFineWheel(`r`,t),class:`min-w-0 w-full bg-white dark:bg-gray-800 border border-slate-200 dark:border-gray-700 rounded-lg p-3 text-xs font-mono text-center text-slate-700 dark:text-gray-300`},null,40,Ic),J(`button`,{type:`button`,onPointerdown:t[135]||=$(t=>e.startFixedA1A2Repeat(`r`,1),[`prevent`]),onPointerup:t[136]||=(...t)=>e.stopFixedA1A2Repeat&&e.stopFixedA1A2Repeat(...t),onPointerleave:t[137]||=(...t)=>e.stopFixedA1A2Repeat&&e.stopFixedA1A2Repeat(...t),onPointercancel:t[138]||=(...t)=>e.stopFixedA1A2Repeat&&e.stopFixedA1A2Repeat(...t),class:`rounded-lg bg-slate-200 dark:bg-gray-800 hover:bg-slate-300 dark:hover:bg-gray-700 text-slate-700 dark:text-gray-300 text-sm font-bold transition-colors`},`+`,32)])]))])]),J(`div`,Rc,[J(`div`,zc,[t[199]||=J(`span`,{class:`text-[9px] text-slate-400 block font-bold mb-1`},`a1 = -a0 - r + δ`,-1),J(`span`,{class:`block max-w-full truncate text-sm font-mono font-bold role-text-secondary-muted`,title:e.formatFixedFineCoeff(e.fixedCurrentA1)},A(e.formatFixedFineCoeff(e.fixedCurrentA1)),9,Bc)]),J(`div`,Vc,[t[200]||=J(`span`,{class:`text-[9px] text-slate-400 block font-bold mb-1`},`a2 = r + δ`,-1),J(`span`,{class:`block max-w-full truncate text-sm font-mono font-bold role-text-secondary-muted`,title:e.formatFixedFineCoeff(e.fixedCurrentA2)},A(e.formatFixedFineCoeff(e.fixedCurrentA2)),9,Hc)]),J(`div`,Uc,[t[201]||=J(`span`,{class:`text-[9px] text-slate-400 block font-bold mb-1`},`差值 a1-a2`,-1),J(`span`,{class:`block max-w-full truncate text-xs font-mono text-slate-600 dark:text-gray-300`,title:e.formatFixedFineCoeff(e.fixedCurrentA1A2Diff)},A(e.formatFixedFineCoeff(e.fixedCurrentA1A2Diff)),9,Wc)]),J(`div`,Gc,[t[202]||=J(`span`,{class:`text-[9px] text-slate-400 block font-bold mb-1`},`總和 a1+a2`,-1),J(`span`,{class:`block max-w-full truncate text-xs font-mono text-slate-600 dark:text-gray-300`,title:e.formatFixedFineCoeff(e.fixedCurrentA1A2Sum)},A(e.formatFixedFineCoeff(e.fixedCurrentA1A2Sum)),9,Kc)])]),J(`div`,qc,[J(`p`,Jc,[t[203]||=J(`span`,{class:`font-bold`},`運算說明:`,-1),t[204]||=J(`br`,null,null,-1),Y(` a0 = 2^`+A(e.shiftBitsA)+`,δ = (a1 + a2 + a0) / 2,r = (a2 - a1 - a0) / 2。 `,1)])])])])])]),J(`p`,Yc,`註:b 係數乘以 2^`+A(e.shiftBitsB)+`,a 係數乘以 2^`+A(e.shiftBitsA)+` 後四捨五入,可用於定點數 DSP 實作。`,1)])],2),J(`main`,{class:k([e.mobileTab===`chart`?`flex bg-white dark:bg-[#0f0f0f] !p-0`:`hidden`,`lg:flex flex-1 flex-col overflow-y-auto bg-slate-50 dark:bg-[#0f0f0f] lg:p-6 gap-0 lg:gap-6 custom-scrollbar relative transition-colors duration-300`])},[e.globalError?(K(),q(`div`,Xc,[t[210]||=J(`svg`,{class:`w-4 h-4`,fill:`none`,stroke:`currentColor`,viewBox:`0 0 24 24`},[J(`path`,{"stroke-linecap":`round`,"stroke-linejoin":`round`,"stroke-width":`2`,d:`M12 8v4m0 4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z`})],-1),Y(` `+A(e.globalError)+` `,1),J(`button`,{onClick:t[140]||=t=>e.globalError=null,class:`ml-2 role-hover-error`},`×`)])):X(``,!0),J(`div`,Zc,[t[213]||=J(`div`,{class:`hidden lg:block absolute inset-0 bg-gradient-to-br role-surface-gradient pointer-events-none`},null,-1),J(`div`,Qc,[t[212]||=J(`h3`,{class:`font-bold text-slate-800 dark:text-gray-200 tracking-wide flex items-center gap-2`},[J(`svg`,{class:`w-5 h-5 role-text-primary`,fill:`none`,stroke:`currentColor`,viewBox:`0 0 24 24`},[J(`path`,{"stroke-linecap":`round`,"stroke-linejoin":`round`,"stroke-width":`2`,d:`M4 19V5m0 14h16M7 16l3-4 3 2 4-7`})]),Y(` 頻率響應 (Frequency Response)`)],-1),e.loadingBode?(K(),q(`div`,$c,[...t[211]||=[J(`span`,{class:`w-2 h-2 rounded-full role-dot-primary animate-ping`},null,-1),Y(` 重新計算中... `,-1)]])):X(``,!0)]),t[214]||=J(`div`,{class:`overflow-x-auto bg-white dark:bg-dark`},[J(`div`,{id:`bodePlot`,class:`min-w-[580px] w-full h-[800px] z-10 relative bg-white dark:bg-dark`})],-1)]),J(`div`,el,[t[222]||=J(`div`,{class:`px-5 py-4 border-b border-slate-100 dark:border-gray-800 bg-white dark:bg-dark backdrop-blur-sm z-10 relative`},[J(`h3`,{class:`font-bold text-slate-800 dark:text-gray-200 tracking-wide flex items-center gap-2`},[J(`svg`,{class:`w-5 h-5 role-text-primary`,fill:`none`,stroke:`currentColor`,viewBox:`0 0 24 24`},[J(`path`,{"stroke-linecap":`round`,"stroke-linejoin":`round`,"stroke-width":`2`,d:`M4 12h4l2-6 4 12 2-6h4`})]),Y(` 時域訊號探討`)])],-1),J(`div`,tl,[t[221]||=J(`p`,{class:`text-base text-slate-500 dark:text-gray-400 mb-4`},`請上傳包含時域訊號的 CSV 檔案,系統會使用上述設定的差分濾波器。 `,-1),J(`div`,nl,[J(`label`,rl,[t[215]||=J(`svg`,{class:`w-5 h-5`,fill:`none`,stroke:`currentColor`,viewBox:`0 0 24 24`},[J(`path`,{"stroke-linecap":`round`,"stroke-linejoin":`round`,"stroke-width":`2`,d:`M4 16v1a3 3 0 003 3h10a3 3 0 003-3v-1m-4-8l-4-4m0 0L8 8m4-4v12`})],-1),t[216]||=Y(` 上傳輸入訊號 (CSV) `,-1),J(`input`,{type:`file`,ref:`fileInput`,accept:`.csv`,onChange:t[141]||=(...t)=>e.handleFileUpload&&e.handleFileUpload(...t),class:`hidden`},null,544)]),e.csvFile?(K(),q(`span`,il,A(e.csvFile.name),1)):X(``,!0),e.csvInfo?(K(),q(`span`,al,A(e.csvInfo.rows)+` 筆 / `+A(e.csvInfo.columns)+` 欄 `,1)):X(``,!0),e.csvParseError?(K(),q(`span`,ol,A(e.csvParseError),1)):X(``,!0),e.csvColumns.length>0?(K(),q(`div`,sl)):X(``,!0),e.csvColumns.length>0?(K(),q(`div`,cl,[t[217]||=J(`span`,{class:`text-sm text-slate-400`},`訊號欄位:`,-1),B(J(`select`,{"onUpdate:modelValue":t[142]||=t=>e.selectedColumn=t,class:`bg-white dark:bg-gray-800 border border-slate-200 dark:border-gray-700 rounded-lg p-3 text-base role-focus-primary outline-none text-slate-900 dark:text-gray-100`},[(K(!0),q(W,null,V(e.csvColumns,(e,t)=>(K(),q(`option`,{key:t,value:t},A(e),9,ll))),128))],512),[[$a,e.selectedColumn]])])):X(``,!0),e.csvFile?(K(),q(`button`,{key:5,onClick:t[143]||=(...t)=>e.processFilter&&e.processFilter(...t),class:`role-bg-primary role-hover-primary role-text-on-fill px-6 py-3 rounded-lg text-base font-semibold transition-all shadow-md role-shadow-primary disabled:opacity-50 disabled:cursor-not-allowed`,disabled:e.loadingFilter||e.csvColumns.length===0},A(e.loadingFilter?`處理中...`:`執行當前濾波器`),9,ul)):X(``,!0),e.filterDone?(K(),q(`button`,{key:6,onClick:t[144]||=(...t)=>e.downloadCsv&&e.downloadCsv(...t),class:`ml-auto bg-slate-700 hover:bg-slate-600 role-text-on-fill px-5 py-3 rounded-lg text-base font-semibold transition-all flex items-center gap-2`},[...t[218]||=[J(`svg`,{class:`w-5 h-5`,fill:`none`,stroke:`currentColor`,viewBox:`0 0 24 24`},[J(`path`,{"stroke-linecap":`round`,"stroke-linejoin":`round`,"stroke-width":`2`,d:`M4 16v1a3 3 0 003 3h10a3 3 0 003-3v-1m-4-4l-4 4m0 0l-4-4m4 4V4`})],-1),Y(` 匯出結果 `,-1)]])):X(``,!0)]),e.csvPreview.length>0?(K(),q(`div`,dl,[t[219]||=J(`h4`,{class:`text-sm font-semibold text-slate-500 dark:text-gray-400 mb-2 uppercase tracking-tight`},` 資料預覽 (前五筆):`,-1),J(`div`,fl,[J(`table`,pl,[J(`thead`,null,[J(`tr`,ml,[(K(!0),q(W,null,V(e.csvColumns,e=>(K(),q(`th`,{key:e,class:`px-4 py-3 font-semibold text-slate-700 dark:text-gray-300`},A(e),1))),128))])]),J(`tbody`,hl,[(K(!0),q(W,null,V(e.csvPreview,(e,t)=>(K(),q(`tr`,{key:t,class:`hover:bg-slate-50/50 dark:hover:bg-gray-800/30 transition-colors`},[(K(!0),q(W,null,V(e,(e,t)=>(K(),q(`td`,{key:t,class:`px-4 py-2 font-mono text-slate-600 dark:text-gray-400`},A(e),1))),128))]))),128))])])])])):X(``,!0),e.filterDone?(K(),q(`h4`,gl,`波形比較圖 `)):X(``,!0),J(`div`,_l,[B(J(`div`,vl,null,512),[[ya,e.filterDone]])]),!e.filterDone&&!e.loadingFilter&&e.csvPreview.length===0?(K(),q(`div`,yl,[...t[220]||=[J(`svg`,{class:`w-12 h-12 mb-3 opacity-50`,fill:`none`,stroke:`currentColor`,viewBox:`0 0 24 24`},[J(`path`,{"stroke-linecap":`round`,"stroke-linejoin":`round`,"stroke-width":`1.5`,d:`M9 19v-6a2 2 0 00-2-2H5a2 2 0 00-2 2v6a2 2 0 002 2h2a2 2 0 002-2zm0 0V9a2 2 0 012-2h2a2 2 0 012 2v10m-6 0a2 2 0 002 2h2a2 2 0 002-2m0 0V5a2 2 0 012-2h2a2 2 0 012 2v14a2 2 0 01-2 2h-2a2 2 0 01-2-2z`})],-1),J(`p`,null,`請上傳包含時間序列的 CSV 檔案進行測試`,-1)]])):X(``,!0)])])],2)]),t[223]||=J(`footer`,{class:`bg-white dark:bg-dark border-t border-slate-200 dark:border-gray-800 py-2 text-center z-20 transition-colors duration-300`},[J(`p`,{class:`text-xs text-slate-400 dark:text-gray-600`},`© 2026 喆富創新科技股份有限公司. All rights reserved.`)],-1)])}so(So(xo,[[`render`,bl]])).mount(`#dea-root`); \ No newline at end of file diff --git a/tests/test_dea_api.py b/tests/test_dea_api.py index cd23a65..3801ba4 100644 --- a/tests/test_dea_api.py +++ b/tests/test_dea_api.py @@ -5,7 +5,16 @@ import unittest from fastapi import HTTPException, UploadFile from fastapi.responses import JSONResponse -from dea_api import BodeParams, DesignParams, add_security_headers, calculate_bode, design_filter, filter_csv +from dea_api import ( + BodeCompareParams, + BodeParams, + DesignParams, + add_security_headers, + calculate_bode, + calculate_bode_compare, + design_filter, + filter_csv, +) class DeaApiTest(unittest.TestCase): @@ -65,6 +74,19 @@ class DeaApiTest(unittest.TestCase): raise AssertionError("Expected a[0] validation to fail") + def test_bode_compare_reuses_one_frequency_axis(self): + body = calculate_bode_compare( + BodeCompareParams( + ideal=BodeParams(fs=1000, b=[1.0], a=[1.0]), + fixed=BodeParams(fs=1000, b=[0.5, 0.5], a=[1.0]), + ) + ) + + self.assertEqual(len(body["freq"]), len(body["ideal"]["mag"])) + self.assertEqual(len(body["freq"]), len(body["fixed"]["mag"])) + self.assertEqual(len(body["ideal"]["phase"]), len(body["fixed"]["phase"])) + + def test_filter_downsamples_plot_response_for_large_csv(self): rows = ["value"] + [str(i) for i in range(6001)] upload = UploadFile(