@canboat/visual-analyzer
Version:
NMEA 2000 data visualization utility (requires SK Server >= 2.15)
1 lines • 184 kB
JavaScript
(self.webpackChunk_canboat_visual_analyzer=self.webpackChunk_canboat_visual_analyzer||[]).push([[543],{3981:(e,t,s)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0});const n=s(74848),a=s(44823),i=s(57592),l=s(6905),r=s(90800),o=s(64545),c="undefined"!=typeof window&&window.location.href.includes("/admin/")?"/plugins/canboat-visual-analyzer":"";t.default=()=>{const[e,t]=(0,a.useState)({isRecording:!1,messageCount:0,fileSize:0}),[s,d]=(0,a.useState)([]),[m,u]=(0,a.useState)(""),[h,p]=(0,a.useState)(!0),[g,x]=(0,a.useState)(()=>r.recordingStorage.getFormat()),[f,j]=(0,a.useState)(!1),[b,y]=(0,a.useState)(null),{state:v,dispatch:N}=(0,l.useRecording)();(0,a.useEffect)(()=>{v.lastUpdate&&t(e=>{const t=v.status;return t.error?y(t.error):y(null),t.isRecording!==e.isRecording&&setTimeout(()=>w(),100),t})},[v.lastUpdate]);const S=[{value:"passthrough",label:"Source Format"},{value:"canboat-json",label:"Canboat JSON"},{value:"canboat-json-pretty",label:"Canboat JSON (Pretty)"},{value:"actisense",label:"Actisense Serial Format"},{value:"actisense-n2k-ascii",label:"Actisense N2K ASCII"},{value:"ikonvert",label:"iKonvert Format"},{value:"ydwg-full-raw",label:"Yacht Devices RAW Format"},{value:"ydwg-raw",label:"Yacht Devices RAW Send Format"},{value:"pcdin",label:"PCDIN Format"},{value:"mxpgn",label:"MXPGN Format"},{value:"candump1",label:"Linux CAN utils (Angstrom)"},{value:"candump2",label:"Linux CAN utils (Debian)"},{value:"candump3",label:"Linux CAN utils (log format)"}];(0,a.useEffect)(()=>{k(),w();const e=setInterval(()=>{w()},1e4);return()=>clearInterval(e)},[]);const k=async()=>{try{const e=await o.server.get({type:"recording"},"/status");if(e.success){const s=e.result;t(s),N({type:"SET_STATUS",payload:s})}}catch(e){console.error("Failed to load recording status:",e)}},w=async()=>{try{const e=await o.server.get({type:"recording"},"/files");if(e.success){const t=e.results;d(t)}}catch(e){console.error("Failed to load recording files:",e)}},C=e=>{if(0===e)return"0 B";const t=Math.floor(Math.log(e)/Math.log(1024));return parseFloat((e/Math.pow(1024,t)).toFixed(2))+" "+["B","KB","MB","GB"][t]},F=e=>e?new Date(e).toLocaleString():"",T=e=>{switch(e){case"canboat-json":case"canboat-json-pretty":default:return"json";case"actisense":case"actisense-n2k-ascii":return"n2k";case"ikonvert":return"iko";case"ydwg-full-raw":case"ydwg-raw":return"ydwg";case"pcdin":return"pcd";case"mxpgn":return"mxp";case"candump1":case"candump2":case"candump3":case"passthrough":return"log"}};return(0,n.jsx)("div",{className:"container-fluid mt-3",children:(0,n.jsxs)(i.Row,{children:[(0,n.jsx)(i.Col,{md:6,children:(0,n.jsxs)(i.Card,{children:[(0,n.jsx)(i.CardHeader,{children:(0,n.jsx)("h5",{children:"Recording Control"})}),(0,n.jsxs)(i.CardBody,{children:[b&&(0,n.jsxs)(i.Alert,{color:"danger",className:"mb-3",children:[(0,n.jsx)("strong",{children:"Error:"})," ",b]}),(0,n.jsxs)("div",{className:"mb-3",children:[(0,n.jsx)(i.Badge,{color:e.isRecording?"success":"secondary",className:"me-2",children:e.isRecording?"● Recording":"○ Not Recording"}),e.isRecording&&e.fileName&&(0,n.jsxs)("small",{className:"text-muted",children:["File: ",e.fileName,e.format&&(0,n.jsxs)("span",{className:"ms-2",children:["Format:"," ",S.find(t=>t.value===e.format)?.label||e.format]})]})]}),e.isRecording&&(0,n.jsxs)("div",{className:"mb-3",children:[(0,n.jsxs)(i.Row,{children:[(0,n.jsxs)(i.Col,{sm:6,children:[(0,n.jsx)("strong",{children:"Messages:"})," ",e.messageCount]}),(0,n.jsxs)(i.Col,{sm:6,children:[(0,n.jsx)("strong",{children:"Size:"})," ",C(e.fileSize)]})]}),e.startTime&&(0,n.jsxs)("div",{className:"mt-2",children:[(0,n.jsx)("strong",{children:"Started:"})," ",F(e.startTime)]})]}),!e.isRecording&&(0,n.jsxs)("div",{className:"mb-3",children:[(0,n.jsxs)(i.FormGroup,{children:[(0,n.jsx)(i.Label,{for:"recordingFormat",children:"Recording Format:"}),(0,n.jsx)(i.Input,{type:"select",id:"recordingFormat",value:g,onChange:e=>{return t=e.target.value,x(t),void r.recordingStorage.setFormat(t);var t},children:S.map(e=>(0,n.jsx)("option",{value:e.value,children:e.label},e.value))})]}),(0,n.jsx)(i.FormGroup,{check:!0,children:(0,n.jsxs)(i.Label,{check:!0,children:[(0,n.jsx)(i.Input,{type:"checkbox",checked:h,onChange:e=>p(e.target.checked)}),"Auto-generate filename"]})}),!h&&(0,n.jsxs)(i.FormGroup,{className:"mt-2",children:[(0,n.jsx)(i.Label,{for:"fileName",children:"Custom filename:"}),(0,n.jsx)(i.Input,{type:"text",id:"fileName",value:m,onChange:e=>u(e.target.value),placeholder:`recording_2025-01-01.${T(g)}`})]})]}),(0,n.jsx)("div",{className:"d-grid gap-2",children:e.isRecording?(0,n.jsx)(i.Button,{color:"danger",onClick:async()=>{j(!0),y(null);try{const e=await o.server.post({type:"recording"},"/stop");if(!e.success){const t=e.error;throw new Error(t||"Failed to stop recording")}w()}catch(e){const t=e instanceof Error?e.message:"Failed to stop recording";y(t)}finally{j(!1)}},disabled:f,children:f?"Stopping...":"Stop Recording"}):(0,n.jsx)(i.Button,{color:"success",onClick:async()=>{j(!0),y(null);try{const e=h?void 0:m||`recording_${(new Date).toISOString().replace(/[:.]/g,"-")}.${T(g)}`;console.log("Starting recording with fileName:",e,"format:",g);const t=await o.server.post({type:"recording",value:{fileName:e,format:g}},"/start");if(console.log("Recording response:",t),!t.success){const e=t.error;throw new Error(e||"Failed to start recording")}t.result,w()}catch(e){const s=e instanceof Error?e.message:"Failed to start recording";y(s),t(e=>({...e,error:s}))}finally{j(!1)}},disabled:f,children:f?"Starting...":"Start Recording"})})]})]})}),(0,n.jsx)(i.Col,{md:6,children:(0,n.jsxs)(i.Card,{children:[(0,n.jsxs)(i.CardHeader,{className:"d-flex justify-content-between align-items-center",children:[(0,n.jsx)("h5",{className:"mb-0",children:"Recorded Files"}),s.length>0&&(0,n.jsx)(i.Button,{size:"sm",color:"outline-danger",onClick:async()=>{if(0!==s.length&&confirm(`Are you sure you want to delete all ${s.length} recording files? This action cannot be undone.`)){j(!0);try{const e=s.map(e=>o.server.delete({type:"recording"},`/files/${encodeURIComponent(e.name)}`)),t=await Promise.allSettled(e),n=t.filter(e=>"rejected"===e.status);if(n.length>0)y(`Failed to delete ${n.length} file(s)`);else{const e=t.filter(e=>"fulfilled"===e.status).map(e=>e.value).filter(e=>!e.success);e.length>0&&y(`Failed to delete ${e.length} file(s)`)}w()}catch(e){y(e instanceof Error?e.message:"Failed to delete files")}finally{j(!1)}}},disabled:f,children:f?"Deleting...":"Delete All"})]}),(0,n.jsx)(i.CardBody,{children:0===s.length?(0,n.jsx)("p",{className:"text-muted",children:"No recordings found."}):(0,n.jsxs)(i.Table,{responsive:!0,size:"sm",children:[(0,n.jsx)("thead",{children:(0,n.jsxs)("tr",{children:[(0,n.jsx)("th",{children:"Filename"}),(0,n.jsx)("th",{children:"Format"}),(0,n.jsx)("th",{children:"Size"}),(0,n.jsx)("th",{children:"Messages"}),(0,n.jsx)("th",{children:"Created"}),(0,n.jsx)("th",{children:"Actions"})]})}),(0,n.jsx)("tbody",{children:s.map(e=>(0,n.jsxs)("tr",{children:[(0,n.jsx)("td",{children:(0,n.jsx)("small",{children:e.name})}),(0,n.jsx)("td",{children:(0,n.jsx)("small",{children:e.format?S.find(t=>t.value===e.format)?.label||e.format:"Unknown"})}),(0,n.jsx)("td",{children:C(e.size)}),(0,n.jsx)("td",{children:e.messageCount.toLocaleString()}),(0,n.jsx)("td",{children:(0,n.jsx)("small",{children:F(e.created)})}),(0,n.jsxs)("td",{children:[(0,n.jsx)(i.Button,{size:"sm",color:"primary",className:"me-1",onClick:()=>{return t=e.name,void window.open(`${c}/api/recording/files/${encodeURIComponent(t)}/download`,"_blank");var t},children:"Download"}),(0,n.jsx)(i.Button,{size:"sm",color:"danger",onClick:()=>(async e=>{if(confirm(`Are you sure you want to delete ${e}?`))try{const t=await o.server.delete({type:"recording"},`/files/${encodeURIComponent(e)}`);if(t.success)w();else{const e=await t.json();y(e.error||"Failed to delete file")}}catch(e){y(e instanceof Error?e.message:"Failed to delete file")}})(e.name),children:"Delete"})]})]},e.name))})]})})]})})]})})}},6905:(e,t,s)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.useRecording=t.RecordingProvider=void 0;const n=s(74848),a=s(44823),i=(0,a.createContext)(void 0),l=(e,t)=>{switch(console.log("RecordingReducer state:",e),t.type){case"RECORDING_STARTED":return{...e,status:{...t.payload,isRecording:!0},lastUpdate:(new Date).toISOString()};case"RECORDING_STOPPED":return{...e,status:{...t.payload,isRecording:!1},lastUpdate:(new Date).toISOString()};case"RECORDING_PROGRESS":return{...e,status:{...e.status,...t.payload},lastUpdate:(new Date).toISOString()};case"RECORDING_ERROR":return{...e,status:{...e.status,error:t.payload.error},lastUpdate:(new Date).toISOString()};case"SET_STATUS":return{...e,status:t.payload,lastUpdate:(new Date).toISOString()};default:return e}},r={status:{isRecording:!1,messageCount:0,fileSize:0}};t.RecordingProvider=({children:e})=>{const[t,s]=(0,a.useReducer)(l,r);return(0,n.jsx)(i.Provider,{value:{state:t,dispatch:s},children:e})},t.useRecording=()=>{const e=(0,a.useContext)(i);if(void 0===e)throw new Error("useRecording must be used within a RecordingProvider");return e}},17368:(e,t,s)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.SentencePanel=void 0;const n=s(74848),a=s(44823),i=s(20261),l=s(79364),r=s(54970),o=s(33679),c=s(57592),d=s(43791),m=s(79972),u=s(47090),h=s(35020),p=s(64170),g=s(83426),x="data",f="pgndef",j="device",b="input",y="mapping",v="readable";t.SentencePanel=e=>{const[t,s]=(0,a.useState)(v),N=(0,r.useObservableState)(e.selectedPgn),S=(0,r.useObservableState)(e.selectedPgnWithHistory||new l.Subject),k=(0,r.useObservableState)(e.info,{}),w=(0,a.useCallback)(()=>{e.onDefinitionsChanged&&e.onDefinitionsChanged(o.changedDefinitionsTracker.getChangedDefinitions())},[e.onDefinitionsChanged]),C=(0,a.useCallback)(t=>{N&&e.definition&&(N.input=t,e.onDefinitionSave&&e.onDefinitionSave(e.definition))},[N,e.selectedPgn]);if((0,a.useCallback)((e,t,s)=>{if(e)try{if("lookup"===t){const t={Name:e,MaxValue:Math.max(...s.map(e=>parseInt(e.key,10))),EnumValues:s.map(e=>({Name:e.value,Value:parseInt(e.key,10)}))};o.changedDefinitionsTracker.addLookup(t),(0,i.updateLookup)(t)}else{const t={Name:e,MaxValue:Math.max(...s.map(e=>parseInt(e.key,10))),EnumBitValues:s.map(e=>({Name:e.value,Bit:parseInt(e.key,10)}))};o.changedDefinitionsTracker.addLookup(t),(0,i.updateBitLookup)(t)}console.log(`Successfully updated ${t} enumeration: ${e}`)}catch(e){console.error(`Failed to save ${t} enumeration:`,e)}else console.warn("No enumeration name provided for lookup save")},[]),null==N)return(0,n.jsx)("div",{children:"Select a PGN to view its data"});let F=e.definition||N.getDefinition();return(0,n.jsxs)("div",{style:{width:"100%",height:"100%",overflow:"auto",display:"flex",flexDirection:"column"},children:[(0,n.jsxs)(c.Nav,{tabs:!0,children:[(0,n.jsx)(c.NavItem,{children:(0,n.jsx)(c.NavLink,{className:t===v?"active ":"",onClick:()=>s(v),children:"Data"})}),(0,n.jsx)(c.NavItem,{children:(0,n.jsx)(c.NavLink,{className:t===x?"active ":"",onClick:()=>s(x),children:"JSON"})}),(0,n.jsx)(c.NavItem,{children:(0,n.jsx)(c.NavLink,{className:t===b?"active ":"",onClick:()=>s(b),children:"Input"})}),k[N.src]?.info&&(0,n.jsx)(c.NavItem,{children:(0,n.jsx)(c.NavLink,{className:t===j?"active ":"",onClick:()=>s(j),children:"Device Info"})}),!e.inEditingTab&&(0,n.jsx)(c.NavItem,{children:(0,n.jsx)(c.NavLink,{className:t===f?"active ":"",onClick:()=>s(f),children:"Definition"})}),(0,n.jsx)(c.NavItem,{children:(0,n.jsx)(c.NavLink,{className:t===y?"active ":"",onClick:()=>s(y),children:"Byte Mapping"})})]}),(0,n.jsxs)(c.TabContent,{activeTab:t,style:{flex:1,overflow:"auto"},children:[(0,n.jsx)(c.TabPane,{tabId:v,children:(0,n.jsx)(c.Card,{children:(0,n.jsx)(c.CardBody,{children:(0,n.jsx)(d.HumanReadableTab,{pgnData:N,definition:F,pgnHistory:S?.history||[]})})})}),(0,n.jsx)(c.TabPane,{tabId:x,children:(0,n.jsx)(c.Card,{children:(0,n.jsx)(c.CardBody,{style:{padding:0},children:(0,n.jsx)(m.JsonDataTab,{pgnData:N,pgnHistory:S?.history||[],onCopyData:async()=>{if(!N)return;const e=JSON.stringify(N,(e,t)=>"input"===e||"rawData"===e||"byteMapping"===e||"definition"===e?void 0:t,2);try{if(navigator.clipboard&&navigator.clipboard.writeText)await navigator.clipboard.writeText(e);else{const t=document.createElement("textarea");t.value=e,t.style.position="fixed",t.style.opacity="0",document.body.appendChild(t),t.select(),document.execCommand("copy"),document.body.removeChild(t)}}catch(e){console.error("Failed to copy PGN data:",e)}}})})})}),(0,n.jsx)(c.TabPane,{tabId:b,children:(0,n.jsx)(c.Card,{children:(0,n.jsx)(c.CardBody,{style:{padding:0},children:(0,n.jsx)(u.InputDataTab,{pgnData:N,onCopyInput:async()=>{if(!N?.input)return;const e=N.input.join("\n");try{if(navigator.clipboard&&navigator.clipboard.writeText)await navigator.clipboard.writeText(e);else{const t=document.createElement("textarea");t.value=e,t.style.position="fixed",t.style.opacity="0",document.body.appendChild(t),t.select(),document.execCommand("copy"),document.body.removeChild(t)}}catch(e){console.error("Failed to copy input data:",e)}},isEditing:e.inEditingTab,onInputChange:C})})})}),void 0!==F&&!e.inEditingTab&&(0,n.jsx)(c.TabPane,{tabId:f,children:(0,n.jsx)(c.Card,{children:(0,n.jsx)(c.CardBody,{style:{padding:0},children:(0,n.jsx)(p.PgnDefinitionTab,{definition:F,pgnData:N,onSave:async t=>{try{if(!N)return;(0,o.saveDefinition)(t,N),w(),e.onDefinitionSave&&e.onDefinitionSave(t)}catch(e){console.error("Failed to save definition:",e)}},hasBeenChanged:o.changedDefinitionsTracker.hasDefinition(F.Id),onExport:async e=>{try{const t=JSON.stringify(e,null,2);if("showSaveFilePicker"in window)try{const s=await window.showSaveFilePicker({suggestedName:`pgn_${e.PGN}_${e.Id}.json`,types:[{description:"JSON files",accept:{"application/json":[".json"]}}]}),n=await s.createWritable();return await n.write(t),await n.close(),void console.log("Definition exported to file:",e.Id)}catch(e){"AbortError"!==e.name&&console.warn("File picker failed, falling back to clipboard:",e)}await navigator.clipboard.writeText(t),console.log("Definition exported to clipboard:",e.Id),alert("PGN definition exported to clipboard!")}catch(e){console.error("Failed to export definition:",e),alert("Failed to export definition. Please try again.")}},onEditPgn:!1===e.inEditingTab?e.onEditPgn:void 0,changedLookups:o.changedDefinitionsTracker.getChangedLookups()},N.pgn)})})}),k[N.src]?.info&&(0,n.jsx)(c.TabPane,{tabId:j,children:(0,n.jsx)(c.Card,{children:(0,n.jsx)(c.CardBody,{style:{padding:0},children:(0,n.jsx)(h.DeviceInfoTab,{pgnData:N,info:k})})})}),(0,n.jsx)(c.TabPane,{tabId:y,children:(0,n.jsxs)(c.Card,{children:[(0,n.jsx)(c.CardHeader,{children:(0,n.jsxs)("small",{children:[(0,n.jsx)("strong",{children:"PGN:"})," ",N.pgn," |",(0,n.jsx)("strong",{children:" Source:"})," ",N.src," |",(0,n.jsx)("strong",{children:" Destination:"})," ",N.dst,(0,n.jsx)("br",{}),(0,n.jsx)("strong",{children:"Description:"})," ",N.description||"N/A"]})}),(0,n.jsx)(c.CardBody,{children:(0,n.jsx)(g.ByteMappingTab,{pgnData:N,definition:F})})]})})]})]})}},20454:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.server=void 0;const s="undefined"!=typeof window&&window.location.href.includes("/admin/")?"/plugins/canboat-visual-analyzer":"",n={"send-n2k":`${s}/api/send-n2k`,"n2k-signalk":`${s}/api/transform/signalk`,recording:`${s}/api/recording`};t.server=new class{constructor(){this.defaultTimeout=1e4,this.defaultRetries=0}async get(e,t=void 0,s={}){return this.send(e,t,"GET",s)}async post(e,t=void 0,s={}){return this.send(e,t,"POST",s)}async delete(e,t=void 0,s={}){return this.send(e,t,"DELETE",s)}async send(e,t="",s="GET",a={}){const{timeout:i=this.defaultTimeout,retries:l=this.defaultRetries,onProgress:r}=a;let o=null;for(let a=0;a<=l;a++)try{a>0&&(r?.(`Retrying... (attempt ${a+1}/${l+1})`),await this.delay(Math.min(1e3*Math.pow(2,a-1),5e3))),r?.("Sending message to SignalK server...");const o=new AbortController,c=setTimeout(()=>o.abort(),i);try{const a=await fetch(n[e.type]+t,{method:s,credentials:"include",headers:{"Content-Type":"application/json"},body:"POST"===s?JSON.stringify(e):void 0,signal:o.signal});if(clearTimeout(c),!a.ok){const e=await a.json();throw new Error(`Send failed (${a.status}): ${e.error||"Unknown error"}`)}const i=await a.json();if(i.error)throw new Error(i.error);return r?.("Message sent successfully"),i}catch(e){throw clearTimeout(c),e}}catch(e){o=e instanceof Error?e:new Error("Unknown error occurred"),e instanceof Error&&"AbortError"===e.name&&(o=new Error(`Request timed out after ${i}ms`)),a<l&&console.warn(`Send attempt ${a+1} failed:`,o.message)}throw o||new Error("Failed to send message after all retries")}delay(e){return new Promise(t=>setTimeout(t,e))}},t.default=t.server},24007:(e,t,s)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0});const n=s(74848),a=s(44823),i=s(57592),l=s(20261);t.default=({changedBitLookups:e,onBitLookupChange:t,onBitLookupRemove:s,onClearAll:r,onBitLookupEdit:o})=>{const[c,d]=(0,a.useState)(""),[m,u]=(0,a.useState)(!0),h=(0,a.useMemo)(()=>{let t;return t=m?Object.values(e):(0,l.getBitEnumerations)(),t.filter(e=>!c||e.Name.toLowerCase().includes(c.toLowerCase()))},[c,e,m]),p=(0,a.useCallback)(e=>{if(!o)return;const t=e.EnumBitValues.map(e=>({key:e.Bit.toString(),value:e.Name}));o(e.Name,"bitlookup",t)},[o]),g=(0,a.useCallback)(t=>{if(e[t]&&window.confirm(`Are you sure you want to delete the bit lookup "${t}"?`)){const n=e[t];n&&(0,l.removeBitLookup)(n),s(t)}},[s,e]);return(0,n.jsx)(n.Fragment,{children:(0,n.jsx)(i.Card,{children:(0,n.jsxs)(i.CardBody,{children:[(0,n.jsxs)("div",{className:"d-flex justify-content-between align-items-center mb-3",children:[(0,n.jsxs)("div",{children:[(0,n.jsx)("h5",{className:"mb-0",children:"Bit Lookups Management"}),(0,n.jsx)("small",{className:"text-muted",children:m?"Showing only bit lookups that have been modified":"Showing all available bit lookups"})]}),(0,n.jsxs)("div",{className:"d-flex gap-2",children:[(0,n.jsx)(i.Button,{color:"primary",size:"sm",onClick:()=>o?.("","bitlookup",[]),disabled:!o,children:"New Bit Lookup"}),(0,n.jsx)(i.Button,{color:"secondary",size:"sm",onClick:r,disabled:0===Object.keys(e).length,children:"Clear All Changes"})]})]}),(0,n.jsxs)(i.Row,{className:"mb-3",children:[(0,n.jsx)(i.Col,{md:"8",children:(0,n.jsx)(i.Input,{size:"sm",type:"text",placeholder:"🔍 Search bit lookups by name...",value:c,onChange:e=>d(e.target.value)})}),(0,n.jsx)(i.Col,{md:"4",children:(0,n.jsxs)(i.FormGroup,{check:!0,size:"sm",children:[(0,n.jsx)(i.Input,{type:"checkbox",id:"showOnlyChangedBit",checked:m,onChange:e=>u(e.target.checked)}),(0,n.jsx)(i.Label,{check:!0,for:"showOnlyChangedBit",className:"text-muted",children:"Show only changed bit lookups"})]})})]}),(0,n.jsx)("div",{style:{height:"500px",overflow:"auto"},children:0===h.length?(0,n.jsxs)("div",{className:"text-center text-muted p-4",children:[(0,n.jsx)("p",{children:"No bit lookups found"}),c?(0,n.jsx)("small",{children:"Try adjusting your search term"}):m?(0,n.jsx)("small",{children:"No modified bit lookups yet"}):(0,n.jsx)("small",{children:"No bit lookups available"})]}):(0,n.jsxs)(i.Table,{responsive:!0,bordered:!0,size:"sm",style:{marginBottom:0},children:[(0,n.jsx)("thead",{style:{position:"sticky",top:0,backgroundColor:"white",zIndex:1},children:(0,n.jsxs)("tr",{children:[(0,n.jsx)("th",{children:"Name"}),(0,n.jsx)("th",{children:"Bit Values Count"}),(0,n.jsx)("th",{style:{width:"120px"},children:"Actions"})]})}),(0,n.jsx)("tbody",{children:h.map((t,s)=>{const a=s%2==0;return(0,n.jsxs)("tr",{style:{backgroundColor:a?"#ffffff":"rgba(0,0,0,.05)"},children:[(0,n.jsxs)("td",{style:{fontFamily:"monospace",fontWeight:"bold"},children:[t.Name,!m&&e[t.Name]&&(0,n.jsx)("span",{className:"badge badge-warning ms-2",title:"Modified",children:"●"})]}),(0,n.jsx)("td",{children:t.EnumBitValues.length}),(0,n.jsx)("td",{children:(0,n.jsxs)("div",{className:"d-flex gap-1",children:[(0,n.jsx)(i.Button,{color:"primary",size:"sm",outline:!0,onClick:()=>p(t),title:"Edit bit lookup",children:"✏️"}),e[t.Name]&&(0,n.jsx)(i.Button,{color:"danger",size:"sm",outline:!0,onClick:()=>g(t.Name),title:"Remove changes",children:"✗"})]})})]},t.Name)})})]})}),(!m||Object.keys(e).length>0)&&(0,n.jsx)(i.Alert,{color:"info",className:"mt-3 mb-0",children:m?(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)("strong",{children:Object.keys(e).length})," bit lookup(s) have been modified and will be saved with your PGN definitions."]}):(0,n.jsxs)(n.Fragment,{children:["Showing ",(0,n.jsx)("strong",{children:h.length})," bit lookup(s)."," ",Object.keys(e).length>0&&(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)("strong",{children:Object.keys(e).length})," have been modified."]})]})})]})})})}},33679:function(e,t,s){"use strict";var n=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(t,"__esModule",{value:!0}),t.saveDefinition=t.changedDefinitionsTracker=void 0;const a=s(74848),i=s(44823),l=s(57592),r=s(20261),o=s(95094),c=s(17368),d=s(64170),m=n(s(43238)),u=n(s(24007)),h=s(64170),p=s(79364),g=s(90800),x=s(54970),f="pgn-definitions",j="lookups",b="bit-lookups";t.changedDefinitionsTracker={_originals:{definitions:{},lookups:{},bitLookups:{}},_storageKeys:{definitions:"changedDefinitionsTracker_definitions",lookups:"changedDefinitionsTracker_lookups",bitLookups:"changedDefinitionsTracker_bitLookups"},_cache:{definitions:null,lookups:null,bitLookups:null},_loadFromStorage:(e,t)=>g.localStorage.getItem(e,t),_saveToStorage(e,t){g.localStorage.setItem(e,t)},get definitions(){return null===this._cache.definitions&&(this._cache.definitions=this._loadFromStorage(this._storageKeys.definitions,{}),Object.values(this._cache.definitions).forEach(e=>{(0,r.updatePGN)(e)})),this._cache.definitions},get lookups(){return null===this._cache.lookups&&(this._cache.lookups=this._loadFromStorage(this._storageKeys.lookups,{}),Object.values(this._cache.lookups).forEach(e=>{(0,r.updateLookup)(e)})),this._cache.lookups},get bitLookups(){return null===this._cache.bitLookups&&(this._cache.bitLookups=this._loadFromStorage(this._storageKeys.bitLookups,{}),Object.values(this._cache.bitLookups).forEach(e=>{(0,r.updateBitLookup)(e)})),this._cache.bitLookups},addDefinition(e){if(!this.hasDefinition(e.Id)){const t=(0,r.getPGNWithId)(e.Id);t&&(this._originals.definitions[e.Id]=t)}this.definitions[e.Id]=e,this._saveToStorage(this._storageKeys.definitions,this.definitions),(0,r.updatePGN)(e),console.log(`Tracked definition change for PGN ID ${e.Id}. Total tracked: ${Object.keys(this.definitions).length}`)},hasDefinition(e){return this.definitions.hasOwnProperty(e)},getDefinition(e){return this.definitions[e]},clearDefinition(e){this.hasDefinition(e)?(delete this.definitions[e],this._saveToStorage(this._storageKeys.definitions,this.definitions),this._originals.definitions[e]?(0,r.updatePGN)(this._originals.definitions[e]):(0,r.removePGN)(this.definitions[e]),console.log(`Removed tracking for PGN ID ${e}. Remaining: ${Object.keys(this.definitions).length}`)):console.warn(`Attempted to clear non-existent PGN ID ${e}`)},addLookup(e){if(e.EnumValues){if(!this.hasLookup(e.Name)){const t=this.getLookup(e.Name);t&&(this._originals.lookups[e.Name]=t)}this.lookups[e.Name]=e,this._saveToStorage(this._storageKeys.lookups,this.lookups),(0,r.updateLookup)(e),console.log(`Tracked change for lookup ${e.Name}`)}else{if(!this.hasBitLookup(e.Name)){const t=this.getBitLookup(e.Name);t&&(this._originals.bitLookups[e.Name]=t)}this.bitLookups[e.Name]=e,this._saveToStorage(this._storageKeys.bitLookups,this.bitLookups),(0,r.updateBitLookup)(e),console.log(`Tracked change for bit lookup ${e.Name}`)}},hasLookup(e){return this.lookups.hasOwnProperty(e)},hasBitLookup(e){return this.bitLookups.hasOwnProperty(e)},getLookup(e){return this.lookups[e]},getBitLookup(e){return this.bitLookups[e]},getChangedDefinitions(){return new Set(Object.keys(this.definitions))},getLookups(){return Object.values(this.lookups)},getBitLookups(){return Object.values(this.bitLookups)},getChangedLookups(){return{lookups:new Set(Object.keys(this.lookups)),bitLookups:new Set(Object.keys(this.bitLookups))}},getAllChanges(){return{definitions:this.getChangedDefinitions(),...this.getChangedLookups()}},clearLookup(e,t){if("lookup"===t){if(!this.lookups.hasOwnProperty(e))return void console.warn(`Attempted to clear non-existent lookup ${e}`);(0,r.removeLookup)(this.lookups[e]),delete this.lookups[e],this._saveToStorage(this._storageKeys.lookups,this.lookups),this._originals.lookups[e]&&(0,r.updateLookup)(this._originals.lookups[e])}else{if(!this.bitLookups.hasOwnProperty(e))return void console.warn(`Attempted to clear non-existent bit lookup ${e}`);(0,r.removeBitLookup)(this.bitLookups[e]),delete this.bitLookups[e],this._saveToStorage(this._storageKeys.bitLookups,this.bitLookups),this._originals.bitLookups[e]&&(0,r.updateBitLookup)(this._originals.bitLookups[e])}},clearAllDefinitions(){this._cache.definitions={},this._saveToStorage(this._storageKeys.definitions,{}),console.log("Cleared all tracked definition changes")},clearAllLookups(){this._cache.lookups={},this._saveToStorage(this._storageKeys.lookups,{}),console.log("Cleared all tracked lookup changes")},clearAllBitLookups(){this._cache.bitLookups={},this._saveToStorage(this._storageKeys.bitLookups,{}),console.log("Cleared all tracked bit lookup changes")},clearAll(){this._cache.definitions={},this._cache.lookups={},this._cache.bitLookups={},this._saveToStorage(this._storageKeys.definitions,{}),this._saveToStorage(this._storageKeys.lookups,{}),this._saveToStorage(this._storageKeys.bitLookups,{}),console.log("Cleared all tracked changes")}},t.saveDefinition=(e,s)=>{let n=s?.getDefinition();if(void 0!==s&&(e.sampleData=s.input),void 0!==n&&t.changedDefinitionsTracker.hasDefinition(n.Id))n.Id!==e.Id&&(t.changedDefinitionsTracker.clearDefinition(n.Id),(0,r.removePGN)(n)),t.changedDefinitionsTracker.addDefinition(e);else{const n={...JSON.parse(JSON.stringify(e)),PGN:e.PGN};((e,t)=>{if(e.Fallback){const s=t?.pgn||e.PGN;if(e.Fallback=!1,e.Description=`My ${s}`,e.Id=`my${s}`,e.Explanation=void 0,t){e.Fields.length>0&&"manufacturerCode"===e.Fields[0].Id&&(e.Fields[0].Match=r.ManufacturerCodeValues[t.fields.manufacturerCode]||void 0,e.Description=`${t.fields.manufacturerCode}: ${s}`,e.Id=(0,h.toCamelCase)(e.Description)),e.Fields.length>2&&"industryCode"===e.Fields[2].Id&&(e.Fields[2].Match=r.IndustryCodeValues[t.fields.industryCode]||void 0);const n=t.partialMatch;if(n){const s=(0,r.getPGNWithId)(n),a="data"===e.Fields[e.Fields.length-1].Id,i=a?e.Fields.length-1:e.Fields.length;a&&(e.Fields=e.Fields.slice(0,i));for(let n=i;n<s.Fields.length;n++){const a=s.Fields[n],i=t.fields[a.Id];if(void 0!==i){const t={...a};void 0!==a.Match&&a.LookupEnumeration&&(t.Match="string"==typeof i?(0,r.getEnumerationValue)(a.LookupEnumeration,i):i),e.Fields.push(t)}}}}}})(n,s),t.changedDefinitionsTracker.addDefinition(n),e=n}return e};const y=new o.FromPgn({returnNulls:!0,checkForInvalidFields:!0,useCamel:!0,useCamelCompat:!1,returnNonMatches:!0,createPGNObjects:!0,includeInputData:!0,includeRawData:!0,includeByteMapping:!0});y.on("error",(e,t)=>{console.error(`Error parsing ${e.pgn} ${t}`)}),t.default=({isEmbedded:e=!1,deviceInfo:s})=>{const[n,r]=(0,i.useState)(f),[o]=(0,i.useState)(new p.ReplaySubject),[h]=(0,i.useState)(new p.ReplaySubject),[g,v]=(0,i.useState)(null),[N,S]=(0,i.useState)(0),[k,w]=(0,i.useState)(null),[C,F]=(0,i.useState)([]),[T,P]=(0,i.useState)(""),R=(0,x.useObservableState)(o,void 0),I=e=>{r(e)},E=(e,t)=>{v(e);const s=t.sampleData;let n;if(s&&s.length>0)for(const e of s)n=y.parseString(e);else n={getDefinition:()=>t};n?(o.next(n),h.next({current:n,history:[]})):console.error(`Failed to parse PGN data for definition ID ${e}`)},O=e=>{(0,t.saveDefinition)(e,R),S(e=>e+1),E(e.Id,e)},L=()=>{v(null),h.next(null)},D=e=>{t.changedDefinitionsTracker.addLookup(e),S(e=>e+1)},B=(e,t,s)=>{if(!e&&0===s.length)return F([{key:"0",value:"Unknown"},{key:"1",value:"Value1"},{key:"2",value:"Value2"}]),P(""),void w({enumName:"",type:t});F(s),P(e||""),w({enumName:e,type:t})},A=()=>{w(null),F([]),P("")},_=(e,t,s)=>{F(n=>n.map((n,a)=>a===e?{key:t,value:s}:n))},z=e=>{t.changedDefinitionsTracker.addLookup(e),S(e=>e+1)};return(0,a.jsxs)(l.Container,{fluid:!0,children:[(0,a.jsx)(l.Card,{children:(0,a.jsxs)(l.CardBody,{children:[(0,a.jsxs)("div",{className:"mb-3",children:[(0,a.jsx)("h4",{children:"PGN Definition Editor"}),(0,a.jsx)("p",{className:"text-muted",children:"Edit and manage PGN definitions, Lookups, and BitLookups for NMEA 2000 data interpretation."})]}),(0,a.jsxs)(l.Nav,{tabs:!0,className:"mb-3",children:[(0,a.jsx)(l.NavItem,{children:(0,a.jsx)(l.NavLink,{className:n===f?"active":"",onClick:()=>I(f),style:{cursor:"pointer"},children:"PGN Definitions"})}),(0,a.jsx)(l.NavItem,{children:(0,a.jsx)(l.NavLink,{className:n===j?"active":"",onClick:()=>I(j),style:{cursor:"pointer"},children:"Lookups"})}),(0,a.jsx)(l.NavItem,{children:(0,a.jsx)(l.NavLink,{className:n===b?"active":"",onClick:()=>I(b),style:{cursor:"pointer"},children:"Bit Lookups"})})]}),(0,a.jsxs)(l.TabContent,{activeTab:n,children:[(0,a.jsxs)(l.TabPane,{tabId:f,children:[(0,a.jsx)(l.Row,{className:"mb-3",children:(0,a.jsx)(l.Col,{md:"12",children:(0,a.jsx)(l.Card,{children:(0,a.jsxs)(l.CardBody,{children:[(0,a.jsxs)("div",{className:"d-flex justify-content-between align-items-center mb-3",children:[(0,a.jsx)("h5",{className:"mb-0",children:"Changed PGN Definitions"}),(0,a.jsx)(l.Button,{color:"secondary",size:"sm",onClick:()=>{t.changedDefinitionsTracker.clearAllDefinitions(),S(e=>e+1),L()},disabled:0===Object.keys(t.changedDefinitionsTracker.definitions).length,children:"Clear All"})]}),0===Object.keys(t.changedDefinitionsTracker.definitions).length?(0,a.jsxs)("div",{className:"text-muted text-center p-4",children:[(0,a.jsx)("p",{children:"No changed definitions"}),(0,a.jsx)("small",{children:"Modified PGN definitions will appear here"})]}):(0,a.jsx)("div",{style:{width:"100%",height:"200px",overflow:"auto",display:"flex",flexDirection:"column"},children:(0,a.jsxs)(l.Table,{responsive:!0,bordered:!0,size:"sm",children:[(0,a.jsx)("thead",{children:(0,a.jsxs)("tr",{children:[(0,a.jsx)("th",{children:"PGN"}),(0,a.jsx)("th",{children:"Description"}),(0,a.jsx)("th",{style:{width:"50px"}})]})}),(0,a.jsx)("tbody",{children:Object.entries(t.changedDefinitionsTracker.definitions).sort(([,e],[,t])=>e.PGN-t.PGN).map(([e,s],n)=>{const i=n%2==0;return(0,a.jsxs)("tr",{style:{backgroundColor:g===e?"#d1ecf1":i?"#ffffff":"rgba(0,0,0,.05)",cursor:"pointer"},onClick:()=>E(e,s),children:[(0,a.jsx)("td",{style:{color:"red",fontWeight:"bold"},children:s.PGN}),(0,a.jsx)("td",{style:{fontFamily:"monospace"},children:s.Description}),(0,a.jsx)("td",{style:{textAlign:"center"},children:(0,a.jsx)(l.Button,{color:"danger",size:"sm",outline:!0,onClick:s=>{s.stopPropagation(),(e=>{t.changedDefinitionsTracker.clearDefinition(e),S(e=>e+1),g===e&&L()})(e)},title:"Remove from changed list",style:{lineHeight:1,padding:"0.125rem 0.375rem"},children:"×"})})]},e)})})]})})]})})})}),(0,a.jsxs)(l.Row,{children:[(0,a.jsx)(l.Col,{md:"6",children:(0,a.jsx)(l.Card,{style:{height:"calc(100vh - 400px)",minHeight:"800px"},children:(0,a.jsx)(l.CardBody,{style:{height:"100%",overflow:"hidden",padding:0},children:g&&R?(0,a.jsx)(d.PgnDefinitionTab,{definition:t.changedDefinitionsTracker.getDefinition(g),pgnData:R,onSave:O,hasBeenChanged:!0,changedLookups:t.changedDefinitionsTracker.getChangedLookups()}):(0,a.jsxs)("div",{className:"text-center text-muted p-4",style:{height:"100%",display:"flex",flexDirection:"column",justifyContent:"center"},children:[(0,a.jsx)("h5",{children:"PGN Definition Structure"}),(0,a.jsx)("p",{children:"Select a PGN definition from the list above to view its field structure and properties here."}),(0,a.jsxs)("div",{className:"text-start",children:[(0,a.jsx)("h6",{children:"This panel will show:"}),(0,a.jsxs)("ul",{className:"list-unstyled",children:[(0,a.jsx)("li",{children:"✓ Field definitions and properties"}),(0,a.jsx)("li",{children:"✓ Data types and units"}),(0,a.jsx)("li",{children:"✓ Enumeration mappings"}),(0,a.jsx)("li",{children:"✓ Field editing capabilities"})]})]})]})})})}),(0,a.jsx)(l.Col,{md:"6",children:(0,a.jsx)(l.Card,{style:{height:"calc(100vh - 400px)",minHeight:"800px"},children:(0,a.jsx)(l.CardBody,{style:{height:"100%",overflow:"hidden",padding:0},children:g?(0,a.jsx)(c.SentencePanel,{selectedPgn:o,selectedPgnWithHistory:h,definition:t.changedDefinitionsTracker.getDefinition(g),onDefinitionSave:O,info:s||new p.ReplaySubject,inEditingTab:!0}):(0,a.jsxs)("div",{className:"text-center text-muted p-4",style:{height:"100%",display:"flex",flexDirection:"column",justifyContent:"center"},children:[(0,a.jsx)("h5",{children:"PGN Data Analysis"}),(0,a.jsx)("p",{children:"Select a PGN definition from the list above to view parsed data and analysis here."}),(0,a.jsxs)("div",{className:"text-start",children:[(0,a.jsx)("h6",{children:"This panel will show:"}),(0,a.jsxs)("ul",{className:"list-unstyled",children:[(0,a.jsx)("li",{children:"✓ Parsed PGN data values"}),(0,a.jsx)("li",{children:"✓ Raw data interpretation"}),(0,a.jsx)("li",{children:"✓ Field-by-field analysis"}),(0,a.jsx)("li",{children:"✓ Data validation results"})]})]})]})})})})]})]}),(0,a.jsx)(l.TabPane,{tabId:j,children:(0,a.jsx)(m.default,{changedLookups:t.changedDefinitionsTracker.lookups,onLookupChange:D,onLookupRemove:e=>{t.changedDefinitionsTracker.clearLookup(e,"lookup"),S(e=>e+1)},onClearAll:()=>{t.changedDefinitionsTracker.clearAllLookups(),S(e=>e+1)},onLookupEdit:B},`lookups-${N}`)}),(0,a.jsx)(l.TabPane,{tabId:b,children:(0,a.jsx)(u.default,{changedBitLookups:t.changedDefinitionsTracker.bitLookups,onBitLookupChange:z,onBitLookupRemove:e=>{t.changedDefinitionsTracker.clearLookup(e,"bitlookup"),S(e=>e+1)},onClearAll:()=>{t.changedDefinitionsTracker.clearAllBitLookups(),S(e=>e+1)},onBitLookupEdit:B},`bitlookups-${N}`)})]})]})}),(0,a.jsxs)(l.Modal,{isOpen:!!k,toggle:A,size:"lg",children:[(0,a.jsxs)(l.ModalHeader,{toggle:A,children:[k?.enumName?"Edit":"Create"," ","lookup"===k?.type?"Lookup":"Bit Lookup"," ","Enumeration",k?.enumName&&k.enumName===T&&(0,a.jsxs)("div",{className:"small text-muted",children:["Current lookup: ",k.enumName]})]}),(0,a.jsxs)(l.ModalBody,{children:[k&&(0,a.jsxs)("div",{className:"mb-3",children:[(0,a.jsxs)("label",{className:"form-label",children:["lookup"===k.type?"Lookup":"Bit Lookup"," Name"]}),(0,a.jsx)(l.Input,{type:"text",placeholder:`Enter ${"lookup"===k.type?"lookup":"bit lookup"} name`,value:T,onChange:e=>P(e.target.value)}),k.enumName&&k.enumName!==T&&(0,a.jsxs)("div",{className:"small text-muted mt-1",children:["Original name: ",k.enumName]})]}),(0,a.jsxs)("div",{className:"d-flex justify-content-between align-items-center mb-3",children:[(0,a.jsx)("h6",{children:"Lookup Values"}),(0,a.jsxs)(l.Button,{color:"success",size:"sm",onClick:()=>{F(e=>[...e,{key:e.length.toString(),value:`Value${e.length}`}])},children:[(0,a.jsx)("i",{className:"fa fa-plus me-2"}),"Add Value"]})]}),(0,a.jsx)("div",{className:"table-responsive",style:{maxHeight:"400px",overflowY:"auto"},children:(0,a.jsxs)(l.Table,{size:"sm",bordered:!0,children:[(0,a.jsx)("thead",{children:(0,a.jsxs)("tr",{children:[(0,a.jsx)("th",{style:{width:"120px"},children:"Key/Value"}),(0,a.jsx)("th",{children:"Name/Description"}),(0,a.jsx)("th",{style:{width:"80px"},children:"Actions"})]})}),(0,a.jsx)("tbody",{children:C.map((e,t)=>(0,a.jsxs)("tr",{children:[(0,a.jsx)("td",{children:(0,a.jsx)(l.Input,{type:"bitlookup"===k?.type?"text":"number",size:"sm",value:e.key,onChange:s=>_(t,s.target.value,e.value),placeholder:"bitlookup"===k?.type?"0x01":"0"})}),(0,a.jsx)("td",{children:(0,a.jsx)(l.Input,{type:"text",size:"sm",value:e.value,onChange:s=>_(t,e.key,s.target.value),placeholder:"Value name"})}),(0,a.jsx)("td",{className:"text-center",children:(0,a.jsx)(l.Button,{color:"danger",size:"sm",onClick:()=>(e=>{F(t=>t.filter((t,s)=>s!==e))})(t),title:"Remove value",children:(0,a.jsx)("i",{className:"fa fa-trash"})})})]},t))})]})}),0===C.length&&(0,a.jsxs)("div",{className:"text-center text-muted p-4",children:[(0,a.jsx)("i",{className:"fa fa-info-circle me-2"}),'No lookup values defined. Click "Add Value" to start.']})]}),(0,a.jsxs)(l.ModalFooter,{children:[(0,a.jsxs)(l.Button,{color:"primary",onClick:()=>{if(!k)return;const e=T.trim();if(!e)return void alert("Please enter a name for the lookup");const s=k.enumName&&k.enumName!==e;if("lookup"===k.type){s&&t.changedDefinitionsTracker.clearLookup(k.enumName,"lookup");const n={Name:e,MaxValue:255,EnumValues:C.map(e=>({Value:parseInt(e.key)||0,Name:e.value})).sort((e,t)=>e.Value-t.Value)};D(n)}else if("bitlookup"===k.type){s&&t.changedDefinitionsTracker.clearLookup(k.enumName,"bitlookup");const n={Name:e,MaxValue:255,EnumBitValues:C.map(e=>({Bit:parseInt(e.key)||0,Name:e.value})).sort((e,t)=>e.Bit-t.Bit)};z(n)}A()},children:[(0,a.jsx)("i",{className:"fa fa-save me-2"}),"Save Lookup"]}),(0,a.jsx)(l.Button,{color:"secondary",onClick:A,children:"Cancel"})]})]})]})}},35020:(e,t,s)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.DeviceInfoTab=void 0;const n=s(74848),a=s(57592);t.DeviceInfoTab=({pgnData:e,info:t})=>{const s=(e,t)=>{try{const s=e.getDefinition();if(s&&s.Fields){const e=s.Fields.find(e=>e.Id===t||e.Name===t);if(e&&e.Name)return e.Name}}catch(e){console.error("Error getting field display name:",e)}return"unknon"};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(a.CardHeader,{children:(0,n.jsxs)("small",{children:[(0,n.jsx)("strong",{children:"PGN:"})," ",e.pgn," |",(0,n.jsx)("strong",{children:" Source:"})," ",e.src," |",(0,n.jsx)("strong",{children:" Destination:"})," ",e.dst,(0,n.jsx)("br",{}),(0,n.jsx)("strong",{children:"Description:"})," ",e.description||"N/A"]})}),(0,n.jsx)("div",{className:"p-3",children:t[e.src]?.info?(0,n.jsx)("div",{children:Object.entries(t[e.src].info).map(([e,t])=>(0,n.jsxs)(a.Card,{className:"mb-3",style:{border:"1px solid #e0e0e0"},children:[(0,n.jsx)(a.CardHeader,{style:{backgroundColor:"#f8f9fa",padding:"10px 15px"},children:(0,n.jsxs)("h6",{className:"mb-0",style:{color:"#495057"},children:["PGN ",e,": ",t.description||"Unknown"]})}),(0,n.jsx)(a.CardBody,{style:{padding:"15px"},children:(0,n.jsx)("div",{className:"row",children:Object.entries(t.fields).filter(([e])=>"description"!==e).map(([e,a])=>(0,n.jsx)("div",{className:"col-12 mb-2",children:(0,n.jsxs)("div",{style:{display:"flex",alignItems:"flex-start"},children:[(0,n.jsxs)("strong",{style:{minWidth:"200px",marginRight:"15px",color:"#6c757d",textTransform:"capitalize",flexShrink:0},children:[s(t,e),":"]}),(0,n.jsx)("span",{style:{wordBreak:"break-word",color:"#212529",flex:1},children:a})]})},e))})})]},e))}):(0,n.jsx)("div",{style:{textAlign:"center",color:"#6c757d",padding:"40px",fontStyle:"italic"},children:"No device information available for this source"})})]})}},35358:(e,t,s)=>{var n={"./af":25177,"./af.js":25177,"./ar":61509,"./ar-dz":41488,"./ar-dz.js":41488,"./ar-kw":58676,"./ar-kw.js":58676,"./ar-ly":42353,"./ar-ly.js":42353,"./ar-ma":24496,"./ar-ma.js":24496,"./ar-ps":6947,"./ar-ps.js":6947,"./ar-sa":82682,"./ar-sa.js":82682,"./ar-tn":89756,"./ar-tn.js":89756,"./ar.js":61509,"./az":95533,"./az.js":95533,"./be":28959,"./be.js":28959,"./bg":47777,"./bg.js":47777,"./bm":54903,"./bm.js":54903,"./bn":61290,"./bn-bd":17357,"./bn-bd.js":17357,"./bn.js":61290,"./bo":31545,"./bo.js":31545,"./br":11470,"./br.js":11470,"./bs":44429,"./bs.js":44429,"./ca":7306,"./ca.js":7306,"./cs":56464,"./cs.js":56464,"./cv":73635,"./cv.js":73635,"./cy":64226,"./cy.js":64226,"./da":93601,"./da.js":93601,"./de":77853,"./de-at":26111,"./de-at.js":26111,"./de-ch":54697,"./de-ch.js":54697,"./de.js":77853,"./dv":60708,"./dv.js":60708,"./el":54691,"./el.js":54691,"./en-au":53872,"./en-au.js":53872,"./en-ca":28298,"./en-ca.js":28298,"./en-gb":56195,"./en-gb.js":56195,"./en-ie":66584,"./en-ie.js":66584,"./en-il":65543,"./en-il.js":65543,"./en-in":9033,"./en-in.js":9033,"./en-nz":79402,"./en-nz.js":79402,"./en-sg":43004,"./en-sg.js":43004,"./eo":32934,"./eo.js":32934,"./es":97650,"./es-do":20838,"./es-do.js":20838,"./es-mx":17730,"./es-mx.js":17730,"./es-us":56575,"./es-us.js":56575,"./es.js":97650,"./et":3035,"./et.js":3035,"./eu":3508,"./eu.js":3508,"./fa":119,"./fa.js":119,"./fi":90527,"./fi.js":90527,"./fil":95995,"./fil.js":95995,"./fo":52477,"./fo.js":52477,"./fr":85498,"./fr-ca":26435,"./fr-ca.js":26435,"./fr-ch":37892,"./fr-ch.js":37892,"./fr.js":85498,"./fy":37071,"./fy.js":37071,"./ga":41734,"./ga.js":41734,"./gd":70217,"./gd.js":70217,"./gl":77329,"./gl.js":77329,"./gom-deva":32124,"./gom-deva.js":32124,"./gom-latn":93383,"./gom-latn.js":93383,"./gu":95050,"./gu.js":95050,"./he":11713,"./he.js":11713,"./hi":43861,"./hi.js":43861,"./hr":26308,"./hr.js":26308,"./hu":90609,"./hu.js":90609,"./hy-am":17160,"./hy-am.js":17160,"./id":74063,"./id.js":74063,"./is":89374,"./is.js":89374,"./it":88383,"./it-ch":21827,"./it-ch.js":21827,"./it.js":88383,"./ja":23827,"./ja.js":23827,"./jv":89722,"./jv.js":89722,"./ka":41794,"./ka.js":41794,"./kk":27088,"./kk.js":27088,"./km":96870,"./km.js":96870,"./kn":84451,"./kn.js":84451,"./ko":63164,"./ko.js":63164,"./ku":98174,"./ku-kmr":6181,"./ku-kmr.js":6181,"./ku.js":98174,"./ky":78474,"./ky.js":78474,"./lb":79680,"./lb.js":79680,"./lo":15867,"./lo.js":15867,"./lt":45766,"./lt.js":45766,"./lv":69532,"./lv.js":69532,"./me":58076,"./me.js":58076,"./mi":41848,"./mi.js":41848,"./mk":30306,"./mk.js":30306,"./ml":73739,"./ml.js":73739,"./mn":99053,"./mn.js":99053,"./mr":86169,"./mr.js":86169,"./ms":73386,"./ms-my":92297,"./ms-my.js":92297,"./ms.js":73386,"./mt":77075,"./mt.js":77075,"./my":72264,"./my.js":72264,"./nb":22274,"./nb.js":22274,"./ne":8235,"./ne.js":8235,"./nl":92572,"./nl-be":43784,"./nl-be.js":43784,"./nl.js":92572,"./nn":54566,"./nn.js":54566,"./oc-lnc":69330,"./oc-lnc.js":69330,"./pa-in":29849,"./pa-in.js":29849,"./pl":94418,"./pl.js":94418,"./pt":79834,"./pt-br":48303,"./pt-br.js":48303,"./pt.js":79834,"./ro":24457,"./ro.js":24457,"./ru":82271,"./ru.js":82271,"./sd":1221,"./sd.js":1221,"./se":33478,"./se.js":33478,"./si":17538,"./si.js":17538,"./sk":5784,"./sk.js":5784,"./sl":46637,"./sl.js":46637,"./sq":86794,"./sq.js":86794,"./sr":45719,"./sr-cyrl":3322,"./sr-cyrl.js":3322,"./sr.js":45719,"./ss":56e3,"./ss.js":56e3,"./sv":41011,"./sv.js":41011,"./sw":40748,"./sw.js":40748,"./ta":11025,"./ta.js":11025,"./te":11885,"./te.js":11885,"./tet":28861,"./tet.js":28861,"./tg":86571,"./tg.js":86571,"./th":55802,"./th.js":55802,"./tk":59527,"./tk.js":59527,"./tl-ph":29231,"./tl-ph.js":29231,"./tlh":31052,"./tlh.js":31052,"./tr":85096,"./tr.js":85096,"./tzl":79846,"./tzl.js":79846,"./tzm":81765,"./tzm-latn":97711,"./tzm-latn.js":97711,"./tzm.js":81765,"./ug-cn":48414,"./ug-cn.js":48414,"./uk":16618,"./uk.js":16618,"./ur":57777,"./ur.js":57777,"./uz":57609,"./uz-latn":72475,"./uz-latn.js":72475,"./uz.js":57609,"./vi":21135,"./vi.js":21135,"./x-pseudo":64051,"./x-pseudo.js":64051,"./yo":82218,"./yo.js":82218,"./zh-cn":52648,"./zh-cn.js":52648,"./zh-hk":1632,"./zh-hk.js":1632,"./zh-mo":31541,"./zh-mo.js":31541,"./zh-tw":50304,"./zh-tw.js":50304};function a(e){var t=i(e);return s(t)}function i(e){if(!s.o(n,e)){var t=new Error("Cannot find module '"+e+"'");throw t.code="MODULE_NOT_FOUND",t}return n[e]}a.keys=function(){return Object.keys(n)},a.resolve=i,e.exports=a,a.id=35358},40002:function(e,t,s){"use strict";var n=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(t,"__esModule",{value:!0}),t.FilterPanel=t.filterFor=t.getFilterConfig=void 0;const a=s(74848),i=s(44823),l=s(57592),r=s(54970),o=n(s(33501)),c=s(20261),d=s(95094);t.getFilterConfig=e=>{const t=e?.pgn?.map(e=>isNaN(Number(e))?null:Number(e)).filter(e=>null!==e),s=e?.pgn?.map(e=>isNaN(Number(e))?e:null).filter(e=>null!==e);return(0,d.setupFilters)({pgn:t,id:s,src:e?.src,dst:e?.dst,manufacturer:e?.manufacturer,filter:e?.javaScript})},t.filterFor=(e,t)=>e&&void 0!==t?e=>(0,d.filterPGN)(e,t):()=>!0;const m=(0,c.getAllPGNs)().filter(e=>void 0===e.Fallback||!1===e.Fallback).map(e=>({value:e.Id,label:`${e.PGN} ${e.Description}`})),u=m.reduce((e,t)=>(e[t.value]=t,e),{}),h=Object.values(c.ManufacturerCode).sort().map(e=>({value:e,label:e})),p=e=>u[e]||{value:e,label:e},g=(e,t)=>{const s=t?.[e]?.info[126996]?.fields.modelId,n=t?.[e]?.info[60928]?.fields.manufacturerCode;return{value:e,label:`${e} ${s?"("+s+")":""} ${n?"["+n+"]":""}`}},x=(e,t)=>{const s=t?.[e]?.info[126996]?.fields.modelId,n=t?.[e]?.info[60928]?.fields.manufacturerCode;return{value:e,label:`${e} ${s?"("+s+")":""} ${n?"["+n+"]":""}`}},f=e=>({value:e,label:e}),j="visual_analyzer_filter_panel_state",b="visual_analyzer_options_panel_state",y=({filterOptions:e,onFilterOptionsChange:t})=>{const[s,n]=(0,i.useState)(()=>{try{if("undefined"!=typeof window&&window.localStorage){const e=window.localStorage.getItem(b);return null!==e&&JSON.parse(e)}}catch(e){console.warn("Failed to load options panel state from localStorage:",e)}return!1});return(0,i.useEffect)(()=>{try{"undefined"!=typeof window&&window.localStorage&&window.localStorage.setItem(b,JSON.stringify(s))}catch(e){console.warn("Failed to save options panel state to localStorage:",e)}},[s]),(0,a.jsxs)(l.Card,{children:[(0,a.jsxs)(l.CardHeader,{className:"d-flex justify-content-between align-items-center py-2",style:{cursor:"pointer"},children:[(0,a.jsx)("div",{className:"d-flex align-items-center flex-grow-1",onClick:()=>n(!s),children:(0,a.jsx)("h6",{className:"mb-0",style:{fontWeight:"bold"},children:"Options"})}),(0,a.jsxs)("div",{className:"d-flex align-items-center",children:[(0,a.jsx)("span",{style:{fontSize:"14px",fontWeight:"500",marginRight:"8px"},children:"Pause Updates"}),(0,a.jsxs)(l.Label,{className:"switch switch-text switch-primary mb-0 me-3",children:[(0,a.jsx)(l.Input,{type:"checkbox",id:"pauseUpdates",name:"pauseUpdates",className:"switch-input",onChange:s=>{s.stopPropagation(),t.next({...e,pauseUpdates:s.target.checked})},checked:e?.pauseUpdates??!1,onClick:e=>e.stopPropagation()}),(0,a.jsx)("span",{className:"switch-label","data-on":"On","data-off":"Off"}),(0,a.jsx)("span",{className:"switch-handle"})]}),(0,a.jsx)(l.Button,{color:"outline-primary",size:"sm",style:{border:"none",fontSize:"16px",padding:"2px 6px"},onClick:e=>{e.stopPropagation(),n(!s)},children:s?"−":"+"})]})]}),(0,a.jsx)(l.Collapse,{isOpen:s,children:(0,a.jsxs)(l.CardBody,{children:[(0,a.jsxs)(l.Row,{children:[(0,a.jsx)(l.Col,{xs:"12",md:"6",className:"mb-2",children:(0,a.jsxs)(l.Label,{className:"d-flex align-items-center",style:{cursor:"pointer"},children:[(0,a.jsx)(l.Input,{type:"checkbox",className:"me-2",checked:e?.showInfoPgns??!1,onChange:s=>{t.next({...e,showInfoPgns:s.target.checked})}}),(0,a.jsx)("span",{children:"Show Info PGNs"})]})}),(0,a.jsx)(l.Col,{xs:"12",md:"6",className:"mb-2",children:(0,a.jsxs)(l.Label,{className:"d-flex align-items-center",style:{cursor:"pointer"},children:[(0,a.jsx)(l.Input,{type:"checkbox",className:"me-2",checked:e?.showUnknownProprietaryPGNsOnSeparateLines??!1,onChange:s=>{t.next({...e,showUnknownProprietaryPGNsOnSeparateLines:s.target.checked})}}),(0,a.jsx)("span",{children:"Show Unknown Proprietary PGNs On Separate Lines"})]})}),(0,a.jsx)(l.Col,{xs:"12",md:"6",className:"mb-2",children:(0,a.jsxs)(l.Label,{className:"d-flex align-items-center",style:{cursor:"pointer"},children:[(0,a.jsx)(l.Input,{type:"checkbox",className:"me-2",checked:e?.showPgn126208OnSeparateLines??!1,onChange:s=>{t.next({...e,showPgn126208OnSeparateLines:s.target.checked})}}),(0,a.jsx)("span",{children:"Show PGN 126208 On Separate Lines"})]})}),(0,a.jsx)(l.Col,{xs:"12",md:"6",className:"mb-2",children:(0,a.jsxs)(l.Label,{className:"d-flex align-items-center",style:{cursor:"pointer"},children:[(0,a.jsx)(l.Input,{type:"checkbox",className:"me-2",checked:e?.showAISOnSeparateLines??!1,onChange:s=>{t.next({...e,showAISOnSeparateLines:s.target.checked})}}),(0,a.jsx)("span",{children:"Show AIS Messages On Separate Lines"})]})})]}),(0,a.jsx)(l.Row,{children:(0,a.jsx)(l.Col,{xs:"12",md:"6",className:"mb-2",children:(0,a.jsxs)(l.Label,{className:"d-block",style:{cursor:"default"},children:[(0,a.jsx)("span",{className:"mb-2 d-block",children:"Max History Size per PGN"}),(0,a.jsx)(l.Input,{type:"number",min:"0",max:"1000",value:e?.maxHistorySize??10,onChange:s=>{const n=parseInt(s.target.value,10);t.next({...e,maxHistorySize:isNaN(n)?10:Math.max(0,Math.min(1e3,n))})},style:{width:"100px"}}),(0,a.jsx)("small",{className:"text-muted d-block mt-1",children:"Set to 0 to disable history tracking. History stores previous values of each PGN allowing you to see changes over time by expanding rows with the chevron icon."})]})})})]})})]})};t.FilterPanel=e=>{const[t,s]=(0,i.useState)(()=>{try{if("undefined"!=typeof window&&window.localStorage){const e=window.localStorage.getItem(j);return!!e&&JSON.parse(e)}}catch(e){return!1}return!1}),n=(0,r.useObservableState)(e.filter),c=(0,r.useObservableState)(e.availableSrcs),d=(0,r.useObservableState)(e.deviceInfo),u=(0,r.useObservableState)(e.doFiltering),b=(0,r.useObservableState)(e.filterOptions);return(0,i.useEffect)(()=>{try{"undefined"!=typeof window&&window.localStorage&&window.localStorage.setItem(j,JSON.stringify(t))}catch(e){console.warn("Failed to save filter panel state to localStorage:",e)}},[t]),(0,a.jsxs)(a.Fragment,{children:[(0,a.jsxs)(l.Card,{className:"mb-3",children:[(0,a.jsxs)(l.CardHeader,{className:"d-flex justify-content-between align-items-center py-2",style:{cursor:"pointer"},children:[(0,a.jsx)("div",{className:"d-flex align-items-center flex-grow-1",onClick:()=>s(!t),children:(0,a.jsx)("h6",{className:"mb-0",style:{fontWeight:"bold"},children:"Filters"})}),(0,a.jsxs)("div",{class