From 39b137ed63e0906f8c56ea5a6ad9c97c4c90e661 Mon Sep 17 00:00:00 2001 From: Vladimir Mandic Date: Thu, 6 Jan 2022 07:59:13 -0500 Subject: [PATCH] add node with wasm build target --- .build.json | 16 + CHANGELOG.md | 9 +- dist/face-api.esm-nobundle.js | 2 +- dist/face-api.esm.js | 2 +- dist/face-api.js | 2 +- dist/face-api.node-gpu.js | 2 +- dist/face-api.node-wasm.js | 4691 +++++++++++++++++ dist/face-api.node.js | 2 +- src/tfjs/tf-node-wasm.ts | 5 + typedoc/classes/AgeGenderNet.html | 2 +- typedoc/classes/BoundingBox.html | 2 +- typedoc/classes/Box.html | 2 +- typedoc/classes/ComposableTask.html | 2 +- .../ComputeAllFaceDescriptorsTask.html | 2 +- .../ComputeFaceDescriptorsTaskBase.html | 2 +- .../ComputeSingleFaceDescriptorTask.html | 2 +- .../classes/DetectAllFaceLandmarksTask.html | 2 +- typedoc/classes/DetectAllFacesTask.html | 2 +- .../classes/DetectFaceLandmarksTaskBase.html | 2 +- typedoc/classes/DetectFacesTaskBase.html | 2 +- .../DetectSingleFaceLandmarksTask.html | 2 +- typedoc/classes/DetectSingleFaceTask.html | 2 +- typedoc/classes/Dimensions.html | 2 +- typedoc/classes/FaceDetection.html | 2 +- typedoc/classes/FaceDetectionNet.html | 2 +- typedoc/classes/FaceExpressionNet.html | 2 +- typedoc/classes/FaceExpressions.html | 2 +- typedoc/classes/FaceLandmark68Net.html | 2 +- typedoc/classes/FaceLandmark68TinyNet.html | 2 +- typedoc/classes/FaceLandmarkNet.html | 2 +- typedoc/classes/FaceLandmarks.html | 2 +- typedoc/classes/FaceLandmarks5.html | 2 +- typedoc/classes/FaceLandmarks68.html | 2 +- typedoc/classes/FaceMatch.html | 2 +- typedoc/classes/FaceMatcher.html | 2 +- typedoc/classes/FaceRecognitionNet.html | 2 +- typedoc/classes/LabeledBox.html | 2 +- typedoc/classes/LabeledFaceDescriptors.html | 2 +- typedoc/classes/NetInput.html | 2 +- typedoc/classes/NeuralNetwork.html | 2 +- typedoc/classes/ObjectDetection.html | 2 +- typedoc/classes/Point.html | 2 +- typedoc/classes/PredictedBox.html | 2 +- typedoc/classes/Rect.html | 2 +- typedoc/classes/SsdMobilenetv1.html | 2 +- typedoc/classes/SsdMobilenetv1Options.html | 2 +- typedoc/classes/TinyFaceDetector.html | 2 +- typedoc/classes/TinyFaceDetectorOptions.html | 2 +- typedoc/classes/TinyYolov2.html | 2 +- typedoc/classes/TinyYolov2Options.html | 2 +- typedoc/classes/draw.DrawBox.html | 2 +- typedoc/classes/draw.DrawBoxOptions.html | 2 +- typedoc/classes/draw.DrawFaceLandmarks.html | 2 +- .../draw.DrawFaceLandmarksOptions.html | 2 +- typedoc/classes/draw.DrawTextField.html | 2 +- .../classes/draw.DrawTextFieldOptions.html | 2 +- typedoc/enums/Gender.html | 2 +- typedoc/enums/draw.AnchorPosition.html | 2 +- typedoc/index.html | 2 +- typedoc/interfaces/IBoundingBox.html | 2 +- typedoc/interfaces/IDimensions.html | 2 +- typedoc/interfaces/IFaceDetecion.html | 2 +- typedoc/interfaces/IFaceLandmarks.html | 2 +- typedoc/interfaces/IFaceMatch.html | 2 +- typedoc/interfaces/IPoint.html | 2 +- typedoc/interfaces/IRect.html | 2 +- .../interfaces/ISsdMobilenetv1Options.html | 2 +- typedoc/interfaces/ITinyYolov2Options.html | 2 +- typedoc/interfaces/draw.IDrawBoxOptions.html | 2 +- .../draw.IDrawFaceLandmarksOptions.html | 2 +- .../draw.IDrawTextFieldOptions.html | 2 +- typedoc/modules/draw.html | 2 +- typedoc/modules/utils.html | 2 +- 73 files changed, 4787 insertions(+), 72 deletions(-) create mode 100644 dist/face-api.node-wasm.js create mode 100644 src/tfjs/tf-node-wasm.ts diff --git a/.build.json b/.build.json index 42fd31d..a5f2d35 100644 --- a/.build.json +++ b/.build.json @@ -69,6 +69,22 @@ "output": "dist/face-api.node-gpu.js", "external": ["@tensorflow"] }, + { + "name": "tfjs/node/wasm", + "platform": "node", + "format": "cjs", + "input": "src/tfjs/tf-node-wasm.ts", + "output": "dist/tfjs.esm.js", + "external": ["@tensorflow"] + }, + { + "name": "faceapi/node/wasm", + "platform": "node", + "format": "cjs", + "input": "src/index.ts", + "output": "dist/face-api.node-wasm.js", + "external": ["@tensorflow"] + }, { "name": "tfjs/browser/tf-version", "platform": "browser", diff --git a/CHANGELOG.md b/CHANGELOG.md index 481399d..5727ebf 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,12 +9,15 @@ ## Changelog +### **1.6.3** 2022/01/06 mandic00@live.com + + +### **origin/master** 2022/01/01 mandic00@live.com + + ### **1.6.2** 2022/01/01 mandic00@live.com -### **origin/master** 2021/12/27 mandic00@live.com - - ### **1.6.1** 2021/12/09 mandic00@live.com - rebuild diff --git a/dist/face-api.esm-nobundle.js b/dist/face-api.esm-nobundle.js index 88b3f18..d04caca 100644 --- a/dist/face-api.esm-nobundle.js +++ b/dist/face-api.esm-nobundle.js @@ -2135,7 +2135,7 @@ function drawFaceLandmarks(canvasArg, faceLandmarks) { } // package.json -var version10 = "1.6.2"; +var version10 = "1.6.3"; // src/xception/extractParams.ts function extractorsFactory2(extractWeights, paramMappings) { diff --git a/dist/face-api.esm.js b/dist/face-api.esm.js index ababfa9..cae3d92 100644 --- a/dist/face-api.esm.js +++ b/dist/face-api.esm.js @@ -65931,7 +65931,7 @@ function drawFaceLandmarks(canvasArg, faceLandmarks) { } // package.json -var version5 = "1.6.2"; +var version5 = "1.6.3"; // src/xception/extractParams.ts function extractorsFactory2(extractWeights, paramMappings) { diff --git a/dist/face-api.js b/dist/face-api.js index 91c250e..54808fd 100644 --- a/dist/face-api.js +++ b/dist/face-api.js @@ -4616,7 +4616,7 @@ return a / b;`,bte=` } `}};function tse(e){let{inputs:t,backend:n,attrs:r}=e,{x:s,segmentIds:a}=t,{numSegments:o}=r,i=s.shape.length,c=[],l=0,u=_.getAxesPermutation([l],i),d=s;u!=null&&(d=Tn({inputs:{x:s},backend:n,attrs:{perm:u}}),c.push(d),l=_.getInnerMostAxes(1,i)[0]);let p=_.segment_util.computeOutShape(d.shape,l,o),h=k.sizeFromShape([d.shape[l]]),f=ge({inputs:{x:d},backend:n,attrs:{shape:[-1,h]}});c.push(f);let m=Mh(s.dtype),g=(x,w,T,C,D)=>{let F=x.shape[0],O=x.shape[1],$=_.segment_util.segOpComputeOptimalWindowSize(O,D),R={windowSize:$,inSize:O,batchSize:F,numSegments:D},N=new ese(R,w),L=n.compileAndRun(N,[x,T],C);if(c.push(L),L.shape[1]===D)return L;let G=y_({backend:n,attrs:{start:0,stop:D,step:1,dtype:"float32"}}),j=I_({inputs:{x:G},backend:n,attrs:{reps:[O/$]}});return c.push(G),c.push(j),g(L,w,j,C,D)},b=g(f,"unsortedSegmentSum",a,m,o),y=ge({inputs:{x:b},backend:n,attrs:{shape:p}}),v=y;if(u!=null){c.push(y);let x=_.getUndoAxesPermutation(u);v=Tn({inputs:{x:v},backend:n,attrs:{perm:x}})}return c.forEach(x=>n.disposeIntermediateTensorInfo(x)),v}var nse={kernelName:zl,backendName:"webgl",kernelFunc:tse},rse=[Dee,Ree,mY,bY,xY,IY,TY,_Y,AY,FY,OY,LY,WY,GY,ZY,qY,eZ,sZ,nZ,cZ,lZ,pZ,gZ,IZ,TZ,NZ,$Z,PZ,BZ,VZ,Y9,qZ,rJ,aJ,ZZ,uJ,dJ,iJ,fJ,bJ,xJ,kJ,SJ,NJ,$J,PJ,EJ,LJ,WJ,UJ,qJ,ZJ,tQ,sQ,aQ,oQ,cQ,lQ,pQ,fQ,gQ,xQ,IQ,CQ,_Q,DQ,RQ,LQ,VQ,X9,GQ,HZ,qQ,YQ,QQ,J9,ree,iee,uee,gee,hee,xee,Iee,Nee,Oee,Gee,Vee,Kee,Yee,Jee,zee,ete,nte,ote,lte,fte,kte,rY,Ste,Nte,Ate,$te,EZ,Ote,Lte,zte,Ute,qte,eY,Xte,Yte,AZ,yte,Qte,ine,rne,aY,dne,fne,yne,wne,Tne,Nne,Ane,$ne,Pne,Lne,Wne,Une,jne,Xne,Jne,wZ,xte,tre,rre,are,ire,ure,dre,hre,mre,bre,xre,kre,Sre,Nre,Ere,Dre,$re,vte,pY,Ore,Bre,Vre,jre,Xre,hY,Zre,Qre,nse,Mte];for(let e of rse)Vl(e);var $t;(function(e){e[e.float32=0]="float32",e[e.int32=1]="int32",e[e.bool=2]="bool",e[e.string=3]="string",e[e.complex64=4]="complex64"})($t||($t={}));var Yd;(function(e){e[e.linear=0]="linear",e[e.relu=1]="relu",e[e.relu6=2]="relu6",e[e.prelu=3]="prelu",e[e.leakyrelu=4]="leakyrelu",e[e.sigmoid=5]="sigmoid",e[e.elu=6]="elu"})(Yd||(Yd={}));var T_;function sse(e){T_=e.wasm.cwrap(Oo,null,["number","array","number","number","array","number","number","number","number","number","number","number","number"])}function ase(e){let{inputs:t,backend:n,attrs:r}=e,{a:s,b:a,bias:o,preluActivationWeights:i}=t;if(s.dtype!=="float32"||a.dtype!=="float32")throw new Error("_FusedMatMul for non non-float32 tensors not yet supported.");let{transposeA:c,transposeB:l,activation:u,leakyreluAlpha:d}=r,p=n.dataIdMap.get(s.dataId).id,h=n.dataIdMap.get(a.dataId).id,f=0;if(o!=null){let D=n.dataIdMap.get(o.dataId);if(D.shape.length!==1)throw new Error(`_FusedMatMul only supports rank-1 bias but got rank ${D.shape.length}.`);f=D.id}let m=i==null?0:n.dataIdMap.get(i.dataId).id,g=Yd[u];if(g==null)throw new Error(`${u} activation not yet supported for FusedConv2D in the wasm backend.`);let b=c?s.shape[2]:s.shape[1],y=l?a.shape[1]:a.shape[2],v=su.assertAndGetBroadcastShape(s.shape.slice(0,-2),a.shape.slice(0,-2)),x=n.makeOutput([...v,b,y],s.dtype),w=n.dataIdMap.get(x.dataId).id,T=new Uint8Array(new Int32Array(s.shape).buffer),C=new Uint8Array(new Int32Array(a.shape).buffer);return T_(p,T,s.shape.length,h,C,a.shape.length,c,l,g,f,m,d||0,w),x}var ose={kernelName:Oo,backendName:"wasm",setupFunc:sse,kernelFunc:ase};function un(e,t){let n;function r(a){n=a.wasm.cwrap(e,null,["number","number","number"])}function s(a){let{backend:o,inputs:{x:i}}=a,c=o.dataIdMap.get(i.dataId).id,l=o.makeOutput(i.shape,t||i.dtype),u=o.dataIdMap.get(l.dataId).id;return k.sizeFromShape(l.shape)===0||n(c,$t[i.dtype],u),l}return{kernelName:e,backendName:"wasm",setupFunc:r,kernelFunc:s}}var ise=un(Yi);function Cn(e,t,n){let r;function s(o){r=o.wasm.cwrap(e,null,["number","array","number","number","array","number","number","number"])}function a(o){let{backend:i,inputs:c}=o,{a:l,b:u}=c,d=i.dataIdMap.get(l.dataId).id,p=i.dataIdMap.get(u.dataId).id,h=n!=null?n:l.dtype,f=_.assertAndGetBroadcastShape(l.shape,u.shape),m=i.makeOutput(f,h);if(k.sizeFromShape(f)===0)return m;let g=new Uint8Array(new Int32Array(l.shape).buffer),b=new Uint8Array(new Int32Array(u.shape).buffer),y=i.dataIdMap.get(m.dataId).id;return(()=>r(d,g,l.shape.length,p,b,u.shape.length,$t[l.dtype],y))(),m}return{kernelName:e,backendName:"wasm",setupFunc:s,kernelFunc:a}}var cse=!0,use=Cn(Zs,cse),C_;function lse(e){C_=e.wasm.cwrap(Ba,null,["array","number","number","number"])}function dse(e){let{inputs:t,backend:n}=e,r=n.makeOutput(t[0].shape,t[0].dtype);if(k.sizeFromShape(r.shape)===0)return r;let s=t.map(i=>n.dataIdMap.get(i.dataId).id),a=new Uint8Array(new Int32Array(s).buffer),o=n.dataIdMap.get(r.dataId).id;return C_(a,s.length,$t[r.dtype],o),r}var pse={kernelName:Ba,backendName:"wasm",setupFunc:lse,kernelFunc:dse};function Pm(e){let{inputs:{x:t},backend:n}=e,r=n.makeOutput(t.shape,t.dtype),s=n.typedArrayFromHeap(t);return n.typedArrayFromHeap(r).set(s),r}var hse={kernelName:so,backendName:"wasm",kernelFunc:Pm},N_;function fse(e){N_=e.wasm.cwrap(Po,null,["number","array","number","number","number","array","number"])}function Bu(e){let{inputs:t,backend:n,attrs:r}=e,[s,a]=gse(t.x.shape,r.perm),o=!0;for(let f=0;f=s&&(a===-1||r[a]>r[o])&&(a=o);r[a]=s}return[n,r]}var bse={kernelName:Po,backendName:"wasm",kernelFunc:Bu,setupFunc:fse};function Ca(e,t,n){let r=e.shape,s=e.shape.length,a=k.parseAxisParam(t,r),o=a,i=_.getAxesPermutation(o,s),c=null,l=!1;if(i!=null){let u=new Array(s);for(let h=0;h`new shape: ${o}, old shape: ${r.shape}. New shape and old shape must have the same number of elements.`),e.backend.incRef(r.dataId),{dataId:r.dataId,shape:o,dtype:r.dtype}}var Ase={kernelName:Pc,backendName:"wasm",kernelFunc:Vn},F_;function Dse(e){F_=e.wasm.cwrap(Va,null,["number","array","number","number","array","number","number","number","number"])}function Fse(e){let{inputs:t,backend:n,attrs:r}=e,{a:s,b:a}=t,{transposeA:o,transposeB:i}=r;if(s.dtype!=="float32"||a.dtype!=="float32")throw new Error("BatchMatMul for non non-float32 tensors not yet supported.");let c=s.shape.length,l=a.shape.length,u=o?s.shape[c-2]:s.shape[c-1],d=i?a.shape[l-1]:a.shape[l-2],p=o?s.shape[c-1]:s.shape[c-2],h=i?a.shape[l-2]:a.shape[l-1],f=s.shape.slice(0,-2),m=a.shape.slice(0,-2),g=k.sizeFromShape(f),b=k.sizeFromShape(m),v=su.assertAndGetBroadcastShape(s.shape.slice(0,-2),a.shape.slice(0,-2)).concat([p,h]);k.assert(u===d,()=>`Error in matMul: inner shapes (${u}) and (${d}) of Tensors with shapes ${s.shape} and ${a.shape} and transposeA=${o} and transposeB=${i} must match.`);let x=o?[g,u,p]:[g,p,u],w=i?[b,h,d]:[b,d,h],T=Vn({inputs:{x:s},backend:n,attrs:{shape:x}}),C=Vn({inputs:{x:a},backend:n,attrs:{shape:w}}),D=n.dataIdMap.get(T.dataId).id,F=n.dataIdMap.get(C.dataId).id,O=o?T.shape[2]:T.shape[1],$=i?C.shape[1]:C.shape[2],R=Math.max(g,b),N=n.makeOutput([R,O,$],T.dtype),L=n.dataIdMap.get(N.dataId).id,G=new Uint8Array(new Int32Array(T.shape).buffer),j=new Uint8Array(new Int32Array(C.shape).buffer);return F_(D,G,T.shape.length,F,j,C.shape.length,o,i,L),n.disposeData(T.dataId),n.disposeData(C.dataId),N.shape=v,N}var $se={kernelName:Va,backendName:"wasm",setupFunc:Dse,kernelFunc:Fse};function xi(e){let{inputs:{x:t},attrs:{begin:n,size:r},backend:s}=e,[a,o]=Gt.parseSliceParams(t,n,r),i=Gt.isSliceContinous(t.shape,a,o),c=s.readSync(t.dataId),l=s.makeOutput(o,t.dtype),u=k.computeStrides(t.shape),d=s.dataIdMap.get(l.dataId);if(i){let f=Gt.computeFlatOffset(a,u);return t.dtype==="string"?d.stringBytes=c.slice(f,f+k.sizeFromShape(o)):s.typedArrayFromHeap(l).set(c.subarray(f,f+k.sizeFromShape(o))),l}if(t.dtype==="string"){let f=pm(c,a,o,t.shape,t.dtype);return d.stringBytes=f,l}let p=s.typedArrayFromHeap(l),h=t.shape.length;if(h===2)Rse(c,u[0],p,a,o);else if(h===3)Pse(c,u[0],u[1],p,a,o);else if(h===4)Ose(c,u[0],u[1],u[2],p,a,o);else{let f=pm(c,a,o,t.shape,t.dtype);p.set(f)}return l}function Rse(e,t,n,r,s){let a=0,o=r[0],i=r[1],c=o+s[0];for(let l=o;lb*y),c=_.getReshaped(s.shape,a,i),l=_.getPermuted(c.length,a.length),u=_.getReshapedPermuted(s.shape,a,i),d=_.getSliceBeginCoords(o,a.length),p=_.getSliceSize(u,o,a.length),h=Vn({inputs:{x:s},backend:n,attrs:{shape:c}}),f=Bu({inputs:{x:h},backend:n,attrs:{perm:l}}),m=Vn({inputs:{x:f},backend:n,attrs:{shape:u}}),g=xi({inputs:{x:m},backend:n,attrs:{begin:d,size:p}});return n.disposeData(h.dataId),n.disposeData(f.dataId),n.disposeData(h.dataId),g}var Bse={kernelName:oc,backendName:"wasm",kernelFunc:Lse};function Zd(e){let{inputs:{x:t},attrs:{dtype:n},backend:r}=e,s=r.makeOutput(t.shape,n),a=r.typedArrayFromHeap(t);return r.typedArrayFromHeap(s).set(a),s}var zse={kernelName:Ua,backendName:"wasm",kernelFunc:Zd},Wse=un(Ga),$_;function Vse(e){$_=e.wasm.cwrap(Js,null,["number","number","number","number"])}function Use(e){let{inputs:t,backend:n,attrs:r}=e,{x:s}=t,{clipValueMin:a,clipValueMax:o}=r,i=n.dataIdMap.get(s.dataId).id,c=n.makeOutput(s.shape,s.dtype),l=n.dataIdMap.get(c.dataId).id;return $_(i,a,o,l),c}var Gse={kernelName:Js,backendName:"wasm",setupFunc:Vse,kernelFunc:Use};function R_(e){let{inputs:t,backend:n}=e,r=k.parseAxisParam(e.attrs.axis,t[0].shape)[0],s=_.computeOutShape(t.map(h=>h.shape),r),a=t.filter(h=>k.sizeFromShape(h.shape)>0);if(a.length===1)return Pm({inputs:{x:a[0]},backend:n});let o=n.makeOutput(s,t[0].dtype);if(k.sizeFromShape(s)===0)return o;let i=a.map(h=>h.shape);if(_.assertParamsConsistent(i,r),a[0].dtype==="string"){let h=a.map(v=>{let x=k.sizeFromShape(v.shape.slice(r));return Vn({inputs:{x:v},backend:n,attrs:{shape:[-1,x]}})}),f=h.map(v=>({vals:n.readSync(v.dataId),shape:v.shape}));s=_.computeOutShape(h.map(v=>v.shape),1);let m=h[0].shape[0]===1,g=_w(f,s,t[0].dtype,m),b=_.computeOutShape(a.map(v=>v.shape),r);o.shape=b;let y=n.dataIdMap.get(o.dataId);return y.stringBytes=_.fromStringArrayToUint8(g),h.forEach(v=>n.disposeData(v.dataId)),o}let c=k.sizeFromShape(a[0].shape.slice(0,r)),l=0,u=a.map(h=>{let f=k.sizeFromShape(h.shape.slice(r));return l+=f,f}),d=a.map(h=>n.typedArrayFromHeap(h)),p=n.typedArrayFromHeap(o);for(let h=0;h`cumsum does not support ${s.dtype} tensors in the WASM backend`);let l=_.getAxesPermutation([a],c),u=s;l!==null&&(u=Bu({inputs:{x:s},attrs:{perm:l},backend:n}));let d=_.getInnerMostAxes(1,c)[0];_.assertAxesAreInnerMostDims("cumsum",[d],c);let p=n.makeOutput(u.shape,u.dtype),h=u.shape[d],f=n.dataIdMap.get(u.dataId).id,m=n.dataIdMap.get(p.dataId).id;L_(f,o?1:0,i?1:0,h,m,$t[s.dtype]);let g=p;if(l!==null){let b=_.getUndoAxesPermutation(l);g=Bu({inputs:{x:p},attrs:{perm:b},backend:n}),n.disposeData(u.dataId),n.disposeData(p.dataId)}return g}var aae={kernelName:Xa,backendName:"wasm",setupFunc:rae,kernelFunc:sae},B_;function oae(e){B_=e.wasm.cwrap(uc,null,["number","number","number","array","number","array","array","number","number"])}function iae(e){let{backend:t,inputs:n,attrs:r}=e,{x:s}=n,{blockSize:a,dataFormat:o}=r,i=s.shape[0],c=o==="NHWC"?s.shape[1]:s.shape[2],l=o==="NHWC"?s.shape[2]:s.shape[3],u=o==="NHWC"?s.shape[3]:s.shape[1],d=c*a,p=l*a,h=u/(a*a),f=o==="NHWC"?[i,d,p,h]:[i,h,d,p],m=t.makeOutput(f,"float32"),b=t.dataIdMap.get(s.dataId).id,y=new Uint8Array(new Int32Array(k.computeStrides(s.shape)).buffer),v=new Uint8Array(new Int32Array(f).buffer),x=new Uint8Array(new Int32Array(k.computeStrides(f)).buffer),w=t.dataIdMap.get(m.dataId).id;return B_(b,a,o==="NHWC"?1:0,y,s.shape.length-1,v,x,f.length,w),m}var cae={kernelName:uc,backendName:"wasm",setupFunc:oae,kernelFunc:iae},z_;function uae(e){z_=e.wasm.cwrap(Ya,null,["number","number","number","number","number","number","number","number","number","number","number","number","number","number","number","number","number","number","number"])}function lae(e){let{inputs:t,attrs:n,backend:r}=e,{x:s,filter:a}=t,o=r.dataIdMap.get(s.dataId).id,i=r.dataIdMap.get(a.dataId).id,{strides:c,dilations:l,pad:u,dimRoundingMode:d}=n,p=l==null?[1,1]:l,h=_.computeConv2DInfo(s.shape,a.shape,c,p,u,d,!0),f=h.filterHeight,m=h.filterWidth,g=h.padInfo.top,b=h.padInfo.right,y=h.padInfo.bottom,v=h.padInfo.left,x=h.dilationHeight,w=h.dilationWidth,T=h.strideHeight,C=h.strideWidth,D=h.inChannels,F=h.outChannels,O=h.padInfo.type==="SAME"?1:0;if(h.dataFormat!=="channelsLast")throw new Error(`wasm backend DepthwiseConv2dNative does not support dataFormat:'${h.dataFormat}'. Please use 'channelsLast'.`);let $=r.makeOutput(h.outShape,"float32"),R=r.dataIdMap.get($.dataId).id;return z_(o,s.shape[0],s.shape[1],s.shape[2],i,f,m,g,b,y,v,O,x,w,T,C,D,F,R),$}var dae={kernelName:Ya,backendName:"wasm",setupFunc:uae,kernelFunc:lae},pae=un(Ja),hae=!1,fae=Cn(dc,hae,"bool"),mae=un(Qa,"float32");function i1(e){let{inputs:t,attrs:n,backend:r}=e,{input:s}=t,{dim:a}=n,o=s.shape.length,i=s.shape.slice(),c=a;return a<0&&(k.assert(-(o+1)<=a,()=>`Axis must be in the interval [${-(o+1)}, ${o}]`),c=o+a+1),i.splice(c,0,1),Vn({inputs:{x:s},backend:r,attrs:{shape:i}})}var gae={kernelName:pc,backendName:"wasm",kernelFunc:i1};function W_(e){let{attrs:{shape:t,value:n,dtype:r},backend:s}=e,a=s.makeOutput(t,r);return s.typedArrayFromHeap(a).fill(n),a}var bae={kernelName:El,backendName:"wasm",kernelFunc:W_},V_;function yae(e){V_=e.wasm.cwrap(fc,null,["number","number","number","number","number","number"])}function vae(e){let{inputs:t,backend:n}=e,{image:r}=t,s=n.makeOutput(r.shape,r.dtype),a=n.dataIdMap.get(r.dataId).id,o=n.dataIdMap.get(s.dataId).id,[i,c,l,u]=r.shape;return V_(a,i,c,l,u,o),s}var xae={kernelName:fc,backendName:"wasm",kernelFunc:vae,setupFunc:yae},wae=un(eo),kae=!1,Iae=Cn(to,kae),U_;function Sae(e){U_=e.wasm.cwrap(no,null,["number","number","number","number","number","number","number"])}function Tae(e){let{backend:t,inputs:n,attrs:r}=e,{varianceEpsilon:s}=r,{x:a,mean:o,variance:i,offset:c,scale:l}=n,u=t.dataIdMap.get(a.dataId).id,d=t.dataIdMap.get(o.dataId).id,p=t.dataIdMap.get(i.dataId).id,h=c!=null?t.dataIdMap.get(c.dataId).id:0,f=l!=null?t.dataIdMap.get(l.dataId).id:0,m=t.makeOutput(a.shape,a.dtype);if(k.sizeFromShape(a.shape)===0)return m;let g=t.dataIdMap.get(m.dataId).id;return U_(u,d,p,h,f,s,g),m}var Cae={kernelName:no,backendName:"wasm",setupFunc:Sae,kernelFunc:Tae},G_;function Nae(e){G_=e.wasm.cwrap(Mo,null,["number","number","number","number","number","number","number","number","number","number","number","number","number","number","number","number","number","number","number","number","number","number","number"])}function _ae(e){let{inputs:t,attrs:n,backend:r}=e,{x:s,filter:a,bias:o,preluActivationWeights:i}=t,{strides:c,pad:l,dilations:u,dataFormat:d,dimRoundingMode:p,activation:h,leakyreluAlpha:f}=n,m=_.computeConv2DInfo(s.shape,a.shape,c,u,l,p),g=Yd[h];if(g==null)throw new Error(`${h} activation not yet supported for FusedConv2D in the wasm backend.`);let b=r.dataIdMap.get(s.dataId).id,y=r.dataIdMap.get(a.dataId).id,v=m.outChannels,x=0;if(o!=null){let re=r.dataIdMap.get(o.dataId);if(re.shape.length!==1)throw new Error(`FusedConv2D only supports rank-1 bias but got rank ${re.shape.length}.`);if(re.shape[0]!==v)throw new Error(`FusedConv2D bias shape (${re.shape}) does not match the number of output channels (${v})`);x=re.id}let w=m.filterHeight,T=m.filterWidth,C=m.padInfo.top,D=m.padInfo.right,F=m.padInfo.bottom,O=m.padInfo.left,$=m.dilationHeight,R=m.dilationWidth,N=m.strideHeight,L=m.strideWidth,G=m.inChannels,j=m.padInfo.type==="SAME"?1:0,K=m.batchSize,q=m.inHeight,Z=m.inWidth;if(d!=="NHWC")throw new Error(`wasm backend FusedConv2D does not support dataFormat:'${d}'. Please use 'NHWC'.`);let te=r.makeOutput(m.outShape,"float32"),se=r.dataIdMap.get(te.dataId).id,oe=i==null?0:r.dataIdMap.get(i.dataId).id;return G_(b,K,q,Z,y,w,T,x,C,D,F,O,j,$,R,N,L,G,v,g,oe,f||0,se),te}var Eae={kernelName:Mo,backendName:"wasm",setupFunc:Nae,kernelFunc:_ae},H_;function Aae(e){H_=e.wasm.cwrap(Lo,null,["number","number","number","number","number","number","number","number","number","number","number","number","number","number","number","number","number","number","number","number","number","number","number"])}function Dae(e){let{inputs:t,attrs:n,backend:r}=e,{x:s,filter:a,bias:o,preluActivationWeights:i}=t,{strides:c,pad:l,dilations:u,dataFormat:d,dimRoundingMode:p,activation:h,leakyreluAlpha:f}=n,m=_.computeConv2DInfo(s.shape,a.shape,c,u,l,p,!0),g=Yd[h];if(g==null)throw new Error(`${h} activation not yet supported for FusedDepthwiseConv2D in the wasm backend.`);let b=r.dataIdMap.get(s.dataId).id,y=r.dataIdMap.get(a.dataId).id,v=m.outChannels,x=0;if(o!=null){let re=r.dataIdMap.get(o.dataId);if(re.shape.length!==1)throw new Error(`FusedDepthwiseConv2D only supports rank-1 bias but got rank ${re.shape.length}.`);if(re.shape[0]!==v)throw new Error(`FusedDepthwiseConv2D bias shape (${re.shape}) does not match the number of output channels (${v})`);x=re.id}let w=m.filterHeight,T=m.filterWidth,C=m.padInfo.top,D=m.padInfo.right,F=m.padInfo.bottom,O=m.padInfo.left,$=m.dilationHeight,R=m.dilationWidth,N=m.strideHeight,L=m.strideWidth,G=m.inChannels,j=m.padInfo.type==="SAME"?1:0,K=m.batchSize,q=m.inHeight,Z=m.inWidth;if(d!=="NHWC")throw new Error(`wasm backend FusedDepthwiseConv2D does not support dataFormat:'${d}'. Please use 'NHWC'.`);let te=r.makeOutput(m.outShape,"float32"),se=r.dataIdMap.get(te.dataId).id,oe=i==null?0:r.dataIdMap.get(i.dataId).id;return H_(b,K,q,Z,y,w,T,x,C,D,F,O,j,$,R,N,L,G,v,g,oe,f||0,se),te}var Fae={kernelName:Lo,backendName:"wasm",setupFunc:Aae,kernelFunc:Dae},j_;function $ae(e){j_=e.wasm.cwrap(gc,null,["number","number","number","number","number","number","array","number"])}function Rae(e){let{backend:t,inputs:n}=e,{params:r,indices:s}=n,[a,o,i,c]=xy.prepareAndValidate(r,s),l=t.makeOutput(a,r.dtype);if(o===0)return l;let u=s.shape,d=u[u.length-1],h=t.dataIdMap.get(r.dataId).id,m=t.dataIdMap.get(s.dataId).id,g=new Uint8Array(new Int32Array(c).buffer),b=t.dataIdMap.get(l.dataId).id;return j_(h,$t[r.dtype],m,o,d,i,g,b),l}var Pae={kernelName:gc,backendName:"wasm",setupFunc:$ae,kernelFunc:Rae},q_;function Oae(e){q_=e.wasm.cwrap("Gather",null,["number","number","array","number","number","number","array","number"])}function Mae(e){let{backend:t,inputs:n,attrs:r}=e,{x:s,indices:a}=n,{axis:o,batchDims:i}=r,c=k.parseAxisParam(o,s.shape)[0],l=t.readSync(a.dataId),u=s.shape[c];for(let F=0;F=0,()=>`GatherV2: the index value ${O} is not in [0, ${u-1}]`)}let d=_.segment_util.collectGatherOpShapeInfo(s,a,c,i),p=Vn({inputs:{x:s},attrs:{shape:[d.batchSize,d.outerSize,d.dimSize,d.sliceSize]},backend:t}),h=k.sizeFromShape(a.shape),f=Vn({inputs:{x:a},attrs:{shape:[d.batchSize,h/d.batchSize]},backend:t}),m=[d.batchSize,d.outerSize,h/d.batchSize,d.sliceSize],g=t.makeOutput(m,s.dtype);if(k.sizeFromShape(s.shape)===0)return g;let b=p.shape.length-1,v=t.dataIdMap.get(p.dataId).id,w=t.dataIdMap.get(f.dataId).id,T=t.dataIdMap.get(g.dataId).id,C=new Uint8Array(new Int32Array(k.computeStrides(p.shape)).buffer),D=new Uint8Array(new Int32Array(k.computeStrides(m)).buffer);return q_(v,$t[s.dtype],C,b,w,d.batchSize,D,T),t.disposeData(p.dataId),t.disposeData(f.dataId),g.shape=d.outputShape,g}var Lae={kernelName:mc,backendName:"wasm",setupFunc:Oae,kernelFunc:Mae},Bae=!1,zae=Cn(bc,Bae,"bool"),Wae=!1,Vae=Cn(ro,Wae,"bool"),K_;function Uae(e){K_=e.wasm.cwrap(ao,null,["number","number","number","number"])}function Gae(e){let{inputs:{x:t},attrs:{alpha:n},backend:r}=e,s=r.dataIdMap.get(t.dataId).id,a=r.makeOutput(t.shape,"float32");if(k.sizeFromShape(t.shape)!==0){let o=r.dataIdMap.get(a.dataId).id;K_(s,$t[t.dtype],n,o)}return a}var Hae={kernelName:ao,backendName:"wasm",setupFunc:Uae,kernelFunc:Gae},jae=!1,qae=Cn(wc,jae,"bool"),Kae=!1,Xae=Cn(kc,Kae,"bool"),Yae=un(oo),Zae=!1,Jae=Cn(Sc,Zae,"bool"),X_;function Qae(e){X_=e.wasm.cwrap(io,null,["number","number","number","number"])}function eoe(e){let{backend:t,inputs:n,attrs:r}=e,{reductionIndices:s,keepDims:a}=r,{x:o}=n,c=t.dataIdMap.get(o.dataId).id,l=o,{transposed:u,axes:d,originalAxes:p,inputWasTransposed:h}=Ca(o,s,t);if(h){let v=t.dataIdMap.get(u.dataId).id;l=u,c=v}let f=l.shape.length;_.assertAxesAreInnerMostDims("max",d,f);let[m,g]=_.computeOutAndReduceShapes(l.shape,d),b=k.sizeFromShape(g),y=t.makeOutput(m,o.dtype);if(k.sizeFromShape(l.shape)!==0){let v=t.dataIdMap.get(y.dataId).id;X_(c,$t[o.dtype],b,v)}if(h&&t.disposeData(u.dataId),a){let v=_.expandShapeToKeepDim(y.shape,p);y.shape=v}return y}var toe={kernelName:io,backendName:"wasm",setupFunc:Qae,kernelFunc:eoe},noe=!1,roe=Cn(co,noe),Y_;function soe(e){Y_=e.wasm.cwrap(uo,null,["number","number","number","number","number","number","number","number","number","number","number","number","number","number","number","number","number"])}function aoe(e){let{inputs:t,attrs:n,backend:r}=e,s=t.x,a=r.dataIdMap.get(s.dataId).id;k.assert(s.dtype==="float32",()=>`Error in MaxPool: only float32 input is supported. Got ${s.dtype}.`);let{filterSize:o,strides:i,pad:c,dimRoundingMode:l}=n,u=_.computePool2DInfo(s.shape,o,i,1,c,l),d=u.filterHeight,p=u.filterWidth,h=u.padInfo.top,f=u.padInfo.right,m=u.padInfo.bottom,g=u.padInfo.left,b=u.dilationHeight,y=u.dilationWidth,v=u.strideHeight,x=u.strideWidth,w=u.inChannels,T=u.outChannels;if(u.dataFormat!=="channelsLast")throw new Error(`wasm backend does not support dataFormat:'${u.dataFormat}'. Please use 'channelsLast'.`);let C=r.makeOutput(u.outShape,"float32"),D=r.dataIdMap.get(C.dataId).id;return Y_(a,s.shape[0],s.shape[1],s.shape[2],d,p,h,f,m,g,b,y,v,x,w,T,D),C}var ooe={kernelName:uo,backendName:"wasm",setupFunc:soe,kernelFunc:aoe},Z_;function ioe(e){Z_=e.wasm.cwrap(lo,null,["number, number, number"])}function coe(e){let{backend:t,inputs:n,attrs:r}=e,{axis:s,keepDims:a}=r,{x:o}=n,i=t.dataIdMap.get(o.dataId).id,c=i,l=o,{transposed:u,axes:d,originalAxes:p,inputWasTransposed:h}=Ca(o,s,t),f=d;if(h){let x=t.dataIdMap.get(u.dataId).id;x!==i&&(l=u,c=x,f=_.getInnerMostAxes(f.length,l.shape.length))}_.assertAxesAreInnerMostDims("mean",f,l.shape.length);let[m,g]=_.computeOutAndReduceShapes(l.shape,f),b=k.sizeFromShape(g),y=l;l.dtype!=="float32"&&(y=Zd({backend:t,inputs:{x:l},attrs:{dtype:"float32"}}),c=t.dataIdMap.get(y.dataId).id);let v=t.makeOutput(m,"float32");if(k.sizeFromShape(l.shape)!==0){let x=t.dataIdMap.get(v.dataId).id;Z_(c,b,x)}if(h&&t.disposeData(u.dataId),a){let x=_.expandShapeToKeepDim(v.shape,p);v.shape=x}return l.dtype!=="float32"&&t.disposeData(y.dataId),v}var uoe={kernelName:lo,backendName:"wasm",setupFunc:ioe,kernelFunc:coe},J_;function loe(e){J_=e.wasm.cwrap(po,null,["number","number","number","number"])}function doe(e){let{backend:t,inputs:n,attrs:r}=e,{axis:s,keepDims:a}=r,{x:o}=n,i=t.dataIdMap.get(o.dataId).id,c=i,l=o,{transposed:u,axes:d,originalAxes:p,inputWasTransposed:h}=Ca(o,s,t);if(h){let v=t.dataIdMap.get(u.dataId).id;v!==i&&(l=u,c=v)}let f=l.shape.length;_.assertAxesAreInnerMostDims("min",d,f);let[m,g]=_.computeOutAndReduceShapes(l.shape,d),b=k.sizeFromShape(g),y=t.makeOutput(m,l.dtype);if(k.sizeFromShape(l.shape)!==0){let v=t.dataIdMap.get(y.dataId).id;J_(c,$t[o.dtype],b,v)}if(h&&t.disposeData(u.dataId),a){let v=_.expandShapeToKeepDim(y.shape,p);y.shape=v}return y}var poe={kernelName:po,backendName:"wasm",setupFunc:loe,kernelFunc:doe},hoe=!1,foe=Cn(ho,hoe),c1;(function(e){e[e.reflect=0]="reflect",e[e.symmetric=1]="symmetric"})(c1||(c1={}));var Q_;function moe(e){Q_=e.wasm.cwrap(fo,null,["number","array","number","number","array","array","number","number"])}function goe(e){let{inputs:{x:t},backend:n,attrs:{paddings:r,mode:s}}=e,a=r.map((f,m)=>f[0]+t.shape[m]+f[1]),o=n.dataIdMap.get(t.dataId).id,i=n.makeOutput(a,t.dtype),c=n.dataIdMap.get(i.dataId).id,l=new Uint8Array(new Int32Array(t.shape).buffer),u=r.map(f=>f[0]),d=r.map(f=>f[1]),p=new Uint8Array(new Int32Array(u).buffer),h=new Uint8Array(new Int32Array(d).buffer);return Q_(o,l,t.shape.length,$t[t.dtype],p,h,c1[s],c),i}var boe={kernelName:fo,backendName:"wasm",kernelFunc:goe,setupFunc:moe},yoe=!0,voe=Cn(mo,yoe),xoe=un(Cc);function u1(e,t){let n=new Int32Array(e.wasm.HEAPU8.buffer,t,4),r=n[0],s=n[1],a=n[2],o=n[3];return e.wasm._free(t),{pSelectedIndices:r,selectedSize:s,pSelectedScores:a,pValidOutputs:o}}var eE;function woe(e){eE=e.wasm.cwrap(_c,"number",["number","number","number","number","number"])}function koe(e){let{backend:t,inputs:n,attrs:r}=e,{iouThreshold:s,maxOutputSize:a,scoreThreshold:o}=r,{boxes:i,scores:c}=n,l=t.dataIdMap.get(i.dataId).id,u=t.dataIdMap.get(c.dataId).id,d=eE(l,u,a,s,o),{pSelectedIndices:p,selectedSize:h,pSelectedScores:f,pValidOutputs:m}=u1(t,d);return t.wasm._free(f),t.wasm._free(m),t.makeOutput([h],"int32",p)}var Ioe={kernelName:_c,backendName:"wasm",setupFunc:woe,kernelFunc:koe},tE;function Soe(e){tE=e.wasm.cwrap(Ec,"number",["number","number","number","number","number","bool"])}function Toe(e){let{backend:t,inputs:n,attrs:r}=e,{iouThreshold:s,maxOutputSize:a,scoreThreshold:o,padToMaxOutputSize:i}=r,{boxes:c,scores:l}=n,u=t.dataIdMap.get(c.dataId).id,d=t.dataIdMap.get(l.dataId).id,p=tE(u,d,a,s,o,i),{pSelectedIndices:h,selectedSize:f,pSelectedScores:m,pValidOutputs:g}=u1(t,p);t.wasm._free(m);let b=t.makeOutput([f],"int32",h),y=t.makeOutput([],"int32",g);return[b,y]}var Coe={kernelName:Ec,backendName:"wasm",setupFunc:Soe,kernelFunc:Toe},nE;function Noe(e){nE=e.wasm.cwrap(Ac,"number",["number","number","number","number","number","number"])}function _oe(e){let{backend:t,inputs:n,attrs:r}=e,{iouThreshold:s,maxOutputSize:a,scoreThreshold:o,softNmsSigma:i}=r,{boxes:c,scores:l}=n,u=t.dataIdMap.get(c.dataId).id,d=t.dataIdMap.get(l.dataId).id,p=nE(u,d,a,s,o,i),{pSelectedIndices:h,selectedSize:f,pSelectedScores:m,pValidOutputs:g}=u1(t,p);t.wasm._free(g);let b=t.makeOutput([f],"int32",h),y=t.makeOutput([f],"float32",m);return[b,y]}var Eoe={kernelName:Ac,backendName:"wasm",setupFunc:Noe,kernelFunc:_oe},Aoe=!1,Doe=Cn(Nc,Aoe,"bool"),rE;function Foe(e){rE=e.wasm.cwrap(go,null,["number","number","number","number","number"])}function $oe(e){let{inputs:t,backend:n,attrs:r}=e,{indices:s}=t,{depth:a,onValue:o,offValue:i}=r,c=n.makeOutput([...s.shape,a],"int32"),l=n.dataIdMap.get(c.dataId).id,d=n.dataIdMap.get(s.dataId).id;return rE(d,a,o,i,l),c}var Roe={kernelName:go,backendName:"wasm",setupFunc:Foe,kernelFunc:$oe};function Poe(e){let{inputs:{x:t},backend:n}=e,r=n.makeOutput(t.shape,t.dtype);return n.typedArrayFromHeap(r).fill(1),r}var Ooe={kernelName:Dc,backendName:"wasm",kernelFunc:Poe};function Moe(e){let{inputs:t,backend:n,attrs:r}=e,{axis:s}=r;if(t.length===1)return i1({inputs:{input:t[0]},backend:n,attrs:{dim:s}});let a=t[0].shape,o=t[0].dtype;t.forEach(u=>{k.assertShapesMatch(a,u.shape,"All tensors passed to stack must have matching shapes"),k.assert(o===u.dtype,()=>"All tensors passed to stack must have matching dtypes")});let i=[],c=t.map(u=>{let d=i1({inputs:{input:u},backend:n,attrs:{dim:s}});return i.push(d),d}),l=R_({inputs:c,backend:n,attrs:{axis:s}});return i.forEach(u=>n.disposeData(u.dataId)),l}var Loe={kernelName:Fc,backendName:"wasm",kernelFunc:Moe},sE;function Boe(e){sE=e.wasm.cwrap(bo,null,["number","array","number","number","array","array","number","number"])}function zoe(e){let{inputs:{x:t},backend:n,attrs:{paddings:r,constantValue:s}}=e,a=r.map((m,g)=>m[0]+t.shape[g]+m[1]);if(k.sizeFromShape(t.shape)===0)return W_({backend:n,attrs:{shape:a,value:s,dtype:t.dtype}});let o=n.dataIdMap.get(t.dataId).id,i=n.makeOutput(a,t.dtype),l=n.dataIdMap.get(i.dataId).id,u=new Uint8Array(new Int32Array(t.shape).buffer),d=r.map(m=>m[0]),p=r.map(m=>m[1]),h=new Uint8Array(new Int32Array(d).buffer),f=new Uint8Array(new Int32Array(p).buffer);return sE(o,u,t.shape.length,$t[t.dtype],h,f,s,l),i}var aE={kernelName:bo,backendName:"wasm",kernelFunc:zoe,setupFunc:Boe},Woe=!1,Voe=Cn(yo,Woe),oE;function Uoe(e){oE=e.wasm.cwrap(vo,null,["number","number","number"])}function Goe(e){let{inputs:t,backend:n}=e,{x:r,alpha:s}=t,a=n.dataIdMap.get(r.dataId).id,o=n.dataIdMap.get(s.dataId).id,i=a,c=r,l=c;c.dtype!=="float32"&&(l=Zd({backend:n,inputs:{x:r},attrs:{dtype:"float32"}}),i=n.dataIdMap.get(l.dataId).id);let u=n.makeOutput(r.shape,"float32"),d=n.dataIdMap.get(u.dataId).id;return oE(i,o,d),c.dtype!=="float32"&&n.disposeData(l.dataId),u}var Hoe={kernelName:vo,backendName:"wasm",setupFunc:Uoe,kernelFunc:Goe},iE;function joe(e){iE=e.wasm.cwrap($c,null,["number","number","number","number"])}function qoe(e){let{backend:t,inputs:n,attrs:r}=e,{axis:s,keepDims:a}=r,{x:o}=n,i=t.dataIdMap.get(o.dataId).id,c=i,l=o,{transposed:u,axes:d,originalAxes:p,inputWasTransposed:h}=Ca(o,s,t),f=d;if(h){let v=t.dataIdMap.get(u.dataId).id;v!==i&&(l=u,c=v,f=_.getInnerMostAxes(f.length,l.shape.length))}_.assertAxesAreInnerMostDims("prod",f,l.shape.length);let[m,g]=_.computeOutAndReduceShapes(l.shape,f),b=k.sizeFromShape(g),y=t.makeOutput(m,l.dtype);if(k.sizeFromShape(l.shape)!==0){let v=t.dataIdMap.get(y.dataId).id;iE(c,b,$t[y.dtype],v)}if(h&&t.disposeData(u.dataId),a){let v=_.expandShapeToKeepDim(y.shape,p);y.shape=v}return y}var Koe={kernelName:$c,backendName:"wasm",setupFunc:joe,kernelFunc:qoe},Xoe=e=>{let{backend:t,attrs:n}=e,{start:r,stop:s,step:a,dtype:o}=n,i=Dw(r,s,a,o),c=t.makeOutput([i.length],o);return t.typedArrayFromHeap(c).set(i),c},Yoe={kernelName:Rl,backendName:"wasm",kernelFunc:Xoe},Zoe=!0,Joe=Cn(Za,Zoe),Qoe=un(xo),eie=un(ko),cE;function tie(e){cE=e.wasm.cwrap(wo,null,["number","number","number","number","number","number","number","number","number","number"])}function nie(e){let{backend:t,inputs:n,attrs:r}=e,{images:s}=n,{alignCorners:a,halfPixelCenters:o,size:i}=r,[c,l]=i,[u,d,p,h]=s.shape,f=[u,c,l,h],m=t.dataIdMap.get(s.dataId),g;m.dtype!=="float32"&&(g=Zd({backend:t,inputs:{x:s},attrs:{dtype:"float32"}}),m=t.dataIdMap.get(g.dataId));let b=m.id,y=t.makeOutput(f,"float32");if(k.sizeFromShape(s.shape)===0)return y;let v=t.dataIdMap.get(y.dataId).id;return cE(b,u,d,p,h,c,l,a?1:0,o?1:0,v),g!=null&&t.disposeData(g.dataId),y}var rie={kernelName:wo,backendName:"wasm",setupFunc:tie,kernelFunc:nie},uE;function sie(e){uE=e.wasm.cwrap(Io,null,["number","array","number","array","number","number"])}function aie(e){let{inputs:t,backend:n,attrs:r}=e,{x:s}=t,{dims:a}=r,o=k.parseAxisParam(a,s.shape);if(s.shape.length===0)return Pm({inputs:{x:s},backend:n});let i=n.makeOutput(s.shape,s.dtype),c=n.dataIdMap.get(s.dataId).id,l=n.dataIdMap.get(i.dataId).id,u=new Uint8Array(new Int32Array(o).buffer),d=new Uint8Array(new Int32Array(s.shape).buffer);uE(c,u,o.length,d,s.shape.length,l);let p=Vn({inputs:{x:i},attrs:{shape:s.shape},backend:n});return n.disposeData(i.dataId),p}var oie={kernelName:Io,backendName:"wasm",kernelFunc:aie,setupFunc:sie},lE;function iie(e){lE=e.wasm.cwrap(Zc,null,["number","number","number","number","number","number","number","number","array","number","number"])}function cie(e){let{inputs:t,backend:n,attrs:r}=e,{image:s}=t,{radians:a,fillValue:o,center:i}=r,c=n.makeOutput(s.shape,s.dtype),l=n.dataIdMap.get(s.dataId).id,u=n.dataIdMap.get(c.dataId).id,[d,p,h,f]=s.shape,[m,g]=_.getImageCenter(i,p,h),b=o===0,y=255,v=typeof o=="number"?[o,o,o,b?0:y]:[...o,y],x=new Uint8Array(new Int32Array(v).buffer);return lE(l,d,p,h,f,a,m,g,x,v.length,u),c}var uie={kernelName:Zc,backendName:"wasm",kernelFunc:cie,setupFunc:iie},lie=un(So),die=un(To),dE;function pie(e){dE=e.wasm.cwrap(Oc,null,["number","number","number","number","number","number","array","number","number"])}function hie(e){let{backend:t,inputs:n,attrs:r}=e,{indices:s,updates:a}=n,{shape:o}=r,i=t.makeOutput(o,a.dtype);if(k.sizeFromShape(o)===0)return i;let{sliceRank:c,numUpdates:l,sliceSize:u,strides:d,outputSize:p}=wy.calculateShapes(a,s,o),f=t.dataIdMap.get(s.dataId).id,g=t.dataIdMap.get(a.dataId).id,b=new Uint8Array(new Int32Array(d).buffer),y=t.dataIdMap.get(i.dataId).id;return dE(f,g,$t[a.dtype],c,l,u,b,p,y),i}var fie={kernelName:Oc,backendName:"wasm",setupFunc:pie,kernelFunc:hie},pE;function mie(e){pE=e.wasm.cwrap("SelectV2",null,["number","number","number","number","number"])}function gie(e){let{inputs:t,backend:n}=e,{condition:r,t:s,e:a}=t,o=n.dataIdMap.get(r.dataId).id,i=n.dataIdMap.get(s.dataId).id,c=n.dataIdMap.get(a.dataId).id,l=n.makeOutput(s.shape,s.dtype),u=n.dataIdMap.get(l.dataId).id,d=r.shape.length,p=s.shape.length,h=d===0||d>1||p===1?1:k.sizeFromShape(s.shape.slice(1));return pE(o,i,c,h,u),l}var bie={kernelName:Mc,backendName:"wasm",kernelFunc:gie,setupFunc:mie},hE;function yie(e){hE=e.wasm.cwrap(No,null,["number","number"])}function vie(e){let{backend:t,inputs:{x:n}}=e,r=t.dataIdMap.get(n.dataId).id,s=t.makeOutput(n.shape,n.dtype),a=t.dataIdMap.get(s.dataId).id;return k.sizeFromShape(s.shape)===0||hE(r,a),s}var xie={kernelName:"Sigmoid",backendName:"wasm",setupFunc:yie,kernelFunc:vie},wie=un(Co),fE;function kie(e){fE=e.wasm.cwrap(Ao,null,["number","number","number","number"])}function Iie(e){let{backend:t,inputs:{logits:n},attrs:{dim:r}}=e,s=t.dataIdMap.get(n.dataId).id,a=t.makeOutput(n.shape,n.dtype),o=t.dataIdMap.get(a.dataId).id,i=n.shape[r],c=k.sizeFromShape(n.shape)/i;return k.sizeFromShape(a.shape)===0||fE(s,o,i,c),a}var Sie={kernelName:Ao,backendName:"wasm",setupFunc:kie,kernelFunc:Iie};function Tie(e){let{inputs:t,backend:n,attrs:r}=e,{x:s}=t,{blockShape:a,paddings:o}=r,i=k.sizeFromShape(a),c=[[0,0]];c.push(...o);for(let T=1+a.length;T0?c+1:0;if(u<0)throw new Error(_.getSparseSegmentReductionNegativeSegmentIdsErrorMessage());let d=s.shape.slice();d[0]=u;let p=n.dataIdMap.get(s.dataId).id,h=n.dataIdMap.get(a.dataId).id,f=n.dataIdMap.get(o.dataId).id,m=n.makeOutput(d,s.dtype),g=n.dataIdMap.get(m.dataId).id,b=n.makeOutput([4],"int32"),y=n.dataIdMap.get(b.dataId).id;bE(p,$t[s.dtype],s.shape[0],h,f,g,y,t,0);let v=n.readSync(b.dataId),x;switch(v[0]){case 0:{x=_.getSparseSegmentReductionNegativeSegmentIdsErrorMessage();break}case 1:{x=_.getSparseSegmentReductionNonIncreasingSegmentIdsErrorMessage();break}case 2:x=_.getSparseSegmentReductionSegmentIdOutOfRangeErrorMessage(v[1],v[2]);break;case 3:x=_.getSparseSegmentReductionIndicesOutOfRangeErrorMessage(v[1],v[2],v[3]);break;default:x=""}if(n.disposeData(b.dataId),x)throw n.disposeData(m.dataId),new Error(x);return m}function $ie(e){return vE(e,!0)}var Rie={kernelName:Ml,backendName:"wasm",setupFunc:yE,kernelFunc:$ie};function Pie(e){return vE(e,!1)}var Oie={kernelName:Ll,backendName:"wasm",setupFunc:yE,kernelFunc:Pie};function Mie(e){let{inputs:t,attrs:n,backend:r}=e,{x:s}=t,{numOrSizeSplits:a,axis:o}=n,i=k.parseAxisParam(o,s.shape)[0],c=_.prepareSplitSize(s,a,i),l=new Array(s.shape.length).fill(0),u=s.shape.slice();return c.map(d=>{let p=[...u];p[i]=d;let h=xi({inputs:{x:s},attrs:{begin:l,size:p},backend:r});return l[i]+=d,h})}var Lie={kernelName:Gc,backendName:"wasm",kernelFunc:Mie},Bie=un(_o),zie=un(Bl),Wie=!0,Vie=Cn(Do,Wie),xE;function Uie(e){xE=e.wasm.cwrap(ea,null,["number","number","number","number"])}function Gie(e){let{backend:t,inputs:n,attrs:r}=e,{alpha:s}=r,{x:a}=n,o=t.dataIdMap.get(a.dataId).id,i=t.makeOutput(a.shape,a.dtype),c=t.dataIdMap.get(i.dataId).id;return xE(o,s,$t[a.dtype],c),i}var Hie={kernelName:ea,backendName:"wasm",setupFunc:Uie,kernelFunc:Gie},wE;function jie(e){wE=e.wasm.cwrap(jc,null,["number","array","number","array","array","array","array","array","number","number"])}function qie(e){let{backend:t,inputs:n,attrs:r}=e,{x:s}=n,{begin:a,end:o,strides:i,beginMask:c,endMask:l,ellipsisMask:u,newAxisMask:d,shrinkAxisMask:p}=r,{finalShapeSparse:h,finalShape:f,isIdentity:m,sliceDim0:g,isSimpleSlice:b,begin:y,end:v,strides:x}=Gt.sliceInfo(s.shape,a,o,i,c,l,u,d,p),w;if(m)w=Vn({inputs:{x:s},backend:t,attrs:{shape:f}});else if(g||b){k.assert(s.shape.length>=1,()=>`Input must have rank at least 1, got: ${s.shape.length}`);let T=Gt.computeOutShape(y,v,x),C=xi({inputs:{x:s},backend:t,attrs:{begin:y,size:T}});w=Vn({inputs:{x:C},backend:t,attrs:{shape:f}}),t.disposeData(C.dataId)}else{let T=t.makeOutput(h,"float32"),C=t.dataIdMap.get(s.dataId).id,D=new Uint8Array(new Int32Array(k.computeStrides(s.shape)).buffer),F=new Uint8Array(new Int32Array(y).buffer),O=new Uint8Array(new Int32Array(v).buffer),$=new Uint8Array(new Int32Array(x).buffer),R=new Uint8Array(new Int32Array(h).buffer),N=new Uint8Array(new Int32Array(k.computeStrides(h)).buffer),L=t.dataIdMap.get(T.dataId).id;wE(C,D,s.shape.length,F,O,$,R,N,h.length,L),w=Vn({inputs:{x:T},backend:t,attrs:{shape:f}}),t.disposeData(T.dataId)}return w}var Kie={kernelName:jc,backendName:"wasm",setupFunc:jie,kernelFunc:qie},Xie=!0,Yie=Cn(Fo,Xie),kE;function Zie(e){kE=e.wasm.cwrap(Eo,null,["number","number","number","number"])}function Jie(e){let{backend:t,inputs:n,attrs:r}=e,{axis:s,keepDims:a}=r,{x:o}=n,i=t.dataIdMap.get(o.dataId).id,c=i,l=o,{transposed:u,axes:d,originalAxes:p,inputWasTransposed:h}=Ca(o,s,t),f=d;if(h){let v=t.dataIdMap.get(u.dataId).id;v!==i&&(l=u,c=v,f=_.getInnerMostAxes(f.length,l.shape.length))}_.assertAxesAreInnerMostDims("sum",f,l.shape.length);let[m,g]=_.computeOutAndReduceShapes(l.shape,f),b=k.sizeFromShape(g),y=t.makeOutput(m,l.dtype);if(k.sizeFromShape(l.shape)!==0){let v=t.dataIdMap.get(y.dataId).id;kE(c,b,$t[y.dtype],v)}if(h&&t.disposeData(u.dataId),a){let v=_.expandShapeToKeepDim(y.shape,p);y.shape=v}return y}var Qie={kernelName:Eo,backendName:"wasm",setupFunc:Zie,kernelFunc:Jie},ece=un($o),tce=un(Ro),IE;function nce(e){IE=e.wasm.cwrap(Qs,null,["number","array","number","array","number","number"])}function rce(e){let{inputs:t,backend:n,attrs:r}=e,{x:s}=t,a=n.dataIdMap.get(s.dataId).id,{reps:o}=r,i=new Array(s.shape.length);for(let p=0;p{let{x:r}=e,{k:s,sorted:a}=n,o=t.dataIdMap.get(r.dataId).id,i=new Uint8Array(new Int32Array(r.shape).buffer),c=r.shape.slice();c[c.length-1]=s;let l=t.makeOutput(c,r.dtype),u=t.dataIdMap.get(l.dataId).id,d=t.makeOutput(c,"int32"),p=t.dataIdMap.get(d.dataId).id;return SE(o,i,r.shape.length,$t[r.dtype],s,a,u,p),[l,d]},ice={kernelName:qc,backendName:"wasm",setupFunc:ace,kernelFunc:oce},TE;function cce(e){TE=e.wasm.cwrap(Kc,null,["number","number","bool","number","number","number","number","number","number","array","number","number","number","number","number"])}function uce(e){let{backend:t,inputs:n,attrs:r}=e,{image:s,transforms:a}=n,{interpolation:o,fillMode:i,fillValue:c,outputShape:l}=r,[u,d,p,h]=s.shape,[f,m]=l!=null?l:[d,p],g=[u,f,m,h],b=new Uint8Array(new Int32Array(k.computeStrides(s.shape)).buffer),y=t.makeOutput(g,s.dtype),v=t.dataIdMap.get(y.dataId).id,w=t.dataIdMap.get(s.dataId).id,C=t.dataIdMap.get(a.dataId).id,D=o==="nearest"?1:2,F;switch(i){case"constant":F=1;break;case"reflect":F=2;break;case"wrap":F=3;break;case"nearest":F=4;break;default:F=1;break}return TE(w,C,a.shape[0]>1,u,f,m,h,p,d,b,s.shape.length-1,D,F,c,v),y}var lce={kernelName:Kc,backendName:"wasm",setupFunc:cce,kernelFunc:uce};function dce(e){let{inputs:t,backend:n,attrs:r}=e,{value:s}=t,{axis:a}=r;a<0&&(a+=s.shape.length);let o=s.shape[a],i=s.shape.length,c=new Array(i-1),l=0;for(let h=0;h({dataId:h,dtype:f,shape:c}))}var pce={kernelName:Xc,backendName:"wasm",kernelFunc:dce};function hce(e){let{inputs:{x:t},backend:n}=e,r=n.makeOutput(t.shape,t.dtype);return n.typedArrayFromHeap(r).fill(0),r}var fce={kernelName:Yc,backendName:"wasm",kernelFunc:hce},mce=[ise,use,pse,xse,Ise,Cse,Ese,$se,Bse,zse,Wse,Gse,Hse,Kse,Zse,Jse,Qse,nae,aae,cae,dae,pae,fae,mae,gae,bae,xae,wae,Iae,ose,Cae,Eae,Fae,Pae,Lae,zae,Vae,hse,Hae,qae,Xae,Yae,Jae,toe,roe,ooe,uoe,poe,foe,boe,voe,xoe,Ioe,Coe,Eoe,Doe,Roe,Ooe,Loe,aE,Voe,Hoe,Koe,Yoe,Joe,Qoe,eie,Ase,rie,oie,uie,die,lie,fie,bie,xie,wie,Mse,Sie,Cie,Eie,Fie,Rie,Oie,Lie,Bie,zie,Vie,Hie,Kie,Yie,Qie,ece,tce,sce,ice,lce,bse,pce,fce];for(let e of mce)Vl(e);var l1=Q();l1.registerFlag("WASM_HAS_SIMD_SUPPORT",async()=>WebAssembly.validate(new Uint8Array([0,97,115,109,1,0,0,0,1,4,1,96,0,0,3,2,1,0,10,9,1,7,0,65,0,253,15,26,11])));l1.registerFlag("WASM_HAS_MULTITHREAD_SUPPORT",async()=>{if(l1.get("IS_NODE"))return!1;try{return new MessageChannel().port1.postMessage(new SharedArrayBuffer(1)),WebAssembly.validate(new Uint8Array([0,97,115,109,1,0,0,0,1,4,1,96,0,0,3,2,1,0,5,4,1,3,1,1,10,11,1,9,0,65,0,254,16,2,0,26,11]))}catch(e){return!1}});var CE=Oa(BD()),gce='var Module={};function threadPrintErr(){var text=Array.prototype.slice.call(arguments).join(" ");console.error(text)}function threadAlert(){var text=Array.prototype.slice.call(arguments).join(" ");postMessage({cmd:"alert",text:text,threadId:Module["_pthread_self"]()})}var err=threadPrintErr;this.alert=threadAlert;Module["instantiateWasm"]=function(info,receiveInstance){var instance=new WebAssembly.Instance(Module["wasmModule"],info);Module["wasmModule"]=null;receiveInstance(instance);return instance.exports};function moduleLoaded(){}this.onmessage=function(e){try{if(e.data.cmd==="load"){Module["wasmModule"]=e.data.wasmModule;Module["wasmMemory"]=e.data.wasmMemory;Module["buffer"]=Module["wasmMemory"].buffer;Module["ENVIRONMENT_IS_PTHREAD"]=true;if(typeof e.data.urlOrBlob==="string"){importScripts(e.data.urlOrBlob)}else{var objectUrl=URL.createObjectURL(e.data.urlOrBlob);importScripts(objectUrl);URL.revokeObjectURL(objectUrl)}WasmBackendModuleThreadedSimd(Module).then(function(instance){Module=instance;moduleLoaded()})}else if(e.data.cmd==="objectTransfer"){Module["PThread"].receiveObjectTransfer(e.data)}else if(e.data.cmd==="run"){Module["__performance_now_clock_drift"]=performance.now()-e.data.time;Module["__emscripten_thread_init"](e.data.threadInfoStruct,0,0);var max=e.data.stackBase;var top=e.data.stackBase+e.data.stackSize;Module["establishStackSpace"](top,max);Module["_emscripten_tls_init"]();Module["PThread"].receiveObjectTransfer(e.data);Module["PThread"].setThreadStatus(Module["_pthread_self"](),1);try{var result=Module["invokeEntryPoint"](e.data.start_routine,e.data.arg);if(!Module["getNoExitRuntime"]())Module["PThread"].threadExit(result)}catch(ex){if(ex==="Canceled!"){Module["PThread"].threadCancel()}else if(ex!="unwind"){if(ex instanceof Module["ExitStatus"]){if(Module["getNoExitRuntime"]()){}else{Module["PThread"].threadExit(ex.status)}}else{Module["PThread"].threadExit(-2);throw ex}}}}else if(e.data.cmd==="cancel"){if(Module["_pthread_self"]()){Module["PThread"].threadCancel()}}else if(e.data.target==="setimmediate"){}else if(e.data.cmd==="processThreadQueue"){if(Module["_pthread_self"]()){Module["_emscripten_current_thread_process_queued_calls"]()}}else{err("worker.js received unknown command "+e.data.cmd);err(e.data)}}catch(ex){err("worker.js onmessage() captured an uncaught exception: "+ex);if(ex&&ex.stack)err(ex.stack);throw ex}};if(typeof process==="object"&&typeof process.versions==="object"&&typeof process.versions.node==="string"){self={location:{href:__filename}};var onmessage=this.onmessage;var nodeWorkerThreads=require("worker_threads");global.Worker=nodeWorkerThreads.Worker;var parentPort=nodeWorkerThreads.parentPort;parentPort.on("message",function(data){onmessage({data:data})});var nodeFS=require("fs");var nodeRead=function(filename){return nodeFS.readFileSync(filename,"utf8")};function globalEval(x){global.require=require;global.Module=Module;eval.call(null,x)}importScripts=function(f){globalEval(nodeRead(f))};postMessage=function(msg){parentPort.postMessage(msg)};if(typeof performance==="undefined"){performance={now:function(){return Date.now()}}}}',bce=Oa(zD()),NE=class extends wl{constructor(e){super();this.wasm=e,this.dataIdNextNumber=1,this.wasm.tfjs.initWithThreadsCount(EE),p1=this.wasm.tfjs.getThreadsCount(),this.dataIdMap=new jp(this,ks())}write(e,t,n){let r={id:this.dataIdNextNumber++};return this.move(r,e,t,n,1),r}numDataIds(){return this.dataIdMap.numDataIds()}async time(e){let t=k.now();return e(),{kernelMs:k.now()-t}}move(e,t,n,r,s){let a=this.dataIdNextNumber++;if(r==="string"){let l=t;this.dataIdMap.set(e,{id:a,stringBytes:l,shape:n,dtype:r,memoryOffset:null,refCount:s});return}let o=k.sizeFromShape(n),i=o*k.bytesPerElement(r),c=this.wasm._malloc(i);this.dataIdMap.set(e,{id:a,memoryOffset:c,shape:n,dtype:r,refCount:s}),this.wasm.tfjs.registerTensor(a,o,c),t!=null&&this.wasm.HEAPU8.set(new Uint8Array(t.buffer,t.byteOffset,i),c)}async read(e){return this.readSync(e)}readSync(e,t,n){let{memoryOffset:r,dtype:s,shape:a,stringBytes:o}=this.dataIdMap.get(e);if(s==="string")return(t==null||t===0)&&(n==null||n>=o.length)?o:o.slice(t,n);t=t||0,n=n||k.sizeFromShape(a);let i=k.bytesPerElement(s),c=this.wasm.HEAPU8.slice(r+t*i,r+n*i);return xce(c.buffer,s)}disposeData(e,t=!1){if(this.dataIdMap.has(e)){let n=this.dataIdMap.get(e);if(n.refCount--,!t&&n.refCount>0)return!1;this.wasm._free(n.memoryOffset),this.wasm.tfjs.disposeData(n.id),this.dataIdMap.delete(e)}return!0}refCount(e){return this.dataIdMap.has(e)?this.dataIdMap.get(e).refCount:0}incRef(e){let t=this.dataIdMap.get(e);t!=null&&t.refCount++}floatPrecision(){return 32}getMemoryOffset(e){return this.dataIdMap.get(e).memoryOffset}dispose(){this.wasm.tfjs.dispose(),"PThread"in this.wasm&&this.wasm.PThread.terminateAllThreads(),this.wasm=null}memory(){return{unreliable:!1}}makeOutput(e,t,n){let r;if(n==null)r=this.write(null,e,t);else{let s=this.dataIdNextNumber++;r={id:s},this.dataIdMap.set(r,{id:s,memoryOffset:n,shape:e,dtype:t,refCount:1});let a=k.sizeFromShape(e);this.wasm.tfjs.registerTensor(s,a,n)}return{dataId:r,shape:e,dtype:t}}typedArrayFromHeap({shape:e,dtype:t,dataId:n}){let r=this.wasm.HEAPU8.buffer,{memoryOffset:s}=this.dataIdMap.get(n),a=k.sizeFromShape(e);switch(t){case"float32":return new Float32Array(r,s,a);case"int32":return new Int32Array(r,s,a);case"bool":return new Uint8Array(r,s,a);default:throw new Error(`Unknown dtype ${t}`)}}};function yce(e){return(t,n)=>(k.fetch(e,{credentials:"same-origin"}).then(r=>{r.ok||t.env.a(`failed to load wasm binary file at '${e}'`),r.arrayBuffer().then(s=>{WebAssembly.instantiate(s,t).then(a=>{n(a.instance,a.module)})})}),{})}function _E(e,t,n){if(Om!=null)return Om;let r="tfjs-backend-wasm.wasm";return e&&t?r="tfjs-backend-wasm-threaded-simd.wasm":e&&(r="tfjs-backend-wasm-simd.wasm"),Qd!=null&&Qd[r]!=null?Qd[r]:n+r}async function vce(){let[e,t]=await Promise.all([Q().getAsync("WASM_HAS_SIMD_SUPPORT"),Q().getAsync("WASM_HAS_MULTITHREAD_SUPPORT")]);return new Promise((n,r)=>{let s={};s.locateFile=(i,c)=>{if(i.endsWith(".worker.js")){let l=gce,u=new Blob([l],{type:"application/javascript"});return URL.createObjectURL(u)}return i.endsWith(".wasm")?_E(e,t,Jd!=null?Jd:c):c+i},d1&&(s.instantiateWasm=yce(_E(e,t,Jd!=null?Jd:"")));let a=!1;s.onAbort=()=>{if(a||ep)return;ep=!0,r({message:"Make sure the server can serve the `.wasm` file relative to the bundled js file. For more details see https://github.com/tensorflow/tfjs/blob/master/tfjs-backend-wasm/README.md#using-bundlers"})};let o;t&&e&&Om==null?(s.mainScriptUrlOrBlob=new Blob(["var WasmBackendModuleThreadedSimd = "+CE.default.toString()],{type:"text/javascript"}),o=(0,CE.default)(s)):o=(0,bce.default)(s),o.then(i=>{a=!0,ep=!1;let c=null;i.tfjs={init:i.cwrap("init",null,[]),initWithThreadsCount:i.cwrap("init_with_threads_count",null,["number"]),getThreadsCount:i.cwrap("get_threads_count","number",[]),registerTensor:i.cwrap("register_tensor",null,["number","number","number"]),disposeData:i.cwrap("dispose_data",c,["number"]),dispose:i.cwrap("dispose",c,[])},n({wasm:i})})})}function xce(e,t){switch(t){case"float32":return new Float32Array(e);case"int32":return new Int32Array(e);case"bool":return new Uint8Array(e);default:throw new Error(`Unknown dtype ${t}`)}}var wce=["tfjs-backend-wasm.wasm","tfjs-backend-wasm-simd.wasm","tfjs-backend-wasm-threaded-simd.wasm"],Om=null,Jd=null,Qd={},ep=!1,d1=!1;function kce(e,t=!1){if(_y("setWasmPath has been deprecated in favor of setWasmPaths and will be removed in a future release."),ep)throw new Error("The WASM backend was already initialized. Make sure you call `setWasmPath()` before you call `tf.setBackend()` or `tf.ready()`");Om=e,d1=t}function Ice(e,t=!1){if(ep)throw new Error("The WASM backend was already initialized. Make sure you call `setWasmPaths()` before you call `tf.setBackend()` or `tf.ready()`");if(typeof e=="string")Jd=e;else{Qd=e;let n=wce.filter(r=>Qd[r]==null);if(n.length>0)throw new Error(`There were no entries found for the following binaries: ${n.join(",")}. Please either call setWasmPaths with a map providing a path for each binary, or with a string indicating the directory where all the binaries can be found.`)}d1=t}var EE=-1,p1=-1;function Sce(e){EE=e}function Tce(){if(p1===-1)throw new Error("WASM backend not initialized.");return p1}var Cce="3.12.0",Nce=2;Vh("wasm",async()=>{let{wasm:e}=await vce();return new NE(e)},Nce);var _ce="3.12.0",Ece="3.12.0",Ace="3.12.0",Dce="3.12.0",Fce="3.12.0",$ce="3.12.0",Rce="3.12.0",Pce="3.12.0",Oce={tfjs:_ce,"tfjs-core":Ece,"tfjs-data":Ace,"tfjs-layers":Dce,"tfjs-converter":Fce,"tfjs-backend-cpu":$ce,"tfjs-backend-webgl":Rce,"tfjs-backend-wasm":Pce};var L1={};Up(L1,{AnchorPosition:()=>fs,DrawBox:()=>zm,DrawBoxOptions:()=>N1,DrawFaceLandmarks:()=>M1,DrawFaceLandmarksOptions:()=>O1,DrawTextField:()=>_a,DrawTextFieldOptions:()=>ap,drawContour:()=>Fs,drawDetections:()=>Hce,drawFaceExpressions:()=>Yce,drawFaceLandmarks:()=>Jce});function Fs(e,t,n=!1){if(e.beginPath(),t.slice(1).forEach(({x:r,y:s},a)=>{let o=t[a];e.moveTo(o.x,o.y),e.lineTo(r,s)}),n){let r=t[t.length-1],s=t[0];if(!r||!s)return;e.moveTo(r.x,r.y),e.lineTo(s.x,s.y)}e.stroke()}var b1={};Up(b1,{computeReshapedDimensions:()=>g1,getCenterPoint:()=>Ii,isDimensions:()=>Lm,isEven:()=>Mm,isFloat:()=>m1,isTensor:()=>wi,isTensor1D:()=>Mce,isTensor2D:()=>f1,isTensor3D:()=>$s,isTensor4D:()=>br,isValidNumber:()=>Kr,isValidProbablitiy:()=>zu,range:()=>ps,round:()=>ki});var Nn=class{constructor(t,n){if(!Kr(t)||!Kr(n))throw new Error(`Dimensions.constructor - expected width and height to be valid numbers, instead have ${JSON.stringify({width:t,height:n})}`);this._width=t,this._height=n}get width(){return this._width}get height(){return this._height}reverse(){return new Nn(1/this.width,1/this.height)}};function wi(e,t){return e instanceof Ee&&e.shape.length===t}function Mce(e){return wi(e,1)}function f1(e){return wi(e,2)}function $s(e){return wi(e,3)}function br(e){return wi(e,4)}function m1(e){return e%1!=0}function Mm(e){return e%2==0}function ki(e,t=2){let n=10**t;return Math.floor(e*n)/n}function Lm(e){return e&&e.width&&e.height}function g1({width:e,height:t},n){let r=n/Math.max(t,e);return new Nn(Math.round(e*r),Math.round(t*r))}function Ii(e){return e.reduce((t,n)=>t.add(n),new Pe(0,0)).div(new Pe(e.length,e.length))}function ps(e,t,n){return Array(e).fill(0).map((r,s)=>t+s*n)}function Kr(e){return!!e&&e!==1/0&&e!==-1/0&&!Number.isNaN(e)||e===0}function zu(e){return Kr(e)&&e>=0&&e<=1}var Pe=class{constructor(t,n){this._x=t,this._y=n}get x(){return this._x}get y(){return this._y}add(t){return new Pe(this.x+t.x,this.y+t.y)}sub(t){return new Pe(this.x-t.x,this.y-t.y)}mul(t){return new Pe(this.x*t.x,this.y*t.y)}div(t){return new Pe(this.x/t.x,this.y/t.y)}abs(){return new Pe(Math.abs(this.x),Math.abs(this.y))}magnitude(){return Math.sqrt(this.x**2+this.y**2)}floor(){return new Pe(Math.floor(this.x),Math.floor(this.y))}};var ut=class{static isRect(t){return!!t&&[t.x,t.y,t.width,t.height].every(Kr)}static assertIsValidBox(t,n,r=!1){if(!ut.isRect(t))throw new Error(`${n} - invalid box: ${JSON.stringify(t)}, expected object with properties x, y, width, height`);if(!r&&(t.width<0||t.height<0))throw new Error(`${n} - width (${t.width}) and height (${t.height}) must be positive numbers`)}constructor(t,n=!0){let r=t||{},s=[r.left,r.top,r.right,r.bottom].every(Kr),a=[r.x,r.y,r.width,r.height].every(Kr);if(!a&&!s)throw new Error(`Box.constructor - expected box to be IBoundingBox | IRect, instead have ${JSON.stringify(r)}`);let[o,i,c,l]=a?[r.x,r.y,r.width,r.height]:[r.left,r.top,r.right-r.left,r.bottom-r.top];ut.assertIsValidBox({x:o,y:i,width:c,height:l},"Box.constructor",n),this._x=o,this._y=i,this._width=c,this._height=l}get x(){return this._x}get y(){return this._y}get width(){return this._width}get height(){return this._height}get left(){return this.x}get top(){return this.y}get right(){return this.x+this.width}get bottom(){return this.y+this.height}get area(){return this.width*this.height}get topLeft(){return new Pe(this.left,this.top)}get topRight(){return new Pe(this.right,this.top)}get bottomLeft(){return new Pe(this.left,this.bottom)}get bottomRight(){return new Pe(this.right,this.bottom)}round(){let[t,n,r,s]=[this.x,this.y,this.width,this.height].map(a=>Math.round(a));return new ut({x:t,y:n,width:r,height:s})}floor(){let[t,n,r,s]=[this.x,this.y,this.width,this.height].map(a=>Math.floor(a));return new ut({x:t,y:n,width:r,height:s})}toSquare(){let{x:t,y:n,width:r,height:s}=this,a=Math.abs(r-s);return rn&&(i=-d+n+r,d=n),p>t&&(c=-p+t+s,p=t),l<1&&(c=2-l,l=1),u<1&&(c=2-u,u=1),{dy:o,edy:c,dx:a,edx:i,y:u,ey:p,x:l,ex:d,w:r,h:s}}calibrate(t){return new ut({left:this.left+t.left*this.width,top:this.top+t.top*this.height,right:this.right+t.right*this.width,bottom:this.bottom+t.bottom*this.height}).toSquare().round()}};var Wu=class extends ut{constructor(t,n,r,s,a=!1){super({left:t,top:n,right:r,bottom:s},a)}};var Na=class{constructor(t,n,r,s,a){this._imageDims=new Nn(a.width,a.height),this._score=t,this._classScore=n,this._className=r,this._box=new ut(s).rescale(this._imageDims)}get score(){return this._score}get classScore(){return this._classScore}get className(){return this._className}get box(){return this._box}get imageDims(){return this._imageDims}get imageWidth(){return this.imageDims.width}get imageHeight(){return this.imageDims.height}get relativeBox(){return new ut(this._box).rescale(this.imageDims.reverse())}forSize(t,n){return new Na(this.score,this.classScore,this.className,this.relativeBox,{width:t,height:n})}};var xt=class extends Na{constructor(t,n,r){super(t,t,"",n,r)}forSize(t,n){let{score:r,relativeBox:s,imageDims:a}=super.forSize(t,n);return new xt(r,s,a)}};function y1(e,t,n=!0){let r=Math.max(0,Math.min(e.right,t.right)-Math.max(e.left,t.left)),s=Math.max(0,Math.min(e.bottom,t.bottom)-Math.max(e.top,t.top)),a=r*s;return n?a/(e.area+t.area-a):a/Math.min(e.area,t.area)}function v1(e){let t=e.map(i=>i.x),n=e.map(i=>i.y),r=t.reduce((i,c)=>ccii({score:o,boxIndex:i})).sort((o,i)=>o.score-i.score).map(o=>o.boxIndex),a=[];for(;s.length>0;){let o=s.pop();a.push(o);let i=s,c=[];for(let l=0;lc[u]<=n)}return a}function Xr(e,t){return M(()=>{let[n,r,s]=t,a=xn([...e.shape.slice(0,3),1],n,"float32"),o=xn([...e.shape.slice(0,3),1],r,"float32"),i=xn([...e.shape.slice(0,3),1],s,"float32"),c=et([a,o,i],3);return fe(e,c)})}function w1(e,t=!1){return M(()=>{let[n,r]=e.shape.slice(1);if(n===r)return e;let s=Math.abs(n-r),a=Math.round(s*(t?.5:1)),o=n>r?2:1,i=p=>{let h=e.shape.slice();return h[o]=p,xn(h,0,"float32")},c=i(a),l=s-c.shape[o],d=[t&&l?i(l):null,e,c].filter(p=>!!p).map(p=>ce(p,"float32"));return et(d,o)})}function Lce(e){let t=e.slice();for(let n=t.length-1;n>0;n--){let r=Math.floor(Math.random()*(n+1)),s=t[n];t[n]=t[r],t[r]=s}return t}function tp(e){return 1/(1+Math.exp(-e))}function Bce(e){return Math.log(e/(1-e))}var Vu=class extends ut{constructor(t,n,r,s,a=!1){super({x:t,y:n,width:r,height:s},a)}};var zce=.5,Wce=.43,Vce=.45,yr=class{constructor(t,n,r=new Pe(0,0)){let{width:s,height:a}=n;this._imgDims=new Nn(s,a),this._shift=r,this._positions=t.map(o=>o.mul(new Pe(s,a)).add(r))}get shift(){return new Pe(this._shift.x,this._shift.y)}get imageWidth(){return this._imgDims.width}get imageHeight(){return this._imgDims.height}get positions(){return this._positions}get relativePositions(){return this._positions.map(t=>t.sub(this._shift).div(new Pe(this.imageWidth,this.imageHeight)))}forSize(t,n){return new this.constructor(this.relativePositions,{width:t,height:n})}shiftBy(t,n){return new this.constructor(this.relativePositions,this._imgDims,new Pe(t,n))}shiftByPoint(t){return this.shiftBy(t.x,t.y)}align(t,n={}){if(t){let a=t instanceof xt?t.box.floor():new ut(t);return this.shiftBy(a.x,a.y).align(null,n)}let{useDlibAlignment:r,minBoxPadding:s}={useDlibAlignment:!1,minBoxPadding:.2,...n};return r?this.alignDlib():this.alignMinBbox(s)}alignDlib(){let t=this.getRefPointsForAlignment(),[n,r,s]=t,a=d=>s.sub(d).magnitude(),o=(a(n)+a(r))/2,i=Math.floor(o/Vce),c=Ii(t),l=Math.floor(Math.max(0,c.x-zce*i)),u=Math.floor(Math.max(0,c.y-Wce*i));return new Vu(l,u,Math.min(i,this.imageWidth+l),Math.min(i,this.imageHeight+u))}alignMinBbox(t){let n=v1(this.positions);return n.pad(n.width*t,n.height*t)}getRefPointsForAlignment(){throw new Error("getRefPointsForAlignment not implemented by base class")}};var AE=class extends yr{getRefPointsForAlignment(){let t=this.positions;return[t[0],t[1],Ii([t[3],t[4]])]}};var Uu=class extends yr{getJawOutline(){return this.positions.slice(0,17)}getLeftEyeBrow(){return this.positions.slice(17,22)}getRightEyeBrow(){return this.positions.slice(22,27)}getNose(){return this.positions.slice(27,36)}getLeftEye(){return this.positions.slice(36,42)}getRightEye(){return this.positions.slice(42,48)}getMouth(){return this.positions.slice(48,68)}getRefPointsForAlignment(){return[this.getLeftEye(),this.getRightEye(),this.getMouth()].map(Ii)}};var np=class{constructor(t,n){this._label=t,this._distance=n}get label(){return this._label}get distance(){return this._distance}toString(t=!0){return`${this.label}${t?` (${ki(this.distance)})`:""}`}};var rp=class extends ut{static assertIsValidLabeledBox(t,n){if(ut.assertIsValidBox(t,n),!Kr(t.label))throw new Error(`${n} - expected property label (${t.label}) to be a number`)}constructor(t,n){super(t);this._label=n}get label(){return this._label}};var Rs=class{constructor(t,n){if(typeof t!="string")throw new Error("LabeledFaceDescriptors - constructor expected label to be a string");if(!Array.isArray(n)||n.some(r=>!(r instanceof Float32Array)))throw new Error("LabeledFaceDescriptors - constructor expected descriptors to be an array of Float32Array");this._label=t,this._descriptors=n}get label(){return this._label}get descriptors(){return this._descriptors}toJSON(){return{label:this.label,descriptors:this.descriptors.map(t=>Array.from(t))}}static fromJSON(t){let n=t.descriptors.map(r=>new Float32Array(r));return new Rs(t.label,n)}};var DE=class extends rp{static assertIsValidPredictedBox(t,n){if(rp.assertIsValidLabeledBox(t,n),!zu(t.score)||!zu(t.classScore))throw new Error(`${n} - expected properties score (${t.score}) and (${t.classScore}) to be a number between [0, 1]`)}constructor(t,n,r,s){super(t,n);this._score=r,this._classScore=s}get score(){return this._score}get classScore(){return this._classScore}};function hs(e){return e.detection instanceof xt}function Si(e,t){return{...e,...{detection:t}}}function k1(){let e=window.fetch;if(!e)throw new Error("fetch - missing fetch implementation for browser environment");return{Canvas:HTMLCanvasElement,CanvasRenderingContext2D,Image:HTMLImageElement,ImageData,Video:HTMLVideoElement,createCanvasElement:()=>document.createElement("canvas"),createImageElement:()=>document.createElement("img"),createVideoElement:()=>document.createElement("video"),fetch:e,readFile:()=>{throw new Error("readFile - filesystem not available for browser environment")}}}function sp(){return typeof global=="object"&&typeof process!="undefined"&&process.versions!=null&&process.versions.node!=null}function Bm(e){let t="";if(!e&&sp())try{e=pD("fs")}catch(r){t=r.toString()}return{readFile:e?r=>new Promise((s,a)=>{e.readFile(r,(o,i)=>o?a(o):s(i))}):()=>{throw new Error(`readFile - failed to require fs in nodejs environment with error: ${t}`)}}}function I1(){let e=global.Canvas||global.HTMLCanvasElement,t=global.Image||global.HTMLImageElement,n=global.Video||global.HTMLVideoElement,r=()=>{if(e)return new e;throw new Error("createCanvasElement - missing Canvas implementation for nodejs environment")},s=()=>{if(t)return new t;throw new Error("createImageElement - missing Image implementation for nodejs environment")},a=()=>{if(n)return new n;throw new Error("createVideoElement - missing Video implementation for nodejs environment")},o=global.fetch,i=Bm();return{Canvas:e||class{},CanvasRenderingContext2D:global.CanvasRenderingContext2D||class{},Image:t||class{},ImageData:global.ImageData||class{},Video:global.HTMLVideoElement||class{},createCanvasElement:r,createImageElement:s,createVideoElement:a,fetch:o,...i}}function S1(){return typeof window=="object"&&typeof document!="undefined"&&typeof HTMLImageElement!="undefined"&&typeof HTMLCanvasElement!="undefined"&&typeof HTMLVideoElement!="undefined"&&typeof ImageData!="undefined"&&typeof CanvasRenderingContext2D!="undefined"}var nn;function Uce(){if(!nn)throw new Error("getEnv - environment is not defined, check isNodejs() and isBrowser()");return nn}function T1(e){nn=e}function C1(){return S1()?T1(k1()):sp()?T1(I1()):null}function Gce(e){if(nn||C1(),!nn)throw new Error("monkeyPatch - environment is not defined, check isNodejs() and isBrowser()");let{Canvas:t=nn.Canvas,Image:n=nn.Image}=e;nn.Canvas=t,nn.Image=n,nn.createCanvasElement=e.createCanvasElement||(()=>new t),nn.createImageElement=e.createImageElement||(()=>new n),nn.ImageData=e.ImageData||nn.ImageData,nn.Video=e.Video||nn.Video,nn.fetch=e.fetch||nn.fetch,nn.readFile=e.readFile||nn.readFile}var tt={getEnv:Uce,setEnv:T1,initialize:C1,createBrowserEnv:k1,createFileSystem:Bm,createNodejsEnv:I1,monkeyPatch:Gce,isBrowser:S1,isNodejs:sp};C1();function Ti(e){return!tt.isNodejs()&&typeof e=="string"?document.getElementById(e):e}function Un(e){let{Canvas:t,CanvasRenderingContext2D:n}=tt.getEnv();if(e instanceof n)return e;let r=Ti(e);if(!(r instanceof t))throw new Error("resolveContext2d - expected canvas to be of instance of Canvas");let s=r.getContext("2d");if(!s)throw new Error("resolveContext2d - canvas 2d context is null");return s}var fs;(function(s){s.TOP_LEFT="TOP_LEFT",s.TOP_RIGHT="TOP_RIGHT",s.BOTTOM_LEFT="BOTTOM_LEFT",s.BOTTOM_RIGHT="BOTTOM_RIGHT"})(fs||(fs={}));var ap=class{constructor(t={}){let{anchorPosition:n,backgroundColor:r,fontColor:s,fontSize:a,fontStyle:o,padding:i}=t;this.anchorPosition=n||fs.TOP_LEFT,this.backgroundColor=r||"rgba(0, 0, 0, 0.5)",this.fontColor=s||"rgba(255, 255, 255, 1)",this.fontSize=a||14,this.fontStyle=o||"Georgia",this.padding=i||4}},_a=class{constructor(t,n,r={}){this.text=typeof t=="string"?[t]:t instanceof _a?t.text:t,this.anchor=n,this.options=new ap(r)}measureWidth(t){let{padding:n}=this.options;return this.text.map(r=>t.measureText(r).width).reduce((r,s)=>r{let f=c+d.x,m=c+d.y+(h+1)*o;r.fillText(p,f,m)})}};var N1=class{constructor(t={}){let{boxColor:n,lineWidth:r,label:s,drawLabelOptions:a}=t;this.boxColor=n||"rgba(0, 0, 255, 1)",this.lineWidth=r||2,this.label=s;let o={anchorPosition:fs.BOTTOM_LEFT,backgroundColor:this.boxColor};this.drawLabelOptions=new ap({...o,...a})}},zm=class{constructor(t,n={}){this.box=new ut(t),this.options=new N1(n)}draw(t){let n=Un(t),{boxColor:r,lineWidth:s}=this.options,{x:a,y:o,width:i,height:c}=this.box;n.strokeStyle=r,n.lineWidth=s,n.strokeRect(a,o,i,c);let{label:l}=this.options;l&&new _a([l],{x:a-s/2,y:o},this.options.drawLabelOptions).draw(t)}};function Hce(e,t){(Array.isArray(t)?t:[t]).forEach(r=>{let s=r instanceof xt?r.score:hs(r)?r.detection.score:void 0,a=r instanceof xt?r.box:hs(r)?r.detection.box:new ut(r),o=s?`${ki(s)}`:void 0;new zm(a,{label:o}).draw(e)})}function op(e){let{Image:t,Video:n}=tt.getEnv();return e instanceof t&&e.complete||e instanceof n&&e.readyState>=3}function _1(e){return new Promise((t,n)=>{(e instanceof tt.getEnv().Canvas||op(e))&&t(null);function r(a){!a.currentTarget||(a.currentTarget.removeEventListener("load",s),a.currentTarget.removeEventListener("error",r),n(a))}function s(a){!a.currentTarget||(a.currentTarget.removeEventListener("load",s),a.currentTarget.removeEventListener("error",r),t(a))}e.addEventListener("load",s),e.addEventListener("error",r)})}function E1(e){return new Promise((t,n)=>{e instanceof Blob||n(new Error("bufferToImage - expected buf to be of type: Blob"));let r=new FileReader;r.onload=()=>{typeof r.result!="string"&&n(new Error("bufferToImage - expected reader.result to be a string, in onload"));let s=tt.getEnv().createImageElement();s.onload=()=>t(s),s.onerror=n,s.src=r.result},r.onerror=n,r.readAsDataURL(e)})}function Ci(e){let{Image:t,Video:n}=tt.getEnv();return e instanceof t?new Nn(e.naturalWidth,e.naturalHeight):e instanceof n?new Nn(e.videoWidth,e.videoHeight):new Nn(e.width,e.height)}function Ni({width:e,height:t}){let{createCanvasElement:n}=tt.getEnv(),r=n();return r.width=e,r.height=t,r}function ip(e,t){let{ImageData:n}=tt.getEnv();if(!(e instanceof n)&&!op(e))throw new Error("createCanvasFromMedia - media has not finished loading yet");let{width:r,height:s}=t||Ci(e),a=Ni({width:r,height:s});return e instanceof n?Un(a).putImageData(e,0,0):Un(a).drawImage(e,0,0,r,s),a}async function A1(e,t){let n=t||tt.getEnv().createCanvasElement(),[r,s,a]=e.shape.slice(br(e)?1:0),o=M(()=>e.as3D(r,s,a).toInt());return await Go.toPixels(o,n),o.dispose(),n}function Wm(e){let{Image:t,Canvas:n,Video:r}=tt.getEnv();return e instanceof t||e instanceof n||e instanceof r}function D1(e,t,n=!1){let{Image:r,Canvas:s}=tt.getEnv();if(!(e instanceof r||e instanceof s))throw new Error("imageToSquare - expected arg0 to be HTMLImageElement | HTMLCanvasElement");if(t<=0)return Ni({width:1,height:1});let a=Ci(e),o=t/Math.max(a.height,a.width),i=o*a.width,c=o*a.height,l=Ni({width:t,height:t}),u=e instanceof s?e:ip(e),d=Math.abs(i-c)/2,p=n&&i0&&u.height>0&&Un(l).drawImage(u,p,h,i,c),l}var Ps=class{constructor(t,n=!1){this._imageTensors=[];this._canvases=[];this._treatAsBatchInput=!1;this._inputDimensions=[];this._inputSize=0;if(!Array.isArray(t))throw new Error(`NetInput.constructor - expected inputs to be an Array of TResolvedNetInput or to be instanceof tf.Tensor4D, instead have ${t}`);this._treatAsBatchInput=n,this._batchSize=t.length,t.forEach((r,s)=>{if($s(r)){this._imageTensors[s]=r,this._inputDimensions[s]=r.shape;return}if(br(r)){let o=r.shape[0];if(o!==1)throw new Error(`NetInput - tf.Tensor4D with batchSize ${o} passed, but not supported in input array`);this._imageTensors[s]=r,this._inputDimensions[s]=r.shape.slice(1);return}let a=r instanceof tt.getEnv().Canvas?r:ip(r);this._canvases[s]=a,this._inputDimensions[s]=[a.height,a.width,3]})}get imageTensors(){return this._imageTensors}get canvases(){return this._canvases}get isBatchInput(){return this.batchSize>1||this._treatAsBatchInput}get batchSize(){return this._batchSize}get inputDimensions(){return this._inputDimensions}get inputSize(){return this._inputSize}get reshapedInputDimensions(){return ps(this.batchSize,0,1).map((t,n)=>this.getReshapedInputDimensions(n))}getInput(t){return this.canvases[t]||this.imageTensors[t]}getInputDimensions(t){return this._inputDimensions[t]}getInputHeight(t){return this._inputDimensions[t][0]}getInputWidth(t){return this._inputDimensions[t][1]}getReshapedInputDimensions(t){if(typeof this.inputSize!="number")throw new Error("getReshapedInputDimensions - inputSize not set, toBatchTensor has not been called yet");let n=this.getInputWidth(t),r=this.getInputHeight(t);return g1({width:n,height:r},this.inputSize)}toBatchTensor(t,n=!0){return this._inputSize=t,M(()=>{let r=ps(this.batchSize,0,1).map(a=>{let o=this.getInput(a);if(o instanceof Ee){let i=br(o)?o:mn(o);return i=w1(i,n),(i.shape[1]!==t||i.shape[2]!==t)&&(i=er.resizeBilinear(i,[t,t],!1,!1)),i.as3D(t,t,3)}if(o instanceof tt.getEnv().Canvas)return Go.fromPixels(D1(o,t,n));throw new Error(`toBatchTensor - at batchIdx ${a}, expected input to be instanceof tf.Tensor or instanceof HTMLCanvasElement, instead have ${o}`)});return Ot(r.map(a=>ce(a,"float32"))).as4D(this.batchSize,t,t,3)})}};async function bt(e){if(e instanceof Ps)return e;let t=Array.isArray(e)?e:[e];if(!t.length)throw new Error("toNetInput - empty array passed as input");let n=s=>Array.isArray(e)?` at input index ${s}:`:"",r=t.map(Ti);return r.forEach((s,a)=>{if(!Wm(s)&&!$s(s)&&!br(s))throw typeof t[a]=="string"?new Error(`toNetInput -${n(a)} string passed, but could not resolve HTMLElement for element id ${t[a]}`):new Error(`toNetInput -${n(a)} expected media to be of type HTMLImageElement | HTMLVideoElement | HTMLCanvasElement | tf.Tensor3D, or to be an element id`);if(br(s)){let o=s.shape[0];if(o!==1)throw new Error(`toNetInput -${n(a)} tf.Tensor4D with batchSize ${o} passed, but not supported in input array`)}}),await Promise.all(r.map(s=>Wm(s)&&_1(s))),new Ps(r,Array.isArray(e))}async function Gu(e,t){let{Canvas:n}=tt.getEnv(),r=e;if(!(e instanceof n)){let o=await bt(e);if(o.batchSize>1)throw new Error("extractFaces - batchSize > 1 not supported");let i=o.getInput(0);r=i instanceof n?i:await A1(i)}let s=Un(r);return t.map(o=>o instanceof xt?o.forSize(r.width,r.height).box.floor():o).map(o=>o.clipAtImageBorders(r.width,r.height)).map(({x:o,y:i,width:c,height:l})=>{let u=Ni({width:c,height:l});return c>0&&l>0&&Un(u).putImageData(s.getImageData(o,i,c,l),0,0),u})}async function Hu(e,t){if(!$s(e)&&!br(e))throw new Error("extractFaceTensors - expected image tensor to be 3D or 4D");if(br(e)&&e.shape[0]>1)throw new Error("extractFaceTensors - batchSize > 1 not supported");return M(()=>{let[n,r,s]=e.shape.slice(br(e)?1:0);return t.map(i=>i instanceof xt?i.forSize(r,n).box:i).map(i=>i.clipAtImageBorders(r,n)).map(({x:i,y:c,width:l,height:u})=>pu(e.as3D(n,r,s),[c,i,0],[u,l,s]))})}async function Os(e,t){let{fetch:n}=tt.getEnv(),r=await n(e,t);if(!(r.status<400))throw new Error(`failed to fetch: (${r.status}) ${r.statusText}, from url: ${r.url}`);return r}async function jce(e){let t=await Os(e),n=await t.blob();if(!n.type.startsWith("image/"))throw new Error(`fetchImage - expected blob type to be of type image/*, instead have: ${n.type}, for url: ${t.url}`);return E1(n)}async function F1(e){return(await Os(e)).json()}async function qce(e){return new Float32Array(await(await Os(e)).arrayBuffer())}function FE(e){return new Promise((t,n)=>{e instanceof Blob||n(new Error("bufferToVideo - expected buf to be of type: Blob"));let r=tt.getEnv().createVideoElement();r.oncanplay=()=>t(r),r.onerror=n,r.playsInline=!0,r.muted=!0,r.src=URL.createObjectURL(e),r.play()})}async function Kce(e){let t=await Os(e),n=await t.blob();if(!n.type.startsWith("video/"))throw new Error(`fetchVideo - expected blob type to be of type video/*, instead have: ${n.type}, for url: ${t.url}`);return FE(n)}function Vm(e,t){let n=`${t}-weights_manifest.json`;if(!e)return{modelBaseUri:"",manifestUri:n};if(e==="/")return{modelBaseUri:"/",manifestUri:`/${n}`};let r=e.startsWith("http://")?"http://":e.startsWith("https://")?"https://":"";e=e.replace(r,"");let s=e.split("/").filter(i=>i),a=e.endsWith(".json")?s[s.length-1]:n,o=r+(e.endsWith(".json")?s.slice(0,s.length-1):s).join("/");return o=e.startsWith("/")?`/${o}`:o,{modelBaseUri:o,manifestUri:o==="/"?`/${a}`:`${o}/${a}`}}async function $1(e,t){let{manifestUri:n,modelBaseUri:r}=Vm(e,t),s=await F1(n);return Yt.loadWeights(s,r)}function Xce(e,t,n=!1){let{width:r,height:s}=n?Ci(t):t;return e.width=r,e.height=s,{width:r,height:s}}var ln=class{constructor(t){this._params=void 0;this._paramMappings=[];this._name=t}get params(){return this._params}get paramMappings(){return this._paramMappings}get isLoaded(){return!!this.params}getParamFromPath(t){let{obj:n,objProp:r}=this.traversePropertyPath(t);return n[r]}reassignParamFromPath(t,n){let{obj:r,objProp:s}=this.traversePropertyPath(t);r[s].dispose(),r[s]=n}getParamList(){return this._paramMappings.map(({paramPath:t})=>({path:t,tensor:this.getParamFromPath(t)}))}getTrainableParams(){return this.getParamList().filter(t=>t.tensor instanceof ra)}getFrozenParams(){return this.getParamList().filter(t=>!(t.tensor instanceof ra))}variable(){this.getFrozenParams().forEach(({path:t,tensor:n})=>{this.reassignParamFromPath(t,n.variable())})}freeze(){this.getTrainableParams().forEach(({path:t,tensor:n})=>{let r=Kn(n.dataSync());n.dispose(),this.reassignParamFromPath(t,r)})}dispose(t=!0){this.getParamList().forEach(n=>{if(t&&n.tensor.isDisposed)throw new Error(`param tensor has already been disposed for path ${n.path}`);n.tensor.dispose()}),this._params=void 0}serializeParams(){return new Float32Array(this.getParamList().map(({tensor:t})=>Array.from(t.dataSync())).reduce((t,n)=>t.concat(n)))}async load(t){if(t instanceof Float32Array){this.extractWeights(t);return}await this.loadFromUri(t)}async loadFromUri(t){if(t&&typeof t!="string")throw new Error(`${this._name}.loadFromUri - expected model uri`);let n=await $1(t,this.getDefaultModelName());this.loadFromWeightMap(n)}async loadFromDisk(t){if(t&&typeof t!="string")throw new Error(`${this._name}.loadFromDisk - expected model file path`);let{readFile:n}=tt.getEnv(),{manifestUri:r,modelBaseUri:s}=Vm(t,this.getDefaultModelName()),a=l=>Promise.all(l.map(u=>n(u).then(d=>d.buffer))),o=Yt.weightsLoaderFactory(a),i=JSON.parse((await n(r)).toString()),c=await o(i,s);this.loadFromWeightMap(c)}loadFromWeightMap(t){let{paramMappings:n,params:r}=this.extractParamsFromWeightMap(t);this._paramMappings=n,this._params=r}extractWeights(t){let{paramMappings:n,params:r}=this.extractParams(t);this._paramMappings=n,this._params=r}traversePropertyPath(t){if(!this.params)throw new Error("traversePropertyPath - model has no loaded params");let n=t.split("/").reduce((a,o)=>{if(!a.nextObj.hasOwnProperty(o))throw new Error(`traversePropertyPath - object does not have property ${o}, for path ${t}`);return{obj:a.nextObj,objProp:o,nextObj:a.nextObj[o]}},{nextObj:this.params}),{obj:r,objProp:s}=n;if(!r||!s||!(r[s]instanceof Ee))throw new Error(`traversePropertyPath - parameter is not a tensor, for path ${t}`);return{obj:r,objProp:s}}};function Gn(e,t,n){return M(()=>{let r=ei(e,t.depthwise_filter,t.pointwise_filter,n,"same");return r=Y(r,t.bias),r})}function Um(e,t,n=!1){return M(()=>{let r=qe(n?Y(Rt(e,t.conv0.filters,[2,2],"same"),t.conv0.bias):Gn(e,t.conv0,[2,2])),s=Gn(r,t.conv1,[1,1]),a=qe(Y(r,s)),o=Gn(a,t.conv2,[1,1]);return qe(Y(r,Y(s,o)))})}function cp(e,t,n=!1,r=!0){return M(()=>{let s=qe(n?Y(Rt(e,t.conv0.filters,r?[2,2]:[1,1],"same"),t.conv0.bias):Gn(e,t.conv0,r?[2,2]:[1,1])),a=Gn(s,t.conv1,[1,1]),o=qe(Y(s,a)),i=Gn(o,t.conv2,[1,1]),c=qe(Y(s,Y(a,i))),l=Gn(c,t.conv3,[1,1]);return qe(Y(s,Y(a,Y(i,l))))})}function _i(e,t,n="same",r=!1){return M(()=>{let s=Y(Rt(e,t.filters,[1,1],n),t.bias);return r?qe(s):s})}function _n(e,t){Object.keys(e).forEach(n=>{t.some(r=>r.originalPath===n)||e[n].dispose()})}function ju(e,t){return(n,r,s,a)=>{let o=Br(e(n*r*s*s),[s,s,n,r]),i=He(e(r));return t.push({paramPath:`${a}/filters`},{paramPath:`${a}/bias`}),{filters:o,bias:i}}}function Gm(e,t){return(n,r,s)=>{let a=Lr(e(n*r),[n,r]),o=He(e(r));return t.push({paramPath:`${s}/weights`},{paramPath:`${s}/bias`}),{weights:a,bias:o}}}var Hm=class{constructor(t,n,r){this.depthwise_filter=t;this.pointwise_filter=n;this.bias=r}};function qu(e,t){return(n,r,s)=>{let a=Br(e(3*3*n),[3,3,n,1]),o=Br(e(n*r),[1,1,n,r]),i=He(e(r));return t.push({paramPath:`${s}/depthwise_filter`},{paramPath:`${s}/pointwise_filter`},{paramPath:`${s}/bias`}),new Hm(a,o,i)}}function Ku(e){return t=>{let n=e(`${t}/depthwise_filter`,4),r=e(`${t}/pointwise_filter`,4),s=e(`${t}/bias`,1);return new Hm(n,r,s)}}function ar(e,t){return(n,r,s)=>{let a=e[n];if(!wi(a,r))throw new Error(`expected weightMap[${n}] to be a Tensor${r}D, instead have ${a}`);return t.push({originalPath:n,paramPath:s||n}),a}}function En(e){let t=e;function n(s){let a=t.slice(0,s);return t=t.slice(s),a}function r(){return t}return{extractWeights:n,getRemainingWeights:r}}function jm(e,t){let n=ju(e,t),r=qu(e,t);function s(o,i,c,l=!1){let u=l?n(o,i,3,`${c}/conv0`):r(o,i,`${c}/conv0`),d=r(i,i,`${c}/conv1`),p=r(i,i,`${c}/conv2`);return{conv0:u,conv1:d,conv2:p}}function a(o,i,c,l=!1){let{conv0:u,conv1:d,conv2:p}=s(o,i,c,l),h=r(i,i,`${c}/conv3`);return{conv0:u,conv1:d,conv2:p,conv3:h}}return{extractDenseBlock3Params:s,extractDenseBlock4Params:a}}function $E(e){let t=[],{extractWeights:n,getRemainingWeights:r}=En(e),{extractDenseBlock4Params:s}=jm(n,t),a=s(3,32,"dense0",!0),o=s(32,64,"dense1"),i=s(64,128,"dense2"),c=s(128,256,"dense3");if(r().length!==0)throw new Error(`weights remaing after extract: ${r().length}`);return{paramMappings:t,params:{dense0:a,dense1:o,dense2:i,dense3:c}}}function qm(e){return t=>{let n=e(`${t}/filters`,4),r=e(`${t}/bias`,1);return{filters:n,bias:r}}}function Km(e,t){let n=ar(e,t),r=qm(n),s=Ku(n);function a(i,c=!1){let l=c?r(`${i}/conv0`):s(`${i}/conv0`),u=s(`${i}/conv1`),d=s(`${i}/conv2`);return{conv0:l,conv1:u,conv2:d}}function o(i,c=!1){let l=c?r(`${i}/conv0`):s(`${i}/conv0`),u=s(`${i}/conv1`),d=s(`${i}/conv2`),p=s(`${i}/conv3`);return{conv0:l,conv1:u,conv2:d,conv3:p}}return{extractDenseBlock3Params:a,extractDenseBlock4Params:o}}function RE(e){let t=[],{extractDenseBlock4Params:n}=Km(e,t),r={dense0:n("dense0",!0),dense1:n("dense1"),dense2:n("dense2"),dense3:n("dense3")};return _n(e,t),{params:r,paramMappings:t}}var up=class extends ln{constructor(){super("FaceFeatureExtractor")}forwardInput(t){let{params:n}=this;if(!n)throw new Error("FaceFeatureExtractor - load model before inference");return M(()=>{let r=ce(t.toBatchTensor(112,!0),"float32"),a=Xr(r,[122.782,117.001,104.298]).div(255),o=cp(a,n.dense0,!0);return o=cp(o,n.dense1),o=cp(o,n.dense2),o=cp(o,n.dense3),o=lr(o,[7,7],[2,2],"valid"),o})}async forward(t){return this.forwardInput(await bt(t))}getDefaultModelName(){return"face_feature_extractor_model"}extractParamsFromWeightMap(t){return RE(t)}extractParams(t){return $E(t)}};function lp(e,t){return M(()=>Y(De(e,t.weights),t.bias))}function PE(e,t,n){let r=[],{extractWeights:s,getRemainingWeights:a}=En(e),i=Gm(s,r)(t,n,"fc");if(a().length!==0)throw new Error(`weights remaing after extract: ${a().length}`);return{paramMappings:r,params:{fc:i}}}function OE(e){let t=[],n=ar(e,t);function r(a){let o=n(`${a}/weights`,2),i=n(`${a}/bias`,1);return{weights:o,bias:i}}let s={fc:r("fc")};return _n(e,t),{params:s,paramMappings:t}}function Xm(e){let t={},n={};return Object.keys(e).forEach(r=>{let s=r.startsWith("fc")?n:t;s[r]=e[r]}),{featureExtractorMap:t,classifierMap:n}}var dp=class extends ln{constructor(t,n){super(t);this._faceFeatureExtractor=n}get faceFeatureExtractor(){return this._faceFeatureExtractor}runNet(t){let{params:n}=this;if(!n)throw new Error(`${this._name} - load model before inference`);return M(()=>{let r=t instanceof Ps?this.faceFeatureExtractor.forwardInput(t):t;return lp(r.as2D(r.shape[0],-1),n.fc)})}dispose(t=!0){this.faceFeatureExtractor.dispose(t),super.dispose(t)}loadClassifierParams(t){let{params:n,paramMappings:r}=this.extractClassifierParams(t);this._params=n,this._paramMappings=r}extractClassifierParams(t){return PE(t,this.getClassifierChannelsIn(),this.getClassifierChannelsOut())}extractParamsFromWeightMap(t){let{featureExtractorMap:n,classifierMap:r}=Xm(t);return this.faceFeatureExtractor.loadFromWeightMap(n),OE(r)}extractParams(t){let n=this.getClassifierChannelsIn(),r=this.getClassifierChannelsOut(),s=r*n+r,a=t.slice(0,t.length-s),o=t.slice(t.length-s);return this.faceFeatureExtractor.extractWeights(a),this.extractClassifierParams(o)}};var R1=["neutral","happy","sad","angry","fearful","disgusted","surprised"],Ea=class{constructor(t){this.neutral=0;this.happy=0;this.sad=0;this.angry=0;this.fearful=0;this.disgusted=0;this.surprised=0;if(t.length!==7)throw new Error(`FaceExpressions.constructor - expected probabilities.length to be 7, have: ${t.length}`);R1.forEach((n,r)=>{this[n]=t[r]})}asSortedArray(){return R1.map(t=>({expression:t,probability:this[t]})).sort((t,n)=>n.probability-t.probability)}};var Ym=class extends dp{constructor(t=new up){super("FaceExpressionNet",t)}forwardInput(t){return M(()=>Mr(this.runNet(t)))}async forward(t){return this.forwardInput(await bt(t))}async predictExpressions(t){let n=await bt(t),r=await this.forwardInput(n),s=await Promise.all(ht(r).map(async o=>{let i=o.dataSync();return o.dispose(),i}));r.dispose();let a=s.map(o=>new Ea(o));return n.isBatchInput?a:a[0]}getDefaultModelName(){return"face_expression_model"}getClassifierChannelsIn(){return 256}getClassifierChannelsOut(){return 7}};function P1(e){return e.expressions instanceof Ea}function Zm(e,t){return{...e,...{expressions:t}}}function Yce(e,t,n=.1,r){(Array.isArray(t)?t:[t]).forEach(a=>{let o=a instanceof Ea?a:P1(a)?a.expressions:void 0;if(!o)throw new Error("drawFaceExpressions - expected faceExpressions to be FaceExpressions | WithFaceExpressions<{}> or array thereof");let c=o.asSortedArray().filter(d=>d.probability>n),l=hs(a)?a.detection.box.bottomLeft:r||new Pe(0,0);new _a(c.map(d=>`${d.expression} (${ki(d.probability)})`),l).draw(e)})}function Ei(e){return hs(e)&&e.landmarks instanceof yr&&e.unshiftedLandmarks instanceof yr&&e.alignedRect instanceof xt}function Zce(e){let t=(i,c,l,u)=>Math.atan2(u-c,l-i)%Math.PI,n=i=>i*180/Math.PI,r={roll:void 0,pitch:void 0,yaw:void 0};if(!e||!e._positions||e._positions.length!==68)return r;let s=e._positions;r.roll=-t(s[36]._x,s[36]._y,s[45]._x,s[45]._y),r.pitch=t(0,Math.abs(s[0]._x-s[30]._x)/s[30]._x,Math.PI,Math.abs(s[16]._x-s[30]._x)/s[30]._x);let a=s.reduce((i,c)=>ii>c._y?i:c._y,-1/0);return r.yaw=Math.PI*(e._imgDims._height/(o-a)/1.4-1),r}function Xu(e,t){let{box:n}=e.detection,r=t.shiftBy(n.x,n.y),s=r.align(),{imageDims:a}=e.detection,o=new xt(e.detection.score,s.rescale(a.reverse()),a),i=Zce(t);return{...e,...{landmarks:r,unshiftedLandmarks:t,alignedRect:o,angle:i}}}var O1=class{constructor(t={}){let{drawLines:n=!0,drawPoints:r=!0,lineWidth:s,lineColor:a,pointSize:o,pointColor:i}=t;this.drawLines=n,this.drawPoints=r,this.lineWidth=s||1,this.pointSize=o||2,this.lineColor=a||"rgba(0, 255, 255, 1)",this.pointColor=i||"rgba(255, 0, 255, 1)"}},M1=class{constructor(t,n={}){this.faceLandmarks=t,this.options=new O1(n)}draw(t){let n=Un(t),{drawLines:r,drawPoints:s,lineWidth:a,lineColor:o,pointSize:i,pointColor:c}=this.options;if(r&&this.faceLandmarks instanceof Uu&&(n.strokeStyle=o,n.lineWidth=a,Fs(n,this.faceLandmarks.getJawOutline()),Fs(n,this.faceLandmarks.getLeftEyeBrow()),Fs(n,this.faceLandmarks.getRightEyeBrow()),Fs(n,this.faceLandmarks.getNose()),Fs(n,this.faceLandmarks.getLeftEye(),!0),Fs(n,this.faceLandmarks.getRightEye(),!0),Fs(n,this.faceLandmarks.getMouth(),!0)),s){n.strokeStyle=c,n.fillStyle=c;let l=u=>{n.beginPath(),n.arc(u.x,u.y,i,0,2*Math.PI),n.fill()};this.faceLandmarks.positions.forEach(l)}}};function Jce(e,t){(Array.isArray(t)?t:[t]).forEach(r=>{let s=r instanceof yr?r:Ei(r)?r.landmarks:void 0;if(!s)throw new Error("drawFaceLandmarks - expected faceExpressions to be FaceLandmarks | WithFaceLandmarks> or array thereof");new M1(s).draw(e)})}var ME="1.6.2";function eue(e,t){let n=ju(e,t),r=qu(e,t);function s(o,i,c){let l=r(o,i,`${c}/separable_conv0`),u=r(i,i,`${c}/separable_conv1`),d=n(o,i,1,`${c}/expansion_conv`);return{separable_conv0:l,separable_conv1:u,expansion_conv:d}}function a(o,i){let c=r(o,o,`${i}/separable_conv0`),l=r(o,o,`${i}/separable_conv1`),u=r(o,o,`${i}/separable_conv2`);return{separable_conv0:c,separable_conv1:l,separable_conv2:u}}return{extractConvParams:n,extractSeparableConvParams:r,extractReductionBlockParams:s,extractMainBlockParams:a}}function LE(e,t){let n=[],{extractWeights:r,getRemainingWeights:s}=En(e),{extractConvParams:a,extractSeparableConvParams:o,extractReductionBlockParams:i,extractMainBlockParams:c}=eue(r,n),l=a(3,32,3,"entry_flow/conv_in"),u=i(32,64,"entry_flow/reduction_block_0"),d=i(64,128,"entry_flow/reduction_block_1"),p={conv_in:l,reduction_block_0:u,reduction_block_1:d},h={};ps(t,0,1).forEach(b=>{h[`main_block_${b}`]=c(128,`middle_flow/main_block_${b}`)});let f=i(128,256,"exit_flow/reduction_block"),m=o(256,512,"exit_flow/separable_conv"),g={reduction_block:f,separable_conv:m};if(s().length!==0)throw new Error(`weights remaing after extract: ${s().length}`);return{paramMappings:n,params:{entry_flow:p,middle_flow:h,exit_flow:g}}}function tue(e,t){let n=ar(e,t),r=qm(n),s=Ku(n);function a(i){let c=s(`${i}/separable_conv0`),l=s(`${i}/separable_conv1`),u=r(`${i}/expansion_conv`);return{separable_conv0:c,separable_conv1:l,expansion_conv:u}}function o(i){let c=s(`${i}/separable_conv0`),l=s(`${i}/separable_conv1`),u=s(`${i}/separable_conv2`);return{separable_conv0:c,separable_conv1:l,separable_conv2:u}}return{extractConvParams:r,extractSeparableConvParams:s,extractReductionBlockParams:a,extractMainBlockParams:o}}function BE(e,t){let n=[],{extractConvParams:r,extractSeparableConvParams:s,extractReductionBlockParams:a,extractMainBlockParams:o}=tue(e,n),i=r("entry_flow/conv_in"),c=a("entry_flow/reduction_block_0"),l=a("entry_flow/reduction_block_1"),u={conv_in:i,reduction_block_0:c,reduction_block_1:l},d={};ps(t,0,1).forEach(m=>{d[`main_block_${m}`]=o(`middle_flow/main_block_${m}`)});let p=a("exit_flow/reduction_block"),h=s("exit_flow/separable_conv"),f={reduction_block:p,separable_conv:h};return _n(e,n),{params:{entry_flow:u,middle_flow:d,exit_flow:f},paramMappings:n}}function zE(e,t,n){return Y(Rt(e,t.filters,n,"same"),t.bias)}function B1(e,t,n=!0){let r=n?qe(e):e;return r=Gn(r,t.separable_conv0,[1,1]),r=Gn(qe(r),t.separable_conv1,[1,1]),r=Pt(r,[3,3],[2,2],"same"),r=Y(r,zE(e,t.expansion_conv,[2,2])),r}function nue(e,t){let n=Gn(qe(e),t.separable_conv0,[1,1]);return n=Gn(qe(n),t.separable_conv1,[1,1]),n=Gn(qe(n),t.separable_conv2,[1,1]),n=Y(n,e),n}var z1=class extends ln{constructor(t){super("TinyXception");this._numMainBlocks=t}forwardInput(t){let{params:n}=this;if(!n)throw new Error("TinyXception - load model before inference");return M(()=>{let r=ce(t.toBatchTensor(112,!0),"float32"),a=Xr(r,[122.782,117.001,104.298]).div(255),o=qe(zE(a,n.entry_flow.conv_in,[2,2]));return o=B1(o,n.entry_flow.reduction_block_0,!1),o=B1(o,n.entry_flow.reduction_block_1),ps(this._numMainBlocks,0,1).forEach(i=>{o=nue(o,n.middle_flow[`main_block_${i}`])}),o=B1(o,n.exit_flow.reduction_block),o=qe(Gn(o,n.exit_flow.separable_conv,[1,1])),o})}async forward(t){return this.forwardInput(await bt(t))}getDefaultModelName(){return"tiny_xception_model"}extractParamsFromWeightMap(t){return BE(t,this._numMainBlocks)}extractParams(t){return LE(t,this._numMainBlocks)}};function WE(e){let t=[],{extractWeights:n,getRemainingWeights:r}=En(e),s=Gm(n,t),a=s(512,1,"fc/age"),o=s(512,2,"fc/gender");if(r().length!==0)throw new Error(`weights remaing after extract: ${r().length}`);return{paramMappings:t,params:{fc:{age:a,gender:o}}}}function VE(e){let t=[],n=ar(e,t);function r(a){let o=n(`${a}/weights`,2),i=n(`${a}/bias`,1);return{weights:o,bias:i}}let s={fc:{age:r("fc/age"),gender:r("fc/gender")}};return _n(e,t),{params:s,paramMappings:t}}var Ms;(function(n){n.FEMALE="female",n.MALE="male"})(Ms||(Ms={}));var Jm=class extends ln{constructor(t=new z1(2)){super("AgeGenderNet");this._faceFeatureExtractor=t}get faceFeatureExtractor(){return this._faceFeatureExtractor}runNet(t){let{params:n}=this;if(!n)throw new Error(`${this._name} - load model before inference`);return M(()=>{let r=t instanceof Ps?this.faceFeatureExtractor.forwardInput(t):t,s=lr(r,[7,7],[2,2],"valid").as2D(r.shape[0],-1),a=lp(s,n.fc.age).as1D(),o=lp(s,n.fc.gender);return{age:a,gender:o}})}forwardInput(t){return M(()=>{let{age:n,gender:r}=this.runNet(t);return{age:n,gender:Mr(r)}})}async forward(t){return this.forwardInput(await bt(t))}async predictAgeAndGender(t){let n=await bt(t),r=await this.forwardInput(n),s=ht(r.age),a=ht(r.gender),o=s.map((c,l)=>({ageTensor:c,genderTensor:a[l]})),i=await Promise.all(o.map(async({ageTensor:c,genderTensor:l})=>{let u=c.dataSync()[0],d=l.dataSync()[0],p=d>.5,h=p?Ms.MALE:Ms.FEMALE,f=p?d:1-d;return c.dispose(),l.dispose(),{age:u,gender:h,genderProbability:f}}));return r.age.dispose(),r.gender.dispose(),n.isBatchInput?i:i[0]}getDefaultModelName(){return"age_gender_model"}dispose(t=!0){this.faceFeatureExtractor.dispose(t),super.dispose(t)}loadClassifierParams(t){let{params:n,paramMappings:r}=this.extractClassifierParams(t);this._params=n,this._paramMappings=r}extractClassifierParams(t){return WE(t)}extractParamsFromWeightMap(t){let{featureExtractorMap:n,classifierMap:r}=Xm(t);return this.faceFeatureExtractor.loadFromWeightMap(n),VE(r)}extractParams(t){let n=512*1+1+(512*2+2),r=t.slice(0,t.length-n),s=t.slice(t.length-n);return this.faceFeatureExtractor.extractWeights(r),this.extractClassifierParams(s)}};var pp=class extends dp{postProcess(t,n,r){let s=r.map(({width:o,height:i})=>{let c=n/Math.max(i,o);return{width:o*c,height:i*c}}),a=s.length;return M(()=>{let o=(d,p)=>Ot([xn([68],d,"float32"),xn([68],p,"float32")],1).as2D(1,136).as1D(),i=(d,p)=>{let{width:h,height:f}=s[d];return p(h,f)?Math.abs(h-f)/2:0},c=d=>i(d,(p,h)=>pi(d,(p,h)=>ho(c(p),l(p))))).div(Ot(Array.from(Array(a),(d,p)=>o(s[p].width,s[p].height))))})}forwardInput(t){return M(()=>{let n=this.runNet(t);return this.postProcess(n,t.inputSize,t.inputDimensions.map(([r,s])=>({height:r,width:s})))})}async forward(t){return this.forwardInput(await bt(t))}async detectLandmarks(t){let n=await bt(t),r=M(()=>ht(this.forwardInput(n))),s=await Promise.all(r.map(async(a,o)=>{let i=Array.from(a.dataSync()),c=i.filter((u,d)=>Mm(d)),l=i.filter((u,d)=>!Mm(d));return new Uu(Array(68).fill(0).map((u,d)=>new Pe(c[d],l[d])),{height:n.getInputHeight(o),width:n.getInputWidth(o)})}));return r.forEach(a=>a.dispose()),n.isBatchInput?s:s[0]}getClassifierChannelsOut(){return 136}};var Yu=class extends pp{constructor(t=new up){super("FaceLandmark68Net",t)}getDefaultModelName(){return"face_landmark_68_model"}getClassifierChannelsIn(){return 256}};function UE(e){let t=[],{extractDenseBlock3Params:n}=Km(e,t),r={dense0:n("dense0",!0),dense1:n("dense1"),dense2:n("dense2")};return _n(e,t),{params:r,paramMappings:t}}function GE(e){let t=[],{extractWeights:n,getRemainingWeights:r}=En(e),{extractDenseBlock3Params:s}=jm(n,t),a=s(3,32,"dense0",!0),o=s(32,64,"dense1"),i=s(64,128,"dense2");if(r().length!==0)throw new Error(`weights remaing after extract: ${r().length}`);return{paramMappings:t,params:{dense0:a,dense1:o,dense2:i}}}var W1=class extends ln{constructor(){super("TinyFaceFeatureExtractor")}forwardInput(t){let{params:n}=this;if(!n)throw new Error("TinyFaceFeatureExtractor - load model before inference");return M(()=>{let r=ce(t.toBatchTensor(112,!0),"float32"),a=Xr(r,[122.782,117.001,104.298]).div(255),o=Um(a,n.dense0,!0);return o=Um(o,n.dense1),o=Um(o,n.dense2),o=lr(o,[14,14],[2,2],"valid"),o})}async forward(t){return this.forwardInput(await bt(t))}getDefaultModelName(){return"face_feature_extractor_tiny_model"}extractParamsFromWeightMap(t){return UE(t)}extractParams(t){return GE(t)}};var Qm=class extends pp{constructor(t=new W1){super("FaceLandmark68TinyNet",t)}getDefaultModelName(){return"face_landmark_68_tiny_model"}getClassifierChannelsIn(){return 128}};var HE=class extends Yu{};function jE(e,t){return Y(V(e,t.weights),t.biases)}function V1(e,t,n,r,s="same"){let{filters:a,bias:o}=t.conv,i=Rt(e,a,n,s);return i=Y(i,o),i=jE(i,t.scale),r?qe(i):i}function qE(e,t){return V1(e,t,[1,1],!0)}function U1(e,t){return V1(e,t,[1,1],!1)}function eg(e,t){return V1(e,t,[2,2],!0,"valid")}function rue(e,t){function n(i,c,l){let u=e(i),d=u.length/(c*l*l);if(m1(d))throw new Error(`depth has to be an integer: ${d}, weights.length: ${u.length}, numFilters: ${c}, filterSize: ${l}`);return M(()=>Re(Br(u,[c,d,l,l]),[2,3,1,0]))}function r(i,c,l,u){let d=n(i,c,l),p=He(e(c));return t.push({paramPath:`${u}/filters`},{paramPath:`${u}/bias`}),{filters:d,bias:p}}function s(i,c){let l=He(e(i)),u=He(e(i));return t.push({paramPath:`${c}/weights`},{paramPath:`${c}/biases`}),{weights:l,biases:u}}function a(i,c,l,u){let d=r(i,c,l,`${u}/conv`),p=s(c,`${u}/scale`);return{conv:d,scale:p}}function o(i,c,l,u,d=!1){let p=a((d?.5:1)*i,c,l,`${u}/conv1`),h=a(i,c,l,`${u}/conv2`);return{conv1:p,conv2:h}}return{extractConvLayerParams:a,extractResidualLayerParams:o}}function KE(e){let{extractWeights:t,getRemainingWeights:n}=En(e),r=[],{extractConvLayerParams:s,extractResidualLayerParams:a}=rue(t,r),o=s(4704,32,7,"conv32_down"),i=a(9216,32,3,"conv32_1"),c=a(9216,32,3,"conv32_2"),l=a(9216,32,3,"conv32_3"),u=a(36864,64,3,"conv64_down",!0),d=a(36864,64,3,"conv64_1"),p=a(36864,64,3,"conv64_2"),h=a(36864,64,3,"conv64_3"),f=a(147456,128,3,"conv128_down",!0),m=a(147456,128,3,"conv128_1"),g=a(147456,128,3,"conv128_2"),b=a(589824,256,3,"conv256_down",!0),y=a(589824,256,3,"conv256_1"),v=a(589824,256,3,"conv256_2"),x=a(589824,256,3,"conv256_down_out"),w=M(()=>Re(Lr(t(256*128),[128,256]),[1,0]));if(r.push({paramPath:"fc"}),n().length!==0)throw new Error(`weights remaing after extract: ${n().length}`);return{params:{conv32_down:o,conv32_1:i,conv32_2:c,conv32_3:l,conv64_down:u,conv64_1:d,conv64_2:p,conv64_3:h,conv128_down:f,conv128_1:m,conv128_2:g,conv256_down:b,conv256_1:y,conv256_2:v,conv256_down_out:x,fc:w},paramMappings:r}}function sue(e,t){let n=ar(e,t);function r(o){let i=n(`${o}/scale/weights`,1),c=n(`${o}/scale/biases`,1);return{weights:i,biases:c}}function s(o){let i=n(`${o}/conv/filters`,4),c=n(`${o}/conv/bias`,1),l=r(o);return{conv:{filters:i,bias:c},scale:l}}function a(o){return{conv1:s(`${o}/conv1`),conv2:s(`${o}/conv2`)}}return{extractConvLayerParams:s,extractResidualLayerParams:a}}function XE(e){let t=[],{extractConvLayerParams:n,extractResidualLayerParams:r}=sue(e,t),s=n("conv32_down"),a=r("conv32_1"),o=r("conv32_2"),i=r("conv32_3"),c=r("conv64_down"),l=r("conv64_1"),u=r("conv64_2"),d=r("conv64_3"),p=r("conv128_down"),h=r("conv128_1"),f=r("conv128_2"),m=r("conv256_down"),g=r("conv256_1"),b=r("conv256_2"),y=r("conv256_down_out"),{fc:v}=e;if(t.push({originalPath:"fc",paramPath:"fc"}),!f1(v))throw new Error(`expected weightMap[fc] to be a Tensor2D, instead have ${v}`);let x={conv32_down:s,conv32_1:a,conv32_2:o,conv32_3:i,conv64_down:c,conv64_1:l,conv64_2:u,conv64_3:d,conv128_down:p,conv128_1:h,conv128_2:f,conv256_down:m,conv256_1:g,conv256_2:b,conv256_down_out:y,fc:v};return _n(e,t),{params:x,paramMappings:t}}function Yr(e,t){let n=qE(e,t.conv1);return n=U1(n,t.conv2),n=Y(n,e),n=qe(n),n}function hp(e,t){let n=eg(e,t.conv1);n=U1(n,t.conv2);let r=lr(e,2,2,"valid"),s=St(r.shape),a=r.shape[3]!==n.shape[3];if(r.shape[1]!==n.shape[1]||r.shape[2]!==n.shape[2]){let i=[...n.shape];i[1]=1;let c=St(i);n=et([n,c],1);let l=[...n.shape];l[2]=1;let u=St(l);n=et([n,u],2)}return r=a?et([r,s],3):r,n=Y(r,n),n=qe(n),n}var Zu=class extends ln{constructor(){super("FaceRecognitionNet")}forwardInput(t){let{params:n}=this;if(!n)throw new Error("FaceRecognitionNet - load model before inference");return M(()=>{let r=ce(t.toBatchTensor(150,!0),"float32"),a=Xr(r,[122.782,117.001,104.298]).div(255),o=eg(a,n.conv32_down);o=Pt(o,3,2,"valid"),o=Yr(o,n.conv32_1),o=Yr(o,n.conv32_2),o=Yr(o,n.conv32_3),o=hp(o,n.conv64_down),o=Yr(o,n.conv64_1),o=Yr(o,n.conv64_2),o=Yr(o,n.conv64_3),o=hp(o,n.conv128_down),o=Yr(o,n.conv128_1),o=Yr(o,n.conv128_2),o=hp(o,n.conv256_down),o=Yr(o,n.conv256_1),o=Yr(o,n.conv256_2),o=hp(o,n.conv256_down_out);let i=o.mean([1,2]);return De(i,n.fc)})}async forward(t){return this.forwardInput(await bt(t))}async computeFaceDescriptor(t){var a;if((a=t==null?void 0:t.shape)==null?void 0:a.some(o=>o<=0))return new Float32Array(128);let n=await bt(t),r=M(()=>ht(this.forwardInput(n))),s=await Promise.all(r.map(o=>o.data()));return r.forEach(o=>o.dispose()),n.isBatchInput?s:s[0]}getDefaultModelName(){return"face_recognition_model"}extractParamsFromWeightMap(t){return XE(t)}extractParams(t){return KE(t)}};function aue(e){let t=new Zu;return t.extractWeights(e),t}function tg(e,t){return{...e,...{descriptor:t}}}function oue(e){return typeof e.age=="number"}function ng(e,t){return{...e,...{age:t}}}function iue(e){return(e.gender===Ms.MALE||e.gender===Ms.FEMALE)&&zu(e.genderProbability)}function rg(e,t,n){return{...e,...{gender:t,genderProbability:n}}}function cue(e,t){function n(c,l){let u=Br(e(3*3*c),[3,3,c,1]),d=He(e(c)),p=He(e(c)),h=He(e(c)),f=He(e(c));return t.push({paramPath:`${l}/filters`},{paramPath:`${l}/batch_norm_scale`},{paramPath:`${l}/batch_norm_offset`},{paramPath:`${l}/batch_norm_mean`},{paramPath:`${l}/batch_norm_variance`}),{filters:u,batch_norm_scale:d,batch_norm_offset:p,batch_norm_mean:h,batch_norm_variance:f}}function r(c,l,u,d,p){let h=Br(e(c*l*u*u),[u,u,c,l]),f=He(e(l));return t.push({paramPath:`${d}/filters`},{paramPath:`${d}/${p?"batch_norm_offset":"bias"}`}),{filters:h,bias:f}}function s(c,l,u,d){let{filters:p,bias:h}=r(c,l,u,d,!0);return{filters:p,batch_norm_offset:h}}function a(c,l,u){let d=n(c,`${u}/depthwise_conv`),p=s(c,l,1,`${u}/pointwise_conv`);return{depthwise_conv:d,pointwise_conv:p}}function o(){let c=s(3,32,3,"mobilenetv1/conv_0"),l=a(32,64,"mobilenetv1/conv_1"),u=a(64,128,"mobilenetv1/conv_2"),d=a(128,128,"mobilenetv1/conv_3"),p=a(128,256,"mobilenetv1/conv_4"),h=a(256,256,"mobilenetv1/conv_5"),f=a(256,512,"mobilenetv1/conv_6"),m=a(512,512,"mobilenetv1/conv_7"),g=a(512,512,"mobilenetv1/conv_8"),b=a(512,512,"mobilenetv1/conv_9"),y=a(512,512,"mobilenetv1/conv_10"),v=a(512,512,"mobilenetv1/conv_11"),x=a(512,1024,"mobilenetv1/conv_12"),w=a(1024,1024,"mobilenetv1/conv_13");return{conv_0:c,conv_1:l,conv_2:u,conv_3:d,conv_4:p,conv_5:h,conv_6:f,conv_7:m,conv_8:g,conv_9:b,conv_10:y,conv_11:v,conv_12:x,conv_13:w}}function i(){let c=s(1024,256,1,"prediction_layer/conv_0"),l=s(256,512,3,"prediction_layer/conv_1"),u=s(512,128,1,"prediction_layer/conv_2"),d=s(128,256,3,"prediction_layer/conv_3"),p=s(256,128,1,"prediction_layer/conv_4"),h=s(128,256,3,"prediction_layer/conv_5"),f=s(256,64,1,"prediction_layer/conv_6"),m=s(64,128,3,"prediction_layer/conv_7"),g=r(512,12,1,"prediction_layer/box_predictor_0/box_encoding_predictor"),b=r(512,9,1,"prediction_layer/box_predictor_0/class_predictor"),y=r(1024,24,1,"prediction_layer/box_predictor_1/box_encoding_predictor"),v=r(1024,18,1,"prediction_layer/box_predictor_1/class_predictor"),x=r(512,24,1,"prediction_layer/box_predictor_2/box_encoding_predictor"),w=r(512,18,1,"prediction_layer/box_predictor_2/class_predictor"),T=r(256,24,1,"prediction_layer/box_predictor_3/box_encoding_predictor"),C=r(256,18,1,"prediction_layer/box_predictor_3/class_predictor"),D=r(256,24,1,"prediction_layer/box_predictor_4/box_encoding_predictor"),F=r(256,18,1,"prediction_layer/box_predictor_4/class_predictor"),O=r(128,24,1,"prediction_layer/box_predictor_5/box_encoding_predictor"),$=r(128,18,1,"prediction_layer/box_predictor_5/class_predictor");return{conv_0:c,conv_1:l,conv_2:u,conv_3:d,conv_4:p,conv_5:h,conv_6:f,conv_7:m,box_predictor_0:{box_encoding_predictor:g,class_predictor:b},box_predictor_1:{box_encoding_predictor:y,class_predictor:v},box_predictor_2:{box_encoding_predictor:x,class_predictor:w},box_predictor_3:{box_encoding_predictor:T,class_predictor:C},box_predictor_4:{box_encoding_predictor:D,class_predictor:F},box_predictor_5:{box_encoding_predictor:O,class_predictor:$}}}return{extractMobilenetV1Params:o,extractPredictionLayerParams:i}}function YE(e){let t=[],{extractWeights:n,getRemainingWeights:r}=En(e),{extractMobilenetV1Params:s,extractPredictionLayerParams:a}=cue(n,t),o=s(),i=a(),l={extra_dim:zh(n(5118*4),[1,5118,4])};if(t.push({paramPath:"output_layer/extra_dim"}),r().length!==0)throw new Error(`weights remaing after extract: ${r().length}`);return{params:{mobilenetv1:o,prediction_layer:i,output_layer:l},paramMappings:t}}function uue(e,t){let n=ar(e,t);function r(l,u,d){let p=n(`${l}/Conv2d_${u}_pointwise/weights`,4,`${d}/filters`),h=n(`${l}/Conv2d_${u}_pointwise/convolution_bn_offset`,1,`${d}/batch_norm_offset`);return{filters:p,batch_norm_offset:h}}function s(l){let u=`mobilenetv1/conv_${l}`,d=`MobilenetV1/Conv2d_${l}_depthwise`,p=`${u}/depthwise_conv`,h=`${u}/pointwise_conv`,f=n(`${d}/depthwise_weights`,4,`${p}/filters`),m=n(`${d}/BatchNorm/gamma`,1,`${p}/batch_norm_scale`),g=n(`${d}/BatchNorm/beta`,1,`${p}/batch_norm_offset`),b=n(`${d}/BatchNorm/moving_mean`,1,`${p}/batch_norm_mean`),y=n(`${d}/BatchNorm/moving_variance`,1,`${p}/batch_norm_variance`);return{depthwise_conv:{filters:f,batch_norm_scale:m,batch_norm_offset:g,batch_norm_mean:b,batch_norm_variance:y},pointwise_conv:r("MobilenetV1",l,h)}}function a(){return{conv_0:r("MobilenetV1",0,"mobilenetv1/conv_0"),conv_1:s(1),conv_2:s(2),conv_3:s(3),conv_4:s(4),conv_5:s(5),conv_6:s(6),conv_7:s(7),conv_8:s(8),conv_9:s(9),conv_10:s(10),conv_11:s(11),conv_12:s(12),conv_13:s(13)}}function o(l,u){let d=n(`${l}/weights`,4,`${u}/filters`),p=n(`${l}/biases`,1,`${u}/bias`);return{filters:d,bias:p}}function i(l){let u=o(`Prediction/BoxPredictor_${l}/BoxEncodingPredictor`,`prediction_layer/box_predictor_${l}/box_encoding_predictor`),d=o(`Prediction/BoxPredictor_${l}/ClassPredictor`,`prediction_layer/box_predictor_${l}/class_predictor`);return{box_encoding_predictor:u,class_predictor:d}}function c(){return{conv_0:r("Prediction",0,"prediction_layer/conv_0"),conv_1:r("Prediction",1,"prediction_layer/conv_1"),conv_2:r("Prediction",2,"prediction_layer/conv_2"),conv_3:r("Prediction",3,"prediction_layer/conv_3"),conv_4:r("Prediction",4,"prediction_layer/conv_4"),conv_5:r("Prediction",5,"prediction_layer/conv_5"),conv_6:r("Prediction",6,"prediction_layer/conv_6"),conv_7:r("Prediction",7,"prediction_layer/conv_7"),box_predictor_0:i(0),box_predictor_1:i(1),box_predictor_2:i(2),box_predictor_3:i(3),box_predictor_4:i(4),box_predictor_5:i(5)}}return{extractMobilenetV1Params:a,extractPredictionLayerParams:c}}function ZE(e){let t=[],{extractMobilenetV1Params:n,extractPredictionLayerParams:r}=uue(e,t),s=e["Output/extra_dim"];if(t.push({originalPath:"Output/extra_dim",paramPath:"output_layer/extra_dim"}),!$s(s))throw new Error(`expected weightMap['Output/extra_dim'] to be a Tensor3D, instead have ${s}`);let a={mobilenetv1:n(),prediction_layer:r(),output_layer:{extra_dim:s}};return _n(e,t),{params:a,paramMappings:t}}function Fr(e,t,n){return M(()=>{let r=Rt(e,t.filters,n,"same");return r=Y(r,t.batch_norm_offset),Jt(r,0,6)})}var lue=.0010000000474974513;function due(e,t,n){return M(()=>{let r=ua(e,t.filters,n,"same");return r=Is(r,t.batch_norm_mean,t.batch_norm_variance,t.batch_norm_offset,t.batch_norm_scale,lue),Jt(r,0,6)})}function pue(e){return[2,4,6,12].some(t=>t===e)?[2,2]:[1,1]}function JE(e,t){return M(()=>{let n,r=Fr(e,t.conv_0,[2,2]);if([t.conv_1,t.conv_2,t.conv_3,t.conv_4,t.conv_5,t.conv_6,t.conv_7,t.conv_8,t.conv_9,t.conv_10,t.conv_11,t.conv_12,t.conv_13].forEach((a,o)=>{let i=o+1,c=pue(i);r=due(r,a.depthwise_conv,c),r=Fr(r,a.pointwise_conv,[1,1]),i===11&&(n=r)}),n===null)throw new Error("mobileNetV1 - output of conv layer 11 is null");return{out:r,conv11:n}})}function hue(e,t,n){let r=e.arraySync(),s=Math.min(r[t][0],r[t][2]),a=Math.min(r[t][1],r[t][3]),o=Math.max(r[t][0],r[t][2]),i=Math.max(r[t][1],r[t][3]),c=Math.min(r[n][0],r[n][2]),l=Math.min(r[n][1],r[n][3]),u=Math.max(r[n][0],r[n][2]),d=Math.max(r[n][1],r[n][3]),p=(o-s)*(i-a),h=(u-c)*(d-l);if(p<=0||h<=0)return 0;let f=Math.max(s,c),m=Math.max(a,l),g=Math.min(o,u),b=Math.min(i,d),y=Math.max(g-f,0)*Math.max(b-m,0);return y/(p+h-y)}function QE(e,t,n,r,s){let a=e.shape[0],o=Math.min(n,a),i=t.map((u,d)=>({score:u,boxIndex:d})).filter(u=>u.score>s).sort((u,d)=>d.score-u.score),c=u=>u<=r?1:0,l=[];return i.forEach(u=>{if(l.length>=o)return;let d=u.score;for(let p=l.length-1;p>=0;--p){let h=hue(e,u.boxIndex,l[p]);if(h!==0&&(u.score*=c(h),u.score<=s))break}d===u.score&&l.push(u.boxIndex)}),l}function fue(e){let t=ht(Re(e,[1,0])),n=[fe(t[2],t[0]),fe(t[3],t[1])],r=[Y(t[0],me(n[0],2)),Y(t[1],me(n[1],2))];return{sizes:n,centers:r}}function mue(e,t){let{sizes:n,centers:r}=fue(e),s=ht(Re(t,[1,0])),a=me(V(fn(me(s[2],5)),n[0]),2),o=Y(V(me(s[0],10),n[0]),r[0]),i=me(V(fn(me(s[3],5)),n[1]),2),c=Y(V(me(s[1],10),n[1]),r[1]);return Re(Ot([fe(o,a),fe(c,i),Y(o,a),Y(c,i)]),[1,0])}function eA(e,t,n){return M(()=>{let r=e.shape[0],s=mue(U(Pn(n.extra_dim,[r,1,1]),[-1,4]),U(e,[-1,4]));s=U(s,[r,s.shape[0]/r,4]);let a=dr(ze(t,[0,0,1],[-1,-1,-1])),o=ze(a,[0,0,0],[-1,-1,1]);o=U(o,[r,o.shape[1]]);let i=ht(s),c=ht(o);return{boxes:i,scores:c}})}function Ai(e,t){return M(()=>{let n=e.shape[0],r=U(_i(e,t.box_encoding_predictor),[n,-1,1,4]),s=U(_i(e,t.class_predictor),[n,-1,3]);return{boxPredictionEncoding:r,classPrediction:s}})}function tA(e,t,n){return M(()=>{let r=Fr(e,n.conv_0,[1,1]),s=Fr(r,n.conv_1,[2,2]),a=Fr(s,n.conv_2,[1,1]),o=Fr(a,n.conv_3,[2,2]),i=Fr(o,n.conv_4,[1,1]),c=Fr(i,n.conv_5,[2,2]),l=Fr(c,n.conv_6,[1,1]),u=Fr(l,n.conv_7,[2,2]),d=Ai(t,n.box_predictor_0),p=Ai(e,n.box_predictor_1),h=Ai(s,n.box_predictor_2),f=Ai(o,n.box_predictor_3),m=Ai(c,n.box_predictor_4),g=Ai(u,n.box_predictor_5),b=et([d.boxPredictionEncoding,p.boxPredictionEncoding,h.boxPredictionEncoding,f.boxPredictionEncoding,m.boxPredictionEncoding,g.boxPredictionEncoding],1),y=et([d.classPrediction,p.classPrediction,h.classPrediction,f.classPrediction,m.classPrediction,g.classPrediction],1);return{boxPredictions:b,classPredictions:y}})}var $r=class{constructor({minConfidence:t,maxResults:n}={}){this._name="SsdMobilenetv1Options";if(this._minConfidence=t||.5,this._maxResults=n||100,typeof this._minConfidence!="number"||this._minConfidence<=0||this._minConfidence>=1)throw new Error(`${this._name} - expected minConfidence to be a number between 0 and 1`);if(typeof this._maxResults!="number")throw new Error(`${this._name} - expected maxResults to be a number`)}get minConfidence(){return this._minConfidence}get maxResults(){return this._maxResults}};var Di=class extends ln{constructor(){super("SsdMobilenetv1")}forwardInput(t){let{params:n}=this;if(!n)throw new Error("SsdMobilenetv1 - load model before inference");return M(()=>{let r=ce(t.toBatchTensor(512,!1),"float32"),s=fe(me(r,127.5),1),a=JE(s,n.mobilenetv1),{boxPredictions:o,classPredictions:i}=tA(a.out,a.conv11,n.prediction_layer);return eA(o,i,n.output_layer)})}async forward(t){return this.forwardInput(await bt(t))}async locateFaces(t,n={}){let{maxResults:r,minConfidence:s}=new $r(n),a=await bt(t),{boxes:o,scores:i}=this.forwardInput(a),c=o[0],l=i[0];for(let v=1;v{let[x,w]=[Math.max(0,b[v][0]),Math.min(1,b[v][2])].map(D=>D*g),[T,C]=[Math.max(0,b[v][1]),Math.min(1,b[v][3])].map(D=>D*m);return new xt(u[v],new Vu(T,x,C-T,w-x),{height:a.getInputHeight(0),width:a.getInputWidth(0)})});return c.dispose(),l.dispose(),y}getDefaultModelName(){return"ssd_mobilenetv1_model"}extractParamsFromWeightMap(t){return ZE(t)}extractParams(t){return YE(t)}};function nA(e){let t=new Di;return t.extractWeights(e),t}function gue(e){return nA(e)}var rA=class extends Di{};var sA=.4,aA=[new Pe(.738768,.874946),new Pe(2.42204,2.65704),new Pe(4.30971,7.04493),new Pe(10.246,4.59428),new Pe(12.6868,11.8741)],oA=[new Pe(1.603231,2.094468),new Pe(6.041143,7.080126),new Pe(2.882459,3.518061),new Pe(4.266906,5.178857),new Pe(9.041765,10.66308)],iA=[117.001,114.697,97.404],cA="tiny_yolov2_model",uA="tiny_yolov2_separable_conv_model";var sg=e=>typeof e=="number";function G1(e){if(!e)throw new Error(`invalid config: ${e}`);if(typeof e.withSeparableConvs!="boolean")throw new Error(`config.withSeparableConvs has to be a boolean, have: ${e.withSeparableConvs}`);if(!sg(e.iouThreshold)||e.iouThreshold<0||e.iouThreshold>1)throw new Error(`config.iouThreshold has to be a number between [0, 1], have: ${e.iouThreshold}`);if(!Array.isArray(e.classes)||!e.classes.length||!e.classes.every(t=>typeof t=="string"))throw new Error(`config.classes has to be an array class names: string[], have: ${JSON.stringify(e.classes)}`);if(!Array.isArray(e.anchors)||!e.anchors.length||!e.anchors.map(t=>t||{}).every(t=>sg(t.x)&&sg(t.y)))throw new Error(`config.anchors has to be an array of { x: number, y: number }, have: ${JSON.stringify(e.anchors)}`);if(e.meanRgb&&(!Array.isArray(e.meanRgb)||e.meanRgb.length!==3||!e.meanRgb.every(sg)))throw new Error(`config.meanRgb has to be an array of shape [number, number, number], have: ${JSON.stringify(e.meanRgb)}`)}function Ju(e){return M(()=>{let t=V(e,Ie(.10000000149011612));return Y(qe(fe(e,t)),t)})}function Ls(e,t){return M(()=>{let n=pr(e,[[0,0],[1,1],[1,1],[0,0]]);return n=Rt(n,t.conv.filters,[1,1],"valid"),n=fe(n,t.bn.sub),n=V(n,t.bn.truediv),n=Y(n,t.conv.bias),Ju(n)})}function Bs(e,t){return M(()=>{let n=pr(e,[[0,0],[1,1],[1,1],[0,0]]);return n=ei(n,t.depthwise_filter,t.pointwise_filter,[1,1],"valid"),n=Y(n,t.bias),Ju(n)})}function bue(e,t){let n=ju(e,t);function r(o,i){let c=He(e(o)),l=He(e(o));return t.push({paramPath:`${i}/sub`},{paramPath:`${i}/truediv`}),{sub:c,truediv:l}}function s(o,i,c){let l=n(o,i,3,`${c}/conv`),u=r(i,`${c}/bn`);return{conv:l,bn:u}}let a=qu(e,t);return{extractConvParams:n,extractConvWithBatchNormParams:s,extractSeparableConvParams:a}}function lA(e,t,n,r){let{extractWeights:s,getRemainingWeights:a}=En(e),o=[],{extractConvParams:i,extractConvWithBatchNormParams:c,extractSeparableConvParams:l}=bue(s,o),u;if(t.withSeparableConvs){let[d,p,h,f,m,g,b,y,v]=r,x=t.isFirstLayerConv2d?i(d,p,3,"conv0"):l(d,p,"conv0"),w=l(p,h,"conv1"),T=l(h,f,"conv2"),C=l(f,m,"conv3"),D=l(m,g,"conv4"),F=l(g,b,"conv5"),O=y?l(b,y,"conv6"):void 0,$=v?l(y,v,"conv7"):void 0,R=i(v||y||b,5*n,1,"conv8");u={conv0:x,conv1:w,conv2:T,conv3:C,conv4:D,conv5:F,conv6:O,conv7:$,conv8:R}}else{let[d,p,h,f,m,g,b,y,v]=r,x=c(d,p,"conv0"),w=c(p,h,"conv1"),T=c(h,f,"conv2"),C=c(f,m,"conv3"),D=c(m,g,"conv4"),F=c(g,b,"conv5"),O=c(b,y,"conv6"),$=c(y,v,"conv7"),R=i(v,5*n,1,"conv8");u={conv0:x,conv1:w,conv2:T,conv3:C,conv4:D,conv5:F,conv6:O,conv7:$,conv8:R}}if(a().length!==0)throw new Error(`weights remaing after extract: ${a().length}`);return{params:u,paramMappings:o}}function yue(e,t){let n=ar(e,t);function r(i){let c=n(`${i}/sub`,1),l=n(`${i}/truediv`,1);return{sub:c,truediv:l}}function s(i){let c=n(`${i}/filters`,4),l=n(`${i}/bias`,1);return{filters:c,bias:l}}function a(i){let c=s(`${i}/conv`),l=r(`${i}/bn`);return{conv:c,bn:l}}let o=Ku(n);return{extractConvParams:s,extractConvWithBatchNormParams:a,extractSeparableConvParams:o}}function dA(e,t){let n=[],{extractConvParams:r,extractConvWithBatchNormParams:s,extractSeparableConvParams:a}=yue(e,n),o;if(t.withSeparableConvs){let i=t.filterSizes&&t.filterSizes.length||9;o={conv0:t.isFirstLayerConv2d?r("conv0"):a("conv0"),conv1:a("conv1"),conv2:a("conv2"),conv3:a("conv3"),conv4:a("conv4"),conv5:a("conv5"),conv6:i>7?a("conv6"):void 0,conv7:i>8?a("conv7"):void 0,conv8:r("conv8")}}else o={conv0:s("conv0"),conv1:s("conv1"),conv2:s("conv2"),conv3:s("conv3"),conv4:s("conv4"),conv5:s("conv5"),conv6:s("conv6"),conv7:s("conv7"),conv8:r("conv8")};return _n(e,n),{params:o,paramMappings:n}}var ms=class{constructor({inputSize:t,scoreThreshold:n}={}){this._name="TinyYolov2Options";if(this._inputSize=t||416,this._scoreThreshold=n||.5,typeof this._inputSize!="number"||this._inputSize%32!=0)throw new Error(`${this._name} - expected inputSize to be a number divisible by 32`);if(typeof this._scoreThreshold!="number"||this._scoreThreshold<=0||this._scoreThreshold>=1)throw new Error(`${this._name} - expected scoreThreshold to be a number between 0 and 1`)}get inputSize(){return this._inputSize}get scoreThreshold(){return this._scoreThreshold}};var H1=class extends ln{constructor(t){super("TinyYolov2");G1(t),this._config=t}get config(){return this._config}get withClassScores(){return this.config.withClassScores||this.config.classes.length>1}get boxEncodingSize(){return 5+(this.withClassScores?this.config.classes.length:0)}runTinyYolov2(t,n){let r=Ls(t,n.conv0);return r=Pt(r,[2,2],[2,2],"same"),r=Ls(r,n.conv1),r=Pt(r,[2,2],[2,2],"same"),r=Ls(r,n.conv2),r=Pt(r,[2,2],[2,2],"same"),r=Ls(r,n.conv3),r=Pt(r,[2,2],[2,2],"same"),r=Ls(r,n.conv4),r=Pt(r,[2,2],[2,2],"same"),r=Ls(r,n.conv5),r=Pt(r,[2,2],[1,1],"same"),r=Ls(r,n.conv6),r=Ls(r,n.conv7),_i(r,n.conv8,"valid",!1)}runMobilenet(t,n){let r=this.config.isFirstLayerConv2d?Ju(_i(t,n.conv0,"valid",!1)):Bs(t,n.conv0);return r=Pt(r,[2,2],[2,2],"same"),r=Bs(r,n.conv1),r=Pt(r,[2,2],[2,2],"same"),r=Bs(r,n.conv2),r=Pt(r,[2,2],[2,2],"same"),r=Bs(r,n.conv3),r=Pt(r,[2,2],[2,2],"same"),r=Bs(r,n.conv4),r=Pt(r,[2,2],[2,2],"same"),r=Bs(r,n.conv5),r=Pt(r,[2,2],[1,1],"same"),r=n.conv6?Bs(r,n.conv6):r,r=n.conv7?Bs(r,n.conv7):r,_i(r,n.conv8,"valid",!1)}forwardInput(t,n){let{params:r}=this;if(!r)throw new Error("TinyYolov2 - load model before inference");return M(()=>{let s=ce(t.toBatchTensor(n,!1),"float32");return s=this.config.meanRgb?Xr(s,this.config.meanRgb):s,s=s.div(255),this.config.withSeparableConvs?this.runMobilenet(s,r):this.runTinyYolov2(s,r)})}async forward(t,n){return this.forwardInput(await bt(t),n)}async detect(t,n={}){let{inputSize:r,scoreThreshold:s}=new ms(n),a=await bt(t),o=await this.forwardInput(a,r),i=M(()=>ht(o)[0].expandDims()),c={width:a.getInputWidth(0),height:a.getInputHeight(0)},l=await this.extractBoxes(i,a.getReshapedInputDimensions(0),s);o.dispose(),i.dispose();let u=l.map(g=>g.box),d=l.map(g=>g.score),p=l.map(g=>g.classScore),h=l.map(g=>this.config.classes[g.label]);return x1(u.map(g=>g.rescale(r)),d,this.config.iouThreshold,!0).map(g=>new Na(d[g],p[g],h[g],u[g],c))}getDefaultModelName(){return""}extractParamsFromWeightMap(t){return dA(t,this.config)}extractParams(t){let n=this.config.filterSizes||H1.DEFAULT_FILTER_SIZES,r=n?n.length:void 0;if(r!==7&&r!==8&&r!==9)throw new Error(`TinyYolov2 - expected 7 | 8 | 9 convolutional filters, but found ${r} filterSizes in config`);return lA(t,this.config,this.boxEncodingSize,n)}async extractBoxes(t,n,r){let{width:s,height:a}=n,o=Math.max(s,a),i=o/s,c=o/a,l=t.shape[1],u=this.config.anchors.length,[d,p,h]=M(()=>{let b=t.reshape([l,l,u,this.boxEncodingSize]),y=b.slice([0,0,0,0],[l,l,u,4]),v=b.slice([0,0,0,4],[l,l,u,1]),x=this.withClassScores?Mr(b.slice([0,0,0,5],[l,l,u,this.config.classes.length]),3):Ie(0);return[y,v,x]}),f=[],m=await p.array(),g=await d.array();for(let b=0;br){let w=(y+tp(g[b][y][v][0]))/l*i,T=(b+tp(g[b][y][v][1]))/l*c,C=Math.exp(g[b][y][v][2])*this.config.anchors[v].x/l*i,D=Math.exp(g[b][y][v][3])*this.config.anchors[v].y/l*c,F=w-C/2,O=T-D/2,$={row:b,col:y,anchor:v},{classScore:R,label:N}=this.withClassScores?await this.extractPredictedClass(h,$):{classScore:1,label:0};f.push({box:new Wu(F,O,F+C,O+D),score:x,classScore:x*R,label:N,...$})}}return d.dispose(),p.dispose(),h.dispose(),f}async extractPredictedClass(t,n){let{row:r,col:s,anchor:a}=n,o=await t.array();return Array(this.config.classes.length).fill(0).map((i,c)=>o[r][s][a][c]).map((i,c)=>({classScore:i,label:c})).reduce((i,c)=>i.classScore>c.classScore?i:c)}},Qu=H1;Qu.DEFAULT_FILTER_SIZES=[3,16,32,64,128,256,512,1024,1024];var el=class extends Qu{constructor(t=!0){let n={withSeparableConvs:t,iouThreshold:sA,classes:["face"],...t?{anchors:oA,meanRgb:iA}:{anchors:aA,withClassScores:!0}};super(n)}get withSeparableConvs(){return this.config.withSeparableConvs}get anchors(){return this.config.anchors}async locateFaces(t,n){return(await this.detect(t,n)).map(s=>new xt(s.score,s.relativeBox,{width:s.imageWidth,height:s.imageHeight}))}getDefaultModelName(){return this.withSeparableConvs?uA:cA}extractParamsFromWeightMap(t){return super.extractParamsFromWeightMap(t)}};function vue(e,t=!0){let n=new el(t);return n.extractWeights(e),n}var ag=class extends ms{constructor(){super(...arguments);this._name="TinyFaceDetectorOptions"}};var Rr=class{async then(t){return t(await this.run())}async run(){throw new Error("ComposableTask - run is not implemented")}};async function Fi(e,t,n,r,s=({alignedRect:a})=>a){let a=e.map(c=>Ei(c)?s(c):c.detection),o=r||(t instanceof Ee?await Hu(t,a):await Gu(t,a)),i=await n(o);return o.forEach(c=>c instanceof Ee&&c.dispose()),i}async function tl(e,t,n,r,s){return Fi([e],t,async a=>n(a[0]),r,s)}var pA=.4,hA=[new Pe(1.603231,2.094468),new Pe(6.041143,7.080126),new Pe(2.882459,3.518061),new Pe(4.266906,5.178857),new Pe(9.041765,10.66308)],fA=[117.001,114.697,97.404];var nl=class extends Qu{constructor(){let t={withSeparableConvs:!0,iouThreshold:pA,classes:["face"],anchors:hA,meanRgb:fA,isFirstLayerConv2d:!0,filterSizes:[3,16,32,64,128,256,512]};super(t)}get anchors(){return this.config.anchors}async locateFaces(t,n){return(await this.detect(t,n)).map(s=>new xt(s.score,s.relativeBox,{width:s.imageWidth,height:s.imageHeight}))}getDefaultModelName(){return"tiny_face_detector_model"}extractParamsFromWeightMap(t){return super.extractParamsFromWeightMap(t)}};var nt={ssdMobilenetv1:new Di,tinyFaceDetector:new nl,tinyYolov2:new el,faceLandmark68Net:new Yu,faceLandmark68TinyNet:new Qm,faceRecognitionNet:new Zu,faceExpressionNet:new Ym,ageGenderNet:new Jm},mA=(e,t)=>nt.ssdMobilenetv1.locateFaces(e,t),xue=(e,t)=>nt.tinyFaceDetector.locateFaces(e,t),wue=(e,t)=>nt.tinyYolov2.locateFaces(e,t),gA=e=>nt.faceLandmark68Net.detectLandmarks(e),kue=e=>nt.faceLandmark68TinyNet.detectLandmarks(e),Iue=e=>nt.faceRecognitionNet.computeFaceDescriptor(e),Sue=e=>nt.faceExpressionNet.predictExpressions(e),Tue=e=>nt.ageGenderNet.predictAgeAndGender(e),bA=e=>nt.ssdMobilenetv1.load(e),Cue=e=>nt.tinyFaceDetector.load(e),Nue=e=>nt.tinyYolov2.load(e),_ue=e=>nt.faceLandmark68Net.load(e),Eue=e=>nt.faceLandmark68TinyNet.load(e),Aue=e=>nt.faceRecognitionNet.load(e),Due=e=>nt.faceExpressionNet.load(e),Fue=e=>nt.ageGenderNet.load(e),$ue=bA,Rue=mA,Pue=gA;var j1=class extends Rr{constructor(t,n,r){super();this.parentTask=t;this.input=n;this.extractedFaces=r}},rl=class extends j1{async run(){let t=await this.parentTask,n=await Fi(t,this.input,async r=>Promise.all(r.map(s=>nt.faceExpressionNet.predictExpressions(s))),this.extractedFaces);return t.map((r,s)=>Zm(r,n[s]))}withAgeAndGender(){return new al(this,this.input)}},sl=class extends j1{async run(){let t=await this.parentTask;if(!t)return;let n=await tl(t,this.input,r=>nt.faceExpressionNet.predictExpressions(r),this.extractedFaces);return Zm(t,n)}withAgeAndGender(){return new ol(this,this.input)}},$i=class extends rl{withAgeAndGender(){return new Pi(this,this.input)}withFaceDescriptors(){return new Aa(this,this.input)}},Ri=class extends sl{withAgeAndGender(){return new Oi(this,this.input)}withFaceDescriptor(){return new Da(this,this.input)}};var q1=class extends Rr{constructor(t,n,r){super();this.parentTask=t;this.input=n;this.extractedFaces=r}},al=class extends q1{async run(){let t=await this.parentTask,n=await Fi(t,this.input,async r=>Promise.all(r.map(s=>nt.ageGenderNet.predictAgeAndGender(s))),this.extractedFaces);return t.map((r,s)=>{let{age:a,gender:o,genderProbability:i}=n[s];return ng(rg(r,o,i),a)})}withFaceExpressions(){return new rl(this,this.input)}},ol=class extends q1{async run(){let t=await this.parentTask;if(!t)return;let{age:n,gender:r,genderProbability:s}=await tl(t,this.input,a=>nt.ageGenderNet.predictAgeAndGender(a),this.extractedFaces);return ng(rg(t,r,s),n)}withFaceExpressions(){return new sl(this,this.input)}},Pi=class extends al{withFaceExpressions(){return new $i(this,this.input)}withFaceDescriptors(){return new Aa(this,this.input)}},Oi=class extends ol{withFaceExpressions(){return new Ri(this,this.input)}withFaceDescriptor(){return new Da(this,this.input)}};var og=class extends Rr{constructor(t,n){super();this.parentTask=t;this.input=n}},Aa=class extends og{async run(){let t=await this.parentTask;return(await Fi(t,this.input,r=>Promise.all(r.map(s=>nt.faceRecognitionNet.computeFaceDescriptor(s))),null,r=>r.landmarks.align(null,{useDlibAlignment:!0}))).map((r,s)=>tg(t[s],r))}withFaceExpressions(){return new $i(this,this.input)}withAgeAndGender(){return new Pi(this,this.input)}},Da=class extends og{async run(){let t=await this.parentTask;if(!t)return;let n=await tl(t,this.input,r=>nt.faceRecognitionNet.computeFaceDescriptor(r),null,r=>r.landmarks.align(null,{useDlibAlignment:!0}));return tg(t,n)}withFaceExpressions(){return new Ri(this,this.input)}withAgeAndGender(){return new Oi(this,this.input)}};var ig=class extends Rr{constructor(t,n,r){super();this.parentTask=t;this.input=n;this.useTinyLandmarkNet=r}get landmarkNet(){return this.useTinyLandmarkNet?nt.faceLandmark68TinyNet:nt.faceLandmark68Net}},cg=class extends ig{async run(){let t=await this.parentTask,n=t.map(a=>a.detection),r=this.input instanceof Ee?await Hu(this.input,n):await Gu(this.input,n),s=await Promise.all(r.map(a=>this.landmarkNet.detectLandmarks(a)));return r.forEach(a=>a instanceof Ee&&a.dispose()),t.map((a,o)=>Xu(a,s[o]))}withFaceExpressions(){return new $i(this,this.input)}withAgeAndGender(){return new Pi(this,this.input)}withFaceDescriptors(){return new Aa(this,this.input)}},ug=class extends ig{async run(){let t=await this.parentTask;if(!t)return;let{detection:n}=t,r=this.input instanceof Ee?await Hu(this.input,[n]):await Gu(this.input,[n]),s=await this.landmarkNet.detectLandmarks(r[0]);return r.forEach(a=>a instanceof Ee&&a.dispose()),Xu(t,s)}withFaceExpressions(){return new Ri(this,this.input)}withAgeAndGender(){return new Oi(this,this.input)}withFaceDescriptor(){return new Da(this,this.input)}};var lg=class extends Rr{constructor(t,n=new $r){super();this.input=t;this.options=n}},fp=class extends lg{async run(){let{input:t,options:n}=this,r;if(n instanceof ag)r=nt.tinyFaceDetector.locateFaces(t,n);else if(n instanceof $r)r=nt.ssdMobilenetv1.locateFaces(t,n);else if(n instanceof ms)r=nt.tinyYolov2.locateFaces(t,n);else throw new Error("detectFaces - expected options to be instance of TinyFaceDetectorOptions | SsdMobilenetv1Options | TinyYolov2Options");return r}runAndExtendWithFaceDetections(){return new Promise((t,n)=>{this.run().then(r=>t(r.map(s=>Si({},s)))).catch(r=>n(r))})}withFaceLandmarks(t=!1){return new cg(this.runAndExtendWithFaceDetections(),this.input,t)}withFaceExpressions(){return new rl(this.runAndExtendWithFaceDetections(),this.input)}withAgeAndGender(){return new al(this.runAndExtendWithFaceDetections(),this.input)}},dg=class extends lg{async run(){let t=await new fp(this.input,this.options),n=t[0];return t.forEach(r=>{r.score>n.score&&(n=r)}),n}runAndExtendWithFaceDetection(){return new Promise(async t=>{let n=await this.run();t(n?Si({},n):void 0)})}withFaceLandmarks(t=!1){return new ug(this.runAndExtendWithFaceDetection(),this.input,t)}withFaceExpressions(){return new sl(this.runAndExtendWithFaceDetection(),this.input)}withAgeAndGender(){return new ol(this.runAndExtendWithFaceDetection(),this.input)}};function Oue(e,t=new $r){return new dg(e,t)}function pg(e,t=new $r){return new fp(e,t)}async function yA(e,t){return pg(e,new $r(t?{minConfidence:t}:{})).withFaceLandmarks().withFaceDescriptors()}async function Mue(e,t={}){return pg(e,new ms(t)).withFaceLandmarks().withFaceDescriptors()}var Lue=yA;function K1(e,t){if(e.length!==t.length)throw new Error("euclideanDistance: arr1.length !== arr2.length");let n=Array.from(e),r=Array.from(t);return Math.sqrt(n.map((s,a)=>s-r[a]).reduce((s,a)=>s+a**2,0))}var hg=class{constructor(t,n=.6){this._distanceThreshold=n;let r=Array.isArray(t)?t:[t];if(!r.length)throw new Error("FaceRecognizer.constructor - expected atleast one input");let s=1,a=()=>`person ${s++}`;this._labeledDescriptors=r.map(o=>{if(o instanceof Rs)return o;if(o instanceof Float32Array)return new Rs(a(),[o]);if(o.descriptor&&o.descriptor instanceof Float32Array)return new Rs(a(),[o.descriptor]);throw new Error("FaceRecognizer.constructor - expected inputs to be of type LabeledFaceDescriptors | WithFaceDescriptor | Float32Array | Array | Float32Array>")})}get labeledDescriptors(){return this._labeledDescriptors}get distanceThreshold(){return this._distanceThreshold}computeMeanDistance(t,n){return n.map(r=>K1(r,t)).reduce((r,s)=>r+s,0)/(n.length||1)}matchDescriptor(t){return this.labeledDescriptors.map(({descriptors:n,label:r})=>new np(r,this.computeMeanDistance(t,n))).reduce((n,r)=>n.distancet.toJSON())}}static fromJSON(t){let n=t.labeledDescriptors.map(r=>Rs.fromJSON(r));return new hg(n,t.distanceThreshold)}};function Bue(e){let t=new nl;return t.extractWeights(e),t}function vA(e,t){let{width:n,height:r}=new Nn(t.width,t.height);if(n<=0||r<=0)throw new Error(`resizeResults - invalid dimensions: ${JSON.stringify({width:n,height:r})}`);if(Array.isArray(e))return e.map(s=>vA(s,{width:n,height:r}));if(Ei(e)){let s=e.detection.forSize(n,r),a=e.unshiftedLandmarks.forSize(s.box.width,s.box.height);return Xu(Si(e,s),a)}return hs(e)?Si(e,e.detection.forSize(n,r)):e instanceof yr||e instanceof xt?e.forSize(n,r):e}var zue=ME;return Wue;})(); + ${s.shape}`);if(a.shape.length!==1)throw new Error(`Target shape should be a vector but received shape ${a.shape}`);let o=t.dataIdMap.get(r.dataId).id,i=t.dataIdMap.get(s.dataId).id,c=t.dataIdMap.get(a.dataId).id,l=r.shape[0],u=k.sizeFromShape(a.shape),d=t.makeOutput([l,u],r.dtype),p=t.dataIdMap.get(d.dataId).id,h=t.makeOutput([u],a.dtype),f=t.dataIdMap.get(h.dataId).id,m=t.makeOutput([3],"int32"),g=t.dataIdMap.get(m.dataId).id;gE(o,i,c,l,p,f,g);let b=t.readSync(m.dataId),y;switch(b[0]){case 0:{y=_.getSparseReshapeMultipleNegativeOneOutputDimErrorMessage(b[1],b[2]);break}case 1:{y=_.getSparseReshapeNegativeOutputDimErrorMessage(b[1],b[2]);break}case 2:y=_.getSparseReshapeEmptyTensorZeroOutputDimErrorMessage();break;case 3:{let v=Array.from(t.readSync(s.dataId)),x=Array.from(t.readSync(h.dataId));y=_.getSparseReshapeInputOutputMultipleErrorMessage(v,x);break}case 4:{let v=Array.from(t.readSync(s.dataId)),x=Array.from(t.readSync(h.dataId));y=_.getSparseReshapeInputOutputMismatchErrorMessage(v,x);break}default:y=""}if(t.disposeData(m.dataId),y)throw t.disposeData(d.dataId),t.disposeData(h.dataId),new Error(y);return[d,h]}var Fie={kernelName:Hc,backendName:"wasm",setupFunc:Aie,kernelFunc:Die},bE;function yE(e){bE=e.wasm.cwrap("SparseSegmentReduction",null,["number","number","number","number","number","number","number","number","number"])}function vE(e,t){let{backend:n,inputs:r}=e,{data:s,indices:a,segmentIds:o}=r,i=a.shape[0],c=n.readSync(o.dataId,i-1,i)[0],u=i>0?c+1:0;if(u<0)throw new Error(_.getSparseSegmentReductionNegativeSegmentIdsErrorMessage());let d=s.shape.slice();d[0]=u;let p=n.dataIdMap.get(s.dataId).id,h=n.dataIdMap.get(a.dataId).id,f=n.dataIdMap.get(o.dataId).id,m=n.makeOutput(d,s.dtype),g=n.dataIdMap.get(m.dataId).id,b=n.makeOutput([4],"int32"),y=n.dataIdMap.get(b.dataId).id;bE(p,$t[s.dtype],s.shape[0],h,f,g,y,t,0);let v=n.readSync(b.dataId),x;switch(v[0]){case 0:{x=_.getSparseSegmentReductionNegativeSegmentIdsErrorMessage();break}case 1:{x=_.getSparseSegmentReductionNonIncreasingSegmentIdsErrorMessage();break}case 2:x=_.getSparseSegmentReductionSegmentIdOutOfRangeErrorMessage(v[1],v[2]);break;case 3:x=_.getSparseSegmentReductionIndicesOutOfRangeErrorMessage(v[1],v[2],v[3]);break;default:x=""}if(n.disposeData(b.dataId),x)throw n.disposeData(m.dataId),new Error(x);return m}function $ie(e){return vE(e,!0)}var Rie={kernelName:Ml,backendName:"wasm",setupFunc:yE,kernelFunc:$ie};function Pie(e){return vE(e,!1)}var Oie={kernelName:Ll,backendName:"wasm",setupFunc:yE,kernelFunc:Pie};function Mie(e){let{inputs:t,attrs:n,backend:r}=e,{x:s}=t,{numOrSizeSplits:a,axis:o}=n,i=k.parseAxisParam(o,s.shape)[0],c=_.prepareSplitSize(s,a,i),l=new Array(s.shape.length).fill(0),u=s.shape.slice();return c.map(d=>{let p=[...u];p[i]=d;let h=xi({inputs:{x:s},attrs:{begin:l,size:p},backend:r});return l[i]+=d,h})}var Lie={kernelName:Gc,backendName:"wasm",kernelFunc:Mie},Bie=un(_o),zie=un(Bl),Wie=!0,Vie=Cn(Do,Wie),xE;function Uie(e){xE=e.wasm.cwrap(ea,null,["number","number","number","number"])}function Gie(e){let{backend:t,inputs:n,attrs:r}=e,{alpha:s}=r,{x:a}=n,o=t.dataIdMap.get(a.dataId).id,i=t.makeOutput(a.shape,a.dtype),c=t.dataIdMap.get(i.dataId).id;return xE(o,s,$t[a.dtype],c),i}var Hie={kernelName:ea,backendName:"wasm",setupFunc:Uie,kernelFunc:Gie},wE;function jie(e){wE=e.wasm.cwrap(jc,null,["number","array","number","array","array","array","array","array","number","number"])}function qie(e){let{backend:t,inputs:n,attrs:r}=e,{x:s}=n,{begin:a,end:o,strides:i,beginMask:c,endMask:l,ellipsisMask:u,newAxisMask:d,shrinkAxisMask:p}=r,{finalShapeSparse:h,finalShape:f,isIdentity:m,sliceDim0:g,isSimpleSlice:b,begin:y,end:v,strides:x}=Gt.sliceInfo(s.shape,a,o,i,c,l,u,d,p),w;if(m)w=Vn({inputs:{x:s},backend:t,attrs:{shape:f}});else if(g||b){k.assert(s.shape.length>=1,()=>`Input must have rank at least 1, got: ${s.shape.length}`);let T=Gt.computeOutShape(y,v,x),C=xi({inputs:{x:s},backend:t,attrs:{begin:y,size:T}});w=Vn({inputs:{x:C},backend:t,attrs:{shape:f}}),t.disposeData(C.dataId)}else{let T=t.makeOutput(h,"float32"),C=t.dataIdMap.get(s.dataId).id,D=new Uint8Array(new Int32Array(k.computeStrides(s.shape)).buffer),F=new Uint8Array(new Int32Array(y).buffer),O=new Uint8Array(new Int32Array(v).buffer),$=new Uint8Array(new Int32Array(x).buffer),R=new Uint8Array(new Int32Array(h).buffer),N=new Uint8Array(new Int32Array(k.computeStrides(h)).buffer),L=t.dataIdMap.get(T.dataId).id;wE(C,D,s.shape.length,F,O,$,R,N,h.length,L),w=Vn({inputs:{x:T},backend:t,attrs:{shape:f}}),t.disposeData(T.dataId)}return w}var Kie={kernelName:jc,backendName:"wasm",setupFunc:jie,kernelFunc:qie},Xie=!0,Yie=Cn(Fo,Xie),kE;function Zie(e){kE=e.wasm.cwrap(Eo,null,["number","number","number","number"])}function Jie(e){let{backend:t,inputs:n,attrs:r}=e,{axis:s,keepDims:a}=r,{x:o}=n,i=t.dataIdMap.get(o.dataId).id,c=i,l=o,{transposed:u,axes:d,originalAxes:p,inputWasTransposed:h}=Ca(o,s,t),f=d;if(h){let v=t.dataIdMap.get(u.dataId).id;v!==i&&(l=u,c=v,f=_.getInnerMostAxes(f.length,l.shape.length))}_.assertAxesAreInnerMostDims("sum",f,l.shape.length);let[m,g]=_.computeOutAndReduceShapes(l.shape,f),b=k.sizeFromShape(g),y=t.makeOutput(m,l.dtype);if(k.sizeFromShape(l.shape)!==0){let v=t.dataIdMap.get(y.dataId).id;kE(c,b,$t[y.dtype],v)}if(h&&t.disposeData(u.dataId),a){let v=_.expandShapeToKeepDim(y.shape,p);y.shape=v}return y}var Qie={kernelName:Eo,backendName:"wasm",setupFunc:Zie,kernelFunc:Jie},ece=un($o),tce=un(Ro),IE;function nce(e){IE=e.wasm.cwrap(Qs,null,["number","array","number","array","number","number"])}function rce(e){let{inputs:t,backend:n,attrs:r}=e,{x:s}=t,a=n.dataIdMap.get(s.dataId).id,{reps:o}=r,i=new Array(s.shape.length);for(let p=0;p{let{x:r}=e,{k:s,sorted:a}=n,o=t.dataIdMap.get(r.dataId).id,i=new Uint8Array(new Int32Array(r.shape).buffer),c=r.shape.slice();c[c.length-1]=s;let l=t.makeOutput(c,r.dtype),u=t.dataIdMap.get(l.dataId).id,d=t.makeOutput(c,"int32"),p=t.dataIdMap.get(d.dataId).id;return SE(o,i,r.shape.length,$t[r.dtype],s,a,u,p),[l,d]},ice={kernelName:qc,backendName:"wasm",setupFunc:ace,kernelFunc:oce},TE;function cce(e){TE=e.wasm.cwrap(Kc,null,["number","number","bool","number","number","number","number","number","number","array","number","number","number","number","number"])}function uce(e){let{backend:t,inputs:n,attrs:r}=e,{image:s,transforms:a}=n,{interpolation:o,fillMode:i,fillValue:c,outputShape:l}=r,[u,d,p,h]=s.shape,[f,m]=l!=null?l:[d,p],g=[u,f,m,h],b=new Uint8Array(new Int32Array(k.computeStrides(s.shape)).buffer),y=t.makeOutput(g,s.dtype),v=t.dataIdMap.get(y.dataId).id,w=t.dataIdMap.get(s.dataId).id,C=t.dataIdMap.get(a.dataId).id,D=o==="nearest"?1:2,F;switch(i){case"constant":F=1;break;case"reflect":F=2;break;case"wrap":F=3;break;case"nearest":F=4;break;default:F=1;break}return TE(w,C,a.shape[0]>1,u,f,m,h,p,d,b,s.shape.length-1,D,F,c,v),y}var lce={kernelName:Kc,backendName:"wasm",setupFunc:cce,kernelFunc:uce};function dce(e){let{inputs:t,backend:n,attrs:r}=e,{value:s}=t,{axis:a}=r;a<0&&(a+=s.shape.length);let o=s.shape[a],i=s.shape.length,c=new Array(i-1),l=0;for(let h=0;h({dataId:h,dtype:f,shape:c}))}var pce={kernelName:Xc,backendName:"wasm",kernelFunc:dce};function hce(e){let{inputs:{x:t},backend:n}=e,r=n.makeOutput(t.shape,t.dtype);return n.typedArrayFromHeap(r).fill(0),r}var fce={kernelName:Yc,backendName:"wasm",kernelFunc:hce},mce=[ise,use,pse,xse,Ise,Cse,Ese,$se,Bse,zse,Wse,Gse,Hse,Kse,Zse,Jse,Qse,nae,aae,cae,dae,pae,fae,mae,gae,bae,xae,wae,Iae,ose,Cae,Eae,Fae,Pae,Lae,zae,Vae,hse,Hae,qae,Xae,Yae,Jae,toe,roe,ooe,uoe,poe,foe,boe,voe,xoe,Ioe,Coe,Eoe,Doe,Roe,Ooe,Loe,aE,Voe,Hoe,Koe,Yoe,Joe,Qoe,eie,Ase,rie,oie,uie,die,lie,fie,bie,xie,wie,Mse,Sie,Cie,Eie,Fie,Rie,Oie,Lie,Bie,zie,Vie,Hie,Kie,Yie,Qie,ece,tce,sce,ice,lce,bse,pce,fce];for(let e of mce)Vl(e);var l1=Q();l1.registerFlag("WASM_HAS_SIMD_SUPPORT",async()=>WebAssembly.validate(new Uint8Array([0,97,115,109,1,0,0,0,1,4,1,96,0,0,3,2,1,0,10,9,1,7,0,65,0,253,15,26,11])));l1.registerFlag("WASM_HAS_MULTITHREAD_SUPPORT",async()=>{if(l1.get("IS_NODE"))return!1;try{return new MessageChannel().port1.postMessage(new SharedArrayBuffer(1)),WebAssembly.validate(new Uint8Array([0,97,115,109,1,0,0,0,1,4,1,96,0,0,3,2,1,0,5,4,1,3,1,1,10,11,1,9,0,65,0,254,16,2,0,26,11]))}catch(e){return!1}});var CE=Oa(BD()),gce='var Module={};function threadPrintErr(){var text=Array.prototype.slice.call(arguments).join(" ");console.error(text)}function threadAlert(){var text=Array.prototype.slice.call(arguments).join(" ");postMessage({cmd:"alert",text:text,threadId:Module["_pthread_self"]()})}var err=threadPrintErr;this.alert=threadAlert;Module["instantiateWasm"]=function(info,receiveInstance){var instance=new WebAssembly.Instance(Module["wasmModule"],info);Module["wasmModule"]=null;receiveInstance(instance);return instance.exports};function moduleLoaded(){}this.onmessage=function(e){try{if(e.data.cmd==="load"){Module["wasmModule"]=e.data.wasmModule;Module["wasmMemory"]=e.data.wasmMemory;Module["buffer"]=Module["wasmMemory"].buffer;Module["ENVIRONMENT_IS_PTHREAD"]=true;if(typeof e.data.urlOrBlob==="string"){importScripts(e.data.urlOrBlob)}else{var objectUrl=URL.createObjectURL(e.data.urlOrBlob);importScripts(objectUrl);URL.revokeObjectURL(objectUrl)}WasmBackendModuleThreadedSimd(Module).then(function(instance){Module=instance;moduleLoaded()})}else if(e.data.cmd==="objectTransfer"){Module["PThread"].receiveObjectTransfer(e.data)}else if(e.data.cmd==="run"){Module["__performance_now_clock_drift"]=performance.now()-e.data.time;Module["__emscripten_thread_init"](e.data.threadInfoStruct,0,0);var max=e.data.stackBase;var top=e.data.stackBase+e.data.stackSize;Module["establishStackSpace"](top,max);Module["_emscripten_tls_init"]();Module["PThread"].receiveObjectTransfer(e.data);Module["PThread"].setThreadStatus(Module["_pthread_self"](),1);try{var result=Module["invokeEntryPoint"](e.data.start_routine,e.data.arg);if(!Module["getNoExitRuntime"]())Module["PThread"].threadExit(result)}catch(ex){if(ex==="Canceled!"){Module["PThread"].threadCancel()}else if(ex!="unwind"){if(ex instanceof Module["ExitStatus"]){if(Module["getNoExitRuntime"]()){}else{Module["PThread"].threadExit(ex.status)}}else{Module["PThread"].threadExit(-2);throw ex}}}}else if(e.data.cmd==="cancel"){if(Module["_pthread_self"]()){Module["PThread"].threadCancel()}}else if(e.data.target==="setimmediate"){}else if(e.data.cmd==="processThreadQueue"){if(Module["_pthread_self"]()){Module["_emscripten_current_thread_process_queued_calls"]()}}else{err("worker.js received unknown command "+e.data.cmd);err(e.data)}}catch(ex){err("worker.js onmessage() captured an uncaught exception: "+ex);if(ex&&ex.stack)err(ex.stack);throw ex}};if(typeof process==="object"&&typeof process.versions==="object"&&typeof process.versions.node==="string"){self={location:{href:__filename}};var onmessage=this.onmessage;var nodeWorkerThreads=require("worker_threads");global.Worker=nodeWorkerThreads.Worker;var parentPort=nodeWorkerThreads.parentPort;parentPort.on("message",function(data){onmessage({data:data})});var nodeFS=require("fs");var nodeRead=function(filename){return nodeFS.readFileSync(filename,"utf8")};function globalEval(x){global.require=require;global.Module=Module;eval.call(null,x)}importScripts=function(f){globalEval(nodeRead(f))};postMessage=function(msg){parentPort.postMessage(msg)};if(typeof performance==="undefined"){performance={now:function(){return Date.now()}}}}',bce=Oa(zD()),NE=class extends wl{constructor(e){super();this.wasm=e,this.dataIdNextNumber=1,this.wasm.tfjs.initWithThreadsCount(EE),p1=this.wasm.tfjs.getThreadsCount(),this.dataIdMap=new jp(this,ks())}write(e,t,n){let r={id:this.dataIdNextNumber++};return this.move(r,e,t,n,1),r}numDataIds(){return this.dataIdMap.numDataIds()}async time(e){let t=k.now();return e(),{kernelMs:k.now()-t}}move(e,t,n,r,s){let a=this.dataIdNextNumber++;if(r==="string"){let l=t;this.dataIdMap.set(e,{id:a,stringBytes:l,shape:n,dtype:r,memoryOffset:null,refCount:s});return}let o=k.sizeFromShape(n),i=o*k.bytesPerElement(r),c=this.wasm._malloc(i);this.dataIdMap.set(e,{id:a,memoryOffset:c,shape:n,dtype:r,refCount:s}),this.wasm.tfjs.registerTensor(a,o,c),t!=null&&this.wasm.HEAPU8.set(new Uint8Array(t.buffer,t.byteOffset,i),c)}async read(e){return this.readSync(e)}readSync(e,t,n){let{memoryOffset:r,dtype:s,shape:a,stringBytes:o}=this.dataIdMap.get(e);if(s==="string")return(t==null||t===0)&&(n==null||n>=o.length)?o:o.slice(t,n);t=t||0,n=n||k.sizeFromShape(a);let i=k.bytesPerElement(s),c=this.wasm.HEAPU8.slice(r+t*i,r+n*i);return xce(c.buffer,s)}disposeData(e,t=!1){if(this.dataIdMap.has(e)){let n=this.dataIdMap.get(e);if(n.refCount--,!t&&n.refCount>0)return!1;this.wasm._free(n.memoryOffset),this.wasm.tfjs.disposeData(n.id),this.dataIdMap.delete(e)}return!0}refCount(e){return this.dataIdMap.has(e)?this.dataIdMap.get(e).refCount:0}incRef(e){let t=this.dataIdMap.get(e);t!=null&&t.refCount++}floatPrecision(){return 32}getMemoryOffset(e){return this.dataIdMap.get(e).memoryOffset}dispose(){this.wasm.tfjs.dispose(),"PThread"in this.wasm&&this.wasm.PThread.terminateAllThreads(),this.wasm=null}memory(){return{unreliable:!1}}makeOutput(e,t,n){let r;if(n==null)r=this.write(null,e,t);else{let s=this.dataIdNextNumber++;r={id:s},this.dataIdMap.set(r,{id:s,memoryOffset:n,shape:e,dtype:t,refCount:1});let a=k.sizeFromShape(e);this.wasm.tfjs.registerTensor(s,a,n)}return{dataId:r,shape:e,dtype:t}}typedArrayFromHeap({shape:e,dtype:t,dataId:n}){let r=this.wasm.HEAPU8.buffer,{memoryOffset:s}=this.dataIdMap.get(n),a=k.sizeFromShape(e);switch(t){case"float32":return new Float32Array(r,s,a);case"int32":return new Int32Array(r,s,a);case"bool":return new Uint8Array(r,s,a);default:throw new Error(`Unknown dtype ${t}`)}}};function yce(e){return(t,n)=>(k.fetch(e,{credentials:"same-origin"}).then(r=>{r.ok||t.env.a(`failed to load wasm binary file at '${e}'`),r.arrayBuffer().then(s=>{WebAssembly.instantiate(s,t).then(a=>{n(a.instance,a.module)})})}),{})}function _E(e,t,n){if(Om!=null)return Om;let r="tfjs-backend-wasm.wasm";return e&&t?r="tfjs-backend-wasm-threaded-simd.wasm":e&&(r="tfjs-backend-wasm-simd.wasm"),Qd!=null&&Qd[r]!=null?Qd[r]:n+r}async function vce(){let[e,t]=await Promise.all([Q().getAsync("WASM_HAS_SIMD_SUPPORT"),Q().getAsync("WASM_HAS_MULTITHREAD_SUPPORT")]);return new Promise((n,r)=>{let s={};s.locateFile=(i,c)=>{if(i.endsWith(".worker.js")){let l=gce,u=new Blob([l],{type:"application/javascript"});return URL.createObjectURL(u)}return i.endsWith(".wasm")?_E(e,t,Jd!=null?Jd:c):c+i},d1&&(s.instantiateWasm=yce(_E(e,t,Jd!=null?Jd:"")));let a=!1;s.onAbort=()=>{if(a||ep)return;ep=!0,r({message:"Make sure the server can serve the `.wasm` file relative to the bundled js file. For more details see https://github.com/tensorflow/tfjs/blob/master/tfjs-backend-wasm/README.md#using-bundlers"})};let o;t&&e&&Om==null?(s.mainScriptUrlOrBlob=new Blob(["var WasmBackendModuleThreadedSimd = "+CE.default.toString()],{type:"text/javascript"}),o=(0,CE.default)(s)):o=(0,bce.default)(s),o.then(i=>{a=!0,ep=!1;let c=null;i.tfjs={init:i.cwrap("init",null,[]),initWithThreadsCount:i.cwrap("init_with_threads_count",null,["number"]),getThreadsCount:i.cwrap("get_threads_count","number",[]),registerTensor:i.cwrap("register_tensor",null,["number","number","number"]),disposeData:i.cwrap("dispose_data",c,["number"]),dispose:i.cwrap("dispose",c,[])},n({wasm:i})})})}function xce(e,t){switch(t){case"float32":return new Float32Array(e);case"int32":return new Int32Array(e);case"bool":return new Uint8Array(e);default:throw new Error(`Unknown dtype ${t}`)}}var wce=["tfjs-backend-wasm.wasm","tfjs-backend-wasm-simd.wasm","tfjs-backend-wasm-threaded-simd.wasm"],Om=null,Jd=null,Qd={},ep=!1,d1=!1;function kce(e,t=!1){if(_y("setWasmPath has been deprecated in favor of setWasmPaths and will be removed in a future release."),ep)throw new Error("The WASM backend was already initialized. Make sure you call `setWasmPath()` before you call `tf.setBackend()` or `tf.ready()`");Om=e,d1=t}function Ice(e,t=!1){if(ep)throw new Error("The WASM backend was already initialized. Make sure you call `setWasmPaths()` before you call `tf.setBackend()` or `tf.ready()`");if(typeof e=="string")Jd=e;else{Qd=e;let n=wce.filter(r=>Qd[r]==null);if(n.length>0)throw new Error(`There were no entries found for the following binaries: ${n.join(",")}. Please either call setWasmPaths with a map providing a path for each binary, or with a string indicating the directory where all the binaries can be found.`)}d1=t}var EE=-1,p1=-1;function Sce(e){EE=e}function Tce(){if(p1===-1)throw new Error("WASM backend not initialized.");return p1}var Cce="3.12.0",Nce=2;Vh("wasm",async()=>{let{wasm:e}=await vce();return new NE(e)},Nce);var _ce="3.12.0",Ece="3.12.0",Ace="3.12.0",Dce="3.12.0",Fce="3.12.0",$ce="3.12.0",Rce="3.12.0",Pce="3.12.0",Oce={tfjs:_ce,"tfjs-core":Ece,"tfjs-data":Ace,"tfjs-layers":Dce,"tfjs-converter":Fce,"tfjs-backend-cpu":$ce,"tfjs-backend-webgl":Rce,"tfjs-backend-wasm":Pce};var L1={};Up(L1,{AnchorPosition:()=>fs,DrawBox:()=>zm,DrawBoxOptions:()=>N1,DrawFaceLandmarks:()=>M1,DrawFaceLandmarksOptions:()=>O1,DrawTextField:()=>_a,DrawTextFieldOptions:()=>ap,drawContour:()=>Fs,drawDetections:()=>Hce,drawFaceExpressions:()=>Yce,drawFaceLandmarks:()=>Jce});function Fs(e,t,n=!1){if(e.beginPath(),t.slice(1).forEach(({x:r,y:s},a)=>{let o=t[a];e.moveTo(o.x,o.y),e.lineTo(r,s)}),n){let r=t[t.length-1],s=t[0];if(!r||!s)return;e.moveTo(r.x,r.y),e.lineTo(s.x,s.y)}e.stroke()}var b1={};Up(b1,{computeReshapedDimensions:()=>g1,getCenterPoint:()=>Ii,isDimensions:()=>Lm,isEven:()=>Mm,isFloat:()=>m1,isTensor:()=>wi,isTensor1D:()=>Mce,isTensor2D:()=>f1,isTensor3D:()=>$s,isTensor4D:()=>br,isValidNumber:()=>Kr,isValidProbablitiy:()=>zu,range:()=>ps,round:()=>ki});var Nn=class{constructor(t,n){if(!Kr(t)||!Kr(n))throw new Error(`Dimensions.constructor - expected width and height to be valid numbers, instead have ${JSON.stringify({width:t,height:n})}`);this._width=t,this._height=n}get width(){return this._width}get height(){return this._height}reverse(){return new Nn(1/this.width,1/this.height)}};function wi(e,t){return e instanceof Ee&&e.shape.length===t}function Mce(e){return wi(e,1)}function f1(e){return wi(e,2)}function $s(e){return wi(e,3)}function br(e){return wi(e,4)}function m1(e){return e%1!=0}function Mm(e){return e%2==0}function ki(e,t=2){let n=10**t;return Math.floor(e*n)/n}function Lm(e){return e&&e.width&&e.height}function g1({width:e,height:t},n){let r=n/Math.max(t,e);return new Nn(Math.round(e*r),Math.round(t*r))}function Ii(e){return e.reduce((t,n)=>t.add(n),new Pe(0,0)).div(new Pe(e.length,e.length))}function ps(e,t,n){return Array(e).fill(0).map((r,s)=>t+s*n)}function Kr(e){return!!e&&e!==1/0&&e!==-1/0&&!Number.isNaN(e)||e===0}function zu(e){return Kr(e)&&e>=0&&e<=1}var Pe=class{constructor(t,n){this._x=t,this._y=n}get x(){return this._x}get y(){return this._y}add(t){return new Pe(this.x+t.x,this.y+t.y)}sub(t){return new Pe(this.x-t.x,this.y-t.y)}mul(t){return new Pe(this.x*t.x,this.y*t.y)}div(t){return new Pe(this.x/t.x,this.y/t.y)}abs(){return new Pe(Math.abs(this.x),Math.abs(this.y))}magnitude(){return Math.sqrt(this.x**2+this.y**2)}floor(){return new Pe(Math.floor(this.x),Math.floor(this.y))}};var ut=class{static isRect(t){return!!t&&[t.x,t.y,t.width,t.height].every(Kr)}static assertIsValidBox(t,n,r=!1){if(!ut.isRect(t))throw new Error(`${n} - invalid box: ${JSON.stringify(t)}, expected object with properties x, y, width, height`);if(!r&&(t.width<0||t.height<0))throw new Error(`${n} - width (${t.width}) and height (${t.height}) must be positive numbers`)}constructor(t,n=!0){let r=t||{},s=[r.left,r.top,r.right,r.bottom].every(Kr),a=[r.x,r.y,r.width,r.height].every(Kr);if(!a&&!s)throw new Error(`Box.constructor - expected box to be IBoundingBox | IRect, instead have ${JSON.stringify(r)}`);let[o,i,c,l]=a?[r.x,r.y,r.width,r.height]:[r.left,r.top,r.right-r.left,r.bottom-r.top];ut.assertIsValidBox({x:o,y:i,width:c,height:l},"Box.constructor",n),this._x=o,this._y=i,this._width=c,this._height=l}get x(){return this._x}get y(){return this._y}get width(){return this._width}get height(){return this._height}get left(){return this.x}get top(){return this.y}get right(){return this.x+this.width}get bottom(){return this.y+this.height}get area(){return this.width*this.height}get topLeft(){return new Pe(this.left,this.top)}get topRight(){return new Pe(this.right,this.top)}get bottomLeft(){return new Pe(this.left,this.bottom)}get bottomRight(){return new Pe(this.right,this.bottom)}round(){let[t,n,r,s]=[this.x,this.y,this.width,this.height].map(a=>Math.round(a));return new ut({x:t,y:n,width:r,height:s})}floor(){let[t,n,r,s]=[this.x,this.y,this.width,this.height].map(a=>Math.floor(a));return new ut({x:t,y:n,width:r,height:s})}toSquare(){let{x:t,y:n,width:r,height:s}=this,a=Math.abs(r-s);return rn&&(i=-d+n+r,d=n),p>t&&(c=-p+t+s,p=t),l<1&&(c=2-l,l=1),u<1&&(c=2-u,u=1),{dy:o,edy:c,dx:a,edx:i,y:u,ey:p,x:l,ex:d,w:r,h:s}}calibrate(t){return new ut({left:this.left+t.left*this.width,top:this.top+t.top*this.height,right:this.right+t.right*this.width,bottom:this.bottom+t.bottom*this.height}).toSquare().round()}};var Wu=class extends ut{constructor(t,n,r,s,a=!1){super({left:t,top:n,right:r,bottom:s},a)}};var Na=class{constructor(t,n,r,s,a){this._imageDims=new Nn(a.width,a.height),this._score=t,this._classScore=n,this._className=r,this._box=new ut(s).rescale(this._imageDims)}get score(){return this._score}get classScore(){return this._classScore}get className(){return this._className}get box(){return this._box}get imageDims(){return this._imageDims}get imageWidth(){return this.imageDims.width}get imageHeight(){return this.imageDims.height}get relativeBox(){return new ut(this._box).rescale(this.imageDims.reverse())}forSize(t,n){return new Na(this.score,this.classScore,this.className,this.relativeBox,{width:t,height:n})}};var xt=class extends Na{constructor(t,n,r){super(t,t,"",n,r)}forSize(t,n){let{score:r,relativeBox:s,imageDims:a}=super.forSize(t,n);return new xt(r,s,a)}};function y1(e,t,n=!0){let r=Math.max(0,Math.min(e.right,t.right)-Math.max(e.left,t.left)),s=Math.max(0,Math.min(e.bottom,t.bottom)-Math.max(e.top,t.top)),a=r*s;return n?a/(e.area+t.area-a):a/Math.min(e.area,t.area)}function v1(e){let t=e.map(i=>i.x),n=e.map(i=>i.y),r=t.reduce((i,c)=>ccii({score:o,boxIndex:i})).sort((o,i)=>o.score-i.score).map(o=>o.boxIndex),a=[];for(;s.length>0;){let o=s.pop();a.push(o);let i=s,c=[];for(let l=0;lc[u]<=n)}return a}function Xr(e,t){return M(()=>{let[n,r,s]=t,a=xn([...e.shape.slice(0,3),1],n,"float32"),o=xn([...e.shape.slice(0,3),1],r,"float32"),i=xn([...e.shape.slice(0,3),1],s,"float32"),c=et([a,o,i],3);return fe(e,c)})}function w1(e,t=!1){return M(()=>{let[n,r]=e.shape.slice(1);if(n===r)return e;let s=Math.abs(n-r),a=Math.round(s*(t?.5:1)),o=n>r?2:1,i=p=>{let h=e.shape.slice();return h[o]=p,xn(h,0,"float32")},c=i(a),l=s-c.shape[o],d=[t&&l?i(l):null,e,c].filter(p=>!!p).map(p=>ce(p,"float32"));return et(d,o)})}function Lce(e){let t=e.slice();for(let n=t.length-1;n>0;n--){let r=Math.floor(Math.random()*(n+1)),s=t[n];t[n]=t[r],t[r]=s}return t}function tp(e){return 1/(1+Math.exp(-e))}function Bce(e){return Math.log(e/(1-e))}var Vu=class extends ut{constructor(t,n,r,s,a=!1){super({x:t,y:n,width:r,height:s},a)}};var zce=.5,Wce=.43,Vce=.45,yr=class{constructor(t,n,r=new Pe(0,0)){let{width:s,height:a}=n;this._imgDims=new Nn(s,a),this._shift=r,this._positions=t.map(o=>o.mul(new Pe(s,a)).add(r))}get shift(){return new Pe(this._shift.x,this._shift.y)}get imageWidth(){return this._imgDims.width}get imageHeight(){return this._imgDims.height}get positions(){return this._positions}get relativePositions(){return this._positions.map(t=>t.sub(this._shift).div(new Pe(this.imageWidth,this.imageHeight)))}forSize(t,n){return new this.constructor(this.relativePositions,{width:t,height:n})}shiftBy(t,n){return new this.constructor(this.relativePositions,this._imgDims,new Pe(t,n))}shiftByPoint(t){return this.shiftBy(t.x,t.y)}align(t,n={}){if(t){let a=t instanceof xt?t.box.floor():new ut(t);return this.shiftBy(a.x,a.y).align(null,n)}let{useDlibAlignment:r,minBoxPadding:s}={useDlibAlignment:!1,minBoxPadding:.2,...n};return r?this.alignDlib():this.alignMinBbox(s)}alignDlib(){let t=this.getRefPointsForAlignment(),[n,r,s]=t,a=d=>s.sub(d).magnitude(),o=(a(n)+a(r))/2,i=Math.floor(o/Vce),c=Ii(t),l=Math.floor(Math.max(0,c.x-zce*i)),u=Math.floor(Math.max(0,c.y-Wce*i));return new Vu(l,u,Math.min(i,this.imageWidth+l),Math.min(i,this.imageHeight+u))}alignMinBbox(t){let n=v1(this.positions);return n.pad(n.width*t,n.height*t)}getRefPointsForAlignment(){throw new Error("getRefPointsForAlignment not implemented by base class")}};var AE=class extends yr{getRefPointsForAlignment(){let t=this.positions;return[t[0],t[1],Ii([t[3],t[4]])]}};var Uu=class extends yr{getJawOutline(){return this.positions.slice(0,17)}getLeftEyeBrow(){return this.positions.slice(17,22)}getRightEyeBrow(){return this.positions.slice(22,27)}getNose(){return this.positions.slice(27,36)}getLeftEye(){return this.positions.slice(36,42)}getRightEye(){return this.positions.slice(42,48)}getMouth(){return this.positions.slice(48,68)}getRefPointsForAlignment(){return[this.getLeftEye(),this.getRightEye(),this.getMouth()].map(Ii)}};var np=class{constructor(t,n){this._label=t,this._distance=n}get label(){return this._label}get distance(){return this._distance}toString(t=!0){return`${this.label}${t?` (${ki(this.distance)})`:""}`}};var rp=class extends ut{static assertIsValidLabeledBox(t,n){if(ut.assertIsValidBox(t,n),!Kr(t.label))throw new Error(`${n} - expected property label (${t.label}) to be a number`)}constructor(t,n){super(t);this._label=n}get label(){return this._label}};var Rs=class{constructor(t,n){if(typeof t!="string")throw new Error("LabeledFaceDescriptors - constructor expected label to be a string");if(!Array.isArray(n)||n.some(r=>!(r instanceof Float32Array)))throw new Error("LabeledFaceDescriptors - constructor expected descriptors to be an array of Float32Array");this._label=t,this._descriptors=n}get label(){return this._label}get descriptors(){return this._descriptors}toJSON(){return{label:this.label,descriptors:this.descriptors.map(t=>Array.from(t))}}static fromJSON(t){let n=t.descriptors.map(r=>new Float32Array(r));return new Rs(t.label,n)}};var DE=class extends rp{static assertIsValidPredictedBox(t,n){if(rp.assertIsValidLabeledBox(t,n),!zu(t.score)||!zu(t.classScore))throw new Error(`${n} - expected properties score (${t.score}) and (${t.classScore}) to be a number between [0, 1]`)}constructor(t,n,r,s){super(t,n);this._score=r,this._classScore=s}get score(){return this._score}get classScore(){return this._classScore}};function hs(e){return e.detection instanceof xt}function Si(e,t){return{...e,...{detection:t}}}function k1(){let e=window.fetch;if(!e)throw new Error("fetch - missing fetch implementation for browser environment");return{Canvas:HTMLCanvasElement,CanvasRenderingContext2D,Image:HTMLImageElement,ImageData,Video:HTMLVideoElement,createCanvasElement:()=>document.createElement("canvas"),createImageElement:()=>document.createElement("img"),createVideoElement:()=>document.createElement("video"),fetch:e,readFile:()=>{throw new Error("readFile - filesystem not available for browser environment")}}}function sp(){return typeof global=="object"&&typeof process!="undefined"&&process.versions!=null&&process.versions.node!=null}function Bm(e){let t="";if(!e&&sp())try{e=pD("fs")}catch(r){t=r.toString()}return{readFile:e?r=>new Promise((s,a)=>{e.readFile(r,(o,i)=>o?a(o):s(i))}):()=>{throw new Error(`readFile - failed to require fs in nodejs environment with error: ${t}`)}}}function I1(){let e=global.Canvas||global.HTMLCanvasElement,t=global.Image||global.HTMLImageElement,n=global.Video||global.HTMLVideoElement,r=()=>{if(e)return new e;throw new Error("createCanvasElement - missing Canvas implementation for nodejs environment")},s=()=>{if(t)return new t;throw new Error("createImageElement - missing Image implementation for nodejs environment")},a=()=>{if(n)return new n;throw new Error("createVideoElement - missing Video implementation for nodejs environment")},o=global.fetch,i=Bm();return{Canvas:e||class{},CanvasRenderingContext2D:global.CanvasRenderingContext2D||class{},Image:t||class{},ImageData:global.ImageData||class{},Video:global.HTMLVideoElement||class{},createCanvasElement:r,createImageElement:s,createVideoElement:a,fetch:o,...i}}function S1(){return typeof window=="object"&&typeof document!="undefined"&&typeof HTMLImageElement!="undefined"&&typeof HTMLCanvasElement!="undefined"&&typeof HTMLVideoElement!="undefined"&&typeof ImageData!="undefined"&&typeof CanvasRenderingContext2D!="undefined"}var nn;function Uce(){if(!nn)throw new Error("getEnv - environment is not defined, check isNodejs() and isBrowser()");return nn}function T1(e){nn=e}function C1(){return S1()?T1(k1()):sp()?T1(I1()):null}function Gce(e){if(nn||C1(),!nn)throw new Error("monkeyPatch - environment is not defined, check isNodejs() and isBrowser()");let{Canvas:t=nn.Canvas,Image:n=nn.Image}=e;nn.Canvas=t,nn.Image=n,nn.createCanvasElement=e.createCanvasElement||(()=>new t),nn.createImageElement=e.createImageElement||(()=>new n),nn.ImageData=e.ImageData||nn.ImageData,nn.Video=e.Video||nn.Video,nn.fetch=e.fetch||nn.fetch,nn.readFile=e.readFile||nn.readFile}var tt={getEnv:Uce,setEnv:T1,initialize:C1,createBrowserEnv:k1,createFileSystem:Bm,createNodejsEnv:I1,monkeyPatch:Gce,isBrowser:S1,isNodejs:sp};C1();function Ti(e){return!tt.isNodejs()&&typeof e=="string"?document.getElementById(e):e}function Un(e){let{Canvas:t,CanvasRenderingContext2D:n}=tt.getEnv();if(e instanceof n)return e;let r=Ti(e);if(!(r instanceof t))throw new Error("resolveContext2d - expected canvas to be of instance of Canvas");let s=r.getContext("2d");if(!s)throw new Error("resolveContext2d - canvas 2d context is null");return s}var fs;(function(s){s.TOP_LEFT="TOP_LEFT",s.TOP_RIGHT="TOP_RIGHT",s.BOTTOM_LEFT="BOTTOM_LEFT",s.BOTTOM_RIGHT="BOTTOM_RIGHT"})(fs||(fs={}));var ap=class{constructor(t={}){let{anchorPosition:n,backgroundColor:r,fontColor:s,fontSize:a,fontStyle:o,padding:i}=t;this.anchorPosition=n||fs.TOP_LEFT,this.backgroundColor=r||"rgba(0, 0, 0, 0.5)",this.fontColor=s||"rgba(255, 255, 255, 1)",this.fontSize=a||14,this.fontStyle=o||"Georgia",this.padding=i||4}},_a=class{constructor(t,n,r={}){this.text=typeof t=="string"?[t]:t instanceof _a?t.text:t,this.anchor=n,this.options=new ap(r)}measureWidth(t){let{padding:n}=this.options;return this.text.map(r=>t.measureText(r).width).reduce((r,s)=>r{let f=c+d.x,m=c+d.y+(h+1)*o;r.fillText(p,f,m)})}};var N1=class{constructor(t={}){let{boxColor:n,lineWidth:r,label:s,drawLabelOptions:a}=t;this.boxColor=n||"rgba(0, 0, 255, 1)",this.lineWidth=r||2,this.label=s;let o={anchorPosition:fs.BOTTOM_LEFT,backgroundColor:this.boxColor};this.drawLabelOptions=new ap({...o,...a})}},zm=class{constructor(t,n={}){this.box=new ut(t),this.options=new N1(n)}draw(t){let n=Un(t),{boxColor:r,lineWidth:s}=this.options,{x:a,y:o,width:i,height:c}=this.box;n.strokeStyle=r,n.lineWidth=s,n.strokeRect(a,o,i,c);let{label:l}=this.options;l&&new _a([l],{x:a-s/2,y:o},this.options.drawLabelOptions).draw(t)}};function Hce(e,t){(Array.isArray(t)?t:[t]).forEach(r=>{let s=r instanceof xt?r.score:hs(r)?r.detection.score:void 0,a=r instanceof xt?r.box:hs(r)?r.detection.box:new ut(r),o=s?`${ki(s)}`:void 0;new zm(a,{label:o}).draw(e)})}function op(e){let{Image:t,Video:n}=tt.getEnv();return e instanceof t&&e.complete||e instanceof n&&e.readyState>=3}function _1(e){return new Promise((t,n)=>{(e instanceof tt.getEnv().Canvas||op(e))&&t(null);function r(a){!a.currentTarget||(a.currentTarget.removeEventListener("load",s),a.currentTarget.removeEventListener("error",r),n(a))}function s(a){!a.currentTarget||(a.currentTarget.removeEventListener("load",s),a.currentTarget.removeEventListener("error",r),t(a))}e.addEventListener("load",s),e.addEventListener("error",r)})}function E1(e){return new Promise((t,n)=>{e instanceof Blob||n(new Error("bufferToImage - expected buf to be of type: Blob"));let r=new FileReader;r.onload=()=>{typeof r.result!="string"&&n(new Error("bufferToImage - expected reader.result to be a string, in onload"));let s=tt.getEnv().createImageElement();s.onload=()=>t(s),s.onerror=n,s.src=r.result},r.onerror=n,r.readAsDataURL(e)})}function Ci(e){let{Image:t,Video:n}=tt.getEnv();return e instanceof t?new Nn(e.naturalWidth,e.naturalHeight):e instanceof n?new Nn(e.videoWidth,e.videoHeight):new Nn(e.width,e.height)}function Ni({width:e,height:t}){let{createCanvasElement:n}=tt.getEnv(),r=n();return r.width=e,r.height=t,r}function ip(e,t){let{ImageData:n}=tt.getEnv();if(!(e instanceof n)&&!op(e))throw new Error("createCanvasFromMedia - media has not finished loading yet");let{width:r,height:s}=t||Ci(e),a=Ni({width:r,height:s});return e instanceof n?Un(a).putImageData(e,0,0):Un(a).drawImage(e,0,0,r,s),a}async function A1(e,t){let n=t||tt.getEnv().createCanvasElement(),[r,s,a]=e.shape.slice(br(e)?1:0),o=M(()=>e.as3D(r,s,a).toInt());return await Go.toPixels(o,n),o.dispose(),n}function Wm(e){let{Image:t,Canvas:n,Video:r}=tt.getEnv();return e instanceof t||e instanceof n||e instanceof r}function D1(e,t,n=!1){let{Image:r,Canvas:s}=tt.getEnv();if(!(e instanceof r||e instanceof s))throw new Error("imageToSquare - expected arg0 to be HTMLImageElement | HTMLCanvasElement");if(t<=0)return Ni({width:1,height:1});let a=Ci(e),o=t/Math.max(a.height,a.width),i=o*a.width,c=o*a.height,l=Ni({width:t,height:t}),u=e instanceof s?e:ip(e),d=Math.abs(i-c)/2,p=n&&i0&&u.height>0&&Un(l).drawImage(u,p,h,i,c),l}var Ps=class{constructor(t,n=!1){this._imageTensors=[];this._canvases=[];this._treatAsBatchInput=!1;this._inputDimensions=[];this._inputSize=0;if(!Array.isArray(t))throw new Error(`NetInput.constructor - expected inputs to be an Array of TResolvedNetInput or to be instanceof tf.Tensor4D, instead have ${t}`);this._treatAsBatchInput=n,this._batchSize=t.length,t.forEach((r,s)=>{if($s(r)){this._imageTensors[s]=r,this._inputDimensions[s]=r.shape;return}if(br(r)){let o=r.shape[0];if(o!==1)throw new Error(`NetInput - tf.Tensor4D with batchSize ${o} passed, but not supported in input array`);this._imageTensors[s]=r,this._inputDimensions[s]=r.shape.slice(1);return}let a=r instanceof tt.getEnv().Canvas?r:ip(r);this._canvases[s]=a,this._inputDimensions[s]=[a.height,a.width,3]})}get imageTensors(){return this._imageTensors}get canvases(){return this._canvases}get isBatchInput(){return this.batchSize>1||this._treatAsBatchInput}get batchSize(){return this._batchSize}get inputDimensions(){return this._inputDimensions}get inputSize(){return this._inputSize}get reshapedInputDimensions(){return ps(this.batchSize,0,1).map((t,n)=>this.getReshapedInputDimensions(n))}getInput(t){return this.canvases[t]||this.imageTensors[t]}getInputDimensions(t){return this._inputDimensions[t]}getInputHeight(t){return this._inputDimensions[t][0]}getInputWidth(t){return this._inputDimensions[t][1]}getReshapedInputDimensions(t){if(typeof this.inputSize!="number")throw new Error("getReshapedInputDimensions - inputSize not set, toBatchTensor has not been called yet");let n=this.getInputWidth(t),r=this.getInputHeight(t);return g1({width:n,height:r},this.inputSize)}toBatchTensor(t,n=!0){return this._inputSize=t,M(()=>{let r=ps(this.batchSize,0,1).map(a=>{let o=this.getInput(a);if(o instanceof Ee){let i=br(o)?o:mn(o);return i=w1(i,n),(i.shape[1]!==t||i.shape[2]!==t)&&(i=er.resizeBilinear(i,[t,t],!1,!1)),i.as3D(t,t,3)}if(o instanceof tt.getEnv().Canvas)return Go.fromPixels(D1(o,t,n));throw new Error(`toBatchTensor - at batchIdx ${a}, expected input to be instanceof tf.Tensor or instanceof HTMLCanvasElement, instead have ${o}`)});return Ot(r.map(a=>ce(a,"float32"))).as4D(this.batchSize,t,t,3)})}};async function bt(e){if(e instanceof Ps)return e;let t=Array.isArray(e)?e:[e];if(!t.length)throw new Error("toNetInput - empty array passed as input");let n=s=>Array.isArray(e)?` at input index ${s}:`:"",r=t.map(Ti);return r.forEach((s,a)=>{if(!Wm(s)&&!$s(s)&&!br(s))throw typeof t[a]=="string"?new Error(`toNetInput -${n(a)} string passed, but could not resolve HTMLElement for element id ${t[a]}`):new Error(`toNetInput -${n(a)} expected media to be of type HTMLImageElement | HTMLVideoElement | HTMLCanvasElement | tf.Tensor3D, or to be an element id`);if(br(s)){let o=s.shape[0];if(o!==1)throw new Error(`toNetInput -${n(a)} tf.Tensor4D with batchSize ${o} passed, but not supported in input array`)}}),await Promise.all(r.map(s=>Wm(s)&&_1(s))),new Ps(r,Array.isArray(e))}async function Gu(e,t){let{Canvas:n}=tt.getEnv(),r=e;if(!(e instanceof n)){let o=await bt(e);if(o.batchSize>1)throw new Error("extractFaces - batchSize > 1 not supported");let i=o.getInput(0);r=i instanceof n?i:await A1(i)}let s=Un(r);return t.map(o=>o instanceof xt?o.forSize(r.width,r.height).box.floor():o).map(o=>o.clipAtImageBorders(r.width,r.height)).map(({x:o,y:i,width:c,height:l})=>{let u=Ni({width:c,height:l});return c>0&&l>0&&Un(u).putImageData(s.getImageData(o,i,c,l),0,0),u})}async function Hu(e,t){if(!$s(e)&&!br(e))throw new Error("extractFaceTensors - expected image tensor to be 3D or 4D");if(br(e)&&e.shape[0]>1)throw new Error("extractFaceTensors - batchSize > 1 not supported");return M(()=>{let[n,r,s]=e.shape.slice(br(e)?1:0);return t.map(i=>i instanceof xt?i.forSize(r,n).box:i).map(i=>i.clipAtImageBorders(r,n)).map(({x:i,y:c,width:l,height:u})=>pu(e.as3D(n,r,s),[c,i,0],[u,l,s]))})}async function Os(e,t){let{fetch:n}=tt.getEnv(),r=await n(e,t);if(!(r.status<400))throw new Error(`failed to fetch: (${r.status}) ${r.statusText}, from url: ${r.url}`);return r}async function jce(e){let t=await Os(e),n=await t.blob();if(!n.type.startsWith("image/"))throw new Error(`fetchImage - expected blob type to be of type image/*, instead have: ${n.type}, for url: ${t.url}`);return E1(n)}async function F1(e){return(await Os(e)).json()}async function qce(e){return new Float32Array(await(await Os(e)).arrayBuffer())}function FE(e){return new Promise((t,n)=>{e instanceof Blob||n(new Error("bufferToVideo - expected buf to be of type: Blob"));let r=tt.getEnv().createVideoElement();r.oncanplay=()=>t(r),r.onerror=n,r.playsInline=!0,r.muted=!0,r.src=URL.createObjectURL(e),r.play()})}async function Kce(e){let t=await Os(e),n=await t.blob();if(!n.type.startsWith("video/"))throw new Error(`fetchVideo - expected blob type to be of type video/*, instead have: ${n.type}, for url: ${t.url}`);return FE(n)}function Vm(e,t){let n=`${t}-weights_manifest.json`;if(!e)return{modelBaseUri:"",manifestUri:n};if(e==="/")return{modelBaseUri:"/",manifestUri:`/${n}`};let r=e.startsWith("http://")?"http://":e.startsWith("https://")?"https://":"";e=e.replace(r,"");let s=e.split("/").filter(i=>i),a=e.endsWith(".json")?s[s.length-1]:n,o=r+(e.endsWith(".json")?s.slice(0,s.length-1):s).join("/");return o=e.startsWith("/")?`/${o}`:o,{modelBaseUri:o,manifestUri:o==="/"?`/${a}`:`${o}/${a}`}}async function $1(e,t){let{manifestUri:n,modelBaseUri:r}=Vm(e,t),s=await F1(n);return Yt.loadWeights(s,r)}function Xce(e,t,n=!1){let{width:r,height:s}=n?Ci(t):t;return e.width=r,e.height=s,{width:r,height:s}}var ln=class{constructor(t){this._params=void 0;this._paramMappings=[];this._name=t}get params(){return this._params}get paramMappings(){return this._paramMappings}get isLoaded(){return!!this.params}getParamFromPath(t){let{obj:n,objProp:r}=this.traversePropertyPath(t);return n[r]}reassignParamFromPath(t,n){let{obj:r,objProp:s}=this.traversePropertyPath(t);r[s].dispose(),r[s]=n}getParamList(){return this._paramMappings.map(({paramPath:t})=>({path:t,tensor:this.getParamFromPath(t)}))}getTrainableParams(){return this.getParamList().filter(t=>t.tensor instanceof ra)}getFrozenParams(){return this.getParamList().filter(t=>!(t.tensor instanceof ra))}variable(){this.getFrozenParams().forEach(({path:t,tensor:n})=>{this.reassignParamFromPath(t,n.variable())})}freeze(){this.getTrainableParams().forEach(({path:t,tensor:n})=>{let r=Kn(n.dataSync());n.dispose(),this.reassignParamFromPath(t,r)})}dispose(t=!0){this.getParamList().forEach(n=>{if(t&&n.tensor.isDisposed)throw new Error(`param tensor has already been disposed for path ${n.path}`);n.tensor.dispose()}),this._params=void 0}serializeParams(){return new Float32Array(this.getParamList().map(({tensor:t})=>Array.from(t.dataSync())).reduce((t,n)=>t.concat(n)))}async load(t){if(t instanceof Float32Array){this.extractWeights(t);return}await this.loadFromUri(t)}async loadFromUri(t){if(t&&typeof t!="string")throw new Error(`${this._name}.loadFromUri - expected model uri`);let n=await $1(t,this.getDefaultModelName());this.loadFromWeightMap(n)}async loadFromDisk(t){if(t&&typeof t!="string")throw new Error(`${this._name}.loadFromDisk - expected model file path`);let{readFile:n}=tt.getEnv(),{manifestUri:r,modelBaseUri:s}=Vm(t,this.getDefaultModelName()),a=l=>Promise.all(l.map(u=>n(u).then(d=>d.buffer))),o=Yt.weightsLoaderFactory(a),i=JSON.parse((await n(r)).toString()),c=await o(i,s);this.loadFromWeightMap(c)}loadFromWeightMap(t){let{paramMappings:n,params:r}=this.extractParamsFromWeightMap(t);this._paramMappings=n,this._params=r}extractWeights(t){let{paramMappings:n,params:r}=this.extractParams(t);this._paramMappings=n,this._params=r}traversePropertyPath(t){if(!this.params)throw new Error("traversePropertyPath - model has no loaded params");let n=t.split("/").reduce((a,o)=>{if(!a.nextObj.hasOwnProperty(o))throw new Error(`traversePropertyPath - object does not have property ${o}, for path ${t}`);return{obj:a.nextObj,objProp:o,nextObj:a.nextObj[o]}},{nextObj:this.params}),{obj:r,objProp:s}=n;if(!r||!s||!(r[s]instanceof Ee))throw new Error(`traversePropertyPath - parameter is not a tensor, for path ${t}`);return{obj:r,objProp:s}}};function Gn(e,t,n){return M(()=>{let r=ei(e,t.depthwise_filter,t.pointwise_filter,n,"same");return r=Y(r,t.bias),r})}function Um(e,t,n=!1){return M(()=>{let r=qe(n?Y(Rt(e,t.conv0.filters,[2,2],"same"),t.conv0.bias):Gn(e,t.conv0,[2,2])),s=Gn(r,t.conv1,[1,1]),a=qe(Y(r,s)),o=Gn(a,t.conv2,[1,1]);return qe(Y(r,Y(s,o)))})}function cp(e,t,n=!1,r=!0){return M(()=>{let s=qe(n?Y(Rt(e,t.conv0.filters,r?[2,2]:[1,1],"same"),t.conv0.bias):Gn(e,t.conv0,r?[2,2]:[1,1])),a=Gn(s,t.conv1,[1,1]),o=qe(Y(s,a)),i=Gn(o,t.conv2,[1,1]),c=qe(Y(s,Y(a,i))),l=Gn(c,t.conv3,[1,1]);return qe(Y(s,Y(a,Y(i,l))))})}function _i(e,t,n="same",r=!1){return M(()=>{let s=Y(Rt(e,t.filters,[1,1],n),t.bias);return r?qe(s):s})}function _n(e,t){Object.keys(e).forEach(n=>{t.some(r=>r.originalPath===n)||e[n].dispose()})}function ju(e,t){return(n,r,s,a)=>{let o=Br(e(n*r*s*s),[s,s,n,r]),i=He(e(r));return t.push({paramPath:`${a}/filters`},{paramPath:`${a}/bias`}),{filters:o,bias:i}}}function Gm(e,t){return(n,r,s)=>{let a=Lr(e(n*r),[n,r]),o=He(e(r));return t.push({paramPath:`${s}/weights`},{paramPath:`${s}/bias`}),{weights:a,bias:o}}}var Hm=class{constructor(t,n,r){this.depthwise_filter=t;this.pointwise_filter=n;this.bias=r}};function qu(e,t){return(n,r,s)=>{let a=Br(e(3*3*n),[3,3,n,1]),o=Br(e(n*r),[1,1,n,r]),i=He(e(r));return t.push({paramPath:`${s}/depthwise_filter`},{paramPath:`${s}/pointwise_filter`},{paramPath:`${s}/bias`}),new Hm(a,o,i)}}function Ku(e){return t=>{let n=e(`${t}/depthwise_filter`,4),r=e(`${t}/pointwise_filter`,4),s=e(`${t}/bias`,1);return new Hm(n,r,s)}}function ar(e,t){return(n,r,s)=>{let a=e[n];if(!wi(a,r))throw new Error(`expected weightMap[${n}] to be a Tensor${r}D, instead have ${a}`);return t.push({originalPath:n,paramPath:s||n}),a}}function En(e){let t=e;function n(s){let a=t.slice(0,s);return t=t.slice(s),a}function r(){return t}return{extractWeights:n,getRemainingWeights:r}}function jm(e,t){let n=ju(e,t),r=qu(e,t);function s(o,i,c,l=!1){let u=l?n(o,i,3,`${c}/conv0`):r(o,i,`${c}/conv0`),d=r(i,i,`${c}/conv1`),p=r(i,i,`${c}/conv2`);return{conv0:u,conv1:d,conv2:p}}function a(o,i,c,l=!1){let{conv0:u,conv1:d,conv2:p}=s(o,i,c,l),h=r(i,i,`${c}/conv3`);return{conv0:u,conv1:d,conv2:p,conv3:h}}return{extractDenseBlock3Params:s,extractDenseBlock4Params:a}}function $E(e){let t=[],{extractWeights:n,getRemainingWeights:r}=En(e),{extractDenseBlock4Params:s}=jm(n,t),a=s(3,32,"dense0",!0),o=s(32,64,"dense1"),i=s(64,128,"dense2"),c=s(128,256,"dense3");if(r().length!==0)throw new Error(`weights remaing after extract: ${r().length}`);return{paramMappings:t,params:{dense0:a,dense1:o,dense2:i,dense3:c}}}function qm(e){return t=>{let n=e(`${t}/filters`,4),r=e(`${t}/bias`,1);return{filters:n,bias:r}}}function Km(e,t){let n=ar(e,t),r=qm(n),s=Ku(n);function a(i,c=!1){let l=c?r(`${i}/conv0`):s(`${i}/conv0`),u=s(`${i}/conv1`),d=s(`${i}/conv2`);return{conv0:l,conv1:u,conv2:d}}function o(i,c=!1){let l=c?r(`${i}/conv0`):s(`${i}/conv0`),u=s(`${i}/conv1`),d=s(`${i}/conv2`),p=s(`${i}/conv3`);return{conv0:l,conv1:u,conv2:d,conv3:p}}return{extractDenseBlock3Params:a,extractDenseBlock4Params:o}}function RE(e){let t=[],{extractDenseBlock4Params:n}=Km(e,t),r={dense0:n("dense0",!0),dense1:n("dense1"),dense2:n("dense2"),dense3:n("dense3")};return _n(e,t),{params:r,paramMappings:t}}var up=class extends ln{constructor(){super("FaceFeatureExtractor")}forwardInput(t){let{params:n}=this;if(!n)throw new Error("FaceFeatureExtractor - load model before inference");return M(()=>{let r=ce(t.toBatchTensor(112,!0),"float32"),a=Xr(r,[122.782,117.001,104.298]).div(255),o=cp(a,n.dense0,!0);return o=cp(o,n.dense1),o=cp(o,n.dense2),o=cp(o,n.dense3),o=lr(o,[7,7],[2,2],"valid"),o})}async forward(t){return this.forwardInput(await bt(t))}getDefaultModelName(){return"face_feature_extractor_model"}extractParamsFromWeightMap(t){return RE(t)}extractParams(t){return $E(t)}};function lp(e,t){return M(()=>Y(De(e,t.weights),t.bias))}function PE(e,t,n){let r=[],{extractWeights:s,getRemainingWeights:a}=En(e),i=Gm(s,r)(t,n,"fc");if(a().length!==0)throw new Error(`weights remaing after extract: ${a().length}`);return{paramMappings:r,params:{fc:i}}}function OE(e){let t=[],n=ar(e,t);function r(a){let o=n(`${a}/weights`,2),i=n(`${a}/bias`,1);return{weights:o,bias:i}}let s={fc:r("fc")};return _n(e,t),{params:s,paramMappings:t}}function Xm(e){let t={},n={};return Object.keys(e).forEach(r=>{let s=r.startsWith("fc")?n:t;s[r]=e[r]}),{featureExtractorMap:t,classifierMap:n}}var dp=class extends ln{constructor(t,n){super(t);this._faceFeatureExtractor=n}get faceFeatureExtractor(){return this._faceFeatureExtractor}runNet(t){let{params:n}=this;if(!n)throw new Error(`${this._name} - load model before inference`);return M(()=>{let r=t instanceof Ps?this.faceFeatureExtractor.forwardInput(t):t;return lp(r.as2D(r.shape[0],-1),n.fc)})}dispose(t=!0){this.faceFeatureExtractor.dispose(t),super.dispose(t)}loadClassifierParams(t){let{params:n,paramMappings:r}=this.extractClassifierParams(t);this._params=n,this._paramMappings=r}extractClassifierParams(t){return PE(t,this.getClassifierChannelsIn(),this.getClassifierChannelsOut())}extractParamsFromWeightMap(t){let{featureExtractorMap:n,classifierMap:r}=Xm(t);return this.faceFeatureExtractor.loadFromWeightMap(n),OE(r)}extractParams(t){let n=this.getClassifierChannelsIn(),r=this.getClassifierChannelsOut(),s=r*n+r,a=t.slice(0,t.length-s),o=t.slice(t.length-s);return this.faceFeatureExtractor.extractWeights(a),this.extractClassifierParams(o)}};var R1=["neutral","happy","sad","angry","fearful","disgusted","surprised"],Ea=class{constructor(t){this.neutral=0;this.happy=0;this.sad=0;this.angry=0;this.fearful=0;this.disgusted=0;this.surprised=0;if(t.length!==7)throw new Error(`FaceExpressions.constructor - expected probabilities.length to be 7, have: ${t.length}`);R1.forEach((n,r)=>{this[n]=t[r]})}asSortedArray(){return R1.map(t=>({expression:t,probability:this[t]})).sort((t,n)=>n.probability-t.probability)}};var Ym=class extends dp{constructor(t=new up){super("FaceExpressionNet",t)}forwardInput(t){return M(()=>Mr(this.runNet(t)))}async forward(t){return this.forwardInput(await bt(t))}async predictExpressions(t){let n=await bt(t),r=await this.forwardInput(n),s=await Promise.all(ht(r).map(async o=>{let i=o.dataSync();return o.dispose(),i}));r.dispose();let a=s.map(o=>new Ea(o));return n.isBatchInput?a:a[0]}getDefaultModelName(){return"face_expression_model"}getClassifierChannelsIn(){return 256}getClassifierChannelsOut(){return 7}};function P1(e){return e.expressions instanceof Ea}function Zm(e,t){return{...e,...{expressions:t}}}function Yce(e,t,n=.1,r){(Array.isArray(t)?t:[t]).forEach(a=>{let o=a instanceof Ea?a:P1(a)?a.expressions:void 0;if(!o)throw new Error("drawFaceExpressions - expected faceExpressions to be FaceExpressions | WithFaceExpressions<{}> or array thereof");let c=o.asSortedArray().filter(d=>d.probability>n),l=hs(a)?a.detection.box.bottomLeft:r||new Pe(0,0);new _a(c.map(d=>`${d.expression} (${ki(d.probability)})`),l).draw(e)})}function Ei(e){return hs(e)&&e.landmarks instanceof yr&&e.unshiftedLandmarks instanceof yr&&e.alignedRect instanceof xt}function Zce(e){let t=(i,c,l,u)=>Math.atan2(u-c,l-i)%Math.PI,n=i=>i*180/Math.PI,r={roll:void 0,pitch:void 0,yaw:void 0};if(!e||!e._positions||e._positions.length!==68)return r;let s=e._positions;r.roll=-t(s[36]._x,s[36]._y,s[45]._x,s[45]._y),r.pitch=t(0,Math.abs(s[0]._x-s[30]._x)/s[30]._x,Math.PI,Math.abs(s[16]._x-s[30]._x)/s[30]._x);let a=s.reduce((i,c)=>ii>c._y?i:c._y,-1/0);return r.yaw=Math.PI*(e._imgDims._height/(o-a)/1.4-1),r}function Xu(e,t){let{box:n}=e.detection,r=t.shiftBy(n.x,n.y),s=r.align(),{imageDims:a}=e.detection,o=new xt(e.detection.score,s.rescale(a.reverse()),a),i=Zce(t);return{...e,...{landmarks:r,unshiftedLandmarks:t,alignedRect:o,angle:i}}}var O1=class{constructor(t={}){let{drawLines:n=!0,drawPoints:r=!0,lineWidth:s,lineColor:a,pointSize:o,pointColor:i}=t;this.drawLines=n,this.drawPoints=r,this.lineWidth=s||1,this.pointSize=o||2,this.lineColor=a||"rgba(0, 255, 255, 1)",this.pointColor=i||"rgba(255, 0, 255, 1)"}},M1=class{constructor(t,n={}){this.faceLandmarks=t,this.options=new O1(n)}draw(t){let n=Un(t),{drawLines:r,drawPoints:s,lineWidth:a,lineColor:o,pointSize:i,pointColor:c}=this.options;if(r&&this.faceLandmarks instanceof Uu&&(n.strokeStyle=o,n.lineWidth=a,Fs(n,this.faceLandmarks.getJawOutline()),Fs(n,this.faceLandmarks.getLeftEyeBrow()),Fs(n,this.faceLandmarks.getRightEyeBrow()),Fs(n,this.faceLandmarks.getNose()),Fs(n,this.faceLandmarks.getLeftEye(),!0),Fs(n,this.faceLandmarks.getRightEye(),!0),Fs(n,this.faceLandmarks.getMouth(),!0)),s){n.strokeStyle=c,n.fillStyle=c;let l=u=>{n.beginPath(),n.arc(u.x,u.y,i,0,2*Math.PI),n.fill()};this.faceLandmarks.positions.forEach(l)}}};function Jce(e,t){(Array.isArray(t)?t:[t]).forEach(r=>{let s=r instanceof yr?r:Ei(r)?r.landmarks:void 0;if(!s)throw new Error("drawFaceLandmarks - expected faceExpressions to be FaceLandmarks | WithFaceLandmarks> or array thereof");new M1(s).draw(e)})}var ME="1.6.3";function eue(e,t){let n=ju(e,t),r=qu(e,t);function s(o,i,c){let l=r(o,i,`${c}/separable_conv0`),u=r(i,i,`${c}/separable_conv1`),d=n(o,i,1,`${c}/expansion_conv`);return{separable_conv0:l,separable_conv1:u,expansion_conv:d}}function a(o,i){let c=r(o,o,`${i}/separable_conv0`),l=r(o,o,`${i}/separable_conv1`),u=r(o,o,`${i}/separable_conv2`);return{separable_conv0:c,separable_conv1:l,separable_conv2:u}}return{extractConvParams:n,extractSeparableConvParams:r,extractReductionBlockParams:s,extractMainBlockParams:a}}function LE(e,t){let n=[],{extractWeights:r,getRemainingWeights:s}=En(e),{extractConvParams:a,extractSeparableConvParams:o,extractReductionBlockParams:i,extractMainBlockParams:c}=eue(r,n),l=a(3,32,3,"entry_flow/conv_in"),u=i(32,64,"entry_flow/reduction_block_0"),d=i(64,128,"entry_flow/reduction_block_1"),p={conv_in:l,reduction_block_0:u,reduction_block_1:d},h={};ps(t,0,1).forEach(b=>{h[`main_block_${b}`]=c(128,`middle_flow/main_block_${b}`)});let f=i(128,256,"exit_flow/reduction_block"),m=o(256,512,"exit_flow/separable_conv"),g={reduction_block:f,separable_conv:m};if(s().length!==0)throw new Error(`weights remaing after extract: ${s().length}`);return{paramMappings:n,params:{entry_flow:p,middle_flow:h,exit_flow:g}}}function tue(e,t){let n=ar(e,t),r=qm(n),s=Ku(n);function a(i){let c=s(`${i}/separable_conv0`),l=s(`${i}/separable_conv1`),u=r(`${i}/expansion_conv`);return{separable_conv0:c,separable_conv1:l,expansion_conv:u}}function o(i){let c=s(`${i}/separable_conv0`),l=s(`${i}/separable_conv1`),u=s(`${i}/separable_conv2`);return{separable_conv0:c,separable_conv1:l,separable_conv2:u}}return{extractConvParams:r,extractSeparableConvParams:s,extractReductionBlockParams:a,extractMainBlockParams:o}}function BE(e,t){let n=[],{extractConvParams:r,extractSeparableConvParams:s,extractReductionBlockParams:a,extractMainBlockParams:o}=tue(e,n),i=r("entry_flow/conv_in"),c=a("entry_flow/reduction_block_0"),l=a("entry_flow/reduction_block_1"),u={conv_in:i,reduction_block_0:c,reduction_block_1:l},d={};ps(t,0,1).forEach(m=>{d[`main_block_${m}`]=o(`middle_flow/main_block_${m}`)});let p=a("exit_flow/reduction_block"),h=s("exit_flow/separable_conv"),f={reduction_block:p,separable_conv:h};return _n(e,n),{params:{entry_flow:u,middle_flow:d,exit_flow:f},paramMappings:n}}function zE(e,t,n){return Y(Rt(e,t.filters,n,"same"),t.bias)}function B1(e,t,n=!0){let r=n?qe(e):e;return r=Gn(r,t.separable_conv0,[1,1]),r=Gn(qe(r),t.separable_conv1,[1,1]),r=Pt(r,[3,3],[2,2],"same"),r=Y(r,zE(e,t.expansion_conv,[2,2])),r}function nue(e,t){let n=Gn(qe(e),t.separable_conv0,[1,1]);return n=Gn(qe(n),t.separable_conv1,[1,1]),n=Gn(qe(n),t.separable_conv2,[1,1]),n=Y(n,e),n}var z1=class extends ln{constructor(t){super("TinyXception");this._numMainBlocks=t}forwardInput(t){let{params:n}=this;if(!n)throw new Error("TinyXception - load model before inference");return M(()=>{let r=ce(t.toBatchTensor(112,!0),"float32"),a=Xr(r,[122.782,117.001,104.298]).div(255),o=qe(zE(a,n.entry_flow.conv_in,[2,2]));return o=B1(o,n.entry_flow.reduction_block_0,!1),o=B1(o,n.entry_flow.reduction_block_1),ps(this._numMainBlocks,0,1).forEach(i=>{o=nue(o,n.middle_flow[`main_block_${i}`])}),o=B1(o,n.exit_flow.reduction_block),o=qe(Gn(o,n.exit_flow.separable_conv,[1,1])),o})}async forward(t){return this.forwardInput(await bt(t))}getDefaultModelName(){return"tiny_xception_model"}extractParamsFromWeightMap(t){return BE(t,this._numMainBlocks)}extractParams(t){return LE(t,this._numMainBlocks)}};function WE(e){let t=[],{extractWeights:n,getRemainingWeights:r}=En(e),s=Gm(n,t),a=s(512,1,"fc/age"),o=s(512,2,"fc/gender");if(r().length!==0)throw new Error(`weights remaing after extract: ${r().length}`);return{paramMappings:t,params:{fc:{age:a,gender:o}}}}function VE(e){let t=[],n=ar(e,t);function r(a){let o=n(`${a}/weights`,2),i=n(`${a}/bias`,1);return{weights:o,bias:i}}let s={fc:{age:r("fc/age"),gender:r("fc/gender")}};return _n(e,t),{params:s,paramMappings:t}}var Ms;(function(n){n.FEMALE="female",n.MALE="male"})(Ms||(Ms={}));var Jm=class extends ln{constructor(t=new z1(2)){super("AgeGenderNet");this._faceFeatureExtractor=t}get faceFeatureExtractor(){return this._faceFeatureExtractor}runNet(t){let{params:n}=this;if(!n)throw new Error(`${this._name} - load model before inference`);return M(()=>{let r=t instanceof Ps?this.faceFeatureExtractor.forwardInput(t):t,s=lr(r,[7,7],[2,2],"valid").as2D(r.shape[0],-1),a=lp(s,n.fc.age).as1D(),o=lp(s,n.fc.gender);return{age:a,gender:o}})}forwardInput(t){return M(()=>{let{age:n,gender:r}=this.runNet(t);return{age:n,gender:Mr(r)}})}async forward(t){return this.forwardInput(await bt(t))}async predictAgeAndGender(t){let n=await bt(t),r=await this.forwardInput(n),s=ht(r.age),a=ht(r.gender),o=s.map((c,l)=>({ageTensor:c,genderTensor:a[l]})),i=await Promise.all(o.map(async({ageTensor:c,genderTensor:l})=>{let u=c.dataSync()[0],d=l.dataSync()[0],p=d>.5,h=p?Ms.MALE:Ms.FEMALE,f=p?d:1-d;return c.dispose(),l.dispose(),{age:u,gender:h,genderProbability:f}}));return r.age.dispose(),r.gender.dispose(),n.isBatchInput?i:i[0]}getDefaultModelName(){return"age_gender_model"}dispose(t=!0){this.faceFeatureExtractor.dispose(t),super.dispose(t)}loadClassifierParams(t){let{params:n,paramMappings:r}=this.extractClassifierParams(t);this._params=n,this._paramMappings=r}extractClassifierParams(t){return WE(t)}extractParamsFromWeightMap(t){let{featureExtractorMap:n,classifierMap:r}=Xm(t);return this.faceFeatureExtractor.loadFromWeightMap(n),VE(r)}extractParams(t){let n=512*1+1+(512*2+2),r=t.slice(0,t.length-n),s=t.slice(t.length-n);return this.faceFeatureExtractor.extractWeights(r),this.extractClassifierParams(s)}};var pp=class extends dp{postProcess(t,n,r){let s=r.map(({width:o,height:i})=>{let c=n/Math.max(i,o);return{width:o*c,height:i*c}}),a=s.length;return M(()=>{let o=(d,p)=>Ot([xn([68],d,"float32"),xn([68],p,"float32")],1).as2D(1,136).as1D(),i=(d,p)=>{let{width:h,height:f}=s[d];return p(h,f)?Math.abs(h-f)/2:0},c=d=>i(d,(p,h)=>pi(d,(p,h)=>ho(c(p),l(p))))).div(Ot(Array.from(Array(a),(d,p)=>o(s[p].width,s[p].height))))})}forwardInput(t){return M(()=>{let n=this.runNet(t);return this.postProcess(n,t.inputSize,t.inputDimensions.map(([r,s])=>({height:r,width:s})))})}async forward(t){return this.forwardInput(await bt(t))}async detectLandmarks(t){let n=await bt(t),r=M(()=>ht(this.forwardInput(n))),s=await Promise.all(r.map(async(a,o)=>{let i=Array.from(a.dataSync()),c=i.filter((u,d)=>Mm(d)),l=i.filter((u,d)=>!Mm(d));return new Uu(Array(68).fill(0).map((u,d)=>new Pe(c[d],l[d])),{height:n.getInputHeight(o),width:n.getInputWidth(o)})}));return r.forEach(a=>a.dispose()),n.isBatchInput?s:s[0]}getClassifierChannelsOut(){return 136}};var Yu=class extends pp{constructor(t=new up){super("FaceLandmark68Net",t)}getDefaultModelName(){return"face_landmark_68_model"}getClassifierChannelsIn(){return 256}};function UE(e){let t=[],{extractDenseBlock3Params:n}=Km(e,t),r={dense0:n("dense0",!0),dense1:n("dense1"),dense2:n("dense2")};return _n(e,t),{params:r,paramMappings:t}}function GE(e){let t=[],{extractWeights:n,getRemainingWeights:r}=En(e),{extractDenseBlock3Params:s}=jm(n,t),a=s(3,32,"dense0",!0),o=s(32,64,"dense1"),i=s(64,128,"dense2");if(r().length!==0)throw new Error(`weights remaing after extract: ${r().length}`);return{paramMappings:t,params:{dense0:a,dense1:o,dense2:i}}}var W1=class extends ln{constructor(){super("TinyFaceFeatureExtractor")}forwardInput(t){let{params:n}=this;if(!n)throw new Error("TinyFaceFeatureExtractor - load model before inference");return M(()=>{let r=ce(t.toBatchTensor(112,!0),"float32"),a=Xr(r,[122.782,117.001,104.298]).div(255),o=Um(a,n.dense0,!0);return o=Um(o,n.dense1),o=Um(o,n.dense2),o=lr(o,[14,14],[2,2],"valid"),o})}async forward(t){return this.forwardInput(await bt(t))}getDefaultModelName(){return"face_feature_extractor_tiny_model"}extractParamsFromWeightMap(t){return UE(t)}extractParams(t){return GE(t)}};var Qm=class extends pp{constructor(t=new W1){super("FaceLandmark68TinyNet",t)}getDefaultModelName(){return"face_landmark_68_tiny_model"}getClassifierChannelsIn(){return 128}};var HE=class extends Yu{};function jE(e,t){return Y(V(e,t.weights),t.biases)}function V1(e,t,n,r,s="same"){let{filters:a,bias:o}=t.conv,i=Rt(e,a,n,s);return i=Y(i,o),i=jE(i,t.scale),r?qe(i):i}function qE(e,t){return V1(e,t,[1,1],!0)}function U1(e,t){return V1(e,t,[1,1],!1)}function eg(e,t){return V1(e,t,[2,2],!0,"valid")}function rue(e,t){function n(i,c,l){let u=e(i),d=u.length/(c*l*l);if(m1(d))throw new Error(`depth has to be an integer: ${d}, weights.length: ${u.length}, numFilters: ${c}, filterSize: ${l}`);return M(()=>Re(Br(u,[c,d,l,l]),[2,3,1,0]))}function r(i,c,l,u){let d=n(i,c,l),p=He(e(c));return t.push({paramPath:`${u}/filters`},{paramPath:`${u}/bias`}),{filters:d,bias:p}}function s(i,c){let l=He(e(i)),u=He(e(i));return t.push({paramPath:`${c}/weights`},{paramPath:`${c}/biases`}),{weights:l,biases:u}}function a(i,c,l,u){let d=r(i,c,l,`${u}/conv`),p=s(c,`${u}/scale`);return{conv:d,scale:p}}function o(i,c,l,u,d=!1){let p=a((d?.5:1)*i,c,l,`${u}/conv1`),h=a(i,c,l,`${u}/conv2`);return{conv1:p,conv2:h}}return{extractConvLayerParams:a,extractResidualLayerParams:o}}function KE(e){let{extractWeights:t,getRemainingWeights:n}=En(e),r=[],{extractConvLayerParams:s,extractResidualLayerParams:a}=rue(t,r),o=s(4704,32,7,"conv32_down"),i=a(9216,32,3,"conv32_1"),c=a(9216,32,3,"conv32_2"),l=a(9216,32,3,"conv32_3"),u=a(36864,64,3,"conv64_down",!0),d=a(36864,64,3,"conv64_1"),p=a(36864,64,3,"conv64_2"),h=a(36864,64,3,"conv64_3"),f=a(147456,128,3,"conv128_down",!0),m=a(147456,128,3,"conv128_1"),g=a(147456,128,3,"conv128_2"),b=a(589824,256,3,"conv256_down",!0),y=a(589824,256,3,"conv256_1"),v=a(589824,256,3,"conv256_2"),x=a(589824,256,3,"conv256_down_out"),w=M(()=>Re(Lr(t(256*128),[128,256]),[1,0]));if(r.push({paramPath:"fc"}),n().length!==0)throw new Error(`weights remaing after extract: ${n().length}`);return{params:{conv32_down:o,conv32_1:i,conv32_2:c,conv32_3:l,conv64_down:u,conv64_1:d,conv64_2:p,conv64_3:h,conv128_down:f,conv128_1:m,conv128_2:g,conv256_down:b,conv256_1:y,conv256_2:v,conv256_down_out:x,fc:w},paramMappings:r}}function sue(e,t){let n=ar(e,t);function r(o){let i=n(`${o}/scale/weights`,1),c=n(`${o}/scale/biases`,1);return{weights:i,biases:c}}function s(o){let i=n(`${o}/conv/filters`,4),c=n(`${o}/conv/bias`,1),l=r(o);return{conv:{filters:i,bias:c},scale:l}}function a(o){return{conv1:s(`${o}/conv1`),conv2:s(`${o}/conv2`)}}return{extractConvLayerParams:s,extractResidualLayerParams:a}}function XE(e){let t=[],{extractConvLayerParams:n,extractResidualLayerParams:r}=sue(e,t),s=n("conv32_down"),a=r("conv32_1"),o=r("conv32_2"),i=r("conv32_3"),c=r("conv64_down"),l=r("conv64_1"),u=r("conv64_2"),d=r("conv64_3"),p=r("conv128_down"),h=r("conv128_1"),f=r("conv128_2"),m=r("conv256_down"),g=r("conv256_1"),b=r("conv256_2"),y=r("conv256_down_out"),{fc:v}=e;if(t.push({originalPath:"fc",paramPath:"fc"}),!f1(v))throw new Error(`expected weightMap[fc] to be a Tensor2D, instead have ${v}`);let x={conv32_down:s,conv32_1:a,conv32_2:o,conv32_3:i,conv64_down:c,conv64_1:l,conv64_2:u,conv64_3:d,conv128_down:p,conv128_1:h,conv128_2:f,conv256_down:m,conv256_1:g,conv256_2:b,conv256_down_out:y,fc:v};return _n(e,t),{params:x,paramMappings:t}}function Yr(e,t){let n=qE(e,t.conv1);return n=U1(n,t.conv2),n=Y(n,e),n=qe(n),n}function hp(e,t){let n=eg(e,t.conv1);n=U1(n,t.conv2);let r=lr(e,2,2,"valid"),s=St(r.shape),a=r.shape[3]!==n.shape[3];if(r.shape[1]!==n.shape[1]||r.shape[2]!==n.shape[2]){let i=[...n.shape];i[1]=1;let c=St(i);n=et([n,c],1);let l=[...n.shape];l[2]=1;let u=St(l);n=et([n,u],2)}return r=a?et([r,s],3):r,n=Y(r,n),n=qe(n),n}var Zu=class extends ln{constructor(){super("FaceRecognitionNet")}forwardInput(t){let{params:n}=this;if(!n)throw new Error("FaceRecognitionNet - load model before inference");return M(()=>{let r=ce(t.toBatchTensor(150,!0),"float32"),a=Xr(r,[122.782,117.001,104.298]).div(255),o=eg(a,n.conv32_down);o=Pt(o,3,2,"valid"),o=Yr(o,n.conv32_1),o=Yr(o,n.conv32_2),o=Yr(o,n.conv32_3),o=hp(o,n.conv64_down),o=Yr(o,n.conv64_1),o=Yr(o,n.conv64_2),o=Yr(o,n.conv64_3),o=hp(o,n.conv128_down),o=Yr(o,n.conv128_1),o=Yr(o,n.conv128_2),o=hp(o,n.conv256_down),o=Yr(o,n.conv256_1),o=Yr(o,n.conv256_2),o=hp(o,n.conv256_down_out);let i=o.mean([1,2]);return De(i,n.fc)})}async forward(t){return this.forwardInput(await bt(t))}async computeFaceDescriptor(t){var a;if((a=t==null?void 0:t.shape)==null?void 0:a.some(o=>o<=0))return new Float32Array(128);let n=await bt(t),r=M(()=>ht(this.forwardInput(n))),s=await Promise.all(r.map(o=>o.data()));return r.forEach(o=>o.dispose()),n.isBatchInput?s:s[0]}getDefaultModelName(){return"face_recognition_model"}extractParamsFromWeightMap(t){return XE(t)}extractParams(t){return KE(t)}};function aue(e){let t=new Zu;return t.extractWeights(e),t}function tg(e,t){return{...e,...{descriptor:t}}}function oue(e){return typeof e.age=="number"}function ng(e,t){return{...e,...{age:t}}}function iue(e){return(e.gender===Ms.MALE||e.gender===Ms.FEMALE)&&zu(e.genderProbability)}function rg(e,t,n){return{...e,...{gender:t,genderProbability:n}}}function cue(e,t){function n(c,l){let u=Br(e(3*3*c),[3,3,c,1]),d=He(e(c)),p=He(e(c)),h=He(e(c)),f=He(e(c));return t.push({paramPath:`${l}/filters`},{paramPath:`${l}/batch_norm_scale`},{paramPath:`${l}/batch_norm_offset`},{paramPath:`${l}/batch_norm_mean`},{paramPath:`${l}/batch_norm_variance`}),{filters:u,batch_norm_scale:d,batch_norm_offset:p,batch_norm_mean:h,batch_norm_variance:f}}function r(c,l,u,d,p){let h=Br(e(c*l*u*u),[u,u,c,l]),f=He(e(l));return t.push({paramPath:`${d}/filters`},{paramPath:`${d}/${p?"batch_norm_offset":"bias"}`}),{filters:h,bias:f}}function s(c,l,u,d){let{filters:p,bias:h}=r(c,l,u,d,!0);return{filters:p,batch_norm_offset:h}}function a(c,l,u){let d=n(c,`${u}/depthwise_conv`),p=s(c,l,1,`${u}/pointwise_conv`);return{depthwise_conv:d,pointwise_conv:p}}function o(){let c=s(3,32,3,"mobilenetv1/conv_0"),l=a(32,64,"mobilenetv1/conv_1"),u=a(64,128,"mobilenetv1/conv_2"),d=a(128,128,"mobilenetv1/conv_3"),p=a(128,256,"mobilenetv1/conv_4"),h=a(256,256,"mobilenetv1/conv_5"),f=a(256,512,"mobilenetv1/conv_6"),m=a(512,512,"mobilenetv1/conv_7"),g=a(512,512,"mobilenetv1/conv_8"),b=a(512,512,"mobilenetv1/conv_9"),y=a(512,512,"mobilenetv1/conv_10"),v=a(512,512,"mobilenetv1/conv_11"),x=a(512,1024,"mobilenetv1/conv_12"),w=a(1024,1024,"mobilenetv1/conv_13");return{conv_0:c,conv_1:l,conv_2:u,conv_3:d,conv_4:p,conv_5:h,conv_6:f,conv_7:m,conv_8:g,conv_9:b,conv_10:y,conv_11:v,conv_12:x,conv_13:w}}function i(){let c=s(1024,256,1,"prediction_layer/conv_0"),l=s(256,512,3,"prediction_layer/conv_1"),u=s(512,128,1,"prediction_layer/conv_2"),d=s(128,256,3,"prediction_layer/conv_3"),p=s(256,128,1,"prediction_layer/conv_4"),h=s(128,256,3,"prediction_layer/conv_5"),f=s(256,64,1,"prediction_layer/conv_6"),m=s(64,128,3,"prediction_layer/conv_7"),g=r(512,12,1,"prediction_layer/box_predictor_0/box_encoding_predictor"),b=r(512,9,1,"prediction_layer/box_predictor_0/class_predictor"),y=r(1024,24,1,"prediction_layer/box_predictor_1/box_encoding_predictor"),v=r(1024,18,1,"prediction_layer/box_predictor_1/class_predictor"),x=r(512,24,1,"prediction_layer/box_predictor_2/box_encoding_predictor"),w=r(512,18,1,"prediction_layer/box_predictor_2/class_predictor"),T=r(256,24,1,"prediction_layer/box_predictor_3/box_encoding_predictor"),C=r(256,18,1,"prediction_layer/box_predictor_3/class_predictor"),D=r(256,24,1,"prediction_layer/box_predictor_4/box_encoding_predictor"),F=r(256,18,1,"prediction_layer/box_predictor_4/class_predictor"),O=r(128,24,1,"prediction_layer/box_predictor_5/box_encoding_predictor"),$=r(128,18,1,"prediction_layer/box_predictor_5/class_predictor");return{conv_0:c,conv_1:l,conv_2:u,conv_3:d,conv_4:p,conv_5:h,conv_6:f,conv_7:m,box_predictor_0:{box_encoding_predictor:g,class_predictor:b},box_predictor_1:{box_encoding_predictor:y,class_predictor:v},box_predictor_2:{box_encoding_predictor:x,class_predictor:w},box_predictor_3:{box_encoding_predictor:T,class_predictor:C},box_predictor_4:{box_encoding_predictor:D,class_predictor:F},box_predictor_5:{box_encoding_predictor:O,class_predictor:$}}}return{extractMobilenetV1Params:o,extractPredictionLayerParams:i}}function YE(e){let t=[],{extractWeights:n,getRemainingWeights:r}=En(e),{extractMobilenetV1Params:s,extractPredictionLayerParams:a}=cue(n,t),o=s(),i=a(),l={extra_dim:zh(n(5118*4),[1,5118,4])};if(t.push({paramPath:"output_layer/extra_dim"}),r().length!==0)throw new Error(`weights remaing after extract: ${r().length}`);return{params:{mobilenetv1:o,prediction_layer:i,output_layer:l},paramMappings:t}}function uue(e,t){let n=ar(e,t);function r(l,u,d){let p=n(`${l}/Conv2d_${u}_pointwise/weights`,4,`${d}/filters`),h=n(`${l}/Conv2d_${u}_pointwise/convolution_bn_offset`,1,`${d}/batch_norm_offset`);return{filters:p,batch_norm_offset:h}}function s(l){let u=`mobilenetv1/conv_${l}`,d=`MobilenetV1/Conv2d_${l}_depthwise`,p=`${u}/depthwise_conv`,h=`${u}/pointwise_conv`,f=n(`${d}/depthwise_weights`,4,`${p}/filters`),m=n(`${d}/BatchNorm/gamma`,1,`${p}/batch_norm_scale`),g=n(`${d}/BatchNorm/beta`,1,`${p}/batch_norm_offset`),b=n(`${d}/BatchNorm/moving_mean`,1,`${p}/batch_norm_mean`),y=n(`${d}/BatchNorm/moving_variance`,1,`${p}/batch_norm_variance`);return{depthwise_conv:{filters:f,batch_norm_scale:m,batch_norm_offset:g,batch_norm_mean:b,batch_norm_variance:y},pointwise_conv:r("MobilenetV1",l,h)}}function a(){return{conv_0:r("MobilenetV1",0,"mobilenetv1/conv_0"),conv_1:s(1),conv_2:s(2),conv_3:s(3),conv_4:s(4),conv_5:s(5),conv_6:s(6),conv_7:s(7),conv_8:s(8),conv_9:s(9),conv_10:s(10),conv_11:s(11),conv_12:s(12),conv_13:s(13)}}function o(l,u){let d=n(`${l}/weights`,4,`${u}/filters`),p=n(`${l}/biases`,1,`${u}/bias`);return{filters:d,bias:p}}function i(l){let u=o(`Prediction/BoxPredictor_${l}/BoxEncodingPredictor`,`prediction_layer/box_predictor_${l}/box_encoding_predictor`),d=o(`Prediction/BoxPredictor_${l}/ClassPredictor`,`prediction_layer/box_predictor_${l}/class_predictor`);return{box_encoding_predictor:u,class_predictor:d}}function c(){return{conv_0:r("Prediction",0,"prediction_layer/conv_0"),conv_1:r("Prediction",1,"prediction_layer/conv_1"),conv_2:r("Prediction",2,"prediction_layer/conv_2"),conv_3:r("Prediction",3,"prediction_layer/conv_3"),conv_4:r("Prediction",4,"prediction_layer/conv_4"),conv_5:r("Prediction",5,"prediction_layer/conv_5"),conv_6:r("Prediction",6,"prediction_layer/conv_6"),conv_7:r("Prediction",7,"prediction_layer/conv_7"),box_predictor_0:i(0),box_predictor_1:i(1),box_predictor_2:i(2),box_predictor_3:i(3),box_predictor_4:i(4),box_predictor_5:i(5)}}return{extractMobilenetV1Params:a,extractPredictionLayerParams:c}}function ZE(e){let t=[],{extractMobilenetV1Params:n,extractPredictionLayerParams:r}=uue(e,t),s=e["Output/extra_dim"];if(t.push({originalPath:"Output/extra_dim",paramPath:"output_layer/extra_dim"}),!$s(s))throw new Error(`expected weightMap['Output/extra_dim'] to be a Tensor3D, instead have ${s}`);let a={mobilenetv1:n(),prediction_layer:r(),output_layer:{extra_dim:s}};return _n(e,t),{params:a,paramMappings:t}}function Fr(e,t,n){return M(()=>{let r=Rt(e,t.filters,n,"same");return r=Y(r,t.batch_norm_offset),Jt(r,0,6)})}var lue=.0010000000474974513;function due(e,t,n){return M(()=>{let r=ua(e,t.filters,n,"same");return r=Is(r,t.batch_norm_mean,t.batch_norm_variance,t.batch_norm_offset,t.batch_norm_scale,lue),Jt(r,0,6)})}function pue(e){return[2,4,6,12].some(t=>t===e)?[2,2]:[1,1]}function JE(e,t){return M(()=>{let n,r=Fr(e,t.conv_0,[2,2]);if([t.conv_1,t.conv_2,t.conv_3,t.conv_4,t.conv_5,t.conv_6,t.conv_7,t.conv_8,t.conv_9,t.conv_10,t.conv_11,t.conv_12,t.conv_13].forEach((a,o)=>{let i=o+1,c=pue(i);r=due(r,a.depthwise_conv,c),r=Fr(r,a.pointwise_conv,[1,1]),i===11&&(n=r)}),n===null)throw new Error("mobileNetV1 - output of conv layer 11 is null");return{out:r,conv11:n}})}function hue(e,t,n){let r=e.arraySync(),s=Math.min(r[t][0],r[t][2]),a=Math.min(r[t][1],r[t][3]),o=Math.max(r[t][0],r[t][2]),i=Math.max(r[t][1],r[t][3]),c=Math.min(r[n][0],r[n][2]),l=Math.min(r[n][1],r[n][3]),u=Math.max(r[n][0],r[n][2]),d=Math.max(r[n][1],r[n][3]),p=(o-s)*(i-a),h=(u-c)*(d-l);if(p<=0||h<=0)return 0;let f=Math.max(s,c),m=Math.max(a,l),g=Math.min(o,u),b=Math.min(i,d),y=Math.max(g-f,0)*Math.max(b-m,0);return y/(p+h-y)}function QE(e,t,n,r,s){let a=e.shape[0],o=Math.min(n,a),i=t.map((u,d)=>({score:u,boxIndex:d})).filter(u=>u.score>s).sort((u,d)=>d.score-u.score),c=u=>u<=r?1:0,l=[];return i.forEach(u=>{if(l.length>=o)return;let d=u.score;for(let p=l.length-1;p>=0;--p){let h=hue(e,u.boxIndex,l[p]);if(h!==0&&(u.score*=c(h),u.score<=s))break}d===u.score&&l.push(u.boxIndex)}),l}function fue(e){let t=ht(Re(e,[1,0])),n=[fe(t[2],t[0]),fe(t[3],t[1])],r=[Y(t[0],me(n[0],2)),Y(t[1],me(n[1],2))];return{sizes:n,centers:r}}function mue(e,t){let{sizes:n,centers:r}=fue(e),s=ht(Re(t,[1,0])),a=me(V(fn(me(s[2],5)),n[0]),2),o=Y(V(me(s[0],10),n[0]),r[0]),i=me(V(fn(me(s[3],5)),n[1]),2),c=Y(V(me(s[1],10),n[1]),r[1]);return Re(Ot([fe(o,a),fe(c,i),Y(o,a),Y(c,i)]),[1,0])}function eA(e,t,n){return M(()=>{let r=e.shape[0],s=mue(U(Pn(n.extra_dim,[r,1,1]),[-1,4]),U(e,[-1,4]));s=U(s,[r,s.shape[0]/r,4]);let a=dr(ze(t,[0,0,1],[-1,-1,-1])),o=ze(a,[0,0,0],[-1,-1,1]);o=U(o,[r,o.shape[1]]);let i=ht(s),c=ht(o);return{boxes:i,scores:c}})}function Ai(e,t){return M(()=>{let n=e.shape[0],r=U(_i(e,t.box_encoding_predictor),[n,-1,1,4]),s=U(_i(e,t.class_predictor),[n,-1,3]);return{boxPredictionEncoding:r,classPrediction:s}})}function tA(e,t,n){return M(()=>{let r=Fr(e,n.conv_0,[1,1]),s=Fr(r,n.conv_1,[2,2]),a=Fr(s,n.conv_2,[1,1]),o=Fr(a,n.conv_3,[2,2]),i=Fr(o,n.conv_4,[1,1]),c=Fr(i,n.conv_5,[2,2]),l=Fr(c,n.conv_6,[1,1]),u=Fr(l,n.conv_7,[2,2]),d=Ai(t,n.box_predictor_0),p=Ai(e,n.box_predictor_1),h=Ai(s,n.box_predictor_2),f=Ai(o,n.box_predictor_3),m=Ai(c,n.box_predictor_4),g=Ai(u,n.box_predictor_5),b=et([d.boxPredictionEncoding,p.boxPredictionEncoding,h.boxPredictionEncoding,f.boxPredictionEncoding,m.boxPredictionEncoding,g.boxPredictionEncoding],1),y=et([d.classPrediction,p.classPrediction,h.classPrediction,f.classPrediction,m.classPrediction,g.classPrediction],1);return{boxPredictions:b,classPredictions:y}})}var $r=class{constructor({minConfidence:t,maxResults:n}={}){this._name="SsdMobilenetv1Options";if(this._minConfidence=t||.5,this._maxResults=n||100,typeof this._minConfidence!="number"||this._minConfidence<=0||this._minConfidence>=1)throw new Error(`${this._name} - expected minConfidence to be a number between 0 and 1`);if(typeof this._maxResults!="number")throw new Error(`${this._name} - expected maxResults to be a number`)}get minConfidence(){return this._minConfidence}get maxResults(){return this._maxResults}};var Di=class extends ln{constructor(){super("SsdMobilenetv1")}forwardInput(t){let{params:n}=this;if(!n)throw new Error("SsdMobilenetv1 - load model before inference");return M(()=>{let r=ce(t.toBatchTensor(512,!1),"float32"),s=fe(me(r,127.5),1),a=JE(s,n.mobilenetv1),{boxPredictions:o,classPredictions:i}=tA(a.out,a.conv11,n.prediction_layer);return eA(o,i,n.output_layer)})}async forward(t){return this.forwardInput(await bt(t))}async locateFaces(t,n={}){let{maxResults:r,minConfidence:s}=new $r(n),a=await bt(t),{boxes:o,scores:i}=this.forwardInput(a),c=o[0],l=i[0];for(let v=1;v{let[x,w]=[Math.max(0,b[v][0]),Math.min(1,b[v][2])].map(D=>D*g),[T,C]=[Math.max(0,b[v][1]),Math.min(1,b[v][3])].map(D=>D*m);return new xt(u[v],new Vu(T,x,C-T,w-x),{height:a.getInputHeight(0),width:a.getInputWidth(0)})});return c.dispose(),l.dispose(),y}getDefaultModelName(){return"ssd_mobilenetv1_model"}extractParamsFromWeightMap(t){return ZE(t)}extractParams(t){return YE(t)}};function nA(e){let t=new Di;return t.extractWeights(e),t}function gue(e){return nA(e)}var rA=class extends Di{};var sA=.4,aA=[new Pe(.738768,.874946),new Pe(2.42204,2.65704),new Pe(4.30971,7.04493),new Pe(10.246,4.59428),new Pe(12.6868,11.8741)],oA=[new Pe(1.603231,2.094468),new Pe(6.041143,7.080126),new Pe(2.882459,3.518061),new Pe(4.266906,5.178857),new Pe(9.041765,10.66308)],iA=[117.001,114.697,97.404],cA="tiny_yolov2_model",uA="tiny_yolov2_separable_conv_model";var sg=e=>typeof e=="number";function G1(e){if(!e)throw new Error(`invalid config: ${e}`);if(typeof e.withSeparableConvs!="boolean")throw new Error(`config.withSeparableConvs has to be a boolean, have: ${e.withSeparableConvs}`);if(!sg(e.iouThreshold)||e.iouThreshold<0||e.iouThreshold>1)throw new Error(`config.iouThreshold has to be a number between [0, 1], have: ${e.iouThreshold}`);if(!Array.isArray(e.classes)||!e.classes.length||!e.classes.every(t=>typeof t=="string"))throw new Error(`config.classes has to be an array class names: string[], have: ${JSON.stringify(e.classes)}`);if(!Array.isArray(e.anchors)||!e.anchors.length||!e.anchors.map(t=>t||{}).every(t=>sg(t.x)&&sg(t.y)))throw new Error(`config.anchors has to be an array of { x: number, y: number }, have: ${JSON.stringify(e.anchors)}`);if(e.meanRgb&&(!Array.isArray(e.meanRgb)||e.meanRgb.length!==3||!e.meanRgb.every(sg)))throw new Error(`config.meanRgb has to be an array of shape [number, number, number], have: ${JSON.stringify(e.meanRgb)}`)}function Ju(e){return M(()=>{let t=V(e,Ie(.10000000149011612));return Y(qe(fe(e,t)),t)})}function Ls(e,t){return M(()=>{let n=pr(e,[[0,0],[1,1],[1,1],[0,0]]);return n=Rt(n,t.conv.filters,[1,1],"valid"),n=fe(n,t.bn.sub),n=V(n,t.bn.truediv),n=Y(n,t.conv.bias),Ju(n)})}function Bs(e,t){return M(()=>{let n=pr(e,[[0,0],[1,1],[1,1],[0,0]]);return n=ei(n,t.depthwise_filter,t.pointwise_filter,[1,1],"valid"),n=Y(n,t.bias),Ju(n)})}function bue(e,t){let n=ju(e,t);function r(o,i){let c=He(e(o)),l=He(e(o));return t.push({paramPath:`${i}/sub`},{paramPath:`${i}/truediv`}),{sub:c,truediv:l}}function s(o,i,c){let l=n(o,i,3,`${c}/conv`),u=r(i,`${c}/bn`);return{conv:l,bn:u}}let a=qu(e,t);return{extractConvParams:n,extractConvWithBatchNormParams:s,extractSeparableConvParams:a}}function lA(e,t,n,r){let{extractWeights:s,getRemainingWeights:a}=En(e),o=[],{extractConvParams:i,extractConvWithBatchNormParams:c,extractSeparableConvParams:l}=bue(s,o),u;if(t.withSeparableConvs){let[d,p,h,f,m,g,b,y,v]=r,x=t.isFirstLayerConv2d?i(d,p,3,"conv0"):l(d,p,"conv0"),w=l(p,h,"conv1"),T=l(h,f,"conv2"),C=l(f,m,"conv3"),D=l(m,g,"conv4"),F=l(g,b,"conv5"),O=y?l(b,y,"conv6"):void 0,$=v?l(y,v,"conv7"):void 0,R=i(v||y||b,5*n,1,"conv8");u={conv0:x,conv1:w,conv2:T,conv3:C,conv4:D,conv5:F,conv6:O,conv7:$,conv8:R}}else{let[d,p,h,f,m,g,b,y,v]=r,x=c(d,p,"conv0"),w=c(p,h,"conv1"),T=c(h,f,"conv2"),C=c(f,m,"conv3"),D=c(m,g,"conv4"),F=c(g,b,"conv5"),O=c(b,y,"conv6"),$=c(y,v,"conv7"),R=i(v,5*n,1,"conv8");u={conv0:x,conv1:w,conv2:T,conv3:C,conv4:D,conv5:F,conv6:O,conv7:$,conv8:R}}if(a().length!==0)throw new Error(`weights remaing after extract: ${a().length}`);return{params:u,paramMappings:o}}function yue(e,t){let n=ar(e,t);function r(i){let c=n(`${i}/sub`,1),l=n(`${i}/truediv`,1);return{sub:c,truediv:l}}function s(i){let c=n(`${i}/filters`,4),l=n(`${i}/bias`,1);return{filters:c,bias:l}}function a(i){let c=s(`${i}/conv`),l=r(`${i}/bn`);return{conv:c,bn:l}}let o=Ku(n);return{extractConvParams:s,extractConvWithBatchNormParams:a,extractSeparableConvParams:o}}function dA(e,t){let n=[],{extractConvParams:r,extractConvWithBatchNormParams:s,extractSeparableConvParams:a}=yue(e,n),o;if(t.withSeparableConvs){let i=t.filterSizes&&t.filterSizes.length||9;o={conv0:t.isFirstLayerConv2d?r("conv0"):a("conv0"),conv1:a("conv1"),conv2:a("conv2"),conv3:a("conv3"),conv4:a("conv4"),conv5:a("conv5"),conv6:i>7?a("conv6"):void 0,conv7:i>8?a("conv7"):void 0,conv8:r("conv8")}}else o={conv0:s("conv0"),conv1:s("conv1"),conv2:s("conv2"),conv3:s("conv3"),conv4:s("conv4"),conv5:s("conv5"),conv6:s("conv6"),conv7:s("conv7"),conv8:r("conv8")};return _n(e,n),{params:o,paramMappings:n}}var ms=class{constructor({inputSize:t,scoreThreshold:n}={}){this._name="TinyYolov2Options";if(this._inputSize=t||416,this._scoreThreshold=n||.5,typeof this._inputSize!="number"||this._inputSize%32!=0)throw new Error(`${this._name} - expected inputSize to be a number divisible by 32`);if(typeof this._scoreThreshold!="number"||this._scoreThreshold<=0||this._scoreThreshold>=1)throw new Error(`${this._name} - expected scoreThreshold to be a number between 0 and 1`)}get inputSize(){return this._inputSize}get scoreThreshold(){return this._scoreThreshold}};var H1=class extends ln{constructor(t){super("TinyYolov2");G1(t),this._config=t}get config(){return this._config}get withClassScores(){return this.config.withClassScores||this.config.classes.length>1}get boxEncodingSize(){return 5+(this.withClassScores?this.config.classes.length:0)}runTinyYolov2(t,n){let r=Ls(t,n.conv0);return r=Pt(r,[2,2],[2,2],"same"),r=Ls(r,n.conv1),r=Pt(r,[2,2],[2,2],"same"),r=Ls(r,n.conv2),r=Pt(r,[2,2],[2,2],"same"),r=Ls(r,n.conv3),r=Pt(r,[2,2],[2,2],"same"),r=Ls(r,n.conv4),r=Pt(r,[2,2],[2,2],"same"),r=Ls(r,n.conv5),r=Pt(r,[2,2],[1,1],"same"),r=Ls(r,n.conv6),r=Ls(r,n.conv7),_i(r,n.conv8,"valid",!1)}runMobilenet(t,n){let r=this.config.isFirstLayerConv2d?Ju(_i(t,n.conv0,"valid",!1)):Bs(t,n.conv0);return r=Pt(r,[2,2],[2,2],"same"),r=Bs(r,n.conv1),r=Pt(r,[2,2],[2,2],"same"),r=Bs(r,n.conv2),r=Pt(r,[2,2],[2,2],"same"),r=Bs(r,n.conv3),r=Pt(r,[2,2],[2,2],"same"),r=Bs(r,n.conv4),r=Pt(r,[2,2],[2,2],"same"),r=Bs(r,n.conv5),r=Pt(r,[2,2],[1,1],"same"),r=n.conv6?Bs(r,n.conv6):r,r=n.conv7?Bs(r,n.conv7):r,_i(r,n.conv8,"valid",!1)}forwardInput(t,n){let{params:r}=this;if(!r)throw new Error("TinyYolov2 - load model before inference");return M(()=>{let s=ce(t.toBatchTensor(n,!1),"float32");return s=this.config.meanRgb?Xr(s,this.config.meanRgb):s,s=s.div(255),this.config.withSeparableConvs?this.runMobilenet(s,r):this.runTinyYolov2(s,r)})}async forward(t,n){return this.forwardInput(await bt(t),n)}async detect(t,n={}){let{inputSize:r,scoreThreshold:s}=new ms(n),a=await bt(t),o=await this.forwardInput(a,r),i=M(()=>ht(o)[0].expandDims()),c={width:a.getInputWidth(0),height:a.getInputHeight(0)},l=await this.extractBoxes(i,a.getReshapedInputDimensions(0),s);o.dispose(),i.dispose();let u=l.map(g=>g.box),d=l.map(g=>g.score),p=l.map(g=>g.classScore),h=l.map(g=>this.config.classes[g.label]);return x1(u.map(g=>g.rescale(r)),d,this.config.iouThreshold,!0).map(g=>new Na(d[g],p[g],h[g],u[g],c))}getDefaultModelName(){return""}extractParamsFromWeightMap(t){return dA(t,this.config)}extractParams(t){let n=this.config.filterSizes||H1.DEFAULT_FILTER_SIZES,r=n?n.length:void 0;if(r!==7&&r!==8&&r!==9)throw new Error(`TinyYolov2 - expected 7 | 8 | 9 convolutional filters, but found ${r} filterSizes in config`);return lA(t,this.config,this.boxEncodingSize,n)}async extractBoxes(t,n,r){let{width:s,height:a}=n,o=Math.max(s,a),i=o/s,c=o/a,l=t.shape[1],u=this.config.anchors.length,[d,p,h]=M(()=>{let b=t.reshape([l,l,u,this.boxEncodingSize]),y=b.slice([0,0,0,0],[l,l,u,4]),v=b.slice([0,0,0,4],[l,l,u,1]),x=this.withClassScores?Mr(b.slice([0,0,0,5],[l,l,u,this.config.classes.length]),3):Ie(0);return[y,v,x]}),f=[],m=await p.array(),g=await d.array();for(let b=0;br){let w=(y+tp(g[b][y][v][0]))/l*i,T=(b+tp(g[b][y][v][1]))/l*c,C=Math.exp(g[b][y][v][2])*this.config.anchors[v].x/l*i,D=Math.exp(g[b][y][v][3])*this.config.anchors[v].y/l*c,F=w-C/2,O=T-D/2,$={row:b,col:y,anchor:v},{classScore:R,label:N}=this.withClassScores?await this.extractPredictedClass(h,$):{classScore:1,label:0};f.push({box:new Wu(F,O,F+C,O+D),score:x,classScore:x*R,label:N,...$})}}return d.dispose(),p.dispose(),h.dispose(),f}async extractPredictedClass(t,n){let{row:r,col:s,anchor:a}=n,o=await t.array();return Array(this.config.classes.length).fill(0).map((i,c)=>o[r][s][a][c]).map((i,c)=>({classScore:i,label:c})).reduce((i,c)=>i.classScore>c.classScore?i:c)}},Qu=H1;Qu.DEFAULT_FILTER_SIZES=[3,16,32,64,128,256,512,1024,1024];var el=class extends Qu{constructor(t=!0){let n={withSeparableConvs:t,iouThreshold:sA,classes:["face"],...t?{anchors:oA,meanRgb:iA}:{anchors:aA,withClassScores:!0}};super(n)}get withSeparableConvs(){return this.config.withSeparableConvs}get anchors(){return this.config.anchors}async locateFaces(t,n){return(await this.detect(t,n)).map(s=>new xt(s.score,s.relativeBox,{width:s.imageWidth,height:s.imageHeight}))}getDefaultModelName(){return this.withSeparableConvs?uA:cA}extractParamsFromWeightMap(t){return super.extractParamsFromWeightMap(t)}};function vue(e,t=!0){let n=new el(t);return n.extractWeights(e),n}var ag=class extends ms{constructor(){super(...arguments);this._name="TinyFaceDetectorOptions"}};var Rr=class{async then(t){return t(await this.run())}async run(){throw new Error("ComposableTask - run is not implemented")}};async function Fi(e,t,n,r,s=({alignedRect:a})=>a){let a=e.map(c=>Ei(c)?s(c):c.detection),o=r||(t instanceof Ee?await Hu(t,a):await Gu(t,a)),i=await n(o);return o.forEach(c=>c instanceof Ee&&c.dispose()),i}async function tl(e,t,n,r,s){return Fi([e],t,async a=>n(a[0]),r,s)}var pA=.4,hA=[new Pe(1.603231,2.094468),new Pe(6.041143,7.080126),new Pe(2.882459,3.518061),new Pe(4.266906,5.178857),new Pe(9.041765,10.66308)],fA=[117.001,114.697,97.404];var nl=class extends Qu{constructor(){let t={withSeparableConvs:!0,iouThreshold:pA,classes:["face"],anchors:hA,meanRgb:fA,isFirstLayerConv2d:!0,filterSizes:[3,16,32,64,128,256,512]};super(t)}get anchors(){return this.config.anchors}async locateFaces(t,n){return(await this.detect(t,n)).map(s=>new xt(s.score,s.relativeBox,{width:s.imageWidth,height:s.imageHeight}))}getDefaultModelName(){return"tiny_face_detector_model"}extractParamsFromWeightMap(t){return super.extractParamsFromWeightMap(t)}};var nt={ssdMobilenetv1:new Di,tinyFaceDetector:new nl,tinyYolov2:new el,faceLandmark68Net:new Yu,faceLandmark68TinyNet:new Qm,faceRecognitionNet:new Zu,faceExpressionNet:new Ym,ageGenderNet:new Jm},mA=(e,t)=>nt.ssdMobilenetv1.locateFaces(e,t),xue=(e,t)=>nt.tinyFaceDetector.locateFaces(e,t),wue=(e,t)=>nt.tinyYolov2.locateFaces(e,t),gA=e=>nt.faceLandmark68Net.detectLandmarks(e),kue=e=>nt.faceLandmark68TinyNet.detectLandmarks(e),Iue=e=>nt.faceRecognitionNet.computeFaceDescriptor(e),Sue=e=>nt.faceExpressionNet.predictExpressions(e),Tue=e=>nt.ageGenderNet.predictAgeAndGender(e),bA=e=>nt.ssdMobilenetv1.load(e),Cue=e=>nt.tinyFaceDetector.load(e),Nue=e=>nt.tinyYolov2.load(e),_ue=e=>nt.faceLandmark68Net.load(e),Eue=e=>nt.faceLandmark68TinyNet.load(e),Aue=e=>nt.faceRecognitionNet.load(e),Due=e=>nt.faceExpressionNet.load(e),Fue=e=>nt.ageGenderNet.load(e),$ue=bA,Rue=mA,Pue=gA;var j1=class extends Rr{constructor(t,n,r){super();this.parentTask=t;this.input=n;this.extractedFaces=r}},rl=class extends j1{async run(){let t=await this.parentTask,n=await Fi(t,this.input,async r=>Promise.all(r.map(s=>nt.faceExpressionNet.predictExpressions(s))),this.extractedFaces);return t.map((r,s)=>Zm(r,n[s]))}withAgeAndGender(){return new al(this,this.input)}},sl=class extends j1{async run(){let t=await this.parentTask;if(!t)return;let n=await tl(t,this.input,r=>nt.faceExpressionNet.predictExpressions(r),this.extractedFaces);return Zm(t,n)}withAgeAndGender(){return new ol(this,this.input)}},$i=class extends rl{withAgeAndGender(){return new Pi(this,this.input)}withFaceDescriptors(){return new Aa(this,this.input)}},Ri=class extends sl{withAgeAndGender(){return new Oi(this,this.input)}withFaceDescriptor(){return new Da(this,this.input)}};var q1=class extends Rr{constructor(t,n,r){super();this.parentTask=t;this.input=n;this.extractedFaces=r}},al=class extends q1{async run(){let t=await this.parentTask,n=await Fi(t,this.input,async r=>Promise.all(r.map(s=>nt.ageGenderNet.predictAgeAndGender(s))),this.extractedFaces);return t.map((r,s)=>{let{age:a,gender:o,genderProbability:i}=n[s];return ng(rg(r,o,i),a)})}withFaceExpressions(){return new rl(this,this.input)}},ol=class extends q1{async run(){let t=await this.parentTask;if(!t)return;let{age:n,gender:r,genderProbability:s}=await tl(t,this.input,a=>nt.ageGenderNet.predictAgeAndGender(a),this.extractedFaces);return ng(rg(t,r,s),n)}withFaceExpressions(){return new sl(this,this.input)}},Pi=class extends al{withFaceExpressions(){return new $i(this,this.input)}withFaceDescriptors(){return new Aa(this,this.input)}},Oi=class extends ol{withFaceExpressions(){return new Ri(this,this.input)}withFaceDescriptor(){return new Da(this,this.input)}};var og=class extends Rr{constructor(t,n){super();this.parentTask=t;this.input=n}},Aa=class extends og{async run(){let t=await this.parentTask;return(await Fi(t,this.input,r=>Promise.all(r.map(s=>nt.faceRecognitionNet.computeFaceDescriptor(s))),null,r=>r.landmarks.align(null,{useDlibAlignment:!0}))).map((r,s)=>tg(t[s],r))}withFaceExpressions(){return new $i(this,this.input)}withAgeAndGender(){return new Pi(this,this.input)}},Da=class extends og{async run(){let t=await this.parentTask;if(!t)return;let n=await tl(t,this.input,r=>nt.faceRecognitionNet.computeFaceDescriptor(r),null,r=>r.landmarks.align(null,{useDlibAlignment:!0}));return tg(t,n)}withFaceExpressions(){return new Ri(this,this.input)}withAgeAndGender(){return new Oi(this,this.input)}};var ig=class extends Rr{constructor(t,n,r){super();this.parentTask=t;this.input=n;this.useTinyLandmarkNet=r}get landmarkNet(){return this.useTinyLandmarkNet?nt.faceLandmark68TinyNet:nt.faceLandmark68Net}},cg=class extends ig{async run(){let t=await this.parentTask,n=t.map(a=>a.detection),r=this.input instanceof Ee?await Hu(this.input,n):await Gu(this.input,n),s=await Promise.all(r.map(a=>this.landmarkNet.detectLandmarks(a)));return r.forEach(a=>a instanceof Ee&&a.dispose()),t.map((a,o)=>Xu(a,s[o]))}withFaceExpressions(){return new $i(this,this.input)}withAgeAndGender(){return new Pi(this,this.input)}withFaceDescriptors(){return new Aa(this,this.input)}},ug=class extends ig{async run(){let t=await this.parentTask;if(!t)return;let{detection:n}=t,r=this.input instanceof Ee?await Hu(this.input,[n]):await Gu(this.input,[n]),s=await this.landmarkNet.detectLandmarks(r[0]);return r.forEach(a=>a instanceof Ee&&a.dispose()),Xu(t,s)}withFaceExpressions(){return new Ri(this,this.input)}withAgeAndGender(){return new Oi(this,this.input)}withFaceDescriptor(){return new Da(this,this.input)}};var lg=class extends Rr{constructor(t,n=new $r){super();this.input=t;this.options=n}},fp=class extends lg{async run(){let{input:t,options:n}=this,r;if(n instanceof ag)r=nt.tinyFaceDetector.locateFaces(t,n);else if(n instanceof $r)r=nt.ssdMobilenetv1.locateFaces(t,n);else if(n instanceof ms)r=nt.tinyYolov2.locateFaces(t,n);else throw new Error("detectFaces - expected options to be instance of TinyFaceDetectorOptions | SsdMobilenetv1Options | TinyYolov2Options");return r}runAndExtendWithFaceDetections(){return new Promise((t,n)=>{this.run().then(r=>t(r.map(s=>Si({},s)))).catch(r=>n(r))})}withFaceLandmarks(t=!1){return new cg(this.runAndExtendWithFaceDetections(),this.input,t)}withFaceExpressions(){return new rl(this.runAndExtendWithFaceDetections(),this.input)}withAgeAndGender(){return new al(this.runAndExtendWithFaceDetections(),this.input)}},dg=class extends lg{async run(){let t=await new fp(this.input,this.options),n=t[0];return t.forEach(r=>{r.score>n.score&&(n=r)}),n}runAndExtendWithFaceDetection(){return new Promise(async t=>{let n=await this.run();t(n?Si({},n):void 0)})}withFaceLandmarks(t=!1){return new ug(this.runAndExtendWithFaceDetection(),this.input,t)}withFaceExpressions(){return new sl(this.runAndExtendWithFaceDetection(),this.input)}withAgeAndGender(){return new ol(this.runAndExtendWithFaceDetection(),this.input)}};function Oue(e,t=new $r){return new dg(e,t)}function pg(e,t=new $r){return new fp(e,t)}async function yA(e,t){return pg(e,new $r(t?{minConfidence:t}:{})).withFaceLandmarks().withFaceDescriptors()}async function Mue(e,t={}){return pg(e,new ms(t)).withFaceLandmarks().withFaceDescriptors()}var Lue=yA;function K1(e,t){if(e.length!==t.length)throw new Error("euclideanDistance: arr1.length !== arr2.length");let n=Array.from(e),r=Array.from(t);return Math.sqrt(n.map((s,a)=>s-r[a]).reduce((s,a)=>s+a**2,0))}var hg=class{constructor(t,n=.6){this._distanceThreshold=n;let r=Array.isArray(t)?t:[t];if(!r.length)throw new Error("FaceRecognizer.constructor - expected atleast one input");let s=1,a=()=>`person ${s++}`;this._labeledDescriptors=r.map(o=>{if(o instanceof Rs)return o;if(o instanceof Float32Array)return new Rs(a(),[o]);if(o.descriptor&&o.descriptor instanceof Float32Array)return new Rs(a(),[o.descriptor]);throw new Error("FaceRecognizer.constructor - expected inputs to be of type LabeledFaceDescriptors | WithFaceDescriptor | Float32Array | Array | Float32Array>")})}get labeledDescriptors(){return this._labeledDescriptors}get distanceThreshold(){return this._distanceThreshold}computeMeanDistance(t,n){return n.map(r=>K1(r,t)).reduce((r,s)=>r+s,0)/(n.length||1)}matchDescriptor(t){return this.labeledDescriptors.map(({descriptors:n,label:r})=>new np(r,this.computeMeanDistance(t,n))).reduce((n,r)=>n.distancet.toJSON())}}static fromJSON(t){let n=t.labeledDescriptors.map(r=>Rs.fromJSON(r));return new hg(n,t.distanceThreshold)}};function Bue(e){let t=new nl;return t.extractWeights(e),t}function vA(e,t){let{width:n,height:r}=new Nn(t.width,t.height);if(n<=0||r<=0)throw new Error(`resizeResults - invalid dimensions: ${JSON.stringify({width:n,height:r})}`);if(Array.isArray(e))return e.map(s=>vA(s,{width:n,height:r}));if(Ei(e)){let s=e.detection.forSize(n,r),a=e.unshiftedLandmarks.forSize(s.box.width,s.box.height);return Xu(Si(e,s),a)}return hs(e)?Si(e,e.detection.forSize(n,r)):e instanceof yr||e instanceof xt?e.forSize(n,r):e}var zue=ME;return Wue;})(); /** * @license * Copyright 2017 Google LLC. All Rights Reserved. diff --git a/dist/face-api.node-gpu.js b/dist/face-api.node-gpu.js index 77e8375..733a044 100644 --- a/dist/face-api.node-gpu.js +++ b/dist/face-api.node-gpu.js @@ -2290,7 +2290,7 @@ function drawFaceLandmarks(canvasArg, faceLandmarks) { } // package.json -var version = "1.6.2"; +var version = "1.6.3"; // src/ageGenderNet/AgeGenderNet.ts var tf20 = __toModule(require_tfjs_esm()); diff --git a/dist/face-api.node-wasm.js b/dist/face-api.node-wasm.js new file mode 100644 index 0000000..98af701 --- /dev/null +++ b/dist/face-api.node-wasm.js @@ -0,0 +1,4691 @@ +/* + Face-API + homepage: + author: ' +*/ + +var __create = Object.create; +var __defProp = Object.defineProperty; +var __getOwnPropDesc = Object.getOwnPropertyDescriptor; +var __getOwnPropNames = Object.getOwnPropertyNames; +var __getProtoOf = Object.getPrototypeOf; +var __hasOwnProp = Object.prototype.hasOwnProperty; +var __markAsModule = (target) => __defProp(target, "__esModule", { value: true }); +var __commonJS = (cb, mod) => function __require() { + return mod || (0, cb[Object.keys(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports; +}; +var __export = (target, all) => { + __markAsModule(target); + for (var name in all) + __defProp(target, name, { get: all[name], enumerable: true }); +}; +var __reExport = (target, module2, desc) => { + if (module2 && typeof module2 === "object" || typeof module2 === "function") { + for (let key of __getOwnPropNames(module2)) + if (!__hasOwnProp.call(target, key) && key !== "default") + __defProp(target, key, { get: () => module2[key], enumerable: !(desc = __getOwnPropDesc(module2, key)) || desc.enumerable }); + } + return target; +}; +var __toModule = (module2) => { + return __reExport(__markAsModule(__defProp(module2 != null ? __create(__getProtoOf(module2)) : {}, "default", module2 && module2.__esModule && "default" in module2 ? { get: () => module2.default, enumerable: true } : { value: module2, enumerable: true })), module2); +}; + +// dist/tfjs.esm.js +var require_tfjs_esm = __commonJS({ + "dist/tfjs.esm.js"(exports) { + var __create2 = Object.create; + var __defProp2 = Object.defineProperty; + var __getOwnPropDesc2 = Object.getOwnPropertyDescriptor; + var __getOwnPropNames2 = Object.getOwnPropertyNames; + var __getProtoOf2 = Object.getPrototypeOf; + var __hasOwnProp2 = Object.prototype.hasOwnProperty; + var __markAsModule2 = (target) => __defProp2(target, "__esModule", { value: true }); + var __reExport2 = (target, module22, desc) => { + if (module22 && typeof module22 === "object" || typeof module22 === "function") { + for (let key of __getOwnPropNames2(module22)) + if (!__hasOwnProp2.call(target, key) && key !== "default") + __defProp2(target, key, { get: () => module22[key], enumerable: !(desc = __getOwnPropDesc2(module22, key)) || desc.enumerable }); + } + return target; + }; + var __toModule2 = (module22) => { + return __reExport2(__markAsModule2(__defProp2(module22 != null ? __create2(__getProtoOf2(module22)) : {}, "default", module22 && module22.__esModule && "default" in module22 ? { get: () => module22.default, enumerable: true } : { value: module22, enumerable: true })), module22); + }; + __markAsModule2(exports); + __reExport2(exports, __toModule2(require("@tensorflow/tfjs"))); + __reExport2(exports, __toModule2(require("@tensorflow/tfjs-backend-wasm"))); + } +}); + +// src/index.ts +__export(exports, { + AgeGenderNet: () => AgeGenderNet, + BoundingBox: () => BoundingBox, + Box: () => Box, + ComposableTask: () => ComposableTask, + ComputeAllFaceDescriptorsTask: () => ComputeAllFaceDescriptorsTask, + ComputeFaceDescriptorsTaskBase: () => ComputeFaceDescriptorsTaskBase, + ComputeSingleFaceDescriptorTask: () => ComputeSingleFaceDescriptorTask, + DetectAllFaceLandmarksTask: () => DetectAllFaceLandmarksTask, + DetectAllFacesTask: () => DetectAllFacesTask, + DetectFaceLandmarksTaskBase: () => DetectFaceLandmarksTaskBase, + DetectFacesTaskBase: () => DetectFacesTaskBase, + DetectSingleFaceLandmarksTask: () => DetectSingleFaceLandmarksTask, + DetectSingleFaceTask: () => DetectSingleFaceTask, + Dimensions: () => Dimensions, + FACE_EXPRESSION_LABELS: () => FACE_EXPRESSION_LABELS, + FaceDetection: () => FaceDetection, + FaceDetectionNet: () => FaceDetectionNet, + FaceExpressionNet: () => FaceExpressionNet, + FaceExpressions: () => FaceExpressions, + FaceLandmark68Net: () => FaceLandmark68Net, + FaceLandmark68TinyNet: () => FaceLandmark68TinyNet, + FaceLandmarkNet: () => FaceLandmarkNet, + FaceLandmarks: () => FaceLandmarks, + FaceLandmarks5: () => FaceLandmarks5, + FaceLandmarks68: () => FaceLandmarks68, + FaceMatch: () => FaceMatch, + FaceMatcher: () => FaceMatcher, + FaceRecognitionNet: () => FaceRecognitionNet, + Gender: () => Gender, + LabeledBox: () => LabeledBox, + LabeledFaceDescriptors: () => LabeledFaceDescriptors, + NetInput: () => NetInput, + NeuralNetwork: () => NeuralNetwork, + ObjectDetection: () => ObjectDetection, + Point: () => Point, + PredictedBox: () => PredictedBox, + Rect: () => Rect, + SsdMobilenetv1: () => SsdMobilenetv1, + SsdMobilenetv1Options: () => SsdMobilenetv1Options, + TinyFaceDetector: () => TinyFaceDetector, + TinyFaceDetectorOptions: () => TinyFaceDetectorOptions, + TinyYolov2: () => TinyYolov2, + TinyYolov2Options: () => TinyYolov2Options, + allFaces: () => allFaces, + allFacesSsdMobilenetv1: () => allFacesSsdMobilenetv1, + allFacesTinyYolov2: () => allFacesTinyYolov2, + awaitMediaLoaded: () => awaitMediaLoaded, + bufferToImage: () => bufferToImage, + computeFaceDescriptor: () => computeFaceDescriptor, + createCanvas: () => createCanvas, + createCanvasFromMedia: () => createCanvasFromMedia, + createFaceDetectionNet: () => createFaceDetectionNet, + createFaceRecognitionNet: () => createFaceRecognitionNet, + createSsdMobilenetv1: () => createSsdMobilenetv1, + createTinyFaceDetector: () => createTinyFaceDetector, + createTinyYolov2: () => createTinyYolov2, + detectAllFaces: () => detectAllFaces, + detectFaceLandmarks: () => detectFaceLandmarks, + detectFaceLandmarksTiny: () => detectFaceLandmarksTiny, + detectLandmarks: () => detectLandmarks, + detectSingleFace: () => detectSingleFace, + draw: () => draw_exports, + env: () => env, + euclideanDistance: () => euclideanDistance, + extendWithAge: () => extendWithAge, + extendWithFaceDescriptor: () => extendWithFaceDescriptor, + extendWithFaceDetection: () => extendWithFaceDetection, + extendWithFaceExpressions: () => extendWithFaceExpressions, + extendWithFaceLandmarks: () => extendWithFaceLandmarks, + extendWithGender: () => extendWithGender, + extractFaceTensors: () => extractFaceTensors, + extractFaces: () => extractFaces, + fetchImage: () => fetchImage, + fetchJson: () => fetchJson, + fetchNetWeights: () => fetchNetWeights, + fetchOrThrow: () => fetchOrThrow, + fetchVideo: () => fetchVideo, + getContext2dOrThrow: () => getContext2dOrThrow, + getMediaDimensions: () => getMediaDimensions, + imageTensorToCanvas: () => imageTensorToCanvas, + imageToSquare: () => imageToSquare, + inverseSigmoid: () => inverseSigmoid, + iou: () => iou, + isMediaElement: () => isMediaElement, + isMediaLoaded: () => isMediaLoaded, + isWithAge: () => isWithAge, + isWithFaceDetection: () => isWithFaceDetection, + isWithFaceExpressions: () => isWithFaceExpressions, + isWithFaceLandmarks: () => isWithFaceLandmarks, + isWithGender: () => isWithGender, + loadAgeGenderModel: () => loadAgeGenderModel, + loadFaceDetectionModel: () => loadFaceDetectionModel, + loadFaceExpressionModel: () => loadFaceExpressionModel, + loadFaceLandmarkModel: () => loadFaceLandmarkModel, + loadFaceLandmarkTinyModel: () => loadFaceLandmarkTinyModel, + loadFaceRecognitionModel: () => loadFaceRecognitionModel, + loadSsdMobilenetv1Model: () => loadSsdMobilenetv1Model, + loadTinyFaceDetectorModel: () => loadTinyFaceDetectorModel, + loadTinyYolov2Model: () => loadTinyYolov2Model, + loadWeightMap: () => loadWeightMap, + locateFaces: () => locateFaces, + matchDimensions: () => matchDimensions, + minBbox: () => minBbox, + nets: () => nets, + nonMaxSuppression: () => nonMaxSuppression, + normalize: () => normalize, + padToSquare: () => padToSquare, + predictAgeAndGender: () => predictAgeAndGender, + recognizeFaceExpressions: () => recognizeFaceExpressions, + resizeResults: () => resizeResults, + resolveInput: () => resolveInput, + shuffleArray: () => shuffleArray, + sigmoid: () => sigmoid, + ssdMobilenetv1: () => ssdMobilenetv1, + tf: () => tf42, + tinyFaceDetector: () => tinyFaceDetector, + tinyYolov2: () => tinyYolov2, + toNetInput: () => toNetInput, + utils: () => utils_exports, + validateConfig: () => validateConfig, + version: () => version2 +}); +var tf42 = __toModule(require_tfjs_esm()); + +// src/draw/index.ts +var draw_exports = {}; +__export(draw_exports, { + AnchorPosition: () => AnchorPosition, + DrawBox: () => DrawBox, + DrawBoxOptions: () => DrawBoxOptions, + DrawFaceLandmarks: () => DrawFaceLandmarks, + DrawFaceLandmarksOptions: () => DrawFaceLandmarksOptions, + DrawTextField: () => DrawTextField, + DrawTextFieldOptions: () => DrawTextFieldOptions, + drawContour: () => drawContour, + drawDetections: () => drawDetections, + drawFaceExpressions: () => drawFaceExpressions, + drawFaceLandmarks: () => drawFaceLandmarks +}); + +// src/draw/drawContour.ts +function drawContour(ctx, points, isClosed = false) { + ctx.beginPath(); + points.slice(1).forEach(({ x, y }, prevIdx) => { + const from = points[prevIdx]; + ctx.moveTo(from.x, from.y); + ctx.lineTo(x, y); + }); + if (isClosed) { + const from = points[points.length - 1]; + const to = points[0]; + if (!from || !to) { + return; + } + ctx.moveTo(from.x, from.y); + ctx.lineTo(to.x, to.y); + } + ctx.stroke(); +} + +// src/utils/index.ts +var utils_exports = {}; +__export(utils_exports, { + computeReshapedDimensions: () => computeReshapedDimensions, + getCenterPoint: () => getCenterPoint, + isDimensions: () => isDimensions, + isEven: () => isEven, + isFloat: () => isFloat, + isTensor: () => isTensor, + isTensor1D: () => isTensor1D, + isTensor2D: () => isTensor2D, + isTensor3D: () => isTensor3D, + isTensor4D: () => isTensor4D, + isValidNumber: () => isValidNumber, + isValidProbablitiy: () => isValidProbablitiy, + range: () => range, + round: () => round +}); +var tf = __toModule(require_tfjs_esm()); + +// src/classes/Dimensions.ts +var Dimensions = class { + constructor(width, height) { + if (!isValidNumber(width) || !isValidNumber(height)) { + throw new Error(`Dimensions.constructor - expected width and height to be valid numbers, instead have ${JSON.stringify({ width, height })}`); + } + this._width = width; + this._height = height; + } + get width() { + return this._width; + } + get height() { + return this._height; + } + reverse() { + return new Dimensions(1 / this.width, 1 / this.height); + } +}; + +// src/utils/index.ts +function isTensor(tensor2, dim) { + return tensor2 instanceof tf.Tensor && tensor2.shape.length === dim; +} +function isTensor1D(tensor2) { + return isTensor(tensor2, 1); +} +function isTensor2D(tensor2) { + return isTensor(tensor2, 2); +} +function isTensor3D(tensor2) { + return isTensor(tensor2, 3); +} +function isTensor4D(tensor2) { + return isTensor(tensor2, 4); +} +function isFloat(num) { + return num % 1 !== 0; +} +function isEven(num) { + return num % 2 === 0; +} +function round(num, prec = 2) { + const f = 10 ** prec; + return Math.floor(num * f) / f; +} +function isDimensions(obj) { + return obj && obj.width && obj.height; +} +function computeReshapedDimensions({ width, height }, inputSize) { + const scale2 = inputSize / Math.max(height, width); + return new Dimensions(Math.round(width * scale2), Math.round(height * scale2)); +} +function getCenterPoint(pts) { + return pts.reduce((sum, pt) => sum.add(pt), new Point(0, 0)).div(new Point(pts.length, pts.length)); +} +function range(num, start, step) { + return Array(num).fill(0).map((_, i) => start + i * step); +} +function isValidNumber(num) { + return !!num && num !== Infinity && num !== -Infinity && !Number.isNaN(num) || num === 0; +} +function isValidProbablitiy(num) { + return isValidNumber(num) && num >= 0 && num <= 1; +} + +// src/classes/Point.ts +var Point = class { + constructor(x, y) { + this._x = x; + this._y = y; + } + get x() { + return this._x; + } + get y() { + return this._y; + } + add(pt) { + return new Point(this.x + pt.x, this.y + pt.y); + } + sub(pt) { + return new Point(this.x - pt.x, this.y - pt.y); + } + mul(pt) { + return new Point(this.x * pt.x, this.y * pt.y); + } + div(pt) { + return new Point(this.x / pt.x, this.y / pt.y); + } + abs() { + return new Point(Math.abs(this.x), Math.abs(this.y)); + } + magnitude() { + return Math.sqrt(this.x ** 2 + this.y ** 2); + } + floor() { + return new Point(Math.floor(this.x), Math.floor(this.y)); + } +}; + +// src/classes/Box.ts +var Box = class { + static isRect(rect) { + return !!rect && [rect.x, rect.y, rect.width, rect.height].every(isValidNumber); + } + static assertIsValidBox(box, callee, allowNegativeDimensions = false) { + if (!Box.isRect(box)) { + throw new Error(`${callee} - invalid box: ${JSON.stringify(box)}, expected object with properties x, y, width, height`); + } + if (!allowNegativeDimensions && (box.width < 0 || box.height < 0)) { + throw new Error(`${callee} - width (${box.width}) and height (${box.height}) must be positive numbers`); + } + } + constructor(_box, allowNegativeDimensions = true) { + const box = _box || {}; + const isBbox = [box.left, box.top, box.right, box.bottom].every(isValidNumber); + const isRect = [box.x, box.y, box.width, box.height].every(isValidNumber); + if (!isRect && !isBbox) { + throw new Error(`Box.constructor - expected box to be IBoundingBox | IRect, instead have ${JSON.stringify(box)}`); + } + const [x, y, width, height] = isRect ? [box.x, box.y, box.width, box.height] : [box.left, box.top, box.right - box.left, box.bottom - box.top]; + Box.assertIsValidBox({ + x, + y, + width, + height + }, "Box.constructor", allowNegativeDimensions); + this._x = x; + this._y = y; + this._width = width; + this._height = height; + } + get x() { + return this._x; + } + get y() { + return this._y; + } + get width() { + return this._width; + } + get height() { + return this._height; + } + get left() { + return this.x; + } + get top() { + return this.y; + } + get right() { + return this.x + this.width; + } + get bottom() { + return this.y + this.height; + } + get area() { + return this.width * this.height; + } + get topLeft() { + return new Point(this.left, this.top); + } + get topRight() { + return new Point(this.right, this.top); + } + get bottomLeft() { + return new Point(this.left, this.bottom); + } + get bottomRight() { + return new Point(this.right, this.bottom); + } + round() { + const [x, y, width, height] = [this.x, this.y, this.width, this.height].map((val) => Math.round(val)); + return new Box({ + x, + y, + width, + height + }); + } + floor() { + const [x, y, width, height] = [this.x, this.y, this.width, this.height].map((val) => Math.floor(val)); + return new Box({ + x, + y, + width, + height + }); + } + toSquare() { + let { + x, + y, + width, + height + } = this; + const diff = Math.abs(width - height); + if (width < height) { + x -= diff / 2; + width += diff; + } + if (height < width) { + y -= diff / 2; + height += diff; + } + return new Box({ x, y, width, height }); + } + rescale(s) { + const scaleX = isDimensions(s) ? s.width : s; + const scaleY = isDimensions(s) ? s.height : s; + return new Box({ + x: this.x * scaleX, + y: this.y * scaleY, + width: this.width * scaleX, + height: this.height * scaleY + }); + } + pad(padX, padY) { + const [x, y, width, height] = [ + this.x - padX / 2, + this.y - padY / 2, + this.width + padX, + this.height + padY + ]; + return new Box({ + x, + y, + width, + height + }); + } + clipAtImageBorders(imgWidth, imgHeight) { + const { x, y, right, bottom } = this; + const clippedX = Math.max(x, 0); + const clippedY = Math.max(y, 0); + const newWidth = right - clippedX; + const newHeight = bottom - clippedY; + const clippedWidth = Math.min(newWidth, imgWidth - clippedX); + const clippedHeight = Math.min(newHeight, imgHeight - clippedY); + return new Box({ + x: clippedX, + y: clippedY, + width: clippedWidth, + height: clippedHeight + }).floor(); + } + shift(sx, sy) { + const { width, height } = this; + const x = this.x + sx; + const y = this.y + sy; + return new Box({ + x, + y, + width, + height + }); + } + padAtBorders(imageHeight, imageWidth) { + const w = this.width + 1; + const h = this.height + 1; + const dx = 1; + const dy = 1; + let edx = w; + let edy = h; + let x = this.left; + let y = this.top; + let ex = this.right; + let ey = this.bottom; + if (ex > imageWidth) { + edx = -ex + imageWidth + w; + ex = imageWidth; + } + if (ey > imageHeight) { + edy = -ey + imageHeight + h; + ey = imageHeight; + } + if (x < 1) { + edy = 2 - x; + x = 1; + } + if (y < 1) { + edy = 2 - y; + y = 1; + } + return { + dy, + edy, + dx, + edx, + y, + ey, + x, + ex, + w, + h + }; + } + calibrate(region) { + return new Box({ + left: this.left + region.left * this.width, + top: this.top + region.top * this.height, + right: this.right + region.right * this.width, + bottom: this.bottom + region.bottom * this.height + }).toSquare().round(); + } +}; + +// src/classes/BoundingBox.ts +var BoundingBox = class extends Box { + constructor(left, top, right, bottom, allowNegativeDimensions = false) { + super({ left, top, right, bottom }, allowNegativeDimensions); + } +}; + +// src/classes/ObjectDetection.ts +var ObjectDetection = class { + constructor(score, classScore, className, relativeBox, imageDims) { + this._imageDims = new Dimensions(imageDims.width, imageDims.height); + this._score = score; + this._classScore = classScore; + this._className = className; + this._box = new Box(relativeBox).rescale(this._imageDims); + } + get score() { + return this._score; + } + get classScore() { + return this._classScore; + } + get className() { + return this._className; + } + get box() { + return this._box; + } + get imageDims() { + return this._imageDims; + } + get imageWidth() { + return this.imageDims.width; + } + get imageHeight() { + return this.imageDims.height; + } + get relativeBox() { + return new Box(this._box).rescale(this.imageDims.reverse()); + } + forSize(width, height) { + return new ObjectDetection(this.score, this.classScore, this.className, this.relativeBox, { width, height }); + } +}; + +// src/classes/FaceDetection.ts +var FaceDetection = class extends ObjectDetection { + constructor(score, relativeBox, imageDims) { + super(score, score, "", relativeBox, imageDims); + } + forSize(width, height) { + const { score, relativeBox, imageDims } = super.forSize(width, height); + return new FaceDetection(score, relativeBox, imageDims); + } +}; + +// src/ops/iou.ts +function iou(box1, box2, isIOU = true) { + const width = Math.max(0, Math.min(box1.right, box2.right) - Math.max(box1.left, box2.left)); + const height = Math.max(0, Math.min(box1.bottom, box2.bottom) - Math.max(box1.top, box2.top)); + const interSection = width * height; + return isIOU ? interSection / (box1.area + box2.area - interSection) : interSection / Math.min(box1.area, box2.area); +} + +// src/ops/minBbox.ts +function minBbox(pts) { + const xs = pts.map((pt) => pt.x); + const ys = pts.map((pt) => pt.y); + const minX = xs.reduce((min, x) => x < min ? x : min, Infinity); + const minY = ys.reduce((min, y) => y < min ? y : min, Infinity); + const maxX = xs.reduce((max, x) => max < x ? x : max, 0); + const maxY = ys.reduce((max, y) => max < y ? y : max, 0); + return new BoundingBox(minX, minY, maxX, maxY); +} + +// src/ops/nonMaxSuppression.ts +function nonMaxSuppression(boxes, scores, iouThreshold, isIOU = true) { + let indicesSortedByScore = scores.map((score, boxIndex) => ({ score, boxIndex })).sort((c1, c2) => c1.score - c2.score).map((c) => c.boxIndex); + const pick = []; + while (indicesSortedByScore.length > 0) { + const curr = indicesSortedByScore.pop(); + pick.push(curr); + const indices = indicesSortedByScore; + const outputs = []; + for (let i = 0; i < indices.length; i++) { + const idx = indices[i]; + const currBox = boxes[curr]; + const idxBox = boxes[idx]; + outputs.push(iou(currBox, idxBox, isIOU)); + } + indicesSortedByScore = indicesSortedByScore.filter((_, j) => outputs[j] <= iouThreshold); + } + return pick; +} + +// src/ops/normalize.ts +var tf2 = __toModule(require_tfjs_esm()); +function normalize(x, meanRgb) { + return tf2.tidy(() => { + const [r, g, b] = meanRgb; + const avg_r = tf2.fill([...x.shape.slice(0, 3), 1], r, "float32"); + const avg_g = tf2.fill([...x.shape.slice(0, 3), 1], g, "float32"); + const avg_b = tf2.fill([...x.shape.slice(0, 3), 1], b, "float32"); + const avg_rgb = tf2.concat([avg_r, avg_g, avg_b], 3); + return tf2.sub(x, avg_rgb); + }); +} + +// src/ops/padToSquare.ts +var tf3 = __toModule(require_tfjs_esm()); +function padToSquare(imgTensor, isCenterImage = false) { + return tf3.tidy(() => { + const [height, width] = imgTensor.shape.slice(1); + if (height === width) + return imgTensor; + const dimDiff = Math.abs(height - width); + const paddingAmount = Math.round(dimDiff * (isCenterImage ? 0.5 : 1)); + const paddingAxis = height > width ? 2 : 1; + const createPaddingTensor = (paddingAmountLocal) => { + const paddingTensorShape = imgTensor.shape.slice(); + paddingTensorShape[paddingAxis] = paddingAmountLocal; + return tf3.fill(paddingTensorShape, 0, "float32"); + }; + const paddingTensorAppend = createPaddingTensor(paddingAmount); + const remainingPaddingAmount = dimDiff - paddingTensorAppend.shape[paddingAxis]; + const paddingTensorPrepend = isCenterImage && remainingPaddingAmount ? createPaddingTensor(remainingPaddingAmount) : null; + const tensorsToStack = [paddingTensorPrepend, imgTensor, paddingTensorAppend].filter((t) => !!t).map((t) => tf3.cast(t, "float32")); + return tf3.concat(tensorsToStack, paddingAxis); + }); +} + +// src/ops/shuffleArray.ts +function shuffleArray(inputArray) { + const array = inputArray.slice(); + for (let i = array.length - 1; i > 0; i--) { + const j = Math.floor(Math.random() * (i + 1)); + const x = array[i]; + array[i] = array[j]; + array[j] = x; + } + return array; +} + +// src/ops/index.ts +function sigmoid(x) { + return 1 / (1 + Math.exp(-x)); +} +function inverseSigmoid(x) { + return Math.log(x / (1 - x)); +} + +// src/classes/Rect.ts +var Rect = class extends Box { + constructor(x, y, width, height, allowNegativeDimensions = false) { + super({ x, y, width, height }, allowNegativeDimensions); + } +}; + +// src/classes/FaceLandmarks.ts +var relX = 0.5; +var relY = 0.43; +var relScale = 0.45; +var FaceLandmarks = class { + constructor(relativeFaceLandmarkPositions, imgDims, shift = new Point(0, 0)) { + const { width, height } = imgDims; + this._imgDims = new Dimensions(width, height); + this._shift = shift; + this._positions = relativeFaceLandmarkPositions.map((pt) => pt.mul(new Point(width, height)).add(shift)); + } + get shift() { + return new Point(this._shift.x, this._shift.y); + } + get imageWidth() { + return this._imgDims.width; + } + get imageHeight() { + return this._imgDims.height; + } + get positions() { + return this._positions; + } + get relativePositions() { + return this._positions.map((pt) => pt.sub(this._shift).div(new Point(this.imageWidth, this.imageHeight))); + } + forSize(width, height) { + return new this.constructor(this.relativePositions, { width, height }); + } + shiftBy(x, y) { + return new this.constructor(this.relativePositions, this._imgDims, new Point(x, y)); + } + shiftByPoint(pt) { + return this.shiftBy(pt.x, pt.y); + } + align(detection, options = {}) { + if (detection) { + const box = detection instanceof FaceDetection ? detection.box.floor() : new Box(detection); + return this.shiftBy(box.x, box.y).align(null, options); + } + const { useDlibAlignment, minBoxPadding } = { useDlibAlignment: false, minBoxPadding: 0.2, ...options }; + if (useDlibAlignment) { + return this.alignDlib(); + } + return this.alignMinBbox(minBoxPadding); + } + alignDlib() { + const centers = this.getRefPointsForAlignment(); + const [leftEyeCenter, rightEyeCenter, mouthCenter] = centers; + const distToMouth = (pt) => mouthCenter.sub(pt).magnitude(); + const eyeToMouthDist = (distToMouth(leftEyeCenter) + distToMouth(rightEyeCenter)) / 2; + const size = Math.floor(eyeToMouthDist / relScale); + const refPoint = getCenterPoint(centers); + const x = Math.floor(Math.max(0, refPoint.x - relX * size)); + const y = Math.floor(Math.max(0, refPoint.y - relY * size)); + return new Rect(x, y, Math.min(size, this.imageWidth + x), Math.min(size, this.imageHeight + y)); + } + alignMinBbox(padding) { + const box = minBbox(this.positions); + return box.pad(box.width * padding, box.height * padding); + } + getRefPointsForAlignment() { + throw new Error("getRefPointsForAlignment not implemented by base class"); + } +}; + +// src/classes/FaceLandmarks5.ts +var FaceLandmarks5 = class extends FaceLandmarks { + getRefPointsForAlignment() { + const pts = this.positions; + return [ + pts[0], + pts[1], + getCenterPoint([pts[3], pts[4]]) + ]; + } +}; + +// src/classes/FaceLandmarks68.ts +var FaceLandmarks68 = class extends FaceLandmarks { + getJawOutline() { + return this.positions.slice(0, 17); + } + getLeftEyeBrow() { + return this.positions.slice(17, 22); + } + getRightEyeBrow() { + return this.positions.slice(22, 27); + } + getNose() { + return this.positions.slice(27, 36); + } + getLeftEye() { + return this.positions.slice(36, 42); + } + getRightEye() { + return this.positions.slice(42, 48); + } + getMouth() { + return this.positions.slice(48, 68); + } + getRefPointsForAlignment() { + return [ + this.getLeftEye(), + this.getRightEye(), + this.getMouth() + ].map(getCenterPoint); + } +}; + +// src/classes/FaceMatch.ts +var FaceMatch = class { + constructor(label, distance) { + this._label = label; + this._distance = distance; + } + get label() { + return this._label; + } + get distance() { + return this._distance; + } + toString(withDistance = true) { + return `${this.label}${withDistance ? ` (${round(this.distance)})` : ""}`; + } +}; + +// src/classes/LabeledBox.ts +var LabeledBox = class extends Box { + static assertIsValidLabeledBox(box, callee) { + Box.assertIsValidBox(box, callee); + if (!isValidNumber(box.label)) { + throw new Error(`${callee} - expected property label (${box.label}) to be a number`); + } + } + constructor(box, label) { + super(box); + this._label = label; + } + get label() { + return this._label; + } +}; + +// src/classes/LabeledFaceDescriptors.ts +var LabeledFaceDescriptors = class { + constructor(label, descriptors) { + if (!(typeof label === "string")) { + throw new Error("LabeledFaceDescriptors - constructor expected label to be a string"); + } + if (!Array.isArray(descriptors) || descriptors.some((desc) => !(desc instanceof Float32Array))) { + throw new Error("LabeledFaceDescriptors - constructor expected descriptors to be an array of Float32Array"); + } + this._label = label; + this._descriptors = descriptors; + } + get label() { + return this._label; + } + get descriptors() { + return this._descriptors; + } + toJSON() { + return { + label: this.label, + descriptors: this.descriptors.map((d) => Array.from(d)) + }; + } + static fromJSON(json) { + const descriptors = json.descriptors.map((d) => new Float32Array(d)); + return new LabeledFaceDescriptors(json.label, descriptors); + } +}; + +// src/classes/PredictedBox.ts +var PredictedBox = class extends LabeledBox { + static assertIsValidPredictedBox(box, callee) { + LabeledBox.assertIsValidLabeledBox(box, callee); + if (!isValidProbablitiy(box.score) || !isValidProbablitiy(box.classScore)) { + throw new Error(`${callee} - expected properties score (${box.score}) and (${box.classScore}) to be a number between [0, 1]`); + } + } + constructor(box, label, score, classScore) { + super(box, label); + this._score = score; + this._classScore = classScore; + } + get score() { + return this._score; + } + get classScore() { + return this._classScore; + } +}; + +// src/factories/WithFaceDetection.ts +function isWithFaceDetection(obj) { + return obj.detection instanceof FaceDetection; +} +function extendWithFaceDetection(sourceObj, detection) { + const extension = { detection }; + return { ...sourceObj, ...extension }; +} + +// src/env/createBrowserEnv.ts +function createBrowserEnv() { + const fetch = window.fetch; + if (!fetch) + throw new Error("fetch - missing fetch implementation for browser environment"); + const readFile = () => { + throw new Error("readFile - filesystem not available for browser environment"); + }; + return { + Canvas: HTMLCanvasElement, + CanvasRenderingContext2D, + Image: HTMLImageElement, + ImageData, + Video: HTMLVideoElement, + createCanvasElement: () => document.createElement("canvas"), + createImageElement: () => document.createElement("img"), + createVideoElement: () => document.createElement("video"), + fetch, + readFile + }; +} + +// src/env/isNodejs.ts +function isNodejs() { + return typeof global === "object" && typeof process !== "undefined" && process.versions != null && process.versions.node != null; +} + +// src/env/createFileSystem.ts +function createFileSystem(fs) { + let requireFsError = ""; + if (!fs && isNodejs()) { + try { + fs = require("fs"); + } catch (err) { + requireFsError = err.toString(); + } + } + const readFile = fs ? (filePath) => new Promise((resolve, reject) => { + fs.readFile(filePath, (err, buffer) => err ? reject(err) : resolve(buffer)); + }) : () => { + throw new Error(`readFile - failed to require fs in nodejs environment with error: ${requireFsError}`); + }; + return { readFile }; +} + +// src/env/createNodejsEnv.ts +function createNodejsEnv() { + const Canvas = global["Canvas"] || global.HTMLCanvasElement; + const Image = global.Image || global.HTMLImageElement; + const Video = global["Video"] || global.HTMLVideoElement; + const createCanvasElement = () => { + if (Canvas) + return new Canvas(); + throw new Error("createCanvasElement - missing Canvas implementation for nodejs environment"); + }; + const createImageElement = () => { + if (Image) + return new Image(); + throw new Error("createImageElement - missing Image implementation for nodejs environment"); + }; + const createVideoElement = () => { + if (Video) + return new Video(); + throw new Error("createVideoElement - missing Video implementation for nodejs environment"); + }; + const fetch = global.fetch; + const fileSystem = createFileSystem(); + return { + Canvas: Canvas || class { + }, + CanvasRenderingContext2D: global.CanvasRenderingContext2D || class { + }, + Image: Image || class { + }, + ImageData: global.ImageData || class { + }, + Video: global.HTMLVideoElement || class { + }, + createCanvasElement, + createImageElement, + createVideoElement, + fetch, + ...fileSystem + }; +} + +// src/env/isBrowser.ts +function isBrowser() { + return typeof window === "object" && typeof document !== "undefined" && typeof HTMLImageElement !== "undefined" && typeof HTMLCanvasElement !== "undefined" && typeof HTMLVideoElement !== "undefined" && typeof ImageData !== "undefined" && typeof CanvasRenderingContext2D !== "undefined"; +} + +// src/env/index.ts +var environment; +function getEnv() { + if (!environment) { + throw new Error("getEnv - environment is not defined, check isNodejs() and isBrowser()"); + } + return environment; +} +function setEnv(env2) { + environment = env2; +} +function initialize() { + if (isBrowser()) + return setEnv(createBrowserEnv()); + if (isNodejs()) + return setEnv(createNodejsEnv()); + return null; +} +function monkeyPatch(env2) { + if (!environment) { + initialize(); + } + if (!environment) { + throw new Error("monkeyPatch - environment is not defined, check isNodejs() and isBrowser()"); + } + const { Canvas = environment.Canvas, Image = environment.Image } = env2; + environment.Canvas = Canvas; + environment.Image = Image; + environment.createCanvasElement = env2.createCanvasElement || (() => new Canvas()); + environment.createImageElement = env2.createImageElement || (() => new Image()); + environment.ImageData = env2.ImageData || environment.ImageData; + environment.Video = env2.Video || environment.Video; + environment.fetch = env2.fetch || environment.fetch; + environment.readFile = env2.readFile || environment.readFile; +} +var env = { + getEnv, + setEnv, + initialize, + createBrowserEnv, + createFileSystem, + createNodejsEnv, + monkeyPatch, + isBrowser, + isNodejs +}; +initialize(); + +// src/dom/resolveInput.ts +function resolveInput(arg) { + if (!env.isNodejs() && typeof arg === "string") { + return document.getElementById(arg); + } + return arg; +} + +// src/dom/getContext2dOrThrow.ts +function getContext2dOrThrow(canvasArg) { + const { Canvas, CanvasRenderingContext2D: CanvasRenderingContext2D2 } = env.getEnv(); + if (canvasArg instanceof CanvasRenderingContext2D2) { + return canvasArg; + } + const canvas = resolveInput(canvasArg); + if (!(canvas instanceof Canvas)) { + throw new Error("resolveContext2d - expected canvas to be of instance of Canvas"); + } + const ctx = canvas.getContext("2d"); + if (!ctx) { + throw new Error("resolveContext2d - canvas 2d context is null"); + } + return ctx; +} + +// src/draw/DrawTextField.ts +var AnchorPosition; +(function(AnchorPosition2) { + AnchorPosition2["TOP_LEFT"] = "TOP_LEFT"; + AnchorPosition2["TOP_RIGHT"] = "TOP_RIGHT"; + AnchorPosition2["BOTTOM_LEFT"] = "BOTTOM_LEFT"; + AnchorPosition2["BOTTOM_RIGHT"] = "BOTTOM_RIGHT"; +})(AnchorPosition || (AnchorPosition = {})); +var DrawTextFieldOptions = class { + constructor(options = {}) { + const { + anchorPosition, + backgroundColor, + fontColor, + fontSize, + fontStyle, + padding + } = options; + this.anchorPosition = anchorPosition || AnchorPosition.TOP_LEFT; + this.backgroundColor = backgroundColor || "rgba(0, 0, 0, 0.5)"; + this.fontColor = fontColor || "rgba(255, 255, 255, 1)"; + this.fontSize = fontSize || 14; + this.fontStyle = fontStyle || "Georgia"; + this.padding = padding || 4; + } +}; +var DrawTextField = class { + constructor(text, anchor, options = {}) { + this.text = typeof text === "string" ? [text] : text instanceof DrawTextField ? text.text : text; + this.anchor = anchor; + this.options = new DrawTextFieldOptions(options); + } + measureWidth(ctx) { + const { padding } = this.options; + return this.text.map((l) => ctx.measureText(l).width).reduce((w0, w1) => w0 < w1 ? w1 : w0, 0) + 2 * padding; + } + measureHeight() { + const { fontSize, padding } = this.options; + return this.text.length * fontSize + 2 * padding; + } + getUpperLeft(ctx, canvasDims) { + const { anchorPosition } = this.options; + const isShiftLeft = anchorPosition === AnchorPosition.BOTTOM_RIGHT || anchorPosition === AnchorPosition.TOP_RIGHT; + const isShiftTop = anchorPosition === AnchorPosition.BOTTOM_LEFT || anchorPosition === AnchorPosition.BOTTOM_RIGHT; + const textFieldWidth = this.measureWidth(ctx); + const textFieldHeight = this.measureHeight(); + const x = isShiftLeft ? this.anchor.x - textFieldWidth : this.anchor.x; + const y = isShiftTop ? this.anchor.y - textFieldHeight : this.anchor.y; + if (canvasDims) { + const { width, height } = canvasDims; + const newX = Math.max(Math.min(x, width - textFieldWidth), 0); + const newY = Math.max(Math.min(y, height - textFieldHeight), 0); + return { x: newX, y: newY }; + } + return { x, y }; + } + draw(canvasArg) { + const canvas = resolveInput(canvasArg); + const ctx = getContext2dOrThrow(canvas); + const { + backgroundColor, + fontColor, + fontSize, + fontStyle, + padding + } = this.options; + ctx.font = `${fontSize}px ${fontStyle}`; + const maxTextWidth = this.measureWidth(ctx); + const textHeight = this.measureHeight(); + ctx.fillStyle = backgroundColor; + const upperLeft = this.getUpperLeft(ctx, canvas); + ctx.fillRect(upperLeft.x, upperLeft.y, maxTextWidth, textHeight); + ctx.fillStyle = fontColor; + this.text.forEach((textLine, i) => { + const x = padding + upperLeft.x; + const y = padding + upperLeft.y + (i + 1) * fontSize; + ctx.fillText(textLine, x, y); + }); + } +}; + +// src/draw/DrawBox.ts +var DrawBoxOptions = class { + constructor(options = {}) { + const { + boxColor, + lineWidth, + label, + drawLabelOptions + } = options; + this.boxColor = boxColor || "rgba(0, 0, 255, 1)"; + this.lineWidth = lineWidth || 2; + this.label = label; + const defaultDrawLabelOptions = { + anchorPosition: AnchorPosition.BOTTOM_LEFT, + backgroundColor: this.boxColor + }; + this.drawLabelOptions = new DrawTextFieldOptions({ ...defaultDrawLabelOptions, ...drawLabelOptions }); + } +}; +var DrawBox = class { + constructor(box, options = {}) { + this.box = new Box(box); + this.options = new DrawBoxOptions(options); + } + draw(canvasArg) { + const ctx = getContext2dOrThrow(canvasArg); + const { boxColor, lineWidth } = this.options; + const { + x, + y, + width, + height + } = this.box; + ctx.strokeStyle = boxColor; + ctx.lineWidth = lineWidth; + ctx.strokeRect(x, y, width, height); + const { label } = this.options; + if (label) { + new DrawTextField([label], { x: x - lineWidth / 2, y }, this.options.drawLabelOptions).draw(canvasArg); + } + } +}; + +// src/draw/drawDetections.ts +function drawDetections(canvasArg, detections) { + const detectionsArray = Array.isArray(detections) ? detections : [detections]; + detectionsArray.forEach((det) => { + const score = det instanceof FaceDetection ? det.score : isWithFaceDetection(det) ? det.detection.score : void 0; + const box = det instanceof FaceDetection ? det.box : isWithFaceDetection(det) ? det.detection.box : new Box(det); + const label = score ? `${round(score)}` : void 0; + new DrawBox(box, { label }).draw(canvasArg); + }); +} + +// src/faceExpressionNet/FaceExpressionNet.ts +var tf18 = __toModule(require_tfjs_esm()); + +// src/dom/isMediaLoaded.ts +function isMediaLoaded(media) { + const { Image, Video } = env.getEnv(); + return media instanceof Image && media.complete || media instanceof Video && media.readyState >= 3; +} + +// src/dom/awaitMediaLoaded.ts +function awaitMediaLoaded(media) { + return new Promise((resolve, reject) => { + if (media instanceof env.getEnv().Canvas || isMediaLoaded(media)) + resolve(null); + function onError(e) { + if (!e.currentTarget) + return; + e.currentTarget.removeEventListener("load", onLoad); + e.currentTarget.removeEventListener("error", onError); + reject(e); + } + function onLoad(e) { + if (!e.currentTarget) + return; + e.currentTarget.removeEventListener("load", onLoad); + e.currentTarget.removeEventListener("error", onError); + resolve(e); + } + media.addEventListener("load", onLoad); + media.addEventListener("error", onError); + }); +} + +// src/dom/bufferToImage.ts +function bufferToImage(buf) { + return new Promise((resolve, reject) => { + if (!(buf instanceof Blob)) + reject(new Error("bufferToImage - expected buf to be of type: Blob")); + const reader = new FileReader(); + reader.onload = () => { + if (typeof reader.result !== "string") + reject(new Error("bufferToImage - expected reader.result to be a string, in onload")); + const img = env.getEnv().createImageElement(); + img.onload = () => resolve(img); + img.onerror = reject; + img.src = reader.result; + }; + reader.onerror = reject; + reader.readAsDataURL(buf); + }); +} + +// src/dom/getMediaDimensions.ts +function getMediaDimensions(input) { + const { Image, Video } = env.getEnv(); + if (input instanceof Image) { + return new Dimensions(input.naturalWidth, input.naturalHeight); + } + if (input instanceof Video) { + return new Dimensions(input.videoWidth, input.videoHeight); + } + return new Dimensions(input.width, input.height); +} + +// src/dom/createCanvas.ts +function createCanvas({ width, height }) { + const { createCanvasElement } = env.getEnv(); + const canvas = createCanvasElement(); + canvas.width = width; + canvas.height = height; + return canvas; +} +function createCanvasFromMedia(media, dims) { + const { ImageData: ImageData2 } = env.getEnv(); + if (!(media instanceof ImageData2) && !isMediaLoaded(media)) { + throw new Error("createCanvasFromMedia - media has not finished loading yet"); + } + const { width, height } = dims || getMediaDimensions(media); + const canvas = createCanvas({ width, height }); + if (media instanceof ImageData2) { + getContext2dOrThrow(canvas).putImageData(media, 0, 0); + } else { + getContext2dOrThrow(canvas).drawImage(media, 0, 0, width, height); + } + return canvas; +} + +// src/dom/imageTensorToCanvas.ts +var tf4 = __toModule(require_tfjs_esm()); +async function imageTensorToCanvas(imgTensor, canvas) { + const targetCanvas = canvas || env.getEnv().createCanvasElement(); + const [height, width, numChannels] = imgTensor.shape.slice(isTensor4D(imgTensor) ? 1 : 0); + const imgTensor3D = tf4.tidy(() => imgTensor.as3D(height, width, numChannels).toInt()); + await tf4.browser.toPixels(imgTensor3D, targetCanvas); + imgTensor3D.dispose(); + return targetCanvas; +} + +// src/dom/isMediaElement.ts +function isMediaElement(input) { + const { Image, Canvas, Video } = env.getEnv(); + return input instanceof Image || input instanceof Canvas || input instanceof Video; +} + +// src/dom/NetInput.ts +var tf5 = __toModule(require_tfjs_esm()); + +// src/dom/imageToSquare.ts +function imageToSquare(input, inputSize, centerImage = false) { + const { Image, Canvas } = env.getEnv(); + if (!(input instanceof Image || input instanceof Canvas)) { + throw new Error("imageToSquare - expected arg0 to be HTMLImageElement | HTMLCanvasElement"); + } + if (inputSize <= 0) + return createCanvas({ width: 1, height: 1 }); + const dims = getMediaDimensions(input); + const scale2 = inputSize / Math.max(dims.height, dims.width); + const width = scale2 * dims.width; + const height = scale2 * dims.height; + const targetCanvas = createCanvas({ width: inputSize, height: inputSize }); + const inputCanvas = input instanceof Canvas ? input : createCanvasFromMedia(input); + const offset = Math.abs(width - height) / 2; + const dx = centerImage && width < height ? offset : 0; + const dy = centerImage && height < width ? offset : 0; + if (inputCanvas.width > 0 && inputCanvas.height > 0) + getContext2dOrThrow(targetCanvas).drawImage(inputCanvas, dx, dy, width, height); + return targetCanvas; +} + +// src/dom/NetInput.ts +var NetInput = class { + constructor(inputs, treatAsBatchInput = false) { + this._imageTensors = []; + this._canvases = []; + this._treatAsBatchInput = false; + this._inputDimensions = []; + this._inputSize = 0; + if (!Array.isArray(inputs)) { + throw new Error(`NetInput.constructor - expected inputs to be an Array of TResolvedNetInput or to be instanceof tf.Tensor4D, instead have ${inputs}`); + } + this._treatAsBatchInput = treatAsBatchInput; + this._batchSize = inputs.length; + inputs.forEach((input, idx) => { + if (isTensor3D(input)) { + this._imageTensors[idx] = input; + this._inputDimensions[idx] = input.shape; + return; + } + if (isTensor4D(input)) { + const batchSize = input.shape[0]; + if (batchSize !== 1) { + throw new Error(`NetInput - tf.Tensor4D with batchSize ${batchSize} passed, but not supported in input array`); + } + this._imageTensors[idx] = input; + this._inputDimensions[idx] = input.shape.slice(1); + return; + } + const canvas = input instanceof env.getEnv().Canvas ? input : createCanvasFromMedia(input); + this._canvases[idx] = canvas; + this._inputDimensions[idx] = [canvas.height, canvas.width, 3]; + }); + } + get imageTensors() { + return this._imageTensors; + } + get canvases() { + return this._canvases; + } + get isBatchInput() { + return this.batchSize > 1 || this._treatAsBatchInput; + } + get batchSize() { + return this._batchSize; + } + get inputDimensions() { + return this._inputDimensions; + } + get inputSize() { + return this._inputSize; + } + get reshapedInputDimensions() { + return range(this.batchSize, 0, 1).map((_, batchIdx) => this.getReshapedInputDimensions(batchIdx)); + } + getInput(batchIdx) { + return this.canvases[batchIdx] || this.imageTensors[batchIdx]; + } + getInputDimensions(batchIdx) { + return this._inputDimensions[batchIdx]; + } + getInputHeight(batchIdx) { + return this._inputDimensions[batchIdx][0]; + } + getInputWidth(batchIdx) { + return this._inputDimensions[batchIdx][1]; + } + getReshapedInputDimensions(batchIdx) { + if (typeof this.inputSize !== "number") { + throw new Error("getReshapedInputDimensions - inputSize not set, toBatchTensor has not been called yet"); + } + const width = this.getInputWidth(batchIdx); + const height = this.getInputHeight(batchIdx); + return computeReshapedDimensions({ width, height }, this.inputSize); + } + toBatchTensor(inputSize, isCenterInputs = true) { + this._inputSize = inputSize; + return tf5.tidy(() => { + const inputTensors = range(this.batchSize, 0, 1).map((batchIdx) => { + const input = this.getInput(batchIdx); + if (input instanceof tf5.Tensor) { + let imgTensor = isTensor4D(input) ? input : tf5.expandDims(input); + imgTensor = padToSquare(imgTensor, isCenterInputs); + if (imgTensor.shape[1] !== inputSize || imgTensor.shape[2] !== inputSize) { + imgTensor = tf5.image.resizeBilinear(imgTensor, [inputSize, inputSize], false, false); + } + return imgTensor.as3D(inputSize, inputSize, 3); + } + if (input instanceof env.getEnv().Canvas) { + return tf5.browser.fromPixels(imageToSquare(input, inputSize, isCenterInputs)); + } + throw new Error(`toBatchTensor - at batchIdx ${batchIdx}, expected input to be instanceof tf.Tensor or instanceof HTMLCanvasElement, instead have ${input}`); + }); + const batchTensor = tf5.stack(inputTensors.map((t) => tf5.cast(t, "float32"))).as4D(this.batchSize, inputSize, inputSize, 3); + return batchTensor; + }); + } +}; + +// src/dom/toNetInput.ts +async function toNetInput(inputs) { + if (inputs instanceof NetInput) + return inputs; + const inputArgArray = Array.isArray(inputs) ? inputs : [inputs]; + if (!inputArgArray.length) + throw new Error("toNetInput - empty array passed as input"); + const getIdxHint = (idx) => Array.isArray(inputs) ? ` at input index ${idx}:` : ""; + const inputArray = inputArgArray.map(resolveInput); + inputArray.forEach((input, i) => { + if (!isMediaElement(input) && !isTensor3D(input) && !isTensor4D(input)) { + if (typeof inputArgArray[i] === "string") + throw new Error(`toNetInput -${getIdxHint(i)} string passed, but could not resolve HTMLElement for element id ${inputArgArray[i]}`); + throw new Error(`toNetInput -${getIdxHint(i)} expected media to be of type HTMLImageElement | HTMLVideoElement | HTMLCanvasElement | tf.Tensor3D, or to be an element id`); + } + if (isTensor4D(input)) { + const batchSize = input.shape[0]; + if (batchSize !== 1) + throw new Error(`toNetInput -${getIdxHint(i)} tf.Tensor4D with batchSize ${batchSize} passed, but not supported in input array`); + } + }); + await Promise.all(inputArray.map((input) => isMediaElement(input) && awaitMediaLoaded(input))); + return new NetInput(inputArray, Array.isArray(inputs)); +} + +// src/dom/extractFaces.ts +async function extractFaces(input, detections) { + const { Canvas } = env.getEnv(); + let canvas = input; + if (!(input instanceof Canvas)) { + const netInput = await toNetInput(input); + if (netInput.batchSize > 1) + throw new Error("extractFaces - batchSize > 1 not supported"); + const tensorOrCanvas = netInput.getInput(0); + canvas = tensorOrCanvas instanceof Canvas ? tensorOrCanvas : await imageTensorToCanvas(tensorOrCanvas); + } + const ctx = getContext2dOrThrow(canvas); + const boxes = detections.map((det) => det instanceof FaceDetection ? det.forSize(canvas.width, canvas.height).box.floor() : det).map((box) => box.clipAtImageBorders(canvas.width, canvas.height)); + return boxes.map(({ x, y, width, height }) => { + const faceImg = createCanvas({ width, height }); + if (width > 0 && height > 0) + getContext2dOrThrow(faceImg).putImageData(ctx.getImageData(x, y, width, height), 0, 0); + return faceImg; + }); +} + +// src/dom/extractFaceTensors.ts +var tf6 = __toModule(require_tfjs_esm()); +async function extractFaceTensors(imageTensor, detections) { + if (!isTensor3D(imageTensor) && !isTensor4D(imageTensor)) { + throw new Error("extractFaceTensors - expected image tensor to be 3D or 4D"); + } + if (isTensor4D(imageTensor) && imageTensor.shape[0] > 1) { + throw new Error("extractFaceTensors - batchSize > 1 not supported"); + } + return tf6.tidy(() => { + const [imgHeight, imgWidth, numChannels] = imageTensor.shape.slice(isTensor4D(imageTensor) ? 1 : 0); + const boxes = detections.map((det) => det instanceof FaceDetection ? det.forSize(imgWidth, imgHeight).box : det).map((box) => box.clipAtImageBorders(imgWidth, imgHeight)); + const faceTensors = boxes.map(({ + x, + y, + width, + height + }) => tf6.slice3d(imageTensor.as3D(imgHeight, imgWidth, numChannels), [y, x, 0], [height, width, numChannels])); + return faceTensors; + }); +} + +// src/dom/fetchOrThrow.ts +async function fetchOrThrow(url, init) { + const { fetch } = env.getEnv(); + const res = await fetch(url, init); + if (!(res.status < 400)) { + throw new Error(`failed to fetch: (${res.status}) ${res.statusText}, from url: ${res.url}`); + } + return res; +} + +// src/dom/fetchImage.ts +async function fetchImage(uri) { + const res = await fetchOrThrow(uri); + const blob = await res.blob(); + if (!blob.type.startsWith("image/")) { + throw new Error(`fetchImage - expected blob type to be of type image/*, instead have: ${blob.type}, for url: ${res.url}`); + } + return bufferToImage(blob); +} + +// src/dom/fetchJson.ts +async function fetchJson(uri) { + return (await fetchOrThrow(uri)).json(); +} + +// src/dom/fetchNetWeights.ts +async function fetchNetWeights(uri) { + return new Float32Array(await (await fetchOrThrow(uri)).arrayBuffer()); +} + +// src/dom/bufferToVideo.ts +function bufferToVideo(buf) { + return new Promise((resolve, reject) => { + if (!(buf instanceof Blob)) + reject(new Error("bufferToVideo - expected buf to be of type: Blob")); + const video = env.getEnv().createVideoElement(); + video.oncanplay = () => resolve(video); + video.onerror = reject; + video.playsInline = true; + video.muted = true; + video.src = URL.createObjectURL(buf); + video.play(); + }); +} + +// src/dom/fetchVideo.ts +async function fetchVideo(uri) { + const res = await fetchOrThrow(uri); + const blob = await res.blob(); + if (!blob.type.startsWith("video/")) { + throw new Error(`fetchVideo - expected blob type to be of type video/*, instead have: ${blob.type}, for url: ${res.url}`); + } + return bufferToVideo(blob); +} + +// src/dom/loadWeightMap.ts +var tf7 = __toModule(require_tfjs_esm()); + +// src/common/getModelUris.ts +function getModelUris(uri, defaultModelName) { + const defaultManifestFilename = `${defaultModelName}-weights_manifest.json`; + if (!uri) { + return { + modelBaseUri: "", + manifestUri: defaultManifestFilename + }; + } + if (uri === "/") { + return { + modelBaseUri: "/", + manifestUri: `/${defaultManifestFilename}` + }; + } + const protocol = uri.startsWith("http://") ? "http://" : uri.startsWith("https://") ? "https://" : ""; + uri = uri.replace(protocol, ""); + const parts = uri.split("/").filter((s) => s); + const manifestFile = uri.endsWith(".json") ? parts[parts.length - 1] : defaultManifestFilename; + let modelBaseUri = protocol + (uri.endsWith(".json") ? parts.slice(0, parts.length - 1) : parts).join("/"); + modelBaseUri = uri.startsWith("/") ? `/${modelBaseUri}` : modelBaseUri; + return { + modelBaseUri, + manifestUri: modelBaseUri === "/" ? `/${manifestFile}` : `${modelBaseUri}/${manifestFile}` + }; +} + +// src/dom/loadWeightMap.ts +async function loadWeightMap(uri, defaultModelName) { + const { manifestUri, modelBaseUri } = getModelUris(uri, defaultModelName); + const manifest = await fetchJson(manifestUri); + return tf7.io.loadWeights(manifest, modelBaseUri); +} + +// src/dom/matchDimensions.ts +function matchDimensions(input, reference, useMediaDimensions = false) { + const { width, height } = useMediaDimensions ? getMediaDimensions(reference) : reference; + input.width = width; + input.height = height; + return { width, height }; +} + +// src/faceFeatureExtractor/FaceFeatureExtractor.ts +var tf15 = __toModule(require_tfjs_esm()); + +// src/NeuralNetwork.ts +var tf8 = __toModule(require_tfjs_esm()); +var NeuralNetwork = class { + constructor(name) { + this._params = void 0; + this._paramMappings = []; + this._name = name; + } + get params() { + return this._params; + } + get paramMappings() { + return this._paramMappings; + } + get isLoaded() { + return !!this.params; + } + getParamFromPath(paramPath) { + const { obj, objProp } = this.traversePropertyPath(paramPath); + return obj[objProp]; + } + reassignParamFromPath(paramPath, tensor2) { + const { obj, objProp } = this.traversePropertyPath(paramPath); + obj[objProp].dispose(); + obj[objProp] = tensor2; + } + getParamList() { + return this._paramMappings.map(({ paramPath }) => ({ + path: paramPath, + tensor: this.getParamFromPath(paramPath) + })); + } + getTrainableParams() { + return this.getParamList().filter((param) => param.tensor instanceof tf8.Variable); + } + getFrozenParams() { + return this.getParamList().filter((param) => !(param.tensor instanceof tf8.Variable)); + } + variable() { + this.getFrozenParams().forEach(({ path, tensor: tensor2 }) => { + this.reassignParamFromPath(path, tensor2.variable()); + }); + } + freeze() { + this.getTrainableParams().forEach(({ path, tensor: variable }) => { + const tensor2 = tf8.tensor(variable.dataSync()); + variable.dispose(); + this.reassignParamFromPath(path, tensor2); + }); + } + dispose(throwOnRedispose = true) { + this.getParamList().forEach((param) => { + if (throwOnRedispose && param.tensor.isDisposed) { + throw new Error(`param tensor has already been disposed for path ${param.path}`); + } + param.tensor.dispose(); + }); + this._params = void 0; + } + serializeParams() { + return new Float32Array(this.getParamList().map(({ tensor: tensor2 }) => Array.from(tensor2.dataSync())).reduce((flat, arr) => flat.concat(arr))); + } + async load(weightsOrUrl) { + if (weightsOrUrl instanceof Float32Array) { + this.extractWeights(weightsOrUrl); + return; + } + await this.loadFromUri(weightsOrUrl); + } + async loadFromUri(uri) { + if (uri && typeof uri !== "string") { + throw new Error(`${this._name}.loadFromUri - expected model uri`); + } + const weightMap = await loadWeightMap(uri, this.getDefaultModelName()); + this.loadFromWeightMap(weightMap); + } + async loadFromDisk(filePath) { + if (filePath && typeof filePath !== "string") { + throw new Error(`${this._name}.loadFromDisk - expected model file path`); + } + const { readFile } = env.getEnv(); + const { manifestUri, modelBaseUri } = getModelUris(filePath, this.getDefaultModelName()); + const fetchWeightsFromDisk = (filePaths) => Promise.all(filePaths.map((fp) => readFile(fp).then((buf) => buf.buffer))); + const loadWeights = tf8.io.weightsLoaderFactory(fetchWeightsFromDisk); + const manifest = JSON.parse((await readFile(manifestUri)).toString()); + const weightMap = await loadWeights(manifest, modelBaseUri); + this.loadFromWeightMap(weightMap); + } + loadFromWeightMap(weightMap) { + const { paramMappings, params } = this.extractParamsFromWeightMap(weightMap); + this._paramMappings = paramMappings; + this._params = params; + } + extractWeights(weights) { + const { paramMappings, params } = this.extractParams(weights); + this._paramMappings = paramMappings; + this._params = params; + } + traversePropertyPath(paramPath) { + if (!this.params) { + throw new Error("traversePropertyPath - model has no loaded params"); + } + const result = paramPath.split("/").reduce((res, objProp2) => { + if (!res.nextObj.hasOwnProperty(objProp2)) { + throw new Error(`traversePropertyPath - object does not have property ${objProp2}, for path ${paramPath}`); + } + return { obj: res.nextObj, objProp: objProp2, nextObj: res.nextObj[objProp2] }; + }, { nextObj: this.params }); + const { obj, objProp } = result; + if (!obj || !objProp || !(obj[objProp] instanceof tf8.Tensor)) { + throw new Error(`traversePropertyPath - parameter is not a tensor, for path ${paramPath}`); + } + return { obj, objProp }; + } +}; + +// src/faceFeatureExtractor/denseBlock.ts +var tf10 = __toModule(require_tfjs_esm()); + +// src/common/depthwiseSeparableConv.ts +var tf9 = __toModule(require_tfjs_esm()); +function depthwiseSeparableConv(x, params, stride) { + return tf9.tidy(() => { + let out = tf9.separableConv2d(x, params.depthwise_filter, params.pointwise_filter, stride, "same"); + out = tf9.add(out, params.bias); + return out; + }); +} + +// src/faceFeatureExtractor/denseBlock.ts +function denseBlock3(x, denseBlockParams, isFirstLayer = false) { + return tf10.tidy(() => { + const out1 = tf10.relu(isFirstLayer ? tf10.add(tf10.conv2d(x, denseBlockParams.conv0.filters, [2, 2], "same"), denseBlockParams.conv0.bias) : depthwiseSeparableConv(x, denseBlockParams.conv0, [2, 2])); + const out2 = depthwiseSeparableConv(out1, denseBlockParams.conv1, [1, 1]); + const in3 = tf10.relu(tf10.add(out1, out2)); + const out3 = depthwiseSeparableConv(in3, denseBlockParams.conv2, [1, 1]); + return tf10.relu(tf10.add(out1, tf10.add(out2, out3))); + }); +} +function denseBlock4(x, denseBlockParams, isFirstLayer = false, isScaleDown = true) { + return tf10.tidy(() => { + const out1 = tf10.relu(isFirstLayer ? tf10.add(tf10.conv2d(x, denseBlockParams.conv0.filters, isScaleDown ? [2, 2] : [1, 1], "same"), denseBlockParams.conv0.bias) : depthwiseSeparableConv(x, denseBlockParams.conv0, isScaleDown ? [2, 2] : [1, 1])); + const out2 = depthwiseSeparableConv(out1, denseBlockParams.conv1, [1, 1]); + const in3 = tf10.relu(tf10.add(out1, out2)); + const out3 = depthwiseSeparableConv(in3, denseBlockParams.conv2, [1, 1]); + const in4 = tf10.relu(tf10.add(out1, tf10.add(out2, out3))); + const out4 = depthwiseSeparableConv(in4, denseBlockParams.conv3, [1, 1]); + return tf10.relu(tf10.add(out1, tf10.add(out2, tf10.add(out3, out4)))); + }); +} + +// src/common/convLayer.ts +var tf11 = __toModule(require_tfjs_esm()); +function convLayer(x, params, padding = "same", withRelu = false) { + return tf11.tidy(() => { + const out = tf11.add(tf11.conv2d(x, params.filters, [1, 1], padding), params.bias); + return withRelu ? tf11.relu(out) : out; + }); +} + +// src/common/disposeUnusedWeightTensors.ts +function disposeUnusedWeightTensors(weightMap, paramMappings) { + Object.keys(weightMap).forEach((path) => { + if (!paramMappings.some((pm) => pm.originalPath === path)) { + weightMap[path].dispose(); + } + }); +} + +// src/common/extractConvParamsFactory.ts +var tf12 = __toModule(require_tfjs_esm()); +function extractConvParamsFactory(extractWeights, paramMappings) { + return (channelsIn, channelsOut, filterSize, mappedPrefix) => { + const filters = tf12.tensor4d(extractWeights(channelsIn * channelsOut * filterSize * filterSize), [filterSize, filterSize, channelsIn, channelsOut]); + const bias = tf12.tensor1d(extractWeights(channelsOut)); + paramMappings.push({ paramPath: `${mappedPrefix}/filters` }, { paramPath: `${mappedPrefix}/bias` }); + return { filters, bias }; + }; +} + +// src/common/extractFCParamsFactory.ts +var tf13 = __toModule(require_tfjs_esm()); +function extractFCParamsFactory(extractWeights, paramMappings) { + return (channelsIn, channelsOut, mappedPrefix) => { + const fc_weights = tf13.tensor2d(extractWeights(channelsIn * channelsOut), [channelsIn, channelsOut]); + const fc_bias = tf13.tensor1d(extractWeights(channelsOut)); + paramMappings.push({ paramPath: `${mappedPrefix}/weights` }, { paramPath: `${mappedPrefix}/bias` }); + return { + weights: fc_weights, + bias: fc_bias + }; + }; +} + +// src/common/extractSeparableConvParamsFactory.ts +var tf14 = __toModule(require_tfjs_esm()); + +// src/common/types.ts +var SeparableConvParams = class { + constructor(depthwise_filter, pointwise_filter, bias) { + this.depthwise_filter = depthwise_filter; + this.pointwise_filter = pointwise_filter; + this.bias = bias; + } +}; + +// src/common/extractSeparableConvParamsFactory.ts +function extractSeparableConvParamsFactory(extractWeights, paramMappings) { + return (channelsIn, channelsOut, mappedPrefix) => { + const depthwise_filter = tf14.tensor4d(extractWeights(3 * 3 * channelsIn), [3, 3, channelsIn, 1]); + const pointwise_filter = tf14.tensor4d(extractWeights(channelsIn * channelsOut), [1, 1, channelsIn, channelsOut]); + const bias = tf14.tensor1d(extractWeights(channelsOut)); + paramMappings.push({ paramPath: `${mappedPrefix}/depthwise_filter` }, { paramPath: `${mappedPrefix}/pointwise_filter` }, { paramPath: `${mappedPrefix}/bias` }); + return new SeparableConvParams(depthwise_filter, pointwise_filter, bias); + }; +} +function loadSeparableConvParamsFactory(extractWeightEntry) { + return (prefix) => { + const depthwise_filter = extractWeightEntry(`${prefix}/depthwise_filter`, 4); + const pointwise_filter = extractWeightEntry(`${prefix}/pointwise_filter`, 4); + const bias = extractWeightEntry(`${prefix}/bias`, 1); + return new SeparableConvParams(depthwise_filter, pointwise_filter, bias); + }; +} + +// src/common/extractWeightEntryFactory.ts +function extractWeightEntryFactory(weightMap, paramMappings) { + return (originalPath, paramRank, mappedPath) => { + const tensor2 = weightMap[originalPath]; + if (!isTensor(tensor2, paramRank)) { + throw new Error(`expected weightMap[${originalPath}] to be a Tensor${paramRank}D, instead have ${tensor2}`); + } + paramMappings.push({ originalPath, paramPath: mappedPath || originalPath }); + return tensor2; + }; +} + +// src/common/extractWeightsFactory.ts +function extractWeightsFactory(weights) { + let remainingWeights = weights; + function extractWeights(numWeights) { + const ret = remainingWeights.slice(0, numWeights); + remainingWeights = remainingWeights.slice(numWeights); + return ret; + } + function getRemainingWeights() { + return remainingWeights; + } + return { + extractWeights, + getRemainingWeights + }; +} + +// src/faceFeatureExtractor/extractorsFactory.ts +function extractorsFactory(extractWeights, paramMappings) { + const extractConvParams = extractConvParamsFactory(extractWeights, paramMappings); + const extractSeparableConvParams = extractSeparableConvParamsFactory(extractWeights, paramMappings); + function extractDenseBlock3Params(channelsIn, channelsOut, mappedPrefix, isFirstLayer = false) { + const conv0 = isFirstLayer ? extractConvParams(channelsIn, channelsOut, 3, `${mappedPrefix}/conv0`) : extractSeparableConvParams(channelsIn, channelsOut, `${mappedPrefix}/conv0`); + const conv1 = extractSeparableConvParams(channelsOut, channelsOut, `${mappedPrefix}/conv1`); + const conv22 = extractSeparableConvParams(channelsOut, channelsOut, `${mappedPrefix}/conv2`); + return { conv0, conv1, conv2: conv22 }; + } + function extractDenseBlock4Params(channelsIn, channelsOut, mappedPrefix, isFirstLayer = false) { + const { conv0, conv1, conv2: conv22 } = extractDenseBlock3Params(channelsIn, channelsOut, mappedPrefix, isFirstLayer); + const conv3 = extractSeparableConvParams(channelsOut, channelsOut, `${mappedPrefix}/conv3`); + return { + conv0, + conv1, + conv2: conv22, + conv3 + }; + } + return { + extractDenseBlock3Params, + extractDenseBlock4Params + }; +} + +// src/faceFeatureExtractor/extractParams.ts +function extractParams(weights) { + const paramMappings = []; + const { + extractWeights, + getRemainingWeights + } = extractWeightsFactory(weights); + const { + extractDenseBlock4Params + } = extractorsFactory(extractWeights, paramMappings); + const dense0 = extractDenseBlock4Params(3, 32, "dense0", true); + const dense1 = extractDenseBlock4Params(32, 64, "dense1"); + const dense2 = extractDenseBlock4Params(64, 128, "dense2"); + const dense3 = extractDenseBlock4Params(128, 256, "dense3"); + if (getRemainingWeights().length !== 0) { + throw new Error(`weights remaing after extract: ${getRemainingWeights().length}`); + } + return { + paramMappings, + params: { + dense0, + dense1, + dense2, + dense3 + } + }; +} + +// src/common/loadConvParamsFactory.ts +function loadConvParamsFactory(extractWeightEntry) { + return (prefix) => { + const filters = extractWeightEntry(`${prefix}/filters`, 4); + const bias = extractWeightEntry(`${prefix}/bias`, 1); + return { filters, bias }; + }; +} + +// src/faceFeatureExtractor/loadParamsFactory.ts +function loadParamsFactory(weightMap, paramMappings) { + const extractWeightEntry = extractWeightEntryFactory(weightMap, paramMappings); + const extractConvParams = loadConvParamsFactory(extractWeightEntry); + const extractSeparableConvParams = loadSeparableConvParamsFactory(extractWeightEntry); + function extractDenseBlock3Params(prefix, isFirstLayer = false) { + const conv0 = isFirstLayer ? extractConvParams(`${prefix}/conv0`) : extractSeparableConvParams(`${prefix}/conv0`); + const conv1 = extractSeparableConvParams(`${prefix}/conv1`); + const conv22 = extractSeparableConvParams(`${prefix}/conv2`); + return { conv0, conv1, conv2: conv22 }; + } + function extractDenseBlock4Params(prefix, isFirstLayer = false) { + const conv0 = isFirstLayer ? extractConvParams(`${prefix}/conv0`) : extractSeparableConvParams(`${prefix}/conv0`); + const conv1 = extractSeparableConvParams(`${prefix}/conv1`); + const conv22 = extractSeparableConvParams(`${prefix}/conv2`); + const conv3 = extractSeparableConvParams(`${prefix}/conv3`); + return { + conv0, + conv1, + conv2: conv22, + conv3 + }; + } + return { + extractDenseBlock3Params, + extractDenseBlock4Params + }; +} + +// src/faceFeatureExtractor/extractParamsFromWeightMap.ts +function extractParamsFromWeightMap(weightMap) { + const paramMappings = []; + const { + extractDenseBlock4Params + } = loadParamsFactory(weightMap, paramMappings); + const params = { + dense0: extractDenseBlock4Params("dense0", true), + dense1: extractDenseBlock4Params("dense1"), + dense2: extractDenseBlock4Params("dense2"), + dense3: extractDenseBlock4Params("dense3") + }; + disposeUnusedWeightTensors(weightMap, paramMappings); + return { params, paramMappings }; +} + +// src/faceFeatureExtractor/FaceFeatureExtractor.ts +var FaceFeatureExtractor = class extends NeuralNetwork { + constructor() { + super("FaceFeatureExtractor"); + } + forwardInput(input) { + const { params } = this; + if (!params) { + throw new Error("FaceFeatureExtractor - load model before inference"); + } + return tf15.tidy(() => { + const batchTensor = tf15.cast(input.toBatchTensor(112, true), "float32"); + const meanRgb = [122.782, 117.001, 104.298]; + const normalized = normalize(batchTensor, meanRgb).div(255); + let out = denseBlock4(normalized, params.dense0, true); + out = denseBlock4(out, params.dense1); + out = denseBlock4(out, params.dense2); + out = denseBlock4(out, params.dense3); + out = tf15.avgPool(out, [7, 7], [2, 2], "valid"); + return out; + }); + } + async forward(input) { + return this.forwardInput(await toNetInput(input)); + } + getDefaultModelName() { + return "face_feature_extractor_model"; + } + extractParamsFromWeightMap(weightMap) { + return extractParamsFromWeightMap(weightMap); + } + extractParams(weights) { + return extractParams(weights); + } +}; + +// src/faceProcessor/FaceProcessor.ts +var tf17 = __toModule(require_tfjs_esm()); + +// src/common/fullyConnectedLayer.ts +var tf16 = __toModule(require_tfjs_esm()); +function fullyConnectedLayer(x, params) { + return tf16.tidy(() => tf16.add(tf16.matMul(x, params.weights), params.bias)); +} + +// src/faceProcessor/extractParams.ts +function extractParams2(weights, channelsIn, channelsOut) { + const paramMappings = []; + const { + extractWeights, + getRemainingWeights + } = extractWeightsFactory(weights); + const extractFCParams = extractFCParamsFactory(extractWeights, paramMappings); + const fc = extractFCParams(channelsIn, channelsOut, "fc"); + if (getRemainingWeights().length !== 0) { + throw new Error(`weights remaing after extract: ${getRemainingWeights().length}`); + } + return { + paramMappings, + params: { fc } + }; +} + +// src/faceProcessor/extractParamsFromWeightMap.ts +function extractParamsFromWeightMap2(weightMap) { + const paramMappings = []; + const extractWeightEntry = extractWeightEntryFactory(weightMap, paramMappings); + function extractFcParams(prefix) { + const weights = extractWeightEntry(`${prefix}/weights`, 2); + const bias = extractWeightEntry(`${prefix}/bias`, 1); + return { weights, bias }; + } + const params = { + fc: extractFcParams("fc") + }; + disposeUnusedWeightTensors(weightMap, paramMappings); + return { params, paramMappings }; +} + +// src/faceProcessor/util.ts +function seperateWeightMaps(weightMap) { + const featureExtractorMap = {}; + const classifierMap = {}; + Object.keys(weightMap).forEach((key) => { + const map = key.startsWith("fc") ? classifierMap : featureExtractorMap; + map[key] = weightMap[key]; + }); + return { featureExtractorMap, classifierMap }; +} + +// src/faceProcessor/FaceProcessor.ts +var FaceProcessor = class extends NeuralNetwork { + constructor(_name, faceFeatureExtractor) { + super(_name); + this._faceFeatureExtractor = faceFeatureExtractor; + } + get faceFeatureExtractor() { + return this._faceFeatureExtractor; + } + runNet(input) { + const { params } = this; + if (!params) { + throw new Error(`${this._name} - load model before inference`); + } + return tf17.tidy(() => { + const bottleneckFeatures = input instanceof NetInput ? this.faceFeatureExtractor.forwardInput(input) : input; + return fullyConnectedLayer(bottleneckFeatures.as2D(bottleneckFeatures.shape[0], -1), params.fc); + }); + } + dispose(throwOnRedispose = true) { + this.faceFeatureExtractor.dispose(throwOnRedispose); + super.dispose(throwOnRedispose); + } + loadClassifierParams(weights) { + const { params, paramMappings } = this.extractClassifierParams(weights); + this._params = params; + this._paramMappings = paramMappings; + } + extractClassifierParams(weights) { + return extractParams2(weights, this.getClassifierChannelsIn(), this.getClassifierChannelsOut()); + } + extractParamsFromWeightMap(weightMap) { + const { featureExtractorMap, classifierMap } = seperateWeightMaps(weightMap); + this.faceFeatureExtractor.loadFromWeightMap(featureExtractorMap); + return extractParamsFromWeightMap2(classifierMap); + } + extractParams(weights) { + const cIn = this.getClassifierChannelsIn(); + const cOut = this.getClassifierChannelsOut(); + const classifierWeightSize = cOut * cIn + cOut; + const featureExtractorWeights = weights.slice(0, weights.length - classifierWeightSize); + const classifierWeights = weights.slice(weights.length - classifierWeightSize); + this.faceFeatureExtractor.extractWeights(featureExtractorWeights); + return this.extractClassifierParams(classifierWeights); + } +}; + +// src/faceExpressionNet/FaceExpressions.ts +var FACE_EXPRESSION_LABELS = ["neutral", "happy", "sad", "angry", "fearful", "disgusted", "surprised"]; +var FaceExpressions = class { + constructor(probabilities) { + this.neutral = 0; + this.happy = 0; + this.sad = 0; + this.angry = 0; + this.fearful = 0; + this.disgusted = 0; + this.surprised = 0; + if (probabilities.length !== 7) { + throw new Error(`FaceExpressions.constructor - expected probabilities.length to be 7, have: ${probabilities.length}`); + } + FACE_EXPRESSION_LABELS.forEach((expression, idx) => { + this[expression] = probabilities[idx]; + }); + } + asSortedArray() { + return FACE_EXPRESSION_LABELS.map((expression) => ({ expression, probability: this[expression] })).sort((e0, e1) => e1.probability - e0.probability); + } +}; + +// src/faceExpressionNet/FaceExpressionNet.ts +var FaceExpressionNet = class extends FaceProcessor { + constructor(faceFeatureExtractor = new FaceFeatureExtractor()) { + super("FaceExpressionNet", faceFeatureExtractor); + } + forwardInput(input) { + return tf18.tidy(() => tf18.softmax(this.runNet(input))); + } + async forward(input) { + return this.forwardInput(await toNetInput(input)); + } + async predictExpressions(input) { + const netInput = await toNetInput(input); + const out = await this.forwardInput(netInput); + const probabilitesByBatch = await Promise.all(tf18.unstack(out).map(async (t) => { + const data = t.dataSync(); + t.dispose(); + return data; + })); + out.dispose(); + const predictionsByBatch = probabilitesByBatch.map((probabilites) => new FaceExpressions(probabilites)); + return netInput.isBatchInput ? predictionsByBatch : predictionsByBatch[0]; + } + getDefaultModelName() { + return "face_expression_model"; + } + getClassifierChannelsIn() { + return 256; + } + getClassifierChannelsOut() { + return 7; + } +}; + +// src/factories/WithFaceExpressions.ts +function isWithFaceExpressions(obj) { + return obj.expressions instanceof FaceExpressions; +} +function extendWithFaceExpressions(sourceObj, expressions) { + const extension = { expressions }; + return { ...sourceObj, ...extension }; +} + +// src/draw/drawFaceExpressions.ts +function drawFaceExpressions(canvasArg, faceExpressions, minConfidence = 0.1, textFieldAnchor) { + const faceExpressionsArray = Array.isArray(faceExpressions) ? faceExpressions : [faceExpressions]; + faceExpressionsArray.forEach((e) => { + const expr = e instanceof FaceExpressions ? e : isWithFaceExpressions(e) ? e.expressions : void 0; + if (!expr) { + throw new Error("drawFaceExpressions - expected faceExpressions to be FaceExpressions | WithFaceExpressions<{}> or array thereof"); + } + const sorted = expr.asSortedArray(); + const resultsToDisplay = sorted.filter((exprLocal) => exprLocal.probability > minConfidence); + const anchor = isWithFaceDetection(e) ? e.detection.box.bottomLeft : textFieldAnchor || new Point(0, 0); + const drawTextField = new DrawTextField(resultsToDisplay.map((exprLocal) => `${exprLocal.expression} (${round(exprLocal.probability)})`), anchor); + drawTextField.draw(canvasArg); + }); +} + +// src/factories/WithFaceLandmarks.ts +function isWithFaceLandmarks(obj) { + return isWithFaceDetection(obj) && obj["landmarks"] instanceof FaceLandmarks && obj["unshiftedLandmarks"] instanceof FaceLandmarks && obj["alignedRect"] instanceof FaceDetection; +} +function calculateFaceAngle(mesh) { + const radians = (a1, a2, b1, b2) => Math.atan2(b2 - a2, b1 - a1) % Math.PI; + const degrees = (theta) => theta * 180 / Math.PI; + const angle = { roll: void 0, pitch: void 0, yaw: void 0 }; + if (!mesh || !mesh._positions || mesh._positions.length !== 68) + return angle; + const pt = mesh._positions; + angle.roll = -radians(pt[36]._x, pt[36]._y, pt[45]._x, pt[45]._y); + angle.pitch = radians(0, Math.abs(pt[0]._x - pt[30]._x) / pt[30]._x, Math.PI, Math.abs(pt[16]._x - pt[30]._x) / pt[30]._x); + const bottom = pt.reduce((prev, cur) => prev < cur._y ? prev : cur._y, Infinity); + const top = pt.reduce((prev, cur) => prev > cur._y ? prev : cur._y, -Infinity); + angle.yaw = Math.PI * (mesh._imgDims._height / (top - bottom) / 1.4 - 1); + return angle; +} +function extendWithFaceLandmarks(sourceObj, unshiftedLandmarks) { + const { box: shift } = sourceObj.detection; + const landmarks = unshiftedLandmarks.shiftBy(shift.x, shift.y); + const rect = landmarks.align(); + const { imageDims } = sourceObj.detection; + const alignedRect = new FaceDetection(sourceObj.detection.score, rect.rescale(imageDims.reverse()), imageDims); + const angle = calculateFaceAngle(unshiftedLandmarks); + const extension = { + landmarks, + unshiftedLandmarks, + alignedRect, + angle + }; + return { ...sourceObj, ...extension }; +} + +// src/draw/DrawFaceLandmarks.ts +var DrawFaceLandmarksOptions = class { + constructor(options = {}) { + const { + drawLines = true, + drawPoints = true, + lineWidth, + lineColor, + pointSize, + pointColor + } = options; + this.drawLines = drawLines; + this.drawPoints = drawPoints; + this.lineWidth = lineWidth || 1; + this.pointSize = pointSize || 2; + this.lineColor = lineColor || "rgba(0, 255, 255, 1)"; + this.pointColor = pointColor || "rgba(255, 0, 255, 1)"; + } +}; +var DrawFaceLandmarks = class { + constructor(faceLandmarks, options = {}) { + this.faceLandmarks = faceLandmarks; + this.options = new DrawFaceLandmarksOptions(options); + } + draw(canvasArg) { + const ctx = getContext2dOrThrow(canvasArg); + const { + drawLines, + drawPoints, + lineWidth, + lineColor, + pointSize, + pointColor + } = this.options; + if (drawLines && this.faceLandmarks instanceof FaceLandmarks68) { + ctx.strokeStyle = lineColor; + ctx.lineWidth = lineWidth; + drawContour(ctx, this.faceLandmarks.getJawOutline()); + drawContour(ctx, this.faceLandmarks.getLeftEyeBrow()); + drawContour(ctx, this.faceLandmarks.getRightEyeBrow()); + drawContour(ctx, this.faceLandmarks.getNose()); + drawContour(ctx, this.faceLandmarks.getLeftEye(), true); + drawContour(ctx, this.faceLandmarks.getRightEye(), true); + drawContour(ctx, this.faceLandmarks.getMouth(), true); + } + if (drawPoints) { + ctx.strokeStyle = pointColor; + ctx.fillStyle = pointColor; + const drawPoint = (pt) => { + ctx.beginPath(); + ctx.arc(pt.x, pt.y, pointSize, 0, 2 * Math.PI); + ctx.fill(); + }; + this.faceLandmarks.positions.forEach(drawPoint); + } + } +}; +function drawFaceLandmarks(canvasArg, faceLandmarks) { + const faceLandmarksArray = Array.isArray(faceLandmarks) ? faceLandmarks : [faceLandmarks]; + faceLandmarksArray.forEach((f) => { + const landmarks = f instanceof FaceLandmarks ? f : isWithFaceLandmarks(f) ? f.landmarks : void 0; + if (!landmarks) { + throw new Error("drawFaceLandmarks - expected faceExpressions to be FaceLandmarks | WithFaceLandmarks> or array thereof"); + } + new DrawFaceLandmarks(landmarks).draw(canvasArg); + }); +} + +// package.json +var version = "1.6.3"; + +// src/ageGenderNet/AgeGenderNet.ts +var tf20 = __toModule(require_tfjs_esm()); + +// src/xception/TinyXception.ts +var tf19 = __toModule(require_tfjs_esm()); + +// src/xception/extractParams.ts +function extractorsFactory2(extractWeights, paramMappings) { + const extractConvParams = extractConvParamsFactory(extractWeights, paramMappings); + const extractSeparableConvParams = extractSeparableConvParamsFactory(extractWeights, paramMappings); + function extractReductionBlockParams(channelsIn, channelsOut, mappedPrefix) { + const separable_conv0 = extractSeparableConvParams(channelsIn, channelsOut, `${mappedPrefix}/separable_conv0`); + const separable_conv1 = extractSeparableConvParams(channelsOut, channelsOut, `${mappedPrefix}/separable_conv1`); + const expansion_conv = extractConvParams(channelsIn, channelsOut, 1, `${mappedPrefix}/expansion_conv`); + return { separable_conv0, separable_conv1, expansion_conv }; + } + function extractMainBlockParams(channels, mappedPrefix) { + const separable_conv0 = extractSeparableConvParams(channels, channels, `${mappedPrefix}/separable_conv0`); + const separable_conv1 = extractSeparableConvParams(channels, channels, `${mappedPrefix}/separable_conv1`); + const separable_conv2 = extractSeparableConvParams(channels, channels, `${mappedPrefix}/separable_conv2`); + return { separable_conv0, separable_conv1, separable_conv2 }; + } + return { + extractConvParams, + extractSeparableConvParams, + extractReductionBlockParams, + extractMainBlockParams + }; +} +function extractParams3(weights, numMainBlocks) { + const paramMappings = []; + const { + extractWeights, + getRemainingWeights + } = extractWeightsFactory(weights); + const { + extractConvParams, + extractSeparableConvParams, + extractReductionBlockParams, + extractMainBlockParams + } = extractorsFactory2(extractWeights, paramMappings); + const entry_flow_conv_in = extractConvParams(3, 32, 3, "entry_flow/conv_in"); + const entry_flow_reduction_block_0 = extractReductionBlockParams(32, 64, "entry_flow/reduction_block_0"); + const entry_flow_reduction_block_1 = extractReductionBlockParams(64, 128, "entry_flow/reduction_block_1"); + const entry_flow = { + conv_in: entry_flow_conv_in, + reduction_block_0: entry_flow_reduction_block_0, + reduction_block_1: entry_flow_reduction_block_1 + }; + const middle_flow = {}; + range(numMainBlocks, 0, 1).forEach((idx) => { + middle_flow[`main_block_${idx}`] = extractMainBlockParams(128, `middle_flow/main_block_${idx}`); + }); + const exit_flow_reduction_block = extractReductionBlockParams(128, 256, "exit_flow/reduction_block"); + const exit_flow_separable_conv = extractSeparableConvParams(256, 512, "exit_flow/separable_conv"); + const exit_flow = { + reduction_block: exit_flow_reduction_block, + separable_conv: exit_flow_separable_conv + }; + if (getRemainingWeights().length !== 0) { + throw new Error(`weights remaing after extract: ${getRemainingWeights().length}`); + } + return { + paramMappings, + params: { entry_flow, middle_flow, exit_flow } + }; +} + +// src/xception/extractParamsFromWeightMap.ts +function loadParamsFactory2(weightMap, paramMappings) { + const extractWeightEntry = extractWeightEntryFactory(weightMap, paramMappings); + const extractConvParams = loadConvParamsFactory(extractWeightEntry); + const extractSeparableConvParams = loadSeparableConvParamsFactory(extractWeightEntry); + function extractReductionBlockParams(mappedPrefix) { + const separable_conv0 = extractSeparableConvParams(`${mappedPrefix}/separable_conv0`); + const separable_conv1 = extractSeparableConvParams(`${mappedPrefix}/separable_conv1`); + const expansion_conv = extractConvParams(`${mappedPrefix}/expansion_conv`); + return { separable_conv0, separable_conv1, expansion_conv }; + } + function extractMainBlockParams(mappedPrefix) { + const separable_conv0 = extractSeparableConvParams(`${mappedPrefix}/separable_conv0`); + const separable_conv1 = extractSeparableConvParams(`${mappedPrefix}/separable_conv1`); + const separable_conv2 = extractSeparableConvParams(`${mappedPrefix}/separable_conv2`); + return { separable_conv0, separable_conv1, separable_conv2 }; + } + return { + extractConvParams, + extractSeparableConvParams, + extractReductionBlockParams, + extractMainBlockParams + }; +} +function extractParamsFromWeightMap3(weightMap, numMainBlocks) { + const paramMappings = []; + const { + extractConvParams, + extractSeparableConvParams, + extractReductionBlockParams, + extractMainBlockParams + } = loadParamsFactory2(weightMap, paramMappings); + const entry_flow_conv_in = extractConvParams("entry_flow/conv_in"); + const entry_flow_reduction_block_0 = extractReductionBlockParams("entry_flow/reduction_block_0"); + const entry_flow_reduction_block_1 = extractReductionBlockParams("entry_flow/reduction_block_1"); + const entry_flow = { + conv_in: entry_flow_conv_in, + reduction_block_0: entry_flow_reduction_block_0, + reduction_block_1: entry_flow_reduction_block_1 + }; + const middle_flow = {}; + range(numMainBlocks, 0, 1).forEach((idx) => { + middle_flow[`main_block_${idx}`] = extractMainBlockParams(`middle_flow/main_block_${idx}`); + }); + const exit_flow_reduction_block = extractReductionBlockParams("exit_flow/reduction_block"); + const exit_flow_separable_conv = extractSeparableConvParams("exit_flow/separable_conv"); + const exit_flow = { + reduction_block: exit_flow_reduction_block, + separable_conv: exit_flow_separable_conv + }; + disposeUnusedWeightTensors(weightMap, paramMappings); + return { params: { entry_flow, middle_flow, exit_flow }, paramMappings }; +} + +// src/xception/TinyXception.ts +function conv(x, params, stride) { + return tf19.add(tf19.conv2d(x, params.filters, stride, "same"), params.bias); +} +function reductionBlock(x, params, isActivateInput = true) { + let out = isActivateInput ? tf19.relu(x) : x; + out = depthwiseSeparableConv(out, params.separable_conv0, [1, 1]); + out = depthwiseSeparableConv(tf19.relu(out), params.separable_conv1, [1, 1]); + out = tf19.maxPool(out, [3, 3], [2, 2], "same"); + out = tf19.add(out, conv(x, params.expansion_conv, [2, 2])); + return out; +} +function mainBlock(x, params) { + let out = depthwiseSeparableConv(tf19.relu(x), params.separable_conv0, [1, 1]); + out = depthwiseSeparableConv(tf19.relu(out), params.separable_conv1, [1, 1]); + out = depthwiseSeparableConv(tf19.relu(out), params.separable_conv2, [1, 1]); + out = tf19.add(out, x); + return out; +} +var TinyXception = class extends NeuralNetwork { + constructor(numMainBlocks) { + super("TinyXception"); + this._numMainBlocks = numMainBlocks; + } + forwardInput(input) { + const { params } = this; + if (!params) { + throw new Error("TinyXception - load model before inference"); + } + return tf19.tidy(() => { + const batchTensor = tf19.cast(input.toBatchTensor(112, true), "float32"); + const meanRgb = [122.782, 117.001, 104.298]; + const normalized = normalize(batchTensor, meanRgb).div(255); + let out = tf19.relu(conv(normalized, params.entry_flow.conv_in, [2, 2])); + out = reductionBlock(out, params.entry_flow.reduction_block_0, false); + out = reductionBlock(out, params.entry_flow.reduction_block_1); + range(this._numMainBlocks, 0, 1).forEach((idx) => { + out = mainBlock(out, params.middle_flow[`main_block_${idx}`]); + }); + out = reductionBlock(out, params.exit_flow.reduction_block); + out = tf19.relu(depthwiseSeparableConv(out, params.exit_flow.separable_conv, [1, 1])); + return out; + }); + } + async forward(input) { + return this.forwardInput(await toNetInput(input)); + } + getDefaultModelName() { + return "tiny_xception_model"; + } + extractParamsFromWeightMap(weightMap) { + return extractParamsFromWeightMap3(weightMap, this._numMainBlocks); + } + extractParams(weights) { + return extractParams3(weights, this._numMainBlocks); + } +}; + +// src/ageGenderNet/extractParams.ts +function extractParams4(weights) { + const paramMappings = []; + const { + extractWeights, + getRemainingWeights + } = extractWeightsFactory(weights); + const extractFCParams = extractFCParamsFactory(extractWeights, paramMappings); + const age = extractFCParams(512, 1, "fc/age"); + const gender = extractFCParams(512, 2, "fc/gender"); + if (getRemainingWeights().length !== 0) { + throw new Error(`weights remaing after extract: ${getRemainingWeights().length}`); + } + return { + paramMappings, + params: { fc: { age, gender } } + }; +} + +// src/ageGenderNet/extractParamsFromWeightMap.ts +function extractParamsFromWeightMap4(weightMap) { + const paramMappings = []; + const extractWeightEntry = extractWeightEntryFactory(weightMap, paramMappings); + function extractFcParams(prefix) { + const weights = extractWeightEntry(`${prefix}/weights`, 2); + const bias = extractWeightEntry(`${prefix}/bias`, 1); + return { weights, bias }; + } + const params = { + fc: { + age: extractFcParams("fc/age"), + gender: extractFcParams("fc/gender") + } + }; + disposeUnusedWeightTensors(weightMap, paramMappings); + return { params, paramMappings }; +} + +// src/ageGenderNet/types.ts +var Gender; +(function(Gender2) { + Gender2["FEMALE"] = "female"; + Gender2["MALE"] = "male"; +})(Gender || (Gender = {})); + +// src/ageGenderNet/AgeGenderNet.ts +var AgeGenderNet = class extends NeuralNetwork { + constructor(faceFeatureExtractor = new TinyXception(2)) { + super("AgeGenderNet"); + this._faceFeatureExtractor = faceFeatureExtractor; + } + get faceFeatureExtractor() { + return this._faceFeatureExtractor; + } + runNet(input) { + const { params } = this; + if (!params) { + throw new Error(`${this._name} - load model before inference`); + } + return tf20.tidy(() => { + const bottleneckFeatures = input instanceof NetInput ? this.faceFeatureExtractor.forwardInput(input) : input; + const pooled = tf20.avgPool(bottleneckFeatures, [7, 7], [2, 2], "valid").as2D(bottleneckFeatures.shape[0], -1); + const age = fullyConnectedLayer(pooled, params.fc.age).as1D(); + const gender = fullyConnectedLayer(pooled, params.fc.gender); + return { age, gender }; + }); + } + forwardInput(input) { + return tf20.tidy(() => { + const { age, gender } = this.runNet(input); + return { age, gender: tf20.softmax(gender) }; + }); + } + async forward(input) { + return this.forwardInput(await toNetInput(input)); + } + async predictAgeAndGender(input) { + const netInput = await toNetInput(input); + const out = await this.forwardInput(netInput); + const ages = tf20.unstack(out.age); + const genders = tf20.unstack(out.gender); + const ageAndGenderTensors = ages.map((ageTensor, i) => ({ + ageTensor, + genderTensor: genders[i] + })); + const predictionsByBatch = await Promise.all(ageAndGenderTensors.map(async ({ ageTensor, genderTensor }) => { + const age = ageTensor.dataSync()[0]; + const probMale = genderTensor.dataSync()[0]; + const isMale = probMale > 0.5; + const gender = isMale ? Gender.MALE : Gender.FEMALE; + const genderProbability = isMale ? probMale : 1 - probMale; + ageTensor.dispose(); + genderTensor.dispose(); + return { age, gender, genderProbability }; + })); + out.age.dispose(); + out.gender.dispose(); + return netInput.isBatchInput ? predictionsByBatch : predictionsByBatch[0]; + } + getDefaultModelName() { + return "age_gender_model"; + } + dispose(throwOnRedispose = true) { + this.faceFeatureExtractor.dispose(throwOnRedispose); + super.dispose(throwOnRedispose); + } + loadClassifierParams(weights) { + const { params, paramMappings } = this.extractClassifierParams(weights); + this._params = params; + this._paramMappings = paramMappings; + } + extractClassifierParams(weights) { + return extractParams4(weights); + } + extractParamsFromWeightMap(weightMap) { + const { featureExtractorMap, classifierMap } = seperateWeightMaps(weightMap); + this.faceFeatureExtractor.loadFromWeightMap(featureExtractorMap); + return extractParamsFromWeightMap4(classifierMap); + } + extractParams(weights) { + const classifierWeightSize = 512 * 1 + 1 + (512 * 2 + 2); + const featureExtractorWeights = weights.slice(0, weights.length - classifierWeightSize); + const classifierWeights = weights.slice(weights.length - classifierWeightSize); + this.faceFeatureExtractor.extractWeights(featureExtractorWeights); + return this.extractClassifierParams(classifierWeights); + } +}; + +// src/faceLandmarkNet/FaceLandmark68NetBase.ts +var tf21 = __toModule(require_tfjs_esm()); +var FaceLandmark68NetBase = class extends FaceProcessor { + postProcess(output, inputSize, originalDimensions) { + const inputDimensions = originalDimensions.map(({ width, height }) => { + const scale2 = inputSize / Math.max(height, width); + return { + width: width * scale2, + height: height * scale2 + }; + }); + const batchSize = inputDimensions.length; + return tf21.tidy(() => { + const createInterleavedTensor = (fillX, fillY) => tf21.stack([tf21.fill([68], fillX, "float32"), tf21.fill([68], fillY, "float32")], 1).as2D(1, 136).as1D(); + const getPadding = (batchIdx, cond) => { + const { width, height } = inputDimensions[batchIdx]; + return cond(width, height) ? Math.abs(width - height) / 2 : 0; + }; + const getPaddingX = (batchIdx) => getPadding(batchIdx, (w, h) => w < h); + const getPaddingY = (batchIdx) => getPadding(batchIdx, (w, h) => h < w); + const landmarkTensors = output.mul(tf21.fill([batchSize, 136], inputSize, "float32")).sub(tf21.stack(Array.from(Array(batchSize), (_, batchIdx) => createInterleavedTensor(getPaddingX(batchIdx), getPaddingY(batchIdx))))).div(tf21.stack(Array.from(Array(batchSize), (_, batchIdx) => createInterleavedTensor(inputDimensions[batchIdx].width, inputDimensions[batchIdx].height)))); + return landmarkTensors; + }); + } + forwardInput(input) { + return tf21.tidy(() => { + const out = this.runNet(input); + return this.postProcess(out, input.inputSize, input.inputDimensions.map(([height, width]) => ({ height, width }))); + }); + } + async forward(input) { + return this.forwardInput(await toNetInput(input)); + } + async detectLandmarks(input) { + const netInput = await toNetInput(input); + const landmarkTensors = tf21.tidy(() => tf21.unstack(this.forwardInput(netInput))); + const landmarksForBatch = await Promise.all(landmarkTensors.map(async (landmarkTensor, batchIdx) => { + const landmarksArray = Array.from(landmarkTensor.dataSync()); + const xCoords = landmarksArray.filter((_, i) => isEven(i)); + const yCoords = landmarksArray.filter((_, i) => !isEven(i)); + return new FaceLandmarks68(Array(68).fill(0).map((_, i) => new Point(xCoords[i], yCoords[i])), { + height: netInput.getInputHeight(batchIdx), + width: netInput.getInputWidth(batchIdx) + }); + })); + landmarkTensors.forEach((t) => t.dispose()); + return netInput.isBatchInput ? landmarksForBatch : landmarksForBatch[0]; + } + getClassifierChannelsOut() { + return 136; + } +}; + +// src/faceLandmarkNet/FaceLandmark68Net.ts +var FaceLandmark68Net = class extends FaceLandmark68NetBase { + constructor(faceFeatureExtractor = new FaceFeatureExtractor()) { + super("FaceLandmark68Net", faceFeatureExtractor); + } + getDefaultModelName() { + return "face_landmark_68_model"; + } + getClassifierChannelsIn() { + return 256; + } +}; + +// src/faceFeatureExtractor/TinyFaceFeatureExtractor.ts +var tf22 = __toModule(require_tfjs_esm()); + +// src/faceFeatureExtractor/extractParamsFromWeightMapTiny.ts +function extractParamsFromWeightMapTiny(weightMap) { + const paramMappings = []; + const { + extractDenseBlock3Params + } = loadParamsFactory(weightMap, paramMappings); + const params = { + dense0: extractDenseBlock3Params("dense0", true), + dense1: extractDenseBlock3Params("dense1"), + dense2: extractDenseBlock3Params("dense2") + }; + disposeUnusedWeightTensors(weightMap, paramMappings); + return { params, paramMappings }; +} + +// src/faceFeatureExtractor/extractParamsTiny.ts +function extractParamsTiny(weights) { + const paramMappings = []; + const { + extractWeights, + getRemainingWeights + } = extractWeightsFactory(weights); + const { + extractDenseBlock3Params + } = extractorsFactory(extractWeights, paramMappings); + const dense0 = extractDenseBlock3Params(3, 32, "dense0", true); + const dense1 = extractDenseBlock3Params(32, 64, "dense1"); + const dense2 = extractDenseBlock3Params(64, 128, "dense2"); + if (getRemainingWeights().length !== 0) { + throw new Error(`weights remaing after extract: ${getRemainingWeights().length}`); + } + return { + paramMappings, + params: { dense0, dense1, dense2 } + }; +} + +// src/faceFeatureExtractor/TinyFaceFeatureExtractor.ts +var TinyFaceFeatureExtractor = class extends NeuralNetwork { + constructor() { + super("TinyFaceFeatureExtractor"); + } + forwardInput(input) { + const { params } = this; + if (!params) { + throw new Error("TinyFaceFeatureExtractor - load model before inference"); + } + return tf22.tidy(() => { + const batchTensor = tf22.cast(input.toBatchTensor(112, true), "float32"); + const meanRgb = [122.782, 117.001, 104.298]; + const normalized = normalize(batchTensor, meanRgb).div(255); + let out = denseBlock3(normalized, params.dense0, true); + out = denseBlock3(out, params.dense1); + out = denseBlock3(out, params.dense2); + out = tf22.avgPool(out, [14, 14], [2, 2], "valid"); + return out; + }); + } + async forward(input) { + return this.forwardInput(await toNetInput(input)); + } + getDefaultModelName() { + return "face_feature_extractor_tiny_model"; + } + extractParamsFromWeightMap(weightMap) { + return extractParamsFromWeightMapTiny(weightMap); + } + extractParams(weights) { + return extractParamsTiny(weights); + } +}; + +// src/faceLandmarkNet/FaceLandmark68TinyNet.ts +var FaceLandmark68TinyNet = class extends FaceLandmark68NetBase { + constructor(faceFeatureExtractor = new TinyFaceFeatureExtractor()) { + super("FaceLandmark68TinyNet", faceFeatureExtractor); + } + getDefaultModelName() { + return "face_landmark_68_tiny_model"; + } + getClassifierChannelsIn() { + return 128; + } +}; + +// src/faceLandmarkNet/index.ts +var FaceLandmarkNet = class extends FaceLandmark68Net { +}; + +// src/faceRecognitionNet/FaceRecognitionNet.ts +var tf27 = __toModule(require_tfjs_esm()); + +// src/faceRecognitionNet/convLayer.ts +var tf24 = __toModule(require_tfjs_esm()); + +// src/faceRecognitionNet/scaleLayer.ts +var tf23 = __toModule(require_tfjs_esm()); +function scale(x, params) { + return tf23.add(tf23.mul(x, params.weights), params.biases); +} + +// src/faceRecognitionNet/convLayer.ts +function convLayer2(x, params, strides, withRelu, padding = "same") { + const { filters, bias } = params.conv; + let out = tf24.conv2d(x, filters, strides, padding); + out = tf24.add(out, bias); + out = scale(out, params.scale); + return withRelu ? tf24.relu(out) : out; +} +function conv2(x, params) { + return convLayer2(x, params, [1, 1], true); +} +function convNoRelu(x, params) { + return convLayer2(x, params, [1, 1], false); +} +function convDown(x, params) { + return convLayer2(x, params, [2, 2], true, "valid"); +} + +// src/faceRecognitionNet/extractParams.ts +var tf25 = __toModule(require_tfjs_esm()); +function extractorsFactory3(extractWeights, paramMappings) { + function extractFilterValues(numFilterValues, numFilters, filterSize) { + const weights = extractWeights(numFilterValues); + const depth = weights.length / (numFilters * filterSize * filterSize); + if (isFloat(depth)) { + throw new Error(`depth has to be an integer: ${depth}, weights.length: ${weights.length}, numFilters: ${numFilters}, filterSize: ${filterSize}`); + } + return tf25.tidy(() => tf25.transpose(tf25.tensor4d(weights, [numFilters, depth, filterSize, filterSize]), [2, 3, 1, 0])); + } + function extractConvParams(numFilterValues, numFilters, filterSize, mappedPrefix) { + const filters = extractFilterValues(numFilterValues, numFilters, filterSize); + const bias = tf25.tensor1d(extractWeights(numFilters)); + paramMappings.push({ paramPath: `${mappedPrefix}/filters` }, { paramPath: `${mappedPrefix}/bias` }); + return { filters, bias }; + } + function extractScaleLayerParams(numWeights, mappedPrefix) { + const weights = tf25.tensor1d(extractWeights(numWeights)); + const biases = tf25.tensor1d(extractWeights(numWeights)); + paramMappings.push({ paramPath: `${mappedPrefix}/weights` }, { paramPath: `${mappedPrefix}/biases` }); + return { + weights, + biases + }; + } + function extractConvLayerParams(numFilterValues, numFilters, filterSize, mappedPrefix) { + const conv3 = extractConvParams(numFilterValues, numFilters, filterSize, `${mappedPrefix}/conv`); + const scale2 = extractScaleLayerParams(numFilters, `${mappedPrefix}/scale`); + return { conv: conv3, scale: scale2 }; + } + function extractResidualLayerParams(numFilterValues, numFilters, filterSize, mappedPrefix, isDown = false) { + const conv1 = extractConvLayerParams((isDown ? 0.5 : 1) * numFilterValues, numFilters, filterSize, `${mappedPrefix}/conv1`); + const conv22 = extractConvLayerParams(numFilterValues, numFilters, filterSize, `${mappedPrefix}/conv2`); + return { conv1, conv2: conv22 }; + } + return { + extractConvLayerParams, + extractResidualLayerParams + }; +} +function extractParams5(weights) { + const { + extractWeights, + getRemainingWeights + } = extractWeightsFactory(weights); + const paramMappings = []; + const { + extractConvLayerParams, + extractResidualLayerParams + } = extractorsFactory3(extractWeights, paramMappings); + const conv32_down = extractConvLayerParams(4704, 32, 7, "conv32_down"); + const conv32_1 = extractResidualLayerParams(9216, 32, 3, "conv32_1"); + const conv32_2 = extractResidualLayerParams(9216, 32, 3, "conv32_2"); + const conv32_3 = extractResidualLayerParams(9216, 32, 3, "conv32_3"); + const conv64_down = extractResidualLayerParams(36864, 64, 3, "conv64_down", true); + const conv64_1 = extractResidualLayerParams(36864, 64, 3, "conv64_1"); + const conv64_2 = extractResidualLayerParams(36864, 64, 3, "conv64_2"); + const conv64_3 = extractResidualLayerParams(36864, 64, 3, "conv64_3"); + const conv128_down = extractResidualLayerParams(147456, 128, 3, "conv128_down", true); + const conv128_1 = extractResidualLayerParams(147456, 128, 3, "conv128_1"); + const conv128_2 = extractResidualLayerParams(147456, 128, 3, "conv128_2"); + const conv256_down = extractResidualLayerParams(589824, 256, 3, "conv256_down", true); + const conv256_1 = extractResidualLayerParams(589824, 256, 3, "conv256_1"); + const conv256_2 = extractResidualLayerParams(589824, 256, 3, "conv256_2"); + const conv256_down_out = extractResidualLayerParams(589824, 256, 3, "conv256_down_out"); + const fc = tf25.tidy(() => tf25.transpose(tf25.tensor2d(extractWeights(256 * 128), [128, 256]), [1, 0])); + paramMappings.push({ paramPath: "fc" }); + if (getRemainingWeights().length !== 0) { + throw new Error(`weights remaing after extract: ${getRemainingWeights().length}`); + } + const params = { + conv32_down, + conv32_1, + conv32_2, + conv32_3, + conv64_down, + conv64_1, + conv64_2, + conv64_3, + conv128_down, + conv128_1, + conv128_2, + conv256_down, + conv256_1, + conv256_2, + conv256_down_out, + fc + }; + return { params, paramMappings }; +} + +// src/faceRecognitionNet/extractParamsFromWeightMap.ts +function extractorsFactory4(weightMap, paramMappings) { + const extractWeightEntry = extractWeightEntryFactory(weightMap, paramMappings); + function extractScaleLayerParams(prefix) { + const weights = extractWeightEntry(`${prefix}/scale/weights`, 1); + const biases = extractWeightEntry(`${prefix}/scale/biases`, 1); + return { weights, biases }; + } + function extractConvLayerParams(prefix) { + const filters = extractWeightEntry(`${prefix}/conv/filters`, 4); + const bias = extractWeightEntry(`${prefix}/conv/bias`, 1); + const scale2 = extractScaleLayerParams(prefix); + return { conv: { filters, bias }, scale: scale2 }; + } + function extractResidualLayerParams(prefix) { + return { + conv1: extractConvLayerParams(`${prefix}/conv1`), + conv2: extractConvLayerParams(`${prefix}/conv2`) + }; + } + return { + extractConvLayerParams, + extractResidualLayerParams + }; +} +function extractParamsFromWeightMap5(weightMap) { + const paramMappings = []; + const { + extractConvLayerParams, + extractResidualLayerParams + } = extractorsFactory4(weightMap, paramMappings); + const conv32_down = extractConvLayerParams("conv32_down"); + const conv32_1 = extractResidualLayerParams("conv32_1"); + const conv32_2 = extractResidualLayerParams("conv32_2"); + const conv32_3 = extractResidualLayerParams("conv32_3"); + const conv64_down = extractResidualLayerParams("conv64_down"); + const conv64_1 = extractResidualLayerParams("conv64_1"); + const conv64_2 = extractResidualLayerParams("conv64_2"); + const conv64_3 = extractResidualLayerParams("conv64_3"); + const conv128_down = extractResidualLayerParams("conv128_down"); + const conv128_1 = extractResidualLayerParams("conv128_1"); + const conv128_2 = extractResidualLayerParams("conv128_2"); + const conv256_down = extractResidualLayerParams("conv256_down"); + const conv256_1 = extractResidualLayerParams("conv256_1"); + const conv256_2 = extractResidualLayerParams("conv256_2"); + const conv256_down_out = extractResidualLayerParams("conv256_down_out"); + const { fc } = weightMap; + paramMappings.push({ originalPath: "fc", paramPath: "fc" }); + if (!isTensor2D(fc)) { + throw new Error(`expected weightMap[fc] to be a Tensor2D, instead have ${fc}`); + } + const params = { + conv32_down, + conv32_1, + conv32_2, + conv32_3, + conv64_down, + conv64_1, + conv64_2, + conv64_3, + conv128_down, + conv128_1, + conv128_2, + conv256_down, + conv256_1, + conv256_2, + conv256_down_out, + fc + }; + disposeUnusedWeightTensors(weightMap, paramMappings); + return { params, paramMappings }; +} + +// src/faceRecognitionNet/residualLayer.ts +var tf26 = __toModule(require_tfjs_esm()); +function residual(x, params) { + let out = conv2(x, params.conv1); + out = convNoRelu(out, params.conv2); + out = tf26.add(out, x); + out = tf26.relu(out); + return out; +} +function residualDown(x, params) { + let out = convDown(x, params.conv1); + out = convNoRelu(out, params.conv2); + let pooled = tf26.avgPool(x, 2, 2, "valid"); + const zeros2 = tf26.zeros(pooled.shape); + const isPad = pooled.shape[3] !== out.shape[3]; + const isAdjustShape = pooled.shape[1] !== out.shape[1] || pooled.shape[2] !== out.shape[2]; + if (isAdjustShape) { + const padShapeX = [...out.shape]; + padShapeX[1] = 1; + const zerosW = tf26.zeros(padShapeX); + out = tf26.concat([out, zerosW], 1); + const padShapeY = [...out.shape]; + padShapeY[2] = 1; + const zerosH = tf26.zeros(padShapeY); + out = tf26.concat([out, zerosH], 2); + } + pooled = isPad ? tf26.concat([pooled, zeros2], 3) : pooled; + out = tf26.add(pooled, out); + out = tf26.relu(out); + return out; +} + +// src/faceRecognitionNet/FaceRecognitionNet.ts +var FaceRecognitionNet = class extends NeuralNetwork { + constructor() { + super("FaceRecognitionNet"); + } + forwardInput(input) { + const { params } = this; + if (!params) { + throw new Error("FaceRecognitionNet - load model before inference"); + } + return tf27.tidy(() => { + const batchTensor = tf27.cast(input.toBatchTensor(150, true), "float32"); + const meanRgb = [122.782, 117.001, 104.298]; + const normalized = normalize(batchTensor, meanRgb).div(255); + let out = convDown(normalized, params.conv32_down); + out = tf27.maxPool(out, 3, 2, "valid"); + out = residual(out, params.conv32_1); + out = residual(out, params.conv32_2); + out = residual(out, params.conv32_3); + out = residualDown(out, params.conv64_down); + out = residual(out, params.conv64_1); + out = residual(out, params.conv64_2); + out = residual(out, params.conv64_3); + out = residualDown(out, params.conv128_down); + out = residual(out, params.conv128_1); + out = residual(out, params.conv128_2); + out = residualDown(out, params.conv256_down); + out = residual(out, params.conv256_1); + out = residual(out, params.conv256_2); + out = residualDown(out, params.conv256_down_out); + const globalAvg = out.mean([1, 2]); + const fullyConnected = tf27.matMul(globalAvg, params.fc); + return fullyConnected; + }); + } + async forward(input) { + return this.forwardInput(await toNetInput(input)); + } + async computeFaceDescriptor(input) { + var _a; + if ((_a = input == null ? void 0 : input.shape) == null ? void 0 : _a.some((dim) => dim <= 0)) + return new Float32Array(128); + const netInput = await toNetInput(input); + const faceDescriptorTensors = tf27.tidy(() => tf27.unstack(this.forwardInput(netInput))); + const faceDescriptorsForBatch = await Promise.all(faceDescriptorTensors.map((t) => t.data())); + faceDescriptorTensors.forEach((t) => t.dispose()); + return netInput.isBatchInput ? faceDescriptorsForBatch : faceDescriptorsForBatch[0]; + } + getDefaultModelName() { + return "face_recognition_model"; + } + extractParamsFromWeightMap(weightMap) { + return extractParamsFromWeightMap5(weightMap); + } + extractParams(weights) { + return extractParams5(weights); + } +}; + +// src/faceRecognitionNet/index.ts +function createFaceRecognitionNet(weights) { + const net = new FaceRecognitionNet(); + net.extractWeights(weights); + return net; +} + +// src/factories/WithFaceDescriptor.ts +function extendWithFaceDescriptor(sourceObj, descriptor) { + const extension = { descriptor }; + return { ...sourceObj, ...extension }; +} + +// src/factories/WithAge.ts +function isWithAge(obj) { + return typeof obj.age === "number"; +} +function extendWithAge(sourceObj, age) { + const extension = { age }; + return { ...sourceObj, ...extension }; +} + +// src/factories/WithGender.ts +function isWithGender(obj) { + return (obj.gender === Gender.MALE || obj.gender === Gender.FEMALE) && isValidProbablitiy(obj.genderProbability); +} +function extendWithGender(sourceObj, gender, genderProbability) { + const extension = { gender, genderProbability }; + return { ...sourceObj, ...extension }; +} + +// src/ssdMobilenetv1/SsdMobilenetv1.ts +var tf34 = __toModule(require_tfjs_esm()); + +// src/ssdMobilenetv1/extractParams.ts +var tf28 = __toModule(require_tfjs_esm()); +function extractorsFactory5(extractWeights, paramMappings) { + function extractDepthwiseConvParams(numChannels, mappedPrefix) { + const filters = tf28.tensor4d(extractWeights(3 * 3 * numChannels), [3, 3, numChannels, 1]); + const batch_norm_scale = tf28.tensor1d(extractWeights(numChannels)); + const batch_norm_offset = tf28.tensor1d(extractWeights(numChannels)); + const batch_norm_mean = tf28.tensor1d(extractWeights(numChannels)); + const batch_norm_variance = tf28.tensor1d(extractWeights(numChannels)); + paramMappings.push({ paramPath: `${mappedPrefix}/filters` }, { paramPath: `${mappedPrefix}/batch_norm_scale` }, { paramPath: `${mappedPrefix}/batch_norm_offset` }, { paramPath: `${mappedPrefix}/batch_norm_mean` }, { paramPath: `${mappedPrefix}/batch_norm_variance` }); + return { + filters, + batch_norm_scale, + batch_norm_offset, + batch_norm_mean, + batch_norm_variance + }; + } + function extractConvParams(channelsIn, channelsOut, filterSize, mappedPrefix, isPointwiseConv) { + const filters = tf28.tensor4d(extractWeights(channelsIn * channelsOut * filterSize * filterSize), [filterSize, filterSize, channelsIn, channelsOut]); + const bias = tf28.tensor1d(extractWeights(channelsOut)); + paramMappings.push({ paramPath: `${mappedPrefix}/filters` }, { paramPath: `${mappedPrefix}/${isPointwiseConv ? "batch_norm_offset" : "bias"}` }); + return { filters, bias }; + } + function extractPointwiseConvParams(channelsIn, channelsOut, filterSize, mappedPrefix) { + const { + filters, + bias + } = extractConvParams(channelsIn, channelsOut, filterSize, mappedPrefix, true); + return { + filters, + batch_norm_offset: bias + }; + } + function extractConvPairParams(channelsIn, channelsOut, mappedPrefix) { + const depthwise_conv = extractDepthwiseConvParams(channelsIn, `${mappedPrefix}/depthwise_conv`); + const pointwise_conv = extractPointwiseConvParams(channelsIn, channelsOut, 1, `${mappedPrefix}/pointwise_conv`); + return { depthwise_conv, pointwise_conv }; + } + function extractMobilenetV1Params() { + const conv_0 = extractPointwiseConvParams(3, 32, 3, "mobilenetv1/conv_0"); + const conv_1 = extractConvPairParams(32, 64, "mobilenetv1/conv_1"); + const conv_2 = extractConvPairParams(64, 128, "mobilenetv1/conv_2"); + const conv_3 = extractConvPairParams(128, 128, "mobilenetv1/conv_3"); + const conv_4 = extractConvPairParams(128, 256, "mobilenetv1/conv_4"); + const conv_5 = extractConvPairParams(256, 256, "mobilenetv1/conv_5"); + const conv_6 = extractConvPairParams(256, 512, "mobilenetv1/conv_6"); + const conv_7 = extractConvPairParams(512, 512, "mobilenetv1/conv_7"); + const conv_8 = extractConvPairParams(512, 512, "mobilenetv1/conv_8"); + const conv_9 = extractConvPairParams(512, 512, "mobilenetv1/conv_9"); + const conv_10 = extractConvPairParams(512, 512, "mobilenetv1/conv_10"); + const conv_11 = extractConvPairParams(512, 512, "mobilenetv1/conv_11"); + const conv_12 = extractConvPairParams(512, 1024, "mobilenetv1/conv_12"); + const conv_13 = extractConvPairParams(1024, 1024, "mobilenetv1/conv_13"); + return { + conv_0, + conv_1, + conv_2, + conv_3, + conv_4, + conv_5, + conv_6, + conv_7, + conv_8, + conv_9, + conv_10, + conv_11, + conv_12, + conv_13 + }; + } + function extractPredictionLayerParams() { + const conv_0 = extractPointwiseConvParams(1024, 256, 1, "prediction_layer/conv_0"); + const conv_1 = extractPointwiseConvParams(256, 512, 3, "prediction_layer/conv_1"); + const conv_2 = extractPointwiseConvParams(512, 128, 1, "prediction_layer/conv_2"); + const conv_3 = extractPointwiseConvParams(128, 256, 3, "prediction_layer/conv_3"); + const conv_4 = extractPointwiseConvParams(256, 128, 1, "prediction_layer/conv_4"); + const conv_5 = extractPointwiseConvParams(128, 256, 3, "prediction_layer/conv_5"); + const conv_6 = extractPointwiseConvParams(256, 64, 1, "prediction_layer/conv_6"); + const conv_7 = extractPointwiseConvParams(64, 128, 3, "prediction_layer/conv_7"); + const box_encoding_0_predictor = extractConvParams(512, 12, 1, "prediction_layer/box_predictor_0/box_encoding_predictor"); + const class_predictor_0 = extractConvParams(512, 9, 1, "prediction_layer/box_predictor_0/class_predictor"); + const box_encoding_1_predictor = extractConvParams(1024, 24, 1, "prediction_layer/box_predictor_1/box_encoding_predictor"); + const class_predictor_1 = extractConvParams(1024, 18, 1, "prediction_layer/box_predictor_1/class_predictor"); + const box_encoding_2_predictor = extractConvParams(512, 24, 1, "prediction_layer/box_predictor_2/box_encoding_predictor"); + const class_predictor_2 = extractConvParams(512, 18, 1, "prediction_layer/box_predictor_2/class_predictor"); + const box_encoding_3_predictor = extractConvParams(256, 24, 1, "prediction_layer/box_predictor_3/box_encoding_predictor"); + const class_predictor_3 = extractConvParams(256, 18, 1, "prediction_layer/box_predictor_3/class_predictor"); + const box_encoding_4_predictor = extractConvParams(256, 24, 1, "prediction_layer/box_predictor_4/box_encoding_predictor"); + const class_predictor_4 = extractConvParams(256, 18, 1, "prediction_layer/box_predictor_4/class_predictor"); + const box_encoding_5_predictor = extractConvParams(128, 24, 1, "prediction_layer/box_predictor_5/box_encoding_predictor"); + const class_predictor_5 = extractConvParams(128, 18, 1, "prediction_layer/box_predictor_5/class_predictor"); + const box_predictor_0 = { + box_encoding_predictor: box_encoding_0_predictor, + class_predictor: class_predictor_0 + }; + const box_predictor_1 = { + box_encoding_predictor: box_encoding_1_predictor, + class_predictor: class_predictor_1 + }; + const box_predictor_2 = { + box_encoding_predictor: box_encoding_2_predictor, + class_predictor: class_predictor_2 + }; + const box_predictor_3 = { + box_encoding_predictor: box_encoding_3_predictor, + class_predictor: class_predictor_3 + }; + const box_predictor_4 = { + box_encoding_predictor: box_encoding_4_predictor, + class_predictor: class_predictor_4 + }; + const box_predictor_5 = { + box_encoding_predictor: box_encoding_5_predictor, + class_predictor: class_predictor_5 + }; + return { + conv_0, + conv_1, + conv_2, + conv_3, + conv_4, + conv_5, + conv_6, + conv_7, + box_predictor_0, + box_predictor_1, + box_predictor_2, + box_predictor_3, + box_predictor_4, + box_predictor_5 + }; + } + return { + extractMobilenetV1Params, + extractPredictionLayerParams + }; +} +function extractParams6(weights) { + const paramMappings = []; + const { + extractWeights, + getRemainingWeights + } = extractWeightsFactory(weights); + const { + extractMobilenetV1Params, + extractPredictionLayerParams + } = extractorsFactory5(extractWeights, paramMappings); + const mobilenetv1 = extractMobilenetV1Params(); + const prediction_layer = extractPredictionLayerParams(); + const extra_dim = tf28.tensor3d(extractWeights(5118 * 4), [1, 5118, 4]); + const output_layer = { + extra_dim + }; + paramMappings.push({ paramPath: "output_layer/extra_dim" }); + if (getRemainingWeights().length !== 0) { + throw new Error(`weights remaing after extract: ${getRemainingWeights().length}`); + } + return { + params: { + mobilenetv1, + prediction_layer, + output_layer + }, + paramMappings + }; +} + +// src/ssdMobilenetv1/extractParamsFromWeightMap.ts +function extractorsFactory6(weightMap, paramMappings) { + const extractWeightEntry = extractWeightEntryFactory(weightMap, paramMappings); + function extractPointwiseConvParams(prefix, idx, mappedPrefix) { + const filters = extractWeightEntry(`${prefix}/Conv2d_${idx}_pointwise/weights`, 4, `${mappedPrefix}/filters`); + const batch_norm_offset = extractWeightEntry(`${prefix}/Conv2d_${idx}_pointwise/convolution_bn_offset`, 1, `${mappedPrefix}/batch_norm_offset`); + return { filters, batch_norm_offset }; + } + function extractConvPairParams(idx) { + const mappedPrefix = `mobilenetv1/conv_${idx}`; + const prefixDepthwiseConv = `MobilenetV1/Conv2d_${idx}_depthwise`; + const mappedPrefixDepthwiseConv = `${mappedPrefix}/depthwise_conv`; + const mappedPrefixPointwiseConv = `${mappedPrefix}/pointwise_conv`; + const filters = extractWeightEntry(`${prefixDepthwiseConv}/depthwise_weights`, 4, `${mappedPrefixDepthwiseConv}/filters`); + const batch_norm_scale = extractWeightEntry(`${prefixDepthwiseConv}/BatchNorm/gamma`, 1, `${mappedPrefixDepthwiseConv}/batch_norm_scale`); + const batch_norm_offset = extractWeightEntry(`${prefixDepthwiseConv}/BatchNorm/beta`, 1, `${mappedPrefixDepthwiseConv}/batch_norm_offset`); + const batch_norm_mean = extractWeightEntry(`${prefixDepthwiseConv}/BatchNorm/moving_mean`, 1, `${mappedPrefixDepthwiseConv}/batch_norm_mean`); + const batch_norm_variance = extractWeightEntry(`${prefixDepthwiseConv}/BatchNorm/moving_variance`, 1, `${mappedPrefixDepthwiseConv}/batch_norm_variance`); + return { + depthwise_conv: { + filters, + batch_norm_scale, + batch_norm_offset, + batch_norm_mean, + batch_norm_variance + }, + pointwise_conv: extractPointwiseConvParams("MobilenetV1", idx, mappedPrefixPointwiseConv) + }; + } + function extractMobilenetV1Params() { + return { + conv_0: extractPointwiseConvParams("MobilenetV1", 0, "mobilenetv1/conv_0"), + conv_1: extractConvPairParams(1), + conv_2: extractConvPairParams(2), + conv_3: extractConvPairParams(3), + conv_4: extractConvPairParams(4), + conv_5: extractConvPairParams(5), + conv_6: extractConvPairParams(6), + conv_7: extractConvPairParams(7), + conv_8: extractConvPairParams(8), + conv_9: extractConvPairParams(9), + conv_10: extractConvPairParams(10), + conv_11: extractConvPairParams(11), + conv_12: extractConvPairParams(12), + conv_13: extractConvPairParams(13) + }; + } + function extractConvParams(prefix, mappedPrefix) { + const filters = extractWeightEntry(`${prefix}/weights`, 4, `${mappedPrefix}/filters`); + const bias = extractWeightEntry(`${prefix}/biases`, 1, `${mappedPrefix}/bias`); + return { filters, bias }; + } + function extractBoxPredictorParams(idx) { + const box_encoding_predictor = extractConvParams(`Prediction/BoxPredictor_${idx}/BoxEncodingPredictor`, `prediction_layer/box_predictor_${idx}/box_encoding_predictor`); + const class_predictor = extractConvParams(`Prediction/BoxPredictor_${idx}/ClassPredictor`, `prediction_layer/box_predictor_${idx}/class_predictor`); + return { box_encoding_predictor, class_predictor }; + } + function extractPredictionLayerParams() { + return { + conv_0: extractPointwiseConvParams("Prediction", 0, "prediction_layer/conv_0"), + conv_1: extractPointwiseConvParams("Prediction", 1, "prediction_layer/conv_1"), + conv_2: extractPointwiseConvParams("Prediction", 2, "prediction_layer/conv_2"), + conv_3: extractPointwiseConvParams("Prediction", 3, "prediction_layer/conv_3"), + conv_4: extractPointwiseConvParams("Prediction", 4, "prediction_layer/conv_4"), + conv_5: extractPointwiseConvParams("Prediction", 5, "prediction_layer/conv_5"), + conv_6: extractPointwiseConvParams("Prediction", 6, "prediction_layer/conv_6"), + conv_7: extractPointwiseConvParams("Prediction", 7, "prediction_layer/conv_7"), + box_predictor_0: extractBoxPredictorParams(0), + box_predictor_1: extractBoxPredictorParams(1), + box_predictor_2: extractBoxPredictorParams(2), + box_predictor_3: extractBoxPredictorParams(3), + box_predictor_4: extractBoxPredictorParams(4), + box_predictor_5: extractBoxPredictorParams(5) + }; + } + return { + extractMobilenetV1Params, + extractPredictionLayerParams + }; +} +function extractParamsFromWeightMap6(weightMap) { + const paramMappings = []; + const { + extractMobilenetV1Params, + extractPredictionLayerParams + } = extractorsFactory6(weightMap, paramMappings); + const extra_dim = weightMap["Output/extra_dim"]; + paramMappings.push({ originalPath: "Output/extra_dim", paramPath: "output_layer/extra_dim" }); + if (!isTensor3D(extra_dim)) { + throw new Error(`expected weightMap['Output/extra_dim'] to be a Tensor3D, instead have ${extra_dim}`); + } + const params = { + mobilenetv1: extractMobilenetV1Params(), + prediction_layer: extractPredictionLayerParams(), + output_layer: { + extra_dim + } + }; + disposeUnusedWeightTensors(weightMap, paramMappings); + return { params, paramMappings }; +} + +// src/ssdMobilenetv1/mobileNetV1.ts +var tf30 = __toModule(require_tfjs_esm()); + +// src/ssdMobilenetv1/pointwiseConvLayer.ts +var tf29 = __toModule(require_tfjs_esm()); +function pointwiseConvLayer(x, params, strides) { + return tf29.tidy(() => { + let out = tf29.conv2d(x, params.filters, strides, "same"); + out = tf29.add(out, params.batch_norm_offset); + return tf29.clipByValue(out, 0, 6); + }); +} + +// src/ssdMobilenetv1/mobileNetV1.ts +var epsilon = 0.0010000000474974513; +function depthwiseConvLayer(x, params, strides) { + return tf30.tidy(() => { + let out = tf30.depthwiseConv2d(x, params.filters, strides, "same"); + out = tf30.batchNorm(out, params.batch_norm_mean, params.batch_norm_variance, params.batch_norm_offset, params.batch_norm_scale, epsilon); + return tf30.clipByValue(out, 0, 6); + }); +} +function getStridesForLayerIdx(layerIdx) { + return [2, 4, 6, 12].some((idx) => idx === layerIdx) ? [2, 2] : [1, 1]; +} +function mobileNetV1(x, params) { + return tf30.tidy(() => { + let conv11; + let out = pointwiseConvLayer(x, params.conv_0, [2, 2]); + const convPairParams = [ + params.conv_1, + params.conv_2, + params.conv_3, + params.conv_4, + params.conv_5, + params.conv_6, + params.conv_7, + params.conv_8, + params.conv_9, + params.conv_10, + params.conv_11, + params.conv_12, + params.conv_13 + ]; + convPairParams.forEach((param, i) => { + const layerIdx = i + 1; + const depthwiseConvStrides = getStridesForLayerIdx(layerIdx); + out = depthwiseConvLayer(out, param.depthwise_conv, depthwiseConvStrides); + out = pointwiseConvLayer(out, param.pointwise_conv, [1, 1]); + if (layerIdx === 11) + conv11 = out; + }); + if (conv11 === null) { + throw new Error("mobileNetV1 - output of conv layer 11 is null"); + } + return { + out, + conv11 + }; + }); +} + +// src/ssdMobilenetv1/nonMaxSuppression.ts +function IOU(boxes, i, j) { + const boxesData = boxes.arraySync(); + const yminI = Math.min(boxesData[i][0], boxesData[i][2]); + const xminI = Math.min(boxesData[i][1], boxesData[i][3]); + const ymaxI = Math.max(boxesData[i][0], boxesData[i][2]); + const xmaxI = Math.max(boxesData[i][1], boxesData[i][3]); + const yminJ = Math.min(boxesData[j][0], boxesData[j][2]); + const xminJ = Math.min(boxesData[j][1], boxesData[j][3]); + const ymaxJ = Math.max(boxesData[j][0], boxesData[j][2]); + const xmaxJ = Math.max(boxesData[j][1], boxesData[j][3]); + const areaI = (ymaxI - yminI) * (xmaxI - xminI); + const areaJ = (ymaxJ - yminJ) * (xmaxJ - xminJ); + if (areaI <= 0 || areaJ <= 0) + return 0; + const intersectionYmin = Math.max(yminI, yminJ); + const intersectionXmin = Math.max(xminI, xminJ); + const intersectionYmax = Math.min(ymaxI, ymaxJ); + const intersectionXmax = Math.min(xmaxI, xmaxJ); + const intersectionArea = Math.max(intersectionYmax - intersectionYmin, 0) * Math.max(intersectionXmax - intersectionXmin, 0); + return intersectionArea / (areaI + areaJ - intersectionArea); +} +function nonMaxSuppression2(boxes, scores, maxOutputSize, iouThreshold, scoreThreshold) { + const numBoxes = boxes.shape[0]; + const outputSize = Math.min(maxOutputSize, numBoxes); + const candidates = scores.map((score, boxIndex) => ({ score, boxIndex })).filter((c) => c.score > scoreThreshold).sort((c1, c2) => c2.score - c1.score); + const suppressFunc = (x) => x <= iouThreshold ? 1 : 0; + const selected = []; + candidates.forEach((c) => { + if (selected.length >= outputSize) + return; + const originalScore = c.score; + for (let j = selected.length - 1; j >= 0; --j) { + const iou2 = IOU(boxes, c.boxIndex, selected[j]); + if (iou2 === 0) + continue; + c.score *= suppressFunc(iou2); + if (c.score <= scoreThreshold) + break; + } + if (originalScore === c.score) { + selected.push(c.boxIndex); + } + }); + return selected; +} + +// src/ssdMobilenetv1/outputLayer.ts +var tf31 = __toModule(require_tfjs_esm()); +function getCenterCoordinatesAndSizesLayer(x) { + const vec = tf31.unstack(tf31.transpose(x, [1, 0])); + const sizes = [ + tf31.sub(vec[2], vec[0]), + tf31.sub(vec[3], vec[1]) + ]; + const centers = [ + tf31.add(vec[0], tf31.div(sizes[0], 2)), + tf31.add(vec[1], tf31.div(sizes[1], 2)) + ]; + return { sizes, centers }; +} +function decodeBoxesLayer(x0, x1) { + const { sizes, centers } = getCenterCoordinatesAndSizesLayer(x0); + const vec = tf31.unstack(tf31.transpose(x1, [1, 0])); + const div0_out = tf31.div(tf31.mul(tf31.exp(tf31.div(vec[2], 5)), sizes[0]), 2); + const add0_out = tf31.add(tf31.mul(tf31.div(vec[0], 10), sizes[0]), centers[0]); + const div1_out = tf31.div(tf31.mul(tf31.exp(tf31.div(vec[3], 5)), sizes[1]), 2); + const add1_out = tf31.add(tf31.mul(tf31.div(vec[1], 10), sizes[1]), centers[1]); + return tf31.transpose(tf31.stack([ + tf31.sub(add0_out, div0_out), + tf31.sub(add1_out, div1_out), + tf31.add(add0_out, div0_out), + tf31.add(add1_out, div1_out) + ]), [1, 0]); +} +function outputLayer(boxPredictions, classPredictions, params) { + return tf31.tidy(() => { + const batchSize = boxPredictions.shape[0]; + let boxes = decodeBoxesLayer(tf31.reshape(tf31.tile(params.extra_dim, [batchSize, 1, 1]), [-1, 4]), tf31.reshape(boxPredictions, [-1, 4])); + boxes = tf31.reshape(boxes, [batchSize, boxes.shape[0] / batchSize, 4]); + const scoresAndClasses = tf31.sigmoid(tf31.slice(classPredictions, [0, 0, 1], [-1, -1, -1])); + let scores = tf31.slice(scoresAndClasses, [0, 0, 0], [-1, -1, 1]); + scores = tf31.reshape(scores, [batchSize, scores.shape[1]]); + const boxesByBatch = tf31.unstack(boxes); + const scoresByBatch = tf31.unstack(scores); + return { boxes: boxesByBatch, scores: scoresByBatch }; + }); +} + +// src/ssdMobilenetv1/predictionLayer.ts +var tf33 = __toModule(require_tfjs_esm()); + +// src/ssdMobilenetv1/boxPredictionLayer.ts +var tf32 = __toModule(require_tfjs_esm()); +function boxPredictionLayer(x, params) { + return tf32.tidy(() => { + const batchSize = x.shape[0]; + const boxPredictionEncoding = tf32.reshape(convLayer(x, params.box_encoding_predictor), [batchSize, -1, 1, 4]); + const classPrediction = tf32.reshape(convLayer(x, params.class_predictor), [batchSize, -1, 3]); + return { boxPredictionEncoding, classPrediction }; + }); +} + +// src/ssdMobilenetv1/predictionLayer.ts +function predictionLayer(x, conv11, params) { + return tf33.tidy(() => { + const conv0 = pointwiseConvLayer(x, params.conv_0, [1, 1]); + const conv1 = pointwiseConvLayer(conv0, params.conv_1, [2, 2]); + const conv22 = pointwiseConvLayer(conv1, params.conv_2, [1, 1]); + const conv3 = pointwiseConvLayer(conv22, params.conv_3, [2, 2]); + const conv4 = pointwiseConvLayer(conv3, params.conv_4, [1, 1]); + const conv5 = pointwiseConvLayer(conv4, params.conv_5, [2, 2]); + const conv6 = pointwiseConvLayer(conv5, params.conv_6, [1, 1]); + const conv7 = pointwiseConvLayer(conv6, params.conv_7, [2, 2]); + const boxPrediction0 = boxPredictionLayer(conv11, params.box_predictor_0); + const boxPrediction1 = boxPredictionLayer(x, params.box_predictor_1); + const boxPrediction2 = boxPredictionLayer(conv1, params.box_predictor_2); + const boxPrediction3 = boxPredictionLayer(conv3, params.box_predictor_3); + const boxPrediction4 = boxPredictionLayer(conv5, params.box_predictor_4); + const boxPrediction5 = boxPredictionLayer(conv7, params.box_predictor_5); + const boxPredictions = tf33.concat([ + boxPrediction0.boxPredictionEncoding, + boxPrediction1.boxPredictionEncoding, + boxPrediction2.boxPredictionEncoding, + boxPrediction3.boxPredictionEncoding, + boxPrediction4.boxPredictionEncoding, + boxPrediction5.boxPredictionEncoding + ], 1); + const classPredictions = tf33.concat([ + boxPrediction0.classPrediction, + boxPrediction1.classPrediction, + boxPrediction2.classPrediction, + boxPrediction3.classPrediction, + boxPrediction4.classPrediction, + boxPrediction5.classPrediction + ], 1); + return { + boxPredictions, + classPredictions + }; + }); +} + +// src/ssdMobilenetv1/SsdMobilenetv1Options.ts +var SsdMobilenetv1Options = class { + constructor({ minConfidence, maxResults } = {}) { + this._name = "SsdMobilenetv1Options"; + this._minConfidence = minConfidence || 0.5; + this._maxResults = maxResults || 100; + if (typeof this._minConfidence !== "number" || this._minConfidence <= 0 || this._minConfidence >= 1) { + throw new Error(`${this._name} - expected minConfidence to be a number between 0 and 1`); + } + if (typeof this._maxResults !== "number") { + throw new Error(`${this._name} - expected maxResults to be a number`); + } + } + get minConfidence() { + return this._minConfidence; + } + get maxResults() { + return this._maxResults; + } +}; + +// src/ssdMobilenetv1/SsdMobilenetv1.ts +var SsdMobilenetv1 = class extends NeuralNetwork { + constructor() { + super("SsdMobilenetv1"); + } + forwardInput(input) { + const { params } = this; + if (!params) + throw new Error("SsdMobilenetv1 - load model before inference"); + return tf34.tidy(() => { + const batchTensor = tf34.cast(input.toBatchTensor(512, false), "float32"); + const x = tf34.sub(tf34.div(batchTensor, 127.5), 1); + const features = mobileNetV1(x, params.mobilenetv1); + const { boxPredictions, classPredictions } = predictionLayer(features.out, features.conv11, params.prediction_layer); + return outputLayer(boxPredictions, classPredictions, params.output_layer); + }); + } + async forward(input) { + return this.forwardInput(await toNetInput(input)); + } + async locateFaces(input, options = {}) { + const { maxResults, minConfidence } = new SsdMobilenetv1Options(options); + const netInput = await toNetInput(input); + const { boxes: _boxes, scores: _scores } = this.forwardInput(netInput); + const boxes = _boxes[0]; + const scores = _scores[0]; + for (let i = 1; i < _boxes.length; i++) { + _boxes[i].dispose(); + _scores[i].dispose(); + } + const scoresData = Array.from(scores.dataSync()); + const iouThreshold = 0.5; + const indices = nonMaxSuppression2(boxes, scoresData, maxResults, iouThreshold, minConfidence); + const reshapedDims = netInput.getReshapedInputDimensions(0); + const inputSize = netInput.inputSize; + const padX = inputSize / reshapedDims.width; + const padY = inputSize / reshapedDims.height; + const boxesData = boxes.arraySync(); + const results = indices.map((idx) => { + const [top, bottom] = [ + Math.max(0, boxesData[idx][0]), + Math.min(1, boxesData[idx][2]) + ].map((val) => val * padY); + const [left, right] = [ + Math.max(0, boxesData[idx][1]), + Math.min(1, boxesData[idx][3]) + ].map((val) => val * padX); + return new FaceDetection(scoresData[idx], new Rect(left, top, right - left, bottom - top), { height: netInput.getInputHeight(0), width: netInput.getInputWidth(0) }); + }); + boxes.dispose(); + scores.dispose(); + return results; + } + getDefaultModelName() { + return "ssd_mobilenetv1_model"; + } + extractParamsFromWeightMap(weightMap) { + return extractParamsFromWeightMap6(weightMap); + } + extractParams(weights) { + return extractParams6(weights); + } +}; + +// src/ssdMobilenetv1/index.ts +function createSsdMobilenetv1(weights) { + const net = new SsdMobilenetv1(); + net.extractWeights(weights); + return net; +} +function createFaceDetectionNet(weights) { + return createSsdMobilenetv1(weights); +} +var FaceDetectionNet = class extends SsdMobilenetv1 { +}; + +// src/tinyYolov2/const.ts +var IOU_THRESHOLD = 0.4; +var BOX_ANCHORS = [ + new Point(0.738768, 0.874946), + new Point(2.42204, 2.65704), + new Point(4.30971, 7.04493), + new Point(10.246, 4.59428), + new Point(12.6868, 11.8741) +]; +var BOX_ANCHORS_SEPARABLE = [ + new Point(1.603231, 2.094468), + new Point(6.041143, 7.080126), + new Point(2.882459, 3.518061), + new Point(4.266906, 5.178857), + new Point(9.041765, 10.66308) +]; +var MEAN_RGB_SEPARABLE = [117.001, 114.697, 97.404]; +var DEFAULT_MODEL_NAME = "tiny_yolov2_model"; +var DEFAULT_MODEL_NAME_SEPARABLE_CONV = "tiny_yolov2_separable_conv_model"; + +// src/tinyYolov2/TinyYolov2Base.ts +var tf39 = __toModule(require_tfjs_esm()); + +// src/tinyYolov2/config.ts +var isNumber = (arg) => typeof arg === "number"; +function validateConfig(config) { + if (!config) { + throw new Error(`invalid config: ${config}`); + } + if (typeof config.withSeparableConvs !== "boolean") { + throw new Error(`config.withSeparableConvs has to be a boolean, have: ${config.withSeparableConvs}`); + } + if (!isNumber(config.iouThreshold) || config.iouThreshold < 0 || config.iouThreshold > 1) { + throw new Error(`config.iouThreshold has to be a number between [0, 1], have: ${config.iouThreshold}`); + } + if (!Array.isArray(config.classes) || !config.classes.length || !config.classes.every((c) => typeof c === "string")) { + throw new Error(`config.classes has to be an array class names: string[], have: ${JSON.stringify(config.classes)}`); + } + if (!Array.isArray(config.anchors) || !config.anchors.length || !config.anchors.map((a) => a || {}).every((a) => isNumber(a.x) && isNumber(a.y))) { + throw new Error(`config.anchors has to be an array of { x: number, y: number }, have: ${JSON.stringify(config.anchors)}`); + } + if (config.meanRgb && (!Array.isArray(config.meanRgb) || config.meanRgb.length !== 3 || !config.meanRgb.every(isNumber))) { + throw new Error(`config.meanRgb has to be an array of shape [number, number, number], have: ${JSON.stringify(config.meanRgb)}`); + } +} + +// src/tinyYolov2/convWithBatchNorm.ts +var tf36 = __toModule(require_tfjs_esm()); + +// src/tinyYolov2/leaky.ts +var tf35 = __toModule(require_tfjs_esm()); +function leaky(x) { + return tf35.tidy(() => { + const min = tf35.mul(x, tf35.scalar(0.10000000149011612)); + return tf35.add(tf35.relu(tf35.sub(x, min)), min); + }); +} + +// src/tinyYolov2/convWithBatchNorm.ts +function convWithBatchNorm(x, params) { + return tf36.tidy(() => { + let out = tf36.pad(x, [[0, 0], [1, 1], [1, 1], [0, 0]]); + out = tf36.conv2d(out, params.conv.filters, [1, 1], "valid"); + out = tf36.sub(out, params.bn.sub); + out = tf36.mul(out, params.bn.truediv); + out = tf36.add(out, params.conv.bias); + return leaky(out); + }); +} + +// src/tinyYolov2/depthwiseSeparableConv.ts +var tf37 = __toModule(require_tfjs_esm()); +function depthwiseSeparableConv2(x, params) { + return tf37.tidy(() => { + let out = tf37.pad(x, [[0, 0], [1, 1], [1, 1], [0, 0]]); + out = tf37.separableConv2d(out, params.depthwise_filter, params.pointwise_filter, [1, 1], "valid"); + out = tf37.add(out, params.bias); + return leaky(out); + }); +} + +// src/tinyYolov2/extractParams.ts +var tf38 = __toModule(require_tfjs_esm()); +function extractorsFactory7(extractWeights, paramMappings) { + const extractConvParams = extractConvParamsFactory(extractWeights, paramMappings); + function extractBatchNormParams(size, mappedPrefix) { + const sub6 = tf38.tensor1d(extractWeights(size)); + const truediv = tf38.tensor1d(extractWeights(size)); + paramMappings.push({ paramPath: `${mappedPrefix}/sub` }, { paramPath: `${mappedPrefix}/truediv` }); + return { sub: sub6, truediv }; + } + function extractConvWithBatchNormParams(channelsIn, channelsOut, mappedPrefix) { + const conv3 = extractConvParams(channelsIn, channelsOut, 3, `${mappedPrefix}/conv`); + const bn = extractBatchNormParams(channelsOut, `${mappedPrefix}/bn`); + return { conv: conv3, bn }; + } + const extractSeparableConvParams = extractSeparableConvParamsFactory(extractWeights, paramMappings); + return { + extractConvParams, + extractConvWithBatchNormParams, + extractSeparableConvParams + }; +} +function extractParams7(weights, config, boxEncodingSize, filterSizes) { + const { + extractWeights, + getRemainingWeights + } = extractWeightsFactory(weights); + const paramMappings = []; + const { + extractConvParams, + extractConvWithBatchNormParams, + extractSeparableConvParams + } = extractorsFactory7(extractWeights, paramMappings); + let params; + if (config.withSeparableConvs) { + const [s0, s1, s2, s3, s4, s5, s6, s7, s8] = filterSizes; + const conv0 = config.isFirstLayerConv2d ? extractConvParams(s0, s1, 3, "conv0") : extractSeparableConvParams(s0, s1, "conv0"); + const conv1 = extractSeparableConvParams(s1, s2, "conv1"); + const conv22 = extractSeparableConvParams(s2, s3, "conv2"); + const conv3 = extractSeparableConvParams(s3, s4, "conv3"); + const conv4 = extractSeparableConvParams(s4, s5, "conv4"); + const conv5 = extractSeparableConvParams(s5, s6, "conv5"); + const conv6 = s7 ? extractSeparableConvParams(s6, s7, "conv6") : void 0; + const conv7 = s8 ? extractSeparableConvParams(s7, s8, "conv7") : void 0; + const conv8 = extractConvParams(s8 || s7 || s6, 5 * boxEncodingSize, 1, "conv8"); + params = { + conv0, + conv1, + conv2: conv22, + conv3, + conv4, + conv5, + conv6, + conv7, + conv8 + }; + } else { + const [s0, s1, s2, s3, s4, s5, s6, s7, s8] = filterSizes; + const conv0 = extractConvWithBatchNormParams(s0, s1, "conv0"); + const conv1 = extractConvWithBatchNormParams(s1, s2, "conv1"); + const conv22 = extractConvWithBatchNormParams(s2, s3, "conv2"); + const conv3 = extractConvWithBatchNormParams(s3, s4, "conv3"); + const conv4 = extractConvWithBatchNormParams(s4, s5, "conv4"); + const conv5 = extractConvWithBatchNormParams(s5, s6, "conv5"); + const conv6 = extractConvWithBatchNormParams(s6, s7, "conv6"); + const conv7 = extractConvWithBatchNormParams(s7, s8, "conv7"); + const conv8 = extractConvParams(s8, 5 * boxEncodingSize, 1, "conv8"); + params = { + conv0, + conv1, + conv2: conv22, + conv3, + conv4, + conv5, + conv6, + conv7, + conv8 + }; + } + if (getRemainingWeights().length !== 0) { + throw new Error(`weights remaing after extract: ${getRemainingWeights().length}`); + } + return { params, paramMappings }; +} + +// src/tinyYolov2/extractParamsFromWeightMap.ts +function extractorsFactory8(weightMap, paramMappings) { + const extractWeightEntry = extractWeightEntryFactory(weightMap, paramMappings); + function extractBatchNormParams(prefix) { + const sub6 = extractWeightEntry(`${prefix}/sub`, 1); + const truediv = extractWeightEntry(`${prefix}/truediv`, 1); + return { sub: sub6, truediv }; + } + function extractConvParams(prefix) { + const filters = extractWeightEntry(`${prefix}/filters`, 4); + const bias = extractWeightEntry(`${prefix}/bias`, 1); + return { filters, bias }; + } + function extractConvWithBatchNormParams(prefix) { + const conv3 = extractConvParams(`${prefix}/conv`); + const bn = extractBatchNormParams(`${prefix}/bn`); + return { conv: conv3, bn }; + } + const extractSeparableConvParams = loadSeparableConvParamsFactory(extractWeightEntry); + return { + extractConvParams, + extractConvWithBatchNormParams, + extractSeparableConvParams + }; +} +function extractParamsFromWeightMap7(weightMap, config) { + const paramMappings = []; + const { + extractConvParams, + extractConvWithBatchNormParams, + extractSeparableConvParams + } = extractorsFactory8(weightMap, paramMappings); + let params; + if (config.withSeparableConvs) { + const numFilters = config.filterSizes && config.filterSizes.length || 9; + params = { + conv0: config.isFirstLayerConv2d ? extractConvParams("conv0") : extractSeparableConvParams("conv0"), + conv1: extractSeparableConvParams("conv1"), + conv2: extractSeparableConvParams("conv2"), + conv3: extractSeparableConvParams("conv3"), + conv4: extractSeparableConvParams("conv4"), + conv5: extractSeparableConvParams("conv5"), + conv6: numFilters > 7 ? extractSeparableConvParams("conv6") : void 0, + conv7: numFilters > 8 ? extractSeparableConvParams("conv7") : void 0, + conv8: extractConvParams("conv8") + }; + } else { + params = { + conv0: extractConvWithBatchNormParams("conv0"), + conv1: extractConvWithBatchNormParams("conv1"), + conv2: extractConvWithBatchNormParams("conv2"), + conv3: extractConvWithBatchNormParams("conv3"), + conv4: extractConvWithBatchNormParams("conv4"), + conv5: extractConvWithBatchNormParams("conv5"), + conv6: extractConvWithBatchNormParams("conv6"), + conv7: extractConvWithBatchNormParams("conv7"), + conv8: extractConvParams("conv8") + }; + } + disposeUnusedWeightTensors(weightMap, paramMappings); + return { params, paramMappings }; +} + +// src/tinyYolov2/TinyYolov2Options.ts +var TinyYolov2Options = class { + constructor({ inputSize, scoreThreshold } = {}) { + this._name = "TinyYolov2Options"; + this._inputSize = inputSize || 416; + this._scoreThreshold = scoreThreshold || 0.5; + if (typeof this._inputSize !== "number" || this._inputSize % 32 !== 0) { + throw new Error(`${this._name} - expected inputSize to be a number divisible by 32`); + } + if (typeof this._scoreThreshold !== "number" || this._scoreThreshold <= 0 || this._scoreThreshold >= 1) { + throw new Error(`${this._name} - expected scoreThreshold to be a number between 0 and 1`); + } + } + get inputSize() { + return this._inputSize; + } + get scoreThreshold() { + return this._scoreThreshold; + } +}; + +// src/tinyYolov2/TinyYolov2Base.ts +var _TinyYolov2Base = class extends NeuralNetwork { + constructor(config) { + super("TinyYolov2"); + validateConfig(config); + this._config = config; + } + get config() { + return this._config; + } + get withClassScores() { + return this.config.withClassScores || this.config.classes.length > 1; + } + get boxEncodingSize() { + return 5 + (this.withClassScores ? this.config.classes.length : 0); + } + runTinyYolov2(x, params) { + let out = convWithBatchNorm(x, params.conv0); + out = tf39.maxPool(out, [2, 2], [2, 2], "same"); + out = convWithBatchNorm(out, params.conv1); + out = tf39.maxPool(out, [2, 2], [2, 2], "same"); + out = convWithBatchNorm(out, params.conv2); + out = tf39.maxPool(out, [2, 2], [2, 2], "same"); + out = convWithBatchNorm(out, params.conv3); + out = tf39.maxPool(out, [2, 2], [2, 2], "same"); + out = convWithBatchNorm(out, params.conv4); + out = tf39.maxPool(out, [2, 2], [2, 2], "same"); + out = convWithBatchNorm(out, params.conv5); + out = tf39.maxPool(out, [2, 2], [1, 1], "same"); + out = convWithBatchNorm(out, params.conv6); + out = convWithBatchNorm(out, params.conv7); + return convLayer(out, params.conv8, "valid", false); + } + runMobilenet(x, params) { + let out = this.config.isFirstLayerConv2d ? leaky(convLayer(x, params.conv0, "valid", false)) : depthwiseSeparableConv2(x, params.conv0); + out = tf39.maxPool(out, [2, 2], [2, 2], "same"); + out = depthwiseSeparableConv2(out, params.conv1); + out = tf39.maxPool(out, [2, 2], [2, 2], "same"); + out = depthwiseSeparableConv2(out, params.conv2); + out = tf39.maxPool(out, [2, 2], [2, 2], "same"); + out = depthwiseSeparableConv2(out, params.conv3); + out = tf39.maxPool(out, [2, 2], [2, 2], "same"); + out = depthwiseSeparableConv2(out, params.conv4); + out = tf39.maxPool(out, [2, 2], [2, 2], "same"); + out = depthwiseSeparableConv2(out, params.conv5); + out = tf39.maxPool(out, [2, 2], [1, 1], "same"); + out = params.conv6 ? depthwiseSeparableConv2(out, params.conv6) : out; + out = params.conv7 ? depthwiseSeparableConv2(out, params.conv7) : out; + return convLayer(out, params.conv8, "valid", false); + } + forwardInput(input, inputSize) { + const { params } = this; + if (!params) { + throw new Error("TinyYolov2 - load model before inference"); + } + return tf39.tidy(() => { + let batchTensor = tf39.cast(input.toBatchTensor(inputSize, false), "float32"); + batchTensor = this.config.meanRgb ? normalize(batchTensor, this.config.meanRgb) : batchTensor; + batchTensor = batchTensor.div(255); + return this.config.withSeparableConvs ? this.runMobilenet(batchTensor, params) : this.runTinyYolov2(batchTensor, params); + }); + } + async forward(input, inputSize) { + return this.forwardInput(await toNetInput(input), inputSize); + } + async detect(input, forwardParams = {}) { + const { inputSize, scoreThreshold } = new TinyYolov2Options(forwardParams); + const netInput = await toNetInput(input); + const out = await this.forwardInput(netInput, inputSize); + const out0 = tf39.tidy(() => tf39.unstack(out)[0].expandDims()); + const inputDimensions = { + width: netInput.getInputWidth(0), + height: netInput.getInputHeight(0) + }; + const results = await this.extractBoxes(out0, netInput.getReshapedInputDimensions(0), scoreThreshold); + out.dispose(); + out0.dispose(); + const boxes = results.map((res) => res.box); + const scores = results.map((res) => res.score); + const classScores = results.map((res) => res.classScore); + const classNames = results.map((res) => this.config.classes[res.label]); + const indices = nonMaxSuppression(boxes.map((box) => box.rescale(inputSize)), scores, this.config.iouThreshold, true); + const detections = indices.map((idx) => new ObjectDetection(scores[idx], classScores[idx], classNames[idx], boxes[idx], inputDimensions)); + return detections; + } + getDefaultModelName() { + return ""; + } + extractParamsFromWeightMap(weightMap) { + return extractParamsFromWeightMap7(weightMap, this.config); + } + extractParams(weights) { + const filterSizes = this.config.filterSizes || _TinyYolov2Base.DEFAULT_FILTER_SIZES; + const numFilters = filterSizes ? filterSizes.length : void 0; + if (numFilters !== 7 && numFilters !== 8 && numFilters !== 9) { + throw new Error(`TinyYolov2 - expected 7 | 8 | 9 convolutional filters, but found ${numFilters} filterSizes in config`); + } + return extractParams7(weights, this.config, this.boxEncodingSize, filterSizes); + } + async extractBoxes(outputTensor, inputBlobDimensions, scoreThreshold) { + const { width, height } = inputBlobDimensions; + const inputSize = Math.max(width, height); + const correctionFactorX = inputSize / width; + const correctionFactorY = inputSize / height; + const numCells = outputTensor.shape[1]; + const numBoxes = this.config.anchors.length; + const [boxesTensor, scoresTensor, classScoresTensor] = tf39.tidy(() => { + const reshaped = outputTensor.reshape([numCells, numCells, numBoxes, this.boxEncodingSize]); + const boxes = reshaped.slice([0, 0, 0, 0], [numCells, numCells, numBoxes, 4]); + const scores = reshaped.slice([0, 0, 0, 4], [numCells, numCells, numBoxes, 1]); + const classScores = this.withClassScores ? tf39.softmax(reshaped.slice([0, 0, 0, 5], [numCells, numCells, numBoxes, this.config.classes.length]), 3) : tf39.scalar(0); + return [boxes, scores, classScores]; + }); + const results = []; + const scoresData = await scoresTensor.array(); + const boxesData = await boxesTensor.array(); + for (let row = 0; row < numCells; row++) { + for (let col = 0; col < numCells; col++) { + for (let anchor = 0; anchor < numBoxes; anchor++) { + const score = sigmoid(scoresData[row][col][anchor][0]); + if (!scoreThreshold || score > scoreThreshold) { + const ctX = (col + sigmoid(boxesData[row][col][anchor][0])) / numCells * correctionFactorX; + const ctY = (row + sigmoid(boxesData[row][col][anchor][1])) / numCells * correctionFactorY; + const widthLocal = Math.exp(boxesData[row][col][anchor][2]) * this.config.anchors[anchor].x / numCells * correctionFactorX; + const heightLocal = Math.exp(boxesData[row][col][anchor][3]) * this.config.anchors[anchor].y / numCells * correctionFactorY; + const x = ctX - widthLocal / 2; + const y = ctY - heightLocal / 2; + const pos = { row, col, anchor }; + const { classScore, label } = this.withClassScores ? await this.extractPredictedClass(classScoresTensor, pos) : { classScore: 1, label: 0 }; + results.push({ + box: new BoundingBox(x, y, x + widthLocal, y + heightLocal), + score, + classScore: score * classScore, + label, + ...pos + }); + } + } + } + } + boxesTensor.dispose(); + scoresTensor.dispose(); + classScoresTensor.dispose(); + return results; + } + async extractPredictedClass(classesTensor, pos) { + const { row, col, anchor } = pos; + const classesData = await classesTensor.array(); + return Array(this.config.classes.length).fill(0).map((_, i) => classesData[row][col][anchor][i]).map((classScore, label) => ({ + classScore, + label + })).reduce((max, curr) => max.classScore > curr.classScore ? max : curr); + } +}; +var TinyYolov2Base = _TinyYolov2Base; +TinyYolov2Base.DEFAULT_FILTER_SIZES = [3, 16, 32, 64, 128, 256, 512, 1024, 1024]; + +// src/tinyYolov2/TinyYolov2.ts +var TinyYolov2 = class extends TinyYolov2Base { + constructor(withSeparableConvs = true) { + const config = { + withSeparableConvs, + iouThreshold: IOU_THRESHOLD, + classes: ["face"], + ...withSeparableConvs ? { + anchors: BOX_ANCHORS_SEPARABLE, + meanRgb: MEAN_RGB_SEPARABLE + } : { + anchors: BOX_ANCHORS, + withClassScores: true + } + }; + super(config); + } + get withSeparableConvs() { + return this.config.withSeparableConvs; + } + get anchors() { + return this.config.anchors; + } + async locateFaces(input, forwardParams) { + const objectDetections = await this.detect(input, forwardParams); + return objectDetections.map((det) => new FaceDetection(det.score, det.relativeBox, { width: det.imageWidth, height: det.imageHeight })); + } + getDefaultModelName() { + return this.withSeparableConvs ? DEFAULT_MODEL_NAME_SEPARABLE_CONV : DEFAULT_MODEL_NAME; + } + extractParamsFromWeightMap(weightMap) { + return super.extractParamsFromWeightMap(weightMap); + } +}; + +// src/tinyYolov2/index.ts +function createTinyYolov2(weights, withSeparableConvs = true) { + const net = new TinyYolov2(withSeparableConvs); + net.extractWeights(weights); + return net; +} + +// src/tinyFaceDetector/TinyFaceDetectorOptions.ts +var TinyFaceDetectorOptions = class extends TinyYolov2Options { + constructor() { + super(...arguments); + this._name = "TinyFaceDetectorOptions"; + } +}; + +// src/globalApi/ComposableTask.ts +var ComposableTask = class { + async then(onfulfilled) { + return onfulfilled(await this.run()); + } + async run() { + throw new Error("ComposableTask - run is not implemented"); + } +}; + +// src/globalApi/DetectFaceLandmarksTasks.ts +var tf41 = __toModule(require_tfjs_esm()); + +// src/globalApi/extractFacesAndComputeResults.ts +var tf40 = __toModule(require_tfjs_esm()); +async function extractAllFacesAndComputeResults(parentResults, input, computeResults, extractedFaces, getRectForAlignment = ({ alignedRect }) => alignedRect) { + const faceBoxes = parentResults.map((parentResult) => isWithFaceLandmarks(parentResult) ? getRectForAlignment(parentResult) : parentResult.detection); + const faces = extractedFaces || (input instanceof tf40.Tensor ? await extractFaceTensors(input, faceBoxes) : await extractFaces(input, faceBoxes)); + const results = await computeResults(faces); + faces.forEach((f) => f instanceof tf40.Tensor && f.dispose()); + return results; +} +async function extractSingleFaceAndComputeResult(parentResult, input, computeResult, extractedFaces, getRectForAlignment) { + return extractAllFacesAndComputeResults([parentResult], input, async (faces) => computeResult(faces[0]), extractedFaces, getRectForAlignment); +} + +// src/tinyFaceDetector/const.ts +var IOU_THRESHOLD2 = 0.4; +var BOX_ANCHORS2 = [ + new Point(1.603231, 2.094468), + new Point(6.041143, 7.080126), + new Point(2.882459, 3.518061), + new Point(4.266906, 5.178857), + new Point(9.041765, 10.66308) +]; +var MEAN_RGB = [117.001, 114.697, 97.404]; + +// src/tinyFaceDetector/TinyFaceDetector.ts +var TinyFaceDetector = class extends TinyYolov2Base { + constructor() { + const config = { + withSeparableConvs: true, + iouThreshold: IOU_THRESHOLD2, + classes: ["face"], + anchors: BOX_ANCHORS2, + meanRgb: MEAN_RGB, + isFirstLayerConv2d: true, + filterSizes: [3, 16, 32, 64, 128, 256, 512] + }; + super(config); + } + get anchors() { + return this.config.anchors; + } + async locateFaces(input, forwardParams) { + const objectDetections = await this.detect(input, forwardParams); + return objectDetections.map((det) => new FaceDetection(det.score, det.relativeBox, { width: det.imageWidth, height: det.imageHeight })); + } + getDefaultModelName() { + return "tiny_face_detector_model"; + } + extractParamsFromWeightMap(weightMap) { + return super.extractParamsFromWeightMap(weightMap); + } +}; + +// src/globalApi/nets.ts +var nets = { + ssdMobilenetv1: new SsdMobilenetv1(), + tinyFaceDetector: new TinyFaceDetector(), + tinyYolov2: new TinyYolov2(), + faceLandmark68Net: new FaceLandmark68Net(), + faceLandmark68TinyNet: new FaceLandmark68TinyNet(), + faceRecognitionNet: new FaceRecognitionNet(), + faceExpressionNet: new FaceExpressionNet(), + ageGenderNet: new AgeGenderNet() +}; +var ssdMobilenetv1 = (input, options) => nets.ssdMobilenetv1.locateFaces(input, options); +var tinyFaceDetector = (input, options) => nets.tinyFaceDetector.locateFaces(input, options); +var tinyYolov2 = (input, options) => nets.tinyYolov2.locateFaces(input, options); +var detectFaceLandmarks = (input) => nets.faceLandmark68Net.detectLandmarks(input); +var detectFaceLandmarksTiny = (input) => nets.faceLandmark68TinyNet.detectLandmarks(input); +var computeFaceDescriptor = (input) => nets.faceRecognitionNet.computeFaceDescriptor(input); +var recognizeFaceExpressions = (input) => nets.faceExpressionNet.predictExpressions(input); +var predictAgeAndGender = (input) => nets.ageGenderNet.predictAgeAndGender(input); +var loadSsdMobilenetv1Model = (url) => nets.ssdMobilenetv1.load(url); +var loadTinyFaceDetectorModel = (url) => nets.tinyFaceDetector.load(url); +var loadTinyYolov2Model = (url) => nets.tinyYolov2.load(url); +var loadFaceLandmarkModel = (url) => nets.faceLandmark68Net.load(url); +var loadFaceLandmarkTinyModel = (url) => nets.faceLandmark68TinyNet.load(url); +var loadFaceRecognitionModel = (url) => nets.faceRecognitionNet.load(url); +var loadFaceExpressionModel = (url) => nets.faceExpressionNet.load(url); +var loadAgeGenderModel = (url) => nets.ageGenderNet.load(url); +var loadFaceDetectionModel = loadSsdMobilenetv1Model; +var locateFaces = ssdMobilenetv1; +var detectLandmarks = detectFaceLandmarks; + +// src/globalApi/PredictFaceExpressionsTask.ts +var PredictFaceExpressionsTaskBase = class extends ComposableTask { + constructor(parentTask, input, extractedFaces) { + super(); + this.parentTask = parentTask; + this.input = input; + this.extractedFaces = extractedFaces; + } +}; +var PredictAllFaceExpressionsTask = class extends PredictFaceExpressionsTaskBase { + async run() { + const parentResults = await this.parentTask; + const faceExpressionsByFace = await extractAllFacesAndComputeResults(parentResults, this.input, async (faces) => Promise.all(faces.map((face) => nets.faceExpressionNet.predictExpressions(face))), this.extractedFaces); + return parentResults.map((parentResult, i) => extendWithFaceExpressions(parentResult, faceExpressionsByFace[i])); + } + withAgeAndGender() { + return new PredictAllAgeAndGenderTask(this, this.input); + } +}; +var PredictSingleFaceExpressionsTask = class extends PredictFaceExpressionsTaskBase { + async run() { + const parentResult = await this.parentTask; + if (!parentResult) { + return void 0; + } + const faceExpressions = await extractSingleFaceAndComputeResult(parentResult, this.input, (face) => nets.faceExpressionNet.predictExpressions(face), this.extractedFaces); + return extendWithFaceExpressions(parentResult, faceExpressions); + } + withAgeAndGender() { + return new PredictSingleAgeAndGenderTask(this, this.input); + } +}; +var PredictAllFaceExpressionsWithFaceAlignmentTask = class extends PredictAllFaceExpressionsTask { + withAgeAndGender() { + return new PredictAllAgeAndGenderWithFaceAlignmentTask(this, this.input); + } + withFaceDescriptors() { + return new ComputeAllFaceDescriptorsTask(this, this.input); + } +}; +var PredictSingleFaceExpressionsWithFaceAlignmentTask = class extends PredictSingleFaceExpressionsTask { + withAgeAndGender() { + return new PredictSingleAgeAndGenderWithFaceAlignmentTask(this, this.input); + } + withFaceDescriptor() { + return new ComputeSingleFaceDescriptorTask(this, this.input); + } +}; + +// src/globalApi/PredictAgeAndGenderTask.ts +var PredictAgeAndGenderTaskBase = class extends ComposableTask { + constructor(parentTask, input, extractedFaces) { + super(); + this.parentTask = parentTask; + this.input = input; + this.extractedFaces = extractedFaces; + } +}; +var PredictAllAgeAndGenderTask = class extends PredictAgeAndGenderTaskBase { + async run() { + const parentResults = await this.parentTask; + const ageAndGenderByFace = await extractAllFacesAndComputeResults(parentResults, this.input, async (faces) => Promise.all(faces.map((face) => nets.ageGenderNet.predictAgeAndGender(face))), this.extractedFaces); + return parentResults.map((parentResult, i) => { + const { age, gender, genderProbability } = ageAndGenderByFace[i]; + return extendWithAge(extendWithGender(parentResult, gender, genderProbability), age); + }); + } + withFaceExpressions() { + return new PredictAllFaceExpressionsTask(this, this.input); + } +}; +var PredictSingleAgeAndGenderTask = class extends PredictAgeAndGenderTaskBase { + async run() { + const parentResult = await this.parentTask; + if (!parentResult) + return void 0; + const { age, gender, genderProbability } = await extractSingleFaceAndComputeResult(parentResult, this.input, (face) => nets.ageGenderNet.predictAgeAndGender(face), this.extractedFaces); + return extendWithAge(extendWithGender(parentResult, gender, genderProbability), age); + } + withFaceExpressions() { + return new PredictSingleFaceExpressionsTask(this, this.input); + } +}; +var PredictAllAgeAndGenderWithFaceAlignmentTask = class extends PredictAllAgeAndGenderTask { + withFaceExpressions() { + return new PredictAllFaceExpressionsWithFaceAlignmentTask(this, this.input); + } + withFaceDescriptors() { + return new ComputeAllFaceDescriptorsTask(this, this.input); + } +}; +var PredictSingleAgeAndGenderWithFaceAlignmentTask = class extends PredictSingleAgeAndGenderTask { + withFaceExpressions() { + return new PredictSingleFaceExpressionsWithFaceAlignmentTask(this, this.input); + } + withFaceDescriptor() { + return new ComputeSingleFaceDescriptorTask(this, this.input); + } +}; + +// src/globalApi/ComputeFaceDescriptorsTasks.ts +var ComputeFaceDescriptorsTaskBase = class extends ComposableTask { + constructor(parentTask, input) { + super(); + this.parentTask = parentTask; + this.input = input; + } +}; +var ComputeAllFaceDescriptorsTask = class extends ComputeFaceDescriptorsTaskBase { + async run() { + const parentResults = await this.parentTask; + const descriptors = await extractAllFacesAndComputeResults(parentResults, this.input, (faces) => Promise.all(faces.map((face) => nets.faceRecognitionNet.computeFaceDescriptor(face))), null, (parentResult) => parentResult.landmarks.align(null, { useDlibAlignment: true })); + return descriptors.map((descriptor, i) => extendWithFaceDescriptor(parentResults[i], descriptor)); + } + withFaceExpressions() { + return new PredictAllFaceExpressionsWithFaceAlignmentTask(this, this.input); + } + withAgeAndGender() { + return new PredictAllAgeAndGenderWithFaceAlignmentTask(this, this.input); + } +}; +var ComputeSingleFaceDescriptorTask = class extends ComputeFaceDescriptorsTaskBase { + async run() { + const parentResult = await this.parentTask; + if (!parentResult) + return void 0; + const descriptor = await extractSingleFaceAndComputeResult(parentResult, this.input, (face) => nets.faceRecognitionNet.computeFaceDescriptor(face), null, (parentResult2) => parentResult2.landmarks.align(null, { useDlibAlignment: true })); + return extendWithFaceDescriptor(parentResult, descriptor); + } + withFaceExpressions() { + return new PredictSingleFaceExpressionsWithFaceAlignmentTask(this, this.input); + } + withAgeAndGender() { + return new PredictSingleAgeAndGenderWithFaceAlignmentTask(this, this.input); + } +}; + +// src/globalApi/DetectFaceLandmarksTasks.ts +var DetectFaceLandmarksTaskBase = class extends ComposableTask { + constructor(parentTask, input, useTinyLandmarkNet) { + super(); + this.parentTask = parentTask; + this.input = input; + this.useTinyLandmarkNet = useTinyLandmarkNet; + } + get landmarkNet() { + return this.useTinyLandmarkNet ? nets.faceLandmark68TinyNet : nets.faceLandmark68Net; + } +}; +var DetectAllFaceLandmarksTask = class extends DetectFaceLandmarksTaskBase { + async run() { + const parentResults = await this.parentTask; + const detections = parentResults.map((res) => res.detection); + const faces = this.input instanceof tf41.Tensor ? await extractFaceTensors(this.input, detections) : await extractFaces(this.input, detections); + const faceLandmarksByFace = await Promise.all(faces.map((face) => this.landmarkNet.detectLandmarks(face))); + faces.forEach((f) => f instanceof tf41.Tensor && f.dispose()); + return parentResults.map((parentResult, i) => extendWithFaceLandmarks(parentResult, faceLandmarksByFace[i])); + } + withFaceExpressions() { + return new PredictAllFaceExpressionsWithFaceAlignmentTask(this, this.input); + } + withAgeAndGender() { + return new PredictAllAgeAndGenderWithFaceAlignmentTask(this, this.input); + } + withFaceDescriptors() { + return new ComputeAllFaceDescriptorsTask(this, this.input); + } +}; +var DetectSingleFaceLandmarksTask = class extends DetectFaceLandmarksTaskBase { + async run() { + const parentResult = await this.parentTask; + if (!parentResult) { + return void 0; + } + const { detection } = parentResult; + const faces = this.input instanceof tf41.Tensor ? await extractFaceTensors(this.input, [detection]) : await extractFaces(this.input, [detection]); + const landmarks = await this.landmarkNet.detectLandmarks(faces[0]); + faces.forEach((f) => f instanceof tf41.Tensor && f.dispose()); + return extendWithFaceLandmarks(parentResult, landmarks); + } + withFaceExpressions() { + return new PredictSingleFaceExpressionsWithFaceAlignmentTask(this, this.input); + } + withAgeAndGender() { + return new PredictSingleAgeAndGenderWithFaceAlignmentTask(this, this.input); + } + withFaceDescriptor() { + return new ComputeSingleFaceDescriptorTask(this, this.input); + } +}; + +// src/globalApi/DetectFacesTasks.ts +var DetectFacesTaskBase = class extends ComposableTask { + constructor(input, options = new SsdMobilenetv1Options()) { + super(); + this.input = input; + this.options = options; + } +}; +var DetectAllFacesTask = class extends DetectFacesTaskBase { + async run() { + const { input, options } = this; + let result; + if (options instanceof TinyFaceDetectorOptions) + result = nets.tinyFaceDetector.locateFaces(input, options); + else if (options instanceof SsdMobilenetv1Options) + result = nets.ssdMobilenetv1.locateFaces(input, options); + else if (options instanceof TinyYolov2Options) + result = nets.tinyYolov2.locateFaces(input, options); + else + throw new Error("detectFaces - expected options to be instance of TinyFaceDetectorOptions | SsdMobilenetv1Options | TinyYolov2Options"); + return result; + } + runAndExtendWithFaceDetections() { + return new Promise((resolve, reject) => { + this.run().then((detections) => resolve(detections.map((detection) => extendWithFaceDetection({}, detection)))).catch((err) => reject(err)); + }); + } + withFaceLandmarks(useTinyLandmarkNet = false) { + return new DetectAllFaceLandmarksTask(this.runAndExtendWithFaceDetections(), this.input, useTinyLandmarkNet); + } + withFaceExpressions() { + return new PredictAllFaceExpressionsTask(this.runAndExtendWithFaceDetections(), this.input); + } + withAgeAndGender() { + return new PredictAllAgeAndGenderTask(this.runAndExtendWithFaceDetections(), this.input); + } +}; +var DetectSingleFaceTask = class extends DetectFacesTaskBase { + async run() { + const faceDetections = await new DetectAllFacesTask(this.input, this.options); + let faceDetectionWithHighestScore = faceDetections[0]; + faceDetections.forEach((faceDetection) => { + if (faceDetection.score > faceDetectionWithHighestScore.score) + faceDetectionWithHighestScore = faceDetection; + }); + return faceDetectionWithHighestScore; + } + runAndExtendWithFaceDetection() { + return new Promise(async (resolve) => { + const detection = await this.run(); + resolve(detection ? extendWithFaceDetection({}, detection) : void 0); + }); + } + withFaceLandmarks(useTinyLandmarkNet = false) { + return new DetectSingleFaceLandmarksTask(this.runAndExtendWithFaceDetection(), this.input, useTinyLandmarkNet); + } + withFaceExpressions() { + return new PredictSingleFaceExpressionsTask(this.runAndExtendWithFaceDetection(), this.input); + } + withAgeAndGender() { + return new PredictSingleAgeAndGenderTask(this.runAndExtendWithFaceDetection(), this.input); + } +}; + +// src/globalApi/detectFaces.ts +function detectSingleFace(input, options = new SsdMobilenetv1Options()) { + return new DetectSingleFaceTask(input, options); +} +function detectAllFaces(input, options = new SsdMobilenetv1Options()) { + return new DetectAllFacesTask(input, options); +} + +// src/globalApi/allFaces.ts +async function allFacesSsdMobilenetv1(input, minConfidence) { + return detectAllFaces(input, new SsdMobilenetv1Options(minConfidence ? { minConfidence } : {})).withFaceLandmarks().withFaceDescriptors(); +} +async function allFacesTinyYolov2(input, forwardParams = {}) { + return detectAllFaces(input, new TinyYolov2Options(forwardParams)).withFaceLandmarks().withFaceDescriptors(); +} +var allFaces = allFacesSsdMobilenetv1; + +// src/euclideanDistance.ts +function euclideanDistance(arr1, arr2) { + if (arr1.length !== arr2.length) + throw new Error("euclideanDistance: arr1.length !== arr2.length"); + const desc1 = Array.from(arr1); + const desc2 = Array.from(arr2); + return Math.sqrt(desc1.map((val, i) => val - desc2[i]).reduce((res, diff) => res + diff ** 2, 0)); +} + +// src/globalApi/FaceMatcher.ts +var FaceMatcher = class { + constructor(inputs, distanceThreshold = 0.6) { + this._distanceThreshold = distanceThreshold; + const inputArray = Array.isArray(inputs) ? inputs : [inputs]; + if (!inputArray.length) + throw new Error("FaceRecognizer.constructor - expected atleast one input"); + let count = 1; + const createUniqueLabel = () => `person ${count++}`; + this._labeledDescriptors = inputArray.map((desc) => { + if (desc instanceof LabeledFaceDescriptors) + return desc; + if (desc instanceof Float32Array) + return new LabeledFaceDescriptors(createUniqueLabel(), [desc]); + if (desc.descriptor && desc.descriptor instanceof Float32Array) + return new LabeledFaceDescriptors(createUniqueLabel(), [desc.descriptor]); + throw new Error("FaceRecognizer.constructor - expected inputs to be of type LabeledFaceDescriptors | WithFaceDescriptor | Float32Array | Array | Float32Array>"); + }); + } + get labeledDescriptors() { + return this._labeledDescriptors; + } + get distanceThreshold() { + return this._distanceThreshold; + } + computeMeanDistance(queryDescriptor, descriptors) { + return descriptors.map((d) => euclideanDistance(d, queryDescriptor)).reduce((d1, d2) => d1 + d2, 0) / (descriptors.length || 1); + } + matchDescriptor(queryDescriptor) { + return this.labeledDescriptors.map(({ descriptors, label }) => new FaceMatch(label, this.computeMeanDistance(queryDescriptor, descriptors))).reduce((best, curr) => best.distance < curr.distance ? best : curr); + } + findBestMatch(queryDescriptor) { + const bestMatch = this.matchDescriptor(queryDescriptor); + return bestMatch.distance < this._distanceThreshold ? bestMatch : new FaceMatch("unknown", bestMatch.distance); + } + toJSON() { + return { + distanceThreshold: this._distanceThreshold, + labeledDescriptors: this._labeledDescriptors.map((ld) => ld.toJSON()) + }; + } + static fromJSON(json) { + const labeledDescriptors = json.labeledDescriptors.map((ld) => LabeledFaceDescriptors.fromJSON(ld)); + return new FaceMatcher(labeledDescriptors, json.distanceThreshold); + } +}; + +// src/tinyFaceDetector/index.ts +function createTinyFaceDetector(weights) { + const net = new TinyFaceDetector(); + net.extractWeights(weights); + return net; +} + +// src/resizeResults.ts +function resizeResults(results, dimensions) { + const { width, height } = new Dimensions(dimensions.width, dimensions.height); + if (width <= 0 || height <= 0) { + throw new Error(`resizeResults - invalid dimensions: ${JSON.stringify({ width, height })}`); + } + if (Array.isArray(results)) { + return results.map((obj) => resizeResults(obj, { width, height })); + } + if (isWithFaceLandmarks(results)) { + const resizedDetection = results.detection.forSize(width, height); + const resizedLandmarks = results.unshiftedLandmarks.forSize(resizedDetection.box.width, resizedDetection.box.height); + return extendWithFaceLandmarks(extendWithFaceDetection(results, resizedDetection), resizedLandmarks); + } + if (isWithFaceDetection(results)) { + return extendWithFaceDetection(results, results.detection.forSize(width, height)); + } + if (results instanceof FaceLandmarks || results instanceof FaceDetection) { + return results.forSize(width, height); + } + return results; +} + +// src/index.ts +var version2 = version; +// Annotate the CommonJS export names for ESM import in node: +0 && (module.exports = { + AgeGenderNet, + BoundingBox, + Box, + ComposableTask, + ComputeAllFaceDescriptorsTask, + ComputeFaceDescriptorsTaskBase, + ComputeSingleFaceDescriptorTask, + DetectAllFaceLandmarksTask, + DetectAllFacesTask, + DetectFaceLandmarksTaskBase, + DetectFacesTaskBase, + DetectSingleFaceLandmarksTask, + DetectSingleFaceTask, + Dimensions, + FACE_EXPRESSION_LABELS, + FaceDetection, + FaceDetectionNet, + FaceExpressionNet, + FaceExpressions, + FaceLandmark68Net, + FaceLandmark68TinyNet, + FaceLandmarkNet, + FaceLandmarks, + FaceLandmarks5, + FaceLandmarks68, + FaceMatch, + FaceMatcher, + FaceRecognitionNet, + Gender, + LabeledBox, + LabeledFaceDescriptors, + NetInput, + NeuralNetwork, + ObjectDetection, + Point, + PredictedBox, + Rect, + SsdMobilenetv1, + SsdMobilenetv1Options, + TinyFaceDetector, + TinyFaceDetectorOptions, + TinyYolov2, + TinyYolov2Options, + allFaces, + allFacesSsdMobilenetv1, + allFacesTinyYolov2, + awaitMediaLoaded, + bufferToImage, + computeFaceDescriptor, + createCanvas, + createCanvasFromMedia, + createFaceDetectionNet, + createFaceRecognitionNet, + createSsdMobilenetv1, + createTinyFaceDetector, + createTinyYolov2, + detectAllFaces, + detectFaceLandmarks, + detectFaceLandmarksTiny, + detectLandmarks, + detectSingleFace, + draw, + env, + euclideanDistance, + extendWithAge, + extendWithFaceDescriptor, + extendWithFaceDetection, + extendWithFaceExpressions, + extendWithFaceLandmarks, + extendWithGender, + extractFaceTensors, + extractFaces, + fetchImage, + fetchJson, + fetchNetWeights, + fetchOrThrow, + fetchVideo, + getContext2dOrThrow, + getMediaDimensions, + imageTensorToCanvas, + imageToSquare, + inverseSigmoid, + iou, + isMediaElement, + isMediaLoaded, + isWithAge, + isWithFaceDetection, + isWithFaceExpressions, + isWithFaceLandmarks, + isWithGender, + loadAgeGenderModel, + loadFaceDetectionModel, + loadFaceExpressionModel, + loadFaceLandmarkModel, + loadFaceLandmarkTinyModel, + loadFaceRecognitionModel, + loadSsdMobilenetv1Model, + loadTinyFaceDetectorModel, + loadTinyYolov2Model, + loadWeightMap, + locateFaces, + matchDimensions, + minBbox, + nets, + nonMaxSuppression, + normalize, + padToSquare, + predictAgeAndGender, + recognizeFaceExpressions, + resizeResults, + resolveInput, + shuffleArray, + sigmoid, + ssdMobilenetv1, + tf, + tinyFaceDetector, + tinyYolov2, + toNetInput, + utils, + validateConfig, + version +}); diff --git a/dist/face-api.node.js b/dist/face-api.node.js index af42017..8f222ff 100644 --- a/dist/face-api.node.js +++ b/dist/face-api.node.js @@ -2290,7 +2290,7 @@ function drawFaceLandmarks(canvasArg, faceLandmarks) { } // package.json -var version = "1.6.2"; +var version = "1.6.3"; // src/ageGenderNet/AgeGenderNet.ts var tf20 = __toModule(require_tfjs_esm()); diff --git a/src/tfjs/tf-node-wasm.ts b/src/tfjs/tf-node-wasm.ts new file mode 100644 index 0000000..5be902b --- /dev/null +++ b/src/tfjs/tf-node-wasm.ts @@ -0,0 +1,5 @@ +/* eslint-disable import/no-extraneous-dependencies */ +/* eslint-disable node/no-unpublished-import */ + +export * from '@tensorflow/tfjs'; +export * from '@tensorflow/tfjs-backend-wasm'; diff --git a/typedoc/classes/AgeGenderNet.html b/typedoc/classes/AgeGenderNet.html index 05526f6..976a54d 100644 --- a/typedoc/classes/AgeGenderNet.html +++ b/typedoc/classes/AgeGenderNet.html @@ -1 +1 @@ -AgeGenderNet | @vladmandic/face-api - v1.6.2
Options
All
  • Public
  • Public/Protected
  • All
Menu

Hierarchy

Index

Constructors

constructor

  • new AgeGenderNet(faceFeatureExtractor?: TinyXception): AgeGenderNet

Properties

_name

_name: any

Accessors

faceFeatureExtractor

  • get faceFeatureExtractor(): TinyXception

isLoaded

  • get isLoaded(): boolean

paramMappings

  • get paramMappings(): ParamMapping[]

params

  • get params(): undefined | TNetParams
  • Returns undefined | TNetParams

Methods

dispose

  • dispose(throwOnRedispose?: boolean): void

extractClassifierParams

  • extractClassifierParams(weights: Float32Array): { paramMappings: ParamMapping[]; params: NetParams }

extractWeights

  • extractWeights(weights: Float32Array): void

forward

forwardInput

freeze

  • freeze(): void

getFrozenParams

  • getFrozenParams(): { path: string; tensor: Tensor }[]

getParamFromPath

  • getParamFromPath(paramPath: string): Tensor

getParamList

  • getParamList(): { path: string; tensor: Tensor }[]

getTrainableParams

  • getTrainableParams(): { path: string; tensor: Tensor }[]

load

  • load(weightsOrUrl: undefined | string | Float32Array): Promise<void>

loadClassifierParams

  • loadClassifierParams(weights: Float32Array): void

loadFromDisk

  • loadFromDisk(filePath: undefined | string): Promise<void>

loadFromUri

  • loadFromUri(uri: undefined | string): Promise<void>

loadFromWeightMap

  • loadFromWeightMap(weightMap: NamedTensorMap): void

predictAgeAndGender

reassignParamFromPath

  • reassignParamFromPath(paramPath: string, tensor: Tensor): void

runNet

serializeParams

  • serializeParams(): Float32Array

variable

  • variable(): void

Legend

  • Constructor
  • Property
  • Method
  • Inherited constructor
  • Inherited property
  • Inherited method
  • Property
  • Static method

Settings

Theme

\ No newline at end of file +AgeGenderNet | @vladmandic/face-api - v1.6.3
Options
All
  • Public
  • Public/Protected
  • All
Menu

Hierarchy

Index

Constructors

constructor

  • new AgeGenderNet(faceFeatureExtractor?: TinyXception): AgeGenderNet

Properties

_name

_name: any

Accessors

faceFeatureExtractor

  • get faceFeatureExtractor(): TinyXception

isLoaded

  • get isLoaded(): boolean

paramMappings

  • get paramMappings(): ParamMapping[]

params

  • get params(): undefined | TNetParams
  • Returns undefined | TNetParams

Methods

dispose

  • dispose(throwOnRedispose?: boolean): void

extractClassifierParams

  • extractClassifierParams(weights: Float32Array): { paramMappings: ParamMapping[]; params: NetParams }

extractWeights

  • extractWeights(weights: Float32Array): void

forward

forwardInput

freeze

  • freeze(): void

getFrozenParams

  • getFrozenParams(): { path: string; tensor: Tensor }[]

getParamFromPath

  • getParamFromPath(paramPath: string): Tensor

getParamList

  • getParamList(): { path: string; tensor: Tensor }[]

getTrainableParams

  • getTrainableParams(): { path: string; tensor: Tensor }[]

load

  • load(weightsOrUrl: undefined | string | Float32Array): Promise<void>

loadClassifierParams

  • loadClassifierParams(weights: Float32Array): void

loadFromDisk

  • loadFromDisk(filePath: undefined | string): Promise<void>

loadFromUri

  • loadFromUri(uri: undefined | string): Promise<void>

loadFromWeightMap

  • loadFromWeightMap(weightMap: NamedTensorMap): void

predictAgeAndGender

reassignParamFromPath

  • reassignParamFromPath(paramPath: string, tensor: Tensor): void

runNet

serializeParams

  • serializeParams(): Float32Array

variable

  • variable(): void

Legend

  • Constructor
  • Property
  • Method
  • Inherited constructor
  • Inherited property
  • Inherited method
  • Property
  • Static method

Settings

Theme

\ No newline at end of file diff --git a/typedoc/classes/BoundingBox.html b/typedoc/classes/BoundingBox.html index e1f7bd9..f4c5dac 100644 --- a/typedoc/classes/BoundingBox.html +++ b/typedoc/classes/BoundingBox.html @@ -1 +1 @@ -BoundingBox | @vladmandic/face-api - v1.6.2
Options
All
  • Public
  • Public/Protected
  • All
Menu

Hierarchy

Implements

Index

Constructors

constructor

  • new BoundingBox(left: number, top: number, right: number, bottom: number, allowNegativeDimensions?: boolean): BoundingBox

Accessors

area

  • get area(): number

bottom

  • get bottom(): number

bottomLeft

bottomRight

height

  • get height(): number

left

  • get left(): number

right

  • get right(): number

top

  • get top(): number

topLeft

topRight

width

  • get width(): number

x

  • get x(): number

y

  • get y(): number

Methods

calibrate

  • calibrate(region: Box<any>): Box<any>

clipAtImageBorders

  • clipAtImageBorders(imgWidth: number, imgHeight: number): Box<any>

floor

  • floor(): Box<any>

pad

  • pad(padX: number, padY: number): Box<any>

padAtBorders

  • padAtBorders(imageHeight: number, imageWidth: number): { dx: number; dy: number; edx: number; edy: number; ex: number; ey: number; h: number; w: number; x: number; y: number }
  • Parameters

    • imageHeight: number
    • imageWidth: number

    Returns { dx: number; dy: number; edx: number; edy: number; ex: number; ey: number; h: number; w: number; x: number; y: number }

    • dx: number
    • dy: number
    • edx: number
    • edy: number
    • ex: number
    • ey: number
    • h: number
    • w: number
    • x: number
    • y: number

rescale

round

  • round(): Box<any>

shift

  • shift(sx: number, sy: number): Box<any>

toSquare

  • toSquare(): Box<any>

Static assertIsValidBox

  • assertIsValidBox(box: any, callee: string, allowNegativeDimensions?: boolean): void

Static isRect

  • isRect(rect: any): boolean

Legend

  • Constructor
  • Property
  • Method
  • Inherited constructor
  • Inherited property
  • Inherited method
  • Property
  • Static method

Settings

Theme

\ No newline at end of file +BoundingBox | @vladmandic/face-api - v1.6.3
Options
All
  • Public
  • Public/Protected
  • All
Menu

Hierarchy

Implements

Index

Constructors

constructor

  • new BoundingBox(left: number, top: number, right: number, bottom: number, allowNegativeDimensions?: boolean): BoundingBox

Accessors

area

  • get area(): number

bottom

  • get bottom(): number

bottomLeft

bottomRight

height

  • get height(): number

left

  • get left(): number

right

  • get right(): number

top

  • get top(): number

topLeft

topRight

width

  • get width(): number

x

  • get x(): number

y

  • get y(): number

Methods

calibrate

  • calibrate(region: Box<any>): Box<any>

clipAtImageBorders

  • clipAtImageBorders(imgWidth: number, imgHeight: number): Box<any>

floor

  • floor(): Box<any>

pad

  • pad(padX: number, padY: number): Box<any>

padAtBorders

  • padAtBorders(imageHeight: number, imageWidth: number): { dx: number; dy: number; edx: number; edy: number; ex: number; ey: number; h: number; w: number; x: number; y: number }
  • Parameters

    • imageHeight: number
    • imageWidth: number

    Returns { dx: number; dy: number; edx: number; edy: number; ex: number; ey: number; h: number; w: number; x: number; y: number }

    • dx: number
    • dy: number
    • edx: number
    • edy: number
    • ex: number
    • ey: number
    • h: number
    • w: number
    • x: number
    • y: number

rescale

round

  • round(): Box<any>

shift

  • shift(sx: number, sy: number): Box<any>

toSquare

  • toSquare(): Box<any>

Static assertIsValidBox

  • assertIsValidBox(box: any, callee: string, allowNegativeDimensions?: boolean): void

Static isRect

  • isRect(rect: any): boolean

Legend

  • Constructor
  • Property
  • Method
  • Inherited constructor
  • Inherited property
  • Inherited method
  • Property
  • Static method

Settings

Theme

\ No newline at end of file diff --git a/typedoc/classes/Box.html b/typedoc/classes/Box.html index 521ee53..6f29c3d 100644 --- a/typedoc/classes/Box.html +++ b/typedoc/classes/Box.html @@ -1 +1 @@ -Box | @vladmandic/face-api - v1.6.2
Options
All
  • Public
  • Public/Protected
  • All
Menu

Type parameters

  • BoxType = any

Hierarchy

Implements

Index

Constructors

constructor

Accessors

area

  • get area(): number

bottom

  • get bottom(): number

bottomLeft

bottomRight

height

  • get height(): number

left

  • get left(): number

right

  • get right(): number

top

  • get top(): number

topLeft

topRight

width

  • get width(): number

x

  • get x(): number

y

  • get y(): number

Methods

calibrate

  • calibrate(region: Box<any>): Box<any>

clipAtImageBorders

  • clipAtImageBorders(imgWidth: number, imgHeight: number): Box<BoxType>

floor

  • floor(): Box<BoxType>

pad

  • pad(padX: number, padY: number): Box<BoxType>

padAtBorders

  • padAtBorders(imageHeight: number, imageWidth: number): { dx: number; dy: number; edx: number; edy: number; ex: number; ey: number; h: number; w: number; x: number; y: number }
  • Parameters

    • imageHeight: number
    • imageWidth: number

    Returns { dx: number; dy: number; edx: number; edy: number; ex: number; ey: number; h: number; w: number; x: number; y: number }

    • dx: number
    • dy: number
    • edx: number
    • edy: number
    • ex: number
    • ey: number
    • h: number
    • w: number
    • x: number
    • y: number

rescale

round

  • round(): Box<BoxType>

shift

  • shift(sx: number, sy: number): Box<BoxType>

toSquare

  • toSquare(): Box<BoxType>

Static assertIsValidBox

  • assertIsValidBox(box: any, callee: string, allowNegativeDimensions?: boolean): void
  • Parameters

    • box: any
    • callee: string
    • allowNegativeDimensions: boolean = false

    Returns void

Static isRect

  • isRect(rect: any): boolean

Legend

  • Constructor
  • Property
  • Method
  • Inherited constructor
  • Inherited property
  • Inherited method
  • Property
  • Static method

Settings

Theme

\ No newline at end of file +Box | @vladmandic/face-api - v1.6.3
Options
All
  • Public
  • Public/Protected
  • All
Menu

Type parameters

  • BoxType = any

Hierarchy

Implements

Index

Constructors

constructor

Accessors

area

  • get area(): number

bottom

  • get bottom(): number

bottomLeft

bottomRight

height

  • get height(): number

left

  • get left(): number

right

  • get right(): number

top

  • get top(): number

topLeft

topRight

width

  • get width(): number

x

  • get x(): number

y

  • get y(): number

Methods

calibrate

  • calibrate(region: Box<any>): Box<any>

clipAtImageBorders

  • clipAtImageBorders(imgWidth: number, imgHeight: number): Box<BoxType>

floor

  • floor(): Box<BoxType>

pad

  • pad(padX: number, padY: number): Box<BoxType>

padAtBorders

  • padAtBorders(imageHeight: number, imageWidth: number): { dx: number; dy: number; edx: number; edy: number; ex: number; ey: number; h: number; w: number; x: number; y: number }
  • Parameters

    • imageHeight: number
    • imageWidth: number

    Returns { dx: number; dy: number; edx: number; edy: number; ex: number; ey: number; h: number; w: number; x: number; y: number }

    • dx: number
    • dy: number
    • edx: number
    • edy: number
    • ex: number
    • ey: number
    • h: number
    • w: number
    • x: number
    • y: number

rescale

round

  • round(): Box<BoxType>

shift

  • shift(sx: number, sy: number): Box<BoxType>

toSquare

  • toSquare(): Box<BoxType>

Static assertIsValidBox

  • assertIsValidBox(box: any, callee: string, allowNegativeDimensions?: boolean): void
  • Parameters

    • box: any
    • callee: string
    • allowNegativeDimensions: boolean = false

    Returns void

Static isRect

  • isRect(rect: any): boolean

Legend

  • Constructor
  • Property
  • Method
  • Inherited constructor
  • Inherited property
  • Inherited method
  • Property
  • Static method

Settings

Theme

\ No newline at end of file diff --git a/typedoc/classes/ComposableTask.html b/typedoc/classes/ComposableTask.html index 86cb2da..07f0d75 100644 --- a/typedoc/classes/ComposableTask.html +++ b/typedoc/classes/ComposableTask.html @@ -1 +1 @@ -ComposableTask | @vladmandic/face-api - v1.6.2
Options
All
  • Public
  • Public/Protected
  • All
Menu

Type parameters

  • T

Hierarchy

Index

Constructors

Methods

Constructors

constructor

Methods

run

  • run(): Promise<T>

then

  • then(onfulfilled: (value: T) => T | PromiseLike<T>): Promise<T>
  • Parameters

    • onfulfilled: (value: T) => T | PromiseLike<T>
        • (value: T): T | PromiseLike<T>
        • Parameters

          • value: T

          Returns T | PromiseLike<T>

    Returns Promise<T>

Legend

  • Constructor
  • Property
  • Method
  • Inherited constructor
  • Inherited property
  • Inherited method
  • Property
  • Static method

Settings

Theme

\ No newline at end of file +ComposableTask | @vladmandic/face-api - v1.6.3
Options
All
  • Public
  • Public/Protected
  • All
Menu

Type parameters

  • T

Hierarchy

Index

Constructors

Methods

Constructors

constructor

Methods

run

  • run(): Promise<T>

then

  • then(onfulfilled: (value: T) => T | PromiseLike<T>): Promise<T>
  • Parameters

    • onfulfilled: (value: T) => T | PromiseLike<T>
        • (value: T): T | PromiseLike<T>
        • Parameters

          • value: T

          Returns T | PromiseLike<T>

    Returns Promise<T>

Legend

  • Constructor
  • Property
  • Method
  • Inherited constructor
  • Inherited property
  • Inherited method
  • Property
  • Static method

Settings

Theme

\ No newline at end of file diff --git a/typedoc/classes/ComputeAllFaceDescriptorsTask.html b/typedoc/classes/ComputeAllFaceDescriptorsTask.html index 50d99d4..00658f2 100644 --- a/typedoc/classes/ComputeAllFaceDescriptorsTask.html +++ b/typedoc/classes/ComputeAllFaceDescriptorsTask.html @@ -1 +1 @@ -ComputeAllFaceDescriptorsTask | @vladmandic/face-api - v1.6.2
Options
All
  • Public
  • Public/Protected
  • All
Menu

Class ComputeAllFaceDescriptorsTask<TSource>

Type parameters

Hierarchy

Index

Constructors

constructor

Methods

run

then

withAgeAndGender

  • withAgeAndGender(): PredictAllAgeAndGenderWithFaceAlignmentTask<WithFaceDescriptor<TSource>>

withFaceExpressions

  • withFaceExpressions(): PredictAllFaceExpressionsWithFaceAlignmentTask<WithFaceDescriptor<TSource>>

Legend

  • Constructor
  • Property
  • Method
  • Inherited constructor
  • Inherited property
  • Inherited method
  • Property
  • Static method

Settings

Theme

\ No newline at end of file +ComputeAllFaceDescriptorsTask | @vladmandic/face-api - v1.6.3
Options
All
  • Public
  • Public/Protected
  • All
Menu

Class ComputeAllFaceDescriptorsTask<TSource>

Type parameters

Hierarchy

Index

Constructors

constructor

Methods

run

then

withAgeAndGender

  • withAgeAndGender(): PredictAllAgeAndGenderWithFaceAlignmentTask<WithFaceDescriptor<TSource>>

withFaceExpressions

  • withFaceExpressions(): PredictAllFaceExpressionsWithFaceAlignmentTask<WithFaceDescriptor<TSource>>

Legend

  • Constructor
  • Property
  • Method
  • Inherited constructor
  • Inherited property
  • Inherited method
  • Property
  • Static method

Settings

Theme

\ No newline at end of file diff --git a/typedoc/classes/ComputeFaceDescriptorsTaskBase.html b/typedoc/classes/ComputeFaceDescriptorsTaskBase.html index e02a67b..cf81bc5 100644 --- a/typedoc/classes/ComputeFaceDescriptorsTaskBase.html +++ b/typedoc/classes/ComputeFaceDescriptorsTaskBase.html @@ -1 +1 @@ -ComputeFaceDescriptorsTaskBase | @vladmandic/face-api - v1.6.2
Options
All
  • Public
  • Public/Protected
  • All
Menu

Class ComputeFaceDescriptorsTaskBase<TReturn, TParentReturn>

Type parameters

  • TReturn

  • TParentReturn

Hierarchy

Index

Constructors

Methods

Constructors

constructor

Methods

run

  • run(): Promise<TReturn>

then

  • then(onfulfilled: (value: TReturn) => TReturn | PromiseLike<TReturn>): Promise<TReturn>
  • Parameters

    • onfulfilled: (value: TReturn) => TReturn | PromiseLike<TReturn>
        • (value: TReturn): TReturn | PromiseLike<TReturn>
        • Parameters

          • value: TReturn

          Returns TReturn | PromiseLike<TReturn>

    Returns Promise<TReturn>

Legend

  • Constructor
  • Property
  • Method
  • Inherited constructor
  • Inherited property
  • Inherited method
  • Property
  • Static method

Settings

Theme

\ No newline at end of file +ComputeFaceDescriptorsTaskBase | @vladmandic/face-api - v1.6.3
Options
All
  • Public
  • Public/Protected
  • All
Menu

Class ComputeFaceDescriptorsTaskBase<TReturn, TParentReturn>

Type parameters

  • TReturn

  • TParentReturn

Hierarchy

Index

Constructors

Methods

Constructors

constructor

Methods

run

  • run(): Promise<TReturn>

then

  • then(onfulfilled: (value: TReturn) => TReturn | PromiseLike<TReturn>): Promise<TReturn>
  • Parameters

    • onfulfilled: (value: TReturn) => TReturn | PromiseLike<TReturn>
        • (value: TReturn): TReturn | PromiseLike<TReturn>
        • Parameters

          • value: TReturn

          Returns TReturn | PromiseLike<TReturn>

    Returns Promise<TReturn>

Legend

  • Constructor
  • Property
  • Method
  • Inherited constructor
  • Inherited property
  • Inherited method
  • Property
  • Static method

Settings

Theme

\ No newline at end of file diff --git a/typedoc/classes/ComputeSingleFaceDescriptorTask.html b/typedoc/classes/ComputeSingleFaceDescriptorTask.html index 4e35f5a..399415a 100644 --- a/typedoc/classes/ComputeSingleFaceDescriptorTask.html +++ b/typedoc/classes/ComputeSingleFaceDescriptorTask.html @@ -1 +1 @@ -ComputeSingleFaceDescriptorTask | @vladmandic/face-api - v1.6.2
Options
All
  • Public
  • Public/Protected
  • All
Menu

Class ComputeSingleFaceDescriptorTask<TSource>

Type parameters

Hierarchy

Index

Constructors

constructor

Methods

run

then

withAgeAndGender

  • withAgeAndGender(): PredictSingleAgeAndGenderWithFaceAlignmentTask<WithFaceDescriptor<TSource>>

withFaceExpressions

  • withFaceExpressions(): PredictSingleFaceExpressionsWithFaceAlignmentTask<WithFaceDescriptor<TSource>>

Legend

  • Constructor
  • Property
  • Method
  • Inherited constructor
  • Inherited property
  • Inherited method
  • Property
  • Static method

Settings

Theme

\ No newline at end of file +ComputeSingleFaceDescriptorTask | @vladmandic/face-api - v1.6.3
Options
All
  • Public
  • Public/Protected
  • All
Menu

Class ComputeSingleFaceDescriptorTask<TSource>

Type parameters

Hierarchy

Index

Constructors

constructor

Methods

run

then

withAgeAndGender

  • withAgeAndGender(): PredictSingleAgeAndGenderWithFaceAlignmentTask<WithFaceDescriptor<TSource>>

withFaceExpressions

  • withFaceExpressions(): PredictSingleFaceExpressionsWithFaceAlignmentTask<WithFaceDescriptor<TSource>>

Legend

  • Constructor
  • Property
  • Method
  • Inherited constructor
  • Inherited property
  • Inherited method
  • Property
  • Static method

Settings

Theme

\ No newline at end of file diff --git a/typedoc/classes/DetectAllFaceLandmarksTask.html b/typedoc/classes/DetectAllFaceLandmarksTask.html index 8607cfc..95e464b 100644 --- a/typedoc/classes/DetectAllFaceLandmarksTask.html +++ b/typedoc/classes/DetectAllFaceLandmarksTask.html @@ -1 +1 @@ -DetectAllFaceLandmarksTask | @vladmandic/face-api - v1.6.2
Options
All
  • Public
  • Public/Protected
  • All
Menu

Class DetectAllFaceLandmarksTask<TSource>

Type parameters

Hierarchy

Index

Constructors

constructor

Methods

run

then

withAgeAndGender

withFaceDescriptors

withFaceExpressions

Legend

  • Constructor
  • Property
  • Method
  • Inherited constructor
  • Inherited property
  • Inherited method
  • Property
  • Static method

Settings

Theme

\ No newline at end of file +DetectAllFaceLandmarksTask | @vladmandic/face-api - v1.6.3
Options
All
  • Public
  • Public/Protected
  • All
Menu

Class DetectAllFaceLandmarksTask<TSource>

Type parameters

Hierarchy

Index

Constructors

constructor

Methods

run

then

withAgeAndGender

withFaceDescriptors

withFaceExpressions

Legend

  • Constructor
  • Property
  • Method
  • Inherited constructor
  • Inherited property
  • Inherited method
  • Property
  • Static method

Settings

Theme

\ No newline at end of file diff --git a/typedoc/classes/DetectAllFacesTask.html b/typedoc/classes/DetectAllFacesTask.html index 6aa8aa0..2f59c91 100644 --- a/typedoc/classes/DetectAllFacesTask.html +++ b/typedoc/classes/DetectAllFacesTask.html @@ -1 +1 @@ -DetectAllFacesTask | @vladmandic/face-api - v1.6.2
Options
All
  • Public
  • Public/Protected
  • All
Menu

Hierarchy

Index

Constructors

constructor

Methods

run

then

withAgeAndGender

  • withAgeAndGender(): PredictAllAgeAndGenderTask<{ detection: FaceDetection }>

withFaceExpressions

  • withFaceExpressions(): PredictAllFaceExpressionsTask<{ detection: FaceDetection }>

withFaceLandmarks

Legend

  • Constructor
  • Property
  • Method
  • Inherited constructor
  • Inherited property
  • Inherited method
  • Property
  • Static method

Settings

Theme

\ No newline at end of file +DetectAllFacesTask | @vladmandic/face-api - v1.6.3
Options
All
  • Public
  • Public/Protected
  • All
Menu

Hierarchy

Index

Constructors

constructor

Methods

run

then

withAgeAndGender

  • withAgeAndGender(): PredictAllAgeAndGenderTask<{ detection: FaceDetection }>

withFaceExpressions

  • withFaceExpressions(): PredictAllFaceExpressionsTask<{ detection: FaceDetection }>

withFaceLandmarks

Legend

  • Constructor
  • Property
  • Method
  • Inherited constructor
  • Inherited property
  • Inherited method
  • Property
  • Static method

Settings

Theme

\ No newline at end of file diff --git a/typedoc/classes/DetectFaceLandmarksTaskBase.html b/typedoc/classes/DetectFaceLandmarksTaskBase.html index e120de0..0f7a02a 100644 --- a/typedoc/classes/DetectFaceLandmarksTaskBase.html +++ b/typedoc/classes/DetectFaceLandmarksTaskBase.html @@ -1 +1 @@ -DetectFaceLandmarksTaskBase | @vladmandic/face-api - v1.6.2
Options
All
  • Public
  • Public/Protected
  • All
Menu

Class DetectFaceLandmarksTaskBase<TReturn, TParentReturn>

Type parameters

  • TReturn

  • TParentReturn

Hierarchy

Index

Constructors

Methods

Constructors

constructor

  • new DetectFaceLandmarksTaskBase<TReturn, TParentReturn>(parentTask: ComposableTask<TParentReturn> | Promise<TParentReturn>, input: any, useTinyLandmarkNet: boolean): DetectFaceLandmarksTaskBase<TReturn, TParentReturn>

Methods

run

  • run(): Promise<TReturn>

then

  • then(onfulfilled: (value: TReturn) => TReturn | PromiseLike<TReturn>): Promise<TReturn>
  • Parameters

    • onfulfilled: (value: TReturn) => TReturn | PromiseLike<TReturn>
        • (value: TReturn): TReturn | PromiseLike<TReturn>
        • Parameters

          • value: TReturn

          Returns TReturn | PromiseLike<TReturn>

    Returns Promise<TReturn>

Legend

  • Constructor
  • Property
  • Method
  • Inherited constructor
  • Inherited property
  • Inherited method
  • Property
  • Static method

Settings

Theme

\ No newline at end of file +DetectFaceLandmarksTaskBase | @vladmandic/face-api - v1.6.3
Options
All
  • Public
  • Public/Protected
  • All
Menu

Class DetectFaceLandmarksTaskBase<TReturn, TParentReturn>

Type parameters

  • TReturn

  • TParentReturn

Hierarchy

Index

Constructors

Methods

Constructors

constructor

  • new DetectFaceLandmarksTaskBase<TReturn, TParentReturn>(parentTask: ComposableTask<TParentReturn> | Promise<TParentReturn>, input: any, useTinyLandmarkNet: boolean): DetectFaceLandmarksTaskBase<TReturn, TParentReturn>

Methods

run

  • run(): Promise<TReturn>

then

  • then(onfulfilled: (value: TReturn) => TReturn | PromiseLike<TReturn>): Promise<TReturn>
  • Parameters

    • onfulfilled: (value: TReturn) => TReturn | PromiseLike<TReturn>
        • (value: TReturn): TReturn | PromiseLike<TReturn>
        • Parameters

          • value: TReturn

          Returns TReturn | PromiseLike<TReturn>

    Returns Promise<TReturn>

Legend

  • Constructor
  • Property
  • Method
  • Inherited constructor
  • Inherited property
  • Inherited method
  • Property
  • Static method

Settings

Theme

\ No newline at end of file diff --git a/typedoc/classes/DetectFacesTaskBase.html b/typedoc/classes/DetectFacesTaskBase.html index 6a591d5..2fcfa05 100644 --- a/typedoc/classes/DetectFacesTaskBase.html +++ b/typedoc/classes/DetectFacesTaskBase.html @@ -1 +1 @@ -DetectFacesTaskBase | @vladmandic/face-api - v1.6.2
Options
All
  • Public
  • Public/Protected
  • All
Menu

Class DetectFacesTaskBase<TReturn>

Type parameters

  • TReturn

Hierarchy

Index

Constructors

Methods

Constructors

constructor

Methods

run

  • run(): Promise<TReturn>

then

  • then(onfulfilled: (value: TReturn) => TReturn | PromiseLike<TReturn>): Promise<TReturn>
  • Parameters

    • onfulfilled: (value: TReturn) => TReturn | PromiseLike<TReturn>
        • (value: TReturn): TReturn | PromiseLike<TReturn>
        • Parameters

          • value: TReturn

          Returns TReturn | PromiseLike<TReturn>

    Returns Promise<TReturn>

Legend

  • Constructor
  • Property
  • Method
  • Inherited constructor
  • Inherited property
  • Inherited method
  • Property
  • Static method

Settings

Theme

\ No newline at end of file +DetectFacesTaskBase | @vladmandic/face-api - v1.6.3
Options
All
  • Public
  • Public/Protected
  • All
Menu

Class DetectFacesTaskBase<TReturn>

Type parameters

  • TReturn

Hierarchy

Index

Constructors

Methods

Constructors

constructor

Methods

run

  • run(): Promise<TReturn>

then

  • then(onfulfilled: (value: TReturn) => TReturn | PromiseLike<TReturn>): Promise<TReturn>
  • Parameters

    • onfulfilled: (value: TReturn) => TReturn | PromiseLike<TReturn>
        • (value: TReturn): TReturn | PromiseLike<TReturn>
        • Parameters

          • value: TReturn

          Returns TReturn | PromiseLike<TReturn>

    Returns Promise<TReturn>

Legend

  • Constructor
  • Property
  • Method
  • Inherited constructor
  • Inherited property
  • Inherited method
  • Property
  • Static method

Settings

Theme

\ No newline at end of file diff --git a/typedoc/classes/DetectSingleFaceLandmarksTask.html b/typedoc/classes/DetectSingleFaceLandmarksTask.html index 70c7b08..e770ca3 100644 --- a/typedoc/classes/DetectSingleFaceLandmarksTask.html +++ b/typedoc/classes/DetectSingleFaceLandmarksTask.html @@ -1 +1 @@ -DetectSingleFaceLandmarksTask | @vladmandic/face-api - v1.6.2
Options
All
  • Public
  • Public/Protected
  • All
Menu

Class DetectSingleFaceLandmarksTask<TSource>

Type parameters

Hierarchy

Index

Constructors

constructor

Methods

run

then

withAgeAndGender

withFaceDescriptor

withFaceExpressions

Legend

  • Constructor
  • Property
  • Method
  • Inherited constructor
  • Inherited property
  • Inherited method
  • Property
  • Static method

Settings

Theme

\ No newline at end of file +DetectSingleFaceLandmarksTask | @vladmandic/face-api - v1.6.3
Options
All
  • Public
  • Public/Protected
  • All
Menu

Class DetectSingleFaceLandmarksTask<TSource>

Type parameters

Hierarchy

Index

Constructors

constructor

Methods

run

then

withAgeAndGender

withFaceDescriptor

withFaceExpressions

Legend

  • Constructor
  • Property
  • Method
  • Inherited constructor
  • Inherited property
  • Inherited method
  • Property
  • Static method

Settings

Theme

\ No newline at end of file diff --git a/typedoc/classes/DetectSingleFaceTask.html b/typedoc/classes/DetectSingleFaceTask.html index 5eb4518..405461c 100644 --- a/typedoc/classes/DetectSingleFaceTask.html +++ b/typedoc/classes/DetectSingleFaceTask.html @@ -1 +1 @@ -DetectSingleFaceTask | @vladmandic/face-api - v1.6.2
Options
All
  • Public
  • Public/Protected
  • All
Menu

Hierarchy

Index

Constructors

constructor

Methods

run

then

withAgeAndGender

  • withAgeAndGender(): PredictSingleAgeAndGenderTask<{ detection: FaceDetection }>

withFaceExpressions

  • withFaceExpressions(): PredictSingleFaceExpressionsTask<{ detection: FaceDetection }>

withFaceLandmarks

Legend

  • Constructor
  • Property
  • Method
  • Inherited constructor
  • Inherited property
  • Inherited method
  • Property
  • Static method

Settings

Theme

\ No newline at end of file +DetectSingleFaceTask | @vladmandic/face-api - v1.6.3
Options
All
  • Public
  • Public/Protected
  • All
Menu

Hierarchy

Index

Constructors

constructor

Methods

run

then

withAgeAndGender

  • withAgeAndGender(): PredictSingleAgeAndGenderTask<{ detection: FaceDetection }>

withFaceExpressions

  • withFaceExpressions(): PredictSingleFaceExpressionsTask<{ detection: FaceDetection }>

withFaceLandmarks

Legend

  • Constructor
  • Property
  • Method
  • Inherited constructor
  • Inherited property
  • Inherited method
  • Property
  • Static method

Settings

Theme

\ No newline at end of file diff --git a/typedoc/classes/Dimensions.html b/typedoc/classes/Dimensions.html index 717abd1..68a3165 100644 --- a/typedoc/classes/Dimensions.html +++ b/typedoc/classes/Dimensions.html @@ -1 +1 @@ -Dimensions | @vladmandic/face-api - v1.6.2
Options
All
  • Public
  • Public/Protected
  • All
Menu

Hierarchy

  • Dimensions

Implements

Index

Constructors

Accessors

Methods

Constructors

constructor

  • new Dimensions(width: number, height: number): Dimensions

Accessors

height

  • get height(): number

width

  • get width(): number

Methods

reverse

Legend

  • Constructor
  • Property
  • Method
  • Inherited constructor
  • Inherited property
  • Inherited method
  • Property
  • Static method

Settings

Theme

\ No newline at end of file +Dimensions | @vladmandic/face-api - v1.6.3
Options
All
  • Public
  • Public/Protected
  • All
Menu

Hierarchy

  • Dimensions

Implements

Index

Constructors

Accessors

Methods

Constructors

constructor

  • new Dimensions(width: number, height: number): Dimensions

Accessors

height

  • get height(): number

width

  • get width(): number

Methods

reverse

Legend

  • Constructor
  • Property
  • Method
  • Inherited constructor
  • Inherited property
  • Inherited method
  • Property
  • Static method

Settings

Theme

\ No newline at end of file diff --git a/typedoc/classes/FaceDetection.html b/typedoc/classes/FaceDetection.html index 8e49c53..a1ceb33 100644 --- a/typedoc/classes/FaceDetection.html +++ b/typedoc/classes/FaceDetection.html @@ -1 +1 @@ -FaceDetection | @vladmandic/face-api - v1.6.2
Options
All
  • Public
  • Public/Protected
  • All
Menu

Hierarchy

Implements

Index

Constructors

constructor

Accessors

box

  • get box(): Box<any>

className

  • get className(): string

classScore

  • get classScore(): number

imageDims

imageHeight

  • get imageHeight(): number

imageWidth

  • get imageWidth(): number

relativeBox

  • get relativeBox(): Box<any>

score

  • get score(): number

Methods

forSize

Legend

  • Constructor
  • Property
  • Method
  • Inherited constructor
  • Inherited property
  • Inherited method
  • Property
  • Static method

Settings

Theme

\ No newline at end of file +FaceDetection | @vladmandic/face-api - v1.6.3
Options
All
  • Public
  • Public/Protected
  • All
Menu

Hierarchy

Implements

Index

Constructors

constructor

Accessors

box

  • get box(): Box<any>

className

  • get className(): string

classScore

  • get classScore(): number

imageDims

imageHeight

  • get imageHeight(): number

imageWidth

  • get imageWidth(): number

relativeBox

  • get relativeBox(): Box<any>

score

  • get score(): number

Methods

forSize

Legend

  • Constructor
  • Property
  • Method
  • Inherited constructor
  • Inherited property
  • Inherited method
  • Property
  • Static method

Settings

Theme

\ No newline at end of file diff --git a/typedoc/classes/FaceDetectionNet.html b/typedoc/classes/FaceDetectionNet.html index 3e139f5..1132063 100644 --- a/typedoc/classes/FaceDetectionNet.html +++ b/typedoc/classes/FaceDetectionNet.html @@ -1 +1 @@ -FaceDetectionNet | @vladmandic/face-api - v1.6.2
Options
All
  • Public
  • Public/Protected
  • All
Menu

Hierarchy

Index

Constructors

constructor

Properties

_name

_name: any

Accessors

isLoaded

  • get isLoaded(): boolean

paramMappings

  • get paramMappings(): ParamMapping[]
  • Returns ParamMapping[]

params

  • get params(): undefined | TNetParams
  • Returns undefined | TNetParams

Methods

dispose

  • dispose(throwOnRedispose?: boolean): void

extractWeights

  • extractWeights(weights: Float32Array): void

forward

  • forward(input: any): Promise<any>

forwardInput

freeze

  • freeze(): void

getFrozenParams

  • getFrozenParams(): { path: string; tensor: Tensor }[]

getParamFromPath

  • getParamFromPath(paramPath: string): Tensor

getParamList

  • getParamList(): { path: string; tensor: Tensor }[]

getTrainableParams

  • getTrainableParams(): { path: string; tensor: Tensor }[]

load

  • load(weightsOrUrl: undefined | string | Float32Array): Promise<void>

loadFromDisk

  • loadFromDisk(filePath: undefined | string): Promise<void>

loadFromUri

  • loadFromUri(uri: undefined | string): Promise<void>

loadFromWeightMap

  • loadFromWeightMap(weightMap: NamedTensorMap): void

locateFaces

reassignParamFromPath

  • reassignParamFromPath(paramPath: string, tensor: Tensor): void

serializeParams

  • serializeParams(): Float32Array

variable

  • variable(): void

Legend

  • Constructor
  • Property
  • Method
  • Inherited constructor
  • Inherited property
  • Inherited method
  • Property
  • Static method

Settings

Theme

\ No newline at end of file +FaceDetectionNet | @vladmandic/face-api - v1.6.3
Options
All
  • Public
  • Public/Protected
  • All
Menu

Hierarchy

Index

Constructors

constructor

Properties

_name

_name: any

Accessors

isLoaded

  • get isLoaded(): boolean

paramMappings

  • get paramMappings(): ParamMapping[]
  • Returns ParamMapping[]

params

  • get params(): undefined | TNetParams
  • Returns undefined | TNetParams

Methods

dispose

  • dispose(throwOnRedispose?: boolean): void

extractWeights

  • extractWeights(weights: Float32Array): void

forward

  • forward(input: any): Promise<any>

forwardInput

freeze

  • freeze(): void

getFrozenParams

  • getFrozenParams(): { path: string; tensor: Tensor }[]

getParamFromPath

  • getParamFromPath(paramPath: string): Tensor

getParamList

  • getParamList(): { path: string; tensor: Tensor }[]

getTrainableParams

  • getTrainableParams(): { path: string; tensor: Tensor }[]

load

  • load(weightsOrUrl: undefined | string | Float32Array): Promise<void>

loadFromDisk

  • loadFromDisk(filePath: undefined | string): Promise<void>

loadFromUri

  • loadFromUri(uri: undefined | string): Promise<void>

loadFromWeightMap

  • loadFromWeightMap(weightMap: NamedTensorMap): void

locateFaces

reassignParamFromPath

  • reassignParamFromPath(paramPath: string, tensor: Tensor): void

serializeParams

  • serializeParams(): Float32Array

variable

  • variable(): void

Legend

  • Constructor
  • Property
  • Method
  • Inherited constructor
  • Inherited property
  • Inherited method
  • Property
  • Static method

Settings

Theme

\ No newline at end of file diff --git a/typedoc/classes/FaceExpressionNet.html b/typedoc/classes/FaceExpressionNet.html index 6f669e0..40e7ae1 100644 --- a/typedoc/classes/FaceExpressionNet.html +++ b/typedoc/classes/FaceExpressionNet.html @@ -1 +1 @@ -FaceExpressionNet | @vladmandic/face-api - v1.6.2
Options
All
  • Public
  • Public/Protected
  • All
Menu

Hierarchy

  • FaceProcessor<FaceFeatureExtractorParams>
    • FaceExpressionNet

Index

Constructors

constructor

  • new FaceExpressionNet(faceFeatureExtractor?: FaceFeatureExtractor): FaceExpressionNet

Properties

_name

_name: any

Accessors

faceFeatureExtractor

  • get faceFeatureExtractor(): IFaceFeatureExtractor<TExtractorParams>

isLoaded

  • get isLoaded(): boolean

paramMappings

  • get paramMappings(): ParamMapping[]

params

  • get params(): undefined | TNetParams
  • Returns undefined | TNetParams

Methods

dispose

  • dispose(throwOnRedispose?: boolean): void

extractClassifierParams

  • extractClassifierParams(weights: Float32Array): { paramMappings: ParamMapping[]; params: NetParams }
  • Parameters

    • weights: Float32Array

    Returns { paramMappings: ParamMapping[]; params: NetParams }

    • paramMappings: ParamMapping[]
    • params: NetParams

extractWeights

  • extractWeights(weights: Float32Array): void
  • Parameters

    • weights: Float32Array

    Returns void

forward

  • forward(input: any): Promise<Tensor2D>

forwardInput

  • forwardInput(input: any): Tensor2D

freeze

  • freeze(): void

getFrozenParams

  • getFrozenParams(): { path: string; tensor: Tensor }[]
  • Returns { path: string; tensor: Tensor }[]

getParamFromPath

  • getParamFromPath(paramPath: string): Tensor
  • Parameters

    • paramPath: string

    Returns Tensor

getParamList

  • getParamList(): { path: string; tensor: Tensor }[]
  • Returns { path: string; tensor: Tensor }[]

getTrainableParams

  • getTrainableParams(): { path: string; tensor: Tensor }[]
  • Returns { path: string; tensor: Tensor }[]

load

  • load(weightsOrUrl: undefined | string | Float32Array): Promise<void>
  • Parameters

    • weightsOrUrl: undefined | string | Float32Array

    Returns Promise<void>

loadClassifierParams

  • loadClassifierParams(weights: Float32Array): void

loadFromDisk

  • loadFromDisk(filePath: undefined | string): Promise<void>
  • Parameters

    • filePath: undefined | string

    Returns Promise<void>

loadFromUri

  • loadFromUri(uri: undefined | string): Promise<void>
  • Parameters

    • uri: undefined | string

    Returns Promise<void>

loadFromWeightMap

  • loadFromWeightMap(weightMap: NamedTensorMap): void
  • Parameters

    • weightMap: NamedTensorMap

    Returns void

predictExpressions

  • predictExpressions(input: any): Promise<any>

reassignParamFromPath

  • reassignParamFromPath(paramPath: string, tensor: Tensor): void
  • Parameters

    • paramPath: string
    • tensor: Tensor

    Returns void

runNet

  • runNet(input: any): Tensor2D

serializeParams

  • serializeParams(): Float32Array

variable

  • variable(): void

Legend

  • Constructor
  • Property
  • Method
  • Inherited constructor
  • Inherited property
  • Inherited method
  • Property
  • Static method

Settings

Theme

\ No newline at end of file +FaceExpressionNet | @vladmandic/face-api - v1.6.3
Options
All
  • Public
  • Public/Protected
  • All
Menu

Hierarchy

  • FaceProcessor<FaceFeatureExtractorParams>
    • FaceExpressionNet

Index

Constructors

constructor

  • new FaceExpressionNet(faceFeatureExtractor?: FaceFeatureExtractor): FaceExpressionNet

Properties

_name

_name: any

Accessors

faceFeatureExtractor

  • get faceFeatureExtractor(): IFaceFeatureExtractor<TExtractorParams>

isLoaded

  • get isLoaded(): boolean

paramMappings

  • get paramMappings(): ParamMapping[]

params

  • get params(): undefined | TNetParams
  • Returns undefined | TNetParams

Methods

dispose

  • dispose(throwOnRedispose?: boolean): void

extractClassifierParams

  • extractClassifierParams(weights: Float32Array): { paramMappings: ParamMapping[]; params: NetParams }
  • Parameters

    • weights: Float32Array

    Returns { paramMappings: ParamMapping[]; params: NetParams }

    • paramMappings: ParamMapping[]
    • params: NetParams

extractWeights

  • extractWeights(weights: Float32Array): void
  • Parameters

    • weights: Float32Array

    Returns void

forward

  • forward(input: any): Promise<Tensor2D>

forwardInput

  • forwardInput(input: any): Tensor2D

freeze

  • freeze(): void

getFrozenParams

  • getFrozenParams(): { path: string; tensor: Tensor }[]
  • Returns { path: string; tensor: Tensor }[]

getParamFromPath

  • getParamFromPath(paramPath: string): Tensor
  • Parameters

    • paramPath: string

    Returns Tensor

getParamList

  • getParamList(): { path: string; tensor: Tensor }[]
  • Returns { path: string; tensor: Tensor }[]

getTrainableParams

  • getTrainableParams(): { path: string; tensor: Tensor }[]
  • Returns { path: string; tensor: Tensor }[]

load

  • load(weightsOrUrl: undefined | string | Float32Array): Promise<void>
  • Parameters

    • weightsOrUrl: undefined | string | Float32Array

    Returns Promise<void>

loadClassifierParams

  • loadClassifierParams(weights: Float32Array): void

loadFromDisk

  • loadFromDisk(filePath: undefined | string): Promise<void>
  • Parameters

    • filePath: undefined | string

    Returns Promise<void>

loadFromUri

  • loadFromUri(uri: undefined | string): Promise<void>
  • Parameters

    • uri: undefined | string

    Returns Promise<void>

loadFromWeightMap

  • loadFromWeightMap(weightMap: NamedTensorMap): void
  • Parameters

    • weightMap: NamedTensorMap

    Returns void

predictExpressions

  • predictExpressions(input: any): Promise<any>

reassignParamFromPath

  • reassignParamFromPath(paramPath: string, tensor: Tensor): void
  • Parameters

    • paramPath: string
    • tensor: Tensor

    Returns void

runNet

  • runNet(input: any): Tensor2D

serializeParams

  • serializeParams(): Float32Array

variable

  • variable(): void

Legend

  • Constructor
  • Property
  • Method
  • Inherited constructor
  • Inherited property
  • Inherited method
  • Property
  • Static method

Settings

Theme

\ No newline at end of file diff --git a/typedoc/classes/FaceExpressions.html b/typedoc/classes/FaceExpressions.html index 843e6f9..96f6444 100644 --- a/typedoc/classes/FaceExpressions.html +++ b/typedoc/classes/FaceExpressions.html @@ -1 +1 @@ -FaceExpressions | @vladmandic/face-api - v1.6.2
Options
All
  • Public
  • Public/Protected
  • All
Menu

Hierarchy

  • FaceExpressions

Index

Constructors

constructor

  • new FaceExpressions(probabilities: number[] | Float32Array): FaceExpressions

Properties

angry

angry: number = 0

disgusted

disgusted: number = 0

fearful

fearful: number = 0

happy

happy: number = 0

neutral

neutral: number = 0

sad

sad: number = 0

surprised

surprised: number = 0

Methods

asSortedArray

  • asSortedArray(): { expression: string; probability: number }[]

Legend

  • Constructor
  • Property
  • Method
  • Inherited constructor
  • Inherited property
  • Inherited method
  • Property
  • Static method

Settings

Theme

\ No newline at end of file +FaceExpressions | @vladmandic/face-api - v1.6.3
Options
All
  • Public
  • Public/Protected
  • All
Menu

Hierarchy

  • FaceExpressions

Index

Constructors

constructor

  • new FaceExpressions(probabilities: number[] | Float32Array): FaceExpressions

Properties

angry

angry: number = 0

disgusted

disgusted: number = 0

fearful

fearful: number = 0

happy

happy: number = 0

neutral

neutral: number = 0

sad

sad: number = 0

surprised

surprised: number = 0

Methods

asSortedArray

  • asSortedArray(): { expression: string; probability: number }[]

Legend

  • Constructor
  • Property
  • Method
  • Inherited constructor
  • Inherited property
  • Inherited method
  • Property
  • Static method

Settings

Theme

\ No newline at end of file diff --git a/typedoc/classes/FaceLandmark68Net.html b/typedoc/classes/FaceLandmark68Net.html index 867e1a4..255e5f1 100644 --- a/typedoc/classes/FaceLandmark68Net.html +++ b/typedoc/classes/FaceLandmark68Net.html @@ -1 +1 @@ -FaceLandmark68Net | @vladmandic/face-api - v1.6.2
Options
All
  • Public
  • Public/Protected
  • All
Menu

Hierarchy

  • FaceLandmark68NetBase<FaceFeatureExtractorParams>

Index

Constructors

constructor

  • new FaceLandmark68Net(faceFeatureExtractor?: FaceFeatureExtractor): FaceLandmark68Net

Properties

_name

_name: any

Accessors

faceFeatureExtractor

  • get faceFeatureExtractor(): IFaceFeatureExtractor<TExtractorParams>

isLoaded

  • get isLoaded(): boolean

paramMappings

  • get paramMappings(): ParamMapping[]
  • Returns ParamMapping[]

params

  • get params(): undefined | TNetParams
  • Returns undefined | TNetParams

Methods

detectLandmarks

dispose

  • dispose(throwOnRedispose?: boolean): void

extractClassifierParams

  • extractClassifierParams(weights: Float32Array): { paramMappings: ParamMapping[]; params: NetParams }
  • Parameters

    • weights: Float32Array

    Returns { paramMappings: ParamMapping[]; params: NetParams }

    • paramMappings: ParamMapping[]
    • params: NetParams

extractWeights

  • extractWeights(weights: Float32Array): void
  • Parameters

    • weights: Float32Array

    Returns void

forward

  • forward(input: any): Promise<Tensor2D>

forwardInput

freeze

  • freeze(): void

getFrozenParams

  • getFrozenParams(): { path: string; tensor: Tensor }[]
  • Returns { path: string; tensor: Tensor }[]

getParamFromPath

  • getParamFromPath(paramPath: string): Tensor
  • Parameters

    • paramPath: string

    Returns Tensor

getParamList

  • getParamList(): { path: string; tensor: Tensor }[]
  • Returns { path: string; tensor: Tensor }[]

getTrainableParams

  • getTrainableParams(): { path: string; tensor: Tensor }[]
  • Returns { path: string; tensor: Tensor }[]

load

  • load(weightsOrUrl: undefined | string | Float32Array): Promise<void>
  • Parameters

    • weightsOrUrl: undefined | string | Float32Array

    Returns Promise<void>

loadClassifierParams

  • loadClassifierParams(weights: Float32Array): void

loadFromDisk

  • loadFromDisk(filePath: undefined | string): Promise<void>
  • Parameters

    • filePath: undefined | string

    Returns Promise<void>

loadFromUri

  • loadFromUri(uri: undefined | string): Promise<void>
  • Parameters

    • uri: undefined | string

    Returns Promise<void>

loadFromWeightMap

  • loadFromWeightMap(weightMap: NamedTensorMap): void
  • Parameters

    • weightMap: NamedTensorMap

    Returns void

postProcess

  • postProcess(output: Tensor2D, inputSize: number, originalDimensions: IDimensions[]): Tensor2D

reassignParamFromPath

  • reassignParamFromPath(paramPath: string, tensor: Tensor): void
  • Parameters

    • paramPath: string
    • tensor: Tensor

    Returns void

runNet

  • runNet(input: any): Tensor2D

serializeParams

  • serializeParams(): Float32Array
  • Returns Float32Array

variable

  • variable(): void

Legend

  • Constructor
  • Property
  • Method
  • Inherited constructor
  • Inherited property
  • Inherited method
  • Property
  • Static method

Settings

Theme

\ No newline at end of file +FaceLandmark68Net | @vladmandic/face-api - v1.6.3
Options
All
  • Public
  • Public/Protected
  • All
Menu

Hierarchy

  • FaceLandmark68NetBase<FaceFeatureExtractorParams>

Index

Constructors

constructor

  • new FaceLandmark68Net(faceFeatureExtractor?: FaceFeatureExtractor): FaceLandmark68Net

Properties

_name

_name: any

Accessors

faceFeatureExtractor

  • get faceFeatureExtractor(): IFaceFeatureExtractor<TExtractorParams>

isLoaded

  • get isLoaded(): boolean

paramMappings

  • get paramMappings(): ParamMapping[]
  • Returns ParamMapping[]

params

  • get params(): undefined | TNetParams
  • Returns undefined | TNetParams

Methods

detectLandmarks

dispose

  • dispose(throwOnRedispose?: boolean): void

extractClassifierParams

  • extractClassifierParams(weights: Float32Array): { paramMappings: ParamMapping[]; params: NetParams }
  • Parameters

    • weights: Float32Array

    Returns { paramMappings: ParamMapping[]; params: NetParams }

    • paramMappings: ParamMapping[]
    • params: NetParams

extractWeights

  • extractWeights(weights: Float32Array): void
  • Parameters

    • weights: Float32Array

    Returns void

forward

  • forward(input: any): Promise<Tensor2D>

forwardInput

freeze

  • freeze(): void

getFrozenParams

  • getFrozenParams(): { path: string; tensor: Tensor }[]
  • Returns { path: string; tensor: Tensor }[]

getParamFromPath

  • getParamFromPath(paramPath: string): Tensor
  • Parameters

    • paramPath: string

    Returns Tensor

getParamList

  • getParamList(): { path: string; tensor: Tensor }[]
  • Returns { path: string; tensor: Tensor }[]

getTrainableParams

  • getTrainableParams(): { path: string; tensor: Tensor }[]
  • Returns { path: string; tensor: Tensor }[]

load

  • load(weightsOrUrl: undefined | string | Float32Array): Promise<void>
  • Parameters

    • weightsOrUrl: undefined | string | Float32Array

    Returns Promise<void>

loadClassifierParams

  • loadClassifierParams(weights: Float32Array): void

loadFromDisk

  • loadFromDisk(filePath: undefined | string): Promise<void>
  • Parameters

    • filePath: undefined | string

    Returns Promise<void>

loadFromUri

  • loadFromUri(uri: undefined | string): Promise<void>
  • Parameters

    • uri: undefined | string

    Returns Promise<void>

loadFromWeightMap

  • loadFromWeightMap(weightMap: NamedTensorMap): void
  • Parameters

    • weightMap: NamedTensorMap

    Returns void

postProcess

  • postProcess(output: Tensor2D, inputSize: number, originalDimensions: IDimensions[]): Tensor2D

reassignParamFromPath

  • reassignParamFromPath(paramPath: string, tensor: Tensor): void
  • Parameters

    • paramPath: string
    • tensor: Tensor

    Returns void

runNet

  • runNet(input: any): Tensor2D

serializeParams

  • serializeParams(): Float32Array
  • Returns Float32Array

variable

  • variable(): void

Legend

  • Constructor
  • Property
  • Method
  • Inherited constructor
  • Inherited property
  • Inherited method
  • Property
  • Static method

Settings

Theme

\ No newline at end of file diff --git a/typedoc/classes/FaceLandmark68TinyNet.html b/typedoc/classes/FaceLandmark68TinyNet.html index 3f44e4c..833a0d0 100644 --- a/typedoc/classes/FaceLandmark68TinyNet.html +++ b/typedoc/classes/FaceLandmark68TinyNet.html @@ -1 +1 @@ -FaceLandmark68TinyNet | @vladmandic/face-api - v1.6.2
Options
All
  • Public
  • Public/Protected
  • All
Menu

Hierarchy

  • FaceLandmark68NetBase<TinyFaceFeatureExtractorParams>
    • FaceLandmark68TinyNet

Index

Constructors

constructor

Properties

_name

_name: any

Accessors

faceFeatureExtractor

  • get faceFeatureExtractor(): IFaceFeatureExtractor<TExtractorParams>

isLoaded

  • get isLoaded(): boolean

paramMappings

  • get paramMappings(): ParamMapping[]
  • Returns ParamMapping[]

params

  • get params(): undefined | TNetParams
  • Returns undefined | TNetParams

Methods

detectLandmarks

dispose

  • dispose(throwOnRedispose?: boolean): void

extractClassifierParams

  • extractClassifierParams(weights: Float32Array): { paramMappings: ParamMapping[]; params: NetParams }
  • Parameters

    • weights: Float32Array

    Returns { paramMappings: ParamMapping[]; params: NetParams }

    • paramMappings: ParamMapping[]
    • params: NetParams

extractWeights

  • extractWeights(weights: Float32Array): void
  • Parameters

    • weights: Float32Array

    Returns void

forward

  • forward(input: any): Promise<Tensor2D>

forwardInput

freeze

  • freeze(): void

getFrozenParams

  • getFrozenParams(): { path: string; tensor: Tensor }[]
  • Returns { path: string; tensor: Tensor }[]

getParamFromPath

  • getParamFromPath(paramPath: string): Tensor
  • Parameters

    • paramPath: string

    Returns Tensor

getParamList

  • getParamList(): { path: string; tensor: Tensor }[]
  • Returns { path: string; tensor: Tensor }[]

getTrainableParams

  • getTrainableParams(): { path: string; tensor: Tensor }[]
  • Returns { path: string; tensor: Tensor }[]

load

  • load(weightsOrUrl: undefined | string | Float32Array): Promise<void>
  • Parameters

    • weightsOrUrl: undefined | string | Float32Array

    Returns Promise<void>

loadClassifierParams

  • loadClassifierParams(weights: Float32Array): void

loadFromDisk

  • loadFromDisk(filePath: undefined | string): Promise<void>
  • Parameters

    • filePath: undefined | string

    Returns Promise<void>

loadFromUri

  • loadFromUri(uri: undefined | string): Promise<void>
  • Parameters

    • uri: undefined | string

    Returns Promise<void>

loadFromWeightMap

  • loadFromWeightMap(weightMap: NamedTensorMap): void
  • Parameters

    • weightMap: NamedTensorMap

    Returns void

postProcess

  • postProcess(output: Tensor2D, inputSize: number, originalDimensions: IDimensions[]): Tensor2D

reassignParamFromPath

  • reassignParamFromPath(paramPath: string, tensor: Tensor): void
  • Parameters

    • paramPath: string
    • tensor: Tensor

    Returns void

runNet

  • runNet(input: any): Tensor2D

serializeParams

  • serializeParams(): Float32Array
  • Returns Float32Array

variable

  • variable(): void

Legend

  • Constructor
  • Property
  • Method
  • Inherited constructor
  • Inherited property
  • Inherited method
  • Property
  • Static method

Settings

Theme

\ No newline at end of file +FaceLandmark68TinyNet | @vladmandic/face-api - v1.6.3
Options
All
  • Public
  • Public/Protected
  • All
Menu

Hierarchy

  • FaceLandmark68NetBase<TinyFaceFeatureExtractorParams>
    • FaceLandmark68TinyNet

Index

Constructors

constructor

Properties

_name

_name: any

Accessors

faceFeatureExtractor

  • get faceFeatureExtractor(): IFaceFeatureExtractor<TExtractorParams>

isLoaded

  • get isLoaded(): boolean

paramMappings

  • get paramMappings(): ParamMapping[]
  • Returns ParamMapping[]

params

  • get params(): undefined | TNetParams
  • Returns undefined | TNetParams

Methods

detectLandmarks

dispose

  • dispose(throwOnRedispose?: boolean): void

extractClassifierParams

  • extractClassifierParams(weights: Float32Array): { paramMappings: ParamMapping[]; params: NetParams }
  • Parameters

    • weights: Float32Array

    Returns { paramMappings: ParamMapping[]; params: NetParams }

    • paramMappings: ParamMapping[]
    • params: NetParams

extractWeights

  • extractWeights(weights: Float32Array): void
  • Parameters

    • weights: Float32Array

    Returns void

forward

  • forward(input: any): Promise<Tensor2D>

forwardInput

freeze

  • freeze(): void

getFrozenParams

  • getFrozenParams(): { path: string; tensor: Tensor }[]
  • Returns { path: string; tensor: Tensor }[]

getParamFromPath

  • getParamFromPath(paramPath: string): Tensor
  • Parameters

    • paramPath: string

    Returns Tensor

getParamList

  • getParamList(): { path: string; tensor: Tensor }[]
  • Returns { path: string; tensor: Tensor }[]

getTrainableParams

  • getTrainableParams(): { path: string; tensor: Tensor }[]
  • Returns { path: string; tensor: Tensor }[]

load

  • load(weightsOrUrl: undefined | string | Float32Array): Promise<void>
  • Parameters

    • weightsOrUrl: undefined | string | Float32Array

    Returns Promise<void>

loadClassifierParams

  • loadClassifierParams(weights: Float32Array): void

loadFromDisk

  • loadFromDisk(filePath: undefined | string): Promise<void>
  • Parameters

    • filePath: undefined | string

    Returns Promise<void>

loadFromUri

  • loadFromUri(uri: undefined | string): Promise<void>
  • Parameters

    • uri: undefined | string

    Returns Promise<void>

loadFromWeightMap

  • loadFromWeightMap(weightMap: NamedTensorMap): void
  • Parameters

    • weightMap: NamedTensorMap

    Returns void

postProcess

  • postProcess(output: Tensor2D, inputSize: number, originalDimensions: IDimensions[]): Tensor2D

reassignParamFromPath

  • reassignParamFromPath(paramPath: string, tensor: Tensor): void
  • Parameters

    • paramPath: string
    • tensor: Tensor

    Returns void

runNet

  • runNet(input: any): Tensor2D

serializeParams

  • serializeParams(): Float32Array
  • Returns Float32Array

variable

  • variable(): void

Legend

  • Constructor
  • Property
  • Method
  • Inherited constructor
  • Inherited property
  • Inherited method
  • Property
  • Static method

Settings

Theme

\ No newline at end of file diff --git a/typedoc/classes/FaceLandmarkNet.html b/typedoc/classes/FaceLandmarkNet.html index 609bd80..e83cfa1 100644 --- a/typedoc/classes/FaceLandmarkNet.html +++ b/typedoc/classes/FaceLandmarkNet.html @@ -1 +1 @@ -FaceLandmarkNet | @vladmandic/face-api - v1.6.2
Options
All
  • Public
  • Public/Protected
  • All
Menu

Hierarchy

Index

Constructors

constructor

  • new FaceLandmarkNet(faceFeatureExtractor?: FaceFeatureExtractor): FaceLandmarkNet

Properties

_name

_name: any

Accessors

faceFeatureExtractor

  • get faceFeatureExtractor(): IFaceFeatureExtractor<TExtractorParams>

isLoaded

  • get isLoaded(): boolean

paramMappings

  • get paramMappings(): ParamMapping[]
  • Returns ParamMapping[]

params

  • get params(): undefined | TNetParams
  • Returns undefined | TNetParams

Methods

detectLandmarks

dispose

  • dispose(throwOnRedispose?: boolean): void

extractClassifierParams

  • extractClassifierParams(weights: Float32Array): { paramMappings: ParamMapping[]; params: NetParams }

extractWeights

  • extractWeights(weights: Float32Array): void

forward

  • forward(input: any): Promise<Tensor2D>

forwardInput

freeze

  • freeze(): void

getFrozenParams

  • getFrozenParams(): { path: string; tensor: Tensor }[]

getParamFromPath

  • getParamFromPath(paramPath: string): Tensor

getParamList

  • getParamList(): { path: string; tensor: Tensor }[]

getTrainableParams

  • getTrainableParams(): { path: string; tensor: Tensor }[]

load

  • load(weightsOrUrl: undefined | string | Float32Array): Promise<void>

loadClassifierParams

  • loadClassifierParams(weights: Float32Array): void

loadFromDisk

  • loadFromDisk(filePath: undefined | string): Promise<void>

loadFromUri

  • loadFromUri(uri: undefined | string): Promise<void>

loadFromWeightMap

  • loadFromWeightMap(weightMap: NamedTensorMap): void

postProcess

  • postProcess(output: Tensor2D, inputSize: number, originalDimensions: IDimensions[]): Tensor2D

reassignParamFromPath

  • reassignParamFromPath(paramPath: string, tensor: Tensor): void

runNet

  • runNet(input: any): Tensor2D

serializeParams

  • serializeParams(): Float32Array

variable

  • variable(): void

Legend

  • Constructor
  • Property
  • Method
  • Inherited constructor
  • Inherited property
  • Inherited method
  • Property
  • Static method

Settings

Theme

\ No newline at end of file +FaceLandmarkNet | @vladmandic/face-api - v1.6.3
Options
All
  • Public
  • Public/Protected
  • All
Menu

Hierarchy

Index

Constructors

constructor

  • new FaceLandmarkNet(faceFeatureExtractor?: FaceFeatureExtractor): FaceLandmarkNet

Properties

_name

_name: any

Accessors

faceFeatureExtractor

  • get faceFeatureExtractor(): IFaceFeatureExtractor<TExtractorParams>

isLoaded

  • get isLoaded(): boolean

paramMappings

  • get paramMappings(): ParamMapping[]
  • Returns ParamMapping[]

params

  • get params(): undefined | TNetParams
  • Returns undefined | TNetParams

Methods

detectLandmarks

dispose

  • dispose(throwOnRedispose?: boolean): void

extractClassifierParams

  • extractClassifierParams(weights: Float32Array): { paramMappings: ParamMapping[]; params: NetParams }

extractWeights

  • extractWeights(weights: Float32Array): void

forward

  • forward(input: any): Promise<Tensor2D>

forwardInput

freeze

  • freeze(): void

getFrozenParams

  • getFrozenParams(): { path: string; tensor: Tensor }[]

getParamFromPath

  • getParamFromPath(paramPath: string): Tensor

getParamList

  • getParamList(): { path: string; tensor: Tensor }[]

getTrainableParams

  • getTrainableParams(): { path: string; tensor: Tensor }[]

load

  • load(weightsOrUrl: undefined | string | Float32Array): Promise<void>

loadClassifierParams

  • loadClassifierParams(weights: Float32Array): void

loadFromDisk

  • loadFromDisk(filePath: undefined | string): Promise<void>

loadFromUri

  • loadFromUri(uri: undefined | string): Promise<void>

loadFromWeightMap

  • loadFromWeightMap(weightMap: NamedTensorMap): void

postProcess

  • postProcess(output: Tensor2D, inputSize: number, originalDimensions: IDimensions[]): Tensor2D

reassignParamFromPath

  • reassignParamFromPath(paramPath: string, tensor: Tensor): void

runNet

  • runNet(input: any): Tensor2D

serializeParams

  • serializeParams(): Float32Array

variable

  • variable(): void

Legend

  • Constructor
  • Property
  • Method
  • Inherited constructor
  • Inherited property
  • Inherited method
  • Property
  • Static method

Settings

Theme

\ No newline at end of file diff --git a/typedoc/classes/FaceLandmarks.html b/typedoc/classes/FaceLandmarks.html index de1ae03..f8079c5 100644 --- a/typedoc/classes/FaceLandmarks.html +++ b/typedoc/classes/FaceLandmarks.html @@ -1,4 +1,4 @@ -FaceLandmarks | @vladmandic/face-api - v1.6.2
Options
All
  • Public
  • Public/Protected
  • All
Menu

Hierarchy

Implements

Index

Constructors

constructor

Accessors

imageHeight

  • get imageHeight(): number

imageWidth

  • get imageWidth(): number

positions

relativePositions

  • get relativePositions(): Point[]

shift

Methods

align