@memoarchitect/architect 0.4.6 → 0.6.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (58) hide show
  1. package/README.md +44 -3
  2. package/dist/assets/AskPanel-Dqc6aaqg.js +1 -0
  3. package/dist/assets/ComplianceWizard-Bi9PLmJH.js +1 -0
  4. package/dist/assets/{DSMView-B4IEz19F.js → DSMView-DbC_fUKT.js} +1 -1
  5. package/dist/assets/{Dashboard-DNRzU1Hk.js → Dashboard-6Dgma4kY.js} +1 -1
  6. package/dist/assets/DhfDashboard-BPXIYJnw.js +1 -0
  7. package/dist/assets/{DhfSettingsPanel-C89T0dv7.js → DhfSettingsPanel-jQ5mh_50.js} +1 -1
  8. package/dist/assets/{DhfWorkbench-4gHayn-l.js → DhfWorkbench-CgFdQIts.js} +3 -3
  9. package/dist/assets/DiagramCanvas-CIfN1ybl.js +1 -0
  10. package/dist/assets/DiagramEditor-Y4sSx9nO.js +4 -0
  11. package/dist/assets/ElementDetailView-B946aM3p.js +2 -0
  12. package/dist/assets/{ImportView-t1dIoZF5.js → ImportView-HCDzL9Xx.js} +1 -1
  13. package/dist/assets/{LayerGrid-fSGvqSEj.js → LayerGrid-DSxAFwPk.js} +1 -1
  14. package/dist/assets/{LayerTable-D8QCFY1b.js → LayerTable-C5VBpm6T.js} +2 -2
  15. package/dist/assets/{MaxGraphCanvas-DYs6MPuP.js → MaxGraphCanvas-B7tAFvDf.js} +6 -6
  16. package/dist/assets/{ModelDiff-CLFqnELG.js → ModelDiff-MM5NKKXK.js} +1 -1
  17. package/dist/assets/OntologyDecompositionDiagram-CAzu3z_q.js +1 -0
  18. package/dist/assets/{OntologyViewer-72jTw72H.js → OntologyViewer-C5ik2Kmi.js} +2 -2
  19. package/dist/assets/{RelationshipOverlay-BDrBRSPP.js → RelationshipOverlay-DSzjs5U7.js} +1 -1
  20. package/dist/assets/{RelationshipsSection-D1-tuVYo.js → RelationshipsSection-2CEoiF6o.js} +1 -1
  21. package/dist/assets/{ReviewDashboard-BVOe2I5w.js → ReviewDashboard-DwlsAVBa.js} +1 -1
  22. package/dist/assets/ScenarioEditor-BRWvcD2f.js +3 -0
  23. package/dist/assets/{StatisticsDashboard-Dn6lsnKe.js → StatisticsDashboard-C67W4pb0.js} +1 -1
  24. package/dist/assets/{SysmlCodeEditor-BLcw6hdp.js → SysmlCodeEditor-CGOcUFE7.js} +1 -1
  25. package/dist/assets/SysmlGenerator-BwRhtec-.js +1 -0
  26. package/dist/assets/{TabularView-B99xy3H3.js → TabularView-CTQgMG25.js} +1 -1
  27. package/dist/assets/TraceabilityMatrix-Bw5ej-So.js +1 -0
  28. package/dist/assets/{WorkflowWizard-C38DZKOe.js → WorkflowWizard-BwGWzMkE.js} +1 -1
  29. package/dist/assets/index-D0i9ua6F.js +3277 -0
  30. package/dist/assets/index-DPzXL4uF.css +1 -0
  31. package/dist/assets/{layout-providers-BAUgp0nu.js → layout-providers-BFnfta4Z.js} +13 -13
  32. package/dist/assets/layout-selection-BTId1JyG.js +1 -0
  33. package/dist/assets/{reactflow-WKyu73tD.js → reactflow-CX-HDacK.js} +1 -1
  34. package/dist/index.html +3 -3
  35. package/lib/bin/memo-architect.js +39 -3
  36. package/lib/bin/memo-architect.js.map +1 -1
  37. package/lib/commands/dev.d.ts.map +1 -1
  38. package/lib/commands/dev.js +9 -0
  39. package/lib/commands/dev.js.map +1 -1
  40. package/lib/commands/example.d.ts +16 -0
  41. package/lib/commands/example.d.ts.map +1 -0
  42. package/lib/commands/example.js +143 -0
  43. package/lib/commands/example.js.map +1 -0
  44. package/package.json +5 -4
  45. package/dist/assets/AskPanel-D9_AKyYt.js +0 -1
  46. package/dist/assets/ComplianceWizard-BNvT_ic6.js +0 -1
  47. package/dist/assets/DhfDashboard-DguH-rDT.js +0 -1
  48. package/dist/assets/DiagramCanvas-BgfO0AtP.js +0 -1
  49. package/dist/assets/DiagramEditor-CEr6iqBf.js +0 -4
  50. package/dist/assets/DiagramSurface-B_lfUNzV.js +0 -2
  51. package/dist/assets/ElementDetailView-AclSjurg.js +0 -2
  52. package/dist/assets/OntologyDecompositionDiagram-cpmTTMRH.js +0 -1
  53. package/dist/assets/ScenarioEditor-CvOkiRC6.js +0 -3
  54. package/dist/assets/SysmlGenerator-CfBQWovl.js +0 -1
  55. package/dist/assets/TraceabilityMatrix-BAJb0X7G.js +0 -1
  56. package/dist/assets/index-CgRwea72.js +0 -3277
  57. package/dist/assets/index-CnFhl4_e.css +0 -1
  58. package/dist/assets/layout-selection-BQ2WuAEB.js +0 -1
@@ -1,3277 +0,0 @@
1
- const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/DiagramEditor-CEr6iqBf.js","assets/reactflow-WKyu73tD.js","assets/zustand-qbFpP9Up.js","assets/DiagramSurface-B_lfUNzV.js","assets/DSMView-B4IEz19F.js","assets/OntologyViewer-72jTw72H.js","assets/TraceabilityMatrix-BAJb0X7G.js","assets/ScenarioEditor-CvOkiRC6.js","assets/ModelDiff-CLFqnELG.js","assets/ComplianceWizard-BNvT_ic6.js","assets/StatisticsDashboard-Dn6lsnKe.js","assets/DhfDashboard-DguH-rDT.js","assets/DhfWorkbench-4gHayn-l.js","assets/AskPanel-D9_AKyYt.js","assets/SysmlGenerator-CfBQWovl.js","assets/ElementDetailView-AclSjurg.js","assets/Dashboard-DNRzU1Hk.js","assets/ReviewDashboard-BVOe2I5w.js","assets/WorkflowWizard-C38DZKOe.js","assets/TabularView-B99xy3H3.js","assets/ImportView-t1dIoZF5.js"])))=>i.map(i=>d[i]);
2
- import{r as nr,j as t}from"./reactflow-WKyu73tD.js";import{a as u,c as jn,W as rr}from"./zustand-qbFpP9Up.js";(function(){const r=document.createElement("link").relList;if(r&&r.supports&&r.supports("modulepreload"))return;for(const o of document.querySelectorAll('link[rel="modulepreload"]'))s(o);new MutationObserver(o=>{for(const i of o)if(i.type==="childList")for(const l of i.addedNodes)l.tagName==="LINK"&&l.rel==="modulepreload"&&s(l)}).observe(document,{childList:!0,subtree:!0});function n(o){const i={};return o.integrity&&(i.integrity=o.integrity),o.referrerPolicy&&(i.referrerPolicy=o.referrerPolicy),o.crossOrigin==="use-credentials"?i.credentials="include":o.crossOrigin==="anonymous"?i.credentials="omit":i.credentials="same-origin",i}function s(o){if(o.ep)return;o.ep=!0;const i=n(o);fetch(o.href,i)}})();var We={},Ut;function or(){if(Ut)return We;Ut=1;var e=nr();return We.createRoot=e.createRoot,We.hydrateRoot=e.hydrateRoot,We}var sr=or();/**
3
- * react-router v7.13.2
4
- *
5
- * Copyright (c) Remix Software Inc.
6
- *
7
- * This source code is licensed under the MIT license found in the
8
- * LICENSE.md file in the root directory of this source tree.
9
- *
10
- * @license MIT
11
- */var $t="popstate";function Wt(e){return typeof e=="object"&&e!=null&&"pathname"in e&&"search"in e&&"hash"in e&&"state"in e&&"key"in e}function ir(e={}){function r(s,o){var c;let i=(c=o.state)==null?void 0:c.masked,{pathname:l,search:a,hash:d}=i||s.location;return Et("",{pathname:l,search:a,hash:d},o.state&&o.state.usr||null,o.state&&o.state.key||"default",i?{pathname:s.location.pathname,search:s.location.search,hash:s.location.hash}:void 0)}function n(s,o){return typeof o=="string"?o:Le(o)}return lr(r,n,null,e)}function Q(e,r){if(e===!1||e===null||typeof e>"u")throw new Error(r)}function he(e,r){if(!e){typeof console<"u"&&console.warn(r);try{throw new Error(r)}catch{}}}function ar(){return Math.random().toString(36).substring(2,10)}function Ht(e,r){return{usr:e.state,key:e.key,idx:r,masked:e.unstable_mask?{pathname:e.pathname,search:e.search,hash:e.hash}:void 0}}function Et(e,r,n=null,s,o){return{pathname:typeof e=="string"?e:e.pathname,search:"",hash:"",...typeof r=="string"?Ie(r):r,state:n,key:r&&r.key||s||ar(),unstable_mask:o}}function Le({pathname:e="/",search:r="",hash:n=""}){return r&&r!=="?"&&(e+=r.charAt(0)==="?"?r:"?"+r),n&&n!=="#"&&(e+=n.charAt(0)==="#"?n:"#"+n),e}function Ie(e){let r={};if(e){let n=e.indexOf("#");n>=0&&(r.hash=e.substring(n),e=e.substring(0,n));let s=e.indexOf("?");s>=0&&(r.search=e.substring(s),e=e.substring(0,s)),e&&(r.pathname=e)}return r}function lr(e,r,n,s={}){let{window:o=document.defaultView,v5Compat:i=!1}=s,l=o.history,a="POP",d=null,c=p();c==null&&(c=0,l.replaceState({...l.state,idx:c},""));function p(){return(l.state||{idx:null}).idx}function m(){a="POP";let v=p(),w=v==null?null:v-c;c=v,d&&d({action:a,location:y.location,delta:w})}function x(v,w){a="PUSH";let _=Wt(v)?v:Et(y.location,v,w);c=p()+1;let N=Ht(_,c),f=y.createHref(_.unstable_mask||_);try{l.pushState(N,"",f)}catch(D){if(D instanceof DOMException&&D.name==="DataCloneError")throw D;o.location.assign(f)}i&&d&&d({action:a,location:y.location,delta:1})}function b(v,w){a="REPLACE";let _=Wt(v)?v:Et(y.location,v,w);c=p();let N=Ht(_,c),f=y.createHref(_.unstable_mask||_);l.replaceState(N,"",f),i&&d&&d({action:a,location:y.location,delta:0})}function k(v){return cr(v)}let y={get action(){return a},get location(){return e(o,l)},listen(v){if(d)throw new Error("A history only accepts one active listener");return o.addEventListener($t,m),d=v,()=>{o.removeEventListener($t,m),d=null}},createHref(v){return r(o,v)},createURL:k,encodeLocation(v){let w=k(v);return{pathname:w.pathname,search:w.search,hash:w.hash}},push:x,replace:b,go(v){return l.go(v)}};return y}function cr(e,r=!1){let n="http://localhost";typeof window<"u"&&(n=window.location.origin!=="null"?window.location.origin:window.location.href),Q(n,"No window.location.(origin|href) available to create URL");let s=typeof e=="string"?e:Le(e);return s=s.replace(/ $/,"%20"),!r&&s.startsWith("//")&&(s=n+s),new URL(s,n)}function Dn(e,r,n="/"){return dr(e,r,n,!1)}function dr(e,r,n,s){let o=typeof r=="string"?Ie(r):r,i=ve(o.pathname||"/",n);if(i==null)return null;let l=An(e);ur(l);let a=null;for(let d=0;a==null&&d<l.length;++d){let c=Sr(i);a=vr(l[d],c,s)}return a}function An(e,r=[],n=[],s="",o=!1){let i=(l,a,d=o,c)=>{let p={relativePath:c===void 0?l.path||"":c,caseSensitive:l.caseSensitive===!0,childrenIndex:a,route:l};if(p.relativePath.startsWith("/")){if(!p.relativePath.startsWith(s)&&d)return;Q(p.relativePath.startsWith(s),`Absolute route path "${p.relativePath}" nested under path "${s}" is not valid. An absolute child route path must start with the combined path of all its parent routes.`),p.relativePath=p.relativePath.slice(s.length)}let m=me([s,p.relativePath]),x=n.concat(p);l.children&&l.children.length>0&&(Q(l.index!==!0,`Index routes must not have child routes. Please remove all child routes from route path "${m}".`),An(l.children,r,x,m,d)),!(l.path==null&&!l.index)&&r.push({path:m,score:xr(m,l.index),routesMeta:x})};return e.forEach((l,a)=>{var d;if(l.path===""||!((d=l.path)!=null&&d.includes("?")))i(l,a);else for(let c of Fn(l.path))i(l,a,!0,c)}),r}function Fn(e){let r=e.split("/");if(r.length===0)return[];let[n,...s]=r,o=n.endsWith("?"),i=n.replace(/\?$/,"");if(s.length===0)return o?[i,""]:[i];let l=Fn(s.join("/")),a=[];return a.push(...l.map(d=>d===""?i:[i,d].join("/"))),o&&a.push(...l),a.map(d=>e.startsWith("/")&&d===""?"/":d)}function ur(e){e.sort((r,n)=>r.score!==n.score?n.score-r.score:br(r.routesMeta.map(s=>s.childrenIndex),n.routesMeta.map(s=>s.childrenIndex)))}var pr=/^:[\w-]+$/,mr=3,fr=2,hr=1,gr=10,yr=-2,Kt=e=>e==="*";function xr(e,r){let n=e.split("/"),s=n.length;return n.some(Kt)&&(s+=yr),r&&(s+=fr),n.filter(o=>!Kt(o)).reduce((o,i)=>o+(pr.test(i)?mr:i===""?hr:gr),s)}function br(e,r){return e.length===r.length&&e.slice(0,-1).every((s,o)=>s===r[o])?e[e.length-1]-r[r.length-1]:0}function vr(e,r,n=!1){let{routesMeta:s}=e,o={},i="/",l=[];for(let a=0;a<s.length;++a){let d=s[a],c=a===s.length-1,p=i==="/"?r:r.slice(i.length)||"/",m=rt({path:d.relativePath,caseSensitive:d.caseSensitive,end:c},p),x=d.route;if(!m&&c&&n&&!s[s.length-1].route.index&&(m=rt({path:d.relativePath,caseSensitive:d.caseSensitive,end:!1},p)),!m)return null;Object.assign(o,m.params),l.push({params:o,pathname:me([i,m.pathname]),pathnameBase:jr(me([i,m.pathnameBase])),route:x}),m.pathnameBase!=="/"&&(i=me([i,m.pathnameBase]))}return l}function rt(e,r){typeof e=="string"&&(e={path:e,caseSensitive:!1,end:!0});let[n,s]=wr(e.path,e.caseSensitive,e.end),o=r.match(n);if(!o)return null;let i=o[0],l=i.replace(/(.)\/+$/,"$1"),a=o.slice(1);return{params:s.reduce((c,{paramName:p,isOptional:m},x)=>{if(p==="*"){let k=a[x]||"";l=i.slice(0,i.length-k.length).replace(/(.)\/+$/,"$1")}const b=a[x];return m&&!b?c[p]=void 0:c[p]=(b||"").replace(/%2F/g,"/"),c},{}),pathname:i,pathnameBase:l,pattern:e}}function wr(e,r=!1,n=!0){he(e==="*"||!e.endsWith("*")||e.endsWith("/*"),`Route path "${e}" will be treated as if it were "${e.replace(/\*$/,"/*")}" because the \`*\` character must always follow a \`/\` in the pattern. To get rid of this warning, please change the route path to "${e.replace(/\*$/,"/*")}".`);let s=[],o="^"+e.replace(/\/*\*?$/,"").replace(/^\/*/,"/").replace(/[\\.*+^${}|()[\]]/g,"\\$&").replace(/\/:([\w-]+)(\?)?/g,(l,a,d,c,p)=>{if(s.push({paramName:a,isOptional:d!=null}),d){let m=p.charAt(c+l.length);return m&&m!=="/"?"/([^\\/]*)":"(?:/([^\\/]*))?"}return"/([^\\/]+)"}).replace(/\/([\w-]+)\?(\/|$)/g,"(/$1)?$2");return e.endsWith("*")?(s.push({paramName:"*"}),o+=e==="*"||e==="/*"?"(.*)$":"(?:\\/(.+)|\\/*)$"):n?o+="\\/*$":e!==""&&e!=="/"&&(o+="(?:(?=\\/|$))"),[new RegExp(o,r?void 0:"i"),s]}function Sr(e){try{return e.split("/").map(r=>decodeURIComponent(r).replace(/\//g,"%2F")).join("/")}catch(r){return he(!1,`The URL path "${e}" could not be decoded because it is a malformed URL segment. This is probably due to a bad percent encoding (${r}).`),e}}function ve(e,r){if(r==="/")return e;if(!e.toLowerCase().startsWith(r.toLowerCase()))return null;let n=r.endsWith("/")?r.length-1:r.length,s=e.charAt(n);return s&&s!=="/"?null:e.slice(n)||"/"}var kr=/^(?:[a-z][a-z0-9+.-]*:|\/\/)/i;function Er(e,r="/"){let{pathname:n,search:s="",hash:o=""}=typeof e=="string"?Ie(e):e,i;return n?(n=n.replace(/\/\/+/g,"/"),n.startsWith("/")?i=Gt(n.substring(1),"/"):i=Gt(n,r)):i=r,{pathname:i,search:Dr(s),hash:Ar(o)}}function Gt(e,r){let n=r.replace(/\/+$/,"").split("/");return e.split("/").forEach(o=>{o===".."?n.length>1&&n.pop():o!=="."&&n.push(o)}),n.length>1?n.join("/"):"/"}function it(e,r,n,s){return`Cannot include a '${e}' character in a manually specified \`to.${r}\` field [${JSON.stringify(s)}]. Please separate it out to the \`to.${n}\` field. Alternatively you may provide the full path as a string in <Link to="..."> and the router will parse it for you.`}function Cr(e){return e.filter((r,n)=>n===0||r.route.path&&r.route.path.length>0)}function Rn(e){let r=Cr(e);return r.map((n,s)=>s===r.length-1?n.pathname:n.pathnameBase)}function _t(e,r,n,s=!1){let o;typeof e=="string"?o=Ie(e):(o={...e},Q(!o.pathname||!o.pathname.includes("?"),it("?","pathname","search",o)),Q(!o.pathname||!o.pathname.includes("#"),it("#","pathname","hash",o)),Q(!o.search||!o.search.includes("#"),it("#","search","hash",o)));let i=e===""||o.pathname==="",l=i?"/":o.pathname,a;if(l==null)a=n;else{let m=r.length-1;if(!s&&l.startsWith("..")){let x=l.split("/");for(;x[0]==="..";)x.shift(),m-=1;o.pathname=x.join("/")}a=m>=0?r[m]:"/"}let d=Er(o,a),c=l&&l!=="/"&&l.endsWith("/"),p=(i||l===".")&&n.endsWith("/");return!d.pathname.endsWith("/")&&(c||p)&&(d.pathname+="/"),d}var me=e=>e.join("/").replace(/\/\/+/g,"/"),jr=e=>e.replace(/\/+$/,"").replace(/^\/*/,"/"),Dr=e=>!e||e==="?"?"":e.startsWith("?")?e:"?"+e,Ar=e=>!e||e==="#"?"":e.startsWith("#")?e:"#"+e,Fr=class{constructor(e,r,n,s=!1){this.status=e,this.statusText=r||"",this.internal=s,n instanceof Error?(this.data=n.toString(),this.error=n):this.data=n}};function Rr(e){return e!=null&&typeof e.status=="number"&&typeof e.statusText=="string"&&typeof e.internal=="boolean"&&"data"in e}function _r(e){return e.map(r=>r.route.path).filter(Boolean).join("/").replace(/\/\/*/g,"/")||"/"}var _n=typeof window<"u"&&typeof window.document<"u"&&typeof window.document.createElement<"u";function Tn(e,r){let n=e;if(typeof n!="string"||!kr.test(n))return{absoluteURL:void 0,isExternal:!1,to:n};let s=n,o=!1;if(_n)try{let i=new URL(window.location.href),l=n.startsWith("//")?new URL(i.protocol+n):new URL(n),a=ve(l.pathname,r);l.origin===i.origin&&a!=null?n=a+l.search+l.hash:o=!0}catch{he(!1,`<Link to="${n}"> contains an invalid URL which will probably break when clicked - please update to a valid URL path.`)}return{absoluteURL:s,isExternal:o,to:n}}Object.getOwnPropertyNames(Object.prototype).sort().join("\0");var In=["POST","PUT","PATCH","DELETE"];new Set(In);var Tr=["GET",...In];new Set(Tr);var Ne=u.createContext(null);Ne.displayName="DataRouter";var ot=u.createContext(null);ot.displayName="DataRouterState";var Ir=u.createContext(!1),Nn=u.createContext({isTransitioning:!1});Nn.displayName="ViewTransition";var Nr=u.createContext(new Map);Nr.displayName="Fetchers";var Or=u.createContext(null);Or.displayName="Await";var de=u.createContext(null);de.displayName="Navigation";var Ve=u.createContext(null);Ve.displayName="Location";var ge=u.createContext({outlet:null,matches:[],isDataRoute:!1});ge.displayName="Route";var Tt=u.createContext(null);Tt.displayName="RouteError";var On="REACT_ROUTER_ERROR",Mr="REDIRECT",Pr="ROUTE_ERROR_RESPONSE";function zr(e){if(e.startsWith(`${On}:${Mr}:{`))try{let r=JSON.parse(e.slice(28));if(typeof r=="object"&&r&&typeof r.status=="number"&&typeof r.statusText=="string"&&typeof r.location=="string"&&typeof r.reloadDocument=="boolean"&&typeof r.replace=="boolean")return r}catch{}}function Br(e){if(e.startsWith(`${On}:${Pr}:{`))try{let r=JSON.parse(e.slice(40));if(typeof r=="object"&&r&&typeof r.status=="number"&&typeof r.statusText=="string")return new Fr(r.status,r.statusText,r.data)}catch{}}function Lr(e,{relative:r}={}){Q(Ue(),"useHref() may be used only in the context of a <Router> component.");let{basename:n,navigator:s}=u.useContext(de),{hash:o,pathname:i,search:l}=$e(e,{relative:r}),a=i;return n!=="/"&&(a=i==="/"?n:me([n,i])),s.createHref({pathname:a,search:l,hash:o})}function Ue(){return u.useContext(Ve)!=null}function ye(){return Q(Ue(),"useLocation() may be used only in the context of a <Router> component."),u.useContext(Ve).location}var Mn="You should call navigate() in a React.useEffect(), not when your component is first rendered.";function Pn(e){u.useContext(de).static||u.useLayoutEffect(e)}function Ce(){let{isDataRoute:e}=u.useContext(ge);return e?Zr():qr()}function qr(){Q(Ue(),"useNavigate() may be used only in the context of a <Router> component.");let e=u.useContext(Ne),{basename:r,navigator:n}=u.useContext(de),{matches:s}=u.useContext(ge),{pathname:o}=ye(),i=JSON.stringify(Rn(s)),l=u.useRef(!1);return Pn(()=>{l.current=!0}),u.useCallback((d,c={})=>{if(he(l.current,Mn),!l.current)return;if(typeof d=="number"){n.go(d);return}let p=_t(d,JSON.parse(i),o,c.relative==="path");e==null&&r!=="/"&&(p.pathname=p.pathname==="/"?r:me([r,p.pathname])),(c.replace?n.replace:n.push)(p,c.state,c)},[r,n,i,o,e])}u.createContext(null);function It(){let{matches:e}=u.useContext(ge),r=e[e.length-1];return r?r.params:{}}function $e(e,{relative:r}={}){let{matches:n}=u.useContext(ge),{pathname:s}=ye(),o=JSON.stringify(Rn(n));return u.useMemo(()=>_t(e,JSON.parse(o),s,r==="path"),[e,o,s,r])}function Vr(e,r){return zn(e,r)}function zn(e,r,n){var v;Q(Ue(),"useRoutes() may be used only in the context of a <Router> component.");let{navigator:s}=u.useContext(de),{matches:o}=u.useContext(ge),i=o[o.length-1],l=i?i.params:{},a=i?i.pathname:"/",d=i?i.pathnameBase:"/",c=i&&i.route;{let w=c&&c.path||"";Ln(a,!c||w.endsWith("*")||w.endsWith("*?"),`You rendered descendant <Routes> (or called \`useRoutes()\`) at "${a}" (under <Route path="${w}">) but the parent route path has no trailing "*". This means if you navigate deeper, the parent won't match anymore and therefore the child routes will never render.
12
-
13
- Please change the parent <Route path="${w}"> to <Route path="${w==="/"?"*":`${w}/*`}">.`)}let p=ye(),m;if(r){let w=typeof r=="string"?Ie(r):r;Q(d==="/"||((v=w.pathname)==null?void 0:v.startsWith(d)),`When overriding the location using \`<Routes location>\` or \`useRoutes(routes, location)\`, the location pathname must begin with the portion of the URL pathname that was matched by all parent routes. The current pathname base is "${d}" but pathname "${w.pathname}" was given in the \`location\` prop.`),m=w}else m=p;let x=m.pathname||"/",b=x;if(d!=="/"){let w=d.replace(/^\//,"").split("/");b="/"+x.replace(/^\//,"").split("/").slice(w.length).join("/")}let k=Dn(e,{pathname:b});he(c||k!=null,`No routes matched location "${m.pathname}${m.search}${m.hash}" `),he(k==null||k[k.length-1].route.element!==void 0||k[k.length-1].route.Component!==void 0||k[k.length-1].route.lazy!==void 0,`Matched leaf route at location "${m.pathname}${m.search}${m.hash}" does not have an element or Component. This means it will render an <Outlet /> with a null value by default resulting in an "empty" page.`);let y=Kr(k&&k.map(w=>Object.assign({},w,{params:Object.assign({},l,w.params),pathname:me([d,s.encodeLocation?s.encodeLocation(w.pathname.replace(/%/g,"%25").replace(/\?/g,"%3F").replace(/#/g,"%23")).pathname:w.pathname]),pathnameBase:w.pathnameBase==="/"?d:me([d,s.encodeLocation?s.encodeLocation(w.pathnameBase.replace(/%/g,"%25").replace(/\?/g,"%3F").replace(/#/g,"%23")).pathname:w.pathnameBase])})),o,n);return r&&y?u.createElement(Ve.Provider,{value:{location:{pathname:"/",search:"",hash:"",state:null,key:"default",unstable_mask:void 0,...m},navigationType:"POP"}},y):y}function Ur(){let e=Xr(),r=Rr(e)?`${e.status} ${e.statusText}`:e instanceof Error?e.message:JSON.stringify(e),n=e instanceof Error?e.stack:null,s="rgba(200,200,200, 0.5)",o={padding:"0.5rem",backgroundColor:s},i={padding:"2px 4px",backgroundColor:s},l=null;return console.error("Error handled by React Router default ErrorBoundary:",e),l=u.createElement(u.Fragment,null,u.createElement("p",null,"💿 Hey developer 👋"),u.createElement("p",null,"You can provide a way better UX than this when your app throws errors by providing your own ",u.createElement("code",{style:i},"ErrorBoundary")," or"," ",u.createElement("code",{style:i},"errorElement")," prop on your route.")),u.createElement(u.Fragment,null,u.createElement("h2",null,"Unexpected Application Error!"),u.createElement("h3",{style:{fontStyle:"italic"}},r),n?u.createElement("pre",{style:o},n):null,l)}var $r=u.createElement(Ur,null),Bn=class extends u.Component{constructor(e){super(e),this.state={location:e.location,revalidation:e.revalidation,error:e.error}}static getDerivedStateFromError(e){return{error:e}}static getDerivedStateFromProps(e,r){return r.location!==e.location||r.revalidation!=="idle"&&e.revalidation==="idle"?{error:e.error,location:e.location,revalidation:e.revalidation}:{error:e.error!==void 0?e.error:r.error,location:r.location,revalidation:e.revalidation||r.revalidation}}componentDidCatch(e,r){this.props.onError?this.props.onError(e,r):console.error("React Router caught the following error during render",e)}render(){let e=this.state.error;if(this.context&&typeof e=="object"&&e&&"digest"in e&&typeof e.digest=="string"){const n=Br(e.digest);n&&(e=n)}let r=e!==void 0?u.createElement(ge.Provider,{value:this.props.routeContext},u.createElement(Tt.Provider,{value:e,children:this.props.component})):this.props.children;return this.context?u.createElement(Wr,{error:e},r):r}};Bn.contextType=Ir;var at=new WeakMap;function Wr({children:e,error:r}){let{basename:n}=u.useContext(de);if(typeof r=="object"&&r&&"digest"in r&&typeof r.digest=="string"){let s=zr(r.digest);if(s){let o=at.get(r);if(o)throw o;let i=Tn(s.location,n);if(_n&&!at.get(r))if(i.isExternal||s.reloadDocument)window.location.href=i.absoluteURL||i.to;else{const l=Promise.resolve().then(()=>window.__reactRouterDataRouter.navigate(i.to,{replace:s.replace}));throw at.set(r,l),l}return u.createElement("meta",{httpEquiv:"refresh",content:`0;url=${i.absoluteURL||i.to}`})}}return e}function Hr({routeContext:e,match:r,children:n}){let s=u.useContext(Ne);return s&&s.static&&s.staticContext&&(r.route.errorElement||r.route.ErrorBoundary)&&(s.staticContext._deepestRenderedBoundaryId=r.route.id),u.createElement(ge.Provider,{value:e},n)}function Kr(e,r=[],n){let s=n==null?void 0:n.state;if(e==null){if(!s)return null;if(s.errors)e=s.matches;else if(r.length===0&&!s.initialized&&s.matches.length>0)e=s.matches;else return null}let o=e,i=s==null?void 0:s.errors;if(i!=null){let p=o.findIndex(m=>m.route.id&&(i==null?void 0:i[m.route.id])!==void 0);Q(p>=0,`Could not find a matching route for errors on route IDs: ${Object.keys(i).join(",")}`),o=o.slice(0,Math.min(o.length,p+1))}let l=!1,a=-1;if(n&&s){l=s.renderFallback;for(let p=0;p<o.length;p++){let m=o[p];if((m.route.HydrateFallback||m.route.hydrateFallbackElement)&&(a=p),m.route.id){let{loaderData:x,errors:b}=s,k=m.route.loader&&!x.hasOwnProperty(m.route.id)&&(!b||b[m.route.id]===void 0);if(m.route.lazy||k){n.isStatic&&(l=!0),a>=0?o=o.slice(0,a+1):o=[o[0]];break}}}}let d=n==null?void 0:n.onError,c=s&&d?(p,m)=>{var x,b;d(p,{location:s.location,params:((b=(x=s.matches)==null?void 0:x[0])==null?void 0:b.params)??{},unstable_pattern:_r(s.matches),errorInfo:m})}:void 0;return o.reduceRight((p,m,x)=>{let b,k=!1,y=null,v=null;s&&(b=i&&m.route.id?i[m.route.id]:void 0,y=m.route.errorElement||$r,l&&(a<0&&x===0?(Ln("route-fallback",!1,"No `HydrateFallback` element provided to render during initial hydration"),k=!0,v=null):a===x&&(k=!0,v=m.route.hydrateFallbackElement||null)));let w=r.concat(o.slice(0,x+1)),_=()=>{let N;return b?N=y:k?N=v:m.route.Component?N=u.createElement(m.route.Component,null):m.route.element?N=m.route.element:N=p,u.createElement(Hr,{match:m,routeContext:{outlet:p,matches:w,isDataRoute:s!=null},children:N})};return s&&(m.route.ErrorBoundary||m.route.errorElement||x===0)?u.createElement(Bn,{location:s.location,revalidation:s.revalidation,component:y,error:b,children:_(),routeContext:{outlet:null,matches:w,isDataRoute:!0},onError:c}):_()},null)}function Nt(e){return`${e} must be used within a data router. See https://reactrouter.com/en/main/routers/picking-a-router.`}function Gr(e){let r=u.useContext(Ne);return Q(r,Nt(e)),r}function Yr(e){let r=u.useContext(ot);return Q(r,Nt(e)),r}function Jr(e){let r=u.useContext(ge);return Q(r,Nt(e)),r}function Ot(e){let r=Jr(e),n=r.matches[r.matches.length-1];return Q(n.route.id,`${e} can only be used on routes that contain a unique "id"`),n.route.id}function Qr(){return Ot("useRouteId")}function Xr(){var s;let e=u.useContext(Tt),r=Yr("useRouteError"),n=Ot("useRouteError");return e!==void 0?e:(s=r.errors)==null?void 0:s[n]}function Zr(){let{router:e}=Gr("useNavigate"),r=Ot("useNavigate"),n=u.useRef(!1);return Pn(()=>{n.current=!0}),u.useCallback(async(o,i={})=>{he(n.current,Mn),n.current&&(typeof o=="number"?await e.navigate(o):await e.navigate(o,{fromRouteId:r,...i}))},[e,r])}var Yt={};function Ln(e,r,n){!r&&!Yt[e]&&(Yt[e]=!0,he(!1,n))}u.memo(eo);function eo({routes:e,future:r,state:n,isStatic:s,onError:o}){return zn(e,void 0,{state:n,isStatic:s,onError:o})}function _e(e){Q(!1,"A <Route> is only ever to be used as the child of <Routes> element, never rendered directly. Please wrap your <Route> in a <Routes>.")}function to({basename:e="/",children:r=null,location:n,navigationType:s="POP",navigator:o,static:i=!1,unstable_useTransitions:l}){Q(!Ue(),"You cannot render a <Router> inside another <Router>. You should never have more than one in your app.");let a=e.replace(/^\/*/,"/"),d=u.useMemo(()=>({basename:a,navigator:o,static:i,unstable_useTransitions:l,future:{}}),[a,o,i,l]);typeof n=="string"&&(n=Ie(n));let{pathname:c="/",search:p="",hash:m="",state:x=null,key:b="default",unstable_mask:k}=n,y=u.useMemo(()=>{let v=ve(c,a);return v==null?null:{location:{pathname:v,search:p,hash:m,state:x,key:b,unstable_mask:k},navigationType:s}},[a,c,p,m,x,b,s,k]);return he(y!=null,`<Router basename="${a}"> is not able to match the URL "${c}${p}${m}" because it does not start with the basename, so the <Router> won't render anything.`),y==null?null:u.createElement(de.Provider,{value:d},u.createElement(Ve.Provider,{children:r,value:y}))}function no({children:e,location:r}){return Vr(Ct(e),r)}function Ct(e,r=[]){let n=[];return u.Children.forEach(e,(s,o)=>{if(!u.isValidElement(s))return;let i=[...r,o];if(s.type===u.Fragment){n.push.apply(n,Ct(s.props.children,i));return}Q(s.type===_e,`[${typeof s.type=="string"?s.type:s.type.name}] is not a <Route> component. All component children of <Routes> must be a <Route> or <React.Fragment>`),Q(!s.props.index||!s.props.children,"An index route cannot have child routes.");let l={id:s.props.id||i.join("-"),caseSensitive:s.props.caseSensitive,element:s.props.element,Component:s.props.Component,index:s.props.index,path:s.props.path,middleware:s.props.middleware,loader:s.props.loader,action:s.props.action,hydrateFallbackElement:s.props.hydrateFallbackElement,HydrateFallback:s.props.HydrateFallback,errorElement:s.props.errorElement,ErrorBoundary:s.props.ErrorBoundary,hasErrorBoundary:s.props.hasErrorBoundary===!0||s.props.ErrorBoundary!=null||s.props.errorElement!=null,shouldRevalidate:s.props.shouldRevalidate,handle:s.props.handle,lazy:s.props.lazy};s.props.children&&(l.children=Ct(s.props.children,i)),n.push(l)}),n}var Ze="get",et="application/x-www-form-urlencoded";function st(e){return typeof HTMLElement<"u"&&e instanceof HTMLElement}function ro(e){return st(e)&&e.tagName.toLowerCase()==="button"}function oo(e){return st(e)&&e.tagName.toLowerCase()==="form"}function so(e){return st(e)&&e.tagName.toLowerCase()==="input"}function io(e){return!!(e.metaKey||e.altKey||e.ctrlKey||e.shiftKey)}function ao(e,r){return e.button===0&&(!r||r==="_self")&&!io(e)}var He=null;function lo(){if(He===null)try{new FormData(document.createElement("form"),0),He=!1}catch{He=!0}return He}var co=new Set(["application/x-www-form-urlencoded","multipart/form-data","text/plain"]);function lt(e){return e!=null&&!co.has(e)?(he(!1,`"${e}" is not a valid \`encType\` for \`<Form>\`/\`<fetcher.Form>\` and will default to "${et}"`),null):e}function uo(e,r){let n,s,o,i,l;if(oo(e)){let a=e.getAttribute("action");s=a?ve(a,r):null,n=e.getAttribute("method")||Ze,o=lt(e.getAttribute("enctype"))||et,i=new FormData(e)}else if(ro(e)||so(e)&&(e.type==="submit"||e.type==="image")){let a=e.form;if(a==null)throw new Error('Cannot submit a <button> or <input type="submit"> without a <form>');let d=e.getAttribute("formaction")||a.getAttribute("action");if(s=d?ve(d,r):null,n=e.getAttribute("formmethod")||a.getAttribute("method")||Ze,o=lt(e.getAttribute("formenctype"))||lt(a.getAttribute("enctype"))||et,i=new FormData(a,e),!lo()){let{name:c,type:p,value:m}=e;if(p==="image"){let x=c?`${c}.`:"";i.append(`${x}x`,"0"),i.append(`${x}y`,"0")}else c&&i.append(c,m)}}else{if(st(e))throw new Error('Cannot submit element that is not <form>, <button>, or <input type="submit|image">');n=Ze,s=null,o=et,l=e}return i&&o==="text/plain"&&(l=i,i=void 0),{action:s,method:n.toLowerCase(),encType:o,formData:i,body:l}}Object.getOwnPropertyNames(Object.prototype).sort().join("\0");function Mt(e,r){if(e===!1||e===null||typeof e>"u")throw new Error(r)}function po(e,r,n,s){let o=typeof e=="string"?new URL(e,typeof window>"u"?"server://singlefetch/":window.location.origin):e;return n?o.pathname.endsWith("/")?o.pathname=`${o.pathname}_.${s}`:o.pathname=`${o.pathname}.${s}`:o.pathname==="/"?o.pathname=`_root.${s}`:r&&ve(o.pathname,r)==="/"?o.pathname=`${r.replace(/\/$/,"")}/_root.${s}`:o.pathname=`${o.pathname.replace(/\/$/,"")}.${s}`,o}async function mo(e,r){if(e.id in r)return r[e.id];try{let n=await import(e.module);return r[e.id]=n,n}catch(n){return console.error(`Error loading route module \`${e.module}\`, reloading page...`),console.error(n),window.__reactRouterContext&&window.__reactRouterContext.isSpaMode,window.location.reload(),new Promise(()=>{})}}function fo(e){return e==null?!1:e.href==null?e.rel==="preload"&&typeof e.imageSrcSet=="string"&&typeof e.imageSizes=="string":typeof e.rel=="string"&&typeof e.href=="string"}async function ho(e,r,n){let s=await Promise.all(e.map(async o=>{let i=r.routes[o.route.id];if(i){let l=await mo(i,n);return l.links?l.links():[]}return[]}));return bo(s.flat(1).filter(fo).filter(o=>o.rel==="stylesheet"||o.rel==="preload").map(o=>o.rel==="stylesheet"?{...o,rel:"prefetch",as:"style"}:{...o,rel:"prefetch"}))}function Jt(e,r,n,s,o,i){let l=(d,c)=>n[c]?d.route.id!==n[c].route.id:!0,a=(d,c)=>{var p;return n[c].pathname!==d.pathname||((p=n[c].route.path)==null?void 0:p.endsWith("*"))&&n[c].params["*"]!==d.params["*"]};return i==="assets"?r.filter((d,c)=>l(d,c)||a(d,c)):i==="data"?r.filter((d,c)=>{var m;let p=s.routes[d.route.id];if(!p||!p.hasLoader)return!1;if(l(d,c)||a(d,c))return!0;if(d.route.shouldRevalidate){let x=d.route.shouldRevalidate({currentUrl:new URL(o.pathname+o.search+o.hash,window.origin),currentParams:((m=n[0])==null?void 0:m.params)||{},nextUrl:new URL(e,window.origin),nextParams:d.params,defaultShouldRevalidate:!0});if(typeof x=="boolean")return x}return!0}):[]}function go(e,r,{includeHydrateFallback:n}={}){return yo(e.map(s=>{let o=r.routes[s.route.id];if(!o)return[];let i=[o.module];return o.clientActionModule&&(i=i.concat(o.clientActionModule)),o.clientLoaderModule&&(i=i.concat(o.clientLoaderModule)),n&&o.hydrateFallbackModule&&(i=i.concat(o.hydrateFallbackModule)),o.imports&&(i=i.concat(o.imports)),i}).flat(1))}function yo(e){return[...new Set(e)]}function xo(e){let r={},n=Object.keys(e).sort();for(let s of n)r[s]=e[s];return r}function bo(e,r){let n=new Set;return new Set(r),e.reduce((s,o)=>{let i=JSON.stringify(xo(o));return n.has(i)||(n.add(i),s.push({key:i,link:o})),s},[])}function qn(){let e=u.useContext(Ne);return Mt(e,"You must render this element inside a <DataRouterContext.Provider> element"),e}function vo(){let e=u.useContext(ot);return Mt(e,"You must render this element inside a <DataRouterStateContext.Provider> element"),e}var Pt=u.createContext(void 0);Pt.displayName="FrameworkContext";function Vn(){let e=u.useContext(Pt);return Mt(e,"You must render this element inside a <HydratedRouter> element"),e}function wo(e,r){let n=u.useContext(Pt),[s,o]=u.useState(!1),[i,l]=u.useState(!1),{onFocus:a,onBlur:d,onMouseEnter:c,onMouseLeave:p,onTouchStart:m}=r,x=u.useRef(null);u.useEffect(()=>{if(e==="render"&&l(!0),e==="viewport"){let y=w=>{w.forEach(_=>{l(_.isIntersecting)})},v=new IntersectionObserver(y,{threshold:.5});return x.current&&v.observe(x.current),()=>{v.disconnect()}}},[e]),u.useEffect(()=>{if(s){let y=setTimeout(()=>{l(!0)},100);return()=>{clearTimeout(y)}}},[s]);let b=()=>{o(!0)},k=()=>{o(!1),l(!1)};return n?e!=="intent"?[i,x,{}]:[i,x,{onFocus:Oe(a,b),onBlur:Oe(d,k),onMouseEnter:Oe(c,b),onMouseLeave:Oe(p,k),onTouchStart:Oe(m,b)}]:[!1,x,{}]}function Oe(e,r){return n=>{e&&e(n),n.defaultPrevented||r(n)}}function So({page:e,...r}){let{router:n}=qn(),s=u.useMemo(()=>Dn(n.routes,e,n.basename),[n.routes,e,n.basename]);return s?u.createElement(Eo,{page:e,matches:s,...r}):null}function ko(e){let{manifest:r,routeModules:n}=Vn(),[s,o]=u.useState([]);return u.useEffect(()=>{let i=!1;return ho(e,r,n).then(l=>{i||o(l)}),()=>{i=!0}},[e,r,n]),s}function Eo({page:e,matches:r,...n}){let s=ye(),{future:o,manifest:i,routeModules:l}=Vn(),{basename:a}=qn(),{loaderData:d,matches:c}=vo(),p=u.useMemo(()=>Jt(e,r,c,i,s,"data"),[e,r,c,i,s]),m=u.useMemo(()=>Jt(e,r,c,i,s,"assets"),[e,r,c,i,s]),x=u.useMemo(()=>{if(e===s.pathname+s.search+s.hash)return[];let y=new Set,v=!1;if(r.forEach(_=>{var f;let N=i.routes[_.route.id];!N||!N.hasLoader||(!p.some(D=>D.route.id===_.route.id)&&_.route.id in d&&((f=l[_.route.id])!=null&&f.shouldRevalidate)||N.hasClientLoader?v=!0:y.add(_.route.id))}),y.size===0)return[];let w=po(e,a,o.unstable_trailingSlashAwareDataRequests,"data");return v&&y.size>0&&w.searchParams.set("_routes",r.filter(_=>y.has(_.route.id)).map(_=>_.route.id).join(",")),[w.pathname+w.search]},[a,o.unstable_trailingSlashAwareDataRequests,d,s,i,p,r,e,l]),b=u.useMemo(()=>go(m,i),[m,i]),k=ko(m);return u.createElement(u.Fragment,null,x.map(y=>u.createElement("link",{key:y,rel:"prefetch",as:"fetch",href:y,...n})),b.map(y=>u.createElement("link",{key:y,rel:"modulepreload",href:y,...n})),k.map(({key:y,link:v})=>u.createElement("link",{key:y,nonce:n.nonce,...v,crossOrigin:v.crossOrigin??n.crossOrigin})))}function Co(...e){return r=>{e.forEach(n=>{typeof n=="function"?n(r):n!=null&&(n.current=r)})}}var jo=typeof window<"u"&&typeof window.document<"u"&&typeof window.document.createElement<"u";try{jo&&(window.__reactRouterVersion="7.13.2")}catch{}function Do({basename:e,children:r,unstable_useTransitions:n,window:s}){let o=u.useRef();o.current==null&&(o.current=ir({window:s,v5Compat:!0}));let i=o.current,[l,a]=u.useState({action:i.action,location:i.location}),d=u.useCallback(c=>{n===!1?a(c):u.startTransition(()=>a(c))},[n]);return u.useLayoutEffect(()=>i.listen(d),[i,d]),u.createElement(to,{basename:e,children:r,location:l.location,navigationType:l.action,navigator:i,unstable_useTransitions:n})}var Un=/^(?:[a-z][a-z0-9+.-]*:|\/\/)/i,$n=u.forwardRef(function({onClick:r,discover:n="render",prefetch:s="none",relative:o,reloadDocument:i,replace:l,unstable_mask:a,state:d,target:c,to:p,preventScrollReset:m,viewTransition:x,unstable_defaultShouldRevalidate:b,...k},y){let{basename:v,navigator:w,unstable_useTransitions:_}=u.useContext(de),N=typeof p=="string"&&Un.test(p),f=Tn(p,v);p=f.to;let D=Lr(p,{relative:o}),E=ye(),R=null;if(a){let $=_t(a,[],E.unstable_mask?E.unstable_mask.pathname:"/",!0);v!=="/"&&($.pathname=$.pathname==="/"?v:me([v,$.pathname])),R=w.createHref($)}let[T,O,j]=wo(s,k),B=_o(p,{replace:l,unstable_mask:a,state:d,target:c,preventScrollReset:m,relative:o,viewTransition:x,unstable_defaultShouldRevalidate:b,unstable_useTransitions:_});function H($){r&&r($),$.defaultPrevented||B($)}let U=!(f.isExternal||i),X=u.createElement("a",{...k,...j,href:(U?R:void 0)||f.absoluteURL||D,onClick:U?H:r,ref:Co(y,O),target:c,"data-discover":!N&&n==="render"?"true":void 0});return T&&!N?u.createElement(u.Fragment,null,X,u.createElement(So,{page:D})):X});$n.displayName="Link";var Ao=u.forwardRef(function({"aria-current":r="page",caseSensitive:n=!1,className:s="",end:o=!1,style:i,to:l,viewTransition:a,children:d,...c},p){let m=$e(l,{relative:c.relative}),x=ye(),b=u.useContext(ot),{navigator:k,basename:y}=u.useContext(de),v=b!=null&&Mo(m)&&a===!0,w=k.encodeLocation?k.encodeLocation(m).pathname:m.pathname,_=x.pathname,N=b&&b.navigation&&b.navigation.location?b.navigation.location.pathname:null;n||(_=_.toLowerCase(),N=N?N.toLowerCase():null,w=w.toLowerCase()),N&&y&&(N=ve(N,y)||N);const f=w!=="/"&&w.endsWith("/")?w.length-1:w.length;let D=_===w||!o&&_.startsWith(w)&&_.charAt(f)==="/",E=N!=null&&(N===w||!o&&N.startsWith(w)&&N.charAt(w.length)==="/"),R={isActive:D,isPending:E,isTransitioning:v},T=D?r:void 0,O;typeof s=="function"?O=s(R):O=[s,D?"active":null,E?"pending":null,v?"transitioning":null].filter(Boolean).join(" ");let j=typeof i=="function"?i(R):i;return u.createElement($n,{...c,"aria-current":T,className:O,ref:p,style:j,to:l,viewTransition:a},typeof d=="function"?d(R):d)});Ao.displayName="NavLink";var Fo=u.forwardRef(({discover:e="render",fetcherKey:r,navigate:n,reloadDocument:s,replace:o,state:i,method:l=Ze,action:a,onSubmit:d,relative:c,preventScrollReset:p,viewTransition:m,unstable_defaultShouldRevalidate:x,...b},k)=>{let{unstable_useTransitions:y}=u.useContext(de),v=No(),w=Oo(a,{relative:c}),_=l.toLowerCase()==="get"?"get":"post",N=typeof a=="string"&&Un.test(a),f=D=>{if(d&&d(D),D.defaultPrevented)return;D.preventDefault();let E=D.nativeEvent.submitter,R=(E==null?void 0:E.getAttribute("formmethod"))||l,T=()=>v(E||D.currentTarget,{fetcherKey:r,method:R,navigate:n,replace:o,state:i,relative:c,preventScrollReset:p,viewTransition:m,unstable_defaultShouldRevalidate:x});y&&n!==!1?u.startTransition(()=>T()):T()};return u.createElement("form",{ref:k,method:_,action:w,onSubmit:s?d:f,...b,"data-discover":!N&&e==="render"?"true":void 0})});Fo.displayName="Form";function Ro(e){return`${e} must be used within a data router. See https://reactrouter.com/en/main/routers/picking-a-router.`}function Wn(e){let r=u.useContext(Ne);return Q(r,Ro(e)),r}function _o(e,{target:r,replace:n,unstable_mask:s,state:o,preventScrollReset:i,relative:l,viewTransition:a,unstable_defaultShouldRevalidate:d,unstable_useTransitions:c}={}){let p=Ce(),m=ye(),x=$e(e,{relative:l});return u.useCallback(b=>{if(ao(b,r)){b.preventDefault();let k=n!==void 0?n:Le(m)===Le(x),y=()=>p(e,{replace:k,unstable_mask:s,state:o,preventScrollReset:i,relative:l,viewTransition:a,unstable_defaultShouldRevalidate:d});c?u.startTransition(()=>y()):y()}},[m,p,x,n,s,o,r,e,i,l,a,d,c])}var To=0,Io=()=>`__${String(++To)}__`;function No(){let{router:e}=Wn("useSubmit"),{basename:r}=u.useContext(de),n=Qr(),s=e.fetch,o=e.navigate;return u.useCallback(async(i,l={})=>{let{action:a,method:d,encType:c,formData:p,body:m}=uo(i,r);if(l.navigate===!1){let x=l.fetcherKey||Io();await s(x,n,l.action||a,{unstable_defaultShouldRevalidate:l.unstable_defaultShouldRevalidate,preventScrollReset:l.preventScrollReset,formData:p,body:m,formMethod:l.method||d,formEncType:l.encType||c,flushSync:l.flushSync})}else await o(l.action||a,{unstable_defaultShouldRevalidate:l.unstable_defaultShouldRevalidate,preventScrollReset:l.preventScrollReset,formData:p,body:m,formMethod:l.method||d,formEncType:l.encType||c,replace:l.replace,state:l.state,fromRouteId:n,flushSync:l.flushSync,viewTransition:l.viewTransition})},[s,o,r,n])}function Oo(e,{relative:r}={}){let{basename:n}=u.useContext(de),s=u.useContext(ge);Q(s,"useFormAction must be used inside a RouteContext");let[o]=s.matches.slice(-1),i={...$e(e||".",{relative:r})},l=ye();if(e==null){i.search=l.search;let a=new URLSearchParams(i.search),d=a.getAll("index");if(d.some(p=>p==="")){a.delete("index"),d.filter(m=>m).forEach(m=>a.append("index",m));let p=a.toString();i.search=p?`?${p}`:""}}return(!e||e===".")&&o.route.index&&(i.search=i.search?i.search.replace(/^\?/,"?index&"):"?index"),n!=="/"&&(i.pathname=i.pathname==="/"?n:me([n,i.pathname])),Le(i)}function Mo(e,{relative:r}={}){let n=u.useContext(Nn);Q(n!=null,"`useViewTransitionState` must be used within `react-router-dom`'s `RouterProvider`. Did you accidentally import `RouterProvider` from `react-router`?");let{basename:s}=Wn("useViewTransitionState"),o=$e(e,{relative:r});if(!n.isTransitioning)return!1;let i=ve(n.currentLocation.pathname,s)||n.currentLocation.pathname,l=ve(n.nextLocation.pathname,s)||n.nextLocation.pathname;return rt(o.pathname,l)!=null||rt(o.pathname,i)!=null}const Po="modulepreload",zo=function(e){return"/"+e},Qt={},te=function(r,n,s){let o=Promise.resolve();if(n&&n.length>0){let l=function(c){return Promise.all(c.map(p=>Promise.resolve(p).then(m=>({status:"fulfilled",value:m}),m=>({status:"rejected",reason:m}))))};document.getElementsByTagName("link");const a=document.querySelector("meta[property=csp-nonce]"),d=(a==null?void 0:a.nonce)||(a==null?void 0:a.getAttribute("nonce"));o=l(n.map(c=>{if(c=zo(c),c in Qt)return;Qt[c]=!0;const p=c.endsWith(".css"),m=p?'[rel="stylesheet"]':"";if(document.querySelector(`link[href="${c}"]${m}`))return;const x=document.createElement("link");if(x.rel=p?"stylesheet":Po,p||(x.as="script"),x.crossOrigin="",x.href=c,d&&x.setAttribute("nonce",d),document.head.appendChild(x),p)return new Promise((b,k)=>{x.addEventListener("load",b),x.addEventListener("error",()=>k(new Error(`Unable to preload CSS for ${c}`)))})}))}function i(l){const a=new Event("vite:preloadError",{cancelable:!0});if(a.payload=l,window.dispatchEvent(a),!a.defaultPrevented)throw l}return o.then(l=>{for(const a of l||[])a.status==="rejected"&&i(a.reason);return r().catch(i)})};let M=null,Ke=null,ct=0;const Bo=1e4;let je=!1,tt=null;const Te=new Map;function Lo(e){const r=Te.get(e.requestId);r&&(clearTimeout(r.timer),Te.delete(e.requestId),e.success?r.resolve(e):r.reject(new Error(e.error||`Could not ${e.operation} diagram source.`)))}function qo(e){for(const r of Te.values())clearTimeout(r.timer),r.reject(new Error(e));Te.clear()}function Vo(){const e=window.__MEMO_DATA__;if(!e)return!1;const r=S.getState();return r.setConnected(!0),e.model&&r.setModel(e.model),e.validation&&r.setValidation(e.validation),e.completeness&&r.setCompleteness(e.completeness),!0}function Hn(e){if(window.__MEMO_DATA__)return;Wo();const r=`ws://${window.location.host}`;if(M&&(M.readyState===WebSocket.OPEN||M.readyState===WebSocket.CONNECTING))return;M=new WebSocket(r);const n=S.getState();M.onopen=()=>{n.setConnected(!0),ct=0,tt=null,je=!1,n.setRestartRequired(null),Ke&&(clearTimeout(Ke),Ke=null)},M.onmessage=s=>{try{const o=JSON.parse(s.data);Uo(o)}catch{}},M.onclose=()=>{n.setConnected(!1),qo("The development server disconnected."),M=null,ct++;const s=Math.min(2e3*Math.pow(2,ct-1),Bo);Ke=setTimeout(()=>Hn(),s)},M.onerror=()=>{}}function Uo(e){const r=S.getState();switch(e.type){case"app:restart-required":je=!0,r.setRestartRequired(e);return;case"model:update":if(je)return;r.setModel(e.payload);break;case"validation:update":if(je)return;r.setValidation(e.payload);break;case"completeness:update":if(je)return;r.setCompleteness(e.payload);break;case"methodology:update":if(je)return;r.setMethodology(e.payload);break;case"error":console.error("[MEMO] Server error:",e.payload.message);break;case"diagram:parse:result":r.applyDiagramParseResult(e.payload.diagramId,e.payload.elementIds,e.payload.errors);break;case"diagram:source:result":Lo(e.payload);break;case"ontology:packages":{const n=e.payload.ontologyHash;if(n){if(tt===null)tt=n;else if(tt!==n){je=!0,r.setRestartRequired({type:"app:restart-required",reason:"ontology-source-changed",changedFile:"(server restarted with different ontology)",instruction:"Reload the page to connect to the new server."});return}}r.setAvailableOntologies(e.payload.packages);break}case"ontology:install:result":r.setOntologyInstallStatus({installing:!1,lastInstalled:e.payload.success?e.payload.packageName:void 0,error:e.payload.error});break;case"ontology:remove:result":r.setOntologyInstallStatus({installing:!1});break;case"diagram:layout":r.mergeDiagramLayouts(e.payload.layouts);break;case"import:result":r.setImportResult(e.payload);break;case"llm:status":r.setLlmStatus(e.payload.available,e.payload.provider,e.payload.model);break;case"llm:ask:result":e.payload.error?r.rejectLlmRequest(e.payload.requestId,e.payload.error):r.resolveLlmRequest(e.payload.requestId,e.payload.answer);break;case"llm:generate:result":e.payload.error?r.rejectLlmRequest(e.payload.requestId,e.payload.error):r.resolveLlmRequest(e.payload.requestId,{sysml:e.payload.sysml,explanation:e.payload.explanation,suggestedFile:e.payload.suggestedFile});break;case"llm:draft:result":e.payload.error?r.rejectLlmRequest(e.payload.requestId,e.payload.error):r.resolveLlmRequest(e.payload.requestId,{markdown:e.payload.markdown,summary:e.payload.summary});break;case"llm:suggest:result":e.payload.error?r.rejectLlmRequest(e.payload.requestId,e.payload.error):r.resolveLlmRequest(e.payload.requestId,e.payload.suggestions);break;case"dhf:docs":Xt(()=>r.setDhfDocuments(e.payload.docs));break;case"dhf:settings":Xt(()=>r.hydrateDhfSettings(e.payload.settings));break;case"dhf:templates:result":r.resolveLlmRequest(e.payload.requestId,e.payload.templates);break;case"dhf:template:content":e.payload.error?r.rejectLlmRequest(e.payload.requestId,e.payload.error):r.resolveLlmRequest(e.payload.requestId,e.payload.content);break}}let jt=!1;const Kn=600,Be=new Map;let Ge=null;function Xt(e){jt=!0;try{e()}finally{jt=!1}}function qe(e){M&&M.readyState===WebSocket.OPEN&&M.send(JSON.stringify(e))}function $o(e){const r=Be.get(e.id);r&&clearTimeout(r),Be.set(e.id,setTimeout(()=>{Be.delete(e.id);const n=S.getState().dhfDocuments.find(s=>s.id===e.id);n&&qe({type:"dhf:doc:save",payload:{doc:n}})},Kn))}let Zt=!1;function Wo(){Zt||(Zt=!0,S.subscribe((e,r)=>{if(!jt){if(e.dhfDocuments!==r.dhfDocuments){const n=new Map(r.dhfDocuments.map(s=>[s.id,s]));for(const s of e.dhfDocuments)n.get(s.id)!==s&&$o(s),n.delete(s.id);for(const s of n.keys()){const o=Be.get(s);o&&(clearTimeout(o),Be.delete(s)),qe({type:"dhf:doc:delete",payload:{docId:s}})}}e.dhfSettings!==r.dhfSettings&&(Ge&&clearTimeout(Ge),Ge=setTimeout(()=>{Ge=null,qe({type:"dhf:settings:save",payload:{settings:S.getState().dhfSettings}})},Kn))}}))}function Ho(e){qe({type:"dhf:templates:list",payload:{requestId:e}})}function Ko(e,r){qe({type:"dhf:template:read",payload:{requestId:e,path:r}})}function Fe(e){M&&M.readyState===WebSocket.OPEN&&M.send(JSON.stringify({type:"element:update",payload:e}))}function en(e){M&&M.readyState===WebSocket.OPEN&&M.send(JSON.stringify({type:"element:create",payload:e}))}function $a(e,r,n){M&&M.readyState===WebSocket.OPEN&&M.send(JSON.stringify({type:"relationship:add",payload:{sourceId:e,targetId:r,type:n}}))}function Go(e){M&&M.readyState===WebSocket.OPEN&&M.send(JSON.stringify({type:"diagram:create",payload:e}))}function tn(e){M&&M.readyState===WebSocket.OPEN&&M.send(JSON.stringify({type:"diagram:update",payload:e}))}function Yo(e){if(M&&M.readyState===WebSocket.OPEN){const r={id:e};M.send(JSON.stringify({type:"diagram:delete",payload:r}))}}function Wa(e,r){if(M&&M.readyState===WebSocket.OPEN){const n={diagramId:e,text:r};M.send(JSON.stringify({type:"diagram:parse",payload:n}))}}function Gn(e,r,n){if(!M||M.readyState!==WebSocket.OPEN)return Promise.reject(new Error("The development server is not connected."));const s=`diagram-source-${Date.now().toString(36)}-${Math.random().toString(36).slice(2,8)}`;return new Promise((o,i)=>{const l=setTimeout(()=>{Te.delete(s),i(new Error(`Timed out while trying to ${e} the SysML source.`))},1e4);Te.set(s,{resolve:o,reject:i,timer:l}),M.send(JSON.stringify({type:e==="load"?"diagram:source:request":"diagram:source:save",payload:{requestId:s,diagramId:r,...e==="save"?{text:n}:{}}}))})}function Ha(e){return Gn("load",e)}function Ka(e,r){return Gn("save",e,r)}function Jo(e){M&&M.readyState===WebSocket.OPEN&&M.send(JSON.stringify({type:"element:remap-kinds",payload:{mappings:e}}))}function dt(e){M&&M.readyState===WebSocket.OPEN&&M.send(JSON.stringify({type:"ontology:save-selection",payload:{selected:e}}))}function Ga(e){M&&M.readyState===WebSocket.OPEN&&M.send(JSON.stringify({type:"ontology:install",payload:{source:e}}))}function Ya(e){M&&M.readyState===WebSocket.OPEN&&M.send(JSON.stringify({type:"open-file",payload:{path:e}}))}function Ja(e){M&&M.readyState===WebSocket.OPEN&&M.send(JSON.stringify({type:"ontology:remove",payload:{packageName:e}}))}function Qa(e,r){M&&M.readyState===WebSocket.OPEN&&M.send(JSON.stringify({type:"diagram:layout:update",payload:{diagramId:e,layout:r}}))}function Qo(e){M&&M.readyState===WebSocket.OPEN&&M.send(JSON.stringify({type:"csv:import",payload:e}))}function Xa(e,r){M&&M.readyState===WebSocket.OPEN&&M.send(JSON.stringify({type:"llm:ask",payload:{requestId:e,question:r}}))}function Za(e,r){M&&M.readyState===WebSocket.OPEN&&M.send(JSON.stringify({type:"llm:generate",payload:{requestId:e,description:r}}))}function el(e,r,n){M&&M.readyState===WebSocket.OPEN&&M.send(JSON.stringify({type:"llm:draft",payload:{requestId:e,documentTypeId:r,targetSections:n}}))}const nn="memo:userViewpoints",Dt="memo:activeView";function Xo(){try{const e=JSON.parse(sessionStorage.getItem(Dt)??"null");if((e==null?void 0:e.type)==="diagram"&&typeof e.diagramId=="string")return e}catch{}return{type:"welcome"}}function rn(e){try{e.type==="diagram"?sessionStorage.setItem(Dt,JSON.stringify(e)):sessionStorage.removeItem(Dt)}catch{}}function Zo(){try{const e=localStorage.getItem(nn);if(e){const r=JSON.parse(e);return localStorage.removeItem(nn),r.length>0&&console.warn(`[MEMO] Migrated ${r.length} user viewpoint(s) from localStorage. Save them to memo.viewpoints.yaml to persist across sessions.`),r}}catch{}return[]}const ke="_folder",Ye=Xo(),S=jn((e,r)=>({model:null,validation:null,completeness:null,connected:!1,restartRequired:null,methodology:null,activeMode:Ye.type==="diagram"?"diagram":"catalog",activeView:Ye,explorerTab:"model",selectedElementId:null,selectedRelationshipId:null,selectedElementIds:new Set,recentlyVisited:[],selectedViewpointId:null,selectedDiagramId:Ye.type==="diagram"?Ye.diagramId:null,searchTerm:"",sidebarCollapsed:!1,propertiesPanelCollapsed:!0,hiddenLayers:new Set,ontologyGroupBy:"layer",collapsedGroups:new Set,availableOntologies:[],selectedOntologies:new Set,focusedOntologyId:null,selectedOntologyKind:null,ontologyViewMode:"visual",showOntologyRelationships:!1,highlightedRelationshipType:null,hiddenEdgeTypes:new Set(["extends"]),ontologyInstallStatus:{installing:!1},gapBarExpanded:!1,gapBarHeight:160,catalogGroupBy:"semantic",catalogCollapsed:new Set,contextMenu:null,attributeFilter:null,labelFilter:null,tagFilters:[],userViewpoints:Zo(),diagramLayouts:{},mergeDiagramLayouts:n=>e(s=>({diagramLayouts:{...s.diagramLayouts,...n}})),setNodeLayout:(n,s,o)=>e(i=>{const l=i.diagramLayouts[n]??{nodes:{},edges:{}};return{diagramLayouts:{...i.diagramLayouts,[n]:{...l,nodes:{...l.nodes,[s]:{...l.nodes[s]??{},...o}}}}}}),diagramParseErrors:{},dhfDocuments:[],dhfSettings:{company:"",product:"",deviceType:"",version:"0.1",phase:"",logoUrl:"",compactLogoUrl:"",primaryColor:"#1B3A4B",compactMode:!1,headerTemplate:"**{{project.product}}** | {{id}} | Rev {{project.version}}",footerTemplate:"Confidential — {{project.company}} | Page {{page}}",documentNumberingPrefix:"DOC"},bulkImportOpen:!1,importResult:null,llmAvailable:!1,llmProvider:void 0,llmModel:void 0,llmPending:new Map,setLlmStatus:(n,s,o)=>e({llmAvailable:n,llmProvider:s,llmModel:o}),registerLlmRequest:(n,s,o)=>e(i=>{const l=new Map(i.llmPending);return l.set(n,{resolve:s,reject:o}),{llmPending:l}}),resolveLlmRequest:(n,s)=>e(o=>{const i=o.llmPending.get(n);if(i){i.resolve(s);const l=new Map(o.llmPending);return l.delete(n),{llmPending:l}}return{}}),rejectLlmRequest:(n,s)=>e(o=>{const i=o.llmPending.get(n);if(i){i.reject(new Error(s));const l=new Map(o.llmPending);return l.delete(n),{llmPending:l}}return{}}),analysisIssues:[],editingElementId:null,pendingEdits:new Map,setRestartRequired:n=>e({restartRequired:n}),setMethodology:n=>e({methodology:n}),setModel:n=>e(s=>{var a,d,c,p;let o=s.activeView,i=s.selectedDiagramId,l=s.selectedViewpointId;if(o.type==="diagram"){const m=o.diagramId,x=(a=n.diagrams)==null?void 0:a.find(y=>y.id===m),b=(c=(d=s.model)==null?void 0:d.diagrams)==null?void 0:c.find(y=>y.id===m),k=x??(b!=null&&b.sourceFile?(p=n.diagrams)==null?void 0:p.find(y=>y.sourceFile===b.sourceFile):void 0);k&&(k.id!==m&&(o={type:"diagram",diagramId:k.id},rn(o)),i=k.id,l=k.viewpointId==="__model"?null:k.viewpointId)}else(o.type==="welcome"||o.type==="dashboard")&&Object.keys(n.elements).length>0&&(o={type:"dashboard"});return{model:n,activeView:o,selectedDiagramId:i,selectedViewpointId:l}}),setValidation:n=>e({validation:n}),setCompleteness:n=>e({completeness:n}),setConnected:n=>e({connected:n}),setAnalysisIssues:n=>e({analysisIssues:n}),setActiveMode:n=>e({activeMode:n}),setActiveView:n=>{rn(n),e({activeView:n})},setExplorerTab:n=>e({explorerTab:n}),selectElement:n=>{e(n?s=>{const o=[n,...s.recentlyVisited.filter(i=>i!==n)].slice(0,20);return{selectedElementId:n,activeView:{type:"element-detail",elementId:n},recentlyVisited:o}}:{selectedElementId:n})},inspectElement:n=>e(s=>({selectedElementId:n,selectedRelationshipId:null,propertiesPanelCollapsed:n?!1:s.propertiesPanelCollapsed,recentlyVisited:n?[n,...s.recentlyVisited.filter(o=>o!==n)].slice(0,20):s.recentlyVisited})),inspectRelationship:n=>e({selectedRelationshipId:n,selectedElementId:null,propertiesPanelCollapsed:n?!1:r().propertiesPanelCollapsed}),toggleElementSelection:n=>e(s=>{const o=new Set(s.selectedElementIds);return o.has(n)?o.delete(n):o.add(n),{selectedElementIds:o}}),selectAllElements:n=>e({selectedElementIds:new Set(n)}),clearElementSelection:()=>e({selectedElementIds:new Set}),updateElementKind:(n,s)=>{const{model:o}=r();if(!o)return;const i=o.elements[n];if(!i)return;const l={...i,kind:s};e(a=>({model:a.model?{...a.model,elements:{...a.model.elements,[n]:l}}:null})),Fe(l)},bulkUpdateAttributes:(n,s)=>{const{model:o}=r();if(!o)return;const i={...o.elements};for(const l of n){const a=i[l];if(!a)continue;const d={...a,attributes:{...a.attributes,...s}};i[l]=d,Fe(d)}e(l=>({model:l.model?{...l.model,elements:i}:null}))},selectViewpoint:n=>e({selectedViewpointId:n,selectedDiagramId:null}),selectDiagram:n=>{var i;if(!n){e({selectedDiagramId:null});return}const{model:s}=r(),o=(i=s==null?void 0:s.diagrams)==null?void 0:i.find(l=>l.id===n);e(o?{selectedDiagramId:n,selectedViewpointId:o.viewpointId==="__model"?null:o.viewpointId}:{selectedDiagramId:n})},setSearchTerm:n=>e({searchTerm:n}),toggleSidebar:()=>e(n=>({sidebarCollapsed:!n.sidebarCollapsed})),togglePropertiesPanel:()=>e(n=>({propertiesPanelCollapsed:!n.propertiesPanelCollapsed})),toggleLayerVisibility:n=>e(s=>{const o=new Set(s.hiddenLayers);return o.has(n)?o.delete(n):o.add(n),{hiddenLayers:o}}),setOntologyGroupBy:n=>e({ontologyGroupBy:n,collapsedGroups:new Set}),toggleGroupCollapsed:n=>e(s=>{const o=new Set(s.collapsedGroups);return o.has(n)?o.delete(n):o.add(n),{collapsedGroups:o}}),setAvailableOntologies:n=>e(s=>{let o=new Set(n.filter(a=>a.selected).map(a=>a.name));const i=["@memoarchitect/ontology"];for(const a of n)i.includes(a.name)&&o.add(a.name);o.size===0&&n.length>0&&(o=new Set(n.map(a=>a.name)));const l=s.focusedOntologyId??(o.size>0?[...o][0]:null);return{availableOntologies:n,selectedOntologies:o,focusedOntologyId:l}}),toggleOntologySelection:n=>e(s=>{const o=new Set(s.selectedOntologies);return o.has(n)?o.delete(n):o.add(n),{selectedOntologies:o}}),setFocusedOntology:n=>e({focusedOntologyId:n}),setSelectedOntologyKind:n=>e({selectedOntologyKind:n}),setOntologyViewMode:n=>e({ontologyViewMode:n}),toggleOntologyRelationships:()=>e(n=>({showOntologyRelationships:!n.showOntologyRelationships})),setHighlightedRelationshipType:n=>e(s=>({highlightedRelationshipType:s.highlightedRelationshipType===n?null:n})),toggleHiddenEdgeType:n=>e(s=>{const o=new Set(s.hiddenEdgeTypes);return o.has(n)?o.delete(n):o.add(n),{hiddenEdgeTypes:o}}),saveOntologySelection:()=>{const{model:n,availableOntologies:s,selectedOntologies:o}=r();if(!n)return{success:!0};const i=s.filter(d=>!o.has(d.name)),l=new Set;for(const d of i)for(const c of d.layers)for(const p of c.kinds)l.add(p.name);const a=[];if(l.size>0){for(const d of Object.values(n.elements))if(l.has(d.kind)){const c=i.find(p=>p.layers.some(m=>m.kinds.some(x=>x.name===d.kind)));a.push({elementId:d.id,elementName:d.name,kind:d.kind,fromOntology:(c==null?void 0:c.name)??"unknown"})}}return{success:!0,orphanedElements:a}},setOntologyInstallStatus:n=>e({ontologyInstallStatus:n}),toggleGapBar:()=>e(n=>({gapBarExpanded:!n.gapBarExpanded})),setGapBarHeight:n=>e({gapBarHeight:Math.max(80,Math.min(400,n))}),setCatalogGroupBy:n=>e({catalogGroupBy:n,catalogCollapsed:new Set}),toggleCatalogCollapsed:n=>e(s=>{const o=new Set(s.catalogCollapsed);return o.has(n)?o.delete(n):o.add(n),{catalogCollapsed:o}}),setCatalogCollapsedAll:n=>e(s=>n?{catalogCollapsed:new Set(["__ALL__"])}:{catalogCollapsed:new Set}),setContextMenu:n=>e({contextMenu:n}),setAttributeFilter:n=>e({attributeFilter:n}),setLabelFilter:n=>e({labelFilter:n}),toggleTagFilter:n=>e(s=>({tagFilters:s.tagFilters.includes(n)?s.tagFilters.filter(i=>i!==n):[...s.tagFilters,n]})),clearTagFilters:()=>e({tagFilters:[]}),setEditingElement:n=>e({editingElementId:n}),updateElementField:(n,s,o)=>e(i=>{const l=new Map(i.pendingEdits),a=l.get(n)||{};return l.set(n,{...a,[s]:o}),{pendingEdits:l}}),updateElementAttribute:(n,s,o)=>e(i=>{const l=new Map(i.pendingEdits),a=l.get(n)||{},d={...a.attributes||{},[s]:o};return l.set(n,{...a,attributes:d}),{pendingEdits:l}}),updateElementFolder:(n,s)=>{var l;const o=(l=r().model)==null?void 0:l.elements[n];if(!o)return;const i={...o,attributes:{...o.attributes,[ke]:s}};e(a=>({model:a.model?{...a.model,elements:{...a.model.elements,[n]:i}}:null})),Fe(i)},moveFolder:(n,s,o)=>{const i=r();if(!i.model)return;const l={...i.model.elements},a=[];for(const[d,c]of Object.entries(l))if(c.kind===n){const p=c.attributes[ke]||"";if(p===s||p.startsWith(s+"/")){const m=p.slice(s.length),x=(o+m).replace("//","/"),b={...c,attributes:{...c.attributes,[ke]:x}};l[d]=b,a.push(d)}}if(a.length!==0){e(d=>({model:d.model?{...d.model,elements:l}:null}));for(const d of a)Fe(l[d])}},addElement:(n,s,o)=>{const i=r();if(!i.model)return;const l=`${n.toLowerCase().replace(/\s+/g,"_")}_${Math.random().toString(36).substr(2,5)}`,a=Object.values(i.model.elements).find(c=>c.kind===n),d={id:l,name:s,kind:n,construct:(a==null?void 0:a.construct)||"part",layer:(a==null?void 0:a.layer)||"Other",doc:"",attributes:{[ke]:o},file:(a==null?void 0:a.file)||"model/generated.sysml"};e(c=>({model:c.model?{...c.model,elements:{...c.model.elements,[l]:d}}:null,selectedElementId:l,activeView:{type:"element-detail",elementId:l}})),en(d)},deleteFolder:(n,s)=>{const o=r();if(!o.model)return;const i={...o.model.elements},l=s.includes("/")?s.split("/").slice(0,-1).join("/"):"",a=[];for(const[d,c]of Object.entries(i))if(c.kind===n){const p=c.attributes[ke]||"";if(p===s||p.startsWith(s+"/")){const m=p.replace(s,l).replace("//","/"),x={...c,attributes:{...c.attributes,[ke]:m}};i[d]=x,a.push(d)}}if(a.length!==0){e(d=>({model:d.model?{...d.model,elements:i}:null}));for(const d of a)Fe(i[d])}},addUserViewpoint:n=>e(s=>({userViewpoints:[...s.userViewpoints,n]})),updateUserViewpoint:n=>e(s=>({userViewpoints:s.userViewpoints.map(o=>o.id===n.id?n:o)})),deleteUserViewpoint:n=>e(s=>({userViewpoints:s.userViewpoints.filter(o=>o.id!==n),selectedViewpointId:s.selectedViewpointId===n?null:s.selectedViewpointId})),createDiagram:({name:n,diagramType:s,viewpointId:o})=>{const i=`diag_${Math.random().toString(36).substr(2,9)}`,l={id:i,name:n,diagramType:s,viewpointId:o,auto:!1,elementIds:[]};e(a=>({model:a.model?{...a.model,diagrams:[...a.model.diagrams??[],l]}:null,selectedDiagramId:i,activeView:{type:"diagram",diagramId:i}})),Go({id:i,name:n,diagramType:s,viewpointId:o,elementIds:[]})},updateDiagramElementIds:(n,s)=>{const{model:o}=r();if(!(o!=null&&o.diagrams))return;const i=o.diagrams.findIndex(d=>d.id===n);if(i<0)return;const l={...o.diagrams[i],elementIds:s},a=[...o.diagrams];a[i]=l,e(d=>({model:d.model?{...d.model,diagrams:a}:null})),tn({id:n,elementIds:s})},deleteDiagram:n=>{e(s=>({model:s.model?{...s.model,diagrams:(s.model.diagrams??[]).filter(o=>o.id!==n)}:null,selectedDiagramId:s.selectedDiagramId===n?null:s.selectedDiagramId,activeView:s.activeView.type==="diagram"&&s.activeView.diagramId===n?{type:"welcome"}:s.activeView})),Yo(n)},applyDiagramParseResult:(n,s,o)=>{const{model:i}=r();if(!(i!=null&&i.diagrams))return;const l=i.diagrams.findIndex(a=>a.id===n);if(l>=0){const a={...i.diagrams[l],elementIds:s},d=[...i.diagrams];d[l]=a,e(c=>({model:c.model?{...c.model,diagrams:d}:null,diagramParseErrors:{...c.diagramParseErrors,[n]:o}})),tn({id:n,elementIds:s})}else e(a=>({diagramParseErrors:{...a.diagramParseErrors,[n]:o}}))},addDhfDocument:n=>e(s=>({dhfDocuments:[...s.dhfDocuments,n]})),setDhfDocuments:n=>e({dhfDocuments:n}),hydrateDhfSettings:n=>e(s=>({dhfSettings:{...s.dhfSettings,...n}})),updateDhfSettings:n=>e(s=>({dhfSettings:{...s.dhfSettings,...n}})),updateDhfDocumentMeta:(n,s)=>e(o=>({dhfDocuments:o.dhfDocuments.map(i=>i.id===n?{...i,...s}:i)})),updateDhfDocumentContent:(n,s)=>e(o=>({dhfDocuments:o.dhfDocuments.map(i=>i.id===n?{...i,content:s}:i)})),removeDhfDocument:n=>e(s=>({dhfDocuments:s.dhfDocuments.filter(o=>o.id!==n),activeView:s.activeView.type==="dhf-document"&&s.activeView.docId===n?{type:"dhf-dashboard"}:s.activeView})),setBulkImportOpen:n=>e({bulkImportOpen:n}),setImportResult:n=>e({importResult:n}),clearImportResult:()=>e({importResult:null}),cancelEdit:n=>e(s=>{const o=new Map(s.pendingEdits);return o.delete(n),{pendingEdits:o}}),applyEdit:async n=>{const{pendingEdits:s,model:o}=r(),i=s.get(n);if(!i||!o)return;const l=o.elements[n];if(!l)return;const a={...l};i.doc!==void 0&&(a.doc=i.doc),i.attributes&&(a.attributes={...l.attributes,...i.attributes}),n.startsWith("new_")?en(a):Fe(a);const d={...o,elements:{...o.elements,[n]:a}},c=new Map(s);c.delete(n),e({model:d,pendingEdits:c})}}));function tl(e){const r=new Map;if(!e)return r;for(const n of Object.values(e.elements))r.has(n.layer)||r.set(n.layer,[]),r.get(n.layer).push(n);return r}function es(e,r){return e?e.relationships.filter(n=>n.sourceId===r||n.targetId===r):[]}function Yn(e,r){return!e||!r||!e.diagrams?null:e.diagrams.find(n=>n.id===r)??null}function on(e,r){return e!=null&&e.diagrams?e.diagrams.filter(n=>n.viewpointId===r):[]}const ts=new Set(["catalog","diagram","dhf"]);function Je(){S(d=>d.model);const e=S(d=>d.setActiveView),r=S(d=>d.setActiveMode),n=S(d=>d.sidebarCollapsed),s=S(d=>d.toggleSidebar),o=S(d=>d.activeMode),i=Ce(),l=ts.has(o);function a(){r("catalog"),e({type:"welcome"}),i("/")}return t.jsxs("div",{className:"flex items-center gap-3 px-4 py-2",style:{background:"#0B1E2D",borderBottom:"1px solid rgba(255,255,255,0.06)",position:"relative",zIndex:10},children:[t.jsx("button",{onClick:l?s:void 0,title:n?"Show explorer":"Hide explorer",style:{width:"28px",height:"28px",borderRadius:"6px",background:"none",border:"none",cursor:l?"pointer":"default",color:l?n?"rgba(255,255,255,0.35)":"#2DD4A8":"rgba(255,255,255,0.12)",display:"flex",alignItems:"center",justifyContent:"center",fontSize:"16px",flexShrink:0,transition:"color 150ms"},onMouseEnter:d=>{l&&(d.currentTarget.style.color="#2DD4A8")},onMouseLeave:d=>{l&&(d.currentTarget.style.color=n?"rgba(255,255,255,0.35)":"#2DD4A8")},children:"☰"}),t.jsx("button",{onClick:a,className:"text-sm font-bold transition-opacity",style:{color:"#2DD4A8",letterSpacing:"0.04em",background:"none",border:"none",cursor:"pointer",padding:0},onMouseEnter:d=>d.currentTarget.style.opacity="0.75",onMouseLeave:d=>d.currentTarget.style.opacity="1",title:"Go to home",children:"MEMO Architect"}),t.jsx("div",{className:"flex-1"}),t.jsx("img",{src:"/logo.png",alt:"MEMO",style:{height:40,opacity:.9,cursor:"pointer"},onClick:a,title:"Go to home"})]})}const Jn="memo-working-sets",Qn="memo-quick-slots";function ns(){return`ws-${Date.now()}-${Math.random().toString(36).slice(2,8)}`}function Qe(e){try{localStorage.setItem(Jn,JSON.stringify(e))}catch{}}function rs(){try{const e=localStorage.getItem(Jn);return e?JSON.parse(e):[]}catch{return[]}}function sn(){try{const e=localStorage.getItem(Qn);return e?JSON.parse(e):[null,null,null,null]}catch{return[null,null,null,null]}}function an(e){try{localStorage.setItem(Qn,JSON.stringify(e))}catch{}}const ut=jn((e,r)=>({workingSets:[],activeWorkingSetId:null,quickSlots:sn(),loadFromStorage:()=>{const n=rs(),s=sn();e({workingSets:n,quickSlots:s})},saveWorkingSet:(n,s)=>{const o=ns(),i=Date.now(),l={id:o,name:n,createdAt:i,updatedAt:i,state:s},a=[...r().workingSets,l];return e({workingSets:a,activeWorkingSetId:o}),Qe(a),o},updateWorkingSet:(n,s)=>{const o=r().workingSets.map(i=>i.id===n?{...i,state:s,updatedAt:Date.now()}:i);e({workingSets:o}),Qe(o)},renameWorkingSet:(n,s)=>{const o=r().workingSets.map(i=>i.id===n?{...i,name:s,updatedAt:Date.now()}:i);e({workingSets:o}),Qe(o)},deleteWorkingSet:n=>{const s=r().workingSets.filter(i=>i.id!==n),o=r().activeWorkingSetId===n?null:r().activeWorkingSetId;e({workingSets:s,activeWorkingSetId:o}),Qe(s)},setActiveWorkingSet:n=>e({activeWorkingSetId:n}),saveQuickSlot:(n,s,o)=>{const i=["Last Session","Slot 1","Slot 2","Slot 3"],l=[...r().quickSlots];for(;l.length<4;)l.push(null);l[n]={name:o??i[n],state:s,savedAt:Date.now()},an(l),e({quickSlots:l})},clearQuickSlot:n=>{const s=[...r().quickSlots];s[n]=null,an(s),e({quickSlots:s})}})),C={badge:"12px",xs:"12px",sm:"13px",md:"14px",lg:"15px",explorer:{group:"13px",kind:"12px",item:"13px",element:"13px",count:"12px",search:"13px"}},g={primary:"#1a1a1a",secondary:"#4B5563",muted:"#6B7280",faint:"#9CA3AF",surface:"#FFFFFF",surfaceAlt:"#F7F7F5",border:"#E5E5E0",borderLight:"#EDEDEA",accent:"#2DD4A8",accentDark:"#1B3A4B"},nl={sm:"0 1px 3px rgba(0,0,0,0.08)",md:"0 2px 8px rgba(0,0,0,0.1)",selected:"0 0 0 2px #2DD4A8, 0 4px 12px rgba(45, 212, 168, 0.3)"},rl={md:"10px"},ol={defaultWidth:2,flowWidth:2.5,arrowSize:16,labelBgPadding:[6,4],labelBgRadius:6,labelBgStyle:{fill:"#FFFFFF",fillOpacity:.92,stroke:"#E5E5E0",strokeWidth:.5}};function pt(){const e=S.getState();return{activeView:e.activeView,explorerTab:e.explorerTab,selectedElementId:e.selectedElementId,selectedViewpointId:e.selectedViewpointId,selectedDiagramId:e.selectedDiagramId,sidebarCollapsed:e.sidebarCollapsed,propertiesPanelCollapsed:e.propertiesPanelCollapsed,hiddenLayers:Array.from(e.hiddenLayers)}}function mt(e){const r=S.getState();r.setActiveView(e.activeView),r.setExplorerTab(e.explorerTab),r.selectElement(e.selectedElementId),e.selectedDiagramId&&r.selectDiagram(e.selectedDiagramId),e.selectedViewpointId&&r.selectViewpoint(e.selectedViewpointId)}function os(){const[e,r]=u.useState(!1),n=u.useRef(null),s=ut(a=>a.quickSlots),o=ut(a=>a.saveQuickSlot),i=ut(a=>a.clearQuickSlot);u.useEffect(()=>{if(!e)return;const a=d=>{n.current&&!n.current.contains(d.target)&&r(!1)};return document.addEventListener("mousedown",a),()=>document.removeEventListener("mousedown",a)},[e]),u.useEffect(()=>{const a=()=>{o(0,pt(),"Last Session")};return window.addEventListener("beforeunload",a),()=>window.removeEventListener("beforeunload",a)},[o]),u.useEffect(()=>{const a=d=>{if(!(d.ctrlKey||d.metaKey))return;const c=d.key==="1"?1:d.key==="2"?2:d.key==="3"?3:null;if(c)if(d.preventDefault(),d.shiftKey)o(c,pt());else{const p=s[c];p&&mt(p.state)}};return window.addEventListener("keydown",a),()=>window.removeEventListener("keydown",a)},[s,o]);const l=["Last Session","Slot 1","Slot 2","Slot 3"];return t.jsxs("div",{ref:n,style:{position:"relative"},children:[t.jsxs("button",{onClick:()=>r(a=>!a),className:"flex items-center gap-1 px-3 py-1.5 text-sm font-medium rounded-md transition-all",style:e?{background:"rgba(45,212,168,0.15)",color:"#2DD4A8"}:{background:"transparent",color:"rgba(255,255,255,0.5)"},title:"Workspaces (Ctrl+1/2/3 to restore, Ctrl+Shift+1/2/3 to save)",children:[t.jsx("span",{children:"⊟"}),t.jsx("span",{style:{fontSize:"10px",marginLeft:"2px",opacity:.7},children:"▾"})]}),e&&t.jsxs("div",{style:{position:"absolute",top:"calc(100% + 6px)",right:0,zIndex:100,background:"#132D3E",border:"1px solid rgba(45,212,168,0.2)",borderRadius:"8px",minWidth:"240px",boxShadow:"0 8px 24px rgba(0,0,0,0.4)",overflow:"hidden"},children:[t.jsx("div",{className:"px-3 py-2",style:{borderBottom:"1px solid rgba(255,255,255,0.08)",fontSize:C.xs,color:"rgba(255,255,255,0.4)",fontWeight:600},children:"WORKSPACES"}),t.jsxs("div",{className:"px-3 py-2",style:{borderBottom:"1px solid rgba(255,255,255,0.06)"},children:[t.jsxs("div",{className:"flex items-center justify-between gap-2",children:[t.jsx("span",{style:{fontSize:C.xs,color:"rgba(255,255,255,0.5)",fontWeight:600},children:"Last Session"}),s[0]?t.jsx("button",{onClick:()=>{mt(s[0].state),r(!1)},className:"px-2 py-0.5 rounded text-xs",style:{background:"rgba(45,212,168,0.15)",color:"#2DD4A8",border:"none",cursor:"pointer"},children:"Restore"}):t.jsx("span",{style:{fontSize:"10px",color:"rgba(255,255,255,0.25)"},children:"— none saved —"})]}),s[0]&&t.jsx("div",{style:{fontSize:"10px",color:"rgba(255,255,255,0.3)",marginTop:2},children:new Date(s[0].savedAt).toLocaleString()})]}),[1,2,3].map(a=>{const d=s[a];return t.jsxs("div",{className:"flex items-center gap-2 px-3 py-2",style:{borderBottom:"1px solid rgba(255,255,255,0.04)"},children:[t.jsxs("span",{style:{fontSize:"10px",fontWeight:700,color:"rgba(255,255,255,0.3)",minWidth:"16px"},children:["⌃",a]}),t.jsx("div",{className:"flex-1 min-w-0",children:d?t.jsxs(t.Fragment,{children:[t.jsx("div",{style:{fontSize:C.xs,color:"rgba(255,255,255,0.7)",fontWeight:500},children:d.name}),t.jsx("div",{style:{fontSize:"10px",color:"rgba(255,255,255,0.3)"},children:new Date(d.savedAt).toLocaleTimeString()})]}):t.jsx("span",{style:{fontSize:C.xs,color:"rgba(255,255,255,0.25)",fontStyle:"italic"},children:"empty"})}),t.jsxs("div",{className:"flex gap-1",children:[d&&t.jsx("button",{onClick:()=>{mt(d.state),r(!1)},style:{fontSize:"10px",padding:"2px 6px",borderRadius:3,background:"rgba(45,212,168,0.15)",color:"#2DD4A8",border:"none",cursor:"pointer"},children:"Restore"}),t.jsx("button",{onClick:()=>o(a,pt(),l[a]),style:{fontSize:"10px",padding:"2px 6px",borderRadius:3,background:"rgba(255,255,255,0.1)",color:"rgba(255,255,255,0.6)",border:"none",cursor:"pointer"},title:`Save current view to Slot ${a} (⌃⇧${a})`,children:"Save"}),d&&t.jsx("button",{onClick:()=>i(a),style:{fontSize:"10px",padding:"2px 4px",borderRadius:3,background:"transparent",color:"rgba(255,255,255,0.3)",border:"none",cursor:"pointer"},title:"Clear slot",children:"✕"})]})]},a)})]})]})}const ss="/help/",is=[{id:"dashboard",label:"Dashboard",icon:"⌂"},{id:"catalog",label:"Model Explorer",icon:"☰"},{id:"diagram",label:"Diagrams",icon:"⊟"},{id:"dhf",label:"DHF",icon:"⊞"},{id:"scenario",label:"Scenarios",icon:"▶"},{id:"ontology",label:"Ontology",icon:"◉"},{id:"import",label:"Import",icon:"↓"}],as=new Set(["dsm","traceability","statistics","compliance-wizard","model-diff","review-dashboard","workflow-wizard"]),ln=[{id:"dsm",label:"Design Structure Matrix",icon:"▤",view:{type:"dsm"}},{id:"traceability",label:"Traceability Matrix",icon:"☷",view:{type:"traceability"}},{id:"statistics",label:"Statistics Dashboard",icon:"⊠",view:{type:"statistics"}},{id:"compliance-wizard",label:"Compliance Wizard",icon:"☑",view:{type:"compliance-wizard"}},{id:"model-diff",label:"Model Diff",icon:"↔",view:{type:"model-diff"}},{id:"review-dashboard",label:"Design Review Dashboard",icon:"📋",view:{type:"review-dashboard"}},{id:"workflow-wizard",label:"Workflow Wizard",icon:"🧙",view:{type:"workflow-wizard"}}];function ls({activeViewType:e}){const r=S(a=>a.setActiveView);S(a=>a.setActiveMode);const[n,s]=u.useState(!1),o=u.useRef(null),l=ln.map(a=>a.id).includes(e);return u.useEffect(()=>{function a(d){o.current&&!o.current.contains(d.target)&&s(!1)}return n&&document.addEventListener("mousedown",a),()=>document.removeEventListener("mousedown",a)},[n]),t.jsxs("div",{ref:o,style:{position:"relative"},children:[t.jsxs("button",{onClick:()=>s(a=>!a),className:"flex items-center gap-1 px-4 py-1.5 text-sm font-medium rounded-md transition-all",style:l||n?{background:"rgba(45, 212, 168, 0.15)",color:"#2DD4A8"}:{background:"transparent",color:"rgba(255,255,255,0.5)"},children:[t.jsx("span",{className:"mr-0.5",children:"⚙"}),"Tools",t.jsx("span",{style:{fontSize:"10px",marginLeft:"2px",opacity:.7},children:"▾"})]}),n&&t.jsx("div",{style:{position:"absolute",top:"calc(100% + 6px)",left:0,zIndex:100,background:"#132D3E",border:"1px solid rgba(45,212,168,0.2)",borderRadius:"8px",minWidth:"220px",boxShadow:"0 8px 24px rgba(0,0,0,0.4)",overflow:"hidden"},children:ln.map((a,d)=>{const c=e===a.view.type;return t.jsxs("button",{onClick:()=>{r(c?{type:"welcome"}:a.view),s(!1)},className:"w-full flex items-center gap-3 px-4 py-2.5 text-left transition-colors",style:{fontSize:"13px",color:c?"#2DD4A8":"rgba(255,255,255,0.75)",background:c?"rgba(45,212,168,0.1)":"transparent",borderTop:d>0?"1px solid rgba(255,255,255,0.05)":"none"},onMouseEnter:p=>{c||(p.currentTarget.style.background="rgba(255,255,255,0.06)")},onMouseLeave:p=>{c||(p.currentTarget.style.background="transparent")},children:[t.jsx("span",{style:{width:"18px",textAlign:"center",opacity:.7},children:a.icon}),a.label]},a.id)})})]})}function cs(){const e=S(m=>m.activeMode),r=S(m=>m.setActiveMode),n=S(m=>m.activeView),s=S(m=>m.setActiveView),o=S(m=>m.setExplorerTab),i=S(m=>m.sidebarCollapsed),l=S(m=>m.toggleSidebar),a=Ce(),d=["catalog","diagram","dhf"],c=as.has(n.type)?"":e==="dhf"||n.type==="dhf-dashboard"?"dhf":n.type==="scenario-editor"?"scenario":n.type==="ontology"||n.type==="ontology-detail"?"ontology":n.type==="import"?"import":n.type==="diagram"||e==="diagram"?"diagram":e==="catalog"?"catalog":n.type==="dashboard"?"dashboard":e;function p(m){if(m===c&&d.includes(m)){l();return}switch(d.includes(m)&&i&&l(),r(m),m){case"dashboard":s({type:"dashboard"}),a("/");break;case"catalog":s({type:"welcome"}),a("/catalog");break;case"diagram":o("views"),s({type:"welcome"}),a("/");break;case"dhf":s({type:"dhf-dashboard"}),a("/");break;case"scenario":s({type:"scenario-editor"}),a("/");break;case"ontology":s({type:"ontology"}),a("/");break;case"import":s({type:"import"}),a("/");break}}return t.jsxs("div",{className:"flex items-center gap-1 px-5 py-3",style:{background:"#1B3A4B",borderBottom:"1px solid rgba(255,255,255,0.08)",overflow:"visible",position:"relative",zIndex:10},children:[is.map(m=>t.jsxs("button",{onClick:()=>p(m.id),className:"px-4 py-1.5 text-sm font-medium rounded-md transition-all",style:c===m.id?{background:"rgba(45, 212, 168, 0.15)",color:"#2DD4A8"}:{background:"transparent",color:"rgba(255,255,255,0.5)"},children:[t.jsx("span",{className:"mr-1.5",children:m.icon}),m.label]},m.id)),t.jsx("div",{style:{width:"1px",height:"20px",background:"rgba(255,255,255,0.12)",margin:"0 4px"}}),t.jsx(ls,{activeViewType:n.type}),t.jsx("div",{className:"flex-1"}),t.jsx(os,{}),t.jsx("a",{href:ss,target:"_blank",rel:"noopener noreferrer",className:"px-4 py-1.5 text-sm font-medium rounded-md transition-all",style:{color:"rgba(255,255,255,0.4)",textDecoration:"none"},onMouseEnter:m=>m.currentTarget.style.color="rgba(255,255,255,0.75)",onMouseLeave:m=>m.currentTarget.style.color="rgba(255,255,255,0.4)",children:"? Help"}),t.jsx("img",{src:"/memo-top.png",alt:"MEMO",className:"ml-3",style:{height:56,marginTop:-4,marginBottom:-10}})]})}const ie={business:"#8E44AD",requirements:"#4A90D9",risk:"#E74C3C",functional:"#E67E22",behavior:"#FF6B6B",logical:"#7B68EE",physical:"#95A5A6",software:"#F39C12",interfaces:"#1ABC9C",verification:"#2ECC71",ui:"#3498DB"},At={business:"Business Analysis",requirements:"Requirements",risk:"Risk Management",functional:"Functional Analysis",behavior:"Behavior",logical:"Logical Architecture",physical:"Physical Architecture",software:"Software Architecture",interfaces:"Interfaces & Ports",verification:"Verification",ui:"UI Wireframe"},ds=["business","requirements","risk","functional","behavior","logical","physical","software","interfaces","verification","ui"],sl={mitigates:"#E74C3C",causes:"#C0392B",leadsTo:"#E74C3C",identifies:"#D35400",traceTo:"#4A90D9",satisfy:"#2ECC71",verify:"#27AE60",allocateTo:"#E67E22",aggregation:"#7B68EE",composedOf:"#8E44AD",decomposedBy:"#D35400",flow:"#3498DB",succession:"#95A5A6"},us=[{id:"stakeholders",label:"Stakeholders & Goals",color:"#8E44AD",kinds:["Actor","Stakeholder","Goal","Concern","Responsibility","Capability"]},{id:"requirements",label:"Requirements",color:"#4A90D9",kinds:["Requirement","Requirement","Requirement","Requirement","DesignSpecification","Requirement","Standard","RegulatoryRequirement"]},{id:"use-cases",label:"Use Cases & Scenarios",color:"#E67E22",kinds:["UseCase","Scenario","UserActivity","UIFunction"]},{id:"functions",label:"Functions",color:"#D35400",kinds:["Function","Function"]},{id:"behavior",label:"Behavior",color:"#FF6B6B",kinds:["ActionDefinition","ActionUsage","ItemDefinition"]},{id:"logical",label:"Logical Architecture",color:"#7B68EE",kinds:["System","SystemExternal","Subsystem","Component","LogicalComponent","LogicalComponentExternal","EnvironmentElement"]},{id:"decisions",label:"Architecture Decisions",color:"#6C5CE7",kinds:["ArchitectureDecision","ArchitectureRationale","QualityAttribute","Question"]},{id:"physical",label:"Physical Architecture",color:"#95A5A6",kinds:["PhysicalComponent","ElectricalComponent","MechanicalComponent","PhysicalModule","HardwareNode","ComputingDevice","FPGA","Catheter","Microcontroller","SingleBoardComputer"]},{id:"software",label:"Software Architecture",color:"#F39C12",kinds:["Software","SoftwareComponent","SoftwareModule","Firmware","Docker","OperatingSystem","RosNode"]},{id:"interfaces",label:"Interfaces & Ports",color:"#1ABC9C",kinds:["Port","Port","Port","Port","Port","Interface","SoftwareInterface","SoftwareProvidedInterface","SoftwareRequiredInterface","DataType","RosTopic","RosService"]},{id:"risk",label:"Risk Management",color:"#E74C3C",kinds:["Hazard","HazardousSituation","Harm","Risk","RiskControl","SafetyGoal"]},{id:"verification",label:"Verification & Testing",color:"#2ECC71",kinds:["Test"]},{id:"ui",label:"UI Wireframes",color:"#3498DB",kinds:["UIScreen","UIPanel","UIElement"]}],zt={};for(const e of us)for(const r of e.kinds)zt[r]=e;const ps=new Set(Object.keys(zt)),ms=[...ps].sort(),fs=new Set(["ActionDefinition","ActionUsage","ItemDefinition"]),hs={general:{label:"GEN",fullName:"General View",color:"#7B68EE"},interconnection:{label:"INT",fullName:"Interconnection View",color:"#1ABC9C"},actionflow:{label:"ACT",fullName:"Action Flow View",color:"#F39C12"},statetransition:{label:"STM",fullName:"State Transition View",color:"#FF6B6B"},sequence:{label:"SEQ",fullName:"Sequence View",color:"#3498DB"},grid:{label:"GRID",fullName:"Grid View",color:"#2ECC71"},browser:{label:"BRW",fullName:"Browser View",color:"#95A5A6"},geometry:{label:"GEO",fullName:"Geometry View",color:"#8E44AD"}},Ae={bdd:{code:"BDD",label:"BDD",fullName:"Block Definition Diagram",color:"#7B68EE",viewKind:"general"},ibd:{code:"IBD",label:"IBD",fullName:"Internal Block Diagram",color:"#1ABC9C",viewKind:"interconnection"},req:{code:"REQ",label:"REQ",fullName:"Requirements Diagram",color:"#4A90D9",viewKind:"general"},ucd:{code:"UCD",label:"UCD",fullName:"Use Case Diagram",color:"#E67E22",viewKind:"general"},act:{code:"ACT",label:"ACT",fullName:"Activity Diagram",color:"#F39C12",viewKind:"actionflow"},afd:{code:"AFD",label:"AFD",fullName:"Action Flow Diagram",color:"#FF6B6B",viewKind:"actionflow"},ofd:{code:"OFD",label:"OFD",fullName:"Operational Flow Diagram",color:"#F39C12",viewKind:"actionflow"},ffd:{code:"FFD",label:"FFD",fullName:"Functional Flow Diagram",color:"#F39C12",viewKind:"actionflow"},pkg:{code:"PKG",label:"PKG",fullName:"Package Diagram",color:"#95A5A6",viewKind:"general"},par:{code:"PAR",label:"PAR",fullName:"Parametric Diagram",color:"#2ECC71",viewKind:"interconnection"},risk:{code:"RISK",label:"RISK",fullName:"Risk Diagram",color:"#E74C3C",viewKind:"general"},stm:{code:"STM",label:"STM",fullName:"State Transition Diagram",color:"#FF6B6B",viewKind:"statetransition"},seq:{code:"SEQ",label:"SEQ",fullName:"Sequence Diagram",color:"#3498DB",viewKind:"sequence"},fmea:{code:"FMEA",label:"FMEA",fullName:"FMEA Matrix",color:"#E74C3C",viewKind:"grid"},alloc:{code:"ALLOC",label:"ALLOC",fullName:"Allocation Matrix",color:"#E67E22",viewKind:"grid"},"threat-model":{code:"THREAT",label:"THREAT",fullName:"Threat Model Diagram",color:"#C0392B",viewKind:"general"}};function gs(e){const r=e.diagramType.trim().toLowerCase();return r==="ofd"||r==="ffd"?r:"afd"}const il=["#FFFFFF","#f8fafc","#f0f9ff","#fdf2f8","#f0fdf4"];function Se({label:e,onClick:r,icon:n}){return t.jsxs("button",{className:"w-full flex items-center gap-2 px-3 py-1.5 text-left text-xs",style:{color:"#374151",background:"transparent",border:"none",cursor:"pointer",whiteSpace:"nowrap"},onMouseEnter:s=>s.currentTarget.style.background="#F0F0ED",onMouseLeave:s=>s.currentTarget.style.background="transparent",onClick:s=>{s.stopPropagation(),r()},children:[n&&t.jsx("span",{style:{fontSize:"12px",width:"14px",flexShrink:0},children:n}),e]})}function ys(){return t.jsx("div",{style:{height:"1px",background:"#E5E5E0",margin:"3px 0"}})}function xs({x:e,y:r,target:n,onViewVisual:s,onViewTable:o,onToggleSelection:i,onViewProperties:l,onClose:a}){const d=u.useRef(null);u.useEffect(()=>{if(!d.current)return;const p=d.current,{innerWidth:m,innerHeight:x}=window,b=p.getBoundingClientRect();b.right>m&&(p.style.left=`${e-b.width}px`),b.bottom>x&&(p.style.top=`${r-b.height}px`)},[e,r]);const c={position:"fixed",top:r,left:e,background:"#FFFFFF",border:"1px solid #E5E5E0",borderRadius:"6px",boxShadow:"0 4px 12px rgba(0,0,0,0.12)",zIndex:9999,minWidth:"180px",padding:"4px 0"};return n.type==="package"?t.jsxs("div",{ref:d,style:c,onMouseDown:p=>p.stopPropagation(),children:[t.jsx(Se,{icon:"⬜",label:"View Visual Layout",onClick:()=>{s(n.pkgName),a()}}),t.jsx(Se,{icon:"☰",label:"View as Table",onClick:()=>{o(n.pkgName),a()}}),t.jsx(ys,{}),t.jsx(Se,{icon:n.isSelected?"☑":"☐",label:n.isSelected?"Deselect for Project":"Select for Project",onClick:()=>i(n.pkgName)})]}):n.type==="layer"?t.jsxs("div",{ref:d,style:c,onMouseDown:p=>p.stopPropagation(),children:[t.jsx(Se,{icon:"⬜",label:"View Visual Layout",onClick:()=>{s(n.pkgName),a()}}),t.jsx(Se,{icon:"☰",label:"View as Table",onClick:()=>o(n.pkgName,n.layerId)})]}):t.jsxs("div",{ref:d,style:c,onMouseDown:p=>p.stopPropagation(),children:[t.jsx(Se,{icon:"🔍",label:"View Properties",onClick:()=>l(n.kindName,n.pkgName)}),t.jsx(Se,{icon:"☰",label:"View as Table",onClick:()=>o(n.pkgName,n.layerId)}),t.jsx(Se,{icon:"⬜",label:"Show in Visual Layout",onClick:()=>{s(n.pkgName),a()}})]})}function bs({kindsToRemap:e,onConfirm:r,onCancel:n}){const s=S(p=>p.availableOntologies),o=S(p=>p.selectedOntologies),i=s.filter(p=>o.has(p.name)).flatMap(p=>p.layers.flatMap(m=>m.kinds.map(x=>x.name))).filter((p,m,x)=>x.indexOf(p)===m).sort(),[l,a]=u.useState(Object.fromEntries(e.map(p=>[p,""])));function d(p,m){a(x=>({...x,[p]:m}))}const c=e.every(p=>l[p]);return t.jsx("div",{className:"fixed inset-0 flex items-center justify-center z-50",style:{background:"rgba(0,0,0,0.4)"},children:t.jsxs("div",{className:"rounded-xl shadow-2xl max-w-lg w-full mx-4 overflow-hidden",style:{background:"#FFFFFF",border:"1px solid #E5E5E0"},children:[t.jsxs("div",{className:"px-6 py-4",style:{borderBottom:"1px solid #E5E5E0"},children:[t.jsx("h2",{className:"text-sm font-semibold",style:{color:"#1a1a1a"},children:"Remap Orphaned Kinds"}),t.jsx("p",{className:"text-xs mt-1",style:{color:"#6B7280"},children:"Map each orphaned kind to a kind in the selected ontologies. Model elements will be updated to use the new kind."})]}),t.jsx("div",{className:"px-6 py-4 space-y-3 max-h-64 overflow-y-auto",children:e.map(p=>t.jsxs("div",{className:"flex items-center gap-3",children:[t.jsx("div",{className:"flex-1 px-2 py-1 rounded text-xs font-medium",style:{background:"#FEF2F2",color:"#EF4444",border:"1px solid #FCA5A5"},children:p}),t.jsx("span",{style:{color:"#9CA3AF"},children:"→"}),t.jsxs("select",{value:l[p],onChange:m=>d(p,m.target.value),className:"flex-1 text-xs rounded-md px-2 py-1 focus:outline-none",style:{border:"1px solid #E5E5E0",color:"#1a1a1a",background:"#FFFFFF"},children:[t.jsx("option",{value:"",children:"Select target kind…"}),i.map(m=>t.jsx("option",{value:m,children:m},m))]})]},p))}),t.jsxs("div",{className:"px-6 py-4 flex gap-2 justify-end",style:{borderTop:"1px solid #E5E5E0"},children:[t.jsx("button",{onClick:n,className:"px-3 py-1.5 text-xs rounded-md",style:{background:"#F0F0ED",color:"#374151"},children:"Back"}),t.jsx("button",{onClick:()=>r(l),disabled:!c,className:"px-3 py-1.5 text-xs rounded-md font-medium",style:{background:c?"#1B3A4B":"#E5E5E0",color:c?"#FFFFFF":"#9CA3AF",cursor:c?"pointer":"not-allowed"},children:"Apply Remapping"})]})]})})}function vs({orphans:e,onKeep:r,onRemap:n,onCancel:s}){const[o,i]=u.useState(!1),l=new Map;for(const a of e)l.has(a.kind)||l.set(a.kind,[]),l.get(a.kind).push(a);return o?t.jsx(bs,{kindsToRemap:[...l.keys()],onConfirm:n,onCancel:()=>i(!1)}):t.jsx("div",{className:"fixed inset-0 flex items-center justify-center z-50",style:{background:"rgba(0,0,0,0.4)"},onClick:a=>{a.target===a.currentTarget&&s()},children:t.jsxs("div",{className:"rounded-xl shadow-2xl max-w-md w-full mx-4 overflow-hidden",style:{background:"#FFFFFF",border:"1px solid #E5E5E0"},children:[t.jsxs("div",{className:"px-6 py-4",style:{borderBottom:"1px solid #E5E5E0",background:"#FEF2F2"},children:[t.jsxs("div",{className:"flex items-center gap-2",children:[t.jsx("span",{className:"text-red-500 text-lg",children:"⚠"}),t.jsx("h2",{className:"text-sm font-semibold",style:{color:"#1a1a1a"},children:"Orphaned Elements"})]}),t.jsxs("p",{className:"text-xs mt-1",style:{color:"#6B7280"},children:[e.length," element",e.length!==1?"s":""," use kinds from the deselected ontology."]})]}),t.jsx("div",{className:"px-6 py-4 max-h-48 overflow-y-auto",children:[...l.entries()].map(([a,d])=>t.jsxs("div",{className:"mb-3",children:[t.jsxs("div",{className:"text-xs font-semibold mb-1",style:{color:"#374151"},children:[a,t.jsxs("span",{className:"ml-1 font-normal",style:{color:"#9CA3AF"},children:["(",d.length," element",d.length!==1?"s":"",")"]})]}),t.jsxs("div",{className:"flex flex-wrap gap-1",children:[d.slice(0,5).map(c=>t.jsx("span",{className:"px-1.5 py-0.5 text-xs rounded",style:{background:"#FEF2F2",color:"#EF4444",border:"1px solid #FCA5A5"},children:c.elementName},c.elementId)),d.length>5&&t.jsxs("span",{className:"text-xs",style:{color:"#9CA3AF"},children:["+",d.length-5," more"]})]})]},a))}),t.jsxs("div",{className:"px-6 py-4 flex gap-2 justify-end",style:{borderTop:"1px solid #E5E5E0"},children:[t.jsx("button",{onClick:s,className:"px-3 py-1.5 text-xs rounded-md",style:{background:"#F0F0ED",color:"#374151"},children:"Cancel"}),t.jsx("button",{onClick:r,className:"px-3 py-1.5 text-xs rounded-md",style:{background:"#FEF2F2",color:"#EF4444",border:"1px solid #FCA5A5"},children:"Keep (mark orphaned)"}),t.jsx("button",{onClick:()=>i(!0),className:"px-3 py-1.5 text-xs rounded-md font-medium",style:{background:"#1B3A4B",color:"#FFFFFF"},children:"Remap kinds →"})]})]})})}const cn={ontology:"📦",profile:"🔧",extension:"🧩"};function ws(e){const r=new Map(e.map(a=>[a.name,a])),n=new Map;function s(a){if(n.has(a))return n.get(a);const d=r.get(a);if(!d||!d.derivesFrom||!r.has(d.derivesFrom))return n.set(a,0),0;const c=s(d.derivesFrom)+1;return n.set(a,c),c}for(const a of e)s(a.name);const o=new Map;for(const a of e){const d=n.get(a.name)??0,c=o.get(d)??[];c.push(a),o.set(d,c)}const i=Math.max(...o.keys()),l=[];for(let a=0;a<=i;a++){const d=o.get(a)??[];l.push(...d.sort((c,p)=>c.name.localeCompare(p.name)))}return l}function Ss(e){const r=new Map(e.map(a=>[a.name,a])),n=new Map;function s(a){if(n.has(a))return n.get(a);const d=r.get(a);if(!d||!d.extends||!r.has(d.extends))return n.set(a,0),0;const c=s(d.extends)+1;return n.set(a,c),c}for(const a of e)s(a.name);const o=new Map;for(const a of e){const d=n.get(a.name)??0,c=o.get(d)??[];c.push(a),o.set(d,c)}const i=o.size>0?Math.max(...o.keys()):0,l=[];for(let a=0;a<=i;a++){const d=o.get(a)??[];l.push(...d.sort((c,p)=>c.name.localeCompare(p.name)))}return l}function ks({pkgName:e,onCancel:r,onConfirm:n}){const s=e.replace("@memo/","");return t.jsx("div",{className:"fixed inset-0 z-50 flex items-center justify-center",style:{background:"rgba(0,0,0,0.45)"},onMouseDown:o=>{o.target===o.currentTarget&&r()},children:t.jsxs("div",{className:"rounded-xl p-5 shadow-2xl",style:{background:"#FFFFFF",maxWidth:"340px",width:"90vw"},children:[t.jsx("div",{className:"font-semibold mb-1.5",style:{fontSize:C.sm,color:g.primary},children:"Remove ontology?"}),t.jsxs("div",{className:"mb-4",style:{fontSize:C.xs,color:g.secondary,lineHeight:1.5},children:["Removing ",t.jsx("strong",{children:s})," will affect all model elements that depend on its kinds. Those elements will become orphaned until you add a compatible ontology."]}),t.jsxs("div",{className:"flex gap-2 justify-end",children:[t.jsx("button",{onClick:r,className:"px-3 py-1.5 rounded-md font-medium",style:{fontSize:C.xs,background:g.surfaceAlt,color:g.secondary,border:`1px solid ${g.border}`,cursor:"pointer"},children:"Cancel"}),t.jsx("button",{onClick:n,className:"px-3 py-1.5 rounded-md font-medium",style:{fontSize:C.xs,background:"#DC2626",color:"#FFFFFF",border:"none",cursor:"pointer"},children:"Remove"})]})]})})}function Es(){const e=S(h=>h.availableOntologies),r=S(h=>h.selectedOntologies),n=S(h=>h.toggleOntologySelection),s=S(h=>h.saveOntologySelection),o=S(h=>h.selectedOntologyKind),i=S(h=>h.setSelectedOntologyKind),l=S(h=>h.setActiveView),a=S(h=>h.setOntologyViewMode),d=S(h=>h.activeView),[c,p]=u.useState(""),[m,x]=u.useState(()=>new Set(e.filter(h=>h.selected).map(h=>h.name))),[b,k]=u.useState(new Set),[y,v]=u.useState(()=>new Set(e.filter(h=>h.selected).map(h=>h.name))),w=u.useMemo(()=>{if(r.size!==y.size)return!0;for(const h of r)if(!y.has(h))return!0;return!1},[r,y]),[_,N]=u.useState(null),[f,D]=u.useState(null),[E,R]=u.useState(null),T=u.useRef(new Map),O=u.useMemo(()=>{const h=c.trim()?e.map(A=>({...A,layers:A.layers.map(P=>({...P,kinds:P.kinds.filter(Y=>Y.name.toLowerCase().includes(c.toLowerCase())||Y.label.toLowerCase().includes(c.toLowerCase())||Y.layer.toLowerCase().includes(c.toLowerCase()))})).filter(P=>P.kinds.length>0)})).filter(A=>A.layers.length>0||A.name.toLowerCase().includes(c.toLowerCase())):e;return Ss(h)},[e,c]);u.useEffect(()=>{c.trim()&&(x(new Set(O.map(h=>h.name))),k(new Set(O.flatMap(h=>h.layers.map(A=>`${h.name}:${A.id}`)))))},[c,O]),u.useEffect(()=>{if(o&&T.current.has(o)){for(const h of e)for(const A of h.layers)if(A.kinds.find(P=>P.name===o)){x(P=>new Set([...P,h.name])),k(P=>new Set([...P,`${h.name}:${A.id}`]));break}setTimeout(()=>{var h;(h=T.current.get(o))==null||h.scrollIntoView({behavior:"smooth",block:"nearest"})},80)}},[o,e]);function j(h){l({type:"ontology-detail",packageName:h})}function B(h,A){l({type:"ontology-detail",packageName:h,layerId:A})}function H(h,A){i(o===h?null:h),l({type:"ontology-detail",packageName:A})}function U(h){x(A=>{const P=new Set(A);return P.has(h)?P.delete(h):P.add(h),P})}function X(h){k(A=>{const P=new Set(A);return P.has(h)?P.delete(h):P.add(h),P})}function $(h,A,P){h.stopPropagation(),P?D(A):n(A)}function ae(){const h=s();h.orphanedElements&&h.orphanedElements.length>0?N(h.orphanedElements):(dt([...r]),v(new Set(r)))}function I(){dt([...r]),v(new Set(r)),N(null)}function W(h){Jo(h),dt([...r]),v(new Set(r)),N(null)}function G(h,A){h.preventDefault(),h.stopPropagation(),R({x:h.clientX,y:h.clientY,target:A})}function L(h,A){a("table"),l({type:"ontology-detail",packageName:h,layerId:A}),R(null)}function F(h){a("visual"),l({type:"ontology-detail",packageName:h}),R(null)}function q(h){r.has(h)?D(h):n(h),R(null)}function K(h,A){i(h),l({type:"ontology-detail",packageName:A}),R(null)}if(u.useEffect(()=>{function h(A){A.key==="Escape"&&(i(null),R(null),D(null))}return document.addEventListener("keydown",h),()=>document.removeEventListener("keydown",h)},[i]),u.useEffect(()=>{if(!E)return;function h(){R(null)}return document.addEventListener("mousedown",h),()=>document.removeEventListener("mousedown",h)},[E]),e.length===0)return t.jsx("div",{className:"flex-1 flex items-center justify-center p-4",children:t.jsxs("div",{className:"text-center",style:{color:g.faint},children:[t.jsx("div",{className:"text-xl mb-2",children:"◉"}),t.jsx("div",{style:{fontSize:C.xs},children:"No ontology packages"}),t.jsx("div",{style:{fontSize:C.xs,opacity:.7,marginTop:"4px"},children:"Start memo-architect dev to load"})]})});const ne=d.type==="ontology-detail"?d.packageName:null;return t.jsxs("div",{className:"flex flex-col flex-1 overflow-hidden",style:{fontSize:C.explorer.item},children:[t.jsx("div",{className:"px-3 py-2 sticky top-0 z-10",style:{background:g.surface,borderBottom:`1px solid ${g.border}`},children:t.jsx("input",{type:"text",placeholder:"Search kinds...",value:c,onChange:h=>p(h.target.value),className:"w-full px-2.5 py-1.5 rounded-lg focus:outline-none",style:{fontSize:C.explorer.search,border:`1px solid ${g.border}`,background:g.surfaceAlt,color:g.primary},onFocus:h=>h.currentTarget.style.borderColor="#2563EB",onBlur:h=>h.currentTarget.style.borderColor=g.border})}),t.jsx("div",{className:"flex-1 overflow-y-auto py-1",children:O.map(h=>{const A=r.has(h.name),P=ne===h.name,Y=m.has(h.name),re=h.name.replace("@memo/",""),Z=cn[h.type]??cn.ontology;return t.jsxs("div",{children:[t.jsxs("div",{className:"flex items-center gap-1.5 px-2 py-1.5 cursor-pointer",style:{borderRadius:"6px",margin:"0 4px",background:P?`${g.accent}18`:"transparent",borderLeft:P?`3px solid ${g.accentDark}`:"3px solid transparent",opacity:A?1:.55},onMouseEnter:z=>{P||(z.currentTarget.style.background="#F0F0ED")},onMouseLeave:z=>{z.currentTarget.style.background=P?`${g.accent}18`:"transparent"},onClick:z=>{z.stopPropagation(),U(h.name)},onDoubleClick:()=>j(h.name),onContextMenu:z=>G(z,{type:"package",pkgName:h.name,isSelected:A}),children:[t.jsx("input",{type:"checkbox",checked:A,onChange:z=>$(z,h.name,A),onClick:z=>z.stopPropagation(),style:{cursor:"pointer",accentColor:"#2563EB",flexShrink:0},title:A?"Deselect for project":"Select for project"}),t.jsx("span",{style:{color:g.muted,fontSize:"10px"},children:Y?"▾":"▸"}),t.jsx("span",{children:Z}),t.jsx("span",{className:"font-semibold truncate flex-1",style:{color:g.primary,fontSize:C.explorer.group},children:re}),t.jsx("span",{style:{color:g.faint},children:h.kindCount})]}),Y&&h.layers.map(z=>{const se=ie[z.id]??z.color??g.muted,xe=`${h.name}:${z.id}`,ue=b.has(xe),be=ws(z.kinds);return t.jsxs("div",{children:[t.jsxs("div",{className:"flex items-center gap-2 px-3 py-1 cursor-pointer",style:{borderRadius:"4px",margin:"0 4px 0 20px"},onMouseEnter:V=>V.currentTarget.style.background="#F0F0ED",onMouseLeave:V=>V.currentTarget.style.background="transparent",onClick:V=>{V.stopPropagation(),X(xe)},onDoubleClick:()=>B(h.name,z.id),onContextMenu:V=>G(V,{type:"layer",pkgName:h.name,layerId:z.id,layerLabel:z.label}),children:[t.jsx("span",{style:{color:g.faint,fontSize:"9px"},children:ue?"▾":"▸"}),t.jsx("span",{className:"w-2 h-2 rounded flex-shrink-0",style:{backgroundColor:se}}),t.jsx("span",{className:"flex-1 truncate capitalize",style:{color:g.muted,fontSize:C.explorer.kind},children:z.label}),t.jsx("span",{style:{color:g.faint},children:z.kindCount})]}),ue&&(()=>{const V=new Map;for(const J of be){const ce=J.derivesFrom?V.get(J.derivesFrom)??0:0;V.set(J.name,J.derivesFrom?ce+1:0)}const ee=J=>{const ce=o===J.name,qt=V.get(J.name)??0,Vt=qt===0,tr=36+qt*12;return t.jsxs("div",{ref:we=>{we&&T.current.set(J.name,we)},className:"flex items-center gap-1.5 px-3 py-0.5 cursor-pointer",style:{borderRadius:"4px",margin:`0 4px 0 ${tr}px`,background:ce?`${g.accent}18`:"transparent",borderLeft:ce?`2px solid ${se}`:"2px solid transparent",transition:"background 150ms ease"},onMouseEnter:we=>{ce||(we.currentTarget.style.background="#F0F0ED")},onMouseLeave:we=>{we.currentTarget.style.background=ce?`${g.accent}18`:"transparent"},onClick:()=>H(J.name,h.name),onContextMenu:we=>G(we,{type:"kind",kindName:J.name,pkgName:h.name,layerId:z.id}),children:[!Vt&&t.jsx("span",{style:{color:g.faint,fontSize:"9px",flexShrink:0},children:"↳"}),t.jsx("span",{className:"truncate",style:{color:ce?g.accentDark:g.primary,fontWeight:Vt?500:400,fontSize:C.explorer.item},children:J.name}),J.instanceCount>0&&t.jsxs("span",{style:{color:g.faint,fontSize:"10px"},children:["·",J.instanceCount]})]},J.name)},le=[],pe=new Map;for(const J of be){const ce=J.group??"";pe.has(ce)||(pe.set(ce,[]),le.push(ce)),pe.get(ce).push(J)}return le.filter(J=>J!=="").length<=1?be.map(ee):le.map(J=>t.jsxs("div",{children:[J&&t.jsxs("div",{className:"px-3 py-0.5 flex items-center gap-1.5",style:{margin:"0 4px 0 30px"},children:[t.jsx("span",{className:"capitalize truncate",style:{color:g.faint,fontSize:C.explorer.kind,letterSpacing:"0.02em"},children:J.replace(/_/g," ")}),t.jsx("span",{style:{color:g.faint,fontSize:"10px"},children:pe.get(J).length})]}),pe.get(J).map(ee)]},`grp:${xe}:${J||"_root"}`))})()]},xe)})]},h.name)})}),w&&t.jsx("div",{className:"px-3 py-2 flex-shrink-0",style:{borderTop:`1px solid ${g.border}`,background:g.surfaceAlt},children:t.jsx("button",{onClick:ae,className:"w-full py-1.5 rounded-md font-medium",style:{fontSize:C.xs,background:"#2563EB",color:"#FFFFFF",border:"none",cursor:"pointer"},children:"Save Selection"})}),f&&t.jsx(ks,{pkgName:f,onCancel:()=>D(null),onConfirm:()=>{n(f),D(null)}}),_&&t.jsx(vs,{orphans:_,onKeep:I,onRemap:W,onCancel:()=>N(null)}),E&&t.jsx(xs,{x:E.x,y:E.y,target:E.target,onViewVisual:F,onViewTable:L,onToggleSelection:q,onViewProperties:K,onClose:()=>R(null)})]})}function Cs(){const e=S(d=>d.model),r=S(d=>d.recentlyVisited),n=S(d=>d.selectElement),s=u.useMemo(()=>e?r.map(d=>e.elements[d]).filter(Boolean):[],[r,e]),o=u.useMemo(()=>{if(!e||s.length>0)return[];const d=new Map;for(const c of Object.values(e.elements))if(d.has(c.kind)||d.set(c.kind,c),d.size>=12)break;return Array.from(d.values())},[e,s.length]),i=s.length>0?s:o,l=s.length>0?"Recently visited":"Sample elements",a=s.length>0?`${s.length} item${s.length===1?"":"s"} this session`:"Click any to start exploring";return t.jsxs("div",{className:"flex flex-col flex-1 overflow-hidden",children:[t.jsxs("div",{className:"px-3 py-3",style:{borderBottom:`1px solid ${g.border}`},children:[t.jsx("div",{style:{fontSize:"10px",fontWeight:700,textTransform:"uppercase",letterSpacing:"0.08em",color:g.muted,marginBottom:"2px"},children:l}),t.jsx("div",{style:{fontSize:"11px",color:g.muted,opacity:.8},children:a})]}),t.jsx("div",{className:"flex-1 overflow-y-auto",style:{padding:"4px 0"},children:i.length===0?t.jsx("div",{style:{padding:"24px 16px",textAlign:"center",fontSize:"12px",color:g.muted,lineHeight:"1.6"},children:"No elements in this model yet."}):i.map(d=>{const c=ie[d.layer]||g.muted;return t.jsx("button",{onClick:()=>n(d.id),style:{display:"flex",alignItems:"flex-start",gap:"8px",width:"100%",padding:"8px 12px",background:"transparent",border:"none",borderLeft:`3px solid ${c}`,cursor:"pointer",textAlign:"left",transition:"background 0.1s"},onMouseEnter:p=>p.currentTarget.style.background=g.surfaceAlt,onMouseLeave:p=>p.currentTarget.style.background="transparent",children:t.jsxs("div",{style:{flex:1,minWidth:0},children:[t.jsx("div",{style:{fontSize:C.explorer.item,fontWeight:500,color:g.primary,whiteSpace:"nowrap",overflow:"hidden",textOverflow:"ellipsis"},children:d.name}),t.jsxs("div",{style:{fontSize:"10px",color:g.muted,marginTop:"2px",whiteSpace:"nowrap",overflow:"hidden",textOverflow:"ellipsis"},children:[t.jsx("span",{style:{color:c,fontWeight:600},children:d.kind}),d.shortId&&t.jsx("span",{style:{marginLeft:"6px",fontFamily:"monospace",opacity:.7},children:d.shortId})]})]})},d.id)})})]})}const js=`---
14
- id: change-record
15
- title: Design Change Record
16
- standard: 21 CFR Part 820
17
- clauses: ["820.30(i)"]
18
- required_for: ["FDA_510k", "FDA_PMA"]
19
- ---
20
-
21
- {{include:shared/snippets/document-control-header.md}}
22
-
23
- ---
24
-
25
- ## 1. Purpose
26
-
27
- Documents design changes for **{{project.product}}** per 21 CFR 820.30(i). All changes must be evaluated for safety impact and approved before implementation.
28
-
29
- ---
30
-
31
- ## 2. Change Log
32
-
33
- Record each change with its identifier, description, affected items, and verification status:
34
-
35
- | Change # | Date | Description | Reason | Impact Assessment | Approved By |
36
- | --- | --- | --- | --- | --- | --- |
37
- | CHG-001 | | | | | |
38
-
39
- ---
40
-
41
- ## 3. Substantial Equivalence Assessment
42
-
43
- Assess substantial equivalence to the predicate device, comparing intended use and technological characteristics.
44
-
45
- _[TODO: For FDA-cleared devices, assess whether any changes affect substantial equivalence]_
46
-
47
- ---
48
-
49
- ## 4. Risk Assessment for Changes
50
-
51
- Assess the risk impact of each change per ISO 14971, including effects on existing risk controls.
52
-
53
- _[TODO: Document risk management activity triggered by each significant change]_
54
-
55
- ---
56
-
57
- {{include:shared/snippets/revision-history-table.md}}
58
- `,Ds=`---
59
- id: design-input
60
- title: Design Input Plan
61
- standard: 21 CFR Part 820
62
- clauses: ["820.30(c)"]
63
- required_for: ["FDA_510k", "FDA_PMA"]
64
- ---
65
-
66
- {{include:shared/snippets/document-control-header.md}}
67
-
68
- {{toc}}
69
-
70
- ---
71
-
72
- ## 1. Purpose
73
-
74
- Defines design inputs for **{{project.product}}** per 21 CFR 820.30(c). Design inputs are the physical and performance requirements to which the device design must conform.
75
-
76
- ---
77
-
78
- ## 2. Design Input Requirements
79
-
80
- ### 2.1 Performance Requirements
81
-
82
- \`\`\`memo-query
83
- kind: Requirement
84
- display: table
85
- columns: name, layer, doc
86
- sort: name
87
- empty: "No system requirements defined."
88
- \`\`\`
89
-
90
- ### 2.2 Design Inputs from User Needs
91
-
92
- \`\`\`memo-query
93
- kind: [DesignInput, StakeholderNeed]
94
- display: table
95
- columns: name, layer, doc
96
- sort: name
97
- empty: "No design inputs defined. Add DesignInput elements."
98
- \`\`\`
99
-
100
- ---
101
-
102
- ## 3. Regulatory and Standards Requirements
103
-
104
- Complete the table below for **{{project.product}}**:
105
-
106
- | Standard | Requirement | Input Reference |
107
- | --- | --- | --- |
108
- | 21 CFR 820.30 | Design controls | |
109
- | ISO 14971 | Risk management requirements | |
110
- | IEC 62304 | Software development | |
111
-
112
- ---
113
-
114
- ## 4. Design Input Review
115
-
116
- Record the review of design inputs for completeness, unambiguity, and absence of conflicts per 21 CFR 820.30(c).
117
-
118
- _[TODO: Document the design input review process and sign-off]_
119
-
120
- ---
121
-
122
- {{include:shared/snippets/revision-history-table.md}}
123
-
124
- {{include:shared/snippets/approval-block.md}}
125
- `,As=`---
126
- id: design-output
127
- title: Design Output Plan
128
- standard: 21 CFR Part 820
129
- clauses: ["820.30(d)"]
130
- required_for: ["FDA_510k", "FDA_PMA"]
131
- ---
132
-
133
- {{include:shared/snippets/document-control-header.md}}
134
-
135
- {{toc}}
136
-
137
- ---
138
-
139
- ## 1. Purpose
140
-
141
- Defines design outputs for **{{project.product}}** per 21 CFR 820.30(d). Design outputs are the results of the design process, forming the basis for manufacturing.
142
-
143
- ---
144
-
145
- ## 2. Design Outputs
146
-
147
- ### 2.1 Hardware Design Outputs
148
-
149
- \`\`\`memo-query
150
- kind: [Component, Subsystem, DesignOutput]
151
- where: layer == "physical"
152
- display: table
153
- columns: name, kind, layer, doc
154
- sort: name
155
- empty: "No hardware design outputs defined."
156
- \`\`\`
157
-
158
- ### 2.2 Software Design Outputs
159
-
160
- \`\`\`memo-query
161
- kind: [SoftwareItem, SoftwareUnit, DesignOutput]
162
- where: layer == "software"
163
- display: table
164
- columns: name, kind, layer, doc
165
- sort: name
166
- empty: "No software design outputs defined."
167
- \`\`\`
168
-
169
- ### 2.3 All Design Outputs
170
-
171
- \`\`\`memo-query
172
- kind: DesignOutput
173
- display: table
174
- columns: name, layer, doc
175
- sort: name
176
- empty: "No DesignOutput elements defined. Add DesignOutput elements."
177
- \`\`\`
178
-
179
- ---
180
-
181
- ## 3. Design Output → Input Traceability
182
-
183
- Traceability from design outputs back to design inputs, generated live from the model:
184
-
185
- _[TODO: Demonstrate that each design output meets a design input requirement]_
186
-
187
- ---
188
-
189
- ## 4. Essential Design Output Documents
190
-
191
- List the documents constituting the essential design outputs for the DHF.
192
-
193
- | Document | Description | Status |
194
- | --- | --- | --- |
195
- | Engineering drawings | Physical design specifications | |
196
- | Software architecture | Software design specifications | |
197
- | Manufacturing specs | Production procedures | |
198
- | Labeling | Device labels and IFU | |
199
-
200
- ---
201
-
202
- {{include:shared/snippets/revision-history-table.md}}
203
-
204
- {{include:shared/snippets/approval-block.md}}
205
- `,Fs=`---
206
- id: design-review
207
- title: Design Review Record
208
- standard: 21 CFR Part 820
209
- clauses: ["820.30(e)"]
210
- required_for: ["FDA_510k", "FDA_PMA"]
211
- ---
212
-
213
- {{include:shared/snippets/document-control-header.md}}
214
-
215
- ---
216
-
217
- ## 1. Purpose
218
-
219
- Documents formal design reviews for **{{project.product}}** per 21 CFR 820.30(e).
220
-
221
- ---
222
-
223
- ## 2. Design Review Log
224
-
225
- Record of formal design reviews with dates, participants, and outcomes:
226
-
227
- | Review | Date | Stage | Attendees | Outcome | Actions |
228
- | --- | --- | --- | --- | --- | --- |
229
- | DR-001 | | Preliminary Design | | | |
230
- | DR-002 | | Critical Design | | | |
231
- | DR-003 | | Final Design | | | |
232
-
233
- ---
234
-
235
- ## 3. Open Action Items
236
-
237
- Action items raised during review, their owners, and due dates:
238
-
239
- _[TODO: Track all open action items from design reviews]_
240
-
241
- ---
242
-
243
- ## 4. Design Status at Review
244
-
245
- Snapshot of the design state at the time of review, computed from the model:
246
-
247
- \`\`\`memo-query
248
- kind: [Requirement, Requirement, DesignInput, DesignOutput]
249
- display: count
250
- label: Total design elements at last review
251
- \`\`\`
252
-
253
- ---
254
-
255
- {{include:shared/snippets/revision-history-table.md}}
256
- `,Rs=`---
257
- id: design-validation
258
- title: Design Validation Records
259
- standard: 21 CFR Part 820
260
- clauses: ["820.30(g)"]
261
- required_for: ["FDA_510k", "FDA_PMA"]
262
- ---
263
-
264
- {{include:shared/snippets/document-control-header.md}}
265
-
266
- ---
267
-
268
- ## 1. Purpose
269
-
270
- Documents design validation confirming the device meets user needs and intended use for **{{project.product}}** per 21 CFR 820.30(g).
271
-
272
- ---
273
-
274
- ## 2. Validation Plan Reference
275
-
276
- Reference the validation plan governing these activities and note any deviations from it.
277
-
278
- _[TODO: Reference V&V Plan]_
279
-
280
- ---
281
-
282
- ## 3. Clinical/Bench Validation
283
-
284
- Describe clinical or bench validation activities demonstrating conformity with user needs under actual or simulated use conditions.
285
-
286
- \`\`\`memo-query
287
- kind: ValidationActivity
288
- display: table
289
- columns: name, layer, doc
290
- sort: name
291
- empty: "No validation activities defined."
292
- \`\`\`
293
-
294
- ---
295
-
296
- ## 4. User Need Coverage
297
-
298
- Coverage of user needs by validation activities, computed live from the model:
299
-
300
- \`\`\`memo-query
301
- kind: [StakeholderNeed, Requirement]
302
- display: table
303
- columns: name, layer, doc
304
- empty: "No user needs defined."
305
- \`\`\`
306
-
307
- ---
308
-
309
- ## 5. Conclusion
310
-
311
- Summarize the outcome and state the overall conclusion, including any conditions or follow-up actions.
312
-
313
- _[TODO: State validation conclusion — device meets intended use for intended users]_
314
-
315
- ---
316
-
317
- {{include:shared/snippets/revision-history-table.md}}
318
-
319
- {{include:shared/snippets/approval-block.md}}
320
- `,_s=`---
321
- id: design-verification
322
- title: Design Verification Records
323
- standard: 21 CFR Part 820
324
- clauses: ["820.30(f)"]
325
- required_for: ["FDA_510k", "FDA_PMA"]
326
- ---
327
-
328
- {{include:shared/snippets/document-control-header.md}}
329
-
330
- ---
331
-
332
- ## 1. Purpose
333
-
334
- Documents design verification that design outputs meet design inputs for **{{project.product}}** per 21 CFR 820.30(f).
335
-
336
- ---
337
-
338
- ## 2. Verification Matrix
339
-
340
- The verification traceability below is generated live from the model — every requirement should be covered by at least one verification activity:
341
-
342
- \`\`\`memo-query
343
- kind: VerificationActivity
344
- display: table
345
- columns: name, layer, doc
346
- sort: name
347
- empty: "No verification activities defined."
348
- \`\`\`
349
-
350
- ---
351
-
352
- ## 3. Test Results
353
-
354
- Test executions and their outcomes are summarized below from the model:
355
-
356
- \`\`\`memo-query
357
- kind: TestCase
358
- display: table
359
- columns: name, layer, doc
360
- sort: name
361
- empty: "No test cases defined."
362
- \`\`\`
363
-
364
- ---
365
-
366
- ## 4. Design Input Coverage
367
-
368
- Coverage of design inputs by verification activities, computed live from the model:
369
-
370
- _[TODO: Demonstrate that all design inputs are verified by at least one test]_
371
-
372
- ---
373
-
374
- {{include:shared/snippets/revision-history-table.md}}
375
-
376
- {{include:shared/snippets/approval-block.md}}
377
- `,Ts=`---
378
- id: dhf-index
379
- title: Design History File Index
380
- standard: 21 CFR Part 820
381
- clauses: ["820.30(j)", "ISO 13485:2016 §4.2.4"]
382
- required_for: ["FDA_510k", "FDA_PMA", "CE", "MDR"]
383
- ---
384
-
385
- {{include:shared/snippets/document-control-header.md}}
386
-
387
- {{toc}}
388
-
389
- ---
390
-
391
- ## 1. Purpose
392
-
393
- This Design History File (DHF) Index serves as the master index for all design and development records for **{{project.product}}** per 21 CFR 820.30(j).
394
-
395
- ---
396
-
397
- ## 2. Device Summary
398
-
399
- Key characteristics of **{{project.product}}**, drawn from the model:
400
-
401
- | Field | Value |
402
- | --- | --- |
403
- | Device Name | {{project.product}} |
404
- | Company | {{project.company}} |
405
- | Device Type | {{project.device_type}} |
406
- | Development Phase | {{project.phase}} |
407
- | Version | {{project.version}} |
408
-
409
- ---
410
-
411
- ## 3. DHF Documents
412
-
413
- ### Risk Management
414
-
415
- | Document | Standard | Status |
416
- | --- | --- | --- |
417
- | Risk Management Plan | ISO 14971:2019 §4.4 | |
418
- | Hazard Analysis Report | ISO 14971:2019 §5-7 | |
419
- | FMEA | IEC 60812:2018 | |
420
- | Risk Management Report | ISO 14971:2019 §9 | |
421
-
422
- ### Design Controls
423
-
424
- | Document | Standard | Status |
425
- | --- | --- | --- |
426
- | User Needs | 21 CFR 820.30(c) | |
427
- | Design Input Plan | 21 CFR 820.30(c) | |
428
- | Design Output Plan | 21 CFR 820.30(d) | |
429
- | V&V Plan | 21 CFR 820.30(f-g) | |
430
- | V&V Report | 21 CFR 820.30(f-g) | |
431
- | Design Transfer Plan | 21 CFR 820.30(h) | |
432
-
433
- ### Software Documentation
434
-
435
- | Document | Standard | Status |
436
- | --- | --- | --- |
437
- | Software Development Plan | IEC 62304 §5.1 | |
438
- | Software Requirements Specification | IEC 62304 §5.2 | |
439
- | Software Architecture Description | IEC 62304 §5.3 | |
440
- | SOUP List | IEC 62304 §8.1.2 | |
441
- | Software Traceability Matrix | IEC 62304 §5.7.5 | |
442
-
443
- ### Usability Engineering
444
-
445
- | Document | Standard | Status |
446
- | --- | --- | --- |
447
- | Usability Engineering Plan | IEC 62366-1 §4 | |
448
- | Use-Related Risk Analysis | IEC 62366-1 §5 | |
449
- | Summative Evaluation Report | IEC 62366-1 §5.9 | |
450
-
451
- ---
452
-
453
- ## 4. Model Summary
454
-
455
- Summary statistics of the system model at the time this document was generated:
456
-
457
- \`\`\`memo-query
458
- kind: [Requirement, Requirement]
459
- display: count
460
- label: Total requirements
461
- \`\`\`
462
-
463
- \`\`\`memo-query
464
- kind: Hazard
465
- display: count
466
- label: Total hazards
467
- \`\`\`
468
-
469
- \`\`\`memo-query
470
- kind: [TestCase, VerificationActivity]
471
- display: count
472
- label: Total test cases
473
- \`\`\`
474
-
475
- ---
476
-
477
- ## 5. All Model Elements
478
-
479
- {{glossary}}
480
-
481
- ---
482
-
483
- {{include:shared/snippets/revision-history-table.md}}
484
-
485
- {{include:shared/snippets/approval-block.md}}
486
-
487
- {{include:shared/snippets/references-section.md}}
488
- `,Is=`---
489
- id: transfer-plan
490
- title: Design Transfer Plan
491
- standard: 21 CFR Part 820
492
- clauses: ["820.30(h)"]
493
- required_for: ["FDA_510k", "FDA_PMA"]
494
- ---
495
-
496
- {{include:shared/snippets/document-control-header.md}}
497
-
498
- ---
499
-
500
- ## 1. Purpose
501
-
502
- Defines design transfer activities for **{{project.product}}** per 21 CFR 820.30(h), ensuring device design is correctly translated to production specifications.
503
-
504
- ---
505
-
506
- ## 2. Transfer Checklist
507
-
508
- Checklist of items required before design transfer to production is complete:
509
-
510
- | Activity | Responsible | Completion Date | Status |
511
- | --- | --- | --- | --- |
512
- | Engineering drawings released to production | | | |
513
- | Software build process documented | | | |
514
- | Production procedures validated | | | |
515
- | Test equipment calibrated | | | |
516
- | Production personnel trained | | | |
517
- | First article inspection completed | | | |
518
-
519
- ---
520
-
521
- ## 3. Production Specifications
522
-
523
- Production specifications derived from the design outputs:
524
-
525
- \`\`\`memo-query
526
- kind: DesignOutput
527
- display: table
528
- columns: name, layer, doc
529
- sort: name
530
- empty: "No design outputs defined."
531
- \`\`\`
532
-
533
- ---
534
-
535
- {{include:shared/snippets/revision-history-table.md}}
536
-
537
- {{include:shared/snippets/approval-block.md}}
538
- `,Ns=`---
539
- id: user-needs
540
- title: User Needs Document
541
- standard: 21 CFR Part 820
542
- clauses: ["820.30(c)"]
543
- required_for: ["FDA_510k", "FDA_PMA"]
544
- ---
545
-
546
- {{include:shared/snippets/document-control-header.md}}
547
-
548
- {{toc}}
549
-
550
- ---
551
-
552
- ## 1. Purpose
553
-
554
- This document captures user needs for **{{project.product}}** per 21 CFR 820.30(c) Design Input requirements. User needs represent the intended purpose of the device as stated by customers and intended users.
555
-
556
- ---
557
-
558
- ## 2. Intended Users
559
-
560
- Identify every intended user group of **{{project.product}}**, including their roles, training assumptions, and use environments.
561
-
562
- _[TODO: Describe all intended user groups with their roles, training levels, and environments]_
563
-
564
- ---
565
-
566
- ## 3. User Needs
567
-
568
- User needs captured for **{{project.product}}** are listed below from the model. Each user need should trace forward to at least one design input:
569
-
570
- \`\`\`memo-query
571
- kind: [StakeholderNeed, Requirement]
572
- display: table
573
- columns: name, layer, doc
574
- sort: name
575
- empty: "No user need elements defined. Add StakeholderNeed or Requirement elements."
576
- \`\`\`
577
-
578
- ---
579
-
580
- ## 4. Use Cases
581
-
582
- Use cases describing how intended users interact with **{{project.product}}**, drawn from the model:
583
-
584
- \`\`\`memo-query
585
- kind: UseCase
586
- display: table
587
- columns: name, layer, doc
588
- sort: name
589
- empty: "No use cases defined."
590
- \`\`\`
591
-
592
- ---
593
-
594
- ## 5. Customer Requirements
595
-
596
- List customer-stated requirements that serve as input to the design process.
597
-
598
- _[TODO: List customer-stated requirements as input to the design process]_
599
-
600
- ---
601
-
602
- ## 6. Regulatory Requirements
603
-
604
- Regulatory and standards requirements applicable to **{{project.product}}**:
605
-
606
- | Standard | Applicability | Notes |
607
- | --- | --- | --- |
608
- | 21 CFR Part 820 | Quality System Regulation | |
609
- | IEC 62304 | Software lifecycle | If Class B/C SW |
610
- | ISO 14971 | Risk management | |
611
-
612
- ---
613
-
614
- {{include:shared/snippets/revision-history-table.md}}
615
-
616
- {{include:shared/snippets/approval-block.md}}
617
-
618
- {{include:shared/snippets/references-section.md}}
619
- `,Os=`---
620
- id: vv-plan
621
- title: Verification and Validation Plan
622
- standard: 21 CFR Part 820
623
- clauses: ["820.30(f)", "820.30(g)"]
624
- required_for: ["FDA_510k", "FDA_PMA", "CE"]
625
- ---
626
-
627
- {{include:shared/snippets/document-control-header.md}}
628
-
629
- {{toc}}
630
-
631
- ---
632
-
633
- ## 1. Purpose
634
-
635
- This V&V Plan defines verification and validation activities for **{{project.product}}** per 21 CFR 820.30(f)-(g) and ISO 13485:2016 §7.3.6-7.3.7.
636
-
637
- ---
638
-
639
- ## 2. Scope
640
-
641
- This plan covers:
642
- - Software verification (per IEC 62304 §5.6-5.7)
643
- - Hardware verification
644
- - System-level validation
645
- - Usability validation (per IEC 62366-1)
646
-
647
- ---
648
-
649
- ## 3. Verification Activities
650
-
651
- ### 3.1 Requirements to Verify
652
-
653
- \`\`\`memo-query
654
- kind: [Requirement, Requirement]
655
- display: table
656
- columns: name, layer, doc
657
- sort: name
658
- empty: "No requirements defined."
659
- \`\`\`
660
-
661
- ### 3.2 Verification Test Cases
662
-
663
- \`\`\`memo-query
664
- kind: [TestCase, VerificationActivity]
665
- display: table
666
- columns: name, kind, layer, doc
667
- sort: name
668
- empty: "No verification test cases defined."
669
- \`\`\`
670
-
671
- ---
672
-
673
- ## 4. Validation Activities
674
-
675
- Validation activities demonstrating that **{{project.product}}** meets user needs and intended uses:
676
-
677
- \`\`\`memo-query
678
- kind: ValidationActivity
679
- display: table
680
- columns: name, layer, doc
681
- sort: name
682
- empty: "No validation activities defined."
683
- \`\`\`
684
-
685
- ---
686
-
687
- ## 5. Acceptance Criteria
688
-
689
- State the objective criteria that must be met for the validation to be considered successful.
690
-
691
- _[TODO: Define objective acceptance criteria for all V&V activities]_
692
-
693
- ---
694
-
695
- ## 6. Test Environment
696
-
697
- Describe the hardware, software, tools, and configuration of the test environment in sufficient detail to reproduce the test setup.
698
-
699
- _[TODO: Describe hardware, software, and clinical test environments]_
700
-
701
- ---
702
-
703
- {{include:shared/snippets/revision-history-table.md}}
704
-
705
- {{include:shared/snippets/approval-block.md}}
706
-
707
- {{include:shared/snippets/references-section.md}}
708
- `,Ms=`---
709
- id: vv-report
710
- title: Verification and Validation Report
711
- standard: 21 CFR Part 820
712
- clauses: ["820.30(f)", "820.30(g)"]
713
- required_for: ["FDA_510k", "FDA_PMA", "CE"]
714
- ---
715
-
716
- {{include:shared/snippets/document-control-header.md}}
717
-
718
- {{toc}}
719
-
720
- ---
721
-
722
- ## 1. Purpose
723
-
724
- This V&V Report documents the results of all verification and validation activities for **{{project.product}}**.
725
-
726
- ---
727
-
728
- ## 2. Summary
729
-
730
- Summary metrics computed live from the model:
731
-
732
- \`\`\`memo-query
733
- kind: TestCase
734
- display: count
735
- label: Total test cases
736
- \`\`\`
737
-
738
- \`\`\`memo-query
739
- kind: [VerificationActivity, ValidationActivity]
740
- display: count
741
- label: V&V activities
742
- \`\`\`
743
-
744
- ---
745
-
746
- ## 3. Verification Results
747
-
748
- ### 3.1 Test Results by Requirement
749
-
750
- \`\`\`memo-query
751
- kind: [TestCase, VerificationActivity]
752
- display: table
753
- columns: name, kind, layer, doc
754
- sort: name
755
- empty: "No verification activities defined."
756
- \`\`\`
757
-
758
- ---
759
-
760
- ## 4. Validation Results
761
-
762
- Results of the validation activities are summarized below:
763
-
764
- \`\`\`memo-query
765
- kind: ValidationActivity
766
- display: table
767
- columns: name, layer, doc
768
- sort: name
769
- empty: "No validation activities defined."
770
- \`\`\`
771
-
772
- ---
773
-
774
- ## 5. Known Anomalies and Deviations
775
-
776
- Record any anomalies, deviations from plan, and their disposition, including rationale for acceptance of unresolved anomalies.
777
-
778
- _[TODO: List any unresolved anomalies and provide justification for acceptance]_
779
-
780
- ---
781
-
782
- ## 6. V&V Conclusion
783
-
784
- State the overall verification and validation conclusion for **{{project.product}}**, including any conditions, limitations, or required follow-up actions.
785
-
786
- _[TODO: State whether the device meets all design inputs and is fit for intended use]_
787
-
788
- ---
789
-
790
- {{include:shared/snippets/revision-history-table.md}}
791
-
792
- {{include:shared/snippets/approval-block.md}}
793
- `,Ps=`---
794
- id: incident-response
795
- title: Cybersecurity Incident Response Plan
796
- standard: FDA Cybersecurity Guidance 2023
797
- clauses: ["5.2"]
798
- required_for: ["FDA_510k", "FDA_PMA"]
799
- ---
800
-
801
- {{include:shared/snippets/document-control-header.md}}
802
-
803
- ---
804
-
805
- ## 1. Purpose
806
-
807
- Defines the incident response process for cybersecurity events affecting **{{project.product}}**.
808
-
809
- ---
810
-
811
- ## 2. Incident Classification
812
-
813
- Define the severity classes for security incidents and the criteria for assigning them.
814
-
815
- | Class | Description | Response Time | FDA Reporting |
816
- | --- | --- | --- | --- |
817
- | Class 1 | Exploited vulnerability affecting device safety | 24 hours | Required within 30 days |
818
- | Class 2 | Unpatched but known vulnerability | 72 hours | Likely required |
819
- | Class 3 | Suspected security event | 5 days | Assess case-by-case |
820
-
821
- ---
822
-
823
- ## 3. Response Team
824
-
825
- Identify the incident response team members, their roles, and contact paths.
826
-
827
- | Role | Responsible Party | Contact |
828
- | --- | --- | --- |
829
- | Incident Commander | | |
830
- | Security Lead | | |
831
- | Regulatory Affairs | | |
832
- | Clinical Safety | | |
833
- | Legal/Compliance | | |
834
-
835
- ---
836
-
837
- ## 4. Response Procedure
838
-
839
- 1. Detection and initial assessment
840
- 2. Containment of affected devices
841
- 3. Impact analysis (patient safety, data)
842
- 4. Develop and test patch
843
- 5. Deploy and verify patch
844
- 6. FDA notification (if required)
845
- 7. Customer notification
846
- 8. Post-incident review
847
-
848
- ---
849
-
850
- ## 5. Coordinated Vulnerability Disclosure
851
-
852
- Describe the process by which external researchers can report vulnerabilities and how reports are triaged and disclosed.
853
-
854
- _[TODO: Describe the coordinated disclosure policy for external researchers]_
855
-
856
- ---
857
-
858
- {{include:shared/snippets/revision-history-table.md}}
859
- `,zs=`---
860
- id: postmarket-surveillance
861
- title: Post-Market Cybersecurity Surveillance Plan
862
- standard: FDA Cybersecurity Guidance 2023
863
- clauses: ["5"]
864
- required_for: ["FDA_510k", "FDA_PMA"]
865
- ---
866
-
867
- {{include:shared/snippets/document-control-header.md}}
868
-
869
- ---
870
-
871
- ## 1. Purpose
872
-
873
- Defines ongoing cybersecurity surveillance for **{{project.product}}** in the post-market phase per FDA's 2023 guidance.
874
-
875
- ---
876
-
877
- ## 2. Surveillance Sources
878
-
879
- - NVD / CVE database monitoring for SOUP vulnerabilities
880
- - ICS-CERT / FDA MedSun cybersecurity alerts
881
- - Vulnerability reports from customers and researchers
882
- - Threat intelligence feeds
883
-
884
- ---
885
-
886
- ## 3. SOUP Monitoring
887
-
888
- Describe the process for ongoing monitoring of SOUP components for newly published vulnerabilities.
889
-
890
- \`\`\`memo-query
891
- kind: SOUPComponent
892
- display: table
893
- columns: name, doc
894
- sort: name
895
- empty: "No SOUP components to monitor."
896
- \`\`\`
897
-
898
- ---
899
-
900
- ## 4. Response Timelines
901
-
902
- Define target timelines for triage, containment, remediation, and notification per incident class.
903
-
904
- | Severity | CVSS Score | Response Target |
905
- | --- | --- | --- |
906
- | Critical | 9.0–10.0 | 30 days |
907
- | High | 7.0–8.9 | 60 days |
908
- | Medium | 4.0–6.9 | 90 days |
909
- | Low | < 4.0 | Next release |
910
-
911
- ---
912
-
913
- ## 5. Patch and Update Process
914
-
915
- Describe how security patches are developed, verified, approved, and deployed to fielded devices.
916
-
917
- _[TODO: Describe how security patches are tested, validated, and released]_
918
-
919
- ---
920
-
921
- {{include:shared/snippets/revision-history-table.md}}
922
- `,Bs=`---
923
- id: security-arch
924
- title: Cybersecurity Architecture Description
925
- standard: FDA Cybersecurity Guidance 2023
926
- clauses: ["3.3"]
927
- required_for: ["FDA_510k", "FDA_PMA"]
928
- ---
929
-
930
- {{include:shared/snippets/document-control-header.md}}
931
-
932
- {{toc}}
933
-
934
- ---
935
-
936
- ## 1. Purpose
937
-
938
- Describes the cybersecurity architecture for **{{project.product}}** per FDA's 2023 guidance and IEC 81001-5-1:2021.
939
-
940
- ---
941
-
942
- ## 2. Security Architecture
943
-
944
- This section describes the security architecture of **{{project.product}}**. The security-relevant elements below are drawn from the model:
945
-
946
- {{diagram:security-architecture}}
947
-
948
- ---
949
-
950
- ## 3. Trusted Zones and Communication Paths
951
-
952
- Define the trusted zones, the communication paths crossing zone boundaries, and the protection applied at each crossing.
953
-
954
- \`\`\`memo-query
955
- kind: Interface
956
- display: table
957
- columns: name, layer, doc
958
- sort: name
959
- empty: "No interfaces defined."
960
- \`\`\`
961
-
962
- ---
963
-
964
- ## 4. Security Controls
965
-
966
- Security controls implemented in **{{project.product}}** are listed below from the model. Each control should trace to at least one identified threat:
967
-
968
- \`\`\`memo-query
969
- kind: SecurityControl
970
- display: table
971
- columns: name, layer, doc
972
- sort: name
973
- empty: "No security controls defined."
974
- \`\`\`
975
-
976
- ---
977
-
978
- ## 5. Cybersecurity Design Principles Applied
979
-
980
- Describe how core security principles (least privilege, defense in depth, secure defaults, fail secure) are applied in the design.
981
-
982
- _[TODO: Document which NIST CSF or IEC 81001-5-1 principles are applied]_
983
-
984
- | Principle | Implementation | Reference |
985
- | --- | --- | --- |
986
- | Least privilege | | |
987
- | Defense in depth | | |
988
- | Fail secure | | |
989
- | Cryptographic controls | | |
990
- | Secure boot | | |
991
-
992
- ---
993
-
994
- ## 6. Security Testing
995
-
996
- Describe the security testing performed (e.g. static analysis, fuzzing, penetration testing) and reference the detailed results.
997
-
998
- _[TODO: Describe penetration testing, vulnerability scanning, and security code review]_
999
-
1000
- ---
1001
-
1002
- {{include:shared/snippets/revision-history-table.md}}
1003
-
1004
- {{include:shared/snippets/approval-block.md}}
1005
- `,Ls=`---
1006
- id: threat-model
1007
- title: Cybersecurity Threat Model
1008
- standard: FDA Cybersecurity Guidance 2023
1009
- clauses: ["3.2"]
1010
- required_for: ["FDA_510k", "FDA_PMA"]
1011
- ---
1012
-
1013
- {{include:shared/snippets/document-control-header.md}}
1014
-
1015
- {{toc}}
1016
-
1017
- ---
1018
-
1019
- ## 1. Purpose
1020
-
1021
- This threat model documents cybersecurity threats for **{{project.product}}** per FDA's 2023 Cybersecurity in Medical Devices guidance and IEC 81001-5-1:2021.
1022
-
1023
- ---
1024
-
1025
- ## 2. System Assets
1026
-
1027
- Assets requiring protection (data, functions, interfaces), drawn from the model:
1028
-
1029
- \`\`\`memo-query
1030
- kind: [SoftwareSystem, Interface, SOUPComponent]
1031
- display: table
1032
- columns: name, kind, layer, doc
1033
- sort: name
1034
- empty: "No system assets defined."
1035
- \`\`\`
1036
-
1037
- ---
1038
-
1039
- ## 3. Entry Points and Attack Surface
1040
-
1041
- Entry points and externally reachable interfaces constituting the attack surface, drawn from the model:
1042
-
1043
- \`\`\`memo-query
1044
- kind: Interface
1045
- display: table
1046
- columns: name, layer, doc
1047
- sort: name
1048
- empty: "No interfaces defined."
1049
- \`\`\`
1050
-
1051
- ---
1052
-
1053
- ## 4. Threat Catalog
1054
-
1055
- The threat catalog below is generated from the model. Each threat should be assessed for likelihood and impact and trace to mitigating security controls:
1056
-
1057
- \`\`\`memo-query
1058
- kind: ThreatModel
1059
- display: table
1060
- columns: name, layer, doc
1061
- sort: name
1062
- empty: "No threat model elements defined. Add ThreatModel elements."
1063
- \`\`\`
1064
-
1065
- ### 4.1 STRIDE Analysis
1066
-
1067
- | Threat Category | Description | Affected Assets | Likelihood | Impact |
1068
- | --- | --- | --- | --- | --- |
1069
- | Spoofing | | | | |
1070
- | Tampering | | | | |
1071
- | Repudiation | | | | |
1072
- | Information Disclosure | | | | |
1073
- | Denial of Service | | | | |
1074
- | Elevation of Privilege | | | | |
1075
-
1076
- ---
1077
-
1078
- ## 5. Security Controls
1079
-
1080
- Security controls implemented in **{{project.product}}** are listed below from the model. Each control should trace to at least one identified threat:
1081
-
1082
- \`\`\`memo-query
1083
- kind: SecurityControl
1084
- display: table
1085
- columns: name, layer, doc
1086
- sort: name
1087
- empty: "No security controls defined."
1088
- \`\`\`
1089
-
1090
- ---
1091
-
1092
- ## 6. Unmitigated Threats
1093
-
1094
- Threats without a mitigating security control are surfaced below by a live model query — this list should be empty before release:
1095
-
1096
- _[TODO: List any threats without security controls and provide residual risk justification]_
1097
-
1098
- ---
1099
-
1100
- {{include:shared/snippets/revision-history-table.md}}
1101
-
1102
- {{include:shared/snippets/approval-block.md}}
1103
-
1104
- {{include:shared/snippets/references-section.md}}
1105
- `,qs=`---
1106
- id: vuln-assessment
1107
- title: Vulnerability Assessment and Penetration Testing Report
1108
- standard: FDA Cybersecurity Guidance 2023
1109
- clauses: ["3.4"]
1110
- required_for: ["FDA_510k", "FDA_PMA"]
1111
- ---
1112
-
1113
- {{include:shared/snippets/document-control-header.md}}
1114
-
1115
- {{toc}}
1116
-
1117
- ---
1118
-
1119
- ## 1. Purpose
1120
-
1121
- Documents cybersecurity vulnerability assessment and testing for **{{project.product}}** per FDA's 2023 cybersecurity guidance.
1122
-
1123
- ---
1124
-
1125
- ## 2. Scope of Assessment
1126
-
1127
- Define the boundaries of this assessment: components, interfaces, and threat classes in and out of scope.
1128
-
1129
- \`\`\`memo-query
1130
- kind: [SoftwareSystem, SoftwareItem, Interface]
1131
- display: table
1132
- columns: name, kind, layer
1133
- sort: name
1134
- empty: "No software assets defined."
1135
- \`\`\`
1136
-
1137
- ---
1138
-
1139
- ## 3. SOUP/Third-Party Component Vulnerabilities
1140
-
1141
- Known vulnerabilities in SOUP and third-party components (e.g. from CVE/NVD monitoring) and their disposition:
1142
-
1143
- \`\`\`memo-query
1144
- kind: SOUPComponent
1145
- display: table
1146
- columns: name, doc
1147
- sort: name
1148
- empty: "No SOUP components defined."
1149
- \`\`\`
1150
-
1151
- ---
1152
-
1153
- ## 4. Vulnerability Findings
1154
-
1155
- Identified vulnerabilities and their assessment are listed below:
1156
-
1157
- | CVE / Finding | Component | Severity (CVSS) | Status | Mitigation |
1158
- | --- | --- | --- | --- | --- |
1159
- | | | | | |
1160
-
1161
- ---
1162
-
1163
- ## 5. Penetration Test Results
1164
-
1165
- Summarize the scope, methodology, and findings of penetration testing.
1166
-
1167
- _[TODO: Summarize penetration testing scope, methodology, and findings]_
1168
-
1169
- ---
1170
-
1171
- ## 6. Residual Vulnerabilities
1172
-
1173
- Vulnerabilities remaining after mitigation, with the rationale for their acceptability:
1174
-
1175
- _[TODO: Document any accepted residual vulnerabilities with justification]_
1176
-
1177
- ---
1178
-
1179
- {{include:shared/snippets/revision-history-table.md}}
1180
-
1181
- {{include:shared/snippets/approval-block.md}}
1182
- `,Vs=`---
1183
- id: change-control
1184
- title: Software Change Control Log
1185
- standard: IEC 62304:2006+AMD1:2015
1186
- clauses: ["6"]
1187
- required_for: ["CE", "FDA_510k", "MDR"]
1188
- ---
1189
-
1190
- {{include:shared/snippets/document-control-header.md}}
1191
-
1192
- ---
1193
-
1194
- ## 1. Purpose
1195
-
1196
- This log documents all changes to **{{project.product}}** software, including the change description, impact assessment, and approval per IEC 62304:2006 §6.
1197
-
1198
- ---
1199
-
1200
- ## 2. Change Log
1201
-
1202
- Record each change with its identifier, description, affected items, and verification status:
1203
-
1204
- | Change ID | Date | Version | Description | Impact Assessment | Approved By |
1205
- | --- | --- | --- | --- | --- | --- |
1206
- | CHG-001 | | 1.0.0 | Initial release | N/A | |
1207
-
1208
- ---
1209
-
1210
- ## 3. Change Procedure
1211
-
1212
- All changes must:
1213
- 1. Be requested via the change request process
1214
- 2. Have an impact assessment (safety, requirements, design, test)
1215
- 3. Be approved prior to implementation
1216
- 4. Be verified and validated after implementation
1217
- 5. Be documented in this log
1218
-
1219
- ---
1220
-
1221
- {{include:shared/snippets/revision-history-table.md}}
1222
- `,Us=`---
1223
- id: detailed-design
1224
- title: Software Detailed Design
1225
- standard: IEC 62304:2006+AMD1:2015
1226
- clauses: ["5.4"]
1227
- required_for: ["CE", "FDA_510k"]
1228
- ---
1229
-
1230
- {{include:shared/snippets/document-control-header.md}}
1231
-
1232
- {{toc}}
1233
-
1234
- ---
1235
-
1236
- ## 1. Purpose
1237
-
1238
- This document provides detailed design specifications for **{{project.product}}** software per IEC 62304:2006 §5.4, sufficient to implement and test each software unit.
1239
-
1240
- ---
1241
-
1242
- ## 2. Software Units
1243
-
1244
- The software units — the lowest level of decomposition per IEC 62304 — are listed below from the model:
1245
-
1246
- \`\`\`memo-query
1247
- kind: SoftwareUnit
1248
- display: table
1249
- columns: name, layer, doc
1250
- sort: name
1251
- empty: "No SoftwareUnit elements defined."
1252
- \`\`\`
1253
-
1254
- ---
1255
-
1256
- ## 3. Unit Specifications
1257
-
1258
- ### 3.1 Algorithms and Data Structures
1259
-
1260
- _[TODO: Describe key algorithms, data structures, and design patterns]_
1261
-
1262
- ### 3.2 State Machines
1263
-
1264
- {{diagram:state-machine}}
1265
-
1266
- _[TODO: Document state machine diagrams for stateful components]_
1267
-
1268
- ### 3.3 Interface Specifications
1269
-
1270
- \`\`\`memo-query
1271
- kind: Interface
1272
- display: table
1273
- columns: name, layer, doc
1274
- sort: name
1275
- empty: "No Interface elements defined."
1276
- \`\`\`
1277
-
1278
- ---
1279
-
1280
- ## 4. Design Verification Criteria
1281
-
1282
- The criteria used to verify that design outputs meet design inputs:
1283
-
1284
- _[TODO: List criteria that verify this design meets software requirements]_
1285
-
1286
- ---
1287
-
1288
- {{include:shared/snippets/revision-history-table.md}}
1289
-
1290
- {{include:shared/snippets/approval-block.md}}
1291
- `,$s=`---
1292
- id: integration-test
1293
- title: Software Integration Test Plan
1294
- standard: IEC 62304:2006+AMD1:2015
1295
- clauses: ["5.6"]
1296
- required_for: ["CE", "FDA_510k", "MDR"]
1297
- ---
1298
-
1299
- {{include:shared/snippets/document-control-header.md}}
1300
-
1301
- {{toc}}
1302
-
1303
- ---
1304
-
1305
- ## 1. Purpose
1306
-
1307
- This Integration Test Plan defines the approach for integration testing of **{{project.product}}** software per IEC 62304:2006 §5.6.
1308
-
1309
- ---
1310
-
1311
- ## 2. Software Items Under Test
1312
-
1313
- The software items in scope for this test plan, drawn from the model:
1314
-
1315
- \`\`\`memo-query
1316
- kind: [SoftwareItem, SoftwareUnit]
1317
- display: table
1318
- columns: name, kind, layer, doc
1319
- sort: name
1320
- empty: "No software items defined."
1321
- \`\`\`
1322
-
1323
- ---
1324
-
1325
- ## 3. Integration Test Cases
1326
-
1327
- Integration test cases are listed below from the model:
1328
-
1329
- \`\`\`memo-query
1330
- kind: TestCase
1331
- where: layer == "verification"
1332
- display: table
1333
- columns: name, layer, doc
1334
- sort: name
1335
- empty: "No integration test cases defined. Add TestCase elements."
1336
- \`\`\`
1337
-
1338
- ---
1339
-
1340
- ## 4. Integration Sequence
1341
-
1342
- Describe the order in which software items are integrated and tested, and the rationale for that order.
1343
-
1344
- _[TODO: Define the order in which software items are integrated and tested]_
1345
-
1346
- ---
1347
-
1348
- ## 5. Pass/Fail Criteria
1349
-
1350
- State the objective criteria used to judge each test as passed or failed.
1351
-
1352
- _[TODO: Define objective pass/fail criteria for integration tests]_
1353
-
1354
- ---
1355
-
1356
- {{include:shared/snippets/revision-history-table.md}}
1357
-
1358
- {{include:shared/snippets/approval-block.md}}
1359
- `,Ws=`---
1360
- id: sad
1361
- title: Software Architecture Description
1362
- standard: IEC 62304:2006+AMD1:2015
1363
- clauses: ["5.3"]
1364
- required_for: ["CE", "FDA_510k", "MDR"]
1365
- ---
1366
-
1367
- {{include:shared/snippets/document-control-header.md}}
1368
-
1369
- {{toc}}
1370
-
1371
- ---
1372
-
1373
- ## 1. Purpose
1374
-
1375
- This Software Architecture Description (SAD) defines the architecture of **{{project.product}}** software per IEC 62304:2006 §5.3 and ISO/IEC/IEEE 42010:2022.
1376
-
1377
- ---
1378
-
1379
- ## 2. System Overview
1380
-
1381
- This section gives a high-level overview of the **{{project.product}}** software system. The composition below is drawn live from the architecture model:
1382
-
1383
- \`\`\`memo-query
1384
- kind: SoftwareSystem
1385
- display: table
1386
- columns: name, layer, doc
1387
- sort: name
1388
- empty: "No SoftwareSystem defined."
1389
- \`\`\`
1390
-
1391
- **Total elements:**
1392
-
1393
- \`\`\`memo-query
1394
- kind: [SoftwareSystem, SoftwareItem, SoftwareUnit, SOUPComponent]
1395
- display: count
1396
- label: Total software elements
1397
- \`\`\`
1398
-
1399
- ---
1400
-
1401
- ## 3. Software Architecture
1402
-
1403
- This section describes the decomposition of the software into software items per IEC 62304 §5.3.1. The architecture view and the element tables that follow are generated from the model:
1404
-
1405
- {{diagram:software-architecture}}
1406
-
1407
- ### 3.1 Software Items
1408
-
1409
- \`\`\`memo-query
1410
- kind: SoftwareItem
1411
- display: table
1412
- columns: name, layer, doc
1413
- sort: name
1414
- empty: "No SoftwareItem elements defined."
1415
- \`\`\`
1416
-
1417
- ### 3.2 Software Units
1418
-
1419
- \`\`\`memo-query
1420
- kind: SoftwareUnit
1421
- display: table
1422
- columns: name, layer, doc
1423
- sort: name
1424
- empty: "No SoftwareUnit elements defined."
1425
- \`\`\`
1426
-
1427
- ### 3.3 Interfaces
1428
-
1429
- \`\`\`memo-query
1430
- kind: Interface
1431
- display: table
1432
- columns: name, layer, doc
1433
- sort: name
1434
- empty: "No Interface elements defined."
1435
- \`\`\`
1436
-
1437
- ---
1438
-
1439
- ## 4. SOUP Components
1440
-
1441
- Software of Unknown Provenance (SOUP) used by **{{project.product}}** is listed below per IEC 62304 §5.3.3–5.3.4. For each SOUP item, functional/performance requirements and required hardware/software must be specified:
1442
-
1443
- \`\`\`memo-query
1444
- kind: SOUPComponent
1445
- display: table
1446
- columns: name, doc, layer
1447
- sort: name
1448
- empty: "No SOUP components identified."
1449
- \`\`\`
1450
-
1451
- ---
1452
-
1453
- ## 5. Architecture Decisions
1454
-
1455
- Record the significant architecture decisions, the alternatives considered, and the rationale — including decisions driven by risk control measures (ISO 14971) or cybersecurity considerations.
1456
-
1457
- _[TODO: Document key architecture decisions and their rationale]_
1458
-
1459
- ---
1460
-
1461
- ## 6. Software Item Segregation
1462
-
1463
- Describe the segregation between software items that is necessary for risk control per IEC 62304 §5.3.5, and the rationale for the integrity of each segregation boundary.
1464
-
1465
- _[TODO: Describe how safety-critical software items are segregated from non-safety-critical items]_
1466
-
1467
- ---
1468
-
1469
- {{include:shared/snippets/revision-history-table.md}}
1470
-
1471
- {{include:shared/snippets/approval-block.md}}
1472
-
1473
- {{include:shared/snippets/references-section.md}}
1474
- `,Hs=`---
1475
- id: sbom
1476
- title: Software Bill of Materials (SBOM)
1477
- standard: IEC 62304:2006+AMD1:2015
1478
- clauses: ["8.1.2"]
1479
- required_for: ["FDA_510k", "FDA_PMA", "CE"]
1480
- ---
1481
-
1482
- {{include:shared/snippets/document-control-header.md}}
1483
-
1484
- {{toc}}
1485
-
1486
- ---
1487
-
1488
- ## 1. Purpose
1489
-
1490
- This Software Bill of Materials (SBOM) provides a complete inventory of software components in **{{project.product}}**, including first-party code, SOUP, and open-source dependencies. Required for FDA cybersecurity submissions and EU MDR.
1491
-
1492
- ---
1493
-
1494
- ## 2. First-Party Software
1495
-
1496
- Software developed in-house for this system is listed below from the model:
1497
-
1498
- \`\`\`memo-query
1499
- kind: [SoftwareSystem, SoftwareItem, SoftwareUnit]
1500
- display: table
1501
- columns: name, kind, layer, doc
1502
- sort: name
1503
- empty: "No first-party software items defined."
1504
- \`\`\`
1505
-
1506
- ---
1507
-
1508
- ## 3. SOUP and Third-Party Components
1509
-
1510
- All third-party and SOUP components with their versions and origins, generated from the model:
1511
-
1512
- \`\`\`memo-query
1513
- kind: SOUPComponent
1514
- display: table
1515
- columns: name, doc, layer
1516
- sort: name
1517
- empty: "No SOUP components defined."
1518
- \`\`\`
1519
-
1520
- ---
1521
-
1522
- ## 4. Dependency Versions
1523
-
1524
- Exact component versions currently recorded in the model — keep these synchronized with the build system:
1525
-
1526
- _[TODO: Attach machine-readable SBOM (CycloneDX or SPDX format)]_
1527
-
1528
- ---
1529
-
1530
- ## 5. Vulnerability Assessment
1531
-
1532
- Assessment of component vulnerabilities and their disposition:
1533
-
1534
- _[TODO: Reference FDA cybersecurity submission or security assessment]_
1535
-
1536
- ---
1537
-
1538
- {{include:shared/snippets/revision-history-table.md}}
1539
-
1540
- {{include:shared/snippets/approval-block.md}}
1541
- `,Ks=`---
1542
- id: sdp
1543
- title: Software Development Plan
1544
- standard: IEC 62304:2006+AMD1:2015
1545
- clauses: ["5.1"]
1546
- required_for: ["CE", "FDA_510k", "MDR"]
1547
- ---
1548
-
1549
- {{include:shared/snippets/document-control-header.md}}
1550
-
1551
- {{toc}}
1552
-
1553
- ---
1554
-
1555
- ## 1. Purpose and Scope
1556
-
1557
- This Software Development Plan (SDP) defines the processes, activities, and tasks for the development of software for **{{project.product}}**. This plan is maintained per IEC 62304:2006 §5.1.
1558
-
1559
- ---
1560
-
1561
- ## 2. Software Classification
1562
-
1563
- <!-- [GUIDANCE] Classify software per IEC 62304 §4.3: Class A (no injury), Class B (non-serious injury), Class C (death or serious injury). -->
1564
-
1565
- | Software Item | Classification | Justification |
1566
- | --- | --- | --- |
1567
- | {{project.product}} Software System | Class B | |
1568
-
1569
- \`\`\`memo-query
1570
- kind: [SoftwareSystem, SoftwareItem]
1571
- display: table
1572
- columns: name, kind, layer, doc
1573
- sort: name
1574
- empty: "No software items defined. Add SoftwareSystem or SoftwareItem elements."
1575
- \`\`\`
1576
-
1577
- ---
1578
-
1579
- ## 3. Development Standards and Procedures
1580
-
1581
- Identify the coding standards, review procedures, and quality gates applied during development.
1582
-
1583
- | Activity | Standard | Reference Procedure |
1584
- | --- | --- | --- |
1585
- | Requirements | IEC 62304 §5.2 | SRS |
1586
- | Architecture | IEC 62304 §5.3 | SAD |
1587
- | Detailed Design | IEC 62304 §5.4 | SDS |
1588
- | Implementation | IEC 62304 §5.5 | Coding standard |
1589
- | Integration | IEC 62304 §5.6 | Integration Test Plan |
1590
- | System Testing | IEC 62304 §5.7 | System Test Plan |
1591
- | Release | IEC 62304 §5.8 | Release procedure |
1592
-
1593
- ---
1594
-
1595
- ## 4. Software Safety Activities
1596
-
1597
- ### 4.1 Software Items of Unknown Provenance (SOUP)
1598
-
1599
- \`\`\`memo-query
1600
- kind: SOUPComponent
1601
- display: table
1602
- columns: name, doc, layer
1603
- sort: name
1604
- empty: "No SOUP components defined."
1605
- \`\`\`
1606
-
1607
- ### 4.2 Software-Related Hazards
1608
-
1609
- \`\`\`memo-query
1610
- kind: Hazard
1611
- where: layer == "software"
1612
- display: table
1613
- columns: name, doc, layer
1614
- sort: name
1615
- empty: "No software-related hazards defined."
1616
- \`\`\`
1617
-
1618
- ---
1619
-
1620
- ## 5. Configuration Management
1621
-
1622
- Describe how configuration items are identified, versioned, and controlled per IEC 62304 §8.
1623
-
1624
- _[TODO: Describe version control, branching strategy, and release process]_
1625
-
1626
- ---
1627
-
1628
- ## 6. Problem Resolution
1629
-
1630
- Describe the problem resolution process per IEC 62304 §9, including how problems are reported, investigated, and tracked to closure.
1631
-
1632
- _[TODO: Describe defect tracking and resolution process]_
1633
-
1634
- ---
1635
-
1636
- ## 7. Development Environment
1637
-
1638
- Describe the toolchain, languages, build system, and environments used for development.
1639
-
1640
- _[TODO: List development tools, compilers, IDEs, and their versions]_
1641
-
1642
- ---
1643
-
1644
- {{include:shared/snippets/revision-history-table.md}}
1645
-
1646
- {{include:shared/snippets/approval-block.md}}
1647
-
1648
- {{include:shared/snippets/references-section.md}}
1649
- `,Gs=`---
1650
- id: soup
1651
- title: SOUP List (Software of Unknown Provenance)
1652
- standard: IEC 62304:2006+AMD1:2015
1653
- clauses: ["8.1.2"]
1654
- required_for: ["CE", "FDA_510k", "MDR"]
1655
- ---
1656
-
1657
- {{include:shared/snippets/document-control-header.md}}
1658
-
1659
- {{toc}}
1660
-
1661
- ---
1662
-
1663
- ## 1. Purpose
1664
-
1665
- This document lists all Software of Unknown Provenance (SOUP) components used in **{{project.product}}** per IEC 62304:2006 §8.1.2. SOUP includes off-the-shelf software, open-source libraries, and third-party components that were not developed under a quality management system.
1666
-
1667
- ---
1668
-
1669
- ## 2. SOUP Inventory
1670
-
1671
- The complete inventory of SOUP and third-party components in **{{project.product}}**, generated from the model:
1672
-
1673
- \`\`\`memo-query
1674
- kind: SOUPComponent
1675
- display: table
1676
- columns: name, layer, doc
1677
- sort: name
1678
- empty: "No SOUP components defined. Add SOUPComponent elements to the model."
1679
- \`\`\`
1680
-
1681
- ---
1682
-
1683
- ## 3. SOUP Risk Assessment
1684
-
1685
- For each SOUP component, the potential impact on device safety must be evaluated.
1686
-
1687
- \`\`\`memo-query
1688
- kind: SOUPComponent
1689
- display: table
1690
- columns: name, doc
1691
- sort: name
1692
- empty: "No SOUP components to evaluate."
1693
- \`\`\`
1694
-
1695
- ### 3.1 Known Anomalies
1696
-
1697
- _[TODO: For each SOUP component, list known anomalies and assess impact on safety]_
1698
-
1699
- ---
1700
-
1701
- ## 4. SOUP Maintenance
1702
-
1703
- ### 4.1 Update Monitoring
1704
-
1705
- _[TODO: Describe the process for monitoring SOUP components for security patches and updates]_
1706
-
1707
- ### 4.2 Version Pinning
1708
-
1709
- _[TODO: Describe how SOUP versions are pinned in configuration management]_
1710
-
1711
- ---
1712
-
1713
- ## 5. SBOM Integration
1714
-
1715
- Describe how this document relates to the machine-readable SBOM (e.g. SPDX/CycloneDX) produced by the build pipeline.
1716
-
1717
- _[TODO: Reference Software Bill of Materials (SBOM) for FDA cybersecurity requirements]_
1718
-
1719
- ---
1720
-
1721
- {{include:shared/snippets/revision-history-table.md}}
1722
-
1723
- {{include:shared/snippets/approval-block.md}}
1724
-
1725
- {{include:shared/snippets/references-section.md}}
1726
- `,Ys=`---
1727
- id: srs
1728
- title: Software Requirements Specification
1729
- standard: IEC 62304:2006+AMD1:2015
1730
- clauses: ["5.2"]
1731
- required_for: ["CE", "FDA_510k", "MDR"]
1732
- ---
1733
-
1734
- {{include:shared/snippets/document-control-header.md}}
1735
-
1736
- {{toc}}
1737
-
1738
- ---
1739
-
1740
- ## 1. Purpose
1741
-
1742
- This Software Requirements Specification (SRS) defines the software requirements for **{{project.product}}** in accordance with IEC 62304:2006 §5.2.
1743
-
1744
- ---
1745
-
1746
- ## 2. Requirements Summary
1747
-
1748
- Summary metrics for the requirements captured in the model:
1749
-
1750
- \`\`\`memo-query
1751
- kind: Requirement
1752
- display: count
1753
- label: Total software requirements
1754
- \`\`\`
1755
-
1756
- \`\`\`memo-query
1757
- kind: Requirement
1758
- display: count
1759
- label: System requirements
1760
- \`\`\`
1761
-
1762
- ---
1763
-
1764
- ## 3. Functional Requirements
1765
-
1766
- Functional requirements are listed below from the model:
1767
-
1768
- \`\`\`memo-query
1769
- kind: Requirement
1770
- where: doc contains "shall"
1771
- display: table
1772
- columns: name, layer, doc
1773
- sort: name
1774
- empty: "No functional software requirements defined."
1775
- \`\`\`
1776
-
1777
- ### All Software Requirements
1778
-
1779
- \`\`\`memo-query
1780
- kind: Requirement
1781
- display: table
1782
- columns: name, kind, layer, doc
1783
- sort: name
1784
- empty: "No software requirements defined. Add Requirement elements to model/requirements/*.sysml."
1785
- \`\`\`
1786
-
1787
- ---
1788
-
1789
- ## 4. System Requirements (Allocated to Software)
1790
-
1791
- System requirements allocated to software per IEC 62304 §5.2, drawn from the model:
1792
-
1793
- \`\`\`memo-query
1794
- kind: Requirement
1795
- display: table
1796
- columns: name, layer, doc
1797
- sort: name
1798
- empty: "No system requirements defined."
1799
- \`\`\`
1800
-
1801
- ---
1802
-
1803
- ## 5. Non-Functional Requirements
1804
-
1805
- ### 5.1 Performance Requirements
1806
-
1807
- _[TODO: Define performance requirements (response time, throughput, memory)]_
1808
-
1809
- ### 5.2 Safety Requirements
1810
-
1811
- \`\`\`memo-query
1812
- kind: Hazard
1813
- where: layer == "software"
1814
- display: table
1815
- columns: name, doc
1816
- sort: name
1817
- empty: "No software safety requirements derived from hazard analysis."
1818
- \`\`\`
1819
-
1820
- ### 5.3 Security Requirements
1821
-
1822
- \`\`\`memo-query
1823
- kind: [SecurityControl, ThreatModel]
1824
- display: table
1825
- columns: name, layer, doc
1826
- empty: "No security requirements defined."
1827
- \`\`\`
1828
-
1829
- ---
1830
-
1831
- ## 6. SOUP Requirements
1832
-
1833
- This section is generated from the system model. The table below lists the **SOUP Requirements** elements currently defined:
1834
-
1835
- \`\`\`memo-query
1836
- kind: SOUPComponent
1837
- display: table
1838
- columns: name, doc
1839
- sort: name
1840
- empty: "No SOUP components identified."
1841
- \`\`\`
1842
-
1843
- ---
1844
-
1845
- ## 7. Requirements Traceability
1846
-
1847
- This section is generated from the system model. The table below lists the **Requirements Traceability** elements currently defined:
1848
-
1849
- \`\`\`memo-query
1850
- kind: Requirement
1851
- display: table
1852
- columns: name, layer
1853
- sort: name
1854
- empty: "No software requirements to trace."
1855
- \`\`\`
1856
-
1857
- ---
1858
-
1859
- {{include:shared/snippets/revision-history-table.md}}
1860
-
1861
- {{include:shared/snippets/approval-block.md}}
1862
-
1863
- {{include:shared/snippets/references-section.md}}
1864
- `,Js=`---
1865
- id: sw-traceability
1866
- title: Software Traceability Matrix
1867
- standard: IEC 62304:2006+AMD1:2015
1868
- clauses: ["5.1.1", "5.7.5"]
1869
- required_for: ["CE", "FDA_510k", "MDR"]
1870
- ---
1871
-
1872
- {{include:shared/snippets/document-control-header.md}}
1873
-
1874
- {{toc}}
1875
-
1876
- ---
1877
-
1878
- ## 1. Purpose
1879
-
1880
- This Software Traceability Matrix demonstrates bidirectional traceability from system requirements through software requirements, design, implementation, and test for **{{project.product}}**.
1881
-
1882
- ---
1883
-
1884
- ## 2. Traceability Summary
1885
-
1886
- The following metric is computed live from the model:
1887
-
1888
- \`\`\`memo-query
1889
- kind: Requirement
1890
- display: count
1891
- label: System requirements
1892
- \`\`\`
1893
-
1894
- \`\`\`memo-query
1895
- kind: Requirement
1896
- display: count
1897
- label: Software requirements
1898
- \`\`\`
1899
-
1900
- \`\`\`memo-query
1901
- kind: TestCase
1902
- display: count
1903
- label: Test cases
1904
- \`\`\`
1905
-
1906
- ---
1907
-
1908
- ## 3. System → Software Requirements
1909
-
1910
- This section is generated from the system model. The table below lists the **System → Software Requirements** elements currently defined:
1911
-
1912
- \`\`\`memo-query
1913
- kind: Requirement
1914
- display: table
1915
- columns: name, layer, doc
1916
- sort: name
1917
- empty: "No system requirements defined."
1918
- \`\`\`
1919
-
1920
- ---
1921
-
1922
- ## 4. Software Requirements
1923
-
1924
- This section is generated from the system model. The table below lists the **Software Requirements** elements currently defined:
1925
-
1926
- \`\`\`memo-query
1927
- kind: Requirement
1928
- display: table
1929
- columns: name, layer, doc
1930
- sort: name
1931
- empty: "No software requirements defined."
1932
- \`\`\`
1933
-
1934
- ---
1935
-
1936
- ## 5. Software Requirements → Design Elements
1937
-
1938
- This section is generated from the system model. The table below lists the **Software Requirements → Design Elements** elements currently defined:
1939
-
1940
- \`\`\`memo-query
1941
- kind: [SoftwareItem, SoftwareUnit]
1942
- display: table
1943
- columns: name, kind, layer, doc
1944
- sort: name
1945
- empty: "No software design elements defined."
1946
- \`\`\`
1947
-
1948
- ---
1949
-
1950
- ## 6. Test Cases
1951
-
1952
- This section is generated from the system model. The table below lists the **Test Cases** elements currently defined:
1953
-
1954
- \`\`\`memo-query
1955
- kind: TestCase
1956
- display: table
1957
- columns: name, layer, doc
1958
- sort: name
1959
- empty: "No test cases defined. Add TestCase elements."
1960
- \`\`\`
1961
-
1962
- ---
1963
-
1964
- ## 7. Untraced Requirements
1965
-
1966
- Complete this section for **{{project.product}}** using the guidance below.
1967
-
1968
- _[TODO: List any software requirements without corresponding test cases]_
1969
-
1970
- ---
1971
-
1972
- {{include:shared/snippets/revision-history-table.md}}
1973
-
1974
- {{include:shared/snippets/approval-block.md}}
1975
- `,Qs=`---
1976
- id: system-test
1977
- title: Software System Test Plan
1978
- standard: IEC 62304:2006+AMD1:2015
1979
- clauses: ["5.7"]
1980
- required_for: ["CE", "FDA_510k", "MDR"]
1981
- ---
1982
-
1983
- {{include:shared/snippets/document-control-header.md}}
1984
-
1985
- {{toc}}
1986
-
1987
- ---
1988
-
1989
- ## 1. Purpose
1990
-
1991
- This System Test Plan defines the approach for system-level testing of **{{project.product}}** per IEC 62304:2006 §5.7.
1992
-
1993
- ---
1994
-
1995
- ## 2. System Requirements Under Test
1996
-
1997
- This section is generated from the system model. The table below lists the **System Requirements Under Test** elements currently defined:
1998
-
1999
- \`\`\`memo-query
2000
- kind: Requirement
2001
- display: table
2002
- columns: name, layer, doc
2003
- sort: name
2004
- empty: "No system requirements defined."
2005
- \`\`\`
2006
-
2007
- ---
2008
-
2009
- ## 3. System Test Cases
2010
-
2011
- This section is generated from the system model. The table below lists the **System Test Cases** elements currently defined:
2012
-
2013
- \`\`\`memo-query
2014
- kind: [TestCase, ValidationActivity]
2015
- display: table
2016
- columns: name, kind, layer, doc
2017
- sort: name
2018
- empty: "No system test cases defined."
2019
- \`\`\`
2020
-
2021
- ---
2022
-
2023
- ## 4. Test Environment
2024
-
2025
- Describe the hardware, software, tools, and configuration of the test environment in sufficient detail to reproduce the test setup.
2026
-
2027
- _[TODO: Describe the test environment, tools, and hardware configuration]_
2028
-
2029
- ---
2030
-
2031
- ## 5. Anomaly Reporting
2032
-
2033
- Complete this section for **{{project.product}}** using the guidance below.
2034
-
2035
- _[TODO: Describe how test failures and anomalies are documented and tracked]_
2036
-
2037
- ---
2038
-
2039
- {{include:shared/snippets/revision-history-table.md}}
2040
-
2041
- {{include:shared/snippets/approval-block.md}}
2042
- `,Xs=`---
2043
- id: formative-eval
2044
- title: Formative Usability Evaluation Report
2045
- standard: IEC 62366-1:2015+AMD1:2020
2046
- clauses: ["5.7"]
2047
- required_for: ["CE", "MDR"]
2048
- ---
2049
-
2050
- {{include:shared/snippets/document-control-header.md}}
2051
-
2052
- ---
2053
-
2054
- ## 1. Purpose
2055
-
2056
- Documents formative (iterative) usability evaluation activities for **{{project.product}}** during design development.
2057
-
2058
- ---
2059
-
2060
- ## 2. Evaluation Methods Used
2061
-
2062
- Complete this section for **{{project.product}}** using the guidance below.
2063
-
2064
- _[TODO: Describe methods used — expert review, cognitive walkthrough, prototype testing, etc.]_
2065
-
2066
- ---
2067
-
2068
- ## 3. Issues Identified and Resolved
2069
-
2070
- Complete the table below for **{{project.product}}**:
2071
-
2072
- | Issue | Severity | Resolution | Status |
2073
- | --- | --- | --- | --- |
2074
- | | | | |
2075
-
2076
- ---
2077
-
2078
- ## 4. Design Changes Made
2079
-
2080
- Complete this section for **{{project.product}}** using the guidance below.
2081
-
2082
- _[TODO: Summarize user interface design changes made as a result of formative evaluations]_
2083
-
2084
- ---
2085
-
2086
- {{include:shared/snippets/revision-history-table.md}}
2087
-
2088
- {{include:shared/snippets/approval-block.md}}
2089
- `,Zs=`---
2090
- id: summative-eval
2091
- title: Summative Usability Evaluation Report
2092
- standard: IEC 62366-1:2015+AMD1:2020
2093
- clauses: ["5.9"]
2094
- required_for: ["CE", "FDA_510k", "MDR"]
2095
- ---
2096
-
2097
- {{include:shared/snippets/document-control-header.md}}
2098
-
2099
- {{toc}}
2100
-
2101
- ---
2102
-
2103
- ## 1. Purpose
2104
-
2105
- This report documents the results of summative (validation) usability testing for **{{project.product}}** per IEC 62366-1:2015 §5.9.
2106
-
2107
- ---
2108
-
2109
- ## 2. Test Participants
2110
-
2111
- Complete this section for **{{project.product}}** using the guidance below.
2112
-
2113
- _[TODO: Describe participant demographics, number, and selection criteria]_
2114
-
2115
- ---
2116
-
2117
- ## 3. Test Scenarios
2118
-
2119
- This section is generated from the system model. The table below lists the **Test Scenarios** elements currently defined:
2120
-
2121
- \`\`\`memo-query
2122
- kind: [UseCase, ValidationActivity]
2123
- display: table
2124
- columns: name, layer, doc
2125
- sort: name
2126
- empty: "No validation scenarios defined."
2127
- \`\`\`
2128
-
2129
- ---
2130
-
2131
- ## 4. Results
2132
-
2133
- ### 4.1 Task Completion Rates
2134
-
2135
- _[TODO: Report task completion rates and time-on-task for each critical task]_
2136
-
2137
- ### 4.2 Use Errors Observed
2138
-
2139
- _[TODO: List all use errors observed during testing]_
2140
-
2141
- ### 4.3 Pass/Fail Assessment
2142
-
2143
- _[TODO: State whether each test scenario passed or failed per pre-defined criteria]_
2144
-
2145
- ---
2146
-
2147
- ## 5. Conclusions
2148
-
2149
- Complete this section for **{{project.product}}** using the guidance below.
2150
-
2151
- _[TODO: State whether the device passed summative usability evaluation]_
2152
-
2153
- ---
2154
-
2155
- {{include:shared/snippets/revision-history-table.md}}
2156
-
2157
- {{include:shared/snippets/approval-block.md}}
2158
- `,ei=`---
2159
- id: task-analysis
2160
- title: Task Analysis
2161
- standard: IEC 62366-1:2015+AMD1:2020
2162
- clauses: ["5.4"]
2163
- required_for: ["CE", "MDR"]
2164
- ---
2165
-
2166
- {{include:shared/snippets/document-control-header.md}}
2167
-
2168
- {{toc}}
2169
-
2170
- ---
2171
-
2172
- ## 1. Purpose
2173
-
2174
- Documents task analysis for **{{project.product}}** per IEC 62366-1:2015 §5.4, identifying tasks that could cause hazardous situations if performed incorrectly.
2175
-
2176
- ---
2177
-
2178
- ## 2. User Tasks
2179
-
2180
- This section is generated from the system model. The table below lists the **User Tasks** elements currently defined:
2181
-
2182
- \`\`\`memo-query
2183
- kind: UserActivity
2184
- display: table
2185
- columns: name, layer, doc
2186
- sort: name
2187
- empty: "No UserActivity elements defined."
2188
- \`\`\`
2189
-
2190
- ---
2191
-
2192
- ## 3. Critical Tasks
2193
-
2194
- Complete this section for **{{project.product}}** using the guidance below.
2195
-
2196
- _[TODO: Identify which tasks are critical (could lead to hazardous situation if performed incorrectly)]_
2197
-
2198
- | Task | Critical | Hazardous Situation if Error | Mitigation |
2199
- | --- | --- | --- | --- |
2200
- | | | | |
2201
-
2202
- ---
2203
-
2204
- ## 4. Task Flow Analysis
2205
-
2206
- The diagram below is rendered from the corresponding model view and reflects the current state of the model:
2207
-
2208
- {{diagram:task-flow}}
2209
-
2210
- _[TODO: Document sequential and parallel task flows with decision points]_
2211
-
2212
- ---
2213
-
2214
- {{include:shared/snippets/revision-history-table.md}}
2215
- `,ti=`---
2216
- id: ue-plan
2217
- title: Usability Engineering Plan
2218
- standard: IEC 62366-1:2015+AMD1:2020
2219
- clauses: ["4"]
2220
- required_for: ["CE", "FDA_510k", "MDR"]
2221
- ---
2222
-
2223
- {{include:shared/snippets/document-control-header.md}}
2224
-
2225
- {{toc}}
2226
-
2227
- ---
2228
-
2229
- ## 1. Purpose
2230
-
2231
- This Usability Engineering Plan (UE Plan) defines the usability engineering activities for **{{project.product}}** per IEC 62366-1:2015.
2232
-
2233
- ---
2234
-
2235
- ## 2. Intended Users
2236
-
2237
- Identify every intended user group of **{{project.product}}**, including their roles, training assumptions, and use environments.
2238
-
2239
- _[TODO: Define all intended user groups (clinicians, patients, technicians, lay users)]_
2240
-
2241
- ---
2242
-
2243
- ## 3. Intended Use Environment
2244
-
2245
- Complete this section for **{{project.product}}** using the guidance below.
2246
-
2247
- _[TODO: Describe all use environments: clinical, home, ambulatory, etc.]_
2248
-
2249
- ---
2250
-
2251
- ## 4. Use-Related Hazards
2252
-
2253
- This section is generated from the system model. The table below lists the **Use-Related Hazards** elements currently defined:
2254
-
2255
- \`\`\`memo-query
2256
- kind: [UseCase, UserActivity]
2257
- display: table
2258
- columns: name, layer, doc
2259
- sort: name
2260
- empty: "No use cases or user activities defined."
2261
- \`\`\`
2262
-
2263
- ---
2264
-
2265
- ## 5. Usability Testing Plan
2266
-
2267
- ### 5.1 Formative Evaluation
2268
-
2269
- _[TODO: Describe formative evaluation approach: cognitive walkthrough, expert review, prototype testing]_
2270
-
2271
- ### 5.2 Summative Evaluation
2272
-
2273
- _[TODO: Describe summative usability testing: participants, scenarios, pass/fail criteria]_
2274
-
2275
- ---
2276
-
2277
- ## 6. User Interface Elements
2278
-
2279
- This section is generated from the system model. The table below lists the **User Interface Elements** elements currently defined:
2280
-
2281
- \`\`\`memo-query
2282
- kind: UserInterface
2283
- display: table
2284
- columns: name, layer, doc
2285
- sort: name
2286
- empty: "No UserInterface elements defined."
2287
- \`\`\`
2288
-
2289
- ---
2290
-
2291
- {{include:shared/snippets/revision-history-table.md}}
2292
-
2293
- {{include:shared/snippets/approval-block.md}}
2294
-
2295
- {{include:shared/snippets/references-section.md}}
2296
- `,ni=`---
2297
- id: ui-spec
2298
- title: User Interface Specification
2299
- standard: IEC 62366-1:2015+AMD1:2020
2300
- clauses: ["5.6"]
2301
- required_for: ["CE", "MDR"]
2302
- ---
2303
-
2304
- {{include:shared/snippets/document-control-header.md}}
2305
-
2306
- {{toc}}
2307
-
2308
- ---
2309
-
2310
- ## 1. Purpose
2311
-
2312
- Specifies the user interface design for **{{project.product}}** per IEC 62366-1:2015 §5.6.
2313
-
2314
- ---
2315
-
2316
- ## 2. User Interface Elements
2317
-
2318
- This section is generated from the system model. The table below lists the **User Interface Elements** elements currently defined:
2319
-
2320
- \`\`\`memo-query
2321
- kind: UserInterface
2322
- display: table
2323
- columns: name, layer, doc
2324
- sort: name
2325
- empty: "No UserInterface elements defined."
2326
- \`\`\`
2327
-
2328
- ---
2329
-
2330
- ## 3. Screen/Mode Specifications
2331
-
2332
- Complete this section for **{{project.product}}** using the guidance below.
2333
-
2334
- _[TODO: Document each screen, mode, and key interaction with screenshots or wireframes]_
2335
-
2336
- ---
2337
-
2338
- ## 4. Alerts and Alarms
2339
-
2340
- Complete this section for **{{project.product}}** using the guidance below.
2341
-
2342
- _[TODO: Document all alarms, alerts, and status indicators with their visual/auditory characteristics]_
2343
-
2344
- ---
2345
-
2346
- ## 5. Labeling on Device
2347
-
2348
- Complete this section for **{{project.product}}** using the guidance below.
2349
-
2350
- _[TODO: Document all labels, symbols, and icons used on the physical device]_
2351
-
2352
- ---
2353
-
2354
- {{include:shared/snippets/revision-history-table.md}}
2355
-
2356
- {{include:shared/snippets/approval-block.md}}
2357
- `,ri=`---
2358
- id: urra
2359
- title: Use-Related Risk Analysis
2360
- standard: IEC 62366-1:2015+AMD1:2020
2361
- clauses: ["5"]
2362
- required_for: ["CE", "FDA_510k", "MDR"]
2363
- ---
2364
-
2365
- {{include:shared/snippets/document-control-header.md}}
2366
-
2367
- {{toc}}
2368
-
2369
- ---
2370
-
2371
- ## 1. Purpose
2372
-
2373
- This Use-Related Risk Analysis (URRA) identifies use errors and use-related hazardous situations for **{{project.product}}** per IEC 62366-1:2015 §5.
2374
-
2375
- ---
2376
-
2377
- ## 2. Use Scenarios
2378
-
2379
- This section is generated from the system model. The table below lists the **Use Scenarios** elements currently defined:
2380
-
2381
- \`\`\`memo-query
2382
- kind: [UseCase, UserActivity]
2383
- display: table
2384
- columns: name, layer, doc
2385
- sort: name
2386
- empty: "No use scenarios defined. Add UseCase or UserActivity elements."
2387
- \`\`\`
2388
-
2389
- ---
2390
-
2391
- ## 3. Use Errors and Abnormal Use
2392
-
2393
- This section is generated from the system model. The table below lists the **Use Errors and Abnormal Use** elements currently defined:
2394
-
2395
- \`\`\`memo-query
2396
- kind: [Hazard, HazardousSituation]
2397
- where: layer == "ui"
2398
- display: table
2399
- columns: name, doc, layer
2400
- sort: name
2401
- empty: "No use-related hazards defined."
2402
- \`\`\`
2403
-
2404
- ---
2405
-
2406
- ## 4. Critical Tasks
2407
-
2408
- Complete this section for **{{project.product}}** using the guidance below.
2409
-
2410
- _[TODO: Identify the critical tasks whose failure could cause a hazardous situation]_
2411
-
2412
- ---
2413
-
2414
- ## 5. Mitigation Measures
2415
-
2416
- This section is generated from the system model. The table below lists the **Mitigation Measures** elements currently defined:
2417
-
2418
- \`\`\`memo-query
2419
- kind: [RiskControl, UsabilityRequirement]
2420
- display: table
2421
- columns: name, layer, doc
2422
- sort: name
2423
- empty: "No usability-related risk controls defined."
2424
- \`\`\`
2425
-
2426
- ---
2427
-
2428
- {{include:shared/snippets/revision-history-table.md}}
2429
-
2430
- {{include:shared/snippets/approval-block.md}}
2431
- `,oi=`---
2432
- id: use-spec
2433
- title: Intended Use and Indications for Use Specification
2434
- standard: IEC 62366-1:2015+AMD1:2020
2435
- clauses: ["5.1"]
2436
- required_for: ["CE", "FDA_510k", "MDR"]
2437
- ---
2438
-
2439
- {{include:shared/snippets/document-control-header.md}}
2440
-
2441
- ---
2442
-
2443
- ## 1. Intended Use
2444
-
2445
- Complete this section for **{{project.product}}** using the guidance below.
2446
-
2447
- _[TODO: Provide the FDA-required Indications for Use statement and intended use statement]_
2448
-
2449
- ---
2450
-
2451
- ## 2. Intended User Profile
2452
-
2453
- Complete this section for **{{project.product}}** using the guidance below.
2454
-
2455
- _[TODO: Describe user knowledge, training level, and physical/cognitive capabilities]_
2456
-
2457
- ---
2458
-
2459
- ## 3. Use Environment
2460
-
2461
- Complete this section for **{{project.product}}** using the guidance below.
2462
-
2463
- _[TODO: Describe physical, social, technical environments where the device will be used]_
2464
-
2465
- ---
2466
-
2467
- ## 4. Use Cases
2468
-
2469
- Use cases describing how intended users interact with **{{project.product}}**, drawn from the model:
2470
-
2471
- \`\`\`memo-query
2472
- kind: UseCase
2473
- display: table
2474
- columns: name, layer, doc
2475
- sort: name
2476
- empty: "No UseCase elements defined."
2477
- \`\`\`
2478
-
2479
- ---
2480
-
2481
- ## 5. Known Use-Related Constraints
2482
-
2483
- Complete this section for **{{project.product}}** using the guidance below.
2484
-
2485
- _[TODO: Describe contraindications, limitations, and warnings that constrain use]_
2486
-
2487
- ---
2488
-
2489
- {{include:shared/snippets/revision-history-table.md}}
2490
-
2491
- {{include:shared/snippets/approval-block.md}}
2492
- `,si=`---
2493
- id: fmea
2494
- title: Failure Mode and Effects Analysis
2495
- standard: IEC 60812:2018
2496
- clauses: ["5", "6", "7"]
2497
- required_for: ["CE", "FDA_510k", "FDA_PMA"]
2498
- ---
2499
-
2500
- {{include:shared/snippets/document-control-header.md}}
2501
-
2502
- {{toc}}
2503
-
2504
- ---
2505
-
2506
- ## 1. Purpose and Scope
2507
-
2508
- This FMEA documents failure modes for **{{project.product}}** components, their effects, severity, and mitigations. Combines hardware, software, and system-level failure analysis.
2509
-
2510
- ---
2511
-
2512
- ## 2. Component Inventory
2513
-
2514
- This section is generated from the system model. The table below lists the **Component Inventory** elements currently defined:
2515
-
2516
- \`\`\`memo-query
2517
- kind: [Component, Subsystem, SoftwareItem]
2518
- display: table
2519
- columns: name, kind, layer, doc
2520
- sort: name
2521
- empty: "No components defined. Add Component, Subsystem, or SoftwareItem elements."
2522
- \`\`\`
2523
-
2524
- ---
2525
-
2526
- ## 3. FMEA Worksheet
2527
-
2528
- ### 3.1 Hardware Failures
2529
-
2530
- \`\`\`memo-query
2531
- kind: Component
2532
- display: table
2533
- columns: name, layer, doc
2534
- sort: name
2535
- empty: "No hardware components defined."
2536
- \`\`\`
2537
-
2538
- ### 3.2 Software Failures
2539
-
2540
- \`\`\`memo-query
2541
- kind: [SoftwareItem, SoftwareUnit]
2542
- display: table
2543
- columns: name, kind, layer, doc
2544
- sort: name
2545
- empty: "No software items defined."
2546
- \`\`\`
2547
-
2548
- ### 3.3 Interface Failures
2549
-
2550
- \`\`\`memo-query
2551
- kind: Interface
2552
- display: table
2553
- columns: name, layer, doc
2554
- sort: name
2555
- empty: "No interfaces defined."
2556
- \`\`\`
2557
-
2558
- ---
2559
-
2560
- ## 4. Risk Controls for FMEA Items
2561
-
2562
- This section is generated from the system model. The table below lists the **Risk Controls for FMEA Items** elements currently defined:
2563
-
2564
- \`\`\`memo-query
2565
- kind: RiskControl
2566
- display: table
2567
- columns: name, layer, doc
2568
- sort: name
2569
- empty: "No risk controls defined."
2570
- \`\`\`
2571
-
2572
- ---
2573
-
2574
- ## 5. Unmitigated Failures
2575
-
2576
- Complete this section for **{{project.product}}** using the guidance below.
2577
-
2578
- _[TODO: List any failure modes without risk controls and justify residual risk]_
2579
-
2580
- ---
2581
-
2582
- {{include:shared/snippets/revision-history-table.md}}
2583
-
2584
- {{include:shared/snippets/approval-block.md}}
2585
- `,ii=`---
2586
- id: fta
2587
- title: Fault Tree Analysis
2588
- standard: ISO 14971:2019
2589
- clauses: ["5", "6"]
2590
- required_for: ["CE"]
2591
- ---
2592
-
2593
- {{include:shared/snippets/document-control-header.md}}
2594
-
2595
- {{toc}}
2596
-
2597
- ---
2598
-
2599
- ## 1. Purpose
2600
-
2601
- This Fault Tree Analysis (FTA) complements the FMEA by providing a top-down analysis of failure modes that could lead to identified harms for **{{project.product}}**.
2602
-
2603
- ---
2604
-
2605
- ## 2. Top Events (Harms)
2606
-
2607
- This section is generated from the system model. The table below lists the **Top Events (Harms)** elements currently defined:
2608
-
2609
- \`\`\`memo-query
2610
- kind: Harm
2611
- display: table
2612
- columns: name, doc, layer
2613
- sort: name
2614
- empty: "No harm elements defined. Add Harm elements to the model."
2615
- \`\`\`
2616
-
2617
- ---
2618
-
2619
- ## 3. Contributing Failure Modes
2620
-
2621
- This section is generated from the system model. The table below lists the **Contributing Failure Modes** elements currently defined:
2622
-
2623
- \`\`\`memo-query
2624
- kind: [Hazard, HazardousSituation]
2625
- display: grouped
2626
- group_by: layer
2627
- columns: name, kind, doc
2628
- sort: name
2629
- empty: "No hazards or hazardous situations defined."
2630
- \`\`\`
2631
-
2632
- ---
2633
-
2634
- ## 4. Fault Tree Diagrams
2635
-
2636
- The diagram below is rendered from the corresponding model view and reflects the current state of the model:
2637
-
2638
- {{diagram:fta-diagram}}
2639
-
2640
- _[TODO: Attach or reference FTA diagram files]_
2641
-
2642
- ---
2643
-
2644
- ## 5. Cut Sets and Recommendations
2645
-
2646
- Complete this section for **{{project.product}}** using the guidance below.
2647
-
2648
- _[TODO: List minimal cut sets and associated risk reduction recommendations]_
2649
-
2650
- ---
2651
-
2652
- {{include:shared/snippets/revision-history-table.md}}
2653
-
2654
- {{include:shared/snippets/approval-block.md}}
2655
- `,ai=`---
2656
- id: har
2657
- title: Hazard Analysis Report
2658
- standard: ISO 14971:2019
2659
- clauses: ["5", "6", "7"]
2660
- required_for: ["CE", "FDA_510k", "FDA_PMA", "MDR"]
2661
- ---
2662
-
2663
- {{include:shared/snippets/document-control-header.md}}
2664
-
2665
- {{toc}}
2666
-
2667
- ---
2668
-
2669
- ## 1. Purpose
2670
-
2671
- This Hazard Analysis Report documents the systematic identification of hazards, hazardous situations, and harms associated with **{{project.product}}**, along with the associated risk estimation and risk control measures.
2672
-
2673
- ---
2674
-
2675
- ## 2. Hazard Summary
2676
-
2677
- The following metric is computed live from the model:
2678
-
2679
- \`\`\`memo-query
2680
- kind: Hazard
2681
- display: count
2682
- label: Total hazards identified
2683
- \`\`\`
2684
-
2685
- \`\`\`memo-query
2686
- kind: HazardousSituation
2687
- display: count
2688
- label: Hazardous situations
2689
- \`\`\`
2690
-
2691
- \`\`\`memo-query
2692
- kind: RiskControl
2693
- display: count
2694
- label: Risk control measures
2695
- \`\`\`
2696
-
2697
- ---
2698
-
2699
- ## 3. Hazard Identification
2700
-
2701
- All foreseeable hazards arising from the device, its intended use, and reasonably foreseeable misuse are listed below.
2702
-
2703
- ### 3.1 Energy Hazards
2704
-
2705
- \`\`\`memo-query
2706
- kind: Hazard
2707
- where: doc contains "energy"
2708
- display: table
2709
- columns: name, doc, layer
2710
- sort: name
2711
- empty: "No energy hazards identified."
2712
- \`\`\`
2713
-
2714
- ### 3.2 Biological and Chemical Hazards
2715
-
2716
- \`\`\`memo-query
2717
- kind: Hazard
2718
- where: doc contains "biolog"
2719
- display: table
2720
- columns: name, doc, layer
2721
- empty: "No biological/chemical hazards identified."
2722
- \`\`\`
2723
-
2724
- ### 3.3 Operational Hazards
2725
-
2726
- \`\`\`memo-query
2727
- kind: Hazard
2728
- display: grouped
2729
- group_by: layer
2730
- columns: name, doc
2731
- sort: name
2732
- empty: "No hazards defined. Add Hazard elements to model/risk/*.sysml."
2733
- \`\`\`
2734
-
2735
- ---
2736
-
2737
- ## 4. Hazardous Situations
2738
-
2739
- This section is generated from the system model. The table below lists the **Hazardous Situations** elements currently defined:
2740
-
2741
- \`\`\`memo-query
2742
- kind: HazardousSituation
2743
- display: table
2744
- columns: name, doc, layer
2745
- sort: name
2746
- empty: "No hazardous situations defined. Add HazardousSituation elements."
2747
- \`\`\`
2748
-
2749
- ---
2750
-
2751
- ## 5. Risk Estimation
2752
-
2753
- <!-- [GUIDANCE] For each hazardous situation, estimate probability of occurrence and severity of harm per ISO 14971:2019 §5. -->
2754
-
2755
- \`\`\`memo-query
2756
- kind: Harm
2757
- display: table
2758
- columns: name, doc, layer
2759
- sort: name
2760
- empty: "No harm elements defined. Add Harm elements linked to HazardousSituation."
2761
- \`\`\`
2762
-
2763
- ---
2764
-
2765
- ## 6. Risk Control Measures
2766
-
2767
- ### 6.1 Inherent Safety by Design
2768
-
2769
- \`\`\`memo-query
2770
- kind: RiskControl
2771
- where: doc contains "design"
2772
- display: table
2773
- columns: name, doc, layer
2774
- empty: "No inherent safety controls."
2775
- \`\`\`
2776
-
2777
- ### 6.2 Protective Measures
2778
-
2779
- \`\`\`memo-query
2780
- kind: RiskControl
2781
- display: table
2782
- columns: name, doc, layer
2783
- sort: name
2784
- empty: "No risk controls defined. Add RiskControl elements."
2785
- \`\`\`
2786
-
2787
- ### 6.3 Information for Safety
2788
-
2789
- _[TODO: List all warnings, cautions, and contraindications in labeling]_
2790
-
2791
- ---
2792
-
2793
- ## 7. Residual Risk Evaluation
2794
-
2795
- This section is generated from the system model. The table below lists the **Residual Risk Evaluation** elements currently defined:
2796
-
2797
- \`\`\`memo-query
2798
- kind: Hazard
2799
- display: table
2800
- columns: name, layer, doc
2801
- sort: name
2802
- empty: "All hazards have been evaluated."
2803
- \`\`\`
2804
-
2805
- ---
2806
-
2807
- ## 8. Benefit-Risk Analysis
2808
-
2809
- <!-- [GUIDANCE] Per ISO 14971:2019 §8, if residual risks remain after all control measures, the overall residual risk must be judged acceptable relative to medical benefits. -->
2810
-
2811
- _[TODO: Document benefit-risk justification if any residual risks remain]_
2812
-
2813
- ---
2814
-
2815
- {{include:shared/snippets/revision-history-table.md}}
2816
-
2817
- {{include:shared/snippets/approval-block.md}}
2818
-
2819
- {{include:shared/snippets/references-section.md}}
2820
- `,li=`---
2821
- id: risk-benefit
2822
- title: Risk-Benefit Analysis
2823
- standard: ISO 14971:2019
2824
- clauses: ["8"]
2825
- required_for: ["CE", "MDR"]
2826
- ---
2827
-
2828
- {{include:shared/snippets/document-control-header.md}}
2829
-
2830
- ---
2831
-
2832
- ## 1. Purpose
2833
-
2834
- This document provides the benefit-risk analysis for **{{project.product}}** as required by ISO 14971:2019 §8. It is prepared when residual risks cannot be further reduced and a judgment of acceptability must be made.
2835
-
2836
- ---
2837
-
2838
- ## 2. Medical Benefits
2839
-
2840
- Complete this section for **{{project.product}}** using the guidance below.
2841
-
2842
- _[TODO: Describe the medical benefits of the device for its intended patient population]_
2843
-
2844
- ---
2845
-
2846
- ## 3. Residual Risks Summary
2847
-
2848
- This section is generated from the system model. The table below lists the **Residual Risks Summary** elements currently defined:
2849
-
2850
- \`\`\`memo-query
2851
- kind: Hazard
2852
- display: table
2853
- columns: name, doc, layer
2854
- sort: name
2855
- empty: "No residual risks identified — standard risk controls are sufficient."
2856
- \`\`\`
2857
-
2858
- ---
2859
-
2860
- ## 4. Benefit-Risk Conclusion
2861
-
2862
- Complete this section for **{{project.product}}** using the guidance below.
2863
-
2864
- _[TODO: State the conclusion: the medical benefits of the intended use outweigh the residual risks]_
2865
-
2866
- ---
2867
-
2868
- {{include:shared/snippets/revision-history-table.md}}
2869
-
2870
- {{include:shared/snippets/approval-block.md}}
2871
- `,ci=`---
2872
- id: risk-matrix
2873
- title: Risk Matrix
2874
- standard: ISO 14971:2019
2875
- clauses: ["5", "6"]
2876
- required_for: ["CE", "MDR"]
2877
- ---
2878
-
2879
- {{include:shared/snippets/document-control-header.md}}
2880
-
2881
- ---
2882
-
2883
- ## Risk Matrix
2884
-
2885
- This matrix shows the distribution of identified hazards across severity and probability levels.
2886
-
2887
- \`\`\`memo-query
2888
- kind: Hazard
2889
- display: matrix
2890
- row_kind: kind
2891
- col_kind: layer
2892
- empty: "No hazards defined."
2893
- \`\`\`
2894
-
2895
- ### Hazard Coverage by Layer
2896
-
2897
- \`\`\`memo-query
2898
- kind: [Hazard, HazardousSituation, Harm]
2899
- display: grouped
2900
- group_by: layer
2901
- columns: name, kind, doc
2902
- empty: "No risk elements defined."
2903
- \`\`\`
2904
-
2905
- ---
2906
-
2907
- ## Risk Control Coverage
2908
-
2909
- This section is generated from the system model. The table below lists the **Risk Control Coverage** elements currently defined:
2910
-
2911
- \`\`\`memo-query
2912
- kind: RiskControl
2913
- display: table
2914
- columns: name, layer, doc
2915
- sort: name
2916
- empty: "No risk controls defined."
2917
- \`\`\`
2918
-
2919
- ---
2920
-
2921
- {{include:shared/snippets/revision-history-table.md}}
2922
- `,di=`---
2923
- id: rmp
2924
- title: Risk Management Plan
2925
- standard: ISO 14971:2019
2926
- clauses: ["4.4"]
2927
- required_for: ["CE", "FDA_510k", "FDA_PMA", "MDR"]
2928
- ---
2929
-
2930
- {{include:shared/snippets/document-control-header.md}}
2931
-
2932
- {{toc}}
2933
-
2934
- ---
2935
-
2936
- ## 1. Purpose and Scope
2937
-
2938
- This Risk Management Plan (RMP) defines the risk management activities for **{{project.product}}** developed by **{{project.company}}**. This plan is maintained throughout the product lifecycle in accordance with ISO 14971:2019.
2939
-
2940
- ### 1.1 Intended Use
2941
-
2942
- <!-- [GUIDANCE] Describe the intended use of the device, intended users, and intended use environment. -->
2943
-
2944
- _[TODO: Describe intended use, intended users, and intended use environment]_
2945
-
2946
- ### 1.2 Scope of Risk Management
2947
-
2948
- This plan applies to all phases of the product lifecycle: design, development, manufacture, post-market surveillance, and eventual decommission.
2949
-
2950
- ---
2951
-
2952
- ## 2. Regulatory Context
2953
-
2954
- Complete the table below for **{{project.product}}**:
2955
-
2956
- | Requirement | Reference |
2957
- | --- | --- |
2958
- | Risk Management Process | ISO 14971:2019 §4.1 |
2959
- | Risk Management Plan | ISO 14971:2019 §4.4 |
2960
- | Risk Estimation | ISO 14971:2019 §5 |
2961
- | Risk Evaluation | ISO 14971:2019 §6 |
2962
- | Risk Control | ISO 14971:2019 §7 |
2963
- | Overall Residual Risk | ISO 14971:2019 §8 |
2964
- | Risk Management Review | ISO 14971:2019 §9 |
2965
- | Post-production | ISO 14971:2019 §10 |
2966
-
2967
- ---
2968
-
2969
- ## 3. Risk Management Team
2970
-
2971
- <!-- [GUIDANCE] List all personnel involved in risk management activities. -->
2972
-
2973
- | Role | Name | Responsibilities |
2974
- | --- | --- | --- |
2975
- | Risk Management Lead | | Overall RM coordination |
2976
- | Clinical Representative | | Clinical risk input |
2977
- | Software Engineer | | Software FMEA and SOUP risk |
2978
- | Regulatory Affairs | | Standards compliance |
2979
- | Quality Engineer | | Process compliance |
2980
-
2981
- ---
2982
-
2983
- ## 4. Risk Acceptability Criteria
2984
-
2985
- ### 4.1 Severity Levels
2986
-
2987
- \`\`\`memo-query
2988
- kind: RiskAcceptabilityCriteria
2989
- display: table
2990
- columns: name, doc, layer
2991
- empty: "No risk acceptability criteria defined. Add RiskAcceptabilityCriteria elements to the model."
2992
- \`\`\`
2993
-
2994
- ### 4.2 Risk Policy
2995
-
2996
- <!-- [GUIDANCE] Define the risk policy: ALARP, broadly acceptable, or unacceptable regions. -->
2997
-
2998
- _[TODO: Define risk acceptability matrix — probability vs. severity]_
2999
-
3000
- Residual risk is acceptable when:
3001
- - All individual risks are reduced to ALARP or broadly acceptable level
3002
- - Overall residual risk is acceptable per §8 of ISO 14971:2019
3003
- - Unmitigated hazards:
3004
-
3005
- \`\`\`memo-query
3006
- kind: Hazard
3007
- where: layer == "risk"
3008
- display: count
3009
- label: Total hazards in model
3010
- \`\`\`
3011
-
3012
- ---
3013
-
3014
- ## 5. Risk Management Activities
3015
-
3016
- ### 5.1 Hazard Identification
3017
-
3018
- All hazard identification activities are documented in the Hazard Analysis Report (HAR).
3019
-
3020
- \`\`\`memo-query
3021
- kind: Hazard
3022
- display: table
3023
- columns: name, layer, doc
3024
- sort: name
3025
- empty: "No hazards defined. Add Hazard elements to model/risk/*.sysml."
3026
- \`\`\`
3027
-
3028
- ### 5.2 Risk Estimation and Evaluation
3029
-
3030
- Risk estimation is performed for each hazardous situation per ISO 14971:2019 §5–6.
3031
-
3032
- \`\`\`memo-query
3033
- kind: HazardousSituation
3034
- display: table
3035
- columns: name, layer, doc
3036
- sort: name
3037
- empty: "No hazardous situations defined."
3038
- \`\`\`
3039
-
3040
- ### 5.3 Risk Control Measures
3041
-
3042
- \`\`\`memo-query
3043
- kind: RiskControl
3044
- display: table
3045
- columns: name, layer, doc
3046
- sort: name
3047
- empty: "No risk controls defined."
3048
- \`\`\`
3049
-
3050
- ### 5.4 Residual Risk Evaluation
3051
-
3052
- Unmitigated hazards (hazards without associated risk controls):
3053
-
3054
- \`\`\`memo-query
3055
- kind: Hazard
3056
- display: table
3057
- columns: name, doc
3058
- empty: "All hazards have associated risk controls."
3059
- \`\`\`
3060
-
3061
- ---
3062
-
3063
- ## 6. Risk Management Documentation
3064
-
3065
- Complete the table below for **{{project.product}}**:
3066
-
3067
- | Document | Purpose | Reference |
3068
- | --- | --- | --- |
3069
- | Hazard Analysis Report (HAR) | Hazard identification and estimation | HAR |
3070
- | FMEA | Failure mode analysis | FMEA |
3071
- | Risk Benefit Analysis | Benefit-risk justification | N/A |
3072
- | Risk Management Report | Overall residual risk summary | N/A |
3073
-
3074
- ---
3075
-
3076
- ## 7. Plan Maintenance
3077
-
3078
- This plan shall be reviewed:
3079
- - At each major design change
3080
- - Following post-market surveillance findings
3081
- - Prior to each design review gate
3082
- - At least annually during active development
3083
-
3084
- ---
3085
-
3086
- {{include:shared/snippets/revision-history-table.md}}
3087
-
3088
- {{include:shared/snippets/approval-block.md}}
3089
-
3090
- {{include:shared/snippets/references-section.md}}
3091
- `,ui=`---
3092
- id: rmr
3093
- title: Risk Management Report
3094
- standard: ISO 14971:2019
3095
- clauses: ["9"]
3096
- required_for: ["CE", "FDA_510k", "FDA_PMA", "MDR"]
3097
- ---
3098
-
3099
- {{include:shared/snippets/document-control-header.md}}
3100
-
3101
- {{toc}}
3102
-
3103
- ---
3104
-
3105
- ## 1. Purpose
3106
-
3107
- This Risk Management Report (RMR) summarizes the results of all risk management activities performed for **{{project.product}}** in accordance with ISO 14971:2019 §9.
3108
-
3109
- ---
3110
-
3111
- ## 2. Summary Statistics
3112
-
3113
- The following metric is computed live from the model:
3114
-
3115
- \`\`\`memo-query
3116
- kind: Hazard
3117
- display: count
3118
- label: Total hazards identified
3119
- \`\`\`
3120
-
3121
- \`\`\`memo-query
3122
- kind: RiskControl
3123
- display: count
3124
- label: Risk controls implemented
3125
- \`\`\`
3126
-
3127
- \`\`\`memo-query
3128
- kind: HazardousSituation
3129
- display: count
3130
- label: Hazardous situations analyzed
3131
- \`\`\`
3132
-
3133
- ---
3134
-
3135
- ## 3. Risk Management Plan Compliance
3136
-
3137
- <!-- [GUIDANCE] Confirm that the risk management plan was executed as documented. -->
3138
-
3139
- _[TODO: Confirm that all activities in the Risk Management Plan were completed]_
3140
-
3141
- | Activity | Status | Reference |
3142
- | --- | --- | --- |
3143
- | Hazard identification | | HAR |
3144
- | Risk estimation | | HAR |
3145
- | Risk evaluation | | HAR |
3146
- | Risk control implementation | | Design records |
3147
- | Residual risk evaluation | | HAR |
3148
- | Overall residual risk | | This document |
3149
- | Post-production monitoring | | Post-Market Surveillance Plan |
3150
-
3151
- ---
3152
-
3153
- ## 4. Overall Residual Risk Evaluation
3154
-
3155
- ### 4.1 Remaining Hazards
3156
-
3157
- \`\`\`memo-query
3158
- kind: Hazard
3159
- display: table
3160
- columns: name, layer, doc
3161
- sort: name
3162
- empty: "All identified hazards have been evaluated."
3163
- \`\`\`
3164
-
3165
- ### 4.2 Overall Residual Risk Conclusion
3166
-
3167
- <!-- [GUIDANCE] Conclude whether the overall residual risk is acceptable relative to the medical benefits of the device. -->
3168
-
3169
- _[TODO: State the overall residual risk conclusion with justification]_
3170
-
3171
- ---
3172
-
3173
- ## 5. Benefit-Risk Statement
3174
-
3175
- Complete this section for **{{project.product}}** using the guidance below.
3176
-
3177
- _[TODO: State clearly that the benefits of the device outweigh the residual risks for the intended use]_
3178
-
3179
- ---
3180
-
3181
- ## 6. Post-Production Information Collection
3182
-
3183
- Post-production information collection activities are documented in the Post-Market Surveillance Plan.
3184
-
3185
- ---
3186
-
3187
- {{include:shared/snippets/revision-history-table.md}}
3188
-
3189
- {{include:shared/snippets/approval-block.md}}
3190
-
3191
- {{include:shared/snippets/references-section.md}}
3192
- `,pi=`---
3193
- id: approval-block
3194
- title: Approval Block
3195
- ---
3196
-
3197
- ## Approvals
3198
-
3199
- This document has been reviewed and approved by the following personnel:
3200
-
3201
- | Name | Role | Signature | Date |
3202
- | --- | --- | --- | --- |
3203
- | | Quality Assurance | | |
3204
- | | Regulatory Affairs | | |
3205
- | | Engineering Lead | | |
3206
- | | Clinical Affairs | | |
3207
-
3208
- `,mi=`---
3209
- id: document-control-header
3210
- title: Document Control Header
3211
- ---
3212
-
3213
- | Field | Value |
3214
- | --- | --- |
3215
- | **Product** | {{project.product}} |
3216
- | **Company** | {{project.company}} |
3217
- | **Device Type** | {{project.device_type}} |
3218
- | **Document Version** | {{project.version}} |
3219
- | **Development Phase** | {{project.phase}} |
3220
- | **Date** | — |
3221
- | **Confidentiality** | Confidential — {{project.company}} |
3222
-
3223
- `,fi=`---
3224
- id: references-section
3225
- title: References
3226
- ---
3227
-
3228
- ## References
3229
-
3230
- | Standard | Title |
3231
- | --- | --- |
3232
- | ISO 14971:2019 | Medical devices — Application of risk management to medical devices |
3233
- | IEC 62304:2006+AMD1:2015 | Medical device software — Software life cycle processes |
3234
- | IEC 62366-1:2015+AMD1:2020 | Medical devices — Usability engineering |
3235
- | ISO 13485:2016 | Medical devices — Quality management systems |
3236
- | 21 CFR Part 820 | Quality System Regulation |
3237
- | IEC 81001-5-1:2021 | Health software and health IT systems safety, effectiveness and security |
3238
-
3239
- `,hi=`---
3240
- id: revision-history-table
3241
- title: Revision History Table
3242
- ---
3243
-
3244
- ## Revision History
3245
-
3246
- | Version | Date | Author | Description of Change |
3247
- | --- | --- | --- | --- |
3248
- | 1.0 | {{project.version}} | {{project.authors}} | Initial release |
3249
-
3250
- `,gi=Object.assign({"../../../../node_modules/@memoarchitect/ontology/src/compliance/dhf-templates/21cfr820/change-record.md":js,"../../../../node_modules/@memoarchitect/ontology/src/compliance/dhf-templates/21cfr820/design-input.md":Ds,"../../../../node_modules/@memoarchitect/ontology/src/compliance/dhf-templates/21cfr820/design-output.md":As,"../../../../node_modules/@memoarchitect/ontology/src/compliance/dhf-templates/21cfr820/design-review.md":Fs,"../../../../node_modules/@memoarchitect/ontology/src/compliance/dhf-templates/21cfr820/design-validation.md":Rs,"../../../../node_modules/@memoarchitect/ontology/src/compliance/dhf-templates/21cfr820/design-verification.md":_s,"../../../../node_modules/@memoarchitect/ontology/src/compliance/dhf-templates/21cfr820/dhf-index.md":Ts,"../../../../node_modules/@memoarchitect/ontology/src/compliance/dhf-templates/21cfr820/transfer-plan.md":Is,"../../../../node_modules/@memoarchitect/ontology/src/compliance/dhf-templates/21cfr820/user-needs.md":Ns,"../../../../node_modules/@memoarchitect/ontology/src/compliance/dhf-templates/21cfr820/vv-plan.md":Os,"../../../../node_modules/@memoarchitect/ontology/src/compliance/dhf-templates/21cfr820/vv-report.md":Ms,"../../../../node_modules/@memoarchitect/ontology/src/compliance/dhf-templates/fda-cybersecurity/incident-response.md":Ps,"../../../../node_modules/@memoarchitect/ontology/src/compliance/dhf-templates/fda-cybersecurity/postmarket-surveillance.md":zs,"../../../../node_modules/@memoarchitect/ontology/src/compliance/dhf-templates/fda-cybersecurity/security-arch.md":Bs,"../../../../node_modules/@memoarchitect/ontology/src/compliance/dhf-templates/fda-cybersecurity/threat-model.md":Ls,"../../../../node_modules/@memoarchitect/ontology/src/compliance/dhf-templates/fda-cybersecurity/vuln-assessment.md":qs,"../../../../node_modules/@memoarchitect/ontology/src/compliance/dhf-templates/iec-62304/change-control.md":Vs,"../../../../node_modules/@memoarchitect/ontology/src/compliance/dhf-templates/iec-62304/detailed-design.md":Us,"../../../../node_modules/@memoarchitect/ontology/src/compliance/dhf-templates/iec-62304/integration-test.md":$s,"../../../../node_modules/@memoarchitect/ontology/src/compliance/dhf-templates/iec-62304/sad.md":Ws,"../../../../node_modules/@memoarchitect/ontology/src/compliance/dhf-templates/iec-62304/sbom.md":Hs,"../../../../node_modules/@memoarchitect/ontology/src/compliance/dhf-templates/iec-62304/sdp.md":Ks,"../../../../node_modules/@memoarchitect/ontology/src/compliance/dhf-templates/iec-62304/soup.md":Gs,"../../../../node_modules/@memoarchitect/ontology/src/compliance/dhf-templates/iec-62304/srs.md":Ys,"../../../../node_modules/@memoarchitect/ontology/src/compliance/dhf-templates/iec-62304/sw-traceability.md":Js,"../../../../node_modules/@memoarchitect/ontology/src/compliance/dhf-templates/iec-62304/system-test.md":Qs,"../../../../node_modules/@memoarchitect/ontology/src/compliance/dhf-templates/iec-62366/formative-eval.md":Xs,"../../../../node_modules/@memoarchitect/ontology/src/compliance/dhf-templates/iec-62366/summative-eval.md":Zs,"../../../../node_modules/@memoarchitect/ontology/src/compliance/dhf-templates/iec-62366/task-analysis.md":ei,"../../../../node_modules/@memoarchitect/ontology/src/compliance/dhf-templates/iec-62366/ue-plan.md":ti,"../../../../node_modules/@memoarchitect/ontology/src/compliance/dhf-templates/iec-62366/ui-spec.md":ni,"../../../../node_modules/@memoarchitect/ontology/src/compliance/dhf-templates/iec-62366/urra.md":ri,"../../../../node_modules/@memoarchitect/ontology/src/compliance/dhf-templates/iec-62366/use-spec.md":oi,"../../../../node_modules/@memoarchitect/ontology/src/compliance/dhf-templates/iso-14971/fmea.md":si,"../../../../node_modules/@memoarchitect/ontology/src/compliance/dhf-templates/iso-14971/fta.md":ii,"../../../../node_modules/@memoarchitect/ontology/src/compliance/dhf-templates/iso-14971/har.md":ai,"../../../../node_modules/@memoarchitect/ontology/src/compliance/dhf-templates/iso-14971/risk-benefit.md":li,"../../../../node_modules/@memoarchitect/ontology/src/compliance/dhf-templates/iso-14971/risk-matrix.md":ci,"../../../../node_modules/@memoarchitect/ontology/src/compliance/dhf-templates/iso-14971/rmp.md":di,"../../../../node_modules/@memoarchitect/ontology/src/compliance/dhf-templates/iso-14971/rmr.md":ui,"../../../../node_modules/@memoarchitect/ontology/src/compliance/dhf-templates/shared/snippets/approval-block.md":pi,"../../../../node_modules/@memoarchitect/ontology/src/compliance/dhf-templates/shared/snippets/document-control-header.md":mi,"../../../../node_modules/@memoarchitect/ontology/src/compliance/dhf-templates/shared/snippets/references-section.md":fi,"../../../../node_modules/@memoarchitect/ontology/src/compliance/dhf-templates/shared/snippets/revision-history-table.md":hi}),Bt={};for(const[e,r]of Object.entries(gi)){const n=e.match(/dhf-templates\/(.+)\.md$/);n&&(Bt[n[1]]=r)}function yi(e){return e.replace(/^---[\s\S]*?---\n?/,"")}function Xn(e){return e.replace(/\{\{include:([^}]+)\}\}/g,(r,n)=>{const s=n.replace(/\.md$/,""),o=Bt[s];return o?Xn(yi(o)):`<!-- [include: ${n} — not found] -->`})}function xi(e){const r=Bt[e];return r?Xn(r):null}const Ee=[{id:"risk",label:"Risk Management",color:"#dc2626",templates:[{id:"iso-14971/rmp",title:"Risk Management Plan",prefix:"RMP"},{id:"iso-14971/har",title:"Hazard Analysis Report",prefix:"HAR"},{id:"iso-14971/fmea",title:"FMEA",prefix:"FMEA"},{id:"iso-14971/fta",title:"Fault Tree Analysis",prefix:"FTA"},{id:"iso-14971/risk-benefit",title:"Risk-Benefit Analysis",prefix:"RBA"},{id:"iso-14971/rmr",title:"Risk Management Report",prefix:"RMR"}]},{id:"software",label:"Software",color:"#2563eb",templates:[{id:"iec-62304/sdp",title:"Software Development Plan",prefix:"SDP"},{id:"iec-62304/srs",title:"Software Requirements Spec",prefix:"SRS"},{id:"iec-62304/sad",title:"Software Architecture Description",prefix:"SAD"},{id:"iec-62304/detailed-design",title:"Software Detailed Design",prefix:"DDS"},{id:"iec-62304/integration-test",title:"Integration Test Plan",prefix:"ITP"},{id:"iec-62304/system-test",title:"System Test Plan",prefix:"STP"},{id:"iec-62304/soup",title:"SOUP List",prefix:"SOUP"},{id:"iec-62304/sbom",title:"Software Bill of Materials",prefix:"SBOM"},{id:"iec-62304/sw-traceability",title:"SW Traceability Matrix",prefix:"STM"},{id:"iec-62304/change-control",title:"Change Control Log",prefix:"CCL"}]},{id:"usability",label:"Usability",color:"#7c3aed",templates:[{id:"iec-62366/ue-plan",title:"Usability Engineering Plan",prefix:"UEP"},{id:"iec-62366/use-spec",title:"Intended Use Specification",prefix:"USE"},{id:"iec-62366/ui-spec",title:"User Interface Specification",prefix:"UIS"},{id:"iec-62366/task-analysis",title:"Task Analysis",prefix:"TA"},{id:"iec-62366/urra",title:"Use-Related Risk Analysis",prefix:"URRA"},{id:"iec-62366/formative-eval",title:"Formative Evaluation",prefix:"FE"},{id:"iec-62366/summative-eval",title:"Summative Evaluation",prefix:"SE"}]},{id:"requirements",label:"Requirements",color:"#0891b2",templates:[{id:"21cfr820/user-needs",title:"User Needs",prefix:"UN"},{id:"21cfr820/design-input",title:"Design Input Specification",prefix:"DIS"},{id:"21cfr820/design-output",title:"Design Output Specification",prefix:"DOS"}]},{id:"vv",label:"Verification & Validation",color:"#0d9488",templates:[{id:"21cfr820/vv-plan",title:"V&V Plan",prefix:"VVP"},{id:"21cfr820/vv-report",title:"V&V Report",prefix:"VVR"},{id:"21cfr820/design-verification",title:"Design Verification Report",prefix:"DVR"},{id:"21cfr820/design-validation",title:"Design Validation Report",prefix:"DVAR"},{id:"21cfr820/design-review",title:"Design Review Record",prefix:"DRR"}]},{id:"release",label:"Release & Change",color:"#4f46e5",templates:[{id:"21cfr820/transfer-plan",title:"Design Transfer Plan",prefix:"DTP"},{id:"21cfr820/change-record",title:"Design Change Record",prefix:"DCR"},{id:"21cfr820/dhf-index",title:"DHF Index",prefix:"DHF"}]},{id:"system",label:"System",color:"#059669",templates:[{id:"system/srs",title:"System Requirements Specification",prefix:"SRS"},{id:"system/sad",title:"System Architecture Description",prefix:"SyAD"},{id:"system/sds",title:"System Design Specification",prefix:"SDS"},{id:"system/icd",title:"Interface Control Document",prefix:"ICD"},{id:"system/svvp",title:"System V&V Plan",prefix:"SVVP"},{id:"system/svvr",title:"System V&V Report",prefix:"SVVR"}]},{id:"hardware",label:"Hardware",color:"#b45309",templates:[{id:"hardware/hdp",title:"Hardware Development Plan",prefix:"HDP"},{id:"hardware/hds",title:"Hardware Design Specification",prefix:"HDS"},{id:"hardware/hvp",title:"Hardware Verification Plan",prefix:"HVP"},{id:"hardware/hvr",title:"Hardware Verification Report",prefix:"HVR"},{id:"hardware/hbom",title:"Hardware Bill of Materials",prefix:"HBOM"},{id:"hardware/haz",title:"Hardware Hazard Analysis",prefix:"HHA"}]},{id:"cybersecurity",label:"Cybersecurity",color:"#d97706",templates:[{id:"fda-cybersecurity/threat-model",title:"Threat Model",prefix:"TM"},{id:"fda-cybersecurity/security-arch",title:"Security Architecture",prefix:"SA"},{id:"fda-cybersecurity/vuln-assessment",title:"Vulnerability Assessment",prefix:"VA"},{id:"fda-cybersecurity/postmarket-surveillance",title:"Post-Market Surveillance",prefix:"PMS"},{id:"fda-cybersecurity/incident-response",title:"Incident Response Plan",prefix:"IRP"}]}],Ft="#6B7280";function bi(e){var r;return((r=Ee.find(n=>n.label===e))==null?void 0:r.color)??Ft}function ft(e){const r=e.split(/[^a-zA-Z0-9]+/).filter(Boolean);return r.length>=2?r.slice(0,4).map(n=>n[0].toUpperCase()).join(""):r.length===1?r[0].slice(0,3).toUpperCase():"DOC"}const vi={position:"fixed",inset:0,zIndex:9999,display:"flex",alignItems:"center",justifyContent:"center",background:"rgba(0,0,0,0.4)"},wi={background:"#fff",borderRadius:"12px",padding:"20px",width:"460px",maxHeight:"560px",display:"flex",flexDirection:"column",boxShadow:"0 20px 60px rgba(0,0,0,0.2)"},dn=["Category","Template","Confirm"];function un(e,r=1e4){const{registerLlmRequest:n}=S.getState(),s=`dhf-${Date.now()}-${Math.random().toString(36).slice(2)}`;return new Promise((o,i)=>{n(s,o,i),e(s),setTimeout(()=>i(new Error("Request timed out.")),r)})}function Si({initialGroupId:e,existingDocs:r,numberingPrefix:n,onCreate:s,onClose:o}){const i=S(F=>F.connected),l=Ee.find(F=>F.id===e)??null,[a,d]=u.useState(l?1:0),[c,p]=u.useState(l),[m,x]=u.useState(""),[b,k]=u.useState({builtIn:new Set,repo:new Set,blank:!1}),[y,v]=u.useState("Untitled Document"),[w,_]=u.useState(null),[N,f]=u.useState(null),[D,E]=u.useState({}),[R,T]=u.useState(!1),[O,j]=u.useState(null),H=c===null&&a>0?m.trim()||"Other":(c==null?void 0:c.label)??"",U=(c==null?void 0:c.color)??Ft,X=u.useMemo(()=>new Set(r.map(F=>F.templateId)),[r]);u.useEffect(()=>{a!==1||w!==null||!i||un(F=>Ho(F)).then(_).catch(F=>f((F==null?void 0:F.message)??"Could not list repository files."))},[a,w,i]);const $=u.useMemo(()=>{const F=[];for(const q of(c==null?void 0:c.templates)??[])b.builtIn.has(q.id)&&F.push({key:q.id,defaultTitle:q.title,prefix:q.prefix,templateId:q.id});for(const q of b.repo){const K=w==null?void 0:w.find(h=>h.path===q),ne=(K==null?void 0:K.title)??q.split("/").pop().replace(/\.md$/,"");F.push({key:`repo:${q}`,defaultTitle:ne,prefix:ft(ne),templateId:`repo:${q}`})}return b.blank&&F.push({key:"blank",defaultTitle:y.trim()||"Untitled Document",prefix:ft(y),templateId:"blank"}),F},[b,c,w,y]),ae=F=>D[F.key]??F.defaultTitle,I=F=>F.templateId==="blank"||F.templateId.startsWith("repo:")?ft(ae(F)):F.prefix,W=u.useMemo(()=>{const F=new Map;return $.map(q=>{const K=`${n}-${I(q)}-`,ne=r.filter(A=>A.id.startsWith(K)).length,h=F.get(K)??0;return F.set(K,h+1),`${K}${String(ne+h+1).padStart(3,"0")}`})},[$,D,r,n]);async function G(){T(!0),j(null);try{const F=[];for(const q of $){let K=null;q.templateId.startsWith("repo:")?K=await un(ne=>Ko(ne,q.templateId.slice(5))):q.templateId==="blank"&&(K=`# ${ae(q)}
3251
-
3252
- _[TODO: Add content]_
3253
- `),F.push({title:ae(q),prefix:I(q),templateId:q.templateId,groupLabel:H,content:K})}s(F)}catch(F){j((F==null?void 0:F.message)??"Could not read template."),T(!1)}}const L=a===0?!0:a===1?$.length>0:$.length>0&&!R;return t.jsx("div",{style:vi,onClick:F=>{F.target===F.currentTarget&&o()},children:t.jsxs("div",{style:wi,children:[t.jsxs("div",{style:{display:"flex",alignItems:"center",gap:"8px",marginBottom:"4px"},children:[t.jsx("span",{style:{fontSize:"14px",fontWeight:700,color:"#1B3A4B",flex:1},children:"New Document"}),t.jsx("button",{onClick:o,style:{background:"none",border:"none",cursor:"pointer",color:"#9CA3AF",fontSize:"18px",lineHeight:1},children:"×"})]}),t.jsx("div",{style:{display:"flex",gap:"6px",marginBottom:"14px"},children:dn.map((F,q)=>t.jsxs("div",{style:{display:"flex",alignItems:"center",gap:"5px",fontSize:"11px",fontWeight:q===a?700:500,color:q===a?"#1B3A4B":q<a?"#059669":"#9CA3AF"},children:[t.jsx("span",{style:{width:"16px",height:"16px",borderRadius:"50%",display:"inline-flex",alignItems:"center",justifyContent:"center",fontSize:"9px",fontWeight:700,color:"#fff",background:q===a?"#1B3A4B":q<a?"#059669":"#D1D5DB"},children:q<a?"✓":q+1}),F,q<dn.length-1&&t.jsx("span",{style:{color:"#D1D5DB"},children:"—"})]},F))}),a===0&&t.jsxs("div",{style:{flex:1,overflowY:"auto",display:"flex",flexDirection:"column",gap:"4px"},children:[Ee.map(F=>t.jsx(pn,{label:F.label,color:F.color,detail:`${F.templates.length} meMO templates`,selected:(c==null?void 0:c.id)===F.id,onClick:()=>{p(F),k({builtIn:new Set,repo:new Set,blank:!1})}},F.id)),t.jsx(pn,{label:"Other",color:Ft,detail:"Custom category — blank or repository template",selected:c===null&&m!=="",onClick:()=>{p(null),x(m||"Other"),k({builtIn:new Set,repo:new Set,blank:!1})}}),c===null&&m!==""&&t.jsx("input",{value:m,onChange:F=>x(F.target.value),placeholder:"Category name, e.g. Clinical",autoFocus:!0,style:{margin:"2px 0 0 26px",padding:"6px 8px",border:"1px solid #D1D5DB",borderRadius:"5px",fontSize:"12px",color:"#1B3A4B",outline:"none"}})]}),a===1&&t.jsxs("div",{style:{flex:1,overflowY:"auto",display:"flex",flexDirection:"column",gap:"10px"},children:[t.jsxs("div",{style:{display:"flex",alignItems:"center",gap:"6px",fontSize:"12px",color:"#6B7280"},children:[t.jsx("span",{style:{width:"9px",height:"9px",borderRadius:"50%",background:U,display:"inline-block"}}),t.jsx("strong",{style:{color:"#1B3A4B"},children:H}),t.jsx("span",{children:"— pick one or more sources"})]}),c&&c.templates.length>0&&t.jsx(ht,{title:"meMO templates",hint:"Prefilled sections and model queries",children:c.templates.map(F=>t.jsx(gt,{label:F.title,sub:F.id,color:U,checked:b.builtIn.has(F.id),disabled:X.has(F.id),disabledNote:"exists",onToggle:()=>k(q=>{const K=new Set(q.builtIn);return K.has(F.id)?K.delete(F.id):K.add(F.id),{...q,builtIn:K}})},F.id))}),t.jsx(ht,{title:"Blank document",hint:"Start from an empty page",children:t.jsx(gt,{label:b.blank?"":"Blank document",color:U,checked:b.blank,onToggle:()=>k(F=>({...F,blank:!F.blank})),children:b.blank&&t.jsx("input",{value:y,onChange:F=>v(F.target.value),onClick:F=>F.stopPropagation(),style:{flex:1,padding:"4px 8px",border:"1px solid #D1D5DB",borderRadius:"5px",fontSize:"12px",color:"#1B3A4B",outline:"none"}})})}),t.jsxs(ht,{title:"From repository",hint:"Any markdown file in this project",children:[!i&&t.jsx(Me,{text:"Dev server not connected — repository templates unavailable."}),i&&N&&t.jsx(Me,{text:N,error:!0}),i&&!N&&w===null&&t.jsx(Me,{text:"Loading repository files…"}),i&&(w==null?void 0:w.length)===0&&t.jsx(Me,{text:"No markdown files found in this project."}),i&&(w==null?void 0:w.map(F=>t.jsx(gt,{label:F.title,sub:F.path,color:U,checked:b.repo.has(F.path),onToggle:()=>k(q=>{const K=new Set(q.repo);return K.has(F.path)?K.delete(F.path):K.add(F.path),{...q,repo:K}})},F.path)))]})]}),a===2&&t.jsxs("div",{style:{flex:1,overflowY:"auto",display:"flex",flexDirection:"column",gap:"6px"},children:[t.jsxs("div",{style:{fontSize:"12px",color:"#6B7280",marginBottom:"4px"},children:[$.length," document",$.length===1?"":"s"," will be created in",t.jsxs("strong",{style:{color:"#1B3A4B"},children:[" ",H]})," and saved to ",t.jsx("code",{style:{background:"#F3F4F6",padding:"0 4px",borderRadius:"3px",fontSize:"11px"},children:"dhf/documents/"}),":"]}),$.map((F,q)=>t.jsxs("div",{style:{display:"flex",alignItems:"center",gap:"8px",padding:"7px 10px",border:"1px solid #E5E7EB",borderRadius:"6px"},children:[t.jsx("span",{style:{fontSize:"11px",fontFamily:"monospace",fontWeight:700,color:U,whiteSpace:"nowrap"},children:W[q]}),t.jsx("input",{value:ae(F),onChange:K=>E(ne=>({...ne,[F.key]:K.target.value})),style:{flex:1,padding:"4px 8px",border:"1px solid #E5E7EB",borderRadius:"5px",fontSize:"12px",color:"#1B3A4B",outline:"none"}}),t.jsx("span",{style:{fontSize:"10px",color:"#9CA3AF",whiteSpace:"nowrap"},children:F.templateId==="blank"?"blank":F.templateId.startsWith("repo:")?"repo":"meMO"})]},F.key)),O&&t.jsx(Me,{text:O,error:!0})]}),t.jsxs("div",{style:{display:"flex",gap:"8px",justifyContent:"flex-end",marginTop:"16px"},children:[a>0&&t.jsx("button",{onClick:()=>d(F=>F-1),disabled:R,style:{padding:"7px 14px",borderRadius:"6px",border:"1px solid #E5E7EB",background:"#fff",fontSize:"13px",cursor:"pointer",color:"#374151",marginRight:"auto"},children:"← Back"}),t.jsx("button",{onClick:o,style:{padding:"7px 14px",borderRadius:"6px",border:"1px solid #E5E7EB",background:"#fff",fontSize:"13px",cursor:"pointer",color:"#374151"},children:"Cancel"}),a<2?t.jsx("button",{onClick:()=>d(F=>F+1),disabled:!L,style:{padding:"7px 16px",borderRadius:"6px",border:"none",background:L?"#1B3A4B":"#E5E7EB",color:L?"#fff":"#9CA3AF",fontSize:"13px",fontWeight:600,cursor:L?"pointer":"default"},children:"Next →"}):t.jsx("button",{onClick:G,disabled:!L,style:{padding:"7px 16px",borderRadius:"6px",border:"none",background:L?U:"#E5E7EB",color:L?"#fff":"#9CA3AF",fontSize:"13px",fontWeight:600,cursor:L?"pointer":"default"},children:R?"Creating…":`Create ${$.length>0?`(${$.length})`:""}`})]})]})})}function pn({label:e,color:r,detail:n,selected:s,onClick:o}){return t.jsxs("button",{onClick:o,style:{display:"flex",alignItems:"center",gap:"10px",padding:"9px 10px",borderRadius:"6px",border:`1px solid ${s?r:"#E5E7EB"}`,background:s?`${r}10`:"#fff",cursor:"pointer",textAlign:"left"},children:[t.jsx("span",{style:{width:"10px",height:"10px",borderRadius:"50%",background:r,flexShrink:0}}),t.jsx("span",{style:{flex:1,fontSize:"13px",fontWeight:600,color:"#1B3A4B"},children:e}),t.jsx("span",{style:{fontSize:"11px",color:"#9CA3AF"},children:n})]})}function ht({title:e,hint:r,children:n}){return t.jsxs("div",{children:[t.jsxs("div",{style:{fontSize:"10px",fontWeight:700,color:"#6B7280",textTransform:"uppercase",letterSpacing:"0.05em",marginBottom:"2px"},children:[e," ",t.jsxs("span",{style:{fontWeight:400,textTransform:"none",letterSpacing:0,color:"#9CA3AF"},children:["— ",r]})]}),t.jsx("div",{style:{display:"flex",flexDirection:"column",gap:"2px"},children:n})]})}function gt({label:e,sub:r,color:n,checked:s,disabled:o,disabledNote:i,onToggle:l,children:a}){return t.jsxs("label",{style:{display:"flex",alignItems:"center",gap:"10px",padding:"6px 8px",borderRadius:"6px",cursor:o?"not-allowed":"pointer",background:s?`${n}10`:"transparent",opacity:o?.45:1},children:[t.jsx("input",{type:"checkbox",checked:s,disabled:o,onChange:()=>!o&&l(),style:{accentColor:n}}),e&&t.jsx("span",{style:{fontSize:"13px",color:"#1B3A4B"},children:e}),a,r&&t.jsx("span",{style:{marginLeft:"auto",fontSize:"10px",fontFamily:"monospace",color:"#9CA3AF",overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap",maxWidth:"180px"},children:r}),o&&i&&t.jsx("span",{style:{fontSize:"10px",color:"#9CA3AF"},children:i})]})}function Me({text:e,error:r}){return t.jsx("div",{style:{fontSize:"11px",color:r?"#DC2626":"#9CA3AF",fontStyle:"italic",padding:"4px 8px"},children:e})}function fe({expanded:e,size:r=14,color:n=g.muted}){return t.jsx("svg",{width:r,height:r,viewBox:"0 0 16 16",fill:"none",style:{transition:"transform 150ms ease",transform:e?"rotate(90deg)":"rotate(0deg)",flexShrink:0},children:t.jsx("path",{d:"M6 4L10 8L6 12",stroke:n,strokeWidth:"1.5",strokeLinecap:"round",strokeLinejoin:"round"})})}function De({open:e,color:r=g.muted}){return e?t.jsxs("svg",{width:"16",height:"16",viewBox:"0 0 16 16",fill:"none",style:{flexShrink:0},children:[t.jsx("path",{d:"M1.5 3.5h4.8l1.2 1.5H14.5v8H1.5z",fill:r,opacity:"0.15",stroke:r,strokeWidth:"1",strokeLinejoin:"round"}),t.jsx("path",{d:"M1.5 5h13v8H1.5z",fill:r,opacity:"0.08"})]}):t.jsx("svg",{width:"16",height:"16",viewBox:"0 0 16 16",fill:"none",style:{flexShrink:0},children:t.jsx("path",{d:"M1.5 3.5h4.8l1.2 1.5H14.5v8H1.5z",fill:r,opacity:"0.15",stroke:r,strokeWidth:"1",strokeLinejoin:"round"})})}function Rt({color:e=g.muted}){return t.jsxs("svg",{width:"14",height:"14",viewBox:"0 0 16 16",fill:"none",style:{flexShrink:0},children:[t.jsx("rect",{x:"2",y:"1.5",width:"12",height:"13",rx:"1.5",fill:e,opacity:"0.1",stroke:e,strokeWidth:"1"}),t.jsx("line",{x1:"5",y1:"5.5",x2:"11",y2:"5.5",stroke:e,strokeWidth:"0.8",opacity:"0.5"}),t.jsx("line",{x1:"5",y1:"8",x2:"11",y2:"8",stroke:e,strokeWidth:"0.8",opacity:"0.5"}),t.jsx("line",{x1:"5",y1:"10.5",x2:"9",y2:"10.5",stroke:e,strokeWidth:"0.8",opacity:"0.5"})]})}function ki({elementId:e,currentKind:r,onClose:n}){const s=S(a=>a.updateElementKind),[o,i]=u.useState(r),l=u.useRef(null);return u.useEffect(()=>{const a=d=>{l.current&&!l.current.contains(d.target)&&n()};return document.addEventListener("mousedown",a),()=>document.removeEventListener("mousedown",a)},[n]),t.jsxs("div",{ref:l,className:"fixed z-50 rounded-lg overflow-hidden py-3 px-4",style:{top:"50%",left:"50%",transform:"translate(-50%, -50%)",background:"#FFFFFF",border:"1px solid #E5E7EB",boxShadow:"0 8px 32px rgba(0,0,0,0.16)",minWidth:"320px"},children:[t.jsx("div",{className:"font-semibold mb-3",style:{color:"#1B3A4B",fontSize:"13px"},children:"Change Element Type"}),t.jsxs("div",{className:"text-xs mb-1",style:{color:"#6B7280"},children:["Current: ",t.jsx("span",{style:{color:"#DC2626",fontWeight:600},children:r})," (not in ontology)"]}),t.jsx("select",{value:o,onChange:a=>i(a.target.value),className:"w-full px-3 py-2 rounded-lg mb-3 focus:outline-none",style:{background:"#F9F9F8",border:"1px solid #E5E7EB",color:"#1B3A4B",fontSize:"13px"},children:ms.map(a=>t.jsx("option",{value:a,children:a},a))}),t.jsxs("div",{className:"flex gap-2 justify-end",children:[t.jsx("button",{onClick:n,className:"px-3 py-1.5 rounded",style:{fontSize:"12px",color:"#6B7280",background:"#F0F0ED"},children:"Cancel"}),t.jsx("button",{onClick:()=>{s(e,o),n()},className:"px-3 py-1.5 rounded font-medium",style:{fontSize:"12px",color:"#FFFFFF",background:"#2DD4A8"},children:"Apply"})]})]})}function Ei({menu:e,onClose:r}){const n=S(b=>b.model),s=S(b=>b.selectElement),o=S(b=>b.addElement),i=S(b=>b.updateElementFolder),l=S(b=>b.moveFolder),a=S(b=>b.deleteFolder),[d,c]=u.useState(null),p=u.useRef(null);if(u.useEffect(()=>{const b=k=>{p.current&&!p.current.contains(k.target)&&r()};return document.addEventListener("mousedown",b),()=>document.removeEventListener("mousedown",b)},[r]),!n)return null;let m="",x=[];if(e.type==="element"&&e.elementId){const b=n.elements[e.elementId];if(!b)return null;m=b.name;const k=!zt[b.kind];x=[{label:"View details",action:()=>s(b.id)},{label:"Move to folder...",action:()=>{const y=window.prompt("Enter new folder path (e.g., Manufacturers/Hardware):",b.attributes[ke]||"");y!==null&&i(b.id,y)}},{label:"Copy ID",action:()=>{var y;return(y=navigator.clipboard)==null?void 0:y.writeText(b.id)}},...k?[{label:"⚠ Change Type…",action:()=>c({elementId:b.id,currentKind:b.kind})}]:[]]}else e.type==="folder"&&e.folderId&&e.kind?(m=`Folder: ${e.folderId.split("/").pop()}`,x=[{label:"Add Element here",action:()=>{const b=window.prompt("Enter element name:");b&&o(e.kind,b,e.folderId)}},{label:"Add Sub-group",action:()=>{const b=window.prompt("Enter group name:");if(b){const k=e.folderId?`${e.folderId}/${b}`:b;o(e.kind,`(new ${b} element)`,k)}}},{label:"Move Folder...",action:()=>{const b=window.prompt("Enter new folder path:",e.folderId);b&&b!==e.folderId&&l(e.kind,e.folderId,b)}},{label:"Delete Folder (Move items up)",danger:!0,action:()=>{window.confirm(`Move all elements in "${e.folderId}" to its parent group?`)&&a(e.kind,e.folderId)}}]):e.type==="kind"&&e.kind&&(m=`Category: ${e.kind}`,x=[{label:"Add Element",action:()=>{const b=window.prompt("Enter element name:");b&&o(e.kind,b,"")}},{label:"New Group",action:()=>{const b=window.prompt("Enter group name:");b&&o(e.kind,`(new ${b} element)`,b)}}]);return x.length?t.jsxs(t.Fragment,{children:[t.jsxs("div",{ref:p,className:"fixed z-50 rounded-lg overflow-hidden py-1",style:{left:e.x,top:e.y,background:g.surface,border:`1px solid ${g.border}`,boxShadow:"0 4px 16px rgba(0,0,0,0.12)",minWidth:"220px"},children:[t.jsx("div",{className:"px-3 py-1.5 font-bold truncate bg-slate-50",style:{color:g.primary,fontSize:C.xs,borderBottom:`1px solid ${g.border}`},children:m.toUpperCase()}),x.map((b,k)=>t.jsx("div",{className:"px-3 py-2 cursor-pointer transition-colors",style:{color:b.danger?"#DC2626":g.secondary,fontSize:C.explorer.item},onMouseEnter:y=>y.currentTarget.style.background="#F0F0ED",onMouseLeave:y=>y.currentTarget.style.background="transparent",onClick:()=>{b.action(),d||r()},children:b.label},k))]}),d&&t.jsx(ki,{elementId:d.elementId,currentKind:d.currentKind,onClose:()=>{c(null),r()}})]}):null}function Ci(e){const r=[],n=[...e].sort((o,i)=>o.name.localeCompare(i.name));for(const o of n){const l=(o.attributes[ke]||"").split("/").filter(Boolean);let a=r,d="";for(const c of l){d=d?`${d}/${c}`:c;const p=`f:${d}`;let m=a.find(x=>x.id===p);m||(m={id:p,name:c,type:"folder",children:[]},a.push(m)),a=m.children}a.push({id:o.id,name:o.name,type:"element",children:[],element:o})}const s=o=>{o.sort((i,l)=>i.type!==l.type?i.type==="folder"?-1:1:i.name.localeCompare(l.name));for(const i of o)i.children.length>0&&s(i.children)};return s(r),r}function Zn({nodes:e,level:r,expanded:n,toggleExpand:s,selectedElementId:o,selectElement:i,selectedElementIds:l,toggleElementSelection:a,violationCounts:d,baseColor:c,onContextMenu:p,onDragStart:m,onDrop:x,isUndefined:b}){return t.jsx(t.Fragment,{children:e.map(k=>{if(k.type==="folder"){const y=n.has(k.id);return t.jsxs("div",{style:{marginLeft:r>0?"16px":"0"},draggable:!0,onDragStart:v=>m(v,k),onDragOver:v=>v.preventDefault(),onDrop:v=>x(v,k.id.replace("f:","")),children:[t.jsxs("div",{className:"flex items-center gap-1.5 px-2 py-1 cursor-pointer select-none",style:{borderRadius:"4px",margin:"0 4px"},onMouseEnter:v=>v.currentTarget.style.background="#F0F0ED",onMouseLeave:v=>v.currentTarget.style.background="transparent",onClick:()=>s(k.id),onContextMenu:v=>p(v,"folder",k.id),children:[t.jsx(fe,{expanded:y,size:12,color:g.muted}),t.jsx(De,{open:y,color:c}),t.jsx("span",{className:"font-medium flex-1 truncate",style:{color:g.secondary,fontSize:C.explorer.kind},children:k.name})]}),y&&t.jsx(Zn,{nodes:k.children,level:r+1,expanded:n,toggleExpand:s,selectedElementId:o,selectElement:i,selectedElementIds:l,toggleElementSelection:a,violationCounts:d,baseColor:c,onContextMenu:p,onDragStart:m,onDrop:x,isUndefined:b})]},k.id)}else{const y=k.element,v=o===y.id,w=l.has(y.id),_=d.get(y.id)||0,N=ie[y.layer]||c;return t.jsxs("div",{className:"group flex items-center gap-1.5 px-2 py-1 cursor-pointer",style:{borderRadius:"4px",margin:"0 4px",marginLeft:(r>0?16:0)+20+"px",background:w?"#FFF3CD":v?g.accent+"18":"transparent",fontWeight:v||w?500:400},draggable:!0,onDragStart:f=>m(f,{type:"element",element:y,id:y.id,name:y.name,children:[]}),onMouseEnter:f=>{!v&&!w&&(f.currentTarget.style.background="#F0F0ED")},onMouseLeave:f=>{f.currentTarget.style.background=w?"#FFF3CD":v?g.accent+"18":"transparent"},onClick:f=>{f.metaKey||f.ctrlKey||f.shiftKey?(f.preventDefault(),a(y.id)):i(y.id)},onContextMenu:f=>p(f,"element",y.id),children:[t.jsx("input",{type:"checkbox",checked:w,onChange:f=>{f.stopPropagation(),a(y.id)},onClick:f=>f.stopPropagation(),className:"flex-shrink-0",style:{width:"12px",height:"12px",cursor:"pointer",opacity:w?1:0,transition:"opacity 120ms",accentColor:"#2DD4A8"},onMouseEnter:f=>{f.currentTarget.style.opacity="1"},onMouseLeave:f=>{f.currentTarget.style.opacity=w?"1":"0"}}),t.jsx(Rt,{color:b?"#F59E0B":N}),t.jsxs("span",{className:"truncate flex-1",style:{color:v?g.accentDark:g.primary,fontSize:C.explorer.item},children:[y.shortId&&t.jsxs("span",{style:{color:g.muted,fontWeight:500,marginRight:"4px"},children:["[",y.shortId,"]"]}),y.name]}),b&&t.jsx("span",{title:`Kind "${y.kind}" is not defined in the ontology`,style:{color:"#F59E0B",fontSize:"12px",flexShrink:0},children:"⚠"}),_>0&&t.jsx("span",{className:"px-1 py-0.5 rounded-full",style:{background:"#FEF2F2",color:"#DC2626",fontSize:C.explorer.count,fontWeight:600,minWidth:"16px",textAlign:"center"},children:_})]},y.id)}})})}const mn=Object.fromEntries(ds.map((e,r)=>[e,r]));function ji(e,r,n=[]){const s=new Map;for(const o of e)if(r.has(o.name))for(const i of o.layers)if(!s.has(i.id))s.set(i.id,{id:i.id,label:i.label,color:i.color??ie[i.id]??"#6B7280",kinds:i.kinds.map(l=>l.name)});else{const l=s.get(i.id);for(const a of i.kinds)l.kinds.includes(a.name)||l.kinds.push(a.name)}for(const o of n)s.has(o)||s.set(o,{id:o,label:At[o]??o.charAt(0).toUpperCase()+o.slice(1),color:ie[o]??"#6B7280",kinds:[]});return[...s.values()].sort((o,i)=>{const l=mn[o.id]??999,a=mn[i.id]??999;return l!==a?l-a:o.label.localeCompare(i.label)})}function Di(e,r){const n={};for(const s of e)if(r.has(s.name))for(const o of s.layers)for(const i of o.kinds)n[i.name]=o.id;return n}function Ai(e,r){const n={};for(const s of e)if(r.has(s.name))for(const o of s.layers)for(const i of o.kinds)n[i.name]=i.group;return n}function Fi(e){return e.split(/[_-]/).map(r=>r.charAt(0).toUpperCase()+r.slice(1)).join(" ")}function Ri(e,r,n,s){const o=r.toLowerCase(),i=new Set(["views","viewpoints","methodology","manifest"]),l=Di(n,s),a=Ai(n,s),d=new Set;for(const k of e)fs.has(k.kind)&&!l[k.kind]&&d.add(k.layer);const c=ji(n,s,d).filter(k=>!i.has(k.id)),p=new Set(c.map(k=>k.id)),m=(k,y)=>{const v=new Map;for(const[w,_]of k.entries()){const N=a[w]??"";v.has(N)||v.set(N,new Map),v.get(N).set(w,Ci(_))}return[...v.entries()].sort((w,_)=>w[0].localeCompare(_[0])).map(([w,_])=>({id:w,label:w?Fi(w):"",color:w?ie[w]??y:y,kinds:_}))},x=[];for(const k of c){const y=new Map;for(const v of e)(l[v.kind]??v.layer)===k.id&&(o&&!v.name.toLowerCase().includes(o)&&!v.kind.toLowerCase().includes(o)||(y.has(v.kind)||y.set(v.kind,[]),y.get(v.kind).push(v)));y.size>0&&x.push({group:k,subGroups:m(y,k.color)})}const b=new Map;for(const k of e){const y=l[k.kind]??k.layer;p.has(y)||i.has(y)||o&&!k.name.toLowerCase().includes(o)&&!k.kind.toLowerCase().includes(o)||(b.has(k.kind)||b.set(k.kind,[]),b.get(k.kind).push(k))}if(b.size>0){const k="#F59E0B";x.push({group:{id:"undefined",label:"Undefined — Not in Ontology",color:k,kinds:[]},subGroups:m(b,k)})}return x}function fn({searchTerm:e}){const r=S(I=>I.model),n=S(I=>I.selectedElementId),s=S(I=>I.selectElement),o=S(I=>I.setActiveView),i=S(I=>I.selectedElementIds),l=S(I=>I.toggleElementSelection),a=S(I=>I.selectAllElements),d=S(I=>I.clearElementSelection),c=S(I=>I.updateElementFolder),p=S(I=>I.moveFolder),m=S(I=>I.validation),x=S(I=>I.availableOntologies),b=S(I=>I.selectedOntologies),k=S(I=>I.setExplorerTab),y=S(I=>I.setActiveMode),v=S(I=>I.setSelectedOntologyKind),w=u.useCallback(I=>{s(I),o({type:"element-detail",elementId:I})},[s,o]),[_,N]=u.useState(new Set),[f,D]=u.useState(null),[E,R]=u.useState(null),T=u.useCallback((I,W)=>{W==null||W.stopPropagation(),N(G=>{const L=new Set(G);return L.has(I)?L.delete(I):L.add(I),L})},[]),O=u.useCallback((I,W,G,L)=>{I.preventDefault(),D({x:I.clientX,y:I.clientY,type:W,elementId:W==="element"?G:void 0,folderId:W==="folder"?G.replace("f:",""):void 0,kind:L||(W==="kind"?G.replace("k:","").split(":").pop():void 0)})},[]),j=u.useMemo(()=>r?Ri(Object.values(r.elements),e,x,b):[],[r,e,x,b]),B=u.useCallback((I,W,G)=>{var L;R({id:W.id,kind:G}),I.dataTransfer.setData("application/memo-node",JSON.stringify({id:W.id,type:W.type,kind:G,name:W.name,elementId:(L=W.element)==null?void 0:L.id,folderPath:W.type==="folder"?W.id.replace("f:",""):void 0})),I.dataTransfer.effectAllowed="move"},[]),H=u.useCallback((I,W)=>{(E==null?void 0:E.kind)===W&&(I.preventDefault(),I.dataTransfer.dropEffect="move")},[E]),U=u.useCallback((I,W,G)=>{I.preventDefault(),R(null);try{const L=JSON.parse(I.dataTransfer.getData("application/memo-node"));if(L.kind!==G)return;if(L.type==="element")c(L.elementId,W);else if(L.type==="folder"){if(W===L.folderPath||W.startsWith(L.folderPath+"/"))return;const F=L.folderPath.includes("/")?L.folderPath.slice(L.folderPath.lastIndexOf("/")+1):L.folderPath,q=W?W+"/"+F:F;p(L.kind,L.folderPath,q)}}catch(L){console.error("Drop error:",L)}},[c,p]),X=u.useMemo(()=>{const I=new Map;if(m)for(const W of m.violations)I.set(W.elementId,(I.get(W.elementId)||0)+1);return I},[m]),$=u.useMemo(()=>{const I=[],W=G=>{for(const L of G)L.type==="element"&&L.element?I.push(L.element.id):W(L.children)};for(const{subGroups:G}of j)for(const L of G)for(const F of L.kinds.values())W(F);return I},[j]),ae=i.size;return t.jsxs("div",{className:"flex-1 flex flex-col overflow-hidden",children:[ae>0&&t.jsxs("div",{className:"flex items-center gap-2 px-3 py-1.5 flex-shrink-0",style:{background:"#FFFBEB",borderBottom:"1px solid #FDE68A",fontSize:"12px"},children:[t.jsxs("span",{style:{color:"#92400E",fontWeight:600},children:[ae," selected"]}),t.jsx("span",{style:{color:"#B45309"},children:"— Cmd/Ctrl+click to multi-select"}),t.jsx("button",{onClick:d,className:"ml-auto px-2 py-0.5 rounded",style:{color:"#92400E",background:"#FDE68A",fontSize:"12px",fontWeight:500},children:"Clear"})]}),e&&$.length>0&&t.jsxs("div",{className:"flex items-center gap-2 px-3 py-1",style:{background:"#F0F9FF",borderBottom:"1px solid #BAE6FD",fontSize:"12px"},children:[t.jsxs("span",{style:{color:"#0369A1"},children:[$.length," matching"]}),t.jsx("button",{onClick:()=>a($),className:"ml-auto px-2 py-0.5 rounded",style:{color:"#0369A1",background:"#BAE6FD",fontSize:"12px",fontWeight:500},children:"Select All"})]}),t.jsxs("div",{className:"flex-1 overflow-y-auto py-1",style:{fontSize:C.explorer.item},children:[j.map(({group:I,subGroups:W})=>{const G=`g:${I.id}`,L=_.has(G),F=I.id==="undefined",q=h=>h.reduce((A,P)=>A+(P.type==="element"?1:q(P.children)),0),K=h=>Array.from(h.kinds.values()).reduce((A,P)=>A+q(P),0),ne=W.reduce((h,A)=>h+K(A),0);return t.jsxs("div",{className:"mb-0.5",children:[t.jsxs("div",{className:"flex items-center gap-1.5 px-2 py-1.5 cursor-pointer select-none",style:{margin:"0 4px",borderRadius:"4px",...F?{background:"#FFF3CD"}:{}},onMouseEnter:h=>h.currentTarget.style.background=F?"#FDE68A":"#F0F0ED",onMouseLeave:h=>h.currentTarget.style.background=F?"#FFF3CD":"transparent",onClick:()=>T(G),onContextMenu:h=>O(h,"group",G),children:[t.jsx(fe,{expanded:L,size:14,color:I.color}),F?t.jsx("span",{style:{fontSize:"14px",lineHeight:1,flexShrink:0},children:"⚠"}):t.jsx(De,{open:L,color:I.color}),t.jsx("span",{className:"font-semibold flex-1 truncate",style:{color:F?"#92400E":g.primary,fontSize:C.explorer.group},children:I.label}),t.jsx("span",{className:"px-1.5 py-0.5 rounded-full",style:{background:I.color+"25",color:I.color,fontSize:C.explorer.count,fontWeight:600,minWidth:"20px",textAlign:"center"},children:ne})]}),(()=>{const h=(A,P,Y)=>{const re=`k:${I.id}:${Y?Y+":":""}${A}`,Z=_.has(re),z=V=>{var ee;for(const le of V){if(le.type==="element")return(ee=le.element)==null?void 0:ee.layer;const pe=z(le.children);if(pe)return pe}},se=z(P),xe=F?"#F59E0B":se&&ie[se]||I.color,ue=V=>V.flatMap(ee=>ee.type==="element"&&ee.element?[ee.element.id]:ue(ee.children)),be=ue(P);return t.jsxs("div",{style:{marginLeft:"16px"},onDragOver:V=>H(V,A),onDrop:V=>U(V,"",A),children:[t.jsxs("div",{className:"flex items-center gap-1.5 px-2 py-1 cursor-pointer select-none",style:{borderRadius:"4px",margin:"0 4px"},onMouseEnter:V=>V.currentTarget.style.background="#F0F0ED",onMouseLeave:V=>V.currentTarget.style.background="transparent",onClick:()=>T(re),onContextMenu:V=>O(V,"kind",re,A),children:[t.jsx(fe,{expanded:Z,size:12,color:g.muted}),t.jsx(De,{open:Z,color:xe}),t.jsxs("span",{className:"font-medium flex-1 truncate",style:{color:F?"#B45309":g.secondary,fontSize:C.explorer.kind},children:[A,F&&t.jsx("span",{style:{color:"#F59E0B",marginLeft:"4px"},children:"·"})]}),t.jsx("button",{onClick:V=>{V.stopPropagation(),a(be)},title:"Select all in this category",className:"px-1 rounded",style:{color:g.faint,fontSize:"10px",opacity:.6},onMouseEnter:V=>V.currentTarget.style.opacity="1",onMouseLeave:V=>V.currentTarget.style.opacity="0.6",children:"☑"}),!F&&t.jsx("button",{onClick:V=>{V.stopPropagation();for(const ee of x)for(const le of ee.layers)if(le.kinds.some(pe=>pe.name===A)){v(A),k("ontologies"),y("ontology"),o({type:"ontology-detail",packageName:ee.name,layerId:le.id});return}},title:"View kind in Ontology",className:"px-1 rounded",style:{color:g.faint,fontSize:"10px",opacity:.6},onMouseEnter:V=>V.currentTarget.style.opacity="1",onMouseLeave:V=>V.currentTarget.style.opacity="0.6",children:"⬡"})]}),Z&&t.jsx(Zn,{nodes:P,level:0,expanded:_,toggleExpand:T,selectedElementId:n,selectElement:w,selectedElementIds:i,toggleElementSelection:l,violationCounts:X,baseColor:xe,onContextMenu:(V,ee,le)=>O(V,ee,le,A),onDragStart:(V,ee)=>B(V,ee,A),onDrop:(V,ee)=>U(V,ee,A),isUndefined:F})]},A)};return L?W.map(A=>{if(!A.id)return t.jsx("div",{children:Array.from(A.kinds.entries()).map(([Z,z])=>h(Z,z,""))},"__root");const P=`sg:${I.id}:${A.id}`,Y=_.has(P),re=K(A);return t.jsxs("div",{style:{marginLeft:"16px"},children:[t.jsxs("div",{className:"flex items-center gap-1.5 px-2 py-1 cursor-pointer select-none",style:{borderRadius:"4px",margin:"0 4px"},onMouseEnter:Z=>Z.currentTarget.style.background="#F0F0ED",onMouseLeave:Z=>Z.currentTarget.style.background="transparent",onClick:()=>T(P),children:[t.jsx(fe,{expanded:Y,size:13,color:A.color}),t.jsx(De,{open:Y,color:A.color}),t.jsx("span",{className:"font-semibold flex-1 truncate",style:{color:g.primary,fontSize:C.explorer.kind},children:A.label}),t.jsx("span",{className:"px-1.5 py-0.5 rounded-full",style:{background:A.color+"25",color:A.color,fontSize:C.explorer.count,fontWeight:600,minWidth:"20px",textAlign:"center"},children:re})]}),Y&&Array.from(A.kinds.entries()).map(([Z,z])=>h(Z,z,A.id))]},A.id)}):null})()]},I.id)}),f&&t.jsx(Ei,{menu:f,onClose:()=>D(null)})]})]})}function _i({diagram:e}){const r=["afd","ofd","ffd"].includes(e.diagramType.toLowerCase())?gs(e):e.diagramType,n=Ae[r];return n?t.jsx("span",{className:"px-1.5 py-0.5 rounded font-semibold",style:{background:n.color+"20",color:n.color,fontSize:C.badge},title:n.fullName,children:n.code}):null}function Ti({viewpointId:e,onClose:r}){const n=S(c=>c.createDiagram),[s,o]=u.useState("Untitled"),[i,l]=u.useState("bdd"),a=u.useRef(null);u.useEffect(()=>{const c=p=>{a.current&&!a.current.contains(p.target)&&r()};return document.addEventListener("mousedown",c),()=>document.removeEventListener("mousedown",c)},[r]);const d=()=>{s.trim()&&(n({name:s.trim(),diagramType:i,viewpointId:e}),r())};return t.jsxs("div",{ref:a,className:"fixed z-50 rounded-lg overflow-hidden py-3 px-4",style:{top:"50%",left:"50%",transform:"translate(-50%, -50%)",background:"#FFFFFF",border:"1px solid #E5E7EB",boxShadow:"0 8px 32px rgba(0,0,0,0.16)",minWidth:"300px"},children:[t.jsx("div",{className:"font-semibold mb-3",style:{color:g.primary,fontSize:"13px"},children:"New Diagram"}),t.jsx("label",{className:"block mb-1",style:{fontSize:C.xs,color:g.secondary},children:"Name"}),t.jsx("input",{autoFocus:!0,value:s,onChange:c=>o(c.target.value),onKeyDown:c=>{c.key==="Enter"&&d(),c.key==="Escape"&&r()},className:"w-full px-3 py-2 rounded-lg mb-3 focus:outline-none",style:{background:"#F9F9F8",border:"1px solid #E5E7EB",color:g.primary,fontSize:"13px"}}),t.jsx("label",{className:"block mb-1",style:{fontSize:C.xs,color:g.secondary},children:"Type"}),t.jsx("select",{value:i,onChange:c=>l(c.target.value),className:"w-full px-3 py-2 rounded-lg mb-4 focus:outline-none",style:{background:"#F9F9F8",border:"1px solid #E5E7EB",color:g.primary,fontSize:"13px"},children:Object.entries(Ae).map(([c,p])=>t.jsxs("option",{value:c,children:[p.fullName," (",p.code,")"]},c))}),t.jsxs("div",{className:"flex gap-2 justify-end",children:[t.jsx("button",{onClick:r,className:"px-3 py-1.5 rounded",style:{fontSize:"12px",color:g.secondary,background:"#F0F0ED"},children:"Cancel"}),t.jsx("button",{onClick:d,className:"px-3 py-1.5 rounded font-medium",style:{fontSize:"12px",color:"#FFFFFF",background:g.accent},children:"Create"})]})]})}function yt({label:e,count:r,defaultOpen:n,children:s}){const[o,i]=u.useState(n);return t.jsxs("div",{children:[t.jsxs("div",{className:"flex items-center gap-1 px-2 py-1 cursor-pointer select-none",style:{borderRadius:"4px",margin:"0 4px"},onMouseEnter:l=>l.currentTarget.style.background="#F0F0ED",onMouseLeave:l=>l.currentTarget.style.background="transparent",onClick:()=>i(l=>!l),children:[t.jsx(fe,{expanded:o,size:12,color:g.faint}),t.jsx("span",{style:{color:g.faint,fontSize:C.xs},children:e}),t.jsx("span",{className:"ml-1 px-1 rounded",style:{background:"#F0F0ED",color:g.faint,fontSize:C.badge,fontWeight:600},children:r})]}),o&&s]})}function Ii({searchTerm:e}){const r=S(E=>E.model),n=S(E=>E.methodology),s=S(E=>E.activeView),o=S(E=>E.setActiveView),i=S(E=>E.selectViewpoint),l=S(E=>E.deleteDiagram),[a,d]=u.useState(new Set(["__model"])),[c,p]=u.useState(null),m=E=>{d(R=>{const T=new Set(R);return T.has(E)?T.delete(E):T.add(E),T})},x=u.useMemo(()=>(r==null?void 0:r.viewpoints)??[],[r==null?void 0:r.viewpoints]),b=u.useMemo(()=>{if(!n)return[];const E=[];for(const R of n.folders){const T=R.parts.Viewpoint??[];for(const O of T){const j=O.attributes.id,B=O.attributes.name,H=O.attributes.title,U=O.attributes.shortDescription??O.attributes.longDescription;E.push({id:typeof j=="string"?j:O.partName,name:typeof B=="string"?B:O.partName,title:typeof H=="string"?H:typeof B=="string"?B:O.partName,description:typeof U=="string"?U:"",folder:R.name})}}return E},[n]),k=E=>{if(!e)return E;const R=e.toLowerCase();return E.filter(T=>T.name.toLowerCase().includes(R)||T.diagramType.toLowerCase().includes(R))},y=s.type==="diagram"?s.diagramId:null,v=on(r,"__model"),w=E=>E.id.startsWith("diag-sample-"),_=k(v.filter(E=>E.auto&&w(E))),N=k(v.filter(E=>E.auto&&!w(E))),f=k(v.filter(E=>!E.auto)),D=(E,R)=>E.map(T=>t.jsx(Ni,{diag:T,isSelected:y===T.id,onSelect:()=>{o({type:"diagram",diagramId:T.id}),i(R==="__model"?null:R)},onDelete:T.auto?void 0:()=>l(T.id)},T.id));return t.jsxs("div",{className:"flex-1 overflow-y-auto py-1",style:{fontSize:C.explorer.item},children:[b.length>0&&t.jsxs("div",{style:{marginBottom:"6px",borderBottom:`1px solid ${g.border}`,paddingBottom:"6px"},children:[t.jsx("div",{className:"px-3 py-1",style:{fontSize:"10px",fontWeight:700,textTransform:"uppercase",letterSpacing:"0.08em",color:g.muted},children:"Methodology Viewpoints"}),b.map(E=>{const R=a.has(`mvp::${E.id}`);return t.jsxs("div",{className:"mb-0.5",children:[t.jsxs("div",{className:"flex items-center gap-1.5 px-2 py-1.5 cursor-pointer select-none",style:{borderRadius:"4px",margin:"0 4px"},onMouseEnter:T=>T.currentTarget.style.background="#F0F0ED",onMouseLeave:T=>T.currentTarget.style.background="transparent",onClick:()=>m(`mvp::${E.id}`),title:E.description,children:[t.jsx(fe,{expanded:R,size:14,color:g.accent}),t.jsx(De,{open:R,color:g.accent}),t.jsx("span",{className:"font-semibold flex-1 truncate",style:{color:g.primary,fontSize:C.explorer.group},children:E.title}),t.jsx("span",{style:{color:g.faint,fontSize:C.badge,fontFamily:"monospace"},children:E.id})]}),R&&t.jsxs("div",{style:{marginLeft:"24px",padding:"4px 0",fontSize:C.xs,color:g.muted,lineHeight:1.5},children:[E.description||t.jsx("em",{children:"No description."}),t.jsxs("div",{style:{marginTop:"4px",fontSize:"10px",color:g.faint},children:["from ",t.jsx("code",{style:{fontFamily:"monospace"},children:E.folder})," · views & diagrams pending (Phase D2 stub)"]})]})]},`mvp::${E.id}`)})]}),t.jsxs("div",{className:"mb-0.5",children:[t.jsxs("div",{className:"flex items-center gap-1.5 px-2 py-1.5 cursor-pointer select-none",style:{borderRadius:"4px",margin:"0 4px"},onMouseEnter:E=>E.currentTarget.style.background="#F0F0ED",onMouseLeave:E=>E.currentTarget.style.background="transparent",onClick:()=>{i(null),m("__model")},children:[t.jsx(fe,{expanded:a.has("__model"),size:14,color:g.accent}),t.jsx(De,{open:a.has("__model"),color:g.accent}),t.jsx("span",{className:"font-semibold flex-1",style:{color:g.primary,fontSize:C.explorer.group},children:"Model Viewpoint"}),t.jsx("span",{style:{color:g.faint,fontSize:C.explorer.count},children:v.length})]}),a.has("__model")&&t.jsxs("div",{style:{marginLeft:"16px"},children:[_.length>0&&t.jsx(yt,{label:"Samples",count:_.length,defaultOpen:!1,children:t.jsx("div",{style:{marginLeft:"12px"},children:D(_,"__model")})}),N.length>0&&t.jsx(yt,{label:"Generated",count:N.length,defaultOpen:!1,children:t.jsx("div",{style:{marginLeft:"12px"},children:D(N,"__model")})}),D(f,"__model"),t.jsxs("button",{className:"flex items-center gap-1 px-2 py-1 w-full text-left",style:{borderRadius:"4px",margin:"2px 4px",color:g.accent,fontSize:C.xs,background:"transparent"},onMouseEnter:E=>E.currentTarget.style.background=g.accent+"12",onMouseLeave:E=>E.currentTarget.style.background="transparent",onClick:()=>p("__model"),children:[t.jsx("span",{style:{fontSize:"14px",lineHeight:1},children:"+"})," New Diagram"]})]})]}),x.map(E=>{var H;const R=a.has(E.id),T=(H=E.visibleLayers)!=null&&H[0]&&ie[E.visibleLayers[0]]||g.muted,O=on(r,E.id),j=k(O.filter(U=>U.auto)),B=k(O.filter(U=>!U.auto));return t.jsxs("div",{className:"mb-0.5",children:[t.jsxs("div",{className:"flex items-center gap-1.5 px-2 py-1.5 cursor-pointer select-none",style:{borderRadius:"4px",margin:"0 4px"},onMouseEnter:U=>U.currentTarget.style.background="#F0F0ED",onMouseLeave:U=>U.currentTarget.style.background="transparent",onClick:()=>{i(E.id),m(E.id)},children:[t.jsx(fe,{expanded:R,size:14,color:T}),t.jsx(De,{open:R,color:T}),t.jsx("span",{className:"font-semibold flex-1 truncate",style:{color:g.primary,fontSize:C.explorer.group},children:E.label}),t.jsx("span",{style:{color:g.faint,fontSize:C.explorer.count},children:O.length})]}),R&&t.jsxs("div",{style:{marginLeft:"16px"},children:[j.length>0&&t.jsx(yt,{label:"Generated",count:j.length,defaultOpen:!1,children:t.jsx("div",{style:{marginLeft:"12px"},children:D(j,E.id)})}),D(B,E.id),t.jsxs("button",{className:"flex items-center gap-1 px-2 py-1 w-full text-left",style:{borderRadius:"4px",margin:"2px 4px",color:g.accent,fontSize:C.xs,background:"transparent"},onMouseEnter:U=>U.currentTarget.style.background=g.accent+"12",onMouseLeave:U=>U.currentTarget.style.background="transparent",onClick:()=>p(E.id),children:[t.jsx("span",{style:{fontSize:"14px",lineHeight:1},children:"+"})," New Diagram"]})]})]},E.id)}),t.jsx("div",{className:"px-3 py-2 mt-2",style:{borderTop:`1px solid ${g.border}`},children:t.jsx("div",{className:"flex flex-wrap items-center gap-1.5",style:{color:g.faint,fontSize:C.xs},children:Object.entries(Ae).map(([E,R])=>t.jsx("span",{className:"px-1.5 py-0.5 rounded",style:{background:R.color+"15",color:R.color,fontSize:C.badge,fontWeight:600},children:R.code},E))})}),c!==null&&t.jsx(Ti,{viewpointId:c,onClose:()=>p(null)})]})}function Ni({diag:e,isSelected:r,onSelect:n,onDelete:s}){var d;const[o,i]=u.useState(!1),l=Ae[e.diagramType],a=((d=e.elementIds)==null?void 0:d.length)??0;return t.jsxs("div",{className:"flex items-center gap-2 px-2 py-1 cursor-pointer group",style:{borderRadius:"4px",margin:"0 4px",background:r?g.accent+"18":o?"#F0F0ED":"transparent",fontSize:C.explorer.item},onMouseEnter:()=>i(!0),onMouseLeave:()=>i(!1),onClick:n,title:[l==null?void 0:l.fullName,e.description].filter(Boolean).join(" — "),children:[t.jsx(_i,{diagram:e}),e.auto&&t.jsx("span",{className:"px-1 py-0.5 rounded",style:{background:"#F0F0ED",color:g.faint,fontSize:C.badge,fontWeight:600},children:"AUTO"}),t.jsx("span",{className:"truncate flex-1",style:{color:r?g.accentDark:g.primary},children:e.name}),a>0&&t.jsx("span",{className:"px-1.5 py-0.5 rounded-full",style:{background:"#F0F0ED",color:g.muted,fontSize:C.explorer.count,fontWeight:600,minWidth:"18px",textAlign:"center"},children:a}),s&&o&&t.jsx("button",{onClick:c=>{c.stopPropagation(),s()},title:"Delete diagram",style:{background:"none",border:"none",cursor:"pointer",color:"#DC2626",fontSize:"12px",padding:"0 2px",lineHeight:1},children:"×"})]})}function Oi(){const e=S(f=>f.setActiveView),r=S(f=>f.activeView),n=S(f=>f.dhfDocuments),s=S(f=>f.addDhfDocument),o=S(f=>f.removeDhfDocument),i=S(f=>f.dhfSettings),l=S(f=>f.methodology),a=u.useMemo(()=>{if(!l)return[];const f=[];for(const D of l.folders){const E=D.parts.DhfDocumentBinding??[];for(const R of E){const T=R.attributes,O=T.id,j=T.documentTitle,B=T.groupLabel,H=T.templateId,U=T.viewKind,X=T.regulatoryReference,$=T.required;f.push({id:typeof O=="string"?O:R.partName,partName:R.partName,documentTitle:typeof j=="string"?j:R.partName,groupLabel:typeof B=="string"?B:"",templateId:typeof H=="string"?H:"",viewKind:typeof U=="string"?U:"",regulatoryReference:typeof X=="string"?X:"",required:typeof $=="boolean"?$:!1,folder:D.name})}}return f},[l]),[d,c]=u.useState(new Set(Ee.map(f=>f.id))),[p,m]=u.useState(null),[x,b]=u.useState(null),k=r.type==="dhf-document"?r.docId:null,y=u.useMemo(()=>{const f=new Set(Ee.map(D=>D.label));return[...new Set(n.map(D=>D.group))].filter(D=>D&&!f.has(D)).sort()},[n]);function v(f){c(D=>{const E=new Set(D);return E.has(f)?E.delete(f):E.add(f),E})}function w(f,D){f.preventDefault(),f.stopPropagation(),b({x:f.clientX,y:f.clientY,groupId:D})}function _(f){const D=i.documentNumberingPrefix||"DOC",E=[];for(const R of f){const T=`${D}-${R.prefix}-`,O=[...n,...E].filter($=>$.id.startsWith(T)),j=`${T}${String(O.length+1).padStart(3,"0")}`,B=$=>$.replace(/^---[\s\S]*?---\n?/,""),H=R.content!==null?B(R.content):(()=>{const $=xi(R.templateId);return $?B($):`# ${R.title}
3254
-
3255
- _[TODO: Add content]_
3256
- `})(),U=`---
3257
- id: ${j}
3258
- title: ${R.title}
3259
- template: ${R.templateId}
3260
- ---
3261
-
3262
- ${H}`,X={id:j,title:R.title,group:R.groupLabel,templateId:R.templateId,content:U,createdAt:Date.now(),authors:"",approvers:""};s(X),E.push(X),E.length===1&&e({type:"dhf-document",docId:X.id})}m(null)}u.useEffect(()=>{if(!x)return;function f(){b(null)}return window.addEventListener("click",f),()=>window.removeEventListener("click",f)},[x]);function N(f){const D=n.find(T=>T.templateId===f.templateId);if(D){e({type:"dhf-document",docId:D.id});return}const E=Ee.find(T=>T.templates.some(O=>O.id===f.templateId)),R=E==null?void 0:E.templates.find(T=>T.id===f.templateId);E&&R&&_([{title:R.title,prefix:R.prefix,templateId:R.id,groupLabel:E.label,content:null}])}return t.jsxs(t.Fragment,{children:[t.jsxs("div",{className:"flex-1 overflow-y-auto py-1",children:[t.jsx("div",{style:{padding:"4px 10px 8px"},children:t.jsxs("button",{onClick:()=>m({}),style:{width:"100%",padding:"7px 10px",borderRadius:"6px",border:"none",background:g.accentDark,fontSize:C.explorer.item,fontWeight:600,color:"#fff",cursor:"pointer",display:"flex",alignItems:"center",justifyContent:"center",gap:"6px"},onMouseEnter:f=>{f.currentTarget.style.background="#254B60"},onMouseLeave:f=>{f.currentTarget.style.background=g.accentDark},children:[t.jsx("span",{style:{fontSize:"14px",lineHeight:1},children:"+"})," New Document"]})}),a.length>0&&t.jsxs("div",{style:{marginBottom:"6px",borderBottom:`1px solid ${g.border}`,paddingBottom:"6px"},children:[t.jsx("div",{className:"px-3 py-1",style:{fontSize:"10px",fontWeight:700,textTransform:"uppercase",letterSpacing:"0.08em",color:g.muted},children:"Methodology DHF"}),a.map(f=>{const D=n.find(T=>T.templateId===f.templateId),E=D!=null&&k===D.id,R=Ee.some(T=>T.templates.some(O=>O.id===f.templateId));return t.jsxs("div",{onClick:()=>N(f),style:{display:"flex",alignItems:"center",gap:"6px",padding:"5px 12px",cursor:R?"pointer":"default",background:E?"#EEF2FF":"transparent",borderLeft:E?"2px solid #6366F1":"2px solid transparent"},title:`${f.regulatoryReference||""} · template: ${f.templateId}${R?"":" (unknown — no built-in template)"}`,onMouseEnter:T=>{!E&&R&&(T.currentTarget.style.background=g.surfaceAlt)},onMouseLeave:T=>{T.currentTarget.style.background=E?"#EEF2FF":"transparent"},children:[t.jsx("span",{style:{fontSize:"9px",fontFamily:"monospace",color:f.required?"#DC2626":g.faint,fontWeight:700},children:f.id}),t.jsx("span",{style:{flex:1,fontSize:C.explorer.element,color:g.primary,overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap"},children:f.documentTitle}),D?t.jsx("span",{style:{fontSize:"9px",color:"#059669",fontWeight:700},children:"✓"}):t.jsx("span",{style:{fontSize:"9px",color:g.faint},children:"+"})]},`mdhf::${f.id}`)})]}),Ee.filter(f=>n.some(D=>D.group===f.label)).map(f=>{const D=d.has(f.id),E=n.filter(R=>R.group===f.label);return t.jsxs("div",{children:[t.jsxs("button",{onClick:()=>v(f.id),onContextMenu:R=>w(R,f.id),className:"w-full flex items-center gap-2 px-3 py-2 text-left",style:{fontSize:C.xs,fontWeight:600,color:g.secondary,borderRadius:"4px"},onMouseEnter:R=>R.currentTarget.style.background=g.surfaceAlt,onMouseLeave:R=>R.currentTarget.style.background="transparent",title:"Right-click to add documents",children:[t.jsx("span",{style:{display:"inline-block",width:"7px",height:"7px",borderRadius:"50%",background:f.color,flexShrink:0}}),t.jsx("span",{className:"flex-1 uppercase tracking-wide",style:{fontSize:"10px"},children:f.label}),E.length>0&&t.jsx("span",{style:{fontSize:"10px",color:f.color,fontWeight:700},children:E.length}),t.jsx(fe,{expanded:D,size:11})]}),D&&E.map(R=>{const T=k===R.id;return t.jsxs("div",{style:{display:"flex",alignItems:"center",paddingLeft:"28px",paddingRight:"4px",background:T?`${f.color}18`:"transparent",borderLeft:T?`2px solid ${f.color}`:"2px solid transparent",cursor:"pointer"},onMouseEnter:O=>{T||(O.currentTarget.style.background=g.surfaceAlt)},onMouseLeave:O=>{O.currentTarget.style.background=T?`${f.color}18`:"transparent"},children:[t.jsxs("button",{onClick:()=>e({type:"dhf-document",docId:R.id}),style:{flex:1,display:"flex",alignItems:"center",gap:"6px",background:"none",border:"none",padding:"5px 0",fontSize:C.explorer.element,color:T?f.color:g.primary,fontWeight:T?600:400,cursor:"pointer",textAlign:"left"},children:[t.jsx(Rt,{color:f.color}),t.jsx("span",{style:{flex:1,overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap"},children:R.id})]}),t.jsx("button",{onClick:O=>{O.stopPropagation(),o(R.id)},title:"Remove document",style:{background:"none",border:"none",cursor:"pointer",color:"#9CA3AF",padding:"2px 4px",borderRadius:"3px",fontSize:"12px",opacity:0,transition:"opacity 0.1s"},onMouseEnter:O=>{O.currentTarget.style.opacity="1",O.currentTarget.style.color="#ef4444"},onMouseLeave:O=>{O.currentTarget.style.opacity="0",O.currentTarget.style.color="#9CA3AF"},children:"×"})]},R.id)})]},f.id)}),y.map(f=>{const D=`custom:${f}`,E=d.has(D),R=bi(f),T=n.filter(O=>O.group===f);return t.jsxs("div",{children:[t.jsxs("button",{onClick:()=>v(D),className:"w-full flex items-center gap-2 px-3 py-2 text-left",style:{fontSize:C.xs,fontWeight:600,color:g.secondary,borderRadius:"4px"},onMouseEnter:O=>O.currentTarget.style.background=g.surfaceAlt,onMouseLeave:O=>O.currentTarget.style.background="transparent",children:[t.jsx("span",{style:{display:"inline-block",width:"7px",height:"7px",borderRadius:"50%",background:R,flexShrink:0}}),t.jsx("span",{className:"flex-1 uppercase tracking-wide",style:{fontSize:"10px"},children:f}),t.jsx("span",{style:{fontSize:"10px",color:R,fontWeight:700},children:T.length}),t.jsx(fe,{expanded:E,size:11})]}),E&&T.map(O=>{const j=k===O.id;return t.jsxs("div",{style:{display:"flex",alignItems:"center",paddingLeft:"28px",paddingRight:"4px",background:j?`${R}18`:"transparent",borderLeft:j?`2px solid ${R}`:"2px solid transparent",cursor:"pointer"},onMouseEnter:B=>{j||(B.currentTarget.style.background=g.surfaceAlt)},onMouseLeave:B=>{B.currentTarget.style.background=j?`${R}18`:"transparent"},children:[t.jsxs("button",{onClick:()=>e({type:"dhf-document",docId:O.id}),style:{flex:1,display:"flex",alignItems:"center",gap:"6px",background:"none",border:"none",padding:"5px 0",fontSize:C.explorer.element,color:j?R:g.primary,fontWeight:j?600:400,cursor:"pointer",textAlign:"left"},children:[t.jsx(Rt,{color:R}),t.jsx("span",{style:{flex:1,overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap"},children:O.id})]}),t.jsx("button",{onClick:B=>{B.stopPropagation(),o(O.id)},title:"Remove document",style:{background:"none",border:"none",cursor:"pointer",color:"#9CA3AF",padding:"2px 4px",borderRadius:"3px",fontSize:"12px",opacity:0,transition:"opacity 0.1s"},onMouseEnter:B=>{B.currentTarget.style.opacity="1",B.currentTarget.style.color="#ef4444"},onMouseLeave:B=>{B.currentTarget.style.opacity="0",B.currentTarget.style.color="#9CA3AF"},children:"×"})]},O.id)})]},D)}),n.length===0&&t.jsxs("div",{style:{padding:"16px 14px",fontSize:"11px",color:"#9CA3AF",lineHeight:"1.6"},children:["No documents yet. Use ",t.jsx("strong",{children:"+ New Document"})," to create one from a meMO template, a blank page, or a markdown file in this repository."]}),t.jsxs("div",{style:{margin:"8px 10px 6px",padding:"8px",background:"#F0FDF9",borderRadius:"8px",border:"1px solid #A7F3D0"},children:[t.jsxs("div",{style:{fontSize:"10px",fontWeight:700,color:"#065F46",textTransform:"uppercase",letterSpacing:"0.06em",marginBottom:"6px",display:"flex",alignItems:"center",gap:"4px"},children:[t.jsx("span",{children:"✦"})," AI Tools"]}),t.jsxs("div",{style:{display:"flex",flexDirection:"column",gap:"3px"},children:[t.jsx(hn,{label:"Model Q&A",description:"Ask questions about your model",active:r.type==="ask",onClick:()=>e({type:"ask"})}),t.jsx(hn,{label:"SysML Generator",description:"Natural language → SysML v2",active:r.type==="sysml-generator",onClick:()=>e({type:"sysml-generator"})})]})]})]}),x&&t.jsx("div",{style:{position:"fixed",zIndex:9998,left:x.x,top:x.y,background:"#fff",borderRadius:"8px",border:"1px solid #E5E7EB",boxShadow:"0 8px 24px rgba(0,0,0,0.12)",padding:"4px 0",minWidth:"160px"},onClick:f=>f.stopPropagation(),children:t.jsx("button",{onClick:()=>{m({initialGroupId:x.groupId}),b(null)},style:{display:"block",width:"100%",padding:"8px 14px",background:"none",border:"none",textAlign:"left",fontSize:"13px",color:"#1B3A4B",cursor:"pointer"},onMouseEnter:f=>f.currentTarget.style.background="#F3F4F6",onMouseLeave:f=>f.currentTarget.style.background="none",children:"Add document…"})}),p&&t.jsx(Si,{initialGroupId:p.initialGroupId,existingDocs:n,numberingPrefix:i.documentNumberingPrefix||"DOC",onCreate:_,onClose:()=>m(null)})]})}function hn({label:e,description:r,active:n,onClick:s}){return t.jsxs("button",{onClick:s,style:{display:"flex",flexDirection:"column",width:"100%",padding:"5px 8px",borderRadius:"5px",border:"none",textAlign:"left",cursor:"pointer",background:n?"#D1FAE5":"rgba(255,255,255,0.7)",transition:"background 0.1s"},onMouseEnter:o=>{n||(o.currentTarget.style.background="rgba(255,255,255,0.95)")},onMouseLeave:o=>{n||(o.currentTarget.style.background="rgba(255,255,255,0.7)")},children:[t.jsx("span",{style:{fontSize:"12px",fontWeight:600,color:"#065F46"},children:e}),t.jsx("span",{style:{fontSize:"10px",color:"#6B7280",marginTop:"1px"},children:r})]})}function Mi(){const e=S(l=>l.sidebarCollapsed);S(l=>l.explorerTab);const r=S(l=>l.setExplorerTab),n=S(l=>l.searchTerm),s=S(l=>l.setSearchTerm);S(l=>l.model);const o=S(l=>l.activeMode),i=S(l=>l.activeView);return u.useEffect(()=>{(i.type==="ontology"||i.type==="ontology-detail")&&r("ontologies")},[i.type]),e?null:t.jsx("div",{className:"flex flex-col overflow-hidden flex-shrink-0",style:{width:"300px",background:g.surface,borderRight:`1px solid ${g.border}`},children:o==="dashboard"?t.jsx(Cs,{}):o==="dhf"?t.jsx(Oi,{}):o==="diagram"?t.jsxs(t.Fragment,{children:[t.jsx("div",{className:"px-3 py-2",style:{borderBottom:`1px solid ${g.border}`},children:t.jsx("input",{type:"text",placeholder:"Search diagrams...",value:n,onChange:l=>s(l.target.value),className:"w-full px-3 py-2 rounded-lg focus:outline-none",style:{background:g.surfaceAlt,border:`1px solid ${g.border}`,color:g.primary,fontSize:C.explorer.search}})}),t.jsx(Ii,{searchTerm:n})]}):o==="ontology"?t.jsx(Es,{}):o==="scenario"?t.jsxs(t.Fragment,{children:[t.jsx("div",{className:"px-3 py-2",style:{borderBottom:`1px solid ${g.border}`},children:t.jsx("input",{type:"text",placeholder:"Search elements...",value:n,onChange:l=>s(l.target.value),className:"w-full px-3 py-2 rounded-lg focus:outline-none",style:{background:g.surfaceAlt,border:`1px solid ${g.border}`,color:g.primary,fontSize:C.explorer.search}})}),t.jsx(fn,{searchTerm:n})]}):t.jsxs(t.Fragment,{children:[t.jsx("div",{className:"px-3 py-2",style:{borderBottom:`1px solid ${g.border}`},children:t.jsx("input",{type:"text",placeholder:"Search elements...",value:n,onChange:l=>s(l.target.value),className:"w-full px-3 py-2 rounded-lg focus:outline-none",style:{background:g.surfaceAlt,border:`1px solid ${g.border}`,color:g.primary,fontSize:C.explorer.search}})}),t.jsx(fn,{searchTerm:n})]})})}function gn({value:e,onSave:r,multiline:n,forceEdit:s}){const[o,i]=u.useState(!1),[l,a]=u.useState(e);u.useEffect(()=>{a(e)},[e]);const d=u.useCallback(()=>{i(!1),l!==e&&r(l)},[l,e,r]),c=u.useCallback(p=>{p.key==="Enter"&&!n&&d(),p.key==="Escape"&&(a(e),i(!1))},[d,n,e]);return!o&&!s?t.jsx("span",{className:"cursor-pointer rounded px-1 py-0.5 transition-colors",style:{color:"#1a1a1a"},onMouseEnter:p=>p.currentTarget.style.background="#F0F0ED",onMouseLeave:p=>p.currentTarget.style.background="transparent",onClick:()=>{a(e),i(!0)},title:"Click to edit",children:e||t.jsx("span",{style:{color:"#D1D5DB",fontStyle:"italic"},children:"empty"})}):n?t.jsx("textarea",{value:l,onChange:p=>a(p.target.value),onBlur:d,onKeyDown:c,autoFocus:!0,className:"w-full px-2 py-1 text-xs rounded focus:outline-none",style:{border:"1px solid #2DD4A8",background:"#FAFAF8",color:"#1a1a1a",resize:"vertical",minHeight:"48px"}}):t.jsx("input",{value:l,onChange:p=>a(p.target.value),onBlur:d,onKeyDown:c,autoFocus:!0,className:"w-full px-2 py-1 text-xs rounded focus:outline-none",style:{border:"1px solid #2DD4A8",background:"#FAFAF8",color:"#1a1a1a"}})}function oe({title:e,count:r,defaultOpen:n=!0,actions:s,children:o}){const[i,l]=u.useState(n);return t.jsxs("div",{style:{borderBottom:"1px solid #EDEDEA"},children:[t.jsxs("div",{className:"flex items-center gap-2 px-3 py-1.5 cursor-pointer transition-colors",style:{borderRadius:"6px",margin:"2px 4px"},onMouseEnter:a=>a.currentTarget.style.background="#F0F0ED",onMouseLeave:a=>a.currentTarget.style.background="transparent",onClick:()=>l(a=>!a),children:[t.jsx("span",{className:"font-medium flex-1 text-xs",style:{color:"#374151"},children:e}),s&&t.jsx("span",{onClick:a=>a.stopPropagation(),children:s}),typeof r=="number"&&t.jsx("span",{className:"text-xs",style:{color:"#9CA3AF"},children:r}),t.jsx("span",{style:{color:"#D1D5DB"},children:i?"▾":"▸"})]}),i&&t.jsx("div",{className:"px-4 pb-3",children:o})]})}function xt({label:e,kind:r,kindColor:n,onClick:s,arrow:o,typeBadge:i,typeColor:l,selected:a}){return t.jsxs("div",{className:"flex items-center gap-1.5 cursor-pointer transition-colors ml-2",style:{borderRadius:"6px",padding:"4px 8px",background:a?"#2DD4A818":"transparent",color:a?"#1B3A4B":"#374151",fontWeight:a?500:400,fontSize:C.xs},onMouseEnter:d=>{a||(d.currentTarget.style.background="#F0F0ED")},onMouseLeave:d=>{a||(d.currentTarget.style.background="transparent")},onClick:s,children:[o&&t.jsx("span",{style:{color:"#9CA3AF"},children:o}),i&&t.jsx("span",{className:"px-1 py-0.5 rounded",style:{background:(l||"#2563EB")+"18",color:l||"#2563EB",fontSize:C.xs},children:i}),t.jsx("span",{className:"truncate",children:e}),r&&t.jsx("span",{className:"ml-auto flex-shrink-0 px-1 py-0.5 rounded",style:{background:(n||"#666")+"15",color:n||"#666",fontSize:C.badge},children:r})]})}function Pi(){const e=S(l=>l.model),r=S(l=>l.activeView),n=r.type==="diagram"?r.diagramId:null,s=Yn(e,n);if(!s)return null;const o=Ae[s.diagramType],i={borderBottom:"1px solid #EDEDEA"};return t.jsxs(t.Fragment,{children:[t.jsxs("div",{className:"p-4",style:{...i,borderLeft:`3px solid ${(o==null?void 0:o.color)||"#6B7280"}`},children:[t.jsx("div",{className:"text-sm font-semibold truncate",style:{color:"#1a1a1a"},children:s.name}),t.jsxs("div",{className:"flex items-center gap-2 text-xs mt-1.5",children:[o&&t.jsx("span",{className:"px-2 py-0.5 rounded-md font-medium",style:{background:o.color+"18",color:o.color},children:o.code}),t.jsx("span",{style:{color:"#6B7280"},children:(o==null?void 0:o.fullName)||s.diagramType})]}),s.auto&&t.jsx("div",{className:"text-xs mt-1",style:{color:"#6B7280"},children:"Auto-generated"})]}),t.jsxs("div",{className:"flex-1 overflow-y-auto",children:[s.description&&t.jsx(oe,{title:"Description",defaultOpen:!0,children:t.jsx("div",{className:"text-xs leading-relaxed",style:{color:"#374151"},children:s.description})}),t.jsx(oe,{title:"Details",defaultOpen:!0,children:t.jsxs("div",{className:"space-y-1.5",children:[t.jsxs("div",{className:"flex text-xs",children:[t.jsx("span",{className:"min-w-[80px]",style:{color:"#6B7280"},children:"ID"}),t.jsx("span",{className:"truncate font-mono",style:{color:"#1a1a1a",fontSize:C.xs},children:s.id})]}),t.jsxs("div",{className:"flex text-xs",children:[t.jsx("span",{className:"min-w-[80px]",style:{color:"#6B7280"},children:"Viewpoint"}),t.jsx("span",{style:{color:"#1a1a1a"},children:s.viewpointId})]}),t.jsxs("div",{className:"flex text-xs",children:[t.jsx("span",{className:"min-w-[80px]",style:{color:"#6B7280"},children:"Type"}),t.jsx("span",{style:{color:"#1a1a1a"},children:s.diagramType})]})]})}),s.properties&&Object.keys(s.properties).length>0&&t.jsx(oe,{title:"Properties",count:Object.keys(s.properties).length,children:t.jsx("div",{className:"space-y-1.5",children:Object.entries(s.properties).map(([l,a])=>t.jsxs("div",{className:"flex text-xs",children:[t.jsx("span",{className:"min-w-[80px]",style:{color:"#6B7280"},children:l}),t.jsx("span",{className:"truncate",style:{color:"#1a1a1a"},children:a})]},l))})}),s.elementIds&&s.elementIds.length>0&&t.jsx(oe,{title:"Scoped Elements",count:s.elementIds.length,defaultOpen:!1,children:t.jsx("div",{className:"text-xs",style:{color:"#6B7280"},children:s.elementIds.join(", ")})}),s.relationshipTypes&&s.relationshipTypes.length>0&&t.jsx(oe,{title:"Relationship Types",count:s.relationshipTypes.length,children:t.jsx("div",{className:"flex flex-wrap gap-1",children:s.relationshipTypes.map(l=>t.jsx("span",{className:"px-1.5 py-0.5 rounded text-xs",style:{background:"#EFF6FF",color:"#2563EB",fontSize:C.xs},children:l},l))})})]})]})}function zi(){var _,N;const e=S(f=>f.model),r=S(f=>f.selectedElementId),n=S(f=>f.validation),s=S(f=>f.selectElement),o=S(f=>f.updateElementField),i=S(f=>f.updateElementAttribute),l=S(f=>f.applyEdit),[a,d]=u.useState(!1);u.useEffect(()=>{d(!1)},[r]),u.useEffect(()=>{if(!r)return;const f=D=>{(D.metaKey||D.ctrlKey)&&D.key==="s"&&(D.preventDefault(),l(r),d(!1))};return window.addEventListener("keydown",f),()=>window.removeEventListener("keydown",f)},[r,l]);const c=u.useMemo(()=>r&&e?es(e,r):[],[e,r]);if(!r||!e)return null;const p=e.elements[r];if(!p)return null;const m=c.filter(f=>f.sourceId===r),x=c.filter(f=>f.targetId===r),b=ie[p.layer]||"#666",k=(n==null?void 0:n.violations.filter(f=>f.elementId===r))||[],y=Object.entries(p.attributes).filter(([f])=>f!=="name"),v=f=>{o(r,"doc",f),l(r)},w=(f,D)=>{i(r,f,D),l(r)};return t.jsxs(t.Fragment,{children:[t.jsxs("div",{className:"p-4",style:{borderBottom:"1px solid #EDEDEA",borderLeft:`3px solid ${b}`},children:[t.jsxs("div",{className:"flex items-center gap-2 mb-1.5",children:[t.jsx("span",{className:"w-2.5 h-2.5 flex-shrink-0",style:{background:b,borderRadius:"3px"}}),t.jsx("span",{className:"text-sm font-semibold truncate",style:{color:"#1a1a1a"},children:p.name})]}),t.jsxs("div",{className:"flex items-center gap-2 text-xs",children:[t.jsx("span",{className:"px-2 py-0.5 rounded-md font-medium",style:{background:b+"18",color:b},children:p.kind}),t.jsx("span",{style:{color:"#6B7280"},children:p.construct})]}),t.jsxs("div",{className:"text-xs mt-1.5 capitalize",style:{color:"#6B7280"},children:[p.layer," layer"]})]}),t.jsxs("div",{className:"flex-1 overflow-y-auto",children:[t.jsx(oe,{title:"Description",defaultOpen:!0,children:t.jsx("div",{className:"text-xs leading-relaxed",children:t.jsx(gn,{value:p.doc||"",onSave:v,multiline:!0})})}),p.parameters&&p.parameters.length>0&&t.jsx(oe,{title:"Parameters",count:p.parameters.length,children:t.jsx("div",{className:"space-y-1.5",children:p.parameters.map(f=>t.jsxs("div",{className:"flex items-center gap-2 text-xs",children:[t.jsx("span",{className:"px-1.5 py-0.5 rounded font-mono",style:{fontSize:"10px",background:f.direction==="in"?"#EFF6FF":f.direction==="out"?"#FFF7ED":"#F0FDF4",color:f.direction==="in"?"#2563EB":f.direction==="out"?"#EA580C":"#16A34A"},children:f.direction}),t.jsx("span",{style:{color:"#374151",fontWeight:500},children:f.name}),t.jsx("span",{style:{color:"#6B7280"},children:":"}),t.jsx("span",{style:{color:"#6B7280"},children:f.type})]},f.name))})}),p.allocatedTo&&t.jsx(oe,{title:"Allocated To",defaultOpen:!0,children:t.jsx(xt,{label:((_=e.elements[p.allocatedTo])==null?void 0:_.name)||p.allocatedTo,kind:(N=e.elements[p.allocatedTo])==null?void 0:N.kind,kindColor:"#E67E22",arrow:"→",onClick:()=>s(p.allocatedTo)})}),y.length>0&&t.jsx(oe,{title:"Attributes",count:y.length,defaultOpen:!0,actions:t.jsx("button",{onClick:()=>{a&&r&&l(r),d(f=>!f)},className:"px-2 py-0.5 rounded text-xs font-medium",style:{background:a?"#2DD4A8":"#F0F0ED",color:a?"#FFFFFF":"#6B7280",border:"none",cursor:"pointer"},title:a?"Save (Ctrl+S)":"Edit attributes",children:a?"✓ Save":"✏ Edit"}),children:t.jsx("div",{className:"space-y-1.5",children:y.map(([f,D])=>t.jsxs("div",{className:"flex text-xs items-start",children:[t.jsx("span",{className:"min-w-[80px] pt-0.5",style:{color:"#6B7280"},children:f}),t.jsx(gn,{value:D,onSave:E=>w(f,E),forceEdit:a})]},f))})}),m.length>0&&t.jsx(oe,{title:"Outgoing",count:m.length,defaultOpen:!0,children:m.map(f=>{const D=e.elements[f.targetId],E=D&&ie[D.layer]||"#666";return t.jsx(xt,{label:(D==null?void 0:D.name)||f.targetId,kind:D==null?void 0:D.kind,kindColor:E,arrow:"→",typeBadge:f.type,typeColor:"#2563EB",onClick:()=>s(f.targetId)},f.id)})}),x.length>0&&t.jsx(oe,{title:"Incoming",count:x.length,defaultOpen:!0,children:x.map(f=>{const D=e.elements[f.sourceId],E=D&&ie[D.layer]||"#666";return t.jsx(xt,{label:(D==null?void 0:D.name)||f.sourceId,kind:D==null?void 0:D.kind,kindColor:E,arrow:"←",typeBadge:f.type,typeColor:"#10B981",onClick:()=>s(f.sourceId)},f.id)})}),k.length>0&&t.jsx(oe,{title:"Guidance",count:k.length,defaultOpen:!0,children:t.jsx("div",{className:"space-y-2",children:k.map((f,D)=>t.jsxs("div",{className:"text-xs p-2.5 rounded-lg",style:{background:f.severity==="error"?"#FEF2F2":f.severity==="warning"?"#FFFBEB":"#EFF6FF",border:`1px solid ${f.severity==="error"?"#FECACA":f.severity==="warning"?"#FDE68A":"#BFDBFE"}`},children:[t.jsx("div",{style:{color:f.severity==="error"?"#DC2626":f.severity==="warning"?"#D97706":"#2563EB"},children:f.description}),t.jsxs("div",{className:"mt-0.5",style:{color:"#6B7280"},children:["[",f.ruleId,"]"]})]},`${f.ruleId}-${D}`))})}),k.length===0&&t.jsx("div",{className:"p-4",children:t.jsxs("div",{className:"text-xs flex items-center gap-1",style:{color:"#10B981"},children:[t.jsx("span",{children:"✓"})," All rules satisfied"]})}),p.file&&t.jsx(oe,{title:"Source",defaultOpen:!1,children:t.jsxs("button",{className:"flex items-center gap-1.5 text-xs w-full text-left rounded px-1 py-0.5 transition-colors",style:{color:"#2563EB",background:"transparent",border:"none",cursor:"pointer",wordBreak:"break-all"},onMouseEnter:f=>{f.currentTarget.style.background="#EFF6FF"},onMouseLeave:f=>{f.currentTarget.style.background="transparent"},onClick:()=>{navigator.clipboard.writeText(p.file).catch(()=>{})},title:"Click to copy path",children:[t.jsx("span",{style:{flexShrink:0},children:"⟨/⟩"}),t.jsx("span",{className:"font-mono truncate",children:p.file}),t.jsx("span",{style:{flexShrink:0,color:"#9CA3AF",fontSize:"9px"},children:"copy"})]})})]})]})}function Bi(){const e=S(c=>c.model),r=S(c=>c.selectedRelationshipId);if(!e||!r)return null;const n=e.relationships.find(c=>c.id===r);if(!n)return null;const s=e.elements[n.sourceId],o=e.elements[n.targetId],i=n.type==="flow",l=n.flowItem,a=l&&/energy|power|voltage|current/i.test(l)?"Energy":l&&/material|fluid|gas|batch/i.test(l)?"Material":i?"Data":"Control",d=a==="Energy"?"#D97706":a==="Material"?"#16A34A":a==="Data"?"#3498DB":"#4B5563";return t.jsxs(t.Fragment,{children:[t.jsxs("div",{className:"p-4",style:{borderBottom:"1px solid #EDEDEA",borderLeft:`3px solid ${d}`},children:[t.jsx("div",{className:"text-sm font-semibold",style:{color:"#1a1a1a"},children:"Connection"}),t.jsxs("div",{className:"mt-1 text-xs",style:{color:"#6B7280"},children:[(s==null?void 0:s.name)??n.sourceId," → ",(o==null?void 0:o.name)??n.targetId]}),t.jsxs("div",{className:"mt-2 flex gap-2",children:[t.jsxs("span",{className:"px-2 py-0.5 rounded-md text-xs font-medium",style:{background:d+"18",color:d},children:[a," flow"]}),t.jsx("span",{className:"px-2 py-0.5 rounded-md text-xs font-medium",style:{background:"#F3F4F6",color:"#374151"},children:n.type})]})]}),t.jsxs("div",{className:"flex-1 overflow-y-auto",children:[t.jsx(oe,{title:"Involved item",defaultOpen:!0,children:t.jsx("div",{className:"text-xs",style:{color:"#374151"},children:l??"No transported item is modeled for this connection."})}),t.jsx(oe,{title:"Endpoints",defaultOpen:!0,children:t.jsxs("div",{className:"space-y-2 text-xs",children:[t.jsxs("div",{children:[t.jsx("span",{style:{color:"#6B7280"},children:"Source"}),t.jsx("div",{style:{color:"#1a1a1a",fontWeight:500},children:(s==null?void 0:s.name)??n.sourceId})]}),t.jsxs("div",{children:[t.jsx("span",{style:{color:"#6B7280"},children:"Target"}),t.jsx("div",{style:{color:"#1a1a1a",fontWeight:500},children:(o==null?void 0:o.name)??n.targetId})]})]})}),t.jsx(oe,{title:"Traceability",defaultOpen:!1,children:t.jsx("div",{className:"text-xs",style:{color:"#6B7280"},children:n.file||"Model relationship"})})]})]})}function Li(){const e=S(a=>a.selectedElementId),r=S(a=>a.activeView),n=S(a=>a.selectedRelationshipId),s=S(a=>a.propertiesPanelCollapsed),o=S(a=>a.togglePropertiesPanel);if(s)return t.jsxs("div",{className:"flex flex-col items-center flex-shrink-0 cursor-pointer",style:{width:"40px",background:"#FAFAF8",borderLeft:"1px solid #E5E5E0"},onClick:o,title:"Expand properties",children:[t.jsx("div",{className:"flex items-center justify-center mt-2",style:{color:"#6B7280",fontSize:"20px",width:"32px",height:"32px",borderRadius:"6px"},children:"◂"}),t.jsx("div",{style:{writingMode:"vertical-rl",textOrientation:"mixed",color:"#6B7280",fontSize:"12px",fontWeight:600,letterSpacing:"0.1em"},children:"Properties"})]});const i=r.type==="diagram"&&!e&&!n,l=!!e;return t.jsxs("div",{className:"flex flex-col overflow-hidden flex-shrink-0",style:{width:"300px",background:"#FAFAF8",borderLeft:"1px solid #E5E5E0"},children:[t.jsxs("div",{className:"flex items-center justify-between px-3 py-1.5",style:{borderBottom:"1px solid #EDEDEA"},children:[t.jsx("span",{className:"text-xs font-medium",style:{color:"#6B7280"},children:"Properties"}),t.jsx("button",{onClick:o,className:"flex items-center justify-center",style:{color:"#6B7280",fontSize:"20px",lineHeight:1,width:"32px",height:"32px",borderRadius:"6px"},onMouseEnter:a=>a.currentTarget.style.color="#374151",onMouseLeave:a=>a.currentTarget.style.color="#6B7280",title:"Collapse properties","aria-label":"Collapse properties",children:"▸"})]}),n?t.jsx(Bi,{}):l?t.jsx(zi,{}):i?t.jsx(Pi,{}):t.jsx("div",{className:"flex-1 flex items-center justify-center p-4",children:t.jsx("span",{className:"text-xs text-center",style:{color:"#6B7280"},children:"Select an element or diagram to view properties"})})]})}function bt(e=g.border){return{borderTop:`1px solid ${e}`}}function qi({placeholder:e,value:r,onChange:n}){return t.jsx("input",{type:"text",value:r,placeholder:e,onChange:s=>n(s.target.value),className:"flex-1 px-2 py-1 rounded focus:outline-none",style:{background:"#F7F7F5",border:"1px solid #E5E5E0",color:g.primary,fontSize:C.xs,minWidth:0}})}function Vi({values:e}){const r=[...new Set(e.filter(Boolean))];return r.length===0?t.jsx("span",{style:{color:g.faint,fontSize:"12px"},children:"—"}):r.length===1?t.jsx("span",{style:{color:g.muted,fontSize:"12px"},children:r[0]}):t.jsxs("span",{style:{color:"#F59E0B",fontSize:"12px"},children:[r.length," different values"]})}function Ui(){const e=S(y=>y.model),r=S(y=>y.selectedElementIds),n=S(y=>y.clearElementSelection),s=S(y=>y.bulkUpdateAttributes),o=u.useMemo(()=>[...r],[r]),i=u.useMemo(()=>o.map(y=>e==null?void 0:e.elements[y]).filter(Boolean),[o,e]),l=u.useMemo(()=>{if(i.length===0)return[];const y="_",v=i.map(_=>new Set(Object.keys(_.attributes).filter(N=>!N.startsWith(y))));return[...v[0]].filter(_=>v.every(N=>N.has(_))).sort()},[i]),a=u.useMemo(()=>{const y={};for(const v of l)y[v]=i.map(w=>w.attributes[v]??"");return y},[i,l]),d=u.useMemo(()=>[...new Set(i.map(y=>y.kind))].sort(),[i]),[c,p]=u.useState({}),m=u.useCallback((y,v)=>{p(w=>({...w,[y]:v}))},[]),x=Object.values(c).some(y=>y!==""),b=u.useCallback(()=>{const y=Object.fromEntries(Object.entries(c).filter(([,v])=>v!==""));Object.keys(y).length!==0&&(s(o,y),p({}))},[c,o,s]),k=u.useCallback(()=>{p({})},[]);return i.length<2?null:t.jsxs("div",{className:"flex flex-col overflow-hidden",style:{width:"280px",background:g.surface,borderLeft:`1px solid ${g.border}`,fontSize:C.xs},children:[t.jsxs("div",{className:"flex items-center justify-between px-4 py-3 flex-shrink-0",style:{borderBottom:`1px solid ${g.border}`},children:[t.jsxs("div",{children:[t.jsx("div",{className:"font-semibold",style:{color:g.primary,fontSize:C.sm},children:"Bulk Edit"}),t.jsxs("div",{style:{color:g.muted,fontSize:"12px",marginTop:"2px"},children:[o.length," elements selected"]})]}),t.jsx("button",{onClick:n,className:"px-2 py-1 rounded",style:{color:g.muted,background:"#F0F0ED",fontSize:"12px"},title:"Clear selection",children:"✕ Clear"})]}),t.jsxs("div",{className:"px-4 py-3 flex-shrink-0",style:bt(),children:[t.jsx("div",{style:{color:g.muted,fontSize:"12px",fontWeight:600,marginBottom:"6px",textTransform:"uppercase",letterSpacing:"0.5px"},children:"Selection"}),t.jsx("div",{className:"flex flex-wrap gap-1",children:d.map(y=>t.jsx("span",{className:"px-2 py-0.5 rounded-full",style:{background:"#EEF2FF",color:"#4F46E5",fontSize:"12px",fontWeight:500},children:y},y))}),t.jsxs("div",{style:{color:g.faint,fontSize:"12px",marginTop:"6px"},children:[i.map(y=>y.name).slice(0,5).join(", "),i.length>5&&` +${i.length-5} more`]})]}),t.jsxs("div",{className:"flex-1 overflow-y-auto px-4 py-3",style:bt(),children:[t.jsxs("div",{style:{color:g.muted,fontSize:"12px",fontWeight:600,marginBottom:"8px",textTransform:"uppercase",letterSpacing:"0.5px"},children:["Common Attributes",l.length>0&&t.jsxs("span",{style:{color:g.faint,fontWeight:400,marginLeft:"4px"},children:["(",l.length,")"]})]}),l.length===0?t.jsx("div",{style:{color:g.faint,fontSize:"12px"},children:"No common attributes across selected elements."}):t.jsx("div",{className:"space-y-3",children:l.map(y=>t.jsxs("div",{children:[t.jsxs("div",{className:"flex items-center justify-between mb-1",children:[t.jsx("span",{style:{color:g.secondary,fontSize:"12px",fontWeight:500},children:y}),t.jsx(Vi,{values:a[y]})]}),t.jsx(qi,{placeholder:`Set for all ${o.length} elements…`,value:c[y]??"",onChange:v=>m(y,v)})]},y))})]}),l.length>0&&t.jsxs("div",{className:"flex items-center gap-2 px-4 py-3 flex-shrink-0",style:bt(),children:[t.jsx("button",{onClick:k,disabled:!x,className:"flex-1 py-1.5 rounded",style:{fontSize:C.xs,fontWeight:500,color:x?g.secondary:g.faint,background:x?"#F0F0ED":"#F7F7F5",cursor:x?"pointer":"default"},children:"Reset"}),t.jsxs("button",{onClick:b,disabled:!x,className:"flex-1 py-1.5 rounded font-semibold",style:{fontSize:C.xs,color:"#FFFFFF",background:x?"#2DD4A8":"#A7F3D0",cursor:x?"pointer":"default"},children:["Apply to ",o.length]})]})]})}const yn="memo-gapbar-pulse";if(typeof document<"u"&&!document.getElementById(yn)){const e=document.createElement("style");e.id=yn,e.textContent=`
3263
- @keyframes memo-pulse-red {
3264
- 0%, 100% { opacity: 1; }
3265
- 50% { opacity: 0.35; }
3266
- }
3267
- `,document.head.appendChild(e)}const Xe={error:{color:"#DC2626",bg:"#FEF2F2",icon:"✖"},warning:{color:"#D97706",bg:"#FFFBEB",icon:"⚠"},info:{color:"#2563EB",bg:"#EFF6FF",icon:"ℹ"}};function $i(){const e=S(j=>j.validation),r=S(j=>j.analysisIssues),n=S(j=>j.selectElement),s=S(j=>j.model),o=S(j=>j.completeness),i=S(j=>j.gapBarExpanded),l=S(j=>j.toggleGapBar),a=S(j=>j.gapBarHeight),d=S(j=>j.setGapBarHeight),[c,p]=u.useState("problems"),m=u.useRef(!1),x=u.useRef(0),b=u.useRef(0),k=s==null?void 0:s.metadata,y=s?Object.keys(s.elements).length:0,v=k!=null&&k.gitUser?t.jsxs(t.Fragment,{children:["@",k.gitUser,k.gitBranch&&t.jsxs(t.Fragment,{children:[" · ",k.gitBranch]}),k.gitCommitShort&&t.jsx("span",{style:{marginLeft:"4px",fontFamily:"monospace",fontSize:C.badge},children:k.gitCommitShort})]}):null,w=(e==null?void 0:e.violations.filter(j=>j.severity==="error"))??[],_=(e==null?void 0:e.violations.filter(j=>j.severity==="warning"))??[],N=(e==null?void 0:e.violations.length)??0,f=r.filter(j=>j.severity==="warning").length,D=N>0||r.length>0,E=!!o,R=D&&E,T=(o==null?void 0:o.layers.filter(j=>j.totalElements>0))??[],O=u.useCallback(j=>{j.preventDefault(),m.current=!0,x.current=j.clientY,b.current=a;const B=U=>{if(!m.current)return;const X=x.current-U.clientY;d(b.current+X)},H=()=>{m.current=!1,document.removeEventListener("mousemove",B),document.removeEventListener("mouseup",H)};document.addEventListener("mousemove",B),document.addEventListener("mouseup",H)},[a,d]);return t.jsxs("div",{style:{background:g.surface,borderTop:`1px solid ${g.border}`,flexShrink:0},children:[i&&t.jsx("div",{style:{height:"4px",cursor:"row-resize",background:"transparent",flexShrink:0},onMouseDown:O,onMouseEnter:j=>{j.currentTarget.style.background=g.accent+"40"},onMouseLeave:j=>{j.currentTarget.style.background="transparent"}}),t.jsxs("div",{className:"flex items-center px-4 gap-3 cursor-pointer select-none",style:{height:"32px",fontSize:C.sm},onClick:l,children:[t.jsx("span",{style:{color:g.faint,fontSize:"10px",transition:"transform 150ms ease",transform:i?"rotate(0deg)":"rotate(-90deg)",display:"inline-block"},children:"▼"}),t.jsx("span",{style:{color:g.secondary,fontWeight:600,fontSize:C.xs},children:"Problems"}),w.length>0&&t.jsxs("span",{className:"flex items-center gap-1",style:{color:"#DC2626",fontSize:C.xs},children:[t.jsx("span",{style:{fontSize:"10px"},children:"✖"})," ",w.length]}),_.length>0&&t.jsxs("span",{className:"flex items-center gap-1",style:{color:"#D97706",fontSize:C.xs},children:[t.jsx("span",{style:{fontSize:"10px"},children:"⚠"})," ",_.length]}),f>0&&t.jsxs("span",{className:"flex items-center gap-1",style:{color:"#D97706",fontSize:C.xs},children:[t.jsx("span",{style:{fontSize:"9px",opacity:.7},children:"DSM"}),t.jsx("span",{style:{fontSize:"10px"},children:"⚠"})," ",f]}),!D&&e&&t.jsx("span",{style:{color:"#10B981",fontSize:C.xs},children:"✓ No problems"}),!e&&t.jsx("span",{style:{color:g.faint,fontSize:C.xs},children:"Waiting for validation…"}),E&&t.jsxs(t.Fragment,{children:[t.jsx("div",{style:{width:"1px",height:"14px",background:g.border,flexShrink:0}}),t.jsx("span",{style:{color:g.secondary,fontWeight:600,fontSize:C.xs},children:"Completeness"}),t.jsxs("span",{style:{color:o.overall>=80?"#10B981":o.overall>=50?"#D97706":"#DC2626",fontSize:C.xs,fontWeight:600},children:[o.overall,"%"]}),t.jsx("div",{className:"flex items-center gap-0.5",children:T.map(j=>{const B=j.percentage<40;return t.jsx("div",{title:`${At[j.layerId]||j.layerLabel}: ${j.percentage}%`,style:{width:8,height:8,borderRadius:"2px",background:j.layerColor,opacity:Math.max(j.percentage/100,.12),flexShrink:0,animation:B?"memo-pulse-red 1.4s ease-in-out infinite":"none",cursor:"default"}},j.layerId)})})]}),t.jsxs("span",{className:"ml-auto flex items-center gap-1",style:{fontSize:C.xs},children:[e&&t.jsxs("span",{style:{color:g.faint},children:[e.rulesEvaluated," rules | ",e.rulesPassed," passed |"," "]}),t.jsxs("strong",{style:{color:g.secondary,fontWeight:700},children:[y," elements"]}),s&&t.jsxs(t.Fragment,{children:[t.jsx("span",{style:{color:g.faint},children:" · "}),t.jsxs("strong",{style:{color:g.secondary,fontWeight:700},children:[s.relationships.length," rels"]})]}),v&&t.jsxs("span",{style:{color:g.faint},children:[" | ",v]})]})]}),i&&t.jsxs("div",{style:{borderTop:`1px solid ${g.borderLight}`},children:[R&&t.jsx("div",{className:"flex",style:{borderBottom:`1px solid ${g.border}`,background:"#FAFAF8"},children:["problems","completeness"].map(j=>t.jsx("button",{onClick:B=>{B.stopPropagation(),p(j)},className:"px-4 py-1.5 font-medium transition-colors",style:{fontSize:C.xs,borderBottom:c===j?`2px solid ${g.accent}`:"2px solid transparent",color:c===j?g.accentDark:g.faint,background:"transparent"},children:j==="problems"?`Problems (${N+r.length})`:`Completeness ${o.overall}%`},j))}),(c==="problems"||!R)&&t.jsx("div",{className:"overflow-y-auto",style:{maxHeight:`${a}px`},children:D?t.jsxs(t.Fragment,{children:[N>0&&(e==null?void 0:e.violations.map((j,B)=>{const H=Xe[j.severity]||Xe.info;return t.jsxs("div",{className:"flex items-center gap-2 px-4 py-1.5 cursor-pointer transition-colors",style:{color:H.color,fontSize:C.xs},onMouseEnter:U=>U.currentTarget.style.background=H.bg,onMouseLeave:U=>U.currentTarget.style.background="transparent",onClick:()=>n(j.elementId),children:[t.jsx("span",{children:H.icon}),t.jsxs("span",{style:{color:g.faint},children:["[",j.ruleId,"]"]}),t.jsxs("span",{className:"font-medium",children:[j.elementKind,"/",j.elementName]}),t.jsx("span",{className:"truncate flex-1",style:{color:g.muted},children:j.description})]},`${j.ruleId}-${j.elementId}-${B}`)})),r.length>0&&t.jsxs(t.Fragment,{children:[N>0&&t.jsx("div",{style:{padding:"4px 16px",fontSize:"10px",fontWeight:600,color:g.faint,background:g.surfaceAlt,borderTop:`1px solid ${g.border}`,textTransform:"uppercase",letterSpacing:"0.06em"},children:"DSM Analysis"}),r.map(j=>{const B=Xe[j.severity]||Xe.info;return t.jsxs("div",{className:"flex items-center gap-2 px-4 py-1.5 cursor-pointer transition-colors",style:{color:B.color,fontSize:C.xs},onMouseEnter:H=>H.currentTarget.style.background=B.bg,onMouseLeave:H=>H.currentTarget.style.background="transparent",onClick:()=>n(j.elementId),children:[t.jsx("span",{children:B.icon}),t.jsxs("span",{style:{color:g.faint},children:["[",j.source,"]"]}),t.jsx("span",{className:"font-medium",children:j.elementName}),t.jsx("span",{className:"truncate flex-1",style:{color:g.muted},children:j.message}),j.tag&&t.jsx("span",{style:{flexShrink:0,fontSize:"9px",padding:"1px 5px",borderRadius:"4px",background:"#E5E7EB",color:"#374151"},children:j.tag})]},j.id)})]})]}):t.jsx("div",{className:"px-4 py-3",style:{color:g.faint,fontSize:C.xs},children:e?"✓ No problems found":"Waiting for validation…"})}),(c==="completeness"||!R)&&E&&t.jsxs("div",{className:"overflow-y-auto",style:{maxHeight:`${a}px`},children:[t.jsxs("div",{className:"px-4 py-2 flex items-center gap-3",style:{borderBottom:`1px solid ${g.borderLight}`},children:[t.jsxs("span",{style:{fontWeight:700,fontSize:"18px",color:o.overall>=80?"#10B981":o.overall>=50?"#D97706":"#DC2626"},children:[o.overall,"%"]}),t.jsx("div",{className:"flex-1 flex items-center gap-0.5",style:{height:"8px"},children:T.map(j=>{const B=Math.max(j.totalElements/o.totalElements*100,2);return t.jsx("div",{style:{width:`${B}%`,height:"100%",background:j.layerColor+"30",borderRadius:"4px",overflow:"hidden"},children:t.jsx("div",{style:{width:`${j.percentage}%`,height:"100%",background:j.layerColor,borderRadius:"4px"}})},j.layerId)})}),t.jsxs("span",{style:{color:g.faint,fontSize:C.xs},children:[o.completeElements,"/",o.totalElements]})]}),t.jsx("div",{className:"px-4 py-2 grid gap-1.5",style:{gridTemplateColumns:"repeat(auto-fill, minmax(220px, 1fr))"},children:T.map(j=>t.jsxs("div",{className:"flex items-center gap-2",style:{fontSize:C.xs},children:[t.jsx("span",{className:"w-2.5 h-2.5 rounded flex-shrink-0",style:{backgroundColor:j.layerColor}}),t.jsx("span",{className:"flex-1 truncate",style:{color:"#374151"},children:At[j.layerId]||j.layerLabel}),t.jsxs("span",{style:{color:"#6B7280"},children:[j.percentage,"%"]}),t.jsxs("span",{style:{color:"#9CA3AF"},children:["(",j.completeElements,"/",j.totalElements,")"]})]},j.layerId))})]})]})]})}function Wi(){const[e,r]=u.useState(!1),[n,s]=u.useState(""),[o,i]=u.useState(0),l=u.useRef(null),a=S(v=>v.model),d=S(v=>v.selectElement),c=S(v=>v.setActiveView),p=S(v=>v.selectViewpoint),m=S(v=>v.setExplorerTab);u.useEffect(()=>{const v=w=>{(w.metaKey||w.ctrlKey)&&w.key==="k"&&(w.preventDefault(),r(_=>!_),s(""),i(0)),w.key==="Escape"&&e&&r(!1)};return window.addEventListener("keydown",v),()=>window.removeEventListener("keydown",v)},[e]),u.useEffect(()=>{e&&setTimeout(()=>{var v;return(v=l.current)==null?void 0:v.focus()},50)},[e]);const x=u.useMemo(()=>{const v=[];if(v.push({id:"tool:dsm",label:"DSM",sublabel:"Design Structure Matrix",kind:"tool",action:()=>c({type:"dsm"})},{id:"tool:traceability",label:"Traceability Matrix",sublabel:"N×N trace matrix with presets",kind:"tool",action:()=>c({type:"traceability"})},{id:"tool:ontology",label:"Ontology",sublabel:"Ontology Viewer",kind:"tool",action:()=>c({type:"ontology"})}),!a)return v;for(const w of a.diagrams??[]){const _=Ae[w.diagramType];v.push({id:`diag:${w.id}`,label:w.name,sublabel:(_==null?void 0:_.fullName)||w.diagramType,kind:"diagram",color:_==null?void 0:_.color,action:()=>{c({type:"diagram",diagramId:w.id}),p(w.viewpointId==="__model"?null:w.viewpointId),m("views")}})}for(const w of a.viewpoints??[])v.push({id:`vp:${w.id}`,label:w.label,sublabel:"Viewpoint",kind:"viewpoint",action:()=>{p(w.id),m("views")}});for(const w of Object.values(a.elements))v.push({id:`el:${w.id}`,label:w.name,sublabel:`${w.kind} · ${w.layer}`,kind:"element",color:ie[w.layer],action:()=>{d(w.id),m("model")}});return v},[a,c,d,p,m]),b=u.useMemo(()=>{if(!n)return x.slice(0,20);const v=n.toLowerCase();return x.filter(w=>{var _;return w.label.toLowerCase().includes(v)||((_=w.sublabel)==null?void 0:_.toLowerCase().includes(v))}).slice(0,20)},[x,n]);u.useEffect(()=>{i(0)},[b]);const k=u.useCallback(v=>{v.key==="ArrowDown"&&(v.preventDefault(),i(w=>Math.min(w+1,b.length-1))),v.key==="ArrowUp"&&(v.preventDefault(),i(w=>Math.max(w-1,0))),v.key==="Enter"&&b[o]&&(b[o].action(),r(!1))},[b,o]);if(!e)return null;const y={element:"○",diagram:"▦",tool:"⚙",viewpoint:"◉"};return t.jsx("div",{className:"fixed inset-0 z-50 flex items-start justify-center pt-24",style:{background:"rgba(0,0,0,0.4)"},onClick:()=>r(!1),children:t.jsxs("div",{className:"rounded-xl overflow-hidden",style:{width:"520px",maxHeight:"400px",background:"#FFFFFF",boxShadow:"0 16px 48px rgba(0,0,0,0.2)"},onClick:v=>v.stopPropagation(),children:[t.jsxs("div",{className:"flex items-center gap-2 px-4 py-3",style:{borderBottom:"1px solid #E5E5E0"},children:[t.jsx("span",{style:{color:"#9CA3AF",fontSize:"14px"},children:"⌕"}),t.jsx("input",{ref:l,type:"text",placeholder:"Search elements, diagrams, tools...",value:n,onChange:v=>s(v.target.value),onKeyDown:k,className:"flex-1 text-sm focus:outline-none",style:{color:"#1a1a1a",background:"transparent"}}),t.jsx("kbd",{className:"px-1.5 py-0.5 rounded text-xs",style:{background:"#F0F0ED",color:"#9CA3AF",fontSize:"10px"},children:"ESC"})]}),t.jsxs("div",{className:"overflow-y-auto",style:{maxHeight:"340px"},children:[b.length===0&&t.jsx("div",{className:"px-4 py-6 text-center text-xs",style:{color:"#9CA3AF"},children:"No results found"}),b.map((v,w)=>t.jsxs("div",{className:"flex items-center gap-2 px-4 py-2 cursor-pointer",style:{background:w===o?"#F0F0ED":"transparent"},onMouseEnter:()=>i(w),onClick:()=>{v.action(),r(!1)},children:[t.jsx("span",{style:{color:v.color||"#9CA3AF",fontSize:"12px"},children:y[v.kind]||"○"}),t.jsx("span",{className:"text-sm truncate",style:{color:"#1a1a1a"},children:v.label}),v.sublabel&&t.jsx("span",{className:"text-xs truncate ml-auto",style:{color:"#9CA3AF"},children:v.sublabel})]},v.id))]}),t.jsx("div",{className:"px-4 py-2 flex items-center gap-3",style:{borderTop:"1px solid #E5E5E0",background:"#FAFAF8"},children:t.jsxs("span",{className:"text-xs",style:{color:"#9CA3AF"},children:["↑↓"," navigate · ","↵"," select · esc close"]})})]})})}const Hi=["general","interconnection","actionflow","statetransition","sequence","grid","browser","geometry"];new Set(Hi);const Ki={id:"requirements-matrix",name:"Requirements Matrix",description:"Standard requirements spreadsheet with ID, title, description, priority columns. Typical export from DOORS, Jama, or a simple Excel requirements log.",defaultKind:"Requirement",columnMappings:[{sourceColumn:"req id",targetAttribute:"id",transform:"sanitize-id",required:!0},{sourceColumn:"requirement id",targetAttribute:"id",transform:"sanitize-id",required:!0},{sourceColumn:"id",targetAttribute:"id",transform:"sanitize-id",required:!0},{sourceColumn:"req #",targetAttribute:"id",transform:"sanitize-id"},{sourceColumn:"number",targetAttribute:"id",transform:"sanitize-id"},{sourceColumn:"title",targetAttribute:"name",required:!0},{sourceColumn:"requirement title",targetAttribute:"name",required:!0},{sourceColumn:"name",targetAttribute:"name",required:!0},{sourceColumn:"summary",targetAttribute:"name"},{sourceColumn:"description",targetAttribute:"doc"},{sourceColumn:"text",targetAttribute:"doc"},{sourceColumn:"statement",targetAttribute:"doc"},{sourceColumn:"requirement text",targetAttribute:"doc"},{sourceColumn:"kind",targetAttribute:"kind"},{sourceColumn:"type",targetAttribute:"kind"},{sourceColumn:"category",targetAttribute:"category"},{sourceColumn:"priority",targetAttribute:"priority"},{sourceColumn:"rationale",targetAttribute:"rationale"},{sourceColumn:"verification method",targetAttribute:"verificationMethod"},{sourceColumn:"status",targetAttribute:"status"}]},Gi={id:"hazard-log",name:"Hazard Log",description:"ISO 14971 hazard analysis spreadsheet with hazard ID, description, severity, probability and risk level columns.",defaultKind:"Hazard",columnMappings:[{sourceColumn:"hazard id",targetAttribute:"id",transform:"sanitize-id",required:!0},{sourceColumn:"haz id",targetAttribute:"id",transform:"sanitize-id"},{sourceColumn:"id",targetAttribute:"id",transform:"sanitize-id",required:!0},{sourceColumn:"hazard",targetAttribute:"name",required:!0},{sourceColumn:"hazard description",targetAttribute:"name",required:!0},{sourceColumn:"name",targetAttribute:"name",required:!0},{sourceColumn:"description",targetAttribute:"doc"},{sourceColumn:"hazardous situation",targetAttribute:"doc"},{sourceColumn:"kind",targetAttribute:"kind"},{sourceColumn:"severity",targetAttribute:"severity"},{sourceColumn:"probability",targetAttribute:"probability"},{sourceColumn:"risk level",targetAttribute:"riskLevel"},{sourceColumn:"risk",targetAttribute:"riskLevel"},{sourceColumn:"harm",targetAttribute:"harm"},{sourceColumn:"foreseeable misuse",targetAttribute:"foreseeableMisuse"},{sourceColumn:"mitigation",targetAttribute:"mitigation"},{sourceColumn:"residual risk",targetAttribute:"residualRisk"},{sourceColumn:"status",targetAttribute:"status"}]},Yi={id:"fmea-worksheet",name:"FMEA Worksheet",description:"Failure Mode and Effects Analysis spreadsheet. Maps component failure modes to MEMO Failure kind with FMEA attributes (severity, occurrence, detection, RPN).",defaultKind:"Failure",columnMappings:[{sourceColumn:"id",targetAttribute:"id",transform:"sanitize-id",required:!0},{sourceColumn:"fmea id",targetAttribute:"id",transform:"sanitize-id"},{sourceColumn:"failure mode",targetAttribute:"name",required:!0},{sourceColumn:"failure mode description",targetAttribute:"name"},{sourceColumn:"name",targetAttribute:"name",required:!0},{sourceColumn:"description",targetAttribute:"doc"},{sourceColumn:"effect",targetAttribute:"doc"},{sourceColumn:"effect of failure",targetAttribute:"effect"},{sourceColumn:"kind",targetAttribute:"kind"},{sourceColumn:"component",targetAttribute:"component"},{sourceColumn:"function",targetAttribute:"function"},{sourceColumn:"severity",targetAttribute:"severity"},{sourceColumn:"s",targetAttribute:"severity"},{sourceColumn:"occurrence",targetAttribute:"occurrence"},{sourceColumn:"o",targetAttribute:"occurrence"},{sourceColumn:"detection",targetAttribute:"detection"},{sourceColumn:"d",targetAttribute:"detection"},{sourceColumn:"rpn",targetAttribute:"rpn"},{sourceColumn:"risk priority number",targetAttribute:"rpn"},{sourceColumn:"cause",targetAttribute:"cause"},{sourceColumn:"controls",targetAttribute:"controls"},{sourceColumn:"action",targetAttribute:"action"}]},Ji={id:"verification-table",name:"Verification Table",description:"Verification and validation traceability matrix mapping requirements to test methods and results.",defaultKind:"VerificationTest",columnMappings:[{sourceColumn:"test id",targetAttribute:"id",transform:"sanitize-id",required:!0},{sourceColumn:"verification id",targetAttribute:"id",transform:"sanitize-id"},{sourceColumn:"id",targetAttribute:"id",transform:"sanitize-id",required:!0},{sourceColumn:"test name",targetAttribute:"name",required:!0},{sourceColumn:"name",targetAttribute:"name",required:!0},{sourceColumn:"title",targetAttribute:"name"},{sourceColumn:"description",targetAttribute:"doc"},{sourceColumn:"objective",targetAttribute:"doc"},{sourceColumn:"kind",targetAttribute:"kind"},{sourceColumn:"requirement id",targetAttribute:"requirementId"},{sourceColumn:"req id",targetAttribute:"requirementId"},{sourceColumn:"method",targetAttribute:"method"},{sourceColumn:"test method",targetAttribute:"method"},{sourceColumn:"verification method",targetAttribute:"method"},{sourceColumn:"result",targetAttribute:"result"},{sourceColumn:"pass/fail",targetAttribute:"result"},{sourceColumn:"status",targetAttribute:"status"},{sourceColumn:"evidence",targetAttribute:"evidence"},{sourceColumn:"notes",targetAttribute:"notes"}]},xn=[Ki,Gi,Yi,Ji];function Qi(e,r){return e.map(n=>{const s=n.trim().toLowerCase();if(r){const l=r.columnMappings.find(a=>a.sourceColumn.toLowerCase()===s);if(l)return{...l,sourceColumn:n}}const o=Xi.find(l=>l.sourceColumn.toLowerCase()===s);if(o)return{...o,sourceColumn:n};const i=na(n);return{sourceColumn:n,targetAttribute:i}})}const Xi=[{sourceColumn:"id",targetAttribute:"id",transform:"sanitize-id"},{sourceColumn:"identifier",targetAttribute:"id",transform:"sanitize-id"},{sourceColumn:"uid",targetAttribute:"id",transform:"sanitize-id"},{sourceColumn:"name",targetAttribute:"name"},{sourceColumn:"title",targetAttribute:"name"},{sourceColumn:"label",targetAttribute:"name"},{sourceColumn:"description",targetAttribute:"doc"},{sourceColumn:"text",targetAttribute:"doc"},{sourceColumn:"notes",targetAttribute:"doc"},{sourceColumn:"kind",targetAttribute:"kind"},{sourceColumn:"type",targetAttribute:"kind"},{sourceColumn:"category",targetAttribute:"kind"},{sourceColumn:"construct",targetAttribute:"construct"}];function Zi(e,r,n,s){const o=[],i=[],l=new Set,a=[];for(const y of r){if(!y.targetAttribute){i.push(y.sourceColumn);continue}l.has(y.targetAttribute)||(l.add(y.targetAttribute),a.push(y))}const d=l.has("id"),c=l.has("name"),p=l.has("kind");d||o.push("No column mapped to 'id' — id will be auto-generated from row number"),c||o.push("No column mapped to 'name'"),!p&&!s&&o.push("No column mapped to 'kind' and no defaultKind set");const m=["id","name","kind","construct","doc"],x=Array.from(l).filter(y=>!m.includes(y)),b=[...m.filter(y=>l.has(y)),...x];for(const y of["id","name","kind"])b.includes(y)||b.unshift(y);const k=[b.map(bn).join(",")];return e.forEach((y,v)=>{const w={};for(const f of a){const D=y[f.sourceColumn]??"";w[f.targetAttribute]=ea(D,f.transform)}(!w.id||w.id.trim()==="")&&(w.id=`row_${v+1}`),(!w.kind||w.kind.trim()==="")&&s&&(w.kind=s);const _=w.kind;_&&n.kinds&&!n.kinds[_]&&o.push(`Row ${v+2}: unknown kind '${_}' (not in config)`);const N=b.map(f=>bn(w[f]??""));k.push(N.join(","))}),{csv:k.join(`
3268
- `)+`
3269
- `,skippedColumns:i,warnings:o}}function ea(e,r){if(!r)return e;switch(r){case"sanitize-id":return ta(e);case"upper":return e.toUpperCase();case"lower":return e.toLowerCase();default:return e}}function ta(e){let r=e.trim().replace(/[\s\-]+/g,"_").replace(/[^a-zA-Z0-9_]/g,"").toLowerCase();return/^\d/.test(r)&&(r="e_"+r),r}function na(e){return e.trim().replace(/[^a-zA-Z0-9 _-]/g,"").split(/[\s_-]+/).map((r,n)=>n===0?r.toLowerCase():r.charAt(0).toUpperCase()+r.slice(1).toLowerCase()).join("")}function bn(e){return e.includes(",")||e.includes('"')||e.includes(`
3270
- `)?`"${e.replace(/"/g,'""')}"`:e}function ra(e){const r=e.trim().split(/\r?\n/).filter(Boolean);if(r.length<2)return{headers:[],rows:[]};const s=r[0].includes(" ")?" ":",",o=a=>a.split(s).map(d=>d.replace(/^"(.*)"$/,"$1").replace(/""/g,'"').trim()),i=o(r[0]),l=r.slice(1).map(a=>{const d=o(a),c={};return i.forEach((p,m)=>{c[p]=d[m]??""}),c});return{headers:i,rows:l}}const vn=["id","name","kind","construct","doc","— skip —"];function oa(){const e=S(h=>h.bulkImportOpen),r=S(h=>h.setBulkImportOpen),n=S(h=>h.importResult),s=S(h=>h.clearImportResult),o=S(h=>h.model),i=u.useRef(null),[l,a]=u.useState("input"),[d,c]=u.useState(""),[p,m]=u.useState(null),[x,b]=u.useState("bulk_import"),[k,y]=u.useState(""),[v,w]=u.useState([]),[_,N]=u.useState([]),[f,D]=u.useState([]),[E,R]=u.useState([]),[T,O]=u.useState([]),[j,B]=u.useState([]),[H,U]=u.useState(""),[X,$]=u.useState(!1);rr.useMemo(()=>o?Array.from(new Set(Object.values(o.elements).map(h=>h.kind))).sort():[],[o]),u.useEffect(()=>{e||(a("input"),c(""),m(null),b("bulk_import"),y(""),w([]),N([]),D([]),R([]),O([]),B([]),U(""),$(!1),s())},[e,s]),u.useEffect(()=>{n&&$(!1)},[n]);const ae=u.useCallback(()=>{r(!1)},[r]),I=u.useCallback(h=>{var Y;const A=(Y=h.target.files)==null?void 0:Y[0];if(!A)return;const P=new FileReader;P.onload=re=>{var se;const Z=(se=re.target)==null?void 0:se.result;c(Z),y("");const z=A.name.replace(/\.[^.]+$/,"").replace(/[^a-zA-Z0-9_]/g,"_");z&&b(z)},P.readAsText(A)},[]),W=u.useCallback(()=>{if(!d.trim()){y("Paste CSV data or upload a file first.");return}const{headers:h,rows:A}=ra(d);if(h.length===0){y("Could not parse headers. Make sure the first row contains column names.");return}if(A.length===0){y("No data rows found after the header row.");return}w(h),N(A),D(Qi(h,p??void 0)),y(""),a("mapping")},[d,p]),G=u.useCallback(()=>{const h=p==null?void 0:p.defaultKind,A=Zi(_,f,{},h);U(A.csv),B(A.warnings);const P=A.csv.trim().split(`
3271
- `);if(P.length<2){O(["No rows to preview after applying mappings."]),R([]),a("preview");return}const Y=P[0].split(",").map(z=>z.replace(/^"|"$/g,"").trim()),re=[],Z=[];P.slice(1,21).forEach((z,se)=>{const xe=z.split(",").map(be=>be.replace(/^"|"$/g,"").trim()),ue={rowIndex:se+1,id:"",name:"",kind:"",doc:""};Y.forEach((be,V)=>{ue[be]=xe[V]??""}),ue.id||Z.push(`Row ${se+2}: missing id`),ue.name||Z.push(`Row ${se+2}: missing name`),ue.kind||Z.push(`Row ${se+2}: missing kind`),re.push(ue)}),R(re),O(Z),a("preview")},[_,f,p]),L=u.useCallback(()=>{H&&($(!0),s(),Qo({elementsCsv:H,packageName:x||"bulk_import"}))},[H,x,s]),F=u.useCallback((h,A)=>{D(P=>P.map((Y,re)=>re===h?{...Y,targetAttribute:A}:Y))},[]);if(!e)return null;const q={input:"1 · Input",mapping:"2 · Map columns",preview:"3 · Preview & Import"},K=["input","mapping","preview"],ne=K.indexOf(l);return t.jsx("div",{ref:i,className:"fixed inset-0 z-50 flex items-center justify-center",style:{background:"rgba(0,0,0,0.35)"},onMouseDown:h=>{h.target===i.current&&ae()},children:t.jsxs("div",{className:"flex flex-col rounded-2xl overflow-hidden",style:{width:680,maxHeight:"90vh",background:"#FFFFFF",boxShadow:"0 24px 64px rgba(0,0,0,0.18)",border:"1px solid #E5E5E0"},children:[t.jsxs("div",{className:"flex items-center justify-between px-6 py-4",style:{background:"linear-gradient(135deg, #1B3A4B, #2D6A7A)",flexShrink:0},children:[t.jsxs("div",{children:[t.jsx("h2",{style:{fontSize:"15px",fontWeight:700,color:"#2DD4A8",margin:0},children:"Bulk Import Elements"}),t.jsx("p",{style:{fontSize:"12px",color:"rgba(255,255,255,0.6)",margin:"2px 0 0"},children:"Import from CSV, Excel paste, or requirements spreadsheet"})]}),t.jsx("button",{onClick:ae,style:sa,children:"✕"})]}),t.jsx("div",{className:"flex",style:{borderBottom:"1px solid #F0F0EC",background:"#FAFAF8",flexShrink:0},children:K.map((h,A)=>t.jsx("div",{className:"flex-1 flex items-center justify-center py-2.5",style:{fontSize:C.xs,fontWeight:A===ne?700:400,color:A===ne?"#1B3A4B":A<ne?"#2D6A7A":"#9CA3AF",borderBottom:A===ne?"2px solid #2D6A7A":"2px solid transparent"},children:q[h]},h))}),t.jsxs("div",{className:"flex-1 overflow-y-auto px-6 py-5",style:{minHeight:0},children:[l==="input"&&t.jsxs("div",{className:"flex flex-col gap-4",children:[t.jsxs("div",{children:[t.jsx("label",{style:vt,children:"Artifact type (recipe preset)"}),t.jsxs("select",{value:(p==null?void 0:p.id)??"",onChange:h=>{const A=xn.find(P=>P.id===h.target.value)??null;m(A)},style:wt,children:[t.jsx("option",{value:"",children:"— Custom / no preset —"}),xn.map(h=>t.jsx("option",{value:h.id,children:h.name},h.id))]}),p&&t.jsx("p",{style:{fontSize:C.xs,color:"#6B7280",marginTop:4},children:p.description})]}),t.jsxs("div",{children:[t.jsxs("label",{style:vt,children:["Package name ",t.jsx("span",{style:{color:"#9CA3AF",fontWeight:400},children:"(for the generated .sysml file)"})]}),t.jsx("input",{type:"text",value:x,onChange:h=>b(h.target.value.replace(/[^a-zA-Z0-9_]/g,"_")),style:wt,placeholder:"bulk_import"})]}),t.jsxs("div",{children:[t.jsxs("label",{style:vt,children:["CSV data ",t.jsx("span",{style:{color:"#E74C3C"},children:"*"})]}),t.jsx("textarea",{value:d,onChange:h=>{c(h.target.value),y("")},placeholder:`Paste CSV or tab-separated data here.
3272
- First row must be the header.
3273
-
3274
- Example:
3275
- id,name,kind,doc
3276
- req_001,System shall be safe,Requirement,Safety requirement`,rows:10,style:{...wt,resize:"vertical",fontFamily:"monospace",fontSize:"12px",lineHeight:"1.5"}}),k&&t.jsx("p",{style:{fontSize:C.xs,color:"#E74C3C",marginTop:4},children:k})]}),t.jsxs("div",{className:"flex items-center gap-3",children:[t.jsx("span",{style:{fontSize:C.xs,color:"#6B7280"},children:"or upload a file:"}),t.jsxs("label",{style:{cursor:"pointer",padding:"4px 12px",borderRadius:6,background:"#F3F4F6",border:"1px solid #E5E5E0",fontSize:C.xs,color:"#374151"},children:["Browse…",t.jsx("input",{type:"file",accept:".csv,.tsv,.txt",style:{display:"none"},onChange:I})]}),d&&t.jsxs("span",{style:{fontSize:C.xs,color:"#6B7280"},children:[d.split(`
3277
- `).length," line(s) loaded"]})]})]}),l==="mapping"&&t.jsxs("div",{className:"flex flex-col gap-3",children:[t.jsxs("p",{style:{fontSize:C.xs,color:"#6B7280",margin:0},children:["Map each source column to a MEMO attribute. ",t.jsx("strong",{children:"id"}),", ",t.jsx("strong",{children:"name"}),", and ",t.jsx("strong",{children:"kind"})," are required. Unrecognised columns are passed through as dynamic attributes."]}),t.jsxs("div",{style:{border:"1px solid #E5E5E0",borderRadius:8,overflow:"hidden"},children:[t.jsxs("div",{className:"flex",style:{background:"#F8F8F5",padding:"8px 12px",borderBottom:"1px solid #E5E5E0"},children:[t.jsx("span",{style:{flex:1,fontSize:C.xs,fontWeight:600,color:"#374151"},children:"Source column"}),t.jsx("span",{style:{flex:1,fontSize:C.xs,fontWeight:600,color:"#374151"},children:"Maps to"}),t.jsx("span",{style:{width:80,fontSize:C.xs,fontWeight:600,color:"#374151"},children:"Transform"})]}),f.map((h,A)=>{const P=["id","name","kind"].includes(h.targetAttribute),Y=!h.targetAttribute,re=f.filter((z,se)=>se!==A&&["id","name","kind","doc","construct"].includes(z.targetAttribute)).map(z=>z.targetAttribute),Z=vn.filter(z=>z==="— skip —"||!re.includes(z)||z===h.targetAttribute);return t.jsxs("div",{className:"flex items-center",style:{padding:"6px 12px",borderBottom:A<f.length-1?"1px solid #F0F0EC":"none",background:P?"#F0FDF4":"transparent"},children:[t.jsx("div",{style:{flex:1,fontSize:C.xs,color:"#374151",fontFamily:"monospace"},children:h.sourceColumn}),t.jsx("div",{style:{flex:1,paddingRight:8},children:t.jsxs("select",{value:h.targetAttribute||"",onChange:z=>F(A,z.target.value==="— skip —"?"":z.target.value),style:{width:"100%",fontSize:C.xs,padding:"3px 6px",borderRadius:5,border:`1px solid ${Y?"#E5E5E0":P?"#22C55E":"#E5E5E0"}`,background:Y?"#F9FAFB":"#FFFFFF",color:Y?"#9CA3AF":"#1a1a1a"},children:[Z.map(z=>t.jsx("option",{value:z,children:z},z)),h.targetAttribute&&!vn.includes(h.targetAttribute)&&t.jsx("option",{value:h.targetAttribute,children:h.targetAttribute})]})}),t.jsx("div",{style:{width:80,fontSize:"10px",color:"#9CA3AF"},children:h.transform??"—"})]},A)})]}),_.length>0&&t.jsxs("details",{children:[t.jsxs("summary",{style:{fontSize:C.xs,color:"#6B7280",cursor:"pointer",marginTop:4},children:["Show raw data sample (",Math.min(_.length,3)," of ",_.length," rows)"]}),t.jsx("div",{style:{marginTop:6,overflowX:"auto"},children:t.jsxs("table",{style:{fontSize:"10px",borderCollapse:"collapse",width:"100%"},children:[t.jsx("thead",{children:t.jsx("tr",{children:v.map(h=>t.jsx("th",{style:Re,children:h},h))})}),t.jsx("tbody",{children:_.slice(0,3).map((h,A)=>t.jsx("tr",{children:v.map(P=>t.jsx("td",{style:ze,children:h[P]??""},P))},A))})]})})]})]}),l==="preview"&&t.jsxs("div",{className:"flex flex-col gap-4",children:[T.length>0&&t.jsxs("div",{style:{background:"#FEF2F2",border:"1px solid #FECACA",borderRadius:8,padding:"10px 14px"},children:[t.jsxs("p",{style:{fontSize:C.xs,fontWeight:700,color:"#DC2626",margin:"0 0 4px"},children:[T.length," validation error(s) — rows with missing required fields will be skipped"]}),T.slice(0,5).map((h,A)=>t.jsx("p",{style:{fontSize:"11px",color:"#DC2626",margin:"1px 0"},children:h},A)),T.length>5&&t.jsxs("p",{style:{fontSize:"11px",color:"#DC2626",margin:"2px 0 0"},children:["+",T.length-5," more…"]})]}),j.length>0&&t.jsxs("div",{style:{background:"#FFFBEB",border:"1px solid #FDE68A",borderRadius:8,padding:"10px 14px"},children:[t.jsxs("p",{style:{fontSize:C.xs,fontWeight:700,color:"#D97706",margin:"0 0 4px"},children:[j.length," warning(s)"]}),j.slice(0,3).map((h,A)=>t.jsx("p",{style:{fontSize:"11px",color:"#D97706",margin:"1px 0"},children:h},A))]}),n&&t.jsxs("div",{style:{background:n.success?"#F0FDF4":"#FEF2F2",border:`1px solid ${n.success?"#86EFAC":"#FECACA"}`,borderRadius:8,padding:"12px 14px"},children:[t.jsx("p",{style:{fontSize:C.xs,fontWeight:700,margin:"0 0 4px",color:n.success?"#16A34A":"#DC2626"},children:n.success?`Import complete — ${n.elementsImported} element(s) written to ${n.generatedFile??"model"}`:"Import failed"}),n.errors.map((h,A)=>t.jsx("p",{style:{fontSize:"11px",color:"#DC2626",margin:"1px 0"},children:h},A)),n.warnings.slice(0,3).map((h,A)=>t.jsx("p",{style:{fontSize:"11px",color:"#D97706",margin:"1px 0"},children:h},A))]}),E.length>0&&t.jsxs(t.Fragment,{children:[t.jsxs("p",{style:{fontSize:C.xs,color:"#6B7280",margin:0},children:["Showing first ",E.length," of ",_.length," row(s)",_.length>E.length&&` (+${_.length-E.length} more will be imported)`]}),t.jsx("div",{style:{overflowX:"auto",borderRadius:8,border:"1px solid #E5E5E0"},children:t.jsxs("table",{style:{fontSize:"11px",borderCollapse:"collapse",width:"100%"},children:[t.jsx("thead",{children:t.jsxs("tr",{style:{background:"#F8F8F5"},children:[t.jsx("th",{style:Re,children:"#"}),t.jsx("th",{style:Re,children:"id"}),t.jsx("th",{style:Re,children:"name"}),t.jsx("th",{style:Re,children:"kind"}),t.jsx("th",{style:Re,children:"doc"})]})}),t.jsx("tbody",{children:E.map(h=>{const A=!h.id||!h.name||!h.kind;return t.jsxs("tr",{style:{background:A?"#FEF9F9":"transparent"},children:[t.jsx("td",{style:Sn,children:h.rowIndex}),t.jsx("td",{style:{...Sn,color:h.id?"#1a1a1a":"#DC2626"},children:h.id||"⚠ missing"}),t.jsx("td",{style:{...ze,maxWidth:160,overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap"},children:String(h.name||"—")}),t.jsx("td",{style:{...ze,color:h.kind?"#1B3A4B":"#DC2626"},children:h.kind||"⚠ missing"}),t.jsx("td",{style:{...ze,maxWidth:180,overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap",color:"#6B7280"},children:String(h.doc||"—")})]},h.rowIndex)})})]})})]}),E.length===0&&T.length===0&&t.jsx("p",{style:{fontSize:C.xs,color:"#9CA3AF",textAlign:"center",padding:"24px 0"},children:"No rows to preview."})]})]}),t.jsxs("div",{className:"flex items-center justify-between px-6 py-4",style:{borderTop:"1px solid #F0F0EC",background:"#FAFAF8",flexShrink:0},children:[t.jsx("div",{className:"flex gap-2",children:l!=="input"&&!n&&t.jsx("button",{onClick:()=>a(K[ne-1]),style:wn,children:"← Back"})}),t.jsxs("div",{className:"flex gap-2 items-center",children:[t.jsx("button",{onClick:ae,style:wn,children:n!=null&&n.success?"Done":"Cancel"}),!n&&t.jsxs(t.Fragment,{children:[l==="input"&&t.jsx("button",{onClick:W,style:St,children:"Next →"}),l==="mapping"&&t.jsx("button",{onClick:G,style:St,children:"Preview →"}),l==="preview"&&t.jsx("button",{onClick:L,disabled:X||E.length===0,style:{...St,opacity:X||E.length===0?.5:1,cursor:X||E.length===0?"not-allowed":"pointer"},children:X?"Importing…":`Import ${_.length} element(s)`})]})]})]})]})})}const vt={display:"block",fontSize:C.xs,fontWeight:600,color:"#374151",marginBottom:6},wt={width:"100%",padding:"7px 10px",borderRadius:8,border:"1px solid #E5E5E0",fontSize:C.sm,color:"#1a1a1a",background:"#FAFAF8",boxSizing:"border-box"},sa={background:"rgba(255,255,255,0.12)",border:"none",borderRadius:8,color:"rgba(255,255,255,0.8)",cursor:"pointer",padding:"6px 10px",fontSize:"14px"},St={padding:"7px 18px",borderRadius:8,background:"#1B3A4B",border:"none",color:"#FFFFFF",fontSize:C.xs,fontWeight:600,cursor:"pointer"},wn={padding:"7px 14px",borderRadius:8,background:"transparent",border:"1px solid #E5E5E0",color:"#374151",fontSize:C.xs,cursor:"pointer"},Re={padding:"5px 8px",textAlign:"left",fontWeight:600,fontSize:"10px",color:"#6B7280",borderBottom:"1px solid #E5E5E0",whiteSpace:"nowrap"},ze={padding:"4px 8px",fontSize:"11px",color:"#1a1a1a",borderBottom:"1px solid #F5F5F2"},Sn={...ze,fontFamily:"monospace",fontSize:"10px",color:"#6B7280"};function ia(){var a,d;const e=S(c=>c.activeView),r=S(c=>c.model),n=S(c=>c.selectedElementId),s=S(c=>c.selectElement),o=S(c=>c.setActiveView),i=Ce(),l=[];switch(e.type){case"diagram":{const c=Yn(r,e.diagramId);if(c){const p=c.viewpointId==="__model"?"Model Viewpoint":((d=(a=r==null?void 0:r.viewpoints)==null?void 0:a.find(k=>k.id===c.viewpointId))==null?void 0:d.label)||c.viewpointId;l.push({label:p});const m=c.viewKind?hs[c.viewKind]:void 0,x=Ae[c.diagramType],b=(m==null?void 0:m.label)??(x==null?void 0:x.code)??c.diagramType;l.push({label:`${b}: ${c.name}`})}break}case"element-detail":{const c=e.elementId,p=r==null?void 0:r.elements[c];if(p){const m=p.shortId??p.id,x=m.split("-")[0];l.push({label:"Catalog",onClick:()=>i("/catalog")}),l.push({label:x,onClick:()=>i(`/catalog/${x}`)}),l.push({label:`${m} ${p.name}`})}break}case"dsm":l.push({label:"Tools"}),l.push({label:"DSM"});break;case"traceability":l.push({label:"Tools"}),l.push({label:"Traceability Matrix"});break;case"ontology":l.push({label:"Tools"}),l.push({label:"Ontology"});break}if(n&&r&&e.type!=="element-detail"){const c=r.elements[n];c&&l.push({label:c.name,onClick:()=>s(c.id)})}return l.length===0?null:t.jsxs("div",{className:"flex items-center gap-1 px-4 py-1.5",style:{background:"#FAFAF8",borderBottom:"1px solid #E5E5E0"},children:[t.jsx("button",{className:"text-xs px-1 py-0.5 rounded transition-colors",style:{color:"#9CA3AF"},onMouseEnter:c=>{c.currentTarget.style.color="#374151",c.currentTarget.style.background="#F0F0ED"},onMouseLeave:c=>{c.currentTarget.style.color="#9CA3AF",c.currentTarget.style.background="transparent"},onClick:()=>o({type:"welcome"}),title:"Home",children:"⌂"}),l.map((c,p)=>t.jsxs("span",{className:"flex items-center gap-1",children:[t.jsx("span",{className:"text-xs",style:{color:"#D1D5DB"},children:"/"}),c.onClick?t.jsx("button",{className:"text-xs px-1 py-0.5 rounded transition-colors",style:{color:"#374151"},onMouseEnter:m=>m.currentTarget.style.background="#F0F0ED",onMouseLeave:m=>m.currentTarget.style.background="transparent",onClick:c.onClick,children:c.label}):t.jsx("span",{className:"text-xs",style:{color:p===l.length-1?"#374151":"#9CA3AF"},children:c.label})]},p)),t.jsx("div",{className:"flex-1"}),t.jsxs("kbd",{className:"px-1.5 py-0.5 rounded text-xs",style:{background:"#F0F0ED",color:"#9CA3AF",fontSize:"9px"},children:["⌘","K"]})]})}const kn="memo-onboarding-completed",Pe=[{title:"Welcome to MEMO Architect",description:"MEMO is a model-based systems engineering tool for medical devices. You'll land on the Dashboard — it shows your model health and suggests the next action. Let's take a quick tour.",target:"center",position:"center"},{title:"Model Explorer",description:"Browse your model elements organized by architecture layer. Switch to Views tab to see diagrams grouped by viewpoint.",target:"left panel",position:"left"},{title:"Unified Canvas",description:"The center area renders your selected view — diagrams, action flows, DSM matrices, and more.",target:"center canvas",position:"center"},{title:"Properties Panel",description:"View and edit element properties, relationships, and attributes. Select any element to see its details.",target:"right panel",position:"right"},{title:"Tools Menu",description:"Access analysis tools from the toolbar: DSM, Trace Matrix, Action Flow, Ontology, Scenarios, Diff, Compliance, and Stats.",target:"toolbar",position:"center"},{title:"Command Palette",description:"Press Cmd+K (or Ctrl+K) to quickly search elements, diagrams, viewpoints, and tools.",target:"keyboard shortcut",position:"center"},{title:"Working Sets",description:"Save and restore your workspace layout using the Sets tab in the Explorer panel. Great for switching between review contexts.",target:"explorer sets tab",position:"left"},{title:"You're all set!",description:"Start from the Dashboard — it shows your model status and suggests the next step. Use the Workflow Wizard (Tools menu) for a guided path through requirements, risk, and verification.",target:"center",position:"center"}];function aa(){const[e,r]=u.useState(!1),[n,s]=u.useState(0);u.useEffect(()=>{try{if(!localStorage.getItem(kn)){const x=setTimeout(()=>r(!0),800);return()=>clearTimeout(x)}}catch{}},[]);const o=u.useCallback(()=>{r(!1);try{localStorage.setItem(kn,"true")}catch{}},[]),i=u.useCallback(()=>{n>=Pe.length-1?o():s(n+1)},[n,o]),l=u.useCallback(()=>{n>0&&s(n-1)},[n]);if(!e)return null;const a=Pe[n],d=n===Pe.length-1,c=n===0,p=()=>{switch(a.position){case"left":return{left:"300px",top:"50%",transform:"translateY(-50%)"};case"right":return{right:"300px",top:"50%",transform:"translateY(-50%)"};case"bottom":return{left:"50%",bottom:"80px",transform:"translateX(-50%)"};case"center":default:return{left:"50%",top:"50%",transform:"translate(-50%, -50%)"}}};return t.jsxs(t.Fragment,{children:[t.jsx("div",{className:"fixed inset-0 z-50",style:{background:"rgba(0,0,0,0.4)",backdropFilter:"blur(2px)"},onClick:o}),t.jsxs("div",{className:"fixed z-50 rounded-xl p-5 max-w-sm",style:{...p(),background:"#FFFFFF",boxShadow:"0 8px 32px rgba(0,0,0,0.2)",border:"1px solid #E5E5E0"},onClick:m=>m.stopPropagation(),children:[t.jsx("div",{className:"flex items-center gap-1 mb-3",children:Pe.map((m,x)=>t.jsx("div",{className:"h-1 rounded-full transition-all",style:{width:x===n?"20px":"8px",background:x===n?"#2DD4A8":x<n?"#2DD4A880":"#E5E5E0"}},x))}),t.jsx("h3",{className:"text-sm font-semibold mb-1.5",style:{color:"#1B3A4B"},children:a.title}),t.jsx("p",{className:"text-xs leading-relaxed mb-4",style:{color:"#6B7280"},children:a.description}),t.jsxs("div",{className:"flex items-center gap-2",children:[!c&&t.jsx("button",{onClick:l,className:"px-3 py-1.5 text-xs rounded-lg",style:{background:"#F3F4F6",color:"#6B7280"},children:"Back"}),t.jsx("div",{className:"flex-1"}),t.jsx("button",{onClick:o,className:"px-3 py-1.5 text-xs rounded-lg",style:{color:"#9CA3AF"},children:"Skip tour"}),t.jsx("button",{onClick:i,className:"px-4 py-1.5 text-xs font-medium rounded-lg",style:{background:"#2DD4A8",color:"#FFFFFF"},children:d?"Get started":"Next"})]}),t.jsxs("div",{className:"text-center mt-2",style:{color:"#D1D5DB",fontSize:"10px"},children:[n+1," of ",Pe.length]})]})]})}function la(){const e=S(n=>n.restartRequired);if(!e)return null;const r=e.reason==="ontology-selection-changed"?"Ontology selection changed":"Ontology source changed";return t.jsx("div",{style:{position:"fixed",inset:0,zIndex:9999,display:"flex",alignItems:"center",justifyContent:"center",background:"rgba(15, 23, 42, 0.85)",backdropFilter:"blur(4px)"},children:t.jsxs("div",{style:{background:"#1E293B",border:"1px solid #F59E0B",borderRadius:"12px",padding:"32px 40px",maxWidth:"480px",width:"90%",textAlign:"center",color:"#F8FAFC",boxShadow:"0 25px 50px rgba(0,0,0,0.5)"},children:[t.jsx("div",{style:{fontSize:"2rem",marginBottom:"12px"},children:"⚠️"}),t.jsx("div",{style:{fontSize:"1.1rem",fontWeight:600,marginBottom:"8px",color:"#F59E0B"},children:"Restart Required"}),t.jsx("div",{style:{fontSize:"0.875rem",color:"#CBD5E1",marginBottom:"4px"},children:r}),t.jsx("div",{style:{fontSize:"0.75rem",color:"#94A3B8",marginBottom:"24px",fontFamily:"monospace"},children:e.changedFile}),t.jsx("div",{style:{fontSize:"0.875rem",color:"#E2E8F0",marginBottom:"24px",lineHeight:1.6},children:e.instruction}),t.jsx("div",{style:{display:"flex",gap:"12px",justifyContent:"center"},children:t.jsx("button",{onClick:()=>window.location.reload(),style:{background:"#F59E0B",color:"#0F172A",border:"none",borderRadius:"6px",padding:"8px 20px",fontWeight:600,fontSize:"0.875rem",cursor:"pointer"},children:"Reload page"})})]})})}const En={Hazard:"HZD",HazardousEvent:"HZD-EVT",HazardousSituation:"HZD-SIT",Risk:"RISK",RiskControl:"RISK-CTL",MitigationMeasure:"MIT",ResidualRisk:"RRISK",StakeholderRequirement:"STK-REQ",Requirement:"REQ",SoftwareSpecification:"SW-SPEC",InterfaceRequirement:"REQ",PerformanceRequirement:"PERF-REQ",SafetyRequirement:"SAF-REQ",RegulatoryRequirement:"REG-REQ",FunctionalRequirement:"REQ",NonFunctionalRequirement:"NFR",SystemComponent:"SYS-COMP",SoftwareComponent:"SW-COMP",HardwareComponent:"HW-COMP",Subsystem:"SUBSYS",Module:"MOD",Interface:"IF",Port:"PORT",Action:"ACT",ActionDefinition:"ACT-DEF",UseCase:"UC",Stakeholder:"STK",OperationalScenario:"OPS",Mission:"MSNS",Capability:"CAP",DesignInput:"DI",DesignOutput:"DO",VerificationActivity:"VER",ValidationActivity:"VAL",TestCase:"TC",Item:"ITM",Part:"PART"};function ca(e){return e.length<=3?e.toUpperCase():(e[0]+e.slice(1).replace(/[aeiouAEIOU]/g,"")).slice(0,3).toUpperCase()}function da(e){if(En[e])return En[e];const r=e.replace(/([A-Z])/g," $1").trim().split(" ").filter(Boolean);return r.length===0?"EL":r.map(ca).join("-")}function ua(e){return e.split("-")[0]}function pa(e){return`/catalog/${e.split("-")[0]}/${e}`}function ma(e){return`/catalog/${e}`}function fa(){const e=S(o=>o.model),r=Ce(),n=u.useMemo(()=>{if(!e)return[];const o={};for(const i of Object.values(e.elements)){const l=da(i.kind),a=ua(l);o[a]||(o[a]={count:0,kinds:new Set,layer:i.layer}),o[a].count++,o[a].kinds.add(i.kind)}return Object.entries(o).sort((i,l)=>l[1].count-i[1].count)},[e]);if(!e)return t.jsx("div",{style:{flex:1,display:"flex",alignItems:"center",justifyContent:"center",background:"#F7F7F5"},children:t.jsx("p",{style:{color:g.muted,fontSize:C.sm},children:"Loading…"})});const s=Object.keys(e.elements).length;return t.jsxs("div",{style:{flex:1,overflow:"auto",background:"#F7F7F5",padding:"32px 40px"},children:[t.jsx("h1",{style:{fontSize:"20px",fontWeight:700,color:g.primary,marginBottom:"4px",marginTop:0},children:"Catalog"}),t.jsxs("p",{style:{color:g.muted,fontSize:C.sm,marginTop:0,marginBottom:"24px"},children:[s," elements across ",n.length," families"]}),t.jsx("div",{style:{display:"grid",gridTemplateColumns:"repeat(auto-fill, minmax(200px, 1fr))",gap:"12px"},children:n.map(([o,i])=>{const l=ie[i.layer]??"#9CA3AF";return t.jsx(ha,{family:o,count:i.count,kinds:i.kinds,color:l,onClick:()=>r(ma(o))},o)})})]})}function ha({family:e,count:r,kinds:n,color:s,onClick:o}){return t.jsxs("div",{onClick:o,style:{background:g.surface,border:`1px solid ${g.border}`,borderRadius:"10px",padding:"16px",cursor:"pointer",transition:"box-shadow 0.15s, border-color 0.15s",borderTop:`3px solid ${s}`},onMouseEnter:i=>{i.currentTarget.style.boxShadow="0 4px 12px rgba(0,0,0,0.08)",i.currentTarget.style.borderTopColor=s},onMouseLeave:i=>{i.currentTarget.style.boxShadow="none"},children:[t.jsx("div",{style:{fontWeight:700,fontSize:"15px",color:g.primary,marginBottom:"4px"},children:e}),t.jsx("div",{style:{fontSize:"22px",fontWeight:800,color:s,lineHeight:1,marginBottom:"6px"},children:r}),t.jsxs("div",{style:{fontSize:"11px",color:g.muted,lineHeight:"1.5"},children:[Array.from(n).slice(0,3).join(", "),n.size>3&&` +${n.size-3} more`]})]})}function ga({family:e}){const r=S(d=>d.model),n=Ce(),[s,o]=u.useState(""),i=u.useMemo(()=>r?Object.values(r.elements).filter(d=>{const c=d.shortId??"";return c.startsWith(e+"-")||c.startsWith(e+" ")}):[],[r,e]),l=u.useMemo(()=>{if(!s.trim())return i;const d=s.toLowerCase();return i.filter(c=>c.name.toLowerCase().includes(d)||(c.shortId??"").toLowerCase().includes(d)||c.kind.toLowerCase().includes(d))},[i,s]),a=u.useMemo(()=>{const d={};for(const c of i)d[c.kind]=(d[c.kind]??0)+1;return d},[i]);return r?i.length===0?t.jsx(kt,{family:e,children:t.jsxs("p",{style:{color:g.muted,fontSize:C.sm},children:["No elements found with family prefix ",t.jsx("code",{children:e}),"."]})}):t.jsxs(kt,{family:e,children:[t.jsx("div",{style:{display:"flex",flexWrap:"wrap",gap:"6px",marginBottom:"16px"},children:Object.entries(a).map(([d,c])=>{const p=ie[d]??"#9CA3AF";return t.jsxs("span",{style:{fontSize:C.xs,padding:"2px 8px",borderRadius:"12px",background:p+"20",color:p,border:`1px solid ${p}40`,fontWeight:500},children:[d," · ",c]},d)})}),t.jsx("input",{type:"search",placeholder:`Search ${i.length} elements…`,value:s,onChange:d=>o(d.target.value),style:{width:"100%",boxSizing:"border-box",padding:"7px 12px",fontSize:C.sm,border:`1px solid ${g.border}`,borderRadius:"6px",background:g.surface,color:g.primary,outline:"none",marginBottom:"12px"}}),t.jsxs("div",{style:{background:g.surface,border:`1px solid ${g.border}`,borderRadius:"8px",overflow:"hidden"},children:[t.jsxs("div",{style:{display:"grid",gridTemplateColumns:"140px 1fr 120px 120px",padding:"8px 16px",background:g.surfaceAlt,borderBottom:`1px solid ${g.border}`,fontSize:C.xs,fontWeight:600,color:g.muted,gap:"12px"},children:[t.jsx("span",{children:"ID"}),t.jsx("span",{children:"Name"}),t.jsx("span",{children:"Kind"}),t.jsx("span",{children:"Layer"})]}),l.length===0?t.jsxs("div",{style:{padding:"24px 16px",color:g.muted,fontSize:C.sm,textAlign:"center"},children:['No results for "',s,'"']}):l.map((d,c)=>t.jsx(ya,{element:d,zebra:c%2===1,onClick:()=>n(pa(d.shortId??d.id))},d.id))]}),t.jsxs("p",{style:{color:g.faint,fontSize:"11px",marginTop:"8px"},children:[l.length," of ",i.length," elements shown"]})]}):t.jsx(kt,{family:e,children:t.jsx("p",{style:{color:g.muted,fontSize:C.sm},children:"Loading model…"})})}function ya({element:e,zebra:r,onClick:n}){const s=ie[e.layer]??"#9CA3AF";return t.jsxs("div",{onClick:n,style:{display:"grid",gridTemplateColumns:"140px 1fr 120px 120px",padding:"10px 16px",gap:"12px",background:r?"#FAFAF8":g.surface,cursor:"pointer",borderBottom:`1px solid ${g.borderLight}`,alignItems:"center",transition:"background 0.1s"},onMouseEnter:o=>o.currentTarget.style.background="#F0FDF4",onMouseLeave:o=>o.currentTarget.style.background=r?"#FAFAF8":g.surface,children:[t.jsx("code",{style:{fontSize:"11px",color:"#2DD4A8",fontWeight:600,fontFamily:"monospace"},children:e.shortId??e.id}),t.jsx("span",{style:{fontSize:C.sm,color:g.primary,fontWeight:500,overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap"},children:e.name}),t.jsx("span",{style:{fontSize:C.xs,color:g.secondary},children:e.kind}),t.jsx("span",{style:{fontSize:"11px",color:s,fontWeight:500,background:s+"15",padding:"2px 6px",borderRadius:"4px",width:"fit-content"},children:e.layer})]})}function kt({family:e,children:r}){const n=Ce();return t.jsxs("div",{style:{flex:1,overflow:"auto",background:"#F7F7F5",padding:"32px 40px"},children:[t.jsxs("nav",{style:{fontSize:C.xs,color:g.muted,marginBottom:"20px"},children:[t.jsx("button",{onClick:()=>n("/catalog"),style:{background:"none",border:"none",color:"#2DD4A8",cursor:"pointer",padding:0,fontSize:C.xs},children:"Catalog"})," / ",t.jsx("span",{style:{color:g.primary,fontWeight:600},children:e})]}),t.jsx("h1",{style:{fontSize:"20px",fontWeight:700,color:g.primary,marginBottom:"6px",marginTop:0},children:e}),r]})}const xa=u.lazy(()=>te(()=>import("./DiagramEditor-CEr6iqBf.js"),__vite__mapDeps([0,1,2,3])).then(e=>({default:e.DiagramEditor}))),ba=u.lazy(()=>te(()=>import("./DiagramSurface-B_lfUNzV.js"),__vite__mapDeps([3,1,2])).then(e=>({default:e.DiagramSurface}))),va=u.lazy(()=>te(()=>import("./DSMView-B4IEz19F.js"),__vite__mapDeps([4,1,2])).then(e=>({default:e.DSMView}))),wa=u.lazy(()=>te(()=>import("./OntologyViewer-72jTw72H.js"),__vite__mapDeps([5,1,2])).then(e=>({default:e.OntologyViewer}))),Sa=u.lazy(()=>te(()=>import("./TraceabilityMatrix-BAJb0X7G.js"),__vite__mapDeps([6,1,2])).then(e=>({default:e.TraceabilityMatrix}))),ka=u.lazy(()=>te(()=>import("./ScenarioEditor-CvOkiRC6.js"),__vite__mapDeps([7,1,2])).then(e=>({default:e.ScenarioEditor}))),Ea=u.lazy(()=>te(()=>import("./ModelDiff-CLFqnELG.js"),__vite__mapDeps([8,1,2])).then(e=>({default:e.ModelDiff}))),Ca=u.lazy(()=>te(()=>import("./ComplianceWizard-BNvT_ic6.js"),__vite__mapDeps([9,1,2])).then(e=>({default:e.ComplianceWizard}))),ja=u.lazy(()=>te(()=>import("./StatisticsDashboard-Dn6lsnKe.js"),__vite__mapDeps([10,1,2])).then(e=>({default:e.StatisticsDashboard}))),Da=u.lazy(()=>te(()=>import("./DhfDashboard-DguH-rDT.js"),__vite__mapDeps([11,1,2])).then(e=>({default:e.DhfDashboard}))),Aa=u.lazy(()=>te(()=>import("./DhfWorkbench-4gHayn-l.js"),__vite__mapDeps([12,1,2])).then(e=>({default:e.DhfWorkbench}))),Fa=u.lazy(()=>te(()=>import("./AskPanel-D9_AKyYt.js"),__vite__mapDeps([13,1,2])).then(e=>({default:e.AskPanel}))),Ra=u.lazy(()=>te(()=>import("./SysmlGenerator-CfBQWovl.js"),__vite__mapDeps([14,1,2])).then(e=>({default:e.SysmlGenerator}))),er=u.lazy(()=>te(()=>import("./ElementDetailView-AclSjurg.js"),__vite__mapDeps([15,1,2])).then(e=>({default:e.ElementDetailView}))),_a=u.lazy(()=>te(()=>import("./Dashboard-DNRzU1Hk.js"),__vite__mapDeps([16,1,2])).then(e=>({default:e.Dashboard}))),Ta=u.lazy(()=>te(()=>import("./ReviewDashboard-BVOe2I5w.js"),__vite__mapDeps([17,1,2])).then(e=>({default:e.ReviewDashboard}))),Ia=u.lazy(()=>te(()=>import("./WorkflowWizard-C38DZKOe.js"),__vite__mapDeps([18,1,2])).then(e=>({default:e.WorkflowWizard}))),Na=u.lazy(()=>te(()=>import("./TabularView-B99xy3H3.js"),__vite__mapDeps([19,1,2])).then(e=>({default:e.TabularView}))),Oa=u.lazy(()=>te(()=>import("./ImportView-t1dIoZF5.js"),__vite__mapDeps([20,1,2])).then(e=>({default:e.ImportView})));function Ma(){const e=S(o=>o.activeView);S(o=>o.selectedViewpointId);const r=S(o=>o.selectedDiagramId),n=S(o=>o.selectDiagram);u.useEffect(()=>{e.type==="diagram"&&r!==e.diagramId&&n(e.diagramId)},[e,r,n]);const s=()=>{switch(e.type){case"diagram":return t.jsx(xa,{diagramId:e.diagramId});case"dsm":return t.jsx(va,{});case"traceability":return t.jsx(Sa,{});case"tabular":return t.jsx(Na,{});case"ontology":case"ontology-detail":return t.jsx(wa,{});case"scenario-editor":return t.jsx(ka,{});case"model-diff":return t.jsx(Ea,{});case"compliance-wizard":return t.jsx(Ca,{});case"statistics":return t.jsx(ja,{});case"dhf-dashboard":case"dhf-document":return t.jsx(Aa,{});case"dhf-dashboard-legacy":return t.jsx(Da,{});case"ask":return t.jsx(Fa,{});case"sysml-generator":return t.jsx(Ra,{});case"element-detail":return t.jsx(er,{});case"dashboard":return t.jsx(_a,{});case"review-dashboard":return t.jsx(Ta,{});case"workflow-wizard":return t.jsx(Ia,{});case"import":return t.jsx(Oa,{});case"welcome":default:return t.jsx(Cn,{})}};return(e.type==="welcome"||e.type==="dashboard")&&e.type==="welcome"?t.jsx(Cn,{}):t.jsx(u.Suspense,{fallback:t.jsx(Lt,{}),children:s()})}function Lt(){return t.jsx("div",{className:"flex-1 flex items-center justify-center",style:{background:"#F7F7F5"},children:t.jsxs("div",{className:"text-center",style:{color:"#9CA3AF"},children:[t.jsx("img",{src:"/logo.png",alt:"MEMO Logo",style:{width:"180px",marginBottom:"24px",opacity:.4,filter:"grayscale(1)"},className:"animate-pulse"}),t.jsx("div",{className:"text-xs mt-2",children:"Loading view..."})]})})}const nt="linear-gradient(135deg, #EEF7F3 0%, #EAF2F8 55%, #F2EEF8 100%)";function Cn(){var d;const e=S(c=>c.model),r=S(c=>c.setActiveView),n=S(c=>c.selectElement),s=S(c=>c.setExplorerTab),o=((d=e==null?void 0:e.diagrams)==null?void 0:d.length)??0,i=e?Object.keys(e.elements).length:0,l=u.useMemo(()=>{if(!e)return[];const c=new Map;for(const p of Object.values(e.elements))c.has(p.kind)||c.set(p.kind,p);return Array.from(c.values()).slice(0,8)},[e]);function a(c){n(c),r({type:"element-detail",elementId:c})}return t.jsxs("div",{className:"flex-1 flex flex-col items-center justify-center overflow-auto",style:{background:nt,padding:"48px 40px"},children:[t.jsx("img",{src:"/logo.png",alt:"MEMO Logo",style:{width:"520px",maxWidth:"80vw",maxHeight:"40vh",objectFit:"contain",marginBottom:"-36px",opacity:.97}}),t.jsx("h2",{style:{fontSize:"18px",fontWeight:700,color:"#1B3A4B",marginBottom:"6px",marginTop:0},children:"MEMO Architect"}),t.jsx("p",{style:{fontSize:"14px",color:"#4B6E80",marginTop:0,marginBottom:"24px",maxWidth:"480px",textAlign:"center",lineHeight:"1.6"},children:"SysML-based medical device architecture tool, aligned with ISO 14971 and IEC 62304."}),i>0&&t.jsxs("div",{className:"flex items-center gap-4 mb-6",style:{fontSize:"13px",color:"#4B6E80"},children:[t.jsxs("span",{children:[t.jsx("strong",{style:{color:"#1B3A4B"},children:i})," elements"]}),t.jsx("span",{style:{color:"#CBD5DB"},children:"·"}),t.jsxs("span",{children:[t.jsx("strong",{style:{color:"#1B3A4B"},children:o})," diagrams"]}),(e==null?void 0:e.relationships)&&t.jsxs(t.Fragment,{children:[t.jsx("span",{style:{color:"#CBD5DB"},children:"·"}),t.jsxs("span",{children:[t.jsx("strong",{style:{color:"#1B3A4B"},children:e.relationships.length})," relationships"]})]})]}),t.jsxs("div",{className:"flex gap-3 mb-8",children:[t.jsx("button",{onClick:()=>s("model"),className:"px-5 py-2.5 text-sm font-semibold rounded-lg transition-all",style:{background:"#1B3A4B",color:"#FFFFFF",border:"none",cursor:"pointer"},onMouseEnter:c=>c.currentTarget.style.background="#244D63",onMouseLeave:c=>c.currentTarget.style.background="#1B3A4B",children:"Browse Model"}),o>0&&t.jsxs("button",{onClick:()=>s("views"),className:"px-5 py-2.5 text-sm font-semibold rounded-lg transition-all",style:{background:"#2DD4A815",color:"#1B3A4B",border:"1px solid #2DD4A840",cursor:"pointer"},onMouseEnter:c=>c.currentTarget.style.background="#2DD4A830",onMouseLeave:c=>c.currentTarget.style.background="#2DD4A815",children:["View Diagrams (",o,")"]})]}),l.length>0&&t.jsxs("div",{style:{width:"100%",maxWidth:"680px"},children:[t.jsx("div",{style:{fontSize:"11px",fontWeight:600,color:"#7A9BAA",textTransform:"uppercase",letterSpacing:"0.08em",marginBottom:"10px"},children:"Quick Browse"}),t.jsx("div",{style:{display:"grid",gridTemplateColumns:"repeat(auto-fill, minmax(180px, 1fr))",gap:"8px"},children:l.map(c=>t.jsxs("button",{onClick:()=>a(c.id),style:{textAlign:"left",background:"rgba(255,255,255,0.7)",border:"1px solid rgba(255,255,255,0.9)",borderRadius:"8px",padding:"10px 12px",cursor:"pointer",transition:"all 0.15s",backdropFilter:"blur(4px)"},onMouseEnter:p=>{p.currentTarget.style.background="rgba(255,255,255,0.95)",p.currentTarget.style.boxShadow="0 2px 8px rgba(0,0,0,0.08)",p.currentTarget.style.transform="translateY(-1px)"},onMouseLeave:p=>{p.currentTarget.style.background="rgba(255,255,255,0.7)",p.currentTarget.style.boxShadow="none",p.currentTarget.style.transform="none"},children:[t.jsx("div",{style:{fontSize:"10px",color:"#7A9BAA",fontWeight:600,textTransform:"uppercase",letterSpacing:"0.05em",marginBottom:"3px"},children:c.kind}),t.jsx("div",{style:{fontSize:"13px",color:"#1B3A4B",fontWeight:500,whiteSpace:"nowrap",overflow:"hidden",textOverflow:"ellipsis"},children:c.name}),c.shortId&&t.jsx("div",{style:{fontSize:"10px",color:"#9CB8C5",marginTop:"2px",fontFamily:"monospace"},children:c.shortId})]},c.id))})]})]})}function Pa(){const e=S(x=>x.connected),r=S(x=>x.model),n=S(x=>x.activeView),s=S(x=>x.selectedElementIds),{pathname:o}=ye(),i=o.startsWith("/catalog"),l=S(x=>x.activeMode),a=S(x=>x.sidebarCollapsed),d=S(x=>x.toggleSidebar),c=S(x=>x.toggleGapBar);u.useEffect(()=>{const x=b=>{(b.metaKey||b.ctrlKey)&&b.shiftKey&&b.key==="P"&&(b.preventDefault(),c())};return window.addEventListener("keydown",x),()=>window.removeEventListener("keydown",x)},[c]);const p=n.type!=="scenario-editor"&&n.type!=="dsm";u.useEffect(()=>{p&&a&&d()},[n.type]),u.useEffect(()=>{Vo()||Hn()},[]);const m=r?Object.keys(r.elements).length:0;return e?r?m===0?t.jsxs("div",{className:"flex flex-col h-screen",style:{background:nt,color:"#1a1a1a"},children:[t.jsx(Je,{}),t.jsx("div",{className:"flex-1 flex items-center justify-center",children:t.jsxs("div",{className:"text-center max-w-lg",style:{lineHeight:"1.7"},children:[t.jsx("img",{src:"/logo.png",alt:"MEMO Logo",style:{width:"380px",maxWidth:"80vw",display:"block",margin:"0 auto -20px auto",opacity:.35,filter:"grayscale(1)"}}),t.jsx("h2",{style:{fontSize:"20px",fontWeight:700,color:"#1B3A4B",marginBottom:"8px"},children:"Your model is empty"}),t.jsxs("p",{style:{fontSize:"14px",color:"#4B6E80",marginBottom:"20px"},children:["Connected successfully — but no ",t.jsx("code",{children:".sysml"})," elements found yet."]}),t.jsxs("div",{style:{textAlign:"left",background:"rgba(255,255,255,0.65)",borderRadius:"10px",padding:"16px 20px",fontSize:"13px",border:"1px solid rgba(255,255,255,0.9)"},children:[t.jsx("p",{style:{fontWeight:600,marginBottom:"8px",color:"#1B3A4B"},children:"Get started:"}),t.jsxs("ol",{style:{paddingLeft:"18px",margin:0,color:"#4B6E80"},children:[t.jsxs("li",{style:{marginBottom:"6px"},children:["Create a ",t.jsx("code",{children:".sysml"})," file in your ",t.jsx("code",{children:"model/"})," directory"]}),t.jsxs("li",{style:{marginBottom:"6px"},children:["Import from CSV: ",t.jsx("code",{children:"pnpm memo import template elements"})]}),t.jsxs("li",{children:["Scaffold a new project: ",t.jsx("code",{children:"pnpm memo init my-device"})]})]})]})]})})]}):t.jsxs("div",{className:"flex flex-col h-screen",style:{background:"#F7F7F5",color:"#1a1a1a"},children:[t.jsx(qa,{}),t.jsx(Je,{}),t.jsx(cs,{}),t.jsx(ia,{}),t.jsxs("div",{className:"flex flex-1 overflow-hidden",children:[p&&t.jsx(Mi,{}),t.jsx("div",{className:"flex-1 flex flex-col",style:{minWidth:0},children:t.jsxs(no,{children:[t.jsx(_e,{path:"/catalog",element:t.jsx(fa,{})}),t.jsx(_e,{path:"/catalog/:family",element:t.jsx(za,{})}),t.jsx(_e,{path:"/catalog/:family/:shortId",element:t.jsx(Ba,{})}),t.jsx(_e,{path:"/diagrams/:diagramType/:diagramId",element:t.jsx(La,{})}),t.jsx(_e,{path:"*",element:t.jsx(Ma,{})})]})}),n.type!=="element-detail"&&n.type!=="scenario-editor"&&n.type!=="ontology"&&n.type!=="ontology-detail"&&n.type!=="ask"&&n.type!=="sysml-generator"&&!i&&l!=="dhf"&&l!=="ontology"&&(s.size>=2?t.jsx(Ui,{}):t.jsx(Li,{}))]}),t.jsx($i,{}),t.jsx(Wi,{}),t.jsx(oa,{}),t.jsx(aa,{}),t.jsx(la,{})]}):t.jsxs("div",{className:"flex flex-col h-screen",style:{background:nt,color:"#1a1a1a"},children:[t.jsx(Je,{}),t.jsx("div",{className:"flex-1 flex items-center justify-center",children:t.jsxs("div",{className:"text-center",children:[t.jsx("img",{src:"/logo.png",alt:"MEMO Logo",style:{width:"360px",maxWidth:"80vw",display:"block",margin:"0 auto -20px auto",opacity:.45,filter:"grayscale(1)"},className:"animate-pulse"}),t.jsx("h2",{style:{fontSize:"18px",fontWeight:700,color:"#1B3A4B",marginBottom:"6px"},children:"MEMO Architect"}),t.jsx("p",{style:{color:"#6B7280",fontSize:"14px"},children:"Loading model data…"})]})})]}):t.jsxs("div",{className:"flex flex-col h-screen",style:{background:nt,color:"#1a1a1a"},children:[t.jsx(Je,{}),t.jsx("div",{className:"flex-1 flex items-center justify-center",children:t.jsxs("div",{className:"text-center max-w-md",children:[t.jsx("img",{src:"/logo.png",alt:"MEMO Logo",style:{width:"360px",maxWidth:"80vw",display:"block",margin:"0 auto -20px auto",opacity:.45,filter:"grayscale(1)"},className:"animate-pulse"}),t.jsx("h2",{style:{fontSize:"18px",fontWeight:700,color:"#1B3A4B",marginBottom:"8px"},children:"MEMO Architect"}),t.jsx("p",{style:{color:"#6B7280",fontSize:"14px",marginBottom:"20px"},children:"Connecting to dev server…"}),t.jsxs("div",{style:{color:"#6B7280",fontSize:"13px",lineHeight:"1.6",textAlign:"left",background:"rgba(255,255,255,0.6)",borderRadius:"10px",padding:"16px 20px",border:"1px solid rgba(255,255,255,0.9)"},children:[t.jsx("p",{style:{fontWeight:600,color:"#374151",marginBottom:"8px"},children:"Start the MEMO dev server:"}),t.jsx("code",{style:{display:"block",margin:"0 0 12px",padding:"8px 14px",background:"#1B3A4B",color:"#2DD4A8",borderRadius:"6px",fontFamily:"monospace",fontSize:"13px"},children:"pnpm architect -- dev --port 3000"}),t.jsx("p",{style:{color:"#9CA3AF",marginBottom:"8px"},children:"Or try the example project:"}),t.jsx("code",{style:{display:"block",padding:"8px 14px",background:"#1B3A4B",color:"#2DD4A8",borderRadius:"6px",fontFamily:"monospace",fontSize:"13px"},children:"pnpm example:dev"})]})]})})]})}function za(){const{family:e=""}=It();return t.jsx(ga,{family:e.toUpperCase()})}function Ba(){const{shortId:e=""}=It(),r=S(o=>o.model),n=S(o=>o.setActiveView),s=S(o=>o.selectElement);return u.useEffect(()=>{if(!r)return;const o=Object.values(r.elements).find(i=>(i.shortId??i.id)===e);o&&(s(o.id),n({type:"element-detail",elementId:o.id}))},[e,r,n,s]),t.jsx(u.Suspense,{fallback:t.jsx(Lt,{}),children:t.jsx(er,{})})}function La(){const{diagramId:e=""}=It(),r=S(o=>o.model),n=S(o=>o.selectDiagram),s=S(o=>o.setActiveView);return u.useEffect(()=>{var i;if(!r)return;const o=(i=r.diagrams)==null?void 0:i.find(l=>l.id===e||l.id.toLowerCase().replace(/\s+/g,"-")===e);o&&(n(o.id),s({type:"diagram",diagramId:o.id}))},[e,r,n,s]),t.jsx(u.Suspense,{fallback:t.jsx(Lt,{}),children:t.jsx(ba,{})})}function qa(){const e=S(o=>o.activeView),r=S(o=>o.model),n=Ce(),s=ye();return u.useEffect(()=>{if(e.type==="element-detail"&&r){const o=e.elementId,i=r.elements[o];if(i){const l=i.shortId??i.id,d=`/catalog/${l.split("-")[0]}/${l}`;s.pathname!==d&&n(d,{replace:!1})}}},[e]),null}sr.createRoot(document.getElementById("root")).render(t.jsx(u.StrictMode,{children:t.jsx(Do,{children:t.jsx(Pa,{})})}));export{g as C,Ae as D,ol as E,C as F,zt as K,ds as L,sl as R,nl as S,hs as V,te as _,Wa as a,tl as b,At as c,ie as d,es as e,Fe as f,Yn as g,$a as h,el as i,Xa as j,Za as k,Ha as l,rl as m,Qa as n,en as o,il as p,us as q,gs as r,Ka as s,Ga as t,S as u,Ja as v,Ya as w};