Files
tcad-bodeplot/static/build/app.js
T

3 lines
151 KiB
JavaScript
Raw Normal View History

(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<e.length;n++)e[n](...t)},O=(e,t,n,r=!1)=>{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<e.length;n++){let r=e[n],i=g(r)?me(r):ue(r);if(i)for(let e in i)t[e]=i[e]}return t}else if(g(e)||v(e))return e}var de=/;(?![^(]*\))/g,fe=/:([^]+)/,pe=/\/\*[^]*?\*\//g;function me(e){let t={};return e.replace(pe,``).split(de).forEach(e=>{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;n<e.length;n++){let r=k(e[n]);r&&(t+=r+` `)}else if(v(e))for(let n in e)e[n]&&(t+=n+` `);return t.trim()}var he=`itemscope,allowfullscreen,formnovalidate,ismap,nomodule,novalidate,readonly`,ge=e(he);he+``;function _e(e){return!!e||e===``}function ve(e,t){if(e.length!==t.length)return!1;let n=!0;for(let r=0;n&&r<e.length;r++)n=ye(e[r],t[r]);return n}function ye(e,t){if(e===t)return!0;let n=m(e),r=m(t);if(n||r)return n&&r?e.getTime()===t.getTime():!1;if(n=_(e),r=_(t),n||r)return e===t;if(n=d(e),r=d(t),n||r)return n&&r?ve(e,t):!1;if(n=v(e),r=v(t),n||r){if(!n||!r||Object.keys(e).length!==Object.keys(t).length)return!1;for(let n in e){let r=e.hasOwnProperty(n),i=t.hasOwnProperty(n);if(r&&!i||!r&&i||!ye(e[n],t[n]))return!1}}return String(e)===String(t)}function be(e,t){return e.findIndex(e=>ye(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._w
`||n===`\r`)&&!a?(n===`\r`&&o===`
`&&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.length<a.length;)t.push(``);return t.map(e=>e.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}},async fetchMCUPorts(){this.loadingMCUPorts=!0,this.mcuStatus=``;try{let e=await fetch(`/api/mcu/ports`);if(!e.ok){let t={detail:`無法取得 MCU COM Port清單`};try{t=await e.json()}catch{}throw Error(t.detail||`無法取得 MCU COM Port清單`)}let t=await e.json();this.mcuPorts=Array.isArray(t.ports)?t.ports:[];let n=this.mcuPorts.map(e=>e.device);(!this.mcuPort||!n.includes(this.mcuPort))&&(t.default_port&&n.includes(t.default_port)?this.mcuPort=t.default_port:n.length>0?this.mcuPort=n[0]:this.mcuPort=t.default_port||``),this.mcuStatus=n.length>0?`已偵測