Spaces:
Running
Running
Joel Woodfield commited on
Commit ·
290a07c
1
Parent(s): ab51f9c
Fix bug where projector was not reset when dataset changes
Browse files
backend/src/manager.py
CHANGED
|
@@ -18,6 +18,8 @@ class Manager:
|
|
| 18 |
|
| 19 |
def handle_set_dataset(self, dataset: dict) -> None:
|
| 20 |
self._reset_model()
|
|
|
|
|
|
|
| 21 |
|
| 22 |
try:
|
| 23 |
parsed_dataset = Dataset(
|
|
@@ -31,6 +33,8 @@ class Manager:
|
|
| 31 |
|
| 32 |
def handle_set_dataset_csv(self, args: dict) -> dict:
|
| 33 |
self._reset_model()
|
|
|
|
|
|
|
| 34 |
|
| 35 |
try:
|
| 36 |
buffer = args["buffer"]
|
|
|
|
| 18 |
|
| 19 |
def handle_set_dataset(self, dataset: dict) -> None:
|
| 20 |
self._reset_model()
|
| 21 |
+
self._projector = None
|
| 22 |
+
self._preprocessor = None
|
| 23 |
|
| 24 |
try:
|
| 25 |
parsed_dataset = Dataset(
|
|
|
|
| 33 |
|
| 34 |
def handle_set_dataset_csv(self, args: dict) -> dict:
|
| 35 |
self._reset_model()
|
| 36 |
+
self._projector = None
|
| 37 |
+
self._preprocessor = None
|
| 38 |
|
| 39 |
try:
|
| 40 |
buffer = args["buffer"]
|
dist/assets/{index-C3x3HctU.js → index-D01VFfwo.js}
RENAMED
|
@@ -7640,4 +7640,4 @@ To see available arguments, refer to the scikit-learn documentation (search for
|
|
| 7640 |
For **Manual** datasets, the model is trained on the datapoints on the plot and decision regions are evaluated using the regions visible in the plot.
|
| 7641 |
|
| 7642 |
For **uploaded and preset** datasets, the model is trained on the dataset after normalization and noise, but before the 2d projection. When plotting decision regions, the visible points on the plot are mapped to the original input space via an inverse projection. For coordinate projection, non-projected coordinates are filled using the dataset mean.
|
| 7643 |
-
`,OU=["LogisticRegression","SVC","LinearSVC","NuSVC","LinearDiscriminantAnalysis","QuadraticDiscriminantAnalysis","DecisionTreeClassifier","RandomForestClassifier","ExtraTreesClassifier","ExtraTreeClassifier","AdaBoostClassifier","GradientBoostingClassifier","HistGradientBoostingClassifier","KNeighborsClassifier"],HR=[{name:"Iris",url:"/datasets/iris.csv",inputColumns:"1,2",outputColumn:"5"},{name:"Titanic",url:"/datasets/titanic.csv",inputColumns:"1,2",outputColumn:"6"}];function FU({pointLabel:Mt,setPointLabel:dr,setCanAddPoints:Cr,undoDataPoint:Pr,clearDataPoints:yn,modelSettings:En,setModelSettings:$n,csvSettings:Ca,onGetDecisionBoundary:ni,onCsvUpload:Ma,onCsvSettingsChange:Ja,csvError:fi,onCsvExport:Oi,onSvgExport:Si}){const Ps=["Data","Model","Export","Usage"],[fl,au]=Ld.useState("Data"),ho=HR.map(Xs=>Xs.name),qe=["Manual","Upload"],[kl,lf]=Ld.useState("Manual");function xl(Xs){return ho.includes(Xs)}function Lo(Xs){lf(Xs),xl(Xs)&&Ml(Xs)}async function Ml(Xs){const Ii=HR.find(ji=>ji.name===Xs);if(!Ii)return;const is=await(await fetch(Ii.url)).blob(),jl=new File([is],`${Ii.name}.csv`,{type:"text/csv"}),df={...Ca,inputColumns:Ii.inputColumns,outputColumn:Ii.outputColumn};Ma(jl,df)}return Ld.useEffect(()=>{yn(),Cr(kl==="Manual")},[kl]),yu.jsxs(YR,{className:"bg-white flex flex-col h-full min-w-0 min-h-0 overflow-auto border border-gray-200 rounded p-6 gap-4",children:[yu.jsx(pF,{tabs:Ps,activeTab:fl,onChange:au}),yu.jsxs("div",{className:"flex flex-col gap-8 min-h-0 overflow-auto",children:[fl==="Data"&&yu.jsxs(yu.Fragment,{children:[yu.jsxs(BE,{label:"Dataset",children:[yu.jsx(FE,{label:"Input",options:qe,groupedOptions:[{label:"Built-in",options:ho}],activeOption:kl,onChange:Lo}),kl==="Manual"&&yu.jsxs(yu.Fragment,{children:[yu.jsx(FE,{label:"Point Label",options:kb.map(Xs=>Xs.name),activeOption:Mt,onChange:Xs=>dr(Xs)}),yu.jsxs("div",{className:"grid grid-cols-2 gap-2",children:[yu.jsx(ik,{label:"Undo",onClick:Pr}),yu.jsx(ik,{label:"Clear",onClick:yn})]})]}),kl==="Upload"&&yu.jsx(hF,{label:"Upload CSV",onFileUpload:Ma}),(kl==="Upload"||xl(kl))&&yu.jsx(yu.Fragment,{children:yu.jsxs("div",{className:"grid grid-cols-[minmax(0,2fr)_minmax(0,1fr)] gap-2",children:[yu.jsx(rk,{label:"Input Columns",value:Ca.inputColumns,onChange:Xs=>{Ja({...Ca,inputColumns:Xs})}}),yu.jsx(rk,{label:"Output Column",value:Ca.outputColumn,onChange:Xs=>{Ja({...Ca,outputColumn:Xs})}})]})})]}),(kl==="Upload"||xl(kl))&&yu.jsxs(yu.Fragment,{children:[yu.jsxs(BE,{label:"Preprocessing",children:[yu.jsx(FE,{label:"Normalizer",options:["None","MinMax","Standard"],activeOption:Ca.normalizerType,onChange:Xs=>{Ja({...Ca,normalizerType:Xs})}}),yu.jsx(rk,{label:"Normal noise standard deviation",value:Ca.normalNoiseStd,onChange:Xs=>{Ja({...Ca,normalNoiseStd:Xs})}})]}),yu.jsxs(BE,{label:"Plotting",children:[yu.jsx(FE,{label:"Projection",options:["Coordinates","PCA"],activeOption:Ca.projectionType,onChange:Xs=>{Ja({...Ca,projectionType:Xs})}}),Ca.projectionType==="Coordinates"&&yu.jsxs("div",{className:"grid grid-cols-2 gap-2",children:[yu.jsx(rk,{label:"X1 Column",value:Ca.x1Column||"",onChange:Xs=>{Ja({...Ca,x1Column:Xs})}}),yu.jsx(rk,{label:"X2 Column",value:Ca.x2Column||"",onChange:Xs=>{Ja({...Ca,x2Column:Xs})}})]})]}),fi&&yu.jsx(BE,{label:"Error",children:yu.jsxs("p",{className:"text-red-600 font-semibold",children:["CSV Error: ",fi]})})]})]}),fl==="Model"&&yu.jsxs(yu.Fragment,{children:[yu.jsxs(BE,{label:"Classifier Options",children:[yu.jsx(FE,{label:"Type",options:OU,activeOption:En.type,onChange:Xs=>{$n({...En,type:Xs})}}),yu.jsx(rk,{label:"Arguments",value:En.arguments,onChange:Xs=>{$n({...En,arguments:Xs})}})]}),yu.jsx(ik,{label:"Get Decision Boundary",onClick:ni})]}),fl==="Export"&&yu.jsxs("div",{className:"flex flex-col gap-4",children:[yu.jsx(ik,{label:"Dataset as CSV",onClick:Oi}),yu.jsx(ik,{label:"Plot as SVG",onClick:Si})]}),fl==="Usage"&&yu.jsx("div",{className:"prose leading-loose overflow-auto",children:yu.jsx(LU,{components:{h1:({children:Xs})=>yu.jsx("h1",{className:"text-2xl font-bold mt-12 mb-2 first:mt-4",children:Xs}),h2:({children:Xs})=>yu.jsx("h2",{className:"text-xl font-semibold mt-12 mb-2 first:mt-4",children:Xs}),h3:({children:Xs})=>yu.jsx("h3",{className:"text-lg font-semibold mt-12 mb-2 first:mt-4",children:Xs}),p:({children:Xs})=>yu.jsx("p",{className:"leading-6 mb-3 last:mb-0",children:Xs}),ul:({children:Xs})=>yu.jsx("ul",{className:"list-disc pl-5 mb-3",children:Xs}),ol:({children:Xs})=>yu.jsx("ol",{className:"list-decimal pl-5 mb-3",children:Xs}),li:({children:Xs})=>yu.jsx("li",{className:"mb-1",children:Xs}),code:({children:Xs})=>yu.jsx("code",{className:"bg-gray-200 px-1 py-0.5 rounded",children:Xs})},children:RU})})]})]})}const LO=Symbol("Comlink.proxy"),BU=Symbol("Comlink.endpoint"),PO=Symbol("Comlink.releaseProxy"),gD=Symbol("Comlink.finalizer"),n8=Symbol("Comlink.thrown"),zO=Mt=>typeof Mt=="object"&&Mt!==null||typeof Mt=="function",NU={canHandle:Mt=>zO(Mt)&&Mt[LO],serialize(Mt){const{port1:dr,port2:Cr}=new MessageChannel;return DO(Mt,dr),[Cr,[Cr]]},deserialize(Mt){return Mt.start(),OO(Mt)}},jU={canHandle:Mt=>zO(Mt)&&n8 in Mt,serialize({value:Mt}){let dr;return Mt instanceof Error?dr={isError:!0,value:{message:Mt.message,name:Mt.name,stack:Mt.stack}}:dr={isError:!1,value:Mt},[dr,[]]},deserialize(Mt){throw Mt.isError?Object.assign(new Error(Mt.value.message),Mt.value):Mt.value}},IO=new Map([["proxy",NU],["throw",jU]]);function UU(Mt,dr){for(const Cr of Mt)if(dr===Cr||Cr==="*"||Cr instanceof RegExp&&Cr.test(dr))return!0;return!1}function DO(Mt,dr=globalThis,Cr=["*"]){dr.addEventListener("message",function Pr(yn){if(!yn||!yn.data)return;if(!UU(Cr,yn.origin)){console.warn(`Invalid origin '${yn.origin}' for comlink proxy`);return}const{id:En,type:$n,path:Ca}=Object.assign({path:[]},yn.data),ni=(yn.data.argumentList||[]).map(mS);let Ma;try{const Ja=Ca.slice(0,-1).reduce((Oi,Si)=>Oi[Si],Mt),fi=Ca.reduce((Oi,Si)=>Oi[Si],Mt);switch($n){case"GET":Ma=fi;break;case"SET":Ja[Ca.slice(-1)[0]]=mS(yn.data.value),Ma=!0;break;case"APPLY":Ma=fi.apply(Ja,ni);break;case"CONSTRUCT":{const Oi=new fi(...ni);Ma=jO(Oi)}break;case"ENDPOINT":{const{port1:Oi,port2:Si}=new MessageChannel;DO(Mt,Si),Ma=NO(Oi,[Oi])}break;case"RELEASE":Ma=void 0;break;default:return}}catch(Ja){Ma={value:Ja,[n8]:0}}Promise.resolve(Ma).catch(Ja=>({value:Ja,[n8]:0})).then(Ja=>{const[fi,Oi]=l8(Ja);dr.postMessage(Object.assign(Object.assign({},fi),{id:En}),Oi),$n==="RELEASE"&&(dr.removeEventListener("message",Pr),RO(dr),gD in Mt&&typeof Mt[gD]=="function"&&Mt[gD]())}).catch(Ja=>{const[fi,Oi]=l8({value:new TypeError("Unserializable return value"),[n8]:0});dr.postMessage(Object.assign(Object.assign({},fi),{id:En}),Oi)})}),dr.start&&dr.start()}function VU(Mt){return Mt.constructor.name==="MessagePort"}function RO(Mt){VU(Mt)&&Mt.close()}function OO(Mt,dr){const Cr=new Map;return Mt.addEventListener("message",function(yn){const{data:En}=yn;if(!En||!En.id)return;const $n=Cr.get(En.id);if($n)try{$n(En)}finally{Cr.delete(En.id)}}),ED(Mt,Cr,[],dr)}function QE(Mt){if(Mt)throw new Error("Proxy has been released and is not useable")}function FO(Mt){return ok(Mt,new Map,{type:"RELEASE"}).then(()=>{RO(Mt)})}const o8=new WeakMap,s8="FinalizationRegistry"in globalThis&&new FinalizationRegistry(Mt=>{const dr=(o8.get(Mt)||0)-1;o8.set(Mt,dr),dr===0&&FO(Mt)});function qU(Mt,dr){const Cr=(o8.get(dr)||0)+1;o8.set(dr,Cr),s8&&s8.register(Mt,dr,Mt)}function HU(Mt){s8&&s8.unregister(Mt)}function ED(Mt,dr,Cr=[],Pr=function(){}){let yn=!1;const En=new Proxy(Pr,{get($n,Ca){if(QE(yn),Ca===PO)return()=>{HU(En),FO(Mt),dr.clear(),yn=!0};if(Ca==="then"){if(Cr.length===0)return{then:()=>En};const ni=ok(Mt,dr,{type:"GET",path:Cr.map(Ma=>Ma.toString())}).then(mS);return ni.then.bind(ni)}return ED(Mt,dr,[...Cr,Ca])},set($n,Ca,ni){QE(yn);const[Ma,Ja]=l8(ni);return ok(Mt,dr,{type:"SET",path:[...Cr,Ca].map(fi=>fi.toString()),value:Ma},Ja).then(mS)},apply($n,Ca,ni){QE(yn);const Ma=Cr[Cr.length-1];if(Ma===BU)return ok(Mt,dr,{type:"ENDPOINT"}).then(mS);if(Ma==="bind")return ED(Mt,dr,Cr.slice(0,-1));const[Ja,fi]=GR(ni);return ok(Mt,dr,{type:"APPLY",path:Cr.map(Oi=>Oi.toString()),argumentList:Ja},fi).then(mS)},construct($n,Ca){QE(yn);const[ni,Ma]=GR(Ca);return ok(Mt,dr,{type:"CONSTRUCT",path:Cr.map(Ja=>Ja.toString()),argumentList:ni},Ma).then(mS)}});return qU(En,Mt),En}function GU(Mt){return Array.prototype.concat.apply([],Mt)}function GR(Mt){const dr=Mt.map(l8);return[dr.map(Cr=>Cr[0]),GU(dr.map(Cr=>Cr[1]))]}const BO=new WeakMap;function NO(Mt,dr){return BO.set(Mt,dr),Mt}function jO(Mt){return Object.assign(Mt,{[LO]:!0})}function l8(Mt){for(const[dr,Cr]of IO)if(Cr.canHandle(Mt)){const[Pr,yn]=Cr.serialize(Mt);return[{type:"HANDLER",name:dr,value:Pr},yn]}return[{type:"RAW",value:Mt},BO.get(Mt)||[]]}function mS(Mt){switch(Mt.type){case"HANDLER":return IO.get(Mt.name).deserialize(Mt.value);case"RAW":return Mt.value}}function ok(Mt,dr,Cr,Pr){return new Promise(yn=>{const En=WU();dr.set(En,yn),Mt.start&&Mt.start(),Mt.postMessage(Object.assign({id:En},Cr),Pr)})}function WU(){return new Array(4).fill(0).map(()=>Math.floor(Math.random()*Number.MAX_SAFE_INTEGER).toString(16)).join("-")}function ZU(){const Mt=Ld.useRef(null),dr=Ld.useRef(null),[Cr,Pr]=Ld.useState(!1);return Ld.useEffect(()=>{const En=new Worker(new URL("/assets/pyodide.worker-CKAjTPz8.js",import.meta.url),{type:"module"}),$n=OO(En);return Mt.current=$n,dr.current=En,(async()=>{try{await $n.setErrorHandler(jO(Ca=>{alert(Ca)})),await $n.init(),console.log("Pyodide intialized"),Pr(!0)}catch(Ca){console.error("Failed to initialize Pyodide backend:",Ca)}})(),()=>{Mt.current&&(Mt.current[PO](),Mt.current=null),dr.current?.terminate(),dr.current=null,Pr(!1)}},[]),{getBackend:Ld.useCallback(()=>{if(!Mt.current)throw new Error("Pyodide backend is not ready");return Mt.current},[]),backendReady:Cr}}const YU={inputColumns:"1,2",outputColumn:"3",normalizerType:"None",normalNoiseStd:"0.0",projectionType:"Coordinates",x1Column:"1",x2Column:"2"},XU=500,KU=[-10,10],$U=[-10,10];function JU(){const{getBackend:Mt,backendReady:dr}=ZU(),[Cr,Pr]=Ld.useState({xPoints:[],yPoints:[],labels:[]}),yn=new fF(Cr.labels),[En,$n]=Ld.useState(!0),[Ca,ni]=Ld.useState(kb[0].name),[Ma,Ja]=Ld.useState(XU),fi=Ld.useRef(KU),Oi=Ld.useRef($U),[Si,Ps]=Ld.useState(0);function fl(qi,os){fi.current=qi,Oi.current=os,ji()}function au(qi,os){fi.current=qi,Oi.current=os,Ps(wi=>wi+1),console.log(fi.current,Oi.current)}const[ho,qe]=Ld.useState({type:"LogisticRegression",arguments:""});async function kl(qi){qe(qi),dr&&(await Mt().setModelConfig(qi),await ji())}const[lf,xl]=Ld.useState(YU),[Lo,Ml]=Ld.useState(null),[Xs,Ii]=Ld.useState(null),Yu=Ld.useRef(null);async function is(qi,os,wi){const Kl={xPoints:[...Cr.xPoints,qi],yPoints:[...Cr.yPoints,os],labels:[...Cr.labels,wi]};Pr(Kl),dr&&(await Mt().setDataset2d(Kl),await ji())}async function jl(){const qi={xPoints:Cr.xPoints.slice(0,-1),yPoints:Cr.yPoints.slice(0,-1),labels:Cr.labels.slice(0,-1)};Pr(qi),dr&&(await Mt().setDataset2d(qi),await ji())}async function df(){const qi={xPoints:[],yPoints:[],labels:[]};Pr(qi),dr&&(await Mt().setDataset2d(qi),await ji())}async function ji(){if(!dr)return;const qi={xmin:fi.current[0],xmax:fi.current[1],ymin:Oi.current[0],ymax:Oi.current[1],resolution:Ma},os=await Mt().getDecisionBoundary(qi);Ii(os)}async function oo(){dr&&(await Mt().buildModel(),await ji())}async function Yo(qi,os){const wi=os??lf;if(os&&xl(os),!dr){alert("Python backend is not ready yet.");return}const Kl=await qi.arrayBuffer();console.log(Kl);const El=await Mt().setDatasetCsv(NO(Kl,[Kl]),wi);El.status==="OK"?(Pr(El.dataPoints),El.xRange&&El.yRange&&au(El.xRange,El.yRange),Ml(null)):El.status==="CSV_ERROR"&&Ml(El.message),await ji()}async function ul(qi){if(!dr)return;xl(qi);const os=await Mt().setCsvSettings(qi);os.status==="OK"?(Pr(os.dataPoints),os.xRange&&os.yRange&&au(os.xRange,os.yRange),Ml(null)):os.status==="CSV_ERROR"&&Ml(os.message),await ji()}function Xl(qi,os){const wi=new Blob([os],{type:"text/csv;charset=utf-8"}),Kl=URL.createObjectURL(wi),El=document.createElement("a");El.href=Kl,El.download=qi,document.body.appendChild(El),El.click(),El.remove(),URL.revokeObjectURL(Kl)}async function Vf(){if(!dr){alert("Python backend is not ready yet.");return}const qi=await Mt().getDatasetCsv();Xl("dataset.csv",qi)}function Ui(){Yu.current&&Yu.current?.downloadSvg()}return console.log("rendering app"),Ld.useEffect(()=>{dr&&(async()=>(await Mt().setDataset2d(Cr),await Mt().setModelConfig(ho),await ji()))()},[dr,Mt]),{backendReady:dr,dataPoints:Cr,labelColors:yn,canAddPoints:En,setCanAddPoints:$n,pointLabel:Ca,setPointLabel:ni,xRangeRef:fi,yRangeRef:Oi,handleRangeChange:fl,rangeVersion:Si,modelSettings:ho,handleModelSettingsChange:kl,csvSettings:lf,handleCsvSettingsChange:ul,csvError:Lo,decisionBoundaryResult:Xs,handleAddDataPoint:is,handleUndoDataPoint:jl,handleClearDataPoints:df,handleGetDecisionBoundary:oo,handleCsvUpload:Yo,getCsvDataset:Vf,plotHandle:Yu,getPlotSvg:Ui}}function QU(){const Mt=JU();return yu.jsxs("div",{className:"grid grid-cols-[1fr_12fr_1fr] h-dvh bg-stone-50",children:[yu.jsx("div",{}),yu.jsxs("div",{className:"flex flex-col gap-6 p-6 min-h-0",children:[yu.jsx("div",{className:"title",children:"Decision Boundary Visualizer"}),yu.jsxs("div",{className:"grid grid-cols-[8fr_4fr] gap-12 flex-1 min-h-0",children:[yu.jsx(dF,{dataPoints:Mt.dataPoints,addDataPoint:Mt.handleAddDataPoint,decisionBoundaryResult:Mt.decisionBoundaryResult,xRangeRef:Mt.xRangeRef,yRangeRef:Mt.yRangeRef,setRanges:Mt.handleRangeChange,canAddPoints:Mt.canAddPoints,pointLabel:Mt.pointLabel,labelColors:Mt.labelColors,plotHandle:Mt.plotHandle}),yu.jsx(FU,{pointLabel:Mt.pointLabel,setPointLabel:Mt.setPointLabel,setCanAddPoints:Mt.setCanAddPoints,undoDataPoint:Mt.handleUndoDataPoint,clearDataPoints:Mt.handleClearDataPoints,modelSettings:Mt.modelSettings,setModelSettings:Mt.handleModelSettingsChange,csvSettings:Mt.csvSettings,onCsvSettingsChange:Mt.handleCsvSettingsChange,onGetDecisionBoundary:Mt.handleGetDecisionBoundary,onCsvUpload:Mt.handleCsvUpload,csvError:Mt.csvError,onCsvExport:Mt.getCsvDataset,onSvgExport:Mt.getPlotSvg})]})]}),yu.jsx("div",{})]})}KO.createRoot(document.getElementById("root")).render(yu.jsx(Ld.StrictMode,{children:yu.jsx(QU,{})}));
|
|
|
|
| 7640 |
For **Manual** datasets, the model is trained on the datapoints on the plot and decision regions are evaluated using the regions visible in the plot.
|
| 7641 |
|
| 7642 |
For **uploaded and preset** datasets, the model is trained on the dataset after normalization and noise, but before the 2d projection. When plotting decision regions, the visible points on the plot are mapped to the original input space via an inverse projection. For coordinate projection, non-projected coordinates are filled using the dataset mean.
|
| 7643 |
+
`,OU=["LogisticRegression","SVC","LinearSVC","NuSVC","LinearDiscriminantAnalysis","QuadraticDiscriminantAnalysis","DecisionTreeClassifier","RandomForestClassifier","ExtraTreesClassifier","ExtraTreeClassifier","AdaBoostClassifier","GradientBoostingClassifier","HistGradientBoostingClassifier","KNeighborsClassifier"],HR=[{name:"Iris",url:"/datasets/iris.csv",inputColumns:"1,2",outputColumn:"5"},{name:"Titanic",url:"/datasets/titanic.csv",inputColumns:"1,2",outputColumn:"6"}];function FU({pointLabel:Mt,setPointLabel:dr,setCanAddPoints:Cr,undoDataPoint:Pr,clearDataPoints:yn,modelSettings:En,setModelSettings:$n,csvSettings:Ca,onGetDecisionBoundary:ni,onCsvUpload:Ma,onCsvSettingsChange:Ja,csvError:fi,onCsvExport:Oi,onSvgExport:Si}){const Ps=["Data","Model","Export","Usage"],[fl,au]=Ld.useState("Data"),ho=HR.map(Xs=>Xs.name),qe=["Manual","Upload"],[kl,lf]=Ld.useState("Manual");function xl(Xs){return ho.includes(Xs)}function Lo(Xs){lf(Xs),xl(Xs)&&Ml(Xs)}async function Ml(Xs){const Ii=HR.find(ji=>ji.name===Xs);if(!Ii)return;const is=await(await fetch(Ii.url)).blob(),jl=new File([is],`${Ii.name}.csv`,{type:"text/csv"}),df={...Ca,inputColumns:Ii.inputColumns,outputColumn:Ii.outputColumn};Ma(jl,df)}return Ld.useEffect(()=>{yn(),Cr(kl==="Manual")},[kl]),yu.jsxs(YR,{className:"bg-white flex flex-col h-full min-w-0 min-h-0 overflow-auto border border-gray-200 rounded p-6 gap-4",children:[yu.jsx(pF,{tabs:Ps,activeTab:fl,onChange:au}),yu.jsxs("div",{className:"flex flex-col gap-8 min-h-0 overflow-auto",children:[fl==="Data"&&yu.jsxs(yu.Fragment,{children:[yu.jsxs(BE,{label:"Dataset",children:[yu.jsx(FE,{label:"Input",options:qe,groupedOptions:[{label:"Built-in",options:ho}],activeOption:kl,onChange:Lo}),kl==="Manual"&&yu.jsxs(yu.Fragment,{children:[yu.jsx(FE,{label:"Point Label",options:kb.map(Xs=>Xs.name),activeOption:Mt,onChange:Xs=>dr(Xs)}),yu.jsxs("div",{className:"grid grid-cols-2 gap-2",children:[yu.jsx(ik,{label:"Undo",onClick:Pr}),yu.jsx(ik,{label:"Clear",onClick:yn})]})]}),kl==="Upload"&&yu.jsx(hF,{label:"Upload CSV",onFileUpload:Ma}),(kl==="Upload"||xl(kl))&&yu.jsx(yu.Fragment,{children:yu.jsxs("div",{className:"grid grid-cols-[minmax(0,2fr)_minmax(0,1fr)] gap-2",children:[yu.jsx(rk,{label:"Input Columns",value:Ca.inputColumns,onChange:Xs=>{Ja({...Ca,inputColumns:Xs})}}),yu.jsx(rk,{label:"Output Column",value:Ca.outputColumn,onChange:Xs=>{Ja({...Ca,outputColumn:Xs})}})]})})]}),(kl==="Upload"||xl(kl))&&yu.jsxs(yu.Fragment,{children:[yu.jsxs(BE,{label:"Preprocessing",children:[yu.jsx(FE,{label:"Normalizer",options:["None","MinMax","Standard"],activeOption:Ca.normalizerType,onChange:Xs=>{Ja({...Ca,normalizerType:Xs})}}),yu.jsx(rk,{label:"Normal noise standard deviation",value:Ca.normalNoiseStd,onChange:Xs=>{Ja({...Ca,normalNoiseStd:Xs})}})]}),yu.jsxs(BE,{label:"Plotting",children:[yu.jsx(FE,{label:"Projection",options:["Coordinates","PCA"],activeOption:Ca.projectionType,onChange:Xs=>{Ja({...Ca,projectionType:Xs})}}),Ca.projectionType==="Coordinates"&&yu.jsxs("div",{className:"grid grid-cols-2 gap-2",children:[yu.jsx(rk,{label:"X1 Column",value:Ca.x1Column||"",onChange:Xs=>{Ja({...Ca,x1Column:Xs})}}),yu.jsx(rk,{label:"X2 Column",value:Ca.x2Column||"",onChange:Xs=>{Ja({...Ca,x2Column:Xs})}})]})]}),fi&&yu.jsx(BE,{label:"Error",children:yu.jsxs("p",{className:"text-red-600 font-semibold",children:["CSV Error: ",fi]})})]})]}),fl==="Model"&&yu.jsxs(yu.Fragment,{children:[yu.jsxs(BE,{label:"Classifier Options",children:[yu.jsx(FE,{label:"Type",options:OU,activeOption:En.type,onChange:Xs=>{$n({...En,type:Xs})}}),yu.jsx(rk,{label:"Arguments",value:En.arguments,onChange:Xs=>{$n({...En,arguments:Xs})}})]}),yu.jsx(ik,{label:"Get Decision Boundary",onClick:ni})]}),fl==="Export"&&yu.jsxs("div",{className:"flex flex-col gap-4",children:[yu.jsx(ik,{label:"Dataset as CSV",onClick:Oi}),yu.jsx(ik,{label:"Plot as SVG",onClick:Si})]}),fl==="Usage"&&yu.jsx("div",{className:"prose leading-loose overflow-auto",children:yu.jsx(LU,{components:{h1:({children:Xs})=>yu.jsx("h1",{className:"text-2xl font-bold mt-12 mb-2 first:mt-4",children:Xs}),h2:({children:Xs})=>yu.jsx("h2",{className:"text-xl font-semibold mt-12 mb-2 first:mt-4",children:Xs}),h3:({children:Xs})=>yu.jsx("h3",{className:"text-lg font-semibold mt-12 mb-2 first:mt-4",children:Xs}),p:({children:Xs})=>yu.jsx("p",{className:"leading-6 mb-3 last:mb-0",children:Xs}),ul:({children:Xs})=>yu.jsx("ul",{className:"list-disc pl-5 mb-3",children:Xs}),ol:({children:Xs})=>yu.jsx("ol",{className:"list-decimal pl-5 mb-3",children:Xs}),li:({children:Xs})=>yu.jsx("li",{className:"mb-1",children:Xs}),code:({children:Xs})=>yu.jsx("code",{className:"bg-gray-200 px-1 py-0.5 rounded",children:Xs})},children:RU})})]})]})}const LO=Symbol("Comlink.proxy"),BU=Symbol("Comlink.endpoint"),PO=Symbol("Comlink.releaseProxy"),gD=Symbol("Comlink.finalizer"),n8=Symbol("Comlink.thrown"),zO=Mt=>typeof Mt=="object"&&Mt!==null||typeof Mt=="function",NU={canHandle:Mt=>zO(Mt)&&Mt[LO],serialize(Mt){const{port1:dr,port2:Cr}=new MessageChannel;return DO(Mt,dr),[Cr,[Cr]]},deserialize(Mt){return Mt.start(),OO(Mt)}},jU={canHandle:Mt=>zO(Mt)&&n8 in Mt,serialize({value:Mt}){let dr;return Mt instanceof Error?dr={isError:!0,value:{message:Mt.message,name:Mt.name,stack:Mt.stack}}:dr={isError:!1,value:Mt},[dr,[]]},deserialize(Mt){throw Mt.isError?Object.assign(new Error(Mt.value.message),Mt.value):Mt.value}},IO=new Map([["proxy",NU],["throw",jU]]);function UU(Mt,dr){for(const Cr of Mt)if(dr===Cr||Cr==="*"||Cr instanceof RegExp&&Cr.test(dr))return!0;return!1}function DO(Mt,dr=globalThis,Cr=["*"]){dr.addEventListener("message",function Pr(yn){if(!yn||!yn.data)return;if(!UU(Cr,yn.origin)){console.warn(`Invalid origin '${yn.origin}' for comlink proxy`);return}const{id:En,type:$n,path:Ca}=Object.assign({path:[]},yn.data),ni=(yn.data.argumentList||[]).map(mS);let Ma;try{const Ja=Ca.slice(0,-1).reduce((Oi,Si)=>Oi[Si],Mt),fi=Ca.reduce((Oi,Si)=>Oi[Si],Mt);switch($n){case"GET":Ma=fi;break;case"SET":Ja[Ca.slice(-1)[0]]=mS(yn.data.value),Ma=!0;break;case"APPLY":Ma=fi.apply(Ja,ni);break;case"CONSTRUCT":{const Oi=new fi(...ni);Ma=jO(Oi)}break;case"ENDPOINT":{const{port1:Oi,port2:Si}=new MessageChannel;DO(Mt,Si),Ma=NO(Oi,[Oi])}break;case"RELEASE":Ma=void 0;break;default:return}}catch(Ja){Ma={value:Ja,[n8]:0}}Promise.resolve(Ma).catch(Ja=>({value:Ja,[n8]:0})).then(Ja=>{const[fi,Oi]=l8(Ja);dr.postMessage(Object.assign(Object.assign({},fi),{id:En}),Oi),$n==="RELEASE"&&(dr.removeEventListener("message",Pr),RO(dr),gD in Mt&&typeof Mt[gD]=="function"&&Mt[gD]())}).catch(Ja=>{const[fi,Oi]=l8({value:new TypeError("Unserializable return value"),[n8]:0});dr.postMessage(Object.assign(Object.assign({},fi),{id:En}),Oi)})}),dr.start&&dr.start()}function VU(Mt){return Mt.constructor.name==="MessagePort"}function RO(Mt){VU(Mt)&&Mt.close()}function OO(Mt,dr){const Cr=new Map;return Mt.addEventListener("message",function(yn){const{data:En}=yn;if(!En||!En.id)return;const $n=Cr.get(En.id);if($n)try{$n(En)}finally{Cr.delete(En.id)}}),ED(Mt,Cr,[],dr)}function QE(Mt){if(Mt)throw new Error("Proxy has been released and is not useable")}function FO(Mt){return ok(Mt,new Map,{type:"RELEASE"}).then(()=>{RO(Mt)})}const o8=new WeakMap,s8="FinalizationRegistry"in globalThis&&new FinalizationRegistry(Mt=>{const dr=(o8.get(Mt)||0)-1;o8.set(Mt,dr),dr===0&&FO(Mt)});function qU(Mt,dr){const Cr=(o8.get(dr)||0)+1;o8.set(dr,Cr),s8&&s8.register(Mt,dr,Mt)}function HU(Mt){s8&&s8.unregister(Mt)}function ED(Mt,dr,Cr=[],Pr=function(){}){let yn=!1;const En=new Proxy(Pr,{get($n,Ca){if(QE(yn),Ca===PO)return()=>{HU(En),FO(Mt),dr.clear(),yn=!0};if(Ca==="then"){if(Cr.length===0)return{then:()=>En};const ni=ok(Mt,dr,{type:"GET",path:Cr.map(Ma=>Ma.toString())}).then(mS);return ni.then.bind(ni)}return ED(Mt,dr,[...Cr,Ca])},set($n,Ca,ni){QE(yn);const[Ma,Ja]=l8(ni);return ok(Mt,dr,{type:"SET",path:[...Cr,Ca].map(fi=>fi.toString()),value:Ma},Ja).then(mS)},apply($n,Ca,ni){QE(yn);const Ma=Cr[Cr.length-1];if(Ma===BU)return ok(Mt,dr,{type:"ENDPOINT"}).then(mS);if(Ma==="bind")return ED(Mt,dr,Cr.slice(0,-1));const[Ja,fi]=GR(ni);return ok(Mt,dr,{type:"APPLY",path:Cr.map(Oi=>Oi.toString()),argumentList:Ja},fi).then(mS)},construct($n,Ca){QE(yn);const[ni,Ma]=GR(Ca);return ok(Mt,dr,{type:"CONSTRUCT",path:Cr.map(Ja=>Ja.toString()),argumentList:ni},Ma).then(mS)}});return qU(En,Mt),En}function GU(Mt){return Array.prototype.concat.apply([],Mt)}function GR(Mt){const dr=Mt.map(l8);return[dr.map(Cr=>Cr[0]),GU(dr.map(Cr=>Cr[1]))]}const BO=new WeakMap;function NO(Mt,dr){return BO.set(Mt,dr),Mt}function jO(Mt){return Object.assign(Mt,{[LO]:!0})}function l8(Mt){for(const[dr,Cr]of IO)if(Cr.canHandle(Mt)){const[Pr,yn]=Cr.serialize(Mt);return[{type:"HANDLER",name:dr,value:Pr},yn]}return[{type:"RAW",value:Mt},BO.get(Mt)||[]]}function mS(Mt){switch(Mt.type){case"HANDLER":return IO.get(Mt.name).deserialize(Mt.value);case"RAW":return Mt.value}}function ok(Mt,dr,Cr,Pr){return new Promise(yn=>{const En=WU();dr.set(En,yn),Mt.start&&Mt.start(),Mt.postMessage(Object.assign({id:En},Cr),Pr)})}function WU(){return new Array(4).fill(0).map(()=>Math.floor(Math.random()*Number.MAX_SAFE_INTEGER).toString(16)).join("-")}function ZU(){const Mt=Ld.useRef(null),dr=Ld.useRef(null),[Cr,Pr]=Ld.useState(!1);return Ld.useEffect(()=>{const En=new Worker(new URL("/assets/pyodide.worker-CrNRKrWB.js",import.meta.url),{type:"module"}),$n=OO(En);return Mt.current=$n,dr.current=En,(async()=>{try{await $n.setErrorHandler(jO(Ca=>{alert(Ca)})),await $n.init(),console.log("Pyodide intialized"),Pr(!0)}catch(Ca){console.error("Failed to initialize Pyodide backend:",Ca)}})(),()=>{Mt.current&&(Mt.current[PO](),Mt.current=null),dr.current?.terminate(),dr.current=null,Pr(!1)}},[]),{getBackend:Ld.useCallback(()=>{if(!Mt.current)throw new Error("Pyodide backend is not ready");return Mt.current},[]),backendReady:Cr}}const YU={inputColumns:"1,2",outputColumn:"3",normalizerType:"None",normalNoiseStd:"0.0",projectionType:"Coordinates",x1Column:"1",x2Column:"2"},XU=500,KU=[-10,10],$U=[-10,10];function JU(){const{getBackend:Mt,backendReady:dr}=ZU(),[Cr,Pr]=Ld.useState({xPoints:[],yPoints:[],labels:[]}),yn=new fF(Cr.labels),[En,$n]=Ld.useState(!0),[Ca,ni]=Ld.useState(kb[0].name),[Ma,Ja]=Ld.useState(XU),fi=Ld.useRef(KU),Oi=Ld.useRef($U),[Si,Ps]=Ld.useState(0);function fl(qi,os){fi.current=qi,Oi.current=os,ji()}function au(qi,os){fi.current=qi,Oi.current=os,Ps(wi=>wi+1),console.log(fi.current,Oi.current)}const[ho,qe]=Ld.useState({type:"LogisticRegression",arguments:""});async function kl(qi){qe(qi),dr&&(await Mt().setModelConfig(qi),await ji())}const[lf,xl]=Ld.useState(YU),[Lo,Ml]=Ld.useState(null),[Xs,Ii]=Ld.useState(null),Yu=Ld.useRef(null);async function is(qi,os,wi){const Kl={xPoints:[...Cr.xPoints,qi],yPoints:[...Cr.yPoints,os],labels:[...Cr.labels,wi]};Pr(Kl),dr&&(await Mt().setDataset2d(Kl),await ji())}async function jl(){const qi={xPoints:Cr.xPoints.slice(0,-1),yPoints:Cr.yPoints.slice(0,-1),labels:Cr.labels.slice(0,-1)};Pr(qi),dr&&(await Mt().setDataset2d(qi),await ji())}async function df(){const qi={xPoints:[],yPoints:[],labels:[]};Pr(qi),dr&&(await Mt().setDataset2d(qi),await ji())}async function ji(){if(!dr)return;const qi={xmin:fi.current[0],xmax:fi.current[1],ymin:Oi.current[0],ymax:Oi.current[1],resolution:Ma},os=await Mt().getDecisionBoundary(qi);Ii(os)}async function oo(){dr&&(await Mt().buildModel(),await ji())}async function Yo(qi,os){const wi=os??lf;if(os&&xl(os),!dr){alert("Python backend is not ready yet.");return}const Kl=await qi.arrayBuffer();console.log(Kl);const El=await Mt().setDatasetCsv(NO(Kl,[Kl]),wi);El.status==="OK"?(Pr(El.dataPoints),El.xRange&&El.yRange&&au(El.xRange,El.yRange),Ml(null)):El.status==="CSV_ERROR"&&Ml(El.message),await ji()}async function ul(qi){if(!dr)return;xl(qi);const os=await Mt().setCsvSettings(qi);os.status==="OK"?(Pr(os.dataPoints),os.xRange&&os.yRange&&au(os.xRange,os.yRange),Ml(null)):os.status==="CSV_ERROR"&&Ml(os.message),await ji()}function Xl(qi,os){const wi=new Blob([os],{type:"text/csv;charset=utf-8"}),Kl=URL.createObjectURL(wi),El=document.createElement("a");El.href=Kl,El.download=qi,document.body.appendChild(El),El.click(),El.remove(),URL.revokeObjectURL(Kl)}async function Vf(){if(!dr){alert("Python backend is not ready yet.");return}const qi=await Mt().getDatasetCsv();Xl("dataset.csv",qi)}function Ui(){Yu.current&&Yu.current?.downloadSvg()}return console.log("rendering app"),Ld.useEffect(()=>{dr&&(async()=>(await Mt().setDataset2d(Cr),await Mt().setModelConfig(ho),await ji()))()},[dr,Mt]),{backendReady:dr,dataPoints:Cr,labelColors:yn,canAddPoints:En,setCanAddPoints:$n,pointLabel:Ca,setPointLabel:ni,xRangeRef:fi,yRangeRef:Oi,handleRangeChange:fl,rangeVersion:Si,modelSettings:ho,handleModelSettingsChange:kl,csvSettings:lf,handleCsvSettingsChange:ul,csvError:Lo,decisionBoundaryResult:Xs,handleAddDataPoint:is,handleUndoDataPoint:jl,handleClearDataPoints:df,handleGetDecisionBoundary:oo,handleCsvUpload:Yo,getCsvDataset:Vf,plotHandle:Yu,getPlotSvg:Ui}}function QU(){const Mt=JU();return yu.jsxs("div",{className:"grid grid-cols-[1fr_12fr_1fr] h-dvh bg-stone-50",children:[yu.jsx("div",{}),yu.jsxs("div",{className:"flex flex-col gap-6 p-6 min-h-0",children:[yu.jsx("div",{className:"title",children:"Decision Boundary Visualizer"}),yu.jsxs("div",{className:"grid grid-cols-[8fr_4fr] gap-12 flex-1 min-h-0",children:[yu.jsx(dF,{dataPoints:Mt.dataPoints,addDataPoint:Mt.handleAddDataPoint,decisionBoundaryResult:Mt.decisionBoundaryResult,xRangeRef:Mt.xRangeRef,yRangeRef:Mt.yRangeRef,setRanges:Mt.handleRangeChange,canAddPoints:Mt.canAddPoints,pointLabel:Mt.pointLabel,labelColors:Mt.labelColors,plotHandle:Mt.plotHandle}),yu.jsx(FU,{pointLabel:Mt.pointLabel,setPointLabel:Mt.setPointLabel,setCanAddPoints:Mt.setCanAddPoints,undoDataPoint:Mt.handleUndoDataPoint,clearDataPoints:Mt.handleClearDataPoints,modelSettings:Mt.modelSettings,setModelSettings:Mt.handleModelSettingsChange,csvSettings:Mt.csvSettings,onCsvSettingsChange:Mt.handleCsvSettingsChange,onGetDecisionBoundary:Mt.handleGetDecisionBoundary,onCsvUpload:Mt.handleCsvUpload,csvError:Mt.csvError,onCsvExport:Mt.getCsvDataset,onSvgExport:Mt.getPlotSvg})]})]}),yu.jsx("div",{})]})}KO.createRoot(document.getElementById("root")).render(yu.jsx(Ld.StrictMode,{children:yu.jsx(QU,{})}));
|
dist/assets/{pyodide.worker-CKAjTPz8.js → pyodide.worker-CrNRKrWB.js}
RENAMED
|
@@ -1,4 +1,4 @@
|
|
| 1 |
-
(function(){"use strict";const v=Symbol("Comlink.proxy"),O=Symbol("Comlink.endpoint"),T=Symbol("Comlink.releaseProxy"),C=Symbol("Comlink.finalizer"),g=Symbol("Comlink.thrown"),b=n=>typeof n=="object"&&n!==null||typeof n=="function",A={canHandle:n=>b(n)&&n[v],serialize(n){const{port1:e,port2:t}=new MessageChannel;return R(n,e),[t,[t]]},deserialize(n){return n.start(),z(n)}},k={canHandle:n=>b(n)&&g in n,serialize({value:n}){let e;return n instanceof Error?e={isError:!0,value:{message:n.message,name:n.name,stack:n.stack}}:e={isError:!1,value:n},[e,[]]},deserialize(n){throw n.isError?Object.assign(new Error(n.value.message),n.value):n.value}},
|
| 2 |
from dataclasses import asdict
|
| 3 |
|
| 4 |
from sklearn.exceptions import NotFittedError
|
|
@@ -18,6 +18,8 @@ class Manager:
|
|
| 18 |
|
| 19 |
def handle_set_dataset(self, dataset: dict) -> None:
|
| 20 |
self._reset_model()
|
|
|
|
|
|
|
| 21 |
|
| 22 |
try:
|
| 23 |
parsed_dataset = Dataset(
|
|
@@ -31,6 +33,8 @@ class Manager:
|
|
| 31 |
|
| 32 |
def handle_set_dataset_csv(self, args: dict) -> dict:
|
| 33 |
self._reset_model()
|
|
|
|
|
|
|
| 34 |
|
| 35 |
try:
|
| 36 |
buffer = args["buffer"]
|
|
|
|
| 1 |
+
(function(){"use strict";const v=Symbol("Comlink.proxy"),O=Symbol("Comlink.endpoint"),T=Symbol("Comlink.releaseProxy"),C=Symbol("Comlink.finalizer"),g=Symbol("Comlink.thrown"),b=n=>typeof n=="object"&&n!==null||typeof n=="function",A={canHandle:n=>b(n)&&n[v],serialize(n){const{port1:e,port2:t}=new MessageChannel;return R(n,e),[t,[t]]},deserialize(n){return n.start(),z(n)}},k={canHandle:n=>b(n)&&g in n,serialize({value:n}){let e;return n instanceof Error?e={isError:!0,value:{message:n.message,name:n.name,stack:n.stack}}:e={isError:!1,value:n},[e,[]]},deserialize(n){throw n.isError?Object.assign(new Error(n.value.message),n.value):n.value}},N=new Map([["proxy",A],["throw",k]]);function D(n,e){for(const t of n)if(e===t||t==="*"||t instanceof RegExp&&t.test(e))return!0;return!1}function R(n,e=globalThis,t=["*"]){e.addEventListener("message",function i(s){if(!s||!s.data)return;if(!D(t,s.origin)){console.warn(`Invalid origin '${s.origin}' for comlink proxy`);return}const{id:r,type:o,path:d}=Object.assign({path:[]},s.data),c=(s.data.argumentList||[]).map(f);let a;try{const l=d.slice(0,-1).reduce((u,_)=>u[_],n),p=d.reduce((u,_)=>u[_],n);switch(o){case"GET":a=p;break;case"SET":l[d.slice(-1)[0]]=f(s.data.value),a=!0;break;case"APPLY":a=p.apply(l,c);break;case"CONSTRUCT":{const u=new p(...c);a=F(u)}break;case"ENDPOINT":{const{port1:u,port2:_}=new MessageChannel;R(n,_),a=L(u,[u])}break;case"RELEASE":a=void 0;break;default:return}}catch(l){a={value:l,[g]:0}}Promise.resolve(a).catch(l=>({value:l,[g]:0})).then(l=>{const[p,u]=h(l);e.postMessage(Object.assign(Object.assign({},p),{id:r}),u),o==="RELEASE"&&(e.removeEventListener("message",i),w(e),C in n&&typeof n[C]=="function"&&n[C]())}).catch(l=>{const[p,u]=h({value:new TypeError("Unserializable return value"),[g]:0});e.postMessage(Object.assign(Object.assign({},p),{id:r}),u)})}),e.start&&e.start()}function M(n){return n.constructor.name==="MessagePort"}function w(n){M(n)&&n.close()}function z(n,e){const t=new Map;return n.addEventListener("message",function(s){const{data:r}=s;if(!r||!r.id)return;const o=t.get(r.id);if(o)try{o(r)}finally{t.delete(r.id)}}),S(n,t,[],e)}function y(n){if(n)throw new Error("Proxy has been released and is not useable")}function P(n){return m(n,new Map,{type:"RELEASE"}).then(()=>{w(n)})}const x=new WeakMap,E="FinalizationRegistry"in globalThis&&new FinalizationRegistry(n=>{const e=(x.get(n)||0)-1;x.set(n,e),e===0&&P(n)});function I(n,e){const t=(x.get(e)||0)+1;x.set(e,t),E&&E.register(n,e,n)}function B(n){E&&E.unregister(n)}function S(n,e,t=[],i=function(){}){let s=!1;const r=new Proxy(i,{get(o,d){if(y(s),d===T)return()=>{B(r),P(n),e.clear(),s=!0};if(d==="then"){if(t.length===0)return{then:()=>r};const c=m(n,e,{type:"GET",path:t.map(a=>a.toString())}).then(f);return c.then.bind(c)}return S(n,e,[...t,d])},set(o,d,c){y(s);const[a,l]=h(c);return m(n,e,{type:"SET",path:[...t,d].map(p=>p.toString()),value:a},l).then(f)},apply(o,d,c){y(s);const a=t[t.length-1];if(a===O)return m(n,e,{type:"ENDPOINT"}).then(f);if(a==="bind")return S(n,e,t.slice(0,-1));const[l,p]=V(c);return m(n,e,{type:"APPLY",path:t.map(u=>u.toString()),argumentList:l},p).then(f)},construct(o,d){y(s);const[c,a]=V(d);return m(n,e,{type:"CONSTRUCT",path:t.map(l=>l.toString()),argumentList:c},a).then(f)}});return I(r,n),r}function U(n){return Array.prototype.concat.apply([],n)}function V(n){const e=n.map(h);return[e.map(t=>t[0]),U(e.map(t=>t[1]))]}const j=new WeakMap;function L(n,e){return j.set(n,e),n}function F(n){return Object.assign(n,{[v]:!0})}function h(n){for(const[e,t]of N)if(t.canHandle(n)){const[i,s]=t.serialize(n);return[{type:"HANDLER",name:e,value:i},s]}return[{type:"RAW",value:n},j.get(n)||[]]}function f(n){switch(n.type){case"HANDLER":return N.get(n.name).deserialize(n.value);case"RAW":return n.value}}function m(n,e,t,i){return new Promise(s=>{const r=H();e.set(r,s),n.start&&n.start(),n.postMessage(Object.assign({id:r},t),i)})}function H(){return new Array(4).fill(0).map(()=>Math.floor(Math.random()*Number.MAX_SAFE_INTEGER).toString(16)).join("-")}var G=`import csv
|
| 2 |
from dataclasses import asdict
|
| 3 |
|
| 4 |
from sklearn.exceptions import NotFittedError
|
|
|
|
| 18 |
|
| 19 |
def handle_set_dataset(self, dataset: dict) -> None:
|
| 20 |
self._reset_model()
|
| 21 |
+
self._projector = None
|
| 22 |
+
self._preprocessor = None
|
| 23 |
|
| 24 |
try:
|
| 25 |
parsed_dataset = Dataset(
|
|
|
|
| 33 |
|
| 34 |
def handle_set_dataset_csv(self, args: dict) -> dict:
|
| 35 |
self._reset_model()
|
| 36 |
+
self._projector = None
|
| 37 |
+
self._preprocessor = None
|
| 38 |
|
| 39 |
try:
|
| 40 |
buffer = args["buffer"]
|
dist/index.html
CHANGED
|
@@ -5,7 +5,7 @@
|
|
| 5 |
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
|
| 6 |
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
| 7 |
<title>Decision Boundary</title>
|
| 8 |
-
<script type="module" crossorigin src="/assets/index-
|
| 9 |
<link rel="stylesheet" crossorigin href="/assets/index-CzJqFli5.css">
|
| 10 |
</head>
|
| 11 |
<body>
|
|
|
|
| 5 |
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
|
| 6 |
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
| 7 |
<title>Decision Boundary</title>
|
| 8 |
+
<script type="module" crossorigin src="/assets/index-D01VFfwo.js"></script>
|
| 9 |
<link rel="stylesheet" crossorigin href="/assets/index-CzJqFli5.css">
|
| 10 |
</head>
|
| 11 |
<body>
|